summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/animation/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/animation/animation.pro12
-rw-r--r--tests/auto/corelib/animation/qabstractanimation/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/animation/qabstractanimation/qabstractanimation.pro4
-rw-r--r--tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp130
-rw-r--r--tests/auto/corelib/animation/qanimationgroup/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/animation/qanimationgroup/qanimationgroup.pro4
-rw-r--r--tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp63
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST3
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro4
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp202
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/BLACKLIST6
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro4
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp89
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/BLACKLIST6
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro4
-rw-r--r--tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp182
-rw-r--r--tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST9
-rw-r--r--tests/auto/corelib/animation/qsequentialanimationgroup/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/animation/qsequentialanimationgroup/qsequentialanimationgroup.pro4
-rw-r--r--tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp232
-rw-r--r--tests/auto/corelib/animation/qvariantanimation/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/animation/qvariantanimation/qvariantanimation.pro4
-rw-r--r--tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp62
-rw-r--r--tests/auto/corelib/codecs/codecs.pro4
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/.gitattributes1
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/.gitignore1
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/QT4-crashtest.txtbin34 -> 0 bytes
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/echo/echo.pro4
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/echo/main.cpp47
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/korean.txt1
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro3
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/test.pro6
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp2469
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/utf8.txt1
-rw-r--r--tests/auto/corelib/codecs/utf8/tst_utf8.cpp277
-rw-r--r--tests/auto/corelib/codecs/utf8/utf8.pro4
-rw-r--r--tests/auto/corelib/codecs/utf8/utf8data.cpp160
-rw-r--r--tests/auto/corelib/corelib.pro17
-rw-r--r--tests/auto/corelib/global/CMakeLists.txt25
-rw-r--r--tests/auto/corelib/global/global.pro14
-rw-r--r--tests/auto/corelib/global/q20/CMakeLists.txt1
-rw-r--r--tests/auto/corelib/global/q20/memory/CMakeLists.txt16
-rw-r--r--tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp161
-rw-r--r--tests/auto/corelib/global/q_func_info/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/global/q_func_info/q_func_info.pro4
-rw-r--r--tests/auto/corelib/global/q_func_info/tst_q_func_info.cpp31
-rw-r--r--tests/auto/corelib/global/qcompare/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/global/qcompare/tst_qcompare.cpp840
-rw-r--r--tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt39
-rw-r--r--tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp600
-rw-r--r--tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h63
-rw-r--r--tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp59
-rw-r--r--tests/auto/corelib/global/qcomparehelpers/wrappertypes.h116
-rw-r--r--tests/auto/corelib/global/qflags/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/global/qflags/qflags.pro6
-rw-r--r--tests/auto/corelib/global/qflags/tst_qflags.cpp285
-rw-r--r--tests/auto/corelib/global/qfloat16/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/global/qfloat16/qfloat16.pro4
-rw-r--r--tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp649
-rw-r--r--tests/auto/corelib/global/qgetputenv/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/global/qgetputenv/qgetputenv.pro4
-rw-r--r--tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp45
-rw-r--r--tests/auto/corelib/global/qglobal/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/global/qglobal/qglobal.c74
-rw-r--r--tests/auto/corelib/global/qglobal/qglobal.pro4
-rw-r--r--tests/auto/corelib/global/qglobal/tst_qglobal.cpp650
-rw-r--r--tests/auto/corelib/global/qglobalstatic/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro11
-rw-r--r--tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp71
-rw-r--r--tests/auto/corelib/global/qhooks/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/global/qhooks/qhooks.pro4
-rw-r--r--tests/auto/corelib/global/qhooks/tst_qhooks.cpp37
-rw-r--r--tests/auto/corelib/global/qkeycombination/.gitignore1
-rw-r--r--tests/auto/corelib/global/qkeycombination/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp279
-rw-r--r--tests/auto/corelib/global/qlogging/BLACKLIST8
-rw-r--r--tests/auto/corelib/global/qlogging/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/global/qlogging/app/app.pro25
-rw-r--r--tests/auto/corelib/global/qlogging/app/main.cpp29
-rw-r--r--tests/auto/corelib/global/qlogging/qlogging.pro8
-rw-r--r--tests/auto/corelib/global/qlogging/test/test.pro21
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qlogging.cpp306
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp334
-rw-r--r--tests/auto/corelib/global/qnativeinterface/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/global/qnativeinterface/tst_qnativeinterface.cpp115
-rw-r--r--tests/auto/corelib/global/qnumeric/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/global/qnumeric/qnumeric.pro6
-rw-r--r--tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp863
-rw-r--r--tests/auto/corelib/global/qoperatingsystemversion/.gitignore1
-rw-r--r--tests/auto/corelib/global/qoperatingsystemversion/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/global/qoperatingsystemversion/tst_qoperatingsystemversion.cpp254
-rw-r--r--tests/auto/corelib/global/qrand/.gitignore1
-rw-r--r--tests/auto/corelib/global/qrand/qrand.pro4
-rw-r--r--tests/auto/corelib/global/qrand/tst_qrand.cpp74
-rw-r--r--tests/auto/corelib/global/qrandomgenerator/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/global/qrandomgenerator/qrandomgenerator.pro4
-rw-r--r--tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp195
-rw-r--r--tests/auto/corelib/global/qtendian/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/global/qtendian/qtendian.pro4
-rw-r--r--tests/auto/corelib/global/qtendian/tst_qtendian.cpp255
-rw-r--r--tests/auto/corelib/global/qxp/CMakeLists.txt2
-rw-r--r--tests/auto/corelib/global/qxp/function_ref/CMakeLists.txt16
-rw-r--r--tests/auto/corelib/global/qxp/function_ref/tst_qxp_function_ref.cpp281
-rw-r--r--tests/auto/corelib/global/qxp/is_virtual_base_of/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/global/qxp/is_virtual_base_of/tst_is_virtual_base_of.cpp102
-rw-r--r--tests/auto/corelib/io/CMakeLists.txt70
-rw-r--r--tests/auto/corelib/io/io.pro77
-rw-r--r--tests/auto/corelib/io/largefile/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/largefile/largefile.pro6
-rw-r--r--tests/auto/corelib/io/largefile/tst_largefile.cpp78
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/CMakeLists.txt32
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro5
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc5
-rw-r--r--tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp209
-rw-r--r--tests/auto/corelib/io/qbuffer/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/io/qbuffer/qbuffer.pro4
-rw-r--r--tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp135
-rw-r--r--tests/auto/corelib/io/qdataurl/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/qdataurl/qdataurl.pro4
-rw-r--r--tests/auto/corelib/io/qdataurl/tst_qdataurl.cpp97
-rw-r--r--tests/auto/corelib/io/qdebug/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/io/qdebug/qdebug.pro4
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp794
-rw-r--r--tests/auto/corelib/io/qdir/CMakeLists.txt103
-rw-r--r--tests/auto/corelib/io/qdir/Info.plist2
-rw-r--r--tests/auto/corelib/io/qdir/qdir.pro14
-rw-r--r--tests/auto/corelib/io/qdir/qdir.qrc5
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt (renamed from tests/auto/corelib/io/qfileselector/platforms/+mac/test)0
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt (renamed from tests/auto/corelib/io/qfileselector/platforms/+mac/test5)0
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt (renamed from tests/auto/corelib/io/qfileselector/platforms/+osx/test)0
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/qdir.pro3
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp29
-rw-r--r--tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp29
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp403
-rw-r--r--tests/auto/corelib/io/qdiriterator/CMakeLists.txt45
-rw-r--r--tests/auto/corelib/io/qdiriterator/qdiriterator.pro8
-rw-r--r--tests/auto/corelib/io/qdiriterator/qdiriterator.qrc6
-rw-r--r--tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp233
-rw-r--r--tests/auto/corelib/io/qdirlisting/.gitignore1
-rw-r--r--tests/auto/corelib/io/qdirlisting/CMakeLists.txt46
-rw-r--r--tests/auto/corelib/io/qdirlisting/entrylist/directory/dummy (renamed from tests/auto/corelib/io/qfileselector/platforms/+osx/test4)0
-rw-r--r--tests/auto/corelib/io/qdirlisting/entrylist/file (renamed from tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+ios/test)0
-rw-r--r--tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp611
-rw-r--r--tests/auto/corelib/io/qfile/BLACKLIST7
-rw-r--r--tests/auto/corelib/io/qfile/CMakeLists.txt93
-rw-r--r--tests/auto/corelib/io/qfile/qfile.pro3
-rw-r--r--tests/auto/corelib/io/qfile/qfile.qrc5
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/main.cpp38
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro4
-rw-r--r--tests/auto/corelib/io/qfile/test.pro26
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp1124
-rw-r--r--tests/auto/corelib/io/qfileinfo/CMakeLists.txt60
-rw-r--r--tests/auto/corelib/io/qfileinfo/qfileinfo.pro8
-rw-r--r--tests/auto/corelib/io/qfileinfo/qfileinfo.qrc5
-rw-r--r--tests/auto/corelib/io/qfileinfo/testdata.qrc8
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp833
-rw-r--r--tests/auto/corelib/io/qfileselector/CMakeLists.txt77
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+ios/test (renamed from tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+macos/test (renamed from tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/+wasm/test (renamed from tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/test)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/test (renamed from tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/test)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+wasm/test (renamed from tests/auto/corelib/serialization/json/invalidBinaryData/38.bjson)0
-rw-r--r--tests/auto/corelib/io/qfileselector/platforms/+wasm/test2 (renamed from tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/050.xml)0
-rw-r--r--tests/auto/corelib/io/qfileselector/qfileselector.pro5
-rw-r--r--tests/auto/corelib/io/qfileselector/qfileselector.qrc65
-rw-r--r--tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp51
-rw-r--r--tests/auto/corelib/io/qfilesystementry/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro6
-rw-r--r--tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp48
-rw-r--r--tests/auto/corelib/io/qfilesystemmetadata/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/qfilesystemmetadata/qfilesystemmetadata.pro4
-rw-r--r--tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp36
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST6
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro4
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp247
-rw-r--r--tests/auto/corelib/io/qiodevice/BLACKLIST2
-rw-r--r--tests/auto/corelib/io/qiodevice/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/io/qiodevice/qiodevice.pro12
-rw-r--r--tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp89
-rw-r--r--tests/auto/corelib/io/qipaddress/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/qipaddress/qipaddress.pro4
-rw-r--r--tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp35
-rw-r--r--tests/auto/corelib/io/qlockfile/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/io/qlockfile/qlockfile.pro3
-rw-r--r--tests/auto/corelib/io/qlockfile/qlockfiletesthelper/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp29
-rw-r--r--tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro6
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp112
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.pro6
-rw-r--r--tests/auto/corelib/io/qloggingcategory/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/qloggingcategory/qloggingcategory.pro7
-rw-r--r--tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp70
-rw-r--r--tests/auto/corelib/io/qloggingregistry/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro13
-rw-r--r--tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp71
-rw-r--r--tests/auto/corelib/io/qnodebug/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/io/qnodebug/qnodebug.pro4
-rw-r--r--tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp33
-rw-r--r--tests/auto/corelib/io/qprocess-noapplication/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro4
-rw-r--r--tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp33
-rw-r--r--tests/auto/corelib/io/qprocess/BLACKLIST9
-rw-r--r--tests/auto/corelib/io/qprocess/CMakeLists.txt39
-rw-r--r--tests/auto/corelib/io/qprocess/crasher.h58
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp32
-rw-r--r--tests/auto/corelib/io/qprocess/qprocess.pri22
-rw-r--r--tests/auto/corelib/io/qprocess/qprocess.pro18
-rw-r--r--tests/auto/corelib/io/qprocess/test/CMakeLists.txt48
-rw-r--r--tests/auto/corelib/io/qprocess/test/test.pro22
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/main.cpp31
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/testDetached.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/io/qprocess/testForwarding/main.cpp31
-rw-r--r--tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp31
-rw-r--r--tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp44
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessHang/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro6
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt25
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro6
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro12
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp109
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp1154
-rw-r--r--tests/auto/corelib/io/qprocessenvironment/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro4
-rw-r--r--tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp83
-rw-r--r--tests/auto/corelib/io/qresourceengine/CMakeLists.txt58
-rw-r--r--tests/auto/corelib/io/qresourceengine/compressed.qrc5
-rwxr-xr-xtests/auto/corelib/io/qresourceengine/generateResources.sh9
-rw-r--r--tests/auto/corelib/io/qresourceengine/qresourceengine.pro2
-rw-r--r--tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro33
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore1
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/CMakeLists.txt25
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro8
-rw-r--r--tests/auto/corelib/io/qresourceengine/testqrc/test.qrc6
-rw-r--r--tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp306
-rw-r--r--tests/auto/corelib/io/qresourceengine/uncompressed.rccbin0 -> 16478 bytes
-rw-r--r--tests/auto/corelib/io/qresourceengine/world.txt1
-rw-r--r--tests/auto/corelib/io/qresourceengine/zlib.rccbin0 -> 137 bytes
-rw-r--r--tests/auto/corelib/io/qresourceengine/zstd.rccbin0 -> 112 bytes
-rw-r--r--tests/auto/corelib/io/qsavefile/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/io/qsavefile/qsavefile.pro5
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp99
-rw-r--r--tests/auto/corelib/io/qsettings/.gitattributes2
-rw-r--r--tests/auto/corelib/io/qsettings/CMakeLists.txt51
-rw-r--r--tests/auto/corelib/io/qsettings/float.ini3
-rw-r--r--tests/auto/corelib/io/qsettings/qsettings.pro11
-rw-r--r--tests/auto/corelib/io/qsettings/qsettings.qrc12
-rw-r--r--tests/auto/corelib/io/qsettings/qt5settings.ini11
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile4.ini2
-rw-r--r--tests/auto/corelib/io/qsettings/resourcefile5.ini2
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp822
-rw-r--r--tests/auto/corelib/io/qsettings/utf8settings.ini11
-rw-r--r--tests/auto/corelib/io/qstandardpaths/CMakeLists.txt29
-rw-r--r--tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro10
-rw-r--r--tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp561
-rw-r--r--tests/auto/corelib/io/qstorageinfo/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/io/qstorageinfo/qstorageinfo.pro4
-rw-r--r--tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp386
-rw-r--r--tests/auto/corelib/io/qtemporarydir/BLACKLIST2
-rw-r--r--tests/auto/corelib/io/qtemporarydir/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro7
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp162
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/CMakeLists.txt59
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro10
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.qrc5
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp246
-rw-r--r--tests/auto/corelib/io/qurl/CMakeLists.txt28
-rw-r--r--tests/auto/corelib/io/qurl/idna-test.c29
-rw-r--r--tests/auto/corelib/io/qurl/qurl.pro6
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp562
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl_mac.mm31
-rw-r--r--tests/auto/corelib/io/qurlinternal/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/io/qurlinternal/qurlinternal.pro5
-rw-r--r--tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp605
-rw-r--r--tests/auto/corelib/io/qurlinternal/utf8data.cpp135
-rw-r--r--tests/auto/corelib/io/qurlquery/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/io/qurlquery/qurlquery.pro5
-rw-r--r--tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp203
-rw-r--r--tests/auto/corelib/io/qurluts46/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/io/qurluts46/testdata/IdnaTestV2.txt6374
-rw-r--r--tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp154
-rw-r--r--tests/auto/corelib/io/qzip/.gitignore1
-rw-r--r--tests/auto/corelib/io/qzip/CMakeLists.txt26
-rw-r--r--tests/auto/corelib/io/qzip/testdata/symlink.zipbin0 -> 289 bytes
-rw-r--r--tests/auto/corelib/io/qzip/testdata/test.zipbin0 -> 286 bytes
-rw-r--r--tests/auto/corelib/io/qzip/tst_qzip.cpp116
-rw-r--r--tests/auto/corelib/ipc/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/ipc/ipctestcommon.h83
-rw-r--r--tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp442
-rw-r--r--tests/auto/corelib/ipc/qsharedmemory/CMakeLists.txt27
-rw-r--r--tests/auto/corelib/ipc/qsharedmemory/producerconsumer/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/ipc/qsharedmemory/producerconsumer/main.cpp174
-rw-r--r--tests/auto/corelib/ipc/qsharedmemory/tst_qsharedmemory.cpp966
-rw-r--r--tests/auto/corelib/ipc/qsystemsemaphore/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/main.cpp80
-rw-r--r--tests/auto/corelib/ipc/qsystemsemaphore/tst_qsystemsemaphore.cpp368
-rw-r--r--tests/auto/corelib/itemmodels/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/itemmodels/itemmodels.pro19
-rw-r--r--tests/auto/corelib/itemmodels/qabstractitemmodel/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro9
-rw-r--r--tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp392
-rw-r--r--tests/auto/corelib/itemmodels/qabstractproxymodel/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/itemmodels/qabstractproxymodel/qabstractproxymodel.pro5
-rw-r--r--tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp245
-rw-r--r--tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp867
-rw-r--r--tests/auto/corelib/itemmodels/qidentityproxymodel/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/itemmodels/qidentityproxymodel/qidentityproxymodel.pro8
-rw-r--r--tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp226
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp80
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/qitemmodel.pro4
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp144
-rw-r--r--tests/auto/corelib/itemmodels/qitemselectionmodel/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/itemmodels/qitemselectionmodel/qitemselectionmodel.pro4
-rw-r--r--tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp607
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp5501
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h173
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp4991
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h192
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro8
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp70
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore1
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro16
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp69
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro16
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp157
-rw-r--r--tests/auto/corelib/itemmodels/qstringlistmodel/CMakeLists.txt18
-rw-r--r--tests/auto/corelib/itemmodels/qstringlistmodel/qmodellistener.h29
-rw-r--r--tests/auto/corelib/itemmodels/qstringlistmodel/qstringlistmodel.pro5
-rw-r--r--tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp249
-rw-r--r--tests/auto/corelib/itemmodels/qtransposeproxymodel/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp962
-rw-r--r--tests/auto/corelib/kernel/CMakeLists.txt54
-rw-r--r--tests/auto/corelib/kernel/kernel.pro46
-rw-r--r--tests/auto/corelib/kernel/qapplicationstatic/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qapplicationstatic/tst_qapplicationstatic.cpp40
-rw-r--r--tests/auto/corelib/kernel/qchronotimer/.gitignore1
-rw-r--r--tests/auto/corelib/kernel/qchronotimer/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp1266
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt39
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro9
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp368
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h42
-rw-r--r--tests/auto/corelib/kernel/qdeadlinetimer/BLACKLIST2
-rw-r--r--tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qdeadlinetimer/qdeadlinetimer.pro5
-rw-r--r--tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp507
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST4
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/qelapsedtimer.pro5
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp118
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST6
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro4
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp415
-rw-r--r--tests/auto/corelib/kernel/qeventloop/BLACKLIST4
-rw-r--r--tests/auto/corelib/kernel/qeventloop/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/kernel/qeventloop/qeventloop.pro8
-rw-r--r--tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp101
-rw-r--r--tests/auto/corelib/kernel/qjniarray/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp165
-rw-r--r--tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java60
-rw-r--r--tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp379
-rw-r--r--tests/auto/corelib/kernel/qjniobject/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java345
-rw-r--r--tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp2108
-rw-r--r--tests/auto/corelib/kernel/qjnitypes/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp284
-rw-r--r--tests/auto/corelib/kernel/qmath/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qmath/qmath.pro4
-rw-r--r--tests/auto/corelib/kernel/qmath/tst_qmath.cpp189
-rw-r--r--tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp749
-rw-r--r--tests/auto/corelib/kernel/qmetaenum/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro4
-rw-r--r--tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp52
-rw-r--r--tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro4
-rw-r--r--tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp247
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/CMakeLists.txt36
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/forwarddeclared.cpp17
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/forwarddeclared.h12
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro5
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp1373
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro4
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp382
-rw-r--r--tests/auto/corelib/kernel/qmetaproperty/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qmetaproperty/qmetaproperty.pro4
-rw-r--r--tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp137
-rw-r--r--tests/auto/corelib/kernel/qmetatype/CMakeLists.txt63
-rw-r--r--tests/auto/corelib/kernel/qmetatype/lib1.cpp5
-rw-r--r--tests/auto/corelib/kernel/qmetatype/lib2.cpp5
-rw-r--r--tests/auto/corelib/kernel/qmetatype/lib_common.cpp13
-rw-r--r--tests/auto/corelib/kernel/qmetatype/qmetatype.pro32
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp2145
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h568
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp733
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype3.cpp14
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h269
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h24
-rw-r--r--tests/auto/corelib/kernel/qmetatype/typeFlags.binbin144 -> 452 bytes
-rw-r--r--tests/auto/corelib/kernel/qmimedata/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qmimedata/qmimedata.pro4
-rw-r--r--tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp61
-rw-r--r--tests/auto/corelib/kernel/qobject/BLACKLIST2
-rw-r--r--tests/auto/corelib/kernel/qobject/CMakeLists.txt26
-rw-r--r--tests/auto/corelib/kernel/qobject/qobject.pro4
-rw-r--r--tests/auto/corelib/kernel/qobject/signalbug/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/kernel/qobject/signalbug/signalbug.cpp29
-rw-r--r--tests/auto/corelib/kernel/qobject/signalbug/signalbug.h29
-rw-r--r--tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro6
-rw-r--r--tests/auto/corelib/kernel/qobject/test.pro10
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp3713
-rw-r--r--tests/auto/corelib/kernel/qpermission/.gitignore1
-rw-r--r--tests/auto/corelib/kernel/qpermission/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qpermission/tst_qpermission.cpp284
-rw-r--r--tests/auto/corelib/kernel/qpointer/CMakeLists.txt31
-rw-r--r--tests/auto/corelib/kernel/qpointer/qpointer.pro5
-rw-r--r--tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp154
-rw-r--r--tests/auto/corelib/kernel/qproperty/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp2582
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp198
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro5
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro6
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/test.pro8
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp821
-rw-r--r--tests/auto/corelib/kernel/qsignalblocker/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro5
-rw-r--r--tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp47
-rw-r--r--tests/auto/corelib/kernel/qsignalmapper/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro4
-rw-r--r--tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp47
-rw-r--r--tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST3
-rw-r--r--tests/auto/corelib/kernel/qsocketnotifier/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro8
-rw-r--r--tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp194
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro5
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp101
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro3
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/test.pro7
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp292
-rw-r--r--tests/auto/corelib/kernel/qtimer/BLACKLIST5
-rw-r--r--tests/auto/corelib/kernel/qtimer/CMakeLists.txt34
-rw-r--r--tests/auto/corelib/kernel/qtimer/qtimer.pro7
-rw-r--r--tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp757
-rw-r--r--tests/auto/corelib/kernel/qtranslator/CMakeLists.txt56
-rw-r--r--tests/auto/corelib/kernel/qtranslator/android_testdata.qrc8
-rw-r--r--tests/auto/corelib/kernel/qtranslator/hellotr_la.qmbin230 -> 237 bytes
-rw-r--r--tests/auto/corelib/kernel/qtranslator/qtranslator.pro9
-rw-r--r--tests/auto/corelib/kernel/qtranslator/qtranslator.qrc6
-rw-r--r--tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp214
-rw-r--r--tests/auto/corelib/kernel/qvariant/CMakeLists.txt44
-rw-r--r--tests/auto/corelib/kernel/qvariant/qvariant.pro12
-rw-r--r--tests/auto/corelib/kernel/qvariant/qvariant.qrc6
-rw-r--r--tests/auto/corelib/kernel/qvariant/stream/qt4.9/qregexp.binbin30 -> 0 bytes
-rw-r--r--tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregexp.binbin30 -> 0 bytes
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp3535
-rw-r--r--tests/auto/corelib/kernel/qwineventnotifier/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/kernel/qwineventnotifier/qwineventnotifier.pro4
-rw-r--r--tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp41
-rw-r--r--tests/auto/corelib/kernel/qwinregistrykey/.gitignore1
-rw-r--r--tests/auto/corelib/kernel/qwinregistrykey/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/kernel/qwinregistrykey/tst_qwinregistrykey.cpp242
-rw-r--r--tests/auto/corelib/mimetypes/CMakeLists.txt7
-rw-r--r--tests/auto/corelib/mimetypes/mimetypes.pro8
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/CMakeLists.txt9
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml7
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml13
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt86
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro16
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp35
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt86
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro17
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp32
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro5
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/test.qml29
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/test.txt6
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc14
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml15
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp488
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h40
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/webm-glob-deleteall.xml7
-rw-r--r--tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro5
-rw-r--r--tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp162
-rw-r--r--tests/auto/corelib/platform/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/platform/android/CMakeLists.txt28
-rw-r--r--tests/auto/corelib/platform/android/testdata/assets/test.txt1
-rw-r--r--tests/auto/corelib/platform/android/testdata/assets/top_level_dir/file_in_top_dir.txt1
-rw-r--r--tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/file_in_sub_dir.txt1
-rw-r--r--tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/sub_dir_2/sub_dir_3/file_in_sub_dir_3.txt1
-rw-r--r--tests/auto/corelib/platform/android/tst_android.cpp377
-rw-r--r--tests/auto/corelib/platform/android_appless/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/platform/android_appless/tst_android_appless.cpp53
-rw-r--r--tests/auto/corelib/platform/windows/CMakeLists.txt4
-rw-r--r--tests/auto/corelib/platform/windows/qcomobject/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp268
-rw-r--r--tests/auto/corelib/plugin/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/plugin/plugin.pro15
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/CMakeLists.txt31
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp31
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h33
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json5
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro14
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h29
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin2/CMakeLists.txt31
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp31
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h31
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro14
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h29
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro15
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/staticplugin/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/staticplugin/main.cpp22
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/staticplugin/plugin.json3
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/test/CMakeLists.txt32
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/test/test.pro30
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp213
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/winrt.pri9
-rw-r--r--tests/auto/corelib/plugin/qlibrary/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/plugin/qlibrary/lib/CMakeLists.txt75
-rw-r--r--tests/auto/corelib/plugin/qlibrary/lib/lib.pro21
-rw-r--r--tests/auto/corelib/plugin/qlibrary/lib/mylib.c29
-rw-r--r--tests/auto/corelib/plugin/qlibrary/lib2/CMakeLists.txt110
-rw-r--r--tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro47
-rw-r--r--tests/auto/corelib/plugin/qlibrary/lib2/mylib.c29
-rw-r--r--tests/auto/corelib/plugin/qlibrary/qlibrary.pro15
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt28
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst/tst.pro25
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp306
-rw-r--r--tests/auto/corelib/plugin/qplugin/CMakeLists.txt48
-rw-r--r--tests/auto/corelib/plugin/qplugin/debugplugin/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/plugin/qplugin/debugplugin/debugplugin.pro6
-rw-r--r--tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp29
-rw-r--r--tests/auto/corelib/plugin/qplugin/invalidplugin/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/plugin/qplugin/invalidplugin/invalidplugin.pro5
-rw-r--r--tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp30
-rw-r--r--tests/auto/corelib/plugin/qplugin/qplugin.pro17
-rw-r--r--tests/auto/corelib/plugin/qplugin/releaseplugin/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp29
-rw-r--r--tests/auto/corelib/plugin/qplugin/releaseplugin/releaseplugin.pro6
-rw-r--r--tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp146
-rw-r--r--tests/auto/corelib/plugin/qplugin/tst_qplugin.pro6
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/almostplugin/CMakeLists.txt18
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.cpp29
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.h31
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.pro12
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/corrupt1.elf64.sobin239745 -> 0 bytes
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/corrupt2.elf64.sobin240097 -> 0 bytes
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/corrupt3.elf64.sobin240097 -> 0 bytes
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/garbage1.so4
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/garbage2.so1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/garbage3.so1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/garbage4.so1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/elftest/garbage5.so2
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp85
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/lib/CMakeLists.txt34
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/lib/lib.pro14
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/lib/mylib.c29
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt138
-rwxr-xr-xtests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl29
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri13
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro15
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro41
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro9
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro2
-rwxr-xr-xtests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl99
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp1
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro20
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/CMakeLists.txt25
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp14
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/CMakeLists.txt32
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/plugininterface.h29
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.cpp80
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.h21
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp29
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h31
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro14
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst/CMakeLists.txt71
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst/tst.pro16
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp913
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/winrt.pri9
-rw-r--r--tests/auto/corelib/plugin/quuid/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/plugin/quuid/quuid.pro6
-rw-r--r--tests/auto/corelib/plugin/quuid/test/CMakeLists.txt26
-rw-r--r--tests/auto/corelib/plugin/quuid/test/test.pro19
-rw-r--r--tests/auto/corelib/plugin/quuid/testProcessUniqueness/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp33
-rw-r--r--tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro9
-rw-r--r--tests/auto/corelib/plugin/quuid/tst_quuid.cpp155
-rw-r--r--tests/auto/corelib/plugin/quuid/tst_quuid_darwin.mm33
-rw-r--r--tests/auto/corelib/serialization/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/serialization/cborlargedatavalidation.cpp120
-rw-r--r--tests/auto/corelib/serialization/json/CMakeLists.txt36
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/10.bjsonbin544 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/11.bjsonbin542 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/12.bjsonbin506 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/13.bjsonbin544 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/14.bjsonbin521 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/15.bjsonbin536 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/16.bjsonbin874 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/17.bjsonbin49 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/18.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/19.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/20.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/21.bjsonbin552 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/22.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/23.bjsonbin533 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/24.bjsonbin506 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/25.bjsonbin542 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/26.bjsonbin628 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/27.bjsonbin51 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/28.bjsonbin542 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/29.bjsonbin544 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/30.bjsonbin542 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/31.bjsonbin553 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/32.bjsonbin536 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/33.bjsonbin544 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/34.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/35.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/36.bjsonbin524 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/37.bjsonbin536 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/39.bjsonbin24 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/40.bjsonbin60 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/invalidBinaryData/41.bjsonbin32 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/json.pro12
-rw-r--r--tests/auto/corelib/serialization/json/json.qrc9
-rw-r--r--tests/auto/corelib/serialization/json/simple.duplicates.json1
-rw-r--r--tests/auto/corelib/serialization/json/test.bjsonbin35392 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/json/test.duplicates.json66
-rw-r--r--tests/auto/corelib/serialization/json/test3.duplicates.json15
-rw-r--r--tests/auto/corelib/serialization/json/tst_qtjson.cpp1768
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro11
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp307
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro8
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp80
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro11
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp2172
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro7
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp73
-rw-r--r--tests/auto/corelib/serialization/qdatastream/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp28
-rw-r--r--tests/auto/corelib/serialization/qdatastream/qdatastream.pro11
-rw-r--r--tests/auto/corelib/serialization/qdatastream/testdata.qrc5
-rw-r--r--tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp818
-rw-r--r--tests/auto/corelib/serialization/qdatastream/typedef.q5bin0 -> 28 bytes
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro4
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp58
-rw-r--r--tests/auto/corelib/serialization/qtextstream/BLACKLIST10
-rw-r--r--tests/auto/corelib/serialization/qtextstream/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/serialization/qtextstream/qtextstream.pro2
-rw-r--r--tests/auto/corelib/serialization/qtextstream/qtextstream_integrity.qrc7
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp30
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro8
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp31
-rw-r--r--tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro8
-rw-r--r--tests/auto/corelib/serialization/qtextstream/shift-jis.txt764
-rw-r--r--tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp29
-rw-r--r--tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro8
-rw-r--r--tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt49
-rw-r--r--tests/auto/corelib/serialization/qtextstream/test/test.pro28
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp477
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest.zipbin0 -> 107060 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Entries6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/canonxml.html44
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Entries7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Entries3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/022.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Entries2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries.Log3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Entries7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/002.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Entries22
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/001.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/002.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/003.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/004.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/005.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/006.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/007.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/008.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/009.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/010.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/011.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/012.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/013.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/014.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/015.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/016.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/017.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/018.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/019.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/020.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/021.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/022.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/023.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/024.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/025.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/026.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/027.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/028.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/029.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/030.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/031.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/032.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/033.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/034.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/035.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/036.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/037.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/038.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/039.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/040.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/041.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/042.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/043.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/044.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/045.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/046.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/047.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/048.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/049.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/051.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/052.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/053.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/054.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/055.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/056.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/057.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/058.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/059.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/060.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/061.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/062.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/063.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/064.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/065.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/066.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/067.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/068.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/069.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/070.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/071.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/072.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/073.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/074.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/075.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/076.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/077.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/078.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/079.xml8
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/080.xml8
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/081.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/082.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/083.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/084.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/085.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/086.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/087.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/088.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/089.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/090.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/091.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/092.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/093.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/094.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/095.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/096.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/097.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/098.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/099.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/100.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/101.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/102.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/103.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/104.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/105.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/106.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/107.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/108.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/109.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/110.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/111.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/112.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/113.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/114.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/115.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/116.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/117.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/118.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/119.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/120.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/121.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/122.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/123.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/124.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/125.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/126.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/127.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/128.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/129.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/130.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/131.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/132.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/133.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/134.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/135.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/136.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/137.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/138.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/139.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/140.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/141.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/142.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/143.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/144.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/145.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/146.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/147.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/148.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/149.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/150.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/151.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/152.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/153.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/154.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/155.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/156.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/157.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/158.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/159.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/160.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/161.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/162.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/163.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/164.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/165.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/167.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/168.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/169.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/170.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/171.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/172.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/173.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/174.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/175.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/176.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/177.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/178.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/179.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/180.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/181.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/182.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/183.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/184.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.xml3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/186.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Entries189
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/null.ent0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/readme.html60
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries.Log3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.ent0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.ent4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.entbin4 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.entbin54 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.ent0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.xml9
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.xml10
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.entbin12 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Entries29
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/001.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/002.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/003.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/004.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/005.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/006.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/007.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/008.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/009.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/010.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/011.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/012.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/013.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/014.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Entries15
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.ent0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-1.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-2.ent0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-1.ent4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-2.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-1.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-2.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.ent4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.ent4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.ent5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.ent4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.ent5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.ent4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.ent5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.ent2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-1.ent3
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-2.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Entries65
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/001.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/002.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/003.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/004.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/005.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/006.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/007.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/008.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/009.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/010.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/011.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/012.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/013.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/014.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/015.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/016.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/017.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/018.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/019.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/020.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/021.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/022.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/023.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/024.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/025.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/026.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/027.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/028.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/029.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/030.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/031.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Entries32
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/001.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/002.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/003.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/004.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/005.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/006.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/007.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/008.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/009.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/010.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/011.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/012.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/013.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/014.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/015.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/016.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/017.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/018.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/019.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/020.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/021.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/022.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/023.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/024.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/025.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/026.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/027.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/028.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/029.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/030.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/031.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/032.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/033.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/034.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/035.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/036.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/037.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/038.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/039.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/040.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/041.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/042.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/043.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/044.xml10
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/045.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/046.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/047.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/048.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/049.xmlbin124 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/050.xmlbin132 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/051.xmlbin140 -> 0 bytes
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/052.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/053.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/054.xml10
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/055.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/056.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/057.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/058.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/059.xml10
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/060.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/061.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/062.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/063.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/064.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/065.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/066.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/067.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/068.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/069.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/070.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/071.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/072.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/073.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/074.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/075.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/076.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/077.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/078.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/079.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/080.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/081.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/082.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/083.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/084.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/085.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/086.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/087.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/088.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/089.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/090.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/091.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/092.xml10
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/093.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/094.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/095.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/096.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.ent1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.xml8
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/098.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/099.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/100.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/101.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/102.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/103.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/104.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/105.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/106.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/107.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/108.xml7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/109.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/110.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/111.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/112.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/113.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/114.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/115.xml6
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/116.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/117.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/118.xml5
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/119.xml4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Entries121
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/001.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/002.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/003.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/004.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/005.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/006.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/007.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/008.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/009.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/010.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/011.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/012.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/013.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/014.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/015.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/016.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/017.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/018.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/019.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/020.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/021.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/022.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/023.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/024.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/025.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/026.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/027.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/028.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/029.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/030.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/031.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/032.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/033.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/034.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/035.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/036.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/037.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/038.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/039.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/040.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/041.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/042.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/043.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/044.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/045.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/046.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/047.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/048.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/049.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/050.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/051.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/052.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/053.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/054.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/055.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/056.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/057.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/058.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/059.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/060.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/061.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/062.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/063.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/064.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/065.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/066.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/067.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/068.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/070.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/071.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/072.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/073.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/074.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/075.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/077.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/078.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/079.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/080.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/081.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/082.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/083.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/084.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/085.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/086.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/087.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/088.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/089.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/092.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/093.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/094.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/095.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/096.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/097.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/098.xml2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/099.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/100.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/101.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/102.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/103.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/104.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/105.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/106.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/107.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/108.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/109.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/110.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/111.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/112.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/113.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/114.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/115.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/116.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/117.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/118.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/119.xml1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Entries120
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Repository1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Root1
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/xmltest.xml1433
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/069.xml (renamed from tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/069.xml)0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/076.xml (renamed from tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/076.xml)0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/090.xml (renamed from tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/090.xml)0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/091.xml (renamed from tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/091.xml)0
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/019.ref2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/024.ref4
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/039.ref2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/041.ref2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/1.ref2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/2.ref2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/21.ref10
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.ref8003
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.xml1002
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/data/namespaceCDATA.ref2
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/qc14n.h51
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/qxmlstream.pro6
-rwxr-xr-xtests/auto/corelib/serialization/qxmlstream/setupSuite.sh33
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml20
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml20
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml15
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp795
-rw-r--r--tests/auto/corelib/serialization/serialization.pro20
-rw-r--r--tests/auto/corelib/statemachine/qstate/qstate.pro4
-rw-r--r--tests/auto/corelib/statemachine/qstate/tst_qstate.cpp374
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro5
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp6700
-rw-r--r--tests/auto/corelib/statemachine/statemachine.pro4
-rw-r--r--tests/auto/corelib/text/CMakeLists.txt29
-rw-r--r--tests/auto/corelib/text/qanystringview/.gitignore1
-rw-r--r--tests/auto/corelib/text/qanystringview/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp918
-rw-r--r--tests/auto/corelib/text/qbytearray/.gitignore (renamed from tests/auto/corelib/tools/qbytearray/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qbytearray/CMakeLists.txt29
-rw-r--r--tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp2921
-rw-r--r--tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm74
-rw-r--r--tests/auto/corelib/text/qbytearray_large/.gitattributes (renamed from tests/auto/corelib/tools/qbytearray/.gitattributes)0
-rw-r--r--tests/auto/corelib/text/qbytearray_large/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/text/qbytearray_large/rfc3252.txt (renamed from tests/auto/corelib/tools/qbytearray/rfc3252.txt)0
-rw-r--r--tests/auto/corelib/text/qbytearray_large/tst_qbytearray_large.cpp224
-rw-r--r--tests/auto/corelib/text/qbytearrayapisymmetry/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp1561
-rw-r--r--tests/auto/corelib/text/qbytearraylist/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qbytearraylist/tst_qbytearraylist.cpp304
-rw-r--r--tests/auto/corelib/text/qbytearraymatcher/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/text/qbytearraymatcher/tst_qbytearraymatcher.cpp291
-rw-r--r--tests/auto/corelib/text/qbytearrayview/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp728
-rw-r--r--tests/auto/corelib/text/qbytedatabuffer/.gitignore (renamed from tests/auto/corelib/tools/qbytedatabuffer/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qbytedatabuffer/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp204
-rw-r--r--tests/auto/corelib/text/qchar/.gitignore (renamed from tests/auto/corelib/tools/qchar/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qchar/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/text/qchar/data/NormalizationTest.txt (renamed from tests/auto/corelib/tools/qchar/data/NormalizationTest.txt)0
-rw-r--r--tests/auto/corelib/text/qchar/tst_qchar.cpp1047
-rw-r--r--tests/auto/corelib/text/qcollator/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/text/qcollator/tst_qcollator.cpp354
-rw-r--r--tests/auto/corelib/text/qlatin1stringmatcher/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp567
-rw-r--r--tests/auto/corelib/text/qlatin1stringview/.gitignore1
-rw-r--r--tests/auto/corelib/text/qlatin1stringview/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/text/qlatin1stringview/tst_qlatin1stringview.cpp519
-rw-r--r--tests/auto/corelib/text/qlocale/.gitignore (renamed from tests/auto/corelib/tools/qlocale/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qlocale/CMakeLists.txt11
-rw-r--r--tests/auto/corelib/text/qlocale/syslocaleapp/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.cpp21
-rw-r--r--tests/auto/corelib/text/qlocale/test/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/text/qlocale/tst_qlocale.cpp4628
-rw-r--r--tests/auto/corelib/text/qregularexpression/.gitignore (renamed from tests/auto/corelib/tools/qregularexpression/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qregularexpression/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp2579
-rw-r--r--tests/auto/corelib/text/qstring/.gitignore (renamed from tests/auto/corelib/tools/qstring/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qstring/CMakeLists.txt47
-rw-r--r--tests/auto/corelib/text/qstring/double_data.h9998
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring.cpp9345
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring_mac.mm48
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring_wasm.cpp29
-rw-r--r--tests/auto/corelib/text/qstring_no_cast_from_bytearray/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/text/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp21
-rw-r--r--tests/auto/corelib/text/qstringapisymmetry/.gitignore (renamed from tests/auto/corelib/tools/qstringapisymmetry/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qstringapisymmetry/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp3655
-rw-r--r--tests/auto/corelib/text/qstringbuilder/CMakeLists.txt7
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder1/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp578
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp36
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder2/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp37
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder3/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp36
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder4/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp37
-rw-r--r--tests/auto/corelib/text/qstringconverter/CMakeLists.txt28
-rw-r--r--tests/auto/corelib/text/qstringconverter/euc_kr.txt1
-rw-r--r--tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp2839
-rw-r--r--tests/auto/corelib/text/qstringiterator/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp637
-rw-r--r--tests/auto/corelib/text/qstringlist/.gitignore (renamed from tests/auto/corelib/tools/qstringlist/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qstringlist/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp479
-rw-r--r--tests/auto/corelib/text/qstringmatcher/.gitignore (renamed from tests/auto/corelib/tools/qstringmatcher/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qstringmatcher/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/text/qstringmatcher/tst_qstringmatcher.cpp153
-rw-r--r--tests/auto/corelib/text/qstringtokenizer/.gitignore1
-rw-r--r--tests/auto/corelib/text/qstringtokenizer/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp140
-rw-r--r--tests/auto/corelib/text/qstringview/.gitignore (renamed from tests/auto/corelib/tools/qstringview/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qstringview/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/text/qstringview/tst_qstringview.cpp914
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/.gitignore (renamed from tests/auto/corelib/tools/qtextboundaryfinder/.gitignore)0
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/CMakeLists.txt24
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/data/GraphemeBreakTest.txt1215
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/data/LineBreakTest.txt10306
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/data/SentenceBreakTest.txt540
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.html248
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.txt1854
-rw-r--r--tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp861
-rw-r--r--tests/auto/corelib/text/qunicodetools/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp199
-rw-r--r--tests/auto/corelib/text/shared/test_number_shared.h105
-rw-r--r--tests/auto/corelib/thread/CMakeLists.txt47
-rw-r--r--tests/auto/corelib/thread/qatomicint/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qatomicint/qatomicint.pro4
-rw-r--r--tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp141
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char/char.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/int/int.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/long/long.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri11
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro18
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/schar/schar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/short/short.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp405
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uint/uint.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qatomicpointer/qatomicpointer.pro4
-rw-r--r--tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp231
-rw-r--r--tests/auto/corelib/thread/qfuture/CMakeLists.txt26
-rw-r--r--tests/auto/corelib/thread/qfuture/qfuture.pro5
-rw-r--r--tests/auto/corelib/thread/qfuture/tst_qfuture.cpp4091
-rw-r--r--tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro4
-rw-r--r--tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp69
-rw-r--r--tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qfuturewatcher/qfuturewatcher.pro4
-rw-r--r--tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp513
-rw-r--r--tests/auto/corelib/thread/qmutex/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/thread/qmutex/qmutex.pro5
-rw-r--r--tests/auto/corelib/thread/qmutex/tst_qmutex.cpp334
-rw-r--r--tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qmutexlocker/qmutexlocker.pro4
-rw-r--r--tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp131
-rw-r--r--tests/auto/corelib/thread/qpromise/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp158
-rw-r--r--tests/auto/corelib/thread/qpromise/tst_qpromise.cpp784
-rw-r--r--tests/auto/corelib/thread/qreadlocker/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qreadlocker/qreadlocker.pro4
-rw-r--r--tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp45
-rw-r--r--tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qreadwritelock/qreadwritelock.pro4
-rw-r--r--tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp344
-rw-r--r--tests/auto/corelib/thread/qresultstore/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/thread/qresultstore/qresultstore.pro5
-rw-r--r--tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp218
-rw-r--r--tests/auto/corelib/thread/qsemaphore/BLACKLIST10
-rw-r--r--tests/auto/corelib/thread/qsemaphore/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qsemaphore/qsemaphore.pro4
-rw-r--r--tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp121
-rw-r--r--tests/auto/corelib/thread/qthread/BLACKLIST3
-rw-r--r--tests/auto/corelib/thread/qthread/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/thread/qthread/qthread.pro9
-rw-r--r--tests/auto/corelib/thread/qthread/tst_qthread.cpp576
-rw-r--r--tests/auto/corelib/thread/qthreadonce/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp31
-rw-r--r--tests/auto/corelib/thread/qthreadonce/qthreadonce.h29
-rw-r--r--tests/auto/corelib/thread/qthreadonce/qthreadonce.pro12
-rw-r--r--tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp55
-rw-r--r--tests/auto/corelib/thread/qthreadpool/BLACKLIST3
-rw-r--r--tests/auto/corelib/thread/qthreadpool/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qthreadpool/qthreadpool.pro4
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp707
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt27
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp29
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro16
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/qthreadstorage.pro8
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/test/test.pro16
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp99
-rw-r--r--tests/auto/corelib/thread/qwaitcondition/BLACKLIST2
-rw-r--r--tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qwaitcondition/qwaitcondition.pro4
-rw-r--r--tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp96
-rw-r--r--tests/auto/corelib/thread/qwritelocker/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/thread/qwritelocker/qwritelocker.pro4
-rw-r--r--tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp45
-rw-r--r--tests/auto/corelib/thread/thread.pro27
-rw-r--r--tests/auto/corelib/time/CMakeLists.txt9
-rw-r--r--tests/auto/corelib/time/qcalendar/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp454
-rw-r--r--tests/auto/corelib/time/qdate/.gitignore (renamed from tests/auto/corelib/tools/qdate/.gitignore)0
-rw-r--r--tests/auto/corelib/time/qdate/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/time/qdate/tst_qdate.cpp1759
-rw-r--r--tests/auto/corelib/time/qdatetime/.gitignore (renamed from tests/auto/corelib/tools/qdatetime/.gitignore)0
-rw-r--r--tests/auto/corelib/time/qdatetime/CMakeLists.txt33
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp4841
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime_mac.mm47
-rw-r--r--tests/auto/corelib/time/qdatetimeparser/.gitignore1
-rw-r--r--tests/auto/corelib/time/qdatetimeparser/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/time/qdatetimeparser/tst_qdatetimeparser.cpp211
-rw-r--r--tests/auto/corelib/time/qtime/.gitignore (renamed from tests/auto/corelib/tools/qtime/.gitignore)0
-rw-r--r--tests/auto/corelib/time/qtime/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/time/qtime/tst_qtime.cpp691
-rw-r--r--tests/auto/corelib/time/qtimezone/CMakeLists.txt38
-rw-r--r--tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp1879
-rw-r--r--tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm43
-rw-r--r--tests/auto/corelib/tools/CMakeLists.txt58
-rw-r--r--tests/auto/corelib/tools/collections/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/collections/collections.pro7
-rw-r--r--tests/auto/corelib/tools/collections/tst_collections.cpp1128
-rw-r--r--tests/auto/corelib/tools/containerapisymmetry/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro7
-rw-r--r--tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp1257
-rw-r--r--tests/auto/corelib/tools/qalgorithms/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qalgorithms/qalgorithms.pro4
-rw-r--r--tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp936
-rw-r--r--tests/auto/corelib/tools/qarraydata/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qarraydata/qarraydata.pro5
-rw-r--r--tests/auto/corelib/tools/qarraydata/simplevector.h178
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp2033
-rw-r--r--tests/auto/corelib/tools/qarraydata_strictiterators/qarraydata_strictiterators.pro3
-rw-r--r--tests/auto/corelib/tools/qatomicscopedvaluerollback/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp164
-rw-r--r--tests/auto/corelib/tools/qbitarray/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qbitarray/qbitarray.pro4
-rw-r--r--tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp517
-rw-r--r--tests/auto/corelib/tools/qbytearray/android_testdata.qrc5
-rw-r--r--tests/auto/corelib/tools/qbytearray/qbytearray.pro16
-rw-r--r--tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp2344
-rw-r--r--tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm97
-rw-r--r--tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro4
-rw-r--r--tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp279
-rw-r--r--tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro5
-rw-r--r--tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp217
-rw-r--r--tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro4
-rw-r--r--tests/auto/corelib/tools/qbytedatabuffer/tst_qbytedatabuffer.cpp161
-rw-r--r--tests/auto/corelib/tools/qcache/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qcache/qcache.pro4
-rw-r--r--tests/auto/corelib/tools/qcache/tst_qcache.cpp166
-rw-r--r--tests/auto/corelib/tools/qchar/qchar.pro11
-rw-r--r--tests/auto/corelib/tools/qchar/testdata.qrc5
-rw-r--r--tests/auto/corelib/tools/qchar/tst_qchar.cpp1021
-rw-r--r--tests/auto/corelib/tools/qcollator/qcollator.pro6
-rw-r--r--tests/auto/corelib/tools/qcollator/tst_qcollator.cpp239
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/CMakeLists.txt21
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/qcommandlineparser.pro3
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/testhelper/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp40
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro5
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp258
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.pro4
-rw-r--r--tests/auto/corelib/tools/qcontiguouscache/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qcontiguouscache/qcontiguouscache.pro4
-rw-r--r--tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp87
-rw-r--r--tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt28
-rw-r--r--tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro11
-rw-r--r--tests/auto/corelib/tools/qcryptographichash/testdata.qrc6
-rw-r--r--tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp441
-rw-r--r--tests/auto/corelib/tools/qdate/qdate.pro4
-rw-r--r--tests/auto/corelib/tools/qdate/tst_qdate.cpp1505
-rw-r--r--tests/auto/corelib/tools/qdatetime/BLACKLIST2
-rw-r--r--tests/auto/corelib/tools/qdatetime/qdatetime.pro17
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp3508
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm70
-rw-r--r--tests/auto/corelib/tools/qduplicatetracker/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp230
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/qeasingcurve.pro4
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp116
-rw-r--r--tests/auto/corelib/tools/qexplicitlyshareddatapointer/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro4
-rw-r--r--tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp52
-rw-r--r--tests/auto/corelib/tools/qflatmap/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp732
-rw-r--r--tests/auto/corelib/tools/qfreelist/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qfreelist/qfreelist.pro5
-rw-r--r--tests/auto/corelib/tools/qfreelist/tst_qfreelist.cpp36
-rw-r--r--tests/auto/corelib/tools/qhash/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qhash/qhash.pro4
-rw-r--r--tests/auto/corelib/tools/qhash/tst_qhash.cpp2126
-rw-r--r--tests/auto/corelib/tools/qhash_strictiterators/qhash_strictiterators.pro3
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro4
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp516
-rw-r--r--tests/auto/corelib/tools/qhashseed/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp186
-rw-r--r--tests/auto/corelib/tools/qhashseed/tst_qhashseed_helper.cpp14
-rw-r--r--tests/auto/corelib/tools/qlatin1string/.gitignore1
-rw-r--r--tests/auto/corelib/tools/qlatin1string/qlatin1string.pro9
-rw-r--r--tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp225
-rw-r--r--tests/auto/corelib/tools/qline/CMakeLists.txt25
-rw-r--r--tests/auto/corelib/tools/qline/qline.pro5
-rw-r--r--tests/auto/corelib/tools/qline/tst_qline.cpp200
-rw-r--r--tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro4
-rw-r--r--tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp1107
-rw-r--r--tests/auto/corelib/tools/qlist/.gitignore2
-rw-r--r--tests/auto/corelib/tools/qlist/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/tools/qlist/qlist.pro4
-rw-r--r--tests/auto/corelib/tools/qlist/tst_qlist.cpp4832
-rw-r--r--tests/auto/corelib/tools/qlist_strictiterators/qlist_strictiterators.pro3
-rw-r--r--tests/auto/corelib/tools/qlocale/BLACKLIST2
-rw-r--r--tests/auto/corelib/tools/qlocale/qlocale.pro4
-rw-r--r--tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.cpp40
-rw-r--r--tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro7
-rw-r--r--tests/auto/corelib/tools/qlocale/test/test.pro19
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp2998
-rw-r--r--tests/auto/corelib/tools/qmacautoreleasepool/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro5
-rw-r--r--tests/auto/corelib/tools/qmacautoreleasepool/tst_qmacautoreleasepool.mm54
-rw-r--r--tests/auto/corelib/tools/qmakearray/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qmakearray/qmakearray.pro4
-rw-r--r--tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp31
-rw-r--r--tests/auto/corelib/tools/qmap/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qmap/qmap.pro4
-rw-r--r--tests/auto/corelib/tools/qmap/tst_qmap.cpp1703
-rw-r--r--tests/auto/corelib/tools/qmap_strictiterators/qmap_strictiterators.pro3
-rw-r--r--tests/auto/corelib/tools/qmargins/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qmargins/qmargins.pro4
-rw-r--r--tests/auto/corelib/tools/qmargins/tst_qmargins.cpp190
-rw-r--r--tests/auto/corelib/tools/qmessageauthenticationcode/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qmessageauthenticationcode/qmessageauthenticationcode.pro5
-rw-r--r--tests/auto/corelib/tools/qmessageauthenticationcode/tst_qmessageauthenticationcode.cpp198
-rw-r--r--tests/auto/corelib/tools/qoffsetstringarray/CMakeLists.txt26
-rw-r--r--tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp105
-rw-r--r--tests/auto/corelib/tools/qpair/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/tools/qpair/qpair.pro4
-rw-r--r--tests/auto/corelib/tools/qpair/tst_qpair.cpp167
-rw-r--r--tests/auto/corelib/tools/qpoint/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qpoint/qpoint.pro4
-rw-r--r--tests/auto/corelib/tools/qpoint/tst_qpoint.cpp154
-rw-r--r--tests/auto/corelib/tools/qpointf/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qpointf/qpointf.pro4
-rw-r--r--tests/auto/corelib/tools/qpointf/tst_qpointf.cpp125
-rw-r--r--tests/auto/corelib/tools/qqueue/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qqueue/qqueue.pro4
-rw-r--r--tests/auto/corelib/tools/qqueue/tst_qqueue.cpp31
-rw-r--r--tests/auto/corelib/tools/qrect/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qrect/qrect.pro4
-rw-r--r--tests/auto/corelib/tools/qrect/tst_qrect.cpp228
-rw-r--r--tests/auto/corelib/tools/qregexp/.gitignore1
-rw-r--r--tests/auto/corelib/tools/qregexp/qregexp.pro4
-rw-r--r--tests/auto/corelib/tools/qregexp/tst_qregexp.cpp1386
-rw-r--r--tests/auto/corelib/tools/qregularexpression/qregularexpression.pro4
-rw-r--r--tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp2254
-rw-r--r--tests/auto/corelib/tools/qringbuffer/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qringbuffer/qringbuffer.pro4
-rw-r--r--tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp52
-rw-r--r--tests/auto/corelib/tools/qscopedpointer/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro4
-rw-r--r--tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp145
-rw-r--r--tests/auto/corelib/tools/qscopedvaluerollback/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qscopedvaluerollback/qscopedvaluerollback.pro4
-rw-r--r--tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp44
-rw-r--r--tests/auto/corelib/tools/qscopeguard/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/tools/qscopeguard/qscopeguard.pro4
-rw-r--r--tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp163
-rw-r--r--tests/auto/corelib/tools/qset/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qset/qset.pro4
-rw-r--r--tests/auto/corelib/tools/qset/tst_qset.cpp557
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/CMakeLists.txt22
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/externaltests.cpp69
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/externaltests.h29
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/externaltests.pri6
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp31
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h31
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/nontracked.cpp31
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/nontracked.h29
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro17
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp747
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/wrapper.cpp29
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/wrapper.h29
-rw-r--r--tests/auto/corelib/tools/qsize/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qsize/qsize.pro4
-rw-r--r--tests/auto/corelib/tools/qsize/tst_qsize.cpp151
-rw-r--r--tests/auto/corelib/tools/qsizef/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qsizef/qsizef.pro4
-rw-r--r--tests/auto/corelib/tools/qsizef/tst_qsizef.cpp122
-rw-r--r--tests/auto/corelib/tools/qspan/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/tools/qspan/tst_qspan.cpp450
-rw-r--r--tests/auto/corelib/tools/qstl/CMakeLists.txt17
-rw-r--r--tests/auto/corelib/tools/qstl/qstl.pro4
-rw-r--r--tests/auto/corelib/tools/qstl/tst_qstl.cpp35
-rw-r--r--tests/auto/corelib/tools/qstring/double_data.h10023
-rw-r--r--tests/auto/corelib/tools/qstring/qstring.pro17
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp7044
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring_mac.mm68
-rw-r--r--tests/auto/corelib/tools/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro6
-rw-r--r--tests/auto/corelib/tools/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp46
-rw-r--r--tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro6
-rw-r--r--tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp1221
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder.pro6
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/qstringbuilder1.pro4
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp369
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp56
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/qstringbuilder2.pro4
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp57
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/qstringbuilder3.pro4
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp56
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/qstringbuilder4.pro4
-rw-r--r--tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp57
-rw-r--r--tests/auto/corelib/tools/qstringiterator/qstringiterator.pro5
-rw-r--r--tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp662
-rw-r--r--tests/auto/corelib/tools/qstringlist/qstringlist.pro4
-rw-r--r--tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp465
-rw-r--r--tests/auto/corelib/tools/qstringmatcher/qstringmatcher.pro5
-rw-r--r--tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp147
-rw-r--r--tests/auto/corelib/tools/qstringref/qstringref.pro4
-rw-r--r--tests/auto/corelib/tools/qstringref/tst_qstringref.cpp2158
-rw-r--r--tests/auto/corelib/tools/qstringview/qstringview.pro6
-rw-r--r--tests/auto/corelib/tools/qstringview/tst_qstringview.cpp639
-rw-r--r--tests/auto/corelib/tools/qtaggedpointer/.gitignore1
-rw-r--r--tests/auto/corelib/tools/qtaggedpointer/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp478
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt850
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt7344
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt530
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt2085
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/qtextboundaryfinder.pro11
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/testdata.qrc8
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp848
-rw-r--r--tests/auto/corelib/tools/qtime/qtime.pro4
-rw-r--r--tests/auto/corelib/tools/qtime/tst_qtime.cpp802
-rw-r--r--tests/auto/corelib/tools/qtimeline/BLACKLIST9
-rw-r--r--tests/auto/corelib/tools/qtimeline/CMakeLists.txt19
-rw-r--r--tests/auto/corelib/tools/qtimeline/qtimeline.pro4
-rw-r--r--tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp386
-rw-r--r--tests/auto/corelib/tools/qtimezone/BLACKLIST171
-rw-r--r--tests/auto/corelib/tools/qtimezone/qtimezone.pro12
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp1333
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm68
-rw-r--r--tests/auto/corelib/tools/qtyperevision/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/tools/qtyperevision/tst_qtyperevision.cpp202
-rw-r--r--tests/auto/corelib/tools/quniquehandle/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp308
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/qvarlengtharray.pro4
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp854
-rw-r--r--tests/auto/corelib/tools/qvector/.gitignore1
-rw-r--r--tests/auto/corelib/tools/qvector/qvector.pro5
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp2956
-rw-r--r--tests/auto/corelib/tools/qvector_strictiterators/qvector_strictiterators.pro3
-rw-r--r--tests/auto/corelib/tools/qversionnumber/CMakeLists.txt20
-rw-r--r--tests/auto/corelib/tools/qversionnumber/qversionnumber.pro6
-rw-r--r--tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp299
-rw-r--r--tests/auto/corelib/tools/tools.pro71
1873 files changed, 172018 insertions, 105347 deletions
diff --git a/tests/auto/corelib/CMakeLists.txt b/tests/auto/corelib/CMakeLists.txt
new file mode 100644
index 0000000000..7654fe0c20
--- /dev/null
+++ b/tests/auto/corelib/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(kernel)
+if(NOT UIKIT)
+ add_subdirectory(animation)
+ add_subdirectory(global)
+ add_subdirectory(io)
+ add_subdirectory(ipc)
+ add_subdirectory(itemmodels)
+ add_subdirectory(mimetypes)
+ add_subdirectory(plugin)
+ add_subdirectory(serialization)
+ add_subdirectory(text)
+ add_subdirectory(thread)
+ add_subdirectory(time)
+ add_subdirectory(tools)
+endif()
+add_subdirectory(platform)
diff --git a/tests/auto/corelib/animation/CMakeLists.txt b/tests/auto/corelib/animation/CMakeLists.txt
new file mode 100644
index 0000000000..85c121d243
--- /dev/null
+++ b/tests/auto/corelib/animation/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qabstractanimation)
+add_subdirectory(qanimationgroup)
+add_subdirectory(qparallelanimationgroup)
+add_subdirectory(qpauseanimation)
+add_subdirectory(qsequentialanimationgroup)
+add_subdirectory(qvariantanimation)
+if(TARGET Qt::Widgets)
+ add_subdirectory(qpropertyanimation)
+endif()
diff --git a/tests/auto/corelib/animation/animation.pro b/tests/auto/corelib/animation/animation.pro
deleted file mode 100644
index 30c98f4a11..0000000000
--- a/tests/auto/corelib/animation/animation.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qabstractanimation \
- qanimationgroup \
- qparallelanimationgroup \
- qpauseanimation \
- qpropertyanimation \
- qsequentialanimationgroup \
- qvariantanimation
-
-!qtHaveModule(widgets): SUBDIRS -= \
- qpropertyanimation
diff --git a/tests/auto/corelib/animation/qabstractanimation/CMakeLists.txt b/tests/auto/corelib/animation/qabstractanimation/CMakeLists.txt
new file mode 100644
index 0000000000..6e1ac655ba
--- /dev/null
+++ b/tests/auto/corelib/animation/qabstractanimation/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qabstractanimation Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractanimation LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qabstractanimation
+ SOURCES
+ tst_qabstractanimation.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/animation/qabstractanimation/qabstractanimation.pro b/tests/auto/corelib/animation/qabstractanimation/qabstractanimation.pro
deleted file mode 100644
index 32701c2c9c..0000000000
--- a/tests/auto/corelib/animation/qabstractanimation/qabstractanimation.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qabstractanimation
-QT = core testlib
-SOURCES = tst_qabstractanimation.cpp
diff --git a/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp b/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
index 66a752df5d..6c87428d75 100644
--- a/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
+++ b/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
@@ -1,35 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qabstractanimation.h>
#include <QtCore/qanimationgroup.h>
-#include <QtTest>
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
class tst_QAbstractAnimation : public QObject
{
@@ -48,6 +24,11 @@ private slots:
void avoidJumpAtStart();
void avoidJumpAtStartWithStop();
void avoidJumpAtStartWithRunning();
+ void stateBinding();
+ void loopCountBinding();
+ void currentTimeBinding();
+ void currentLoopBinding();
+ void directionBinding();
};
class TestableQAbstractAnimation : public QAbstractAnimation
@@ -56,10 +37,10 @@ class TestableQAbstractAnimation : public QAbstractAnimation
public:
TestableQAbstractAnimation() : m_duration(10) {}
- virtual ~TestableQAbstractAnimation() {};
+ virtual ~TestableQAbstractAnimation() override { }
- int duration() const { return m_duration; }
- virtual void updateCurrentTime(int) {}
+ int duration() const override { return m_duration; }
+ virtual void updateCurrentTime(int) override {}
void setDuration(int duration) { m_duration = duration; }
private:
@@ -70,8 +51,8 @@ class DummyQAnimationGroup : public QAnimationGroup
{
Q_OBJECT
public:
- int duration() const { return 10; }
- virtual void updateCurrentTime(int) {}
+ int duration() const override { return 10; }
+ virtual void updateCurrentTime(int) override {}
};
void tst_QAbstractAnimation::construction()
@@ -228,6 +209,89 @@ void tst_QAbstractAnimation::avoidJumpAtStartWithRunning()
QVERIFY(anim3.currentTime() < 50);
}
+void tst_QAbstractAnimation::stateBinding()
+{
+ TestableQAbstractAnimation animation;
+ QTestPrivate::testReadOnlyPropertyBasics(animation, QAbstractAnimation::Stopped,
+ QAbstractAnimation::Running, "state",
+ [&] { animation.start(); });
+}
+
+void tst_QAbstractAnimation::loopCountBinding()
+{
+ TestableQAbstractAnimation animation;
+ QTestPrivate::testReadWritePropertyBasics(animation, 42, 43, "loopCount");
+}
+
+void tst_QAbstractAnimation::currentTimeBinding()
+{
+ TestableQAbstractAnimation animation;
+
+ QProperty<int> currentTimeProperty;
+ animation.bindableCurrentTime().setBinding(Qt::makePropertyBinding(currentTimeProperty));
+ QCOMPARE(animation.currentTime(), currentTimeProperty);
+
+ // This should cancel the binding
+ animation.start();
+
+ currentTimeProperty = 5;
+ QVERIFY(animation.currentTime() != currentTimeProperty);
+
+ QTestPrivate::testReadWritePropertyBasics(animation, 6, 7, "currentTime");
+}
+
+void tst_QAbstractAnimation::currentLoopBinding()
+{
+ TestableQAbstractAnimation animation;
+
+ QTestPrivate::testReadOnlyPropertyBasics(animation, 0, 3, "currentLoop", [&] {
+ // Trigger an update of currentLoop
+ animation.setLoopCount(4);
+ // This brings us to the end of the animation, so currentLoop should be loopCount - 1
+ animation.setCurrentTime(42);
+ });
+}
+
+void tst_QAbstractAnimation::directionBinding()
+{
+ TestableQAbstractAnimation animation;
+ QTestPrivate::testReadWritePropertyBasics(animation, QAbstractAnimation::Backward,
+ QAbstractAnimation::Forward, "direction");
+
+ // setDirection() may trigger a currentLoop update. Make sure the observers
+ // are notified about direction and currentLoop changes only after a consistent
+ // state is reached.
+ QProperty<int> currLoopObserver;
+ currLoopObserver.setBinding([&] { return animation.currentLoop(); });
+
+ QProperty<QAbstractAnimation::Direction> directionObserver;
+ directionObserver.setBinding([&] { return animation.direction(); });
+
+ animation.setLoopCount(10);
+
+ bool currentLoopChanged = false;
+ auto currentLoopHandler = animation.bindableCurrentLoop().onValueChanged([&] {
+ QVERIFY(!currentLoopChanged);
+ QCOMPARE(currLoopObserver, 9);
+ QCOMPARE(directionObserver, QAbstractAnimation::Backward);
+ currentLoopChanged = true;
+ });
+
+ bool directionChanged = false;
+ auto directionHandler = animation.bindableDirection().onValueChanged([&] {
+ QVERIFY(!directionChanged);
+ QCOMPARE(currLoopObserver, 9);
+ QCOMPARE(directionObserver, QAbstractAnimation::Backward);
+ directionChanged = true;
+ });
+
+ QCOMPARE(animation.direction(), QAbstractAnimation::Forward);
+ // This will set currentLoop to 9
+ animation.setDirection(QAbstractAnimation::Backward);
+
+ QVERIFY(currentLoopChanged);
+ QVERIFY(directionChanged);
+}
QTEST_MAIN(tst_QAbstractAnimation)
diff --git a/tests/auto/corelib/animation/qanimationgroup/CMakeLists.txt b/tests/auto/corelib/animation/qanimationgroup/CMakeLists.txt
new file mode 100644
index 0000000000..a8160051a3
--- /dev/null
+++ b/tests/auto/corelib/animation/qanimationgroup/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qanimationgroup Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qanimationgroup LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qanimationgroup
+ SOURCES
+ tst_qanimationgroup.cpp
+)
diff --git a/tests/auto/corelib/animation/qanimationgroup/qanimationgroup.pro b/tests/auto/corelib/animation/qanimationgroup/qanimationgroup.pro
deleted file mode 100644
index f4b5747216..0000000000
--- a/tests/auto/corelib/animation/qanimationgroup/qanimationgroup.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qanimationgroup
-QT = core testlib
-SOURCES = tst_qanimationgroup.cpp
diff --git a/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp b/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp
index 2b7de50971..5345283252 100644
--- a/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp
+++ b/tests/auto/corelib/animation/qanimationgroup/tst_qanimationgroup.cpp
@@ -1,32 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QPauseAnimation>
+#include <QVariantAnimation>
+#include <QPropertyAnimation>
+#include <QSignalSpy>
#include <QtCore/qanimationgroup.h>
#include <QtCore/qsequentialanimationgroup.h>
@@ -79,12 +58,12 @@ class TestAnimation : public QVariantAnimation
{
Q_OBJECT
public:
- virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
+ virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)};
virtual void updateState(QAbstractAnimation::State oldState,
- QAbstractAnimation::State newState)
+ QAbstractAnimation::State newState) override
{
- Q_UNUSED(oldState)
- Q_UNUSED(newState)
+ Q_UNUSED(oldState);
+ Q_UNUSED(newState);
};
};
@@ -92,16 +71,16 @@ class UncontrolledAnimation : public QPropertyAnimation
{
Q_OBJECT
public:
- UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0)
+ UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = nullptr)
: QPropertyAnimation(target, propertyName, parent), id(0)
{
setDuration(250);
}
- int duration() const { return -1; /* not time driven */ }
+ int duration() const override { return -1; /* not time driven */ }
protected:
- void timerEvent(QTimerEvent *event)
+ void timerEvent(QTimerEvent *event) override
{
if (event->timerId() == id)
stop();
@@ -130,7 +109,7 @@ void tst_QAnimationGroup::emptyGroup()
QCOMPARE(group.state(), QAnimationGroup::Stopped);
group.start();
- QCOMPARE(groupStateChangedSpy.count(), 2);
+ QCOMPARE(groupStateChangedSpy.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(groupStateChangedSpy.at(0).first()),
QAnimationGroup::Running);
@@ -142,7 +121,7 @@ void tst_QAnimationGroup::emptyGroup()
QTest::ignoreMessage(QtWarningMsg, "QAbstractAnimation::pause: Cannot pause a stopped animation");
group.pause();
- QCOMPARE(groupStateChangedSpy.count(), 2);
+ QCOMPARE(groupStateChangedSpy.size(), 2);
QCOMPARE(group.state(), QAnimationGroup::Stopped);
group.start();
@@ -156,7 +135,7 @@ void tst_QAnimationGroup::emptyGroup()
group.stop();
- QCOMPARE(groupStateChangedSpy.count(), 4);
+ QCOMPARE(groupStateChangedSpy.size(), 4);
QCOMPARE(group.state(), QAnimationGroup::Stopped);
}
@@ -286,7 +265,8 @@ void tst_QAnimationGroup::setParentAutoAdd()
void tst_QAnimationGroup::beginNestedGroup()
{
- QAnimationGroup *parent = new QParallelAnimationGroup();
+ QParallelAnimationGroup group;
+ QAnimationGroup *parent = &group;
for (int i = 0; i < 10; ++i) {
if (i & 1) {
@@ -343,7 +323,8 @@ void tst_QAnimationGroup::addChildTwice()
void tst_QAnimationGroup::loopWithoutStartValue()
{
- QAnimationGroup *parent = new QSequentialAnimationGroup();
+ QSequentialAnimationGroup group;
+ QAnimationGroup *parent = &group;
QObject o;
o.setProperty("ole", 0);
QCOMPARE(o.property("ole").toInt(), 0);
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST
index b5b37b4498..9172149e33 100644
--- a/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST
+++ b/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST
@@ -1,3 +1,2 @@
[deleteChildrenWithRunningGroup]
-osx-10.12
-osx-10.13
+macos
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/CMakeLists.txt b/tests/auto/corelib/animation/qparallelanimationgroup/CMakeLists.txt
new file mode 100644
index 0000000000..c532ad7327
--- /dev/null
+++ b/tests/auto/corelib/animation/qparallelanimationgroup/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qparallelanimationgroup Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qparallelanimationgroup LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qparallelanimationgroup
+ SOURCES
+ tst_qparallelanimationgroup.cpp
+)
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro b/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro
deleted file mode 100644
index 5b4c6ab90a..0000000000
--- a/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qparallelanimationgroup
-QT = core testlib
-SOURCES = tst_qparallelanimationgroup.cpp
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
index 18a6268ec0..c47ce53364 100644
--- a/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
+++ b/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
@@ -1,34 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QVariantAnimation>
+#include <QPropertyAnimation>
+#include <QSignalSpy>
#include <QtCore/qparallelanimationgroup.h>
+#include <QtCore/qscopeguard.h>
Q_DECLARE_METATYPE(QAbstractAnimation::State)
@@ -92,12 +71,12 @@ class TestAnimation : public QVariantAnimation
{
Q_OBJECT
public:
- virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
+ virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)};
virtual void updateState(QAbstractAnimation::State newState,
- QAbstractAnimation::State oldState)
+ QAbstractAnimation::State oldState) override
{
- Q_UNUSED(oldState)
- Q_UNUSED(newState)
+ Q_UNUSED(oldState);
+ Q_UNUSED(newState);
};
};
@@ -108,15 +87,15 @@ public:
TestAnimation2(QAbstractAnimation *animation) : QVariantAnimation(animation) {}
TestAnimation2(int duration, QAbstractAnimation *animation) : QVariantAnimation(animation), m_duration(duration) {}
- virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
+ virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)};
virtual void updateState(QAbstractAnimation::State newState,
- QAbstractAnimation::State oldState)
+ QAbstractAnimation::State oldState) override
{
- Q_UNUSED(oldState)
- Q_UNUSED(newState)
+ Q_UNUSED(oldState);
+ Q_UNUSED(newState);
};
- virtual int duration() const {
+ virtual int duration() const override {
return m_duration;
}
private:
@@ -127,17 +106,17 @@ class UncontrolledAnimation : public QPropertyAnimation
{
Q_OBJECT
public:
- UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0)
+ UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = nullptr)
: QPropertyAnimation(target, propertyName, parent), id(0)
{
setDuration(250);
setEndValue(0);
}
- int duration() const { return -1; /* not time driven */ }
+ int duration() const override { return -1; /* not time driven */ }
protected:
- void timerEvent(QTimerEvent *event)
+ void timerEvent(QTimerEvent *event) override
{
if (event->timerId() == id)
stop();
@@ -256,38 +235,38 @@ void tst_QParallelAnimationGroup::stateChanged()
//first; let's start forward
group.start();
//all the animations should be started
- QCOMPARE(spy1.count(), 1);
+ QCOMPARE(spy1.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy1.last().first()), TestAnimation::Running);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy2.last().first()), TestAnimation::Running);
- QCOMPARE(spy3.count(), 1);
+ QCOMPARE(spy3.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy3.last().first()), TestAnimation::Running);
- QCOMPARE(spy4.count(), 1);
+ QCOMPARE(spy4.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy4.last().first()), TestAnimation::Running);
group.setCurrentTime(1500); //anim1 should be finished
QCOMPARE(group.state(), QAnimationGroup::Running);
- QCOMPARE(spy1.count(), 2);
+ QCOMPARE(spy1.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy1.last().first()), TestAnimation::Stopped);
- QCOMPARE(spy2.count(), 1); //no change
- QCOMPARE(spy3.count(), 1); //no change
- QCOMPARE(spy4.count(), 1); //no change
+ QCOMPARE(spy2.size(), 1); //no change
+ QCOMPARE(spy3.size(), 1); //no change
+ QCOMPARE(spy4.size(), 1); //no change
group.setCurrentTime(2500); //anim2 should be finished
QCOMPARE(group.state(), QAnimationGroup::Running);
- QCOMPARE(spy1.count(), 2); //no change
- QCOMPARE(spy2.count(), 2);
+ QCOMPARE(spy1.size(), 2); //no change
+ QCOMPARE(spy2.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy2.last().first()), TestAnimation::Stopped);
- QCOMPARE(spy3.count(), 1); //no change
- QCOMPARE(spy4.count(), 1); //no change
+ QCOMPARE(spy3.size(), 1); //no change
+ QCOMPARE(spy4.size(), 1); //no change
group.setCurrentTime(3500); //everything should be finished
QCOMPARE(group.state(), QAnimationGroup::Stopped);
- QCOMPARE(spy1.count(), 2); //no change
- QCOMPARE(spy2.count(), 2); //no change
- QCOMPARE(spy3.count(), 2);
+ QCOMPARE(spy1.size(), 2); //no change
+ QCOMPARE(spy2.size(), 2); //no change
+ QCOMPARE(spy3.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy3.last().first()), TestAnimation::Stopped);
- QCOMPARE(spy4.count(), 2);
+ QCOMPARE(spy4.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy4.last().first()), TestAnimation::Stopped);
//cleanup
@@ -302,38 +281,38 @@ void tst_QParallelAnimationGroup::stateChanged()
//only anim3 and anim4 should be started
QCOMPARE(group.state(), QAnimationGroup::Running);
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 0);
- QCOMPARE(spy3.count(), 1);
+ QCOMPARE(spy1.size(), 0);
+ QCOMPARE(spy2.size(), 0);
+ QCOMPARE(spy3.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy3.last().first()), TestAnimation::Running);
- QCOMPARE(spy4.count(), 1);
+ QCOMPARE(spy4.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy4.last().first()), TestAnimation::Running);
group.setCurrentTime(1500); //anim2 should be started
QCOMPARE(group.state(), QAnimationGroup::Running);
- QCOMPARE(spy1.count(), 0); //no change
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy1.size(), 0); //no change
+ QCOMPARE(spy2.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy2.last().first()), TestAnimation::Running);
- QCOMPARE(spy3.count(), 1); //no change
- QCOMPARE(spy4.count(), 1); //no change
+ QCOMPARE(spy3.size(), 1); //no change
+ QCOMPARE(spy4.size(), 1); //no change
group.setCurrentTime(500); //anim1 is finally also started
QCOMPARE(group.state(), QAnimationGroup::Running);
- QCOMPARE(spy1.count(), 1);
+ QCOMPARE(spy1.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy1.last().first()), TestAnimation::Running);
- QCOMPARE(spy2.count(), 1); //no change
- QCOMPARE(spy3.count(), 1); //no change
- QCOMPARE(spy4.count(), 1); //no change
+ QCOMPARE(spy2.size(), 1); //no change
+ QCOMPARE(spy3.size(), 1); //no change
+ QCOMPARE(spy4.size(), 1); //no change
group.setCurrentTime(0); //everything should be stopped
QCOMPARE(group.state(), QAnimationGroup::Stopped);
- QCOMPARE(spy1.count(), 2);
+ QCOMPARE(spy1.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy1.last().first()), TestAnimation::Stopped);
- QCOMPARE(spy2.count(), 2);
+ QCOMPARE(spy2.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy2.last().first()), TestAnimation::Stopped);
- QCOMPARE(spy3.count(), 2);
+ QCOMPARE(spy3.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy3.last().first()), TestAnimation::Stopped);
- QCOMPARE(spy4.count(), 2);
+ QCOMPARE(spy4.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy4.last().first()), TestAnimation::Stopped);
}
@@ -427,8 +406,8 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup()
QVERIFY(groupStateChangedSpy.isValid());
QVERIFY(childStateChangedSpy.isValid());
- QCOMPARE(groupStateChangedSpy.count(), 0);
- QCOMPARE(childStateChangedSpy.count(), 0);
+ QCOMPARE(groupStateChangedSpy.size(), 0);
+ QCOMPARE(childStateChangedSpy.size(), 0);
QCOMPARE(group.state(), QAnimationGroup::Stopped);
QCOMPARE(anim.state(), QAnimationGroup::Stopped);
@@ -439,8 +418,8 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup()
QCOMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(anim.state(), QAnimationGroup::Running);
- QCOMPARE(groupStateChangedSpy.count(), 1);
- QCOMPARE(childStateChangedSpy.count(), 1);
+ QCOMPARE(groupStateChangedSpy.size(), 1);
+ QCOMPARE(childStateChangedSpy.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(groupStateChangedSpy.at(0).first()),
QAnimationGroup::Running);
@@ -450,8 +429,8 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup()
// starting directly a running child will not have any effect
anim.start();
- QCOMPARE(groupStateChangedSpy.count(), 1);
- QCOMPARE(childStateChangedSpy.count(), 1);
+ QCOMPARE(groupStateChangedSpy.size(), 1);
+ QCOMPARE(childStateChangedSpy.size(), 1);
anim.pause();
@@ -594,8 +573,8 @@ void tst_QParallelAnimationGroup::startGroupWithRunningChild()
QVERIFY(stateChangedSpy1.isValid());
QVERIFY(stateChangedSpy2.isValid());
- QCOMPARE(stateChangedSpy1.count(), 0);
- QCOMPARE(stateChangedSpy2.count(), 0);
+ QCOMPARE(stateChangedSpy1.size(), 0);
+ QCOMPARE(stateChangedSpy2.size(), 0);
QCOMPARE(group.state(), QAnimationGroup::Stopped);
QCOMPARE(anim1.state(), QAnimationGroup::Stopped);
QCOMPARE(anim2.state(), QAnimationGroup::Stopped);
@@ -620,13 +599,13 @@ void tst_QParallelAnimationGroup::startGroupWithRunningChild()
group.start();
- QCOMPARE(stateChangedSpy1.count(), 3);
+ QCOMPARE(stateChangedSpy1.size(), 3);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy1.at(1).first()),
QAnimationGroup::Stopped);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy1.at(2).first()),
QAnimationGroup::Running);
- QCOMPARE(stateChangedSpy2.count(), 4);
+ QCOMPARE(stateChangedSpy2.size(), 4);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy2.at(2).first()),
QAnimationGroup::Stopped);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy2.at(3).first()),
@@ -677,22 +656,22 @@ void tst_QParallelAnimationGroup::zeroDurationAnimation()
group.addAnimation(&anim1);
group.addAnimation(&anim2);
group.addAnimation(&anim3);
- QCOMPARE(stateChangedSpy1.count(), 0);
+ QCOMPARE(stateChangedSpy1.size(), 0);
group.start();
- QCOMPARE(stateChangedSpy1.count(), 2);
- QCOMPARE(finishedSpy1.count(), 1);
+ QCOMPARE(stateChangedSpy1.size(), 2);
+ QCOMPARE(finishedSpy1.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy1.at(0).first()),
QAnimationGroup::Running);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy1.at(1).first()),
QAnimationGroup::Stopped);
- QCOMPARE(stateChangedSpy2.count(), 1);
- QCOMPARE(finishedSpy2.count(), 0);
+ QCOMPARE(stateChangedSpy2.size(), 1);
+ QCOMPARE(finishedSpy2.size(), 0);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy1.at(0).first()),
QAnimationGroup::Running);
- QCOMPARE(stateChangedSpy3.count(), 1);
- QCOMPARE(finishedSpy3.count(), 0);
+ QCOMPARE(stateChangedSpy3.size(), 1);
+ QCOMPARE(finishedSpy3.size(), 0);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy3.at(0).first()),
QAnimationGroup::Running);
@@ -710,21 +689,21 @@ void tst_QParallelAnimationGroup::zeroDurationAnimation()
stateChangedSpy3.clear();
group.start();
- QCOMPARE(stateChangedSpy1.count(), 2);
- QCOMPARE(stateChangedSpy2.count(), 1);
- QCOMPARE(stateChangedSpy3.count(), 1);
+ QCOMPARE(stateChangedSpy1.size(), 2);
+ QCOMPARE(stateChangedSpy2.size(), 1);
+ QCOMPARE(stateChangedSpy3.size(), 1);
group.setCurrentTime(50);
- QCOMPARE(stateChangedSpy1.count(), 2);
- QCOMPARE(stateChangedSpy2.count(), 1);
- QCOMPARE(stateChangedSpy3.count(), 2);
+ QCOMPARE(stateChangedSpy1.size(), 2);
+ QCOMPARE(stateChangedSpy2.size(), 1);
+ QCOMPARE(stateChangedSpy3.size(), 2);
group.setCurrentTime(150);
- QCOMPARE(stateChangedSpy1.count(), 4);
- QCOMPARE(stateChangedSpy2.count(), 3);
- QCOMPARE(stateChangedSpy3.count(), 4);
+ QCOMPARE(stateChangedSpy1.size(), 4);
+ QCOMPARE(stateChangedSpy2.size(), 3);
+ QCOMPARE(stateChangedSpy3.size(), 4);
group.setCurrentTime(50);
- QCOMPARE(stateChangedSpy1.count(), 6);
- QCOMPARE(stateChangedSpy2.count(), 5);
- QCOMPARE(stateChangedSpy3.count(), 6);
+ QCOMPARE(stateChangedSpy1.size(), 6);
+ QCOMPARE(stateChangedSpy2.size(), 5);
+ QCOMPARE(stateChangedSpy3.size(), 6);
}
@@ -756,7 +735,7 @@ void tst_QParallelAnimationGroup::stopUncontrolledAnimations()
group.start();
- QCOMPARE(stateChangedSpy.count(), 2);
+ QCOMPARE(stateChangedSpy.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy.at(0).first()),
QAnimationGroup::Running);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy.at(1).first()),
@@ -787,7 +766,7 @@ struct AnimState {
int state;
};
QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(AnimState, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(AnimState, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
#define Running QAbstractAnimation::Running
@@ -950,6 +929,7 @@ void tst_QParallelAnimationGroup::autoAdd()
test = static_cast<TestAnimation2*>(group.animationAt(0));
test->setParent(0); // remove the last one (with duration = 250)
+ const auto deleteParentlessObject = qScopeGuard([test] { delete test; });
QCOMPARE(test->group(), static_cast<QAnimationGroup*>(0));
QCOMPARE(group.duration(), 0);
}
@@ -965,7 +945,7 @@ void tst_QParallelAnimationGroup::pauseResume()
QTest::qWait(100);
QCOMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
const int currentTime = group.currentLoopTime();
QCOMPARE(anim->currentLoopTime(), currentTime);
@@ -975,7 +955,7 @@ void tst_QParallelAnimationGroup::pauseResume()
QCOMPARE(group.currentLoopTime(), currentTime);
QCOMPARE(anim->state(), QAnimationGroup::Paused);
QCOMPARE(anim->currentLoopTime(), currentTime);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
group.resume();
@@ -983,21 +963,21 @@ void tst_QParallelAnimationGroup::pauseResume()
QCOMPARE(group.currentLoopTime(), currentTime);
QCOMPARE(anim->state(), QAnimationGroup::Running);
QCOMPARE(anim->currentLoopTime(), currentTime);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
group.stop();
spy.clear();
new TestAnimation2(500, &group);
group.start();
- QCOMPARE(spy.count(), 1); //the animation should have been started
+ QCOMPARE(spy.size(), 1); //the animation should have been started
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy.last().first()), TestAnimation::Running);
group.setCurrentTime(250); //end of first animation
- QCOMPARE(spy.count(), 2); //the animation should have been stopped
+ QCOMPARE(spy.size(), 2); //the animation should have been stopped
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(spy.last().first()), TestAnimation::Stopped);
group.pause();
- QCOMPARE(spy.count(), 2); //this shouldn't have changed
+ QCOMPARE(spy.size(), 2); //this shouldn't have changed
group.resume();
- QCOMPARE(spy.count(), 2); //this shouldn't have changed
+ QCOMPARE(spy.size(), 2); //this shouldn't have changed
}
// This is a regression test for QTBUG-8910, where a crash occurred when the
diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
index e223ec82e2..714df08b18 100644
--- a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
+++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
@@ -1,6 +1,6 @@
[pauseAndPropertyAnimations]
-*
+macos
[multipleSequentialGroups]
-osx
+macos
[noTimerUpdates]
-osx
+macos
diff --git a/tests/auto/corelib/animation/qpauseanimation/CMakeLists.txt b/tests/auto/corelib/animation/qpauseanimation/CMakeLists.txt
new file mode 100644
index 0000000000..aa0cb1edc5
--- /dev/null
+++ b/tests/auto/corelib/animation/qpauseanimation/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpauseanimation Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpauseanimation LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qpauseanimation
+ SOURCES
+ tst_qpauseanimation.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro b/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro
deleted file mode 100644
index 7f19bc7545..0000000000
--- a/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qpauseanimation
-QT = core-private testlib
-SOURCES = tst_qpauseanimation.cpp
diff --git a/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp
index 290c2abc98..8b11656706 100644
--- a/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp
+++ b/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp
@@ -1,40 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
#include <QtCore/qpauseanimation.h>
#include <QtCore/qpropertyanimation.h>
#include <QtCore/qsequentialanimationgroup.h>
+#include <QParallelAnimationGroup>
+
#include <private/qabstractanimation_p.h>
-#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX)
# define BAD_TIMER_RESOLUTION
#endif
@@ -56,7 +34,7 @@ class TestablePauseAnimation : public QPauseAnimation
{
Q_OBJECT
public:
- TestablePauseAnimation(QObject *parent = 0)
+ TestablePauseAnimation(QObject *parent = nullptr)
: QPauseAnimation(parent),
m_updateCurrentTimeCount(0)
{
@@ -64,7 +42,7 @@ public:
int m_updateCurrentTimeCount;
protected:
- void updateCurrentTime(int currentTime)
+ void updateCurrentTime(int currentTime) override
{
QPauseAnimation::updateCurrentTime(currentTime);
++m_updateCurrentTimeCount;
@@ -103,6 +81,7 @@ private slots:
void sequentialGroupWithPause();
void multipleSequentialGroups();
void zeroDuration();
+ void bindings();
};
void tst_QPauseAnimation::initTestCase()
@@ -440,5 +419,51 @@ void tst_QPauseAnimation::zeroDuration()
QCOMPARE(animation.m_updateCurrentTimeCount, 1);
}
+void tst_QPauseAnimation::bindings()
+{
+ TestablePauseAnimation animation;
+
+ QProperty<int> duration;
+ animation.bindableDuration().setBinding(Qt::makePropertyBinding(duration));
+
+ duration = 42;
+ QCOMPARE(animation.duration(), 42);
+
+ // negative values must be ignored
+ QTest::ignoreMessage(QtWarningMsg,
+ "QPauseAnimation::setDuration: cannot set a negative duration");
+ duration = -1;
+ QCOMPARE(animation.duration(), 42);
+ QCOMPARE(duration, -1);
+
+ // Setting an invalid value shouldn't clear the binding
+ QTest::ignoreMessage(QtWarningMsg,
+ "QPauseAnimation::setDuration: cannot set a negative duration");
+ animation.setDuration(-1);
+ QVERIFY(animation.bindableDuration().hasBinding());
+ QCOMPARE(animation.duration(), 42);
+
+ QProperty<int> durationObserver;
+ durationObserver.setBinding(animation.bindableDuration().makeBinding());
+
+ animation.setDuration(46);
+ QCOMPARE(durationObserver, 46);
+
+ // Setting a valid value should clear the binding
+ QVERIFY(!animation.bindableDuration().hasBinding());
+
+ // Setting an invalid value also doesn't affect the observer
+ QTest::ignoreMessage(QtWarningMsg,
+ "QPauseAnimation::setDuration: cannot set a negative duration");
+ animation.setDuration(-1);
+ QCOMPARE(durationObserver, 46);
+
+ QTestPrivate::testReadWritePropertyBasics(animation, 10, 20, "duration");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QPauseAnimation::duration");
+ return;
+ }
+}
+
QTEST_MAIN(tst_QPauseAnimation)
#include "tst_qpauseanimation.moc"
diff --git a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST
deleted file mode 100644
index a8719b241a..0000000000
--- a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST
+++ /dev/null
@@ -1,6 +0,0 @@
-[statesAndSignals:normal animation]
-windows
-[startBackwardWithoutEndValue]
-windows
-[startWithoutStartValue]
-osx
diff --git a/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt b/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt
new file mode 100644
index 0000000000..38383aff46
--- /dev/null
+++ b/tests/auto/corelib/animation/qpropertyanimation/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpropertyanimation Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpropertyanimation LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qpropertyanimation
+ SOURCES
+ tst_qpropertyanimation.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::Widgets
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro b/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro
deleted file mode 100644
index 72a36876b7..0000000000
--- a/tests/auto/corelib/animation/qpropertyanimation/qpropertyanimation.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qpropertyanimation
-QT = core gui widgets testlib core-private
-SOURCES = tst_qpropertyanimation.cpp
diff --git a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp
index 41a051a719..03755fa7ab 100644
--- a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp
+++ b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp
@@ -1,36 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
+#include <QSignalSpy>
+#include <QAnimationGroup>
+#include <QSequentialAnimationGroup>
#include <QtCore/qpropertyanimation.h>
#include <QtCore/qvariantanimation.h>
#include <private/qabstractanimation_p.h>
-#include <QtGui/qtouchdevice.h>
+#include <QtGui/qpointingdevice.h>
#include <QtWidgets/qwidget.h>
Q_DECLARE_METATYPE(QAbstractAnimation::State)
@@ -39,10 +18,10 @@ class UncontrolledAnimation : public QPropertyAnimation
{
Q_OBJECT
public:
- int duration() const { return -1; /* not time driven */ }
+ int duration() const override { return -1; /* not time driven */ }
protected:
- void updateCurrentTime(int currentTime)
+ void updateCurrentTime(int currentTime) override
{
QPropertyAnimation::updateCurrentTime(currentTime);
if (currentTime >= QPropertyAnimation::duration() || currentLoop() >= 1)
@@ -65,7 +44,7 @@ private:
class DummyPropertyAnimation : public QPropertyAnimation
{
public:
- DummyPropertyAnimation(QObject *parent = 0) : QPropertyAnimation(parent)
+ DummyPropertyAnimation(QObject *parent = nullptr) : QPropertyAnimation(parent)
{
setTargetObject(&o);
this->setPropertyName("x");
@@ -115,10 +94,10 @@ public:
static const int interval = 1000/60;
qint64 until = m_elapsed + ms;
while (m_elapsed < until) {
- advanceAnimation(m_elapsed);
+ advanceAnimation();
m_elapsed += interval;
}
- advanceAnimation(m_elapsed);
+ advanceAnimation();
// This is to make sure that animations that were started with DeleteWhenStopped
// will actually delete themselves within the test function.
// Normally, they won't be deleted until the main event loop is processed.
@@ -190,6 +169,7 @@ private slots:
void totalDuration();
void zeroLoopCount();
void recursiveAnimations();
+ void bindings();
};
void tst_QPropertyAnimation::initTestCase()
@@ -286,16 +266,16 @@ void tst_QPropertyAnimation::statesAndSignals_data()
void tst_QPropertyAnimation::statesAndSignals()
{
QFETCH(bool, uncontrolled);
- QPropertyAnimation *anim;
+ std::unique_ptr<QPropertyAnimation> anim;
if (uncontrolled)
- anim = new UncontrolledAnimation;
+ anim = std::make_unique<UncontrolledAnimation>();
else
- anim = new DummyPropertyAnimation;
+ anim = std::make_unique<DummyPropertyAnimation>();
anim->setDuration(100);
- QSignalSpy finishedSpy(anim, &QPropertyAnimation::finished);
- QSignalSpy runningSpy(anim, &QPropertyAnimation::stateChanged);
- QSignalSpy currentLoopSpy(anim, &QPropertyAnimation::currentLoopChanged);
+ QSignalSpy finishedSpy(anim.get(), &QPropertyAnimation::finished);
+ QSignalSpy runningSpy(anim.get(), &QPropertyAnimation::stateChanged);
+ QSignalSpy currentLoopSpy(anim.get(), &QPropertyAnimation::currentLoopChanged);
QVERIFY(finishedSpy.isValid());
QVERIFY(runningSpy.isValid());
@@ -303,9 +283,9 @@ void tst_QPropertyAnimation::statesAndSignals()
anim->setCurrentTime(1);
anim->setCurrentTime(100);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(runningSpy.count(), 0);
- QCOMPARE(currentLoopSpy.count(), 0);
+ QCOMPARE(finishedSpy.size(), 0);
+ QCOMPARE(runningSpy.size(), 0);
+ QCOMPARE(currentLoopSpy.size(), 0);
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
anim->setLoopCount(3);
@@ -314,26 +294,26 @@ void tst_QPropertyAnimation::statesAndSignals()
if (uncontrolled)
QSKIP("Uncontrolled animations don't handle looping");
- QCOMPARE(currentLoopSpy.count(), 1);
+ QCOMPARE(currentLoopSpy.size(), 1);
QCOMPARE(anim->currentLoop(), 1);
anim->setCurrentTime(0);
- QCOMPARE(currentLoopSpy.count(), 2);
+ QCOMPARE(currentLoopSpy.size(), 2);
QCOMPARE(anim->currentLoop(), 0);
anim->start();
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QCOMPARE(runningSpy.count(), 1); //anim must have started
+ QCOMPARE(runningSpy.size(), 1); //anim must have started
QCOMPARE(anim->currentLoop(), 0);
runningSpy.clear();
anim->stop();
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
- QCOMPARE(runningSpy.count(), 1); //anim must have stopped
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 1); //anim must have stopped
+ QCOMPARE(finishedSpy.size(), 0);
QCOMPARE(anim->currentLoopTime(), 0);
QCOMPARE(anim->currentLoop(), 0);
- QCOMPARE(currentLoopSpy.count(), 2);
+ QCOMPARE(currentLoopSpy.size(), 2);
runningSpy.clear();
{
@@ -341,33 +321,31 @@ void tst_QPropertyAnimation::statesAndSignals()
anim->start();
timeDriver.wait(1000);
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
- QCOMPARE(runningSpy.count(), 2); //started and stopped again
+ QCOMPARE(runningSpy.size(), 2); //started and stopped again
runningSpy.clear();
- QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(finishedSpy.size(), 1);
QCOMPARE(anim->currentLoopTime(), 100);
QCOMPARE(anim->currentLoop(), 2);
- QCOMPARE(currentLoopSpy.count(), 4);
+ QCOMPARE(currentLoopSpy.size(), 4);
anim->start(); // auto-rewinds
QCOMPARE(anim->state(), QAnimationGroup::Running);
QCOMPARE(anim->currentTime(), 0);
QCOMPARE(anim->currentLoop(), 0);
- QCOMPARE(currentLoopSpy.count(), 5);
- QCOMPARE(runningSpy.count(), 1); // anim has started
- QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(currentLoopSpy.size(), 5);
+ QCOMPARE(runningSpy.size(), 1); // anim has started
+ QCOMPARE(finishedSpy.size(), 1);
QCOMPARE(anim->currentLoop(), 0);
runningSpy.clear();
timeDriver.wait(1000);
- QCOMPARE(currentLoopSpy.count(), 7);
+ QCOMPARE(currentLoopSpy.size(), 7);
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
QCOMPARE(anim->currentLoop(), 2);
- QCOMPARE(runningSpy.count(), 1); // anim has stopped
- QCOMPARE(finishedSpy.count(), 2);
+ QCOMPARE(runningSpy.size(), 1); // anim has stopped
+ QCOMPARE(finishedSpy.size(), 2);
QCOMPARE(anim->currentLoopTime(), 100);
-
- delete anim;
}
}
@@ -386,8 +364,8 @@ void tst_QPropertyAnimation::deletion1()
anim->setEndValue(20);
anim->setDuration(200);
anim->start();
- QCOMPARE(runningSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 1);
+ QCOMPARE(finishedSpy.size(), 0);
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
@@ -397,8 +375,8 @@ void tst_QPropertyAnimation::deletion1()
timeDriver.wait(150);
QVERIFY(anim); //The animation should not have been deleted
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
- QCOMPARE(runningSpy.count(), 2);
- QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(runningSpy.size(), 2);
+ QCOMPARE(finishedSpy.size(), 1);
anim->start(QVariantAnimation::DeleteWhenStopped);
QVERIFY(anim);
@@ -407,8 +385,8 @@ void tst_QPropertyAnimation::deletion1()
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
timeDriver.wait(150);
- QCOMPARE(runningSpy.count(), 4);
- QCOMPARE(finishedSpy.count(), 2);
+ QCOMPARE(runningSpy.size(), 4);
+ QCOMPARE(finishedSpy.size(), 2);
QVERIFY(!anim); //The animation must have been deleted
delete object;
}
@@ -416,9 +394,10 @@ void tst_QPropertyAnimation::deletion1()
void tst_QPropertyAnimation::deletion2()
{
TestAnimationDriver timeDriver;
- //test that the animation get deleted if the object is deleted
+ // test that the animation does not get deleted if the object is deleted
QObject *object = new QWidget;
QPointer<QPropertyAnimation> anim = new QPropertyAnimation(object,"minimumWidth");
+ QVERIFY(anim->parent() != object);
anim->setStartValue(10);
anim->setEndValue(20);
anim->setDuration(200);
@@ -438,21 +417,25 @@ void tst_QPropertyAnimation::deletion2()
QVERIFY(anim);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QCOMPARE(runningSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 1);
+ QCOMPARE(finishedSpy.size(), 0);
//we can't call deletaLater directly because the delete would only happen in the next loop of _this_ event loop
QTimer::singleShot(0, object, SLOT(deleteLater()));
timeDriver.wait(50);
+ QVERIFY(anim);
QVERIFY(!anim->targetObject());
+
+ delete anim;
}
void tst_QPropertyAnimation::deletion3()
{
//test that the stopped signal is emit when the animation is destroyed
TestAnimationDriver timeDriver;
- QObject *object = new QWidget;
+ QWidget w;
+ QObject *object = &w;
QPropertyAnimation *anim = new QPropertyAnimation(object,"minimumWidth");
anim->setStartValue(10);
anim->setEndValue(20);
@@ -468,11 +451,11 @@ void tst_QPropertyAnimation::deletion3()
timeDriver.wait(50);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QCOMPARE(runningSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 1);
+ QCOMPARE(finishedSpy.size(), 0);
delete anim;
- QCOMPARE(runningSpy.count(), 2);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 2);
+ QCOMPARE(finishedSpy.size(), 0);
}
void tst_QPropertyAnimation::duration0()
@@ -508,7 +491,7 @@ public:
void setOle(int v) { o = v; values << v; }
int o;
- QVector<int> values;
+ QList<int> values;
};
void tst_QPropertyAnimation::noStartValue()
@@ -564,7 +547,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning()
QVERIFY(runningSpy.isValid());
anim->start(QVariantAnimation::DeleteWhenStopped);
timeDriver.wait(anim->duration());
- QCOMPARE(runningSpy.count(), 2); //started and then stopped
+ QCOMPARE(runningSpy.size(), 2); //started and then stopped
QVERIFY(!anim);
}
{
@@ -576,7 +559,7 @@ void tst_QPropertyAnimation::startWhenAnotherIsRunning()
timeDriver.wait(anim->duration()/2);
QPointer<QVariantAnimation> anim2 = new QPropertyAnimation(&o, "ole");
anim2->setEndValue(100);
- QCOMPARE(runningSpy.count(), 1);
+ QCOMPARE(runningSpy.size(), 1);
QCOMPARE(anim->state(), QVariantAnimation::Running);
//anim2 will interrupt anim1
@@ -925,7 +908,7 @@ void tst_QPropertyAnimation::zeroDurationStart()
anim.start();
//the animation stops immediately
QCOMPARE(anim.state(), QAbstractAnimation::Stopped);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
//let's check the first state change
const QVariantList firstChange = spy.first();
@@ -1210,8 +1193,8 @@ void tst_QPropertyAnimation::valueChanged()
QCOMPARE(anim.currentTime(), anim.duration());
//let's check that the values go forward
- QCOMPARE(spy.count(), 6); //we should have got everything from 0 to 5
- for (int i = 0; i < spy.count(); ++i) {
+ QCOMPARE(spy.size(), 6); //we should have got everything from 0 to 5
+ for (int i = 0; i < spy.size(); ++i) {
QCOMPARE(qvariant_cast<QVariant>(spy.at(i).first()).toInt(), i);
}
}
@@ -1283,7 +1266,7 @@ public:
innerAnim->start();
}
- void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) override
{
QPropertyAnimation::updateState(newState, oldState);
if (newState == QAbstractAnimation::Stopped)
@@ -1327,8 +1310,8 @@ void tst_QPropertyAnimation::totalDuration()
void tst_QPropertyAnimation::zeroLoopCount()
{
- DummyPropertyAnimation* anim;
- anim = new DummyPropertyAnimation;
+ DummyPropertyAnimation animation;
+ auto *anim = &animation;
anim->setStartValue(0);
anim->setDuration(20);
anim->setLoopCount(0);
@@ -1341,15 +1324,15 @@ void tst_QPropertyAnimation::zeroLoopCount()
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
QCOMPARE(anim->currentValue().toInt(), 0);
- QCOMPARE(runningSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 0);
+ QCOMPARE(finishedSpy.size(), 0);
anim->start();
QCOMPARE(anim->state(), QAnimationGroup::Stopped);
QCOMPARE(anim->currentValue().toInt(), 0);
- QCOMPARE(runningSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(runningSpy.size(), 0);
+ QCOMPARE(finishedSpy.size(), 0);
}
@@ -1396,6 +1379,29 @@ void tst_QPropertyAnimation::recursiveAnimations()
QCOMPARE(o.y(), qreal(4000));
}
+void tst_QPropertyAnimation::bindings()
+{
+ std::unique_ptr<AnimationObject> o1(new AnimationObject);
+ std::unique_ptr<AnimationObject> o2(new AnimationObject);
+ QPropertyAnimation a(o1.get(), "value");
+
+ QTestPrivate::testReadWritePropertyBasics<QPropertyAnimation, QByteArray>(
+ a, QByteArray("realValue"), QByteArray("value"), "propertyName");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for QPropertyAnimation::propertyName";
+ return;
+ }
+ QTestPrivate::testReadWritePropertyBasics<QPropertyAnimation, QObject *>(a, o2.get(), o1.get(),
+ "targetObject");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for QPropertyAnimation::targetObject";
+ return;
+ }
+
+ a.setTargetObject(o1.get());
+ o1.reset();
+ QCOMPARE(a.targetObject(), nullptr);
+}
QTEST_MAIN(tst_QPropertyAnimation)
#include "tst_qpropertyanimation.moc"
diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST
index 4c999ff88f..79053cbf68 100644
--- a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST
+++ b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST
@@ -1,8 +1,5 @@
-[startGroupWithRunningChild]
-windows
[finishWithUncontrolledAnimation]
-windows
-osx-10.12
-osx-10.13
+macos
[groupWithZeroDurationAnimations]
-osx
+macos
+
diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/CMakeLists.txt b/tests/auto/corelib/animation/qsequentialanimationgroup/CMakeLists.txt
new file mode 100644
index 0000000000..e2ebe8baa9
--- /dev/null
+++ b/tests/auto/corelib/animation/qsequentialanimationgroup/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsequentialanimationgroup Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsequentialanimationgroup LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsequentialanimationgroup
+ SOURCES
+ tst_qsequentialanimationgroup.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/qsequentialanimationgroup.pro b/tests/auto/corelib/animation/qsequentialanimationgroup/qsequentialanimationgroup.pro
deleted file mode 100644
index b0271e8ea2..0000000000
--- a/tests/auto/corelib/animation/qsequentialanimationgroup/qsequentialanimationgroup.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsequentialanimationgroup
-QT = core testlib
-SOURCES = tst_qsequentialanimationgroup.cpp
diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
index 06e9fe7a66..7555622162 100644
--- a/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
+++ b/tests/auto/corelib/animation/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp
@@ -1,34 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
+
+#include <QVariantAnimation>
+#include <QProperty>
+#include <QPropertyAnimation>
+#include <QSignalSpy>
+#include <QParallelAnimationGroup>
+
#include <QtCore/qanimationgroup.h>
#include <QtCore/qsequentialanimationgroup.h>
+#include <QtCore/qscopeguard.h>
Q_DECLARE_METATYPE(QAbstractAnimation::State)
@@ -65,6 +49,7 @@ private slots:
void insertAnimation();
void clear();
void pauseResume();
+ void bindings();
};
void tst_QSequentialAnimationGroup::initTestCase()
@@ -96,19 +81,19 @@ class TestAnimation : public QVariantAnimation
{
Q_OBJECT
public:
- virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)};
+ virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)};
virtual void updateState(QAbstractAnimation::State newState,
- QAbstractAnimation::State oldState)
+ QAbstractAnimation::State oldState) override
{
- Q_UNUSED(oldState)
- Q_UNUSED(newState)
+ Q_UNUSED(oldState);
+ Q_UNUSED(newState);
};
};
class DummyPropertyAnimation : public QPropertyAnimation
{
public:
- DummyPropertyAnimation(QObject *parent = 0) : QPropertyAnimation(parent)
+ DummyPropertyAnimation(QObject *parent = nullptr) : QPropertyAnimation(parent)
{
setTargetObject(&o);
this->setPropertyName("value");
@@ -122,17 +107,17 @@ class UncontrolledAnimation : public QPropertyAnimation
{
Q_OBJECT
public:
- UncontrolledAnimation(QObject *target, QObject *parent = 0)
+ UncontrolledAnimation(QObject *target, QObject *parent = nullptr)
: QPropertyAnimation(target, "value", parent)
{
setDuration(250);
setEndValue(0);
}
- int duration() const { return -1; /* not time driven */ }
+ int duration() const override { return -1; /* not time driven */ }
protected:
- void updateCurrentTime(int currentTime)
+ void updateCurrentTime(int currentTime) override
{
QPropertyAnimation::updateCurrentTime(currentTime);
if (currentTime >= QPropertyAnimation::duration())
@@ -563,13 +548,13 @@ void tst_QSequentialAnimationGroup::seekingBackwards()
QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped);
}
-typedef QVector<QAbstractAnimation::State> StateList;
+using StateList = QList<QAbstractAnimation::State>;
static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates)
{
bool equals = true;
- for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) {
- if (i >= spy.count() || i >= expectedStates.count()) {
+ for (int i = 0; i < qMax(expectedStates.size(), spy.size()); ++i) {
+ if (i >= spy.size() || i >= expectedStates.size()) {
equals = false;
break;
}
@@ -584,14 +569,14 @@ static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates
if (!equals) {
const char *stateStrings[] = {"Stopped", "Paused", "Running"};
QString e,a;
- for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) {
- if (i < expectedStates.count()) {
+ for (int i = 0; i < qMax(expectedStates.size(), spy.size()); ++i) {
+ if (i < expectedStates.size()) {
int exp = int(expectedStates.at(i));
if (!e.isEmpty())
e += QLatin1String(", ");
e += QLatin1String(stateStrings[exp]);
}
- if (i < spy.count()) {
+ if (i < spy.size()) {
QList<QVariant> args = spy.at(i);
QAbstractAnimation::State actual = qvariant_cast<QAbstractAnimation::State>(args.value(1));
if (!a.isEmpty())
@@ -605,8 +590,8 @@ static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates
}
qDebug("\n"
- "expected (count == %d): %s\n"
- "actual (count == %d): %s\n", expectedStates.count(), qPrintable(e), spy.count(), qPrintable(a));
+ "expected (count == %zd): %s\n"
+ "actual (count == %zd): %s\n", size_t(expectedStates.size()), qPrintable(e), size_t(spy.size()), qPrintable(a));
}
return equals;
}
@@ -653,8 +638,8 @@ void tst_QSequentialAnimationGroup::pauseAndResume()
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
- QCOMPARE(a1StateChangedSpy.count(), 5); // Running,Paused,Stopped,Running,Stopped
- QCOMPARE(seqStateChangedSpy.count(), 2); // Running,Paused
+ QCOMPARE(a1StateChangedSpy.size(), 5); // Running,Paused,Stopped,Running,Stopped
+ QCOMPARE(seqStateChangedSpy.size(), 2); // Running,Paused
QVERIFY(compareStates(a1StateChangedSpy, (StateList() << QAbstractAnimation::Running
<< QAbstractAnimation::Paused
@@ -695,7 +680,7 @@ void tst_QSequentialAnimationGroup::pauseAndResume()
QCOMPARE(a3_s_o1->currentLoop(), 0);
QVERIFY(a3_s_o1->currentLoopTime() >= 1);
- QCOMPARE(seqStateChangedSpy.count(), 3); // Running,Paused,Running
+ QCOMPARE(seqStateChangedSpy.size(), 3); // Running,Paused,Running
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(seqStateChangedSpy.at(2).first()),
QAnimationGroup::Running);
@@ -716,13 +701,13 @@ void tst_QSequentialAnimationGroup::pauseAndResume()
QCOMPARE(a3_s_o1->currentLoop(), 0);
QVERIFY(a3_s_o1->currentLoopTime() >= 1);
- QCOMPARE(seqStateChangedSpy.count(), 4); // Running,Paused,Running,Paused
+ QCOMPARE(seqStateChangedSpy.size(), 4); // Running,Paused,Running,Paused
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(seqStateChangedSpy.at(3).first()),
QAnimationGroup::Paused);
group.stop();
- QCOMPARE(seqStateChangedSpy.count(), 5); // Running,Paused,Running,Paused,Stopped
+ QCOMPARE(seqStateChangedSpy.size(), 5); // Running,Paused,Running,Paused,Stopped
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(seqStateChangedSpy.at(4).first()),
QAnimationGroup::Stopped);
}
@@ -738,12 +723,12 @@ void tst_QSequentialAnimationGroup::restart()
QVERIFY(seqStateChangedSpy.isValid());
QVariantAnimation *anims[3];
- QSignalSpy *animsStateChanged[3];
+ QScopedPointer<QSignalSpy> animsStateChanged[3];
for (int i = 0; i < 3; i++) {
anims[i] = new DummyPropertyAnimation;
anims[i]->setDuration(100);
- animsStateChanged[i] = new QSignalSpy(anims[i], &QVariantAnimation::stateChanged);
+ animsStateChanged[i].reset(new QSignalSpy(anims[i], &QVariantAnimation::stateChanged));
QVERIFY(animsStateChanged[i]->isValid());
}
@@ -766,7 +751,7 @@ void tst_QSequentialAnimationGroup::restart()
QTRY_COMPARE(group.state(), QAnimationGroup::Stopped);
for (int i = 0; i < 3; i++) {
- QCOMPARE(animsStateChanged[i]->count(), 4);
+ QCOMPARE(animsStateChanged[i]->size(), 4);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(animsStateChanged[i]->at(0).first()),
QAnimationGroup::Running);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(animsStateChanged[i]->at(1).first()),
@@ -777,22 +762,22 @@ void tst_QSequentialAnimationGroup::restart()
QAnimationGroup::Stopped);
}
- QCOMPARE(seqStateChangedSpy.count(), 2);
+ QCOMPARE(seqStateChangedSpy.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(seqStateChangedSpy.at(0).first()),
QAnimationGroup::Running);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(seqStateChangedSpy.at(1).first()),
QAnimationGroup::Stopped);
- QCOMPARE(seqCurrentAnimChangedSpy.count(), 6);
- for(int i=0; i<seqCurrentAnimChangedSpy.count(); i++)
+ QCOMPARE(seqCurrentAnimChangedSpy.size(), 6);
+ for(int i=0; i<seqCurrentAnimChangedSpy.size(); i++)
QCOMPARE(static_cast<QAbstractAnimation*>(anims[i%3]), qvariant_cast<QAbstractAnimation*>(seqCurrentAnimChangedSpy.at(i).at(0)));
group.start();
- QCOMPARE(animsStateChanged[0]->count(), 5);
- QCOMPARE(animsStateChanged[1]->count(), 4);
- QCOMPARE(animsStateChanged[2]->count(), 4);
- QCOMPARE(seqStateChangedSpy.count(), 3);
+ QCOMPARE(animsStateChanged[0]->size(), 5);
+ QCOMPARE(animsStateChanged[1]->size(), 4);
+ QCOMPARE(animsStateChanged[2]->size(), 4);
+ QCOMPARE(seqStateChangedSpy.size(), 3);
}
void tst_QSequentialAnimationGroup::looping()
@@ -848,21 +833,21 @@ void tst_QSequentialAnimationGroup::looping()
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused);
- QCOMPARE(a1Spy.count(), 5); // Running,Paused,Stopped,Running,Stopped
+ QCOMPARE(a1Spy.size(), 5); // Running,Paused,Stopped,Running,Stopped
QVERIFY(compareStates(a1Spy, (StateList() << QAbstractAnimation::Running
<< QAbstractAnimation::Paused
<< QAbstractAnimation::Stopped
<< QAbstractAnimation::Running
<< QAbstractAnimation::Stopped)));
- QCOMPARE(a2Spy.count(), 4); // Running,Stopped,Running,Stopped
+ QCOMPARE(a2Spy.size(), 4); // Running,Stopped,Running,Stopped
QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running
<< QAbstractAnimation::Stopped
<< QAbstractAnimation::Running
<< QAbstractAnimation::Paused)));
- QCOMPARE(seqSpy.count(), 2); // Running,Paused
- QCOMPARE(groupSpy.count(), 2); // Running,Paused
+ QCOMPARE(seqSpy.size(), 2); // Running,Paused
+ QCOMPARE(groupSpy.size(), 2); // Running,Paused
// Looping, current time = duration + 1
group.setCurrentTime(group.duration() + 1);
@@ -883,8 +868,8 @@ void tst_QSequentialAnimationGroup::looping()
QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped);
QCOMPARE(a3_s_o1->state(), QAnimationGroup::Stopped);
- QCOMPARE(a1Spy.count(), 7); // Running,Paused,Stopped,Running,Stopped,Running,Stopped
- QCOMPARE(a2Spy.count(), 4); // Running, Stopped, Running, Stopped
+ QCOMPARE(a1Spy.size(), 7); // Running,Paused,Stopped,Running,Stopped,Running,Stopped
+ QCOMPARE(a2Spy.size(), 4); // Running, Stopped, Running, Stopped
QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running
<< QAbstractAnimation::Stopped
<< QAbstractAnimation::Running
@@ -895,7 +880,7 @@ void tst_QSequentialAnimationGroup::looping()
<< QAbstractAnimation::Stopped
<< QAbstractAnimation::Running
<< QAbstractAnimation::Paused)));
- QCOMPARE(groupSpy.count(), 2);
+ QCOMPARE(groupSpy.size(), 2);
}
void tst_QSequentialAnimationGroup::startDelay()
@@ -1094,8 +1079,8 @@ void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup()
QVERIFY(groupStateChangedSpy.isValid());
QVERIFY(childStateChangedSpy.isValid());
- QCOMPARE(groupStateChangedSpy.count(), 0);
- QCOMPARE(childStateChangedSpy.count(), 0);
+ QCOMPARE(groupStateChangedSpy.size(), 0);
+ QCOMPARE(childStateChangedSpy.size(), 0);
QCOMPARE(group.state(), QAnimationGroup::Stopped);
QCOMPARE(anim.state(), QAnimationGroup::Stopped);
@@ -1106,8 +1091,8 @@ void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup()
QCOMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(anim.state(), QAnimationGroup::Running);
- QCOMPARE(groupStateChangedSpy.count(), 1);
- QCOMPARE(childStateChangedSpy.count(), 1);
+ QCOMPARE(groupStateChangedSpy.size(), 1);
+ QCOMPARE(childStateChangedSpy.size(), 1);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(groupStateChangedSpy.at(0).first()),
QAnimationGroup::Running);
@@ -1117,8 +1102,8 @@ void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup()
// starting directly a running child will not have any effect
anim.start();
- QCOMPARE(groupStateChangedSpy.count(), 1);
- QCOMPARE(childStateChangedSpy.count(), 1);
+ QCOMPARE(groupStateChangedSpy.size(), 1);
+ QCOMPARE(childStateChangedSpy.size(), 1);
anim.pause();
@@ -1261,8 +1246,8 @@ void tst_QSequentialAnimationGroup::startGroupWithRunningChild()
QVERIFY(stateChangedSpy1.isValid());
QVERIFY(stateChangedSpy2.isValid());
- QCOMPARE(stateChangedSpy1.count(), 0);
- QCOMPARE(stateChangedSpy2.count(), 0);
+ QCOMPARE(stateChangedSpy1.size(), 0);
+ QCOMPARE(stateChangedSpy2.size(), 0);
QCOMPARE(group.state(), QAnimationGroup::Stopped);
QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
QCOMPARE(anim2->state(), QAnimationGroup::Stopped);
@@ -1295,13 +1280,12 @@ void tst_QSequentialAnimationGroup::startGroupWithRunningChild()
QCOMPARE(anim1->state(), QAnimationGroup::Running);
QCOMPARE(anim2->state(), QAnimationGroup::Paused);
- QTest::qWait(300);
-
+ // Wait until anim1 finishes (anim2 should be still running)
+ QTRY_COMPARE(anim1->state(), QAnimationGroup::Stopped);
QCOMPARE(group.state(), QAnimationGroup::Running);
- QCOMPARE(anim1->state(), QAnimationGroup::Stopped);
QCOMPARE(anim2->state(), QAnimationGroup::Running);
- QCOMPARE(stateChangedSpy2.count(), 4);
+ QCOMPARE(stateChangedSpy2.size(), 4);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy2.at(2).first()),
QAnimationGroup::Stopped);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy2.at(3).first()),
@@ -1341,7 +1325,7 @@ void tst_QSequentialAnimationGroup::zeroDurationAnimation()
group.setLoopCount(2);
group.start();
- QCOMPARE(stateChangedSpy.count(), 2);
+ QCOMPARE(stateChangedSpy.size(), 2);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy.at(0).first()),
QAnimationGroup::Running);
QCOMPARE(qvariant_cast<QAbstractAnimation::State>(stateChangedSpy.at(1).first()),
@@ -1418,7 +1402,7 @@ void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation()
const int actualDuration = notTimeDriven.currentLoopTime();
QCOMPARE(group.state(), QAnimationGroup::Stopped);
QCOMPARE(group.currentLoopTime(), actualDuration);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
//2nd case:
// lets make sure the seeking will work again
@@ -1434,54 +1418,62 @@ void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation()
//3rd case:
//now let's add a perfectly defined animation at the end
- QCOMPARE(animStateChangedSpy.count(), 0);
+ QCOMPARE(animStateChangedSpy.size(), 0);
group.start();
QCOMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running);
QCOMPARE(group.currentLoopTime(), 0);
QCOMPARE(notTimeDriven.currentLoopTime(), 0);
- QCOMPARE(animStateChangedSpy.count(), 0);
+ QCOMPARE(animStateChangedSpy.size(), 0);
QTest::qWait(300); //wait for the end of notTimeDriven
QTRY_COMPARE(notTimeDriven.state(), QAnimationGroup::Stopped);
QCOMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(anim.state(), QAnimationGroup::Running);
QCOMPARE(group.currentAnimation(), static_cast<QAbstractAnimation*>(&anim));
- QCOMPARE(animStateChangedSpy.count(), 1);
+ QCOMPARE(animStateChangedSpy.size(), 1);
QTest::qWait(300); //wait for the end of anim
QTRY_COMPARE(anim.state(), QAnimationGroup::Stopped);
QCOMPARE(anim.currentLoopTime(), anim.duration());
//we should simply be at the end
- QCOMPARE(spy.count(), 1);
- QCOMPARE(animStateChangedSpy.count(), 2);
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(animStateChangedSpy.size(), 2);
QCOMPARE(group.currentLoopTime(), notTimeDriven.currentLoopTime() + anim.currentLoopTime());
}
void tst_QSequentialAnimationGroup::addRemoveAnimation()
{
//this test is specific to the sequential animation group
+ QPointer<QAbstractAnimation> anim0 = new QPropertyAnimation;
+ QPointer<QAbstractAnimation> anim1 = new QPropertyAnimation;
+ QPointer<QAbstractAnimation> anim2 = new QPropertyAnimation;
+
+ const auto guard = qScopeGuard([&]() {
+ // If they don't belong to a group when the function returns, we have to delete.
+ delete anim0.data();
+ delete anim1.data();
+ delete anim2.data();
+ });
+
QSequentialAnimationGroup group;
QCOMPARE(group.duration(), 0);
QCOMPARE(group.currentLoopTime(), 0);
- QAbstractAnimation *anim1 = new QPropertyAnimation;
group.addAnimation(anim1);
QCOMPARE(group.duration(), 250);
QCOMPARE(group.currentLoopTime(), 0);
QCOMPARE(group.currentAnimation(), anim1);
//let's append an animation
- QAbstractAnimation *anim2 = new QPropertyAnimation;
group.addAnimation(anim2);
QCOMPARE(group.duration(), 500);
QCOMPARE(group.currentLoopTime(), 0);
QCOMPARE(group.currentAnimation(), anim1);
//let's prepend an animation
- QAbstractAnimation *anim0 = new QPropertyAnimation;
group.insertAnimation(0, anim0);
QCOMPARE(group.duration(), 750);
QCOMPARE(group.currentLoopTime(), 0);
@@ -1600,7 +1592,7 @@ void tst_QSequentialAnimationGroup::clear()
{
SequentialAnimationGroup group;
QPointer<QAbstractAnimation> anim1 = new DummyPropertyAnimation(&group);
- group.connect(anim1, SIGNAL(finished()), SLOT(clear()));
+ connect(anim1, &QAbstractAnimation::finished, &group, &QSequentialAnimationGroup::clear);
new DummyPropertyAnimation(&group);
QCOMPARE(group.animationCount(), 2);
@@ -1615,7 +1607,7 @@ void tst_QSequentialAnimationGroup::clear()
group.start();
QTest::qWait(anim1->duration() + 100);
QTRY_COMPARE(group.state(), QAbstractAnimation::Running);
- QVERIFY(anim1 == 0); //anim1 should have been deleted
+ QTRY_COMPARE(anim1, nullptr); // anim1 should have been deleted
}
void tst_QSequentialAnimationGroup::pauseResume()
@@ -1633,7 +1625,7 @@ void tst_QSequentialAnimationGroup::pauseResume()
QTest::qWait(100);
QTRY_COMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(anim->state(), QAnimationGroup::Running);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
const int currentTime = group.currentLoopTime();
QCOMPARE(anim->currentLoopTime(), currentTime);
@@ -1643,7 +1635,7 @@ void tst_QSequentialAnimationGroup::pauseResume()
QCOMPARE(group.currentLoopTime(), currentTime);
QCOMPARE(anim->state(), QAnimationGroup::Paused);
QCOMPARE(anim->currentLoopTime(), currentTime);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
group.resume();
@@ -1651,7 +1643,59 @@ void tst_QSequentialAnimationGroup::pauseResume()
QCOMPARE(group.currentLoopTime(), currentTime);
QCOMPARE(anim->state(), QAnimationGroup::Running);
QCOMPARE(anim->currentLoopTime(), currentTime);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
+}
+
+void tst_QSequentialAnimationGroup::bindings()
+{
+ // create a group consisting of three animations
+ QSequentialAnimationGroup group;
+ QPointer<QAbstractAnimation> anim1 = new DummyPropertyAnimation(&group);
+ QCOMPARE(group.animationCount(), 1);
+ QPointer<QAbstractAnimation> anim2 = new DummyPropertyAnimation(&group);
+ QCOMPARE(group.animationCount(), 2);
+ QPointer<QAbstractAnimation> anim3 = new DummyPropertyAnimation(&group);
+ QCOMPARE(group.animationCount(), 3);
+
+ // bind a QProperty to group.currentAnimation
+ QProperty<QAbstractAnimation *> currentAnim;
+ currentAnim.setBinding([&]() { return group.currentAnimation(); });
+
+ // check that everything behaves as expected
+ QSignalSpy spy(&group, &QSequentialAnimationGroup::currentAnimationChanged);
+ QVERIFY(spy.isValid());
+
+ int totalDuration = group.duration();
+
+ group.setCurrentTime(int(totalDuration * 0.5 / 3));
+ QCOMPARE(currentAnim.value(), anim1.get());
+ QCOMPARE(spy.size(), 0);
+
+ group.setCurrentTime(int(totalDuration * 1.5 / 3));
+ QCOMPARE(currentAnim.value(), anim2.get());
+ QCOMPARE(spy.size(), 1);
+
+ // change to other style of formulating a binding to test both
+ currentAnim.setBinding(group.bindableCurrentAnimation().makeBinding());
+
+ group.setCurrentTime(int(totalDuration * 2.5 / 3));
+ QCOMPARE(currentAnim.value(), anim3.get());
+ QCOMPARE(spy.size(), 2);
+
+ // currentAnimation is read-only. Binding it to something should have no effect
+ QProperty<QAbstractAnimation *> leader;
+ group.bindableCurrentAnimation().setBinding([&]() { return leader.value(); });
+
+ QCOMPARE(group.currentAnimation(), anim3.get());
+
+ QTestPrivate::testReadOnlyPropertyBasics(group, anim3.get(), anim2.get(), "currentAnimation",
+ [&group, totalDuration]() {
+ group.setCurrentTime(int(totalDuration * 1.5 / 3));
+ });
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QSequentialAnimationGroup::currentAnimation");
+ return;
+ }
}
QTEST_MAIN(tst_QSequentialAnimationGroup)
diff --git a/tests/auto/corelib/animation/qvariantanimation/CMakeLists.txt b/tests/auto/corelib/animation/qvariantanimation/CMakeLists.txt
new file mode 100644
index 0000000000..9abc16040f
--- /dev/null
+++ b/tests/auto/corelib/animation/qvariantanimation/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qvariantanimation Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qvariantanimation LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qvariantanimation
+ SOURCES
+ tst_qvariantanimation.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/animation/qvariantanimation/qvariantanimation.pro b/tests/auto/corelib/animation/qvariantanimation/qvariantanimation.pro
deleted file mode 100644
index b82d3bc6e0..0000000000
--- a/tests/auto/corelib/animation/qvariantanimation/qvariantanimation.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qvariantanimation
-QT = core testlib
-SOURCES = tst_qvariantanimation.cpp
diff --git a/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp b/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp
index ac20fb35ec..661c4b8108 100644
--- a/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp
+++ b/tests/auto/corelib/animation/qvariantanimation/tst_qvariantanimation.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qvariantanimation.h>
-#include <QtTest>
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
class tst_QVariantAnimation : public QObject
{
@@ -44,13 +20,15 @@ private slots:
void keyValues();
void duration();
void interpolation();
+ void durationBindings();
+ void easingCurveBindings();
};
class TestableQVariantAnimation : public QVariantAnimation
{
Q_OBJECT
public:
- void updateCurrentValue(const QVariant&) {}
+ void updateCurrentValue(const QVariant&) override {}
};
void tst_QVariantAnimation::construction()
@@ -154,6 +132,32 @@ void tst_QVariantAnimation::interpolation()
QCOMPARE(pointAnim.currentValue().toPoint(), QPoint(50, 50));
}
+void tst_QVariantAnimation::durationBindings()
+{
+ QVariantAnimation animation;
+
+ // duration property
+ QProperty<int> duration;
+ animation.bindableDuration().setBinding(Qt::makePropertyBinding(duration));
+
+ // negative values must be ignored
+ QTest::ignoreMessage(QtWarningMsg,
+ "QVariantAnimation::setDuration: cannot set a negative duration");
+ duration = -1;
+ QVERIFY(animation.duration() != duration);
+
+ QTestPrivate::testReadWritePropertyBasics(animation, 42, 43, "duration");
+}
+
+void tst_QVariantAnimation::easingCurveBindings()
+{
+ QVariantAnimation animation;
+
+ QTestPrivate::testReadWritePropertyBasics(animation, QEasingCurve(QEasingCurve::InQuad),
+ QEasingCurve(QEasingCurve::BezierSpline),
+ "easingCurve");
+}
+
QTEST_MAIN(tst_QVariantAnimation)
#include "tst_qvariantanimation.moc"
diff --git a/tests/auto/corelib/codecs/codecs.pro b/tests/auto/corelib/codecs/codecs.pro
deleted file mode 100644
index 5cd26536b7..0000000000
--- a/tests/auto/corelib/codecs/codecs.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qtextcodec \
- utf8 \ # Integrate into qtextcodec test? See QTBUG-22590.
diff --git a/tests/auto/corelib/codecs/qtextcodec/.gitattributes b/tests/auto/corelib/codecs/qtextcodec/.gitattributes
deleted file mode 100644
index a27a4d9153..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-utf8.txt -crlf
diff --git a/tests/auto/corelib/codecs/qtextcodec/.gitignore b/tests/auto/corelib/codecs/qtextcodec/.gitignore
deleted file mode 100644
index bdbd16ad43..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qtextcodec
diff --git a/tests/auto/corelib/codecs/qtextcodec/QT4-crashtest.txt b/tests/auto/corelib/codecs/qtextcodec/QT4-crashtest.txt
deleted file mode 100644
index d64a06e206..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/QT4-crashtest.txt
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro b/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro
deleted file mode 100644
index 512da8939b..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += main.cpp
-QT = core
-
-load(qt_test_helper)
diff --git a/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp b/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp
deleted file mode 100644
index 52645184a3..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QTextCodec>
-
-int main(int argc, char **argv)
-{
- qputenv("LC_ALL", "C");
- QCoreApplication app(argc, argv);
-
- QString string(QChar(0x410));
- QTextCodec *locale = QTextCodec::codecForLocale();
- QTextEncoder *encoder = locale->makeEncoder();
- QByteArray output = encoder->fromUnicode(string);
- printf("%s\n", output.data());
-
- return 0;
-}
diff --git a/tests/auto/corelib/codecs/qtextcodec/korean.txt b/tests/auto/corelib/codecs/qtextcodec/korean.txt
deleted file mode 100644
index 07e1b07f76..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/korean.txt
+++ /dev/null
@@ -1 +0,0 @@
-ȳ Ͻ?
diff --git a/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro b/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro
deleted file mode 100644
index 15de02a42d..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = test.pro
-unix: SUBDIRS += echo
diff --git a/tests/auto/corelib/codecs/qtextcodec/test.pro b/tests/auto/corelib/codecs/qtextcodec/test.pro
deleted file mode 100644
index 7505c5ad51..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/test.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-QT = core testlib
-SOURCES = tst_qtextcodec.cpp
-
-TARGET = tst_qtextcodec
-TESTDATA += *.txt
diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
deleted file mode 100644
index 6cadebfd7f..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
+++ /dev/null
@@ -1,2469 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-
-#include <qtextcodec.h>
-#include <qfile.h>
-#include <time.h>
-#if QT_CONFIG(process)
-# include <qprocess.h>
-#endif
-#include <QThreadPool>
-
-class tst_QTextCodec : public QObject
-{
- Q_OBJECT
-
-private slots:
- void threadSafety();
-
- void toUnicode_data();
- void toUnicode();
- void codecForName_data();
- void codecForName();
- void fromUnicode_data();
- void fromUnicode();
- void toUnicode_codecForHtml();
- void toUnicode_incremental();
- void codecForLocale();
-
- void asciiToIscii() const;
- void nonFlaggedCodepointFFFF() const;
- void flagF7808080() const;
- void nonFlaggedEFBFBF() const;
- void decode0D() const;
- void aliasForUTF16() const;
- void mibForTSCII() const;
- void codecForTSCII() const;
- void iso8859_16() const;
-
- void utf8Codec_data();
- void utf8Codec();
-
- void utf8bom_data();
- void utf8bom();
-
- void utf8stateful_data();
- void utf8stateful();
-
- void utfHeaders_data();
- void utfHeaders();
-
- void codecForHtml_data();
- void codecForHtml();
-
- void codecForUtfText_data();
- void codecForUtfText();
-
-#if defined(Q_OS_UNIX)
- void toLocal8Bit();
-#endif
-
- void invalidNames();
- void checkAliases_data();
- void checkAliases();
-
- void moreToFromUnicode_data();
- void moreToFromUnicode();
-
- void shiftJis();
- void userCodec();
-};
-
-void tst_QTextCodec::toUnicode_data()
-{
- QTest::addColumn<QString>("fileName");
- QTest::addColumn<QString>("codecName");
-
- QTest::newRow( "korean-eucKR" ) << QFINDTESTDATA("korean.txt") << "eucKR";
- QTest::newRow( "UTF-8" ) << QFINDTESTDATA("utf8.txt") << "UTF-8";
-}
-
-void tst_QTextCodec::toUnicode()
-{
- QFETCH( QString, fileName );
- QFETCH( QString, codecName );
-
- QFile file( fileName );
-
- if ( file.open( QIODevice::ReadOnly ) ) {
- QByteArray ba = file.readAll();
- QVERIFY(!ba.isEmpty());
- QTextCodec *c = QTextCodec::codecForName( codecName.toLatin1() );
- QVERIFY(c != 0);
- QString uniString = c->toUnicode( ba );
- if (codecName == QLatin1String("UTF-8")) {
- QCOMPARE(uniString, QString::fromUtf8(ba));
- QCOMPARE(ba, uniString.toUtf8());
- }
- QVERIFY(!uniString.isEmpty());
- QCOMPARE( ba, c->fromUnicode( uniString ) );
- QCOMPARE(ba, c->fromUnicode(QStringView(uniString)) );
-
- char ch = '\0';
- QVERIFY(c->toUnicode(&ch, 1).length() == 1);
- QVERIFY(c->toUnicode(&ch, 1).at(0).unicode() == 0);
- } else {
- QFAIL(qPrintable("File could not be opened: " + file.errorString()));
- }
-}
-
-void tst_QTextCodec::codecForName_data()
-{
- QTest::addColumn<QString>("hint");
- QTest::addColumn<QString>("actualCodecName");
-
- QTest::newRow("data1") << "iso88591" << "ISO-8859-1";
- QTest::newRow("data2") << "iso88592" << "ISO-8859-2";
- QTest::newRow("data3") << " IsO(8)8/5*9-2 " << "ISO-8859-2";
- QTest::newRow("data4") << " IsO(8)8/5*2-9 " << "";
- QTest::newRow("data5") << "latin2" << "ISO-8859-2";
-}
-
-void tst_QTextCodec::codecForName()
-{
- QFETCH(QString, hint);
- QFETCH(QString, actualCodecName);
-
- QTextCodec *codec = QTextCodec::codecForName(hint.toLatin1());
- if (actualCodecName.isEmpty()) {
- QVERIFY(!codec);
- } else {
- QVERIFY(codec != 0);
- QCOMPARE(QString(codec->name()), actualCodecName);
- }
-}
-
-void tst_QTextCodec::fromUnicode_data()
-{
- QTest::addColumn<QString>("codecName");
- QTest::addColumn<bool>("eightBit");
-
- QTest::newRow("ISO-8859-1") << "ISO-8859-1" << true;
- QTest::newRow("ISO-8859-2") << "ISO-8859-2" << true;
- QTest::newRow("ISO-8859-3") << "ISO-8859-3" << true;
- QTest::newRow("ISO-8859-4") << "ISO-8859-4" << true;
- QTest::newRow("ISO-8859-5") << "ISO-8859-5" << true;
- QTest::newRow("ISO-8859-6") << "ISO-8859-6" << true;
- QTest::newRow("ISO-8859-7") << "ISO-8859-7" << true;
- QTest::newRow("ISO-8859-8") << "ISO-8859-8" << true;
- QTest::newRow("ISO-8859-9") << "ISO-8859-9" << true;
- QTest::newRow("ISO-8859-10") << "ISO-8859-10" << true;
- QTest::newRow("ISO-8859-13") << "ISO-8859-13" << true;
- QTest::newRow("ISO-8859-14") << "ISO-8859-14" << true;
- QTest::newRow("ISO-8859-15") << "ISO-8859-15" << true;
-// QTest::newRow("ISO-8859-16") << "ISO-8859-16" << true;
-
- QTest::newRow("IBM850") << "IBM850" << true;
- QTest::newRow("IBM874") << "IBM874" << true;
- QTest::newRow("IBM866") << "IBM866" << true;
-
- QTest::newRow("windows-1250") << "windows-1250" << true;
- QTest::newRow("windows-1251") << "windows-1251" << true;
- QTest::newRow("windows-1252") << "windows-1252" << true;
- QTest::newRow("windows-1253") << "windows-1253" << true;
- QTest::newRow("windows-1254") << "windows-1254" << true;
- QTest::newRow("windows-1255") << "windows-1255" << true;
- QTest::newRow("windows-1256") << "windows-1256" << true;
- QTest::newRow("windows-1257") << "windows-1257" << true;
- QTest::newRow("windows-1258") << "windows-1258" << true;
-
- QTest::newRow("Apple Roman") << "Apple Roman" << true;
- //QTest::newRow("WINSAMI2") << "WINSAMI2" << true;
- QTest::newRow("TIS-620") << "TIS-620" << true;
- QTest::newRow("SJIS") << "SJIS" << false;
-
- // all codecs from documentation
- QTest::newRow("Big5") << "Big5" << false;
- QTest::newRow("Big5-HKSCS") << "Big5-HKSCS" << false;
- QTest::newRow("CP949") << "CP949" << false;
- QTest::newRow("windows-949") << "windows-949" << false;
- QTest::newRow("EUC-JP") << "EUC-JP" << false;
- QTest::newRow("EUC-KR") << "EUC-KR" << false;
- QTest::newRow("GB18030") << "GB18030" << false;
- QTest::newRow("HP-ROMAN8") << "HP-ROMAN8" << false;
- QTest::newRow("IBM 850") << "IBM 850" << false;
- QTest::newRow("IBM 866") << "IBM 866" << false;
- QTest::newRow("IBM 874") << "IBM 874" << false;
- QTest::newRow("ISO 2022-JP") << "ISO 2022-JP" << false;
- //ISO 8859-1 to 10 and ISO 8859-13 to 16 tested previously
- // Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml tested in Iscii test
- QTest::newRow("KOI8-R") << "KOI8-R" << false;
- QTest::newRow("KOI8-U") << "KOI8-U" << false;
- QTest::newRow("Macintosh") << "Macintosh" << true;
- QTest::newRow("Shift-JIS") << "Shift-JIS" << false;
- QTest::newRow("TIS-620") << "TIS-620" << false;
- QTest::newRow("TSCII") << "TSCII" << false;
- QTest::newRow("UTF-8") << "UTF-8" << false;
- QTest::newRow("UTF-16") << "UTF-16" << false;
- QTest::newRow("UTF-16BE") << "UTF-16BE" << false;
- QTest::newRow("UTF-16LE") << "UTF-16LE" << false;
- QTest::newRow("UTF-32") << "UTF-32" << false;
- QTest::newRow("UTF-32BE") << "UTF-32BE" << false;
- QTest::newRow("UTF-32LE") << "UTF-32LE" << false;
- //Windows-1250 to 1258 tested previously
-}
-
-void tst_QTextCodec::fromUnicode()
-{
- QFETCH(QString, codecName);
- QFETCH(bool, eightBit);
-
- QTextCodec *codec = QTextCodec::codecForName(codecName.toLatin1());
- QVERIFY(codec != 0);
-
- // Check if the reverse lookup is what we expect
- if (eightBit) {
- char chars[128];
- for (int i = 0; i < 128; ++i)
- chars[i] = i + 128;
- QString s = codec->toUnicode(chars, 128);
- QByteArray c = codec->fromUnicode(s);
- QCOMPARE(c.size(), 128);
-
- int numberOfQuestionMarks = 0;
- for (int i = 0; i < 128; ++i) {
- if (c.at(i) == '?')
- ++numberOfQuestionMarks;
- else
- QCOMPARE(c.at(i), char(i + 128));
- }
- QVERIFY(numberOfQuestionMarks != 128);
- }
-
- /*
- If the encoding is a superset of ASCII, test that the byte
- array is correct (no off by one, no trailing '\0').
- */
- QByteArray result = codec->fromUnicode(QStringViewLiteral("abc"));
- if (result.startsWith('a')) {
- QCOMPARE(result.size(), 3);
- QCOMPARE(result, QByteArray("abc"));
- } else {
- QVERIFY(true);
- }
-}
-
-void tst_QTextCodec::toUnicode_codecForHtml()
-{
- QFile file(QFINDTESTDATA("QT4-crashtest.txt"));
- QVERIFY(file.open(QFile::ReadOnly));
-
- QByteArray data = file.readAll();
- QTextCodec *codec = QTextCodec::codecForHtml(data);
- codec->toUnicode(data); // this line crashes
-}
-
-
-void tst_QTextCodec::toUnicode_incremental()
-{
- QByteArray ba;
- ba += char(0xf0);
- ba += char(0x90);
- ba += char(0x80);
- ba += char(0x80);
- ba += char(0xf4);
- ba += char(0x8f);
- ba += char(0xbf);
- ba += char(0xbd);
-
- QString expected = QString::fromUtf8(ba);
-
- QString incremental;
- QTextDecoder *utf8Decoder = QTextCodec::codecForMib(106)->makeDecoder();
-
- QString actual;
- for (int i = 0; i < ba.size(); ++i)
- utf8Decoder->toUnicode(&actual, ba.constData() + i, 1);
-
- QCOMPARE(actual, expected);
-
-
- delete utf8Decoder;
-}
-
-void tst_QTextCodec::codecForLocale()
-{
- QTextCodec *codec = QTextCodec::codecForLocale();
- QVERIFY(codec != 0);
-
- // The rest of this test is for Unix only
-#if defined(Q_OS_UNIX)
- // get a time string that is locale-encoded
- QByteArray originalLocaleEncodedTimeString;
- originalLocaleEncodedTimeString.resize(1024);
- time_t t;
- time(&t);
- int r = strftime(originalLocaleEncodedTimeString.data(),
- originalLocaleEncodedTimeString.size(),
- "%A%a%B%b%Z",
- localtime(&t));
- QVERIFY(r != 0);
- originalLocaleEncodedTimeString.resize(r);
-
- QString unicodeTimeString = codec->toUnicode(originalLocaleEncodedTimeString);
- QByteArray localeEncodedTimeString = codec->fromUnicode(unicodeTimeString);
- QCOMPARE(localeEncodedTimeString, originalLocaleEncodedTimeString);
-
- // find a codec that is not the codecForLocale()
- QTextCodec *codec2 = 0;
- const auto availableMibs = QTextCodec::availableMibs();
- for (int mib : availableMibs ) {
- if (mib != codec->mibEnum()) {
- codec2 = QTextCodec::codecForMib(mib);
- if (codec2)
- break;
- }
- }
-
- // Only run the rest of the test if we could find a codec that is not
- // already the codecForLocale().
- if (codec2) {
- // set it, codecForLocale() should return it now
- QTextCodec::setCodecForLocale(codec2);
- QCOMPARE(QTextCodec::codecForLocale(), codec2);
-
- // reset back to the default
- QTextCodec::setCodecForLocale(0);
- QCOMPARE(QTextCodec::codecForLocale(), codec);
- }
-#endif
-}
-
-void tst_QTextCodec::asciiToIscii() const
-{
- /* Add all low, 7-bit ASCII characters. */
- QString ascii;
- const int len = 0xA0 - 1;
- ascii.resize(len);
-
- for(int i = 0; i < len; ++i)
- ascii[i] = QChar(i + 1);
-
- static const char *const isciiCodecs[] =
- {
- "Iscii-Mlm",
- "Iscii-Knd",
- "Iscii-Tlg",
- "Iscii-Tml",
- "Iscii-Ori",
- "Iscii-Gjr",
- "Iscii-Pnj",
- "Iscii-Bng",
- "Iscii-Dev"
- };
- const int isciiCodecsLen = sizeof(isciiCodecs) / sizeof(const char *);
-
- for(int i = 0; i < isciiCodecsLen; ++i) {
- /* For each codec. */
-
- const QTextCodec *const textCodec = QTextCodec::codecForName(isciiCodecs[i]);
- if (!textCodec)
- QSKIP("No ISCII codecs available.");
-
- for(int i2 = 0; i2 < len; ++i2) {
- /* For each character in ascii. */
- const QChar c(ascii[i2]);
- QVERIFY2(textCodec->canEncode(c), qPrintable(QString::fromLatin1("Failed to encode %1 with encoding %2")
- .arg(QString::number(c.unicode()), QString::fromLatin1(textCodec->name().constData()))));
- }
-
- QVERIFY2(textCodec->canEncode(ascii), qPrintable(QString::fromLatin1("Failed for full string with encoding %1")
- .arg(QString::fromLatin1(textCodec->name().constData()))));
- QVERIFY(textCodec->canEncode(QStringView(ascii)));
- }
-}
-
-void tst_QTextCodec::nonFlaggedCodepointFFFF() const
-{
- //Check that the code point 0xFFFF (=non-character code 0xEFBFBF) is not flagged
- const QChar ch(0xFFFF);
-
- QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
- QVERIFY(codec);
-
- const QByteArray asDecoded = codec->fromUnicode(QStringView(&ch, 1));
- QCOMPARE(asDecoded, QByteArray("\357\277\277"));
-
- QByteArray ffff("\357\277\277");
- QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(ffff.constData(), ffff.length(), &state) == QByteArray::fromHex("EFBFBF"));
-}
-
-void tst_QTextCodec::flagF7808080() const
-{
- /* This test case stems from test not-wf-sa-170, tests/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml,
- * whose description reads:
- *
- * "Four byte UTF-8 encodings can encode UCS-4 characters
- * which are beyond the range of legal XML characters
- * (and can't be expressed in Unicode surrogate pairs).
- * This document holds such a character."
- *
- * In binary, this is:
- * 11110111100000001000000010000000
- * * * * *
- * 11110www10xxxxxx10yyyyyy10zzzzzz
- *
- * With multibyte logic removed it is the codepoint 0x1C0000.
- */
- QByteArray input;
- input.resize(4);
- input[0] = char(0xF7);
- input[1] = char(0x80);
- input[2] = char(0x80);
- input[3] = char(0x80);
-
- QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
- QVERIFY(codec);
-
- //QVERIFY(!codec->canEncode(QChar(0x1C0000)));
-
- QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QCOMPARE(codec->toUnicode(input.constData(), input.length(), &state), QString(input.size(), QChar(0)));
-}
-
-void tst_QTextCodec::nonFlaggedEFBFBF() const
-{
- /* Check that the codec does NOT flag EFBFBF.
- * This is a regression test; see QTBUG-33229
- */
- QByteArray validInput;
- validInput.resize(3);
- validInput[0] = char(0xEF);
- validInput[1] = char(0xBF);
- validInput[2] = char(0xBF);
-
- const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
- QVERIFY(codec);
-
- {
- //QVERIFY(!codec->canEncode(QChar(0xFFFF)));
- QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(validInput.constData(), validInput.length(), &state) == QByteArray::fromHex("EFBFBF"));
-
- QByteArray start("<?pi ");
- start.append(validInput);
- start.append("?>");
- }
-
- // Check that 0xEFBFBF is correctly decoded when preceded by an arbitrary character
- {
- QByteArray start("B");
- start.append(validInput);
-
- QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(start.constData(), start.length(), &state) == QByteArray("B").append(QByteArray::fromHex("EFBFBF")));
- }
-}
-
-void tst_QTextCodec::decode0D() const
-{
- QByteArray input;
- input.resize(3);
- input[0] = 'A';
- input[1] = '\r';
- input[2] = 'B';
-
- QCOMPARE(QString::fromUtf8(input.constData()).toUtf8(), input);
-}
-
-void tst_QTextCodec::aliasForUTF16() const
-{
- QVERIFY(QTextCodec::codecForName("UTF-16")->aliases().isEmpty());
-}
-
-void tst_QTextCodec::mibForTSCII() const
-{
- QTextCodec *codec = QTextCodec::codecForName("TSCII");
- QVERIFY(codec);
- QCOMPARE(codec->mibEnum(), 2107);
-}
-
-void tst_QTextCodec::codecForTSCII() const
-{
- QTextCodec *codec = QTextCodec::codecForMib(2107);
- QVERIFY(codec);
- QCOMPARE(codec->mibEnum(), 2107);
-}
-
-void tst_QTextCodec::iso8859_16() const
-{
- QTextCodec *codec = QTextCodec::codecForName("ISO8859-16");
- QVERIFY(codec);
- QCOMPARE(codec->name(), QByteArray("ISO-8859-16"));
-}
-
-static QString fromInvalidUtf8Sequence(const QByteArray &ba)
-{
- return QString().fill(QChar::ReplacementCharacter, ba.size());
-}
-
-// copied from tst_QString::fromUtf8_data()
-void tst_QTextCodec::utf8Codec_data()
-{
- QTest::addColumn<QByteArray>("utf8");
- QTest::addColumn<QString>("res");
- QTest::addColumn<int>("len");
- QString str;
-
- QTest::newRow("str0") << QByteArray("abcdefgh") << QString("abcdefgh") << -1;
- QTest::newRow("str0-len") << QByteArray("abcdefgh") << QString("abc") << 3;
- QTest::newRow("str1") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
- << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") << -1;
- QTest::newRow("str1-len") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
- << QString::fromLatin1("\366\344\374\326\304") << 10;
-
- str += QChar(0x05e9);
- str += QChar(0x05d3);
- str += QChar(0x05d2);
- QTest::newRow("str2") << QByteArray("\327\251\327\223\327\222") << str << -1;
-
- str = QChar(0x05e9);
- QTest::newRow("str2-len") << QByteArray("\327\251\327\223\327\222") << str << 2;
-
- str = QChar(0x20ac);
- str += " some text";
- QTest::newRow("str3") << QByteArray("\342\202\254 some text") << str << -1;
-
- str = QChar(0x20ac);
- str += " some ";
- QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9;
-
- str = "hello";
- str += QChar::ReplacementCharacter;
- str += QChar(0x68);
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QChar(0x61);
- str += QChar::ReplacementCharacter;
- QTest::newRow("invalid utf8") << QByteArray("hello\344h\344\344\366\344a\304") << str << -1;
- QTest::newRow("invalid utf8-len") << QByteArray("hello\344h\344\344\366\344a\304") << QString("hello") << 5;
-
- str = "Prohl";
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QLatin1Char('e');
- str += QChar::ReplacementCharacter;
- str += " plugin";
- str += QChar::ReplacementCharacter;
- str += " Netscape";
-
- QTest::newRow("task28417") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << str << -1;
- QTest::newRow("task28417-len") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << QString("") << 0;
-
- QTest::newRow("null-1") << QByteArray() << QString() << -1;
- QTest::newRow("null0") << QByteArray() << QString() << 0;
- // QTest::newRow("null5") << QByteArray() << QString() << 5;
- QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << QString() << -1;
- QTest::newRow("empty0") << QByteArray() << QString() << 0;
- QTest::newRow("empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1("\0abcd", 5) << 5;
- QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab") << -1;
- QTest::newRow("other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab\0cd", 5) << 5;
-
- str = "Old Italic: ";
- str += QChar(0xd800);
- str += QChar(0xdf00);
- str += QChar(0xd800);
- str += QChar(0xdf01);
- str += QChar(0xd800);
- str += QChar(0xdf02);
- str += QChar(0xd800);
- str += QChar(0xdf03);
- str += QChar(0xd800);
- str += QChar(0xdf04);
- QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str << -1;
-
- QTest::newRow("surrogate-len") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str.left(16) << 20;
-
- // from http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html
-
- // 2.1.1 U+00000000
- QByteArray utf8;
- utf8 += char(0x00);
- str = QChar(QChar::Null);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.1") << utf8 << str << 1;
-
- // 2.1.2 U+00000080
- utf8.clear();
- utf8 += char(0xc2);
- utf8 += char(0x80);
- str = QChar(0x80);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.2") << utf8 << str << -1;
-
- // 2.1.3 U+00000800
- utf8.clear();
- utf8 += char(0xe0);
- utf8 += char(0xa0);
- utf8 += char(0x80);
- str = QChar(0x800);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.3") << utf8 << str << -1;
-
- // 2.1.4 U+00010000
- utf8.clear();
- utf8 += char(0xf0);
- utf8 += char(0x90);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str.clear();
- str += QChar(0xd800);
- str += QChar(0xdc00);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.4") << utf8 << str << -1;
-
- // 2.1.5 U+00200000 (not a valid Unicode character)
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x88);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.5") << utf8 << str << -1;
-
- // 2.1.6 U+04000000 (not a valid Unicode character)
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x84);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.6") << utf8 << str << -1;
-
- // 2.2.1 U+0000007F
- utf8.clear();
- utf8 += char(0x7f);
- str = QChar(0x7f);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.1") << utf8 << str << -1;
-
- // 2.2.2 U+000007FF
- utf8.clear();
- utf8 += char(0xdf);
- utf8 += char(0xbf);
- str = QChar(0x7ff);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.2") << utf8 << str << -1;
-
- // 2.2.3 U+000FFFF - non-character code
- utf8.clear();
- utf8 += char(0xef);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = QString::fromUtf8(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.3") << utf8 << str << -1;
-
- // 2.2.4 U+001FFFFF
- utf8.clear();
- utf8 += char(0xf7);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.4") << utf8 << str << -1;
-
- // 2.2.5 U+03FFFFFF (not a valid Unicode character)
- utf8.clear();
- utf8 += char(0xfb);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.5") << utf8 << str << -1;
-
- // 2.2.6 U+7FFFFFFF
- utf8.clear();
- utf8 += char(0xfd);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.6") << utf8 << str << -1;
-
- // 2.3.1 U+0000D7FF
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0x9f);
- utf8 += char(0xbf);
- str = QChar(0xd7ff);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.1") << utf8 << str << -1;
-
- // 2.3.2 U+0000E000
- utf8.clear();
- utf8 += char(0xee);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = QChar(0xe000);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.2") << utf8 << str << -1;
-
- // 2.3.3 U+0000FFFD
- utf8.clear();
- utf8 += char(0xef);
- utf8 += char(0xbf);
- utf8 += char(0xbd);
- str = QChar(QChar::ReplacementCharacter);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.3") << utf8 << str << -1;
-
- // 2.3.4 U+0010FFFD
- utf8.clear();
- utf8 += char(0xf4);
- utf8 += char(0x8f);
- utf8 += char(0xbf);
- utf8 += char(0xbd);
- str.clear();
- str += QChar(0xdbff);
- str += QChar(0xdffd);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.4") << utf8 << str << -1;
-
- // 2.3.5 U+00110000
- utf8.clear();
- utf8 += char(0xf4);
- utf8 += char(0x90);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.5") << utf8 << str << -1;
-
- // 3.1.1
- utf8.clear();
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.1") << utf8 << str << -1;
-
- // 3.1.2
- utf8.clear();
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.2") << utf8 << str << -1;
-
- // 3.1.3
- utf8.clear();
- utf8 += char(0x80);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.3") << utf8 << str << -1;
-
- // 3.1.4
- utf8.clear();
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.4") << utf8 << str << -1;
-
- // 3.1.5
- utf8.clear();
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.5") << utf8 << str << -1;
-
- // 3.1.6
- utf8.clear();
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.6") << utf8 << str << -1;
-
- // 3.1.7
- utf8.clear();
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.7") << utf8 << str << -1;
-
- // 3.1.8
- utf8.clear();
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- utf8 += char(0xbf);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.8") << utf8 << str << -1;
-
- // 3.1.9
- utf8.clear();
- for (uint i = 0x80; i<= 0xbf; ++i)
- utf8 += i;
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.9") << utf8 << str << -1;
-
- // 3.2.1
- utf8.clear();
- str.clear();
- for (uint i = 0xc8; i <= 0xdf; ++i) {
- utf8 += i;
- utf8 += char(0x20);
-
- str += QChar::ReplacementCharacter;
- str += QChar(0x0020);
- }
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.1") << utf8 << str << -1;
-
- // 3.2.2
- utf8.clear();
- str.clear();
- for (uint i = 0xe0; i <= 0xef; ++i) {
- utf8 += i;
- utf8 += char(0x20);
-
- str += QChar::ReplacementCharacter;
- str += QChar(0x0020);
- }
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.2") << utf8 << str << -1;
-
- // 3.2.3
- utf8.clear();
- str.clear();
- for (uint i = 0xf0; i <= 0xf7; ++i) {
- utf8 += i;
- utf8 += 0x20;
-
- str += QChar::ReplacementCharacter;
- str += QChar(0x0020);
- }
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.3") << utf8 << str << -1;
-
- // 3.2.4
- utf8.clear();
- str.clear();
- for (uint i = 0xf8; i <= 0xfb; ++i) {
- utf8 += i;
- utf8 += 0x20;
-
- str += QChar::ReplacementCharacter;
- str += QChar(0x0020);
- }
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.4") << utf8 << str << -1;
-
- // 3.2.5
- utf8.clear();
- str.clear();
- for (uint i = 0xfc; i <= 0xfd; ++i) {
- utf8 += i;
- utf8 += 0x20;
-
- str += QChar::ReplacementCharacter;
- str += QChar(0x0020);
- }
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.5") << utf8 << str << -1;
-
- // 3.3.1
- utf8.clear();
- utf8 += char(0xc0);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.1") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.1-1") << utf8 << str << -1;
-
- // 3.3.2
- utf8.clear();
- utf8 += char(0xe0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xe0);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-2") << utf8 << str << -1;
- utf8 += 0x30;
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-3") << utf8 << str << -1;
-
- // 3.3.3
- utf8.clear();
- utf8 += char(0xf0);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf0);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-3") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-5") << utf8 << str << -1;
-
- // 3.3.4
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-3") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-5") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf8);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-6") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-7") << utf8 << str << -1;
-
- // 3.3.5
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-3") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-5") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-6") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-7") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfc);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-8") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-9") << utf8 << str << -1;
-
- // 3.3.6
- utf8.clear();
- utf8 += char(0xdf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.6") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.6-1") << utf8 << str << -1;
-
- // 3.3.7
- utf8.clear();
- utf8 += char(0xef);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xef);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-3") << utf8 << str << -1;
-
- // 3.3.8
- utf8.clear();
- utf8 += char(0xf7);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf7);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-3") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xf7);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-5") << utf8 << str << -1;
-
- // 3.3.9
- utf8.clear();
- utf8 += char(0xfb);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfb);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-3") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfb);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-5") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfb);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-6") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-7") << utf8 << str << -1;
-
- // 3.3.10
- utf8.clear();
- utf8 += char(0xfd);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-1") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfd);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-2") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-3") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfd);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-4") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-5") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfd);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-6") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-7") << utf8 << str << -1;
-
- utf8.clear();
- utf8 += char(0xfd);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-8") << utf8 << str << -1;
- utf8 += char(0x30);
- str += 0x30;
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-9") << utf8 << str << -1;
-
- // 3.4
- utf8.clear();
- utf8 += char(0xc0);
- utf8 += char(0xe0);
- utf8 += char(0x80);
- utf8 += char(0xf0);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0xf8);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0xfc);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0xdf);
- utf8 += char(0xef);
- utf8 += char(0xbf);
- utf8 += char(0xf7);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xfb);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xfd);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.4") << utf8 << str << -1;
-
- // 3.5.1
- utf8.clear();
- utf8 += char(0xfe);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.1") << utf8 << str << -1;
-
- // 3.5.2
- utf8.clear();
- utf8 += char(0xff);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2") << utf8 << str << -1;
-
- // 3.5.2
- utf8.clear();
- utf8 += char(0xfe);
- utf8 += char(0xfe);
- utf8 += char(0xff);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2-1") << utf8 << str << -1;
-
- // 4.1.1
- utf8.clear();
- utf8 += char(0xc0);
- utf8 += char(0xaf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.1") << utf8 << str << -1;
-
- // 4.1.2
- utf8.clear();
- utf8 += char(0xe0);
- utf8 += char(0x80);
- utf8 += char(0xaf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.2") << utf8 << str << -1;
-
- // 4.1.3
- utf8.clear();
- utf8 += char(0xf0);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0xaf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.3") << utf8 << str << -1;
-
- // 4.1.4
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0xaf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.4") << utf8 << str << -1;
-
- // 4.1.5
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0xaf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.5") << utf8 << str << -1;
-
- // 4.2.1
- utf8.clear();
- utf8 += char(0xc1);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.1") << utf8 << str << -1;
-
- // 4.2.2
- utf8.clear();
- utf8 += char(0xe0);
- utf8 += char(0x9f);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.2") << utf8 << str << -1;
-
- // 4.2.3
- utf8.clear();
- utf8 += char(0xf0);
- utf8 += char(0x8f);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.3") << utf8 << str << -1;
-
- // 4.2.4
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x87);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.4") << utf8 << str << -1;
-
- // 4.2.5
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x83);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.5") << utf8 << str << -1;
-
- // 4.3.1
- utf8.clear();
- utf8 += char(0xc0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.1") << utf8 << str << -1;
-
- // 4.3.2
- utf8.clear();
- utf8 += char(0xe0);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.2") << utf8 << str << -1;
-
- // 4.3.3
- utf8.clear();
- utf8 += char(0xf0);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.3") << utf8 << str << -1;
-
- // 4.3.4
- utf8.clear();
- utf8 += char(0xf8);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.4") << utf8 << str << -1;
-
- // 4.3.5
- utf8.clear();
- utf8 += char(0xfc);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.5") << utf8 << str << -1;
-
- // 5.1.1
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xa0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.1") << utf8 << str << -1;
-
- // 5.1.2
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xad);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.2") << utf8 << str << -1;
-
- // 5.1.3
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xae);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.3") << utf8 << str << -1;
-
- // 5.1.4
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xaf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.4") << utf8 << str << -1;
-
- // 5.1.5
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xb0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.5") << utf8 << str << -1;
-
- // 5.1.6
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xbe);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.6") << utf8 << str << -1;
-
- // 5.1.7
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.7") << utf8 << str << -1;
-
- // 5.2.1
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xa0);
- utf8 += char(0x80);
- utf8 += char(0xed);
- utf8 += char(0xb0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.1") << utf8 << str << -1;
-
- // 5.2.2
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xa0);
- utf8 += char(0x80);
- utf8 += char(0xed);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.2") << utf8 << str << -1;
-
- // 5.2.3
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xad);
- utf8 += char(0xbf);
- utf8 += char(0xed);
- utf8 += char(0xb0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.3") << utf8 << str << -1;
-
- // 5.2.4
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xad);
- utf8 += char(0xbf);
- utf8 += char(0xed);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.4") << utf8 << str << -1;
-
- // 5.2.5
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xae);
- utf8 += char(0x80);
- utf8 += char(0xed);
- utf8 += char(0xb0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.5") << utf8 << str << -1;
-
- // 5.2.6
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xae);
- utf8 += char(0x80);
- utf8 += char(0xed);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.6") << utf8 << str << -1;
-
- // 5.2.7
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xaf);
- utf8 += char(0xbf);
- utf8 += char(0xed);
- utf8 += char(0xb0);
- utf8 += char(0x80);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.7") << utf8 << str << -1;
-
- // 5.2.8
- utf8.clear();
- utf8 += char(0xed);
- utf8 += char(0xaf);
- utf8 += char(0xbf);
- utf8 += char(0xed);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- str = fromInvalidUtf8Sequence(utf8);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.8") << utf8 << str << -1;
-
- // 5.3.1 - non-character code
- utf8.clear();
- utf8 += char(0xef);
- utf8 += char(0xbf);
- utf8 += char(0xbe);
- //str = QChar(QChar::ReplacementCharacter);
- str = QChar(0xfffe);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.1") << utf8 << str << -1;
-
- // 5.3.2 - non-character code
- utf8.clear();
- utf8 += char(0xef);
- utf8 += char(0xbf);
- utf8 += char(0xbf);
- //str = QChar(QChar::ReplacementCharacter);
- str = QChar(0xffff);
- QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.2") << utf8 << str << -1;
-}
-
-void tst_QTextCodec::utf8Codec()
-{
- QTextCodec *codec = QTextCodec::codecForMib(106); // UTF-8
- QVERIFY(codec != 0);
-
- QFETCH(QByteArray, utf8);
- QFETCH(QString, res);
- QFETCH(int, len);
-
- QString str = codec->toUnicode(utf8.isNull() ? 0 : utf8.constData(),
- len < 0 ? qstrlen(utf8.constData()) : len);
- QCOMPARE(str, res);
-
- str = QString::fromUtf8(utf8.isNull() ? 0 : utf8.constData(), len);
- QCOMPARE(str, res);
-}
-
-void tst_QTextCodec::utf8bom_data()
-{
- QTest::addColumn<QByteArray>("data");
- QTest::addColumn<QString>("result");
-
- QTest::newRow("nobom")
- << QByteArray("\302\240", 2)
- << QString::fromLatin1("\240");
-
- {
- static const ushort data[] = { 0x201d };
- QTest::newRow("nobom 2")
- << QByteArray("\342\200\235", 3)
- << QString::fromUtf16(data, sizeof(data)/sizeof(short));
- }
-
- {
- static const ushort data[] = { 0xf000 };
- QTest::newRow("bom1")
- << QByteArray("\357\200\200", 3)
- << QString::fromUtf16(data, sizeof(data)/sizeof(short));
- }
-
- {
- static const ushort data[] = { 0xfec0 };
- QTest::newRow("bom2")
- << QByteArray("\357\273\200", 3)
- << QString::fromUtf16(data, sizeof(data)/sizeof(short));
- }
-
- {
- QTest::newRow("normal-bom")
- << QByteArray("\357\273\277a", 4)
- << QString("a");
- }
-
- { // test the non-SIMD code-path
- static const ushort data[] = { 0x61, 0xfeff, 0x62 };
- QTest::newRow("middle-bom (non SIMD)")
- << QByteArray("a\357\273\277b")
- << QString::fromUtf16(data, sizeof(data)/sizeof(short));
- }
-
- { // test the SIMD code-path
- static const ushort data[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0xfeff, 0x6d };
- QTest::newRow("middle-bom (SIMD)")
- << QByteArray("abcdefghijkl\357\273\277m")
- << QString::fromUtf16(data, sizeof(data)/sizeof(short));
- }
-}
-
-void tst_QTextCodec::utf8bom()
-{
- QFETCH(QByteArray, data);
- QFETCH(QString, result);
-
- QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
- QVERIFY(codec);
-
- QCOMPARE(codec->toUnicode(data.constData(), data.length(), 0), result);
-
- QTextCodec::ConverterState state;
- QCOMPARE(codec->toUnicode(data.constData(), data.length(), &state), result);
-}
-
-void tst_QTextCodec::utf8stateful_data()
-{
- QTest::addColumn<QByteArray>("buffer1");
- QTest::addColumn<QByteArray>("buffer2");
- QTest::addColumn<QString>("result"); // null QString indicates decoder error
-
- // valid buffer continuations
- QTest::newRow("1of2+valid") << QByteArray("\xc2") << QByteArray("\xa0") << "\xc2\xa0";
- QTest::newRow("1of3+valid") << QByteArray("\xe0") << QByteArray("\xa0\x80") << "\xe0\xa0\x80";
- QTest::newRow("2of3+valid") << QByteArray("\xe0\xa0") << QByteArray("\x80") << "\xe0\xa0\x80";
- QTest::newRow("1of4+valid") << QByteArray("\360") << QByteArray("\220\210\203") << "\360\220\210\203";
- QTest::newRow("2of4+valid") << QByteArray("\360\220") << QByteArray("\210\203") << "\360\220\210\203";
- QTest::newRow("3of4+valid") << QByteArray("\360\220\210") << QByteArray("\203") << "\360\220\210\203";
- QTest::newRow("1ofBom+valid") << QByteArray("\xef") << QByteArray("\xbb\xbf") << "";
- QTest::newRow("2ofBom+valid") << QByteArray("\xef\xbb") << QByteArray("\xbf") << "";
-
- // invalid continuation
- QTest::newRow("1of2+invalid") << QByteArray("\xc2") << QByteArray("a") << QString();
- QTest::newRow("1of3+invalid") << QByteArray("\xe0") << QByteArray("a") << QString();
- QTest::newRow("2of3+invalid") << QByteArray("\xe0\xa0") << QByteArray("a") << QString();
- QTest::newRow("1of4+invalid") << QByteArray("\360") << QByteArray("a") << QString();
- QTest::newRow("2of4+invalid") << QByteArray("\360\220") << QByteArray("a") << QString();
- QTest::newRow("3of4+invalid") << QByteArray("\360\220\210") << QByteArray("a") << QString();
-
- // invalid: sequence too short (the empty second buffer causes a state reset)
- QTest::newRow("1of2+empty") << QByteArray("\xc2") << QByteArray() << QString();
- QTest::newRow("1of3+empty") << QByteArray("\xe0") << QByteArray() << QString();
- QTest::newRow("2of3+empty") << QByteArray("\xe0\xa0") << QByteArray() << QString();
- QTest::newRow("1of4+empty") << QByteArray("\360") << QByteArray() << QString();
- QTest::newRow("2of4+empty") << QByteArray("\360\220") << QByteArray() << QString();
- QTest::newRow("3of4+empty") << QByteArray("\360\220\210") << QByteArray() << QString();
-
- // overlong sequence:
- QTest::newRow("overlong-1of2") << QByteArray("\xc1") << QByteArray("\x81") << QString();
- QTest::newRow("overlong-1of3") << QByteArray("\xe0") << QByteArray("\x81\x81") << QString();
- QTest::newRow("overlong-2of3") << QByteArray("\xe0\x81") << QByteArray("\x81") << QString();
- QTest::newRow("overlong-1of4") << QByteArray("\xf0") << QByteArray("\x80\x81\x81") << QString();
- QTest::newRow("overlong-2of4") << QByteArray("\xf0\x80") << QByteArray("\x81\x81") << QString();
- QTest::newRow("overlong-3of4") << QByteArray("\xf0\x80\x81") << QByteArray("\x81") << QString();
-
- // out of range:
- // leading byte 0xF4 can produce codepoints above U+10FFFF, which aren't valid
- QTest::newRow("outofrange1-1of4") << QByteArray("\xf4") << QByteArray("\x90\x80\x80") << QString();
- QTest::newRow("outofrange1-2of4") << QByteArray("\xf4\x90") << QByteArray("\x80\x80") << QString();
- QTest::newRow("outofrange1-3of4") << QByteArray("\xf4\x90\x80") << QByteArray("\x80") << QString();
- QTest::newRow("outofrange2-1of4") << QByteArray("\xf5") << QByteArray("\x90\x80\x80") << QString();
- QTest::newRow("outofrange2-2of4") << QByteArray("\xf5\x90") << QByteArray("\x80\x80") << QString();
- QTest::newRow("outofrange2-3of4") << QByteArray("\xf5\x90\x80") << QByteArray("\x80") << QString();
- QTest::newRow("outofrange-1of5") << QByteArray("\xf8") << QByteArray("\x88\x80\x80\x80") << QString();
- QTest::newRow("outofrange-2of5") << QByteArray("\xf8\x88") << QByteArray("\x80\x80\x80") << QString();
- QTest::newRow("outofrange-3of5") << QByteArray("\xf8\x88\x80") << QByteArray("\x80\x80") << QString();
- QTest::newRow("outofrange-4of5") << QByteArray("\xf8\x88\x80\x80") << QByteArray("\x80") << QString();
- QTest::newRow("outofrange-1of6") << QByteArray("\xfc") << QByteArray("\x84\x80\x80\x80\x80") << QString();
- QTest::newRow("outofrange-2of6") << QByteArray("\xfc\x84") << QByteArray("\x80\x80\x80\x80") << QString();
- QTest::newRow("outofrange-3of6") << QByteArray("\xfc\x84\x80") << QByteArray("\x80\x80\x80") << QString();
- QTest::newRow("outofrange-4of6") << QByteArray("\xfc\x84\x80\x80") << QByteArray("\x80\x80") << QString();
- QTest::newRow("outofrange-5of6") << QByteArray("\xfc\x84\x80\x80\x80") << QByteArray("\x80") << QString();
-}
-
-void tst_QTextCodec::utf8stateful()
-{
- QFETCH(QByteArray, buffer1);
- QFETCH(QByteArray, buffer2);
- QFETCH(QString, result);
-
- QTextCodec *utf8codec = QTextCodec::codecForName("utf-8");
- QVERIFY(utf8codec);
-
- QTextCodec::ConverterState state;
- memset(&state, 0, sizeof state);
-
- QString decoded1 = utf8codec->toUnicode(buffer1, buffer1.size(), &state);
- if (result.isNull()) {
- // the decoder may have found an early error (invalidChars > 0):
- // if it has, remainingChars == 0;
- // if it hasn't, then it must have a state
- QVERIFY2((state.remainingChars == 0) != (state.invalidChars == 0),
- "remainingChars = " + QByteArray::number(state.remainingChars) +
- "; invalidChars = " + QByteArray::number(state.invalidChars));
- } else {
- QVERIFY(state.remainingChars > 0);
- QCOMPARE(state.invalidChars, 0);
- }
-
- QString decoded2 = utf8codec->toUnicode(buffer2, buffer2.size(), &state);
- QCOMPARE(state.remainingChars, 0);
- if (result.isNull()) {
- QVERIFY(state.invalidChars > 0);
- } else {
- QCOMPARE(decoded1 + decoded2, result);
- }
-}
-
-void tst_QTextCodec::utfHeaders_data()
-{
- QTest::addColumn<QByteArray>("codecName");
- QTest::addColumn<int>("flags");
- QTest::addColumn<QByteArray>("encoded");
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<bool>("toUnicode");
-
- QTest::newRow("utf8 bom")
- << QByteArray("UTF-8")
- << 0
- << QByteArray("\xef\xbb\xbfhello")
- << QString::fromLatin1("hello")
- << true;
- QTest::newRow("utf8 nobom")
- << QByteArray("UTF-8")
- << 0
- << QByteArray("hello")
- << QString::fromLatin1("hello")
- << true;
- QTest::newRow("utf8 bom ignore header")
- << QByteArray("UTF-8")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xef\xbb\xbfhello")
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hello"))
- << true;
- QTest::newRow("utf8 nobom ignore header")
- << QByteArray("UTF-8")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("hello")
- << QString::fromLatin1("hello")
- << true;
-
- QTest::newRow("utf16 bom be")
- << QByteArray("UTF-16")
- << 0
- << QByteArray("\xfe\xff\0h\0e\0l", 8)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16 bom le")
- << QByteArray("UTF-16")
- << 0
- << QByteArray("\xff\xfeh\0e\0l\0", 8)
- << QString::fromLatin1("hel")
- << true;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- QTest::newRow("utf16 nobom")
- << QByteArray("UTF-16")
- << 0
- << QByteArray("\0h\0e\0l", 6)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16 bom be ignore header")
- << QByteArray("UTF-16")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xfe\xff\0h\0e\0l", 8)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
- } else {
- QTest::newRow("utf16 nobom")
- << QByteArray("UTF-16")
- << 0
- << QByteArray("h\0e\0l\0", 6)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16 bom le ignore header")
- << QByteArray("UTF-16")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xff\xfeh\0e\0l\0", 8)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
- }
-
- QTest::newRow("utf16-be bom be")
- << QByteArray("UTF-16BE")
- << 0
- << QByteArray("\xfe\xff\0h\0e\0l", 8)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16-be nobom")
- << QByteArray("UTF-16BE")
- << 0
- << QByteArray("\0h\0e\0l", 6)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16-be bom be ignore header")
- << QByteArray("UTF-16BE")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xfe\xff\0h\0e\0l", 8)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
-
- QTest::newRow("utf16-le bom le")
- << QByteArray("UTF-16LE")
- << 0
- << QByteArray("\xff\xfeh\0e\0l\0", 8)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16-le nobom")
- << QByteArray("UTF-16LE")
- << 0
- << QByteArray("h\0e\0l\0", 6)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf16-le bom le ignore header")
- << QByteArray("UTF-16LE")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xff\xfeh\0e\0l\0", 8)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
-
-
- QTest::newRow("utf32 bom be")
- << QByteArray("UTF-32")
- << 0
- << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32 bom le")
- << QByteArray("UTF-32")
- << 0
- << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
- << QString::fromLatin1("hel")
- << true;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- QTest::newRow("utf32 nobom")
- << QByteArray("UTF-32")
- << 0
- << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32 bom be ignore header")
- << QByteArray("UTF-32")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
- } else {
- QTest::newRow("utf32 nobom")
- << QByteArray("UTF-32")
- << 0
- << QByteArray("h\0\0\0e\0\0\0l\0\0\0", 12)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32 bom le ignore header")
- << QByteArray("UTF-32")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
- }
-
-
- QTest::newRow("utf32-be bom be")
- << QByteArray("UTF-32BE")
- << 0
- << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32-be nobom")
- << QByteArray("UTF-32BE")
- << 0
- << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32-be bom be ignore header")
- << QByteArray("UTF-32BE")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
-
-
- QTest::newRow("utf32-le bom le")
- << QByteArray("UTF-32LE")
- << 0
- << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32-le nobom")
- << QByteArray("UTF-32LE")
- << 0
- << QByteArray("h\0\0\0e\0\0\0l\0\0\0", 12)
- << QString::fromLatin1("hel")
- << true;
- QTest::newRow("utf32-le bom le ignore header")
- << QByteArray("UTF-32LE")
- << (int)QTextCodec::IgnoreHeader
- << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
- << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
- << true;
-}
-
-void tst_QTextCodec::utfHeaders()
-{
- QFETCH(QByteArray, codecName);
- QTextCodec *codec = QTextCodec::codecForName(codecName);
- QVERIFY(codec != 0);
-
- QFETCH(int, flags);
- QTextCodec::ConversionFlags cFlags = QTextCodec::ConversionFlags(flags);
- QTextCodec::ConverterState state(cFlags);
-
- QFETCH(QByteArray, encoded);
- QFETCH(QString, unicode);
-
- QFETCH(bool, toUnicode);
-
- QLatin1String ignoreReverseTestOn = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? QLatin1String(" le") : QLatin1String(" be");
- QString rowName(QTest::currentDataTag());
-
- if (toUnicode) {
- QString result = codec->toUnicode(encoded.constData(), encoded.length(), &state);
- QCOMPARE(result.length(), unicode.length());
- QCOMPARE(result, unicode);
-
- if (!rowName.endsWith("nobom") && !rowName.contains(ignoreReverseTestOn)) {
- QTextCodec::ConverterState state2(cFlags);
- QByteArray reencoded = codec->fromUnicode(unicode.unicode(), unicode.length(), &state2);
- QCOMPARE(reencoded, encoded);
- }
- } else {
- QByteArray result = codec->fromUnicode(unicode.unicode(), unicode.length(), &state);
- QCOMPARE(result, encoded);
- }
-}
-
-void tst_QTextCodec::codecForHtml_data()
-{
- QTest::addColumn<QByteArray>("html");
- QTest::addColumn<int>("defaultCodecMib");
- QTest::addColumn<int>("expectedMibEnum");
-
- int noDefault = -1;
- int fallback = 4; // latin 1
- QByteArray html = "<html><head></head><body>blah</body></html>";
- QTest::newRow("no charset, latin 1") << html << noDefault << fallback;
-
- QTest::newRow("no charset, default UTF-8") << html << 106 << 106;
-
- html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-15\" /></head></html>";
- QTest::newRow("latin 15, default UTF-8") << html << 106 << 111;
-
- html = "<html><head><meta content=\"text/html; charset=ISO-8859-15\" http-equiv=\"content-type\" /></head></html>";
- QTest::newRow("latin 15, default UTF-8 (#2)") << html << 106 << 111;
-
- html = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><title>Test</title></head>";
- QTest::newRow("UTF-8, no default") << html << noDefault << 106;
-
- html = "<!DOCTYPE html><html><head><meta charset=\"ISO_8859-1:1987\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><title>Test</title></head>";
- QTest::newRow("latin 1, no default") << html << noDefault << 4;
-
- html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"utf-8\"><title>Test</title></head>";
- QTest::newRow("UTF-8, no default (#2)") << html << noDefault << 106;
-
- html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8/></head></html>";
- QTest::newRow("UTF-8, no quotes") << html << noDefault << 106;
-
- html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset='UTF-8'/></head></html>";
- QTest::newRow("UTF-8, single quotes") << html << noDefault << 106;
-
- html = "<!DOCTYPE html><html><head><meta charset=utf-8><title>Test</title></head>";
- QTest::newRow("UTF-8, > terminator") << html << noDefault << 106;
-
- html = "<!DOCTYPE html><html><head><meta charset= utf-8 ><title>Test</title></head>";
- QTest::newRow("UTF-8, > terminator with spaces") << html << noDefault << 106;
-
- html = "<!DOCTYPE html><html><head><meta charset= utf/8 ><title>Test</title></head>";
- QTest::newRow("UTF-8, > teminator with early backslash)") << html << noDefault << 106;
-
- // Test invalid charsets.
- html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=invalid-foo\" /></head></html>";
- QTest::newRow("invalid charset, no default") << html << noDefault << fallback;
- QTest::newRow("invalid charset, default UTF-8") << html << 106 << 106;
-
- html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"";
- html.prepend(QByteArray().fill(' ', 512 - html.size()));
- QTest::newRow("invalid charset (large header)") << html << noDefault << fallback;
-
- html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"utf-8";
- QTest::newRow("invalid charset (no closing double quote)") << html << noDefault << fallback;
-
- html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset='utf-8";
- QTest::newRow("invalid charset (no closing single quote)") << html << noDefault << fallback;
-
- html = "<!DOCTYPE html><html><head><meta charset=utf-8 foo=bar><title>Test</title></head>";
- QTest::newRow("invalid (space terminator)") << html << noDefault << fallback;
-
- html = "<!DOCTYPE html><html><head><meta charset=\" utf' 8 /><title>Test</title></head>";
- QTest::newRow("invalid charset, early terminator (')") << html << noDefault << fallback;
-
- const char src[] = { char(0xff), char(0xfe), char(0x7a), char(0x03), 0, 0 };
- html = src;
- QTest::newRow("greek text UTF-16LE") << html << 106 << 1014;
-
- html = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><span style=\"color: rgb(0, 0, 0); font-family: "
- "'Galatia SIL'; font-size: 27px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; "
- "line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: "
- "auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: "
- "none;\">&#x37b</span>\000";
- QTest::newRow("greek text UTF-8") << html << 106 << 106;
-
- html = "<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=unicode\">"
- "<head/><body><p>bla</p></body></html>"; // QTBUG-41998, ICU will return UTF-16.
- QTest::newRow("legacy unicode UTF-8") << html << 106 << 106;
-}
-
-void tst_QTextCodec::codecForHtml()
-{
- QFETCH(QByteArray, html);
- QFETCH(int, defaultCodecMib);
- QFETCH(int, expectedMibEnum);
-
- if (defaultCodecMib != -1)
- QCOMPARE(QTextCodec::codecForHtml(html, QTextCodec::codecForMib(defaultCodecMib))->mibEnum(), expectedMibEnum);
- else // Test one parameter version when there is no default codec.
- QCOMPARE(QTextCodec::codecForHtml(html)->mibEnum(), expectedMibEnum);
-}
-
-void tst_QTextCodec::codecForUtfText_data()
-{
- QTest::addColumn<QByteArray>("encoded");
- QTest::addColumn<bool>("detected");
- QTest::addColumn<int>("mib");
-
-
- QTest::newRow("utf8 bom")
- << QByteArray("\xef\xbb\xbfhello")
- << true
- << 106;
- QTest::newRow("utf8 nobom")
- << QByteArray("hello")
- << false
- << 0;
-
- QTest::newRow("utf16 bom be")
- << QByteArray("\xfe\xff\0h\0e\0l", 8)
- << true
- << 1013;
- QTest::newRow("utf16 bom le")
- << QByteArray("\xff\xfeh\0e\0l\0", 8)
- << true
- << 1014;
- QTest::newRow("utf16 nobom")
- << QByteArray("\0h\0e\0l", 6)
- << false
- << 0;
-
- QTest::newRow("utf32 bom be")
- << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
- << true
- << 1018;
- QTest::newRow("utf32 bom le")
- << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
- << true
- << 1019;
- QTest::newRow("utf32 nobom")
- << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
- << false
- << 0;
-}
-
-void tst_QTextCodec::codecForUtfText()
-{
- QFETCH(QByteArray, encoded);
- QFETCH(bool, detected);
- QFETCH(int, mib);
-
- QTextCodec *codec = QTextCodec::codecForUtfText(encoded, 0);
- if (detected)
- QCOMPARE(codec->mibEnum(), mib);
- else
- QVERIFY(!codec);
-}
-
-#if defined(Q_OS_UNIX)
-void tst_QTextCodec::toLocal8Bit()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QProcess process;
- process.start("echo_helper");
- QString string(QChar(0x410));
- process.write((const char*)string.utf16(), string.length()*2);
-
- process.closeWriteChannel();
- process.waitForFinished();
- QCOMPARE(process.exitStatus(), QProcess::NormalExit);
- QCOMPARE(process.exitCode(), 0);
-#endif
-}
-#endif
-
-class LoadAndConvert: public QRunnable
-{
-public:
- LoadAndConvert(const QByteArray &source, QByteArray *destination)
- : codecName(source), target(destination)
- {}
- QByteArray codecName;
- QByteArray *target;
- void run()
- {
- QTextCodec *c = QTextCodec::codecForName(codecName);
- if (!c) {
- qWarning() << "WARNING" << codecName << "not found?";
- return;
- }
- QString str = QString::fromLatin1(codecName);
- QByteArray b = c->fromUnicode(str);
- c->toUnicode(b);
- *target = codecName;
- }
-};
-
-class LoadAndConvertMIB: public QRunnable
-{
-public:
- LoadAndConvertMIB(int mib, int *target)
- : mib(mib), target(target)
- {}
- int mib;
- int *target;
- void run()
- {
- QTextCodec *c = QTextCodec::codecForMib(mib);
- if (!c) {
- qWarning() << "WARNING" << mib << "not found?";
- return;
- }
- QString str = QString::number(mib);
- QByteArray b = c->fromUnicode(str);
- c->toUnicode(b);
- *target = mib;
- }
-};
-
-
-void tst_QTextCodec::threadSafety()
-{
- QList<QByteArray> codecList = QTextCodec::availableCodecs();
- const QVector<int> mibList = QTextCodec::availableMibs().toVector();
- QThreadPool::globalInstance()->setMaxThreadCount(12);
-
- QVector<QByteArray> res;
- res.resize(codecList.size());
- for (int i = 0; i < codecList.size(); ++i) {
- QThreadPool::globalInstance()->start(new LoadAndConvert(codecList.at(i), &res[i]));
- }
-
- QVector<int> res2;
- res2.resize(mibList.size());
- for (int i = 0; i < mibList.size(); ++i) {
- QThreadPool::globalInstance()->start(new LoadAndConvertMIB(mibList.at(i), &res2[i]));
- }
-
- // wait for all threads to finish working
- QThreadPool::globalInstance()->waitForDone();
-
- QCOMPARE(res.toList(), codecList);
- QCOMPARE(res2, mibList);
-}
-
-void tst_QTextCodec::invalidNames()
-{
- QVERIFY(!QTextCodec::codecForName(""));
- QVERIFY(!QTextCodec::codecForName(QByteArray()));
- QVERIFY(!QTextCodec::codecForName("-"));
- QVERIFY(!QTextCodec::codecForName("\1a\2b\3a\4d\5c\6s\7a\xffr\xec_\x9c_"));
- QVERIFY(!QTextCodec::codecForName("\n"));
- QVERIFY(!QTextCodec::codecForName("don't exist"));
- QByteArray huge = "azertyuiop^$qsdfghjklm<wxcvbn,;:=1234567890�_";
- huge = huge + huge + huge + huge + huge + huge + huge + huge;
- huge = huge + huge + huge + huge + huge + huge + huge + huge;
- huge = huge + huge + huge + huge + huge + huge + huge + huge;
- huge = huge + huge + huge + huge + huge + huge + huge + huge;
- QVERIFY(!QTextCodec::codecForName(huge));
-}
-
-void tst_QTextCodec::checkAliases_data()
-{
- QTest::addColumn<QByteArray>("codecName");
- const QList<QByteArray> codecList = QTextCodec::availableCodecs();
- for (const QByteArray &a : codecList)
- QTest::newRow( a.constData() ) << a;
-}
-
-void tst_QTextCodec::checkAliases()
-{
- QFETCH( QByteArray, codecName );
- QTextCodec *c = QTextCodec::codecForName(codecName);
- QVERIFY(c);
- QCOMPARE(QTextCodec::codecForName(codecName), c);
- QCOMPARE(QTextCodec::codecForName(c->name()), c);
-
- const auto aliases = c->aliases();
- for (const QByteArray &a : aliases) {
- QCOMPARE(QTextCodec::codecForName(a), c);
- }
-}
-
-
-void tst_QTextCodec::moreToFromUnicode_data() {
- QTest::addColumn<QByteArray>("codecName");
- QTest::addColumn<QByteArray>("testData");
-
- QTest::newRow("russian") << QByteArray("ISO-8859-5")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\x00");
-
- QTest::newRow("arabic") << QByteArray("ISO-8859-6")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA4\xAC\xAD\xBB\xBF\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2");
-
- QTest::newRow("greek") << QByteArray("ISO-8859-7")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA6\xA7\xA8\xA9\xAB\xAC\xAD\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE");
-
- QTest::newRow("turkish") << QByteArray("ISO-8859-9")
- << QByteArray("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("latin1") << QByteArray("ISO-8859-1")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QByteArray sms7bit_ba;
- for (int i=1; i <= 0x7f; ++i) {
- if (i!='\x1b') {
- sms7bit_ba.append(i);
- }
- }
-
- QTest::newRow("latin2") << QByteArray("ISO-8859-2")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("latin3") << QByteArray("ISO-8859-3")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBF\xC0\xC1\xC2\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("latin4") << QByteArray("ISO-8859-4")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("russian 2") << QByteArray("ISO-8859-5")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("arabic 2") << QByteArray("ISO-8859-6")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA4\xAC\xAD\xBB\xBF\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2");
-
- QTest::newRow("greek 2") << QByteArray("ISO-8859-7")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA6\xA7\xA8\xA9\xAB\xAC\xAD\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE");
-
- QTest::newRow("latin5") << QByteArray("ISO-8859-9")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("latin6") << QByteArray("ISO-8859-10")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
-#if 0
- QByteArray iso8859_11_ba;
- for (int x=0x20; x<=0x7f; ++x) {
- iso8859_11_ba.append(x);
- }
- for (int x=0xa0; x<0xff; ++x) {
- if ((x>=0xdb && x<0xdf) || x>0xfb){
- continue;
- }
- iso8859_11_ba.append(x);
- }
- QTest::newRow("latin-thai") << QByteArray("ISO-8859-11") << iso8859_11_ba;
-#endif
-
- QTest::newRow("latin7") << QByteArray("ISO-8859-13")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("celtic") << QByteArray("ISO-8859-14")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("latin9") << QByteArray("ISO-8859-15")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
-// QTest::newRow("latin10") << QByteArray("ISO-8859-16")
-// << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp850") << QByteArray("CP850")
- << QByteArray("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff");
-
- QTest::newRow("cp874") << QByteArray("CP874")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x85\x91\x92\x93\x94\x95\x96\x97\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB");
-
- QTest::newRow("cp1250") << QByteArray("CP1250")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x84\x85\x86\x87\x89\x8A\x8B\x8C\x8D\x8E\x8F\x91\x92\x93\x94\x95\x96\x97\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp1251") << QByteArray("CP1251")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp1252") << QByteArray("CP1252")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8E\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp1253") << QByteArray("CP1253")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x89\x8B\x91\x92\x93\x94\x95\x96\x97\x99\x9B\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE");
-
- QTest::newRow("cp1254") << QByteArray("CP1254")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp1255") << QByteArray("CP1255")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89,x8B\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9B\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFD\xFE");
-
- QTest::newRow("cp1256") << QByteArray("CP1256")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp1257") << QByteArray("CP1257")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x84\x85\x86\x87\x89\x8B\x8D\x8E\x8F\x91\x92\x93\x94\x95\x96\x97\x99\x9B\x9D\x9E\xA0\xA2\xA3\xA4\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QTest::newRow("cp1258") << QByteArray("CP1258")
- << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8B\x8C\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9B\x9C\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
-
- QByteArray koi8_r_ba;
- for (int x=0x20; x<=0xff; ++x) {
- if (x!=0x9A && x!=0xbf) {
- koi8_r_ba.append(x);
- }
- }
- QTest::newRow("KOI8-R") << QByteArray("KOI8-R") << koi8_r_ba;
-
- QByteArray koi8_u_ba;
- for (int x=0x20; x<=0xff; ++x) {
- koi8_u_ba.append(x);
- }
- QTest::newRow("KOI8-U") << QByteArray("KOI8-U") << koi8_u_ba;
-
-
- QByteArray big5_ba;
- for (unsigned char u=0xa1; u<=0xf9; u++) {
- if (u==0xc8) {
- continue;
- }
- for (unsigned char v=0x40; v<=0x7e; v++) {
- big5_ba.append(u);
- big5_ba.append(v);
- }
- unsigned char v_up;
- switch (u) {
- case 0xa2: v_up=0xa1; break;
- case 0xa3: v_up=0xbf; break;
- case 0xc7: v_up=0xfc; break;
- case 0xf9: v_up=0xd5; break;
- default: v_up=0xfe;
- }
-
- for (unsigned char v=0xa1; v<=v_up; v++) {
- if (u==0xa2 && (v==0xcc || v==0xce)) {
- continue;
- }
- big5_ba.append(u);
- big5_ba.append(v);
- }
- }
-
- QTest::newRow("BIG5") << QByteArray("BIG5") << big5_ba;
-
- QByteArray gb2312_ba;
- for (unsigned char u=0xa1; u<=0xf7; u++) {
- for (unsigned char v=0xa1; v<=0xfe; v++) {
- gb2312_ba.append(u);
- gb2312_ba.append(v);
- }
- }
-
- QTest::newRow("GB2312") << QByteArray("GB2312") << gb2312_ba;
-}
-
-void tst_QTextCodec::moreToFromUnicode()
-{
- QFETCH( QByteArray, codecName );
- QFETCH( QByteArray, testData );
-
- QTextCodec *c = QTextCodec::codecForName( codecName.data() );
- QVERIFY(c);
-
- QString uStr = c->toUnicode(testData);
- QByteArray cStr = c->fromUnicode(uStr);
- QCOMPARE(testData, cStr);
-}
-
-void tst_QTextCodec::shiftJis()
-{
- QByteArray backslashTilde("\\~");
- QTextCodec* codec = QTextCodec::codecForName("shift_jis");
- QString string = codec->toUnicode(backslashTilde);
- QCOMPARE(string.length(), 2);
- QCOMPARE(string.at(0), QChar(QLatin1Char('\\')));
- QCOMPARE(string.at(1), QChar(QLatin1Char('~')));
-
- QByteArray encoded = codec->fromUnicode(string);
- QCOMPARE(encoded, backslashTilde);
-}
-
-struct UserCodec : public QTextCodec
-{
- // implement pure virtuals
- QByteArray name() const override
- { return "UserCodec"; }
- QList<QByteArray> aliases() const override
- { return QList<QByteArray>() << "usercodec" << "user-codec"; }
- int mibEnum() const override
- { return 5000; }
-
- virtual QString convertToUnicode(const char *, int, ConverterState *) const override
- { return QString(); }
- virtual QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override
- { return QByteArray(); }
-};
-
-void tst_QTextCodec::userCodec()
-{
- // check that it isn't there
- static bool executedOnce = false;
- if (executedOnce)
- QSKIP("Test already executed once");
-
- QVERIFY(!QTextCodec::availableCodecs().contains("UserCodec"));
- QVERIFY(!QTextCodec::codecForName("UserCodec"));
-
- UserCodec *codec = new UserCodec;
- executedOnce = true;
-
- QList<QByteArray> availableCodecs = QTextCodec::availableCodecs();
- QVERIFY(availableCodecs.contains("UserCodec"));
- QVERIFY(availableCodecs.contains("usercodec"));
- QVERIFY(availableCodecs.contains("user-codec"));
-
- QTextCodec *pcodec = QTextCodec::codecForName("UserCodec");
- QCOMPARE(pcodec, codec);
-
- pcodec = QTextCodec::codecForName("user-codec");
- QCOMPARE(pcodec, codec);
-
- pcodec = QTextCodec::codecForName("User-Codec");
- QCOMPARE(pcodec, codec);
-
- pcodec = QTextCodec::codecForMib(5000);
- QCOMPARE(pcodec, codec);
-
- delete codec;
-
- pcodec = QTextCodec::codecForName("UserCodec");
- QCOMPARE(pcodec, nullptr);
-}
-
-struct DontCrashAtExit {
- ~DontCrashAtExit() {
- QTextCodec *c = QTextCodec::codecForName("utf8");
- if (c)
- c->toUnicode("azerty");
-
- }
-} dontCrashAtExit;
-
-
-QTEST_MAIN(tst_QTextCodec)
-#include "tst_qtextcodec.moc"
diff --git a/tests/auto/corelib/codecs/qtextcodec/utf8.txt b/tests/auto/corelib/codecs/qtextcodec/utf8.txt
deleted file mode 100644
index f5ab44c8f4..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/utf8.txt
+++ /dev/null
@@ -1 +0,0 @@
-<doc>𐀀􏿽</doc>
diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
deleted file mode 100644
index 9ce1748e72..0000000000
--- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
-
-#include <qtextcodec.h>
-#include <QScopedPointer>
-
-static const char utf8bom[] = "\xEF\xBB\xBF";
-
-class tst_Utf8 : public QObject
-{
- Q_OBJECT
-
-public:
- // test data:
- QTextCodec *codec;
- QString (*from8BitPtr)(const char *, int);
- static QByteArray to8Bit(const QString &);
-
- inline QString from8Bit(const QByteArray &ba)
- { return from8BitPtr(ba.constData(), ba.length()); }
-public slots:
- void initTestCase();
- void init();
-
-private slots:
- void roundTrip_data();
- void roundTrip();
-
- void charByChar_data();
- void charByChar();
-
- void invalidUtf8_data();
- void invalidUtf8();
-
- void nonCharacters_data();
- void nonCharacters();
-};
-
-void tst_Utf8::initTestCase()
-{
- QTest::addColumn<bool>("useLocale");
- QTest::newRow("utf8codec") << false;
-
- // is the locale UTF-8?
- if (QString(QChar(QChar::ReplacementCharacter)).toLocal8Bit() == "\xEF\xBF\xBD") {
- QTest::newRow("localecodec") << true;
- qInfo() << "locale is utf8";
- }
-}
-
-void tst_Utf8::init()
-{
- QFETCH_GLOBAL(bool, useLocale);
- if (useLocale) {
- codec = QTextCodec::codecForLocale();
- from8BitPtr = &QString::fromLocal8Bit;
- } else {
- codec = QTextCodec::codecForMib(106);
- from8BitPtr = &QString::fromUtf8;
- }
-}
-
-QByteArray tst_Utf8::to8Bit(const QString &s)
-{
- QFETCH_GLOBAL(bool, useLocale);
- if (useLocale)
- return s.toLocal8Bit();
- else
- return s.toUtf8();
-}
-
-void tst_Utf8::roundTrip_data()
-{
- QTest::addColumn<QByteArray>("utf8");
- QTest::addColumn<QString>("utf16");
-
- QTest::newRow("empty") << QByteArray() << QString();
- QTest::newRow("nul") << QByteArray("", 1) << QString(QChar(QChar::Null));
-
- static const char ascii[] = "This is a standard US-ASCII message";
- QTest::newRow("ascii") << QByteArray(ascii) << QString::fromLatin1(ascii);
-
- static const char ascii2[] = "\1This\2is\3an\4US-ASCII\020 message interspersed with control chars";
- QTest::newRow("ascii2") << QByteArray(ascii2) << QString::fromLatin1(ascii2);
-
- static const char utf8_1[] = "\302\240"; // NBSP
- QTest::newRow("utf8_1") << QByteArray(utf8_1) << QString(QChar(QChar::Nbsp));
-
- static const char utf8_2[] = "\342\202\254"; // Euro symbol
- QTest::newRow("utf8_2") << QByteArray(utf8_2) << QString(QChar(0x20AC));
-
-#if 0
- // Can't test this because QString::fromUtf8 consumes it
- static const char utf8_3[] = "\357\273\277"; // byte order mark
- QTest::newRow("utf8_3") << QByteArray(utf8_3) << QString(QChar(QChar::ByteOrderMark));
-#endif
-
- static const char utf8_4[] = "\357\277\275"; // replacement char
- QTest::newRow("utf8_4") << QByteArray(utf8_4) << QString(QChar(QChar::ReplacementCharacter));
-
- static const char utf8_5[] = "\360\220\210\203"; // U+010203
- static const uint utf32_5[] = { 0x010203 };
- QTest::newRow("utf8_5") << QByteArray(utf8_5) << QString::fromUcs4(utf32_5, 1);
-
- static const char utf8_6[] = "\364\217\277\275"; // U+10FFFD
- static const uint utf32_6[] = { 0x10FFFD };
- QTest::newRow("utf8_6") << QByteArray(utf8_6) << QString::fromUcs4(utf32_6, 1);
-
- static const char utf8_7[] = "abc\302\240\303\241\303\251\307\275 \342\202\254def";
- static const ushort utf16_7[] = { 'a', 'b', 'c', 0x00A0,
- 0x00E1, 0x00E9, 0x01FD,
- ' ', 0x20AC, 'd', 'e', 'f', 0 };
- QTest::newRow("utf8_7") << QByteArray(utf8_7) << QString::fromUtf16(utf16_7);
-
- static const char utf8_8[] = "abc\302\240\303\241\303\251\307\275 \364\217\277\275 \342\202\254def";
- static const uint utf32_8[] = { 'a', 'b', 'c', 0x00A0,
- 0x00E1, 0x00E9, 0x01FD,
- ' ', 0x10FFFD, ' ',
- 0x20AC, 'd', 'e', 'f', 0 };
- QTest::newRow("utf8_8") << QByteArray(utf8_8) << QString::fromUcs4(utf32_8);
-}
-
-void tst_Utf8::roundTrip()
-{
- QFETCH(QByteArray, utf8);
- QFETCH(QString, utf16);
-
- QCOMPARE(to8Bit(utf16), utf8);
- QCOMPARE(from8Bit(utf8), utf16);
-
- QCOMPARE(to8Bit(from8Bit(utf8)), utf8);
- QCOMPARE(from8Bit(to8Bit(utf16)), utf16);
-
- // repeat with a longer message
- utf8.prepend("12345678901234");
- utf16.prepend(QLatin1String("12345678901234"));
- QCOMPARE(to8Bit(utf16), utf8);
- QCOMPARE(from8Bit(utf8), utf16);
-
- QCOMPARE(to8Bit(from8Bit(utf8)), utf8);
- QCOMPARE(from8Bit(to8Bit(utf16)), utf16);
-}
-
-void tst_Utf8::charByChar_data()
-{
- roundTrip_data();
-}
-
-void tst_Utf8::charByChar()
-{
- QFETCH(QByteArray, utf8);
- QFETCH(QString, utf16);
-
- {
- // from utf16 to utf8 char by char:
- const QScopedPointer<QTextEncoder> encoder(codec->makeEncoder());
- QByteArray encoded;
-
- for (int i = 0; i < utf16.length(); ++i) {
- encoded += encoder->fromUnicode(utf16.constData() + i, 1);
- QVERIFY(!encoder->hasFailure());
- }
-
- if (encoded.startsWith(utf8bom))
- encoded = encoded.mid(int(strlen(utf8bom)));
- QCOMPARE(encoded, utf8);
- }
- {
- // from utf8 to utf16 char by char:
- const QScopedPointer<QTextDecoder> decoder(codec->makeDecoder());
- QString decoded;
-
- for (int i = 0; i < utf8.length(); ++i) {
- decoded += decoder->toUnicode(utf8.constData() + i, 1);
- QVERIFY(!decoder->hasFailure());
- }
-
- QCOMPARE(decoded, utf16);
- }
-}
-
-void tst_Utf8::invalidUtf8_data()
-{
- QTest::addColumn<QByteArray>("utf8");
-
- extern void loadInvalidUtf8Rows();
- loadInvalidUtf8Rows();
-}
-
-void tst_Utf8::invalidUtf8()
-{
- QFETCH(QByteArray, utf8);
- QFETCH_GLOBAL(bool, useLocale);
-
- const QScopedPointer<QTextDecoder> decoder(codec->makeDecoder());
- decoder->toUnicode(utf8);
-
- // Only enforce correctness on our UTF-8 decoder
- // The system's UTF-8 codec is sometimes buggy
- // GNU libc's iconv is known to accept U+FFFF and U+FFFE encoded as UTF-8
- // OS X's iconv is known to accept those, plus surrogates and codepoints above U+10FFFF
- if (!useLocale)
- QVERIFY(decoder->hasFailure() || decoder->needsMoreData());
- else if (!decoder->hasFailure() && !decoder->needsMoreData())
- qWarning("System codec does not report failure when it should. Should report bug upstream.");
-
- // add a continuation character and test that we don't accidentally use it
- // (buffer overrun)
- utf8 += char(0x80 | 0x3f);
- decoder->toUnicode(utf8.constData(), utf8.size() - 1);
- if (!useLocale)
- QVERIFY(decoder->hasFailure());
- else if (!decoder->hasFailure())
- qWarning("System codec does not report failure when it should. Should report bug upstream.");
-}
-
-void tst_Utf8::nonCharacters_data()
-{
- QTest::addColumn<QByteArray>("utf8");
- QTest::addColumn<QString>("utf16");
-
- extern void loadNonCharactersRows();
- loadNonCharactersRows();
-}
-
-void tst_Utf8::nonCharacters()
-{
- QFETCH(QByteArray, utf8);
- QFETCH(QString, utf16);
- QFETCH_GLOBAL(bool, useLocale);
-
- const QScopedPointer<QTextDecoder> decoder(codec->makeDecoder());
- decoder->toUnicode(utf8);
-
- // Only enforce correctness on our UTF-8 decoder
- if (!useLocale)
- QVERIFY(!decoder->hasFailure());
- else if (decoder->hasFailure())
- qWarning("System codec reports failure when it shouldn't. Should report bug upstream.");
-
- const QScopedPointer<QTextEncoder> encoder(codec->makeEncoder());
- encoder->fromUnicode(utf16);
- if (!useLocale)
- QVERIFY(!encoder->hasFailure());
- else if (encoder->hasFailure())
- qWarning("System codec reports failure when it shouldn't. Should report bug upstream.");
-}
-
-QTEST_MAIN(tst_Utf8)
-#include "tst_utf8.moc"
diff --git a/tests/auto/corelib/codecs/utf8/utf8.pro b/tests/auto/corelib/codecs/utf8/utf8.pro
deleted file mode 100644
index 355d890824..0000000000
--- a/tests/auto/corelib/codecs/utf8/utf8.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_utf8
-QT = core testlib
-SOURCES += tst_utf8.cpp utf8data.cpp
diff --git a/tests/auto/corelib/codecs/utf8/utf8data.cpp b/tests/auto/corelib/codecs/utf8/utf8data.cpp
deleted file mode 100644
index 221e1d5579..0000000000
--- a/tests/auto/corelib/codecs/utf8/utf8data.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
-
-void loadInvalidUtf8Rows()
-{
- // Wrong continuations
- QTest::newRow("bad-continuation-1char") << QByteArray("\x80");
- QTest::newRow("bad-continuation-2chars-1") << QByteArray("\xC2\xC0");
- QTest::newRow("bad-continuation-2chars-2") << QByteArray("\xC3\xDF");
- QTest::newRow("bad-continuation-2chars-3") << QByteArray("\xC7\xF0");
- QTest::newRow("bad-continuation-3chars-1") << QByteArray("\xE0\xA0\xC0");
- QTest::newRow("bad-continuation-3chars-2") << QByteArray("\xE0\xC0\xA0");
- QTest::newRow("bad-continuation-4chars-1") << QByteArray("\xF0\x90\x80\xC0");
- QTest::newRow("bad-continuation-4chars-2") << QByteArray("\xF0\x90\xC0\x80");
- QTest::newRow("bad-continuation-4chars-3") << QByteArray("\xF0\xC0\x80\x80");
-
- // Too short
- QTest::newRow("too-short-2chars") << QByteArray("\xC2");
- QTest::newRow("too-short-3chars-1") << QByteArray("\xE0");
- QTest::newRow("too-short-3chars-2") << QByteArray("\xE0\xA0");
- QTest::newRow("too-short-4chars-1") << QByteArray("\xF0");
- QTest::newRow("too-short-4chars-2") << QByteArray("\xF0\x90");
- QTest::newRow("too-short-4chars-3") << QByteArray("\xF0\x90\x80");
-
- // Surrogate pairs must now be present either
- // U+D800: 1101 10 0000 00 0000
- // encoding: xxxz:1101 xz10:0000 xz00:0000
- QTest::newRow("hi-surrogate") << QByteArray("\xED\xA0\x80");
- // U+DC00: 1101 11 0000 00 0000
- // encoding: xxxz:1101 xz11:0000 xz00:0000
- QTest::newRow("lo-surrogate") << QByteArray("\xED\xB0\x80");
-
- // not even in pair:
- QTest::newRow("surrogate-pair") << QByteArray("\xED\xA0\x80\xED\xB0\x80");
-
- // Characters outside the Unicode range:
- // 0x110000: 00 0100 01 0000 00 0000 00 0000
- // encoding: xxxx:z100 xz01:0000 xz00:0000 xz00:0000
- QTest::newRow("non-unicode-1") << QByteArray("\xF4\x90\x80\x80");
- // 0x200000: 00 1000 00 0000 00 0000 00 0000
- // encoding: xxxx:xz00 xz00:1000 xz00:0000 xz00:0000 xz00:0000
- QTest::newRow("non-unicode-2") << QByteArray("\xF8\x88\x80\x80\x80");
- // 0x04000000: 0100 00 0000 00 0000 00 0000 00 0000
- // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80");
- // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111
- // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF");
-
- // As seen above, 0xFE and 0xFF never appear:
- QTest::newRow("fe") << QByteArray("\xFE");
- QTest::newRow("fe-bis") << QByteArray("\xFE\xBF\xBF\xBF\xBF\xBF\xBF");
- QTest::newRow("ff") << QByteArray("\xFF");
- QTest::newRow("ff-bis") << QByteArray("\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF");
-
- // some combinations in UTF-8 are invalid even though they have the proper bits set
- // these are known as overlong sequences
-
- // "A": U+0041: 01 00 0001
- // overlong 2: xxz0:0001 xz00:0001
- QTest::newRow("overlong-1-2") << QByteArray("\xC1\x81");
- // overlong 3: xxxz:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-3") << QByteArray("\xE0\x81\x81");
- // overlong 4: xxxx:z000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-4") << QByteArray("\xF0\x80\x81\x81");
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-5") << QByteArray("\xF8\x80\x80\x81\x81");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0001 xz00:0001
- QTest::newRow("overlong-1-6") << QByteArray("\xFC\x80\x80\x80\x81\x81");
-
- // U+0080: 10 00 0000
- // proper encoding: xxz0:0010 xz00:0000
- // overlong 3: xxxz:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-3") << QByteArray("\xE0\x82\x80");
- // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80");
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000
- QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80");
-
- // U+0800: 10 0000 00 0000
- // proper encoding: xxxz:0000 xz10:0000 xz00:0000
- // overlong 4: xxxx:z000 xz00:0000 xz10:0000 xz00:0000
- QTest::newRow("overlong-3-4") << QByteArray("\xF0\x80\xA0\x80");
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz10:0000 xz00:0000
- QTest::newRow("overlong-3-5") << QByteArray("\xF8\x80\x80\xA0\x80");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz10:0000 xz00:0000
- QTest::newRow("overlong-3-6") << QByteArray("\xFC\x80\x80\x80\xA0\x80");
-
- // U+010000: 00 0100 00 0000 00 0000
- // proper encoding: xxxx:z000 xz00:0100 xz00:0000 xz00:0000
- // overlong 5: xxxx:xz00 xz00:0000 xz00:0100 xz00:0000 xz00:0000
- QTest::newRow("overlong-4-5") << QByteArray("\xF8\x80\x84\x80\x80");
- // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0100 xz00:0000 xz00:0000
- QTest::newRow("overlong-4-6") << QByteArray("\xFC\x80\x80\x84\x80\x80");
-
-}
-
-void loadNonCharactersRows()
-{
- // Unicode has a couple of "non-characters" that one can use internally
- // These characters are allowed for text-interchange (see http://www.unicode.org/versions/corrigendum9.html)
- //
- // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
- // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
- // U+FDEF (inclusive)
-
- // U+FDD0 through U+FDEF
- for (int i = 0; i < 16; ++i) {
- char utf8[] = { char(0357), char(0267), char(0220 + i), 0 };
- QString utf16 = QChar(0xfdd0 + i);
- QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16;
- }
-
- // the last two in Planes 1 through 16
- for (uint plane = 1; plane <= 16; ++plane) {
- for (uint lower = 0xfffe; lower < 0x10000; ++lower) {
- uint ucs4 = (plane << 16) | lower;
- char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)),
- char(0x80 | (uchar(ucs4 >> 12) & 0x3f)),
- char(0x80 | (uchar(ucs4 >> 6) & 0x3f)),
- char(0x80 | (uchar(ucs4) & 0x3f)),
- 0 };
- ushort utf16[] = { QChar::highSurrogate(ucs4), QChar::lowSurrogate(ucs4), 0 };
-
- QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QString::fromUtf16(utf16);
- }
- }
-
- QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe));
- QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff));
-}
diff --git a/tests/auto/corelib/corelib.pro b/tests/auto/corelib/corelib.pro
deleted file mode 100644
index 44e1c519b0..0000000000
--- a/tests/auto/corelib/corelib.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-TEMPLATE=subdirs
-
-SUBDIRS = \
- kernel
-
-!uikit: SUBDIRS += \
- animation \
- codecs \
- global \
- io \
- itemmodels \
- mimetypes \
- plugin \
- serialization \
- statemachine \
- thread \
- tools
diff --git a/tests/auto/corelib/global/CMakeLists.txt b/tests/auto/corelib/global/CMakeLists.txt
new file mode 100644
index 0000000000..7970116672
--- /dev/null
+++ b/tests/auto/corelib/global/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT INTEGRITY)
+ add_subdirectory(qcompare)
+endif()
+add_subdirectory(qcomparehelpers)
+add_subdirectory(qflags)
+add_subdirectory(q_func_info)
+add_subdirectory(qgetputenv)
+add_subdirectory(qglobal)
+add_subdirectory(qnumeric)
+add_subdirectory(qfloat16)
+add_subdirectory(qkeycombination)
+if(NOT INTEGRITY)
+ add_subdirectory(qnativeinterface)
+endif()
+add_subdirectory(qrandomgenerator)
+add_subdirectory(qlogging)
+add_subdirectory(qtendian)
+add_subdirectory(qglobalstatic)
+add_subdirectory(qhooks)
+add_subdirectory(qoperatingsystemversion)
+add_subdirectory(qxp)
+add_subdirectory(q20)
diff --git a/tests/auto/corelib/global/global.pro b/tests/auto/corelib/global/global.pro
deleted file mode 100644
index 139e073644..0000000000
--- a/tests/auto/corelib/global/global.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qflags \
- q_func_info \
- qgetputenv \
- qglobal \
- qnumeric \
- qfloat16 \
- qrand \
- qrandomgenerator \
- qlogging \
- qtendian \
- qglobalstatic \
- qhooks
diff --git a/tests/auto/corelib/global/q20/CMakeLists.txt b/tests/auto/corelib/global/q20/CMakeLists.txt
new file mode 100644
index 0000000000..bd28f8b999
--- /dev/null
+++ b/tests/auto/corelib/global/q20/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(memory)
diff --git a/tests/auto/corelib/global/q20/memory/CMakeLists.txt b/tests/auto/corelib/global/q20/memory/CMakeLists.txt
new file mode 100644
index 0000000000..f36ff0f592
--- /dev/null
+++ b/tests/auto/corelib/global/q20/memory/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_q20_memory LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_q20_memory
+ EXCEPTIONS
+ SOURCES
+ tst_q20_memory.cpp
+ LIBRARIES
+ Qt::Core
+)
diff --git a/tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp b/tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp
new file mode 100644
index 0000000000..22dbb09e7c
--- /dev/null
+++ b/tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp
@@ -0,0 +1,161 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <q20memory.h>
+#include <QtCore/q20memory.h>
+
+#include <QTest>
+#include <QObject>
+#include <QExplicitlySharedDataPointer>
+#include <QSharedDataPointer>
+
+struct Private : QSharedData {};
+
+class tst_q20_memory : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void raw();
+ void smart();
+ void recursion();
+ void usesPointerTraits();
+ void prefersPointerTraits();
+
+private Q_SLOTS:
+ void to_address_broken_const_propagation_QExplicitlySharedDataPointer()
+ { to_address_broken_const_propagation<QExplicitlySharedDataPointer<Private>>(); }
+ void to_address_broken_const_propagation_QSharedDataPointer()
+ { to_address_broken_const_propagation<QSharedDataPointer<Private>>(); }
+ void to_address_broken_const_propagation_shared_ptr()
+ { to_address_broken_const_propagation<std::shared_ptr<Private>>(); }
+ void to_address_broken_const_propagation_unique_ptr()
+ { to_address_broken_const_propagation<std::unique_ptr<Private>>(); }
+
+private:
+ template <typename Pointer>
+ void to_address_broken_const_propagation();
+};
+
+void tst_q20_memory::raw()
+{
+ auto i = 0;
+ auto p = &i;
+ QVERIFY(q20::to_address(p) == &i);
+}
+
+template <typename T>
+class MinimalPtr {
+public:
+ using element_type = T;
+
+ explicit MinimalPtr(T *d) : d(d) {}
+
+ T *operator->() const noexcept { return d; }
+
+private:
+ T *d;
+};
+
+void tst_q20_memory::smart()
+{
+ int i;
+ MinimalPtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename T>
+class RecursivePtr {
+public:
+ using element_type = T;
+
+ explicit RecursivePtr(T *d) : d(d) {}
+
+ MinimalPtr<T> operator->() const noexcept { return d; }
+
+private:
+ MinimalPtr<T> d;
+};
+
+void tst_q20_memory::recursion()
+{
+ int i;
+ RecursivePtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename T>
+class NoDerefOperatorPtr {
+public:
+ using element_type = T;
+
+ explicit NoDerefOperatorPtr(T *d) : d(d) {}
+
+ T *get() const noexcept { return d; }
+
+private:
+ T *d;
+};
+
+namespace std {
+template <typename T>
+struct pointer_traits<NoDerefOperatorPtr<T>>
+{
+ static T *to_address(const NoDerefOperatorPtr<T> &ptr) noexcept { return ptr.get(); }
+};
+} // namespace std
+
+void tst_q20_memory::usesPointerTraits()
+{
+ int i;
+ NoDerefOperatorPtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename T>
+class PrefersPointerTraitsPtr
+{
+public:
+ using element_type = T;
+
+ explicit PrefersPointerTraitsPtr(T *d) : d(d) {}
+
+ T *operator->() const noexcept { return nullptr; }
+
+ T *get() const noexcept { return d; }
+
+private:
+ T *d;
+};
+
+namespace std {
+template <typename T>
+struct pointer_traits<PrefersPointerTraitsPtr<T>>
+{
+ static T *to_address(const PrefersPointerTraitsPtr<T> &p) noexcept { return p.get(); }
+};
+} // namespace std
+
+void tst_q20_memory::prefersPointerTraits()
+{
+ int i;
+ PrefersPointerTraitsPtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename Pointer>
+void tst_q20_memory::to_address_broken_const_propagation()
+{
+ Pointer p(nullptr);
+ QCOMPARE_EQ(q20::to_address(p), nullptr);
+ p = Pointer{new Private()};
+ QCOMPARE_EQ(q20::to_address(p), p.operator->());
+ static_assert(std::is_same_v<decltype(q20::to_address(p)),
+ decltype(std::as_const(p).operator->())>);
+}
+
+QTEST_GUILESS_MAIN(tst_q20_memory)
+#include "tst_q20_memory.moc"
+
diff --git a/tests/auto/corelib/global/q_func_info/CMakeLists.txt b/tests/auto/corelib/global/q_func_info/CMakeLists.txt
new file mode 100644
index 0000000000..88119484cd
--- /dev/null
+++ b/tests/auto/corelib/global/q_func_info/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_q_func_info Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_q_func_info LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_q_func_info
+ SOURCES
+ tst_q_func_info.cpp
+)
diff --git a/tests/auto/corelib/global/q_func_info/q_func_info.pro b/tests/auto/corelib/global/q_func_info/q_func_info.pro
deleted file mode 100644
index 7663a880eb..0000000000
--- a/tests/auto/corelib/global/q_func_info/q_func_info.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_q_func_info
-QT = core testlib
-SOURCES = tst_q_func_info.cpp
diff --git a/tests/auto/corelib/global/q_func_info/tst_q_func_info.cpp b/tests/auto/corelib/global/q_func_info/tst_q_func_info.cpp
index 32e4217ad0..b288f1d3a1 100644
--- a/tests/auto/corelib/global/q_func_info/tst_q_func_info.cpp
+++ b/tests/auto/corelib/global/q_func_info/tst_q_func_info.cpp
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QString>
-#include <QtTest/QtTest>
+#include <QTest>
#include <QtDebug>
class tst_q_func_info : public QObject
diff --git a/tests/auto/corelib/global/qcompare/CMakeLists.txt b/tests/auto/corelib/global/qcompare/CMakeLists.txt
new file mode 100644
index 0000000000..b29dcae618
--- /dev/null
+++ b/tests/auto/corelib/global/qcompare/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcompare Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcompare LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcompare
+ SOURCES
+ tst_qcompare.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
new file mode 100644
index 0000000000..e36429e62b
--- /dev/null
+++ b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
@@ -0,0 +1,840 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QtCompare>
+#include <QtTest/QTest>
+
+#ifdef __cpp_lib_three_way_comparison
+#include <compare>
+#endif // __cpp_lib_three_way_comparison
+
+class tst_QCompare: public QObject
+{
+ Q_OBJECT
+private slots:
+ void legacyPartialOrdering();
+ void legacyConversions();
+ void stdQtBinaryCompatibility();
+ void partialOrdering();
+ void weakOrdering();
+ void strongOrdering();
+ void threeWayCompareWithLiteralZero();
+ void conversions();
+ void is_eq_overloads();
+ void compareThreeWay();
+};
+
+void tst_QCompare::legacyPartialOrdering()
+{
+ static_assert(QPartialOrdering::Unordered == QPartialOrdering::unordered);
+ static_assert(QPartialOrdering::Less == QPartialOrdering::less);
+ static_assert(QPartialOrdering::Equivalent == QPartialOrdering::equivalent);
+ static_assert(QPartialOrdering::Greater == QPartialOrdering::greater);
+
+ static_assert(QPartialOrdering::Unordered == QPartialOrdering::Unordered);
+ static_assert(QPartialOrdering::Unordered != QPartialOrdering::Less);
+ static_assert(QPartialOrdering::Unordered != QPartialOrdering::Equivalent);
+ static_assert(QPartialOrdering::Unordered != QPartialOrdering::Greater);
+
+ static_assert(QPartialOrdering::Less != QPartialOrdering::Unordered);
+ static_assert(QPartialOrdering::Less == QPartialOrdering::Less);
+ static_assert(QPartialOrdering::Less != QPartialOrdering::Equivalent);
+ static_assert(QPartialOrdering::Less != QPartialOrdering::Greater);
+
+ static_assert(QPartialOrdering::Equivalent != QPartialOrdering::Unordered);
+ static_assert(QPartialOrdering::Equivalent != QPartialOrdering::Less);
+ static_assert(QPartialOrdering::Equivalent == QPartialOrdering::Equivalent);
+ static_assert(QPartialOrdering::Equivalent != QPartialOrdering::Greater);
+
+ static_assert(QPartialOrdering::Greater != QPartialOrdering::Unordered);
+ static_assert(QPartialOrdering::Greater != QPartialOrdering::Less);
+ static_assert(QPartialOrdering::Greater != QPartialOrdering::Equivalent);
+ static_assert(QPartialOrdering::Greater == QPartialOrdering::Greater);
+
+ static_assert(!is_eq (QPartialOrdering::Unordered));
+ static_assert(!is_neq (QPartialOrdering::Unordered));
+ static_assert(!is_lt (QPartialOrdering::Unordered));
+ static_assert(!is_lteq(QPartialOrdering::Unordered));
+ static_assert(!is_gt (QPartialOrdering::Unordered));
+ static_assert(!is_gteq(QPartialOrdering::Unordered));
+
+ static_assert(!(QPartialOrdering::Unordered == 0));
+ static_assert(!(QPartialOrdering::Unordered != 0));
+ static_assert(!(QPartialOrdering::Unordered < 0));
+ static_assert(!(QPartialOrdering::Unordered <= 0));
+ static_assert(!(QPartialOrdering::Unordered > 0));
+ static_assert(!(QPartialOrdering::Unordered >= 0));
+
+ static_assert(!(0 == QPartialOrdering::Unordered));
+ static_assert(!(0 != QPartialOrdering::Unordered));
+ static_assert(!(0 < QPartialOrdering::Unordered));
+ static_assert(!(0 <= QPartialOrdering::Unordered));
+ static_assert(!(0 > QPartialOrdering::Unordered));
+ static_assert(!(0 >= QPartialOrdering::Unordered));
+
+
+ static_assert(!is_eq (QPartialOrdering::Less));
+ static_assert( is_neq (QPartialOrdering::Less));
+ static_assert( is_lt (QPartialOrdering::Less));
+ static_assert( is_lteq(QPartialOrdering::Less));
+ static_assert(!is_gt (QPartialOrdering::Less));
+ static_assert(!is_gteq(QPartialOrdering::Less));
+
+ static_assert(!(QPartialOrdering::Less == 0));
+ static_assert( (QPartialOrdering::Less != 0));
+ static_assert( (QPartialOrdering::Less < 0));
+ static_assert( (QPartialOrdering::Less <= 0));
+ static_assert(!(QPartialOrdering::Less > 0));
+ static_assert(!(QPartialOrdering::Less >= 0));
+
+ static_assert(!(0 == QPartialOrdering::Less));
+ static_assert( (0 != QPartialOrdering::Less));
+ static_assert(!(0 < QPartialOrdering::Less));
+ static_assert(!(0 <= QPartialOrdering::Less));
+ static_assert( (0 > QPartialOrdering::Less));
+ static_assert( (0 >= QPartialOrdering::Less));
+
+
+ static_assert( is_eq (QPartialOrdering::Equivalent));
+ static_assert(!is_neq (QPartialOrdering::Equivalent));
+ static_assert(!is_lt (QPartialOrdering::Equivalent));
+ static_assert( is_lteq(QPartialOrdering::Equivalent));
+ static_assert(!is_gt (QPartialOrdering::Equivalent));
+ static_assert( is_gteq(QPartialOrdering::Equivalent));
+
+ static_assert( (QPartialOrdering::Equivalent == 0));
+ static_assert(!(QPartialOrdering::Equivalent != 0));
+ static_assert(!(QPartialOrdering::Equivalent < 0));
+ static_assert( (QPartialOrdering::Equivalent <= 0));
+ static_assert(!(QPartialOrdering::Equivalent > 0));
+ static_assert( (QPartialOrdering::Equivalent >= 0));
+
+ static_assert( (0 == QPartialOrdering::Equivalent));
+ static_assert(!(0 != QPartialOrdering::Equivalent));
+ static_assert(!(0 < QPartialOrdering::Equivalent));
+ static_assert( (0 <= QPartialOrdering::Equivalent));
+ static_assert(!(0 > QPartialOrdering::Equivalent));
+ static_assert( (0 >= QPartialOrdering::Equivalent));
+
+
+ static_assert(!is_eq (QPartialOrdering::Greater));
+ static_assert( is_neq (QPartialOrdering::Greater));
+ static_assert(!is_lt (QPartialOrdering::Greater));
+ static_assert(!is_lteq(QPartialOrdering::Greater));
+ static_assert( is_gt (QPartialOrdering::Greater));
+ static_assert( is_gteq(QPartialOrdering::Greater));
+
+ static_assert(!(QPartialOrdering::Greater == 0));
+ static_assert( (QPartialOrdering::Greater != 0));
+ static_assert(!(QPartialOrdering::Greater < 0));
+ static_assert(!(QPartialOrdering::Greater <= 0));
+ static_assert( (QPartialOrdering::Greater > 0));
+ static_assert( (QPartialOrdering::Greater >= 0));
+
+ static_assert(!(0 == QPartialOrdering::Greater));
+ static_assert( (0 != QPartialOrdering::Greater));
+ static_assert( (0 < QPartialOrdering::Greater));
+ static_assert( (0 <= QPartialOrdering::Greater));
+ static_assert(!(0 > QPartialOrdering::Greater));
+ static_assert(!(0 >= QPartialOrdering::Greater));
+}
+
+void tst_QCompare::legacyConversions()
+{
+#define CHECK_CONVERTS(Lhs, Rhs) static_assert(std::is_convertible_v<Lhs, Rhs>)
+#define CHECK_ALL(NS) do { \
+ CHECK_CONVERTS(QPartialOrdering, NS ::partial_ordering); \
+ static_assert(QPartialOrdering::Less == NS ::partial_ordering::less); \
+ static_assert(QPartialOrdering::Greater == NS ::partial_ordering::greater); \
+ static_assert(QPartialOrdering::Equivalent == NS ::partial_ordering::equivalent); \
+ static_assert(QPartialOrdering::Unordered == NS ::partial_ordering::unordered); \
+ \
+ CHECK_CONVERTS(NS ::partial_ordering, QPartialOrdering); \
+ CHECK_CONVERTS(NS ::weak_ordering, QPartialOrdering); \
+ CHECK_CONVERTS(NS ::strong_ordering, QPartialOrdering); \
+ } while (false)
+
+ CHECK_ALL(Qt);
+#ifdef __cpp_lib_three_way_comparison
+ CHECK_ALL(std);
+#endif // __cpp_lib_three_way_comparison
+
+#undef CHECK_ALL
+#undef CHECK_CONVERTS
+}
+
+void tst_QCompare::stdQtBinaryCompatibility()
+{
+#ifndef __cpp_lib_three_way_comparison
+ QSKIP("This test requires C++20 three-way-comparison support enabled in the stdlib.");
+#else
+ QCOMPARE_EQ(sizeof(std::partial_ordering), 1U);
+ QCOMPARE_EQ(sizeof( Qt::partial_ordering), 1U);
+ QCOMPARE_EQ(sizeof(std:: weak_ordering), 1U);
+ QCOMPARE_EQ(sizeof( Qt:: weak_ordering), 1U);
+ QCOMPARE_EQ(sizeof(std:: strong_ordering), 1U);
+ QCOMPARE_EQ(sizeof( Qt:: strong_ordering), 1U);
+
+ auto valueOf = [](auto obj) {
+ typename QIntegerForSizeof<decltype(obj)>::Unsigned value;
+ memcpy(&value, &obj, sizeof(obj));
+ return value;
+ };
+#define CHECK(type, flag) \
+ QCOMPARE_EQ(valueOf( Qt:: type ## _ordering :: flag), \
+ valueOf(std:: type ## _ordering :: flag)) \
+ /* end */
+ CHECK(partial, unordered);
+ CHECK(partial, less);
+ CHECK(partial, greater);
+ CHECK(partial, equivalent);
+
+ CHECK(weak, less);
+ CHECK(weak, greater);
+ CHECK(weak, equivalent);
+
+ CHECK(strong, less);
+ CHECK(strong, greater);
+ CHECK(strong, equivalent);
+ CHECK(strong, equal);
+#undef CHECK
+#endif //__cpp_lib_three_way_comparison
+}
+
+void tst_QCompare::partialOrdering()
+{
+ static_assert(Qt::partial_ordering::unordered == Qt::partial_ordering::unordered);
+ static_assert(Qt::partial_ordering::unordered != Qt::partial_ordering::less);
+ static_assert(Qt::partial_ordering::unordered != Qt::partial_ordering::equivalent);
+ static_assert(Qt::partial_ordering::unordered != Qt::partial_ordering::greater);
+
+ static_assert(Qt::partial_ordering::less != Qt::partial_ordering::unordered);
+ static_assert(Qt::partial_ordering::less == Qt::partial_ordering::less);
+ static_assert(Qt::partial_ordering::less != Qt::partial_ordering::equivalent);
+ static_assert(Qt::partial_ordering::less != Qt::partial_ordering::greater);
+
+ static_assert(Qt::partial_ordering::equivalent != Qt::partial_ordering::unordered);
+ static_assert(Qt::partial_ordering::equivalent != Qt::partial_ordering::less);
+ static_assert(Qt::partial_ordering::equivalent == Qt::partial_ordering::equivalent);
+ static_assert(Qt::partial_ordering::equivalent != Qt::partial_ordering::greater);
+
+ static_assert(Qt::partial_ordering::greater != Qt::partial_ordering::unordered);
+ static_assert(Qt::partial_ordering::greater != Qt::partial_ordering::less);
+ static_assert(Qt::partial_ordering::greater != Qt::partial_ordering::equivalent);
+ static_assert(Qt::partial_ordering::greater == Qt::partial_ordering::greater);
+
+ static_assert(!is_eq (Qt::partial_ordering::unordered));
+ static_assert(!is_neq (Qt::partial_ordering::unordered));
+ static_assert(!is_lt (Qt::partial_ordering::unordered));
+ static_assert(!is_lteq(Qt::partial_ordering::unordered));
+ static_assert(!is_gt (Qt::partial_ordering::unordered));
+ static_assert(!is_gteq(Qt::partial_ordering::unordered));
+
+ static_assert(!(Qt::partial_ordering::unordered == 0));
+ static_assert(!(Qt::partial_ordering::unordered != 0));
+ static_assert(!(Qt::partial_ordering::unordered < 0));
+ static_assert(!(Qt::partial_ordering::unordered <= 0));
+ static_assert(!(Qt::partial_ordering::unordered > 0));
+ static_assert(!(Qt::partial_ordering::unordered >= 0));
+
+ static_assert(!(0 == Qt::partial_ordering::unordered));
+ static_assert(!(0 != Qt::partial_ordering::unordered));
+ static_assert(!(0 < Qt::partial_ordering::unordered));
+ static_assert(!(0 <= Qt::partial_ordering::unordered));
+ static_assert(!(0 > Qt::partial_ordering::unordered));
+ static_assert(!(0 >= Qt::partial_ordering::unordered));
+
+
+ static_assert(!is_eq (Qt::partial_ordering::less));
+ static_assert( is_neq (Qt::partial_ordering::less));
+ static_assert( is_lt (Qt::partial_ordering::less));
+ static_assert( is_lteq(Qt::partial_ordering::less));
+ static_assert(!is_gt (Qt::partial_ordering::less));
+ static_assert(!is_gteq(Qt::partial_ordering::less));
+
+ static_assert(!(Qt::partial_ordering::less == 0));
+ static_assert( (Qt::partial_ordering::less != 0));
+ static_assert( (Qt::partial_ordering::less < 0));
+ static_assert( (Qt::partial_ordering::less <= 0));
+ static_assert(!(Qt::partial_ordering::less > 0));
+ static_assert(!(Qt::partial_ordering::less >= 0));
+
+ static_assert(!(0 == Qt::partial_ordering::less));
+ static_assert( (0 != Qt::partial_ordering::less));
+ static_assert(!(0 < Qt::partial_ordering::less));
+ static_assert(!(0 <= Qt::partial_ordering::less));
+ static_assert( (0 > Qt::partial_ordering::less));
+ static_assert( (0 >= Qt::partial_ordering::less));
+
+
+ static_assert( is_eq (Qt::partial_ordering::equivalent));
+ static_assert(!is_neq (Qt::partial_ordering::equivalent));
+ static_assert(!is_lt (Qt::partial_ordering::equivalent));
+ static_assert( is_lteq(Qt::partial_ordering::equivalent));
+ static_assert(!is_gt (Qt::partial_ordering::equivalent));
+ static_assert( is_gteq(Qt::partial_ordering::equivalent));
+
+ static_assert( (Qt::partial_ordering::equivalent == 0));
+ static_assert(!(Qt::partial_ordering::equivalent != 0));
+ static_assert(!(Qt::partial_ordering::equivalent < 0));
+ static_assert( (Qt::partial_ordering::equivalent <= 0));
+ static_assert(!(Qt::partial_ordering::equivalent > 0));
+ static_assert( (Qt::partial_ordering::equivalent >= 0));
+
+ static_assert( (0 == Qt::partial_ordering::equivalent));
+ static_assert(!(0 != Qt::partial_ordering::equivalent));
+ static_assert(!(0 < Qt::partial_ordering::equivalent));
+ static_assert( (0 <= Qt::partial_ordering::equivalent));
+ static_assert(!(0 > Qt::partial_ordering::equivalent));
+ static_assert( (0 >= Qt::partial_ordering::equivalent));
+
+
+ static_assert(!is_eq (Qt::partial_ordering::greater));
+ static_assert( is_neq (Qt::partial_ordering::greater));
+ static_assert(!is_lt (Qt::partial_ordering::greater));
+ static_assert(!is_lteq(Qt::partial_ordering::greater));
+ static_assert( is_gt (Qt::partial_ordering::greater));
+ static_assert( is_gteq(Qt::partial_ordering::greater));
+
+ static_assert(!(Qt::partial_ordering::greater == 0));
+ static_assert( (Qt::partial_ordering::greater != 0));
+ static_assert(!(Qt::partial_ordering::greater < 0));
+ static_assert(!(Qt::partial_ordering::greater <= 0));
+ static_assert( (Qt::partial_ordering::greater > 0));
+ static_assert( (Qt::partial_ordering::greater >= 0));
+
+ static_assert(!(0 == Qt::partial_ordering::greater));
+ static_assert( (0 != Qt::partial_ordering::greater));
+ static_assert( (0 < Qt::partial_ordering::greater));
+ static_assert( (0 <= Qt::partial_ordering::greater));
+ static_assert(!(0 > Qt::partial_ordering::greater));
+ static_assert(!(0 >= Qt::partial_ordering::greater));
+}
+
+void tst_QCompare::weakOrdering()
+{
+ static_assert(Qt::weak_ordering::less == Qt::weak_ordering::less);
+ static_assert(Qt::weak_ordering::less != Qt::weak_ordering::equivalent);
+ static_assert(Qt::weak_ordering::less != Qt::weak_ordering::greater);
+
+ static_assert(Qt::weak_ordering::equivalent != Qt::weak_ordering::less);
+ static_assert(Qt::weak_ordering::equivalent == Qt::weak_ordering::equivalent);
+ static_assert(Qt::weak_ordering::equivalent != Qt::weak_ordering::greater);
+
+ static_assert(Qt::weak_ordering::greater != Qt::weak_ordering::less);
+ static_assert(Qt::weak_ordering::greater != Qt::weak_ordering::equivalent);
+ static_assert(Qt::weak_ordering::greater == Qt::weak_ordering::greater);
+
+ static_assert(!is_eq (Qt::weak_ordering::less));
+ static_assert( is_neq (Qt::weak_ordering::less));
+ static_assert( is_lt (Qt::weak_ordering::less));
+ static_assert( is_lteq(Qt::weak_ordering::less));
+ static_assert(!is_gt (Qt::weak_ordering::less));
+ static_assert(!is_gteq(Qt::weak_ordering::less));
+
+ static_assert(!(Qt::weak_ordering::less == 0));
+ static_assert( (Qt::weak_ordering::less != 0));
+ static_assert( (Qt::weak_ordering::less < 0));
+ static_assert( (Qt::weak_ordering::less <= 0));
+ static_assert(!(Qt::weak_ordering::less > 0));
+ static_assert(!(Qt::weak_ordering::less >= 0));
+
+ static_assert(!(0 == Qt::weak_ordering::less));
+ static_assert( (0 != Qt::weak_ordering::less));
+ static_assert(!(0 < Qt::weak_ordering::less));
+ static_assert(!(0 <= Qt::weak_ordering::less));
+ static_assert( (0 > Qt::weak_ordering::less));
+ static_assert( (0 >= Qt::weak_ordering::less));
+
+
+ static_assert( is_eq (Qt::weak_ordering::equivalent));
+ static_assert(!is_neq (Qt::weak_ordering::equivalent));
+ static_assert(!is_lt (Qt::weak_ordering::equivalent));
+ static_assert( is_lteq(Qt::weak_ordering::equivalent));
+ static_assert(!is_gt (Qt::weak_ordering::equivalent));
+ static_assert( is_gteq(Qt::weak_ordering::equivalent));
+
+ static_assert( (Qt::weak_ordering::equivalent == 0));
+ static_assert(!(Qt::weak_ordering::equivalent != 0));
+ static_assert(!(Qt::weak_ordering::equivalent < 0));
+ static_assert( (Qt::weak_ordering::equivalent <= 0));
+ static_assert(!(Qt::weak_ordering::equivalent > 0));
+ static_assert( (Qt::weak_ordering::equivalent >= 0));
+
+ static_assert( (0 == Qt::weak_ordering::equivalent));
+ static_assert(!(0 != Qt::weak_ordering::equivalent));
+ static_assert(!(0 < Qt::weak_ordering::equivalent));
+ static_assert( (0 <= Qt::weak_ordering::equivalent));
+ static_assert(!(0 > Qt::weak_ordering::equivalent));
+ static_assert( (0 >= Qt::weak_ordering::equivalent));
+
+
+ static_assert(!is_eq (Qt::weak_ordering::greater));
+ static_assert( is_neq (Qt::weak_ordering::greater));
+ static_assert(!is_lt (Qt::weak_ordering::greater));
+ static_assert(!is_lteq(Qt::weak_ordering::greater));
+ static_assert( is_gt (Qt::weak_ordering::greater));
+ static_assert( is_gteq(Qt::weak_ordering::greater));
+
+ static_assert(!(Qt::weak_ordering::greater == 0));
+ static_assert( (Qt::weak_ordering::greater != 0));
+ static_assert(!(Qt::weak_ordering::greater < 0));
+ static_assert(!(Qt::weak_ordering::greater <= 0));
+ static_assert( (Qt::weak_ordering::greater > 0));
+ static_assert( (Qt::weak_ordering::greater >= 0));
+
+ static_assert(!(0 == Qt::weak_ordering::greater));
+ static_assert( (0 != Qt::weak_ordering::greater));
+ static_assert( (0 < Qt::weak_ordering::greater));
+ static_assert( (0 <= Qt::weak_ordering::greater));
+ static_assert(!(0 > Qt::weak_ordering::greater));
+ static_assert(!(0 >= Qt::weak_ordering::greater));
+}
+
+void tst_QCompare::strongOrdering()
+{
+ static_assert(Qt::strong_ordering::less == Qt::strong_ordering::less);
+ static_assert(Qt::strong_ordering::less != Qt::strong_ordering::equal);
+ static_assert(Qt::strong_ordering::less != Qt::strong_ordering::equivalent);
+ static_assert(Qt::strong_ordering::less != Qt::strong_ordering::greater);
+
+ static_assert(Qt::strong_ordering::equal != Qt::strong_ordering::less);
+ static_assert(Qt::strong_ordering::equal == Qt::strong_ordering::equal);
+ static_assert(Qt::strong_ordering::equal == Qt::strong_ordering::equivalent);
+ static_assert(Qt::strong_ordering::equal != Qt::strong_ordering::greater);
+
+ static_assert(Qt::strong_ordering::equivalent != Qt::strong_ordering::less);
+ static_assert(Qt::strong_ordering::equivalent == Qt::strong_ordering::equal);
+ static_assert(Qt::strong_ordering::equivalent == Qt::strong_ordering::equivalent);
+ static_assert(Qt::strong_ordering::equivalent != Qt::strong_ordering::greater);
+
+ static_assert(Qt::strong_ordering::greater != Qt::strong_ordering::less);
+ static_assert(Qt::strong_ordering::greater != Qt::strong_ordering::equal);
+ static_assert(Qt::strong_ordering::greater != Qt::strong_ordering::equivalent);
+ static_assert(Qt::strong_ordering::greater == Qt::strong_ordering::greater);
+
+ static_assert(!is_eq (Qt::strong_ordering::less));
+ static_assert( is_neq (Qt::strong_ordering::less));
+ static_assert( is_lt (Qt::strong_ordering::less));
+ static_assert( is_lteq(Qt::strong_ordering::less));
+ static_assert(!is_gt (Qt::strong_ordering::less));
+ static_assert(!is_gteq(Qt::strong_ordering::less));
+
+ static_assert(!(Qt::strong_ordering::less == 0));
+ static_assert( (Qt::strong_ordering::less != 0));
+ static_assert( (Qt::strong_ordering::less < 0));
+ static_assert( (Qt::strong_ordering::less <= 0));
+ static_assert(!(Qt::strong_ordering::less > 0));
+ static_assert(!(Qt::strong_ordering::less >= 0));
+
+ static_assert(!(0 == Qt::strong_ordering::less));
+ static_assert( (0 != Qt::strong_ordering::less));
+ static_assert(!(0 < Qt::strong_ordering::less));
+ static_assert(!(0 <= Qt::strong_ordering::less));
+ static_assert( (0 > Qt::strong_ordering::less));
+ static_assert( (0 >= Qt::strong_ordering::less));
+
+
+ static_assert( is_eq (Qt::strong_ordering::equal));
+ static_assert(!is_neq (Qt::strong_ordering::equal));
+ static_assert(!is_lt (Qt::strong_ordering::equal));
+ static_assert( is_lteq(Qt::strong_ordering::equal));
+ static_assert(!is_gt (Qt::strong_ordering::equal));
+ static_assert( is_gteq(Qt::strong_ordering::equal));
+
+ static_assert( (Qt::strong_ordering::equal == 0));
+ static_assert(!(Qt::strong_ordering::equal != 0));
+ static_assert(!(Qt::strong_ordering::equal < 0));
+ static_assert( (Qt::strong_ordering::equal <= 0));
+ static_assert(!(Qt::strong_ordering::equal > 0));
+ static_assert( (Qt::strong_ordering::equal >= 0));
+
+ static_assert( (0 == Qt::strong_ordering::equal));
+ static_assert(!(0 != Qt::strong_ordering::equal));
+ static_assert(!(0 < Qt::strong_ordering::equal));
+ static_assert( (0 <= Qt::strong_ordering::equal));
+ static_assert(!(0 > Qt::strong_ordering::equal));
+ static_assert( (0 >= Qt::strong_ordering::equal));
+
+
+ static_assert( is_eq (Qt::strong_ordering::equivalent));
+ static_assert(!is_neq (Qt::strong_ordering::equivalent));
+ static_assert(!is_lt (Qt::strong_ordering::equivalent));
+ static_assert( is_lteq(Qt::strong_ordering::equivalent));
+ static_assert(!is_gt (Qt::strong_ordering::equivalent));
+ static_assert( is_gteq(Qt::strong_ordering::equivalent));
+
+ static_assert( (Qt::strong_ordering::equivalent == 0));
+ static_assert(!(Qt::strong_ordering::equivalent != 0));
+ static_assert(!(Qt::strong_ordering::equivalent < 0));
+ static_assert( (Qt::strong_ordering::equivalent <= 0));
+ static_assert(!(Qt::strong_ordering::equivalent > 0));
+ static_assert( (Qt::strong_ordering::equivalent >= 0));
+
+ static_assert( (0 == Qt::strong_ordering::equivalent));
+ static_assert(!(0 != Qt::strong_ordering::equivalent));
+ static_assert(!(0 < Qt::strong_ordering::equivalent));
+ static_assert( (0 <= Qt::strong_ordering::equivalent));
+ static_assert(!(0 > Qt::strong_ordering::equivalent));
+ static_assert( (0 >= Qt::strong_ordering::equivalent));
+
+
+ static_assert(!is_eq (Qt::strong_ordering::greater));
+ static_assert( is_neq (Qt::strong_ordering::greater));
+ static_assert(!is_lt (Qt::strong_ordering::greater));
+ static_assert(!is_lteq(Qt::strong_ordering::greater));
+ static_assert( is_gt (Qt::strong_ordering::greater));
+ static_assert( is_gteq(Qt::strong_ordering::greater));
+
+ static_assert(!(Qt::strong_ordering::greater == 0));
+ static_assert( (Qt::strong_ordering::greater != 0));
+ static_assert(!(Qt::strong_ordering::greater < 0));
+ static_assert(!(Qt::strong_ordering::greater <= 0));
+ static_assert( (Qt::strong_ordering::greater > 0));
+ static_assert( (Qt::strong_ordering::greater >= 0));
+
+ static_assert(!(0 == Qt::strong_ordering::greater));
+ static_assert( (0 != Qt::strong_ordering::greater));
+ static_assert( (0 < Qt::strong_ordering::greater));
+ static_assert( (0 <= Qt::strong_ordering::greater));
+ static_assert(!(0 > Qt::strong_ordering::greater));
+ static_assert(!(0 >= Qt::strong_ordering::greater));
+}
+
+void tst_QCompare::threeWayCompareWithLiteralZero()
+{
+#ifndef __cpp_lib_three_way_comparison
+ QSKIP("This test requires C++20 <=> support enabled in the compiler and the stdlib.");
+#else
+ // the result of <=> is _always_ a std::_ordering type:
+#define CHECK(O) do { \
+ using StdO = typename QtOrderingPrivate::StdOrdering<O>::type; \
+ static_assert(std::is_same_v<decltype(0 <=> std::declval<O&>()), StdO>); \
+ static_assert(std::is_same_v<decltype(std::declval<O&>() <=> 0), StdO>); \
+ } while (false)
+
+ CHECK(Qt::partial_ordering);
+ CHECK(Qt::weak_ordering);
+ CHECK(Qt::strong_ordering);
+ CHECK(QPartialOrdering);
+ // API symmetry check:
+ CHECK(std::partial_ordering);
+ CHECK(std::weak_ordering);
+ CHECK(std::strong_ordering);
+
+#undef CHECK
+
+#define CHECK(O, what, reversed) do { \
+ using StdO = typename QtOrderingPrivate::StdOrdering<O>::type; \
+ static_assert((O :: what <=> 0) == StdO:: what); \
+ static_assert((0 <=> O :: what) == StdO:: reversed); \
+ } while (false)
+
+ CHECK(Qt::partial_ordering, unordered, unordered);
+ CHECK(Qt::partial_ordering, equivalent, equivalent);
+ CHECK(Qt::partial_ordering, less, greater);
+ CHECK(Qt::partial_ordering, greater, less);
+
+ CHECK(Qt::weak_ordering, equivalent, equivalent);
+ CHECK(Qt::weak_ordering, less, greater);
+ CHECK(Qt::weak_ordering, greater, less);
+
+ CHECK(Qt::strong_ordering, equal, equal);
+ CHECK(Qt::strong_ordering, less, greater);
+ CHECK(Qt::strong_ordering, greater, less);
+
+ CHECK(QPartialOrdering, unordered, unordered);
+ CHECK(QPartialOrdering, equivalent, equivalent);
+ CHECK(QPartialOrdering, less, greater);
+ CHECK(QPartialOrdering, greater, less);
+
+ // API symmetry check:
+
+ CHECK(std::partial_ordering, unordered, unordered);
+ CHECK(std::partial_ordering, equivalent, equivalent);
+ CHECK(std::partial_ordering, less, greater);
+ CHECK(std::partial_ordering, greater, less);
+
+ CHECK(std::weak_ordering, equivalent, equivalent);
+ CHECK(std::weak_ordering, less, greater);
+ CHECK(std::weak_ordering, greater, less);
+
+ CHECK(std::strong_ordering, equal, equal);
+ CHECK(std::strong_ordering, less, greater);
+ CHECK(std::strong_ordering, greater, less);
+
+#undef CHECK
+#endif // __cpp_lib_three_way_comparisons
+
+}
+
+void tst_QCompare::conversions()
+{
+ // Qt::weak_ordering -> Qt::partial_ordering
+ {
+ constexpr Qt::partial_ordering less = Qt::weak_ordering::less;
+ static_assert(less == Qt::partial_ordering::less);
+ constexpr Qt::partial_ordering equivalent = Qt::weak_ordering::equivalent;
+ static_assert(equivalent == Qt::partial_ordering::equivalent);
+ constexpr Qt::partial_ordering greater = Qt::weak_ordering::greater;
+ static_assert(greater == Qt::partial_ordering::greater);
+ }
+ // Qt::strong_ordering -> Qt::partial_ordering
+ {
+ constexpr Qt::partial_ordering less = Qt::strong_ordering::less;
+ static_assert(less == Qt::partial_ordering::less);
+ constexpr Qt::partial_ordering equal = Qt::strong_ordering::equal;
+ static_assert(equal == Qt::partial_ordering::equivalent);
+ constexpr Qt::partial_ordering equivalent = Qt::strong_ordering::equivalent;
+ static_assert(equivalent == Qt::partial_ordering::equivalent);
+ constexpr Qt::partial_ordering greater = Qt::strong_ordering::greater;
+ static_assert(greater == Qt::partial_ordering::greater);
+ }
+ // Qt::strong_ordering -> Qt::weak_ordering
+ {
+ constexpr Qt::weak_ordering less = Qt::strong_ordering::less;
+ static_assert(less == Qt::weak_ordering::less);
+ constexpr Qt::weak_ordering equal = Qt::strong_ordering::equal;
+ static_assert(equal == Qt::weak_ordering::equivalent);
+ constexpr Qt::weak_ordering equivalent = Qt::strong_ordering::equivalent;
+ static_assert(equivalent == Qt::weak_ordering::equivalent);
+ constexpr Qt::weak_ordering greater = Qt::strong_ordering::greater;
+ static_assert(greater == Qt::weak_ordering::greater);
+ }
+ // Mixed types
+ {
+ static_assert(Qt::partial_ordering::less == Qt::strong_ordering::less);
+ static_assert(Qt::partial_ordering::equivalent != Qt::strong_ordering::less);
+ static_assert(Qt::partial_ordering::equivalent == Qt::strong_ordering::equal);
+ static_assert(Qt::partial_ordering::greater == Qt::strong_ordering::greater);
+
+ static_assert(Qt::partial_ordering::less == Qt::weak_ordering::less);
+ static_assert(Qt::partial_ordering::equivalent == Qt::weak_ordering::equivalent);
+ static_assert(Qt::partial_ordering::greater == Qt::weak_ordering::greater);
+
+ static_assert(Qt::weak_ordering::less == Qt::strong_ordering::less);
+ static_assert(Qt::weak_ordering::equivalent != Qt::strong_ordering::greater);
+ static_assert(Qt::weak_ordering::equivalent == Qt::strong_ordering::equal);
+ static_assert(Qt::weak_ordering::greater == Qt::strong_ordering::greater);
+
+ static_assert(Qt::weak_ordering::less == Qt::partial_ordering::less);
+ static_assert(Qt::weak_ordering::equivalent == Qt::partial_ordering::equivalent);
+ static_assert(Qt::weak_ordering::greater == Qt::partial_ordering::greater);
+
+ static_assert(Qt::strong_ordering::less == Qt::partial_ordering::less);
+ static_assert(Qt::strong_ordering::equivalent == Qt::partial_ordering::equivalent);
+ static_assert(Qt::strong_ordering::equal == Qt::partial_ordering::equivalent);
+ static_assert(Qt::strong_ordering::greater == Qt::partial_ordering::greater);
+
+ static_assert(Qt::strong_ordering::less == Qt::weak_ordering::less);
+ static_assert(Qt::strong_ordering::equivalent == Qt::weak_ordering::equivalent);
+ static_assert(Qt::strong_ordering::equal == Qt::weak_ordering::equivalent);
+ static_assert(Qt::strong_ordering::greater == Qt::weak_ordering::greater);
+ }
+#ifdef __cpp_lib_three_way_comparison
+ // Qt::partial_ordering <-> std::partial_ordering
+ {
+ static_assert(Qt::partial_ordering::less == std::partial_ordering::less);
+ static_assert(Qt::partial_ordering::less != std::partial_ordering::greater);
+ static_assert(std::partial_ordering::unordered != Qt::partial_ordering::equivalent);
+ static_assert(std::partial_ordering::unordered == Qt::partial_ordering::unordered);
+
+ static_assert((Qt::partial_ordering(std::partial_ordering::less) ==
+ std::partial_ordering::less));
+ static_assert((Qt::partial_ordering(std::partial_ordering::equivalent) ==
+ std::partial_ordering::equivalent));
+ static_assert((Qt::partial_ordering(std::partial_ordering::greater) ==
+ std::partial_ordering::greater));
+ static_assert((Qt::partial_ordering(std::partial_ordering::unordered) ==
+ std::partial_ordering::unordered));
+ }
+ // Qt::weak_ordering <-> std::weak_ordering
+ {
+ static_assert(Qt::weak_ordering::less == std::weak_ordering::less);
+ static_assert(Qt::weak_ordering::less != std::weak_ordering::equivalent);
+ static_assert(std::weak_ordering::greater != Qt::weak_ordering::less);
+ static_assert(std::weak_ordering::equivalent == Qt::weak_ordering::equivalent);
+
+ static_assert((Qt::weak_ordering(std::weak_ordering::less) ==
+ std::weak_ordering::less));
+ static_assert((Qt::weak_ordering(std::weak_ordering::equivalent) ==
+ std::weak_ordering::equivalent));
+ static_assert((Qt::weak_ordering(std::weak_ordering::greater) ==
+ std::weak_ordering::greater));
+ }
+ // Qt::strong_ordering <-> std::strong_ordering
+ {
+ static_assert(Qt::strong_ordering::less == std::strong_ordering::less);
+ static_assert(Qt::strong_ordering::less != std::strong_ordering::equivalent);
+ static_assert(std::strong_ordering::greater != Qt::strong_ordering::less);
+ static_assert(std::strong_ordering::equivalent == Qt::strong_ordering::equivalent);
+
+ static_assert((Qt::strong_ordering(std::strong_ordering::less) ==
+ std::strong_ordering::less));
+ static_assert((Qt::strong_ordering(std::strong_ordering::equivalent) ==
+ std::strong_ordering::equivalent));
+ static_assert((Qt::strong_ordering(std::strong_ordering::greater) ==
+ std::strong_ordering::greater));
+ }
+ // Mixed Qt::*_ordering <> std::*_ordering types
+ {
+ static_assert(Qt::strong_ordering::less == std::partial_ordering::less);
+ static_assert(Qt::strong_ordering::less != std::partial_ordering::greater);
+ static_assert(Qt::strong_ordering::equal == std::weak_ordering::equivalent);
+ static_assert(Qt::strong_ordering::equivalent != std::weak_ordering::less);
+
+ static_assert(Qt::weak_ordering::less != std::partial_ordering::greater);
+ static_assert(Qt::weak_ordering::less == std::partial_ordering::less);
+ static_assert(Qt::weak_ordering::equivalent == std::strong_ordering::equivalent);
+ static_assert(Qt::weak_ordering::equivalent != std::strong_ordering::less);
+
+ static_assert(Qt::partial_ordering::less != std::weak_ordering::greater);
+ static_assert(Qt::partial_ordering::less == std::weak_ordering::less);
+ static_assert(Qt::partial_ordering::equivalent == std::strong_ordering::equivalent);
+ static_assert(Qt::partial_ordering::equivalent != std::strong_ordering::less);
+ }
+#endif
+
+}
+
+void tst_QCompare::is_eq_overloads()
+{
+#ifndef __cpp_lib_three_way_comparison
+ QSKIP("This test requires C++20 three-way-comparison support enabled in the stdlib.");
+#else
+ constexpr auto u = std::partial_ordering::unordered;
+ constexpr auto l = std::weak_ordering::less;
+ constexpr auto g = std::strong_ordering::greater;
+ constexpr auto e = std::weak_ordering::equivalent;
+ constexpr auto s = std::strong_ordering::equal;
+
+ // This is a compile-time check that unqualified name lookup of
+ // std::is_eq-like functions isn't ambiguous, so we can recommend it to our
+ // users for minimizing porting on the way to C++20.
+
+ // The goal is to check each std::ordering and each is_eq function at least
+ // once, not to test all combinations (we're not the stdlib test suite here).
+
+ QVERIFY(is_eq(s));
+ QVERIFY(is_neq(u));
+ QVERIFY(is_lt(l));
+ QVERIFY(is_gt(g));
+ QVERIFY(is_lteq(e));
+ QVERIFY(is_gteq(s));
+#endif // __cpp_lib_three_way_comparison
+}
+
+class StringWrapper
+{
+public:
+ explicit StringWrapper() {}
+ explicit StringWrapper(const QString &val) : m_val(val) {}
+ QString value() const { return m_val; }
+
+private:
+ static Qt::weak_ordering compareHelper(const QString &lhs, const QString &rhs) noexcept
+ {
+ const int res = QString::compare(lhs, rhs, Qt::CaseInsensitive);
+ if (res < 0)
+ return Qt::weak_ordering::less;
+ else if (res > 0)
+ return Qt::weak_ordering::greater;
+ else
+ return Qt::weak_ordering::equivalent;
+ }
+
+ friend bool comparesEqual(const StringWrapper &lhs, const StringWrapper &rhs) noexcept
+ { return QString::compare(lhs.m_val, rhs.m_val, Qt::CaseInsensitive) == 0; }
+ friend Qt::weak_ordering
+ compareThreeWay(const StringWrapper &lhs, const StringWrapper &rhs) noexcept
+ { return compareHelper(lhs.m_val, rhs.m_val); }
+ Q_DECLARE_WEAKLY_ORDERED(StringWrapper)
+
+ // these helper functions are intentionally non-noexcept
+ friend bool comparesEqual(const StringWrapper &lhs, int rhs)
+ { return comparesEqual(lhs, StringWrapper(QString::number(rhs))); }
+ friend Qt::weak_ordering compareThreeWay(const StringWrapper &lhs, int rhs)
+ { return compareHelper(lhs.m_val, QString::number(rhs)); }
+ Q_DECLARE_WEAKLY_ORDERED(StringWrapper, int)
+
+ QString m_val;
+};
+
+void tst_QCompare::compareThreeWay()
+{
+ // test noexcept
+
+ // for custom types
+ static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper>(),
+ std::declval<StringWrapper>())));
+ static_assert(!noexcept(qCompareThreeWay(std::declval<StringWrapper>(),
+ std::declval<int>())));
+ static_assert(!noexcept(qCompareThreeWay(std::declval<int>(),
+ std::declval<StringWrapper>())));
+ // for built-in types
+ static_assert(noexcept(qCompareThreeWay(std::declval<int>(), std::declval<int>())));
+ static_assert(noexcept(qCompareThreeWay(std::declval<float>(), std::declval<int>())));
+ static_assert(noexcept(qCompareThreeWay(std::declval<double>(), std::declval<float>())));
+ static_assert(noexcept(qCompareThreeWay(std::declval<int>(), std::declval<int>())));
+
+ // enums
+ enum TestEnum : int {
+ Smaller,
+ Bigger
+ };
+ static_assert(noexcept(qCompareThreeWay(std::declval<TestEnum>(), std::declval<TestEnum>())));
+
+ // pointers
+ static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper *>(),
+ std::declval<StringWrapper *>())));
+ static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper *>(), nullptr)));
+
+ // Test some actual comparison results
+
+ // for custom types
+ QCOMPARE_EQ(qCompareThreeWay(StringWrapper("ABC"), StringWrapper("abc")),
+ Qt::weak_ordering::equivalent);
+ QVERIFY(StringWrapper("ABC") == StringWrapper("abc"));
+ QCOMPARE_EQ(qCompareThreeWay(StringWrapper("ABC"), StringWrapper("qwe")),
+ Qt::weak_ordering::less);
+ QVERIFY(StringWrapper("ABC") != StringWrapper("qwe"));
+ QCOMPARE_EQ(qCompareThreeWay(StringWrapper("qwe"), StringWrapper("ABC")),
+ Qt::weak_ordering::greater);
+ QVERIFY(StringWrapper("qwe") != StringWrapper("ABC"));
+ QCOMPARE_EQ(qCompareThreeWay(StringWrapper("10"), 10), Qt::weak_ordering::equivalent);
+ QVERIFY(StringWrapper("10") == 10);
+ QCOMPARE_EQ(qCompareThreeWay(StringWrapper("10"), 12), Qt::weak_ordering::less);
+ QVERIFY(StringWrapper("10") != 12);
+ QCOMPARE_EQ(qCompareThreeWay(StringWrapper("12"), 10), Qt::weak_ordering::greater);
+ QVERIFY(StringWrapper("12") != 10);
+
+ // reversed compareThreeWay()
+ auto result = qCompareThreeWay(10, StringWrapper("12"));
+ QCOMPARE_EQ(result, Qt::weak_ordering::less);
+ static_assert(std::is_same_v<decltype(result), Qt::weak_ordering>);
+ QVERIFY(10 != StringWrapper("12"));
+ result = qCompareThreeWay(12, StringWrapper("10"));
+ QCOMPARE_EQ(result, Qt::weak_ordering::greater);
+ static_assert(std::is_same_v<decltype(result), Qt::weak_ordering>);
+ QVERIFY(12 != StringWrapper("10"));
+ result = qCompareThreeWay(10, StringWrapper("10"));
+ QCOMPARE_EQ(result, Qt::weak_ordering::equivalent);
+ static_assert(std::is_same_v<decltype(result), Qt::weak_ordering>);
+ QVERIFY(10 == StringWrapper("10"));
+
+ // built-in types
+ QCOMPARE_EQ(qCompareThreeWay(1, 1.0), Qt::partial_ordering::equivalent);
+ QCOMPARE_EQ(qCompareThreeWay(1, 2), Qt::strong_ordering::less);
+ QCOMPARE_EQ(qCompareThreeWay(2.0f, 1.0), Qt::partial_ordering::greater);
+
+ // enums
+ QCOMPARE_EQ(qCompareThreeWay(Smaller, Bigger), Qt::strong_ordering::less);
+
+ // pointers
+ std::array<int, 2> arr{1, 0};
+ QCOMPARE_EQ(qCompareThreeWay(&arr[1], &arr[0]), Qt::strong_ordering::greater);
+ QCOMPARE_EQ(qCompareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent);
+}
+
+QTEST_MAIN(tst_QCompare)
+#include "tst_qcompare.moc"
diff --git a/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt b/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt
new file mode 100644
index 0000000000..31d8bff0a5
--- /dev/null
+++ b/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcomparehelpers LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcomparehelpers
+ SOURCES
+ tst_qcomparehelpers.h tst_qcomparehelpers.cpp tst_qcomparehelpers1.cpp
+ wrappertypes.h
+ LIBRARIES
+ Qt::TestPrivate
+)
+
+# CMake recognizes CXX_STANDARD=23 only starting from version 3.20
+# macOS has some issues with concepts, see QTBUG-117765
+if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20" AND NOT MACOS AND NOT VXWORKS AND NOT (LINUX AND "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64"))
+ qt_internal_add_test(tst_qcomparehelpers_cpp23
+ SOURCES
+ tst_qcomparehelpers.h tst_qcomparehelpers.cpp tst_qcomparehelpers1.cpp
+ wrappertypes.h
+ DEFINES
+ tst_QCompareHelpers=tst_QCompareHelpersCpp23
+ LIBRARIES
+ Qt::TestPrivate
+ )
+
+ # Try to build this test in C++23 mode to test std::float16_t support.
+ # Use CXX_STANDARD_REQUIRED OFF, so that we just fall back to C++17 if the
+ # compiler does not support C++23.
+ set_target_properties(tst_qcomparehelpers_cpp23
+ PROPERTIES
+ CXX_STANDARD 23
+ CXX_STANDARD_REQUIRED OFF
+ )
+endif()
diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp
new file mode 100644
index 0000000000..f140c23ed0
--- /dev/null
+++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp
@@ -0,0 +1,600 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "tst_qcomparehelpers.h"
+#include "wrappertypes.h"
+
+#if defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
+#include <stdfloat>
+#endif
+
+/*
+ NOTE: Do not add any other test cases to this cpp file!
+ minGW already complains about a too large tst_qcomparehelpers.cpp.obj
+ object file.
+
+ Create a new cpp file and add new tests there.
+*/
+
+template<typename LeftType, typename RightType, typename OrderingType>
+void tst_QCompareHelpers::compareImpl()
+{
+ QFETCH(LeftType, lhs);
+ QFETCH(RightType, rhs);
+ QFETCH(OrderingType, expectedOrdering);
+
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, expectedOrdering);
+#ifdef __cpp_lib_three_way_comparison
+ // Also check std types.
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, QtOrderingPrivate::to_std(expectedOrdering));
+#endif // __cpp_lib_three_way_comparison
+}
+
+template<typename LeftType, typename RightType>
+void tst_QCompareHelpers::compareIntData()
+{
+ QTest::addColumn<LeftType>("lhs");
+ QTest::addColumn<RightType>("rhs");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrdering");
+
+ auto createRow = [](auto lhs, auto rhs, Qt::strong_ordering ordering) {
+ QTest::addRow("%d vs %d", lhs, rhs) << LeftType(lhs) << RightType(rhs) << ordering;
+ };
+
+ createRow(0, 0, Qt::strong_ordering::equivalent);
+ createRow(-1, 0, Qt::strong_ordering::less);
+ createRow(1, 0, Qt::strong_ordering::greater);
+ constexpr int max = std::numeric_limits<int>::max();
+ constexpr int min = std::numeric_limits<int>::min();
+ createRow(max, max, Qt::strong_ordering::equivalent);
+ createRow(min, min, Qt::strong_ordering::equivalent);
+ createRow(max, min, Qt::strong_ordering::greater);
+ createRow(min, max, Qt::strong_ordering::less);
+}
+
+template<typename LeftType, typename RightType>
+void tst_QCompareHelpers::compareFloatData()
+{
+ QTest::addColumn<LeftType>("lhs");
+ QTest::addColumn<RightType>("rhs");
+ QTest::addColumn<Qt::partial_ordering>("expectedOrdering");
+
+ auto createRow = [](auto lhs, auto rhs, Qt::partial_ordering ordering) {
+ QTest::addRow("%f vs %f", lhs, rhs) << LeftType(lhs) << RightType(rhs) << ordering;
+ };
+
+ createRow(0.0, 0.0, Qt::partial_ordering::equivalent);
+ createRow(-0.000001, 0.0, Qt::partial_ordering::less);
+ createRow(0.000001, 0.0, Qt::partial_ordering::greater);
+
+ const double nan = qQNaN();
+ createRow(nan, 0.0, Qt::partial_ordering::unordered);
+ createRow(0.0, nan, Qt::partial_ordering::unordered);
+ createRow(nan, nan, Qt::partial_ordering::unordered);
+
+ const double inf = qInf();
+ createRow(inf, 0.0, Qt::partial_ordering::greater);
+ createRow(0.0, inf, Qt::partial_ordering::less);
+ createRow(-inf, 0.0, Qt::partial_ordering::less);
+ createRow(0.0, -inf, Qt::partial_ordering::greater);
+ createRow(inf, inf, Qt::partial_ordering::equivalent);
+ createRow(-inf, -inf, Qt::partial_ordering::equivalent);
+ createRow(-inf, inf, Qt::partial_ordering::less);
+ createRow(inf, -inf, Qt::partial_ordering::greater);
+
+ createRow(nan, inf, Qt::partial_ordering::unordered);
+ createRow(inf, nan, Qt::partial_ordering::unordered);
+ createRow(nan, -inf, Qt::partial_ordering::unordered);
+ createRow(-inf, nan, Qt::partial_ordering::unordered);
+}
+
+template<typename LeftType, typename RightType>
+void tst_QCompareHelpers::compareStringData()
+{
+ QTest::addColumn<LeftType>("lhs");
+ QTest::addColumn<RightType>("rhs");
+ QTest::addColumn<Qt::weak_ordering>("expectedOrdering");
+
+ auto createRow = [](auto lhs, auto rhs, Qt::weak_ordering ordering) {
+ QTest::addRow("'%s' vs '%s'", lhs, rhs) << LeftType(lhs) << RightType(rhs) << ordering;
+ };
+
+ createRow("", "", Qt::weak_ordering::equivalent);
+ createRow("Ab", "abc", Qt::weak_ordering::less);
+ createRow("aBc", "AB", Qt::weak_ordering::greater);
+ createRow("ab", "AB", Qt::weak_ordering::equivalent);
+ createRow("ABC", "abc", Qt::weak_ordering::equivalent);
+}
+
+void tst_QCompareHelpers::comparisonCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<IntWrapper>();
+ if (QTest::currentTestFailed())
+ return;
+
+ QTestPrivate::testAllComparisonOperatorsCompile<IntWrapper, int>();
+ if (QTest::currentTestFailed())
+ return;
+
+ QTestPrivate::testAllComparisonOperatorsCompile<DoubleWrapper>();
+ if (QTest::currentTestFailed())
+ return;
+
+ QTestPrivate::testAllComparisonOperatorsCompile<DoubleWrapper, double>();
+ if (QTest::currentTestFailed())
+ return;
+
+ QTestPrivate::testAllComparisonOperatorsCompile<DoubleWrapper, IntWrapper>();
+ if (QTest::currentTestFailed())
+ return;
+
+ QTestPrivate::testAllComparisonOperatorsCompile<StringWrapper<QString>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ QTestPrivate::testAllComparisonOperatorsCompile<StringWrapper<QString>, QAnyStringView>();
+ if (QTest::currentTestFailed())
+ return;
+}
+
+void tst_QCompareHelpers::compare_IntWrapper_data()
+{
+ compareIntData<IntWrapper, IntWrapper>();
+}
+
+void tst_QCompareHelpers::compare_IntWrapper()
+{
+ compareImpl<IntWrapper, IntWrapper, Qt::strong_ordering>();
+}
+
+void tst_QCompareHelpers::compare_IntWrapper_int_data()
+{
+ compareIntData<IntWrapper, int>();
+}
+
+void tst_QCompareHelpers::compare_IntWrapper_int()
+{
+ compareImpl<IntWrapper, int, Qt::strong_ordering>();
+}
+
+void tst_QCompareHelpers::compare_DoubleWrapper_data()
+{
+ compareFloatData<DoubleWrapper, DoubleWrapper>();
+}
+
+void tst_QCompareHelpers::compare_DoubleWrapper()
+{
+ compareImpl<DoubleWrapper, DoubleWrapper, Qt::partial_ordering>();
+}
+
+void tst_QCompareHelpers::compare_DoubleWrapper_double_data()
+{
+ compareFloatData<DoubleWrapper, double>();
+}
+
+void tst_QCompareHelpers::compare_DoubleWrapper_double()
+{
+ compareImpl<DoubleWrapper, double, Qt::partial_ordering>();
+}
+
+void tst_QCompareHelpers::compare_IntWrapper_DoubleWrapper_data()
+{
+ QTest::addColumn<IntWrapper>("lhs");
+ QTest::addColumn<DoubleWrapper>("rhs");
+ QTest::addColumn<Qt::partial_ordering>("expectedOrdering");
+
+ auto createRow = [](auto lhs, auto rhs, Qt::partial_ordering ordering) {
+ QTest::addRow("%d vs %f", lhs, rhs) << IntWrapper(lhs) << DoubleWrapper(rhs) << ordering;
+ };
+
+ createRow(0, 0.0, Qt::partial_ordering::equivalent);
+ createRow(-1, 0.0, Qt::partial_ordering::less);
+ createRow(1, 0.0, Qt::partial_ordering::greater);
+ createRow(0, -0.000001, Qt::partial_ordering::greater);
+ createRow(0, 0.000001, Qt::partial_ordering::less);
+
+ constexpr int max = std::numeric_limits<int>::max();
+ constexpr int min = std::numeric_limits<int>::min();
+ const double nan = qQNaN();
+ createRow(0, nan, Qt::partial_ordering::unordered);
+ createRow(max, nan, Qt::partial_ordering::unordered);
+ createRow(min, nan, Qt::partial_ordering::unordered);
+
+ const double inf = qInf();
+ createRow(0, inf, Qt::partial_ordering::less);
+ createRow(0, -inf, Qt::partial_ordering::greater);
+ createRow(max, inf, Qt::partial_ordering::less);
+ createRow(max, -inf, Qt::partial_ordering::greater);
+ createRow(min, inf, Qt::partial_ordering::less);
+ createRow(min, -inf, Qt::partial_ordering::greater);
+}
+
+void tst_QCompareHelpers::compare_IntWrapper_DoubleWrapper()
+{
+ compareImpl<IntWrapper, DoubleWrapper, Qt::partial_ordering>();
+}
+
+void tst_QCompareHelpers::compare_StringWrapper_data()
+{
+ compareStringData<StringWrapper<QString>, StringWrapper<QString>>();
+}
+
+void tst_QCompareHelpers::compare_StringWrapper()
+{
+ compareImpl<StringWrapper<QString>, StringWrapper<QString>, Qt::weak_ordering>();
+}
+
+void tst_QCompareHelpers::compare_StringWrapper_AnyStringView_data()
+{
+ compareStringData<StringWrapper<QString>, QAnyStringView>();
+}
+
+void tst_QCompareHelpers::compare_StringWrapper_AnyStringView()
+{
+ compareImpl<StringWrapper<QString>, QAnyStringView, Qt::weak_ordering>();
+}
+
+#define DECLARE_TYPE(Name, Type, Attrs, RetType, Constexpr, Suffix) \
+class Dummy ## Name \
+{ \
+public: \
+ Constexpr Dummy ## Name () {} \
+\
+private: \
+ friend Attrs Constexpr bool \
+ comparesEqual(const Dummy ## Name &lhs, const Dummy ## Name &rhs) noexcept; \
+ friend Attrs Constexpr RetType \
+ compareThreeWay(const Dummy ## Name &lhs, const Dummy ## Name &rhs) noexcept; \
+ friend Attrs Constexpr bool \
+ comparesEqual(const Dummy ## Name &lhs, int rhs) noexcept; \
+ friend Attrs Constexpr RetType \
+ compareThreeWay(const Dummy ## Name &lhs, int rhs) noexcept; \
+ Q_DECLARE_ ## Type ##_ORDERED ## Suffix (Dummy ## Name) \
+ Q_DECLARE_ ## Type ##_ORDERED ## Suffix (Dummy ## Name, int) \
+}; \
+\
+Attrs Constexpr bool comparesEqual(const Dummy ## Name &lhs, const Dummy ## Name &rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
+Attrs Constexpr RetType \
+compareThreeWay(const Dummy ## Name &lhs, const Dummy ## Name &rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; } \
+Attrs Constexpr bool comparesEqual(const Dummy ## Name &lhs, int rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
+Attrs Constexpr RetType compareThreeWay(const Dummy ## Name &lhs, int rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; }
+
+DECLARE_TYPE(PartialConstAttr, PARTIALLY, Q_DECL_PURE_FUNCTION, Qt::partial_ordering, constexpr,
+ _LITERAL_TYPE)
+DECLARE_TYPE(PartialConst, PARTIALLY, /* no attrs */, Qt::partial_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(PartialAttr, PARTIALLY, Q_DECL_CONST_FUNCTION, Qt::partial_ordering, , )
+DECLARE_TYPE(Partial, PARTIALLY, /* no attrs */, Qt::partial_ordering, , )
+
+DECLARE_TYPE(WeakConstAttr, WEAKLY, Q_DECL_PURE_FUNCTION, Qt::weak_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(WeakConst, WEAKLY, /* no attrs */, Qt::weak_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(WeakAttr, WEAKLY, Q_DECL_CONST_FUNCTION, Qt::weak_ordering, , )
+DECLARE_TYPE(Weak, WEAKLY, /* no attrs */, Qt::weak_ordering, , )
+
+DECLARE_TYPE(StrongConstAttr, STRONGLY, Q_DECL_PURE_FUNCTION, Qt::strong_ordering, constexpr,
+ _LITERAL_TYPE)
+DECLARE_TYPE(StrongConst, STRONGLY, /* no attrs */, Qt::strong_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(StrongAttr, STRONGLY, Q_DECL_CONST_FUNCTION, Qt::strong_ordering, , )
+DECLARE_TYPE(Strong, STRONGLY, /* no attrs */, Qt::strong_ordering, , )
+
+#define DECLARE_EQUALITY_COMPARABLE(Name, Attrs, Constexpr, Suffix) \
+class Dummy ## Name \
+{ \
+public: \
+ Constexpr Dummy ## Name (int) {} \
+\
+private: \
+ friend Attrs Constexpr bool \
+ comparesEqual(const Dummy ## Name &lhs, const Dummy ## Name &rhs) noexcept; \
+ friend Attrs Constexpr bool comparesEqual(const Dummy ## Name &lhs, int rhs) noexcept; \
+ Q_DECLARE_EQUALITY_COMPARABLE ## Suffix (Dummy ## Name) \
+ Q_DECLARE_EQUALITY_COMPARABLE ## Suffix (Dummy ## Name, int) \
+}; \
+\
+Attrs Constexpr bool comparesEqual(const Dummy ## Name &lhs, const Dummy ## Name &rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
+Attrs Constexpr bool comparesEqual(const Dummy ## Name &lhs, int rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
+
+DECLARE_EQUALITY_COMPARABLE(ConstAttr, Q_DECL_PURE_FUNCTION, constexpr, _LITERAL_TYPE)
+DECLARE_EQUALITY_COMPARABLE(Const, /* no attrs */, constexpr, _LITERAL_TYPE)
+DECLARE_EQUALITY_COMPARABLE(Attr, Q_DECL_CONST_FUNCTION, , )
+DECLARE_EQUALITY_COMPARABLE(None, /* no attrs */, , )
+
+void tst_QCompareHelpers::generatedClasses()
+{
+#define COMPARE(ClassName) \
+ do { \
+ QTestPrivate::testAllComparisonOperatorsCompile<ClassName>(); \
+ QTestPrivate::testAllComparisonOperatorsCompile<ClassName, int>(); \
+ } while (0)
+
+ COMPARE(DummyPartialConstAttr);
+ COMPARE(DummyPartialConst);
+ COMPARE(DummyPartialAttr);
+ COMPARE(DummyPartial);
+
+ COMPARE(DummyWeakConstAttr);
+ COMPARE(DummyWeakConst);
+ COMPARE(DummyWeakAttr);
+ COMPARE(DummyWeak);
+
+ COMPARE(DummyStrongConstAttr);
+ COMPARE(DummyStrongConst);
+ COMPARE(DummyStrongAttr);
+ COMPARE(DummyStrong);
+#undef COMPARE
+
+ QTestPrivate::testEqualityOperatorsCompile<DummyConstAttr>();
+ QTestPrivate::testEqualityOperatorsCompile<DummyConstAttr, int>();
+
+ QTestPrivate::testEqualityOperatorsCompile<DummyConst>();
+ QTestPrivate::testEqualityOperatorsCompile<DummyConst, int>();
+
+ QTestPrivate::testEqualityOperatorsCompile<DummyAttr>();
+ QTestPrivate::testEqualityOperatorsCompile<DummyAttr, int>();
+
+ QTestPrivate::testEqualityOperatorsCompile<DummyNone>();
+ QTestPrivate::testEqualityOperatorsCompile<DummyNone, int>();
+}
+
+template <typename LeftType, typename RightType,
+ Qt::if_integral<LeftType> = true,
+ Qt::if_integral<RightType> = true>
+void testOrderForTypes()
+{
+ LeftType l0{0};
+ LeftType l1{1};
+ RightType r0{0};
+ RightType r1{1};
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), Qt::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), Qt::strong_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, r1), Qt::strong_ordering::equivalent);
+ // also swap types
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), Qt::strong_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), Qt::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, l1), Qt::strong_ordering::equivalent);
+
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), std::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), std::strong_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, r1), std::strong_ordering::equivalent);
+
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), std::strong_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), std::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, l1), std::strong_ordering::equivalent);
+#endif // __cpp_lib_three_way_comparison
+
+ if constexpr (std::is_signed_v<LeftType>) {
+ LeftType lm1{-1};
+ QCOMPARE_EQ(Qt::compareThreeWay(lm1, r1), Qt::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, lm1), Qt::strong_ordering::greater);
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(Qt::compareThreeWay(lm1, r1), std::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, lm1), std::strong_ordering::greater);
+#endif // __cpp_lib_three_way_comparison
+ }
+ if constexpr (std::is_signed_v<RightType>) {
+ RightType rm1{-1};
+ QCOMPARE_EQ(Qt::compareThreeWay(rm1, l1), Qt::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, rm1), Qt::strong_ordering::greater);
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(Qt::compareThreeWay(rm1, l1), std::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, rm1), std::strong_ordering::greater);
+#endif // __cpp_lib_three_way_comparison
+ }
+}
+
+template <typename LeftType, typename RightType,
+ Qt::if_floating_point<LeftType> = true,
+ Qt::if_floating_point<RightType> = true>
+void testOrderForTypes()
+{
+ constexpr auto lNeg = LeftType(-1);
+ constexpr auto lPos = LeftType( 1);
+
+ constexpr auto rNeg = RightType(-1);
+ constexpr auto rPos = RightType( 1);
+
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rPos), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(lPos, rNeg), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lPos), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(rPos, lNeg), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNeg), Qt::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNeg), Qt::partial_ordering::equivalent);
+
+ LeftType lNaN{std::numeric_limits<LeftType>::quiet_NaN()};
+ LeftType lInf{std::numeric_limits<LeftType>::infinity()};
+
+ RightType rNaN{std::numeric_limits<RightType>::quiet_NaN()};
+ RightType rInf{std::numeric_limits<RightType>::infinity()};
+
+ QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rPos), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNaN), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNaN), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lPos), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lNaN), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rNaN), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rInf), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, -lInf), Qt::partial_ordering::unordered);
+
+ QCOMPARE_EQ(Qt::compareThreeWay(lInf, rPos), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(rPos, lInf), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(rInf, lNeg), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rInf), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(lInf, -rInf), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(-lInf, rInf), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(-rInf, lInf), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(rInf, -lInf), Qt::partial_ordering::greater);
+
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rPos), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(lPos, rNeg), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lPos), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(rPos, lNeg), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNeg), std::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNeg), std::partial_ordering::equivalent);
+
+ QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rPos), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNeg, lNaN), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rNaN), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lPos), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, lNaN), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rNaN), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNaN, rInf), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, -lInf), std::partial_ordering::unordered);
+
+ QCOMPARE_EQ(Qt::compareThreeWay(lInf, rPos), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(rPos, lInf), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(rInf, lNeg), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(lNeg, rInf), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(lInf, -rInf), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(-lInf, rInf), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(-rInf, lInf), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(rInf, -lInf), std::partial_ordering::greater);
+#endif // __cpp_lib_three_way_comparison
+}
+
+template <typename IntType, typename FloatType,
+ Qt::if_integral<IntType> = true,
+ Qt::if_floating_point<FloatType> = true>
+void testOrderForTypes()
+{
+ IntType l0{0};
+ IntType l1{1};
+
+ constexpr FloatType r0{0};
+ constexpr FloatType r1{1};
+ FloatType rNaN{std::numeric_limits<FloatType>::quiet_NaN()};
+
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), Qt::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, r0), Qt::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(r0, l0), Qt::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, rNaN), Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, l1), Qt::partial_ordering::unordered);
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, r1), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l1, r0), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(r1, l0), std::partial_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(r0, l1), std::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, r0), std::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(r0, l0), std::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(l0, rNaN), std::partial_ordering::unordered);
+ QCOMPARE_EQ(Qt::compareThreeWay(rNaN, l1), std::partial_ordering::unordered);
+#endif // __cpp_lib_three_way_comparison
+}
+
+enum class TestEnum : quint8 {
+ Smaller,
+ Bigger
+};
+
+void tst_QCompareHelpers::builtinOrder()
+{
+#define TEST_BUILTIN(Left, Right) \
+ testOrderForTypes<Left, Right>(); \
+ if (QTest::currentTestFailed()) { \
+ qDebug("Failed Qt::compareThreeWay() test for builtin types " #Left " and " #Right); \
+ return; \
+ }
+
+ // some combinations
+ TEST_BUILTIN(char, char)
+#if CHAR_MIN < 0
+ TEST_BUILTIN(char, short)
+ TEST_BUILTIN(qint8, char)
+#else
+ TEST_BUILTIN(char, ushort)
+ TEST_BUILTIN(quint8, char)
+#endif
+ TEST_BUILTIN(qint8, qint8)
+ TEST_BUILTIN(qint8, int)
+ TEST_BUILTIN(ulong, quint8)
+ TEST_BUILTIN(ushort, uchar)
+ TEST_BUILTIN(int, int)
+ TEST_BUILTIN(uint, ulong)
+ TEST_BUILTIN(long, int)
+ TEST_BUILTIN(uint, quint64)
+ TEST_BUILTIN(qint64, short)
+ TEST_BUILTIN(wchar_t, wchar_t)
+ TEST_BUILTIN(uint, char16_t)
+ TEST_BUILTIN(char32_t, char32_t)
+ TEST_BUILTIN(char32_t, ushort)
+#ifdef __cpp_char8_t
+ TEST_BUILTIN(char8_t, char8_t)
+ TEST_BUILTIN(char8_t, ushort)
+ TEST_BUILTIN(char8_t, uint)
+ TEST_BUILTIN(char8_t, quint64)
+#endif // __cpp_char8_t
+#ifdef QT_SUPPORTS_INT128
+ TEST_BUILTIN(qint128, qint128)
+ TEST_BUILTIN(quint128, quint128)
+ TEST_BUILTIN(qint128, int)
+ TEST_BUILTIN(ushort, quint128)
+#endif
+ TEST_BUILTIN(float, double)
+ TEST_BUILTIN(double, float)
+ TEST_BUILTIN(quint64, float)
+ TEST_BUILTIN(qint64, double)
+#ifdef __STDCPP_FLOAT16_T__
+ TEST_BUILTIN(std::float16_t, std::float16_t)
+ TEST_BUILTIN(std::float16_t, double)
+ TEST_BUILTIN(qint64, std::float16_t)
+ TEST_BUILTIN(uint, std::float16_t)
+#endif
+ TEST_BUILTIN(long double, long double)
+ TEST_BUILTIN(float, long double)
+ TEST_BUILTIN(double, long double)
+ TEST_BUILTIN(quint64, long double)
+ TEST_BUILTIN(ushort, long double)
+
+#if QFLOAT16_IS_NATIVE
+ {
+ // Cannot use TEST_BUILTIN here, because std::numeric_limits are not defined
+ // for QtPrivate::NativeFloat16Type.
+ constexpr auto smaller = QtPrivate::NativeFloat16Type(1);
+ constexpr auto bigger = QtPrivate::NativeFloat16Type(2);
+ // native vs native
+ QCOMPARE_EQ(Qt::compareThreeWay(smaller, smaller), Qt::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(smaller, bigger), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(bigger, smaller), Qt::partial_ordering::greater);
+ // native vs float
+ QCOMPARE_EQ(Qt::compareThreeWay(smaller, 1.0f), Qt::partial_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(1.0f, bigger), Qt::partial_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(bigger, 1.0f), Qt::partial_ordering::greater);
+ const auto floatNaN = std::numeric_limits<float>::quiet_NaN();
+ QCOMPARE_EQ(Qt::compareThreeWay(bigger, floatNaN), Qt::partial_ordering::unordered);
+ }
+#endif
+
+ QCOMPARE_EQ(Qt::compareThreeWay(TestEnum::Smaller, TestEnum::Bigger),
+ Qt::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(TestEnum::Bigger, TestEnum::Smaller),
+ Qt::strong_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(TestEnum::Smaller, TestEnum::Smaller),
+ Qt::strong_ordering::equivalent);
+
+ std::array<int, 2> arr{1, 0};
+ QCOMPARE_EQ(Qt::compareThreeWay(&arr[0], &arr[1]), Qt::strong_ordering::less);
+ QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent);
+
+ class Base {};
+ class Derived : public Base {};
+
+ auto b = std::make_unique<Base>();
+ auto d = std::make_unique<Derived>();
+ QCOMPARE_NE(Qt::compareThreeWay(b.get(), d.get()), Qt::strong_ordering::equivalent);
+ QCOMPARE_EQ(Qt::compareThreeWay(b.get(), nullptr), Qt::strong_ordering::greater);
+ QCOMPARE_EQ(Qt::compareThreeWay(nullptr, d.get()), Qt::strong_ordering::less);
+
+#undef TEST_BUILTIN
+}
+
+QTEST_MAIN(tst_QCompareHelpers)
+#include "tst_qcomparehelpers.moc"
diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h
new file mode 100644
index 0000000000..16398b0978
--- /dev/null
+++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h
@@ -0,0 +1,63 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef TST_QCOMPAREHELPERS_H
+#define TST_QCOMPAREHELPERS_H
+
+#include <QtCore/qcompare.h>
+
+#include <QtTest/qtest.h>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+
+class tst_QCompareHelpers : public QObject
+{
+ Q_OBJECT
+
+private:
+ template <typename LeftType, typename RightType, typename OrderingType>
+ void compareImpl();
+
+ template <typename LeftType, typename RightType>
+ void compareIntData();
+
+ template <typename LeftType, typename RightType>
+ void compareFloatData();
+
+ template <typename LeftType, typename RightType>
+ void compareStringData();
+
+private Q_SLOTS:
+ // tst_qcomparehelpers.cpp
+ void comparisonCompiles();
+
+ void compare_IntWrapper_data();
+ void compare_IntWrapper();
+
+ void compare_IntWrapper_int_data();
+ void compare_IntWrapper_int();
+
+ void compare_DoubleWrapper_data();
+ void compare_DoubleWrapper();
+
+ void compare_DoubleWrapper_double_data();
+ void compare_DoubleWrapper_double();
+
+ void compare_IntWrapper_DoubleWrapper_data();
+ void compare_IntWrapper_DoubleWrapper();
+
+ void compare_StringWrapper_data();
+ void compare_StringWrapper();
+
+ void compare_StringWrapper_AnyStringView_data();
+ void compare_StringWrapper_AnyStringView();
+
+ void generatedClasses();
+
+ void builtinOrder();
+
+ // Add new test cases to tst_qcomparehelpers1.cpp, because minGW already
+ // complains about a too large tst_qcomparehelpers.cpp.obj object file
+ void compareWithAttributes();
+};
+
+#endif // TST_QCOMPAREHELPERS_H
diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp
new file mode 100644
index 0000000000..a3b8200a63
--- /dev/null
+++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "tst_qcomparehelpers.h"
+
+#define DECLARE_TYPE(Name, Type, RetType, Constexpr, Suffix) \
+class Deprecated ## Name \
+{ \
+public: \
+ Constexpr Deprecated ## Name () {} \
+\
+private: \
+ friend Constexpr bool \
+ comparesEqual(const Deprecated ## Name &lhs, int rhs) noexcept; \
+ friend Constexpr RetType \
+ compareThreeWay(const Deprecated ## Name &lhs, int rhs) noexcept; \
+ Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Deprecated ## Name, int, \
+ Q_DECL_DEPRECATED_X("This op is deprecated")) \
+}; \
+\
+Constexpr bool comparesEqual(const Deprecated ## Name &lhs, int rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
+Constexpr RetType compareThreeWay(const Deprecated ## Name &lhs, int rhs) noexcept \
+{ Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; }
+
+DECLARE_TYPE(PartialConst, PARTIALLY, Qt::partial_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(Partial, PARTIALLY, Qt::partial_ordering, , )
+DECLARE_TYPE(WeakConst, WEAKLY, Qt::weak_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(Weak, WEAKLY, Qt::weak_ordering, , )
+DECLARE_TYPE(StrongConst, STRONGLY, Qt::strong_ordering, constexpr, _LITERAL_TYPE)
+DECLARE_TYPE(Strong, STRONGLY, Qt::strong_ordering, , )
+
+#undef DECLARE_TYPE
+
+void tst_QCompareHelpers::compareWithAttributes()
+{
+ // All these comparisons would trigger deprecation warnings.
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
+#define COMPARE(ClassName) \
+ do { \
+ ClassName c; \
+ QCOMPARE_EQ(c, 0); \
+ QCOMPARE_LE(c, 0); \
+ QCOMPARE_GE(0, c); \
+ } while (false)
+
+ COMPARE(DeprecatedPartialConst);
+ COMPARE(DeprecatedPartial);
+ COMPARE(DeprecatedWeakConst);
+ COMPARE(DeprecatedWeak);
+ COMPARE(DeprecatedStrongConst);
+ COMPARE(DeprecatedStrong);
+
+#undef COMPARE
+
+QT_WARNING_POP
+}
diff --git a/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h b/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h
new file mode 100644
index 0000000000..1dd221a8b0
--- /dev/null
+++ b/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h
@@ -0,0 +1,116 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef TST_QCOMPAREHELPERS_WRAPPERTYPES_H
+#define TST_QCOMPAREHELPERS_WRAPPERTYPES_H
+
+#include <QtCore/qanystringview.h>
+#include <QtCore/qcompare.h>
+
+class IntWrapper
+{
+public:
+ // implicit constructor and operator int() to simulate the case that
+ // triggers a bug on MSVC < 19.36.
+ IntWrapper(int val) : m_val(val) {}
+ operator int() const noexcept { return m_val; }
+
+ int value() const { return m_val; }
+
+private:
+ friend bool comparesEqual(const IntWrapper &lhs, const IntWrapper &rhs) noexcept
+ { return lhs.m_val == rhs.m_val; }
+ friend Qt::strong_ordering
+ compareThreeWay(const IntWrapper &lhs, const IntWrapper &rhs) noexcept
+ {
+ return Qt::compareThreeWay(lhs.m_val, rhs.m_val);
+ }
+ friend bool comparesEqual(const IntWrapper &lhs, int rhs) noexcept
+ { return lhs.m_val == rhs; }
+ friend Qt::strong_ordering compareThreeWay(const IntWrapper &lhs, int rhs) noexcept
+ { return compareThreeWay(lhs, IntWrapper(rhs)); }
+
+ Q_DECLARE_STRONGLY_ORDERED(IntWrapper)
+ Q_DECLARE_STRONGLY_ORDERED(IntWrapper, int)
+
+ int m_val = 0;
+};
+
+class DoubleWrapper
+{
+public:
+ explicit DoubleWrapper(double val) : m_val(val) {}
+ double value() const { return m_val; }
+
+private:
+ friend bool comparesEqual(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept
+ { return lhs.m_val == rhs.m_val; }
+ friend Qt::partial_ordering
+ compareThreeWay(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept
+ {
+ return Qt::compareThreeWay(lhs.m_val, rhs.m_val);
+ }
+ friend bool comparesEqual(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept
+ { return comparesEqual(lhs, DoubleWrapper(rhs.value())); }
+ friend Qt::partial_ordering
+ compareThreeWay(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept
+ { return compareThreeWay(lhs, DoubleWrapper(rhs.value())); }
+ friend bool comparesEqual(const DoubleWrapper &lhs, double rhs) noexcept
+ { return lhs.m_val == rhs; }
+ friend Qt::partial_ordering compareThreeWay(const DoubleWrapper &lhs, double rhs) noexcept
+ {
+ return Qt::compareThreeWay(lhs.m_val, rhs);
+ }
+
+ Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper)
+ Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper, IntWrapper)
+ Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper, double)
+
+ double m_val = 0.0;
+};
+
+template <typename String>
+class StringWrapper
+{
+public:
+ explicit StringWrapper(String val) : m_val(val) {}
+ String value() const { return m_val; }
+
+private:
+ static bool equalsHelper(QAnyStringView lhs, QAnyStringView rhs) noexcept
+ { return QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive) == 0; }
+
+ static Qt::weak_ordering compareHelper(QAnyStringView lhs, QAnyStringView rhs) noexcept
+ {
+ const int res = QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive);
+ if (res < 0)
+ return Qt::weak_ordering::less;
+ else if (res > 0)
+ return Qt::weak_ordering::greater;
+ else
+ return Qt::weak_ordering::equivalent;
+ }
+
+ // Some of the helper functions are intentionally NOT marked as noexcept
+ // to test the conditional noexcept in the macros.
+ template <typename T>
+ friend bool comparesEqual(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
+ { return StringWrapper<T>::equalsHelper(lhs.m_val, rhs.m_val); }
+ template <typename T>
+ friend Qt::weak_ordering
+ compareThreeWay(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
+ { return StringWrapper<T>::compareHelper(lhs.m_val, rhs.m_val); }
+ template <typename T>
+ friend bool comparesEqual(const StringWrapper<T> &lhs, QAnyStringView rhs)
+ { return StringWrapper<T>::equalsHelper(lhs.m_val, rhs); }
+ template <typename T>
+ friend Qt::weak_ordering compareThreeWay(const StringWrapper<T> &lhs, QAnyStringView rhs)
+ { return StringWrapper<T>::compareHelper(lhs.m_val, rhs); }
+
+ Q_DECLARE_WEAKLY_ORDERED(StringWrapper)
+ Q_DECLARE_WEAKLY_ORDERED(StringWrapper, QAnyStringView)
+
+ String m_val;
+};
+
+#endif // TST_QCOMPAREHELPERS_WRAPPERTYPES_H
diff --git a/tests/auto/corelib/global/qflags/CMakeLists.txt b/tests/auto/corelib/global/qflags/CMakeLists.txt
new file mode 100644
index 0000000000..8b01ea774f
--- /dev/null
+++ b/tests/auto/corelib/global/qflags/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qflags Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qflags LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qflags
+ SOURCES
+ tst_qflags.cpp
+)
+
+qt_internal_add_test(tst_qflags_non_typesafe
+ SOURCES
+ tst_qflags.cpp
+ DEFINES
+ QFLAGS_TEST_NO_TYPESAFE_FLAGS
+)
diff --git a/tests/auto/corelib/global/qflags/qflags.pro b/tests/auto/corelib/global/qflags/qflags.pro
deleted file mode 100644
index c3c11fa81b..0000000000
--- a/tests/auto/corelib/global/qflags/qflags.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qflags
-QT = core testlib
-SOURCES = tst_qflags.cpp
-qtConfig(c++11): CONFIG += c++11
-qtConfig(c++14): CONFIG += c++14
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp
index 72b086350e..d226e8d6b4 100644
--- a/tests/auto/corelib/global/qflags/tst_qflags.cpp
+++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp
@@ -1,39 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifdef QFLAGS_TEST_NO_TYPESAFE_FLAGS
+# ifdef QT_TYPESAFE_FLAGS
+# undef QT_TYPESAFE_FLAGS
+# endif
+#else
+# ifndef QT_TYPESAFE_FLAGS
+# define QT_TYPESAFE_FLAGS
+# endif
+#endif
+
+#include <QTest>
class tst_QFlags: public QObject
{
Q_OBJECT
private slots:
+ void boolCasts() const;
+ void operators() const;
+ void mixingDifferentEnums() const;
void testFlag() const;
void testFlagZeroFlag() const;
void testFlagMultiBits() const;
+ void testFlags();
+ void testAnyFlag();
void constExpr();
void signedness();
void classEnum();
@@ -42,14 +33,113 @@ private slots:
void adl();
};
+void tst_QFlags::boolCasts() const
+{
+ // This tests that the operator overloading is sufficient so that common
+ // idioms involving flags -> bool casts work as expected:
+
+ const Qt::Alignment nonNull = Qt::AlignCenter;
+ const Qt::Alignment null = {};
+
+ // basic premiss:
+ QVERIFY(bool(nonNull));
+ QVERIFY(!bool(null));
+
+ // The rest is just checking that stuff compiles:
+
+ // QVERIFY should compile:
+ QVERIFY(nonNull);
+ QVERIFY(!null);
+
+ // ifs should compile:
+ if (null) QFAIL("Can't contextually convert QFlags to bool!");
+ if (!nonNull) QFAIL("Missing operator! on QFlags (shouldn't be necessary).");
+
+ // ternary should compile:
+ QVERIFY(nonNull ? true : false);
+ QVERIFY(!null ? true : false);
+
+ // logical operators should compile:
+ QVERIFY(nonNull && true);
+ QVERIFY(nonNull || false);
+ QVERIFY(!null && true);
+ QVERIFY(!null || false);
+
+ // ... in both directions:
+ QVERIFY(true && nonNull);
+ QVERIFY(false || nonNull);
+ QVERIFY(true && !null);
+ QVERIFY(false || !null);
+
+ // ... and mixed:
+ QVERIFY(null || nonNull);
+ QVERIFY(!(null && nonNull));
+}
+
+void tst_QFlags::operators() const
+{
+#define CHECK(op, LHS, RHS, RES) \
+ do { \
+ QCOMPARE((LHS op RHS), (RES)); \
+ QCOMPARE(( /*CTAD*/ QFlags(LHS) op RHS), (RES)); \
+ QCOMPARE((LHS op QFlags(RHS)), (RES)); \
+ QCOMPARE((QFlags(LHS) op QFlags(RHS)), (RES)); \
+ QCOMPARE((QFlags(LHS) op ## = RHS), (RES)); \
+ QCOMPARE((QFlags(LHS) op ## = QFlags(RHS)), (RES)); \
+ } while (false)
+
+ CHECK(|, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter);
+ CHECK(|, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter);
+ CHECK(&, Qt::AlignHCenter, Qt::AlignVCenter, Qt::Alignment());
+ CHECK(&, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter);
+ CHECK(^, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter);
+ CHECK(^, Qt::AlignHCenter, Qt::AlignHCenter, Qt::Alignment());
+#undef CHECK
+}
+
+void tst_QFlags::mixingDifferentEnums() const
+{
+#define CHECK(op, LHS, RHS, RES) \
+ /* LHS must be QFlags'able */ \
+ do { \
+ QCOMPARE((LHS op RHS), (RES)); \
+ QCOMPARE((RHS op LHS), (RES)); \
+ /*QCOMPARE(( / *CTAD* / QFlags(LHS) op RHS), (RES));*/ \
+ /*QCOMPARE((QFlags(LHS) op ## = RHS), (RES));*/ \
+ } while (false)
+
+ // AlignmentFlags <-> TextFlags
+ {
+ CHECK(|, Qt::AlignCenter, Qt::TextSingleLine, 0x0184);
+ CHECK(&, Qt::AlignCenter, Qt::TextSingleLine, 0x0000);
+ CHECK(^, Qt::AlignCenter, Qt::TextSingleLine, 0x0184);
+ }
+ // QFlags<AlignmentFlags> <-> TextFlags
+ {
+#ifndef QT_TYPESAFE_FLAGS // QTBUG-101344
+ Qt::Alignment MyAlignCenter = Qt::AlignCenter; // convert enum to QFlags
+ CHECK(|, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned!
+ CHECK(&, MyAlignCenter, Qt::TextSingleLine, 0x0000U); // yes, unsigned!
+ CHECK(^, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned!
+#endif
+ }
+ // TextElideMode <-> TextFlags
+ {
+ CHECK(|, Qt::ElideNone, Qt::TextSingleLine, 0x0103);
+ CHECK(&, Qt::ElideNone, Qt::TextSingleLine, 0x0000);
+ CHECK(^, Qt::ElideNone, Qt::TextSingleLine, 0x0103);
+ }
+#undef CHECK
+}
+
void tst_QFlags::testFlag() const
{
Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton;
QVERIFY(btn.testFlag(Qt::LeftButton));
- QVERIFY(!btn.testFlag(Qt::MidButton));
+ QVERIFY(!btn.testFlag(Qt::MiddleButton));
- btn = 0;
+ btn = { };
QVERIFY(!btn.testFlag(Qt::LeftButton));
}
@@ -89,9 +179,66 @@ void tst_QFlags::testFlagMultiBits() const
}
}
+void tst_QFlags::testFlags()
+{
+ using Int = Qt::TextInteractionFlags::Int;
+ constexpr Int Zero(0);
+
+ Qt::TextInteractionFlags flags;
+ QCOMPARE(flags.toInt(), Zero);
+ QVERIFY(flags.testFlags(flags));
+ QVERIFY(Qt::TextInteractionFlags::fromInt(Zero).testFlags(flags));
+ QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse));
+ QVERIFY(!flags.testFlags(Qt::TextSelectableByKeyboard));
+ QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
+ QVERIFY(flags.testFlags(Qt::TextInteractionFlags::fromInt(Zero)));
+ QVERIFY(flags.testFlags(Qt::TextInteractionFlags(Qt::TextSelectableByMouse) & ~Qt::TextSelectableByMouse));
+
+ flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard;
+ QVERIFY(flags.toInt() != Zero);
+ QVERIFY(flags.testFlags(flags));
+ QVERIFY(flags.testFlags(Qt::TextSelectableByMouse));
+ QVERIFY(flags.testFlags(Qt::TextSelectableByKeyboard));
+ QVERIFY(flags.testFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse));
+ QVERIFY(!flags.testFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse | Qt::TextEditable));
+ QVERIFY(!flags.testFlags(Qt::TextInteractionFlags()));
+ QVERIFY(!flags.testFlags(Qt::TextInteractionFlags::fromInt(Zero)));
+ QVERIFY(!flags.testFlags(Qt::TextEditable));
+ QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse | Qt::TextEditable));
+}
+
+void tst_QFlags::testAnyFlag()
+{
+ Qt::TextInteractionFlags flags;
+ QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction));
+ QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByMouse));
+ QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByKeyboard));
+ QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
+ QVERIFY(!flags.testAnyFlag(Qt::TextEditorInteraction));
+ QVERIFY(!flags.testAnyFlag(Qt::TextBrowserInteraction));
+
+ flags = Qt::TextSelectableByMouse;
+ QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction));
+ QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse));
+ QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByKeyboard));
+ QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
+ QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction));
+ QVERIFY(flags.testAnyFlag(Qt::TextBrowserInteraction));
+
+ flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard;
+ QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction));
+ QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse));
+ QVERIFY(flags.testAnyFlags(Qt::TextSelectableByKeyboard));
+ QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
+ QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction));
+ QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction));
+ QVERIFY(flags.testAnyFlag(Qt::TextBrowserInteraction));
+}
+
template <unsigned int N, typename T> bool verifyConstExpr(T n) { return n == N; }
+template <unsigned int N, typename T> bool verifyConstExpr(QFlags<T> n) { return n.toInt() == N; }
-Q_DECL_RELAXED_CONSTEXPR Qt::MouseButtons testRelaxedConstExpr()
+constexpr Qt::MouseButtons testRelaxedConstExpr()
{
Qt::MouseButtons value;
value = Qt::LeftButton | Qt::RightButton;
@@ -103,30 +250,33 @@ Q_DECL_RELAXED_CONSTEXPR Qt::MouseButtons testRelaxedConstExpr()
void tst_QFlags::constExpr()
{
-#ifdef Q_COMPILER_CONSTEXPR
Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton;
- switch (btn) {
- case Qt::LeftButton: QVERIFY(false); break;
- case Qt::RightButton: QVERIFY(false); break;
- case int(Qt::LeftButton | Qt::RightButton): QVERIFY(true); break;
- default: QVERIFY(false);
+ switch (btn.toInt()) {
+ case Qt::LeftButton: QVERIFY(false); break;
+ case Qt::RightButton: QVERIFY(false); break;
+ case (Qt::LeftButton | Qt::RightButton).toInt(): QVERIFY(true); break;
+ default: QFAIL(qPrintable(QStringLiteral("Unexpected button: %1").arg(btn.toInt())));
}
- QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) & Qt::LeftButton)>(Qt::LeftButton));
- QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) & Qt::MiddleButton)>(0));
- QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) | Qt::MiddleButton)>(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton));
- QVERIFY(verifyConstExpr<uint(~(Qt::LeftButton | Qt::RightButton))>(~(Qt::LeftButton | Qt::RightButton)));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::LeftButton) ^ Qt::RightButton)>(Qt::LeftButton ^ Qt::RightButton));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(0))>(0));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::RightButton) & 0xff)>(Qt::RightButton));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::RightButton) | 0xff)>(0xff));
+#define VERIFY_CONSTEXPR(expression, expected) \
+ QVERIFY(verifyConstExpr<(expression).toInt()>(expected))
+
+ VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) & Qt::LeftButton, Qt::LeftButton);
+ VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) & Qt::MiddleButton, 0);
+ VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) | Qt::MiddleButton, Qt::LeftButton | Qt::RightButton | Qt::MiddleButton);
+ VERIFY_CONSTEXPR(~(Qt::LeftButton | Qt::RightButton), ~(Qt::LeftButton | Qt::RightButton));
+ VERIFY_CONSTEXPR(Qt::MouseButtons(Qt::LeftButton) ^ Qt::RightButton, Qt::LeftButton ^ Qt::RightButton);
+ VERIFY_CONSTEXPR(Qt::MouseButtons(0), 0);
+#ifndef QT_TYPESAFE_FLAGS
+ QVERIFY(verifyConstExpr<(Qt::MouseButtons(Qt::RightButton) & 0xff)>(Qt::RightButton));
+ QVERIFY(verifyConstExpr<(Qt::MouseButtons(Qt::RightButton) | 0xff)>(0xff));
+#endif
QVERIFY(!verifyConstExpr<Qt::RightButton>(~Qt::MouseButtons(Qt::LeftButton)));
-#if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304
- QVERIFY(verifyConstExpr<uint(testRelaxedConstExpr())>(Qt::MiddleButton));
-#endif
-#endif
+ VERIFY_CONSTEXPR(testRelaxedConstExpr(), Qt::MiddleButton);
+
+#undef VERIFY_CONSTEXPR
}
void tst_QFlags::signedness()
@@ -135,14 +285,13 @@ void tst_QFlags::signedness()
// underlying type is implementation-defined, we need to allow for
// a different signedness, so we only check that the relative
// signedness of the types matches:
- Q_STATIC_ASSERT((std::is_unsigned<typename std::underlying_type<Qt::MouseButton>::type>::value ==
+ static_assert((std::is_unsigned<typename std::underlying_type<Qt::MouseButton>::type>::value ==
std::is_unsigned<Qt::MouseButtons::Int>::value));
- Q_STATIC_ASSERT((std::is_signed<typename std::underlying_type<Qt::AlignmentFlag>::type>::value ==
+ static_assert((std::is_signed<typename std::underlying_type<Qt::AlignmentFlag>::type>::value ==
std::is_signed<Qt::Alignment::Int>::value));
}
-#if defined(Q_COMPILER_CLASS_ENUM)
enum class MyStrictEnum { StrictZero, StrictOne, StrictTwo, StrictFour=4 };
Q_DECLARE_FLAGS( MyStrictFlags, MyStrictEnum )
Q_DECLARE_OPERATORS_FOR_FLAGS( MyStrictFlags )
@@ -150,15 +299,12 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( MyStrictFlags )
enum class MyStrictNoOpEnum { StrictZero, StrictOne, StrictTwo, StrictFour=4 };
Q_DECLARE_FLAGS( MyStrictNoOpFlags, MyStrictNoOpEnum )
-Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isComplex );
-Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isStatic );
-Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isLarge );
-Q_STATIC_ASSERT( !QTypeInfo<MyStrictFlags>::isPointer );
-#endif
+static_assert( !QTypeInfo<MyStrictFlags>::isComplex );
+static_assert( QTypeInfo<MyStrictFlags>::isRelocatable );
+static_assert( !std::is_pointer_v<MyStrictFlags> );
void tst_QFlags::classEnum()
{
-#if defined(Q_COMPILER_CLASS_ENUM)
// The main aim of the test is making sure it compiles
// The QCOMPARE are there as an extra
MyStrictEnum e1 = MyStrictEnum::StrictOne;
@@ -181,11 +327,14 @@ void tst_QFlags::classEnum()
QVERIFY(!f0);
+#ifndef QT_TYPESAFE_FLAGS
QCOMPARE(f3 & int(1), 1);
QCOMPARE(f3 & uint(1), 1);
+#endif
QCOMPARE(f3 & MyStrictEnum::StrictOne, 1);
MyStrictFlags aux;
+#ifndef QT_TYPESAFE_FLAGS
aux = f3;
aux &= int(1);
QCOMPARE(aux, 1);
@@ -193,6 +342,7 @@ void tst_QFlags::classEnum()
aux = f3;
aux &= uint(1);
QCOMPARE(aux, 1);
+#endif
aux = f3;
aux &= MyStrictEnum::StrictOne;
@@ -257,27 +407,19 @@ void tst_QFlags::classEnum()
// Just to make sure it compiles
if (false)
qDebug() << f3;
-#endif
}
void tst_QFlags::initializerLists()
{
-#if defined(Q_COMPILER_INITIALIZER_LISTS)
Qt::MouseButtons bts = { Qt::LeftButton, Qt::RightButton };
QVERIFY(bts.testFlag(Qt::LeftButton));
QVERIFY(bts.testFlag(Qt::RightButton));
QVERIFY(!bts.testFlag(Qt::MiddleButton));
-#if defined(Q_COMPILER_CLASS_ENUM)
MyStrictNoOpFlags flags = { MyStrictNoOpEnum::StrictOne, MyStrictNoOpEnum::StrictFour };
QVERIFY(flags.testFlag(MyStrictNoOpEnum::StrictOne));
QVERIFY(flags.testFlag(MyStrictNoOpEnum::StrictFour));
QVERIFY(!flags.testFlag(MyStrictNoOpEnum::StrictTwo));
-#endif // Q_COMPILER_CLASS_ENUM
-
-#else
- QSKIP("This test requires C++11 initializer_list support.");
-#endif // Q_COMPILER_INITIALIZER_LISTS
}
void tst_QFlags::testSetFlags()
@@ -286,11 +428,11 @@ void tst_QFlags::testSetFlags()
btn.setFlag(Qt::LeftButton);
QVERIFY(btn.testFlag(Qt::LeftButton));
- QVERIFY(!btn.testFlag(Qt::MidButton));
+ QVERIFY(!btn.testFlag(Qt::MiddleButton));
btn.setFlag(Qt::LeftButton, false);
QVERIFY(!btn.testFlag(Qt::LeftButton));
- QVERIFY(!btn.testFlag(Qt::MidButton));
+ QVERIFY(!btn.testFlag(Qt::MiddleButton));
MyStrictFlags flags;
flags.setFlag(MyStrictEnum::StrictOne);
@@ -331,10 +473,9 @@ enum MyEnum { Zero, One, Two, Four=4 };
Q_DECLARE_FLAGS( MyFlags, MyEnum )
Q_DECLARE_OPERATORS_FOR_FLAGS( MyFlags )
-Q_STATIC_ASSERT( !QTypeInfo<MyFlags>::isComplex );
-Q_STATIC_ASSERT( !QTypeInfo<MyFlags>::isStatic );
-Q_STATIC_ASSERT( !QTypeInfo<MyFlags>::isLarge );
-Q_STATIC_ASSERT( !QTypeInfo<MyFlags>::isPointer );
+static_assert( !QTypeInfo<MyFlags>::isComplex );
+static_assert( QTypeInfo<MyFlags>::isRelocatable );
+static_assert( !std::is_pointer_v<MyFlags> );
QTEST_MAIN(tst_QFlags)
#include "tst_qflags.moc"
diff --git a/tests/auto/corelib/global/qfloat16/CMakeLists.txt b/tests/auto/corelib/global/qfloat16/CMakeLists.txt
new file mode 100644
index 0000000000..f6ca52b0df
--- /dev/null
+++ b/tests/auto/corelib/global/qfloat16/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfloat16 Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfloat16 LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfloat16
+ SOURCES
+ tst_qfloat16.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/global/qfloat16/qfloat16.pro b/tests/auto/corelib/global/qfloat16/qfloat16.pro
deleted file mode 100644
index 42081181b4..0000000000
--- a/tests/auto/corelib/global/qfloat16/qfloat16.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfloat16
-QT = core testlib
-SOURCES = tst_qfloat16.cpp
diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
index b73a297245..7acf8c2cf6 100644
--- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
+++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
@@ -1,55 +1,228 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 by Southwest Research Institute (R)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QFloat16>
+#include <QMetaType>
+#include <QTextStream>
+
+#include <private/qcomparisontesthelper_p.h>
#include <math.h>
+//#define DO_FULL_TEST
+
+static_assert(sizeof(float) == sizeof(quint32), "Float not 32-bit");
+
class tst_qfloat16: public QObject
{
Q_OBJECT
private slots:
+ void compareCompiles();
+ void relationalOperatorsAreConstexpr();
+ void ordering_data();
+ void ordering();
void fuzzyCompare_data();
void fuzzyCompare();
+ void fuzzyIsNull_data();
+ void fuzzyIsNull();
void ltgt_data();
void ltgt();
- void qNan();
+ void qNaN();
+ void infinity();
void float_cast();
void float_cast_data();
void promotionTests();
void arithOps_data();
void arithOps();
+#if defined DO_FULL_TEST
+ void floatToFloat16Full_data();
+ void floatToFloat16Full();
+ void floatFromFloat16Full();
+#endif
void floatToFloat16();
void floatFromFloat16();
+ void finite_data();
+ void finite();
+ void properties();
+ void limits();
+ void mantissaOverflow();
+ void dataStream();
+ void textStream();
};
+void tst_qfloat16::compareCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, float>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, double>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, long double>();
+#if QFLOAT16_IS_NATIVE
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qfloat16::NativeType>();
+#endif
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, int>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint8>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint8>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint16>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint16>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, char16_t>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, long>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, unsigned long>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, wchar_t>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint32>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint32>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint64>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint64>();
+#ifdef QT_SUPPORTS_INT128
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint128>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint128>();
+#endif
+}
+
+void tst_qfloat16::relationalOperatorsAreConstexpr()
+{
+#if QFLOAT16_IS_NATIVE
+
+#define CHECK_CONSTEXPR(Type) \
+ do { \
+ constexpr qfloat16 lhs = qfloat16(0.0f); \
+ constexpr Type rhs = 1; \
+ static_assert(lhs < rhs); \
+ static_assert(rhs >= lhs); \
+ } while (false)
+
+ CHECK_CONSTEXPR(qfloat16);
+ CHECK_CONSTEXPR(float);
+ CHECK_CONSTEXPR(double);
+ CHECK_CONSTEXPR(long double);
+ CHECK_CONSTEXPR(qfloat16::NativeType);
+ CHECK_CONSTEXPR(qint8);
+ CHECK_CONSTEXPR(quint8);
+ CHECK_CONSTEXPR(qint16);
+ CHECK_CONSTEXPR(quint16);
+ CHECK_CONSTEXPR(qint32);
+ CHECK_CONSTEXPR(quint32);
+ CHECK_CONSTEXPR(long);
+ CHECK_CONSTEXPR(unsigned long);
+ CHECK_CONSTEXPR(qint64);
+ CHECK_CONSTEXPR(quint64);
+#ifdef QT_SUPPORTS_INT128
+ CHECK_CONSTEXPR(qint128);
+ CHECK_CONSTEXPR(quint128);
+#endif
+
+#undef CHECK_CONSTEXPR
+
+#else
+ QSKIP("This check is only relevant for native float16 types");
+#endif // QFLOAT16_IS_NATIVE
+}
+
+void tst_qfloat16::ordering_data()
+{
+ QTest::addColumn<float>("left");
+ QTest::addColumn<float>("right");
+
+ auto row = [](float left, float right) {
+ QTest::addRow("%f_vs_%f", left, right) << left << right;
+ };
+
+ row(0.0f, 0.0f);
+ row(0.000001f, 0.0f);
+ row(0.0f, 0.000001f);
+ row(-1.000001f, 1.000001f);
+ const float nan = std::numeric_limits<float>::quiet_NaN();
+ const float inf = std::numeric_limits<float>::infinity();
+ row(nan, nan);
+ row(nan, inf);
+ row(inf, nan);
+ row(-inf, nan);
+ row(nan, -inf);
+ row(-inf, inf);
+ row(inf, -inf);
+ row(-inf, 0.0f);
+ row(0.0f, inf);
+ row(0.0f, nan);
+ row(nan, 0.0f);
+ row(2.0f, 314.159f);
+ row(-314.159f, 2.0f);
+ row(-2.0f, 314.159f);
+ row(nan, 314.159f);
+ row(-314.159f, inf);
+ row(-inf, 314.159f);
+ row(2.0f, -inf);
+ row(-2.0f, nan);
+ row(-inf, -2.0f);
+ // testing with values outside qfloat16 range
+ row(0.0f, 13e5f);
+ // generateRow(inf, 13e5f); // fails qfloat16 vs qfloat16 and qfloat16 vs int (QTBUG-118193)
+ row(0.0f, -13e5f);
+ // generateRow(-inf, -13e5f); // fails qfloat16 vs qfloat16 and qfloat16 vs int (QTBUG-118193)
+}
+
+void tst_qfloat16::ordering()
+{
+ QFETCH(float, left);
+ QFETCH(float, right);
+
+ const auto expectedOrder = Qt::compareThreeWay(left, right);
+ const auto lhs = qfloat16(left);
+
+#define POSTCHECK(msg) \
+ if (QTest::currentTestFailed()) { qDebug(msg); return; }
+
+#define CHECK_FP(RHS) \
+ do { \
+ QTestPrivate::testAllComparisonOperators(lhs, static_cast<RHS>(right), expectedOrder); \
+ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \
+ } while (false) \
+ /* END */
+
+ CHECK_FP(qfloat16);
+ CHECK_FP(float);
+ CHECK_FP(double);
+ CHECK_FP(long double);
+
+#undef CHECK_FP
+
+#define CHECK_INT(RHS) \
+ do { \
+ const auto rhs = static_cast<RHS>(right); \
+ const auto expectedRes = Qt::compareThreeWay(left, rhs); \
+ QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); \
+ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \
+ } while (false) \
+ /* END */
+
+ if (qIsFinite(right)) {
+ CHECK_INT(int);
+ CHECK_INT(qint8);
+ CHECK_INT(signed char);
+ CHECK_INT(qint16);
+ CHECK_INT(qint32);
+ CHECK_INT(qint64);
+#if QT_SUPPORTS_INT128
+ CHECK_INT(qint128);
+#endif
+ if (right >= 0) {
+ CHECK_INT(unsigned int);
+ CHECK_INT(quint8);
+ CHECK_INT(unsigned char);
+ CHECK_INT(quint16);
+ CHECK_INT(quint32);
+ CHECK_INT(quint64);
+ #if QT_SUPPORTS_INT128
+ CHECK_INT(quint128);
+ #endif
+ }
+ }
+
+#undef CHECK_INT
+#undef POSTCHECK
+}
+
void tst_qfloat16::fuzzyCompare_data()
{
QTest::addColumn<qfloat16>("val1");
@@ -95,12 +268,40 @@ void tst_qfloat16::fuzzyCompare()
}
}
+void tst_qfloat16::fuzzyIsNull_data()
+{
+ QTest::addColumn<qfloat16>("value");
+ QTest::addColumn<bool>("isNull");
+ using Bounds = std::numeric_limits<qfloat16>;
+ const qfloat16 one(1), huge(1000), tiny(0.00976f);
+
+ QTest::newRow("zero") << qfloat16(0.0f) << true;
+ QTest::newRow("min") << Bounds::min() << true;
+ QTest::newRow("denorm_min") << Bounds::denorm_min() << true;
+ QTest::newRow("tiny") << tiny << true;
+
+ QTest::newRow("deci") << qfloat16(.1) << false;
+ QTest::newRow("one") << one << false;
+ QTest::newRow("ten") << qfloat16(10) << false;
+ QTest::newRow("huge") << huge << false;
+}
+
+void tst_qfloat16::fuzzyIsNull()
+{
+ QFETCH(qfloat16, value);
+ QFETCH(bool, isNull);
+
+ QCOMPARE(::qFuzzyIsNull(value), isNull);
+ QCOMPARE(::qFuzzyIsNull(-value), isNull);
+}
+
void tst_qfloat16::ltgt_data()
{
QTest::addColumn<float>("val1");
QTest::addColumn<float>("val2");
QTest::newRow("zero") << 0.0f << 0.0f;
+ QTest::newRow("-zero") << -0.0f << 0.0f;
QTest::newRow("ten") << 10.0f << 10.0f;
QTest::newRow("large") << 100000.0f << 100000.0f;
QTest::newRow("small") << 0.0000001f << 0.0000001f;
@@ -152,38 +353,57 @@ void tst_qfloat16::ltgt()
# pragma GCC optimize "no-fast-math"
#endif
-void tst_qfloat16::qNan()
+void tst_qfloat16::qNaN()
{
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404)
QSKIP("Non-conformant fast math mode is enabled, cannot run test");
#endif
- qfloat16 nan = qQNaN();
- QVERIFY(!(0. > nan));
- QVERIFY(!(0. < nan));
+ using Bounds = std::numeric_limits<qfloat16>;
+ const qfloat16 nan = Bounds::quiet_NaN();
+ const qfloat16 zero(0), one(1);
+ QVERIFY(!(zero > nan));
+ QVERIFY(!(zero < nan));
+ QVERIFY(!(zero == nan));
QVERIFY(!qIsInf(nan));
QVERIFY(qIsNaN(nan));
- QVERIFY(qIsNaN(nan + 1.f));
+ QVERIFY(qIsNaN(nan + one));
QVERIFY(qIsNaN(-nan));
- qfloat16 inf = qInf();
- QVERIFY(inf > qfloat16(0));
- QVERIFY(-inf < qfloat16(0));
- QVERIFY(!qIsNaN(inf));
- QVERIFY(qIsInf(inf));
- QVERIFY(qIsInf(-inf));
- QVERIFY(qIsInf(2.f*inf));
- QVERIFY(qIsInf(inf*2.f));
- // QTBUG-75812: QEMU/arm64 compiler over-optimizes, so flakily fails 1/inf == 0 :-(
- if (qfloat16(9.785e-4f) == qfloat16(9.794e-4f))
- QCOMPARE(qfloat16(1.f) / inf, qfloat16(0.f));
-#ifdef Q_CC_INTEL
- QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue);
-#endif
- QVERIFY(qIsNaN(nan*0.f));
-#ifdef Q_CC_INTEL
- QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue);
-#endif
- QVERIFY(qIsNaN(inf*0.f));
- QVERIFY(qFuzzyCompare(qfloat16(1.f/inf), qfloat16(0.0)));
+ QVERIFY(qIsNaN(nan * zero));
+ QVERIFY(qIsNaN(Bounds::infinity() * zero));
+
+ QVERIFY(!nan.isNormal());
+ QVERIFY(!qIsFinite(nan));
+ QVERIFY(!(nan == nan));
+ QCOMPARE(nan, nan); // Despite the preceding
+ QCOMPARE(qFpClassify(nan), FP_NAN);
+}
+
+void tst_qfloat16::infinity()
+{
+ const qfloat16 huge = std::numeric_limits<qfloat16>::infinity();
+ const qfloat16 zero(0), one(1), two(2);
+ QVERIFY(huge > -huge);
+ QVERIFY(huge > zero);
+ QVERIFY(-huge < zero);
+ QCOMPARE(huge, huge);
+ QCOMPARE(-huge, -huge);
+
+ QCOMPARE(one / huge, zero);
+ QVERIFY(qFuzzyCompare(one / huge, zero)); // (same thing)
+
+ QVERIFY(qIsInf(huge));
+ QVERIFY(qIsInf(-huge));
+ QVERIFY(qIsInf(two * huge));
+ QVERIFY(qIsInf(huge * two));
+
+ QVERIFY(!huge.isNormal());
+ QVERIFY(!(-huge).isNormal());
+ QVERIFY(!qIsNaN(huge));
+ QVERIFY(!qIsNaN(-huge));
+ QVERIFY(!qIsFinite(huge));
+ QVERIFY(!qIsFinite(-huge));
+ QCOMPARE(qFpClassify(huge), FP_INFINITE);
+ QCOMPARE(qFpClassify(-huge), FP_INFINITE);
}
void tst_qfloat16::float_cast_data()
@@ -261,7 +481,7 @@ void tst_qfloat16::promotionTests()
QCOMPARE(sizeof(double),sizeof(qfloat16(1.f)*1));
QCOMPARE(sizeof(double),sizeof(qfloat16(1.f)/1));
- QCOMPARE(QString::number(1.f),QString::number(qfloat16(1.f)));
+ QCOMPARE(QString::number(1.f),QString::number(double(qfloat16(1.f))));
}
void tst_qfloat16::arithOps_data()
@@ -311,22 +531,80 @@ void tst_qfloat16::arithOps()
QVERIFY(qFuzzyCompare(r4,1.f/val2));
}
+#if defined DO_FULL_TEST
+void tst_qfloat16::floatToFloat16Full_data()
+{
+ QTest::addColumn<quint32>("group");
+ for (quint32 j = 0x00; j < 0x100; ++j)
+ QTest::addRow("%02x", j) << j;
+
+}
+
+void tst_qfloat16::floatToFloat16Full()
+{
+ QFETCH(quint32, group);
+ for (quint32 j = 0x00; j < 0x100; ++j) {
+ quint32 data[1<<16];
+ qfloat16 out[1<<16];
+ qfloat16 expected[1<<16];
+ float in[1<<16];
+
+ for (int i = 0; i < (1<<16); ++i)
+ data[i] = (group << 24) | (j << 16) | i;
+
+ memcpy(in, data, (1<<16)*sizeof(float));
+
+ for (int i = 0; i < (1<<16); ++i)
+ expected[i] = qfloat16(in[i]);
+
+ qFloatToFloat16(out, in, 1<<16);
+
+ for (int i = 0; i < (1<<16); ++i) {
+ if (out[i] != expected[i])
+ QVERIFY(qIsNaN(out[i]) && qIsNaN(expected[i]));
+ }
+ }
+}
+
+void tst_qfloat16::floatFromFloat16Full()
+{
+ quint16 data[1<<16];
+ float out[1<<16];
+ float expected[1<<16];
+
+ for (int i = 0; i < (1<<16); ++i)
+ data[i] = i;
+
+ const qfloat16 *in = reinterpret_cast<const qfloat16 *>(data);
+
+ for (int i = 0; i < (1<<16); ++i)
+ expected[i] = float(in[i]);
+
+ qFloatFromFloat16(out, in, 1<<16);
+
+ for (int i = 0; i < (1<<16); ++i)
+ if (out[i] != expected[i])
+ QVERIFY(qIsNaN(out[i]) && qIsNaN(expected[i]));
+}
+#endif
+
void tst_qfloat16::floatToFloat16()
{
- float in[63];
- qfloat16 out[63];
- qfloat16 expected[63];
+ constexpr int count = 10000;
+ float in[count];
+ qfloat16 out[count];
+ qfloat16 expected[count];
- for (int i = 0; i < 63; ++i)
- in[i] = i * (1/13.f);
+ for (int i = 0; i < count; ++i)
+ in[i] = (i - count/2) * (1/13.f);
- for (int i = 0; i < 63; ++i)
+ for (int i = 0; i < count; ++i)
expected[i] = qfloat16(in[i]);
- qFloatToFloat16(out, in, 63);
+ qFloatToFloat16(out, in, count);
- for (int i = 0; i < 63; ++i)
- QVERIFY(qFuzzyCompare(out[i], expected[i]));
+ for (int i = 0; i < count; ++i)
+ QVERIFY(out[i] == expected[i]);
}
void tst_qfloat16::floatFromFloat16()
@@ -347,5 +625,246 @@ void tst_qfloat16::floatFromFloat16()
QCOMPARE(out[i], expected[i]);
}
+static qfloat16 powf16(qfloat16 base, int raise)
+{
+ const qfloat16 one(1.f);
+ if (raise < 0) {
+ raise = -raise;
+ base = one / base;
+ }
+ qfloat16 answer = (raise & 1) ? base : one;
+ while (raise > 0) {
+ raise >>= 1;
+ base *= base;
+ if (raise & 1)
+ answer *= base;
+ }
+ return answer;
+}
+
+void tst_qfloat16::finite_data()
+{
+ using Bounds = std::numeric_limits<qfloat16>;
+ QTest::addColumn<qfloat16>("value");
+ QTest::addColumn<int>("mode");
+
+ QTest::newRow("zero") << qfloat16(0) << FP_ZERO;
+ QTest::newRow("-zero") << -qfloat16(0) << FP_ZERO;
+ QTest::newRow("one") << qfloat16(1) << FP_NORMAL;
+ QTest::newRow("-one") << qfloat16(-1) << FP_NORMAL;
+ QTest::newRow("ten") << qfloat16(10) << FP_NORMAL;
+ QTest::newRow("-ten") << qfloat16(-10) << FP_NORMAL;
+ QTest::newRow("max") << Bounds::max() << FP_NORMAL;
+ QTest::newRow("lowest") << Bounds::lowest() << FP_NORMAL;
+ QTest::newRow("min") << Bounds::min() << FP_NORMAL;
+ QTest::newRow("-min") << -Bounds::min() << FP_NORMAL;
+ QTest::newRow("denorm_min") << Bounds::denorm_min() << FP_SUBNORMAL;
+ QTest::newRow("-denorm_min") << -Bounds::denorm_min() << FP_SUBNORMAL;
+}
+
+void tst_qfloat16::finite()
+{
+ QFETCH(qfloat16, value);
+ QFETCH(int, mode);
+ QCOMPARE(value.isNormal(), mode == FP_NORMAL);
+ QCOMPARE(value, value); // Fuzzy
+ QVERIFY(value == value); // Exact
+ QVERIFY(qIsFinite(value));
+ QVERIFY(!qIsInf(value));
+ QVERIFY(!qIsNaN(value));
+ QCOMPARE(qFpClassify(value), mode);
+
+ // *NOT* using QCOMPARE() on finite qfloat16 values, since that uses fuzzy
+ // comparison, and we need exact here.
+ const qfloat16 zero(0), plus(+1), minus(-1);
+ const qfloat16 magnitude = (value < zero) ? -value : value;
+ QVERIFY(value.copySign(plus) == magnitude);
+ QVERIFY(value.copySign(minus) == -magnitude);
+}
+
+void tst_qfloat16::properties()
+{
+ using Bounds = std::numeric_limits<qfloat16>;
+ QVERIFY(Bounds::is_specialized);
+ QVERIFY(Bounds::is_signed);
+ QVERIFY(!Bounds::is_integer);
+ QVERIFY(!Bounds::is_exact);
+
+ // While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011
+ // Annex F (C11, normative for C++11), there are a few corner cases regarding
+ // denormals where GHS compiler is relying hardware behavior that is not IEC
+ // 559 compliant.
+
+ // On GHS the compiler reports std::numeric_limits<float>::is_iec559 as false.
+ // and the same supposed to be for qfloat16.
+#if !defined(Q_CC_GHS)
+ QVERIFY(Bounds::is_iec559);
+#endif //Q_CC_GHS
+#if QT_CONFIG(signaling_nan)
+ // Technically, presence of NaN and infinities are implied from the above check, but that checkings GHS compiler complies.
+ QVERIFY(Bounds::has_infinity && Bounds::has_quiet_NaN && Bounds::has_signaling_NaN);
+#endif
+ QVERIFY(Bounds::is_bounded);
+ QVERIFY(!Bounds::is_modulo);
+ QVERIFY(!Bounds::traps);
+ QVERIFY(Bounds::has_infinity);
+ QVERIFY(Bounds::has_quiet_NaN);
+#if QT_CONFIG(signaling_nan)
+ QVERIFY(Bounds::has_signaling_NaN);
+#endif
+#if !defined(Q_CC_GHS)
+ QCOMPARE(Bounds::has_denorm, std::denorm_present);
+#else
+ // For GHS compiler the "denorm_indeterminite" is the expected return value.
+ QCOMPARE(Bounds::has_denorm, std::denorm_indeterminate);
+#endif // Q_CC_GHS
+ QCOMPARE(Bounds::round_style, std::round_to_nearest);
+ QCOMPARE(Bounds::radix, 2);
+ // Untested: has_denorm_loss
+}
+
+void tst_qfloat16::limits() // See also: qNaN() and infinity()
+{
+ // *NOT* using QCOMPARE() on finite qfloat16 values, since that uses fuzzy
+ // comparison, and we need exact here.
+ using Bounds = std::numeric_limits<qfloat16>;
+
+ // A few useful values:
+ const qfloat16 zero(0), one(1), ten(10);
+
+ // The specifics of minus zero:
+ // (IEEE 754 seems to want -zero < zero, but -0. == 0. and -0.f == 0.f in C++.)
+ QVERIFY(-zero <= zero);
+ QVERIFY(-zero == zero);
+ QVERIFY(!(-zero > zero));
+
+ // digits in the mantissa, including the implicit 1 before the binary dot at its left:
+ QVERIFY(qfloat16(1 << (Bounds::digits - 1)) + one > qfloat16(1 << (Bounds::digits - 1)));
+ QVERIFY(qfloat16(1 << Bounds::digits) + one == qfloat16(1 << Bounds::digits));
+
+ // There is a wilful of-by-one in how m(ax|in)_exponent are defined; they're
+ // the lowest and highest n for which radix^{n-1} are normal and finite.
+ const qfloat16 two(Bounds::radix);
+ qfloat16 bit = powf16(two, Bounds::max_exponent - 1);
+ QVERIFY(qIsFinite(bit));
+ QVERIFY(qIsInf(bit * two));
+ bit = powf16(two, Bounds::min_exponent - 1);
+ QVERIFY(bit.isNormal());
+ QCOMPARE(qFpClassify(bit), FP_NORMAL);
+ QVERIFY(!(bit / two).isNormal());
+ QCOMPARE(qFpClassify(bit / two), FP_SUBNORMAL);
+ QVERIFY(bit / two > zero);
+
+ // Base ten (with no matching off-by-one idiocy):
+ // the lowest negative number n such that 10^n is a valid normalized value
+ qfloat16 low10(powf16(ten, Bounds::min_exponent10));
+ QVERIFY(low10 > zero);
+ QVERIFY(low10.isNormal());
+ low10 /= ten;
+ QVERIFY(low10 == zero || !low10.isNormal());
+ // the largest positive number n such that 10^n is a representable finite value
+ qfloat16 high10(powf16(ten, Bounds::max_exponent10));
+ QVERIFY(high10 > zero);
+ QVERIFY(qIsFinite(high10));
+ QVERIFY(!qIsFinite(high10 * ten));
+ QCOMPARE(qFpClassify(high10), FP_NORMAL);
+
+ // How many digits are significant ? (Casts avoid linker errors ...)
+ QCOMPARE(int(Bounds::digits10), 3); // ~9.88e-4 has enough sigificant digits:
+ qfloat16 below(9.876e-4f), above(9.884e-4f); // both round to ~9.88e-4
+ QVERIFY(below == above);
+ QCOMPARE(int(Bounds::max_digits10), 5); // we need 5 to distinguish these two:
+ QVERIFY(qfloat16(1000.5f) != qfloat16(1001.4f));
+
+ // Actual limiting values of the type:
+ const qfloat16 rose(one + Bounds::epsilon());
+ QVERIFY(rose > one);
+ QVERIFY(one + Bounds::epsilon() / two == one);
+
+ QVERIFY(Bounds::max() > zero);
+ QVERIFY(qIsInf(Bounds::max() * rose));
+
+ QVERIFY(Bounds::lowest() < zero);
+ QVERIFY(qIsInf(Bounds::lowest() * rose));
+
+ QVERIFY(Bounds::min() > zero);
+ QVERIFY(!(Bounds::min() / rose).isNormal());
+
+ QVERIFY(Bounds::denorm_min() > zero);
+ QVERIFY(Bounds::denorm_min() / two == zero);
+ const qfloat16 under = (-Bounds::denorm_min()) / two;
+ QVERIFY(under == -zero);
+ QCOMPARE(qfloat16(1).copySign(under), qfloat16(-1));
+}
+
+void tst_qfloat16::mantissaOverflow()
+{
+ // Test we don't change category due to mantissa overflow when rounding.
+ quint32 in = 0x7fffffff;
+ float f;
+ memcpy(&f, &in, 4);
+
+ qfloat16 f16 = qfloat16(f);
+ qfloat16 f16s[1];
+ qFloatToFloat16(f16s, &f, 1);
+ QCOMPARE(f16, f16s[0]);
+ QVERIFY(qIsNaN(f16));
+}
+
+void tst_qfloat16::dataStream()
+{
+ QByteArray ba;
+ QDataStream ds(&ba, QIODevice::ReadWrite);
+ ds << qfloat16(1.5) << qfloat16(-1);
+ QCOMPARE(ba.size(), 4);
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ QCOMPARE(ba, QByteArray("\x3e\0\xbc\0", 4));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ ds.setByteOrder(QDataStream::LittleEndian);
+ ds << qfloat16(0) << qfloat16(-1);
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ QCOMPARE(ba, QByteArray("\0\0\0\xbc", 4));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ qfloat16 zero = 1;
+ ds >> zero;
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ QCOMPARE(zero, qfloat16(0));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ QMetaType mt = QMetaType(QMetaType::Float16);
+ QVERIFY(mt.save(ds, &zero));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ zero = -1;
+ QVERIFY(mt.load(ds, &zero));
+ QCOMPARE(zero, qfloat16(0));
+}
+
+void tst_qfloat16::textStream()
+{
+ QString buffer;
+ {
+ QTextStream ts(&buffer);
+ ts << qfloat16(0) << Qt::endl << qfloat16(1.5);
+ QCOMPARE(ts.status(), QTextStream::Ok);
+ }
+ QCOMPARE(buffer, "0\n1.5");
+
+ {
+ QTextStream ts(&buffer);
+ qfloat16 zero = qfloat16(-2.5), threehalves = 1234;
+ ts >> zero >> threehalves;
+ QCOMPARE(ts.status(), QTextStream::Ok);
+ QCOMPARE(zero, qfloat16(0));
+ QCOMPARE(threehalves, 1.5);
+ }
+}
+
QTEST_APPLESS_MAIN(tst_qfloat16)
#include "tst_qfloat16.moc"
diff --git a/tests/auto/corelib/global/qgetputenv/CMakeLists.txt b/tests/auto/corelib/global/qgetputenv/CMakeLists.txt
new file mode 100644
index 0000000000..f1a5cbeef3
--- /dev/null
+++ b/tests/auto/corelib/global/qgetputenv/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qgetputenv Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qgetputenv LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qgetputenv
+ SOURCES
+ tst_qgetputenv.cpp
+)
diff --git a/tests/auto/corelib/global/qgetputenv/qgetputenv.pro b/tests/auto/corelib/global/qgetputenv/qgetputenv.pro
deleted file mode 100644
index c6d1100335..0000000000
--- a/tests/auto/corelib/global/qgetputenv/qgetputenv.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qgetputenv
-QT = core testlib
-SOURCES = tst_qgetputenv.cpp
diff --git a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
index 544cb1bf07..96f2ce853c 100644
--- a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
+++ b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qdebug.h>
-#include <QtTest/QtTest>
+#include <QTest>
#include <qglobal.h>
#ifdef Q_OS_WIN
@@ -85,7 +60,11 @@ void tst_QGetPutEnv::getSetCheck()
QCOMPARE(sresult, QString());
#endif
- QVERIFY(qputenv(varName, QByteArray("supervalue")));
+ constexpr char varValueFullString[] = "supervalue123";
+ const auto varValueQBA = QByteArray::fromRawData(varValueFullString, sizeof varValueFullString - 4);
+ QCOMPARE_EQ(varValueQBA, "supervalue");
+
+ QVERIFY(qputenv(varName, varValueQBA));
QVERIFY(qEnvironmentVariableIsSet(varName));
QVERIFY(!qEnvironmentVariableIsEmpty(varName));
@@ -135,9 +114,7 @@ void tst_QGetPutEnv::encoding()
static const wchar_t rawvalue[] = { 'a', 0x00E1, 0x03B1, 0x0430, 0 };
QString value = QString::fromWCharArray(rawvalue);
-#if defined(Q_OS_WINRT)
- QSKIP("Test cannot be run on this platform");
-#elif defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
const wchar_t wvarName[] = L"should_not_exist";
_wputenv_s(wvarName, rawvalue);
#else
@@ -214,7 +191,7 @@ void tst_QGetPutEnv::intValue()
bool actualOk = !ok;
// Self-test: confirm that it was like the docs said it should be
- if (value.length() < maxlen) {
+ if (value.size() < maxlen) {
QCOMPARE(value.toInt(&actualOk, 0), expected);
QCOMPARE(actualOk, ok);
}
diff --git a/tests/auto/corelib/global/qglobal/CMakeLists.txt b/tests/auto/corelib/global/qglobal/CMakeLists.txt
new file mode 100644
index 0000000000..5a0877663b
--- /dev/null
+++ b/tests/auto/corelib/global/qglobal/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qglobal Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qglobal LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qglobal
+ SOURCES
+ qglobal.c
+ tst_qglobal.cpp
+ NO_PCH_SOURCES
+ tst_qglobal.cpp # undef QT_NO_FOREACH
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/global/qglobal/qglobal.c b/tests/auto/corelib/global/qglobal/qglobal.c
index 0719c4b921..2cfbd5e3be 100644
--- a/tests/auto/corelib/global/qglobal/qglobal.c
+++ b/tests/auto/corelib/global/qglobal/qglobal.c
@@ -1,41 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qglobal.h>
-
-#if QT_HAS_INCLUDE(<stdbool.h>) || __STDC_VERSION__ >= 199901L
-# include <stdbool.h>
-#else
-# undef true
-# define true 1
-# undef false
-# define false 0
-#endif
+#include <QtCore/qtversion.h>
+#include <QtCore/qyieldcpu.h>
+#include <QtCore/qtypes.h>
#ifdef Q_COMPILER_THREAD_LOCAL
# include <threads.h>
@@ -46,6 +15,11 @@
* everything works.
*/
+#if defined(Q_OS_VXWORKS) && !defined(thread_local)
+// threads.h forgot to define this (should be fixed for version 23.11)
+# define thread_local _Thread_local
+#endif
+
/* Types and Q_UNUSED */
void tst_GlobalTypes()
{
@@ -77,15 +51,28 @@ void tst_GlobalTypes()
qintptr qip;
quintptr qup;
Q_UNUSED(qs); Q_UNUSED(qp); Q_UNUSED(qip); Q_UNUSED(qup);
+
+#ifdef QT_SUPPORTS_INT128
+ qint128 s128;
+ quint128 u128;
+ Q_UNUSED(s128); Q_UNUSED(u128);
+#endif /* QT_SUPPORTS_INT128 */
}
+#if QT_SUPPORTS_INT128
+qint128 tst_qint128_min() { return Q_INT128_MIN + 0; }
+qint128 tst_qint128_max() { return 0 + Q_INT128_MAX; }
+quint128 tst_quint128_max() { return Q_UINT128_MAX - 1 + 1; }
+#endif
+
/* Qt version */
int tst_QtVersion()
{
return QT_VERSION;
}
-const char *tst_qVersion() Q_DECL_NOTHROW
+const char *tst_qVersion() Q_DECL_NOEXCEPT;
+const char *tst_qVersion()
{
#if !defined(QT_NAMESPACE)
return qVersion();
@@ -94,6 +81,12 @@ const char *tst_qVersion() Q_DECL_NOTHROW
#endif
}
+void tst_qYieldCpu(void) Q_DECL_NOEXCEPT;
+void tst_qYieldCpu(void)
+{
+ qYieldCpu();
+}
+
/* Static assertion */
Q_STATIC_ASSERT(true);
Q_STATIC_ASSERT(1);
@@ -106,12 +99,19 @@ Q_STATIC_ASSERT(!0);
Q_STATIC_ASSERT(!!true);
Q_STATIC_ASSERT(!!1);
+#ifdef __COUNTER__
+// if the compiler supports __COUNTER__, multiple
+// Q_STATIC_ASSERT's on a single line should compile:
+Q_STATIC_ASSERT(true); Q_STATIC_ASSERT_X(!false, "");
+#endif // __COUNTER__
+
#ifdef Q_COMPILER_THREAD_LOCAL
static thread_local int gt_var;
void thread_local_test()
{
static thread_local int t_var;
t_var = gt_var;
+ Q_UNUSED(t_var);
}
#endif
diff --git a/tests/auto/corelib/global/qglobal/qglobal.pro b/tests/auto/corelib/global/qglobal/qglobal.pro
deleted file mode 100644
index a40cb9a288..0000000000
--- a/tests/auto/corelib/global/qglobal/qglobal.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qglobal
-QT = core testlib
-SOURCES = tst_qglobal.cpp qglobal.c
diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
index 78b954f373..1a19048bbe 100644
--- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
+++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
@@ -1,38 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#undef QT_NO_FOREACH // this file tests Q_FOREACH!
+
+#include <QTest>
#include <QPair>
-#include <QTextCodec>
#include <QSysInfo>
#include <QLatin1String>
+#include <QString>
+#include <QtVersion>
+
+#include <cmath>
+#include <limits>
+#include <type_traits>
class tst_QGlobal: public QObject
{
@@ -49,18 +31,30 @@ private slots:
void qConstructorFunction();
void qCoreAppStartupFunction();
void qCoreAppStartupFunctionRestart();
- void qAlignOf();
void integerForSize();
- void qprintable();
- void qprintable_data();
+ void int128Literals();
void buildAbiEndianness();
void testqOverload();
+ void testqMinMax();
+ void qRoundFloats_data();
+ void qRoundFloats();
+ void qRoundDoubles_data();
+ void qRoundDoubles();
+ void PRImacros();
+ void testqToUnderlying();
+ void nodiscard();
};
extern "C" { // functions in qglobal.c
void tst_GlobalTypes();
int tst_QtVersion();
const char *tst_qVersion();
+#if QT_SUPPORTS_INT128
+qint128 tst_qint128_min();
+qint128 tst_qint128_max();
+quint128 tst_quint128_max();
+#endif
+
}
void tst_QGlobal::cMode()
@@ -96,14 +90,14 @@ void tst_QGlobal::qIsNull()
void tst_QGlobal::for_each()
{
- QVector<int> list;
+ QList<int> list;
list << 0 << 1 << 2 << 3 << 4 << 5;
int counter = 0;
foreach(int i, list) {
QCOMPARE(i, counter++);
}
- QCOMPARE(counter, list.count());
+ QCOMPARE(counter, list.size());
// do it again, to make sure we don't have any for-scoping
// problems with older compilers
@@ -111,21 +105,61 @@ void tst_QGlobal::for_each()
foreach(int i, list) {
QCOMPARE(i, counter++);
}
- QCOMPARE(counter, list.count());
+ QCOMPARE(counter, list.size());
// check whether we can pass a constructor as container argument
counter = 0;
- foreach (int i, QVector<int>(list)) {
+ foreach (int i, QList<int>(list)) {
QCOMPARE(i, counter++);
}
- QCOMPARE(counter, list.count());
+ QCOMPARE(counter, list.size());
// check whether we can use a lambda
counter = 0;
foreach (int i, [&](){ return list; }()) {
QCOMPARE(i, counter++);
}
- QCOMPARE(counter, list.count());
+ QCOMPARE(counter, list.size());
+
+ // Should also work with an existing variable
+ int local = 0;
+ counter = 0;
+ foreach (local, list) {
+ QCOMPARE(local, counter++);
+ }
+ QCOMPARE(counter, list.size());
+ QCOMPARE(local, counter - 1);
+
+ // Test the macro does not mess if/else conditions
+ counter = 0;
+ if (true)
+ foreach (int i, list)
+ QCOMPARE(i, counter++);
+ else
+ QFAIL("If/Else mismatch");
+ QCOMPARE(counter, list.size());
+
+ counter = 0;
+ if (false)
+ foreach (int i, list)
+ if (i) QFAIL("If/Else mismatch");
+ else QFAIL("If/Else mismatch");
+ else
+ foreach (int i, list)
+ if (false) { }
+ else QCOMPARE(i, counter++);
+ QCOMPARE(counter, list.size());
+
+ // break and continue
+ counter = 0;
+ foreach (int i, list) {
+ if (i == 0)
+ continue;
+ QCOMPARE(i, (counter++) + 1);
+ if (i == 3)
+ break;
+ }
+ QCOMPARE(counter, 3);
}
void tst_QGlobal::qassert()
@@ -309,6 +343,9 @@ struct MyTemplate
void tst_QGlobal::qstaticassert()
{
+ // Test multiple Q_STATIC_ASSERT on a single line
+ Q_STATIC_ASSERT(true); Q_STATIC_ASSERT_X(!false, "");
+
// Force compilation of these classes
MyTrue tmp1;
MyExpresion tmp2;
@@ -316,11 +353,6 @@ void tst_QGlobal::qstaticassert()
Q_UNUSED(tmp1);
Q_UNUSED(tmp2);
Q_UNUSED(tmp3);
-#ifdef __COUNTER__
- // if the compiler supports __COUNTER__, multiple
- // Q_STATIC_ASSERT's on a single line should compile:
- Q_STATIC_ASSERT(true); Q_STATIC_ASSERT_X(!false, "");
-#endif // __COUNTER__
QVERIFY(true); // if the test compiles it has passed.
}
@@ -394,182 +426,177 @@ template <class T> struct AlignmentInStruct { T dummy; };
typedef int (*fun) ();
typedef int (Empty::*memFun) ();
-#define TEST_AlignOf(type, alignment) \
- do { \
- TEST_AlignOf_impl(type, alignment); \
- \
- TEST_AlignOf_impl(type &, alignment); \
- TEST_AlignOf_RValueRef(type &&, alignment); \
- \
- TEST_AlignOf_impl(type [5], alignment); \
- TEST_AlignOf_impl(type (&) [5], alignment); \
- \
- TEST_AlignOf_impl(AlignmentInStruct<type>, alignment); \
- \
- /* Some internal sanity validation, just for fun */ \
- TEST_AlignOf_impl(AlignmentInStruct<type [5]>, alignment); \
- TEST_AlignOf_impl(AlignmentInStruct<type &>, Q_ALIGNOF(void *)); \
- TEST_AlignOf_impl(AlignmentInStruct<type (&) [5]>, \
- Q_ALIGNOF(void *)); \
- TEST_AlignOf_RValueRef(AlignmentInStruct<type &&>, \
- Q_ALIGNOF(void *)); \
- } while (false) \
- /**/
-
-#ifdef Q_COMPILER_RVALUE_REFS
-#define TEST_AlignOf_RValueRef(type, alignment) \
- TEST_AlignOf_impl(type, alignment)
-#else
-#define TEST_AlignOf_RValueRef(type, alignment) do {} while (false)
-#endif
-
-#define TEST_AlignOf_impl(type, alignment) \
- do { \
- QCOMPARE(Q_ALIGNOF(type), size_t(alignment)); \
- /* Compare to native operator for compilers that support it,
- otherwise... erm... check consistency! :-) */ \
- QCOMPARE(QT_EMULATED_ALIGNOF(type), Q_ALIGNOF(type)); \
- } while (false)
- /**/
-
-void tst_QGlobal::qAlignOf()
-{
- // Built-in types, except 64-bit integers and double
- TEST_AlignOf(char, 1);
- TEST_AlignOf(signed char, 1);
- TEST_AlignOf(unsigned char, 1);
- TEST_AlignOf(qint8, 1);
- TEST_AlignOf(quint8, 1);
- TEST_AlignOf(qint16, 2);
- TEST_AlignOf(quint16, 2);
- TEST_AlignOf(qint32, 4);
- TEST_AlignOf(quint32, 4);
- TEST_AlignOf(void *, sizeof(void *));
-
- // Depends on platform and compiler, disabling test for now
- // TEST_AlignOf(long double, 16);
-
- // Empty struct
- TEST_AlignOf(Empty, 1);
-
- // Function pointers
- TEST_AlignOf(fun, Q_ALIGNOF(void *));
- TEST_AlignOf(memFun, Q_ALIGNOF(void *));
-
-
- // 64-bit integers and double
- TEST_AlignOf_impl(qint64, 8);
- TEST_AlignOf_impl(quint64, 8);
- TEST_AlignOf_impl(double, 8);
-
- TEST_AlignOf_impl(qint64 &, 8);
- TEST_AlignOf_impl(quint64 &, 8);
- TEST_AlignOf_impl(double &, 8);
-
- TEST_AlignOf_RValueRef(qint64 &&, 8);
- TEST_AlignOf_RValueRef(quint64 &&, 8);
- TEST_AlignOf_RValueRef(double &&, 8);
-
- // 32-bit x86 ABI idiosyncrasies
-#if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN)
- TEST_AlignOf_impl(AlignmentInStruct<qint64>, 4);
-#else
- TEST_AlignOf_impl(AlignmentInStruct<qint64>, 8);
-#endif
-
- TEST_AlignOf_impl(AlignmentInStruct<quint64>, Q_ALIGNOF(AlignmentInStruct<qint64>));
- TEST_AlignOf_impl(AlignmentInStruct<double>, Q_ALIGNOF(AlignmentInStruct<qint64>));
-
- // 32-bit x86 ABI, Clang disagrees with gcc
-#if !defined(Q_PROCESSOR_X86_32) || !defined(Q_CC_CLANG)
- TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(qint64));
-#else
- TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(AlignmentInStruct<qint64>));
-#endif
-
- TEST_AlignOf_impl(qint64 (&) [5], Q_ALIGNOF(qint64 [5]));
- TEST_AlignOf_impl(quint64 [5], Q_ALIGNOF(quint64 [5]));
- TEST_AlignOf_impl(quint64 (&) [5], Q_ALIGNOF(quint64 [5]));
- TEST_AlignOf_impl(double [5], Q_ALIGNOF(double [5]));
- TEST_AlignOf_impl(double (&) [5], Q_ALIGNOF(double [5]));
-}
-
-#undef TEST_AlignOf
-#undef TEST_AlignOf_RValueRef
-#undef TEST_AlignOf_impl
-
void tst_QGlobal::integerForSize()
{
// compile-only test:
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<1>::Signed) == 1);
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<2>::Signed) == 2);
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<4>::Signed) == 4);
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<8>::Signed) == 8);
-
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<1>::Unsigned) == 1);
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<2>::Unsigned) == 2);
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<4>::Unsigned) == 4);
- Q_STATIC_ASSERT(sizeof(QIntegerForSize<8>::Unsigned) == 8);
-}
+ static_assert(sizeof(QIntegerForSize<1>::Signed) == 1);
+ static_assert(sizeof(QIntegerForSize<2>::Signed) == 2);
+ static_assert(sizeof(QIntegerForSize<4>::Signed) == 4);
+ static_assert(sizeof(QIntegerForSize<8>::Signed) == 8);
+#ifdef QT_SUPPORTS_INT128
+ static_assert(sizeof(QIntegerForSize<16>::Signed) == 16);
+#endif
-typedef QPair<const char *, const char *> stringpair;
-Q_DECLARE_METATYPE(stringpair)
+ static_assert(sizeof(QIntegerForSize<1>::Unsigned) == 1);
+ static_assert(sizeof(QIntegerForSize<2>::Unsigned) == 2);
+ static_assert(sizeof(QIntegerForSize<4>::Unsigned) == 4);
+ static_assert(sizeof(QIntegerForSize<8>::Unsigned) == 8);
+#ifdef QT_SUPPORTS_INT128
+ static_assert(sizeof(QIntegerForSize<16>::Unsigned) == 16);
+#endif
+}
-void tst_QGlobal::qprintable()
+void tst_QGlobal::int128Literals()
{
- QFETCH(QVector<stringpair>, localestrings);
- QFETCH(int, utf8index);
-
- QVERIFY(utf8index >= 0 && utf8index < localestrings.count());
- if (utf8index < 0 || utf8index >= localestrings.count())
- return;
-
- const char *const utf8string = localestrings.at(utf8index).second;
+#ifdef QT_SUPPORTS_INT128
+#define COMPARE_EQ(lhs, rhs, Expected128) do { \
+ constexpr auto lhs_ = lhs; \
+ static_assert(std::is_same_v<std::remove_cv_t<decltype(lhs_)>, Expected128>); \
+ QCOMPARE_EQ(lhs_, rhs); \
+ } while (0)
+ COMPARE_EQ(Q_INT128_MIN, std::numeric_limits<qint128>::min(), qint128);
+ COMPARE_EQ(Q_INT128_MAX, std::numeric_limits<qint128>::max(), qint128);
+ COMPARE_EQ(Q_UINT128_MAX, std::numeric_limits<quint128>::max(), quint128);
+ QCOMPARE_EQ(tst_qint128_min(), Q_INT128_MIN);
+ QCOMPARE_EQ(tst_qint128_max(), Q_INT128_MAX);
+ QCOMPARE_EQ(tst_quint128_max(), Q_UINT128_MAX);
+ {
+ #define CHECK_S(x) COMPARE_EQ(Q_INT128_C(x), Q_INT64_C(x), qint128)
+ #define CHECK_U(x) COMPARE_EQ(Q_UINT128_C(x), Q_UINT64_C(x), quint128);
+ #define CHECK(x) do { CHECK_S(x); CHECK_U(x); } while (0)
+ // basics:
+ CHECK(0);
+ CHECK(1);
+ CHECK_S(-1);
+ QCOMPARE_EQ(Q_INT64_C(9223372036854775807), std::numeric_limits<qint64>::max());
+ CHECK(9223372036854775807); // LLONG_MAX
+ // Q_INT64_C(-9223372036854775808) gives -Wimplicitly-unsigned-literal on GCC, so use numeric_limits:
+ {
+ constexpr auto i = Q_INT128_C(-9223372036854775808); // LLONG_MIN
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ QCOMPARE_EQ(i, std::numeric_limits<qint64>::min());
+ }
+ // actual 128-bit numbers
+ {
+ constexpr auto i = Q_INT128_C( 9223372036854775808); // LLONG_MAX + 1
+ constexpr auto u = Q_UINT128_C(9223372036854775808); // LLONG_MAX + 1
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ static_assert(std::is_same_v<decltype(u), const quint128>);
+ QCOMPARE_EQ(i, qint128{ std::numeric_limits<qint64>::max()} + 1);
+ QCOMPARE_EQ(u, quint128{std::numeric_limits<qint64>::max()} + 1);
+ }
+ {
+ constexpr auto i = Q_INT128_C(-9223372036854775809); // LLONG_MIN - 1
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ QCOMPARE_EQ(i, qint128{std::numeric_limits<qint64>::min()} - 1);
+ }
+ {
+ constexpr auto i = Q_INT128_C( 18446744073709551616); // ULLONG_MAX + 1
+ constexpr auto u = Q_UINT128_C(18446744073709551616);
+ constexpr auto expected = qint128{1} << 64;
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ static_assert(std::is_same_v<decltype(expected), const qint128>);
+ static_assert(std::is_same_v<decltype(u), const quint128>);
+ QCOMPARE_EQ(i, expected);
+ QCOMPARE_EQ(u, quint128{expected});
+ }
+ {
+ // compilers don't let one write signed _MIN literals, so use MIN + 1:
+ // Q_INT128_C(-170141183460469231731687303715884105728) gives
+ // ERROR: ~~~ outside range of representable values of type qint128
+ // This is because the unary minus is technically speaking not part of
+ // the literal, but called on the result of the literal.
+ constexpr auto i = Q_INT128_C(-170141183460469231731687303715884105727); // 128-bit MIN + 1
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ QCOMPARE_EQ(i, std::numeric_limits<qint128>::min() + 1);
+ }
+ {
+ constexpr auto i = Q_INT128_C( 170141183460469231731687303715884105727); // MAX
+ constexpr auto u = Q_UINT128_C(340282366920938463463374607431768211455); // UMAX
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ static_assert(std::is_same_v<decltype(u), const quint128>);
+ QCOMPARE_EQ(i, std::numeric_limits<qint128>::max());
+ QCOMPARE_EQ(u, std::numeric_limits<quint128>::max());
+ QCOMPARE_EQ(u, Q_UINT128_C(-1));
+ }
- QString string = QString::fromUtf8(utf8string);
+ // binary literals:
+ CHECK(0b0);
+ CHECK(0b1);
+ CHECK_S(-0b1);
+ CHECK(0b01);
+ CHECK(0b10);
+ CHECK(0b1'1); // with digit separator
+ CHECK(0b0111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111);
+ //bytes |---1---| |---2---| |---3---| |---4---| |---5---| |---6---| |---7---| |---8---|
+ {
+ // bytes: |---1---| |---2---| |---3---| |---4---| |---5---| |---6---| |---7---| |---8---| |---9---| |--10---| |--11---| |--12---| |--13---| |--14---| |--15---| |--16---|
+ constexpr auto i = Q_INT128_C( 0b0111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111);
+ constexpr auto u = Q_UINT128_C(0b1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111'1111);
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ static_assert(std::is_same_v<decltype(u), const quint128>);
+ QCOMPARE_EQ(i, std::numeric_limits<qint128>::max());
+ QCOMPARE_EQ(u, std::numeric_limits<quint128>::max());
+ QCOMPARE_EQ(u, Q_UINT128_C(-0b1));
+ }
- for (const stringpair &pair : qAsConst(localestrings)) {
- QTextCodec *codec = QTextCodec::codecForName(pair.first);
- if (!codec)
- continue;
- QTextCodec::setCodecForLocale(codec);
- // test qPrintable()
- QVERIFY(qstrcmp(qPrintable(string), pair.second) == 0);
- for (const stringpair &pair2 : qAsConst(localestrings)) {
- if (pair2.second == pair.second)
- continue;
- QVERIFY(qstrcmp(qPrintable(string), pair2.second) != 0);
+ // octal literals:
+ CHECK(00);
+ CHECK(01);
+ CHECK(02);
+ CHECK(03);
+ CHECK(04);
+ CHECK(05);
+ CHECK(06);
+ CHECK(07);
+ CHECK_S(-01);
+ CHECK(010);
+ CHECK_S(-01'0); // with digit separator
+ CHECK(07'7777'7777'7777'7777'7777); // LLONG_MAX
+ {
+ // bits: 120| 108| 96| 84| 72| 60| 48| 36| 24| 12| 0|
+ constexpr auto i = Q_INT128_C( 0177'7777'7777'7777'7777'7777'7777'7777'7777'7777'7777);
+ constexpr auto u = Q_UINT128_C(0377'7777'7777'7777'7777'7777'7777'7777'7777'7777'7777);
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ static_assert(std::is_same_v<decltype(u), const quint128>);
+ QCOMPARE_EQ(i, std::numeric_limits<qint128>::max());
+ QCOMPARE_EQ(u, std::numeric_limits<quint128>::max());
+ QCOMPARE_EQ(u, Q_UINT128_C(-01));
}
- // test qUtf8Printable()
- QVERIFY(qstrcmp(qUtf8Printable(string), utf8string) == 0);
- for (const stringpair &pair2 : qAsConst(localestrings)) {
- if (qstrcmp(pair2.second, utf8string) == 0)
- continue;
- QVERIFY(qstrcmp(qUtf8Printable(string), pair2.second) != 0);
+
+ // hex literals:
+ CHECK(0x0);
+ CHECK(0x1);
+ CHECK(0x9);
+ CHECK(0xA);
+ CHECK(0xB);
+ CHECK(0xC);
+ CHECK(0xD);
+ CHECK(0xE);
+ CHECK(0x0F);
+ CHECK(0x10);
+ CHECK_S(-0x1);
+ CHECK_S(-0x1'0); // with digit separator
+ CHECK(0x7FFF'FFFF'FFFF'FFFF);
+ {
+ constexpr auto i = Q_INT128_C( 0x7FFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF);
+ constexpr auto u = Q_UINT128_C(0xFFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF'FFFF);
+ static_assert(std::is_same_v<decltype(i), const qint128>);
+ static_assert(std::is_same_v<decltype(u), const quint128>);
+ QCOMPARE_EQ(i, std::numeric_limits<qint128>::max());
+ QCOMPARE_EQ(u, std::numeric_limits<quint128>::max());
+ QCOMPARE_EQ(Q_UINT128_C(-1), u);
}
+ #undef CHECK
}
-
- QTextCodec::setCodecForLocale(0);
+#undef COMPARE_EQ
+#else
+ QSKIP("This test requires 128-bit integer support enabled in the compiler.");
+#endif
}
-void tst_QGlobal::qprintable_data()
-{
- QTest::addColumn<QVector<stringpair> >("localestrings");
- QTest::addColumn<int>("utf8index"); // index of utf8 string
-
- // Unicode: HIRAGANA LETTER A, I, U, E, O (U+3442, U+3444, U+3446, U+3448, U+344a)
- static const char *const utf8string = "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a";
- static const char *const eucjpstring = "\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa";
- static const char *const sjisstring = "\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8";
-
- QVector<stringpair> japanesestrings;
- japanesestrings << stringpair("UTF-8", utf8string)
- << stringpair("EUC-JP", eucjpstring)
- << stringpair("Shift_JIS", sjisstring);
-
- QTest::newRow("Japanese") << japanesestrings << 0;
-
-}
+typedef QPair<const char *, const char *> stringpair;
+Q_DECLARE_METATYPE(stringpair)
void tst_QGlobal::buildAbiEndianness()
{
@@ -651,8 +678,6 @@ void tst_QGlobal::testqOverload()
QVERIFY(QConstOverload<QByteArray>::of(&Overloaded::mixedFoo) ==
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo));
-#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
-
// void returning free overloaded functions
QVERIFY(qOverload<>(&freeOverloaded) ==
static_cast<void (*)()>(&freeOverloaded));
@@ -696,11 +721,216 @@ void tst_QGlobal::testqOverload()
QVERIFY(qConstOverload<QByteArray>(&Overloaded::mixedFoo) ==
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo));
+
+#endif
+}
+
+// enforce that types are identical when comparing
+template<typename T>
+void compare(T a, T b)
+{ QCOMPARE(a, b); }
+
+void tst_QGlobal::testqMinMax()
+{
+ // signed types
+ compare(qMin(float(1), double(-1)), double(-1));
+ compare(qMin(double(1), float(-1)), double(-1));
+ compare(qMin(short(1), int(-1)), int(-1));
+ compare(qMin(short(1), long(-1)), long(-1));
+ compare(qMin(qint64(1), short(-1)), qint64(-1));
+
+ compare(qMax(float(1), double(-1)), double(1));
+ compare(qMax(short(1), long(-1)), long(1));
+ compare(qMax(qint64(1), short(-1)), qint64(1));
+
+ // unsigned types
+ compare(qMin(ushort(1), ulong(2)), ulong(1));
+ compare(qMin(quint64(1), ushort(2)), quint64(1));
+
+ compare(qMax(ushort(1), ulong(2)), ulong(2));
+ compare(qMax(quint64(1), ushort(2)), quint64(2));
+}
+
+void tst_QGlobal::qRoundFloats_data()
+{
+ QTest::addColumn<float>("actual");
+ QTest::addColumn<float>("expected");
+
+ QTest::newRow("round half") << 0.5f << 1.0f;
+ QTest::newRow("round negative half") << -0.5f << -1.0f;
+ QTest::newRow("round negative") << -1.4f << -1.0f;
+ QTest::newRow("round largest representable float less than 0.5") << std::nextafter(0.5f, 0.0f) << 0.0f;
+}
+
+void tst_QGlobal::qRoundFloats() {
+ QFETCH(float, actual);
+ QFETCH(float, expected);
+
+#if !(defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG))
+ QEXPECT_FAIL("round largest representable float less than 0.5",
+ "We know qRound fails in this case, but decided that we value simplicity over correctness",
+ Continue);
#endif
+ QCOMPARE(qRound(actual), expected);
+#if !(defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG))
+ QEXPECT_FAIL("round largest representable float less than 0.5",
+ "We know qRound fails in this case, but decided that we value simplicity over correctness",
+ Continue);
#endif
+ QCOMPARE(qRound64(actual), expected);
}
+void tst_QGlobal::qRoundDoubles_data() {
+ QTest::addColumn<double>("actual");
+ QTest::addColumn<double>("expected");
+
+ QTest::newRow("round half") << 0.5 << 1.0;
+ QTest::newRow("round negative half") << -0.5 << -1.0;
+ QTest::newRow("round negative") << -1.4 << -1.0;
+ QTest::newRow("round largest representable double less than 0.5") << std::nextafter(0.5, 0.0) << 0.0;
+}
+
+void tst_QGlobal::qRoundDoubles() {
+ QFETCH(double, actual);
+ QFETCH(double, expected);
+
+#if !(defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG))
+ QEXPECT_FAIL("round largest representable double less than 0.5",
+ "We know qRound fails in this case, but decided that we value simplicity over correctness",
+ Continue);
+#endif
+ QCOMPARE(qRound(actual), expected);
+
+#if !(defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG))
+ QEXPECT_FAIL("round largest representable double less than 0.5",
+ "We know qRound fails in this case, but decided that we value simplicity over correctness",
+ Continue);
+#endif
+ QCOMPARE(qRound64(actual), expected);
+}
+
+void tst_QGlobal::PRImacros()
+{
+ // none of these calls must generate a -Wformat warning
+ {
+ quintptr p = 123u;
+ QCOMPARE(QString::asprintf("The value %" PRIuQUINTPTR " is nice", p), "The value 123 is nice");
+ QCOMPARE(QString::asprintf("The value %" PRIoQUINTPTR " is nice", p), "The value 173 is nice");
+ QCOMPARE(QString::asprintf("The value %" PRIxQUINTPTR " is nice", p), "The value 7b is nice");
+ QCOMPARE(QString::asprintf("The value %" PRIXQUINTPTR " is nice", p), "The value 7B is nice");
+ }
+
+ {
+ qintptr p = 123;
+ QCOMPARE(QString::asprintf("The value %" PRIdQINTPTR " is nice", p), "The value 123 is nice");
+ QCOMPARE(QString::asprintf("The value %" PRIiQINTPTR " is nice", p), "The value 123 is nice");
+ }
+
+ {
+ qptrdiff d = 123;
+ QCOMPARE(QString::asprintf("The value %" PRIdQPTRDIFF " is nice", d), "The value 123 is nice");
+ QCOMPARE(QString::asprintf("The value %" PRIiQPTRDIFF " is nice", d), "The value 123 is nice");
+ }
+ {
+ qsizetype s = 123;
+ QCOMPARE(QString::asprintf("The value %" PRIdQSIZETYPE " is nice", s), "The value 123 is nice");
+ QCOMPARE(QString::asprintf("The value %" PRIiQSIZETYPE " is nice", s), "The value 123 is nice");
+ }
+}
+
+void tst_QGlobal::testqToUnderlying()
+{
+ enum class E {
+ E1 = 123,
+ E2 = 456,
+ };
+ static_assert(std::is_same_v<decltype(qToUnderlying(E::E1)), int>);
+ QCOMPARE(qToUnderlying(E::E1), 123);
+ QCOMPARE(qToUnderlying(E::E2), 456);
+
+ enum EE : unsigned long {
+ EE1 = 123,
+ EE2 = 456,
+ };
+ static_assert(std::is_same_v<decltype(qToUnderlying(EE1)), unsigned long>);
+ QCOMPARE(qToUnderlying(EE1), 123UL);
+ QCOMPARE(qToUnderlying(EE2), 456UL);
+}
+
+void tst_QGlobal::nodiscard()
+{
+ // Syntax-only test, just to make sure that the Q_NODISCARD_* compile
+ // on all platforms.
+ // Other code is just to silence all various compiler warnings about
+ // unused private members or methods.
+ class Test {
+ public:
+ Q_NODISCARD_CTOR_X("Why construct a Test instead of just passing the int through?")
+ explicit Test(int val) : m_val(val) {}
+ Q_NODISCARD_CTOR explicit Test(float val) : m_val(int(val)) {}
+
+ Q_NODISCARD_X("Why call get() if you don't use the returned value, hu?") // NOT idiomatic use!
+ int get() const { return m_val; }
+
+ private:
+ int m_val;
+ };
+
+ Test t{42};
+ QCOMPARE(t.get(), 42);
+ Test t2{42.0f};
+ QCOMPARE(t2.get(), 42);
+}
+
+QT_BEGIN_NAMESPACE
+
+// Compile-time typeinfo tests
+struct Complex1
+{
+ ~Complex1();
+};
+static_assert(QTypeInfo<Complex1>::isComplex);
+static_assert(!QTypeInfo<Complex1>::isRelocatable);
+
+struct Complex2
+{
+ Complex2(Complex2 &&);
+};
+static_assert(QTypeInfo<Complex2>::isComplex);
+static_assert(!QTypeInfo<Complex2>::isRelocatable);
+
+struct Complex3
+{
+ Complex3(int);
+};
+static_assert(QTypeInfo<Complex3>::isComplex);
+static_assert(QTypeInfo<Complex3>::isRelocatable);
+
+struct Relocatable1
+{
+ ~Relocatable1();
+};
+Q_DECLARE_TYPEINFO(Relocatable1, Q_RELOCATABLE_TYPE);
+static_assert(QTypeInfo<Relocatable1>::isComplex);
+static_assert(QTypeInfo<Relocatable1>::isRelocatable);
+
+struct Relocatable2
+{
+ Relocatable2(int);
+};
+Q_DECLARE_TYPEINFO(Relocatable2, Q_RELOCATABLE_TYPE);
+static_assert(QTypeInfo<Relocatable2>::isComplex);
+static_assert(QTypeInfo<Relocatable2>::isRelocatable);
+
+struct Trivial1
+{
+ int x[42];
+};
+static_assert(!QTypeInfo<Trivial1>::isComplex);
+static_assert(QTypeInfo<Trivial1>::isRelocatable);
+
+QT_END_NAMESPACE
QTEST_APPLESS_MAIN(tst_QGlobal)
#include "tst_qglobal.moc"
diff --git a/tests/auto/corelib/global/qglobalstatic/CMakeLists.txt b/tests/auto/corelib/global/qglobalstatic/CMakeLists.txt
new file mode 100644
index 0000000000..6707e46dff
--- /dev/null
+++ b/tests/auto/corelib/global/qglobalstatic/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qglobalstatic Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qglobalstatic LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qglobalstatic
+ EXCEPTIONS
+ SOURCES
+ tst_qglobalstatic.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro b/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro
deleted file mode 100644
index 21bb040b8d..0000000000
--- a/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-QT += testlib core-private
-
-QT -= gui
-
-TARGET = tst_qglobalstatic
-CONFIG += console
-CONFIG += exceptions
-
-SOURCES += tst_qglobalstatic.cpp
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp
index 2d7db813dd..b8836668f5 100644
--- a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp
+++ b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp
@@ -1,39 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Thiago Macieira <thiago@kde.org>
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Thiago Macieira <thiago@kde.org>
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QThread>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QReadWriteLock>
-#if defined(Q_OS_UNIX)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
#include <sys/resource.h>
#endif
+#include <QtTest/private/qemulationdetector_p.h>
+
class tst_QGlobalStatic : public QObject
{
Q_OBJECT
@@ -53,7 +31,7 @@ private Q_SLOTS:
void tst_QGlobalStatic::initTestCase()
{
-#if defined(Q_OS_UNIX)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
// The tests create a lot of threads, which require file descriptors. On systems like
// OS X low defaults such as 256 as the limit for the number of simultaneously
// open files is not sufficient.
@@ -145,7 +123,7 @@ void tst_QGlobalStatic::exception()
exceptionCaught = true;
}
QVERIFY(exceptionCaught);
- QCOMPARE(Q_QGS_throwingGS::guard.load(), 0);
+ QCOMPARE(QtGlobalStatic::Holder<Q_QGS_throwingGS>::guard.loadRelaxed(), 0);
QVERIFY(!throwingGS.exists());
QVERIFY(!throwingGS.isDestroyed());
}
@@ -154,10 +132,10 @@ QBasicAtomicInt exceptionControlVar = Q_BASIC_ATOMIC_INITIALIZER(1);
Q_GLOBAL_STATIC_WITH_ARGS(ThrowingType, exceptionGS, (exceptionControlVar))
void tst_QGlobalStatic::catchExceptionAndRetry()
{
- if (exceptionControlVar.load() != 1)
+ if (exceptionControlVar.loadRelaxed() != 1)
QSKIP("This test cannot be run more than once");
- ThrowingType::constructedCount.store(0);
- ThrowingType::destructedCount.store(0);
+ ThrowingType::constructedCount.storeRelaxed(0);
+ ThrowingType::destructedCount.storeRelaxed(0);
bool exceptionCaught = false;
try {
@@ -165,11 +143,11 @@ void tst_QGlobalStatic::catchExceptionAndRetry()
} catch (int) {
exceptionCaught = true;
}
- QCOMPARE(ThrowingType::constructedCount.load(), 1);
+ QCOMPARE(ThrowingType::constructedCount.loadRelaxed(), 1);
QVERIFY(exceptionCaught);
exceptionGS();
- QCOMPARE(ThrowingType::constructedCount.load(), 2);
+ QCOMPARE(ThrowingType::constructedCount.loadRelaxed(), 2);
}
QBasicAtomicInt threadStressTestControlVar = Q_BASIC_ATOMIC_INITIALIZER(5);
@@ -178,14 +156,17 @@ Q_GLOBAL_STATIC_WITH_ARGS(ThrowingType, threadStressTestGS, (threadStressTestCon
void tst_QGlobalStatic::threadStressTest()
{
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Frequently hangs on QEMU, QTBUG-91423");
+
class ThreadStressTestThread: public QThread
{
public:
QReadWriteLock *lock;
- void run()
+ void run() override
{
QReadLocker l(lock);
- //usleep(qrand() * 200 / RAND_MAX);
+ //usleep(QRandomGenerator::global()->generate(200));
// thundering herd
try {
threadStressTestGS();
@@ -194,13 +175,19 @@ void tst_QGlobalStatic::threadStressTest()
}
};
- ThrowingType::constructedCount.store(0);
- ThrowingType::destructedCount.store(0);
- int expectedConstructionCount = threadStressTestControlVar.load() + 1;
+ ThrowingType::constructedCount.storeRelaxed(0);
+ ThrowingType::destructedCount.storeRelaxed(0);
+ int expectedConstructionCount = threadStressTestControlVar.loadRelaxed() + 1;
if (expectedConstructionCount <= 0)
QSKIP("This test cannot be run more than once");
+#ifdef Q_OS_INTEGRITY
+ // OPEN_REALTIME_THREADS = 123 on current INTEGRITY environment
+ // if try to create more, app is halted
+ const int numThreads = 122;
+#else
const int numThreads = 200;
+#endif
ThreadStressTestThread threads[numThreads];
QReadWriteLock lock;
lock.lockForWrite();
diff --git a/tests/auto/corelib/global/qhooks/CMakeLists.txt b/tests/auto/corelib/global/qhooks/CMakeLists.txt
new file mode 100644
index 0000000000..2d2051015f
--- /dev/null
+++ b/tests/auto/corelib/global/qhooks/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qhooks Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qhooks LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qhooks
+ SOURCES
+ tst_qhooks.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/global/qhooks/qhooks.pro b/tests/auto/corelib/global/qhooks/qhooks.pro
deleted file mode 100644
index a5c0d63cb9..0000000000
--- a/tests/auto/corelib/global/qhooks/qhooks.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qhooks
-QT = core-private testlib
-SOURCES = tst_qhooks.cpp
diff --git a/tests/auto/corelib/global/qhooks/tst_qhooks.cpp b/tests/auto/corelib/global/qhooks/tst_qhooks.cpp
index 5fa7566e86..efdd9d7da1 100644
--- a/tests/auto/corelib/global/qhooks/tst_qhooks.cpp
+++ b/tests/auto/corelib/global/qhooks/tst_qhooks.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <QtCore/private/qhooks_p.h>
class tst_QHooks: public QObject
@@ -81,7 +56,7 @@ void tst_QHooks::testAddRemoveObject()
QCOMPARE(objectCount, 0);
}
-static QVector<QString> hookOrder;
+static QList<QString> hookOrder;
static QHooks::AddQObjectCallback existingAddHook = 0;
static QHooks::RemoveQObjectCallback existingRemoveHook = 0;
diff --git a/tests/auto/corelib/global/qkeycombination/.gitignore b/tests/auto/corelib/global/qkeycombination/.gitignore
new file mode 100644
index 0000000000..9ce23dd85c
--- /dev/null
+++ b/tests/auto/corelib/global/qkeycombination/.gitignore
@@ -0,0 +1 @@
+tst_qkeycombination
diff --git a/tests/auto/corelib/global/qkeycombination/CMakeLists.txt b/tests/auto/corelib/global/qkeycombination/CMakeLists.txt
new file mode 100644
index 0000000000..911eef7289
--- /dev/null
+++ b/tests/auto/corelib/global/qkeycombination/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qkeycombination Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qkeycombination LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qkeycombination
+ SOURCES
+ tst_qkeycombination.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp b/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp
new file mode 100644
index 0000000000..9941f8e154
--- /dev/null
+++ b/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp
@@ -0,0 +1,279 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QObject>
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+
+class tst_QKeyCombination : public QObject
+{
+ Q_OBJECT
+private slots:
+ void compareCompiles();
+ void construction();
+ void operator_eq();
+ void operator_or();
+};
+
+constexpr int bitwiseOr()
+{
+ return 0;
+}
+
+template <typename ...T>
+constexpr auto bitwiseOr(T ... args)
+{
+ return (... | ((int)args));
+}
+
+void tst_QKeyCombination::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QKeyCombination>();
+}
+
+void tst_QKeyCombination::construction()
+{
+ {
+ QKeyCombination combination;
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers{});
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::Key_unknown));
+ }
+
+ {
+ QKeyCombination combination(Qt::CTRL); // explicit
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::ControlModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::ControlModifier, Qt::Key_unknown));
+ }
+
+ {
+ QKeyCombination combination(Qt::SHIFT); // explicit
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::ShiftModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::ShiftModifier, Qt::Key_unknown));
+ }
+
+ {
+ QKeyCombination combination(Qt::AltModifier); // explicit
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::AltModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::AltModifier, Qt::Key_unknown));
+ }
+
+ {
+ QKeyCombination combination(Qt::AltModifier | Qt::ControlModifier); // explicit
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::AltModifier | Qt::ControlModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::AltModifier, Qt::ControlModifier, Qt::Key_unknown));
+ }
+
+ {
+ QKeyCombination combination = Qt::Key_A; // implicit
+ QCOMPARE(combination.key(), Qt::Key_A);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers{});
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::Key_A));
+ }
+
+ {
+ QKeyCombination combination = Qt::Key_F1; // implicit
+ QCOMPARE(combination.key(), Qt::Key_F1);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers{});
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::Key_F1));
+ }
+
+ {
+ QKeyCombination combination(Qt::SHIFT, Qt::Key_F1);
+ QCOMPARE(combination.key(), Qt::Key_F1);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::ShiftModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::SHIFT, Qt::Key_F1));
+ }
+
+ {
+ QKeyCombination combination(Qt::SHIFT | Qt::CTRL, Qt::Key_F1);
+ QCOMPARE(combination.key(), Qt::Key_F1);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::ShiftModifier | Qt::ControlModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::SHIFT, Qt::CTRL, Qt::Key_F1));
+ }
+
+ {
+ QKeyCombination combination(Qt::AltModifier, Qt::Key_F1);
+ QCOMPARE(combination.key(), Qt::Key_F1);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::AltModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::AltModifier, Qt::Key_F1));
+ }
+
+ // corner cases
+ {
+ QKeyCombination combination = Qt::Key_Alt;
+ QCOMPARE(combination.key(), Qt::Key_Alt);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers{});
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::Key_Alt));
+ }
+
+ {
+ QKeyCombination combination(Qt::ALT, Qt::Key_Alt);
+ QCOMPARE(combination.key(), Qt::Key_Alt);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::AltModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::ALT, Qt::Key_Alt));
+ }
+
+ {
+ QKeyCombination combination(Qt::Key_unknown);
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers{});
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::Key_unknown));
+ }
+
+ {
+ QKeyCombination combination(Qt::CTRL | Qt::SHIFT, Qt::Key_unknown);
+ QCOMPARE(combination.key(), Qt::Key_unknown);
+ QCOMPARE(combination.keyboardModifiers(), Qt::KeyboardModifiers(Qt::ControlModifier | Qt::ShiftModifier));
+ QCOMPARE(combination.toCombined(), bitwiseOr(Qt::CTRL, Qt::SHIFT, Qt::Key_unknown));
+ }
+}
+
+void tst_QKeyCombination::operator_eq()
+{
+ // default
+ {
+ QKeyCombination a, b;
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ // key only
+ {
+ QKeyCombination a;
+ QKeyCombination b(Qt::Key_X);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::Key_Y);
+ QKeyCombination b;
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::Key_Y);
+ QKeyCombination b(Qt::Key_X);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::Key_F1);
+ QKeyCombination b(Qt::Key_F1);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ // modifier only
+ {
+ QKeyCombination a;
+ QKeyCombination b(Qt::CTRL);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::CTRL);
+ QKeyCombination b;
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::CTRL);
+ QKeyCombination b(Qt::SHIFT);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::CTRL);
+ QKeyCombination b(Qt::CTRL);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ {
+ QKeyCombination a(Qt::CTRL);
+ QKeyCombination b(Qt::ControlModifier);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ {
+ QKeyCombination a(Qt::ControlModifier);
+ QKeyCombination b(Qt::CTRL);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ {
+ QKeyCombination a(Qt::ControlModifier);
+ QKeyCombination b(Qt::ControlModifier);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ // key and modifier
+ {
+ QKeyCombination a(Qt::Key_A);
+ QKeyCombination b(Qt::SHIFT, Qt::Key_A);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::CTRL, Qt::Key_A);
+ QKeyCombination b(Qt::SHIFT, Qt::Key_A);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::SHIFT, Qt::Key_A);
+ QKeyCombination b(Qt::SHIFT, Qt::Key_A);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ {
+ QKeyCombination a(Qt::SHIFT, Qt::Key_A);
+ QKeyCombination b(Qt::SHIFT, Qt::Key_Escape);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::SHIFT, Qt::Key_A);
+ QKeyCombination b(Qt::ShiftModifier, Qt::Key_A);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ {
+ QKeyCombination a(Qt::SHIFT | Qt::CTRL, Qt::Key_A);
+ QKeyCombination b(Qt::ControlModifier | Qt::ShiftModifier, Qt::Key_A);
+ QT_TEST_EQUALITY_OPS(a, b, true);
+ }
+
+ // corner cases
+ {
+ QKeyCombination a(Qt::CTRL);
+ QKeyCombination b(Qt::Key_Control);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+
+ {
+ QKeyCombination a(Qt::ALT);
+ QKeyCombination b(Qt::Key_Alt);
+ QT_TEST_EQUALITY_OPS(a, b, false);
+ }
+}
+
+void tst_QKeyCombination::operator_or()
+{
+ // note tha operator+ between enumerators of the same enumeration
+ // yields int, so one can't do
+ // Qt::SHIFT + Qt::CTRL + Qt::Key_A
+ // but one can do
+ // Qt::SHIFT | Qt::CTRL | Qt::Key_A
+
+ QCOMPARE(Qt::SHIFT | Qt::Key_A, QKeyCombination(Qt::SHIFT, Qt::Key_A));
+ QCOMPARE(Qt::AltModifier | Qt::Key_F1, QKeyCombination(Qt::AltModifier, Qt::Key_F1));
+ QCOMPARE(Qt::SHIFT | Qt::ALT | Qt::Key_F1, QKeyCombination(Qt::SHIFT | Qt::ALT, Qt::Key_F1));
+ QCOMPARE(Qt::ControlModifier | Qt::Key_Escape, QKeyCombination(Qt::ControlModifier, Qt::Key_Escape));
+}
+
+QTEST_APPLESS_MAIN(tst_QKeyCombination)
+
+#include "tst_qkeycombination.moc"
diff --git a/tests/auto/corelib/global/qlogging/BLACKLIST b/tests/auto/corelib/global/qlogging/BLACKLIST
index e474064f54..6cd7fc045d 100644
--- a/tests/auto/corelib/global/qlogging/BLACKLIST
+++ b/tests/auto/corelib/global/qlogging/BLACKLIST
@@ -1,7 +1,7 @@
[qMessagePattern:backtrace]
-# QTBUG-63915
-b2qt 64bit
+# QTBUG-121389
+b2qt 32bit
[qMessagePattern:backtrace depth,separator]
-# QTBUG-63915
-b2qt 64bit
+# QTBUG-121389
+b2qt 32bit
diff --git a/tests/auto/corelib/global/qlogging/CMakeLists.txt b/tests/auto/corelib/global/qlogging/CMakeLists.txt
new file mode 100644
index 0000000000..f35c9c4192
--- /dev/null
+++ b/tests/auto/corelib/global/qlogging/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlogging LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_executable(qlogging_helper
+ NO_INSTALL
+ OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ SOURCES app/main.cpp
+ DEFINES QT_MESSAGELOGCONTEXT
+ LIBRARIES Qt::Core)
+
+# Fixes required for the backtrace stack to be correct
+if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND NOT MINGW)
+ target_link_options(qlogging_helper PRIVATE -rdynamic)
+endif()
+set_target_properties(qlogging_helper PROPERTIES CXX_VISIBILITY_PRESET default)
+
+qt_internal_add_test(tst_qlogging SOURCES tst_qlogging.cpp
+ DEFINES
+ QT_MESSAGELOGCONTEXT
+)
+
+add_dependencies(tst_qlogging qlogging_helper)
+
+qt_internal_add_test(tst_qmessagelogger SOURCES tst_qmessagelogger.cpp
+ DEFINES
+ QT_MESSAGELOGCONTEXT
+)
diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro
deleted file mode 100644
index 3ada382ff4..0000000000
--- a/tests/auto/corelib/global/qlogging/app/app.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-TEMPLATE = app
-
-debug_and_release {
- CONFIG(debug, debug|release) {
- TARGET = ../debug/helper
- } else {
- TARGET = ../release/helper
- }
-} else {
- TARGET = ../helper
-}
-
-QT = core
-
-DESTDIR = ./
-
-CONFIG += cmdline
-
-SOURCES += main.cpp
-DEFINES += QT_MESSAGELOGCONTEXT
-
-gcc:!mingw:!haiku {
- QMAKE_LFLAGS += -rdynamic
- contains(QT_ARCH, arm): QMAKE_CXXFLAGS += -funwind-tables -fno-inline
-}
diff --git a/tests/auto/corelib/global/qlogging/app/main.cpp b/tests/auto/corelib/global/qlogging/app/main.cpp
index 4c26bb85e3..e5b669e14f 100644
--- a/tests/auto/corelib/global/qlogging/app/main.cpp
+++ b/tests/auto/corelib/global/qlogging/app/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
#include <QLoggingCategory>
diff --git a/tests/auto/corelib/global/qlogging/qlogging.pro b/tests/auto/corelib/global/qlogging/qlogging.pro
deleted file mode 100644
index bbe75297d5..0000000000
--- a/tests/auto/corelib/global/qlogging/qlogging.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TEMPLATE = subdirs
-
-!winrt {
- test.depends = app
- SUBDIRS += app
-}
-
-SUBDIRS += test
diff --git a/tests/auto/corelib/global/qlogging/test/test.pro b/tests/auto/corelib/global/qlogging/test/test.pro
deleted file mode 100644
index 91896d4494..0000000000
--- a/tests/auto/corelib/global/qlogging/test/test.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-CONFIG += testcase
-qtConfig(c++11): CONFIG += c++11
-qtConfig(c++14): CONFIG += c++14
-debug_and_release {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qlogging
- !android:!winrt: TEST_HELPER_INSTALLS = ../debug/helper
- } else {
- TARGET = ../../release/tst_qlogging
- !android:!winrt: TEST_HELPER_INSTALLS = ../release/helper
- }
-} else {
- TARGET = ../tst_qlogging
- !android:!winrt: TEST_HELPER_INSTALLS = ../helper
-}
-
-QT = core testlib
-SOURCES = ../tst_qlogging.cpp
-
-DEFINES += QT_MESSAGELOGCONTEXT
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
index d3ed1a6d0d..defe3ac421 100644
--- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
+++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
@@ -1,31 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qdebug.h>
#include <qglobal.h>
@@ -33,6 +9,8 @@
# include <QtCore/QProcess>
#endif
#include <QtTest/QTest>
+#include <QList>
+#include <QMap>
class tst_qmessagehandler : public QObject
{
@@ -48,12 +26,12 @@ private slots:
void defaultHandler();
void installMessageHandler();
- void installMsgHandler();
- void installBothHandler();
#ifdef QT_BUILD_INTERNAL
void cleanupFuncinfo_data();
void cleanupFuncinfo();
+ void cleanupFuncinfoBad_data();
+ void cleanupFuncinfoBad();
#endif
void qMessagePattern_data();
@@ -64,7 +42,10 @@ private slots:
void formatLogMessage();
private:
- QStringList m_baseEnvironment;
+ QString backtraceHelperPath();
+#if QT_CONFIG(process)
+ QProcessEnvironment m_baseEnvironment;
+#endif
};
static QtMsgType s_type;
@@ -82,15 +63,6 @@ void customMessageHandler(QtMsgType type, const QMessageLogContext &context, con
s_message = msg;
}
-void customMsgHandler(QtMsgType type, const char *msg)
-{
- s_type = type;
- s_file = 0;
- s_line = 0;
- s_function = 0;
- s_message = QString::fromLocal8Bit(msg);
-}
-
tst_qmessagehandler::tst_qmessagehandler()
{
// ensure it's unset, otherwise we'll have trouble
@@ -100,19 +72,14 @@ tst_qmessagehandler::tst_qmessagehandler()
void tst_qmessagehandler::initTestCase()
{
#if QT_CONFIG(process)
- m_baseEnvironment = QProcess::systemEnvironment();
- for (int i = 0; i < m_baseEnvironment.count(); ++i) {
- if (m_baseEnvironment.at(i).startsWith("QT_MESSAGE_PATTERN=")) {
- m_baseEnvironment.removeAt(i);
- break;
- }
- }
+ m_baseEnvironment = QProcessEnvironment::systemEnvironment();
+ m_baseEnvironment.remove("QT_MESSAGE_PATTERN");
+ m_baseEnvironment.insert("QT_FORCE_STDERR_LOGGING", "1");
#endif // QT_CONFIG(process)
}
void tst_qmessagehandler::cleanup()
{
- qInstallMsgHandler(0);
qInstallMessageHandler((QtMessageHandler)0);
s_type = QtFatalMsg;
s_file = 0;
@@ -143,36 +110,6 @@ void tst_qmessagehandler::installMessageHandler()
QCOMPARE((void*)myHandler, (void*)customMessageHandler);
}
-void tst_qmessagehandler::installMsgHandler()
-{
- QtMsgHandler oldHandler = qInstallMsgHandler(customMsgHandler);
-
- qDebug("installMsgHandler");
-
- QCOMPARE(s_type, QtDebugMsg);
- QCOMPARE(s_message, QString::fromLocal8Bit("installMsgHandler"));
- QCOMPARE(s_file, (const char*)0);
- QCOMPARE(s_function, (const char*)0);
- QCOMPARE(s_line, 0);
-
- QtMsgHandler myHandler = qInstallMsgHandler(oldHandler);
- QCOMPARE((void*)myHandler, (void*)customMsgHandler);
-}
-
-void tst_qmessagehandler::installBothHandler()
-{
- qInstallMessageHandler(customMessageHandler);
- qInstallMsgHandler(customMsgHandler);
-
- qDebug("installBothHandler"); int line = __LINE__;
-
- QCOMPARE(s_type, QtDebugMsg);
- QCOMPARE(s_message, QString::fromLocal8Bit("installBothHandler"));
- QCOMPARE(s_file, __FILE__);
- QCOMPARE(s_function, Q_FUNC_INFO);
- QCOMPARE(s_line, line);
-}
-
# define ADD(x) QTest::newRow(x) << Q_FUNC_INFO << x;
class TestClass1
@@ -194,7 +131,7 @@ public:
char *func_Pchar() { ADD("TestClass1::func_Pchar"); return 0; }
const char *func_KPchar() { ADD("TestClass1::func_KPchar"); return 0; }
const volatile char *func_VKPchar() { ADD("TestClass1::func_VKPchar"); return 0; }
- const volatile unsigned long long * const volatile func_KVPKVull() { ADD("TestClass1::func_KVPKVull"); return 0; }
+ const volatile unsigned long long * func_KVPull() { ADD("TestClass1::func_KVPull"); return 0; }
const void * const volatile *func_KPKVvoid() { ADD("TestClass1::func_KPKVvoid"); return 0; }
QList<int> func_ai() { ADD("TestClass1::func_ai"); return QList<int>(); }
@@ -231,9 +168,13 @@ public:
int operator%(int) { ADD("TestClass1::operator%"); return 0; }
int x;
int &operator++() { ADD("TestClass1::operator++"); return x; }
- int operator++(int) { ADD("TestClass1::operator++"); return 0; }
int &operator--() { ADD("TestClass1::operator--"); return x; }
- int operator--(int) { ADD("TestClass1::operator--"); return 0; }
+
+ // slightly different to avoid duplicate test rows
+#define ADD2(x) QTest::newRow(x ".postfix") << Q_FUNC_INFO << x;
+ int operator++(int) { ADD2("TestClass1::operator++"); return 0; }
+ int operator--(int) { ADD2("TestClass1::operator--"); return 0; }
+#undef ADD2
int nested_struct()
{
@@ -254,19 +195,15 @@ public:
int rvalue() && { ADD("TestClass1::rvalue"); return 0; }
int const_rvalue() const && { ADD("TestClass1::const_rvalue"); return 0; }
#endif
-#ifdef Q_COMPILER_DECLTYPE
int decltype_param(int x = 0, decltype(x) = 0) { ADD("TestClass1::decltype_param"); return x; }
template<typename T> int decltype_template_param(T x = 0, decltype(x) = 0)
{ ADD("TestClass1::decltype_template_param"); return x; }
template<typename T> void decltype_template_param2(T x, decltype(x + QString()))
{ ADD("TestClass1::decltype_template_param2"); }
-# ifdef Q_COMPILER_AUTO_FUNCTION
auto decltype_return(int x = 0) -> decltype(x)
{ ADD("TestClass1::decltype_return"); return x; }
template <typename T> auto decltype_template_return(T x = 0) -> decltype(x)
{ ADD("TestClass1::decltype_template_return"); return x; }
-# endif
-#endif
public:
TestClass1()
@@ -285,7 +222,7 @@ public:
func_Pchar();
func_KPchar();
func_VKPchar();
- func_KVPKVull();
+ func_KVPull();
func_KPKVvoid();
func_ai();
func_aptr();
@@ -323,15 +260,11 @@ public:
std::move(*this).rvalue();
std::move(*this).const_rvalue();
#endif
-#ifdef Q_COMPILER_DECLTYPE
decltype_param();
decltype_template_param(0);
decltype_template_param2(QByteArray(), QString());
-# ifdef Q_COMPILER_AUTO_FUNCTION
decltype_return();
decltype_template_return(0);
-# endif
-#endif
}
};
@@ -496,11 +429,11 @@ void tst_qmessagehandler::cleanupFuncinfo_data()
<< "TestClass1::func_VKPchar";
QTest::newRow("msvc_13")
- << "volatile const unsigned __int64 *volatile const __thiscall TestClass1::func_KVPKVull(void)"
- << "TestClass1::func_KVPKVull";
+ << "volatile const unsigned __int64 *__thiscall TestClass1::func_KVPull(void)"
+ << "TestClass1::func_KVPull";
QTest::newRow("gcc_13")
- << "const volatile long long unsigned int* const volatile TestClass1::func_KVPKVull()"
- << "TestClass1::func_KVPKVull";
+ << "const volatile long long unsigned int* TestClass1::func_KVPull()"
+ << "TestClass1::func_KVPull";
QTest::newRow("msvc_14")
<< "const void *volatile const *__thiscall TestClass1::func_KPKVvoid(void)"
@@ -603,7 +536,7 @@ void tst_qmessagehandler::cleanupFuncinfo_data()
QTest::newRow("msvc_28")
<< "class std::map<long,void const *,struct std::less<long>,class std::allocator<struct std::pair<long const ,void const *> > > *__thiscall TestClass2<class std::map<long,void const *,struct std::less<long>,class std::allocator<struct std::pair<long const ,void const *> > > >::func_template1<class TestClass2<class std::map<long,void const *,struct std::less<long>,class std::allocator<struct std::pair<long const ,void const *> > > >>(void)"
<< "TestClass2::func_template1";
- QTest::newRow("gcc_21")
+ QTest::newRow("gcc_28")
<< "T* TestClass2<T>::func_template1() [with S = TestClass2<std::map<long int, const void*, std::less<long int>, std::allocator<std::pair<const long int, const void*> > > >, T = std::map<long int, const void*, std::less<long int>, std::allocator<std::pair<const long int, const void*> > >]"
<< "TestClass2::func_template1";
@@ -672,6 +605,34 @@ void tst_qmessagehandler::cleanupFuncinfo_data()
<< "int TestClass1::operator>(int)"
<< "TestClass1::operator>";
+ QTest::newRow("gcc_40")
+ << "Polymorphic<void (*)(int)>::~Polymorphic()"
+ << "Polymorphic::~Polymorphic";
+
+ QTest::newRow("gcc_41")
+ << "function<void (int*)>()::S::f()"
+ << "function()::S::f";
+
+ QTest::newRow("msvc_41")
+ << "void `void function<void __cdecl(int *)>(void)'::`2'::S::f(void)"
+ << "function(void)'::`2'::S::f";
+
+ QTest::newRow("gcc_42")
+ << "function<Polymorphic<void (int*)> >()::S::f(Polymorphic<void (int*)>*)"
+ << "function()::S::f";
+
+ QTest::newRow("msvc_42")
+ << "void `void function<Polymorphic<void __cdecl(int *)> >(void)'::`2'::S::f(Polymorphic<void __cdecl(int *)> *)"
+ << "function(void)'::`2'::S::f";
+
+ QTest::newRow("gcc_lambda_1") << "main(int, char**)::<lambda()>"
+ << "main(int, char**)::<lambda()>";
+
+ QTest::newRow("gcc_lambda_with_auto_1")
+ << "SomeClass::someMethod(const QString&, const QString&)::<lambda(auto:57)> [with "
+ "auto:57 = QNetworkReply::NetworkError]"
+ << "SomeClass::someMethod(const QString&, const QString&)::<lambda(auto:57)>";
+
QTest::newRow("objc_1")
<< "-[SomeClass someMethod:withArguments:]"
<< "-[SomeClass someMethod:withArguments:]";
@@ -687,6 +648,14 @@ void tst_qmessagehandler::cleanupFuncinfo_data()
QTest::newRow("objc_4")
<< "__31-[SomeClass someMethodSchedulingBlock]_block_invoke"
<< "__31-[SomeClass someMethodSchedulingBlock]_block_invoke";
+
+ QTest::newRow("thunk-1")
+ << "non-virtual thunk to QFutureWatcherBasePrivate::postCallOutEvent(QFutureCallOutEvent const&)"
+ << "QFutureWatcherBasePrivate::postCallOutEvent";
+
+ QTest::newRow("thunk-2")
+ << "virtual thunk to std::basic_iostream<char, std::char_traits<char> >::~basic_iostream()"
+ << "std::basic_iostream::~basic_iostream";
}
#endif
@@ -707,6 +676,41 @@ void tst_qmessagehandler::cleanupFuncinfo()
QEXPECT_FAIL("TestClass1::nested_struct_const", "Nested function processing is broken", Continue);
QTEST(QString::fromLatin1(result), "expected");
}
+
+void tst_qmessagehandler::cleanupFuncinfoBad_data()
+{
+ QTest::addColumn<QByteArray>("funcinfo");
+
+ auto addBadFrame = [i = 0](const char *symbol) mutable {
+ QTest::addRow("%d", ++i) << QByteArray(symbol);
+ };
+ addBadFrame("typeinfo for QEventLoop");
+ addBadFrame("typeinfo name for QtPrivate::ResultStoreBase");
+ addBadFrame("typeinfo name for ._anon_476");
+ addBadFrame("typeinfo name for std::__1::__function::__base<bool (void*, void*)>");
+ addBadFrame("vtable for BezierEase");
+ addBadFrame("vtable for Polymorphic<void ()>");
+ addBadFrame("vtable for Polymorphic<void (*)(int)>");
+ addBadFrame("TLS wrapper function for (anonymous namespace)::jitStacks");
+ addBadFrame("lcCheckIndex()::category");
+ addBadFrame("guard variable for lcEPDetach()::category");
+ addBadFrame("guard variable for QImageReader::read(QImage*)::disableNxImageLoading");
+ addBadFrame("VTT for std::__1::ostrstream");
+ addBadFrame("qIsRelocatable<(anonymous namespace)::Data>");
+ addBadFrame("qt_incomplete_metaTypeArray<(anonymous namespace)::qt_meta_stringdata_CLASSQNonContiguousByteDeviceIoDeviceImplENDCLASS_t, QtPrivate::TypeAndForceComplete<void, std::integral_constant<bool, true> > >");
+ addBadFrame("f()::i");
+}
+
+void tst_qmessagehandler::cleanupFuncinfoBad()
+{
+ QFETCH(QByteArray, funcinfo);
+
+ // A corrupted stack trace may find non-sensical symbols that aren't
+ // functions. The result doesn't matter, so long as we don't crash or hang.
+
+ QByteArray result = qCleanupFuncinfo(funcinfo);
+ qDebug() << "Decode of" << funcinfo << "produced" << result;
+}
#endif
void tst_qmessagehandler::qMessagePattern_data()
@@ -717,16 +721,16 @@ void tst_qmessagehandler::qMessagePattern_data()
// %{file} is tricky because of shadow builds
QTest::newRow("basic") << "%{type} %{appname} %{line} %{function} %{message}" << true << (QList<QByteArray>()
- << "debug 39 T::T static constructor"
+ << "debug 14 T::T static constructor"
// we can't be sure whether the QT_MESSAGE_PATTERN is already destructed
<< "static destructor"
- << "debug tst_qlogging 60 MyClass::myFunction from_a_function 34"
- << "debug tst_qlogging 70 main qDebug"
- << "info tst_qlogging 71 main qInfo"
- << "warning tst_qlogging 72 main qWarning"
- << "critical tst_qlogging 73 main qCritical"
- << "warning tst_qlogging 76 main qDebug with category"
- << "debug tst_qlogging 80 main qDebug2");
+ << "debug tst_qlogging 35 MyClass::myFunction from_a_function 34"
+ << "debug tst_qlogging 45 main qDebug"
+ << "info tst_qlogging 46 main qInfo"
+ << "warning tst_qlogging 47 main qWarning"
+ << "critical tst_qlogging 48 main qCritical"
+ << "warning tst_qlogging 51 main qDebug with category"
+ << "debug tst_qlogging 55 main qDebug2");
QTest::newRow("invalid") << "PREFIX: %{unknown} %{message}" << false << (QList<QByteArray>()
@@ -769,42 +773,62 @@ void tst_qmessagehandler::qMessagePattern_data()
QTest::qWait(10000);
QTest::newRow("time") << "/%{time yyyy - MM - d}/%{message}"
<< true << (QList<QByteArray>()
- << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toUtf8() + "/qDebug"));
+ << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toLocal8Bit() + "/qDebug"));
QTest::newRow("time-time") << "/%{time yyyy - MM - d}/%{time dd-MM-yy}/%{message}"
<< true << (QList<QByteArray>()
- << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toUtf8()
- + '/' + QDateTime::currentDateTime().toString("dd-MM-yy").toUtf8()
+ << ('/' + QDateTime::currentDateTime().toString("yyyy - MM - d").toLocal8Bit()
+ + '/' + QDateTime::currentDateTime().toString("dd-MM-yy").toLocal8Bit()
+ "/qDebug"));
QTest::newRow("skipped-time-shown-time")
<< "/%{if-warning}%{time yyyy - MM - d}%{endif}%{if-debug}%{time dd-MM-yy}%{endif}/%{message}"
<< true << (QList<QByteArray>()
- << ('/' + QDateTime::currentDateTime().toString("dd-MM-yy").toUtf8() + "/qDebug"));
+ << ('/' + QDateTime::currentDateTime().toString("dd-MM-yy").toLocal8Bit() + "/qDebug"));
// %{time} should have a padding of 6 so if it takes less than 10 seconds to show
// the first message, there should be 5 spaces
QTest::newRow("time-process") << "<%{time process}>%{message}" << true << (QList<QByteArray>()
<< "< ");
-#ifdef __GLIBC__
+#define BACKTRACE_HELPER_NAME "qlogging_helper"
+
#ifdef QT_NAMESPACE
#define QT_NAMESPACE_STR QT_STRINGIFY(QT_NAMESPACE::)
#else
#define QT_NAMESPACE_STR ""
#endif
-#ifndef QT_NO_DEBUG
- QTest::newRow("backtrace") << "[%{backtrace}] %{message}" << true << (QList<QByteArray>()
- // MyClass::qt_static_metacall is explicitly marked as hidden in the Q_OBJECT macro
- << "[MyClass::myFunction|MyClass::mySlot1|?helper?|" QT_NAMESPACE_STR "QMetaMethod::invoke|" QT_NAMESPACE_STR "QMetaObject::invokeMethod] from_a_function 34");
-#endif
+#ifdef __GLIBC__
+# if QT_CONFIG(static)
+ // These test cases don't work with static Qt builds
+# elif !defined(Q_PROCESSOR_X86)
+ // On most RISC platforms, call frames do not have to be stored to the
+ // stack (the return pointer may be saved in any callee-saved register), so
+ // this test isn't reliable.
+# elif defined(QT_ASAN_ENABLED)
+ // These tests produce far more call frames under ASan
+# else
+# ifndef QT_NO_DEBUG
+ QList<QByteArray> expectedBacktrace = {
+ // MyClass::qt_static_metacall is explicitly marked as hidden in the
+ // Q_OBJECT macro hence the ?helper? frame
+ "[MyClass::myFunction|MyClass::mySlot1|?" BACKTRACE_HELPER_NAME "?|",
+
+ // QMetaObject::invokeMethodImpl calls internal function
+ // (QMetaMethodPrivate::invokeImpl, at the time of this writing), which
+ // will usually show only as ?libQt6Core.so? or equivalent, so we skip
+
+ "|" QT_NAMESPACE_STR "QMetaObject::invokeMethodImpl] from_a_function 34"
+ };
+ QTest::newRow("backtrace") << "[%{backtrace}] %{message}" << true << expectedBacktrace;
+# endif
QTest::newRow("backtrace depth,separator") << "[%{backtrace depth=2 separator=\"\n\"}] %{message}" << true << (QList<QByteArray>()
<< "[MyClass::myFunction\nMyClass::mySlot1] from_a_function 34"
<< "[T::T\n");
-#endif
-
+# endif // #if !QT_CONFIG(static)
+#endif // #ifdef __GLIBC__
}
@@ -821,18 +845,14 @@ void tst_qmessagehandler::qMessagePattern()
QFETCH(QList<QByteArray>, expected);
QProcess process;
-#ifndef Q_OS_ANDROID
- const QString appExe(QLatin1String("helper"));
-#else
- const QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/libhelper.so"));
-#endif
+ const QString appExe(backtraceHelperPath());
//
// test QT_MESSAGE_PATTERN
//
- QStringList environment = m_baseEnvironment;
- environment.prepend("QT_MESSAGE_PATTERN=\"" + pattern + QLatin1Char('"'));
- process.setEnvironment(environment);
+ QProcessEnvironment environment = m_baseEnvironment;
+ environment.insert("QT_MESSAGE_PATTERN", pattern);
+ process.setProcessEnvironment(environment);
process.start(appExe);
QVERIFY2(process.waitForStarted(), qPrintable(
@@ -845,15 +865,16 @@ void tst_qmessagehandler::qMessagePattern()
QVERIFY(!output.isEmpty());
QCOMPARE(!output.contains("QT_MESSAGE_PATTERN"), valid);
- for (const QByteArray &e : qAsConst(expected)) {
+ for (const QByteArray &e : std::as_const(expected)) {
if (!output.contains(e)) {
- qDebug() << output;
- qDebug() << "expected: " << e;
- QVERIFY(output.contains(e));
+ // use QDebug so we get proper string escaping for the newlines
+ QString buf;
+ QDebug(&buf) << "Got:" << output << "; Expected:" << e;
+ QVERIFY2(output.contains(e), qPrintable(buf));
}
}
if (pattern.startsWith("%{pid}"))
- QVERIFY2(output.startsWith('"' + pid), "PID: " + pid + "\noutput:\n" + output);
+ QVERIFY2(output.startsWith(pid), "PID: " + pid + "\noutput:\n" + output);
#endif
}
@@ -871,20 +892,10 @@ void tst_qmessagehandler::setMessagePattern()
//
QProcess process;
-#ifndef Q_OS_ANDROID
- const QString appExe(QLatin1String("helper"));
-#else
- const QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/libhelper.so"));
-#endif
+ const QString appExe(backtraceHelperPath());
// make sure there is no QT_MESSAGE_PATTERN in the environment
- QStringList environment = m_baseEnvironment;
- QMutableListIterator<QString> iter(environment);
- while (iter.hasNext()) {
- if (iter.next().startsWith("QT_MESSAGE_PATTERN"))
- iter.remove();
- }
- process.setEnvironment(environment);
+ process.setProcessEnvironment(m_baseEnvironment);
process.start(appExe);
QVERIFY2(process.waitForStarted(), qPrintable(
@@ -944,7 +955,11 @@ void tst_qmessagehandler::formatLogMessage_data()
<< format << "[F] msg"
<< QtFatalMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
QTest::newRow("if_cat")
+#ifndef Q_OS_ANDROID
<< format << "[F] cat: msg"
+#else
+ << format << "[F] : msg"
+#endif
<< QtFatalMsg << BA("") << 0 << BA("func") << BA("cat") << "msg";
}
@@ -966,6 +981,17 @@ void tst_qmessagehandler::formatLogMessage()
QCOMPARE(r, result);
}
+QString tst_qmessagehandler::backtraceHelperPath()
+{
+#ifdef Q_OS_ANDROID
+ QString appExe(QCoreApplication::applicationDirPath()
+ + QLatin1String("/lib" BACKTRACE_HELPER_NAME ".so"));
+#else
+ QString appExe(QCoreApplication::applicationDirPath()
+ + QLatin1String("/" BACKTRACE_HELPER_NAME));
+#endif
+ return appExe;
+}
QTEST_MAIN(tst_qmessagehandler)
#include "tst_qlogging.moc"
diff --git a/tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp b/tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp
new file mode 100644
index 0000000000..9c6b9e275d
--- /dev/null
+++ b/tests/auto/corelib/global/qlogging/tst_qmessagelogger.cpp
@@ -0,0 +1,334 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <qlogging.h>
+#include <qloggingcategory.h>
+#include <QtTest/QTest>
+
+Q_LOGGING_CATEGORY(debugTestCategory, "debug", QtDebugMsg)
+Q_LOGGING_CATEGORY(infoTestCategory, "info", QtInfoMsg)
+Q_LOGGING_CATEGORY(warningTestCategory, "warning", QtWarningMsg)
+Q_LOGGING_CATEGORY(criticalTestCategory, "critical", QtCriticalMsg)
+
+struct LoggerMessageInfo
+{
+ QtMsgType messageType { QtFatalMsg };
+ QString message;
+ const char *file { nullptr };
+ int line { 0 };
+ const char *function { nullptr };
+ const char *category { nullptr };
+};
+
+LoggerMessageInfo messageInfo;
+
+static void customMessageHandler(QtMsgType type, const QMessageLogContext &context,
+ const QString &message)
+{
+ messageInfo.messageType = type;
+ messageInfo.message = message;
+ messageInfo.file = context.file;
+ messageInfo.line = context.line;
+ messageInfo.function = context.function;
+ messageInfo.category = context.category;
+}
+
+class tst_QMessageLogger : public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase_data();
+
+ void init();
+ void cleanup();
+
+ void logMessage();
+ void logMessageWithLoggingCategory();
+ void logMessageWithLoggingCategoryDisabled();
+ void logMessageWithCategoryFunction();
+ void logMessageWithNoDebug();
+
+private:
+ void logWithLoggingCategoryHelper(bool messageTypeEnabled);
+};
+
+void tst_QMessageLogger::initTestCase_data()
+{
+ QTest::addColumn<QtMsgType>("messageType");
+ QTest::addColumn<QByteArray>("categoryName");
+ QTest::addColumn<QByteArray>("messageText");
+ QTest::addColumn<bool>("useDebugStream");
+
+ // not testing QtFatalMsg, as it terminates the application
+ QTest::newRow("debug") << QtDebugMsg << QByteArray("categoryDebug")
+ << QByteArray("debug message") << false;
+ QTest::newRow("info") << QtInfoMsg << QByteArray("categoryInfo") << QByteArray("info message")
+ << false;
+ QTest::newRow("warning") << QtWarningMsg << QByteArray("categoryWarning")
+ << QByteArray("warning message") << false;
+ QTest::newRow("critical") << QtCriticalMsg << QByteArray("categoryCritical")
+ << QByteArray("critical message") << false;
+
+#ifndef QT_NO_DEBUG_STREAM
+ QTest::newRow("stream debug") << QtDebugMsg << QByteArray("categoryDebug")
+ << QByteArray("debug message") << true;
+ QTest::newRow("stream info") << QtInfoMsg << QByteArray("categoryInfo")
+ << QByteArray("info message") << true;
+ QTest::newRow("stream warning") << QtWarningMsg << QByteArray("categoryWarning")
+ << QByteArray("warning message") << true;
+ QTest::newRow("stream critical") << QtCriticalMsg << QByteArray("categoryCritical")
+ << QByteArray("critical message") << true;
+#endif
+}
+
+void tst_QMessageLogger::init()
+{
+ qInstallMessageHandler(customMessageHandler);
+}
+
+void tst_QMessageLogger::cleanup()
+{
+ qInstallMessageHandler((QtMessageHandler)0);
+ messageInfo.messageType = QtFatalMsg;
+ messageInfo.message.clear();
+ messageInfo.file = nullptr;
+ messageInfo.line = 0;
+ messageInfo.function = nullptr;
+ messageInfo.category = nullptr;
+}
+
+void tst_QMessageLogger::logMessage()
+{
+ const int line = QT_MESSAGELOG_LINE;
+ QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC);
+
+ QFETCH_GLOBAL(QtMsgType, messageType);
+ QFETCH_GLOBAL(QByteArray, messageText);
+ QFETCH_GLOBAL(bool, useDebugStream);
+ if (useDebugStream) {
+#ifndef QT_NO_DEBUG_STREAM
+ switch (messageType) {
+ case QtDebugMsg:
+ logger.debug().noquote() << messageText;
+ break;
+ case QtInfoMsg:
+ logger.info().noquote() << messageText;
+ break;
+ case QtWarningMsg:
+ logger.warning().noquote() << messageText;
+ break;
+ case QtCriticalMsg:
+ logger.critical().noquote() << messageText;
+ break;
+ default:
+ QFAIL("Invalid message type");
+ break;
+ }
+#else
+ QSKIP("Qt debug stream disabled");
+#endif
+ } else {
+ switch (messageType) {
+ case QtDebugMsg:
+ logger.debug("%s", messageText.constData());
+ break;
+ case QtInfoMsg:
+ logger.info("%s", messageText.constData());
+ break;
+ case QtWarningMsg:
+ logger.warning("%s", messageText.constData());
+ break;
+ case QtCriticalMsg:
+ logger.critical("%s", messageText.constData());
+ break;
+ default:
+ QFAIL("Invalid message type");
+ break;
+ }
+ }
+
+ QCOMPARE(messageInfo.messageType, messageType);
+ QCOMPARE(messageInfo.message, messageText);
+ QCOMPARE(messageInfo.file, __FILE__);
+ QCOMPARE(messageInfo.line, line);
+ QCOMPARE(messageInfo.function, Q_FUNC_INFO);
+}
+
+void tst_QMessageLogger::logMessageWithLoggingCategory()
+{
+ logWithLoggingCategoryHelper(true);
+}
+
+void tst_QMessageLogger::logMessageWithLoggingCategoryDisabled()
+{
+ logWithLoggingCategoryHelper(false);
+}
+
+void tst_QMessageLogger::logMessageWithCategoryFunction()
+{
+ const int line = QT_MESSAGELOG_LINE;
+ QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC);
+
+ const QLoggingCategory *category = nullptr;
+ QFETCH_GLOBAL(QtMsgType, messageType);
+ QFETCH_GLOBAL(QByteArray, messageText);
+ QFETCH_GLOBAL(bool, useDebugStream);
+ if (useDebugStream) {
+#ifndef QT_NO_DEBUG_STREAM
+ switch (messageType) {
+ case QtDebugMsg:
+ logger.debug(debugTestCategory()).noquote() << messageText;
+ category = &debugTestCategory();
+ break;
+ case QtInfoMsg:
+ logger.info(infoTestCategory()).noquote() << messageText;
+ category = &infoTestCategory();
+ break;
+ case QtWarningMsg:
+ logger.warning(warningTestCategory()).noquote() << messageText;
+ category = &warningTestCategory();
+ break;
+ case QtCriticalMsg:
+ logger.critical(criticalTestCategory()).noquote() << messageText;
+ category = &criticalTestCategory();
+ break;
+ default:
+ QFAIL("Invalid message type");
+ break;
+ }
+#else
+ QSKIP("Qt debug stream disabled");
+#endif
+ } else {
+ switch (messageType) {
+ case QtDebugMsg:
+ logger.debug(debugTestCategory(), "%s", messageText.constData());
+ category = &debugTestCategory();
+ break;
+ case QtInfoMsg:
+ logger.info(infoTestCategory(), "%s", messageText.constData());
+ category = &infoTestCategory();
+ break;
+ case QtWarningMsg:
+ logger.warning(warningTestCategory(), "%s", messageText.constData());
+ category = &warningTestCategory();
+ break;
+ case QtCriticalMsg:
+ logger.critical(criticalTestCategory(), "%s", messageText.constData());
+ category = &criticalTestCategory();
+ break;
+ default:
+ QFAIL("Invalid message type");
+ break;
+ }
+ }
+
+ QCOMPARE(messageInfo.messageType, messageType);
+ QCOMPARE(messageInfo.message, messageText);
+ QCOMPARE(messageInfo.file, __FILE__);
+ QCOMPARE(messageInfo.line, line);
+ QCOMPARE(messageInfo.function, Q_FUNC_INFO);
+ QCOMPARE(messageInfo.category, category->categoryName());
+}
+
+void tst_QMessageLogger::logMessageWithNoDebug()
+{
+ const int line = QT_MESSAGELOG_LINE;
+ QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC);
+
+ QFETCH_GLOBAL(QByteArray, messageText);
+ QFETCH_GLOBAL(bool, useDebugStream);
+ if (useDebugStream) {
+#ifndef QT_NO_DEBUG_STREAM
+ logger.noDebug().noquote() << messageText;
+#else
+ QSKIP("Qt debug stream disabled");
+#endif
+ } else {
+ logger.noDebug("%s", messageText.constData());
+ }
+
+ // the callback was not called
+ QVERIFY(messageInfo.messageType == QtFatalMsg);
+ QVERIFY(messageInfo.message.isEmpty());
+ QVERIFY(messageInfo.file == nullptr);
+ QVERIFY(messageInfo.line == 0);
+ QVERIFY(messageInfo.function == nullptr);
+ QVERIFY(messageInfo.category == nullptr);
+}
+
+void tst_QMessageLogger::logWithLoggingCategoryHelper(bool messageTypeEnabled)
+{
+ QFETCH_GLOBAL(QtMsgType, messageType);
+ QFETCH_GLOBAL(QByteArray, categoryName);
+ QLoggingCategory category(categoryName.constData(), messageType);
+ if (!messageTypeEnabled)
+ category.setEnabled(messageType, false);
+
+ const int line = QT_MESSAGELOG_LINE;
+ QMessageLogger logger(QT_MESSAGELOG_FILE, line, QT_MESSAGELOG_FUNC);
+
+ QFETCH_GLOBAL(QByteArray, messageText);
+ QFETCH_GLOBAL(bool, useDebugStream);
+ if (useDebugStream) {
+#ifndef QT_NO_DEBUG_STREAM
+ switch (messageType) {
+ case QtDebugMsg:
+ logger.debug(category).noquote() << messageText;
+ break;
+ case QtInfoMsg:
+ logger.info(category).noquote() << messageText;
+ break;
+ case QtWarningMsg:
+ logger.warning(category).noquote() << messageText;
+ break;
+ case QtCriticalMsg:
+ logger.critical(category).noquote() << messageText;
+ break;
+ default:
+ QFAIL("Invalid message type");
+ break;
+ }
+#else
+ QSKIP("Qt debug stream disabled");
+#endif
+ } else {
+ switch (messageType) {
+ case QtDebugMsg:
+ logger.debug(category, "%s", messageText.constData());
+ break;
+ case QtInfoMsg:
+ logger.info(category, "%s", messageText.constData());
+ break;
+ case QtWarningMsg:
+ logger.warning(category, "%s", messageText.constData());
+ break;
+ case QtCriticalMsg:
+ logger.critical(category, "%s", messageText.constData());
+ break;
+ default:
+ QFAIL("Invalid message type");
+ break;
+ }
+ }
+
+ if (messageTypeEnabled) {
+ QCOMPARE(messageInfo.messageType, messageType);
+ QCOMPARE(messageInfo.message, messageText);
+ QCOMPARE(messageInfo.file, __FILE__);
+ QCOMPARE(messageInfo.line, line);
+ QCOMPARE(messageInfo.function, Q_FUNC_INFO);
+ QCOMPARE(messageInfo.category, categoryName);
+ } else {
+ // the callback was not called
+ QVERIFY(messageInfo.messageType == QtFatalMsg);
+ QVERIFY(messageInfo.message.isEmpty());
+ QVERIFY(messageInfo.file == nullptr);
+ QVERIFY(messageInfo.line == 0);
+ QVERIFY(messageInfo.function == nullptr);
+ QVERIFY(messageInfo.category == nullptr);
+ }
+}
+
+QTEST_MAIN(tst_QMessageLogger)
+#include "tst_qmessagelogger.moc"
diff --git a/tests/auto/corelib/global/qnativeinterface/CMakeLists.txt b/tests/auto/corelib/global/qnativeinterface/CMakeLists.txt
new file mode 100644
index 0000000000..2c87e07b21
--- /dev/null
+++ b/tests/auto/corelib/global/qnativeinterface/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qnativeinterface LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qnativeinterface
+ SOURCES
+ tst_qnativeinterface.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/global/qnativeinterface/tst_qnativeinterface.cpp b/tests/auto/corelib/global/qnativeinterface/tst_qnativeinterface.cpp
new file mode 100644
index 0000000000..602342770e
--- /dev/null
+++ b/tests/auto/corelib/global/qnativeinterface/tst_qnativeinterface.cpp
@@ -0,0 +1,115 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <QtCore/qnativeinterface.h>
+#include <QtCore/private/qnativeinterface_p.h>
+
+class tst_QNativeInterface: public QObject
+{
+ Q_OBJECT
+private slots:
+ void typeInfo() const;
+ void resolve() const;
+ void accessor() const;
+
+ friend struct PublicClass;
+};
+
+struct InterfaceImplementation;
+
+struct PublicClass
+{
+ PublicClass();
+ QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(PublicClass)
+ std::unique_ptr<InterfaceImplementation> m_implementation;
+
+ friend void tst_QNativeInterface::resolve() const;
+};
+
+QT_BEGIN_NAMESPACE
+namespace QNativeInterface {
+struct Interface
+{
+ QT_DECLARE_NATIVE_INTERFACE(Interface, 10, PublicClass)
+ virtual int foo() = 0;
+};
+
+struct OtherInterface
+{
+ QT_DECLARE_NATIVE_INTERFACE(OtherInterface, 10, PublicClass)
+};
+}
+
+QT_DEFINE_NATIVE_INTERFACE(Interface);
+QT_DEFINE_NATIVE_INTERFACE(OtherInterface);
+QT_END_NAMESPACE
+
+struct NotInterface {};
+
+struct AlmostInterface
+{
+ struct TypeInfo {
+ // Missing required members
+ };
+};
+
+using namespace QNativeInterface;
+
+struct InterfaceImplementation : public Interface
+{
+ int foo() override { return 123; }
+};
+
+PublicClass::PublicClass() : m_implementation(new InterfaceImplementation) {}
+
+void* PublicClass::resolveInterface(char const* name, int revision) const
+{
+ auto *implementation = m_implementation.get();
+ QT_NATIVE_INTERFACE_RETURN_IF(Interface, implementation);
+ QT_NATIVE_INTERFACE_RETURN_IF(OtherInterface, implementation);
+ return nullptr;
+}
+
+void tst_QNativeInterface::typeInfo() const
+{
+ using namespace QNativeInterface::Private;
+
+ QCOMPARE(TypeInfo<Interface>::haveTypeInfo, true);
+ QCOMPARE(TypeInfo<NotInterface>::haveTypeInfo, false);
+ QCOMPARE(TypeInfo<AlmostInterface>::haveTypeInfo, false);
+
+ QCOMPARE(TypeInfo<Interface>::isCompatibleWith<PublicClass>, true);
+ QCOMPARE(TypeInfo<Interface>::isCompatibleWith<QObject>, false);
+ QCOMPARE(TypeInfo<Interface>::isCompatibleWith<int>, false);
+
+ QCOMPARE(TypeInfo<Interface>::revision(), 10);
+ QCOMPARE(TypeInfo<Interface>::name(), "Interface");
+}
+
+void tst_QNativeInterface::resolve() const
+{
+ using namespace QNativeInterface::Private;
+
+ PublicClass foo;
+
+ QVERIFY(foo.resolveInterface("Interface", 10));
+
+ QTest::ignoreMessage(QtWarningMsg, "Native interface revision mismatch "
+ "(requested 5 / available 10) for interface Interface");
+
+ QCOMPARE(foo.resolveInterface("Interface", 5), nullptr);
+ QCOMPARE(foo.resolveInterface("NotInterface", 10), nullptr);
+ QCOMPARE(foo.resolveInterface("OtherInterface", 10), nullptr);
+}
+
+void tst_QNativeInterface::accessor() const
+{
+ PublicClass foo;
+ QVERIFY(foo.nativeInterface<Interface>());
+ QCOMPARE(foo.nativeInterface<Interface>()->foo(), 123);
+}
+
+QTEST_MAIN(tst_QNativeInterface)
+#include "tst_qnativeinterface.moc"
diff --git a/tests/auto/corelib/global/qnumeric/CMakeLists.txt b/tests/auto/corelib/global/qnumeric/CMakeLists.txt
new file mode 100644
index 0000000000..e53a096c92
--- /dev/null
+++ b/tests/auto/corelib/global/qnumeric/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qnumeric Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qnumeric LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qnumeric
+ SOURCES
+ tst_qnumeric.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/global/qnumeric/qnumeric.pro b/tests/auto/corelib/global/qnumeric/qnumeric.pro
deleted file mode 100644
index 188bb5b463..0000000000
--- a/tests/auto/corelib/global/qnumeric/qnumeric.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qnumeric
-QT = core-private testlib
-SOURCES = tst_qnumeric.cpp
-intel_icc: QMAKE_CXXFLAGS += -fp-model strict
-intel_icl: QMAKE_CXXFLAGS += /fp:strict
diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
index 03300c6dbe..d21fabd74e 100644
--- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
+++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
@@ -1,52 +1,79 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <QtGlobal>
#include "private/qnumeric_p.h"
#include <math.h>
#include <float.h>
+namespace {
+ template <typename F> struct Fuzzy {};
+ /* Data taken from qglobal.h's implementation of qFuzzyCompare:
+ * qFuzzyCompare conflates values with fractional difference up to (and
+ * including) the given scale.
+ */
+ template <> struct Fuzzy<double> { constexpr static double scale = 1e12; };
+ template <> struct Fuzzy<float> { constexpr static float scale = 1e5f; };
+}
+
class tst_QNumeric: public QObject
{
Q_OBJECT
+ // Support for floating-point:
+ template<typename F> inline void fuzzyCompare_data();
+ template<typename F> inline void fuzzyCompare();
+ template<typename F> inline void fuzzyIsNull_data();
+ template<typename F> inline void fuzzyIsNull();
+ template<typename F> inline void checkNaN(F nan);
+ template<typename F> inline void rawNaN_data();
+ template<typename F> inline void rawNaN();
+#if QT_CONFIG(signaling_nan)
+ template<typename F> inline void distinctNaN();
+#endif
+ template<typename F, typename Whole> inline void generalNaN_data();
+ template<typename F, typename Whole> inline void generalNaN();
+ template<typename F> inline void infinity();
+ template<typename F> inline void classifyfp();
+ template<typename F, typename Count> inline void distance_data();
+ template<typename F, typename Count> inline void distance();
+
private slots:
- void fuzzyCompare_data();
- void fuzzyCompare();
- void qNan();
- void floatDistance_data();
- void floatDistance();
- void floatDistance_double_data();
- void floatDistance_double();
+ // Floating-point tests:
+ void fuzzyCompareF_data() { fuzzyCompare_data<float>(); }
+ void fuzzyCompareF() { fuzzyCompare<float>(); }
+ void fuzzyCompareD_data() { fuzzyCompare_data<double>(); }
+ void fuzzyCompareD() { fuzzyCompare<double>(); }
+ void fuzzyIsNullF_data() { fuzzyIsNull_data<float>(); }
+ void fuzzyIsNullF() { fuzzyIsNull<float>(); }
+ void fuzzyIsNullD_data() { fuzzyIsNull_data<double>(); }
+ void fuzzyIsNullD() { fuzzyIsNull<double>(); }
+ void rawNaNF_data() { rawNaN_data<float>(); }
+ void rawNaNF() { rawNaN<float>(); }
+ void rawNaND_data() { rawNaN_data<double>(); }
+ void rawNaND() { rawNaN<double>(); }
+#if QT_CONFIG(signaling_nan)
+ void distinctNaNF();
+ void distinctNaND() { distinctNaN<double>(); }
+#endif
+ void generalNaNd_data() { generalNaN_data<double, quint64>(); }
+ void generalNaNd() { generalNaN<double, quint64>(); }
+ void generalNaNf_data() { generalNaN_data<float, quint32>(); }
+ void generalNaNf() { generalNaN<float, quint32>(); }
+ void infinityF() { infinity<float>(); }
+ void infinityD() { infinity<double>(); }
+ void classifyF() { classifyfp<float>(); }
+ void classifyD() { classifyfp<double>(); }
+ void floatDistance_data() { distance_data<float, quint32>(); }
+ void floatDistance() { distance<float, quint32>(); }
+ void doubleDistance_data() { distance_data<double, quint64>(); }
+ void doubleDistance() { distance<double, quint64>(); }
+
+ // Whole number tests:
void addOverflow_data();
void addOverflow();
void mulOverflow_data();
@@ -54,30 +81,41 @@ private slots:
void signedOverflow();
};
+// Floating-point tests:
+
+template<typename F>
void tst_QNumeric::fuzzyCompare_data()
{
- QTest::addColumn<double>("val1");
- QTest::addColumn<double>("val2");
+ QTest::addColumn<F>("val1");
+ QTest::addColumn<F>("val2");
QTest::addColumn<bool>("isEqual");
-
- QTest::newRow("zero") << 0.0 << 0.0 << true;
- QTest::newRow("ten") << 10.0 << 10.0 << true;
- QTest::newRow("large") << 1000000000.0 << 1000000000.0 << true;
- QTest::newRow("small") << 0.00000000001 << 0.00000000001 << true;
- QTest::newRow("eps") << 10.000000000000001 << 10.00000000000002 << true;
- QTest::newRow("eps2") << 10.000000000000001 << 10.000000000000009 << true;
-
- QTest::newRow("mis1") << 0.0 << 1.0 << false;
- QTest::newRow("mis2") << 0.0 << 10000000.0 << false;
- QTest::newRow("mis3") << 0.0 << 0.000000001 << false;
- QTest::newRow("mis4") << 100000000.0 << 0.000000001 << false;
- QTest::newRow("mis5") << 0.0000000001 << 0.000000001 << false;
+ const F zero(0), one(1), ten(10);
+ const F huge = Fuzzy<F>::scale, tiny = one / huge;
+ const F deci(.1f), giga(1e9f), nano(1e-9f), big(1e7f), small(1e-10f);
+
+ QTest::newRow("zero") << zero << zero << true;
+ QTest::newRow("ten") << ten << ten << true;
+ QTest::newRow("large") << giga << giga << true;
+ QTest::newRow("small") << small << small << true;
+ QTest::newRow("10+9*tiny==10") << (ten + 9 * tiny) << ten << true;
+ QTest::newRow("huge+.9==huge") << (huge + 9 * deci) << huge << true;
+ QTest::newRow("eps2") << (ten + tiny) << (ten + 2 * tiny) << true;
+ QTest::newRow("eps9") << (ten + tiny) << (ten + 9 * tiny) << true;
+
+ QTest::newRow("0!=1") << zero << one << false;
+ QTest::newRow("0!=big") << zero << big << false;
+ QTest::newRow("0!=nano") << zero << nano << false;
+ QTest::newRow("giga!=nano") << giga << nano << false;
+ QTest::newRow("small!=nano") << small << nano << false;
+ QTest::newRow("huge+1.1!=huge") << (huge + 1 + deci) << huge << false;
+ QTest::newRow("1+1.1*tiny!=1") << (one + tiny * (one + deci)) << one << false;
}
+template<typename F>
void tst_QNumeric::fuzzyCompare()
{
- QFETCH(double, val1);
- QFETCH(double, val2);
+ QFETCH(F, val1);
+ QFETCH(F, val2);
QFETCH(bool, isEqual);
QCOMPARE(::qFuzzyCompare(val1, val2), isEqual);
@@ -86,140 +124,287 @@ void tst_QNumeric::fuzzyCompare()
QCOMPARE(::qFuzzyCompare(-val2, -val1), isEqual);
}
+template<typename F>
+void tst_QNumeric::fuzzyIsNull_data()
+{
+ QTest::addColumn<F>("value");
+ QTest::addColumn<bool>("isNull");
+ using Bounds = std::numeric_limits<F>;
+ const F one(1), huge = Fuzzy<F>::scale, tiny = one / huge;
+
+ QTest::newRow("zero") << F(0) << true;
+ QTest::newRow("min") << Bounds::min() << true;
+ QTest::newRow("denorm_min") << Bounds::denorm_min() << true;
+ QTest::newRow("tiny") << tiny << true;
+
+ QTest::newRow("deci") << F(.1) << false;
+ QTest::newRow("one") << one << false;
+ QTest::newRow("ten") << F(10) << false;
+ QTest::newRow("large") << F(1e9) << false;
+ QTest::newRow("huge") << huge << false;
+}
+
+template<typename F>
+void tst_QNumeric::fuzzyIsNull()
+{
+ QFETCH(F, value);
+ QFETCH(bool, isNull);
+
+ QCOMPARE(::qFuzzyIsNull(value), isNull);
+ QCOMPARE(::qFuzzyIsNull(-value), isNull);
+}
+
+static void clearFpExceptions()
+{
+ // Call after any functions that exercise floating-point exceptions, such as
+ // sqrt(-1) or log(0).
+#ifdef Q_OS_WIN
+ _clearfp();
+#endif
+}
+
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
// turn -ffast-math off
# pragma GCC optimize "no-fast-math"
#endif
-void tst_QNumeric::qNan()
+template<typename F>
+void tst_QNumeric::checkNaN(F nan)
+{
+ const auto cleanup = qScopeGuard([]() { clearFpExceptions(); });
+#define CHECKNAN(value) \
+ do { \
+ const F v = (value); \
+ QCOMPARE(qFpClassify(v), FP_NAN); \
+ QVERIFY(qIsNaN(v)); \
+ QVERIFY(!qIsFinite(v)); \
+ QVERIFY(!qIsInf(v)); \
+ } while (0)
+ const F zero(0), one(1), two(2);
+
+ QVERIFY(!(zero > nan));
+ QVERIFY(!(zero < nan));
+ QVERIFY(!(zero == nan));
+ QVERIFY(!(nan == nan));
+
+ CHECKNAN(nan);
+ CHECKNAN(nan + one);
+ CHECKNAN(nan - one);
+ CHECKNAN(-nan);
+ CHECKNAN(nan * two);
+ CHECKNAN(nan / two);
+ CHECKNAN(one / nan);
+ CHECKNAN(zero / nan);
+ CHECKNAN(zero * nan);
+ CHECKNAN(sqrt(-one));
+
+ // When any NaN is expected, any NaN will do:
+ QCOMPARE(nan, nan);
+ QCOMPARE(nan, -nan);
+ QCOMPARE(nan, qQNaN());
+#undef CHECKNAN
+}
+
+template<typename F>
+void tst_QNumeric::rawNaN_data()
{
#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404)
QSKIP("Non-conformant fast math mode is enabled, cannot run test");
#endif
- double nan = qQNaN();
- QVERIFY(!(0 > nan));
- QVERIFY(!(0 < nan));
- QVERIFY(qIsNaN(nan));
- QVERIFY(qIsNaN(nan + 1));
- QVERIFY(qIsNaN(-nan));
-
- Q_STATIC_ASSERT(sizeof(double) == 8);
-#ifdef Q_LITTLE_ENDIAN
- const uchar bytes[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f };
-#else
- const uchar bytes[] = { 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
+ QTest::addColumn<F>("nan");
+
+ QTest::newRow("quiet") << F(qQNaN());
+#if QT_CONFIG(signaling_nan)
+ QTest::newRow("signaling") << F(qSNaN());
#endif
- memcpy(&nan, bytes, 8);
- QVERIFY(!qIsFinite(nan));
- QVERIFY(!qIsInf(nan));
- QVERIFY(qIsNaN(nan));
-
- double inf = qInf();
- QVERIFY(inf > 0);
- QVERIFY(-inf < 0);
- QVERIFY(qIsInf(inf));
- QVERIFY(qIsInf(-inf));
- QVERIFY(qIsInf(2*inf));
- QCOMPARE(1/inf, 0.0);
- QVERIFY(qIsNaN(0*nan));
- QVERIFY(qIsNaN(0*inf));
- QVERIFY(qFuzzyCompare(1/inf, 0.0));
}
-void tst_QNumeric::floatDistance_data()
+template<typename F>
+void tst_QNumeric::rawNaN()
{
- QTest::addColumn<float>("val1");
- QTest::addColumn<float>("val2");
- QTest::addColumn<quint32>("expectedDistance");
+ QFETCH(F, nan);
+#ifdef Q_OS_WASM
+# ifdef __asmjs
+ QEXPECT_FAIL("", "Fastcomp conflates quiet and signaling NaNs", Continue);
+# endif // but the modern clang compiler handls it fine.
+#endif
+ checkNaN(nan);
+}
- // exponent: 8 bits
- // mantissa: 23 bits
- const quint32 number_of_denormals = (1 << 23) - 1; // Set to 0 if denormals are not included
+#if QT_CONFIG(signaling_nan)
+template<typename F>
+void tst_QNumeric::distinctNaN()
+{
+ const F qnan = qQNaN();
+ const F snan = qSNaN();
+ QVERIFY(memcmp(&qnan, &snan, sizeof(F)) != 0);
+}
- quint32 _0_to_1 = quint32((1 << 23) * 126 + 1 + number_of_denormals); // We need +1 to include the 0
- quint32 _1_to_2 = quint32(1 << 23);
+void tst_QNumeric::distinctNaNF() {
+#ifdef Q_CC_MSVC
+ QEXPECT_FAIL("", "MSVC's float conflates quiet and signaling NaNs", Continue);
+#endif
+ distinctNaN<float>();
+}
+#endif // signaling_nan
- // We don't need +1 because FLT_MAX has all bits set in the mantissa. (Thus mantissa
- // have not wrapped back to 0, which would be the case for 1 in _0_to_1
- quint32 _0_to_FLT_MAX = quint32((1 << 23) * 254) + number_of_denormals;
-
- quint32 _0_to_FLT_MIN = 1 + number_of_denormals;
- QTest::newRow("[0,FLT_MIN]") << 0.F << FLT_MIN << _0_to_FLT_MIN;
- QTest::newRow("[0,FLT_MAX]") << 0.F << FLT_MAX << _0_to_FLT_MAX;
- QTest::newRow("[1,1.5]") << 1.0F << 1.5F << quint32(1 << 22);
- QTest::newRow("[0,1]") << 0.F << 1.0F << _0_to_1;
- QTest::newRow("[0.5,1]") << 0.5F << 1.0F << quint32(1 << 23);
- QTest::newRow("[1,2]") << 1.F << 2.0F << _1_to_2;
- QTest::newRow("[-1,+1]") << -1.F << +1.0F << 2 * _0_to_1;
- QTest::newRow("[-1,0]") << -1.F << 0.0F << _0_to_1;
- QTest::newRow("[-1,FLT_MAX]") << -1.F << FLT_MAX << _0_to_1 + _0_to_FLT_MAX;
- QTest::newRow("[-2,-1") << -2.F << -1.F << _1_to_2;
- QTest::newRow("[-1,-2") << -1.F << -2.F << _1_to_2;
- QTest::newRow("[FLT_MIN,FLT_MAX]") << FLT_MIN << FLT_MAX << _0_to_FLT_MAX - _0_to_FLT_MIN;
- QTest::newRow("[-FLT_MAX,FLT_MAX]") << -FLT_MAX << FLT_MAX << (2*_0_to_FLT_MAX);
- float denormal = FLT_MIN;
- denormal/=2.0F;
- QTest::newRow("denormal") << 0.F << denormal << _0_to_FLT_MIN/2;
+template<typename F, typename Whole>
+void tst_QNumeric::generalNaN_data()
+{
+ static_assert(sizeof(F) == sizeof(Whole));
+ QTest::addColumn<Whole>("whole");
+ // Every value with every bit of the exponent set is a NaN.
+ // Sign and mantissa can be anything without interfering with that.
+ using Bounds = std::numeric_limits<F>;
+ // Bounds::digits is one more than the number of bits used to encode the mantissa:
+ const int mantissaBits = Bounds::digits - 1;
+ // One bit for sign, the rest are mantissa and exponent:
+ const int exponentBits = sizeof(F) * CHAR_BIT - 1 - mantissaBits;
+
+ const Whole exponent = ((Whole(1) << exponentBits) - 1) << mantissaBits;
+ const Whole sign = Whole(1) << (exponentBits + mantissaBits);
+ const Whole mantissaTop = Whole(1) << (mantissaBits - 1);
+
+ QTest::newRow("lowload") << (exponent | 1);
+ QTest::newRow("sign-lowload") << (sign | exponent | 1);
+ QTest::newRow("highload") << (exponent | mantissaTop);
+ QTest::newRow("sign-highload") << (sign | exponent | mantissaTop);
}
-void tst_QNumeric::floatDistance()
+template<typename F, typename Whole>
+void tst_QNumeric::generalNaN()
{
- QFETCH(float, val1);
- QFETCH(float, val2);
- QFETCH(quint32, expectedDistance);
-#ifdef Q_OS_QNX
- QEXPECT_FAIL("denormal", "See QTBUG-37094", Continue);
-#endif
- QCOMPARE(qFloatDistance(val1, val2), expectedDistance);
+ static_assert(sizeof(F) == sizeof(Whole));
+ QFETCH(const Whole, whole);
+ F nan;
+ memcpy(&nan, &whole, sizeof(F));
+ checkNaN(nan);
+}
+
+template<typename F>
+void tst_QNumeric::infinity()
+{
+ const auto cleanup = qScopeGuard([]() { clearFpExceptions(); });
+ const F inf = qInf();
+ const F zero(0), one(1), two(2);
+ QVERIFY(inf > zero);
+ QVERIFY(-inf < zero);
+ QVERIFY(qIsInf(inf));
+ QCOMPARE(inf, inf);
+ QCOMPARE(-inf, -inf);
+ QVERIFY(qIsInf(-inf));
+ QVERIFY(qIsInf(inf + one));
+ QVERIFY(qIsInf(inf - one));
+ QVERIFY(qIsInf(-inf - one));
+ QVERIFY(qIsInf(-inf + one));
+ QVERIFY(qIsInf(inf * two));
+ QVERIFY(qIsInf(-inf * two));
+ QVERIFY(qIsInf(inf / two));
+ QVERIFY(qIsInf(-inf / two));
+ QVERIFY(qFuzzyCompare(one / inf, zero));
+ QCOMPARE(1.0 / inf, 0.0);
+ QVERIFY(qFuzzyCompare(one / -inf, zero));
+ QCOMPARE(one / -inf, zero);
+ QVERIFY(qIsNaN(zero * inf));
+ QVERIFY(qIsNaN(zero * -inf));
+ QCOMPARE(log(zero), -inf);
+}
+
+template<typename F>
+void tst_QNumeric::classifyfp()
+{
+ using Bounds = std::numeric_limits<F>;
+ const F huge = Bounds::max();
+ const F tiny = Bounds::min();
+ // NaNs already handled, see checkNaN()'s callers.
+ const F one(1), two(2), inf(qInf());
+
+ QCOMPARE(qFpClassify(inf), FP_INFINITE);
+ QCOMPARE(qFpClassify(-inf), FP_INFINITE);
+ QT_WARNING_PUSH;
+ QT_WARNING_DISABLE_MSVC(4056);
+ QCOMPARE(qFpClassify(huge * two), FP_INFINITE);
+ QCOMPARE(qFpClassify(huge * -two), FP_INFINITE);
+ QT_WARNING_POP;
+
+ QCOMPARE(qFpClassify(one), FP_NORMAL);
+ QCOMPARE(qFpClassify(huge), FP_NORMAL);
+ QCOMPARE(qFpClassify(-huge), FP_NORMAL);
+ QCOMPARE(qFpClassify(tiny), FP_NORMAL);
+ QCOMPARE(qFpClassify(-tiny), FP_NORMAL);
+ if (Bounds::has_denorm == std::denorm_present) {
+ QCOMPARE(qFpClassify(tiny / two), FP_SUBNORMAL);
+ QCOMPARE(qFpClassify(tiny / -two), FP_SUBNORMAL);
+ }
}
-void tst_QNumeric::floatDistance_double_data()
+template<typename F, typename Count>
+void tst_QNumeric::distance_data()
{
- QTest::addColumn<double>("val1");
- QTest::addColumn<double>("val2");
- QTest::addColumn<quint64>("expectedDistance");
+ using Bounds = std::numeric_limits<F>;
+ const F huge = Bounds::max();
+ const F tiny = Bounds::min();
- // exponent: 11 bits
- // mantissa: 52 bits
- const quint64 number_of_denormals = (Q_UINT64_C(1) << 52) - 1; // Set to 0 if denormals are not included
+ QTest::addColumn<F>("from");
+ QTest::addColumn<F>("stop");
+ QTest::addColumn<Count>("expectedDistance");
- quint64 _0_to_1 = (Q_UINT64_C(1) << 52) * ((1 << (11-1)) - 2) + 1 + number_of_denormals; // We need +1 to include the 0
- quint64 _1_to_2 = Q_UINT64_C(1) << 52;
+ using Bounds = std::numeric_limits<F>;
+ const int mantissaBits = Bounds::digits - 1;
+ const int exponentBits = sizeof(F) * CHAR_BIT - 1 - mantissaBits;
- // We don't need +1 because DBL_MAX has all bits set in the mantissa. (Thus mantissa
+ // Set to 1 and 0 if denormals are not included:
+ const Count count_0_to_tiny = Count(1) << mantissaBits;
+ const Count count_denormals = count_0_to_tiny - 1;
+
+ // We need +1 to include the 0:
+ const Count count_0_to_1
+ = (Count(1) << mantissaBits) * ((Count(1) << (exponentBits - 1)) - 2)
+ + 1 + count_denormals;
+ const Count count_1_to_2 = Count(1) << mantissaBits;
+
+ // We don't need +1 because huge has all bits set in the mantissa. (Thus mantissa
// have not wrapped back to 0, which would be the case for 1 in _0_to_1
- quint64 _0_to_DBL_MAX = quint64((Q_UINT64_C(1) << 52) * ((1 << 11) - 2)) + number_of_denormals;
-
- quint64 _0_to_DBL_MIN = 1 + number_of_denormals;
- QTest::newRow("[0,DBL_MIN]") << 0.0 << DBL_MIN << _0_to_DBL_MIN;
- QTest::newRow("[0,DBL_MAX]") << 0.0 << DBL_MAX << _0_to_DBL_MAX;
- QTest::newRow("[1,1.5]") << 1.0 << 1.5 << (Q_UINT64_C(1) << 51);
- QTest::newRow("[0,1]") << 0.0 << 1.0 << _0_to_1;
- QTest::newRow("[0.5,1]") << 0.5 << 1.0 << (Q_UINT64_C(1) << 52);
- QTest::newRow("[1,2]") << 1.0 << 2.0 << _1_to_2;
- QTest::newRow("[-1,+1]") << -1.0 << +1.0 << 2 * _0_to_1;
- QTest::newRow("[-1,0]") << -1.0 << 0.0 << _0_to_1;
- QTest::newRow("[-1,DBL_MAX]") << -1.0 << DBL_MAX << _0_to_1 + _0_to_DBL_MAX;
- QTest::newRow("[-2,-1") << -2.0 << -1.0 << _1_to_2;
- QTest::newRow("[-1,-2") << -1.0 << -2.0 << _1_to_2;
- QTest::newRow("[DBL_MIN,DBL_MAX]") << DBL_MIN << DBL_MAX << _0_to_DBL_MAX - _0_to_DBL_MIN;
- QTest::newRow("[-DBL_MAX,DBL_MAX]") << -DBL_MAX << DBL_MAX << (2*_0_to_DBL_MAX);
- double denormal = DBL_MIN;
- denormal/=2.0;
- QTest::newRow("denormal") << 0.0 << denormal << _0_to_DBL_MIN/2;
+ const Count count_0_to_huge
+ = (Count(1) << mantissaBits) * ((Count(1) << exponentBits) - 2)
+ + count_denormals;
+
+ const F zero(0), half(.5), one(1), sesqui(1.5), two(2);
+ const F denormal = tiny / two;
+
+ QTest::newRow("[0,tiny]") << zero << tiny << count_0_to_tiny;
+ QTest::newRow("[0,huge]") << zero << huge << count_0_to_huge;
+ QTest::newRow("[1,1.5]") << one << sesqui << (Count(1) << (mantissaBits - 1));
+ QTest::newRow("[0,1]") << zero << one << count_0_to_1;
+ QTest::newRow("[0.5,1]") << half << one << (Count(1) << mantissaBits);
+ QTest::newRow("[1,2]") << one << two << count_1_to_2;
+ QTest::newRow("[-1,+1]") << -one << +one << 2 * count_0_to_1;
+ QTest::newRow("[-1,0]") << -one << zero << count_0_to_1;
+ QTest::newRow("[-1,huge]") << -one << huge << count_0_to_1 + count_0_to_huge;
+ QTest::newRow("[-2,-1") << -two << -one << count_1_to_2;
+ QTest::newRow("[-1,-2") << -one << -two << count_1_to_2;
+ QTest::newRow("[tiny,huge]") << tiny << huge << count_0_to_huge - count_0_to_tiny;
+ QTest::newRow("[-huge,huge]") << -huge << huge << (2 * count_0_to_huge);
+ QTest::newRow("denormal") << zero << denormal << count_0_to_tiny / 2;
}
-void tst_QNumeric::floatDistance_double()
+template<typename F, typename Count>
+void tst_QNumeric::distance()
{
- QFETCH(double, val1);
- QFETCH(double, val2);
- QFETCH(quint64, expectedDistance);
-#ifdef Q_OS_QNX
- QEXPECT_FAIL("denormal", "See QTBUG-37094", Continue);
-#endif
- QCOMPARE(qFloatDistance(val1, val2), expectedDistance);
+ QFETCH(F, from);
+ QFETCH(F, stop);
+ QFETCH(Count, expectedDistance);
+ if constexpr (std::numeric_limits<F>::has_denorm != std::denorm_present) {
+ if (qstrcmp(QTest::currentDataTag(), "denormal") == 0) {
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+ }
+ QCOMPARE(qFloatDistance(from, stop), expectedDistance);
+ QCOMPARE(qFloatDistance(stop, from), expectedDistance);
}
+// Whole number tests:
+
void tst_QNumeric::addOverflow_data()
{
QTest::addColumn<int>("size");
@@ -246,119 +431,138 @@ template <typename Int> static void addOverflow_template()
#if defined(Q_CC_MSVC) && Q_CC_MSVC < 2000
QSKIP("Test disabled, this test generates an Internal Compiler Error compiling in release mode");
#else
- const Int max = std::numeric_limits<Int>::max();
- const Int min = std::numeric_limits<Int>::min();
+ constexpr Int max = std::numeric_limits<Int>::max();
+ constexpr Int min = std::numeric_limits<Int>::min();
Int r;
+#define ADD_COMPARE_NONOVF(v1, v2, expected) \
+ do { \
+ QCOMPARE(qAddOverflow(Int(v1), Int(v2), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ QCOMPARE(qAddOverflow(Int(v1), (std::integral_constant<Int, Int(v2)>()), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ QCOMPARE(qAddOverflow<v2>(Int(v1), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ } while (false)
+#define ADD_COMPARE_OVF(v1, v2) \
+ do { \
+ QCOMPARE(qAddOverflow(Int(v1), Int(v2), &r), true); \
+ QCOMPARE(qAddOverflow(Int(v1), (std::integral_constant<Int, Int(v2)>()), &r), true); \
+ QCOMPARE(qAddOverflow<v2>(Int(v1), &r), true); \
+ } while (false)
+#define SUB_COMPARE_NONOVF(v1, v2, expected) \
+ do { \
+ QCOMPARE(qSubOverflow(Int(v1), Int(v2), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ QCOMPARE(qSubOverflow(Int(v1), (std::integral_constant<Int, Int(v2)>()), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ QCOMPARE(qSubOverflow<v2>(Int(v1), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ } while (false)
+#define SUB_COMPARE_OVF(v1, v2) \
+ do { \
+ QCOMPARE(qSubOverflow(Int(v1), Int(v2), &r), true); \
+ QCOMPARE(qSubOverflow(Int(v1), (std::integral_constant<Int, Int(v2)>()), &r), true); \
+ QCOMPARE(qSubOverflow<v2>(Int(v1), &r), true); \
+ } while (false)
+
// basic values
- QCOMPARE(add_overflow(Int(0), Int(0), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(add_overflow(Int(1), Int(0), &r), false);
- QCOMPARE(r, Int(1));
- QCOMPARE(add_overflow(Int(0), Int(1), &r), false);
- QCOMPARE(r, Int(1));
-
- QCOMPARE(sub_overflow(Int(0), Int(0), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(sub_overflow(Int(1), Int(0), &r), false);
- QCOMPARE(r, Int(1));
- QCOMPARE(sub_overflow(Int(1), Int(1), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(sub_overflow(Int(0), Int(1), &r), !min);
+ ADD_COMPARE_NONOVF(0, 0, 0);
+ ADD_COMPARE_NONOVF(1, 0, 1);
+ ADD_COMPARE_NONOVF(0, 1, 1);
+
+ SUB_COMPARE_NONOVF(0, 0, 0);
+ SUB_COMPARE_NONOVF(1, 0, 1);
+ SUB_COMPARE_NONOVF(1, 1, 0);
if (min)
- QCOMPARE(r, Int(-1));
+ SUB_COMPARE_NONOVF(0, 1, -1);
+ else
+ SUB_COMPARE_OVF(0, 1);
// half-way through max
- QCOMPARE(add_overflow(Int(max/2), Int(max/2), &r), false);
- QCOMPARE(r, Int(max / 2 * 2));
- QCOMPARE(sub_overflow(Int(max/2), Int(max/2), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(add_overflow(Int(max/2 - 1), Int(max/2 + 1), &r), false);
- QCOMPARE(r, Int(max / 2 * 2));
- QCOMPARE(sub_overflow(Int(max/2 - 1), Int(max/2 + 1), &r), !min);
+ ADD_COMPARE_NONOVF(max/2, max/2, max / 2 * 2);
+ SUB_COMPARE_NONOVF(max/2, max/2, 0);
+ ADD_COMPARE_NONOVF(max/2 - 1, max/2 + 1, max / 2 * 2);
if (min)
- QCOMPARE(r, Int(-2));
- QCOMPARE(add_overflow(Int(max/2 + 1), Int(max/2), &r), false);
- QCOMPARE(r, max);
- QCOMPARE(sub_overflow(Int(max/2 + 1), Int(max/2), &r), false);
- QCOMPARE(r, Int(1));
- QCOMPARE(add_overflow(Int(max/2), Int(max/2 + 1), &r), false);
- QCOMPARE(r, max);
- QCOMPARE(sub_overflow(Int(max/2), Int(max/2 + 1), &r), !min);
+ SUB_COMPARE_NONOVF(max/2 - 1, max/2 + 1, -2);
+ else
+ SUB_COMPARE_OVF(max/2 - 1, max/2 + 1);
+
+ ADD_COMPARE_NONOVF(max/2 + 1, max/2, max);
+ SUB_COMPARE_NONOVF(max/2 + 1, max/2, 1);
+ ADD_COMPARE_NONOVF(max/2, max/2 + 1, max);
if (min)
- QCOMPARE(r, Int(-1));
+ SUB_COMPARE_NONOVF(max/2, max/2 + 1, -1);
+ else
+ SUB_COMPARE_OVF(max/2, max/2 + 1);
- QCOMPARE(add_overflow(Int(min/2), Int(min/2), &r), false);
- QCOMPARE(r, Int(min / 2 * 2));
- QCOMPARE(sub_overflow(Int(min/2), Int(min/2), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(add_overflow(Int(min/2 - 1), Int(min/2 + 1), &r), !min);
+ ADD_COMPARE_NONOVF(min/2, min/2, min / 2 * 2);
+ SUB_COMPARE_NONOVF(min/2, min/2, 0);
if (min)
- QCOMPARE(r, Int(min / 2 * 2));
- QCOMPARE(sub_overflow(Int(min/2 - 1), Int(min/2 + 1), &r), false);
- QCOMPARE(r, Int(-2));
- QCOMPARE(sub_overflow(Int(min/2 + 1), Int(min/2), &r), false);
- QCOMPARE(r, Int(1));
- QCOMPARE(sub_overflow(Int(min/2), Int(min/2 + 1), &r), !min);
+ ADD_COMPARE_NONOVF(min/2 - 1, min/2 + 1, min / 2 * 2);
+ else
+ ADD_COMPARE_OVF(min/2 - 1, min/2 + 1);
+ SUB_COMPARE_NONOVF(min/2 - 1, min/2 + 1, -2);
+ SUB_COMPARE_NONOVF(min/2 + 1, min/2, 1);
if (min)
- QCOMPARE(r, Int(-1));
+ SUB_COMPARE_NONOVF(min/2, min/2 + 1, -1);
+ else
+ SUB_COMPARE_OVF(min/2, min/2 + 1);
// more than half
- QCOMPARE(add_overflow(Int(max/4 * 3), Int(max/4), &r), false);
- QCOMPARE(r, Int(max / 4 * 4));
+ ADD_COMPARE_NONOVF(max/4 * 3, max/4, max / 4 * 4);
// max
- QCOMPARE(add_overflow(max, Int(0), &r), false);
- QCOMPARE(r, max);
- QCOMPARE(sub_overflow(max, Int(0), &r), false);
- QCOMPARE(r, max);
- QCOMPARE(add_overflow(Int(0), max, &r), false);
- QCOMPARE(r, max);
- QCOMPARE(sub_overflow(Int(0), max, &r), !min);
+ ADD_COMPARE_NONOVF(max, 0, max);
+ SUB_COMPARE_NONOVF(max, 0, max);
+ ADD_COMPARE_NONOVF(0, max, max);
if (min)
- QCOMPARE(r, Int(-max));
-
- QCOMPARE(add_overflow(min, Int(0), &r), false);
- QCOMPARE(r, min);
- QCOMPARE(sub_overflow(min, Int(0), &r), false);
- QCOMPARE(r, min);
- QCOMPARE(add_overflow(Int(0), min, &r), false);
- QCOMPARE(r, min);
- QCOMPARE(sub_overflow(Int(0), Int(min+1), &r), !min);
+ SUB_COMPARE_NONOVF(0, max, -max);
+ else
+ SUB_COMPARE_OVF(0, max);
+
+ ADD_COMPARE_NONOVF(min, 0, min);
+ SUB_COMPARE_NONOVF(min, 0, min);
+ ADD_COMPARE_NONOVF(0, min, min);
if (min)
- QCOMPARE(r, Int(-(min+1)));
+ SUB_COMPARE_NONOVF(0, min+1, -(min+1));
+ else
+ SUB_COMPARE_OVF(0, min+1);
// 64-bit issues
- if (max > std::numeric_limits<uint>::max()) {
- QCOMPARE(add_overflow(Int(std::numeric_limits<uint>::max()), Int(std::numeric_limits<uint>::max()), &r), false);
- QCOMPARE(r, Int(2 * Int(std::numeric_limits<uint>::max())));
- QCOMPARE(sub_overflow(Int(std::numeric_limits<uint>::max()), Int(std::numeric_limits<uint>::max()), &r), false);
- QCOMPARE(r, Int(0));
+ if constexpr (max > std::numeric_limits<uint>::max()) {
+ ADD_COMPARE_NONOVF(std::numeric_limits<uint>::max(), std::numeric_limits<uint>::max(), 2 * Int(std::numeric_limits<uint>::max()));
+ SUB_COMPARE_NONOVF(std::numeric_limits<uint>::max(), std::numeric_limits<uint>::max(), 0);
}
- if (min && min < -Int(std::numeric_limits<uint>::max())) {
- QCOMPARE(add_overflow(Int(-Int(std::numeric_limits<uint>::max())), Int(-Int(std::numeric_limits<uint>::max())), &r), false);
- QCOMPARE(r, Int(-2 * Int(std::numeric_limits<uint>::max())));
- QCOMPARE(sub_overflow(Int(-Int(std::numeric_limits<uint>::max())), Int(-Int(std::numeric_limits<uint>::max())), &r), false);
- QCOMPARE(r, Int(0));
+ if constexpr (min != 0) {
+ if (qint64(min) < qint64(-std::numeric_limits<uint>::max())) {
+ ADD_COMPARE_NONOVF(-Int(std::numeric_limits<uint>::max()), -Int(std::numeric_limits<uint>::max()), -2 * Int(std::numeric_limits<uint>::max()));
+ SUB_COMPARE_NONOVF(-Int(std::numeric_limits<uint>::max()), -Int(std::numeric_limits<uint>::max()), 0);
+ }
}
// overflows past max
- QCOMPARE(add_overflow(max, Int(1), &r), true);
- QCOMPARE(add_overflow(Int(1), max, &r), true);
- QCOMPARE(add_overflow(Int(max/2 + 1), Int(max/2 + 1), &r), true);
- if (!min) {
- QCOMPARE(sub_overflow(Int(-max), Int(-2), &r), true);
- QCOMPARE(sub_overflow(Int(max/2 - 1), Int(max/2 + 1), &r), true);
+ ADD_COMPARE_OVF(max, 1);
+ ADD_COMPARE_OVF(1, max);
+ ADD_COMPARE_OVF(max/2 + 1, max/2 + 1);
+
+ // overflows past min
+ if constexpr (min != 0) {
+ ADD_COMPARE_OVF(-max, -2);
+ SUB_COMPARE_OVF(-max, 2);
+ SUB_COMPARE_OVF(-max/2 - 1, max/2 + 2);
+
+ SUB_COMPARE_OVF(min, 1);
+ SUB_COMPARE_OVF(1, min);
+ SUB_COMPARE_OVF(min/2 - 1, -Int(min/2));
+ ADD_COMPARE_OVF(min, -1);
+ ADD_COMPARE_OVF(-1, min);
}
- // overflows past min (in case of min == 0, repeats some tests above)
- if (min) {
- QCOMPARE(sub_overflow(min, Int(1), &r), true);
- QCOMPARE(sub_overflow(Int(1), min, &r), true);
- QCOMPARE(sub_overflow(Int(min/2 - 1), Int(-Int(min/2)), &r), true);
- QCOMPARE(add_overflow(min, Int(-1), &r), true);
- QCOMPARE(add_overflow(Int(-1), min, &r), true);
- }
+#undef ADD_COMPARE_NONOVF
+#undef ADD_COMPARE_OVF
+#undef SUB_COMPARE_NONOVF
+#undef SUB_COMPARE_OVF
#endif
}
@@ -398,77 +602,82 @@ template <typename Int> static void mulOverflow_template()
#if defined(Q_CC_MSVC) && Q_CC_MSVC < 1900
QSKIP("Test disabled, this test generates an Internal Compiler Error compiling");
#else
- const Int max = std::numeric_limits<Int>::max();
- const Int min = std::numeric_limits<Int>::min();
+ constexpr Int max = std::numeric_limits<Int>::max();
+ constexpr Int min = std::numeric_limits<Int>::min();
// for unsigned (even number of significant bits): mid2 = mid1 - 1
// for signed (odd number of significant bits): mid2 = mid1 / 2 - 1
- const Int mid1 = Int(Int(1) << sizeof(Int) * CHAR_BIT / 2);
- const Int mid2 = (std::numeric_limits<Int>::digits % 2 ? mid1 / 2 : mid1) - 1;
+ constexpr Int mid1 = Int(Int(1) << (sizeof(Int) * CHAR_BIT / 2));
+ constexpr Int mid2 = (std::numeric_limits<Int>::digits % 2 ? mid1 / 2 : mid1) - 1;
Int r;
+#define MUL_COMPARE_NONOVF(v1, v2, expected) \
+ do { \
+ QCOMPARE(qMulOverflow(Int(v1), Int(v2), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ QCOMPARE(qMulOverflow(Int(v1), (std::integral_constant<Int, v2>()), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ QCOMPARE(qMulOverflow<v2>(Int(v1), &r), false); \
+ QCOMPARE(r, Int(expected)); \
+ } while (false);
+#define MUL_COMPARE_OVF(v1, v2) \
+ do { \
+ QCOMPARE(qMulOverflow(Int(v1), Int(v2), &r), true); \
+ QCOMPARE(qMulOverflow(Int(v1), (std::integral_constant<Int, v2>()), &r), true); \
+ QCOMPARE(qMulOverflow<v2>(Int(v1), &r), true); \
+ } while (false);
+
// basic multiplications
- QCOMPARE(mul_overflow(Int(0), Int(0), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(mul_overflow(Int(1), Int(0), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(mul_overflow(Int(0), Int(1), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(mul_overflow(max, Int(0), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(mul_overflow(Int(0), max, &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(mul_overflow(min, Int(0), &r), false);
- QCOMPARE(r, Int(0));
- QCOMPARE(mul_overflow(Int(0), min, &r), false);
- QCOMPARE(r, Int(0));
-
- QCOMPARE(mul_overflow(Int(1), Int(1), &r), false);
- QCOMPARE(r, Int(1));
- QCOMPARE(mul_overflow(Int(1), max, &r), false);
- QCOMPARE(r, max);
- QCOMPARE(mul_overflow(max, Int(1), &r), false);
- QCOMPARE(r, max);
- QCOMPARE(mul_overflow(Int(1), min, &r), false);
- QCOMPARE(r, min);
- QCOMPARE(mul_overflow(min, Int(1), &r), false);
- QCOMPARE(r, min);
+ MUL_COMPARE_NONOVF(0, 0, 0);
+ MUL_COMPARE_NONOVF(1, 0, 0);
+ MUL_COMPARE_NONOVF(0, 1, 0);
+ MUL_COMPARE_NONOVF(max, 0, 0);
+ MUL_COMPARE_NONOVF(0, max, 0);
+ MUL_COMPARE_NONOVF(min, 0, 0);
+ MUL_COMPARE_NONOVF(0, min, 0);
+ if constexpr (min != 0) {
+ MUL_COMPARE_NONOVF(0, -1, 0);
+ MUL_COMPARE_NONOVF(1, -1, -1);
+ MUL_COMPARE_NONOVF(max, -1, -max);
+ }
+
+ MUL_COMPARE_NONOVF(1, 1, 1);
+ MUL_COMPARE_NONOVF(1, max, max);
+ MUL_COMPARE_NONOVF(max, 1, max);
+ MUL_COMPARE_NONOVF(1, min, min);
+ MUL_COMPARE_NONOVF(min, 1, min);
// almost max
- QCOMPARE(mul_overflow(mid1, mid2, &r), false);
- QCOMPARE(r, Int(max - mid1 + 1));
- QCOMPARE(mul_overflow(Int(max / 2), Int(2), &r), false);
- QCOMPARE(r, Int(max & ~Int(1)));
- QCOMPARE(mul_overflow(Int(max / 4), Int(4), &r), false);
- QCOMPARE(r, Int(max & ~Int(3)));
- if (min) {
- QCOMPARE(mul_overflow(Int(-mid1), mid2, &r), false);
- QCOMPARE(r, Int(-max + mid1 - 1));
- QCOMPARE(mul_overflow(Int(-max / 2), Int(2), &r), false);
- QCOMPARE(r, Int(-max + 1));
- QCOMPARE(mul_overflow(Int(-max / 4), Int(4), &r), false);
- QCOMPARE(r, Int(-max + 3));
-
- QCOMPARE(mul_overflow(Int(-mid1), Int(mid2 + 1), &r), false);
- QCOMPARE(r, min);
- QCOMPARE(mul_overflow(mid1, Int(-mid2 - 1), &r), false);
- QCOMPARE(r, min);
+ MUL_COMPARE_NONOVF(mid1, mid2, max - mid1 + 1);
+ MUL_COMPARE_NONOVF(max / 2, 2, max & ~Int(1));
+ MUL_COMPARE_NONOVF(max / 4, 4, max & ~Int(3));
+ if constexpr (min != 0) {
+ MUL_COMPARE_NONOVF(-mid1, mid2, -max + mid1 - 1);
+ MUL_COMPARE_NONOVF(-max / 2, 2, -max + 1);
+ MUL_COMPARE_NONOVF(-max / 4, 4, -max + 3);
+
+ MUL_COMPARE_NONOVF(-mid1, mid2 + 1, min);
+ MUL_COMPARE_NONOVF(mid1, -mid2 - 1, min);
}
// overflows
- QCOMPARE(mul_overflow(max, Int(2), &r), true);
- QCOMPARE(mul_overflow(Int(max / 2), Int(3), &r), true);
- QCOMPARE(mul_overflow(mid1, Int(mid2 + 1), &r), true);
- QCOMPARE(mul_overflow(Int(max / 2 + 2), Int(2), &r), true);
- QCOMPARE(mul_overflow(Int(1ULL << (std::numeric_limits<Int>::digits - 1)), Int(2), &r), true);
-
- if (min) {
- QCOMPARE(mul_overflow(min, Int(2), &r), true);
- QCOMPARE(mul_overflow(Int(min / 2), Int(3), &r), true);
- QCOMPARE(mul_overflow(Int(min / 2 - 1), Int(2), &r), true);
- QCOMPARE(mul_overflow(Int(min + min/2), Int(2), &r), true);
+ MUL_COMPARE_OVF(max, 2);
+ MUL_COMPARE_OVF(max / 2, 3);
+ MUL_COMPARE_OVF(mid1, mid2 + 1);
+ MUL_COMPARE_OVF(max / 2 + 2, 2);
+ MUL_COMPARE_OVF(max - max / 2, 2);
+ MUL_COMPARE_OVF(1ULL << (std::numeric_limits<Int>::digits - 1), 2);
+
+ if constexpr (min != 0) {
+ MUL_COMPARE_OVF(min, -1);
+ MUL_COMPARE_OVF(min, 2);
+ MUL_COMPARE_OVF(min / 2, 3);
+ MUL_COMPARE_OVF(min / 2 - 1, 2);
}
+
+#undef MUL_COMPARE_NONOVF
+#undef MUL_COMPARE_OVF
#endif
}
@@ -503,7 +712,7 @@ void tst_QNumeric::mulOverflow()
if (size == -32)
MulOverflowDispatch<qint32>()();
if (size == -64) {
-#if QT_POINTER_SIZE == 8
+#if QT_POINTER_SIZE == 8 || defined(Q_INTRINSIC_MUL_OVERFLOW64)
MulOverflowDispatch<qint64>()();
#else
QFAIL("128-bit multiplication not supported on this platform");
@@ -517,28 +726,28 @@ void tst_QNumeric::signedOverflow()
const int maxInt = std::numeric_limits<int>::max();
int r;
- QCOMPARE(add_overflow(minInt + 1, int(-1), &r), false);
- QCOMPARE(add_overflow(minInt, int(-1), &r), true);
- QCOMPARE(add_overflow(minInt, minInt, &r), true);
- QCOMPARE(add_overflow(maxInt - 1, int(1), &r), false);
- QCOMPARE(add_overflow(maxInt, int(1), &r), true);
- QCOMPARE(add_overflow(maxInt, maxInt, &r), true);
-
- QCOMPARE(sub_overflow(minInt + 1, int(1), &r), false);
- QCOMPARE(sub_overflow(minInt, int(1), &r), true);
- QCOMPARE(sub_overflow(minInt, maxInt, &r), true);
- QCOMPARE(sub_overflow(maxInt - 1, int(-1), &r), false);
- QCOMPARE(sub_overflow(maxInt, int(-1), &r), true);
- QCOMPARE(sub_overflow(maxInt, minInt, &r), true);
-
- QCOMPARE(mul_overflow(minInt, int(1), &r), false);
- QCOMPARE(mul_overflow(minInt, int(-1), &r), true);
- QCOMPARE(mul_overflow(minInt, int(2), &r), true);
- QCOMPARE(mul_overflow(minInt, minInt, &r), true);
- QCOMPARE(mul_overflow(maxInt, int(1), &r), false);
- QCOMPARE(mul_overflow(maxInt, int(-1), &r), false);
- QCOMPARE(mul_overflow(maxInt, int(2), &r), true);
- QCOMPARE(mul_overflow(maxInt, maxInt, &r), true);
+ QCOMPARE(qAddOverflow(minInt + 1, int(-1), &r), false);
+ QCOMPARE(qAddOverflow(minInt, int(-1), &r), true);
+ QCOMPARE(qAddOverflow(minInt, minInt, &r), true);
+ QCOMPARE(qAddOverflow(maxInt - 1, int(1), &r), false);
+ QCOMPARE(qAddOverflow(maxInt, int(1), &r), true);
+ QCOMPARE(qAddOverflow(maxInt, maxInt, &r), true);
+
+ QCOMPARE(qSubOverflow(minInt + 1, int(1), &r), false);
+ QCOMPARE(qSubOverflow(minInt, int(1), &r), true);
+ QCOMPARE(qSubOverflow(minInt, maxInt, &r), true);
+ QCOMPARE(qSubOverflow(maxInt - 1, int(-1), &r), false);
+ QCOMPARE(qSubOverflow(maxInt, int(-1), &r), true);
+ QCOMPARE(qSubOverflow(maxInt, minInt, &r), true);
+
+ QCOMPARE(qMulOverflow(minInt, int(1), &r), false);
+ QCOMPARE(qMulOverflow(minInt, int(-1), &r), true);
+ QCOMPARE(qMulOverflow(minInt, int(2), &r), true);
+ QCOMPARE(qMulOverflow(minInt, minInt, &r), true);
+ QCOMPARE(qMulOverflow(maxInt, int(1), &r), false);
+ QCOMPARE(qMulOverflow(maxInt, int(-1), &r), false);
+ QCOMPARE(qMulOverflow(maxInt, int(2), &r), true);
+ QCOMPARE(qMulOverflow(maxInt, maxInt, &r), true);
}
QTEST_APPLESS_MAIN(tst_QNumeric)
diff --git a/tests/auto/corelib/global/qoperatingsystemversion/.gitignore b/tests/auto/corelib/global/qoperatingsystemversion/.gitignore
new file mode 100644
index 0000000000..8fb5143f7c
--- /dev/null
+++ b/tests/auto/corelib/global/qoperatingsystemversion/.gitignore
@@ -0,0 +1 @@
+tst_qoperatingsystemversion
diff --git a/tests/auto/corelib/global/qoperatingsystemversion/CMakeLists.txt b/tests/auto/corelib/global/qoperatingsystemversion/CMakeLists.txt
new file mode 100644
index 0000000000..f0e682d664
--- /dev/null
+++ b/tests/auto/corelib/global/qoperatingsystemversion/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qoperatingsystemversion Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qoperatingsystemversion LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qoperatingsystemversion
+ SOURCES
+ tst_qoperatingsystemversion.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/global/qoperatingsystemversion/tst_qoperatingsystemversion.cpp b/tests/auto/corelib/global/qoperatingsystemversion/tst_qoperatingsystemversion.cpp
new file mode 100644
index 0000000000..4c4ff72722
--- /dev/null
+++ b/tests/auto/corelib/global/qoperatingsystemversion/tst_qoperatingsystemversion.cpp
@@ -0,0 +1,254 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qoperatingsystemversion.h>
+
+class tst_QOperatingSystemVersion : public QObject
+{
+ Q_OBJECT
+private slots:
+ void construction_data();
+ void construction();
+ void globals_data();
+ void globals();
+
+ void anyOf();
+
+ void comparison_data();
+ void comparison();
+ void comparison2_data();
+ void comparison2();
+
+ void mixedComparison();
+};
+
+void tst_QOperatingSystemVersion::construction_data()
+{
+ QTest::addColumn<QOperatingSystemVersion::OSType>("osType");
+ QTest::addColumn<int>("majorVersion");
+ QTest::addColumn<int>("minorVersion");
+ QTest::addColumn<int>("microVersion");
+ QTest::addColumn<int>("segmentCount");
+
+ QTest::newRow("Major only") << QOperatingSystemVersion::OSType::Windows << 1 << -1 << -1 << 1;
+ QTest::newRow("Major and minor") << QOperatingSystemVersion::OSType::MacOS
+ << 1 << 2 << -1 << 2;
+ QTest::newRow("Major, minor and micro") << QOperatingSystemVersion::OSType::Android
+ << 1 << 2 << 3 << 3;
+}
+
+void tst_QOperatingSystemVersion::construction()
+{
+ QFETCH(QOperatingSystemVersion::OSType, osType);
+ QFETCH(int, majorVersion);
+ QFETCH(int, minorVersion);
+ QFETCH(int, microVersion);
+ QFETCH(int, segmentCount);
+
+ const QOperatingSystemVersion systemVersion(osType, majorVersion, minorVersion, microVersion);
+ QCOMPARE(systemVersion.type(), osType);
+ QCOMPARE(systemVersion.segmentCount(), segmentCount);
+ QCOMPARE(systemVersion.majorVersion(), majorVersion);
+ QCOMPARE(systemVersion.minorVersion(), minorVersion);
+ QCOMPARE(systemVersion.microVersion(), microVersion);
+ if (osType != QOperatingSystemVersion::OSType::Unknown)
+ QVERIFY(!systemVersion.name().isEmpty());
+}
+
+void tst_QOperatingSystemVersion::globals_data()
+{
+ QTest::addColumn<QOperatingSystemVersion>("osver");
+ QTest::addColumn<QOperatingSystemVersion::OSType>("osType");
+
+#define ADDROW(os) QTest::newRow(#os) << QOperatingSystemVersion(QOperatingSystemVersion::os)
+ // legacy ones (global variables)
+ ADDROW(Windows7) << QOperatingSystemVersion::Windows;
+ ADDROW(Windows10) << QOperatingSystemVersion::Windows;
+ ADDROW(OSXMavericks) << QOperatingSystemVersion::MacOS;
+ ADDROW(MacOSMonterey) << QOperatingSystemVersion::MacOS;
+ ADDROW(AndroidJellyBean) << QOperatingSystemVersion::Android;
+ ADDROW(Android11) << QOperatingSystemVersion::Android;
+
+ // new ones (static constexpr)
+ ADDROW(Windows11) << QOperatingSystemVersion::Windows;
+ ADDROW(Android12) << QOperatingSystemVersion::Android;
+#undef ADDROW
+}
+
+void tst_QOperatingSystemVersion::globals()
+{
+ QFETCH(QOperatingSystemVersion, osver);
+ QFETCH(QOperatingSystemVersion::OSType, osType);
+ QCOMPARE(osver.type(), osType);
+ QCOMPARE_NE(osver.majorVersion(), 0);
+}
+
+void tst_QOperatingSystemVersion::anyOf()
+{
+ std::initializer_list<QOperatingSystemVersion::OSType> typesToCheck = {
+ QOperatingSystemVersion::OSType::Windows, QOperatingSystemVersion::OSType::Android,
+ QOperatingSystemVersion::OSType::MacOS, QOperatingSystemVersion::OSType::Unknown
+ };
+ {
+ // type found case
+ const QOperatingSystemVersion systemVersion(QOperatingSystemVersion::OSType::MacOS, 1);
+ QCOMPARE(systemVersion.isAnyOfType(typesToCheck), true);
+ }
+ {
+ // type NOT found case
+ const QOperatingSystemVersion systemVersion(QOperatingSystemVersion::OSType::WatchOS, 1);
+ QCOMPARE(systemVersion.isAnyOfType(typesToCheck), false);
+ }
+}
+
+void tst_QOperatingSystemVersion::comparison_data()
+{
+ QTest::addColumn<QOperatingSystemVersion::OSType>("lhsType");
+ QTest::addColumn<int>("lhsMajor");
+ QTest::addColumn<int>("lhsMinor");
+ QTest::addColumn<int>("lhsMicro");
+
+ QTest::addColumn<QOperatingSystemVersion::OSType>("rhsType");
+ QTest::addColumn<int>("rhsMajor");
+ QTest::addColumn<int>("rhsMinor");
+ QTest::addColumn<int>("rhsMicro");
+
+ QTest::addColumn<Qt::partial_ordering>("expectedResult");
+
+ QTest::addRow("mismatching types") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << QOperatingSystemVersion::OSType::MacOS << 1 << 2 << 3
+ << Qt::partial_ordering::unordered;
+
+ QTest::addRow("equal versions") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << Qt::partial_ordering::equivalent;
+
+ QTest::addRow("lhs micro less") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 2
+ << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << Qt::partial_ordering::less;
+
+ QTest::addRow("rhs micro less") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 2
+ << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 1
+ << Qt::partial_ordering::greater;
+
+ QTest::addRow("lhs minor less") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << QOperatingSystemVersion::OSType::Windows << 1 << 3 << 3
+ << Qt::partial_ordering::less;
+
+ QTest::addRow("rhs minor less") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 2
+ << QOperatingSystemVersion::OSType::Windows << 1 << 1 << 3
+ << Qt::partial_ordering::greater;
+
+ QTest::addRow("lhs major less") << QOperatingSystemVersion::OSType::Windows << 0 << 5 << 6
+ << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << Qt::partial_ordering::less;
+
+ QTest::addRow("rhs major less") << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << QOperatingSystemVersion::OSType::Windows << 0 << 2 << 3
+ << Qt::partial_ordering::greater;
+
+ QTest::addRow("different segmentCount")
+ << QOperatingSystemVersion::OSType::Windows << 1 << 2 << 3
+ << QOperatingSystemVersion::OSType::Windows << 1 << 2 << -1
+ << Qt::partial_ordering::equivalent;
+}
+
+void tst_QOperatingSystemVersion::comparison()
+{
+ QFETCH(QOperatingSystemVersion::OSType, lhsType);
+ QFETCH(int, lhsMajor);
+ QFETCH(int, lhsMinor);
+ QFETCH(int, lhsMicro);
+
+ const QOperatingSystemVersion lhsSystemInfo(lhsType, lhsMajor, lhsMinor, lhsMicro);
+
+ QFETCH(QOperatingSystemVersion::OSType, rhsType);
+ QFETCH(int, rhsMajor);
+ QFETCH(int, rhsMinor);
+ QFETCH(int, rhsMicro);
+
+ const QOperatingSystemVersion rhsSystemInfo(rhsType, rhsMajor, rhsMinor, rhsMicro);
+
+ QFETCH(const Qt::partial_ordering, expectedResult);
+
+ QCOMPARE_EQ(lhsSystemInfo < rhsSystemInfo, is_lt(expectedResult));
+ QCOMPARE_EQ(lhsSystemInfo <= rhsSystemInfo, is_lteq(expectedResult));
+ QCOMPARE_EQ(lhsSystemInfo > rhsSystemInfo, is_gt(expectedResult));
+ QCOMPARE_EQ(lhsSystemInfo >= rhsSystemInfo, is_gteq(expectedResult));
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(lhsSystemInfo <=> rhsSystemInfo, expectedResult);
+#endif
+}
+
+void tst_QOperatingSystemVersion::comparison2_data()
+{
+ QTest::addColumn<QOperatingSystemVersion>("lhs");
+ QTest::addColumn<QOperatingSystemVersion>("rhs");
+ QTest::addColumn<Qt::partial_ordering>("result");
+
+#define ADDROW(os1, os2) \
+ QTest::newRow(#os1 "-vs-" #os2) << QOperatingSystemVersion(QOperatingSystemVersion::os1) \
+ << QOperatingSystemVersion(QOperatingSystemVersion::os2)
+
+ // Cross-OS testing: not comparables.
+ ADDROW(Windows10, MacOSMonterey) << Qt::partial_ordering::unordered;
+ ADDROW(Windows11, MacOSMonterey) << Qt::partial_ordering::unordered;
+ ADDROW(MacOSMonterey, Windows10) << Qt::partial_ordering::unordered;
+ ADDROW(MacOSMonterey, Windows11) << Qt::partial_ordering::unordered;
+ ADDROW(Windows10, MacOSVentura) << Qt::partial_ordering::unordered;
+ ADDROW(Windows11, MacOSVentura) << Qt::partial_ordering::unordered;
+ ADDROW(MacOSVentura, Windows10) << Qt::partial_ordering::unordered;
+ ADDROW(MacOSVentura, Windows11) << Qt::partial_ordering::unordered;
+ ADDROW(Windows10, Android10) << Qt::partial_ordering::unordered;
+ ADDROW(Windows11, Android11) << Qt::partial_ordering::unordered;
+
+ // Same-OS tests. This list does not have to be exhaustive.
+ ADDROW(Windows7, Windows7) << Qt::partial_ordering::equivalent;
+ ADDROW(Windows7, Windows8) << Qt::partial_ordering::less;
+ ADDROW(Windows8, Windows7) << Qt::partial_ordering::greater;
+ ADDROW(Windows8, Windows10) << Qt::partial_ordering::less;
+ ADDROW(Windows10, Windows8) << Qt::partial_ordering::greater;
+ ADDROW(Windows10, Windows10_21H1) << Qt::partial_ordering::less;
+ ADDROW(Windows10_21H1, Windows10) << Qt::partial_ordering::greater;
+ ADDROW(Windows10, Windows11) << Qt::partial_ordering::less;
+ ADDROW(MacOSCatalina, MacOSCatalina) << Qt::partial_ordering::equivalent;
+ ADDROW(MacOSCatalina, MacOSBigSur) << Qt::partial_ordering::less;
+ ADDROW(MacOSBigSur, MacOSCatalina) << Qt::partial_ordering::greater;
+ ADDROW(MacOSMonterey, MacOSVentura) << Qt::partial_ordering::less;
+ ADDROW(MacOSVentura, MacOSVentura) << Qt::partial_ordering::equivalent;
+ ADDROW(MacOSVentura, MacOSMonterey) << Qt::partial_ordering::greater;
+#undef ADDROW
+}
+
+void tst_QOperatingSystemVersion::comparison2()
+{
+ QFETCH(QOperatingSystemVersion, lhs);
+ QFETCH(QOperatingSystemVersion, rhs);
+ QFETCH(const Qt::partial_ordering, result);
+
+ QEXPECT_FAIL("Windows10-vs-Windows10_21H1", "QTBUG-107907: Unexpected behavior", Abort);
+ QEXPECT_FAIL("Windows10-vs-Windows11", "QTBUG-107907: Unexpected behavior", Abort);
+
+ const bool comparable = (result != Qt::partial_ordering::unordered);
+ QCOMPARE_EQ(lhs < rhs, is_lt(result) && comparable);
+ QEXPECT_FAIL("Windows10_21H1-vs-Windows10", "QTBUG-107907: Unexpected behavior", Abort);
+ QCOMPARE_EQ(lhs <= rhs, is_lteq(result) && comparable);
+ QCOMPARE_EQ(lhs > rhs, is_gt(result) && comparable);
+ QCOMPARE_EQ(lhs >= rhs, is_gteq(result) && comparable);
+#ifdef __cpp_lib_three_way_comparison
+ QCOMPARE_EQ(lhs <=> rhs, result);
+#endif
+}
+
+void tst_QOperatingSystemVersion::mixedComparison()
+{
+ // ==
+ QVERIFY(QOperatingSystemVersion::Windows10
+ >= QOperatingSystemVersionBase(QOperatingSystemVersionBase::Windows, 10, 0));
+ QVERIFY(QOperatingSystemVersion::Windows10
+ <= QOperatingSystemVersionBase(QOperatingSystemVersionBase::Windows, 10, 0));
+}
+
+QTEST_MAIN(tst_QOperatingSystemVersion)
+#include "tst_qoperatingsystemversion.moc"
diff --git a/tests/auto/corelib/global/qrand/.gitignore b/tests/auto/corelib/global/qrand/.gitignore
deleted file mode 100644
index e8ec2ebfd1..0000000000
--- a/tests/auto/corelib/global/qrand/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qrand
diff --git a/tests/auto/corelib/global/qrand/qrand.pro b/tests/auto/corelib/global/qrand/qrand.pro
deleted file mode 100644
index ee1430aea5..0000000000
--- a/tests/auto/corelib/global/qrand/qrand.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qrand
-QT = core testlib
-SOURCES = tst_qrand.cpp
diff --git a/tests/auto/corelib/global/qrand/tst_qrand.cpp b/tests/auto/corelib/global/qrand/tst_qrand.cpp
deleted file mode 100644
index 6a4b2b322b..0000000000
--- a/tests/auto/corelib/global/qrand/tst_qrand.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
-
-class tst_QRand: public QObject
-{
- Q_OBJECT
-private slots:
- void testqrand();
-};
-
-void tst_QRand::testqrand()
-{
- const int numTestValues = 100;
-
- int generatedNumbers[numTestValues];
- bool generatesSameSequence = true;
-
- // test without calling srand() first
- // should give same sequence as with srand(1)
-
- for (int i=0; i<numTestValues; ++i)
- generatedNumbers[i] = qrand();
-
- qsrand(1);
- for (int i=0; i<numTestValues; ++i)
- if (generatedNumbers[i] != qrand())
- generatesSameSequence = false;
-
- QVERIFY(generatesSameSequence);
-
- for (unsigned int seed=1; seed < 10; seed+=100) {
-
- qsrand(seed);
- for (int i=0; i<numTestValues; ++i)
- generatedNumbers[i] = qrand();
-
- qsrand(seed);
- generatesSameSequence = true;
- for (int i=0; i<numTestValues; ++i)
- if (generatedNumbers[i] != qrand())
- generatesSameSequence = false;
-
- QVERIFY(generatesSameSequence);
- }
-}
-
-QTEST_MAIN(tst_QRand)
-#include "tst_qrand.moc"
diff --git a/tests/auto/corelib/global/qrandomgenerator/CMakeLists.txt b/tests/auto/corelib/global/qrandomgenerator/CMakeLists.txt
new file mode 100644
index 0000000000..3d8f892414
--- /dev/null
+++ b/tests/auto/corelib/global/qrandomgenerator/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qrandomgenerator Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qrandomgenerator LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qrandomgenerator
+ SOURCES
+ tst_qrandomgenerator.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/global/qrandomgenerator/qrandomgenerator.pro b/tests/auto/corelib/global/qrandomgenerator/qrandomgenerator.pro
deleted file mode 100644
index 0307b0c1eb..0000000000
--- a/tests/auto/corelib/global/qrandomgenerator/qrandomgenerator.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qrandomgenerator
-QT = core-private testlib
-SOURCES = tst_qrandomgenerator.cpp
diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
index 7c04611823..a32045bbbb 100644
--- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
+++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
@@ -1,36 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
-#include <qlinkedlist.h>
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qlist.h>
#include <qobject.h>
#include <qrandom.h>
-#include <qvector.h>
#include <private/qrandom_p.h>
#include <algorithm>
@@ -40,7 +14,6 @@
# define HAVE_FALLBACK_ENGINE
#endif
-#define COMMA ,
#define QVERIFY_3TIMES(statement) \
do {\
if (!static_cast<bool>(statement))\
@@ -57,7 +30,7 @@ static const double RandomValueFP = double(0.3010463714599609);
static void setRNGControl(uint v)
{
#ifdef QT_BUILD_INTERNAL
- qt_randomdevice_control.store(v);
+ qt_randomdevice_control.storeRelaxed(v);
#else
Q_UNUSED(v);
#endif
@@ -103,6 +76,10 @@ private slots:
void bounded();
void boundedQuality_data() { generate32_data(); }
void boundedQuality();
+ void bounded64_data();
+ void bounded64();
+ void bounded64Quality_data() { generate32_data(); }
+ void bounded64Quality();
void generateReal_data() { generate32_data(); }
void generateReal();
@@ -148,6 +125,12 @@ void tst_QRandomGenerator::basics()
// default constructible
QRandomGenerator rng;
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-move")
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1301
+QT_WARNING_DISABLE_GCC("-Wself-move")
+#endif
// copyable && movable
rng = rng;
rng = std::move(rng);
@@ -156,6 +139,7 @@ void tst_QRandomGenerator::basics()
QRandomGenerator64 rng64;
rng64 = rng64;
rng64 = std::move(rng64);
+QT_WARNING_POP
// 32- and 64-bit should be interchangeable:
rng = rng64;
@@ -183,8 +167,8 @@ void tst_QRandomGenerator::basics()
QRandomGenerator64 systemRng64 = *system64;
systemRng64 = *system64;
- Q_STATIC_ASSERT(std::is_same<decltype(rng64.generate()) COMMA quint64>::value);
- Q_STATIC_ASSERT(std::is_same<decltype(system64->generate()) COMMA quint64>::value);
+ static_assert(std::is_same_v<decltype(rng64.generate()), quint64>);
+ static_assert(std::is_same_v<decltype(system64->generate()), quint64>);
}
void tst_QRandomGenerator::knownSequence()
@@ -320,7 +304,7 @@ void tst_QRandomGenerator::generate32_data()
QTest::newRow("fixed") << (RandomValue32 & RandomDataMask);
QTest::newRow("global") << 0U;
#ifdef QT_BUILD_INTERNAL
- if (qt_has_hwrng())
+ if (qHasHwrng())
QTest::newRow("hwrng") << uint(UseSystemRNG);
QTest::newRow("system") << uint(UseSystemRNG | SkipHWRNG);
# ifdef HAVE_FALLBACK_ENGINE
@@ -391,7 +375,7 @@ void tst_QRandomGenerator::quality()
AcceptableThreshold = 4 * PerfectDistribution,
FailureThreshold = 16 * PerfectDistribution
};
- Q_STATIC_ASSERT(FailureThreshold > AcceptableThreshold);
+ static_assert(FailureThreshold > AcceptableThreshold);
QFETCH(uint, control);
if (control & RandomDataMask)
@@ -511,7 +495,7 @@ void tst_QRandomGenerator::generateNonContiguous()
QFETCH(uint, control);
RandomGenerator rng(control);
- QLinkedList<quint64> list = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ std::list<quint64> list(8);
auto longerArrayCheck = [&] {
QRandomGenerator().generate(list.begin(), list.end());
return find_if(list.begin(), list.end(), [&](quint64 cur) {
@@ -564,7 +548,7 @@ void tst_QRandomGenerator::bounded()
QVERIFY(value < sup);
QCOMPARE(value, expected);
- int ivalue = rng.bounded(sup);
+ int ivalue = rng.bounded(int(sup));
QVERIFY(ivalue < int(sup));
QCOMPARE(ivalue, int(expected));
@@ -587,10 +571,11 @@ void tst_QRandomGenerator::bounded()
QVERIFY(ivalue < 0);
}
-void tst_QRandomGenerator::boundedQuality()
+template <typename UInt> static void boundedQuality_template()
{
- enum { Bound = 283 }; // a prime number
- enum {
+ using Int = std::make_signed_t<UInt>;
+ constexpr Int Bound = 283; // a prime number
+ enum : Int {
BufferCount = Bound * 32,
// if the distribution were perfect, each byte in the buffer would
@@ -610,7 +595,7 @@ void tst_QRandomGenerator::boundedQuality()
AcceptableThreshold = 4 * PerfectDistribution,
FailureThreshold = 16 * PerfectDistribution
};
- Q_STATIC_ASSERT(FailureThreshold > AcceptableThreshold);
+ static_assert(FailureThreshold > AcceptableThreshold);
QFETCH(uint, control);
if (control & RandomDataMask)
@@ -622,10 +607,13 @@ void tst_QRandomGenerator::boundedQuality()
{
// test the quality of the generator
- QVector<quint32> buffer(BufferCount, 0xcdcdcdcd);
+ UInt filler = 0xcdcdcdcd;
+ if (sizeof(filler) > sizeof(quint32))
+ filler |= filler << (std::numeric_limits<UInt>::digits / 2);
+ QVector<UInt> buffer(BufferCount, filler);
generate(buffer.begin(), buffer.end(), [&] { return rng.bounded(Bound); });
- for (quint32 value : qAsConst(buffer)) {
+ for (UInt value : std::as_const(buffer)) {
QVERIFY(value < Bound);
histogram[value]++;
}
@@ -646,6 +634,75 @@ void tst_QRandomGenerator::boundedQuality()
<< "at" << std::min_element(begin(histogram), end(histogram)) - histogram;
}
+void tst_QRandomGenerator::boundedQuality()
+{
+ boundedQuality_template<quint32>();
+}
+
+void tst_QRandomGenerator::bounded64Quality()
+{
+ boundedQuality_template<quint64>();
+}
+
+void tst_QRandomGenerator::bounded64_data()
+{
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("Test only possible in developer builds");
+#endif
+
+ QTest::addColumn<uint>("control");
+ QTest::addColumn<quint64>("sup");
+ QTest::addColumn<quint64>("expected");
+
+ auto newRow = [&](unsigned val, unsigned sup) {
+ Q_ASSERT((val & ~RandomDataMask) == 0);
+
+ unsigned control = SetRandomData | val;
+ QTest::addRow("%u,%u", val, sup) << control << quint64(sup) << quint64(val);
+ };
+
+ // useless: we can only generate zeroes:
+ newRow(0, 1);
+
+ newRow(0x10, 200);
+ newRow(0x20, 200);
+ newRow(0x80, 200);
+}
+
+void tst_QRandomGenerator::bounded64()
+{
+ QFETCH(uint, control);
+ QFETCH(quint64, sup);
+ QFETCH(quint64, expected);
+ RandomGenerator rng(control);
+
+ quint64 value = rng.bounded(sup);
+ QVERIFY(value < sup);
+ QCOMPARE(value, expected);
+
+ qint64 ivalue = rng.bounded(qint64(sup));
+ QVERIFY(ivalue < int(sup));
+ QCOMPARE(ivalue, int(expected));
+
+ // confirm only the bound now
+ setRNGControl(control & (SkipHWRNG|SkipSystemRNG|UseSystemRNG));
+ value = rng.bounded(sup);
+ QVERIFY(value < sup);
+
+ value = rng.bounded(sup / 2, 3 * sup / 2);
+ QVERIFY(value >= sup / 2);
+ QVERIFY(value < 3 * sup / 2);
+
+ ivalue = rng.bounded(-qint64(sup), qint64(sup));
+ QVERIFY(ivalue >= -qint64(sup));
+ QVERIFY(ivalue < qint64(sup));
+
+ // wholly negative range
+ ivalue = rng.bounded(-qint64(sup), qint64(0));
+ QVERIFY(ivalue >= -qint64(sup));
+ QVERIFY(ivalue < 0);
+}
+
void tst_QRandomGenerator::generateReal()
{
QFETCH(uint, control);
@@ -670,18 +727,16 @@ void tst_QRandomGenerator::qualityReal()
return;
RandomGenerator rng(control);
- enum {
- SampleSize = 160,
+ constexpr int SampleSize = 16000;
- // Expected value: sample size times proportion of the range:
- PerfectOctile = SampleSize / 8,
- PerfectHalf = SampleSize / 2,
+ // Expected value: sample size times proportion of the range:
+ constexpr int PerfectOctile = SampleSize / 8;
+ constexpr int PerfectHalf = SampleSize / 2;
- // Variance is (1 - proportion of range) * expected; sqrt() for standard deviations.
- // Should usually be within twice that and almost never outside four times:
- RangeHalf = 25, // floor(4 * sqrt((1 - 0.5) * PerfectHalf))
- RangeOctile = 16 // floor(4 * sqrt((1 - 0.125) * PerfectOctile))
- };
+ // Variance is (1 - proportion of range) * expected; sqrt() for standard deviations.
+ // Should usually be within twice that and almost never outside four times:
+ constexpr int RangeHalf = 252; // floor(4 * sqrt((1 - 0.5) * PerfectHalf))
+ constexpr int RangeOctile = 167; // floor(4 * sqrt((1 - 0.125) * PerfectOctile))
double data[SampleSize];
std::generate(std::begin(data), std::end(data), [&rng] { return rng.generateDouble(); });
@@ -755,7 +810,7 @@ void tst_QRandomGenerator::stdUniformIntDistribution_data()
auto newRow = [&](quint32 max) {
#ifdef QT_BUILD_INTERNAL
- if (qt_has_hwrng())
+ if (qHasHwrng())
QTest::addRow("hwrng:%u", max) << uint(UseSystemRNG) << max;
QTest::addRow("system:%u", max) << uint(UseSystemRNG | SkipHWRNG) << max;
# ifdef HAVE_FALLBACK_ENGINE
@@ -842,18 +897,20 @@ void tst_QRandomGenerator::stdGenerateCanonical()
{
QFETCH(uint, control);
RandomGenerator rng(control);
+ auto generate_canonical = [&rng]() {
+ return std::generate_canonical<qreal, 32>(rng);
+ };
for (int i = 0; i < 4; ++i) {
QVERIFY_3TIMES([&] {
- qreal value = std::generate_canonical<qreal COMMA 32>(rng);
+ qreal value = generate_canonical();
return value > 0 && value < 1 && value != RandomValueFP;
}());
}
// and should hopefully be different from repeated calls
for (int i = 0; i < 4; ++i)
- QVERIFY_3TIMES(std::generate_canonical<qreal COMMA 32>(rng) !=
- std::generate_canonical<qreal COMMA 32>(rng));
+ QVERIFY_3TIMES(generate_canonical() != generate_canonical());
}
void tst_QRandomGenerator::stdUniformRealDistribution_data()
@@ -868,7 +925,7 @@ void tst_QRandomGenerator::stdUniformRealDistribution_data()
auto newRow = [&](double min, double sup) {
#ifdef QT_BUILD_INTERNAL
- if (qt_has_hwrng())
+ if (qHasHwrng())
QTest::addRow("hwrng:%g-%g", min, sup) << uint(UseSystemRNG) << min << sup;
QTest::addRow("system:%g-%g", min, sup) << uint(UseSystemRNG | SkipHWRNG) << min << sup;
# ifdef HAVE_FALLBACK_ENGINE
@@ -882,7 +939,7 @@ void tst_QRandomGenerator::stdUniformRealDistribution_data()
newRow(0, 1); // canonical
newRow(0, 200);
newRow(0, numeric_limits<quint32>::max() + 1.);
- newRow(0, numeric_limits<quint64>::max() + 1.);
+ newRow(0, double(numeric_limits<quint64>::max()) + 1.);
newRow(-1, 1.6);
}
@@ -920,18 +977,18 @@ template <typename Generator> void stdRandomDistributions_template()
{
Generator rd;
- std::bernoulli_distribution()(rd);
+ (void)std::bernoulli_distribution()(rd);
- std::binomial_distribution<quint32>()(rd);
- std::binomial_distribution<quint64>()(rd);
+ (void)std::binomial_distribution<quint32>()(rd);
+ (void)std::binomial_distribution<quint64>()(rd);
- std::negative_binomial_distribution<quint32>()(rd);
- std::negative_binomial_distribution<quint64>()(rd);
+ (void)std::negative_binomial_distribution<quint32>()(rd);
+ (void)std::negative_binomial_distribution<quint64>()(rd);
- std::poisson_distribution<int>()(rd);
- std::poisson_distribution<qint64>()(rd);
+ (void)std::poisson_distribution<int>()(rd);
+ (void)std::poisson_distribution<qint64>()(rd);
- std::normal_distribution<qreal>()(rd);
+ (void)std::normal_distribution<qreal>()(rd);
{
std::discrete_distribution<int> discrete{0, 1, 1, 10000, 2};
diff --git a/tests/auto/corelib/global/qtendian/CMakeLists.txt b/tests/auto/corelib/global/qtendian/CMakeLists.txt
new file mode 100644
index 0000000000..cf1a22f678
--- /dev/null
+++ b/tests/auto/corelib/global/qtendian/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtendian Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtendian LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtendian
+ SOURCES
+ tst_qtendian.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/global/qtendian/qtendian.pro b/tests/auto/corelib/global/qtendian/qtendian.pro
deleted file mode 100644
index 890976d26c..0000000000
--- a/tests/auto/corelib/global/qtendian/qtendian.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtendian
-QT = core core-private testlib
-SOURCES = tst_qtendian.cpp
diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
index 2345bb39c1..8e50b2bd08 100644
--- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
+++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
@@ -1,40 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <QtCore/qendian.h>
#include <QtCore/private/qendian_p.h>
+#include <QtCore/qsysinfo.h>
+#if QT_SUPPORTS_INT128
+#define ONLY_INT128(...) __VA_ARGS__
+#else
+#define ONLY_INT128(...)
+#endif
class tst_QtEndian: public QObject
{
Q_OBJECT
+public:
+ enum Signedness {
+ Unsigned,
+ Signed
+ };
+ Q_ENUM(Signedness);
private slots:
void fromBigEndian();
@@ -54,11 +41,15 @@ private slots:
void endianIntegers_data();
void endianIntegers();
- void endianBitfields();
+ void endianBitfieldUnions_data();
+ void endianBitfieldUnions();
};
struct TestData
{
+ ONLY_INT128(
+ quint128 data128;
+ )
quint64 data64;
quint32 data32;
quint16 data16;
@@ -75,6 +66,9 @@ template <> quint8 getData(const TestData &d) { return d.data8; }
template <> quint16 getData(const TestData &d) { return d.data16; }
template <> quint32 getData(const TestData &d) { return d.data32; }
template <> quint64 getData(const TestData &d) { return d.data64; }
+ONLY_INT128(
+template <> quint128 getData(const TestData &d) { return d.data128; }
+)
template <> float getData(const TestData &d) { return d.dataFloat; }
union RawTestData
@@ -92,6 +86,9 @@ Float int2Float(typename QIntegerForSizeof<Float>::Unsigned i)
}
static const TestData inNativeEndian = {
+ ONLY_INT128(
+ Q_UINT128_C(0x0123'4567'89ab'cdef'18ba'df00'd1da'cafe),
+ )
Q_UINT64_C(0x0123456789abcdef),
0x00c0ffee,
0xcafe,
@@ -101,6 +98,9 @@ static const TestData inNativeEndian = {
'\0'
};
static const RawTestData inBigEndian = {
+ ONLY_INT128(
+ "\x01\x23\x45\x67\x89\xab\xcd\xef\x18\xba\xdf\x00\xd1\xda\xca\xfe"
+ )
"\x01\x23\x45\x67\x89\xab\xcd\xef"
"\x00\xc0\xff\xee"
"\xca\xfe"
@@ -109,6 +109,9 @@ static const RawTestData inBigEndian = {
"\x01\x23\x45\x67\x89\xab\xcd\xef"
};
static const RawTestData inLittleEndian = {
+ ONLY_INT128(
+ "\xfe\xca\xda\xd1\x00\xdf\xba\x18\xef\xcd\xab\x89\x67\x45\x23\x01"
+ )
"\xef\xcd\xab\x89\x67\x45\x23\x01"
"\xee\xff\xc0\x00"
"\xfe\xca"
@@ -120,27 +123,37 @@ static const RawTestData inLittleEndian = {
#define EXPAND_ENDIAN_TEST(endian) \
do { \
/* Unsigned tests */ \
- ENDIAN_TEST(endian, quint, 64); \
- ENDIAN_TEST(endian, quint, 32); \
- ENDIAN_TEST(endian, quint, 16); \
- ENDIAN_TEST(endian, quint, 8); \
+ ONLY_INT128( \
+ ENDIAN_TEST_INT(endian, ui, 128); \
+ ) \
+ ENDIAN_TEST_INT(endian, ui, 64); \
+ ENDIAN_TEST_INT(endian, ui, 32); \
+ ENDIAN_TEST_INT(endian, ui, 16); \
+ ENDIAN_TEST_INT(endian, ui, 8); \
\
/* Signed tests */ \
- ENDIAN_TEST(endian, qint, 64); \
- ENDIAN_TEST(endian, qint, 32); \
- ENDIAN_TEST(endian, qint, 16); \
- ENDIAN_TEST(endian, qint, 8); \
+ ONLY_INT128( \
+ ENDIAN_TEST_INT(endian, i, 128); \
+ ) \
+ ENDIAN_TEST_INT(endian, i, 64); \
+ ENDIAN_TEST_INT(endian, i, 32); \
+ ENDIAN_TEST_INT(endian, i, 16); \
+ ENDIAN_TEST_INT(endian, i, 8); \
} while (false) \
/**/
-#define ENDIAN_TEST(endian, type, size) \
+#define ENDIAN_TEST_INT(Endian, Uns, Size) \
+ ENDIAN_TEST(Endian, q ## Uns ## nt ## Size, data ## Size)
+
+#define ENDIAN_TEST(endian, Type, Data) \
do { \
+ static_assert(std::is_same_v<decltype(qbswap(std::declval<Type>())), Type>); \
QCOMPARE(qFrom ## endian ## Endian( \
- (type ## size)(in ## endian ## Endian.data.data ## size)), \
- (type ## size)(inNativeEndian.data ## size)); \
- QCOMPARE(qFrom ## endian ## Endian<type ## size>( \
- in ## endian ## Endian.rawData + offsetof(TestData, data ## size)), \
- (type ## size)(inNativeEndian.data ## size)); \
+ (Type)(in ## endian ## Endian.data.Data)), \
+ (Type)(inNativeEndian.Data)); \
+ QCOMPARE(qFrom ## endian ## Endian<Type>( \
+ in ## endian ## Endian.rawData + offsetof(TestData, Data)), \
+ (Type)(inNativeEndian.Data)); \
} while (false) \
/**/
@@ -156,6 +169,9 @@ void tst_QtEndian::fromLittleEndian()
#undef ENDIAN_TEST
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wmemset-elt-size")
+
template <typename T>
void transformRegion_template(T (*transformOne)(T), void (*transformRegion)(const void *, qsizetype, void *))
{
@@ -225,6 +241,7 @@ void transformRegion_template(T (*transformOne)(T), void (*transformRegion)(cons
for (int i = 0; i < 64; ++i)
QCOMPARE(dest[i], expected);
}
+QT_WARNING_POP
void tst_QtEndian::fromBigEndianRegion_data()
{
@@ -257,18 +274,18 @@ void tst_QtEndian::fromLittleEndianRegion()
}
}
-#define ENDIAN_TEST(endian, type, size) \
- do { \
- QCOMPARE(qTo ## endian ## Endian( \
- (type ## size)(inNativeEndian.data ## size)), \
- (type ## size)(in ## endian ## Endian.data.data ## size)); \
- \
- RawTestData test; \
- qTo ## endian ## Endian( \
- (type ## size)(inNativeEndian.data ## size), \
- test.rawData + offsetof(TestData, data ## size)); \
- QCOMPARE(test.data.data ## size, in ## endian ## Endian.data.data ## size ); \
- } while (false) \
+#define ENDIAN_TEST(endian, Type, Data) \
+ do { \
+ QCOMPARE(qTo ## endian ## Endian( \
+ (Type)(inNativeEndian.Data)), \
+ (Type)(in ## endian ## Endian.data.Data)); \
+ \
+ RawTestData test; \
+ qTo ## endian ## Endian( \
+ (Type)(inNativeEndian.Data), \
+ test.rawData + offsetof(TestData, Data)); \
+ QCOMPARE(test.data.Data, in ## endian ## Endian.data.Data ); \
+ } while (false) \
/**/
void tst_QtEndian::toBigEndian()
@@ -356,32 +373,108 @@ void tst_QtEndian::endianIntegers()
#endif
}
-void tst_QtEndian::endianBitfields()
+template<template<typename... Accessors> typename Union, template<int, int, typename> typename Member>
+void testBitfieldUnion()
{
- union {
- quint32_be_bitfield<21, 11> upper;
- quint32_be_bitfield<10, 11> lower;
- qint32_be_bitfield<0, 10> bottom;
- } u;
-
- u.upper = 200;
- QCOMPARE(u.upper, 200U);
- u.lower = 1000;
- u.bottom = -8;
- QCOMPARE(u.lower, 1000U);
- QCOMPARE(u.upper, 200U);
-
- u.lower += u.upper;
- QCOMPARE(u.upper, 200U);
- QCOMPARE(u.lower, 1200U);
-
- u.upper = 65536 + 7;
- u.lower = 65535;
- QCOMPARE(u.lower, 65535U & ((1<<11) - 1));
- QCOMPARE(u.upper, 7U);
-
- QCOMPARE(u.bottom, -8);
+ using upper = Member<21, 11, uint>;
+ using lower = Member<10, 11, uint>;
+ using bottom = Member<0, 10, int>;
+ using all = Member<0, 32, uint>;
+
+ using UnionType = Union<upper, lower, bottom, all>;
+ UnionType u;
+
+ u.template set<upper>(200);
+ QCOMPARE(u.template get<upper>(), 200U);
+ u.template set<lower>(1000);
+ u.template set<bottom>(-8);
+ QCOMPARE(u.template get<lower>(), 1000U);
+ QCOMPARE(u.template get<upper>(), 200U);
+
+ u.template set<lower>(u.template get<lower>() + u.template get<upper>());
+ QCOMPARE(u.template get<upper>(), 200U);
+ QCOMPARE(u.template get<lower>(), 1200U);
+
+ u.template set<upper>(65536 + 7);
+ u.template set<lower>(65535);
+ QCOMPARE(u.template get<lower>(), 65535U & ((1<<11) - 1));
+ QCOMPARE(u.template get<upper>(), 7U);
+
+ QCOMPARE(u.template get<bottom>(), -8);
+
+ UnionType u2(QSpecialIntegerBitfieldZero);
+ QCOMPARE(u2.data(), 0U);
+
+ u2.template set<all>(std::numeric_limits<uint>::max());
+ QCOMPARE(u2.template get<all>(), std::numeric_limits<uint>::max());
+
+ u2.template set<all>(453);
+ QCOMPARE(u2.template get<all>(), 453U);
+
+ u2.template set<all>(0);
+ QCOMPARE(u2.template get<all>(), 0U);
+
+ UnionType u3(42U);
+ QCOMPARE(u3.data(), 42U);
+
+ using BEUintAccessor = QSpecialIntegerAccessor<QBigEndianStorageType<uint>, 21, 11>;
+ using LEUintAccessor = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, 21, 11>;
+ using BEIntAccessor = QSpecialIntegerAccessor<QBigEndianStorageType<int>, 0, 10>;
+ using LEIntAccessor = QSpecialIntegerAccessor<QLittleEndianStorageType<int>, 0, 10>;
+
+ if constexpr (std::is_same_v<BEUintAccessor, upper>) {
+ QCOMPARE(u.template get<BEUintAccessor>(), 7U);
+ } else if constexpr (std::is_same_v<LEUintAccessor, upper>) {
+ QCOMPARE(u.template get<LEUintAccessor>(), 7U);
+ } else if constexpr (std::is_same_v<BEIntAccessor, bottom>) {
+ QCOMPARE(u.template get<BEIntAccessor>(), -8);
+ } else if constexpr (std::is_same_v<LEIntAccessor, bottom>) {
+ QCOMPARE(u.template get<LEIntAccessor>(), -8);
+ } else {
+ QFAIL("none of the manually defined accessors match");
+ }
}
+void tst_QtEndian::endianBitfieldUnions_data()
+{
+ QTest::addColumn<QSysInfo::Endian>("byteOrder");
+ QTest::addColumn<Signedness>("signedness");
+
+ QTest::addRow("little endian unsigned") << QSysInfo::LittleEndian << Unsigned;
+ QTest::addRow("little endian signed") << QSysInfo::LittleEndian << Signed;
+ QTest::addRow("big endian unsigned") << QSysInfo::BigEndian << Unsigned;
+ QTest::addRow("big endian signed") << QSysInfo::BigEndian << Signed;
+}
+
+void tst_QtEndian::endianBitfieldUnions()
+{
+ QFETCH(QSysInfo::Endian, byteOrder);
+ QFETCH(Signedness, signedness);
+
+ switch (byteOrder) {
+ case QSysInfo::LittleEndian:
+ switch (signedness) {
+ case Unsigned:
+ testBitfieldUnion<quint32_le_bitfield_union, quint32_le_bitfield_member>();
+ return;
+ case Signed:
+ testBitfieldUnion<qint32_le_bitfield_union, qint32_le_bitfield_member>();
+ return;
+ }
+ Q_UNREACHABLE_RETURN();
+ case QSysInfo::BigEndian:
+ switch (signedness) {
+ case Unsigned:
+ testBitfieldUnion<quint32_be_bitfield_union, quint32_be_bitfield_member>();
+ return;
+ case Signed:
+ testBitfieldUnion<qint32_be_bitfield_union, qint32_be_bitfield_member>();
+ return;
+ }
+ Q_UNREACHABLE_RETURN();
+ }
+}
+
+
QTEST_MAIN(tst_QtEndian)
#include "tst_qtendian.moc"
diff --git a/tests/auto/corelib/global/qxp/CMakeLists.txt b/tests/auto/corelib/global/qxp/CMakeLists.txt
new file mode 100644
index 0000000000..2178f446db
--- /dev/null
+++ b/tests/auto/corelib/global/qxp/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(function_ref)
+add_subdirectory(is_virtual_base_of)
diff --git a/tests/auto/corelib/global/qxp/function_ref/CMakeLists.txt b/tests/auto/corelib/global/qxp/function_ref/CMakeLists.txt
new file mode 100644
index 0000000000..351fe24b22
--- /dev/null
+++ b/tests/auto/corelib/global/qxp/function_ref/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qxp_function_ref LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qxp_function_ref
+ EXCEPTIONS
+ SOURCES
+ tst_qxp_function_ref.cpp
+ LIBRARIES
+ Qt::Core
+)
diff --git a/tests/auto/corelib/global/qxp/function_ref/tst_qxp_function_ref.cpp b/tests/auto/corelib/global/qxp/function_ref/tst_qxp_function_ref.cpp
new file mode 100644
index 0000000000..ee50a311ef
--- /dev/null
+++ b/tests/auto/corelib/global/qxp/function_ref/tst_qxp_function_ref.cpp
@@ -0,0 +1,281 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qxpfunctional.h>
+
+#include <QTest>
+
+#include <type_traits>
+
+// checking dependency q20::remove_cvref_t:
+#define CHECK(in, out) \
+ static_assert(std::is_same_v<q20::remove_cvref_t< in >, out >)
+CHECK(int, int);
+CHECK(const int, int);
+CHECK(int &, int);
+CHECK(const int &, int);
+CHECK(int &&, int);
+CHECK(const int &&, int);
+CHECK(int *, int *);
+CHECK(const int *, const int *);
+CHECK(int[4], int[4]);
+CHECK(const int (&)[4], int[4]);
+#undef CHECK
+
+template <typename T> constexpr inline bool
+is_noexcept_function_ref_helper_v = false;
+template <typename R, typename...Args> constexpr inline bool
+is_noexcept_function_ref_helper_v<qxp::function_ref<R(Args...) noexcept(true)>> = true;
+template <typename R, typename...Args> constexpr inline bool
+is_noexcept_function_ref_helper_v<qxp::function_ref<R(Args...) const noexcept(true)>> = true;
+
+template <typename T> constexpr inline bool
+is_noexcept_function_ref_v = is_noexcept_function_ref_helper_v<q20::remove_cvref_t<T>>;
+
+class tst_qxp_function_ref : public QObject
+{
+ Q_OBJECT
+public:
+ using QObject::QObject;
+
+private Q_SLOTS:
+ void basics();
+ void constOverloads();
+ void constExpr();
+ void voidReturning();
+ void ctad();
+};
+
+void tst_qxp_function_ref::basics()
+{
+ static_assert(std::is_trivially_copyable_v<qxp::function_ref<int(int)>>);
+ static_assert(std::is_trivially_copyable_v<qxp::function_ref<int()>>);
+ static_assert(std::is_trivially_copyable_v<qxp::function_ref<void()>>);
+
+ {
+ Q_CONSTINIT static int invoked = 0;
+ auto lambda = [](int i) noexcept { ++invoked; return i; };
+ const qxp::function_ref<int(int)> f = lambda;
+ QCOMPARE(invoked, 0);
+ QCOMPARE(f(42), 42);
+ QCOMPARE(invoked, 1);
+
+ const int fourtyTwo = 42;
+
+ const qxp::function_ref<int(int) noexcept> f2 = std::move(lambda);
+ QCOMPARE(invoked, 1);
+ QCOMPARE(f2(fourtyTwo), 42);
+ QCOMPARE(invoked, 2);
+
+ int (*fpr)(int) = lambda;
+
+ const qxp::function_ref f3 = fpr;
+ static_assert(!is_noexcept_function_ref_v<decltype(f3)>);
+ QCOMPARE(invoked, 2);
+ QCOMPARE(f3(42), 42);
+ QCOMPARE(invoked, 3);
+
+ int (*fpr2)(int) noexcept = lambda;
+
+ const qxp::function_ref f4 = fpr2;
+ static_assert(is_noexcept_function_ref_v<decltype(f4)>);
+ QCOMPARE(invoked, 3);
+ QCOMPARE(f4(42), 42);
+ QCOMPARE(invoked, 4);
+ }
+ {
+ Q_CONSTINIT static int invoked = 0;
+ auto lambda = [] { ++invoked; return 42; };
+ const qxp::function_ref<int()> f = lambda;
+ QCOMPARE(invoked, 0);
+ QCOMPARE(f(), 42);
+ QCOMPARE(invoked, 1);
+
+ const qxp::function_ref<int()> f2 = std::move(lambda);
+ QCOMPARE(invoked, 1);
+ QCOMPARE(f2(), 42);
+ QCOMPARE(invoked, 2);
+
+ int (*fpr)() = lambda;
+
+ const qxp::function_ref f3 = fpr;
+ static_assert(!is_noexcept_function_ref_v<decltype(f3)>);
+ QCOMPARE(invoked, 2);
+ QCOMPARE(f3(), 42);
+ QCOMPARE(invoked, 3);
+ }
+ {
+ Q_CONSTINIT static int invoked = 0;
+ auto lambda = [] { ++invoked; };
+ const qxp::function_ref<void()> f = lambda;
+ QCOMPARE(invoked, 0);
+ f();
+ QCOMPARE(invoked, 1);
+
+ const qxp::function_ref<void()> f2 = std::move(lambda);
+ QCOMPARE(invoked, 1);
+ f2();
+ QCOMPARE(invoked, 2);
+
+ void (*fpr)() = lambda;
+
+ const qxp::function_ref f3 = fpr;
+ QCOMPARE(invoked, 2);
+ f3();
+ QCOMPARE(invoked, 3);
+ }
+}
+
+void tst_qxp_function_ref::constOverloads()
+{
+ auto func_c = [](qxp::function_ref<int() const> callable)
+ {
+ return callable();
+ };
+ auto func_m = [](qxp::function_ref<int() /*mutable*/> callable)
+ {
+ return callable();
+ };
+
+ struct S
+ {
+ int operator()() { return 1; }
+ int operator()() const { return 2; }
+ };
+ S s;
+ QCOMPARE(func_c(s), 2);
+ QCOMPARE(func_m(s), 1);
+ const S cs;
+ QCOMPARE(func_c(cs), 2);
+#if 0
+ // this should not compile (and doesn't, but currently fails with an error in the impl,
+ // not by failing a constructor constaint → spec issue?).
+ QCOMPARE(func_m(cs), 2);
+#endif
+}
+
+void tst_qxp_function_ref::constExpr()
+{
+ Q_CONSTINIT static int invoked = 0;
+ {
+ Q_CONSTINIT static auto lambda = [] (int i) { ++invoked; return i; };
+ // the function object constructor is constexpr, so this should be constinit:
+ Q_CONSTINIT static qxp::function_ref<int(int)> f = lambda;
+
+ QCOMPARE(invoked, 0);
+ QCOMPARE(f(15), 15);
+ QCOMPARE(invoked, 1);
+ }
+ {
+ constexpr static auto lambda = [] (int i) { ++invoked; return i; };
+ // the function object constructor is constexpr, so this should be constinit:
+ Q_CONSTINIT static qxp::function_ref<int(int) const> f = lambda;
+
+ QCOMPARE(invoked, 1);
+ QCOMPARE(f(51), 51);
+ QCOMPARE(invoked, 2);
+
+#if 0 // ### should this work?:
+ Q_CONSTINIT static qxp::function_ref<int(int)> f2 = lambda;
+
+ QCOMPARE(invoked, 2);
+ QCOMPARE(f(150), 150);
+ QCOMPARE(invoked, 3);
+#endif
+
+ }
+}
+
+int i_f_i_nx(int i) noexcept { return i; }
+void v_f_i_nx(int) noexcept {}
+int i_f_v_nx() noexcept { return 42; }
+void v_f_v_nx() noexcept {}
+
+int i_f_i_ex(int i) { return i; }
+void v_f_i_ex(int) {}
+int i_f_v_ex() { return 42; }
+void v_f_v_ex() {}
+
+void tst_qxp_function_ref::voidReturning()
+{
+ // check that "casting" int to void returns works:
+
+ using Fi = qxp::function_ref<void(int)>;
+ using Fv = qxp::function_ref<void()>;
+
+ {
+ Fi fi = i_f_i_nx;
+ fi(42);
+ Fv fv = i_f_v_nx;
+ fv();
+ }
+
+ {
+ Fi fi = i_f_i_ex;
+ fi(42);
+ Fv fv = i_f_v_ex;
+ fv();
+ }
+
+ // now with lambdas
+
+ bool ok = false; // prevent lambdas from decaying to function pointers
+ {
+ auto lambda1 = [&](int i) noexcept { return i + int(ok); };
+ Fi fi = lambda1;
+ fi(42);
+ auto lambda2 = [&]() noexcept { return int(ok); };
+ Fv fv = lambda2;
+ fv();
+ }
+
+ {
+ auto lambda1 = [&](int i) { return i + int(ok); };
+ Fi fi = lambda1;
+ fi(42);
+ auto lambda2 = [&]() { return int(ok); };
+ Fv fv = lambda2;
+ fv();
+ }
+}
+
+void tst_qxp_function_ref::ctad()
+{
+#define CHECK(fun, sig) \
+ do { \
+ qxp::function_ref f = fun; \
+ static_assert(std::is_same_v<decltype(f), \
+ qxp::function_ref<sig>>); \
+ qxp::function_ref f2 = &fun; \
+ static_assert(std::is_same_v<decltype(f2), \
+ qxp::function_ref<sig>>); \
+ static_assert(std::is_trivially_copyable_v<decltype(f)>); \
+ static_assert(std::is_trivially_copyable_v<decltype(f2)>); \
+ } while (false)
+
+ CHECK(i_f_i_nx, int (int) noexcept);
+ CHECK(v_f_i_nx, void(int) noexcept);
+ CHECK(i_f_v_nx, int ( ) noexcept);
+ CHECK(v_f_v_nx, void( ) noexcept);
+
+ CHECK(i_f_i_ex, int (int));
+ CHECK(v_f_i_ex, void(int));
+ CHECK(i_f_v_ex, int ( ));
+ CHECK(v_f_v_ex, void( ));
+
+#undef CHECK
+
+#if 0 // no deduction guides for the non-function-pointer case, so no CTAD for lambdas
+ {
+ auto lambda = [](int i) -> int { return i; };
+ qxp::function_ref f = lambda;
+ static_assert(std::is_same_v<decltype(f),
+ qxp::function_ref<int(int)>>);
+ }
+#endif
+}
+
+
+QTEST_APPLESS_MAIN(tst_qxp_function_ref);
+
+#include "tst_qxp_function_ref.moc"
diff --git a/tests/auto/corelib/global/qxp/is_virtual_base_of/CMakeLists.txt b/tests/auto/corelib/global/qxp/is_virtual_base_of/CMakeLists.txt
new file mode 100644
index 0000000000..85a6daab7c
--- /dev/null
+++ b/tests/auto/corelib/global/qxp/is_virtual_base_of/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qxp_is_virtual_base_of LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qxp_is_virtual_base_of
+ EXCEPTIONS
+ SOURCES
+ tst_is_virtual_base_of.cpp
+ LIBRARIES
+ Qt::Core
+)
+
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90449
+# GCCs < 10 have no way to suppress "inaccessible base" warnings, except by disabling all warnings:
+qt_internal_extend_target(tst_qxp_is_virtual_base_of
+ CONDITION GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10")
+ COMPILE_OPTIONS -w
+)
diff --git a/tests/auto/corelib/global/qxp/is_virtual_base_of/tst_is_virtual_base_of.cpp b/tests/auto/corelib/global/qxp/is_virtual_base_of/tst_is_virtual_base_of.cpp
new file mode 100644
index 0000000000..e50575f5ec
--- /dev/null
+++ b/tests/auto/corelib/global/qxp/is_virtual_base_of/tst_is_virtual_base_of.cpp
@@ -0,0 +1,102 @@
+// Copyright (C) 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qxptype_traits.h>
+
+#include <QTest>
+
+class tst_qxp_is_virtual_base_of : public QObject
+{
+ Q_OBJECT
+};
+
+class Base {
+public:
+ virtual ~Base() {}
+};
+
+// Only works with classes
+static_assert(!qxp::is_virtual_base_of_v<int, int>);
+static_assert(!qxp::is_virtual_base_of_v<int, Base>);
+static_assert(!qxp::is_virtual_base_of_v<Base, int>);
+
+// A class isn't a virtual base of itself
+static_assert(!qxp::is_virtual_base_of_v<Base, Base>);
+
+// Non-virtual bases
+class NonVirtualDerived : public Base {};
+class NonVirtualPrivateDerived : private Base {};
+
+static_assert(!qxp::is_virtual_base_of_v<Base, NonVirtualDerived>);
+static_assert(!qxp::is_virtual_base_of_v<Base, NonVirtualPrivateDerived>);
+
+static_assert(!qxp::is_virtual_base_of_v<NonVirtualPrivateDerived, NonVirtualDerived>);
+static_assert(!qxp::is_virtual_base_of_v<NonVirtualDerived, NonVirtualPrivateDerived>);
+
+static_assert(!qxp::is_virtual_base_of_v<tst_qxp_is_virtual_base_of, QObject>);
+
+// Virtual bases
+class VirtualDerived1 : public virtual Base {};
+class VirtualDerived2 : public virtual Base {};
+class VirtualDerived3 : public VirtualDerived1, public VirtualDerived2 {};
+class VirtualDerived4 : public VirtualDerived3, public virtual Base {};
+class VirtualPrivateDerived : private virtual Base {};
+
+static_assert(qxp::is_virtual_base_of_v<Base, VirtualDerived1>);
+static_assert(qxp::is_virtual_base_of_v<Base, VirtualDerived2>);
+static_assert(qxp::is_virtual_base_of_v<Base, VirtualDerived3>);
+static_assert(!qxp::is_virtual_base_of_v<VirtualDerived1, VirtualDerived3>);
+static_assert(qxp::is_virtual_base_of_v<Base, VirtualDerived4>);
+static_assert(qxp::is_virtual_base_of_v<Base, VirtualPrivateDerived>);
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Winaccessible-base")
+QT_WARNING_DISABLE_CLANG("-Winaccessible-base")
+// Ambiguous non-virtual base
+class IntermediateDerived : public Base {};
+class AmbiguousBase1 : public IntermediateDerived, public Base {};
+class AmbiguousBase2 : public IntermediateDerived, public virtual Base {};
+
+static_assert(!qxp::is_virtual_base_of_v<Base, AmbiguousBase1>);
+#ifndef Q_CC_MSVC_ONLY // https://developercommunity.visualstudio.com/t/c-templates-multiple-inheritance-ambiguous-access/185674
+static_assert(!qxp::is_virtual_base_of_v<Base, AmbiguousBase2>);
+#endif
+QT_WARNING_POP
+
+// Const
+static_assert(!qxp::is_virtual_base_of_v< Base, const NonVirtualDerived>);
+static_assert(!qxp::is_virtual_base_of_v<const Base, NonVirtualDerived>);
+static_assert(!qxp::is_virtual_base_of_v<const Base, const NonVirtualDerived>);
+
+static_assert(!qxp::is_virtual_base_of_v< Base, const NonVirtualPrivateDerived>);
+static_assert(!qxp::is_virtual_base_of_v<const Base, NonVirtualPrivateDerived>);
+static_assert(!qxp::is_virtual_base_of_v<const Base, const NonVirtualPrivateDerived>);
+
+static_assert(qxp::is_virtual_base_of_v< Base, const VirtualDerived1>);
+static_assert(qxp::is_virtual_base_of_v<const Base, VirtualDerived1>);
+static_assert(qxp::is_virtual_base_of_v<const Base, const VirtualDerived1>);
+
+static_assert(qxp::is_virtual_base_of_v< Base, const VirtualDerived2>);
+static_assert(qxp::is_virtual_base_of_v<const Base, VirtualDerived2>);
+static_assert(qxp::is_virtual_base_of_v<const Base, const VirtualDerived2>);
+
+static_assert(qxp::is_virtual_base_of_v< Base, const VirtualDerived3>);
+static_assert(qxp::is_virtual_base_of_v<const Base, VirtualDerived3>);
+static_assert(qxp::is_virtual_base_of_v<const Base, const VirtualDerived3>);
+
+static_assert(qxp::is_virtual_base_of_v< Base, const VirtualDerived4>);
+static_assert(qxp::is_virtual_base_of_v<const Base, VirtualDerived4>);
+static_assert(qxp::is_virtual_base_of_v<const Base, const VirtualDerived4>);
+
+static_assert(qxp::is_virtual_base_of_v< Base, const VirtualDerived4>);
+static_assert(qxp::is_virtual_base_of_v<const Base, VirtualDerived4>);
+static_assert(qxp::is_virtual_base_of_v<const Base, const VirtualDerived4>);
+
+static_assert(qxp::is_virtual_base_of_v< Base, const VirtualPrivateDerived>);
+static_assert(qxp::is_virtual_base_of_v<const Base, VirtualPrivateDerived>);
+static_assert(qxp::is_virtual_base_of_v<const Base, const VirtualPrivateDerived>);
+
+
+QTEST_APPLESS_MAIN(tst_qxp_is_virtual_base_of);
+
+#include "tst_is_virtual_base_of.moc"
diff --git a/tests/auto/corelib/io/CMakeLists.txt b/tests/auto/corelib/io/CMakeLists.txt
new file mode 100644
index 0000000000..7fdf4b52b0
--- /dev/null
+++ b/tests/auto/corelib/io/CMakeLists.txt
@@ -0,0 +1,70 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# There is no mounted filesystem for IO testing on INTEGRITY yet.
+if(INTEGRITY)
+ return()
+endif()
+
+if(QT_FEATURE_private_tests)
+ add_subdirectory(qabstractfileengine)
+ add_subdirectory(qfileinfo)
+ add_subdirectory(qipaddress)
+ add_subdirectory(qloggingregistry)
+ add_subdirectory(qurlinternal)
+endif()
+add_subdirectory(qbuffer)
+add_subdirectory(qdataurl)
+add_subdirectory(qdiriterator)
+add_subdirectory(qdirlisting)
+add_subdirectory(qfile)
+add_subdirectory(largefile)
+add_subdirectory(qfileselector)
+add_subdirectory(qfilesystemmetadata)
+add_subdirectory(qloggingcategory)
+add_subdirectory(qnodebug)
+add_subdirectory(qsavefile)
+add_subdirectory(qstandardpaths)
+if(NOT QNX)
+ add_subdirectory(qstorageinfo)
+endif()
+add_subdirectory(qtemporarydir)
+add_subdirectory(qtemporaryfile)
+add_subdirectory(qurlquery)
+add_subdirectory(qurluts46)
+if(TARGET Qt::Concurrent)
+ if(NOT INTEGRITY)
+ add_subdirectory(qdebug)
+ endif()
+ add_subdirectory(qlockfile)
+ add_subdirectory(qurl)
+endif()
+if(NOT ANDROID)
+ add_subdirectory(qdir)
+ add_subdirectory(qresourceengine)
+endif()
+if(QT_FEATURE_private_tests)
+ add_subdirectory(qfilesystementry)
+endif()
+# QTBUG-88508
+if(QT_FEATURE_filesystemwatcher AND NOT ANDROID)
+ add_subdirectory(qfilesystemwatcher)
+endif()
+if(TARGET Qt::Network)
+ add_subdirectory(qiodevice)
+endif()
+if(QT_FEATURE_process AND TARGET Qt::Network AND NOT ANDROID)
+ add_subdirectory(qprocess)
+endif()
+if(QT_FEATURE_process)
+ add_subdirectory(qprocess-noapplication)
+endif()
+if(QT_FEATURE_processenvironment)
+ add_subdirectory(qprocessenvironment)
+endif()
+if(QT_FEATURE_settings AND TARGET Qt::Gui)
+ add_subdirectory(qsettings)
+endif()
+if(QT_FEATURE_private_tests)
+ add_subdirectory(qzip)
+endif()
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
deleted file mode 100644
index eee2c0e30d..0000000000
--- a/tests/auto/corelib/io/io.pro
+++ /dev/null
@@ -1,77 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qabstractfileengine \
- qbuffer \
- qdataurl \
- qdebug \
- qdir \
- qdiriterator \
- qfile \
- largefile \
- qfileinfo \
- qfileselector \
- qfilesystemmetadata \
- qfilesystementry \
- qfilesystemwatcher \
- qiodevice \
- qipaddress \
- qlockfile \
- qloggingcategory \
- qloggingregistry \
- qnodebug \
- qprocess \
- qprocess-noapplication \
- qprocessenvironment \
- qresourceengine \
- qsettings \
- qsavefile \
- qstandardpaths \
- qstorageinfo \
- qtemporarydir \
- qtemporaryfile \
- qurl \
- qurlinternal \
- qurlquery \
-
-!qtHaveModule(gui): SUBDIRS -= \
- qsettings
-
-!qtHaveModule(network): SUBDIRS -= \
- qiodevice \
- qprocess
-
-!qtHaveModule(concurrent): SUBDIRS -= \
- qdebug \
- qlockfile \
- qurl
-
-!qtConfig(private_tests): SUBDIRS -= \
- qabstractfileengine \
- qfileinfo \
- qipaddress \
- qurlinternal \
- qloggingregistry
-
-win32:!qtConfig(private_tests): SUBDIRS -= \
- qfilesystementry
-
-!qtConfig(filesystemwatcher): SUBDIRS -= \
- qfilesystemwatcher
-
-!qtConfig(processenvironment): SUBDIRS -= \
- qprocessenvironment
-
-!qtConfig(process): SUBDIRS -= \
- qprocess \
- qprocess-noapplication
-
-!qtConfig(settings): SUBDIRS -= \
- qsettings
-
-winrt: SUBDIRS -= \
- qstorageinfo
-
-android: SUBDIRS -= \
- qprocess \
- qdir \
- qresourceengine
diff --git a/tests/auto/corelib/io/largefile/CMakeLists.txt b/tests/auto/corelib/io/largefile/CMakeLists.txt
new file mode 100644
index 0000000000..17b411ab33
--- /dev/null
+++ b/tests/auto/corelib/io/largefile/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_largefile Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_largefile LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_largefile
+ SOURCES
+ tst_largefile.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/io/largefile/largefile.pro b/tests/auto/corelib/io/largefile/largefile.pro
deleted file mode 100644
index e96d1398ca..0000000000
--- a/tests/auto/corelib/io/largefile/largefile.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_largefile
-QT = core testlib
-SOURCES = tst_largefile.cpp
-INCLUDEPATH += ../../../../shared/
-HEADERS += ../../../../shared/emulationdetector.h
diff --git a/tests/auto/corelib/io/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp
index dca7672b8e..6fa3569c4f 100644
--- a/tests/auto/corelib/io/largefile/tst_largefile.cpp
+++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp
@@ -1,34 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
-#include <QtAlgorithms>
#include <QFile>
#include <QFileInfo>
#include <QRandomGenerator>
@@ -36,6 +10,7 @@
#include <QDebug>
+#include <algorithm>
#include <cstdlib>
#include <cstdio>
@@ -48,7 +23,7 @@
# endif
#endif // Q_OS_WIN
-#include "emulationdetector.h"
+#include <QtTest/private/qemulationdetector_p.h>
class tst_LargeFile
: public QObject
@@ -62,18 +37,25 @@ public:
, fd_(-1)
, stream_(0)
{
- #if defined(QT_LARGEFILE_SUPPORT) && !defined(Q_OS_MAC) && !defined(Q_OS_WINRT)
- maxSizeBits = 36; // 64 GiB
- #elif defined(Q_OS_MAC)
+ #if defined(Q_OS_DARWIN)
// HFS+ does not support sparse files, so we limit file size for the test
// on Mac OS.
maxSizeBits = 24; // 16 MiB
+ #elif defined(Q_OS_QNX)
+ // Many of the filesystems that QNX supports use a 32-bit format.
+ // This means that files are limited to 2 GB − 1 bytes.
+ // Limit max size to 256MB
+ maxSizeBits = 28; // 256 MiB
+ #elif defined (Q_OS_WASM)
+ maxSizeBits = 28; // 256 MiB
+ #elif defined(QT_LARGEFILE_SUPPORT)
+ maxSizeBits = 36; // 64 GiB
#else
maxSizeBits = 24; // 16 MiB
#endif
// QEMU only supports < 4GB files
- if (EmulationDetector::isRunningArmOnX86())
+ if (QTestPrivate::isRunningArmOnX86())
maxSizeBits = qMin(maxSizeBits, 28);
}
@@ -127,7 +109,7 @@ private:
QFile largeFile;
- QVector<QByteArray> generatedBlocks;
+ QByteArrayList generatedBlocks;
int fd_;
FILE *stream_;
@@ -299,7 +281,7 @@ void tst_LargeFile::createSparseFile()
DWORD bytes;
if (!::DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0,
&bytes, NULL)) {
- QWARN("Unable to set test file as sparse. "
+ qWarning("Unable to set test file as sparse. "
"Limiting test file to 16MiB.");
maxSizeBits = 24;
}
@@ -347,11 +329,10 @@ void tst_LargeFile::fillFileSparsely()
{
if (failed) {
this_->maxSizeBits = lastKnownGoodIndex;
- QWARN( qPrintable(
- QString("QFile::error %1: '%2'. Maximum size bits reset to %3.")
- .arg(this_->largeFile.error())
- .arg(this_->largeFile.errorString())
- .arg(this_->maxSizeBits)) );
+ qWarning("QFile::error %d: '%s'. Maximum size bits reset to %d.",
+ this_->largeFile.error(),
+ qPrintable(this_->largeFile.errorString()),
+ this_->maxSizeBits);
} else
lastKnownGoodIndex = qMax<int>(index_, lastKnownGoodIndex);
}
@@ -489,13 +470,13 @@ void tst_LargeFile::mapFile()
// Keep full block mapped to facilitate OS and/or internal reuse by Qt.
uchar *baseAddress = largeFile.map(position, blockSize);
QVERIFY( baseAddress );
- QVERIFY( qEqual(block.begin(), block.end(), reinterpret_cast<char*>(baseAddress)) );
+ QVERIFY( std::equal(block.begin(), block.end(), reinterpret_cast<char*>(baseAddress)) );
for (int offset = 1; offset < blockSize; ++offset) {
uchar *address = largeFile.map(position + offset, blockSize - offset);
QVERIFY( address );
- if ( !qEqual(block.begin() + offset, block.end(), reinterpret_cast<char*>(address)) ) {
+ if ( !std::equal(block.begin() + offset, block.end(), reinterpret_cast<char*>(address)) ) {
qDebug() << "Expected:" << block.toHex();
qDebug() << "Actual :" << QByteArray(reinterpret_cast<char*>(address), blockSize).toHex();
QVERIFY(false);
@@ -512,19 +493,22 @@ void tst_LargeFile::mapFile()
//Linux: memory-mapping beyond EOF usually succeeds, but depends on the filesystem
// 32-bit: limited to 44-bit offsets (when sizeof(off_t) == 8)
//Windows: memory-mapping beyond EOF is not allowed
+//wasm: as for linux
void tst_LargeFile::mapOffsetOverflow()
{
enum {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN)
Succeeds = false,
MaxOffset = 63
-#else
+#elif defined(Q_OS_WASM)
Succeeds = true,
-# if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
MaxOffset = sizeof(QT_OFF_T) > 4 ? 43 : 30
-# else
+#elif (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && (Q_PROCESSOR_WORDSIZE == 4)
+ Succeeds = true,
+ MaxOffset = sizeof(QT_OFF_T) > 4 ? 43 : 30
+#else
+ Succeeds = true,
MaxOffset = 8 * sizeof(QT_OFF_T) - 1
-# endif
#endif
};
diff --git a/tests/auto/corelib/io/qabstractfileengine/CMakeLists.txt b/tests/auto/corelib/io/qabstractfileengine/CMakeLists.txt
new file mode 100644
index 0000000000..7e7ad98d73
--- /dev/null
+++ b/tests/auto/corelib/io/qabstractfileengine/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qabstractfileengine Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractfileengine LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qabstractfileengine
+ SOURCES
+ tst_qabstractfileengine.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+# Resources:
+set(qabstractfileengine_resource_files
+ "resources/"
+)
+
+qt_internal_add_resource(tst_qabstractfileengine "qabstractfileengine"
+ PREFIX
+ "/tst_qabstractfileengine/"
+ FILES
+ ${qabstractfileengine_resource_files}
+)
+
diff --git a/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro b/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro
deleted file mode 100644
index 641bb7341b..0000000000
--- a/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qabstractfileengine
-QT = core-private core testlib
-SOURCES = tst_qabstractfileengine.cpp
-RESOURCES += qabstractfileengine.qrc
diff --git a/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc b/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc
deleted file mode 100644
index 5401b086b2..0000000000
--- a/tests/auto/corelib/io/qabstractfileengine/qabstractfileengine.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/tst_qabstractfileengine/">
- <file>resources/</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
index 1072cb44f9..cf00c1525c 100644
--- a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
+++ b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the FOO module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/private/qabstractfileengine_p.h>
#include <QtCore/private/qfsfileengine_p.h>
@@ -42,6 +17,8 @@
#include <QtCore/QDebug>
#include "../../../../shared/filesystem.h"
+using namespace Qt::StringLiterals;
+
class tst_QAbstractFileEngine
: public QObject
{
@@ -76,8 +53,10 @@ public:
{
}
- bool open(QIODevice::OpenMode openMode)
+ bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override
{
+ Q_UNUSED(permissions);
+
if (openForRead_ || openForWrite_) {
qWarning("%s: file is already open for %s",
Q_FUNC_INFO,
@@ -108,7 +87,7 @@ public:
return true;
}
- bool close()
+ bool close() override
{
openFile_.clear();
@@ -119,7 +98,7 @@ public:
return true;
}
- qint64 size() const
+ qint64 size() const override
{
QSharedPointer<File> file = resolveFile(false);
if (!file)
@@ -129,7 +108,7 @@ public:
return file->content.size();
}
- qint64 pos() const
+ qint64 pos() const override
{
if (!openForRead_ && !openForWrite_) {
qWarning("%s: file is not open", Q_FUNC_INFO);
@@ -138,7 +117,7 @@ public:
return position_;
}
- bool seek(qint64 pos)
+ bool seek(qint64 pos) override
{
if (!openForRead_ && !openForWrite_) {
qWarning("%s: file is not open", Q_FUNC_INFO);
@@ -153,7 +132,7 @@ public:
return false;
}
- bool flush()
+ bool flush() override
{
if (!openForRead_ && !openForWrite_) {
qWarning("%s: file is not open", Q_FUNC_INFO);
@@ -163,7 +142,7 @@ public:
return true;
}
- bool remove()
+ bool remove() override
{
QMutexLocker lock(&fileSystemMutex);
int count = fileSystem.remove(fileName_);
@@ -171,7 +150,7 @@ public:
return (count == 1);
}
- bool copy(const QString &newName)
+ bool copy(const QString &newName) override
{
QMutexLocker lock(&fileSystemMutex);
if (!fileSystem.contains(fileName_)
@@ -182,7 +161,7 @@ public:
return true;
}
- bool rename(const QString &newName)
+ bool rename(const QString &newName) override
{
QMutexLocker lock(&fileSystemMutex);
if (!fileSystem.contains(fileName_)
@@ -193,29 +172,7 @@ public:
return true;
}
- // bool link(const QString &newName)
- // {
- // Q_UNUSED(newName)
- // return false;
- // }
-
- // bool mkdir(const QString &dirName, bool createParentDirectories) const
- // {
- // Q_UNUSED(dirName)
- // Q_UNUSED(createParentDirectories)
-
- // return false;
- // }
-
- // bool rmdir(const QString &dirName, bool recurseParentDirectories) const
- // {
- // Q_UNUSED(dirName)
- // Q_UNUSED(recurseParentDirectories)
-
- // return false;
- // }
-
- bool setSize(qint64 size)
+ bool setSize(qint64 size) override
{
if (size < 0)
return false;
@@ -234,7 +191,7 @@ public:
return (file->content.size() == size);
}
- FileFlags fileFlags(FileFlags type) const
+ FileFlags fileFlags(FileFlags type) const override
{
QSharedPointer<File> file = resolveFile(false);
if (file) {
@@ -245,14 +202,7 @@ public:
return FileFlags();
}
- // bool setPermissions(uint perms)
- // {
- // Q_UNUSED(perms)
-
- // return false;
- // }
-
- QString fileName(FileName file) const
+ QString fileName(FileName file) const override
{
switch (file) {
case DefaultName:
@@ -265,8 +215,10 @@ public:
return QLatin1String("AbsoluteName");
case AbsolutePathName:
return QLatin1String("AbsolutePathName");
- case LinkName:
- return QLatin1String("LinkName");
+ case AbsoluteLinkTarget:
+ return QLatin1String("AbsoluteLinkTarget");
+ case RawLinkPath:
+ return QLatin1String("RawLinkPath");
case CanonicalName:
return QLatin1String("CanonicalName");
case CanonicalPathName:
@@ -281,7 +233,7 @@ public:
return QString();
}
- uint ownerId(FileOwner owner) const
+ uint ownerId(FileOwner owner) const override
{
QSharedPointer<File> file = resolveFile(false);
if (file) {
@@ -302,7 +254,7 @@ public:
return -2;
}
- QString owner(FileOwner owner) const
+ QString owner(FileOwner owner) const override
{
QSharedPointer<File> file = resolveFile(false);
if (file) {
@@ -335,19 +287,19 @@ public:
return QString();
}
- QDateTime fileTime(FileTime time) const
+ QDateTime fileTime(QFile::FileTime time) const override
{
QSharedPointer<File> file = resolveFile(false);
if (file) {
QMutexLocker lock(&file->mutex);
switch (time) {
- case BirthTime:
+ case QFile::FileBirthTime:
return file->birth;
- case MetadataChangeTime:
+ case QFile::FileMetadataChangeTime:
return file->change;
- case ModificationTime:
+ case QFile::FileModificationTime:
return file->modification;
- case AccessTime:
+ case QFile::FileAccessTime:
return file->access;
}
}
@@ -355,14 +307,7 @@ public:
return QDateTime();
}
- bool setFileTime(const QDateTime &newDate, FileTime time)
- {
- Q_UNUSED(newDate);
- Q_UNUSED(time);
- return false;
- }
-
- void setFileName(const QString &file)
+ void setFileName(const QString &file) override
{
if (openForRead_ || openForWrite_)
qWarning("%s: Can't set file name while file is open", Q_FUNC_INFO);
@@ -370,21 +315,7 @@ public:
fileName_ = file;
}
- // typedef QAbstractFileEngineIterator Iterator;
- // Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames)
- // {
- // Q_UNUSED(filters)
- // Q_UNUSED(filterNames)
-
- // return 0;
- // }
-
- // Iterator *endEntryList()
- // {
- // return 0;
- // }
-
- qint64 read(char *data, qint64 maxLen)
+ qint64 read(char *data, qint64 maxLen) override
{
if (!openForRead_) {
qWarning("%s: file must be open for reading", Q_FUNC_INFO);
@@ -407,7 +338,7 @@ public:
return readSize;
}
- qint64 write(const char *data, qint64 length)
+ qint64 write(const char *data, qint64 length) override
{
if (!openForWrite_) {
qWarning("%s: file must be open for writing", Q_FUNC_INFO);
@@ -501,27 +432,28 @@ public:
class Iterator : public QAbstractFileEngineIterator
{
public:
- Iterator(QDir::Filters filters, const QStringList &filterNames)
- : QAbstractFileEngineIterator(filters, filterNames)
+ Iterator(const QString &path, QDir::Filters filters, const QStringList &filterNames)
+ : QAbstractFileEngineIterator(path, filters, filterNames)
{
names.append("foo");
names.append("bar");
index = -1;
}
- QString currentFileName() const
- {
- return names.at(index);
- }
- bool hasNext() const
+ QString currentFileName() const override
{
- return index < names.size() - 1;
+ if (!names.isEmpty() && index < names.size())
+ return names.at(index);
+ return {};
}
- QString next()
+ bool advance() override
{
- if (!hasNext())
- return QString();
- ++index;
- return currentFilePath();
+ if (names.isEmpty())
+ return false;
+ if (index < names.size() - 1) {
+ ++index;
+ return true;
+ }
+ return false;
}
QStringList names;
int index;
@@ -530,11 +462,13 @@ public:
: QFSFileEngine(fileName)
{
}
- Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames)
+
+ IteratorUniquePtr
+ beginEntryList(const QString &path, QDir::Filters filters, const QStringList &filterNames) override
{
- return new Iterator(filters, filterNames);
+ return std::make_unique<Iterator>(path, filters, filterNames);
}
- FileFlags fileFlags(FileFlags type) const
+ FileFlags fileFlags(FileFlags type) const override
{
if (fileName(DefaultName).endsWith(".tar")) {
FileFlags ret = QFSFileEngine::fileFlags(type);
@@ -556,18 +490,27 @@ QHash<QString, QSharedPointer<ReferenceFileEngine::File> > ReferenceFileEngine::
class FileEngineHandler
: QAbstractFileEngineHandler
{
- QAbstractFileEngine *create(const QString &fileName) const
+ Q_DISABLE_COPY_MOVE(FileEngineHandler)
+ std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override
{
if (fileName.endsWith(".tar") || fileName.contains(".tar/"))
- return new MountingFileEngine(fileName);
- if (fileName.startsWith("QFSFileEngine:"))
- return new QFSFileEngine(fileName.mid(14));
- if (fileName.startsWith("reference-file-engine:"))
- return new ReferenceFileEngine(fileName.mid(22));
- if (fileName.startsWith("resource:"))
- return QAbstractFileEngine::create(QLatin1String(":/tst_qabstractfileengine/resources/") + fileName.mid(9));
- return 0;
+ return std::make_unique<MountingFileEngine>(fileName);
+
+ if (auto l1 = "QFSFileEngine:"_L1; fileName.startsWith(l1))
+ return std::make_unique<QFSFileEngine>(fileName.sliced(l1.size()));
+
+ if (auto l1 = "reference-file-engine:"_L1; fileName.startsWith(l1))
+ return std::make_unique<ReferenceFileEngine>(fileName.sliced(l1.size()));
+
+ if (auto l1 = "resource:"_L1; fileName.startsWith(l1)) {
+ const auto p = ":/tst_qabstractfileengine/resources/"_L1 + fileName.sliced(l1.size());
+ return QAbstractFileEngine::create(p);
+ }
+
+ return nullptr;
}
+public:
+ FileEngineHandler() = default;
};
void tst_QAbstractFileEngine::initTestCase()
@@ -583,12 +526,13 @@ void tst_QAbstractFileEngine::cleanupTestCase()
bool failed = false;
FileEngineHandler handler;
- Q_FOREACH(QString file, filesForRemoval)
+ for (const QString &file : std::as_const(filesForRemoval)) {
if (!QFile::remove(file)
|| QFile::exists(file)) {
failed = true;
qDebug() << "Couldn't remove file:" << file;
}
+ }
QVERIFY(!failed);
@@ -597,9 +541,9 @@ void tst_QAbstractFileEngine::cleanupTestCase()
void tst_QAbstractFileEngine::customHandler()
{
- QScopedPointer<QAbstractFileEngine> file;
+ std::unique_ptr<QAbstractFileEngine> file;
{
- file.reset(QAbstractFileEngine::create("resource:file.txt"));
+ file = QAbstractFileEngine::create(u"resource:file.txt"_s);
QVERIFY(file);
}
@@ -677,12 +621,12 @@ void tst_QAbstractFileEngine::fileIO()
* the original size + the '\r' characters added by autocrlf. */
QFile::OpenMode openMode = QIODevice::ReadOnly | QIODevice::Unbuffered;
-#ifdef Q_OS_WIN
+#if defined (Q_OS_WIN) || defined(Q_OS_WASM)
openMode |= QIODevice::Text;
#endif
QVERIFY(file.open(openMode));
QVERIFY(file.isOpen());
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) || defined(Q_OS_WASM)
const qint64 convertedSize = fileSize + readContent.count('\n');
if (file.size() == convertedSize)
fileSize = convertedSize;
@@ -894,7 +838,8 @@ void tst_QAbstractFileEngine::mounting()
QCOMPARE(dir.entryList(), (QStringList() << "bar" << "foo"));
QDir dir2(fs.path());
bool found = false;
- foreach (QFileInfo info, dir2.entryInfoList()) {
+ const auto entries = dir2.entryInfoList();
+ for (const QFileInfo &info : entries) {
if (info.fileName() == QLatin1String("test.tar")) {
QVERIFY(!found);
found = true;
diff --git a/tests/auto/corelib/io/qbuffer/CMakeLists.txt b/tests/auto/corelib/io/qbuffer/CMakeLists.txt
new file mode 100644
index 0000000000..87022451a0
--- /dev/null
+++ b/tests/auto/corelib/io/qbuffer/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbuffer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbuffer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbuffer
+ SOURCES
+ tst_qbuffer.cpp
+)
diff --git a/tests/auto/corelib/io/qbuffer/qbuffer.pro b/tests/auto/corelib/io/qbuffer/qbuffer.pro
deleted file mode 100644
index 76b1088595..0000000000
--- a/tests/auto/corelib/io/qbuffer/qbuffer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qbuffer
-QT = core testlib
-SOURCES = tst_qbuffer.cpp
diff --git a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
index 4968742110..acfd60e224 100644
--- a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
+++ b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp
@@ -1,47 +1,28 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QTestEventLoop>
#include <QBuffer>
#include <QByteArray>
+#include <QElapsedTimer>
+
+#include <string>
class tst_QBuffer : public QObject
{
Q_OBJECT
private slots:
void open();
+ void openWriteOnlyDoesNotTruncate();
void getSetCheck();
void readBlock();
void readBlockPastEnd();
void writeBlock_data();
void writeBlock();
void seek();
+ void invalidSeeks();
void seekTest_data();
void seekTest();
void read_rawdata();
@@ -57,6 +38,7 @@ private slots:
void readLineBoundaries();
void getAndUngetChar();
void writeAfterQByteArrayResize();
+ void writeOfMoreThan2GiB();
void read_null();
protected slots:
@@ -130,6 +112,29 @@ void tst_QBuffer::open()
b.close();
}
+void tst_QBuffer::openWriteOnlyDoesNotTruncate()
+{
+ QBuffer b;
+ const auto data = QByteArrayLiteral("Hey, presto!");
+
+ {
+ QVERIFY(b.open(QIODevice::WriteOnly));
+ b.write(data);
+ b.close();
+ }
+ {
+ QVERIFY(b.open(QIODevice::ReadOnly));
+ QCOMPARE(b.readAll(), data);
+ b.close();
+ }
+ {
+ QVERIFY(b.open(QIODevice::WriteOnly));
+ QCOMPARE(b.size(), data.size());
+ QCOMPARE(b.pos(), 0);
+ b.close();
+ }
+}
+
// some status() tests, too
void tst_QBuffer::readBlock()
{
@@ -286,6 +291,29 @@ void tst_QBuffer::seek()
QCOMPARE(buffer.size(), pos);
}
+void tst_QBuffer::invalidSeeks()
+{
+ if constexpr (sizeof(qsizetype) == sizeof(qint64)) {
+ // sizeof(qsizetype) == sizeof(qint64), so +1 would overflow
+ QSKIP("This is a 32-bit-only test.");
+ } else {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QCOMPARE(buffer.buffer().size(), qsizetype(0));
+ QCOMPARE(buffer.pos(), qint64(0));
+ constexpr qint64 MaxQByteArrayCapacity = (std::numeric_limits<qsizetype>::max)();
+ // this should fail fast, not after trying to allocate nearly 2 GiB of data,
+ // potentially crashing in the process:
+ QVERIFY(!buffer.seek(2 * MaxQByteArrayCapacity - 1));
+ QCOMPARE(buffer.buffer().size(), qsizetype(0));
+ QCOMPARE(buffer.pos(), qint64(0));
+ // ditto:
+ QVERIFY(!buffer.seek(MaxQByteArrayCapacity + 1));
+ QCOMPARE(buffer.buffer().size(), qsizetype(0));
+ QCOMPARE(buffer.pos(), qint64(0));
+ }
+}
+
void tst_QBuffer::seekTest_data()
{
writeBlock_data();
@@ -598,6 +626,55 @@ void tst_QBuffer::writeAfterQByteArrayResize()
QCOMPARE(buffer.buffer().size(), 1000);
}
+void tst_QBuffer::writeOfMoreThan2GiB()
+{
+ if constexpr (sizeof(void*) == 4)
+ QSKIP("This is a 64-bit-only test");
+
+ [[maybe_unused]] constexpr size_t GiB = 1024 * 1024 * 1024;
+
+#ifndef QT_NO_EXCEPTIONS
+
+ try {
+ //
+ // GIVEN: an empty QBuffer open for writing
+ //
+ QBuffer buffer;
+ QVERIFY(buffer.open(QIODevice::WriteOnly));
+
+ //
+ // WHEN: writing more than 2GiB in a singe chunk:
+ //
+ QElapsedTimer timer;
+ timer.start();
+
+ const std::string input(2 * GiB + 1, 42);
+
+ qDebug("created dataset in %lld ms", timer.restart());
+
+ const auto inputSize = qint64(input.size());
+
+ QCOMPARE(buffer.write(input.data(), inputSize), inputSize);
+
+ qDebug("performed write in %lld ms", timer.restart());
+
+ //
+ // THEN: the buffer contains the written data
+ //
+ QCOMPARE(buffer.buffer().size(), inputSize);
+ QVERIFY(buffer.buffer() == QByteArrayView{input});
+
+ qDebug("verified result in %lld ms", timer.elapsed());
+
+ } catch (const std::bad_alloc &) {
+ QSKIP("Cannot allocate enough memory for this test");
+ }
+
+#else
+ QSKIP("This test requires exceptions enabled.");
+#endif // QT_NO_EXCEPTIONS
+}
+
void tst_QBuffer::read_null()
{
QByteArray buffer;
diff --git a/tests/auto/corelib/io/qdataurl/CMakeLists.txt b/tests/auto/corelib/io/qdataurl/CMakeLists.txt
new file mode 100644
index 0000000000..4157db90d8
--- /dev/null
+++ b/tests/auto/corelib/io/qdataurl/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdataurl Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdataurl LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdataurl
+ SOURCES
+ tst_qdataurl.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/io/qdataurl/qdataurl.pro b/tests/auto/corelib/io/qdataurl/qdataurl.pro
deleted file mode 100644
index 7085c9d881..0000000000
--- a/tests/auto/corelib/io/qdataurl/qdataurl.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdataurl
-QT = core core-private testlib
-SOURCES = tst_qdataurl.cpp
diff --git a/tests/auto/corelib/io/qdataurl/tst_qdataurl.cpp b/tests/auto/corelib/io/qdataurl/tst_qdataurl.cpp
index 66720d28e0..e694a79101 100644
--- a/tests/auto/corelib/io/qdataurl/tst_qdataurl.cpp
+++ b/tests/auto/corelib/io/qdataurl/tst_qdataurl.cpp
@@ -1,77 +1,58 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "private/qdataurl_p.h"
-#include <QtTest/QtTest>
+#include <QTest>
#include <QtCore/QDebug>
+using namespace Qt::Literals;
+
class tst_QDataUrl : public QObject
{
Q_OBJECT
private slots:
- void nonData();
- void emptyData();
- void alreadyPercentageEncoded();
+ void decode_data();
+ void decode();
};
-void tst_QDataUrl::nonData()
+void tst_QDataUrl::decode_data()
{
- QLatin1String data("http://test.com");
- QUrl url(data);
- QString mimeType;
- QByteArray payload;
- bool result = qDecodeDataUrl(url, mimeType, payload);
- QVERIFY(!result);
-}
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<bool>("result");
+ QTest::addColumn<QString>("mimeType");
+ QTest::addColumn<QByteArray>("payload");
-void tst_QDataUrl::emptyData()
-{
- QLatin1String data("data:text/plain");
- QUrl url(data);
- QString mimeType;
- QByteArray payload;
- bool result = qDecodeDataUrl(url, mimeType, payload);
- QVERIFY(result);
- QCOMPARE(mimeType, QLatin1String("text/plain;charset=US-ASCII"));
- QVERIFY(payload.isNull());
+ auto row = [](const char *tag, const char *url, bool success, QString mimeType = {}, QByteArray payload = {}) {
+ QTest::newRow(tag) << url << success <<mimeType << payload;
+ };
+
+ row("nonData", "http://test.com", false);
+ row("emptyData", "data:text/plain", true,
+ "text/plain;charset=US-ASCII"_L1);
+ row("alreadyPercentageEncoded", "data:text/plain,%E2%88%9A", true,
+ "text/plain"_L1, QByteArray::fromPercentEncoding("%E2%88%9A"));
+ row("everythingIsCaseInsensitive", "Data:texT/PlaiN;charSet=iSo-8859-1;Base64,SGVsbG8=", true,
+ "texT/PlaiN;charSet=iSo-8859-1"_L1, QByteArrayLiteral("Hello"));
}
-void tst_QDataUrl::alreadyPercentageEncoded()
+void tst_QDataUrl::decode()
{
- QLatin1String data("data:text/plain,%E2%88%9A");
- QUrl url(data);
- QString mimeType;
- QByteArray payload;
- bool result = qDecodeDataUrl(url, mimeType, payload);
- QVERIFY(result);
- QCOMPARE(mimeType, QLatin1String("text/plain"));
- QCOMPARE(payload, QByteArray::fromPercentEncoding("%E2%88%9A"));
+ QFETCH(const QString, input);
+ QFETCH(const bool, result);
+ QFETCH(const QString, mimeType);
+ QFETCH(const QByteArray, payload);
+
+ QString actualMimeType;
+ QByteArray actualPayload;
+
+ QUrl url(input);
+ const bool actualResult = qDecodeDataUrl(url, actualMimeType, actualPayload);
+
+ QCOMPARE(actualResult, result);
+ QCOMPARE(actualMimeType, mimeType);
+ QCOMPARE(actualPayload, payload);
+ QCOMPARE(actualPayload.isNull(), payload.isNull()); // assume nullness is significant
}
QTEST_MAIN(tst_QDataUrl)
diff --git a/tests/auto/corelib/io/qdebug/CMakeLists.txt b/tests/auto/corelib/io/qdebug/CMakeLists.txt
new file mode 100644
index 0000000000..89d39c4375
--- /dev/null
+++ b/tests/auto/corelib/io/qdebug/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdebug Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdebug LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdebug
+ SOURCES
+ tst_qdebug.cpp
+ LIBRARIES
+ Qt::Concurrent
+)
+
+if (APPLE)
+ enable_language(OBJCXX)
+ set_source_files_properties(tst_qdebug.cpp PROPERTIES LANGUAGE OBJCXX)
+endif()
diff --git a/tests/auto/corelib/io/qdebug/qdebug.pro b/tests/auto/corelib/io/qdebug/qdebug.pro
deleted file mode 100644
index 45c0aa4061..0000000000
--- a/tests/auto/corelib/io/qdebug/qdebug.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdebug
-QT = core testlib concurrent
-SOURCES = tst_qdebug.cpp
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index 7b8b1df166..15da0758d0 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -1,39 +1,51 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtCore/QtDebug>
-#include <QtTest/QtTest>
+#include <QTest>
#include <QtConcurrentRun>
#include <QFutureSynchronizer>
+#include <QVariant>
+#include <QSemaphore>
+#include <QLine>
+#include <QMimeType>
+#include <QMimeDatabase>
+#include <QMetaType>
+
+#include <q20chrono.h>
+
+#ifdef __cpp_lib_memory_resource
+# include <memory_resource>
+namespace pmr = std::pmr;
+#else
+namespace pmr = std;
+#endif
+
+using namespace std::chrono;
+using namespace q20::chrono;
+using namespace Qt::StringLiterals;
+
+static_assert(QTypeTraits::has_ostream_operator_v<QDebug, int>);
+static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMetaType>);
+static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QList<int>>);
+static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, QString>>);
+struct NonStreamable {};
+static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, NonStreamable>);
+static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QList<NonStreamable>>);
+static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, NonStreamable>>);
+struct ConvertsToQVariant {
+ operator QVariant() {return QVariant::fromValue(*this);};
+};
+static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, ConvertsToQVariant>);
+
+#if defined(Q_OS_DARWIN)
+#include <objc/runtime.h>
+#include <Foundation/Foundation.h>
+#endif
class tst_QDebug: public QObject
{
@@ -49,6 +61,7 @@ private slots:
void assignment() const;
void warningWithoutDebug() const;
void criticalWithoutDebug() const;
+ void basics() const;
void debugWithBool() const;
void debugSpaceHandling() const;
void debugNoQuotes() const;
@@ -56,16 +69,39 @@ private slots:
void stateSaver() const;
void veryLongWarningMessage() const;
void qDebugQChar() const;
+ void qDebugQMetaType() const;
void qDebugQString() const;
- void qDebugQStringRef() const;
void qDebugQStringView() const;
+ void qDebugQUtf8StringView() const;
void qDebugQLatin1String() const;
+ void qDebugStdString() const;
+ void qDebugStdStringView() const;
+ void qDebugStdWString() const;
+ void qDebugStdWStringView() const;
+ void qDebugStdU8String() const;
+ void qDebugStdU8StringView() const;
+ void qDebugStdU16String() const;
+ void qDebugStdU16StringView() const;
+ void qDebugStdU32String() const;
+ void qDebugStdU32StringView() const;
void qDebugQByteArray() const;
+ void qDebugQByteArrayView() const;
void qDebugQFlags() const;
+ void qDebugStdChrono_data() const;
+ void qDebugStdChrono() const;
+ void qDebugStdOptional() const;
void textStreamModifiers() const;
void resetFormat() const;
void defaultMessagehandler() const;
void threadSafety() const;
+ void toString() const;
+ void noQVariantEndlessRecursion() const;
+#if defined(Q_OS_DARWIN)
+ void objcInCppMode_data() const;
+ void objcInCppMode() const;
+ void objcInObjcMode_data() const;
+ void objcInObjcMode() const;
+#endif
};
void tst_QDebug::assignment() const
@@ -155,6 +191,46 @@ void tst_QDebug::criticalWithoutDebug() const
QCOMPARE(QString::fromLatin1(s_function), function);
}
+void tst_QDebug::basics() const
+{
+ // test simple types, without quoting or other modifications
+ // (bool tested in the next function)
+ MessageHandlerSetter mhs(myMessageHandler);
+
+ qDebug() << 'X';
+ QCOMPARE(s_msg, "X");
+
+ qDebug() << 123;
+ QCOMPARE(s_msg, "123");
+
+ qDebug() << 456U;
+ QCOMPARE(s_msg, "456");
+
+ qDebug() << -123L;
+ QCOMPARE(s_msg, "-123");
+
+ qDebug() << 456UL;
+ QCOMPARE(s_msg, "456");
+
+ qDebug() << Q_INT64_C(-123);
+ QCOMPARE(s_msg, "-123");
+
+ qDebug() << Q_UINT64_C(456);
+ QCOMPARE(s_msg, "456");
+
+ qDebug() << "Hello";
+ QCOMPARE(s_msg, "Hello");
+
+ qDebug() << u"World";
+ QCOMPARE(s_msg, "World");
+
+ qDebug() << (void *)0xfff;
+ QCOMPARE(s_msg, "0xfff");
+
+ qDebug() << nullptr;
+ QCOMPARE(s_msg, "(nullptr)");
+}
+
void tst_QDebug::debugWithBool() const
{
QString file, function;
@@ -243,11 +319,17 @@ void tst_QDebug::debugNoQuotes() const
MessageHandlerSetter mhs(myMessageHandler);
{
QDebug d = qDebug();
+ QVERIFY(d.quoteStrings());
d << QStringLiteral("Hello");
+ QVERIFY(d.quoteStrings());
d.noquote();
+ QVERIFY(!d.quoteStrings());
d << QStringLiteral("Hello");
+ QVERIFY(!d.quoteStrings());
d.quote();
+ QVERIFY(d.quoteStrings());
d << QStringLiteral("Hello");
+ QVERIFY(d.quoteStrings());
}
QCOMPARE(s_msg, QString::fromLatin1("\"Hello\" Hello \"Hello\""));
@@ -256,7 +338,7 @@ void tst_QDebug::debugNoQuotes() const
d << QChar('H');
d << QLatin1String("Hello");
d << QByteArray("Hello");
- d.noquote();
+ d.setQuoteStrings(false);
d << QChar('H');
d << QLatin1String("Hello");
d << QByteArray("Hello");
@@ -309,7 +391,7 @@ void tst_QDebug::stateSaver() const
QDebug d = qDebug();
{
QDebugStateSaver saver(d);
- d.nospace() << hex << right << qSetFieldWidth(3) << qSetPadChar('0') << 42;
+ d.nospace() << Qt::hex << Qt::right << qSetFieldWidth(3) << qSetPadChar('0') << 42;
}
d << 42;
}
@@ -327,7 +409,7 @@ void tst_QDebug::stateSaver() const
{
QDebug d = qDebug();
- d.noquote().nospace() << QStringLiteral("Hello") << hex << 42;
+ d.noquote().nospace() << QStringLiteral("Hello") << Qt::hex << 42;
{
QDebugStateSaver saver(d);
d.resetFormat();
@@ -381,6 +463,25 @@ void tst_QDebug::qDebugQChar() const
}
+void tst_QDebug::qDebugQMetaType() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << QMetaType::fromType<int>() << QMetaType::fromType<QString>();
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 4; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, R"(QMetaType(int) QMetaType(QString))"_L1);
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+}
+
void tst_QDebug::qDebugQString() const
{
/* Use a basic string. */
@@ -388,7 +489,7 @@ void tst_QDebug::qDebugQString() const
QString file, function;
int line = 0;
const QString in(QLatin1String("input"));
- const QStringRef inRef(&in);
+ const QStringView inRef{ in };
MessageHandlerSetter mhs(myMessageHandler);
{ qDebug() << inRef; }
@@ -453,60 +554,59 @@ void tst_QDebug::qDebugQString() const
QCOMPARE(s_msg, QString("\"\\U000E0001 \\U00100000\""));
// broken surrogate pairs
- ushort utf16[] = { 0xDC00, 0xD800, 'x', 0xD800, 0 };
+ char16_t utf16[] = { 0xDC00, 0xD800, 'x', 0xD800, 0 };
string = QString::fromUtf16(utf16);
qDebug() << string;
QCOMPARE(s_msg, QString("\"\\uDC00\\uD800x\\uD800\""));
}
-void tst_QDebug::qDebugQStringRef() const
+void tst_QDebug::qDebugQStringView() const
{
/* Use a basic string. */
{
- QString file, function;
+ QLatin1String file, function;
int line = 0;
- const QString in(QLatin1String("input"));
- const QStringRef inRef(&in);
+ const QStringView inView = u"input";
MessageHandlerSetter mhs(myMessageHandler);
- { qDebug() << inRef; }
+ { qDebug() << inView; }
#ifndef QT_NO_MESSAGELOGCONTEXT
- file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
+ file = QLatin1String(__FILE__); line = __LINE__ - 2; function = QLatin1String(Q_FUNC_INFO);
#endif
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QString::fromLatin1("\"input\""));
- QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_msg, QLatin1String("\"input\""));
+ QCOMPARE(QLatin1String(s_file), file);
QCOMPARE(s_line, line);
- QCOMPARE(QString::fromLatin1(s_function), function);
+ QCOMPARE(QLatin1String(s_function), function);
}
- /* Use a null QStringRef. */
+ /* Use a null QStringView. */
{
QString file, function;
int line = 0;
- const QStringRef inRef;
+ const QStringView inView;
MessageHandlerSetter mhs(myMessageHandler);
- { qDebug() << inRef; }
+ { qDebug() << inView; }
#ifndef QT_NO_MESSAGELOGCONTEXT
file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
#endif
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QString::fromLatin1("\"\""));
- QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_msg, QLatin1String("\"\""));
+ QCOMPARE(QLatin1String(s_file), file);
QCOMPARE(s_line, line);
- QCOMPARE(QString::fromLatin1(s_function), function);
+ QCOMPARE(QLatin1String(s_function), function);
}
}
-void tst_QDebug::qDebugQStringView() const
+void tst_QDebug::qDebugQUtf8StringView() const
{
- /* Use a basic string. */
+ /* Use a utf8 string. */
{
QLatin1String file, function;
int line = 0;
- const QStringView inView = QStringViewLiteral("input");
+ const QUtf8StringView inView = u8"\U0001F609 is ;-)";
MessageHandlerSetter mhs(myMessageHandler);
{ qDebug() << inView; }
@@ -514,18 +614,18 @@ void tst_QDebug::qDebugQStringView() const
file = QLatin1String(__FILE__); line = __LINE__ - 2; function = QLatin1String(Q_FUNC_INFO);
#endif
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QLatin1String("\"input\""));
+ QCOMPARE(s_msg, QString::fromUtf8("\"\\xF0\\x9F\\x98\\x89 is ;-)\""));
QCOMPARE(QLatin1String(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QLatin1String(s_function), function);
}
- /* Use a null QStringView. */
+ /* Use a null QUtf8StringView. */
{
QString file, function;
int line = 0;
- const QStringView inView;
+ const QUtf8StringView inView;
MessageHandlerSetter mhs(myMessageHandler);
{ qDebug() << inView; }
@@ -578,6 +678,324 @@ void tst_QDebug::qDebugQLatin1String() const
QCOMPARE(s_msg, QString("\"\\nSm\\u00F8rg\\u00E5sbord\\\\\""));
}
+void tst_QDebug::qDebugStdString() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << pmr::string("foo") << std::string("") << std::string("barbaz", 3);
+ d.nospace().noquote() << std::string("baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::string string("\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdString(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdString(string));
+}
+
+void tst_QDebug::qDebugStdStringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::string_view("foo") << std::string_view("") << std::string_view("barbaz", 3);
+ d.nospace().noquote() << std::string_view("baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::string_view string("\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdString(std::string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdString(std::string(string)));
+}
+
+void tst_QDebug::qDebugStdWString() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << pmr::wstring(L"foo") << std::wstring(L"") << std::wstring(L"barbaz", 3);
+ d.nospace().noquote() << std::wstring(L"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::wstring string(L"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdWString(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdWString(string));
+}
+
+void tst_QDebug::qDebugStdWStringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::wstring_view(L"foo") << std::wstring_view(L"") << std::wstring_view(L"barbaz", 3);
+ d.nospace().noquote() << std::wstring_view(L"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::wstring_view string(L"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdWString(std::wstring(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdWString(std::wstring(string)));
+}
+
+void tst_QDebug::qDebugStdU8String() const
+{
+#ifndef __cpp_lib_char8_t
+ QSKIP("This test requires C++20 char8_t support enabled in the compiler.");
+#else
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << pmr::u8string(u8"foo") << std::u8string(u8"") << std::u8string(u8"barbaz", 3);
+ d.nospace().noquote() << std::u8string(u8"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u8string string(u8"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QUtf8StringView(string).toString());
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QUtf8StringView(string).toString());
+#endif // __cpp_lib_char8_t
+}
+
+void tst_QDebug::qDebugStdU8StringView() const
+{
+#ifndef __cpp_lib_char8_t
+ QSKIP("This test requires C++20 char8_t support enabled in the compiler.");
+#else
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u16string_view(u"foo") << std::u16string_view(u"") << std::u16string_view(u"barbaz", 3);
+ d.nospace().noquote() << std::u16string_view(u"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u16string_view string(u"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU16String(std::u16string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU16String(std::u16string(string)));
+#endif // __cpp_lib_char8_t
+}
+
+void tst_QDebug::qDebugStdU16String() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << pmr::u16string(u"foo") << std::u16string(u"") << std::u16string(u"barbaz", 3);
+ d.nospace().noquote() << std::u16string(u"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u16string string(u"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU16String(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU16String(string));
+}
+
+void tst_QDebug::qDebugStdU16StringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u16string_view(u"foo") << std::u16string_view(u"") << std::u16string_view(u"barbaz", 3);
+ d.nospace().noquote() << std::u16string_view(u"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u16string_view string(u"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU16String(std::u16string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU16String(std::u16string(string)));
+}
+
+void tst_QDebug::qDebugStdU32String() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << pmr::u32string(U"foo") << std::u32string(U"") << std::u32string(U"barbaz", 3);
+ d.nospace().noquote() << std::u32string(U"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u32string string(U"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU32String(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU32String(string));
+}
+
+void tst_QDebug::qDebugStdU32StringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u32string_view(U"foo") << std::u32string_view(U"") << std::u32string_view(U"barbaz", 3);
+ d.nospace().noquote() << std::u32string_view(U"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u32string_view string(U"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU32String(std::u32string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU32String(std::u32string(string)));
+}
+
void tst_QDebug::qDebugQByteArray() const
{
QString file, function;
@@ -620,6 +1038,48 @@ void tst_QDebug::qDebugQByteArray() const
QCOMPARE(s_msg, QString("\"\\xFF\"\"FFFF\""));
}
+void tst_QDebug::qDebugQByteArrayView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << QByteArrayView("foo") << QByteArrayView("") << QByteArrayView("barbaz", 3);
+ d.nospace().noquote() << QByteArrayView("baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ QByteArrayView ba = "\"Hello\"";
+ qDebug() << ba;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << ba;
+ QCOMPARE(s_msg, QString::fromLatin1(ba));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << ba;
+ QCOMPARE(s_msg, " " + QString::fromLatin1(ba));
+
+ ba = "\nSm\xC3\xB8rg\xC3\xA5sbord\\";
+ qDebug().noquote().nospace() << ba;
+ QCOMPARE(s_msg, QString::fromUtf8(ba));
+
+ qDebug() << ba;
+ QCOMPARE(s_msg, QString("\"\\nSm\\xC3\\xB8rg\\xC3\\xA5sbord\\\\\""));
+
+ // ensure that it closes hex escape sequences correctly
+ qDebug() << QByteArrayView("\377FFFF");
+ QCOMPARE(s_msg, QString("\"\\xFF\"\"FFFF\""));
+}
+
enum TestEnum {
Flag1 = 0x1,
Flag2 = 0x10
@@ -655,12 +1115,135 @@ void tst_QDebug::qDebugQFlags() const
QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::FlagType>(EnumFlag1)"));
}
+using ToStringFunction = std::function<QString()>;
+void tst_QDebug::qDebugStdChrono_data() const
+{
+ using attoseconds = duration<int64_t, std::atto>;
+ using femtoseconds = duration<int64_t, std::femto>;
+ using picoseconds = duration<int64_t, std::pico>;
+ using centiseconds = duration<int64_t, std::centi>;
+ using deciseconds = duration<int64_t, std::deci>;
+
+ using quadriennia = duration<int, std::ratio_multiply<std::ratio<4>, years::period>>;
+ using decades = duration<int, std::ratio_multiply<years::period, std::deca>>; // decayears
+ using centuries = duration<int16_t, std::ratio_multiply<years::period, std::hecto>>; // hectoyears
+ using millennia = duration<int16_t, std::ratio_multiply<years::period, std::kilo>>; // kiloyears
+ using gigayears = duration<int8_t, std::ratio_multiply<years::period, std::giga>>;
+ using fortnights = duration<int, std::ratio_multiply<days::period, std::ratio<14>>>;
+ using microfortnights = duration<int64_t, std::ratio_multiply<fortnights::period, std::micro>>;
+ using telecom = duration<int64_t, std::ratio<1, 8000>>; // 8 kHz
+
+ using kiloseconds = duration<int64_t, std::kilo>;
+ using exaseconds = duration<int8_t, std::exa>;
+ using meter_per_light = duration<int64_t, std::ratio<1, 299'792'458>>;
+ using kilometer_per_light = duration<int64_t, std::ratio<1000, 299'792'458>>;
+
+ QTest::addColumn<ToStringFunction>("fn");
+ QTest::addColumn<QString>("expected");
+
+ auto addRow = [](const char *name, auto duration, const char *expected) {
+ auto toString = [duration]() { return QDebug::toString(duration); };
+ QTest::newRow(name) << ToStringFunction(toString) << expected;
+ };
+
+ addRow("1as", attoseconds{1}, "1as");
+ addRow("1fs", femtoseconds{1}, "1fs");
+ addRow("1ps", picoseconds{1}, "1ps");
+ addRow("0ns", 0ns, "0ns");
+ addRow("1000ns", 1000ns, "1000ns");
+ addRow("0us", 0us, "0us");
+ addRow("0ms", 0ms, "0ms");
+ addRow("1cs", centiseconds{1}, "1cs");
+ addRow("2ds", deciseconds{2}, "2ds");
+ addRow("-1s", -1s, "-1s");
+ addRow("0s", 0s, "0s");
+ addRow("1s", 1s, "1s");
+ addRow("60s", 60s, "60s");
+ addRow("1min", 1min, "1min");
+ addRow("1h", 1h, "1h");
+ addRow("1days", days{1}, "1d");
+ addRow("365days", days{365}, "365d");
+ addRow("1weeks", weeks{1}, "1wk");
+ addRow("1years", years{1}, "1yr"); // 365.2425 days
+ addRow("42years", years{42}, "42yr");
+
+ addRow("1ks", kiloseconds{1}, "1[1000]s");
+ addRow("2fortnights", fortnights{2}, "2[2]wk");
+ addRow("1quadriennia", quadriennia{1}, "1[4]yr");
+ addRow("1decades", decades{1}, "1[10]yr");
+ addRow("1centuries", centuries{1}, "1[100]yr");
+ addRow("1millennia", millennia{1}, "1[1000]yr");
+#if defined(Q_OS_LINUX) || defined(Q_OS_DARWIN)
+ // some OSes print the exponent differently
+ addRow("1Es", exaseconds{1}, "1[1e+18]s");
+ addRow("13gigayears", gigayears{13}, "13[1e+09]yr");
+#endif
+
+ // months are one twelfth of a Gregorian year, not 30 days
+ addRow("1months", months{1}, "1[2629746]s");
+
+ // weird units
+ addRow("2microfortnights", microfortnights{2}, "2[756/625]s");
+ addRow("1telecom", telecom{1}, "1[1/8000]s");
+ addRow("10m/c", meter_per_light{10}, "10[1/299792458]s");
+ addRow("10km/c", kilometer_per_light{10}, "10[500/149896229]s");
+
+ // real floting point
+ using fpsec = duration<double>;
+ using fpmsec = duration<double, std::milli>;
+ using fpnsec = duration<double, std::nano>;
+ addRow("1.0s", fpsec{1}, "1s");
+ addRow("1.5s", fpsec{1.5}, "1.5s");
+ addRow("1.0ms", fpmsec{1}, "1ms");
+ addRow("1.5ms", fpmsec{1.5}, "1.5ms");
+ addRow("1.0ns", fpnsec{1}, "1ns");
+ addRow("1.5ns", fpnsec{1.5}, "1.5ns");
+
+ // and some precision setting too
+ QTest::newRow("1.00000ns")
+ << ToStringFunction([]() {
+ QString buffer;
+ QDebug d(&buffer);
+ d.nospace() << qSetRealNumberPrecision(5) << Qt::fixed << fpnsec{1};
+ return buffer;
+ }) << "1.00000ns";
+}
+
+void tst_QDebug::qDebugStdChrono() const
+{
+ QFETCH(ToStringFunction, fn);
+ QFETCH(QString, expected);
+ QCOMPARE(fn(), expected);
+}
+
+void tst_QDebug::qDebugStdOptional() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ std::optional<QByteArray> notSet = std::nullopt;
+ std::optional<QByteArray> set("foo");
+ auto no = std::nullopt;
+ QDebug d = qDebug();
+ d << notSet << set << no;
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 4; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("nullopt std::optional(\"foo\") nullopt"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+}
+
void tst_QDebug::textStreamModifiers() const
{
QString file, function;
int line = 0;
MessageHandlerSetter mhs(myMessageHandler);
- { qDebug() << hex << short(0xf) << int(0xf) << unsigned(0xf) << long(0xf) << qint64(0xf) << quint64(0xf); }
+ { qDebug() << Qt::hex << short(0xf) << int(0xf) << unsigned(0xf) << long(0xf) << qint64(0xf) << quint64(0xf); }
#ifndef QT_NO_MESSAGELOGCONTEXT
file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
#endif
@@ -678,7 +1261,7 @@ void tst_QDebug::resetFormat() const
MessageHandlerSetter mhs(myMessageHandler);
{
QDebug d = qDebug();
- d.nospace().noquote() << hex << int(0xf);
+ d.nospace().noquote() << Qt::hex << int(0xf);
d.resetFormat() << int(0xf) << QStringLiteral("foo");
}
#ifndef QT_NO_MESSAGELOGCONTEXT
@@ -734,12 +1317,105 @@ void tst_QDebug::threadSafety() const
s_sema.release(numThreads);
sync.waitForFinished();
QMutexLocker lock(&s_mutex);
- QCOMPARE(s_messages.count(), numThreads);
+ QCOMPARE(s_messages.size(), numThreads);
for (int i = 0; i < numThreads; ++i) {
QCOMPARE(s_messages.at(i), QStringLiteral("doDebug"));
}
}
+void tst_QDebug::toString() const
+{
+ // By reference.
+ {
+ MyPoint point(3, 4);
+ QString expectedString;
+ QDebug stream(&expectedString);
+ stream.nospace() << point;
+ QCOMPARE(QDebug::toString(point), expectedString);
+ }
+
+ // By pointer.
+ {
+ QObject qobject;
+ qobject.setObjectName("test");
+ QString expectedString;
+ QDebug stream(&expectedString);
+ stream.nospace() << &qobject;
+ QCOMPARE(QDebug::toString(&qobject), expectedString);
+ }
+}
+
+void tst_QDebug::noQVariantEndlessRecursion() const
+{
+ ConvertsToQVariant conv;
+ QVariant var = QVariant::fromValue(conv);
+ QTest::ignoreMessage(QtDebugMsg, "QVariant(ConvertsToQVariant, )");
+ qDebug() << var;
+}
+
+#if defined(Q_OS_DARWIN)
+
+@interface MyObjcClass : NSObject
+@end
+
+@implementation MyObjcClass : NSObject
+- (NSString *)description
+{
+ return @"MyObjcClass is the best";
+}
+@end
+
+void tst_QDebug::objcInCppMode_data() const
+{
+ QTest::addColumn<objc_object *>("object");
+ QTest::addColumn<QString>("message");
+
+ QTest::newRow("nil") << static_cast<objc_object*>(nullptr) << QString::fromLatin1("(null)");
+
+ // Not an NSObject subclass
+ auto *nsproxy = reinterpret_cast<objc_object *>(class_createInstance(objc_getClass("NSProxy"), 0));
+ QTest::newRow("NSProxy") << nsproxy << QString::fromLatin1("<NSProxy: 0x%1>").arg(uintptr_t(nsproxy), 1, 16);
+
+ // Plain NSObject
+ auto *nsobject = reinterpret_cast<objc_object *>(class_createInstance(objc_getClass("NSObject"), 0));
+ QTest::newRow("NSObject") << nsobject << QString::fromLatin1("<NSObject: 0x%1>").arg(uintptr_t(nsobject), 1, 16);
+
+ auto str = QString::fromLatin1("foo");
+ QTest::newRow("NSString") << reinterpret_cast<objc_object*>(str.toNSString()) << str;
+
+ // Custom debug description
+ QTest::newRow("MyObjcClass") << reinterpret_cast<objc_object*>([[MyObjcClass alloc] init])
+ << QString::fromLatin1("MyObjcClass is the best");
+}
+
+void tst_QDebug::objcInCppMode() const
+{
+ QFETCH(objc_object *, object);
+ QFETCH(QString, message);
+
+ MessageHandlerSetter mhs(myMessageHandler);
+ { qDebug() << object; }
+
+ QCOMPARE(s_msg, message);
+}
+
+void tst_QDebug::objcInObjcMode_data() const
+{
+ objcInCppMode_data();
+}
+
+void tst_QDebug::objcInObjcMode() const
+{
+ QFETCH(objc_object *, object);
+ QFETCH(QString, message);
+
+ MessageHandlerSetter mhs(myMessageHandler);
+ { qDebug() << static_cast<id>(object); }
+
+ QCOMPARE(s_msg, message);
+}
+#endif
+
// Should compile: instentiation of unrelated operator<< should not cause cause compilation
// error in QDebug operators (QTBUG-47375)
class TestClassA {};
diff --git a/tests/auto/corelib/io/qdir/CMakeLists.txt b/tests/auto/corelib/io/qdir/CMakeLists.txt
new file mode 100644
index 0000000000..4032d7ac19
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/CMakeLists.txt
@@ -0,0 +1,103 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdir Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdir LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "testdir")
+list(APPEND test_data "testData")
+list(APPEND test_data "searchdir")
+list(APPEND test_data "resources")
+list(APPEND test_data "entrylist")
+list(APPEND test_data "types")
+list(APPEND test_data "tst_qdir.cpp")
+
+qt_internal_add_test(tst_qdir
+ SOURCES
+ tst_qdir.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+ TESTDATA ${test_data}
+)
+
+# Resources:
+set(qdir_resource_files
+ "resources/entryList/"
+)
+
+qt_internal_add_resource(tst_qdir "qdir"
+ PREFIX
+ "/tst_qdir/"
+ FILES
+ ${qdir_resource_files}
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qdir CONDITION CONFIG___contains___builtin_testdata
+ DEFINES
+ BUILTIN_TESTDATA
+)
+
+if(ANDROID)
+ # Resources:
+ set(android_testdata_resource_files
+ "entrylist/directory/dummy"
+ "entrylist/file"
+ "resources/entryList/file1.data"
+ "resources/entryList/file2.data"
+ "resources/entryList/file3.data"
+ "resources/entryList/file4.nothing"
+ "searchdir/subdir1/picker.png"
+ "searchdir/subdir2/picker.png"
+ "testData/empty"
+ "testdir/dir/qdir.pro"
+ "testdir/dir/qrc_qdir.cpp"
+ "testdir/dir/tmp/empty"
+ "testdir/dir/tst_qdir.cpp"
+ "testdir/spaces/foo. bar"
+ "testdir/spaces/foo.bar"
+ "tst_qdir.cpp"
+ "types/a"
+ "types/a.a"
+ "types/a.b"
+ "types/a.c"
+ "types/b"
+ "types/b.a"
+ "types/b.b"
+ "types/b.c"
+ "types/c"
+ "types/c.a"
+ "types/c.b"
+ "types/c.c"
+ "types/d.a/dummy"
+ "types/d.b/dummy"
+ "types/d.c/dummy"
+ "types/d/dummy"
+ "types/e.a/dummy"
+ "types/e.b/dummy"
+ "types/e.c/dummy"
+ "types/e/dummy"
+ "types/f.a/dummy"
+ "types/f.b/dummy"
+ "types/f.c/dummy"
+ "types/f/dummy"
+ )
+
+ qt_internal_add_resource(tst_qdir "android_testdata"
+ PREFIX
+ "/android_testdata"
+ FILES
+ ${android_testdata_resource_files}
+ )
+endif()
diff --git a/tests/auto/corelib/io/qdir/Info.plist b/tests/auto/corelib/io/qdir/Info.plist
index 7dc5622bde..e1f6fbe24a 100644
--- a/tests/auto/corelib/io/qdir/Info.plist
+++ b/tests/auto/corelib/io/qdir/Info.plist
@@ -6,8 +6,6 @@
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
- <key>CFBundleGetInfoString</key>
- <string>Created by Qt/QMake</string>
<key>CFBundleIconFile</key>
<string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>
<key>CFBundleIdentifier</key>
diff --git a/tests/auto/corelib/io/qdir/qdir.pro b/tests/auto/corelib/io/qdir/qdir.pro
deleted file mode 100644
index a8b106e250..0000000000
--- a/tests/auto/corelib/io/qdir/qdir.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdir
-QT = core core-private testlib
-SOURCES = tst_qdir.cpp
-RESOURCES += qdir.qrc
-ios: QMAKE_INFO_PLIST = Info.plist
-
-TESTDATA += testdir testData searchdir resources entrylist types tst_qdir.cpp
-
-contains(CONFIG, builtin_testdata): DEFINES += BUILTIN_TESTDATA
-
-android:!android-embedded {
- RESOURCES += android_testdata.qrc
-}
diff --git a/tests/auto/corelib/io/qdir/qdir.qrc b/tests/auto/corelib/io/qdir/qdir.qrc
deleted file mode 100644
index 4c5b5af3b8..0000000000
--- a/tests/auto/corelib/io/qdir/qdir.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/tst_qdir/">
- <file>resources/entryList/</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+mac/test b/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+mac/test
+++ b/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+mac/test5 b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+mac/test5
+++ b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+osx/test b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+osx/test
+++ b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt b/tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt
new file mode 100644
index 0000000000..d0ec6dee9a
--- /dev/null
+++ b/tests/auto/corelib/io/qdir/testdir/dir/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## qdir Binary:
+#####################################################################
+
+qt_internal_add_executable(qdir
+ GUI
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro b/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro
index 856d5ea2fb..e69de29bb2 100644
--- a/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro
+++ b/tests/auto/corelib/io/qdir/testdir/dir/qdir.pro
@@ -1,3 +0,0 @@
-
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp b/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp
index a1d5c2c9ff..b9f84b6006 100644
--- a/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/testdir/dir/qrc_qdir.cpp
@@ -1,29 +1,4 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
diff --git a/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp
index a1d5c2c9ff..b9f84b6006 100644
--- a/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/testdir/dir/tst_qdir.cpp
@@ -1,29 +1,4 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 34588b19bc..b19f158746 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -1,33 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QTemporaryFile>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
#include <qcoreapplication.h>
#include <qdebug.h>
@@ -37,11 +17,10 @@
#if defined(Q_OS_WIN)
#include <QtCore/private/qfsfileengine_p.h>
-#include "../../../network-settings.h"
#endif
#if defined(Q_OS_WIN) && !defined(_WIN32_WINNT)
-#define _WIN32_WINNT 0x500
+#define _WIN32_WINNT 0x0A00
#endif
#include "../../../../shared/filesystem.h"
@@ -51,7 +30,11 @@
# include <sys/stat.h>
#endif
-#if defined(Q_OS_VXWORKS) || defined(Q_OS_WINRT)
+#ifdef Q_OS_INTEGRITY
+#include "qplatformdefs.h"
+#endif
+
+#if defined(Q_OS_VXWORKS)
#define Q_NO_SYMLINKS
#endif
@@ -65,6 +48,8 @@
#include "private/qdir_p.h"
#endif
+using namespace Qt::StringLiterals;
+
static QByteArray msgDoesNotExist(const QString &name)
{
return (QLatin1Char('"') + QDir::toNativeSeparators(name)
@@ -106,6 +91,8 @@ private slots:
void mkdirRmdir_data();
void mkdirRmdir();
void mkdirOnSymlink();
+ void mkdirWithPermissions_data();
+ void mkdirWithPermissions();
void makedirReturnCode();
@@ -140,6 +127,7 @@ private slots:
void normalizePathSegments();
#endif
+ void compareCompiles();
void compare();
void QDir_default();
@@ -216,34 +204,41 @@ private slots:
void emptyDir();
void nonEmptyDir();
+ void stdfilesystem();
+
private:
-#ifdef BUILTIN_TESTDATA
- QString m_dataPath;
QSharedPointer<QTemporaryDir> m_dataDir;
-#else
- const QString m_dataPath;
-#endif
+ QString m_dataPath;
+
+ constexpr static const std::array m_testDirs = {
+ "entrylist"_L1,
+ "resources"_L1,
+ "searchdir"_L1,
+ "testData"_L1,
+ "testdir"_L1,
+ "types"_L1,
+ "tst_qdir.cpp"_L1,
+ };
};
Q_DECLARE_METATYPE(tst_QDir::UncHandling)
tst_QDir::tst_QDir()
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
: m_dataPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
#elif !defined(BUILTIN_TESTDATA)
: m_dataPath(QFileInfo(QFINDTESTDATA("testData")).absolutePath())
#endif
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QString resourceSourcePath = QStringLiteral(":/android_testdata/");
QDirIterator it(resourceSourcePath, QDirIterator::Subdirectories);
while (it.hasNext()) {
- it.next();
-
- QFileInfo fileInfo = it.fileInfo();
+ QFileInfo fileInfo = it.nextFileInfo();
if (!fileInfo.isDir()) {
- QString destination = m_dataPath + QLatin1Char('/') + fileInfo.filePath().mid(resourceSourcePath.length());
+ QString destination = m_dataPath + QLatin1Char('/')
+ + fileInfo.filePath().mid(resourceSourcePath.length());
QFileInfo destinationFileInfo(destination);
if (!destinationFileInfo.exists()) {
QDir().mkpath(destinationFileInfo.path());
@@ -271,6 +266,20 @@ void tst_QDir::initTestCase()
m_dataDir = QEXTRACTTESTDATA("/");
QVERIFY2(!m_dataDir.isNull(), qPrintable("Did not find testdata. Is this builtin?"));
m_dataPath = m_dataDir->path();
+#elif QT_CONFIG(cxx17_filesystem) // This code doesn't work in QNX on the CI
+ m_dataDir.reset(new QTemporaryDir);
+ m_dataPath = m_dataDir->path();
+
+ QString sourceDir = QFileInfo(QFINDTESTDATA(m_testDirs[0])).absolutePath();
+ namespace fs = std::filesystem;
+ for (const auto &entry : m_testDirs) {
+ auto l1 = QLatin1StringView(entry);
+ const auto src = fs::path(QString(sourceDir + u'/' + l1).toStdString());
+ const auto dest = fs::path(QString(m_dataPath + u'/' + l1).toStdString());
+ std::error_code ec;
+ fs::copy(src, dest, fs::copy_options::recursive, ec);
+ QCOMPARE(ec.value(), 0);
+ }
#endif
QVERIFY2(!m_dataPath.isEmpty(), "test data not found");
@@ -332,6 +341,7 @@ void tst_QDir::setPath()
QFETCH(QString, dir1);
QFETCH(QString, dir2);
+ QDir::setCurrent(m_dataPath + "/entrylist"_L1);
QDir shared;
QDir qDir1(dir1);
QStringList entries1 = qDir1.entryList();
@@ -349,21 +359,21 @@ void tst_QDir::mkdirRmdir_data()
QTest::addColumn<QString>("path");
QTest::addColumn<bool>("recurse");
- QStringList dirs;
- dirs << "testdir/one"
- << "testdir/two/three/four"
- << "testdir/../testdir/three";
- QTest::newRow("plain") << QDir::currentPath() + "/" + dirs.at(0) << false;
- QTest::newRow("recursive") << QDir::currentPath() + "/" + dirs.at(1) << true;
- QTest::newRow("with-..") << QDir::currentPath() + "/" + dirs.at(2) << false;
-
- QTest::newRow("relative-plain") << dirs.at(0) << false;
- QTest::newRow("relative-recursive") << dirs.at(1) << true;
- QTest::newRow("relative-with-..") << dirs.at(2) << false;
+ const struct {
+ const char *name; // shall have a prefix added
+ const char *path; // relative
+ bool recurse;
+ } cases[] = {
+ { "plain", "testdir/one", false },
+ { "recursive", "testdir/two/three/four", true },
+ { "with-..", "testdir/../testdir/three", false },
+ };
- // Ensure that none of these directories already exist
- for (int i = 0; i < dirs.count(); ++i)
- QVERIFY(!QFile::exists(dirs.at(i)));
+ for (const auto &it : cases) {
+ QVERIFY(!QFile::exists(it.path));
+ QTest::addRow("absolute-%s", it.name) << (QDir::currentPath() + "/") + it.path << it.recurse;
+ QTest::addRow("relative-%s", it.name) << QString::fromLatin1(it.path) << it.recurse;
+ }
}
void tst_QDir::mkdirRmdir()
@@ -394,7 +404,7 @@ void tst_QDir::mkdirRmdir()
void tst_QDir::mkdirOnSymlink()
{
-#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS)
+#if !defined(Q_OS_UNIX) || defined(Q_NO_SYMLINKS) || defined(Q_OS_INTEGRITY)
QSKIP("Test only valid on an OS that supports symlinks");
#else
// Create the structure:
@@ -438,10 +448,55 @@ void tst_QDir::mkdirOnSymlink()
path = "two/four/five";
fi.setFile(path);
+#if defined(Q_OS_QNX)
+ QSKIP("Fails on QNX QTBUG-98561");
+#endif
QVERIFY2(fi.exists() && fi.isDir(), msgDoesNotExist(path).constData());
#endif
}
+void tst_QDir::mkdirWithPermissions_data()
+{
+ QTest::addColumn<QFile::Permissions>("permissions");
+
+ for (int u = 0; u < 8; ++u) {
+ for (int g = 0; g < 8; ++g) {
+ for (int o = 0; o < 8; ++o) {
+ auto permissions = QFileDevice::Permissions::fromInt((u << 12) | (g << 4) | o);
+ QTest::addRow("%04x", permissions.toInt()) << permissions;
+ }
+ }
+ }
+}
+
+void tst_QDir::mkdirWithPermissions()
+{
+ QFETCH(QFile::Permissions, permissions);
+
+#ifdef Q_OS_WIN
+ QNtfsPermissionCheckGuard permissionGuard;
+#endif
+#ifdef Q_OS_UNIX
+ auto restoreMask = qScopeGuard([oldMask = umask(0)] { umask(oldMask); });
+#endif
+
+ const QFile::Permissions setPermissions = {
+ QFile::ReadOther, QFile::WriteOther, QFile::ExeOther,
+ QFile::ReadGroup, QFile::WriteGroup, QFile::ExeGroup,
+ QFile::ReadOwner, QFile::WriteOwner, QFile::ExeOwner
+ };
+
+ const QString path = u"tmpdir"_s;
+ QDir dir;
+ auto deleteDirectory = qScopeGuard([&dir, &path] { dir.rmdir(path); });
+
+ QVERIFY(dir.mkdir(path, permissions));
+ auto actualPermissions = QFileInfo(dir.filePath(path)).permissions();
+ QCOMPARE(actualPermissions & setPermissions, permissions);
+ QVERIFY(dir.rmdir(path));
+ deleteDirectory.dismiss();
+}
+
void tst_QDir::makedirReturnCode()
{
QString dirName = QString::fromLatin1("makedirReturnCode");
@@ -457,10 +512,15 @@ void tst_QDir::makedirReturnCode()
QVERIFY(!QDir::current().mkdir(dirName)); // calling mkdir on an existing dir will fail.
QVERIFY(QDir::current().mkpath(dirName)); // calling mkpath on an existing dir will pass
+ // the next line specifically targets Windows and macOS (QTBUG-85997, QTBUG-97110)
+ // calling mkpath on an existing drive name (Windows) or root path (macOS) shall pass
+ QVERIFY(QDir().mkpath(QDir::rootPath()));
+ QVERIFY(!QDir().mkdir(QDir::rootPath()));
+
// Remove the directory and create a file with the same path
QDir::current().rmdir(dirName);
QVERIFY(!f.exists());
- f.open(QIODevice::WriteOnly);
+ QVERIFY(f.open(QIODevice::WriteOnly));
f.write("test");
f.close();
QVERIFY2(f.exists(), msgDoesNotExist(f.fileName()).constData());
@@ -481,12 +541,12 @@ void tst_QDir::removeRecursively_data()
<< tmpdir + "two/three"
<< "relative";
QDir dir;
- for (int i = 0; i < dirs.count(); ++i)
+ for (int i = 0; i < dirs.size(); ++i)
dir.mkpath(dirs.at(i));
QStringList files;
files << tmpdir + "one/file";
files << tmpdir + "two/three/file";
- for (int i = 0; i < files.count(); ++i) {
+ for (int i = 0; i < files.size(); ++i) {
QFile file(files.at(i));
QVERIFY(file.open(QIODevice::WriteOnly));
file.write("Hello");
@@ -528,7 +588,7 @@ void tst_QDir::removeRecursivelyFailure()
#ifdef Q_OS_UNIX
QFile dirAsFile(path); // yay, I have to use QFile to change a dir's permissions...
- QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions
+ QVERIFY(dirAsFile.setPermissions({})); // no permissions
QVERIFY(!QDir().rmdir(path));
QDir dir(path);
@@ -554,7 +614,7 @@ void tst_QDir::removeRecursivelySymlink()
QDir().mkpath(tmpdir);
QDir currentDir;
currentDir.mkdir("myDir");
- QFile("testfile").open(QIODevice::WriteOnly);
+ QVERIFY(QFile("testfile").open(QIODevice::WriteOnly));
const QString link = tmpdir + "linkToDir.lnk";
const QString linkToFile = tmpdir + "linkToFile.lnk";
#ifndef Q_NO_SYMLINKS_TO_DIRS
@@ -585,8 +645,8 @@ void tst_QDir::exists_data()
QTest::newRow("simple dir") << (m_dataPath + "/resources") << true;
QTest::newRow("simple dir with slash") << (m_dataPath + "/resources/") << true;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
+#if defined(Q_OS_WIN)
+ const QString uncRoot = QStringLiteral("//") + QTest::uncServerName();
QTest::newRow("unc 1") << uncRoot << true;
QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << true;
QTest::newRow("unc 3") << uncRoot + "/testshare" << true;
@@ -597,7 +657,7 @@ void tst_QDir::exists_data()
QTest::newRow("unc 8") << uncRoot + "/asharethatshouldnotexist" << false;
QTest::newRow("unc 9") << "//ahostthatshouldnotexist" << false;
#endif
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
+#if defined (Q_OS_WIN)
QTest::newRow("This drive should exist") << "C:/" << true;
// find a non-existing drive and check if it does not exist
#ifdef QT_BUILD_INTERNAL
@@ -664,32 +724,29 @@ void tst_QDir::QDir_default()
QCOMPARE(dir.absolutePath(), QDir::currentPath());
}
-void tst_QDir::compare()
+void tst_QDir::compareCompiles()
{
- // operator==
-
- // Not using QCOMPARE to test result of QDir::operator==
+ QTestPrivate::testEqualityOperatorsCompile<QDir>();
+}
+void tst_QDir::compare()
+{
QDir dir;
dir.makeAbsolute();
- QVERIFY(dir == QDir::currentPath());
+ QT_TEST_EQUALITY_OPS(dir, QDir::currentPath(), true);
QCOMPARE(QDir(), QDir(QDir::currentPath()));
- QVERIFY(QDir("../") == QDir(QDir::currentPath() + "/.."));
+
+ QT_TEST_EQUALITY_OPS(QDir("../"), QDir(QDir::currentPath() + "/.."), true);
}
-static QStringList filterLinks(const QStringList &list)
+static QStringList filterLinks(QStringList &&list)
{
-#ifndef Q_NO_SYMLINKS
- return list;
-#else
- QStringList result;
- foreach (QString str, list) {
- if (!str.endsWith(QLatin1String(".lnk")))
- result.append(str);
- }
- return result;
+#ifdef Q_NO_SYMLINKS
+ auto isDotLnk = [](const auto &s) { return s.endsWith(".lnk"_L1); };
+ list.removeIf(isDotLnk);
#endif
+ return std::move(list);
}
void tst_QDir::entryList_data()
@@ -713,13 +770,16 @@ void tst_QDir::entryList_data()
<< QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(',');
QTest::newRow("testdir1") << (m_dataPath + "/testdir") << QStringList()
<< (int)(QDir::AllDirs) << (int)(QDir::NoSort)
- << QString(".,..,dir,spaces").split(',');
+ << QString(".,..,dir,dir.lnk,spaces").split(',');
QTest::newRow("resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
<< (int)(QDir::NoFilter) << (int)(QDir::NoSort)
<< QString("file1.data,file2.data,file3.data").split(',');
QTest::newRow("resources2") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data")
<< (int)(QDir::Files) << (int)(QDir::NoSort)
<< QString("file1.data,file2.data,file3.data").split(',');
+ QTest::newRow("testdir.lnk") << (m_dataPath + "/testdir/dir.lnk") << QStringList()
+ << (int)(QDir::NoFilter) << (int)(QDir::NoSort)
+ << QString(".,..,aaaaa.txt,subdir,subdir.lnk").split(',');
}
void tst_QDir::entryList()
@@ -753,6 +813,12 @@ void tst_QDir::entryListWithTestFiles_data()
QTest::newRow("QDir::AllEntries") << (m_dataPath + "/entrylist/") << QStringList("*")
<< int(QDir::AllEntries) << int(QDir::Name)
<< filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
+ // Tests an assert in QDirSortItemComparator, when QDir::LocaleAware is set
+ // a QCollator is used
+ QTest::newRow("QDir::AllEntries")
+ << (m_dataPath + "/entrylist/") << QStringList("*")
+ << int(QDir::AllEntries) << int(QDir::Name | QDir::LocaleAware)
+ << filterLinks(QString(".,..,directory,file,linktodirectory.lnk,linktofile.lnk,writable").split(','));
QTest::newRow("QDir::Files") << (m_dataPath + "/entrylist/") << QStringList("*")
<< int(QDir::Files) << int(QDir::Name)
<< filterLinks(QString("file,linktofile.lnk,writable").split(','));
@@ -884,14 +950,14 @@ void tst_QDir::entryListWithTestFiles()
#if defined(Q_OS_WIN)
// ### Sadly, this is a platform difference right now.
// Note we are using capital L in entryList on one side here, to test case-insensitivity
- const QVector<QPair<QString, QString> > symLinks =
+ const QList<QPair<QString, QString> > symLinks =
{
{m_dataPath + "/entryList/file", entrylistPath + "linktofile.lnk"},
{m_dataPath + "/entryList/directory", entrylistPath + "linktodirectory.lnk"},
{m_dataPath + "/entryList/nothing", entrylistPath + "brokenlink.lnk"}
};
#else
- const QVector<QPair<QString, QString> > symLinks =
+ const QList<QPair<QString, QString> > symLinks =
{
{"file", entrylistPath + "linktofile.lnk"},
{"directory", entrylistPath + "linktodirectory.lnk"},
@@ -956,7 +1022,7 @@ void tst_QDir::entryListTimedSort()
QFileInfo aFileInfo(aFile);
QFileInfo bFileInfo(bFile);
- QVERIFY(bFileInfo.lastModified().msecsTo(aFileInfo.lastModified()) < 0);
+ QVERIFY(bFileInfo.lastModified(QTimeZone::UTC).msecsTo(aFileInfo.lastModified(QTimeZone::UTC)) < 0);
QCOMPARE(actual.size(), 2);
QCOMPARE(actual.first(), bFileInfo.fileName());
@@ -975,8 +1041,8 @@ void tst_QDir::entryListSimple_data()
QTest::newRow("simple dir") << (m_dataPath + "/resources") << 2;
QTest::newRow("simple dir with slash") << (m_dataPath + "/resources/") << 2;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
+#if defined(Q_OS_WIN)
+ const QString uncRoot = QStringLiteral("//") + QTest::uncServerName();
QTest::newRow("unc 1") << uncRoot << 2;
QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << 2;
QTest::newRow("unc 3") << uncRoot + "/testshare" << 2;
@@ -1002,7 +1068,7 @@ void tst_QDir::entryListSimple()
QDir dir(dirName);
QStringList actual = dir.entryList();
- QVERIFY2(actual.count() >= countMin, msgEntryListFailed(actual.count(), countMin, dirName).constData());
+ QVERIFY2(actual.size() >= countMin, msgEntryListFailed(actual.size(), countMin, dirName).constData());
}
void tst_QDir::entryListWithSymLinks()
@@ -1015,7 +1081,7 @@ void tst_QDir::entryListWithSymLinks()
QFile::remove("testfile.cpp");
QDir dir;
dir.mkdir("myDir");
- QFile("testfile.cpp").open(QIODevice::WriteOnly);
+ QVERIFY(QFile("testfile.cpp").open(QIODevice::WriteOnly));
# ifndef Q_NO_SYMLINKS_TO_DIRS
QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
# endif
@@ -1211,11 +1277,11 @@ void tst_QDir::setNameFilters()
dir.setNameFilters(nameFilters);
QStringList actual = dir.entryList();
- int max = qMin(actual.count(), expected.count());
+ int max = qMin(actual.size(), expected.size());
for (int i=0; i<max; ++i)
QCOMPARE(actual[i], expected[i]);
- QCOMPARE(actual.count(), expected.count());
+ QCOMPARE(actual.size(), expected.size());
}
void
@@ -1246,7 +1312,7 @@ tst_QDir::cleanPath_data()
#else
QTest::newRow("data10") << "/:/" << "/:";
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QTest::newRow("data11") << "//foo//bar" << "//foo/bar";
#endif
QTest::newRow("data12") << "ab/a/" << "ab/a"; // Path item with length of 2
@@ -1258,16 +1324,26 @@ tst_QDir::cleanPath_data()
QTest::newRow("data14") << "c://foo" << "c:/foo";
// Drive letters and unc path in one string
-#if defined(Q_OS_WINRT)
- const QString root = QDir::rootPath(); // has trailing slash
- QTest::newRow("root-up") << (root + "path/..") << root;
- QTest::newRow("above-root") << (root + "..") << (root + "..");
-#elif defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
QTest::newRow("data15") << "//c:/foo" << "//c:/foo";
QTest::newRow("drive-up") << "A:/path/.." << "A:/";
QTest::newRow("drive-above-root") << "A:/.." << "A:/..";
QTest::newRow("unc-server-up") << "//server/path/.." << "//server";
QTest::newRow("unc-server-above-root") << "//server/.." << "//server/..";
+
+ QTest::newRow("longpath") << uR"(\\?\d:\)"_s << u"d:/"_s;
+ QTest::newRow("longpath-slash") << u"//?/d:/"_s << u"d:/"_s;
+ QTest::newRow("longpath-mixed-slashes") << uR"(//?/d:\)"_s << u"d:/"_s;
+ QTest::newRow("longpath-mixed-slashes-2") << uR"(\\?\d:/)"_s << u"d:/"_s;
+
+ QTest::newRow("unc-network-share") << uR"(\\?\UNC\localhost\c$\tmp.txt)"_s
+ << u"//localhost/c$/tmp.txt"_s;
+ QTest::newRow("unc-network-share-slash") << u"//?/UNC/localhost/c$/tmp.txt"_s
+ << u"//localhost/c$/tmp.txt"_s;
+ QTest::newRow("unc-network-share-mixed-slashes") << uR"(//?/UNC/localhost\c$\tmp.txt)"_s
+ << u"//localhost/c$/tmp.txt"_s;
+ QTest::newRow("unc-network-share-mixed-slashes-2") << uR"(\\?\UNC\localhost/c$/tmp.txt)"_s
+ << u"//localhost/c$/tmp.txt"_s;
#else
QTest::newRow("data15") << "//c:/foo" << "/c:/foo";
#endif // non-windows
@@ -1384,7 +1460,7 @@ void tst_QDir::absoluteFilePath_data()
QTest::addColumn<QString>("fileName");
QTest::addColumn<QString>("expectedFilePath");
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QTest::newRow("UNC-rel") << "//machine/share" << "dir" << "//machine/share/dir";
QTest::newRow("UNC-abs") << "//machine/share/path/to/blah" << "/dir" << "//machine/share/dir";
QTest::newRow("UNC-UNC") << "//machine/share/path/to/blah" << "//host/share/path" << "//host/share/path";
@@ -1422,7 +1498,7 @@ void tst_QDir::absolutePath_data()
QTest::addColumn<QString>("expectedPath");
QTest::newRow("0") << "/machine/share/dir1" << "/machine/share/dir1";
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
+#if defined(Q_OS_WIN)
QTest::newRow("1") << "\\machine\\share\\dir1" << "/machine/share/dir1";
QTest::newRow("2") << "//machine/share/dir1" << "//machine/share/dir1";
QTest::newRow("3") << "\\\\machine\\share\\dir1" << "//machine/share/dir1";
@@ -1490,12 +1566,10 @@ void tst_QDir::relativeFilePath_data()
QTest::newRow("27") << "C:" << "D:/" << "D:/";
QTest::newRow("28") << "C:/" << "D:" << "D:";
QTest::newRow("29") << "C:/" << "D:/" << "D:/";
-#ifndef Q_OS_WINRT
QTest::newRow("30") << "C:/foo/bar" << "//anotherHost/foo/bar" << "//anotherHost/foo/bar";
QTest::newRow("31") << "//anotherHost/foo" << "//anotherHost/foo/bar" << "bar";
QTest::newRow("32") << "//anotherHost/foo" << "bar" << "bar";
QTest::newRow("33") << "//anotherHost/foo" << "C:/foo/bar" << "C:/foo/bar";
-#endif // !Q_OS_WINRT
#endif
QTest::newRow("resource0") << ":/prefix" << "foo.bar" << "foo.bar";
@@ -1549,7 +1623,7 @@ void tst_QDir::filePath()
void tst_QDir::remove()
{
QFile f("remove-test");
- f.open(QIODevice::WriteOnly);
+ QVERIFY(f.open(QIODevice::WriteOnly));
f.close();
QDir dir;
QVERIFY(dir.remove("remove-test"));
@@ -1562,12 +1636,12 @@ void tst_QDir::remove()
void tst_QDir::rename()
{
QFile f("rename-test");
- f.open(QIODevice::WriteOnly);
+ QVERIFY(f.open(QIODevice::WriteOnly));
f.close();
QDir dir;
QVERIFY(dir.rename("rename-test", "rename-test-renamed"));
QVERIFY(dir.rename("rename-test-renamed", "rename-test"));
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_DARWIN)
QVERIFY(!dir.rename("rename-test", "/etc/rename-test-renamed"));
#elif !defined(Q_OS_WIN)
// on windows this is possible - maybe make the test a bit better
@@ -1656,7 +1730,10 @@ void tst_QDir::dirName()
void tst_QDir::operator_eq()
{
QDir dir1(".");
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
dir1 = dir1;
+QT_WARNING_POP
dir1.setPath("..");
}
@@ -1665,9 +1742,9 @@ void tst_QDir::dotAndDotDot()
{
QDir dir(QString((m_dataPath + "/testdir/")));
QStringList entryList = dir.entryList(QDir::Dirs);
- QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces"));
+ QCOMPARE(entryList, QStringList({ u"."_s, u".."_s, u"dir"_s, u"dir.lnk"_s, u"spaces"_s }));
entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces"));
+ QCOMPARE(entryList, QStringList({ u"dir"_s, u"dir.lnk"_s, u"spaces"_s }));
}
void tst_QDir::homePath()
@@ -1680,7 +1757,7 @@ void tst_QDir::homePath()
QVERIFY(QDir::isAbsolutePath(strHome));
#ifdef Q_OS_UNIX
- if (strHome.length() > 1) // root dir = "/"
+ if (strHome.size() > 1) // root dir = "/"
QVERIFY(!strHome.endsWith('/'));
QByteArray envHome = qgetenv("HOME");
@@ -1689,16 +1766,12 @@ void tst_QDir::homePath()
qputenv("HOME", envHome);
#elif defined(Q_OS_WIN)
- if (strHome.length() > 3 // root dir = "c:/"; "//" is not really valid...
-#if defined(Q_OS_WINRT)
- && strHome.length() > QDir::rootPath().length()
-#endif
- )
+ if (strHome.length() > 3) // root dir = "c:/"; "//" is not really valid...
QVERIFY(!strHome.endsWith('/'));
#endif
QStringList entries = homeDir.entryList();
- for (int i = 0; i < entries.count(); ++i) {
+ for (int i = 0; i < entries.size(); ++i) {
QFileInfo fi(QDir::homePath() + "/" + entries[i]);
QCOMPARE(fi.exists(), true);
}
@@ -1714,7 +1787,7 @@ void tst_QDir::tempPath()
QVERIFY(QDir::isAbsolutePath(path));
#ifdef Q_OS_UNIX
- if (path.length() > 1) // root dir = "/"
+ if (path.size() > 1) // root dir = "/"
QVERIFY(!path.endsWith('/'));
#elif defined(Q_OS_WIN)
if (path.length() > 3) // root dir = "c:/"; "//" is not really valid...
@@ -1745,6 +1818,11 @@ void tst_QDir::nativeSeparators()
QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/"));
QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/"));
+ QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\\\?\\C:\\")), QString("C:/"));
+ QCOMPARE(QDir::fromNativeSeparators(uR"(\\?\UNC\localhost\c$\tmp.txt)"_s),
+ u"//localhost/c$/tmp.txt"_s);
+ QCOMPARE(QDir::fromNativeSeparators(uR"(//?/UNC/localhost\c$\tmp.txt)"_s),
+ u"//localhost/c$/tmp.txt"_s);
#else
QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/"));
QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
@@ -1784,16 +1862,16 @@ void tst_QDir::searchPaths()
{
QFETCH(QString, filename);
QFETCH(QString, searchPathPrefixes);
- QStringList searchPathPrefixList = searchPathPrefixes.split(";", QString::SkipEmptyParts);
+ QStringList searchPathPrefixList = searchPathPrefixes.split(";", Qt::SkipEmptyParts);
QFETCH(QString, searchPaths);
- QStringList searchPathsList = searchPaths.split(";", QString::SkipEmptyParts);
+ QStringList searchPathsList = searchPaths.split(";", Qt::SkipEmptyParts);
QFETCH(QString, expectedAbsolutePath);
bool exists = !expectedAbsolutePath.isEmpty();
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QDir::setSearchPaths(searchPathPrefixList.at(i), searchPathsList.at(i).split(","));
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QCOMPARE(QDir::searchPaths(searchPathPrefixList.at(i)), searchPathsList.at(i).split(","));
}
@@ -1804,19 +1882,19 @@ void tst_QDir::searchPaths()
QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath);
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList());
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty());
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
- foreach (QString path, searchPathsList.at(i).split(",")) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
+ const auto parts = searchPathsList.at(i).split(",");
+ for (const QString &path : parts)
QDir::addSearchPath(searchPathPrefixList.at(i), path);
- }
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QCOMPARE(QDir::searchPaths(searchPathPrefixList.at(i)), searchPathsList.at(i).split(","));
}
@@ -1827,10 +1905,10 @@ void tst_QDir::searchPaths()
QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath);
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList());
}
- for (int i = 0; i < searchPathPrefixList.count(); ++i) {
+ for (int i = 0; i < searchPathPrefixList.size(); ++i) {
QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty());
}
}
@@ -2045,7 +2123,7 @@ void tst_QDir::detachingOperations()
QCOMPARE(dir2.nameFilters(), nameFilters);
QCOMPARE(dir2.sorting(), sorting);
- dir2 = path1;
+ dir2.setPath(path1);
QCOMPARE(dir2.path(), path1);
QCOMPARE(dir2.filter(), filter);
QCOMPARE(dir2.nameFilters(), nameFilters);
@@ -2140,18 +2218,15 @@ void tst_QDir::match()
void tst_QDir::drives()
{
- QFileInfoList list(QDir::drives());
+ const QFileInfoList list(QDir::drives());
#if defined(Q_OS_WIN)
QVERIFY(list.count() >= 1); //system
QLatin1Char systemdrive('c');
#endif
-#if defined(Q_OS_WINRT)
- QSKIP("WinRT has no concept of drives");
-#endif
#if defined(Q_OS_WIN)
QVERIFY(list.count() <= 26);
bool foundsystem = false;
- foreach (QFileInfo fi, list) {
+ for (const QFileInfo &fi : list) {
QCOMPARE(fi.absolutePath().size(), 3); //"x:/"
QCOMPARE(fi.absolutePath().at(1), QChar(QLatin1Char(':')));
QCOMPARE(fi.absolutePath().at(2), QChar(QLatin1Char('/')));
@@ -2160,7 +2235,7 @@ void tst_QDir::drives()
}
QCOMPARE(foundsystem, true);
#else
- QCOMPARE(list.count(), 1); //root
+ QCOMPARE(list.size(), 1); //root
QCOMPARE(list.at(0).absolutePath(), QLatin1String("/"));
#endif
}
@@ -2172,7 +2247,7 @@ void tst_QDir::arrayOperator()
QStringList entries(dir1.entryList());
int i = dir2.count();
- QCOMPARE(i, entries.count());
+ QCOMPARE(i, entries.size());
--i;
for (;i>=0;--i) {
QCOMPARE(dir2[i], entries.at(i));
@@ -2204,11 +2279,9 @@ void tst_QDir::equalityOperator_data()
<< true;
//need a path in the root directory that is unlikely to be a symbolic link.
-#if defined (Q_OS_WINRT)
- QString pathinroot(QDir::rootPath() + QLatin1String("assets/.."));
-#elif defined (Q_OS_WIN)
+#if defined (Q_OS_WIN)
QString pathinroot("c:/windows/..");
-#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#elif defined(Q_OS_ANDROID)
QString pathinroot("/system/..");
#elif defined(Q_OS_HAIKU)
QString pathinroot("/boot/..");
@@ -2277,9 +2350,9 @@ void tst_QDir::isRelative_data()
QTest::newRow("homepath") << QDir::homePath() << false;
QTest::newRow("temppath") << QDir::tempPath() << false;
QTest::newRow("rootpath") << QDir::rootPath() << false;
- foreach (QFileInfo root, QDir::drives()) {
+ const auto drives = QDir::drives();
+ for (const QFileInfo &root : drives)
QTest::newRow(root.absolutePath().toLocal8Bit()) << root.absolutePath() << false;
- }
QTest::newRow("resource") << ":/prefix" << false;
}
@@ -2337,14 +2410,12 @@ void tst_QDir::cdBelowRoot_data()
QTest::newRow("android") << "/" << "system" << "/system";
#elif defined(Q_OS_UNIX)
QTest::newRow("unix") << "/" << "tmp" << "/tmp";
-#elif defined(Q_OS_WINRT)
- QTest::newRow("winrt") << QDir::rootPath() << QDir::rootPath() << QDir::rootPath();
#else // Windows+CE
const QString systemDrive = QString::fromLocal8Bit(qgetenv("SystemDrive")) + QLatin1Char('/');
const QString systemRoot = QString::fromLocal8Bit(qgetenv("SystemRoot"));
QTest::newRow("windows-drive")
<< systemDrive << systemRoot.mid(3) << QDir::cleanPath(systemRoot);
- const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
+ const QString uncRoot = QStringLiteral("//") + QTest::uncServerName();
const QString testDirectory = QStringLiteral("testshare");
QTest::newRow("windows-share")
<< uncRoot << testDirectory << QDir::cleanPath(uncRoot + QLatin1Char('/') + testDirectory);
@@ -2366,9 +2437,6 @@ void tst_QDir::cdBelowRoot()
if (::getuid() == 0)
QSKIP("Running this test as root doesn't make sense");
#endif
-#ifdef Q_OS_WINRT
- QSKIP("WinRT has no concept of system root");
-#endif
QDir dir(targetPath);
QVERIFY2(!dir.cd("../.."), qPrintable(dir.absolutePath()));
QCOMPARE(dir.path(), targetPath);
@@ -2401,6 +2469,45 @@ void tst_QDir::nonEmptyDir()
QVERIFY(!dir.isEmpty());
}
+void tst_QDir::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+ namespace fs = std::filesystem;
+ fs::path path(".");
+ QDir dir(path);
+ QCOMPARE(dir, QDir(QStringLiteral(".")));
+
+ path = path / "testdir" / "dir";
+ dir.setPath(path);
+
+ QCOMPARE(dir, QDir(QStringLiteral("./testdir/dir")));
+
+ auto fsPath = dir.filesystemPath();
+ QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.path());
+ fsPath = dir.filesystemAbsolutePath();
+ QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.absolutePath());
+ fsPath = dir.filesystemCanonicalPath();
+ QCOMPARE(QString::fromStdU16String(fsPath.u16string()), dir.canonicalPath());
+
+ QDir emptyPath(fs::path{});
+ QCOMPARE(emptyPath, QDir(QStringLiteral(".")));
+
+ {
+ // Test QDir ctor with filter and sorting reversed
+ QDir filteredDir(fs::path{"."} / "searchdir", "subdir*",
+ QDir::SortFlag::Reversed, QDir::Filter::Dirs);
+ QStringList entries = filteredDir.entryList();
+ QCOMPARE(entries, QStringList() << "subdir2" << "subdir1");
+ QCOMPARE(filteredDir.sorting(), QDir::SortFlag::Reversed);
+ QCOMPARE(filteredDir.filter(), QDir::Filter::Dirs);
+ QCOMPARE(filteredDir.nameFilters().size(), 1);
+ QCOMPARE(filteredDir.nameFilters().first(), "subdir*");
+ }
+#else
+ QSKIP("Not supported");
+#endif
+}
+
QTEST_MAIN(tst_QDir)
#include "tst_qdir.moc"
diff --git a/tests/auto/corelib/io/qdiriterator/CMakeLists.txt b/tests/auto/corelib/io/qdiriterator/CMakeLists.txt
new file mode 100644
index 0000000000..41784546aa
--- /dev/null
+++ b/tests/auto/corelib/io/qdiriterator/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdiriterator Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdiriterator LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "entrylist")
+
+qt_internal_add_test(tst_qdiriterator
+ SOURCES
+ tst_qdiriterator.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ TESTDATA ${test_data}
+)
+
+# Resources:
+set(qdiriterator_resource_files
+ "entrylist/directory/dummy"
+ "entrylist/file"
+)
+
+qt_internal_add_resource(tst_qdiriterator "qdiriterator"
+ PREFIX
+ "/testdata/"
+ FILES
+ ${qdiriterator_resource_files}
+)
+
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qdiriterator CONDITION CONFIG___contains___builtin_testdata
+ DEFINES
+ BUILTIN_TESTDATA
+)
diff --git a/tests/auto/corelib/io/qdiriterator/qdiriterator.pro b/tests/auto/corelib/io/qdiriterator/qdiriterator.pro
deleted file mode 100644
index 7c1f026bdb..0000000000
--- a/tests/auto/corelib/io/qdiriterator/qdiriterator.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdiriterator
-QT = core-private core testlib
-SOURCES = tst_qdiriterator.cpp
-RESOURCES += qdiriterator.qrc
-
-TESTDATA += entrylist
-contains(CONFIG, builtin_testdata): DEFINES += BUILTIN_TESTDATA
diff --git a/tests/auto/corelib/io/qdiriterator/qdiriterator.qrc b/tests/auto/corelib/io/qdiriterator/qdiriterator.qrc
deleted file mode 100644
index af9998bdb4..0000000000
--- a/tests/auto/corelib/io/qdiriterator/qdiriterator.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/testdata/">
- <file>entrylist/file</file>
- <file>entrylist/directory/dummy</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
index 0b125925bb..a0a8917c27 100644
--- a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
+++ b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp
@@ -1,50 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qcoreapplication.h>
#include <qdebug.h>
#include <qdiriterator.h>
#include <qfileinfo.h>
#include <qstringlist.h>
+#include <QSet>
+#include <QString>
#include <QtCore/private/qfsfileengine_p.h>
-#if defined(Q_OS_VXWORKS) || defined(Q_OS_WINRT)
+#if defined(Q_OS_VXWORKS)
#define Q_NO_SYMLINKS
#endif
-#if defined(Q_OS_WIN)
-# include "../../../network-settings.h"
+#include "../../../../shared/filesystem.h"
+
+#ifdef Q_OS_ANDROID
+#include <QStandardPaths>
#endif
+using namespace Qt::StringLiterals;
+
Q_DECLARE_METATYPE(QDirIterator::IteratorFlags)
Q_DECLARE_METATYPE(QDir::Filters)
@@ -66,16 +46,10 @@ private: // convenience functions
return false;
}
- enum Cleanup { DoDelete, DontDelete };
- bool createFile(const QString &fileName, Cleanup cleanup = DoDelete)
+ bool createFile(const QString &fileName)
{
QFile file(fileName);
- if (file.open(QIODevice::WriteOnly)) {
- if (cleanup == DoDelete)
- createdFiles << fileName;
- return true;
- }
- return false;
+ return file.open(QIODevice::WriteOnly);
}
bool createLink(const QString &destination, const QString &linkName)
@@ -89,7 +63,6 @@ private: // convenience functions
private slots:
void initTestCase();
- void cleanupTestCase();
void iterateRelativeDirectory_data();
void iterateRelativeDirectory();
void iterateResource_data();
@@ -97,6 +70,8 @@ private slots:
void stopLinkLoop();
#ifdef QT_BUILD_INTERNAL
void engineWithNoIterator();
+ void testQFsFileEngineIterator_data() { iterateRelativeDirectory_data(); }
+ void testQFsFileEngineIterator();
#endif
void absoluteFilePathsFromRelativeIteratorPath();
void recurseWithFilters() const;
@@ -110,25 +85,24 @@ private slots:
#ifndef Q_OS_WIN
void hiddenDirs_hiddenFiles();
#endif
-#ifdef BUILTIN_TESTDATA
+
private:
QSharedPointer<QTemporaryDir> m_dataDir;
-#endif
};
void tst_QDirIterator::initTestCase()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- QString testdata_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ QString testdata_dir;
+#ifdef Q_OS_ANDROID
+ testdata_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QString resourceSourcePath = QStringLiteral(":/testdata");
QDirIterator it(resourceSourcePath, QDirIterator::Subdirectories);
while (it.hasNext()) {
- it.next();
-
- QFileInfo fileInfo = it.fileInfo();
+ QFileInfo fileInfo = it.nextFileInfo();
if (!fileInfo.isDir()) {
- QString destination = testdata_dir + QLatin1Char('/') + fileInfo.filePath().mid(resourceSourcePath.length());
+ QString destination = testdata_dir + QLatin1Char('/')
+ + fileInfo.filePath().mid(resourceSourcePath.length());
QFileInfo destinationFileInfo(destination);
if (!destinationFileInfo.exists()) {
QDir().mkpath(destinationFileInfo.path());
@@ -143,29 +117,22 @@ void tst_QDirIterator::initTestCase()
#elif defined(BUILTIN_TESTDATA)
m_dataDir = QEXTRACTTESTDATA("/testdata");
QVERIFY2(!m_dataDir.isNull(), qPrintable("Could not extract test data"));
- QString testdata_dir = m_dataDir->path();
+ testdata_dir = m_dataDir->path();
#else
-
- // chdir into testdata directory, then find testdata by relative paths.
- QString testdata_dir = QFileInfo(QFINDTESTDATA("entrylist")).absolutePath();
+ m_dataDir.reset(new QTemporaryDir);
+ testdata_dir = m_dataDir->path();
#endif
+ QVERIFY(!testdata_dir.isEmpty());
+ // Must call QDir::setCurrent() here because all the tests that use relative
+ // paths depend on that.
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
- QFile::remove("entrylist/entrylist1.lnk");
- QFile::remove("entrylist/entrylist2.lnk");
- QFile::remove("entrylist/entrylist3.lnk");
- QFile::remove("entrylist/entrylist4.lnk");
- QFile::remove("entrylist/directory/entrylist1.lnk");
- QFile::remove("entrylist/directory/entrylist2.lnk");
- QFile::remove("entrylist/directory/entrylist3.lnk");
- QFile::remove("entrylist/directory/entrylist4.lnk");
-
createDirectory("entrylist");
createDirectory("entrylist/directory");
- createFile("entrylist/file", DontDelete);
+ createFile("entrylist/file");
createFile("entrylist/writable");
- createFile("entrylist/directory/dummy", DontDelete);
+ createFile("entrylist/directory/dummy");
createDirectory("recursiveDirs");
createDirectory("recursiveDirs/dir1");
@@ -213,20 +180,6 @@ void tst_QDirIterator::initTestCase()
#endif
}
-void tst_QDirIterator::cleanupTestCase()
-{
- Q_FOREACH(QString fileName, createdFiles)
- QFile::remove(fileName);
-
- Q_FOREACH(QString dirName, createdDirectories)
- currentDir.rmdir(dirName);
-
-#ifdef Q_OS_WINRT
- QDir::setCurrent(QCoreApplication::applicationDirPath());
-#endif // Q_OS_WINRT
-
-}
-
void tst_QDirIterator::iterateRelativeDirectory_data()
{
QTest::addColumn<QString>("dirName"); // relative from current path or abs
@@ -236,7 +189,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data()
QTest::addColumn<QStringList>("entries");
QTest::newRow("no flags")
- << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QString("entrylist") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::NoFilter) << QStringList("*")
<< QString(
"entrylist/.,"
@@ -252,7 +205,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data()
"entrylist/writable").split(',');
QTest::newRow("NoDot")
- << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QString("entrylist") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::AllEntries | QDir::NoDot) << QStringList("*")
<< QString(
"entrylist/..,"
@@ -267,7 +220,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data()
"entrylist/writable").split(',');
QTest::newRow("NoDotDot")
- << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QString("entrylist") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::AllEntries | QDir::NoDotDot) << QStringList("*")
<< QString(
"entrylist/.,"
@@ -282,7 +235,7 @@ void tst_QDirIterator::iterateRelativeDirectory_data()
"entrylist/writable").split(',');
QTest::newRow("NoDotAndDotDot")
- << QString("entrylist") << QDirIterator::IteratorFlags(0)
+ << QString("entrylist") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::AllEntries | QDir::NoDotAndDotDot) << QStringList("*")
<< QString(
"entrylist/file,"
@@ -335,12 +288,12 @@ void tst_QDirIterator::iterateRelativeDirectory_data()
"entrylist/writable").split(',');
QTest::newRow("empty, default")
- << QString("empty") << QDirIterator::IteratorFlags(0)
+ << QString("empty") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::NoFilter) << QStringList("*")
<< QString("empty/.,empty/..").split(',');
QTest::newRow("empty, QDir::NoDotAndDotDot")
- << QString("empty") << QDirIterator::IteratorFlags(0)
+ << QString("empty") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*")
<< QStringList();
}
@@ -351,7 +304,7 @@ void tst_QDirIterator::iterateRelativeDirectory()
QFETCH(QDirIterator::IteratorFlags, flags);
QFETCH(QDir::Filters, filters);
QFETCH(QStringList, nameFilters);
- QFETCH(QStringList, entries);
+ QFETCH(const QStringList, entries);
QDirIterator it(dirName, nameFilters, filters, flags);
QStringList list;
@@ -379,13 +332,13 @@ void tst_QDirIterator::iterateRelativeDirectory()
list.sort();
QStringList sortedEntries;
- foreach(QString item, entries)
+ for (const QString &item : entries)
sortedEntries.append(QFileInfo(item).canonicalFilePath());
sortedEntries.sort();
if (sortedEntries != list) {
- qDebug() << "EXPECTED:" << sortedEntries;
qDebug() << "ACTUAL: " << list;
+ qDebug() << "EXPECTED:" << sortedEntries;
}
QCOMPARE(list, sortedEntries);
@@ -399,16 +352,17 @@ void tst_QDirIterator::iterateResource_data()
QTest::addColumn<QStringList>("nameFilters");
QTest::addColumn<QStringList>("entries");
- QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa") << QDirIterator::IteratorFlags(0)
+ QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa") << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
<< QStringList();
- QTest::newRow(":/testdata") << QString::fromLatin1(":/testdata/") << QDirIterator::IteratorFlags(0)
+ QTest::newRow("qrc:/testdata") << u":/testdata/"_s << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
<< QString::fromLatin1(":/testdata/entrylist").split(QLatin1String(","));
- QTest::newRow(":/testdata/entrylist") << QString::fromLatin1(":/testdata/entrylist") << QDirIterator::IteratorFlags(0)
+ QTest::newRow("qrc:/testdata/entrylist") << u":/testdata/entrylist"_s << QDirIterator::IteratorFlags{}
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
<< QString::fromLatin1(":/testdata/entrylist/directory,:/testdata/entrylist/file").split(QLatin1String(","));
- QTest::newRow(":/testdata recursive") << QString::fromLatin1(":/testdata") << QDirIterator::IteratorFlags(QDirIterator::Subdirectories)
+ QTest::newRow("qrc:/testdata recursive") << u":/testdata"_s
+ << QDirIterator::IteratorFlags(QDirIterator::Subdirectories)
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
<< QString::fromLatin1(":/testdata/entrylist,:/testdata/entrylist/directory,:/testdata/entrylist/directory/dummy,:/testdata/entrylist/file").split(QLatin1String(","));
}
@@ -434,8 +388,8 @@ void tst_QDirIterator::iterateResource()
sortedEntries.sort();
if (sortedEntries != list) {
- qDebug() << "EXPECTED:" << sortedEntries;
qDebug() << "ACTUAL:" << list;
+ qDebug() << "EXPECTED:" << sortedEntries;
}
QCOMPARE(list, sortedEntries);
@@ -468,7 +422,7 @@ void tst_QDirIterator::stopLinkLoop()
QStringList list;
int max = 200;
while (--max && it.hasNext())
- it.next();
+ it.nextFileInfo();
QVERIFY(max);
// The goal of this test is only to ensure that the test above don't malfunction
@@ -482,16 +436,20 @@ public:
: QFSFileEngine(fileName)
{ }
- QAbstractFileEngineIterator *beginEntryList(QDir::Filters, const QStringList &)
- { return 0; }
+ IteratorUniquePtr
+ beginEntryList(const QString &, QDir::Filters, const QStringList &) override
+ { return nullptr; }
};
class EngineWithNoIteratorHandler : public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(EngineWithNoIteratorHandler)
public:
- QAbstractFileEngine *create(const QString &fileName) const
+ EngineWithNoIteratorHandler() = default;
+
+ std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override
{
- return new EngineWithNoIterator(fileName);
+ return std::make_unique<EngineWithNoIterator>(fileName);
}
};
#endif
@@ -504,15 +462,48 @@ void tst_QDirIterator::engineWithNoIterator()
QDir("entrylist").entryList();
QVERIFY(true); // test that the above line doesn't crash
}
+
+class CustomEngineHandler : public QAbstractFileEngineHandler
+{
+ Q_DISABLE_COPY_MOVE(CustomEngineHandler)
+public:
+ CustomEngineHandler() = default;
+
+ std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override
+ {
+ // We want to test QFSFileEngine specifically, so force QDirIterator to use it
+ // over the default QFileSystemEngine
+ return std::make_unique<QFSFileEngine>(fileName);
+ }
+};
+
+void tst_QDirIterator::testQFsFileEngineIterator()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(QDir::Filters, filters);
+ QFETCH(QDirIterator::IteratorFlags, flags);
+
+ if (dirName == u"empty")
+ return; // This row isn't useful in this test
+
+ CustomEngineHandler handler;
+ bool isEmpty = true;
+ QDirIterator iter(dirName, nameFilters, filters, flags);
+ while (iter.hasNext()) {
+ const QFileInfo &fi = iter.nextFileInfo();
+ if (fi.filePath().contains(u"entrylist"))
+ isEmpty = false; // At least one entry in `entrylist` dir
+ }
+ QVERIFY(!isEmpty);
+}
#endif
void tst_QDirIterator::absoluteFilePathsFromRelativeIteratorPath()
{
QDirIterator it("entrylist/", QDir::NoDotAndDotDot);
- while (it.hasNext()) {
- it.next();
- QVERIFY(QFileInfo(it.filePath()).absoluteFilePath().contains("entrylist"));
- }
+ while (it.hasNext())
+ QVERIFY(it.nextFileInfo().absoluteFilePath().contains("entrylist"));
}
void tst_QDirIterator::recurseWithFilters() const
@@ -529,11 +520,9 @@ void tst_QDirIterator::recurseWithFilters() const
expectedEntries.insert(QString::fromLatin1("recursiveDirs/textFileA.txt"));
QVERIFY(it.hasNext());
- it.next();
- actualEntries.insert(it.fileInfo().filePath());
+ actualEntries.insert(it.next());
QVERIFY(it.hasNext());
- it.next();
- actualEntries.insert(it.fileInfo().filePath());
+ actualEntries.insert(it.next());
QCOMPARE(actualEntries, expectedEntries);
QVERIFY(!it.hasNext());
@@ -550,23 +539,31 @@ void tst_QDirIterator::longPath()
while (dir.exists(dirName) || dir.mkdir(dirName)) {
++n;
dirName.append('x');
+ if (n >= 20480)
+ {
+ break;
+ }
+ }
+ if (n >= 20480)
+ {
+ qWarning("No maximum length on directory names");
}
-
QDirIterator it(dir.absolutePath(), QDir::NoDotAndDotDot|QDir::Dirs, QDirIterator::Subdirectories);
int m = 0;
while (it.hasNext()) {
++m;
- it.next();
+ it.nextFileInfo();
}
QCOMPARE(n, m);
-
dirName.chop(1);
- while (dirName.length() > 0 && dir.exists(dirName) && dir.rmdir(dirName)) {
+ while (dirName.size() > 0 && dir.exists(dirName) && dir.rmdir(dirName)) {
+ --n;
dirName.chop(1);
}
- dir.cdUp();
- dir.rmdir("longpaths");
+ QCOMPARE(n, 0);
+ QVERIFY(dir.cdUp());
+ QVERIFY(dir.rmdir("longpaths"));
}
void tst_QDirIterator::dirorder()
@@ -592,11 +589,11 @@ void tst_QDirIterator::uncPaths_data()
{
QTest::addColumn<QString>("dirName");
QTest::newRow("uncserver")
- <<QString("//" + QtNetworkSettings::winServerName());
+ <<QString("//" + QTest::uncServerName());
QTest::newRow("uncserver/testshare")
- <<QString("//" + QtNetworkSettings::winServerName() + "/testshare");
+ <<QString("//" + QTest::uncServerName() + "/testshare");
QTest::newRow("uncserver/testshare/tmp")
- <<QString("//" + QtNetworkSettings::winServerName() + "/testshare/tmp");
+ <<QString("//" + QTest::uncServerName() + "/testshare/tmp");
}
void tst_QDirIterator::uncPaths()
{
@@ -623,8 +620,7 @@ void tst_QDirIterator::hiddenDirs_hiddenFiles()
QDirIterator di("hiddenDirs_hiddenFiles", QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (di.hasNext()) {
++matches;
- QString filename = di.next();
- if (QFileInfo(filename).isDir())
+ if (di.nextFileInfo().isDir())
++failures; // search was only supposed to find files
}
QCOMPARE(matches, 6);
@@ -637,8 +633,7 @@ void tst_QDirIterator::hiddenDirs_hiddenFiles()
QDirIterator di("hiddenDirs_hiddenFiles", QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (di.hasNext()) {
++matches;
- QString filename = di.next();
- if (!QFileInfo(filename).isDir())
+ if (!di.nextFileInfo().isDir())
++failures; // search was only supposed to find files
}
QCOMPARE(matches, 6);
diff --git a/tests/auto/corelib/io/qdirlisting/.gitignore b/tests/auto/corelib/io/qdirlisting/.gitignore
new file mode 100644
index 0000000000..4965f97d03
--- /dev/null
+++ b/tests/auto/corelib/io/qdirlisting/.gitignore
@@ -0,0 +1 @@
+tst_qdirlisting
diff --git a/tests/auto/corelib/io/qdirlisting/CMakeLists.txt b/tests/auto/corelib/io/qdirlisting/CMakeLists.txt
new file mode 100644
index 0000000000..77431776d9
--- /dev/null
+++ b/tests/auto/corelib/io/qdirlisting/CMakeLists.txt
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdirlisting Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdirlisting LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "entrylist")
+
+qt_internal_add_test(tst_qdirlisting
+ SOURCES
+ tst_qdirlisting.cpp
+ LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ TESTDATA ${test_data}
+)
+
+# Resources:
+set(qdirlisting_resource_files
+ "entrylist/directory/dummy"
+ "entrylist/file"
+)
+
+qt_internal_add_resource(tst_qdirlisting "qdirlisting"
+ PREFIX
+ "/testdata/"
+ FILES
+ ${qdirlisting_resource_files}
+)
+
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qdirlisting CONDITION CONFIG___contains___builtin_testdata
+ DEFINES
+ BUILTIN_TESTDATA
+)
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+osx/test4 b/tests/auto/corelib/io/qdirlisting/entrylist/directory/dummy
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+osx/test4
+++ b/tests/auto/corelib/io/qdirlisting/entrylist/directory/dummy
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+ios/test b/tests/auto/corelib/io/qdirlisting/entrylist/file
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+ios/test
+++ b/tests/auto/corelib/io/qdirlisting/entrylist/file
diff --git a/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp b/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp
new file mode 100644
index 0000000000..bb4e1b30d2
--- /dev/null
+++ b/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp
@@ -0,0 +1,611 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qdirlisting.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+#include <QSet>
+#include <QString>
+
+#include <QtCore/private/qfsfileengine_p.h>
+
+#if defined(Q_OS_VXWORKS)
+#define Q_NO_SYMLINKS
+#endif
+
+#include "../../../../shared/filesystem.h"
+
+#ifdef Q_OS_ANDROID
+#include <QStandardPaths>
+#endif
+
+using namespace Qt::StringLiterals;
+
+Q_DECLARE_METATYPE(QDirListing::IteratorFlags)
+Q_DECLARE_METATYPE(QDir::Filters)
+
+using ItFlag = QDirListing::IteratorFlag;
+
+class tst_QDirListing : public QObject
+{
+ Q_OBJECT
+
+private: // convenience functions
+ QStringList createdDirectories;
+ QStringList createdFiles;
+
+ QDir currentDir;
+ bool createDirectory(const QString &dirName)
+ {
+ if (currentDir.mkdir(dirName)) {
+ createdDirectories.prepend(dirName);
+ return true;
+ }
+ return false;
+ }
+
+ bool createFile(const QString &fileName)
+ {
+ QFile file(fileName);
+ return file.open(QIODevice::WriteOnly);
+ }
+
+ bool createLink(const QString &destination, const QString &linkName)
+ {
+ if (QFile::link(destination, linkName)) {
+ createdFiles << linkName;
+ return true;
+ }
+ return false;
+ }
+
+private slots:
+ void initTestCase();
+ void iterateRelativeDirectory_data();
+ void iterateRelativeDirectory();
+ void iterateResource_data();
+ void iterateResource();
+ void stopLinkLoop();
+#ifdef QT_BUILD_INTERNAL
+ void engineWithNoIterator();
+ void testQFsFileEngineIterator_data() { iterateRelativeDirectory_data(); }
+ void testQFsFileEngineIterator();
+#endif
+ void absoluteFilePathsFromRelativeIteratorPath();
+ void recurseWithFilters() const;
+ void longPath();
+ void dirorder();
+ void relativePaths();
+#if defined(Q_OS_WIN)
+ void uncPaths_data();
+ void uncPaths();
+#endif
+#ifndef Q_OS_WIN
+ void hiddenDirs_hiddenFiles();
+#endif
+
+private:
+ QSharedPointer<QTemporaryDir> m_dataDir;
+};
+
+void tst_QDirListing::initTestCase()
+{
+ QString testdata_dir;
+#ifdef Q_OS_ANDROID
+ testdata_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ QString resourceSourcePath = QStringLiteral(":/testdata");
+ for (const auto &dirEntry : QDirListing(resourceSourcePath, ItFlag::Recursive)) {
+ if (!dirEntry.isDir()) {
+ const QString &filePath = dirEntry.filePath();
+ QString destination = testdata_dir + QLatin1Char('/')
+ + filePath.sliced(resourceSourcePath.length());
+ QFileInfo destinationFileInfo(destination);
+ if (!destinationFileInfo.exists()) {
+ QDir().mkpath(destinationFileInfo.path());
+ if (!QFile::copy(filePath, destination))
+ qWarning("Failed to copy %s", qPrintable(filePath));
+ }
+ }
+
+ }
+
+ testdata_dir += QStringLiteral("/entrylist");
+#elif defined(BUILTIN_TESTDATA)
+ m_dataDir = QEXTRACTTESTDATA("/testdata");
+ QVERIFY2(!m_dataDir.isNull(), qPrintable("Could not extract test data"));
+ testdata_dir = m_dataDir->path();
+#else
+ m_dataDir.reset(new QTemporaryDir);
+ testdata_dir = m_dataDir->path();
+#endif
+
+ QVERIFY(!testdata_dir.isEmpty());
+ // Must call QDir::setCurrent() here because all the tests that use relative
+ // paths depend on that.
+ QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
+
+ createDirectory("entrylist");
+ createDirectory("entrylist/directory");
+ createFile("entrylist/file");
+ createFile("entrylist/writable");
+ createFile("entrylist/directory/dummy");
+
+ createDirectory("recursiveDirs");
+ createDirectory("recursiveDirs/dir1");
+ createFile("recursiveDirs/textFileA.txt");
+ createFile("recursiveDirs/dir1/aPage.html");
+ createFile("recursiveDirs/dir1/textFileB.txt");
+
+ createDirectory("foo");
+ createDirectory("foo/bar");
+ createFile("foo/bar/readme.txt");
+
+ createDirectory("empty");
+
+#ifndef Q_NO_SYMLINKS
+# if defined(Q_OS_WIN)
+ // ### Sadly, this is a platform difference right now.
+ createLink("entrylist/file", "entrylist/linktofile.lnk");
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ createLink("entrylist/directory", "entrylist/linktodirectory.lnk");
+# endif
+ createLink("entrylist/nothing", "entrylist/brokenlink.lnk");
+# else
+ createLink("file", "entrylist/linktofile.lnk");
+# ifndef Q_NO_SYMLINKS_TO_DIRS
+ createLink("directory", "entrylist/linktodirectory.lnk");
+# endif
+ createLink("nothing", "entrylist/brokenlink.lnk");
+# endif
+#endif
+
+#if !defined(Q_OS_WIN)
+ createDirectory("hiddenDirs_hiddenFiles");
+ createFile("hiddenDirs_hiddenFiles/normalFile");
+ createFile("hiddenDirs_hiddenFiles/.hiddenFile");
+ createDirectory("hiddenDirs_hiddenFiles/normalDirectory");
+ createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory");
+ createFile("hiddenDirs_hiddenFiles/normalDirectory/normalFile");
+ createFile("hiddenDirs_hiddenFiles/normalDirectory/.hiddenFile");
+ createFile("hiddenDirs_hiddenFiles/.hiddenDirectory/normalFile");
+ createFile("hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenFile");
+ createDirectory("hiddenDirs_hiddenFiles/normalDirectory/normalDirectory");
+ createDirectory("hiddenDirs_hiddenFiles/normalDirectory/.hiddenDirectory");
+ createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory/normalDirectory");
+ createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenDirectory");
+#endif
+}
+
+void tst_QDirListing::iterateRelativeDirectory_data()
+{
+ QTest::addColumn<QString>("dirName"); // relative from current path or abs
+ QTest::addColumn<QDirListing::IteratorFlags>("flags");
+ QTest::addColumn<QDir::Filters>("filters");
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<QStringList>("entries");
+
+ QTest::newRow("no flags")
+ << QString("entrylist") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::NoFilter) << QStringList("*")
+ << QString(
+ "entrylist/.,"
+ "entrylist/..,"
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("NoDot")
+ << QString("entrylist") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::AllEntries | QDir::NoDot) << QStringList("*")
+ << QString(
+ "entrylist/..,"
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("NoDotDot")
+ << QString("entrylist") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::AllEntries | QDir::NoDotDot) << QStringList("*")
+ << QString(
+ "entrylist/.,"
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("NoDotAndDotDot")
+ << QString("entrylist") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::AllEntries | QDir::NoDotAndDotDot) << QStringList("*")
+ << QString(
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks")
+ << QString("entrylist") << QDirListing::IteratorFlags(ItFlag::Recursive | ItFlag::FollowSymlinks)
+ << QDir::Filters(QDir::NoFilter) << QStringList("*")
+ << QString(
+ "entrylist/.,"
+ "entrylist/..,"
+ "entrylist/directory/.,"
+ "entrylist/directory/..,"
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory,"
+ "entrylist/directory/dummy,"
+#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
+ "entrylist/linktodirectory.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("QDir::Subdirectories / QDir::Files")
+ << QString("entrylist") << QDirListing::IteratorFlags(ItFlag::Recursive)
+ << QDir::Filters(QDir::Files) << QStringList("*")
+ << QString("entrylist/directory/dummy,"
+ "entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/writable").split(',');
+
+ QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks / QDir::Files")
+ << QString("entrylist") << QDirListing::IteratorFlags(ItFlag::Recursive | QDirListing::IteratorFlag::FollowSymlinks)
+ << QDir::Filters(QDir::Files) << QStringList("*")
+ << QString("entrylist/file,"
+#ifndef Q_NO_SYMLINKS
+ "entrylist/linktofile.lnk,"
+#endif
+ "entrylist/directory/dummy,"
+ "entrylist/writable").split(',');
+
+ QTest::newRow("empty, default")
+ << QString("empty") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::NoFilter) << QStringList("*")
+ << QString("empty/.,empty/..").split(',');
+
+ QTest::newRow("empty, QDir::NoDotAndDotDot")
+ << QString("empty") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*")
+ << QStringList();
+}
+
+void tst_QDirListing::iterateRelativeDirectory()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QDirListing::IteratorFlags, flags);
+ QFETCH(QDir::Filters, filters);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(const QStringList, entries);
+
+ QStringList list;
+ for (const auto &dirEntry : QDirListing(dirName, nameFilters, filters, flags)) {
+ // Using canonical file paths for final comparison
+ list << dirEntry.fileInfo().canonicalFilePath();
+ }
+
+ // The order of items returned by QDirListing is not guaranteed.
+ list.sort();
+
+ QStringList sortedEntries;
+ for (const QString &item : entries)
+ sortedEntries.append(QFileInfo(item).canonicalFilePath());
+ sortedEntries.sort();
+
+ if (sortedEntries != list) {
+ qDebug() << "ACTUAL: " << list;
+ qDebug() << "EXPECTED:" << sortedEntries;
+ }
+
+ QCOMPARE(list, sortedEntries);
+}
+
+void tst_QDirListing::iterateResource_data()
+{
+ QTest::addColumn<QString>("dirName"); // relative from current path or abs
+ QTest::addColumn<QDirListing::IteratorFlags>("flags");
+ QTest::addColumn<QDir::Filters>("filters");
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<QStringList>("entries");
+
+ QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa") << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QStringList();
+ QTest::newRow("qrc:/testdata") << u":/testdata/"_s << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QString::fromLatin1(":/testdata/entrylist").split(QLatin1String(","));
+ QTest::newRow("qrc:/testdata/entrylist") << u":/testdata/entrylist"_s << QDirListing::IteratorFlags{}
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QString::fromLatin1(":/testdata/entrylist/directory,:/testdata/entrylist/file").split(QLatin1String(","));
+ QTest::newRow("qrc:/testdata recursive") << u":/testdata"_s
+ << QDirListing::IteratorFlags(ItFlag::Recursive)
+ << QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
+ << QString::fromLatin1(":/testdata/entrylist,:/testdata/entrylist/directory,:/testdata/entrylist/directory/dummy,:/testdata/entrylist/file").split(QLatin1String(","));
+}
+
+void tst_QDirListing::iterateResource()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QDirListing::IteratorFlags, flags);
+ QFETCH(QDir::Filters, filters);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(QStringList, entries);
+
+ QStringList list;
+ for (const auto &dirEntry : QDirListing(dirName, nameFilters, filters, flags)) {
+ QString dir = dirEntry.fileInfo().filePath();
+ if (!dir.startsWith(":/qt-project.org"))
+ list.emplace_back(std::move(dir));
+ }
+
+ list.sort();
+ QStringList sortedEntries = entries;
+ sortedEntries.sort();
+
+ if (sortedEntries != list) {
+ qDebug() << "ACTUAL:" << list;
+ qDebug() << "EXPECTED:" << sortedEntries;
+ }
+
+ QCOMPARE(list, sortedEntries);
+}
+
+void tst_QDirListing::stopLinkLoop()
+{
+#ifdef Q_OS_WIN
+ // ### Sadly, this is a platform difference right now.
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/entrylist1.lnk");
+ createLink("entrylist/.", "entrylist/entrylist2.lnk");
+ createLink("entrylist/../entrylist/.", "entrylist/entrylist3.lnk");
+ createLink("entrylist/..", "entrylist/entrylist4.lnk");
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/directory/entrylist1.lnk");
+ createLink("entrylist/.", "entrylist/directory/entrylist2.lnk");
+ createLink("entrylist/../directory/.", "entrylist/directory/entrylist3.lnk");
+ createLink("entrylist/..", "entrylist/directory/entrylist4.lnk");
+#else
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/entrylist1.lnk");
+ createLink(".", "entrylist/entrylist2.lnk");
+ createLink("../entrylist/.", "entrylist/entrylist3.lnk");
+ createLink("..", "entrylist/entrylist4.lnk");
+ createLink(QDir::currentPath() + QLatin1String("/entrylist"), "entrylist/directory/entrylist1.lnk");
+ createLink(".", "entrylist/directory/entrylist2.lnk");
+ createLink("../directory/.", "entrylist/directory/entrylist3.lnk");
+ createLink("..", "entrylist/directory/entrylist4.lnk");
+#endif
+
+ constexpr auto flags = ItFlag::Recursive | ItFlag::FollowSymlinks;
+ QDirListing dirIter(u"entrylist"_s, flags);
+ QStringList list;
+ int max = 200;
+ auto it = dirIter.begin();
+ while (--max && it != dirIter.end())
+ ++it;
+ QCOMPARE_GT(max, 0);
+
+ // The goal of this test is only to ensure that the test above don't malfunction
+}
+
+#ifdef QT_BUILD_INTERNAL
+class EngineWithNoIterator : public QFSFileEngine
+{
+public:
+ EngineWithNoIterator(const QString &fileName)
+ : QFSFileEngine(fileName)
+ { }
+
+ IteratorUniquePtr beginEntryList(const QString &, QDir::Filters, const QStringList &) override
+ { return nullptr; }
+};
+
+class EngineWithNoIteratorHandler : public QAbstractFileEngineHandler
+{
+ Q_DISABLE_COPY_MOVE(EngineWithNoIteratorHandler)
+public:
+ EngineWithNoIteratorHandler() = default;
+
+ std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override
+ {
+ return std::make_unique<EngineWithNoIterator>(fileName);
+ }
+};
+#endif
+
+#ifdef QT_BUILD_INTERNAL
+void tst_QDirListing::engineWithNoIterator()
+{
+ EngineWithNoIteratorHandler handler;
+
+ QDir("entrylist").entryList();
+ QVERIFY(true); // test that the above line doesn't crash
+}
+
+class CustomEngineHandler : public QAbstractFileEngineHandler
+{
+ Q_DISABLE_COPY_MOVE(CustomEngineHandler)
+public:
+ CustomEngineHandler() = default;
+
+ std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override
+ {
+ // We want to test QFSFileEngine specifically, so force QDirListing to use it
+ // over the default QFileSystemEngine
+ return std::make_unique<QFSFileEngine>(fileName);
+ }
+};
+
+void tst_QDirListing::testQFsFileEngineIterator()
+{
+ QFETCH(QString, dirName);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(QDir::Filters, filters);
+ QFETCH(QDirListing::IteratorFlags, flags);
+
+ if (dirName == u"empty")
+ return; // This row isn't useful in this test
+
+ CustomEngineHandler handler;
+ bool isEmpty = true;
+ for (const auto &dirEntry : QDirListing(u"entrylist"_s, nameFilters, filters, flags)) {
+ if (dirEntry.filePath().contains(u"entrylist"))
+ isEmpty = false; // At least one entry in `entrylist` dir
+ }
+ QVERIFY(!isEmpty); // At least one entry
+}
+#endif
+
+void tst_QDirListing::absoluteFilePathsFromRelativeIteratorPath()
+{
+ for (const auto &dirEntry : QDirListing(u"entrylist/"_s, QDir::NoDotAndDotDot))
+ QVERIFY(dirEntry.absoluteFilePath().contains("entrylist"));
+}
+
+void tst_QDirListing::recurseWithFilters() const
+{
+ QSet<QString> actualEntries;
+ QSet<QString> expectedEntries;
+ expectedEntries.insert(QString::fromLatin1("recursiveDirs/dir1/textFileB.txt"));
+ expectedEntries.insert(QString::fromLatin1("recursiveDirs/textFileA.txt"));
+
+ for (const auto &dirEntry : QDirListing(u"recursiveDirs/"_s, QStringList{u"*.txt"_s},
+ QDir::Files, ItFlag::Recursive)) {
+ actualEntries.insert(dirEntry.filePath());
+ }
+
+ QCOMPARE(actualEntries, expectedEntries);
+}
+
+void tst_QDirListing::longPath()
+{
+ QDir dir;
+ dir.mkdir("longpaths");
+ dir.cd("longpaths");
+
+ QString dirName = "x";
+ qsizetype n = 0;
+ while (dir.exists(dirName) || dir.mkdir(dirName)) {
+ ++n;
+ dirName.append('x');
+ }
+
+ QDirListing dirList(dir.absolutePath(), QDir::NoDotAndDotDot|QDir::Dirs, ItFlag::Recursive);
+ qsizetype m = 0;
+ for (auto it = dirList.begin(); it != dirList.end(); ++it)
+ ++m;
+
+ QCOMPARE(n, m);
+
+ dirName.chop(1);
+ while (dirName.size() > 0 && dir.exists(dirName) && dir.rmdir(dirName))
+ dirName.chop(1);
+
+ dir.cdUp();
+ dir.rmdir("longpaths");
+}
+
+void tst_QDirListing::dirorder()
+{
+ QStringList entries;
+ for (const auto &dirEntry : QDirListing(u"foo"_s, ItFlag::Recursive))
+ entries.append(dirEntry.filePath());
+
+ QCOMPARE_GT(entries.indexOf(u"foo/bar"_s), entries.indexOf(u"foo"_s));
+}
+
+void tst_QDirListing::relativePaths()
+{
+ for (const auto &dirEntry : QDirListing(u"*"_s, ItFlag::Recursive))
+ QCOMPARE(dirEntry.filePath(), QDir::cleanPath(dirEntry.filePath()));
+}
+
+#if defined(Q_OS_WIN)
+void tst_QDirListing::uncPaths_data()
+{
+ QTest::addColumn<QString>("dirName");
+ QTest::newRow("uncserver")
+ <<QString("//" + QTest::uncServerName());
+ QTest::newRow("uncserver/testshare")
+ <<QString("//" + QTest::uncServerName() + "/testshare");
+ QTest::newRow("uncserver/testshare/tmp")
+ <<QString("//" + QTest::uncServerName() + "/testshare/tmp");
+}
+void tst_QDirListing::uncPaths()
+{
+ QFETCH(QString, dirName);
+ constexpr auto dirFilters = QDir::AllEntries | QDir::NoDotAndDotDot;
+ for (const auto &dirEntry : QDirListing(dirName, dirFilters, ItFlag::Recursive)) {
+ const QString &filePath = dirEntry.filePath();
+ QCOMPARE(filePath, QDir::cleanPath(filePath));
+ }
+}
+#endif
+
+#ifndef Q_OS_WIN
+// In Unix it is easy to create hidden files, but in Windows it requires
+// a special call since hidden files need to be "marked" while in Unix
+// anything starting by a '.' is a hidden file.
+// For that reason this test is not run in Windows.
+void tst_QDirListing::hiddenDirs_hiddenFiles()
+{
+ // Only files
+ {
+ int matches = 0;
+ int failures = 0;
+ constexpr auto filters = QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot;
+ for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters,
+ ItFlag::Recursive)) {
+ ++matches;
+ if (dirEntry.isDir())
+ ++failures; // search was only supposed to find files
+ }
+ QCOMPARE(matches, 6);
+ QCOMPARE(failures, 0);
+ }
+ // Only directories
+ {
+ int matches = 0;
+ int failures = 0;
+ constexpr auto filters = QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot;
+ for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters,
+ ItFlag::Recursive)) {
+ ++matches;
+ if (!dirEntry.isDir())
+ ++failures; // search was only supposed to find files
+ }
+ QCOMPARE(matches, 6);
+ QCOMPARE(failures, 0);
+ }
+}
+#endif // Q_OS_WIN
+
+QTEST_MAIN(tst_QDirListing)
+
+#include "tst_qdirlisting.moc"
+
diff --git a/tests/auto/corelib/io/qfile/BLACKLIST b/tests/auto/corelib/io/qfile/BLACKLIST
deleted file mode 100644
index 8366667166..0000000000
--- a/tests/auto/corelib/io/qfile/BLACKLIST
+++ /dev/null
@@ -1,7 +0,0 @@
-# QTBUG-48455
-[readLineStdin]
-msvc-2015 ci
-msvc-2017 ci
-[readLineStdin_lineByLine]
-msvc-2015 ci
-msvc-2017 ci
diff --git a/tests/auto/corelib/io/qfile/CMakeLists.txt b/tests/auto/corelib/io/qfile/CMakeLists.txt
new file mode 100644
index 0000000000..567dcc8a2e
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/CMakeLists.txt
@@ -0,0 +1,93 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfile Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfile LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "dosfile.txt")
+list(APPEND test_data "noendofline.txt")
+list(APPEND test_data "testfile.txt")
+list(APPEND test_data "testlog.txt")
+list(APPEND test_data "two.dots.file")
+list(APPEND test_data "tst_qfile.cpp")
+list(APPEND test_data "forCopying.txt")
+list(APPEND test_data "forRenaming.txt")
+list(APPEND test_data "resources/file1.ext1")
+
+qt_internal_add_test(tst_qfile
+ SOURCES
+ tst_qfile.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+ TESTDATA ${test_data}
+)
+
+# Resources:
+set(qfile_resource_files
+ "resources/"
+)
+
+qt_internal_add_resource(tst_qfile "qfile"
+ PREFIX
+ "/tst_qfileinfo/"
+ FILES
+ ${qfile_resource_files}
+)
+set(rename-fallback_resource_files
+ "rename-fallback.qrc"
+)
+
+qt_internal_add_resource(tst_qfile "rename-fallback"
+ PREFIX
+ "/"
+ FILES
+ ${rename-fallback_resource_files}
+)
+set(copy-fallback_resource_files
+ "copy-fallback.qrc"
+)
+
+qt_internal_add_resource(tst_qfile "copy-fallback"
+ PREFIX
+ "/"
+ FILES
+ ${copy-fallback_resource_files}
+)
+
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qfile CONDITION TARGET Qt::Network
+ LIBRARIES
+ Qt::Network
+)
+
+qt_internal_extend_target(tst_qfile CONDITION NOT TARGET Qt::Network
+ DEFINES
+ QT_NO_NETWORK
+)
+
+qt_internal_extend_target(tst_qfile CONDITION CONFIG___contains___builtin_testdata
+ DEFINES
+ BUILTIN_TESTDATA
+)
+
+qt_internal_extend_target(tst_qfile CONDITION WIN32
+ LIBRARIES
+ ole32
+ uuid
+)
+add_subdirectory(stdinprocess)
+if(QT_FEATURE_process)
+ add_dependencies(tst_qfile stdinprocess_helper)
+endif()
diff --git a/tests/auto/corelib/io/qfile/qfile.pro b/tests/auto/corelib/io/qfile/qfile.pro
deleted file mode 100644
index 91c5c15f66..0000000000
--- a/tests/auto/corelib/io/qfile/qfile.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = test.pro
-!winrt: SUBDIRS += stdinprocess
diff --git a/tests/auto/corelib/io/qfile/qfile.qrc b/tests/auto/corelib/io/qfile/qfile.qrc
deleted file mode 100644
index 2c63d8afeb..0000000000
--- a/tests/auto/corelib/io/qfile/qfile.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/tst_qfileinfo/">
- <file>resources/</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/CMakeLists.txt b/tests/auto/corelib/io/qfile/stdinprocess/CMakeLists.txt
new file mode 100644
index 0000000000..2a4c2a9615
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/stdinprocess/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## stdinprocess_helper Binary:
+#####################################################################
+
+qt_internal_add_test_helper(stdinprocess_helper
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
index 77a1932bd5..0f92ba2670 100644
--- a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
+++ b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
@@ -41,13 +16,16 @@ int main(int argc, char *argv[])
QFile file;
if (strcmp(argv[1], "all") == 0) {
- file.open(stdin, QFile::ReadWrite);
+ if (!file.open(stdin, QFile::ReadWrite))
+ return 1;
printf("%s", file.readAll().constData());
} else if (strcmp(argv[1], "line") == 0) {
if (strcmp(argv[2], "0") == 0) {
- file.open(stdin, QFile::ReadWrite);
+ if (!file.open(stdin, QFile::ReadWrite))
+ return 1;
} else {
- file.open(0, QFile::ReadWrite);
+ if (!file.open(0, QFile::ReadWrite))
+ return 1;
}
char line[1024];
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
deleted file mode 100644
index 512da8939b..0000000000
--- a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += main.cpp
-QT = core
-
-load(qt_test_helper)
diff --git a/tests/auto/corelib/io/qfile/test.pro b/tests/auto/corelib/io/qfile/test.pro
deleted file mode 100644
index 95389ab3e2..0000000000
--- a/tests/auto/corelib/io/qfile/test.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-CONFIG += testcase
-QT = core-private testlib
-qtHaveModule(network): QT += network
-else: DEFINES += QT_NO_NETWORK
-
-contains(CONFIG, builtin_testdata) {
- DEFINES += BUILTIN_TESTDATA
-}
-
-TESTDATA += BLACKLIST
-
-TARGET = tst_qfile
-
-SOURCES = tst_qfile.cpp
-INCLUDEPATH += ../../../../shared/
-HEADERS += ../../../../shared/emulationdetector.h
-
-RESOURCES += qfile.qrc rename-fallback.qrc copy-fallback.qrc
-
-TESTDATA += \
- dosfile.txt noendofline.txt testfile.txt \
- testlog.txt two.dots.file tst_qfile.cpp \
- Makefile forCopying.txt forRenaming.txt \
- resources/file1.ext1
-
-win32:!winrt: LIBS += -lole32 -luuid
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 678a80c3f7..d69cc167d6 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -1,33 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#include <QTest>
+#include <QScopedValueRollback>
#include <qplatformdefs.h>
#include <QCoreApplication>
@@ -35,13 +13,23 @@
#include <QDir>
#include <QFile>
#include <QFileInfo>
+#include <QOperatingSystemVersion>
+#include <QRandomGenerator>
+#include <QStorageInfo>
+#include <QScopeGuard>
+#include <QStandardPaths>
#include <QTemporaryDir>
+#include <QTemporaryFile>
#include <private/qabstractfileengine_p.h>
#include <private/qfsfileengine_p.h>
#include <private/qfilesystemengine_p.h>
-#include "emulationdetector.h"
+#ifdef Q_OS_WIN
+#include <QtCore/private/qfunctions_win_p.h>
+#endif
+
+#include <QtTest/private/qemulationdetector_p.h>
#ifdef Q_OS_WIN
QT_BEGIN_NAMESPACE
@@ -60,11 +48,14 @@ QT_END_NAMESPACE
#else
# include <sys/types.h>
# include <unistd.h>
+# include <private/qcore_unix_p.h>
#endif
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
# include <sys/mount.h>
#elif defined(Q_OS_LINUX)
+# include <sys/eventfd.h>
# include <sys/vfs.h>
+# include <sys/wait.h>
#elif defined(Q_OS_FREEBSD)
# include <sys/param.h>
# include <sys/mount.h>
@@ -91,9 +82,7 @@ QT_END_NAMESPACE
# undef fileno
#endif
-#if defined(Q_OS_WIN)
-#include "../../../network-settings.h"
-#endif
+#include "../../../../shared/filesystem.h"
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
@@ -111,6 +100,8 @@ QT_END_NAMESPACE
#define QT_OPEN_BINARY 0
#endif
+using namespace Qt::StringLiterals;
+
Q_DECLARE_METATYPE(QFile::FileError)
@@ -175,6 +166,8 @@ private slots:
void ungetChar();
void createFile();
void createFileNewOnly();
+ void createFilePermissions_data();
+ void createFilePermissions();
void openFileExistingOnly();
void append();
void permissions_data();
@@ -182,33 +175,39 @@ private slots:
#ifdef Q_OS_WIN
void permissionsNtfs_data();
void permissionsNtfs();
+#if QT_DEPRECATED_SINCE(6,6)
+ void deprecatedNtfsPermissionCheck();
+#endif
#endif
+ void setPermissions_data();
void setPermissions();
void copy();
void copyAfterFail();
void copyRemovesTemporaryFile() const;
void copyShouldntOverwrite();
void copyFallback();
-#ifndef Q_OS_WINRT
void link();
void linkToDir();
void absolutePathLinkToRelativePath();
void readBrokenLink();
-#endif
void readTextFile_data();
void readTextFile();
void readTextFile2();
void writeTextFile_data();
void writeTextFile();
/* void largeFileSupport(); */
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
void largeUncFileSupport();
#endif
void flush();
void bufferedRead();
#ifdef Q_OS_UNIX
+ void isSequential_data();
void isSequential();
#endif
+ void decodeName_data();
+ void decodeName();
+ void encodeName_data() { decodeName_data(); }
void encodeName();
void truncate();
void seekToPos();
@@ -230,9 +229,18 @@ private slots:
void writeLargeDataBlock();
void readFromWriteOnlyFile();
void writeToReadOnlyFile();
-#if defined(Q_OS_LINUX) || defined(Q_OS_AIX) || defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+#if defined(Q_OS_LINUX)
+ void virtualFile_data();
void virtualFile();
#endif
+#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
+ void unixPipe_data();
+ void unixPipe();
+ void unixFifo_data() { unixPipe_data(); }
+ void unixFifo();
+ void socketPair_data() { unixPipe_data(); }
+ void socketPair();
+#endif
void textFile();
void rename_data();
void rename();
@@ -279,6 +287,15 @@ private slots:
void reuseQFile();
+ void moveToTrash_data();
+ void moveToTrash();
+ void moveToTrashDuplicateName();
+ void moveToTrashOpenFile_data();
+ void moveToTrashOpenFile();
+ void moveToTrashXdgSafety();
+
+ void stdfilesystem();
+
private:
#ifdef BUILTIN_TESTDATA
QSharedPointer<QTemporaryDir> m_dataDir;
@@ -403,7 +420,8 @@ void tst_QFile::cleanup()
// Clean out everything except the readonly-files.
const QDir dir(m_temporaryDir.path());
- foreach (const QFileInfo &fi, dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
+ const auto entries = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
+ for (const QFileInfo &fi : entries) {
const QString fileName = fi.fileName();
if (fileName != QLatin1String(noReadFile) && fileName != QLatin1String(readOnlyFile)) {
const QString absoluteFilePath = fi.absoluteFilePath();
@@ -421,6 +439,8 @@ void tst_QFile::cleanup()
tst_QFile::tst_QFile() : m_oldDir(QDir::currentPath())
{
+ QStandardPaths::setTestModeEnabled(true);
+ QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
}
static QByteArray msgOpenFailed(QIODevice::OpenMode om, const QFile &file)
@@ -499,7 +519,7 @@ void tst_QFile::initTestCase()
file.write("b", 1);
file.close();
#ifndef Q_OS_WIN // Not supported on Windows.
- QVERIFY2(file.setPermissions(0), qPrintable(file.errorString()));
+ QVERIFY2(file.setPermissions({ }), qPrintable(file.errorString()));
#else
QVERIFY2(file.open(QFile::WriteOnly), msgOpenFailed(file).constData());
#endif
@@ -545,11 +565,15 @@ void tst_QFile::exists()
file.remove();
QVERIFY(!file.exists());
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- const QString uncPath = "//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt";
+#if defined(Q_OS_WIN)
+ const QString uncPath = "//" + QTest::uncServerName() + "/testshare/readme.txt";
QFile unc(uncPath);
QVERIFY2(unc.exists(), msgFileDoesNotExist(uncPath).constData());
#endif
+
+ QTest::ignoreMessage(QtWarningMsg, "Broken filename passed to function");
+ QVERIFY(!QFile::exists(QDir::currentPath() + QLatin1Char('/') +
+ QChar(QChar::Null) + QLatin1String("x/y")));
}
void tst_QFile::open_data()
@@ -597,7 +621,7 @@ void tst_QFile::open_data()
<< int(QIODevice::ReadOnly)
<< false
<< QFile::OpenError;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
//opening devices requires administrative privileges (and elevation).
HANDLE hTest = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hTest != INVALID_HANDLE_VALUE) {
@@ -608,7 +632,7 @@ void tst_QFile::open_data()
QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
<< false << QFile::OpenError;
}
- QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testshare/test.pri" << int(QIODevice::ReadOnly)
+ QTest::newRow("uncFile") << "//" + QTest::uncServerName() + "/testshare/test.pri" << int(QIODevice::ReadOnly)
<< true << QFile::NoError;
#endif
}
@@ -622,13 +646,13 @@ void tst_QFile::open()
QFETCH( bool, ok );
-#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_WASM)
if (::getuid() == 0)
// root and Chuck Norris don't care for file permissions. Skip.
QSKIP("Running this test as root doesn't make sense");
#endif
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN32)
QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort);
#endif
if (filename.isEmpty())
@@ -680,9 +704,9 @@ void tst_QFile::size_data()
QTest::addColumn<qint64>("size");
QTest::newRow( "exist01" ) << m_testFile << (qint64)245;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
// Only test UNC on Windows./
- QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testshare/test.pri") << (qint64)34;
+ QTest::newRow("unc") << "//" + QString(QTest::uncServerName() + "/testshare/test.pri") << (qint64)34;
#endif
}
@@ -980,7 +1004,6 @@ void tst_QFile::readAllStdin()
process.start(m_stdinProcess, QStringList(QStringLiteral("all")));
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
for (int i = 0; i < 5; ++i) {
- QTest::qWait(1000);
process.write(lotsOfData);
while (process.bytesToWrite() > 0)
QVERIFY(process.waitForBytesWritten());
@@ -1015,7 +1038,6 @@ void tst_QFile::readLineStdin()
QIODevice::Text | QIODevice::ReadWrite);
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
for (int i = 0; i < 5; ++i) {
- QTest::qWait(1000);
process.write(lotsOfData);
while (process.bytesToWrite() > 0)
QVERIFY(process.waitForBytesWritten());
@@ -1096,7 +1118,7 @@ void tst_QFile::missingEndOfLine()
void tst_QFile::readBlock()
{
QFile f( m_testFile );
- f.open( QIODevice::ReadOnly );
+ QVERIFY( f.open( QIODevice::ReadOnly ) );
int length = 0;
char p[256];
@@ -1111,7 +1133,7 @@ void tst_QFile::readBlock()
void tst_QFile::getch()
{
QFile f( m_testFile );
- f.open( QIODevice::ReadOnly );
+ QVERIFY( f.open( QIODevice::ReadOnly ) );
char c;
int i = 0;
@@ -1164,7 +1186,7 @@ void tst_QFile::ungetChar()
QCOMPARE(buf[2], '4');
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QString driveLetters()
{
wchar_t volumeName[MAX_PATH];
@@ -1198,12 +1220,15 @@ static inline QChar invalidDriveLetter()
void tst_QFile::invalidFile_data()
{
QTest::addColumn<QString>("fileName");
+
+#if defined(Q_OS_WASM)
+ QSKIP("No invalid files on wasm");
+#endif
+
#if !defined(Q_OS_WIN)
QTest::newRow( "x11" ) << QString( "qwe//" );
#else
-#if !defined(Q_OS_WINRT)
QTest::newRow( "colon2" ) << invalidDriveLetter() + QString::fromLatin1(":ail:invalid");
-#endif
QTest::newRow( "colon3" ) << QString( ":failinvalid" );
QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
@@ -1214,7 +1239,6 @@ void tst_QFile::invalidFile_data()
QTest::newRow( "pipe" ) << QString( "fail|invalid" );
#endif
}
-
void tst_QFile::invalidFile()
{
QFETCH( QString, fileName );
@@ -1249,6 +1273,55 @@ void tst_QFile::createFileNewOnly()
QFile::remove("createme.txt");
}
+void tst_QFile::createFilePermissions_data()
+{
+ QTest::addColumn<QFile::Permissions>("permissions");
+
+ for (int u = 0; u < 8; ++u) {
+ for (int g = 0; g < 8; ++g) {
+ for (int o = 0; o < 8; ++o) {
+ auto permissions = QFileDevice::Permissions::fromInt((u << 12) | (g << 4) | o);
+ QTest::addRow("%04x", permissions.toInt()) << permissions;
+ }
+ }
+ }
+}
+
+void tst_QFile::createFilePermissions()
+{
+ QFETCH(QFile::Permissions, permissions);
+
+#ifdef Q_OS_WIN
+ QNtfsPermissionCheckGuard permissionGuard;
+#endif
+#ifdef Q_OS_UNIX
+ auto restoreMask = qScopeGuard([oldMask = umask(0)] { umask(oldMask); });
+#endif
+
+ const QFile::Permissions setPermissions = {
+ QFile::ReadOther, QFile::WriteOther, QFile::ExeOther,
+ QFile::ReadGroup, QFile::WriteGroup, QFile::ExeGroup,
+ QFile::ReadOwner, QFile::WriteOwner, QFile::ExeOwner
+ };
+
+ const QString fileName = u"createme.txt"_s;
+
+ QFile::remove(fileName);
+ QVERIFY(!QFile::exists(fileName));
+
+ QFile f(fileName);
+ auto removeFile = qScopeGuard([&f] {
+ f.close();
+ f.remove();
+ });
+ QVERIFY2(f.open(QIODevice::WriteOnly, permissions), msgOpenFailed(f).constData());
+
+ QVERIFY(QFile::exists(fileName));
+
+ auto actualPermissions = QFileInfo(fileName).permissions();
+ QCOMPARE(actualPermissions & setPermissions, permissions);
+}
+
void tst_QFile::openFileExistingOnly()
{
QFile::remove("dontcreateme.txt");
@@ -1308,7 +1381,10 @@ void tst_QFile::permissions_data()
QTest::addColumn<bool>("expected");
QTest::addColumn<bool>("create");
+#ifndef Q_OS_WASM
+ // Application path is empty on wasm
QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true << false;
+#endif
QTest::newRow("data1") << m_testSourceFile << uint(QFile::ReadUser) << true << false;
QTest::newRow("readonly") << QString::fromLatin1("readonlyfile") << uint(QFile::WriteUser) << false << false;
QTest::newRow("longfile") << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
@@ -1339,11 +1415,11 @@ void tst_QFile::permissions()
QFile::Permissions staticResult = QFile::permissions(file) & perms;
if (create) {
- QFile::remove(file);
+ QVERIFY(QFile::remove(file));
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- if (qt_ntfs_permission_lookup)
+#if defined(Q_OS_WIN)
+ if (qAreNtfsPermissionChecksEnabled())
QEXPECT_FAIL("readonly", "QTBUG-25630", Abort);
#endif
#ifdef Q_OS_UNIX
@@ -1365,27 +1441,61 @@ void tst_QFile::permissionsNtfs_data()
void tst_QFile::permissionsNtfs()
{
- QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup);
- qt_ntfs_permission_lookup++;
+ QNtfsPermissionCheckGuard permissionGuard;
permissions();
}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+#if QT_DEPRECATED_SINCE(6,6)
+void tst_QFile::deprecatedNtfsPermissionCheck()
+{
+ QScopedValueRollback<int> guard(qt_ntfs_permission_lookup);
+
+ QCOMPARE(qAreNtfsPermissionChecksEnabled(), false);
+ qt_ntfs_permission_lookup++;
+ QCOMPARE(qAreNtfsPermissionChecksEnabled(), true);
+ qt_ntfs_permission_lookup--;
+ QCOMPARE(qAreNtfsPermissionChecksEnabled(), false);
+}
+#endif
+QT_WARNING_POP
+
#endif
+void tst_QFile::setPermissions_data()
+{
+ QTest::addColumn<bool>("opened");
+ QTest::newRow("closed") << false; // chmod()
+ QTest::newRow("opened") << true; // fchmod()
+}
+
void tst_QFile::setPermissions()
{
- if ( QFile::exists( "createme.txt" ) )
- QFile::remove( "createme.txt" );
+#ifdef Q_OS_UNIX
+ if (::getuid() == 0)
+ QSKIP("Running this test as root doesn't make sense");
+#endif
+ QFETCH(bool, opened);
+
+ auto remove = []() { QFile::remove("createme.txt"); };
+ auto guard = qScopeGuard(remove);
+ remove();
QVERIFY( !QFile::exists( "createme.txt" ) );
QFile f("createme.txt");
QVERIFY2(f.open(QIODevice::WriteOnly | QIODevice::Truncate), msgOpenFailed(f).constData());
f.putChar('a');
- f.close();
+ if (!opened)
+ f.close();
QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser);
+ QVERIFY(f.setPermissions(QFile::ReadUser));
+ QVERIFY((f.permissions() & perms) == QFile::ReadUser);
QVERIFY(f.setPermissions(perms));
QVERIFY((f.permissions() & perms) == perms);
+ // we should end the test with the file in writeable state
}
void tst_QFile::copy()
@@ -1488,19 +1598,14 @@ void tst_QFile::copyFallback()
#include <shlobj.h>
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
static QString getWorkingDirectoryForLink(const QString &linkFileName)
{
- bool neededCoInit = false;
QString ret;
+ QComHelper comHelper;
IShellLink *psl;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
- if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
- neededCoInit = true;
- CoInitialize(NULL);
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
- }
if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
IPersistFile *ppf;
@@ -1519,15 +1624,10 @@ static QString getWorkingDirectoryForLink(const QString &linkFileName)
psl->Release();
}
- if (neededCoInit) {
- CoUninitialize();
- }
-
return ret;
}
#endif
-#ifndef Q_OS_WINRT
void tst_QFile::link()
{
QFile::remove("myLink.lnk");
@@ -1578,7 +1678,7 @@ void tst_QFile::absolutePathLinkToRelativePath()
QFile::remove("myDir/myLink.lnk");
QDir dir;
dir.mkdir("myDir");
- QFile("myDir/test.txt").open(QFile::WriteOnly);
+ QVERIFY(QFile("myDir/test.txt").open(QFile::WriteOnly));
#ifdef Q_OS_WIN
QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
@@ -1602,7 +1702,6 @@ void tst_QFile::readBrokenLink()
QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
}
-#endif // Q_OS_WINRT
void tst_QFile::readTextFile_data()
{
@@ -1683,11 +1782,11 @@ void tst_QFile::writeTextFile()
QCOMPARE(file.write(in), qlonglong(in.size()));
file.close();
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QCOMPARE(file.readAll(), out);
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
// Helper for executing QFile::open() with warning in QTRY_VERIFY(), which evaluates the condition
// multiple times
static bool qFileOpen(QFile &file, QIODevice::OpenMode ioFlags)
@@ -1723,7 +1822,7 @@ void tst_QFile::largeUncFileSupport()
qint64 size = Q_INT64_C(8589934592);
qint64 dataOffset = Q_INT64_C(8589914592);
QByteArray knownData("LargeFile content at offset 8589914592");
- QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
+ QString largeFile("//" + QTest::uncServerName() + "/testsharelargefile/file.bin");
const QByteArray largeFileEncoded = QFile::encodeName(largeFile);
{
@@ -1756,7 +1855,7 @@ void tst_QFile::largeUncFileSupport()
// Retry in case of sharing violation
QTRY_VERIFY(fOpen(largeFileEncoded, "rb", &fhF));
StdioFileGuard fh(fhF);
- int fd = int(_fileno(fh));
+ int fd = int(QT_FILENO(fh));
QFile file;
QVERIFY(file.open(fd, QIODevice::ReadOnly));
QCOMPARE(file.size(), size);
@@ -1820,17 +1919,64 @@ void tst_QFile::bufferedRead()
}
#ifdef Q_OS_UNIX
+void tst_QFile::isSequential_data()
+{
+ QTest::addColumn<QString>("deviceName");
+ QTest::addColumn<bool>("acceptFailOpen");
+
+ QTest::newRow("/dev/null") << QString("/dev/null") << false;
+ QTest::newRow("/dev/tty") << QString("/dev/tty") << true;
+ QTest::newRow("/dev/zero") << QString("/dev/zero") << false;
+}
+
void tst_QFile::isSequential()
{
- QFile zero("/dev/null");
- QVERIFY2(zero.open(QFile::ReadOnly), msgOpenFailed(zero).constData());
- QVERIFY(zero.isSequential());
+ QFETCH(QString, deviceName);
+ QFETCH(bool, acceptFailOpen);
+
+ if (access(deviceName.toUtf8().data(), R_OK) == 0) {
+ QFile device(deviceName);
+ QVERIFY2(device.open(QFile::ReadOnly) || acceptFailOpen, msgOpenFailed(device).constData());
+ QVERIFY(!device.isOpen() || device.isSequential());
+ }
}
#endif
+void tst_QFile::decodeName_data()
+{
+ QTest::addColumn<QByteArray>("bytearray");
+ QTest::addColumn<QString>("qstring");
+
+ QTest::newRow("null") << QByteArray() << QString();
+ QTest::newRow("simple") << "/path/to/file"_ba << u"/path/to/file"_s;
+
+#ifndef Q_OS_WIN
+# ifdef Q_OS_DARWIN
+ // Mac always expects filenames in UTF-8... and decomposed...
+ QTest::newRow("filé") << "/path/to/file\xCC\x81"_ba << u"/path/to/filé"_s;
+# else
+ QTest::newRow("filé") << "/path/to/fil\xC3\xA9"_ba << u"/path/to/filé"_s;
+# endif
+ QTest::newRow("fraction-slash")
+ << "/path\342\201\204to\342\201\204file"_ba << u"/path⁄to⁄file"_s;
+ QTest::newRow("fraction-slash-u16") << "/path\u2044to\u2044file"_ba << u"/path⁄to⁄file"_s;
+#endif // !Q_OS_WIN
+}
+
+void tst_QFile::decodeName()
+{
+ QFETCH(QByteArray, bytearray);
+ QFETCH(QString, qstring);
+
+ QCOMPARE(QFile::decodeName(bytearray), qstring);
+}
+
void tst_QFile::encodeName()
{
- QCOMPARE(QFile::encodeName(QString()), QByteArray());
+ QFETCH(QString, qstring);
+ QFETCH(QByteArray, bytearray);
+
+ QCOMPARE(QFile::encodeName(qstring), bytearray);
}
void tst_QFile::truncate()
@@ -2097,16 +2243,12 @@ void tst_QFile::i18nFileName()
{
QFile file(fileName);
QVERIFY2(file.open(QFile::WriteOnly | QFile::Text), msgOpenFailed(file).constData());
- QTextStream ts(&file);
- ts.setCodec("UTF-8");
- ts << fileName << endl;
+ file.write(fileName.toUtf8());
}
{
QFile file(fileName);
QVERIFY2(file.open(QFile::ReadOnly | QFile::Text), msgOpenFailed(file).constData());
- QTextStream ts(&file);
- ts.setCodec("UTF-8");
- QString line = ts.readLine();
+ QString line = QString::fromUtf8(file.readAll());
QCOMPARE(line, fileName);
}
}
@@ -2148,23 +2290,19 @@ void tst_QFile::longFileName()
{
QFile file(fileName);
QVERIFY2(file.open(QFile::WriteOnly | QFile::Text), msgOpenFailed(file).constData());
- QTextStream ts(&file);
- ts << fileName << endl;
+ file.write(fileName.toUtf8());
}
{
QFile file(fileName);
QVERIFY2(file.open(QFile::ReadOnly | QFile::Text), msgOpenFailed(file).constData());
- QTextStream ts(&file);
- QString line = ts.readLine();
- QCOMPARE(line, fileName);
+ QString line = QString::fromUtf8(file.readAll());
}
QString newName = fileName + QLatin1Char('1');
{
QVERIFY(QFile::copy(fileName, newName));
QFile file(newName);
QVERIFY2(file.open(QFile::ReadOnly | QFile::Text), msgOpenFailed(file).constData());
- QTextStream ts(&file);
- QString line = ts.readLine();
+ QString line = QString::fromUtf8(file.readAll());
QCOMPARE(line, fileName);
}
@@ -2173,8 +2311,7 @@ void tst_QFile::longFileName()
QVERIFY(QFile::rename(fileName, newName));
QFile file(newName);
QVERIFY2(file.open(QFile::ReadOnly | QFile::Text), msgOpenFailed(file).constData());
- QTextStream ts(&file);
- QString line = ts.readLine();
+ QString line = QString::fromUtf8(file.readAll());
QCOMPARE(line, fileName);
}
QVERIFY2(QFile::exists(newName), msgFileDoesNotExist(newName).constData());
@@ -2185,36 +2322,10 @@ class MyEngine : public QAbstractFileEngine
{
public:
MyEngine(int n) { number = n; }
- virtual ~MyEngine() {}
-
- void setFileName(const QString &) {}
- bool open(QIODevice::OpenMode) { return false; }
- bool close() { return false; }
- bool flush() { return false; }
- qint64 size() const { return 123 + number; }
- qint64 at() const { return -1; }
- bool seek(qint64) { return false; }
- bool isSequential() const { return false; }
- qint64 read(char *, qint64) { return -1; }
- qint64 write(const char *, qint64) { return -1; }
- bool remove() { return false; }
- bool copy(const QString &) { return false; }
- bool rename(const QString &) { return false; }
- bool link(const QString &) { return false; }
- bool mkdir(const QString &, bool) const { return false; }
- bool rmdir(const QString &, bool) const { return false; }
- bool setSize(qint64) { return false; }
- QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); }
- bool caseSensitive() const { return false; }
- bool isRelativePath() const { return false; }
- FileFlags fileFlags(FileFlags) const { return 0; }
- bool chmod(uint) { return false; }
- QString fileName(FileName) const { return name; }
- uint ownerId(FileOwner) const { return 0; }
- QString owner(FileOwner) const { return QString(); }
- QDateTime fileTime(FileTime) const { return QDateTime(); }
- bool setFileTime(const QDateTime &newDate, FileTime time)
- { Q_UNUSED(newDate) Q_UNUSED(time) return false; }
+
+ qint64 size() const override { return 123 + number; }
+ QStringList entryList(QDir::Filters, const QStringList &) const override { return QStringList(); }
+ QString fileName(FileName) const override { return name; }
private:
int number;
@@ -2223,19 +2334,24 @@ private:
class MyHandler : public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(MyHandler)
public:
- inline QAbstractFileEngine *create(const QString &) const
+ MyHandler() = default;
+ std::unique_ptr<QAbstractFileEngine> create(const QString &) const override
{
- return new MyEngine(1);
+ return std::make_unique<MyEngine>(1);
}
};
class MyHandler2 : public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(MyHandler2)
public:
- inline QAbstractFileEngine *create(const QString &) const
+ MyHandler2() = default;
+
+ std::unique_ptr<QAbstractFileEngine> create(const QString &) const override
{
- return new MyEngine(2);
+ return std::make_unique<MyEngine>(2);
}
};
#endif
@@ -2263,8 +2379,11 @@ void tst_QFile::fileEngineHandler()
#ifdef QT_BUILD_INTERNAL
class MyRecursiveHandler : public QAbstractFileEngineHandler
{
+ Q_DISABLE_COPY_MOVE(MyRecursiveHandler)
public:
- inline QAbstractFileEngine *create(const QString &fileName) const
+ MyRecursiveHandler() = default;
+
+ std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override
{
if (fileName.startsWith(":!")) {
QDir dir;
@@ -2275,9 +2394,9 @@ public:
const QString realFile = m_dataDir->filePath(fileName.mid(2));
#endif
if (dir.exists(realFile))
- return new QFSFileEngine(realFile);
+ return std::make_unique<QFSFileEngine>(realFile);
}
- return 0;
+ return nullptr;
}
#ifdef BUILTIN_TESTDATA
@@ -2302,7 +2421,7 @@ void tst_QFile::useQFileInAFileHandler()
void tst_QFile::getCharFF()
{
QFile file("file.txt");
- file.open(QFile::ReadWrite);
+ QVERIFY(file.open(QFile::ReadWrite));
file.write("\xff\xff\xff");
file.flush();
file.seek(0);
@@ -2405,7 +2524,7 @@ void tst_QFile::fullDisk()
QVERIFY(!file.isOpen());
QCOMPARE(file.error(), QFile::ResourceError);
- file.open(QIODevice::WriteOnly);
+ QVERIFY2(file.open(QIODevice::WriteOnly), msgOpenFailed(file).constData());
QCOMPARE(file.error(), QFile::NoError);
QVERIFY(file.flush()); // Shouldn't inherit write buffer
file.close();
@@ -2427,10 +2546,10 @@ void tst_QFile::writeLargeDataBlock_data()
QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd;
QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(QT_NO_NETWORK)
+#if defined(Q_OS_WIN) && !defined(QT_NO_NETWORK)
// Some semi-randomness to avoid collisions.
QTest::newRow("unc file")
- << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
+ << QString("//" + QTest::uncServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
.arg(QHostInfo::localHostName())
.arg(QTime::currentTime().msec()) << (int)OpenQFile;
#endif
@@ -2523,19 +2642,42 @@ void tst_QFile::writeToReadOnlyFile()
QCOMPARE(file.write(&c, 1), qint64(-1));
}
-#if defined(Q_OS_LINUX) || defined(Q_OS_AIX) || defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+#if defined(Q_OS_LINUX)
// This platform have 0-sized virtual files
+void tst_QFile::virtualFile_data()
+{
+ QTest::addColumn<QIODevice::OpenMode>("mode");
+ QTest::newRow("buffered") << QIODevice::OpenMode();
+ QTest::newRow("unbuffered") << QIODevice::OpenMode(QIODevice::Unbuffered);
+}
+
void tst_QFile::virtualFile()
{
- // test if QFile works with virtual files
- QString fname;
-#if defined(Q_OS_LINUX)
- fname = "/proc/self/maps";
-#elif defined(Q_OS_AIX)
- fname = QString("/proc/%1/map").arg(getpid());
-#else // defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
- fname = "/proc/curproc/map";
-#endif
+ QFETCH(QIODevice::OpenMode, mode);
+
+ // We need to test a large-ish /proc file on Linux, one that is usually
+ // over 4 kB (because the kernel writes in chunks of that), has a
+ // cross-platform file format, and is definitely readable. The best
+ // candidate and the one we can verify anything in is /proc/<PID>/maps.
+ // However, our act of reading may change the map because we allocate
+ // memory, so we fork() here so we have a frozen snapshot of the file.
+
+ int efd = eventfd(0, EFD_CLOEXEC);
+ pid_t pid = fork();
+ if (pid == 0) {
+ // child
+ uint64_t val;
+ eventfd_read(efd, &val);
+ _exit(0);
+ }
+ QVERIFY2(pid > 0, "fork failed: " + qt_error_string().toLocal8Bit());
+ auto waitForChild = qScopeGuard([=] {
+ eventfd_write(efd, 1);
+ close(efd);
+ waitpid(pid, nullptr, 0);
+ });
+
+ QString fname = u"/proc/%1/maps"_s.arg(pid);
// consistency check
QFileInfo fi(fname);
@@ -2545,12 +2687,8 @@ void tst_QFile::virtualFile()
// open the file
QFile f(fname);
- QVERIFY2(f.open(QIODevice::ReadOnly), msgOpenFailed(f).constData());
- if (EmulationDetector::isRunningArmOnX86())
- QEXPECT_FAIL("","QEMU does not read /proc/self/maps size correctly", Continue);
+ QVERIFY2(f.open(QIODevice::ReadOnly | mode), msgOpenFailed(f).constData());
QCOMPARE(f.size(), Q_INT64_C(0));
- if (EmulationDetector::isRunningArmOnX86())
- QEXPECT_FAIL("","QEMU does not read /proc/self/maps size correctly", Continue);
QVERIFY(f.atEnd());
// read data
@@ -2558,26 +2696,183 @@ void tst_QFile::virtualFile()
QCOMPARE(data.size(), 16);
QCOMPARE(f.pos(), Q_INT64_C(16));
+ // seeking
+ QVERIFY(f.seek(1));
+ QCOMPARE(f.pos(), Q_INT64_C(1));
+ QVERIFY(f.seek(0));
+ QCOMPARE(f.pos(), Q_INT64_C(0));
+
// line-reading
- data = f.readLine();
- QVERIFY(!data.isEmpty());
+ QList<QByteArray> lines;
+ for (data = f.readLine(); !data.isEmpty(); data = f.readLine()) {
+ // chop the newline -- not using .trimmed() so cut exactly one byte
+ data.chop(1);
+ lines += std::move(data);
+ }
+
+ if (!QT_CONFIG(static) && !QTestPrivate::isRunningArmOnX86()) {
+ // we must be able to find QtCore and QtTest somewhere
+ static const char corelib[] = "libQt" QT_STRINGIFY(QT_VERSION_MAJOR) "Core";
+ static const char testlib[] = "libQt" QT_STRINGIFY(QT_VERSION_MAJOR) "Test";
+ auto contains = [&](QByteArrayView text, quintptr ptr = 0) {
+ // this is not the same a QList::contains()
+ return std::any_of(lines.constBegin(), lines.constEnd(), [=](QByteArrayView entry) {
+ if (!entry.contains(text))
+ return false;
+ if (!ptr)
+ return true;
+ qsizetype dash = entry.indexOf('-');
+ qsizetype space = entry.indexOf(' ', dash);
+ quintptr start = entry.left(dash).toULong(nullptr, 16);
+ quintptr end = entry.left(space).mid(dash + 1).toULong(nullptr, 16);
+ return start <= ptr && ptr <= end;
+ });
+ };
+ QVERIFY(contains(corelib, quintptr(f.metaObject())));
+ QVERIFY(contains(testlib));
+ }
// read all:
+ QVERIFY(f.seek(0));
data = f.readAll();
QVERIFY(f.pos() != 0);
QVERIFY(!data.isEmpty());
- // seeking
- QVERIFY(f.seek(1));
- QCOMPARE(f.pos(), Q_INT64_C(1));
+ QCOMPARE(data, lines.join('\n') + '\n');
+}
+#endif // defined(Q_OS_LINUX) || defined(Q_OS_AIX) || defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
+
+#if defined (Q_OS_UNIX) && !defined(Q_OS_WASM)
+// wasm does not have working fifo
+// https://github.com/nodejs/node/issues/38344
+// wasm does not have blocking pipe I/O
+// https://github.com/emscripten-core/emscripten/issues/13214
+// wasm does not, by default, have socketpair
+// https://emscripten.org/docs/porting/networking.html
+static void unixPipe_helper(int pipes[2])
+{
+ // start a thread and wait for it to write a first byte
+ static constexpr int Timeout = 1000;
+ QScopedPointer<QThread> thr(QThread::create([fd = pipes[1]]() {
+ char c = 1;
+ qt_safe_write(fd, &c, 1);
+ QTest::qSleep(Timeout);
+ c = 2;
+ qt_safe_write(fd, &c, 1);
+ }));
+
+ thr->start();
+
+ // synchronize with the thread having started
+ char c = 0;
+ QVERIFY2(qt_safe_read(pipes[0], &c, 1) == 1, qPrintable(qt_error_string()));
+ QCOMPARE(c, '\1');
+
+ QFETCH(bool, useStdio);
+ QFile f;
+ if (useStdio) {
+ FILE *fh = fdopen(pipes[0], "rb");
+ QVERIFY(f.open(fh, QIODevice::ReadOnly | QIODevice::Unbuffered, QFileDevice::AutoCloseHandle));
+ pipes[0] = -1; // QFile fclose()s the FILE* and that close()s the fd
+ } else {
+ QVERIFY(f.open(pipes[0], QIODevice::ReadOnly | QIODevice::Unbuffered));
+ }
+
+ // this ought to block
+ c = 0;
+ QCOMPARE(f.read(&c, 1), 1);
+ QCOMPARE(c, '\2');
+
+ thr->wait();
+}
+
+void tst_QFile::unixPipe_data()
+{
+ QTest::addColumn<bool>("useStdio");
+ QTest::newRow("no-stdio") << false;
+ QTest::newRow("with-stdio") << true;
+}
+
+void tst_QFile::unixPipe()
+{
+ int pipes[2] = { -1, -1 };
+ QVERIFY2(pipe(pipes) == 0, qPrintable(qt_error_string()));
+ unixPipe_helper(pipes);
+ if (pipes[0] != -1)
+ qt_safe_close(pipes[0]);
+ qt_safe_close(pipes[1]);
+}
+
+void tst_QFile::unixFifo()
+{
+ QByteArray fifopath = []() -> QByteArray {
+ QByteArray dir = qgetenv("XDG_RUNTIME_DIR");
+ if (dir.isEmpty())
+ dir = QFile::encodeName(QDir::tempPath());
+
+ // try to create a FIFO
+ for (int attempts = 10; attempts; --attempts) {
+ QByteArray fifopath = dir + "/tst_qfile_fifo." +
+ QByteArray::number(QRandomGenerator::global()->generate());
+ int ret = mkfifo(fifopath, 0600);
+ if (ret == 0)
+ return fifopath;
+ }
+
+ qWarning("Failed to create a FIFO at %s; last error was %s",
+ dir.constData(), strerror(errno));
+ return {};
+ }();
+ if (fifopath.isEmpty())
+ return;
+
+ auto removeFifo = qScopeGuard([&fifopath] { unlink(fifopath); });
+
+ // with a FIFO, the two open() system calls synchronize
+ QScopedPointer<QThread> thr(QThread::create([&fifopath]() {
+ int fd = qt_safe_open(fifopath, O_WRONLY);
+ QTest::qSleep(500);
+ char c = 2;
+ qt_safe_write(fd, &c, 1);
+ qt_safe_close(fd);
+ }));
+ thr->start();
+
+ QFETCH(bool, useStdio);
+ QFile f;
+ if (useStdio) {
+ FILE *fh = fopen(fifopath, "rb");
+ QVERIFY(f.open(fh, QIODevice::ReadOnly | QIODevice::Unbuffered, QFileDevice::AutoCloseHandle));
+ } else {
+ f.setFileName(QFile::decodeName(fifopath));
+ QVERIFY(f.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
+ }
+
+ char c = 0;
+ QCOMPARE(f.read(&c, 1), 1); // this ought to block
+ QCOMPARE(c, '\2');
+ thr->wait();
}
+
+void tst_QFile::socketPair()
+{
+#if defined(Q_OS_VXWORKS)
+ QSKIP("socketpair is not available on Vxworks");
+#else
+ int pipes[2] = { -1, -1 };
+ QVERIFY2(socketpair(AF_UNIX, SOCK_STREAM, 0, pipes) == 0, qPrintable(qt_error_string()));
+ unixPipe_helper(pipes);
+ if (pipes[0] != -1)
+ qt_safe_close(pipes[0]);
+ qt_safe_close(pipes[1]);
#endif
+}
+#endif /* UNIX && !WASM; */
void tst_QFile::textFile()
{
- const char *openMode = QOperatingSystemVersion::current().type() != QOperatingSystemVersion::Windows
- ? "w" : "wt";
- StdioFileGuard fs(fopen("writeabletextfile", openMode));
+ // The "t" is ignored everywhere except on Windows
+ StdioFileGuard fs(fopen("writeabletextfile", "wt"));
QVERIFY(fs);
QFile f;
QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n");
@@ -2678,7 +2973,7 @@ void tst_QFile::renameWithAtEndSpecialFile() const
class PeculiarAtEnd : public QFile
{
public:
- virtual bool atEnd() const
+ virtual bool atEnd() const override
{
return true;
}
@@ -2787,9 +3082,9 @@ void tst_QFile::appendAndRead()
void tst_QFile::miscWithUncPathAsCurrentDir()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QString current = QDir::currentPath();
- const QString path = QLatin1String("//") + QtNetworkSettings::winServerName()
+ const QString path = QLatin1String("//") + QTest::uncServerName()
+ QLatin1String("/testshare");
QVERIFY2(QDir::setCurrent(path), qPrintable(QDir::toNativeSeparators(path)));
QFile file("test.pri");
@@ -2817,13 +3112,16 @@ void tst_QFile::handle()
QVERIFY(fd > 2);
QCOMPARE(int(file.handle()), fd);
char c = '\0';
- const auto readResult = QT_READ(int(file.handle()), &c, 1);
- QCOMPARE(readResult, static_cast<decltype(readResult)>(1));
+ {
+ const auto readResult = QT_READ(int(file.handle()), &c, 1);
+ decltype(readResult) expected = 1;
+ QCOMPARE(readResult, expected);
+ }
QCOMPARE(c, '/');
// test if the QFile and the handle remain in sync
QVERIFY(file.getChar(&c));
- QCOMPARE(c, '*');
+ QCOMPARE(c, '/');
// same, but read from QFile first now
file.close();
@@ -2838,22 +3136,22 @@ void tst_QFile::handle()
QCOMPARE(QT_READ(fd, &c, 1), 1);
#endif
- QCOMPARE(c, '*');
+ QCOMPARE(c, '/');
//test round trip of adopted stdio file handle
QFile file2;
StdioFileGuard fp(fopen(qPrintable(m_testSourceFile), "r"));
QVERIFY(fp);
- file2.open(fp, QIODevice::ReadOnly);
- QCOMPARE(int(file2.handle()), int(fileno(fp)));
- QCOMPARE(int(file2.handle()), int(fileno(fp)));
+ QVERIFY(file2.open(fp, QIODevice::ReadOnly));
+ QCOMPARE(int(file2.handle()), int(QT_FILENO(fp)));
+ QCOMPARE(int(file2.handle()), int(QT_FILENO(fp)));
fp.close();
//test round trip of adopted posix file handle
#ifdef Q_OS_UNIX
QFile file3;
fd = QT_OPEN(qPrintable(m_testSourceFile), QT_OPEN_RDONLY);
- file3.open(fd, QIODevice::ReadOnly);
+ QVERIFY(file3.open(fd, QIODevice::ReadOnly));
QCOMPARE(int(file3.handle()), fd);
QT_CLOSE(fd);
#endif
@@ -2876,12 +3174,8 @@ void tst_QFile::nativeHandleLeaks()
}
#ifdef Q_OS_WIN
-# ifndef Q_OS_WINRT
handle1 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-# else
- handle1 = ::CreateFile2(L"qt_file.tmp", GENERIC_READ, 0, OPEN_ALWAYS, NULL);
-# endif
QVERIFY( INVALID_HANDLE_VALUE != handle1 );
QVERIFY( ::CloseHandle(handle1) );
#endif
@@ -2895,12 +3189,8 @@ void tst_QFile::nativeHandleLeaks()
}
#ifdef Q_OS_WIN
-# ifndef Q_OS_WINRT
handle2 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-# else
- handle2 = ::CreateFile2(L"qt_file.tmp", GENERIC_READ, 0, OPEN_ALWAYS, NULL);
-# endif
QVERIFY( INVALID_HANDLE_VALUE != handle2 );
QVERIFY( ::CloseHandle(handle2) );
#endif
@@ -3173,13 +3463,15 @@ void tst_QFile::mapResource_data()
QString validFile = ":/tst_qfileinfo/resources/file1.ext1";
QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1";
+ const char modes[] = "invalid";
for (int i = 0; i < 2; ++i) {
QString file = (i == 0) ? validFile : invalidFile;
- QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file;
- QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file;
- QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file;
- QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file;
+ const char *mode = i == 0 ? modes + 2 : modes;
+ QTest::addRow("0, 0 (%s)", mode) << 0 << 0 << QFile::UnspecifiedError << file;
+ QTest::addRow("0, BIG (%s)", mode) << 0 << 4096 << QFile::UnspecifiedError << file;
+ QTest::addRow("-1, 0 (%s)", mode) << -1 << 0 << QFile::UnspecifiedError << file;
+ QTest::addRow("0, -1 (%s)", mode) << 0 << -1 << QFile::UnspecifiedError << file;
}
QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile;
@@ -3197,7 +3489,7 @@ void tst_QFile::mapResource()
QCOMPARE(file.error(), error);
QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0));
if (error == QFile::NoError)
- QCOMPARE(QString(memory[0]), QString::number(offset + 1));
+ QCOMPARE(QString(QChar(memory[0])), QString::number(offset + 1));
QVERIFY(file.unmap(memory));
}
@@ -3250,7 +3542,7 @@ void tst_QFile::mapOpenMode()
*memory = 'a';
file.unmap(memory);
file.close();
- file.open(QIODevice::OpenMode(openMode));
+ QVERIFY(file.open(QIODevice::OpenMode(openMode)));
file.seek(0);
char c;
QVERIFY(file.getChar(&c));
@@ -3397,7 +3689,7 @@ void tst_QFile::openStandardStreamsFileDescriptors()
{
QFile in;
- in.open(STDIN_FILENO, QIODevice::ReadOnly);
+ QVERIFY(in.open(STDIN_FILENO, QIODevice::ReadOnly));
QCOMPARE( in.pos(), streamCurrentPosition(STDIN_FILENO) );
QCOMPARE( in.size(), streamExpectedSize(STDIN_FILENO) );
}
@@ -3411,7 +3703,7 @@ void tst_QFile::openStandardStreamsFileDescriptors()
{
QFile err;
- err.open(STDERR_FILENO, QIODevice::WriteOnly);
+ QVERIFY(err.open(STDERR_FILENO, QIODevice::WriteOnly));
QCOMPARE( err.pos(), streamCurrentPosition(STDERR_FILENO) );
QCOMPARE( err.size(), streamExpectedSize(STDERR_FILENO) );
}
@@ -3427,21 +3719,21 @@ void tst_QFile::openStandardStreamsBufferedStreams()
// Using streams
{
QFile in;
- in.open(stdin, QIODevice::ReadOnly);
+ QVERIFY(in.open(stdin, QIODevice::ReadOnly));
QCOMPARE( in.pos(), streamCurrentPosition(stdin) );
QCOMPARE( in.size(), streamExpectedSize(QT_FILENO(stdin)) );
}
{
QFile out;
- out.open(stdout, QIODevice::WriteOnly);
+ QVERIFY(out.open(stdout, QIODevice::WriteOnly));
QCOMPARE( out.pos(), streamCurrentPosition(stdout) );
QCOMPARE( out.size(), streamExpectedSize(QT_FILENO(stdout)) );
}
{
QFile err;
- err.open(stderr, QIODevice::WriteOnly);
+ QVERIFY(err.open(stderr, QIODevice::WriteOnly));
QCOMPARE( err.pos(), streamCurrentPosition(stderr) );
QCOMPARE( err.size(), streamExpectedSize(QT_FILENO(stderr)) );
}
@@ -3495,7 +3787,7 @@ void tst_QFile::caseSensitivity()
{
#if defined(Q_OS_WIN)
const bool caseSensitive = false;
-#elif defined(Q_OS_MAC)
+#elif defined(Q_OS_DARWIN)
const bool caseSensitive = pathconf(QDir::currentPath().toLatin1().constData(), _PC_CASE_SENSITIVE);
#else
const bool caseSensitive = true;
@@ -3509,11 +3801,16 @@ void tst_QFile::caseSensitivity()
QVERIFY(f.write(testData));
f.close();
}
- QStringList alternates;
QFileInfo fi(filename);
QVERIFY(fi.exists());
- alternates << "file.txt" << "File.TXT" << "fIlE.TxT" << fi.absoluteFilePath().toUpper() << fi.absoluteFilePath().toLower();
- foreach (QString alt, alternates) {
+ const auto alternates = {
+ u"file.txt"_s,
+ u"File.TXT"_s,
+ u"fIlE.TxT"_s,
+ fi.absoluteFilePath().toUpper(),
+ fi.absoluteFilePath().toLower(),
+ };
+ for (const QString &alt : alternates) {
QFileInfo fi2(alt);
QCOMPARE(fi2.exists(), !caseSensitive);
QCOMPARE(fi.size() == fi2.size(), !caseSensitive);
@@ -3668,5 +3965,432 @@ void tst_QFile::reuseQFile()
}
}
+void tst_QFile::moveToTrash_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<bool>("create");
+ QTest::addColumn<bool>("result");
+
+ // success cases
+ {
+ QTemporaryFile temp(QDir::tempPath() + "/tst_qfile-moveToTrash-XXXXXX");
+ if (!temp.open())
+ QSKIP("Failed to create temporary file!");
+ QTest::newRow("temporary file") << temp.fileName() << true << true;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
+ if (QDir::tempPath() == "/tmp")
+ QTest::newRow("var-temporary file") << "/var" + temp.fileName() << true << true;
+#endif
+ }
+ {
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qfile-moveToTrash-XXXXXX");
+ if (!tempDir.isValid())
+ QSKIP("Failed to create temporary directory!");
+ tempDir.setAutoRemove(false);
+ QTest::newRow("temporary dir")
+ << tempDir.path() + QLatin1Char('/')
+ << true << true;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
+ if (QDir::tempPath() == "/tmp")
+ QTest::newRow("var-temporary dir") << "/var" + tempDir.path() << true << true;
+#endif
+ }
+ {
+ QTemporaryDir homeDir(QDir::homePath() + QLatin1String("/tst_qfile.moveToTrash-XXXXXX"));
+ if (!homeDir.isValid())
+ QSKIP("Failed to create temporary directory in $HOME!");
+ QTemporaryFile homeFile(homeDir.path()
+ + QLatin1String("/tst_qfile-moveToTrash-XXXXX"));
+ if (!homeFile.open())
+ QSKIP("Failed to create temporary file in $HOME");
+ homeDir.setAutoRemove(false);
+ QTest::newRow("home file")
+ << homeFile.fileName()
+ << true << true;
+
+ QTest::newRow("home dir")
+ << homeDir.path() + QLatin1Char('/')
+ << true << true;
+ }
+ QTest::newRow("relative") << QStringLiteral("tst_qfile-moveToTrash.tmp") << true << true;
+
+ // failure cases
+ QTest::newRow("root") << QDir::rootPath() << false << false;
+ QTest::newRow("no-such-file") << QString::fromLatin1("no/such/file") << false << false;
+}
+
+void tst_QFile::moveToTrash()
+{
+#if defined(Q_OS_ANDROID) or defined(Q_OS_WEBOS) or defined(Q_OS_VXWORKS)
+ QSKIP("This platform doesn't implement a trash bin");
+#endif
+ QFETCH(QString, source);
+ QFETCH(bool, create);
+ QFETCH(bool, result);
+
+ auto ensureFile = [](const QString &source, bool create) {
+ if (QFileInfo::exists(source) || !create)
+ return;
+ if (source.endsWith(QLatin1Char('/'))) {
+ QDir::root().mkdir(source);
+ QFile file(source + QLatin1String("test"));
+ if (!file.open(QIODevice::WriteOnly))
+ QSKIP("Couldn't create directory with file");
+ } else {
+ QFile sourceFile(source);
+ QVERIFY2(sourceFile.open(QFile::WriteOnly | QFile::Text), qPrintable(sourceFile.errorString()));
+ sourceFile.close();
+ }
+ };
+ auto cleanupFile = [source, create]() {
+ if (!QFileInfo::exists(source) || !create)
+ return;
+ if (source.endsWith(QLatin1Char('/'))) {
+ QDir(source).removeRecursively();
+ } else {
+ QFile sourceFile(source);
+ sourceFile.remove();
+ }
+ };
+
+ ensureFile(source, create);
+ if (!QFileInfo::exists(source) && create) return;
+
+ /* This test makes assumptions about the file system layout
+ which might be wrong - moveToTrash may fail if the file lives
+ on a file system that is different from the home file system, and
+ has no .Trash directory.
+ */
+ const QStorageInfo sourceStorage(source);
+ const bool mayFail = sourceStorage.isValid()
+ && QStorageInfo(source) != QStorageInfo(QDir::home());
+
+ // non-static version
+ {
+ QFile sourceFile(source);
+ const bool success = sourceFile.moveToTrash();
+
+ // tolerate moveToTrash failing
+ if (result && !success && mayFail)
+ result = false;
+
+ if (result) {
+ // if any of the test fails, we still want to remove the file
+ auto onFailure = qScopeGuard(cleanupFile);
+ QVERIFY2(success, qPrintable(sourceFile.errorString()));
+ QCOMPARE(sourceFile.error(), QFile::NoError);
+ QVERIFY(source != sourceFile.fileName());
+ if (!sourceFile.fileName().isEmpty()) {
+ QVERIFY2(sourceFile.exists(), qPrintable(sourceFile.fileName()));
+ // remove file/dir in trash as well, don't fill disk
+ if (source.endsWith(QLatin1Char('/')))
+ QDir(sourceFile.fileName()).removeRecursively();
+ else
+ sourceFile.remove();
+ }
+ } else {
+ QVERIFY(!success);
+ QVERIFY(!sourceFile.errorString().isEmpty());
+ QCOMPARE(source, sourceFile.fileName());
+ }
+ }
+
+ // don't retry
+ if (mayFail)
+ return;
+
+ // static version
+ {
+ ensureFile(source, create);
+ if (!QFileInfo::exists(source) && create) return;
+ QString pathInTrash;
+ const bool success = QFile::moveToTrash(source, &pathInTrash);
+ QCOMPARE(success, result);
+ if (result) {
+ auto onFailure = qScopeGuard(cleanupFile);
+ QVERIFY(source != pathInTrash);
+ if (!pathInTrash.isEmpty()) {
+ // remove file/dir in trash as well, don't fill disk
+ QVERIFY2(QFile::exists(pathInTrash), qPrintable(pathInTrash));
+ if (source.endsWith(QLatin1Char('/')))
+ QDir(pathInTrash).removeRecursively();
+ else
+ QFile::remove(pathInTrash);
+ }
+ }
+ }
+}
+
+void tst_QFile::moveToTrashDuplicateName()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_WEBOS) || defined(Q_OS_VXWORKS)
+ QSKIP("This platform doesn't implement a trash bin");
+#endif
+ QString origFileName = []() {
+ QTemporaryFile temp(QDir::homePath() + "/tst_qfile.moveToTrashOpenFile.XXXXXX");
+ temp.setAutoRemove(false);
+ if (!temp.open())
+ qWarning("Failed to create temporary file: %ls", qUtf16Printable(temp.errorString()));
+ return temp.fileName();
+ }();
+
+ QFile f1(origFileName);
+ QFile f2(origFileName);
+ [&] {
+ QByteArrayView message1 = "Hello, World\n";
+ QVERIFY2(f1.open(QIODevice::ReadWrite | QIODevice::Unbuffered), qPrintable(f1.errorString()));
+ f1.write(message1.data(), message1.size());
+ QVERIFY2(f1.moveToTrash(), qPrintable(f1.errorString()));
+
+ QByteArrayView message2 = "Good morning, Vietnam!\n";
+ QVERIFY2(f2.open(QIODevice::ReadWrite | QIODevice::Unbuffered | QIODevice::NewOnly),
+ qPrintable(f2.errorString()));
+ f2.write(message2.data(), message2.size());
+ QVERIFY2(f2.moveToTrash(), qPrintable(f2.errorString()));
+
+ QCOMPARE_NE(f1.fileName(), f2.fileName());
+ }();
+ f1.remove();
+ if (!f2.fileName().isEmpty())
+ f2.remove();
+ QFile::remove(origFileName);
+}
+
+void tst_QFile::moveToTrashOpenFile_data()
+{
+ QTest::addColumn<bool>("useStatic");
+ QTest::addColumn<bool>("success");
+
+ // QFile::moveToTrash() non-static member closes the file before trashing,
+ // so this must always succeed.
+ QTest::newRow("member") << false << true;
+
+ // QFile::moveToTrash() static member cannot close the file because it
+ // operates on another QFile, so this operation will fail on OSes that do
+ // not permit deleting open files.
+ QTest::newRow("static") << true
+#ifdef Q_OS_WIN
+ << false;
+#else
+ << true;
+#endif
+}
+
+void tst_QFile::moveToTrashOpenFile()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_WEBOS) || defined(Q_OS_VXWORKS)
+ QSKIP("This platform doesn't implement a trash bin");
+#endif
+ QFETCH(bool, useStatic);
+ QFETCH(bool, success);
+ const QByteArrayView contents = "Hello, World\n";
+
+ QString newFileName, origFileName;
+ auto cleanup = qScopeGuard([&] {
+ if (!origFileName.isEmpty())
+ QFile::remove(origFileName);
+ if (!newFileName.isEmpty() && newFileName != origFileName)
+ QFile::remove(newFileName);
+ });
+
+ origFileName = []() {
+ QTemporaryFile temp(QDir::homePath() + "/tst_qfile.moveToTrashOpenFile.XXXXXX");
+ temp.setAutoRemove(false);
+ if (!temp.open())
+ qWarning("Failed to create temporary file: %ls", qUtf16Printable(temp.errorString()));
+ return temp.fileName();
+ }();
+
+ QFile f;
+ f.setFileName(origFileName);
+ QVERIFY2(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered), qPrintable(f.errorString()));
+ f.write(contents.data(), contents.size());
+
+ QString errorString;
+ auto doMoveToTrash = [&](QFile *f) {
+ if (!f->moveToTrash())
+ errorString = f->errorString();
+ newFileName = f->fileName();
+ };
+ if (useStatic) {
+ // it's the same as the static QFile::moveToTrash(), but gives us
+ // the error string
+ QFile other(origFileName);
+ doMoveToTrash(&other);
+ } else {
+ doMoveToTrash(&f);
+ }
+ QCOMPARE_NE(f.fileName(), QString());
+
+ if (success) {
+ QCOMPARE(errorString, QString());
+ QCOMPARE_NE(newFileName, origFileName); // must have changed!
+ QVERIFY(!QFile::exists(origFileName));
+ QVERIFY(QFile::exists(newFileName));
+ QCOMPARE(QFileInfo(newFileName).size(), contents.size());
+ } else {
+ QCOMPARE_NE(errorString, QString());
+ QCOMPARE(newFileName, origFileName); // mustn't have changed!
+ QVERIFY(QFile::exists(origFileName));
+ QCOMPARE(QFileInfo(origFileName).size(), contents.size());
+ }
+}
+
+void tst_QFile::moveToTrashXdgSafety()
+{
+#if defined(Q_OS_VXWORKS)
+ QSKIP("This platform doesn't implement a trash bin");
+#endif
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID) || defined(Q_OS_WEBOS)
+ QSKIP("This test is specific to XDG Unix systems");
+#else
+ QDir(m_temporaryDir.path()).mkdir("emptydir");
+
+ // See if we can find a writable volume to conduct our tests on
+ QString volumeRoot;
+ QStorageInfo homeVolume(QDir::homePath());
+ auto isVolumeSuitable = [this](const QString &rootPath) {
+ return QFile::link(m_temporaryDir.path() + "/emptydir", rootPath + "/.Trash");
+ };
+ for (const QStorageInfo &volume : QStorageInfo::mountedVolumes()) {
+ if (volume.isRoot())
+ continue;
+ if (volume == homeVolume)
+ continue;
+
+ if (isVolumeSuitable(volume.rootPath())) {
+ volumeRoot = volume.rootPath();
+ break;
+ }
+ }
+
+# ifdef Q_OS_LINUX
+ // fallback to /dev/shm, which is usually a tmpfs but is ignored by
+ // QStorageInfo as a virtual filesystem
+ if (volumeRoot.isEmpty() && isVolumeSuitable("/dev/shm"))
+ volumeRoot = "/dev/shm";
+# endif
+
+ if (volumeRoot.isEmpty())
+ QSKIP("Could not find any suitable volume to run this test with");
+
+ QDir genericTrashDir = volumeRoot + "/.Trash";
+ auto cleanup = qScopeGuard([&] {
+ if (QFileInfo(genericTrashDir.path()).isDir())
+ genericTrashDir.removeRecursively();
+ else
+ QFile::remove(genericTrashDir.path());
+ });
+
+ QString testFileName = volumeRoot + "/tst_qfile.moveToTrashSafety." + QString::number(getpid());
+ auto tryTrashing = [&] {
+ static int counter = 0;
+ QFile f(testFileName + u'.' + QString::number(counter++));
+ if (!f.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
+ qWarning("Failed to create temporary file: %ls", qUtf16Printable(f.errorString()));
+ return false;
+ }
+ bool ok = f.moveToTrash();
+ f.remove();
+ f.close();
+ return ok;
+ };
+
+ QTest::ignoreMessage(QtCriticalMsg,
+ "Warning: '" + QFile::encodeName(genericTrashDir.absolutePath())
+ + "' is a symlink to '" + QFile::encodeName(m_temporaryDir.path())
+ + "/emptydir'");
+ QVERIFY(tryTrashing());
+ QVERIFY(genericTrashDir.entryList(QDir::NoDotAndDotDot).isEmpty());
+
+ QFile::remove(genericTrashDir.path());
+ genericTrashDir.mkdir(genericTrashDir.path(), QFile::ExeOwner | QFile::ReadOwner);
+ QTest::ignoreMessage(QtCriticalMsg, "Warning: '" + QFile::encodeName(genericTrashDir.absolutePath())
+ + "' doesn't have sticky bit set!");
+ QVERIFY(tryTrashing());
+ QVERIFY(genericTrashDir.entryList(QDir::NoDotAndDotDot).isEmpty());
+
+ if (geteuid() != 0) {
+ // set the sticky bit, but make the dir unwritable; there'll be no
+ // warning and we should just fall back to the next option
+ chmod(QFile::encodeName(genericTrashDir.path()), 01555);
+ QVERIFY(tryTrashing());
+ QVERIFY(genericTrashDir.entryList(QDir::NoDotAndDotDot).isEmpty());
+
+ // ditto for our user's subdir now
+ chmod(QFile::encodeName(genericTrashDir.path()), 01755);
+ genericTrashDir.mkdir(QString::number(getuid()), QFile::ReadOwner);
+ QVERIFY(tryTrashing());
+ }
+#endif
+}
+
+void tst_QFile::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+ namespace fs = std::filesystem;
+ auto toFSPath = [](const QFile &file) { return fs::path(file.fileName().toStdU16String()); };
+ fs::path path { "./path" };
+ QFile file(path);
+ QCOMPARE(toFSPath(file), path);
+
+ QCOMPARE(path, file.filesystemFileName());
+
+ {
+ QFile parentedFile(path, this);
+ QCOMPARE(file.fileName(), parentedFile.fileName());
+ QCOMPARE(parentedFile.parent(), this);
+ }
+
+ path = path / "filename";
+ file.setFileName(path);
+ QCOMPARE(toFSPath(file), path);
+
+ path = "test-file";
+ file.setFileName(path);
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.close();
+
+ path = "tile-fest";
+ QVERIFY(file.rename(path));
+ QVERIFY(fs::exists(path));
+#ifdef Q_OS_WIN
+ fs::path linkfile { "test-link.lnk" };
+#else
+ fs::path linkfile { "test-link" };
+#endif
+ QVERIFY(file.link(linkfile));
+ QVERIFY(fs::exists(linkfile));
+ QVERIFY(QFile::remove(linkfile));
+ QVERIFY(QFile::link(file.filesystemFileName(), linkfile));
+ QVERIFY(fs::exists(linkfile));
+ QCOMPARE(QFileInfo(QFile::filesystemSymLinkTarget(linkfile)),
+ QFileInfo(file.filesystemFileName()));
+ QCOMPARE(QFileInfo(QFile(linkfile).filesystemSymLinkTarget()),
+ QFileInfo(file.filesystemFileName()));
+
+ fs::path copyfile { "copy-file" };
+ QVERIFY(file.copy(copyfile));
+ QVERIFY(fs::exists(copyfile));
+ QVERIFY(QFile::remove(copyfile));
+ QVERIFY(QFile::copy(file.filesystemFileName(), copyfile));
+ QVERIFY(fs::exists(copyfile));
+
+ QFileDevice::Permissions p = QFile::permissions(path);
+ QVERIFY(p.testFlag(QFile::WriteUser) || p.testFlag(QFile::WriteOwner)); // some we know for sure
+ if (p.testFlag(QFile::ReadUser))
+ p.setFlag(QFile::ReadUser, false);
+ else if (p.testFlag(QFile::ReadOwner))
+ p.setFlag(QFile::ReadOwner, false);
+ QVERIFY(QFile::setPermissions(path, p));
+
+ path = "test-exists";
+ fs::create_directory(path);
+ QVERIFY(QFile::exists(path) == fs::exists(path));
+#else
+ QSKIP("Not supported");
+#endif
+}
+
QTEST_MAIN(tst_QFile)
#include "tst_qfile.moc"
diff --git a/tests/auto/corelib/io/qfileinfo/CMakeLists.txt b/tests/auto/corelib/io/qfileinfo/CMakeLists.txt
new file mode 100644
index 0000000000..3b997e1bca
--- /dev/null
+++ b/tests/auto/corelib/io/qfileinfo/CMakeLists.txt
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfileinfo Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfileinfo LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfileinfo
+ SOURCES
+ tst_qfileinfo.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
+
+# Resources:
+set(qfileinfo_resource_files
+ "resources/"
+)
+
+qt_internal_add_resource(tst_qfileinfo "qfileinfo"
+ PREFIX
+ "/tst_qfileinfo/"
+ FILES
+ ${qfileinfo_resource_files}
+)
+set(testdata_resource_files
+ "resources/file1"
+ "resources/file1.ext1"
+ "resources/file1.ext1.ext2"
+ "tst_qfileinfo.cpp"
+)
+
+qt_internal_add_resource(tst_qfileinfo "testdata"
+ PREFIX
+ "/testdata"
+ FILES
+ ${testdata_resource_files}
+)
+
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qfileinfo CONDITION WIN32
+ LIBRARIES
+ advapi32
+ netapi32
+)
+
+if (APPLE)
+ enable_language(OBJCXX)
+ set_source_files_properties(tst_qfileinfo.cpp PROPERTIES LANGUAGE OBJCXX)
+endif()
diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
deleted file mode 100644
index 496729f9f1..0000000000
--- a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfileinfo
-QT = core-private testlib
-SOURCES = tst_qfileinfo.cpp
-RESOURCES += qfileinfo.qrc \
- testdata.qrc
-
-win32:!winrt: LIBS += -ladvapi32 -lnetapi32
diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.qrc b/tests/auto/corelib/io/qfileinfo/qfileinfo.qrc
deleted file mode 100644
index 2c63d8afeb..0000000000
--- a/tests/auto/corelib/io/qfileinfo/qfileinfo.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/tst_qfileinfo/">
- <file>resources/</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qfileinfo/testdata.qrc b/tests/auto/corelib/io/qfileinfo/testdata.qrc
deleted file mode 100644
index d2974bae77..0000000000
--- a/tests/auto/corelib/io/qfileinfo/testdata.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
- <qresource prefix="/testdata">
- <file>resources/file1</file>
- <file>resources/file1.ext1</file>
- <file>resources/file1.ext1.ext2</file>
- <file>tst_qfileinfo.cpp</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index baf78f6a04..f7d531f61f 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -1,32 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QStandardPaths>
+#include <QScopeGuard>
#include <qfile.h>
#include <qdir.h>
@@ -48,31 +26,28 @@
#endif
#ifdef Q_OS_WIN
#include <qt_windows.h>
-#if !defined(Q_OS_WINRT)
+#include <private/qwinregistry_p.h>
#include <lm.h>
#endif
-#endif
#include <qplatformdefs.h>
#include <qdebug.h>
-#if defined(Q_OS_WIN)
-#include "../../../network-settings.h"
-#endif
#include <private/qfileinfo_p.h>
#include "../../../../shared/filesystem.h"
-#if defined(Q_OS_VXWORKS) || defined(Q_OS_WINRT)
+#if defined(Q_OS_MACOS)
+#include <Foundation/Foundation.h>
+#endif
+
+#if defined(Q_OS_VXWORKS)
#define Q_NO_SYMLINKS
#endif
#if defined(Q_OS_WIN)
-QT_BEGIN_NAMESPACE
-extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
-QT_END_NAMESPACE
-# ifndef Q_OS_WINRT
bool IsUserAdmin();
-# endif
#endif
+using namespace Qt::StringLiterals;
+
inline bool qIsLikelyToBeFat(const QString &path)
{
QByteArray name = QStorageInfo(path).fileSystemType().toLower();
@@ -95,32 +70,12 @@ inline bool qIsLikelyToBeNfs(const QString &path)
#endif
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-enum NtfsTargetType {
- NtfsTargetFile = 0x0,
- NtfsTargetDir = 0x1
-};
-
-static bool createNtfsSymLinkHelper(const QString &path, const QString &target, NtfsTargetType targetType)
+#if defined(Q_OS_WIN)
+static QByteArray msgInsufficientPrivileges(const QString &errorMessage)
{
- DWORD dwFlags = targetType;
- DWORD err = ERROR_SUCCESS;
-
- SetLastError(0);
- const bool result = CreateSymbolicLink(reinterpret_cast<const wchar_t*>(path.utf16()),
- reinterpret_cast<const wchar_t*>(target.utf16()), dwFlags);
- err = GetLastError();
-
- // CreateSymbolicLink can return TRUE & still fail to create the link,
- // the error code in that case might be ERROR_PRIVILEGE_NOT_HELD (1314)
- if (!result || err != ERROR_SUCCESS) {
- qWarning() << "Error creating NTFS-symlink from:" << path << "to" << target << ":" << qt_error_string(err);
-
- return false;
- }
- return true;
+ return "Insufficient privileges (" + errorMessage.toLocal8Bit() + ')';
}
-#endif
+#endif // Q_OS_WIN
static QString seedAndTemplate()
{
@@ -218,6 +173,7 @@ private slots:
void systemFiles();
+ void compareCompiles();
void compare_data();
void compare();
@@ -226,15 +182,28 @@ private slots:
void fileTimes_data();
void fileTimes();
+ void setFileTimes();
void fakeFileTimes_data();
void fakeFileTimes();
void isSymLink_data();
void isSymLink();
+ void isSymbolicLink_data();
+ void isSymbolicLink();
+
+ void isShortcut_data();
+ void isShortcut();
+
+ void isAlias_data();
+ void isAlias();
+
+ void link_data();
+ void link();
+
void isHidden_data();
void isHidden();
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_DARWIN)
void isHiddenFromFinder();
#endif
@@ -246,7 +215,7 @@ private slots:
void refresh();
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
void ntfsJunctionPointsAndSymlinks_data();
void ntfsJunctionPointsAndSymlinks();
void brokenShortcut();
@@ -263,15 +232,16 @@ private slots:
void detachingOperations();
-#if !defined(Q_OS_WINRT)
void owner();
-#endif
void group();
void invalidState_data();
void invalidState();
void nonExistingFile();
+ void stdfilesystem();
+ void readSymLink();
+
private:
const QString m_currentDir;
QString m_sourceFile;
@@ -383,7 +353,7 @@ void tst_QFileInfo::isDir_data()
QFile::remove("brokenlink.lnk");
QFile::remove("dummyfile");
QFile file3("dummyfile");
- file3.open(QIODevice::WriteOnly);
+ QVERIFY(file3.open(QIODevice::WriteOnly));
if (file3.link("brokenlink.lnk")) {
file3.remove();
QFileInfo info3("brokenlink.lnk");
@@ -404,13 +374,13 @@ void tst_QFileInfo::isDir_data()
QTest::newRow("broken link") << "brokenlink.lnk" << false;
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
+#if defined(Q_OS_WIN)
QTest::newRow("drive 1") << "c:" << true;
QTest::newRow("drive 2") << "c:/" << true;
//QTest::newRow("drive 2") << "t:s" << false;
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
+#if defined(Q_OS_WIN)
+ const QString uncRoot = QStringLiteral("//") + QTest::uncServerName();
QTest::newRow("unc 1") << uncRoot << true;
QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << true;
QTest::newRow("unc 3") << uncRoot + "/testshare" << true;
@@ -446,14 +416,14 @@ void tst_QFileInfo::isRoot_data()
QTest::newRow("simple dir") << m_resourcesDir << false;
QTest::newRow("simple dir with slash") << (m_resourcesDir + QLatin1Char('/')) << false;
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
+#if defined(Q_OS_WIN)
QTest::newRow("drive 1") << "c:" << false;
QTest::newRow("drive 2") << "c:/" << true;
QTest::newRow("drive 3") << "p:/" << false;
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
+#if defined(Q_OS_WIN)
+ const QString uncRoot = QStringLiteral("//") + QTest::uncServerName();
QTest::newRow("unc 1") << uncRoot << true;
QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << true;
QTest::newRow("unc 3") << uncRoot + "/testshare" << false;
@@ -490,19 +460,14 @@ void tst_QFileInfo::exists_data()
QTest::newRow("data8") << (m_resourcesDir + "/*.ext1") << false;
QTest::newRow("data9") << (m_resourcesDir + "/file?.ext1") << false;
QTest::newRow("data10") << "." << true;
-
- // Skip for the WinRT case, as GetFileAttributesEx removes _any_
- // trailing whitespace and "." is a valid entry as seen in data10
-#ifndef Q_OS_WINRT
QTest::newRow("data11") << ". " << false;
-#endif
QTest::newRow("empty") << "" << false;
QTest::newRow("simple dir") << m_resourcesDir << true;
QTest::newRow("simple dir with slash") << (m_resourcesDir + QLatin1Char('/')) << true;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- const QString uncRoot = QStringLiteral("//") + QtNetworkSettings::winServerName();
+#if defined(Q_OS_WIN)
+ const QString uncRoot = QStringLiteral("//") + QTest::uncServerName();
QTest::newRow("unc 1") << uncRoot << true;
QTest::newRow("unc 2") << uncRoot + QLatin1Char('/') << true;
QTest::newRow("unc 3") << uncRoot + "/testshare" << true;
@@ -536,7 +501,7 @@ void tst_QFileInfo::absolutePath_data()
QTest::addColumn<QString>("filename");
QString drivePrefix;
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINRT))
+#if defined(Q_OS_WIN)
drivePrefix = QDir::currentPath().left(2);
QString nonCurrentDrivePrefix =
drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:");
@@ -546,8 +511,6 @@ void tst_QFileInfo::absolutePath_data()
QTest::newRow("<not current drive>:my.dll") << nonCurrentDrivePrefix + "my.dll"
<< nonCurrentDrivePrefix + "/"
<< "my.dll";
-#elif defined(Q_OS_WINRT)
- drivePrefix = QDir::currentPath().left(2);
#endif
QTest::newRow("0") << "/machine/share/dir1/" << drivePrefix + "/machine/share/dir1" << "";
QTest::newRow("1") << "/machine/share/dir1" << drivePrefix + "/machine/share" << "dir1";
@@ -555,7 +518,7 @@ void tst_QFileInfo::absolutePath_data()
QTest::newRow("3") << "/usr/local/bin/" << drivePrefix + "/usr/local/bin" << "";
QTest::newRow("/test") << "/test" << drivePrefix + "/" << "test";
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QTest::newRow("c:\\autoexec.bat") << "c:\\autoexec.bat" << "C:/"
<< "autoexec.bat";
QTest::newRow("c:autoexec.bat") << QDir::currentPath().left(2) + "autoexec.bat" << QDir::currentPath()
@@ -650,6 +613,8 @@ void tst_QFileInfo::canonicalFilePath()
QVERIFY(tempFile.open(QFile::WriteOnly));
QFileInfo fi(tempFile.fileName());
QCOMPARE(fi.canonicalFilePath(), QDir::currentPath() + "/" + fileName);
+ fi = QFileInfo(tempFile.fileName() + QString::fromLatin1("/"));
+ QCOMPARE(fi.canonicalFilePath(), QString::fromLatin1(""));
tempFile.remove();
// This used to crash on Mac, verify that it doesn't anymore.
@@ -693,7 +658,7 @@ void tst_QFileInfo::canonicalFilePath()
QFile file(QDir::currentPath());
if (file.link(link)) {
QFile tempfile("tempfile.txt");
- tempfile.open(QIODevice::ReadWrite);
+ QVERIFY(tempfile.open(QIODevice::ReadWrite));
tempfile.write("This file is generated by the QFileInfo autotest.");
QVERIFY(tempfile.flush());
tempfile.close();
@@ -729,15 +694,15 @@ void tst_QFileInfo::canonicalFilePath()
}
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
{
const QString linkTarget = QStringLiteral("res");
- BOOL ret = createNtfsSymLinkHelper(linkTarget, m_resourcesDir, NtfsTargetDir);
- if (!ret)
- QSKIP("Symbolic links aren't supported by FS");
+ const auto result = FileSystem::createSymbolicLink(linkTarget, m_resourcesDir);
+ if (result.dwErr == ERROR_PRIVILEGE_NOT_HELD)
+ QSKIP(msgInsufficientPrivileges(result.errorMessage));
+ QVERIFY2(result.dwErr == ERROR_SUCCESS, qPrintable(result.errorMessage));
QString currentPath = QDir::currentPath();
- bool is_res_Current = QDir::setCurrent(linkTarget);
- QCOMPARE(is_res_Current, true);
+ QVERIFY(QDir::setCurrent(linkTarget));
const QString actualCanonicalPath = QFileInfo("file1").canonicalFilePath();
QVERIFY(QDir::setCurrent(currentPath));
QCOMPARE(actualCanonicalPath, m_resourcesDir + QStringLiteral("/file1"));
@@ -799,7 +764,7 @@ void tst_QFileInfo::bundleName_data()
QTest::newRow("root") << "/" << "";
QTest::newRow("etc") << "/etc" << "";
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
QTest::newRow("safari") << "/Applications/Safari.app" << "Safari";
#endif
}
@@ -826,7 +791,7 @@ void tst_QFileInfo::dir_data()
QTest::newRow("absFilePath") << QDir::currentPath() + "/tmp.txt" << false << QDir::currentPath();
QTest::newRow("absFilePathAbsPath") << QDir::currentPath() + "/tmp.txt" << true << QDir::currentPath();
QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << true << ":/tst_qfileinfo/resources";
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QTest::newRow("driveWithSlash") << "C:/file1.ext1.ext2" << true << "C:/";
QTest::newRow("driveWithoutSlash") << QDir::currentPath().left(2) + "file1.ext1.ext2" << false << QDir::currentPath().left(2);
#endif
@@ -1017,7 +982,7 @@ void tst_QFileInfo::size()
void tst_QFileInfo::systemFiles()
{
-#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
+#if !defined(Q_OS_WIN)
QSKIP("This is a Windows only test");
#endif
QFileInfo fi("c:\\pagefile.sys");
@@ -1028,7 +993,11 @@ void tst_QFileInfo::systemFiles()
QCOMPARE(fi.metadataChangeTime(), fi.lastModified()); // On Windows, they're the same
QVERIFY(fi.birthTime().isValid());
QVERIFY(fi.birthTime() <= fi.lastModified());
- QCOMPARE(fi.created(), fi.birthTime()); // On Windows, they're the same
+}
+
+void tst_QFileInfo::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QFileInfo>();
}
void tst_QFileInfo::compare_data()
@@ -1057,7 +1026,7 @@ void tst_QFileInfo::compare_data()
<< m_sourceFile
#if defined(Q_OS_WIN)
<< true;
-#elif defined(Q_OS_MAC)
+#elif defined(Q_OS_DARWIN)
<< !pathconf(QDir::currentPath().toLatin1().constData(), _PC_CASE_SENSITIVE);
#else
<< false;
@@ -1066,7 +1035,7 @@ void tst_QFileInfo::compare_data()
void tst_QFileInfo::compare()
{
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_DARWIN)
if (qstrcmp(QTest::currentDataTag(), "casesense1") == 0)
QSKIP("Qt thinks all UNIX filesystems are case sensitive, see QTBUG-28246");
#endif
@@ -1075,7 +1044,7 @@ void tst_QFileInfo::compare()
QFETCH(QString, file2);
QFETCH(bool, same);
QFileInfo fi1(file1), fi2(file2);
- QCOMPARE(fi1 == fi2, same);
+ QT_TEST_EQUALITY_OPS(fi1, fi2, same);
}
void tst_QFileInfo::consistent_data()
@@ -1143,8 +1112,8 @@ void tst_QFileInfo::fileTimes()
{
// try to guess if file times on this filesystem round to the second
QFileInfo cwd(".");
- if (cwd.lastModified().toMSecsSinceEpoch() % 1000 == 0
- && cwd.lastRead().toMSecsSinceEpoch() % 1000 == 0) {
+ if (cwd.lastModified(QTimeZone::UTC).toMSecsSinceEpoch() % 1000 == 0
+ && cwd.lastRead(QTimeZone::UTC).toMSecsSinceEpoch() % 1000 == 0) {
fsClockSkew = sleepTime = 1000;
noAccessTime = qIsLikelyToBeFat(fileName);
@@ -1164,46 +1133,46 @@ void tst_QFileInfo::fileTimes()
QDateTime birthTime, writeTime, metadataChangeTime, readTime;
// --- Create file and write to it
- beforeBirth = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
+ beforeBirth = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew);
{
QFile file(fileName);
QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
QFileInfo fileInfo(fileName);
- birthTime = fileInfo.birthTime();
+ birthTime = fileInfo.birthTime(QTimeZone::UTC);
QVERIFY2(!birthTime.isValid() || birthTime > beforeBirth,
datePairString(birthTime, beforeBirth));
QTest::qSleep(sleepTime);
- beforeWrite = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
+ beforeWrite = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew);
QTextStream ts(&file);
- ts << fileName << endl;
+ ts << fileName << Qt::endl;
}
{
QFileInfo fileInfo(fileName);
- writeTime = fileInfo.lastModified();
+ writeTime = fileInfo.lastModified(QTimeZone::UTC);
QVERIFY2(writeTime > beforeWrite, datePairString(writeTime, beforeWrite));
- QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed
+ QCOMPARE(fileInfo.birthTime(QTimeZone::UTC), birthTime); // mustn't have changed
}
// --- Change the file's metadata
QTest::qSleep(sleepTime);
- beforeMetadataChange = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
+ beforeMetadataChange = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew);
{
QFile file(fileName);
file.setPermissions(file.permissions());
}
{
QFileInfo fileInfo(fileName);
- metadataChangeTime = fileInfo.metadataChangeTime();
+ metadataChangeTime = fileInfo.metadataChangeTime(QTimeZone::UTC);
QVERIFY2(metadataChangeTime > beforeMetadataChange,
datePairString(metadataChangeTime, beforeMetadataChange));
QVERIFY(metadataChangeTime >= writeTime); // not all filesystems can store both times
- QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed
+ QCOMPARE(fileInfo.birthTime(QTimeZone::UTC), birthTime); // mustn't have changed
}
// --- Read the file
QTest::qSleep(sleepTime);
- beforeRead = QDateTime::currentDateTime().addMSecs(-fsClockSkew);
+ beforeRead = QDateTime::currentDateTimeUtc().addMSecs(-fsClockSkew);
{
QFile file(fileName);
QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
@@ -1213,28 +1182,23 @@ void tst_QFileInfo::fileTimes()
}
QFileInfo fileInfo(fileName);
- readTime = fileInfo.lastRead();
- QCOMPARE(fileInfo.lastModified(), writeTime); // mustn't have changed
- QCOMPARE(fileInfo.birthTime(), birthTime); // mustn't have changed
+ readTime = fileInfo.lastRead(QTimeZone::UTC);
+ QCOMPARE(fileInfo.lastModified(QTimeZone::UTC), writeTime); // mustn't have changed
+ QCOMPARE(fileInfo.birthTime(QTimeZone::UTC), birthTime); // mustn't have changed
QVERIFY(readTime.isValid());
-#if defined(Q_OS_WINRT) || defined(Q_OS_QNX) || (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED))
+#if defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
noAccessTime = true;
#elif defined(Q_OS_WIN)
//In Vista the last-access timestamp is not updated when the file is accessed/touched (by default).
//To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
//is set to 0, in the test machine.
- HKEY key;
- if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\FileSystem",
- 0, KEY_READ, &key)) {
- DWORD disabledAccessTimes = 0;
- DWORD size = sizeof(DWORD);
- LONG error = RegQueryValueEx(key, L"NtfsDisableLastAccessUpdate"
- , NULL, NULL, (LPBYTE)&disabledAccessTimes, &size);
- if (ERROR_SUCCESS == error && disabledAccessTimes)
- noAccessTime = true;
- RegCloseKey(key);
- }
+ const auto disabledAccessTimes =
+ QWinRegistryKey(HKEY_LOCAL_MACHINE,
+ LR"(SYSTEM\CurrentControlSet\Control\FileSystem)")
+ .dwordValue(L"NtfsDisableLastAccessUpdate");
+ if (disabledAccessTimes.second && disabledAccessTimes.first != 0)
+ noAccessTime = true;
#endif
if (noAccessTime)
@@ -1244,6 +1208,21 @@ void tst_QFileInfo::fileTimes()
QVERIFY(writeTime < beforeRead);
}
+void tst_QFileInfo::setFileTimes()
+{
+ QByteArray data("OLE\nOLE\nOLE");
+ QTemporaryFile file;
+
+ QVERIFY(file.open());
+ QCOMPARE(file.write(data), data.size());
+ QCOMPARE(file.size(), data.size());
+
+ const QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-5000);
+ QVERIFY(file.setFileTime(before, QFile::FileModificationTime));
+ const QDateTime mtime = file.fileTime(QFile::FileModificationTime).toUTC();
+ QCOMPARE(mtime, before);
+}
+
void tst_QFileInfo::fakeFileTimes_data()
{
QTest::addColumn<QDateTime>("when");
@@ -1253,7 +1232,7 @@ void tst_QFileInfo::fakeFileTimes_data()
QTest::newRow("early") << QDateTime(QDate(1901, 12, 14), QTime(12, 0));
// QTBUG-12006 claims XP handled this (2010-Mar-26 8:46:10) wrong due to an MS API bug:
- QTest::newRow("XP-bug") << QDateTime::fromTime_t(1269593170);
+ QTest::newRow("XP-bug") << QDateTime::fromSecsSinceEpoch(1269593170);
}
void tst_QFileInfo::fakeFileTimes()
@@ -1261,7 +1240,7 @@ void tst_QFileInfo::fakeFileTimes()
QFETCH(QDateTime, when);
QFile file("faketimefile.txt");
- file.open(QIODevice::WriteOnly);
+ QVERIFY(file.open(QIODevice::WriteOnly));
file.write("\n", 1);
file.close();
@@ -1270,12 +1249,12 @@ void tst_QFileInfo::fakeFileTimes()
the file is open at the time. Of course, when writing, close() changes
modification time, so need to re-open for read in order to setFileTime().
*/
- file.open(QIODevice::ReadOnly);
+ QVERIFY(file.open(QIODevice::ReadOnly));
bool ok = file.setFileTime(when, QFileDevice::FileModificationTime);
file.close();
if (ok)
- QCOMPARE(QFileInfo(file.fileName()).lastModified(), when);
+ QCOMPARE(QFileInfo(file.fileName()).lastModified(QTimeZone::UTC), when);
else
QSKIP("Unable to set file metadata to contrived values");
}
@@ -1292,7 +1271,7 @@ void tst_QFileInfo::isSymLink_data()
QVERIFY(file1.link("link.lnk"));
QFile file2("dummyfile");
- file2.open(QIODevice::WriteOnly);
+ QVERIFY(file2.open(QIODevice::WriteOnly));
QVERIFY(file2.link("brokenlink.lnk"));
file2.remove();
@@ -1327,13 +1306,228 @@ void tst_QFileInfo::isSymLink()
#endif
}
+void tst_QFileInfo::isShortcut_data()
+{
+ QFile::remove("link.lnk");
+ QFile::remove("symlink.lnk");
+ QFile::remove("link");
+ QFile::remove("symlink");
+ QFile::remove("directory.lnk");
+ QFile::remove("directory");
+
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isShortcut");
+
+ QFile regularFile(m_sourceFile);
+ QTest::newRow("regular")
+ << regularFile.fileName() << false;
+ QTest::newRow("directory")
+ << QDir::currentPath() << false;
+#if defined(Q_OS_WIN)
+ // windows shortcuts
+ QVERIFY(regularFile.link("link.lnk"));
+ QTest::newRow("shortcut")
+ << "link.lnk" << true;
+ QVERIFY(regularFile.link("link"));
+ QTest::newRow("invalid-shortcut")
+ << "link" << false;
+ QVERIFY(QFile::link(QDir::currentPath(), "directory.lnk"));
+ QTest::newRow("directory-shortcut")
+ << "directory.lnk" << true;
+#endif
+}
+
+void tst_QFileInfo::isShortcut()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isShortcut);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isShortcut(), isShortcut);
+}
+
+void tst_QFileInfo::isAlias_data()
+{
+ QFile::remove("symlink");
+ QFile::remove("file-alias");
+ QFile::remove("directory-alias");
+
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isAlias");
+
+ QFile regularFile(m_sourceFile);
+ QTest::newRow("regular-file") << regularFile.fileName() << false;
+ QTest::newRow("directory") << QDir::currentPath() << false;
+
+#if defined(Q_OS_MACOS)
+ auto createAlias = [](const QString &target, const QString &alias) {
+ NSURL *targetUrl = [NSURL fileURLWithPath:target.toNSString()];
+ NSURL *aliasUrl = [NSURL fileURLWithPath:alias.toNSString()];
+ NSData *bookmarkData = [targetUrl bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile
+ includingResourceValuesForKeys:nil relativeToURL:nil error:nullptr];
+ Q_ASSERT(bookmarkData);
+
+ bool success = [NSURL writeBookmarkData:bookmarkData toURL:aliasUrl
+ options:NSURLBookmarkCreationSuitableForBookmarkFile error:nullptr];
+ Q_ASSERT(success);
+ };
+
+ regularFile.link("symlink");
+ QTest::newRow("symlink") << "symlink" << false;
+
+ createAlias(regularFile.fileName(), QDir::current().filePath("file-alias"));
+ QTest::newRow("file-alias") << "file-alias" << true;
+
+ createAlias(QDir::currentPath(), QDir::current().filePath("directory-alias"));
+ QTest::newRow("directory-alias") << "directory-alias" << true;
+
+ regularFile.copy("non-existing-file");
+ createAlias("non-existing-file", QDir::current().filePath("non-existing-file-alias"));
+ QDir::current().remove("non-existing-file");
+ QTest::newRow("non-existing-file-alias") << "non-existing-file-alias" << true;
+#endif
+}
+
+void tst_QFileInfo::isAlias()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isAlias);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isAlias(), isAlias);
+}
+
+void tst_QFileInfo::isSymbolicLink_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isSymbolicLink");
+
+ QFile regularFile(m_sourceFile);
+ QTest::newRow("regular")
+ << regularFile.fileName() << false;
+ QTest::newRow("directory")
+ << QDir::currentPath() << false;
+
+#ifndef Q_NO_SYMLINKS
+#if defined(Q_OS_WIN)
+ const auto creationResult = FileSystem::createSymbolicLink("symlink", m_sourceFile);
+ if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD) {
+ qWarning() << qPrintable(msgInsufficientPrivileges(creationResult.errorMessage));
+ } else {
+ QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
+ QTest::newRow("NTFS-symlink")
+ << "symlink" << true;
+ }
+#else // Unix:
+ QVERIFY(regularFile.link("symlink.lnk"));
+ QTest::newRow("symlink.lnk")
+ << "symlink.lnk" << true;
+ QVERIFY(regularFile.link("symlink"));
+ QTest::newRow("symlink")
+ << "symlink" << true;
+ QVERIFY(QFile::link(QDir::currentPath(), "directory"));
+ QTest::newRow("directory-symlink")
+ << "directory" << true;
+#endif
+#endif // !Q_NO_SYMLINKS
+}
+
+void tst_QFileInfo::isSymbolicLink()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isSymbolicLink);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isSymbolicLink(), isSymbolicLink);
+}
+
+void tst_QFileInfo::link_data()
+{
+ QFile::remove("link");
+ QFile::remove("link.lnk");
+ QFile::remove("brokenlink");
+ QFile::remove("brokenlink.lnk");
+ QFile::remove("dummyfile");
+ QFile::remove("relative/link");
+
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isShortcut");
+ QTest::addColumn<bool>("isSymbolicLink");
+ QTest::addColumn<QString>("linkTarget");
+
+ QFile file1(m_sourceFile);
+ QFile file2("dummyfile");
+ QVERIFY(file2.open(QIODevice::WriteOnly));
+
+ QTest::newRow("existent file") << m_sourceFile << false << false << "";
+#if defined(Q_OS_WIN)
+ // windows shortcuts
+ QVERIFY(file1.link("link.lnk"));
+ QTest::newRow("link.lnk")
+ << "link.lnk" << true << false << QFileInfo(m_sourceFile).absoluteFilePath();
+
+ QVERIFY(file2.link("brokenlink.lnk"));
+ QTest::newRow("broken link.lnk")
+ << "brokenlink.lnk" << true << false << QFileInfo("dummyfile").absoluteFilePath();
+#endif
+
+#ifndef Q_NO_SYMLINKS
+#if defined(Q_OS_WIN)
+ auto creationResult = FileSystem::createSymbolicLink("link", m_sourceFile);
+ if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD) {
+ qWarning() << qPrintable(msgInsufficientPrivileges(creationResult.errorMessage));
+ } else {
+ QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
+ QTest::newRow("link")
+ << "link" << false << true << QFileInfo(m_sourceFile).absoluteFilePath();
+ }
+
+ creationResult = FileSystem::createSymbolicLink("brokenlink", "dummyfile");
+ if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD) {
+ qWarning() << qPrintable(msgInsufficientPrivileges(creationResult.errorMessage));
+ } else {
+ QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
+ QTest::newRow("broken link")
+ << "brokenlink" << false << true << QFileInfo("dummyfile").absoluteFilePath();
+ }
+#else // Unix:
+ QVERIFY(file1.link("link"));
+ QTest::newRow("link")
+ << "link" << false << true << QFileInfo(m_sourceFile).absoluteFilePath();
+
+ QVERIFY(file2.link("brokenlink"));
+ QTest::newRow("broken link")
+ << "brokenlink" << false << true << QFileInfo("dummyfile").absoluteFilePath();
+
+ QDir::current().mkdir("relative");
+ QFile::link("../dummyfile", "relative/link");
+ QTest::newRow("relative link")
+ << "relative/link" << false << true << QFileInfo("dummyfile").absoluteFilePath();
+#endif
+#endif // !Q_NO_SYMLINKS
+ file2.remove();
+}
+
+void tst_QFileInfo::link()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isShortcut);
+ QFETCH(bool, isSymbolicLink);
+ QFETCH(QString, linkTarget);
+
+ QFileInfo fi(path);
+ QCOMPARE(fi.isShortcut(), isShortcut);
+ QCOMPARE(fi.isSymbolicLink(), isSymbolicLink);
+ QCOMPARE(fi.symLinkTarget(), linkTarget);
+}
+
void tst_QFileInfo::isHidden_data()
{
QTest::addColumn<QString>("path");
QTest::addColumn<bool>("isHidden");
- foreach (const QFileInfo& info, QDir::drives()) {
+ const auto drives = QDir::drives();
+ for (const QFileInfo& info : drives)
QTest::newRow(qPrintable("drive." + info.path())) << info.path() << false;
- }
#if defined(Q_OS_WIN)
QVERIFY(QDir("./hidden-directory").exists() || QDir().mkdir("./hidden-directory"));
@@ -1348,14 +1542,14 @@ void tst_QFileInfo::isHidden_data()
QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << true;
#endif
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_DARWIN)
// /bin has the hidden attribute on OS X
QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << true;
#elif !defined(Q_OS_WIN)
QTest::newRow("/bin/") << QString::fromLatin1("/bin/") << false;
#endif
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
QTest::newRow("mac_etc") << QString::fromLatin1("/etc") << true;
QTest::newRow("mac_private_etc") << QString::fromLatin1("/private/etc") << false;
QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false;
@@ -1371,7 +1565,7 @@ void tst_QFileInfo::isHidden()
QCOMPARE(fi.isHidden(), isHidden);
}
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_DARWIN)
void tst_QFileInfo::isHiddenFromFinder()
{
const char *filename = "test_foobar.txt";
@@ -1397,7 +1591,7 @@ void tst_QFileInfo::isBundle_data()
QTest::addColumn<QString>("path");
QTest::addColumn<bool>("isBundle");
QTest::newRow("root") << QString::fromLatin1("/") << false;
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications") << false;
QTest::newRow("mac_Applications") << QString::fromLatin1("/Applications/Safari.app") << true;
#endif
@@ -1451,14 +1645,14 @@ void tst_QFileInfo::refresh()
file.flush();
QFileInfo info(file);
- QDateTime lastModified = info.lastModified();
+ QDateTime lastModified = info.lastModified(QTimeZone::UTC);
QCOMPARE(info.size(), qint64(7));
QTest::qSleep(sleepTime);
QCOMPARE(file.write("JOJOJO"), qint64(6));
file.flush();
- QCOMPARE(info.lastModified(), lastModified);
+ QCOMPARE(info.lastModified(QTimeZone::UTC), lastModified);
QCOMPARE(info.size(), qint64(7));
#if defined(Q_OS_WIN)
@@ -1466,7 +1660,7 @@ void tst_QFileInfo::refresh()
#endif
info.refresh();
QCOMPARE(info.size(), qint64(13));
- QVERIFY(info.lastModified() > lastModified);
+ QVERIFY(info.lastModified(QTimeZone::UTC) > lastModified);
QFileInfo info2 = info;
QCOMPARE(info2.size(), info.size());
@@ -1475,11 +1669,26 @@ void tst_QFileInfo::refresh()
QCOMPARE(info2.size(), info.size());
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
+
+struct NtfsTestResource {
+
+ enum Type { None, SymLink, Junction };
+
+ explicit NtfsTestResource(Type tp = None, const QString &s = QString(), const QString &t = QString())
+ : source(s), target(t), type(tp) {}
+
+ QString source;
+ QString target;
+ Type type;
+};
+
+Q_DECLARE_METATYPE(NtfsTestResource)
+
void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
{
+ QTest::addColumn<NtfsTestResource>("resource");
QTest::addColumn<QString>("path");
- QTest::addColumn<bool>("isSymLink");
QTest::addColumn<QString>("linkTarget");
QTest::addColumn<QString>("canonicalFilePath");
@@ -1500,25 +1709,20 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString fileInSymlink(absSymlink);
fileInSymlink.append("\\file");
QFile file(fileInTarget);
- file.open(QIODevice::ReadWrite);
+ QVERIFY2(file.open(QIODevice::ReadWrite), qPrintable(file.errorString()));
file.close();
- bool result = true;
- if (!pwd.exists("abs_symlink"))
- result = createNtfsSymLinkHelper(absSymlink, absTarget, NtfsTargetDir);
- if (result && !pwd.exists(relSymlink))
- result = createNtfsSymLinkHelper(relSymlink, relTarget, NtfsTargetDir);
- if (!result) {
- //we need at least one data set for the test not to assert fail when skipping _data function
- QDir target("target");
- QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath();
- QSKIP("link not supported by FS or insufficient privilege");
- }
QVERIFY2(file.exists(), msgDoesNotExist(file.fileName()).constData());
- QTest::newRow("absolute dir symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
- QTest::newRow("relative dir symlink") << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
- QTest::newRow("file in symlink dir") << fileInSymlink << false << "" << target.canonicalPath().append("/file");
+ QTest::newRow("absolute dir symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, absSymlink, absTarget)
+ << absSymlink << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
+ QTest::newRow("relative dir symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, relSymlink, relTarget)
+ << relSymlink << QDir::fromNativeSeparators(absTarget) << target.canonicalPath();
+ QTest::newRow("file in symlink dir")
+ << NtfsTestResource()
+ << fileInSymlink << "" << target.canonicalPath().append("/file");
}
{
//File symlinks
@@ -1531,41 +1735,50 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString relSymlink = "rel_symlink.cpp";
QString relToRelTarget = QDir::toNativeSeparators(relativeDir.relativeFilePath(target.absoluteFilePath()));
QString relToRelSymlink = "relative/rel_symlink";
- QVERIFY(pwd.exists("abs_symlink.cpp") || createNtfsSymLinkHelper(absSymlink, absTarget, NtfsTargetFile));
- QVERIFY(pwd.exists(relSymlink) || createNtfsSymLinkHelper(relSymlink, relTarget, NtfsTargetFile));
- QVERIFY(pwd.exists(relToRelSymlink) || createNtfsSymLinkHelper(relToRelSymlink, relToRelTarget, NtfsTargetFile));
- QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
- QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
- QTest::newRow("relative to relative file symlink") << relToRelSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+
+ QTest::newRow("absolute file symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, absSymlink, absTarget)
+ << absSymlink << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+ QTest::newRow("relative file symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, relSymlink, relTarget)
+ << relSymlink << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
+ QTest::newRow("relative to relative file symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, relToRelSymlink, relToRelTarget)
+ << relToRelSymlink << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath();
}
{
// Symlink to UNC share
pwd.mkdir("unc");
- QString uncTarget = QStringLiteral("//") + QtNetworkSettings::winServerName() + "/testshare";
+ QString uncTarget = QStringLiteral("//") + QTest::uncServerName() + "/testshare";
QString uncSymlink = QDir::toNativeSeparators(pwd.absolutePath().append("\\unc\\link_to_unc"));
- QVERIFY(pwd.exists("link_to_unc") || createNtfsSymLinkHelper(uncSymlink, uncTarget, NtfsTargetDir));
- QTest::newRow("UNC symlink") << uncSymlink << true << uncTarget << uncTarget;
+ QTest::newRow("UNC symlink")
+ << NtfsTestResource(NtfsTestResource::SymLink, uncSymlink, uncTarget)
+ << QDir::fromNativeSeparators(uncSymlink) << QDir::fromNativeSeparators(uncTarget) << uncTarget;
}
//Junctions
QString target = "target";
QString junction = "junction_pwd";
- FileSystem::createNtfsJunction(target, junction);
QFileInfo targetInfo(target);
- QTest::newRow("junction_pwd") << junction << false << QString() << QString();
+ QTest::newRow("junction_pwd")
+ << NtfsTestResource(NtfsTestResource::Junction, junction, target)
+ << junction << QString() << QString();
QFileInfo fileInJunction(targetInfo.absoluteFilePath().append("/file"));
QFile file(fileInJunction.absoluteFilePath());
- file.open(QIODevice::ReadWrite);
+ QVERIFY2(file.open(QIODevice::ReadWrite), qPrintable(file.errorString()));
file.close();
QVERIFY2(file.exists(), msgDoesNotExist(file.fileName()).constData());
- QTest::newRow("file in junction") << fileInJunction.absoluteFilePath() << false << "" << fileInJunction.canonicalFilePath();
+ QTest::newRow("file in junction")
+ << NtfsTestResource()
+ << fileInJunction.absoluteFilePath() << QString() << fileInJunction.canonicalFilePath();
target = QDir::rootPath();
junction = "junction_root";
- FileSystem::createNtfsJunction(target, junction);
targetInfo.setFile(target);
- QTest::newRow("junction_root") << junction << false << QString() << QString();
+ QTest::newRow("junction_root")
+ << NtfsTestResource(NtfsTestResource::Junction, junction, target)
+ << junction << QString() << QString();
//Mountpoint
wchar_t buffer[MAX_PATH];
@@ -1574,35 +1787,83 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
QString rootVolume = QString::fromWCharArray(buffer);
junction = "mountpoint";
rootVolume.replace("\\\\?\\","\\??\\");
- FileSystem::createNtfsJunction(rootVolume, junction);
- QTest::newRow("mountpoint") << junction << false << QString() << QString();
+ QTest::newRow("mountpoint")
+ << NtfsTestResource(NtfsTestResource::Junction, junction, rootVolume)
+ << junction << QString() << QString();
}
void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
{
+ QFETCH(NtfsTestResource, resource);
QFETCH(QString, path);
- QFETCH(bool, isSymLink);
QFETCH(QString, linkTarget);
QFETCH(QString, canonicalFilePath);
+ bool isSymLink = false;
+ bool isJunction = false;
+ FileSystem::Result creationResult;
+ switch (resource.type) {
+ case NtfsTestResource::None:
+ break;
+ case NtfsTestResource::SymLink:
+ isSymLink = true;
+ creationResult = FileSystem::createSymbolicLink(resource.source, resource.target);
+ break;
+ case NtfsTestResource::Junction:
+ isJunction = true;
+ creationResult = FileSystem::createNtfsJunction(resource.target, resource.source);
+ if (creationResult.dwErr == ERROR_NOT_SUPPORTED) // Special value indicating non-NTFS drive
+ QSKIP(qPrintable(creationResult.errorMessage));
+ break;
+ }
+
+ if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD)
+ QSKIP(msgInsufficientPrivileges(creationResult.errorMessage));
+ QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
+
QFileInfo fi(path);
- const bool actualIsSymLink = fi.isSymLink();
- const QString actualSymLinkTarget = isSymLink ? fi.symLinkTarget() : QString();
- const QString actualCanonicalFilePath = isSymLink ? fi.canonicalFilePath() : QString();
- // Ensure that junctions, mountpoints are removed. If this fails, do not remove
- // temporary directory to prevent it from trashing the system.
- if (fi.isDir()) {
- if (!QDir().rmdir(fi.filePath())) {
- qWarning("Unable to remove NTFS junction '%s'', keeping '%s'.",
- qPrintable(fi.fileName()), qPrintable(QDir::toNativeSeparators(m_dir.path())));
- m_dir.setAutoRemove(false);
+ auto guard = qScopeGuard([&fi, this]() {
+ // Ensure that junctions, mountpoints are removed. If this fails, do not remove
+ // temporary directory to prevent it from trashing the system.
+ if (fi.isDir()) {
+ if (!QDir().rmdir(fi.filePath())) {
+ qWarning("Unable to remove NTFS junction '%ls', keeping '%ls'.",
+ qUtf16Printable(fi.fileName()),
+ qUtf16Printable(QDir::toNativeSeparators(m_dir.path())));
+ m_dir.setAutoRemove(false);
+ }
}
- }
- QCOMPARE(actualIsSymLink, isSymLink);
+ });
+ const QString actualCanonicalFilePath = fi.canonicalFilePath();
+ QCOMPARE(fi.isJunction(), isJunction);
+ QCOMPARE(fi.isSymbolicLink(), isSymLink);
if (isSymLink) {
- QCOMPARE(actualSymLinkTarget, linkTarget);
+ QCOMPARE(fi.symLinkTarget(), linkTarget);
QCOMPARE(actualCanonicalFilePath, canonicalFilePath);
}
+
+ if (isJunction) {
+ if (creationResult.target.startsWith(uR"(\??\)"))
+ creationResult.target = creationResult.target.sliced(4);
+
+ // resolve volume to drive letter
+ static const QRegularExpression matchVolumeRe(uR"(^Volume\{([a-z]|[0-9]|-)+\}\\)"_s,
+ QRegularExpression::CaseInsensitiveOption);
+ auto matchVolume = matchVolumeRe.match(creationResult.target);
+ if (matchVolume.hasMatch()) {
+ Q_ASSERT(matchVolume.capturedStart() == 0);
+ DWORD len;
+ wchar_t buffer[MAX_PATH];
+ const QString volumeName = uR"(\\?\)"_s + matchVolume.captured();
+ if (GetVolumePathNamesForVolumeName(reinterpret_cast<LPCWSTR>(volumeName.utf16()),
+ buffer, MAX_PATH, &len) != 0) {
+ creationResult.target.replace(0, matchVolume.capturedLength(),
+ QString::fromWCharArray(buffer));
+ }
+ }
+ QCOMPARE(fi.junctionTarget(), QDir::fromNativeSeparators(creationResult.target));
+ QCOMPARE(actualCanonicalFilePath, QFileInfo(creationResult.link).canonicalFilePath());
+ }
}
void tst_QFileInfo::brokenShortcut()
@@ -1615,14 +1876,16 @@ void tst_QFileInfo::brokenShortcut()
file.close();
QFileInfo info(linkName);
- QVERIFY(info.isSymLink());
+ QVERIFY(!info.isSymbolicLink());
+ QVERIFY(info.isShortcut());
QVERIFY(!info.exists());
QFile::remove(linkName);
QDir current; // QTBUG-21863
QVERIFY(current.mkdir(linkName));
QFileInfo dirInfo(linkName);
- QVERIFY(!dirInfo.isSymLink());
+ QVERIFY(!dirInfo.isSymbolicLink());
+ QVERIFY(!dirInfo.isShortcut());
QVERIFY(dirInfo.isDir());
current.rmdir(linkName);
}
@@ -1631,42 +1894,48 @@ void tst_QFileInfo::brokenShortcut()
void tst_QFileInfo::isWritable()
{
QFile tempfile("tempfile.txt");
- tempfile.open(QIODevice::WriteOnly);
+ QVERIFY(tempfile.open(QIODevice::WriteOnly));
tempfile.write("This file is generated by the QFileInfo autotest.");
tempfile.close();
QVERIFY(QFileInfo("tempfile.txt").isWritable());
tempfile.remove();
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QFileInfo fi("c:\\pagefile.sys");
QVERIFY2(fi.exists(), msgDoesNotExist(fi.absoluteFilePath()).constData());
QVERIFY(!fi.isWritable());
#endif
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINRT)
- QScopedValueRollback<int> ntfsMode(qt_ntfs_permission_lookup);
- qt_ntfs_permission_lookup = 1;
+#if defined (Q_OS_WIN)
+ QNtfsPermissionCheckGuard permissionGuard;
QFileInfo fi2(QFile::decodeName(qgetenv("SystemRoot") + "/system.ini"));
QVERIFY(fi2.exists());
QCOMPARE(fi2.isWritable(), IsUserAdmin());
#endif
#if defined (Q_OS_QNX) // On QNX /etc is usually on a read-only filesystem
- QVERIFY(!QFileInfo("/etc/passwd").isWritable());
+ QCOMPARE(QFileInfo("/etc/passwd").isWritable(), (geteuid() == 0));
#elif defined (Q_OS_UNIX) && !defined(Q_OS_VXWORKS) // VxWorks does not have users/groups
- if (::getuid() == 0)
- QVERIFY(QFileInfo("/etc/passwd").isWritable());
- else
- QVERIFY(!QFileInfo("/etc/passwd").isWritable());
+ for (const char *attempt : { "/etc/passwd", "/etc/machine-id", "/proc/version" }) {
+ if (access(attempt, F_OK) == -1)
+ continue;
+ QCOMPARE(QFileInfo(attempt).isWritable(), ::access(attempt, W_OK) == 0);
+ }
#endif
}
void tst_QFileInfo::isExecutable()
{
QString appPath = QCoreApplication::applicationDirPath();
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- appPath += "/libtst_qfileinfo.so";
+#ifdef Q_OS_ANDROID
+ QDir dir(appPath);
+ QVERIFY(dir.exists());
+ dir.setNameFilters({ "libtst_qfileinfo*.so" });
+ QStringList entries = dir.entryList();
+ QCOMPARE(entries.size(), 1);
+
+ appPath += "/" + entries[0];
#else
appPath += "/tst_qfileinfo";
# if defined(Q_OS_WIN)
@@ -1674,6 +1943,7 @@ void tst_QFileInfo::isExecutable()
# endif
#endif
QFileInfo fi(appPath);
+ QVERIFY(fi.exists());
QCOMPARE(fi.isExecutable(), true);
QCOMPARE(QFileInfo(m_proFile).isExecutable(), false);
@@ -1744,7 +2014,7 @@ private:
void tst_QFileInfo::testDecomposedUnicodeNames()
{
-#ifndef Q_OS_MAC
+#ifndef Q_OS_DARWIN
QSKIP("This is a OS X only test (unless you know more about filesystems, then maybe you should try it ;)");
#else
QFETCH(QString, filePath);
@@ -1824,7 +2094,7 @@ void tst_QFileInfo::detachingOperations()
QVERIFY(!info1.caching());
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
bool IsUserAdmin()
{
BOOL b;
@@ -1846,13 +2116,12 @@ bool IsUserAdmin()
return b != FALSE;
}
-#endif // Q_OS_WIN && !Q_OS_WINRT
+#endif // Q_OS_WIN
-#ifndef Q_OS_WINRT
void tst_QFileInfo::owner()
{
QString userName;
-#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_INTEGRITY)
{
passwd *user = getpwuid(geteuid());
QVERIFY(user);
@@ -1865,7 +2134,7 @@ void tst_QFileInfo::owner()
DWORD bufSize = 1024;
if (GetUserNameW(usernameBuf, &bufSize)) {
userName = QString::fromWCharArray(usernameBuf);
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && IsUserAdmin()) {
+ if (IsUserAdmin()) {
// Special case : If the user is a member of Administrators group, all files
// created by the current user are owned by the Administrators group.
LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
@@ -1889,7 +2158,7 @@ void tst_QFileInfo::owner()
NetApiBufferFree(pBuf);
}
}
- qt_ntfs_permission_lookup = 1;
+ QNtfsPermissionCheckGuard permissionGuard;
#endif
if (userName.isEmpty())
QSKIP("Can't retrieve the user name");
@@ -1906,16 +2175,12 @@ void tst_QFileInfo::owner()
QCOMPARE(fi.owner(), userName);
QFile::remove(fileName);
-#if defined(Q_OS_WIN)
- qt_ntfs_permission_lookup = 0;
-#endif
}
-#endif // !Q_OS_WINRT
void tst_QFileInfo::group()
{
QString expected;
-#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_INTEGRITY)
struct group *gr;
gid_t gid = getegid();
@@ -1979,12 +2244,13 @@ static void stateCheck(const QFileInfo &info, const QString &dirname, const QStr
QVERIFY(!info.isHidden());
QVERIFY(!info.isFile());
QVERIFY(!info.isDir());
- QVERIFY(!info.isSymLink());
+ QVERIFY(!info.isSymbolicLink());
+ QVERIFY(!info.isShortcut());
QVERIFY(!info.isBundle());
QVERIFY(!info.isRoot());
QCOMPARE(info.isNativePath(), !filename.isEmpty());
- QCOMPARE(info.readLink(), QString());
+ QCOMPARE(info.symLinkTarget(), QString());
QCOMPARE(info.ownerId(), uint(-2));
QCOMPARE(info.groupId(), uint(-2));
QCOMPARE(info.owner(), QString());
@@ -1992,11 +2258,10 @@ static void stateCheck(const QFileInfo &info, const QString &dirname, const QStr
QCOMPARE(info.permissions(), QFile::Permissions());
- QVERIFY(!info.created().isValid());
- QVERIFY(!info.birthTime().isValid());
- QVERIFY(!info.metadataChangeTime().isValid());
- QVERIFY(!info.lastRead().isValid());
- QVERIFY(!info.lastModified().isValid());
+ QVERIFY(!info.birthTime(QTimeZone::UTC).isValid());
+ QVERIFY(!info.metadataChangeTime(QTimeZone::UTC).isValid());
+ QVERIFY(!info.lastRead(QTimeZone::UTC).isValid());
+ QVERIFY(!info.lastModified(QTimeZone::UTC).isValid());
};
void tst_QFileInfo::invalidState_data()
@@ -2034,5 +2299,129 @@ void tst_QFileInfo::nonExistingFile()
stateCheck(info, dirname, filename);
}
+void tst_QFileInfo::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+
+ namespace fs = std::filesystem;
+
+ // Verify constructing with fs::path leads to valid objects
+ {
+ // We compare using absoluteFilePath since QFileInfo::operator== ends up using
+ // canonicalFilePath which evaluates to empty-string for non-existent paths causing
+ // these tests to always succeed.
+ QDir base{ "../" }; // Used for the QFileInfo(QDir, <path>) ctor
+ auto doCompare = [&base](const char *filepath) {
+ QCOMPARE(QFileInfo(fs::path(filepath)).absoluteFilePath(),
+ QFileInfo(QString::fromLocal8Bit(filepath)).absoluteFilePath());
+ QCOMPARE(QFileInfo(base, fs::path(filepath)).absoluteFilePath(),
+ QFileInfo(base, QString::fromLocal8Bit(filepath)).absoluteFilePath());
+ };
+#define COMPARE_CONSTRUCTION(filepath) \
+ doCompare(filepath); if (QTest::currentTestFailed()) return
+
+ COMPARE_CONSTRUCTION("./file");
+
+#ifdef Q_OS_WIN32
+ COMPARE_CONSTRUCTION("C:\\path\\to\\file.txt");
+ COMPARE_CONSTRUCTION("x:\\path/to\\file.txt");
+ COMPARE_CONSTRUCTION("D:/path/TO/file.txt");
+ COMPARE_CONSTRUCTION("//sharename/folder/file.txt");
+#endif
+ COMPARE_CONSTRUCTION("/path/TO/file.txt");
+ COMPARE_CONSTRUCTION("./path/TO/file.txt");
+ COMPARE_CONSTRUCTION("../file.txt");
+#if !(defined(__GLIBCXX__) && defined(Q_OS_WIN32))
+ // libstdc++ bug on Windows - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111244
+ COMPARE_CONSTRUCTION("./filæ.txt");
+#endif
+
+ // Test unicode strings
+ QCOMPARE(QFileInfo(fs::path(u"./filæ.txt")).absoluteFilePath(),
+ QFileInfo(u"./filæ.txt"_s).absoluteFilePath());
+ QCOMPARE(QFileInfo(base, fs::path(u"./filæ.txt")).absoluteFilePath(),
+ QFileInfo(base, u"./filæ.txt"_s).absoluteFilePath());
+#ifdef __cpp_char8_t
+ QCOMPARE(QFileInfo(fs::path(u8"./filæ.txt")).absoluteFilePath(),
+ QFileInfo(u8"./filæ.txt").absoluteFilePath());
+ QCOMPARE(QFileInfo(base, fs::path(u8"./filæ.txt")).absoluteFilePath(),
+ QFileInfo(base, u8"./filæ.txt").absoluteFilePath());
+#endif
+
+#undef COMPARE_CONSTRUCTION
+ {
+ // One proper comparison with operator== for each ctor
+ QFile file(QStringLiteral("./filesystem_test_file.txt"));
+ if (!file.open(QFile::NewOnly))
+ QVERIFY(file.exists());
+ file.close();
+
+ QFileInfo pinfo{ fs::path{ "./filesystem_test_file.txt" } };
+ QFileInfo info{ QStringLiteral("./filesystem_test_file.txt") };
+ QCOMPARE(pinfo, info);
+ }
+
+ {
+ // And once more for QFileInfo(QDir, <path>)
+ const QString &subdir = QStringLiteral("./filesystem_test_dir/");
+ base = QDir(QStringLiteral("."));
+ if (!base.exists(subdir))
+ QVERIFY(base.mkdir(subdir));
+ base.cd(subdir);
+ QFile file{ base.filePath(QStringLiteral("./filesystem_test_file.txt")) };
+ if (!file.open(QFile::NewOnly))
+ QVERIFY(file.exists());
+ file.close();
+ QFileInfo pinfo{ base, fs::path{ "filesystem_test_file.txt" } };
+ QFileInfo info{ base, QStringLiteral("filesystem_test_file.txt") };
+ QCOMPARE(pinfo, info);
+ }
+ }
+
+ // Verify that functions returning path all point to the same place
+ {
+#define COMPARE_PATHS(actual, expected) \
+ QCOMPARE(QString::fromStdU16String(actual.u16string()), expected)
+
+ QFile file(QStringLiteral("./orig"));
+ if (!file.open(QFile::NewOnly))
+ QVERIFY(file.exists());
+ file.close();
+
+ QFileInfo info{ QStringLiteral("./orig") };
+ COMPARE_PATHS(info.filesystemPath(), info.path());
+ COMPARE_PATHS(info.filesystemAbsolutePath(), info.absolutePath());
+ COMPARE_PATHS(info.filesystemCanonicalPath(), info.canonicalPath());
+ COMPARE_PATHS(info.filesystemFilePath(), info.filePath());
+ COMPARE_PATHS(info.filesystemAbsoluteFilePath(), info.absoluteFilePath());
+ COMPARE_PATHS(info.filesystemCanonicalFilePath(), info.canonicalFilePath());
+
+ QVERIFY(file.link(QStringLiteral("./filesystem_test_symlink.lnk")));
+ info = QFileInfo{ "./filesystem_test_symlink.lnk" };
+
+ COMPARE_PATHS(info.filesystemSymLinkTarget(), info.symLinkTarget());
+#undef COMPARE_PATHS
+ }
+
+#else
+ QSKIP("Not supported");
+#endif
+}
+
+void tst_QFileInfo::readSymLink()
+{
+ QString symLinkName("./a.link");
+ const auto tidier = qScopeGuard([symLinkName]() { QFile::remove(symLinkName); });
+
+#ifdef Q_OS_WIN
+ QVERIFY2(CreateSymbolicLink(L"a.link", L"..\\..\\a", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
+ != 0,
+ "Failed to create symlink for test");
+#else
+ QVERIFY2(QFile::link("../../a", symLinkName), "Failed to create symlink for test");
+#endif
+ QFileInfo info(symLinkName);
+ QCOMPARE(info.readSymLink(), QString("../../a"));
+}
QTEST_MAIN(tst_QFileInfo)
#include "tst_qfileinfo.moc"
diff --git a/tests/auto/corelib/io/qfileselector/CMakeLists.txt b/tests/auto/corelib/io/qfileselector/CMakeLists.txt
new file mode 100644
index 0000000000..c27c4f4f96
--- /dev/null
+++ b/tests/auto/corelib/io/qfileselector/CMakeLists.txt
@@ -0,0 +1,77 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfileselectors Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfileselectors LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Resources:
+set(qfileselector_resource_files
+ "extras/+custom1/test"
+ "extras/+custom1/test3"
+ "extras/+custom2/test"
+ "extras/+custom3/+custom2/test"
+ "extras/+custom3/+custom4/test"
+ "extras/+custom3/+custom5/test"
+ "extras/+custom3/test"
+ "extras/+custom5/+custom3/test"
+ "extras/test"
+ "extras/test2"
+ "platforms/+android/test"
+ "platforms/+android/test2"
+ "platforms/+darwin/test"
+ "platforms/+haiku/test"
+ "platforms/+haiku/test2"
+ "platforms/+ios/test"
+ "platforms/+ios/test2"
+ "platforms/+linux/test"
+ "platforms/+linux/test2"
+ "platforms/+wasm/test"
+ "platforms/+wasm/test2"
+ "platforms/+macos/test"
+ "platforms/+macos/test2"
+ "platforms/+qnx/test"
+ "platforms/+qnx/test2"
+ "platforms/+unix/+emscripten/+wasm/test"
+ "platforms/+unix/+emscripten/test"
+ "platforms/+unix/+android/test"
+ "platforms/+unix/+darwin/+ios/test"
+ "platforms/+unix/+darwin/+macos/test"
+ "platforms/+unix/+darwin/test"
+ "platforms/+unix/+haiku/test"
+ "platforms/+unix/+linux/test"
+ "platforms/+unix/+qnx/test"
+ "platforms/+unix/test"
+ "platforms/+unix/test3"
+ "platforms/+wince/test"
+ "platforms/+wince/test2"
+ "platforms/+windows/+wince/test"
+ "platforms/+windows/+winnt/test"
+ "platforms/+windows/+winrt/test"
+ "platforms/+windows/test"
+ "platforms/+windows/test3"
+ "platforms/+winnt/test2"
+ "platforms/+winrt/test"
+ "platforms/+winrt/test2"
+ "platforms/test"
+ "platforms/test2"
+ "platforms/test3"
+ "platforms/test4"
+ "platforms/test5"
+)
+
+qt_internal_add_test(tst_qfileselectors
+ SOURCES
+ tst_qfileselector.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ TESTDATA ${qfileselector_resource_files}
+ BUILTIN_TESTDATA
+)
+
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+ios/test
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+macos/test
+++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+ios/test
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+macos/test
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/+macos/test
+++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+macos/test
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/+wasm/test
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/+osx/test
+++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/+wasm/test
diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/test
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/io/qfileselector/platforms/+unix/+darwin/+mac/test
+++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/test
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/38.bjson b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/38.bjson
+++ b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/050.xml b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test2
index e69de29bb2..e69de29bb2 100644
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/050.xml
+++ b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test2
diff --git a/tests/auto/corelib/io/qfileselector/qfileselector.pro b/tests/auto/corelib/io/qfileselector/qfileselector.pro
deleted file mode 100644
index edcc91e8ed..0000000000
--- a/tests/auto/corelib/io/qfileselector/qfileselector.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfileselectors
-QT = core-private testlib
-SOURCES = tst_qfileselector.cpp
-RESOURCES = qfileselector.qrc
diff --git a/tests/auto/corelib/io/qfileselector/qfileselector.qrc b/tests/auto/corelib/io/qfileselector/qfileselector.qrc
deleted file mode 100644
index 54b2e0a0e2..0000000000
--- a/tests/auto/corelib/io/qfileselector/qfileselector.qrc
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/">
- <file>extras/test</file>
- <file>extras/test2</file>
- <file>extras/+custom1/test</file>
- <file>extras/+custom1/test3</file>
- <file>extras/+custom2/test</file>
- <file>extras/+custom3/test</file>
- <file>extras/+custom3/+custom2/test</file>
- <file>extras/+custom3/+custom4/test</file>
- <file>extras/+custom3/+custom5/test</file>
- <file>extras/+custom5/+custom3/test</file>
-
- <!-- platforms/test: deepest possible selection -->
- <file>platforms/test</file>
- <file>platforms/+unix/+android/test</file>
- <file>platforms/+unix/+darwin/+mac/+ios/test</file>
- <file>platforms/+unix/+darwin/+mac/+osx/+macos/test</file>
- <file>platforms/+unix/+darwin/+mac/+osx/test</file>
- <file>platforms/+unix/+darwin/+mac/test</file>
- <file>platforms/+unix/+darwin/test</file>
- <file>platforms/+unix/+haiku/test</file>
- <file>platforms/+unix/+linux/test</file>
- <file>platforms/+unix/+qnx/test</file>
- <file>platforms/+unix/test</file>
- <file>platforms/+windows/+wince/test</file>
- <file>platforms/+windows/+winnt/test</file>
- <file>platforms/+windows/+winrt/test</file>
- <file>platforms/+windows/test</file>
- <file>platforms/+android/test</file>
- <file>platforms/+ios/test</file>
- <file>platforms/+macos/test</file>
- <file>platforms/+osx/test</file>
- <file>platforms/+darwin/test</file>
- <file>platforms/+mac/test</file>
- <file>platforms/+haiku/test</file>
- <file>platforms/+linux/test</file>
- <file>platforms/+qnx/test</file>
- <file>platforms/+wince/test</file>
- <file>platforms/+winrt/test</file>
-
- <!-- platforms/test2: shallow selection for the deepest selector -->
- <file>platforms/test2</file>
- <file>platforms/+android/test2</file>
- <file>platforms/+ios/test2</file>
- <file>platforms/+macos/test2</file>
- <file>platforms/+haiku/test2</file>
- <file>platforms/+linux/test2</file>
- <file>platforms/+qnx/test2</file>
- <file>platforms/+wince/test2</file>
- <file>platforms/+winnt/test2</file>
- <file>platforms/+winrt/test2</file>
-
- <!-- platforms/test3: selection for the family only -->
- <file>platforms/test3</file>
- <file>platforms/+windows/test3</file>
- <file>platforms/+unix/test3</file>
-
- <!-- platforms/test4 and 5: special cases for macOS -->
- <file>platforms/test4</file>
- <file>platforms/+osx/test4</file>
- <file>platforms/test5</file>
- <file>platforms/+mac/test5</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp
index 11b1fdaeeb..626166c8b8 100644
--- a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp
+++ b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qplatformdefs.h>
#include <QCoreApplication>
@@ -85,7 +60,7 @@ void tst_QFileSelector::basicTest_data()
QString expectedPlatform1File(":/platforms");
QString expectedPlatform2File(""); //Only the last selector
QString expectedPlatform3File; // Only the first selector (the family)
-#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && \
+#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WASM) && \
!defined(Q_OS_DARWIN) && !defined(Q_OS_LINUX) && !defined(Q_OS_HAIKU) && !defined(Q_OS_QNX)
/* We are only aware of specific unixes, and do not have test files for any of the others.
However those unixes can get a selector added from the result of a uname call, so this will
@@ -96,10 +71,11 @@ void tst_QFileSelector::basicTest_data()
expectedPlatform2File = QString(":/platforms/test2");
#else
QString distributionName;
-# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD) || defined(Q_OS_WINRT)
+# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
distributionName = QSysInfo::productType();
# endif
- foreach (const QString &selector, QFileSelectorPrivate::platformSelectors()) {
+ const auto platformSelectors = QFileSelectorPrivate::platformSelectors();
+ for (const QString &selector : platformSelectors) {
// skip the Linux distribution name (if any) since we don't have files for them
if (selector == distributionName)
continue;
@@ -126,14 +102,6 @@ void tst_QFileSelector::basicTest_data()
QTest::newRow("platform3") << QString(":/platforms/test3") << QStringList()
<< expectedPlatform3File;
-#ifdef Q_OS_MACOS
- // special case for compatibility code
- QTest::newRow("osx-compat") << QString(":/platforms/test4") << QStringList()
- << ":/platforms/+osx/test4";
- QTest::newRow("mac-compat") << QString(":/platforms/test5") << QStringList()
- << ":/platforms/+mac/test5";
-#endif
-
QString resourceTestPath(":/extras/test");
QString custom1("custom1");
QTest::newRow("custom1-noselector") << resourceTestPath << QStringList()
@@ -223,6 +191,9 @@ void tst_QFileSelector::urlConvenience_data()
strUrlWithFragment = QString("file:") + testWithQueryAndFragment;
QTest::newRow("file with query and fragment too") << QUrl(strUrlWithFragment) << (QStringList()) << QUrl(strUrlWithFragment);
+ // preserve path to root
+ QTest::newRow("path to root") << QUrl("file:///") << (QStringList()) << QUrl("file:///");
+
// http://qt-project.org/images/qtdn/sprites-combined-latest.png is chosen as a representative real world URL
// But note that this test is checking that http urls are NOT selected so it shouldn't be checked
QUrl testHttpUrl("http://qt-project.org/images/sprites-combined-latest.png");
diff --git a/tests/auto/corelib/io/qfilesystementry/CMakeLists.txt b/tests/auto/corelib/io/qfilesystementry/CMakeLists.txt
new file mode 100644
index 0000000000..85686a12b1
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystementry/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfilesystementry Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfilesystementry LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfilesystementry
+ SOURCES
+ tst_qfilesystementry.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro b/tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro
deleted file mode 100644
index 474836fba2..0000000000
--- a/tests/auto/corelib/io/qfilesystementry/qfilesystementry.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfilesystementry
-QT = core-private testlib
-SOURCES = tst_qfilesystementry.cpp \
- $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp
-HEADERS = $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry_p.h
diff --git a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
index aed4895a47..b35d89cbf3 100644
--- a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
+++ b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
@@ -1,35 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QtCore/private/qfilesystementry_p.h>
+using namespace Qt::StringLiterals;
+
class tst_QFileSystemEntry : public QObject
{
Q_OBJECT
@@ -104,6 +81,17 @@ void tst_QFileSystemEntry::getSetCheck_data()
<< QString("A:dir\\without\\leading\\backslash.bat")
<< absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat")
<< "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false << false;
+
+ QTest::newRow("longpath")
+ << uR"(\\?\D:\)"_s
+ << absPrefix + QLatin1String(R"(D:\)")
+ << "D:/" << "" << "" << "" << "" << "" << true << false;
+
+ QTest::newRow("uncprefix")
+ << uR"(\\?\UNC\localhost\C$\tmp.txt)"_s
+ << absPrefix + QLatin1String(R"(UNC\localhost\C$\tmp.txt)")
+ << "//localhost/C$/tmp.txt" << "tmp.txt" << "tmp" << "tmp" << "txt" << "txt" << true
+ << false;
}
void tst_QFileSystemEntry::getSetCheck()
@@ -137,7 +125,7 @@ void tst_QFileSystemEntry::getSetCheck()
QCOMPARE(entry2.isRelative(), relative);
QCOMPARE(entry2.filePath(), filepath);
// Since this entry was created using the native path,
- // the object shouldnot change nativeFilePath.
+ // the object shouldn't change nativeFilePath.
QCOMPARE(entry2.nativeFilePath(), nativeFilePath);
QCOMPARE(entry2.fileName(), filename);
QCOMPARE(entry2.baseName(), baseName);
diff --git a/tests/auto/corelib/io/qfilesystemmetadata/CMakeLists.txt b/tests/auto/corelib/io/qfilesystemmetadata/CMakeLists.txt
new file mode 100644
index 0000000000..cf9f647eda
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystemmetadata/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfilesystemmetadata Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfilesystemmetadata LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfilesystemmetadata
+ SOURCES
+ tst_qfilesystemmetadata.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/io/qfilesystemmetadata/qfilesystemmetadata.pro b/tests/auto/corelib/io/qfilesystemmetadata/qfilesystemmetadata.pro
deleted file mode 100644
index a7d50ece43..0000000000
--- a/tests/auto/corelib/io/qfilesystemmetadata/qfilesystemmetadata.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase parallel_test
-TARGET = tst_qfilesystemmetadata
-QT = core-private testlib
-SOURCES = tst_qfilesystemmetadata.cpp
diff --git a/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp b/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp
index ea4da39cd5..9ec49999ca 100644
--- a/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp
+++ b/tests/auto/corelib/io/qfilesystemmetadata/tst_qfilesystemmetadata.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QtCore/QDateTime>
#include <QtCore/private/qfilesystemmetadata_p.h>
class tst_QFileSystemMetaData : public QObject
@@ -67,14 +43,14 @@ void tst_QFileSystemMetaData::timeSinceEpoch()
data.ftCreationTime = epochToFileTime(afterEpochUtc);
meta.fillFromFindData(data);
QCOMPARE(meta.birthTime().toUTC(),
- QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), Qt::UTC));
+ QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), QTimeZone::UTC));
#else
QT_STATBUF data;
memset(&data, 0, sizeof(data));
data.st_ctime = afterEpochUtc;
meta.fillFromStatBuf(data);
QCOMPARE(meta.metadataChangeTime().toUTC(),
- QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), Qt::UTC));
+ QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), QTimeZone::UTC));
#endif
}
#else // i.e. no Q_AUTOTEST_EXPORT
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST
index 90b714758a..3b59c6477a 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST
+++ b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST
@@ -7,3 +7,9 @@ windows
[watchFileAndItsDirectory:native backend-specialchars]
osx
windows
+# QTBUG-102095
+[watchDirectory]
+macos arm ci
+# QTBUG-102096
+[signalsEmittedAfterFileMoved]
+macos arm ci
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/CMakeLists.txt b/tests/auto/corelib/io/qfilesystemwatcher/CMakeLists.txt
new file mode 100644
index 0000000000..0a48155895
--- /dev/null
+++ b/tests/auto/corelib/io/qfilesystemwatcher/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfilesystemwatcher Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfilesystemwatcher LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfilesystemwatcher
+ SOURCES
+ tst_qfilesystemwatcher.cpp
+)
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
deleted file mode 100644
index 46dd70289b..0000000000
--- a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfilesystemwatcher
-QT = core testlib
-SOURCES = tst_qfilesystemwatcher.cpp
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index 67ffa91e57..a5b0087f9c 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -1,31 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QCoreApplication>
@@ -33,7 +9,32 @@
#include <QFileSystemWatcher>
#include <QElapsedTimer>
#include <QTextStream>
+#include <QMap>
+#include <QString>
#include <QDir>
+#include <QSignalSpy>
+#include <QTimer>
+#include <QTemporaryFile>
+#if defined(Q_OS_WIN)
+#include <qt_windows.h>
+#endif
+
+#ifdef Q_OS_ANDROID
+#include <QStandardPaths>
+#endif
+
+using namespace std::chrono_literals;
+
+#if defined(Q_OS_QNX)
+// Longer polling times on QNX, otherwise the tests fail on the CI
+constexpr auto nativeEngineTimeout = 1s;
+constexpr auto pollingEngineTimeout = 1s;
+constexpr bool isQNX = true;
+#else
+constexpr auto nativeEngineTimeout = 0ms;
+constexpr auto pollingEngineTimeout = 20ms;
+constexpr bool isQNX = false;
+#endif
/* All tests need to run in temporary directories not used
* by the application to avoid non-deterministic failures on Windows
@@ -46,11 +47,13 @@ public:
tst_QFileSystemWatcher();
private slots:
+#ifdef QT_BUILD_INTERNAL
void basicTest_data();
void basicTest();
void watchDirectory_data();
void watchDirectory();
+#endif
void addPath();
void removePath();
@@ -58,8 +61,10 @@ private slots:
void removePaths();
void removePathsFilesInSameDirectory();
+#ifdef QT_BUILD_INTERNAL
void watchFileAndItsDirectory_data() { basicTest_data(); }
void watchFileAndItsDirectory();
+#endif
void nonExistingFile();
@@ -67,12 +72,17 @@ private slots:
void destroyAfterQCoreApplication();
+#ifdef QT_BUILD_INTERNAL
void QTBUG2331();
void QTBUG2331_data() { basicTest_data(); }
+#endif
void signalsEmittedAfterFileMoved();
void watchUnicodeCharacters();
+#if defined(Q_OS_WIN)
+ void watchDirectoryAttributeChanges();
+#endif
private:
QString m_tempDirPattern;
@@ -85,11 +95,12 @@ tst_QFileSystemWatcher::tst_QFileSystemWatcher()
m_tempDirPattern += QLatin1Char('/');
m_tempDirPattern += QStringLiteral("tst_qfilesystemwatcherXXXXXX");
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QDir::setCurrent(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
#endif
}
+#ifdef QT_BUILD_INTERNAL
void tst_QFileSystemWatcher::basicTest_data()
{
QTest::addColumn<QString>("backend");
@@ -104,7 +115,7 @@ void tst_QFileSystemWatcher::basicTest_data()
+ QChar(ushort(0x00DC)) // LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS
+ QStringLiteral(".txt");
-#if !defined(Q_OS_QNX) || !defined(QT_NO_INOTIFY)
+#if !defined(QT_NO_INOTIFY)
QTest::newRow("native backend-testfile") << "native" << testFile;
QTest::newRow("native backend-specialchars") << "native" << specialCharacterFile;
#endif
@@ -132,26 +143,27 @@ void tst_QFileSystemWatcher::basicTest()
watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
QVERIFY(watcher.addPath(testFile.fileName()));
+ const bool isPollerBackend = backend == u"poller";
+
QSignalSpy changedSpy(&watcher, &QFileSystemWatcher::fileChanged);
QVERIFY(changedSpy.isValid());
QEventLoop eventLoop;
QTimer timer;
+ timer.setInterval(isPollerBackend ? pollingEngineTimeout : nativeEngineTimeout);
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
// modify the file, should get a signal from the watcher
- // resolution of the modification time is system dependent, but it's at most 1 second when using
- // the polling engine. I've heard rumors that FAT32 has a 2 second resolution. So, we have to
- // wait a bit before we can modify the file (hrmph)...
- QTest::qWait(2000);
+ if (isPollerBackend || isQNX)
+ QTest::qWait(pollingEngineTimeout);
- testFile.open(QIODevice::WriteOnly | QIODevice::Append);
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Append));
testFile.write(QByteArray("world"));
testFile.close();
// waiting max 5 seconds for notification for file modification to trigger
- QTRY_COMPARE(changedSpy.count(), 1);
- QCOMPARE(changedSpy.at(0).count(), 1);
+ QTRY_COMPARE(changedSpy.size(), 1);
+ QCOMPARE(changedSpy.at(0).size(), 1);
QString fileName = changedSpy.at(0).at(0).toString();
QCOMPARE(fileName, testFile.fileName());
@@ -160,25 +172,25 @@ void tst_QFileSystemWatcher::basicTest()
// remove the watch and modify the file, should not get a signal from the watcher
QVERIFY(watcher.removePath(testFile.fileName()));
- testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
testFile.write(QByteArray("hello universe!"));
testFile.close();
- // waiting max 5 seconds for notification for file modification to trigger
- timer.start(5000);
+ // waiting for notification for file modification to trigger
+ timer.start();
eventLoop.exec();
- QCOMPARE(changedSpy.count(), 0);
+ QCOMPARE(changedSpy.size(), 0);
// readd the file watch with a relative path
const QString relativeTestFileName = QDir::current().relativeFilePath(testFile.fileName());
QVERIFY(!relativeTestFileName.isEmpty());
QVERIFY(watcher.addPath(relativeTestFileName));
- testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
testFile.write(QByteArray("hello multiverse!"));
testFile.close();
- QTRY_VERIFY(changedSpy.count() > 0);
+ QTRY_VERIFY(changedSpy.size() > 0);
QVERIFY(watcher.removePath(relativeTestFileName));
@@ -194,8 +206,8 @@ void tst_QFileSystemWatcher::basicTest()
#if !defined(Q_OS_QNX)
// waiting max 5 seconds for notification for file permission modification to trigger
- QTRY_COMPARE(changedSpy.count(), 1);
- QCOMPARE(changedSpy.at(0).count(), 1);
+ QTRY_COMPARE(changedSpy.size(), 1);
+ QCOMPARE(changedSpy.at(0).size(), 1);
fileName = changedSpy.at(0).at(0).toString();
QCOMPARE(fileName, testFile.fileName());
@@ -208,11 +220,11 @@ void tst_QFileSystemWatcher::basicTest()
QVERIFY(watcher.removePath(testFile.fileName()));
testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOther);
- // waiting max 5 seconds for notification for file modification to trigger
- timer.start(5000);
+ // waiting for notification for file modification to trigger
+ timer.start();
eventLoop.exec();
- QCOMPARE(changedSpy.count(), 0);
+ QCOMPARE(changedSpy.size(), 0);
// readd the file watch
QVERIFY(watcher.addPath(testFile.fileName()));
@@ -223,8 +235,8 @@ void tst_QFileSystemWatcher::basicTest()
// waiting max 5 seconds for notification for file removal to trigger
// > 0 && < 3 because some platforms may emit two changes
// XXX: which platforms? (QTBUG-23370)
- QTRY_VERIFY(changedSpy.count() > 0 && changedSpy.count() < 3);
- QCOMPARE(changedSpy.at(0).count(), 1);
+ QTRY_VERIFY(changedSpy.size() > 0 && changedSpy.size() < 3);
+ QCOMPARE(changedSpy.at(0).size(), 1);
fileName = changedSpy.at(0).at(0).toString();
QCOMPARE(fileName, testFile.fileName());
@@ -236,11 +248,11 @@ void tst_QFileSystemWatcher::basicTest()
testFile.write(QByteArray("hello"));
testFile.close();
- // waiting max 5 seconds for notification for file recreation to trigger
- timer.start(5000);
+ // waiting for notification for file recreation to trigger
+ timer.start();
eventLoop.exec();
- QCOMPARE(changedSpy.count(), 0);
+ QCOMPARE(changedSpy.size(), 0);
QVERIFY(testFile.remove());
}
@@ -251,7 +263,9 @@ void tst_QFileSystemWatcher::watchDirectory_data()
QTest::addColumn<QStringList>("testDirNames");
const QStringList testDirNames = {QStringLiteral("testdir"), QStringLiteral("testdir2")};
+#if !defined(QT_NO_INOTIFY)
QTest::newRow("native backend") << "native" << testDirNames;
+#endif
QTest::newRow("poller backend") << "poller" << testDirNames;
}
@@ -282,16 +296,18 @@ void tst_QFileSystemWatcher::watchDirectory()
watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
QVERIFY(watcher.addPaths(testDirs).isEmpty());
+ const bool isPollerBackend = backend == u"poller";
+
QSignalSpy changedSpy(&watcher, &QFileSystemWatcher::directoryChanged);
QVERIFY(changedSpy.isValid());
QEventLoop eventLoop;
QTimer timer;
+ timer.setInterval(isPollerBackend ? pollingEngineTimeout : nativeEngineTimeout);
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
- // resolution of the modification time is system dependent, but it's at most 1 second when using
- // the polling engine. From what I know, FAT32 has a 2 second resolution. So we have to
- // wait before modifying the directory...
- QTest::qWait(2000);
+ if (isPollerBackend || isQNX)
+ QTest::qWait(pollingEngineTimeout);
+
// remove the watch, should not get notification of a new file
QVERIFY(watcher.removePaths(testDirs).isEmpty());
for (const auto &testFileName : testFiles) {
@@ -300,11 +316,11 @@ void tst_QFileSystemWatcher::watchDirectory()
testFile.close();
}
- // waiting max 5 seconds for notification for file recreationg to trigger
- timer.start(5000);
+ // waiting for notification for file recreation to trigger
+ timer.start();
eventLoop.exec();
- QCOMPARE(changedSpy.count(), 0);
+ QCOMPARE(changedSpy.size(), 0);
QVERIFY(watcher.addPaths(testDirs).isEmpty());
@@ -312,7 +328,7 @@ void tst_QFileSystemWatcher::watchDirectory()
for (const auto &testFileName : testFiles)
QVERIFY(QFile::remove(testFileName));
- timer.start(5000);
+ timer.start();
eventLoop.exec();
// remove the directory, should get a signal from the watcher
@@ -324,10 +340,10 @@ void tst_QFileSystemWatcher::watchDirectory()
signalCounter[testDirName] = 0;
// waiting max 5 seconds for notification for directory removal to trigger
- QTRY_COMPARE(changedSpy.count(), testDirs.size() * 2);
- for (int i = 0; i < changedSpy.count(); i++) {
+ QTRY_COMPARE(changedSpy.size(), testDirs.size() * 2);
+ for (int i = 0; i < changedSpy.size(); i++) {
const auto &signal = changedSpy.at(i);
- QCOMPARE(signal.count(), 1);
+ QCOMPARE(signal.size(), 1);
auto it = signalCounter.find(signal.at(0).toString());
QVERIFY(it != signalCounter.end());
@@ -339,7 +355,7 @@ void tst_QFileSystemWatcher::watchDirectory()
QCOMPARE(count, 2);
// flush pending signals (like the one from the rmdir above)
- timer.start(5000);
+ timer.start();
eventLoop.exec();
changedSpy.clear();
@@ -351,27 +367,28 @@ void tst_QFileSystemWatcher::watchDirectory()
}
}
- // waiting max 5 seconds for notification for dir recreation to trigger
- timer.start(5000);
+ // waiting for notification for dir recreation to trigger
+ timer.start();
eventLoop.exec();
- QCOMPARE(changedSpy.count(), 0);
+ QCOMPARE(changedSpy.size(), 0);
for (const auto &testDirName : testDirs)
QVERIFY(temporaryDir.rmdir(testDirName));
}
+#endif // QT_BUILD_INTERNAL
void tst_QFileSystemWatcher::addPath()
{
QFileSystemWatcher watcher;
QString home = QDir::homePath();
QVERIFY(watcher.addPath(home));
- QCOMPARE(watcher.directories().count(), 1);
+ QCOMPARE(watcher.directories().size(), 1);
QCOMPARE(watcher.directories().first(), home);
// second watch on an already-watched path should fail
QVERIFY(!watcher.addPath(home));
- QCOMPARE(watcher.directories().count(), 1);
+ QCOMPARE(watcher.directories().size(), 1);
// With empty string
QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::addPath: path is empty");
@@ -384,9 +401,9 @@ void tst_QFileSystemWatcher::removePath()
QString home = QDir::homePath();
QVERIFY(watcher.addPath(home));
QVERIFY(watcher.removePath(home));
- QCOMPARE(watcher.directories().count(), 0);
+ QCOMPARE(watcher.directories().size(), 0);
QVERIFY(!watcher.removePath(home));
- QCOMPARE(watcher.directories().count(), 0);
+ QCOMPARE(watcher.directories().size(), 0);
// With empty string
QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::removePath: path is empty");
@@ -397,9 +414,15 @@ void tst_QFileSystemWatcher::addPaths()
{
QFileSystemWatcher watcher;
QStringList paths;
- paths << QDir::homePath() << QDir::currentPath();
+ paths << QDir::homePath() << QDir::tempPath();
+#ifndef Q_OS_QNX
+ // Adding this makes QNX fail and we haven't investigated why
+ for (const QFileInfo &fi : QDir::drives())
+ paths << fi.absoluteFilePath(); // on Unix, this will be just "/"
+#endif
+
QCOMPARE(watcher.addPaths(paths), QStringList());
- QCOMPARE(watcher.directories().count(), 2);
+ QCOMPARE(watcher.directories().size(), paths.size());
// With empty list
paths.clear();
@@ -465,11 +488,17 @@ void tst_QFileSystemWatcher::removePaths()
{
QFileSystemWatcher watcher;
QStringList paths;
- paths << QDir::homePath() << QDir::currentPath();
+ paths << QDir::homePath() << QDir::tempPath();
+#ifndef Q_OS_QNX
+ // Adding this makes QNX fail and we haven't investigated why
+ for (const QFileInfo &fi : QDir::drives())
+ paths << fi.absoluteFilePath(); // on Unix, this will be just "/"
+#endif
+
QCOMPARE(watcher.addPaths(paths), QStringList());
- QCOMPARE(watcher.directories().count(), 2);
+ QCOMPARE(watcher.directories().size(), paths.size());
QCOMPARE(watcher.removePaths(paths), QStringList());
- QCOMPARE(watcher.directories().count(), 0);
+ QCOMPARE(watcher.directories().size(), 0);
//With empty list
paths.clear();
@@ -502,6 +531,7 @@ void tst_QFileSystemWatcher::removePathsFilesInSameDirectory()
QCOMPARE(watcher.files().size(), 0);
}
+#ifdef QT_BUILD_INTERNAL
static QByteArray msgFileOperationFailed(const char *what, const QFile &f)
{
return what + QByteArrayLiteral(" failed on \"")
@@ -536,28 +566,29 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
QVERIFY(watcher.addPath(testDir.absolutePath()));
QVERIFY(watcher.addPath(testFileName));
+ const bool isPollerBackend = backend == u"poller";
+
QSignalSpy fileChangedSpy(&watcher, &QFileSystemWatcher::fileChanged);
FileSystemWatcherSpy dirChangedSpy(&watcher, FileSystemWatcherSpy::SpyOnDirectoryChanged);
QVERIFY(fileChangedSpy.isValid());
QEventLoop eventLoop;
QTimer timer;
+ timer.setInterval(isPollerBackend ? pollingEngineTimeout : nativeEngineTimeout);
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
- // resolution of the modification time is system dependent, but it's at most 1 second when using
- // the polling engine. From what I know, FAT32 has a 2 second resolution. So we have to
- // wait before modifying the directory...
- QTest::qWait(2000);
+ if (isPollerBackend || isQNX)
+ QTest::qWait(pollingEngineTimeout);
QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", testFile));
QVERIFY2(testFile.write(QByteArrayLiteral("hello again")), msgFileOperationFailed("write", testFile));
testFile.close();
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
// wait again for the file's atime to be updated
QTest::qWait(2000);
#endif
- QTRY_VERIFY(fileChangedSpy.count() > 0);
+ QTRY_VERIFY(fileChangedSpy.size() > 0);
QVERIFY2(dirChangedSpy.count() == 0, dirChangedSpy.receivedFilesMessage());
fileChangedSpy.clear();
@@ -566,9 +597,9 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
QVERIFY2(secondFile.write(QByteArrayLiteral("Foo")) > 0, msgFileOperationFailed("write", secondFile));
secondFile.close();
- timer.start(3000);
+ timer.start();
eventLoop.exec();
- int fileChangedSpyCount = fileChangedSpy.count();
+ int fileChangedSpyCount = fileChangedSpy.size();
#ifdef Q_OS_WIN
if (fileChangedSpyCount != 0)
QEXPECT_FAIL("", "See QTBUG-30943", Continue);
@@ -580,7 +611,7 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
QVERIFY(QFile::remove(testFileName));
- QTRY_VERIFY(fileChangedSpy.count() > 0);
+ QTRY_VERIFY(fileChangedSpy.size() > 0);
QTRY_COMPARE(dirChangedSpy.count(), 1);
fileChangedSpy.clear();
@@ -590,9 +621,9 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
QVERIFY(!watcher.removePath(testFileName));
QVERIFY(QFile::remove(secondFileName));
- timer.start(3000);
+ timer.start();
eventLoop.exec();
- QCOMPARE(fileChangedSpy.count(), 0);
+ QCOMPARE(fileChangedSpy.size(), 0);
QCOMPARE(dirChangedSpy.count(), 1);
// QTBUG-61792, removal should succeed (bug on Windows which uses one change
@@ -601,6 +632,7 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory()
QVERIFY(temporaryDir.rmdir(testDirName));
}
+#endif // QT_BUILD_INTERNAL
void tst_QFileSystemWatcher::nonExistingFile()
{
@@ -613,9 +645,11 @@ void tst_QFileSystemWatcher::nonExistingFile()
QStringList() << "../..//./does-not-exist");
// empty path is not actually a failure
+ QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::addPaths: list is empty");
QCOMPARE(watcher.addPaths(QStringList() << QString()), QStringList());
// empty path is not actually a failure
+ QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::removePaths: list is empty");
QCOMPARE(watcher.removePaths(QStringList() << QString()), QStringList());
}
@@ -673,6 +707,7 @@ void tst_QFileSystemWatcher::destroyAfterQCoreApplication()
QTest::qWait(30);
}
+#ifdef QT_BUILD_INTERNAL
// regression test for QTBUG2331.
// essentially, on windows, directories were not unwatched after being deleted
// from the disk, causing all sorts of interesting problems.
@@ -693,9 +728,10 @@ void tst_QFileSystemWatcher::QTBUG2331()
// remove directory, we should get one change signal, and we should no longer
// be watching the directory.
QVERIFY(temporaryDirectory.remove());
- QTRY_COMPARE(changedSpy.count(), 1);
+ QTRY_COMPARE(changedSpy.size(), 1);
QCOMPARE(watcher.directories(), QStringList());
}
+#endif // QT_BUILD_INTERNAL
class SignalReceiver : public QObject
{
@@ -704,7 +740,7 @@ public:
SignalReceiver(const QDir &moveSrcDir,
const QString &moveDestination,
QFileSystemWatcher *watcher,
- QObject *parent = 0)
+ QObject *parent = nullptr)
: QObject(parent),
added(false),
moveSrcDir(moveSrcDir),
@@ -720,7 +756,8 @@ public slots:
QCOMPARE(finfo.absolutePath(), moveSrcDir.absolutePath());
if (!added) {
- foreach (const QFileInfo &fi, moveDestination.entryInfoList(QDir::Files | QDir::NoSymLinks))
+ const auto entries = moveDestination.entryInfoList(QDir::Files | QDir::NoSymLinks);
+ for (const QFileInfo &fi : entries)
watcher->addPath(fi.absoluteFilePath());
added = true;
}
@@ -760,9 +797,9 @@ void tst_QFileSystemWatcher::signalsEmittedAfterFileMoved()
QVERIFY(watcher.addPath(movePath));
// add files to watcher
- QFileInfoList files = testDir.entryInfoList(QDir::Files | QDir::NoSymLinks);
+ const QFileInfoList files = testDir.entryInfoList(QDir::Files | QDir::NoSymLinks);
QCOMPARE(files.size(), fileCount);
- foreach (const QFileInfo &finfo, files)
+ for (const QFileInfo &finfo : files)
QVERIFY(watcher.addPath(finfo.absoluteFilePath()));
// create the signal receiver
@@ -774,7 +811,7 @@ void tst_QFileSystemWatcher::signalsEmittedAfterFileMoved()
QCOMPARE(changedSpy.count(), 0);
// move files to second directory
- foreach (const QFileInfo &finfo, files)
+ for (const QFileInfo &finfo : files)
QVERIFY(testDir.rename(finfo.fileName(), QString("movehere/%2").arg(finfo.fileName())));
QCoreApplication::processEvents();
@@ -801,5 +838,27 @@ void tst_QFileSystemWatcher::watchUnicodeCharacters()
QTRY_COMPARE(changedSpy.count(), 1);
}
+#if defined(Q_OS_WIN)
+void tst_QFileSystemWatcher::watchDirectoryAttributeChanges()
+{
+ QTemporaryDir temporaryDirectory(m_tempDirPattern);
+ QVERIFY2(temporaryDirectory.isValid(), qPrintable(temporaryDirectory.errorString()));
+
+ QDir testDir(temporaryDirectory.path());
+ const QString subDir(QString::fromLatin1("attrib_test"));
+ QVERIFY(testDir.mkdir(subDir));
+ testDir = QDir(temporaryDirectory.path() + QDir::separator() + subDir);
+
+ QFileSystemWatcher watcher;
+ QVERIFY(watcher.addPath(temporaryDirectory.path()));
+ FileSystemWatcherSpy changedSpy(&watcher, FileSystemWatcherSpy::SpyOnDirectoryChanged);
+ QCOMPARE(changedSpy.count(), 0);
+ QVERIFY(SetFileAttributes(reinterpret_cast<LPCWSTR>(testDir.absolutePath().utf16()), FILE_ATTRIBUTE_HIDDEN) != 0);
+ QTRY_COMPARE(changedSpy.count(), 1);
+ QVERIFY(SetFileAttributes(reinterpret_cast<LPCWSTR>(testDir.absolutePath().utf16()), FILE_ATTRIBUTE_NORMAL) != 0);
+ QTRY_COMPARE(changedSpy.count(), 2);
+}
+#endif
+
QTEST_MAIN(tst_QFileSystemWatcher)
#include "tst_qfilesystemwatcher.moc"
diff --git a/tests/auto/corelib/io/qiodevice/BLACKLIST b/tests/auto/corelib/io/qiodevice/BLACKLIST
deleted file mode 100644
index b8a61d3ca9..0000000000
--- a/tests/auto/corelib/io/qiodevice/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[unget]
-redhatenterpriselinuxworkstation-6.6
diff --git a/tests/auto/corelib/io/qiodevice/CMakeLists.txt b/tests/auto/corelib/io/qiodevice/CMakeLists.txt
new file mode 100644
index 0000000000..18cae40663
--- /dev/null
+++ b/tests/auto/corelib/io/qiodevice/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qiodevice Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qiodevice LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "tst_qiodevice.cpp")
+
+qt_internal_add_test(tst_qiodevice
+ SOURCES
+ tst_qiodevice.cpp
+ LIBRARIES
+ Qt::Network
+ TESTDATA ${test_data}
+ QT_TEST_SERVER_LIST "apache2" "cyrus"
+)
diff --git a/tests/auto/corelib/io/qiodevice/qiodevice.pro b/tests/auto/corelib/io/qiodevice/qiodevice.pro
deleted file mode 100644
index 1c978953d6..0000000000
--- a/tests/auto/corelib/io/qiodevice/qiodevice.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qiodevice
-QT = core network testlib
-SOURCES = tst_qiodevice.cpp
-
-TESTDATA += tst_qiodevice.cpp
-MOC_DIR=tmp
-
-android:!android-embedded {
- RESOURCES += \
- android_testdata.qrc
-}
diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
index da5327594c..ad88d14bc9 100644
--- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
+++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtNetwork/QtNetwork>
-#include <QtTest/QtTest>
+#include <QTest>
#include "../../../network-settings.h"
@@ -70,7 +45,7 @@ private:
void tst_QIODevice::initTestCase()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QVERIFY(QFileInfo(QStringLiteral("./tst_qiodevice.cpp")).exists()
|| QFile::copy(QStringLiteral(":/tst_qiodevice.cpp"), QStringLiteral("./tst_qiodevice.cpp")));
#endif
@@ -104,18 +79,20 @@ void tst_QIODevice::getSetCheck()
//----------------------------------------------------------------------------------
void tst_QIODevice::constructing_QTcpSocket()
{
-#if defined(Q_OS_WINRT)
- QSKIP("Synchronous socket calls are broken on winrt. See QTBUG-40922");
-#endif
+#ifdef QT_TEST_SERVER
+ if (!QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143))
+ QSKIP("No network test server available");
+#else
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
+#endif
QTcpSocket socket;
QIODevice *device = &socket;
QVERIFY(!device->isOpen());
- socket.connectToHost(QtNetworkSettings::serverName(), 143);
+ socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
QVERIFY(socket.waitForConnected(30000));
QVERIFY(device->isOpen());
QCOMPARE(device->readChannelCount(), 1);
@@ -133,7 +110,7 @@ void tst_QIODevice::constructing_QTcpSocket()
socket.close();
QCOMPARE(socket.readChannelCount(), 0);
QCOMPARE(socket.writeChannelCount(), 0);
- socket.connectToHost(QtNetworkSettings::serverName(), 143);
+ socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
QVERIFY(socket.waitForConnected(30000));
QVERIFY(device->isOpen());
@@ -194,16 +171,16 @@ void tst_QIODevice::constructing_QFile()
void tst_QIODevice::read_QByteArray()
{
QFile f(QFINDTESTDATA("tst_qiodevice.cpp"));
- f.open(QIODevice::ReadOnly);
+ QVERIFY(f.open(QIODevice::ReadOnly));
QByteArray b = f.read(10);
- QCOMPARE(b.length(), 10);
+ QCOMPARE(b.size(), 10);
b = f.read(256);
- QCOMPARE(b.length(), 256);
+ QCOMPARE(b.size(), 256);
b = f.read(0);
- QCOMPARE(b.length(), 0);
+ QCOMPARE(b.size(), 0);
}
//--------------------------------------------------------------------
@@ -263,9 +240,6 @@ void tst_QIODevice::unget()
buffer.ungetChar('Q');
QCOMPARE(buffer.readLine(buf, 3), qint64(1));
-#if defined(Q_OS_WINRT)
- QSKIP("Synchronous socket calls are broken on winrt. See QTBUG-40922");
-#endif
for (int i = 0; i < 2; ++i) {
QTcpSocket socket;
QIODevice *dev;
@@ -276,9 +250,17 @@ void tst_QIODevice::unget()
result = QByteArray("ZXCV");
lineResult = "ZXCV";
} else {
- if (!QtNetworkSettings::verifyTestNetworkSettings())
- QSKIP("No network test server available");
- socket.connectToHost(QtNetworkSettings::serverName(), 80);
+#ifdef QT_TEST_SERVER
+ const bool hasNetworkServer =
+ QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80);
+#else
+ const bool hasNetworkServer = QtNetworkSettings::verifyTestNetworkSettings();
+#endif
+ if (!hasNetworkServer) {
+ qInfo("No network test server: skipping QTcpSocket part of test.");
+ continue;
+ }
+ socket.connectToHost(QtNetworkSettings::httpServerName(), 80);
socket.write("GET / HTTP/1.0\r\n\r\n");
QVERIFY(socket.waitForReadyRead());
dev = &socket;
@@ -413,6 +395,9 @@ void tst_QIODevice::readLine()
QVERIFY(buffer.open(QIODevice::ReadWrite));
QVERIFY(buffer.canReadLine());
+ QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine (QBuffer): Called with maxSize < 2");
+ QCOMPARE(buffer.readLine(nullptr, 0), qint64(-1));
+
int linelen = data.indexOf('\n') + 1;
QByteArray line;
line.reserve(linelen + 100);
@@ -561,7 +546,8 @@ protected:
qint64 readData(char *data, qint64 maxSize) override
{
maxSize = qMin(maxSize, qint64(buf->size() - offset));
- memcpy(data, buf->constData() + offset, maxSize);
+ if (maxSize > 0)
+ memcpy(data, buf->constData() + offset, maxSize);
offset += maxSize;
return maxSize;
}
@@ -604,13 +590,15 @@ protected:
qint64 readData(char *data, qint64 maxSize) override
{
maxSize = qMin(maxSize, qint64(buf.size() - pos()));
- memcpy(data, buf.constData() + pos(), maxSize);
+ if (maxSize > 0)
+ memcpy(data, buf.constData() + pos(), maxSize);
return maxSize;
}
qint64 writeData(const char *data, qint64 maxSize) override
{
maxSize = qMin(maxSize, qint64(buf.size() - pos()));
- memcpy(buf.data() + pos(), data, maxSize);
+ if (maxSize > 0)
+ memcpy(buf.data() + pos(), data, maxSize);
return maxSize;
}
@@ -652,11 +640,12 @@ void tst_QIODevice::skip_data()
do {
QByteArray devName(sequential ? "sequential" : "random-access");
- QTest::newRow(qPrintable(devName + "-small_data")) << true << QByteArray("abcdefghij")
+ QTest::newRow(qPrintable(devName + "-small_data")) << sequential
+ << QByteArray("abcdefghij")
<< 3 << 6 << 6 << 'j';
- QTest::newRow(qPrintable(devName + "-big_data")) << true << bigData
+ QTest::newRow(qPrintable(devName + "-big_data")) << sequential << bigData
<< 1 << 10000 << 10000 << 'x';
- QTest::newRow(qPrintable(devName + "-beyond_the_end")) << true << bigData
+ QTest::newRow(qPrintable(devName + "-beyond_the_end")) << sequential << bigData
<< 1 << 20000 << 19999 << '\0';
sequential = !sequential;
diff --git a/tests/auto/corelib/io/qipaddress/CMakeLists.txt b/tests/auto/corelib/io/qipaddress/CMakeLists.txt
new file mode 100644
index 0000000000..c57ef52c1d
--- /dev/null
+++ b/tests/auto/corelib/io/qipaddress/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qipaddress Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qipaddress LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qipaddress
+ SOURCES
+ tst_qipaddress.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/io/qipaddress/qipaddress.pro b/tests/auto/corelib/io/qipaddress/qipaddress.pro
deleted file mode 100644
index 9c769052ed..0000000000
--- a/tests/auto/corelib/io/qipaddress/qipaddress.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += tst_qipaddress.cpp
-TARGET = tst_qipaddress
-QT = core core-private testlib
-CONFIG += testcase
diff --git a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp
index d41efa18f5..c0a738e22d 100644
--- a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp
+++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#define _CRT_SECURE_NO_WARNINGS 1
#include <QtCore/QString>
-#include <QtTest/QtTest>
+#include <QTest>
#include <QtCore/private/qipaddress_p.h>
#ifdef __GLIBC__
@@ -93,7 +70,7 @@ namespace QTest {
char *toString(const Ip6 &ip6)
{
char buf[sizeof "1111:2222:3333:4444:5555:6666:7777:8888" + 2];
- sprintf(buf, "%x:%x:%x:%x:%x:%x:%x:%x",
+ snprintf(buf, sizeof(buf), "%x:%x:%x:%x:%x:%x:%x:%x",
ip6.u8[0] << 8 | ip6.u8[1],
ip6.u8[2] << 8 | ip6.u8[3],
ip6.u8[4] << 8 | ip6.u8[5],
diff --git a/tests/auto/corelib/io/qlockfile/CMakeLists.txt b/tests/auto/corelib/io/qlockfile/CMakeLists.txt
new file mode 100644
index 0000000000..1dda272d52
--- /dev/null
+++ b/tests/auto/corelib/io/qlockfile/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qlockfile Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlockfile LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qlockfile
+ SOURCES
+ tst_qlockfile.cpp
+ LIBRARIES
+ Qt::Concurrent
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qlockfile CONDITION WIN32
+ LIBRARIES
+ advapi32
+)
+add_subdirectory(qlockfiletesthelper)
+
+if(QT_FEATURE_process AND NOT ANDROID)
+ add_dependencies(tst_qlockfile qlockfile_test_helper)
+endif()
diff --git a/tests/auto/corelib/io/qlockfile/qlockfile.pro b/tests/auto/corelib/io/qlockfile/qlockfile.pro
deleted file mode 100644
index 91f104305c..0000000000
--- a/tests/auto/corelib/io/qlockfile/qlockfile.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += tst_qlockfile.pro qlockfiletesthelper/qlockfile_test_helper.pro
diff --git a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/CMakeLists.txt b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/CMakeLists.txt
new file mode 100644
index 0000000000..c8bde9d606
--- /dev/null
+++ b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## qlockfile_test_helper Binary:
+#####################################################################
+
+qt_internal_add_test_helper(qlockfile_test_helper
+ OVERRIDE_OUTPUT_DIRECTORY
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ qlockfile_test_helper.cpp
+)
diff --git a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp
index e086bf1904..b990209f32 100644
--- a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp
+++ b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDebug>
#include <QCoreApplication>
diff --git a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro
deleted file mode 100644
index 97135d279e..0000000000
--- a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TARGET = qlockfile_test_helper
-SOURCES += qlockfile_test_helper.cpp
-
-CONFIG += cmdline
-QT = core
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
index eeeb3bc6e2..b7056e20c9 100644
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
@@ -1,46 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2013 David Faure <faure+bluesystems@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
+
+#include <QTest>
#include <QtConcurrentRun>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
+#include <QSemaphore>
+#include <QFutureSynchronizer>
+
#include <qlockfile.h>
#include <qtemporarydir.h>
#include <qsysinfo.h>
#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
#include <unistd.h>
+
+#include <sys/stat.h> // utimensat
#include <sys/time.h>
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#elif defined(Q_OS_WIN)
# include <qt_windows.h>
+# include <QOperatingSystemVersion>
#endif
#include <private/qlockfile_p.h> // for getLockFileHandle()
+using namespace std::chrono_literals;
+
class tst_QLockFile : public QObject
{
Q_OBJECT
@@ -78,7 +66,7 @@ public:
void tst_QLockFile::initTestCase()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QSKIP("This test requires deploying and running external console applications");
#elif !QT_CONFIG(process)
QSKIP("This test requires QProcess support");
@@ -96,6 +84,7 @@ void tst_QLockFile::lockUnlock()
const QString fileName = dir.path() + "/lock1";
QVERIFY(!QFile(fileName).exists());
QLockFile lockFile(fileName);
+ QCOMPARE(lockFile.fileName(), fileName);
QVERIFY(lockFile.lock());
QVERIFY(lockFile.isLocked());
QCOMPARE(int(lockFile.error()), int(QLockFile::NoError));
@@ -110,7 +99,7 @@ void tst_QLockFile::lockUnlock()
QVERIFY(lockFile.getLockInfo(&pid, &hostname, &appname));
QCOMPARE(pid, QCoreApplication::applicationPid());
QCOMPARE(appname, qAppName());
- QVERIFY(!lockFile.tryLock(200));
+ QVERIFY(!lockFile.tryLock(200ms));
QCOMPARE(int(lockFile.error()), int(QLockFile::LockFailedError));
// Unlock deletes the lock file
@@ -163,13 +152,13 @@ void tst_QLockFile::lockOutOtherThread()
QVERIFY(lockFile.lock());
// Other thread can't acquire lock
- QFuture<QLockFile::LockError> ret = QtConcurrent::run<QLockFile::LockError>(tryLockFromThread, fileName);
+ auto ret = QtConcurrent::run(tryLockFromThread, fileName);
QCOMPARE(ret.result(), QLockFile::LockFailedError);
lockFile.unlock();
// Now other thread can acquire lock
- QFuture<QLockFile::LockError> ret2 = QtConcurrent::run<QLockFile::LockError>(tryLockFromThread, fileName);
+ auto ret2 = QtConcurrent::run(tryLockFromThread, fileName);
QCOMPARE(ret2.result(), QLockFile::NoError);
}
@@ -186,13 +175,13 @@ static QLockFile::LockError lockFromThread(const QString &fileName)
void tst_QLockFile::raceWithOtherThread()
{
const QString fileName = dir.path() + "/raceWithOtherThread";
- QFuture<QLockFile::LockError> ret = QtConcurrent::run<QLockFile::LockError>(lockFromThread, fileName);
- QFuture<QLockFile::LockError> ret2 = QtConcurrent::run<QLockFile::LockError>(lockFromThread, fileName);
+ auto ret = QtConcurrent::run(lockFromThread, fileName);
+ auto ret2 = QtConcurrent::run(lockFromThread, fileName);
QCOMPARE(ret.result(), QLockFile::NoError);
QCOMPARE(ret2.result(), QLockFile::NoError);
}
-static bool lockFromThread(const QString &fileName, int sleepMs, QSemaphore *semThreadReady, QSemaphore *semMainThreadDone)
+static bool lockFromThreadAndWait(const QString &fileName, int sleepMs, QSemaphore *semThreadReady, QSemaphore *semMainThreadDone)
{
QLockFile lockFile(fileName);
if (!lockFile.lock()) {
@@ -233,7 +222,7 @@ void tst_QLockFile::waitForLock()
QLockFile lockFile(fileName);
QSemaphore semThreadReady, semMainThreadDone;
// Lock file from a thread
- QFuture<bool> ret = QtConcurrent::run<bool>(lockFromThread, fileName, threadSleepMs, &semThreadReady, &semMainThreadDone);
+ auto ret = QtConcurrent::run(lockFromThreadAndWait, fileName, threadSleepMs, &semThreadReady, &semMainThreadDone);
semThreadReady.acquire();
if (releaseEarly) // let the thread release the lock after threadSleepMs
@@ -248,7 +237,7 @@ void tst_QLockFile::waitForLock()
if (!releaseEarly) // only let the thread release the lock now
semMainThreadDone.release();
- QVERIFY(ret); // waits for the thread to finish
+ QVERIFY(ret.result()); // waits for the thread to finish
}
void tst_QLockFile::staleLockFromCrashedProcess_data()
@@ -289,7 +278,7 @@ void tst_QLockFile::staleLockFromCrashedProcessReusedPid()
{
#if !QT_CONFIG(process)
QSKIP("This test requires QProcess support");
-#elif defined(Q_OS_WINRT) || defined(QT_PLATFORM_UIKIT)
+#elif defined(QT_PLATFORM_UIKIT)
QSKIP("We cannot retrieve information about other processes on this platform.");
#else
const QString fileName = dir.path() + "/staleLockFromCrashedProcessReusedPid";
@@ -328,7 +317,7 @@ void tst_QLockFile::staleShortLockFromBusyProcess()
QString hostname, appname;
QTRY_VERIFY(secondLock.getLockInfo(&pid, &hostname, &appname));
#ifdef Q_OS_UNIX
- QCOMPARE(pid, proc.pid());
+ QCOMPARE(pid, proc.processId());
#endif
secondLock.setStaleLockTime(100);
@@ -355,8 +344,8 @@ void tst_QLockFile::staleLongLockFromBusyProcess()
QTRY_VERIFY(QFile::exists(fileName));
QLockFile secondLock(fileName);
- secondLock.setStaleLockTime(0);
- QVERIFY(!secondLock.tryLock(100)); // never stale
+ secondLock.setStaleLockTime(0ms);
+ QVERIFY(!secondLock.tryLock(100ms)); // never stale
QCOMPARE(int(secondLock.error()), int(QLockFile::LockFailedError));
qint64 pid;
QTRY_VERIFY(secondLock.getLockInfo(&pid, NULL, NULL));
@@ -410,7 +399,7 @@ void tst_QLockFile::staleLockRace()
QThreadPool::globalInstance()->setMaxThreadCount(10);
QFutureSynchronizer<QString> synchronizer;
for (int i = 0; i < 8; ++i)
- synchronizer.addFuture(QtConcurrent::run<QString>(tryStaleLockFromThread, fileName));
+ synchronizer.addFuture(QtConcurrent::run(tryStaleLockFromThread, fileName));
synchronizer.waitForFinished();
foreach (const QFuture<QString> &future, synchronizer.futures())
QVERIFY2(future.result().isEmpty(), qPrintable(future.result()));
@@ -444,7 +433,7 @@ void tst_QLockFile::noPermissions()
const QString fileName = dir.path() + "/staleLock";
QFile dirAsFile(dir.path()); // I have to use QFile to change a dir's permissions...
- QVERIFY2(dirAsFile.setPermissions(QFile::Permissions(0)), qPrintable(dir.path())); // no permissions
+ QVERIFY2(dirAsFile.setPermissions(QFile::Permissions{}), qPrintable(dir.path())); // no permissions
PermissionRestorer permissionRestorer(dir.path());
QLockFile lockFile(fileName);
@@ -463,7 +452,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(ProcessProperties)
static inline ProcessProperties processProperties()
{
ProcessProperties result;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
HANDLE processToken = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &processToken)) {
DWORD elevation; // struct containing a DWORD, not present in some MinGW headers.
@@ -492,11 +481,11 @@ void tst_QLockFile::noPermissionsWindows()
{
// Windows: Do the permissions test in a system directory in which
// files cannot be created.
-#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
+#if !defined(Q_OS_WIN)
QSKIP("This test is for desktop Windows only");
#endif
#ifdef Q_OS_WIN
- if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows7)
QSKIP("This test requires at least Windows 7");
#endif
if (const int p = processProperties()) {
@@ -524,15 +513,15 @@ void tst_QLockFile::corruptedLockFile()
}
QLockFile secondLock(fileName);
- secondLock.setStaleLockTime(100);
- QVERIFY(secondLock.tryLock(10000));
+ secondLock.setStaleLockTime(100ms);
+ QVERIFY(secondLock.tryLock(10s));
QCOMPARE(int(secondLock.error()), int(QLockFile::NoError));
}
void tst_QLockFile::corruptedLockFileInTheFuture()
{
-#if !defined(Q_OS_UNIX)
- QSKIP("This tests needs utimes");
+#if !defined(Q_OS_UNIX) || defined(Q_OS_VXWORKS)
+ QSKIP("This test needs utimensat");
#else
// This test is the same as the previous one, but the corruption was so there is a corrupted
// .rmlock whose timestamp is in the future
@@ -544,11 +533,12 @@ void tst_QLockFile::corruptedLockFileInTheFuture()
QVERIFY(file.open(QFile::WriteOnly));
}
- struct timeval times[2];
- gettimeofday(times, 0);
- times[1].tv_sec = (times[0].tv_sec += 600);
- times[1].tv_usec = times[0].tv_usec;
- utimes(fileName.toLocal8Bit(), times);
+ struct timespec times[2];
+ clock_gettime(CLOCK_REALTIME, times);
+ times[0].tv_sec += 600;
+ times[1].tv_sec = times[0].tv_sec;
+ times[1].tv_nsec = times[0].tv_nsec;
+ utimensat(0 /* ignored */, fileName.toLocal8Bit(), times, 0);
QTest::ignoreMessage(QtInfoMsg, "QLockFile: Lock file '" + fileName.toUtf8() + "' has a modification time in the future");
corruptedLockFile();
@@ -577,7 +567,7 @@ void tst_QLockFile::hostnameChange()
{
// we should fail to lock
QLockFile lock2(lockFile);
- QVERIFY(!lock2.tryLock(1000));
+ QVERIFY(!lock2.tryLock(1s));
}
}
@@ -604,7 +594,7 @@ void tst_QLockFile::differentMachines()
{
// we should fail to lock
QLockFile lock2(lockFile);
- QVERIFY(!lock2.tryLock(1000));
+ QVERIFY(!lock2.tryLock(1s));
}
}
@@ -633,7 +623,7 @@ void tst_QLockFile::reboot()
f.close();
// we should succeed in locking
- QVERIFY(lock1.tryLock(0));
+ QVERIFY(lock1.tryLock(0ms));
}
bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid)
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro b/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro
deleted file mode 100644
index da2660fd02..0000000000
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qlockfile
-SOURCES += tst_qlockfile.cpp
-
-QT = core-private testlib concurrent
-win32:!winrt:LIBS += -ladvapi32
diff --git a/tests/auto/corelib/io/qloggingcategory/CMakeLists.txt b/tests/auto/corelib/io/qloggingcategory/CMakeLists.txt
new file mode 100644
index 0000000000..0e9fc98fae
--- /dev/null
+++ b/tests/auto/corelib/io/qloggingcategory/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qloggingcategory Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qloggingcategory LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qloggingcategory
+ SOURCES
+ tst_qloggingcategory.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/io/qloggingcategory/qloggingcategory.pro b/tests/auto/corelib/io/qloggingcategory/qloggingcategory.pro
deleted file mode 100644
index 8492daefc1..0000000000
--- a/tests/auto/corelib/io/qloggingcategory/qloggingcategory.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = app
-TARGET = tst_qloggingcategory
-
-CONFIG += testcase
-QT = core core-private testlib
-
-SOURCES += tst_qloggingcategory.cpp
diff --git a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
index 11a9b3f189..476ca275a4 100644
--- a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
+++ b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
@@ -1,34 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QMutexLocker>
#include <QLoggingCategory>
+#include <QMap>
+#include <QStringList>
Q_LOGGING_CATEGORY(TST_LOG, "tst.log")
Q_LOGGING_CATEGORY(Digia_Oslo_Office_com, "Digia.Oslo.Office.com")
@@ -101,10 +78,10 @@ public:
{
QString ret;
QTextStream out(&ret);
- for (int a = 0; a < _configitemEntryOrder.count(); a++) {
+ for (int a = 0; a < _configitemEntryOrder.size(); a++) {
out << _configitemEntryOrder[a]
<< " = "
- << _values.value(_configitemEntryOrder[a]) << endl;
+ << _values.value(_configitemEntryOrder[a]) << Qt::endl;
}
out.flush();
return ret.toLatin1();
@@ -133,7 +110,7 @@ public:
: _logtext(logtext), _configuration(configuration)
{}
protected:
- void run()
+ void run() override
{
for (int i = 0; i < 2000; i++) {
_configuration->addKey("Digia*", true);
@@ -176,7 +153,7 @@ inline QString cleanLogLine(const QString &qstring)
buf.remove("../");
buf.remove("qlog/");
QString ret;
- for (int i = 0; i < buf.length(); i++) {
+ for (int i = 0; i < buf.size(); i++) {
if (buf[i] >= '!' && buf[i] <= 'z')
ret += buf[i];
}
@@ -204,7 +181,7 @@ private slots:
void initTestCase()
{
qputenv("XDG_CONFIG_DIRS", "/does/not/exist");
- qputenv("QT_MESSAGE_PATTERN", QByteArray("%{category}: %{type},%{message}"));
+ qputenv("QT_MESSAGE_PATTERN", "%{category}: %{type},%{message}");
oldMessageHandler = qInstallMessageHandler(myCustomMessageHandler);
// Create configuration
_config = new Configuration();
@@ -369,11 +346,9 @@ private slots:
}
Q_LOGGING_CATEGORY(TST_MACRO_1, "tst.macro.1")
-#ifdef Q_COMPILER_VARIADIC_MACROS
Q_LOGGING_CATEGORY(TST_MACRO_2, "tst.macro.2", QtDebugMsg)
Q_LOGGING_CATEGORY(TST_MACRO_3, "tst.macro.3", QtFatalMsg)
Q_LOGGING_CATEGORY(TST_MACRO_4, "tst.macro.4", QtInfoMsg)
-#endif
void QLoggingCategoryMacro()
{
@@ -384,7 +359,6 @@ private slots:
QCOMPARE(cat1.isWarningEnabled(), true);
QCOMPARE(cat1.isCriticalEnabled(), true);
-#ifdef Q_COMPILER_VARIADIC_MACROS
const QLoggingCategory &cat2 = TST_MACRO_2();
QCOMPARE(cat2.categoryName(), "tst.macro.2");
QCOMPARE(cat2.isDebugEnabled(), true);
@@ -405,7 +379,6 @@ private slots:
QCOMPARE(cat4.isInfoEnabled(), true);
QCOMPARE(cat4.isWarningEnabled(), true);
QCOMPARE(cat4.isCriticalEnabled(), true);
-#endif
}
void qCDebugMacros()
@@ -824,7 +797,7 @@ private slots:
{
_config->clear();
_config->addKey("LoggingCategoryObject", true);
- QLoggingCategory *pcategorybject = 0;
+ QLoggingCategory *pcategorybject = nullptr;
QLoggingCategory::setFilterRules(_config->array());
{
QLoggingCategory mycategoryobject("LoggingCategoryObject");
@@ -930,7 +903,7 @@ private slots:
buf = QStringLiteral("Digia.Berlin.Office.com.debug: Berlin \"from Thread 2\" :false");
compareagainst.append(cleanLogLine(buf));
- for (int i = 0; i < threadtest.count(); i++) {
+ for (int i = 0; i < threadtest.size(); i++) {
if (!compareagainst.contains(cleanLogLine(threadtest[i]))){
fprintf(stdout, "%s\r\n", threadtest[i].toLatin1().constData());
QVERIFY2(false, "Multithread log is not complete!");
@@ -943,6 +916,23 @@ private slots:
delete _config;
qInstallMessageHandler(oldMessageHandler);
}
+
+ void qFatalMacros()
+ {
+ QLoggingCategory customCategory("custom");
+
+ // compile-only test for fatal macros
+ return;
+
+ qFatal("Message");
+ qFatal("Message %d", 42);
+ qFatal(customCategory, "Message %d", 42);
+ qFatal(TST_LOG, "Message %d", 42);
+
+ qFatal() << "Message" << 42;
+ qCFatal(customCategory) << "Message" << 42;
+ qCFatal(TST_LOG) << "Message" << 42;
+ }
};
QTEST_MAIN(tst_QLogging)
diff --git a/tests/auto/corelib/io/qloggingregistry/CMakeLists.txt b/tests/auto/corelib/io/qloggingregistry/CMakeLists.txt
new file mode 100644
index 0000000000..5442c76e7f
--- /dev/null
+++ b/tests/auto/corelib/io/qloggingregistry/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qloggingregistry Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qloggingregistry LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "qtlogging.ini")
+
+qt_internal_add_test(tst_qloggingregistry
+ SOURCES
+ tst_qloggingregistry.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro
deleted file mode 100644
index ac976e9b9c..0000000000
--- a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TEMPLATE = app
-TARGET = tst_qloggingregistry
-
-CONFIG += testcase
-QT = core core-private testlib
-
-SOURCES += tst_qloggingregistry.cpp
-TESTDATA += qtlogging.ini
-
-android:!android-embedded {
- RESOURCES += \
- android_testdata.qrc
-}
diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
index a10e706ed7..b3af31ac27 100644
--- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
+++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
@@ -1,33 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QLoggingCategory>
+#include <QStandardPaths>
#include <QtCore/private/qloggingregistry_p.h>
@@ -158,10 +134,13 @@ private slots:
QFETCH(QtMsgType, msgType);
QFETCH(LoggingRuleState, result);
- QLoggingRule rule(QStringRef(&pattern), true);
+ const auto categoryL1 = category.toLatin1();
+ const auto categoryL1S = QLatin1String(categoryL1);
+
+ QLoggingRule rule(pattern, true);
LoggingRuleState state = Invalid;
if (rule.flags != 0) {
- switch (rule.pass(category, msgType)) {
+ switch (rule.pass(categoryL1S, msgType)) {
case -1: QFAIL("Shoudn't happen, we set pattern to true"); break;
case 0: state = NoMatch; break;
case 1: state = Match; break;
@@ -178,24 +157,24 @@ private slots:
// default category, and optional ...
//
QLoggingSettingsParser parser;
- parser.setContent("[Rules]\n"
- "default=false\n"
- "default=true");
+ parser.setContent(u"[Rules]\n"
+ "default=false\n"
+ "default=true");
QCOMPARE(parser.rules().size(), 2);
- parser.setContent("[Rules]\n"
- "default=false");
+ parser.setContent(u"[Rules]\n"
+ "default=false");
QCOMPARE(parser.rules().size(), 1);
// QSettings escapes * to %2A when writing.
- parser.setContent("[Rules]\n"
- "module.%2A=false");
+ parser.setContent(u"[Rules]\n"
+ "module.%2A=false");
QCOMPARE(parser.rules().size(), 1);
QCOMPARE(parser.rules().first().category, QString("module."));
QCOMPARE(parser.rules().first().flags, QLoggingRule::LeftFilter);
- parser.setContent("[OtherSection]\n"
- "default=false");
+ parser.setContent(u"[OtherSection]\n"
+ "default=false");
QCOMPARE(parser.rules().size(), 0);
}
@@ -286,7 +265,7 @@ private slots:
// set Config rule
QLoggingSettingsParser parser;
- parser.setContent("[Rules]\nDigia.*=false");
+ parser.setContent(u"[Rules]\nDigia.*=false");
registry->ruleSets[QLoggingRegistry::ConfigRules] = parser.rules();
registry->updateRules();
@@ -298,7 +277,7 @@ private slots:
QVERIFY(cat.isWarningEnabled());
// set Env rule, should overwrite Config one
- parser.setContent("Digia.*=false");
+ parser.setContent(u"Digia.*=false");
registry->ruleSets[QLoggingRegistry::EnvironmentRules] = parser.rules();
registry->updateRules();
@@ -312,10 +291,10 @@ private slots:
QTest::ignoreMessage(QtWarningMsg, "Ignoring malformed logging rule: '***=false'");
QTest::ignoreMessage(QtWarningMsg, "Ignoring malformed logging rule: '*=0'");
QTest::ignoreMessage(QtWarningMsg, "Ignoring malformed logging rule: '*=TRUE'");
- parser.setContent("[Rules]\n"
- "***=false\n"
- "*=0\n"
- "*=TRUE\n");
+ parser.setContent(u"[Rules]\n"
+ "***=false\n"
+ "*=0\n"
+ "*=TRUE\n");
QVERIFY(parser.rules().isEmpty());
}
};
diff --git a/tests/auto/corelib/io/qnodebug/CMakeLists.txt b/tests/auto/corelib/io/qnodebug/CMakeLists.txt
new file mode 100644
index 0000000000..5fc64976c3
--- /dev/null
+++ b/tests/auto/corelib/io/qnodebug/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qnodebug Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qnodebug LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qnodebug
+ SOURCES
+ tst_qnodebug.cpp
+)
diff --git a/tests/auto/corelib/io/qnodebug/qnodebug.pro b/tests/auto/corelib/io/qnodebug/qnodebug.pro
deleted file mode 100644
index 7e35f92474..0000000000
--- a/tests/auto/corelib/io/qnodebug/qnodebug.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qnodebug
-QT = core testlib
-SOURCES = tst_qnodebug.cpp
diff --git a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
index 569c610e24..0ff46c45a4 100644
--- a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
+++ b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// This test is for "release" mode, with -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT
#ifndef QT_NO_DEBUG
@@ -37,7 +12,7 @@
#include <QtCore/QtCore>
#include <QtCore/QtDebug>
#include <QtCore/QLoggingCategory>
-#include <QtTest/QtTest>
+#include <QTest>
class tst_QNoDebug: public QObject
{
@@ -65,7 +40,7 @@ void tst_QNoDebug::noDebugOutput() const
void tst_QNoDebug::streaming() const
{
QDateTime dt(QDate(1,2,3),QTime(4,5,6));
- const QByteArray debugString = dt.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t")).toLatin1();
+ const QByteArray debugString = dt.toString(u"yyyy-MM-dd HH:mm:ss.zzz t").toLocal8Bit();
const QByteArray message = "QDateTime(" + debugString + " Qt::LocalTime)";
QTest::ignoreMessage(QtWarningMsg, message.constData());
qWarning() << dt;
diff --git a/tests/auto/corelib/io/qprocess-noapplication/CMakeLists.txt b/tests/auto/corelib/io/qprocess-noapplication/CMakeLists.txt
new file mode 100644
index 0000000000..fd4312baf7
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess-noapplication/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## qprocess-noapplication Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(qprocess-noapplication LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(qprocess-noapplication
+ SOURCES
+ tst_qprocessnoapplication.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro b/tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro
deleted file mode 100644
index 8e46320e0c..0000000000
--- a/tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-CONFIG -= debug_and_release_target
-QT = core testlib
-SOURCES = tst_qprocessnoapplication.cpp
diff --git a/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp b/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp
index b9702a93cf..c84651913d 100644
--- a/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp
+++ b/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QThread>
-#include <QtTest>
+#include <QTest>
class tst_QProcessNoApplication : public QObject
{
@@ -49,7 +24,7 @@ void tst_QProcessNoApplication::initializationDeadlock()
struct MyThread : public QThread
{
- void run()
+ void run() override
{
// what we execute does not matter, as long as we try to
// and that the process exits
diff --git a/tests/auto/corelib/io/qprocess/BLACKLIST b/tests/auto/corelib/io/qprocess/BLACKLIST
deleted file mode 100644
index b355bb0f75..0000000000
--- a/tests/auto/corelib/io/qprocess/BLACKLIST
+++ /dev/null
@@ -1,9 +0,0 @@
-[lockupsInStartDetached]
-redhatenterpriselinuxworkstation-6.6
-# QTBUG-48455
-[fileWriterProcess]
-msvc-2015 ci
-msvc-2017 ci
-[softExitInSlots]
-# QTBUG-66903
-windows
diff --git a/tests/auto/corelib/io/qprocess/CMakeLists.txt b/tests/auto/corelib/io/qprocess/CMakeLists.txt
new file mode 100644
index 0000000000..17dea9688f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(qprocess LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(test)
+add_subdirectory(testProcessCrash)
+add_subdirectory(testProcessEcho)
+add_subdirectory(testProcessEcho2)
+add_subdirectory(testProcessEcho3)
+add_subdirectory(testProcessEnvironment)
+add_subdirectory(testProcessHang)
+add_subdirectory(testProcessNormal)
+add_subdirectory(testProcessOutput)
+add_subdirectory(testProcessDeadWhileReading)
+add_subdirectory(testProcessEOF)
+add_subdirectory(testExitCodes)
+add_subdirectory(testForwarding)
+add_subdirectory(testForwardingHelper)
+if(TARGET Qt::Widgets)
+ add_subdirectory(testGuiProcess)
+endif()
+add_subdirectory(testDetached)
+add_subdirectory(fileWriterProcess)
+add_subdirectory(testSetWorkingDirectory)
+add_subdirectory(testSoftExit)
+add_subdirectory(testProcessSpacesArgs)
+add_subdirectory(testSpaceInName)
+if(WIN32)
+ add_subdirectory(testProcessEchoGui)
+ add_subdirectory(testSetNamedPipeHandleState)
+endif()
+if(UNIX)
+ add_subdirectory(testUnixProcessParameters)
+endif()
diff --git a/tests/auto/corelib/io/qprocess/crasher.h b/tests/auto/corelib/io/qprocess/crasher.h
new file mode 100644
index 0000000000..7d55bf980f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/crasher.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#if defined(_MSC_VER)
+# include <intrin.h>
+#endif
+#if __has_include(<signal.h>)
+# include <signal.h>
+#endif
+#if __has_include(<sys/resource.h>)
+# include <sys/resource.h>
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+namespace tst_QProcessCrash {
+struct NoCoreDumps
+{
+#if defined(RLIMIT_CORE)
+ struct rlimit rlim;
+ NoCoreDumps()
+ {
+ if (getrlimit(RLIMIT_CORE, &rlim) == 0 && rlim.rlim_cur != 0) {
+ struct rlimit newrlim = rlim;
+ newrlim.rlim_cur = 0;
+ setrlimit(RLIMIT_CORE, &newrlim);
+ }
+ }
+ ~NoCoreDumps()
+ {
+ setrlimit(RLIMIT_CORE, &rlim);
+ }
+#endif // RLIMIT_CORE
+};
+
+void crashFallback(volatile int *ptr = nullptr)
+{
+ *ptr = 0;
+}
+
+void crash()
+{
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+ __ud2();
+#elif __has_builtin(__builtin_trap)
+ __builtin_trap();
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ asm("ud2");
+#elif defined(SIGILL)
+ raise(SIGILL);
+#endif
+
+ crashFallback();
+}
+} // namespace tst_QProcessCrash
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt b/tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt
new file mode 100644
index 0000000000..d431ba2c3f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## fileWriterProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(fileWriterProcess
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro b/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro
deleted file mode 100644
index 2744491151..0000000000
--- a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-QT = core
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
index efeadadb93..0349a48067 100644
--- a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
+++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
#include <QFile>
@@ -34,7 +9,8 @@ int main(int argc, char **argv)
{
QCoreApplication ca(argc, argv);
QFile f;
- f.open(stdin, QIODevice::ReadOnly);
+ if (!f.open(stdin, QIODevice::ReadOnly))
+ return 1;
QByteArray input;
char buf[1024];
qint64 len;
diff --git a/tests/auto/corelib/io/qprocess/qprocess.pri b/tests/auto/corelib/io/qprocess/qprocess.pri
deleted file mode 100644
index 8d17090545..0000000000
--- a/tests/auto/corelib/io/qprocess/qprocess.pri
+++ /dev/null
@@ -1,22 +0,0 @@
-SUBPROGRAMS = \
- testProcessCrash \
- testProcessEcho \
- testProcessEcho2 \
- testProcessEcho3 \
- testProcessEnvironment \
- testProcessHang \
- testProcessNormal \
- testProcessOutput \
- testProcessDeadWhileReading \
- testProcessEOF \
- testExitCodes \
- testForwarding \
- testForwardingHelper \
- testGuiProcess \
- testDetached \
- fileWriterProcess \
- testSetWorkingDirectory \
- testSoftExit
-
-!qtHaveModule(widgets): SUBPROGRAMS -= \
- testGuiProcess
diff --git a/tests/auto/corelib/io/qprocess/qprocess.pro b/tests/auto/corelib/io/qprocess/qprocess.pro
deleted file mode 100644
index 3867ac5741..0000000000
--- a/tests/auto/corelib/io/qprocess/qprocess.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TEMPLATE = subdirs
-
-include(qprocess.pri)
-SUBDIRS = $$SUBPROGRAMS
-# Add special cases
-SUBDIRS += testProcessSpacesArgs/nospace.pro \
- testProcessSpacesArgs/onespace.pro \
- testProcessSpacesArgs/twospaces.pro \
- testSpaceInName
-
-win32 {
- SUBDIRS += \
- testProcessEchoGui \
- testSetNamedPipeHandleState
-}
-
-test.depends += $$SUBDIRS
-SUBDIRS += test
diff --git a/tests/auto/corelib/io/qprocess/test/CMakeLists.txt b/tests/auto/corelib/io/qprocess/test/CMakeLists.txt
new file mode 100644
index 0000000000..89893583ac
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/test/CMakeLists.txt
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qprocess Test:
+#####################################################################
+
+qt_internal_add_test(tst_qprocess
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../tst_qprocess.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+ Qt::TestPrivate
+)
+
+## Build assorted sub-programs called from the test:
+add_dependencies(tst_qprocess
+ testProcessCrash
+ testProcessEcho
+ testProcessEcho2
+ testProcessEcho3
+ testProcessEnvironment
+ testProcessHang
+ testProcessNormal
+ testProcessOutput
+ testProcessDeadWhileReading
+ testProcessEOF
+ testExitCodes
+ testForwarding
+ testDetached
+ fileWriterProcess
+ testSetWorkingDirectory
+ testSoftExit
+ nospace onespace twospaces
+ testSpaceInName
+)
+if(TARGET Qt::Widgets)
+ add_dependencies(tst_qprocess testGuiProcess)
+endif()
+if(WIN32)
+ add_dependencies(tst_qprocess testProcessEchoGui testSetNamedPipeHandleState)
+endif()
+
+if(UNIX)
+ add_dependencies(tst_qprocess testUnixProcessParameters)
+endif()
diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro
deleted file mode 100644
index 63187c9668..0000000000
--- a/tests/auto/corelib/io/qprocess/test/test.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-CONFIG += testcase
-CONFIG -= debug_and_release_target
-QT = core-private testlib network
-SOURCES = ../tst_qprocess.cpp
-INCLUDEPATH += ../../../../../shared
-HEADERS += ../../../../../shared/emulationdetector.h
-
-TARGET = ../tst_qprocess
-
-win32:TESTDATA += ../testBatFiles/*
-
-include(../qprocess.pri)
-
-mac:CONFIG += insignificant_test # QTBUG-25895 - sometimes hangs
-
-for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}/$${file}"
-
-TEST_HELPER_INSTALLS += \
- ../testProcessSpacesArgs/nospace \
- "../testProcessSpacesArgs/one space" \
- "../testProcessSpacesArgs/two space s" \
- "../test Space In Name/testSpaceInName"
diff --git a/tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt
new file mode 100644
index 0000000000..2439fc67a7
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testDetached Binary:
+#####################################################################
+
+qt_internal_add_executable(testDetached
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testDetached/main.cpp b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
index c10e32d584..9b0b3855a0 100644
--- a/tests/auto/corelib/io/qprocess/testDetached/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
#include <QDebug>
#include <QStringList>
@@ -66,7 +41,7 @@ struct Args
static Args parseArguments(const QStringList &args)
{
Args result;
- if (args.count() < 2) {
+ if (args.size() < 2) {
result.exitCode = 128;
result.errorMessage = "Usage: testDetached [--out-channel={stdout|stderr}] filename.txt\n";
return result;
diff --git a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro b/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro
deleted file mode 100644
index 3d80b668df..0000000000
--- a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-QT = core
-CONFIG += cmdline
-INSTALLS =
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt
new file mode 100644
index 0000000000..bc03f52d00
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testExitCodes Binary:
+#####################################################################
+
+qt_internal_add_executable(testExitCodes
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp b/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
index f681870609..3f186d2272 100644
--- a/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdlib.h>
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro b/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro
deleted file mode 100644
index 5eaf8dc881..0000000000
--- a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES += main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt
new file mode 100644
index 0000000000..77739d2c68
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testForwarding Binary:
+#####################################################################
+
+qt_internal_add_executable(testForwarding
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
+
+add_dependencies(testForwarding testForwardingHelper)
diff --git a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp
index b5d56a1138..774a8622e1 100644
--- a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtCore/QDeadlineTimer>
@@ -38,7 +13,7 @@ static bool waitForDoneFileWritten(const QString &filePath, int msecs = 30000)
{
QDeadlineTimer t(msecs);
do {
- QThread::msleep(250);
+ QThread::sleep(std::chrono::milliseconds{250});
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
continue;
diff --git a/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro b/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro
deleted file mode 100644
index 4d91e0cf36..0000000000
--- a/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt
new file mode 100644
index 0000000000..9f5f064307
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testForwardingHelper Binary:
+#####################################################################
+
+qt_internal_add_executable(testForwardingHelper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp b/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp
index 682ca7346b..4b4d9d4715 100644
--- a/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <fstream>
#include <stdio.h>
@@ -36,8 +11,8 @@ int main(int argc, char *argv[])
return 1;
}
fputs("out data", stdout);
- fputs("err data", stderr);
fflush(stdout);
+ fputs("err data", stderr);
fflush(stderr);
std::ofstream out(argv[1]);
out << "That's all folks!";
diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro b/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt
new file mode 100644
index 0000000000..781f49e515
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testGuiProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(testGuiProcess
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::Widgets
+)
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp b/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
index 98babfacb8..1c65268511 100644
--- a/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro b/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro
deleted file mode 100644
index ef438d6399..0000000000
--- a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += main.cpp
-QT += widgets
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt
new file mode 100644
index 0000000000..2f167899eb
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessCrash Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessCrash
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp b/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
index 262db73d72..a5f1eef88a 100644
--- a/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
@@ -1,40 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-struct Foo
-{
- int i;
-};
+#include "../crasher.h"
+using namespace tst_QProcessCrash;
int main()
{
- *(volatile char*)0 = 0;
- Foo *f = 0;
- return f->i;
+ [[maybe_unused]] // NoCoreDumps may be an empty struct, not a RAII class
+ NoCoreDumps disableCoreDumps;
+ crash();
+ return 0;
}
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro b/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro
deleted file mode 100644
index 640ce4cd09..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-CONFIG -= qt
-
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt
new file mode 100644
index 0000000000..bdd82c6419
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessDeadWhileReading Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessDeadWhileReading
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
index eb780fbc3a..0add9d56de 100644
--- a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
deleted file mode 100644
index c7be60a82d..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt
new file mode 100644
index 0000000000..8914bf181d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEOF Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEOF
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
index 4fb2e29c2d..a0efdbd271 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt
new file mode 100644
index 0000000000..071156f759
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEcho Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEcho
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
index e18e48e516..7b87380900 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro b/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt
new file mode 100644
index 0000000000..9f71b1ebb6
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEcho2 Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEcho2
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
index ce4494b048..b67480e6bb 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro b/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt
new file mode 100644
index 0000000000..badc9ef82d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEcho3 Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEcho3
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
index dfd6e009db..161f8bd547 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro b/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt
new file mode 100644
index 0000000000..43663e62e8
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEchoGui Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEchoGui
+ GUI
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main_win.cpp
+)
+target_link_libraries(testProcessEchoGui PRIVATE user32)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
index abe957c1ea..ab54e4a328 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <windows.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro b/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro
deleted file mode 100644
index 935f43630c..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-win32 {
- SOURCES = main_win.cpp
- LIBS += -luser32
-}
-
-CONFIG -= qt app_bundle
-DESTDIR = ./
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt
new file mode 100644
index 0000000000..9069bbc7c8
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEnvironment Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEnvironment
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
index 9f13f5c00f..dae98c3af6 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
#include <stdlib.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro b/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt
new file mode 100644
index 0000000000..cb6f490c40
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessHang Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessHang
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp b/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp
index cb904134f9..89fcadfb8f 100644
--- a/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro b/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt
new file mode 100644
index 0000000000..7eb6388792
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessNormal Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessNormal
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp b/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
index 4611ed4547..a714713cf2 100644
--- a/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
int main()
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro b/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro
deleted file mode 100644
index 7e1119c117..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-CONFIG -= qt
-
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt
new file mode 100644
index 0000000000..78005b2b93
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessOutput Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessOutput
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp b/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
index 4934708153..08d059e0f9 100644
--- a/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro b/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro
deleted file mode 100644
index 0bbb6b3c0e..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt
new file mode 100644
index 0000000000..5ea7bf53f4
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_executable(nospace
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+
+qt_internal_add_executable(onespace
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+set_target_properties(onespace PROPERTIES OUTPUT_NAME "one space")
+
+qt_internal_add_executable(twospaces
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+set_target_properties(twospaces PROPERTIES OUTPUT_NAME "two space s")
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
index 0d40a9b83c..2c319fa9af 100644
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro
deleted file mode 100644
index 7954a2f74b..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-OBJECTS_DIR = $${OBJECTS_DIR}-nospace
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro
deleted file mode 100644
index 44a365c9a5..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-OBJECTS_DIR = $${OBJECTS_DIR}-onespace
-
-TARGET = "one space"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro
deleted file mode 100644
index bd2db9fb6d..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-OBJECTS_DIR = $${OBJECTS_DIR}-twospaces
-
-TARGET = "two space s"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt
new file mode 100644
index 0000000000..5e532aa017
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSetNamedPipeHandleState Binary:
+#####################################################################
+
+qt_internal_add_executable(testSetNamedPipeHandleState
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+target_link_libraries(testSetNamedPipeHandleState PRIVATE kernel32.lib)
diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp
index 488b03ab57..ace55e9058 100644
--- a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <windows.h>
diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt
new file mode 100644
index 0000000000..f5b9c22c90
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSetWorkingDirectory Binary:
+#####################################################################
+
+qt_internal_add_executable(testSetWorkingDirectory
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
index 37d7deb1ac..c12ca2de7a 100644
--- a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
deleted file mode 100644
index 4d91e0cf36..0000000000
--- a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt
new file mode 100644
index 0000000000..44099dcab1
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSoftExit Binary:
+#####################################################################
+
+qt_internal_add_executable(testSoftExit
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+)
+
+qt_internal_extend_target(testSoftExit CONDITION WIN32
+ SOURCES
+ main_win.cpp
+ LIBRARIES
+ user32
+)
+
+qt_internal_extend_target(testSoftExit CONDITION UNIX
+ SOURCES
+ main_unix.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp b/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
index ed0f16ac17..6d5078e75e 100644
--- a/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <sys/types.h>
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp b/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
index 898029483f..cbef8418e6 100644
--- a/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <windows.h>
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro
deleted file mode 100644
index 2cfcb4794e..0000000000
--- a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-win32 {
- SOURCES = main_win.cpp
- LIBS += -luser32
-}
-unix {
- SOURCES = main_unix.cpp
-}
-
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt
new file mode 100644
index 0000000000..9cc05bfc3d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSpaceInName Binary:
+#####################################################################
+
+qt_internal_add_executable(testSpaceInName
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+set_property(TARGET testSpaceInName PROPERTY
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../test Space In Name")
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp b/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
index 0e2374de06..ca54a6bfde 100644
--- a/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro b/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro
deleted file mode 100644
index 48f28c4c8b..0000000000
--- a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = "../test Space In Name"
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt
new file mode 100644
index 0000000000..9b6c48933c
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 Intel Corporation.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessNormal Binary:
+#####################################################################
+
+qt_internal_add_executable(testUnixProcessParameters
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp
new file mode 100644
index 0000000000..42a173debe
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp
@@ -0,0 +1,109 @@
+// Copyright (C) 2023 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <string_view>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+ if (argc < 2) {
+ printf("Usage: %s command [extra]\nSee source code for commands\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ std::string_view cmd = argv[1];
+ errno = 0;
+
+ if (cmd.size() == 0) {
+ // just checking that we did get here
+ return EXIT_SUCCESS;
+ }
+
+ if (cmd == "reset-ids") {
+ if (getuid() == geteuid() && getgid() == getegid())
+ return EXIT_SUCCESS;
+ fprintf(stderr, "Real: %d %d; Effective: %d %d\n",
+ getuid(), getgid(), geteuid(), getegid());
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "reset-sighand") {
+ bool ok = true;
+
+ // confirm our signal block mask is empty
+ sigset_t set;
+ sigprocmask(SIG_SETMASK, nullptr, &set);
+ for (int signo = 1; signo < NSIG; ++signo) {
+ if (sigismember(&set, signo)) {
+ fprintf(stderr, "'%s' is blocked.\n", strsignal(signo));
+ ok = false;
+ }
+ }
+
+ // confirm SIGUSR1 was not ignored
+ struct sigaction action;
+ sigaction(SIGUSR1, nullptr, &action);
+ if (action.sa_handler != SIG_DFL) {
+ fprintf(stderr, "SIGUSR1 is SIG_IGN\n");
+ ok = false;
+ }
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ if (cmd == "ignore-sigpipe") {
+ // confirm SIGPIPE was ignored
+ struct sigaction action;
+ sigaction(SIGPIPE, nullptr, &action);
+ if (action.sa_handler == SIG_IGN)
+ return EXIT_SUCCESS;
+ fprintf(stderr, "SIGPIPE is SIG_DFL\n");
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "file-descriptors") {
+ int fd = atoi(argv[2]);
+ if (close(fd) < 0 && errno == EBADF)
+ return EXIT_SUCCESS;
+ fprintf(stderr, "%d is a valid file descriptor\n", fd);
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "file-descriptors2") {
+ int fd1 = atoi(argv[2]); // should be open
+ int fd2 = atoi(argv[3]); // should be closed
+ if (close(fd1) < 0)
+ fprintf(stderr, "%d was not a valid file descriptor\n", fd1);
+ if (close(fd2) == 0 || errno != EBADF)
+ fprintf(stderr, "%d is a valid file descriptor\n", fd2);
+ return EXIT_SUCCESS;
+ }
+
+ if (cmd == "noctty") {
+ int fd = open("/dev/tty", O_RDONLY);
+ if (fd == -1)
+ return EXIT_SUCCESS;
+ fprintf(stderr, "Could open /dev/tty\n");
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "setsid") {
+ pid_t pgid = getpgrp();
+ if (pgid == getpid())
+ return EXIT_SUCCESS;
+ fprintf(stderr, "Process group was %d\n", pgid);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(stderr, "Unknown command \"%s\"", cmd.data());
+ return EXIT_FAILURE;
+}
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index e0aa577154..5f35732979 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -1,48 +1,37 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <emulationdetector.h>
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QTestEventLoop>
+#include <QSignalSpy>
+
#include <QtCore/QProcess>
#include <QtCore/QDir>
+#include <QtCore/QElapsedTimer>
#include <QtCore/QFile>
#include <QtCore/QThread>
#include <QtCore/QTemporaryDir>
-#include <QtCore/QRegExp>
+#include <QtCore/QRegularExpression>
#include <QtCore/QDebug>
#include <QtCore/QMetaType>
+#include <QtCore/QScopeGuard>
#include <QtNetwork/QHostInfo>
+
+#include <qplatformdefs.h>
+#ifdef Q_OS_UNIX
+# include <private/qcore_unix_p.h>
+# include <sys/wait.h>
+#endif
+
+#include <QtTest/private/qemulationdetector_p.h>
+
#include <stdlib.h>
-typedef void (QProcess::*QProcessFinishedSignal1)(int);
-typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus);
+#include "crasher.h"
+
+using namespace Qt::StringLiterals;
+
typedef void (QProcess::*QProcessErrorSignal)(QProcess::ProcessError);
class tst_QProcess : public QObject
@@ -58,6 +47,8 @@ private slots:
void getSetCheck();
void constructing();
void simpleStart();
+ void startCommand();
+ void startCommandEmptyString();
void startWithOpen();
void startWithOldOpen();
void execute();
@@ -98,8 +89,11 @@ private slots:
void environmentIsSorted();
void spaceInName();
void setStandardInputFile();
+ void setStandardInputFileFailure();
void setStandardOutputFile_data();
void setStandardOutputFile();
+ void setStandardOutputFileFailure_data() { setStandardOutputFile_data(); }
+ void setStandardOutputFileFailure();
void setStandardOutputFileNullDevice();
void setStandardOutputFileAndWaitForBytesWritten();
void setStandardOutputProcess_data();
@@ -110,6 +104,7 @@ private slots:
void discardUnwantedOutput();
void setWorkingDirectory();
void setNonExistentWorkingDirectory();
+ void detachedSetNonExistentWorkingDirectory();
void exitStatus_data();
void exitStatus();
@@ -124,6 +119,22 @@ private slots:
void nativeArguments();
void createProcessArgumentsModifier();
#endif // Q_OS_WIN
+#if defined(Q_OS_UNIX)
+ void setChildProcessModifier_data();
+ void setChildProcessModifier();
+ void failChildProcessModifier_data() { setChildProcessModifier_data(); }
+ void failChildProcessModifier();
+ void throwInChildProcessModifier();
+ void terminateInChildProcessModifier_data();
+ void terminateInChildProcessModifier();
+ void raiseInChildProcessModifier();
+ void unixProcessParameters_data();
+ void unixProcessParameters();
+ void impossibleUnixProcessParameters_data();
+ void impossibleUnixProcessParameters();
+ void unixProcessParametersAndChildModifier();
+ void unixProcessParametersOtherFileDescriptors();
+#endif
void exitCodeTest();
void systemEnvironment();
void lockupsInStartDetached();
@@ -141,6 +152,8 @@ private slots:
void startStopStartStopBuffers();
void processEventsInAReadyReadSlot_data();
void processEventsInAReadyReadSlot();
+ void startFromCurrentWorkingDir_data();
+ void startFromCurrentWorkingDir();
// keep these at the end, since they use lots of processes and sometimes
// caused obscure failures to occur in tests that followed them (esp. on the Mac)
@@ -159,16 +172,28 @@ protected slots:
void waitForBytesWrittenInABytesWrittenSlotSlot();
private:
+ QString nonExistentFileName = u"/this/file/cant/exist/hopefully"_s;
+
qint64 bytesAvailable;
QTemporaryDir m_temporaryDir;
+ bool haveWorkingVFork = false;
};
void tst_QProcess::initTestCase()
{
+#if defined(QT_ASAN_ENABLED)
+ QSKIP("Skipping QProcess tests under ASAN as they are flaky (QTBUG-109329)");
+#endif
QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString()));
// chdir to our testdata path and execute helper apps relative to that.
QString testdata_dir = QFileInfo(QFINDTESTDATA("testProcessNormal")).absolutePath();
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
+
+#if defined(Q_OS_LINUX) && QT_CONFIG(forkfd_pidfd)
+ // see detect_clone_pidfd_support() in forkfd_linux.c for explanation
+ waitid(/*P_PIDFD*/ idtype_t(3), INT_MAX, NULL, WEXITED|WNOHANG);
+ haveWorkingVFork = (errno == EBADF);
+#endif
}
void tst_QProcess::cleanupTestCase()
@@ -185,13 +210,13 @@ void tst_QProcess::getSetCheck()
{
QProcess obj1;
// ProcessChannelMode QProcess::readChannelMode()
- // void QProcess::setReadChannelMode(ProcessChannelMode)
- obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::SeparateChannels));
- QCOMPARE(QProcess::ProcessChannelMode(QProcess::SeparateChannels), obj1.readChannelMode());
- obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::MergedChannels));
- QCOMPARE(QProcess::ProcessChannelMode(QProcess::MergedChannels), obj1.readChannelMode());
- obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::ForwardedChannels));
- QCOMPARE(QProcess::ProcessChannelMode(QProcess::ForwardedChannels), obj1.readChannelMode());
+ // void QProcess::setProcessChannelMode(ProcessChannelMode)
+ obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::SeparateChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::SeparateChannels), obj1.processChannelMode());
+ obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::MergedChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::MergedChannels), obj1.processChannelMode());
+ obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::ForwardedChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::ForwardedChannels), obj1.processChannelMode());
// ProcessChannel QProcess::readChannel()
// void QProcess::setReadChannel(ProcessChannel)
@@ -209,7 +234,7 @@ void tst_QProcess::constructing()
QCOMPARE(process.environment(), QStringList());
QCOMPARE(process.error(), QProcess::UnknownError);
QCOMPARE(process.state(), QProcess::NotRunning);
- QCOMPARE(process.pid(), Q_PID(0));
+ QCOMPARE(process.processId(), 0);
QCOMPARE(process.readAllStandardOutput(), QByteArray());
QCOMPARE(process.readAllStandardError(), QByteArray());
QCOMPARE(process.canReadLine(), false);
@@ -255,12 +280,45 @@ void tst_QProcess::simpleStart()
process.reset();
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(0).at(0)), QProcess::Starting);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(1).at(0)), QProcess::Running);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(2).at(0)), QProcess::NotRunning);
}
+void tst_QProcess::startCommand()
+{
+ QProcess process;
+ process.startCommand("testProcessSpacesArgs/nospace foo \"b a r\" baz");
+ QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(), qPrintable(process.errorString()));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QCOMPARE(process.exitCode(), 0);
+ QByteArray actual = process.readAll();
+ actual.remove(0, actual.indexOf('|') + 1);
+ QByteArray expected = "foo|b a r|baz";
+ QCOMPARE(actual, expected);
+}
+
+void tst_QProcess::startCommandEmptyString()
+{
+ static const char warningMsg[] =
+ "QProcess::startCommand: empty or whitespace-only command was provided";
+ QProcess process;
+
+ QTest::ignoreMessage(QtWarningMsg, warningMsg);
+ process.startCommand("");
+ QVERIFY(!process.waitForStarted());
+
+ QTest::ignoreMessage(QtWarningMsg, warningMsg);
+ process.startCommand(" ");
+ QVERIFY(!process.waitForStarted());
+
+ QTest::ignoreMessage(QtWarningMsg, warningMsg);
+ process.startCommand("\t\n");
+ QVERIFY(!process.waitForStarted());
+}
+
void tst_QProcess::startWithOpen()
{
QProcess p;
@@ -314,9 +372,7 @@ void tst_QProcess::readFromProcess()
{
QProcess *process = qobject_cast<QProcess *>(sender());
QVERIFY(process);
- int lines = 0;
while (process->canReadLine()) {
- ++lines;
process->readLine();
}
}
@@ -334,30 +390,24 @@ void tst_QProcess::crashTest()
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
QSignalSpy spy(process.data(), &QProcess::errorOccurred);
- QSignalSpy spy2(process.data(), static_cast<QProcessErrorSignal>(&QProcess::error));
- QSignalSpy spy3(process.data(), static_cast<QProcessFinishedSignal2>(&QProcess::finished));
-
+ QSignalSpy spy2(process.data(), &QProcess::finished);
QVERIFY(spy.isValid());
QVERIFY(spy2.isValid());
- QVERIFY(spy3.isValid());
QVERIFY(process->waitForFinished(30000));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy2.at(0).at(0).constData()), QProcess::Crashed);
-
- QCOMPARE(spy3.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy3.at(0).at(1).constData()), QProcess::CrashExit);
+ QCOMPARE(spy2.size(), 1);
+ QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
QCOMPARE(process->exitStatus(), QProcess::CrashExit);
// delete process;
process.reset();
- QCOMPARE(stateSpy.count(), 3);
+ QCOMPARE(stateSpy.size(), 3);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(0).at(0)), QProcess::Starting);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(1).at(0)), QProcess::Running);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(2).at(0)), QProcess::NotRunning);
@@ -373,22 +423,21 @@ void tst_QProcess::crashTest2()
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
QSignalSpy spy(&process, static_cast<QProcessErrorSignal>(&QProcess::errorOccurred));
- QSignalSpy spy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy spy2(&process, &QProcess::finished);
QVERIFY(spy.isValid());
QVERIFY(spy2.isValid());
- QObject::connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &tst_QProcess::exitLoopSlot);
+ QObject::connect(&process, &QProcess::finished, this, &tst_QProcess::exitLoopSlot);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout())
QFAIL("Failed to detect crash : operation timed out");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.size(), 1);
QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
QCOMPARE(process.exitStatus(), QProcess::CrashExit);
@@ -420,7 +469,7 @@ void tst_QProcess::echoTest()
process.write(input);
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
do {
QVERIFY(process.isOpen());
@@ -479,7 +528,7 @@ void tst_QProcess::echoTest2()
QVERIFY(spy1.isValid());
QVERIFY(spy2.isValid());
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
forever {
QTestEventLoop::instance().enterLoop(1);
@@ -494,9 +543,9 @@ void tst_QProcess::echoTest2()
break;
}
- QVERIFY(spy0.count() > 0);
- QVERIFY(spy1.count() > 0);
- QVERIFY(spy2.count() > 0);
+ QVERIFY(spy0.size() > 0);
+ QVERIFY(spy1.size() > 0);
+ QVERIFY(spy2.size() > 0);
QCOMPARE(process.readAllStandardOutput(), QByteArray("Hello"));
QCOMPARE(process.readAllStandardError(), QByteArray("Hello"));
@@ -597,8 +646,8 @@ void tst_QProcess::exitStatus()
QFETCH(QStringList, processList);
QFETCH(QList<QProcess::ExitStatus>, exitStatus);
- QCOMPARE(exitStatus.count(), processList.count());
- for (int i = 0; i < processList.count(); ++i) {
+ QCOMPARE(exitStatus.size(), processList.size());
+ for (int i = 0; i < processList.size(); ++i) {
process.start(processList.at(i));
QVERIFY(process.waitForStarted(5000));
QVERIFY(process.waitForFinished(30000));
@@ -644,19 +693,15 @@ void tst_QProcess::readTimeoutAndThenCrash()
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
QSignalSpy spy(&process, &QProcess::errorOccurred);
- QSignalSpy spy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
QVERIFY(spy.isValid());
- QVERIFY(spy2.isValid());
process.kill();
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.state(), QProcess::NotRunning);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy2.at(0).at(0).constData()), QProcess::Crashed);
}
void tst_QProcess::waitForFinished()
@@ -696,20 +741,18 @@ void tst_QProcess::deadWhileReading()
void tst_QProcess::restartProcessDeadlock()
{
-
// The purpose of this test is to detect whether restarting a
// process in the finished() connected slot causes a deadlock
// because of the way QProcessManager uses its locks.
QProcess process;
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &tst_QProcess::restartProcess);
+ connect(&process, &QProcess::finished, this, &tst_QProcess::restartProcess);
process.start("testProcessEcho/testProcessEcho");
QCOMPARE(process.write("", 1), qlonglong(1));
QVERIFY(process.waitForFinished(5000));
- QObject::disconnect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished), nullptr, nullptr);
+ QObject::disconnect(&process, &QProcess::finished, nullptr, nullptr);
QCOMPARE(process.write("", 1), qlonglong(1));
QVERIFY(process.waitForFinished(5000));
@@ -834,7 +877,7 @@ void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives()
proc.start("testProcessEcho/testProcessEcho");
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
proc.write("A");
@@ -842,7 +885,7 @@ void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives()
if (QTestEventLoop::instance().timeout())
QFAIL("Operation timed out");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QTestEventLoop::instance().enterLoop(1);
QVERIFY(QTestEventLoop::instance().timeout());
@@ -908,12 +951,11 @@ public:
SoftExitProcess(int n) : waitedForFinished(false), n(n), killing(false)
{
- connect(this, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- this, &SoftExitProcess::finishedSlot);
+ connect(this, &QProcess::finished, this, &SoftExitProcess::finishedSlot);
switch (n) {
case 0:
- setReadChannelMode(QProcess::MergedChannels);
+ setProcessChannelMode(QProcess::MergedChannels);
connect(this, &QIODevice::readyRead, this, &SoftExitProcess::terminateSlot);
break;
case 1:
@@ -929,7 +971,7 @@ public:
this, &SoftExitProcess::terminateSlot);
break;
case 4:
- setReadChannelMode(QProcess::MergedChannels);
+ setProcessChannelMode(QProcess::MergedChannels);
connect(this, SIGNAL(channelReadyRead(int)), this, SLOT(terminateSlot()));
break;
default:
@@ -1025,13 +1067,23 @@ void tst_QProcess::softExitInSlots()
void tst_QProcess::mergedChannels()
{
QProcess process;
- process.setReadChannelMode(QProcess::MergedChannels);
- QCOMPARE(process.readChannelMode(), QProcess::MergedChannels);
+ process.setProcessChannelMode(QProcess::MergedChannels);
+ QCOMPARE(process.processChannelMode(), QProcess::MergedChannels);
process.start("testProcessEcho2/testProcessEcho2");
QVERIFY(process.waitForStarted(5000));
+ {
+ QCOMPARE(process.write("abc"), qlonglong(3));
+ while (process.bytesAvailable() < 6)
+ QVERIFY(process.waitForReadyRead(5000));
+ QCOMPARE(process.readAllStandardOutput(), QByteArray("aabbcc"));
+ QTest::ignoreMessage(QtWarningMsg,
+ "QProcess::readAllStandardError: Called with MergedChannels");
+ QCOMPARE(process.readAllStandardError(), QByteArray());
+ }
+
for (int i = 0; i < 100; ++i) {
QCOMPARE(process.write("abc"), qlonglong(3));
while (process.bytesAvailable() < 6)
@@ -1077,6 +1129,10 @@ void tst_QProcess::forwardedChannels_data()
<< true
<< int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel)
<< QByteArray("out data") << QByteArray("err data");
+ QTest::newRow("detached-merged-forwarding")
+ << true
+ << int(QProcess::MergedChannels) << int(QProcess::ManagedInputChannel)
+ << QByteArray("out data" "err data") << QByteArray();
}
void tst_QProcess::forwardedChannels()
@@ -1094,9 +1150,8 @@ void tst_QProcess::forwardedChannels()
QVERIFY(process.waitForStarted(5000));
QCOMPARE(process.write("input"), 5);
process.closeWriteChannel();
- QVERIFY(process.waitForFinished(5000));
+ QVERIFY(process.waitForFinished(40000)); // testForwarding has a 30s wait
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
- QCOMPARE(process.exitCode(), 0);
const char *err;
switch (process.exitCode()) {
case 0: err = "ok"; break;
@@ -1149,13 +1204,12 @@ public:
}
protected:
- inline void run()
+ inline void run() override
{
exitCode = 90210;
QProcess process;
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &TestThread::catchExitCode, Qt::DirectConnection);
+ connect(&process, &QProcess::finished, this, &TestThread::catchExitCode, Qt::DirectConnection);
process.start("testProcessEcho/testProcessEcho");
@@ -1186,8 +1240,13 @@ void tst_QProcess::processInAThread()
void tst_QProcess::processesInMultipleThreads()
{
- if (EmulationDetector::isRunningArmOnX86())
- QSKIP("Flakily hangs in QEMU. QTBUG-67760");
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Test is too slow to run on emulator");
+
+#if defined(Q_OS_QNX)
+ QSKIP("QNX: Large amount of threads is unstable and do not finish in given time");
+#endif
+
for (int i = 0; i < 10; ++i) {
// run from 1 to 10 threads, but run at least some tests
// with more threads than the ideal
@@ -1195,18 +1254,16 @@ void tst_QProcess::processesInMultipleThreads()
if (i > 7)
threadCount = qMax(threadCount, QThread::idealThreadCount() + 2);
- QVector<TestThread *> threads(threadCount);
+ QList<TestThread *> threads(threadCount);
+ QScopeGuard cleanup([&threads]() { qDeleteAll(threads); });
for (int j = 0; j < threadCount; ++j)
threads[j] = new TestThread;
for (int j = 0; j < threadCount; ++j)
threads[j]->start();
- for (int j = 0; j < threadCount; ++j) {
+ for (int j = 0; j < threadCount; ++j)
QVERIFY(threads[j]->wait(10000));
- }
- for (int j = 0; j < threadCount; ++j) {
+ for (int j = 0; j < threadCount; ++j)
QCOMPARE(threads[j]->code(), 0);
- }
- qDeleteAll(threads);
}
}
@@ -1228,8 +1285,7 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlot()
{
QProcess process;
connect(&process, &QIODevice::readyRead, this, &tst_QProcess::waitForReadyReadInAReadyReadSlotSlot);
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &tst_QProcess::exitLoopSlot);
+ connect(&process, &QProcess::finished, this, &tst_QProcess::exitLoopSlot);
bytesAvailable = 0;
process.start("testProcessEcho/testProcessEcho");
@@ -1241,13 +1297,13 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlot()
QTestEventLoop::instance().enterLoop(30);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
process.disconnect();
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
- QVERIFY(process.bytesAvailable() > bytesAvailable);
+ QVERIFY(process.bytesAvailable() >= bytesAvailable);
}
void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot()
@@ -1257,6 +1313,8 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot()
bytesAvailable = process->bytesAvailable();
process->write("bar", 4);
QVERIFY(process->waitForReadyRead(5000));
+ QVERIFY(process->bytesAvailable() > bytesAvailable);
+ bytesAvailable = process->bytesAvailable();
QTestEventLoop::instance().exitLoop();
}
@@ -1275,7 +1333,7 @@ void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot()
QTestEventLoop::instance().enterLoop(30);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
process.write("", 1);
process.disconnect();
QVERIFY(process.waitForFinished());
@@ -1349,6 +1407,9 @@ void tst_QProcess::spaceArgsTest()
QFETCH(QStringList, args);
QFETCH(QString, stringArgs);
+ auto splitString = QProcess::splitCommand(stringArgs);
+ QCOMPARE(args, splitString);
+
QStringList programs;
programs << QString::fromLatin1("testProcessSpacesArgs/nospace")
<< QString::fromLatin1("testProcessSpacesArgs/one space")
@@ -1375,28 +1436,6 @@ void tst_QProcess::spaceArgsTest()
actual.removeFirst();
QCOMPARE(actual, args);
-
- if (program.contains(QLatin1Char(' ')))
- program = QLatin1Char('"') + program + QLatin1Char('"');
-
- if (!stringArgs.isEmpty())
- program += QLatin1Char(' ') + stringArgs;
-
- errorMessage.clear();
- process.start(program);
- started = process.waitForStarted(5000);
- if (!started)
- errorMessage = startFailMessage(program, process);
-
- QVERIFY2(started, errorMessage.constData());
- QVERIFY(process.waitForFinished(5000));
-
- actual = QString::fromLatin1(process.readAll()).split("|");
- QVERIFY(!actual.isEmpty());
- // not interested in the program name, it might be different.
- actual.removeFirst();
-
- QCOMPARE(actual, args);
}
}
@@ -1447,11 +1486,484 @@ void tst_QProcess::createProcessArgumentsModifier()
}
#endif // Q_OS_WIN
+#ifdef Q_OS_UNIX
+static constexpr int sigs[] = { SIGABRT, SIGILL, SIGSEGV };
+struct DisableCrashLogger
+{
+ // disable core dumps too
+ tst_QProcessCrash::NoCoreDumps disableCoreDumps {};
+ std::array<struct sigaction, std::size(sigs)> oldhandlers;
+ DisableCrashLogger()
+ {
+ struct sigaction def = {};
+ def.sa_handler = SIG_DFL;
+ for (uint i = 0; i < std::size(sigs); ++i)
+ sigaction(sigs[i], &def, &oldhandlers[i]);
+ }
+ ~DisableCrashLogger()
+ {
+ // restore them
+ for (uint i = 0; i < std::size(sigs); ++i)
+ sigaction(sigs[i], &oldhandlers[i], nullptr);
+ }
+};
+
+QT_BEGIN_NAMESPACE
+Q_AUTOTEST_EXPORT bool _qprocessUsingVfork() noexcept;
+QT_END_NAMESPACE
+static constexpr char messageFromChildProcess[] = "Message from the child process";
+static_assert(std::char_traits<char>::length(messageFromChildProcess) <= PIPE_BUF);
+static void childProcessModifier(int fd)
+{
+ QT_WRITE(fd, messageFromChildProcess, strlen(messageFromChildProcess));
+ QT_CLOSE(fd);
+}
+
+void tst_QProcess::setChildProcessModifier_data()
+{
+ QTest::addColumn<bool>("detached");
+ QTest::addColumn<bool>("useVfork");
+ QTest::newRow("normal") << false << false;
+ QTest::newRow("detached") << true << false;
+
+#ifdef QT_BUILD_INTERNAL
+ if (_qprocessUsingVfork()) {
+ QTest::newRow("normal-vfork") << false << true;
+ QTest::newRow("detached-vfork") << true << true;
+ }
+#endif
+}
+
+void tst_QProcess::setChildProcessModifier()
+{
+ QFETCH(bool, detached);
+ QFETCH(bool, useVfork);
+ int pipes[2] = { -1 , -1 };
+ QVERIFY(qt_safe_pipe(pipes) == 0);
+
+ QProcess process;
+ if (useVfork)
+ process.setUnixProcessParameters(QProcess::UnixProcessFlag::UseVFork);
+ process.setChildProcessModifier([pipes]() {
+ ::childProcessModifier(pipes[1]);
+ });
+ process.setProgram("testProcessNormal/testProcessNormal");
+ if (detached) {
+ process.startDetached();
+ } else {
+ process.start("testProcessNormal/testProcessNormal");
+ if (process.state() != QProcess::Starting)
+ QCOMPARE(process.state(), QProcess::Running);
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QCOMPARE(process.exitCode(), 0);
+ }
+
+ char buf[sizeof messageFromChildProcess] = {};
+ qt_safe_close(pipes[1]);
+ QCOMPARE(qt_safe_read(pipes[0], buf, sizeof(buf)), qint64(sizeof(messageFromChildProcess)) - 1);
+ QCOMPARE(buf, messageFromChildProcess);
+ qt_safe_close(pipes[0]);
+}
+
+void tst_QProcess::failChildProcessModifier()
+{
+ static const char failureMsg[] =
+ "Some error message from the child process would go here if this were a "
+ "real application";
+ static_assert(sizeof(failureMsg) < _POSIX_PIPE_BUF / 2,
+ "Implementation detail: the length of the message is limited");
+
+ QFETCH(bool, detached);
+ QFETCH(bool, useVfork);
+
+ QProcess process;
+ if (useVfork)
+ process.setUnixProcessParameters(QProcess::UnixProcessFlag::UseVFork);
+ process.setChildProcessModifier([&process]() {
+ process.failChildProcessModifier(failureMsg, EPERM);
+ });
+ process.setProgram("testProcessNormal/testProcessNormal");
+
+ if (detached) {
+ qint64 pid;
+ QVERIFY(!process.startDetached(&pid));
+ QCOMPARE(pid, -1);
+ } else {
+ process.start();
+ QVERIFY(!process.waitForStarted(5000));
+ }
+
+ QString errMsg = process.errorString();
+ QVERIFY2(errMsg.startsWith("Child process modifier reported error: "_L1 + failureMsg),
+ qPrintable(errMsg));
+ QVERIFY2(errMsg.endsWith(strerror(EPERM)), qPrintable(errMsg));
+}
+
+void tst_QProcess::throwInChildProcessModifier()
+{
+#ifndef __cpp_exceptions
+ Q_SKIP("Exceptions disabled.");
+#else
+ static constexpr char What[] = "tst_QProcess::throwInChildProcessModifier()::MyException";
+ struct MyException : std::exception {
+ const char *what() const noexcept override { return What; }
+ };
+ QProcess process;
+ process.setChildProcessModifier([]() {
+ throw MyException();
+ });
+ process.setProgram("testProcessNormal/testProcessNormal");
+
+ process.start();
+ QVERIFY(!process.waitForStarted(5000));
+ QCOMPARE(process.state(), QProcess::NotRunning);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QVERIFY2(process.errorString().contains("Child process modifier threw an exception"),
+ qPrintable(process.errorString()));
+ QVERIFY2(process.errorString().contains(What),
+ qPrintable(process.errorString()));
+
+ // try again, to ensure QProcess internal state wasn't corrupted
+ process.start();
+ QVERIFY(!process.waitForStarted(5000));
+ QCOMPARE(process.state(), QProcess::NotRunning);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QVERIFY2(process.errorString().contains("Child process modifier threw an exception"),
+ qPrintable(process.errorString()));
+ QVERIFY2(process.errorString().contains(What),
+ qPrintable(process.errorString()));
+#endif
+}
+
+void tst_QProcess::terminateInChildProcessModifier_data()
+{
+ using F = std::function<void(void)>;
+ QTest::addColumn<F>("function");
+ QTest::addColumn<QProcess::ExitStatus>("exitStatus");
+ QTest::addColumn<bool>("stderrIsEmpty");
+
+ QTest::newRow("_exit") << F([]() { _exit(0); }) << QProcess::NormalExit << true;
+ QTest::newRow("abort") << F(std::abort) << QProcess::CrashExit << true;
+ QTest::newRow("sigkill") << F([]() { raise(SIGKILL); }) << QProcess::CrashExit << true;
+ QTest::newRow("terminate") << F(std::terminate) << QProcess::CrashExit
+ << (std::get_terminate() == std::abort);
+ QTest::newRow("crash") << F([]() { tst_QProcessCrash::crash(); }) << QProcess::CrashExit << true;
+}
+
+void tst_QProcess::terminateInChildProcessModifier()
+{
+ QFETCH(std::function<void(void)>, function);
+ QFETCH(QProcess::ExitStatus, exitStatus);
+ QFETCH(bool, stderrIsEmpty);
+
+ // temporarily disable QTest's crash logger
+ DisableCrashLogger disableCrashLogging;
+
+ // testForwardingHelper prints to both stdout and stderr, so if we fail to
+ // fail we should be able to tell too
+ QProcess process;
+ process.setChildProcessModifier(function);
+ process.setProgram("testForwardingHelper/testForwardingHelper");
+ process.setArguments({ "/dev/null" });
+
+ // temporarily disable QTest's crash logger while starting the child process
+ {
+ DisableCrashLogger d;
+ process.start();
+ }
+
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
+ QCOMPARE(process.exitStatus(), exitStatus);
+ QCOMPARE(process.readAllStandardOutput(), QByteArray());
+
+ // some environments print extra stuff to stderr when we crash
+#ifndef Q_OS_QNX
+ if (!QTestPrivate::isRunningArmOnX86()) {
+ QByteArray standardError = process.readAllStandardError();
+ QVERIFY2(standardError.isEmpty() == stderrIsEmpty,
+ "stderr was: " + standardError);
+ }
+#endif
+}
+
+void tst_QProcess::raiseInChildProcessModifier()
+{
+#ifdef QT_BUILD_INTERNAL
+ // This is similar to the above, but knowing that raise() doesn't unblock
+ // signals, unlike abort(), this implies that
+ // 1) the raise() in the child modifier will not run our handler
+ // 2) the write() to stdout after that will run
+ // 3) QProcess resets the signal handlers to the defaults, then unblocks
+ // 4) at that point, the signal will be delivered to the child, but our
+ // handler is no longer active so there'll be no write() to stderr
+ //
+ // Note for maintenance: if in the future this test causes the parent
+ // process to die with SIGUSR1, it means the C library is buggy and is
+ // using a cached PID in the child process after vfork().
+ if (!QT_PREPEND_NAMESPACE(_qprocessUsingVfork()))
+ QSKIP("QProcess will only block Unix signals when using vfork()");
+
+ // we use SIGUSR1 because QtTest doesn't log it and because its default
+ // action is termination, not core dumping
+ struct SigUsr1Handler {
+ SigUsr1Handler()
+ {
+ struct sigaction sa = {};
+ sa.sa_flags = SA_RESETHAND;
+ sa.sa_handler = [](int) {
+ static const char msg[] = "SIGUSR1 handler was run";
+ write(STDERR_FILENO, msg, strlen(msg));
+ raise(SIGUSR1); // re-raise
+ };
+ sigaction(SIGUSR1, &sa, nullptr);
+ }
+ ~SigUsr1Handler() { restore(); }
+ static void restore() { signal(SIGUSR1, SIG_DFL); }
+ } sigUsr1Handler;
+
+ QProcess process;
+
+ // QProcess will block signals with UseVFork
+ process.setUnixProcessParameters(QProcess::UnixProcessFlag::UseVFork |
+ QProcess::UnixProcessFlag::ResetSignalHandlers);
+ process.setChildProcessModifier([]() {
+ raise(SIGUSR1);
+ ::childProcessModifier(STDOUT_FILENO);
+ });
+
+ // testForwardingHelper prints to both stdout and stderr, so if we fail to
+ // fail we should be able to tell too
+ process.setProgram("testForwardingHelper/testForwardingHelper");
+ process.setArguments({ "/dev/null" });
+
+ process.start();
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
+ QCOMPARE(process.error(), QProcess::Crashed);
+
+ // ensure the write() from the child modifier DID get run
+ QCOMPARE(process.readAllStandardOutput(), messageFromChildProcess);
+
+ // some environments print extra stuff to stderr when we crash
+ if (!QTestPrivate::isRunningArmOnX86()) {
+ // and write() from the SIGUSR1 handler did not
+ QCOMPARE(process.readAllStandardError(), QByteArray());
+ }
+#else
+ QSKIP("Requires QT_BUILD_INTERNAL symbols");
+#endif
+}
+
+void tst_QProcess::unixProcessParameters_data()
+{
+ QTest::addColumn<QProcess::UnixProcessParameters>("params");
+ QTest::addColumn<QString>("cmd");
+ QTest::newRow("defaults") << QProcess::UnixProcessParameters{} << QString();
+
+ auto addRow = [](const char *cmd, QProcess::UnixProcessFlags flags) {
+ QProcess::UnixProcessParameters params = {};
+ params.flags = flags;
+ QTest::addRow("%s", cmd) << params << cmd;
+ };
+ using P = QProcess::UnixProcessFlag;
+ addRow("reset-sighand", P::ResetSignalHandlers);
+ addRow("ignore-sigpipe", P::IgnoreSigPipe);
+ addRow("file-descriptors", P::CloseFileDescriptors);
+ addRow("setsid", P::CreateNewSession);
+ addRow("reset-ids", P::ResetIds);
+
+ // On FreeBSD, we need to be session leader to disconnect from the CTTY
+ addRow("noctty", P::DisconnectControllingTerminal | P::CreateNewSession);
+}
+
+void tst_QProcess::unixProcessParameters()
+{
+ QFETCH(QProcess::UnixProcessParameters, params);
+ QFETCH(QString, cmd);
+
+ // set up a few things
+ struct Scope {
+ int devnull;
+ struct sigaction old_sigusr1, old_sigpipe;
+ Scope()
+ {
+ int fd = open("/dev/null", O_RDONLY);
+ devnull = fcntl(fd, F_DUPFD, 100);
+ close(fd);
+
+ // we ignore SIGUSR1 and reset SIGPIPE to Terminate
+ struct sigaction act = {};
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = SIG_IGN;
+ sigaction(SIGUSR1, &act, &old_sigusr1);
+ act.sa_handler = SIG_DFL;
+ sigaction(SIGPIPE, &act, &old_sigpipe);
+
+ // and we block SIGUSR2
+ sigset_t *set = &act.sa_mask; // reuse this sigset_t
+ sigaddset(set, SIGUSR2);
+ sigprocmask(SIG_BLOCK, set, nullptr);
+ }
+ ~Scope()
+ {
+ if (devnull != -1)
+ dismiss();
+ }
+ void dismiss()
+ {
+ close(devnull);
+ sigaction(SIGUSR1, &old_sigusr1, nullptr);
+ sigaction(SIGPIPE, &old_sigpipe, nullptr);
+ devnull = -1;
+
+ sigset_t *set = &old_sigusr1.sa_mask; // reuse this sigset_t
+ sigaddset(set, SIGUSR2);
+ sigprocmask(SIG_BLOCK, set, nullptr);
+ }
+ } scope;
+
+ if (params.flags & QProcess::UnixProcessFlag::ResetIds) {
+ if (getuid() == geteuid() && getgid() == getegid())
+ qInfo("Process has identical real and effective IDs; this test will do nothing");
+ }
+
+ if (params.flags & QProcess::UnixProcessFlag::DisconnectControllingTerminal) {
+ if (int fd = open("/dev/tty", O_RDONLY); fd < 0) {
+ qInfo("Process has no controlling terminal; this test will do nothing");
+ close(fd);
+ }
+ }
+
+ QProcess process;
+ process.setUnixProcessParameters(params);
+ process.setStandardInputFile(QProcess::nullDevice()); // so we can't mess with SIGPIPE
+ process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
+ process.setArguments({ cmd, QString::number(scope.devnull) });
+ process.start();
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY(process.waitForFinished(5000));
+
+ const QString stdErr = process.readAllStandardError();
+ QCOMPARE(stdErr, QString());
+ QCOMPARE(process.readAll(), QString());
+ QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+}
+
+void tst_QProcess::impossibleUnixProcessParameters_data()
+{
+ using P = QProcess::UnixProcessParameters;
+ QTest::addColumn<P>("params");
+ QTest::newRow("setsid") << P{ QProcess::UnixProcessFlag::CreateNewSession };
+}
+
+void tst_QProcess::impossibleUnixProcessParameters()
+{
+ QFETCH(QProcess::UnixProcessParameters, params);
+
+ QProcess process;
+ if (params.flags & QProcess::UnixProcessFlag::CreateNewSession) {
+ process.setChildProcessModifier([]() {
+ // double setsid() should cause the second to fail
+ setsid();
+ });
+ }
+ process.setUnixProcessParameters(params);
+ process.start("testProcessNormal/testProcessNormal");
+
+ QVERIFY(!process.waitForStarted(5000));
+ qDebug() << process.errorString();
+}
+
+void tst_QProcess::unixProcessParametersAndChildModifier()
+{
+ static constexpr char message[] = "Message from the handler function\n";
+ static_assert(std::char_traits<char>::length(message) <= PIPE_BUF);
+ QProcess process;
+ QAtomicInt vforkControl;
+ int pipes[2];
+
+ pid_t oldpgid = getpgrp();
+
+ QVERIFY2(pipe(pipes) == 0, qPrintable(qt_error_string()));
+ auto pipeGuard0 = qScopeGuard([=] { close(pipes[0]); });
+ {
+ auto pipeGuard1 = qScopeGuard([=] { close(pipes[1]); });
+
+ // verify that our modifier runs before the parameters are applied
+ process.setChildProcessModifier([=, &vforkControl] {
+ const char *pgidmsg = "PGID mismatch. ";
+ if (getpgrp() != oldpgid)
+ write(pipes[1], pgidmsg, strlen(pgidmsg));
+ write(pipes[1], message, strlen(message));
+ vforkControl.storeRelaxed(1);
+ });
+ auto flags = QProcess::UnixProcessFlag::CloseFileDescriptors |
+ QProcess::UnixProcessFlag::CreateNewSession |
+ QProcess::UnixProcessFlag::UseVFork;
+ process.setUnixProcessParameters({ flags });
+ process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
+ process.setArguments({ "file-descriptors", QString::number(pipes[1]) });
+ process.start();
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ } // closes the writing end of the pipe
+
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.readAllStandardError(), QString());
+ QCOMPARE(process.readAll(), QString());
+
+ char buf[2 * sizeof(message)];
+ int r = read(pipes[0], buf, sizeof(buf));
+ QVERIFY2(r >= 0, qPrintable(qt_error_string()));
+ QCOMPARE(QByteArrayView(buf, r), message);
+
+ if (haveWorkingVFork)
+ QVERIFY2(vforkControl.loadRelaxed(), "QProcess doesn't appear to have used vfork()");
+}
+
+void tst_QProcess::unixProcessParametersOtherFileDescriptors()
+{
+ constexpr int TargetFileDescriptor = 3;
+ int fd1 = open("/dev/null", O_RDONLY);
+ int devnull = fcntl(fd1, F_DUPFD, 100); // instead of F_DUPFD_CLOEXEC
+ close(fd1);
+
+ auto closeFds = qScopeGuard([&] {
+ close(devnull);
+ });
+
+ QProcess process;
+ QProcess::UnixProcessParameters params;
+ params.flags = QProcess::UnixProcessFlag::CloseFileDescriptors
+ | QProcess::UnixProcessFlag::UseVFork;
+ params.lowestFileDescriptorToClose = 4;
+ process.setUnixProcessParameters(params);
+ process.setChildProcessModifier([devnull, &process]() {
+ if (dup2(devnull, TargetFileDescriptor) != TargetFileDescriptor)
+ process.failChildProcessModifier("dup2", errno);
+ });
+ process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
+ process.setArguments({ "file-descriptors2", QString::number(TargetFileDescriptor),
+ QString::number(devnull) });
+ process.start();
+
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.readAllStandardError(), QString());
+ QCOMPARE(process.readAll(), QString());
+ QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+}
+#endif
+
void tst_QProcess::exitCodeTest()
{
for (int i = 0; i < 255; ++i) {
QProcess process;
- process.start("testExitCodes/testExitCodes " + QString::number(i));
+ process.start("testExitCodes/testExitCodes", {QString::number(i)});
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitCode(), i);
QCOMPARE(process.error(), QProcess::UnknownError);
@@ -1467,21 +1979,16 @@ void tst_QProcess::failToStart()
QProcess process;
QSignalSpy stateSpy(&process, &QProcess::stateChanged);
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
-
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(stateSpy.isValid());
QVERIFY(errorSpy.isValid());
- QVERIFY(errorSpy2.isValid());
QVERIFY(finishedSpy.isValid());
- QVERIFY(finishedSpy2.isValid());
// OS X and HP-UX have a really low default process limit (~100), so spawning
// to many processes here will cause test failures later on.
#if defined Q_OS_HPUX
const int attempts = 15;
-#elif defined Q_OS_MAC
+#elif defined Q_OS_DARWIN
const int attempts = 15;
#else
const int attempts = 50;
@@ -1489,8 +1996,7 @@ void tst_QProcess::failToStart()
for (int j = 0; j < 8; ++j) {
for (int i = 0; i < attempts; ++i) {
- QCOMPARE(errorSpy.count(), j * attempts + i);
- QCOMPARE(errorSpy2.count(), j * attempts + i);
+ QCOMPARE(errorSpy.size(), j * attempts + i);
process.start("/blurp");
switch (j) {
@@ -1514,14 +2020,12 @@ void tst_QProcess::failToStart()
}
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(errorSpy.count(), j * attempts + i + 1);
- QCOMPARE(errorSpy2.count(), j * attempts + i + 1);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(finishedSpy2.count(), 0);
+ QCOMPARE(errorSpy.size(), j * attempts + i + 1);
+ QCOMPARE(finishedSpy.size(), 0);
int it = j * attempts + i + 1;
- QCOMPARE(stateSpy.count(), it * 2);
+ QCOMPARE(stateSpy.size(), it * 2);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(it * 2 - 2).at(0)), QProcess::Starting);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(it * 2 - 1).at(0)), QProcess::NotRunning);
}
@@ -1536,24 +2040,17 @@ void tst_QProcess::failToStartWithWait()
QProcess process;
QEventLoop loop;
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
-
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(errorSpy.isValid());
- QVERIFY(errorSpy2.isValid());
QVERIFY(finishedSpy.isValid());
- QVERIFY(finishedSpy2.isValid());
for (int i = 0; i < 50; ++i) {
process.start("/blurp", QStringList() << "-v" << "-debug");
process.waitForStarted();
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(errorSpy.count(), i + 1);
- QCOMPARE(errorSpy2.count(), i + 1);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(finishedSpy2.count(), 0);
+ QCOMPARE(errorSpy.size(), i + 1);
+ QCOMPARE(finishedSpy.size(), 0);
}
}
@@ -1565,14 +2062,9 @@ void tst_QProcess::failToStartWithEventLoop()
QProcess process;
QEventLoop loop;
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
-
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(errorSpy.isValid());
- QVERIFY(errorSpy2.isValid());
QVERIFY(finishedSpy.isValid());
- QVERIFY(finishedSpy2.isValid());
// The error signal may be emitted before start() returns
connect(&process, &QProcess::errorOccurred, &loop, &QEventLoop::quit, Qt::QueuedConnection);
@@ -1584,10 +2076,8 @@ void tst_QProcess::failToStartWithEventLoop()
loop.exec();
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(errorSpy.count(), i + 1);
- QCOMPARE(errorSpy2.count(), i + 1);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(finishedSpy2.count(), 0);
+ QCOMPARE(errorSpy.size(), i + 1);
+ QCOMPARE(finishedSpy.size(), 0);
}
}
@@ -1595,8 +2085,7 @@ void tst_QProcess::failToStartEmptyArgs_data()
{
QTest::addColumn<int>("startOverload");
QTest::newRow("start(QString, QStringList, OpenMode)") << 0;
- QTest::newRow("start(QString, OpenMode)") << 1;
- QTest::newRow("start(OpenMode)") << 2;
+ QTest::newRow("start(OpenMode)") << 1;
}
void tst_QProcess::failToStartEmptyArgs()
@@ -1605,7 +2094,7 @@ void tst_QProcess::failToStartEmptyArgs()
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
QProcess process;
- QSignalSpy errorSpy(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
+ QSignalSpy errorSpy(&process, static_cast<QProcessErrorSignal>(&QProcess::errorOccurred));
QVERIFY(errorSpy.isValid());
switch (startOverload) {
@@ -1613,9 +2102,6 @@ void tst_QProcess::failToStartEmptyArgs()
process.start(QString(), QStringList(), QIODevice::ReadWrite);
break;
case 1:
- process.start(QString(), QIODevice::ReadWrite);
- break;
- case 2:
process.start(QIODevice::ReadWrite);
break;
default:
@@ -1623,7 +2109,7 @@ void tst_QProcess::failToStartEmptyArgs()
};
QVERIFY(!process.waitForStarted());
- QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy.size(), 1);
QCOMPARE(process.error(), QProcess::FailedToStart);
}
@@ -1680,9 +2166,9 @@ void tst_QProcess::setEnvironment()
QStringList environment = QProcess::systemEnvironment();
if (value.isNull()) {
int pos;
- QRegExp rx(name + "=.*");
+ QRegularExpression rx(name + "=.*");
#ifdef Q_OS_WIN
- rx.setCaseSensitivity(Qt::CaseInsensitive);
+ rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
#endif
while ((pos = environment.indexOf(rx)) != -1)
environment.removeAt(pos);
@@ -1805,7 +2291,7 @@ void tst_QProcess::systemEnvironment()
QVERIFY(!QProcessEnvironment::systemEnvironment().isEmpty());
QVERIFY(QProcessEnvironment::systemEnvironment().contains("PATH"));
- QVERIFY(!QProcess::systemEnvironment().filter(QRegExp("^PATH=", Qt::CaseInsensitive)).isEmpty());
+ QVERIFY(!QProcess::systemEnvironment().filter(QRegularExpression("^PATH=", QRegularExpression::CaseInsensitiveOption)).isEmpty());
}
void tst_QProcess::spaceInName()
@@ -1855,24 +2341,16 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess()
QProcess process;
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QSignalSpy finishedSpy1(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
-
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(errorSpy.isValid());
- QVERIFY(errorSpy2.isValid());
- QVERIFY(finishedSpy1.isValid());
- QVERIFY(finishedSpy2.isValid());
+ QVERIFY(finishedSpy.isValid());
QVERIFY(!process.waitForReadyRead()); // used to crash
process.start("doesntexist");
QVERIFY(!process.waitForReadyRead());
- QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy.size(), 1);
QCOMPARE(errorSpy.at(0).at(0).toInt(), 0);
- QCOMPARE(errorSpy2.count(), 1);
- QCOMPARE(errorSpy2.at(0).at(0).toInt(), 0);
- QCOMPARE(finishedSpy1.count(), 0);
- QCOMPARE(finishedSpy2.count(), 0);
+ QCOMPARE(finishedSpy.size(), 0);
}
void tst_QProcess::setStandardInputFile()
@@ -1881,12 +2359,21 @@ void tst_QProcess::setStandardInputFile()
QProcess process;
QFile file(m_temporaryDir.path() + QLatin1String("/data-sif"));
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
QVERIFY(file.open(QIODevice::WriteOnly));
file.write(data, sizeof data);
file.close();
process.setStandardInputFile(file.fileName());
process.start("testProcessEcho/testProcessEcho");
+ QVERIFY(process.waitForStarted());
+ QCOMPARE(errorOccurredSpy.size(), 0);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::Running);
+ stateSpy.clear();
QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
@@ -1903,31 +2390,50 @@ void tst_QProcess::setStandardInputFile()
QCOMPARE(all.size(), 0);
}
+void tst_QProcess::setStandardInputFileFailure()
+{
+ QProcess process;
+ process.setStandardInputFile(nonExistentFileName);
+
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
+ process.start("testProcessEcho/testProcessEcho");
+ QVERIFY(!process.waitForStarted());
+
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(errorOccurredSpy[0][0].value<QProcess::ProcessError>(), QProcess::FailedToStart);
+
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::NotRunning);
+}
+
void tst_QProcess::setStandardOutputFile_data()
{
- QTest::addColumn<int>("channelToTest");
- QTest::addColumn<int>("_channelMode");
+ QTest::addColumn<QProcess::ProcessChannel>("channelToTest");
+ QTest::addColumn<QProcess::ProcessChannelMode>("channelMode");
QTest::addColumn<bool>("append");
- QTest::newRow("stdout-truncate") << int(QProcess::StandardOutput)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stdout-truncate") << QProcess::StandardOutput
+ << QProcess::SeparateChannels
<< false;
- QTest::newRow("stdout-append") << int(QProcess::StandardOutput)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stdout-append") << QProcess::StandardOutput
+ << QProcess::SeparateChannels
<< true;
- QTest::newRow("stderr-truncate") << int(QProcess::StandardError)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stderr-truncate") << QProcess::StandardError
+ << QProcess::SeparateChannels
<< false;
- QTest::newRow("stderr-append") << int(QProcess::StandardError)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stderr-append") << QProcess::StandardError
+ << QProcess::SeparateChannels
<< true;
- QTest::newRow("merged-truncate") << int(QProcess::StandardOutput)
- << int(QProcess::MergedChannels)
+ QTest::newRow("merged-truncate") << QProcess::StandardOutput
+ << QProcess::MergedChannels
<< false;
- QTest::newRow("merged-append") << int(QProcess::StandardOutput)
- << int(QProcess::MergedChannels)
+ QTest::newRow("merged-append") << QProcess::StandardOutput
+ << QProcess::MergedChannels
<< true;
}
@@ -1936,11 +2442,10 @@ void tst_QProcess::setStandardOutputFile()
static const char data[] = "Original data. ";
static const char testdata[] = "Test data.";
- QFETCH(int, channelToTest);
- QFETCH(int, _channelMode);
+ QFETCH(QProcess::ProcessChannel, channelToTest);
+ QFETCH(QProcess::ProcessChannelMode, channelMode);
QFETCH(bool, append);
- QProcess::ProcessChannelMode channelMode = QProcess::ProcessChannelMode(_channelMode);
QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
// create the destination file with data
@@ -1951,13 +2456,23 @@ void tst_QProcess::setStandardOutputFile()
// run the process
QProcess process;
- process.setReadChannelMode(channelMode);
+ process.setProcessChannelMode(channelMode);
if (channelToTest == QProcess::StandardOutput)
process.setStandardOutputFile(file.fileName(), mode);
else
process.setStandardErrorFile(file.fileName(), mode);
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
process.start("testProcessEcho2/testProcessEcho2");
+ QVERIFY(process.waitForStarted());
+ QCOMPARE(errorOccurredSpy.size(), 0);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::Running);
+ stateSpy.clear();
+
process.write(testdata, sizeof testdata);
QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
@@ -1982,6 +2497,34 @@ void tst_QProcess::setStandardOutputFile()
QCOMPARE(all.size(), expectedsize);
}
+void tst_QProcess::setStandardOutputFileFailure()
+{
+ QFETCH(QProcess::ProcessChannel, channelToTest);
+ QFETCH(QProcess::ProcessChannelMode, channelMode);
+ QFETCH(bool, append);
+
+ QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
+
+ // run the process
+ QProcess process;
+ process.setProcessChannelMode(channelMode);
+ if (channelToTest == QProcess::StandardOutput)
+ process.setStandardOutputFile(nonExistentFileName, mode);
+ else
+ process.setStandardErrorFile(nonExistentFileName, mode);
+
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
+ process.start("testProcessEcho2/testProcessEcho2");
+ QVERIFY(!process.waitForStarted());
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(errorOccurredSpy[0][0].value<QProcess::ProcessError>(), QProcess::FailedToStart);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::NotRunning);
+}
+
void tst_QProcess::setStandardOutputFileNullDevice()
{
static const char testdata[] = "Test data.";
@@ -2033,14 +2576,18 @@ void tst_QProcess::setStandardOutputProcess_data()
void tst_QProcess::setStandardOutputProcess()
{
QProcess source;
+ QProcess intermediate;
QProcess sink;
QFETCH(bool, merged);
QFETCH(bool, waitForBytesWritten);
- source.setReadChannelMode(merged ? QProcess::MergedChannels : QProcess::SeparateChannels);
- source.setStandardOutputProcess(&sink);
+ source.setProcessChannelMode(merged ? QProcess::MergedChannels : QProcess::SeparateChannels);
+ source.setStandardOutputProcess(&intermediate);
+ intermediate.setStandardOutputProcess(&sink);
source.start("testProcessEcho2/testProcessEcho2");
+ intermediate.setProgram("testProcessEcho/testProcessEcho");
+ QVERIFY(intermediate.startDetached());
sink.start("testProcessEcho2/testProcessEcho2");
QByteArray data("Hello, World");
@@ -2072,7 +2619,7 @@ void tst_QProcess::fileWriterProcess()
stdinStr += line;
}
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
const QString fileName = m_temporaryDir.path() + QLatin1String("/fileWriterProcess.txt");
const QString binary = QDir::currentPath() + QLatin1String("/fileWriterProcess/fileWriterProcess");
@@ -2082,7 +2629,7 @@ void tst_QProcess::fileWriterProcess()
QVERIFY(QFile::remove(fileName));
QProcess process;
process.setWorkingDirectory(m_temporaryDir.path());
- process.start(binary, QIODevice::ReadWrite | QIODevice::Text);
+ process.start(binary, {}, QIODevice::ReadWrite | QIODevice::Text);
process.write(stdinStr);
process.closeWriteChannel();
while (process.bytesToWrite()) {
@@ -2253,18 +2800,48 @@ void tst_QProcess::setWorkingDirectory()
void tst_QProcess::setNonExistentWorkingDirectory()
{
QProcess process;
- process.setWorkingDirectory("this/directory/should/not/exist/for/sure");
+ process.setWorkingDirectory(nonExistentFileName);
+
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
// use absolute path because on Windows, the executable is relative to the parent's CWD
// while on Unix with fork it's relative to the child's (with posix_spawn, it could be either).
process.start(QFileInfo("testSetWorkingDirectory/testSetWorkingDirectory").absoluteFilePath());
+
QVERIFY(!process.waitForFinished());
- QCOMPARE(int(process.error()), int(QProcess::FailedToStart));
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::NotRunning);
+
+#ifdef Q_OS_UNIX
+ QVERIFY2(process.errorString().startsWith("chdir:"), process.errorString().toLocal8Bit());
+#endif
+}
+
+void tst_QProcess::detachedSetNonExistentWorkingDirectory()
+{
+ QProcess process;
+ process.setWorkingDirectory(nonExistentFileName);
+
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
+ // use absolute path because on Windows, the executable is relative to the parent's CWD
+ // while on Unix with fork it's relative to the child's (with posix_spawn, it could be either).
+ process.setProgram(QFileInfo("testSetWorkingDirectory/testSetWorkingDirectory").absoluteFilePath());
+
+ qint64 pid = -1;
+ QVERIFY(!process.startDetached(&pid));
+ QCOMPARE(pid, -1);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QVERIFY(process.errorString() != "Unknown error");
+
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
#ifdef Q_OS_UNIX
-# ifdef QPROCESS_USE_SPAWN
- QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue);
-# endif
QVERIFY2(process.errorString().startsWith("chdir:"), process.errorString().toLocal8Bit());
#endif
}
@@ -2293,7 +2870,6 @@ void tst_QProcess::invalidProgramString_data()
QTest::addColumn<QString>("programString");
QTest::newRow("null string") << QString();
QTest::newRow("empty string") << QString("");
- QTest::newRow("only blank string") << QString(" ");
}
void tst_QProcess::invalidProgramString()
@@ -2303,14 +2879,11 @@ void tst_QProcess::invalidProgramString()
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
QSignalSpy spy(&process, &QProcess::errorOccurred);
- QSignalSpy spy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
QVERIFY(spy.isValid());
- QVERIFY(spy2.isValid());
process.start(programString);
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(spy.count(), 1);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(!QProcess::startDetached(programString));
}
@@ -2321,7 +2894,7 @@ void tst_QProcess::onlyOneStartedSignal()
QProcess process;
QSignalSpy spyStarted(&process, &QProcess::started);
- QSignalSpy spyFinished(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy spyFinished(&process, &QProcess::finished);
QVERIFY(spyStarted.isValid());
QVERIFY(spyFinished.isValid());
@@ -2329,8 +2902,8 @@ void tst_QProcess::onlyOneStartedSignal()
process.start("testProcessNormal/testProcessNormal");
QVERIFY(process.waitForStarted(5000));
QVERIFY(process.waitForFinished(5000));
- QCOMPARE(spyStarted.count(), 1);
- QCOMPARE(spyFinished.count(), 1);
+ QCOMPARE(spyStarted.size(), 1);
+ QCOMPARE(spyFinished.size(), 1);
spyStarted.clear();
spyFinished.clear();
@@ -2339,8 +2912,8 @@ void tst_QProcess::onlyOneStartedSignal()
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
- QCOMPARE(spyStarted.count(), 1);
- QCOMPARE(spyFinished.count(), 1);
+ QCOMPARE(spyStarted.size(), 1);
+ QCOMPARE(spyFinished.size(), 1);
}
class BlockOnReadStdOut : public QObject
@@ -2355,7 +2928,7 @@ public:
public slots:
void block()
{
- QThread::sleep(1);
+ QThread::sleep(std::chrono::seconds{1});
}
};
@@ -2364,13 +2937,12 @@ void tst_QProcess::finishProcessBeforeReadingDone()
QProcess process;
BlockOnReadStdOut blocker(&process);
QEventLoop loop;
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- &loop, &QEventLoop::quit);
+ connect(&process, &QProcess::finished, &loop, &QEventLoop::quit);
process.start("testProcessOutput/testProcessOutput");
QVERIFY(process.waitForStarted());
loop.exec();
QStringList lines = QString::fromLocal8Bit(process.readAllStandardOutput()).split(
- QRegExp(QStringLiteral("[\r\n]")), QString::SkipEmptyParts);
+ QRegularExpression(QStringLiteral("[\r\n]")), Qt::SkipEmptyParts);
QVERIFY(!lines.isEmpty());
QCOMPARE(lines.last(), QStringLiteral("10239 -this is a number"));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
@@ -2408,23 +2980,23 @@ void tst_QProcess::startStopStartStop()
//-----------------------------------------------------------------------------
void tst_QProcess::startStopStartStopBuffers_data()
{
- QTest::addColumn<int>("channelMode1");
- QTest::addColumn<int>("channelMode2");
+ QTest::addColumn<QProcess::ProcessChannelMode>("channelMode1");
+ QTest::addColumn<QProcess::ProcessChannelMode>("channelMode2");
- QTest::newRow("separate-separate") << int(QProcess::SeparateChannels) << int(QProcess::SeparateChannels);
- QTest::newRow("separate-merged") << int(QProcess::SeparateChannels) << int(QProcess::MergedChannels);
- QTest::newRow("merged-separate") << int(QProcess::MergedChannels) << int(QProcess::SeparateChannels);
- QTest::newRow("merged-merged") << int(QProcess::MergedChannels) << int(QProcess::MergedChannels);
- QTest::newRow("merged-forwarded") << int(QProcess::MergedChannels) << int(QProcess::ForwardedChannels);
+ QTest::newRow("separate-separate") << QProcess::SeparateChannels << QProcess::SeparateChannels;
+ QTest::newRow("separate-merged") << QProcess::SeparateChannels << QProcess::MergedChannels;
+ QTest::newRow("merged-separate") << QProcess::MergedChannels << QProcess::SeparateChannels;
+ QTest::newRow("merged-merged") << QProcess::MergedChannels << QProcess::MergedChannels;
+ QTest::newRow("merged-forwarded") << QProcess::MergedChannels << QProcess::ForwardedChannels;
}
void tst_QProcess::startStopStartStopBuffers()
{
- QFETCH(int, channelMode1);
- QFETCH(int, channelMode2);
+ QFETCH(QProcess::ProcessChannelMode, channelMode1);
+ QFETCH(QProcess::ProcessChannelMode, channelMode2);
QProcess process;
- process.setProcessChannelMode(QProcess::ProcessChannelMode(channelMode1));
+ process.setProcessChannelMode(channelMode1);
process.start("testProcessHang/testProcessHang");
QVERIFY2(process.waitForReadyRead(), process.errorString().toLocal8Bit());
if (channelMode1 == QProcess::SeparateChannels || channelMode1 == QProcess::ForwardedOutputChannel) {
@@ -2435,14 +3007,18 @@ void tst_QProcess::startStopStartStopBuffers()
}
// We want to test that the write buffer still has bytes after the child
- // exiting. We do that by writing to a child process that never reads. We
- // just have to write more data than a pipe can hold, so that even if
- // QProcess finds the pipe writable (during waitForFinished() or in the
- // QWindowsPipeWriter thread), some data will remain. The worst case I know
- // of is Linux, which defaults to 64 kB of buffer.
+ // exits. We can do that by writing data until the OS stops consuming data,
+ // indicating that the pipe buffers are full. The initial value of 128 kB
+ // should make this loop typicall run only once; the worst case I know of
+ // is Linux, which defaults to 64 kB of buffer.
- process.write(QByteArray(128 * 1024, 'a'));
- QVERIFY(process.bytesToWrite() > 0);
+ QByteArray chunk(128 * 1024, 'a');
+ do {
+ process.write(chunk);
+ QVERIFY(process.bytesToWrite() > 0);
+ process.waitForBytesWritten(1);
+ } while (process.bytesToWrite() == 0);
+ chunk = {};
process.kill();
QVERIFY(process.waitForFinished());
@@ -2450,7 +3026,8 @@ void tst_QProcess::startStopStartStopBuffers()
#ifndef Q_OS_WIN
// confirm that our buffers are still full
// Note: this doesn't work on Windows because our buffers are drained into
- // QWindowsPipeWriter before being sent to the child process.
+ // QWindowsPipeWriter before being sent to the child process and are lost
+ // in waitForFinished() -> processFinished() -> cleanup().
QVERIFY(process.bytesToWrite() > 0);
QVERIFY(process.bytesAvailable() > 0); // channelMode1 is not ForwardedChannels
if (channelMode1 == QProcess::SeparateChannels || channelMode1 == QProcess::ForwardedOutputChannel) {
@@ -2460,8 +3037,8 @@ void tst_QProcess::startStopStartStopBuffers()
}
#endif
- process.setProcessChannelMode(QProcess::ProcessChannelMode(channelMode2));
- process.start("testProcessEcho2/testProcessEcho2", QIODevice::ReadWrite | QIODevice::Text);
+ process.setProcessChannelMode(channelMode2);
+ process.start("testProcessEcho2/testProcessEcho2", {}, QIODevice::ReadWrite | QIODevice::Text);
// the buffers should now be empty
QCOMPARE(process.bytesToWrite(), qint64(0));
@@ -2510,5 +3087,94 @@ void tst_QProcess::processEventsInAReadyReadSlot()
QVERIFY(process.waitForFinished());
}
+enum class ChdirMode {
+ None = 0,
+ InParent,
+ InChild
+};
+Q_DECLARE_METATYPE(ChdirMode)
+
+void tst_QProcess::startFromCurrentWorkingDir_data()
+{
+ qRegisterMetaType<ChdirMode>();
+ QTest::addColumn<QString>("programPrefix");
+ QTest::addColumn<ChdirMode>("chdirMode");
+ QTest::addColumn<bool>("success");
+
+ constexpr bool IsWindows = true
+#ifdef Q_OS_UNIX
+ && false
+#endif
+ ;
+
+ // baseline: trying to execute the directory, this can't possibly succeed!
+ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
+
+ // cross-platform behavior: neither OS searches the setWorkingDirectory()
+ // dir without "./"
+ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
+
+ // cross-platform behavior: both OSes search the parent's CWD with "./"
+ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
+
+ // opposite behaviors: Windows searches the parent's CWD and Unix searches
+ // the child's with "./"
+ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
+
+ // Windows searches the parent's CWD without "./"
+ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
+}
+
+void tst_QProcess::startFromCurrentWorkingDir()
+{
+ QFETCH(QString, programPrefix);
+ QFETCH(ChdirMode, chdirMode);
+ QFETCH(bool, success);
+
+ QProcess process;
+ qRegisterMetaType<QProcess::ProcessError>();
+ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
+ QVERIFY(errorSpy.isValid());
+
+ // both the dir name and the executable name
+ const QString target = QStringLiteral("testProcessNormal");
+ process.setProgram(programPrefix + target);
+
+#ifdef Q_OS_UNIX
+ // Reset PATH, to be sure it doesn't contain . or the empty path.
+ // We can't do this on Windows because DLLs are searched in PATH
+ // and Windows always searches "." anyway.
+ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
+ qputenv("PATH", old);
+ });
+ qputenv("PATH", "/");
+#endif
+
+ switch (chdirMode) {
+ case ChdirMode::InParent: {
+ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
+ QDir::setCurrent(old);
+ });
+ QVERIFY(QDir::setCurrent(target));
+ process.start();
+ break;
+ }
+ case ChdirMode::InChild:
+ process.setWorkingDirectory(target);
+ Q_FALLTHROUGH();
+ case ChdirMode::None:
+ process.start();
+ break;
+ }
+
+ QCOMPARE(process.waitForStarted(), success);
+ QCOMPARE(errorSpy.size(), int(!success));
+ if (success) {
+ QVERIFY(process.waitForFinished());
+ } else {
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ }
+}
+
QTEST_MAIN(tst_QProcess)
#include "tst_qprocess.moc"
diff --git a/tests/auto/corelib/io/qprocessenvironment/CMakeLists.txt b/tests/auto/corelib/io/qprocessenvironment/CMakeLists.txt
new file mode 100644
index 0000000000..02c6909031
--- /dev/null
+++ b/tests/auto/corelib/io/qprocessenvironment/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qprocessenvironment Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qprocessenvironment LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qprocessenvironment
+ SOURCES
+ tst_qprocessenvironment.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro b/tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro
deleted file mode 100644
index 04cef29a64..0000000000
--- a/tests/auto/corelib/io/qprocessenvironment/qprocessenvironment.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qprocessenvironment
-QT = core testlib
-SOURCES = tst_qprocessenvironment.cpp
diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp
index af5078a3dc..6a2a3daaa2 100644
--- a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp
+++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QObject>
#include <QProcessEnvironment>
@@ -34,8 +10,10 @@ class tst_QProcessEnvironment: public QObject
{
Q_OBJECT
private slots:
+ void compareCompiles();
void operator_eq();
void clearAndIsEmpty();
+ void clearAndInheritsFromParent();
void insert();
void emptyNull();
void toStringList();
@@ -47,6 +25,11 @@ private slots:
void putenv();
};
+void tst_QProcessEnvironment::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QProcessEnvironment>();
+}
+
void tst_QProcessEnvironment::operator_eq()
{
QProcessEnvironment e1;
@@ -58,6 +41,9 @@ void tst_QProcessEnvironment::operator_eq()
QProcessEnvironment e2;
QCOMPARE(e1, e2);
+ auto parentEnv = QProcessEnvironment(QProcessEnvironment::InheritFromParent);
+ QT_TEST_EQUALITY_OPS(parentEnv, e2, false);
+
e1.clear();
QCOMPARE(e1, e2);
@@ -65,22 +51,45 @@ void tst_QProcessEnvironment::operator_eq()
QCOMPARE(e1, e2);
e1.insert("FOO", "bar");
- QVERIFY(e1 != e2);
+ QT_TEST_EQUALITY_OPS(e1, e2, false);
e2.insert("FOO", "bar");
QCOMPARE(e1, e2);
e2.insert("FOO", "baz");
- QVERIFY(e1 != e2);
+ QT_TEST_EQUALITY_OPS(e1, e2, false);
+
+ QT_TEST_EQUALITY_OPS(e2, parentEnv, false);
}
void tst_QProcessEnvironment::clearAndIsEmpty()
{
QProcessEnvironment e;
+ QVERIFY(e.isEmpty());
+ QVERIFY(!e.inheritsFromParent());
+ e.insert("FOO", "bar");
+ QVERIFY(!e.isEmpty());
+ QVERIFY(!e.inheritsFromParent());
+ e.clear();
+ QVERIFY(e.isEmpty());
+ QVERIFY(!e.inheritsFromParent());
+}
+
+void tst_QProcessEnvironment::clearAndInheritsFromParent()
+{
+ QProcessEnvironment e(QProcessEnvironment::InheritFromParent);
+ QVERIFY(e.isEmpty());
+ QVERIFY(e.inheritsFromParent());
+ // Clearing null environment keeps it null
+ e.clear();
+ QVERIFY(e.isEmpty());
+ QVERIFY(e.inheritsFromParent());
e.insert("FOO", "bar");
QVERIFY(!e.isEmpty());
+ QVERIFY(!e.inheritsFromParent());
e.clear();
QVERIFY(e.isEmpty());
+ QVERIFY(!e.inheritsFromParent());
}
void tst_QProcessEnvironment::insert()
@@ -126,7 +135,7 @@ void tst_QProcessEnvironment::toStringList()
e.insert("FOO", "bar");
QStringList result = e.toStringList();
QVERIFY(!result.isEmpty());
- QCOMPARE(result.length(), 1);
+ QCOMPARE(result.size(), 1);
QCOMPARE(result.at(0), QString("FOO=bar"));
e.clear();
@@ -138,7 +147,7 @@ void tst_QProcessEnvironment::toStringList()
e.insert("A", "bc");
e.insert("HELLO", "World");
result = e.toStringList();
- QCOMPARE(result.length(), 4);
+ QCOMPARE(result.size(), 4);
// order is not specified, so use contains()
QVERIFY(result.contains("FOO=bar"));
@@ -155,7 +164,7 @@ void tst_QProcessEnvironment::keys()
e.insert("FOO", "bar");
QStringList result = e.keys();
- QCOMPARE(result.length(), 1);
+ QCOMPARE(result.size(), 1);
QCOMPARE(result.at(0), QString("FOO"));
e.clear();
@@ -167,7 +176,7 @@ void tst_QProcessEnvironment::keys()
e.insert("A", "bc");
e.insert("HELLO", "World");
result = e.keys();
- QCOMPARE(result.length(), 4);
+ QCOMPARE(result.size(), 4);
// order is not specified, so use contains()
QVERIFY(result.contains("FOO"));
@@ -190,7 +199,7 @@ void tst_QProcessEnvironment::insertEnv()
e.insert(e2);
QStringList keys = e.keys();
- QCOMPARE(keys.length(), 5);
+ QCOMPARE(keys.size(), 5);
QCOMPARE(e.value("FOO"), QString("bar"));
QCOMPARE(e.value("A"), QString("bc"));
@@ -240,7 +249,7 @@ void tst_QProcessEnvironment::caseSensitivity()
QCOMPARE(e.value("foo"), QString("bar"));
QStringList list = e.toStringList();
- QCOMPARE(list.length(), 2);
+ QCOMPARE(list.size(), 2);
QVERIFY(list.contains("foo=bar"));
QVERIFY(list.contains("FOO=baz"));
#endif
diff --git a/tests/auto/corelib/io/qresourceengine/CMakeLists.txt b/tests/auto/corelib/io/qresourceengine/CMakeLists.txt
new file mode 100644
index 0000000000..a86cc8e76a
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/CMakeLists.txt
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qresourceengine Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qresourceengine LANGUAGES C CXX ASM)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+set(test_data "parentdir.txt")
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ testqrc/*)
+list(APPEND test_data ${test_data_glob})
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ *.rcc)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_qresourceengine
+ SOURCES
+ tst_qresourceengine.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ moctestplugin
+ TESTDATA ${test_data}
+)
+
+set_source_files_properties("world.txt"
+ PROPERTIES QT_DISCARD_FILE_CONTENTS TRUE
+)
+
+qt_internal_add_resource(tst_qresourceengine "qt_resource_empty"
+ PREFIX
+ "/empty"
+ FILES
+ "world.txt"
+)
+
+qt_add_resources(additional_sources testqrc/test.qrc)
+target_sources(tst_qresourceengine PRIVATE ${additional_sources})
+
+if(ANDROID)
+ qt_add_resources(additional_sources android_testdata.qrc)
+ target_sources(tst_qresourceengine PRIVATE ${additional_sources})
+endif()
+
+qt_add_binary_resources(tst_qresourceengine_runtime_resource "testqrc/test.qrc"
+ DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/runtime_resource.rcc"
+ OPTIONS -root "/runtime_resource/" -binary)
+add_dependencies(tst_qresourceengine tst_qresourceengine_runtime_resource)
+
+add_subdirectory(staticplugin)
diff --git a/tests/auto/corelib/io/qresourceengine/compressed.qrc b/tests/auto/corelib/io/qresourceengine/compressed.qrc
new file mode 100644
index 0000000000..f7c7cbc20f
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/compressed.qrc
@@ -0,0 +1,5 @@
+<RCC version="1.0">
+ <qresource>
+ <file>zero.txt</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/corelib/io/qresourceengine/generateResources.sh b/tests/auto/corelib/io/qresourceengine/generateResources.sh
new file mode 100755
index 0000000000..18d1e0b80f
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/generateResources.sh
@@ -0,0 +1,9 @@
+# Copyright (C) 2016 Intel Corporation.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+#!/bin/sh
+count=`awk '/ZERO_FILE_LEN/ { print $3 }' tst_qresourceengine.cpp`
+dd if=/dev/zero of=zero.txt bs=1 count=$count
+rcc --binary -o uncompressed.rcc --no-compress compressed.qrc
+rcc --binary -o zlib.rcc --compress-algo zlib --compress 9 compressed.qrc
+rcc --binary -o zstd.rcc --compress-algo zstd --compress 19 compressed.qrc
+rm zero.txt
diff --git a/tests/auto/corelib/io/qresourceengine/qresourceengine.pro b/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
deleted file mode 100644
index 1e12a41dea..0000000000
--- a/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = staticplugin qresourceengine_test.pro
diff --git a/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro b/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro
deleted file mode 100644
index 3838a72c21..0000000000
--- a/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro
+++ /dev/null
@@ -1,33 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qresourceengine
-
-QT = core testlib
-SOURCES = tst_qresourceengine.cpp
-RESOURCES += testqrc/test.qrc
-
-qtPrepareTool(QMAKE_RCC, rcc, _DEP)
-runtime_resource.target = runtime_resource.rcc
-runtime_resource.depends = $$PWD/testqrc/test.qrc $$QMAKE_RCC_EXE
-runtime_resource.commands = $$QMAKE_RCC -root /runtime_resource/ -binary $$PWD/testqrc/test.qrc -o $${runtime_resource.target}
-QMAKE_EXTRA_TARGETS = runtime_resource
-PRE_TARGETDEPS += $${runtime_resource.target}
-QMAKE_DISTCLEAN += $${runtime_resource.target}
-
-TESTDATA += \
- parentdir.txt \
- testqrc/*
-GENERATED_TESTDATA = $${runtime_resource.target}
-
-android:!android-embedded {
- RESOURCES += android_testdata.qrc
-}
-
-win32 {
- CONFIG(debug, debug|release): LIBS += -Lstaticplugin/debug
- else: LIBS += -Lstaticplugin/release
-} else {
- LIBS += -Lstaticplugin
-}
-LIBS += -lmoctestplugin
-
-builtin_testdata: DEFINES += BUILTIN_TESTDATA
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore b/tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore
deleted file mode 100644
index c397dde6a5..0000000000
--- a/tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-moctestplugin_plugin_resources.cpp
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/CMakeLists.txt b/tests/auto/corelib/io/qresourceengine/staticplugin/CMakeLists.txt
new file mode 100644
index 0000000000..1012fcaa62
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/staticplugin/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## moctestplugin Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(moctestplugin
+ STATIC
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+ DEFINES
+ QT_STATICPLUGIN
+)
+
+qt_internal_add_resource(moctestplugin "qmake_plugin_resource"
+ PREFIX
+ "/staticplugin"
+ FILES
+ "main.cpp"
+)
+
+qt_autogen_tools_initial_setup(moctestplugin)
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro b/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro
deleted file mode 100644
index e19d884548..0000000000
--- a/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TEMPLATE = lib
-TARGET = moctestplugin
-CONFIG += plugin static
-SOURCES = main.cpp
-plugin_resource.files = main.cpp
-plugin_resource.prefix = /staticplugin
-RESOURCES += plugin_resource
-QT = core
diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc
index f5e8c849a6..56972ea764 100644
--- a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc
+++ b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc
@@ -9,10 +9,10 @@
<file>searchpath1/search_file.txt</file>
<file>searchpath2/search_file.txt</file>
<file>search_file.txt</file>
- </qresource>
- <qresource><file>test/testdir.txt</file>
+ <file>test/testdir.txt</file>
<file>otherdir/otherdir.txt</file>
<file alias="aliasdir/aliasdir.txt">test/testdir2.txt</file>
+ <file alias="uncompresseddir/uncompressed.txt" compression-algorithm="none">aliasdir/compressme.txt</file>
<file>test/test</file>
</qresource>
<qresource lang="ko">
@@ -21,7 +21,7 @@
<qresource lang="de_CH">
<file alias="aliasdir/aliasdir.txt" compress="9" threshold="30">aliasdir/compressme.txt</file>
</qresource>
- <qresource lang="de">
+ <qresource lang="de" compression-algorithm="none">
<file alias="aliasdir/aliasdir.txt">test/german.txt</file>
</qresource>
<qresource prefix="withoutslashes">
diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
index 0b50c391b8..cf0e258412 100644
--- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
+++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
@@ -1,36 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2019 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QResource>
+#include <QtPlugin>
#include <QtCore/QCoreApplication>
-#include <QtCore/QMimeDatabase>
+#include <QtCore/QScopeGuard>
+#include <QtCore/private/qglobal_p.h>
class tst_QResourceEngine: public QObject
{
@@ -38,8 +15,10 @@ class tst_QResourceEngine: public QObject
public:
tst_QResourceEngine()
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- : m_runtimeResourceRcc(QFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QStringLiteral("/runtime_resource.rcc")).absoluteFilePath())
+#ifdef Q_OS_ANDROID
+ : m_runtimeResourceRcc(
+ QFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
+ + QStringLiteral("/runtime_resource.rcc")).absoluteFilePath())
#else
: m_runtimeResourceRcc(QFINDTESTDATA("runtime_resource.rcc"))
#endif
@@ -51,14 +30,18 @@ private slots:
void checkUnregisterResource_data();
void checkUnregisterResource();
+ void compressedResource_data();
+ void compressedResource();
void checkStructure_data();
void checkStructure();
void searchPath_data();
void searchPath();
void doubleSlashInRoot();
+ void setLocale_data();
void setLocale();
void lastModified();
void resourcesInStaticPlugins();
+ void qtResourceEmpty();
private:
const QString m_runtimeResourceRcc;
@@ -67,17 +50,16 @@ private:
void tst_QResourceEngine::initTestCase()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QString sourcePath(QStringLiteral(":/android_testdata/"));
QString dataPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
QDirIterator it(sourcePath, QDirIterator::Subdirectories);
while (it.hasNext()) {
- it.next();
-
- QFileInfo fileInfo = it.fileInfo();
+ QFileInfo fileInfo = it.nextFileInfo();
if (!fileInfo.isDir()) {
- QString destination(dataPath + QLatin1Char('/') + fileInfo.filePath().mid(sourcePath.length()));
+ QString destination(dataPath + QLatin1Char('/')
+ + fileInfo.filePath().mid(sourcePath.length()));
QFileInfo destinationFileInfo(destination);
if (!destinationFileInfo.exists()) {
QVERIFY(QDir().mkpath(destinationFileInfo.path()));
@@ -102,6 +84,75 @@ void tst_QResourceEngine::cleanupTestCase()
QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc, "/secondary_root/"));
}
+void tst_QResourceEngine::compressedResource_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<int>("compressionAlgo");
+ QTest::addColumn<bool>("supported");
+
+ QTest::newRow("uncompressed")
+ << QFINDTESTDATA("uncompressed.rcc") << int(QResource::NoCompression) << true;
+ QTest::newRow("zlib")
+ << QFINDTESTDATA("zlib.rcc") << int(QResource::ZlibCompression) << true;
+ QTest::newRow("zstd")
+ << QFINDTESTDATA("zstd.rcc") << int(QResource::ZstdCompression) << QT_CONFIG(zstd);
+}
+
+// Note: generateResource.sh parses this line. Make sure it's a simple number.
+#define ZERO_FILE_LEN 16384
+// End note
+void tst_QResourceEngine::compressedResource()
+{
+ QFETCH(QString, fileName);
+ QFETCH(int, compressionAlgo);
+ QFETCH(bool, supported);
+ const QByteArray expectedData(ZERO_FILE_LEN, '\0');
+
+ QVERIFY(!QResource("zero.txt").isValid());
+ QCOMPARE(QResource::registerResource(fileName), supported);
+ if (!supported)
+ return;
+
+ auto unregister = qScopeGuard([=] { QResource::unregisterResource(fileName); });
+
+ QResource resource("zero.txt");
+ QVERIFY(resource.isValid());
+ QVERIFY(resource.size() > 0);
+ QVERIFY(resource.data());
+ QCOMPARE(resource.compressionAlgorithm(), QResource::Compression(compressionAlgo));
+
+ if (compressionAlgo == QResource::NoCompression) {
+ QCOMPARE(resource.size(), ZERO_FILE_LEN);
+ QCOMPARE(memcmp(resource.data(), expectedData.data(), ZERO_FILE_LEN), 0);
+
+ // API guarantees it will be QByteArray::fromRawData:
+ QCOMPARE(static_cast<const void *>(resource.uncompressedData().constData()),
+ static_cast<const void *>(resource.data()));
+ } else {
+ // reasonable expectation:
+ QVERIFY(resource.size() < ZERO_FILE_LEN);
+ }
+
+ // using the engine
+ QFile f(":/zero.txt");
+ QVERIFY(f.exists());
+ QVERIFY(f.open(QIODevice::ReadOnly));
+
+ // verify that we can decompress correctly
+ QCOMPARE(resource.uncompressedSize(), ZERO_FILE_LEN);
+ QCOMPARE(f.size(), ZERO_FILE_LEN);
+
+ QByteArray data = resource.uncompressedData();
+ QCOMPARE(data.size(), expectedData.size());
+ QCOMPARE(data, expectedData);
+
+ // decompression through the engine
+ data = f.readAll();
+ QCOMPARE(data.size(), expectedData.size());
+ QCOMPARE(data, expectedData);
+}
+
+
void tst_QResourceEngine::checkStructure_data()
{
QTest::addColumn<QString>("pathName");
@@ -115,24 +166,22 @@ void tst_QResourceEngine::checkStructure_data()
QStringList rootContents;
rootContents << QLatin1String("aliasdir")
+#ifdef Q_OS_ANDROID
+ << QLatin1String("android_testdata")
+#endif
+ << QLatin1String("empty")
<< QLatin1String("otherdir")
- << QLatin1String("qt-project.org")
<< QLatin1String("runtime_resource")
<< QLatin1String("searchpath1")
<< QLatin1String("searchpath2")
<< QLatin1String("secondary_root")
<< QLatin1String("staticplugin")
<< QLatin1String("test")
- << QLatin1String("withoutslashes");
-
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- rootContents.insert(1, QLatin1String("android_testdata"));
-#endif
-
#if defined(BUILTIN_TESTDATA)
- rootContents.insert(9, QLatin1String("testqrc"));
+ << QLatin1String("testqrc")
#endif
-
+ << QLatin1String("uncompresseddir")
+ << QLatin1String("withoutslashes");
QTest::newRow("root dir") << QString(":/")
<< QByteArray()
@@ -141,7 +190,13 @@ void tst_QResourceEngine::checkStructure_data()
<< "parentdir.txt"
<< "runtime_resource.rcc"
#endif
- << "search_file.txt")
+ << "search_file.txt"
+#if defined(BUILTIN_TESTDATA)
+ << "uncompressed.rcc"
+ << "zlib.rcc"
+ << "zstd.rcc"
+#endif
+ )
<< rootContents
<< QLocale::c()
<< qlonglong(0);
@@ -158,56 +213,56 @@ void tst_QResourceEngine::checkStructure_data()
for(int i = 0; i < roots.size(); ++i) {
const QString root = roots.at(i);
- QTest::addRow("%s prefix dir", qPrintable(root)) << QString(root + "test/abc/123/+++")
+ QTest::addRow("prefix dir on %s", qPrintable(root)) << QString(root + "test/abc/123/+++")
<< QByteArray()
<< (QStringList() << QLatin1String("currentdir.txt") << QLatin1String("currentdir2.txt") << QLatin1String("parentdir.txt"))
<< (QStringList() << QLatin1String("subdir"))
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s parent to prefix", qPrintable(root)) << QString(root + "test/abc/123")
+ QTest::addRow("parent to prefix on %s", qPrintable(root)) << QString(root + "test/abc/123")
<< QByteArray()
<< QStringList()
<< (QStringList() << QLatin1String("+++"))
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s two parents prefix", qPrintable(root)) << QString(root + "test/abc")
+ QTest::addRow("two parents prefix on %s", qPrintable(root)) << QString(root + "test/abc")
<< QByteArray()
<< QStringList()
<< QStringList(QLatin1String("123"))
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s test dir ", qPrintable(root)) << QString(root + "test")
+ QTest::addRow("test dir on %s", qPrintable(root)) << QString(root + "test")
<< QByteArray()
<< (QStringList() << QLatin1String("testdir.txt"))
<< (QStringList() << QLatin1String("abc") << QLatin1String("test"))
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s prefix no slashes", qPrintable(root)) << QString(root + "withoutslashes")
+ QTest::addRow("prefix no slashes on %s", qPrintable(root)) << QString(root + "withoutslashes")
<< QByteArray()
<< QStringList("blahblah.txt")
<< QStringList()
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s other dir", qPrintable(root)) << QString(root + "otherdir")
+ QTest::addRow("other dir on %s", qPrintable(root)) << QString(root + "otherdir")
<< QByteArray()
<< QStringList(QLatin1String("otherdir.txt"))
<< QStringList()
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s alias dir", qPrintable(root)) << QString(root + "aliasdir")
+ QTest::addRow("alias dir on %s", qPrintable(root)) << QString(root + "aliasdir")
<< QByteArray()
<< QStringList(QLatin1String("aliasdir.txt"))
<< QStringList()
<< QLocale::c()
<< qlonglong(0);
- QTest::addRow("%s second test dir", qPrintable(root)) << QString(root + "test/test")
+ QTest::addRow("second test dir on %s", qPrintable(root)) << QString(root + "test/test")
<< QByteArray()
<< (QStringList() << QLatin1String("test1.txt") << QLatin1String("test2.txt"))
<< QStringList()
@@ -215,7 +270,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(0);
info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test1.txt"));
- QTest::addRow("%s test1 text", qPrintable(root)) << QString(root + "test/test/test1.txt")
+ QTest::addRow("test1 text on %s", qPrintable(root)) << QString(root + "test/test/test1.txt")
<< QByteArray("abc\n")
<< QStringList()
<< QStringList()
@@ -223,7 +278,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/blahblah.txt"));
- QTest::addRow("%s text no slashes", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt")
+ QTest::addRow("text no slashes on %s", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt")
<< QByteArray("qwerty\n")
<< QStringList()
<< QStringList()
@@ -232,7 +287,7 @@ void tst_QResourceEngine::checkStructure_data()
info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test2.txt"));
- QTest::addRow("%s test1 text", qPrintable(root)) << QString(root + "test/test/test2.txt")
+ QTest::addRow("test2 text on %s", qPrintable(root)) << QString(root + "test/test/test2.txt")
<< QByteArray("def\n")
<< QStringList()
<< QStringList()
@@ -240,7 +295,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/currentdir.txt"));
- QTest::addRow("%s currentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt")
+ QTest::addRow("currentdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt")
<< QByteArray("\"This is the current dir\"\n")
<< QStringList()
<< QStringList()
@@ -248,7 +303,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/currentdir2.txt"));
- QTest::addRow("%s currentdir text2", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt")
+ QTest::addRow("currentdir text2 on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt")
<< QByteArray("\"This is also the current dir\"\n")
<< QStringList()
<< QStringList()
@@ -256,7 +311,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("parentdir.txt"));
- QTest::addRow("%s parentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt")
+ QTest::addRow("parentdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt")
<< QByteArray("abcdefgihklmnopqrstuvwxyz \n")
<< QStringList()
<< QStringList()
@@ -264,7 +319,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/subdir/subdir.txt"));
- QTest::addRow("%s subdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt")
+ QTest::addRow("subdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt")
<< QByteArray("\"This is in the sub directory\"\n")
<< QStringList()
<< QStringList()
@@ -272,7 +327,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir.txt"));
- QTest::addRow("%s testdir text", qPrintable(root)) << QString(root + "test/testdir.txt")
+ QTest::addRow("testdir text on %s", qPrintable(root)) << QString(root + "test/testdir.txt")
<< QByteArray("\"This is in the test directory\"\n")
<< QStringList()
<< QStringList()
@@ -280,7 +335,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/otherdir/otherdir.txt"));
- QTest::addRow("%s otherdir text", qPrintable(root)) << QString(root + "otherdir/otherdir.txt")
+ QTest::addRow("otherdir text on %s", qPrintable(root)) << QString(root + "otherdir/otherdir.txt")
<< QByteArray("\"This is the other dir\"\n")
<< QStringList()
<< QStringList()
@@ -288,7 +343,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir2.txt"));
- QTest::addRow("%s alias text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
+ QTest::addRow("alias text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
<< QByteArray("\"This is another file in this directory\"\n")
<< QStringList()
<< QStringList()
@@ -296,7 +351,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt"));
- QTest::addRow("%s korean text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
+ QTest::addRow("korean text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
<< QByteArray("\"This is a korean text file\"\n")
<< QStringList()
<< QStringList()
@@ -304,7 +359,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt"));
- QTest::addRow("%s korean text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
+ QTest::addRow("korean text 2 on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
<< QByteArray("\"This is a korean text file\"\n")
<< QStringList()
<< QStringList()
@@ -312,7 +367,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt"));
- QTest::addRow("%s german text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
+ QTest::addRow("german text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
<< QByteArray("Deutsch\n")
<< QStringList()
<< QStringList()
@@ -320,7 +375,7 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt"));
- QTest::addRow("%s german text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
+ QTest::addRow("german text 2 on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
<< QByteArray("Deutsch\n")
<< QStringList()
<< QStringList()
@@ -328,10 +383,18 @@ void tst_QResourceEngine::checkStructure_data()
<< qlonglong(info.size());
QFile file(QFINDTESTDATA("testqrc/aliasdir/compressme.txt"));
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/compressme.txt"));
- QTest::addRow("%s compressed text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
- << file.readAll()
+ QByteArray compressmeContents = file.readAll();
+ QTest::addRow("compressed text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt")
+ << compressmeContents
+ << QStringList()
+ << QStringList()
+ << QLocale("de_CH")
+ << qlonglong(info.size());
+
+ QTest::addRow("non-compressed text on %s", qPrintable(root)) << QString(root + "uncompresseddir/uncompressed.txt")
+ << compressmeContents
<< QStringList()
<< QStringList()
<< QLocale("de_CH")
@@ -348,11 +411,6 @@ void tst_QResourceEngine::checkStructure()
QFETCH(QLocale, locale);
QFETCH(qlonglong, contentsSize);
- // We rely on the existence of the root "qt-project.org" in resources. For
- // static builds on MSVC these resources are only added if they are used.
- QMimeDatabase db;
- Q_UNUSED(db);
-
bool directory = (containedDirs.size() + containedFiles.size() > 0);
QLocale::setDefault(locale);
@@ -379,7 +437,7 @@ void tst_QResourceEngine::checkStructure()
}
list = dir.entryInfoList(QDir::Files, QDir::Name);
- QCOMPARE(containedFiles.size(), list.size());
+ QCOMPARE(list.size(), containedFiles.size());
for (i=0; i<list.size(); ++i) {
QVERIFY(!list.at(i).isDir());
@@ -387,7 +445,7 @@ void tst_QResourceEngine::checkStructure()
}
list = dir.entryInfoList(QDir::NoFilter, QDir::SortFlags(QDir::Name | QDir::DirsFirst));
- QCOMPARE(containedFiles.size() + containedDirs.size(), list.size());
+ QCOMPARE(list.size(), containedFiles.size() + containedDirs.size());
for (i=0; i<list.size(); ++i) {
QString expectedName;
@@ -414,38 +472,62 @@ void tst_QResourceEngine::checkStructure()
// check that it is still valid after closing the file
file.close();
QCOMPARE(ba, contents);
+
+ // memory should be writable because we used MapPrivateOption
+ *ptr = '\0';
+
+ // but shouldn't affect the actual file or a new mapping
+ QFile file2(pathName);
+ QVERIFY(file2.open(QFile::ReadOnly));
+ QCOMPARE(file2.readAll(), contents);
+ ptr = file2.map(0, file.size(), QFile::MapPrivateOption);
+ QVERIFY2(ptr, qPrintable(file2.errorString()));
+ QByteArrayView bav(reinterpret_cast<const char *>(ptr), file.size());
+ QCOMPARE(bav, contents);
}
QLocale::setDefault(QLocale::system());
}
void tst_QResourceEngine::searchPath_data()
{
+ auto searchPath = QFileInfo(QFINDTESTDATA("testqrc/test.qrc")).canonicalPath();
+
+ QTest::addColumn<QString>("searchPathPrefix");
QTest::addColumn<QString>("searchPath");
QTest::addColumn<QString>("file");
QTest::addColumn<QByteArray>("expected");
- QTest::newRow("no_search_path") << QString()
- << ":search_file.txt"
- << QByteArray("root\n");
- QTest::newRow("path1") << "/searchpath1"
- << ":search_file.txt"
- << QByteArray("path1\n");
- QTest::newRow("no_search_path2") << QString()
- << ":/search_file.txt"
- << QByteArray("root\n");
- QTest::newRow("path2") << "/searchpath2"
- << ":search_file.txt"
- << QByteArray("path2\n");
+ QTest::newRow("no_search_path")
+ << QString()
+ << QString()
+ << ":search_file.txt"
+ << QByteArray("root\n");
+ QTest::newRow("path1")
+ << "searchpath1"
+ << searchPath
+ << "searchpath1:searchpath1/search_file.txt"
+ << QByteArray("path1\n");
+ QTest::newRow("no_search_path2")
+ << QString()
+ << QString()
+ << ":/search_file.txt"
+ << QByteArray("root\n");
+ QTest::newRow("path2")
+ << "searchpath2"
+ << searchPath + "/searchpath2"
+ << "searchpath2:search_file.txt"
+ << QByteArray("path2\n");
}
void tst_QResourceEngine::searchPath()
{
+ QFETCH(QString, searchPathPrefix);
QFETCH(QString, searchPath);
QFETCH(QString, file);
QFETCH(QByteArray, expected);
- if(!searchPath.isEmpty())
- QDir::addResourceSearchPath(searchPath);
+ if (!searchPath.isEmpty())
+ QDir::addSearchPath(searchPathPrefix, searchPath);
QFile qf(file);
QVERIFY(qf.open(QFile::ReadOnly));
QByteArray actual = qf.readAll();
@@ -482,6 +564,15 @@ void tst_QResourceEngine::checkUnregisterResource()
QVERIFY(QFile::exists(file_check));
QVERIFY(QResource::unregisterResource(rcc_file, root));
QVERIFY(!QFile::exists(file_check));
+ {
+ // QTBUG-86088
+ QVERIFY(QResource::registerResource(rcc_file, root));
+ QFile file(file_check);
+ QVERIFY(file.open(QFile::ReadOnly));
+ QVERIFY(!QResource::unregisterResource(rcc_file, root));
+ file.close();
+ QVERIFY(!QFile::exists(file_check));
+ }
QVERIFY(QResource::registerResource(rcc_file, root));
QVERIFY(QFile::exists(file_check));
QFileInfo fileInfo(file_check);
@@ -498,22 +589,31 @@ void tst_QResourceEngine::doubleSlashInRoot()
QVERIFY(QFile::exists("://secondary_root/runtime_resource/search_file.txt"));
}
+void tst_QResourceEngine::setLocale_data()
+{
+ QTest::addColumn<QString>("prefix");
+ QTest::newRow("built-in") << QString();
+ QTest::newRow("runtime") << "/runtime_resource/";
+}
+
void tst_QResourceEngine::setLocale()
{
+ QFETCH(QString, prefix);
QLocale::setDefault(QLocale::c());
// default constructed QResource gets the default locale
QResource resource;
- resource.setFileName("aliasdir/aliasdir.txt");
- QVERIFY(!resource.isCompressed());
+ resource.setFileName(prefix + "aliasdir/aliasdir.txt");
+ QVERIFY(resource.isValid());
+ QCOMPARE(resource.compressionAlgorithm(), QResource::NoCompression);
// change the default locale and make sure it doesn't affect the resource
QLocale::setDefault(QLocale("de_CH"));
- QVERIFY(!resource.isCompressed());
+ QCOMPARE(resource.compressionAlgorithm(), QResource::NoCompression);
// then explicitly set the locale on qresource
resource.setLocale(QLocale("de_CH"));
- QVERIFY(resource.isCompressed());
+ QVERIFY(resource.compressionAlgorithm() != QResource::NoCompression);
// the reset the default locale back
QLocale::setDefault(QLocale::system());
@@ -543,6 +643,14 @@ void tst_QResourceEngine::resourcesInStaticPlugins()
QVERIFY(QFile::exists(":/staticplugin/main.cpp"));
}
+void tst_QResourceEngine::qtResourceEmpty()
+{
+ QFile f(":/empty/world.txt");
+ QVERIFY(f.exists());
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ QVERIFY(f.readAll().isEmpty());
+}
+
QTEST_MAIN(tst_QResourceEngine)
#include "tst_qresourceengine.moc"
diff --git a/tests/auto/corelib/io/qresourceengine/uncompressed.rcc b/tests/auto/corelib/io/qresourceengine/uncompressed.rcc
new file mode 100644
index 0000000000..4b009f73d5
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/uncompressed.rcc
Binary files differ
diff --git a/tests/auto/corelib/io/qresourceengine/world.txt b/tests/auto/corelib/io/qresourceengine/world.txt
new file mode 100644
index 0000000000..ce01362503
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/world.txt
@@ -0,0 +1 @@
+hello
diff --git a/tests/auto/corelib/io/qresourceengine/zlib.rcc b/tests/auto/corelib/io/qresourceengine/zlib.rcc
new file mode 100644
index 0000000000..66f79fa630
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/zlib.rcc
Binary files differ
diff --git a/tests/auto/corelib/io/qresourceengine/zstd.rcc b/tests/auto/corelib/io/qresourceengine/zstd.rcc
new file mode 100644
index 0000000000..672fa05d14
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/zstd.rcc
Binary files differ
diff --git a/tests/auto/corelib/io/qsavefile/CMakeLists.txt b/tests/auto/corelib/io/qsavefile/CMakeLists.txt
new file mode 100644
index 0000000000..26869eb163
--- /dev/null
+++ b/tests/auto/corelib/io/qsavefile/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsavefile Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsavefile LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "tst_qsavefile.cpp")
+
+qt_internal_add_test(tst_qsavefile
+ SOURCES
+ tst_qsavefile.cpp
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/corelib/io/qsavefile/qsavefile.pro b/tests/auto/corelib/io/qsavefile/qsavefile.pro
deleted file mode 100644
index dd22d69ce6..0000000000
--- a/tests/auto/corelib/io/qsavefile/qsavefile.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsavefile
-QT = core testlib
-SOURCES = tst_qsavefile.cpp
-TESTDATA += tst_qsavefile.cpp
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index f1327933c4..c027f8a3c1 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -1,45 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 David Faure <faure@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2012 David Faure <faure@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSaveFile>
#include <qcoreapplication.h>
#include <qstring.h>
+#include <qsystemdetection.h>
#include <qtemporaryfile.h>
#include <qfile.h>
#include <qdir.h>
#include <qset.h>
-#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
+#if defined(Q_OS_UNIX)
#include <unistd.h> // for geteuid
#endif
#if defined(Q_OS_WIN)
-# include <windows.h>
+# include <qt_windows.h>
+#endif
+
+#ifdef Q_OS_INTEGRITY
+#include "qplatformdefs.h"
#endif
// Restore permissions so that the QTemporaryDir cleanup can happen
@@ -109,23 +90,40 @@ void tst_QSaveFile::transactionalWrite()
QCOMPARE(file.fileName(), targetFile);
QVERIFY(!QFile::exists(targetFile));
- QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ const char *data = "Hello";
+ QCOMPARE(file.write(data), qint64(strlen(data)));
QCOMPARE(file.error(), QFile::NoError);
QVERIFY(!QFile::exists(targetFile));
+ QVERIFY(file.fileTime(QFile::FileModificationTime).isValid());
QVERIFY(file.commit());
QVERIFY(QFile::exists(targetFile));
QCOMPARE(file.fileName(), targetFile);
+#if defined(Q_OS_WIN)
+ // Without this delay, file.fileTime() and file.size() tests fail to
+ // pass on Windows in the CI. It passes locally in a VM, so it looks like
+ // it depends on how often different filesystems on different OSes, update
+ // their metadata.
+ // Interestingly, this delay is enough to fix similar tests in the rest
+ // of tst_QSaveFile's functions.
+ QTRY_VERIFY(file.fileTime(QFile::FileModificationTime).isValid());
+#else
+ QVERIFY(file.fileTime(QFile::FileModificationTime).isValid());
+#endif
+
+ QCOMPARE(file.size(), qint64(strlen(data)));
QFile reader(targetFile);
QVERIFY(reader.open(QIODevice::ReadOnly));
- QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("Hello"));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1(data));
+ QCOMPARE(file.fileTime(QFile::FileModificationTime),
+ reader.fileTime(QFile::FileModificationTime));
// check that permissions are the same as for QFile
const QString otherFile = dir.path() + QString::fromLatin1("/otherfile");
QFile::remove(otherFile);
QFile other(otherFile);
- other.open(QIODevice::WriteOnly);
+ QVERIFY(other.open(QIODevice::WriteOnly));
other.close();
QCOMPARE(QFile::permissions(targetFile), QFile::permissions(otherFile));
}
@@ -136,16 +134,21 @@ void tst_QSaveFile::retryTransactionalWrite()
{
#ifndef Q_OS_UNIX
QSKIP("This test is Unix only");
-#endif
+#else
+ // root can open the read-only file for writing...
+ if (geteuid() == 0)
+ QSKIP("This test does not work as the root user");
+#endif //Q_OS_UNIX
QTemporaryDir dir;
QVERIFY2(dir.isValid(), qPrintable(dir.errorString()));
+ const char *data = "Hello";
QString targetFile = dir.path() + QLatin1String("/outfile");
const QString readOnlyName = targetFile + QLatin1String(".ro");
{
QFile readOnlyFile(readOnlyName);
QVERIFY2(readOnlyFile.open(QIODevice::WriteOnly), msgCannotOpen(readOnlyFile).constData());
- readOnlyFile.write("Hello");
+ readOnlyFile.write(data);
readOnlyFile.close();
auto permissions = readOnlyFile.permissions();
permissions &= ~(QFileDevice::WriteOwner | QFileDevice::WriteGroup | QFileDevice::WriteUser);
@@ -158,13 +161,15 @@ void tst_QSaveFile::retryTransactionalWrite()
file.setFileName(targetFile);
QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData());
QVERIFY(file.isOpen());
- QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ QCOMPARE(file.write(data), qint64(strlen(data)));
QCOMPARE(file.error(), QFile::NoError);
QVERIFY(file.commit());
+ QCOMPARE(file.size(), qint64(strlen(data)));
}
void tst_QSaveFile::saveTwice()
{
+ const char *hello = "Hello";
// Check that we can reuse a QSaveFile object
// (and test the case of an existing target file)
QTemporaryDir dir;
@@ -172,16 +177,19 @@ void tst_QSaveFile::saveTwice()
const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
QSaveFile file(targetFile);
QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData());
- QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ QCOMPARE(file.write(hello), qint64(strlen(hello)));
QVERIFY2(file.commit(), qPrintable(file.errorString()));
+ QCOMPARE(file.size(), qint64(strlen(hello)));
+ const char *world = "World";
QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData());
- QCOMPARE(file.write("World"), Q_INT64_C(5));
+ QCOMPARE(file.write(world), qint64(strlen(world)));
QVERIFY2(file.commit(), qPrintable(file.errorString()));
+ QCOMPARE(file.size(), qint64(strlen(world)));
QFile reader(targetFile);
QVERIFY2(reader.open(QIODevice::ReadOnly), msgCannotOpen(reader).constData());
- QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("World"));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1(world));
}
void tst_QSaveFile::textStreamManualFlush()
@@ -192,16 +200,18 @@ void tst_QSaveFile::textStreamManualFlush()
QSaveFile file(targetFile);
QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData());
+ const char *data = "Manual flush";
QTextStream ts(&file);
- ts << "Manual flush";
+ ts << data;
ts.flush();
QCOMPARE(file.error(), QFile::NoError);
QVERIFY(!QFile::exists(targetFile));
QVERIFY(file.commit());
+ QCOMPARE(file.size(), qint64(strlen(data)));
QFile reader(targetFile);
QVERIFY(reader.open(QIODevice::ReadOnly));
- QCOMPARE(QString::fromLatin1(reader.readAll().constData()), QString::fromLatin1("Manual flush"));
+ QCOMPARE(QString::fromLatin1(reader.readAll().constData()), QString::fromLatin1(data));
QFile::remove(targetFile);
}
@@ -356,7 +366,7 @@ void tst_QSaveFile::transactionalWriteErrorRenaming()
#ifdef Q_OS_UNIX
// Make rename() fail for lack of permissions in the directory
QFile dirAsFile(dir.path()); // yay, I have to use QFile to change a dir's permissions...
- QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions
+ QVERIFY(dirAsFile.setPermissions(QFile::Permissions{})); // no permissions
PermissionRestorer permissionRestorer(dir.path());
#else
// Windows: Make rename() fail for lack of permissions on an existing target file
@@ -448,6 +458,7 @@ void tst_QSaveFile::symlink()
QVERIFY(saveFile.open(QIODevice::WriteOnly));
QCOMPARE(saveFile.write(someData), someData.size());
saveFile.commit();
+ QCOMPARE(saveFile.size(), someData.size());
QFile file(targetFile);
QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData());
@@ -477,6 +488,7 @@ void tst_QSaveFile::symlink()
QVERIFY(saveFile.open(QIODevice::WriteOnly));
QCOMPARE(saveFile.write(someData), someData.size());
saveFile.commit();
+ QCOMPARE(saveFile.size(), someData.size());
// the explicit file becomes a file instead of a link
QVERIFY(!QFileInfo(cyclicLink + QLatin1Char('1')).isSymLink());
@@ -556,6 +568,7 @@ void tst_QSaveFile::alternateDataStream()
QVERIFY2(file.open(QIODevice::WriteOnly), qPrintable(file.errorString()));
file.write(newContent);
QVERIFY2(file.commit(), qPrintable(file.errorString()));
+ QCOMPARE(file.size(), qint64(strlen(newContent)));
// check the contents
QFile targetFile(adsName);
diff --git a/tests/auto/corelib/io/qsettings/.gitattributes b/tests/auto/corelib/io/qsettings/.gitattributes
index a4ad8d7644..920df33b54 100644
--- a/tests/auto/corelib/io/qsettings/.gitattributes
+++ b/tests/auto/corelib/io/qsettings/.gitattributes
@@ -1,5 +1,3 @@
resourcefile.ini -crlf
resourcefile2.ini -crlf
resourcefile3.ini -crlf
-resourcefile4.ini -crlf
-resourcefile5.ini -crlf
diff --git a/tests/auto/corelib/io/qsettings/CMakeLists.txt b/tests/auto/corelib/io/qsettings/CMakeLists.txt
new file mode 100644
index 0000000000..e68b2644af
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/CMakeLists.txt
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsettings Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsettings LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Test:
+set(qsettings_resource_files
+ "bom.ini"
+ "resourcefile.ini"
+ "resourcefile2.ini"
+ "resourcefile3.ini"
+ "resourcefile6.plist"
+ "withcomments.ini"
+ "float.ini"
+ "qt5settings.ini"
+ "utf8settings.ini"
+)
+
+qt_internal_add_test(tst_qsettings
+ SOURCES
+ tst_qsettings.cpp
+ INCLUDE_DIRECTORIES
+ ../../kernel/qmetatype
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ TESTDATA ${qsettings_resource_files}
+ BUILTIN_TESTDATA
+)
+
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qsettings CONDITION MSVC
+ LIBRARIES
+ advapi32
+)
+
+qt_internal_extend_target(tst_qsettings CONDITION APPLE
+ LIBRARIES
+ ${FWCoreFoundation}
+)
diff --git a/tests/auto/corelib/io/qsettings/float.ini b/tests/auto/corelib/io/qsettings/float.ini
new file mode 100644
index 0000000000..bf9312c14c
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/float.ini
@@ -0,0 +1,3 @@
+[test]
+float=0.5
+float_qvariant=@Variant(\0\0\0\x87?\0\0\0)
diff --git a/tests/auto/corelib/io/qsettings/qsettings.pro b/tests/auto/corelib/io/qsettings/qsettings.pro
deleted file mode 100644
index 79552b62df..0000000000
--- a/tests/auto/corelib/io/qsettings/qsettings.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsettings
-QT = core-private gui testlib
-SOURCES = tst_qsettings.cpp
-RESOURCES += qsettings.qrc
-INCLUDEPATH += $$PWD/../../kernel/qmetatype
-
-msvc: LIBS += advapi32.lib
-darwin: LIBS += -framework CoreFoundation
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qsettings/qsettings.qrc b/tests/auto/corelib/io/qsettings/qsettings.qrc
deleted file mode 100644
index db1d8c663f..0000000000
--- a/tests/auto/corelib/io/qsettings/qsettings.qrc
+++ /dev/null
@@ -1,12 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>resourcefile.ini</file>
- <file>resourcefile2.ini</file>
- <file>resourcefile3.ini</file>
- <file>resourcefile4.ini</file>
- <file>resourcefile5.ini</file>
- <file>resourcefile6.plist</file>
- <file>bom.ini</file>
- <file>withcomments.ini</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/io/qsettings/qt5settings.ini b/tests/auto/corelib/io/qsettings/qt5settings.ini
new file mode 100644
index 0000000000..59239d29f3
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/qt5settings.ini
@@ -0,0 +1,11 @@
+[General]
+.%2C%27%25U%U0430%U0431%U0432%U0433%22%09=".,'%!@#$"
+%U265F=\x2658\x265a
+%UD83C%UDF0D=\xd83c\xdf10
+
+[Test]
+BAR=BAR
+B%C4R=B\xc4R
+OST=OST
+%D6SE=\xd6SE
+%U042D%U0442%U043E\%U0442%U0435%U0441%U0442=\x42d\x442\x43e \x442\x435\x441\x442
diff --git a/tests/auto/corelib/io/qsettings/resourcefile4.ini b/tests/auto/corelib/io/qsettings/resourcefile4.ini
deleted file mode 100644
index 09c21b1591..0000000000
--- a/tests/auto/corelib/io/qsettings/resourcefile4.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[Fa%E7ade]
-QU%C9BEC=Façade/QUÉBEC
diff --git a/tests/auto/corelib/io/qsettings/resourcefile5.ini b/tests/auto/corelib/io/qsettings/resourcefile5.ini
deleted file mode 100644
index d2d2103560..0000000000
--- a/tests/auto/corelib/io/qsettings/resourcefile5.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[Fa%E7ade]
-QU%C9BEC=Faade/QUBEC
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index 8b69518ef7..f4d7f076ef 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -1,49 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QtCore/QSettings>
#include <private/qsettings_p.h>
+
+#include "tst_qmetatype_common.h"
+
#include <QtCore/QCoreApplication>
-#include <QtCore/QDateTime>
-#include <QtCore/QtGlobal>
-#include <QtCore/QMetaType>
-#include <QtCore/QString>
#include <QtCore/QDir>
+#include <QtCore/QEventLoop>
+#include <QtCore/QtGlobal>
#include <QtCore/QThread>
#include <QtCore/QSysInfo>
-#include <QtGui/QKeySequence>
-
-#include <QtCore>
-#include <QtGui>
-#include "tst_qmetatype.h"
+#if QT_CONFIG(shortcut)
+# include <QtGui/QKeySequence>
+#endif
#include <cctype>
#include <stdlib.h>
@@ -54,14 +27,28 @@
#if defined(Q_OS_WIN)
#include <QtCore/qt_windows.h>
+#include <private/qwinregistry_p.h>
+#define QT_UNLINK _unlink
#else
#include <unistd.h>
+#define QT_UNLINK unlink
#endif
#if defined(Q_OS_DARWIN)
#include <CoreFoundation/CoreFoundation.h>
#endif
+#ifdef Q_OS_INTEGRITY
+#include "qplatformdefs.h"
+#endif
+
+#if defined(Q_OS_WASM)
+#include <QtCore/private/qstdweb_p.h>
+
+#include "emscripten/threading.h"
+#include "emscripten/val.h"
+#endif
+
Q_DECLARE_METATYPE(QSettings::Format)
#ifndef QSETTINGS_P_H_VERSION
@@ -72,7 +59,7 @@ QT_FORWARD_DECLARE_CLASS(QSettings)
static inline bool canWriteNativeSystemSettings()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
HKEY key;
const LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software", 0, KEY_WRITE, &key);
if (result == ERROR_SUCCESS)
@@ -99,6 +86,20 @@ static inline bool canWriteNativeSystemSettings()
static const char insufficientPermissionSkipMessage[] = "Insufficient permissions for this test.";
+static void populateWithFormats()
+{
+ QTest::addColumn<QSettings::Format>("format");
+
+ QTest::newRow("native") << QSettings::NativeFormat;
+#if defined(Q_OS_WASM)
+ if (qstdweb::haveJspi())
+ QTest::newRow("idb") << QSettings::WebIndexedDBFormat;
+#endif // defined(Q_OS_WASM)
+ QTest::newRow("ini") << QSettings::IniFormat;
+ QTest::newRow("custom1") << QSettings::CustomFormat1;
+ QTest::newRow("custom2") << QSettings::CustomFormat2;
+}
+
class tst_QSettings : public QObject
{
Q_OBJECT
@@ -111,8 +112,11 @@ public slots:
void cleanup() { cleanupTestFiles(); }
private slots:
void getSetCheck();
- void ctor_data();
+ void ctor_data() { populateWithFormats(); }
void ctor();
+#ifdef Q_OS_WASM
+ void idb();
+#endif
void beginGroup();
void setValue();
void remove();
@@ -123,16 +127,16 @@ private slots:
void syncAlternateDataStream();
#endif
void setFallbacksEnabled();
- void setFallbacksEnabled_data();
- void fromFile_data();
+ void setFallbacksEnabled_data() { populateWithFormats(); }
+ void fromFile_data() { populateWithFormats(); }
void fromFile();
- void testArrays_data();
+ void testArrays_data() { populateWithFormats(); }
void testArrays();
- void testCaseSensitivity_data();
+ void testCaseSensitivity_data() { populateWithFormats(); }
void testCaseSensitivity();
void testErrorHandling_data();
void testErrorHandling();
- void testChildKeysAndGroups_data();
+ void testChildKeysAndGroups_data() { populateWithFormats(); }
void testChildKeysAndGroups();
void testUpdateRequestEvent();
void testThreadSafety();
@@ -142,10 +146,10 @@ private slots:
void testRegistryShortRootNames();
void testRegistry32And64Bit();
void trailingWhitespace();
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
void fileName();
#endif
- void isWritable_data();
+ void isWritable_data() { populateWithFormats(); }
void isWritable();
void registerFormat();
void setPath();
@@ -154,42 +158,45 @@ private slots:
#if !defined(Q_OS_WIN) && !defined(QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER)
void dontReorderIniKeysNeedlessly();
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
void consistentRegistryStorage();
#endif
#ifdef QT_BUILD_INTERNAL
- void allKeys_data();
+ void allKeys_data() { populateWithFormats(); }
void allKeys();
- void childGroups_data();
+ void childGroups_data() { populateWithFormats(); }
void childGroups();
- void childKeys_data();
+ void childKeys_data() { populateWithFormats(); }
void childKeys();
- void setIniCodec();
void testIniParsing_data();
void testIniParsing();
void testEscapes();
void testNormalizedKey_data();
void testNormalizedKey();
- void testVariantTypes_data();
+ void testVariantTypes_data() { populateWithFormats(); }
void testVariantTypes();
void testMetaTypes_data();
void testMetaTypes();
#endif
- void rainersSyncBugOnMac_data();
+ void rainersSyncBugOnMac_data() { populateWithFormats(); }
void rainersSyncBugOnMac();
void recursionBug();
void testByteArray_data();
void testByteArray();
void testByteArrayNativeFormat();
- void iniCodec();
void bom();
void embeddedZeroByte_data();
void embeddedZeroByte();
void spaceAfterComment();
+ void floatAsQVariant();
void testXdg();
+
+ void testReadKeys_data();
+ void testReadKeys();
+
private:
void cleanupTestFiles();
@@ -211,12 +218,7 @@ void tst_QSettings::getSetCheck()
static QString settingsPath(const char *path = nullptr)
{
// Temporary path for files that are specified explicitly in the constructor.
-#ifndef Q_OS_WINRT
static const QString tempPath = QDir::tempPath() + QLatin1String("/tst_QSettings");
-#else
- static const QString tempPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
- + QLatin1String("/tst_QSettings");
-#endif
return path && *path ? tempPath + QLatin1Char('/') + QLatin1String(path) : tempPath;
}
@@ -277,16 +279,6 @@ static bool writeCustom3File(QIODevice &device, const QSettings::SettingsMap &ma
return true;
}
-static void populateWithFormats()
-{
- QTest::addColumn<QSettings::Format>("format");
-
- QTest::newRow("native") << QSettings::NativeFormat;
- QTest::newRow("ini") << QSettings::IniFormat;
- QTest::newRow("custom1") << QSettings::CustomFormat1;
- QTest::newRow("custom2") << QSettings::CustomFormat2;
-}
-
tst_QSettings::tst_QSettings()
: m_canWriteNativeSystemSettings(canWriteNativeSystemSettings())
{
@@ -311,14 +303,17 @@ void tst_QSettings::initTestCase()
void tst_QSettings::cleanupTestFiles()
{
- QSettings::setSystemIniPath(settingsPath("__system__"));
- QSettings::setUserIniPath(settingsPath("__user__"));
+ QSettings::setPath(QSettings::IniFormat, QSettings::SystemScope, settingsPath("__system__"));
+ QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, settingsPath("__system__"));
+
+ QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, settingsPath("__user__"));
+ QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, settingsPath("__user__"));
QDir settingsDir(settingsPath());
if (settingsDir.exists())
QVERIFY(settingsDir.removeRecursively());
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QSettings("HKEY_CURRENT_USER\\Software\\software.org", QSettings::NativeFormat).clear();
QSettings("HKEY_CURRENT_USER\\Software\\other.software.org", QSettings::NativeFormat).clear();
QSettings("HKEY_CURRENT_USER\\Software\\foo", QSettings::NativeFormat).clear();
@@ -333,7 +328,7 @@ void tst_QSettings::cleanupTestFiles()
QSettings("HKEY_LOCAL_MACHINE\\Software\\bat", QSettings::NativeFormat).clear();
QSettings("HKEY_LOCAL_MACHINE\\Software\\baz", QSettings::NativeFormat).clear();
}
-#elif defined(Q_OS_DARWIN) || defined(Q_OS_WINRT)
+#elif defined(Q_OS_DARWIN)
QSettings(QSettings::UserScope, "software.org", "KillerAPP").clear();
QSettings(QSettings::SystemScope, "software.org", "KillerAPP").clear();
QSettings(QSettings::UserScope, "other.software.org", "KillerAPP").clear();
@@ -343,15 +338,36 @@ void tst_QSettings::cleanupTestFiles()
QSettings(QSettings::UserScope, "other.software.org").clear();
QSettings(QSettings::SystemScope, "other.software.org").clear();
#endif
+#if defined(Q_OS_WASM)
+ emscripten::val::global("window")["localStorage"].call<void>("clear");
+ if (qstdweb::haveJspi()) {
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::UserScope, "software.org",
+ "KillerAPP")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::SystemScope, "software.org",
+ "KillerAPP")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::UserScope, "other.software.org",
+ "KillerAPP")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::SystemScope,
+ "other.software.org", "KillerAPP")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::UserScope, "software.org")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::SystemScope, "software.org")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::UserScope, "other.software.org")
+ .clear();
+ QSettings(QSettings::Format::WebIndexedDBFormat, QSettings::SystemScope,
+ "other.software.org")
+ .clear();
+ }
+#endif
const QString foo(QLatin1String("foo"));
-#if defined(Q_OS_WINRT)
- QSettings(foo, QSettings::NativeFormat).clear();
- QFile fooFile(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QLatin1Char('/') + foo);
-#else
QFile fooFile(foo);
-#endif
if (fooFile.exists())
QVERIFY2(fooFile.remove(), qPrintable(fooFile.errorString()));
}
@@ -360,11 +376,6 @@ void tst_QSettings::cleanupTestFiles()
Test the constructors and the assignment operator.
*/
-void tst_QSettings::ctor_data()
-{
- populateWithFormats();
-}
-
void tst_QSettings::ctor()
{
QFETCH(QSettings::Format, format);
@@ -527,14 +538,14 @@ void tst_QSettings::ctor()
QSettings settings5(format, QSettings::UserScope, "SoftWare.ORG", "killerApp");
bool caseSensitive = true;
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_DARWIN)
if (format == QSettings::NativeFormat) {
// more details in QMacSettingsPrivate::QMacSettingsPrivate(), organization was comify()-ed
- caseSensitive = settings5.fileName().contains("SoftWare.ORG");;
+ caseSensitive = settings5.fileName().contains("SoftWare.ORG");
} else {
caseSensitive = pathconf(settings5.fileName().toLatin1().constData(), _PC_CASE_SENSITIVE);
}
-#elif defined(Q_OS_WIN32) || defined(Q_OS_WINRT)
+#elif defined(Q_OS_WIN32)
caseSensitive = false;
#endif
if (caseSensitive)
@@ -580,7 +591,7 @@ void tst_QSettings::ctor()
QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 5);
- QCOMPARE(settings1.allKeys().count(), 6);
+ QCOMPARE(settings1.allKeys().size(), 6);
QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), -7);
QCOMPARE(settings2.value("alpha/beta/geometry/x").toInt(), 1);
@@ -588,7 +599,7 @@ void tst_QSettings::ctor()
QCOMPARE(settings2.value("alpha/beta/geometry/width").toInt(), 3);
QCOMPARE(settings2.value("alpha/beta/geometry/height").toInt(), 4);
QCOMPARE(settings2.value("alpha/gamma/splitter").toInt(), 5);
- QCOMPARE(settings2.allKeys().count(), 6);
+ QCOMPARE(settings2.allKeys().size(), 6);
}
{
@@ -599,7 +610,7 @@ void tst_QSettings::ctor()
QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 5);
- QCOMPARE(settings1.allKeys().count(), 6);
+ QCOMPARE(settings1.allKeys().size(), 6);
}
{
@@ -608,8 +619,8 @@ void tst_QSettings::ctor()
QCoreApplication::instance()->setOrganizationName("");
QCoreApplication::instance()->setApplicationName("");
QSettings settings;
-#if defined(Q_OS_MAC) || defined(Q_OS_WINRT)
- QEXPECT_FAIL("native", "Default settings on Mac/WinRT are valid, despite organization domain, name, and app name being null", Continue);
+#if defined(Q_OS_DARWIN)
+ QEXPECT_FAIL("native", "Default settings on Mac are valid, despite organization domain, name, and app name being null", Continue);
#endif
QCOMPARE(settings.status(), QSettings::AccessError);
QCoreApplication::instance()->setOrganizationName("software.org");
@@ -623,8 +634,8 @@ void tst_QSettings::ctor()
}
QSettings settings(format, QSettings::UserScope, "", "");
-#if defined(Q_OS_MAC) || defined(Q_OS_WINRT)
- QEXPECT_FAIL("native", "Default settings on Mac/WinRT are valid, despite organization domain, name, and app name being null", Continue);
+#if defined(Q_OS_DARWIN)
+ QEXPECT_FAIL("native", "Default settings on Mac are valid, despite organization domain, name, and app name being null", Continue);
#endif
QCOMPARE(settings.status(), QSettings::AccessError);
QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP");
@@ -648,6 +659,50 @@ void tst_QSettings::ctor()
}
}
+#if defined(Q_OS_WASM)
+void tst_QSettings::idb()
+{
+ if (!qstdweb::haveJspi())
+ QSKIP("JSPI needed for IndexedDB format");
+
+ QString systemScopeOrganizationWideFile;
+ {
+ QSettings settingsUserScopeAppSpecific(QSettings::Format::WebIndexedDBFormat,
+ QSettings::UserScope, "software.org", "KillerAPP");
+ QSettings settingsUserScopeOrganizationWide(QSettings::Format::WebIndexedDBFormat,
+ QSettings::UserScope, "software.org");
+ QSettings settingsSystemScopeAppSpecific(QSettings::Format::WebIndexedDBFormat,
+ QSettings::SystemScope, "software.org",
+ "KillerAPP");
+ QSettings settingsSystemScopeOrganizationWide(QSettings::Format::WebIndexedDBFormat,
+ QSettings::SystemScope, "software.org");
+
+ settingsSystemScopeOrganizationWide.setValue("testKey", 1);
+ systemScopeOrganizationWideFile = settingsSystemScopeOrganizationWide.fileName();
+ }
+
+ // Emscripten's memfs has a bug that makes a file appear twice in the hashmap.
+ while (QFile::exists(systemScopeOrganizationWideFile)) {
+ Q_ASSERT(QFile::remove(systemScopeOrganizationWideFile));
+ }
+
+ QEventLoop loop;
+ QTimer timer;
+ timer.setInterval(1);
+
+ connect(&timer, &QTimer::timeout, [&loop]() { loop.quit(); });
+ timer.start();
+
+ loop.exec();
+ {
+ QSettings settingsUserScopeAppSpecific(QSettings::Format::WebIndexedDBFormat,
+ QSettings::UserScope, "software.org", "KillerAPP");
+
+ QCOMPARE(settingsUserScopeAppSpecific.value("testKey").toInt(), 1);
+ }
+}
+#endif // Q_OS_WASM
+
void tst_QSettings::testByteArray_data()
{
QTest::addColumn<QByteArray>("data");
@@ -687,28 +742,6 @@ void tst_QSettings::testByteArrayNativeFormat()
#endif
}
-void tst_QSettings::iniCodec()
-{
- {
- QSettings settings("QtProject", "tst_qsettings");
- settings.setIniCodec("cp1251");
- QByteArray ba;
- ba.resize(256);
- for (int i = 0; i < ba.size(); i++)
- ba[i] = i;
- settings.setValue("array",ba);
- }
- {
- QSettings settings("QtProject", "tst_qsettings");
- settings.setIniCodec("cp1251");
- QByteArray ba = settings.value("array").toByteArray();
- QCOMPARE(ba.size(), 256);
- for (int i = 0; i < ba.size(); i++)
- QCOMPARE((uchar)ba.at(i), (uchar)i);
- }
-
-}
-
void tst_QSettings::bom()
{
QSettings s(":/bom.ini", QSettings::IniFormat);
@@ -736,6 +769,10 @@ void tst_QSettings::embeddedZeroByte_data()
QTest::newRow("@bytearray\\0") << QVariant(bytes);
QTest::newRow("@string\\0") << QVariant(QString::fromLatin1(bytes.data(), bytes.size()));
+
+ bytes = QByteArray("@\xdd\x7d", 3);
+ QTest::newRow("@-prefixed data") << QVariant(bytes);
+ QTest::newRow("@-prefixed data as string") << QVariant(QString::fromLatin1(bytes.data(), bytes.size()));
}
void tst_QSettings::embeddedZeroByte()
@@ -749,11 +786,11 @@ void tst_QSettings::embeddedZeroByte()
QSettings settings("QtProject", "tst_qsettings");
QVariant outValue = settings.value(QTest::currentDataTag());
- switch (value.type()) {
- case QVariant::ByteArray:
+ switch (value.typeId()) {
+ case QMetaType::QByteArray:
QCOMPARE(outValue.toByteArray(), value.toByteArray());
break;
- case QVariant::String:
+ case QMetaType::QString:
QCOMPARE(outValue.toString(), value.toString());
break;
default:
@@ -793,6 +830,20 @@ void tst_QSettings::spaceAfterComment()
settings.endGroup();
}
+// test if a qvariant-encoded float can be read
+void tst_QSettings::floatAsQVariant()
+{
+ QVERIFY(QFile::exists(":/float.ini"));
+ QSettings s(":/float.ini", QSettings::IniFormat);
+
+ s.beginGroup("test");
+ QCOMPARE(s.value("float").toDouble(), 0.5);
+ QCOMPARE(s.value("float_qvariant").toDouble(), 0.5);
+
+ QCOMPARE(s.value("float").toFloat(), 0.5);
+ QCOMPARE(s.value("float_qvariant").toFloat(), 0.5);
+}
+
void tst_QSettings::testErrorHandling_data()
{
QTest::addColumn<int>("filePerms"); // -1 means file should not exist
@@ -957,11 +1008,12 @@ void tst_QSettings::testIniParsing()
if ( settings.status() == QSettings::NoError ) { // else no point proceeding
QVariant v = settings.value(key);
- QVERIFY(v.canConvert(expect.type()));
+ if (expect.isValid())
+ QVERIFY(v.canConvert(expect.metaType()));
// check some types so as to give prettier error messages
- if ( v.type() == QVariant::String ) {
+ if ( v.typeId() == QMetaType::QString ) {
QCOMPARE(v.toString(), expect.toString());
- } else if ( v.type() == QVariant::Int ) {
+ } else if ( v.typeId() == QMetaType::Int ) {
QCOMPARE(v.toInt(), expect.toInt());
} else {
QCOMPARE(v, expect);
@@ -1117,6 +1169,14 @@ void tst_QSettings::setValue()
settings.setValue("key 2", QString("false"));
QCOMPARE(settings.value("key 2", true).toBool(), false);
+ settings.setValue("key 2", double(1234.56));
+ QCOMPARE(settings.value("key 2").toDouble(), double(1234.56));
+ QCOMPARE(settings.value("key 2").toString().left(7), QString::number(double(1234.56)));
+
+ settings.setValue("key 2", float(1234.56));
+ QCOMPARE(settings.value("key 2").toFloat(), float(1234.56));
+ QCOMPARE(settings.value("key 2").toString().left(7), QString::number(float(1234.56)));
+
// The following block should not compile.
/*
settings.setValue("key 2", "true");
@@ -1143,7 +1203,7 @@ void tst_QSettings::setValue()
QCOMPARE(settings.value("key 2").toStringList(), QStringList() << "" << "a" << "" << "bc" << "");
settings.setValue("key 3", QList<QVariant>());
- QCOMPARE(settings.value("key 3").toList(), QList<QVariant>());
+ QVERIFY(settings.value("key 3").toList().isEmpty());
settings.setValue("key 3", QList<QVariant>() << 1 << QString("a"));
QCOMPARE(settings.value("key 3").toList(), QList<QVariant>() << 1 << QString("a"));
@@ -1177,7 +1237,7 @@ template<int MetaTypeId>
static void testMetaTypesHelper(QSettings::Format format)
{
typedef typename MetaEnumToType<MetaTypeId>::Type Type;
- const char *key = QMetaType::typeName(MetaTypeId);
+ const char *key = QMetaType(MetaTypeId).name();
Type *value = TestValueFactory<MetaTypeId>::create();
QVariant inputVariant = QVariant::fromValue(*value);
@@ -1196,8 +1256,8 @@ static void testMetaTypesHelper(QSettings::Format format)
QSettings settings(format, scope, organization, applicationName);
QVariant outputVariant = settings.value(key);
if (MetaTypeId != QMetaType::QVariant)
- QVERIFY(outputVariant.canConvert(MetaTypeId));
- if (outputVariant.type() != inputVariant.type())
+ QVERIFY(outputVariant.canConvert(QMetaType(MetaTypeId)));
+ if (outputVariant.typeId() != inputVariant.typeId())
qWarning() << "type mismatch between" << inputVariant << "and" << outputVariant;
QCOMPARE(qvariant_cast<Type >(outputVariant), *value);
}
@@ -1236,7 +1296,7 @@ void tst_QSettings::testMetaTypes_data()
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
{ \
const char *formatName = QMetaEnum::fromType<QSettings::Format>().valueToKey(formats[i]); \
- const char *typeName = QMetaType::typeName(QMetaType::MetaTypeName); \
+ const char *typeName = QMetaType(QMetaType::MetaTypeName).name(); \
QTest::newRow(QString("%1:%2").arg(formatName).arg(typeName).toLatin1().constData()) \
<< QSettings::Format(formats[i]) << int(QMetaType::MetaTypeName); \
}
@@ -1271,102 +1331,102 @@ FOR_EACH_CORE_METATYPE(RETURN_CREATE_FUNCTION)
TypeTestFunctionGetter::get(type)(format);
}
-
-void tst_QSettings::testVariantTypes_data()
-{
- populateWithFormats();
-}
#endif
#ifdef QT_BUILD_INTERNAL
void tst_QSettings::testVariantTypes()
{
-#define testVal(key, val, tp, rtype) \
- { \
- QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP"); \
- settings1.setValue(key, QVariant::fromValue(val)); \
- } \
- QConfFile::clearCache(); \
- { \
- QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP"); \
- QVariant v = settings2.value(key); \
- QVERIFY(qvariant_cast<tp >(v) == val); \
- QVERIFY(v.type() == QVariant::rtype); \
+ QFETCH(QSettings::Format, format);
+
+ {
+ QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QVERIFY(!settings.contains("empty"));
+ QCOMPARE(settings.value("empty"), QVariant());
+
+ settings.setValue("empty", QVariant());
+ QVERIFY(settings.contains("empty"));
+ QCOMPARE(settings.value("empty"), QVariant());
+
+ settings.setValue("empty", QVariant(1));
+ QVERIFY(settings.contains("empty"));
+ QCOMPARE(settings.value("empty"), QVariant(1));
+
+ settings.setValue("empty", QVariant());
+ QVERIFY(settings.contains("empty"));
+ QCOMPARE(settings.value("empty"), QVariant());
+
+ settings.remove("empty");
+ QVERIFY(!settings.contains("empty"));
+ QCOMPARE(settings.value("empty"), QVariant());
}
- typedef QMap<QString, QVariant> TestVariantMap;
+ auto checker = [format](const char *key, auto value, QMetaType::Type expected) {
+ {
+ QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
+ settings.setValue(key, QVariant::fromValue(value));
+ }
+ QConfFile::clearCache();
+ {
+ QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
+ QVariant actual = settings.value(key);
+ QCOMPARE(actual.metaType().id(), expected);
+ QCOMPARE(qvariant_cast<decltype(value)>(actual), value);
+ }
+ };
+#define testValue(key, supplied, expected) do { \
+ checker(key, supplied, QMetaType::expected); \
+ if (QTest::currentTestFailed()) \
+ return; \
+ } while (0)
- QFETCH(QSettings::Format, format);
+ typedef QMap<QString, QVariant> TestVariantMap;
TestVariantMap m2;
m2.insert("ene", "due");
m2.insert("rike", "fake");
m2.insert("borba", "dorba");
- testVal("key2", m2, TestVariantMap, Map);
-
- QStringList l2;
+ testValue("customMap", m2, QVariantMap);
- l2 << "ene" << "due" << "@Point(1 2)" << "@fake";
- testVal("key3", l2, QStringList, StringList);
+ QStringList l2 { "ene", "due", "@Point(1 2)", "@fake" };
+ testValue("stringsAt", l2, QStringList);
- l2.clear();
- l2 << "ene" << "due" << "rike" << "fake";
- testVal("key3", l2, QStringList, StringList);
+ l2 = { "ene", "due", "rike", "fake" };
+ testValue("strings", l2, QStringList);
- QList<QVariant> l3;
QDate date = QDate::currentDate();
QTime time = QTime::currentTime();
- l3 << QString("ene") << 10 << QVariant::fromValue(QColor(1, 2, 3)) << QVariant(QRect(1, 2, 3, 4))
- << QVariant(QSize(4, 56)) << QVariant(QPoint(4, 2)) << true << false << date << time;
- testVal("key3", l3, QVariantList, List);
-
- testVal("key4", QString("hello"), QString, String);
- testVal("key5", QColor(1, 2, 3), QColor, Color);
- testVal("key6", QRect(1, 2, 3, 4), QRect, Rect);
- testVal("key7", QSize(4, 56), QSize, Size);
- testVal("key8", QPoint(4, 2), QPoint, Point);
- testVal("key10", date, QDate, Date);
- testVal("key11", time, QTime, Time);
- testVal("key12", QByteArray("foo bar"), QByteArray, ByteArray);
+ QList<QVariant> l3 { QString("ene"), 10, QVariant::fromValue(QColor(1, 2, 3)),
+ QVariant(QRect(1, 2, 3, 4)), QVariant(QSize(4, 56)), QVariant(QPoint(4, 2)),
+ true, false, date, time };
+ testValue("mixedList", l3, QVariantList);
+
+ testValue("string", QString("hello"), QString);
+ testValue("color", QColor(1, 2, 3), QColor);
+ testValue("rect", QRect(1, 2, 3, 4), QRect);
+ testValue("size", QSize(4, 56), QSize);
+ testValue("point", QPoint(4, 2), QPoint);
+ testValue("date", date, QDate);
+ testValue("time", time, QTime);
+ testValue("byteArray", QByteArray("foo bar"), QByteArray);
+
+ QList<QVariant> l4 { QVariant(m2), QVariant(l2), QVariant(l3) };
+ testValue("collectList", l4, QVariantList);
- {
- QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
- QVERIFY(!settings.contains("key99"));
- QCOMPARE(settings.value("key99"), QVariant());
-
- settings.setValue("key99", QVariant());
- QVERIFY(settings.contains("key99"));
- QCOMPARE(settings.value("key99"), QVariant());
-
- settings.setValue("key99", QVariant(1));
- QVERIFY(settings.contains("key99"));
- QCOMPARE(settings.value("key99"), QVariant(1));
-
- settings.setValue("key99", QVariant());
- QVERIFY(settings.contains("key99"));
- QCOMPARE(settings.value("key99"), QVariant());
-
- settings.remove("key99");
- QVERIFY(!settings.contains("key99"));
- QCOMPARE(settings.value("key99"), QVariant());
- }
-
- QList<QVariant> l4;
- l4 << QVariant(m2) << QVariant(l2) << QVariant(l3);
- testVal("key13", l4, QVariantList, List);
QDateTime dt = QDateTime::currentDateTime();
- dt.setOffsetFromUtc(3600);
- testVal("key14", dt, QDateTime, DateTime);
+ dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(3600));
+ testValue("dateTime", dt, QDateTime);
+#if QT_CONFIG(shortcut)
// We store key sequences as strings instead of binary variant blob, for improved
// readability in the resulting format.
- if (format >= QSettings::InvalidFormat) {
- testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QKeySequence, KeySequence);
- } else {
- testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QString, String);
- }
+ QKeySequence seq(Qt::ControlModifier | Qt::Key_F1);
+ if (format >= QSettings::InvalidFormat)
+ testValue("keySequence", seq, QKeySequence);
+ else
+ testValue("keySequence", seq.toString(QKeySequence::NativeText), QString);
+#endif // QT_CONFIG(shortcut)
-#undef testVal
+#undef testValue
}
#endif
@@ -1736,14 +1796,9 @@ void tst_QSettings::sync()
// Now "some other app" will change other.software.org.ini
QString userConfDir = settingsPath("__user__") + QDir::separator();
-#if !defined(Q_OS_WINRT)
- unlink((userConfDir + "other.software.org.ini").toLatin1());
+ QT_UNLINK((userConfDir + "other.software.org.ini").toLatin1());
rename((userConfDir + "software.org.ini").toLatin1(),
(userConfDir + "other.software.org.ini").toLatin1());
-#else
- QFile::remove(userConfDir + "other.software.org.ini");
- QFile::rename(userConfDir + "software.org.ini" , userConfDir + "other.software.org.ini");
-#endif
settings2.sync();
@@ -1761,12 +1816,12 @@ void tst_QSettings::sync()
QCOMPARE(settings2.value("moo/beta/geometry/width").toInt(), 3);
QCOMPARE(settings2.value("moo/beta/geometry/height").toInt(), 4);
QCOMPARE(settings2.value("moo/gamma/splitter").toInt(), 5);
- QCOMPARE(settings2.allKeys().count(), 11);
+ QCOMPARE(settings2.allKeys().size(), 11);
// Now, software.org.ini no longer exists, this is same as another app
// clearing all settings.
settings1.sync();
- QCOMPARE(settings1.allKeys().count(), 0);
+ QCOMPARE(settings1.allKeys().size(), 0);
// Now "some other app" will change software.org.ini
QVERIFY(QFile::rename((userConfDir + "other.software.org.ini").toLatin1(),
@@ -1784,7 +1839,7 @@ void tst_QSettings::sync()
QCOMPARE(settings1.value("moo/beta/geometry/width").toInt(), 3);
QCOMPARE(settings1.value("moo/beta/geometry/height").toInt(), 4);
QCOMPARE(settings1.value("moo/gamma/splitter").toInt(), 5);
- QCOMPARE(settings1.allKeys().count(), 11);
+ QCOMPARE(settings1.allKeys().size(), 11);
}
void tst_QSettings::syncNonWriteableDir()
@@ -1859,11 +1914,6 @@ void tst_QSettings::syncAlternateDataStream()
}
#endif
-void tst_QSettings::setFallbacksEnabled_data()
-{
- populateWithFormats();
-}
-
void tst_QSettings::setFallbacksEnabled()
{
QFETCH(QSettings::Format, format);
@@ -1948,11 +1998,6 @@ void tst_QSettings::setFallbacksEnabled()
QVERIFY(!settings1.contains("key 5"));
}
-void tst_QSettings::testChildKeysAndGroups_data()
-{
- populateWithFormats();
-}
-
void tst_QSettings::testChildKeysAndGroups()
{
QFETCH(QSettings::Format, format);
@@ -2013,6 +2058,24 @@ void tst_QSettings::testChildKeysAndGroups()
l.sort();
QCOMPARE(l, QStringList() << "bar" << "foo");
}
+
+#if defined(Q_OS_WASM)
+ // WebIndexedDBFormat does not use the cached settings file on creation, but instead always uses
+ // the file from the indexed DB anew.
+ if (format == QSettings::Format::WebIndexedDBFormat)
+ settings1.sync();
+#endif
+
+ {
+ QSettings settings3(format, QSettings::UserScope, "software.org", "application");
+ settings3.setFallbacksEnabled(false);
+ settings3.beginGroup("alpha");
+ QCOMPARE(settings3.childGroups(), QStringList());
+ settings3.setFallbacksEnabled(true);
+ QStringList children = settings3.childGroups();
+ children.sort();
+ QCOMPARE(children, QStringList({"beta", "gamma"}));
+ }
}
void tst_QSettings::testUpdateRequestEvent()
@@ -2058,7 +2121,7 @@ int numThreadSafetyFailures;
class SettingsThread : public QThread
{
public:
- void run();
+ void run() override;
void start(int n) { param = n; QThread::start(); }
private:
@@ -2072,7 +2135,7 @@ void SettingsThread::run()
settings.setValue(QString::number((param * NumIterations) + i), param);
settings.sync();
if (settings.status() != QSettings::NoError) {
- QWARN(qPrintable(QString("Unexpected QSettings status %1").arg((int)settings.status())));
+ qWarning() << qPrintable(QString("Unexpected QSettings status %1").arg((int)settings.status()));
++numThreadSafetyFailures;
}
}
@@ -2080,6 +2143,16 @@ void SettingsThread::run()
void tst_QSettings::testThreadSafety()
{
+#if !QT_CONFIG(thread)
+ QSKIP("This test requires threads to be enabled.");
+#endif // !QT_CONFIG(thread)
+#if defined(Q_OS_WASM)
+ if (!qstdweb::haveJspi())
+ QSKIP("Test needs jspi on WASM. Calls are proxied to the main thread from SettingsThreads, "
+ "which necessitates the use of an event loop to yield to the main loop. Event loops "
+ "require jspi.");
+#endif
+
SettingsThread threads[NumThreads];
int i, j;
@@ -2087,6 +2160,19 @@ void tst_QSettings::testThreadSafety()
for (i = 0; i < NumThreads; ++i)
threads[i].start(i + 1);
+
+#if defined(Q_OS_WASM) && QT_CONFIG(thread)
+ QEventLoop loop;
+ int remaining = NumThreads;
+ for (int i = 0; i < NumThreads; ++i) {
+ QObject::connect(&threads[i], &QThread::finished, this, [&remaining, &loop]() {
+ if (!--remaining)
+ loop.quit();
+ });
+ }
+ loop.exec();
+#endif // defined(Q_OS_WASM) && QT_CONFIG(thread)
+
for (i = 0; i < NumThreads; ++i)
threads[i].wait();
@@ -2141,20 +2227,17 @@ void tst_QSettings::testNormalizedKey()
inKey.detach();
- QString result = QSettingsPrivate::normalizedKey(inKey);
- QCOMPARE(result, outKey);
-
- /*
- If the key is already normalized, we verify that outKey is
- just a shallow copy of the input string. This is an important
- optimization that shouldn't be removed accidentally.
- */
- if (inKey == outKey) {
- QVERIFY(!result.isDetached());
- } else {
- if (!result.isEmpty()) {
- QVERIFY(result.isDetached());
- }
+ {
+ auto result = QSettingsPrivate::normalizedKey(inKey);
+ QCOMPARE(result, outKey);
+ }
+ {
+ auto result = QSettingsPrivate::normalizedKey(QUtf8StringView{inKey.toUtf8()});
+ QCOMPARE(result, outKey);
+ }
+ {
+ auto result = QSettingsPrivate::normalizedKey(QLatin1String{inKey.toLatin1()});
+ QCOMPARE(result, outKey);
}
}
#endif
@@ -2180,6 +2263,8 @@ void tst_QSettings::testEmptyData()
vList2 << emptyString << nullString;
vList3 << QString("foo");
+ const auto rm = QScopeGuard([=] { QFile::remove(filename); });
+
{
QSettings settings(filename, QSettings::IniFormat);
settings.setValue("nullString", nullString);
@@ -2233,7 +2318,6 @@ void tst_QSettings::testEmptyData()
QCOMPARE(settings.value("vList3").toList(), vList3);
QCOMPARE(settings.status(), QSettings::NoError);
}
- QFile::remove(filename);
}
void tst_QSettings::testEmptyKey()
@@ -2277,7 +2361,7 @@ void tst_QSettings::testRegistryShortRootNames()
void tst_QSettings::testRegistry32And64Bit()
{
-#if !defined (Q_OS_WIN) || defined(Q_OS_WINRT)
+#if !defined (Q_OS_WIN)
QSKIP("This test is specific to the Windows registry.", SkipAll);
#else
@@ -2323,14 +2407,15 @@ void tst_QSettings::testRegistry32And64Bit()
void tst_QSettings::trailingWhitespace()
{
+ const QString path = settingsPath("trailingWhitespace");
{
- QSettings s("tst_QSettings_trailingWhitespace");
+ QSettings s(path, QSettings::IniFormat);
s.setValue("trailingSpace", "x ");
s.setValue("trailingTab", "x\t");
s.setValue("trailingNewline", "x\n");
}
{
- QSettings s("tst_QSettings_trailingWhitespace");
+ QSettings s(path, QSettings::IniFormat);
QCOMPARE(s.value("trailingSpace").toString(), QLatin1String("x "));
QCOMPARE(s.value("trailingTab").toString(), QLatin1String("x\t"));
QCOMPARE(s.value("trailingNewline").toString(), QLatin1String("x\n"));
@@ -2338,11 +2423,6 @@ void tst_QSettings::trailingWhitespace()
}
}
-void tst_QSettings::fromFile_data()
-{
- populateWithFormats();
-}
-
void tst_QSettings::fromFile()
{
QFETCH(QSettings::Format, format);
@@ -2357,13 +2437,19 @@ void tst_QSettings::fromFile()
QString path = "foo";
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
if (format == QSettings::NativeFormat)
path = "\\HKEY_CURRENT_USER\\Software\\foo";
#endif
QStringList strList = QStringList() << "hope" << "destiny" << "chastity";
+#if !defined(Q_OS_WIN)
+ auto deleteFile = QScopeGuard([path, oldCur]() {
+ QFile::remove(path);
+ QDir::setCurrent(oldCur);
+ });
+#endif // !defined(Q_OS_WIN)
{
QSettings settings1(path, format);
QVERIFY(settings1.allKeys().isEmpty());
@@ -2399,75 +2485,8 @@ void tst_QSettings::fromFile()
QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
QCOMPARE(settings1.allKeys().size(), 3);
}
-
- QDir::setCurrent(oldCur);
}
-#ifdef QT_BUILD_INTERNAL
-void tst_QSettings::setIniCodec()
-{
- QByteArray expeContents4, expeContents5;
- QByteArray actualContents4, actualContents5;
-
- {
- QFile inFile(":/resourcefile4.ini");
- inFile.open(QIODevice::ReadOnly);
- expeContents4 = inFile.readAll();
- inFile.close();
- }
-
- {
- QFile inFile(":/resourcefile5.ini");
- inFile.open(QIODevice::ReadOnly);
- expeContents5 = inFile.readAll();
- inFile.close();
- }
-
- {
- QSettings settings4(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
- settings4.setIniCodec("UTF-8");
- settings4.setValue(QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"), QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"));
- settings4.sync();
-
- QSettings settings5(QSettings::IniFormat, QSettings::UserScope, "other.software.org", "KillerAPP");
- settings5.setIniCodec("ISO 8859-1");
- settings5.setValue(QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"), QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"));
- settings5.sync();
-
- {
- QFile inFile(settings4.fileName());
- inFile.open(QIODevice::ReadOnly | QIODevice::Text);
- actualContents4 = inFile.readAll();
- inFile.close();
- }
-
- {
- QFile inFile(settings5.fileName());
- inFile.open(QIODevice::ReadOnly | QIODevice::Text);
- actualContents5 = inFile.readAll();
- inFile.close();
- }
- }
-
- QConfFile::clearCache();
-
- QCOMPARE(actualContents4, expeContents4);
- QCOMPARE(actualContents5, expeContents5);
-
- QSettings settings4(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
- settings4.setIniCodec("UTF-8");
- QSettings settings5(QSettings::IniFormat, QSettings::UserScope, "other.software.org", "KillerAPP");
- settings5.setIniCodec("Latin-1");
-
- QCOMPARE(settings4.allKeys().count(), 1);
- QCOMPARE(settings5.allKeys().count(), 1);
-
- QCOMPARE(settings4.allKeys().first(), settings5.allKeys().first());
- QCOMPARE(settings4.value(settings4.allKeys().first()).toString(),
- settings5.value(settings5.allKeys().first()).toString());
-}
-#endif
-
static bool containsSubList(QStringList mom, QStringList son)
{
for (int i = 0; i < son.size(); ++i) {
@@ -2477,11 +2496,6 @@ static bool containsSubList(QStringList mom, QStringList son)
return true;
}
-void tst_QSettings::testArrays_data()
-{
- populateWithFormats();
-}
-
/*
Tests beginReadArray(), beginWriteArray(), endArray(), and
setArrayIndex().
@@ -2547,17 +2561,17 @@ void tst_QSettings::testArrays()
QCOMPARE(settings1.value("ene").toInt(), 2);
QCOMPARE(settings1.value("due").toInt(), 3);
QCOMPARE(settings1.value("rike").toInt(), 4);
- QCOMPARE(settings1.allKeys().count(), 3);
+ QCOMPARE(settings1.allKeys().size(), 3);
settings1.setArrayIndex(1);
QCOMPARE(settings1.value("ene").toInt(), 5);
QCOMPARE(settings1.value("due").toInt(), 6);
QCOMPARE(settings1.value("rike").toInt(), 7);
- QCOMPARE(settings1.allKeys().count(), 3);
+ QCOMPARE(settings1.allKeys().size(), 3);
settings1.setArrayIndex(2);
QCOMPARE(settings1.value("ene").toInt(), 8);
QCOMPARE(settings1.value("due").toInt(), 9);
QCOMPARE(settings1.value("rike").toInt(), 10);
- QCOMPARE(settings1.allKeys().count(), 3);
+ QCOMPARE(settings1.allKeys().size(), 3);
settings1.endArray();
settings1.endGroup();
@@ -2607,17 +2621,17 @@ void tst_QSettings::testArrays()
QCOMPARE(settings1.value("ene").toInt(), 2);
QCOMPARE(settings1.value("due").toInt(), 3);
QCOMPARE(settings1.value("rike").toInt(), 4);
- QCOMPARE(settings1.allKeys().count(), 3);
+ QCOMPARE(settings1.allKeys().size(), 3);
settings1.setArrayIndex(1);
QCOMPARE(settings1.value("ene").toInt(), 5);
QCOMPARE(settings1.value("due").toInt(), 6);
QCOMPARE(settings1.value("rike").toInt(), 7);
- QCOMPARE(settings1.allKeys().count(), 3);
+ QCOMPARE(settings1.allKeys().size(), 3);
settings1.setArrayIndex(2);
QCOMPARE(settings1.value("ene").toInt(), 8);
QCOMPARE(settings1.value("due").toInt(), 9);
QCOMPARE(settings1.value("rike").toInt(), 10);
- QCOMPARE(settings1.allKeys().count(), 3);
+ QCOMPARE(settings1.allKeys().size(), 3);
settings1.endArray();
settings1.endGroup();
@@ -2762,14 +2776,14 @@ static QByteArray iniEscapedKey(const QString &str)
static QString iniUnescapedKey(const QByteArray &ba)
{
QString result;
- QSettingsPrivate::iniUnescapedKey(ba, 0, ba.size(), result);
+ QSettingsPrivate::iniUnescapedKey(ba, result);
return result;
}
static QByteArray iniEscapedStringList(const QStringList &strList)
{
QByteArray result;
- QSettingsPrivate::iniEscapedStringList(strList, result, 0);
+ QSettingsPrivate::iniEscapedStringList(strList, result);
return result;
}
@@ -2777,23 +2791,9 @@ static QStringList iniUnescapedStringList(const QByteArray &ba)
{
QStringList result;
QString str;
-#if QSETTINGS_P_H_VERSION >= 2
- bool isStringList = QSettingsPrivate::iniUnescapedStringList(ba, 0, ba.size(), str, result
-#if QSETTINGS_P_H_VERSION >= 3
- , 0
-#endif
- );
+ bool isStringList = QSettingsPrivate::iniUnescapedStringList(ba, str, result);
if (!isStringList)
result = QStringList(str);
-#else
- QStringList *strList = QSettingsPrivate::iniUnescapedStringList(ba, 0, ba.size(), str);
- if (strList) {
- result = *strList;
- delete strList;
- } else {
- result = QStringList(str);
- }
-#endif
return result;
}
#endif
@@ -2803,7 +2803,7 @@ QString escapeWeirdChars(const QString &s)
QString result;
bool escapeNextDigit = false;
- for (int i = 0; i < s.length(); ++i) {
+ for (int i = 0; i < s.size(); ++i) {
QChar c = s.at(i);
if (c.unicode() < ' ' || c.unicode() > '~'
|| (escapeNextDigit && c.unicode() >= '0' && c.unicode() <= 'f')) {
@@ -2892,8 +2892,8 @@ void tst_QSettings::testEscapes()
testEscapedStringList(QChar(0) + QString("0"), "\\0\\x30");
testEscapedStringList("~!@#$%^&*()_+.-/\\=", "\"~!@#$%^&*()_+.-/\\\\=\"");
testEscapedStringList("~!@#$%^&*()_+.-/\\", "~!@#$%^&*()_+.-/\\\\");
- testEscapedStringList(QString("\x7F") + "12aFz", "\\x7f\\x31\\x32\\x61\\x46z");
- testEscapedStringList(QString(" \t\n\\n") + QChar(0x123) + QChar(0x4567), "\" \\t\\n\\\\n\\x123\\x4567\"");
+ testEscapedStringList(QString("\x7F") + "12aFz", QByteArray("\x7f") + "12aFz");
+ testEscapedStringList(QString(" \t\n\\n") + QChar(0x123) + QChar(0x4567), "\" \\t\\n\\\\n\xC4\xA3\xE4\x95\xA7\"");
testEscapedStringList(QString("\a\b\f\n\r\t\v'\"?\001\002\x03\x04"), "\\a\\b\\f\\n\\r\\t\\v'\\\"?\\x1\\x2\\x3\\x4");
testEscapedStringList(QStringList() << "," << ";" << "a" << "ab, \tc, d ", "\",\", \";\", a, \"ab, \\tc, d \"");
@@ -2908,7 +2908,7 @@ void tst_QSettings::testEscapes()
QString() + QChar(0) + QChar(0) + QChar(0) + QChar(0) + QChar(1)
+ QChar(0111) + QChar(011111) + QChar(0) + QChar(0xCDEF) + "GH"
+ QChar(0x3456),
- "\\0\\0\\0\\0\\x1I\\x1249\\0\\xcdefGH\\x3456");
+ "\\0\\0\\0\\0\\x1I\xE1\x89\x89\\0\xEC\xB7\xAFGH\xE3\x91\x96");
testUnescapedStringList(QByteArray("\\c\\d\\e\\f\\g\\$\\*\\\0", 16), "\f", "\\f");
testUnescapedStringList("\"a\", \t\"bc \", \" d\" , \"ef \" ,,g, hi i,,, ,",
QStringList() << "a" << "bc " << " d" << "ef " << "" << "g" << "hi i"
@@ -2923,8 +2923,6 @@ void tst_QSettings::testEscapes()
testVariant(QString("Hello, World!"), QString("Hello, World!"), toString);
testVariant(QString("@Hello World!"), QString("@@Hello World!"), toString);
testVariant(QString("@@Hello World!"), QString("@@@Hello World!"), toString);
- testVariant(QByteArray("Hello World!"), QString("@ByteArray(Hello World!)"), toString);
- testVariant(QByteArray("@Hello World!"), QString("@ByteArray(@Hello World!)"), toString);
testVariant(QVariant(100), QString("100"), toString);
testVariant(QStringList() << "ene" << "due" << "rike", QString::fromLatin1("@Variant(\x0\x0\x0\xb\x0\x0\x0\x3\x0\x0\x0\x6\x0\x65\x0n\x0\x65\x0\x0\x0\x6\x0\x64\x0u\x0\x65\x0\x0\x0\x8\x0r\x0i\x0k\x0\x65)", 50), toStringList);
testVariant(QRect(1, 2, 3, 4), QString("@Rect(1 2 3 4)"), toRect);
@@ -2945,11 +2943,6 @@ void tst_QSettings::testEscapes()
}
#endif
-void tst_QSettings::testCaseSensitivity_data()
-{
- populateWithFormats();
-}
-
void tst_QSettings::testCaseSensitivity()
{
QFETCH(QSettings::Format, format);
@@ -3029,7 +3022,7 @@ void tst_QSettings::testCaseSensitivity()
}
}
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
// Please write a fileName() test for the other platforms
void tst_QSettings::fileName()
{
@@ -3099,11 +3092,6 @@ void tst_QSettings::fileName()
}
#endif
-void tst_QSettings::isWritable_data()
-{
- populateWithFormats();
-}
-
void tst_QSettings::isWritable()
{
QFETCH(QSettings::Format, format);
@@ -3133,7 +3121,7 @@ void tst_QSettings::isWritable()
QSettings s3(format, QSettings::SystemScope, "foo.org", "Something Different");
if (s1.status() == QSettings::NoError && s1.contains("foo")) {
-#if defined(Q_OS_MACX)
+#if defined(Q_OS_MACOS)
QVERIFY(s1.isWritable());
if (format == QSettings::NativeFormat) {
QVERIFY(!s2.isWritable());
@@ -3156,13 +3144,6 @@ void tst_QSettings::isWritable()
}
#ifdef QT_BUILD_INTERNAL
-void tst_QSettings::childGroups_data()
-{
- populateWithFormats();
-}
-#endif
-
-#ifdef QT_BUILD_INTERNAL
void tst_QSettings::childGroups()
{
QFETCH(QSettings::Format, format);
@@ -3232,13 +3213,6 @@ void tst_QSettings::childGroups()
#endif
#ifdef QT_BUILD_INTERNAL
-void tst_QSettings::childKeys_data()
-{
- populateWithFormats();
-}
-#endif
-
-#ifdef QT_BUILD_INTERNAL
void tst_QSettings::childKeys()
{
QFETCH(QSettings::Format, format);
@@ -3306,13 +3280,6 @@ void tst_QSettings::childKeys()
#endif
#ifdef QT_BUILD_INTERNAL
-void tst_QSettings::allKeys_data()
-{
- populateWithFormats();
-}
-#endif
-
-#ifdef QT_BUILD_INTERNAL
void tst_QSettings::allKeys()
{
QFETCH(QSettings::Format, format);
@@ -3463,7 +3430,7 @@ void tst_QSettings::setPath()
path checks that it has no bad side effects.
*/
for (int i = 0; i < 2; ++i) {
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) && !defined(Q_OS_WASM)
TEST_PATH(i == 0, "conf", NativeFormat, UserScope, "alpha")
TEST_PATH(i == 0, "conf", NativeFormat, SystemScope, "beta")
#endif
@@ -3572,19 +3539,20 @@ void tst_QSettings::dontReorderIniKeysNeedlessly()
}
#endif
-void tst_QSettings::rainersSyncBugOnMac_data()
-{
- ctor_data();
-}
-
void tst_QSettings::rainersSyncBugOnMac()
{
QFETCH(QSettings::Format, format);
-#if defined(Q_OS_DARWIN) || defined(Q_OS_WINRT)
+#if defined(Q_OS_DARWIN)
if (format == QSettings::NativeFormat)
QSKIP("Apple OSes do not support direct reads from and writes to .plist files, due to caching and background syncing. See QTBUG-34899.");
#endif
+#if defined(Q_OS_WASM)
+ if (format == QSettings::NativeFormat)
+ QSKIP("WASM's localStorage backend recognizes no concept of file");
+ if (format == QSettings::WebIndexedDBFormat)
+ QSKIP("WASM's indexedDB backend uses the virtual FS file only as a backing store");
+#endif // Q_OS_WASM
QString fileName;
@@ -3608,7 +3576,7 @@ void tst_QSettings::rainersSyncBugOnMac()
void tst_QSettings::recursionBug()
{
QPixmap pix(10,10);
- pix.fill("blue");
+ pix.fill(Qt::blue);
{
QSettings settings(settingsPath("starrunner.ini"), QSettings::IniFormat);
@@ -3616,18 +3584,15 @@ void tst_QSettings::recursionBug()
}
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
-static DWORD readKeyType(HKEY handle, const QString &rSubKey)
+static DWORD readKeyType(HKEY handle, QStringView rSubKey)
{
DWORD dataType;
DWORD dataSize;
- LONG res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()), 0, &dataType, 0, &dataSize);
-
- if (res == ERROR_SUCCESS)
- return dataType;
-
- return 0;
+ LONG res = RegQueryValueEx(handle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()),
+ nullptr, &dataType, nullptr, &dataSize);
+ return res == ERROR_SUCCESS ? dataType : 0;
}
// This is a regression test for QTBUG-13249, where QSettings was storing
@@ -3647,42 +3612,25 @@ void tst_QSettings::consistentRegistryStorage()
QCOMPARE(settings1.value("quint64_value").toULongLong(), (quint64)1024);
settings1.sync();
- HKEY handle;
- LONG res;
- QString keyName = "Software\\software.org\\KillerAPP";
- res = RegOpenKeyEx(HKEY_CURRENT_USER, reinterpret_cast<const wchar_t *>(keyName.utf16()), 0, KEY_READ, &handle);
- if (res == ERROR_SUCCESS)
- {
- DWORD dataType;
- dataType = readKeyType(handle, QString("qint32_value"));
- if (dataType != 0) {
- QCOMPARE((int)REG_DWORD, (int)dataType);
- }
- dataType = readKeyType(handle, QString("quint32_value"));
- if (dataType != 0) {
- QCOMPARE((int)REG_DWORD, (int)dataType);
- }
- dataType = readKeyType(handle, QString("qint64_value"));
- if (dataType != 0) {
- QCOMPARE((int)REG_QWORD, (int)dataType);
- }
- dataType = readKeyType(handle, QString("quint64_value"));
- if (dataType != 0) {
- QCOMPARE((int)REG_QWORD, (int)dataType);
- }
+ QWinRegistryKey handle(HKEY_CURRENT_USER, LR"(Software\software.org\KillerAPP)");
+ if (handle.isValid()) {
+ QCOMPARE(readKeyType(handle, L"qint32_value"), DWORD(REG_DWORD));
+ QCOMPARE(readKeyType(handle, L"quint32_value"), DWORD(REG_DWORD));
+ QCOMPARE(readKeyType(handle, L"qint64_value"), DWORD(REG_QWORD));
+ QCOMPARE(readKeyType(handle, L"quint64_value"), DWORD(REG_QWORD));
RegCloseKey(handle);
}
}
#endif
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(QT_NO_STANDARDPATHS)
+#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WASM) && !defined(QT_NO_STANDARDPATHS)
QT_BEGIN_NAMESPACE
extern void clearDefaultPaths();
QT_END_NAMESPACE
#endif
void tst_QSettings::testXdg()
{
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(QT_NO_STANDARDPATHS)
+#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WASM) && !defined(QT_NO_STANDARDPATHS)
// Note: The XDG_CONFIG_DIRS test must be done before overriding the system path
// by QSettings::setPath/setSystemIniPath (used in cleanupTestFiles()).
clearDefaultPaths();
@@ -3747,5 +3695,39 @@ void tst_QSettings::testXdg()
#endif
}
+void tst_QSettings::testReadKeys_data()
+{
+ QTest::addColumn<QString>("filepath");
+
+ QTest::newRow("escaped") << ":/qt5settings.ini";
+ QTest::newRow("utf-8") << ":/utf8settings.ini";
+}
+
+void tst_QSettings::testReadKeys()
+{
+ QFETCH(QString, filepath);
+
+ QSettings settings(filepath, QSettings::IniFormat);
+ QCOMPARE(settings.status(), QSettings::NoError);
+
+ QVariantMap expectedValues;
+ expectedValues.insert("Test/BAR", "BAR");
+ expectedValues.insert("Test/OST", "OST");
+ expectedValues.insert("Test/B\xC3\x84R", "B\xC3\x84R"); // BÄR
+ expectedValues.insert("Test/\xC3\x96SE", "\xC3\x96SE"); // ÖSE
+ expectedValues.insert(
+ "Test/\xD0\xAD\xD1\x82\xD0\xBE/\xD1\x82\xD0\xB5\xD1\x81\xD1\x82", // Это/тест
+ "\xD0\xAD\xD1\x82\xD0\xBE \xD1\x82\xD0\xB5\xD1\x81\xD1\x82"); // Это тест
+ expectedValues.insert(".,'%U\xD0\xB0\xD0\xB1\xD0\xB2\xD0\xB3\"\t", ".,'%!@#$");
+ expectedValues.insert("\xE2\x99\x9F", "\xE2\x99\x98\xE2\x99\x9A"); // ♟︎ ♘♚
+ expectedValues.insert("\xF0\x9F\x8C\x8D", "\xF0\x9F\x8C\x90"); // 🌍 🌐
+
+ QVariantMap readValues;
+ for (const auto &key : settings.allKeys())
+ readValues.insert(key, settings.value(key));
+
+ QCOMPARE(readValues, expectedValues);
+}
+
QTEST_MAIN(tst_QSettings)
#include "tst_qsettings.moc"
diff --git a/tests/auto/corelib/io/qsettings/utf8settings.ini b/tests/auto/corelib/io/qsettings/utf8settings.ini
new file mode 100644
index 0000000000..bac010254f
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/utf8settings.ini
@@ -0,0 +1,11 @@
+[General]
+.%2C%27%25Uабвг%22%09=".,'%!@#$"
+♟=♘♚
+🌍=🌐
+
+[Test]
+BAR=BAR
+BÄR=BÄR
+OST=OST
+ÖSE=ÖSE
+Это\тест=Это тест
diff --git a/tests/auto/corelib/io/qstandardpaths/CMakeLists.txt b/tests/auto/corelib/io/qstandardpaths/CMakeLists.txt
new file mode 100644
index 0000000000..90bc0f3b70
--- /dev/null
+++ b/tests/auto/corelib/io/qstandardpaths/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstandardpaths Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstandardpaths LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "tst_qstandardpaths.cpp")
+
+qt_internal_add_test(tst_qstandardpaths
+ SOURCES
+ tst_qstandardpaths.cpp
+ TESTDATA ${test_data}
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qstandardpaths CONDITION boot2qt
+ DEFINES
+ SKIP_FINDEXECUTABLE
+)
diff --git a/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro b/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro
deleted file mode 100644
index 44b1ce8dd8..0000000000
--- a/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstandardpaths
-QT = core testlib
-INCLUDEPATH += ../../../../shared/
-HEADERS += ../../../../shared/emulationdetector.h
-SOURCES = tst_qstandardpaths.cpp
-TESTDATA += tst_qstandardpaths.cpp qstandardpaths.pro
-
-# QTBUG-64404
-boot2qt: DEFINES+=SKIP_FINDEXECUTABLE
diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
index 1379c788d1..4bb7042790 100644
--- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
+++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
@@ -1,55 +1,77 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
#include <qstandardpaths.h>
+#include <QTest>
+#include <QOperatingSystemVersion>
#include <qdebug.h>
-#include <qstandardpaths.h>
#include <qfileinfo.h>
+#include <qplatformdefs.h>
+#include <qregularexpression.h>
#include <qsysinfo.h>
-#include <qregexp.h>
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN)
# include <qt_windows.h>
#endif
#ifdef Q_OS_UNIX
#include <unistd.h>
#include <sys/types.h>
+#include <pwd.h>
#endif
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && !defined(Q_OS_ANDROID)
#define Q_XDG_PLATFORM
#endif
-#include "emulationdetector.h"
+using namespace Qt::StringLiterals;
// Update this when adding new enum values; update enumNames too
-static const int MaxStandardLocation = QStandardPaths::AppConfigLocation;
+static const int MaxStandardLocation = QStandardPaths::GenericStateLocation;
+
+static QString genericCacheLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation);
+}
+static QString cacheLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+}
+
+static QString genericStateLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::GenericStateLocation);
+}
+static QString stateLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::StateLocation);
+}
+
+static QString genericDataLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
+}
+static QString appDataLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
+}
+static QString appLocalDataLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
+}
+
+static QString genericConfigLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
+}
+static QString configLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
+}
+static QString appConfigLoc()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
+}
class tst_qstandardpaths : public QObject
{
@@ -58,6 +80,7 @@ class tst_qstandardpaths : public QObject
private slots:
void initTestCase();
void dump();
+ void init();
void testDefaultLocations();
void testCustomLocations();
void enableTestMode();
@@ -68,6 +91,7 @@ private slots:
void testFindExecutable();
void testFindExecutableLinkToDirectory();
void testRuntimeDirectory();
+ void testCustomRuntimeDirectory_data();
void testCustomRuntimeDirectory();
void testAllWritableLocations_data();
void testAllWritableLocations();
@@ -83,14 +107,17 @@ private:
qputenv("XDG_CONFIG_DIRS", QFile::encodeName(m_globalConfigDir));
m_localAppDir = m_localAppTempDir.path();
m_globalAppDir = m_globalAppTempDir.path();
+ m_stateDir = m_stateTempDir.path();
qputenv("XDG_DATA_HOME", QFile::encodeName(m_localAppDir));
qputenv("XDG_DATA_DIRS", QFile::encodeName(m_globalAppDir));
+ qputenv("XDG_STATE_HOME", QFile::encodeName(m_stateDir));
}
void setDefaultLocations() {
- qputenv("XDG_CONFIG_HOME", QByteArray());
- qputenv("XDG_CONFIG_DIRS", QByteArray());
- qputenv("XDG_DATA_HOME", QByteArray());
- qputenv("XDG_DATA_DIRS", QByteArray());
+ qputenv("XDG_CONFIG_HOME", nullptr);
+ qputenv("XDG_CONFIG_DIRS", nullptr);
+ qputenv("XDG_DATA_HOME", nullptr);
+ qputenv("XDG_DATA_DIRS", nullptr);
+ qputenv("XDG_STATE_HOME", nullptr);
}
#endif
@@ -105,6 +132,8 @@ private:
QTemporaryDir m_localAppTempDir;
QString m_globalAppDir;
QTemporaryDir m_globalAppTempDir;
+ QString m_stateDir;
+ QTemporaryDir m_stateTempDir;
};
static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths::DesktopLocation)] = {
@@ -117,7 +146,7 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths
"PicturesLocation",
"TempLocation",
"HomeLocation",
- "DataLocation",
+ "AppLocalDataLocation",
"CacheLocation",
"GenericDataLocation",
"RuntimeLocation",
@@ -126,12 +155,16 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths
"GenericCacheLocation",
"GenericConfigLocation",
"AppDataLocation",
- "AppConfigLocation"
+ "AppConfigLocation",
+ "PublicShareLocation",
+ "TemplatesLocation",
+ "StateLocation",
+ "GenericStateLocation"
};
void tst_qstandardpaths::initTestCase()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN)
// Disable WOW64 redirection, see testFindExecutable()
if (QSysInfo::buildCpuArchitecture() != QSysInfo::currentCpuArchitecture()) {
void *oldMode;
@@ -140,11 +173,12 @@ void tst_qstandardpaths::initTestCase()
qErrnoWarning("Wow64DisableWow64FsRedirection() failed");
QVERIFY(disabledDisableWow64FsRedirection);
}
-#endif // Q_OS_WIN && !Q_OS_WINRT && !Q_OS_WINCE
+#endif // Q_OS_WIN
QVERIFY2(m_localConfigTempDir.isValid(), qPrintable(m_localConfigTempDir.errorString()));
QVERIFY2(m_globalConfigTempDir.isValid(), qPrintable(m_globalConfigTempDir.errorString()));
QVERIFY2(m_localAppTempDir.isValid(), qPrintable(m_localAppTempDir.errorString()));
QVERIFY2(m_globalAppTempDir.isValid(), qPrintable(m_globalAppTempDir.errorString()));
+ QVERIFY2(m_stateTempDir.isValid(), qPrintable(m_stateTempDir.errorString()));
}
void tst_qstandardpaths::dump()
@@ -161,25 +195,37 @@ void tst_qstandardpaths::dump()
}
}
+void tst_qstandardpaths::init()
+{
+ // Some unittests set a custom org/app names, restore the original ones
+ // before each unittest is run
+ static const QString org = QCoreApplication::organizationName();
+ static const QString app = QCoreApplication::applicationName();
+ QCoreApplication::setOrganizationName(org);
+ QCoreApplication::setApplicationName(app);
+}
+
void tst_qstandardpaths::testDefaultLocations()
{
#ifdef Q_XDG_PLATFORM
setDefaultLocations();
const QString expectedConfHome = QDir::homePath() + QString::fromLatin1("/.config");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), expectedConfHome);
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), expectedConfHome);
+ QCOMPARE(configLoc(), expectedConfHome);
+ QCOMPARE(genericConfigLoc(), expectedConfHome);
const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation);
- QCOMPARE(confDirs.count(), 2);
+ QCOMPARE(confDirs.size(), 2);
QVERIFY(confDirs.contains(expectedConfHome));
QCOMPARE(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation), confDirs);
const QStringList genericDataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
- QCOMPARE(genericDataDirs.count(), 3);
+ QCOMPARE(genericDataDirs.size(), 3);
const QString expectedDataHome = QDir::homePath() + QString::fromLatin1("/.local/share");
QCOMPARE(genericDataDirs.at(0), expectedDataHome);
QCOMPARE(genericDataDirs.at(1), QString::fromLatin1("/usr/local/share"));
QCOMPARE(genericDataDirs.at(2), QString::fromLatin1("/usr/share"));
+ const QString expectedGenericStateLocation = QDir::homePath() + QString::fromLatin1("/.local/state");
+ QCOMPARE(genericStateLoc(), expectedGenericStateLocation);
#endif
}
@@ -198,8 +244,8 @@ void tst_qstandardpaths::testCustomLocations()
setCustomLocations();
// test writableLocation()
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), m_localConfigDir);
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), m_localConfigDir);
+ QCOMPARE(configLoc(), m_localConfigDir);
+ QCOMPARE(genericConfigLoc(), m_localConfigDir);
// test locate()
const QString thisFileName = QString::fromLatin1("aFile");
@@ -231,37 +277,76 @@ void tst_qstandardpaths::enableTestMode()
setCustomLocations(); // for the global config dir
const QString qttestDir = QDir::homePath() + QLatin1String("/.qttest");
- // ConfigLocation
+ // *Config*Location
const QString configDir = qttestDir + QLatin1String("/config");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), configDir);
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), configDir);
+ QCOMPARE(configLoc(), configDir);
+ QCOMPARE(genericConfigLoc(), configDir);
const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation);
QCOMPARE(confDirs, QStringList() << configDir << m_globalConfigDir);
+ // AppConfigLocation should be "GenericConfigLocation/organization-name/app-name"
+ QCOMPARE(appConfigLoc(), configDir + "/tst_qstandardpaths"_L1);
- // GenericDataLocation
+ // *Data*Location
const QString dataDir = qttestDir + QLatin1String("/share");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), dataDir);
+ QCOMPARE(genericDataLoc(), dataDir);
const QStringList gdDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
QCOMPARE(gdDirs, QStringList() << dataDir << m_globalAppDir);
+ // AppDataLocation/AppLocalDataLocation should be
+ // "GenericDataLocation/organization-name/app-name"
+ QCOMPARE(appDataLoc(), dataDir + "/tst_qstandardpaths"_L1);
+ QCOMPARE(appLocalDataLoc(), dataDir + "/tst_qstandardpaths"_L1);
- // GenericCacheLocation
+ // *CacheLocation
const QString cacheDir = qttestDir + QLatin1String("/cache");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation), cacheDir);
+ QCOMPARE(genericCacheLoc(), cacheDir);
const QStringList cacheDirs = QStandardPaths::standardLocations(QStandardPaths::GenericCacheLocation);
QCOMPARE(cacheDirs, QStringList() << cacheDir);
+ // CacheLocation should be "GenericCacheLocation/organization-name/app-name"
+ QCOMPARE(cacheLoc(), cacheDir + "/tst_qstandardpaths"_L1);
+
+ // *StateLocation
+ const QString stateDir = qttestDir + QLatin1String("/state");
+ QCOMPARE(genericStateLoc(), stateDir);
+ const QStringList stateDirs = QStandardPaths::standardLocations(QStandardPaths::GenericStateLocation);
+ QCOMPARE(stateDirs, QStringList() << stateDir);
+ // StateLocation should be "GenericStateLocation/organization-name/app-name"
+ QCOMPARE(stateLoc(), stateDir + "/tst_qstandardpaths"_L1);
+
+ QCoreApplication::setOrganizationName("Qt");
+ QCOMPARE(appConfigLoc(), configDir + "/Qt/tst_qstandardpaths"_L1);
+ QCOMPARE(appDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1);
+ QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/tst_qstandardpaths"_L1);
+ QCOMPARE(cacheLoc(), cacheDir + "/Qt/tst_qstandardpaths"_L1);
+ QCOMPARE(stateLoc(), stateDir + "/Qt/tst_qstandardpaths"_L1);
+
+ QCoreApplication::setApplicationName("QtTest");
+ QCOMPARE(appConfigLoc(), configDir + "/Qt/QtTest"_L1);
+ QCOMPARE(appDataLoc(), dataDir + "/Qt/QtTest"_L1);
+ QCOMPARE(appLocalDataLoc(), dataDir + "/Qt/QtTest"_L1);
+ QCOMPARE(cacheLoc(), cacheDir + "/Qt/QtTest"_L1);
+ QCOMPARE(stateLoc(), stateDir + "/Qt/QtTest"_L1);
+
+ // Check these are unaffected by org/app names
+ QCOMPARE(genericConfigLoc(), configDir);
+ QCOMPARE(configLoc(), configDir);
+ QCOMPARE(genericDataLoc(), dataDir);
+ QCOMPARE(genericCacheLoc(), cacheDir);
+ QCOMPARE(genericStateLoc(), stateDir);
#endif
// On all platforms, we want to ensure that the writableLocation is different in test mode and real mode.
// Check this for locations where test programs typically write. Not desktop, download, music etc...
typedef QHash<QStandardPaths::StandardLocation, QString> LocationHash;
LocationHash testLocations;
- testLocations.insert(QStandardPaths::AppDataLocation, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
- testLocations.insert(QStandardPaths::AppLocalDataLocation, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
- testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
- testLocations.insert(QStandardPaths::ConfigLocation, QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
- testLocations.insert(QStandardPaths::GenericConfigLocation, QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
- testLocations.insert(QStandardPaths::CacheLocation, QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
- testLocations.insert(QStandardPaths::GenericCacheLocation, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
+ testLocations.insert(QStandardPaths::AppDataLocation, appDataLoc());
+ testLocations.insert(QStandardPaths::AppLocalDataLocation, appLocalDataLoc());
+ testLocations.insert(QStandardPaths::GenericDataLocation, genericDataLoc());
+ testLocations.insert(QStandardPaths::ConfigLocation, configLoc());
+ testLocations.insert(QStandardPaths::GenericConfigLocation, genericConfigLoc());
+ testLocations.insert(QStandardPaths::CacheLocation, cacheLoc());
+ testLocations.insert(QStandardPaths::GenericCacheLocation, genericCacheLoc());
+ testLocations.insert(QStandardPaths::StateLocation, stateLoc());
+ testLocations.insert(QStandardPaths::GenericStateLocation, genericStateLoc());
// On Windows, what should "Program Files" become, in test mode?
//testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation));
@@ -283,7 +368,7 @@ void tst_qstandardpaths::testLocateAll()
#ifdef Q_XDG_PLATFORM
setCustomLocations();
const QStringList appsDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "applications", QStandardPaths::LocateDirectory);
- QCOMPARE(appsDirs.count(), 0); // they don't exist yet
+ QCOMPARE(appsDirs.size(), 0); // they don't exist yet
const QStringList expectedAppsDirs = QStringList() << m_localAppDir + QLatin1String("/applications")
<< m_globalAppDir + QLatin1String("/applications");
QDir().mkdir(expectedAppsDirs.at(0));
@@ -306,49 +391,42 @@ void tst_qstandardpaths::testLocateAll()
void tst_qstandardpaths::testDataLocation()
{
- // On all platforms, DataLocation should be GenericDataLocation / organization name / app name
+ // On all platforms, AppLocalDataLocation should be GenericDataLocation / organization name / app name
// This allows one app to access the data of another app.
- // Android and WinRT are an exception to this case, owing to the fact that
+ // Android is an exception to this case, owing to the fact that
// applications are sandboxed.
-#if !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT)
- const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/tst_qstandardpaths");
+#if !defined(Q_OS_ANDROID)
+ const QString base = genericDataLoc();
+ QCOMPARE(appLocalDataLoc(), base + "/tst_qstandardpaths");
QCoreApplication::instance()->setOrganizationName("Qt");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/Qt/tst_qstandardpaths");
+ QCOMPARE(appLocalDataLoc(), base + "/Qt/tst_qstandardpaths");
QCoreApplication::instance()->setApplicationName("QtTest");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), base + "/Qt/QtTest");
+ QCOMPARE(appLocalDataLoc(), base + "/Qt/QtTest");
#endif
#ifdef Q_XDG_PLATFORM
setDefaultLocations();
const QString expectedAppDataDir = QDir::homePath() + QString::fromLatin1("/.local/share/Qt/QtTest");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation), expectedAppDataDir);
+ QCOMPARE(appLocalDataLoc(), expectedAppDataDir);
const QStringList appDataDirs = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation);
- QCOMPARE(appDataDirs.count(), 3);
+ QCOMPARE(appDataDirs.size(), 3);
QCOMPARE(appDataDirs.at(0), expectedAppDataDir);
QCOMPARE(appDataDirs.at(1), QString::fromLatin1("/usr/local/share/Qt/QtTest"));
QCOMPARE(appDataDirs.at(2), QString::fromLatin1("/usr/share/Qt/QtTest"));
#endif
-
- // reset for other tests
- QCoreApplication::setOrganizationName(QString());
- QCoreApplication::setApplicationName(QString());
}
void tst_qstandardpaths::testAppConfigLocation()
{
// On all platforms where applications are not sandboxed,
// AppConfigLocation should be GenericConfigLocation / organization name / app name
-#if !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT)
- const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/tst_qstandardpaths");
+#if !defined(Q_OS_ANDROID)
+ const QString base = genericConfigLoc();
+ QCOMPARE(appConfigLoc(), base + "/tst_qstandardpaths");
QCoreApplication::setOrganizationName("Qt");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/Qt/tst_qstandardpaths");
+ QCOMPARE(appConfigLoc(), base + "/Qt/tst_qstandardpaths");
QCoreApplication::setApplicationName("QtTest");
- QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation), base + "/Qt/QtTest");
- // reset for other tests
- QCoreApplication::setOrganizationName(QString());
- QCoreApplication::setApplicationName(QString());
+ QCOMPARE(appConfigLoc(), base + "/Qt/QtTest");
#endif
}
@@ -360,10 +438,10 @@ static inline QFileInfo findSh()
QLatin1String sh("/sh");
QByteArray pEnv = qgetenv("PATH");
const QLatin1Char pathSep(':');
- const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, QString::SkipEmptyParts);
- foreach (const QString &path, rawPaths) {
+ const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, Qt::SkipEmptyParts);
+ for (const QString &path : rawPaths) {
if (QFile::exists(path + sh))
- return path + sh;
+ return QFileInfo(path + sh);
}
return QFileInfo();
}
@@ -381,7 +459,6 @@ void tst_qstandardpaths::testFindExecutable_data()
QTest::addColumn<QString>("needle");
QTest::addColumn<QString>("expected");
#ifdef Q_OS_WIN
-# ifndef Q_OS_WINRT
const QFileInfo cmdFi = QFileInfo(QDir::cleanPath(QString::fromLocal8Bit(qgetenv("COMSPEC"))));
const QString cmdPath = cmdFi.absoluteFilePath();
@@ -406,7 +483,6 @@ void tst_qstandardpaths::testFindExecutable_data()
QTest::newRow("win8-logo-nosuffix")
<< QString() << logo << logoPath;
}
-# endif // Q_OS_WINRT
#else
const QFileInfo shFi = findSh();
Q_ASSERT(shFi.exists());
@@ -448,8 +524,6 @@ void tst_qstandardpaths::testFindExecutable()
void tst_qstandardpaths::testFindExecutableLinkToDirectory()
{
- // WinRT has no link support
-#ifndef Q_OS_WINRT
// link to directory
const QString target = QDir::tempPath() + QDir::separator() + QLatin1String("link.lnk");
QFile::remove(target);
@@ -457,24 +531,205 @@ void tst_qstandardpaths::testFindExecutableLinkToDirectory()
QVERIFY(appFile.link(target));
QVERIFY(QStandardPaths::findExecutable(target).isEmpty());
QFile::remove(target);
-#endif
}
+using RuntimeDirSetup = std::optional<QString> (*)(QDir &);
+Q_DECLARE_METATYPE(RuntimeDirSetup);
+
void tst_qstandardpaths::testRuntimeDirectory()
{
#ifdef Q_XDG_PLATFORM
const QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
QVERIFY(!runtimeDir.isEmpty());
+#endif
+}
+
+// INTEGRITY PJF System doesn't support user ID related APIs. getpwuid is not defined.
+// testCustomRuntimeDirectory_data test will always FAIL for INTEGRITY.
+#if defined(Q_XDG_PLATFORM) && !defined(Q_OS_INTEGRITY)
+static QString fallbackXdgRuntimeDir()
+{
+ static QString username = [] {
+ struct passwd *pw = getpwuid(geteuid());
+ return QString::fromLocal8Bit(pw->pw_name);
+ }();
+
+ // QDir::temp() might change from call to call
+ return QDir::temp().filePath("runtime-" + username);
+}
+#endif
+
+[[maybe_unused]] static QString updateRuntimeDir(const QString &path)
+{
+ qputenv("XDG_RUNTIME_DIR", QFile::encodeName(path));
+ return path;
+}
+
+[[maybe_unused]] static void clearRuntimeDir()
+{
+ qunsetenv("XDG_RUNTIME_DIR");
+#ifdef Q_XDG_PLATFORM
+#if !defined(Q_OS_WASM) && !defined(Q_OS_INTEGRITY)
+ QTest::ignoreMessage(QtWarningMsg,
+ qPrintable("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '"
+ + fallbackXdgRuntimeDir() + '\''));
+#endif
+#endif
+}
+
+void tst_qstandardpaths::testCustomRuntimeDirectory_data()
+{
+#ifdef Q_OS_INTEGRITY
+ QSKIP("Test requires getgid/getpwuid API that are not available on INTEGRITY");
+#elif defined(Q_XDG_PLATFORM)
+ QTest::addColumn<RuntimeDirSetup>("setup");
+ auto addRow = [](const char *name, RuntimeDirSetup f) {
+ QTest::newRow(name) << f;
+ };
- // Check that it can automatically fix permissions
- QFile file(runtimeDir);
- const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser;
- const QFile::Permissions additionalPerms = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner;
- QCOMPARE(file.permissions(), wantedPerms | additionalPerms);
- QVERIFY(file.setPermissions(wantedPerms | QFile::ExeGroup));
- const QString runtimeDirAgain = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
- QCOMPARE(runtimeDirAgain, runtimeDir);
- QCOMPARE(QFile(runtimeDirAgain).permissions(), wantedPerms | additionalPerms);
+
+# if defined(Q_OS_UNIX)
+ if (::getuid() == 0)
+ QSKIP("Running this test as root doesn't make sense");
+# endif
+
+ addRow("environment:non-existing", [](QDir &d) -> std::optional<QString> {
+ return updateRuntimeDir(d.filePath("runtime"));
+ });
+
+ addRow("environment:existing", [](QDir &d) -> std::optional<QString> {
+ QString p = d.filePath("runtime");
+ d.mkdir("runtime");
+ QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
+ return updateRuntimeDir(p);
+ });
+
+ addRow("environment-to-existing-wrong-perm", [](QDir &d) -> std::optional<QString> {
+ QString p = d.filePath("runtime");
+ d.mkdir("runtime");
+ QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
+ QFile::ExeGroup | QFile::ExeOther);
+ updateRuntimeDir(p);
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: wrong permissions on runtime directory %1, "
+ "0711 instead of 0700")
+ .arg(p).toLatin1());
+ return fallbackXdgRuntimeDir();
+ });
+
+ addRow("environment:wrong-owner", [](QDir &) -> std::optional<QString> {
+ QT_STATBUF st;
+ QT_STAT("/", &st);
+
+ updateRuntimeDir("/");
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '/' is not owned by UID "
+ "%1, but a directory permissions %2 owned by UID %3 GID %4")
+ .arg(getuid())
+ .arg(st.st_mode & 07777, 4, 8, QChar('0'))
+ .arg(st.st_uid)
+ .arg(st.st_gid).toLatin1());
+ return fallbackXdgRuntimeDir();
+ });
+
+ // static so that it can be used in RuntimeDirSetup callable without capturing
+ static auto failedToOpen = [](const QFile &f) {
+ qCritical("QFile::Open: failed to open '%s': %s",
+ qPrintable(f.fileName()), qPrintable(f.errorString()));
+ return std::nullopt;
+ };
+
+ addRow("environment:file", [](QDir &d) -> std::optional<QString> {
+ QString p = d.filePath("file");
+ QFile f(p);
+ if (!f.open(QIODevice::WriteOnly))
+ return failedToOpen(f);
+ f.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
+
+ updateRuntimeDir(p);
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '%1' is not a directory, "
+ "but a regular file permissions 0600 owned by UID %2 GID %3")
+ .arg(p).arg(getuid()).arg(getgid()).toLatin1());
+ return fallbackXdgRuntimeDir();
+ });
+
+ addRow("environment:broken-symlink", [](QDir &d) -> std::optional<QString> {
+ QString p = d.filePath("link");
+ QFile::link(d.filePath("this-goes-nowhere"), p);
+ updateRuntimeDir(p);
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '%1' is not a directory, "
+ "but a broken symlink")
+ .arg(p).toLatin1());
+ return fallbackXdgRuntimeDir();
+ });
+
+ addRow("environment:symlink-to-dir", [](QDir &d) -> std::optional<QString> {
+ QString p = d.filePath("link");
+ d.mkdir("dir");
+ QFile::link(d.filePath("dir"), p);
+ QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
+ updateRuntimeDir(p);
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '%1' is not a directory, "
+ "but a symbolic link to a directory permissions 0700 owned by UID %2 GID %3")
+ .arg(p).arg(getuid()).arg(getgid()).toLatin1());
+ return fallbackXdgRuntimeDir();
+ });
+
+ addRow("no-environment:non-existing", [](QDir &) -> std::optional<QString> {
+ clearRuntimeDir();
+ return fallbackXdgRuntimeDir();
+ });
+
+ addRow("no-environment:existing", [](QDir &d) -> std::optional<QString> {
+ clearRuntimeDir();
+ QString p = fallbackXdgRuntimeDir();
+ d.mkdir(p); // probably has wrong permissions
+ QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
+ return p;
+ });
+
+ addRow("no-environment:fallback-is-file", [](QDir &) -> std::optional<QString> {
+ QString p = fallbackXdgRuntimeDir();
+ QFile f(p);
+ if (!f.open(QIODevice::WriteOnly))
+ return failedToOpen(f);
+ f.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
+
+ clearRuntimeDir();
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '%1' is not a directory, "
+ "but a regular file permissions 0600 owned by UID %2 GID %3")
+ .arg(p).arg(getuid()).arg(getgid()).toLatin1());
+ return QString();
+ });
+
+ addRow("environment-and-fallback-are-files", [](QDir &d) -> std::optional<QString> {
+ QString p = d.filePath("file1");
+ QFile f(p);
+ if (!f.open(QIODevice::WriteOnly))
+ return failedToOpen(f);
+ f.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup);
+ updateRuntimeDir(p);
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '%1' is not a directory, "
+ "but a regular file permissions 0640 owned by UID %2 GID %3")
+ .arg(p).arg(getuid()).arg(getgid()).toLatin1());
+
+ f.close();
+ f.setFileName(fallbackXdgRuntimeDir());
+ if (!f.open(QIODevice::WriteOnly))
+ return failedToOpen(f);
+ f.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup);
+ QTest::ignoreMessage(QtWarningMsg,
+ QString("QStandardPaths: runtime directory '%1' is not a directory, "
+ "but a regular file permissions 0640 owned by UID %2 GID %3")
+ .arg(f.fileName()).arg(getuid()).arg(getgid()).toLatin1());
+
+ return QString();
+ });
#endif
}
@@ -488,47 +743,40 @@ void tst_qstandardpaths::testCustomRuntimeDirectory()
#ifdef Q_XDG_PLATFORM
struct EnvVarRestorer
{
- EnvVarRestorer() : origRuntimeDir(qgetenv("XDG_RUNTIME_DIR")) {}
- ~EnvVarRestorer() { qputenv("XDG_RUNTIME_DIR", origRuntimeDir.constData()); }
- const QByteArray origRuntimeDir;
+ ~EnvVarRestorer()
+ {
+ qputenv("XDG_RUNTIME_DIR", origRuntimeDir);
+ qputenv("TMPDIR", origTempDir);
+ }
+ const QByteArray origRuntimeDir = qgetenv("XDG_RUNTIME_DIR");
+ const QByteArray origTempDir = qgetenv("TMPDIR");
};
EnvVarRestorer restorer;
- // When $XDG_RUNTIME_DIR points to a directory with wrong ownership, QStandardPaths should warn
- QByteArray rootOwnedFileName = "/tmp";
- if (EmulationDetector::isRunningArmOnX86()) {
- // Directory "tmp" under toolchain sysroot is detected by qemu and has same uid as current user.
- // Try /opt instead, it might not be located in the sysroot.
- QFileInfo rootOwnedFile = QFileInfo(QString::fromLatin1(rootOwnedFileName));
- if (rootOwnedFile.ownerId() == ::geteuid()) {
- rootOwnedFileName = "/opt";
- }
+ // set up the environment to point to a place we control
+ QTemporaryDir tempDir;
+ QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString()));
+
+ QDir d(tempDir.path());
+ qputenv("TMPDIR", QFile::encodeName(tempDir.path()));
+
+ QFETCH(RuntimeDirSetup, setup);
+ std::optional<QString> opt = setup(d);
+ QVERIFY(opt);
+ QString expected = *opt;
+
+ QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+ QCOMPARE(runtimeDir, expected);
+
+ if (!runtimeDir.isEmpty()) {
+ QFileInfo runtimeInfo(runtimeDir);
+ QVERIFY(runtimeInfo.isDir());
+ QVERIFY(!runtimeInfo.isSymLink());
+ auto expectedPerms = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
+ | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser;
+ QCOMPARE(QString::number(runtimeInfo.permissions(), 16),
+ QString::number(expectedPerms, 16));
}
- qputenv("XDG_RUNTIME_DIR", QFile::encodeName(rootOwnedFileName));
-
- // It's very unlikely that /tmp is 0600 or that we can chmod it
- // The call below outputs
- // "QStandardPaths: wrong ownership on runtime directory /tmp, 0 instead of $UID"
- // but we can't reliably expect that it's owned by uid 0, I think.
- const uid_t uid = geteuid();
- QTest::ignoreMessage(QtWarningMsg,
- qPrintable(QString::fromLatin1("QStandardPaths: wrong ownership on runtime directory " + rootOwnedFileName + ", 0 instead of %1").arg(uid)));
- const QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
- QVERIFY2(runtimeDir.isEmpty(), qPrintable(runtimeDir));
-
- // When $XDG_RUNTIME_DIR points to a non-existing directory, QStandardPaths should warn (QTBUG-48771)
- qputenv("XDG_RUNTIME_DIR", "does_not_exist");
- QTest::ignoreMessage(QtWarningMsg, "QStandardPaths: XDG_RUNTIME_DIR points to non-existing path 'does_not_exist', please create it with 0700 permissions.");
- const QString nonExistingRuntimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
- QVERIFY2(nonExistingRuntimeDir.isEmpty(), qPrintable(nonExistingRuntimeDir));
-
- // When $XDG_RUNTIME_DIR points to a file, QStandardPaths should warn
- const QString file = QFINDTESTDATA("tst_qstandardpaths.cpp");
- QVERIFY(!file.isEmpty());
- qputenv("XDG_RUNTIME_DIR", QFile::encodeName(file));
- QTest::ignoreMessage(QtWarningMsg, qPrintable(QString::fromLatin1("QStandardPaths: XDG_RUNTIME_DIR points to '%1' which is not a directory").arg(file)));
- const QString noRuntimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
- QVERIFY2(noRuntimeDir.isEmpty(), qPrintable(file));
#endif
}
@@ -566,7 +814,8 @@ void tst_qstandardpaths::testAllWritableLocations()
void tst_qstandardpaths::testCleanPath()
{
- const QRegExp filter(QStringLiteral("\\\\"));
+#if QT_CONFIG(regularexpression)
+ const QRegularExpression filter(QStringLiteral("\\\\"));
QVERIFY(filter.isValid());
for (int i = 0; i <= QStandardPaths::GenericCacheLocation; ++i) {
const QStringList paths = QStandardPaths::standardLocations(QStandardPaths::StandardLocation(i));
@@ -574,6 +823,9 @@ void tst_qstandardpaths::testCleanPath()
qPrintable(QString::fromLatin1("Backslash found in %1 %2")
.arg(i).arg(paths.join(QLatin1Char(',')))));
}
+#else
+ QSKIP("regularexpression feature disabled");
+#endif
}
void tst_qstandardpaths::testXdgPathCleanup()
@@ -586,6 +838,35 @@ void tst_qstandardpaths::testXdgPathCleanup()
QVERIFY(!appsDirs.contains("/applications"));
QVERIFY(!appsDirs.contains(uncleanGlobalAppDir + "/applications"));
QVERIFY(!appsDirs.contains("relative/path/applications"));
+
+ const QString uncleanGlobalConfigDir = "/./" + QFile::encodeName(m_globalConfigDir);
+ qputenv("XDG_CONFIG_DIRS", QFile::encodeName(uncleanGlobalConfigDir) + "::relative/path");
+ const QStringList configDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation);
+ QVERIFY(!configDirs.contains("relative/path"_L1));
+ QVERIFY(!configDirs.contains(""_L1));
+
+ // Relative paths in XDG_* env vars are ignored
+ const QString relative("./someRelativeDir");
+
+ qputenv("XDG_CACHE_HOME", relative.toLatin1());
+ const QString cacheDir = cacheLoc();
+ QCOMPARE_NE(cacheDir, relative);
+
+ qputenv("XDG_STATE_HOME", relative.toLatin1());
+ const QString stateDir = stateLoc();
+ QCOMPARE_NE(stateDir, relative);
+
+ qputenv("XDG_DATA_HOME", relative.toLatin1());
+ const QString localDataDir = genericDataLoc();
+ QCOMPARE_NE(localDataDir, relative);
+
+ qputenv("XDG_CONFIG_HOME", relative.toLatin1());
+ const QString localConfig = configLoc();
+ QCOMPARE_NE(localConfig, relative);
+
+ qputenv("XDG_RUNTIME_DIR", relative.toLatin1());
+ const QString runtimeDir = genericDataLoc();
+ QCOMPARE_NE(runtimeDir, relative);
#endif
}
diff --git a/tests/auto/corelib/io/qstorageinfo/CMakeLists.txt b/tests/auto/corelib/io/qstorageinfo/CMakeLists.txt
new file mode 100644
index 0000000000..acbd90cb45
--- /dev/null
+++ b/tests/auto/corelib/io/qstorageinfo/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstorageinfo Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstorageinfo LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstorageinfo
+ SOURCES
+ tst_qstorageinfo.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/io/qstorageinfo/qstorageinfo.pro b/tests/auto/corelib/io/qstorageinfo/qstorageinfo.pro
deleted file mode 100644
index de27504a9b..0000000000
--- a/tests/auto/corelib/io/qstorageinfo/qstorageinfo.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstorageinfo
-QT = core-private testlib
-SOURCES = tst_qstorageinfo.cpp
diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
index fe63cecccd..6a6339a8ec 100644
--- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
+++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
@@ -1,52 +1,49 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QSet>
+#include <QStandardPaths>
#include <QStorageInfo>
+#include <QTemporaryFile>
+#include "private/qemulationdetector_p.h"
#include <stdarg.h>
+#ifdef Q_OS_WIN
+# include <io.h> // _get_osfhandle
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
#include "../../../../manual/qstorageinfo/printvolumes.cpp"
+#ifdef Q_OS_LINUX
+# include "../../../../../src/corelib/io/qstorageinfo_linux_p.h"
+#endif
+
class tst_QStorageInfo : public QObject
{
Q_OBJECT
private slots:
void defaultValues();
void dump();
+ void compareCompiles();
void operatorEqual();
-#ifndef Q_OS_WINRT
void operatorNotEqual();
void root();
void currentStorage();
+ void storageList_data();
void storageList();
- void tempFile();
- void caching();
+ void freeSpaceUpdate();
+
+#if defined(Q_OS_LINUX) && defined(QT_BUILD_INTERNAL)
+ void testParseMountInfo_data();
+ void testParseMountInfo();
+ void testParseMountInfo_filtered_data();
+ void testParseMountInfo_filtered();
#endif
};
@@ -92,33 +89,44 @@ void tst_QStorageInfo::dump()
printVolumes(QStorageInfo::mountedVolumes(), qInfoPrinter);
}
+void tst_QStorageInfo::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QStorageInfo>();
+}
+
void tst_QStorageInfo::operatorEqual()
{
{
QStorageInfo storage1 = QStorageInfo::root();
QStorageInfo storage2(QDir::rootPath());
- QCOMPARE(storage1, storage2);
+ QT_TEST_EQUALITY_OPS(storage1, storage2, true);
}
{
QStorageInfo storage1(QCoreApplication::applicationDirPath());
QStorageInfo storage2(QCoreApplication::applicationFilePath());
- QCOMPARE(storage1, storage2);
+ QT_TEST_EQUALITY_OPS(storage1, storage2, true);
}
{
QStorageInfo storage1;
QStorageInfo storage2;
- QCOMPARE(storage1, storage2);
+ QT_TEST_EQUALITY_OPS(storage1, storage2, true);
+ }
+
+ // Test copy ctor
+ {
+ QStorageInfo storage1 = QStorageInfo::root();
+ QStorageInfo storage2(storage1);
+ QT_TEST_EQUALITY_OPS(storage1, storage2, true);
}
}
-#ifndef Q_OS_WINRT
void tst_QStorageInfo::operatorNotEqual()
{
QStorageInfo storage1 = QStorageInfo::root();
QStorageInfo storage2;
- QVERIFY(storage1 != storage2);
+ QT_TEST_EQUALITY_OPS(storage1, storage2, false);
}
void tst_QStorageInfo::root()
@@ -132,9 +140,9 @@ void tst_QStorageInfo::root()
QVERIFY(!storage.device().isEmpty());
QVERIFY(!storage.fileSystemType().isEmpty());
#ifndef Q_OS_HAIKU
- QVERIFY(storage.bytesTotal() >= 0);
- QVERIFY(storage.bytesFree() >= 0);
- QVERIFY(storage.bytesAvailable() >= 0);
+ QCOMPARE_GE(storage.bytesTotal(), 0);
+ QCOMPARE_GE(storage.bytesFree(), 0);
+ QCOMPARE_GE(storage.bytesAvailable(), 0);
#endif
}
@@ -147,13 +155,16 @@ void tst_QStorageInfo::currentStorage()
QVERIFY(appPath.startsWith(storage.rootPath(), Qt::CaseInsensitive));
QVERIFY(!storage.device().isEmpty());
QVERIFY(!storage.fileSystemType().isEmpty());
- QVERIFY(storage.bytesTotal() >= 0);
- QVERIFY(storage.bytesFree() >= 0);
- QVERIFY(storage.bytesAvailable() >= 0);
+ QCOMPARE_GE(storage.bytesTotal(), 0);
+ QCOMPARE_GE(storage.bytesFree(), 0);
+ QCOMPARE_GE(storage.bytesAvailable(), 0);
}
-void tst_QStorageInfo::storageList()
+void tst_QStorageInfo::storageList_data()
{
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("QEMU appears not to emulate the system calls correctly.");
+
QStorageInfo root = QStorageInfo::root();
QList<QStorageInfo> volumes = QStorageInfo::mountedVolumes();
@@ -163,9 +174,26 @@ void tst_QStorageInfo::storageList()
volumes.removeOne(root);
QVERIFY(!volumes.contains(root));
- foreach (const QStorageInfo &storage, volumes) {
+ if (volumes.isEmpty())
+ QSKIP("Only the root volume was mounted on this system");
+
+ QTest::addColumn<QStorageInfo>("storage");
+ QSet<QString> seenRoots;
+ for (const QStorageInfo &storage : std::as_const(volumes)) {
if (!storage.isReady())
continue;
+ QString rootPath = storage.rootPath();
+ if (seenRoots.contains(rootPath))
+ qInfo() << rootPath << "is mounted over; QStorageInfo may be unpredictable";
+ else
+ QTest::newRow(qUtf8Printable(rootPath)) << storage;
+ seenRoots.insert(rootPath);
+ }
+}
+
+void tst_QStorageInfo::storageList()
+{
+ QFETCH(QStorageInfo, storage);
QVERIFY(storage.isValid());
QVERIFY(!storage.isRoot());
@@ -173,64 +201,262 @@ void tst_QStorageInfo::storageList()
QVERIFY(!storage.device().isEmpty());
QVERIFY(!storage.fileSystemType().isEmpty());
#endif
- }
+
+ QStorageInfo other(storage.rootPath());
+ QVERIFY(other.isValid());
+ QCOMPARE(other.rootPath(), storage.rootPath());
+ QCOMPARE(other.device(), storage.device());
+ QCOMPARE(other.subvolume(), storage.subvolume());
+ QCOMPARE(other.fileSystemType(), storage.fileSystemType());
+ QCOMPARE(other.name(), storage.name());
+ QCOMPARE(other.displayName(), storage.displayName());
+
+ QCOMPARE(other.bytesTotal(), storage.bytesTotal());
+ QCOMPARE(other.blockSize(), storage.blockSize());
+ // not comparing free space because it may have changed
+
+ QCOMPARE(other.isRoot(), storage.isRoot());
+ QCOMPARE(other.isReadOnly(), storage.isReadOnly());
+ QCOMPARE(other.isReady(), storage.isReady());
}
-void tst_QStorageInfo::tempFile()
+static QString suitableDirectoryForWriting()
{
- QTemporaryFile file;
- QVERIFY2(file.open(), qPrintable(file.errorString()));
-
- QStorageInfo storage1(file.fileName());
+ std::initializer_list<const char *> inadvisableFs = {
#ifdef Q_OS_LINUX
- if (storage1.fileSystemType() == "btrfs")
- QSKIP("This test doesn't work on btrfs, probably due to a btrfs bug");
+ // See comment below. If we can get a tmpfs, let's try it.
+ "btrfs",
+ "xfs",
#endif
-
- qint64 free = storage1.bytesFree();
- QVERIFY(free != -1);
-
- file.write(QByteArray(1024*1024, '1'));
- file.flush();
- file.close();
-
- QStorageInfo storage2(file.fileName());
- if (free == storage2.bytesFree() && storage2.fileSystemType() == "apfs") {
- QEXPECT_FAIL("", "This test is likely to fail on APFS", Continue);
+ };
+
+ QString tempDir = QDir::tempPath();
+ QString fsType = QStorageInfo(tempDir).fileSystemType();
+ if (std::find(std::begin(inadvisableFs), std::end(inadvisableFs), fsType)
+ != std::end(inadvisableFs)) {
+ // the RuntimeLocation on Linux is almost always a tmpfs
+ QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
+ if (!runtimeDir.isEmpty())
+ return runtimeDir;
}
- QVERIFY(free != storage2.bytesFree());
+ return tempDir;
}
-void tst_QStorageInfo::caching()
+void tst_QStorageInfo::freeSpaceUpdate()
{
- QTemporaryFile file;
+ // Some filesystems don't update the free space unless we ask that the OS
+ // flush its buffers to disk and even then the update may not be entirely
+ // synchronous. So we always ask the OS to flush them and we may keep
+ // trying to write until the free space changes (with a maximum so we don't
+ // exhaust and cause other problems).
+ //
+ // In the past, we had this issue with APFS (Apple systems), BTRFS and XFS
+ // (Linux). Current testing is that APFS and XFS always succeed after the
+ // first block is written and BTRFS almost always by the second block.
+
+ auto flushAndSync = [](QFile &file) {
+ file.flush();
+
+#ifdef Q_OS_WIN
+ FlushFileBuffers(HANDLE(_get_osfhandle(file.handle())));
+#elif _POSIX_VERSION >= 200112L
+ fsync(file.handle());
+ sync();
+#endif
+ };
+
+ QTemporaryFile file(suitableDirectoryForWriting() + "/tst_qstorageinfo.XXXXXX");
QVERIFY2(file.open(), qPrintable(file.errorString()));
QStorageInfo storage1(file.fileName());
-#ifdef Q_OS_LINUX
- if (storage1.fileSystemType() == "btrfs")
- QSKIP("This test doesn't work on btrfs, probably due to a btrfs bug");
-#endif
+ qInfo() << "Testing on" << storage1;
qint64 free = storage1.bytesFree();
QStorageInfo storage2(storage1);
QCOMPARE(free, storage2.bytesFree());
- QVERIFY(free != -1);
-
- file.write(QByteArray(1024*1024, '\0'));
- file.flush();
+ QCOMPARE_NE(free, -1);
+
+ // let's see if we can make it change
+ QByteArray block(1024 * 1024 / 2, '\0');
+
+ // let's try and keep to less than ~10% of the free disk space
+ int maxIterations = 25;
+ if (free < 256 * block.size())
+ maxIterations = free / 10 / block.size();
+ if (maxIterations == 0)
+ QSKIP("Not enough free disk space to continue");
+
+ file.write(block);
+ flushAndSync(file);
+ for (int i = 0; i < maxIterations; ++i) {
+ QStorageInfo storage3(file.fileName());
+ qint64 nowFree = storage3.bytesFree();
+ if (nowFree != free)
+ break;
+
+ // grow some more
+ file.write(block);
+ flushAndSync(file);
+ }
+ // qDebug() << "Needed to grow" << file.fileName() << "to" << file.size();
+ QCOMPARE(storage1, storage2);
QCOMPARE(free, storage1.bytesFree());
QCOMPARE(free, storage2.bytesFree());
storage2.refresh();
QCOMPARE(storage1, storage2);
- if (free == storage2.bytesFree() && storage2.fileSystemType() == "apfs") {
- QEXPECT_FAIL("", "This test is likely to fail on APFS", Continue);
- }
- QVERIFY(free != storage2.bytesFree());
+ QCOMPARE_NE(free, storage2.bytesFree());
}
-#endif
+
+#if defined(Q_OS_LINUX) && defined(QT_BUILD_INTERNAL)
+void tst_QStorageInfo::testParseMountInfo_data()
+{
+ QTest::addColumn<QByteArray>("line");
+ QTest::addColumn<MountInfo>("expected");
+
+ QTest::newRow("tmpfs")
+ << "17 25 0:18 / /dev rw,nosuid,relatime shared:2 - tmpfs tmpfs rw,seclabel,mode=755\n"_ba
+ << MountInfo{"/dev", "tmpfs", "tmpfs", "", makedev(0, 18)};
+ QTest::newRow("proc")
+ << "23 66 0:21 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw\n"_ba
+ << MountInfo{"/proc", "proc", "proc", "", makedev(0, 21)};
+
+ // E.g. on Android
+ QTest::newRow("rootfs")
+ << "618 618 0:1 / / ro,relatime master:1 - rootfs rootfs ro,seclabel\n"_ba
+ << MountInfo{"/", "rootfs", "rootfs", "", makedev(0, 1)};
+
+ QTest::newRow("ext4")
+ << "47 66 8:3 / /home rw,relatime shared:50 - ext4 /dev/sda3 rw,stripe=32736\n"_ba
+ << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3)};
+
+ QTest::newRow("empty-optional-field")
+ << "23 25 0:22 / /apex rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,seclabel,mode=755\n"_ba
+ << MountInfo{"/apex", "tmpfs", "tmpfs", "", makedev(0, 22)};
+
+ QTest::newRow("one-optional-field")
+ << "47 66 8:3 / /home rw,relatime shared:50 - ext4 /dev/sda3 rw,stripe=32736\n"_ba
+ << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3)};
+
+ QTest::newRow("multiple-optional-fields")
+ << "47 66 8:3 / /home rw,relatime shared:142 master:111 - ext4 /dev/sda3 rw,stripe=32736\n"_ba
+ << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3)};
+
+ QTest::newRow("mountdir-with-utf8")
+ << "129 66 8:51 / /mnt/lab\xC3\xA9l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba
+ << MountInfo{"/mnt/labél", "ext4", "/dev/sdd3", "", makedev(8, 51)};
+
+ QTest::newRow("mountdir-with-space")
+ << "129 66 8:51 / /mnt/labe\\040l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba
+ << MountInfo{"/mnt/labe l", "ext4", "/dev/sdd3", "", makedev(8, 51)};
+
+ QTest::newRow("mountdir-with-tab")
+ << "129 66 8:51 / /mnt/labe\\011l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba
+ << MountInfo{"/mnt/labe\tl", "ext4", "/dev/sdd3", "", makedev(8, 51)};
+
+ QTest::newRow("mountdir-with-backslash")
+ << "129 66 8:51 / /mnt/labe\\134l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba
+ << MountInfo{"/mnt/labe\\l", "ext4", "/dev/sdd3", "", makedev(8, 51)};
+
+ QTest::newRow("mountdir-with-newline")
+ << "129 66 8:51 / /mnt/labe\\012l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba
+ << MountInfo{"/mnt/labe\nl", "ext4", "/dev/sdd3", "", makedev(8, 51)};
+
+ QTest::newRow("btrfs-subvol")
+ << "775 503 0:49 /foo/bar / rw,relatime shared:142 master:111 - btrfs "
+ "/dev/mapper/vg0-stuff rw,ssd,discard,space_cache,subvolid=272,subvol=/foo/bar\n"_ba
+ << MountInfo{"/", "btrfs", "/dev/mapper/vg0-stuff", "/foo/bar", makedev(0, 49)};
+
+ QTest::newRow("bind-mount")
+ << "59 47 8:17 /rpmbuild /home/user/rpmbuild rw,relatime shared:48 - ext4 /dev/sdb1 rw\n"_ba
+ << MountInfo{"/home/user/rpmbuild", "ext4", "/dev/sdb1", "/rpmbuild", makedev(8, 17)};
+
+ QTest::newRow("space-dash-space")
+ << "47 66 8:3 / /home\\040-\\040dir rw,relatime shared:50 - ext4 /dev/sda3 rw,stripe=32736\n"_ba
+ << MountInfo{"/home - dir", "ext4", "/dev/sda3", "", makedev(8, 3)};
+
+ QTest::newRow("btrfs-mount-bind-file")
+ << "1799 1778 0:49 "
+ "/var_lib_docker/containers/81fde0fec3dd3d99765c3f7fd9cf1ab121b6ffcfd05d5d7ff434db933fe9d795/resolv.conf "
+ "/etc/resolv.conf rw,relatime - btrfs /dev/mapper/vg0-stuff "
+ "rw,ssd,discard,space_cache,subvolid=1773,subvol=/var_lib_docker\n"_ba
+ << MountInfo{"/etc/resolv.conf", "btrfs", "/dev/mapper/vg0-stuff",
+ "/var_lib_docker/containers/81fde0fec3dd3d99765c3f7fd9cf1ab121b6ffcfd05d5d7ff434db933fe9d795/resolv.conf",
+ makedev(0, 49)};
+
+ QTest::newRow("very-long-line-QTBUG-77059")
+ << "727 26 0:52 / "
+ "/var/lib/docker/overlay2/f3fbad5eedef71145f00729f0826ea8c44defcfec8c92c58aee0aa2c5ea3fa3a/merged "
+ "rw,relatime shared:399 - overlay overlay "
+ "rw,lowerdir=/var/lib/docker/overlay2/l/PUP2PIY4EQLAOEDQOZ56BHVE53:"
+ "/var/lib/docker/overlay2/l/6IIID3C6J3SUXZEA3GJXKQSTLD:"
+ "/var/lib/docker/overlay2/l/PA6N6URNR7XDBBGGOSFWSFQ2CG:"
+ "/var/lib/docker/overlay2/l/5EOMBTZNCPOCE4LM3I4JCTNSTT:"
+ "/var/lib/docker/overlay2/l/DAMINQ46P3LKX2GDDDIWQKDIWC:"
+ "/var/lib/docker/overlay2/l/DHR3N57AEH4OG5QER5XJW2LXIN:"
+ "/var/lib/docker/overlay2/l/NW26KA7QPRS2KSVQI77QJWLMHW,"
+ "upperdir=/var/lib/docker/overlay2/f3fbad5eedef71145f00729f0826ea8c44defcfec8c92c58aee0aa2c5ea3fa3a/diff,"
+ "workdir=/var/lib/docker/overlay2/f3fbad5eedef71145f00729f0826ea8c44defcfec8c92c58aee0aa2c5ea3fa3a/work,"
+ "index=off,xino=off\n"_ba
+ << MountInfo{"/var/lib/docker/overlay2/f3fbad5eedef71145f00729f0826ea8c44defcfec8c92c58aee0aa2c5ea3fa3a/merged",
+ "overlay", "overlay", "", makedev(0, 52)};
+
+ QTest::newRow("sshfs-src-device-not-start-with-slash")
+ << "128 92 0:64 / /mnt-point rw,nosuid,nodev,relatime shared:234 - "
+ "fuse.sshfs admin@192.168.1.2:/storage/emulated/0 rw,user_id=1000,group_id=1000\n"_ba
+ << MountInfo{"/mnt-point", "fuse.sshfs",
+ "admin@192.168.1.2:/storage/emulated/0", "", makedev(0, 64)};
+}
+
+void tst_QStorageInfo::testParseMountInfo()
+{
+ QFETCH(QByteArray, line);
+ QFETCH(MountInfo, expected);
+
+ const std::vector<MountInfo> result = doParseMountInfo(line);
+ QVERIFY(!result.empty());
+ const MountInfo &a = result.front();
+ QCOMPARE(a.mountPoint, expected.mountPoint);
+ QCOMPARE(a.fsType, expected.fsType);
+ QCOMPARE(a.device, expected.device);
+ QCOMPARE(a.fsRoot, expected.fsRoot);
+ QCOMPARE(a.stDev, expected.stDev);
+}
+
+void tst_QStorageInfo::testParseMountInfo_filtered_data()
+{
+ QTest::addColumn<QByteArray>("line");
+
+ QTest::newRow("proc")
+ << "23 66 0:21 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw\n"_ba;
+
+ QTest::newRow("sys")
+ << "24 66 0:22 / /sys rw,nosuid,nodev,noexec,relatime shared:2 - sysfs sysfs rw\n"_ba;
+ QTest::newRow("sys-kernel")
+ << "26 24 0:6 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime "
+ "shared:3 - securityfs securityfs rw\n"_ba;
+
+ QTest::newRow("dev")
+ << "25 66 0:5 / /dev rw,nosuid shared:8 - devtmpfs devtmpfs "
+ "rw,size=4096k,nr_inodes=8213017,mode=755,inode64\n"_ba;
+ QTest::newRow("dev-shm")
+ << "27 25 0:23 / /dev/shm rw,nosuid,nodev shared:9 - tmpfs tmpfs rw,inode64\n"_ba;
+
+ QTest::newRow("var-run")
+ << "46 28 0:25 / /var/run rw,nosuid,nodev,noexec,relatime shared:1 - "
+ "tmpfs tmpfs rw,size=32768k,mode=755,inode64\n"_ba;
+ QTest::newRow("var-lock")
+ << "46 28 0:25 / /var/lock rw,nosuid,nodev,noexec,relatime shared:1 - "
+ "tmpfs tmpfs rw,size=32768k,mode=755,inode64\n"_ba;
+}
+void tst_QStorageInfo::testParseMountInfo_filtered()
+{
+ QFETCH(QByteArray, line);
+ QVERIFY(doParseMountInfo(line, FilterMountInfo::Filtered).empty());
+}
+
+#endif // Q_OS_LINUX
QTEST_MAIN(tst_QStorageInfo)
diff --git a/tests/auto/corelib/io/qtemporarydir/BLACKLIST b/tests/auto/corelib/io/qtemporarydir/BLACKLIST
new file mode 100644
index 0000000000..da7dac909f
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporarydir/BLACKLIST
@@ -0,0 +1,2 @@
+[QTBUG43352_failedSetPermissions]
+macos-14 arm ci
diff --git a/tests/auto/corelib/io/qtemporarydir/CMakeLists.txt b/tests/auto/corelib/io/qtemporarydir/CMakeLists.txt
new file mode 100644
index 0000000000..0ddde7d0b3
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporarydir/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtemporarydir Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtemporarydir LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtemporarydir
+ SOURCES
+ tst_qtemporarydir.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
+
+qt_internal_extend_target(tst_qtemporarydir CONDITION WIN32
+ LIBRARIES
+ shlwapi
+)
diff --git a/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro b/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro
deleted file mode 100644
index 5908648378..0000000000
--- a/tests/auto/corelib/io/qtemporarydir/qtemporarydir.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtemporarydir
-SOURCES += tst_qtemporarydir.cpp
-INCLUDEPATH += ../../../../shared/
-HEADERS += ../../../../shared/emulationdetector.h
-
-QT = core testlib testlib-private
diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
index 6dbb8ddd0d..737317a8fb 100644
--- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -1,49 +1,31 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QStandardPaths>
#include <qcoreapplication.h>
#include <qstring.h>
#include <qtemporarydir.h>
#include <qfile.h>
#include <qdir.h>
#include <qset.h>
-#include <qtextcodec.h>
#include <QtTest/private/qtesthelpers_p.h>
#ifdef Q_OS_WIN
-# include <windows.h>
+# include <shlwapi.h>
+# include <qt_windows.h>
#endif
#ifdef Q_OS_UNIX // for geteuid()
# include <sys/types.h>
# include <unistd.h>
#endif
-#include "emulationdetector.h"
+
+#ifdef Q_OS_INTEGRITY
+#include "qplatformdefs.h"
+#endif
+
+#include <optional>
+
+using namespace Qt::StringLiterals;
class tst_QTemporaryDir : public QObject
{
@@ -55,6 +37,7 @@ public slots:
private slots:
void construction();
+ void moveSemantics();
void fileTemplate();
void fileTemplate_data();
void getSetCheck();
@@ -70,7 +53,7 @@ private slots:
void QTBUG_4796_data();
void QTBUG_4796();
- void QTBUG43352_failedSetPermissions();
+ void nestedTempDirs();
private:
QString m_previousCurrent;
@@ -101,6 +84,58 @@ void tst_QTemporaryDir::construction()
QCOMPARE(dir.errorString(), QString());
}
+void tst_QTemporaryDir::moveSemantics()
+{
+ {
+ auto original = std::optional<QTemporaryDir>(std::in_place);
+ QVERIFY(original->isValid());
+
+ original->setAutoRemove(true);
+
+ auto OriginalDirectoryInfo = QFileInfo(original->path());
+ OriginalDirectoryInfo.setCaching(false);
+ QVERIFY(OriginalDirectoryInfo.exists());
+
+ QTemporaryDir movedInto = std::move(*original);
+
+ original.reset();
+
+ QVERIFY(OriginalDirectoryInfo.exists());
+ QVERIFY(movedInto.path() == OriginalDirectoryInfo.filePath());
+ }
+
+ {
+ auto movedInto = QTemporaryDir();
+ QVERIFY(movedInto.isValid());
+
+ movedInto.setAutoRemove(true);
+
+ auto movedIntoInitialDirectoryInfo = QFileInfo(movedInto.path());
+ movedIntoInitialDirectoryInfo.setCaching(false);
+ QVERIFY(movedIntoInitialDirectoryInfo.exists());
+
+ auto OriginalDirectoryInfo = QFileInfo();
+ OriginalDirectoryInfo.setCaching(false);
+
+ {
+ auto original = QTemporaryDir();
+ QVERIFY(original.isValid());
+
+ original.setAutoRemove(true);
+
+ OriginalDirectoryInfo.setFile(original.path());
+ QVERIFY(OriginalDirectoryInfo.exists());
+
+ movedInto = std::move(original);
+ }
+
+ QVERIFY(!movedIntoInitialDirectoryInfo.exists());
+ QVERIFY(OriginalDirectoryInfo.exists());
+
+ QVERIFY(movedInto.path() == OriginalDirectoryInfo.filePath());
+ }
+}
+
// Testing get/set functions
void tst_QTemporaryDir::getSetCheck()
{
@@ -158,6 +193,28 @@ void tst_QTemporaryDir::fileTemplate_data()
prefix = "qt_" + hanTestText();
QTest::newRow("Chinese") << (prefix + "XXXXXX" + umlautTestText()) << prefix << umlautTestText();
}
+
+#ifdef Q_OS_WIN
+ auto tmp = QDir::toNativeSeparators(QDir::tempPath());
+ if (PathGetDriveNumber((const wchar_t *) tmp.utf16()) < 0)
+ return; // skip if we have no drive letter
+
+ tmp.data()[1] = u'$';
+ const auto tmpPath = tmp + uR"(\UNC.XXXXXX.tmpDir)"_s;
+
+ QTest::newRow("UNC-backslash")
+ << uR"(\\localhost\)"_s + tmpPath << "UNC."
+ << ".tmpDir";
+ QTest::newRow("UNC-prefix")
+ << uR"(\\?\UNC\localhost\)"_s + tmpPath << "UNC."
+ << ".tmpDir";
+ QTest::newRow("UNC-slash")
+ << u"//localhost/"_s + QDir::fromNativeSeparators(tmpPath) << "UNC."
+ << ".tmpDir";
+ QTest::newRow("UNC-prefix-slash")
+ << uR"(//?/UNC/localhost/)"_s + QDir::fromNativeSeparators(tmpPath) << "UNC."
+ << ".tmpDir";
+#endif
}
void tst_QTemporaryDir::fileTemplate()
@@ -171,9 +228,9 @@ void tst_QTemporaryDir::fileTemplate()
QVERIFY(tempDir.isValid());
QString dirName = QDir(tempDir.path()).dirName();
- if (prefix.length()) {
- QCOMPARE(dirName.left(prefix.length()), prefix);
- QCOMPARE(dirName.right(suffix.length()), suffix);
+ if (prefix.size()) {
+ QCOMPARE(dirName.left(prefix.size()), prefix);
+ QCOMPARE(dirName.right(suffix.size()), suffix);
}
}
@@ -290,7 +347,7 @@ void tst_QTemporaryDir::nonWritableCurrentDir()
{
#ifdef Q_OS_UNIX
-# if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+# ifdef Q_OS_ANDROID
const char nonWritableDir[] = "/data";
# else
const char nonWritableDir[] = "/home";
@@ -311,12 +368,6 @@ void tst_QTemporaryDir::nonWritableCurrentDir()
const QFileInfo nonWritableDirFi = QFileInfo(QLatin1String(nonWritableDir));
QVERIFY(nonWritableDirFi.isDir());
- if (EmulationDetector::isRunningArmOnX86()) {
- if (nonWritableDirFi.ownerId() == ::geteuid()) {
- QSKIP("Sysroot directories are owned by the current user");
- }
- }
-
QVERIFY(!nonWritableDirFi.isWritable());
ChdirOnReturn cor(QDir::currentPath());
@@ -333,12 +384,13 @@ void tst_QTemporaryDir::nonWritableCurrentDir()
void tst_QTemporaryDir::openOnRootDrives()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
// If it's possible to create a file in the root directory, it
// must be possible to create a temp dir there too.
- foreach (const QFileInfo &driveInfo, QDir::drives()) {
+ const auto drives = QDir::drives();
+ for (const QFileInfo &driveInfo : drives) {
QFile testFile(driveInfo.filePath() + "XXXXXX");
if (testFile.open(QIODevice::ReadWrite)) {
testFile.remove();
@@ -347,7 +399,7 @@ void tst_QTemporaryDir::openOnRootDrives()
QVERIFY(dir.isValid());
}
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
SetErrorMode(lastErrorMode);
#endif
}
@@ -427,7 +479,7 @@ void tst_QTemporaryDir::QTBUG_4796() // unicode support
{
~CleanOnReturn()
{
- foreach (const QString &tempName, tempNames)
+ for (const QString &tempName : std::as_const(tempNames))
QVERIFY(QDir(tempName).removeRecursively());
}
@@ -497,22 +549,24 @@ void tst_QTemporaryDir::QTBUG_4796() // unicode support
#ifdef Q_OS_WIN
QTest::qWait(20);
#endif
- foreach (const QString &tempName, cleaner.tempNames)
+ for (const QString &tempName : std::as_const(cleaner.tempNames))
QVERIFY2(!QDir(tempName).exists(), qPrintable(tempName));
cleaner.reset();
}
-void tst_QTemporaryDir::QTBUG43352_failedSetPermissions()
+void tst_QTemporaryDir::nestedTempDirs()
{
- QString path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/");
- int count = QDir(path).entryList().size();
+ QTemporaryDir parentDir;
+ const QString &parentPath = parentDir.path();
{
- QTemporaryDir dir(path);
+ QTemporaryDir tempdir(parentPath);
}
- QCOMPARE(QDir(path).entryList().size(), count);
+ QDir dir(parentPath);
+ dir.setFilter(QDir::NoDotAndDotDot);
+ QCOMPARE(dir.count(), 0);
}
QTEST_MAIN(tst_QTemporaryDir)
diff --git a/tests/auto/corelib/io/qtemporaryfile/CMakeLists.txt b/tests/auto/corelib/io/qtemporaryfile/CMakeLists.txt
new file mode 100644
index 0000000000..9b453302c9
--- /dev/null
+++ b/tests/auto/corelib/io/qtemporaryfile/CMakeLists.txt
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtemporaryfile Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtemporaryfile LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "tst_qtemporaryfile.cpp")
+
+qt_internal_add_test(tst_qtemporaryfile
+ SOURCES
+ tst_qtemporaryfile.cpp
+ LIBRARIES
+ Qt::TestPrivate
+ TESTDATA ${test_data}
+)
+
+# Resources:
+set(qtemporaryfile_resource_files
+ "resources/test.txt"
+)
+
+qt_internal_add_resource(tst_qtemporaryfile "qtemporaryfile"
+ PREFIX
+ "/"
+ FILES
+ ${qtemporaryfile_resource_files}
+)
+
+
+## Scopes:
+#####################################################################
+
+if(ANDROID)
+ # Resources:
+ set(android_testdata_resource_files
+ "resources/test.txt"
+ "tst_qtemporaryfile.cpp"
+ )
+
+ qt_internal_add_resource(tst_qtemporaryfile "android_testdata"
+ PREFIX
+ "/android_testdata"
+ FILES
+ ${android_testdata_resource_files}
+ )
+endif()
+
+qt_internal_extend_target(tst_qtemporaryfile CONDITION WIN32
+ LIBRARIES
+ shlwapi
+)
diff --git a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro b/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro
deleted file mode 100644
index 11a5d58dc8..0000000000
--- a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtemporaryfile
-QT = core testlib testlib-private
-SOURCES = tst_qtemporaryfile.cpp
-TESTDATA += tst_qtemporaryfile.cpp
-RESOURCES += qtemporaryfile.qrc
-
-android:!android-embedded {
- RESOURCES += android_testdata.qrc
-}
diff --git a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.qrc b/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.qrc
deleted file mode 100644
index efadde8b4d..0000000000
--- a/tests/auto/corelib/io/qtemporaryfile/qtemporaryfile.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>resources/test.txt</file>
-</qresource>
-</RCC> \ No newline at end of file
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index dbc3d68e93..579e6d5511 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -1,47 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qcoreapplication.h>
-#include <qstring.h>
-#include <qtemporarydir.h>
-#include <qtemporaryfile.h>
#include <qfile.h>
#include <qdatetime.h>
#include <qdir.h>
#include <qset.h>
-#include <qtextcodec.h>
+#include <qstandardpaths.h>
+#include <qstring.h>
+#include <qtemporarydir.h>
+#include <qtemporaryfile.h>
#include <QtTest/private/qtesthelpers_p.h>
#if defined(Q_OS_WIN)
-# include <windows.h>
+# include <shlwapi.h>
+# include <qt_windows.h>
#endif
#if defined(Q_OS_UNIX)
# include <sys/types.h>
@@ -51,6 +27,17 @@
# include <unistd.h> // close(2)
#endif
+#ifdef Q_OS_ANDROID
+#include <QDirIterator>
+#include <QStandardPaths>
+#endif
+
+#ifdef Q_OS_INTEGRITY
+#include "qplatformdefs.h"
+#endif
+
+using namespace Qt::StringLiterals;
+
class tst_QTemporaryFile : public QObject
{
Q_OBJECT
@@ -77,6 +64,7 @@ private slots:
void stressTest();
void rename();
void renameFdLeak();
+ void moveToTrash();
void reOpenThroughQFile();
void keepOpenMode();
void resetTemplateAfterError();
@@ -87,6 +75,7 @@ private slots:
void QTBUG_4796_data();
void QTBUG_4796();
void guaranteeUnique();
+ void stdfilesystem();
private:
QTemporaryDir m_temporaryDir;
QString m_previousCurrent;
@@ -94,6 +83,9 @@ private:
void tst_QTemporaryFile::initTestCase()
{
+ QStandardPaths::setTestModeEnabled(true);
+ QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
+
QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString()));
m_previousCurrent = QDir::currentPath();
QVERIFY(QDir::setCurrent(m_temporaryDir.path()));
@@ -102,15 +94,15 @@ void tst_QTemporaryFile::initTestCase()
QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX"));
QCoreApplication::setApplicationName("tst_qtemporaryfile");
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QString sourceDir(":/android_testdata/");
QDirIterator it(sourceDir, QDirIterator::Subdirectories);
while (it.hasNext()) {
- it.next();
-
- QFileInfo sourceFileInfo = it.fileInfo();
+ QFileInfo sourceFileInfo = it.nextFileInfo();
if (!sourceFileInfo.isDir()) {
- QFileInfo destinationFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/') + sourceFileInfo.filePath().mid(sourceDir.length()));
+ QFileInfo destinationFileInfo(
+ QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/')
+ + sourceFileInfo.filePath().mid(sourceDir.length()));
if (!destinationFileInfo.exists()) {
QVERIFY(QDir().mkpath(destinationFileInfo.path()));
@@ -202,6 +194,32 @@ void tst_QTemporaryFile::fileTemplate_data()
prefix = "qt_" + hanTestText();
QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix << QString() << QString();
}
+
+#ifdef Q_OS_WIN
+ auto tmp = QDir::toNativeSeparators(QDir::tempPath());
+ if (PathGetDriveNumber((const wchar_t *) tmp.utf16()) < 0)
+ return; // skip if we have no drive letter
+
+ tmp.data()[1] = u'$';
+ const auto tmpPath = tmp + uR"(\QTBUG-74291.XXXXXX.tmpFile)"_s;
+
+ QTest::newRow("UNC-backslash")
+ << uR"(\\localhost\)"_s + tmpPath << "QTBUG-74291."
+ << ".tmpFile"
+ << "";
+ QTest::newRow("UNC-prefix")
+ << uR"(\\?\UNC\localhost\)"_s + tmpPath << "QTBUG-74291."
+ << ".tmpFile"
+ << "";
+ QTest::newRow("UNC-slash")
+ << u"//localhost/"_s + QDir::fromNativeSeparators(tmpPath) << "QTBUG-74291."
+ << ".tmpFile"
+ << "";
+ QTest::newRow("UNC-prefix-slash")
+ << uR"(//?/UNC/localhost/)"_s + QDir::fromNativeSeparators(tmpPath) << "QTBUG-74291."
+ << ".tmpFile"
+ << "";
+#endif
}
void tst_QTemporaryFile::fileTemplate()
@@ -215,14 +233,14 @@ void tst_QTemporaryFile::fileTemplate()
if (!fileTemplate.isEmpty())
file.setFileTemplate(fileTemplate);
- QCOMPARE(file.open(), true);
+ QVERIFY2(file.open(), qPrintable(file.errorString()));
QString fileName = QFileInfo(file).fileName();
- if (prefix.length())
- QCOMPARE(fileName.left(prefix.length()), prefix);
+ if (prefix.size())
+ QCOMPARE(fileName.left(prefix.size()), prefix);
- if (suffix.length())
- QCOMPARE(fileName.right(suffix.length()), suffix);
+ if (suffix.size())
+ QCOMPARE(fileName.right(suffix.size()), suffix);
}
@@ -236,7 +254,7 @@ void tst_QTemporaryFile::fileName()
QString absoluteTempPath = QDir(tempPath).absolutePath();
QTemporaryFile file;
file.setAutoRemove(true);
- file.open();
+ QVERIFY(file.open());
QString fileName = file.fileName();
QVERIFY2(fileName.contains("/tst_qtemporaryfile."), qPrintable(fileName));
QVERIFY(QFile::exists(fileName));
@@ -351,7 +369,7 @@ void tst_QTemporaryFile::nonWritableCurrentDir()
ChdirOnReturn cor(QDir::currentPath());
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
QDir::setCurrent("/data");
#else
QDir::setCurrent("/home");
@@ -376,7 +394,7 @@ void tst_QTemporaryFile::io()
before.setSecsSinceEpoch(before.toSecsSinceEpoch());
QVERIFY(file.open());
- QVERIFY(file.readLink().isEmpty()); // it's not a link!
+ QVERIFY(file.symLinkTarget().isEmpty()); // it's not a link!
QFile::Permissions perm = file.permissions();
QVERIFY(perm & QFile::ReadOwner);
QVERIFY(file.setPermissions(perm));
@@ -408,7 +426,7 @@ void tst_QTemporaryFile::io()
file.reset();
QFile compare(file.fileName());
- compare.open(QIODevice::ReadOnly);
+ QVERIFY(compare.open(QIODevice::ReadOnly));
QCOMPARE(compare.readAll() , data);
QCOMPARE(compare.fileTime(QFile::FileModificationTime), mtime);
}
@@ -442,7 +460,7 @@ void tst_QTemporaryFile::removeAndReOpen()
QString fileName;
{
QTemporaryFile file;
- file.open();
+ QVERIFY(file.open());
fileName = file.fileName(); // materializes any unnamed file
QVERIFY(QFile::exists(fileName));
@@ -462,7 +480,7 @@ void tst_QTemporaryFile::removeAndReOpen()
void tst_QTemporaryFile::removeUnnamed()
{
QTemporaryFile file;
- file.open();
+ QVERIFY(file.open());
// we did not call fileName(), so the file name may not have a name
QVERIFY(file.remove());
@@ -505,21 +523,25 @@ void tst_QTemporaryFile::resize()
void tst_QTemporaryFile::openOnRootDrives()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
// If it's possible to create a file in the root directory, it
// must be possible to create a temp file there too.
- foreach (QFileInfo driveInfo, QDir::drives()) {
+ const auto drives = QDir::drives();
+ for (const QFileInfo &driveInfo : drives) {
QFile testFile(driveInfo.filePath() + "XXXXXX.txt");
if (testFile.open(QIODevice::ReadWrite)) {
testFile.remove();
QTemporaryFile file(driveInfo.filePath() + "XXXXXX.txt");
file.setAutoRemove(true);
QVERIFY(file.open());
+
+ QFileInfo fi(file.fileName());
+ QCOMPARE(fi.absoluteDir(), driveInfo.filePath());
}
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
SetErrorMode(lastErrorMode);
#endif
}
@@ -569,14 +591,8 @@ void tst_QTemporaryFile::rename()
void tst_QTemporaryFile::renameFdLeak()
{
-#ifdef Q_OS_UNIX
-
-# if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- ChdirOnReturn cor(QDir::currentPath());
- QDir::setCurrent(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
-# endif
-
- const QByteArray sourceFile = QFile::encodeName(QFINDTESTDATA(__FILE__));
+#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
+ const QByteArray sourceFile = QFile::encodeName(QFINDTESTDATA("CMakeLists.txt"));
QVERIFY(!sourceFile.isEmpty());
// Test this on Unix only
@@ -612,6 +628,55 @@ void tst_QTemporaryFile::renameFdLeak()
#endif
}
+void tst_QTemporaryFile::moveToTrash()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_WEBOS) || defined(Q_OS_VXWORKS)
+ QSKIP("This platform doesn't implement a trash bin");
+#endif
+#ifdef Q_OS_WIN
+ // QTemporaryFile won't really close the file with close(), so this is
+ // expected to fail with a sharing violation error.
+ constexpr bool expectSuccess = false;
+#else
+ constexpr bool expectSuccess = true;
+#endif
+ const QByteArrayView contents = "Hello, World\n";
+
+ QTemporaryFile f(QDir::homePath() + "/tst_qtemporaryfile.moveToTrash.XXXXXX");
+ QString origFileName;
+ auto cleanup = qScopeGuard([&] {
+ if (!origFileName.isEmpty())
+ QFile::remove(origFileName);
+ if (QString fn = f.fileName(); !fn.isEmpty() && fn != origFileName)
+ QFile::remove(fn);
+ });
+
+ if (!f.open())
+ QSKIP("Failed to create temporary file");
+ f.write(contents.data(), contents.size());
+
+ // we need an actual file name:
+ // 1) so we can delete it in the clean-up guard in case we fail to trash
+ // 2) so that the file exists on Linux in the first place (no sense in
+ // trashing an unnamed file)
+ origFileName = f.fileName();
+
+ if (expectSuccess) {
+ QVERIFY2(f.moveToTrash(), qPrintable(f.errorString()));
+ QCOMPARE_NE(f.fileName(), origFileName); // must have changed!
+ QCOMPARE_NE(f.fileName(), QString());
+ QVERIFY(!QFile::exists(origFileName));
+ QVERIFY(QFile::exists(f.fileName()));
+ QCOMPARE(QFileInfo(f.fileName()).size(), contents.size());
+ } else {
+ QVERIFY(!f.moveToTrash());
+ QCOMPARE(f.fileName(), origFileName); // mustn't have changed!
+ QCOMPARE_NE(f.error(), QFile::NoError);
+ QCOMPARE_NE(f.errorString(), "Unknown error");
+ QVERIFY(QFile::exists(origFileName));
+ }
+}
+
void tst_QTemporaryFile::reOpenThroughQFile()
{
QByteArray data("abcdefghij");
@@ -780,8 +845,9 @@ void tst_QTemporaryFile::createNativeFile_data()
QTest::addColumn<bool>("valid");
QTest::addColumn<QByteArray>("content");
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- const QString nativeFilePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QStringLiteral("/resources/test.txt");
+#ifdef Q_OS_ANDROID
+ const QString nativeFilePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
+ + QStringLiteral("/resources/test.txt");
#else
const QString nativeFilePath = QFINDTESTDATA("resources/test.txt");
#endif
@@ -804,7 +870,7 @@ void tst_QTemporaryFile::createNativeFile()
QFile f(filePath);
if (currentPos != -1) {
- f.open(QIODevice::ReadOnly);
+ QVERIFY(f.open(QIODevice::ReadOnly));
f.seek(currentPos);
}
QTemporaryFile *tempFile = QTemporaryFile::createNativeFile(f);
@@ -847,7 +913,7 @@ void tst_QTemporaryFile::QTBUG_4796()
{
~CleanOnReturn()
{
- Q_FOREACH(QString tempName, tempNames)
+ for (const QString &tempName : std::as_const(tempNames))
QFile::remove(tempName);
}
@@ -935,7 +1001,7 @@ void tst_QTemporaryFile::QTBUG_4796()
}
}
- Q_FOREACH(QString const &tempName, cleaner.tempNames)
+ for (const QString &tempName : std::as_const(cleaner.tempNames))
QVERIFY( !QFile::exists(tempName) );
cleaner.reset();
@@ -949,7 +1015,7 @@ void tst_QTemporaryFile::guaranteeUnique()
// First pass. See which filename QTemporaryFile will try first.
{
QTemporaryFile tmpFile("testFile1.XXXXXX");
- tmpFile.open();
+ QVERIFY(tmpFile.open());
takenFileName = tmpFile.fileName();
QVERIFY(QFile::exists(takenFileName));
}
@@ -971,5 +1037,49 @@ void tst_QTemporaryFile::guaranteeUnique()
QVERIFY(dir.rmdir(takenFileName));
}
+void tst_QTemporaryFile::stdfilesystem()
+{
+#if !QT_CONFIG(cxx17_filesystem)
+ QSKIP("std::filesystem not available");
+#else
+ // ctor
+ {
+ std::filesystem::path testFile("testFile1.XXXXXX");
+ QTemporaryFile file(testFile);
+ QCOMPARE(file.fileTemplate(), QtPrivate::fromFilesystemPath(testFile));
+ }
+ // rename
+ {
+ QTemporaryFile file("testFile1.XXXXXX");
+ QVERIFY(file.open());
+ QByteArray payload = "abc123 I am a string";
+ file.write(payload);
+ QVERIFY(file.rename(std::filesystem::path("./test")));
+ file.close();
+
+ QFile f(u"./test"_s);
+ QVERIFY(f.exists());
+ QVERIFY(f.open(QFile::ReadOnly));
+ QCOMPARE(f.readAll(), payload);
+ }
+ // createNativeFile
+ {
+ std::filesystem::path resource(":/resources/test.txt");
+ std::unique_ptr<QTemporaryFile> tmp(QTemporaryFile::createNativeFile(resource));
+ QVERIFY(tmp);
+ QFile file(resource);
+ QVERIFY(file.open(QFile::ReadOnly));
+ QCOMPARE(tmp->readAll(), file.readAll());
+ }
+ // setFileTemplate
+ {
+ QTemporaryFile file;
+ std::filesystem::path testFile("testFile1.XXXXXX");
+ file.setFileTemplate(testFile);
+ QCOMPARE(file.fileTemplate(), QtPrivate::fromFilesystemPath(testFile));
+ }
+#endif
+}
+
QTEST_MAIN(tst_QTemporaryFile)
#include "tst_qtemporaryfile.moc"
diff --git a/tests/auto/corelib/io/qurl/CMakeLists.txt b/tests/auto/corelib/io/qurl/CMakeLists.txt
new file mode 100644
index 0000000000..d105b323df
--- /dev/null
+++ b/tests/auto/corelib/io/qurl/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qurl Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qurl LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qurl
+ SOURCES
+ tst_qurl.cpp
+ LIBRARIES
+ Qt::Concurrent
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qurl CONDITION APPLE
+ SOURCES
+ tst_qurl_mac.mm
+)
diff --git a/tests/auto/corelib/io/qurl/idna-test.c b/tests/auto/corelib/io/qurl/idna-test.c
index 035d3e1c89..856c40c7b0 100644
--- a/tests/auto/corelib/io/qurl/idna-test.c
+++ b/tests/auto/corelib/io/qurl/idna-test.c
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
struct idna
{
diff --git a/tests/auto/corelib/io/qurl/qurl.pro b/tests/auto/corelib/io/qurl/qurl.pro
deleted file mode 100644
index c046c75522..0000000000
--- a/tests/auto/corelib/io/qurl/qurl.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qurl
-QT = core testlib concurrent
-SOURCES = tst_qurl.cpp
-
-mac: OBJECTIVE_SOURCES += tst_qurl_mac.mm
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index d697dae9dd..bd454fb695 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -1,44 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define QT_DEPRECATED
-#define QT_DISABLE_DEPRECATED_BEFORE 0
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
#include <qurl.h>
-#include <QtTest/QtTest>
#include <QtCore/QDebug>
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QDirIterator>
+
#include <qcoreapplication.h>
#include <qfileinfo.h>
-#include <qtextcodec.h>
#include <qmap.h>
+#include <QtTest/private/qemulationdetector_p.h>
+
+using namespace Qt::StringLiterals;
+
Q_DECLARE_METATYPE(QUrl::FormattingOptions)
class tst_QUrl : public QObject
@@ -48,13 +27,12 @@ class tst_QUrl : public QObject
private slots:
void initTestCase();
void cleanupTestCase();
- void effectiveTLDs_data();
- void effectiveTLDs();
void getSetCheck();
void constructing();
void hashInPath();
void unc();
void assignment();
+ void orderingCompiles();
void comparison();
void comparison2_data();
void comparison2();
@@ -70,6 +48,8 @@ private slots:
void toString_PreferLocalFile();
void toString_constructed_data();
void toString_constructed();
+ void toDisplayString_PreferLocalFile_data();
+ void toDisplayString_PreferLocalFile();
void toAndFromStringList_data();
void toAndFromStringList();
void isParentOf_data();
@@ -136,8 +116,8 @@ private slots:
void emptyQueryOrFragment();
void hasFragment_data();
void hasFragment();
- void setEncodedFragment_data();
- void setEncodedFragment();
+ void setFragment_data();
+ void setFragment();
void fromEncoded();
void stripTrailingSlash_data();
void stripTrailingSlash();
@@ -311,6 +291,11 @@ void tst_QUrl::assignment()
QCOMPARE(url, copy);
}
+void tst_QUrl::orderingCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QUrl>();
+}
+
void tst_QUrl::comparison()
{
QUrl url1("http://qt-project.org/");
@@ -350,15 +335,15 @@ void tst_QUrl::comparison()
// 6.2.2.1 Make sure hexdecimal characters in percent encoding are
// treated case-insensitively
QUrl url5;
- url5.setEncodedQuery("a=%2a");
+ url5.setQuery(QLatin1String("a=%2a"));
QUrl url6;
- url6.setEncodedQuery("a=%2A");
+ url6.setQuery(QLatin1String("a=%2A"));
QCOMPARE(url5, url6);
QUrl url7;
- url7.setEncodedQuery("a=C");
+ url7.setQuery(QLatin1String("a=C"));
QUrl url8;
- url8.setEncodedQuery("a=c");
+ url8.setQuery(QLatin1String("a=c"));
QVERIFY(url7 != url8);
QVERIFY(url7 < url8);
@@ -459,18 +444,19 @@ void tst_QUrl::comparison2()
QFETCH(QUrl, url2);
QFETCH(int, ordering);
+ const Qt::weak_ordering expectedOrdering = [&ordering] {
+ if (ordering > 0)
+ return Qt::weak_ordering::greater;
+ else if (ordering < 0)
+ return Qt::weak_ordering::less;
+ return Qt::weak_ordering::equivalent;
+ }();
+
QCOMPARE(url1.toString() == url2.toString(), ordering == 0);
- QCOMPARE(url1 == url2, ordering == 0);
- QCOMPARE(url1 != url2, ordering != 0);
+ QT_TEST_ALL_COMPARISON_OPS(url1, url2, expectedOrdering);
if (ordering == 0)
QCOMPARE(qHash(url1), qHash(url2));
- QCOMPARE(url1 < url2, ordering < 0);
- QCOMPARE(!(url1 < url2), ordering >= 0);
-
- QCOMPARE(url2 < url1, ordering > 0);
- QCOMPARE(!(url2 < url1), ordering <= 0);
-
// redundant checks (the above should catch these)
QCOMPARE(url1 < url2 || url2 < url1, ordering != 0);
QVERIFY(!(url1 < url2 && url2 < url1));
@@ -502,7 +488,7 @@ void tst_QUrl::setUrl()
QVERIFY(url.isValid());
QCOMPARE(url.scheme(), QString::fromLatin1("file"));
QCOMPARE(url.path(), QString::fromLatin1("/"));
- QVERIFY(url.encodedQuery().isEmpty());
+ QVERIFY(url.query().isEmpty());
QVERIFY(url.userInfo().isEmpty());
QVERIFY(url.authority().isEmpty());
QVERIFY(url.fragment().isEmpty());
@@ -517,7 +503,7 @@ void tst_QUrl::setUrl()
QVERIFY(url.isValid());
QCOMPARE(url.scheme(), QString::fromLatin1("http"));
QCOMPARE(url.path(), QString());
- QVERIFY(url.encodedQuery().isEmpty());
+ QVERIFY(url.query().isEmpty());
QVERIFY(url.userInfo().isEmpty());
QVERIFY(url.fragment().isEmpty());
QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar"));
@@ -536,7 +522,7 @@ void tst_QUrl::setUrl()
QVERIFY(url.isValid());
QCOMPARE(url.scheme(), QString::fromLatin1("http"));
QCOMPARE(url.path(), QString());
- QVERIFY(url.encodedQuery().isEmpty());
+ QVERIFY(url.query().isEmpty());
QCOMPARE(url.userName(), QString::fromLatin1("user:"));
QCOMPARE(url.password(), QString::fromLatin1("pass@"));
QCOMPARE(url.userInfo(), QString::fromLatin1("user%3A:pass@"));
@@ -781,7 +767,7 @@ void tst_QUrl::setUrl()
QVERIFY(url.isValid());
QCOMPARE(url.scheme(), QString("http"));
QCOMPARE(url.host(), QString("1.2.3.4"));
- QCOMPARE(url.encodedQuery(), QByteArray("foo"));
+ QCOMPARE(url.query(QUrl::FullyEncoded), QLatin1String("foo"));
}
{
QUrl url;
@@ -798,13 +784,13 @@ void tst_QUrl::setUrl()
QCOMPARE(url.scheme(), QString("data"));
QCOMPARE(url.host(), QString());
QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';"));
- QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B");
+ QCOMPARE(url.path(QUrl::FullyEncoded), QLatin1String("text/javascript,d5%20%3D%20'five%5Cu0027s'%3B"));
}
{
// invalid port number
QUrl url;
- url.setEncodedUrl("foo://tel:2147483648");
+ url.setUrl(QLatin1String("foo://tel:2147483648"), QUrl::StrictMode);
QVERIFY(!url.isValid());
}
@@ -1112,7 +1098,7 @@ void tst_QUrl::toAndFromStringList()
QFETCH(QStringList, strings);
const QList<QUrl> urls = QUrl::fromStringList(strings);
- QCOMPARE(urls.count(), strings.count());
+ QCOMPARE(urls.size(), strings.size());
const QStringList converted = QUrl::toStringList(urls);
QCOMPARE(converted, strings);
}
@@ -1144,7 +1130,7 @@ void tst_QUrl::toString_constructed_data()
QTest::addColumn<QString>("host");
QTest::addColumn<int>("port");
QTest::addColumn<QString>("path");
- QTest::addColumn<QByteArray>("query");
+ QTest::addColumn<QString>("query");
QTest::addColumn<QString>("fragment");
QTest::addColumn<QString>("asString");
QTest::addColumn<QByteArray>("asEncoded");
@@ -1153,19 +1139,19 @@ void tst_QUrl::toString_constructed_data()
QString n("");
QTest::newRow("data1") << n << n << n << QString::fromLatin1("qt-project.org") << -1 << QString::fromLatin1("/index.html")
- << QByteArray() << n << QString::fromLatin1("//qt-project.org/index.html")
+ << QString() << n << QString::fromLatin1("//qt-project.org/index.html")
<< QByteArray("//qt-project.org/index.html") << 0u;
- QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QByteArray()
+ QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QString()
<< n << QString::fromLatin1("file:///root") << QByteArray("file:///root") << 0u;
QTest::newRow("userAndPass") << QString::fromLatin1("http") << QString::fromLatin1("dfaure") << QString::fromLatin1("kde")
- << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
+ << "kde.org" << 443 << QString::fromLatin1("/") << QString() << n
<< QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/")
<< 0u;
QTest::newRow("PassWithoutUser") << QString::fromLatin1("http") << n << QString::fromLatin1("kde")
- << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
+ << "kde.org" << 443 << QString::fromLatin1("/") << QString() << n
<< QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/") << 0u;
QTest::newRow("PassWithoutUser-RemovePassword") << QString::fromLatin1("http") << n << QString::fromLatin1("kde")
- << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
+ << "kde.org" << 443 << QString::fromLatin1("/") << QString() << n
<< QString::fromLatin1("http://kde.org:443/") << QByteArray("http://kde.org:443/")
<< uint(QUrl::RemovePassword);
}
@@ -1178,7 +1164,7 @@ void tst_QUrl::toString_constructed()
QFETCH(QString, host);
QFETCH(int, port);
QFETCH(QString, path);
- QFETCH(QByteArray, query);
+ QFETCH(QString, query);
QFETCH(QString, fragment);
QFETCH(QString, asString);
QFETCH(QByteArray, asEncoded);
@@ -1198,7 +1184,7 @@ void tst_QUrl::toString_constructed()
if (!path.isEmpty())
url.setPath(path);
if (!query.isEmpty())
- url.setEncodedQuery(query);
+ url.setQuery(query, QUrl::StrictMode);
if (!fragment.isEmpty())
url.setFragment(fragment);
@@ -1210,6 +1196,32 @@ void tst_QUrl::toString_constructed()
QCOMPARE(url.toEncoded(formattingOptions), asEncoded);
}
+void tst_QUrl::toDisplayString_PreferLocalFile_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QString>("string");
+
+ QTest::newRow("basic") << QUrl::fromLocalFile("/home/charles/foomoo")
+ << QString::fromLatin1("/home/charles/foomoo");
+ QTest::newRow("with%") << QUrl::fromLocalFile("/home/charles/foo%20moo")
+ << QString::fromLatin1("/home/charles/foo%20moo");
+ QTest::newRow("non-local") << QUrl("file://host/foo")
+ << QString::fromLatin1("//host/foo");
+ QTest::newRow("query-and-fragment") << QUrl("file://user:pass@example.org/a?b=c%20d%23e#frag%23ment")
+ << QString::fromLatin1("file://user@example.org/a?b=c d%23e#frag%23ment");
+ QTest::newRow("http") << QUrl("http://user:pass@example.org/a?b=c%20d%23e#frag%23ment")
+ << QString::fromLatin1("http://user@example.org/a?b=c d%23e#frag%23ment");
+}
+
+void tst_QUrl::toDisplayString_PreferLocalFile()
+{
+ QFETCH(QUrl, url);
+ QFETCH(QString, string);
+
+ if (url.isLocalFile() && url.query().isEmpty() && url.fragment().isEmpty())
+ QCOMPARE(url.toLocalFile(), string);
+ QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), string);
+}
void tst_QUrl::isParentOf()
{
@@ -1226,38 +1238,43 @@ void tst_QUrl::toLocalFile_data()
QTest::addColumn<QString>("theUrl");
QTest::addColumn<QString>("theFile");
- QTest::newRow("data0") << QString::fromLatin1("file:/a.txt") << QString::fromLatin1("/a.txt");
- QTest::newRow("data4") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
- QTest::newRow("data4a") << QString::fromLatin1("webdavs://somewebdavhost/somedir/somefile")
+ QTest::newRow("file:/") << QString::fromLatin1("file:/a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("file:///") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("file:////") << QString::fromLatin1("file:////somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
+ QTest::newRow("FILE:/") << QString::fromLatin1("FILE:/a.txt") << QString::fromLatin1("/a.txt");
+
+ QTest::newRow("path-delimiter") << QString::fromLatin1("file:///Mambo <%235>.mp3") << QString::fromLatin1("/Mambo <#5>.mp3");
+ QTest::newRow("path-percent") << QString::fromLatin1("file:///a%25.txt") << QString::fromLatin1("/a%.txt");
+ QTest::newRow("path-percent-percent") << QString::fromLatin1("file:///a%25%25.txt") << QString::fromLatin1("/a%%.txt");
+ QTest::newRow("path-percent-a-percent") << QString::fromLatin1("file:///a%25a%25.txt") << QString::fromLatin1("/a%a%.txt");
+ QTest::newRow("path-control-char") << QString::fromLatin1("file:///a%1f.txt") << QString::fromLatin1("/a\x1f.txt");
+ QTest::newRow("path-percent-hex-hex") << QString::fromLatin1("file:///%2580.txt") << QString::fromLatin1("/%80.txt");
+
+ QTest::newRow("webdavs") << QString::fromLatin1("webdavs://somewebdavhost/somedir/somefile")
#ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only.
- << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile");
+ << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile");
#else
- << QString();
+ << QString();
#endif
#ifdef Q_OS_WIN
- QTest::newRow("data5") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("c:/a.txt");
+ QTest::newRow("windows-drive-absolute") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("c:/a.txt");
#else
- QTest::newRow("data5") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
+ QTest::newRow("windows-drive-absolute") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
#endif
- QTest::newRow("data6") << QString::fromLatin1("file://somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
- QTest::newRow("data7") << QString::fromLatin1("file://somehost/") << QString::fromLatin1("//somehost/");
- QTest::newRow("data8") << QString::fromLatin1("file://somehost") << QString::fromLatin1("//somehost");
- QTest::newRow("data9") << QString::fromLatin1("file:////somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
- QTest::newRow("data10") << QString::fromLatin1("FILE:/a.txt") << QString::fromLatin1("/a.txt");
- QTest::newRow("data11") << QString::fromLatin1("file:///Mambo <%235>.mp3") << QString::fromLatin1("/Mambo <#5>.mp3");
- QTest::newRow("data12") << QString::fromLatin1("file:///a%25.txt") << QString::fromLatin1("/a%.txt");
- QTest::newRow("data13") << QString::fromLatin1("file:///a%25%25.txt") << QString::fromLatin1("/a%%.txt");
- QTest::newRow("data14") << QString::fromLatin1("file:///a%25a%25.txt") << QString::fromLatin1("/a%a%.txt");
- QTest::newRow("data15") << QString::fromLatin1("file:///a%1f.txt") << QString::fromLatin1("/a\x1f.txt");
- QTest::newRow("data16") << QString::fromLatin1("file:///%2580.txt") << QString::fromLatin1("/%80.txt");
+ QTest::newRow("windows-unc-path") << QString::fromLatin1("file://somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
+ QTest::newRow("windows-unc-root") << QString::fromLatin1("file://somehost/") << QString::fromLatin1("//somehost/");
+ QTest::newRow("windows-unc-nopath") << QString::fromLatin1("file://somehost") << QString::fromLatin1("//somehost");
+ QTest::newRow("windows-extlen-path") << QString::fromLatin1("file:////%3F/somedir/somefile") << QString::fromLatin1("//?/somedir/somefile");
+ QTest::newRow("windows-wsl-path") << QString::fromLatin1("file:////wsl$/somedir/somefile") << QString::fromLatin1("//wsl$/somedir/somefile");
+ QTest::newRow("windows-device-path") << QString::fromLatin1("file:////./somedir/somefile") << QString::fromLatin1("//./somedir/somefile");
// and some that result in empty (i.e., not local)
- QTest::newRow("xdata0") << QString::fromLatin1("/a.txt") << QString();
- QTest::newRow("xdata1") << QString::fromLatin1("//a.txt") << QString();
- QTest::newRow("xdata2") << QString::fromLatin1("///a.txt") << QString();
- QTest::newRow("xdata3") << QString::fromLatin1("foo:/a.txt") << QString();
- QTest::newRow("xdata4") << QString::fromLatin1("foo://a.txt") << QString();
- QTest::newRow("xdata5") << QString::fromLatin1("foo:///a.txt") << QString();
+ QTest::newRow("noscheme-absolute") << QString::fromLatin1("/a.txt") << QString();
+ QTest::newRow("noscheme-host") << QString::fromLatin1("//a.txt") << QString();
+ QTest::newRow("noscheme-host-path") << QString::fromLatin1("///a.txt") << QString();
+ QTest::newRow("fooscheme-absolute") << QString::fromLatin1("foo:/a.txt") << QString();
+ QTest::newRow("fooscheme-host") << QString::fromLatin1("foo://a.txt") << QString();
+ QTest::newRow("fooscheme-host-path") << QString::fromLatin1("foo:///a.txt") << QString();
}
void tst_QUrl::toLocalFile()
@@ -1276,21 +1293,57 @@ void tst_QUrl::fromLocalFile_data()
QTest::addColumn<QString>("theUrl");
QTest::addColumn<QString>("thePath");
- QTest::newRow("data0") << QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
- QTest::newRow("data1") << QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt");
- QTest::newRow("data2") << QString::fromLatin1("/a/b.txt") << QString::fromLatin1("file:///a/b.txt") << QString::fromLatin1("/a/b.txt");
- QTest::newRow("data3") << QString::fromLatin1("c:/a.txt") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
- QTest::newRow("data4") << QString::fromLatin1("//somehost/somedir/somefile") << QString::fromLatin1("file://somehost/somedir/somefile")
- << QString::fromLatin1("/somedir/somefile");
- QTest::newRow("data4a") << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile")
- << QString::fromLatin1("webdavs://somewebdavhost/somedir/somefile")
- << QString::fromLatin1("/somedir/somefile");
- QTest::newRow("data5") << QString::fromLatin1("//somehost") << QString::fromLatin1("file://somehost")
- << QString::fromLatin1("");
- QTest::newRow("data6") << QString::fromLatin1("//somehost/") << QString::fromLatin1("file://somehost/")
- << QString::fromLatin1("/");
- QTest::newRow("data7") << QString::fromLatin1("/Mambo <#5>.mp3") << QString::fromLatin1("file:///Mambo <%235>.mp3")
- << QString::fromLatin1("/Mambo <#5>.mp3");
+ QTest::newRow("absolute-path") << QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("relative-path") << QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt");
+ QTest::newRow("absolute-two-path") << QString::fromLatin1("/a/b.txt") << QString::fromLatin1("file:///a/b.txt") << QString::fromLatin1("/a/b.txt");
+ QTest::newRow("path-delimiters") << QString::fromLatin1("/Mambo <#5>.mp3") << QString::fromLatin1("file:///Mambo <%235>.mp3")
+ << QString::fromLatin1("/Mambo <#5>.mp3");
+
+ // Windows absolute details
+ QTest::newRow("windows-drive") << QString::fromLatin1("c:/a.txt") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
+
+ // Windows UNC paths
+ for (const char *suffix : { "", "/", "/somedir/somefile" }) {
+ const char *pathDescription =
+ strlen(suffix) == 0 ? "nopath" :
+ strlen(suffix) > 1 ? "path" : "root";
+
+ QTest::addRow("windows-unc-%s", pathDescription)
+ << QString("//somehost") + suffix
+ << QString("file://somehost") + suffix
+ << QString(suffix);
+#ifdef Q_OS_WIN32
+ // debackslashification only happens on Windows
+ QString suffixWithBackslashes(suffix);
+ suffixWithBackslashes.replace('/', '\\');
+
+ QTest::addRow("windows-backslash-unc-%s", pathDescription)
+ << QString(QString("\\\\somehost") + suffixWithBackslashes)
+ << QString("file://somehost") + suffix
+ << QString(suffix);
+ QTest::addRow("windows-backslash-extlen-%s", pathDescription)
+ << QString(QString("\\\\?") + suffixWithBackslashes)
+ << QString("file:////%3F") + suffix
+ << QString("//?") + suffix;
+#endif
+ QTest::addRow("windows-extlen-%s", pathDescription)
+ << QString("//?") + suffix
+ << QString("file:////%3F") + suffix
+ << QString("//?") + suffix;
+ QTest::addRow("windows-wsl-%s", pathDescription)
+ << QString("//wsl$") + suffix
+ << QString("file:////wsl$") + suffix
+ << QString("//wsl$") + suffix;
+ QTest::addRow("windows-device--%s", pathDescription)
+ << QString("//.") + suffix
+ << QString("file:////.") + suffix
+ << QString("//.") + suffix;
+ }
+
+ QTest::newRow("windows-webdav")
+ << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile")
+ << QString::fromLatin1("webdavs://somewebdavhost/somedir/somefile")
+ << QString::fromLatin1("/somedir/somefile");
}
void tst_QUrl::fromLocalFile()
@@ -1311,19 +1364,19 @@ void tst_QUrl::fromLocalFileNormalize_data()
QTest::addColumn<QString>("theUrl");
QTest::addColumn<QString>("urlWithNormalizedPath");
- QTest::newRow("data0") << QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("file:///a.txt");
- QTest::newRow("data1") << QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("file:a.txt");
- QTest::newRow("data8") << QString::fromLatin1("/a%.txt") << QString::fromLatin1("file:///a%25.txt")
- << QString::fromLatin1("file:///a%25.txt");
- QTest::newRow("data9") << QString::fromLatin1("/a%25.txt") << QString::fromLatin1("file:///a%2525.txt")
- << QString::fromLatin1("file:///a%2525.txt");
- QTest::newRow("data10") << QString::fromLatin1("/%80.txt") << QString::fromLatin1("file:///%2580.txt")
- << QString::fromLatin1("file:///%2580.txt");
- QTest::newRow("data11") << QString::fromLatin1("./a.txt") << QString::fromLatin1("file:./a.txt") << QString::fromLatin1("file:a.txt");
- QTest::newRow("data12") << QString::fromLatin1("././a.txt") << QString::fromLatin1("file:././a.txt") << QString::fromLatin1("file:a.txt");
- QTest::newRow("data13") << QString::fromLatin1("b/../a.txt") << QString::fromLatin1("file:b/../a.txt") << QString::fromLatin1("file:a.txt");
- QTest::newRow("data14") << QString::fromLatin1("/b/../a.txt") << QString::fromLatin1("file:///b/../a.txt") << QString::fromLatin1("file:///a.txt");
- QTest::newRow("data15") << QString::fromLatin1("/b/.") << QString::fromLatin1("file:///b/.") << QString::fromLatin1("file:///b");
+ QTest::newRow("absolute-path") << QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("file:///a.txt");
+ QTest::newRow("relative-path") << QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("file:a.txt");
+ QTest::newRow("percent") << QString::fromLatin1("/a%.txt") << QString::fromLatin1("file:///a%25.txt")
+ << QString::fromLatin1("file:///a%25.txt");
+ QTest::newRow("percent25") << QString::fromLatin1("/a%25.txt") << QString::fromLatin1("file:///a%2525.txt")
+ << QString::fromLatin1("file:///a%2525.txt");
+ QTest::newRow("percent80") << QString::fromLatin1("/%80.txt") << QString::fromLatin1("file:///%2580.txt")
+ << QString::fromLatin1("file:///%2580.txt");
+ QTest::newRow("relative-dot") << QString::fromLatin1("./a.txt") << QString::fromLatin1("file:./a.txt") << QString::fromLatin1("file:a.txt");
+ QTest::newRow("relative-dot-dot") << QString::fromLatin1("././a.txt") << QString::fromLatin1("file:././a.txt") << QString::fromLatin1("file:a.txt");
+ QTest::newRow("relative-path-dotdot") << QString::fromLatin1("b/../a.txt") << QString::fromLatin1("file:b/../a.txt") << QString::fromLatin1("file:a.txt");
+ QTest::newRow("absolute-path-dotdot") << QString::fromLatin1("/b/../a.txt") << QString::fromLatin1("file:///b/../a.txt") << QString::fromLatin1("file:///a.txt");
+ QTest::newRow("absolute-path-dot") << QString::fromLatin1("/b/.") << QString::fromLatin1("file:///b/.") << QString::fromLatin1("file:///b");
}
void tst_QUrl::fromLocalFileNormalize()
@@ -1342,7 +1395,7 @@ void tst_QUrl::fromLocalFileNormalize()
void tst_QUrl::macTypes()
{
-#ifndef Q_OS_MAC
+#ifndef Q_OS_DARWIN
QSKIP("This is a Mac-only test");
#else
extern void tst_QUrl_mactypes(); // in tst_qurl_mac.mm
@@ -1757,7 +1810,7 @@ void tst_QUrl::symmetry()
QCOMPARE(url.host(QUrl::EncodeUnicode | QUrl::EncodeSpaces), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se"));
QCOMPARE(url.path(), QString::fromLatin1("/pub"));
// this will be encoded ...
- QCOMPARE(url.encodedQuery().constData(), QString::fromLatin1("a=b&a=d%C3%B8&a=f").toLatin1().constData());
+ QCOMPARE(url.query(QUrl::FullyEncoded), QLatin1String("a=b&a=d%C3%B8&a=f"));
QCOMPARE(url.fragment(), QString::fromUtf8("vræl"));
QUrl onlyHost("//qt-project.org");
@@ -1803,8 +1856,8 @@ void tst_QUrl::ipvfuture_data()
QTest::newRow("non-hex-version") << "x://[vz.1234]" << false;
QTest::newRow("digit-ver") << "x://[v7.1]" << true << "x://[v7.1]";
- QTest::newRow("lowercase-hex-ver") << "x://[va.1]" << true << "x://[vA.1]";
- QTest::newRow("lowercase-hex-ver") << "x://[vA.1]" << true << "x://[vA.1]";
+ QTest::newRow("lowercase-hex-ver-lower") << "x://[va.1]" << true << "x://[vA.1]";
+ QTest::newRow("lowercase-hex-ver-upper") << "x://[vA.1]" << true << "x://[vA.1]";
QTest::newRow("data-digits") << "x://[v7.1234]" << true << "x://[v7.1234]";
QTest::newRow("data-unreserved") << "x://[v7.hello~-WORLD_.com]" << true << "x://[v7.hello~-WORLD_.com]";
@@ -1852,6 +1905,8 @@ void tst_QUrl::ipv6_data()
QTest::addColumn<bool>("isValid");
QTest::addColumn<QString>("output");
+ QTest::newRow("empty") << "//[]" << false << "";
+
QTest::newRow("case 1") << QString::fromLatin1("//[56:56:56:56:56:56:56:56]") << true
<< "//[56:56:56:56:56:56:56:56]";
QTest::newRow("case 2") << QString::fromLatin1("//[::56:56:56:56:56:56:56]") << true
@@ -2009,13 +2064,14 @@ void tst_QUrl::hasQuery()
QUrl qurl(url);
QCOMPARE(qurl.hasQuery(), trueFalse);
- QCOMPARE(qurl.encodedQuery().isNull(), !trueFalse);
+ QCOMPARE(qurl.query().isNull(), !trueFalse);
}
void tst_QUrl::nameprep()
{
- QUrl url(QString::fromUtf8("http://www.fu""\xc3""\x9f""ball.de/"));
- QCOMPARE(url.toString(), QString::fromLatin1("http://www.fussball.de/"));
+ // U+FB01 LATIN SMALL LIGATURE FI
+ QUrl url(u"http://www.\uFB01le.de/"_s);
+ QCOMPARE(url.toString(), QStringLiteral(u"http://www.file.de/"));
}
void tst_QUrl::isValid()
@@ -2078,14 +2134,15 @@ void tst_QUrl::isValid()
}
{
- QUrl url = QUrl::fromEncoded("foo://%f0%9f%93%99.example.la/g");
+ // U+1F100 DIGIT ZERO FULL STOP
+ QUrl url = QUrl::fromEncoded("foo://%f0%9f%84%80.example.la/g");
QVERIFY(!url.isValid());
QVERIFY(url.toString().isEmpty());
QCOMPARE(url.path(), QString("/g"));
- url.setHost("%f0%9f%93%99.example.la/");
+ url.setHost("%f0%9f%84%80.example.la/");
QVERIFY(!url.isValid());
QVERIFY(url.toString().isEmpty());
- url.setHost("\xf0\x9f\x93\x99.example.la/");
+ url.setHost("\xf0\x9f\x84\x80.example.la/");
QVERIFY(!url.isValid());
QVERIFY(url.toString().isEmpty());
QVERIFY2(url.errorString().contains("Invalid hostname"),
@@ -2192,10 +2249,12 @@ void tst_QUrl::schemeValidator_data()
QTest::newRow("percent-encoded") << "%68%74%%74%70://example.com" << false << "%68%74%%74%70";
static const char controls[] = "!\"$&'()*,;<=>[\\]^_`{|}~";
- for (size_t i = 0; i < sizeof(controls) - 1; ++i)
- QTest::newRow(("with-" + QByteArray(1, controls[i])).constData())
- << QString("pre%1post://example.com/").arg(QLatin1Char(controls[i]))
- << false << QString("pre%1post").arg(QLatin1Char(controls[i]));
+ for (char control : controls) {
+ const QString scheme = QLatin1String("pre") + QLatin1Char(control) + QLatin1String("post");
+ QTest::newRow((QByteArrayLiteral("with-") + control).constData())
+ << (scheme + QLatin1String("://example.com/"))
+ << false << scheme;
+ }
}
void tst_QUrl::schemeValidator()
@@ -2342,7 +2401,7 @@ void tst_QUrl::tolerantParser()
QVERIFY(url.isValid());
QVERIFY(!url.toString().isEmpty());
QCOMPARE(url.path(), QString("/path with spaces.html"));
- url.setEncodedUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode);
+ url.setUrl(QLatin1String("http://www.example.com/path%20with spaces.html"), QUrl::StrictMode);
QVERIFY(!url.isValid());
QVERIFY(url.toString().isEmpty());
}
@@ -2392,36 +2451,36 @@ void tst_QUrl::tolerantParser()
QCOMPARE(url.toEncoded(), QByteArray("%25hello.com/f%25"));
QCOMPARE(url.toString(), QString("%25hello.com/f%25"));
- url.setEncodedUrl("http://www.host.com/foo.php?P0=[2006-3-8]");
+ url.setUrl(QLatin1String("http://www.host.com/foo.php?P0=[2006-3-8]"), QUrl::StrictMode);
QVERIFY(url.isValid());
QVERIFY(!url.toString().isEmpty());
- url.setEncodedUrl("http://foo.bar/[image][1].jpg");
+ url.setUrl(QLatin1String("http://foo.bar/[image][1].jpg"), QUrl::StrictMode);
QVERIFY(url.isValid());
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg"));
QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg"));
QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg"));
- url.setEncodedUrl("http://foo.bar/%5Bimage%5D%5B1%5D.jpg");
+ url.setUrl(QLatin1String("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"), QUrl::StrictMode);
QVERIFY(url.isValid());
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
- url.setEncodedUrl("//[::56:56:56:56:56:56:56]");
+ url.setUrl(QLatin1String("//[::56:56:56:56:56:56:56]"), QUrl::StrictMode);
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]"));
QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]"));
- url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}");
+ url.setUrl(QLatin1String("data:text/css,div%20{%20border-right:%20solid;%20}"), QUrl::TolerantMode);
QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D"));
QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D"));
QCOMPARE(url.toString(), QString("data:text/css,div %7B border-right: solid; %7D"));
}
{
- QByteArray tsdgeos("http://google.com/c?c=Translation+%C2%BB+trunk|");
+ const QString tsdgeos = QLatin1String("http://google.com/c?c=Translation+%C2%BB+trunk|");
QUrl tsdgeosQUrl;
- tsdgeosQUrl.setEncodedUrl(tsdgeos, QUrl::TolerantMode);
+ tsdgeosQUrl.setUrl(tsdgeos, QUrl::TolerantMode);
QVERIFY(tsdgeosQUrl.isValid()); // failed in Qt-4.4, works in Qt-4.5
QByteArray tsdgeosExpected("http://google.com/c?c=Translation+%C2%BB+trunk%7C");
QCOMPARE(QString(tsdgeosQUrl.toEncoded()), QString(tsdgeosExpected));
@@ -2626,31 +2685,31 @@ void tst_QUrl::emptyQueryOrFragment()
// start with an empty one
QUrl url("http://www.foo.bar/baz");
QVERIFY(!url.hasQuery());
- QVERIFY(url.encodedQuery().isNull());
+ QVERIFY(url.query().isNull());
// add encodedQuery
url.setQuery("abc=def");
QVERIFY(url.hasQuery());
QCOMPARE(url.query(), QString(QLatin1String("abc=def")));
QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def")));
- url.setEncodedQuery("abc=def");
+ url.setQuery(QLatin1String("abc=def"));
QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def")));
// remove encodedQuery
url.setQuery(QString());
QVERIFY(!url.hasQuery());
- QVERIFY(url.encodedQuery().isNull());
+ QVERIFY(url.query().isNull());
QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz")));
- url.setEncodedQuery(QByteArray());
+ url.setQuery(QString());
QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz")));
// add empty encodedQuery
url.setQuery("");
QVERIFY(url.hasQuery());
- QVERIFY(url.encodedQuery().isEmpty());
- QVERIFY(!url.encodedQuery().isNull());
+ QVERIFY(url.query().isEmpty());
+ QVERIFY(!url.query().isNull());
QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?")));
- url.setEncodedQuery("");
+ url.setQuery(QLatin1String(""));
QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?")));
}
}
@@ -2682,35 +2741,33 @@ void tst_QUrl::hasFragment()
QCOMPARE(qurl.fragment().isNull(), !trueFalse);
}
-void tst_QUrl::setEncodedFragment_data()
+void tst_QUrl::setFragment_data()
{
- QTest::addColumn<QByteArray>("base");
- QTest::addColumn<QByteArray>("fragment");
- QTest::addColumn<QByteArray>("expected");
+ QTest::addColumn<QString>("base");
+ QTest::addColumn<QString>("fragment");
+ QTest::addColumn<QString>("expected");
- typedef QByteArray BA;
- QTest::newRow("null") << BA("http://www.kde.org") << BA() << BA("http://www.kde.org");
- QTest::newRow("empty") << BA("http://www.kde.org") << BA("") << BA("http://www.kde.org#");
- QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc");
- QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new");
- QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c");
- QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a%23b"); // toString uses "a#b"
- QTest::newRow("unicode") << BA("http://www.kde.org") << BA("\xc3\xa9") << BA("http://www.kde.org#%C3%A9");
- QTest::newRow("binary") << BA("http://www.kde.org") << BA("\x00\xc0\x80", 3) << BA("http://www.kde.org#%00%C0%80");
+ QTest::newRow("null") << QString::fromLatin1("http://www.kde.org") << QString() << QString::fromLatin1("http://www.kde.org");
+ QTest::newRow("empty") << QString::fromLatin1("http://www.kde.org") << QString::fromLatin1("") << QString::fromLatin1("http://www.kde.org#");
+ QTest::newRow("basic test") << QString::fromLatin1("http://www.kde.org") << QString::fromLatin1("abc") << QString::fromLatin1("http://www.kde.org#abc");
+ QTest::newRow("initial url has fragment") << QString::fromLatin1("http://www.kde.org#old") << QString::fromLatin1("new") << QString::fromLatin1("http://www.kde.org#new");
+ QTest::newRow("encoded fragment") << QString::fromLatin1("http://www.kde.org") << QString::fromLatin1("a%20c") << QString::fromLatin1("http://www.kde.org#a%20c");
+ QTest::newRow("with #") << QString::fromLatin1("http://www.kde.org") << QString::fromLatin1("a#b") << QString::fromLatin1("http://www.kde.org#a%23b"); // toString uses "a#b"
+ QTest::newRow("unicode") << QString::fromLatin1("http://www.kde.org") << QString::fromUtf8("\xc3\xa9") << QString::fromLatin1("http://www.kde.org#%C3%A9");
}
-void tst_QUrl::setEncodedFragment()
+void tst_QUrl::setFragment()
{
- QFETCH(QByteArray, base);
- QFETCH(QByteArray, fragment);
- QFETCH(QByteArray, expected);
+ QFETCH(QString, base);
+ QFETCH(QString, fragment);
+ QFETCH(QString, expected);
QUrl u;
- u.setEncodedUrl(base, QUrl::TolerantMode);
+ u.setUrl(base, QUrl::TolerantMode);
QVERIFY(u.isValid());
- u.setEncodedFragment(fragment);
+ u.setFragment(fragment);
QVERIFY(u.isValid());
QCOMPARE(!fragment.isNull(), u.hasFragment());
- QCOMPARE(QString::fromLatin1(u.toEncoded()), QString::fromLatin1(expected));
+ QCOMPARE(QString::fromUtf8(u.toEncoded()), expected);
}
void tst_QUrl::fromEncoded()
@@ -3120,8 +3177,10 @@ void tst_QUrl::fromUserInput_data()
QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl;
// FTP with double slashes in path
- QTest::newRow("ftp-double-slash-1") << "ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath");
- QTest::newRow("ftp-double-slash-1") << "ftp://ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath");
+ QTest::newRow("ftp-double-slash-no-scheme")
+ << "ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath");
+ QTest::newRow("ftp-double-slash-scheme")
+ << "ftp://ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath");
}
void tst_QUrl::fromUserInput()
@@ -3172,12 +3231,10 @@ void tst_QUrl::fromUserInputWithCwd_data()
QTest::newRow(QByteArray(fileName) + "-in-dot") << fileName << QStringLiteral(".") << url << url;
}
-#ifndef Q_OS_WINRT // WinRT cannot cd outside current / sandbox
QDir parent(base);
QVERIFY(parent.cdUp());
QUrl parentUrl = QUrl::fromLocalFile(parent.path());
QTest::newRow("dotdot") << ".." << base << parentUrl << parentUrl;
-#endif
QTest::newRow("nonexisting") << "nonexisting" << base << QUrl("http://nonexisting") << QUrl::fromLocalFile(base + "/nonexisting");
QTest::newRow("short-url") << "example.org" << base << QUrl("http://example.org") << QUrl::fromLocalFile(base + "/example.org");
@@ -3258,14 +3315,14 @@ void tst_QUrl::isEmptyForEncodedUrl()
{
{
QUrl url;
- url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
+ url.setUrl(QLatin1String("LABEL=USB_STICK"), QUrl::TolerantMode);
QVERIFY( url.isValid() );
QCOMPARE( url.path(), QString("LABEL=USB_STICK") );
QVERIFY( !url.isEmpty() );
}
{
QUrl url;
- url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
+ url.setUrl(QLatin1String("LABEL=USB_STICK"), QUrl::TolerantMode);
QVERIFY( url.isValid() );
QVERIFY( !url.isEmpty() );
QCOMPARE( url.path(), QString("LABEL=USB_STICK") );
@@ -3277,7 +3334,7 @@ void tst_QUrl::isEmptyForEncodedUrl()
void tst_QUrl::toEncodedNotUsingUninitializedPath()
{
QUrl url;
- url.setEncodedPath("/test.txt");
+ url.setPath(QLatin1String("/test.txt"));
url.setHost("example.com");
QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt");
@@ -3387,39 +3444,6 @@ void tst_QUrl::acceptEmptyAuthoritySegments()
QCOMPARE(QUrl(file_uni_bar, QUrl::StrictMode).toString(), file_triple_bar);
}
-void tst_QUrl::effectiveTLDs_data()
-{
- QTest::addColumn<QUrl>("domain");
- QTest::addColumn<QString>("TLD");
-
- QTest::newRow("yes0") << QUrl::fromEncoded("http://test.co.uk") << ".co.uk";
- QTest::newRow("yes1") << QUrl::fromEncoded("http://test.com") << ".com";
- QTest::newRow("yes2") << QUrl::fromEncoded("http://www.test.de") << ".de";
- QTest::newRow("yes3") << QUrl::fromEncoded("http://test.ulm.museum") << ".ulm.museum";
- QTest::newRow("yes4") << QUrl::fromEncoded("http://www.com.krodsherad.no") << ".krodsherad.no";
- QTest::newRow("yes5") << QUrl::fromEncoded("http://www.co.uk.1.bg") << ".1.bg";
- QTest::newRow("yes6") << QUrl::fromEncoded("http://www.com.com.cn") << ".com.cn";
- QTest::newRow("yes7") << QUrl::fromEncoded("http://www.test.org.ws") << ".org.ws";
- QTest::newRow("yes9") << QUrl::fromEncoded("http://www.com.co.uk.wallonie.museum") << ".wallonie.museum";
- QTest::newRow("yes10") << QUrl::fromEncoded("http://www.com.evje-og-hornnes.no") << ".evje-og-hornnes.no";
- QTest::newRow("yes11") << QUrl::fromEncoded("http://www.bla.kamijima.ehime.jp") << ".kamijima.ehime.jp";
- QTest::newRow("yes12") << QUrl::fromEncoded("http://www.bla.kakuda.miyagi.jp") << ".kakuda.miyagi.jp";
- QTest::newRow("yes13") << QUrl::fromEncoded("http://mypage.betainabox.com") << ".betainabox.com";
- QTest::newRow("yes14") << QUrl::fromEncoded("http://mypage.rhcloud.com") << ".rhcloud.com";
- QTest::newRow("yes15") << QUrl::fromEncoded("http://mypage.int.az") << ".int.az";
- QTest::newRow("yes16") << QUrl::fromEncoded("http://anything.pagespeedmobilizer.com") << ".pagespeedmobilizer.com";
- QTest::newRow("yes17") << QUrl::fromEncoded("http://anything.eu-central-1.compute.amazonaws.com") << ".eu-central-1.compute.amazonaws.com";
- QTest::newRow("yes18") << QUrl::fromEncoded("http://anything.ltd.hk") << ".ltd.hk";
-}
-
-void tst_QUrl::effectiveTLDs()
-{
- QFETCH(QUrl, domain);
- QFETCH(QString, TLD);
- QCOMPARE(domain.topLevelDomain(QUrl::PrettyDecoded), TLD);
- QCOMPARE(domain.topLevelDomain(QUrl::FullyDecoded), TLD);
-}
-
void tst_QUrl::lowercasesScheme()
{
QUrl url;
@@ -3642,17 +3666,6 @@ void tst_QUrl::componentEncodings()
QCOMPARE(url.toString(formatting),
(((QString(toString ))))); // the weird () and space is to align the output
- if (formatting == QUrl::FullyEncoded) {
- QCOMPARE(url.encodedUserName(), userName.toUtf8());
- QCOMPARE(url.encodedPassword(), password.toUtf8());
- // no encodedUserInfo
- QCOMPARE(url.encodedHost(), host.toUtf8());
- // no encodedAuthority
- QCOMPARE(url.encodedPath(), path.toUtf8());
- QCOMPARE(url.encodedQuery(), query.toUtf8());
- QCOMPARE(url.encodedFragment(), fragment.toUtf8());
- }
-
// repeat with the URL we got from toString
QUrl url2(toString);
QCOMPARE(url2.userName(formatting), userName);
@@ -3796,106 +3809,106 @@ void tst_QUrl::setComponents_data()
QTest::newRow("invalid-username-1") << QUrl("http://example.com")
<< int(UserName) << "{}" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-username-2") << QUrl("http://example.com")
<< int(UserName) << "foo/bar" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-username-3") << QUrl("http://example.com")
<< int(UserName) << "foo:bar" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-password-1") << QUrl("http://example.com")
<< int(Password) << "{}" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-password-2") << QUrl("http://example.com")
<< int(Password) << "foo/bar" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-password-3") << QUrl("http://example.com")
<< int(Password) << "foo:bar" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-userinfo-1") << QUrl("http://example.com")
<< int(UserInfo) << "{}" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-userinfo-2") << QUrl("http://example.com")
<< int(UserInfo) << "foo/bar" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-host-1") << QUrl("http://example.com")
<< int(Host) << "-not-valid-" << Tolerant << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-host-2") << QUrl("http://example.com")
<< int(Host) << "%31%30.%30.%30.%31" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-authority-1") << QUrl("http://example.com")
<< int(Authority) << "-not-valid-" << Tolerant << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-authority-2") << QUrl("http://example.com")
<< int(Authority) << "%31%30.%30.%30.%31" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-path-0") << QUrl("http://example.com")
<< int(Path) << "{}" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-query-1") << QUrl("http://example.com")
<< int(Query) << "{}" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("invalid-fragment-1") << QUrl("http://example.com")
<< int(Fragment) << "{}" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
// these test cases are "compound invalid":
// they produces isValid == false, but the original is still available
QTest::newRow("invalid-path-1") << QUrl("/relative")
<< int(Path) << "c:/" << Strict << false
- << PrettyDecoded << "c:/" << "";
+ << PrettyDecoded << "c:/" << QString();
QTest::newRow("invalid-path-2") << QUrl("http://example.com")
<< int(Path) << "relative" << Strict << false
- << PrettyDecoded << "relative" << "";
+ << PrettyDecoded << "relative" << QString();
QTest::newRow("invalid-path-3") << QUrl("trash:/")
<< int(Path) << "//path" << Tolerant << false
- << PrettyDecoded << "//path" << "";
+ << PrettyDecoded << "//path" << QString();
// -- test bad percent encoding --
// unnecessary to test the scheme, since percent-decoding is not performed in it;
// see tests above
QTest::newRow("bad-percent-username") << QUrl("http://example.com")
<< int(UserName) << "bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-password") << QUrl("http://user@example.com")
<< int(Password) << "bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-userinfo-1") << QUrl("http://example.com")
<< int(UserInfo) << "bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-userinfo-2") << QUrl("http://example.com")
<< int(UserInfo) << "bar%:foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-userinfo-3") << QUrl("http://example.com")
<< int(UserInfo) << "bar:%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-authority-1") << QUrl("http://example.com")
<< int(Authority) << "bar%foo@example.org" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-authority-2") << QUrl("http://example.com")
<< int(Authority) << "bar%:foo@example.org" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-authority-3") << QUrl("http://example.com")
<< int(Authority) << "bar:%foo@example.org" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-authority-4") << QUrl("http://example.com")
<< int(Authority) << "bar:foo@bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-host") << QUrl("http://example.com")
<< int(Host) << "bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-path") << QUrl("http://example.com")
<< int(Path) << "/bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-query") << QUrl("http://example.com")
<< int(Query) << "bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("bad-percent-fragment") << QUrl("http://example.com")
<< int(Fragment) << "bar%foo" << Strict << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
// -- test decoded behaviour --
// '%' characters are not permitted in the scheme, this tests that it fails to set anything
@@ -3911,7 +3924,7 @@ void tst_QUrl::setComponents_data()
// '%' characters are not permitted in the hostname, these test that it fails to set anything
QTest::newRow("invalid-host-encode") << QUrl("http://example.com")
<< int(Host) << "ex%61mple.com" << Decoded << false
- << PrettyDecoded << "" << "";
+ << PrettyDecoded << QString() << QString();
QTest::newRow("path-encode") << QUrl("http://example.com/foo")
<< int(Path) << "/bar%23" << Decoded << true
<< PrettyDecoded << "/bar%2523" << "http://example.com/bar%2523";
@@ -3950,41 +3963,44 @@ void tst_QUrl::setComponents()
QFETCH(int, encoding);
QFETCH(QString, output);
+#define QNULLCOMPARE(a, b) \
+ do { QCOMPARE(a, b); QCOMPARE(a.isNull(), b.isNull()); } while (false)
+
switch (component) {
case Scheme:
// scheme is only parsed in strict mode
copy.setScheme(newValue);
- QCOMPARE(copy.scheme(), output);
+ QCOMPARE(copy.scheme(), output); // schemes don't become null
break;
case Path:
copy.setPath(newValue, QUrl::ParsingMode(parsingMode));
- QCOMPARE(copy.path(QUrl::ComponentFormattingOptions(encoding)), output);
+ QNULLCOMPARE(copy.path(QUrl::ComponentFormattingOptions(encoding)), output);
break;
case UserInfo:
copy.setUserInfo(newValue, QUrl::ParsingMode(parsingMode));
- QCOMPARE(copy.userInfo(QUrl::ComponentFormattingOptions(encoding)), output);
+ QNULLCOMPARE(copy.userInfo(QUrl::ComponentFormattingOptions(encoding)), output);
break;
case UserName:
copy.setUserName(newValue, QUrl::ParsingMode(parsingMode));
- QCOMPARE(copy.userName(QUrl::ComponentFormattingOptions(encoding)), output);
+ QNULLCOMPARE(copy.userName(QUrl::ComponentFormattingOptions(encoding)), output);
break;
case Password:
copy.setPassword(newValue, QUrl::ParsingMode(parsingMode));
- QCOMPARE(copy.password(QUrl::ComponentFormattingOptions(encoding)), output);
+ QNULLCOMPARE(copy.password(QUrl::ComponentFormattingOptions(encoding)), output);
break;
case Host:
copy.setHost(newValue, QUrl::ParsingMode(parsingMode));
- QCOMPARE(copy.host(QUrl::ComponentFormattingOptions(encoding)), output);
+ QNULLCOMPARE(copy.host(QUrl::ComponentFormattingOptions(encoding)), output);
break;
case Authority:
copy.setAuthority(newValue, QUrl::ParsingMode(parsingMode));
- QCOMPARE(copy.authority(QUrl::ComponentFormattingOptions(encoding)), output);
+ QNULLCOMPARE(copy.authority(QUrl::ComponentFormattingOptions(encoding)), output);
break;
case Query:
@@ -3999,6 +4015,7 @@ void tst_QUrl::setComponents()
QCOMPARE(copy.fragment(QUrl::ComponentFormattingOptions(encoding)), output);
break;
}
+#undef QNULLCOMPARE
QFETCH(bool, isValid);
QCOMPARE(copy.isValid(), isValid);
@@ -4069,16 +4086,15 @@ public:
for (int i = 0 ; i < m_urls.size(); ++i)
m_urls[i] = QUrl::fromEncoded("http://www.kde.org", QUrl::StrictMode);
}
- QVector<QUrl> m_urls;
+ QList<QUrl> m_urls;
};
-static const UrlStorage * s_urlStorage = 0;
+static const UrlStorage * s_urlStorage = nullptr;
void tst_QUrl::testThreadingHelper()
{
const UrlStorage* storage = s_urlStorage;
- for (int i = 0 ; i < storage->m_urls.size(); ++i ) {
- const QUrl& u = storage->m_urls.at(i);
+ for (const auto &u : storage->m_urls) {
// QVERIFY/QCOMPARE trigger race conditions in helgrind
if (!u.isValid())
qFatal("invalid url");
@@ -4110,12 +4126,30 @@ void tst_QUrl::testThreadingHelper()
void tst_QUrl::testThreading()
{
+ enum { Count = 100 };
+
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("This test fails in QEMU and looks like because of a data race, QTBUG-93176");
s_urlStorage = new UrlStorage;
- QThreadPool::globalInstance()->setMaxThreadCount(100);
- QFutureSynchronizer<void> sync;
- for (int i = 0; i < 100; ++i)
- sync.addFuture(QtConcurrent::run(this, &tst_QUrl::testThreadingHelper));
- sync.waitForFinished();
+ QThreadPool::globalInstance()->setMaxThreadCount(Count);
+
+ // Written this way because wasm need the eventloop
+ QList<QFuture<void>> futures;
+ futures.reserve(Count);
+
+ for (int i = 0; i < Count; ++i)
+ futures.push_back(QtConcurrent::run(&tst_QUrl::testThreadingHelper, this));
+
+ QEventLoop loop;
+ std::atomic<int> remaining = Count;
+ for (int i = 0; i < Count; ++i) {
+ futures[i].then([&]() {
+ if (!--remaining)
+ loop.quit();
+ });
+ }
+ loop.exec();
+
delete s_urlStorage;
}
diff --git a/tests/auto/corelib/io/qurl/tst_qurl_mac.mm b/tests/auto/corelib/io/qurl/tst_qurl_mac.mm
index f2d151a090..a7cf3ebee5 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl_mac.mm
+++ b/tests/auto/corelib/io/qurl/tst_qurl_mac.mm
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
+#include <QTest>
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
diff --git a/tests/auto/corelib/io/qurlinternal/CMakeLists.txt b/tests/auto/corelib/io/qurlinternal/CMakeLists.txt
new file mode 100644
index 0000000000..a5c36b6ed9
--- /dev/null
+++ b/tests/auto/corelib/io/qurlinternal/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qurlinternal LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if(NOT QT_FEATURE_private_tests)
+ return()
+endif()
+
+#####################################################################
+## tst_qurlinternal Test:
+#####################################################################
+
+qt_internal_add_test(tst_qurlinternal
+ SOURCES
+ tst_qurlinternal.cpp
+ utf8data.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/io/qurlinternal/qurlinternal.pro b/tests/auto/corelib/io/qurlinternal/qurlinternal.pro
deleted file mode 100644
index 3828512dce..0000000000
--- a/tests/auto/corelib/io/qurlinternal/qurlinternal.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-requires(qtConfig(private_tests))
-TARGET = tst_qurlinternal
-SOURCES += tst_qurlinternal.cpp ../../codecs/utf8/utf8data.cpp
-QT = core core-private testlib
diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
index bcf6d6c32b..1c121ac719 100644
--- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
+++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
@@ -1,36 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QUrl>
-#include <QtTest/QtTest>
+#include <QTest>
-#include "private/qtldurl_p.h"
#include "private/qurl_p.h"
// For testsuites
@@ -42,18 +16,20 @@
#define STRINGPREP_BIDI_BOTH_L_AND_RAL 4
#define STRINGPREP_BIDI_LEADTRAIL_NOT_RAL 5
-struct ushortarray {
- ushortarray() {}
+using namespace Qt::StringLiterals;
+
+struct char16array {
+ char16array() {}
template <size_t N>
- ushortarray(unsigned short (&array)[N])
+ char16array(char16_t (&array)[N])
{
- memcpy(points, array, N*sizeof(unsigned short));
+ memcpy(points, array, N*sizeof(char16_t));
}
- unsigned short points[100];
+ char16_t points[100];
};
-Q_DECLARE_METATYPE(ushortarray)
+Q_DECLARE_METATYPE(char16array)
Q_DECLARE_METATYPE(QUrl::FormattingOptions)
Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions)
@@ -66,10 +42,6 @@ private Q_SLOTS:
#ifdef QT_BUILD_INTERNAL
void idna_testsuite_data();
void idna_testsuite();
- void nameprep_testsuite_data();
- void nameprep_testsuite();
- void nameprep_highcodes_data();
- void nameprep_highcodes();
#endif
void ace_testsuite_data();
void ace_testsuite();
@@ -85,8 +57,6 @@ private Q_SLOTS:
void encodingRecode();
void encodingRecodeInvalidUtf8_data();
void encodingRecodeInvalidUtf8();
- void recodeByteArray_data();
- void recodeByteArray();
};
#include "tst_qurlinternal.moc"
@@ -94,146 +64,149 @@ private Q_SLOTS:
void tst_QUrlInternal::idna_testsuite_data()
{
QTest::addColumn<int>("numchars");
- QTest::addColumn<ushortarray>("unicode");
+ QTest::addColumn<char16array>("unicode");
QTest::addColumn<QByteArray>("punycode");
QTest::addColumn<int>("allowunassigned");
QTest::addColumn<int>("usestd3asciirules");
QTest::addColumn<int>("toasciirc");
QTest::addColumn<int>("tounicoderc");
- unsigned short d1[] = { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643,
- 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A,
- 0x061F };
- QTest::newRow("Arabic (Egyptian)") << 17 << ushortarray(d1)
+ char16_t d1[] = { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643,
+ 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A,
+ 0x061F };
+ QTest::newRow("Arabic (Egyptian)") << 17 << char16array(d1)
<< QByteArray(IDNA_ACE_PREFIX "egbpdaj6bu4bxfgehfvwxn")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d2[] = { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D,
- 0x6587 };
- QTest::newRow("Chinese (simplified)") << 9 << ushortarray(d2)
+ char16_t d2[] = { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D,
+ 0x6587 };
+ QTest::newRow("Chinese (simplified)") << 9 << char16array(d2)
<< QByteArray(IDNA_ACE_PREFIX "ihqwcrb4cv8a8dqg056pqjye")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d3[] = { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D,
- 0x6587 };
- QTest::newRow("Chinese (traditional)") << 9 << ushortarray(d3)
+ char16_t d3[] = { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D,
+ 0x6587 };
+ QTest::newRow("Chinese (traditional)") << 9 << char16array(d3)
<< QByteArray(IDNA_ACE_PREFIX "ihqwctvzc91f659drss3x8bo0yb")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d4[] = { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073,
- 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076,
- 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 };
- QTest::newRow("Czech") << 22 << ushortarray(d4)
+ char16_t d4[] = { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073,
+ 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076,
+ 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 };
+ QTest::newRow("Czech") << 22 << char16array(d4)
<< QByteArray(IDNA_ACE_PREFIX "Proprostnemluvesky-uyb24dma41a")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d5[] = { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5,
- 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9,
- 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA };
- QTest::newRow("Hebrew") << 22 << ushortarray(d5)
+ char16_t d5[] = { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5,
+ 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9,
+ 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA };
+ QTest::newRow("Hebrew") << 22 << char16array(d5)
<< QByteArray(IDNA_ACE_PREFIX "4dbcagdahymbxekheh6e0a7fei0b")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d6[] = { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928,
- 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902,
- 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938,
- 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 };
- QTest::newRow("Hindi (Devanagari)") << 30 << ushortarray(d6)
+ char16_t d6[] = { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928,
+ 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902,
+ 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938,
+ 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 };
+ QTest::newRow("Hindi (Devanagari)") << 30 << char16array(d6)
<< QByteArray(IDNA_ACE_PREFIX "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd")
<< 0 << 0 << IDNA_SUCCESS;
- unsigned short d7[] = { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E,
- 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044,
- 0x306E, 0x304B };
- QTest::newRow("Japanese (kanji and hiragana)") << 18 << ushortarray(d7)
+ char16_t d7[] = { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E,
+ 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044,
+ 0x306E, 0x304B };
+ QTest::newRow("Japanese (kanji and hiragana)") << 18 << char16array(d7)
<< QByteArray(IDNA_ACE_PREFIX "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa")
<< 0 << 0 << IDNA_SUCCESS;
- unsigned short d8[] = { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435,
- 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432,
- 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443,
- 0x0441, 0x0441, 0x043A, 0x0438 };
- QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d8)
+ char16_t d8[] = { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435,
+ 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432,
+ 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443,
+ 0x0441, 0x0441, 0x043A, 0x0438 };
+ QTest::newRow("Russian (Cyrillic)") << 28 << char16array(d8)
<< QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d9[] = { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F,
- 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069,
- 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074,
- 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065,
- 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C };
- QTest::newRow("Spanish") << 40 << ushortarray(d9)
+ char16_t d9[] = { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F,
+ 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069,
+ 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074,
+ 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065,
+ 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C };
+ QTest::newRow("Spanish") << 40 << char16array(d9)
<< QByteArray(IDNA_ACE_PREFIX "PorqunopuedensimplementehablarenEspaol-fmd56a")
<< 0 << 0 << IDNA_SUCCESS;
- unsigned short d10[] = { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD,
- 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3,
- 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069,
- 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 };
- QTest::newRow("Vietnamese") << 31 << ushortarray(d10)
+ char16_t d10[] = { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD,
+ 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3,
+ 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069,
+ 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 };
+ QTest::newRow("Vietnamese") << 31 << char16array(d10)
<< QByteArray(IDNA_ACE_PREFIX "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g")
<< 0 << 0 << IDNA_SUCCESS;
- unsigned short d11[] = { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F };
- QTest::newRow("Japanese") << 8 << ushortarray(d11)
+ char16_t d11[] = { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F };
+ QTest::newRow("Japanese") << 8 << char16array(d11)
<< QByteArray(IDNA_ACE_PREFIX "3B-ww4c5e180e575a65lsy2b")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
// this test does NOT include nameprepping, so the capitals will remain
- unsigned short d12[] = { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069,
- 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052,
- 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 };
- QTest::newRow("Japanese2") << 24 << ushortarray(d12)
+ char16_t d12[] = { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069,
+ 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052,
+ 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 };
+ QTest::newRow("Japanese2") << 24 << char16array(d12)
<< QByteArray(IDNA_ACE_PREFIX "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n")
<< 0 << 0 << IDNA_SUCCESS;
- unsigned short d13[] = { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E,
- 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061,
- 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834,
- 0x6240 };
- QTest::newRow("Japanese3") << 25 << ushortarray(d13)
+ char16_t d13[] = { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E,
+ 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061,
+ 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834,
+ 0x6240 };
+ QTest::newRow("Japanese3") << 25 << char16array(d13)
<< QByteArray(IDNA_ACE_PREFIX "Hello-Another-Way--fc4qua05auwb3674vfr0b")
<< 0 << 0 << IDNA_SUCCESS;
- unsigned short d14[] = { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 };
- QTest::newRow("Japanese4") << 8 << ushortarray(d14)
+ char16_t d14[] = { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 };
+ QTest::newRow("Japanese4") << 8 << char16array(d14)
<< QByteArray(IDNA_ACE_PREFIX "2-u9tlzr9756bt3uc0v")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d15[] = { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069,
- 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D };
- QTest::newRow("Japanese5") << 13 << ushortarray(d15)
+ char16_t d15[] = { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069,
+ 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D };
+ QTest::newRow("Japanese5") << 13 << char16array(d15)
<< QByteArray(IDNA_ACE_PREFIX "MajiKoi5-783gue6qz075azm5e")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d16[] = { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 };
- QTest::newRow("Japanese6") << 9 << ushortarray(d16)
+ char16_t d16[] = { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 };
+ QTest::newRow("Japanese6") << 9 << char16array(d16)
<< QByteArray(IDNA_ACE_PREFIX "de-jg4avhby1noc0d")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d17[] = { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 };
- QTest::newRow("Japanese7") << 7 << ushortarray(d17)
+ char16_t d17[] = { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 };
+ QTest::newRow("Japanese7") << 7 << char16array(d17)
<< QByteArray(IDNA_ACE_PREFIX "d9juau41awczczp")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d18[] = { 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac };
- QTest::newRow("Greek") << 8 << ushortarray(d18)
+ char16_t d18[] = { 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac };
+ QTest::newRow("Greek") << 8 << char16array(d18)
<< QByteArray(IDNA_ACE_PREFIX "hxargifdar")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d19[] = { 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
- 0x0127, 0x0061 };
- QTest::newRow("Maltese (Malti)") << 10 << ushortarray(d19)
+ char16_t d19[] = { 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
+ 0x0127, 0x0061 };
+ QTest::newRow("Maltese (Malti)") << 10 << char16array(d19)
<< QByteArray(IDNA_ACE_PREFIX "bonusaa-5bb1da")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
- unsigned short d20[] = {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
- 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
- 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
- 0x0441, 0x0441, 0x043a, 0x0438 };
- QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d20)
+ char16_t d20[] = {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
+ 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
+ 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
+ 0x0441, 0x0441, 0x043a, 0x0438 };
+ QTest::newRow("Russian (Cyrillic)") << 28 << char16array(d20)
<< QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l")
<< 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
+
+ char16_t d21[] = { 0xd800, 0xdef7 };
+ QTest::newRow("U+102F7") << 2 << char16array(d21) << QByteArray(IDNA_ACE_PREFIX "r97c");
}
#endif
@@ -241,323 +214,16 @@ void tst_QUrlInternal::idna_testsuite_data()
void tst_QUrlInternal::idna_testsuite()
{
QFETCH(int, numchars);
- QFETCH(ushortarray, unicode);
+ QFETCH(char16array, unicode);
QFETCH(QByteArray, punycode);
QString result;
- qt_punycodeEncoder((QChar*)unicode.points, numchars, &result);
+ qt_punycodeEncoder(QStringView{unicode.points, numchars}, &result);
QCOMPARE(result.toLatin1(), punycode);
QCOMPARE(qt_punycodeDecoder(result), QString::fromUtf16(unicode.points, numchars));
}
#endif
-#ifdef QT_BUILD_INTERNAL
-void tst_QUrlInternal::nameprep_testsuite_data()
-{
- QTest::addColumn<QString>("in");
- QTest::addColumn<QString>("out");
- QTest::addColumn<QString>("profile");
- QTest::addColumn<int>("flags");
- QTest::addColumn<int>("rc");
-
- QTest::newRow("Map to nothing")
- << QString::fromUtf8("foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B"
- "bar""\xE2\x80\x8B\xE2\x81\xA0""baz\xEF\xB8\x80\xEF\xB8\x88"
- "\xEF\xB8\x8F\xEF\xBB\xBF")
- << QString::fromUtf8("foobarbaz")
- << QString() << 0 << 0;
-
- QTest::newRow("Case folding ASCII U+0043 U+0041 U+0046 U+0045")
- << QString::fromUtf8("CAFE")
- << QString::fromUtf8("cafe")
- << QString() << 0 << 0;
-
- QTest::newRow("Case folding 8bit U+00DF (german sharp s)")
- << QString::fromUtf8("\xC3\x9F")
- << QString("ss")
- << QString() << 0 << 0;
-
- QTest::newRow("Case folding U+0130 (turkish capital I with dot)")
- << QString::fromUtf8("\xC4\xB0")
- << QString::fromUtf8("i\xcc\x87")
- << QString() << 0 << 0;
-
- QTest::newRow("Case folding multibyte U+0143 U+037A")
- << QString::fromUtf8("\xC5\x83\xCD\xBA")
- << QString::fromUtf8("\xC5\x84 \xCE\xB9")
- << QString() << 0 << 0;
-
- QTest::newRow("Case folding U+2121 U+33C6 U+1D7BB")
- << QString::fromUtf8("\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB")
- << QString::fromUtf8("telc\xE2\x88\x95""kg\xCF\x83")
- << QString() << 0 << 0;
-
- QTest::newRow("Normalization of U+006a U+030c U+00A0 U+00AA")
- << QString::fromUtf8("\x6A\xCC\x8C\xC2\xA0\xC2\xAA")
- << QString::fromUtf8("\xC7\xB0 a")
- << QString() << 0 << 0;
-
- QTest::newRow("Case folding U+1FB7 and normalization")
- << QString::fromUtf8("\xE1\xBE\xB7")
- << QString::fromUtf8("\xE1\xBE\xB6\xCE\xB9")
- << QString() << 0 << 0;
-
- QTest::newRow("Self-reverting case folding U+01F0 and normalization")
-// << QString::fromUtf8("\xC7\xF0") ### typo in the original testsuite
- << QString::fromUtf8("\xC7\xB0")
- << QString::fromUtf8("\xC7\xB0")
- << QString() << 0 << 0;
-
- QTest::newRow("Self-reverting case folding U+0390 and normalization")
- << QString::fromUtf8("\xCE\x90")
- << QString::fromUtf8("\xCE\x90")
- << QString() << 0 << 0;
-
- QTest::newRow("Self-reverting case folding U+03B0 and normalization")
- << QString::fromUtf8("\xCE\xB0")
- << QString::fromUtf8("\xCE\xB0")
- << QString() << 0 << 0;
-
- QTest::newRow("Self-reverting case folding U+1E96 and normalization")
- << QString::fromUtf8("\xE1\xBA\x96")
- << QString::fromUtf8("\xE1\xBA\x96")
- << QString() << 0 << 0;
-
- QTest::newRow("Self-reverting case folding U+1F56 and normalization")
- << QString::fromUtf8("\xE1\xBD\x96")
- << QString::fromUtf8("\xE1\xBD\x96")
- << QString() << 0 << 0;
-
- QTest::newRow("ASCII space character U+0020")
- << QString::fromUtf8("\x20")
- << QString::fromUtf8("\x20")
- << QString() << 0 << 0;
-
- QTest::newRow("Non-ASCII 8bit space character U+00A0")
- << QString::fromUtf8("\xC2\xA0")
- << QString::fromUtf8("\x20")
- << QString() << 0 << 0;
-
- QTest::newRow("Non-ASCII multibyte space character U+1680")
- << QString::fromUtf8("x\xE1\x9A\x80x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Non-ASCII multibyte space character U+2000")
- << QString::fromUtf8("\xE2\x80\x80")
- << QString::fromUtf8("\x20")
- << QString() << 0 << 0;
-
- QTest::newRow("Zero Width Space U+200b")
- << QString::fromUtf8("\xE2\x80\x8b")
- << QString()
- << QString() << 0 << 0;
-
- QTest::newRow("Non-ASCII multibyte space character U+3000")
- << QString::fromUtf8("\xE3\x80\x80")
- << QString::fromUtf8("\x20")
- << QString() << 0 << 0;
-
- QTest::newRow("ASCII control characters U+0010 U+007F")
- << QString::fromUtf8("\x10\x7F")
- << QString::fromUtf8("\x10\x7F")
- << QString() << 0 << 0;
-
- QTest::newRow("Non-ASCII 8bit control character U+0080")
- << QString::fromUtf8("x\xC2\x80x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Non-ASCII 8bit control character U+0085")
- << QString::fromUtf8("x\xC2\x85x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Non-ASCII multibyte control character U+180E")
- << QString::fromUtf8("x\xE1\xA0\x8Ex")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Zero Width No-Break Space U+FEFF")
- << QString::fromUtf8("\xEF\xBB\xBF")
- << QString()
- << QString() << 0 << 0;
-
- QTest::newRow("Non-ASCII control character U+1D175")
- << QString::fromUtf8("x\xF0\x9D\x85\xB5x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Plane 0 private use character U+F123")
- << QString::fromUtf8("x\xEF\x84\xA3x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Plane 15 private use character U+F1234")
- << QString::fromUtf8("x\xF3\xB1\x88\xB4x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Plane 16 private use character U+10F234")
- << QString::fromUtf8("x\xF4\x8F\x88\xB4x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Non-character code point U+8FFFE")
- << QString::fromUtf8("x\xF2\x8F\xBF\xBEx")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Non-character code point U+10FFFF")
- << QString::fromUtf8("x\xF4\x8F\xBF\xBFx")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Surrogate code U+DF42")
- << QString::fromUtf8("x\xED\xBD\x82x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Non-plain text character U+FFFD")
- << QString::fromUtf8("x\xEF\xBF\xBDx")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Ideographic description character U+2FF5")
- << QString::fromUtf8("x\xE2\xBF\xB5x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Display property character U+0341")
- << QString::fromUtf8("\xCD\x81")
- << QString::fromUtf8("\xCC\x81")
- << QString() << 0 << 0;
-
- QTest::newRow("Left-to-right mark U+200E")
- << QString::fromUtf8("x\xE2\x80\x8Ex")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Deprecated U+202A")
- << QString::fromUtf8("x\xE2\x80\xAA")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Language tagging character U+E0001")
- << QString::fromUtf8("x\xF3\xA0\x80\x81x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Language tagging character U+E0042")
- << QString::fromUtf8("x\xF3\xA0\x81\x82x")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
-
- QTest::newRow("Bidi: RandALCat character U+05BE and LCat characters")
- << QString::fromUtf8("foo\xD6\xBE""bar")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL;
-
- QTest::newRow("Bidi: RandALCat character U+FD50 and LCat characters")
- << QString::fromUtf8("foo\xEF\xB5\x90""bar")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL;
-
- QTest::newRow("Bidi: RandALCat character U+FB38 and LCat characters")
- << QString::fromUtf8("foo\xEF\xB9\xB6""bar")
- << QString::fromUtf8("foo \xd9\x8e""bar")
- << QString() << 0 << 0;
-
- QTest::newRow("Bidi: RandALCat without trailing RandALCat U+0627 U+0031")
- << QString::fromUtf8("\xD8\xA7\x31")
- << QString()
- << QString("Nameprep") << 0 << STRINGPREP_BIDI_LEADTRAIL_NOT_RAL;
-
- QTest::newRow("Bidi: RandALCat character U+0627 U+0031 U+0628")
- << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8")
- << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8")
- << QString() << 0 << 0;
-
- QTest::newRow("Unassigned code point U+E0002")
- << QString::fromUtf8("\xF3\xA0\x80\x82")
- << QString()
- << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED;
-
- QTest::newRow("Larger test (shrinking)")
- << QString::fromUtf8("X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2"
- "\xaa\xce\xb0\xe2\x80\x80")
- << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ")
- << QString("Nameprep") << 0 << 0;
-
- QTest::newRow("Larger test (expanding)")
- << QString::fromUtf8("X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80")
- << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88"
- "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91"
- "\xe3\x83\xbc\xe3\x83\x88")
- << QString() << 0 << 0;
-}
-#endif
-
-#ifdef QT_BUILD_INTERNAL
-void tst_QUrlInternal::nameprep_testsuite()
-{
- QFETCH(QString, in);
- QFETCH(QString, out);
- QFETCH(QString, profile);
-
- qt_nameprep(&in, 0);
- QCOMPARE(in, out);
-}
-#endif
-
-#ifdef QT_BUILD_INTERNAL
-void tst_QUrlInternal::nameprep_highcodes_data()
-{
- QTest::addColumn<QString>("in");
- QTest::addColumn<QString>("out");
- QTest::addColumn<QString>("profile");
- QTest::addColumn<int>("flags");
- QTest::addColumn<int>("rc");
-
- {
- QChar st[] = { '-', 0xd801, 0xdc1d, 'a' };
- QChar se[] = { '-', 0xd801, 0xdc45, 'a' };
- QTest::newRow("highcodes (U+1041D)")
- << QString(st, sizeof(st)/sizeof(st[0]))
- << QString(se, sizeof(se)/sizeof(se[0]))
- << QString() << 0 << 0;
- }
- {
- QChar st[] = { 0x011C, 0xd835, 0xdf6e, 0x0110 };
- QChar se[] = { 0x011D, 0x03C9, 0x0111 };
- QTest::newRow("highcodes (U+1D76E)")
- << QString(st, sizeof(st)/sizeof(st[0]))
- << QString(se, sizeof(se)/sizeof(se[0]))
- << QString() << 0 << 0;
- }
- {
- QChar st[] = { 'D', 'o', '\'', 0x2060, 'h' };
- QChar se[] = { 'd', 'o', '\'', 'h' };
- QTest::newRow("highcodes (D, o, ', U+2060, h)")
- << QString(st, sizeof(st)/sizeof(st[0]))
- << QString(se, sizeof(se)/sizeof(se[0]))
- << QString() << 0 << 0;
- }
-}
-#endif
-
-#ifdef QT_BUILD_INTERNAL
-void tst_QUrlInternal::nameprep_highcodes()
-{
- QFETCH(QString, in);
- QFETCH(QString, out);
- QFETCH(QString, profile);
-
- qt_nameprep(&in, 0);
- QCOMPARE(in, out);
-}
-#endif
-
void tst_QUrlInternal::ace_testsuite_data()
{
QTest::addColumn<QString>("in");
@@ -569,8 +235,9 @@ void tst_QUrlInternal::ace_testsuite_data()
QTest::newRow("ascii-mixed") << "FLuke" << "fluke" << "fluke" << "fluke";
QTest::newRow("ascii-upper") << "FLUKE" << "fluke" << "fluke" << "fluke";
- QTest::newRow("asciifolded") << QString::fromLatin1("stra\337e") << "strasse" << "." << "strasse";
- QTest::newRow("asciifolded-dotcom") << QString::fromLatin1("stra\337e.example.com") << "strasse.example.com" << "." << "strasse.example.com";
+ // U+FB01 LATIN SMALL LIGATURE FI
+ QTest::newRow("asciifolded") << u"\uFB01le"_s << "file" << "." << "file";
+ QTest::newRow("asciifolded-dotcom") << u"\uFB01le.example.com"_s << "file.example.com" << "." << "file.example.com";
QTest::newRow("greek-mu") << QString::fromLatin1("\265V")
<<"xn--v-lmb"
<< "."
@@ -652,29 +319,35 @@ void tst_QUrlInternal::ace_testsuite_data()
<< taiwaneseIDN;
// violations / invalids
- QTest::newRow("invalid-punycode") << "xn--z" << "xn--z" << "xn--z" << "xn--z";
+ auto badRow = [](const char *name, const char *text) {
+ QTest::newRow(name) << text << text << text << text;
+ };
+
+ badRow("invalid-punycode", "xn--z");
// U+00A0 NO-BREAK SPACE encodes to Punycode "6a"
// but it is prohibited and should have caused encoding failure
- QTest::newRow("invalid-nameprep-prohibited") << "xn--6a" << "xn--6a" << "xn--6a" << "xn--6a";
+ badRow("invalid-nameprep-prohibited", "xn--6a");
// U+00AD SOFT HYPHEN between "a" and "b" encodes to Punycode "ab-5da"
// but it should have been removed in the nameprep stage
- QTest::newRow("invalid-nameprep-maptonothing") << "xn-ab-5da" << "xn-ab-5da" << "xn-ab-5da" << "xn-ab-5da";
+ badRow("invalid-nameprep-maptonothing", "xn-ab-5da");
// U+00C1 LATIN CAPITAL LETTER A WITH ACUTE encodes to Punycode "4ba"
// but it should have nameprepped to lowercase first
- QTest::newRow("invalid-nameprep-uppercase") << "xn--4ba" << "xn--4ba" << "xn--4ba" << "xn--4ba";
+ badRow("invalid-nameprep-uppercase", "xn--4ba");
// U+00B5 MICRO SIGN encodes to Punycode "sba"
// but is should have nameprepped to NFKC U+03BC GREEK SMALL LETTER MU
- QTest::newRow("invalid-nameprep-nonnfkc") << "xn--sba" << "xn--sba" << "xn--sba" << "xn--sba";
+ badRow("invalid-nameprep-nonnfkc", "xn--sba");
- // U+04CF CYRILLIC SMALL LETTER PALOCHKA encodes to "s5a"
- // but it's not in RFC 3454's allowed character list (Unicode 3.2)
- QTest::newRow("invalid-nameprep-unassigned") << "xn--s5a" << "xn--s5a" << "xn--s5a" << "xn--s5a";
- // same character, see QTBUG-60364
- QTest::newRow("invalid-nameprep-unassigned2") << "xn--80ak6aa92e" << "xn--80ak6aa92e" << "xn--80ak6aa92e" << "xn--80ak6aa92e";
+ // Decodes to "a" in some versions, see QTBUG-95689
+ badRow("punycode-overflow-1", "xn--5p32g");
+ // Decodes to the same string as "xn--097c" in some versions, see QTBUG-95689
+ badRow("punycode-overflow-2", "xn--400595c");
+
+ // Encodes 2**32, decodes to empty string in some versions
+ badRow("punycode-overflow-3", "xn--l0902716a");
}
void tst_QUrlInternal::ace_testsuite()
@@ -729,9 +402,6 @@ void tst_QUrlInternal::std3violations_data()
QTest::newRow("control") << "\033foo" << false;
QTest::newRow("bang") << "foo!" << false;
QTest::newRow("plus") << "foo+bar" << false;
- QTest::newRow("dot") << "foo.bar";
- QTest::newRow("startingdot") << ".bar" << false;
- QTest::newRow("startingdot2") << ".example.com" << false;
QTest::newRow("slash") << "foo/bar" << true;
QTest::newRow("colon") << "foo:80" << true;
QTest::newRow("question") << "foo?bar" << true;
@@ -752,17 +422,6 @@ void tst_QUrlInternal::std3violations()
{
QFETCH(QString, source);
-#ifdef QT_BUILD_INTERNAL
- {
- QString prepped = source;
- qt_nameprep(&prepped, 0);
- QVERIFY(!qt_check_std3rules(prepped.constData(), prepped.length()));
- }
-#endif
-
- if (source.contains('.'))
- return; // this test ends here
-
QUrl url;
url.setHost(source);
QVERIFY(url.host().isEmpty());
@@ -848,7 +507,7 @@ void tst_QUrlInternal::correctEncodedMistakes()
QString dataTag = QTest::currentDataTag();
QString output = dataTag;
- if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), 0))
+ if (!qt_urlRecode(output, input, { }))
output += input;
QCOMPARE(output, dataTag + expected);
@@ -856,7 +515,7 @@ void tst_QUrlInternal::correctEncodedMistakes()
output = dataTag;
QString expected2 = QUrl::fromPercentEncoding(expected.toLatin1());
- if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyDecoded))
+ if (!qt_urlRecode(output, input, QUrl::FullyDecoded))
output += input;
QCOMPARE(output, dataTag + expected2);
}
@@ -1020,7 +679,7 @@ void tst_QUrlInternal::encodingRecode()
QString output = QTest::currentDataTag();
expected.prepend(output);
- if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), encodingMode))
+ if (!qt_urlRecode(output, input, encodingMode))
output += input;
QCOMPARE(output, expected);
}
@@ -1048,54 +707,24 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8()
// prepend some data to be sure that it remains there
QString output = QTest::currentDataTag();
- if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::PrettyDecoded))
+ if (!qt_urlRecode(output, input, QUrl::PrettyDecoded))
output += input;
QCOMPARE(output, QTest::currentDataTag() + input);
// this is just control
output = QTest::currentDataTag();
- if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded))
+ if (!qt_urlRecode(output, input, QUrl::FullyEncoded))
output += input;
QCOMPARE(output, QTest::currentDataTag() + input);
// verify for security reasons that all bad UTF-8 data got replaced by QChar::ReplacementCharacter
output = QTest::currentDataTag();
- if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded))
+ if (!qt_urlRecode(output, input, QUrl::FullyEncoded))
output += input;
- for (int i = int(strlen(QTest::currentDataTag())); i < output.length(); ++i) {
+ for (int i = int(strlen(QTest::currentDataTag())); i < output.size(); ++i) {
QVERIFY2(output.at(i).unicode() < 0x80 || output.at(i) == QChar::ReplacementCharacter,
qPrintable(QString("Character at i == %1 was U+%2").arg(i).arg(output.at(i).unicode(), 4, 16, QLatin1Char('0'))));
}
}
-void tst_QUrlInternal::recodeByteArray_data()
-{
- QTest::addColumn<QByteArray>("input");
- QTest::addColumn<QString>("expected");
-
- QTest::newRow("null") << QByteArray() << QString();
- QTest::newRow("empty") << QByteArray("") << QString("");
- QTest::newRow("normal") << QByteArray("Hello") << "Hello";
- QTest::newRow("valid-utf8") << QByteArray("\xc3\xa9") << "%C3%A9";
- QTest::newRow("percent-encoded") << QByteArray("%C3%A9%00%C0%80") << "%C3%A9%00%C0%80";
- QTest::newRow("invalid-utf8-1") << QByteArray("\xc3\xc3") << "%C3%C3";
- QTest::newRow("invalid-utf8-2") << QByteArray("\xc0\x80") << "%C0%80";
-
- // note: percent-encoding the control characters ("\0" -> "%00") would also
- // be correct, but it's unnecessary for this function
- QTest::newRow("binary") << QByteArray("\0\x1f", 2) << QString::fromLatin1("\0\x1f", 2);;
- QTest::newRow("binary+percent-encoded") << QByteArray("\0%25", 4) << QString::fromLatin1("\0%25", 4);
-}
-
-void tst_QUrlInternal::recodeByteArray()
-{
- QFETCH(QByteArray, input);
- QFETCH(QString, expected);
- QString output = qt_urlRecodeByteArray(input);
-
- QCOMPARE(output.isNull(), input.isNull());
- QCOMPARE(output.isEmpty(), input.isEmpty());
- QCOMPARE(output, expected);
-}
-
QTEST_APPLESS_MAIN(tst_QUrlInternal)
diff --git a/tests/auto/corelib/io/qurlinternal/utf8data.cpp b/tests/auto/corelib/io/qurlinternal/utf8data.cpp
new file mode 100644
index 0000000000..edeff0182c
--- /dev/null
+++ b/tests/auto/corelib/io/qurlinternal/utf8data.cpp
@@ -0,0 +1,135 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QTest>
+
+void loadInvalidUtf8Rows()
+{
+ // Wrong continuations
+ QTest::newRow("bad-continuation-1char") << QByteArray("\x80");
+ QTest::newRow("bad-continuation-2chars-1") << QByteArray("\xC2\xC0");
+ QTest::newRow("bad-continuation-2chars-2") << QByteArray("\xC3\xDF");
+ QTest::newRow("bad-continuation-2chars-3") << QByteArray("\xC7\xF0");
+ QTest::newRow("bad-continuation-3chars-1") << QByteArray("\xE0\xA0\xC0");
+ QTest::newRow("bad-continuation-3chars-2") << QByteArray("\xE0\xC0\xA0");
+ QTest::newRow("bad-continuation-4chars-1") << QByteArray("\xF0\x90\x80\xC0");
+ QTest::newRow("bad-continuation-4chars-2") << QByteArray("\xF0\x90\xC0\x80");
+ QTest::newRow("bad-continuation-4chars-3") << QByteArray("\xF0\xC0\x80\x80");
+
+ // Too short
+ QTest::newRow("too-short-2chars") << QByteArray("\xC2");
+ QTest::newRow("too-short-3chars-1") << QByteArray("\xE0");
+ QTest::newRow("too-short-3chars-2") << QByteArray("\xE0\xA0");
+ QTest::newRow("too-short-4chars-1") << QByteArray("\xF0");
+ QTest::newRow("too-short-4chars-2") << QByteArray("\xF0\x90");
+ QTest::newRow("too-short-4chars-3") << QByteArray("\xF0\x90\x80");
+
+ // Surrogate pairs must now be present either
+ // U+D800: 1101 10 0000 00 0000
+ // encoding: xxxz:1101 xz10:0000 xz00:0000
+ QTest::newRow("hi-surrogate") << QByteArray("\xED\xA0\x80");
+ // U+DC00: 1101 11 0000 00 0000
+ // encoding: xxxz:1101 xz11:0000 xz00:0000
+ QTest::newRow("lo-surrogate") << QByteArray("\xED\xB0\x80");
+
+ // not even in pair:
+ QTest::newRow("surrogate-pair") << QByteArray("\xED\xA0\x80\xED\xB0\x80");
+
+ // Characters outside the Unicode range:
+ // 0x110000: 00 0100 01 0000 00 0000 00 0000
+ // encoding: xxxx:z100 xz01:0000 xz00:0000 xz00:0000
+ QTest::newRow("non-unicode-1") << QByteArray("\xF4\x90\x80\x80");
+ // 0x200000: 00 1000 00 0000 00 0000 00 0000
+ // encoding: xxxx:xz00 xz00:1000 xz00:0000 xz00:0000 xz00:0000
+ QTest::newRow("non-unicode-2") << QByteArray("\xF8\x88\x80\x80\x80");
+ // 0x04000000: 0100 00 0000 00 0000 00 0000 00 0000
+ // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("non-unicode-3") << QByteArray("\xFC\x84\x80\x80\x80\x80");
+ // 0x7fffffff: 1 11 1111 11 1111 11 1111 11 1111 11 1111
+ // encoding: xxxx:xxz0 xz00:0100 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("non-unicode-4") << QByteArray("\xFD\xBF\xBF\xBF\xBF\xBF");
+
+ // As seen above, 0xFE and 0xFF never appear:
+ QTest::newRow("fe") << QByteArray("\xFE");
+ QTest::newRow("fe-bis") << QByteArray("\xFE\xBF\xBF\xBF\xBF\xBF\xBF");
+ QTest::newRow("ff") << QByteArray("\xFF");
+ QTest::newRow("ff-bis") << QByteArray("\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF");
+
+ // some combinations in UTF-8 are invalid even though they have the proper bits set
+ // these are known as overlong sequences
+
+ // "A": U+0041: 01 00 0001
+ // overlong 2: xxz0:0001 xz00:0001
+ QTest::newRow("overlong-1-2") << QByteArray("\xC1\x81");
+ // overlong 3: xxxz:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-3") << QByteArray("\xE0\x81\x81");
+ // overlong 4: xxxx:z000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-4") << QByteArray("\xF0\x80\x81\x81");
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-5") << QByteArray("\xF8\x80\x80\x81\x81");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0001 xz00:0001
+ QTest::newRow("overlong-1-6") << QByteArray("\xFC\x80\x80\x80\x81\x81");
+
+ // U+0080: 10 00 0000
+ // proper encoding: xxz0:0010 xz00:0000
+ // overlong 3: xxxz:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-3") << QByteArray("\xE0\x82\x80");
+ // overlong 4: xxxx:z000 xz00:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-4") << QByteArray("\xF0\x80\x82\x80");
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-5") << QByteArray("\xF8\x80\x80\x82\x80");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz00:0010 xz00:0000
+ QTest::newRow("overlong-2-6") << QByteArray("\xFC\x80\x80\x80\x82\x80");
+
+ // U+0800: 10 0000 00 0000
+ // proper encoding: xxxz:0000 xz10:0000 xz00:0000
+ // overlong 4: xxxx:z000 xz00:0000 xz10:0000 xz00:0000
+ QTest::newRow("overlong-3-4") << QByteArray("\xF0\x80\xA0\x80");
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0000 xz10:0000 xz00:0000
+ QTest::newRow("overlong-3-5") << QByteArray("\xF8\x80\x80\xA0\x80");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0000 xz10:0000 xz00:0000
+ QTest::newRow("overlong-3-6") << QByteArray("\xFC\x80\x80\x80\xA0\x80");
+
+ // U+010000: 00 0100 00 0000 00 0000
+ // proper encoding: xxxx:z000 xz00:0100 xz00:0000 xz00:0000
+ // overlong 5: xxxx:xz00 xz00:0000 xz00:0100 xz00:0000 xz00:0000
+ QTest::newRow("overlong-4-5") << QByteArray("\xF8\x80\x84\x80\x80");
+ // overlong 6: xxxx:xxz0 xz00:0000 xz00:0000 xz00:0100 xz00:0000 xz00:0000
+ QTest::newRow("overlong-4-6") << QByteArray("\xFC\x80\x80\x84\x80\x80");
+
+}
+
+void loadNonCharactersRows()
+{
+ // Unicode has a couple of "non-characters" that one can use internally
+ // These characters are allowed for text-interchange (see http://www.unicode.org/versions/corrigendum9.html)
+ //
+ // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
+ // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
+ // U+FDEF (inclusive)
+
+ // U+FDD0 through U+FDEF
+ for (int i = 0; i < 16; ++i) {
+ char utf8[] = { char(0357), char(0267), char(0220 + i), 0 };
+ QString utf16 = QChar(0xfdd0 + i);
+ QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16;
+ }
+
+ // the last two in Planes 1 through 16
+ for (uint plane = 1; plane <= 16; ++plane) {
+ for (uint lower = 0xfffe; lower < 0x10000; ++lower) {
+ uint ucs4 = (plane << 16) | lower;
+ char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)),
+ char(0x80 | (uchar(ucs4 >> 12) & 0x3f)),
+ char(0x80 | (uchar(ucs4 >> 6) & 0x3f)),
+ char(0x80 | (uchar(ucs4) & 0x3f)),
+ 0 };
+ const auto utf16 = QChar::fromUcs4(ucs4);
+
+ QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QStringView{utf16}.toString();
+ }
+ }
+
+ QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe));
+ QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff));
+}
diff --git a/tests/auto/corelib/io/qurlquery/CMakeLists.txt b/tests/auto/corelib/io/qurlquery/CMakeLists.txt
new file mode 100644
index 0000000000..c9f5491416
--- /dev/null
+++ b/tests/auto/corelib/io/qurlquery/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qurlquery Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qurlquery LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qurlquery
+ SOURCES
+ tst_qurlquery.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/io/qurlquery/qurlquery.pro b/tests/auto/corelib/io/qurlquery/qurlquery.pro
deleted file mode 100644
index 68129f356f..0000000000
--- a/tests/auto/corelib/io/qurlquery/qurlquery.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-QT = core core-private testlib
-TARGET = tst_qurlquery
-CONFIG += testcase
-SOURCES += tst_qurlquery.cpp
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp
index d839141091..8360bdbe28 100644
--- a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp
+++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp
@@ -1,38 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2012 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QtCore/QUrlQuery>
-#include <QtTest/QtTest>
typedef QList<QPair<QString, QString> > QueryItems;
Q_DECLARE_METATYPE(QueryItems)
Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions)
+using namespace Qt::StringLiterals;
+
class tst_QUrlQuery : public QObject
{
Q_OBJECT
@@ -44,6 +24,9 @@ public:
}
private Q_SLOTS:
+ void compareCompiles();
+ void compareEquality_data();
+ void compareEquality();
void constructing();
void addRemove();
void multiAddRemove();
@@ -67,46 +50,35 @@ private Q_SLOTS:
void old_hasQueryItem();
};
-static QString prettyElement(const QString &key, const QString &value)
-{
- QString result;
- if (key.isNull())
- result += "null -> ";
- else
- result += '"' % key % "\" -> ";
- if (value.isNull())
- result += "null";
- else
- result += '"' % value % '"';
- return result;
-}
-
-static QString prettyPair(QList<QPair<QString, QString> >::const_iterator it)
+static QString prettyPair(const QPair<QString, QString> &pair)
{
- return prettyElement(it->first, it->second);
+ const auto represent = [](const QString &s) {
+ return s.isNull() ? u"null"_s : u'"' + s + u'"';
+ };
+ return represent(pair.first) + " -> "_L1 + represent(pair.second);
}
-template <typename T>
-static QByteArray prettyList(const T &items)
+static QByteArray prettyList(const QueryItems &items)
{
- QString result = "(";
- bool first = true;
- typename T::const_iterator it = items.constBegin();
- for ( ; it != items.constEnd(); ++it) {
- if (!first)
- result += ", ";
- first = false;
- result += prettyPair(it);
- }
- result += QLatin1Char(')');
+ if (items.isEmpty())
+ return "()";
+ auto it = items.constBegin();
+ QString result = u'(' + prettyPair(*it);
+ for (++it; it != items.constEnd(); ++it)
+ result += ", "_L1 + prettyPair(*it);
+ result += u')';
return result.toLocal8Bit();
}
-static bool compare(const QList<QPair<QString, QString> > &actual, const QueryItems &expected,
+static bool compare(const QueryItems &actual, const QueryItems &expected,
const char *actualStr, const char *expectedStr, const char *file, int line)
{
+ auto formatter = [](const void *val) -> const char * {
+ const QueryItems items = *static_cast<const QueryItems *>(val);
+ return qstrdup(prettyList(items).constData());
+ };
return QTest::compare_helper(actual == expected, "Compared values are not the same",
- qstrdup(prettyList(actual)), qstrdup(prettyList(expected).data()),
+ &actual, &expected, formatter, formatter,
actualStr, expectedStr, file, line);
}
@@ -155,6 +127,48 @@ static QUrlQuery emptyQuery()
return QUrlQuery();
}
+void tst_QUrlQuery::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QUrlQuery>();
+}
+
+void tst_QUrlQuery::compareEquality_data()
+{
+ QTest::addColumn<QUrlQuery>("url1");
+ QTest::addColumn<QUrlQuery>("url2");
+ QTest::addColumn<bool>("equal");
+
+ QTest::newRow("empty-empty") << QUrlQuery() << QUrlQuery() << true;
+
+ QUrlQuery notEmpty;
+ notEmpty.addQueryItem("a", "b");
+ QTest::newRow("empty-notEmpty") << QUrlQuery() << notEmpty << false;
+
+ QUrlQuery notEmpty_copy = notEmpty;
+ QTest::newRow("sameItems") << notEmpty_copy << notEmpty << true;
+
+ QUrlQuery notEmpty_modified = notEmpty;
+ notEmpty_modified.addQueryItem("c", "d");
+ QTest::newRow("addedItems") << notEmpty_copy << notEmpty_modified << false;
+
+ QUrlQuery notEmpty2;
+ notEmpty2.addQueryItem("c", "d");
+ QTest::newRow("differentItems") << notEmpty2 << notEmpty << false;
+
+ QUrlQuery differentPairDelimiters;
+ differentPairDelimiters.setQueryDelimiters('(', ')');
+ QTest::newRow("defaultDelimiters-differentDelimiters") << QUrlQuery() << differentPairDelimiters
+ << false;
+}
+
+void tst_QUrlQuery::compareEquality()
+{
+ QFETCH(QUrlQuery, url1);
+ QFETCH(QUrlQuery, url2);
+ QFETCH(bool, equal);
+ QT_TEST_EQUALITY_OPS(url1, url2, equal);
+}
+
void tst_QUrlQuery::constructing()
{
QUrlQuery empty;
@@ -173,7 +187,7 @@ void tst_QUrlQuery::constructing()
QVERIFY(!copy.isDetached());
QCOMPARE(copy, empty);
QCOMPARE(qHash(copy), qHash(empty));
- QVERIFY(!(copy != empty));
+ QT_TEST_EQUALITY_OPS(copy, empty, true);
copy = empty;
QCOMPARE(copy, empty);
@@ -205,20 +219,50 @@ void tst_QUrlQuery::constructing()
other.addQueryItem("a", "b");
QVERIFY(!other.isEmpty());
QVERIFY(other.isDetached());
- QVERIFY(other != empty);
- QVERIFY(!(other == empty));
+ QCOMPARE_NE(other, empty);
+ QT_TEST_EQUALITY_OPS(other, empty, false);
+ // copy-construct
QUrlQuery copy(other);
QCOMPARE(copy, other);
copy.clear();
QVERIFY(copy.isEmpty());
- QVERIFY(copy != other);
+ QCOMPARE_NE(copy, other);
+ // copy-assign
copy = other;
QVERIFY(!copy.isEmpty());
QCOMPARE(copy, other);
+ // move-construct
+ QUrlQuery moved(std::move(other));
+ QCOMPARE(moved, copy);
+
+ // self move-assign
+ {
+ auto &self = moved; // prevent -Wself-move
+ moved = std::move(self);
+ }
+ QCOMPARE(moved, copy);
+
+ // self move-assign of moved-from (Hinnant Criterion)
+ {
+ auto &self = other; // prevent -Wself-move
+ other = std::move(self);
+ }
+ // shouldn't crash; here, or further down
+
+ // copy-assign to moved-from object
+ other = copy;
+ QCOMPARE(other, copy);
+ QCOMPARE(other, moved);
+
+ // move-assign
+ moved = std::move(other);
+ QCOMPARE(moved, copy);
+
+ // (move-)assign default-constructed
copy = QUrlQuery();
QVERIFY(copy.isEmpty());
@@ -233,27 +277,38 @@ void tst_QUrlQuery::constructing()
query += qMakePair(QString("prosent"), QString("%"));
copy.setQueryItems(query);
QVERIFY(!copy.isEmpty());
+
+ QUrlQuery fromList = {
+ {QString("type"), QString("login")},
+ {QString("name"), QString::fromUtf8("åge nissemannsen")},
+ {QString("ole&du"), QString::fromUtf8("anne+jørgen=sant")},
+ {QString("prosent"), QString("%")}
+ };
+ QCOMPARE(fromList, copy);
}
void tst_QUrlQuery::addRemove()
{
QUrlQuery query;
+ QCOMPARE(query, query);
{
// one item
query.addQueryItem("a", "b");
QVERIFY(!query.isEmpty());
QVERIFY(query.hasQueryItem("a"));
+ QCOMPARE_NE(query, QUrlQuery());
QCOMPARE(query.queryItemValue("a"), QString("b"));
QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
QList<QPair<QString, QString> > allItems = query.queryItems();
- QCOMPARE(allItems.count(), 1);
+ QCOMPARE(allItems.size(), 1);
QCOMPARE(allItems.at(0).first, QString("a"));
QCOMPARE(allItems.at(0).second, QString("b"));
}
QUrlQuery original = query;
+ QCOMPARE(query, original);
{
// two items
@@ -266,12 +321,12 @@ void tst_QUrlQuery::addRemove()
QCOMPARE(query.allQueryItemValues("c"), QStringList() << "d");
QList<QPair<QString, QString> > allItems = query.queryItems();
- QCOMPARE(allItems.count(), 2);
+ QCOMPARE(allItems.size(), 2);
QVERIFY(allItems.contains(qItem("a", "b")));
QVERIFY(allItems.contains(qItem("c", "d")));
- QVERIFY(query != original);
- QVERIFY(!(query == original));
+ QCOMPARE_NE(query, original);
+ QT_TEST_EQUALITY_OPS(query, original, false);
}
{
@@ -289,12 +344,12 @@ void tst_QUrlQuery::addRemove()
QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
QList<QPair<QString, QString> > allItems = query.queryItems();
- QCOMPARE(allItems.count(), 1);
+ QCOMPARE(allItems.size(), 1);
QCOMPARE(allItems.at(0).first, QString("a"));
QCOMPARE(allItems.at(0).second, QString("b"));
QCOMPARE(query, original);
- QVERIFY(!(query != original));
+ QT_TEST_EQUALITY_OPS(query, original, true);
QCOMPARE(qHash(query), qHash(original));
}
@@ -313,12 +368,12 @@ void tst_QUrlQuery::addRemove()
QCOMPARE(query.allQueryItemValues("e"), QStringList() << emptyButNotNull);
QList<QPair<QString, QString> > allItems = query.queryItems();
- QCOMPARE(allItems.count(), 2);
+ QCOMPARE(allItems.size(), 2);
QVERIFY(allItems.contains(qItem("a", "b")));
QVERIFY(allItems.contains(qItem("e", emptyButNotNull)));
- QVERIFY(query != original);
- QVERIFY(!(query == original));
+ QCOMPARE_NE(query, original);
+ QT_TEST_EQUALITY_OPS(query, original, false);
}
{
@@ -326,6 +381,9 @@ void tst_QUrlQuery::addRemove()
query.removeQueryItem("a");
query.removeQueryItem("e");
QVERIFY(query.isEmpty());
+ QVERIFY(query.isDetached());
+ QCOMPARE_NE(query, original);
+ QCOMPARE(query, QUrlQuery());
}
}
@@ -528,12 +586,11 @@ void tst_QUrlQuery::reconstructQuery_data()
baselist << qItem("a", "b") << qItem("c", "d");
QTest::newRow("2-ab-cd") << "a=b&c=d" << baselist;
- // the same entry multiply defined
+ // The same entry multiply defined
QTest::newRow("2-a-a") << "a&a" << (QueryItems() << qItem("a", QString()) << qItem("a", QString()));
QTest::newRow("2-ab-ab") << "a=b&a=b" << (QueryItems() << qItem("a", "b") << qItem("a", "b"));
QTest::newRow("2-ab-ac") << "a=b&a=c" << (QueryItems() << qItem("a", "b") << qItem("a", "c"));
QTest::newRow("2-ac-ab") << "a=c&a=b" << (QueryItems() << qItem("a", "c") << qItem("a", "b"));
- QTest::newRow("2-ab-cd") << "a=b&c=d" << (QueryItems() << qItem("a", "b") << qItem("c", "d"));
QTest::newRow("2-cd-ab") << "c=d&a=b" << (QueryItems() << qItem("c", "d") << qItem("a", "b"));
QueryItems list2 = baselist + qItem("somekey", QString());
diff --git a/tests/auto/corelib/io/qurluts46/CMakeLists.txt b/tests/auto/corelib/io/qurluts46/CMakeLists.txt
new file mode 100644
index 0000000000..ac3f7cac48
--- /dev/null
+++ b/tests/auto/corelib/io/qurluts46/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qurluts46 Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qurluts46 LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qurluts46
+ SOURCES
+ tst_qurluts46.cpp
+ TESTDATA
+ testdata/IdnaTestV2.txt
+)
diff --git a/tests/auto/corelib/io/qurluts46/testdata/IdnaTestV2.txt b/tests/auto/corelib/io/qurluts46/testdata/IdnaTestV2.txt
new file mode 100644
index 0000000000..5c1e6a880f
--- /dev/null
+++ b/tests/auto/corelib/io/qurluts46/testdata/IdnaTestV2.txt
@@ -0,0 +1,6374 @@
+# IdnaTestV2.txt
+# Date: 2023-08-15, 23:21:16 GMT
+# © 2023 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
+#
+# Unicode IDNA Compatible Preprocessing for UTS #46
+# Version: 15.1.0
+#
+# For documentation and usage, see https://www.unicode.org/reports/tr46
+#
+# Test cases for verifying UTS #46 conformance.
+#
+# FORMAT:
+#
+# This file is in UTF-8, where characters may be escaped using the \uXXXX or \x{XXXX}
+# convention where they could otherwise have a confusing display.
+# These characters include control codes and combining marks.
+#
+# Columns (c1, c2,...) are separated by semicolons.
+# Leading and trailing spaces and tabs in each column are ignored.
+# Comments are indicated with hash marks.
+#
+# Column 1: source - The source string to be tested
+# Column 2: toUnicode - The result of applying toUnicode to the source,
+# with Transitional_Processing=false.
+# A blank value means the same as the source value.
+# Column 3: toUnicodeStatus - A set of status codes, each corresponding to a particular test.
+# A blank value means [] (no errors).
+# Column 4: toAsciiN - The result of applying toASCII to the source,
+# with Transitional_Processing=false.
+# A blank value means the same as the toUnicode value.
+# Column 5: toAsciiNStatus - A set of status codes, each corresponding to a particular test.
+# A blank value means the same as the toUnicodeStatus value.
+# An explicit [] means no errors.
+# Column 6: toAsciiT - The result of applying toASCII to the source,
+# with Transitional_Processing=true.
+# A blank value means the same as the toAsciiN value.
+# Column 7: toAsciiTStatus - A set of status codes, each corresponding to a particular test.
+# A blank value means the same as the toAsciiNStatus value.
+# An explicit [] means no errors.
+#
+# The line comments currently show visible characters that have been escaped.
+#
+# CONFORMANCE:
+#
+# To test for conformance to UTS #46, an implementation will perform the toUnicode, toAsciiN, and
+# toAsciiT operations on the source string, then verify the resulting strings and relevant status
+# values.
+#
+# If the implementation converts illegal code points into U+FFFD (as per
+# https://www.unicode.org/reports/tr46/#Processing) then the string comparisons need to
+# account for that by treating U+FFFD in the actual value as a wildcard when comparing to the
+# expected value in the test file.
+#
+# A status in toUnicode, toAsciiN or toAsciiT is indicated by a value in square brackets,
+# such as "[B5 B6]". In such a case, the contents is a list of status codes based on the step
+# numbers in UTS #46 and IDNA2008, with the following formats.
+#
+# Pn for Section 4 Processing step n
+# Vn for 4.1 Validity Criteria step n
+# U1 for UseSTD3ASCIIRules
+# An for 4.2 ToASCII step n
+# Bn for Bidi (in IDNA2008)
+# Cn for ContextJ (in IDNA2008)
+# Xn for toUnicode issues (see below)
+#
+# Thus C1 = Appendix A.1. ZERO WIDTH NON-JOINER, and C2 = Appendix A.2. ZERO WIDTH JOINER.
+# (The CONTEXTO tests are optional for client software, and not tested here.)
+#
+# Implementations that allow values of particular input flags to be false would ignore
+# the corresponding status codes listed in the table below when testing for errors.
+#
+# VerifyDnsLength: P4
+# CheckHyphens: V2, V3
+# CheckBidi: V8
+# CheckJoiners: V7
+# UseSTD3ASCIIRules: U1
+#
+# Implementations may be more strict than the default settings for UTS #46.
+# In particular, an implementation conformant to IDNA2008 would disallow the input for lines
+# marked with NV8.
+#
+# Implementations need only record that there is an error: they need not reproduce the
+# precise status codes (after removing the ignored status values).
+#
+# Compatibility errors
+#
+# The special error codes X3 and X4_2 are now returned where a toASCII error code
+# was formerly being generated in toUnicode due to an empty label.
+#
+# A3 was being generated in the following cases (in addition to its normal usage).
+# • an empty label in toUnicode. In this case, it is replaced by X3.
+#
+# A4_2 was being generated in the following case (in addition to its normal usage).
+# • an empty label in V8 (CheckBidi). In this case, it is being replaced by X4_2.
+# ============================================================================================
+fass.de; ; ; ; ; ; # fass.de
+faß.de; ; ; xn--fa-hia.de; ; fass.de; # faß.de
+Faß.de; faß.de; ; xn--fa-hia.de; ; fass.de; # faß.de
+xn--fa-hia.de; faß.de; ; xn--fa-hia.de; ; ; # faß.de
+
+# BIDI TESTS
+
+à\u05D0; ; [B5, B6]; xn--0ca24w; ; ; # àא
+a\u0300\u05D0; à\u05D0; [B5, B6]; xn--0ca24w; ; ; # àא
+A\u0300\u05D0; à\u05D0; [B5, B6]; xn--0ca24w; ; ; # àא
+À\u05D0; à\u05D0; [B5, B6]; xn--0ca24w; ; ; # àא
+xn--0ca24w; à\u05D0; [B5, B6]; xn--0ca24w; ; ; # àא
+0à.\u05D0; ; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+0a\u0300.\u05D0; 0à.\u05D0; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+0A\u0300.\u05D0; 0à.\u05D0; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+0À.\u05D0; 0à.\u05D0; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+xn--0-sfa.xn--4db; 0à.\u05D0; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+à.\u05D0\u0308; ; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+a\u0300.\u05D0\u0308; à.\u05D0\u0308; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+A\u0300.\u05D0\u0308; à.\u05D0\u0308; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+À.\u05D0\u0308; à.\u05D0\u0308; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+xn--0ca.xn--ssa73l; à.\u05D0\u0308; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+à.\u05D00\u0660\u05D0; ; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+a\u0300.\u05D00\u0660\u05D0; à.\u05D00\u0660\u05D0; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+A\u0300.\u05D00\u0660\u05D0; à.\u05D00\u0660\u05D0; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+À.\u05D00\u0660\u05D0; à.\u05D00\u0660\u05D0; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+xn--0ca.xn--0-zhcb98c; à.\u05D00\u0660\u05D0; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+\u0308.\u05D0; ; [B1, V5]; xn--ssa.xn--4db; ; ; # ̈.א
+xn--ssa.xn--4db; \u0308.\u05D0; [B1, V5]; xn--ssa.xn--4db; ; ; # ̈.א
+à.\u05D00\u0660; ; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+a\u0300.\u05D00\u0660; à.\u05D00\u0660; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+A\u0300.\u05D00\u0660; à.\u05D00\u0660; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+À.\u05D00\u0660; à.\u05D00\u0660; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+xn--0ca.xn--0-zhc74b; à.\u05D00\u0660; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+àˇ.\u05D0; ; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+a\u0300ˇ.\u05D0; àˇ.\u05D0; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+A\u0300ˇ.\u05D0; àˇ.\u05D0; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+Àˇ.\u05D0; àˇ.\u05D0; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+xn--0ca88g.xn--4db; àˇ.\u05D0; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+à\u0308.\u05D0; ; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+a\u0300\u0308.\u05D0; à\u0308.\u05D0; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+A\u0300\u0308.\u05D0; à\u0308.\u05D0; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+À\u0308.\u05D0; à\u0308.\u05D0; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+xn--0ca81i.xn--4db; à\u0308.\u05D0; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+
+# CONTEXT TESTS
+
+a\u200Cb; ; [C1]; xn--ab-j1t; ; ab; [] # ab
+A\u200CB; a\u200Cb; [C1]; xn--ab-j1t; ; ab; [] # ab
+A\u200Cb; a\u200Cb; [C1]; xn--ab-j1t; ; ab; [] # ab
+ab; ; ; ; ; ; # ab
+xn--ab-j1t; a\u200Cb; [C1]; xn--ab-j1t; ; ; # ab
+a\u094D\u200Cb; ; ; xn--ab-fsf604u; ; xn--ab-fsf; # a्b
+A\u094D\u200CB; a\u094D\u200Cb; ; xn--ab-fsf604u; ; xn--ab-fsf; # a्b
+A\u094D\u200Cb; a\u094D\u200Cb; ; xn--ab-fsf604u; ; xn--ab-fsf; # a्b
+xn--ab-fsf; a\u094Db; ; xn--ab-fsf; ; ; # a्b
+a\u094Db; ; ; xn--ab-fsf; ; ; # a्b
+A\u094DB; a\u094Db; ; xn--ab-fsf; ; ; # a्b
+A\u094Db; a\u094Db; ; xn--ab-fsf; ; ; # a्b
+xn--ab-fsf604u; a\u094D\u200Cb; ; xn--ab-fsf604u; ; ; # a्b
+\u0308\u200C\u0308\u0628b; ; [B1, C1, V5]; xn--b-bcba413a2w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+\u0308\u200C\u0308\u0628B; \u0308\u200C\u0308\u0628b; [B1, C1, V5]; xn--b-bcba413a2w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+xn--b-bcba413a; \u0308\u0308\u0628b; [B1, V5]; xn--b-bcba413a; ; ; # ̈̈بb
+xn--b-bcba413a2w8b; \u0308\u200C\u0308\u0628b; [B1, C1, V5]; xn--b-bcba413a2w8b; ; ; # ̈̈بb
+a\u0628\u0308\u200C\u0308; ; [B5, B6, C1]; xn--a-ccba213a5w8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+A\u0628\u0308\u200C\u0308; a\u0628\u0308\u200C\u0308; [B5, B6, C1]; xn--a-ccba213a5w8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+xn--a-ccba213a; a\u0628\u0308\u0308; [B5, B6]; xn--a-ccba213a; ; ; # aب̈̈
+xn--a-ccba213a5w8b; a\u0628\u0308\u200C\u0308; [B5, B6, C1]; xn--a-ccba213a5w8b; ; ; # aب̈̈
+a\u0628\u0308\u200C\u0308\u0628b; ; [B5]; xn--ab-uuba211bca8057b; ; xn--ab-uuba211bca; # aب̈̈بb
+A\u0628\u0308\u200C\u0308\u0628B; a\u0628\u0308\u200C\u0308\u0628b; [B5]; xn--ab-uuba211bca8057b; ; xn--ab-uuba211bca; # aب̈̈بb
+A\u0628\u0308\u200C\u0308\u0628b; a\u0628\u0308\u200C\u0308\u0628b; [B5]; xn--ab-uuba211bca8057b; ; xn--ab-uuba211bca; # aب̈̈بb
+xn--ab-uuba211bca; a\u0628\u0308\u0308\u0628b; [B5]; xn--ab-uuba211bca; ; ; # aب̈̈بb
+xn--ab-uuba211bca8057b; a\u0628\u0308\u200C\u0308\u0628b; [B5]; xn--ab-uuba211bca8057b; ; ; # aب̈̈بb
+a\u200Db; ; [C2]; xn--ab-m1t; ; ab; [] # ab
+A\u200DB; a\u200Db; [C2]; xn--ab-m1t; ; ab; [] # ab
+A\u200Db; a\u200Db; [C2]; xn--ab-m1t; ; ab; [] # ab
+xn--ab-m1t; a\u200Db; [C2]; xn--ab-m1t; ; ; # ab
+a\u094D\u200Db; ; ; xn--ab-fsf014u; ; xn--ab-fsf; # a्b
+A\u094D\u200DB; a\u094D\u200Db; ; xn--ab-fsf014u; ; xn--ab-fsf; # a्b
+A\u094D\u200Db; a\u094D\u200Db; ; xn--ab-fsf014u; ; xn--ab-fsf; # a्b
+xn--ab-fsf014u; a\u094D\u200Db; ; xn--ab-fsf014u; ; ; # a्b
+\u0308\u200D\u0308\u0628b; ; [B1, C2, V5]; xn--b-bcba413a7w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+\u0308\u200D\u0308\u0628B; \u0308\u200D\u0308\u0628b; [B1, C2, V5]; xn--b-bcba413a7w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+xn--b-bcba413a7w8b; \u0308\u200D\u0308\u0628b; [B1, C2, V5]; xn--b-bcba413a7w8b; ; ; # ̈̈بb
+a\u0628\u0308\u200D\u0308; ; [B5, B6, C2]; xn--a-ccba213abx8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+A\u0628\u0308\u200D\u0308; a\u0628\u0308\u200D\u0308; [B5, B6, C2]; xn--a-ccba213abx8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+xn--a-ccba213abx8b; a\u0628\u0308\u200D\u0308; [B5, B6, C2]; xn--a-ccba213abx8b; ; ; # aب̈̈
+a\u0628\u0308\u200D\u0308\u0628b; ; [B5, C2]; xn--ab-uuba211bca5157b; ; xn--ab-uuba211bca; [B5] # aب̈̈بb
+A\u0628\u0308\u200D\u0308\u0628B; a\u0628\u0308\u200D\u0308\u0628b; [B5, C2]; xn--ab-uuba211bca5157b; ; xn--ab-uuba211bca; [B5] # aب̈̈بb
+A\u0628\u0308\u200D\u0308\u0628b; a\u0628\u0308\u200D\u0308\u0628b; [B5, C2]; xn--ab-uuba211bca5157b; ; xn--ab-uuba211bca; [B5] # aب̈̈بb
+xn--ab-uuba211bca5157b; a\u0628\u0308\u200D\u0308\u0628b; [B5, C2]; xn--ab-uuba211bca5157b; ; ; # aب̈̈بb
+
+# SELECTED TESTS
+
+¡; ; ; xn--7a; ; ; # ¡
+xn--7a; ¡; ; xn--7a; ; ; # ¡
+᧚; ; ; xn--pkf; ; ; # ᧚
+xn--pkf; ᧚; ; xn--pkf; ; ; # ᧚
+。; .; [X4_2]; ; [A4_2]; ; # .
+.; ; [X4_2]; ; [A4_2]; ; # .
+ꭠ; ; ; xn--3y9a; ; ; # ꭠ
+xn--3y9a; ꭠ; ; xn--3y9a; ; ; # ꭠ
+1234567890ä1234567890123456789012345678901234567890123456; ; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+1234567890a\u03081234567890123456789012345678901234567890123456; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+1234567890A\u03081234567890123456789012345678901234567890123456; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+1234567890Ä1234567890123456789012345678901234567890123456; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+xn--12345678901234567890123456789012345678901234567890123456-fxe; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+www.eXample.cOm; www.example.com; ; ; ; ; # www.example.com
+Bücher.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+Bu\u0308cher.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+bu\u0308cher.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+bücher.de; ; ; xn--bcher-kva.de; ; ; # bücher.de
+BÜCHER.DE; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+BU\u0308CHER.DE; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+xn--bcher-kva.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+ÖBB; öbb; ; xn--bb-eka; ; ; # öbb
+O\u0308BB; öbb; ; xn--bb-eka; ; ; # öbb
+o\u0308bb; öbb; ; xn--bb-eka; ; ; # öbb
+öbb; ; ; xn--bb-eka; ; ; # öbb
+Öbb; öbb; ; xn--bb-eka; ; ; # öbb
+O\u0308bb; öbb; ; xn--bb-eka; ; ; # öbb
+xn--bb-eka; öbb; ; xn--bb-eka; ; ; # öbb
+FAẞ.de; faß.de; ; xn--fa-hia.de; ; fass.de; # faß.de
+FAẞ.DE; faß.de; ; xn--fa-hia.de; ; fass.de; # faß.de
+βόλος.com; ; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+βο\u0301λος.com; βόλος.com; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+ΒΟ\u0301ΛΟΣ.COM; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+ΒΌΛΟΣ.COM; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+βόλοσ.com; ; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+βο\u0301λοσ.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+Βο\u0301λοσ.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+Βόλοσ.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+xn--nxasmq6b.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+Βο\u0301λος.com; βόλος.com; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+Βόλος.com; βόλος.com; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+xn--nxasmm1c.com; βόλος.com; ; xn--nxasmm1c.com; ; ; # βόλος.com
+xn--nxasmm1c; βόλος; ; xn--nxasmm1c; ; ; # βόλος
+βόλος; ; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+βο\u0301λος; βόλος; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+ΒΟ\u0301ΛΟΣ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+ΒΌΛΟΣ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+βόλοσ; ; ; xn--nxasmq6b; ; ; # βόλοσ
+βο\u0301λοσ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+Βο\u0301λοσ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+Βόλοσ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+xn--nxasmq6b; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+Βόλος; βόλος; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+Βο\u0301λος; βόλος; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+www.ශ\u0DCA\u200Dර\u0DD3.com; ; ; www.xn--10cl1a0b660p.com; ; www.xn--10cl1a0b.com; # www.ශ්රී.com
+WWW.ශ\u0DCA\u200Dර\u0DD3.COM; www.ශ\u0DCA\u200Dර\u0DD3.com; ; www.xn--10cl1a0b660p.com; ; www.xn--10cl1a0b.com; # www.ශ්රී.com
+Www.ශ\u0DCA\u200Dර\u0DD3.com; www.ශ\u0DCA\u200Dර\u0DD3.com; ; www.xn--10cl1a0b660p.com; ; www.xn--10cl1a0b.com; # www.ශ්රී.com
+www.xn--10cl1a0b.com; www.ශ\u0DCAර\u0DD3.com; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+www.ශ\u0DCAර\u0DD3.com; ; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+WWW.ශ\u0DCAර\u0DD3.COM; www.ශ\u0DCAර\u0DD3.com; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+Www.ශ\u0DCAර\u0DD3.com; www.ශ\u0DCAර\u0DD3.com; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+www.xn--10cl1a0b660p.com; www.ශ\u0DCA\u200Dර\u0DD3.com; ; www.xn--10cl1a0b660p.com; ; ; # www.ශ්රී.com
+\u0646\u0627\u0645\u0647\u200C\u0627\u06CC; ; ; xn--mgba3gch31f060k; ; xn--mgba3gch31f; # نامهای
+xn--mgba3gch31f; \u0646\u0627\u0645\u0647\u0627\u06CC; ; xn--mgba3gch31f; ; ; # نامهای
+\u0646\u0627\u0645\u0647\u0627\u06CC; ; ; xn--mgba3gch31f; ; ; # نامهای
+xn--mgba3gch31f060k; \u0646\u0627\u0645\u0647\u200C\u0627\u06CC; ; xn--mgba3gch31f060k; ; ; # نامهای
+xn--mgba3gch31f060k.com; \u0646\u0627\u0645\u0647\u200C\u0627\u06CC.com; ; xn--mgba3gch31f060k.com; ; ; # نامهای.com
+\u0646\u0627\u0645\u0647\u200C\u0627\u06CC.com; ; ; xn--mgba3gch31f060k.com; ; xn--mgba3gch31f.com; # نامهای.com
+\u0646\u0627\u0645\u0647\u200C\u0627\u06CC.COM; \u0646\u0627\u0645\u0647\u200C\u0627\u06CC.com; ; xn--mgba3gch31f060k.com; ; xn--mgba3gch31f.com; # نامهای.com
+xn--mgba3gch31f.com; \u0646\u0627\u0645\u0647\u0627\u06CC.com; ; xn--mgba3gch31f.com; ; ; # نامهای.com
+\u0646\u0627\u0645\u0647\u0627\u06CC.com; ; ; xn--mgba3gch31f.com; ; ; # نامهای.com
+\u0646\u0627\u0645\u0647\u0627\u06CC.COM; \u0646\u0627\u0645\u0647\u0627\u06CC.com; ; xn--mgba3gch31f.com; ; ; # نامهای.com
+a.b.c。d。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+a.b.c。d。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+A.B.C。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+A.b.c。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+a.b.c.d.; ; ; ; ; ; # a.b.c.d.
+A.B.C。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+A.b.c。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+U\u0308.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+ü.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+u\u0308.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+U\u0308.XN--TDA; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.XN--TDA; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.xn--Tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+U\u0308.xn--Tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+xn--tda.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+ü.ü; ; ; xn--tda.xn--tda; ; ; # ü.ü
+u\u0308.u\u0308; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+U\u0308.U\u0308; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.Ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+U\u0308.u\u0308; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+xn--u-ccb; u\u0308; [V1]; xn--u-ccb; ; ; # ü
+a⒈com; ; [V6]; xn--acom-0w1b; ; ; # a⒈com
+a1.com; ; ; ; ; ; # a1.com
+A⒈COM; a⒈com; [V6]; xn--acom-0w1b; ; ; # a⒈com
+A⒈Com; a⒈com; [V6]; xn--acom-0w1b; ; ; # a⒈com
+xn--acom-0w1b; a⒈com; [V6]; xn--acom-0w1b; ; ; # a⒈com
+xn--a-ecp.ru; a⒈.ru; [V6]; xn--a-ecp.ru; ; ; # a⒈.ru
+xn--0.pt; ; [P4]; ; ; ; # xn--0.pt
+xn--a.pt; \u0080.pt; [V6]; xn--a.pt; ; ; # .pt
+xn--a-Ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--a-A\u0308.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--a-a\u0308.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--a-ä.pt; ; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+XN--A-Ä.PT; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+XN--A-A\u0308.PT; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+Xn--A-A\u0308.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+Xn--A-Ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--xn--a--gua.pt; xn--a-ä.pt; [V2]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+日本語。JP; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。JP; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。Jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+xn--wgv71a119e.jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語.jp; ; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語.JP; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語.Jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。Jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+☕; ; ; xn--53h; ; ; # ☕
+xn--53h; ☕; ; xn--53h; ; ; # ☕
+1.aß\u200C\u200Db\u200C\u200Dcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß\u0302ßz; ; [C1, C2]; 1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.aßbcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz
+1.ASS\u200C\u200DB\u200C\u200DCSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSS\u0302SSZ; 1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ASS\u200C\u200DB\u200C\u200DCSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSŜSSZ; 1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssyssssssssssssssss\u0302ssz; 1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssyssssssssssssssss\u0302ssz; 1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssyssssssssssssssss\u0302ssz; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ASSBCSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSS\u0302SSZ; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ASSBCSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSŜSSZ; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssyssssssssssssssss\u0302ssz; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; 1.ass\u200C\u200Db\u200C\u200Dcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Aß\u200C\u200Db\u200C\u200Dcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß\u0302ßz; 1.aß\u200C\u200Db\u200C\u200Dcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß\u0302ßz; [C1, C2]; 1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.aßbcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz
+1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; 1.aß\u200C\u200Db\u200C\u200Dcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß\u0302ßz; [C1, C2]; 1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; [C1, C2, A4_2]; ; # 1.aßbcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz
+\u200Cx\u200Dn\u200C-\u200D-bß; ; [C1, C2]; xn--xn--b-pqa5796ccahd; ; xn--bss; [] # xn--bß
+\u200CX\u200DN\u200C-\u200D-BSS; \u200Cx\u200Dn\u200C-\u200D-bss; [C1, C2]; xn--xn--bss-7z6ccid; ; xn--bss; [] # xn--bss
+\u200Cx\u200Dn\u200C-\u200D-bss; ; [C1, C2]; xn--xn--bss-7z6ccid; ; xn--bss; [] # xn--bss
+\u200CX\u200Dn\u200C-\u200D-Bss; \u200Cx\u200Dn\u200C-\u200D-bss; [C1, C2]; xn--xn--bss-7z6ccid; ; xn--bss; [] # xn--bss
+xn--bss; 夙; ; xn--bss; ; ; # 夙
+夙; ; ; xn--bss; ; ; # 夙
+xn--xn--bss-7z6ccid; \u200Cx\u200Dn\u200C-\u200D-bss; [C1, C2]; xn--xn--bss-7z6ccid; ; ; # xn--bss
+\u200CX\u200Dn\u200C-\u200D-Bß; \u200Cx\u200Dn\u200C-\u200D-bß; [C1, C2]; xn--xn--b-pqa5796ccahd; ; xn--bss; [] # xn--bß
+xn--xn--b-pqa5796ccahd; \u200Cx\u200Dn\u200C-\u200D-bß; [C1, C2]; xn--xn--b-pqa5796ccahd; ; ; # xn--bß
+ˣ\u034Fℕ\u200B﹣\u00AD-\u180Cℬ\uFE00ſ\u2064𝔰󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+x\u034FN\u200B-\u00AD-\u180CB\uFE00s\u2064s󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+x\u034Fn\u200B-\u00AD-\u180Cb\uFE00s\u2064s󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+X\u034FN\u200B-\u00AD-\u180CB\uFE00S\u2064S󠇯FFL; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+X\u034Fn\u200B-\u00AD-\u180CB\uFE00s\u2064s󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+xn--bssffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+夡夞夜夙; ; ; xn--bssffl; ; ; # 夡夞夜夙
+ˣ\u034Fℕ\u200B﹣\u00AD-\u180Cℬ\uFE00S\u2064𝔰󠇯FFL; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+x\u034FN\u200B-\u00AD-\u180CB\uFE00S\u2064s󠇯FFL; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+ˣ\u034Fℕ\u200B﹣\u00AD-\u180Cℬ\uFE00s\u2064𝔰󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; ; ; ; # 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; ; ; ; # 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; ; ; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; ; ; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; ; ; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; ; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+ä1234567890123456789012345678901234567890123456789012345; ; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+a\u03081234567890123456789012345678901234567890123456789012345; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+A\u03081234567890123456789012345678901234567890123456789012345; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+Ä1234567890123456789012345678901234567890123456789012345; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+xn--1234567890123456789012345678901234567890123456789012345-9te; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890a\u0308123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890A\u0308123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890a\u0308123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890A\u0308123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890a\u0308123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890A\u0308123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890a\u03081234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890A\u03081234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890a\u03081234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890A\u03081234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890a\u03081234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890A\u03081234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+a.b..-q--a-.e; ; [V2, V3, X4_2]; ; [V2, V3, A4_2]; ; # a.b..-q--a-.e
+a.b..-q--ä-.e; ; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+a.b..-q--a\u0308-.e; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.B..-Q--A\u0308-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.B..-Q--Ä-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.b..-Q--Ä-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.b..-Q--A\u0308-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+a.b..xn---q----jra.e; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+a..c; ; [X4_2]; ; [A4_2]; ; # a..c
+a.-b.; ; [V3]; ; ; ; # a.-b.
+a.b-.c; ; [V3]; ; ; ; # a.b-.c
+a.-.c; ; [V3]; ; ; ; # a.-.c
+a.bc--de.f; ; [V2]; ; ; ; # a.bc--de.f
+ä.\u00AD.c; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+a\u0308.\u00AD.c; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+A\u0308.\u00AD.C; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+Ä.\u00AD.C; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+xn--4ca..c; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+ä.-b.; ; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+a\u0308.-b.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+A\u0308.-B.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+Ä.-B.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+xn--4ca.-b.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+ä.b-.c; ; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+a\u0308.b-.c; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+A\u0308.B-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+Ä.B-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+Ä.b-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+A\u0308.b-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+xn--4ca.b-.c; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+ä.-.c; ; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+a\u0308.-.c; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+A\u0308.-.C; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+Ä.-.C; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+xn--4ca.-.c; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+ä.bc--de.f; ; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+a\u0308.bc--de.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+A\u0308.BC--DE.F; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+Ä.BC--DE.F; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+Ä.bc--De.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+A\u0308.bc--De.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+xn--4ca.bc--de.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+a.b.\u0308c.d; ; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+A.B.\u0308C.D; a.b.\u0308c.d; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+A.b.\u0308c.d; a.b.\u0308c.d; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+a.b.xn--c-bcb.d; a.b.\u0308c.d; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+A0; a0; ; ; ; ; # a0
+0A; 0a; ; ; ; ; # 0a
+0A.\u05D0; 0a.\u05D0; [B1]; 0a.xn--4db; ; ; # 0a.א
+0a.\u05D0; ; [B1]; 0a.xn--4db; ; ; # 0a.א
+0a.xn--4db; 0a.\u05D0; [B1]; 0a.xn--4db; ; ; # 0a.א
+c.xn--0-eha.xn--4db; c.0ü.\u05D0; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+b-.\u05D0; ; [B6, V3]; b-.xn--4db; ; ; # b-.א
+B-.\u05D0; b-.\u05D0; [B6, V3]; b-.xn--4db; ; ; # b-.א
+b-.xn--4db; b-.\u05D0; [B6, V3]; b-.xn--4db; ; ; # b-.א
+d.xn----dha.xn--4db; d.ü-.\u05D0; [B6, V3]; d.xn----dha.xn--4db; ; ; # d.ü-.א
+a\u05D0; ; [B5, B6]; xn--a-0hc; ; ; # aא
+A\u05D0; a\u05D0; [B5, B6]; xn--a-0hc; ; ; # aא
+xn--a-0hc; a\u05D0; [B5, B6]; xn--a-0hc; ; ; # aא
+\u05D0\u05C7; ; ; xn--vdbr; ; ; # אׇ
+xn--vdbr; \u05D0\u05C7; ; xn--vdbr; ; ; # אׇ
+\u05D09\u05C7; ; ; xn--9-ihcz; ; ; # א9ׇ
+xn--9-ihcz; \u05D09\u05C7; ; xn--9-ihcz; ; ; # א9ׇ
+\u05D0a\u05C7; ; [B2, B3]; xn--a-ihcz; ; ; # אaׇ
+\u05D0A\u05C7; \u05D0a\u05C7; [B2, B3]; xn--a-ihcz; ; ; # אaׇ
+xn--a-ihcz; \u05D0a\u05C7; [B2, B3]; xn--a-ihcz; ; ; # אaׇ
+\u05D0\u05EA; ; ; xn--4db6c; ; ; # את
+xn--4db6c; \u05D0\u05EA; ; xn--4db6c; ; ; # את
+\u05D0\u05F3\u05EA; ; ; xn--4db6c0a; ; ; # א׳ת
+xn--4db6c0a; \u05D0\u05F3\u05EA; ; xn--4db6c0a; ; ; # א׳ת
+a\u05D0Tz; a\u05D0tz; [B5]; xn--atz-qpe; ; ; # aאtz
+a\u05D0tz; ; [B5]; xn--atz-qpe; ; ; # aאtz
+A\u05D0TZ; a\u05D0tz; [B5]; xn--atz-qpe; ; ; # aאtz
+A\u05D0tz; a\u05D0tz; [B5]; xn--atz-qpe; ; ; # aאtz
+xn--atz-qpe; a\u05D0tz; [B5]; xn--atz-qpe; ; ; # aאtz
+\u05D0T\u05EA; \u05D0t\u05EA; [B2]; xn--t-zhc3f; ; ; # אtת
+\u05D0t\u05EA; ; [B2]; xn--t-zhc3f; ; ; # אtת
+xn--t-zhc3f; \u05D0t\u05EA; [B2]; xn--t-zhc3f; ; ; # אtת
+\u05D07\u05EA; ; ; xn--7-zhc3f; ; ; # א7ת
+xn--7-zhc3f; \u05D07\u05EA; ; xn--7-zhc3f; ; ; # א7ת
+\u05D0\u0667\u05EA; ; ; xn--4db6c6t; ; ; # א٧ת
+xn--4db6c6t; \u05D0\u0667\u05EA; ; xn--4db6c6t; ; ; # א٧ת
+a7\u0667z; ; [B5]; xn--a7z-06e; ; ; # a7٧z
+A7\u0667Z; a7\u0667z; [B5]; xn--a7z-06e; ; ; # a7٧z
+A7\u0667z; a7\u0667z; [B5]; xn--a7z-06e; ; ; # a7٧z
+xn--a7z-06e; a7\u0667z; [B5]; xn--a7z-06e; ; ; # a7٧z
+\u05D07\u0667\u05EA; ; [B4]; xn--7-zhc3fty; ; ; # א7٧ת
+xn--7-zhc3fty; \u05D07\u0667\u05EA; [B4]; xn--7-zhc3fty; ; ; # א7٧ת
+ஹ\u0BCD\u200D; ; ; xn--dmc4b194h; ; xn--dmc4b; # ஹ்
+xn--dmc4b; ஹ\u0BCD; ; xn--dmc4b; ; ; # ஹ்
+ஹ\u0BCD; ; ; xn--dmc4b; ; ; # ஹ்
+xn--dmc4b194h; ஹ\u0BCD\u200D; ; xn--dmc4b194h; ; ; # ஹ்
+ஹ\u200D; ; [C2]; xn--dmc225h; ; xn--dmc; [] # ஹ
+xn--dmc; ஹ; ; xn--dmc; ; ; # ஹ
+ஹ; ; ; xn--dmc; ; ; # ஹ
+xn--dmc225h; ஹ\u200D; [C2]; xn--dmc225h; ; ; # ஹ
+\u200D; ; [C2]; xn--1ug; ; ; [A4_2] #
+; ; [X4_2]; ; [A4_2]; ; #
+xn--1ug; \u200D; [C2]; xn--1ug; ; ; #
+ஹ\u0BCD\u200C; ; ; xn--dmc4by94h; ; xn--dmc4b; # ஹ்
+xn--dmc4by94h; ஹ\u0BCD\u200C; ; xn--dmc4by94h; ; ; # ஹ்
+ஹ\u200C; ; [C1]; xn--dmc025h; ; xn--dmc; [] # ஹ
+xn--dmc025h; ஹ\u200C; [C1]; xn--dmc025h; ; ; # ஹ
+\u200C; ; [C1]; xn--0ug; ; ; [A4_2] #
+xn--0ug; \u200C; [C1]; xn--0ug; ; ; #
+\u0644\u0670\u200C\u06ED\u06EF; ; ; xn--ghb2gxqia7523a; ; xn--ghb2gxqia; # لٰۭۯ
+xn--ghb2gxqia; \u0644\u0670\u06ED\u06EF; ; xn--ghb2gxqia; ; ; # لٰۭۯ
+\u0644\u0670\u06ED\u06EF; ; ; xn--ghb2gxqia; ; ; # لٰۭۯ
+xn--ghb2gxqia7523a; \u0644\u0670\u200C\u06ED\u06EF; ; xn--ghb2gxqia7523a; ; ; # لٰۭۯ
+\u0644\u0670\u200C\u06EF; ; ; xn--ghb2g3qq34f; ; xn--ghb2g3q; # لٰۯ
+xn--ghb2g3q; \u0644\u0670\u06EF; ; xn--ghb2g3q; ; ; # لٰۯ
+\u0644\u0670\u06EF; ; ; xn--ghb2g3q; ; ; # لٰۯ
+xn--ghb2g3qq34f; \u0644\u0670\u200C\u06EF; ; xn--ghb2g3qq34f; ; ; # لٰۯ
+\u0644\u200C\u06ED\u06EF; ; ; xn--ghb25aga828w; ; xn--ghb25aga; # لۭۯ
+xn--ghb25aga; \u0644\u06ED\u06EF; ; xn--ghb25aga; ; ; # لۭۯ
+\u0644\u06ED\u06EF; ; ; xn--ghb25aga; ; ; # لۭۯ
+xn--ghb25aga828w; \u0644\u200C\u06ED\u06EF; ; xn--ghb25aga828w; ; ; # لۭۯ
+\u0644\u200C\u06EF; ; ; xn--ghb65a953d; ; xn--ghb65a; # لۯ
+xn--ghb65a; \u0644\u06EF; ; xn--ghb65a; ; ; # لۯ
+\u0644\u06EF; ; ; xn--ghb65a; ; ; # لۯ
+xn--ghb65a953d; \u0644\u200C\u06EF; ; xn--ghb65a953d; ; ; # لۯ
+\u0644\u0670\u200C\u06ED; ; [B3, C1]; xn--ghb2gxqy34f; ; xn--ghb2gxq; [] # لٰۭ
+xn--ghb2gxq; \u0644\u0670\u06ED; ; xn--ghb2gxq; ; ; # لٰۭ
+\u0644\u0670\u06ED; ; ; xn--ghb2gxq; ; ; # لٰۭ
+xn--ghb2gxqy34f; \u0644\u0670\u200C\u06ED; [B3, C1]; xn--ghb2gxqy34f; ; ; # لٰۭ
+\u06EF\u200C\u06EF; ; [C1]; xn--cmba004q; ; xn--cmba; [] # ۯۯ
+xn--cmba; \u06EF\u06EF; ; xn--cmba; ; ; # ۯۯ
+\u06EF\u06EF; ; ; xn--cmba; ; ; # ۯۯ
+xn--cmba004q; \u06EF\u200C\u06EF; [C1]; xn--cmba004q; ; ; # ۯۯ
+\u0644\u200C; ; [B3, C1]; xn--ghb413k; ; xn--ghb; [] # ل
+xn--ghb; \u0644; ; xn--ghb; ; ; # ل
+\u0644; ; ; xn--ghb; ; ; # ل
+xn--ghb413k; \u0644\u200C; [B3, C1]; xn--ghb413k; ; ; # ل
+a。。b; a..b; [X4_2]; ; [A4_2]; ; # a..b
+A。。B; a..b; [X4_2]; ; [A4_2]; ; # a..b
+a..b; ; [X4_2]; ; [A4_2]; ; # a..b
+\u200D。。\u06B9\u200C; \u200D..\u06B9\u200C; [B1, B3, C1, C2, X4_2]; xn--1ug..xn--skb080k; [B1, B3, C1, C2, A4_2]; ..xn--skb; [A4_2] # ..ڹ
+..xn--skb; ..\u06B9; [X4_2]; ..xn--skb; [A4_2]; ; # ..ڹ
+xn--1ug..xn--skb080k; \u200D..\u06B9\u200C; [B1, B3, C1, C2, X4_2]; xn--1ug..xn--skb080k; [B1, B3, C1, C2, A4_2]; ; # ..ڹ
+\u05D00\u0660; ; [B4]; xn--0-zhc74b; ; ; # א0٠
+xn--0-zhc74b; \u05D00\u0660; [B4]; xn--0-zhc74b; ; ; # א0٠
+$; ; [V6]; ; ; ; # $
+
+# RANDOMIZED TESTS
+
+c.0ü.\u05D0; ; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+c.0u\u0308.\u05D0; c.0ü.\u05D0; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0U\u0308.\u05D0; c.0ü.\u05D0; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0Ü.\u05D0; c.0ü.\u05D0; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0ü.\u05D0; c.0ü.\u05D0; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0u\u0308.\u05D0; c.0ü.\u05D0; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+⒕∝\u065F򓤦.-󠄯; ⒕∝\u065F򓤦.-; [V3, V6]; xn--7hb713lfwbi1311b.-; ; ; # ⒕∝ٟ.-
+14.∝\u065F򓤦.-󠄯; 14.∝\u065F򓤦.-; [V3, V6]; 14.xn--7hb713l3v90n.-; ; ; # 14.∝ٟ.-
+14.xn--7hb713l3v90n.-; 14.∝\u065F򓤦.-; [V3, V6]; 14.xn--7hb713l3v90n.-; ; ; # 14.∝ٟ.-
+xn--7hb713lfwbi1311b.-; ⒕∝\u065F򓤦.-; [V3, V6]; xn--7hb713lfwbi1311b.-; ; ; # ⒕∝ٟ.-
+ꡣ.\u07CF; ; ; xn--8c9a.xn--qsb; ; ; # ꡣ.ߏ
+xn--8c9a.xn--qsb; ꡣ.\u07CF; ; xn--8c9a.xn--qsb; ; ; # ꡣ.ߏ
+≯\u0603。-; ≯\u0603.-; [B1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+>\u0338\u0603。-; ≯\u0603.-; [B1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+≯\u0603。-; ≯\u0603.-; [B1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+>\u0338\u0603。-; ≯\u0603.-; [B1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+xn--lfb566l.-; ≯\u0603.-; [B1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+⾛𐹧⾕.\u115F󠗰ςႭ; 走𐹧谷.\u115F󠗰ςႭ; [B5, V6]; xn--6g3a1x434z.xn--3xa827dhpae6345i; ; xn--6g3a1x434z.xn--4xa627dhpae6345i; # 走𐹧谷.ςႭ
+走𐹧谷.\u115F󠗰ςႭ; ; [B5, V6]; xn--6g3a1x434z.xn--3xa827dhpae6345i; ; xn--6g3a1x434z.xn--4xa627dhpae6345i; # 走𐹧谷.ςႭ
+走𐹧谷.\u115F󠗰ςⴍ; ; [B5, V6]; xn--6g3a1x434z.xn--3xa380eotvh7453a; ; xn--6g3a1x434z.xn--4xa180eotvh7453a; # 走𐹧谷.ςⴍ
+走𐹧谷.\u115F󠗰ΣႭ; 走𐹧谷.\u115F󠗰σႭ; [B5, V6]; xn--6g3a1x434z.xn--4xa627dhpae6345i; ; ; # 走𐹧谷.σႭ
+走𐹧谷.\u115F󠗰σⴍ; ; [B5, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+走𐹧谷.\u115F󠗰Σⴍ; 走𐹧谷.\u115F󠗰σⴍ; [B5, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+xn--6g3a1x434z.xn--4xa180eotvh7453a; 走𐹧谷.\u115F󠗰σⴍ; [B5, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+xn--6g3a1x434z.xn--4xa627dhpae6345i; 走𐹧谷.\u115F󠗰σႭ; [B5, V6]; xn--6g3a1x434z.xn--4xa627dhpae6345i; ; ; # 走𐹧谷.σႭ
+xn--6g3a1x434z.xn--3xa380eotvh7453a; 走𐹧谷.\u115F󠗰ςⴍ; [B5, V6]; xn--6g3a1x434z.xn--3xa380eotvh7453a; ; ; # 走𐹧谷.ςⴍ
+xn--6g3a1x434z.xn--3xa827dhpae6345i; 走𐹧谷.\u115F󠗰ςႭ; [B5, V6]; xn--6g3a1x434z.xn--3xa827dhpae6345i; ; ; # 走𐹧谷.ςႭ
+⾛𐹧⾕.\u115F󠗰ςⴍ; 走𐹧谷.\u115F󠗰ςⴍ; [B5, V6]; xn--6g3a1x434z.xn--3xa380eotvh7453a; ; xn--6g3a1x434z.xn--4xa180eotvh7453a; # 走𐹧谷.ςⴍ
+⾛𐹧⾕.\u115F󠗰ΣႭ; 走𐹧谷.\u115F󠗰σႭ; [B5, V6]; xn--6g3a1x434z.xn--4xa627dhpae6345i; ; ; # 走𐹧谷.σႭ
+⾛𐹧⾕.\u115F󠗰σⴍ; 走𐹧谷.\u115F󠗰σⴍ; [B5, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+⾛𐹧⾕.\u115F󠗰Σⴍ; 走𐹧谷.\u115F󠗰σⴍ; [B5, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+\u200D≠ᢙ≯.솣-ᡴႠ; ; [C2, V6]; xn--jbf929a90b0b.xn----6zg521d196p; ; xn--jbf911clb.xn----6zg521d196p; [V6] # ≠ᢙ≯.솣-ᡴႠ
+\u200D=\u0338ᢙ>\u0338.솣-ᡴႠ; \u200D≠ᢙ≯.솣-ᡴႠ; [C2, V6]; xn--jbf929a90b0b.xn----6zg521d196p; ; xn--jbf911clb.xn----6zg521d196p; [V6] # ≠ᢙ≯.솣-ᡴႠ
+\u200D=\u0338ᢙ>\u0338.솣-ᡴⴀ; \u200D≠ᢙ≯.솣-ᡴⴀ; [C2]; xn--jbf929a90b0b.xn----p9j493ivi4l; ; xn--jbf911clb.xn----p9j493ivi4l; [] # ≠ᢙ≯.솣-ᡴⴀ
+\u200D≠ᢙ≯.솣-ᡴⴀ; ; [C2]; xn--jbf929a90b0b.xn----p9j493ivi4l; ; xn--jbf911clb.xn----p9j493ivi4l; [] # ≠ᢙ≯.솣-ᡴⴀ
+xn--jbf911clb.xn----p9j493ivi4l; ≠ᢙ≯.솣-ᡴⴀ; ; xn--jbf911clb.xn----p9j493ivi4l; ; ; # ≠ᢙ≯.솣-ᡴⴀ
+≠ᢙ≯.솣-ᡴⴀ; ; ; xn--jbf911clb.xn----p9j493ivi4l; ; ; # ≠ᢙ≯.솣-ᡴⴀ
+=\u0338ᢙ>\u0338.솣-ᡴⴀ; ≠ᢙ≯.솣-ᡴⴀ; ; xn--jbf911clb.xn----p9j493ivi4l; ; ; # ≠ᢙ≯.솣-ᡴⴀ
+=\u0338ᢙ>\u0338.솣-ᡴႠ; ≠ᢙ≯.솣-ᡴႠ; [V6]; xn--jbf911clb.xn----6zg521d196p; ; ; # ≠ᢙ≯.솣-ᡴႠ
+≠ᢙ≯.솣-ᡴႠ; ; [V6]; xn--jbf911clb.xn----6zg521d196p; ; ; # ≠ᢙ≯.솣-ᡴႠ
+xn--jbf911clb.xn----6zg521d196p; ≠ᢙ≯.솣-ᡴႠ; [V6]; xn--jbf911clb.xn----6zg521d196p; ; ; # ≠ᢙ≯.솣-ᡴႠ
+xn--jbf929a90b0b.xn----p9j493ivi4l; \u200D≠ᢙ≯.솣-ᡴⴀ; [C2]; xn--jbf929a90b0b.xn----p9j493ivi4l; ; ; # ≠ᢙ≯.솣-ᡴⴀ
+xn--jbf929a90b0b.xn----6zg521d196p; \u200D≠ᢙ≯.솣-ᡴႠ; [C2, V6]; xn--jbf929a90b0b.xn----6zg521d196p; ; ; # ≠ᢙ≯.솣-ᡴႠ
+񯞜.𐿇\u0FA2\u077D\u0600; 񯞜.𐿇\u0FA1\u0FB7\u077D\u0600; [V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+񯞜.𐿇\u0FA1\u0FB7\u077D\u0600; 񯞜.𐿇\u0FA1\u0FB7\u077D\u0600; [V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+񯞜.𐿇\u0FA1\u0FB7\u077D\u0600; ; [V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+xn--gw68a.xn--ifb57ev2psc6027m; 񯞜.𐿇\u0FA1\u0FB7\u077D\u0600; [V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+𣳔\u0303.𑓂; ; [V5]; xn--nsa95820a.xn--wz1d; ; ; # 𣳔̃.𑓂
+xn--nsa95820a.xn--wz1d; 𣳔\u0303.𑓂; [V5]; xn--nsa95820a.xn--wz1d; ; ; # 𣳔̃.𑓂
+𞤀𞥅񘐱。󠄌Ⴣꡥ; 𞤢𞥅񘐱.Ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--7nd0578e; ; ; # 𞤢𞥅.Ⴣꡥ
+𞤢𞥅񘐱。󠄌ⴣꡥ; 𞤢𞥅񘐱.ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--rlju750b; ; ; # 𞤢𞥅.ⴣꡥ
+xn--9d6hgcy3556a.xn--rlju750b; 𞤢𞥅񘐱.ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--rlju750b; ; ; # 𞤢𞥅.ⴣꡥ
+xn--9d6hgcy3556a.xn--7nd0578e; 𞤢𞥅񘐱.Ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--7nd0578e; ; ; # 𞤢𞥅.Ⴣꡥ
+𞤀𞥅񘐱。󠄌ⴣꡥ; 𞤢𞥅񘐱.ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--rlju750b; ; ; # 𞤢𞥅.ⴣꡥ
+\u08E2𑁿ς𖬱。󠅡렧; \u08E2𑁿ς𖬱.렧; [B1, V6]; xn--3xa73xp48ys2xc.xn--kn2b; ; xn--4xa53xp48ys2xc.xn--kn2b; # 𑁿ς𖬱.렧
+\u08E2𑁿ς𖬱。󠅡렧; \u08E2𑁿ς𖬱.렧; [B1, V6]; xn--3xa73xp48ys2xc.xn--kn2b; ; xn--4xa53xp48ys2xc.xn--kn2b; # 𑁿ς𖬱.렧
+\u08E2𑁿Σ𖬱。󠅡렧; \u08E2𑁿σ𖬱.렧; [B1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+\u08E2𑁿Σ𖬱。󠅡렧; \u08E2𑁿σ𖬱.렧; [B1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+\u08E2𑁿σ𖬱。󠅡렧; \u08E2𑁿σ𖬱.렧; [B1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+\u08E2𑁿σ𖬱。󠅡렧; \u08E2𑁿σ𖬱.렧; [B1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+xn--4xa53xp48ys2xc.xn--kn2b; \u08E2𑁿σ𖬱.렧; [B1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+xn--3xa73xp48ys2xc.xn--kn2b; \u08E2𑁿ς𖬱.렧; [B1, V6]; xn--3xa73xp48ys2xc.xn--kn2b; ; ; # 𑁿ς𖬱.렧
+-\u200D。𞤍\u200C\u200D⒈; -\u200D.𞤯\u200C\u200D⒈; [B1, C1, C2, V3, V6]; xn----ugn.xn--0ugc555aiv51d; ; -.xn--tsh3666n; [B1, V3, V6] # -.𞤯⒈
+-\u200D。𞤍\u200C\u200D1.; -\u200D.𞤯\u200C\u200D1.; [B1, C1, C2, V3]; xn----ugn.xn--1-rgnd61297b.; ; -.xn--1-0i8r.; [B1, V3] # -.𞤯1.
+-\u200D。𞤯\u200C\u200D1.; -\u200D.𞤯\u200C\u200D1.; [B1, C1, C2, V3]; xn----ugn.xn--1-rgnd61297b.; ; -.xn--1-0i8r.; [B1, V3] # -.𞤯1.
+-.xn--1-0i8r.; -.𞤯1.; [B1, V3]; -.xn--1-0i8r.; ; ; # -.𞤯1.
+xn----ugn.xn--1-rgnd61297b.; -\u200D.𞤯\u200C\u200D1.; [B1, C1, C2, V3]; xn----ugn.xn--1-rgnd61297b.; ; ; # -.𞤯1.
+-\u200D。𞤯\u200C\u200D⒈; -\u200D.𞤯\u200C\u200D⒈; [B1, C1, C2, V3, V6]; xn----ugn.xn--0ugc555aiv51d; ; -.xn--tsh3666n; [B1, V3, V6] # -.𞤯⒈
+-.xn--tsh3666n; -.𞤯⒈; [B1, V3, V6]; -.xn--tsh3666n; ; ; # -.𞤯⒈
+xn----ugn.xn--0ugc555aiv51d; -\u200D.𞤯\u200C\u200D⒈; [B1, C1, C2, V3, V6]; xn----ugn.xn--0ugc555aiv51d; ; ; # -.𞤯⒈
+\u200C򅎭.Ⴒ𑇀; ; [C1, V6]; xn--0ug15083f.xn--qnd6272k; ; xn--bn95b.xn--qnd6272k; [V6] # .Ⴒ𑇀
+\u200C򅎭.ⴒ𑇀; ; [C1, V6]; xn--0ug15083f.xn--9kj2034e; ; xn--bn95b.xn--9kj2034e; [V6] # .ⴒ𑇀
+xn--bn95b.xn--9kj2034e; 򅎭.ⴒ𑇀; [V6]; xn--bn95b.xn--9kj2034e; ; ; # .ⴒ𑇀
+xn--0ug15083f.xn--9kj2034e; \u200C򅎭.ⴒ𑇀; [C1, V6]; xn--0ug15083f.xn--9kj2034e; ; ; # .ⴒ𑇀
+xn--bn95b.xn--qnd6272k; 򅎭.Ⴒ𑇀; [V6]; xn--bn95b.xn--qnd6272k; ; ; # .Ⴒ𑇀
+xn--0ug15083f.xn--qnd6272k; \u200C򅎭.Ⴒ𑇀; [C1, V6]; xn--0ug15083f.xn--qnd6272k; ; ; # .Ⴒ𑇀
+繱𑖿\u200D.8︒; 繱𑖿\u200D.8︒; [V6]; xn--1ug6928ac48e.xn--8-o89h; ; xn--gl0as212a.xn--8-o89h; # 繱𑖿.8︒
+繱𑖿\u200D.8。; 繱𑖿\u200D.8.; ; xn--1ug6928ac48e.8.; ; xn--gl0as212a.8.; # 繱𑖿.8.
+xn--gl0as212a.8.; 繱𑖿.8.; ; xn--gl0as212a.8.; ; ; # 繱𑖿.8.
+繱𑖿.8.; ; ; xn--gl0as212a.8.; ; ; # 繱𑖿.8.
+xn--1ug6928ac48e.8.; 繱𑖿\u200D.8.; ; xn--1ug6928ac48e.8.; ; ; # 繱𑖿.8.
+繱𑖿\u200D.8.; ; ; xn--1ug6928ac48e.8.; ; xn--gl0as212a.8.; # 繱𑖿.8.
+xn--gl0as212a.xn--8-o89h; 繱𑖿.8︒; [V6]; xn--gl0as212a.xn--8-o89h; ; ; # 繱𑖿.8︒
+xn--1ug6928ac48e.xn--8-o89h; 繱𑖿\u200D.8︒; [V6]; xn--1ug6928ac48e.xn--8-o89h; ; ; # 繱𑖿.8︒
+󠆾.𞀈; .𞀈; [V5, X4_2]; .xn--ph4h; [V5, A4_2]; ; # .𞀈
+󠆾.𞀈; .𞀈; [V5, X4_2]; .xn--ph4h; [V5, A4_2]; ; # .𞀈
+.xn--ph4h; .𞀈; [V5, X4_2]; .xn--ph4h; [V5, A4_2]; ; # .𞀈
+ß\u06EB。\u200D; ß\u06EB.\u200D; [C2]; xn--zca012a.xn--1ug; ; xn--ss-59d.; [] # ß۫.
+SS\u06EB。\u200D; ss\u06EB.\u200D; [C2]; xn--ss-59d.xn--1ug; ; xn--ss-59d.; [] # ss۫.
+ss\u06EB。\u200D; ss\u06EB.\u200D; [C2]; xn--ss-59d.xn--1ug; ; xn--ss-59d.; [] # ss۫.
+Ss\u06EB。\u200D; ss\u06EB.\u200D; [C2]; xn--ss-59d.xn--1ug; ; xn--ss-59d.; [] # ss۫.
+xn--ss-59d.; ss\u06EB.; ; xn--ss-59d.; ; ; # ss۫.
+ss\u06EB.; ; ; xn--ss-59d.; ; ; # ss۫.
+SS\u06EB.; ss\u06EB.; ; xn--ss-59d.; ; ; # ss۫.
+Ss\u06EB.; ss\u06EB.; ; xn--ss-59d.; ; ; # ss۫.
+xn--ss-59d.xn--1ug; ss\u06EB.\u200D; [C2]; xn--ss-59d.xn--1ug; ; ; # ss۫.
+xn--zca012a.xn--1ug; ß\u06EB.\u200D; [C2]; xn--zca012a.xn--1ug; ; ; # ß۫.
+󠐵\u200C⒈.󠎇; 󠐵\u200C⒈.󠎇; [C1, V6]; xn--0ug88o47900b.xn--tv36e; ; xn--tshz2001k.xn--tv36e; [V6] # ⒈.
+󠐵\u200C1..󠎇; ; [C1, V6, X4_2]; xn--1-rgn37671n..xn--tv36e; [C1, V6, A4_2]; xn--1-bs31m..xn--tv36e; [V6, A4_2] # 1..
+xn--1-bs31m..xn--tv36e; 󠐵1..󠎇; [V6, X4_2]; xn--1-bs31m..xn--tv36e; [V6, A4_2]; ; # 1..
+xn--1-rgn37671n..xn--tv36e; 󠐵\u200C1..󠎇; [C1, V6, X4_2]; xn--1-rgn37671n..xn--tv36e; [C1, V6, A4_2]; ; # 1..
+xn--tshz2001k.xn--tv36e; 󠐵⒈.󠎇; [V6]; xn--tshz2001k.xn--tv36e; ; ; # ⒈.
+xn--0ug88o47900b.xn--tv36e; 󠐵\u200C⒈.󠎇; [C1, V6]; xn--0ug88o47900b.xn--tv36e; ; ; # ⒈.
+󟈣\u065F\uAAB2ß。󌓧; 󟈣\u065F\uAAB2ß.󌓧; [V6]; xn--zca92z0t7n5w96j.xn--bb79d; ; xn--ss-3xd2839nncy1m.xn--bb79d; # ٟꪲß.
+󟈣\u065F\uAAB2SS。󌓧; 󟈣\u065F\uAAB2ss.󌓧; [V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+󟈣\u065F\uAAB2ss。󌓧; 󟈣\u065F\uAAB2ss.󌓧; [V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+󟈣\u065F\uAAB2Ss。󌓧; 󟈣\u065F\uAAB2ss.󌓧; [V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+xn--ss-3xd2839nncy1m.xn--bb79d; 󟈣\u065F\uAAB2ss.󌓧; [V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+xn--zca92z0t7n5w96j.xn--bb79d; 󟈣\u065F\uAAB2ß.󌓧; [V6]; xn--zca92z0t7n5w96j.xn--bb79d; ; ; # ٟꪲß.
+\u0774\u200C𞤿。𽘐䉜\u200D񿤼; \u0774\u200C𞤿.𽘐䉜\u200D񿤼; [C1, C2, V6]; xn--4pb607jjt73a.xn--1ug236ke314donv1a; ; xn--4pb2977v.xn--z0nt555ukbnv; [V6] # ݴ𞤿.䉜
+\u0774\u200C𞤝。𽘐䉜\u200D񿤼; \u0774\u200C𞤿.𽘐䉜\u200D񿤼; [C1, C2, V6]; xn--4pb607jjt73a.xn--1ug236ke314donv1a; ; xn--4pb2977v.xn--z0nt555ukbnv; [V6] # ݴ𞤿.䉜
+xn--4pb2977v.xn--z0nt555ukbnv; \u0774𞤿.𽘐䉜񿤼; [V6]; xn--4pb2977v.xn--z0nt555ukbnv; ; ; # ݴ𞤿.䉜
+xn--4pb607jjt73a.xn--1ug236ke314donv1a; \u0774\u200C𞤿.𽘐䉜\u200D񿤼; [C1, C2, V6]; xn--4pb607jjt73a.xn--1ug236ke314donv1a; ; ; # ݴ𞤿.䉜
+򔭜ςᡱ⒈.≮𑄳\u200D𐮍; ; [B1, V6]; xn--3xa407hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # ςᡱ⒈.≮𑄳𐮍
+򔭜ςᡱ⒈.<\u0338𑄳\u200D𐮍; 򔭜ςᡱ⒈.≮𑄳\u200D𐮍; [B1, V6]; xn--3xa407hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # ςᡱ⒈.≮𑄳𐮍
+򔭜ςᡱ1..≮𑄳\u200D𐮍; ; [B1, V6, X4_2]; xn--1-xmb999meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # ςᡱ1..≮𑄳𐮍
+򔭜ςᡱ1..<\u0338𑄳\u200D𐮍; 򔭜ςᡱ1..≮𑄳\u200D𐮍; [B1, V6, X4_2]; xn--1-xmb999meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # ςᡱ1..≮𑄳𐮍
+򔭜Σᡱ1..<\u0338𑄳\u200D𐮍; 򔭜σᡱ1..≮𑄳\u200D𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+򔭜Σᡱ1..≮𑄳\u200D𐮍; 򔭜σᡱ1..≮𑄳\u200D𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+򔭜σᡱ1..≮𑄳\u200D𐮍; ; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+򔭜σᡱ1..<\u0338𑄳\u200D𐮍; 򔭜σᡱ1..≮𑄳\u200D𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+xn--1-zmb699meq63t..xn--gdh5392g6sd; 򔭜σᡱ1..≮𑄳𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; [B1, V6, A4_2]; ; # σᡱ1..≮𑄳𐮍
+xn--1-zmb699meq63t..xn--1ug85gn777ahze; 򔭜σᡱ1..≮𑄳\u200D𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; ; # σᡱ1..≮𑄳𐮍
+xn--1-xmb999meq63t..xn--1ug85gn777ahze; 򔭜ςᡱ1..≮𑄳\u200D𐮍; [B1, V6, X4_2]; xn--1-xmb999meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; ; # ςᡱ1..≮𑄳𐮍
+򔭜Σᡱ⒈.<\u0338𑄳\u200D𐮍; 򔭜σᡱ⒈.≮𑄳\u200D𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+򔭜Σᡱ⒈.≮𑄳\u200D𐮍; 򔭜σᡱ⒈.≮𑄳\u200D𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+򔭜σᡱ⒈.≮𑄳\u200D𐮍; ; [B1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+򔭜σᡱ⒈.<\u0338𑄳\u200D𐮍; 򔭜σᡱ⒈.≮𑄳\u200D𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+xn--4xa207hkzinr77u.xn--gdh5392g6sd; 򔭜σᡱ⒈.≮𑄳𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--gdh5392g6sd; ; ; # σᡱ⒈.≮𑄳𐮍
+xn--4xa207hkzinr77u.xn--1ug85gn777ahze; 򔭜σᡱ⒈.≮𑄳\u200D𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; ; # σᡱ⒈.≮𑄳𐮍
+xn--3xa407hkzinr77u.xn--1ug85gn777ahze; 򔭜ςᡱ⒈.≮𑄳\u200D𐮍; [B1, V6]; xn--3xa407hkzinr77u.xn--1ug85gn777ahze; ; ; # ςᡱ⒈.≮𑄳𐮍
+\u3164\u094DႠ\u17D0.\u180B; \u3164\u094DႠ\u17D0.; [V6]; xn--n3b468azngju2a.; ; ; # ्Ⴀ័.
+\u1160\u094DႠ\u17D0.\u180B; \u1160\u094DႠ\u17D0.; [V6]; xn--n3b468aoqa89r.; ; ; # ्Ⴀ័.
+\u1160\u094Dⴀ\u17D0.\u180B; \u1160\u094Dⴀ\u17D0.; [V6]; xn--n3b742bkqf4ty.; ; ; # ्ⴀ័.
+xn--n3b742bkqf4ty.; \u1160\u094Dⴀ\u17D0.; [V6]; xn--n3b742bkqf4ty.; ; ; # ्ⴀ័.
+xn--n3b468aoqa89r.; \u1160\u094DႠ\u17D0.; [V6]; xn--n3b468aoqa89r.; ; ; # ्Ⴀ័.
+\u3164\u094Dⴀ\u17D0.\u180B; \u3164\u094Dⴀ\u17D0.; [V6]; xn--n3b445e53po6d.; ; ; # ्ⴀ័.
+xn--n3b445e53po6d.; \u3164\u094Dⴀ\u17D0.; [V6]; xn--n3b445e53po6d.; ; ; # ्ⴀ័.
+xn--n3b468azngju2a.; \u3164\u094DႠ\u17D0.; [V6]; xn--n3b468azngju2a.; ; ; # ्Ⴀ័.
+❣\u200D.\u09CD𑰽\u0612\uA929; ❣\u200D.\u09CD𑰽\u0612\uA929; [C2, V5]; xn--1ugy10a.xn--0fb32q3w7q2g4d; ; xn--pei.xn--0fb32q3w7q2g4d; [V5] # ❣.্𑰽ؒꤩ
+❣\u200D.\u09CD𑰽\u0612\uA929; ; [C2, V5]; xn--1ugy10a.xn--0fb32q3w7q2g4d; ; xn--pei.xn--0fb32q3w7q2g4d; [V5] # ❣.্𑰽ؒꤩ
+xn--pei.xn--0fb32q3w7q2g4d; ❣.\u09CD𑰽\u0612\uA929; [V5]; xn--pei.xn--0fb32q3w7q2g4d; ; ; # ❣.্𑰽ؒꤩ
+xn--1ugy10a.xn--0fb32q3w7q2g4d; ❣\u200D.\u09CD𑰽\u0612\uA929; [C2, V5]; xn--1ugy10a.xn--0fb32q3w7q2g4d; ; ; # ❣.্𑰽ؒꤩ
+≮𐳺𐹄.≯񪮸ꡅ; ; [B1, V6]; xn--gdh7943gk2a.xn--hdh1383c5e36c; ; ; # ≮𐳺.≯ꡅ
+<\u0338𐳺𐹄.>\u0338񪮸ꡅ; ≮𐳺𐹄.≯񪮸ꡅ; [B1, V6]; xn--gdh7943gk2a.xn--hdh1383c5e36c; ; ; # ≮𐳺.≯ꡅ
+xn--gdh7943gk2a.xn--hdh1383c5e36c; ≮𐳺𐹄.≯񪮸ꡅ; [B1, V6]; xn--gdh7943gk2a.xn--hdh1383c5e36c; ; ; # ≮𐳺.≯ꡅ
+\u0CCC𐧅𐳏󠲺。\u0CCDᠦ; \u0CCC𐧅𐳏󠲺.\u0CCDᠦ; [B1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+\u0CCC𐧅𐳏󠲺。\u0CCDᠦ; \u0CCC𐧅𐳏󠲺.\u0CCDᠦ; [B1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+\u0CCC𐧅𐲏󠲺。\u0CCDᠦ; \u0CCC𐧅𐳏󠲺.\u0CCDᠦ; [B1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+xn--7tc6360ky5bn2732c.xn--8tc429c; \u0CCC𐧅𐳏󠲺.\u0CCDᠦ; [B1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+\u0CCC𐧅𐲏󠲺。\u0CCDᠦ; \u0CCC𐧅𐳏󠲺.\u0CCDᠦ; [B1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+\u0349。𧡫; \u0349.𧡫; [V5]; xn--nua.xn--bc6k; ; ; # ͉.𧡫
+xn--nua.xn--bc6k; \u0349.𧡫; [V5]; xn--nua.xn--bc6k; ; ; # ͉.𧡫
+𑰿󠅦.\u1160; 𑰿.\u1160; [V5, V6]; xn--ok3d.xn--psd; ; ; # 𑰿.
+𑰿󠅦.\u1160; 𑰿.\u1160; [V5, V6]; xn--ok3d.xn--psd; ; ; # 𑰿.
+xn--ok3d.xn--psd; 𑰿.\u1160; [V5, V6]; xn--ok3d.xn--psd; ; ; # 𑰿.
+-𞤆\u200D。󸼄𞳒; -𞤨\u200D.󸼄𞳒; [B1, B5, B6, C2, V3, V6]; xn----ugnx367r.xn--846h96596c; ; xn----ni8r.xn--846h96596c; [B1, B5, B6, V3, V6] # -𞤨.
+-𞤨\u200D。󸼄𞳒; -𞤨\u200D.󸼄𞳒; [B1, B5, B6, C2, V3, V6]; xn----ugnx367r.xn--846h96596c; ; xn----ni8r.xn--846h96596c; [B1, B5, B6, V3, V6] # -𞤨.
+xn----ni8r.xn--846h96596c; -𞤨.󸼄𞳒; [B1, B5, B6, V3, V6]; xn----ni8r.xn--846h96596c; ; ; # -𞤨.
+xn----ugnx367r.xn--846h96596c; -𞤨\u200D.󸼄𞳒; [B1, B5, B6, C2, V3, V6]; xn----ugnx367r.xn--846h96596c; ; ; # -𞤨.
+ꡏ󠇶≯𳾽。\u1DFD⾇滸𐹰; ꡏ󠇶≯𳾽.\u1DFD舛滸𐹰; [B1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+ꡏ󠇶>\u0338𳾽。\u1DFD⾇滸𐹰; ꡏ󠇶≯𳾽.\u1DFD舛滸𐹰; [B1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+ꡏ󠇶≯𳾽。\u1DFD舛滸𐹰; ꡏ󠇶≯𳾽.\u1DFD舛滸𐹰; [B1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+ꡏ󠇶>\u0338𳾽。\u1DFD舛滸𐹰; ꡏ󠇶≯𳾽.\u1DFD舛滸𐹰; [B1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ꡏ󠇶≯𳾽.\u1DFD舛滸𐹰; [B1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+蔏。𑰺; 蔏.𑰺; [V5]; xn--uy1a.xn--jk3d; ; ; # 蔏.𑰺
+蔏。𑰺; 蔏.𑰺; [V5]; xn--uy1a.xn--jk3d; ; ; # 蔏.𑰺
+xn--uy1a.xn--jk3d; 蔏.𑰺; [V5]; xn--uy1a.xn--jk3d; ; ; # 蔏.𑰺
+𝟿𐮋。󠄊; 9𐮋.; [B1]; xn--9-rv5i.; ; ; # 9𐮋.
+9𐮋。󠄊; 9𐮋.; [B1]; xn--9-rv5i.; ; ; # 9𐮋.
+xn--9-rv5i.; 9𐮋.; [B1]; xn--9-rv5i.; ; ; # 9𐮋.
+󟇇-䟖F。\u07CB⒈\u0662; 󟇇-䟖f.\u07CB⒈\u0662; [B4, V6]; xn---f-mz8b08788k.xn--bib53ev44d; ; ; # -䟖f.ߋ⒈٢
+󟇇-䟖F。\u07CB1.\u0662; 󟇇-䟖f.\u07CB1.\u0662; [B1, V6]; xn---f-mz8b08788k.xn--1-ybd.xn--bib; ; ; # -䟖f.ߋ1.٢
+󟇇-䟖f。\u07CB1.\u0662; 󟇇-䟖f.\u07CB1.\u0662; [B1, V6]; xn---f-mz8b08788k.xn--1-ybd.xn--bib; ; ; # -䟖f.ߋ1.٢
+xn---f-mz8b08788k.xn--1-ybd.xn--bib; 󟇇-䟖f.\u07CB1.\u0662; [B1, V6]; xn---f-mz8b08788k.xn--1-ybd.xn--bib; ; ; # -䟖f.ߋ1.٢
+󟇇-䟖f。\u07CB⒈\u0662; 󟇇-䟖f.\u07CB⒈\u0662; [B4, V6]; xn---f-mz8b08788k.xn--bib53ev44d; ; ; # -䟖f.ߋ⒈٢
+xn---f-mz8b08788k.xn--bib53ev44d; 󟇇-䟖f.\u07CB⒈\u0662; [B4, V6]; xn---f-mz8b08788k.xn--bib53ev44d; ; ; # -䟖f.ߋ⒈٢
+\u200C。𐹺; \u200C.𐹺; [B1, C1]; xn--0ug.xn--yo0d; ; .xn--yo0d; [B1, A4_2] # .𐹺
+\u200C。𐹺; \u200C.𐹺; [B1, C1]; xn--0ug.xn--yo0d; ; .xn--yo0d; [B1, A4_2] # .𐹺
+.xn--yo0d; .𐹺; [B1, X4_2]; .xn--yo0d; [B1, A4_2]; ; # .𐹺
+xn--0ug.xn--yo0d; \u200C.𐹺; [B1, C1]; xn--0ug.xn--yo0d; ; ; # .𐹺
+𐡆.≯\u200C-𞥀; ; [B1, C1]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1] # 𐡆.≯-𞥀
+𐡆.>\u0338\u200C-𞥀; 𐡆.≯\u200C-𞥀; [B1, C1]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1] # 𐡆.≯-𞥀
+𐡆.>\u0338\u200C-𞤞; 𐡆.≯\u200C-𞥀; [B1, C1]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1] # 𐡆.≯-𞥀
+𐡆.≯\u200C-𞤞; 𐡆.≯\u200C-𞥀; [B1, C1]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1] # 𐡆.≯-𞥀
+xn--le9c.xn----ogo9956r; 𐡆.≯-𞥀; [B1]; xn--le9c.xn----ogo9956r; ; ; # 𐡆.≯-𞥀
+xn--le9c.xn----rgn40iy359e; 𐡆.≯\u200C-𞥀; [B1, C1]; xn--le9c.xn----rgn40iy359e; ; ; # 𐡆.≯-𞥀
+󠁀-。≠\uFCD7; 󠁀-.≠\u0647\u062C; [B1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+󠁀-。=\u0338\uFCD7; 󠁀-.≠\u0647\u062C; [B1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+󠁀-。≠\u0647\u062C; 󠁀-.≠\u0647\u062C; [B1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+󠁀-。=\u0338\u0647\u062C; 󠁀-.≠\u0647\u062C; [B1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+xn----f411m.xn--rgb7c611j; 󠁀-.≠\u0647\u062C; [B1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+񻬹𑈵。\u200D𞨶; 񻬹𑈵.\u200D𞨶; [B1, C2, V6]; xn--8g1d12120a.xn--1ug6651p; ; xn--8g1d12120a.xn--5l6h; [V6] # 𑈵.
+xn--8g1d12120a.xn--5l6h; 񻬹𑈵.𞨶; [V6]; xn--8g1d12120a.xn--5l6h; ; ; # 𑈵.
+xn--8g1d12120a.xn--1ug6651p; 񻬹𑈵.\u200D𞨶; [B1, C2, V6]; xn--8g1d12120a.xn--1ug6651p; ; ; # 𑈵.
+𑋧\uA9C02。㧉򒖄; 𑋧\uA9C02.㧉򒖄; [V5, V6]; xn--2-5z4eu89y.xn--97l02706d; ; ; # 𑋧꧀2.㧉
+𑋧\uA9C02。㧉򒖄; 𑋧\uA9C02.㧉򒖄; [V5, V6]; xn--2-5z4eu89y.xn--97l02706d; ; ; # 𑋧꧀2.㧉
+xn--2-5z4eu89y.xn--97l02706d; 𑋧\uA9C02.㧉򒖄; [V5, V6]; xn--2-5z4eu89y.xn--97l02706d; ; ; # 𑋧꧀2.㧉
+\u200C𽬄𐹴𞩥。≯6; \u200C𽬄𐹴𞩥.≯6; [B1, C1, V6]; xn--0ug7105gf5wfxepq.xn--6-ogo; ; xn--so0du768aim9m.xn--6-ogo; [B1, B5, B6, V6] # 𐹴.≯6
+\u200C𽬄𐹴𞩥。>\u03386; \u200C𽬄𐹴𞩥.≯6; [B1, C1, V6]; xn--0ug7105gf5wfxepq.xn--6-ogo; ; xn--so0du768aim9m.xn--6-ogo; [B1, B5, B6, V6] # 𐹴.≯6
+xn--so0du768aim9m.xn--6-ogo; 𽬄𐹴𞩥.≯6; [B1, B5, B6, V6]; xn--so0du768aim9m.xn--6-ogo; ; ; # 𐹴.≯6
+xn--0ug7105gf5wfxepq.xn--6-ogo; \u200C𽬄𐹴𞩥.≯6; [B1, C1, V6]; xn--0ug7105gf5wfxepq.xn--6-ogo; ; ; # 𐹴.≯6
+𑁿.𐹦𻞵-\u200D; 𑁿.𐹦𻞵-\u200D; [B1, C2, V5, V6]; xn--q30d.xn----ugn1088hfsxv; ; xn--q30d.xn----i26i1299n; [B1, V3, V5, V6] # 𑁿.𐹦-
+𑁿.𐹦𻞵-\u200D; ; [B1, C2, V5, V6]; xn--q30d.xn----ugn1088hfsxv; ; xn--q30d.xn----i26i1299n; [B1, V3, V5, V6] # 𑁿.𐹦-
+xn--q30d.xn----i26i1299n; 𑁿.𐹦𻞵-; [B1, V3, V5, V6]; xn--q30d.xn----i26i1299n; ; ; # 𑁿.𐹦-
+xn--q30d.xn----ugn1088hfsxv; 𑁿.𐹦𻞵-\u200D; [B1, C2, V5, V6]; xn--q30d.xn----ugn1088hfsxv; ; ; # 𑁿.𐹦-
+⤸ς𺱀。\uFFA0; ⤸ς𺱀.\uFFA0; [V6]; xn--3xa392qmp03d.xn--cl7c; ; xn--4xa192qmp03d.xn--cl7c; # ⤸ς.
+⤸ς𺱀。\u1160; ⤸ς𺱀.\u1160; [V6]; xn--3xa392qmp03d.xn--psd; ; xn--4xa192qmp03d.xn--psd; # ⤸ς.
+⤸Σ𺱀。\u1160; ⤸σ𺱀.\u1160; [V6]; xn--4xa192qmp03d.xn--psd; ; ; # ⤸σ.
+⤸σ𺱀。\u1160; ⤸σ𺱀.\u1160; [V6]; xn--4xa192qmp03d.xn--psd; ; ; # ⤸σ.
+xn--4xa192qmp03d.xn--psd; ⤸σ𺱀.\u1160; [V6]; xn--4xa192qmp03d.xn--psd; ; ; # ⤸σ.
+xn--3xa392qmp03d.xn--psd; ⤸ς𺱀.\u1160; [V6]; xn--3xa392qmp03d.xn--psd; ; ; # ⤸ς.
+⤸Σ𺱀。\uFFA0; ⤸σ𺱀.\uFFA0; [V6]; xn--4xa192qmp03d.xn--cl7c; ; ; # ⤸σ.
+⤸σ𺱀。\uFFA0; ⤸σ𺱀.\uFFA0; [V6]; xn--4xa192qmp03d.xn--cl7c; ; ; # ⤸σ.
+xn--4xa192qmp03d.xn--cl7c; ⤸σ𺱀.\uFFA0; [V6]; xn--4xa192qmp03d.xn--cl7c; ; ; # ⤸σ.
+xn--3xa392qmp03d.xn--cl7c; ⤸ς𺱀.\uFFA0; [V6]; xn--3xa392qmp03d.xn--cl7c; ; ; # ⤸ς.
+\u0765\u1035𐫔\u06D5.𐦬𑋪Ⴃ; ; [B2, B3, V6]; xn--llb10as9tqp5y.xn--bnd9168j21f; ; ; # ݥဵ𐫔ە.𐦬𑋪Ⴃ
+\u0765\u1035𐫔\u06D5.𐦬𑋪ⴃ; ; [B2, B3]; xn--llb10as9tqp5y.xn--ukj7371e21f; ; ; # ݥဵ𐫔ە.𐦬𑋪ⴃ
+xn--llb10as9tqp5y.xn--ukj7371e21f; \u0765\u1035𐫔\u06D5.𐦬𑋪ⴃ; [B2, B3]; xn--llb10as9tqp5y.xn--ukj7371e21f; ; ; # ݥဵ𐫔ە.𐦬𑋪ⴃ
+xn--llb10as9tqp5y.xn--bnd9168j21f; \u0765\u1035𐫔\u06D5.𐦬𑋪Ⴃ; [B2, B3, V6]; xn--llb10as9tqp5y.xn--bnd9168j21f; ; ; # ݥဵ𐫔ە.𐦬𑋪Ⴃ
+\u0661\u1B44-킼.\u1BAA\u0616\u066C≯; ; [B1, B5, B6, V5]; xn----9pc551nk39n.xn--4fb6o571degg; ; ; # ١᭄-킼.᮪ؖ٬≯
+\u0661\u1B44-킼.\u1BAA\u0616\u066C>\u0338; \u0661\u1B44-킼.\u1BAA\u0616\u066C≯; [B1, B5, B6, V5]; xn----9pc551nk39n.xn--4fb6o571degg; ; ; # ١᭄-킼.᮪ؖ٬≯
+xn----9pc551nk39n.xn--4fb6o571degg; \u0661\u1B44-킼.\u1BAA\u0616\u066C≯; [B1, B5, B6, V5]; xn----9pc551nk39n.xn--4fb6o571degg; ; ; # ١᭄-킼.᮪ؖ٬≯
+-。\u06C2\u0604򅖡𑓂; -.\u06C2\u0604򅖡𑓂; [B1, B2, B3, V3, V6]; -.xn--mfb39a7208dzgs3d; ; ; # -.ۂ𑓂
+-。\u06C1\u0654\u0604򅖡𑓂; -.\u06C2\u0604򅖡𑓂; [B1, B2, B3, V3, V6]; -.xn--mfb39a7208dzgs3d; ; ; # -.ۂ𑓂
+-.xn--mfb39a7208dzgs3d; -.\u06C2\u0604򅖡𑓂; [B1, B2, B3, V3, V6]; -.xn--mfb39a7208dzgs3d; ; ; # -.ۂ𑓂
+\u200D󯑖󠁐.\u05BD𙮰ꡝ𐋡; \u200D󯑖󠁐.\u05BD𙮰ꡝ𐋡; [C2, V5, V6]; xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ; xn--b726ey18m.xn--ldb8734fg0qcyzzg; [V5, V6] # .ֽꡝ𐋡
+\u200D󯑖󠁐.\u05BD𙮰ꡝ𐋡; ; [C2, V5, V6]; xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ; xn--b726ey18m.xn--ldb8734fg0qcyzzg; [V5, V6] # .ֽꡝ𐋡
+xn--b726ey18m.xn--ldb8734fg0qcyzzg; 󯑖󠁐.\u05BD𙮰ꡝ𐋡; [V5, V6]; xn--b726ey18m.xn--ldb8734fg0qcyzzg; ; ; # .ֽꡝ𐋡
+xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; \u200D󯑖󠁐.\u05BD𙮰ꡝ𐋡; [C2, V5, V6]; xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ; ; # .ֽꡝ𐋡
+︒􃈵ς񀠇。𐮈; ︒􃈵ς񀠇.𐮈; [B1, V6]; xn--3xa3729jwz5t7gl5f.xn--f29c; ; xn--4xa1729jwz5t7gl5f.xn--f29c; # ︒ς.𐮈
+。􃈵ς񀠇。𐮈; .􃈵ς񀠇.𐮈; [V6, X4_2]; .xn--3xa88573c7n64d.xn--f29c; [V6, A4_2]; .xn--4xa68573c7n64d.xn--f29c; # .ς.𐮈
+。􃈵Σ񀠇。𐮈; .􃈵σ񀠇.𐮈; [V6, X4_2]; .xn--4xa68573c7n64d.xn--f29c; [V6, A4_2]; ; # .σ.𐮈
+。􃈵σ񀠇。𐮈; .􃈵σ񀠇.𐮈; [V6, X4_2]; .xn--4xa68573c7n64d.xn--f29c; [V6, A4_2]; ; # .σ.𐮈
+.xn--4xa68573c7n64d.xn--f29c; .􃈵σ񀠇.𐮈; [V6, X4_2]; .xn--4xa68573c7n64d.xn--f29c; [V6, A4_2]; ; # .σ.𐮈
+.xn--3xa88573c7n64d.xn--f29c; .􃈵ς񀠇.𐮈; [V6, X4_2]; .xn--3xa88573c7n64d.xn--f29c; [V6, A4_2]; ; # .ς.𐮈
+︒􃈵Σ񀠇。𐮈; ︒􃈵σ񀠇.𐮈; [B1, V6]; xn--4xa1729jwz5t7gl5f.xn--f29c; ; ; # ︒σ.𐮈
+︒􃈵σ񀠇。𐮈; ︒􃈵σ񀠇.𐮈; [B1, V6]; xn--4xa1729jwz5t7gl5f.xn--f29c; ; ; # ︒σ.𐮈
+xn--4xa1729jwz5t7gl5f.xn--f29c; ︒􃈵σ񀠇.𐮈; [B1, V6]; xn--4xa1729jwz5t7gl5f.xn--f29c; ; ; # ︒σ.𐮈
+xn--3xa3729jwz5t7gl5f.xn--f29c; ︒􃈵ς񀠇.𐮈; [B1, V6]; xn--3xa3729jwz5t7gl5f.xn--f29c; ; ; # ︒ς.𐮈
+\u07D9.\u06EE󆾃≯󠅲; \u07D9.\u06EE󆾃≯; [B2, B3, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+\u07D9.\u06EE󆾃>\u0338󠅲; \u07D9.\u06EE󆾃≯; [B2, B3, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+\u07D9.\u06EE󆾃≯󠅲; \u07D9.\u06EE󆾃≯; [B2, B3, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+\u07D9.\u06EE󆾃>\u0338󠅲; \u07D9.\u06EE󆾃≯; [B2, B3, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+xn--0sb.xn--bmb691l0524t; \u07D9.\u06EE󆾃≯; [B2, B3, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+\u1A73󚙸.𐭍; ; [B1, V5, V6]; xn--2of22352n.xn--q09c; ; ; # ᩳ.𐭍
+xn--2of22352n.xn--q09c; \u1A73󚙸.𐭍; [B1, V5, V6]; xn--2of22352n.xn--q09c; ; ; # ᩳ.𐭍
+⒉󠊓≠。Ⴟ⬣Ⴈ; ⒉󠊓≠.Ⴟ⬣Ⴈ; [V6]; xn--1ch07f91401d.xn--gnd9b297j; ; ; # ⒉≠.Ⴟ⬣Ⴈ
+⒉󠊓=\u0338。Ⴟ⬣Ⴈ; ⒉󠊓≠.Ⴟ⬣Ⴈ; [V6]; xn--1ch07f91401d.xn--gnd9b297j; ; ; # ⒉≠.Ⴟ⬣Ⴈ
+2.󠊓≠。Ⴟ⬣Ⴈ; 2.󠊓≠.Ⴟ⬣Ⴈ; [V6]; 2.xn--1chz4101l.xn--gnd9b297j; ; ; # 2.≠.Ⴟ⬣Ⴈ
+2.󠊓=\u0338。Ⴟ⬣Ⴈ; 2.󠊓≠.Ⴟ⬣Ⴈ; [V6]; 2.xn--1chz4101l.xn--gnd9b297j; ; ; # 2.≠.Ⴟ⬣Ⴈ
+2.󠊓=\u0338。ⴟ⬣ⴈ; 2.󠊓≠.ⴟ⬣ⴈ; [V6]; 2.xn--1chz4101l.xn--45iz7d6b; ; ; # 2.≠.ⴟ⬣ⴈ
+2.󠊓≠。ⴟ⬣ⴈ; 2.󠊓≠.ⴟ⬣ⴈ; [V6]; 2.xn--1chz4101l.xn--45iz7d6b; ; ; # 2.≠.ⴟ⬣ⴈ
+2.xn--1chz4101l.xn--45iz7d6b; 2.󠊓≠.ⴟ⬣ⴈ; [V6]; 2.xn--1chz4101l.xn--45iz7d6b; ; ; # 2.≠.ⴟ⬣ⴈ
+2.xn--1chz4101l.xn--gnd9b297j; 2.󠊓≠.Ⴟ⬣Ⴈ; [V6]; 2.xn--1chz4101l.xn--gnd9b297j; ; ; # 2.≠.Ⴟ⬣Ⴈ
+⒉󠊓=\u0338。ⴟ⬣ⴈ; ⒉󠊓≠.ⴟ⬣ⴈ; [V6]; xn--1ch07f91401d.xn--45iz7d6b; ; ; # ⒉≠.ⴟ⬣ⴈ
+⒉󠊓≠。ⴟ⬣ⴈ; ⒉󠊓≠.ⴟ⬣ⴈ; [V6]; xn--1ch07f91401d.xn--45iz7d6b; ; ; # ⒉≠.ⴟ⬣ⴈ
+xn--1ch07f91401d.xn--45iz7d6b; ⒉󠊓≠.ⴟ⬣ⴈ; [V6]; xn--1ch07f91401d.xn--45iz7d6b; ; ; # ⒉≠.ⴟ⬣ⴈ
+xn--1ch07f91401d.xn--gnd9b297j; ⒉󠊓≠.Ⴟ⬣Ⴈ; [V6]; xn--1ch07f91401d.xn--gnd9b297j; ; ; # ⒉≠.Ⴟ⬣Ⴈ
+-󠉱\u0FB8Ⴥ。-𐹽\u0774𞣑; -󠉱\u0FB8Ⴥ.-𐹽\u0774𞣑; [B1, V3, V6]; xn----xmg12fm2555h.xn----05c4213ryr0g; ; ; # -ྸჅ.-𐹽ݴ𞣑
+-󠉱\u0FB8ⴥ。-𐹽\u0774𞣑; -󠉱\u0FB8ⴥ.-𐹽\u0774𞣑; [B1, V3, V6]; xn----xmg317tgv352a.xn----05c4213ryr0g; ; ; # -ྸⴥ.-𐹽ݴ𞣑
+xn----xmg317tgv352a.xn----05c4213ryr0g; -󠉱\u0FB8ⴥ.-𐹽\u0774𞣑; [B1, V3, V6]; xn----xmg317tgv352a.xn----05c4213ryr0g; ; ; # -ྸⴥ.-𐹽ݴ𞣑
+xn----xmg12fm2555h.xn----05c4213ryr0g; -󠉱\u0FB8Ⴥ.-𐹽\u0774𞣑; [B1, V3, V6]; xn----xmg12fm2555h.xn----05c4213ryr0g; ; ; # -ྸჅ.-𐹽ݴ𞣑
+\u0659。𑄴︒\u0627\u07DD; \u0659.𑄴︒\u0627\u07DD; [B1, V5, V6]; xn--1hb.xn--mgb09fp820c08pa; ; ; # ٙ.𑄴︒اߝ
+\u0659。𑄴。\u0627\u07DD; \u0659.𑄴.\u0627\u07DD; [B1, V5]; xn--1hb.xn--w80d.xn--mgb09f; ; ; # ٙ.𑄴.اߝ
+xn--1hb.xn--w80d.xn--mgb09f; \u0659.𑄴.\u0627\u07DD; [B1, V5]; xn--1hb.xn--w80d.xn--mgb09f; ; ; # ٙ.𑄴.اߝ
+xn--1hb.xn--mgb09fp820c08pa; \u0659.𑄴︒\u0627\u07DD; [B1, V5, V6]; xn--1hb.xn--mgb09fp820c08pa; ; ; # ٙ.𑄴︒اߝ
+Ⴙ\u0638.󠆓\u200D; Ⴙ\u0638.\u200D; [B1, B5, B6, C2, V6]; xn--3gb194c.xn--1ug; ; xn--3gb194c.; [B5, B6, V6] # Ⴙظ.
+ⴙ\u0638.󠆓\u200D; ⴙ\u0638.\u200D; [B1, B5, B6, C2]; xn--3gb910r.xn--1ug; ; xn--3gb910r.; [B5, B6] # ⴙظ.
+xn--3gb910r.; ⴙ\u0638.; [B5, B6]; xn--3gb910r.; ; ; # ⴙظ.
+xn--3gb910r.xn--1ug; ⴙ\u0638.\u200D; [B1, B5, B6, C2]; xn--3gb910r.xn--1ug; ; ; # ⴙظ.
+xn--3gb194c.; Ⴙ\u0638.; [B5, B6, V6]; xn--3gb194c.; ; ; # Ⴙظ.
+xn--3gb194c.xn--1ug; Ⴙ\u0638.\u200D; [B1, B5, B6, C2, V6]; xn--3gb194c.xn--1ug; ; ; # Ⴙظ.
+󠆸。₆0𐺧\u0756; .60𐺧\u0756; [B1, X4_2]; .xn--60-cke9470y; [B1, A4_2]; ; # .60𐺧ݖ
+󠆸。60𐺧\u0756; .60𐺧\u0756; [B1, X4_2]; .xn--60-cke9470y; [B1, A4_2]; ; # .60𐺧ݖ
+.xn--60-cke9470y; .60𐺧\u0756; [B1, X4_2]; .xn--60-cke9470y; [B1, A4_2]; ; # .60𐺧ݖ
+6\u084F。-𑈴; 6\u084F.-𑈴; [B1, V3]; xn--6-jjd.xn----6n8i; ; ; # 6ࡏ.-𑈴
+6\u084F。-𑈴; 6\u084F.-𑈴; [B1, V3]; xn--6-jjd.xn----6n8i; ; ; # 6ࡏ.-𑈴
+xn--6-jjd.xn----6n8i; 6\u084F.-𑈴; [B1, V3]; xn--6-jjd.xn----6n8i; ; ; # 6ࡏ.-𑈴
+\u200D񋌿𐹰。\u0ACDς𞰎\u08D6; \u200D񋌿𐹰.\u0ACDς𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, V5, V6] # 𐹰.્ςࣖ
+\u200D񋌿𐹰。\u0ACDς𞰎\u08D6; \u200D񋌿𐹰.\u0ACDς𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, V5, V6] # 𐹰.્ςࣖ
+\u200D񋌿𐹰。\u0ACDΣ𞰎\u08D6; \u200D񋌿𐹰.\u0ACDσ𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, V5, V6] # 𐹰.્σࣖ
+\u200D񋌿𐹰。\u0ACDσ𞰎\u08D6; \u200D񋌿𐹰.\u0ACDσ𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, V5, V6] # 𐹰.્σࣖ
+xn--oo0d1330n.xn--4xa21xcwbfz15g; 񋌿𐹰.\u0ACDσ𞰎\u08D6; [B1, B5, B6, V5, V6]; xn--oo0d1330n.xn--4xa21xcwbfz15g; ; ; # 𐹰.્σࣖ
+xn--1ugx105gq26y.xn--4xa21xcwbfz15g; \u200D񋌿𐹰.\u0ACDσ𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; ; # 𐹰.્σࣖ
+xn--1ugx105gq26y.xn--3xa41xcwbfz15g; \u200D񋌿𐹰.\u0ACDς𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ; ; # 𐹰.્ςࣖ
+\u200D񋌿𐹰。\u0ACDΣ𞰎\u08D6; \u200D񋌿𐹰.\u0ACDσ𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, V5, V6] # 𐹰.્σࣖ
+\u200D񋌿𐹰。\u0ACDσ𞰎\u08D6; \u200D񋌿𐹰.\u0ACDσ𞰎\u08D6; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, V5, V6] # 𐹰.્σࣖ
+⒈񟄜Ⴓ⒪.\u0DCA򘘶\u088B𐹢; ⒈񟄜Ⴓ⒪.\u0DCA򘘶\u088B𐹢; [B1, V5, V6]; xn--rnd762h7cx3027d.xn--3xb99xpx1yoes3e; ; ; # ⒈Ⴓ⒪.්ࢋ𐹢
+1.񟄜Ⴓ(o).\u0DCA򘘶\u088B𐹢; ; [B1, B6, V5, V6]; 1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; ; ; # 1.Ⴓ(o).්ࢋ𐹢
+1.񟄜ⴓ(o).\u0DCA򘘶\u088B𐹢; ; [B1, B6, V5, V6]; 1.xn--(o)-ej1bu5389e.xn--3xb99xpx1yoes3e; ; ; # 1.ⴓ(o).්ࢋ𐹢
+1.񟄜Ⴓ(O).\u0DCA򘘶\u088B𐹢; 1.񟄜Ⴓ(o).\u0DCA򘘶\u088B𐹢; [B1, B6, V5, V6]; 1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; ; ; # 1.Ⴓ(o).්ࢋ𐹢
+1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; 1.񟄜Ⴓ(o).\u0DCA򘘶\u088B𐹢; [B1, B6, V5, V6]; 1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; ; ; # 1.Ⴓ(o).්ࢋ𐹢
+1.xn--(o)-ej1bu5389e.xn--3xb99xpx1yoes3e; 1.񟄜ⴓ(o).\u0DCA򘘶\u088B𐹢; [B1, B6, V5, V6]; 1.xn--(o)-ej1bu5389e.xn--3xb99xpx1yoes3e; ; ; # 1.ⴓ(o).්ࢋ𐹢
+⒈񟄜ⴓ⒪.\u0DCA򘘶\u088B𐹢; ⒈񟄜ⴓ⒪.\u0DCA򘘶\u088B𐹢; [B1, V5, V6]; xn--tsh0ds63atl31n.xn--3xb99xpx1yoes3e; ; ; # ⒈ⴓ⒪.්ࢋ𐹢
+xn--tsh0ds63atl31n.xn--3xb99xpx1yoes3e; ⒈񟄜ⴓ⒪.\u0DCA򘘶\u088B𐹢; [B1, V5, V6]; xn--tsh0ds63atl31n.xn--3xb99xpx1yoes3e; ; ; # ⒈ⴓ⒪.්ࢋ𐹢
+xn--rnd762h7cx3027d.xn--3xb99xpx1yoes3e; ⒈񟄜Ⴓ⒪.\u0DCA򘘶\u088B𐹢; [B1, V5, V6]; xn--rnd762h7cx3027d.xn--3xb99xpx1yoes3e; ; ; # ⒈Ⴓ⒪.්ࢋ𐹢
+𞤷.𐮐𞢁𐹠\u0624; ; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𞤷.𐮐𞢁𐹠\u0648\u0654; 𞤷.𐮐𞢁𐹠\u0624; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𞤕.𐮐𞢁𐹠\u0648\u0654; 𞤷.𐮐𞢁𐹠\u0624; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𞤕.𐮐𞢁𐹠\u0624; 𞤷.𐮐𞢁𐹠\u0624; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+xn--ve6h.xn--jgb1694kz0b2176a; 𞤷.𐮐𞢁𐹠\u0624; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𐲈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+𐲈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+𐳈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+xn----ue6i.xn--v80d6662t; 𐳈-.𑄳񢌻; [B1, B3, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+𐳈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+-󠉖ꡧ.󠊂񇆃🄉; -󠉖ꡧ.󠊂񇆃🄉; [V3, V6]; xn----hg4ei0361g.xn--207ht163h7m94c; ; ; # -ꡧ.🄉
+-󠉖ꡧ.󠊂񇆃8,; ; [V3, V6]; xn----hg4ei0361g.xn--8,-k362evu488a; ; ; # -ꡧ.8,
+xn----hg4ei0361g.xn--8,-k362evu488a; -󠉖ꡧ.󠊂񇆃8,; [V3, V6]; xn----hg4ei0361g.xn--8,-k362evu488a; ; ; # -ꡧ.8,
+xn----hg4ei0361g.xn--207ht163h7m94c; -󠉖ꡧ.󠊂񇆃🄉; [V3, V6]; xn----hg4ei0361g.xn--207ht163h7m94c; ; ; # -ꡧ.🄉
+󠾛󠈴臯𧔤.\u0768𝟝; 󠾛󠈴臯𧔤.\u07685; [B1, V6]; xn--zb1at733hm579ddhla.xn--5-b5c; ; ; # 臯𧔤.ݨ5
+󠾛󠈴臯𧔤.\u07685; ; [B1, V6]; xn--zb1at733hm579ddhla.xn--5-b5c; ; ; # 臯𧔤.ݨ5
+xn--zb1at733hm579ddhla.xn--5-b5c; 󠾛󠈴臯𧔤.\u07685; [B1, V6]; xn--zb1at733hm579ddhla.xn--5-b5c; ; ; # 臯𧔤.ݨ5
+≮𐹣.𝨿; ≮𐹣.𝨿; [B1, V5]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+<\u0338𐹣.𝨿; ≮𐹣.𝨿; [B1, V5]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+≮𐹣.𝨿; ; [B1, V5]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+<\u0338𐹣.𝨿; ≮𐹣.𝨿; [B1, V5]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+xn--gdh1504g.xn--e92h; ≮𐹣.𝨿; [B1, V5]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+𐹯ᯛ\u0A4D。脥; 𐹯ᯛ\u0A4D.脥; [B1]; xn--ybc101g3m1p.xn--740a; ; ; # 𐹯ᯛ੍.脥
+𐹯ᯛ\u0A4D。脥; 𐹯ᯛ\u0A4D.脥; [B1]; xn--ybc101g3m1p.xn--740a; ; ; # 𐹯ᯛ੍.脥
+xn--ybc101g3m1p.xn--740a; 𐹯ᯛ\u0A4D.脥; [B1]; xn--ybc101g3m1p.xn--740a; ; ; # 𐹯ᯛ੍.脥
+\u1B44\u115F𞷿򃀍.-; ; [B1, B5, V3, V5, V6]; xn--osd971cpx70btgt8b.-; ; ; # ᭄.-
+xn--osd971cpx70btgt8b.-; \u1B44\u115F𞷿򃀍.-; [B1, B5, V3, V5, V6]; xn--osd971cpx70btgt8b.-; ; ; # ᭄.-
+\u200C。\u0354; \u200C.\u0354; [C1, V5]; xn--0ug.xn--yua; ; .xn--yua; [V5, A4_2] # .͔
+\u200C。\u0354; \u200C.\u0354; [C1, V5]; xn--0ug.xn--yua; ; .xn--yua; [V5, A4_2] # .͔
+.xn--yua; .\u0354; [V5, X4_2]; .xn--yua; [V5, A4_2]; ; # .͔
+xn--0ug.xn--yua; \u200C.\u0354; [C1, V5]; xn--0ug.xn--yua; ; ; # .͔
+𞤥󠅮.ᡄႮ; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤥󠅮.ᡄႮ; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤥󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤃󠅮.ᡄႮ; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤃󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+xn--de6h.xn--37e857h; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤥.ᡄⴎ; ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤃.ᡄႮ; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤃.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+xn--de6h.xn--mnd799a; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤥󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤃󠅮.ᡄႮ; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤃󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤥.ᡄႮ; ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤧𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤧𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤧𝨨ξ.𪺏㛨❸; ; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+xn--zxa5691vboja.xn--bfi293ci119b; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤧𝨨ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+᠆몆\u200C-。Ⴛ𐦅︒; ᠆몆\u200C-.Ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd2362jhgh; ; xn----e3j6620g.xn--znd2362jhgh; [B1, B5, B6, V3, V6] # ᠆몆-.Ⴛ𐦅︒
+᠆몆\u200C-。Ⴛ𐦅︒; ᠆몆\u200C-.Ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd2362jhgh; ; xn----e3j6620g.xn--znd2362jhgh; [B1, B5, B6, V3, V6] # ᠆몆-.Ⴛ𐦅︒
+᠆몆\u200C-。Ⴛ𐦅。; ᠆몆\u200C-.Ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd4948j.; ; xn----e3j6620g.xn--znd4948j.; [B1, B5, B6, V3, V6] # ᠆몆-.Ⴛ𐦅.
+᠆몆\u200C-。Ⴛ𐦅。; ᠆몆\u200C-.Ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd4948j.; ; xn----e3j6620g.xn--znd4948j.; [B1, B5, B6, V3, V6] # ᠆몆-.Ⴛ𐦅.
+᠆몆\u200C-。ⴛ𐦅。; ᠆몆\u200C-.ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlju661e.; ; xn----e3j6620g.xn--jlju661e.; [B1, B5, B6, V3, V6] # ᠆몆-.ⴛ𐦅.
+᠆몆\u200C-。ⴛ𐦅。; ᠆몆\u200C-.ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlju661e.; ; xn----e3j6620g.xn--jlju661e.; [B1, B5, B6, V3, V6] # ᠆몆-.ⴛ𐦅.
+xn----e3j6620g.xn--jlju661e.; ᠆몆-.ⴛ𐦅.; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--jlju661e.; ; ; # ᠆몆-.ⴛ𐦅.
+xn----e3j425bsk1o.xn--jlju661e.; ᠆몆\u200C-.ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlju661e.; ; ; # ᠆몆-.ⴛ𐦅.
+xn----e3j6620g.xn--znd4948j.; ᠆몆-.Ⴛ𐦅.; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--znd4948j.; ; ; # ᠆몆-.Ⴛ𐦅.
+xn----e3j425bsk1o.xn--znd4948j.; ᠆몆\u200C-.Ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd4948j.; ; ; # ᠆몆-.Ⴛ𐦅.
+᠆몆\u200C-。ⴛ𐦅︒; ᠆몆\u200C-.ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlj4997dhgh; ; xn----e3j6620g.xn--jlj4997dhgh; [B1, B5, B6, V3, V6] # ᠆몆-.ⴛ𐦅︒
+᠆몆\u200C-。ⴛ𐦅︒; ᠆몆\u200C-.ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlj4997dhgh; ; xn----e3j6620g.xn--jlj4997dhgh; [B1, B5, B6, V3, V6] # ᠆몆-.ⴛ𐦅︒
+xn----e3j6620g.xn--jlj4997dhgh; ᠆몆-.ⴛ𐦅︒; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--jlj4997dhgh; ; ; # ᠆몆-.ⴛ𐦅︒
+xn----e3j425bsk1o.xn--jlj4997dhgh; ᠆몆\u200C-.ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlj4997dhgh; ; ; # ᠆몆-.ⴛ𐦅︒
+xn----e3j6620g.xn--znd2362jhgh; ᠆몆-.Ⴛ𐦅︒; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--znd2362jhgh; ; ; # ᠆몆-.Ⴛ𐦅︒
+xn----e3j425bsk1o.xn--znd2362jhgh; ᠆몆\u200C-.Ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd2362jhgh; ; ; # ᠆몆-.Ⴛ𐦅︒
+󠾳.︒⥱\u200C𐹬; ; [B1, C1, V6]; xn--uf66e.xn--0ugz28axl3pqxna; ; xn--uf66e.xn--qtiz073e3ik; [B1, V6] # .︒⥱𐹬
+󠾳.。⥱\u200C𐹬; 󠾳..⥱\u200C𐹬; [B1, C1, V6, X4_2]; xn--uf66e..xn--0ugz28as66q; [B1, C1, V6, A4_2]; xn--uf66e..xn--qti2829e; [B1, V6, A4_2] # ..⥱𐹬
+xn--uf66e..xn--qti2829e; 󠾳..⥱𐹬; [B1, V6, X4_2]; xn--uf66e..xn--qti2829e; [B1, V6, A4_2]; ; # ..⥱𐹬
+xn--uf66e..xn--0ugz28as66q; 󠾳..⥱\u200C𐹬; [B1, C1, V6, X4_2]; xn--uf66e..xn--0ugz28as66q; [B1, C1, V6, A4_2]; ; # ..⥱𐹬
+xn--uf66e.xn--qtiz073e3ik; 󠾳.︒⥱𐹬; [B1, V6]; xn--uf66e.xn--qtiz073e3ik; ; ; # .︒⥱𐹬
+xn--uf66e.xn--0ugz28axl3pqxna; 󠾳.︒⥱\u200C𐹬; [B1, C1, V6]; xn--uf66e.xn--0ugz28axl3pqxna; ; ; # .︒⥱𐹬
+𐯖.𐹠Ⴑ񚇜𐫊; ; [B1, V6]; xn--n49c.xn--pnd4619jwicl862o; ; ; # .𐹠Ⴑ𐫊
+𐯖.𐹠ⴑ񚇜𐫊; ; [B1, V6]; xn--n49c.xn--8kj8702ewicl862o; ; ; # .𐹠ⴑ𐫊
+xn--n49c.xn--8kj8702ewicl862o; 𐯖.𐹠ⴑ񚇜𐫊; [B1, V6]; xn--n49c.xn--8kj8702ewicl862o; ; ; # .𐹠ⴑ𐫊
+xn--n49c.xn--pnd4619jwicl862o; 𐯖.𐹠Ⴑ񚇜𐫊; [B1, V6]; xn--n49c.xn--pnd4619jwicl862o; ; ; # .𐹠Ⴑ𐫊
+\u0FA4񱤯.𝟭Ⴛ; \u0FA4񱤯.1Ⴛ; [V5, V6]; xn--0fd40533g.xn--1-q1g; ; ; # ྤ.1Ⴛ
+\u0FA4񱤯.1Ⴛ; ; [V5, V6]; xn--0fd40533g.xn--1-q1g; ; ; # ྤ.1Ⴛ
+\u0FA4񱤯.1ⴛ; ; [V5, V6]; xn--0fd40533g.xn--1-tws; ; ; # ྤ.1ⴛ
+xn--0fd40533g.xn--1-tws; \u0FA4񱤯.1ⴛ; [V5, V6]; xn--0fd40533g.xn--1-tws; ; ; # ྤ.1ⴛ
+xn--0fd40533g.xn--1-q1g; \u0FA4񱤯.1Ⴛ; [V5, V6]; xn--0fd40533g.xn--1-q1g; ; ; # ྤ.1Ⴛ
+\u0FA4񱤯.𝟭ⴛ; \u0FA4񱤯.1ⴛ; [V5, V6]; xn--0fd40533g.xn--1-tws; ; ; # ྤ.1ⴛ
+-\u0826齀。릿𐸋; -\u0826齀.릿𐸋; [B1, B5, B6, V3, V6]; xn----6gd0617i.xn--7y2bm55m; ; ; # -ࠦ齀.릿
+-\u0826齀。릿𐸋; -\u0826齀.릿𐸋; [B1, B5, B6, V3, V6]; xn----6gd0617i.xn--7y2bm55m; ; ; # -ࠦ齀.릿
+xn----6gd0617i.xn--7y2bm55m; -\u0826齀.릿𐸋; [B1, B5, B6, V3, V6]; xn----6gd0617i.xn--7y2bm55m; ; ; # -ࠦ齀.릿
+󠔊\u071C鹝꾗。񾵐\u200D\u200D⏃; 󠔊\u071C鹝꾗.񾵐\u200D\u200D⏃; [B1, B6, C2, V6]; xn--mnb6558e91kyq533a.xn--1uga46zs309y; ; xn--mnb6558e91kyq533a.xn--6mh27269e; [B1, B6, V6] # ܜ鹝꾗.⏃
+󠔊\u071C鹝꾗。񾵐\u200D\u200D⏃; 󠔊\u071C鹝꾗.񾵐\u200D\u200D⏃; [B1, B6, C2, V6]; xn--mnb6558e91kyq533a.xn--1uga46zs309y; ; xn--mnb6558e91kyq533a.xn--6mh27269e; [B1, B6, V6] # ܜ鹝꾗.⏃
+xn--mnb6558e91kyq533a.xn--6mh27269e; 󠔊\u071C鹝꾗.񾵐⏃; [B1, B6, V6]; xn--mnb6558e91kyq533a.xn--6mh27269e; ; ; # ܜ鹝꾗.⏃
+xn--mnb6558e91kyq533a.xn--1uga46zs309y; 󠔊\u071C鹝꾗.񾵐\u200D\u200D⏃; [B1, B6, C2, V6]; xn--mnb6558e91kyq533a.xn--1uga46zs309y; ; ; # ܜ鹝꾗.⏃
+≮.-\u0708--; ≮.-\u0708--; [B1, V2, V3]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+<\u0338.-\u0708--; ≮.-\u0708--; [B1, V2, V3]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+≮.-\u0708--; ; [B1, V2, V3]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+<\u0338.-\u0708--; ≮.-\u0708--; [B1, V2, V3]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+xn--gdh.xn------eqf; ≮.-\u0708--; [B1, V2, V3]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+𐹸󠋳。\u200Dς𝟩; 𐹸󠋳.\u200Dς7; [B1, C2, V6]; xn--wo0di5177c.xn--7-xmb248s; ; xn--wo0di5177c.xn--7-zmb; [B1, V6] # 𐹸.ς7
+𐹸󠋳。\u200Dς7; 𐹸󠋳.\u200Dς7; [B1, C2, V6]; xn--wo0di5177c.xn--7-xmb248s; ; xn--wo0di5177c.xn--7-zmb; [B1, V6] # 𐹸.ς7
+𐹸󠋳。\u200DΣ7; 𐹸󠋳.\u200Dσ7; [B1, C2, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, V6] # 𐹸.σ7
+𐹸󠋳。\u200Dσ7; 𐹸󠋳.\u200Dσ7; [B1, C2, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, V6] # 𐹸.σ7
+xn--wo0di5177c.xn--7-zmb; 𐹸󠋳.σ7; [B1, V6]; xn--wo0di5177c.xn--7-zmb; ; ; # 𐹸.σ7
+xn--wo0di5177c.xn--7-zmb938s; 𐹸󠋳.\u200Dσ7; [B1, C2, V6]; xn--wo0di5177c.xn--7-zmb938s; ; ; # 𐹸.σ7
+xn--wo0di5177c.xn--7-xmb248s; 𐹸󠋳.\u200Dς7; [B1, C2, V6]; xn--wo0di5177c.xn--7-xmb248s; ; ; # 𐹸.ς7
+𐹸󠋳。\u200DΣ𝟩; 𐹸󠋳.\u200Dσ7; [B1, C2, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, V6] # 𐹸.σ7
+𐹸󠋳。\u200Dσ𝟩; 𐹸󠋳.\u200Dσ7; [B1, C2, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, V6] # 𐹸.σ7
+ς򅜌8.𞭤; ς򅜌8.𞭤; [V6]; xn--8-xmb44974n.xn--su6h; ; xn--8-zmb14974n.xn--su6h; # ς8.
+ς򅜌8.𞭤; ; [V6]; xn--8-xmb44974n.xn--su6h; ; xn--8-zmb14974n.xn--su6h; # ς8.
+Σ򅜌8.𞭤; σ򅜌8.𞭤; [V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+σ򅜌8.𞭤; ; [V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+xn--8-zmb14974n.xn--su6h; σ򅜌8.𞭤; [V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+xn--8-xmb44974n.xn--su6h; ς򅜌8.𞭤; [V6]; xn--8-xmb44974n.xn--su6h; ; ; # ς8.
+Σ򅜌8.𞭤; σ򅜌8.𞭤; [V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+σ򅜌8.𞭤; σ򅜌8.𞭤; [V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+\u200Cᡑ🄀\u0684.-𐫄𑲤; \u200Cᡑ🄀\u0684.-𐫄𑲤; [B1, C1, V3, V6]; xn--9ib722gvtfi563c.xn----ek5i065b; ; xn--9ib722gbw95a.xn----ek5i065b; [B1, B5, B6, V3, V6] # ᡑ🄀ڄ.-𐫄𑲤
+\u200Cᡑ0.\u0684.-𐫄𑲤; ; [B1, C1, V3]; xn--0-o7j263b.xn--9ib.xn----ek5i065b; ; xn--0-o7j.xn--9ib.xn----ek5i065b; [B1, V3] # ᡑ0.ڄ.-𐫄𑲤
+xn--0-o7j.xn--9ib.xn----ek5i065b; ᡑ0.\u0684.-𐫄𑲤; [B1, V3]; xn--0-o7j.xn--9ib.xn----ek5i065b; ; ; # ᡑ0.ڄ.-𐫄𑲤
+xn--0-o7j263b.xn--9ib.xn----ek5i065b; \u200Cᡑ0.\u0684.-𐫄𑲤; [B1, C1, V3]; xn--0-o7j263b.xn--9ib.xn----ek5i065b; ; ; # ᡑ0.ڄ.-𐫄𑲤
+xn--9ib722gbw95a.xn----ek5i065b; ᡑ🄀\u0684.-𐫄𑲤; [B1, B5, B6, V3, V6]; xn--9ib722gbw95a.xn----ek5i065b; ; ; # ᡑ🄀ڄ.-𐫄𑲤
+xn--9ib722gvtfi563c.xn----ek5i065b; \u200Cᡑ🄀\u0684.-𐫄𑲤; [B1, C1, V3, V6]; xn--9ib722gvtfi563c.xn----ek5i065b; ; ; # ᡑ🄀ڄ.-𐫄𑲤
+𖠍。𐪿넯򞵲; 𖠍.𐪿넯򞵲; [B2, B3, V6]; xn--4e9e.xn--l60bj21opd57g; ; ; # 𖠍.넯
+𖠍。𐪿넯򞵲; 𖠍.𐪿넯򞵲; [B2, B3, V6]; xn--4e9e.xn--l60bj21opd57g; ; ; # 𖠍.넯
+xn--4e9e.xn--l60bj21opd57g; 𖠍.𐪿넯򞵲; [B2, B3, V6]; xn--4e9e.xn--l60bj21opd57g; ; ; # 𖠍.넯
+᠇Ⴘ。\u0603Ⴈ𝆊; ᠇Ⴘ.\u0603Ⴈ𝆊; [B1, V6]; xn--wnd558a.xn--lfb465c1v87a; ; ; # ᠇Ⴘ.Ⴈ𝆊
+᠇ⴘ。\u0603ⴈ𝆊; ᠇ⴘ.\u0603ⴈ𝆊; [B1, V6]; xn--d6e009h.xn--lfb290rfu3z; ; ; # ᠇ⴘ.ⴈ𝆊
+xn--d6e009h.xn--lfb290rfu3z; ᠇ⴘ.\u0603ⴈ𝆊; [B1, V6]; xn--d6e009h.xn--lfb290rfu3z; ; ; # ᠇ⴘ.ⴈ𝆊
+xn--wnd558a.xn--lfb465c1v87a; ᠇Ⴘ.\u0603Ⴈ𝆊; [B1, V6]; xn--wnd558a.xn--lfb465c1v87a; ; ; # ᠇Ⴘ.Ⴈ𝆊
+⒚󠋑𞤰。牣\u0667Ⴜᣥ; ⒚󠋑𞤰.牣\u0667Ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib404ccxgh00h; ; ; # ⒚𞤰.牣٧Ⴜᣥ
+19.󠋑𞤰。牣\u0667Ⴜᣥ; 19.󠋑𞤰.牣\u0667Ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib404ccxgh00h; ; ; # 19.𞤰.牣٧Ⴜᣥ
+19.󠋑𞤰。牣\u0667ⴜᣥ; 19.󠋑𞤰.牣\u0667ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib285gtxo2l9d; ; ; # 19.𞤰.牣٧ⴜᣥ
+19.󠋑𞤎。牣\u0667Ⴜᣥ; 19.󠋑𞤰.牣\u0667Ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib404ccxgh00h; ; ; # 19.𞤰.牣٧Ⴜᣥ
+19.󠋑𞤎。牣\u0667ⴜᣥ; 19.󠋑𞤰.牣\u0667ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib285gtxo2l9d; ; ; # 19.𞤰.牣٧ⴜᣥ
+19.xn--oe6h75760c.xn--gib285gtxo2l9d; 19.󠋑𞤰.牣\u0667ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib285gtxo2l9d; ; ; # 19.𞤰.牣٧ⴜᣥ
+19.xn--oe6h75760c.xn--gib404ccxgh00h; 19.󠋑𞤰.牣\u0667Ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib404ccxgh00h; ; ; # 19.𞤰.牣٧Ⴜᣥ
+⒚󠋑𞤰。牣\u0667ⴜᣥ; ⒚󠋑𞤰.牣\u0667ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib285gtxo2l9d; ; ; # ⒚𞤰.牣٧ⴜᣥ
+⒚󠋑𞤎。牣\u0667Ⴜᣥ; ⒚󠋑𞤰.牣\u0667Ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib404ccxgh00h; ; ; # ⒚𞤰.牣٧Ⴜᣥ
+⒚󠋑𞤎。牣\u0667ⴜᣥ; ⒚󠋑𞤰.牣\u0667ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib285gtxo2l9d; ; ; # ⒚𞤰.牣٧ⴜᣥ
+xn--cthy466n29j3e.xn--gib285gtxo2l9d; ⒚󠋑𞤰.牣\u0667ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib285gtxo2l9d; ; ; # ⒚𞤰.牣٧ⴜᣥ
+xn--cthy466n29j3e.xn--gib404ccxgh00h; ⒚󠋑𞤰.牣\u0667Ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib404ccxgh00h; ; ; # ⒚𞤰.牣٧Ⴜᣥ
+-𐋱𐰽⒈.Ⴓ; ; [B1, V3, V6]; xn----ecp0206g90h.xn--rnd; ; ; # -𐋱𐰽⒈.Ⴓ
+-𐋱𐰽1..Ⴓ; ; [B1, V3, V6, X4_2]; xn---1-895nq11a..xn--rnd; [B1, V3, V6, A4_2]; ; # -𐋱𐰽1..Ⴓ
+-𐋱𐰽1..ⴓ; ; [B1, V3, X4_2]; xn---1-895nq11a..xn--blj; [B1, V3, A4_2]; ; # -𐋱𐰽1..ⴓ
+xn---1-895nq11a..xn--blj; -𐋱𐰽1..ⴓ; [B1, V3, X4_2]; xn---1-895nq11a..xn--blj; [B1, V3, A4_2]; ; # -𐋱𐰽1..ⴓ
+xn---1-895nq11a..xn--rnd; -𐋱𐰽1..Ⴓ; [B1, V3, V6, X4_2]; xn---1-895nq11a..xn--rnd; [B1, V3, V6, A4_2]; ; # -𐋱𐰽1..Ⴓ
+-𐋱𐰽⒈.ⴓ; ; [B1, V3, V6]; xn----ecp0206g90h.xn--blj; ; ; # -𐋱𐰽⒈.ⴓ
+xn----ecp0206g90h.xn--blj; -𐋱𐰽⒈.ⴓ; [B1, V3, V6]; xn----ecp0206g90h.xn--blj; ; ; # -𐋱𐰽⒈.ⴓ
+xn----ecp0206g90h.xn--rnd; -𐋱𐰽⒈.Ⴓ; [B1, V3, V6]; xn----ecp0206g90h.xn--rnd; ; ; # -𐋱𐰽⒈.Ⴓ
+\u200C긃.榶-; ; [C1, V3]; xn--0ug3307c.xn----d87b; ; xn--ej0b.xn----d87b; [V3] # 긃.榶-
+\u200C긃.榶-; \u200C긃.榶-; [C1, V3]; xn--0ug3307c.xn----d87b; ; xn--ej0b.xn----d87b; [V3] # 긃.榶-
+xn--ej0b.xn----d87b; 긃.榶-; [V3]; xn--ej0b.xn----d87b; ; ; # 긃.榶-
+xn--0ug3307c.xn----d87b; \u200C긃.榶-; [C1, V3]; xn--0ug3307c.xn----d87b; ; ; # 긃.榶-
+뉓泓𜵽.\u09CD\u200D; ; [V5, V6]; xn--lwwp69lqs7m.xn--b7b605i; ; xn--lwwp69lqs7m.xn--b7b; # 뉓泓.্
+뉓泓𜵽.\u09CD\u200D; 뉓泓𜵽.\u09CD\u200D; [V5, V6]; xn--lwwp69lqs7m.xn--b7b605i; ; xn--lwwp69lqs7m.xn--b7b; # 뉓泓.্
+xn--lwwp69lqs7m.xn--b7b; 뉓泓𜵽.\u09CD; [V5, V6]; xn--lwwp69lqs7m.xn--b7b; ; ; # 뉓泓.্
+xn--lwwp69lqs7m.xn--b7b605i; 뉓泓𜵽.\u09CD\u200D; [V5, V6]; xn--lwwp69lqs7m.xn--b7b605i; ; ; # 뉓泓.্
+\u200D𐹴ß。\u0EB4\u2B75񪅌; \u200D𐹴ß.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--zca770nip7n.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ß.ິ
+\u200D𐹴ß。\u0EB4\u2B75񪅌; \u200D𐹴ß.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--zca770nip7n.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ß.ິ
+\u200D𐹴SS。\u0EB4\u2B75񪅌; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ss.ິ
+\u200D𐹴ss。\u0EB4\u2B75񪅌; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ss.ິ
+\u200D𐹴Ss。\u0EB4\u2B75񪅌; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ss.ິ
+xn--ss-ti3o.xn--57c638l8774i; 𐹴ss.\u0EB4\u2B75񪅌; [B1, V5, V6]; xn--ss-ti3o.xn--57c638l8774i; ; ; # 𐹴ss.ິ
+xn--ss-l1t5169j.xn--57c638l8774i; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; ; # 𐹴ss.ິ
+xn--zca770nip7n.xn--57c638l8774i; \u200D𐹴ß.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--zca770nip7n.xn--57c638l8774i; ; ; # 𐹴ß.ິ
+\u200D𐹴SS。\u0EB4\u2B75񪅌; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ss.ິ
+\u200D𐹴ss。\u0EB4\u2B75񪅌; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ss.ິ
+\u200D𐹴Ss。\u0EB4\u2B75񪅌; \u200D𐹴ss.\u0EB4\u2B75񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, V5, V6] # 𐹴ss.ິ
+\u1B44.\u1BAA-≮≠; \u1B44.\u1BAA-≮≠; [V5]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+\u1B44.\u1BAA-<\u0338=\u0338; \u1B44.\u1BAA-≮≠; [V5]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+\u1B44.\u1BAA-≮≠; ; [V5]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+\u1B44.\u1BAA-<\u0338=\u0338; \u1B44.\u1BAA-≮≠; [V5]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+xn--1uf.xn----nmlz65aub; \u1B44.\u1BAA-≮≠; [V5]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+\u1BF3Ⴑ\u115F.𑄴Ⅎ; \u1BF3Ⴑ\u115F.𑄴Ⅎ; [V5, V6]; xn--pnd26a55x.xn--f3g7465g; ; ; # ᯳Ⴑ.𑄴Ⅎ
+\u1BF3Ⴑ\u115F.𑄴Ⅎ; ; [V5, V6]; xn--pnd26a55x.xn--f3g7465g; ; ; # ᯳Ⴑ.𑄴Ⅎ
+\u1BF3ⴑ\u115F.𑄴ⅎ; ; [V5, V6]; xn--osd925cvyn.xn--73g3065g; ; ; # ᯳ⴑ.𑄴ⅎ
+\u1BF3Ⴑ\u115F.𑄴ⅎ; ; [V5, V6]; xn--pnd26a55x.xn--73g3065g; ; ; # ᯳Ⴑ.𑄴ⅎ
+xn--pnd26a55x.xn--73g3065g; \u1BF3Ⴑ\u115F.𑄴ⅎ; [V5, V6]; xn--pnd26a55x.xn--73g3065g; ; ; # ᯳Ⴑ.𑄴ⅎ
+xn--osd925cvyn.xn--73g3065g; \u1BF3ⴑ\u115F.𑄴ⅎ; [V5, V6]; xn--osd925cvyn.xn--73g3065g; ; ; # ᯳ⴑ.𑄴ⅎ
+xn--pnd26a55x.xn--f3g7465g; \u1BF3Ⴑ\u115F.𑄴Ⅎ; [V5, V6]; xn--pnd26a55x.xn--f3g7465g; ; ; # ᯳Ⴑ.𑄴Ⅎ
+\u1BF3ⴑ\u115F.𑄴ⅎ; \u1BF3ⴑ\u115F.𑄴ⅎ; [V5, V6]; xn--osd925cvyn.xn--73g3065g; ; ; # ᯳ⴑ.𑄴ⅎ
+\u1BF3Ⴑ\u115F.𑄴ⅎ; \u1BF3Ⴑ\u115F.𑄴ⅎ; [V5, V6]; xn--pnd26a55x.xn--73g3065g; ; ; # ᯳Ⴑ.𑄴ⅎ
+𜉆。Ⴃ𐴣𐹹똯; 𜉆.Ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--bnd4785f8r8bdeb; ; ; # .Ⴃ𐴣𐹹똯
+𜉆。Ⴃ𐴣𐹹똯; 𜉆.Ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--bnd4785f8r8bdeb; ; ; # .Ⴃ𐴣𐹹똯
+𜉆。ⴃ𐴣𐹹똯; 𜉆.ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--ukjy205b8rscdeb; ; ; # .ⴃ𐴣𐹹똯
+𜉆。ⴃ𐴣𐹹똯; 𜉆.ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--ukjy205b8rscdeb; ; ; # .ⴃ𐴣𐹹똯
+xn--187g.xn--ukjy205b8rscdeb; 𜉆.ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--ukjy205b8rscdeb; ; ; # .ⴃ𐴣𐹹똯
+xn--187g.xn--bnd4785f8r8bdeb; 𜉆.Ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--bnd4785f8r8bdeb; ; ; # .Ⴃ𐴣𐹹똯
+𐫀。⳻󠙾󠄷\u3164; 𐫀.⳻󠙾\u3164; [B1, V6]; xn--pw9c.xn--mkj83l4v899a; ; ; # 𐫀.⳻
+𐫀。⳻󠙾󠄷\u1160; 𐫀.⳻󠙾\u1160; [B1, V6]; xn--pw9c.xn--psd742lxt32w; ; ; # 𐫀.⳻
+xn--pw9c.xn--psd742lxt32w; 𐫀.⳻󠙾\u1160; [B1, V6]; xn--pw9c.xn--psd742lxt32w; ; ; # 𐫀.⳻
+xn--pw9c.xn--mkj83l4v899a; 𐫀.⳻󠙾\u3164; [B1, V6]; xn--pw9c.xn--mkj83l4v899a; ; ; # 𐫀.⳻
+\u079A⾇.\u071E-𐋰; \u079A舛.\u071E-𐋰; [B2, B3]; xn--7qb6383d.xn----20c3154q; ; ; # ޚ舛.ܞ-𐋰
+\u079A舛.\u071E-𐋰; ; [B2, B3]; xn--7qb6383d.xn----20c3154q; ; ; # ޚ舛.ܞ-𐋰
+xn--7qb6383d.xn----20c3154q; \u079A舛.\u071E-𐋰; [B2, B3]; xn--7qb6383d.xn----20c3154q; ; ; # ޚ舛.ܞ-𐋰
+Ⴉ猕󹛫≮.︒; Ⴉ猕󹛫≮.︒; [V6]; xn--hnd212gz32d54x5r.xn--y86c; ; ; # Ⴉ猕≮.︒
+Ⴉ猕󹛫<\u0338.︒; Ⴉ猕󹛫≮.︒; [V6]; xn--hnd212gz32d54x5r.xn--y86c; ; ; # Ⴉ猕≮.︒
+Ⴉ猕󹛫≮.。; Ⴉ猕󹛫≮..; [V6, X4_2]; xn--hnd212gz32d54x5r..; [V6, A4_2]; ; # Ⴉ猕≮..
+Ⴉ猕󹛫<\u0338.。; Ⴉ猕󹛫≮..; [V6, X4_2]; xn--hnd212gz32d54x5r..; [V6, A4_2]; ; # Ⴉ猕≮..
+ⴉ猕󹛫<\u0338.。; ⴉ猕󹛫≮..; [V6, X4_2]; xn--gdh892bbz0d5438s..; [V6, A4_2]; ; # ⴉ猕≮..
+ⴉ猕󹛫≮.。; ⴉ猕󹛫≮..; [V6, X4_2]; xn--gdh892bbz0d5438s..; [V6, A4_2]; ; # ⴉ猕≮..
+xn--gdh892bbz0d5438s..; ⴉ猕󹛫≮..; [V6, X4_2]; xn--gdh892bbz0d5438s..; [V6, A4_2]; ; # ⴉ猕≮..
+xn--hnd212gz32d54x5r..; Ⴉ猕󹛫≮..; [V6, X4_2]; xn--hnd212gz32d54x5r..; [V6, A4_2]; ; # Ⴉ猕≮..
+ⴉ猕󹛫<\u0338.︒; ⴉ猕󹛫≮.︒; [V6]; xn--gdh892bbz0d5438s.xn--y86c; ; ; # ⴉ猕≮.︒
+ⴉ猕󹛫≮.︒; ⴉ猕󹛫≮.︒; [V6]; xn--gdh892bbz0d5438s.xn--y86c; ; ; # ⴉ猕≮.︒
+xn--gdh892bbz0d5438s.xn--y86c; ⴉ猕󹛫≮.︒; [V6]; xn--gdh892bbz0d5438s.xn--y86c; ; ; # ⴉ猕≮.︒
+xn--hnd212gz32d54x5r.xn--y86c; Ⴉ猕󹛫≮.︒; [V6]; xn--hnd212gz32d54x5r.xn--y86c; ; ; # Ⴉ猕≮.︒
+🏮。\u062B鳳\u07E2󠅉; 🏮.\u062B鳳\u07E2; [B1, B2]; xn--8m8h.xn--qgb29f6z90a; ; ; # 🏮.ث鳳ߢ
+🏮。\u062B鳳\u07E2󠅉; 🏮.\u062B鳳\u07E2; [B1, B2]; xn--8m8h.xn--qgb29f6z90a; ; ; # 🏮.ث鳳ߢ
+xn--8m8h.xn--qgb29f6z90a; 🏮.\u062B鳳\u07E2; [B1, B2]; xn--8m8h.xn--qgb29f6z90a; ; ; # 🏮.ث鳳ߢ
+\u200D𐹶。ß; \u200D𐹶.ß; [B1, C2]; xn--1ug9105g.xn--zca; ; xn--uo0d.ss; [B1] # 𐹶.ß
+\u200D𐹶。SS; \u200D𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; xn--uo0d.ss; [B1] # 𐹶.ss
+\u200D𐹶。ss; \u200D𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; xn--uo0d.ss; [B1] # 𐹶.ss
+\u200D𐹶。Ss; \u200D𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; xn--uo0d.ss; [B1] # 𐹶.ss
+xn--uo0d.ss; 𐹶.ss; [B1]; xn--uo0d.ss; ; ; # 𐹶.ss
+xn--1ug9105g.ss; \u200D𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; ; # 𐹶.ss
+xn--1ug9105g.xn--zca; \u200D𐹶.ß; [B1, C2]; xn--1ug9105g.xn--zca; ; ; # 𐹶.ß
+Å둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+A\u030A둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+Å둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+A\u030A둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+a\u030A둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+å둄-.\u200C; ; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+xn----1fa1788k.; å둄-.; [V3]; xn----1fa1788k.; ; ; # å둄-.
+xn----1fa1788k.xn--0ug; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; ; # å둄-.
+a\u030A둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+å둄-.\u200C; å둄-.\u200C; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+\u3099򬎑\u1DD7𞤀.򱲢-\u0953; \u3099򬎑\u1DD7𞤢.򱲢-\u0953; [B1, B6, V5, V6]; xn--veg121fwg63altj9d.xn----eyd92688s; ; ; # ゙ᷗ𞤢.-॓
+\u3099򬎑\u1DD7𞤢.򱲢-\u0953; ; [B1, B6, V5, V6]; xn--veg121fwg63altj9d.xn----eyd92688s; ; ; # ゙ᷗ𞤢.-॓
+xn--veg121fwg63altj9d.xn----eyd92688s; \u3099򬎑\u1DD7𞤢.򱲢-\u0953; [B1, B6, V5, V6]; xn--veg121fwg63altj9d.xn----eyd92688s; ; ; # ゙ᷗ𞤢.-॓
+ς.ß񴱄\u06DD\u2D7F; ; [B5, B6, V6]; xn--3xa.xn--zca281az71b8x73m; ; xn--4xa.xn--ss-y8d4760biv60n; # ς.ß⵿
+Σ.SS񴱄\u06DD\u2D7F; σ.ss񴱄\u06DD\u2D7F; [B5, B6, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+σ.ss񴱄\u06DD\u2D7F; ; [B5, B6, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+Σ.ss񴱄\u06DD\u2D7F; σ.ss񴱄\u06DD\u2D7F; [B5, B6, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+xn--4xa.xn--ss-y8d4760biv60n; σ.ss񴱄\u06DD\u2D7F; [B5, B6, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+Σ.ß񴱄\u06DD\u2D7F; σ.ß񴱄\u06DD\u2D7F; [B5, B6, V6]; xn--4xa.xn--zca281az71b8x73m; ; xn--4xa.xn--ss-y8d4760biv60n; # σ.ß⵿
+σ.ß񴱄\u06DD\u2D7F; ; [B5, B6, V6]; xn--4xa.xn--zca281az71b8x73m; ; xn--4xa.xn--ss-y8d4760biv60n; # σ.ß⵿
+xn--4xa.xn--zca281az71b8x73m; σ.ß񴱄\u06DD\u2D7F; [B5, B6, V6]; xn--4xa.xn--zca281az71b8x73m; ; ; # σ.ß⵿
+xn--3xa.xn--zca281az71b8x73m; ς.ß񴱄\u06DD\u2D7F; [B5, B6, V6]; xn--3xa.xn--zca281az71b8x73m; ; ; # ς.ß⵿
+ꡀ𞀟。\u066B\u0599; ꡀ𞀟.\u066B\u0599; [B1]; xn--8b9a1720d.xn--kcb33b; ; ; # ꡀ𞀟.٫֙
+ꡀ𞀟。\u066B\u0599; ꡀ𞀟.\u066B\u0599; [B1]; xn--8b9a1720d.xn--kcb33b; ; ; # ꡀ𞀟.٫֙
+xn--8b9a1720d.xn--kcb33b; ꡀ𞀟.\u066B\u0599; [B1]; xn--8b9a1720d.xn--kcb33b; ; ; # ꡀ𞀟.٫֙
+򈛉\u200C\u08A9。⧅񘘡-𐭡; 򈛉\u200C\u08A9.⧅񘘡-𐭡; [B1, B5, B6, C1, V6]; xn--yyb780jll63m.xn----zir1232guu71b; ; xn--yyb56242i.xn----zir1232guu71b; [B1, B5, B6, V6] # ࢩ.⧅-𐭡
+򈛉\u200C\u08A9。⧅񘘡-𐭡; 򈛉\u200C\u08A9.⧅񘘡-𐭡; [B1, B5, B6, C1, V6]; xn--yyb780jll63m.xn----zir1232guu71b; ; xn--yyb56242i.xn----zir1232guu71b; [B1, B5, B6, V6] # ࢩ.⧅-𐭡
+xn--yyb56242i.xn----zir1232guu71b; 򈛉\u08A9.⧅񘘡-𐭡; [B1, B5, B6, V6]; xn--yyb56242i.xn----zir1232guu71b; ; ; # ࢩ.⧅-𐭡
+xn--yyb780jll63m.xn----zir1232guu71b; 򈛉\u200C\u08A9.⧅񘘡-𐭡; [B1, B5, B6, C1, V6]; xn--yyb780jll63m.xn----zir1232guu71b; ; ; # ࢩ.⧅-𐭡
+룱\u200D𰍨\u200C。𝨖︒; 룱\u200D𰍨\u200C.𝨖︒; [C1, C2, V5, V6]; xn--0ugb3358ili2v.xn--y86cl899a; ; xn--ct2b0738h.xn--y86cl899a; [V5, V6] # 룱𰍨.𝨖︒
+룱\u200D𰍨\u200C。𝨖︒; 룱\u200D𰍨\u200C.𝨖︒; [C1, C2, V5, V6]; xn--0ugb3358ili2v.xn--y86cl899a; ; xn--ct2b0738h.xn--y86cl899a; [V5, V6] # 룱𰍨.𝨖︒
+룱\u200D𰍨\u200C。𝨖。; 룱\u200D𰍨\u200C.𝨖.; [C1, C2, V5]; xn--0ugb3358ili2v.xn--772h.; ; xn--ct2b0738h.xn--772h.; [V5] # 룱𰍨.𝨖.
+룱\u200D𰍨\u200C。𝨖。; 룱\u200D𰍨\u200C.𝨖.; [C1, C2, V5]; xn--0ugb3358ili2v.xn--772h.; ; xn--ct2b0738h.xn--772h.; [V5] # 룱𰍨.𝨖.
+xn--ct2b0738h.xn--772h.; 룱𰍨.𝨖.; [V5]; xn--ct2b0738h.xn--772h.; ; ; # 룱𰍨.𝨖.
+xn--0ugb3358ili2v.xn--772h.; 룱\u200D𰍨\u200C.𝨖.; [C1, C2, V5]; xn--0ugb3358ili2v.xn--772h.; ; ; # 룱𰍨.𝨖.
+xn--ct2b0738h.xn--y86cl899a; 룱𰍨.𝨖︒; [V5, V6]; xn--ct2b0738h.xn--y86cl899a; ; ; # 룱𰍨.𝨖︒
+xn--0ugb3358ili2v.xn--y86cl899a; 룱\u200D𰍨\u200C.𝨖︒; [C1, C2, V5, V6]; xn--0ugb3358ili2v.xn--y86cl899a; ; ; # 룱𰍨.𝨖︒
+🄄.\u1CDC⒈ß; 🄄.\u1CDC⒈ß; [V5, V6]; xn--x07h.xn--zca344lmif; ; xn--x07h.xn--ss-k1r094b; # 🄄.᳜⒈ß
+3,.\u1CDC1.ß; ; [V5, V6]; 3,.xn--1-43l.xn--zca; ; 3,.xn--1-43l.ss; # 3,.᳜1.ß
+3,.\u1CDC1.SS; 3,.\u1CDC1.ss; [V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.\u1CDC1.ss; ; [V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.\u1CDC1.Ss; 3,.\u1CDC1.ss; [V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.xn--1-43l.ss; 3,.\u1CDC1.ss; [V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.xn--1-43l.xn--zca; 3,.\u1CDC1.ß; [V5, V6]; 3,.xn--1-43l.xn--zca; ; ; # 3,.᳜1.ß
+🄄.\u1CDC⒈SS; 🄄.\u1CDC⒈ss; [V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+🄄.\u1CDC⒈ss; 🄄.\u1CDC⒈ss; [V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+🄄.\u1CDC⒈Ss; 🄄.\u1CDC⒈ss; [V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+xn--x07h.xn--ss-k1r094b; 🄄.\u1CDC⒈ss; [V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+xn--x07h.xn--zca344lmif; 🄄.\u1CDC⒈ß; [V5, V6]; xn--x07h.xn--zca344lmif; ; ; # 🄄.᳜⒈ß
+񇌍\u2D7F。𞼓򡄨𑐺; 񇌍\u2D7F.𞼓򡄨𑐺; [B2, B3, V6]; xn--eoj16016a.xn--0v1d3848a3lr0d; ; ; # ⵿.𑐺
+񇌍\u2D7F。𞼓򡄨𑐺; 񇌍\u2D7F.𞼓򡄨𑐺; [B2, B3, V6]; xn--eoj16016a.xn--0v1d3848a3lr0d; ; ; # ⵿.𑐺
+xn--eoj16016a.xn--0v1d3848a3lr0d; 񇌍\u2D7F.𞼓򡄨𑐺; [B2, B3, V6]; xn--eoj16016a.xn--0v1d3848a3lr0d; ; ; # ⵿.𑐺
+\u1DFD\u103A\u094D.≠\u200D㇛; \u103A\u094D\u1DFD.≠\u200D㇛; [C2, V5]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [V5] # ်्᷽.≠㇛
+\u103A\u094D\u1DFD.≠\u200D㇛; \u103A\u094D\u1DFD.≠\u200D㇛; [C2, V5]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [V5] # ်्᷽.≠㇛
+\u103A\u094D\u1DFD.=\u0338\u200D㇛; \u103A\u094D\u1DFD.≠\u200D㇛; [C2, V5]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [V5] # ်्᷽.≠㇛
+\u103A\u094D\u1DFD.≠\u200D㇛; ; [C2, V5]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [V5] # ်्᷽.≠㇛
+\u103A\u094D\u1DFD.=\u0338\u200D㇛; \u103A\u094D\u1DFD.≠\u200D㇛; [C2, V5]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [V5] # ်्᷽.≠㇛
+xn--n3b956a9zm.xn--1ch912d; \u103A\u094D\u1DFD.≠㇛; [V5]; xn--n3b956a9zm.xn--1ch912d; ; ; # ်्᷽.≠㇛
+xn--n3b956a9zm.xn--1ug63gz5w; \u103A\u094D\u1DFD.≠\u200D㇛; [C2, V5]; xn--n3b956a9zm.xn--1ug63gz5w; ; ; # ်्᷽.≠㇛
+Ⴁ𐋨娤.\u200D\u033C\u0662𑖿; ; [B1, C2, V6]; xn--8md2578ag21g.xn--9ta62ngt6aou8t; ; xn--8md2578ag21g.xn--9ta62nrv36a; [B1, V5, V6] # Ⴁ𐋨娤.̼٢𑖿
+ⴁ𐋨娤.\u200D\u033C\u0662𑖿; ; [B1, C2]; xn--skjw75lg29h.xn--9ta62ngt6aou8t; ; xn--skjw75lg29h.xn--9ta62nrv36a; [B1, V5] # ⴁ𐋨娤.̼٢𑖿
+xn--skjw75lg29h.xn--9ta62nrv36a; ⴁ𐋨娤.\u033C\u0662𑖿; [B1, V5]; xn--skjw75lg29h.xn--9ta62nrv36a; ; ; # ⴁ𐋨娤.̼٢𑖿
+xn--skjw75lg29h.xn--9ta62ngt6aou8t; ⴁ𐋨娤.\u200D\u033C\u0662𑖿; [B1, C2]; xn--skjw75lg29h.xn--9ta62ngt6aou8t; ; ; # ⴁ𐋨娤.̼٢𑖿
+xn--8md2578ag21g.xn--9ta62nrv36a; Ⴁ𐋨娤.\u033C\u0662𑖿; [B1, V5, V6]; xn--8md2578ag21g.xn--9ta62nrv36a; ; ; # Ⴁ𐋨娤.̼٢𑖿
+xn--8md2578ag21g.xn--9ta62ngt6aou8t; Ⴁ𐋨娤.\u200D\u033C\u0662𑖿; [B1, C2, V6]; xn--8md2578ag21g.xn--9ta62ngt6aou8t; ; ; # Ⴁ𐋨娤.̼٢𑖿
+🄀Ⴄ\u0669\u0820。⒈\u0FB6ß; 🄀Ⴄ\u0669\u0820.⒈\u0FB6ß; [B1, V6]; xn--iib29f26o6n43c.xn--zca117e3vp; ; xn--iib29f26o6n43c.xn--ss-1sj588o; # 🄀Ⴄ٩ࠠ.⒈ྶß
+0.Ⴄ\u0669\u0820。1.\u0FB6ß; 0.Ⴄ\u0669\u0820.1.\u0FB6ß; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--zca117e; ; 0.xn--iib29f26o.1.xn--ss-1sj; # 0.Ⴄ٩ࠠ.1.ྶß
+0.ⴄ\u0669\u0820。1.\u0FB6ß; 0.ⴄ\u0669\u0820.1.\u0FB6ß; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--zca117e; ; 0.xn--iib29fp25e.1.xn--ss-1sj; # 0.ⴄ٩ࠠ.1.ྶß
+0.Ⴄ\u0669\u0820。1.\u0FB6SS; 0.Ⴄ\u0669\u0820.1.\u0FB6ss; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--ss-1sj; ; ; # 0.Ⴄ٩ࠠ.1.ྶss
+0.ⴄ\u0669\u0820。1.\u0FB6ss; 0.ⴄ\u0669\u0820.1.\u0FB6ss; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--ss-1sj; ; ; # 0.ⴄ٩ࠠ.1.ྶss
+0.Ⴄ\u0669\u0820。1.\u0FB6Ss; 0.Ⴄ\u0669\u0820.1.\u0FB6ss; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--ss-1sj; ; ; # 0.Ⴄ٩ࠠ.1.ྶss
+0.xn--iib29f26o.1.xn--ss-1sj; 0.Ⴄ\u0669\u0820.1.\u0FB6ss; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--ss-1sj; ; ; # 0.Ⴄ٩ࠠ.1.ྶss
+0.xn--iib29fp25e.1.xn--ss-1sj; 0.ⴄ\u0669\u0820.1.\u0FB6ss; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--ss-1sj; ; ; # 0.ⴄ٩ࠠ.1.ྶss
+0.xn--iib29fp25e.1.xn--zca117e; 0.ⴄ\u0669\u0820.1.\u0FB6ß; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--zca117e; ; ; # 0.ⴄ٩ࠠ.1.ྶß
+0.xn--iib29f26o.1.xn--zca117e; 0.Ⴄ\u0669\u0820.1.\u0FB6ß; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--zca117e; ; ; # 0.Ⴄ٩ࠠ.1.ྶß
+🄀ⴄ\u0669\u0820。⒈\u0FB6ß; 🄀ⴄ\u0669\u0820.⒈\u0FB6ß; [B1, V6]; xn--iib29fp25e0219a.xn--zca117e3vp; ; xn--iib29fp25e0219a.xn--ss-1sj588o; # 🄀ⴄ٩ࠠ.⒈ྶß
+🄀Ⴄ\u0669\u0820。⒈\u0FB6SS; 🄀Ⴄ\u0669\u0820.⒈\u0FB6ss; [B1, V6]; xn--iib29f26o6n43c.xn--ss-1sj588o; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶss
+🄀ⴄ\u0669\u0820。⒈\u0FB6ss; 🄀ⴄ\u0669\u0820.⒈\u0FB6ss; [B1, V6]; xn--iib29fp25e0219a.xn--ss-1sj588o; ; ; # 🄀ⴄ٩ࠠ.⒈ྶss
+🄀Ⴄ\u0669\u0820。⒈\u0FB6Ss; 🄀Ⴄ\u0669\u0820.⒈\u0FB6ss; [B1, V6]; xn--iib29f26o6n43c.xn--ss-1sj588o; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶss
+xn--iib29f26o6n43c.xn--ss-1sj588o; 🄀Ⴄ\u0669\u0820.⒈\u0FB6ss; [B1, V6]; xn--iib29f26o6n43c.xn--ss-1sj588o; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶss
+xn--iib29fp25e0219a.xn--ss-1sj588o; 🄀ⴄ\u0669\u0820.⒈\u0FB6ss; [B1, V6]; xn--iib29fp25e0219a.xn--ss-1sj588o; ; ; # 🄀ⴄ٩ࠠ.⒈ྶss
+xn--iib29fp25e0219a.xn--zca117e3vp; 🄀ⴄ\u0669\u0820.⒈\u0FB6ß; [B1, V6]; xn--iib29fp25e0219a.xn--zca117e3vp; ; ; # 🄀ⴄ٩ࠠ.⒈ྶß
+xn--iib29f26o6n43c.xn--zca117e3vp; 🄀Ⴄ\u0669\u0820.⒈\u0FB6ß; [B1, V6]; xn--iib29f26o6n43c.xn--zca117e3vp; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶß
+≠.\u200C-\u066B; ; [B1, C1]; xn--1ch.xn----vqc597q; ; xn--1ch.xn----vqc; [B1, V3] # ≠.-٫
+=\u0338.\u200C-\u066B; ≠.\u200C-\u066B; [B1, C1]; xn--1ch.xn----vqc597q; ; xn--1ch.xn----vqc; [B1, V3] # ≠.-٫
+xn--1ch.xn----vqc; ≠.-\u066B; [B1, V3]; xn--1ch.xn----vqc; ; ; # ≠.-٫
+xn--1ch.xn----vqc597q; ≠.\u200C-\u066B; [B1, C1]; xn--1ch.xn----vqc597q; ; ; # ≠.-٫
+\u0660۱。󠳶𞠁\u0665; \u0660۱.󠳶𞠁\u0665; [B1, V6]; xn--8hb40a.xn--eib7967vner3e; ; ; # ٠۱.𞠁٥
+\u0660۱。󠳶𞠁\u0665; \u0660۱.󠳶𞠁\u0665; [B1, V6]; xn--8hb40a.xn--eib7967vner3e; ; ; # ٠۱.𞠁٥
+xn--8hb40a.xn--eib7967vner3e; \u0660۱.󠳶𞠁\u0665; [B1, V6]; xn--8hb40a.xn--eib7967vner3e; ; ; # ٠۱.𞠁٥
+\u200C\u0663⒖。󱅉𽷛\u1BF3; \u200C\u0663⒖.󱅉𽷛\u1BF3; [B1, C1, V6]; xn--cib152kwgd.xn--1zf13512buy41d; ; xn--cib675m.xn--1zf13512buy41d; [B1, V6] # ٣⒖.᯳
+\u200C\u066315.。󱅉𽷛\u1BF3; \u200C\u066315..󱅉𽷛\u1BF3; [B1, C1, V6, X4_2]; xn--15-gyd983x..xn--1zf13512buy41d; [B1, C1, V6, A4_2]; xn--15-gyd..xn--1zf13512buy41d; [B1, V6, A4_2] # ٣15..᯳
+xn--15-gyd..xn--1zf13512buy41d; \u066315..󱅉𽷛\u1BF3; [B1, V6, X4_2]; xn--15-gyd..xn--1zf13512buy41d; [B1, V6, A4_2]; ; # ٣15..᯳
+xn--15-gyd983x..xn--1zf13512buy41d; \u200C\u066315..󱅉𽷛\u1BF3; [B1, C1, V6, X4_2]; xn--15-gyd983x..xn--1zf13512buy41d; [B1, C1, V6, A4_2]; ; # ٣15..᯳
+xn--cib675m.xn--1zf13512buy41d; \u0663⒖.󱅉𽷛\u1BF3; [B1, V6]; xn--cib675m.xn--1zf13512buy41d; ; ; # ٣⒖.᯳
+xn--cib152kwgd.xn--1zf13512buy41d; \u200C\u0663⒖.󱅉𽷛\u1BF3; [B1, C1, V6]; xn--cib152kwgd.xn--1zf13512buy41d; ; ; # ٣⒖.᯳
+\u1BF3.-逋񳦭󙙮; ; [V3, V5, V6]; xn--1zf.xn----483d46987byr50b; ; ; # ᯳.-逋
+xn--1zf.xn----483d46987byr50b; \u1BF3.-逋񳦭󙙮; [V3, V5, V6]; xn--1zf.xn----483d46987byr50b; ; ; # ᯳.-逋
+\u0756。\u3164\u200Dς; \u0756.\u3164\u200Dς; [C2, V6]; xn--9ob.xn--3xa995lq2l; ; xn--9ob.xn--4xa574u; [V6] # ݖ.ς
+\u0756。\u1160\u200Dς; \u0756.\u1160\u200Dς; [C2, V6]; xn--9ob.xn--3xa580ebol; ; xn--9ob.xn--4xa380e; [V6] # ݖ.ς
+\u0756。\u1160\u200DΣ; \u0756.\u1160\u200Dσ; [C2, V6]; xn--9ob.xn--4xa380ebol; ; xn--9ob.xn--4xa380e; [V6] # ݖ.σ
+\u0756。\u1160\u200Dσ; \u0756.\u1160\u200Dσ; [C2, V6]; xn--9ob.xn--4xa380ebol; ; xn--9ob.xn--4xa380e; [V6] # ݖ.σ
+xn--9ob.xn--4xa380e; \u0756.\u1160σ; [V6]; xn--9ob.xn--4xa380e; ; ; # ݖ.σ
+xn--9ob.xn--4xa380ebol; \u0756.\u1160\u200Dσ; [C2, V6]; xn--9ob.xn--4xa380ebol; ; ; # ݖ.σ
+xn--9ob.xn--3xa580ebol; \u0756.\u1160\u200Dς; [C2, V6]; xn--9ob.xn--3xa580ebol; ; ; # ݖ.ς
+\u0756。\u3164\u200DΣ; \u0756.\u3164\u200Dσ; [C2, V6]; xn--9ob.xn--4xa795lq2l; ; xn--9ob.xn--4xa574u; [V6] # ݖ.σ
+\u0756。\u3164\u200Dσ; \u0756.\u3164\u200Dσ; [C2, V6]; xn--9ob.xn--4xa795lq2l; ; xn--9ob.xn--4xa574u; [V6] # ݖ.σ
+xn--9ob.xn--4xa574u; \u0756.\u3164σ; [V6]; xn--9ob.xn--4xa574u; ; ; # ݖ.σ
+xn--9ob.xn--4xa795lq2l; \u0756.\u3164\u200Dσ; [C2, V6]; xn--9ob.xn--4xa795lq2l; ; ; # ݖ.σ
+xn--9ob.xn--3xa995lq2l; \u0756.\u3164\u200Dς; [C2, V6]; xn--9ob.xn--3xa995lq2l; ; ; # ݖ.ς
+ᡆႣ。󞢧\u0315\u200D\u200D; ᡆႣ.󞢧\u0315\u200D\u200D; [C2, V6]; xn--bnd320b.xn--5sa649la993427a; ; xn--bnd320b.xn--5sa98523p; [V6] # ᡆႣ.̕
+ᡆႣ。󞢧\u0315\u200D\u200D; ᡆႣ.󞢧\u0315\u200D\u200D; [C2, V6]; xn--bnd320b.xn--5sa649la993427a; ; xn--bnd320b.xn--5sa98523p; [V6] # ᡆႣ.̕
+ᡆⴃ。󞢧\u0315\u200D\u200D; ᡆⴃ.󞢧\u0315\u200D\u200D; [C2, V6]; xn--57e237h.xn--5sa649la993427a; ; xn--57e237h.xn--5sa98523p; [V6] # ᡆⴃ.̕
+xn--57e237h.xn--5sa98523p; ᡆⴃ.󞢧\u0315; [V6]; xn--57e237h.xn--5sa98523p; ; ; # ᡆⴃ.̕
+xn--57e237h.xn--5sa649la993427a; ᡆⴃ.󞢧\u0315\u200D\u200D; [C2, V6]; xn--57e237h.xn--5sa649la993427a; ; ; # ᡆⴃ.̕
+xn--bnd320b.xn--5sa98523p; ᡆႣ.󞢧\u0315; [V6]; xn--bnd320b.xn--5sa98523p; ; ; # ᡆႣ.̕
+xn--bnd320b.xn--5sa649la993427a; ᡆႣ.󞢧\u0315\u200D\u200D; [C2, V6]; xn--bnd320b.xn--5sa649la993427a; ; ; # ᡆႣ.̕
+ᡆⴃ。󞢧\u0315\u200D\u200D; ᡆⴃ.󞢧\u0315\u200D\u200D; [C2, V6]; xn--57e237h.xn--5sa649la993427a; ; xn--57e237h.xn--5sa98523p; [V6] # ᡆⴃ.̕
+㭄\u200D\u084F𑚵.ς𐮮\u200C\u200D; 㭄\u200D\u084F𑚵.ς𐮮\u200C\u200D; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--3xa895lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.ς𐮮
+㭄\u200D\u084F𑚵.ς𐮮\u200C\u200D; ; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--3xa895lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.ς𐮮
+㭄\u200D\u084F𑚵.Σ𐮮\u200C\u200D; 㭄\u200D\u084F𑚵.σ𐮮\u200C\u200D; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+㭄\u200D\u084F𑚵.σ𐮮\u200C\u200D; ; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+xn--ewb302xhu1l.xn--4xa0426k; 㭄\u084F𑚵.σ𐮮; [B5, B6]; xn--ewb302xhu1l.xn--4xa0426k; ; ; # 㭄ࡏ𑚵.σ𐮮
+xn--ewb962jfitku4r.xn--4xa695lda6932v; 㭄\u200D\u084F𑚵.σ𐮮\u200C\u200D; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; ; # 㭄ࡏ𑚵.σ𐮮
+xn--ewb962jfitku4r.xn--3xa895lda6932v; 㭄\u200D\u084F𑚵.ς𐮮\u200C\u200D; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--3xa895lda6932v; ; ; # 㭄ࡏ𑚵.ς𐮮
+㭄\u200D\u084F𑚵.Σ𐮮\u200C\u200D; 㭄\u200D\u084F𑚵.σ𐮮\u200C\u200D; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+㭄\u200D\u084F𑚵.σ𐮮\u200C\u200D; 㭄\u200D\u084F𑚵.σ𐮮\u200C\u200D; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+\u17B5。𞯸ꡀ🄋; \u17B5.𞯸ꡀ🄋; [B1, B2, B3, V5, V6]; xn--03e.xn--8b9ar252dngd; ; ; # .ꡀ🄋
+xn--03e.xn--8b9ar252dngd; \u17B5.𞯸ꡀ🄋; [B1, B2, B3, V5, V6]; xn--03e.xn--8b9ar252dngd; ; ; # .ꡀ🄋
+󐪺暑.⾑\u0668; 󐪺暑.襾\u0668; [B5, B6, V6]; xn--tlvq3513e.xn--hib9228d; ; ; # 暑.襾٨
+󐪺暑.襾\u0668; ; [B5, B6, V6]; xn--tlvq3513e.xn--hib9228d; ; ; # 暑.襾٨
+xn--tlvq3513e.xn--hib9228d; 󐪺暑.襾\u0668; [B5, B6, V6]; xn--tlvq3513e.xn--hib9228d; ; ; # 暑.襾٨
+󠄚≯ꡢ。\u0891\u1DFF; ≯ꡢ.\u0891\u1DFF; [B1, V6]; xn--hdh7783c.xn--9xb680i; ; ; # ≯ꡢ.᷿
+󠄚>\u0338ꡢ。\u0891\u1DFF; ≯ꡢ.\u0891\u1DFF; [B1, V6]; xn--hdh7783c.xn--9xb680i; ; ; # ≯ꡢ.᷿
+xn--hdh7783c.xn--9xb680i; ≯ꡢ.\u0891\u1DFF; [B1, V6]; xn--hdh7783c.xn--9xb680i; ; ; # ≯ꡢ.᷿
+\uFDC3𮁱\u0B4D𐨿.󐧤Ⴗ; \u0643\u0645\u0645𮁱\u0B4D𐨿.󐧤Ⴗ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--vnd55511o; ; ; # كمم𮁱୍𐨿.Ⴗ
+\u0643\u0645\u0645𮁱\u0B4D𐨿.󐧤Ⴗ; ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--vnd55511o; ; ; # كمم𮁱୍𐨿.Ⴗ
+\u0643\u0645\u0645𮁱\u0B4D𐨿.󐧤ⴗ; ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--fljz2846h; ; ; # كمم𮁱୍𐨿.ⴗ
+xn--fhbea662czx68a2tju.xn--fljz2846h; \u0643\u0645\u0645𮁱\u0B4D𐨿.󐧤ⴗ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--fljz2846h; ; ; # كمم𮁱୍𐨿.ⴗ
+xn--fhbea662czx68a2tju.xn--vnd55511o; \u0643\u0645\u0645𮁱\u0B4D𐨿.󐧤Ⴗ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--vnd55511o; ; ; # كمم𮁱୍𐨿.Ⴗ
+\uFDC3𮁱\u0B4D𐨿.󐧤ⴗ; \u0643\u0645\u0645𮁱\u0B4D𐨿.󐧤ⴗ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--fljz2846h; ; ; # كمم𮁱୍𐨿.ⴗ
+𞀨。\u1B44򡛨𞎇; 𞀨.\u1B44򡛨𞎇; [V5, V6]; xn--mi4h.xn--1uf6843smg20c; ; ; # 𞀨.᭄
+𞀨。\u1B44򡛨𞎇; 𞀨.\u1B44򡛨𞎇; [V5, V6]; xn--mi4h.xn--1uf6843smg20c; ; ; # 𞀨.᭄
+xn--mi4h.xn--1uf6843smg20c; 𞀨.\u1B44򡛨𞎇; [V5, V6]; xn--mi4h.xn--1uf6843smg20c; ; ; # 𞀨.᭄
+󠣼\u200C.𐺰\u200Cᡟ; 󠣼\u200C.𐺰\u200Cᡟ; [B1, B2, B3, C1, V6]; xn--0ug18531l.xn--v8e340bp21t; ; xn--q046e.xn--v8e7227j; [B1, B2, B3, V6] # .𐺰ᡟ
+󠣼\u200C.𐺰\u200Cᡟ; ; [B1, B2, B3, C1, V6]; xn--0ug18531l.xn--v8e340bp21t; ; xn--q046e.xn--v8e7227j; [B1, B2, B3, V6] # .𐺰ᡟ
+xn--q046e.xn--v8e7227j; 󠣼.𐺰ᡟ; [B1, B2, B3, V6]; xn--q046e.xn--v8e7227j; ; ; # .𐺰ᡟ
+xn--0ug18531l.xn--v8e340bp21t; 󠣼\u200C.𐺰\u200Cᡟ; [B1, B2, B3, C1, V6]; xn--0ug18531l.xn--v8e340bp21t; ; ; # .𐺰ᡟ
+ᢛ󨅟ß.ጧ; ; [V6]; xn--zca562jc642x.xn--p5d; ; xn--ss-7dp66033t.xn--p5d; # ᢛß.ጧ
+ᢛ󨅟SS.ጧ; ᢛ󨅟ss.ጧ; [V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+ᢛ󨅟ss.ጧ; ; [V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+ᢛ󨅟Ss.ጧ; ᢛ󨅟ss.ጧ; [V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+xn--ss-7dp66033t.xn--p5d; ᢛ󨅟ss.ጧ; [V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+xn--zca562jc642x.xn--p5d; ᢛ󨅟ß.ጧ; [V6]; xn--zca562jc642x.xn--p5d; ; ; # ᢛß.ጧ
+⮒\u200C.񒚗\u200C; ; [C1, V6]; xn--0ugx66b.xn--0ugz2871c; ; xn--b9i.xn--5p9y; [V6] # ⮒.
+xn--b9i.xn--5p9y; ⮒.񒚗; [V6]; xn--b9i.xn--5p9y; ; ; # ⮒.
+xn--0ugx66b.xn--0ugz2871c; ⮒\u200C.񒚗\u200C; [C1, V6]; xn--0ugx66b.xn--0ugz2871c; ; ; # ⮒.
+𞤂񹞁𐹯。Ⴜ; 𞤤񹞁𐹯.Ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--0nd; ; ; # 𞤤𐹯.Ⴜ
+𞤤񹞁𐹯。ⴜ; 𞤤񹞁𐹯.ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--klj; ; ; # 𞤤𐹯.ⴜ
+xn--no0dr648a51o3b.xn--klj; 𞤤񹞁𐹯.ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--klj; ; ; # 𞤤𐹯.ⴜ
+xn--no0dr648a51o3b.xn--0nd; 𞤤񹞁𐹯.Ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--0nd; ; ; # 𞤤𐹯.Ⴜ
+𞤂񹞁𐹯。ⴜ; 𞤤񹞁𐹯.ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--klj; ; ; # 𞤤𐹯.ⴜ
+𐹵⮣\u200C𑄰。񷴿\uFCB7; 𐹵⮣\u200C𑄰.񷴿\u0636\u0645; [B1, B5, B6, C1, V6]; xn--0ug586bcj8p7jc.xn--1gb4a66004i; ; xn--s9i5458e7yb.xn--1gb4a66004i; [B1, B5, B6, V6] # 𐹵⮣𑄰.ضم
+𐹵⮣\u200C𑄰。񷴿\u0636\u0645; 𐹵⮣\u200C𑄰.񷴿\u0636\u0645; [B1, B5, B6, C1, V6]; xn--0ug586bcj8p7jc.xn--1gb4a66004i; ; xn--s9i5458e7yb.xn--1gb4a66004i; [B1, B5, B6, V6] # 𐹵⮣𑄰.ضم
+xn--s9i5458e7yb.xn--1gb4a66004i; 𐹵⮣𑄰.񷴿\u0636\u0645; [B1, B5, B6, V6]; xn--s9i5458e7yb.xn--1gb4a66004i; ; ; # 𐹵⮣𑄰.ضم
+xn--0ug586bcj8p7jc.xn--1gb4a66004i; 𐹵⮣\u200C𑄰.񷴿\u0636\u0645; [B1, B5, B6, C1, V6]; xn--0ug586bcj8p7jc.xn--1gb4a66004i; ; ; # 𐹵⮣𑄰.ضم
+Ⴒ。デß𞤵\u0C4D; Ⴒ.デß𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--zca669cmr3a0f28a; ; xn--qnd.xn--ss-9nh3648ahh20b; # Ⴒ.デß𞤵్
+Ⴒ。テ\u3099ß𞤵\u0C4D; Ⴒ.デß𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--zca669cmr3a0f28a; ; xn--qnd.xn--ss-9nh3648ahh20b; # Ⴒ.デß𞤵్
+ⴒ。テ\u3099ß𞤵\u0C4D; ⴒ.デß𞤵\u0C4D; [B5, B6]; xn--9kj.xn--zca669cmr3a0f28a; ; xn--9kj.xn--ss-9nh3648ahh20b; # ⴒ.デß𞤵్
+ⴒ。デß𞤵\u0C4D; ⴒ.デß𞤵\u0C4D; [B5, B6]; xn--9kj.xn--zca669cmr3a0f28a; ; xn--9kj.xn--ss-9nh3648ahh20b; # ⴒ.デß𞤵్
+Ⴒ。デSS𞤓\u0C4D; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+Ⴒ。テ\u3099SS𞤓\u0C4D; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+ⴒ。テ\u3099ss𞤵\u0C4D; ⴒ.デss𞤵\u0C4D; [B5, B6]; xn--9kj.xn--ss-9nh3648ahh20b; ; ; # ⴒ.デss𞤵్
+ⴒ。デss𞤵\u0C4D; ⴒ.デss𞤵\u0C4D; [B5, B6]; xn--9kj.xn--ss-9nh3648ahh20b; ; ; # ⴒ.デss𞤵్
+Ⴒ。デSs𞤵\u0C4D; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+Ⴒ。テ\u3099Ss𞤵\u0C4D; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+xn--qnd.xn--ss-9nh3648ahh20b; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+xn--9kj.xn--ss-9nh3648ahh20b; ⴒ.デss𞤵\u0C4D; [B5, B6]; xn--9kj.xn--ss-9nh3648ahh20b; ; ; # ⴒ.デss𞤵్
+xn--9kj.xn--zca669cmr3a0f28a; ⴒ.デß𞤵\u0C4D; [B5, B6]; xn--9kj.xn--zca669cmr3a0f28a; ; ; # ⴒ.デß𞤵్
+xn--qnd.xn--zca669cmr3a0f28a; Ⴒ.デß𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--zca669cmr3a0f28a; ; ; # Ⴒ.デß𞤵్
+Ⴒ。デSS𞤵\u0C4D; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+Ⴒ。テ\u3099SS𞤵\u0C4D; Ⴒ.デss𞤵\u0C4D; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+𑁿\u0D4D.7-\u07D2; 𑁿\u0D4D.7-\u07D2; [B1, V5]; xn--wxc1283k.xn--7--yue; ; ; # 𑁿്.7-ߒ
+𑁿\u0D4D.7-\u07D2; ; [B1, V5]; xn--wxc1283k.xn--7--yue; ; ; # 𑁿്.7-ߒ
+xn--wxc1283k.xn--7--yue; 𑁿\u0D4D.7-\u07D2; [B1, V5]; xn--wxc1283k.xn--7--yue; ; ; # 𑁿്.7-ߒ
+≯𑜫󠭇.\u1734񒞤𑍬ᢧ; ; [V5, V6]; xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ; ; # ≯𑜫.᜴𑍬ᢧ
+>\u0338𑜫󠭇.\u1734񒞤𑍬ᢧ; ≯𑜫󠭇.\u1734񒞤𑍬ᢧ; [V5, V6]; xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ; ; # ≯𑜫.᜴𑍬ᢧ
+xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ≯𑜫󠭇.\u1734񒞤𑍬ᢧ; [V5, V6]; xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ; ; # ≯𑜫.᜴𑍬ᢧ
+\u1DDB򎐙Ⴗ쏔。\u0781; \u1DDB򎐙Ⴗ쏔.\u0781; [B1, V5, V6]; xn--vnd148d733ky6n9e.xn--iqb; ; ; # ᷛႷ쏔.ށ
+\u1DDB򎐙Ⴗ쏔。\u0781; \u1DDB򎐙Ⴗ쏔.\u0781; [B1, V5, V6]; xn--vnd148d733ky6n9e.xn--iqb; ; ; # ᷛႷ쏔.ށ
+\u1DDB򎐙ⴗ쏔。\u0781; \u1DDB򎐙ⴗ쏔.\u0781; [B1, V5, V6]; xn--zegy26dw47iy6w2f.xn--iqb; ; ; # ᷛⴗ쏔.ށ
+\u1DDB򎐙ⴗ쏔。\u0781; \u1DDB򎐙ⴗ쏔.\u0781; [B1, V5, V6]; xn--zegy26dw47iy6w2f.xn--iqb; ; ; # ᷛⴗ쏔.ށ
+xn--zegy26dw47iy6w2f.xn--iqb; \u1DDB򎐙ⴗ쏔.\u0781; [B1, V5, V6]; xn--zegy26dw47iy6w2f.xn--iqb; ; ; # ᷛⴗ쏔.ށ
+xn--vnd148d733ky6n9e.xn--iqb; \u1DDB򎐙Ⴗ쏔.\u0781; [B1, V5, V6]; xn--vnd148d733ky6n9e.xn--iqb; ; ; # ᷛႷ쏔.ށ
+ß。𐋳Ⴌ\u0FB8; ß.𐋳Ⴌ\u0FB8; [V6]; xn--zca.xn--lgd10cu829c; ; ss.xn--lgd10cu829c; # ß.𐋳Ⴌྸ
+ß。𐋳Ⴌ\u0FB8; ß.𐋳Ⴌ\u0FB8; [V6]; xn--zca.xn--lgd10cu829c; ; ss.xn--lgd10cu829c; # ß.𐋳Ⴌྸ
+ß。𐋳ⴌ\u0FB8; ß.𐋳ⴌ\u0FB8; ; xn--zca.xn--lgd921mvv0m; ; ss.xn--lgd921mvv0m; # ß.𐋳ⴌྸ
+SS。𐋳Ⴌ\u0FB8; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss。𐋳ⴌ\u0FB8; ss.𐋳ⴌ\u0FB8; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+Ss。𐋳Ⴌ\u0FB8; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss.xn--lgd10cu829c; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss.xn--lgd921mvv0m; ss.𐋳ⴌ\u0FB8; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+ss.𐋳ⴌ\u0FB8; ; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+SS.𐋳Ⴌ\u0FB8; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+Ss.𐋳Ⴌ\u0FB8; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+xn--zca.xn--lgd921mvv0m; ß.𐋳ⴌ\u0FB8; ; xn--zca.xn--lgd921mvv0m; ; ; # ß.𐋳ⴌྸ
+ß.𐋳ⴌ\u0FB8; ; ; xn--zca.xn--lgd921mvv0m; ; ss.xn--lgd921mvv0m; # ß.𐋳ⴌྸ
+xn--zca.xn--lgd10cu829c; ß.𐋳Ⴌ\u0FB8; [V6]; xn--zca.xn--lgd10cu829c; ; ; # ß.𐋳Ⴌྸ
+ß。𐋳ⴌ\u0FB8; ß.𐋳ⴌ\u0FB8; ; xn--zca.xn--lgd921mvv0m; ; ss.xn--lgd921mvv0m; # ß.𐋳ⴌྸ
+SS。𐋳Ⴌ\u0FB8; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss。𐋳ⴌ\u0FB8; ss.𐋳ⴌ\u0FB8; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+Ss。𐋳Ⴌ\u0FB8; ss.𐋳Ⴌ\u0FB8; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+-\u069E𐶡.\u200C⾝\u09CD; -\u069E𐶡.\u200C身\u09CD; [B1, C1, V3, V6]; xn----stc7013r.xn--b7b305imj2f; ; xn----stc7013r.xn--b7b1419d; [B1, V3, V6] # -ڞ.身্
+-\u069E𐶡.\u200C身\u09CD; ; [B1, C1, V3, V6]; xn----stc7013r.xn--b7b305imj2f; ; xn----stc7013r.xn--b7b1419d; [B1, V3, V6] # -ڞ.身্
+xn----stc7013r.xn--b7b1419d; -\u069E𐶡.身\u09CD; [B1, V3, V6]; xn----stc7013r.xn--b7b1419d; ; ; # -ڞ.身্
+xn----stc7013r.xn--b7b305imj2f; -\u069E𐶡.\u200C身\u09CD; [B1, C1, V3, V6]; xn----stc7013r.xn--b7b305imj2f; ; ; # -ڞ.身্
+😮\u0764𑈵𞀖.💅\u200D; 😮\u0764𑈵𞀖.💅\u200D; [B1, C2]; xn--opb4277kuc7elqsa.xn--1ug5265p; ; xn--opb4277kuc7elqsa.xn--kr8h; [B1] # 😮ݤ𑈵𞀖.💅
+😮\u0764𑈵𞀖.💅\u200D; ; [B1, C2]; xn--opb4277kuc7elqsa.xn--1ug5265p; ; xn--opb4277kuc7elqsa.xn--kr8h; [B1] # 😮ݤ𑈵𞀖.💅
+xn--opb4277kuc7elqsa.xn--kr8h; 😮\u0764𑈵𞀖.💅; [B1]; xn--opb4277kuc7elqsa.xn--kr8h; ; ; # 😮ݤ𑈵𞀖.💅
+xn--opb4277kuc7elqsa.xn--1ug5265p; 😮\u0764𑈵𞀖.💅\u200D; [B1, C2]; xn--opb4277kuc7elqsa.xn--1ug5265p; ; ; # 😮ݤ𑈵𞀖.💅
+\u08F2\u200D꙳\u0712.ᢏ\u200C󠍄; ; [B1, B6, C1, C2, V5, V6]; xn--cnb37g904be26j.xn--89e849ax9363a; ; xn--cnb37gdy00a.xn--89e02253p; [B1, B6, V5, V6] # ࣲ꙳ܒ.ᢏ
+xn--cnb37gdy00a.xn--89e02253p; \u08F2꙳\u0712.ᢏ󠍄; [B1, B6, V5, V6]; xn--cnb37gdy00a.xn--89e02253p; ; ; # ࣲ꙳ܒ.ᢏ
+xn--cnb37g904be26j.xn--89e849ax9363a; \u08F2\u200D꙳\u0712.ᢏ\u200C󠍄; [B1, B6, C1, C2, V5, V6]; xn--cnb37g904be26j.xn--89e849ax9363a; ; ; # ࣲ꙳ܒ.ᢏ
+Ⴑ.\u06BF𞯓ᠲ; Ⴑ.\u06BF𞯓ᠲ; [B2, B3, V6]; xn--pnd.xn--ykb840gd555a; ; ; # Ⴑ.ڿᠲ
+Ⴑ.\u06BF𞯓ᠲ; ; [B2, B3, V6]; xn--pnd.xn--ykb840gd555a; ; ; # Ⴑ.ڿᠲ
+ⴑ.\u06BF𞯓ᠲ; ; [B2, B3, V6]; xn--8kj.xn--ykb840gd555a; ; ; # ⴑ.ڿᠲ
+xn--8kj.xn--ykb840gd555a; ⴑ.\u06BF𞯓ᠲ; [B2, B3, V6]; xn--8kj.xn--ykb840gd555a; ; ; # ⴑ.ڿᠲ
+xn--pnd.xn--ykb840gd555a; Ⴑ.\u06BF𞯓ᠲ; [B2, B3, V6]; xn--pnd.xn--ykb840gd555a; ; ; # Ⴑ.ڿᠲ
+ⴑ.\u06BF𞯓ᠲ; ⴑ.\u06BF𞯓ᠲ; [B2, B3, V6]; xn--8kj.xn--ykb840gd555a; ; ; # ⴑ.ڿᠲ
+\u1A5A𛦝\u0C4D。𚝬𝟵; \u1A5A𛦝\u0C4D.𚝬9; [V5, V6]; xn--lqc703ebm93a.xn--9-000p; ; ; # ᩚ్.9
+\u1A5A𛦝\u0C4D。𚝬9; \u1A5A𛦝\u0C4D.𚝬9; [V5, V6]; xn--lqc703ebm93a.xn--9-000p; ; ; # ᩚ్.9
+xn--lqc703ebm93a.xn--9-000p; \u1A5A𛦝\u0C4D.𚝬9; [V5, V6]; xn--lqc703ebm93a.xn--9-000p; ; ; # ᩚ్.9
+\u200C\u06A0𿺆𝟗。Ⴣ꒘\uFCD0񐘖; \u200C\u06A0𿺆9.Ⴣ꒘\u0645\u062E񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ; xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; [B2, B5, V6] # ڠ9.Ⴣ꒘مخ
+\u200C\u06A0𿺆9。Ⴣ꒘\u0645\u062E񐘖; \u200C\u06A0𿺆9.Ⴣ꒘\u0645\u062E񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ; xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; [B2, B5, V6] # ڠ9.Ⴣ꒘مخ
+\u200C\u06A0𿺆9。ⴣ꒘\u0645\u062E񐘖; \u200C\u06A0𿺆9.ⴣ꒘\u0645\u062E񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ; xn--9-vtc42319e.xn--tgb9bz87p833hw316c; [B2, B5, V6] # ڠ9.ⴣ꒘مخ
+xn--9-vtc42319e.xn--tgb9bz87p833hw316c; \u06A0𿺆9.ⴣ꒘\u0645\u062E񐘖; [B2, B5, V6]; xn--9-vtc42319e.xn--tgb9bz87p833hw316c; ; ; # ڠ9.ⴣ꒘مخ
+xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; \u200C\u06A0𿺆9.ⴣ꒘\u0645\u062E񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ; ; # ڠ9.ⴣ꒘مخ
+xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; \u06A0𿺆9.Ⴣ꒘\u0645\u062E񐘖; [B2, B5, V6]; xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; ; ; # ڠ9.Ⴣ꒘مخ
+xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; \u200C\u06A0𿺆9.Ⴣ꒘\u0645\u062E񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ; ; # ڠ9.Ⴣ꒘مخ
+\u200C\u06A0𿺆𝟗。ⴣ꒘\uFCD0񐘖; \u200C\u06A0𿺆9.ⴣ꒘\u0645\u062E񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ; xn--9-vtc42319e.xn--tgb9bz87p833hw316c; [B2, B5, V6] # ڠ9.ⴣ꒘مخ
+ᡖ。\u031F񗛨\u0B82-; ᡖ.\u031F񗛨\u0B82-; [V3, V5, V6]; xn--m8e.xn----mdb555dkk71m; ; ; # ᡖ.̟ஂ-
+ᡖ。\u031F񗛨\u0B82-; ᡖ.\u031F񗛨\u0B82-; [V3, V5, V6]; xn--m8e.xn----mdb555dkk71m; ; ; # ᡖ.̟ஂ-
+xn--m8e.xn----mdb555dkk71m; ᡖ.\u031F񗛨\u0B82-; [V3, V5, V6]; xn--m8e.xn----mdb555dkk71m; ; ; # ᡖ.̟ஂ-
+𞠠浘。絧𞀀; 𞠠浘.絧𞀀; [B2, B3]; xn--e0wp491f.xn--ud0a3573e; ; ; # 𞠠浘.絧𞀀
+xn--e0wp491f.xn--ud0a3573e; 𞠠浘.絧𞀀; [B2, B3]; xn--e0wp491f.xn--ud0a3573e; ; ; # 𞠠浘.絧𞀀
+\u0596Ⴋ.𝟳≯︒\uFE0A; \u0596Ⴋ.7≯︒; [V5, V6]; xn--hcb887c.xn--7-pgoy530h; ; ; # ֖Ⴋ.7≯︒
+\u0596Ⴋ.𝟳>\u0338︒\uFE0A; \u0596Ⴋ.7≯︒; [V5, V6]; xn--hcb887c.xn--7-pgoy530h; ; ; # ֖Ⴋ.7≯︒
+\u0596Ⴋ.7≯。\uFE0A; \u0596Ⴋ.7≯.; [V5, V6]; xn--hcb887c.xn--7-pgo.; ; ; # ֖Ⴋ.7≯.
+\u0596Ⴋ.7>\u0338。\uFE0A; \u0596Ⴋ.7≯.; [V5, V6]; xn--hcb887c.xn--7-pgo.; ; ; # ֖Ⴋ.7≯.
+\u0596ⴋ.7>\u0338。\uFE0A; \u0596ⴋ.7≯.; [V5]; xn--hcb613r.xn--7-pgo.; ; ; # ֖ⴋ.7≯.
+\u0596ⴋ.7≯。\uFE0A; \u0596ⴋ.7≯.; [V5]; xn--hcb613r.xn--7-pgo.; ; ; # ֖ⴋ.7≯.
+xn--hcb613r.xn--7-pgo.; \u0596ⴋ.7≯.; [V5]; xn--hcb613r.xn--7-pgo.; ; ; # ֖ⴋ.7≯.
+xn--hcb887c.xn--7-pgo.; \u0596Ⴋ.7≯.; [V5, V6]; xn--hcb887c.xn--7-pgo.; ; ; # ֖Ⴋ.7≯.
+\u0596ⴋ.𝟳>\u0338︒\uFE0A; \u0596ⴋ.7≯︒; [V5, V6]; xn--hcb613r.xn--7-pgoy530h; ; ; # ֖ⴋ.7≯︒
+\u0596ⴋ.𝟳≯︒\uFE0A; \u0596ⴋ.7≯︒; [V5, V6]; xn--hcb613r.xn--7-pgoy530h; ; ; # ֖ⴋ.7≯︒
+xn--hcb613r.xn--7-pgoy530h; \u0596ⴋ.7≯︒; [V5, V6]; xn--hcb613r.xn--7-pgoy530h; ; ; # ֖ⴋ.7≯︒
+xn--hcb887c.xn--7-pgoy530h; \u0596Ⴋ.7≯︒; [V5, V6]; xn--hcb887c.xn--7-pgoy530h; ; ; # ֖Ⴋ.7≯︒
+\u200DF𑓂。󠺨︒\u077E𐹢; \u200Df𑓂.󠺨︒\u077E𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--fqb1637j8hky9452a; ; xn--f-kq9i.xn--fqb1637j8hky9452a; [B1, V6] # f𑓂.︒ݾ𐹢
+\u200DF𑓂。󠺨。\u077E𐹢; \u200Df𑓂.󠺨.\u077E𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ; xn--f-kq9i.xn--7656e.xn--fqb4175k; [B1, V6] # f𑓂..ݾ𐹢
+\u200Df𑓂。󠺨。\u077E𐹢; \u200Df𑓂.󠺨.\u077E𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ; xn--f-kq9i.xn--7656e.xn--fqb4175k; [B1, V6] # f𑓂..ݾ𐹢
+xn--f-kq9i.xn--7656e.xn--fqb4175k; f𑓂.󠺨.\u077E𐹢; [B1, V6]; xn--f-kq9i.xn--7656e.xn--fqb4175k; ; ; # f𑓂..ݾ𐹢
+xn--f-tgn9761i.xn--7656e.xn--fqb4175k; \u200Df𑓂.󠺨.\u077E𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ; ; # f𑓂..ݾ𐹢
+\u200Df𑓂。󠺨︒\u077E𐹢; \u200Df𑓂.󠺨︒\u077E𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--fqb1637j8hky9452a; ; xn--f-kq9i.xn--fqb1637j8hky9452a; [B1, V6] # f𑓂.︒ݾ𐹢
+xn--f-kq9i.xn--fqb1637j8hky9452a; f𑓂.󠺨︒\u077E𐹢; [B1, V6]; xn--f-kq9i.xn--fqb1637j8hky9452a; ; ; # f𑓂.︒ݾ𐹢
+xn--f-tgn9761i.xn--fqb1637j8hky9452a; \u200Df𑓂.󠺨︒\u077E𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--fqb1637j8hky9452a; ; ; # f𑓂.︒ݾ𐹢
+\u0845🄇𐼗︒。𐹻𑜫; \u0845🄇𐼗︒.𐹻𑜫; [B1, B3, V6]; xn--3vb4696jpxkjh7s.xn--zo0di2m; ; ; # ࡅ🄇𐼗︒.𐹻𑜫
+\u08456,𐼗。。𐹻𑜫; \u08456,𐼗..𐹻𑜫; [B1, V6, X4_2]; xn--6,-r4e4420y..xn--zo0di2m; [B1, V6, A4_2]; ; # ࡅ6,𐼗..𐹻𑜫
+xn--6,-r4e4420y..xn--zo0di2m; \u08456,𐼗..𐹻𑜫; [B1, V6, X4_2]; xn--6,-r4e4420y..xn--zo0di2m; [B1, V6, A4_2]; ; # ࡅ6,𐼗..𐹻𑜫
+xn--3vb4696jpxkjh7s.xn--zo0di2m; \u0845🄇𐼗︒.𐹻𑜫; [B1, B3, V6]; xn--3vb4696jpxkjh7s.xn--zo0di2m; ; ; # ࡅ🄇𐼗︒.𐹻𑜫
+𐹈.\u1DC0𑈱𐦭; ; [B1, V5, V6]; xn--jn0d.xn--7dg0871h3lf; ; ; # .᷀𑈱𐦭
+xn--jn0d.xn--7dg0871h3lf; 𐹈.\u1DC0𑈱𐦭; [B1, V5, V6]; xn--jn0d.xn--7dg0871h3lf; ; ; # .᷀𑈱𐦭
+Ⴂ䠺。𞤃񅏎󙮦\u0693; Ⴂ䠺.𞤥񅏎󙮦\u0693; [B2, V6]; xn--9md875z.xn--pjb9818vg4xno967d; ; ; # Ⴂ䠺.𞤥ړ
+ⴂ䠺。𞤥񅏎󙮦\u0693; ⴂ䠺.𞤥񅏎󙮦\u0693; [B2, V6]; xn--tkj638f.xn--pjb9818vg4xno967d; ; ; # ⴂ䠺.𞤥ړ
+xn--tkj638f.xn--pjb9818vg4xno967d; ⴂ䠺.𞤥񅏎󙮦\u0693; [B2, V6]; xn--tkj638f.xn--pjb9818vg4xno967d; ; ; # ⴂ䠺.𞤥ړ
+xn--9md875z.xn--pjb9818vg4xno967d; Ⴂ䠺.𞤥񅏎󙮦\u0693; [B2, V6]; xn--9md875z.xn--pjb9818vg4xno967d; ; ; # Ⴂ䠺.𞤥ړ
+ⴂ䠺。𞤃񅏎󙮦\u0693; ⴂ䠺.𞤥񅏎󙮦\u0693; [B2, V6]; xn--tkj638f.xn--pjb9818vg4xno967d; ; ; # ⴂ䠺.𞤥ړ
+🄇伐︒.𜙚\uA8C4; ; [V6]; xn--woqs083bel0g.xn--0f9ao925c; ; ; # 🄇伐︒.꣄
+6,伐。.𜙚\uA8C4; 6,伐..𜙚\uA8C4; [V6, X4_2]; xn--6,-7i3c..xn--0f9ao925c; [V6, A4_2]; ; # 6,伐..꣄
+xn--6,-7i3c..xn--0f9ao925c; 6,伐..𜙚\uA8C4; [V6, X4_2]; xn--6,-7i3c..xn--0f9ao925c; [V6, A4_2]; ; # 6,伐..꣄
+xn--woqs083bel0g.xn--0f9ao925c; 🄇伐︒.𜙚\uA8C4; [V6]; xn--woqs083bel0g.xn--0f9ao925c; ; ; # 🄇伐︒.꣄
+\u200D𐹠\uABED\uFFFB。\u200D𐫓Ⴚ𑂹; \u200D𐹠\uABED\uFFFB.\u200D𐫓Ⴚ𑂹; [B1, C2, V6]; xn--1ugz126coy7bdbm.xn--ynd959evs1pv6e; ; xn--429az70n29i.xn--ynd3619jqyd; [B1, B2, B3, V6] # 𐹠꯭.𐫓Ⴚ𑂹
+\u200D𐹠\uABED\uFFFB。\u200D𐫓ⴚ𑂹; \u200D𐹠\uABED\uFFFB.\u200D𐫓ⴚ𑂹; [B1, C2, V6]; xn--1ugz126coy7bdbm.xn--1ug062chv7ov6e; ; xn--429az70n29i.xn--ilj7702eqyd; [B1, B2, B3, V6] # 𐹠꯭.𐫓ⴚ𑂹
+xn--429az70n29i.xn--ilj7702eqyd; 𐹠\uABED\uFFFB.𐫓ⴚ𑂹; [B1, B2, B3, V6]; xn--429az70n29i.xn--ilj7702eqyd; ; ; # 𐹠꯭.𐫓ⴚ𑂹
+xn--1ugz126coy7bdbm.xn--1ug062chv7ov6e; \u200D𐹠\uABED\uFFFB.\u200D𐫓ⴚ𑂹; [B1, C2, V6]; xn--1ugz126coy7bdbm.xn--1ug062chv7ov6e; ; ; # 𐹠꯭.𐫓ⴚ𑂹
+xn--429az70n29i.xn--ynd3619jqyd; 𐹠\uABED\uFFFB.𐫓Ⴚ𑂹; [B1, B2, B3, V6]; xn--429az70n29i.xn--ynd3619jqyd; ; ; # 𐹠꯭.𐫓Ⴚ𑂹
+xn--1ugz126coy7bdbm.xn--ynd959evs1pv6e; \u200D𐹠\uABED\uFFFB.\u200D𐫓Ⴚ𑂹; [B1, C2, V6]; xn--1ugz126coy7bdbm.xn--ynd959evs1pv6e; ; ; # 𐹠꯭.𐫓Ⴚ𑂹
+󠆠.񷐴󌟈; .񷐴󌟈; [V6, X4_2]; .xn--rx21bhv12i; [V6, A4_2]; ; # .
+󠆠.񷐴󌟈; .񷐴󌟈; [V6, X4_2]; .xn--rx21bhv12i; [V6, A4_2]; ; # .
+.xn--rx21bhv12i; .񷐴󌟈; [V6, X4_2]; .xn--rx21bhv12i; [V6, A4_2]; ; # .
+𐫃\u200CႦ.≠𞷙; ; [B1, B2, B3, C1, V6]; xn--end799ekr1p.xn--1ch2802p; ; xn--end1719j.xn--1ch2802p; [B1, B2, B3, V6] # 𐫃Ⴆ.≠
+𐫃\u200CႦ.=\u0338𞷙; 𐫃\u200CႦ.≠𞷙; [B1, B2, B3, C1, V6]; xn--end799ekr1p.xn--1ch2802p; ; xn--end1719j.xn--1ch2802p; [B1, B2, B3, V6] # 𐫃Ⴆ.≠
+𐫃\u200Cⴆ.=\u0338𞷙; 𐫃\u200Cⴆ.≠𞷙; [B1, B2, B3, C1, V6]; xn--0ug132csv7o.xn--1ch2802p; ; xn--xkjz802e.xn--1ch2802p; [B1, B2, B3, V6] # 𐫃ⴆ.≠
+𐫃\u200Cⴆ.≠𞷙; ; [B1, B2, B3, C1, V6]; xn--0ug132csv7o.xn--1ch2802p; ; xn--xkjz802e.xn--1ch2802p; [B1, B2, B3, V6] # 𐫃ⴆ.≠
+xn--xkjz802e.xn--1ch2802p; 𐫃ⴆ.≠𞷙; [B1, B2, B3, V6]; xn--xkjz802e.xn--1ch2802p; ; ; # 𐫃ⴆ.≠
+xn--0ug132csv7o.xn--1ch2802p; 𐫃\u200Cⴆ.≠𞷙; [B1, B2, B3, C1, V6]; xn--0ug132csv7o.xn--1ch2802p; ; ; # 𐫃ⴆ.≠
+xn--end1719j.xn--1ch2802p; 𐫃Ⴆ.≠𞷙; [B1, B2, B3, V6]; xn--end1719j.xn--1ch2802p; ; ; # 𐫃Ⴆ.≠
+xn--end799ekr1p.xn--1ch2802p; 𐫃\u200CႦ.≠𞷙; [B1, B2, B3, C1, V6]; xn--end799ekr1p.xn--1ch2802p; ; ; # 𐫃Ⴆ.≠
+󠁲𙩢𝟥ꘌ.\u0841; 󠁲𙩢3ꘌ.\u0841; [B1, V6]; xn--3-0g3es485d8i15h.xn--zvb; ; ; # 3ꘌ.ࡁ
+󠁲𙩢3ꘌ.\u0841; ; [B1, V6]; xn--3-0g3es485d8i15h.xn--zvb; ; ; # 3ꘌ.ࡁ
+xn--3-0g3es485d8i15h.xn--zvb; 󠁲𙩢3ꘌ.\u0841; [B1, V6]; xn--3-0g3es485d8i15h.xn--zvb; ; ; # 3ꘌ.ࡁ
+-.\u1886󡲣-; ; [V3, V5, V6]; -.xn----pbkx6497q; ; ; # -.ᢆ-
+-.xn----pbkx6497q; -.\u1886󡲣-; [V3, V5, V6]; -.xn----pbkx6497q; ; ; # -.ᢆ-
+󲚗\u200C。\u200C𞰆ς; 󲚗\u200C.\u200C𞰆ς; [B1, B6, C1, V6]; xn--0ug76062m.xn--3xa795lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, V6] # .ς
+󲚗\u200C。\u200C𞰆ς; 󲚗\u200C.\u200C𞰆ς; [B1, B6, C1, V6]; xn--0ug76062m.xn--3xa795lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, V6] # .ς
+󲚗\u200C。\u200C𞰆Σ; 󲚗\u200C.\u200C𞰆σ; [B1, B6, C1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, V6] # .σ
+󲚗\u200C。\u200C𞰆σ; 󲚗\u200C.\u200C𞰆σ; [B1, B6, C1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, V6] # .σ
+xn--qp42f.xn--4xa3011w; 󲚗.𞰆σ; [B2, B3, V6]; xn--qp42f.xn--4xa3011w; ; ; # .σ
+xn--0ug76062m.xn--4xa595lhn92a; 󲚗\u200C.\u200C𞰆σ; [B1, B6, C1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; ; # .σ
+xn--0ug76062m.xn--3xa795lhn92a; 󲚗\u200C.\u200C𞰆ς; [B1, B6, C1, V6]; xn--0ug76062m.xn--3xa795lhn92a; ; ; # .ς
+󲚗\u200C。\u200C𞰆Σ; 󲚗\u200C.\u200C𞰆σ; [B1, B6, C1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, V6] # .σ
+󲚗\u200C。\u200C𞰆σ; 󲚗\u200C.\u200C𞰆σ; [B1, B6, C1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, V6] # .σ
+堕𑓂\u1B02。𐮇𞤽\u200C-; 堕𑓂\u1B02.𐮇𞤽\u200C-; [B3, C1, V3]; xn--5sf345zdk8h.xn----rgnt157hwl9g; ; xn--5sf345zdk8h.xn----iv5iw606c; [B3, V3] # 堕𑓂ᬂ.𐮇𞤽-
+堕𑓂\u1B02。𐮇𞤛\u200C-; 堕𑓂\u1B02.𐮇𞤽\u200C-; [B3, C1, V3]; xn--5sf345zdk8h.xn----rgnt157hwl9g; ; xn--5sf345zdk8h.xn----iv5iw606c; [B3, V3] # 堕𑓂ᬂ.𐮇𞤽-
+xn--5sf345zdk8h.xn----iv5iw606c; 堕𑓂\u1B02.𐮇𞤽-; [B3, V3]; xn--5sf345zdk8h.xn----iv5iw606c; ; ; # 堕𑓂ᬂ.𐮇𞤽-
+xn--5sf345zdk8h.xn----rgnt157hwl9g; 堕𑓂\u1B02.𐮇𞤽\u200C-; [B3, C1, V3]; xn--5sf345zdk8h.xn----rgnt157hwl9g; ; ; # 堕𑓂ᬂ.𐮇𞤽-
+𐹶𑁆ᡕ𞤢。ᡥς\u062Aς; 𐹶𑁆ᡕ𞤢.ᡥς\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xaa16plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥςتς
+𐹶𑁆ᡕ𞤢。ᡥς\u062Aς; 𐹶𑁆ᡕ𞤢.ᡥς\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xaa16plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥςتς
+𐹶𑁆ᡕ𞤀。ᡥΣ\u062AΣ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥσ\u062Aσ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+xn--l8e1317j1ebz456b.xn--4xaa85plx4a; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+xn--l8e1317j1ebz456b.xn--3xaa16plx4a; 𐹶𑁆ᡕ𞤢.ᡥς\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xaa16plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥςتς
+𐹶𑁆ᡕ𞤀。ᡥΣ\u062AΣ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥσ\u062Aσ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣ\u062AΣ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣ\u062Aσ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣ\u062Aς; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+𐹶𑁆ᡕ𞤢。ᡥσ\u062Aς; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+xn--l8e1317j1ebz456b.xn--3xab95plx4a; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+𐹶𑁆ᡕ𞤢。ᡥΣ\u062AΣ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣ\u062Aσ; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣ\u062Aς; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+𐹶𑁆ᡕ𞤢。ᡥσ\u062Aς; 𐹶𑁆ᡕ𞤢.ᡥσ\u062Aς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+󏒰.-𝟻ß; 󏒰.-5ß; [V3, V6]; xn--t960e.xn---5-hia; ; xn--t960e.-5ss; # .-5ß
+󏒰.-5ß; ; [V3, V6]; xn--t960e.xn---5-hia; ; xn--t960e.-5ss; # .-5ß
+󏒰.-5SS; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-5ss; ; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+xn--t960e.-5ss; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+xn--t960e.xn---5-hia; 󏒰.-5ß; [V3, V6]; xn--t960e.xn---5-hia; ; ; # .-5ß
+󏒰.-𝟻SS; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-𝟻ss; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-𝟻Ss; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-5Ss; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+\u200D𐨿.🤒Ⴥ򑮶; ; [C2, V6]; xn--1ug9533g.xn--9nd3211w0gz4b; ; xn--0s9c.xn--9nd3211w0gz4b; [V5, V6] # 𐨿.🤒Ⴥ
+\u200D𐨿.🤒ⴥ򑮶; ; [C2, V6]; xn--1ug9533g.xn--tljz038l0gz4b; ; xn--0s9c.xn--tljz038l0gz4b; [V5, V6] # 𐨿.🤒ⴥ
+xn--0s9c.xn--tljz038l0gz4b; 𐨿.🤒ⴥ򑮶; [V5, V6]; xn--0s9c.xn--tljz038l0gz4b; ; ; # 𐨿.🤒ⴥ
+xn--1ug9533g.xn--tljz038l0gz4b; \u200D𐨿.🤒ⴥ򑮶; [C2, V6]; xn--1ug9533g.xn--tljz038l0gz4b; ; ; # 𐨿.🤒ⴥ
+xn--0s9c.xn--9nd3211w0gz4b; 𐨿.🤒Ⴥ򑮶; [V5, V6]; xn--0s9c.xn--9nd3211w0gz4b; ; ; # 𐨿.🤒Ⴥ
+xn--1ug9533g.xn--9nd3211w0gz4b; \u200D𐨿.🤒Ⴥ򑮶; [C2, V6]; xn--1ug9533g.xn--9nd3211w0gz4b; ; ; # 𐨿.🤒Ⴥ
+𵋅。ß𬵩\u200D; 𵋅.ß𬵩\u200D; [C2, V6]; xn--ey1p.xn--zca870nz438b; ; xn--ey1p.xn--ss-eq36b; [V6] # .ß𬵩
+𵋅。SS𬵩\u200D; 𵋅.ss𬵩\u200D; [C2, V6]; xn--ey1p.xn--ss-n1tx0508a; ; xn--ey1p.xn--ss-eq36b; [V6] # .ss𬵩
+𵋅。ss𬵩\u200D; 𵋅.ss𬵩\u200D; [C2, V6]; xn--ey1p.xn--ss-n1tx0508a; ; xn--ey1p.xn--ss-eq36b; [V6] # .ss𬵩
+𵋅。Ss𬵩\u200D; 𵋅.ss𬵩\u200D; [C2, V6]; xn--ey1p.xn--ss-n1tx0508a; ; xn--ey1p.xn--ss-eq36b; [V6] # .ss𬵩
+xn--ey1p.xn--ss-eq36b; 𵋅.ss𬵩; [V6]; xn--ey1p.xn--ss-eq36b; ; ; # .ss𬵩
+xn--ey1p.xn--ss-n1tx0508a; 𵋅.ss𬵩\u200D; [C2, V6]; xn--ey1p.xn--ss-n1tx0508a; ; ; # .ss𬵩
+xn--ey1p.xn--zca870nz438b; 𵋅.ß𬵩\u200D; [C2, V6]; xn--ey1p.xn--zca870nz438b; ; ; # .ß𬵩
+\u200C𭉝。\u07F1\u0301𞹻; \u200C𭉝.\u07F1\u0301\u063A; [B1, C1, V5]; xn--0ugy003y.xn--lsa46nuub; ; xn--634m.xn--lsa46nuub; [B1, V5] # 𭉝.߱́غ
+\u200C𭉝。\u07F1\u0301\u063A; \u200C𭉝.\u07F1\u0301\u063A; [B1, C1, V5]; xn--0ugy003y.xn--lsa46nuub; ; xn--634m.xn--lsa46nuub; [B1, V5] # 𭉝.߱́غ
+xn--634m.xn--lsa46nuub; 𭉝.\u07F1\u0301\u063A; [B1, V5]; xn--634m.xn--lsa46nuub; ; ; # 𭉝.߱́غ
+xn--0ugy003y.xn--lsa46nuub; \u200C𭉝.\u07F1\u0301\u063A; [B1, C1, V5]; xn--0ugy003y.xn--lsa46nuub; ; ; # 𭉝.߱́غ
+𞼌\u200C𑈶。𐹡; 𞼌\u200C𑈶.𐹡; [B1, B3, C1, V6]; xn--0ug7946gzpxf.xn--8n0d; ; xn--9g1d1288a.xn--8n0d; [B1, V6] # 𑈶.𐹡
+xn--9g1d1288a.xn--8n0d; 𞼌𑈶.𐹡; [B1, V6]; xn--9g1d1288a.xn--8n0d; ; ; # 𑈶.𐹡
+xn--0ug7946gzpxf.xn--8n0d; 𞼌\u200C𑈶.𐹡; [B1, B3, C1, V6]; xn--0ug7946gzpxf.xn--8n0d; ; ; # 𑈶.𐹡
+󠅯򇽭\u200C🜭。𑖿\u1ABBς≠; 򇽭\u200C🜭.𑖿\u1ABBς≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBς=\u0338; 򇽭\u200C🜭.𑖿\u1ABBς≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBς≠; 򇽭\u200C🜭.𑖿\u1ABBς≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBς=\u0338; 򇽭\u200C🜭.𑖿\u1ABBς≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBΣ=\u0338; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBΣ≠; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBσ≠; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBσ=\u0338; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+xn--zb9h5968x.xn--4xa378i1mfjw7y; 򇽭🜭.𑖿\u1ABBσ≠; [V5, V6]; xn--zb9h5968x.xn--4xa378i1mfjw7y; ; ; # 🜭.𑖿᪻σ≠
+xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; ; # 🜭.𑖿᪻σ≠
+xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; 򇽭\u200C🜭.𑖿\u1ABBς≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; ; # 🜭.𑖿᪻ς≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBΣ=\u0338; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBΣ≠; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBσ≠; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭\u200C🜭。𑖿\u1ABBσ=\u0338; 򇽭\u200C🜭.𑖿\u1ABBσ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [V5, V6] # 🜭.𑖿᪻σ≠
+⒋。⒈\u200D򳴢; ⒋.⒈\u200D򳴢; [C2, V6]; xn--wsh.xn--1ug58o74922a; ; xn--wsh.xn--tsh07994h; [V6] # ⒋.⒈
+4.。1.\u200D򳴢; 4..1.\u200D򳴢; [C2, V6, X4_2]; 4..1.xn--1ug64613i; [C2, V6, A4_2]; 4..1.xn--sf51d; [V6, A4_2] # 4..1.
+4..1.xn--sf51d; 4..1.򳴢; [V6, X4_2]; 4..1.xn--sf51d; [V6, A4_2]; ; # 4..1.
+4..1.xn--1ug64613i; 4..1.\u200D򳴢; [C2, V6, X4_2]; 4..1.xn--1ug64613i; [C2, V6, A4_2]; ; # 4..1.
+xn--wsh.xn--tsh07994h; ⒋.⒈򳴢; [V6]; xn--wsh.xn--tsh07994h; ; ; # ⒋.⒈
+xn--wsh.xn--1ug58o74922a; ⒋.⒈\u200D򳴢; [C2, V6]; xn--wsh.xn--1ug58o74922a; ; ; # ⒋.⒈
+\u0644ß。𐇽\u1A60򾅢𞤾; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+\u0644ß。\u1A60𐇽򾅢𞤾; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+\u0644ß。\u1A60𐇽򾅢𞤾; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+\u0644SS。\u1A60𐇽򾅢𞤜; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ss。\u1A60𐇽򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ss。\u1A60𐇽򾅢𞤜; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+xn--ss-svd.xn--jof2298hn83fln78f; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ß。\u1A60𐇽򾅢𞤜; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+xn--zca57y.xn--jof2298hn83fln78f; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; ; # لß.᩠𐇽𞤾
+\u0644SS。\u1A60𐇽򾅢𞤜; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ss。\u1A60𐇽򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ss。\u1A60𐇽򾅢𞤜; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ß。\u1A60𐇽򾅢𞤜; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+\u0644SS。𐇽\u1A60򾅢𞤜; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ss。𐇽\u1A60򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ss。𐇽\u1A60򾅢𞤜; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644ß。𐇽\u1A60򾅢𞤜; \u0644ß.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+\u0644SS。\u1A60𐇽򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644Ss。\u1A60𐇽򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644SS。\u1A60𐇽򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644Ss。\u1A60𐇽򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644SS。𐇽\u1A60򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+\u0644Ss。𐇽\u1A60򾅢𞤾; \u0644ss.\u1A60𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+𐹽𑄳񼜲.\u1DDF\u17B8\uA806𑜫; ; [B1, V5, V6]; xn--1o0di0c0652w.xn--33e362arr1l153d; ; ; # 𐹽𑄳.ᷟី꠆𑜫
+xn--1o0di0c0652w.xn--33e362arr1l153d; 𐹽𑄳񼜲.\u1DDF\u17B8\uA806𑜫; [B1, V5, V6]; xn--1o0di0c0652w.xn--33e362arr1l153d; ; ; # 𐹽𑄳.ᷟី꠆𑜫
+Ⴓ𑜫\u200D򗭓.\u06A7𑰶; Ⴓ𑜫\u200D򗭓.\u06A7𑰶; [V6]; xn--rnd479ep20q7x12e.xn--9jb4223l; ; xn--rnd8945ky009c.xn--9jb4223l; # Ⴓ𑜫.ڧ𑰶
+Ⴓ𑜫\u200D򗭓.\u06A7𑰶; ; [V6]; xn--rnd479ep20q7x12e.xn--9jb4223l; ; xn--rnd8945ky009c.xn--9jb4223l; # Ⴓ𑜫.ڧ𑰶
+ⴓ𑜫\u200D򗭓.\u06A7𑰶; ; [V6]; xn--1ugy52cym7p7xu5e.xn--9jb4223l; ; xn--blj6306ey091d.xn--9jb4223l; # ⴓ𑜫.ڧ𑰶
+xn--blj6306ey091d.xn--9jb4223l; ⴓ𑜫򗭓.\u06A7𑰶; [V6]; xn--blj6306ey091d.xn--9jb4223l; ; ; # ⴓ𑜫.ڧ𑰶
+xn--1ugy52cym7p7xu5e.xn--9jb4223l; ⴓ𑜫\u200D򗭓.\u06A7𑰶; [V6]; xn--1ugy52cym7p7xu5e.xn--9jb4223l; ; ; # ⴓ𑜫.ڧ𑰶
+xn--rnd8945ky009c.xn--9jb4223l; Ⴓ𑜫򗭓.\u06A7𑰶; [V6]; xn--rnd8945ky009c.xn--9jb4223l; ; ; # Ⴓ𑜫.ڧ𑰶
+xn--rnd479ep20q7x12e.xn--9jb4223l; Ⴓ𑜫\u200D򗭓.\u06A7𑰶; [V6]; xn--rnd479ep20q7x12e.xn--9jb4223l; ; ; # Ⴓ𑜫.ڧ𑰶
+ⴓ𑜫\u200D򗭓.\u06A7𑰶; ⴓ𑜫\u200D򗭓.\u06A7𑰶; [V6]; xn--1ugy52cym7p7xu5e.xn--9jb4223l; ; xn--blj6306ey091d.xn--9jb4223l; # ⴓ𑜫.ڧ𑰶
+𐨿.🄆—; ; [V5, V6]; xn--0s9c.xn--8ug8324p; ; ; # 𐨿.🄆—
+𐨿.5,—; ; [V5, V6]; xn--0s9c.xn--5,-81t; ; ; # 𐨿.5,—
+xn--0s9c.xn--5,-81t; 𐨿.5,—; [V5, V6]; xn--0s9c.xn--5,-81t; ; ; # 𐨿.5,—
+xn--0s9c.xn--8ug8324p; 𐨿.🄆—; [V5, V6]; xn--0s9c.xn--8ug8324p; ; ; # 𐨿.🄆—
+򔊱񁦮۸。󠾭-; 򔊱񁦮۸.󠾭-; [V3, V6]; xn--lmb18944c0g2z.xn----2k81m; ; ; # ۸.-
+xn--lmb18944c0g2z.xn----2k81m; 򔊱񁦮۸.󠾭-; [V3, V6]; xn--lmb18944c0g2z.xn----2k81m; ; ; # ۸.-
+𼗸\u07CD𐹮。\u06DDᡎᠴ; 𼗸\u07CD𐹮.\u06DDᡎᠴ; [B1, B5, B6, V6]; xn--osb0855kcc2r.xn--tlb299fhc; ; ; # ߍ𐹮.ᡎᠴ
+xn--osb0855kcc2r.xn--tlb299fhc; 𼗸\u07CD𐹮.\u06DDᡎᠴ; [B1, B5, B6, V6]; xn--osb0855kcc2r.xn--tlb299fhc; ; ; # ߍ𐹮.ᡎᠴ
+\u200DᠮႾ🄂.🚗\u0841𮹌\u200C; ; [B1, C1, C2, V6]; xn--2nd129ay2gnw71c.xn--zvb692j9664aic1g; ; xn--2nd129ai554b.xn--zvb3124wpkpf; [B1, V6] # ᠮႾ🄂.🚗ࡁ𮹌
+\u200DᠮႾ1,.🚗\u0841𮹌\u200C; ; [B1, C1, C2, V6]; xn--1,-ogkx89c39j.xn--zvb692j9664aic1g; ; xn--1,-ogkx89c.xn--zvb3124wpkpf; [B1, B6, V6] # ᠮႾ1,.🚗ࡁ𮹌
+\u200Dᠮⴞ1,.🚗\u0841𮹌\u200C; ; [B1, C1, C2, V6]; xn--1,-v3o161c53q.xn--zvb692j9664aic1g; ; xn--1,-v3o625k.xn--zvb3124wpkpf; [B1, B6, V6] # ᠮⴞ1,.🚗ࡁ𮹌
+xn--1,-v3o625k.xn--zvb3124wpkpf; ᠮⴞ1,.🚗\u0841𮹌; [B1, B6, V6]; xn--1,-v3o625k.xn--zvb3124wpkpf; ; ; # ᠮⴞ1,.🚗ࡁ𮹌
+xn--1,-v3o161c53q.xn--zvb692j9664aic1g; \u200Dᠮⴞ1,.🚗\u0841𮹌\u200C; [B1, C1, C2, V6]; xn--1,-v3o161c53q.xn--zvb692j9664aic1g; ; ; # ᠮⴞ1,.🚗ࡁ𮹌
+xn--1,-ogkx89c.xn--zvb3124wpkpf; ᠮႾ1,.🚗\u0841𮹌; [B1, B6, V6]; xn--1,-ogkx89c.xn--zvb3124wpkpf; ; ; # ᠮႾ1,.🚗ࡁ𮹌
+xn--1,-ogkx89c39j.xn--zvb692j9664aic1g; \u200DᠮႾ1,.🚗\u0841𮹌\u200C; [B1, C1, C2, V6]; xn--1,-ogkx89c39j.xn--zvb692j9664aic1g; ; ; # ᠮႾ1,.🚗ࡁ𮹌
+\u200Dᠮⴞ🄂.🚗\u0841𮹌\u200C; ; [B1, C1, C2, V6]; xn--h7e341b0wlbv45b.xn--zvb692j9664aic1g; ; xn--h7e438h1p44a.xn--zvb3124wpkpf; [B1, V6] # ᠮⴞ🄂.🚗ࡁ𮹌
+xn--h7e438h1p44a.xn--zvb3124wpkpf; ᠮⴞ🄂.🚗\u0841𮹌; [B1, V6]; xn--h7e438h1p44a.xn--zvb3124wpkpf; ; ; # ᠮⴞ🄂.🚗ࡁ𮹌
+xn--h7e341b0wlbv45b.xn--zvb692j9664aic1g; \u200Dᠮⴞ🄂.🚗\u0841𮹌\u200C; [B1, C1, C2, V6]; xn--h7e341b0wlbv45b.xn--zvb692j9664aic1g; ; ; # ᠮⴞ🄂.🚗ࡁ𮹌
+xn--2nd129ai554b.xn--zvb3124wpkpf; ᠮႾ🄂.🚗\u0841𮹌; [B1, V6]; xn--2nd129ai554b.xn--zvb3124wpkpf; ; ; # ᠮႾ🄂.🚗ࡁ𮹌
+xn--2nd129ay2gnw71c.xn--zvb692j9664aic1g; \u200DᠮႾ🄂.🚗\u0841𮹌\u200C; [B1, C1, C2, V6]; xn--2nd129ay2gnw71c.xn--zvb692j9664aic1g; ; ; # ᠮႾ🄂.🚗ࡁ𮹌
+\u0601\u0697.𑚶񼡷⾆; \u0601\u0697.𑚶񼡷舌; [B1, V5, V6]; xn--jfb41a.xn--tc1ap851axo39c; ; ; # ڗ.𑚶舌
+\u0601\u0697.𑚶񼡷舌; ; [B1, V5, V6]; xn--jfb41a.xn--tc1ap851axo39c; ; ; # ڗ.𑚶舌
+xn--jfb41a.xn--tc1ap851axo39c; \u0601\u0697.𑚶񼡷舌; [B1, V5, V6]; xn--jfb41a.xn--tc1ap851axo39c; ; ; # ڗ.𑚶舌
+🞅󠳡󜍙.񲖷; ; [V6]; xn--ie9hi1349bqdlb.xn--oj69a; ; ; # 🞅.
+xn--ie9hi1349bqdlb.xn--oj69a; 🞅󠳡󜍙.񲖷; [V6]; xn--ie9hi1349bqdlb.xn--oj69a; ; ; # 🞅.
+\u20E7񯡎-򫣝.4Ⴄ\u200C; ; [C1, V5, V6]; xn----9snu5320fi76w.xn--4-f0g649i; ; xn----9snu5320fi76w.xn--4-f0g; [V5, V6] # ⃧-.4Ⴄ
+\u20E7񯡎-򫣝.4ⴄ\u200C; ; [C1, V5, V6]; xn----9snu5320fi76w.xn--4-sgn589c; ; xn----9snu5320fi76w.xn--4-ivs; [V5, V6] # ⃧-.4ⴄ
+xn----9snu5320fi76w.xn--4-ivs; \u20E7񯡎-򫣝.4ⴄ; [V5, V6]; xn----9snu5320fi76w.xn--4-ivs; ; ; # ⃧-.4ⴄ
+xn----9snu5320fi76w.xn--4-sgn589c; \u20E7񯡎-򫣝.4ⴄ\u200C; [C1, V5, V6]; xn----9snu5320fi76w.xn--4-sgn589c; ; ; # ⃧-.4ⴄ
+xn----9snu5320fi76w.xn--4-f0g; \u20E7񯡎-򫣝.4Ⴄ; [V5, V6]; xn----9snu5320fi76w.xn--4-f0g; ; ; # ⃧-.4Ⴄ
+xn----9snu5320fi76w.xn--4-f0g649i; \u20E7񯡎-򫣝.4Ⴄ\u200C; [C1, V5, V6]; xn----9snu5320fi76w.xn--4-f0g649i; ; ; # ⃧-.4Ⴄ
+ᚭ。𝌠ß𖫱; ᚭ.𝌠ß𖫱; ; xn--hwe.xn--zca4946pblnc; ; xn--hwe.xn--ss-ci1ub261a; # ᚭ.𝌠ß𖫱
+ᚭ。𝌠ß𖫱; ᚭ.𝌠ß𖫱; ; xn--hwe.xn--zca4946pblnc; ; xn--hwe.xn--ss-ci1ub261a; # ᚭ.𝌠ß𖫱
+ᚭ。𝌠SS𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠Ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+xn--hwe.xn--ss-ci1ub261a; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ.𝌠ss𖫱; ; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ.𝌠SS𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ.𝌠Ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+xn--hwe.xn--zca4946pblnc; ᚭ.𝌠ß𖫱; ; xn--hwe.xn--zca4946pblnc; ; ; # ᚭ.𝌠ß𖫱
+ᚭ.𝌠ß𖫱; ; ; xn--hwe.xn--zca4946pblnc; ; xn--hwe.xn--ss-ci1ub261a; # ᚭ.𝌠ß𖫱
+ᚭ。𝌠SS𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠Ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+₁。𞤫ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+1。𞤫ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+1。𞤉ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+1.xn--gd9al691d; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+₁。𞤉ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+𯻼\u200C.𞶞򻙤񥘇; ; [B2, B3, B6, C1, V6]; xn--0ug27500a.xn--2b7hs861pl540a; ; xn--kg4n.xn--2b7hs861pl540a; [B2, B3, V6] # .
+xn--kg4n.xn--2b7hs861pl540a; 𯻼.𞶞򻙤񥘇; [B2, B3, V6]; xn--kg4n.xn--2b7hs861pl540a; ; ; # .
+xn--0ug27500a.xn--2b7hs861pl540a; 𯻼\u200C.𞶞򻙤񥘇; [B2, B3, B6, C1, V6]; xn--0ug27500a.xn--2b7hs861pl540a; ; ; # .
+𑑄≯。𑜤; 𑑄≯.𑜤; [V5]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+𑑄>\u0338。𑜤; 𑑄≯.𑜤; [V5]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+𑑄≯。𑜤; 𑑄≯.𑜤; [V5]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+𑑄>\u0338。𑜤; 𑑄≯.𑜤; [V5]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+xn--hdh5636g.xn--ci2d; 𑑄≯.𑜤; [V5]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+Ⴋ≮𱲆。\u200D\u07A7𐋣; Ⴋ≮𱲆.\u200D\u07A7𐋣; [C2, V6]; xn--jnd802gsm17c.xn--lrb506jqr4n; ; xn--jnd802gsm17c.xn--lrb6479j; [V5, V6] # Ⴋ≮𱲆.ާ𐋣
+Ⴋ<\u0338𱲆。\u200D\u07A7𐋣; Ⴋ≮𱲆.\u200D\u07A7𐋣; [C2, V6]; xn--jnd802gsm17c.xn--lrb506jqr4n; ; xn--jnd802gsm17c.xn--lrb6479j; [V5, V6] # Ⴋ≮𱲆.ާ𐋣
+ⴋ<\u0338𱲆。\u200D\u07A7𐋣; ⴋ≮𱲆.\u200D\u07A7𐋣; [C2]; xn--gdhz03bxt42d.xn--lrb506jqr4n; ; xn--gdhz03bxt42d.xn--lrb6479j; [V5] # ⴋ≮𱲆.ާ𐋣
+ⴋ≮𱲆。\u200D\u07A7𐋣; ⴋ≮𱲆.\u200D\u07A7𐋣; [C2]; xn--gdhz03bxt42d.xn--lrb506jqr4n; ; xn--gdhz03bxt42d.xn--lrb6479j; [V5] # ⴋ≮𱲆.ާ𐋣
+xn--gdhz03bxt42d.xn--lrb6479j; ⴋ≮𱲆.\u07A7𐋣; [V5]; xn--gdhz03bxt42d.xn--lrb6479j; ; ; # ⴋ≮𱲆.ާ𐋣
+xn--gdhz03bxt42d.xn--lrb506jqr4n; ⴋ≮𱲆.\u200D\u07A7𐋣; [C2]; xn--gdhz03bxt42d.xn--lrb506jqr4n; ; ; # ⴋ≮𱲆.ާ𐋣
+xn--jnd802gsm17c.xn--lrb6479j; Ⴋ≮𱲆.\u07A7𐋣; [V5, V6]; xn--jnd802gsm17c.xn--lrb6479j; ; ; # Ⴋ≮𱲆.ާ𐋣
+xn--jnd802gsm17c.xn--lrb506jqr4n; Ⴋ≮𱲆.\u200D\u07A7𐋣; [C2, V6]; xn--jnd802gsm17c.xn--lrb506jqr4n; ; ; # Ⴋ≮𱲆.ާ𐋣
+\u17D2.򆽒≯; ; [V5, V6]; xn--u4e.xn--hdhx0084f; ; ; # ្.≯
+\u17D2.򆽒>\u0338; \u17D2.򆽒≯; [V5, V6]; xn--u4e.xn--hdhx0084f; ; ; # ្.≯
+xn--u4e.xn--hdhx0084f; \u17D2.򆽒≯; [V5, V6]; xn--u4e.xn--hdhx0084f; ; ; # ្.≯
+񏁇\u1734.𐨺É⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺E\u0301⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺É⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺E\u0301⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺e\u0301⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺é⬓𑄴; ; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+xn--c0e34564d.xn--9ca207st53lg3f; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺e\u0301⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇\u1734.𐨺é⬓𑄴; 񏁇\u1734.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+ᢇ\u200D\uA8C4。︒𞤺; ᢇ\u200D\uA8C4.︒𞤺; [B1, B6, C2, V6]; xn--09e669a6x8j.xn--y86cv562b; ; xn--09e4694e.xn--y86cv562b; [B1, V6] # ᢇ꣄.︒𞤺
+ᢇ\u200D\uA8C4。。𞤺; ᢇ\u200D\uA8C4..𞤺; [B6, C2, X4_2]; xn--09e669a6x8j..xn--ye6h; [B6, C2, A4_2]; xn--09e4694e..xn--ye6h; [A4_2] # ᢇ꣄..𞤺
+ᢇ\u200D\uA8C4。。𞤘; ᢇ\u200D\uA8C4..𞤺; [B6, C2, X4_2]; xn--09e669a6x8j..xn--ye6h; [B6, C2, A4_2]; xn--09e4694e..xn--ye6h; [A4_2] # ᢇ꣄..𞤺
+xn--09e4694e..xn--ye6h; ᢇ\uA8C4..𞤺; [X4_2]; xn--09e4694e..xn--ye6h; [A4_2]; ; # ᢇ꣄..𞤺
+xn--09e669a6x8j..xn--ye6h; ᢇ\u200D\uA8C4..𞤺; [B6, C2, X4_2]; xn--09e669a6x8j..xn--ye6h; [B6, C2, A4_2]; ; # ᢇ꣄..𞤺
+ᢇ\u200D\uA8C4。︒𞤘; ᢇ\u200D\uA8C4.︒𞤺; [B1, B6, C2, V6]; xn--09e669a6x8j.xn--y86cv562b; ; xn--09e4694e.xn--y86cv562b; [B1, V6] # ᢇ꣄.︒𞤺
+xn--09e4694e.xn--y86cv562b; ᢇ\uA8C4.︒𞤺; [B1, V6]; xn--09e4694e.xn--y86cv562b; ; ; # ᢇ꣄.︒𞤺
+xn--09e669a6x8j.xn--y86cv562b; ᢇ\u200D\uA8C4.︒𞤺; [B1, B6, C2, V6]; xn--09e669a6x8j.xn--y86cv562b; ; ; # ᢇ꣄.︒𞤺
+𞩬򖙱\u1714\u200C。\u0631\u07AA≮; 𞩬򖙱\u1714\u200C.\u0631\u07AA≮; [B2, B3, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+𞩬򖙱\u1714\u200C。\u0631\u07AA<\u0338; 𞩬򖙱\u1714\u200C.\u0631\u07AA≮; [B2, B3, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+𞩬򖙱\u1714\u200C。\u0631\u07AA≮; 𞩬򖙱\u1714\u200C.\u0631\u07AA≮; [B2, B3, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+𞩬򖙱\u1714\u200C。\u0631\u07AA<\u0338; 𞩬򖙱\u1714\u200C.\u0631\u07AA≮; [B2, B3, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+xn--fze3930v7hz6b.xn--wgb86el10d; 𞩬򖙱\u1714.\u0631\u07AA≮; [B2, B3, V6]; xn--fze3930v7hz6b.xn--wgb86el10d; ; ; # ᜔.رު≮
+xn--fze607b9651bjwl7c.xn--wgb86el10d; 𞩬򖙱\u1714\u200C.\u0631\u07AA≮; [B2, B3, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; ; # ᜔.رު≮
+Ⴣ.\u0653ᢤ; Ⴣ.\u0653ᢤ; [V5, V6]; xn--7nd.xn--vhb294g; ; ; # Ⴣ.ٓᢤ
+Ⴣ.\u0653ᢤ; ; [V5, V6]; xn--7nd.xn--vhb294g; ; ; # Ⴣ.ٓᢤ
+ⴣ.\u0653ᢤ; ; [V5]; xn--rlj.xn--vhb294g; ; ; # ⴣ.ٓᢤ
+xn--rlj.xn--vhb294g; ⴣ.\u0653ᢤ; [V5]; xn--rlj.xn--vhb294g; ; ; # ⴣ.ٓᢤ
+xn--7nd.xn--vhb294g; Ⴣ.\u0653ᢤ; [V5, V6]; xn--7nd.xn--vhb294g; ; ; # Ⴣ.ٓᢤ
+ⴣ.\u0653ᢤ; ⴣ.\u0653ᢤ; [V5]; xn--rlj.xn--vhb294g; ; ; # ⴣ.ٓᢤ
+󠄈\u0813.싉򄆻Ⴤ򂡐; \u0813.싉򄆻Ⴤ򂡐; [V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈\u0813.싉򄆻Ⴤ򂡐; \u0813.싉򄆻Ⴤ򂡐; [V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈\u0813.싉򄆻Ⴤ򂡐; \u0813.싉򄆻Ⴤ򂡐; [V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈\u0813.싉򄆻Ⴤ򂡐; \u0813.싉򄆻Ⴤ򂡐; [V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈\u0813.싉򄆻ⴤ򂡐; \u0813.싉򄆻ⴤ򂡐; [V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+󠄈\u0813.싉򄆻ⴤ򂡐; \u0813.싉򄆻ⴤ򂡐; [V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+xn--oub.xn--sljz109bpe25dviva; \u0813.싉򄆻ⴤ򂡐; [V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+xn--oub.xn--8nd9522gpe69cviva; \u0813.싉򄆻Ⴤ򂡐; [V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈\u0813.싉򄆻ⴤ򂡐; \u0813.싉򄆻ⴤ򂡐; [V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+󠄈\u0813.싉򄆻ⴤ򂡐; \u0813.싉򄆻ⴤ򂡐; [V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+\uAA2C𑲫≮.⤂; \uAA2C𑲫≮.⤂; [V5]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+\uAA2C𑲫<\u0338.⤂; \uAA2C𑲫≮.⤂; [V5]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+\uAA2C𑲫≮.⤂; ; [V5]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+\uAA2C𑲫<\u0338.⤂; \uAA2C𑲫≮.⤂; [V5]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+xn--gdh1854cn19c.xn--kqi; \uAA2C𑲫≮.⤂; [V5]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+\u0604𐩔≮Ⴢ.Ⴃ; \u0604𐩔≮Ⴢ.Ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+\u0604𐩔<\u0338Ⴢ.Ⴃ; \u0604𐩔≮Ⴢ.Ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+\u0604𐩔≮Ⴢ.Ⴃ; ; [B1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+\u0604𐩔<\u0338Ⴢ.Ⴃ; \u0604𐩔≮Ⴢ.Ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+\u0604𐩔<\u0338ⴢ.ⴃ; \u0604𐩔≮ⴢ.ⴃ; [B1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+\u0604𐩔≮ⴢ.ⴃ; ; [B1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+\u0604𐩔≮Ⴢ.ⴃ; ; [B1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+\u0604𐩔<\u0338Ⴢ.ⴃ; \u0604𐩔≮Ⴢ.ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+xn--mfb416c0jox02t.xn--ukj; \u0604𐩔≮Ⴢ.ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+xn--mfb266l4khr54u.xn--ukj; \u0604𐩔≮ⴢ.ⴃ; [B1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+xn--mfb416c0jox02t.xn--bnd; \u0604𐩔≮Ⴢ.Ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+\u0604𐩔<\u0338ⴢ.ⴃ; \u0604𐩔≮ⴢ.ⴃ; [B1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+\u0604𐩔≮ⴢ.ⴃ; \u0604𐩔≮ⴢ.ⴃ; [B1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+\u0604𐩔≮Ⴢ.ⴃ; \u0604𐩔≮Ⴢ.ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+\u0604𐩔<\u0338Ⴢ.ⴃ; \u0604𐩔≮Ⴢ.ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+𑁅。-; 𑁅.-; [V3, V5]; xn--210d.-; ; ; # 𑁅.-
+xn--210d.-; 𑁅.-; [V3, V5]; xn--210d.-; ; ; # 𑁅.-
+\u0DCA򕸽󠧱。饈≠\u0664; \u0DCA򕸽󠧱.饈≠\u0664; [B1, B5, B6, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+\u0DCA򕸽󠧱。饈=\u0338\u0664; \u0DCA򕸽󠧱.饈≠\u0664; [B1, B5, B6, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+\u0DCA򕸽󠧱。饈≠\u0664; \u0DCA򕸽󠧱.饈≠\u0664; [B1, B5, B6, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+\u0DCA򕸽󠧱。饈=\u0338\u0664; \u0DCA򕸽󠧱.饈≠\u0664; [B1, B5, B6, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+xn--h1c25913jfwov.xn--dib144ler5f; \u0DCA򕸽󠧱.饈≠\u0664; [B1, B5, B6, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+𞥃ᠠ⁷。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞥃ᠠ⁷。>\u0338邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞥃ᠠ7。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞥃ᠠ7。>\u0338邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ7。>\u0338邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ7。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+xn--7-v4j2826w.xn--4-ogoy01bou3i; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ⁷。>\u0338邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ⁷。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+򠿯ᡳ-𑐻.𐹴𐋫\u0605󑎳; ; [B1, B6, V6]; xn----m9j3429kxmy7e.xn--nfb7950kdihrp812a; ; ; # ᡳ-𑐻.𐹴𐋫
+xn----m9j3429kxmy7e.xn--nfb7950kdihrp812a; 򠿯ᡳ-𑐻.𐹴𐋫\u0605󑎳; [B1, B6, V6]; xn----m9j3429kxmy7e.xn--nfb7950kdihrp812a; ; ; # ᡳ-𑐻.𐹴𐋫
+򠶆\u0845\u0A51.넨-󶧈; ; [B5, B6, V6]; xn--3vb26hb6834b.xn----i37ez0957g; ; ; # ࡅੑ.넨-
+򠶆\u0845\u0A51.넨-󶧈; 򠶆\u0845\u0A51.넨-󶧈; [B5, B6, V6]; xn--3vb26hb6834b.xn----i37ez0957g; ; ; # ࡅੑ.넨-
+xn--3vb26hb6834b.xn----i37ez0957g; 򠶆\u0845\u0A51.넨-󶧈; [B5, B6, V6]; xn--3vb26hb6834b.xn----i37ez0957g; ; ; # ࡅੑ.넨-
+ꡦᡑ\u200D⒈。𐋣-; ꡦᡑ\u200D⒈.𐋣-; [C2, V3, V6]; xn--h8e470bl0d838o.xn----381i; ; xn--h8e863drj7h.xn----381i; [V3, V6] # ꡦᡑ⒈.𐋣-
+ꡦᡑ\u200D1.。𐋣-; ꡦᡑ\u200D1..𐋣-; [C2, V3, X4_2]; xn--1-o7j663bdl7m..xn----381i; [C2, V3, A4_2]; xn--1-o7j0610f..xn----381i; [V3, A4_2] # ꡦᡑ1..𐋣-
+xn--1-o7j0610f..xn----381i; ꡦᡑ1..𐋣-; [V3, X4_2]; xn--1-o7j0610f..xn----381i; [V3, A4_2]; ; # ꡦᡑ1..𐋣-
+xn--1-o7j663bdl7m..xn----381i; ꡦᡑ\u200D1..𐋣-; [C2, V3, X4_2]; xn--1-o7j663bdl7m..xn----381i; [C2, V3, A4_2]; ; # ꡦᡑ1..𐋣-
+xn--h8e863drj7h.xn----381i; ꡦᡑ⒈.𐋣-; [V3, V6]; xn--h8e863drj7h.xn----381i; ; ; # ꡦᡑ⒈.𐋣-
+xn--h8e470bl0d838o.xn----381i; ꡦᡑ\u200D⒈.𐋣-; [C2, V3, V6]; xn--h8e470bl0d838o.xn----381i; ; ; # ꡦᡑ⒈.𐋣-
+Ⴌ。􍼠\uFB69; Ⴌ.􍼠\u0679; [B5, B6, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
+Ⴌ。􍼠\u0679; Ⴌ.􍼠\u0679; [B5, B6, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
+ⴌ。􍼠\u0679; ⴌ.􍼠\u0679; [B5, B6, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
+xn--3kj.xn--yib19191t; ⴌ.􍼠\u0679; [B5, B6, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
+xn--knd.xn--yib19191t; Ⴌ.􍼠\u0679; [B5, B6, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
+ⴌ。􍼠\uFB69; ⴌ.􍼠\u0679; [B5, B6, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
+𐮁𐭱.\u0F84\u135E-ᳺ; ; [B1, V5]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-ᳺ
+xn--r19c5a.xn----xjg270ag3m; 𐮁𐭱.\u0F84\u135E-ᳺ; [B1, V5]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-ᳺ
+⒈䰹\u200D-。웈; ⒈䰹\u200D-.웈; [C2, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; xn----dcp160o.xn--kp5b; [V3, V6] # ⒈䰹-.웈
+⒈䰹\u200D-。웈; ⒈䰹\u200D-.웈; [C2, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; xn----dcp160o.xn--kp5b; [V3, V6] # ⒈䰹-.웈
+1.䰹\u200D-。웈; 1.䰹\u200D-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; 1.xn----zw5a.xn--kp5b; [V3] # 1.䰹-.웈
+1.䰹\u200D-。웈; 1.䰹\u200D-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; 1.xn----zw5a.xn--kp5b; [V3] # 1.䰹-.웈
+1.xn----zw5a.xn--kp5b; 1.䰹-.웈; [V3]; 1.xn----zw5a.xn--kp5b; ; ; # 1.䰹-.웈
+1.xn----tgnz80r.xn--kp5b; 1.䰹\u200D-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; ; # 1.䰹-.웈
+xn----dcp160o.xn--kp5b; ⒈䰹-.웈; [V3, V6]; xn----dcp160o.xn--kp5b; ; ; # ⒈䰹-.웈
+xn----tgnx5rjr6c.xn--kp5b; ⒈䰹\u200D-.웈; [C2, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; ; # ⒈䰹-.웈
+て。\u200C󠳽\u07F3; て.\u200C󠳽\u07F3; [C1, V6]; xn--m9j.xn--rtb154j9l73w; ; xn--m9j.xn--rtb10784p; [V6] # て.߳
+xn--m9j.xn--rtb10784p; て.󠳽\u07F3; [V6]; xn--m9j.xn--rtb10784p; ; ; # て.߳
+xn--m9j.xn--rtb154j9l73w; て.\u200C󠳽\u07F3; [C1, V6]; xn--m9j.xn--rtb154j9l73w; ; ; # て.߳
+ς。\uA9C0\u06E7; ς.\uA9C0\u06E7; [V5]; xn--3xa.xn--3lb1944f; ; xn--4xa.xn--3lb1944f; # ς.꧀ۧ
+ς。\uA9C0\u06E7; ς.\uA9C0\u06E7; [V5]; xn--3xa.xn--3lb1944f; ; xn--4xa.xn--3lb1944f; # ς.꧀ۧ
+Σ。\uA9C0\u06E7; σ.\uA9C0\u06E7; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+σ。\uA9C0\u06E7; σ.\uA9C0\u06E7; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+xn--4xa.xn--3lb1944f; σ.\uA9C0\u06E7; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+xn--3xa.xn--3lb1944f; ς.\uA9C0\u06E7; [V5]; xn--3xa.xn--3lb1944f; ; ; # ς.꧀ۧ
+Σ。\uA9C0\u06E7; σ.\uA9C0\u06E7; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+σ。\uA9C0\u06E7; σ.\uA9C0\u06E7; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+\u0BCD󥫅򌉑.ႢႵ; ; [V5, V6]; xn--xmc83135idcxza.xn--9md2b; ; ; # ்.ႢႵ
+\u0BCD󥫅򌉑.ⴂⴕ; ; [V5, V6]; xn--xmc83135idcxza.xn--tkjwb; ; ; # ்.ⴂⴕ
+\u0BCD󥫅򌉑.Ⴂⴕ; ; [V5, V6]; xn--xmc83135idcxza.xn--9md086l; ; ; # ்.Ⴂⴕ
+xn--xmc83135idcxza.xn--9md086l; \u0BCD󥫅򌉑.Ⴂⴕ; [V5, V6]; xn--xmc83135idcxza.xn--9md086l; ; ; # ்.Ⴂⴕ
+xn--xmc83135idcxza.xn--tkjwb; \u0BCD󥫅򌉑.ⴂⴕ; [V5, V6]; xn--xmc83135idcxza.xn--tkjwb; ; ; # ்.ⴂⴕ
+xn--xmc83135idcxza.xn--9md2b; \u0BCD󥫅򌉑.ႢႵ; [V5, V6]; xn--xmc83135idcxza.xn--9md2b; ; ; # ்.ႢႵ
+\u1C32🄈⾛\u05A6.\u200D򯥤\u07FD; \u1C32🄈走\u05A6.\u200D򯥤\u07FD; [C2, V5, V6]; xn--xcb756i493fwi5o.xn--1tb334j1197q; ; xn--xcb756i493fwi5o.xn--1tb13454l; [V5, V6] # ᰲ🄈走֦.߽
+\u1C327,走\u05A6.\u200D򯥤\u07FD; ; [C2, V5, V6]; xn--7,-bid991urn3k.xn--1tb334j1197q; ; xn--7,-bid991urn3k.xn--1tb13454l; [V5, V6] # ᰲ7,走֦.߽
+xn--7,-bid991urn3k.xn--1tb13454l; \u1C327,走\u05A6.򯥤\u07FD; [V5, V6]; xn--7,-bid991urn3k.xn--1tb13454l; ; ; # ᰲ7,走֦.߽
+xn--7,-bid991urn3k.xn--1tb334j1197q; \u1C327,走\u05A6.\u200D򯥤\u07FD; [C2, V5, V6]; xn--7,-bid991urn3k.xn--1tb334j1197q; ; ; # ᰲ7,走֦.߽
+xn--xcb756i493fwi5o.xn--1tb13454l; \u1C32🄈走\u05A6.򯥤\u07FD; [V5, V6]; xn--xcb756i493fwi5o.xn--1tb13454l; ; ; # ᰲ🄈走֦.߽
+xn--xcb756i493fwi5o.xn--1tb334j1197q; \u1C32🄈走\u05A6.\u200D򯥤\u07FD; [C2, V5, V6]; xn--xcb756i493fwi5o.xn--1tb334j1197q; ; ; # ᰲ🄈走֦.߽
+ᢗ。Ӏ񝄻; ᢗ.Ӏ񝄻; [V6]; xn--hbf.xn--d5a86117e; ; ; # ᢗ.Ӏ
+ᢗ。Ӏ񝄻; ᢗ.Ӏ񝄻; [V6]; xn--hbf.xn--d5a86117e; ; ; # ᢗ.Ӏ
+ᢗ。ӏ񝄻; ᢗ.ӏ񝄻; [V6]; xn--hbf.xn--s5a83117e; ; ; # ᢗ.ӏ
+xn--hbf.xn--s5a83117e; ᢗ.ӏ񝄻; [V6]; xn--hbf.xn--s5a83117e; ; ; # ᢗ.ӏ
+xn--hbf.xn--d5a86117e; ᢗ.Ӏ񝄻; [V6]; xn--hbf.xn--d5a86117e; ; ; # ᢗ.Ӏ
+ᢗ。ӏ񝄻; ᢗ.ӏ񝄻; [V6]; xn--hbf.xn--s5a83117e; ; ; # ᢗ.ӏ
+\u0668-。񠏇🝆ᄾ; \u0668-.񠏇🝆ᄾ; [B1, V3, V6]; xn----oqc.xn--qrd1699v327w; ; ; # ٨-.🝆ᄾ
+xn----oqc.xn--qrd1699v327w; \u0668-.񠏇🝆ᄾ; [B1, V3, V6]; xn----oqc.xn--qrd1699v327w; ; ; # ٨-.🝆ᄾ
+-𐋷𖾑。󠆬; -𐋷𖾑.; [V3]; xn----991iq40y.; ; ; # -𐋷𖾑.
+xn----991iq40y.; -𐋷𖾑.; [V3]; xn----991iq40y.; ; ; # -𐋷𖾑.
+\u200C𐹳🐴멈.\uABED񐡼; ; [B1, C1, V5, V6]; xn--0ug6681d406b7bwk.xn--429a8682s; ; xn--422b325mqb6i.xn--429a8682s; [B1, V5, V6] # 𐹳🐴멈.꯭
+\u200C𐹳🐴멈.\uABED񐡼; \u200C𐹳🐴멈.\uABED񐡼; [B1, C1, V5, V6]; xn--0ug6681d406b7bwk.xn--429a8682s; ; xn--422b325mqb6i.xn--429a8682s; [B1, V5, V6] # 𐹳🐴멈.꯭
+xn--422b325mqb6i.xn--429a8682s; 𐹳🐴멈.\uABED񐡼; [B1, V5, V6]; xn--422b325mqb6i.xn--429a8682s; ; ; # 𐹳🐴멈.꯭
+xn--0ug6681d406b7bwk.xn--429a8682s; \u200C𐹳🐴멈.\uABED񐡼; [B1, C1, V5, V6]; xn--0ug6681d406b7bwk.xn--429a8682s; ; ; # 𐹳🐴멈.꯭
+≮.\u0769\u0603; ; [B1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
+<\u0338.\u0769\u0603; ≮.\u0769\u0603; [B1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
+xn--gdh.xn--lfb92e; ≮.\u0769\u0603; [B1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
+𐶭⾆。\u200C𑚶򟱃𞰘; 𐶭舌.\u200C𑚶򟱃𞰘; [B1, B2, B3, C1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; xn--tc1ao37z.xn--6e2dw557azds2d; [B2, B3, B5, B6, V5, V6] # 舌.𑚶
+𐶭舌。\u200C𑚶򟱃𞰘; 𐶭舌.\u200C𑚶򟱃𞰘; [B1, B2, B3, C1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; xn--tc1ao37z.xn--6e2dw557azds2d; [B2, B3, B5, B6, V5, V6] # 舌.𑚶
+xn--tc1ao37z.xn--6e2dw557azds2d; 𐶭舌.𑚶򟱃𞰘; [B2, B3, B5, B6, V5, V6]; xn--tc1ao37z.xn--6e2dw557azds2d; ; ; # 舌.𑚶
+xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; 𐶭舌.\u200C𑚶򟱃𞰘; [B1, B2, B3, C1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; ; # 舌.𑚶
+\u200CჀ-.𝟷ς𞴺ς; \u200CჀ-.1ς𞴺ς; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1ς𞴺ς
+\u200CჀ-.1ς𞴺ς; ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1ς𞴺ς
+\u200Cⴠ-.1ς𞴺ς; ; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺ς
+\u200CჀ-.1Σ𞴺Σ; \u200CჀ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1σ𞴺σ
+\u200Cⴠ-.1σ𞴺σ; ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1σ𞴺σ
+\u200CჀ-.1σ𞴺Σ; \u200CჀ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1σ𞴺σ
+xn----z1g.xn--1-0mba52321c; Ⴠ-.1σ𞴺σ; [B1, B6, V3, V6]; xn----z1g.xn--1-0mba52321c; ; ; # Ⴠ-.1σ𞴺σ
+xn----z1g168i.xn--1-0mba52321c; \u200CჀ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; ; # Ⴠ-.1σ𞴺σ
+xn----2ws.xn--1-0mba52321c; ⴠ-.1σ𞴺σ; [B1, B6, V3]; xn----2ws.xn--1-0mba52321c; ; ; # ⴠ-.1σ𞴺σ
+xn----rgn530d.xn--1-0mba52321c; \u200Cⴠ-.1σ𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; ; # ⴠ-.1σ𞴺σ
+\u200CჀ-.1ς𞴺Σ; \u200CჀ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1ς𞴺σ
+\u200Cⴠ-.1ς𞴺σ; ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺σ
+xn----rgn530d.xn--1-ymbd52321c; \u200Cⴠ-.1ς𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; ; # ⴠ-.1ς𞴺σ
+xn----z1g168i.xn--1-ymbd52321c; \u200CჀ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; ; # Ⴠ-.1ς𞴺σ
+xn----rgn530d.xn--1-ymba92321c; \u200Cⴠ-.1ς𞴺ς; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; ; # ⴠ-.1ς𞴺ς
+xn----z1g168i.xn--1-ymba92321c; \u200CჀ-.1ς𞴺ς; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; ; # Ⴠ-.1ς𞴺ς
+\u200Cⴠ-.𝟷ς𞴺ς; \u200Cⴠ-.1ς𞴺ς; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺ς
+\u200CჀ-.𝟷Σ𞴺Σ; \u200CჀ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1σ𞴺σ
+\u200Cⴠ-.𝟷σ𞴺σ; \u200Cⴠ-.1σ𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1σ𞴺σ
+\u200CჀ-.𝟷σ𞴺Σ; \u200CჀ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1σ𞴺σ
+\u200CჀ-.𝟷ς𞴺Σ; \u200CჀ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, V3, V6] # Ⴠ-.1ς𞴺σ
+\u200Cⴠ-.𝟷ς𞴺σ; \u200Cⴠ-.1ς𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺σ
+𑲘󠄒𓑡。𝟪Ⴜ; 𑲘𓑡.8Ⴜ; [V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
+𑲘󠄒𓑡。8Ⴜ; 𑲘𓑡.8Ⴜ; [V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
+𑲘󠄒𓑡。8ⴜ; 𑲘𓑡.8ⴜ; [V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
+xn--7m3d291b.xn--8-vws; 𑲘𓑡.8ⴜ; [V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
+xn--7m3d291b.xn--8-s1g; 𑲘𓑡.8Ⴜ; [V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
+𑲘󠄒𓑡。𝟪ⴜ; 𑲘𓑡.8ⴜ; [V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
+䪏\u06AB\u07E0\u0941。뭕ᢝ\u17B9; 䪏\u06AB\u07E0\u0941.뭕ᢝ\u17B9; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+䪏\u06AB\u07E0\u0941。뭕ᢝ\u17B9; 䪏\u06AB\u07E0\u0941.뭕ᢝ\u17B9; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+䪏\u06AB\u07E0\u0941。뭕ᢝ\u17B9; 䪏\u06AB\u07E0\u0941.뭕ᢝ\u17B9; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+䪏\u06AB\u07E0\u0941。뭕ᢝ\u17B9; 䪏\u06AB\u07E0\u0941.뭕ᢝ\u17B9; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+xn--ekb23dj4at01n.xn--43e96bh910b; 䪏\u06AB\u07E0\u0941.뭕ᢝ\u17B9; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+\u1BAB。🂉󠁰; \u1BAB.🂉󠁰; [V5, V6]; xn--zxf.xn--fx7ho0250c; ; ; # ᮫.🂉
+\u1BAB。🂉󠁰; \u1BAB.🂉󠁰; [V5, V6]; xn--zxf.xn--fx7ho0250c; ; ; # ᮫.🂉
+xn--zxf.xn--fx7ho0250c; \u1BAB.🂉󠁰; [V5, V6]; xn--zxf.xn--fx7ho0250c; ; ; # ᮫.🂉
+󩎃\u0AC4。ς\u200D𐹮𑈵; 󩎃\u0AC4.ς\u200D𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--3xa006lzo7nsfd; ; xn--dfc53161q.xn--4xa8467k5mc; [B5, V6] # ૄ.ς𐹮𑈵
+󩎃\u0AC4。Σ\u200D𐹮𑈵; 󩎃\u0AC4.σ\u200D𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--4xa895lzo7nsfd; ; xn--dfc53161q.xn--4xa8467k5mc; [B5, V6] # ૄ.σ𐹮𑈵
+󩎃\u0AC4。σ\u200D𐹮𑈵; 󩎃\u0AC4.σ\u200D𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--4xa895lzo7nsfd; ; xn--dfc53161q.xn--4xa8467k5mc; [B5, V6] # ૄ.σ𐹮𑈵
+xn--dfc53161q.xn--4xa8467k5mc; 󩎃\u0AC4.σ𐹮𑈵; [B5, V6]; xn--dfc53161q.xn--4xa8467k5mc; ; ; # ૄ.σ𐹮𑈵
+xn--dfc53161q.xn--4xa895lzo7nsfd; 󩎃\u0AC4.σ\u200D𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--4xa895lzo7nsfd; ; ; # ૄ.σ𐹮𑈵
+xn--dfc53161q.xn--3xa006lzo7nsfd; 󩎃\u0AC4.ς\u200D𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--3xa006lzo7nsfd; ; ; # ૄ.ς𐹮𑈵
+𐫀ᡂ𑜫.𑘿; 𐫀ᡂ𑜫.𑘿; [B1, B2, B3, V5]; xn--17e9625js1h.xn--sb2d; ; ; # 𐫀ᡂ𑜫.𑘿
+𐫀ᡂ𑜫.𑘿; ; [B1, B2, B3, V5]; xn--17e9625js1h.xn--sb2d; ; ; # 𐫀ᡂ𑜫.𑘿
+xn--17e9625js1h.xn--sb2d; 𐫀ᡂ𑜫.𑘿; [B1, B2, B3, V5]; xn--17e9625js1h.xn--sb2d; ; ; # 𐫀ᡂ𑜫.𑘿
+󬚶󸋖򖩰-。\u200C; 󬚶󸋖򖩰-.\u200C; [C1, V3, V6]; xn----7i12hu122k9ire.xn--0ug; ; xn----7i12hu122k9ire.; [V3, V6] # -.
+xn----7i12hu122k9ire.; 󬚶󸋖򖩰-.; [V3, V6]; xn----7i12hu122k9ire.; ; ; # -.
+xn----7i12hu122k9ire.xn--0ug; 󬚶󸋖򖩰-.\u200C; [C1, V3, V6]; xn----7i12hu122k9ire.xn--0ug; ; ; # -.
+𐹣.\u07C2; 𐹣.\u07C2; [B1]; xn--bo0d.xn--dsb; ; ; # 𐹣.߂
+𐹣.\u07C2; ; [B1]; xn--bo0d.xn--dsb; ; ; # 𐹣.߂
+xn--bo0d.xn--dsb; 𐹣.\u07C2; [B1]; xn--bo0d.xn--dsb; ; ; # 𐹣.߂
+-\u07E1。Ↄ; -\u07E1.Ↄ; [B1, V3, V6]; xn----8cd.xn--q5g; ; ; # -ߡ.Ↄ
+-\u07E1。Ↄ; -\u07E1.Ↄ; [B1, V3, V6]; xn----8cd.xn--q5g; ; ; # -ߡ.Ↄ
+-\u07E1。ↄ; -\u07E1.ↄ; [B1, V3]; xn----8cd.xn--r5g; ; ; # -ߡ.ↄ
+xn----8cd.xn--r5g; -\u07E1.ↄ; [B1, V3]; xn----8cd.xn--r5g; ; ; # -ߡ.ↄ
+xn----8cd.xn--q5g; -\u07E1.Ↄ; [B1, V3, V6]; xn----8cd.xn--q5g; ; ; # -ߡ.Ↄ
+-\u07E1。ↄ; -\u07E1.ↄ; [B1, V3]; xn----8cd.xn--r5g; ; ; # -ߡ.ↄ
+\u200D-︒󠄄。ß哑\u200C𐵿; \u200D-︒.ß哑\u200C𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--zca670n5f0binyk; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, V3, V6] # -︒.ß哑
+\u200D-。󠄄。ß哑\u200C𐵿; \u200D-..ß哑\u200C𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--zca670n5f0binyk; [B1, B5, B6, C1, C2, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, V3, V6, A4_2] # -..ß哑
+\u200D-。󠄄。SS哑\u200C𐵿; \u200D-..ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, V3, V6, A4_2] # -..ss哑
+\u200D-。󠄄。ss哑\u200C𐵿; \u200D-..ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, V3, V6, A4_2] # -..ss哑
+\u200D-。󠄄。Ss哑\u200C𐵿; \u200D-..ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, V3, V6, A4_2] # -..ss哑
+-..xn--ss-h46c5711e; -..ss哑𐵿; [B1, B5, B6, V3, V6, X4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, V3, V6, A4_2]; ; # -..ss哑
+xn----tgn..xn--ss-k1ts75zb8ym; \u200D-..ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, V3, V6, A4_2]; ; # -..ss哑
+xn----tgn..xn--zca670n5f0binyk; \u200D-..ß哑\u200C𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--zca670n5f0binyk; [B1, B5, B6, C1, C2, V3, V6, A4_2]; ; # -..ß哑
+\u200D-︒󠄄。SS哑\u200C𐵿; \u200D-︒.ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, V3, V6] # -︒.ss哑
+\u200D-︒󠄄。ss哑\u200C𐵿; \u200D-︒.ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, V3, V6] # -︒.ss哑
+\u200D-︒󠄄。Ss哑\u200C𐵿; \u200D-︒.ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, V3, V6] # -︒.ss哑
+xn----o89h.xn--ss-h46c5711e; -︒.ss哑𐵿; [B1, B5, B6, V3, V6]; xn----o89h.xn--ss-h46c5711e; ; ; # -︒.ss哑
+xn----tgnt341h.xn--ss-k1ts75zb8ym; \u200D-︒.ss哑\u200C𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; ; # -︒.ss哑
+xn----tgnt341h.xn--zca670n5f0binyk; \u200D-︒.ß哑\u200C𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--zca670n5f0binyk; ; ; # -︒.ß哑
+︒.\uFE2F𑑂; ︒.𑑂\uFE2F; [V5, V6]; xn--y86c.xn--s96cu30b; ; ; # ︒.𑑂︯
+︒.𑑂\uFE2F; ︒.𑑂\uFE2F; [V5, V6]; xn--y86c.xn--s96cu30b; ; ; # ︒.𑑂︯
+。.𑑂\uFE2F; ..𑑂\uFE2F; [V5, X4_2]; ..xn--s96cu30b; [V5, A4_2]; ; # ..𑑂︯
+..xn--s96cu30b; ..𑑂\uFE2F; [V5, X4_2]; ..xn--s96cu30b; [V5, A4_2]; ; # ..𑑂︯
+xn--y86c.xn--s96cu30b; ︒.𑑂\uFE2F; [V5, V6]; xn--y86c.xn--s96cu30b; ; ; # ︒.𑑂︯
+\uA92C。\u200D; \uA92C.\u200D; [C2, V5]; xn--zi9a.xn--1ug; ; xn--zi9a.; [V5] # ꤬.
+xn--zi9a.; \uA92C.; [V5]; xn--zi9a.; ; ; # ꤬.
+xn--zi9a.xn--1ug; \uA92C.\u200D; [C2, V5]; xn--zi9a.xn--1ug; ; ; # ꤬.
+\u200D󠸡。\uFCD7; \u200D󠸡.\u0647\u062C; [B1, C2, V6]; xn--1ug80651l.xn--rgb7c; ; xn--d356e.xn--rgb7c; [B1, V6] # .هج
+\u200D󠸡。\u0647\u062C; \u200D󠸡.\u0647\u062C; [B1, C2, V6]; xn--1ug80651l.xn--rgb7c; ; xn--d356e.xn--rgb7c; [B1, V6] # .هج
+xn--d356e.xn--rgb7c; 󠸡.\u0647\u062C; [B1, V6]; xn--d356e.xn--rgb7c; ; ; # .هج
+xn--1ug80651l.xn--rgb7c; \u200D󠸡.\u0647\u062C; [B1, C2, V6]; xn--1ug80651l.xn--rgb7c; ; ; # .هج
+-Ⴄ𝟢\u0663.𑍴ς; -Ⴄ0\u0663.𑍴ς; [B1, V3, V5, V6]; xn---0-iyd216h.xn--3xa1220l; ; xn---0-iyd216h.xn--4xa9120l; # -Ⴄ0٣.𑍴ς
+-Ⴄ0\u0663.𑍴ς; ; [B1, V3, V5, V6]; xn---0-iyd216h.xn--3xa1220l; ; xn---0-iyd216h.xn--4xa9120l; # -Ⴄ0٣.𑍴ς
+-ⴄ0\u0663.𑍴ς; ; [B1, V3, V5]; xn---0-iyd8660b.xn--3xa1220l; ; xn---0-iyd8660b.xn--4xa9120l; # -ⴄ0٣.𑍴ς
+-Ⴄ0\u0663.𑍴Σ; -Ⴄ0\u0663.𑍴σ; [B1, V3, V5, V6]; xn---0-iyd216h.xn--4xa9120l; ; ; # -Ⴄ0٣.𑍴σ
+-ⴄ0\u0663.𑍴σ; ; [B1, V3, V5]; xn---0-iyd8660b.xn--4xa9120l; ; ; # -ⴄ0٣.𑍴σ
+xn---0-iyd8660b.xn--4xa9120l; -ⴄ0\u0663.𑍴σ; [B1, V3, V5]; xn---0-iyd8660b.xn--4xa9120l; ; ; # -ⴄ0٣.𑍴σ
+xn---0-iyd216h.xn--4xa9120l; -Ⴄ0\u0663.𑍴σ; [B1, V3, V5, V6]; xn---0-iyd216h.xn--4xa9120l; ; ; # -Ⴄ0٣.𑍴σ
+xn---0-iyd8660b.xn--3xa1220l; -ⴄ0\u0663.𑍴ς; [B1, V3, V5]; xn---0-iyd8660b.xn--3xa1220l; ; ; # -ⴄ0٣.𑍴ς
+xn---0-iyd216h.xn--3xa1220l; -Ⴄ0\u0663.𑍴ς; [B1, V3, V5, V6]; xn---0-iyd216h.xn--3xa1220l; ; ; # -Ⴄ0٣.𑍴ς
+-ⴄ𝟢\u0663.𑍴ς; -ⴄ0\u0663.𑍴ς; [B1, V3, V5]; xn---0-iyd8660b.xn--3xa1220l; ; xn---0-iyd8660b.xn--4xa9120l; # -ⴄ0٣.𑍴ς
+-Ⴄ𝟢\u0663.𑍴Σ; -Ⴄ0\u0663.𑍴σ; [B1, V3, V5, V6]; xn---0-iyd216h.xn--4xa9120l; ; ; # -Ⴄ0٣.𑍴σ
+-ⴄ𝟢\u0663.𑍴σ; -ⴄ0\u0663.𑍴σ; [B1, V3, V5]; xn---0-iyd8660b.xn--4xa9120l; ; ; # -ⴄ0٣.𑍴σ
+󦈄。-; 󦈄.-; [V3, V6]; xn--xm38e.-; ; ; # .-
+xn--xm38e.-; 󦈄.-; [V3, V6]; xn--xm38e.-; ; ; # .-
+⋠𐋮.򶈮\u0F18ß≯; ⋠𐋮.򶈮\u0F18ß≯; [V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+≼\u0338𐋮.򶈮\u0F18ß>\u0338; ⋠𐋮.򶈮\u0F18ß≯; [V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+⋠𐋮.򶈮\u0F18ß≯; ; [V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+≼\u0338𐋮.򶈮\u0F18ß>\u0338; ⋠𐋮.򶈮\u0F18ß≯; [V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+≼\u0338𐋮.򶈮\u0F18SS>\u0338; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮\u0F18SS≯; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮\u0F18ss≯; ; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+≼\u0338𐋮.򶈮\u0F18ss>\u0338; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+≼\u0338𐋮.򶈮\u0F18Ss>\u0338; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮\u0F18Ss≯; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+xn--pgh4639f.xn--ss-ifj426nle504a; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+xn--pgh4639f.xn--zca593eo6oc013y; ⋠𐋮.򶈮\u0F18ß≯; [V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; ; # ⋠𐋮.༘ß≯
+≼\u0338𐋮.򶈮\u0F18SS>\u0338; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮\u0F18SS≯; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮\u0F18ss≯; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+≼\u0338𐋮.򶈮\u0F18ss>\u0338; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+≼\u0338𐋮.򶈮\u0F18Ss>\u0338; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮\u0F18Ss≯; ⋠𐋮.򶈮\u0F18ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+1𐋸\u0664。󠢮\uFBA4񷝊; 1𐋸\u0664.󠢮\u06C0񷝊; [B1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+1𐋸\u0664。󠢮\u06C0񷝊; 1𐋸\u0664.󠢮\u06C0񷝊; [B1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+1𐋸\u0664。󠢮\u06D5\u0654񷝊; 1𐋸\u0664.󠢮\u06C0񷝊; [B1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+xn--1-hqc3905q.xn--zkb83268gqee4a; 1𐋸\u0664.󠢮\u06C0񷝊; [B1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+儭-。𐹴Ⴢ񥳠\u200C; 儭-.𐹴Ⴢ񥳠\u200C; [B1, B6, C1, V3, V6]; xn----gz7a.xn--6nd249ejl4pusr7b; ; xn----gz7a.xn--6nd5001kyw98a; [B1, B6, V3, V6] # 儭-.𐹴Ⴢ
+儭-。𐹴Ⴢ񥳠\u200C; 儭-.𐹴Ⴢ񥳠\u200C; [B1, B6, C1, V3, V6]; xn----gz7a.xn--6nd249ejl4pusr7b; ; xn----gz7a.xn--6nd5001kyw98a; [B1, B6, V3, V6] # 儭-.𐹴Ⴢ
+儭-。𐹴ⴢ񥳠\u200C; 儭-.𐹴ⴢ񥳠\u200C; [B1, B6, C1, V3, V6]; xn----gz7a.xn--0ug472cfq0pus98b; ; xn----gz7a.xn--qlj9223eywx0b; [B1, B6, V3, V6] # 儭-.𐹴ⴢ
+xn----gz7a.xn--qlj9223eywx0b; 儭-.𐹴ⴢ񥳠; [B1, B6, V3, V6]; xn----gz7a.xn--qlj9223eywx0b; ; ; # 儭-.𐹴ⴢ
+xn----gz7a.xn--0ug472cfq0pus98b; 儭-.𐹴ⴢ񥳠\u200C; [B1, B6, C1, V3, V6]; xn----gz7a.xn--0ug472cfq0pus98b; ; ; # 儭-.𐹴ⴢ
+xn----gz7a.xn--6nd5001kyw98a; 儭-.𐹴Ⴢ񥳠; [B1, B6, V3, V6]; xn----gz7a.xn--6nd5001kyw98a; ; ; # 儭-.𐹴Ⴢ
+xn----gz7a.xn--6nd249ejl4pusr7b; 儭-.𐹴Ⴢ񥳠\u200C; [B1, B6, C1, V3, V6]; xn----gz7a.xn--6nd249ejl4pusr7b; ; ; # 儭-.𐹴Ⴢ
+儭-。𐹴ⴢ񥳠\u200C; 儭-.𐹴ⴢ񥳠\u200C; [B1, B6, C1, V3, V6]; xn----gz7a.xn--0ug472cfq0pus98b; ; xn----gz7a.xn--qlj9223eywx0b; [B1, B6, V3, V6] # 儭-.𐹴ⴢ
+𝟺𐋷\u06B9.𞤭򿍡; 4𐋷\u06B9.𞤭򿍡; [B1, B2, B3, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+4𐋷\u06B9.𞤭򿍡; ; [B1, B2, B3, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+4𐋷\u06B9.𞤋򿍡; 4𐋷\u06B9.𞤭򿍡; [B1, B2, B3, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+xn--4-cvc5384q.xn--le6hi7322b; 4𐋷\u06B9.𞤭򿍡; [B1, B2, B3, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+𝟺𐋷\u06B9.𞤋򿍡; 4𐋷\u06B9.𞤭򿍡; [B1, B2, B3, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+≯-ꡋ𑲣.⒈𐹭; ; [B1, V6]; xn----ogox061d5i8d.xn--tsh0666f; ; ; # ≯-ꡋ𑲣.⒈𐹭
+>\u0338-ꡋ𑲣.⒈𐹭; ≯-ꡋ𑲣.⒈𐹭; [B1, V6]; xn----ogox061d5i8d.xn--tsh0666f; ; ; # ≯-ꡋ𑲣.⒈𐹭
+≯-ꡋ𑲣.1.𐹭; ; [B1]; xn----ogox061d5i8d.1.xn--lo0d; ; ; # ≯-ꡋ𑲣.1.𐹭
+>\u0338-ꡋ𑲣.1.𐹭; ≯-ꡋ𑲣.1.𐹭; [B1]; xn----ogox061d5i8d.1.xn--lo0d; ; ; # ≯-ꡋ𑲣.1.𐹭
+xn----ogox061d5i8d.1.xn--lo0d; ≯-ꡋ𑲣.1.𐹭; [B1]; xn----ogox061d5i8d.1.xn--lo0d; ; ; # ≯-ꡋ𑲣.1.𐹭
+xn----ogox061d5i8d.xn--tsh0666f; ≯-ꡋ𑲣.⒈𐹭; [B1, V6]; xn----ogox061d5i8d.xn--tsh0666f; ; ; # ≯-ꡋ𑲣.⒈𐹭
+\u0330.󰜱蚀; \u0330.󰜱蚀; [V5, V6]; xn--xta.xn--e91aw9417e; ; ; # ̰.蚀
+\u0330.󰜱蚀; ; [V5, V6]; xn--xta.xn--e91aw9417e; ; ; # ̰.蚀
+xn--xta.xn--e91aw9417e; \u0330.󰜱蚀; [V5, V6]; xn--xta.xn--e91aw9417e; ; ; # ̰.蚀
+\uFB39Ⴘ.𞡼𑇀ß\u20D7; \u05D9\u05BCႸ.𞡼𑇀ß\u20D7; [B2, B3, V6]; xn--kdb1d867b.xn--zca284nhg9nrrxg; ; xn--kdb1d867b.xn--ss-yju5690ken9h; # יּႸ.𞡼𑇀ß⃗
+\u05D9\u05BCႸ.𞡼𑇀ß\u20D7; ; [B2, B3, V6]; xn--kdb1d867b.xn--zca284nhg9nrrxg; ; xn--kdb1d867b.xn--ss-yju5690ken9h; # יּႸ.𞡼𑇀ß⃗
+\u05D9\u05BCⴘ.𞡼𑇀ß\u20D7; ; [B2, B3]; xn--kdb1d278n.xn--zca284nhg9nrrxg; ; xn--kdb1d278n.xn--ss-yju5690ken9h; # יּⴘ.𞡼𑇀ß⃗
+\u05D9\u05BCႸ.𞡼𑇀SS\u20D7; \u05D9\u05BCႸ.𞡼𑇀ss\u20D7; [B2, B3, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+\u05D9\u05BCⴘ.𞡼𑇀ss\u20D7; ; [B2, B3]; xn--kdb1d278n.xn--ss-yju5690ken9h; ; ; # יּⴘ.𞡼𑇀ss⃗
+xn--kdb1d278n.xn--ss-yju5690ken9h; \u05D9\u05BCⴘ.𞡼𑇀ss\u20D7; [B2, B3]; xn--kdb1d278n.xn--ss-yju5690ken9h; ; ; # יּⴘ.𞡼𑇀ss⃗
+xn--kdb1d867b.xn--ss-yju5690ken9h; \u05D9\u05BCႸ.𞡼𑇀ss\u20D7; [B2, B3, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+xn--kdb1d278n.xn--zca284nhg9nrrxg; \u05D9\u05BCⴘ.𞡼𑇀ß\u20D7; [B2, B3]; xn--kdb1d278n.xn--zca284nhg9nrrxg; ; ; # יּⴘ.𞡼𑇀ß⃗
+xn--kdb1d867b.xn--zca284nhg9nrrxg; \u05D9\u05BCႸ.𞡼𑇀ß\u20D7; [B2, B3, V6]; xn--kdb1d867b.xn--zca284nhg9nrrxg; ; ; # יּႸ.𞡼𑇀ß⃗
+\uFB39ⴘ.𞡼𑇀ß\u20D7; \u05D9\u05BCⴘ.𞡼𑇀ß\u20D7; [B2, B3]; xn--kdb1d278n.xn--zca284nhg9nrrxg; ; xn--kdb1d278n.xn--ss-yju5690ken9h; # יּⴘ.𞡼𑇀ß⃗
+\uFB39Ⴘ.𞡼𑇀SS\u20D7; \u05D9\u05BCႸ.𞡼𑇀ss\u20D7; [B2, B3, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+\uFB39ⴘ.𞡼𑇀ss\u20D7; \u05D9\u05BCⴘ.𞡼𑇀ss\u20D7; [B2, B3]; xn--kdb1d278n.xn--ss-yju5690ken9h; ; ; # יּⴘ.𞡼𑇀ss⃗
+\u05D9\u05BCႸ.𞡼𑇀ss\u20D7; ; [B2, B3, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+\uFB39Ⴘ.𞡼𑇀ss\u20D7; \u05D9\u05BCႸ.𞡼𑇀ss\u20D7; [B2, B3, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+\u1BA3𐹰򁱓。凬; \u1BA3𐹰򁱓.凬; [B1, V5, V6]; xn--rxfz314ilg20c.xn--t9q; ; ; # ᮣ𐹰.凬
+\u1BA3𐹰򁱓。凬; \u1BA3𐹰򁱓.凬; [B1, V5, V6]; xn--rxfz314ilg20c.xn--t9q; ; ; # ᮣ𐹰.凬
+xn--rxfz314ilg20c.xn--t9q; \u1BA3𐹰򁱓.凬; [B1, V5, V6]; xn--rxfz314ilg20c.xn--t9q; ; ; # ᮣ𐹰.凬
+🢟🄈\u200Dꡎ。\u0F84; 🢟🄈\u200Dꡎ.\u0F84; [C2, V5, V6]; xn--1ug4874cfd0kbmg.xn--3ed; ; xn--nc9aq743ds0e.xn--3ed; [V5, V6] # 🢟🄈ꡎ.྄
+🢟7,\u200Dꡎ。\u0F84; 🢟7,\u200Dꡎ.\u0F84; [C2, V5, V6]; xn--7,-n1t0654eqo3o.xn--3ed; ; xn--7,-gh9hg322i.xn--3ed; [V5, V6] # 🢟7,ꡎ.྄
+xn--7,-gh9hg322i.xn--3ed; 🢟7,ꡎ.\u0F84; [V5, V6]; xn--7,-gh9hg322i.xn--3ed; ; ; # 🢟7,ꡎ.྄
+xn--7,-n1t0654eqo3o.xn--3ed; 🢟7,\u200Dꡎ.\u0F84; [C2, V5, V6]; xn--7,-n1t0654eqo3o.xn--3ed; ; ; # 🢟7,ꡎ.྄
+xn--nc9aq743ds0e.xn--3ed; 🢟🄈ꡎ.\u0F84; [V5, V6]; xn--nc9aq743ds0e.xn--3ed; ; ; # 🢟🄈ꡎ.྄
+xn--1ug4874cfd0kbmg.xn--3ed; 🢟🄈\u200Dꡎ.\u0F84; [C2, V5, V6]; xn--1ug4874cfd0kbmg.xn--3ed; ; ; # 🢟🄈ꡎ.྄
+ꡔ。\u1039ᢇ; ꡔ.\u1039ᢇ; [V5]; xn--tc9a.xn--9jd663b; ; ; # ꡔ.္ᢇ
+xn--tc9a.xn--9jd663b; ꡔ.\u1039ᢇ; [V5]; xn--tc9a.xn--9jd663b; ; ; # ꡔ.္ᢇ
+\u20EB≮.𝨖; ; [V5]; xn--e1g71d.xn--772h; ; ; # ⃫≮.𝨖
+\u20EB<\u0338.𝨖; \u20EB≮.𝨖; [V5]; xn--e1g71d.xn--772h; ; ; # ⃫≮.𝨖
+xn--e1g71d.xn--772h; \u20EB≮.𝨖; [V5]; xn--e1g71d.xn--772h; ; ; # ⃫≮.𝨖
+Ⴢ≯褦.ᠪ\u07EAႾ\u0767; Ⴢ≯褦.ᠪ\u07EAႾ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+Ⴢ>\u0338褦.ᠪ\u07EAႾ\u0767; Ⴢ≯褦.ᠪ\u07EAႾ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+Ⴢ≯褦.ᠪ\u07EAႾ\u0767; ; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+Ⴢ>\u0338褦.ᠪ\u07EAႾ\u0767; Ⴢ≯褦.ᠪ\u07EAႾ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+ⴢ>\u0338褦.ᠪ\u07EAⴞ\u0767; ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+ⴢ≯褦.ᠪ\u07EAⴞ\u0767; ; [B5, B6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ≯褦.ᠪ\u07EAⴞ\u0767; ; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ>\u0338褦.ᠪ\u07EAⴞ\u0767; Ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+xn--6nd461g478e.xn--rpb5x392bcyt; Ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+xn--hdh433bev8e.xn--rpb5x392bcyt; ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+xn--6nd461g478e.xn--rpb5x49td2h; Ⴢ≯褦.ᠪ\u07EAႾ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+ⴢ>\u0338褦.ᠪ\u07EAⴞ\u0767; ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+ⴢ≯褦.ᠪ\u07EAⴞ\u0767; ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ≯褦.ᠪ\u07EAⴞ\u0767; Ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ>\u0338褦.ᠪ\u07EAⴞ\u0767; Ⴢ≯褦.ᠪ\u07EAⴞ\u0767; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+򊉆󠆒\u200C\uA953。𞤙\u067Bꡘ; 򊉆\u200C\uA953.𞤻\u067Bꡘ; [B2, B3, C1, V6]; xn--0ug8815chtz0e.xn--0ib8893fegvj; ; xn--3j9al6189a.xn--0ib8893fegvj; [B2, B3, V6] # ꥓.𞤻ٻꡘ
+򊉆󠆒\u200C\uA953。𞤻\u067Bꡘ; 򊉆\u200C\uA953.𞤻\u067Bꡘ; [B2, B3, C1, V6]; xn--0ug8815chtz0e.xn--0ib8893fegvj; ; xn--3j9al6189a.xn--0ib8893fegvj; [B2, B3, V6] # ꥓.𞤻ٻꡘ
+xn--3j9al6189a.xn--0ib8893fegvj; 򊉆\uA953.𞤻\u067Bꡘ; [B2, B3, V6]; xn--3j9al6189a.xn--0ib8893fegvj; ; ; # ꥓.𞤻ٻꡘ
+xn--0ug8815chtz0e.xn--0ib8893fegvj; 򊉆\u200C\uA953.𞤻\u067Bꡘ; [B2, B3, C1, V6]; xn--0ug8815chtz0e.xn--0ib8893fegvj; ; ; # ꥓.𞤻ٻꡘ
+\u200C.≯; ; [C1]; xn--0ug.xn--hdh; ; .xn--hdh; [A4_2] # .≯
+\u200C.>\u0338; \u200C.≯; [C1]; xn--0ug.xn--hdh; ; .xn--hdh; [A4_2] # .≯
+.xn--hdh; .≯; [X4_2]; .xn--hdh; [A4_2]; ; # .≯
+xn--0ug.xn--hdh; \u200C.≯; [C1]; xn--0ug.xn--hdh; ; ; # .≯
+𰅧񣩠-.\uABED-悜; 𰅧񣩠-.\uABED-悜; [V3, V5, V6]; xn----7m53aj640l.xn----8f4br83t; ; ; # 𰅧-.꯭-悜
+𰅧񣩠-.\uABED-悜; ; [V3, V5, V6]; xn----7m53aj640l.xn----8f4br83t; ; ; # 𰅧-.꯭-悜
+xn----7m53aj640l.xn----8f4br83t; 𰅧񣩠-.\uABED-悜; [V3, V5, V6]; xn----7m53aj640l.xn----8f4br83t; ; ; # 𰅧-.꯭-悜
+ᡉ𶓧⬞ᢜ.-\u200D𞣑\u202E; ; [C2, V3, V6]; xn--87e0ol04cdl39e.xn----ugn5e3763s; ; xn--87e0ol04cdl39e.xn----qinu247r; [V3, V6] # ᡉ⬞ᢜ.-𞣑
+xn--87e0ol04cdl39e.xn----qinu247r; ᡉ𶓧⬞ᢜ.-𞣑\u202E; [V3, V6]; xn--87e0ol04cdl39e.xn----qinu247r; ; ; # ᡉ⬞ᢜ.-𞣑
+xn--87e0ol04cdl39e.xn----ugn5e3763s; ᡉ𶓧⬞ᢜ.-\u200D𞣑\u202E; [C2, V3, V6]; xn--87e0ol04cdl39e.xn----ugn5e3763s; ; ; # ᡉ⬞ᢜ.-𞣑
+⒐\u200C衃Ⴝ.\u0682Ⴔ; ; [B1, B2, B3, C1, V6]; xn--1nd159ecmd785k.xn--7ib433c; ; xn--1nd362hy16e.xn--7ib433c; [B1, B2, B3, V6] # ⒐衃Ⴝ.ڂႴ
+9.\u200C衃Ⴝ.\u0682Ⴔ; ; [B1, B2, B3, C1, V6]; 9.xn--1nd159e1y2f.xn--7ib433c; ; 9.xn--1nd9032d.xn--7ib433c; [B1, B2, B3, V6] # 9.衃Ⴝ.ڂႴ
+9.\u200C衃ⴝ.\u0682ⴔ; ; [B1, B2, B3, C1]; 9.xn--0ug862cbm5e.xn--7ib268q; ; 9.xn--llj1920a.xn--7ib268q; [B1, B2, B3] # 9.衃ⴝ.ڂⴔ
+9.\u200C衃Ⴝ.\u0682ⴔ; ; [B1, B2, B3, C1, V6]; 9.xn--1nd159e1y2f.xn--7ib268q; ; 9.xn--1nd9032d.xn--7ib268q; [B1, B2, B3, V6] # 9.衃Ⴝ.ڂⴔ
+9.xn--1nd9032d.xn--7ib268q; 9.衃Ⴝ.\u0682ⴔ; [B1, B2, B3, V6]; 9.xn--1nd9032d.xn--7ib268q; ; ; # 9.衃Ⴝ.ڂⴔ
+9.xn--1nd159e1y2f.xn--7ib268q; 9.\u200C衃Ⴝ.\u0682ⴔ; [B1, B2, B3, C1, V6]; 9.xn--1nd159e1y2f.xn--7ib268q; ; ; # 9.衃Ⴝ.ڂⴔ
+9.xn--llj1920a.xn--7ib268q; 9.衃ⴝ.\u0682ⴔ; [B1, B2, B3]; 9.xn--llj1920a.xn--7ib268q; ; ; # 9.衃ⴝ.ڂⴔ
+9.xn--0ug862cbm5e.xn--7ib268q; 9.\u200C衃ⴝ.\u0682ⴔ; [B1, B2, B3, C1]; 9.xn--0ug862cbm5e.xn--7ib268q; ; ; # 9.衃ⴝ.ڂⴔ
+9.xn--1nd9032d.xn--7ib433c; 9.衃Ⴝ.\u0682Ⴔ; [B1, B2, B3, V6]; 9.xn--1nd9032d.xn--7ib433c; ; ; # 9.衃Ⴝ.ڂႴ
+9.xn--1nd159e1y2f.xn--7ib433c; 9.\u200C衃Ⴝ.\u0682Ⴔ; [B1, B2, B3, C1, V6]; 9.xn--1nd159e1y2f.xn--7ib433c; ; ; # 9.衃Ⴝ.ڂႴ
+⒐\u200C衃ⴝ.\u0682ⴔ; ; [B1, B2, B3, C1, V6]; xn--0ugx0px1izu2h.xn--7ib268q; ; xn--1shy52abz3f.xn--7ib268q; [B1, B2, B3, V6] # ⒐衃ⴝ.ڂⴔ
+⒐\u200C衃Ⴝ.\u0682ⴔ; ; [B1, B2, B3, C1, V6]; xn--1nd159ecmd785k.xn--7ib268q; ; xn--1nd362hy16e.xn--7ib268q; [B1, B2, B3, V6] # ⒐衃Ⴝ.ڂⴔ
+xn--1nd362hy16e.xn--7ib268q; ⒐衃Ⴝ.\u0682ⴔ; [B1, B2, B3, V6]; xn--1nd362hy16e.xn--7ib268q; ; ; # ⒐衃Ⴝ.ڂⴔ
+xn--1nd159ecmd785k.xn--7ib268q; ⒐\u200C衃Ⴝ.\u0682ⴔ; [B1, B2, B3, C1, V6]; xn--1nd159ecmd785k.xn--7ib268q; ; ; # ⒐衃Ⴝ.ڂⴔ
+xn--1shy52abz3f.xn--7ib268q; ⒐衃ⴝ.\u0682ⴔ; [B1, B2, B3, V6]; xn--1shy52abz3f.xn--7ib268q; ; ; # ⒐衃ⴝ.ڂⴔ
+xn--0ugx0px1izu2h.xn--7ib268q; ⒐\u200C衃ⴝ.\u0682ⴔ; [B1, B2, B3, C1, V6]; xn--0ugx0px1izu2h.xn--7ib268q; ; ; # ⒐衃ⴝ.ڂⴔ
+xn--1nd362hy16e.xn--7ib433c; ⒐衃Ⴝ.\u0682Ⴔ; [B1, B2, B3, V6]; xn--1nd362hy16e.xn--7ib433c; ; ; # ⒐衃Ⴝ.ڂႴ
+xn--1nd159ecmd785k.xn--7ib433c; ⒐\u200C衃Ⴝ.\u0682Ⴔ; [B1, B2, B3, C1, V6]; xn--1nd159ecmd785k.xn--7ib433c; ; ; # ⒐衃Ⴝ.ڂႴ
+\u07E1\u200C。--⸬; \u07E1\u200C.--⸬; [B1, B3, C1, V3]; xn--8sb884j.xn-----iw2a; ; xn--8sb.xn-----iw2a; [B1, V3] # ߡ.--⸬
+xn--8sb.xn-----iw2a; \u07E1.--⸬; [B1, V3]; xn--8sb.xn-----iw2a; ; ; # ߡ.--⸬
+xn--8sb884j.xn-----iw2a; \u07E1\u200C.--⸬; [B1, B3, C1, V3]; xn--8sb884j.xn-----iw2a; ; ; # ߡ.--⸬
+𞥓.\u0718; 𞥓.\u0718; ; xn--of6h.xn--inb; ; ; # 𞥓.ܘ
+𞥓.\u0718; ; ; xn--of6h.xn--inb; ; ; # 𞥓.ܘ
+xn--of6h.xn--inb; 𞥓.\u0718; ; xn--of6h.xn--inb; ; ; # 𞥓.ܘ
+󠄽-.-\u0DCA; -.-\u0DCA; [V3]; -.xn----ptf; ; ; # -.-්
+󠄽-.-\u0DCA; -.-\u0DCA; [V3]; -.xn----ptf; ; ; # -.-්
+-.xn----ptf; -.-\u0DCA; [V3]; -.xn----ptf; ; ; # -.-්
+󠇝\u075B-.\u1927; \u075B-.\u1927; [B1, B3, V3, V5]; xn----k4c.xn--lff; ; ; # ݛ-.ᤧ
+xn----k4c.xn--lff; \u075B-.\u1927; [B1, B3, V3, V5]; xn----k4c.xn--lff; ; ; # ݛ-.ᤧ
+𞤴󠆹⦉𐹺.\uA806⒌󘤸; 𞤴⦉𐹺.\uA806⒌󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--xsh5029b6e77i; ; ; # 𞤴⦉𐹺.꠆⒌
+𞤴󠆹⦉𐹺.\uA8065.󘤸; 𞤴⦉𐹺.\uA8065.󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--5-w93e.xn--7b83e; ; ; # 𞤴⦉𐹺.꠆5.
+𞤒󠆹⦉𐹺.\uA8065.󘤸; 𞤴⦉𐹺.\uA8065.󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--5-w93e.xn--7b83e; ; ; # 𞤴⦉𐹺.꠆5.
+xn--fuix729epewf.xn--5-w93e.xn--7b83e; 𞤴⦉𐹺.\uA8065.󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--5-w93e.xn--7b83e; ; ; # 𞤴⦉𐹺.꠆5.
+𞤒󠆹⦉𐹺.\uA806⒌󘤸; 𞤴⦉𐹺.\uA806⒌󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--xsh5029b6e77i; ; ; # 𞤴⦉𐹺.꠆⒌
+xn--fuix729epewf.xn--xsh5029b6e77i; 𞤴⦉𐹺.\uA806⒌󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--xsh5029b6e77i; ; ; # 𞤴⦉𐹺.꠆⒌
+󠄸₀。𑖿\u200C𐦂\u200D; 0.𑖿\u200C𐦂\u200D; [B1, C2, V5]; 0.xn--0ugc8040p9hk; ; 0.xn--mn9cz2s; [B1, V5] # 0.𑖿𐦂
+󠄸0。𑖿\u200C𐦂\u200D; 0.𑖿\u200C𐦂\u200D; [B1, C2, V5]; 0.xn--0ugc8040p9hk; ; 0.xn--mn9cz2s; [B1, V5] # 0.𑖿𐦂
+0.xn--mn9cz2s; 0.𑖿𐦂; [B1, V5]; 0.xn--mn9cz2s; ; ; # 0.𑖿𐦂
+0.xn--0ugc8040p9hk; 0.𑖿\u200C𐦂\u200D; [B1, C2, V5]; 0.xn--0ugc8040p9hk; ; ; # 0.𑖿𐦂
+Ⴚ𐋸󠄄。𝟝ퟶ\u103A; Ⴚ𐋸.5ퟶ\u103A; [V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+Ⴚ𐋸󠄄。5ퟶ\u103A; Ⴚ𐋸.5ퟶ\u103A; [V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+ⴚ𐋸󠄄。5ퟶ\u103A; ⴚ𐋸.5ퟶ\u103A; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+xn--ilj2659d.xn--5-dug9054m; ⴚ𐋸.5ퟶ\u103A; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+ⴚ𐋸.5ퟶ\u103A; ; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+Ⴚ𐋸.5ퟶ\u103A; ; [V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+xn--ynd2415j.xn--5-dug9054m; Ⴚ𐋸.5ퟶ\u103A; [V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+ⴚ𐋸󠄄。𝟝ퟶ\u103A; ⴚ𐋸.5ퟶ\u103A; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+\u200D-ᠹ﹪.\u1DE1\u1922; ; [C2, V5, V6]; xn----c6j614b1z4v.xn--gff52t; ; xn----c6jx047j.xn--gff52t; [V3, V5, V6] # -ᠹ﹪.ᷡᤢ
+\u200D-ᠹ%.\u1DE1\u1922; ; [C2, V5, V6]; xn---%-u4oy48b.xn--gff52t; ; xn---%-u4o.xn--gff52t; [V3, V5, V6] # -ᠹ%.ᷡᤢ
+xn---%-u4o.xn--gff52t; -ᠹ%.\u1DE1\u1922; [V3, V5, V6]; xn---%-u4o.xn--gff52t; ; ; # -ᠹ%.ᷡᤢ
+xn---%-u4oy48b.xn--gff52t; \u200D-ᠹ%.\u1DE1\u1922; [C2, V5, V6]; xn---%-u4oy48b.xn--gff52t; ; ; # -ᠹ%.ᷡᤢ
+xn----c6jx047j.xn--gff52t; -ᠹ﹪.\u1DE1\u1922; [V3, V5, V6]; xn----c6jx047j.xn--gff52t; ; ; # -ᠹ﹪.ᷡᤢ
+xn----c6j614b1z4v.xn--gff52t; \u200D-ᠹ﹪.\u1DE1\u1922; [C2, V5, V6]; xn----c6j614b1z4v.xn--gff52t; ; ; # -ᠹ﹪.ᷡᤢ
+≠.ᠿ; ; ; xn--1ch.xn--y7e; ; ; # ≠.ᠿ
+=\u0338.ᠿ; ≠.ᠿ; ; xn--1ch.xn--y7e; ; ; # ≠.ᠿ
+xn--1ch.xn--y7e; ≠.ᠿ; ; xn--1ch.xn--y7e; ; ; # ≠.ᠿ
+\u0723\u05A3。㌪; \u0723\u05A3.ハイツ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+\u0723\u05A3。ハイツ; \u0723\u05A3.ハイツ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+xn--ucb18e.xn--eck4c5a; \u0723\u05A3.ハイツ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+\u0723\u05A3.ハイツ; ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+𞷥󠆀≮.\u2D7F-; 𞷥≮.\u2D7F-; [B1, B3, V3, V5, V6]; xn--gdhx802p.xn----i2s; ; ; # ≮.⵿-
+𞷥󠆀<\u0338.\u2D7F-; 𞷥≮.\u2D7F-; [B1, B3, V3, V5, V6]; xn--gdhx802p.xn----i2s; ; ; # ≮.⵿-
+xn--gdhx802p.xn----i2s; 𞷥≮.\u2D7F-; [B1, B3, V3, V5, V6]; xn--gdhx802p.xn----i2s; ; ; # ≮.⵿-
+₆榎򦖎\u0D4D。𞤅\u06ED\uFC5A󠮨; 6榎򦖎\u0D4D.𞤧\u06ED\u064A\u064A󠮨; [B1, B3, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+6榎򦖎\u0D4D。𞤅\u06ED\u064A\u064A󠮨; 6榎򦖎\u0D4D.𞤧\u06ED\u064A\u064A󠮨; [B1, B3, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+6榎򦖎\u0D4D。𞤧\u06ED\u064A\u064A󠮨; 6榎򦖎\u0D4D.𞤧\u06ED\u064A\u064A󠮨; [B1, B3, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; 6榎򦖎\u0D4D.𞤧\u06ED\u064A\u064A󠮨; [B1, B3, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+₆榎򦖎\u0D4D。𞤧\u06ED\uFC5A󠮨; 6榎򦖎\u0D4D.𞤧\u06ED\u064A\u064A󠮨; [B1, B3, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+𣩫.򌑲; 𣩫.򌑲; [V6]; xn--td3j.xn--4628b; ; ; # 𣩫.
+𣩫.򌑲; ; [V6]; xn--td3j.xn--4628b; ; ; # 𣩫.
+xn--td3j.xn--4628b; 𣩫.򌑲; [V6]; xn--td3j.xn--4628b; ; ; # 𣩫.
+\u200D︒。\u06B9\u200C; \u200D︒.\u06B9\u200C; [B1, B3, C1, C2, V6]; xn--1ug2658f.xn--skb080k; ; xn--y86c.xn--skb; [B1, V6] # ︒.ڹ
+xn--y86c.xn--skb; ︒.\u06B9; [B1, V6]; xn--y86c.xn--skb; ; ; # ︒.ڹ
+xn--1ug2658f.xn--skb080k; \u200D︒.\u06B9\u200C; [B1, B3, C1, C2, V6]; xn--1ug2658f.xn--skb080k; ; ; # ︒.ڹ
+xn--skb; \u06B9; ; xn--skb; ; ; # ڹ
+\u06B9; ; ; xn--skb; ; ; # ڹ
+𐹦\u200C𐹶。\u206D; 𐹦\u200C𐹶.\u206D; [B1, C1, V6]; xn--0ug4994goba.xn--sxg; ; xn--eo0d6a.xn--sxg; [B1, V6] # 𐹦𐹶.
+xn--eo0d6a.xn--sxg; 𐹦𐹶.\u206D; [B1, V6]; xn--eo0d6a.xn--sxg; ; ; # 𐹦𐹶.
+xn--0ug4994goba.xn--sxg; 𐹦\u200C𐹶.\u206D; [B1, C1, V6]; xn--0ug4994goba.xn--sxg; ; ; # 𐹦𐹶.
+\u0C4D𝨾\u05A9𝟭。-𑜨; \u0C4D𝨾\u05A91.-𑜨; [V3, V5]; xn--1-rfc312cdp45c.xn----nq0j; ; ; # ్𝨾֩1.-𑜨
+\u0C4D𝨾\u05A91。-𑜨; \u0C4D𝨾\u05A91.-𑜨; [V3, V5]; xn--1-rfc312cdp45c.xn----nq0j; ; ; # ్𝨾֩1.-𑜨
+xn--1-rfc312cdp45c.xn----nq0j; \u0C4D𝨾\u05A91.-𑜨; [V3, V5]; xn--1-rfc312cdp45c.xn----nq0j; ; ; # ్𝨾֩1.-𑜨
+򣿈。뙏; 򣿈.뙏; [V6]; xn--ph26c.xn--281b; ; ; # .뙏
+򣿈。뙏; 򣿈.뙏; [V6]; xn--ph26c.xn--281b; ; ; # .뙏
+xn--ph26c.xn--281b; 򣿈.뙏; [V6]; xn--ph26c.xn--281b; ; ; # .뙏
+񕨚󠄌󑽀ᡀ.\u08B6; 񕨚󑽀ᡀ.\u08B6; [V6]; xn--z7e98100evc01b.xn--czb; ; ; # ᡀ.ࢶ
+xn--z7e98100evc01b.xn--czb; 񕨚󑽀ᡀ.\u08B6; [V6]; xn--z7e98100evc01b.xn--czb; ; ; # ᡀ.ࢶ
+\u200D。񅁛; \u200D.񅁛; [C2, V6]; xn--1ug.xn--6x4u; ; .xn--6x4u; [V6, A4_2] # .
+\u200D。񅁛; \u200D.񅁛; [C2, V6]; xn--1ug.xn--6x4u; ; .xn--6x4u; [V6, A4_2] # .
+.xn--6x4u; .񅁛; [V6, X4_2]; .xn--6x4u; [V6, A4_2]; ; # .
+xn--1ug.xn--6x4u; \u200D.񅁛; [C2, V6]; xn--1ug.xn--6x4u; ; ; # .
+\u084B皥.-; \u084B皥.-; [B1, B2, B3, V3]; xn--9vb4167c.-; ; ; # ࡋ皥.-
+\u084B皥.-; ; [B1, B2, B3, V3]; xn--9vb4167c.-; ; ; # ࡋ皥.-
+xn--9vb4167c.-; \u084B皥.-; [B1, B2, B3, V3]; xn--9vb4167c.-; ; ; # ࡋ皥.-
+𐣸\u0315𐮇.⒈ꡦ; 𐣸\u0315𐮇.⒈ꡦ; [B1, V6]; xn--5sa9915kgvb.xn--tshw539b; ; ; # ̕𐮇.⒈ꡦ
+𐣸\u0315𐮇.1.ꡦ; ; [B1, V6]; xn--5sa9915kgvb.1.xn--cd9a; ; ; # ̕𐮇.1.ꡦ
+xn--5sa9915kgvb.1.xn--cd9a; 𐣸\u0315𐮇.1.ꡦ; [B1, V6]; xn--5sa9915kgvb.1.xn--cd9a; ; ; # ̕𐮇.1.ꡦ
+xn--5sa9915kgvb.xn--tshw539b; 𐣸\u0315𐮇.⒈ꡦ; [B1, V6]; xn--5sa9915kgvb.xn--tshw539b; ; ; # ̕𐮇.⒈ꡦ
+Ⴛ\u200C\u05A2\u200D。\uFFA0ā𐹦; Ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, V6] # Ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\uFFA0a\u0304𐹦; Ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, V6] # Ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\u1160ā𐹦; Ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, V6] # Ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\u1160a\u0304𐹦; Ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, V6] # Ⴛ֢.ā𐹦
+ⴛ\u200C\u05A2\u200D。\u1160a\u0304𐹦; ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda594fdn5q; ; xn--tcb323r.xn--yda594fdn5q; [B5, B6, V6] # ⴛ֢.ā𐹦
+ⴛ\u200C\u05A2\u200D。\u1160ā𐹦; ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda594fdn5q; ; xn--tcb323r.xn--yda594fdn5q; [B5, B6, V6] # ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\u1160Ā𐹦; Ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, V6] # Ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\u1160A\u0304𐹦; Ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, V6] # Ⴛ֢.ā𐹦
+xn--tcb597c.xn--yda594fdn5q; Ⴛ\u05A2.\u1160ā𐹦; [B5, B6, V6]; xn--tcb597c.xn--yda594fdn5q; ; ; # Ⴛ֢.ā𐹦
+xn--tcb597cdmmfa.xn--yda594fdn5q; Ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; ; # Ⴛ֢.ā𐹦
+xn--tcb323r.xn--yda594fdn5q; ⴛ\u05A2.\u1160ā𐹦; [B5, B6, V6]; xn--tcb323r.xn--yda594fdn5q; ; ; # ⴛ֢.ā𐹦
+xn--tcb736kea974k.xn--yda594fdn5q; ⴛ\u200C\u05A2\u200D.\u1160ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda594fdn5q; ; ; # ⴛ֢.ā𐹦
+ⴛ\u200C\u05A2\u200D。\uFFA0a\u0304𐹦; ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda9741khjj; ; xn--tcb323r.xn--yda9741khjj; [B5, B6, V6] # ⴛ֢.ā𐹦
+ⴛ\u200C\u05A2\u200D。\uFFA0ā𐹦; ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda9741khjj; ; xn--tcb323r.xn--yda9741khjj; [B5, B6, V6] # ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\uFFA0Ā𐹦; Ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, V6] # Ⴛ֢.ā𐹦
+Ⴛ\u200C\u05A2\u200D。\uFFA0A\u0304𐹦; Ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, V6] # Ⴛ֢.ā𐹦
+xn--tcb597c.xn--yda9741khjj; Ⴛ\u05A2.\uFFA0ā𐹦; [B5, B6, V6]; xn--tcb597c.xn--yda9741khjj; ; ; # Ⴛ֢.ā𐹦
+xn--tcb597cdmmfa.xn--yda9741khjj; Ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; ; # Ⴛ֢.ā𐹦
+xn--tcb323r.xn--yda9741khjj; ⴛ\u05A2.\uFFA0ā𐹦; [B5, B6, V6]; xn--tcb323r.xn--yda9741khjj; ; ; # ⴛ֢.ā𐹦
+xn--tcb736kea974k.xn--yda9741khjj; ⴛ\u200C\u05A2\u200D.\uFFA0ā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda9741khjj; ; ; # ⴛ֢.ā𐹦
+\uFFF9\u200C。曳⾑𐋰≯; \uFFF9\u200C.曳襾𐋰≯; [C1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [V6] # .曳襾𐋰≯
+\uFFF9\u200C。曳⾑𐋰>\u0338; \uFFF9\u200C.曳襾𐋰≯; [C1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [V6] # .曳襾𐋰≯
+\uFFF9\u200C。曳襾𐋰≯; \uFFF9\u200C.曳襾𐋰≯; [C1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [V6] # .曳襾𐋰≯
+\uFFF9\u200C。曳襾𐋰>\u0338; \uFFF9\u200C.曳襾𐋰≯; [C1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [V6] # .曳襾𐋰≯
+xn--vn7c.xn--hdh501y8wvfs5h; \uFFF9.曳襾𐋰≯; [V6]; xn--vn7c.xn--hdh501y8wvfs5h; ; ; # .曳襾𐋰≯
+xn--0ug2139f.xn--hdh501y8wvfs5h; \uFFF9\u200C.曳襾𐋰≯; [C1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; ; # .曳襾𐋰≯
+≯⒈。ß; ≯⒈.ß; [V6]; xn--hdh84f.xn--zca; ; xn--hdh84f.ss; # ≯⒈.ß
+>\u0338⒈。ß; ≯⒈.ß; [V6]; xn--hdh84f.xn--zca; ; xn--hdh84f.ss; # ≯⒈.ß
+≯1.。ß; ≯1..ß; [X4_2]; xn--1-ogo..xn--zca; [A4_2]; xn--1-ogo..ss; # ≯1..ß
+>\u03381.。ß; ≯1..ß; [X4_2]; xn--1-ogo..xn--zca; [A4_2]; xn--1-ogo..ss; # ≯1..ß
+>\u03381.。SS; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+≯1.。SS; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+≯1.。ss; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+>\u03381.。ss; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+>\u03381.。Ss; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+≯1.。Ss; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+xn--1-ogo..ss; ≯1..ss; [X4_2]; xn--1-ogo..ss; [A4_2]; ; # ≯1..ss
+xn--1-ogo..xn--zca; ≯1..ß; [X4_2]; xn--1-ogo..xn--zca; [A4_2]; ; # ≯1..ß
+>\u0338⒈。SS; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。SS; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。ss; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+>\u0338⒈。ss; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+>\u0338⒈。Ss; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。Ss; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+xn--hdh84f.ss; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+xn--hdh84f.xn--zca; ≯⒈.ß; [V6]; xn--hdh84f.xn--zca; ; ; # ≯⒈.ß
+\u0667\u200D\uFB96。\u07DA-₆Ⴙ; \u0667\u200D\u06B3.\u07DA-6Ⴙ; [B1, B2, B3, C2, V6]; xn--gib6m343e.xn---6-lve002g; ; xn--gib6m.xn---6-lve002g; [B1, B2, B3, V6] # ٧ڳ.ߚ-6Ⴙ
+\u0667\u200D\u06B3。\u07DA-6Ⴙ; \u0667\u200D\u06B3.\u07DA-6Ⴙ; [B1, B2, B3, C2, V6]; xn--gib6m343e.xn---6-lve002g; ; xn--gib6m.xn---6-lve002g; [B1, B2, B3, V6] # ٧ڳ.ߚ-6Ⴙ
+\u0667\u200D\u06B3。\u07DA-6ⴙ; \u0667\u200D\u06B3.\u07DA-6ⴙ; [B1, B2, B3, C2]; xn--gib6m343e.xn---6-lve6529a; ; xn--gib6m.xn---6-lve6529a; [B1, B2, B3] # ٧ڳ.ߚ-6ⴙ
+xn--gib6m.xn---6-lve6529a; \u0667\u06B3.\u07DA-6ⴙ; [B1, B2, B3]; xn--gib6m.xn---6-lve6529a; ; ; # ٧ڳ.ߚ-6ⴙ
+xn--gib6m343e.xn---6-lve6529a; \u0667\u200D\u06B3.\u07DA-6ⴙ; [B1, B2, B3, C2]; xn--gib6m343e.xn---6-lve6529a; ; ; # ٧ڳ.ߚ-6ⴙ
+xn--gib6m.xn---6-lve002g; \u0667\u06B3.\u07DA-6Ⴙ; [B1, B2, B3, V6]; xn--gib6m.xn---6-lve002g; ; ; # ٧ڳ.ߚ-6Ⴙ
+xn--gib6m343e.xn---6-lve002g; \u0667\u200D\u06B3.\u07DA-6Ⴙ; [B1, B2, B3, C2, V6]; xn--gib6m343e.xn---6-lve002g; ; ; # ٧ڳ.ߚ-6Ⴙ
+\u0667\u200D\uFB96。\u07DA-₆ⴙ; \u0667\u200D\u06B3.\u07DA-6ⴙ; [B1, B2, B3, C2]; xn--gib6m343e.xn---6-lve6529a; ; xn--gib6m.xn---6-lve6529a; [B1, B2, B3] # ٧ڳ.ߚ-6ⴙ
+\u200C。≠; \u200C.≠; [C1]; xn--0ug.xn--1ch; ; .xn--1ch; [A4_2] # .≠
+\u200C。=\u0338; \u200C.≠; [C1]; xn--0ug.xn--1ch; ; .xn--1ch; [A4_2] # .≠
+\u200C。≠; \u200C.≠; [C1]; xn--0ug.xn--1ch; ; .xn--1ch; [A4_2] # .≠
+\u200C。=\u0338; \u200C.≠; [C1]; xn--0ug.xn--1ch; ; .xn--1ch; [A4_2] # .≠
+.xn--1ch; .≠; [X4_2]; .xn--1ch; [A4_2]; ; # .≠
+xn--0ug.xn--1ch; \u200C.≠; [C1]; xn--0ug.xn--1ch; ; ; # .≠
+𑖿𝨔.ᡟ𑖿\u1B42\u200C; ; [C1, V5]; xn--461dw464a.xn--v8e29ldzfo952a; ; xn--461dw464a.xn--v8e29loy65a; [V5] # 𑖿𝨔.ᡟ𑖿ᭂ
+xn--461dw464a.xn--v8e29loy65a; 𑖿𝨔.ᡟ𑖿\u1B42; [V5]; xn--461dw464a.xn--v8e29loy65a; ; ; # 𑖿𝨔.ᡟ𑖿ᭂ
+xn--461dw464a.xn--v8e29ldzfo952a; 𑖿𝨔.ᡟ𑖿\u1B42\u200C; [C1, V5]; xn--461dw464a.xn--v8e29ldzfo952a; ; ; # 𑖿𝨔.ᡟ𑖿ᭂ
+򔣳\u200D򑝱.𖬴Ↄ≠-; ; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----61n81bt713h; ; xn--6j00chy9a.xn----61n81bt713h; [V3, V5, V6] # .𖬴Ↄ≠-
+򔣳\u200D򑝱.𖬴Ↄ=\u0338-; 򔣳\u200D򑝱.𖬴Ↄ≠-; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----61n81bt713h; ; xn--6j00chy9a.xn----61n81bt713h; [V3, V5, V6] # .𖬴Ↄ≠-
+򔣳\u200D򑝱.𖬴ↄ=\u0338-; 򔣳\u200D򑝱.𖬴ↄ≠-; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----81n51bt713h; ; xn--6j00chy9a.xn----81n51bt713h; [V3, V5, V6] # .𖬴ↄ≠-
+򔣳\u200D򑝱.𖬴ↄ≠-; ; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----81n51bt713h; ; xn--6j00chy9a.xn----81n51bt713h; [V3, V5, V6] # .𖬴ↄ≠-
+xn--6j00chy9a.xn----81n51bt713h; 򔣳򑝱.𖬴ↄ≠-; [V3, V5, V6]; xn--6j00chy9a.xn----81n51bt713h; ; ; # .𖬴ↄ≠-
+xn--1ug15151gkb5a.xn----81n51bt713h; 򔣳\u200D򑝱.𖬴ↄ≠-; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----81n51bt713h; ; ; # .𖬴ↄ≠-
+xn--6j00chy9a.xn----61n81bt713h; 򔣳򑝱.𖬴Ↄ≠-; [V3, V5, V6]; xn--6j00chy9a.xn----61n81bt713h; ; ; # .𖬴Ↄ≠-
+xn--1ug15151gkb5a.xn----61n81bt713h; 򔣳\u200D򑝱.𖬴Ↄ≠-; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----61n81bt713h; ; ; # .𖬴Ↄ≠-
+\u07E2ς\u200D𝟳。蔑򛖢; \u07E2ς\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-xmb182aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, V6] # ߢς7.蔑
+\u07E2ς\u200D7。蔑򛖢; \u07E2ς\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-xmb182aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, V6] # ߢς7.蔑
+\u07E2Σ\u200D7。蔑򛖢; \u07E2σ\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, V6] # ߢσ7.蔑
+\u07E2σ\u200D7。蔑򛖢; \u07E2σ\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, V6] # ߢσ7.蔑
+xn--7-zmb872a.xn--wy1ao4929b; \u07E2σ7.蔑򛖢; [B2, V6]; xn--7-zmb872a.xn--wy1ao4929b; ; ; # ߢσ7.蔑
+xn--7-zmb872aez5a.xn--wy1ao4929b; \u07E2σ\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; ; # ߢσ7.蔑
+xn--7-xmb182aez5a.xn--wy1ao4929b; \u07E2ς\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-xmb182aez5a.xn--wy1ao4929b; ; ; # ߢς7.蔑
+\u07E2Σ\u200D𝟳。蔑򛖢; \u07E2σ\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, V6] # ߢσ7.蔑
+\u07E2σ\u200D𝟳。蔑򛖢; \u07E2σ\u200D7.蔑򛖢; [B2, C2, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, V6] # ߢσ7.蔑
+𐹰.\u0600; ; [B1, V6]; xn--oo0d.xn--ifb; ; ; # 𐹰.
+xn--oo0d.xn--ifb; 𐹰.\u0600; [B1, V6]; xn--oo0d.xn--ifb; ; ; # 𐹰.
+-\u08A8.𱠖; ; [B1, V3]; xn----mod.xn--5o9n; ; ; # -ࢨ.𱠖
+xn----mod.xn--5o9n; -\u08A8.𱠖; [B1, V3]; xn----mod.xn--5o9n; ; ; # -ࢨ.𱠖
+≯𞱸󠇀。誆⒈; ≯𞱸.誆⒈; [B1, V6]; xn--hdh7151p.xn--tsh1248a; ; ; # ≯𞱸.誆⒈
+>\u0338𞱸󠇀。誆⒈; ≯𞱸.誆⒈; [B1, V6]; xn--hdh7151p.xn--tsh1248a; ; ; # ≯𞱸.誆⒈
+≯𞱸󠇀。誆1.; ≯𞱸.誆1.; [B1]; xn--hdh7151p.xn--1-dy1d.; ; ; # ≯𞱸.誆1.
+>\u0338𞱸󠇀。誆1.; ≯𞱸.誆1.; [B1]; xn--hdh7151p.xn--1-dy1d.; ; ; # ≯𞱸.誆1.
+xn--hdh7151p.xn--1-dy1d.; ≯𞱸.誆1.; [B1]; xn--hdh7151p.xn--1-dy1d.; ; ; # ≯𞱸.誆1.
+xn--hdh7151p.xn--tsh1248a; ≯𞱸.誆⒈; [B1, V6]; xn--hdh7151p.xn--tsh1248a; ; ; # ≯𞱸.誆⒈
+\u0616𞥙䐊\u0650.︒\u0645↺\u069C; \u0616𞥙䐊\u0650.︒\u0645↺\u069C; [B1, V5, V6]; xn--4fb0j490qjg4x.xn--hhb8o948euo5r; ; ; # ؖ𞥙䐊ِ.︒م↺ڜ
+\u0616𞥙䐊\u0650.。\u0645↺\u069C; \u0616𞥙䐊\u0650..\u0645↺\u069C; [B1, V5, X4_2]; xn--4fb0j490qjg4x..xn--hhb8o948e; [B1, V5, A4_2]; ; # ؖ𞥙䐊ِ..م↺ڜ
+xn--4fb0j490qjg4x..xn--hhb8o948e; \u0616𞥙䐊\u0650..\u0645↺\u069C; [B1, V5, X4_2]; xn--4fb0j490qjg4x..xn--hhb8o948e; [B1, V5, A4_2]; ; # ؖ𞥙䐊ِ..م↺ڜ
+xn--4fb0j490qjg4x.xn--hhb8o948euo5r; \u0616𞥙䐊\u0650.︒\u0645↺\u069C; [B1, V5, V6]; xn--4fb0j490qjg4x.xn--hhb8o948euo5r; ; ; # ؖ𞥙䐊ِ.︒م↺ڜ
+퀬-?񶳒.\u200C\u0AC5󩸤۴; ; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; xn---?-6g4k75207c.xn--hmb76q74166b; [V5, V6] # 퀬-?.ૅ۴
+퀬-?񶳒.\u200C\u0AC5󩸤۴; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; xn---?-6g4k75207c.xn--hmb76q74166b; [V5, V6] # 퀬-?.ૅ۴
+xn---?-6g4k75207c.xn--hmb76q74166b; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+xn---?-6g4k75207c.xn--hmb76q48y18505a; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q74166b; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q74166b; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q74166B; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q74166B; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q74166b; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q74166b; 퀬-?񶳒.\u0AC5󩸤۴; [V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q48y18505a; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q48y18505a; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q48Y18505A; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q48Y18505A; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q48y18505a; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q48y18505a; 퀬-?񶳒.\u200C\u0AC5󩸤۴; [C1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+Ⴌ.𐹾︒𑁿𞾄; ; [B1, V6]; xn--knd.xn--y86c030a9ob6374b; ; ; # Ⴌ.𐹾︒𑁿
+Ⴌ.𐹾。𑁿𞾄; Ⴌ.𐹾.𑁿𞾄; [B1, V5, V6]; xn--knd.xn--2o0d.xn--q30dg029a; ; ; # Ⴌ.𐹾.𑁿
+ⴌ.𐹾。𑁿𞾄; ⴌ.𐹾.𑁿𞾄; [B1, V5, V6]; xn--3kj.xn--2o0d.xn--q30dg029a; ; ; # ⴌ.𐹾.𑁿
+xn--3kj.xn--2o0d.xn--q30dg029a; ⴌ.𐹾.𑁿𞾄; [B1, V5, V6]; xn--3kj.xn--2o0d.xn--q30dg029a; ; ; # ⴌ.𐹾.𑁿
+xn--knd.xn--2o0d.xn--q30dg029a; Ⴌ.𐹾.𑁿𞾄; [B1, V5, V6]; xn--knd.xn--2o0d.xn--q30dg029a; ; ; # Ⴌ.𐹾.𑁿
+ⴌ.𐹾︒𑁿𞾄; ; [B1, V6]; xn--3kj.xn--y86c030a9ob6374b; ; ; # ⴌ.𐹾︒𑁿
+xn--3kj.xn--y86c030a9ob6374b; ⴌ.𐹾︒𑁿𞾄; [B1, V6]; xn--3kj.xn--y86c030a9ob6374b; ; ; # ⴌ.𐹾︒𑁿
+xn--knd.xn--y86c030a9ob6374b; Ⴌ.𐹾︒𑁿𞾄; [B1, V6]; xn--knd.xn--y86c030a9ob6374b; ; ; # Ⴌ.𐹾︒𑁿
+񧞿╏。𞩕󠁾; 񧞿╏.𞩕󠁾; [B3, B6, V6]; xn--iyh90030d.xn--1m6hs0260c; ; ; # ╏.
+xn--iyh90030d.xn--1m6hs0260c; 񧞿╏.𞩕󠁾; [B3, B6, V6]; xn--iyh90030d.xn--1m6hs0260c; ; ; # ╏.
+\u200D┮󠇐.\u0C00\u0C4D\u1734\u200D; \u200D┮.\u0C00\u0C4D\u1734\u200D; [C2, V5]; xn--1ug04r.xn--eoc8m432a40i; ; xn--kxh.xn--eoc8m432a; [V5] # ┮.ఀ్᜴
+\u200D┮󠇐.\u0C00\u0C4D\u1734\u200D; \u200D┮.\u0C00\u0C4D\u1734\u200D; [C2, V5]; xn--1ug04r.xn--eoc8m432a40i; ; xn--kxh.xn--eoc8m432a; [V5] # ┮.ఀ్᜴
+xn--kxh.xn--eoc8m432a; ┮.\u0C00\u0C4D\u1734; [V5]; xn--kxh.xn--eoc8m432a; ; ; # ┮.ఀ్᜴
+xn--1ug04r.xn--eoc8m432a40i; \u200D┮.\u0C00\u0C4D\u1734\u200D; [C2, V5]; xn--1ug04r.xn--eoc8m432a40i; ; ; # ┮.ఀ్᜴
+򹚪。🄂; 򹚪.🄂; [V6]; xn--n433d.xn--v07h; ; ; # .🄂
+򹚪。1,; 򹚪.1,; [V6]; xn--n433d.1,; ; ; # .1,
+xn--n433d.1,; 򹚪.1,; [V6]; xn--n433d.1,; ; ; # .1,
+xn--n433d.xn--v07h; 򹚪.🄂; [V6]; xn--n433d.xn--v07h; ; ; # .🄂
+𑍨刍.🛦; ; [V5]; xn--rbry728b.xn--y88h; ; ; # 𑍨刍.🛦
+xn--rbry728b.xn--y88h; 𑍨刍.🛦; [V5]; xn--rbry728b.xn--y88h; ; ; # 𑍨刍.🛦
+󠌏3。\u1BF1𝟒; 󠌏3.\u1BF14; [V5, V6]; xn--3-ib31m.xn--4-pql; ; ; # 3.ᯱ4
+󠌏3。\u1BF14; 󠌏3.\u1BF14; [V5, V6]; xn--3-ib31m.xn--4-pql; ; ; # 3.ᯱ4
+xn--3-ib31m.xn--4-pql; 󠌏3.\u1BF14; [V5, V6]; xn--3-ib31m.xn--4-pql; ; ; # 3.ᯱ4
+\u06876Ⴔ辘.\uFD22\u0687\u200C; \u06876Ⴔ辘.\u0635\u064A\u0687\u200C; [B2, B3, C1, V6]; xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ; xn--6-gsc039eqq6k.xn--0gb6bxk; [B2, B3, V6] # ڇ6Ⴔ辘.صيڇ
+\u06876Ⴔ辘.\u0635\u064A\u0687\u200C; ; [B2, B3, C1, V6]; xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ; xn--6-gsc039eqq6k.xn--0gb6bxk; [B2, B3, V6] # ڇ6Ⴔ辘.صيڇ
+\u06876ⴔ辘.\u0635\u064A\u0687\u200C; ; [B2, B3, C1]; xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ; xn--6-gsc2270akm6f.xn--0gb6bxk; [B2, B3] # ڇ6ⴔ辘.صيڇ
+xn--6-gsc2270akm6f.xn--0gb6bxk; \u06876ⴔ辘.\u0635\u064A\u0687; [B2, B3]; xn--6-gsc2270akm6f.xn--0gb6bxk; ; ; # ڇ6ⴔ辘.صيڇ
+xn--6-gsc2270akm6f.xn--0gb6bxkx18g; \u06876ⴔ辘.\u0635\u064A\u0687\u200C; [B2, B3, C1]; xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ; ; # ڇ6ⴔ辘.صيڇ
+xn--6-gsc039eqq6k.xn--0gb6bxk; \u06876Ⴔ辘.\u0635\u064A\u0687; [B2, B3, V6]; xn--6-gsc039eqq6k.xn--0gb6bxk; ; ; # ڇ6Ⴔ辘.صيڇ
+xn--6-gsc039eqq6k.xn--0gb6bxkx18g; \u06876Ⴔ辘.\u0635\u064A\u0687\u200C; [B2, B3, C1, V6]; xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ; ; # ڇ6Ⴔ辘.صيڇ
+\u06876ⴔ辘.\uFD22\u0687\u200C; \u06876ⴔ辘.\u0635\u064A\u0687\u200C; [B2, B3, C1]; xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ; xn--6-gsc2270akm6f.xn--0gb6bxk; [B2, B3] # ڇ6ⴔ辘.صيڇ
+󠄍.𐮭𞰬򻫞۹; .𐮭𞰬򻫞۹; [B2, V6, X4_2]; .xn--mmb3954kd0uf1zx7f; [B2, V6, A4_2]; ; # .𐮭۹
+.xn--mmb3954kd0uf1zx7f; .𐮭𞰬򻫞۹; [B2, V6, X4_2]; .xn--mmb3954kd0uf1zx7f; [B2, V6, A4_2]; ; # .𐮭۹
+\uA87D≯.򻲀򒳄; \uA87D≯.򻲀򒳄; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+\uA87D>\u0338.򻲀򒳄; \uA87D≯.򻲀򒳄; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+\uA87D≯.򻲀򒳄; ; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+\uA87D>\u0338.򻲀򒳄; \uA87D≯.򻲀򒳄; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+xn--hdh8193c.xn--5z40cp629b; \uA87D≯.򻲀򒳄; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+ςო\u067B.ς\u0714; ; [B5, B6]; xn--3xa80l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # ςოٻ.ςܔ
+ΣᲝ\u067B.Σ\u0714; σო\u067B.σ\u0714; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+σო\u067B.σ\u0714; ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+Σო\u067B.σ\u0714; σო\u067B.σ\u0714; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+xn--4xa60l26n.xn--4xa21o; σო\u067B.σ\u0714; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+Σო\u067B.ς\u0714; σო\u067B.ς\u0714; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # σოٻ.ςܔ
+σო\u067B.ς\u0714; ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # σოٻ.ςܔ
+xn--4xa60l26n.xn--3xa41o; σო\u067B.ς\u0714; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; ; # σოٻ.ςܔ
+xn--3xa80l26n.xn--3xa41o; ςო\u067B.ς\u0714; [B5, B6]; xn--3xa80l26n.xn--3xa41o; ; ; # ςოٻ.ςܔ
+Σო\u067B.Σ\u0714; σო\u067B.σ\u0714; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+򄖚\u0748𠄯\u075F。󠛩; 򄖚\u0748𠄯\u075F.󠛩; [B1, B5, B6, V6]; xn--vob0c4369twfv8b.xn--kl46e; ; ; # ݈𠄯ݟ.
+򄖚\u0748𠄯\u075F。󠛩; 򄖚\u0748𠄯\u075F.󠛩; [B1, B5, B6, V6]; xn--vob0c4369twfv8b.xn--kl46e; ; ; # ݈𠄯ݟ.
+xn--vob0c4369twfv8b.xn--kl46e; 򄖚\u0748𠄯\u075F.󠛩; [B1, B5, B6, V6]; xn--vob0c4369twfv8b.xn--kl46e; ; ; # ݈𠄯ݟ.
+󠳛.\u200D䤫≠Ⴞ; 󠳛.\u200D䤫≠Ⴞ; [C2, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [V6] # .䤫≠Ⴞ
+󠳛.\u200D䤫=\u0338Ⴞ; 󠳛.\u200D䤫≠Ⴞ; [C2, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [V6] # .䤫≠Ⴞ
+󠳛.\u200D䤫≠Ⴞ; ; [C2, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [V6] # .䤫≠Ⴞ
+󠳛.\u200D䤫=\u0338Ⴞ; 󠳛.\u200D䤫≠Ⴞ; [C2, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [V6] # .䤫≠Ⴞ
+󠳛.\u200D䤫=\u0338ⴞ; 󠳛.\u200D䤫≠ⴞ; [C2, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [V6] # .䤫≠ⴞ
+󠳛.\u200D䤫≠ⴞ; ; [C2, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [V6] # .䤫≠ⴞ
+xn--1t56e.xn--1ch153bqvw; 󠳛.䤫≠ⴞ; [V6]; xn--1t56e.xn--1ch153bqvw; ; ; # .䤫≠ⴞ
+xn--1t56e.xn--1ug73gzzpwi3a; 󠳛.\u200D䤫≠ⴞ; [C2, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; ; # .䤫≠ⴞ
+xn--1t56e.xn--2nd141ghl2a; 󠳛.䤫≠Ⴞ; [V6]; xn--1t56e.xn--2nd141ghl2a; ; ; # .䤫≠Ⴞ
+xn--1t56e.xn--2nd159e9vb743e; 󠳛.\u200D䤫≠Ⴞ; [C2, V6]; xn--1t56e.xn--2nd159e9vb743e; ; ; # .䤫≠Ⴞ
+󠳛.\u200D䤫=\u0338ⴞ; 󠳛.\u200D䤫≠ⴞ; [C2, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [V6] # .䤫≠ⴞ
+󠳛.\u200D䤫≠ⴞ; 󠳛.\u200D䤫≠ⴞ; [C2, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [V6] # .䤫≠ⴞ
+𐽘𑈵.𐹣🕥; 𐽘𑈵.𐹣🕥; [B1, B2, B3]; xn--bv0d02c.xn--bo0dq650b; ; ; # 𐽘𑈵.𐹣🕥
+𐽘𑈵.𐹣🕥; ; [B1, B2, B3]; xn--bv0d02c.xn--bo0dq650b; ; ; # 𐽘𑈵.𐹣🕥
+xn--bv0d02c.xn--bo0dq650b; 𐽘𑈵.𐹣🕥; [B1, B2, B3]; xn--bv0d02c.xn--bo0dq650b; ; ; # 𐽘𑈵.𐹣🕥
+⒊⒈𑁄。9; ⒊⒈𑁄.9; [V6]; xn--tshd3512p.9; ; ; # ⒊⒈𑁄.9
+3.1.𑁄。9; 3.1.𑁄.9; [V5]; 3.1.xn--110d.9; ; ; # 3.1.𑁄.9
+3.1.xn--110d.9; 3.1.𑁄.9; [V5]; 3.1.xn--110d.9; ; ; # 3.1.𑁄.9
+xn--tshd3512p.9; ⒊⒈𑁄.9; [V6]; xn--tshd3512p.9; ; ; # ⒊⒈𑁄.9
+-\u200C\u2DF1≮.𐹱򭏴4₉; -\u200C\u2DF1≮.𐹱򭏴49; [B1, C1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, V3, V6] # -ⷱ≮.𐹱49
+-\u200C\u2DF1<\u0338.𐹱򭏴4₉; -\u200C\u2DF1≮.𐹱򭏴49; [B1, C1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, V3, V6] # -ⷱ≮.𐹱49
+-\u200C\u2DF1≮.𐹱򭏴49; ; [B1, C1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, V3, V6] # -ⷱ≮.𐹱49
+-\u200C\u2DF1<\u0338.𐹱򭏴49; -\u200C\u2DF1≮.𐹱򭏴49; [B1, C1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, V3, V6] # -ⷱ≮.𐹱49
+xn----ngo823c.xn--49-ki3om2611f; -\u2DF1≮.𐹱򭏴49; [B1, V3, V6]; xn----ngo823c.xn--49-ki3om2611f; ; ; # -ⷱ≮.𐹱49
+xn----sgn20i14s.xn--49-ki3om2611f; -\u200C\u2DF1≮.𐹱򭏴49; [B1, C1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; ; # -ⷱ≮.𐹱49
+-≯딾。\u0847; -≯딾.\u0847; [B1, V3]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+->\u0338딾。\u0847; -≯딾.\u0847; [B1, V3]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+-≯딾。\u0847; -≯딾.\u0847; [B1, V3]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+->\u0338딾。\u0847; -≯딾.\u0847; [B1, V3]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+xn----pgow547d.xn--5vb; -≯딾.\u0847; [B1, V3]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+𑙢⒈𐹠-。󠗐\u200C; 𑙢⒈𐹠-.󠗐\u200C; [B1, C1, V3, V6]; xn----dcpy090hiyg.xn--0ug23321l; ; xn----dcpy090hiyg.xn--jd46e; [B1, V3, V6] # 𑙢⒈𐹠-.
+𑙢1.𐹠-。󠗐\u200C; 𑙢1.𐹠-.󠗐\u200C; [B1, C1, V3, V6]; xn--1-bf0j.xn----516i.xn--0ug23321l; ; xn--1-bf0j.xn----516i.xn--jd46e; [B1, V3, V6] # 𑙢1.𐹠-.
+xn--1-bf0j.xn----516i.xn--jd46e; 𑙢1.𐹠-.󠗐; [B1, V3, V6]; xn--1-bf0j.xn----516i.xn--jd46e; ; ; # 𑙢1.𐹠-.
+xn--1-bf0j.xn----516i.xn--0ug23321l; 𑙢1.𐹠-.󠗐\u200C; [B1, C1, V3, V6]; xn--1-bf0j.xn----516i.xn--0ug23321l; ; ; # 𑙢1.𐹠-.
+xn----dcpy090hiyg.xn--jd46e; 𑙢⒈𐹠-.󠗐; [B1, V3, V6]; xn----dcpy090hiyg.xn--jd46e; ; ; # 𑙢⒈𐹠-.
+xn----dcpy090hiyg.xn--0ug23321l; 𑙢⒈𐹠-.󠗐\u200C; [B1, C1, V3, V6]; xn----dcpy090hiyg.xn--0ug23321l; ; ; # 𑙢⒈𐹠-.
+\u034A.𐨎; \u034A.𐨎; [V5]; xn--oua.xn--mr9c; ; ; # ͊.𐨎
+\u034A.𐨎; ; [V5]; xn--oua.xn--mr9c; ; ; # ͊.𐨎
+xn--oua.xn--mr9c; \u034A.𐨎; [V5]; xn--oua.xn--mr9c; ; ; # ͊.𐨎
+훉≮。\u0E34; 훉≮.\u0E34; [V5]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+훉<\u0338。\u0E34; 훉≮.\u0E34; [V5]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+훉≮。\u0E34; 훉≮.\u0E34; [V5]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+훉<\u0338。\u0E34; 훉≮.\u0E34; [V5]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+xn--gdh2512e.xn--i4c; 훉≮.\u0E34; [V5]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+\u2DF7򞣉🃘.𴈇𝟸\u0659𞤯; \u2DF7򞣉🃘.𴈇2\u0659𞤯; [B1, B5, B6, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+\u2DF7򞣉🃘.𴈇2\u0659𞤯; ; [B1, B5, B6, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+\u2DF7򞣉🃘.𴈇2\u0659𞤍; \u2DF7򞣉🃘.𴈇2\u0659𞤯; [B1, B5, B6, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+xn--trj8045le6s9b.xn--2-upc23918acjsj; \u2DF7򞣉🃘.𴈇2\u0659𞤯; [B1, B5, B6, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+\u2DF7򞣉🃘.𴈇𝟸\u0659𞤍; \u2DF7򞣉🃘.𴈇2\u0659𞤯; [B1, B5, B6, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+󗇩ßᢞ\u200C。\u0660𞷻\uFCD4-; 󗇩ßᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--zca272jbif10059a.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ßᢞ.٠نخ-
+󗇩ßᢞ\u200C。\u0660𞷻\u0646\u062E-; 󗇩ßᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--zca272jbif10059a.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ßᢞ.٠نخ-
+󗇩SSᢞ\u200C。\u0660𞷻\u0646\u062E-; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ssᢞ.٠نخ-
+󗇩ssᢞ\u200C。\u0660𞷻\u0646\u062E-; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ssᢞ.٠نخ-
+󗇩Ssᢞ\u200C。\u0660𞷻\u0646\u062E-; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ssᢞ.٠نخ-
+xn--ss-jepz4596r.xn----dnc5e1er384z; 󗇩ssᢞ.\u0660𞷻\u0646\u062E-; [B1, V3, V6]; xn--ss-jepz4596r.xn----dnc5e1er384z; ; ; # ssᢞ.٠نخ-
+xn--ss-jep006bqt765b.xn----dnc5e1er384z; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; ; # ssᢞ.٠نخ-
+xn--zca272jbif10059a.xn----dnc5e1er384z; 󗇩ßᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--zca272jbif10059a.xn----dnc5e1er384z; ; ; # ßᢞ.٠نخ-
+󗇩SSᢞ\u200C。\u0660𞷻\uFCD4-; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ssᢞ.٠نخ-
+󗇩ssᢞ\u200C。\u0660𞷻\uFCD4-; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ssᢞ.٠نخ-
+󗇩Ssᢞ\u200C。\u0660𞷻\uFCD4-; 󗇩ssᢞ\u200C.\u0660𞷻\u0646\u062E-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, V3, V6] # ssᢞ.٠نخ-
+ꡆ。Ↄ\u0FB5놮-; ꡆ.Ↄ\u0FB5놮-; [V3, V6]; xn--fc9a.xn----qmg787k869k; ; ; # ꡆ.Ↄྵ놮-
+ꡆ。Ↄ\u0FB5놮-; ꡆ.Ↄ\u0FB5놮-; [V3, V6]; xn--fc9a.xn----qmg787k869k; ; ; # ꡆ.Ↄྵ놮-
+ꡆ。ↄ\u0FB5놮-; ꡆ.ↄ\u0FB5놮-; [V3]; xn--fc9a.xn----qmg097k469k; ; ; # ꡆ.ↄྵ놮-
+ꡆ。ↄ\u0FB5놮-; ꡆ.ↄ\u0FB5놮-; [V3]; xn--fc9a.xn----qmg097k469k; ; ; # ꡆ.ↄྵ놮-
+xn--fc9a.xn----qmg097k469k; ꡆ.ↄ\u0FB5놮-; [V3]; xn--fc9a.xn----qmg097k469k; ; ; # ꡆ.ↄྵ놮-
+xn--fc9a.xn----qmg787k869k; ꡆ.Ↄ\u0FB5놮-; [V3, V6]; xn--fc9a.xn----qmg787k869k; ; ; # ꡆ.Ↄྵ놮-
+\uFDAD\u200D.񥰌\u06A9; \u0644\u0645\u064A\u200D.񥰌\u06A9; [B3, B5, B6, C2, V6]; xn--ghbcp494x.xn--ckb36214f; ; xn--ghbcp.xn--ckb36214f; [B5, B6, V6] # لمي.ک
+\u0644\u0645\u064A\u200D.񥰌\u06A9; ; [B3, B5, B6, C2, V6]; xn--ghbcp494x.xn--ckb36214f; ; xn--ghbcp.xn--ckb36214f; [B5, B6, V6] # لمي.ک
+xn--ghbcp.xn--ckb36214f; \u0644\u0645\u064A.񥰌\u06A9; [B5, B6, V6]; xn--ghbcp.xn--ckb36214f; ; ; # لمي.ک
+xn--ghbcp494x.xn--ckb36214f; \u0644\u0645\u064A\u200D.񥰌\u06A9; [B3, B5, B6, C2, V6]; xn--ghbcp494x.xn--ckb36214f; ; ; # لمي.ک
+Ⴜ\u1C2F𐳒≯。\u06E0\u1732\u0FBA; Ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+Ⴜ\u1C2F𐳒>\u0338。\u06E0\u1732\u0FBA; Ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+ⴜ\u1C2F𐳒>\u0338。\u06E0\u1732\u0FBA; ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5]; xn--r1f68xh1jgv7u.xn--wlb646b4ng; ; ; # ⴜᰯ𐳒≯.۠ᜲྺ
+ⴜ\u1C2F𐳒≯。\u06E0\u1732\u0FBA; ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5]; xn--r1f68xh1jgv7u.xn--wlb646b4ng; ; ; # ⴜᰯ𐳒≯.۠ᜲྺ
+Ⴜ\u1C2F𐲒≯。\u06E0\u1732\u0FBA; Ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+Ⴜ\u1C2F𐲒>\u0338。\u06E0\u1732\u0FBA; Ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+xn--0nd679cf3eq67y.xn--wlb646b4ng; Ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+xn--r1f68xh1jgv7u.xn--wlb646b4ng; ⴜ\u1C2F𐳒≯.\u06E0\u1732\u0FBA; [B1, B5, B6, V5]; xn--r1f68xh1jgv7u.xn--wlb646b4ng; ; ; # ⴜᰯ𐳒≯.۠ᜲྺ
+𐋵。\uFCEC; 𐋵.\u0643\u0645; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+𐋵。\u0643\u0645; 𐋵.\u0643\u0645; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+xn--p97c.xn--fhbe; 𐋵.\u0643\u0645; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+𐋵.\u0643\u0645; ; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+≮𝅶.񱲁\uAAEC⹈󰥭; ≮𝅶.񱲁\uAAEC⹈󰥭; [V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+<\u0338𝅶.񱲁\uAAEC⹈󰥭; ≮𝅶.񱲁\uAAEC⹈󰥭; [V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+≮𝅶.񱲁\uAAEC⹈󰥭; ; [V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+<\u0338𝅶.񱲁\uAAEC⹈󰥭; ≮𝅶.񱲁\uAAEC⹈󰥭; [V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ≮𝅶.񱲁\uAAEC⹈󰥭; [V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+\u2DF0\u0358ᢕ.\u0361𐹷󠴍; \u2DF0\u0358ᢕ.\u0361𐹷󠴍; [B1, V5, V6]; xn--2ua889htsp.xn--cva2687k2tv0g; ; ; # ⷰ͘ᢕ.͡𐹷
+\u2DF0\u0358ᢕ.\u0361𐹷󠴍; ; [B1, V5, V6]; xn--2ua889htsp.xn--cva2687k2tv0g; ; ; # ⷰ͘ᢕ.͡𐹷
+xn--2ua889htsp.xn--cva2687k2tv0g; \u2DF0\u0358ᢕ.\u0361𐹷󠴍; [B1, V5, V6]; xn--2ua889htsp.xn--cva2687k2tv0g; ; ; # ⷰ͘ᢕ.͡𐹷
+\uFD79ᡐ\u200C\u06AD.𑋪\u05C7; \u063A\u0645\u0645ᡐ\u200C\u06AD.𑋪\u05C7; [B1, B2, V5]; xn--5gbwa03bg24eptk.xn--vdb1198k; ; xn--5gbwa03bg24e.xn--vdb1198k; # غممᡐڭ.𑋪ׇ
+\u063A\u0645\u0645ᡐ\u200C\u06AD.𑋪\u05C7; ; [B1, B2, V5]; xn--5gbwa03bg24eptk.xn--vdb1198k; ; xn--5gbwa03bg24e.xn--vdb1198k; # غممᡐڭ.𑋪ׇ
+xn--5gbwa03bg24e.xn--vdb1198k; \u063A\u0645\u0645ᡐ\u06AD.𑋪\u05C7; [B1, B2, V5]; xn--5gbwa03bg24e.xn--vdb1198k; ; ; # غممᡐڭ.𑋪ׇ
+xn--5gbwa03bg24eptk.xn--vdb1198k; \u063A\u0645\u0645ᡐ\u200C\u06AD.𑋪\u05C7; [B1, B2, V5]; xn--5gbwa03bg24eptk.xn--vdb1198k; ; ; # غممᡐڭ.𑋪ׇ
+𑑂。\u200D󥞀🞕򥁔; 𑑂.\u200D󥞀🞕򥁔; [C2, V5, V6]; xn--8v1d.xn--1ug1386plvx1cd8vya; ; xn--8v1d.xn--ye9h41035a2qqs; [V5, V6] # 𑑂.🞕
+𑑂。\u200D󥞀🞕򥁔; 𑑂.\u200D󥞀🞕򥁔; [C2, V5, V6]; xn--8v1d.xn--1ug1386plvx1cd8vya; ; xn--8v1d.xn--ye9h41035a2qqs; [V5, V6] # 𑑂.🞕
+xn--8v1d.xn--ye9h41035a2qqs; 𑑂.󥞀🞕򥁔; [V5, V6]; xn--8v1d.xn--ye9h41035a2qqs; ; ; # 𑑂.🞕
+xn--8v1d.xn--1ug1386plvx1cd8vya; 𑑂.\u200D󥞀🞕򥁔; [C2, V5, V6]; xn--8v1d.xn--1ug1386plvx1cd8vya; ; ; # 𑑂.🞕
+-\u05E9。⒚; -\u05E9.⒚; [B1, V3, V6]; xn----gjc.xn--cth; ; ; # -ש.⒚
+-\u05E9。19.; -\u05E9.19.; [B1, V3]; xn----gjc.19.; ; ; # -ש.19.
+xn----gjc.19.; -\u05E9.19.; [B1, V3]; xn----gjc.19.; ; ; # -ש.19.
+xn----gjc.xn--cth; -\u05E9.⒚; [B1, V3, V6]; xn----gjc.xn--cth; ; ; # -ש.⒚
+􊾻\u0845\u200C。ᢎ\u200D; 􊾻\u0845\u200C.ᢎ\u200D; [B5, B6, C1, C2, V6]; xn--3vb882jz4411a.xn--79e259a; ; xn--3vb50049s.xn--79e; [B5, B6, V6] # ࡅ.ᢎ
+􊾻\u0845\u200C。ᢎ\u200D; 􊾻\u0845\u200C.ᢎ\u200D; [B5, B6, C1, C2, V6]; xn--3vb882jz4411a.xn--79e259a; ; xn--3vb50049s.xn--79e; [B5, B6, V6] # ࡅ.ᢎ
+xn--3vb50049s.xn--79e; 􊾻\u0845.ᢎ; [B5, B6, V6]; xn--3vb50049s.xn--79e; ; ; # ࡅ.ᢎ
+xn--3vb882jz4411a.xn--79e259a; 􊾻\u0845\u200C.ᢎ\u200D; [B5, B6, C1, C2, V6]; xn--3vb882jz4411a.xn--79e259a; ; ; # ࡅ.ᢎ
+ß\u09C1\u1DED。\u06208₅; ß\u09C1\u1DED.\u062085; ; xn--zca266bwrr.xn--85-psd; ; xn--ss-e2f077r.xn--85-psd; # ßুᷭ.ؠ85
+ß\u09C1\u1DED。\u062085; ß\u09C1\u1DED.\u062085; ; xn--zca266bwrr.xn--85-psd; ; xn--ss-e2f077r.xn--85-psd; # ßুᷭ.ؠ85
+SS\u09C1\u1DED。\u062085; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+ss\u09C1\u1DED。\u062085; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+Ss\u09C1\u1DED。\u062085; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+xn--ss-e2f077r.xn--85-psd; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+ss\u09C1\u1DED.\u062085; ; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+SS\u09C1\u1DED.\u062085; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+Ss\u09C1\u1DED.\u062085; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+xn--zca266bwrr.xn--85-psd; ß\u09C1\u1DED.\u062085; ; xn--zca266bwrr.xn--85-psd; ; ; # ßুᷭ.ؠ85
+ß\u09C1\u1DED.\u062085; ; ; xn--zca266bwrr.xn--85-psd; ; xn--ss-e2f077r.xn--85-psd; # ßুᷭ.ؠ85
+SS\u09C1\u1DED。\u06208₅; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+ss\u09C1\u1DED。\u06208₅; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+Ss\u09C1\u1DED。\u06208₅; ss\u09C1\u1DED.\u062085; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+\u0ACD\u0484魅𝟣.₃𐹥ß; \u0ACD\u0484魅1.3𐹥ß; [B1, V5]; xn--1-0xb049b102o.xn--3-qfa7018r; ; xn--1-0xb049b102o.xn--3ss-nv9t; # ્҄魅1.3𐹥ß
+\u0ACD\u0484魅1.3𐹥ß; ; [B1, V5]; xn--1-0xb049b102o.xn--3-qfa7018r; ; xn--1-0xb049b102o.xn--3ss-nv9t; # ્҄魅1.3𐹥ß
+\u0ACD\u0484魅1.3𐹥SS; \u0ACD\u0484魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+\u0ACD\u0484魅1.3𐹥ss; ; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+\u0ACD\u0484魅1.3𐹥Ss; \u0ACD\u0484魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+xn--1-0xb049b102o.xn--3ss-nv9t; \u0ACD\u0484魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+xn--1-0xb049b102o.xn--3-qfa7018r; \u0ACD\u0484魅1.3𐹥ß; [B1, V5]; xn--1-0xb049b102o.xn--3-qfa7018r; ; ; # ્҄魅1.3𐹥ß
+\u0ACD\u0484魅𝟣.₃𐹥SS; \u0ACD\u0484魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+\u0ACD\u0484魅𝟣.₃𐹥ss; \u0ACD\u0484魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+\u0ACD\u0484魅𝟣.₃𐹥Ss; \u0ACD\u0484魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+\u072B。𑓂⒈𑜫󠿻; \u072B.𑓂⒈𑜫󠿻; [B1, V5, V6]; xn--1nb.xn--tsh7798f6rbrt828c; ; ; # ܫ.𑓂⒈𑜫
+\u072B。𑓂1.𑜫󠿻; \u072B.𑓂1.𑜫󠿻; [B1, V5, V6]; xn--1nb.xn--1-jq9i.xn--ji2dg9877c; ; ; # ܫ.𑓂1.𑜫
+xn--1nb.xn--1-jq9i.xn--ji2dg9877c; \u072B.𑓂1.𑜫󠿻; [B1, V5, V6]; xn--1nb.xn--1-jq9i.xn--ji2dg9877c; ; ; # ܫ.𑓂1.𑜫
+xn--1nb.xn--tsh7798f6rbrt828c; \u072B.𑓂⒈𑜫󠿻; [B1, V5, V6]; xn--1nb.xn--tsh7798f6rbrt828c; ; ; # ܫ.𑓂⒈𑜫
+\uFE0Dછ。嵨; છ.嵨; ; xn--6dc.xn--tot; ; ; # છ.嵨
+xn--6dc.xn--tot; છ.嵨; ; xn--6dc.xn--tot; ; ; # છ.嵨
+છ.嵨; ; ; xn--6dc.xn--tot; ; ; # છ.嵨
+Ⴔ≠Ⴀ.𐹥𐹰; ; [B1, V6]; xn--7md3b171g.xn--do0dwa; ; ; # Ⴔ≠Ⴀ.𐹥𐹰
+Ⴔ=\u0338Ⴀ.𐹥𐹰; Ⴔ≠Ⴀ.𐹥𐹰; [B1, V6]; xn--7md3b171g.xn--do0dwa; ; ; # Ⴔ≠Ⴀ.𐹥𐹰
+ⴔ=\u0338ⴀ.𐹥𐹰; ⴔ≠ⴀ.𐹥𐹰; [B1]; xn--1ch603bxb.xn--do0dwa; ; ; # ⴔ≠ⴀ.𐹥𐹰
+ⴔ≠ⴀ.𐹥𐹰; ; [B1]; xn--1ch603bxb.xn--do0dwa; ; ; # ⴔ≠ⴀ.𐹥𐹰
+xn--1ch603bxb.xn--do0dwa; ⴔ≠ⴀ.𐹥𐹰; [B1]; xn--1ch603bxb.xn--do0dwa; ; ; # ⴔ≠ⴀ.𐹥𐹰
+xn--7md3b171g.xn--do0dwa; Ⴔ≠Ⴀ.𐹥𐹰; [B1, V6]; xn--7md3b171g.xn--do0dwa; ; ; # Ⴔ≠Ⴀ.𐹥𐹰
+-\u200C⒙𐫥。𝨵; -\u200C⒙𐫥.𝨵; [C1, V3, V5, V6]; xn----sgn18r3191a.xn--382h; ; xn----ddps939g.xn--382h; [V3, V5, V6] # -⒙𐫥.𝨵
+-\u200C18.𐫥。𝨵; -\u200C18.𐫥.𝨵; [C1, V3, V5]; xn---18-9m0a.xn--rx9c.xn--382h; ; -18.xn--rx9c.xn--382h; [V3, V5] # -18.𐫥.𝨵
+-18.xn--rx9c.xn--382h; -18.𐫥.𝨵; [V3, V5]; -18.xn--rx9c.xn--382h; ; ; # -18.𐫥.𝨵
+xn---18-9m0a.xn--rx9c.xn--382h; -\u200C18.𐫥.𝨵; [C1, V3, V5]; xn---18-9m0a.xn--rx9c.xn--382h; ; ; # -18.𐫥.𝨵
+xn----ddps939g.xn--382h; -⒙𐫥.𝨵; [V3, V5, V6]; xn----ddps939g.xn--382h; ; ; # -⒙𐫥.𝨵
+xn----sgn18r3191a.xn--382h; -\u200C⒙𐫥.𝨵; [C1, V3, V5, V6]; xn----sgn18r3191a.xn--382h; ; ; # -⒙𐫥.𝨵
+︒.ʌᠣ-𐹽; ; [B1, B5, B6, V6]; xn--y86c.xn----73a596nuh9t; ; ; # ︒.ʌᠣ-𐹽
+。.ʌᠣ-𐹽; ..ʌᠣ-𐹽; [B5, B6, X4_2]; ..xn----73a596nuh9t; [B5, B6, A4_2]; ; # ..ʌᠣ-𐹽
+。.Ʌᠣ-𐹽; ..ʌᠣ-𐹽; [B5, B6, X4_2]; ..xn----73a596nuh9t; [B5, B6, A4_2]; ; # ..ʌᠣ-𐹽
+..xn----73a596nuh9t; ..ʌᠣ-𐹽; [B5, B6, X4_2]; ..xn----73a596nuh9t; [B5, B6, A4_2]; ; # ..ʌᠣ-𐹽
+︒.Ʌᠣ-𐹽; ︒.ʌᠣ-𐹽; [B1, B5, B6, V6]; xn--y86c.xn----73a596nuh9t; ; ; # ︒.ʌᠣ-𐹽
+xn--y86c.xn----73a596nuh9t; ︒.ʌᠣ-𐹽; [B1, B5, B6, V6]; xn--y86c.xn----73a596nuh9t; ; ; # ︒.ʌᠣ-𐹽
+\uFE05︒。𦀾\u1CE0; ︒.𦀾\u1CE0; [V6]; xn--y86c.xn--t6f5138v; ; ; # ︒.𦀾᳠
+\uFE05。。𦀾\u1CE0; ..𦀾\u1CE0; [X4_2]; ..xn--t6f5138v; [A4_2]; ; # ..𦀾᳠
+..xn--t6f5138v; ..𦀾\u1CE0; [X4_2]; ..xn--t6f5138v; [A4_2]; ; # ..𦀾᳠
+xn--y86c.xn--t6f5138v; ︒.𦀾\u1CE0; [V6]; xn--y86c.xn--t6f5138v; ; ; # ︒.𦀾᳠
+xn--t6f5138v; 𦀾\u1CE0; ; xn--t6f5138v; ; ; # 𦀾᳠
+𦀾\u1CE0; ; ; xn--t6f5138v; ; ; # 𦀾᳠
+𞮑ß􏞞。ᡁ; 𞮑ß􏞞.ᡁ; [B2, B3, V6]; xn--zca9432wb989f.xn--07e; ; xn--ss-o412ac6305g.xn--07e; # ß.ᡁ
+𞮑SS􏞞。ᡁ; 𞮑ss􏞞.ᡁ; [B2, B3, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+𞮑ss􏞞。ᡁ; 𞮑ss􏞞.ᡁ; [B2, B3, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+𞮑Ss􏞞。ᡁ; 𞮑ss􏞞.ᡁ; [B2, B3, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+xn--ss-o412ac6305g.xn--07e; 𞮑ss􏞞.ᡁ; [B2, B3, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+xn--zca9432wb989f.xn--07e; 𞮑ß􏞞.ᡁ; [B2, B3, V6]; xn--zca9432wb989f.xn--07e; ; ; # ß.ᡁ
+\uA953\u200D\u062C\u066C。𱆎󻡟\u200C󠅆; \uA953\u200D\u062C\u066C.𱆎󻡟\u200C; [B5, B6, C1, V5, V6]; xn--rgb2k500fhq9j.xn--0ug78870a5sp9d; ; xn--rgb2k6711c.xn--ec8nj3948b; [B5, B6, V5, V6] # ꥓ج٬.𱆎
+xn--rgb2k6711c.xn--ec8nj3948b; \uA953\u062C\u066C.𱆎󻡟; [B5, B6, V5, V6]; xn--rgb2k6711c.xn--ec8nj3948b; ; ; # ꥓ج٬.𱆎
+xn--rgb2k500fhq9j.xn--0ug78870a5sp9d; \uA953\u200D\u062C\u066C.𱆎󻡟\u200C; [B5, B6, C1, V5, V6]; xn--rgb2k500fhq9j.xn--0ug78870a5sp9d; ; ; # ꥓ج٬.𱆎
+󠕏.-ß\u200C≠; 󠕏.-ß\u200C≠; [C1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ß≠
+󠕏.-ß\u200C=\u0338; 󠕏.-ß\u200C≠; [C1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ß≠
+󠕏.-ß\u200C≠; ; [C1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ß≠
+󠕏.-ß\u200C=\u0338; 󠕏.-ß\u200C≠; [C1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ß≠
+󠕏.-SS\u200C=\u0338; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-SS\u200C≠; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-ss\u200C≠; ; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-ss\u200C=\u0338; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-Ss\u200C=\u0338; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-Ss\u200C≠; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+xn--u836e.xn---ss-gl2a; 󠕏.-ss≠; [V3, V6]; xn--u836e.xn---ss-gl2a; ; ; # .-ss≠
+xn--u836e.xn---ss-cn0at5l; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; ; # .-ss≠
+xn--u836e.xn----qfa750ve7b; 󠕏.-ß\u200C≠; [C1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; ; # .-ß≠
+󠕏.-SS\u200C=\u0338; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-SS\u200C≠; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-ss\u200C≠; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-ss\u200C=\u0338; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-Ss\u200C=\u0338; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+󠕏.-Ss\u200C≠; 󠕏.-ss\u200C≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [V3, V6] # .-ss≠
+ᡙ\u200C。≯𐋲≠; ᡙ\u200C.≯𐋲≠; [C1]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [] # ᡙ.≯𐋲≠
+ᡙ\u200C。>\u0338𐋲=\u0338; ᡙ\u200C.≯𐋲≠; [C1]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [] # ᡙ.≯𐋲≠
+ᡙ\u200C。≯𐋲≠; ᡙ\u200C.≯𐋲≠; [C1]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [] # ᡙ.≯𐋲≠
+ᡙ\u200C。>\u0338𐋲=\u0338; ᡙ\u200C.≯𐋲≠; [C1]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [] # ᡙ.≯𐋲≠
+xn--p8e.xn--1ch3a7084l; ᡙ.≯𐋲≠; ; xn--p8e.xn--1ch3a7084l; ; ; # ᡙ.≯𐋲≠
+ᡙ.≯𐋲≠; ; ; xn--p8e.xn--1ch3a7084l; ; ; # ᡙ.≯𐋲≠
+ᡙ.>\u0338𐋲=\u0338; ᡙ.≯𐋲≠; ; xn--p8e.xn--1ch3a7084l; ; ; # ᡙ.≯𐋲≠
+xn--p8e650b.xn--1ch3a7084l; ᡙ\u200C.≯𐋲≠; [C1]; xn--p8e650b.xn--1ch3a7084l; ; ; # ᡙ.≯𐋲≠
+𐹧𞲄󠁭񆼩。\u034E🄀; 𐹧𞲄󠁭񆼩.\u034E🄀; [B1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--sua6883w; ; ; # 𐹧𞲄.͎🄀
+𐹧𞲄󠁭񆼩。\u034E0.; 𐹧𞲄󠁭񆼩.\u034E0.; [B1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--0-bgb.; ; ; # 𐹧𞲄.͎0.
+xn--fo0dw409aq58qrn69d.xn--0-bgb.; 𐹧𞲄󠁭񆼩.\u034E0.; [B1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--0-bgb.; ; ; # 𐹧𞲄.͎0.
+xn--fo0dw409aq58qrn69d.xn--sua6883w; 𐹧𞲄󠁭񆼩.\u034E🄀; [B1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--sua6883w; ; ; # 𐹧𞲄.͎🄀
+Ⴄ.\u200D\u0721󻣋ς; Ⴄ.\u200D\u0721󻣋ς; [B1, C2, V6]; xn--cnd.xn--3xa93o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, V6] # Ⴄ.ܡς
+Ⴄ.\u200D\u0721󻣋ς; ; [B1, C2, V6]; xn--cnd.xn--3xa93o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, V6] # Ⴄ.ܡς
+ⴄ.\u200D\u0721󻣋ς; ; [B1, C2, V6]; xn--vkj.xn--3xa93o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, V6] # ⴄ.ܡς
+Ⴄ.\u200D\u0721󻣋Σ; Ⴄ.\u200D\u0721󻣋σ; [B1, C2, V6]; xn--cnd.xn--4xa73o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, V6] # Ⴄ.ܡσ
+ⴄ.\u200D\u0721󻣋σ; ; [B1, C2, V6]; xn--vkj.xn--4xa73o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, V6] # ⴄ.ܡσ
+xn--vkj.xn--4xa73ob5892c; ⴄ.\u0721󻣋σ; [B2, B3, V6]; xn--vkj.xn--4xa73ob5892c; ; ; # ⴄ.ܡσ
+xn--vkj.xn--4xa73o3t5ajq467a; ⴄ.\u200D\u0721󻣋σ; [B1, C2, V6]; xn--vkj.xn--4xa73o3t5ajq467a; ; ; # ⴄ.ܡσ
+xn--cnd.xn--4xa73ob5892c; Ⴄ.\u0721󻣋σ; [B2, B3, V6]; xn--cnd.xn--4xa73ob5892c; ; ; # Ⴄ.ܡσ
+xn--cnd.xn--4xa73o3t5ajq467a; Ⴄ.\u200D\u0721󻣋σ; [B1, C2, V6]; xn--cnd.xn--4xa73o3t5ajq467a; ; ; # Ⴄ.ܡσ
+xn--vkj.xn--3xa93o3t5ajq467a; ⴄ.\u200D\u0721󻣋ς; [B1, C2, V6]; xn--vkj.xn--3xa93o3t5ajq467a; ; ; # ⴄ.ܡς
+xn--cnd.xn--3xa93o3t5ajq467a; Ⴄ.\u200D\u0721󻣋ς; [B1, C2, V6]; xn--cnd.xn--3xa93o3t5ajq467a; ; ; # Ⴄ.ܡς
+ⴄ.\u200D\u0721󻣋ς; ⴄ.\u200D\u0721󻣋ς; [B1, C2, V6]; xn--vkj.xn--3xa93o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, V6] # ⴄ.ܡς
+Ⴄ.\u200D\u0721󻣋Σ; Ⴄ.\u200D\u0721󻣋σ; [B1, C2, V6]; xn--cnd.xn--4xa73o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, V6] # Ⴄ.ܡσ
+ⴄ.\u200D\u0721󻣋σ; ⴄ.\u200D\u0721󻣋σ; [B1, C2, V6]; xn--vkj.xn--4xa73o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, V6] # ⴄ.ܡσ
+򮵛\u0613.Ⴕ; ; [V6]; xn--1fb94204l.xn--tnd; ; ; # ؓ.Ⴕ
+򮵛\u0613.ⴕ; ; [V6]; xn--1fb94204l.xn--dlj; ; ; # ؓ.ⴕ
+xn--1fb94204l.xn--dlj; 򮵛\u0613.ⴕ; [V6]; xn--1fb94204l.xn--dlj; ; ; # ؓ.ⴕ
+xn--1fb94204l.xn--tnd; 򮵛\u0613.Ⴕ; [V6]; xn--1fb94204l.xn--tnd; ; ; # ؓ.Ⴕ
+≯\u1DF3𞤥。\u200C\uA8C4󠪉\u200D; ≯\u1DF3𞤥.\u200C\uA8C4󠪉\u200D; [B1, C1, C2, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, V5, V6] # ≯ᷳ𞤥.꣄
+>\u0338\u1DF3𞤥。\u200C\uA8C4󠪉\u200D; ≯\u1DF3𞤥.\u200C\uA8C4󠪉\u200D; [B1, C1, C2, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, V5, V6] # ≯ᷳ𞤥.꣄
+>\u0338\u1DF3𞤃。\u200C\uA8C4󠪉\u200D; ≯\u1DF3𞤥.\u200C\uA8C4󠪉\u200D; [B1, C1, C2, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, V5, V6] # ≯ᷳ𞤥.꣄
+≯\u1DF3𞤃。\u200C\uA8C4󠪉\u200D; ≯\u1DF3𞤥.\u200C\uA8C4󠪉\u200D; [B1, C1, C2, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, V5, V6] # ≯ᷳ𞤥.꣄
+xn--ofg13qyr21c.xn--0f9au6706d; ≯\u1DF3𞤥.\uA8C4󠪉; [B1, V5, V6]; xn--ofg13qyr21c.xn--0f9au6706d; ; ; # ≯ᷳ𞤥.꣄
+xn--ofg13qyr21c.xn--0ugc0116hix29k; ≯\u1DF3𞤥.\u200C\uA8C4󠪉\u200D; [B1, C1, C2, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; ; # ≯ᷳ𞤥.꣄
+\u200C󠄷。򒑁; \u200C.򒑁; [C1, V6]; xn--0ug.xn--w720c; ; .xn--w720c; [V6, A4_2] # .
+\u200C󠄷。򒑁; \u200C.򒑁; [C1, V6]; xn--0ug.xn--w720c; ; .xn--w720c; [V6, A4_2] # .
+.xn--w720c; .򒑁; [V6, X4_2]; .xn--w720c; [V6, A4_2]; ; # .
+xn--0ug.xn--w720c; \u200C.򒑁; [C1, V6]; xn--0ug.xn--w720c; ; ; # .
+⒈\u0DD6焅.󗡙\u200Dꡟ; ; [C2, V6]; xn--t1c337io97c.xn--1ugz184c9lw7i; ; xn--t1c337io97c.xn--4c9a21133d; [V6] # ⒈ූ焅.ꡟ
+1.\u0DD6焅.󗡙\u200Dꡟ; ; [C2, V5, V6]; 1.xn--t1c6981c.xn--1ugz184c9lw7i; ; 1.xn--t1c6981c.xn--4c9a21133d; [V5, V6] # 1.ූ焅.ꡟ
+1.xn--t1c6981c.xn--4c9a21133d; 1.\u0DD6焅.󗡙ꡟ; [V5, V6]; 1.xn--t1c6981c.xn--4c9a21133d; ; ; # 1.ූ焅.ꡟ
+1.xn--t1c6981c.xn--1ugz184c9lw7i; 1.\u0DD6焅.󗡙\u200Dꡟ; [C2, V5, V6]; 1.xn--t1c6981c.xn--1ugz184c9lw7i; ; ; # 1.ූ焅.ꡟ
+xn--t1c337io97c.xn--4c9a21133d; ⒈\u0DD6焅.󗡙ꡟ; [V6]; xn--t1c337io97c.xn--4c9a21133d; ; ; # ⒈ූ焅.ꡟ
+xn--t1c337io97c.xn--1ugz184c9lw7i; ⒈\u0DD6焅.󗡙\u200Dꡟ; [C2, V6]; xn--t1c337io97c.xn--1ugz184c9lw7i; ; ; # ⒈ූ焅.ꡟ
+\u1DCDς≮.ς𝪦𞤕0; \u1DCDς≮.ς𝪦𞤷0; [B1, B5, V5]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+\u1DCDς<\u0338.ς𝪦𞤕0; \u1DCDς≮.ς𝪦𞤷0; [B1, B5, V5]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+\u1DCDς<\u0338.ς𝪦𞤷0; \u1DCDς≮.ς𝪦𞤷0; [B1, B5, V5]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+\u1DCDς≮.ς𝪦𞤷0; ; [B1, B5, V5]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+\u1DCDΣ≮.Σ𝪦𞤕0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+\u1DCDΣ<\u0338.Σ𝪦𞤕0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+\u1DCDσ<\u0338.σ𝪦𞤷0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+\u1DCDσ≮.σ𝪦𞤷0; ; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+\u1DCDΣ≮.Σ𝪦𞤷0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+\u1DCDΣ<\u0338.Σ𝪦𞤷0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+xn--4xa544kvid.xn--0-zmb55727aggma; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+xn--3xa744kvid.xn--0-xmb85727aggma; \u1DCDς≮.ς𝪦𞤷0; [B1, B5, V5]; xn--3xa744kvid.xn--0-xmb85727aggma; ; ; # ᷍ς≮.ς𝪦𞤷0
+\u1DCDσ≮.σ𝪦𞤕0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+\u1DCDσ<\u0338.σ𝪦𞤕0; \u1DCDσ≮.σ𝪦𞤷0; [B1, B5, V5]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+򢦾ß\u05B9𐫙.\u05AD\u08A1; ; [B1, B5, B6, V5, V6]; xn--zca89v339zj118e.xn--4cb62m; ; xn--ss-xjd6058xlz50g.xn--4cb62m; # ßֹ𐫙.֭ࢡ
+򢦾SS\u05B9𐫙.\u05AD\u08A1; 򢦾ss\u05B9𐫙.\u05AD\u08A1; [B1, B5, B6, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+򢦾ss\u05B9𐫙.\u05AD\u08A1; ; [B1, B5, B6, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+򢦾Ss\u05B9𐫙.\u05AD\u08A1; 򢦾ss\u05B9𐫙.\u05AD\u08A1; [B1, B5, B6, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+xn--ss-xjd6058xlz50g.xn--4cb62m; 򢦾ss\u05B9𐫙.\u05AD\u08A1; [B1, B5, B6, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+xn--zca89v339zj118e.xn--4cb62m; 򢦾ß\u05B9𐫙.\u05AD\u08A1; [B1, B5, B6, V5, V6]; xn--zca89v339zj118e.xn--4cb62m; ; ; # ßֹ𐫙.֭ࢡ
+-𞣄。⒈; -𞣄.⒈; [B1, V3, V6]; xn----xc8r.xn--tsh; ; ; # -𞣄.⒈
+-𞣄。1.; -𞣄.1.; [B1, V3]; xn----xc8r.1.; ; ; # -𞣄.1.
+xn----xc8r.1.; -𞣄.1.; [B1, V3]; xn----xc8r.1.; ; ; # -𞣄.1.
+xn----xc8r.xn--tsh; -𞣄.⒈; [B1, V3, V6]; xn----xc8r.xn--tsh; ; ; # -𞣄.⒈
+񈠢𐫖𝟡。\u063E𑘿; 񈠢𐫖9.\u063E𑘿; [B5, V6]; xn--9-el5iv442t.xn--9gb0830l; ; ; # 𐫖9.ؾ𑘿
+񈠢𐫖9。\u063E𑘿; 񈠢𐫖9.\u063E𑘿; [B5, V6]; xn--9-el5iv442t.xn--9gb0830l; ; ; # 𐫖9.ؾ𑘿
+xn--9-el5iv442t.xn--9gb0830l; 񈠢𐫖9.\u063E𑘿; [B5, V6]; xn--9-el5iv442t.xn--9gb0830l; ; ; # 𐫖9.ؾ𑘿
+\u0668\uFC8C\u0668\u1A5D.\u200D; \u0668\u0646\u0645\u0668\u1A5D.\u200D; [B1, C2]; xn--hhbb5hc956w.xn--1ug; ; xn--hhbb5hc956w.; [B1] # ٨نم٨ᩝ.
+\u0668\u0646\u0645\u0668\u1A5D.\u200D; ; [B1, C2]; xn--hhbb5hc956w.xn--1ug; ; xn--hhbb5hc956w.; [B1] # ٨نم٨ᩝ.
+xn--hhbb5hc956w.; \u0668\u0646\u0645\u0668\u1A5D.; [B1]; xn--hhbb5hc956w.; ; ; # ٨نم٨ᩝ.
+xn--hhbb5hc956w.xn--1ug; \u0668\u0646\u0645\u0668\u1A5D.\u200D; [B1, C2]; xn--hhbb5hc956w.xn--1ug; ; ; # ٨نم٨ᩝ.
+𝟘.Ⴇ󀳑\uFD50񫃱; 0.Ⴇ󀳑\u062A\u062C\u0645񫃱; [B1, B5, V6]; 0.xn--pgbe9e344c2725svff8b; ; ; # 0.Ⴇتجم
+0.Ⴇ󀳑\u062A\u062C\u0645񫃱; ; [B1, B5, V6]; 0.xn--pgbe9e344c2725svff8b; ; ; # 0.Ⴇتجم
+0.ⴇ󀳑\u062A\u062C\u0645񫃱; ; [B1, B5, V6]; 0.xn--pgbe9ez79qd207lvff8b; ; ; # 0.ⴇتجم
+0.xn--pgbe9ez79qd207lvff8b; 0.ⴇ󀳑\u062A\u062C\u0645񫃱; [B1, B5, V6]; 0.xn--pgbe9ez79qd207lvff8b; ; ; # 0.ⴇتجم
+0.xn--pgbe9e344c2725svff8b; 0.Ⴇ󀳑\u062A\u062C\u0645񫃱; [B1, B5, V6]; 0.xn--pgbe9e344c2725svff8b; ; ; # 0.Ⴇتجم
+𝟘.ⴇ󀳑\uFD50񫃱; 0.ⴇ󀳑\u062A\u062C\u0645񫃱; [B1, B5, V6]; 0.xn--pgbe9ez79qd207lvff8b; ; ; # 0.ⴇتجم
+𑇀▍.⁞ᠰ; ; [V5]; xn--9zh3057f.xn--j7e103b; ; ; # 𑇀▍.⁞ᠰ
+xn--9zh3057f.xn--j7e103b; 𑇀▍.⁞ᠰ; [V5]; xn--9zh3057f.xn--j7e103b; ; ; # 𑇀▍.⁞ᠰ
+\u200D-\u067A.򏯩; ; [B1, C2, V6]; xn----qrc357q.xn--ts49b; ; xn----qrc.xn--ts49b; [B1, V3, V6] # -ٺ.
+xn----qrc.xn--ts49b; -\u067A.򏯩; [B1, V3, V6]; xn----qrc.xn--ts49b; ; ; # -ٺ.
+xn----qrc357q.xn--ts49b; \u200D-\u067A.򏯩; [B1, C2, V6]; xn----qrc357q.xn--ts49b; ; ; # -ٺ.
+ᠢ𐮂𐫘寐。\u200C≯✳; ᠢ𐮂𐫘寐.\u200C≯✳; [B1, B5, C1]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5] # ᠢ𐮂𐫘寐.≯✳
+ᠢ𐮂𐫘寐。\u200C>\u0338✳; ᠢ𐮂𐫘寐.\u200C≯✳; [B1, B5, C1]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5] # ᠢ𐮂𐫘寐.≯✳
+ᠢ𐮂𐫘寐。\u200C≯✳; ᠢ𐮂𐫘寐.\u200C≯✳; [B1, B5, C1]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5] # ᠢ𐮂𐫘寐.≯✳
+ᠢ𐮂𐫘寐。\u200C>\u0338✳; ᠢ𐮂𐫘寐.\u200C≯✳; [B1, B5, C1]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5] # ᠢ𐮂𐫘寐.≯✳
+xn--46e6675axzzhota.xn--hdh99p; ᠢ𐮂𐫘寐.≯✳; [B1, B5]; xn--46e6675axzzhota.xn--hdh99p; ; ; # ᠢ𐮂𐫘寐.≯✳
+xn--46e6675axzzhota.xn--0ug06gu8f; ᠢ𐮂𐫘寐.\u200C≯✳; [B1, B5, C1]; xn--46e6675axzzhota.xn--0ug06gu8f; ; ; # ᠢ𐮂𐫘寐.≯✳
+\u200D。󸲜ႺႴ𞨇; \u200D.󸲜ႺႴ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--sndl01647an3h1h; ; .xn--sndl01647an3h1h; [B5, B6, V6, A4_2] # .ႺႴ
+\u200D。󸲜ႺႴ𞨇; \u200D.󸲜ႺႴ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--sndl01647an3h1h; ; .xn--sndl01647an3h1h; [B5, B6, V6, A4_2] # .ႺႴ
+\u200D。󸲜ⴚⴔ𞨇; \u200D.󸲜ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--cljl81825an3r4h; ; .xn--cljl81825an3r4h; [B5, B6, V6, A4_2] # .ⴚⴔ
+\u200D。󸲜Ⴚⴔ𞨇; \u200D.󸲜Ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--ynd036lq981an3r4h; ; .xn--ynd036lq981an3r4h; [B5, B6, V6, A4_2] # .Ⴚⴔ
+.xn--ynd036lq981an3r4h; .󸲜Ⴚⴔ𞨇; [B5, B6, V6, X4_2]; .xn--ynd036lq981an3r4h; [B5, B6, V6, A4_2]; ; # .Ⴚⴔ
+xn--1ug.xn--ynd036lq981an3r4h; \u200D.󸲜Ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--ynd036lq981an3r4h; ; ; # .Ⴚⴔ
+.xn--cljl81825an3r4h; .󸲜ⴚⴔ𞨇; [B5, B6, V6, X4_2]; .xn--cljl81825an3r4h; [B5, B6, V6, A4_2]; ; # .ⴚⴔ
+xn--1ug.xn--cljl81825an3r4h; \u200D.󸲜ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--cljl81825an3r4h; ; ; # .ⴚⴔ
+.xn--sndl01647an3h1h; .󸲜ႺႴ𞨇; [B5, B6, V6, X4_2]; .xn--sndl01647an3h1h; [B5, B6, V6, A4_2]; ; # .ႺႴ
+xn--1ug.xn--sndl01647an3h1h; \u200D.󸲜ႺႴ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--sndl01647an3h1h; ; ; # .ႺႴ
+\u200D。󸲜ⴚⴔ𞨇; \u200D.󸲜ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--cljl81825an3r4h; ; .xn--cljl81825an3r4h; [B5, B6, V6, A4_2] # .ⴚⴔ
+\u200D。󸲜Ⴚⴔ𞨇; \u200D.󸲜Ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--ynd036lq981an3r4h; ; .xn--ynd036lq981an3r4h; [B5, B6, V6, A4_2] # .Ⴚⴔ
+-3.\u200Dヌᢕ; ; [C2, V3]; -3.xn--fbf739aq5o; ; -3.xn--fbf115j; [V3] # -3.ヌᢕ
+-3.xn--fbf115j; -3.ヌᢕ; [V3]; -3.xn--fbf115j; ; ; # -3.ヌᢕ
+-3.xn--fbf739aq5o; -3.\u200Dヌᢕ; [C2, V3]; -3.xn--fbf739aq5o; ; ; # -3.ヌᢕ
+🂃\u0666ß\u200D。󠠂򭰍𞩒-; 🂃\u0666ß\u200D.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--zca34z68yzu83b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, V3, V6] # 🂃٦ß.-
+🂃\u0666SS\u200D。󠠂򭰍𞩒-; 🂃\u0666ss\u200D.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, V3, V6] # 🂃٦ss.-
+🂃\u0666ss\u200D。󠠂򭰍𞩒-; 🂃\u0666ss\u200D.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, V3, V6] # 🂃٦ss.-
+xn--ss-pyd98921c.xn----nz8rh7531csznt; 🂃\u0666ss.󠠂򭰍𞩒-; [B1, V3, V6]; xn--ss-pyd98921c.xn----nz8rh7531csznt; ; ; # 🂃٦ss.-
+xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; 🂃\u0666ss\u200D.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; ; # 🂃٦ss.-
+xn--zca34z68yzu83b.xn----nz8rh7531csznt; 🂃\u0666ß\u200D.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--zca34z68yzu83b.xn----nz8rh7531csznt; ; ; # 🂃٦ß.-
+🂃\u0666Ss\u200D。󠠂򭰍𞩒-; 🂃\u0666ss\u200D.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, V3, V6] # 🂃٦ss.-
+ꇟ-𐾺\u069F。򰀺\u200C; ꇟ-𐾺\u069F.򰀺\u200C; [B5, B6, C1, V6]; xn----utc4430jd3zd.xn--0ugx6670i; ; xn----utc4430jd3zd.xn--bp20d; [B5, B6, V6] # ꇟ-𐾺ڟ.
+xn----utc4430jd3zd.xn--bp20d; ꇟ-𐾺\u069F.򰀺; [B5, B6, V6]; xn----utc4430jd3zd.xn--bp20d; ; ; # ꇟ-𐾺ڟ.
+xn----utc4430jd3zd.xn--0ugx6670i; ꇟ-𐾺\u069F.򰀺\u200C; [B5, B6, C1, V6]; xn----utc4430jd3zd.xn--0ugx6670i; ; ; # ꇟ-𐾺ڟ.
+\u0665.\u0484𐨗𝩋𴤃; ; [B1, V5, V6]; xn--eib.xn--n3a0405kus8eft5l; ; ; # ٥.҄𐨗𝩋
+xn--eib.xn--n3a0405kus8eft5l; \u0665.\u0484𐨗𝩋𴤃; [B1, V5, V6]; xn--eib.xn--n3a0405kus8eft5l; ; ; # ٥.҄𐨗𝩋
+-.񱼓\u0649𐨿; ; [B1, B5, B6, V3, V6]; -.xn--lhb4124khbq4b; ; ; # -.ى𐨿
+-.xn--lhb4124khbq4b; -.񱼓\u0649𐨿; [B1, B5, B6, V3, V6]; -.xn--lhb4124khbq4b; ; ; # -.ى𐨿
+󾬨ς.𞶙녫ß; ; [B2, B3, V6]; xn--3xa96659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # ς.녫ß
+󾬨ς.𞶙녫ß; 󾬨ς.𞶙녫ß; [B2, B3, V6]; xn--3xa96659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # ς.녫ß
+󾬨Σ.𞶙녫SS; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫SS; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨σ.𞶙녫ss; ; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨σ.𞶙녫ss; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫ss; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫ss; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫Ss; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫Ss; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+xn--4xa76659r.xn--ss-d64i8755h; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫ß; 󾬨σ.𞶙녫ß; [B2, B3, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+󾬨Σ.𞶙녫ß; 󾬨σ.𞶙녫ß; [B2, B3, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+󾬨σ.𞶙녫ß; ; [B2, B3, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+󾬨σ.𞶙녫ß; 󾬨σ.𞶙녫ß; [B2, B3, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+xn--4xa76659r.xn--zca5051g4h4i; 󾬨σ.𞶙녫ß; [B2, B3, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; ; # σ.녫ß
+xn--3xa96659r.xn--zca5051g4h4i; 󾬨ς.𞶙녫ß; [B2, B3, V6]; xn--3xa96659r.xn--zca5051g4h4i; ; ; # ς.녫ß
+Ⅎ\u17D2\u200D。≠\u200D\u200C; Ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [V6] # Ⅎ្.≠
+Ⅎ\u17D2\u200D。=\u0338\u200D\u200C; Ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [V6] # Ⅎ្.≠
+Ⅎ\u17D2\u200D。≠\u200D\u200C; Ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [V6] # Ⅎ្.≠
+Ⅎ\u17D2\u200D。=\u0338\u200D\u200C; Ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [V6] # Ⅎ្.≠
+ⅎ\u17D2\u200D。=\u0338\u200D\u200C; ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [] # ⅎ្.≠
+ⅎ\u17D2\u200D。≠\u200D\u200C; ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [] # ⅎ្.≠
+xn--u4e969b.xn--1ch; ⅎ\u17D2.≠; ; xn--u4e969b.xn--1ch; ; ; # ⅎ្.≠
+ⅎ\u17D2.≠; ; ; xn--u4e969b.xn--1ch; ; ; # ⅎ្.≠
+ⅎ\u17D2.=\u0338; ⅎ\u17D2.≠; ; xn--u4e969b.xn--1ch; ; ; # ⅎ្.≠
+Ⅎ\u17D2.=\u0338; Ⅎ\u17D2.≠; [V6]; xn--u4e319b.xn--1ch; ; ; # Ⅎ្.≠
+Ⅎ\u17D2.≠; ; [V6]; xn--u4e319b.xn--1ch; ; ; # Ⅎ្.≠
+xn--u4e319b.xn--1ch; Ⅎ\u17D2.≠; [V6]; xn--u4e319b.xn--1ch; ; ; # Ⅎ្.≠
+xn--u4e823bq1a.xn--0ugb89o; ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2]; xn--u4e823bq1a.xn--0ugb89o; ; ; # ⅎ្.≠
+xn--u4e823bcza.xn--0ugb89o; Ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2, V6]; xn--u4e823bcza.xn--0ugb89o; ; ; # Ⅎ្.≠
+ⅎ\u17D2\u200D。=\u0338\u200D\u200C; ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [] # ⅎ្.≠
+ⅎ\u17D2\u200D。≠\u200D\u200C; ⅎ\u17D2\u200D.≠\u200D\u200C; [C1, C2]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [] # ⅎ្.≠
+𐋺\uAAF6\uA953󧦉.\u200C\u1714\u068F; 𐋺\uAAF6\uA953󧦉.\u200C\u1714\u068F; [B1, C1, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f1wg; ; xn--3j9a14ak27osbz2o.xn--ljb175f; [B1, V5, V6] # 𐋺꫶꥓.᜔ڏ
+𐋺\uAAF6\uA953󧦉.\u200C\u1714\u068F; ; [B1, C1, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f1wg; ; xn--3j9a14ak27osbz2o.xn--ljb175f; [B1, V5, V6] # 𐋺꫶꥓.᜔ڏ
+xn--3j9a14ak27osbz2o.xn--ljb175f; 𐋺\uAAF6\uA953󧦉.\u1714\u068F; [B1, V5, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f; ; ; # 𐋺꫶꥓.᜔ڏ
+xn--3j9a14ak27osbz2o.xn--ljb175f1wg; 𐋺\uAAF6\uA953󧦉.\u200C\u1714\u068F; [B1, C1, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f1wg; ; ; # 𐋺꫶꥓.᜔ڏ
+񺔯\u0FA8.≯; 񺔯\u0FA8.≯; [V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+񺔯\u0FA8.>\u0338; 񺔯\u0FA8.≯; [V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+񺔯\u0FA8.≯; ; [V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+񺔯\u0FA8.>\u0338; 񺔯\u0FA8.≯; [V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+xn--4fd57150h.xn--hdh; 񺔯\u0FA8.≯; [V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+\u200D𞡄Ⴓ.𐇽; \u200D𞡄Ⴓ.𐇽; [B1, C2, V5, V6]; xn--rnd379ex885a.xn--m27c; ; xn--rnd5552v.xn--m27c; [B1, B2, B3, V5, V6] # 𞡄Ⴓ.𐇽
+\u200D𞡄Ⴓ.𐇽; ; [B1, C2, V5, V6]; xn--rnd379ex885a.xn--m27c; ; xn--rnd5552v.xn--m27c; [B1, B2, B3, V5, V6] # 𞡄Ⴓ.𐇽
+\u200D𞡄ⴓ.𐇽; ; [B1, C2, V5]; xn--1ugz52c4i16a.xn--m27c; ; xn--blj7492l.xn--m27c; [B1, B2, B3, V5] # 𞡄ⴓ.𐇽
+xn--blj7492l.xn--m27c; 𞡄ⴓ.𐇽; [B1, B2, B3, V5]; xn--blj7492l.xn--m27c; ; ; # 𞡄ⴓ.𐇽
+xn--1ugz52c4i16a.xn--m27c; \u200D𞡄ⴓ.𐇽; [B1, C2, V5]; xn--1ugz52c4i16a.xn--m27c; ; ; # 𞡄ⴓ.𐇽
+xn--rnd5552v.xn--m27c; 𞡄Ⴓ.𐇽; [B1, B2, B3, V5, V6]; xn--rnd5552v.xn--m27c; ; ; # 𞡄Ⴓ.𐇽
+xn--rnd379ex885a.xn--m27c; \u200D𞡄Ⴓ.𐇽; [B1, C2, V5, V6]; xn--rnd379ex885a.xn--m27c; ; ; # 𞡄Ⴓ.𐇽
+\u200D𞡄ⴓ.𐇽; \u200D𞡄ⴓ.𐇽; [B1, C2, V5]; xn--1ugz52c4i16a.xn--m27c; ; xn--blj7492l.xn--m27c; [B1, B2, B3, V5] # 𞡄ⴓ.𐇽
+𐪒ß\uA8EA.ᡤ; 𐪒ß\uA8EA.ᡤ; [B2, B3]; xn--zca2517f2hvc.xn--08e; ; xn--ss-tu9hw933a.xn--08e; # 𐪒ß꣪.ᡤ
+𐪒ß\uA8EA.ᡤ; ; [B2, B3]; xn--zca2517f2hvc.xn--08e; ; xn--ss-tu9hw933a.xn--08e; # 𐪒ß꣪.ᡤ
+𐪒SS\uA8EA.ᡤ; 𐪒ss\uA8EA.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒ss\uA8EA.ᡤ; ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+xn--ss-tu9hw933a.xn--08e; 𐪒ss\uA8EA.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+xn--zca2517f2hvc.xn--08e; 𐪒ß\uA8EA.ᡤ; [B2, B3]; xn--zca2517f2hvc.xn--08e; ; ; # 𐪒ß꣪.ᡤ
+𐪒SS\uA8EA.ᡤ; 𐪒ss\uA8EA.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒ss\uA8EA.ᡤ; 𐪒ss\uA8EA.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒Ss\uA8EA.ᡤ; 𐪒ss\uA8EA.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒Ss\uA8EA.ᡤ; 𐪒ss\uA8EA.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐨿󠆌鸮𑚶.ς; 𐨿鸮𑚶.ς; [V5]; xn--l76a726rt2h.xn--3xa; ; xn--l76a726rt2h.xn--4xa; # 𐨿鸮𑚶.ς
+𐨿󠆌鸮𑚶.Σ; 𐨿鸮𑚶.σ; [V5]; xn--l76a726rt2h.xn--4xa; ; ; # 𐨿鸮𑚶.σ
+𐨿󠆌鸮𑚶.σ; 𐨿鸮𑚶.σ; [V5]; xn--l76a726rt2h.xn--4xa; ; ; # 𐨿鸮𑚶.σ
+xn--l76a726rt2h.xn--4xa; 𐨿鸮𑚶.σ; [V5]; xn--l76a726rt2h.xn--4xa; ; ; # 𐨿鸮𑚶.σ
+xn--l76a726rt2h.xn--3xa; 𐨿鸮𑚶.ς; [V5]; xn--l76a726rt2h.xn--3xa; ; ; # 𐨿鸮𑚶.ς
+⒗𞤬。-𑚶; ⒗𞤬.-𑚶; [B1, V3, V6]; xn--8shw466n.xn----4j0j; ; ; # ⒗𞤬.-𑚶
+16.𞤬。-𑚶; 16.𞤬.-𑚶; [B1, V3]; 16.xn--ke6h.xn----4j0j; ; ; # 16.𞤬.-𑚶
+16.𞤊。-𑚶; 16.𞤬.-𑚶; [B1, V3]; 16.xn--ke6h.xn----4j0j; ; ; # 16.𞤬.-𑚶
+16.xn--ke6h.xn----4j0j; 16.𞤬.-𑚶; [B1, V3]; 16.xn--ke6h.xn----4j0j; ; ; # 16.𞤬.-𑚶
+⒗𞤊。-𑚶; ⒗𞤬.-𑚶; [B1, V3, V6]; xn--8shw466n.xn----4j0j; ; ; # ⒗𞤬.-𑚶
+xn--8shw466n.xn----4j0j; ⒗𞤬.-𑚶; [B1, V3, V6]; xn--8shw466n.xn----4j0j; ; ; # ⒗𞤬.-𑚶
+\u08B3𞤿⾫。𐹣\u068F⒈; \u08B3𞤿隹.𐹣\u068F⒈; [B1, B2, B3, V6]; xn--8yb0383efiwk.xn--ljb064mol4n; ; ; # ࢳ𞤿隹.𐹣ڏ⒈
+\u08B3𞤿隹。𐹣\u068F1.; \u08B3𞤿隹.𐹣\u068F1.; [B1, B2, B3]; xn--8yb0383efiwk.xn--1-wsc3373r.; ; ; # ࢳ𞤿隹.𐹣ڏ1.
+\u08B3𞤝隹。𐹣\u068F1.; \u08B3𞤿隹.𐹣\u068F1.; [B1, B2, B3]; xn--8yb0383efiwk.xn--1-wsc3373r.; ; ; # ࢳ𞤿隹.𐹣ڏ1.
+xn--8yb0383efiwk.xn--1-wsc3373r.; \u08B3𞤿隹.𐹣\u068F1.; [B1, B2, B3]; xn--8yb0383efiwk.xn--1-wsc3373r.; ; ; # ࢳ𞤿隹.𐹣ڏ1.
+\u08B3𞤝⾫。𐹣\u068F⒈; \u08B3𞤿隹.𐹣\u068F⒈; [B1, B2, B3, V6]; xn--8yb0383efiwk.xn--ljb064mol4n; ; ; # ࢳ𞤿隹.𐹣ڏ⒈
+xn--8yb0383efiwk.xn--ljb064mol4n; \u08B3𞤿隹.𐹣\u068F⒈; [B1, B2, B3, V6]; xn--8yb0383efiwk.xn--ljb064mol4n; ; ; # ࢳ𞤿隹.𐹣ڏ⒈
+\u2433𚎛𝟧\u0661.ᡢ8\u0F72\u0600; \u2433𚎛5\u0661.ᡢ8\u0F72\u0600; [B5, B6, V6]; xn--5-bqc410un435a.xn--8-rkc763epjj; ; ; # 5١.ᡢ8ི
+\u2433𚎛5\u0661.ᡢ8\u0F72\u0600; ; [B5, B6, V6]; xn--5-bqc410un435a.xn--8-rkc763epjj; ; ; # 5١.ᡢ8ི
+xn--5-bqc410un435a.xn--8-rkc763epjj; \u2433𚎛5\u0661.ᡢ8\u0F72\u0600; [B5, B6, V6]; xn--5-bqc410un435a.xn--8-rkc763epjj; ; ; # 5١.ᡢ8ི
+𐹠.🄀⒒-󨰈; ; [B1, V6]; xn--7n0d.xn----xcp9757q1s13g; ; ; # 𐹠.🄀⒒-
+𐹠.0.11.-󨰈; ; [B1, V3, V6]; xn--7n0d.0.11.xn----8j07m; ; ; # 𐹠.0.11.-
+xn--7n0d.0.11.xn----8j07m; 𐹠.0.11.-󨰈; [B1, V3, V6]; xn--7n0d.0.11.xn----8j07m; ; ; # 𐹠.0.11.-
+xn--7n0d.xn----xcp9757q1s13g; 𐹠.🄀⒒-󨰈; [B1, V6]; xn--7n0d.xn----xcp9757q1s13g; ; ; # 𐹠.🄀⒒-
+ς-。\u200C𝟭-; ς-.\u200C1-; [C1, V3]; xn----xmb.xn--1--i1t; ; xn----zmb.1-; [V3] # ς-.1-
+ς-。\u200C1-; ς-.\u200C1-; [C1, V3]; xn----xmb.xn--1--i1t; ; xn----zmb.1-; [V3] # ς-.1-
+Σ-。\u200C1-; σ-.\u200C1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+σ-。\u200C1-; σ-.\u200C1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+xn----zmb.1-; σ-.1-; [V3]; xn----zmb.1-; ; ; # σ-.1-
+xn----zmb.xn--1--i1t; σ-.\u200C1-; [C1, V3]; xn----zmb.xn--1--i1t; ; ; # σ-.1-
+xn----xmb.xn--1--i1t; ς-.\u200C1-; [C1, V3]; xn----xmb.xn--1--i1t; ; ; # ς-.1-
+Σ-。\u200C𝟭-; σ-.\u200C1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+σ-。\u200C𝟭-; σ-.\u200C1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+\u1734-\u0CE2.󠄩Ⴄ; \u1734-\u0CE2.Ⴄ; [V5, V6]; xn----ggf830f.xn--cnd; ; ; # ᜴-ೢ.Ⴄ
+\u1734-\u0CE2.󠄩Ⴄ; \u1734-\u0CE2.Ⴄ; [V5, V6]; xn----ggf830f.xn--cnd; ; ; # ᜴-ೢ.Ⴄ
+\u1734-\u0CE2.󠄩ⴄ; \u1734-\u0CE2.ⴄ; [V5]; xn----ggf830f.xn--vkj; ; ; # ᜴-ೢ.ⴄ
+xn----ggf830f.xn--vkj; \u1734-\u0CE2.ⴄ; [V5]; xn----ggf830f.xn--vkj; ; ; # ᜴-ೢ.ⴄ
+xn----ggf830f.xn--cnd; \u1734-\u0CE2.Ⴄ; [V5, V6]; xn----ggf830f.xn--cnd; ; ; # ᜴-ೢ.Ⴄ
+\u1734-\u0CE2.󠄩ⴄ; \u1734-\u0CE2.ⴄ; [V5]; xn----ggf830f.xn--vkj; ; ; # ᜴-ೢ.ⴄ
+򭈗♋\u06BB𐦥。\u0954⒈; 򭈗♋\u06BB𐦥.\u0954⒈; [B1, B5, B6, V5, V6]; xn--ukb372n129m3rs7f.xn--u3b240l; ; ; # ♋ڻ𐦥.॔⒈
+򭈗♋\u06BB𐦥。\u09541.; 򭈗♋\u06BB𐦥.\u09541.; [B1, B5, B6, V5, V6]; xn--ukb372n129m3rs7f.xn--1-fyd.; ; ; # ♋ڻ𐦥.॔1.
+xn--ukb372n129m3rs7f.xn--1-fyd.; 򭈗♋\u06BB𐦥.\u09541.; [B1, B5, B6, V5, V6]; xn--ukb372n129m3rs7f.xn--1-fyd.; ; ; # ♋ڻ𐦥.॔1.
+xn--ukb372n129m3rs7f.xn--u3b240l; 򭈗♋\u06BB𐦥.\u0954⒈; [B1, B5, B6, V5, V6]; xn--ukb372n129m3rs7f.xn--u3b240l; ; ; # ♋ڻ𐦥.॔⒈
+\u05A4.\u06C1\u1AB3\u200C; \u05A4.\u06C1\u1AB3\u200C; [B1, B3, C1, V5]; xn--vcb.xn--0kb623hm1d; ; xn--vcb.xn--0kb623h; [B1, V5] # ֤.ہ᪳
+\u05A4.\u06C1\u1AB3\u200C; ; [B1, B3, C1, V5]; xn--vcb.xn--0kb623hm1d; ; xn--vcb.xn--0kb623h; [B1, V5] # ֤.ہ᪳
+xn--vcb.xn--0kb623h; \u05A4.\u06C1\u1AB3; [B1, V5]; xn--vcb.xn--0kb623h; ; ; # ֤.ہ᪳
+xn--vcb.xn--0kb623hm1d; \u05A4.\u06C1\u1AB3\u200C; [B1, B3, C1, V5]; xn--vcb.xn--0kb623hm1d; ; ; # ֤.ہ᪳
+񢭏\u0846≮\u0ACD.𞦊; 񢭏\u0846≮\u0ACD.𞦊; [B5, B6, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+񢭏\u0846<\u0338\u0ACD.𞦊; 񢭏\u0846≮\u0ACD.𞦊; [B5, B6, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+񢭏\u0846≮\u0ACD.𞦊; ; [B5, B6, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+񢭏\u0846<\u0338\u0ACD.𞦊; 񢭏\u0846≮\u0ACD.𞦊; [B5, B6, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+xn--4vb80kq29ayo62l.xn--8g6h; 񢭏\u0846≮\u0ACD.𞦊; [B5, B6, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+\u200D。𞀘⒈ꡍ擉; \u200D.𞀘⒈ꡍ擉; [C2, V5, V6]; xn--1ug.xn--tsh026uql4bew9p; ; .xn--tsh026uql4bew9p; [V5, V6, A4_2] # .𞀘⒈ꡍ擉
+\u200D。𞀘1.ꡍ擉; \u200D.𞀘1.ꡍ擉; [C2, V5]; xn--1ug.xn--1-1p4r.xn--s7uv61m; ; .xn--1-1p4r.xn--s7uv61m; [V5, A4_2] # .𞀘1.ꡍ擉
+.xn--1-1p4r.xn--s7uv61m; .𞀘1.ꡍ擉; [V5, X4_2]; .xn--1-1p4r.xn--s7uv61m; [V5, A4_2]; ; # .𞀘1.ꡍ擉
+xn--1ug.xn--1-1p4r.xn--s7uv61m; \u200D.𞀘1.ꡍ擉; [C2, V5]; xn--1ug.xn--1-1p4r.xn--s7uv61m; ; ; # .𞀘1.ꡍ擉
+.xn--tsh026uql4bew9p; .𞀘⒈ꡍ擉; [V5, V6, X4_2]; .xn--tsh026uql4bew9p; [V5, V6, A4_2]; ; # .𞀘⒈ꡍ擉
+xn--1ug.xn--tsh026uql4bew9p; \u200D.𞀘⒈ꡍ擉; [C2, V5, V6]; xn--1ug.xn--tsh026uql4bew9p; ; ; # .𞀘⒈ꡍ擉
+₈\u07CB.\uFB64≠; 8\u07CB.\u067F≠; [B1, B3]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+₈\u07CB.\uFB64=\u0338; 8\u07CB.\u067F≠; [B1, B3]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+8\u07CB.\u067F≠; ; [B1, B3]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+8\u07CB.\u067F=\u0338; 8\u07CB.\u067F≠; [B1, B3]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+xn--8-zbd.xn--4ib883l; 8\u07CB.\u067F≠; [B1, B3]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+ᢡ\u07DE򹐣.⒒\u0642𑍦; ; [B1, B5, V6]; xn--5sb596fi873t.xn--ehb336mvy7n; ; ; # ᢡߞ.⒒ق𑍦
+ᢡ\u07DE򹐣.11.\u0642𑍦; ; [B1, B5, V6]; xn--5sb596fi873t.11.xn--ehb4198k; ; ; # ᢡߞ.11.ق𑍦
+xn--5sb596fi873t.11.xn--ehb4198k; ᢡ\u07DE򹐣.11.\u0642𑍦; [B1, B5, V6]; xn--5sb596fi873t.11.xn--ehb4198k; ; ; # ᢡߞ.11.ق𑍦
+xn--5sb596fi873t.xn--ehb336mvy7n; ᢡ\u07DE򹐣.⒒\u0642𑍦; [B1, B5, V6]; xn--5sb596fi873t.xn--ehb336mvy7n; ; ; # ᢡߞ.⒒ق𑍦
+\u0E48-𐹺𝟜.\u0363\u06E1⒏; \u0E48-𐹺4.\u0363\u06E1⒏; [B1, V5, V6]; xn---4-owiz479s.xn--eva20pjv9a; ; ; # ่-𐹺4.ͣۡ⒏
+\u0E48-𐹺4.\u0363\u06E18.; ; [B1, V5]; xn---4-owiz479s.xn--8-ihb69x.; ; ; # ่-𐹺4.ͣۡ8.
+xn---4-owiz479s.xn--8-ihb69x.; \u0E48-𐹺4.\u0363\u06E18.; [B1, V5]; xn---4-owiz479s.xn--8-ihb69x.; ; ; # ่-𐹺4.ͣۡ8.
+xn---4-owiz479s.xn--eva20pjv9a; \u0E48-𐹺4.\u0363\u06E1⒏; [B1, V5, V6]; xn---4-owiz479s.xn--eva20pjv9a; ; ; # ่-𐹺4.ͣۡ⒏
+⫐。Ⴠ-󃐢; ⫐.Ⴠ-󃐢; [V6]; xn--r3i.xn----z1g58579u; ; ; # ⫐.Ⴠ-
+⫐。Ⴠ-󃐢; ⫐.Ⴠ-󃐢; [V6]; xn--r3i.xn----z1g58579u; ; ; # ⫐.Ⴠ-
+⫐。ⴠ-󃐢; ⫐.ⴠ-󃐢; [V6]; xn--r3i.xn----2wst7439i; ; ; # ⫐.ⴠ-
+xn--r3i.xn----2wst7439i; ⫐.ⴠ-󃐢; [V6]; xn--r3i.xn----2wst7439i; ; ; # ⫐.ⴠ-
+xn--r3i.xn----z1g58579u; ⫐.Ⴠ-󃐢; [V6]; xn--r3i.xn----z1g58579u; ; ; # ⫐.Ⴠ-
+⫐。ⴠ-󃐢; ⫐.ⴠ-󃐢; [V6]; xn--r3i.xn----2wst7439i; ; ; # ⫐.ⴠ-
+𑑂◊.⦟∠; 𑑂◊.⦟∠; [V5]; xn--01h3338f.xn--79g270a; ; ; # 𑑂◊.⦟∠
+𑑂◊.⦟∠; ; [V5]; xn--01h3338f.xn--79g270a; ; ; # 𑑂◊.⦟∠
+xn--01h3338f.xn--79g270a; 𑑂◊.⦟∠; [V5]; xn--01h3338f.xn--79g270a; ; ; # 𑑂◊.⦟∠
+𿌰-\u0662。󋸛ꡂ; 𿌰-\u0662.󋸛ꡂ; [B5, B6, V6]; xn----dqc20828e.xn--bc9an2879c; ; ; # -٢.ꡂ
+xn----dqc20828e.xn--bc9an2879c; 𿌰-\u0662.󋸛ꡂ; [B5, B6, V6]; xn----dqc20828e.xn--bc9an2879c; ; ; # -٢.ꡂ
+\u0678。󠏬\u0741𞪭𐹪; \u064A\u0674.󠏬\u0741𞪭𐹪; [B1, V6]; xn--mhb8f.xn--oob2585kfdsfsbo7h; ; ; # يٴ.݁𐹪
+\u064A\u0674。󠏬\u0741𞪭𐹪; \u064A\u0674.󠏬\u0741𞪭𐹪; [B1, V6]; xn--mhb8f.xn--oob2585kfdsfsbo7h; ; ; # يٴ.݁𐹪
+xn--mhb8f.xn--oob2585kfdsfsbo7h; \u064A\u0674.󠏬\u0741𞪭𐹪; [B1, V6]; xn--mhb8f.xn--oob2585kfdsfsbo7h; ; ; # يٴ.݁𐹪
+𐫆ꌄ。\u200Dᣬ; 𐫆ꌄ.\u200Dᣬ; [B1, B2, B3, C2]; xn--y77ao18q.xn--wdf367a; ; xn--y77ao18q.xn--wdf; [B2, B3] # 𐫆ꌄ.ᣬ
+𐫆ꌄ。\u200Dᣬ; 𐫆ꌄ.\u200Dᣬ; [B1, B2, B3, C2]; xn--y77ao18q.xn--wdf367a; ; xn--y77ao18q.xn--wdf; [B2, B3] # 𐫆ꌄ.ᣬ
+xn--y77ao18q.xn--wdf; 𐫆ꌄ.ᣬ; [B2, B3]; xn--y77ao18q.xn--wdf; ; ; # 𐫆ꌄ.ᣬ
+xn--y77ao18q.xn--wdf367a; 𐫆ꌄ.\u200Dᣬ; [B1, B2, B3, C2]; xn--y77ao18q.xn--wdf367a; ; ; # 𐫆ꌄ.ᣬ
+₀\u0662。󅪞≯-; 0\u0662.󅪞≯-; [B1, B6, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+₀\u0662。󅪞>\u0338-; 0\u0662.󅪞≯-; [B1, B6, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+0\u0662。󅪞≯-; 0\u0662.󅪞≯-; [B1, B6, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+0\u0662。󅪞>\u0338-; 0\u0662.󅪞≯-; [B1, B6, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+xn--0-dqc.xn----ogov3342l; 0\u0662.󅪞≯-; [B1, B6, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+\u031C𐹫-𞯃.𐋤\u0845; ; [B1, V5, V6]; xn----gdb7046r692g.xn--3vb1349j; ; ; # ̜𐹫-.𐋤ࡅ
+xn----gdb7046r692g.xn--3vb1349j; \u031C𐹫-𞯃.𐋤\u0845; [B1, V5, V6]; xn----gdb7046r692g.xn--3vb1349j; ; ; # ̜𐹫-.𐋤ࡅ
+≠。𝩑𐹩Ⴡ\u0594; ≠.𝩑𐹩Ⴡ\u0594; [B1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+=\u0338。𝩑𐹩Ⴡ\u0594; ≠.𝩑𐹩Ⴡ\u0594; [B1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+≠。𝩑𐹩Ⴡ\u0594; ≠.𝩑𐹩Ⴡ\u0594; [B1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+=\u0338。𝩑𐹩Ⴡ\u0594; ≠.𝩑𐹩Ⴡ\u0594; [B1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+=\u0338。𝩑𐹩ⴡ\u0594; ≠.𝩑𐹩ⴡ\u0594; [B1, V5]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+≠。𝩑𐹩ⴡ\u0594; ≠.𝩑𐹩ⴡ\u0594; [B1, V5]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+xn--1ch.xn--fcb363rk03mypug; ≠.𝩑𐹩ⴡ\u0594; [B1, V5]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+xn--1ch.xn--fcb538c649rypog; ≠.𝩑𐹩Ⴡ\u0594; [B1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+=\u0338。𝩑𐹩ⴡ\u0594; ≠.𝩑𐹩ⴡ\u0594; [B1, V5]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+≠。𝩑𐹩ⴡ\u0594; ≠.𝩑𐹩ⴡ\u0594; [B1, V5]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+𖫳≠.Ⴀ𐮀; ; [B1, B5, B6, V5, V6]; xn--1ch9250k.xn--7md2659j; ; ; # 𖫳≠.Ⴀ𐮀
+𖫳=\u0338.Ⴀ𐮀; 𖫳≠.Ⴀ𐮀; [B1, B5, B6, V5, V6]; xn--1ch9250k.xn--7md2659j; ; ; # 𖫳≠.Ⴀ𐮀
+𖫳=\u0338.ⴀ𐮀; 𖫳≠.ⴀ𐮀; [B1, B5, B6, V5]; xn--1ch9250k.xn--rkj6232e; ; ; # 𖫳≠.ⴀ𐮀
+𖫳≠.ⴀ𐮀; ; [B1, B5, B6, V5]; xn--1ch9250k.xn--rkj6232e; ; ; # 𖫳≠.ⴀ𐮀
+xn--1ch9250k.xn--rkj6232e; 𖫳≠.ⴀ𐮀; [B1, B5, B6, V5]; xn--1ch9250k.xn--rkj6232e; ; ; # 𖫳≠.ⴀ𐮀
+xn--1ch9250k.xn--7md2659j; 𖫳≠.Ⴀ𐮀; [B1, B5, B6, V5, V6]; xn--1ch9250k.xn--7md2659j; ; ; # 𖫳≠.Ⴀ𐮀
+󠅾\u0736\u0726.ᢚ閪\u08E2𝩟; \u0736\u0726.ᢚ閪\u08E2𝩟; [B1, B5, B6, V5, V6]; xn--wnb5a.xn--l0b161fis8gbp5m; ; ; # ܶܦ.ᢚ閪𝩟
+󠅾\u0736\u0726.ᢚ閪\u08E2𝩟; \u0736\u0726.ᢚ閪\u08E2𝩟; [B1, B5, B6, V5, V6]; xn--wnb5a.xn--l0b161fis8gbp5m; ; ; # ܶܦ.ᢚ閪𝩟
+xn--wnb5a.xn--l0b161fis8gbp5m; \u0736\u0726.ᢚ閪\u08E2𝩟; [B1, B5, B6, V5, V6]; xn--wnb5a.xn--l0b161fis8gbp5m; ; ; # ܶܦ.ᢚ閪𝩟
+\u200D󠇜\u06CB\uA8E9。\u20DD\u0FB0-ᛟ; \u200D\u06CB\uA8E9.\u20DD\u0FB0-ᛟ; [B1, C2, V5]; xn--blb540ke10h.xn----gmg236cj6k; ; xn--blb8114f.xn----gmg236cj6k; [B1, V5] # ۋ꣩.⃝ྰ-ᛟ
+\u200D󠇜\u06CB\uA8E9。\u20DD\u0FB0-ᛟ; \u200D\u06CB\uA8E9.\u20DD\u0FB0-ᛟ; [B1, C2, V5]; xn--blb540ke10h.xn----gmg236cj6k; ; xn--blb8114f.xn----gmg236cj6k; [B1, V5] # ۋ꣩.⃝ྰ-ᛟ
+xn--blb8114f.xn----gmg236cj6k; \u06CB\uA8E9.\u20DD\u0FB0-ᛟ; [B1, V5]; xn--blb8114f.xn----gmg236cj6k; ; ; # ۋ꣩.⃝ྰ-ᛟ
+xn--blb540ke10h.xn----gmg236cj6k; \u200D\u06CB\uA8E9.\u20DD\u0FB0-ᛟ; [B1, C2, V5]; xn--blb540ke10h.xn----gmg236cj6k; ; ; # ۋ꣩.⃝ྰ-ᛟ
+헁󘖙\u0E3A󚍚。\u06BA𝟜; 헁󘖙\u0E3A󚍚.\u06BA4; [V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+헁󘖙\u0E3A󚍚。\u06BA𝟜; 헁󘖙\u0E3A󚍚.\u06BA4; [V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+헁󘖙\u0E3A󚍚。\u06BA4; 헁󘖙\u0E3A󚍚.\u06BA4; [V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+헁󘖙\u0E3A󚍚。\u06BA4; 헁󘖙\u0E3A󚍚.\u06BA4; [V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+xn--o4c1723h8g85gt4ya.xn--4-dvc; 헁󘖙\u0E3A󚍚.\u06BA4; [V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+𐹭。󃱂\u200CႾ; 𐹭.󃱂\u200CႾ; [B1, C1, V6]; xn--lo0d.xn--2nd949eqw95u; ; xn--lo0d.xn--2nd75260n; [B1, V6] # 𐹭.Ⴞ
+𐹭。󃱂\u200CႾ; 𐹭.󃱂\u200CႾ; [B1, C1, V6]; xn--lo0d.xn--2nd949eqw95u; ; xn--lo0d.xn--2nd75260n; [B1, V6] # 𐹭.Ⴞ
+𐹭。󃱂\u200Cⴞ; 𐹭.󃱂\u200Cⴞ; [B1, C1, V6]; xn--lo0d.xn--0ugx72cwi33v; ; xn--lo0d.xn--mljx1099g; [B1, V6] # 𐹭.ⴞ
+xn--lo0d.xn--mljx1099g; 𐹭.󃱂ⴞ; [B1, V6]; xn--lo0d.xn--mljx1099g; ; ; # 𐹭.ⴞ
+xn--lo0d.xn--0ugx72cwi33v; 𐹭.󃱂\u200Cⴞ; [B1, C1, V6]; xn--lo0d.xn--0ugx72cwi33v; ; ; # 𐹭.ⴞ
+xn--lo0d.xn--2nd75260n; 𐹭.󃱂Ⴞ; [B1, V6]; xn--lo0d.xn--2nd75260n; ; ; # 𐹭.Ⴞ
+xn--lo0d.xn--2nd949eqw95u; 𐹭.󃱂\u200CႾ; [B1, C1, V6]; xn--lo0d.xn--2nd949eqw95u; ; ; # 𐹭.Ⴞ
+𐹭。󃱂\u200Cⴞ; 𐹭.󃱂\u200Cⴞ; [B1, C1, V6]; xn--lo0d.xn--0ugx72cwi33v; ; xn--lo0d.xn--mljx1099g; [B1, V6] # 𐹭.ⴞ
+\uA953.\u033D𑂽馋; ; [V5, V6]; xn--3j9a.xn--bua0708eqzrd; ; ; # ꥓.̽馋
+xn--3j9a.xn--bua0708eqzrd; \uA953.\u033D𑂽馋; [V5, V6]; xn--3j9a.xn--bua0708eqzrd; ; ; # ꥓.̽馋
+󈫝򪛸\u200D。䜖; 󈫝򪛸\u200D.䜖; [C2, V6]; xn--1ug30527h9mxi.xn--k0o; ; xn--g138cxw05a.xn--k0o; [V6] # .䜖
+󈫝򪛸\u200D。䜖; 󈫝򪛸\u200D.䜖; [C2, V6]; xn--1ug30527h9mxi.xn--k0o; ; xn--g138cxw05a.xn--k0o; [V6] # .䜖
+xn--g138cxw05a.xn--k0o; 󈫝򪛸.䜖; [V6]; xn--g138cxw05a.xn--k0o; ; ; # .䜖
+xn--1ug30527h9mxi.xn--k0o; 󈫝򪛸\u200D.䜖; [C2, V6]; xn--1ug30527h9mxi.xn--k0o; ; ; # .䜖
+ᡯ⚉姶🄉.۷\u200D🎪\u200D; ᡯ⚉姶🄉.۷\u200D🎪\u200D; [C2, V6]; xn--c9e433epi4b3j20a.xn--kmb859ja94998b; ; xn--c9e433epi4b3j20a.xn--kmb6733w; [V6] # ᡯ⚉姶🄉.۷🎪
+ᡯ⚉姶8,.۷\u200D🎪\u200D; ; [C2, V6]; xn--8,-g9oy26fzu4d.xn--kmb859ja94998b; ; xn--8,-g9oy26fzu4d.xn--kmb6733w; [V6] # ᡯ⚉姶8,.۷🎪
+xn--8,-g9oy26fzu4d.xn--kmb6733w; ᡯ⚉姶8,.۷🎪; [V6]; xn--8,-g9oy26fzu4d.xn--kmb6733w; ; ; # ᡯ⚉姶8,.۷🎪
+xn--8,-g9oy26fzu4d.xn--kmb859ja94998b; ᡯ⚉姶8,.۷\u200D🎪\u200D; [C2, V6]; xn--8,-g9oy26fzu4d.xn--kmb859ja94998b; ; ; # ᡯ⚉姶8,.۷🎪
+xn--c9e433epi4b3j20a.xn--kmb6733w; ᡯ⚉姶🄉.۷🎪; [V6]; xn--c9e433epi4b3j20a.xn--kmb6733w; ; ; # ᡯ⚉姶🄉.۷🎪
+xn--c9e433epi4b3j20a.xn--kmb859ja94998b; ᡯ⚉姶🄉.۷\u200D🎪\u200D; [C2, V6]; xn--c9e433epi4b3j20a.xn--kmb859ja94998b; ; ; # ᡯ⚉姶🄉.۷🎪
+𞽀.𐹸🚖\u0E3A; ; [B1, V6]; xn--0n7h.xn--o4c9032klszf; ; ; # .𐹸🚖ฺ
+xn--0n7h.xn--o4c9032klszf; 𞽀.𐹸🚖\u0E3A; [B1, V6]; xn--0n7h.xn--o4c9032klszf; ; ; # .𐹸🚖ฺ
+Ⴔᠵ。𐹧\u0747۹; Ⴔᠵ.𐹧\u0747۹; [B1, V6]; xn--snd659a.xn--mmb9ml895e; ; ; # Ⴔᠵ.𐹧݇۹
+Ⴔᠵ。𐹧\u0747۹; Ⴔᠵ.𐹧\u0747۹; [B1, V6]; xn--snd659a.xn--mmb9ml895e; ; ; # Ⴔᠵ.𐹧݇۹
+ⴔᠵ。𐹧\u0747۹; ⴔᠵ.𐹧\u0747۹; [B1]; xn--o7e997h.xn--mmb9ml895e; ; ; # ⴔᠵ.𐹧݇۹
+xn--o7e997h.xn--mmb9ml895e; ⴔᠵ.𐹧\u0747۹; [B1]; xn--o7e997h.xn--mmb9ml895e; ; ; # ⴔᠵ.𐹧݇۹
+xn--snd659a.xn--mmb9ml895e; Ⴔᠵ.𐹧\u0747۹; [B1, V6]; xn--snd659a.xn--mmb9ml895e; ; ; # Ⴔᠵ.𐹧݇۹
+ⴔᠵ。𐹧\u0747۹; ⴔᠵ.𐹧\u0747۹; [B1]; xn--o7e997h.xn--mmb9ml895e; ; ; # ⴔᠵ.𐹧݇۹
+\u135Fᡈ\u200C.︒-𖾐-; \u135Fᡈ\u200C.︒-𖾐-; [C1, V3, V5, V6]; xn--b7d82wo4h.xn-----c82nz547a; ; xn--b7d82w.xn-----c82nz547a; [V3, V5, V6] # ፟ᡈ.︒-𖾐-
+\u135Fᡈ\u200C.。-𖾐-; \u135Fᡈ\u200C..-𖾐-; [C1, V3, V5, X4_2]; xn--b7d82wo4h..xn-----pe4u; [C1, V3, V5, A4_2]; xn--b7d82w..xn-----pe4u; [V3, V5, A4_2] # ፟ᡈ..-𖾐-
+xn--b7d82w..xn-----pe4u; \u135Fᡈ..-𖾐-; [V3, V5, X4_2]; xn--b7d82w..xn-----pe4u; [V3, V5, A4_2]; ; # ፟ᡈ..-𖾐-
+xn--b7d82wo4h..xn-----pe4u; \u135Fᡈ\u200C..-𖾐-; [C1, V3, V5, X4_2]; xn--b7d82wo4h..xn-----pe4u; [C1, V3, V5, A4_2]; ; # ፟ᡈ..-𖾐-
+xn--b7d82w.xn-----c82nz547a; \u135Fᡈ.︒-𖾐-; [V3, V5, V6]; xn--b7d82w.xn-----c82nz547a; ; ; # ፟ᡈ.︒-𖾐-
+xn--b7d82wo4h.xn-----c82nz547a; \u135Fᡈ\u200C.︒-𖾐-; [C1, V3, V5, V6]; xn--b7d82wo4h.xn-----c82nz547a; ; ; # ፟ᡈ.︒-𖾐-
+⒈\u0601⒖\u200C.\u1DF0\u07DB; ; [B1, C1, V5, V6]; xn--jfb844kmfdwb.xn--2sb914i; ; xn--jfb347mib.xn--2sb914i; [B1, V5, V6] # ⒈⒖.ᷰߛ
+1.\u060115.\u200C.\u1DF0\u07DB; ; [B1, C1, V5, V6]; 1.xn--15-1pd.xn--0ug.xn--2sb914i; ; 1.xn--15-1pd..xn--2sb914i; [B1, V5, V6, A4_2] # 1.15..ᷰߛ
+1.xn--15-1pd..xn--2sb914i; 1.\u060115..\u1DF0\u07DB; [B1, V5, V6, X4_2]; 1.xn--15-1pd..xn--2sb914i; [B1, V5, V6, A4_2]; ; # 1.15..ᷰߛ
+1.xn--15-1pd.xn--0ug.xn--2sb914i; 1.\u060115.\u200C.\u1DF0\u07DB; [B1, C1, V5, V6]; 1.xn--15-1pd.xn--0ug.xn--2sb914i; ; ; # 1.15..ᷰߛ
+xn--jfb347mib.xn--2sb914i; ⒈\u0601⒖.\u1DF0\u07DB; [B1, V5, V6]; xn--jfb347mib.xn--2sb914i; ; ; # ⒈⒖.ᷰߛ
+xn--jfb844kmfdwb.xn--2sb914i; ⒈\u0601⒖\u200C.\u1DF0\u07DB; [B1, C1, V5, V6]; xn--jfb844kmfdwb.xn--2sb914i; ; ; # ⒈⒖.ᷰߛ
+𝩜。-\u0B4DႫ; 𝩜.-\u0B4DႫ; [V3, V5, V6]; xn--792h.xn----bse632b; ; ; # 𝩜.-୍Ⴋ
+𝩜。-\u0B4Dⴋ; 𝩜.-\u0B4Dⴋ; [V3, V5]; xn--792h.xn----bse820x; ; ; # 𝩜.-୍ⴋ
+xn--792h.xn----bse820x; 𝩜.-\u0B4Dⴋ; [V3, V5]; xn--792h.xn----bse820x; ; ; # 𝩜.-୍ⴋ
+xn--792h.xn----bse632b; 𝩜.-\u0B4DႫ; [V3, V5, V6]; xn--792h.xn----bse632b; ; ; # 𝩜.-୍Ⴋ
+ßჀ.\u0620刯Ⴝ; ; [B2, B3, V6]; xn--zca442f.xn--fgb845cb66c; ; xn--ss-wgk.xn--fgb845cb66c; # ßჀ.ؠ刯Ⴝ
+ßⴠ.\u0620刯ⴝ; ; [B2, B3]; xn--zca277t.xn--fgb670rovy; ; xn--ss-j81a.xn--fgb670rovy; # ßⴠ.ؠ刯ⴝ
+SSჀ.\u0620刯Ⴝ; ssჀ.\u0620刯Ⴝ; [B2, B3, V6]; xn--ss-wgk.xn--fgb845cb66c; ; ; # ssჀ.ؠ刯Ⴝ
+ssⴠ.\u0620刯ⴝ; ; [B2, B3]; xn--ss-j81a.xn--fgb670rovy; ; ; # ssⴠ.ؠ刯ⴝ
+Ssⴠ.\u0620刯Ⴝ; ssⴠ.\u0620刯Ⴝ; [B2, B3, V6]; xn--ss-j81a.xn--fgb845cb66c; ; ; # ssⴠ.ؠ刯Ⴝ
+xn--ss-j81a.xn--fgb845cb66c; ssⴠ.\u0620刯Ⴝ; [B2, B3, V6]; xn--ss-j81a.xn--fgb845cb66c; ; ; # ssⴠ.ؠ刯Ⴝ
+xn--ss-j81a.xn--fgb670rovy; ssⴠ.\u0620刯ⴝ; [B2, B3]; xn--ss-j81a.xn--fgb670rovy; ; ; # ssⴠ.ؠ刯ⴝ
+xn--ss-wgk.xn--fgb845cb66c; ssჀ.\u0620刯Ⴝ; [B2, B3, V6]; xn--ss-wgk.xn--fgb845cb66c; ; ; # ssჀ.ؠ刯Ⴝ
+xn--zca277t.xn--fgb670rovy; ßⴠ.\u0620刯ⴝ; [B2, B3]; xn--zca277t.xn--fgb670rovy; ; ; # ßⴠ.ؠ刯ⴝ
+xn--zca442f.xn--fgb845cb66c; ßჀ.\u0620刯Ⴝ; [B2, B3, V6]; xn--zca442f.xn--fgb845cb66c; ; ; # ßჀ.ؠ刯Ⴝ
+\u1BAAႣℲ。ᠳ툻\u0673; \u1BAAႣℲ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+\u1BAAႣℲ。ᠳ툻\u0673; \u1BAAႣℲ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+\u1BAAႣℲ。ᠳ툻\u0673; \u1BAAႣℲ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+\u1BAAႣℲ。ᠳ툻\u0673; \u1BAAႣℲ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+\u1BAAⴃⅎ。ᠳ툻\u0673; \u1BAAⴃⅎ.ᠳ툻\u0673; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+\u1BAAⴃⅎ。ᠳ툻\u0673; \u1BAAⴃⅎ.ᠳ툻\u0673; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+\u1BAAႣⅎ。ᠳ툻\u0673; \u1BAAႣⅎ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+\u1BAAႣⅎ。ᠳ툻\u0673; \u1BAAႣⅎ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+xn--bnd957c2pe.xn--sib102gc69k; \u1BAAႣⅎ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+xn--yxf24x4ol.xn--sib102gc69k; \u1BAAⴃⅎ.ᠳ툻\u0673; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+xn--bnd957cone.xn--sib102gc69k; \u1BAAႣℲ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+\u1BAAⴃⅎ。ᠳ툻\u0673; \u1BAAⴃⅎ.ᠳ툻\u0673; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+\u1BAAⴃⅎ。ᠳ툻\u0673; \u1BAAⴃⅎ.ᠳ툻\u0673; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+\u1BAAႣⅎ。ᠳ툻\u0673; \u1BAAႣⅎ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+\u1BAAႣⅎ。ᠳ툻\u0673; \u1BAAႣⅎ.ᠳ툻\u0673; [B5, B6, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+\u06EC.\u08A2𐹫\u067C; ; [B1, V5]; xn--8lb.xn--1ib31ily45b; ; ; # ۬.ࢢ𐹫ټ
+xn--8lb.xn--1ib31ily45b; \u06EC.\u08A2𐹫\u067C; [B1, V5]; xn--8lb.xn--1ib31ily45b; ; ; # ۬.ࢢ𐹫ټ
+\u06B6\u06DF。₇\uA806; \u06B6\u06DF.7\uA806; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+\u06B6\u06DF。7\uA806; \u06B6\u06DF.7\uA806; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+xn--pkb6f.xn--7-x93e; \u06B6\u06DF.7\uA806; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+\u06B6\u06DF.7\uA806; ; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+Ⴣ𐹻.\u200C𝪣≮󠩉; ; [B1, B5, B6, C1, V6]; xn--7nd8101k.xn--0ugy6gn120eb103g; ; xn--7nd8101k.xn--gdh4944ob3x3e; [B1, B5, B6, V5, V6] # Ⴣ𐹻.𝪣≮
+Ⴣ𐹻.\u200C𝪣<\u0338󠩉; Ⴣ𐹻.\u200C𝪣≮󠩉; [B1, B5, B6, C1, V6]; xn--7nd8101k.xn--0ugy6gn120eb103g; ; xn--7nd8101k.xn--gdh4944ob3x3e; [B1, B5, B6, V5, V6] # Ⴣ𐹻.𝪣≮
+ⴣ𐹻.\u200C𝪣<\u0338󠩉; ⴣ𐹻.\u200C𝪣≮󠩉; [B1, B5, B6, C1, V6]; xn--rlj6323e.xn--0ugy6gn120eb103g; ; xn--rlj6323e.xn--gdh4944ob3x3e; [B1, B5, B6, V5, V6] # ⴣ𐹻.𝪣≮
+ⴣ𐹻.\u200C𝪣≮󠩉; ; [B1, B5, B6, C1, V6]; xn--rlj6323e.xn--0ugy6gn120eb103g; ; xn--rlj6323e.xn--gdh4944ob3x3e; [B1, B5, B6, V5, V6] # ⴣ𐹻.𝪣≮
+xn--rlj6323e.xn--gdh4944ob3x3e; ⴣ𐹻.𝪣≮󠩉; [B1, B5, B6, V5, V6]; xn--rlj6323e.xn--gdh4944ob3x3e; ; ; # ⴣ𐹻.𝪣≮
+xn--rlj6323e.xn--0ugy6gn120eb103g; ⴣ𐹻.\u200C𝪣≮󠩉; [B1, B5, B6, C1, V6]; xn--rlj6323e.xn--0ugy6gn120eb103g; ; ; # ⴣ𐹻.𝪣≮
+xn--7nd8101k.xn--gdh4944ob3x3e; Ⴣ𐹻.𝪣≮󠩉; [B1, B5, B6, V5, V6]; xn--7nd8101k.xn--gdh4944ob3x3e; ; ; # Ⴣ𐹻.𝪣≮
+xn--7nd8101k.xn--0ugy6gn120eb103g; Ⴣ𐹻.\u200C𝪣≮󠩉; [B1, B5, B6, C1, V6]; xn--7nd8101k.xn--0ugy6gn120eb103g; ; ; # Ⴣ𐹻.𝪣≮
+𝟵隁⯮.\u180D\u200C; 9隁⯮.\u200C; [C1]; xn--9-mfs8024b.xn--0ug; ; xn--9-mfs8024b.; [] # 9隁⯮.
+9隁⯮.\u180D\u200C; 9隁⯮.\u200C; [C1]; xn--9-mfs8024b.xn--0ug; ; xn--9-mfs8024b.; [] # 9隁⯮.
+xn--9-mfs8024b.; 9隁⯮.; ; xn--9-mfs8024b.; ; ; # 9隁⯮.
+9隁⯮.; ; ; xn--9-mfs8024b.; ; ; # 9隁⯮.
+xn--9-mfs8024b.xn--0ug; 9隁⯮.\u200C; [C1]; xn--9-mfs8024b.xn--0ug; ; ; # 9隁⯮.
+⒏𐹧。Ⴣ\u0F84彦; ⒏𐹧.Ⴣ\u0F84彦; [B1, V6]; xn--0sh2466f.xn--3ed15dt93o; ; ; # ⒏𐹧.Ⴣ྄彦
+8.𐹧。Ⴣ\u0F84彦; 8.𐹧.Ⴣ\u0F84彦; [B1, V6]; 8.xn--fo0d.xn--3ed15dt93o; ; ; # 8.𐹧.Ⴣ྄彦
+8.𐹧。ⴣ\u0F84彦; 8.𐹧.ⴣ\u0F84彦; [B1]; 8.xn--fo0d.xn--3ed972m6o8a; ; ; # 8.𐹧.ⴣ྄彦
+8.xn--fo0d.xn--3ed972m6o8a; 8.𐹧.ⴣ\u0F84彦; [B1]; 8.xn--fo0d.xn--3ed972m6o8a; ; ; # 8.𐹧.ⴣ྄彦
+8.xn--fo0d.xn--3ed15dt93o; 8.𐹧.Ⴣ\u0F84彦; [B1, V6]; 8.xn--fo0d.xn--3ed15dt93o; ; ; # 8.𐹧.Ⴣ྄彦
+⒏𐹧。ⴣ\u0F84彦; ⒏𐹧.ⴣ\u0F84彦; [B1, V6]; xn--0sh2466f.xn--3ed972m6o8a; ; ; # ⒏𐹧.ⴣ྄彦
+xn--0sh2466f.xn--3ed972m6o8a; ⒏𐹧.ⴣ\u0F84彦; [B1, V6]; xn--0sh2466f.xn--3ed972m6o8a; ; ; # ⒏𐹧.ⴣ྄彦
+xn--0sh2466f.xn--3ed15dt93o; ⒏𐹧.Ⴣ\u0F84彦; [B1, V6]; xn--0sh2466f.xn--3ed15dt93o; ; ; # ⒏𐹧.Ⴣ྄彦
+-问񬰔⒛。\u0604-񜗉橬; -问񬰔⒛.\u0604-񜗉橬; [B1, V3, V6]; xn----hdpu849bhis3e.xn----ykc7228efm46d; ; ; # -问⒛.-橬
+-问񬰔20.。\u0604-񜗉橬; -问񬰔20..\u0604-񜗉橬; [B1, V3, V6, X4_2]; xn---20-658jx1776d..xn----ykc7228efm46d; [B1, V3, V6, A4_2]; ; # -问20..-橬
+xn---20-658jx1776d..xn----ykc7228efm46d; -问񬰔20..\u0604-񜗉橬; [B1, V3, V6, X4_2]; xn---20-658jx1776d..xn----ykc7228efm46d; [B1, V3, V6, A4_2]; ; # -问20..-橬
+xn----hdpu849bhis3e.xn----ykc7228efm46d; -问񬰔⒛.\u0604-񜗉橬; [B1, V3, V6]; xn----hdpu849bhis3e.xn----ykc7228efm46d; ; ; # -问⒛.-橬
+\u1BACႬ\u200C\u0325。𝟸; \u1BACႬ\u200C\u0325.2; [C1, V5, V6]; xn--mta930emribme.2; ; xn--mta930emri.2; [V5, V6] # ᮬႬ̥.2
+\u1BACႬ\u200C\u0325。2; \u1BACႬ\u200C\u0325.2; [C1, V5, V6]; xn--mta930emribme.2; ; xn--mta930emri.2; [V5, V6] # ᮬႬ̥.2
+\u1BACⴌ\u200C\u0325。2; \u1BACⴌ\u200C\u0325.2; [C1, V5]; xn--mta176j97cl2q.2; ; xn--mta176jjjm.2; [V5] # ᮬⴌ̥.2
+xn--mta176jjjm.2; \u1BACⴌ\u0325.2; [V5]; xn--mta176jjjm.2; ; ; # ᮬⴌ̥.2
+xn--mta176j97cl2q.2; \u1BACⴌ\u200C\u0325.2; [C1, V5]; xn--mta176j97cl2q.2; ; ; # ᮬⴌ̥.2
+xn--mta930emri.2; \u1BACႬ\u0325.2; [V5, V6]; xn--mta930emri.2; ; ; # ᮬႬ̥.2
+xn--mta930emribme.2; \u1BACႬ\u200C\u0325.2; [C1, V5, V6]; xn--mta930emribme.2; ; ; # ᮬႬ̥.2
+\u1BACⴌ\u200C\u0325。𝟸; \u1BACⴌ\u200C\u0325.2; [C1, V5]; xn--mta176j97cl2q.2; ; xn--mta176jjjm.2; [V5] # ᮬⴌ̥.2
+?。\uA806\u0669󠒩; ?.\uA806\u0669󠒩; [B1, V5, V6]; ?.xn--iib9583fusy0i; ; ; # ?.꠆٩
+?.xn--iib9583fusy0i; ?.\uA806\u0669󠒩; [B1, V5, V6]; ?.xn--iib9583fusy0i; ; ; # ?.꠆٩
+󠄁\u035F⾶。₇︒눇≮; \u035F飛.7︒눇≮; [V5, V6]; xn--9ua0567e.xn--7-ngou006d1ttc; ; ; # ͟飛.7︒눇≮
+󠄁\u035F⾶。₇︒눇<\u0338; \u035F飛.7︒눇≮; [V5, V6]; xn--9ua0567e.xn--7-ngou006d1ttc; ; ; # ͟飛.7︒눇≮
+󠄁\u035F飛。7。눇≮; \u035F飛.7.눇≮; [V5]; xn--9ua0567e.7.xn--gdh6767c; ; ; # ͟飛.7.눇≮
+󠄁\u035F飛。7。눇<\u0338; \u035F飛.7.눇≮; [V5]; xn--9ua0567e.7.xn--gdh6767c; ; ; # ͟飛.7.눇≮
+xn--9ua0567e.7.xn--gdh6767c; \u035F飛.7.눇≮; [V5]; xn--9ua0567e.7.xn--gdh6767c; ; ; # ͟飛.7.눇≮
+xn--9ua0567e.xn--7-ngou006d1ttc; \u035F飛.7︒눇≮; [V5, V6]; xn--9ua0567e.xn--7-ngou006d1ttc; ; ; # ͟飛.7︒눇≮
+\u200C\uFE09𐹴\u200D.\u200C⿃; \u200C𐹴\u200D.\u200C鳥; [B1, C1, C2]; xn--0ugc6024p.xn--0ug1920c; ; xn--so0d.xn--6x6a; [B1] # 𐹴.鳥
+\u200C\uFE09𐹴\u200D.\u200C鳥; \u200C𐹴\u200D.\u200C鳥; [B1, C1, C2]; xn--0ugc6024p.xn--0ug1920c; ; xn--so0d.xn--6x6a; [B1] # 𐹴.鳥
+xn--so0d.xn--6x6a; 𐹴.鳥; [B1]; xn--so0d.xn--6x6a; ; ; # 𐹴.鳥
+xn--0ugc6024p.xn--0ug1920c; \u200C𐹴\u200D.\u200C鳥; [B1, C1, C2]; xn--0ugc6024p.xn--0ug1920c; ; ; # 𐹴.鳥
+🍮.\u200D󠗒𐦁𝨝; 🍮.\u200D󠗒𐦁𝨝; [B1, C2, V6]; xn--lj8h.xn--1ug6603gr1pfwq37h; ; xn--lj8h.xn--ln9ci476aqmr2g; [B1, V6] # 🍮.𐦁𝨝
+🍮.\u200D󠗒𐦁𝨝; ; [B1, C2, V6]; xn--lj8h.xn--1ug6603gr1pfwq37h; ; xn--lj8h.xn--ln9ci476aqmr2g; [B1, V6] # 🍮.𐦁𝨝
+xn--lj8h.xn--ln9ci476aqmr2g; 🍮.󠗒𐦁𝨝; [B1, V6]; xn--lj8h.xn--ln9ci476aqmr2g; ; ; # 🍮.𐦁𝨝
+xn--lj8h.xn--1ug6603gr1pfwq37h; 🍮.\u200D󠗒𐦁𝨝; [B1, C2, V6]; xn--lj8h.xn--1ug6603gr1pfwq37h; ; ; # 🍮.𐦁𝨝
+\u067D\u0943.𞤓\u200D; \u067D\u0943.𞤵\u200D; [B3, C2]; xn--2ib43l.xn--1ugy711p; ; xn--2ib43l.xn--te6h; [] # ٽृ.𞤵
+\u067D\u0943.𞤵\u200D; ; [B3, C2]; xn--2ib43l.xn--1ugy711p; ; xn--2ib43l.xn--te6h; [] # ٽृ.𞤵
+xn--2ib43l.xn--te6h; \u067D\u0943.𞤵; ; xn--2ib43l.xn--te6h; ; ; # ٽृ.𞤵
+\u067D\u0943.𞤵; ; ; xn--2ib43l.xn--te6h; ; ; # ٽृ.𞤵
+\u067D\u0943.𞤓; \u067D\u0943.𞤵; ; xn--2ib43l.xn--te6h; ; ; # ٽृ.𞤵
+xn--2ib43l.xn--1ugy711p; \u067D\u0943.𞤵\u200D; [B3, C2]; xn--2ib43l.xn--1ugy711p; ; ; # ٽृ.𞤵
+\u0664\u0A4D-.󥜽\u1039񦦐; \u0664\u0A4D-.󥜽\u1039񦦐; [B1, V3, V6]; xn----gqc711a.xn--9jd88234f3qm0b; ; ; # ٤੍-.္
+\u0664\u0A4D-.󥜽\u1039񦦐; ; [B1, V3, V6]; xn----gqc711a.xn--9jd88234f3qm0b; ; ; # ٤੍-.္
+xn----gqc711a.xn--9jd88234f3qm0b; \u0664\u0A4D-.󥜽\u1039񦦐; [B1, V3, V6]; xn----gqc711a.xn--9jd88234f3qm0b; ; ; # ٤੍-.္
+4\u103A-𐹸。\uAA29\u200C𐹴≮; 4\u103A-𐹸.\uAA29\u200C𐹴≮; [B1, C1, V5]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, V5] # 4်-𐹸.ꨩ𐹴≮
+4\u103A-𐹸。\uAA29\u200C𐹴<\u0338; 4\u103A-𐹸.\uAA29\u200C𐹴≮; [B1, C1, V5]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, V5] # 4်-𐹸.ꨩ𐹴≮
+4\u103A-𐹸。\uAA29\u200C𐹴≮; 4\u103A-𐹸.\uAA29\u200C𐹴≮; [B1, C1, V5]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, V5] # 4်-𐹸.ꨩ𐹴≮
+4\u103A-𐹸。\uAA29\u200C𐹴<\u0338; 4\u103A-𐹸.\uAA29\u200C𐹴≮; [B1, C1, V5]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, V5] # 4်-𐹸.ꨩ𐹴≮
+xn--4--e4j7831r.xn--gdh8754cz40c; 4\u103A-𐹸.\uAA29𐹴≮; [B1, V5]; xn--4--e4j7831r.xn--gdh8754cz40c; ; ; # 4်-𐹸.ꨩ𐹴≮
+xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; 4\u103A-𐹸.\uAA29\u200C𐹴≮; [B1, C1, V5]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; ; # 4်-𐹸.ꨩ𐹴≮
+\u200C。\uFFA0\u0F84\u0F96; \u200C.\uFFA0\u0F84\u0F96; [C1, V6]; xn--0ug.xn--3ed0by082k; ; .xn--3ed0by082k; [V6, A4_2] # .྄ྖ
+\u200C。\u1160\u0F84\u0F96; \u200C.\u1160\u0F84\u0F96; [C1, V6]; xn--0ug.xn--3ed0b20h; ; .xn--3ed0b20h; [V6, A4_2] # .྄ྖ
+.xn--3ed0b20h; .\u1160\u0F84\u0F96; [V6, X4_2]; .xn--3ed0b20h; [V6, A4_2]; ; # .྄ྖ
+xn--0ug.xn--3ed0b20h; \u200C.\u1160\u0F84\u0F96; [C1, V6]; xn--0ug.xn--3ed0b20h; ; ; # .྄ྖ
+.xn--3ed0by082k; .\uFFA0\u0F84\u0F96; [V6, X4_2]; .xn--3ed0by082k; [V6, A4_2]; ; # .྄ྖ
+xn--0ug.xn--3ed0by082k; \u200C.\uFFA0\u0F84\u0F96; [C1, V6]; xn--0ug.xn--3ed0by082k; ; ; # .྄ྖ
+≯򍘅.\u200D𐅼򲇛; ≯򍘅.\u200D𐅼򲇛; [C2, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [V6] # ≯.𐅼
+>\u0338򍘅.\u200D𐅼򲇛; ≯򍘅.\u200D𐅼򲇛; [C2, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [V6] # ≯.𐅼
+≯򍘅.\u200D𐅼򲇛; ; [C2, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [V6] # ≯.𐅼
+>\u0338򍘅.\u200D𐅼򲇛; ≯򍘅.\u200D𐅼򲇛; [C2, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [V6] # ≯.𐅼
+xn--hdh84488f.xn--xy7cw2886b; ≯򍘅.𐅼򲇛; [V6]; xn--hdh84488f.xn--xy7cw2886b; ; ; # ≯.𐅼
+xn--hdh84488f.xn--1ug8099fbjp4e; ≯򍘅.\u200D𐅼򲇛; [C2, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; ; # ≯.𐅼
+\u0641ß𐰯。𝟕𐫫; \u0641ß𐰯.7𐫫; [B1, B2]; xn--zca96ys96y.xn--7-mm5i; ; xn--ss-jvd2339x.xn--7-mm5i; # فß𐰯.7𐫫
+\u0641ß𐰯。7𐫫; \u0641ß𐰯.7𐫫; [B1, B2]; xn--zca96ys96y.xn--7-mm5i; ; xn--ss-jvd2339x.xn--7-mm5i; # فß𐰯.7𐫫
+\u0641SS𐰯。7𐫫; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+\u0641ss𐰯。7𐫫; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+xn--ss-jvd2339x.xn--7-mm5i; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+xn--zca96ys96y.xn--7-mm5i; \u0641ß𐰯.7𐫫; [B1, B2]; xn--zca96ys96y.xn--7-mm5i; ; ; # فß𐰯.7𐫫
+\u0641SS𐰯。𝟕𐫫; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+\u0641ss𐰯。𝟕𐫫; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+\u0641Ss𐰯。7𐫫; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+\u0641Ss𐰯。𝟕𐫫; \u0641ss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+ß\u07AC\u07A7\u08B1。𐭁􅮙𐹲; ß\u07AC\u07A7\u08B1.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--zca685aoa95h.xn--e09co8cr9861c; ; xn--ss-9qet02k.xn--e09co8cr9861c; # ßެާࢱ.𐭁𐹲
+SS\u07AC\u07A7\u08B1。𐭁􅮙𐹲; ss\u07AC\u07A7\u08B1.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+ss\u07AC\u07A7\u08B1。𐭁􅮙𐹲; ss\u07AC\u07A7\u08B1.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+Ss\u07AC\u07A7\u08B1。𐭁􅮙𐹲; ss\u07AC\u07A7\u08B1.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+xn--ss-9qet02k.xn--e09co8cr9861c; ss\u07AC\u07A7\u08B1.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+xn--zca685aoa95h.xn--e09co8cr9861c; ß\u07AC\u07A7\u08B1.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--zca685aoa95h.xn--e09co8cr9861c; ; ; # ßެާࢱ.𐭁𐹲
+-。󠉗⒌𞯛; -.󠉗⒌𞯛; [B1, V3, V6]; -.xn--xsh6367n1bi3e; ; ; # -.⒌
+-。󠉗5.𞯛; -.󠉗5.𞯛; [B1, V3, V6]; -.xn--5-zz21m.xn--6x6h; ; ; # -.5.
+-.xn--5-zz21m.xn--6x6h; -.󠉗5.𞯛; [B1, V3, V6]; -.xn--5-zz21m.xn--6x6h; ; ; # -.5.
+-.xn--xsh6367n1bi3e; -.󠉗⒌𞯛; [B1, V3, V6]; -.xn--xsh6367n1bi3e; ; ; # -.⒌
+𼎏ς.-≮\uFCAB; 𼎏ς.-≮\u062E\u062C; [B1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏ς.-<\u0338\uFCAB; 𼎏ς.-≮\u062E\u062C; [B1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏ς.-≮\u062E\u062C; ; [B1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏ς.-<\u0338\u062E\u062C; 𼎏ς.-≮\u062E\u062C; [B1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏Σ.-<\u0338\u062E\u062C; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏Σ.-≮\u062E\u062C; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-≮\u062E\u062C; ; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-<\u0338\u062E\u062C; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+xn--4xa92520c.xn----9mcf1400a; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+xn--3xa13520c.xn----9mcf1400a; 𼎏ς.-≮\u062E\u062C; [B1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; ; # ς.-≮خج
+𼎏Σ.-<\u0338\uFCAB; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏Σ.-≮\uFCAB; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-≮\uFCAB; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-<\u0338\uFCAB; 𼎏σ.-≮\u062E\u062C; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+ꡗ\u08B8\u0719.񔤔󠛙\u0C4D\uFC3E; ꡗ\u08B8\u0719.񔤔󠛙\u0C4D\u0643\u064A; [B5, B6, V6]; xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ; ; # ꡗࢸܙ.్كي
+ꡗ\u08B8\u0719.񔤔󠛙\u0C4D\u0643\u064A; ; [B5, B6, V6]; xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ; ; # ꡗࢸܙ.్كي
+xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ꡗ\u08B8\u0719.񔤔󠛙\u0C4D\u0643\u064A; [B5, B6, V6]; xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ; ; # ꡗࢸܙ.్كي
+𐠰\u08B7𞤌𐫭。𐋦\u17CD𝩃; 𐠰\u08B7𞤮𐫭.𐋦\u17CD𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+𐠰\u08B7𞤮𐫭。𐋦\u17CD𝩃; 𐠰\u08B7𞤮𐫭.𐋦\u17CD𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; 𐠰\u08B7𞤮𐫭.𐋦\u17CD𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+𐠰\u08B7𞤮𐫭.𐋦\u17CD𝩃; ; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+𐠰\u08B7𞤌𐫭.𐋦\u17CD𝩃; 𐠰\u08B7𞤮𐫭.𐋦\u17CD𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+₂㘷--。\u06D3\u200C𐫆𑖿; 2㘷--.\u06D3\u200C𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+₂㘷--。\u06D2\u0654\u200C𐫆𑖿; 2㘷--.\u06D3\u200C𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+2㘷--。\u06D3\u200C𐫆𑖿; 2㘷--.\u06D3\u200C𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+2㘷--。\u06D2\u0654\u200C𐫆𑖿; 2㘷--.\u06D3\u200C𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+xn--2---u58b.xn--jlb8024k14g; 2㘷--.\u06D3𐫆𑖿; [B1, V2, V3]; xn--2---u58b.xn--jlb8024k14g; ; ; # 2㘷--.ۓ𐫆𑖿
+xn--2---u58b.xn--jlb820ku99nbgj; 2㘷--.\u06D3\u200C𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; ; # 2㘷--.ۓ𐫆𑖿
+-𘊻.ᡮ\u062D-; -𘊻.ᡮ\u062D-; [B1, B5, B6, V3]; xn----bp5n.xn----bnc231l; ; ; # -𘊻.ᡮح-
+-𘊻.ᡮ\u062D-; ; [B1, B5, B6, V3]; xn----bp5n.xn----bnc231l; ; ; # -𘊻.ᡮح-
+xn----bp5n.xn----bnc231l; -𘊻.ᡮ\u062D-; [B1, B5, B6, V3]; xn----bp5n.xn----bnc231l; ; ; # -𘊻.ᡮح-
+\u200C-ß。ᢣ𐹭\u063F; \u200C-ß.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn----qfa550v.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ß.ᢣ𐹭ؿ
+\u200C-ß。ᢣ𐹭\u063F; \u200C-ß.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn----qfa550v.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ß.ᢣ𐹭ؿ
+\u200C-SS。ᢣ𐹭\u063F; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+\u200C-ss。ᢣ𐹭\u063F; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+\u200C-Ss。ᢣ𐹭\u063F; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+-ss.xn--bhb925glx3p; -ss.ᢣ𐹭\u063F; [B1, B5, B6, V3]; -ss.xn--bhb925glx3p; ; ; # -ss.ᢣ𐹭ؿ
+xn---ss-8m0a.xn--bhb925glx3p; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; ; # -ss.ᢣ𐹭ؿ
+xn----qfa550v.xn--bhb925glx3p; \u200C-ß.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn----qfa550v.xn--bhb925glx3p; ; ; # -ß.ᢣ𐹭ؿ
+\u200C-SS。ᢣ𐹭\u063F; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+\u200C-ss。ᢣ𐹭\u063F; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+\u200C-Ss。ᢣ𐹭\u063F; \u200C-ss.ᢣ𐹭\u063F; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+꧐Ӏ\u1BAA\u08F6.눵; ꧐Ӏ\u1BAA\u08F6.눵; [V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐Ӏ\u1BAA\u08F6.눵; ꧐Ӏ\u1BAA\u08F6.눵; [V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐Ӏ\u1BAA\u08F6.눵; ; [V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐Ӏ\u1BAA\u08F6.눵; ꧐Ӏ\u1BAA\u08F6.눵; [V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐ӏ\u1BAA\u08F6.눵; ꧐ӏ\u1BAA\u08F6.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+꧐ӏ\u1BAA\u08F6.눵; ; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+xn--s5a04sn4u297k.xn--2e1b; ꧐ӏ\u1BAA\u08F6.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+xn--d5a07sn4u297k.xn--2e1b; ꧐Ӏ\u1BAA\u08F6.눵; [V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐ӏ\u1BAA\u08F6.눵; ꧐ӏ\u1BAA\u08F6.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+꧐ӏ\u1BAA\u08F6.눵; ꧐ӏ\u1BAA\u08F6.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+\uA8EA。𖄿𑆾󠇗; \uA8EA.𖄿𑆾; [V5, V6]; xn--3g9a.xn--ud1dz07k; ; ; # ꣪.𑆾
+\uA8EA。𖄿𑆾󠇗; \uA8EA.𖄿𑆾; [V5, V6]; xn--3g9a.xn--ud1dz07k; ; ; # ꣪.𑆾
+xn--3g9a.xn--ud1dz07k; \uA8EA.𖄿𑆾; [V5, V6]; xn--3g9a.xn--ud1dz07k; ; ; # ꣪.𑆾
+󇓓𑚳。񐷿≯⾇; 󇓓𑚳.񐷿≯舛; [V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+󇓓𑚳。񐷿>\u0338⾇; 󇓓𑚳.񐷿≯舛; [V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+󇓓𑚳。񐷿≯舛; 󇓓𑚳.񐷿≯舛; [V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+󇓓𑚳。񐷿>\u0338舛; 󇓓𑚳.񐷿≯舛; [V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+xn--3e2d79770c.xn--hdh0088abyy1c; 󇓓𑚳.񐷿≯舛; [V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+𐫇\u0661\u200C.\u200D\u200C; 𐫇\u0661\u200C.\u200D\u200C; [B1, B3, C1, C2]; xn--9hb652kv99n.xn--0ugb; ; xn--9hb7344k.; [] # 𐫇١.
+𐫇\u0661\u200C.\u200D\u200C; ; [B1, B3, C1, C2]; xn--9hb652kv99n.xn--0ugb; ; xn--9hb7344k.; [] # 𐫇١.
+xn--9hb7344k.; 𐫇\u0661.; ; xn--9hb7344k.; ; ; # 𐫇١.
+𐫇\u0661.; ; ; xn--9hb7344k.; ; ; # 𐫇١.
+xn--9hb652kv99n.xn--0ugb; 𐫇\u0661\u200C.\u200D\u200C; [B1, B3, C1, C2]; xn--9hb652kv99n.xn--0ugb; ; ; # 𐫇١.
+񡅈砪≯ᢑ。≯𝩚򓴔\u200C; 񡅈砪≯ᢑ.≯𝩚򓴔\u200C; [C1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [V6] # 砪≯ᢑ.≯𝩚
+񡅈砪>\u0338ᢑ。>\u0338𝩚򓴔\u200C; 񡅈砪≯ᢑ.≯𝩚򓴔\u200C; [C1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [V6] # 砪≯ᢑ.≯𝩚
+񡅈砪≯ᢑ。≯𝩚򓴔\u200C; 񡅈砪≯ᢑ.≯𝩚򓴔\u200C; [C1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [V6] # 砪≯ᢑ.≯𝩚
+񡅈砪>\u0338ᢑ。>\u0338𝩚򓴔\u200C; 񡅈砪≯ᢑ.≯𝩚򓴔\u200C; [C1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [V6] # 砪≯ᢑ.≯𝩚
+xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; 񡅈砪≯ᢑ.≯𝩚򓴔; [V6]; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; ; ; # 砪≯ᢑ.≯𝩚
+xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; 񡅈砪≯ᢑ.≯𝩚򓴔\u200C; [C1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; ; # 砪≯ᢑ.≯𝩚
+Ⴥ.𑄳㊸; Ⴥ.𑄳43; [V5, V6]; xn--9nd.xn--43-274o; ; ; # Ⴥ.𑄳43
+Ⴥ.𑄳43; ; [V5, V6]; xn--9nd.xn--43-274o; ; ; # Ⴥ.𑄳43
+ⴥ.𑄳43; ; [V5]; xn--tlj.xn--43-274o; ; ; # ⴥ.𑄳43
+xn--tlj.xn--43-274o; ⴥ.𑄳43; [V5]; xn--tlj.xn--43-274o; ; ; # ⴥ.𑄳43
+xn--9nd.xn--43-274o; Ⴥ.𑄳43; [V5, V6]; xn--9nd.xn--43-274o; ; ; # Ⴥ.𑄳43
+ⴥ.𑄳㊸; ⴥ.𑄳43; [V5]; xn--tlj.xn--43-274o; ; ; # ⴥ.𑄳43
+𝟎\u0663。Ⴒᡇ\u08F2𐹠; 0\u0663.Ⴒᡇ\u08F2𐹠; [B1, B5, B6, V6]; xn--0-fqc.xn--10b180bnwgfy0z; ; ; # 0٣.Ⴒᡇࣲ𐹠
+0\u0663。Ⴒᡇ\u08F2𐹠; 0\u0663.Ⴒᡇ\u08F2𐹠; [B1, B5, B6, V6]; xn--0-fqc.xn--10b180bnwgfy0z; ; ; # 0٣.Ⴒᡇࣲ𐹠
+0\u0663。ⴒᡇ\u08F2𐹠; 0\u0663.ⴒᡇ\u08F2𐹠; [B1, B5, B6]; xn--0-fqc.xn--10b369eivp359r; ; ; # 0٣.ⴒᡇࣲ𐹠
+xn--0-fqc.xn--10b369eivp359r; 0\u0663.ⴒᡇ\u08F2𐹠; [B1, B5, B6]; xn--0-fqc.xn--10b369eivp359r; ; ; # 0٣.ⴒᡇࣲ𐹠
+xn--0-fqc.xn--10b180bnwgfy0z; 0\u0663.Ⴒᡇ\u08F2𐹠; [B1, B5, B6, V6]; xn--0-fqc.xn--10b180bnwgfy0z; ; ; # 0٣.Ⴒᡇࣲ𐹠
+𝟎\u0663。ⴒᡇ\u08F2𐹠; 0\u0663.ⴒᡇ\u08F2𐹠; [B1, B5, B6]; xn--0-fqc.xn--10b369eivp359r; ; ; # 0٣.ⴒᡇࣲ𐹠
+񗪨󠄉\uFFA0\u0FB7.񸞰\uA953; 񗪨\uFFA0\u0FB7.񸞰\uA953; [V6]; xn--kgd7493jee34a.xn--3j9au7544a; ; ; # ྷ.꥓
+񗪨󠄉\u1160\u0FB7.񸞰\uA953; 񗪨\u1160\u0FB7.񸞰\uA953; [V6]; xn--kgd36f9z57y.xn--3j9au7544a; ; ; # ྷ.꥓
+xn--kgd36f9z57y.xn--3j9au7544a; 񗪨\u1160\u0FB7.񸞰\uA953; [V6]; xn--kgd36f9z57y.xn--3j9au7544a; ; ; # ྷ.꥓
+xn--kgd7493jee34a.xn--3j9au7544a; 񗪨\uFFA0\u0FB7.񸞰\uA953; [V6]; xn--kgd7493jee34a.xn--3j9au7544a; ; ; # ྷ.꥓
+\u0618.۳\u200C\uA953; ; [C1, V5]; xn--6fb.xn--gmb469jjf1h; ; xn--6fb.xn--gmb0524f; [V5] # ؘ.۳꥓
+xn--6fb.xn--gmb0524f; \u0618.۳\uA953; [V5]; xn--6fb.xn--gmb0524f; ; ; # ؘ.۳꥓
+xn--6fb.xn--gmb469jjf1h; \u0618.۳\u200C\uA953; [C1, V5]; xn--6fb.xn--gmb469jjf1h; ; ; # ؘ.۳꥓
+ᡌ.︒ᢑ; ᡌ.︒ᢑ; [V6]; xn--c8e.xn--bbf9168i; ; ; # ᡌ.︒ᢑ
+ᡌ.。ᢑ; ᡌ..ᢑ; [X4_2]; xn--c8e..xn--bbf; [A4_2]; ; # ᡌ..ᢑ
+xn--c8e..xn--bbf; ᡌ..ᢑ; [X4_2]; xn--c8e..xn--bbf; [A4_2]; ; # ᡌ..ᢑ
+xn--c8e.xn--bbf9168i; ᡌ.︒ᢑ; [V6]; xn--c8e.xn--bbf9168i; ; ; # ᡌ.︒ᢑ
+𑋪\u1073。𞽧; 𑋪\u1073.𞽧; [B1, V5, V6]; xn--xld7443k.xn--4o7h; ; ; # 𑋪ၳ.
+𑋪\u1073。𞽧; 𑋪\u1073.𞽧; [B1, V5, V6]; xn--xld7443k.xn--4o7h; ; ; # 𑋪ၳ.
+xn--xld7443k.xn--4o7h; 𑋪\u1073.𞽧; [B1, V5, V6]; xn--xld7443k.xn--4o7h; ; ; # 𑋪ၳ.
+𞷏。ᠢ򓘆; 𞷏.ᠢ򓘆; [V6]; xn--hd7h.xn--46e66060j; ; ; # .ᠢ
+xn--hd7h.xn--46e66060j; 𞷏.ᠢ򓘆; [V6]; xn--hd7h.xn--46e66060j; ; ; # .ᠢ
+𑄳㴼.\u200C𐹡\u20EB񫺦; 𑄳㴼.\u200C𐹡\u20EB񫺦; [B1, C1, V5, V6]; xn--iym9428c.xn--0ug46a7218cllv0c; ; xn--iym9428c.xn--e1g3464g08p3b; [B1, V5, V6] # 𑄳㴼.𐹡⃫
+𑄳㴼.\u200C𐹡\u20EB񫺦; ; [B1, C1, V5, V6]; xn--iym9428c.xn--0ug46a7218cllv0c; ; xn--iym9428c.xn--e1g3464g08p3b; [B1, V5, V6] # 𑄳㴼.𐹡⃫
+xn--iym9428c.xn--e1g3464g08p3b; 𑄳㴼.𐹡\u20EB񫺦; [B1, V5, V6]; xn--iym9428c.xn--e1g3464g08p3b; ; ; # 𑄳㴼.𐹡⃫
+xn--iym9428c.xn--0ug46a7218cllv0c; 𑄳㴼.\u200C𐹡\u20EB񫺦; [B1, C1, V5, V6]; xn--iym9428c.xn--0ug46a7218cllv0c; ; ; # 𑄳㴼.𐹡⃫
+񠻟𐹳𑈯。\u031D; 񠻟𐹳𑈯.\u031D; [B1, B5, B6, V5, V6]; xn--ro0dw7dey96m.xn--eta; ; ; # 𐹳𑈯.̝
+񠻟𐹳𑈯。\u031D; 񠻟𐹳𑈯.\u031D; [B1, B5, B6, V5, V6]; xn--ro0dw7dey96m.xn--eta; ; ; # 𐹳𑈯.̝
+xn--ro0dw7dey96m.xn--eta; 񠻟𐹳𑈯.\u031D; [B1, B5, B6, V5, V6]; xn--ro0dw7dey96m.xn--eta; ; ; # 𐹳𑈯.̝
+ᢊ뾜󠱴𑚶。\u089D𐹥; ᢊ뾜󠱴𑚶.\u089D𐹥; [B1, V5, V6]; xn--39e4566fjv8bwmt6n.xn--myb6415k; ; ; # ᢊ뾜𑚶.࢝𐹥
+ᢊ뾜󠱴𑚶。\u089D𐹥; ᢊ뾜󠱴𑚶.\u089D𐹥; [B1, V5, V6]; xn--39e4566fjv8bwmt6n.xn--myb6415k; ; ; # ᢊ뾜𑚶.࢝𐹥
+xn--39e4566fjv8bwmt6n.xn--myb6415k; ᢊ뾜󠱴𑚶.\u089D𐹥; [B1, V5, V6]; xn--39e4566fjv8bwmt6n.xn--myb6415k; ; ; # ᢊ뾜𑚶.࢝𐹥
+𐹥≠。𐋲󠧠\u200C; 𐹥≠.𐋲󠧠\u200C; [B1, C1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, V6] # 𐹥≠.𐋲
+𐹥=\u0338。𐋲󠧠\u200C; 𐹥≠.𐋲󠧠\u200C; [B1, C1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, V6] # 𐹥≠.𐋲
+𐹥≠。𐋲󠧠\u200C; 𐹥≠.𐋲󠧠\u200C; [B1, C1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, V6] # 𐹥≠.𐋲
+𐹥=\u0338。𐋲󠧠\u200C; 𐹥≠.𐋲󠧠\u200C; [B1, C1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, V6] # 𐹥≠.𐋲
+xn--1ch6704g.xn--m97cw2999c; 𐹥≠.𐋲󠧠; [B1, V6]; xn--1ch6704g.xn--m97cw2999c; ; ; # 𐹥≠.𐋲
+xn--1ch6704g.xn--0ug3840g51u4g; 𐹥≠.𐋲󠧠\u200C; [B1, C1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; ; # 𐹥≠.𐋲
+\u115F񙯠\u094D.\u200D\uA953𐪤; \u115F񙯠\u094D.\u200D\uA953𐪤; [B1, C2, V6]; xn--n3b542bb085j.xn--1ug6815co9wc; ; xn--n3b542bb085j.xn--3j9al95p; [B5, B6, V5, V6] # ्.꥓
+\u115F񙯠\u094D.\u200D\uA953𐪤; ; [B1, C2, V6]; xn--n3b542bb085j.xn--1ug6815co9wc; ; xn--n3b542bb085j.xn--3j9al95p; [B5, B6, V5, V6] # ्.꥓
+xn--n3b542bb085j.xn--3j9al95p; \u115F񙯠\u094D.\uA953𐪤; [B5, B6, V5, V6]; xn--n3b542bb085j.xn--3j9al95p; ; ; # ्.꥓
+xn--n3b542bb085j.xn--1ug6815co9wc; \u115F񙯠\u094D.\u200D\uA953𐪤; [B1, C2, V6]; xn--n3b542bb085j.xn--1ug6815co9wc; ; ; # ्.꥓
+򌋔󠆎󠆗𑲕。≮; 򌋔𑲕.≮; [V6]; xn--4m3dv4354a.xn--gdh; ; ; # 𑲕.≮
+򌋔󠆎󠆗𑲕。<\u0338; 򌋔𑲕.≮; [V6]; xn--4m3dv4354a.xn--gdh; ; ; # 𑲕.≮
+xn--4m3dv4354a.xn--gdh; 򌋔𑲕.≮; [V6]; xn--4m3dv4354a.xn--gdh; ; ; # 𑲕.≮
+󠆦.\u08E3暀≠; .\u08E3暀≠; [V5, X4_2]; .xn--m0b461k3g2c; [V5, A4_2]; ; # .ࣣ暀≠
+󠆦.\u08E3暀=\u0338; .\u08E3暀≠; [V5, X4_2]; .xn--m0b461k3g2c; [V5, A4_2]; ; # .ࣣ暀≠
+.xn--m0b461k3g2c; .\u08E3暀≠; [V5, X4_2]; .xn--m0b461k3g2c; [V5, A4_2]; ; # .ࣣ暀≠
+𐡤\uABED。\uFD30򜖅\u1DF0; 𐡤\uABED.\u0634\u0645򜖅\u1DF0; [B2, B3, V6]; xn--429ak76o.xn--zgb8a701kox37t; ; ; # 𐡤꯭.شمᷰ
+𐡤\uABED。\u0634\u0645򜖅\u1DF0; 𐡤\uABED.\u0634\u0645򜖅\u1DF0; [B2, B3, V6]; xn--429ak76o.xn--zgb8a701kox37t; ; ; # 𐡤꯭.شمᷰ
+xn--429ak76o.xn--zgb8a701kox37t; 𐡤\uABED.\u0634\u0645򜖅\u1DF0; [B2, B3, V6]; xn--429ak76o.xn--zgb8a701kox37t; ; ; # 𐡤꯭.شمᷰ
+𝉃\u200D⒈。Ⴌ𞱓; 𝉃\u200D⒈.Ⴌ𞱓; [B1, B5, B6, C2, V5, V6]; xn--1ug68oq348b.xn--knd8464v; ; xn--tshz828m.xn--knd8464v; [B1, B5, B6, V5, V6] # 𝉃⒈.Ⴌ
+𝉃\u200D1.。Ⴌ𞱓; 𝉃\u200D1..Ⴌ𞱓; [B1, B5, B6, C2, V5, V6, X4_2]; xn--1-tgn9827q..xn--knd8464v; [B1, B5, B6, C2, V5, V6, A4_2]; xn--1-px8q..xn--knd8464v; [B1, B5, B6, V5, V6, A4_2] # 𝉃1..Ⴌ
+𝉃\u200D1.。ⴌ𞱓; 𝉃\u200D1..ⴌ𞱓; [B1, B5, B6, C2, V5, V6, X4_2]; xn--1-tgn9827q..xn--3kj4524l; [B1, B5, B6, C2, V5, V6, A4_2]; xn--1-px8q..xn--3kj4524l; [B1, B5, B6, V5, V6, A4_2] # 𝉃1..ⴌ
+xn--1-px8q..xn--3kj4524l; 𝉃1..ⴌ𞱓; [B1, B5, B6, V5, V6, X4_2]; xn--1-px8q..xn--3kj4524l; [B1, B5, B6, V5, V6, A4_2]; ; # 𝉃1..ⴌ
+xn--1-tgn9827q..xn--3kj4524l; 𝉃\u200D1..ⴌ𞱓; [B1, B5, B6, C2, V5, V6, X4_2]; xn--1-tgn9827q..xn--3kj4524l; [B1, B5, B6, C2, V5, V6, A4_2]; ; # 𝉃1..ⴌ
+xn--1-px8q..xn--knd8464v; 𝉃1..Ⴌ𞱓; [B1, B5, B6, V5, V6, X4_2]; xn--1-px8q..xn--knd8464v; [B1, B5, B6, V5, V6, A4_2]; ; # 𝉃1..Ⴌ
+xn--1-tgn9827q..xn--knd8464v; 𝉃\u200D1..Ⴌ𞱓; [B1, B5, B6, C2, V5, V6, X4_2]; xn--1-tgn9827q..xn--knd8464v; [B1, B5, B6, C2, V5, V6, A4_2]; ; # 𝉃1..Ⴌ
+𝉃\u200D⒈。ⴌ𞱓; 𝉃\u200D⒈.ⴌ𞱓; [B1, B5, B6, C2, V5, V6]; xn--1ug68oq348b.xn--3kj4524l; ; xn--tshz828m.xn--3kj4524l; [B1, B5, B6, V5, V6] # 𝉃⒈.ⴌ
+xn--tshz828m.xn--3kj4524l; 𝉃⒈.ⴌ𞱓; [B1, B5, B6, V5, V6]; xn--tshz828m.xn--3kj4524l; ; ; # 𝉃⒈.ⴌ
+xn--1ug68oq348b.xn--3kj4524l; 𝉃\u200D⒈.ⴌ𞱓; [B1, B5, B6, C2, V5, V6]; xn--1ug68oq348b.xn--3kj4524l; ; ; # 𝉃⒈.ⴌ
+xn--tshz828m.xn--knd8464v; 𝉃⒈.Ⴌ𞱓; [B1, B5, B6, V5, V6]; xn--tshz828m.xn--knd8464v; ; ; # 𝉃⒈.Ⴌ
+xn--1ug68oq348b.xn--knd8464v; 𝉃\u200D⒈.Ⴌ𞱓; [B1, B5, B6, C2, V5, V6]; xn--1ug68oq348b.xn--knd8464v; ; ; # 𝉃⒈.Ⴌ
+󠣙\u0A4D𱫘𞤸.ς񵯞􈰔; ; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; ; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; # ੍𱫘𞤸.ς
+󠣙\u0A4D𱫘𞤖.Σ񵯞􈰔; 󠣙\u0A4D𱫘𞤸.σ񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𱫘𞤸.σ
+󠣙\u0A4D𱫘𞤸.σ񵯞􈰔; ; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𱫘𞤸.σ
+󠣙\u0A4D𱫘𞤖.σ񵯞􈰔; 󠣙\u0A4D𱫘𞤸.σ񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𱫘𞤸.σ
+xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; 󠣙\u0A4D𱫘𞤸.σ񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𱫘𞤸.σ
+󠣙\u0A4D𱫘𞤖.ς񵯞􈰔; 󠣙\u0A4D𱫘𞤸.ς񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; ; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; # ੍𱫘𞤸.ς
+xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; 󠣙\u0A4D𱫘𞤸.ς񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; ; ; # ੍𱫘𞤸.ς
+󠣙\u0A4D𱫘𞤸.Σ񵯞􈰔; 󠣙\u0A4D𱫘𞤸.σ񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𱫘𞤸.σ
+\u07D3。\u200C𐫀򞭱; \u07D3.\u200C𐫀򞭱; [B1, C1, V6]; xn--usb.xn--0ug9553gm3v5d; ; xn--usb.xn--pw9ci1099a; [B2, B3, V6] # ߓ.𐫀
+xn--usb.xn--pw9ci1099a; \u07D3.𐫀򞭱; [B2, B3, V6]; xn--usb.xn--pw9ci1099a; ; ; # ߓ.𐫀
+xn--usb.xn--0ug9553gm3v5d; \u07D3.\u200C𐫀򞭱; [B1, C1, V6]; xn--usb.xn--0ug9553gm3v5d; ; ; # ߓ.𐫀
+\u1C2E𞀝.\u05A6ꡟ𞤕󠆖; \u1C2E𞀝.\u05A6ꡟ𞤷; [B1, V5]; xn--q1f4493q.xn--xcb8244fifvj; ; ; # ᰮ𞀝.֦ꡟ𞤷
+\u1C2E𞀝.\u05A6ꡟ𞤷󠆖; \u1C2E𞀝.\u05A6ꡟ𞤷; [B1, V5]; xn--q1f4493q.xn--xcb8244fifvj; ; ; # ᰮ𞀝.֦ꡟ𞤷
+xn--q1f4493q.xn--xcb8244fifvj; \u1C2E𞀝.\u05A6ꡟ𞤷; [B1, V5]; xn--q1f4493q.xn--xcb8244fifvj; ; ; # ᰮ𞀝.֦ꡟ𞤷
+䂹󾖅𐋦.\u200D; 䂹󾖅𐋦.\u200D; [C2, V6]; xn--0on3543c5981i.xn--1ug; ; xn--0on3543c5981i.; [V6] # 䂹𐋦.
+䂹󾖅𐋦.\u200D; ; [C2, V6]; xn--0on3543c5981i.xn--1ug; ; xn--0on3543c5981i.; [V6] # 䂹𐋦.
+xn--0on3543c5981i.; 䂹󾖅𐋦.; [V6]; xn--0on3543c5981i.; ; ; # 䂹𐋦.
+xn--0on3543c5981i.xn--1ug; 䂹󾖅𐋦.\u200D; [C2, V6]; xn--0on3543c5981i.xn--1ug; ; ; # 䂹𐋦.
+\uA9C0\u200C𐹲\u200C。\u0767🄉; \uA9C0\u200C𐹲\u200C.\u0767🄉; [B5, B6, C1, V5, V6]; xn--0uga8686hdgvd.xn--rpb6081w; ; xn--7m9an32q.xn--rpb6081w; [B5, B6, V5, V6] # ꧀𐹲.ݧ🄉
+\uA9C0\u200C𐹲\u200C。\u07678,; \uA9C0\u200C𐹲\u200C.\u07678,; [B3, B5, B6, C1, V5, V6]; xn--0uga8686hdgvd.xn--8,-qle; ; xn--7m9an32q.xn--8,-qle; [B3, B5, B6, V5, V6] # ꧀𐹲.ݧ8,
+xn--7m9an32q.xn--8,-qle; \uA9C0𐹲.\u07678,; [B3, B5, B6, V5, V6]; xn--7m9an32q.xn--8,-qle; ; ; # ꧀𐹲.ݧ8,
+xn--0uga8686hdgvd.xn--8,-qle; \uA9C0\u200C𐹲\u200C.\u07678,; [B3, B5, B6, C1, V5, V6]; xn--0uga8686hdgvd.xn--8,-qle; ; ; # ꧀𐹲.ݧ8,
+xn--7m9an32q.xn--rpb6081w; \uA9C0𐹲.\u0767🄉; [B5, B6, V5, V6]; xn--7m9an32q.xn--rpb6081w; ; ; # ꧀𐹲.ݧ🄉
+xn--0uga8686hdgvd.xn--rpb6081w; \uA9C0\u200C𐹲\u200C.\u0767🄉; [B5, B6, C1, V5, V6]; xn--0uga8686hdgvd.xn--rpb6081w; ; ; # ꧀𐹲.ݧ🄉
+︒。Ⴃ≯; ︒.Ⴃ≯; [V6]; xn--y86c.xn--bnd622g; ; ; # ︒.Ⴃ≯
+︒。Ⴃ>\u0338; ︒.Ⴃ≯; [V6]; xn--y86c.xn--bnd622g; ; ; # ︒.Ⴃ≯
+。。Ⴃ≯; ..Ⴃ≯; [V6, X4_2]; ..xn--bnd622g; [V6, A4_2]; ; # ..Ⴃ≯
+。。Ⴃ>\u0338; ..Ⴃ≯; [V6, X4_2]; ..xn--bnd622g; [V6, A4_2]; ; # ..Ⴃ≯
+。。ⴃ>\u0338; ..ⴃ≯; [X4_2]; ..xn--hdh782b; [A4_2]; ; # ..ⴃ≯
+。。ⴃ≯; ..ⴃ≯; [X4_2]; ..xn--hdh782b; [A4_2]; ; # ..ⴃ≯
+..xn--hdh782b; ..ⴃ≯; [X4_2]; ..xn--hdh782b; [A4_2]; ; # ..ⴃ≯
+..xn--bnd622g; ..Ⴃ≯; [V6, X4_2]; ..xn--bnd622g; [V6, A4_2]; ; # ..Ⴃ≯
+︒。ⴃ>\u0338; ︒.ⴃ≯; [V6]; xn--y86c.xn--hdh782b; ; ; # ︒.ⴃ≯
+︒。ⴃ≯; ︒.ⴃ≯; [V6]; xn--y86c.xn--hdh782b; ; ; # ︒.ⴃ≯
+xn--y86c.xn--hdh782b; ︒.ⴃ≯; [V6]; xn--y86c.xn--hdh782b; ; ; # ︒.ⴃ≯
+xn--y86c.xn--bnd622g; ︒.Ⴃ≯; [V6]; xn--y86c.xn--bnd622g; ; ; # ︒.Ⴃ≯
+𐹮。󠢼\u200D; 𐹮.󠢼\u200D; [B1, C2, V6]; xn--mo0d.xn--1ug18431l; ; xn--mo0d.xn--wy46e; [B1, V6] # 𐹮.
+𐹮。󠢼\u200D; 𐹮.󠢼\u200D; [B1, C2, V6]; xn--mo0d.xn--1ug18431l; ; xn--mo0d.xn--wy46e; [B1, V6] # 𐹮.
+xn--mo0d.xn--wy46e; 𐹮.󠢼; [B1, V6]; xn--mo0d.xn--wy46e; ; ; # 𐹮.
+xn--mo0d.xn--1ug18431l; 𐹮.󠢼\u200D; [B1, C2, V6]; xn--mo0d.xn--1ug18431l; ; ; # 𐹮.
+Ⴞ𐹨。︒\u077D\u200DႯ; Ⴞ𐹨.︒\u077D\u200DႯ; [B1, B5, B6, C2, V6]; xn--2nd0990k.xn--eqb228bgzmvp0t; ; xn--2nd0990k.xn--eqb228b583r; [B1, B5, B6, V6] # Ⴞ𐹨.︒ݽႯ
+Ⴞ𐹨。。\u077D\u200DႯ; Ⴞ𐹨..\u077D\u200DႯ; [B2, B3, B5, B6, C2, V6, X4_2]; xn--2nd0990k..xn--eqb228bgzm; [B2, B3, B5, B6, C2, V6, A4_2]; xn--2nd0990k..xn--eqb228b; [B2, B3, B5, B6, V6, A4_2] # Ⴞ𐹨..ݽႯ
+ⴞ𐹨。。\u077D\u200Dⴏ; ⴞ𐹨..\u077D\u200Dⴏ; [B2, B3, B5, B6, C2, X4_2]; xn--mlju223e..xn--eqb096jpgj; [B2, B3, B5, B6, C2, A4_2]; xn--mlju223e..xn--eqb053q; [B2, B3, B5, B6, A4_2] # ⴞ𐹨..ݽⴏ
+Ⴞ𐹨。。\u077D\u200Dⴏ; Ⴞ𐹨..\u077D\u200Dⴏ; [B2, B3, B5, B6, C2, V6, X4_2]; xn--2nd0990k..xn--eqb096jpgj; [B2, B3, B5, B6, C2, V6, A4_2]; xn--2nd0990k..xn--eqb053q; [B2, B3, B5, B6, V6, A4_2] # Ⴞ𐹨..ݽⴏ
+xn--2nd0990k..xn--eqb053q; Ⴞ𐹨..\u077Dⴏ; [B2, B3, B5, B6, V6, X4_2]; xn--2nd0990k..xn--eqb053q; [B2, B3, B5, B6, V6, A4_2]; ; # Ⴞ𐹨..ݽⴏ
+xn--2nd0990k..xn--eqb096jpgj; Ⴞ𐹨..\u077D\u200Dⴏ; [B2, B3, B5, B6, C2, V6, X4_2]; xn--2nd0990k..xn--eqb096jpgj; [B2, B3, B5, B6, C2, V6, A4_2]; ; # Ⴞ𐹨..ݽⴏ
+xn--mlju223e..xn--eqb053q; ⴞ𐹨..\u077Dⴏ; [B2, B3, B5, B6, X4_2]; xn--mlju223e..xn--eqb053q; [B2, B3, B5, B6, A4_2]; ; # ⴞ𐹨..ݽⴏ
+xn--mlju223e..xn--eqb096jpgj; ⴞ𐹨..\u077D\u200Dⴏ; [B2, B3, B5, B6, C2, X4_2]; xn--mlju223e..xn--eqb096jpgj; [B2, B3, B5, B6, C2, A4_2]; ; # ⴞ𐹨..ݽⴏ
+xn--2nd0990k..xn--eqb228b; Ⴞ𐹨..\u077DႯ; [B2, B3, B5, B6, V6, X4_2]; xn--2nd0990k..xn--eqb228b; [B2, B3, B5, B6, V6, A4_2]; ; # Ⴞ𐹨..ݽႯ
+xn--2nd0990k..xn--eqb228bgzm; Ⴞ𐹨..\u077D\u200DႯ; [B2, B3, B5, B6, C2, V6, X4_2]; xn--2nd0990k..xn--eqb228bgzm; [B2, B3, B5, B6, C2, V6, A4_2]; ; # Ⴞ𐹨..ݽႯ
+ⴞ𐹨。︒\u077D\u200Dⴏ; ⴞ𐹨.︒\u077D\u200Dⴏ; [B1, B5, B6, C2, V6]; xn--mlju223e.xn--eqb096jpgj9y7r; ; xn--mlju223e.xn--eqb053qjk7l; [B1, B5, B6, V6] # ⴞ𐹨.︒ݽⴏ
+Ⴞ𐹨。︒\u077D\u200Dⴏ; Ⴞ𐹨.︒\u077D\u200Dⴏ; [B1, B5, B6, C2, V6]; xn--2nd0990k.xn--eqb096jpgj9y7r; ; xn--2nd0990k.xn--eqb053qjk7l; [B1, B5, B6, V6] # Ⴞ𐹨.︒ݽⴏ
+xn--2nd0990k.xn--eqb053qjk7l; Ⴞ𐹨.︒\u077Dⴏ; [B1, B5, B6, V6]; xn--2nd0990k.xn--eqb053qjk7l; ; ; # Ⴞ𐹨.︒ݽⴏ
+xn--2nd0990k.xn--eqb096jpgj9y7r; Ⴞ𐹨.︒\u077D\u200Dⴏ; [B1, B5, B6, C2, V6]; xn--2nd0990k.xn--eqb096jpgj9y7r; ; ; # Ⴞ𐹨.︒ݽⴏ
+xn--mlju223e.xn--eqb053qjk7l; ⴞ𐹨.︒\u077Dⴏ; [B1, B5, B6, V6]; xn--mlju223e.xn--eqb053qjk7l; ; ; # ⴞ𐹨.︒ݽⴏ
+xn--mlju223e.xn--eqb096jpgj9y7r; ⴞ𐹨.︒\u077D\u200Dⴏ; [B1, B5, B6, C2, V6]; xn--mlju223e.xn--eqb096jpgj9y7r; ; ; # ⴞ𐹨.︒ݽⴏ
+xn--2nd0990k.xn--eqb228b583r; Ⴞ𐹨.︒\u077DႯ; [B1, B5, B6, V6]; xn--2nd0990k.xn--eqb228b583r; ; ; # Ⴞ𐹨.︒ݽႯ
+xn--2nd0990k.xn--eqb228bgzmvp0t; Ⴞ𐹨.︒\u077D\u200DႯ; [B1, B5, B6, C2, V6]; xn--2nd0990k.xn--eqb228bgzmvp0t; ; ; # Ⴞ𐹨.︒ݽႯ
+\u200CႦ𝟹。-\u20D2-\u07D1; \u200CႦ3.-\u20D2-\u07D1; [B1, C1, V3, V6]; xn--3-i0g939i.xn-----vue617w; ; xn--3-i0g.xn-----vue617w; [B1, V3, V6] # Ⴆ3.-⃒-ߑ
+\u200CႦ3。-\u20D2-\u07D1; \u200CႦ3.-\u20D2-\u07D1; [B1, C1, V3, V6]; xn--3-i0g939i.xn-----vue617w; ; xn--3-i0g.xn-----vue617w; [B1, V3, V6] # Ⴆ3.-⃒-ߑ
+\u200Cⴆ3。-\u20D2-\u07D1; \u200Cⴆ3.-\u20D2-\u07D1; [B1, C1, V3]; xn--3-rgnv99c.xn-----vue617w; ; xn--3-lvs.xn-----vue617w; [B1, V3] # ⴆ3.-⃒-ߑ
+xn--3-lvs.xn-----vue617w; ⴆ3.-\u20D2-\u07D1; [B1, V3]; xn--3-lvs.xn-----vue617w; ; ; # ⴆ3.-⃒-ߑ
+xn--3-rgnv99c.xn-----vue617w; \u200Cⴆ3.-\u20D2-\u07D1; [B1, C1, V3]; xn--3-rgnv99c.xn-----vue617w; ; ; # ⴆ3.-⃒-ߑ
+xn--3-i0g.xn-----vue617w; Ⴆ3.-\u20D2-\u07D1; [B1, V3, V6]; xn--3-i0g.xn-----vue617w; ; ; # Ⴆ3.-⃒-ߑ
+xn--3-i0g939i.xn-----vue617w; \u200CႦ3.-\u20D2-\u07D1; [B1, C1, V3, V6]; xn--3-i0g939i.xn-----vue617w; ; ; # Ⴆ3.-⃒-ߑ
+\u200Cⴆ𝟹。-\u20D2-\u07D1; \u200Cⴆ3.-\u20D2-\u07D1; [B1, C1, V3]; xn--3-rgnv99c.xn-----vue617w; ; xn--3-lvs.xn-----vue617w; [B1, V3] # ⴆ3.-⃒-ߑ
+箃Ⴡ-󠁝。≠-🤖; 箃Ⴡ-󠁝.≠-🤖; [V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃Ⴡ-󠁝。=\u0338-🤖; 箃Ⴡ-󠁝.≠-🤖; [V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃Ⴡ-󠁝。≠-🤖; 箃Ⴡ-󠁝.≠-🤖; [V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃Ⴡ-󠁝。=\u0338-🤖; 箃Ⴡ-󠁝.≠-🤖; [V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃ⴡ-󠁝。=\u0338-🤖; 箃ⴡ-󠁝.≠-🤖; [V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+箃ⴡ-󠁝。≠-🤖; 箃ⴡ-󠁝.≠-🤖; [V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+xn----4wsr321ay823p.xn----tfot873s; 箃ⴡ-󠁝.≠-🤖; [V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+xn----11g3013fy8x5m.xn----tfot873s; 箃Ⴡ-󠁝.≠-🤖; [V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃ⴡ-󠁝。=\u0338-🤖; 箃ⴡ-󠁝.≠-🤖; [V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+箃ⴡ-󠁝。≠-🤖; 箃ⴡ-󠁝.≠-🤖; [V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+\u07E5.\u06B5; ; ; xn--dtb.xn--okb; ; ; # ߥ.ڵ
+xn--dtb.xn--okb; \u07E5.\u06B5; ; xn--dtb.xn--okb; ; ; # ߥ.ڵ
+\u200C\u200D.𞤿; ; [B1, C1, C2]; xn--0ugc.xn--3e6h; ; .xn--3e6h; [A4_2] # .𞤿
+\u200C\u200D.𞤝; \u200C\u200D.𞤿; [B1, C1, C2]; xn--0ugc.xn--3e6h; ; .xn--3e6h; [A4_2] # .𞤿
+.xn--3e6h; .𞤿; [X4_2]; .xn--3e6h; [A4_2]; ; # .𞤿
+xn--0ugc.xn--3e6h; \u200C\u200D.𞤿; [B1, C1, C2]; xn--0ugc.xn--3e6h; ; ; # .𞤿
+xn--3e6h; 𞤿; ; xn--3e6h; ; ; # 𞤿
+𞤿; ; ; xn--3e6h; ; ; # 𞤿
+𞤝; 𞤿; ; xn--3e6h; ; ; # 𞤿
+🜑𐹧\u0639.ς𑍍蜹; ; [B1]; xn--4gb3736kk4zf.xn--3xa4248dy27d; ; xn--4gb3736kk4zf.xn--4xa2248dy27d; # 🜑𐹧ع.ς𑍍蜹
+🜑𐹧\u0639.Σ𑍍蜹; 🜑𐹧\u0639.σ𑍍蜹; [B1]; xn--4gb3736kk4zf.xn--4xa2248dy27d; ; ; # 🜑𐹧ع.σ𑍍蜹
+🜑𐹧\u0639.σ𑍍蜹; ; [B1]; xn--4gb3736kk4zf.xn--4xa2248dy27d; ; ; # 🜑𐹧ع.σ𑍍蜹
+xn--4gb3736kk4zf.xn--4xa2248dy27d; 🜑𐹧\u0639.σ𑍍蜹; [B1]; xn--4gb3736kk4zf.xn--4xa2248dy27d; ; ; # 🜑𐹧ع.σ𑍍蜹
+xn--4gb3736kk4zf.xn--3xa4248dy27d; 🜑𐹧\u0639.ς𑍍蜹; [B1]; xn--4gb3736kk4zf.xn--3xa4248dy27d; ; ; # 🜑𐹧ع.ς𑍍蜹
+򫠐ス􆟤\u0669.󚃟; 򫠐ス􆟤\u0669.󚃟; [B5, B6, V6]; xn--iib777sp230oo708a.xn--7824e; ; ; # ス٩.
+򫠐ス􆟤\u0669.󚃟; ; [B5, B6, V6]; xn--iib777sp230oo708a.xn--7824e; ; ; # ス٩.
+xn--iib777sp230oo708a.xn--7824e; 򫠐ス􆟤\u0669.󚃟; [B5, B6, V6]; xn--iib777sp230oo708a.xn--7824e; ; ; # ス٩.
+𝪣򕡝.\u059A?\u06C2; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+𝪣򕡝.\u059A?\u06C1\u0654; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+𝪣򕡝.\u059A?\u06C2; ; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+𝪣򕡝.\u059A?\u06C1\u0654; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+xn--8c3hu7971a.xn--?-wec30g; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+xn--8c3hu7971a.\u059A?\u06C2; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+xn--8c3hu7971a.\u059A?\u06C1\u0654; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+XN--8C3HU7971A.\u059A?\u06C1\u0654; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+XN--8C3HU7971A.\u059A?\u06C2; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+Xn--8c3hu7971a.\u059A?\u06C2; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+Xn--8c3hu7971a.\u059A?\u06C1\u0654; 𝪣򕡝.\u059A?\u06C2; [B1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+\u0660򪓵\u200C。\u0757; \u0660򪓵\u200C.\u0757; [B1, C1, V6]; xn--8hb852ke991q.xn--bpb; ; xn--8hb82030l.xn--bpb; [B1, V6] # ٠.ݗ
+xn--8hb82030l.xn--bpb; \u0660򪓵.\u0757; [B1, V6]; xn--8hb82030l.xn--bpb; ; ; # ٠.ݗ
+xn--8hb852ke991q.xn--bpb; \u0660򪓵\u200C.\u0757; [B1, C1, V6]; xn--8hb852ke991q.xn--bpb; ; ; # ٠.ݗ
+\u103A\u200D\u200C。-\u200C; \u103A\u200D\u200C.-\u200C; [C1, V3, V5]; xn--bkd412fca.xn----sgn; ; xn--bkd.-; [V3, V5] # ်.-
+xn--bkd.-; \u103A.-; [V3, V5]; xn--bkd.-; ; ; # ်.-
+xn--bkd412fca.xn----sgn; \u103A\u200D\u200C.-\u200C; [C1, V3, V5]; xn--bkd412fca.xn----sgn; ; ; # ်.-
+︒。\u1B44ᡉ; ︒.\u1B44ᡉ; [V5, V6]; xn--y86c.xn--87e93m; ; ; # ︒.᭄ᡉ
+。。\u1B44ᡉ; ..\u1B44ᡉ; [V5, X4_2]; ..xn--87e93m; [V5, A4_2]; ; # ..᭄ᡉ
+..xn--87e93m; ..\u1B44ᡉ; [V5, X4_2]; ..xn--87e93m; [V5, A4_2]; ; # ..᭄ᡉ
+xn--y86c.xn--87e93m; ︒.\u1B44ᡉ; [V5, V6]; xn--y86c.xn--87e93m; ; ; # ︒.᭄ᡉ
+\u0758ß。ጫᢊ\u0768𝟐; \u0758ß.ጫᢊ\u07682; [B2, B3, B5]; xn--zca724a.xn--2-b5c641gfmf; ; xn--ss-gke.xn--2-b5c641gfmf; # ݘß.ጫᢊݨ2
+\u0758ß。ጫᢊ\u07682; \u0758ß.ጫᢊ\u07682; [B2, B3, B5]; xn--zca724a.xn--2-b5c641gfmf; ; xn--ss-gke.xn--2-b5c641gfmf; # ݘß.ጫᢊݨ2
+\u0758SS。ጫᢊ\u07682; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+\u0758ss。ጫᢊ\u07682; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+xn--ss-gke.xn--2-b5c641gfmf; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+xn--zca724a.xn--2-b5c641gfmf; \u0758ß.ጫᢊ\u07682; [B2, B3, B5]; xn--zca724a.xn--2-b5c641gfmf; ; ; # ݘß.ጫᢊݨ2
+\u0758SS。ጫᢊ\u0768𝟐; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+\u0758ss。ጫᢊ\u0768𝟐; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+\u0758Ss。ጫᢊ\u07682; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+\u0758Ss。ጫᢊ\u0768𝟐; \u0758ss.ጫᢊ\u07682; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+\u07C3𞶇ᚲ.\u0902\u0353𝟚\u09CD; \u07C3𞶇ᚲ.\u0902\u03532\u09CD; [B1, B2, B3, V5, V6]; xn--esb067enh07a.xn--2-lgb874bjxa; ; ; # ߃ᚲ.ं͓2্
+\u07C3𞶇ᚲ.\u0902\u03532\u09CD; ; [B1, B2, B3, V5, V6]; xn--esb067enh07a.xn--2-lgb874bjxa; ; ; # ߃ᚲ.ं͓2্
+xn--esb067enh07a.xn--2-lgb874bjxa; \u07C3𞶇ᚲ.\u0902\u03532\u09CD; [B1, B2, B3, V5, V6]; xn--esb067enh07a.xn--2-lgb874bjxa; ; ; # ߃ᚲ.ं͓2্
+-\u1BAB︒\u200D.񒶈񥹓; ; [C2, V3, V6]; xn----qmlv7tw180a.xn--x50zy803a; ; xn----qml1407i.xn--x50zy803a; [V3, V6] # -᮫︒.
+-\u1BAB。\u200D.񒶈񥹓; -\u1BAB.\u200D.񒶈񥹓; [C2, V3, V6]; xn----qml.xn--1ug.xn--x50zy803a; ; xn----qml..xn--x50zy803a; [V3, V6, A4_2] # -᮫..
+xn----qml..xn--x50zy803a; -\u1BAB..񒶈񥹓; [V3, V6, X4_2]; xn----qml..xn--x50zy803a; [V3, V6, A4_2]; ; # -᮫..
+xn----qml.xn--1ug.xn--x50zy803a; -\u1BAB.\u200D.񒶈񥹓; [C2, V3, V6]; xn----qml.xn--1ug.xn--x50zy803a; ; ; # -᮫..
+xn----qml1407i.xn--x50zy803a; -\u1BAB︒.񒶈񥹓; [V3, V6]; xn----qml1407i.xn--x50zy803a; ; ; # -᮫︒.
+xn----qmlv7tw180a.xn--x50zy803a; -\u1BAB︒\u200D.񒶈񥹓; [C2, V3, V6]; xn----qmlv7tw180a.xn--x50zy803a; ; ; # -᮫︒.
+󠦮.≯𞀆; ; [V6]; xn--t546e.xn--hdh5166o; ; ; # .≯𞀆
+󠦮.>\u0338𞀆; 󠦮.≯𞀆; [V6]; xn--t546e.xn--hdh5166o; ; ; # .≯𞀆
+xn--t546e.xn--hdh5166o; 󠦮.≯𞀆; [V6]; xn--t546e.xn--hdh5166o; ; ; # .≯𞀆
+-𑄳󠊗𐹩。𞮱; -𑄳󠊗𐹩.𞮱; [B1, V3, V6]; xn----p26i72em2894c.xn--zw6h; ; ; # -𑄳𐹩.
+xn----p26i72em2894c.xn--zw6h; -𑄳󠊗𐹩.𞮱; [B1, V3, V6]; xn----p26i72em2894c.xn--zw6h; ; ; # -𑄳𐹩.
+\u06B9.ᡳ\u115F; \u06B9.ᡳ\u115F; [V6]; xn--skb.xn--osd737a; ; ; # ڹ.ᡳ
+\u06B9.ᡳ\u115F; ; [V6]; xn--skb.xn--osd737a; ; ; # ڹ.ᡳ
+xn--skb.xn--osd737a; \u06B9.ᡳ\u115F; [V6]; xn--skb.xn--osd737a; ; ; # ڹ.ᡳ
+㨛𘱎.︒𝟕\u0D01; 㨛𘱎.︒7\u0D01; [V6]; xn--mbm8237g.xn--7-7hf1526p; ; ; # 㨛𘱎.︒7ഁ
+㨛𘱎.。7\u0D01; 㨛𘱎..7\u0D01; [X4_2]; xn--mbm8237g..xn--7-7hf; [A4_2]; ; # 㨛𘱎..7ഁ
+xn--mbm8237g..xn--7-7hf; 㨛𘱎..7\u0D01; [X4_2]; xn--mbm8237g..xn--7-7hf; [A4_2]; ; # 㨛𘱎..7ഁ
+xn--mbm8237g.xn--7-7hf1526p; 㨛𘱎.︒7\u0D01; [V6]; xn--mbm8237g.xn--7-7hf1526p; ; ; # 㨛𘱎.︒7ഁ
+\u06DD𻱧-。𞷁\u2064𞤣≮; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤣<\u0338; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤣≮; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤣<\u0338; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤁<\u0338; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤁≮; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+xn----dxc06304e.xn--gdh5020pk5c; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤁<\u0338; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+\u06DD𻱧-。𞷁\u2064𞤁≮; \u06DD𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+ß\u200C\uAAF6ᢥ.⊶ჁႶ; ß\u200C\uAAF6ᢥ.⊶ჁႶ; [C1, V6]; xn--zca682johfi89m.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [V6] # ß꫶ᢥ.⊶ჁႶ
+ß\u200C\uAAF6ᢥ.⊶ჁႶ; ; [C1, V6]; xn--zca682johfi89m.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [V6] # ß꫶ᢥ.⊶ჁႶ
+ß\u200C\uAAF6ᢥ.⊶ⴡⴖ; ; [C1]; xn--zca682johfi89m.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ß꫶ᢥ.⊶ⴡⴖ
+SS\u200C\uAAF6ᢥ.⊶ჁႶ; ss\u200C\uAAF6ᢥ.⊶ჁႶ; [C1, V6]; xn--ss-4ep585bkm5p.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [V6] # ss꫶ᢥ.⊶ჁႶ
+ss\u200C\uAAF6ᢥ.⊶ⴡⴖ; ; [C1]; xn--ss-4ep585bkm5p.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ss꫶ᢥ.⊶ⴡⴖ
+Ss\u200C\uAAF6ᢥ.⊶Ⴡⴖ; ss\u200C\uAAF6ᢥ.⊶Ⴡⴖ; [C1, V6]; xn--ss-4ep585bkm5p.xn--5nd703gyrh; ; xn--ss-4epx629f.xn--5nd703gyrh; [V6] # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4epx629f.xn--5nd703gyrh; ss\uAAF6ᢥ.⊶Ⴡⴖ; [V6]; xn--ss-4epx629f.xn--5nd703gyrh; ; ; # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4ep585bkm5p.xn--5nd703gyrh; ss\u200C\uAAF6ᢥ.⊶Ⴡⴖ; [C1, V6]; xn--ss-4ep585bkm5p.xn--5nd703gyrh; ; ; # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4epx629f.xn--ifh802b6a; ss\uAAF6ᢥ.⊶ⴡⴖ; ; xn--ss-4epx629f.xn--ifh802b6a; ; ; # ss꫶ᢥ.⊶ⴡⴖ
+ss\uAAF6ᢥ.⊶ⴡⴖ; ; ; xn--ss-4epx629f.xn--ifh802b6a; ; ; # ss꫶ᢥ.⊶ⴡⴖ
+SS\uAAF6ᢥ.⊶ჁႶ; ss\uAAF6ᢥ.⊶ჁႶ; [V6]; xn--ss-4epx629f.xn--undv409k; ; ; # ss꫶ᢥ.⊶ჁႶ
+Ss\uAAF6ᢥ.⊶Ⴡⴖ; ss\uAAF6ᢥ.⊶Ⴡⴖ; [V6]; xn--ss-4epx629f.xn--5nd703gyrh; ; ; # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4epx629f.xn--undv409k; ss\uAAF6ᢥ.⊶ჁႶ; [V6]; xn--ss-4epx629f.xn--undv409k; ; ; # ss꫶ᢥ.⊶ჁႶ
+xn--ss-4ep585bkm5p.xn--ifh802b6a; ss\u200C\uAAF6ᢥ.⊶ⴡⴖ; [C1]; xn--ss-4ep585bkm5p.xn--ifh802b6a; ; ; # ss꫶ᢥ.⊶ⴡⴖ
+xn--ss-4ep585bkm5p.xn--undv409k; ss\u200C\uAAF6ᢥ.⊶ჁႶ; [C1, V6]; xn--ss-4ep585bkm5p.xn--undv409k; ; ; # ss꫶ᢥ.⊶ჁႶ
+xn--zca682johfi89m.xn--ifh802b6a; ß\u200C\uAAF6ᢥ.⊶ⴡⴖ; [C1]; xn--zca682johfi89m.xn--ifh802b6a; ; ; # ß꫶ᢥ.⊶ⴡⴖ
+xn--zca682johfi89m.xn--undv409k; ß\u200C\uAAF6ᢥ.⊶ჁႶ; [C1, V6]; xn--zca682johfi89m.xn--undv409k; ; ; # ß꫶ᢥ.⊶ჁႶ
+ß\u200C\uAAF6ᢥ.⊶ⴡⴖ; ß\u200C\uAAF6ᢥ.⊶ⴡⴖ; [C1]; xn--zca682johfi89m.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ß꫶ᢥ.⊶ⴡⴖ
+SS\u200C\uAAF6ᢥ.⊶ჁႶ; ss\u200C\uAAF6ᢥ.⊶ჁႶ; [C1, V6]; xn--ss-4ep585bkm5p.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [V6] # ss꫶ᢥ.⊶ჁႶ
+ss\u200C\uAAF6ᢥ.⊶ⴡⴖ; ss\u200C\uAAF6ᢥ.⊶ⴡⴖ; [C1]; xn--ss-4ep585bkm5p.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ss꫶ᢥ.⊶ⴡⴖ
+Ss\u200C\uAAF6ᢥ.⊶Ⴡⴖ; ss\u200C\uAAF6ᢥ.⊶Ⴡⴖ; [C1, V6]; xn--ss-4ep585bkm5p.xn--5nd703gyrh; ; xn--ss-4epx629f.xn--5nd703gyrh; [V6] # ss꫶ᢥ.⊶Ⴡⴖ
+\u200D。ς󠁉; \u200D.ς󠁉; [C2, V6]; xn--1ug.xn--3xa44344p; ; .xn--4xa24344p; [V6, A4_2] # .ς
+\u200D。Σ󠁉; \u200D.σ󠁉; [C2, V6]; xn--1ug.xn--4xa24344p; ; .xn--4xa24344p; [V6, A4_2] # .σ
+\u200D。σ󠁉; \u200D.σ󠁉; [C2, V6]; xn--1ug.xn--4xa24344p; ; .xn--4xa24344p; [V6, A4_2] # .σ
+.xn--4xa24344p; .σ󠁉; [V6, X4_2]; .xn--4xa24344p; [V6, A4_2]; ; # .σ
+xn--1ug.xn--4xa24344p; \u200D.σ󠁉; [C2, V6]; xn--1ug.xn--4xa24344p; ; ; # .σ
+xn--1ug.xn--3xa44344p; \u200D.ς󠁉; [C2, V6]; xn--1ug.xn--3xa44344p; ; ; # .ς
+𞵑ß.\u0751\u200D𞤛-; 𞵑ß.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--zca5423w.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ß.ݑ𞤽-
+𞵑ß.\u0751\u200D𞤽-; ; [B2, B3, C2, V3, V6]; xn--zca5423w.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ß.ݑ𞤽-
+𞵑SS.\u0751\u200D𞤛-; 𞵑ss.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ss.ݑ𞤽-
+𞵑ss.\u0751\u200D𞤽-; ; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ss.ݑ𞤽-
+𞵑Ss.\u0751\u200D𞤽-; 𞵑ss.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ss.ݑ𞤽-
+xn--ss-2722a.xn----z3c03218a; 𞵑ss.\u0751𞤽-; [B2, B3, V3, V6]; xn--ss-2722a.xn----z3c03218a; ; ; # ss.ݑ𞤽-
+xn--ss-2722a.xn----z3c011q9513b; 𞵑ss.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; ; # ss.ݑ𞤽-
+xn--zca5423w.xn----z3c011q9513b; 𞵑ß.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--zca5423w.xn----z3c011q9513b; ; ; # ß.ݑ𞤽-
+𞵑ss.\u0751\u200D𞤛-; 𞵑ss.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ss.ݑ𞤽-
+𞵑Ss.\u0751\u200D𞤛-; 𞵑ss.\u0751\u200D𞤽-; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, V3, V6] # ss.ݑ𞤽-
+𑘽\u200D𞤧.𐹧󡦪-; 𑘽\u200D𞤧.𐹧󡦪-; [B1, C2, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, V3, V5, V6] # 𑘽𞤧.𐹧-
+𑘽\u200D𞤧.𐹧󡦪-; ; [B1, C2, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, V3, V5, V6] # 𑘽𞤧.𐹧-
+𑘽\u200D𞤅.𐹧󡦪-; 𑘽\u200D𞤧.𐹧󡦪-; [B1, C2, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, V3, V5, V6] # 𑘽𞤧.𐹧-
+xn--qb2ds317a.xn----k26iq1483f; 𑘽𞤧.𐹧󡦪-; [B1, V3, V5, V6]; xn--qb2ds317a.xn----k26iq1483f; ; ; # 𑘽𞤧.𐹧-
+xn--1ugz808gdimf.xn----k26iq1483f; 𑘽\u200D𞤧.𐹧󡦪-; [B1, C2, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; ; # 𑘽𞤧.𐹧-
+𑘽\u200D𞤅.𐹧󡦪-; 𑘽\u200D𞤧.𐹧󡦪-; [B1, C2, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, V3, V5, V6] # 𑘽𞤧.𐹧-
+⒒򨘙򳳠𑓀.-󞡊; ; [V3, V6]; xn--3shy698frsu9dt1me.xn----x310m; ; ; # ⒒𑓀.-
+11.򨘙򳳠𑓀.-󞡊; ; [V3, V6]; 11.xn--uz1d59632bxujd.xn----x310m; ; ; # 11.𑓀.-
+11.xn--uz1d59632bxujd.xn----x310m; 11.򨘙򳳠𑓀.-󞡊; [V3, V6]; 11.xn--uz1d59632bxujd.xn----x310m; ; ; # 11.𑓀.-
+xn--3shy698frsu9dt1me.xn----x310m; ⒒򨘙򳳠𑓀.-󞡊; [V3, V6]; xn--3shy698frsu9dt1me.xn----x310m; ; ; # ⒒𑓀.-
+-。\u200D; -.\u200D; [C2, V3]; -.xn--1ug; ; -.; [V3] # -.
+-。\u200D; -.\u200D; [C2, V3]; -.xn--1ug; ; -.; [V3] # -.
+-.; ; [V3]; ; ; ; # -.
+-.xn--1ug; -.\u200D; [C2, V3]; -.xn--1ug; ; ; # -.
+≮ᡬ.ς¹-?; ≮ᡬ.ς1-?; [V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+<\u0338ᡬ.ς¹-?; ≮ᡬ.ς1-?; [V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+≮ᡬ.ς1-?; ; [V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+<\u0338ᡬ.ς1-?; ≮ᡬ.ς1-?; [V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+<\u0338ᡬ.Σ1-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.Σ1-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.σ1-?; ; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+<\u0338ᡬ.σ1-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.xn--1-?-pzc; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.xn--1-?-lzc; ≮ᡬ.ς1-?; [V6]; xn--88e732c.xn--1-?-lzc; ; ; # ≮ᡬ.ς1-?
+<\u0338ᡬ.Σ¹-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.Σ¹-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.σ¹-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+<\u0338ᡬ.σ¹-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.σ1-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+XN--88E732C.Σ1-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.ς1-?; ≮ᡬ.ς1-?; [V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+Xn--88e732c.ς1-?; ≮ᡬ.ς1-?; [V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+Xn--88e732c.σ1-?; ≮ᡬ.σ1-?; [V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+ቬ򔠼񁗶。𐨬𝟠; ቬ򔠼񁗶.𐨬8; [V6]; xn--d0d41273c887z.xn--8-ob5i; ; ; # ቬ.𐨬8
+ቬ򔠼񁗶。𐨬8; ቬ򔠼񁗶.𐨬8; [V6]; xn--d0d41273c887z.xn--8-ob5i; ; ; # ቬ.𐨬8
+xn--d0d41273c887z.xn--8-ob5i; ቬ򔠼񁗶.𐨬8; [V6]; xn--d0d41273c887z.xn--8-ob5i; ; ; # ቬ.𐨬8
+𐱲。蔫\u0766; 𐱲.蔫\u0766; [B5, B6, V6]; xn--389c.xn--qpb7055d; ; ; # .蔫ݦ
+xn--389c.xn--qpb7055d; 𐱲.蔫\u0766; [B5, B6, V6]; xn--389c.xn--qpb7055d; ; ; # .蔫ݦ
+򒲧₃。ꡚ𛇑󠄳\u0647; 򒲧3.ꡚ𛇑\u0647; [B5, B6, V6]; xn--3-ep59g.xn--jhb5904fcp0h; ; ; # 3.ꡚ𛇑ه
+򒲧3。ꡚ𛇑󠄳\u0647; 򒲧3.ꡚ𛇑\u0647; [B5, B6, V6]; xn--3-ep59g.xn--jhb5904fcp0h; ; ; # 3.ꡚ𛇑ه
+xn--3-ep59g.xn--jhb5904fcp0h; 򒲧3.ꡚ𛇑\u0647; [B5, B6, V6]; xn--3-ep59g.xn--jhb5904fcp0h; ; ; # 3.ꡚ𛇑ه
+蓸\u0642≠.ß; ; [B5, B6]; xn--ehb015lnt1e.xn--zca; ; xn--ehb015lnt1e.ss; # 蓸ق≠.ß
+蓸\u0642=\u0338.ß; 蓸\u0642≠.ß; [B5, B6]; xn--ehb015lnt1e.xn--zca; ; xn--ehb015lnt1e.ss; # 蓸ق≠.ß
+蓸\u0642=\u0338.SS; 蓸\u0642≠.ss; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸\u0642≠.SS; 蓸\u0642≠.ss; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸\u0642≠.ss; ; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸\u0642=\u0338.ss; 蓸\u0642≠.ss; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸\u0642=\u0338.Ss; 蓸\u0642≠.ss; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸\u0642≠.Ss; 蓸\u0642≠.ss; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+xn--ehb015lnt1e.ss; 蓸\u0642≠.ss; [B5, B6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+xn--ehb015lnt1e.xn--zca; 蓸\u0642≠.ß; [B5, B6]; xn--ehb015lnt1e.xn--zca; ; ; # 蓸ق≠.ß
+\u084E\u067A\u0DD3⒊.𐹹𞱩󠃪\u200C; ; [B1, C1, V6]; xn--zib94gfziuq1a.xn--0ug3205g7eyf3c96h; ; xn--zib94gfziuq1a.xn--xo0dw109an237f; [B1, V6] # ࡎٺී⒊.𐹹
+\u084E\u067A\u0DD33..𐹹𞱩󠃪\u200C; ; [B1, C1, V6, X4_2]; xn--3-prc71ls9j..xn--0ug3205g7eyf3c96h; [B1, C1, V6, A4_2]; xn--3-prc71ls9j..xn--xo0dw109an237f; [B1, V6, A4_2] # ࡎٺී3..𐹹
+xn--3-prc71ls9j..xn--xo0dw109an237f; \u084E\u067A\u0DD33..𐹹𞱩󠃪; [B1, V6, X4_2]; xn--3-prc71ls9j..xn--xo0dw109an237f; [B1, V6, A4_2]; ; # ࡎٺී3..𐹹
+xn--3-prc71ls9j..xn--0ug3205g7eyf3c96h; \u084E\u067A\u0DD33..𐹹𞱩󠃪\u200C; [B1, C1, V6, X4_2]; xn--3-prc71ls9j..xn--0ug3205g7eyf3c96h; [B1, C1, V6, A4_2]; ; # ࡎٺී3..𐹹
+xn--zib94gfziuq1a.xn--xo0dw109an237f; \u084E\u067A\u0DD3⒊.𐹹𞱩󠃪; [B1, V6]; xn--zib94gfziuq1a.xn--xo0dw109an237f; ; ; # ࡎٺී⒊.𐹹
+xn--zib94gfziuq1a.xn--0ug3205g7eyf3c96h; \u084E\u067A\u0DD3⒊.𐹹𞱩󠃪\u200C; [B1, C1, V6]; xn--zib94gfziuq1a.xn--0ug3205g7eyf3c96h; ; ; # ࡎٺී⒊.𐹹
+ς\u200D-.Ⴣ𦟙; ; [C2, V3, V6]; xn----xmb348s.xn--7nd64871a; ; xn----zmb.xn--7nd64871a; [V3, V6] # ς-.Ⴣ𦟙
+ς\u200D-.ⴣ𦟙; ; [C2, V3]; xn----xmb348s.xn--rlj2573p; ; xn----zmb.xn--rlj2573p; [V3] # ς-.ⴣ𦟙
+Σ\u200D-.Ⴣ𦟙; σ\u200D-.Ⴣ𦟙; [C2, V3, V6]; xn----zmb048s.xn--7nd64871a; ; xn----zmb.xn--7nd64871a; [V3, V6] # σ-.Ⴣ𦟙
+σ\u200D-.ⴣ𦟙; ; [C2, V3]; xn----zmb048s.xn--rlj2573p; ; xn----zmb.xn--rlj2573p; [V3] # σ-.ⴣ𦟙
+xn----zmb.xn--rlj2573p; σ-.ⴣ𦟙; [V3]; xn----zmb.xn--rlj2573p; ; ; # σ-.ⴣ𦟙
+xn----zmb048s.xn--rlj2573p; σ\u200D-.ⴣ𦟙; [C2, V3]; xn----zmb048s.xn--rlj2573p; ; ; # σ-.ⴣ𦟙
+xn----zmb.xn--7nd64871a; σ-.Ⴣ𦟙; [V3, V6]; xn----zmb.xn--7nd64871a; ; ; # σ-.Ⴣ𦟙
+xn----zmb048s.xn--7nd64871a; σ\u200D-.Ⴣ𦟙; [C2, V3, V6]; xn----zmb048s.xn--7nd64871a; ; ; # σ-.Ⴣ𦟙
+xn----xmb348s.xn--rlj2573p; ς\u200D-.ⴣ𦟙; [C2, V3]; xn----xmb348s.xn--rlj2573p; ; ; # ς-.ⴣ𦟙
+xn----xmb348s.xn--7nd64871a; ς\u200D-.Ⴣ𦟙; [C2, V3, V6]; xn----xmb348s.xn--7nd64871a; ; ; # ς-.Ⴣ𦟙
+≠。🞳𝟲; ≠.🞳6; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+=\u0338。🞳𝟲; ≠.🞳6; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+≠。🞳6; ≠.🞳6; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+=\u0338。🞳6; ≠.🞳6; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+xn--1ch.xn--6-dl4s; ≠.🞳6; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+≠.🞳6; ; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+=\u0338.🞳6; ≠.🞳6; ; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+󅬽.蠔; ; [V6]; xn--g747d.xn--xl2a; ; ; # .蠔
+xn--g747d.xn--xl2a; 󅬽.蠔; [V6]; xn--g747d.xn--xl2a; ; ; # .蠔
+\u08E6\u200D.뼽; \u08E6\u200D.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+\u08E6\u200D.뼽; \u08E6\u200D.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+\u08E6\u200D.뼽; ; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+\u08E6\u200D.뼽; \u08E6\u200D.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+xn--p0b.xn--e43b; \u08E6.뼽; [V5]; xn--p0b.xn--e43b; ; ; # ࣦ.뼽
+xn--p0b869i.xn--e43b; \u08E6\u200D.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; ; # ࣦ.뼽
+₇\u0BCD􃂷\u06D2。👖\u0675-𞪑; 7\u0BCD􃂷\u06D2.👖\u0627\u0674-𞪑; [B1, V6]; xn--7-rwc839aj3073c.xn----ymc5uv818oghka; ; ; # 7்ے.👖اٴ-
+7\u0BCD􃂷\u06D2。👖\u0627\u0674-𞪑; 7\u0BCD􃂷\u06D2.👖\u0627\u0674-𞪑; [B1, V6]; xn--7-rwc839aj3073c.xn----ymc5uv818oghka; ; ; # 7்ے.👖اٴ-
+xn--7-rwc839aj3073c.xn----ymc5uv818oghka; 7\u0BCD􃂷\u06D2.👖\u0627\u0674-𞪑; [B1, V6]; xn--7-rwc839aj3073c.xn----ymc5uv818oghka; ; ; # 7்ے.👖اٴ-
+-。\u077B; -.\u077B; [B1, V3]; -.xn--cqb; ; ; # -.ݻ
+-。\u077B; -.\u077B; [B1, V3]; -.xn--cqb; ; ; # -.ݻ
+-.xn--cqb; -.\u077B; [B1, V3]; -.xn--cqb; ; ; # -.ݻ
+𑇌𵛓。-⒈ꡏ\u072B; 𑇌𵛓.-⒈ꡏ\u072B; [B1, V3, V5, V6]; xn--8d1dg030h.xn----u1c466tp10j; ; ; # 𑇌.-⒈ꡏܫ
+𑇌𵛓。-1.ꡏ\u072B; 𑇌𵛓.-1.ꡏ\u072B; [B1, B5, B6, V3, V5, V6]; xn--8d1dg030h.-1.xn--1nb7163f; ; ; # 𑇌.-1.ꡏܫ
+xn--8d1dg030h.-1.xn--1nb7163f; 𑇌𵛓.-1.ꡏ\u072B; [B1, B5, B6, V3, V5, V6]; xn--8d1dg030h.-1.xn--1nb7163f; ; ; # 𑇌.-1.ꡏܫ
+xn--8d1dg030h.xn----u1c466tp10j; 𑇌𵛓.-⒈ꡏ\u072B; [B1, V3, V5, V6]; xn--8d1dg030h.xn----u1c466tp10j; ; ; # 𑇌.-⒈ꡏܫ
+璛\u1734\u06AF.-; ; [B1, B5, B6, V3]; xn--ikb175frt4e.-; ; ; # 璛᜴گ.-
+xn--ikb175frt4e.-; 璛\u1734\u06AF.-; [B1, B5, B6, V3]; xn--ikb175frt4e.-; ; ; # 璛᜴گ.-
+󠆰\u08A1\u0A4D샕.𐹲휁; \u08A1\u0A4D샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+󠆰\u08A1\u0A4D샕.𐹲휁; \u08A1\u0A4D샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+󠆰\u08A1\u0A4D샕.𐹲휁; \u08A1\u0A4D샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+󠆰\u08A1\u0A4D샕.𐹲휁; \u08A1\u0A4D샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+xn--qyb07fj857a.xn--728bv72h; \u08A1\u0A4D샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+񍨽.񋸕; 񍨽.񋸕; [V6]; xn--pr3x.xn--rv7w; ; ; # .
+񍨽.񋸕; ; [V6]; xn--pr3x.xn--rv7w; ; ; # .
+xn--pr3x.xn--rv7w; 񍨽.񋸕; [V6]; xn--pr3x.xn--rv7w; ; ; # .
+\u067D𞥕。𑑂𞤶Ⴍ-; \u067D𞥕.𑑂𞤶Ⴍ-; [B1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+\u067D𞥕。𑑂𞤶Ⴍ-; \u067D𞥕.𑑂𞤶Ⴍ-; [B1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+\u067D𞥕。𑑂𞤶ⴍ-; \u067D𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+\u067D𞥕。𑑂𞤔Ⴍ-; \u067D𞥕.𑑂𞤶Ⴍ-; [B1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+\u067D𞥕。𑑂𞤔ⴍ-; \u067D𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+xn--2ib0338v.xn----zvs0199fo91g; \u067D𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+xn--2ib0338v.xn----w0g2740ro9vg; \u067D𞥕.𑑂𞤶Ⴍ-; [B1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+\u067D𞥕。𑑂𞤶ⴍ-; \u067D𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+\u067D𞥕。𑑂𞤔Ⴍ-; \u067D𞥕.𑑂𞤶Ⴍ-; [B1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+\u067D𞥕。𑑂𞤔ⴍ-; \u067D𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+𐯀𐸉𞧏。񢚧₄Ⴋ񂹫; 𐯀𐸉𞧏.񢚧4Ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-t0g49302fnrzm; ; ; # .4Ⴋ
+𐯀𐸉𞧏。񢚧4Ⴋ񂹫; 𐯀𐸉𞧏.񢚧4Ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-t0g49302fnrzm; ; ; # .4Ⴋ
+𐯀𐸉𞧏。񢚧4ⴋ񂹫; 𐯀𐸉𞧏.񢚧4ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-wvs27840bnrzm; ; ; # .4ⴋ
+xn--039c42bq865a.xn--4-wvs27840bnrzm; 𐯀𐸉𞧏.񢚧4ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-wvs27840bnrzm; ; ; # .4ⴋ
+xn--039c42bq865a.xn--4-t0g49302fnrzm; 𐯀𐸉𞧏.񢚧4Ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-t0g49302fnrzm; ; ; # .4Ⴋ
+𐯀𐸉𞧏。񢚧₄ⴋ񂹫; 𐯀𐸉𞧏.񢚧4ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-wvs27840bnrzm; ; ; # .4ⴋ
+4\u06BD︒󠑥.≠; ; [B1, V6]; xn--4-kvc5601q2h50i.xn--1ch; ; ; # 4ڽ︒.≠
+4\u06BD︒󠑥.=\u0338; 4\u06BD︒󠑥.≠; [B1, V6]; xn--4-kvc5601q2h50i.xn--1ch; ; ; # 4ڽ︒.≠
+4\u06BD。󠑥.≠; 4\u06BD.󠑥.≠; [B1, V6]; xn--4-kvc.xn--5136e.xn--1ch; ; ; # 4ڽ..≠
+4\u06BD。󠑥.=\u0338; 4\u06BD.󠑥.≠; [B1, V6]; xn--4-kvc.xn--5136e.xn--1ch; ; ; # 4ڽ..≠
+xn--4-kvc.xn--5136e.xn--1ch; 4\u06BD.󠑥.≠; [B1, V6]; xn--4-kvc.xn--5136e.xn--1ch; ; ; # 4ڽ..≠
+xn--4-kvc5601q2h50i.xn--1ch; 4\u06BD︒󠑥.≠; [B1, V6]; xn--4-kvc5601q2h50i.xn--1ch; ; ; # 4ڽ︒.≠
+𝟓。\u06D7; 5.\u06D7; [V5]; 5.xn--nlb; ; ; # 5.ۗ
+5。\u06D7; 5.\u06D7; [V5]; 5.xn--nlb; ; ; # 5.ۗ
+5.xn--nlb; 5.\u06D7; [V5]; 5.xn--nlb; ; ; # 5.ۗ
+\u200C򺸩.⾕; \u200C򺸩.谷; [C1, V6]; xn--0ug26167i.xn--6g3a; ; xn--i183d.xn--6g3a; [V6] # .谷
+\u200C򺸩.谷; ; [C1, V6]; xn--0ug26167i.xn--6g3a; ; xn--i183d.xn--6g3a; [V6] # .谷
+xn--i183d.xn--6g3a; 򺸩.谷; [V6]; xn--i183d.xn--6g3a; ; ; # .谷
+xn--0ug26167i.xn--6g3a; \u200C򺸩.谷; [C1, V6]; xn--0ug26167i.xn--6g3a; ; ; # .谷
+︒󎰇\u200D.-\u073C\u200C; ; [C1, C2, V3, V6]; xn--1ug1658ftw26f.xn----t2c071q; ; xn--y86c71305c.xn----t2c; [V3, V6] # ︒.-ܼ
+。󎰇\u200D.-\u073C\u200C; .󎰇\u200D.-\u073C\u200C; [C1, C2, V3, V6, X4_2]; .xn--1ug05310k.xn----t2c071q; [C1, C2, V3, V6, A4_2]; .xn--hh50e.xn----t2c; [V3, V6, A4_2] # ..-ܼ
+.xn--hh50e.xn----t2c; .󎰇.-\u073C; [V3, V6, X4_2]; .xn--hh50e.xn----t2c; [V3, V6, A4_2]; ; # ..-ܼ
+.xn--1ug05310k.xn----t2c071q; .󎰇\u200D.-\u073C\u200C; [C1, C2, V3, V6, X4_2]; .xn--1ug05310k.xn----t2c071q; [C1, C2, V3, V6, A4_2]; ; # ..-ܼ
+xn--y86c71305c.xn----t2c; ︒󎰇.-\u073C; [V3, V6]; xn--y86c71305c.xn----t2c; ; ; # ︒.-ܼ
+xn--1ug1658ftw26f.xn----t2c071q; ︒󎰇\u200D.-\u073C\u200C; [C1, C2, V3, V6]; xn--1ug1658ftw26f.xn----t2c071q; ; ; # ︒.-ܼ
+≯𞤟。ᡨ; ≯𞥁.ᡨ; [B1]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+>\u0338𞤟。ᡨ; ≯𞥁.ᡨ; [B1]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+>\u0338𞥁。ᡨ; ≯𞥁.ᡨ; [B1]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+≯𞥁。ᡨ; ≯𞥁.ᡨ; [B1]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+xn--hdhz520p.xn--48e; ≯𞥁.ᡨ; [B1]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+\u0F74𫫰𝨄。\u0713𐹦; \u0F74𫫰𝨄.\u0713𐹦; [B1, V5]; xn--ned8985uo92e.xn--dnb6395k; ; ; # ུ𫫰𝨄.ܓ𐹦
+xn--ned8985uo92e.xn--dnb6395k; \u0F74𫫰𝨄.\u0713𐹦; [B1, V5]; xn--ned8985uo92e.xn--dnb6395k; ; ; # ུ𫫰𝨄.ܓ𐹦
+\u033C\u07DB⁷𝟹。𝟬; \u033C\u07DB73.0; [B1, V5]; xn--73-9yb648b.0; ; ; # ̼ߛ73.0
+\u033C\u07DB73。0; \u033C\u07DB73.0; [B1, V5]; xn--73-9yb648b.0; ; ; # ̼ߛ73.0
+xn--73-9yb648b.0; \u033C\u07DB73.0; [B1, V5]; xn--73-9yb648b.0; ; ; # ̼ߛ73.0
+\u200D.𝟗; \u200D.9; [C2]; xn--1ug.9; ; .9; [A4_2] # .9
+\u200D.9; ; [C2]; xn--1ug.9; ; .9; [A4_2] # .9
+.9; ; [X4_2]; ; [A4_2]; ; # .9
+xn--1ug.9; \u200D.9; [C2]; xn--1ug.9; ; ; # .9
+9; ; ; ; ; ; # 9
+\u0779ᡭ𪕈。\u06B6\u08D9; \u0779ᡭ𪕈.\u06B6\u08D9; [B2, B3]; xn--9pb497fs270c.xn--pkb80i; ; ; # ݹᡭ𪕈.ڶࣙ
+xn--9pb497fs270c.xn--pkb80i; \u0779ᡭ𪕈.\u06B6\u08D9; [B2, B3]; xn--9pb497fs270c.xn--pkb80i; ; ; # ݹᡭ𪕈.ڶࣙ
+\u07265\u07E2겙。\u1CF4𐷚; \u07265\u07E2겙.\u1CF4𐷚; [B1, B2, B3, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+\u07265\u07E2겙。\u1CF4𐷚; \u07265\u07E2겙.\u1CF4𐷚; [B1, B2, B3, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+\u07265\u07E2겙。\u1CF4𐷚; \u07265\u07E2겙.\u1CF4𐷚; [B1, B2, B3, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+\u07265\u07E2겙。\u1CF4𐷚; \u07265\u07E2겙.\u1CF4𐷚; [B1, B2, B3, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+xn--5-j1c97c2483c.xn--e7f2093h; \u07265\u07E2겙.\u1CF4𐷚; [B1, B2, B3, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+Ⴍ𿣍ꡨ\u05AE。Ⴞ\u200C\u200C; Ⴍ𿣍ꡨ\u05AE.Ⴞ\u200C\u200C; [C1, V6]; xn--5cb347co96jug15a.xn--2nd059ea; ; xn--5cb347co96jug15a.xn--2nd; [V6] # Ⴍꡨ֮.Ⴞ
+ⴍ𿣍ꡨ\u05AE。ⴞ\u200C\u200C; ⴍ𿣍ꡨ\u05AE.ⴞ\u200C\u200C; [C1, V6]; xn--5cb172r175fug38a.xn--0uga051h; ; xn--5cb172r175fug38a.xn--mlj; [V6] # ⴍꡨ֮.ⴞ
+xn--5cb172r175fug38a.xn--mlj; ⴍ𿣍ꡨ\u05AE.ⴞ; [V6]; xn--5cb172r175fug38a.xn--mlj; ; ; # ⴍꡨ֮.ⴞ
+xn--5cb172r175fug38a.xn--0uga051h; ⴍ𿣍ꡨ\u05AE.ⴞ\u200C\u200C; [C1, V6]; xn--5cb172r175fug38a.xn--0uga051h; ; ; # ⴍꡨ֮.ⴞ
+xn--5cb347co96jug15a.xn--2nd; Ⴍ𿣍ꡨ\u05AE.Ⴞ; [V6]; xn--5cb347co96jug15a.xn--2nd; ; ; # Ⴍꡨ֮.Ⴞ
+xn--5cb347co96jug15a.xn--2nd059ea; Ⴍ𿣍ꡨ\u05AE.Ⴞ\u200C\u200C; [C1, V6]; xn--5cb347co96jug15a.xn--2nd059ea; ; ; # Ⴍꡨ֮.Ⴞ
+𐋰。󑓱; 𐋰.󑓱; [V6]; xn--k97c.xn--q031e; ; ; # 𐋰.
+xn--k97c.xn--q031e; 𐋰.󑓱; [V6]; xn--k97c.xn--q031e; ; ; # 𐋰.
+󡎦\u17B4\u0B4D.𐹾; ; [B1, V6]; xn--9ic364dho91z.xn--2o0d; ; ; # ୍.𐹾
+xn--9ic364dho91z.xn--2o0d; 󡎦\u17B4\u0B4D.𐹾; [B1, V6]; xn--9ic364dho91z.xn--2o0d; ; ; # ୍.𐹾
+\u08DFႫ𶿸귤.򠅼𝟢휪\u0AE3; \u08DFႫ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+\u08DFႫ𶿸귤.򠅼𝟢휪\u0AE3; \u08DFႫ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+\u08DFႫ𶿸귤.򠅼0휪\u0AE3; ; [V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+\u08DFႫ𶿸귤.򠅼0휪\u0AE3; \u08DFႫ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+\u08DFⴋ𶿸귤.򠅼0휪\u0AE3; \u08DFⴋ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+\u08DFⴋ𶿸귤.򠅼0휪\u0AE3; ; [V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; \u08DFⴋ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; \u08DFႫ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+\u08DFⴋ𶿸귤.򠅼𝟢휪\u0AE3; \u08DFⴋ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+\u08DFⴋ𶿸귤.򠅼𝟢휪\u0AE3; \u08DFⴋ𶿸귤.򠅼0휪\u0AE3; [V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+\u0784.𞡝\u0601; \u0784.𞡝\u0601; [V6]; xn--lqb.xn--jfb1808v; ; ; # ބ.𞡝
+\u0784.𞡝\u0601; ; [V6]; xn--lqb.xn--jfb1808v; ; ; # ބ.𞡝
+xn--lqb.xn--jfb1808v; \u0784.𞡝\u0601; [V6]; xn--lqb.xn--jfb1808v; ; ; # ބ.𞡝
+\u0ACD₃.8\uA8C4\u200D🃤; \u0ACD3.8\uA8C4\u200D🃤; [V5]; xn--3-yke.xn--8-ugnv982dbkwm; ; xn--3-yke.xn--8-sl4et308f; # ્3.8꣄🃤
+\u0ACD3.8\uA8C4\u200D🃤; ; [V5]; xn--3-yke.xn--8-ugnv982dbkwm; ; xn--3-yke.xn--8-sl4et308f; # ્3.8꣄🃤
+xn--3-yke.xn--8-sl4et308f; \u0ACD3.8\uA8C4🃤; [V5]; xn--3-yke.xn--8-sl4et308f; ; ; # ્3.8꣄🃤
+xn--3-yke.xn--8-ugnv982dbkwm; \u0ACD3.8\uA8C4\u200D🃤; [V5]; xn--3-yke.xn--8-ugnv982dbkwm; ; ; # ્3.8꣄🃤
+℻⩷𝆆。𞤠󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆。𞤠󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+fax⩷𝆆。𞥂󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+Fax⩷𝆆。𞤠󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+xn--fax-4c9a1676t.xn--6e6h; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+℻⩷𝆆。𞥂󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆。𞥂󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+fax⩷𝆆。𞤠󠆁\u180C; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+fax⩷𝆆.𞥂; ; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆.𞤠; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+Fax⩷𝆆.𞤠; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆.𞥂; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+Fax⩷𝆆.𞥂; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+ꡕ≠\u105E󮿱。𐵧󠄫\uFFA0; ꡕ≠\u105E󮿱.𐵧\uFFA0; [B2, B3, V6]; xn--cld333gn31h0158l.xn--cl7c96v; ; ; # ꡕ≠ၞ.
+ꡕ=\u0338\u105E󮿱。𐵧󠄫\uFFA0; ꡕ≠\u105E󮿱.𐵧\uFFA0; [B2, B3, V6]; xn--cld333gn31h0158l.xn--cl7c96v; ; ; # ꡕ≠ၞ.
+ꡕ≠\u105E󮿱。𐵧󠄫\u1160; ꡕ≠\u105E󮿱.𐵧\u1160; [B2, B3, V6]; xn--cld333gn31h0158l.xn--psd1510k; ; ; # ꡕ≠ၞ.
+ꡕ=\u0338\u105E󮿱。𐵧󠄫\u1160; ꡕ≠\u105E󮿱.𐵧\u1160; [B2, B3, V6]; xn--cld333gn31h0158l.xn--psd1510k; ; ; # ꡕ≠ၞ.
+xn--cld333gn31h0158l.xn--psd1510k; ꡕ≠\u105E󮿱.𐵧\u1160; [B2, B3, V6]; xn--cld333gn31h0158l.xn--psd1510k; ; ; # ꡕ≠ၞ.
+xn--cld333gn31h0158l.xn--cl7c96v; ꡕ≠\u105E󮿱.𐵧\uFFA0; [B2, B3, V6]; xn--cld333gn31h0158l.xn--cl7c96v; ; ; # ꡕ≠ၞ.
+鱊。\u200C; 鱊.\u200C; [C1]; xn--rt6a.xn--0ug; ; xn--rt6a.; [] # 鱊.
+xn--rt6a.; 鱊.; ; xn--rt6a.; ; ; # 鱊.
+鱊.; ; ; xn--rt6a.; ; ; # 鱊.
+xn--rt6a.xn--0ug; 鱊.\u200C; [C1]; xn--rt6a.xn--0ug; ; ; # 鱊.
+8𐹣.𑍨; 8𐹣.𑍨; [B1, V5]; xn--8-d26i.xn--0p1d; ; ; # 8𐹣.𑍨
+8𐹣.𑍨; ; [B1, V5]; xn--8-d26i.xn--0p1d; ; ; # 8𐹣.𑍨
+xn--8-d26i.xn--0p1d; 8𐹣.𑍨; [B1, V5]; xn--8-d26i.xn--0p1d; ; ; # 8𐹣.𑍨
+⏹𐧀.𐫯; ⏹𐧀.𐫯; [B1]; xn--qoh9161g.xn--1x9c; ; ; # ⏹𐧀.𐫯
+⏹𐧀.𐫯; ; [B1]; xn--qoh9161g.xn--1x9c; ; ; # ⏹𐧀.𐫯
+xn--qoh9161g.xn--1x9c; ⏹𐧀.𐫯; [B1]; xn--qoh9161g.xn--1x9c; ; ; # ⏹𐧀.𐫯
+𞤺\u07CC4.\u200D; 𞤺\u07CC4.\u200D; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+𞤺\u07CC4.\u200D; ; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+𞤘\u07CC4.\u200D; 𞤺\u07CC4.\u200D; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+xn--4-0bd15808a.; 𞤺\u07CC4.; ; xn--4-0bd15808a.; ; ; # 𞤺ߌ4.
+𞤺\u07CC4.; ; ; xn--4-0bd15808a.; ; ; # 𞤺ߌ4.
+𞤘\u07CC4.; 𞤺\u07CC4.; ; xn--4-0bd15808a.; ; ; # 𞤺ߌ4.
+xn--4-0bd15808a.xn--1ug; 𞤺\u07CC4.\u200D; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; ; # 𞤺ߌ4.
+𞤘\u07CC4.\u200D; 𞤺\u07CC4.\u200D; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+⒗\u0981\u20EF-.\u08E2•; ; [B1, V3, V6]; xn----z0d801p6kd.xn--l0b810j; ; ; # ⒗ঁ⃯-.•
+16.\u0981\u20EF-.\u08E2•; ; [B1, V3, V5, V6]; 16.xn----z0d801p.xn--l0b810j; ; ; # 16.ঁ⃯-.•
+16.xn----z0d801p.xn--l0b810j; 16.\u0981\u20EF-.\u08E2•; [B1, V3, V5, V6]; 16.xn----z0d801p.xn--l0b810j; ; ; # 16.ঁ⃯-.•
+xn----z0d801p6kd.xn--l0b810j; ⒗\u0981\u20EF-.\u08E2•; [B1, V3, V6]; xn----z0d801p6kd.xn--l0b810j; ; ; # ⒗ঁ⃯-.•
+-。䏛; -.䏛; [V3]; -.xn--xco; ; ; # -.䏛
+-。䏛; -.䏛; [V3]; -.xn--xco; ; ; # -.䏛
+-.xn--xco; -.䏛; [V3]; -.xn--xco; ; ; # -.䏛
+\u200C񒃠.\u200D; \u200C񒃠.\u200D; [C1, C2, V6]; xn--0ugz7551c.xn--1ug; ; xn--dj8y.; [V6] # .
+\u200C񒃠.\u200D; ; [C1, C2, V6]; xn--0ugz7551c.xn--1ug; ; xn--dj8y.; [V6] # .
+xn--dj8y.; 񒃠.; [V6]; xn--dj8y.; ; ; # .
+xn--0ugz7551c.xn--1ug; \u200C񒃠.\u200D; [C1, C2, V6]; xn--0ugz7551c.xn--1ug; ; ; # .
+⒈⓰󥣇。𐹠\u200D򗷦Ⴕ; ⒈⓰󥣇.𐹠\u200D򗷦Ⴕ; [B1, C2, V6]; xn--tsh0nz9380h.xn--tnd969erj4psgl3e; ; xn--tsh0nz9380h.xn--tnd1990ke579c; [B1, V6] # ⒈⓰.𐹠Ⴕ
+1.⓰󥣇。𐹠\u200D򗷦Ⴕ; 1.⓰󥣇.𐹠\u200D򗷦Ⴕ; [B1, C2, V6]; 1.xn--svh00804k.xn--tnd969erj4psgl3e; ; 1.xn--svh00804k.xn--tnd1990ke579c; [B1, V6] # 1.⓰.𐹠Ⴕ
+1.⓰󥣇。𐹠\u200D򗷦ⴕ; 1.⓰󥣇.𐹠\u200D򗷦ⴕ; [B1, C2, V6]; 1.xn--svh00804k.xn--1ug352csp0psg45e; ; 1.xn--svh00804k.xn--dljv223ee5t2d; [B1, V6] # 1.⓰.𐹠ⴕ
+1.xn--svh00804k.xn--dljv223ee5t2d; 1.⓰󥣇.𐹠򗷦ⴕ; [B1, V6]; 1.xn--svh00804k.xn--dljv223ee5t2d; ; ; # 1.⓰.𐹠ⴕ
+1.xn--svh00804k.xn--1ug352csp0psg45e; 1.⓰󥣇.𐹠\u200D򗷦ⴕ; [B1, C2, V6]; 1.xn--svh00804k.xn--1ug352csp0psg45e; ; ; # 1.⓰.𐹠ⴕ
+1.xn--svh00804k.xn--tnd1990ke579c; 1.⓰󥣇.𐹠򗷦Ⴕ; [B1, V6]; 1.xn--svh00804k.xn--tnd1990ke579c; ; ; # 1.⓰.𐹠Ⴕ
+1.xn--svh00804k.xn--tnd969erj4psgl3e; 1.⓰󥣇.𐹠\u200D򗷦Ⴕ; [B1, C2, V6]; 1.xn--svh00804k.xn--tnd969erj4psgl3e; ; ; # 1.⓰.𐹠Ⴕ
+⒈⓰󥣇。𐹠\u200D򗷦ⴕ; ⒈⓰󥣇.𐹠\u200D򗷦ⴕ; [B1, C2, V6]; xn--tsh0nz9380h.xn--1ug352csp0psg45e; ; xn--tsh0nz9380h.xn--dljv223ee5t2d; [B1, V6] # ⒈⓰.𐹠ⴕ
+xn--tsh0nz9380h.xn--dljv223ee5t2d; ⒈⓰󥣇.𐹠򗷦ⴕ; [B1, V6]; xn--tsh0nz9380h.xn--dljv223ee5t2d; ; ; # ⒈⓰.𐹠ⴕ
+xn--tsh0nz9380h.xn--1ug352csp0psg45e; ⒈⓰󥣇.𐹠\u200D򗷦ⴕ; [B1, C2, V6]; xn--tsh0nz9380h.xn--1ug352csp0psg45e; ; ; # ⒈⓰.𐹠ⴕ
+xn--tsh0nz9380h.xn--tnd1990ke579c; ⒈⓰󥣇.𐹠򗷦Ⴕ; [B1, V6]; xn--tsh0nz9380h.xn--tnd1990ke579c; ; ; # ⒈⓰.𐹠Ⴕ
+xn--tsh0nz9380h.xn--tnd969erj4psgl3e; ⒈⓰󥣇.𐹠\u200D򗷦Ⴕ; [B1, C2, V6]; xn--tsh0nz9380h.xn--tnd969erj4psgl3e; ; ; # ⒈⓰.𐹠Ⴕ
+𞠊ᠮ-ß。\u1CD0効\u0601𷣭; 𞠊ᠮ-ß.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn----qfa310pg973b.xn--jfb197i791bi6x4c; ; xn---ss-21t18904a.xn--jfb197i791bi6x4c; # 𞠊ᠮ-ß.᳐効
+𞠊ᠮ-ß。\u1CD0効\u0601𷣭; 𞠊ᠮ-ß.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn----qfa310pg973b.xn--jfb197i791bi6x4c; ; xn---ss-21t18904a.xn--jfb197i791bi6x4c; # 𞠊ᠮ-ß.᳐効
+𞠊ᠮ-SS。\u1CD0効\u0601𷣭; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-ss。\u1CD0効\u0601𷣭; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-Ss。\u1CD0効\u0601𷣭; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+xn---ss-21t18904a.xn--jfb197i791bi6x4c; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+xn----qfa310pg973b.xn--jfb197i791bi6x4c; 𞠊ᠮ-ß.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn----qfa310pg973b.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ß.᳐効
+𞠊ᠮ-SS。\u1CD0効\u0601𷣭; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-ss。\u1CD0効\u0601𷣭; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-Ss。\u1CD0効\u0601𷣭; 𞠊ᠮ-ss.\u1CD0効\u0601𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𑇀.󠨱; ; [V5, V6]; xn--wd1d.xn--k946e; ; ; # 𑇀.
+xn--wd1d.xn--k946e; 𑇀.󠨱; [V5, V6]; xn--wd1d.xn--k946e; ; ; # 𑇀.
+␒3\uFB88。𝟘𐨿𐹆; ␒3\u0688.0𐨿𐹆; [B1, V6]; xn--3-jsc897t.xn--0-sc5iy3h; ; ; # ␒3ڈ.0𐨿
+␒3\u0688。0𐨿𐹆; ␒3\u0688.0𐨿𐹆; [B1, V6]; xn--3-jsc897t.xn--0-sc5iy3h; ; ; # ␒3ڈ.0𐨿
+xn--3-jsc897t.xn--0-sc5iy3h; ␒3\u0688.0𐨿𐹆; [B1, V6]; xn--3-jsc897t.xn--0-sc5iy3h; ; ; # ␒3ڈ.0𐨿
+\u076B6\u0A81\u08A6。\u1DE3; \u076B6\u0A81\u08A6.\u1DE3; [B1, V5]; xn--6-h5c06gj6c.xn--7eg; ; ; # ݫ6ઁࢦ.ᷣ
+\u076B6\u0A81\u08A6。\u1DE3; \u076B6\u0A81\u08A6.\u1DE3; [B1, V5]; xn--6-h5c06gj6c.xn--7eg; ; ; # ݫ6ઁࢦ.ᷣ
+xn--6-h5c06gj6c.xn--7eg; \u076B6\u0A81\u08A6.\u1DE3; [B1, V5]; xn--6-h5c06gj6c.xn--7eg; ; ; # ݫ6ઁࢦ.ᷣ
+\u0605-𽤞Ⴂ。򅤶\u200D; \u0605-𽤞Ⴂ.򅤶\u200D; [B1, B6, C2, V6]; xn----0kc662fc152h.xn--1ugy3204f; ; xn----0kc662fc152h.xn--ss06b; [B1, V6] # -Ⴂ.
+\u0605-𽤞ⴂ。򅤶\u200D; \u0605-𽤞ⴂ.򅤶\u200D; [B1, B6, C2, V6]; xn----0kc8501a5399e.xn--1ugy3204f; ; xn----0kc8501a5399e.xn--ss06b; [B1, V6] # -ⴂ.
+xn----0kc8501a5399e.xn--ss06b; \u0605-𽤞ⴂ.򅤶; [B1, V6]; xn----0kc8501a5399e.xn--ss06b; ; ; # -ⴂ.
+xn----0kc8501a5399e.xn--1ugy3204f; \u0605-𽤞ⴂ.򅤶\u200D; [B1, B6, C2, V6]; xn----0kc8501a5399e.xn--1ugy3204f; ; ; # -ⴂ.
+xn----0kc662fc152h.xn--ss06b; \u0605-𽤞Ⴂ.򅤶; [B1, V6]; xn----0kc662fc152h.xn--ss06b; ; ; # -Ⴂ.
+xn----0kc662fc152h.xn--1ugy3204f; \u0605-𽤞Ⴂ.򅤶\u200D; [B1, B6, C2, V6]; xn----0kc662fc152h.xn--1ugy3204f; ; ; # -Ⴂ.
+⾆.ꡈ5≯ß; 舌.ꡈ5≯ß; ; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+⾆.ꡈ5>\u0338ß; 舌.ꡈ5≯ß; ; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+舌.ꡈ5≯ß; ; ; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+舌.ꡈ5>\u0338ß; 舌.ꡈ5≯ß; ; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+舌.ꡈ5>\u0338SS; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯SS; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯ss; ; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5>\u0338ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5>\u0338Ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯Ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+xn--tc1a.xn--5ss-3m2a5009e; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+xn--tc1a.xn--5-qfa988w745i; 舌.ꡈ5≯ß; ; xn--tc1a.xn--5-qfa988w745i; ; ; # 舌.ꡈ5≯ß
+⾆.ꡈ5>\u0338SS; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯SS; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5>\u0338ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5>\u0338Ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯Ss; 舌.ꡈ5≯ss; ; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+\u0ACD8\u200D.򾂈\u075C; \u0ACD8\u200D.򾂈\u075C; [B1, B5, B6, C2, V5, V6]; xn--8-yke534n.xn--gpb79046m; ; xn--8-yke.xn--gpb79046m; [B1, B5, B6, V5, V6] # ્8.ݜ
+\u0ACD8\u200D.򾂈\u075C; ; [B1, B5, B6, C2, V5, V6]; xn--8-yke534n.xn--gpb79046m; ; xn--8-yke.xn--gpb79046m; [B1, B5, B6, V5, V6] # ્8.ݜ
+xn--8-yke.xn--gpb79046m; \u0ACD8.򾂈\u075C; [B1, B5, B6, V5, V6]; xn--8-yke.xn--gpb79046m; ; ; # ્8.ݜ
+xn--8-yke534n.xn--gpb79046m; \u0ACD8\u200D.򾂈\u075C; [B1, B5, B6, C2, V5, V6]; xn--8-yke534n.xn--gpb79046m; ; ; # ્8.ݜ
+򸷆\u0A70≮򹓙.񞎧⁷󠯙\u06B6; 򸷆\u0A70≮򹓙.񞎧7󠯙\u06B6; [B5, B6, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+򸷆\u0A70<\u0338򹓙.񞎧⁷󠯙\u06B6; 򸷆\u0A70≮򹓙.񞎧7󠯙\u06B6; [B5, B6, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+򸷆\u0A70≮򹓙.񞎧7󠯙\u06B6; ; [B5, B6, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+򸷆\u0A70<\u0338򹓙.񞎧7󠯙\u06B6; 򸷆\u0A70≮򹓙.񞎧7󠯙\u06B6; [B5, B6, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; 򸷆\u0A70≮򹓙.񞎧7󠯙\u06B6; [B5, B6, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+𞤪.ς; ; ; xn--ie6h.xn--3xa; ; xn--ie6h.xn--4xa; # 𞤪.ς
+𞤈.Σ; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+𞤪.σ; ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+𞤈.σ; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+xn--ie6h.xn--4xa; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+𞤈.ς; 𞤪.ς; ; xn--ie6h.xn--3xa; ; xn--ie6h.xn--4xa; # 𞤪.ς
+xn--ie6h.xn--3xa; 𞤪.ς; ; xn--ie6h.xn--3xa; ; ; # 𞤪.ς
+𞤪.Σ; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+\u200CႺ。ς; \u200CႺ.ς; [C1, V6]; xn--ynd759e.xn--3xa; ; xn--ynd.xn--4xa; [V6] # Ⴚ.ς
+\u200CႺ。ς; \u200CႺ.ς; [C1, V6]; xn--ynd759e.xn--3xa; ; xn--ynd.xn--4xa; [V6] # Ⴚ.ς
+\u200Cⴚ。ς; \u200Cⴚ.ς; [C1]; xn--0ug262c.xn--3xa; ; xn--ilj.xn--4xa; [] # ⴚ.ς
+\u200CႺ。Σ; \u200CႺ.σ; [C1, V6]; xn--ynd759e.xn--4xa; ; xn--ynd.xn--4xa; [V6] # Ⴚ.σ
+\u200Cⴚ。σ; \u200Cⴚ.σ; [C1]; xn--0ug262c.xn--4xa; ; xn--ilj.xn--4xa; [] # ⴚ.σ
+xn--ilj.xn--4xa; ⴚ.σ; ; xn--ilj.xn--4xa; ; ; # ⴚ.σ
+ⴚ.σ; ; ; xn--ilj.xn--4xa; ; ; # ⴚ.σ
+Ⴚ.Σ; Ⴚ.σ; [V6]; xn--ynd.xn--4xa; ; ; # Ⴚ.σ
+ⴚ.ς; ; ; xn--ilj.xn--3xa; ; xn--ilj.xn--4xa; # ⴚ.ς
+Ⴚ.ς; ; [V6]; xn--ynd.xn--3xa; ; xn--ynd.xn--4xa; # Ⴚ.ς
+xn--ynd.xn--4xa; Ⴚ.σ; [V6]; xn--ynd.xn--4xa; ; ; # Ⴚ.σ
+xn--ynd.xn--3xa; Ⴚ.ς; [V6]; xn--ynd.xn--3xa; ; ; # Ⴚ.ς
+xn--ilj.xn--3xa; ⴚ.ς; ; xn--ilj.xn--3xa; ; ; # ⴚ.ς
+Ⴚ.σ; ; [V6]; xn--ynd.xn--4xa; ; ; # Ⴚ.σ
+xn--0ug262c.xn--4xa; \u200Cⴚ.σ; [C1]; xn--0ug262c.xn--4xa; ; ; # ⴚ.σ
+xn--ynd759e.xn--4xa; \u200CႺ.σ; [C1, V6]; xn--ynd759e.xn--4xa; ; ; # Ⴚ.σ
+xn--0ug262c.xn--3xa; \u200Cⴚ.ς; [C1]; xn--0ug262c.xn--3xa; ; ; # ⴚ.ς
+xn--ynd759e.xn--3xa; \u200CႺ.ς; [C1, V6]; xn--ynd759e.xn--3xa; ; ; # Ⴚ.ς
+\u200Cⴚ。ς; \u200Cⴚ.ς; [C1]; xn--0ug262c.xn--3xa; ; xn--ilj.xn--4xa; [] # ⴚ.ς
+\u200CႺ。Σ; \u200CႺ.σ; [C1, V6]; xn--ynd759e.xn--4xa; ; xn--ynd.xn--4xa; [V6] # Ⴚ.σ
+\u200Cⴚ。σ; \u200Cⴚ.σ; [C1]; xn--0ug262c.xn--4xa; ; xn--ilj.xn--4xa; [] # ⴚ.σ
+𞤃.𐹦; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+𞤃.𐹦; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+𞤥.𐹦; ; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+xn--de6h.xn--eo0d; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+𞤥.𐹦; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+\u200D⾕。\u200C\u0310\uA953ꡎ; \u200D谷.\u200C\uA953\u0310ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; xn--6g3a.xn--0sa8175flwa; [V5] # 谷.꥓̐ꡎ
+\u200D⾕。\u200C\uA953\u0310ꡎ; \u200D谷.\u200C\uA953\u0310ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; xn--6g3a.xn--0sa8175flwa; [V5] # 谷.꥓̐ꡎ
+\u200D谷。\u200C\uA953\u0310ꡎ; \u200D谷.\u200C\uA953\u0310ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; xn--6g3a.xn--0sa8175flwa; [V5] # 谷.꥓̐ꡎ
+xn--6g3a.xn--0sa8175flwa; 谷.\uA953\u0310ꡎ; [V5]; xn--6g3a.xn--0sa8175flwa; ; ; # 谷.꥓̐ꡎ
+xn--1ug0273b.xn--0sa359l6n7g13a; \u200D谷.\u200C\uA953\u0310ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; ; # 谷.꥓̐ꡎ
+\u06AA-뉔.𞤐\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+\u06AA-뉔.𞤐\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+\u06AA-뉔.𞤐\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+\u06AA-뉔.𞤐\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+\u06AA-뉔.𞤲\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+\u06AA-뉔.𞤲\u200C; ; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+xn----guc3592k.xn--qe6h; \u06AA-뉔.𞤲; [B2, B3]; xn----guc3592k.xn--qe6h; ; ; # ڪ-뉔.𞤲
+xn----guc3592k.xn--0ug7611p; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; ; # ڪ-뉔.𞤲
+\u06AA-뉔.𞤲\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+\u06AA-뉔.𞤲\u200C; \u06AA-뉔.𞤲\u200C; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+񔲵5ᦛς.\uA8C4\u077B\u1CD2\u0738; 񔲵5ᦛς.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; xn--5-0mb988ng603j.xn--fob7kk44dl41k; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛς.\uA8C4\u077B\u0738\u1CD2; 񔲵5ᦛς.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; xn--5-0mb988ng603j.xn--fob7kk44dl41k; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛς.\uA8C4\u077B\u0738\u1CD2; ; [B1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; xn--5-0mb988ng603j.xn--fob7kk44dl41k; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛΣ.\uA8C4\u077B\u0738\u1CD2; 񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; ; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+xn--5-0mb988ng603j.xn--fob7kk44dl41k; 񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+xn--5-ymb298ng603j.xn--fob7kk44dl41k; 񔲵5ᦛς.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛΣ.\uA8C4\u077B\u0738\u1CD2; 񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; 񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛΣ.\uA8C4\u077B\u1CD2\u0738; 񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛσ.\uA8C4\u077B\u1CD2\u0738; 񔲵5ᦛσ.\uA8C4\u077B\u0738\u1CD2; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+淽。ᠾ; 淽.ᠾ; ; xn--34w.xn--x7e; ; ; # 淽.ᠾ
+xn--34w.xn--x7e; 淽.ᠾ; ; xn--34w.xn--x7e; ; ; # 淽.ᠾ
+淽.ᠾ; ; ; xn--34w.xn--x7e; ; ; # 淽.ᠾ
+𐹴𑘷。-; 𐹴𑘷.-; [B1, V3]; xn--so0do6k.-; ; ; # 𐹴𑘷.-
+xn--so0do6k.-; 𐹴𑘷.-; [B1, V3]; xn--so0do6k.-; ; ; # 𐹴𑘷.-
+򬨩Ⴓ❓。𑄨; 򬨩Ⴓ❓.𑄨; [V5, V6]; xn--rnd896i0j14q.xn--k80d; ; ; # Ⴓ❓.𑄨
+򬨩Ⴓ❓。𑄨; 򬨩Ⴓ❓.𑄨; [V5, V6]; xn--rnd896i0j14q.xn--k80d; ; ; # Ⴓ❓.𑄨
+򬨩ⴓ❓。𑄨; 򬨩ⴓ❓.𑄨; [V5, V6]; xn--8di78qvw32y.xn--k80d; ; ; # ⴓ❓.𑄨
+xn--8di78qvw32y.xn--k80d; 򬨩ⴓ❓.𑄨; [V5, V6]; xn--8di78qvw32y.xn--k80d; ; ; # ⴓ❓.𑄨
+xn--rnd896i0j14q.xn--k80d; 򬨩Ⴓ❓.𑄨; [V5, V6]; xn--rnd896i0j14q.xn--k80d; ; ; # Ⴓ❓.𑄨
+򬨩ⴓ❓。𑄨; 򬨩ⴓ❓.𑄨; [V5, V6]; xn--8di78qvw32y.xn--k80d; ; ; # ⴓ❓.𑄨
+\u200C𐹡𞤌Ⴇ。ßႣ; \u200C𐹡𞤮Ⴇ.ßႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--zca681f; ; xn--fnd1201kegrf.xn--ss-fek; [B1, V6] # 𐹡𞤮Ⴇ.ßႣ
+\u200C𐹡𞤌Ⴇ。ßႣ; \u200C𐹡𞤮Ⴇ.ßႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--zca681f; ; xn--fnd1201kegrf.xn--ss-fek; [B1, V6] # 𐹡𞤮Ⴇ.ßႣ
+\u200C𐹡𞤮ⴇ。ßⴃ; \u200C𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+\u200C𐹡𞤌Ⴇ。SSႣ; \u200C𐹡𞤮Ⴇ.ssႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-fek; ; xn--fnd1201kegrf.xn--ss-fek; [B1, V6] # 𐹡𞤮Ⴇ.ssႣ
+\u200C𐹡𞤮ⴇ。ssⴃ; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+\u200C𐹡𞤌ⴇ。Ssⴃ; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+xn--ykj9323eegwf.xn--ss-151a; 𐹡𞤮ⴇ.ssⴃ; [B1]; xn--ykj9323eegwf.xn--ss-151a; ; ; # 𐹡𞤮ⴇ.ssⴃ
+xn--0ug332c3q0pr56g.xn--ss-151a; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; ; # 𐹡𞤮ⴇ.ssⴃ
+xn--fnd1201kegrf.xn--ss-fek; 𐹡𞤮Ⴇ.ssႣ; [B1, V6]; xn--fnd1201kegrf.xn--ss-fek; ; ; # 𐹡𞤮Ⴇ.ssႣ
+xn--fnd599eyj4pr50g.xn--ss-fek; \u200C𐹡𞤮Ⴇ.ssႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-fek; ; ; # 𐹡𞤮Ⴇ.ssႣ
+xn--0ug332c3q0pr56g.xn--zca417t; \u200C𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; ; # 𐹡𞤮ⴇ.ßⴃ
+xn--fnd599eyj4pr50g.xn--zca681f; \u200C𐹡𞤮Ⴇ.ßႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--zca681f; ; ; # 𐹡𞤮Ⴇ.ßႣ
+\u200C𐹡𞤮ⴇ。ßⴃ; \u200C𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+\u200C𐹡𞤌Ⴇ。SSႣ; \u200C𐹡𞤮Ⴇ.ssႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-fek; ; xn--fnd1201kegrf.xn--ss-fek; [B1, V6] # 𐹡𞤮Ⴇ.ssႣ
+\u200C𐹡𞤮ⴇ。ssⴃ; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+\u200C𐹡𞤌ⴇ。Ssⴃ; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+\u200C𐹡𞤌ⴇ。ßⴃ; \u200C𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+\u200C𐹡𞤌ⴇ。ssⴃ; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+\u200C𐹡𞤌Ⴇ。Ssⴃ; \u200C𐹡𞤮Ⴇ.ssⴃ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-151a; ; xn--fnd1201kegrf.xn--ss-151a; [B1, V6] # 𐹡𞤮Ⴇ.ssⴃ
+xn--fnd1201kegrf.xn--ss-151a; 𐹡𞤮Ⴇ.ssⴃ; [B1, V6]; xn--fnd1201kegrf.xn--ss-151a; ; ; # 𐹡𞤮Ⴇ.ssⴃ
+xn--fnd599eyj4pr50g.xn--ss-151a; \u200C𐹡𞤮Ⴇ.ssⴃ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-151a; ; ; # 𐹡𞤮Ⴇ.ssⴃ
+\u200C𐹡𞤌ⴇ。ßⴃ; \u200C𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+\u200C𐹡𞤌ⴇ。ssⴃ; \u200C𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+\u200C𐹡𞤌Ⴇ。Ssⴃ; \u200C𐹡𞤮Ⴇ.ssⴃ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-151a; ; xn--fnd1201kegrf.xn--ss-151a; [B1, V6] # 𐹡𞤮Ⴇ.ssⴃ
+\u17FF。𞬳; \u17FF.𞬳; [V6]; xn--45e.xn--et6h; ; ; # .
+\u17FF。𞬳; \u17FF.𞬳; [V6]; xn--45e.xn--et6h; ; ; # .
+xn--45e.xn--et6h; \u17FF.𞬳; [V6]; xn--45e.xn--et6h; ; ; # .
+\u0652\u200D。\u0CCD𑚳; \u0652\u200D.\u0CCD𑚳; [C2, V5]; xn--uhb882k.xn--8tc4527k; ; xn--uhb.xn--8tc4527k; [V5] # ْ.್𑚳
+\u0652\u200D。\u0CCD𑚳; \u0652\u200D.\u0CCD𑚳; [C2, V5]; xn--uhb882k.xn--8tc4527k; ; xn--uhb.xn--8tc4527k; [V5] # ْ.್𑚳
+xn--uhb.xn--8tc4527k; \u0652.\u0CCD𑚳; [V5]; xn--uhb.xn--8tc4527k; ; ; # ْ.್𑚳
+xn--uhb882k.xn--8tc4527k; \u0652\u200D.\u0CCD𑚳; [C2, V5]; xn--uhb882k.xn--8tc4527k; ; ; # ْ.್𑚳
+-≠ᠻ.\u076D𞥃≮󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-=\u0338ᠻ.\u076D𞥃<\u0338󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.\u076D𞥃≮󟷺; ; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-=\u0338ᠻ.\u076D𞥃<\u0338󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-=\u0338ᠻ.\u076D𞤡<\u0338󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.\u076D𞤡≮󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+xn----g6j886c.xn--xpb049kk353abj99f; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-=\u0338ᠻ.\u076D𞤡<\u0338󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.\u076D𞤡≮󟷺; -≠ᠻ.\u076D𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+󠰆≯\u07B5𐻪.򊥕≮𑁆\u084C; 󠰆≯\u07B5𐻪.򊥕≮𑁆\u084C; [B1, B5, B6, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+󠰆>\u0338\u07B5𐻪.򊥕<\u0338𑁆\u084C; 󠰆≯\u07B5𐻪.򊥕≮𑁆\u084C; [B1, B5, B6, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+󠰆≯\u07B5𐻪.򊥕≮𑁆\u084C; ; [B1, B5, B6, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+󠰆>\u0338\u07B5𐻪.򊥕<\u0338𑁆\u084C; 󠰆≯\u07B5𐻪.򊥕≮𑁆\u084C; [B1, B5, B6, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; 󠰆≯\u07B5𐻪.򊥕≮𑁆\u084C; [B1, B5, B6, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+≠󦋂.\u0600\u0BCD-\u06B9; ; [B1, V6]; xn--1ch22084l.xn----qkc07co6n; ; ; # ≠.்-ڹ
+=\u0338󦋂.\u0600\u0BCD-\u06B9; ≠󦋂.\u0600\u0BCD-\u06B9; [B1, V6]; xn--1ch22084l.xn----qkc07co6n; ; ; # ≠.்-ڹ
+xn--1ch22084l.xn----qkc07co6n; ≠󦋂.\u0600\u0BCD-\u06B9; [B1, V6]; xn--1ch22084l.xn----qkc07co6n; ; ; # ≠.்-ڹ
+\u17DD󠁣≠。𐹼𐋤; \u17DD󠁣≠.𐹼𐋤; [B1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+\u17DD󠁣=\u0338。𐹼𐋤; \u17DD󠁣≠.𐹼𐋤; [B1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+\u17DD󠁣≠。𐹼𐋤; \u17DD󠁣≠.𐹼𐋤; [B1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+\u17DD󠁣=\u0338。𐹼𐋤; \u17DD󠁣≠.𐹼𐋤; [B1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+xn--54e694cn389z.xn--787ct8r; \u17DD󠁣≠.𐹼𐋤; [B1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+ß𰀻񆬗。𝩨🕮ß; ß𰀻񆬗.𝩨🕮ß; [V5, V6]; xn--zca20040bgrkh.xn--zca3653v86qa; ; xn--ss-jl59biy67d.xn--ss-4d11aw87d; # ß𰀻.𝩨🕮ß
+ß𰀻񆬗。𝩨🕮ß; ß𰀻񆬗.𝩨🕮ß; [V5, V6]; xn--zca20040bgrkh.xn--zca3653v86qa; ; xn--ss-jl59biy67d.xn--ss-4d11aw87d; # ß𰀻.𝩨🕮ß
+SS𰀻񆬗。𝩨🕮SS; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+ss𰀻񆬗。𝩨🕮ss; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+Ss𰀻񆬗。𝩨🕮Ss; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+xn--ss-jl59biy67d.xn--ss-4d11aw87d; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+xn--zca20040bgrkh.xn--zca3653v86qa; ß𰀻񆬗.𝩨🕮ß; [V5, V6]; xn--zca20040bgrkh.xn--zca3653v86qa; ; ; # ß𰀻.𝩨🕮ß
+SS𰀻񆬗。𝩨🕮SS; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+ss𰀻񆬗。𝩨🕮ss; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+Ss𰀻񆬗。𝩨🕮Ss; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+\u200D。\u200C; \u200D.\u200C; [C1, C2]; xn--1ug.xn--0ug; ; .; [A4_2] # .
+xn--1ug.xn--0ug; \u200D.\u200C; [C1, C2]; xn--1ug.xn--0ug; ; ; # .
+\u0483𐭞\u200D.\u17B9𞯌򟩚; ; [B1, C2, V5, V6]; xn--m3a412lrr0o.xn--43e8670vmd79b; ; xn--m3a6965k.xn--43e8670vmd79b; [B1, V5, V6] # ҃𐭞.ឹ
+xn--m3a6965k.xn--43e8670vmd79b; \u0483𐭞.\u17B9𞯌򟩚; [B1, V5, V6]; xn--m3a6965k.xn--43e8670vmd79b; ; ; # ҃𐭞.ឹ
+xn--m3a412lrr0o.xn--43e8670vmd79b; \u0483𐭞\u200D.\u17B9𞯌򟩚; [B1, C2, V5, V6]; xn--m3a412lrr0o.xn--43e8670vmd79b; ; ; # ҃𐭞.ឹ
+\u200C𐠨\u200C临。ꡢ򄷞ⶏ𐹣; \u200C𐠨\u200C临.ꡢ򄷞ⶏ𐹣; [B1, B5, B6, C1, V6]; xn--0uga2656aop9k.xn--uojv340bk71c99u9f; ; xn--miq9646b.xn--uojv340bk71c99u9f; [B2, B3, B5, B6, V6] # 𐠨临.ꡢⶏ𐹣
+xn--miq9646b.xn--uojv340bk71c99u9f; 𐠨临.ꡢ򄷞ⶏ𐹣; [B2, B3, B5, B6, V6]; xn--miq9646b.xn--uojv340bk71c99u9f; ; ; # 𐠨临.ꡢⶏ𐹣
+xn--0uga2656aop9k.xn--uojv340bk71c99u9f; \u200C𐠨\u200C临.ꡢ򄷞ⶏ𐹣; [B1, B5, B6, C1, V6]; xn--0uga2656aop9k.xn--uojv340bk71c99u9f; ; ; # 𐠨临.ꡢⶏ𐹣
+󠑘.󠄮; 󠑘.; [V6]; xn--s136e.; ; ; # .
+󠑘.󠄮; 󠑘.; [V6]; xn--s136e.; ; ; # .
+xn--s136e.; 󠑘.; [V6]; xn--s136e.; ; ; # .
+𐫄\u0D4D.\uAAF6; 𐫄\u0D4D.\uAAF6; [B1, V5]; xn--wxc7880k.xn--2v9a; ; ; # 𐫄്.꫶
+𐫄\u0D4D.\uAAF6; ; [B1, V5]; xn--wxc7880k.xn--2v9a; ; ; # 𐫄്.꫶
+xn--wxc7880k.xn--2v9a; 𐫄\u0D4D.\uAAF6; [B1, V5]; xn--wxc7880k.xn--2v9a; ; ; # 𐫄്.꫶
+\uA9B7󝵙멹。⒛󠨇; \uA9B7󝵙멹.⒛󠨇; [V5, V6]; xn--ym9av13acp85w.xn--dth22121k; ; ; # ꦷ멹.⒛
+\uA9B7󝵙멹。⒛󠨇; \uA9B7󝵙멹.⒛󠨇; [V5, V6]; xn--ym9av13acp85w.xn--dth22121k; ; ; # ꦷ멹.⒛
+\uA9B7󝵙멹。20.󠨇; \uA9B7󝵙멹.20.󠨇; [V5, V6]; xn--ym9av13acp85w.20.xn--d846e; ; ; # ꦷ멹.20.
+\uA9B7󝵙멹。20.󠨇; \uA9B7󝵙멹.20.󠨇; [V5, V6]; xn--ym9av13acp85w.20.xn--d846e; ; ; # ꦷ멹.20.
+xn--ym9av13acp85w.20.xn--d846e; \uA9B7󝵙멹.20.󠨇; [V5, V6]; xn--ym9av13acp85w.20.xn--d846e; ; ; # ꦷ멹.20.
+xn--ym9av13acp85w.xn--dth22121k; \uA9B7󝵙멹.⒛󠨇; [V5, V6]; xn--ym9av13acp85w.xn--dth22121k; ; ; # ꦷ멹.⒛
+Ⴅ󲬹릖󠶚.\u0777𐹳⒊; ; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--7pb000mwm4n; ; ; # Ⴅ릖.ݷ𐹳⒊
+Ⴅ󲬹릖󠶚.\u0777𐹳⒊; Ⴅ󲬹릖󠶚.\u0777𐹳⒊; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--7pb000mwm4n; ; ; # Ⴅ릖.ݷ𐹳⒊
+Ⴅ󲬹릖󠶚.\u0777𐹳3.; ; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--3-55c6803r.; ; ; # Ⴅ릖.ݷ𐹳3.
+Ⴅ󲬹릖󠶚.\u0777𐹳3.; Ⴅ󲬹릖󠶚.\u0777𐹳3.; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--3-55c6803r.; ; ; # Ⴅ릖.ݷ𐹳3.
+ⴅ󲬹릖󠶚.\u0777𐹳3.; ⴅ󲬹릖󠶚.\u0777𐹳3.; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--3-55c6803r.; ; ; # ⴅ릖.ݷ𐹳3.
+ⴅ󲬹릖󠶚.\u0777𐹳3.; ; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--3-55c6803r.; ; ; # ⴅ릖.ݷ𐹳3.
+xn--wkj8016bne45io02g.xn--3-55c6803r.; ⴅ󲬹릖󠶚.\u0777𐹳3.; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--3-55c6803r.; ; ; # ⴅ릖.ݷ𐹳3.
+xn--dnd2167fnet0io02g.xn--3-55c6803r.; Ⴅ󲬹릖󠶚.\u0777𐹳3.; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--3-55c6803r.; ; ; # Ⴅ릖.ݷ𐹳3.
+ⴅ󲬹릖󠶚.\u0777𐹳⒊; ⴅ󲬹릖󠶚.\u0777𐹳⒊; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--7pb000mwm4n; ; ; # ⴅ릖.ݷ𐹳⒊
+ⴅ󲬹릖󠶚.\u0777𐹳⒊; ; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--7pb000mwm4n; ; ; # ⴅ릖.ݷ𐹳⒊
+xn--wkj8016bne45io02g.xn--7pb000mwm4n; ⴅ󲬹릖󠶚.\u0777𐹳⒊; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--7pb000mwm4n; ; ; # ⴅ릖.ݷ𐹳⒊
+xn--dnd2167fnet0io02g.xn--7pb000mwm4n; Ⴅ󲬹릖󠶚.\u0777𐹳⒊; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--7pb000mwm4n; ; ; # Ⴅ릖.ݷ𐹳⒊
+\u200C。︒; \u200C.︒; [C1, V6]; xn--0ug.xn--y86c; ; .xn--y86c; [V6, A4_2] # .︒
+\u200C。。; \u200C..; [C1, X4_2]; xn--0ug..; [C1, A4_2]; ..; [A4_2] # ..
+..; ; [X4_2]; ; [A4_2]; ; # ..
+xn--0ug..; \u200C..; [C1, X4_2]; xn--0ug..; [C1, A4_2]; ; # ..
+.xn--y86c; .︒; [V6, X4_2]; .xn--y86c; [V6, A4_2]; ; # .︒
+xn--0ug.xn--y86c; \u200C.︒; [C1, V6]; xn--0ug.xn--y86c; ; ; # .︒
+≯\u076D.₄; ≯\u076D.4; [B1]; xn--xpb149k.4; ; ; # ≯ݭ.4
+>\u0338\u076D.₄; ≯\u076D.4; [B1]; xn--xpb149k.4; ; ; # ≯ݭ.4
+≯\u076D.4; ; [B1]; xn--xpb149k.4; ; ; # ≯ݭ.4
+>\u0338\u076D.4; ≯\u076D.4; [B1]; xn--xpb149k.4; ; ; # ≯ݭ.4
+xn--xpb149k.4; ≯\u076D.4; [B1]; xn--xpb149k.4; ; ; # ≯ݭ.4
+ᡲ-𝟹.ß-\u200C-; ᡲ-3.ß-\u200C-; [C1, V3]; xn---3-p9o.xn-----fia9303a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ß--
+ᡲ-3.ß-\u200C-; ; [C1, V3]; xn---3-p9o.xn-----fia9303a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ß--
+ᡲ-3.SS-\u200C-; ᡲ-3.ss-\u200C-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-3.ss-\u200C-; ; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-3.Ss-\u200C-; ᡲ-3.ss-\u200C-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+xn---3-p9o.ss--; ᡲ-3.ss--; [V2, V3]; xn---3-p9o.ss--; ; ; # ᡲ-3.ss--
+xn---3-p9o.xn--ss---276a; ᡲ-3.ss-\u200C-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; ; # ᡲ-3.ss--
+xn---3-p9o.xn-----fia9303a; ᡲ-3.ß-\u200C-; [C1, V3]; xn---3-p9o.xn-----fia9303a; ; ; # ᡲ-3.ß--
+ᡲ-𝟹.SS-\u200C-; ᡲ-3.ss-\u200C-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-𝟹.ss-\u200C-; ᡲ-3.ss-\u200C-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-𝟹.Ss-\u200C-; ᡲ-3.ss-\u200C-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+\uFD08𝟦\u0647󎊯。Ӏ; \u0636\u064A4\u0647󎊯.Ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--d5a; ; ; # ضي4ه.Ӏ
+\u0636\u064A4\u0647󎊯。Ӏ; \u0636\u064A4\u0647󎊯.Ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--d5a; ; ; # ضي4ه.Ӏ
+\u0636\u064A4\u0647󎊯。ӏ; \u0636\u064A4\u0647󎊯.ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--s5a; ; ; # ضي4ه.ӏ
+xn--4-tnc6ck183523b.xn--s5a; \u0636\u064A4\u0647󎊯.ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--s5a; ; ; # ضي4ه.ӏ
+xn--4-tnc6ck183523b.xn--d5a; \u0636\u064A4\u0647󎊯.Ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--d5a; ; ; # ضي4ه.Ӏ
+\uFD08𝟦\u0647󎊯。ӏ; \u0636\u064A4\u0647󎊯.ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--s5a; ; ; # ضي4ه.ӏ
+-.\u0602\u0622𑆾🐹; ; [B1, V3, V6]; -.xn--kfb8dy983hgl7g; ; ; # -.آ𑆾🐹
+-.\u0602\u0627\u0653𑆾🐹; -.\u0602\u0622𑆾🐹; [B1, V3, V6]; -.xn--kfb8dy983hgl7g; ; ; # -.آ𑆾🐹
+-.xn--kfb8dy983hgl7g; -.\u0602\u0622𑆾🐹; [B1, V3, V6]; -.xn--kfb8dy983hgl7g; ; ; # -.آ𑆾🐹
+󙶜ᢘ。\u1A7F⺢; 󙶜ᢘ.\u1A7F⺢; [V5, V6]; xn--ibf35138o.xn--fpfz94g; ; ; # ᢘ.᩿⺢
+xn--ibf35138o.xn--fpfz94g; 󙶜ᢘ.\u1A7F⺢; [V5, V6]; xn--ibf35138o.xn--fpfz94g; ; ; # ᢘ.᩿⺢
+≠ႷᠤႫ。?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+=\u0338ႷᠤႫ。?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+≠ႷᠤႫ。?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+=\u0338ႷᠤႫ。?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+=\u0338ⴗᠤⴋ。?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠ⴗᠤⴋ。?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠Ⴗᠤⴋ。?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+=\u0338Ⴗᠤⴋ。?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--66e353ce0ilb.xn--?-7fb34t0u7s; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+xn--jndx718cnnl.xn--?-7fb34t0u7s; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+=\u0338ⴗᠤⴋ。?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠ⴗᠤⴋ。?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠Ⴗᠤⴋ。?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+=\u0338Ⴗᠤⴋ。?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--vnd619as6ig6k.?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+XN--VND619AS6IG6K.?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+Xn--Vnd619as6ig6k.?\u034C\u0633觴; ≠Ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--66e353ce0ilb.?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+XN--66E353CE0ILB.?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+Xn--66e353ce0ilb.?\u034C\u0633觴; ≠ⴗᠤⴋ.?\u034C\u0633觴; [B1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+xn--jndx718cnnl.?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+XN--JNDX718CNNL.?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+Xn--Jndx718cnnl.?\u034C\u0633觴; ≠ႷᠤႫ.?\u034C\u0633觴; [B1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+\u0667.𐥨; ; [B1, V6]; xn--gib.xn--vm9c; ; ; # ٧.
+xn--gib.xn--vm9c; \u0667.𐥨; [B1, V6]; xn--gib.xn--vm9c; ; ; # ٧.
+\uA9C0𝟯。\u200D񼑥𐹪\u1BF3; \uA9C03.\u200D񼑥𐹪\u1BF3; [B1, C2, V5, V6]; xn--3-5z4e.xn--1zf96ony8ygd68c; ; xn--3-5z4e.xn--1zfz754hncv8b; [B5, V5, V6] # ꧀3.𐹪᯳
+\uA9C03。\u200D񼑥𐹪\u1BF3; \uA9C03.\u200D񼑥𐹪\u1BF3; [B1, C2, V5, V6]; xn--3-5z4e.xn--1zf96ony8ygd68c; ; xn--3-5z4e.xn--1zfz754hncv8b; [B5, V5, V6] # ꧀3.𐹪᯳
+xn--3-5z4e.xn--1zfz754hncv8b; \uA9C03.񼑥𐹪\u1BF3; [B5, V5, V6]; xn--3-5z4e.xn--1zfz754hncv8b; ; ; # ꧀3.𐹪᯳
+xn--3-5z4e.xn--1zf96ony8ygd68c; \uA9C03.\u200D񼑥𐹪\u1BF3; [B1, C2, V5, V6]; xn--3-5z4e.xn--1zf96ony8ygd68c; ; ; # ꧀3.𐹪᯳
+򣕄4񠖽.≯\u0664𑀾󠸌; ; [B1, V6]; xn--4-fg85dl688i.xn--dib174li86ntdy0i; ; ; # 4.≯٤𑀾
+򣕄4񠖽.>\u0338\u0664𑀾󠸌; 򣕄4񠖽.≯\u0664𑀾󠸌; [B1, V6]; xn--4-fg85dl688i.xn--dib174li86ntdy0i; ; ; # 4.≯٤𑀾
+xn--4-fg85dl688i.xn--dib174li86ntdy0i; 򣕄4񠖽.≯\u0664𑀾󠸌; [B1, V6]; xn--4-fg85dl688i.xn--dib174li86ntdy0i; ; ; # 4.≯٤𑀾
+򗆧𝟯。⒈\u1A76𝟚򠘌; 򗆧3.⒈\u1A762򠘌; [V6]; xn--3-rj42h.xn--2-13k746cq465x; ; ; # 3.⒈᩶2
+򗆧3。1.\u1A762򠘌; 򗆧3.1.\u1A762򠘌; [V5, V6]; xn--3-rj42h.1.xn--2-13k96240l; ; ; # 3.1.᩶2
+xn--3-rj42h.1.xn--2-13k96240l; 򗆧3.1.\u1A762򠘌; [V5, V6]; xn--3-rj42h.1.xn--2-13k96240l; ; ; # 3.1.᩶2
+xn--3-rj42h.xn--2-13k746cq465x; 򗆧3.⒈\u1A762򠘌; [V6]; xn--3-rj42h.xn--2-13k746cq465x; ; ; # 3.⒈᩶2
+\u200D₅⒈。≯𝟴\u200D; \u200D5⒈.≯8\u200D; [C2, V6]; xn--5-tgnz5r.xn--8-ugn00i; ; xn--5-ecp.xn--8-ogo; [V6] # 5⒈.≯8
+\u200D₅⒈。>\u0338𝟴\u200D; \u200D5⒈.≯8\u200D; [C2, V6]; xn--5-tgnz5r.xn--8-ugn00i; ; xn--5-ecp.xn--8-ogo; [V6] # 5⒈.≯8
+\u200D51.。≯8\u200D; \u200D51..≯8\u200D; [C2, X4_2]; xn--51-l1t..xn--8-ugn00i; [C2, A4_2]; 51..xn--8-ogo; [A4_2] # 51..≯8
+\u200D51.。>\u03388\u200D; \u200D51..≯8\u200D; [C2, X4_2]; xn--51-l1t..xn--8-ugn00i; [C2, A4_2]; 51..xn--8-ogo; [A4_2] # 51..≯8
+51..xn--8-ogo; 51..≯8; [X4_2]; 51..xn--8-ogo; [A4_2]; ; # 51..≯8
+xn--51-l1t..xn--8-ugn00i; \u200D51..≯8\u200D; [C2, X4_2]; xn--51-l1t..xn--8-ugn00i; [C2, A4_2]; ; # 51..≯8
+xn--5-ecp.xn--8-ogo; 5⒈.≯8; [V6]; xn--5-ecp.xn--8-ogo; ; ; # 5⒈.≯8
+xn--5-tgnz5r.xn--8-ugn00i; \u200D5⒈.≯8\u200D; [C2, V6]; xn--5-tgnz5r.xn--8-ugn00i; ; ; # 5⒈.≯8
+ꡰ\u0697\u1086.򪘙\u072F≠\u200C; ꡰ\u0697\u1086.򪘙\u072F≠\u200C; [B5, B6, C1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, V6] # ꡰڗႆ.ܯ≠
+ꡰ\u0697\u1086.򪘙\u072F=\u0338\u200C; ꡰ\u0697\u1086.򪘙\u072F≠\u200C; [B5, B6, C1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, V6] # ꡰڗႆ.ܯ≠
+ꡰ\u0697\u1086.򪘙\u072F≠\u200C; ; [B5, B6, C1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, V6] # ꡰڗႆ.ܯ≠
+ꡰ\u0697\u1086.򪘙\u072F=\u0338\u200C; ꡰ\u0697\u1086.򪘙\u072F≠\u200C; [B5, B6, C1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, V6] # ꡰڗႆ.ܯ≠
+xn--tjb002cn51k.xn--5nb630lbj91q; ꡰ\u0697\u1086.򪘙\u072F≠; [B5, B6, V6]; xn--tjb002cn51k.xn--5nb630lbj91q; ; ; # ꡰڗႆ.ܯ≠
+xn--tjb002cn51k.xn--5nb448jcubcz547b; ꡰ\u0697\u1086.򪘙\u072F≠\u200C; [B5, B6, C1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; ; # ꡰڗႆ.ܯ≠
+𑄱。򪌿𐹵; 𑄱.򪌿𐹵; [B1, B5, B6, V5, V6]; xn--t80d.xn--to0d14792b; ; ; # 𑄱.𐹵
+𑄱。򪌿𐹵; 𑄱.򪌿𐹵; [B1, B5, B6, V5, V6]; xn--t80d.xn--to0d14792b; ; ; # 𑄱.𐹵
+xn--t80d.xn--to0d14792b; 𑄱.򪌿𐹵; [B1, B5, B6, V5, V6]; xn--t80d.xn--to0d14792b; ; ; # 𑄱.𐹵
+𝟥\u0600。\u073D; 3\u0600.\u073D; [B1, V5, V6]; xn--3-rkc.xn--kob; ; ; # 3.ܽ
+3\u0600。\u073D; 3\u0600.\u073D; [B1, V5, V6]; xn--3-rkc.xn--kob; ; ; # 3.ܽ
+xn--3-rkc.xn--kob; 3\u0600.\u073D; [B1, V5, V6]; xn--3-rkc.xn--kob; ; ; # 3.ܽ
+\u0637𐹣\u0666.\u076D긷; ; [B2, B3]; xn--2gb8gu829f.xn--xpb0156f; ; ; # ط𐹣٦.ݭ긷
+\u0637𐹣\u0666.\u076D긷; \u0637𐹣\u0666.\u076D긷; [B2, B3]; xn--2gb8gu829f.xn--xpb0156f; ; ; # ط𐹣٦.ݭ긷
+xn--2gb8gu829f.xn--xpb0156f; \u0637𐹣\u0666.\u076D긷; [B2, B3]; xn--2gb8gu829f.xn--xpb0156f; ; ; # ط𐹣٦.ݭ긷
+︒Ↄ\u2DE7򾀃.Ⴗ𐣞; ︒Ↄ\u2DE7򾀃.Ⴗ𐣞; [B1, B5, B6, V6]; xn--q5g000c056n0226g.xn--vnd8618j; ; ; # ︒Ↄⷧ.Ⴗ
+。Ↄ\u2DE7򾀃.Ⴗ𐣞; .Ↄ\u2DE7򾀃.Ⴗ𐣞; [B5, B6, V6, X4_2]; .xn--q5g000cll06u.xn--vnd8618j; [B5, B6, V6, A4_2]; ; # .Ↄⷧ.Ⴗ
+。ↄ\u2DE7򾀃.ⴗ𐣞; .ↄ\u2DE7򾀃.ⴗ𐣞; [B5, B6, V6, X4_2]; .xn--r5gy00cll06u.xn--flj4541e; [B5, B6, V6, A4_2]; ; # .ↄⷧ.ⴗ
+.xn--r5gy00cll06u.xn--flj4541e; .ↄ\u2DE7򾀃.ⴗ𐣞; [B5, B6, V6, X4_2]; .xn--r5gy00cll06u.xn--flj4541e; [B5, B6, V6, A4_2]; ; # .ↄⷧ.ⴗ
+.xn--q5g000cll06u.xn--vnd8618j; .Ↄ\u2DE7򾀃.Ⴗ𐣞; [B5, B6, V6, X4_2]; .xn--q5g000cll06u.xn--vnd8618j; [B5, B6, V6, A4_2]; ; # .Ↄⷧ.Ⴗ
+︒ↄ\u2DE7򾀃.ⴗ𐣞; ︒ↄ\u2DE7򾀃.ⴗ𐣞; [B1, B5, B6, V6]; xn--r5gy00c056n0226g.xn--flj4541e; ; ; # ︒ↄⷧ.ⴗ
+xn--r5gy00c056n0226g.xn--flj4541e; ︒ↄ\u2DE7򾀃.ⴗ𐣞; [B1, B5, B6, V6]; xn--r5gy00c056n0226g.xn--flj4541e; ; ; # ︒ↄⷧ.ⴗ
+xn--q5g000c056n0226g.xn--vnd8618j; ︒Ↄ\u2DE7򾀃.Ⴗ𐣞; [B1, B5, B6, V6]; xn--q5g000c056n0226g.xn--vnd8618j; ; ; # ︒Ↄⷧ.Ⴗ
+\u0600.\u05B1; ; [B1, V5, V6]; xn--ifb.xn--8cb; ; ; # .ֱ
+xn--ifb.xn--8cb; \u0600.\u05B1; [B1, V5, V6]; xn--ifb.xn--8cb; ; ; # .ֱ
+ς≯。𐹽; ς≯.𐹽; [B1, B6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+ς>\u0338。𐹽; ς≯.𐹽; [B1, B6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+ς≯。𐹽; ς≯.𐹽; [B1, B6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+ς>\u0338。𐹽; ς≯.𐹽; [B1, B6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+Σ>\u0338。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+Σ≯。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ≯。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ>\u0338。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+xn--4xa818m.xn--1o0d; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+xn--3xa028m.xn--1o0d; ς≯.𐹽; [B1, B6]; xn--3xa028m.xn--1o0d; ; ; # ς≯.𐹽
+Σ>\u0338。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+Σ≯。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ≯。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ>\u0338。𐹽; σ≯.𐹽; [B1, B6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+\u17D2\u200D\u075F。𐹶; \u17D2\u200D\u075F.𐹶; [B1, V5]; xn--jpb535fv9f.xn--uo0d; ; xn--jpb535f.xn--uo0d; # ្ݟ.𐹶
+xn--jpb535f.xn--uo0d; \u17D2\u075F.𐹶; [B1, V5]; xn--jpb535f.xn--uo0d; ; ; # ្ݟ.𐹶
+xn--jpb535fv9f.xn--uo0d; \u17D2\u200D\u075F.𐹶; [B1, V5]; xn--jpb535fv9f.xn--uo0d; ; ; # ្ݟ.𐹶
+𾷂\u0A42Ⴊ񂂟.≮; ; [V6]; xn--nbc493aro75ggskb.xn--gdh; ; ; # ੂႪ.≮
+𾷂\u0A42Ⴊ񂂟.<\u0338; 𾷂\u0A42Ⴊ񂂟.≮; [V6]; xn--nbc493aro75ggskb.xn--gdh; ; ; # ੂႪ.≮
+𾷂\u0A42ⴊ񂂟.<\u0338; 𾷂\u0A42ⴊ񂂟.≮; [V6]; xn--nbc229o4y27dgskb.xn--gdh; ; ; # ੂⴊ.≮
+𾷂\u0A42ⴊ񂂟.≮; ; [V6]; xn--nbc229o4y27dgskb.xn--gdh; ; ; # ੂⴊ.≮
+xn--nbc229o4y27dgskb.xn--gdh; 𾷂\u0A42ⴊ񂂟.≮; [V6]; xn--nbc229o4y27dgskb.xn--gdh; ; ; # ੂⴊ.≮
+xn--nbc493aro75ggskb.xn--gdh; 𾷂\u0A42Ⴊ񂂟.≮; [V6]; xn--nbc493aro75ggskb.xn--gdh; ; ; # ੂႪ.≮
+ꡠ.۲; ꡠ.۲; ; xn--5c9a.xn--fmb; ; ; # ꡠ.۲
+ꡠ.۲; ; ; xn--5c9a.xn--fmb; ; ; # ꡠ.۲
+xn--5c9a.xn--fmb; ꡠ.۲; ; xn--5c9a.xn--fmb; ; ; # ꡠ.۲
+𐹣񄷄。ꡬ🄄; 𐹣񄷄.ꡬ🄄; [B1, V6]; xn--bo0d0203l.xn--id9a4443d; ; ; # 𐹣.ꡬ🄄
+𐹣񄷄。ꡬ3,; 𐹣񄷄.ꡬ3,; [B1, B6, V6]; xn--bo0d0203l.xn--3,-yj9h; ; ; # 𐹣.ꡬ3,
+xn--bo0d0203l.xn--3,-yj9h; 𐹣񄷄.ꡬ3,; [B1, B6, V6]; xn--bo0d0203l.xn--3,-yj9h; ; ; # 𐹣.ꡬ3,
+xn--bo0d0203l.xn--id9a4443d; 𐹣񄷄.ꡬ🄄; [B1, V6]; xn--bo0d0203l.xn--id9a4443d; ; ; # 𐹣.ꡬ🄄
+-\u0C4D𞾀𑲓。\u200D\u0D4D; -\u0C4D𞾀𑲓.\u200D\u0D4D; [B1, C2, V3, V6]; xn----x6e0220sclug.xn--wxc317g; ; xn----x6e0220sclug.xn--wxc; [B1, V3, V5, V6] # -్𑲓.്
+-\u0C4D𞾀𑲓。\u200D\u0D4D; -\u0C4D𞾀𑲓.\u200D\u0D4D; [B1, C2, V3, V6]; xn----x6e0220sclug.xn--wxc317g; ; xn----x6e0220sclug.xn--wxc; [B1, V3, V5, V6] # -్𑲓.്
+xn----x6e0220sclug.xn--wxc; -\u0C4D𞾀𑲓.\u0D4D; [B1, V3, V5, V6]; xn----x6e0220sclug.xn--wxc; ; ; # -్𑲓.്
+xn----x6e0220sclug.xn--wxc317g; -\u0C4D𞾀𑲓.\u200D\u0D4D; [B1, C2, V3, V6]; xn----x6e0220sclug.xn--wxc317g; ; ; # -్𑲓.്
+\uA67D\u200C霣🄆。\u200C𑁂\u1B01; \uA67D\u200C霣🄆.\u200C𑁂\u1B01; [C1, V5, V6]; xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ; xn--2q5a751a653w.xn--4sf0725i; [V5, V6] # ꙽霣🄆.𑁂ᬁ
+\uA67D\u200C霣🄆。\u200C𑁂\u1B01; \uA67D\u200C霣🄆.\u200C𑁂\u1B01; [C1, V5, V6]; xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ; xn--2q5a751a653w.xn--4sf0725i; [V5, V6] # ꙽霣🄆.𑁂ᬁ
+\uA67D\u200C霣5,。\u200C𑁂\u1B01; \uA67D\u200C霣5,.\u200C𑁂\u1B01; [C1, V5, V6]; xn--5,-i1tz135dnbqa.xn--4sf36u6u4w; ; xn--5,-op8g373c.xn--4sf0725i; [V5, V6] # ꙽霣5,.𑁂ᬁ
+xn--5,-op8g373c.xn--4sf0725i; \uA67D霣5,.𑁂\u1B01; [V5, V6]; xn--5,-op8g373c.xn--4sf0725i; ; ; # ꙽霣5,.𑁂ᬁ
+xn--5,-i1tz135dnbqa.xn--4sf36u6u4w; \uA67D\u200C霣5,.\u200C𑁂\u1B01; [C1, V5, V6]; xn--5,-i1tz135dnbqa.xn--4sf36u6u4w; ; ; # ꙽霣5,.𑁂ᬁ
+xn--2q5a751a653w.xn--4sf0725i; \uA67D霣🄆.𑁂\u1B01; [V5, V6]; xn--2q5a751a653w.xn--4sf0725i; ; ; # ꙽霣🄆.𑁂ᬁ
+xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; \uA67D\u200C霣🄆.\u200C𑁂\u1B01; [C1, V5, V6]; xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ; ; # ꙽霣🄆.𑁂ᬁ
+兎。ᠼ󠴜𑚶𑰿; 兎.ᠼ󠴜𑚶𑰿; [V6]; xn--b5q.xn--v7e6041kqqd4m251b; ; ; # 兎.ᠼ𑚶𑰿
+兎。ᠼ󠴜𑚶𑰿; 兎.ᠼ󠴜𑚶𑰿; [V6]; xn--b5q.xn--v7e6041kqqd4m251b; ; ; # 兎.ᠼ𑚶𑰿
+xn--b5q.xn--v7e6041kqqd4m251b; 兎.ᠼ󠴜𑚶𑰿; [V6]; xn--b5q.xn--v7e6041kqqd4m251b; ; ; # 兎.ᠼ𑚶𑰿
+𝟙。\u200D𝟸\u200D⁷; 1.\u200D2\u200D7; [C2]; 1.xn--27-l1tb; ; 1.27; [] # 1.27
+1。\u200D2\u200D7; 1.\u200D2\u200D7; [C2]; 1.xn--27-l1tb; ; 1.27; [] # 1.27
+1.27; ; ; ; ; ; # 1.27
+1.xn--27-l1tb; 1.\u200D2\u200D7; [C2]; 1.xn--27-l1tb; ; ; # 1.27
+ᡨ-。󠻋𝟷; ᡨ-.󠻋1; [V3, V6]; xn----z8j.xn--1-5671m; ; ; # ᡨ-.1
+ᡨ-。󠻋1; ᡨ-.󠻋1; [V3, V6]; xn----z8j.xn--1-5671m; ; ; # ᡨ-.1
+xn----z8j.xn--1-5671m; ᡨ-.󠻋1; [V3, V6]; xn----z8j.xn--1-5671m; ; ; # ᡨ-.1
+𑰻񵀐𐫚.\u0668⁹; 𑰻񵀐𐫚.\u06689; [B1, V5, V6]; xn--gx9cr01aul57i.xn--9-oqc; ; ; # 𑰻𐫚.٨9
+𑰻񵀐𐫚.\u06689; ; [B1, V5, V6]; xn--gx9cr01aul57i.xn--9-oqc; ; ; # 𑰻𐫚.٨9
+xn--gx9cr01aul57i.xn--9-oqc; 𑰻񵀐𐫚.\u06689; [B1, V5, V6]; xn--gx9cr01aul57i.xn--9-oqc; ; ; # 𑰻𐫚.٨9
+Ⴜ򈷭\u0F80⾇。Ⴏ♀\u200C\u200C; Ⴜ򈷭\u0F80舛.Ⴏ♀\u200C\u200C; [C1, V6]; xn--zed54dz10wo343g.xn--nnd089ea464d; ; xn--zed54dz10wo343g.xn--nnd651i; [V6] # Ⴜྀ舛.Ⴏ♀
+Ⴜ򈷭\u0F80舛。Ⴏ♀\u200C\u200C; Ⴜ򈷭\u0F80舛.Ⴏ♀\u200C\u200C; [C1, V6]; xn--zed54dz10wo343g.xn--nnd089ea464d; ; xn--zed54dz10wo343g.xn--nnd651i; [V6] # Ⴜྀ舛.Ⴏ♀
+ⴜ򈷭\u0F80舛。ⴏ♀\u200C\u200C; ⴜ򈷭\u0F80舛.ⴏ♀\u200C\u200C; [C1, V6]; xn--zed372mdj2do3v4h.xn--0uga678bgyh; ; xn--zed372mdj2do3v4h.xn--e5h11w; [V6] # ⴜྀ舛.ⴏ♀
+xn--zed372mdj2do3v4h.xn--e5h11w; ⴜ򈷭\u0F80舛.ⴏ♀; [V6]; xn--zed372mdj2do3v4h.xn--e5h11w; ; ; # ⴜྀ舛.ⴏ♀
+xn--zed372mdj2do3v4h.xn--0uga678bgyh; ⴜ򈷭\u0F80舛.ⴏ♀\u200C\u200C; [C1, V6]; xn--zed372mdj2do3v4h.xn--0uga678bgyh; ; ; # ⴜྀ舛.ⴏ♀
+xn--zed54dz10wo343g.xn--nnd651i; Ⴜ򈷭\u0F80舛.Ⴏ♀; [V6]; xn--zed54dz10wo343g.xn--nnd651i; ; ; # Ⴜྀ舛.Ⴏ♀
+xn--zed54dz10wo343g.xn--nnd089ea464d; Ⴜ򈷭\u0F80舛.Ⴏ♀\u200C\u200C; [C1, V6]; xn--zed54dz10wo343g.xn--nnd089ea464d; ; ; # Ⴜྀ舛.Ⴏ♀
+ⴜ򈷭\u0F80⾇。ⴏ♀\u200C\u200C; ⴜ򈷭\u0F80舛.ⴏ♀\u200C\u200C; [C1, V6]; xn--zed372mdj2do3v4h.xn--0uga678bgyh; ; xn--zed372mdj2do3v4h.xn--e5h11w; [V6] # ⴜྀ舛.ⴏ♀
+𑁆𝟰.\u200D; 𑁆4.\u200D; [C2, V5]; xn--4-xu7i.xn--1ug; ; xn--4-xu7i.; [V5] # 𑁆4.
+𑁆4.\u200D; ; [C2, V5]; xn--4-xu7i.xn--1ug; ; xn--4-xu7i.; [V5] # 𑁆4.
+xn--4-xu7i.; 𑁆4.; [V5]; xn--4-xu7i.; ; ; # 𑁆4.
+xn--4-xu7i.xn--1ug; 𑁆4.\u200D; [C2, V5]; xn--4-xu7i.xn--1ug; ; ; # 𑁆4.
+񮴘Ⴞ癀。𑘿\u200D\u200C붼; 񮴘Ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [V5, V6] # Ⴞ癀.𑘿붼
+񮴘Ⴞ癀。𑘿\u200D\u200C붼; 񮴘Ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [V5, V6] # Ⴞ癀.𑘿붼
+񮴘Ⴞ癀。𑘿\u200D\u200C붼; 񮴘Ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [V5, V6] # Ⴞ癀.𑘿붼
+񮴘Ⴞ癀。𑘿\u200D\u200C붼; 񮴘Ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [V5, V6] # Ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿\u200D\u200C붼; 񮴘ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [V5, V6] # ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿\u200D\u200C붼; 񮴘ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [V5, V6] # ⴞ癀.𑘿붼
+xn--mlju35u7qx2f.xn--et3bn23n; 񮴘ⴞ癀.𑘿붼; [V5, V6]; xn--mlju35u7qx2f.xn--et3bn23n; ; ; # ⴞ癀.𑘿붼
+xn--mlju35u7qx2f.xn--0ugb6122js83c; 񮴘ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; ; # ⴞ癀.𑘿붼
+xn--2nd6803c7q37d.xn--et3bn23n; 񮴘Ⴞ癀.𑘿붼; [V5, V6]; xn--2nd6803c7q37d.xn--et3bn23n; ; ; # Ⴞ癀.𑘿붼
+xn--2nd6803c7q37d.xn--0ugb6122js83c; 񮴘Ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; ; # Ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿\u200D\u200C붼; 񮴘ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [V5, V6] # ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿\u200D\u200C붼; 񮴘ⴞ癀.𑘿\u200D\u200C붼; [C1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [V5, V6] # ⴞ癀.𑘿붼
+󚀅-\u0BCD。\u06B9; 󚀅-\u0BCD.\u06B9; [B6, V6]; xn----mze84808x.xn--skb; ; ; # -்.ڹ
+xn----mze84808x.xn--skb; 󚀅-\u0BCD.\u06B9; [B6, V6]; xn----mze84808x.xn--skb; ; ; # -்.ڹ
+ᡃ𝟧≯ᠣ.氁񨏱ꁫ; ᡃ5≯ᠣ.氁񨏱ꁫ; [V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+ᡃ𝟧>\u0338ᠣ.氁񨏱ꁫ; ᡃ5≯ᠣ.氁񨏱ꁫ; [V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+ᡃ5≯ᠣ.氁񨏱ꁫ; ; [V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+ᡃ5>\u0338ᠣ.氁񨏱ꁫ; ᡃ5≯ᠣ.氁񨏱ꁫ; [V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+xn--5-24jyf768b.xn--lqw213ime95g; ᡃ5≯ᠣ.氁񨏱ꁫ; [V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+𐹬𝩇.\u0F76; 𐹬𝩇.\u0FB2\u0F80; [B1, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+𐹬𝩇.\u0FB2\u0F80; 𐹬𝩇.\u0FB2\u0F80; [B1, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+𐹬𝩇.\u0FB2\u0F80; ; [B1, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+xn--ko0d8295a.xn--zed3h; 𐹬𝩇.\u0FB2\u0F80; [B1, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+-𑈶⒏.⒎𰛢󠎭; -𑈶⒏.⒎𰛢󠎭; [V3, V6]; xn----scp6252h.xn--zshy411yzpx2d; ; ; # -𑈶⒏.⒎𰛢
+-𑈶8..7.𰛢󠎭; ; [V3, V6, X4_2]; xn---8-bv5o..7.xn--c35nf1622b; [V3, V6, A4_2]; ; # -𑈶8..7.𰛢
+xn---8-bv5o..7.xn--c35nf1622b; -𑈶8..7.𰛢󠎭; [V3, V6, X4_2]; xn---8-bv5o..7.xn--c35nf1622b; [V3, V6, A4_2]; ; # -𑈶8..7.𰛢
+xn----scp6252h.xn--zshy411yzpx2d; -𑈶⒏.⒎𰛢󠎭; [V3, V6]; xn----scp6252h.xn--zshy411yzpx2d; ; ; # -𑈶⒏.⒎𰛢
+\u200CႡ畝\u200D.≮; \u200CႡ畝\u200D.≮; [C1, C2, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [V6] # Ⴁ畝.≮
+\u200CႡ畝\u200D.<\u0338; \u200CႡ畝\u200D.≮; [C1, C2, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [V6] # Ⴁ畝.≮
+\u200CႡ畝\u200D.≮; ; [C1, C2, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [V6] # Ⴁ畝.≮
+\u200CႡ畝\u200D.<\u0338; \u200CႡ畝\u200D.≮; [C1, C2, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [V6] # Ⴁ畝.≮
+\u200Cⴁ畝\u200D.<\u0338; \u200Cⴁ畝\u200D.≮; [C1, C2]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [] # ⴁ畝.≮
+\u200Cⴁ畝\u200D.≮; ; [C1, C2]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [] # ⴁ畝.≮
+xn--skjy82u.xn--gdh; ⴁ畝.≮; ; xn--skjy82u.xn--gdh; ; ; # ⴁ畝.≮
+ⴁ畝.≮; ; ; xn--skjy82u.xn--gdh; ; ; # ⴁ畝.≮
+ⴁ畝.<\u0338; ⴁ畝.≮; ; xn--skjy82u.xn--gdh; ; ; # ⴁ畝.≮
+Ⴁ畝.<\u0338; Ⴁ畝.≮; [V6]; xn--8md0962c.xn--gdh; ; ; # Ⴁ畝.≮
+Ⴁ畝.≮; ; [V6]; xn--8md0962c.xn--gdh; ; ; # Ⴁ畝.≮
+xn--8md0962c.xn--gdh; Ⴁ畝.≮; [V6]; xn--8md0962c.xn--gdh; ; ; # Ⴁ畝.≮
+xn--0ugc160hb36e.xn--gdh; \u200Cⴁ畝\u200D.≮; [C1, C2]; xn--0ugc160hb36e.xn--gdh; ; ; # ⴁ畝.≮
+xn--8md700fea3748f.xn--gdh; \u200CႡ畝\u200D.≮; [C1, C2, V6]; xn--8md700fea3748f.xn--gdh; ; ; # Ⴁ畝.≮
+\u200Cⴁ畝\u200D.<\u0338; \u200Cⴁ畝\u200D.≮; [C1, C2]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [] # ⴁ畝.≮
+\u200Cⴁ畝\u200D.≮; \u200Cⴁ畝\u200D.≮; [C1, C2]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [] # ⴁ畝.≮
+歷。𐹻≯󳛽\u200D; 歷.𐹻≯󳛽\u200D; [B1, C2, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, V6] # 歷.𐹻≯
+歷。𐹻>\u0338󳛽\u200D; 歷.𐹻≯󳛽\u200D; [B1, C2, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, V6] # 歷.𐹻≯
+歷。𐹻≯󳛽\u200D; 歷.𐹻≯󳛽\u200D; [B1, C2, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, V6] # 歷.𐹻≯
+歷。𐹻>\u0338󳛽\u200D; 歷.𐹻≯󳛽\u200D; [B1, C2, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, V6] # 歷.𐹻≯
+xn--nmw.xn--hdh7804gdms2h; 歷.𐹻≯󳛽; [B1, V6]; xn--nmw.xn--hdh7804gdms2h; ; ; # 歷.𐹻≯
+xn--nmw.xn--1ugx6gs128a1134j; 歷.𐹻≯󳛽\u200D; [B1, C2, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; ; # 歷.𐹻≯
+\u0ECB\u200D.鎁󠰑; \u0ECB\u200D.鎁󠰑; [C2, V5, V6]; xn--t8c059f.xn--iz4a43209d; ; xn--t8c.xn--iz4a43209d; [V5, V6] # ໋.鎁
+\u0ECB\u200D.鎁󠰑; ; [C2, V5, V6]; xn--t8c059f.xn--iz4a43209d; ; xn--t8c.xn--iz4a43209d; [V5, V6] # ໋.鎁
+xn--t8c.xn--iz4a43209d; \u0ECB.鎁󠰑; [V5, V6]; xn--t8c.xn--iz4a43209d; ; ; # ໋.鎁
+xn--t8c059f.xn--iz4a43209d; \u0ECB\u200D.鎁󠰑; [C2, V5, V6]; xn--t8c059f.xn--iz4a43209d; ; ; # ໋.鎁
+\u200D\u200C𞤀。𱘅𐶃; \u200D\u200C𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, V6] # 𞤢.𱘅
+\u200D\u200C𞤀。𱘅𐶃; \u200D\u200C𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, V6] # 𞤢.𱘅
+\u200D\u200C𞤢。𱘅𐶃; \u200D\u200C𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, V6] # 𞤢.𱘅
+xn--9d6h.xn--wh0dj799f; 𞤢.𱘅𐶃; [B5, B6, V6]; xn--9d6h.xn--wh0dj799f; ; ; # 𞤢.𱘅
+xn--0ugb45126a.xn--wh0dj799f; \u200D\u200C𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, V6]; xn--0ugb45126a.xn--wh0dj799f; ; ; # 𞤢.𱘅
+\u200D\u200C𞤢。𱘅𐶃; \u200D\u200C𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, V6] # 𞤢.𱘅
+\u0628≠𝟫-.ς⒍𐹦≠; \u0628≠9-.ς⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--3xa097mzpbzz04b; ; xn--9--etd0100a.xn--4xa887mzpbzz04b; # ب≠9-.ς⒍𐹦≠
+\u0628=\u0338𝟫-.ς⒍𐹦=\u0338; \u0628≠9-.ς⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--3xa097mzpbzz04b; ; xn--9--etd0100a.xn--4xa887mzpbzz04b; # ب≠9-.ς⒍𐹦≠
+\u0628≠9-.ς6.𐹦≠; ; [B1, B3, V3]; xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; # ب≠9-.ς6.𐹦≠
+\u0628=\u03389-.ς6.𐹦=\u0338; \u0628≠9-.ς6.𐹦≠; [B1, B3, V3]; xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; # ب≠9-.ς6.𐹦≠
+\u0628=\u03389-.Σ6.𐹦=\u0338; \u0628≠9-.σ6.𐹦≠; [B1, B3, V3]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+\u0628≠9-.Σ6.𐹦≠; \u0628≠9-.σ6.𐹦≠; [B1, B3, V3]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+\u0628≠9-.σ6.𐹦≠; ; [B1, B3, V3]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+\u0628=\u03389-.σ6.𐹦=\u0338; \u0628≠9-.σ6.𐹦≠; [B1, B3, V3]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; \u0628≠9-.σ6.𐹦≠; [B1, B3, V3]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; \u0628≠9-.ς6.𐹦≠; [B1, B3, V3]; xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ; ; # ب≠9-.ς6.𐹦≠
+\u0628=\u0338𝟫-.Σ⒍𐹦=\u0338; \u0628≠9-.σ⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+\u0628≠𝟫-.Σ⒍𐹦≠; \u0628≠9-.σ⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+\u0628≠𝟫-.σ⒍𐹦≠; \u0628≠9-.σ⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+\u0628=\u0338𝟫-.σ⒍𐹦=\u0338; \u0628≠9-.σ⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+xn--9--etd0100a.xn--4xa887mzpbzz04b; \u0628≠9-.σ⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+xn--9--etd0100a.xn--3xa097mzpbzz04b; \u0628≠9-.ς⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--3xa097mzpbzz04b; ; ; # ب≠9-.ς⒍𐹦≠
+򉛴.-ᡢ\u0592𝨠; ; [V3, V6]; xn--ep37b.xn----hec165lho83b; ; ; # .-ᡢ֒𝨠
+xn--ep37b.xn----hec165lho83b; 򉛴.-ᡢ\u0592𝨠; [V3, V6]; xn--ep37b.xn----hec165lho83b; ; ; # .-ᡢ֒𝨠
+\u06CB⒈ß󠄽。񷋍-; \u06CB⒈ß.񷋍-; [B2, B3, B6, V3, V6]; xn--zca541ato3a.xn----q001f; ; xn--ss-d7d6651a.xn----q001f; # ۋ⒈ß.-
+\u06CB1.ß󠄽。񷋍-; \u06CB1.ß.񷋍-; [B6, V3, V6]; xn--1-cwc.xn--zca.xn----q001f; ; xn--1-cwc.ss.xn----q001f; # ۋ1.ß.-
+\u06CB1.SS󠄽。񷋍-; \u06CB1.ss.񷋍-; [B6, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+\u06CB1.ss󠄽。񷋍-; \u06CB1.ss.񷋍-; [B6, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+\u06CB1.Ss󠄽。񷋍-; \u06CB1.ss.񷋍-; [B6, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+xn--1-cwc.ss.xn----q001f; \u06CB1.ss.񷋍-; [B6, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+xn--1-cwc.xn--zca.xn----q001f; \u06CB1.ß.񷋍-; [B6, V3, V6]; xn--1-cwc.xn--zca.xn----q001f; ; ; # ۋ1.ß.-
+\u06CB⒈SS󠄽。񷋍-; \u06CB⒈ss.񷋍-; [B2, B3, B6, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+\u06CB⒈ss󠄽。񷋍-; \u06CB⒈ss.񷋍-; [B2, B3, B6, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+\u06CB⒈Ss󠄽。񷋍-; \u06CB⒈ss.񷋍-; [B2, B3, B6, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+xn--ss-d7d6651a.xn----q001f; \u06CB⒈ss.񷋍-; [B2, B3, B6, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+xn--zca541ato3a.xn----q001f; \u06CB⒈ß.񷋍-; [B2, B3, B6, V3, V6]; xn--zca541ato3a.xn----q001f; ; ; # ۋ⒈ß.-
+𿀫.\u1BAAςႦ\u200D; 𿀫.\u1BAAςႦ\u200D; [C2, V5, V6]; xn--nu4s.xn--3xa417dxriome; ; xn--nu4s.xn--4xa217dxri; [V5, V6] # .᮪ςႦ
+𿀫.\u1BAAςႦ\u200D; ; [C2, V5, V6]; xn--nu4s.xn--3xa417dxriome; ; xn--nu4s.xn--4xa217dxri; [V5, V6] # .᮪ςႦ
+𿀫.\u1BAAςⴆ\u200D; ; [C2, V5, V6]; xn--nu4s.xn--3xa353jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [V5, V6] # .᮪ςⴆ
+𿀫.\u1BAAΣႦ\u200D; 𿀫.\u1BAAσႦ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa217dxriome; ; xn--nu4s.xn--4xa217dxri; [V5, V6] # .᮪σႦ
+𿀫.\u1BAAσⴆ\u200D; ; [C2, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [V5, V6] # .᮪σⴆ
+𿀫.\u1BAAΣⴆ\u200D; 𿀫.\u1BAAσⴆ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [V5, V6] # .᮪σⴆ
+xn--nu4s.xn--4xa153j7im; 𿀫.\u1BAAσⴆ; [V5, V6]; xn--nu4s.xn--4xa153j7im; ; ; # .᮪σⴆ
+xn--nu4s.xn--4xa153jk8cs1q; 𿀫.\u1BAAσⴆ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; ; # .᮪σⴆ
+xn--nu4s.xn--4xa217dxri; 𿀫.\u1BAAσႦ; [V5, V6]; xn--nu4s.xn--4xa217dxri; ; ; # .᮪σႦ
+xn--nu4s.xn--4xa217dxriome; 𿀫.\u1BAAσႦ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa217dxriome; ; ; # .᮪σႦ
+xn--nu4s.xn--3xa353jk8cs1q; 𿀫.\u1BAAςⴆ\u200D; [C2, V5, V6]; xn--nu4s.xn--3xa353jk8cs1q; ; ; # .᮪ςⴆ
+xn--nu4s.xn--3xa417dxriome; 𿀫.\u1BAAςႦ\u200D; [C2, V5, V6]; xn--nu4s.xn--3xa417dxriome; ; ; # .᮪ςႦ
+𿀫.\u1BAAςⴆ\u200D; 𿀫.\u1BAAςⴆ\u200D; [C2, V5, V6]; xn--nu4s.xn--3xa353jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [V5, V6] # .᮪ςⴆ
+𿀫.\u1BAAΣႦ\u200D; 𿀫.\u1BAAσႦ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa217dxriome; ; xn--nu4s.xn--4xa217dxri; [V5, V6] # .᮪σႦ
+𿀫.\u1BAAσⴆ\u200D; 𿀫.\u1BAAσⴆ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [V5, V6] # .᮪σⴆ
+𿀫.\u1BAAΣⴆ\u200D; 𿀫.\u1BAAσⴆ\u200D; [C2, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [V5, V6] # .᮪σⴆ
+⾆\u08E2.𝈴; 舌\u08E2.𝈴; [B1, B5, B6, V6]; xn--l0b9413d.xn--kl1h; ; ; # 舌.𝈴
+舌\u08E2.𝈴; ; [B1, B5, B6, V6]; xn--l0b9413d.xn--kl1h; ; ; # 舌.𝈴
+xn--l0b9413d.xn--kl1h; 舌\u08E2.𝈴; [B1, B5, B6, V6]; xn--l0b9413d.xn--kl1h; ; ; # 舌.𝈴
+⫞𐹶𖫴。⭠⒈; ⫞𐹶𖫴.⭠⒈; [B1, V6]; xn--53ix188et88b.xn--tsh52w; ; ; # ⫞𐹶𖫴.⭠⒈
+⫞𐹶𖫴。⭠1.; ⫞𐹶𖫴.⭠1.; [B1]; xn--53ix188et88b.xn--1-h6r.; ; ; # ⫞𐹶𖫴.⭠1.
+xn--53ix188et88b.xn--1-h6r.; ⫞𐹶𖫴.⭠1.; [B1]; xn--53ix188et88b.xn--1-h6r.; ; ; # ⫞𐹶𖫴.⭠1.
+xn--53ix188et88b.xn--tsh52w; ⫞𐹶𖫴.⭠⒈; [B1, V6]; xn--53ix188et88b.xn--tsh52w; ; ; # ⫞𐹶𖫴.⭠⒈
+⒈\u200C\uAAEC︒.\u0ACD; ⒈\u200C\uAAEC︒.\u0ACD; [C1, V5, V6]; xn--0ug78o720myr1c.xn--mfc; ; xn--tsh0720cse8b.xn--mfc; [V5, V6] # ⒈ꫬ︒.્
+1.\u200C\uAAEC。.\u0ACD; 1.\u200C\uAAEC..\u0ACD; [C1, V5, X4_2]; 1.xn--0ug7185c..xn--mfc; [C1, V5, A4_2]; 1.xn--sv9a..xn--mfc; [V5, A4_2] # 1.ꫬ..્
+1.xn--sv9a..xn--mfc; 1.\uAAEC..\u0ACD; [V5, X4_2]; 1.xn--sv9a..xn--mfc; [V5, A4_2]; ; # 1.ꫬ..્
+1.xn--0ug7185c..xn--mfc; 1.\u200C\uAAEC..\u0ACD; [C1, V5, X4_2]; 1.xn--0ug7185c..xn--mfc; [C1, V5, A4_2]; ; # 1.ꫬ..્
+xn--tsh0720cse8b.xn--mfc; ⒈\uAAEC︒.\u0ACD; [V5, V6]; xn--tsh0720cse8b.xn--mfc; ; ; # ⒈ꫬ︒.્
+xn--0ug78o720myr1c.xn--mfc; ⒈\u200C\uAAEC︒.\u0ACD; [C1, V5, V6]; xn--0ug78o720myr1c.xn--mfc; ; ; # ⒈ꫬ︒.્
+\u0C46。䰀\u0668𞭅󠅼; \u0C46.䰀\u0668𞭅; [B1, B5, B6, V5, V6]; xn--eqc.xn--hib5476aim6t; ; ; # ె.䰀٨
+xn--eqc.xn--hib5476aim6t; \u0C46.䰀\u0668𞭅; [B1, B5, B6, V5, V6]; xn--eqc.xn--hib5476aim6t; ; ; # ె.䰀٨
+ß\u200D.\u1BF2񄾼; ; [C2, V5, V6]; xn--zca870n.xn--0zf22107b; ; ss.xn--0zf22107b; [V5, V6] # ß.᯲
+SS\u200D.\u1BF2񄾼; ss\u200D.\u1BF2񄾼; [C2, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ss.xn--0zf22107b; [V5, V6] # ss.᯲
+ss\u200D.\u1BF2񄾼; ; [C2, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ss.xn--0zf22107b; [V5, V6] # ss.᯲
+Ss\u200D.\u1BF2񄾼; ss\u200D.\u1BF2񄾼; [C2, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ss.xn--0zf22107b; [V5, V6] # ss.᯲
+ss.xn--0zf22107b; ss.\u1BF2񄾼; [V5, V6]; ss.xn--0zf22107b; ; ; # ss.᯲
+xn--ss-n1t.xn--0zf22107b; ss\u200D.\u1BF2񄾼; [C2, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ; # ss.᯲
+xn--zca870n.xn--0zf22107b; ß\u200D.\u1BF2񄾼; [C2, V5, V6]; xn--zca870n.xn--0zf22107b; ; ; # ß.᯲
+𑓂\u200C≮.≮; ; [V5]; xn--0ugy6glz29a.xn--gdh; ; xn--gdhz656g.xn--gdh; # 𑓂≮.≮
+𑓂\u200C<\u0338.<\u0338; 𑓂\u200C≮.≮; [V5]; xn--0ugy6glz29a.xn--gdh; ; xn--gdhz656g.xn--gdh; # 𑓂≮.≮
+xn--gdhz656g.xn--gdh; 𑓂≮.≮; [V5]; xn--gdhz656g.xn--gdh; ; ; # 𑓂≮.≮
+xn--0ugy6glz29a.xn--gdh; 𑓂\u200C≮.≮; [V5]; xn--0ugy6glz29a.xn--gdh; ; ; # 𑓂≮.≮
+🕼.\uFFA0; 🕼.\uFFA0; [V6]; xn--my8h.xn--cl7c; ; ; # 🕼.
+🕼.\u1160; ; [V6]; xn--my8h.xn--psd; ; ; # 🕼.
+xn--my8h.xn--psd; 🕼.\u1160; [V6]; xn--my8h.xn--psd; ; ; # 🕼.
+xn--my8h.xn--cl7c; 🕼.\uFFA0; [V6]; xn--my8h.xn--cl7c; ; ; # 🕼.
+ᡔ\uFD82。񷘎; ᡔ\u0644\u062D\u0649.񷘎; [B5, B6, V6]; xn--sgb9bq785p.xn--bc31b; ; ; # ᡔلحى.
+ᡔ\u0644\u062D\u0649。񷘎; ᡔ\u0644\u062D\u0649.񷘎; [B5, B6, V6]; xn--sgb9bq785p.xn--bc31b; ; ; # ᡔلحى.
+xn--sgb9bq785p.xn--bc31b; ᡔ\u0644\u062D\u0649.񷘎; [B5, B6, V6]; xn--sgb9bq785p.xn--bc31b; ; ; # ᡔلحى.
+爕򳙑.𝟰気; 爕򳙑.4気; [V6]; xn--1zxq3199c.xn--4-678b; ; ; # 爕.4気
+爕򳙑.4気; ; [V6]; xn--1zxq3199c.xn--4-678b; ; ; # 爕.4気
+xn--1zxq3199c.xn--4-678b; 爕򳙑.4気; [V6]; xn--1zxq3199c.xn--4-678b; ; ; # 爕.4気
+⒋𑍍Ⴝ-.𞬪\u0DCA\u05B5; ⒋𑍍Ⴝ-.𞬪\u0DCA\u05B5; [B1, V3, V6]; xn----t1g323mnk9t.xn--ddb152b7y23b; ; ; # ⒋𑍍Ⴝ-.්ֵ
+4.𑍍Ⴝ-.𞬪\u0DCA\u05B5; ; [B1, B6, V3, V5, V6]; 4.xn----t1g9869q.xn--ddb152b7y23b; ; ; # 4.𑍍Ⴝ-.්ֵ
+4.𑍍ⴝ-.𞬪\u0DCA\u05B5; ; [B1, B6, V3, V5, V6]; 4.xn----wwsx259f.xn--ddb152b7y23b; ; ; # 4.𑍍ⴝ-.්ֵ
+4.xn----wwsx259f.xn--ddb152b7y23b; 4.𑍍ⴝ-.𞬪\u0DCA\u05B5; [B1, B6, V3, V5, V6]; 4.xn----wwsx259f.xn--ddb152b7y23b; ; ; # 4.𑍍ⴝ-.්ֵ
+4.xn----t1g9869q.xn--ddb152b7y23b; 4.𑍍Ⴝ-.𞬪\u0DCA\u05B5; [B1, B6, V3, V5, V6]; 4.xn----t1g9869q.xn--ddb152b7y23b; ; ; # 4.𑍍Ⴝ-.්ֵ
+⒋𑍍ⴝ-.𞬪\u0DCA\u05B5; ⒋𑍍ⴝ-.𞬪\u0DCA\u05B5; [B1, V3, V6]; xn----jcp487avl3w.xn--ddb152b7y23b; ; ; # ⒋𑍍ⴝ-.්ֵ
+xn----jcp487avl3w.xn--ddb152b7y23b; ⒋𑍍ⴝ-.𞬪\u0DCA\u05B5; [B1, V3, V6]; xn----jcp487avl3w.xn--ddb152b7y23b; ; ; # ⒋𑍍ⴝ-.්ֵ
+xn----t1g323mnk9t.xn--ddb152b7y23b; ⒋𑍍Ⴝ-.𞬪\u0DCA\u05B5; [B1, V3, V6]; xn----t1g323mnk9t.xn--ddb152b7y23b; ; ; # ⒋𑍍Ⴝ-.්ֵ
+󞝃。򑆃񉢗--; 󞝃.򑆃񉢗--; [V2, V3, V6]; xn--2y75e.xn-----1l15eer88n; ; ; # .--
+xn--2y75e.xn-----1l15eer88n; 󞝃.򑆃񉢗--; [V2, V3, V6]; xn--2y75e.xn-----1l15eer88n; ; ; # .--
+\u200D\u07DF。\u200C\uABED; \u200D\u07DF.\u200C\uABED; [B1, C1, C2]; xn--6sb394j.xn--0ug1126c; ; xn--6sb.xn--429a; [B1, V5] # ߟ.꯭
+\u200D\u07DF。\u200C\uABED; \u200D\u07DF.\u200C\uABED; [B1, C1, C2]; xn--6sb394j.xn--0ug1126c; ; xn--6sb.xn--429a; [B1, V5] # ߟ.꯭
+xn--6sb.xn--429a; \u07DF.\uABED; [B1, V5]; xn--6sb.xn--429a; ; ; # ߟ.꯭
+xn--6sb394j.xn--0ug1126c; \u200D\u07DF.\u200C\uABED; [B1, C1, C2]; xn--6sb394j.xn--0ug1126c; ; ; # ߟ.꯭
+𞮽\u07FF\u084E。ᢍ򝹁𐫘; 𞮽\u07FF\u084E.ᢍ򝹁𐫘; [B5, B6, V6]; xn--3tb2nz468k.xn--69e8615j5rn5d; ; ; # ߿ࡎ.ᢍ𐫘
+𞮽\u07FF\u084E。ᢍ򝹁𐫘; 𞮽\u07FF\u084E.ᢍ򝹁𐫘; [B5, B6, V6]; xn--3tb2nz468k.xn--69e8615j5rn5d; ; ; # ߿ࡎ.ᢍ𐫘
+xn--3tb2nz468k.xn--69e8615j5rn5d; 𞮽\u07FF\u084E.ᢍ򝹁𐫘; [B5, B6, V6]; xn--3tb2nz468k.xn--69e8615j5rn5d; ; ; # ߿ࡎ.ᢍ𐫘
+\u06ED𞺌𑄚\u1714.ꡞ\u08B7; \u06ED\u0645𑄚\u1714.ꡞ\u08B7; [B1, B5, B6, V5]; xn--hhb94ag41b739u.xn--dzb5582f; ; ; # ۭم𑄚᜔.ꡞࢷ
+\u06ED\u0645𑄚\u1714.ꡞ\u08B7; ; [B1, B5, B6, V5]; xn--hhb94ag41b739u.xn--dzb5582f; ; ; # ۭم𑄚᜔.ꡞࢷ
+xn--hhb94ag41b739u.xn--dzb5582f; \u06ED\u0645𑄚\u1714.ꡞ\u08B7; [B1, B5, B6, V5]; xn--hhb94ag41b739u.xn--dzb5582f; ; ; # ۭم𑄚᜔.ꡞࢷ
+񻂵킃𑘶\u07DC。ς\u063Cς; 񻂵킃𑘶\u07DC.ς\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶\u07DC。ς\u063Cς; 񻂵킃𑘶\u07DC.ς\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶\u07DC。ς\u063Cς; 񻂵킃𑘶\u07DC.ς\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶\u07DC。ς\u063Cς; 񻂵킃𑘶\u07DC.ς\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶\u07DC。Σ\u063CΣ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063CΣ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+xn--3sb7483hoyvbbe76g.xn--4xaa21q; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶\u07DC。Σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶\u07DC。σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶\u07DC。σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+xn--3sb7483hoyvbbe76g.xn--3xab31q; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; ; # 킃𑘶ߜ.σؼς
+xn--3sb7483hoyvbbe76g.xn--3xaa51q; 񻂵킃𑘶\u07DC.ς\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; ; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶\u07DC。Σ\u063CΣ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063CΣ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063Cσ; 񻂵킃𑘶\u07DC.σ\u063Cσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶\u07DC。Σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶\u07DC。Σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶\u07DC。σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶\u07DC。σ\u063Cς; 񻂵킃𑘶\u07DC.σ\u063Cς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+蔰。󠁹\u08DD-𑈵; 蔰.󠁹\u08DD-𑈵; [V6]; xn--sz1a.xn----mrd9984r3dl0i; ; ; # 蔰.ࣝ-𑈵
+xn--sz1a.xn----mrd9984r3dl0i; 蔰.󠁹\u08DD-𑈵; [V6]; xn--sz1a.xn----mrd9984r3dl0i; ; ; # 蔰.ࣝ-𑈵
+ςჅ。\u075A; ςჅ.\u075A; [V6]; xn--3xa677d.xn--epb; ; xn--4xa477d.xn--epb; # ςჅ.ݚ
+ςⴥ。\u075A; ςⴥ.\u075A; ; xn--3xa403s.xn--epb; ; xn--4xa203s.xn--epb; # ςⴥ.ݚ
+ΣჅ。\u075A; σჅ.\u075A; [V6]; xn--4xa477d.xn--epb; ; ; # σჅ.ݚ
+σⴥ。\u075A; σⴥ.\u075A; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+Σⴥ。\u075A; σⴥ.\u075A; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+xn--4xa203s.xn--epb; σⴥ.\u075A; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+σⴥ.\u075A; ; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+ΣჅ.\u075A; σჅ.\u075A; [V6]; xn--4xa477d.xn--epb; ; ; # σჅ.ݚ
+Σⴥ.\u075A; σⴥ.\u075A; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+xn--4xa477d.xn--epb; σჅ.\u075A; [V6]; xn--4xa477d.xn--epb; ; ; # σჅ.ݚ
+xn--3xa403s.xn--epb; ςⴥ.\u075A; ; xn--3xa403s.xn--epb; ; ; # ςⴥ.ݚ
+ςⴥ.\u075A; ; ; xn--3xa403s.xn--epb; ; xn--4xa203s.xn--epb; # ςⴥ.ݚ
+xn--3xa677d.xn--epb; ςჅ.\u075A; [V6]; xn--3xa677d.xn--epb; ; ; # ςჅ.ݚ
+\u0C4DႩ𞰓.\u1B72; \u0C4DႩ𞰓.\u1B72; [B1, V5, V6]; xn--lqc64t7t26c.xn--dwf; ; ; # ్Ⴉ.᭲
+\u0C4DႩ𞰓.\u1B72; ; [B1, V5, V6]; xn--lqc64t7t26c.xn--dwf; ; ; # ్Ⴉ.᭲
+\u0C4Dⴉ𞰓.\u1B72; ; [B1, V5, V6]; xn--lqc478nlr02a.xn--dwf; ; ; # ్ⴉ.᭲
+xn--lqc478nlr02a.xn--dwf; \u0C4Dⴉ𞰓.\u1B72; [B1, V5, V6]; xn--lqc478nlr02a.xn--dwf; ; ; # ్ⴉ.᭲
+xn--lqc64t7t26c.xn--dwf; \u0C4DႩ𞰓.\u1B72; [B1, V5, V6]; xn--lqc64t7t26c.xn--dwf; ; ; # ్Ⴉ.᭲
+\u0C4Dⴉ𞰓.\u1B72; \u0C4Dⴉ𞰓.\u1B72; [B1, V5, V6]; xn--lqc478nlr02a.xn--dwf; ; ; # ్ⴉ.᭲
+⮷≮񎈴󠄟。𐠄; ⮷≮񎈴.𐠄; [B1, V6]; xn--gdh877a3513h.xn--pc9c; ; ; # ⮷≮.𐠄
+⮷<\u0338񎈴󠄟。𐠄; ⮷≮񎈴.𐠄; [B1, V6]; xn--gdh877a3513h.xn--pc9c; ; ; # ⮷≮.𐠄
+xn--gdh877a3513h.xn--pc9c; ⮷≮񎈴.𐠄; [B1, V6]; xn--gdh877a3513h.xn--pc9c; ; ; # ⮷≮.𐠄
+\u06BC。\u200Dẏ\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+\u06BC。\u200Dy\u0307\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+\u06BC。\u200Dẏ\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+\u06BC。\u200Dy\u0307\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+\u06BC。\u200DY\u0307\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+\u06BC。\u200DẎ\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+xn--vkb.xn--08e172a; \u06BC.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+\u06BC.ẏᡤ; ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+\u06BC.y\u0307ᡤ; \u06BC.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+\u06BC.Y\u0307ᡤ; \u06BC.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+\u06BC.Ẏᡤ; \u06BC.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+xn--vkb.xn--08e172ax6aca; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; ; # ڼ.ẏᡤ
+\u06BC。\u200DY\u0307\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+\u06BC。\u200DẎ\u200Cᡤ; \u06BC.\u200Dẏ\u200Cᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+𐹹𑲛。񑂐\u0DCA; 𐹹𑲛.񑂐\u0DCA; [B1, V6]; xn--xo0dg5v.xn--h1c39876d; ; ; # 𐹹𑲛.්
+xn--xo0dg5v.xn--h1c39876d; 𐹹𑲛.񑂐\u0DCA; [B1, V6]; xn--xo0dg5v.xn--h1c39876d; ; ; # 𐹹𑲛.්
+-≠𑈵。嵕\uFEF1۴\uA953; -≠𑈵.嵕\u064A۴\uA953; [B1, B5, V3]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+-=\u0338𑈵。嵕\uFEF1۴\uA953; -≠𑈵.嵕\u064A۴\uA953; [B1, B5, V3]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+-≠𑈵。嵕\u064A۴\uA953; -≠𑈵.嵕\u064A۴\uA953; [B1, B5, V3]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+-=\u0338𑈵。嵕\u064A۴\uA953; -≠𑈵.嵕\u064A۴\uA953; [B1, B5, V3]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+xn----ufo4749h.xn--mhb45a235sns3c; -≠𑈵.嵕\u064A۴\uA953; [B1, B5, V3]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+\u200C񍸰𐹶\u076E.\u06C1\u200D≯\u200D; \u200C񍸰𐹶\u076E.\u06C1\u200D≯\u200D; [B1, B3, C1, C2, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, V6] # 𐹶ݮ.ہ≯
+\u200C񍸰𐹶\u076E.\u06C1\u200D>\u0338\u200D; \u200C񍸰𐹶\u076E.\u06C1\u200D≯\u200D; [B1, B3, C1, C2, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, V6] # 𐹶ݮ.ہ≯
+\u200C񍸰𐹶\u076E.\u06C1\u200D≯\u200D; ; [B1, B3, C1, C2, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, V6] # 𐹶ݮ.ہ≯
+\u200C񍸰𐹶\u076E.\u06C1\u200D>\u0338\u200D; \u200C񍸰𐹶\u076E.\u06C1\u200D≯\u200D; [B1, B3, C1, C2, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, V6] # 𐹶ݮ.ہ≯
+xn--ypb5875khz9y.xn--0kb682l; 񍸰𐹶\u076E.\u06C1≯; [B3, B5, B6, V6]; xn--ypb5875khz9y.xn--0kb682l; ; ; # 𐹶ݮ.ہ≯
+xn--ypb717jrx2o7v94a.xn--0kb660ka35v; \u200C񍸰𐹶\u076E.\u06C1\u200D≯\u200D; [B1, B3, C1, C2, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; ; # 𐹶ݮ.ہ≯
+≮.\u17B5\u0855𐫔; ≮.\u17B5\u0855𐫔; [B1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+<\u0338.\u17B5\u0855𐫔; ≮.\u17B5\u0855𐫔; [B1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+≮.\u17B5\u0855𐫔; ; [B1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+<\u0338.\u17B5\u0855𐫔; ≮.\u17B5\u0855𐫔; [B1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+xn--gdh.xn--kwb589e217p; ≮.\u17B5\u0855𐫔; [B1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+𐩗\u200D。ႩႵ; 𐩗\u200D.ႩႵ; [B3, C2, V6]; xn--1ug4933g.xn--hndy; ; xn--pt9c.xn--hndy; [V6] # 𐩗.ႩႵ
+𐩗\u200D。ႩႵ; 𐩗\u200D.ႩႵ; [B3, C2, V6]; xn--1ug4933g.xn--hndy; ; xn--pt9c.xn--hndy; [V6] # 𐩗.ႩႵ
+𐩗\u200D。ⴉⴕ; 𐩗\u200D.ⴉⴕ; [B3, C2]; xn--1ug4933g.xn--0kjya; ; xn--pt9c.xn--0kjya; [] # 𐩗.ⴉⴕ
+𐩗\u200D。Ⴉⴕ; 𐩗\u200D.Ⴉⴕ; [B3, C2, V6]; xn--1ug4933g.xn--hnd666l; ; xn--pt9c.xn--hnd666l; [V6] # 𐩗.Ⴉⴕ
+xn--pt9c.xn--hnd666l; 𐩗.Ⴉⴕ; [V6]; xn--pt9c.xn--hnd666l; ; ; # 𐩗.Ⴉⴕ
+xn--1ug4933g.xn--hnd666l; 𐩗\u200D.Ⴉⴕ; [B3, C2, V6]; xn--1ug4933g.xn--hnd666l; ; ; # 𐩗.Ⴉⴕ
+xn--pt9c.xn--0kjya; 𐩗.ⴉⴕ; ; xn--pt9c.xn--0kjya; ; ; # 𐩗.ⴉⴕ
+𐩗.ⴉⴕ; ; ; xn--pt9c.xn--0kjya; ; ; # 𐩗.ⴉⴕ
+𐩗.ႩႵ; ; [V6]; xn--pt9c.xn--hndy; ; ; # 𐩗.ႩႵ
+𐩗.Ⴉⴕ; ; [V6]; xn--pt9c.xn--hnd666l; ; ; # 𐩗.Ⴉⴕ
+xn--pt9c.xn--hndy; 𐩗.ႩႵ; [V6]; xn--pt9c.xn--hndy; ; ; # 𐩗.ႩႵ
+xn--1ug4933g.xn--0kjya; 𐩗\u200D.ⴉⴕ; [B3, C2]; xn--1ug4933g.xn--0kjya; ; ; # 𐩗.ⴉⴕ
+xn--1ug4933g.xn--hndy; 𐩗\u200D.ႩႵ; [B3, C2, V6]; xn--1ug4933g.xn--hndy; ; ; # 𐩗.ႩႵ
+𐩗\u200D。ⴉⴕ; 𐩗\u200D.ⴉⴕ; [B3, C2]; xn--1ug4933g.xn--0kjya; ; xn--pt9c.xn--0kjya; [] # 𐩗.ⴉⴕ
+𐩗\u200D。Ⴉⴕ; 𐩗\u200D.Ⴉⴕ; [B3, C2, V6]; xn--1ug4933g.xn--hnd666l; ; xn--pt9c.xn--hnd666l; [V6] # 𐩗.Ⴉⴕ
+\u200C\u200Cㄤ.\u032E󕨑\u09C2; \u200C\u200Cㄤ.\u032E󕨑\u09C2; [C1, V5, V6]; xn--0uga242k.xn--vta284a9o563a; ; xn--1fk.xn--vta284a9o563a; [V5, V6] # ㄤ.̮ূ
+\u200C\u200Cㄤ.\u032E󕨑\u09C2; ; [C1, V5, V6]; xn--0uga242k.xn--vta284a9o563a; ; xn--1fk.xn--vta284a9o563a; [V5, V6] # ㄤ.̮ূ
+xn--1fk.xn--vta284a9o563a; ㄤ.\u032E󕨑\u09C2; [V5, V6]; xn--1fk.xn--vta284a9o563a; ; ; # ㄤ.̮ূ
+xn--0uga242k.xn--vta284a9o563a; \u200C\u200Cㄤ.\u032E󕨑\u09C2; [C1, V5, V6]; xn--0uga242k.xn--vta284a9o563a; ; ; # ㄤ.̮ূ
+𐋻。-\u200C𐫄Ⴗ; 𐋻.-\u200C𐫄Ⴗ; [B1, C1, V3, V6]; xn--v97c.xn----i1g888ih12u; ; xn--v97c.xn----i1g2513q; [B1, V3, V6] # 𐋻.-𐫄Ⴗ
+𐋻。-\u200C𐫄Ⴗ; 𐋻.-\u200C𐫄Ⴗ; [B1, C1, V3, V6]; xn--v97c.xn----i1g888ih12u; ; xn--v97c.xn----i1g2513q; [B1, V3, V6] # 𐋻.-𐫄Ⴗ
+𐋻。-\u200C𐫄ⴗ; 𐋻.-\u200C𐫄ⴗ; [B1, C1, V3]; xn--v97c.xn----sgnv20du99s; ; xn--v97c.xn----lws0526f; [B1, V3] # 𐋻.-𐫄ⴗ
+xn--v97c.xn----lws0526f; 𐋻.-𐫄ⴗ; [B1, V3]; xn--v97c.xn----lws0526f; ; ; # 𐋻.-𐫄ⴗ
+xn--v97c.xn----sgnv20du99s; 𐋻.-\u200C𐫄ⴗ; [B1, C1, V3]; xn--v97c.xn----sgnv20du99s; ; ; # 𐋻.-𐫄ⴗ
+xn--v97c.xn----i1g2513q; 𐋻.-𐫄Ⴗ; [B1, V3, V6]; xn--v97c.xn----i1g2513q; ; ; # 𐋻.-𐫄Ⴗ
+xn--v97c.xn----i1g888ih12u; 𐋻.-\u200C𐫄Ⴗ; [B1, C1, V3, V6]; xn--v97c.xn----i1g888ih12u; ; ; # 𐋻.-𐫄Ⴗ
+𐋻。-\u200C𐫄ⴗ; 𐋻.-\u200C𐫄ⴗ; [B1, C1, V3]; xn--v97c.xn----sgnv20du99s; ; xn--v97c.xn----lws0526f; [B1, V3] # 𐋻.-𐫄ⴗ
+🙑𐷺.≠\u200C; 🙑𐷺.≠\u200C; [B1, C1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, V6] # 🙑.≠
+🙑𐷺.=\u0338\u200C; 🙑𐷺.≠\u200C; [B1, C1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, V6] # 🙑.≠
+🙑𐷺.≠\u200C; ; [B1, C1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, V6] # 🙑.≠
+🙑𐷺.=\u0338\u200C; 🙑𐷺.≠\u200C; [B1, C1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, V6] # 🙑.≠
+xn--bl0dh970b.xn--1ch; 🙑𐷺.≠; [B1, V6]; xn--bl0dh970b.xn--1ch; ; ; # 🙑.≠
+xn--bl0dh970b.xn--0ug83g; 🙑𐷺.≠\u200C; [B1, C1, V6]; xn--bl0dh970b.xn--0ug83g; ; ; # 🙑.≠
+\u064C\u1CD2。𞮞\u2D7F⧎; \u064C\u1CD2.𞮞\u2D7F⧎; [B1, B3, V5, V6]; xn--ohb646i.xn--ewi38jf765c; ; ; # ٌ᳒.⵿⧎
+\u064C\u1CD2。𞮞\u2D7F⧎; \u064C\u1CD2.𞮞\u2D7F⧎; [B1, B3, V5, V6]; xn--ohb646i.xn--ewi38jf765c; ; ; # ٌ᳒.⵿⧎
+xn--ohb646i.xn--ewi38jf765c; \u064C\u1CD2.𞮞\u2D7F⧎; [B1, B3, V5, V6]; xn--ohb646i.xn--ewi38jf765c; ; ; # ٌ᳒.⵿⧎
+Ⴔ𝨨₃󠁦.𝟳𑂹\u0B82; Ⴔ𝨨3󠁦.7𑂹\u0B82; [V6]; xn--3-b1g83426a35t0g.xn--7-cve6271r; ; ; # Ⴔ𝨨3.7𑂹ஂ
+Ⴔ𝨨3󠁦.7𑂹\u0B82; ; [V6]; xn--3-b1g83426a35t0g.xn--7-cve6271r; ; ; # Ⴔ𝨨3.7𑂹ஂ
+ⴔ𝨨3󠁦.7𑂹\u0B82; ; [V6]; xn--3-ews6985n35s3g.xn--7-cve6271r; ; ; # ⴔ𝨨3.7𑂹ஂ
+xn--3-ews6985n35s3g.xn--7-cve6271r; ⴔ𝨨3󠁦.7𑂹\u0B82; [V6]; xn--3-ews6985n35s3g.xn--7-cve6271r; ; ; # ⴔ𝨨3.7𑂹ஂ
+xn--3-b1g83426a35t0g.xn--7-cve6271r; Ⴔ𝨨3󠁦.7𑂹\u0B82; [V6]; xn--3-b1g83426a35t0g.xn--7-cve6271r; ; ; # Ⴔ𝨨3.7𑂹ஂ
+ⴔ𝨨₃󠁦.𝟳𑂹\u0B82; ⴔ𝨨3󠁦.7𑂹\u0B82; [V6]; xn--3-ews6985n35s3g.xn--7-cve6271r; ; ; # ⴔ𝨨3.7𑂹ஂ
+䏈\u200C。\u200C⒈񱢕; 䏈\u200C.\u200C⒈񱢕; [C1, V6]; xn--0ug491l.xn--0ug88oot66q; ; xn--eco.xn--tsh21126d; [V6] # 䏈.⒈
+䏈\u200C。\u200C1.񱢕; 䏈\u200C.\u200C1.񱢕; [C1, V6]; xn--0ug491l.xn--1-rgn.xn--ms39a; ; xn--eco.1.xn--ms39a; [V6] # 䏈.1.
+xn--eco.1.xn--ms39a; 䏈.1.񱢕; [V6]; xn--eco.1.xn--ms39a; ; ; # 䏈.1.
+xn--0ug491l.xn--1-rgn.xn--ms39a; 䏈\u200C.\u200C1.񱢕; [C1, V6]; xn--0ug491l.xn--1-rgn.xn--ms39a; ; ; # 䏈.1.
+xn--eco.xn--tsh21126d; 䏈.⒈񱢕; [V6]; xn--eco.xn--tsh21126d; ; ; # 䏈.⒈
+xn--0ug491l.xn--0ug88oot66q; 䏈\u200C.\u200C⒈񱢕; [C1, V6]; xn--0ug491l.xn--0ug88oot66q; ; ; # 䏈.⒈
+1\uAAF6ß𑲥。\u1DD8; 1\uAAF6ß𑲥.\u1DD8; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; xn--1ss-ir6ln166b.xn--weg; # 1꫶ß𑲥.ᷘ
+1\uAAF6ß𑲥。\u1DD8; 1\uAAF6ß𑲥.\u1DD8; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; xn--1ss-ir6ln166b.xn--weg; # 1꫶ß𑲥.ᷘ
+1\uAAF6SS𑲥。\u1DD8; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1\uAAF6ss𑲥。\u1DD8; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+xn--1ss-ir6ln166b.xn--weg; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+xn--1-qfa2471kdb0d.xn--weg; 1\uAAF6ß𑲥.\u1DD8; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; ; # 1꫶ß𑲥.ᷘ
+1\uAAF6SS𑲥。\u1DD8; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1\uAAF6ss𑲥。\u1DD8; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1\uAAF6Ss𑲥。\u1DD8; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1\uAAF6Ss𑲥。\u1DD8; 1\uAAF6ss𑲥.\u1DD8; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+\u200D񫶩𞪯\u0CCD。\u077C⒈; \u200D񫶩𞪯\u0CCD.\u077C⒈; [B1, C2, V6]; xn--8tc969gzn94a4lm8a.xn--dqb689l; ; xn--8tc9875v5is1a.xn--dqb689l; [B5, B6, V6] # ್.ݼ⒈
+\u200D񫶩𞪯\u0CCD。\u077C1.; \u200D񫶩𞪯\u0CCD.\u077C1.; [B1, C2, V6]; xn--8tc969gzn94a4lm8a.xn--1-g6c.; ; xn--8tc9875v5is1a.xn--1-g6c.; [B5, B6, V6] # ್.ݼ1.
+xn--8tc9875v5is1a.xn--1-g6c.; 񫶩𞪯\u0CCD.\u077C1.; [B5, B6, V6]; xn--8tc9875v5is1a.xn--1-g6c.; ; ; # ್.ݼ1.
+xn--8tc969gzn94a4lm8a.xn--1-g6c.; \u200D񫶩𞪯\u0CCD.\u077C1.; [B1, C2, V6]; xn--8tc969gzn94a4lm8a.xn--1-g6c.; ; ; # ್.ݼ1.
+xn--8tc9875v5is1a.xn--dqb689l; 񫶩𞪯\u0CCD.\u077C⒈; [B5, B6, V6]; xn--8tc9875v5is1a.xn--dqb689l; ; ; # ್.ݼ⒈
+xn--8tc969gzn94a4lm8a.xn--dqb689l; \u200D񫶩𞪯\u0CCD.\u077C⒈; [B1, C2, V6]; xn--8tc969gzn94a4lm8a.xn--dqb689l; ; ; # ್.ݼ⒈
+\u1AB6.𞤳򓢖򻉒\u07D7; \u1AB6.𞤳򓢖򻉒\u07D7; [B1, B2, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+\u1AB6.𞤳򓢖򻉒\u07D7; ; [B1, B2, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+\u1AB6.𞤑򓢖򻉒\u07D7; \u1AB6.𞤳򓢖򻉒\u07D7; [B1, B2, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+xn--zqf.xn--ysb9657vuiz5bj0ep; \u1AB6.𞤳򓢖򻉒\u07D7; [B1, B2, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+\u1AB6.𞤑򓢖򻉒\u07D7; \u1AB6.𞤳򓢖򻉒\u07D7; [B1, B2, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+\u0842𞩚⒈.󠬌8򏳏\u0770; \u0842𞩚⒈.󠬌8򏳏\u0770; [B1, V6]; xn--0vb095ldg52a.xn--8-s5c22427ox454a; ; ; # ࡂ⒈.8ݰ
+\u0842𞩚1..󠬌8򏳏\u0770; ; [B1, V6, X4_2]; xn--1-rid26318a..xn--8-s5c22427ox454a; [B1, V6, A4_2]; ; # ࡂ1..8ݰ
+xn--1-rid26318a..xn--8-s5c22427ox454a; \u0842𞩚1..󠬌8򏳏\u0770; [B1, V6, X4_2]; xn--1-rid26318a..xn--8-s5c22427ox454a; [B1, V6, A4_2]; ; # ࡂ1..8ݰ
+xn--0vb095ldg52a.xn--8-s5c22427ox454a; \u0842𞩚⒈.󠬌8򏳏\u0770; [B1, V6]; xn--0vb095ldg52a.xn--8-s5c22427ox454a; ; ; # ࡂ⒈.8ݰ
+\u0361𐫫\u0369ᡷ。-󠰛鞰; \u0361𐫫\u0369ᡷ.-󠰛鞰; [B1, V3, V5, V6]; xn--cvaq482npv5t.xn----yg7dt1332g; ; ; # ͡𐫫ͩᡷ.-鞰
+xn--cvaq482npv5t.xn----yg7dt1332g; \u0361𐫫\u0369ᡷ.-󠰛鞰; [B1, V3, V5, V6]; xn--cvaq482npv5t.xn----yg7dt1332g; ; ; # ͡𐫫ͩᡷ.-鞰
+-.\u0ACD剘ß𐫃; ; [B1, V3, V5]; -.xn--zca791c493duf8i; ; -.xn--ss-bqg4734erywk; # -.્剘ß𐫃
+-.\u0ACD剘SS𐫃; -.\u0ACD剘ss𐫃; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.\u0ACD剘ss𐫃; ; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.\u0ACD剘Ss𐫃; -.\u0ACD剘ss𐫃; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.xn--ss-bqg4734erywk; -.\u0ACD剘ss𐫃; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.xn--zca791c493duf8i; -.\u0ACD剘ß𐫃; [B1, V3, V5]; -.xn--zca791c493duf8i; ; ; # -.્剘ß𐫃
+\u08FB𞵸。-; \u08FB𞵸.-; [B1, V3, V5, V6]; xn--b1b2719v.-; ; ; # ࣻ.-
+\u08FB𞵸。-; \u08FB𞵸.-; [B1, V3, V5, V6]; xn--b1b2719v.-; ; ; # ࣻ.-
+xn--b1b2719v.-; \u08FB𞵸.-; [B1, V3, V5, V6]; xn--b1b2719v.-; ; ; # ࣻ.-
+⒈󠈻𐹲。≠\u0603𐹽; ⒈󠈻𐹲.≠\u0603𐹽; [B1, V6]; xn--tshw766f1153g.xn--lfb536lb35n; ; ; # ⒈𐹲.≠𐹽
+⒈󠈻𐹲。=\u0338\u0603𐹽; ⒈󠈻𐹲.≠\u0603𐹽; [B1, V6]; xn--tshw766f1153g.xn--lfb536lb35n; ; ; # ⒈𐹲.≠𐹽
+1.󠈻𐹲。≠\u0603𐹽; 1.󠈻𐹲.≠\u0603𐹽; [B1, V6]; 1.xn--qo0dl3077c.xn--lfb536lb35n; ; ; # 1.𐹲.≠𐹽
+1.󠈻𐹲。=\u0338\u0603𐹽; 1.󠈻𐹲.≠\u0603𐹽; [B1, V6]; 1.xn--qo0dl3077c.xn--lfb536lb35n; ; ; # 1.𐹲.≠𐹽
+1.xn--qo0dl3077c.xn--lfb536lb35n; 1.󠈻𐹲.≠\u0603𐹽; [B1, V6]; 1.xn--qo0dl3077c.xn--lfb536lb35n; ; ; # 1.𐹲.≠𐹽
+xn--tshw766f1153g.xn--lfb536lb35n; ⒈󠈻𐹲.≠\u0603𐹽; [B1, V6]; xn--tshw766f1153g.xn--lfb536lb35n; ; ; # ⒈𐹲.≠𐹽
+𐹢󠈚Ⴎ\u200C.㖾𐹡; ; [B1, B5, B6, C1, V6]; xn--mnd289ezj4pqxp0i.xn--pelu572d; ; xn--mnd9001km0o0g.xn--pelu572d; [B1, B5, B6, V6] # 𐹢Ⴎ.㖾𐹡
+𐹢󠈚ⴎ\u200C.㖾𐹡; ; [B1, B5, B6, C1, V6]; xn--0ug342clq0pqxv4i.xn--pelu572d; ; xn--5kjx323em053g.xn--pelu572d; [B1, B5, B6, V6] # 𐹢ⴎ.㖾𐹡
+xn--5kjx323em053g.xn--pelu572d; 𐹢󠈚ⴎ.㖾𐹡; [B1, B5, B6, V6]; xn--5kjx323em053g.xn--pelu572d; ; ; # 𐹢ⴎ.㖾𐹡
+xn--0ug342clq0pqxv4i.xn--pelu572d; 𐹢󠈚ⴎ\u200C.㖾𐹡; [B1, B5, B6, C1, V6]; xn--0ug342clq0pqxv4i.xn--pelu572d; ; ; # 𐹢ⴎ.㖾𐹡
+xn--mnd9001km0o0g.xn--pelu572d; 𐹢󠈚Ⴎ.㖾𐹡; [B1, B5, B6, V6]; xn--mnd9001km0o0g.xn--pelu572d; ; ; # 𐹢Ⴎ.㖾𐹡
+xn--mnd289ezj4pqxp0i.xn--pelu572d; 𐹢󠈚Ⴎ\u200C.㖾𐹡; [B1, B5, B6, C1, V6]; xn--mnd289ezj4pqxp0i.xn--pelu572d; ; ; # 𐹢Ⴎ.㖾𐹡
+򩼗.\u07C7ᡖႳႧ; 򩼗.\u07C7ᡖႳႧ; [B2, B3, V6]; xn--te28c.xn--isb856b9a631d; ; ; # .߇ᡖႳႧ
+򩼗.\u07C7ᡖႳႧ; ; [B2, B3, V6]; xn--te28c.xn--isb856b9a631d; ; ; # .߇ᡖႳႧ
+򩼗.\u07C7ᡖⴓⴇ; ; [B2, B3, V6]; xn--te28c.xn--isb295fbtpmb; ; ; # .߇ᡖⴓⴇ
+xn--te28c.xn--isb295fbtpmb; 򩼗.\u07C7ᡖⴓⴇ; [B2, B3, V6]; xn--te28c.xn--isb295fbtpmb; ; ; # .߇ᡖⴓⴇ
+xn--te28c.xn--isb856b9a631d; 򩼗.\u07C7ᡖႳႧ; [B2, B3, V6]; xn--te28c.xn--isb856b9a631d; ; ; # .߇ᡖႳႧ
+򩼗.\u07C7ᡖⴓⴇ; 򩼗.\u07C7ᡖⴓⴇ; [B2, B3, V6]; xn--te28c.xn--isb295fbtpmb; ; ; # .߇ᡖⴓⴇ
+򩼗.\u07C7ᡖႳⴇ; ; [B2, B3, V6]; xn--te28c.xn--isb286btrgo7w; ; ; # .߇ᡖႳⴇ
+xn--te28c.xn--isb286btrgo7w; 򩼗.\u07C7ᡖႳⴇ; [B2, B3, V6]; xn--te28c.xn--isb286btrgo7w; ; ; # .߇ᡖႳⴇ
+򩼗.\u07C7ᡖႳⴇ; 򩼗.\u07C7ᡖႳⴇ; [B2, B3, V6]; xn--te28c.xn--isb286btrgo7w; ; ; # .߇ᡖႳⴇ
+\u200D􅍉.\u06B3\u0775; ; [B1, C2, V6]; xn--1ug39444n.xn--mkb20b; ; xn--3j78f.xn--mkb20b; [V6] # .ڳݵ
+xn--3j78f.xn--mkb20b; 􅍉.\u06B3\u0775; [V6]; xn--3j78f.xn--mkb20b; ; ; # .ڳݵ
+xn--1ug39444n.xn--mkb20b; \u200D􅍉.\u06B3\u0775; [B1, C2, V6]; xn--1ug39444n.xn--mkb20b; ; ; # .ڳݵ
+𲤱⒛⾳.ꡦ⒈; 𲤱⒛音.ꡦ⒈; [V6]; xn--dth6033bzbvx.xn--tsh9439b; ; ; # ⒛音.ꡦ⒈
+𲤱20.音.ꡦ1.; ; [V6]; xn--20-9802c.xn--0w5a.xn--1-eg4e.; ; ; # 20.音.ꡦ1.
+xn--20-9802c.xn--0w5a.xn--1-eg4e.; 𲤱20.音.ꡦ1.; [V6]; xn--20-9802c.xn--0w5a.xn--1-eg4e.; ; ; # 20.音.ꡦ1.
+xn--dth6033bzbvx.xn--tsh9439b; 𲤱⒛音.ꡦ⒈; [V6]; xn--dth6033bzbvx.xn--tsh9439b; ; ; # ⒛音.ꡦ⒈
+\u07DC8񳦓-。򞲙𑁿𐩥\u09CD; \u07DC8񳦓-.򞲙𑁿𐩥\u09CD; [B2, B3, B5, B6, V3, V6]; xn--8--rve13079p.xn--b7b9842k42df776x; ; ; # ߜ8-.𑁿𐩥্
+\u07DC8񳦓-。򞲙𑁿𐩥\u09CD; \u07DC8񳦓-.򞲙𑁿𐩥\u09CD; [B2, B3, B5, B6, V3, V6]; xn--8--rve13079p.xn--b7b9842k42df776x; ; ; # ߜ8-.𑁿𐩥্
+xn--8--rve13079p.xn--b7b9842k42df776x; \u07DC8񳦓-.򞲙𑁿𐩥\u09CD; [B2, B3, B5, B6, V3, V6]; xn--8--rve13079p.xn--b7b9842k42df776x; ; ; # ߜ8-.𑁿𐩥্
+Ⴕ。۰≮ß\u0745; Ⴕ.۰≮ß\u0745; [V6]; xn--tnd.xn--zca912alh227g; ; xn--tnd.xn--ss-jbe65aw27i; # Ⴕ.۰≮ß݅
+Ⴕ。۰<\u0338ß\u0745; Ⴕ.۰≮ß\u0745; [V6]; xn--tnd.xn--zca912alh227g; ; xn--tnd.xn--ss-jbe65aw27i; # Ⴕ.۰≮ß݅
+ⴕ。۰<\u0338ß\u0745; ⴕ.۰≮ß\u0745; ; xn--dlj.xn--zca912alh227g; ; xn--dlj.xn--ss-jbe65aw27i; # ⴕ.۰≮ß݅
+ⴕ。۰≮ß\u0745; ⴕ.۰≮ß\u0745; ; xn--dlj.xn--zca912alh227g; ; xn--dlj.xn--ss-jbe65aw27i; # ⴕ.۰≮ß݅
+Ⴕ。۰≮SS\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ。۰<\u0338SS\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+ⴕ。۰<\u0338ss\u0745; ⴕ.۰≮ss\u0745; ; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+ⴕ。۰≮ss\u0745; ⴕ.۰≮ss\u0745; ; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+Ⴕ。۰≮Ss\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ。۰<\u0338Ss\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+xn--tnd.xn--ss-jbe65aw27i; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+xn--dlj.xn--ss-jbe65aw27i; ⴕ.۰≮ss\u0745; ; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+ⴕ.۰≮ss\u0745; ; ; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+ⴕ.۰<\u0338ss\u0745; ⴕ.۰≮ss\u0745; ; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+Ⴕ.۰<\u0338SS\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ.۰≮SS\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ.۰≮Ss\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ.۰<\u0338Ss\u0745; Ⴕ.۰≮ss\u0745; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+xn--dlj.xn--zca912alh227g; ⴕ.۰≮ß\u0745; ; xn--dlj.xn--zca912alh227g; ; ; # ⴕ.۰≮ß݅
+ⴕ.۰≮ß\u0745; ; ; xn--dlj.xn--zca912alh227g; ; xn--dlj.xn--ss-jbe65aw27i; # ⴕ.۰≮ß݅
+ⴕ.۰<\u0338ß\u0745; ⴕ.۰≮ß\u0745; ; xn--dlj.xn--zca912alh227g; ; xn--dlj.xn--ss-jbe65aw27i; # ⴕ.۰≮ß݅
+xn--tnd.xn--zca912alh227g; Ⴕ.۰≮ß\u0745; [V6]; xn--tnd.xn--zca912alh227g; ; ; # Ⴕ.۰≮ß݅
+\u07E9-.𝨗꒱\u1B72; ; [B1, B3, V3, V5]; xn----odd.xn--dwf8994dc8wj; ; ; # ߩ-.𝨗꒱᭲
+xn----odd.xn--dwf8994dc8wj; \u07E9-.𝨗꒱\u1B72; [B1, B3, V3, V5]; xn----odd.xn--dwf8994dc8wj; ; ; # ߩ-.𝨗꒱᭲
+𞼸\u200C.≯䕵⫧; ; [B1, B3, C1, V6]; xn--0ugx453p.xn--hdh754ax6w; ; xn--sn7h.xn--hdh754ax6w; [B1, V6] # .≯䕵⫧
+𞼸\u200C.>\u0338䕵⫧; 𞼸\u200C.≯䕵⫧; [B1, B3, C1, V6]; xn--0ugx453p.xn--hdh754ax6w; ; xn--sn7h.xn--hdh754ax6w; [B1, V6] # .≯䕵⫧
+xn--sn7h.xn--hdh754ax6w; 𞼸.≯䕵⫧; [B1, V6]; xn--sn7h.xn--hdh754ax6w; ; ; # .≯䕵⫧
+xn--0ugx453p.xn--hdh754ax6w; 𞼸\u200C.≯䕵⫧; [B1, B3, C1, V6]; xn--0ugx453p.xn--hdh754ax6w; ; ; # .≯䕵⫧
+𐨅ß\uFC57.\u06AC۳︒; 𐨅ß\u064A\u062E.\u06AC۳︒; [B1, B3, V5, V6]; xn--zca23yncs877j.xn--fkb6lp314e; ; xn--ss-ytd5i7765l.xn--fkb6lp314e; # 𐨅ßيخ.ڬ۳︒
+𐨅ß\u064A\u062E.\u06AC۳。; 𐨅ß\u064A\u062E.\u06AC۳.; [B1, V5]; xn--zca23yncs877j.xn--fkb6l.; ; xn--ss-ytd5i7765l.xn--fkb6l.; # 𐨅ßيخ.ڬ۳.
+𐨅SS\u064A\u062E.\u06AC۳。; 𐨅ss\u064A\u062E.\u06AC۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+𐨅ss\u064A\u062E.\u06AC۳。; 𐨅ss\u064A\u062E.\u06AC۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+𐨅Ss\u064A\u062E.\u06AC۳。; 𐨅ss\u064A\u062E.\u06AC۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+xn--ss-ytd5i7765l.xn--fkb6l.; 𐨅ss\u064A\u062E.\u06AC۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+xn--zca23yncs877j.xn--fkb6l.; 𐨅ß\u064A\u062E.\u06AC۳.; [B1, V5]; xn--zca23yncs877j.xn--fkb6l.; ; ; # 𐨅ßيخ.ڬ۳.
+𐨅SS\uFC57.\u06AC۳︒; 𐨅ss\u064A\u062E.\u06AC۳︒; [B1, B3, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+𐨅ss\uFC57.\u06AC۳︒; 𐨅ss\u064A\u062E.\u06AC۳︒; [B1, B3, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+𐨅Ss\uFC57.\u06AC۳︒; 𐨅ss\u064A\u062E.\u06AC۳︒; [B1, B3, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+xn--ss-ytd5i7765l.xn--fkb6lp314e; 𐨅ss\u064A\u062E.\u06AC۳︒; [B1, B3, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+xn--zca23yncs877j.xn--fkb6lp314e; 𐨅ß\u064A\u062E.\u06AC۳︒; [B1, B3, V5, V6]; xn--zca23yncs877j.xn--fkb6lp314e; ; ; # 𐨅ßيخ.ڬ۳︒
+-≮🡒\u1CED.񏿾Ⴁ\u0714; ; [B1, V3, V6]; xn----44l04zxt68c.xn--enb300c1597h; ; ; # -≮🡒᳭.Ⴁܔ
+-<\u0338🡒\u1CED.񏿾Ⴁ\u0714; -≮🡒\u1CED.񏿾Ⴁ\u0714; [B1, V3, V6]; xn----44l04zxt68c.xn--enb300c1597h; ; ; # -≮🡒᳭.Ⴁܔ
+-<\u0338🡒\u1CED.񏿾ⴁ\u0714; -≮🡒\u1CED.񏿾ⴁ\u0714; [B1, V3, V6]; xn----44l04zxt68c.xn--enb135qf106f; ; ; # -≮🡒᳭.ⴁܔ
+-≮🡒\u1CED.񏿾ⴁ\u0714; ; [B1, V3, V6]; xn----44l04zxt68c.xn--enb135qf106f; ; ; # -≮🡒᳭.ⴁܔ
+xn----44l04zxt68c.xn--enb135qf106f; -≮🡒\u1CED.񏿾ⴁ\u0714; [B1, V3, V6]; xn----44l04zxt68c.xn--enb135qf106f; ; ; # -≮🡒᳭.ⴁܔ
+xn----44l04zxt68c.xn--enb300c1597h; -≮🡒\u1CED.񏿾Ⴁ\u0714; [B1, V3, V6]; xn----44l04zxt68c.xn--enb300c1597h; ; ; # -≮🡒᳭.Ⴁܔ
+𞤨。ꡏ\u200D\u200C; 𞤨.ꡏ\u200D\u200C; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+𞤨。ꡏ\u200D\u200C; 𞤨.ꡏ\u200D\u200C; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+𞤆。ꡏ\u200D\u200C; 𞤨.ꡏ\u200D\u200C; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+xn--ge6h.xn--oc9a; 𞤨.ꡏ; ; xn--ge6h.xn--oc9a; ; ; # 𞤨.ꡏ
+𞤨.ꡏ; ; ; xn--ge6h.xn--oc9a; ; ; # 𞤨.ꡏ
+𞤆.ꡏ; 𞤨.ꡏ; ; xn--ge6h.xn--oc9a; ; ; # 𞤨.ꡏ
+xn--ge6h.xn--0ugb9575h; 𞤨.ꡏ\u200D\u200C; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; ; # 𞤨.ꡏ
+𞤆。ꡏ\u200D\u200C; 𞤨.ꡏ\u200D\u200C; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+󠅹𑂶.ᢌ𑂹\u0669; 𑂶.ᢌ𑂹\u0669; [B1, B5, B6, V5]; xn--b50d.xn--iib993gyp5p; ; ; # 𑂶.ᢌ𑂹٩
+󠅹𑂶.ᢌ𑂹\u0669; 𑂶.ᢌ𑂹\u0669; [B1, B5, B6, V5]; xn--b50d.xn--iib993gyp5p; ; ; # 𑂶.ᢌ𑂹٩
+xn--b50d.xn--iib993gyp5p; 𑂶.ᢌ𑂹\u0669; [B1, B5, B6, V5]; xn--b50d.xn--iib993gyp5p; ; ; # 𑂶.ᢌ𑂹٩
+Ⅎ󠅺񝵒。≯⾑; Ⅎ񝵒.≯襾; [V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+Ⅎ󠅺񝵒。>\u0338⾑; Ⅎ񝵒.≯襾; [V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+Ⅎ󠅺񝵒。≯襾; Ⅎ񝵒.≯襾; [V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+Ⅎ󠅺񝵒。>\u0338襾; Ⅎ񝵒.≯襾; [V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+ⅎ󠅺񝵒。>\u0338襾; ⅎ񝵒.≯襾; [V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+ⅎ󠅺񝵒。≯襾; ⅎ񝵒.≯襾; [V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+xn--73g39298c.xn--hdhz171b; ⅎ񝵒.≯襾; [V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+xn--f3g73398c.xn--hdhz171b; Ⅎ񝵒.≯襾; [V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+ⅎ󠅺񝵒。>\u0338⾑; ⅎ񝵒.≯襾; [V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+ⅎ󠅺񝵒。≯⾑; ⅎ񝵒.≯襾; [V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+ς\u200D\u0DD4\u0660。-; ς\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--3xa45ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # ςු٠.-
+ς\u200D\u0DD4\u0660。-; ς\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--3xa45ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # ςු٠.-
+Σ\u200D\u0DD4\u0660。-; σ\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+σ\u200D\u0DD4\u0660。-; σ\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+xn--4xa25ks2j.-; σ\u0DD4\u0660.-; [B1, B5, B6, V3]; xn--4xa25ks2j.-; ; ; # σු٠.-
+xn--4xa25ks2jenu.-; σ\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; ; # σු٠.-
+xn--3xa45ks2jenu.-; ς\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--3xa45ks2jenu.-; ; ; # ςු٠.-
+Σ\u200D\u0DD4\u0660。-; σ\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+σ\u200D\u0DD4\u0660。-; σ\u200D\u0DD4\u0660.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+\u200C.ßႩ-; ; [C1, V3, V6]; xn--0ug.xn----pfa042j; ; .xn--ss--4rn; [V3, V6, A4_2] # .ßႩ-
+\u200C.ßⴉ-; ; [C1, V3]; xn--0ug.xn----pfa2305a; ; .xn--ss--bi1b; [V3, A4_2] # .ßⴉ-
+\u200C.SSႩ-; \u200C.ssႩ-; [C1, V3, V6]; xn--0ug.xn--ss--4rn; ; .xn--ss--4rn; [V3, V6, A4_2] # .ssႩ-
+\u200C.ssⴉ-; ; [C1, V3]; xn--0ug.xn--ss--bi1b; ; .xn--ss--bi1b; [V3, A4_2] # .ssⴉ-
+\u200C.Ssⴉ-; \u200C.ssⴉ-; [C1, V3]; xn--0ug.xn--ss--bi1b; ; .xn--ss--bi1b; [V3, A4_2] # .ssⴉ-
+.xn--ss--bi1b; .ssⴉ-; [V3, X4_2]; .xn--ss--bi1b; [V3, A4_2]; ; # .ssⴉ-
+xn--0ug.xn--ss--bi1b; \u200C.ssⴉ-; [C1, V3]; xn--0ug.xn--ss--bi1b; ; ; # .ssⴉ-
+.xn--ss--4rn; .ssႩ-; [V3, V6, X4_2]; .xn--ss--4rn; [V3, V6, A4_2]; ; # .ssႩ-
+xn--0ug.xn--ss--4rn; \u200C.ssႩ-; [C1, V3, V6]; xn--0ug.xn--ss--4rn; ; ; # .ssႩ-
+xn--0ug.xn----pfa2305a; \u200C.ßⴉ-; [C1, V3]; xn--0ug.xn----pfa2305a; ; ; # .ßⴉ-
+xn--0ug.xn----pfa042j; \u200C.ßႩ-; [C1, V3, V6]; xn--0ug.xn----pfa042j; ; ; # .ßႩ-
+󍭲𐫍㓱。⾑; 󍭲𐫍㓱.襾; [B5, V6]; xn--u7kt691dlj09f.xn--9v2a; ; ; # 𐫍㓱.襾
+󍭲𐫍㓱。襾; 󍭲𐫍㓱.襾; [B5, V6]; xn--u7kt691dlj09f.xn--9v2a; ; ; # 𐫍㓱.襾
+xn--u7kt691dlj09f.xn--9v2a; 󍭲𐫍㓱.襾; [B5, V6]; xn--u7kt691dlj09f.xn--9v2a; ; ; # 𐫍㓱.襾
+\u06A0𐮋𐹰≮。≯󠦗\u200D; \u06A0𐮋𐹰≮.≯󠦗\u200D; [B1, B3, C2, V6]; xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ; xn--2jb053lf13nyoc.xn--hdh08821l; [B1, B3, V6] # ڠ𐮋𐹰≮.≯
+\u06A0𐮋𐹰<\u0338。>\u0338󠦗\u200D; \u06A0𐮋𐹰≮.≯󠦗\u200D; [B1, B3, C2, V6]; xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ; xn--2jb053lf13nyoc.xn--hdh08821l; [B1, B3, V6] # ڠ𐮋𐹰≮.≯
+xn--2jb053lf13nyoc.xn--hdh08821l; \u06A0𐮋𐹰≮.≯󠦗; [B1, B3, V6]; xn--2jb053lf13nyoc.xn--hdh08821l; ; ; # ڠ𐮋𐹰≮.≯
+xn--2jb053lf13nyoc.xn--1ugx6gc8096c; \u06A0𐮋𐹰≮.≯󠦗\u200D; [B1, B3, C2, V6]; xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ; ; # ڠ𐮋𐹰≮.≯
+𝟞。񃰶\u0777\u08B0⩋; 6.񃰶\u0777\u08B0⩋; [B1, B5, B6, V6]; 6.xn--7pb04do15eq748f; ; ; # 6.ݷࢰ⩋
+6。񃰶\u0777\u08B0⩋; 6.񃰶\u0777\u08B0⩋; [B1, B5, B6, V6]; 6.xn--7pb04do15eq748f; ; ; # 6.ݷࢰ⩋
+6.xn--7pb04do15eq748f; 6.񃰶\u0777\u08B0⩋; [B1, B5, B6, V6]; 6.xn--7pb04do15eq748f; ; ; # 6.ݷࢰ⩋
+-\uFCFD。𑇀𑍴; -\u0634\u0649.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+-\uFCFD。𑇀𑍴; -\u0634\u0649.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+-\u0634\u0649。𑇀𑍴; -\u0634\u0649.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+xn----qnc7d.xn--wd1d62a; -\u0634\u0649.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+\u200C󠊶𝟏.\u0D43򪥐𐹬󊓶; \u200C󠊶1.\u0D43򪥐𐹬󊓶; [B1, C1, V5, V6]; xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ; xn--1-f521m.xn--mxc0872kcu37dnmem; [B1, V5, V6] # 1.ൃ𐹬
+\u200C󠊶1.\u0D43򪥐𐹬󊓶; ; [B1, C1, V5, V6]; xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ; xn--1-f521m.xn--mxc0872kcu37dnmem; [B1, V5, V6] # 1.ൃ𐹬
+xn--1-f521m.xn--mxc0872kcu37dnmem; 󠊶1.\u0D43򪥐𐹬󊓶; [B1, V5, V6]; xn--1-f521m.xn--mxc0872kcu37dnmem; ; ; # 1.ൃ𐹬
+xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; \u200C󠊶1.\u0D43򪥐𐹬󊓶; [B1, C1, V5, V6]; xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ; ; # 1.ൃ𐹬
+齙--𝟰.ß; 齙--4.ß; ; xn----4-p16k.xn--zca; ; xn----4-p16k.ss; # 齙--4.ß
+齙--4.ß; ; ; xn----4-p16k.xn--zca; ; xn----4-p16k.ss; # 齙--4.ß
+齙--4.SS; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--4.ss; ; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--4.Ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+xn----4-p16k.ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+xn----4-p16k.xn--zca; 齙--4.ß; ; xn----4-p16k.xn--zca; ; ; # 齙--4.ß
+齙--𝟰.SS; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--𝟰.ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--𝟰.Ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+\u1BF2.𐹢𞀖\u200C; ; [B1, C1, V5]; xn--0zf.xn--0ug9894grqqf; ; xn--0zf.xn--9n0d2296a; [B1, V5] # ᯲.𐹢𞀖
+xn--0zf.xn--9n0d2296a; \u1BF2.𐹢𞀖; [B1, V5]; xn--0zf.xn--9n0d2296a; ; ; # ᯲.𐹢𞀖
+xn--0zf.xn--0ug9894grqqf; \u1BF2.𐹢𞀖\u200C; [B1, C1, V5]; xn--0zf.xn--0ug9894grqqf; ; ; # ᯲.𐹢𞀖
+󃲙󠋘。?-\u200D; 󃲙󠋘.?-\u200D; [C2, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [V3, V6] # .?-
+󃲙󠋘。?-\u200D; 󃲙󠋘.?-\u200D; [C2, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [V3, V6] # .?-
+xn--ct86d8w51a.?-; 󃲙󠋘.?-; [V3, V6]; xn--ct86d8w51a.?-; ; ; # .?-
+xn--ct86d8w51a.xn--?--n1t; 󃲙󠋘.?-\u200D; [C2, V6]; xn--ct86d8w51a.xn--?--n1t; ; ; # .?-
+xn--ct86d8w51a.?-\u200D; 󃲙󠋘.?-\u200D; [C2, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [V3, V6] # .?-
+XN--CT86D8W51A.?-\u200D; 󃲙󠋘.?-\u200D; [C2, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [V3, V6] # .?-
+Xn--Ct86d8w51a.?-\u200D; 󃲙󠋘.?-\u200D; [C2, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [V3, V6] # .?-
+\u1A60.𞵷-𝪩悎; \u1A60.𞵷-𝪩悎; [B1, B2, B3, V5, V6]; xn--jof.xn----gf4bq282iezpa; ; ; # ᩠.-𝪩悎
+\u1A60.𞵷-𝪩悎; ; [B1, B2, B3, V5, V6]; xn--jof.xn----gf4bq282iezpa; ; ; # ᩠.-𝪩悎
+xn--jof.xn----gf4bq282iezpa; \u1A60.𞵷-𝪩悎; [B1, B2, B3, V5, V6]; xn--jof.xn----gf4bq282iezpa; ; ; # ᩠.-𝪩悎
+𛜯󠊛.𞤳񏥾; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+𛜯󠊛.𞤳񏥾; ; [B2, B3, B6, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+𛜯󠊛.𞤑񏥾; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+xn--xx5gy2741c.xn--re6hw266j; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+𛜯󠊛.𞤑񏥾; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+\u071C𐫒\u062E.𐋲; ; [B1]; xn--tgb98b8643d.xn--m97c; ; ; # ܜ𐫒خ.𐋲
+xn--tgb98b8643d.xn--m97c; \u071C𐫒\u062E.𐋲; [B1]; xn--tgb98b8643d.xn--m97c; ; ; # ܜ𐫒خ.𐋲
+𐼑𞤓\u0637\u08E2.?; 𐼑𞤵\u0637\u08E2.?; [B1, V6]; xn--2gb08k9w69agm0g.?; ; ; # 𐼑𞤵ط.?
+𐼑𞤵\u0637\u08E2.?; ; [B1, V6]; xn--2gb08k9w69agm0g.?; ; ; # 𐼑𞤵ط.?
+xn--2gb08k9w69agm0g.?; 𐼑𞤵\u0637\u08E2.?; [B1, V6]; xn--2gb08k9w69agm0g.?; ; ; # 𐼑𞤵ط.?
+Ↄ。\u0A4D\u1CD4𞷣; Ↄ.\u1CD4\u0A4D𞷣; [B1, V5, V6]; xn--q5g.xn--ybc995g0835a; ; ; # Ↄ.᳔੍
+Ↄ。\u1CD4\u0A4D𞷣; Ↄ.\u1CD4\u0A4D𞷣; [B1, V5, V6]; xn--q5g.xn--ybc995g0835a; ; ; # Ↄ.᳔੍
+ↄ。\u1CD4\u0A4D𞷣; ↄ.\u1CD4\u0A4D𞷣; [B1, V5, V6]; xn--r5g.xn--ybc995g0835a; ; ; # ↄ.᳔੍
+xn--r5g.xn--ybc995g0835a; ↄ.\u1CD4\u0A4D𞷣; [B1, V5, V6]; xn--r5g.xn--ybc995g0835a; ; ; # ↄ.᳔੍
+xn--q5g.xn--ybc995g0835a; Ↄ.\u1CD4\u0A4D𞷣; [B1, V5, V6]; xn--q5g.xn--ybc995g0835a; ; ; # Ↄ.᳔੍
+ↄ。\u0A4D\u1CD4𞷣; ↄ.\u1CD4\u0A4D𞷣; [B1, V5, V6]; xn--r5g.xn--ybc995g0835a; ; ; # ↄ.᳔੍
+󠪢-。򛂏≮𑜫; 󠪢-.򛂏≮𑜫; [V3, V6]; xn----bh61m.xn--gdhz157g0em1d; ; ; # -.≮𑜫
+󠪢-。򛂏<\u0338𑜫; 󠪢-.򛂏≮𑜫; [V3, V6]; xn----bh61m.xn--gdhz157g0em1d; ; ; # -.≮𑜫
+xn----bh61m.xn--gdhz157g0em1d; 󠪢-.򛂏≮𑜫; [V3, V6]; xn----bh61m.xn--gdhz157g0em1d; ; ; # -.≮𑜫
+\u200C󠉹\u200D。򌿧≮Ⴉ; \u200C󠉹\u200D.򌿧≮Ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--hnd112gpz83n; ; xn--3n36e.xn--hnd112gpz83n; [V6] # .≮Ⴉ
+\u200C󠉹\u200D。򌿧<\u0338Ⴉ; \u200C󠉹\u200D.򌿧≮Ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--hnd112gpz83n; ; xn--3n36e.xn--hnd112gpz83n; [V6] # .≮Ⴉ
+\u200C󠉹\u200D。򌿧<\u0338ⴉ; \u200C󠉹\u200D.򌿧≮ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--gdh992byu01p; ; xn--3n36e.xn--gdh992byu01p; [V6] # .≮ⴉ
+\u200C󠉹\u200D。򌿧≮ⴉ; \u200C󠉹\u200D.򌿧≮ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--gdh992byu01p; ; xn--3n36e.xn--gdh992byu01p; [V6] # .≮ⴉ
+xn--3n36e.xn--gdh992byu01p; 󠉹.򌿧≮ⴉ; [V6]; xn--3n36e.xn--gdh992byu01p; ; ; # .≮ⴉ
+xn--0ugc90904y.xn--gdh992byu01p; \u200C󠉹\u200D.򌿧≮ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--gdh992byu01p; ; ; # .≮ⴉ
+xn--3n36e.xn--hnd112gpz83n; 󠉹.򌿧≮Ⴉ; [V6]; xn--3n36e.xn--hnd112gpz83n; ; ; # .≮Ⴉ
+xn--0ugc90904y.xn--hnd112gpz83n; \u200C󠉹\u200D.򌿧≮Ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--hnd112gpz83n; ; ; # .≮Ⴉ
+𐹯-𑄴\u08BC。︒䖐⾆; 𐹯-𑄴\u08BC.︒䖐舌; [B1, V6]; xn----rpd7902rclc.xn--fpo216mn07e; ; ; # 𐹯-𑄴ࢼ.︒䖐舌
+𐹯-𑄴\u08BC。。䖐舌; 𐹯-𑄴\u08BC..䖐舌; [B1, X4_2]; xn----rpd7902rclc..xn--fpo216m; [B1, A4_2]; ; # 𐹯-𑄴ࢼ..䖐舌
+xn----rpd7902rclc..xn--fpo216m; 𐹯-𑄴\u08BC..䖐舌; [B1, X4_2]; xn----rpd7902rclc..xn--fpo216m; [B1, A4_2]; ; # 𐹯-𑄴ࢼ..䖐舌
+xn----rpd7902rclc.xn--fpo216mn07e; 𐹯-𑄴\u08BC.︒䖐舌; [B1, V6]; xn----rpd7902rclc.xn--fpo216mn07e; ; ; # 𐹯-𑄴ࢼ.︒䖐舌
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+xn--7kj1858k.xn--pi6b; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+xn--ond3755u.xn--pi6b; 𝪞Ⴐ.쪡; [V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+\u0E3A쩁𐹬.􋉳; ; [B1, V5, V6]; xn--o4c4837g2zvb.xn--5f70g; ; ; # ฺ쩁𐹬.
+\u0E3A쩁𐹬.􋉳; \u0E3A쩁𐹬.􋉳; [B1, V5, V6]; xn--o4c4837g2zvb.xn--5f70g; ; ; # ฺ쩁𐹬.
+xn--o4c4837g2zvb.xn--5f70g; \u0E3A쩁𐹬.􋉳; [B1, V5, V6]; xn--o4c4837g2zvb.xn--5f70g; ; ; # ฺ쩁𐹬.
+ᡅ0\u200C。⎢󤨄; ᡅ0\u200C.⎢󤨄; [C1, V6]; xn--0-z6jy93b.xn--8lh28773l; ; xn--0-z6j.xn--8lh28773l; [V6] # ᡅ0.⎢
+ᡅ0\u200C。⎢󤨄; ᡅ0\u200C.⎢󤨄; [C1, V6]; xn--0-z6jy93b.xn--8lh28773l; ; xn--0-z6j.xn--8lh28773l; [V6] # ᡅ0.⎢
+xn--0-z6j.xn--8lh28773l; ᡅ0.⎢󤨄; [V6]; xn--0-z6j.xn--8lh28773l; ; ; # ᡅ0.⎢
+xn--0-z6jy93b.xn--8lh28773l; ᡅ0\u200C.⎢󤨄; [C1, V6]; xn--0-z6jy93b.xn--8lh28773l; ; ; # ᡅ0.⎢
+𲮚9ꍩ\u17D3.\u200Dß; 𲮚9ꍩ\u17D3.\u200Dß; [C2, V6]; xn--9-i0j5967eg3qz.xn--zca770n; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ß
+𲮚9ꍩ\u17D3.\u200Dß; ; [C2, V6]; xn--9-i0j5967eg3qz.xn--zca770n; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ß
+𲮚9ꍩ\u17D3.\u200DSS; 𲮚9ꍩ\u17D3.\u200Dss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ss
+𲮚9ꍩ\u17D3.\u200Dss; ; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ss
+xn--9-i0j5967eg3qz.ss; 𲮚9ꍩ\u17D3.ss; [V6]; xn--9-i0j5967eg3qz.ss; ; ; # 9ꍩ៓.ss
+xn--9-i0j5967eg3qz.xn--ss-l1t; 𲮚9ꍩ\u17D3.\u200Dss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; ; # 9ꍩ៓.ss
+xn--9-i0j5967eg3qz.xn--zca770n; 𲮚9ꍩ\u17D3.\u200Dß; [C2, V6]; xn--9-i0j5967eg3qz.xn--zca770n; ; ; # 9ꍩ៓.ß
+𲮚9ꍩ\u17D3.\u200DSS; 𲮚9ꍩ\u17D3.\u200Dss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ss
+𲮚9ꍩ\u17D3.\u200Dss; 𲮚9ꍩ\u17D3.\u200Dss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ss
+𲮚9ꍩ\u17D3.\u200DSs; 𲮚9ꍩ\u17D3.\u200Dss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ss
+𲮚9ꍩ\u17D3.\u200DSs; 𲮚9ꍩ\u17D3.\u200Dss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [V6] # 9ꍩ៓.ss
+ꗷ𑆀.\u075D𐩒; ; ; xn--ju8a625r.xn--hpb0073k; ; ; # ꗷ𑆀.ݝ𐩒
+xn--ju8a625r.xn--hpb0073k; ꗷ𑆀.\u075D𐩒; ; xn--ju8a625r.xn--hpb0073k; ; ; # ꗷ𑆀.ݝ𐩒
+⒐≯-。︒򩑣-񞛠; ⒐≯-.︒򩑣-񞛠; [V3, V6]; xn----ogot9g.xn----n89hl0522az9u2a; ; ; # ⒐≯-.︒-
+⒐>\u0338-。︒򩑣-񞛠; ⒐≯-.︒򩑣-񞛠; [V3, V6]; xn----ogot9g.xn----n89hl0522az9u2a; ; ; # ⒐≯-.︒-
+9.≯-。。򩑣-񞛠; 9.≯-..򩑣-񞛠; [V3, V6, X4_2]; 9.xn----ogo..xn----xj54d1s69k; [V3, V6, A4_2]; ; # 9.≯-..-
+9.>\u0338-。。򩑣-񞛠; 9.≯-..򩑣-񞛠; [V3, V6, X4_2]; 9.xn----ogo..xn----xj54d1s69k; [V3, V6, A4_2]; ; # 9.≯-..-
+9.xn----ogo..xn----xj54d1s69k; 9.≯-..򩑣-񞛠; [V3, V6, X4_2]; 9.xn----ogo..xn----xj54d1s69k; [V3, V6, A4_2]; ; # 9.≯-..-
+xn----ogot9g.xn----n89hl0522az9u2a; ⒐≯-.︒򩑣-񞛠; [V3, V6]; xn----ogot9g.xn----n89hl0522az9u2a; ; ; # ⒐≯-.︒-
+򈪚\u0CE3Ⴡ󠢏.\u061D; 򈪚\u0CE3Ⴡ󠢏.\u061D; [B6, V6]; xn--vuc49qvu85xmju7a.xn--cgb; ; ; # ೣჁ.؝
+򈪚\u0CE3Ⴡ󠢏.\u061D; ; [B6, V6]; xn--vuc49qvu85xmju7a.xn--cgb; ; ; # ೣჁ.؝
+򈪚\u0CE3ⴡ󠢏.\u061D; ; [B6, V6]; xn--vuc226n8n28lmju7a.xn--cgb; ; ; # ೣⴡ.؝
+xn--vuc226n8n28lmju7a.xn--cgb; 򈪚\u0CE3ⴡ󠢏.\u061D; [B6, V6]; xn--vuc226n8n28lmju7a.xn--cgb; ; ; # ೣⴡ.؝
+xn--vuc49qvu85xmju7a.xn--cgb; 򈪚\u0CE3Ⴡ󠢏.\u061D; [B6, V6]; xn--vuc49qvu85xmju7a.xn--cgb; ; ; # ೣჁ.؝
+򈪚\u0CE3ⴡ󠢏.\u061D; 򈪚\u0CE3ⴡ󠢏.\u061D; [B6, V6]; xn--vuc226n8n28lmju7a.xn--cgb; ; ; # ೣⴡ.؝
+\u1DEB。𐋩\u0638-𐫮; \u1DEB.𐋩\u0638-𐫮; [B1, V5]; xn--gfg.xn----xnc0815qyyg; ; ; # ᷫ.𐋩ظ-𐫮
+xn--gfg.xn----xnc0815qyyg; \u1DEB.𐋩\u0638-𐫮; [B1, V5]; xn--gfg.xn----xnc0815qyyg; ; ; # ᷫ.𐋩ظ-𐫮
+싇。⾇𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。舛𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。舛𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。舛𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+xn--9u4b.xn--llj123yh74e; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+xn--9u4b.xn--1nd7519ch79d; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。⾇𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。⾇𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。⾇𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+𐹠ς。\u200C\u06BFჀ; 𐹠ς.\u200C\u06BFჀ; [B1, C1, V6]; xn--3xa1267k.xn--ykb632cvxm; ; xn--4xa9167k.xn--ykb632c; [B1, B2, B3, V6] # 𐹠ς.ڿჀ
+𐹠ς。\u200C\u06BFⴠ; 𐹠ς.\u200C\u06BFⴠ; [B1, C1]; xn--3xa1267k.xn--ykb760k9hj; ; xn--4xa9167k.xn--ykb467q; [B1, B2, B3] # 𐹠ς.ڿⴠ
+𐹠Σ。\u200C\u06BFჀ; 𐹠σ.\u200C\u06BFჀ; [B1, C1, V6]; xn--4xa9167k.xn--ykb632cvxm; ; xn--4xa9167k.xn--ykb632c; [B1, B2, B3, V6] # 𐹠σ.ڿჀ
+𐹠σ。\u200C\u06BFⴠ; 𐹠σ.\u200C\u06BFⴠ; [B1, C1]; xn--4xa9167k.xn--ykb760k9hj; ; xn--4xa9167k.xn--ykb467q; [B1, B2, B3] # 𐹠σ.ڿⴠ
+𐹠Σ。\u200C\u06BFⴠ; 𐹠σ.\u200C\u06BFⴠ; [B1, C1]; xn--4xa9167k.xn--ykb760k9hj; ; xn--4xa9167k.xn--ykb467q; [B1, B2, B3] # 𐹠σ.ڿⴠ
+xn--4xa9167k.xn--ykb467q; 𐹠σ.\u06BFⴠ; [B1, B2, B3]; xn--4xa9167k.xn--ykb467q; ; ; # 𐹠σ.ڿⴠ
+xn--4xa9167k.xn--ykb760k9hj; 𐹠σ.\u200C\u06BFⴠ; [B1, C1]; xn--4xa9167k.xn--ykb760k9hj; ; ; # 𐹠σ.ڿⴠ
+xn--4xa9167k.xn--ykb632c; 𐹠σ.\u06BFჀ; [B1, B2, B3, V6]; xn--4xa9167k.xn--ykb632c; ; ; # 𐹠σ.ڿჀ
+xn--4xa9167k.xn--ykb632cvxm; 𐹠σ.\u200C\u06BFჀ; [B1, C1, V6]; xn--4xa9167k.xn--ykb632cvxm; ; ; # 𐹠σ.ڿჀ
+xn--3xa1267k.xn--ykb760k9hj; 𐹠ς.\u200C\u06BFⴠ; [B1, C1]; xn--3xa1267k.xn--ykb760k9hj; ; ; # 𐹠ς.ڿⴠ
+xn--3xa1267k.xn--ykb632cvxm; 𐹠ς.\u200C\u06BFჀ; [B1, C1, V6]; xn--3xa1267k.xn--ykb632cvxm; ; ; # 𐹠ς.ڿჀ
+򇒐\u200C\u0604.\u069A-ß; ; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn----qfa315b; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, V6] # .ښ-ß
+򇒐\u200C\u0604.\u069A-SS; 򇒐\u200C\u0604.\u069A-ss; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, V6] # .ښ-ss
+򇒐\u200C\u0604.\u069A-ss; ; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, V6] # .ښ-ss
+򇒐\u200C\u0604.\u069A-Ss; 򇒐\u200C\u0604.\u069A-ss; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, V6] # .ښ-ss
+xn--mfb98261i.xn---ss-sdf; 򇒐\u0604.\u069A-ss; [B2, B3, B5, B6, V6]; xn--mfb98261i.xn---ss-sdf; ; ; # .ښ-ss
+xn--mfb144kqo32m.xn---ss-sdf; 򇒐\u200C\u0604.\u069A-ss; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; ; # .ښ-ss
+xn--mfb144kqo32m.xn----qfa315b; 򇒐\u200C\u0604.\u069A-ß; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn----qfa315b; ; ; # .ښ-ß
+\u200C\u200D\u17B5\u067A.-\uFBB0󅄞𐸚; \u200C\u200D\u17B5\u067A.-\u06D3󅄞𐸚; [B1, C1, C2, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; xn--zib539f.xn----twc1133r17r6g; [B1, V3, V5, V6] # ٺ.-ۓ
+\u200C\u200D\u17B5\u067A.-\u06D3󅄞𐸚; ; [B1, C1, C2, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; xn--zib539f.xn----twc1133r17r6g; [B1, V3, V5, V6] # ٺ.-ۓ
+\u200C\u200D\u17B5\u067A.-\u06D2\u0654󅄞𐸚; \u200C\u200D\u17B5\u067A.-\u06D3󅄞𐸚; [B1, C1, C2, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; xn--zib539f.xn----twc1133r17r6g; [B1, V3, V5, V6] # ٺ.-ۓ
+xn--zib539f.xn----twc1133r17r6g; \u17B5\u067A.-\u06D3󅄞𐸚; [B1, V3, V5, V6]; xn--zib539f.xn----twc1133r17r6g; ; ; # ٺ.-ۓ
+xn--zib539f8igea.xn----twc1133r17r6g; \u200C\u200D\u17B5\u067A.-\u06D3󅄞𐸚; [B1, C1, C2, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; ; # ٺ.-ۓ
+򡶱。𐮬≠; 򡶱.𐮬≠; [B3, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+򡶱。𐮬=\u0338; 򡶱.𐮬≠; [B3, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+򡶱。𐮬≠; 򡶱.𐮬≠; [B3, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+򡶱。𐮬=\u0338; 򡶱.𐮬≠; [B3, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+xn--dd55c.xn--1ch3003g; 򡶱.𐮬≠; [B3, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+\u0FB2𞶅。𐹮𐹷덝۵; \u0FB2𞶅.𐹮𐹷덝۵; [B1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+\u0FB2𞶅。𐹮𐹷덝۵; \u0FB2𞶅.𐹮𐹷덝۵; [B1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+\u0FB2𞶅。𐹮𐹷덝۵; \u0FB2𞶅.𐹮𐹷덝۵; [B1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+\u0FB2𞶅。𐹮𐹷덝۵; \u0FB2𞶅.𐹮𐹷덝۵; [B1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+xn--fgd0675v.xn--imb5839fidpcbba; \u0FB2𞶅.𐹮𐹷덝۵; [B1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+Ⴏ󠅋-.\u200DႩ; Ⴏ-.\u200DႩ; [C2, V3, V6]; xn----00g.xn--hnd399e; ; xn----00g.xn--hnd; [V3, V6] # Ⴏ-.Ⴉ
+Ⴏ󠅋-.\u200DႩ; Ⴏ-.\u200DႩ; [C2, V3, V6]; xn----00g.xn--hnd399e; ; xn----00g.xn--hnd; [V3, V6] # Ⴏ-.Ⴉ
+ⴏ󠅋-.\u200Dⴉ; ⴏ-.\u200Dⴉ; [C2, V3]; xn----3vs.xn--1ug532c; ; xn----3vs.xn--0kj; [V3] # ⴏ-.ⴉ
+xn----3vs.xn--0kj; ⴏ-.ⴉ; [V3]; xn----3vs.xn--0kj; ; ; # ⴏ-.ⴉ
+xn----3vs.xn--1ug532c; ⴏ-.\u200Dⴉ; [C2, V3]; xn----3vs.xn--1ug532c; ; ; # ⴏ-.ⴉ
+xn----00g.xn--hnd; Ⴏ-.Ⴉ; [V3, V6]; xn----00g.xn--hnd; ; ; # Ⴏ-.Ⴉ
+xn----00g.xn--hnd399e; Ⴏ-.\u200DႩ; [C2, V3, V6]; xn----00g.xn--hnd399e; ; ; # Ⴏ-.Ⴉ
+ⴏ󠅋-.\u200Dⴉ; ⴏ-.\u200Dⴉ; [C2, V3]; xn----3vs.xn--1ug532c; ; xn----3vs.xn--0kj; [V3] # ⴏ-.ⴉ
+⇧𐨏󠾈󯶅。\u0600󠈵󠆉; ⇧𐨏󠾈󯶅.\u0600󠈵; [B1, V6]; xn--l8g5552g64t4g46xf.xn--ifb08144p; ; ; # ⇧𐨏.
+xn--l8g5552g64t4g46xf.xn--ifb08144p; ⇧𐨏󠾈󯶅.\u0600󠈵; [B1, V6]; xn--l8g5552g64t4g46xf.xn--ifb08144p; ; ; # ⇧𐨏.
+≠𐮂.↑🄇⒈; ; [B1, V6]; xn--1chy492g.xn--45gx9iuy44d; ; ; # ≠𐮂.↑🄇⒈
+=\u0338𐮂.↑🄇⒈; ≠𐮂.↑🄇⒈; [B1, V6]; xn--1chy492g.xn--45gx9iuy44d; ; ; # ≠𐮂.↑🄇⒈
+≠𐮂.↑6,1.; ; [B1, V6]; xn--1chy492g.xn--6,1-pw1a.; ; ; # ≠𐮂.↑6,1.
+=\u0338𐮂.↑6,1.; ≠𐮂.↑6,1.; [B1, V6]; xn--1chy492g.xn--6,1-pw1a.; ; ; # ≠𐮂.↑6,1.
+xn--1chy492g.xn--6,1-pw1a.; ≠𐮂.↑6,1.; [B1, V6]; xn--1chy492g.xn--6,1-pw1a.; ; ; # ≠𐮂.↑6,1.
+xn--1chy492g.xn--45gx9iuy44d; ≠𐮂.↑🄇⒈; [B1, V6]; xn--1chy492g.xn--45gx9iuy44d; ; ; # ≠𐮂.↑🄇⒈
+𝩏󠲉ß.ᢤ򄦌\u200C𐹫; ; [B1, B5, B6, C1, V5, V6]; xn--zca3153vupz3e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, V5, V6] # 𝩏ß.ᢤ𐹫
+𝩏󠲉SS.ᢤ򄦌\u200C𐹫; 𝩏󠲉ss.ᢤ򄦌\u200C𐹫; [B1, B5, B6, C1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, V5, V6] # 𝩏ss.ᢤ𐹫
+𝩏󠲉ss.ᢤ򄦌\u200C𐹫; ; [B1, B5, B6, C1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, V5, V6] # 𝩏ss.ᢤ𐹫
+𝩏󠲉Ss.ᢤ򄦌\u200C𐹫; 𝩏󠲉ss.ᢤ򄦌\u200C𐹫; [B1, B5, B6, C1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, V5, V6] # 𝩏ss.ᢤ𐹫
+xn--ss-zb11ap1427e.xn--ubf2596jbt61c; 𝩏󠲉ss.ᢤ򄦌𐹫; [B1, B5, B6, V5, V6]; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; ; ; # 𝩏ss.ᢤ𐹫
+xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; 𝩏󠲉ss.ᢤ򄦌\u200C𐹫; [B1, B5, B6, C1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; ; # 𝩏ss.ᢤ𐹫
+xn--zca3153vupz3e.xn--ubf609atw1tynn3d; 𝩏󠲉ß.ᢤ򄦌\u200C𐹫; [B1, B5, B6, C1, V5, V6]; xn--zca3153vupz3e.xn--ubf609atw1tynn3d; ; ; # 𝩏ß.ᢤ𐹫
+ß𐵳񗘁Ⴇ。\uA67A; ß𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--zca491fci5qkn79a.xn--9x8a; ; xn--ss-rek7420r4hs7b.xn--9x8a; # ßႧ.ꙺ
+ß𐵳񗘁Ⴇ。\uA67A; ß𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--zca491fci5qkn79a.xn--9x8a; ; xn--ss-rek7420r4hs7b.xn--9x8a; # ßႧ.ꙺ
+ß𐵳񗘁ⴇ。\uA67A; ß𐵳񗘁ⴇ.\uA67A; [B1, B5, V5, V6]; xn--zca227tpy4lkns1b.xn--9x8a; ; xn--ss-e61ar955h4hs7b.xn--9x8a; # ßⴇ.ꙺ
+SS𐵳񗘁Ⴇ。\uA67A; ss𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+ss𐵳񗘁ⴇ。\uA67A; ss𐵳񗘁ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-e61ar955h4hs7b.xn--9x8a; ; ; # ssⴇ.ꙺ
+Ss𐵳񗘁Ⴇ。\uA67A; ss𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+xn--ss-rek7420r4hs7b.xn--9x8a; ss𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+xn--ss-e61ar955h4hs7b.xn--9x8a; ss𐵳񗘁ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-e61ar955h4hs7b.xn--9x8a; ; ; # ssⴇ.ꙺ
+xn--zca227tpy4lkns1b.xn--9x8a; ß𐵳񗘁ⴇ.\uA67A; [B1, B5, V5, V6]; xn--zca227tpy4lkns1b.xn--9x8a; ; ; # ßⴇ.ꙺ
+xn--zca491fci5qkn79a.xn--9x8a; ß𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--zca491fci5qkn79a.xn--9x8a; ; ; # ßႧ.ꙺ
+ß𐵳񗘁ⴇ。\uA67A; ß𐵳񗘁ⴇ.\uA67A; [B1, B5, V5, V6]; xn--zca227tpy4lkns1b.xn--9x8a; ; xn--ss-e61ar955h4hs7b.xn--9x8a; # ßⴇ.ꙺ
+SS𐵳񗘁Ⴇ。\uA67A; ss𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+ss𐵳񗘁ⴇ。\uA67A; ss𐵳񗘁ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-e61ar955h4hs7b.xn--9x8a; ; ; # ssⴇ.ꙺ
+Ss𐵳񗘁Ⴇ。\uA67A; ss𐵳񗘁Ⴇ.\uA67A; [B1, B5, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+\u1714。󠆣-𑋪; \u1714.-𑋪; [V3, V5]; xn--fze.xn----ly8i; ; ; # ᜔.-𑋪
+xn--fze.xn----ly8i; \u1714.-𑋪; [V3, V5]; xn--fze.xn----ly8i; ; ; # ᜔.-𑋪
+\uABE8-.򨏜\u05BDß; \uABE8-.򨏜\u05BDß; [V3, V5, V6]; xn----pw5e.xn--zca50wfv060a; ; xn----pw5e.xn--ss-7jd10716y; # ꯨ-.ֽß
+\uABE8-.򨏜\u05BDß; ; [V3, V5, V6]; xn----pw5e.xn--zca50wfv060a; ; xn----pw5e.xn--ss-7jd10716y; # ꯨ-.ֽß
+\uABE8-.򨏜\u05BDSS; \uABE8-.򨏜\u05BDss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+\uABE8-.򨏜\u05BDss; ; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+\uABE8-.򨏜\u05BDSs; \uABE8-.򨏜\u05BDss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+xn----pw5e.xn--ss-7jd10716y; \uABE8-.򨏜\u05BDss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+xn----pw5e.xn--zca50wfv060a; \uABE8-.򨏜\u05BDß; [V3, V5, V6]; xn----pw5e.xn--zca50wfv060a; ; ; # ꯨ-.ֽß
+\uABE8-.򨏜\u05BDSS; \uABE8-.򨏜\u05BDss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+\uABE8-.򨏜\u05BDss; \uABE8-.򨏜\u05BDss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+\uABE8-.򨏜\u05BDSs; \uABE8-.򨏜\u05BDss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+ᡓ-≮。\u066B󠅱ᡄ; ᡓ-≮.\u066Bᡄ; [B1, B6]; xn----s7j866c.xn--kib252g; ; ; # ᡓ-≮.٫ᡄ
+ᡓ-<\u0338。\u066B󠅱ᡄ; ᡓ-≮.\u066Bᡄ; [B1, B6]; xn----s7j866c.xn--kib252g; ; ; # ᡓ-≮.٫ᡄ
+xn----s7j866c.xn--kib252g; ᡓ-≮.\u066Bᡄ; [B1, B6]; xn----s7j866c.xn--kib252g; ; ; # ᡓ-≮.٫ᡄ
+𝟥♮𑜫\u08ED.\u17D2𑜫8󠆏; 3♮𑜫\u08ED.\u17D2𑜫8; [V5]; xn--3-ksd277tlo7s.xn--8-f0jx021l; ; ; # 3♮𑜫࣭.្𑜫8
+3♮𑜫\u08ED.\u17D2𑜫8󠆏; 3♮𑜫\u08ED.\u17D2𑜫8; [V5]; xn--3-ksd277tlo7s.xn--8-f0jx021l; ; ; # 3♮𑜫࣭.្𑜫8
+xn--3-ksd277tlo7s.xn--8-f0jx021l; 3♮𑜫\u08ED.\u17D2𑜫8; [V5]; xn--3-ksd277tlo7s.xn--8-f0jx021l; ; ; # 3♮𑜫࣭.្𑜫8
+-。򕌀\u200D❡; -.򕌀\u200D❡; [C2, V3, V6]; -.xn--1ug800aq795s; ; -.xn--nei54421f; [V3, V6] # -.❡
+-。򕌀\u200D❡; -.򕌀\u200D❡; [C2, V3, V6]; -.xn--1ug800aq795s; ; -.xn--nei54421f; [V3, V6] # -.❡
+-.xn--nei54421f; -.򕌀❡; [V3, V6]; -.xn--nei54421f; ; ; # -.❡
+-.xn--1ug800aq795s; -.򕌀\u200D❡; [C2, V3, V6]; -.xn--1ug800aq795s; ; ; # -.❡
+𝟓☱𝟐򥰵。𝪮񐡳; 5☱2򥰵.𝪮񐡳; [V5, V6]; xn--52-dwx47758j.xn--kd3hk431k; ; ; # 5☱2.𝪮
+5☱2򥰵。𝪮񐡳; 5☱2򥰵.𝪮񐡳; [V5, V6]; xn--52-dwx47758j.xn--kd3hk431k; ; ; # 5☱2.𝪮
+xn--52-dwx47758j.xn--kd3hk431k; 5☱2򥰵.𝪮񐡳; [V5, V6]; xn--52-dwx47758j.xn--kd3hk431k; ; ; # 5☱2.𝪮
+-.-├򖦣; ; [V3, V6]; -.xn----ukp70432h; ; ; # -.-├
+-.xn----ukp70432h; -.-├򖦣; [V3, V6]; -.xn----ukp70432h; ; ; # -.-├
+\u05A5\u076D。\u200D󠀘; \u05A5\u076D.\u200D󠀘; [B1, C2, V5, V6]; xn--wcb62g.xn--1ugy8001l; ; xn--wcb62g.xn--p526e; [B1, V5, V6] # ֥ݭ.
+\u05A5\u076D。\u200D󠀘; \u05A5\u076D.\u200D󠀘; [B1, C2, V5, V6]; xn--wcb62g.xn--1ugy8001l; ; xn--wcb62g.xn--p526e; [B1, V5, V6] # ֥ݭ.
+xn--wcb62g.xn--p526e; \u05A5\u076D.󠀘; [B1, V5, V6]; xn--wcb62g.xn--p526e; ; ; # ֥ݭ.
+xn--wcb62g.xn--1ugy8001l; \u05A5\u076D.\u200D󠀘; [B1, C2, V5, V6]; xn--wcb62g.xn--1ugy8001l; ; ; # ֥ݭ.
+쥥󔏉Ⴎ.\u200C⒈⒈𐫒; 쥥󔏉Ⴎ.\u200C⒈⒈𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--0ug88oa0396u; ; xn--mnd7865gcy28g.xn--tsha6797o; [B1, V6] # 쥥Ⴎ.⒈⒈𐫒
+쥥󔏉Ⴎ.\u200C⒈⒈𐫒; 쥥󔏉Ⴎ.\u200C⒈⒈𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--0ug88oa0396u; ; xn--mnd7865gcy28g.xn--tsha6797o; [B1, V6] # 쥥Ⴎ.⒈⒈𐫒
+쥥󔏉Ⴎ.\u200C1.1.𐫒; ; [B1, C1, V6]; xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; ; xn--mnd7865gcy28g.1.1.xn--7w9c; [B1, V6] # 쥥Ⴎ.1.1.𐫒
+쥥󔏉Ⴎ.\u200C1.1.𐫒; 쥥󔏉Ⴎ.\u200C1.1.𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; ; xn--mnd7865gcy28g.1.1.xn--7w9c; [B1, V6] # 쥥Ⴎ.1.1.𐫒
+쥥󔏉ⴎ.\u200C1.1.𐫒; 쥥󔏉ⴎ.\u200C1.1.𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; ; xn--5kj3511ccyw3h.1.1.xn--7w9c; [B1, V6] # 쥥ⴎ.1.1.𐫒
+쥥󔏉ⴎ.\u200C1.1.𐫒; ; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; ; xn--5kj3511ccyw3h.1.1.xn--7w9c; [B1, V6] # 쥥ⴎ.1.1.𐫒
+xn--5kj3511ccyw3h.1.1.xn--7w9c; 쥥󔏉ⴎ.1.1.𐫒; [B1, V6]; xn--5kj3511ccyw3h.1.1.xn--7w9c; ; ; # 쥥ⴎ.1.1.𐫒
+xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; 쥥󔏉ⴎ.\u200C1.1.𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; ; ; # 쥥ⴎ.1.1.𐫒
+xn--mnd7865gcy28g.1.1.xn--7w9c; 쥥󔏉Ⴎ.1.1.𐫒; [B1, V6]; xn--mnd7865gcy28g.1.1.xn--7w9c; ; ; # 쥥Ⴎ.1.1.𐫒
+xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; 쥥󔏉Ⴎ.\u200C1.1.𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; ; ; # 쥥Ⴎ.1.1.𐫒
+쥥󔏉ⴎ.\u200C⒈⒈𐫒; 쥥󔏉ⴎ.\u200C⒈⒈𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--0ug88oa0396u; ; xn--5kj3511ccyw3h.xn--tsha6797o; [B1, V6] # 쥥ⴎ.⒈⒈𐫒
+쥥󔏉ⴎ.\u200C⒈⒈𐫒; 쥥󔏉ⴎ.\u200C⒈⒈𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--0ug88oa0396u; ; xn--5kj3511ccyw3h.xn--tsha6797o; [B1, V6] # 쥥ⴎ.⒈⒈𐫒
+xn--5kj3511ccyw3h.xn--tsha6797o; 쥥󔏉ⴎ.⒈⒈𐫒; [B1, V6]; xn--5kj3511ccyw3h.xn--tsha6797o; ; ; # 쥥ⴎ.⒈⒈𐫒
+xn--5kj3511ccyw3h.xn--0ug88oa0396u; 쥥󔏉ⴎ.\u200C⒈⒈𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--0ug88oa0396u; ; ; # 쥥ⴎ.⒈⒈𐫒
+xn--mnd7865gcy28g.xn--tsha6797o; 쥥󔏉Ⴎ.⒈⒈𐫒; [B1, V6]; xn--mnd7865gcy28g.xn--tsha6797o; ; ; # 쥥Ⴎ.⒈⒈𐫒
+xn--mnd7865gcy28g.xn--0ug88oa0396u; 쥥󔏉Ⴎ.\u200C⒈⒈𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--0ug88oa0396u; ; ; # 쥥Ⴎ.⒈⒈𐫒
+\u0827𝟶\u06A0-。𑄳; \u08270\u06A0-.𑄳; [B1, V3, V5]; xn--0--p3d67m.xn--v80d; ; ; # ࠧ0ڠ-.𑄳
+\u08270\u06A0-。𑄳; \u08270\u06A0-.𑄳; [B1, V3, V5]; xn--0--p3d67m.xn--v80d; ; ; # ࠧ0ڠ-.𑄳
+xn--0--p3d67m.xn--v80d; \u08270\u06A0-.𑄳; [B1, V3, V5]; xn--0--p3d67m.xn--v80d; ; ; # ࠧ0ڠ-.𑄳
+ς.\uFDC1🞛⒈; ς.\u0641\u0645\u064A🞛⒈; [V6]; xn--3xa.xn--dhbip2802atb20c; ; xn--4xa.xn--dhbip2802atb20c; # ς.فمي🞛⒈
+ς.\u0641\u0645\u064A🞛1.; ; ; xn--3xa.xn--1-gocmu97674d.; ; xn--4xa.xn--1-gocmu97674d.; # ς.فمي🞛1.
+Σ.\u0641\u0645\u064A🞛1.; σ.\u0641\u0645\u064A🞛1.; ; xn--4xa.xn--1-gocmu97674d.; ; ; # σ.فمي🞛1.
+σ.\u0641\u0645\u064A🞛1.; ; ; xn--4xa.xn--1-gocmu97674d.; ; ; # σ.فمي🞛1.
+xn--4xa.xn--1-gocmu97674d.; σ.\u0641\u0645\u064A🞛1.; ; xn--4xa.xn--1-gocmu97674d.; ; ; # σ.فمي🞛1.
+xn--3xa.xn--1-gocmu97674d.; ς.\u0641\u0645\u064A🞛1.; ; xn--3xa.xn--1-gocmu97674d.; ; ; # ς.فمي🞛1.
+Σ.\uFDC1🞛⒈; σ.\u0641\u0645\u064A🞛⒈; [V6]; xn--4xa.xn--dhbip2802atb20c; ; ; # σ.فمي🞛⒈
+σ.\uFDC1🞛⒈; σ.\u0641\u0645\u064A🞛⒈; [V6]; xn--4xa.xn--dhbip2802atb20c; ; ; # σ.فمي🞛⒈
+xn--4xa.xn--dhbip2802atb20c; σ.\u0641\u0645\u064A🞛⒈; [V6]; xn--4xa.xn--dhbip2802atb20c; ; ; # σ.فمي🞛⒈
+xn--3xa.xn--dhbip2802atb20c; ς.\u0641\u0645\u064A🞛⒈; [V6]; xn--3xa.xn--dhbip2802atb20c; ; ; # ς.فمي🞛⒈
+🗩-。𐹻󐞆񥉮; 🗩-.𐹻󐞆񥉮; [B1, V3, V6]; xn----6t3s.xn--zo0d4811u6ru6a; ; ; # 🗩-.𐹻
+🗩-。𐹻󐞆񥉮; 🗩-.𐹻󐞆񥉮; [B1, V3, V6]; xn----6t3s.xn--zo0d4811u6ru6a; ; ; # 🗩-.𐹻
+xn----6t3s.xn--zo0d4811u6ru6a; 🗩-.𐹻󐞆񥉮; [B1, V3, V6]; xn----6t3s.xn--zo0d4811u6ru6a; ; ; # 🗩-.𐹻
+𐡜-🔪。𝟻\u200C𐿀; 𐡜-🔪.5\u200C𐿀; [B1, B3, C1]; xn----5j4iv089c.xn--5-sgn7149h; ; xn----5j4iv089c.xn--5-bn7i; [B1, B3] # 𐡜-🔪.5𐿀
+𐡜-🔪。5\u200C𐿀; 𐡜-🔪.5\u200C𐿀; [B1, B3, C1]; xn----5j4iv089c.xn--5-sgn7149h; ; xn----5j4iv089c.xn--5-bn7i; [B1, B3] # 𐡜-🔪.5𐿀
+xn----5j4iv089c.xn--5-bn7i; 𐡜-🔪.5𐿀; [B1, B3]; xn----5j4iv089c.xn--5-bn7i; ; ; # 𐡜-🔪.5𐿀
+xn----5j4iv089c.xn--5-sgn7149h; 𐡜-🔪.5\u200C𐿀; [B1, B3, C1]; xn----5j4iv089c.xn--5-sgn7149h; ; ; # 𐡜-🔪.5𐿀
+𐹣늿\u200Dß.\u07CF0\u05BC; 𐹣늿\u200Dß.\u07CF0\u05BC; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿\u200Dß.\u07CF0\u05BC; 𐹣늿\u200Dß.\u07CF0\u05BC; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿\u200Dß.\u07CF0\u05BC; ; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿\u200Dß.\u07CF0\u05BC; 𐹣늿\u200Dß.\u07CF0\u05BC; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿\u200DSS.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200DSS.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200Dss.\u07CF0\u05BC; ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200Dss.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+xn--ss-i05i7041a.xn--0-vgc50n; 𐹣늿ss.\u07CF0\u05BC; [B1]; xn--ss-i05i7041a.xn--0-vgc50n; ; ; # 𐹣늿ss.ߏ0ּ
+xn--ss-l1tu910fo0xd.xn--0-vgc50n; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; ; # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200DSs.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200DSs.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+xn--zca770n5s4hev6c.xn--0-vgc50n; 𐹣늿\u200Dß.\u07CF0\u05BC; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; ; # 𐹣늿ß.ߏ0ּ
+𐹣늿\u200DSS.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200DSS.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200Dss.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200Dss.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200DSs.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿\u200DSs.\u07CF0\u05BC; 𐹣늿\u200Dss.\u07CF0\u05BC; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+9󠇥.󪴴ᢓ; 9.󪴴ᢓ; [V6]; 9.xn--dbf91222q; ; ; # 9.ᢓ
+9󠇥.󪴴ᢓ; 9.󪴴ᢓ; [V6]; 9.xn--dbf91222q; ; ; # 9.ᢓ
+9.xn--dbf91222q; 9.󪴴ᢓ; [V6]; 9.xn--dbf91222q; ; ; # 9.ᢓ
+\u200C\uFFA0.𐫭🠗ß⽟; \u200C\uFFA0.𐫭🠗ß玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--zca2289c550e0iwi; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ß玉
+\u200C\u1160.𐫭🠗ß玉; ; [B1, B2, B3, C1, V6]; xn--psd526e.xn--zca2289c550e0iwi; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ß玉
+\u200C\u1160.𐫭🠗SS玉; \u200C\u1160.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ss玉
+\u200C\u1160.𐫭🠗ss玉; ; [B1, B2, B3, C1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ss玉
+\u200C\u1160.𐫭🠗Ss玉; \u200C\u1160.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ss玉
+xn--psd.xn--ss-je6eq954cp25j; \u1160.𐫭🠗ss玉; [B2, B3, V6]; xn--psd.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--psd526e.xn--ss-je6eq954cp25j; \u200C\u1160.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--psd526e.xn--zca2289c550e0iwi; \u200C\u1160.𐫭🠗ß玉; [B1, B2, B3, C1, V6]; xn--psd526e.xn--zca2289c550e0iwi; ; ; # .𐫭🠗ß玉
+\u200C\uFFA0.𐫭🠗SS⽟; \u200C\uFFA0.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ss玉
+\u200C\uFFA0.𐫭🠗ss⽟; \u200C\uFFA0.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ss玉
+\u200C\uFFA0.𐫭🠗Ss⽟; \u200C\uFFA0.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, V6] # .𐫭🠗ss玉
+xn--cl7c.xn--ss-je6eq954cp25j; \uFFA0.𐫭🠗ss玉; [B2, B3, V6]; xn--cl7c.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--0ug7719f.xn--ss-je6eq954cp25j; \u200C\uFFA0.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--0ug7719f.xn--zca2289c550e0iwi; \u200C\uFFA0.𐫭🠗ß玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--zca2289c550e0iwi; ; ; # .𐫭🠗ß玉
+︒Ⴖ\u0366.\u200C; ︒Ⴖ\u0366.\u200C; [C1, V6]; xn--hva929dl29p.xn--0ug; ; xn--hva929dl29p.; [V6] # ︒Ⴖͦ.
+。Ⴖ\u0366.\u200C; .Ⴖ\u0366.\u200C; [C1, V6, X4_2]; .xn--hva929d.xn--0ug; [C1, V6, A4_2]; .xn--hva929d.; [V6, A4_2] # .Ⴖͦ.
+。ⴖ\u0366.\u200C; .ⴖ\u0366.\u200C; [C1, X4_2]; .xn--hva754s.xn--0ug; [C1, A4_2]; .xn--hva754s.; [A4_2] # .ⴖͦ.
+.xn--hva754s.; .ⴖ\u0366.; [X4_2]; .xn--hva754s.; [A4_2]; ; # .ⴖͦ.
+.xn--hva754s.xn--0ug; .ⴖ\u0366.\u200C; [C1, X4_2]; .xn--hva754s.xn--0ug; [C1, A4_2]; ; # .ⴖͦ.
+.xn--hva929d.; .Ⴖ\u0366.; [V6, X4_2]; .xn--hva929d.; [V6, A4_2]; ; # .Ⴖͦ.
+.xn--hva929d.xn--0ug; .Ⴖ\u0366.\u200C; [C1, V6, X4_2]; .xn--hva929d.xn--0ug; [C1, V6, A4_2]; ; # .Ⴖͦ.
+︒ⴖ\u0366.\u200C; ︒ⴖ\u0366.\u200C; [C1, V6]; xn--hva754sy94k.xn--0ug; ; xn--hva754sy94k.; [V6] # ︒ⴖͦ.
+xn--hva754sy94k.; ︒ⴖ\u0366.; [V6]; xn--hva754sy94k.; ; ; # ︒ⴖͦ.
+xn--hva754sy94k.xn--0ug; ︒ⴖ\u0366.\u200C; [C1, V6]; xn--hva754sy94k.xn--0ug; ; ; # ︒ⴖͦ.
+xn--hva929dl29p.; ︒Ⴖ\u0366.; [V6]; xn--hva929dl29p.; ; ; # ︒Ⴖͦ.
+xn--hva929dl29p.xn--0ug; ︒Ⴖ\u0366.\u200C; [C1, V6]; xn--hva929dl29p.xn--0ug; ; ; # ︒Ⴖͦ.
+xn--hva754s.; ⴖ\u0366.; ; xn--hva754s.; ; ; # ⴖͦ.
+ⴖ\u0366.; ; ; xn--hva754s.; ; ; # ⴖͦ.
+Ⴖ\u0366.; ; [V6]; xn--hva929d.; ; ; # Ⴖͦ.
+xn--hva929d.; Ⴖ\u0366.; [V6]; xn--hva929d.; ; ; # Ⴖͦ.
+\u08BB.\u200CႣ𞀒; \u08BB.\u200CႣ𞀒; [B1, C1, V6]; xn--hzb.xn--bnd300f7225a; ; xn--hzb.xn--bnd2938u; [V6] # ࢻ.Ⴃ𞀒
+\u08BB.\u200CႣ𞀒; ; [B1, C1, V6]; xn--hzb.xn--bnd300f7225a; ; xn--hzb.xn--bnd2938u; [V6] # ࢻ.Ⴃ𞀒
+\u08BB.\u200Cⴃ𞀒; ; [B1, C1]; xn--hzb.xn--0ug822cp045a; ; xn--hzb.xn--ukj4430l; [] # ࢻ.ⴃ𞀒
+xn--hzb.xn--ukj4430l; \u08BB.ⴃ𞀒; ; xn--hzb.xn--ukj4430l; ; ; # ࢻ.ⴃ𞀒
+\u08BB.ⴃ𞀒; ; ; xn--hzb.xn--ukj4430l; ; ; # ࢻ.ⴃ𞀒
+\u08BB.Ⴃ𞀒; ; [V6]; xn--hzb.xn--bnd2938u; ; ; # ࢻ.Ⴃ𞀒
+xn--hzb.xn--bnd2938u; \u08BB.Ⴃ𞀒; [V6]; xn--hzb.xn--bnd2938u; ; ; # ࢻ.Ⴃ𞀒
+xn--hzb.xn--0ug822cp045a; \u08BB.\u200Cⴃ𞀒; [B1, C1]; xn--hzb.xn--0ug822cp045a; ; ; # ࢻ.ⴃ𞀒
+xn--hzb.xn--bnd300f7225a; \u08BB.\u200CႣ𞀒; [B1, C1, V6]; xn--hzb.xn--bnd300f7225a; ; ; # ࢻ.Ⴃ𞀒
+\u08BB.\u200Cⴃ𞀒; \u08BB.\u200Cⴃ𞀒; [B1, C1]; xn--hzb.xn--0ug822cp045a; ; xn--hzb.xn--ukj4430l; [] # ࢻ.ⴃ𞀒
+\u200D\u200C。2䫷󠧷; \u200D\u200C.2䫷󠧷; [C1, C2, V6]; xn--0ugb.xn--2-me5ay1273i; ; .xn--2-me5ay1273i; [V6, A4_2] # .2䫷
+\u200D\u200C。2䫷󠧷; \u200D\u200C.2䫷󠧷; [C1, C2, V6]; xn--0ugb.xn--2-me5ay1273i; ; .xn--2-me5ay1273i; [V6, A4_2] # .2䫷
+.xn--2-me5ay1273i; .2䫷󠧷; [V6, X4_2]; .xn--2-me5ay1273i; [V6, A4_2]; ; # .2䫷
+xn--0ugb.xn--2-me5ay1273i; \u200D\u200C.2䫷󠧷; [C1, C2, V6]; xn--0ugb.xn--2-me5ay1273i; ; ; # .2䫷
+-𞀤󜠐。򈬖; -𞀤󜠐.򈬖; [V3, V6]; xn----rq4re4997d.xn--l707b; ; ; # -𞀤.
+xn----rq4re4997d.xn--l707b; -𞀤󜠐.򈬖; [V3, V6]; xn----rq4re4997d.xn--l707b; ; ; # -𞀤.
+󳛂︒\u200C㟀.\u0624⒈; 󳛂︒\u200C㟀.\u0624⒈; [C1, V6]; xn--0ug754gxl4ldlt0k.xn--jgb476m; ; xn--etlt457ccrq7h.xn--jgb476m; [V6] # ︒㟀.ؤ⒈
+󳛂︒\u200C㟀.\u0648\u0654⒈; 󳛂︒\u200C㟀.\u0624⒈; [C1, V6]; xn--0ug754gxl4ldlt0k.xn--jgb476m; ; xn--etlt457ccrq7h.xn--jgb476m; [V6] # ︒㟀.ؤ⒈
+󳛂。\u200C㟀.\u06241.; 󳛂.\u200C㟀.\u06241.; [B1, C1, V6]; xn--z272f.xn--0ug754g.xn--1-smc.; ; xn--z272f.xn--etl.xn--1-smc.; [V6] # .㟀.ؤ1.
+󳛂。\u200C㟀.\u0648\u06541.; 󳛂.\u200C㟀.\u06241.; [B1, C1, V6]; xn--z272f.xn--0ug754g.xn--1-smc.; ; xn--z272f.xn--etl.xn--1-smc.; [V6] # .㟀.ؤ1.
+xn--z272f.xn--etl.xn--1-smc.; 󳛂.㟀.\u06241.; [V6]; xn--z272f.xn--etl.xn--1-smc.; ; ; # .㟀.ؤ1.
+xn--z272f.xn--0ug754g.xn--1-smc.; 󳛂.\u200C㟀.\u06241.; [B1, C1, V6]; xn--z272f.xn--0ug754g.xn--1-smc.; ; ; # .㟀.ؤ1.
+xn--etlt457ccrq7h.xn--jgb476m; 󳛂︒㟀.\u0624⒈; [V6]; xn--etlt457ccrq7h.xn--jgb476m; ; ; # ︒㟀.ؤ⒈
+xn--0ug754gxl4ldlt0k.xn--jgb476m; 󳛂︒\u200C㟀.\u0624⒈; [C1, V6]; xn--0ug754gxl4ldlt0k.xn--jgb476m; ; ; # ︒㟀.ؤ⒈
+𑲜\u07CA𝅼。-\u200D; 𑲜\u07CA𝅼.-\u200D; [B1, C2, V3, V5]; xn--lsb5482l7nre.xn----ugn; ; xn--lsb5482l7nre.-; [B1, V3, V5] # 𑲜ߊ𝅼.-
+xn--lsb5482l7nre.-; 𑲜\u07CA𝅼.-; [B1, V3, V5]; xn--lsb5482l7nre.-; ; ; # 𑲜ߊ𝅼.-
+xn--lsb5482l7nre.xn----ugn; 𑲜\u07CA𝅼.-\u200D; [B1, C2, V3, V5]; xn--lsb5482l7nre.xn----ugn; ; ; # 𑲜ߊ𝅼.-
+\u200C.Ⴉ≠𐫶; \u200C.Ⴉ≠𐫶; [B1, B5, B6, C1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, V6, A4_2] # .Ⴉ≠𐫶
+\u200C.Ⴉ=\u0338𐫶; \u200C.Ⴉ≠𐫶; [B1, B5, B6, C1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, V6, A4_2] # .Ⴉ≠𐫶
+\u200C.Ⴉ≠𐫶; ; [B1, B5, B6, C1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, V6, A4_2] # .Ⴉ≠𐫶
+\u200C.Ⴉ=\u0338𐫶; \u200C.Ⴉ≠𐫶; [B1, B5, B6, C1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, V6, A4_2] # .Ⴉ≠𐫶
+\u200C.ⴉ=\u0338𐫶; \u200C.ⴉ≠𐫶; [B1, B5, B6, C1]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, A4_2] # .ⴉ≠𐫶
+\u200C.ⴉ≠𐫶; ; [B1, B5, B6, C1]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, A4_2] # .ⴉ≠𐫶
+.xn--1chx23bzj4p; .ⴉ≠𐫶; [B5, B6, X4_2]; .xn--1chx23bzj4p; [B5, B6, A4_2]; ; # .ⴉ≠𐫶
+xn--0ug.xn--1chx23bzj4p; \u200C.ⴉ≠𐫶; [B1, B5, B6, C1]; xn--0ug.xn--1chx23bzj4p; ; ; # .ⴉ≠𐫶
+.xn--hnd481gv73o; .Ⴉ≠𐫶; [B5, B6, V6, X4_2]; .xn--hnd481gv73o; [B5, B6, V6, A4_2]; ; # .Ⴉ≠𐫶
+xn--0ug.xn--hnd481gv73o; \u200C.Ⴉ≠𐫶; [B1, B5, B6, C1, V6]; xn--0ug.xn--hnd481gv73o; ; ; # .Ⴉ≠𐫶
+\u200C.ⴉ=\u0338𐫶; \u200C.ⴉ≠𐫶; [B1, B5, B6, C1]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, A4_2] # .ⴉ≠𐫶
+\u200C.ⴉ≠𐫶; \u200C.ⴉ≠𐫶; [B1, B5, B6, C1]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, A4_2] # .ⴉ≠𐫶
+\u0750。≯ς; \u0750.≯ς; [B1]; xn--3ob.xn--3xa918m; ; xn--3ob.xn--4xa718m; # ݐ.≯ς
+\u0750。>\u0338ς; \u0750.≯ς; [B1]; xn--3ob.xn--3xa918m; ; xn--3ob.xn--4xa718m; # ݐ.≯ς
+\u0750。>\u0338Σ; \u0750.≯σ; [B1]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+\u0750。≯Σ; \u0750.≯σ; [B1]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+\u0750。≯σ; \u0750.≯σ; [B1]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+\u0750。>\u0338σ; \u0750.≯σ; [B1]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+xn--3ob.xn--4xa718m; \u0750.≯σ; [B1]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+xn--3ob.xn--3xa918m; \u0750.≯ς; [B1]; xn--3ob.xn--3xa918m; ; ; # ݐ.≯ς
+\u07FC𐸆.𓖏︒񊨩Ⴐ; ; [V6]; xn--0tb8725k.xn--ond3562jt18a7py9c; ; ; # .︒Ⴐ
+\u07FC𐸆.𓖏。񊨩Ⴐ; \u07FC𐸆.𓖏.񊨩Ⴐ; [V6]; xn--0tb8725k.xn--tu8d.xn--ond97931d; ; ; # ..Ⴐ
+\u07FC𐸆.𓖏。񊨩ⴐ; \u07FC𐸆.𓖏.񊨩ⴐ; [V6]; xn--0tb8725k.xn--tu8d.xn--7kj73887a; ; ; # ..ⴐ
+xn--0tb8725k.xn--tu8d.xn--7kj73887a; \u07FC𐸆.𓖏.񊨩ⴐ; [V6]; xn--0tb8725k.xn--tu8d.xn--7kj73887a; ; ; # ..ⴐ
+xn--0tb8725k.xn--tu8d.xn--ond97931d; \u07FC𐸆.𓖏.񊨩Ⴐ; [V6]; xn--0tb8725k.xn--tu8d.xn--ond97931d; ; ; # ..Ⴐ
+\u07FC𐸆.𓖏︒񊨩ⴐ; ; [V6]; xn--0tb8725k.xn--7kj9008dt18a7py9c; ; ; # .︒ⴐ
+xn--0tb8725k.xn--7kj9008dt18a7py9c; \u07FC𐸆.𓖏︒񊨩ⴐ; [V6]; xn--0tb8725k.xn--7kj9008dt18a7py9c; ; ; # .︒ⴐ
+xn--0tb8725k.xn--ond3562jt18a7py9c; \u07FC𐸆.𓖏︒񊨩Ⴐ; [V6]; xn--0tb8725k.xn--ond3562jt18a7py9c; ; ; # .︒Ⴐ
+Ⴥ⚭󠖫⋃。𑌼; Ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--9nd623g4zc5z060c.xn--ro1d; ; ; # Ⴥ⚭⋃.𑌼
+Ⴥ⚭󠖫⋃。𑌼; Ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--9nd623g4zc5z060c.xn--ro1d; ; ; # Ⴥ⚭⋃.𑌼
+ⴥ⚭󠖫⋃。𑌼; ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--vfh16m67gx1162b.xn--ro1d; ; ; # ⴥ⚭⋃.𑌼
+xn--vfh16m67gx1162b.xn--ro1d; ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--vfh16m67gx1162b.xn--ro1d; ; ; # ⴥ⚭⋃.𑌼
+xn--9nd623g4zc5z060c.xn--ro1d; Ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--9nd623g4zc5z060c.xn--ro1d; ; ; # Ⴥ⚭⋃.𑌼
+ⴥ⚭󠖫⋃。𑌼; ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--vfh16m67gx1162b.xn--ro1d; ; ; # ⴥ⚭⋃.𑌼
+🄈。󠷳\u0844; 🄈.󠷳\u0844; [B1, V6]; xn--107h.xn--2vb13094p; ; ; # 🄈.ࡄ
+7,。󠷳\u0844; 7,.󠷳\u0844; [B1, V6]; 7,.xn--2vb13094p; ; ; # 7,.ࡄ
+7,.xn--2vb13094p; 7,.󠷳\u0844; [B1, V6]; 7,.xn--2vb13094p; ; ; # 7,.ࡄ
+xn--107h.xn--2vb13094p; 🄈.󠷳\u0844; [B1, V6]; xn--107h.xn--2vb13094p; ; ; # 🄈.ࡄ
+≮\u0846。섖쮖ß; ≮\u0846.섖쮖ß; [B1]; xn--4vb505k.xn--zca7259goug; ; xn--4vb505k.xn--ss-5z4j006a; # ≮ࡆ.섖쮖ß
+<\u0338\u0846。섖쮖ß; ≮\u0846.섖쮖ß; [B1]; xn--4vb505k.xn--zca7259goug; ; xn--4vb505k.xn--ss-5z4j006a; # ≮ࡆ.섖쮖ß
+<\u0338\u0846。섖쮖SS; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮\u0846。섖쮖SS; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮\u0846。섖쮖ss; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+<\u0338\u0846。섖쮖ss; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+xn--4vb505k.xn--ss-5z4j006a; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮\u0846。섖쮖Ss; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+<\u0338\u0846。섖쮖Ss; ≮\u0846.섖쮖ss; [B1]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+xn--4vb505k.xn--zca7259goug; ≮\u0846.섖쮖ß; [B1]; xn--4vb505k.xn--zca7259goug; ; ; # ≮ࡆ.섖쮖ß
+󠆓⛏-。ꡒ; ⛏-.ꡒ; [V3]; xn----o9p.xn--rc9a; ; ; # ⛏-.ꡒ
+xn----o9p.xn--rc9a; ⛏-.ꡒ; [V3]; xn----o9p.xn--rc9a; ; ; # ⛏-.ꡒ
+\u07BB𐹳\u0626𑁆。\u08A7\u06B0\u200Cᢒ; \u07BB𐹳\u0626𑁆.\u08A7\u06B0\u200Cᢒ; [B2, B3, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1azih; ; xn--lgb32f2753cosb.xn--jkb91hlz1a; # 𐹳ئ𑁆.ࢧڰᢒ
+\u07BB𐹳\u064A𑁆\u0654。\u08A7\u06B0\u200Cᢒ; \u07BB𐹳\u0626𑁆.\u08A7\u06B0\u200Cᢒ; [B2, B3, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1azih; ; xn--lgb32f2753cosb.xn--jkb91hlz1a; # 𐹳ئ𑁆.ࢧڰᢒ
+xn--lgb32f2753cosb.xn--jkb91hlz1a; \u07BB𐹳\u0626𑁆.\u08A7\u06B0ᢒ; [B2, B3, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1a; ; ; # 𐹳ئ𑁆.ࢧڰᢒ
+xn--lgb32f2753cosb.xn--jkb91hlz1azih; \u07BB𐹳\u0626𑁆.\u08A7\u06B0\u200Cᢒ; [B2, B3, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1azih; ; ; # 𐹳ئ𑁆.ࢧڰᢒ
+\u0816.𐨕𚚕; ; [B1, B2, B3, V5, V6]; xn--rub.xn--tr9c248x; ; ; # ࠖ.𐨕
+xn--rub.xn--tr9c248x; \u0816.𐨕𚚕; [B1, B2, B3, V5, V6]; xn--rub.xn--tr9c248x; ; ; # ࠖ.𐨕
+--。𽊆\u0767𐽋𞠬; --.𽊆\u0767𐽋𞠬; [B1, B5, B6, V3, V6]; --.xn--rpb6226k77pfh58p; ; ; # --.ݧ𐽋𞠬
+--.xn--rpb6226k77pfh58p; --.𽊆\u0767𐽋𞠬; [B1, B5, B6, V3, V6]; --.xn--rpb6226k77pfh58p; ; ; # --.ݧ𐽋𞠬
+򛭦𐋥𹸐.≯\u08B0\u08A6󔛣; ; [B1, V6]; xn--887c2298i5mv6a.xn--vybt688qm8981a; ; ; # 𐋥.≯ࢰࢦ
+򛭦𐋥𹸐.>\u0338\u08B0\u08A6󔛣; 򛭦𐋥𹸐.≯\u08B0\u08A6󔛣; [B1, V6]; xn--887c2298i5mv6a.xn--vybt688qm8981a; ; ; # 𐋥.≯ࢰࢦ
+xn--887c2298i5mv6a.xn--vybt688qm8981a; 򛭦𐋥𹸐.≯\u08B0\u08A6󔛣; [B1, V6]; xn--887c2298i5mv6a.xn--vybt688qm8981a; ; ; # 𐋥.≯ࢰࢦ
+䔛󠇒򤸞𐹧.-䤷; 䔛򤸞𐹧.-䤷; [B1, B5, B6, V3, V6]; xn--2loy662coo60e.xn----0n4a; ; ; # 䔛𐹧.-䤷
+䔛󠇒򤸞𐹧.-䤷; 䔛򤸞𐹧.-䤷; [B1, B5, B6, V3, V6]; xn--2loy662coo60e.xn----0n4a; ; ; # 䔛𐹧.-䤷
+xn--2loy662coo60e.xn----0n4a; 䔛򤸞𐹧.-䤷; [B1, B5, B6, V3, V6]; xn--2loy662coo60e.xn----0n4a; ; ; # 䔛𐹧.-䤷
+𐹩.\u200D-; 𐹩.\u200D-; [B1, C2, V3]; xn--ho0d.xn----tgn; ; xn--ho0d.-; [B1, V3] # 𐹩.-
+𐹩.\u200D-; ; [B1, C2, V3]; xn--ho0d.xn----tgn; ; xn--ho0d.-; [B1, V3] # 𐹩.-
+xn--ho0d.-; 𐹩.-; [B1, V3]; xn--ho0d.-; ; ; # 𐹩.-
+xn--ho0d.xn----tgn; 𐹩.\u200D-; [B1, C2, V3]; xn--ho0d.xn----tgn; ; ; # 𐹩.-
+񂈦帷。≯萺\u1DC8-; 񂈦帷.≯萺\u1DC8-; [V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+񂈦帷。>\u0338萺\u1DC8-; 񂈦帷.≯萺\u1DC8-; [V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+񂈦帷。≯萺\u1DC8-; 񂈦帷.≯萺\u1DC8-; [V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+񂈦帷。>\u0338萺\u1DC8-; 񂈦帷.≯萺\u1DC8-; [V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+xn--qutw175s.xn----mimu6tf67j; 񂈦帷.≯萺\u1DC8-; [V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+\u200D攌\uABED。ᢖ-Ⴘ; \u200D攌\uABED.ᢖ-Ⴘ; [C2, V6]; xn--1ug592ykp6b.xn----k1g451d; ; xn--p9ut19m.xn----k1g451d; [V6] # 攌꯭.ᢖ-Ⴘ
+\u200D攌\uABED。ᢖ-ⴘ; \u200D攌\uABED.ᢖ-ⴘ; [C2]; xn--1ug592ykp6b.xn----mck373i; ; xn--p9ut19m.xn----mck373i; [] # 攌꯭.ᢖ-ⴘ
+xn--p9ut19m.xn----mck373i; 攌\uABED.ᢖ-ⴘ; ; xn--p9ut19m.xn----mck373i; ; ; # 攌꯭.ᢖ-ⴘ
+攌\uABED.ᢖ-ⴘ; ; ; xn--p9ut19m.xn----mck373i; ; ; # 攌꯭.ᢖ-ⴘ
+攌\uABED.ᢖ-Ⴘ; ; [V6]; xn--p9ut19m.xn----k1g451d; ; ; # 攌꯭.ᢖ-Ⴘ
+xn--p9ut19m.xn----k1g451d; 攌\uABED.ᢖ-Ⴘ; [V6]; xn--p9ut19m.xn----k1g451d; ; ; # 攌꯭.ᢖ-Ⴘ
+xn--1ug592ykp6b.xn----mck373i; \u200D攌\uABED.ᢖ-ⴘ; [C2]; xn--1ug592ykp6b.xn----mck373i; ; ; # 攌꯭.ᢖ-ⴘ
+xn--1ug592ykp6b.xn----k1g451d; \u200D攌\uABED.ᢖ-Ⴘ; [C2, V6]; xn--1ug592ykp6b.xn----k1g451d; ; ; # 攌꯭.ᢖ-Ⴘ
+\u200Cꖨ.⒗3툒۳; \u200Cꖨ.⒗3툒۳; [C1, V6]; xn--0ug2473c.xn--3-nyc678tu07m; ; xn--9r8a.xn--3-nyc678tu07m; [V6] # ꖨ.⒗3툒۳
+\u200Cꖨ.⒗3툒۳; \u200Cꖨ.⒗3툒۳; [C1, V6]; xn--0ug2473c.xn--3-nyc678tu07m; ; xn--9r8a.xn--3-nyc678tu07m; [V6] # ꖨ.⒗3툒۳
+\u200Cꖨ.16.3툒۳; ; [C1]; xn--0ug2473c.16.xn--3-nyc0117m; ; xn--9r8a.16.xn--3-nyc0117m; [] # ꖨ.16.3툒۳
+\u200Cꖨ.16.3툒۳; \u200Cꖨ.16.3툒۳; [C1]; xn--0ug2473c.16.xn--3-nyc0117m; ; xn--9r8a.16.xn--3-nyc0117m; [] # ꖨ.16.3툒۳
+xn--9r8a.16.xn--3-nyc0117m; ꖨ.16.3툒۳; ; xn--9r8a.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+ꖨ.16.3툒۳; ; ; xn--9r8a.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+ꖨ.16.3툒۳; ꖨ.16.3툒۳; ; xn--9r8a.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+xn--0ug2473c.16.xn--3-nyc0117m; \u200Cꖨ.16.3툒۳; [C1]; xn--0ug2473c.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+xn--9r8a.xn--3-nyc678tu07m; ꖨ.⒗3툒۳; [V6]; xn--9r8a.xn--3-nyc678tu07m; ; ; # ꖨ.⒗3툒۳
+xn--0ug2473c.xn--3-nyc678tu07m; \u200Cꖨ.⒗3툒۳; [C1, V6]; xn--0ug2473c.xn--3-nyc678tu07m; ; ; # ꖨ.⒗3툒۳
+⒈걾6.𐱁\u06D0; ; [B1, V6]; xn--6-dcps419c.xn--glb1794k; ; ; # ⒈걾6.𐱁ې
+⒈걾6.𐱁\u06D0; ⒈걾6.𐱁\u06D0; [B1, V6]; xn--6-dcps419c.xn--glb1794k; ; ; # ⒈걾6.𐱁ې
+1.걾6.𐱁\u06D0; ; [B1]; 1.xn--6-945e.xn--glb1794k; ; ; # 1.걾6.𐱁ې
+1.걾6.𐱁\u06D0; 1.걾6.𐱁\u06D0; [B1]; 1.xn--6-945e.xn--glb1794k; ; ; # 1.걾6.𐱁ې
+1.xn--6-945e.xn--glb1794k; 1.걾6.𐱁\u06D0; [B1]; 1.xn--6-945e.xn--glb1794k; ; ; # 1.걾6.𐱁ې
+xn--6-dcps419c.xn--glb1794k; ⒈걾6.𐱁\u06D0; [B1, V6]; xn--6-dcps419c.xn--glb1794k; ; ; # ⒈걾6.𐱁ې
+𐲞𝟶≮≮.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐲞𝟶<\u0338<\u0338.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐲞0≮≮.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐲞0<\u0338<\u0338.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞0<\u0338<\u0338.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞0≮≮.󠀧\u0639; ; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+xn--0-ngoa5711v.xn--4gb31034p; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞𝟶<\u0338<\u0338.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞𝟶≮≮.󠀧\u0639; 𐳞0≮≮.󠀧\u0639; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+\u0AE3.𐹺\u115F; ; [B1, V5, V6]; xn--8fc.xn--osd3070k; ; ; # ૣ.𐹺
+xn--8fc.xn--osd3070k; \u0AE3.𐹺\u115F; [B1, V5, V6]; xn--8fc.xn--osd3070k; ; ; # ૣ.𐹺
+𝟏𝨙⸖.\u200D; 1𝨙⸖.\u200D; [C2]; xn--1-5bt6845n.xn--1ug; ; xn--1-5bt6845n.; [] # 1𝨙⸖.
+1𝨙⸖.\u200D; ; [C2]; xn--1-5bt6845n.xn--1ug; ; xn--1-5bt6845n.; [] # 1𝨙⸖.
+xn--1-5bt6845n.; 1𝨙⸖.; ; xn--1-5bt6845n.; ; ; # 1𝨙⸖.
+1𝨙⸖.; ; ; xn--1-5bt6845n.; ; ; # 1𝨙⸖.
+xn--1-5bt6845n.xn--1ug; 1𝨙⸖.\u200D; [C2]; xn--1-5bt6845n.xn--1ug; ; ; # 1𝨙⸖.
+𞤐≠\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𞤐=\u0338\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𞤐≠\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𞤐=\u0338\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𞤲=\u0338\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𞤲≠\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+xn--wnb859grzfzw60c.xn----kcd; 𞤲≠\u0726\u1A60.-\u07D5; [B1, V3]; xn--wnb859grzfzw60c.xn----kcd; ; ; # 𞤲≠ܦ᩠.-ߕ
+xn--wnb859grzfzw60c.xn----kcd017p; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; ; # 𞤲≠ܦ᩠.-ߕ
+𞤲=\u0338\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𞤲≠\u0726\u1A60。-\u200C\u07D5; 𞤲≠\u0726\u1A60.-\u200C\u07D5; [B1, C1, V3]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, V3] # 𞤲≠ܦ᩠.-ߕ
+𐹰\u0368-ꡧ。\u0675; 𐹰\u0368-ꡧ.\u0627\u0674; [B1]; xn----shb2387jgkqd.xn--mgb8m; ; ; # 𐹰ͨ-ꡧ.اٴ
+𐹰\u0368-ꡧ。\u0627\u0674; 𐹰\u0368-ꡧ.\u0627\u0674; [B1]; xn----shb2387jgkqd.xn--mgb8m; ; ; # 𐹰ͨ-ꡧ.اٴ
+xn----shb2387jgkqd.xn--mgb8m; 𐹰\u0368-ꡧ.\u0627\u0674; [B1]; xn----shb2387jgkqd.xn--mgb8m; ; ; # 𐹰ͨ-ꡧ.اٴ
+F󠅟。򏗅♚; f.򏗅♚; [V6]; f.xn--45hz6953f; ; ; # f.♚
+F󠅟。򏗅♚; f.򏗅♚; [V6]; f.xn--45hz6953f; ; ; # f.♚
+f󠅟。򏗅♚; f.򏗅♚; [V6]; f.xn--45hz6953f; ; ; # f.♚
+f.xn--45hz6953f; f.򏗅♚; [V6]; f.xn--45hz6953f; ; ; # f.♚
+f󠅟。򏗅♚; f.򏗅♚; [V6]; f.xn--45hz6953f; ; ; # f.♚
+\u0B4D𑄴\u1DE9。𝟮Ⴘ𞀨񃥇; \u0B4D𑄴\u1DE9.2Ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-k1g43076adrwq; ; ; # ୍𑄴ᷩ.2Ⴘ𞀨
+\u0B4D𑄴\u1DE9。2Ⴘ𞀨񃥇; \u0B4D𑄴\u1DE9.2Ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-k1g43076adrwq; ; ; # ୍𑄴ᷩ.2Ⴘ𞀨
+\u0B4D𑄴\u1DE9。2ⴘ𞀨񃥇; \u0B4D𑄴\u1DE9.2ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-nws2918ndrjr; ; ; # ୍𑄴ᷩ.2ⴘ𞀨
+xn--9ic246gs21p.xn--2-nws2918ndrjr; \u0B4D𑄴\u1DE9.2ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-nws2918ndrjr; ; ; # ୍𑄴ᷩ.2ⴘ𞀨
+xn--9ic246gs21p.xn--2-k1g43076adrwq; \u0B4D𑄴\u1DE9.2Ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-k1g43076adrwq; ; ; # ୍𑄴ᷩ.2Ⴘ𞀨
+\u0B4D𑄴\u1DE9。𝟮ⴘ𞀨񃥇; \u0B4D𑄴\u1DE9.2ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-nws2918ndrjr; ; ; # ୍𑄴ᷩ.2ⴘ𞀨
+򓠭\u200C\u200C⒈。勉𑁅; 򓠭\u200C\u200C⒈.勉𑁅; [C1, V6]; xn--0uga855aez302a.xn--4grs325b; ; xn--tsh11906f.xn--4grs325b; [V6] # ⒈.勉𑁅
+򓠭\u200C\u200C1.。勉𑁅; 򓠭\u200C\u200C1..勉𑁅; [C1, V6, X4_2]; xn--1-rgna61159u..xn--4grs325b; [C1, V6, A4_2]; xn--1-yi00h..xn--4grs325b; [V6, A4_2] # 1..勉𑁅
+xn--1-yi00h..xn--4grs325b; 򓠭1..勉𑁅; [V6, X4_2]; xn--1-yi00h..xn--4grs325b; [V6, A4_2]; ; # 1..勉𑁅
+xn--1-rgna61159u..xn--4grs325b; 򓠭\u200C\u200C1..勉𑁅; [C1, V6, X4_2]; xn--1-rgna61159u..xn--4grs325b; [C1, V6, A4_2]; ; # 1..勉𑁅
+xn--tsh11906f.xn--4grs325b; 򓠭⒈.勉𑁅; [V6]; xn--tsh11906f.xn--4grs325b; ; ; # ⒈.勉𑁅
+xn--0uga855aez302a.xn--4grs325b; 򓠭\u200C\u200C⒈.勉𑁅; [C1, V6]; xn--0uga855aez302a.xn--4grs325b; ; ; # ⒈.勉𑁅
+ᡃ.玿񫈜󕞐; ; [V6]; xn--27e.xn--7cy81125a0yq4a; ; ; # ᡃ.玿
+xn--27e.xn--7cy81125a0yq4a; ᡃ.玿񫈜󕞐; [V6]; xn--27e.xn--7cy81125a0yq4a; ; ; # ᡃ.玿
+\u200C\u200C。⒈≯𝟵; \u200C\u200C.⒈≯9; [C1, V6]; xn--0uga.xn--9-ogo37g; ; .xn--9-ogo37g; [V6, A4_2] # .⒈≯9
+\u200C\u200C。⒈>\u0338𝟵; \u200C\u200C.⒈≯9; [C1, V6]; xn--0uga.xn--9-ogo37g; ; .xn--9-ogo37g; [V6, A4_2] # .⒈≯9
+\u200C\u200C。1.≯9; \u200C\u200C.1.≯9; [C1]; xn--0uga.1.xn--9-ogo; ; .1.xn--9-ogo; [A4_2] # .1.≯9
+\u200C\u200C。1.>\u03389; \u200C\u200C.1.≯9; [C1]; xn--0uga.1.xn--9-ogo; ; .1.xn--9-ogo; [A4_2] # .1.≯9
+.1.xn--9-ogo; .1.≯9; [X4_2]; .1.xn--9-ogo; [A4_2]; ; # .1.≯9
+xn--0uga.1.xn--9-ogo; \u200C\u200C.1.≯9; [C1]; xn--0uga.1.xn--9-ogo; ; ; # .1.≯9
+.xn--9-ogo37g; .⒈≯9; [V6, X4_2]; .xn--9-ogo37g; [V6, A4_2]; ; # .⒈≯9
+xn--0uga.xn--9-ogo37g; \u200C\u200C.⒈≯9; [C1, V6]; xn--0uga.xn--9-ogo37g; ; ; # .⒈≯9
+\u115F\u1DE0򐀁.𺻆≯𐮁; ; [B5, B6, V6]; xn--osd615d5659o.xn--hdh5192gkm6r; ; ; # ᷠ.≯𐮁
+\u115F\u1DE0򐀁.𺻆>\u0338𐮁; \u115F\u1DE0򐀁.𺻆≯𐮁; [B5, B6, V6]; xn--osd615d5659o.xn--hdh5192gkm6r; ; ; # ᷠ.≯𐮁
+xn--osd615d5659o.xn--hdh5192gkm6r; \u115F\u1DE0򐀁.𺻆≯𐮁; [B5, B6, V6]; xn--osd615d5659o.xn--hdh5192gkm6r; ; ; # ᷠ.≯𐮁
+󠄫𝩤\u200D\u063E.𝩩-\u081E󑼩; 𝩤\u200D\u063E.𝩩-\u081E󑼩; [B1, C2, V5, V6]; xn--9gb723kg862a.xn----qgd52296avol4f; ; xn--9gb5080v.xn----qgd52296avol4f; [B1, V5, V6] # 𝩤ؾ.𝩩-ࠞ
+xn--9gb5080v.xn----qgd52296avol4f; 𝩤\u063E.𝩩-\u081E󑼩; [B1, V5, V6]; xn--9gb5080v.xn----qgd52296avol4f; ; ; # 𝩤ؾ.𝩩-ࠞ
+xn--9gb723kg862a.xn----qgd52296avol4f; 𝩤\u200D\u063E.𝩩-\u081E󑼩; [B1, C2, V5, V6]; xn--9gb723kg862a.xn----qgd52296avol4f; ; ; # 𝩤ؾ.𝩩-ࠞ
+\u20DA.𑘿-; \u20DA.𑘿-; [V3, V5]; xn--w0g.xn----bd0j; ; ; # ⃚.𑘿-
+\u20DA.𑘿-; ; [V3, V5]; xn--w0g.xn----bd0j; ; ; # ⃚.𑘿-
+xn--w0g.xn----bd0j; \u20DA.𑘿-; [V3, V5]; xn--w0g.xn----bd0j; ; ; # ⃚.𑘿-
+䮸ß.󠵟󠭎紙\u08A8; ; [B1, V6]; xn--zca5349a.xn--xyb1370div70kpzba; ; xn--ss-sf1c.xn--xyb1370div70kpzba; # 䮸ß.紙ࢨ
+䮸SS.󠵟󠭎紙\u08A8; 䮸ss.󠵟󠭎紙\u08A8; [B1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+䮸ss.󠵟󠭎紙\u08A8; ; [B1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+䮸Ss.󠵟󠭎紙\u08A8; 䮸ss.󠵟󠭎紙\u08A8; [B1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+xn--ss-sf1c.xn--xyb1370div70kpzba; 䮸ss.󠵟󠭎紙\u08A8; [B1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+xn--zca5349a.xn--xyb1370div70kpzba; 䮸ß.󠵟󠭎紙\u08A8; [B1, V6]; xn--zca5349a.xn--xyb1370div70kpzba; ; ; # 䮸ß.紙ࢨ
+-Ⴞ.-𝩨⅔𐦕; -Ⴞ.-𝩨2⁄3𐦕; [B1, V3, V6]; xn----w1g.xn---23-pt0a0433lk3jj; ; ; # -Ⴞ.-𝩨2⁄3𐦕
+-Ⴞ.-𝩨2⁄3𐦕; ; [B1, V3, V6]; xn----w1g.xn---23-pt0a0433lk3jj; ; ; # -Ⴞ.-𝩨2⁄3𐦕
+-ⴞ.-𝩨2⁄3𐦕; ; [B1, V3]; xn----zws.xn---23-pt0a0433lk3jj; ; ; # -ⴞ.-𝩨2⁄3𐦕
+xn----zws.xn---23-pt0a0433lk3jj; -ⴞ.-𝩨2⁄3𐦕; [B1, V3]; xn----zws.xn---23-pt0a0433lk3jj; ; ; # -ⴞ.-𝩨2⁄3𐦕
+xn----w1g.xn---23-pt0a0433lk3jj; -Ⴞ.-𝩨2⁄3𐦕; [B1, V3, V6]; xn----w1g.xn---23-pt0a0433lk3jj; ; ; # -Ⴞ.-𝩨2⁄3𐦕
+-ⴞ.-𝩨⅔𐦕; -ⴞ.-𝩨2⁄3𐦕; [B1, V3]; xn----zws.xn---23-pt0a0433lk3jj; ; ; # -ⴞ.-𝩨2⁄3𐦕
+󧈯𐹯\u0AC2。򖢨𐮁񇼖ᡂ; 󧈯𐹯\u0AC2.򖢨𐮁񇼖ᡂ; [B5, B6, V6]; xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; ; ; # 𐹯ૂ.𐮁ᡂ
+󧈯𐹯\u0AC2。򖢨𐮁񇼖ᡂ; 󧈯𐹯\u0AC2.򖢨𐮁񇼖ᡂ; [B5, B6, V6]; xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; ; ; # 𐹯ૂ.𐮁ᡂ
+xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; 󧈯𐹯\u0AC2.򖢨𐮁񇼖ᡂ; [B5, B6, V6]; xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; ; ; # 𐹯ૂ.𐮁ᡂ
+\u1082-\u200D\uA8EA.ꡊ\u200D񼸳; \u1082-\u200D\uA8EA.ꡊ\u200D񼸳; [C2, V5, V6]; xn----gyg250jio7k.xn--1ug8774cri56d; ; xn----gyg3618i.xn--jc9ao4185a; [V5, V6] # ႂ-꣪.ꡊ
+\u1082-\u200D\uA8EA.ꡊ\u200D񼸳; ; [C2, V5, V6]; xn----gyg250jio7k.xn--1ug8774cri56d; ; xn----gyg3618i.xn--jc9ao4185a; [V5, V6] # ႂ-꣪.ꡊ
+xn----gyg3618i.xn--jc9ao4185a; \u1082-\uA8EA.ꡊ񼸳; [V5, V6]; xn----gyg3618i.xn--jc9ao4185a; ; ; # ႂ-꣪.ꡊ
+xn----gyg250jio7k.xn--1ug8774cri56d; \u1082-\u200D\uA8EA.ꡊ\u200D񼸳; [C2, V5, V6]; xn----gyg250jio7k.xn--1ug8774cri56d; ; ; # ႂ-꣪.ꡊ
+۱。≠\u0668; ۱.≠\u0668; [B1]; xn--emb.xn--hib334l; ; ; # ۱.≠٨
+۱。=\u0338\u0668; ۱.≠\u0668; [B1]; xn--emb.xn--hib334l; ; ; # ۱.≠٨
+xn--emb.xn--hib334l; ۱.≠\u0668; [B1]; xn--emb.xn--hib334l; ; ; # ۱.≠٨
+𑈵廊.𐠍; ; [V5]; xn--xytw701b.xn--yc9c; ; ; # 𑈵廊.𐠍
+xn--xytw701b.xn--yc9c; 𑈵廊.𐠍; [V5]; xn--xytw701b.xn--yc9c; ; ; # 𑈵廊.𐠍
+\u200D\u0356-.-Ⴐ\u0661; \u200D\u0356-.-Ⴐ\u0661; [B1, C2, V3, V6]; xn----rgb661t.xn----bqc030f; ; xn----rgb.xn----bqc030f; [B1, V3, V5, V6] # ͖-.-Ⴐ١
+\u200D\u0356-.-Ⴐ\u0661; ; [B1, C2, V3, V6]; xn----rgb661t.xn----bqc030f; ; xn----rgb.xn----bqc030f; [B1, V3, V5, V6] # ͖-.-Ⴐ١
+\u200D\u0356-.-ⴐ\u0661; ; [B1, C2, V3]; xn----rgb661t.xn----bqc2280a; ; xn----rgb.xn----bqc2280a; [B1, V3, V5] # ͖-.-ⴐ١
+xn----rgb.xn----bqc2280a; \u0356-.-ⴐ\u0661; [B1, V3, V5]; xn----rgb.xn----bqc2280a; ; ; # ͖-.-ⴐ١
+xn----rgb661t.xn----bqc2280a; \u200D\u0356-.-ⴐ\u0661; [B1, C2, V3]; xn----rgb661t.xn----bqc2280a; ; ; # ͖-.-ⴐ١
+xn----rgb.xn----bqc030f; \u0356-.-Ⴐ\u0661; [B1, V3, V5, V6]; xn----rgb.xn----bqc030f; ; ; # ͖-.-Ⴐ١
+xn----rgb661t.xn----bqc030f; \u200D\u0356-.-Ⴐ\u0661; [B1, C2, V3, V6]; xn----rgb661t.xn----bqc030f; ; ; # ͖-.-Ⴐ١
+\u200D\u0356-.-ⴐ\u0661; \u200D\u0356-.-ⴐ\u0661; [B1, C2, V3]; xn----rgb661t.xn----bqc2280a; ; xn----rgb.xn----bqc2280a; [B1, V3, V5] # ͖-.-ⴐ١
+\u063A\u0661挏󾯐.-; ; [B1, B2, B3, V3, V6]; xn--5gb2f4205aqi47p.-; ; ; # غ١挏.-
+xn--5gb2f4205aqi47p.-; \u063A\u0661挏󾯐.-; [B1, B2, B3, V3, V6]; xn--5gb2f4205aqi47p.-; ; ; # غ١挏.-
+\u06EF。𐹧𞤽; \u06EF.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+\u06EF。𐹧𞤽; \u06EF.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+\u06EF。𐹧𞤛; \u06EF.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+xn--cmb.xn--fo0dy848a; \u06EF.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+\u06EF。𐹧𞤛; \u06EF.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+Ⴞ𶛀𛗻.ᢗ릫; Ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+Ⴞ𶛀𛗻.ᢗ릫; Ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+Ⴞ𶛀𛗻.ᢗ릫; ; [V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+Ⴞ𶛀𛗻.ᢗ릫; Ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ; [V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+xn--mlj0486jgl2j.xn--hbf6853f; ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+xn--2nd8876sgl2j.xn--hbf6853f; Ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+󠎃󗭞\u06B7𐹷。≯\u200C\u1DFE; 󠎃󗭞\u06B7𐹷.≯\u200C\u1DFE; [B1, C1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, V6] # ڷ𐹷.≯᷾
+󠎃󗭞\u06B7𐹷。>\u0338\u200C\u1DFE; 󠎃󗭞\u06B7𐹷.≯\u200C\u1DFE; [B1, C1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, V6] # ڷ𐹷.≯᷾
+󠎃󗭞\u06B7𐹷。≯\u200C\u1DFE; 󠎃󗭞\u06B7𐹷.≯\u200C\u1DFE; [B1, C1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, V6] # ڷ𐹷.≯᷾
+󠎃󗭞\u06B7𐹷。>\u0338\u200C\u1DFE; 󠎃󗭞\u06B7𐹷.≯\u200C\u1DFE; [B1, C1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, V6] # ڷ𐹷.≯᷾
+xn--qkb4516kbi06fg2id.xn--zfg31q; 󠎃󗭞\u06B7𐹷.≯\u1DFE; [B1, V6]; xn--qkb4516kbi06fg2id.xn--zfg31q; ; ; # ڷ𐹷.≯᷾
+xn--qkb4516kbi06fg2id.xn--zfg59fm0c; 󠎃󗭞\u06B7𐹷.≯\u200C\u1DFE; [B1, C1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; ; # ڷ𐹷.≯᷾
+ᛎ󠅍󠐕\u200D。𐹾𐹪𐻝-; ᛎ󠐕\u200D.𐹾𐹪𐻝-; [B1, B6, C2, V3, V6]; xn--fxe848bq3411a.xn----q26i2bvu; ; xn--fxe63563p.xn----q26i2bvu; [B1, B6, V3, V6] # ᛎ.𐹾𐹪-
+ᛎ󠅍󠐕\u200D。𐹾𐹪𐻝-; ᛎ󠐕\u200D.𐹾𐹪𐻝-; [B1, B6, C2, V3, V6]; xn--fxe848bq3411a.xn----q26i2bvu; ; xn--fxe63563p.xn----q26i2bvu; [B1, B6, V3, V6] # ᛎ.𐹾𐹪-
+xn--fxe63563p.xn----q26i2bvu; ᛎ󠐕.𐹾𐹪𐻝-; [B1, B6, V3, V6]; xn--fxe63563p.xn----q26i2bvu; ; ; # ᛎ.𐹾𐹪-
+xn--fxe848bq3411a.xn----q26i2bvu; ᛎ󠐕\u200D.𐹾𐹪𐻝-; [B1, B6, C2, V3, V6]; xn--fxe848bq3411a.xn----q26i2bvu; ; ; # ᛎ.𐹾𐹪-
+𐹶.𐫂; ; [B1]; xn--uo0d.xn--rw9c; ; ; # 𐹶.𐫂
+xn--uo0d.xn--rw9c; 𐹶.𐫂; [B1]; xn--uo0d.xn--rw9c; ; ; # 𐹶.𐫂
+ß\u200D\u103A。⒈; ß\u200D\u103A.⒈; [C2, V6]; xn--zca679eh2l.xn--tsh; ; xn--ss-f4j.xn--tsh; [V6] # ß်.⒈
+ß\u200D\u103A。1.; ß\u200D\u103A.1.; [C2]; xn--zca679eh2l.1.; ; xn--ss-f4j.1.; [] # ß်.1.
+SS\u200D\u103A。1.; ss\u200D\u103A.1.; [C2]; xn--ss-f4j585j.1.; ; xn--ss-f4j.1.; [] # ss်.1.
+ss\u200D\u103A。1.; ss\u200D\u103A.1.; [C2]; xn--ss-f4j585j.1.; ; xn--ss-f4j.1.; [] # ss်.1.
+Ss\u200D\u103A。1.; ss\u200D\u103A.1.; [C2]; xn--ss-f4j585j.1.; ; xn--ss-f4j.1.; [] # ss်.1.
+xn--ss-f4j.1.; ss\u103A.1.; ; xn--ss-f4j.1.; ; ; # ss်.1.
+ss\u103A.1.; ; ; xn--ss-f4j.1.; ; ; # ss်.1.
+SS\u103A.1.; ss\u103A.1.; ; xn--ss-f4j.1.; ; ; # ss်.1.
+Ss\u103A.1.; ss\u103A.1.; ; xn--ss-f4j.1.; ; ; # ss်.1.
+xn--ss-f4j585j.1.; ss\u200D\u103A.1.; [C2]; xn--ss-f4j585j.1.; ; ; # ss်.1.
+xn--zca679eh2l.1.; ß\u200D\u103A.1.; [C2]; xn--zca679eh2l.1.; ; ; # ß်.1.
+SS\u200D\u103A。⒈; ss\u200D\u103A.⒈; [C2, V6]; xn--ss-f4j585j.xn--tsh; ; xn--ss-f4j.xn--tsh; [V6] # ss်.⒈
+ss\u200D\u103A。⒈; ss\u200D\u103A.⒈; [C2, V6]; xn--ss-f4j585j.xn--tsh; ; xn--ss-f4j.xn--tsh; [V6] # ss်.⒈
+Ss\u200D\u103A。⒈; ss\u200D\u103A.⒈; [C2, V6]; xn--ss-f4j585j.xn--tsh; ; xn--ss-f4j.xn--tsh; [V6] # ss်.⒈
+xn--ss-f4j.xn--tsh; ss\u103A.⒈; [V6]; xn--ss-f4j.xn--tsh; ; ; # ss်.⒈
+xn--ss-f4j585j.xn--tsh; ss\u200D\u103A.⒈; [C2, V6]; xn--ss-f4j585j.xn--tsh; ; ; # ss်.⒈
+xn--zca679eh2l.xn--tsh; ß\u200D\u103A.⒈; [C2, V6]; xn--zca679eh2l.xn--tsh; ; ; # ß်.⒈
+\u0B4D\u200C𙶵𞻘。\u200D; \u0B4D\u200C𙶵𞻘.\u200D; [B1, C2, V5, V6]; xn--9ic637hz82z32jc.xn--1ug; ; xn--9ic6417rn4xb.; [B1, V5, V6] # ୍.
+xn--9ic6417rn4xb.; \u0B4D𙶵𞻘.; [B1, V5, V6]; xn--9ic6417rn4xb.; ; ; # ୍.
+xn--9ic637hz82z32jc.xn--1ug; \u0B4D\u200C𙶵𞻘.\u200D; [B1, C2, V5, V6]; xn--9ic637hz82z32jc.xn--1ug; ; ; # ୍.
+𐮅。\u06BC🁕; 𐮅.\u06BC🁕; [B3]; xn--c29c.xn--vkb8871w; ; ; # 𐮅.ڼ🁕
+𐮅。\u06BC🁕; 𐮅.\u06BC🁕; [B3]; xn--c29c.xn--vkb8871w; ; ; # 𐮅.ڼ🁕
+xn--c29c.xn--vkb8871w; 𐮅.\u06BC🁕; [B3]; xn--c29c.xn--vkb8871w; ; ; # 𐮅.ڼ🁕
+\u0620\u17D2。𐫔󠀧\u200C𑈵; \u0620\u17D2.𐫔󠀧\u200C𑈵; [B2, B3, C1, V6]; xn--fgb471g.xn--0ug9853g7verp838a; ; xn--fgb471g.xn--9w9c29jw3931a; [B2, B3, V6] # ؠ្.𐫔𑈵
+xn--fgb471g.xn--9w9c29jw3931a; \u0620\u17D2.𐫔󠀧𑈵; [B2, B3, V6]; xn--fgb471g.xn--9w9c29jw3931a; ; ; # ؠ្.𐫔𑈵
+xn--fgb471g.xn--0ug9853g7verp838a; \u0620\u17D2.𐫔󠀧\u200C𑈵; [B2, B3, C1, V6]; xn--fgb471g.xn--0ug9853g7verp838a; ; ; # ؠ្.𐫔𑈵
+񋉕.𞣕𞤊; 񋉕.𞣕𞤬; [B1, V5, V6]; xn--tf5w.xn--2b6hof; ; ; # .𞣕𞤬
+񋉕.𞣕𞤬; ; [B1, V5, V6]; xn--tf5w.xn--2b6hof; ; ; # .𞣕𞤬
+xn--tf5w.xn--2b6hof; 񋉕.𞣕𞤬; [B1, V5, V6]; xn--tf5w.xn--2b6hof; ; ; # .𞣕𞤬
+\u06CC𐨿.ß\u0F84𑍬; \u06CC𐨿.ß\u0F84𑍬; ; xn--clb2593k.xn--zca216edt0r; ; xn--clb2593k.xn--ss-toj6092t; # ی𐨿.ß྄𑍬
+\u06CC𐨿.ß\u0F84𑍬; ; ; xn--clb2593k.xn--zca216edt0r; ; xn--clb2593k.xn--ss-toj6092t; # ی𐨿.ß྄𑍬
+\u06CC𐨿.SS\u0F84𑍬; \u06CC𐨿.ss\u0F84𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+\u06CC𐨿.ss\u0F84𑍬; ; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+xn--clb2593k.xn--ss-toj6092t; \u06CC𐨿.ss\u0F84𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+xn--clb2593k.xn--zca216edt0r; \u06CC𐨿.ß\u0F84𑍬; ; xn--clb2593k.xn--zca216edt0r; ; ; # ی𐨿.ß྄𑍬
+\u06CC𐨿.SS\u0F84𑍬; \u06CC𐨿.ss\u0F84𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+\u06CC𐨿.ss\u0F84𑍬; \u06CC𐨿.ss\u0F84𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+\u06CC𐨿.Ss\u0F84𑍬; \u06CC𐨿.ss\u0F84𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+\u06CC𐨿.Ss\u0F84𑍬; \u06CC𐨿.ss\u0F84𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+𝟠≮\u200C。󠅱\u17B4; 8≮\u200C.\u17B4; [C1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [V5, V6] # 8≮.
+𝟠<\u0338\u200C。󠅱\u17B4; 8≮\u200C.\u17B4; [C1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [V5, V6] # 8≮.
+8≮\u200C。󠅱\u17B4; 8≮\u200C.\u17B4; [C1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [V5, V6] # 8≮.
+8<\u0338\u200C。󠅱\u17B4; 8≮\u200C.\u17B4; [C1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [V5, V6] # 8≮.
+xn--8-ngo.xn--z3e; 8≮.\u17B4; [V5, V6]; xn--8-ngo.xn--z3e; ; ; # 8≮.
+xn--8-sgn10i.xn--z3e; 8≮\u200C.\u17B4; [C1, V5, V6]; xn--8-sgn10i.xn--z3e; ; ; # 8≮.
+ᢕ≯︒񄂯.Ⴀ; ᢕ≯︒񄂯.Ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--7md; ; ; # ᢕ≯︒.Ⴀ
+ᢕ>\u0338︒񄂯.Ⴀ; ᢕ≯︒񄂯.Ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--7md; ; ; # ᢕ≯︒.Ⴀ
+ᢕ≯。񄂯.Ⴀ; ᢕ≯.񄂯.Ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--7md; ; ; # ᢕ≯..Ⴀ
+ᢕ>\u0338。񄂯.Ⴀ; ᢕ≯.񄂯.Ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--7md; ; ; # ᢕ≯..Ⴀ
+ᢕ>\u0338。񄂯.ⴀ; ᢕ≯.񄂯.ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--rkj; ; ; # ᢕ≯..ⴀ
+ᢕ≯。񄂯.ⴀ; ᢕ≯.񄂯.ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--rkj; ; ; # ᢕ≯..ⴀ
+xn--fbf851c.xn--ko1u.xn--rkj; ᢕ≯.񄂯.ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--rkj; ; ; # ᢕ≯..ⴀ
+xn--fbf851c.xn--ko1u.xn--7md; ᢕ≯.񄂯.Ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--7md; ; ; # ᢕ≯..Ⴀ
+ᢕ>\u0338︒񄂯.ⴀ; ᢕ≯︒񄂯.ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--rkj; ; ; # ᢕ≯︒.ⴀ
+ᢕ≯︒񄂯.ⴀ; ᢕ≯︒񄂯.ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--rkj; ; ; # ᢕ≯︒.ⴀ
+xn--fbf851cq98poxw1a.xn--rkj; ᢕ≯︒񄂯.ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--rkj; ; ; # ᢕ≯︒.ⴀ
+xn--fbf851cq98poxw1a.xn--7md; ᢕ≯︒񄂯.Ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--7md; ; ; # ᢕ≯︒.Ⴀ
+\u0F9F.-\u082A; \u0F9F.-\u082A; [V3, V5]; xn--vfd.xn----fhd; ; ; # ྟ.-ࠪ
+\u0F9F.-\u082A; ; [V3, V5]; xn--vfd.xn----fhd; ; ; # ྟ.-ࠪ
+xn--vfd.xn----fhd; \u0F9F.-\u082A; [V3, V5]; xn--vfd.xn----fhd; ; ; # ྟ.-ࠪ
+ᵬ󠆠.핒⒒⒈􈄦; ᵬ.핒⒒⒈􈄦; [V6]; xn--tbg.xn--tsht7586kyts9l; ; ; # ᵬ.핒⒒⒈
+ᵬ󠆠.핒⒒⒈􈄦; ᵬ.핒⒒⒈􈄦; [V6]; xn--tbg.xn--tsht7586kyts9l; ; ; # ᵬ.핒⒒⒈
+ᵬ󠆠.핒11.1.􈄦; ᵬ.핒11.1.􈄦; [V6]; xn--tbg.xn--11-5o7k.1.xn--k469f; ; ; # ᵬ.핒11.1.
+ᵬ󠆠.핒11.1.􈄦; ᵬ.핒11.1.􈄦; [V6]; xn--tbg.xn--11-5o7k.1.xn--k469f; ; ; # ᵬ.핒11.1.
+xn--tbg.xn--11-5o7k.1.xn--k469f; ᵬ.핒11.1.􈄦; [V6]; xn--tbg.xn--11-5o7k.1.xn--k469f; ; ; # ᵬ.핒11.1.
+xn--tbg.xn--tsht7586kyts9l; ᵬ.핒⒒⒈􈄦; [V6]; xn--tbg.xn--tsht7586kyts9l; ; ; # ᵬ.핒⒒⒈
+ς𑓂𐋢.\u0668; ς𑓂𐋢.\u0668; [B1]; xn--3xa8371khhl.xn--hib; ; xn--4xa6371khhl.xn--hib; # ς𑓂𐋢.٨
+ς𑓂𐋢.\u0668; ; [B1]; xn--3xa8371khhl.xn--hib; ; xn--4xa6371khhl.xn--hib; # ς𑓂𐋢.٨
+Σ𑓂𐋢.\u0668; σ𑓂𐋢.\u0668; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+σ𑓂𐋢.\u0668; ; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+xn--4xa6371khhl.xn--hib; σ𑓂𐋢.\u0668; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+xn--3xa8371khhl.xn--hib; ς𑓂𐋢.\u0668; [B1]; xn--3xa8371khhl.xn--hib; ; ; # ς𑓂𐋢.٨
+Σ𑓂𐋢.\u0668; σ𑓂𐋢.\u0668; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+σ𑓂𐋢.\u0668; σ𑓂𐋢.\u0668; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+\uA953\u200C𐋻\u200D.\u2DF8𞿄𐹲; ; [B1, B6, C2, V5, V6]; xn--0ugc8356he76c.xn--urju692efj0f; ; xn--3j9a531o.xn--urju692efj0f; [B1, V5, V6] # ꥓𐋻.ⷸ𐹲
+xn--3j9a531o.xn--urju692efj0f; \uA953𐋻.\u2DF8𞿄𐹲; [B1, V5, V6]; xn--3j9a531o.xn--urju692efj0f; ; ; # ꥓𐋻.ⷸ𐹲
+xn--0ugc8356he76c.xn--urju692efj0f; \uA953\u200C𐋻\u200D.\u2DF8𞿄𐹲; [B1, B6, C2, V5, V6]; xn--0ugc8356he76c.xn--urju692efj0f; ; ; # ꥓𐋻.ⷸ𐹲
+⊼。񪧖\u0695; ⊼.񪧖\u0695; [B1, B5, B6, V6]; xn--ofh.xn--rjb13118f; ; ; # ⊼.ڕ
+xn--ofh.xn--rjb13118f; ⊼.񪧖\u0695; [B1, B5, B6, V6]; xn--ofh.xn--rjb13118f; ; ; # ⊼.ڕ
+𐯬񖋔。󜳥; 𐯬񖋔.󜳥; [B2, B3, V6]; xn--949co370q.xn--7g25e; ; ; # .
+xn--949co370q.xn--7g25e; 𐯬񖋔.󜳥; [B2, B3, V6]; xn--949co370q.xn--7g25e; ; ; # .
+\u0601𑍧\u07DD。ς򬍘🀞\u17B5; \u0601𑍧\u07DD.ς򬍘🀞\u17B5; [B1, B6, V6]; xn--jfb66gt010c.xn--3xa823h9p95ars26d; ; xn--jfb66gt010c.xn--4xa623h9p95ars26d; # 𑍧ߝ.ς🀞
+\u0601𑍧\u07DD。Σ򬍘🀞\u17B5; \u0601𑍧\u07DD.σ򬍘🀞\u17B5; [B1, B6, V6]; xn--jfb66gt010c.xn--4xa623h9p95ars26d; ; ; # 𑍧ߝ.σ🀞
+\u0601𑍧\u07DD。σ򬍘🀞\u17B5; \u0601𑍧\u07DD.σ򬍘🀞\u17B5; [B1, B6, V6]; xn--jfb66gt010c.xn--4xa623h9p95ars26d; ; ; # 𑍧ߝ.σ🀞
+xn--jfb66gt010c.xn--4xa623h9p95ars26d; \u0601𑍧\u07DD.σ򬍘🀞\u17B5; [B1, B6, V6]; xn--jfb66gt010c.xn--4xa623h9p95ars26d; ; ; # 𑍧ߝ.σ🀞
+xn--jfb66gt010c.xn--3xa823h9p95ars26d; \u0601𑍧\u07DD.ς򬍘🀞\u17B5; [B1, B6, V6]; xn--jfb66gt010c.xn--3xa823h9p95ars26d; ; ; # 𑍧ߝ.ς🀞
+-𐳲\u0646󠺐。\uABED𝟥; -𐳲\u0646󠺐.\uABED3; [B1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+-𐳲\u0646󠺐。\uABED3; -𐳲\u0646󠺐.\uABED3; [B1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+-𐲲\u0646󠺐。\uABED3; -𐳲\u0646󠺐.\uABED3; [B1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+xn----roc5482rek10i.xn--3-zw5e; -𐳲\u0646󠺐.\uABED3; [B1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+-𐲲\u0646󠺐。\uABED𝟥; -𐳲\u0646󠺐.\uABED3; [B1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+\u200C󠴦。񲨕≮𐦜; \u200C󠴦.񲨕≮𐦜; [B1, B5, B6, C1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, V6] # .≮𐦜
+\u200C󠴦。񲨕<\u0338𐦜; \u200C󠴦.񲨕≮𐦜; [B1, B5, B6, C1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, V6] # .≮𐦜
+\u200C󠴦。񲨕≮𐦜; \u200C󠴦.񲨕≮𐦜; [B1, B5, B6, C1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, V6] # .≮𐦜
+\u200C󠴦。񲨕<\u0338𐦜; \u200C󠴦.񲨕≮𐦜; [B1, B5, B6, C1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, V6] # .≮𐦜
+xn--6v56e.xn--gdhz712gzlr6b; 󠴦.񲨕≮𐦜; [B1, B5, B6, V6]; xn--6v56e.xn--gdhz712gzlr6b; ; ; # .≮𐦜
+xn--0ug22251l.xn--gdhz712gzlr6b; \u200C󠴦.񲨕≮𐦜; [B1, B5, B6, C1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; ; # .≮𐦜
+⒈✌򟬟.𝟡񠱣; ⒈✌򟬟.9񠱣; [V6]; xn--tsh24g49550b.xn--9-o706d; ; ; # ⒈✌.9
+1.✌򟬟.9񠱣; ; [V6]; 1.xn--7bi44996f.xn--9-o706d; ; ; # 1.✌.9
+1.xn--7bi44996f.xn--9-o706d; 1.✌򟬟.9񠱣; [V6]; 1.xn--7bi44996f.xn--9-o706d; ; ; # 1.✌.9
+xn--tsh24g49550b.xn--9-o706d; ⒈✌򟬟.9񠱣; [V6]; xn--tsh24g49550b.xn--9-o706d; ; ; # ⒈✌.9
+𑆾𞤬𐮆.\u0666\u1DD4; ; [B1, V5]; xn--d29c79hf98r.xn--fib011j; ; ; # 𑆾𞤬𐮆.٦ᷔ
+𑆾𞤊𐮆.\u0666\u1DD4; 𑆾𞤬𐮆.\u0666\u1DD4; [B1, V5]; xn--d29c79hf98r.xn--fib011j; ; ; # 𑆾𞤬𐮆.٦ᷔ
+xn--d29c79hf98r.xn--fib011j; 𑆾𞤬𐮆.\u0666\u1DD4; [B1, V5]; xn--d29c79hf98r.xn--fib011j; ; ; # 𑆾𞤬𐮆.٦ᷔ
+ς.\uA9C0\uA8C4; ς.\uA9C0\uA8C4; [V5]; xn--3xa.xn--0f9ars; ; xn--4xa.xn--0f9ars; # ς.꧀꣄
+ς.\uA9C0\uA8C4; ; [V5]; xn--3xa.xn--0f9ars; ; xn--4xa.xn--0f9ars; # ς.꧀꣄
+Σ.\uA9C0\uA8C4; σ.\uA9C0\uA8C4; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+σ.\uA9C0\uA8C4; ; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+xn--4xa.xn--0f9ars; σ.\uA9C0\uA8C4; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+xn--3xa.xn--0f9ars; ς.\uA9C0\uA8C4; [V5]; xn--3xa.xn--0f9ars; ; ; # ς.꧀꣄
+Σ.\uA9C0\uA8C4; σ.\uA9C0\uA8C4; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+σ.\uA9C0\uA8C4; σ.\uA9C0\uA8C4; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+𑰶\u200C≯𐳐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+𑰶\u200C>\u0338𐳐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+𑰶\u200C≯𐳐.\u085B; ; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+𑰶\u200C>\u0338𐳐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+𑰶\u200C>\u0338𐲐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+𑰶\u200C≯𐲐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+xn--hdhz343g3wj.xn--qwb; 𑰶≯𐳐.\u085B; [B1, V5]; xn--hdhz343g3wj.xn--qwb; ; ; # 𑰶≯𐳐.࡛
+xn--0ug06g7697ap4ma.xn--qwb; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; ; # 𑰶≯𐳐.࡛
+𑰶\u200C>\u0338𐲐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+𑰶\u200C≯𐲐.\u085B; 𑰶\u200C≯𐳐.\u085B; [B1, C1, V5]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, V5] # 𑰶≯𐳐.࡛
+羚。≯; 羚.≯; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚。>\u0338; 羚.≯; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚。≯; 羚.≯; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚。>\u0338; 羚.≯; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+xn--xt0a.xn--hdh; 羚.≯; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚.≯; ; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚.>\u0338; 羚.≯; ; xn--xt0a.xn--hdh; ; ; # 羚.≯
+𑓂\u1759.\u08A8; 𑓂\u1759.\u08A8; [B1, V5, V6]; xn--e1e9580k.xn--xyb; ; ; # 𑓂.ࢨ
+𑓂\u1759.\u08A8; ; [B1, V5, V6]; xn--e1e9580k.xn--xyb; ; ; # 𑓂.ࢨ
+xn--e1e9580k.xn--xyb; 𑓂\u1759.\u08A8; [B1, V5, V6]; xn--e1e9580k.xn--xyb; ; ; # 𑓂.ࢨ
+󨣿󠇀\u200D。\u0663ҠჀ𝟑; 󨣿\u200D.\u0663ҡჀ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36kixu; ; xn--1r19e.xn--3-ozb36kixu; [B1, V6] # .٣ҡჀ3
+󨣿󠇀\u200D。\u0663ҠჀ3; 󨣿\u200D.\u0663ҡჀ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36kixu; ; xn--1r19e.xn--3-ozb36kixu; [B1, V6] # .٣ҡჀ3
+󨣿󠇀\u200D。\u0663ҡⴠ3; 󨣿\u200D.\u0663ҡⴠ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, V6] # .٣ҡⴠ3
+xn--1r19e.xn--3-ozb36ko13f; 󨣿.\u0663ҡⴠ3; [B1, V6]; xn--1r19e.xn--3-ozb36ko13f; ; ; # .٣ҡⴠ3
+xn--1ug89936l.xn--3-ozb36ko13f; 󨣿\u200D.\u0663ҡⴠ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; ; # .٣ҡⴠ3
+xn--1r19e.xn--3-ozb36kixu; 󨣿.\u0663ҡჀ3; [B1, V6]; xn--1r19e.xn--3-ozb36kixu; ; ; # .٣ҡჀ3
+xn--1ug89936l.xn--3-ozb36kixu; 󨣿\u200D.\u0663ҡჀ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36kixu; ; ; # .٣ҡჀ3
+󨣿󠇀\u200D。\u0663ҡⴠ𝟑; 󨣿\u200D.\u0663ҡⴠ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, V6] # .٣ҡⴠ3
+󨣿󠇀\u200D。\u0663Ҡⴠ3; 󨣿\u200D.\u0663ҡⴠ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, V6] # .٣ҡⴠ3
+󨣿󠇀\u200D。\u0663Ҡⴠ𝟑; 󨣿\u200D.\u0663ҡⴠ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, V6] # .٣ҡⴠ3
+ᡷ。𐹢\u08E0; ᡷ.𐹢\u08E0; [B1]; xn--k9e.xn--j0b5005k; ; ; # ᡷ.𐹢࣠
+xn--k9e.xn--j0b5005k; ᡷ.𐹢\u08E0; [B1]; xn--k9e.xn--j0b5005k; ; ; # ᡷ.𐹢࣠
+򕮇\u1BF3。\u0666񗜼\u17D2ß; 򕮇\u1BF3.\u0666񗜼\u17D2ß; [B1, V6]; xn--1zf58212h.xn--zca34zk4qx711k; ; xn--1zf58212h.xn--ss-pyd459o3258m; # ᯳.٦្ß
+򕮇\u1BF3。\u0666񗜼\u17D2ß; 򕮇\u1BF3.\u0666񗜼\u17D2ß; [B1, V6]; xn--1zf58212h.xn--zca34zk4qx711k; ; xn--1zf58212h.xn--ss-pyd459o3258m; # ᯳.٦្ß
+򕮇\u1BF3。\u0666񗜼\u17D2SS; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇\u1BF3。\u0666񗜼\u17D2ss; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇\u1BF3。\u0666񗜼\u17D2Ss; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+xn--1zf58212h.xn--ss-pyd459o3258m; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+xn--1zf58212h.xn--zca34zk4qx711k; 򕮇\u1BF3.\u0666񗜼\u17D2ß; [B1, V6]; xn--1zf58212h.xn--zca34zk4qx711k; ; ; # ᯳.٦្ß
+򕮇\u1BF3。\u0666񗜼\u17D2SS; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇\u1BF3。\u0666񗜼\u17D2ss; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇\u1BF3。\u0666񗜼\u17D2Ss; 򕮇\u1BF3.\u0666񗜼\u17D2ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+\u0664򤽎𑲛.󠔢︒≠; ; [B1, V6]; xn--dib0653l2i02d.xn--1ch7467f14u4g; ; ; # ٤𑲛.︒≠
+\u0664򤽎𑲛.󠔢︒=\u0338; \u0664򤽎𑲛.󠔢︒≠; [B1, V6]; xn--dib0653l2i02d.xn--1ch7467f14u4g; ; ; # ٤𑲛.︒≠
+\u0664򤽎𑲛.󠔢。≠; \u0664򤽎𑲛.󠔢.≠; [B1, V6]; xn--dib0653l2i02d.xn--k736e.xn--1ch; ; ; # ٤𑲛..≠
+\u0664򤽎𑲛.󠔢。=\u0338; \u0664򤽎𑲛.󠔢.≠; [B1, V6]; xn--dib0653l2i02d.xn--k736e.xn--1ch; ; ; # ٤𑲛..≠
+xn--dib0653l2i02d.xn--k736e.xn--1ch; \u0664򤽎𑲛.󠔢.≠; [B1, V6]; xn--dib0653l2i02d.xn--k736e.xn--1ch; ; ; # ٤𑲛..≠
+xn--dib0653l2i02d.xn--1ch7467f14u4g; \u0664򤽎𑲛.󠔢︒≠; [B1, V6]; xn--dib0653l2i02d.xn--1ch7467f14u4g; ; ; # ٤𑲛.︒≠
+➆񷧕ỗ⒈.򑬒񡘮\u085B𝟫; ➆񷧕ỗ⒈.򑬒񡘮\u085B9; [V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+➆񷧕o\u0302\u0303⒈.򑬒񡘮\u085B𝟫; ➆񷧕ỗ⒈.򑬒񡘮\u085B9; [V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+➆񷧕ỗ1..򑬒񡘮\u085B9; ; [V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕o\u0302\u03031..򑬒񡘮\u085B9; ➆񷧕ỗ1..򑬒񡘮\u085B9; [V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕O\u0302\u03031..򑬒񡘮\u085B9; ➆񷧕ỗ1..򑬒񡘮\u085B9; [V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕Ỗ1..򑬒񡘮\u085B9; ➆񷧕ỗ1..򑬒񡘮\u085B9; [V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [V6, A4_2]; ; # ➆ỗ1..࡛9
+xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; ➆񷧕ỗ1..򑬒񡘮\u085B9; [V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕O\u0302\u0303⒈.򑬒񡘮\u085B𝟫; ➆񷧕ỗ⒈.򑬒񡘮\u085B9; [V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+➆񷧕Ỗ⒈.򑬒񡘮\u085B𝟫; ➆񷧕ỗ⒈.򑬒񡘮\u085B9; [V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ➆񷧕ỗ⒈.򑬒񡘮\u085B9; [V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+\u200D。𞤘; \u200D.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+\u200D。𞤘; \u200D.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+\u200D。𞤺; \u200D.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+.xn--ye6h; .𞤺; [X4_2]; .xn--ye6h; [A4_2]; ; # .𞤺
+xn--1ug.xn--ye6h; \u200D.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; ; # .𞤺
+\u200D。𞤺; \u200D.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+xn--ye6h; 𞤺; ; xn--ye6h; ; ; # 𞤺
+𞤺; ; ; xn--ye6h; ; ; # 𞤺
+𞤘; 𞤺; ; xn--ye6h; ; ; # 𞤺
+\u0829\u0724.ᢣ; ; [B1, V5]; xn--unb53c.xn--tbf; ; ; # ࠩܤ.ᢣ
+xn--unb53c.xn--tbf; \u0829\u0724.ᢣ; [B1, V5]; xn--unb53c.xn--tbf; ; ; # ࠩܤ.ᢣ
+\u073C\u200C-。𓐾ß; \u073C\u200C-.𓐾ß; [C1, V3, V5, V6]; xn----s2c071q.xn--zca7848m; ; xn----s2c.xn--ss-066q; [V3, V5, V6] # ܼ-.ß
+\u073C\u200C-。𓐾SS; \u073C\u200C-.𓐾ss; [C1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; xn----s2c.xn--ss-066q; [V3, V5, V6] # ܼ-.ss
+\u073C\u200C-。𓐾ss; \u073C\u200C-.𓐾ss; [C1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; xn----s2c.xn--ss-066q; [V3, V5, V6] # ܼ-.ss
+\u073C\u200C-。𓐾Ss; \u073C\u200C-.𓐾ss; [C1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; xn----s2c.xn--ss-066q; [V3, V5, V6] # ܼ-.ss
+xn----s2c.xn--ss-066q; \u073C-.𓐾ss; [V3, V5, V6]; xn----s2c.xn--ss-066q; ; ; # ܼ-.ss
+xn----s2c071q.xn--ss-066q; \u073C\u200C-.𓐾ss; [C1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; ; # ܼ-.ss
+xn----s2c071q.xn--zca7848m; \u073C\u200C-.𓐾ß; [C1, V3, V5, V6]; xn----s2c071q.xn--zca7848m; ; ; # ܼ-.ß
+\u200Cς🃡⒗.\u0CC6仧\u0756; ; [B1, B5, B6, C1, V5, V6]; xn--3xa795lz9czy52d.xn--9ob79ycx2e; ; xn--4xa229nbu92a.xn--9ob79ycx2e; [B5, B6, V5, V6] # ς🃡⒗.ೆ仧ݖ
+\u200Cς🃡16..\u0CC6仧\u0756; ; [B1, B5, B6, C1, V5, X4_2]; xn--16-rbc1800avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2] # ς🃡16..ೆ仧ݖ
+\u200CΣ🃡16..\u0CC6仧\u0756; \u200Cσ🃡16..\u0CC6仧\u0756; [B1, B5, B6, C1, V5, X4_2]; xn--16-ubc7700avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2] # σ🃡16..ೆ仧ݖ
+\u200Cσ🃡16..\u0CC6仧\u0756; ; [B1, B5, B6, C1, V5, X4_2]; xn--16-ubc7700avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2] # σ🃡16..ೆ仧ݖ
+xn--16-ubc66061c..xn--9ob79ycx2e; σ🃡16..\u0CC6仧\u0756; [B5, B6, V5, X4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2]; ; # σ🃡16..ೆ仧ݖ
+xn--16-ubc7700avy99b..xn--9ob79ycx2e; \u200Cσ🃡16..\u0CC6仧\u0756; [B1, B5, B6, C1, V5, X4_2]; xn--16-ubc7700avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; ; # σ🃡16..ೆ仧ݖ
+xn--16-rbc1800avy99b..xn--9ob79ycx2e; \u200Cς🃡16..\u0CC6仧\u0756; [B1, B5, B6, C1, V5, X4_2]; xn--16-rbc1800avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; ; # ς🃡16..ೆ仧ݖ
+\u200CΣ🃡⒗.\u0CC6仧\u0756; \u200Cσ🃡⒗.\u0CC6仧\u0756; [B1, B5, B6, C1, V5, V6]; xn--4xa595lz9czy52d.xn--9ob79ycx2e; ; xn--4xa229nbu92a.xn--9ob79ycx2e; [B5, B6, V5, V6] # σ🃡⒗.ೆ仧ݖ
+\u200Cσ🃡⒗.\u0CC6仧\u0756; ; [B1, B5, B6, C1, V5, V6]; xn--4xa595lz9czy52d.xn--9ob79ycx2e; ; xn--4xa229nbu92a.xn--9ob79ycx2e; [B5, B6, V5, V6] # σ🃡⒗.ೆ仧ݖ
+xn--4xa229nbu92a.xn--9ob79ycx2e; σ🃡⒗.\u0CC6仧\u0756; [B5, B6, V5, V6]; xn--4xa229nbu92a.xn--9ob79ycx2e; ; ; # σ🃡⒗.ೆ仧ݖ
+xn--4xa595lz9czy52d.xn--9ob79ycx2e; \u200Cσ🃡⒗.\u0CC6仧\u0756; [B1, B5, B6, C1, V5, V6]; xn--4xa595lz9czy52d.xn--9ob79ycx2e; ; ; # σ🃡⒗.ೆ仧ݖ
+xn--3xa795lz9czy52d.xn--9ob79ycx2e; \u200Cς🃡⒗.\u0CC6仧\u0756; [B1, B5, B6, C1, V5, V6]; xn--3xa795lz9czy52d.xn--9ob79ycx2e; ; ; # ς🃡⒗.ೆ仧ݖ
+-.𞸚; -.\u0638; [B1, V3]; -.xn--3gb; ; ; # -.ظ
+-.\u0638; ; [B1, V3]; -.xn--3gb; ; ; # -.ظ
+-.xn--3gb; -.\u0638; [B1, V3]; -.xn--3gb; ; ; # -.ظ
+򏛓\u0683.\u0F7E\u0634; ; [B1, B5, B6, V5, V6]; xn--8ib92728i.xn--zgb968b; ; ; # ڃ.ཾش
+xn--8ib92728i.xn--zgb968b; 򏛓\u0683.\u0F7E\u0634; [B1, B5, B6, V5, V6]; xn--8ib92728i.xn--zgb968b; ; ; # ڃ.ཾش
+\u0FE6\u0843񽶬.𐮏; ; [B5, V6]; xn--1vb320b5m04p.xn--m29c; ; ; # ࡃ.𐮏
+xn--1vb320b5m04p.xn--m29c; \u0FE6\u0843񽶬.𐮏; [B5, V6]; xn--1vb320b5m04p.xn--m29c; ; ; # ࡃ.𐮏
+2񎨠\u07CBß。ᠽ; 2񎨠\u07CBß.ᠽ; [B1, V6]; xn--2-qfa924cez02l.xn--w7e; ; xn--2ss-odg83511n.xn--w7e; # 2ߋß.ᠽ
+2񎨠\u07CBSS。ᠽ; 2񎨠\u07CBss.ᠽ; [B1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+2񎨠\u07CBss。ᠽ; 2񎨠\u07CBss.ᠽ; [B1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+xn--2ss-odg83511n.xn--w7e; 2񎨠\u07CBss.ᠽ; [B1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+xn--2-qfa924cez02l.xn--w7e; 2񎨠\u07CBß.ᠽ; [B1, V6]; xn--2-qfa924cez02l.xn--w7e; ; ; # 2ߋß.ᠽ
+2񎨠\u07CBSs。ᠽ; 2񎨠\u07CBss.ᠽ; [B1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+㸳\u07CA≮.\u06CEß-\u200D; 㸳\u07CA≮.\u06CEß-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێß-
+㸳\u07CA<\u0338.\u06CEß-\u200D; 㸳\u07CA≮.\u06CEß-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێß-
+㸳\u07CA≮.\u06CEß-\u200D; ; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێß-
+㸳\u07CA<\u0338.\u06CEß-\u200D; 㸳\u07CA≮.\u06CEß-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێß-
+㸳\u07CA<\u0338.\u06CESS-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA≮.\u06CESS-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA≮.\u06CEss-\u200D; ; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA<\u0338.\u06CEss-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+xn--lsb457kkut.xn--ss--qjf; 㸳\u07CA≮.\u06CEss-; [B2, B3, B5, B6, V3]; xn--lsb457kkut.xn--ss--qjf; ; ; # 㸳ߊ≮.ێss-
+xn--lsb457kkut.xn--ss--qjf2343a; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; ; # 㸳ߊ≮.ێss-
+xn--lsb457kkut.xn----pfa076bys4a; 㸳\u07CA≮.\u06CEß-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn----pfa076bys4a; ; ; # 㸳ߊ≮.ێß-
+㸳\u07CA<\u0338.\u06CESS-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA≮.\u06CESS-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA≮.\u06CEss-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA<\u0338.\u06CEss-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA<\u0338.\u06CESs-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA≮.\u06CESs-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA<\u0338.\u06CESs-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+㸳\u07CA≮.\u06CESs-\u200D; 㸳\u07CA≮.\u06CEss-\u200D; [B2, B3, B5, B6, C2]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, V3] # 㸳ߊ≮.ێss-
+-򷝬\u135E𑜧.\u1DEB-︒; ; [V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkmw278h; ; ; # -፞𑜧.ᷫ-︒
+-򷝬\u135E𑜧.\u1DEB-。; -򷝬\u135E𑜧.\u1DEB-.; [V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkm.; ; ; # -፞𑜧.ᷫ-.
+xn----b5h1837n2ok9f.xn----mkm.; -򷝬\u135E𑜧.\u1DEB-.; [V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkm.; ; ; # -፞𑜧.ᷫ-.
+xn----b5h1837n2ok9f.xn----mkmw278h; -򷝬\u135E𑜧.\u1DEB-︒; [V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkmw278h; ; ; # -፞𑜧.ᷫ-︒
+︒.򚠡\u1A59; ; [V6]; xn--y86c.xn--cof61594i; ; ; # ︒.ᩙ
+。.򚠡\u1A59; ..򚠡\u1A59; [V6, X4_2]; ..xn--cof61594i; [V6, A4_2]; ; # ..ᩙ
+..xn--cof61594i; ..򚠡\u1A59; [V6, X4_2]; ..xn--cof61594i; [V6, A4_2]; ; # ..ᩙ
+xn--y86c.xn--cof61594i; ︒.򚠡\u1A59; [V6]; xn--y86c.xn--cof61594i; ; ; # ︒.ᩙ
+\u0323\u2DE1。\u200C⓾\u200C\u06B9; \u0323\u2DE1.\u200C⓾\u200C\u06B9; [B1, C1, V5]; xn--kta899s.xn--skb970ka771c; ; xn--kta899s.xn--skb116m; [B1, V5] # ̣ⷡ.⓾ڹ
+xn--kta899s.xn--skb116m; \u0323\u2DE1.⓾\u06B9; [B1, V5]; xn--kta899s.xn--skb116m; ; ; # ̣ⷡ.⓾ڹ
+xn--kta899s.xn--skb970ka771c; \u0323\u2DE1.\u200C⓾\u200C\u06B9; [B1, C1, V5]; xn--kta899s.xn--skb970ka771c; ; ; # ̣ⷡ.⓾ڹ
+𞠶ᠴ\u06DD。\u1074𞤵󠅦; 𞠶ᠴ\u06DD.\u1074𞤵; [B1, B2, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𞠶ᠴ\u06DD。\u1074𞤵󠅦; 𞠶ᠴ\u06DD.\u1074𞤵; [B1, B2, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𞠶ᠴ\u06DD。\u1074𞤓󠅦; 𞠶ᠴ\u06DD.\u1074𞤵; [B1, B2, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+xn--tlb199fwl35a.xn--yld4613v; 𞠶ᠴ\u06DD.\u1074𞤵; [B1, B2, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𞠶ᠴ\u06DD。\u1074𞤓󠅦; 𞠶ᠴ\u06DD.\u1074𞤵; [B1, B2, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𑰺.-򑟏; ; [V3, V5, V6]; xn--jk3d.xn----iz68g; ; ; # 𑰺.-
+xn--jk3d.xn----iz68g; 𑰺.-򑟏; [V3, V5, V6]; xn--jk3d.xn----iz68g; ; ; # 𑰺.-
+󠻩.赏; 󠻩.赏; [V6]; xn--2856e.xn--6o3a; ; ; # .赏
+󠻩.赏; ; [V6]; xn--2856e.xn--6o3a; ; ; # .赏
+xn--2856e.xn--6o3a; 󠻩.赏; [V6]; xn--2856e.xn--6o3a; ; ; # .赏
+\u06B0ᠡ。Ⴁ; \u06B0ᠡ.Ⴁ; [B2, B3, V6]; xn--jkb440g.xn--8md; ; ; # ڰᠡ.Ⴁ
+\u06B0ᠡ。Ⴁ; \u06B0ᠡ.Ⴁ; [B2, B3, V6]; xn--jkb440g.xn--8md; ; ; # ڰᠡ.Ⴁ
+\u06B0ᠡ。ⴁ; \u06B0ᠡ.ⴁ; [B2, B3]; xn--jkb440g.xn--skj; ; ; # ڰᠡ.ⴁ
+xn--jkb440g.xn--skj; \u06B0ᠡ.ⴁ; [B2, B3]; xn--jkb440g.xn--skj; ; ; # ڰᠡ.ⴁ
+xn--jkb440g.xn--8md; \u06B0ᠡ.Ⴁ; [B2, B3, V6]; xn--jkb440g.xn--8md; ; ; # ڰᠡ.Ⴁ
+\u06B0ᠡ。ⴁ; \u06B0ᠡ.ⴁ; [B2, B3]; xn--jkb440g.xn--skj; ; ; # ڰᠡ.ⴁ
+\u20DEႪ\u06BBς。-; \u20DEႪ\u06BBς.-; [B1, V3, V5, V6]; xn--3xa53m7zmb0q.-; ; xn--4xa33m7zmb0q.-; # ⃞Ⴊڻς.-
+\u20DEႪ\u06BBς。-; \u20DEႪ\u06BBς.-; [B1, V3, V5, V6]; xn--3xa53m7zmb0q.-; ; xn--4xa33m7zmb0q.-; # ⃞Ⴊڻς.-
+\u20DEⴊ\u06BBς。-; \u20DEⴊ\u06BBς.-; [B1, V3, V5]; xn--3xa53mr38aeel.-; ; xn--4xa33mr38aeel.-; # ⃞ⴊڻς.-
+\u20DEႪ\u06BBΣ。-; \u20DEႪ\u06BBσ.-; [B1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+\u20DEⴊ\u06BBσ。-; \u20DEⴊ\u06BBσ.-; [B1, V3, V5]; xn--4xa33mr38aeel.-; ; ; # ⃞ⴊڻσ.-
+\u20DEႪ\u06BBσ。-; \u20DEႪ\u06BBσ.-; [B1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+xn--4xa33m7zmb0q.-; \u20DEႪ\u06BBσ.-; [B1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+xn--4xa33mr38aeel.-; \u20DEⴊ\u06BBσ.-; [B1, V3, V5]; xn--4xa33mr38aeel.-; ; ; # ⃞ⴊڻσ.-
+xn--3xa53mr38aeel.-; \u20DEⴊ\u06BBς.-; [B1, V3, V5]; xn--3xa53mr38aeel.-; ; ; # ⃞ⴊڻς.-
+xn--3xa53m7zmb0q.-; \u20DEႪ\u06BBς.-; [B1, V3, V5, V6]; xn--3xa53m7zmb0q.-; ; ; # ⃞Ⴊڻς.-
+\u20DEⴊ\u06BBς。-; \u20DEⴊ\u06BBς.-; [B1, V3, V5]; xn--3xa53mr38aeel.-; ; xn--4xa33mr38aeel.-; # ⃞ⴊڻς.-
+\u20DEႪ\u06BBΣ。-; \u20DEႪ\u06BBσ.-; [B1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+\u20DEⴊ\u06BBσ。-; \u20DEⴊ\u06BBσ.-; [B1, V3, V5]; xn--4xa33mr38aeel.-; ; ; # ⃞ⴊڻσ.-
+\u20DEႪ\u06BBσ。-; \u20DEႪ\u06BBσ.-; [B1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+Ⴍ.񍇦\u200C; Ⴍ.񍇦\u200C; [C1, V6]; xn--lnd.xn--0ug56448b; ; xn--lnd.xn--p01x; [V6] # Ⴍ.
+Ⴍ.񍇦\u200C; ; [C1, V6]; xn--lnd.xn--0ug56448b; ; xn--lnd.xn--p01x; [V6] # Ⴍ.
+ⴍ.񍇦\u200C; ; [C1, V6]; xn--4kj.xn--0ug56448b; ; xn--4kj.xn--p01x; [V6] # ⴍ.
+xn--4kj.xn--p01x; ⴍ.񍇦; [V6]; xn--4kj.xn--p01x; ; ; # ⴍ.
+xn--4kj.xn--0ug56448b; ⴍ.񍇦\u200C; [C1, V6]; xn--4kj.xn--0ug56448b; ; ; # ⴍ.
+xn--lnd.xn--p01x; Ⴍ.񍇦; [V6]; xn--lnd.xn--p01x; ; ; # Ⴍ.
+xn--lnd.xn--0ug56448b; Ⴍ.񍇦\u200C; [C1, V6]; xn--lnd.xn--0ug56448b; ; ; # Ⴍ.
+ⴍ.񍇦\u200C; ⴍ.񍇦\u200C; [C1, V6]; xn--4kj.xn--0ug56448b; ; xn--4kj.xn--p01x; [V6] # ⴍ.
+򉟂󠵣.𐫫\u1A60󴺖\u1B44; ; [B2, B3, B6, V6]; xn--9u37blu98h.xn--jof13bt568cork1j; ; ; # .𐫫᩠᭄
+xn--9u37blu98h.xn--jof13bt568cork1j; 򉟂󠵣.𐫫\u1A60󴺖\u1B44; [B2, B3, B6, V6]; xn--9u37blu98h.xn--jof13bt568cork1j; ; ; # .𐫫᩠᭄
+≯❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+>\u0338❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+≯❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+>\u0338❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+xn--i7e163ct2d.xn--vwj7372e; ≯❊ᠯ.𐹱⺨; [B1]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+􁕜𐹧𞭁𐹩。Ⴈ𐫮Ⴏ; 􁕜𐹧𞭁𐹩.Ⴈ𐫮Ⴏ; [B5, B6, V6]; xn--fo0de1270ope54j.xn--gndo2033q; ; ; # 𐹧𐹩.Ⴈ𐫮Ⴏ
+􁕜𐹧𞭁𐹩。ⴈ𐫮ⴏ; 􁕜𐹧𞭁𐹩.ⴈ𐫮ⴏ; [B5, B6, V6]; xn--fo0de1270ope54j.xn--zkjo0151o; ; ; # 𐹧𐹩.ⴈ𐫮ⴏ
+xn--fo0de1270ope54j.xn--zkjo0151o; 􁕜𐹧𞭁𐹩.ⴈ𐫮ⴏ; [B5, B6, V6]; xn--fo0de1270ope54j.xn--zkjo0151o; ; ; # 𐹧𐹩.ⴈ𐫮ⴏ
+xn--fo0de1270ope54j.xn--gndo2033q; 􁕜𐹧𞭁𐹩.Ⴈ𐫮Ⴏ; [B5, B6, V6]; xn--fo0de1270ope54j.xn--gndo2033q; ; ; # 𐹧𐹩.Ⴈ𐫮Ⴏ
+𞠂。\uA926; 𞠂.\uA926; [B1, V5]; xn--145h.xn--ti9a; ; ; # 𞠂.ꤦ
+xn--145h.xn--ti9a; 𞠂.\uA926; [B1, V5]; xn--145h.xn--ti9a; ; ; # 𞠂.ꤦ
+𝟔𐹫.\u0733\u10379ꡇ; 6𐹫.\u1037\u07339ꡇ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+𝟔𐹫.\u1037\u07339ꡇ; 6𐹫.\u1037\u07339ꡇ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+6𐹫.\u1037\u07339ꡇ; ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+xn--6-t26i.xn--9-91c730e8u8n; 6𐹫.\u1037\u07339ꡇ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+\u0724\u0603𞲶.\u06D8; \u0724\u0603𞲶.\u06D8; [B1, V5, V6]; xn--lfb19ct414i.xn--olb; ; ; # ܤ.ۘ
+\u0724\u0603𞲶.\u06D8; ; [B1, V5, V6]; xn--lfb19ct414i.xn--olb; ; ; # ܤ.ۘ
+xn--lfb19ct414i.xn--olb; \u0724\u0603𞲶.\u06D8; [B1, V5, V6]; xn--lfb19ct414i.xn--olb; ; ; # ܤ.ۘ
+✆񱔩ꡋ.\u0632\u200D𞣴; ✆񱔩ꡋ.\u0632\u200D𞣴; [B1, C2, V6]; xn--1biv525bcix0d.xn--xgb253k0m73a; ; xn--1biv525bcix0d.xn--xgb6828v; [B1, V6] # ✆ꡋ.ز
+✆񱔩ꡋ.\u0632\u200D𞣴; ; [B1, C2, V6]; xn--1biv525bcix0d.xn--xgb253k0m73a; ; xn--1biv525bcix0d.xn--xgb6828v; [B1, V6] # ✆ꡋ.ز
+xn--1biv525bcix0d.xn--xgb6828v; ✆񱔩ꡋ.\u0632𞣴; [B1, V6]; xn--1biv525bcix0d.xn--xgb6828v; ; ; # ✆ꡋ.ز
+xn--1biv525bcix0d.xn--xgb253k0m73a; ✆񱔩ꡋ.\u0632\u200D𞣴; [B1, C2, V6]; xn--1biv525bcix0d.xn--xgb253k0m73a; ; ; # ✆ꡋ.ز
+\u0845񃾰𞸍-.≠򃁟𑋪; \u0845񃾰\u0646-.≠򃁟𑋪; [B1, B2, B3, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+\u0845񃾰𞸍-.=\u0338򃁟𑋪; \u0845񃾰\u0646-.≠򃁟𑋪; [B1, B2, B3, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+\u0845񃾰\u0646-.≠򃁟𑋪; ; [B1, B2, B3, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+\u0845񃾰\u0646-.=\u0338򃁟𑋪; \u0845񃾰\u0646-.≠򃁟𑋪; [B1, B2, B3, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+xn----qoc64my971s.xn--1ch7585g76o3c; \u0845񃾰\u0646-.≠򃁟𑋪; [B1, B2, B3, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+𝟛.笠; 3.笠; ; 3.xn--6vz; ; ; # 3.笠
+𝟛.笠; 3.笠; ; 3.xn--6vz; ; ; # 3.笠
+3.笠; ; ; 3.xn--6vz; ; ; # 3.笠
+3.xn--6vz; 3.笠; ; 3.xn--6vz; ; ; # 3.笠
+-\u200D.Ⴞ𐋷; ; [C2, V3, V6]; xn----ugn.xn--2nd2315j; ; -.xn--2nd2315j; [V3, V6] # -.Ⴞ𐋷
+-\u200D.ⴞ𐋷; ; [C2, V3]; xn----ugn.xn--mlj8559d; ; -.xn--mlj8559d; [V3] # -.ⴞ𐋷
+-.xn--mlj8559d; -.ⴞ𐋷; [V3]; -.xn--mlj8559d; ; ; # -.ⴞ𐋷
+xn----ugn.xn--mlj8559d; -\u200D.ⴞ𐋷; [C2, V3]; xn----ugn.xn--mlj8559d; ; ; # -.ⴞ𐋷
+-.xn--2nd2315j; -.Ⴞ𐋷; [V3, V6]; -.xn--2nd2315j; ; ; # -.Ⴞ𐋷
+xn----ugn.xn--2nd2315j; -\u200D.Ⴞ𐋷; [C2, V3, V6]; xn----ugn.xn--2nd2315j; ; ; # -.Ⴞ𐋷
+\u200Dςß\u0731.\u0BCD; \u200Dςß\u0731.\u0BCD; [C2, V5]; xn--zca19ln1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # ςßܱ.்
+\u200Dςß\u0731.\u0BCD; ; [C2, V5]; xn--zca19ln1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # ςßܱ.்
+\u200DΣSS\u0731.\u0BCD; \u200Dσss\u0731.\u0BCD; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+\u200Dσss\u0731.\u0BCD; ; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+\u200DΣss\u0731.\u0BCD; \u200Dσss\u0731.\u0BCD; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+xn--ss-ubc826a.xn--xmc; σss\u0731.\u0BCD; [V5]; xn--ss-ubc826a.xn--xmc; ; ; # σssܱ.்
+xn--ss-ubc826ab34b.xn--xmc; \u200Dσss\u0731.\u0BCD; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; ; # σssܱ.்
+\u200DΣß\u0731.\u0BCD; \u200Dσß\u0731.\u0BCD; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+\u200Dσß\u0731.\u0BCD; ; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+xn--zca39lk1di19a.xn--xmc; \u200Dσß\u0731.\u0BCD; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; ; # σßܱ.்
+xn--zca19ln1di19a.xn--xmc; \u200Dςß\u0731.\u0BCD; [C2, V5]; xn--zca19ln1di19a.xn--xmc; ; ; # ςßܱ.்
+\u200DΣSS\u0731.\u0BCD; \u200Dσss\u0731.\u0BCD; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+\u200Dσss\u0731.\u0BCD; \u200Dσss\u0731.\u0BCD; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+\u200DΣss\u0731.\u0BCD; \u200Dσss\u0731.\u0BCD; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+\u200DΣß\u0731.\u0BCD; \u200Dσß\u0731.\u0BCD; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+\u200Dσß\u0731.\u0BCD; \u200Dσß\u0731.\u0BCD; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+≠.\u200D; ≠.\u200D; [C2]; xn--1ch.xn--1ug; ; xn--1ch.; [] # ≠.
+=\u0338.\u200D; ≠.\u200D; [C2]; xn--1ch.xn--1ug; ; xn--1ch.; [] # ≠.
+≠.\u200D; ; [C2]; xn--1ch.xn--1ug; ; xn--1ch.; [] # ≠.
+=\u0338.\u200D; ≠.\u200D; [C2]; xn--1ch.xn--1ug; ; xn--1ch.; [] # ≠.
+xn--1ch.; ≠.; ; xn--1ch.; ; ; # ≠.
+≠.; ; ; xn--1ch.; ; ; # ≠.
+=\u0338.; ≠.; ; xn--1ch.; ; ; # ≠.
+xn--1ch.xn--1ug; ≠.\u200D; [C2]; xn--1ch.xn--1ug; ; ; # ≠.
+\uFC01。\u0C81ᠼ▗򒁋; \u0626\u062D.\u0C81ᠼ▗򒁋; [B1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+\u0626\u062D。\u0C81ᠼ▗򒁋; \u0626\u062D.\u0C81ᠼ▗򒁋; [B1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+\u064A\u0654\u062D。\u0C81ᠼ▗򒁋; \u0626\u062D.\u0C81ᠼ▗򒁋; [B1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+xn--lgbo.xn--2rc021dcxkrx55t; \u0626\u062D.\u0C81ᠼ▗򒁋; [B1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+󧋵\u09CDς.ς𐨿; 󧋵\u09CDς.ς𐨿; [V6]; xn--3xa702av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্ς.ς𐨿
+󧋵\u09CDς.ς𐨿; ; [V6]; xn--3xa702av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্ς.ς𐨿
+󧋵\u09CDΣ.Σ𐨿; 󧋵\u09CDσ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵\u09CDσ.ς𐨿; ; [V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+󧋵\u09CDσ.σ𐨿; ; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵\u09CDΣ.σ𐨿; 󧋵\u09CDσ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+xn--4xa502av8297a.xn--4xa6055k; 󧋵\u09CDσ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵\u09CDΣ.ς𐨿; 󧋵\u09CDσ.ς𐨿; [V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+xn--4xa502av8297a.xn--3xa8055k; 󧋵\u09CDσ.ς𐨿; [V6]; xn--4xa502av8297a.xn--3xa8055k; ; ; # ্σ.ς𐨿
+xn--3xa702av8297a.xn--3xa8055k; 󧋵\u09CDς.ς𐨿; [V6]; xn--3xa702av8297a.xn--3xa8055k; ; ; # ্ς.ς𐨿
+󧋵\u09CDΣ.Σ𐨿; 󧋵\u09CDσ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵\u09CDσ.ς𐨿; 󧋵\u09CDσ.ς𐨿; [V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+󧋵\u09CDσ.σ𐨿; 󧋵\u09CDσ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵\u09CDΣ.σ𐨿; 󧋵\u09CDσ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵\u09CDΣ.ς𐨿; 󧋵\u09CDσ.ς𐨿; [V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+𐫓\u07D8牅\u08F8。𞦤\u1A17򱍰Ⴙ; 𐫓\u07D8牅\u08F8.𞦤\u1A17򱍰Ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; ; ; # 𐫓ߘ牅ࣸ.ᨗႹ
+𐫓\u07D8牅\u08F8。𞦤\u1A17򱍰Ⴙ; 𐫓\u07D8牅\u08F8.𞦤\u1A17򱍰Ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; ; ; # 𐫓ߘ牅ࣸ.ᨗႹ
+𐫓\u07D8牅\u08F8。𞦤\u1A17򱍰ⴙ; 𐫓\u07D8牅\u08F8.𞦤\u1A17򱍰ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; ; ; # 𐫓ߘ牅ࣸ.ᨗⴙ
+xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; 𐫓\u07D8牅\u08F8.𞦤\u1A17򱍰ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; ; ; # 𐫓ߘ牅ࣸ.ᨗⴙ
+xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; 𐫓\u07D8牅\u08F8.𞦤\u1A17򱍰Ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; ; ; # 𐫓ߘ牅ࣸ.ᨗႹ
+𐫓\u07D8牅\u08F8。𞦤\u1A17򱍰ⴙ; 𐫓\u07D8牅\u08F8.𞦤\u1A17򱍰ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; ; ; # 𐫓ߘ牅ࣸ.ᨗⴙ
+񣤒。륧; 񣤒.륧; [V6]; xn--s264a.xn--pw2b; ; ; # .륧
+񣤒。륧; 񣤒.륧; [V6]; xn--s264a.xn--pw2b; ; ; # .륧
+񣤒。륧; 񣤒.륧; [V6]; xn--s264a.xn--pw2b; ; ; # .륧
+񣤒。륧; 񣤒.륧; [V6]; xn--s264a.xn--pw2b; ; ; # .륧
+xn--s264a.xn--pw2b; 񣤒.륧; [V6]; xn--s264a.xn--pw2b; ; ; # .륧
+𐹷\u200D。󉵢; 𐹷\u200D.󉵢; [B1, C2, V6]; xn--1ugx205g.xn--8088d; ; xn--vo0d.xn--8088d; [B1, V6] # 𐹷.
+xn--vo0d.xn--8088d; 𐹷.󉵢; [B1, V6]; xn--vo0d.xn--8088d; ; ; # 𐹷.
+xn--1ugx205g.xn--8088d; 𐹷\u200D.󉵢; [B1, C2, V6]; xn--1ugx205g.xn--8088d; ; ; # 𐹷.
+Ⴘ\u06C2𑲭。-; Ⴘ\u06C2𑲭.-; [B1, B5, B6, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+Ⴘ\u06C1\u0654𑲭。-; Ⴘ\u06C2𑲭.-; [B1, B5, B6, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+Ⴘ\u06C2𑲭。-; Ⴘ\u06C2𑲭.-; [B1, B5, B6, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+Ⴘ\u06C1\u0654𑲭。-; Ⴘ\u06C2𑲭.-; [B1, B5, B6, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+ⴘ\u06C1\u0654𑲭。-; ⴘ\u06C2𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+ⴘ\u06C2𑲭。-; ⴘ\u06C2𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+xn--1kb147qfk3n.-; ⴘ\u06C2𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+xn--1kb312c139t.-; Ⴘ\u06C2𑲭.-; [B1, B5, B6, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+ⴘ\u06C1\u0654𑲭。-; ⴘ\u06C2𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+ⴘ\u06C2𑲭。-; ⴘ\u06C2𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+\uA806\u067B₆ᡐ。🛇\uFCDD; \uA806\u067B6ᡐ.🛇\u064A\u0645; [B1, V5]; xn--6-rrc018krt9k.xn--hhbj61429a; ; ; # ꠆ٻ6ᡐ.🛇يم
+\uA806\u067B6ᡐ。🛇\u064A\u0645; \uA806\u067B6ᡐ.🛇\u064A\u0645; [B1, V5]; xn--6-rrc018krt9k.xn--hhbj61429a; ; ; # ꠆ٻ6ᡐ.🛇يم
+xn--6-rrc018krt9k.xn--hhbj61429a; \uA806\u067B6ᡐ.🛇\u064A\u0645; [B1, V5]; xn--6-rrc018krt9k.xn--hhbj61429a; ; ; # ꠆ٻ6ᡐ.🛇يم
+򸍂.㇄ᡟ𐫂\u0622; ; [B1, V6]; xn--p292d.xn--hgb154ghrsvm2r; ; ; # .㇄ᡟ𐫂آ
+򸍂.㇄ᡟ𐫂\u0627\u0653; 򸍂.㇄ᡟ𐫂\u0622; [B1, V6]; xn--p292d.xn--hgb154ghrsvm2r; ; ; # .㇄ᡟ𐫂آ
+xn--p292d.xn--hgb154ghrsvm2r; 򸍂.㇄ᡟ𐫂\u0622; [B1, V6]; xn--p292d.xn--hgb154ghrsvm2r; ; ; # .㇄ᡟ𐫂آ
+\u07DF򵚌。-\u07E9; \u07DF򵚌.-\u07E9; [B1, B2, B3, V3, V6]; xn--6sb88139l.xn----pdd; ; ; # ߟ.-ߩ
+xn--6sb88139l.xn----pdd; \u07DF򵚌.-\u07E9; [B1, B2, B3, V3, V6]; xn--6sb88139l.xn----pdd; ; ; # ߟ.-ߩ
+ς\u0643⾑.\u200Cᢟ\u200C⒈; ς\u0643襾.\u200Cᢟ\u200C⒈; [B1, B5, C1, V6]; xn--3xa69jux8r.xn--pbf519aba607b; ; xn--4xa49jux8r.xn--pbf212d; [B5, V6] # ςك襾.ᢟ⒈
+ς\u0643襾.\u200Cᢟ\u200C1.; ; [B1, B5, C1]; xn--3xa69jux8r.xn--1-4ck691bba.; ; xn--4xa49jux8r.xn--1-4ck.; [B5] # ςك襾.ᢟ1.
+Σ\u0643襾.\u200Cᢟ\u200C1.; σ\u0643襾.\u200Cᢟ\u200C1.; [B1, B5, C1]; xn--4xa49jux8r.xn--1-4ck691bba.; ; xn--4xa49jux8r.xn--1-4ck.; [B5] # σك襾.ᢟ1.
+σ\u0643襾.\u200Cᢟ\u200C1.; ; [B1, B5, C1]; xn--4xa49jux8r.xn--1-4ck691bba.; ; xn--4xa49jux8r.xn--1-4ck.; [B5] # σك襾.ᢟ1.
+xn--4xa49jux8r.xn--1-4ck.; σ\u0643襾.ᢟ1.; [B5]; xn--4xa49jux8r.xn--1-4ck.; ; ; # σك襾.ᢟ1.
+xn--4xa49jux8r.xn--1-4ck691bba.; σ\u0643襾.\u200Cᢟ\u200C1.; [B1, B5, C1]; xn--4xa49jux8r.xn--1-4ck691bba.; ; ; # σك襾.ᢟ1.
+xn--3xa69jux8r.xn--1-4ck691bba.; ς\u0643襾.\u200Cᢟ\u200C1.; [B1, B5, C1]; xn--3xa69jux8r.xn--1-4ck691bba.; ; ; # ςك襾.ᢟ1.
+Σ\u0643⾑.\u200Cᢟ\u200C⒈; σ\u0643襾.\u200Cᢟ\u200C⒈; [B1, B5, C1, V6]; xn--4xa49jux8r.xn--pbf519aba607b; ; xn--4xa49jux8r.xn--pbf212d; [B5, V6] # σك襾.ᢟ⒈
+σ\u0643⾑.\u200Cᢟ\u200C⒈; σ\u0643襾.\u200Cᢟ\u200C⒈; [B1, B5, C1, V6]; xn--4xa49jux8r.xn--pbf519aba607b; ; xn--4xa49jux8r.xn--pbf212d; [B5, V6] # σك襾.ᢟ⒈
+xn--4xa49jux8r.xn--pbf212d; σ\u0643襾.ᢟ⒈; [B5, V6]; xn--4xa49jux8r.xn--pbf212d; ; ; # σك襾.ᢟ⒈
+xn--4xa49jux8r.xn--pbf519aba607b; σ\u0643襾.\u200Cᢟ\u200C⒈; [B1, B5, C1, V6]; xn--4xa49jux8r.xn--pbf519aba607b; ; ; # σك襾.ᢟ⒈
+xn--3xa69jux8r.xn--pbf519aba607b; ς\u0643襾.\u200Cᢟ\u200C⒈; [B1, B5, C1, V6]; xn--3xa69jux8r.xn--pbf519aba607b; ; ; # ςك襾.ᢟ⒈
+ᡆ𑓝.𞵆; ᡆ𑓝.𞵆; [V6]; xn--57e0440k.xn--k86h; ; ; # ᡆ.
+ᡆ𑓝.𞵆; ; [V6]; xn--57e0440k.xn--k86h; ; ; # ᡆ.
+xn--57e0440k.xn--k86h; ᡆ𑓝.𞵆; [V6]; xn--57e0440k.xn--k86h; ; ; # ᡆ.
+\u0A4D𦍓\u1DEE。\u200C\u08BD񝹲; \u0A4D𦍓\u1DEE.\u200C\u08BD񝹲; [B1, C1, V5, V6]; xn--ybc461hph93b.xn--jzb740j1y45h; ; xn--ybc461hph93b.xn--jzb29857e; [B1, B2, B3, V5, V6] # ੍𦍓ᷮ.ࢽ
+\u0A4D𦍓\u1DEE。\u200C\u08BD񝹲; \u0A4D𦍓\u1DEE.\u200C\u08BD񝹲; [B1, C1, V5, V6]; xn--ybc461hph93b.xn--jzb740j1y45h; ; xn--ybc461hph93b.xn--jzb29857e; [B1, B2, B3, V5, V6] # ੍𦍓ᷮ.ࢽ
+xn--ybc461hph93b.xn--jzb29857e; \u0A4D𦍓\u1DEE.\u08BD񝹲; [B1, B2, B3, V5, V6]; xn--ybc461hph93b.xn--jzb29857e; ; ; # ੍𦍓ᷮ.ࢽ
+xn--ybc461hph93b.xn--jzb740j1y45h; \u0A4D𦍓\u1DEE.\u200C\u08BD񝹲; [B1, C1, V5, V6]; xn--ybc461hph93b.xn--jzb740j1y45h; ; ; # ੍𦍓ᷮ.ࢽ
+\u062E\u0748񅪪-.\u200C먿; \u062E\u0748񅪪-.\u200C먿; [B1, B2, B3, C1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, V3, V6] # خ݈-.먿
+\u062E\u0748񅪪-.\u200C먿; \u062E\u0748񅪪-.\u200C먿; [B1, B2, B3, C1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, V3, V6] # خ݈-.먿
+\u062E\u0748񅪪-.\u200C먿; ; [B1, B2, B3, C1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, V3, V6] # خ݈-.먿
+\u062E\u0748񅪪-.\u200C먿; \u062E\u0748񅪪-.\u200C먿; [B1, B2, B3, C1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, V3, V6] # خ݈-.먿
+xn----dnc06f42153a.xn--v22b; \u062E\u0748񅪪-.먿; [B2, B3, V3, V6]; xn----dnc06f42153a.xn--v22b; ; ; # خ݈-.먿
+xn----dnc06f42153a.xn--0ug1581d; \u062E\u0748񅪪-.\u200C먿; [B1, B2, B3, C1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; ; # خ݈-.먿
+􋿦。ᠽ; 􋿦.ᠽ; [V6]; xn--j890g.xn--w7e; ; ; # .ᠽ
+􋿦。ᠽ; 􋿦.ᠽ; [V6]; xn--j890g.xn--w7e; ; ; # .ᠽ
+xn--j890g.xn--w7e; 􋿦.ᠽ; [V6]; xn--j890g.xn--w7e; ; ; # .ᠽ
+嬃𝍌.\u200D\u0B44; 嬃𝍌.\u200D\u0B44; [C2]; xn--b6s0078f.xn--0ic557h; ; xn--b6s0078f.xn--0ic; [V5] # 嬃𝍌.ୄ
+嬃𝍌.\u200D\u0B44; ; [C2]; xn--b6s0078f.xn--0ic557h; ; xn--b6s0078f.xn--0ic; [V5] # 嬃𝍌.ୄ
+xn--b6s0078f.xn--0ic; 嬃𝍌.\u0B44; [V5]; xn--b6s0078f.xn--0ic; ; ; # 嬃𝍌.ୄ
+xn--b6s0078f.xn--0ic557h; 嬃𝍌.\u200D\u0B44; [C2]; xn--b6s0078f.xn--0ic557h; ; ; # 嬃𝍌.ୄ
+\u0602𝌪≯.𚋲򵁨; \u0602𝌪≯.𚋲򵁨; [B1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+\u0602𝌪>\u0338.𚋲򵁨; \u0602𝌪≯.𚋲򵁨; [B1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+\u0602𝌪≯.𚋲򵁨; ; [B1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+\u0602𝌪>\u0338.𚋲򵁨; \u0602𝌪≯.𚋲򵁨; [B1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+xn--kfb866llx01a.xn--wp1gm3570b; \u0602𝌪≯.𚋲򵁨; [B1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+򫾥\u08B7\u17CC\uA9C0.𞼠; ; [B5, V6]; xn--dzb638ewm4i1iy1h.xn--3m7h; ; ; # ࢷ៌꧀.
+xn--dzb638ewm4i1iy1h.xn--3m7h; 򫾥\u08B7\u17CC\uA9C0.𞼠; [B5, V6]; xn--dzb638ewm4i1iy1h.xn--3m7h; ; ; # ࢷ៌꧀.
+\u200C.񟛤; ; [C1, V6]; xn--0ug.xn--q823a; ; .xn--q823a; [V6, A4_2] # .
+.xn--q823a; .񟛤; [V6, X4_2]; .xn--q823a; [V6, A4_2]; ; # .
+xn--0ug.xn--q823a; \u200C.񟛤; [C1, V6]; xn--0ug.xn--q823a; ; ; # .
+򺛕Ⴃ䠅.𐸑; 򺛕Ⴃ䠅.𐸑; [V6]; xn--bnd074zr557n.xn--yl0d; ; ; # Ⴃ䠅.
+򺛕Ⴃ䠅.𐸑; ; [V6]; xn--bnd074zr557n.xn--yl0d; ; ; # Ⴃ䠅.
+򺛕ⴃ䠅.𐸑; ; [V6]; xn--ukju77frl47r.xn--yl0d; ; ; # ⴃ䠅.
+xn--ukju77frl47r.xn--yl0d; 򺛕ⴃ䠅.𐸑; [V6]; xn--ukju77frl47r.xn--yl0d; ; ; # ⴃ䠅.
+xn--bnd074zr557n.xn--yl0d; 򺛕Ⴃ䠅.𐸑; [V6]; xn--bnd074zr557n.xn--yl0d; ; ; # Ⴃ䠅.
+򺛕ⴃ䠅.𐸑; 򺛕ⴃ䠅.𐸑; [V6]; xn--ukju77frl47r.xn--yl0d; ; ; # ⴃ䠅.
+\u1BF1𐹳𐹵𞤚。𝟨Ⴅ; \u1BF1𐹳𐹵𞤼.6Ⴅ; [B1, V5, V6]; xn--zzfy954hga2415t.xn--6-h0g; ; ; # ᯱ𐹳𐹵𞤼.6Ⴅ
+\u1BF1𐹳𐹵𞤚。6Ⴅ; \u1BF1𐹳𐹵𞤼.6Ⴅ; [B1, V5, V6]; xn--zzfy954hga2415t.xn--6-h0g; ; ; # ᯱ𐹳𐹵𞤼.6Ⴅ
+\u1BF1𐹳𐹵𞤼。6ⴅ; \u1BF1𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+\u1BF1𐹳𐹵𞤚。6ⴅ; \u1BF1𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+xn--zzfy954hga2415t.xn--6-kvs; \u1BF1𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+xn--zzfy954hga2415t.xn--6-h0g; \u1BF1𐹳𐹵𞤼.6Ⴅ; [B1, V5, V6]; xn--zzfy954hga2415t.xn--6-h0g; ; ; # ᯱ𐹳𐹵𞤼.6Ⴅ
+\u1BF1𐹳𐹵𞤼。𝟨ⴅ; \u1BF1𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+\u1BF1𐹳𐹵𞤚。𝟨ⴅ; \u1BF1𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+-。︒; -.︒; [V3, V6]; -.xn--y86c; ; ; # -.︒
+-。。; -..; [V3, X4_2]; ; [V3, A4_2]; ; # -..
+-..; ; [V3, X4_2]; ; [V3, A4_2]; ; # -..
+-.xn--y86c; -.︒; [V3, V6]; -.xn--y86c; ; ; # -.︒
+\u07DBჀ。-⁵--; \u07DBჀ.-5--; [B1, B2, B3, V2, V3, V6]; xn--2sb866b.-5--; ; ; # ߛჀ.-5--
+\u07DBჀ。-5--; \u07DBჀ.-5--; [B1, B2, B3, V2, V3, V6]; xn--2sb866b.-5--; ; ; # ߛჀ.-5--
+\u07DBⴠ。-5--; \u07DBⴠ.-5--; [B1, B2, B3, V2, V3]; xn--2sb691q.-5--; ; ; # ߛⴠ.-5--
+xn--2sb691q.-5--; \u07DBⴠ.-5--; [B1, B2, B3, V2, V3]; xn--2sb691q.-5--; ; ; # ߛⴠ.-5--
+xn--2sb866b.-5--; \u07DBჀ.-5--; [B1, B2, B3, V2, V3, V6]; xn--2sb866b.-5--; ; ; # ߛჀ.-5--
+\u07DBⴠ。-⁵--; \u07DBⴠ.-5--; [B1, B2, B3, V2, V3]; xn--2sb691q.-5--; ; ; # ߛⴠ.-5--
+≯?󠑕。𐹷𐹻≯𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+>\u0338?󠑕。𐹷𐹻>\u0338𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕。𐹷𐹻≯𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+>\u0338?󠑕。𐹷𐹻>\u0338𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+xn--?-ogo25661n.xn--hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.xn--hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+>\u0338?󠑕.xn--hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+>\u0338?󠑕.XN--HDH8283GDOAQA; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.XN--HDH8283GDOAQA; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.Xn--Hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+>\u0338?󠑕.Xn--Hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+㍔\u08E6\u077C\u200D。\u0346򁳊𝅶\u0604; ルーブル\u08E6\u077C\u200D.\u0346򁳊𝅶\u0604; [B1, B5, B6, C2, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; [B1, B5, B6, V5, V6] # ルーブルࣦݼ.͆
+ルーブル\u08E6\u077C\u200D。\u0346򁳊𝅶\u0604; ルーブル\u08E6\u077C\u200D.\u0346򁳊𝅶\u0604; [B1, B5, B6, C2, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; [B1, B5, B6, V5, V6] # ルーブルࣦݼ.͆
+ルーフ\u3099ル\u08E6\u077C\u200D。\u0346򁳊𝅶\u0604; ルーブル\u08E6\u077C\u200D.\u0346򁳊𝅶\u0604; [B1, B5, B6, C2, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; [B1, B5, B6, V5, V6] # ルーブルࣦݼ.͆
+xn--dqb73el09fncab4h.xn--kua81ls548d3608b; ルーブル\u08E6\u077C.\u0346򁳊𝅶\u0604; [B1, B5, B6, V5, V6]; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; ; ; # ルーブルࣦݼ.͆
+xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ルーブル\u08E6\u077C\u200D.\u0346򁳊𝅶\u0604; [B1, B5, B6, C2, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; ; # ルーブルࣦݼ.͆
+\u200D.F; \u200D.f; [C2]; xn--1ug.f; ; .f; [A4_2] # .f
+\u200D.f; ; [C2]; xn--1ug.f; ; .f; [A4_2] # .f
+.f; ; [X4_2]; ; [A4_2]; ; # .f
+xn--1ug.f; \u200D.f; [C2]; xn--1ug.f; ; ; # .f
+f; ; ; ; ; ; # f
+\u200D㨲。ß; \u200D㨲.ß; [C2]; xn--1ug914h.xn--zca; ; xn--9bm.ss; [] # 㨲.ß
+\u200D㨲。ß; \u200D㨲.ß; [C2]; xn--1ug914h.xn--zca; ; xn--9bm.ss; [] # 㨲.ß
+\u200D㨲。SS; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+\u200D㨲。ss; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+\u200D㨲。Ss; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+xn--9bm.ss; 㨲.ss; ; xn--9bm.ss; ; ; # 㨲.ss
+㨲.ss; ; ; xn--9bm.ss; ; ; # 㨲.ss
+㨲.SS; 㨲.ss; ; xn--9bm.ss; ; ; # 㨲.ss
+㨲.Ss; 㨲.ss; ; xn--9bm.ss; ; ; # 㨲.ss
+xn--1ug914h.ss; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; ; # 㨲.ss
+xn--1ug914h.xn--zca; \u200D㨲.ß; [C2]; xn--1ug914h.xn--zca; ; ; # 㨲.ß
+\u200D㨲。SS; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+\u200D㨲。ss; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+\u200D㨲。Ss; \u200D㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+\u0605\u067E。\u08A8; \u0605\u067E.\u08A8; [B1, V6]; xn--nfb6v.xn--xyb; ; ; # پ.ࢨ
+\u0605\u067E。\u08A8; \u0605\u067E.\u08A8; [B1, V6]; xn--nfb6v.xn--xyb; ; ; # پ.ࢨ
+xn--nfb6v.xn--xyb; \u0605\u067E.\u08A8; [B1, V6]; xn--nfb6v.xn--xyb; ; ; # پ.ࢨ
+⾑\u0753𞤁。𐹵\u0682; 襾\u0753𞤣.𐹵\u0682; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+襾\u0753𞤁。𐹵\u0682; 襾\u0753𞤣.𐹵\u0682; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+襾\u0753𞤣。𐹵\u0682; 襾\u0753𞤣.𐹵\u0682; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+xn--6ob9577deqwl.xn--7ib5526k; 襾\u0753𞤣.𐹵\u0682; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+⾑\u0753𞤣。𐹵\u0682; 襾\u0753𞤣.𐹵\u0682; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+񦴻ς-\u20EB。\u0754-ꡛ; 񦴻ς-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----xmb015tuo34l.xn----53c4874j; ; xn----zmb705tuo34l.xn----53c4874j; # ς-⃫.ݔ-ꡛ
+񦴻ς-\u20EB。\u0754-ꡛ; 񦴻ς-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----xmb015tuo34l.xn----53c4874j; ; xn----zmb705tuo34l.xn----53c4874j; # ς-⃫.ݔ-ꡛ
+񦴻Σ-\u20EB。\u0754-ꡛ; 񦴻σ-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+񦴻σ-\u20EB。\u0754-ꡛ; 񦴻σ-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+xn----zmb705tuo34l.xn----53c4874j; 񦴻σ-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+xn----xmb015tuo34l.xn----53c4874j; 񦴻ς-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----xmb015tuo34l.xn----53c4874j; ; ; # ς-⃫.ݔ-ꡛ
+񦴻Σ-\u20EB。\u0754-ꡛ; 񦴻σ-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+񦴻σ-\u20EB。\u0754-ꡛ; 񦴻σ-\u20EB.\u0754-ꡛ; [B2, B3, B6, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+\u200D.􀸨; \u200D.􀸨; [C2, V6]; xn--1ug.xn--h327f; ; .xn--h327f; [V6, A4_2] # .
+\u200D.􀸨; ; [C2, V6]; xn--1ug.xn--h327f; ; .xn--h327f; [V6, A4_2] # .
+.xn--h327f; .􀸨; [V6, X4_2]; .xn--h327f; [V6, A4_2]; ; # .
+xn--1ug.xn--h327f; \u200D.􀸨; [C2, V6]; xn--1ug.xn--h327f; ; ; # .
+񣭻񌥁。≠𝟲; 񣭻񌥁.≠6; [V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+񣭻񌥁。=\u0338𝟲; 񣭻񌥁.≠6; [V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+񣭻񌥁。≠6; 񣭻񌥁.≠6; [V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+񣭻񌥁。=\u03386; 񣭻񌥁.≠6; [V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+xn--h79w4z99a.xn--6-tfo; 񣭻񌥁.≠6; [V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+󠅊ᡭ\u200D.𐥡; ᡭ\u200D.𐥡; [B6, C2, V6]; xn--98e810b.xn--om9c; ; xn--98e.xn--om9c; [V6] # ᡭ.
+xn--98e.xn--om9c; ᡭ.𐥡; [V6]; xn--98e.xn--om9c; ; ; # ᡭ.
+xn--98e810b.xn--om9c; ᡭ\u200D.𐥡; [B6, C2, V6]; xn--98e810b.xn--om9c; ; ; # ᡭ.
+\u0C40\u0855𐥛𑄴.󭰵; \u0C40\u0855𐥛𑄴.󭰵; [B1, V5, V6]; xn--kwb91r5112avtg.xn--o580f; ; ; # ీࡕ𑄴.
+\u0C40\u0855𐥛𑄴.󭰵; ; [B1, V5, V6]; xn--kwb91r5112avtg.xn--o580f; ; ; # ీࡕ𑄴.
+xn--kwb91r5112avtg.xn--o580f; \u0C40\u0855𐥛𑄴.󭰵; [B1, V5, V6]; xn--kwb91r5112avtg.xn--o580f; ; ; # ీࡕ𑄴.
+𞤮。𑇊\u200C≯\u1CE6; 𞤮.𑇊\u200C≯\u1CE6; [B1, C1, V5]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, V5] # 𞤮.𑇊≯᳦
+𞤮。𑇊\u200C>\u0338\u1CE6; 𞤮.𑇊\u200C≯\u1CE6; [B1, C1, V5]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, V5] # 𞤮.𑇊≯᳦
+𞤌。𑇊\u200C>\u0338\u1CE6; 𞤮.𑇊\u200C≯\u1CE6; [B1, C1, V5]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, V5] # 𞤮.𑇊≯᳦
+𞤌。𑇊\u200C≯\u1CE6; 𞤮.𑇊\u200C≯\u1CE6; [B1, C1, V5]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, V5] # 𞤮.𑇊≯᳦
+xn--me6h.xn--z6fz8ueq2v; 𞤮.𑇊≯\u1CE6; [B1, V5]; xn--me6h.xn--z6fz8ueq2v; ; ; # 𞤮.𑇊≯᳦
+xn--me6h.xn--z6f16kn9b2642b; 𞤮.𑇊\u200C≯\u1CE6; [B1, C1, V5]; xn--me6h.xn--z6f16kn9b2642b; ; ; # 𞤮.𑇊≯᳦
+󠄀𝟕.𞤌񛗓Ⴉ; 7.𞤮񛗓Ⴉ; [B1, B2, B3, V6]; 7.xn--hnd3403vv1vv; ; ; # 7.𞤮Ⴉ
+󠄀7.𞤌񛗓Ⴉ; 7.𞤮񛗓Ⴉ; [B1, B2, B3, V6]; 7.xn--hnd3403vv1vv; ; ; # 7.𞤮Ⴉ
+󠄀7.𞤮񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+7.xn--0kjz523lv1vv; 7.𞤮񛗓ⴉ; [B1, B2, B3, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+7.xn--hnd3403vv1vv; 7.𞤮񛗓Ⴉ; [B1, B2, B3, V6]; 7.xn--hnd3403vv1vv; ; ; # 7.𞤮Ⴉ
+󠄀𝟕.𞤮񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+󠄀7.𞤌񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+󠄀𝟕.𞤌񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+閃9𝩍。Ↄ\u0669\u08B1\u0B4D; 閃9𝩍.Ↄ\u0669\u08B1\u0B4D; [B5, B6, V6]; xn--9-3j6dk517f.xn--iib28ij3c0t9a; ; ; # 閃9𝩍.Ↄ٩ࢱ୍
+閃9𝩍。ↄ\u0669\u08B1\u0B4D; 閃9𝩍.ↄ\u0669\u08B1\u0B4D; [B5, B6]; xn--9-3j6dk517f.xn--iib28ij3c4t9a; ; ; # 閃9𝩍.ↄ٩ࢱ୍
+xn--9-3j6dk517f.xn--iib28ij3c4t9a; 閃9𝩍.ↄ\u0669\u08B1\u0B4D; [B5, B6]; xn--9-3j6dk517f.xn--iib28ij3c4t9a; ; ; # 閃9𝩍.ↄ٩ࢱ୍
+xn--9-3j6dk517f.xn--iib28ij3c0t9a; 閃9𝩍.Ↄ\u0669\u08B1\u0B4D; [B5, B6, V6]; xn--9-3j6dk517f.xn--iib28ij3c0t9a; ; ; # 閃9𝩍.Ↄ٩ࢱ୍
+\uAAF6ᢏ\u0E3A2.𐋢\u0745\u0F9F︒; \uAAF6ᢏ\u0E3A2.𐋢\u0745\u0F9F︒; [V5, V6]; xn--2-2zf840fk16m.xn--sob093bj62sz9d; ; ; # ꫶ᢏฺ2.𐋢݅ྟ︒
+\uAAF6ᢏ\u0E3A2.𐋢\u0745\u0F9F。; \uAAF6ᢏ\u0E3A2.𐋢\u0745\u0F9F.; [V5]; xn--2-2zf840fk16m.xn--sob093b2m7s.; ; ; # ꫶ᢏฺ2.𐋢݅ྟ.
+xn--2-2zf840fk16m.xn--sob093b2m7s.; \uAAF6ᢏ\u0E3A2.𐋢\u0745\u0F9F.; [V5]; xn--2-2zf840fk16m.xn--sob093b2m7s.; ; ; # ꫶ᢏฺ2.𐋢݅ྟ.
+xn--2-2zf840fk16m.xn--sob093bj62sz9d; \uAAF6ᢏ\u0E3A2.𐋢\u0745\u0F9F︒; [V5, V6]; xn--2-2zf840fk16m.xn--sob093bj62sz9d; ; ; # ꫶ᢏฺ2.𐋢݅ྟ︒
+󅴧。≠-󠙄⾛; 󅴧.≠-󠙄走; [V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+󅴧。=\u0338-󠙄⾛; 󅴧.≠-󠙄走; [V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+󅴧。≠-󠙄走; 󅴧.≠-󠙄走; [V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+󅴧。=\u0338-󠙄走; 󅴧.≠-󠙄走; [V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+xn--gm57d.xn----tfo4949b3664m; 󅴧.≠-󠙄走; [V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+\u076E\u0604Ⴊ。-≠\u1160; \u076E\u0604Ⴊ.-≠\u1160; [B1, B2, B3, V3, V6]; xn--mfb73ex6r.xn----5bh589i; ; ; # ݮႪ.-≠
+\u076E\u0604Ⴊ。-=\u0338\u1160; \u076E\u0604Ⴊ.-≠\u1160; [B1, B2, B3, V3, V6]; xn--mfb73ex6r.xn----5bh589i; ; ; # ݮႪ.-≠
+\u076E\u0604ⴊ。-=\u0338\u1160; \u076E\u0604ⴊ.-≠\u1160; [B1, B2, B3, V3, V6]; xn--mfb73ek93f.xn----5bh589i; ; ; # ݮⴊ.-≠
+\u076E\u0604ⴊ。-≠\u1160; \u076E\u0604ⴊ.-≠\u1160; [B1, B2, B3, V3, V6]; xn--mfb73ek93f.xn----5bh589i; ; ; # ݮⴊ.-≠
+xn--mfb73ek93f.xn----5bh589i; \u076E\u0604ⴊ.-≠\u1160; [B1, B2, B3, V3, V6]; xn--mfb73ek93f.xn----5bh589i; ; ; # ݮⴊ.-≠
+xn--mfb73ex6r.xn----5bh589i; \u076E\u0604Ⴊ.-≠\u1160; [B1, B2, B3, V3, V6]; xn--mfb73ex6r.xn----5bh589i; ; ; # ݮႪ.-≠
+\uFB4F𐹧𝟒≯。\u200C; \u05D0\u05DC𐹧4≯.\u200C; [B1, B3, B4, C1]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4] # אל𐹧4≯.
+\uFB4F𐹧𝟒>\u0338。\u200C; \u05D0\u05DC𐹧4≯.\u200C; [B1, B3, B4, C1]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4] # אל𐹧4≯.
+\u05D0\u05DC𐹧4≯。\u200C; \u05D0\u05DC𐹧4≯.\u200C; [B1, B3, B4, C1]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4] # אל𐹧4≯.
+\u05D0\u05DC𐹧4>\u0338。\u200C; \u05D0\u05DC𐹧4≯.\u200C; [B1, B3, B4, C1]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4] # אל𐹧4≯.
+xn--4-zhc0by36txt0w.; \u05D0\u05DC𐹧4≯.; [B3, B4]; xn--4-zhc0by36txt0w.; ; ; # אל𐹧4≯.
+xn--4-zhc0by36txt0w.xn--0ug; \u05D0\u05DC𐹧4≯.\u200C; [B1, B3, B4, C1]; xn--4-zhc0by36txt0w.xn--0ug; ; ; # אל𐹧4≯.
+𝟎。甯; 0.甯; ; 0.xn--qny; ; ; # 0.甯
+0。甯; 0.甯; ; 0.xn--qny; ; ; # 0.甯
+0.xn--qny; 0.甯; ; 0.xn--qny; ; ; # 0.甯
+0.甯; ; ; 0.xn--qny; ; ; # 0.甯
+-⾆.\uAAF6; -舌.\uAAF6; [V3, V5]; xn----ef8c.xn--2v9a; ; ; # -舌.꫶
+-舌.\uAAF6; ; [V3, V5]; xn----ef8c.xn--2v9a; ; ; # -舌.꫶
+xn----ef8c.xn--2v9a; -舌.\uAAF6; [V3, V5]; xn----ef8c.xn--2v9a; ; ; # -舌.꫶
+-。ᢘ; -.ᢘ; [V3]; -.xn--ibf; ; ; # -.ᢘ
+-。ᢘ; -.ᢘ; [V3]; -.xn--ibf; ; ; # -.ᢘ
+-.xn--ibf; -.ᢘ; [V3]; -.xn--ibf; ; ; # -.ᢘ
+🂴Ⴋ.≮; ; [V6]; xn--jnd1986v.xn--gdh; ; ; # 🂴Ⴋ.≮
+🂴Ⴋ.<\u0338; 🂴Ⴋ.≮; [V6]; xn--jnd1986v.xn--gdh; ; ; # 🂴Ⴋ.≮
+🂴ⴋ.<\u0338; 🂴ⴋ.≮; ; xn--2kj7565l.xn--gdh; ; ; # 🂴ⴋ.≮
+🂴ⴋ.≮; ; ; xn--2kj7565l.xn--gdh; ; ; # 🂴ⴋ.≮
+xn--2kj7565l.xn--gdh; 🂴ⴋ.≮; ; xn--2kj7565l.xn--gdh; ; ; # 🂴ⴋ.≮
+xn--jnd1986v.xn--gdh; 🂴Ⴋ.≮; [V6]; xn--jnd1986v.xn--gdh; ; ; # 🂴Ⴋ.≮
+璼𝨭。\u200C󠇟; 璼𝨭.\u200C; [C1]; xn--gky8837e.xn--0ug; ; xn--gky8837e.; [] # 璼𝨭.
+璼𝨭。\u200C󠇟; 璼𝨭.\u200C; [C1]; xn--gky8837e.xn--0ug; ; xn--gky8837e.; [] # 璼𝨭.
+xn--gky8837e.; 璼𝨭.; ; xn--gky8837e.; ; ; # 璼𝨭.
+璼𝨭.; ; ; xn--gky8837e.; ; ; # 璼𝨭.
+xn--gky8837e.xn--0ug; 璼𝨭.\u200C; [C1]; xn--gky8837e.xn--0ug; ; ; # 璼𝨭.
+\u06698񂍽。-5🞥; \u06698񂍽.-5🞥; [B1, V3, V6]; xn--8-qqc97891f.xn---5-rp92a; ; ; # ٩8.-5🞥
+\u06698񂍽。-5🞥; \u06698񂍽.-5🞥; [B1, V3, V6]; xn--8-qqc97891f.xn---5-rp92a; ; ; # ٩8.-5🞥
+xn--8-qqc97891f.xn---5-rp92a; \u06698񂍽.-5🞥; [B1, V3, V6]; xn--8-qqc97891f.xn---5-rp92a; ; ; # ٩8.-5🞥
+\u200C.\u200C; ; [C1]; xn--0ug.xn--0ug; ; .; [A4_2] # .
+xn--0ug.xn--0ug; \u200C.\u200C; [C1]; xn--0ug.xn--0ug; ; ; # .
+\u200D튛.\u0716; ; [B1, C2]; xn--1ug4441e.xn--gnb; ; xn--157b.xn--gnb; [] # 튛.ܖ
+\u200D튛.\u0716; \u200D튛.\u0716; [B1, C2]; xn--1ug4441e.xn--gnb; ; xn--157b.xn--gnb; [] # 튛.ܖ
+xn--157b.xn--gnb; 튛.\u0716; ; xn--157b.xn--gnb; ; ; # 튛.ܖ
+튛.\u0716; ; ; xn--157b.xn--gnb; ; ; # 튛.ܖ
+튛.\u0716; 튛.\u0716; ; xn--157b.xn--gnb; ; ; # 튛.ܖ
+xn--1ug4441e.xn--gnb; \u200D튛.\u0716; [B1, C2]; xn--1ug4441e.xn--gnb; ; ; # 튛.ܖ
+ᡋ𐹰𞽳.\u0779ⴞ; ; [B2, B3, B5, B6, V6]; xn--b8e0417jocvf.xn--9pb883q; ; ; # ᡋ𐹰.ݹⴞ
+ᡋ𐹰𞽳.\u0779Ⴞ; ; [B2, B3, B5, B6, V6]; xn--b8e0417jocvf.xn--9pb068b; ; ; # ᡋ𐹰.ݹႾ
+xn--b8e0417jocvf.xn--9pb068b; ᡋ𐹰𞽳.\u0779Ⴞ; [B2, B3, B5, B6, V6]; xn--b8e0417jocvf.xn--9pb068b; ; ; # ᡋ𐹰.ݹႾ
+xn--b8e0417jocvf.xn--9pb883q; ᡋ𐹰𞽳.\u0779ⴞ; [B2, B3, B5, B6, V6]; xn--b8e0417jocvf.xn--9pb883q; ; ; # ᡋ𐹰.ݹⴞ
+𐷃\u0662𝅻𝟧.𐹮𐹬Ⴇ; 𐷃\u0662𝅻5.𐹮𐹬Ⴇ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--fnd3401kfa; ; ; # ٢𝅻5.𐹮𐹬Ⴇ
+𐷃\u0662𝅻5.𐹮𐹬Ⴇ; ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--fnd3401kfa; ; ; # ٢𝅻5.𐹮𐹬Ⴇ
+𐷃\u0662𝅻5.𐹮𐹬ⴇ; ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--ykjz523efa; ; ; # ٢𝅻5.𐹮𐹬ⴇ
+xn--5-cqc8833rhv7f.xn--ykjz523efa; 𐷃\u0662𝅻5.𐹮𐹬ⴇ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--ykjz523efa; ; ; # ٢𝅻5.𐹮𐹬ⴇ
+xn--5-cqc8833rhv7f.xn--fnd3401kfa; 𐷃\u0662𝅻5.𐹮𐹬Ⴇ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--fnd3401kfa; ; ; # ٢𝅻5.𐹮𐹬Ⴇ
+𐷃\u0662𝅻𝟧.𐹮𐹬ⴇ; 𐷃\u0662𝅻5.𐹮𐹬ⴇ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--ykjz523efa; ; ; # ٢𝅻5.𐹮𐹬ⴇ
+Ⴗ.\u05C2𑄴\uA9B7񘃨; Ⴗ.𑄴\u05C2\uA9B7񘃨; [V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+Ⴗ.𑄴\u05C2\uA9B7񘃨; Ⴗ.𑄴\u05C2\uA9B7񘃨; [V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+Ⴗ.𑄴\u05C2\uA9B7񘃨; ; [V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+ⴗ.𑄴\u05C2\uA9B7񘃨; ; [V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+xn--flj.xn--qdb0605f14ycrms3c; ⴗ.𑄴\u05C2\uA9B7񘃨; [V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+xn--vnd.xn--qdb0605f14ycrms3c; Ⴗ.𑄴\u05C2\uA9B7񘃨; [V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+ⴗ.𑄴\u05C2\uA9B7񘃨; ⴗ.𑄴\u05C2\uA9B7񘃨; [V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+ⴗ.\u05C2𑄴\uA9B7񘃨; ⴗ.𑄴\u05C2\uA9B7񘃨; [V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+𝟾𾤘.򇕛\u066C; 8𾤘.򇕛\u066C; [B1, B5, B6, V6]; xn--8-kh23b.xn--lib78461i; ; ; # 8.٬
+8𾤘.򇕛\u066C; ; [B1, B5, B6, V6]; xn--8-kh23b.xn--lib78461i; ; ; # 8.٬
+xn--8-kh23b.xn--lib78461i; 8𾤘.򇕛\u066C; [B1, B5, B6, V6]; xn--8-kh23b.xn--lib78461i; ; ; # 8.٬
+⒈酫︒。\u08D6; ⒈酫︒.\u08D6; [V5, V6]; xn--tsh4490bfe8c.xn--8zb; ; ; # ⒈酫︒.ࣖ
+1.酫。。\u08D6; 1.酫..\u08D6; [V5, X4_2]; 1.xn--8j4a..xn--8zb; [V5, A4_2]; ; # 1.酫..ࣖ
+1.xn--8j4a..xn--8zb; 1.酫..\u08D6; [V5, X4_2]; 1.xn--8j4a..xn--8zb; [V5, A4_2]; ; # 1.酫..ࣖ
+xn--tsh4490bfe8c.xn--8zb; ⒈酫︒.\u08D6; [V5, V6]; xn--tsh4490bfe8c.xn--8zb; ; ; # ⒈酫︒.ࣖ
+\u2DE3\u200C≮\u1A6B.\u200C\u0E3A; ; [C1, V5]; xn--uof63xk4bf3s.xn--o4c732g; ; xn--uof548an0j.xn--o4c; [V5] # ⷣ≮ᩫ.ฺ
+\u2DE3\u200C<\u0338\u1A6B.\u200C\u0E3A; \u2DE3\u200C≮\u1A6B.\u200C\u0E3A; [C1, V5]; xn--uof63xk4bf3s.xn--o4c732g; ; xn--uof548an0j.xn--o4c; [V5] # ⷣ≮ᩫ.ฺ
+xn--uof548an0j.xn--o4c; \u2DE3≮\u1A6B.\u0E3A; [V5]; xn--uof548an0j.xn--o4c; ; ; # ⷣ≮ᩫ.ฺ
+xn--uof63xk4bf3s.xn--o4c732g; \u2DE3\u200C≮\u1A6B.\u200C\u0E3A; [C1, V5]; xn--uof63xk4bf3s.xn--o4c732g; ; ; # ⷣ≮ᩫ.ฺ
+𞪂。ႷႽ¹\u200D; 𞪂.ႷႽ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-h1gs597m; ; xn--co6h.xn--1-h1gs; [V6] # .ႷႽ1
+𞪂。ႷႽ1\u200D; 𞪂.ႷႽ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-h1gs597m; ; xn--co6h.xn--1-h1gs; [V6] # .ႷႽ1
+𞪂。ⴗⴝ1\u200D; 𞪂.ⴗⴝ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-ugn710dya; ; xn--co6h.xn--1-kwssa; [V6] # .ⴗⴝ1
+𞪂。Ⴗⴝ1\u200D; 𞪂.Ⴗⴝ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-h1g398iewm; ; xn--co6h.xn--1-h1g429s; [V6] # .Ⴗⴝ1
+xn--co6h.xn--1-h1g429s; 𞪂.Ⴗⴝ1; [V6]; xn--co6h.xn--1-h1g429s; ; ; # .Ⴗⴝ1
+xn--co6h.xn--1-h1g398iewm; 𞪂.Ⴗⴝ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-h1g398iewm; ; ; # .Ⴗⴝ1
+xn--co6h.xn--1-kwssa; 𞪂.ⴗⴝ1; [V6]; xn--co6h.xn--1-kwssa; ; ; # .ⴗⴝ1
+xn--co6h.xn--1-ugn710dya; 𞪂.ⴗⴝ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-ugn710dya; ; ; # .ⴗⴝ1
+xn--co6h.xn--1-h1gs; 𞪂.ႷႽ1; [V6]; xn--co6h.xn--1-h1gs; ; ; # .ႷႽ1
+xn--co6h.xn--1-h1gs597m; 𞪂.ႷႽ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-h1gs597m; ; ; # .ႷႽ1
+𞪂。ⴗⴝ¹\u200D; 𞪂.ⴗⴝ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-ugn710dya; ; xn--co6h.xn--1-kwssa; [V6] # .ⴗⴝ1
+𞪂。Ⴗⴝ¹\u200D; 𞪂.Ⴗⴝ1\u200D; [B6, C2, V6]; xn--co6h.xn--1-h1g398iewm; ; xn--co6h.xn--1-h1g429s; [V6] # .Ⴗⴝ1
+𑄴𑄳2.𞳿󠀳-; ; [B1, B3, V3, V5, V6]; xn--2-h87ic.xn----s39r33498d; ; ; # 𑄴𑄳2.-
+xn--2-h87ic.xn----s39r33498d; 𑄴𑄳2.𞳿󠀳-; [B1, B3, V3, V5, V6]; xn--2-h87ic.xn----s39r33498d; ; ; # 𑄴𑄳2.-
+󠕲󟶶\u0665。񀁁𑄳𞤃\u0710; 󠕲󟶶\u0665.񀁁𑄳𞤥\u0710; [B1, B5, B6, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+󠕲󟶶\u0665。񀁁𑄳𞤃\u0710; 󠕲󟶶\u0665.񀁁𑄳𞤥\u0710; [B1, B5, B6, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+󠕲󟶶\u0665。񀁁𑄳𞤥\u0710; 󠕲󟶶\u0665.񀁁𑄳𞤥\u0710; [B1, B5, B6, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; 󠕲󟶶\u0665.񀁁𑄳𞤥\u0710; [B1, B5, B6, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+󠕲󟶶\u0665。񀁁𑄳𞤥\u0710; 󠕲󟶶\u0665.񀁁𑄳𞤥\u0710; [B1, B5, B6, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+\u0720򲠽𐹢\u17BB。ςᢈ🝭\u200C; \u0720򲠽𐹢\u17BB.ςᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, V6] # ܠ𐹢ុ.ςᢈ🝭
+\u0720򲠽𐹢\u17BB。ςᢈ🝭\u200C; \u0720򲠽𐹢\u17BB.ςᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, V6] # ܠ𐹢ុ.ςᢈ🝭
+\u0720򲠽𐹢\u17BB。Σᢈ🝭\u200C; \u0720򲠽𐹢\u17BB.σᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, V6] # ܠ𐹢ុ.σᢈ🝭
+\u0720򲠽𐹢\u17BB。σᢈ🝭\u200C; \u0720򲠽𐹢\u17BB.σᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, V6] # ܠ𐹢ុ.σᢈ🝭
+xn--qnb616fis0qzt36f.xn--4xa847hli46a; \u0720򲠽𐹢\u17BB.σᢈ🝭; [B2, B6, V6]; xn--qnb616fis0qzt36f.xn--4xa847hli46a; ; ; # ܠ𐹢ុ.σᢈ🝭
+xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; \u0720򲠽𐹢\u17BB.σᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; ; # ܠ𐹢ុ.σᢈ🝭
+xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; \u0720򲠽𐹢\u17BB.ςᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ; ; # ܠ𐹢ុ.ςᢈ🝭
+\u0720򲠽𐹢\u17BB。Σᢈ🝭\u200C; \u0720򲠽𐹢\u17BB.σᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, V6] # ܠ𐹢ុ.σᢈ🝭
+\u0720򲠽𐹢\u17BB。σᢈ🝭\u200C; \u0720򲠽𐹢\u17BB.σᢈ🝭\u200C; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, V6] # ܠ𐹢ុ.σᢈ🝭
+\u200D--≮。𐹧; \u200D--≮.𐹧; [B1, C2]; xn-----l1tz1k.xn--fo0d; ; xn-----ujv.xn--fo0d; [B1, V3] # --≮.𐹧
+\u200D--<\u0338。𐹧; \u200D--≮.𐹧; [B1, C2]; xn-----l1tz1k.xn--fo0d; ; xn-----ujv.xn--fo0d; [B1, V3] # --≮.𐹧
+xn-----ujv.xn--fo0d; --≮.𐹧; [B1, V3]; xn-----ujv.xn--fo0d; ; ; # --≮.𐹧
+xn-----l1tz1k.xn--fo0d; \u200D--≮.𐹧; [B1, C2]; xn-----l1tz1k.xn--fo0d; ; ; # --≮.𐹧
+\uA806。𻚏\u0FB0⒕; \uA806.𻚏\u0FB0⒕; [V5, V6]; xn--l98a.xn--dgd218hhp28d; ; ; # ꠆.ྰ⒕
+\uA806。𻚏\u0FB014.; \uA806.𻚏\u0FB014.; [V5, V6]; xn--l98a.xn--14-jsj57880f.; ; ; # ꠆.ྰ14.
+xn--l98a.xn--14-jsj57880f.; \uA806.𻚏\u0FB014.; [V5, V6]; xn--l98a.xn--14-jsj57880f.; ; ; # ꠆.ྰ14.
+xn--l98a.xn--dgd218hhp28d; \uA806.𻚏\u0FB0⒕; [V5, V6]; xn--l98a.xn--dgd218hhp28d; ; ; # ꠆.ྰ⒕
+򮉂\u06BC.𑆺\u0669; 򮉂\u06BC.𑆺\u0669; [B1, B5, B6, V5, V6]; xn--vkb92243l.xn--iib9797k; ; ; # ڼ.𑆺٩
+򮉂\u06BC.𑆺\u0669; ; [B1, B5, B6, V5, V6]; xn--vkb92243l.xn--iib9797k; ; ; # ڼ.𑆺٩
+xn--vkb92243l.xn--iib9797k; 򮉂\u06BC.𑆺\u0669; [B1, B5, B6, V5, V6]; xn--vkb92243l.xn--iib9797k; ; ; # ڼ.𑆺٩
+󠁎\u06D0-。𞤴; 󠁎\u06D0-.𞤴; [B1, V3, V6]; xn----mwc72685y.xn--se6h; ; ; # ې-.𞤴
+󠁎\u06D0-。𞤒; 󠁎\u06D0-.𞤴; [B1, V3, V6]; xn----mwc72685y.xn--se6h; ; ; # ې-.𞤴
+xn----mwc72685y.xn--se6h; 󠁎\u06D0-.𞤴; [B1, V3, V6]; xn----mwc72685y.xn--se6h; ; ; # ې-.𞤴
+𝟠4󠇗𝈻.\u200D𐋵⛧\u200D; 84𝈻.\u200D𐋵⛧\u200D; [C2]; xn--84-s850a.xn--1uga573cfq1w; ; xn--84-s850a.xn--59h6326e; [] # 84𝈻.𐋵⛧
+84󠇗𝈻.\u200D𐋵⛧\u200D; 84𝈻.\u200D𐋵⛧\u200D; [C2]; xn--84-s850a.xn--1uga573cfq1w; ; xn--84-s850a.xn--59h6326e; [] # 84𝈻.𐋵⛧
+xn--84-s850a.xn--59h6326e; 84𝈻.𐋵⛧; ; xn--84-s850a.xn--59h6326e; ; ; # 84𝈻.𐋵⛧
+84𝈻.𐋵⛧; ; ; xn--84-s850a.xn--59h6326e; ; ; # 84𝈻.𐋵⛧
+xn--84-s850a.xn--1uga573cfq1w; 84𝈻.\u200D𐋵⛧\u200D; [C2]; xn--84-s850a.xn--1uga573cfq1w; ; ; # 84𝈻.𐋵⛧
+-\u0601。ᡪ; -\u0601.ᡪ; [B1, V3, V6]; xn----tkc.xn--68e; ; ; # -.ᡪ
+-\u0601。ᡪ; -\u0601.ᡪ; [B1, V3, V6]; xn----tkc.xn--68e; ; ; # -.ᡪ
+xn----tkc.xn--68e; -\u0601.ᡪ; [B1, V3, V6]; xn----tkc.xn--68e; ; ; # -.ᡪ
+≮𝟕.謖ß≯; ≮7.謖ß≯; ; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+<\u0338𝟕.謖ß>\u0338; ≮7.謖ß≯; ; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+≮7.謖ß≯; ; ; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+<\u03387.謖ß>\u0338; ≮7.謖ß≯; ; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+<\u03387.謖SS>\u0338; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖SS≯; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖ss≯; ; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+<\u03387.謖ss>\u0338; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+<\u03387.謖Ss>\u0338; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖Ss≯; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+xn--7-mgo.xn--ss-xjvv174c; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+xn--7-mgo.xn--zca892oly5e; ≮7.謖ß≯; ; xn--7-mgo.xn--zca892oly5e; ; ; # ≮7.謖ß≯
+<\u0338𝟕.謖SS>\u0338; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖SS≯; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖ss≯; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+<\u0338𝟕.謖ss>\u0338; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+<\u0338𝟕.謖Ss>\u0338; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖Ss≯; ≮7.謖ss≯; ; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+朶Ⴉ𞪡.𝨽\u0825📻-; ; [B1, B5, B6, V3, V5, V6]; xn--hnd7245bd56p.xn----3gd37096apmwa; ; ; # 朶Ⴉ.𝨽ࠥ📻-
+朶ⴉ𞪡.𝨽\u0825📻-; ; [B1, B5, B6, V3, V5, V6]; xn--0kjz47pd57t.xn----3gd37096apmwa; ; ; # 朶ⴉ.𝨽ࠥ📻-
+xn--0kjz47pd57t.xn----3gd37096apmwa; 朶ⴉ𞪡.𝨽\u0825📻-; [B1, B5, B6, V3, V5, V6]; xn--0kjz47pd57t.xn----3gd37096apmwa; ; ; # 朶ⴉ.𝨽ࠥ📻-
+xn--hnd7245bd56p.xn----3gd37096apmwa; 朶Ⴉ𞪡.𝨽\u0825📻-; [B1, B5, B6, V3, V5, V6]; xn--hnd7245bd56p.xn----3gd37096apmwa; ; ; # 朶Ⴉ.𝨽ࠥ📻-
+𐤎。󑿰\u200C≮\u200D; 𐤎.󑿰\u200C≮\u200D; [B6, C1, C2, V6]; xn--bk9c.xn--0ugc04p2u638c; ; xn--bk9c.xn--gdhx6802k; [B6, V6] # 𐤎.≮
+𐤎。󑿰\u200C<\u0338\u200D; 𐤎.󑿰\u200C≮\u200D; [B6, C1, C2, V6]; xn--bk9c.xn--0ugc04p2u638c; ; xn--bk9c.xn--gdhx6802k; [B6, V6] # 𐤎.≮
+xn--bk9c.xn--gdhx6802k; 𐤎.󑿰≮; [B6, V6]; xn--bk9c.xn--gdhx6802k; ; ; # 𐤎.≮
+xn--bk9c.xn--0ugc04p2u638c; 𐤎.󑿰\u200C≮\u200D; [B6, C1, C2, V6]; xn--bk9c.xn--0ugc04p2u638c; ; ; # 𐤎.≮
+񭜎⒈。\u200C𝟤; 񭜎⒈.\u200C2; [C1, V6]; xn--tsh94183d.xn--2-rgn; ; xn--tsh94183d.2; [V6] # ⒈.2
+񭜎1.。\u200C2; 񭜎1..\u200C2; [C1, V6, X4_2]; xn--1-ex54e..xn--2-rgn; [C1, V6, A4_2]; xn--1-ex54e..2; [V6, A4_2] # 1..2
+xn--1-ex54e..2; 񭜎1..2; [V6, X4_2]; xn--1-ex54e..2; [V6, A4_2]; ; # 1..2
+xn--1-ex54e..xn--2-rgn; 񭜎1..\u200C2; [C1, V6, X4_2]; xn--1-ex54e..xn--2-rgn; [C1, V6, A4_2]; ; # 1..2
+xn--tsh94183d.2; 񭜎⒈.2; [V6]; xn--tsh94183d.2; ; ; # ⒈.2
+xn--tsh94183d.xn--2-rgn; 񭜎⒈.\u200C2; [C1, V6]; xn--tsh94183d.xn--2-rgn; ; ; # ⒈.2
+󠟊𐹤\u200D.𐹳󙄵𐹶; 󠟊𐹤\u200D.𐹳󙄵𐹶; [B1, C2, V6]; xn--1ugy994g7k93g.xn--ro0dga22807v; ; xn--co0d98977c.xn--ro0dga22807v; [B1, V6] # 𐹤.𐹳𐹶
+󠟊𐹤\u200D.𐹳󙄵𐹶; ; [B1, C2, V6]; xn--1ugy994g7k93g.xn--ro0dga22807v; ; xn--co0d98977c.xn--ro0dga22807v; [B1, V6] # 𐹤.𐹳𐹶
+xn--co0d98977c.xn--ro0dga22807v; 󠟊𐹤.𐹳󙄵𐹶; [B1, V6]; xn--co0d98977c.xn--ro0dga22807v; ; ; # 𐹤.𐹳𐹶
+xn--1ugy994g7k93g.xn--ro0dga22807v; 󠟊𐹤\u200D.𐹳󙄵𐹶; [B1, C2, V6]; xn--1ugy994g7k93g.xn--ro0dga22807v; ; ; # 𐹤.𐹳𐹶
+𞤴𐹻𑓂𐭝.\u094D\uFE07􉛯; 𞤴𐹻𑓂𐭝.\u094D􉛯; [B1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+𞤴𐹻𑓂𐭝.\u094D\uFE07􉛯; 𞤴𐹻𑓂𐭝.\u094D􉛯; [B1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+𞤒𐹻𑓂𐭝.\u094D\uFE07􉛯; 𞤴𐹻𑓂𐭝.\u094D􉛯; [B1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+xn--609c96c09grp2w.xn--n3b28708s; 𞤴𐹻𑓂𐭝.\u094D􉛯; [B1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+𞤒𐹻𑓂𐭝.\u094D\uFE07􉛯; 𞤴𐹻𑓂𐭝.\u094D􉛯; [B1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+\u0668。𐹠𐹽񗮶; \u0668.𐹠𐹽񗮶; [B1, V6]; xn--hib.xn--7n0d2bu9196b; ; ; # ٨.𐹠𐹽
+\u0668。𐹠𐹽񗮶; \u0668.𐹠𐹽񗮶; [B1, V6]; xn--hib.xn--7n0d2bu9196b; ; ; # ٨.𐹠𐹽
+xn--hib.xn--7n0d2bu9196b; \u0668.𐹠𐹽񗮶; [B1, V6]; xn--hib.xn--7n0d2bu9196b; ; ; # ٨.𐹠𐹽
+\u1160񍀜.8򶾵\u069C; ; [B1, V6]; xn--psd85033d.xn--8-otc61545t; ; ; # .8ڜ
+xn--psd85033d.xn--8-otc61545t; \u1160񍀜.8򶾵\u069C; [B1, V6]; xn--psd85033d.xn--8-otc61545t; ; ; # .8ڜ
+\u200D\u200C󠆪。ß𑓃; \u200D\u200C.ß𑓃; [C1, C2]; xn--0ugb.xn--zca0732l; ; .xn--ss-bh7o; [A4_2] # .ß𑓃
+\u200D\u200C󠆪。ß𑓃; \u200D\u200C.ß𑓃; [C1, C2]; xn--0ugb.xn--zca0732l; ; .xn--ss-bh7o; [A4_2] # .ß𑓃
+\u200D\u200C󠆪。SS𑓃; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+\u200D\u200C󠆪。ss𑓃; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+\u200D\u200C󠆪。Ss𑓃; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+.xn--ss-bh7o; .ss𑓃; [X4_2]; .xn--ss-bh7o; [A4_2]; ; # .ss𑓃
+xn--0ugb.xn--ss-bh7o; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; ; # .ss𑓃
+xn--0ugb.xn--zca0732l; \u200D\u200C.ß𑓃; [C1, C2]; xn--0ugb.xn--zca0732l; ; ; # .ß𑓃
+\u200D\u200C󠆪。SS𑓃; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+\u200D\u200C󠆪。ss𑓃; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+\u200D\u200C󠆪。Ss𑓃; \u200D\u200C.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+xn--ss-bh7o; ss𑓃; ; xn--ss-bh7o; ; ; # ss𑓃
+ss𑓃; ; ; xn--ss-bh7o; ; ; # ss𑓃
+SS𑓃; ss𑓃; ; xn--ss-bh7o; ; ; # ss𑓃
+Ss𑓃; ss𑓃; ; xn--ss-bh7o; ; ; # ss𑓃
+︒\u200Cヶ䒩.ꡪ; ; [C1, V6]; xn--0ug287dj0or48o.xn--gd9a; ; xn--qekw60dns9k.xn--gd9a; [V6] # ︒ヶ䒩.ꡪ
+。\u200Cヶ䒩.ꡪ; .\u200Cヶ䒩.ꡪ; [C1, X4_2]; .xn--0ug287dj0o.xn--gd9a; [C1, A4_2]; .xn--qekw60d.xn--gd9a; [A4_2] # .ヶ䒩.ꡪ
+.xn--qekw60d.xn--gd9a; .ヶ䒩.ꡪ; [X4_2]; .xn--qekw60d.xn--gd9a; [A4_2]; ; # .ヶ䒩.ꡪ
+.xn--0ug287dj0o.xn--gd9a; .\u200Cヶ䒩.ꡪ; [C1, X4_2]; .xn--0ug287dj0o.xn--gd9a; [C1, A4_2]; ; # .ヶ䒩.ꡪ
+xn--qekw60dns9k.xn--gd9a; ︒ヶ䒩.ꡪ; [V6]; xn--qekw60dns9k.xn--gd9a; ; ; # ︒ヶ䒩.ꡪ
+xn--0ug287dj0or48o.xn--gd9a; ︒\u200Cヶ䒩.ꡪ; [C1, V6]; xn--0ug287dj0or48o.xn--gd9a; ; ; # ︒ヶ䒩.ꡪ
+xn--qekw60d.xn--gd9a; ヶ䒩.ꡪ; ; xn--qekw60d.xn--gd9a; ; ; # ヶ䒩.ꡪ
+ヶ䒩.ꡪ; ; ; xn--qekw60d.xn--gd9a; ; ; # ヶ䒩.ꡪ
+\u200C⒈𤮍.󢓋\u1A60; ; [C1, V6]; xn--0ug88o7471d.xn--jof45148n; ; xn--tshw462r.xn--jof45148n; [V6] # ⒈𤮍.᩠
+\u200C1.𤮍.󢓋\u1A60; ; [C1, V6]; xn--1-rgn.xn--4x6j.xn--jof45148n; ; 1.xn--4x6j.xn--jof45148n; [V6] # 1.𤮍.᩠
+1.xn--4x6j.xn--jof45148n; 1.𤮍.󢓋\u1A60; [V6]; 1.xn--4x6j.xn--jof45148n; ; ; # 1.𤮍.᩠
+xn--1-rgn.xn--4x6j.xn--jof45148n; \u200C1.𤮍.󢓋\u1A60; [C1, V6]; xn--1-rgn.xn--4x6j.xn--jof45148n; ; ; # 1.𤮍.᩠
+xn--tshw462r.xn--jof45148n; ⒈𤮍.󢓋\u1A60; [V6]; xn--tshw462r.xn--jof45148n; ; ; # ⒈𤮍.᩠
+xn--0ug88o7471d.xn--jof45148n; \u200C⒈𤮍.󢓋\u1A60; [C1, V6]; xn--0ug88o7471d.xn--jof45148n; ; ; # ⒈𤮍.᩠
+⒈\u200C𐫓󠀺。\u1A60񤰵\u200D; ⒈\u200C𐫓󠀺.\u1A60񤰵\u200D; [B1, C1, C2, V5, V6]; xn--0ug78ol75wzcx4i.xn--jof95xex98m; ; xn--tsh4435fk263g.xn--jofz5294e; [B1, V5, V6] # ⒈𐫓.᩠
+1.\u200C𐫓󠀺。\u1A60񤰵\u200D; 1.\u200C𐫓󠀺.\u1A60񤰵\u200D; [B1, C1, C2, V5, V6]; 1.xn--0ug8853gk263g.xn--jof95xex98m; ; 1.xn--8w9c40377c.xn--jofz5294e; [B1, B3, V5, V6] # 1.𐫓.᩠
+1.xn--8w9c40377c.xn--jofz5294e; 1.𐫓󠀺.\u1A60񤰵; [B1, B3, V5, V6]; 1.xn--8w9c40377c.xn--jofz5294e; ; ; # 1.𐫓.᩠
+1.xn--0ug8853gk263g.xn--jof95xex98m; 1.\u200C𐫓󠀺.\u1A60񤰵\u200D; [B1, C1, C2, V5, V6]; 1.xn--0ug8853gk263g.xn--jof95xex98m; ; ; # 1.𐫓.᩠
+xn--tsh4435fk263g.xn--jofz5294e; ⒈𐫓󠀺.\u1A60񤰵; [B1, V5, V6]; xn--tsh4435fk263g.xn--jofz5294e; ; ; # ⒈𐫓.᩠
+xn--0ug78ol75wzcx4i.xn--jof95xex98m; ⒈\u200C𐫓󠀺.\u1A60񤰵\u200D; [B1, C1, C2, V5, V6]; xn--0ug78ol75wzcx4i.xn--jof95xex98m; ; ; # ⒈𐫓.᩠
+𝅵。𝟫𞀈䬺⒈; 𝅵.9𞀈䬺⒈; [V6]; xn--3f1h.xn--9-ecp936non25a; ; ; # .9𞀈䬺⒈
+𝅵。9𞀈䬺1.; 𝅵.9𞀈䬺1.; [V6]; xn--3f1h.xn--91-030c1650n.; ; ; # .9𞀈䬺1.
+xn--3f1h.xn--91-030c1650n.; 𝅵.9𞀈䬺1.; [V6]; xn--3f1h.xn--91-030c1650n.; ; ; # .9𞀈䬺1.
+xn--3f1h.xn--9-ecp936non25a; 𝅵.9𞀈䬺⒈; [V6]; xn--3f1h.xn--9-ecp936non25a; ; ; # .9𞀈䬺⒈
+򡼺≯。盚\u0635; 򡼺≯.盚\u0635; [B5, B6, V6]; xn--hdh30181h.xn--0gb7878c; ; ; # ≯.盚ص
+򡼺>\u0338。盚\u0635; 򡼺≯.盚\u0635; [B5, B6, V6]; xn--hdh30181h.xn--0gb7878c; ; ; # ≯.盚ص
+xn--hdh30181h.xn--0gb7878c; 򡼺≯.盚\u0635; [B5, B6, V6]; xn--hdh30181h.xn--0gb7878c; ; ; # ≯.盚ص
+-񿰭\u05B4。-󠁊𐢸≯; -񿰭\u05B4.-󠁊𐢸≯; [B1, V3, V6]; xn----fgc06667m.xn----pgoy615he5y4i; ; ; # -ִ.-≯
+-񿰭\u05B4。-󠁊𐢸>\u0338; -񿰭\u05B4.-󠁊𐢸≯; [B1, V3, V6]; xn----fgc06667m.xn----pgoy615he5y4i; ; ; # -ִ.-≯
+xn----fgc06667m.xn----pgoy615he5y4i; -񿰭\u05B4.-󠁊𐢸≯; [B1, V3, V6]; xn----fgc06667m.xn----pgoy615he5y4i; ; ; # -ִ.-≯
+󿭓\u1B44\u200C\u0A4D.𐭛񳋔; 󿭓\u1B44\u200C\u0A4D.𐭛񳋔; [B2, B3, B6, V6]; xn--ybc997f6rd2n772c.xn--409c6100y; ; xn--ybc997fb5881a.xn--409c6100y; [B2, B3, V6] # ᭄੍.𐭛
+󿭓\u1B44\u200C\u0A4D.𐭛񳋔; ; [B2, B3, B6, V6]; xn--ybc997f6rd2n772c.xn--409c6100y; ; xn--ybc997fb5881a.xn--409c6100y; [B2, B3, V6] # ᭄੍.𐭛
+xn--ybc997fb5881a.xn--409c6100y; 󿭓\u1B44\u0A4D.𐭛񳋔; [B2, B3, V6]; xn--ybc997fb5881a.xn--409c6100y; ; ; # ᭄੍.𐭛
+xn--ybc997f6rd2n772c.xn--409c6100y; 󿭓\u1B44\u200C\u0A4D.𐭛񳋔; [B2, B3, B6, V6]; xn--ybc997f6rd2n772c.xn--409c6100y; ; ; # ᭄੍.𐭛
+⾇.\u067D𞤴\u06BB\u200D; 舛.\u067D𞤴\u06BB\u200D; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+舛.\u067D𞤴\u06BB\u200D; ; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+舛.\u067D𞤒\u06BB\u200D; 舛.\u067D𞤴\u06BB\u200D; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+xn--8c1a.xn--2ib8jn539l; 舛.\u067D𞤴\u06BB; ; xn--8c1a.xn--2ib8jn539l; ; ; # 舛.ٽ𞤴ڻ
+舛.\u067D𞤴\u06BB; ; ; xn--8c1a.xn--2ib8jn539l; ; ; # 舛.ٽ𞤴ڻ
+舛.\u067D𞤒\u06BB; 舛.\u067D𞤴\u06BB; ; xn--8c1a.xn--2ib8jn539l; ; ; # 舛.ٽ𞤴ڻ
+xn--8c1a.xn--2ib8jv19e6413b; 舛.\u067D𞤴\u06BB\u200D; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; ; # 舛.ٽ𞤴ڻ
+⾇.\u067D𞤒\u06BB\u200D; 舛.\u067D𞤴\u06BB\u200D; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+4򭆥。\u0767≯; 4򭆥.\u0767≯; [B1, B3, V6]; xn--4-xn17i.xn--rpb459k; ; ; # 4.ݧ≯
+4򭆥。\u0767>\u0338; 4򭆥.\u0767≯; [B1, B3, V6]; xn--4-xn17i.xn--rpb459k; ; ; # 4.ݧ≯
+xn--4-xn17i.xn--rpb459k; 4򭆥.\u0767≯; [B1, B3, V6]; xn--4-xn17i.xn--rpb459k; ; ; # 4.ݧ≯
+𲔏𞫨񺿂硲.\u06AD; 𲔏𞫨񺿂硲.\u06AD; [B5, V6]; xn--lcz1610fn78gk609a.xn--gkb; ; ; # 硲.ڭ
+𲔏𞫨񺿂硲.\u06AD; ; [B5, V6]; xn--lcz1610fn78gk609a.xn--gkb; ; ; # 硲.ڭ
+xn--lcz1610fn78gk609a.xn--gkb; 𲔏𞫨񺿂硲.\u06AD; [B5, V6]; xn--lcz1610fn78gk609a.xn--gkb; ; ; # 硲.ڭ
+\u200C.\uFE08\u0666Ⴆ℮; \u200C.\u0666Ⴆ℮; [B1, C1, V6]; xn--0ug.xn--fib263c0yn; ; .xn--fib263c0yn; [B1, V6, A4_2] # .٦Ⴆ℮
+\u200C.\uFE08\u0666ⴆ℮; \u200C.\u0666ⴆ℮; [B1, C1]; xn--0ug.xn--fib628k4li; ; .xn--fib628k4li; [B1, A4_2] # .٦ⴆ℮
+.xn--fib628k4li; .\u0666ⴆ℮; [B1, X4_2]; .xn--fib628k4li; [B1, A4_2]; ; # .٦ⴆ℮
+xn--0ug.xn--fib628k4li; \u200C.\u0666ⴆ℮; [B1, C1]; xn--0ug.xn--fib628k4li; ; ; # .٦ⴆ℮
+.xn--fib263c0yn; .\u0666Ⴆ℮; [B1, V6, X4_2]; .xn--fib263c0yn; [B1, V6, A4_2]; ; # .٦Ⴆ℮
+xn--0ug.xn--fib263c0yn; \u200C.\u0666Ⴆ℮; [B1, C1, V6]; xn--0ug.xn--fib263c0yn; ; ; # .٦Ⴆ℮
+\u06A3.\u0D4D\u200DϞ; \u06A3.\u0D4D\u200Dϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+\u06A3.\u0D4D\u200DϞ; \u06A3.\u0D4D\u200Dϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+\u06A3.\u0D4D\u200Dϟ; ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+xn--5jb.xn--xya149b; \u06A3.\u0D4Dϟ; [B1, V5]; xn--5jb.xn--xya149b; ; ; # ڣ.്ϟ
+xn--5jb.xn--xya149bpvp; \u06A3.\u0D4D\u200Dϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; ; # ڣ.്ϟ
+\u06A3.\u0D4D\u200Dϟ; \u06A3.\u0D4D\u200Dϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+\u200C𞸇𑘿。\u0623𐮂-腍; \u200C\u062D𑘿.\u0623𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+\u200C𞸇𑘿。\u0627\u0654𐮂-腍; \u200C\u062D𑘿.\u0623𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+\u200C\u062D𑘿。\u0623𐮂-腍; \u200C\u062D𑘿.\u0623𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+\u200C\u062D𑘿。\u0627\u0654𐮂-腍; \u200C\u062D𑘿.\u0623𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+xn--sgb4140l.xn----qmc5075grs9e; \u062D𑘿.\u0623𐮂-腍; [B2, B3]; xn--sgb4140l.xn----qmc5075grs9e; ; ; # ح𑘿.أ𐮂-腍
+xn--sgb953kmi8o.xn----qmc5075grs9e; \u200C\u062D𑘿.\u0623𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; ; # ح𑘿.أ𐮂-腍
+-򭷙\u066B纛。𝟛񭤇🄅; -򭷙\u066B纛.3񭤇🄅; [B1, V3, V6]; xn----vqc8143g0tt4i.xn--3-os1sn476y; ; ; # -٫纛.3🄅
+-򭷙\u066B纛。3񭤇4,; -򭷙\u066B纛.3񭤇4,; [B1, V3, V6]; xn----vqc8143g0tt4i.xn--34,-8787l; ; ; # -٫纛.34,
+xn----vqc8143g0tt4i.xn--34,-8787l; -򭷙\u066B纛.3񭤇4,; [B1, V3, V6]; xn----vqc8143g0tt4i.xn--34,-8787l; ; ; # -٫纛.34,
+xn----vqc8143g0tt4i.xn--3-os1sn476y; -򭷙\u066B纛.3񭤇🄅; [B1, V3, V6]; xn----vqc8143g0tt4i.xn--3-os1sn476y; ; ; # -٫纛.3🄅
+🔔.Ⴂ\u07CC\u0BCD𐋮; 🔔.Ⴂ\u07CC\u0BCD𐋮; [B1, B5, V6]; xn--nv8h.xn--nsb46r83e8112a; ; ; # 🔔.Ⴂߌ்𐋮
+🔔.Ⴂ\u07CC\u0BCD𐋮; ; [B1, B5, V6]; xn--nv8h.xn--nsb46r83e8112a; ; ; # 🔔.Ⴂߌ்𐋮
+🔔.ⴂ\u07CC\u0BCD𐋮; ; [B1, B5]; xn--nv8h.xn--nsb46rvz1b222p; ; ; # 🔔.ⴂߌ்𐋮
+xn--nv8h.xn--nsb46rvz1b222p; 🔔.ⴂ\u07CC\u0BCD𐋮; [B1, B5]; xn--nv8h.xn--nsb46rvz1b222p; ; ; # 🔔.ⴂߌ்𐋮
+xn--nv8h.xn--nsb46r83e8112a; 🔔.Ⴂ\u07CC\u0BCD𐋮; [B1, B5, V6]; xn--nv8h.xn--nsb46r83e8112a; ; ; # 🔔.Ⴂߌ்𐋮
+🔔.ⴂ\u07CC\u0BCD𐋮; 🔔.ⴂ\u07CC\u0BCD𐋮; [B1, B5]; xn--nv8h.xn--nsb46rvz1b222p; ; ; # 🔔.ⴂߌ்𐋮
+軥\u06B3.-𖬵; ; [B1, B5, B6, V3]; xn--mkb5480e.xn----6u5m; ; ; # 軥ڳ.-𖬵
+xn--mkb5480e.xn----6u5m; 軥\u06B3.-𖬵; [B1, B5, B6, V3]; xn--mkb5480e.xn----6u5m; ; ; # 軥ڳ.-𖬵
+𐹤\u07CA\u06B6.𐨂-; ; [B1, V3, V5]; xn--pkb56cn614d.xn----974i; ; ; # 𐹤ߊڶ.𐨂-
+xn--pkb56cn614d.xn----974i; 𐹤\u07CA\u06B6.𐨂-; [B1, V3, V5]; xn--pkb56cn614d.xn----974i; ; ; # 𐹤ߊڶ.𐨂-
+-󠅱0。\u17CF\u1DFD톇십; -0.\u17CF\u1DFD톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-󠅱0。\u17CF\u1DFD톇십; -0.\u17CF\u1DFD톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-󠅱0。\u17CF\u1DFD톇십; -0.\u17CF\u1DFD톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-󠅱0。\u17CF\u1DFD톇십; -0.\u17CF\u1DFD톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-0.xn--r4e872ah77nghm; -0.\u17CF\u1DFD톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+ꡰ︒--。\u17CC靈𐹢񘳮; ꡰ︒--.\u17CC靈𐹢񘳮; [B1, B6, V2, V3, V5, V6]; xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ; ; # ꡰ︒--.៌靈𐹢
+ꡰ。--。\u17CC靈𐹢񘳮; ꡰ.--.\u17CC靈𐹢񘳮; [B1, V3, V5, V6]; xn--md9a.--.xn--o4e6836dpxudz0v1c; ; ; # ꡰ.--.៌靈𐹢
+xn--md9a.--.xn--o4e6836dpxudz0v1c; ꡰ.--.\u17CC靈𐹢񘳮; [B1, V3, V5, V6]; xn--md9a.--.xn--o4e6836dpxudz0v1c; ; ; # ꡰ.--.៌靈𐹢
+xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ꡰ︒--.\u17CC靈𐹢񘳮; [B1, B6, V2, V3, V5, V6]; xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ; ; # ꡰ︒--.៌靈𐹢
+\u115FႿႵრ。\u0B4D; \u115FႿႵრ.\u0B4D; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+\u115FႿႵრ。\u0B4D; \u115FႿႵრ.\u0B4D; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+\u115Fⴟⴕრ。\u0B4D; \u115Fⴟⴕრ.\u0B4D; [V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+\u115FႿႵᲠ。\u0B4D; \u115FႿႵრ.\u0B4D; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+xn--tndt4hvw.xn--9ic; \u115FႿႵრ.\u0B4D; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+xn--1od7wz74eeb.xn--9ic; \u115Fⴟⴕრ.\u0B4D; [V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+\u115Fⴟⴕრ。\u0B4D; \u115Fⴟⴕრ.\u0B4D; [V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+\u115FႿႵᲠ。\u0B4D; \u115FႿႵრ.\u0B4D; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+\u115FႿⴕრ。\u0B4D; \u115FႿⴕრ.\u0B4D; [V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
+xn--3nd0etsm92g.xn--9ic; \u115FႿⴕრ.\u0B4D; [V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
+\u115FႿⴕრ。\u0B4D; \u115FႿⴕრ.\u0B4D; [V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
+🄃𐹠.\u0664󠅇; 🄃𐹠.\u0664; [B1, V6]; xn--7n0d1189a.xn--dib; ; ; # 🄃𐹠.٤
+2,𐹠.\u0664󠅇; 2,𐹠.\u0664; [B1, V6]; xn--2,-5g3o.xn--dib; ; ; # 2,𐹠.٤
+xn--2,-5g3o.xn--dib; 2,𐹠.\u0664; [B1, V6]; xn--2,-5g3o.xn--dib; ; ; # 2,𐹠.٤
+xn--7n0d1189a.xn--dib; 🄃𐹠.\u0664; [B1, V6]; xn--7n0d1189a.xn--dib; ; ; # 🄃𐹠.٤
+򻲼\u200C\uFC5B.\u07D2\u0848\u1BF3; 򻲼\u200C\u0630\u0670.\u07D2\u0848\u1BF3; [B2, B3, B5, B6, C1, V6]; xn--vgb2kq00fl213y.xn--tsb0vz43c; ; xn--vgb2kp1223g.xn--tsb0vz43c; [B2, B3, B5, B6, V6] # ذٰ.ߒࡈ᯳
+򻲼\u200C\u0630\u0670.\u07D2\u0848\u1BF3; ; [B2, B3, B5, B6, C1, V6]; xn--vgb2kq00fl213y.xn--tsb0vz43c; ; xn--vgb2kp1223g.xn--tsb0vz43c; [B2, B3, B5, B6, V6] # ذٰ.ߒࡈ᯳
+xn--vgb2kp1223g.xn--tsb0vz43c; 򻲼\u0630\u0670.\u07D2\u0848\u1BF3; [B2, B3, B5, B6, V6]; xn--vgb2kp1223g.xn--tsb0vz43c; ; ; # ذٰ.ߒࡈ᯳
+xn--vgb2kq00fl213y.xn--tsb0vz43c; 򻲼\u200C\u0630\u0670.\u07D2\u0848\u1BF3; [B2, B3, B5, B6, C1, V6]; xn--vgb2kq00fl213y.xn--tsb0vz43c; ; ; # ذٰ.ߒࡈ᯳
+\u200D\u200D𞵪\u200C。ᡘ𑲭\u17B5; \u200D\u200D𞵪\u200C.ᡘ𑲭\u17B5; [B1, C1, C2, V6]; xn--0ugba05538b.xn--03e93aq365d; ; xn--l96h.xn--03e93aq365d; [V6] # .ᡘ𑲭
+xn--l96h.xn--03e93aq365d; 𞵪.ᡘ𑲭\u17B5; [V6]; xn--l96h.xn--03e93aq365d; ; ; # .ᡘ𑲭
+xn--0ugba05538b.xn--03e93aq365d; \u200D\u200D𞵪\u200C.ᡘ𑲭\u17B5; [B1, C1, C2, V6]; xn--0ugba05538b.xn--03e93aq365d; ; ; # .ᡘ𑲭
+𞷻。⚄񗑇𑁿; 𞷻.⚄񗑇𑁿; [B1, V6]; xn--qe7h.xn--c7h2966f7so4a; ; ; # .⚄𑁿
+xn--qe7h.xn--c7h2966f7so4a; 𞷻.⚄񗑇𑁿; [B1, V6]; xn--qe7h.xn--c7h2966f7so4a; ; ; # .⚄𑁿
+\uA8C4≠.𞠨\u0667; \uA8C4≠.𞠨\u0667; [B1, V5]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+\uA8C4=\u0338.𞠨\u0667; \uA8C4≠.𞠨\u0667; [B1, V5]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+\uA8C4≠.𞠨\u0667; ; [B1, V5]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+\uA8C4=\u0338.𞠨\u0667; \uA8C4≠.𞠨\u0667; [B1, V5]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+xn--1chy504c.xn--gib1777v; \uA8C4≠.𞠨\u0667; [B1, V5]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+𝟛𝆪\uA8C4。\uA8EA-; 3\uA8C4𝆪.\uA8EA-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+𝟛\uA8C4𝆪。\uA8EA-; 3\uA8C4𝆪.\uA8EA-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+3\uA8C4𝆪。\uA8EA-; 3\uA8C4𝆪.\uA8EA-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+xn--3-sl4eu679e.xn----xn4e; 3\uA8C4𝆪.\uA8EA-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+\u075F\u1BA2\u103AႧ.4; ; [B1, B2, B3, V6]; xn--jpb846bmjw88a.4; ; ; # ݟᮢ်Ⴇ.4
+\u075F\u1BA2\u103Aⴇ.4; ; [B1, B2, B3]; xn--jpb846bjzj7pr.4; ; ; # ݟᮢ်ⴇ.4
+xn--jpb846bjzj7pr.4; \u075F\u1BA2\u103Aⴇ.4; [B1, B2, B3]; xn--jpb846bjzj7pr.4; ; ; # ݟᮢ်ⴇ.4
+xn--jpb846bmjw88a.4; \u075F\u1BA2\u103AႧ.4; [B1, B2, B3, V6]; xn--jpb846bmjw88a.4; ; ; # ݟᮢ်Ⴇ.4
+ᄹ。\u0ECA򠯤󠄞; ᄹ.\u0ECA򠯤; [V5, V6]; xn--lrd.xn--s8c05302k; ; ; # ᄹ.໊
+ᄹ。\u0ECA򠯤󠄞; ᄹ.\u0ECA򠯤; [V5, V6]; xn--lrd.xn--s8c05302k; ; ; # ᄹ.໊
+xn--lrd.xn--s8c05302k; ᄹ.\u0ECA򠯤; [V5, V6]; xn--lrd.xn--s8c05302k; ; ; # ᄹ.໊
+Ⴆ򻢩.󠆡\uFE09𞤍; Ⴆ򻢩.𞤯; [V6]; xn--end82983m.xn--ne6h; ; ; # Ⴆ.𞤯
+Ⴆ򻢩.󠆡\uFE09𞤍; Ⴆ򻢩.𞤯; [V6]; xn--end82983m.xn--ne6h; ; ; # Ⴆ.𞤯
+ⴆ򻢩.󠆡\uFE09𞤯; ⴆ򻢩.𞤯; [V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+xn--xkjw3965g.xn--ne6h; ⴆ򻢩.𞤯; [V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+xn--end82983m.xn--ne6h; Ⴆ򻢩.𞤯; [V6]; xn--end82983m.xn--ne6h; ; ; # Ⴆ.𞤯
+ⴆ򻢩.󠆡\uFE09𞤯; ⴆ򻢩.𞤯; [V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+ⴆ򻢩.󠆡\uFE09𞤍; ⴆ򻢩.𞤯; [V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+ⴆ򻢩.󠆡\uFE09𞤍; ⴆ򻢩.𞤯; [V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+ß\u080B︒\u067B.帼F∬\u200C; ß\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, V6] # ßࠋ︒ٻ.帼f∫∫
+ß\u080B。\u067B.帼F∫∫\u200C; ß\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ßࠋ.ٻ.帼f∫∫
+ß\u080B。\u067B.帼f∫∫\u200C; ß\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ßࠋ.ٻ.帼f∫∫
+SS\u080B。\u067B.帼F∫∫\u200C; ss\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ssࠋ.ٻ.帼f∫∫
+ss\u080B。\u067B.帼f∫∫\u200C; ss\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ssࠋ.ٻ.帼f∫∫
+Ss\u080B。\u067B.帼F∫∫\u200C; ss\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ssࠋ.ٻ.帼f∫∫
+xn--ss-uze.xn--0ib.xn--f-tcoa9162d; ss\u080B.\u067B.帼f∫∫; [B5, B6]; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; ; ; # ssࠋ.ٻ.帼f∫∫
+xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ss\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; ; # ssࠋ.ٻ.帼f∫∫
+xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ß\u080B.\u067B.帼f∫∫\u200C; [B5, B6, C1]; xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ; ; # ßࠋ.ٻ.帼f∫∫
+ß\u080B︒\u067B.帼f∬\u200C; ß\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, V6] # ßࠋ︒ٻ.帼f∫∫
+SS\u080B︒\u067B.帼F∬\u200C; ss\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, V6] # ssࠋ︒ٻ.帼f∫∫
+ss\u080B︒\u067B.帼f∬\u200C; ss\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, V6] # ssࠋ︒ٻ.帼f∫∫
+Ss\u080B︒\u067B.帼F∬\u200C; ss\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, V6] # ssࠋ︒ٻ.帼f∫∫
+xn--ss-k0d31nu121d.xn--f-tcoa9162d; ss\u080B︒\u067B.帼f∫∫; [B5, B6, V6]; xn--ss-k0d31nu121d.xn--f-tcoa9162d; ; ; # ssࠋ︒ٻ.帼f∫∫
+xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ss\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; ; # ssࠋ︒ٻ.帼f∫∫
+xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ß\u080B︒\u067B.帼f∫∫\u200C; [B5, B6, C1, V6]; xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ; ; # ßࠋ︒ٻ.帼f∫∫
+󘪗。𐹴𞨌\u200D; 󘪗.𐹴𞨌\u200D; [B1, C2, V6]; xn--8l83e.xn--1ug4105gsxwf; ; xn--8l83e.xn--so0dw168a; [B1, V6] # .𐹴
+󘪗。𐹴𞨌\u200D; 󘪗.𐹴𞨌\u200D; [B1, C2, V6]; xn--8l83e.xn--1ug4105gsxwf; ; xn--8l83e.xn--so0dw168a; [B1, V6] # .𐹴
+xn--8l83e.xn--so0dw168a; 󘪗.𐹴𞨌; [B1, V6]; xn--8l83e.xn--so0dw168a; ; ; # .𐹴
+xn--8l83e.xn--1ug4105gsxwf; 󘪗.𐹴𞨌\u200D; [B1, C2, V6]; xn--8l83e.xn--1ug4105gsxwf; ; ; # .𐹴
+񗛨.򅟢𝟨\uA8C4; 񗛨.򅟢6\uA8C4; [V6]; xn--mi60a.xn--6-sl4es8023c; ; ; # .6꣄
+񗛨.򅟢6\uA8C4; ; [V6]; xn--mi60a.xn--6-sl4es8023c; ; ; # .6꣄
+xn--mi60a.xn--6-sl4es8023c; 񗛨.򅟢6\uA8C4; [V6]; xn--mi60a.xn--6-sl4es8023c; ; ; # .6꣄
+\u1AB2\uFD8E。-۹ႱႨ; \u1AB2\u0645\u062E\u062C.-۹ႱႨ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc155e9a; ; ; # ᪲مخج.-۹ႱႨ
+\u1AB2\u0645\u062E\u062C。-۹ႱႨ; \u1AB2\u0645\u062E\u062C.-۹ႱႨ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc155e9a; ; ; # ᪲مخج.-۹ႱႨ
+\u1AB2\u0645\u062E\u062C。-۹ⴑⴈ; \u1AB2\u0645\u062E\u062C.-۹ⴑⴈ; [B1, V3, V5]; xn--rgbd2e831i.xn----zyc3430a9a; ; ; # ᪲مخج.-۹ⴑⴈ
+xn--rgbd2e831i.xn----zyc3430a9a; \u1AB2\u0645\u062E\u062C.-۹ⴑⴈ; [B1, V3, V5]; xn--rgbd2e831i.xn----zyc3430a9a; ; ; # ᪲مخج.-۹ⴑⴈ
+xn--rgbd2e831i.xn----zyc155e9a; \u1AB2\u0645\u062E\u062C.-۹ႱႨ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc155e9a; ; ; # ᪲مخج.-۹ႱႨ
+\u1AB2\uFD8E。-۹ⴑⴈ; \u1AB2\u0645\u062E\u062C.-۹ⴑⴈ; [B1, V3, V5]; xn--rgbd2e831i.xn----zyc3430a9a; ; ; # ᪲مخج.-۹ⴑⴈ
+\u1AB2\u0645\u062E\u062C。-۹Ⴑⴈ; \u1AB2\u0645\u062E\u062C.-۹Ⴑⴈ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc875efr3a; ; ; # ᪲مخج.-۹Ⴑⴈ
+xn--rgbd2e831i.xn----zyc875efr3a; \u1AB2\u0645\u062E\u062C.-۹Ⴑⴈ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc875efr3a; ; ; # ᪲مخج.-۹Ⴑⴈ
+\u1AB2\uFD8E。-۹Ⴑⴈ; \u1AB2\u0645\u062E\u062C.-۹Ⴑⴈ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc875efr3a; ; ; # ᪲مخج.-۹Ⴑⴈ
+𞤤.-\u08A3︒; 𞤤.-\u08A3︒; [B1, V3, V6]; xn--ce6h.xn----cod7069p; ; ; # 𞤤.-ࢣ︒
+𞤤.-\u08A3。; 𞤤.-\u08A3.; [B1, V3]; xn--ce6h.xn----cod.; ; ; # 𞤤.-ࢣ.
+𞤂.-\u08A3。; 𞤤.-\u08A3.; [B1, V3]; xn--ce6h.xn----cod.; ; ; # 𞤤.-ࢣ.
+xn--ce6h.xn----cod.; 𞤤.-\u08A3.; [B1, V3]; xn--ce6h.xn----cod.; ; ; # 𞤤.-ࢣ.
+𞤂.-\u08A3︒; 𞤤.-\u08A3︒; [B1, V3, V6]; xn--ce6h.xn----cod7069p; ; ; # 𞤤.-ࢣ︒
+xn--ce6h.xn----cod7069p; 𞤤.-\u08A3︒; [B1, V3, V6]; xn--ce6h.xn----cod7069p; ; ; # 𞤤.-ࢣ︒
+\u200C𐺨.\u0859--; ; [B1, C1, V3, V5]; xn--0ug7905g.xn-----h6e; ; xn--9p0d.xn-----h6e; [B1, V3, V5] # 𐺨.࡙--
+xn--9p0d.xn-----h6e; 𐺨.\u0859--; [B1, V3, V5]; xn--9p0d.xn-----h6e; ; ; # 𐺨.࡙--
+xn--0ug7905g.xn-----h6e; \u200C𐺨.\u0859--; [B1, C1, V3, V5]; xn--0ug7905g.xn-----h6e; ; ; # 𐺨.࡙--
+𐋸󮘋Ⴢ.Ⴁ; ; [V6]; xn--6nd5215jr2u0h.xn--8md; ; ; # 𐋸Ⴢ.Ⴁ
+𐋸󮘋ⴢ.ⴁ; ; [V6]; xn--qlj1559dr224h.xn--skj; ; ; # 𐋸ⴢ.ⴁ
+𐋸󮘋Ⴢ.ⴁ; ; [V6]; xn--6nd5215jr2u0h.xn--skj; ; ; # 𐋸Ⴢ.ⴁ
+xn--6nd5215jr2u0h.xn--skj; 𐋸󮘋Ⴢ.ⴁ; [V6]; xn--6nd5215jr2u0h.xn--skj; ; ; # 𐋸Ⴢ.ⴁ
+xn--qlj1559dr224h.xn--skj; 𐋸󮘋ⴢ.ⴁ; [V6]; xn--qlj1559dr224h.xn--skj; ; ; # 𐋸ⴢ.ⴁ
+xn--6nd5215jr2u0h.xn--8md; 𐋸󮘋Ⴢ.Ⴁ; [V6]; xn--6nd5215jr2u0h.xn--8md; ; ; # 𐋸Ⴢ.Ⴁ
+񗑿\uA806₄򩞆。𲩧󠒹ς; 񗑿\uA8064򩞆.𲩧󠒹ς; [V6]; xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; ; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; # ꠆4.ς
+񗑿\uA8064򩞆。𲩧󠒹ς; 񗑿\uA8064򩞆.𲩧󠒹ς; [V6]; xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; ; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; # ꠆4.ς
+񗑿\uA8064򩞆。𲩧󠒹Σ; 񗑿\uA8064򩞆.𲩧󠒹σ; [V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+񗑿\uA8064򩞆。𲩧󠒹σ; 񗑿\uA8064򩞆.𲩧󠒹σ; [V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; 񗑿\uA8064򩞆.𲩧󠒹σ; [V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; 񗑿\uA8064򩞆.𲩧󠒹ς; [V6]; xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; ; ; # ꠆4.ς
+񗑿\uA806₄򩞆。𲩧󠒹Σ; 񗑿\uA8064򩞆.𲩧󠒹σ; [V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+񗑿\uA806₄򩞆。𲩧󠒹σ; 񗑿\uA8064򩞆.𲩧󠒹σ; [V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+󠆀\u0723。\u1DF4\u0775; \u0723.\u1DF4\u0775; [B1, V5]; xn--tnb.xn--5pb136i; ; ; # ܣ.ᷴݵ
+xn--tnb.xn--5pb136i; \u0723.\u1DF4\u0775; [B1, V5]; xn--tnb.xn--5pb136i; ; ; # ܣ.ᷴݵ
+𐹱\u0842𝪨。𬼖Ⴑ\u200D; 𐹱\u0842𝪨.𬼖Ⴑ\u200D; [B1, B6, C2, V6]; xn--0vb1535kdb6e.xn--pnd879eqy33c; ; xn--0vb1535kdb6e.xn--pnd93707a; [B1, V6] # 𐹱ࡂ𝪨.𬼖Ⴑ
+𐹱\u0842𝪨。𬼖Ⴑ\u200D; 𐹱\u0842𝪨.𬼖Ⴑ\u200D; [B1, B6, C2, V6]; xn--0vb1535kdb6e.xn--pnd879eqy33c; ; xn--0vb1535kdb6e.xn--pnd93707a; [B1, V6] # 𐹱ࡂ𝪨.𬼖Ⴑ
+𐹱\u0842𝪨。𬼖ⴑ\u200D; 𐹱\u0842𝪨.𬼖ⴑ\u200D; [B1, B6, C2]; xn--0vb1535kdb6e.xn--1ug742c5714c; ; xn--0vb1535kdb6e.xn--8kjz186s; [B1] # 𐹱ࡂ𝪨.𬼖ⴑ
+xn--0vb1535kdb6e.xn--8kjz186s; 𐹱\u0842𝪨.𬼖ⴑ; [B1]; xn--0vb1535kdb6e.xn--8kjz186s; ; ; # 𐹱ࡂ𝪨.𬼖ⴑ
+xn--0vb1535kdb6e.xn--1ug742c5714c; 𐹱\u0842𝪨.𬼖ⴑ\u200D; [B1, B6, C2]; xn--0vb1535kdb6e.xn--1ug742c5714c; ; ; # 𐹱ࡂ𝪨.𬼖ⴑ
+xn--0vb1535kdb6e.xn--pnd93707a; 𐹱\u0842𝪨.𬼖Ⴑ; [B1, V6]; xn--0vb1535kdb6e.xn--pnd93707a; ; ; # 𐹱ࡂ𝪨.𬼖Ⴑ
+xn--0vb1535kdb6e.xn--pnd879eqy33c; 𐹱\u0842𝪨.𬼖Ⴑ\u200D; [B1, B6, C2, V6]; xn--0vb1535kdb6e.xn--pnd879eqy33c; ; ; # 𐹱ࡂ𝪨.𬼖Ⴑ
+𐹱\u0842𝪨。𬼖ⴑ\u200D; 𐹱\u0842𝪨.𬼖ⴑ\u200D; [B1, B6, C2]; xn--0vb1535kdb6e.xn--1ug742c5714c; ; xn--0vb1535kdb6e.xn--8kjz186s; [B1] # 𐹱ࡂ𝪨.𬼖ⴑ
+\u1714𐭪󠙘\u200D。-𐹴; \u1714𐭪󠙘\u200D.-𐹴; [B1, C2, V3, V5, V6]; xn--fze807bso0spy14i.xn----c36i; ; xn--fze4126jujt0g.xn----c36i; [B1, V3, V5, V6] # ᜔𐭪.-𐹴
+\u1714𐭪󠙘\u200D。-𐹴; \u1714𐭪󠙘\u200D.-𐹴; [B1, C2, V3, V5, V6]; xn--fze807bso0spy14i.xn----c36i; ; xn--fze4126jujt0g.xn----c36i; [B1, V3, V5, V6] # ᜔𐭪.-𐹴
+xn--fze4126jujt0g.xn----c36i; \u1714𐭪󠙘.-𐹴; [B1, V3, V5, V6]; xn--fze4126jujt0g.xn----c36i; ; ; # ᜔𐭪.-𐹴
+xn--fze807bso0spy14i.xn----c36i; \u1714𐭪󠙘\u200D.-𐹴; [B1, C2, V3, V5, V6]; xn--fze807bso0spy14i.xn----c36i; ; ; # ᜔𐭪.-𐹴
+𾢬。\u0729︒쯙𝟧; 𾢬.\u0729︒쯙5; [B2, V6]; xn--t92s.xn--5-p1c0712mm8rb; ; ; # .ܩ︒쯙5
+𾢬。\u0729︒쯙𝟧; 𾢬.\u0729︒쯙5; [B2, V6]; xn--t92s.xn--5-p1c0712mm8rb; ; ; # .ܩ︒쯙5
+𾢬。\u0729。쯙5; 𾢬.\u0729.쯙5; [V6]; xn--t92s.xn--znb.xn--5-y88f; ; ; # .ܩ.쯙5
+𾢬。\u0729。쯙5; 𾢬.\u0729.쯙5; [V6]; xn--t92s.xn--znb.xn--5-y88f; ; ; # .ܩ.쯙5
+xn--t92s.xn--znb.xn--5-y88f; 𾢬.\u0729.쯙5; [V6]; xn--t92s.xn--znb.xn--5-y88f; ; ; # .ܩ.쯙5
+xn--t92s.xn--5-p1c0712mm8rb; 𾢬.\u0729︒쯙5; [B2, V6]; xn--t92s.xn--5-p1c0712mm8rb; ; ; # .ܩ︒쯙5
+𞤟-。\u0762≮뻐; 𞥁-.\u0762≮뻐; [B2, B3, V3]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞤟-。\u0762<\u0338뻐; 𞥁-.\u0762≮뻐; [B2, B3, V3]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞥁-。\u0762<\u0338뻐; 𞥁-.\u0762≮뻐; [B2, B3, V3]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞥁-。\u0762≮뻐; 𞥁-.\u0762≮뻐; [B2, B3, V3]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+xn----1j8r.xn--mpb269krv4i; 𞥁-.\u0762≮뻐; [B2, B3, V3]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞥩-򊫠.\u08B4≠; 𞥩-򊫠.\u08B4≠; [B2, B3, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+𞥩-򊫠.\u08B4=\u0338; 𞥩-򊫠.\u08B4≠; [B2, B3, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+𞥩-򊫠.\u08B4≠; ; [B2, B3, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+𞥩-򊫠.\u08B4=\u0338; 𞥩-򊫠.\u08B4≠; [B2, B3, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+xn----cm8rp3609a.xn--9yb852k; 𞥩-򊫠.\u08B4≠; [B2, B3, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+-񅂏ςႼ.\u0661; -񅂏ςႼ.\u0661; [B1, V3, V6]; xn----ymb080hun11i.xn--9hb; ; xn----0mb770hun11i.xn--9hb; # -ςႼ.١
+-񅂏ςႼ.\u0661; ; [B1, V3, V6]; xn----ymb080hun11i.xn--9hb; ; xn----0mb770hun11i.xn--9hb; # -ςႼ.١
+-񅂏ςⴜ.\u0661; ; [B1, V3, V6]; xn----ymb2782aov12f.xn--9hb; ; xn----0mb9682aov12f.xn--9hb; # -ςⴜ.١
+-񅂏ΣႼ.\u0661; -񅂏σႼ.\u0661; [B1, V3, V6]; xn----0mb770hun11i.xn--9hb; ; ; # -σႼ.١
+-񅂏σⴜ.\u0661; ; [B1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+-񅂏Σⴜ.\u0661; -񅂏σⴜ.\u0661; [B1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+xn----0mb9682aov12f.xn--9hb; -񅂏σⴜ.\u0661; [B1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+xn----0mb770hun11i.xn--9hb; -񅂏σႼ.\u0661; [B1, V3, V6]; xn----0mb770hun11i.xn--9hb; ; ; # -σႼ.١
+xn----ymb2782aov12f.xn--9hb; -񅂏ςⴜ.\u0661; [B1, V3, V6]; xn----ymb2782aov12f.xn--9hb; ; ; # -ςⴜ.١
+xn----ymb080hun11i.xn--9hb; -񅂏ςႼ.\u0661; [B1, V3, V6]; xn----ymb080hun11i.xn--9hb; ; ; # -ςႼ.١
+-񅂏ςⴜ.\u0661; -񅂏ςⴜ.\u0661; [B1, V3, V6]; xn----ymb2782aov12f.xn--9hb; ; xn----0mb9682aov12f.xn--9hb; # -ςⴜ.١
+-񅂏ΣႼ.\u0661; -񅂏σႼ.\u0661; [B1, V3, V6]; xn----0mb770hun11i.xn--9hb; ; ; # -σႼ.١
+-񅂏σⴜ.\u0661; -񅂏σⴜ.\u0661; [B1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+-񅂏Σⴜ.\u0661; -񅂏σⴜ.\u0661; [B1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+\u17CA.\u200D𝟮𑀿; \u17CA.\u200D2𑀿; [C2, V5]; xn--m4e.xn--2-tgnv469h; ; xn--m4e.xn--2-ku7i; [V5] # ៊.2𑀿
+\u17CA.\u200D2𑀿; ; [C2, V5]; xn--m4e.xn--2-tgnv469h; ; xn--m4e.xn--2-ku7i; [V5] # ៊.2𑀿
+xn--m4e.xn--2-ku7i; \u17CA.2𑀿; [V5]; xn--m4e.xn--2-ku7i; ; ; # ៊.2𑀿
+xn--m4e.xn--2-tgnv469h; \u17CA.\u200D2𑀿; [C2, V5]; xn--m4e.xn--2-tgnv469h; ; ; # ៊.2𑀿
+≯𝟖。\u1A60𐫓򟇑; ≯8.\u1A60𐫓򟇑; [B1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+>\u0338𝟖。\u1A60𐫓򟇑; ≯8.\u1A60𐫓򟇑; [B1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+≯8。\u1A60𐫓򟇑; ≯8.\u1A60𐫓򟇑; [B1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+>\u03388。\u1A60𐫓򟇑; ≯8.\u1A60𐫓򟇑; [B1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+xn--8-ogo.xn--jof5303iv1z5d; ≯8.\u1A60𐫓򟇑; [B1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+𑲫Ↄ\u0664。\u200C; 𑲫Ↄ\u0664.\u200C; [B1, C1, V5, V6]; xn--dib999kcy1p.xn--0ug; ; xn--dib999kcy1p.; [B1, V5, V6] # 𑲫Ↄ٤.
+𑲫Ↄ\u0664。\u200C; 𑲫Ↄ\u0664.\u200C; [B1, C1, V5, V6]; xn--dib999kcy1p.xn--0ug; ; xn--dib999kcy1p.; [B1, V5, V6] # 𑲫Ↄ٤.
+𑲫ↄ\u0664。\u200C; 𑲫ↄ\u0664.\u200C; [B1, C1, V5]; xn--dib100l8x1p.xn--0ug; ; xn--dib100l8x1p.; [B1, V5] # 𑲫ↄ٤.
+xn--dib100l8x1p.; 𑲫ↄ\u0664.; [B1, V5]; xn--dib100l8x1p.; ; ; # 𑲫ↄ٤.
+xn--dib100l8x1p.xn--0ug; 𑲫ↄ\u0664.\u200C; [B1, C1, V5]; xn--dib100l8x1p.xn--0ug; ; ; # 𑲫ↄ٤.
+xn--dib999kcy1p.; 𑲫Ↄ\u0664.; [B1, V5, V6]; xn--dib999kcy1p.; ; ; # 𑲫Ↄ٤.
+xn--dib999kcy1p.xn--0ug; 𑲫Ↄ\u0664.\u200C; [B1, C1, V5, V6]; xn--dib999kcy1p.xn--0ug; ; ; # 𑲫Ↄ٤.
+𑲫ↄ\u0664。\u200C; 𑲫ↄ\u0664.\u200C; [B1, C1, V5]; xn--dib100l8x1p.xn--0ug; ; xn--dib100l8x1p.; [B1, V5] # 𑲫ↄ٤.
+\u0C00𝟵\u200D\uFC9D.\u200D\u0750⒈; \u0C009\u200D\u0628\u062D.\u200D\u0750⒈; [B1, C2, V5, V6]; xn--9-1mcp570dl51a.xn--3ob977jmfd; ; xn--9-1mcp570d.xn--3ob470m; [B1, V5, V6] # ఀ9بح.ݐ⒈
+\u0C009\u200D\u0628\u062D.\u200D\u07501.; ; [B1, C2, V5]; xn--9-1mcp570dl51a.xn--1-x3c211q.; ; xn--9-1mcp570d.xn--1-x3c.; [B1, V5] # ఀ9بح.ݐ1.
+xn--9-1mcp570d.xn--1-x3c.; \u0C009\u0628\u062D.\u07501.; [B1, V5]; xn--9-1mcp570d.xn--1-x3c.; ; ; # ఀ9بح.ݐ1.
+xn--9-1mcp570dl51a.xn--1-x3c211q.; \u0C009\u200D\u0628\u062D.\u200D\u07501.; [B1, C2, V5]; xn--9-1mcp570dl51a.xn--1-x3c211q.; ; ; # ఀ9بح.ݐ1.
+xn--9-1mcp570d.xn--3ob470m; \u0C009\u0628\u062D.\u0750⒈; [B1, V5, V6]; xn--9-1mcp570d.xn--3ob470m; ; ; # ఀ9بح.ݐ⒈
+xn--9-1mcp570dl51a.xn--3ob977jmfd; \u0C009\u200D\u0628\u062D.\u200D\u0750⒈; [B1, C2, V5, V6]; xn--9-1mcp570dl51a.xn--3ob977jmfd; ; ; # ఀ9بح.ݐ⒈
+\uAAF6。嬶ß葽; \uAAF6.嬶ß葽; [V5]; xn--2v9a.xn--zca7637b14za; ; xn--2v9a.xn--ss-q40dp97m; # ꫶.嬶ß葽
+\uAAF6。嬶SS葽; \uAAF6.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+\uAAF6。嬶ss葽; \uAAF6.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+\uAAF6。嬶Ss葽; \uAAF6.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+xn--2v9a.xn--ss-q40dp97m; \uAAF6.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+xn--2v9a.xn--zca7637b14za; \uAAF6.嬶ß葽; [V5]; xn--2v9a.xn--zca7637b14za; ; ; # ꫶.嬶ß葽
+𑚶⒈。񞻡𐹺; 𑚶⒈.񞻡𐹺; [B5, B6, V5, V6]; xn--tshz969f.xn--yo0d5914s; ; ; # 𑚶⒈.𐹺
+𑚶1.。񞻡𐹺; 𑚶1..񞻡𐹺; [B5, B6, V5, V6, X4_2]; xn--1-3j0j..xn--yo0d5914s; [B5, B6, V5, V6, A4_2]; ; # 𑚶1..𐹺
+xn--1-3j0j..xn--yo0d5914s; 𑚶1..񞻡𐹺; [B5, B6, V5, V6, X4_2]; xn--1-3j0j..xn--yo0d5914s; [B5, B6, V5, V6, A4_2]; ; # 𑚶1..𐹺
+xn--tshz969f.xn--yo0d5914s; 𑚶⒈.񞻡𐹺; [B5, B6, V5, V6]; xn--tshz969f.xn--yo0d5914s; ; ; # 𑚶⒈.𐹺
+𑜤︒≮.񚕽\u05D8𞾩; 𑜤︒≮.񚕽\u05D8𞾩; [B1, B5, B6, V5, V6]; xn--gdh5267fdzpa.xn--deb0091w5q9u; ; ; # 𑜤︒≮.ט
+𑜤︒<\u0338.񚕽\u05D8𞾩; 𑜤︒≮.񚕽\u05D8𞾩; [B1, B5, B6, V5, V6]; xn--gdh5267fdzpa.xn--deb0091w5q9u; ; ; # 𑜤︒≮.ט
+𑜤。≮.񚕽\u05D8𞾩; 𑜤.≮.񚕽\u05D8𞾩; [B1, B5, B6, V5, V6]; xn--ci2d.xn--gdh.xn--deb0091w5q9u; ; ; # 𑜤.≮.ט
+𑜤。<\u0338.񚕽\u05D8𞾩; 𑜤.≮.񚕽\u05D8𞾩; [B1, B5, B6, V5, V6]; xn--ci2d.xn--gdh.xn--deb0091w5q9u; ; ; # 𑜤.≮.ט
+xn--ci2d.xn--gdh.xn--deb0091w5q9u; 𑜤.≮.񚕽\u05D8𞾩; [B1, B5, B6, V5, V6]; xn--ci2d.xn--gdh.xn--deb0091w5q9u; ; ; # 𑜤.≮.ט
+xn--gdh5267fdzpa.xn--deb0091w5q9u; 𑜤︒≮.񚕽\u05D8𞾩; [B1, B5, B6, V5, V6]; xn--gdh5267fdzpa.xn--deb0091w5q9u; ; ; # 𑜤︒≮.ט
+󠆋\u0603񏦤.⇁ς򏋈򺇥; \u0603񏦤.⇁ς򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--3xa174mxv16m8moq; ; xn--lfb04106d.xn--4xa964mxv16m8moq; # .⇁ς
+󠆋\u0603񏦤.⇁Σ򏋈򺇥; \u0603񏦤.⇁σ򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--4xa964mxv16m8moq; ; ; # .⇁σ
+󠆋\u0603񏦤.⇁σ򏋈򺇥; \u0603񏦤.⇁σ򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--4xa964mxv16m8moq; ; ; # .⇁σ
+xn--lfb04106d.xn--4xa964mxv16m8moq; \u0603񏦤.⇁σ򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--4xa964mxv16m8moq; ; ; # .⇁σ
+xn--lfb04106d.xn--3xa174mxv16m8moq; \u0603񏦤.⇁ς򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--3xa174mxv16m8moq; ; ; # .⇁ς
+ς𑐽𵢈𑜫。𞬩\u200C𐫄; ς𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [V6] # ς𑐽𑜫.𐫄
+ς𑐽𵢈𑜫。𞬩\u200C𐫄; ς𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [V6] # ς𑐽𑜫.𐫄
+Σ𑐽𵢈𑜫。𞬩\u200C𐫄; σ𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [V6] # σ𑐽𑜫.𐫄
+σ𑐽𵢈𑜫。𞬩\u200C𐫄; σ𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [V6] # σ𑐽𑜫.𐫄
+xn--4xa2260lk3b8z15g.xn--tw9ct349a; σ𑐽𵢈𑜫.𞬩𐫄; [V6]; xn--4xa2260lk3b8z15g.xn--tw9ct349a; ; ; # σ𑐽𑜫.𐫄
+xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; σ𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; ; # σ𑐽𑜫.𐫄
+xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ς𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ; ; # ς𑐽𑜫.𐫄
+Σ𑐽𵢈𑜫。𞬩\u200C𐫄; σ𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [V6] # σ𑐽𑜫.𐫄
+σ𑐽𵢈𑜫。𞬩\u200C𐫄; σ𑐽𵢈𑜫.𞬩\u200C𐫄; [C1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [V6] # σ𑐽𑜫.𐫄
+-򵏽。-\uFC4C\u075B; -򵏽.-\u0646\u062D\u075B; [B1, V3, V6]; xn----o452j.xn----cnc8e38c; ; ; # -.-نحݛ
+-򵏽。-\u0646\u062D\u075B; -򵏽.-\u0646\u062D\u075B; [B1, V3, V6]; xn----o452j.xn----cnc8e38c; ; ; # -.-نحݛ
+xn----o452j.xn----cnc8e38c; -򵏽.-\u0646\u062D\u075B; [B1, V3, V6]; xn----o452j.xn----cnc8e38c; ; ; # -.-نحݛ
+⺢򇺅𝟤。\u200D🚷; ⺢򇺅2.\u200D🚷; [C2, V6]; xn--2-4jtr4282f.xn--1ugz946p; ; xn--2-4jtr4282f.xn--m78h; [V6] # ⺢2.🚷
+⺢򇺅2。\u200D🚷; ⺢򇺅2.\u200D🚷; [C2, V6]; xn--2-4jtr4282f.xn--1ugz946p; ; xn--2-4jtr4282f.xn--m78h; [V6] # ⺢2.🚷
+xn--2-4jtr4282f.xn--m78h; ⺢򇺅2.🚷; [V6]; xn--2-4jtr4282f.xn--m78h; ; ; # ⺢2.🚷
+xn--2-4jtr4282f.xn--1ugz946p; ⺢򇺅2.\u200D🚷; [C2, V6]; xn--2-4jtr4282f.xn--1ugz946p; ; ; # ⺢2.🚷
+\u0CF8\u200D\u2DFE𐹲。򤐶; \u0CF8\u200D\u2DFE𐹲.򤐶; [B5, B6, C2, V6]; xn--hvc488g69j402t.xn--3e36c; ; xn--hvc220of37m.xn--3e36c; [B5, B6, V6] # ⷾ𐹲.
+\u0CF8\u200D\u2DFE𐹲。򤐶; \u0CF8\u200D\u2DFE𐹲.򤐶; [B5, B6, C2, V6]; xn--hvc488g69j402t.xn--3e36c; ; xn--hvc220of37m.xn--3e36c; [B5, B6, V6] # ⷾ𐹲.
+xn--hvc220of37m.xn--3e36c; \u0CF8\u2DFE𐹲.򤐶; [B5, B6, V6]; xn--hvc220of37m.xn--3e36c; ; ; # ⷾ𐹲.
+xn--hvc488g69j402t.xn--3e36c; \u0CF8\u200D\u2DFE𐹲.򤐶; [B5, B6, C2, V6]; xn--hvc488g69j402t.xn--3e36c; ; ; # ⷾ𐹲.
+𐹢.Ⴍ₉⁸; 𐹢.Ⴍ98; [B1, V6]; xn--9n0d.xn--98-7ek; ; ; # 𐹢.Ⴍ98
+𐹢.Ⴍ98; ; [B1, V6]; xn--9n0d.xn--98-7ek; ; ; # 𐹢.Ⴍ98
+𐹢.ⴍ98; ; [B1]; xn--9n0d.xn--98-u61a; ; ; # 𐹢.ⴍ98
+xn--9n0d.xn--98-u61a; 𐹢.ⴍ98; [B1]; xn--9n0d.xn--98-u61a; ; ; # 𐹢.ⴍ98
+xn--9n0d.xn--98-7ek; 𐹢.Ⴍ98; [B1, V6]; xn--9n0d.xn--98-7ek; ; ; # 𐹢.Ⴍ98
+𐹢.ⴍ₉⁸; 𐹢.ⴍ98; [B1]; xn--9n0d.xn--98-u61a; ; ; # 𐹢.ⴍ98
+\u200C\u034F。ß\u08E2⒚≯; \u200C.ß\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--zca612bx9vo5b; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ß⒚≯
+\u200C\u034F。ß\u08E2⒚>\u0338; \u200C.ß\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--zca612bx9vo5b; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ß⒚≯
+\u200C\u034F。ß\u08E219.≯; \u200C.ß\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--19-fia813f.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ß19.≯
+\u200C\u034F。ß\u08E219.>\u0338; \u200C.ß\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--19-fia813f.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ß19.≯
+\u200C\u034F。SS\u08E219.>\u0338; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ss19.≯
+\u200C\u034F。SS\u08E219.≯; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ss19.≯
+\u200C\u034F。ss\u08E219.≯; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ss19.≯
+\u200C\u034F。ss\u08E219.>\u0338; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ss19.≯
+\u200C\u034F。Ss\u08E219.>\u0338; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ss19.≯
+\u200C\u034F。Ss\u08E219.≯; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2] # .ss19.≯
+.xn--ss19-w0i.xn--hdh; .ss\u08E219.≯; [B1, B5, V6, X4_2]; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2]; ; # .ss19.≯
+xn--0ug.xn--ss19-w0i.xn--hdh; \u200C.ss\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; ; # .ss19.≯
+xn--0ug.xn--19-fia813f.xn--hdh; \u200C.ß\u08E219.≯; [B1, B5, C1, V6]; xn--0ug.xn--19-fia813f.xn--hdh; ; ; # .ß19.≯
+\u200C\u034F。SS\u08E2⒚>\u0338; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ss⒚≯
+\u200C\u034F。SS\u08E2⒚≯; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ss⒚≯
+\u200C\u034F。ss\u08E2⒚≯; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ss⒚≯
+\u200C\u034F。ss\u08E2⒚>\u0338; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ss⒚≯
+\u200C\u034F。Ss\u08E2⒚>\u0338; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ss⒚≯
+\u200C\u034F。Ss\u08E2⒚≯; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2] # .ss⒚≯
+.xn--ss-9if872xjjc; .ss\u08E2⒚≯; [B5, B6, V6, X4_2]; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2]; ; # .ss⒚≯
+xn--0ug.xn--ss-9if872xjjc; \u200C.ss\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; ; # .ss⒚≯
+xn--0ug.xn--zca612bx9vo5b; \u200C.ß\u08E2⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--zca612bx9vo5b; ; ; # .ß⒚≯
+\u200C𞥍ᡌ.𣃔; \u200C𞥍ᡌ.𣃔; [B1, C1, V6]; xn--c8e180bqz13b.xn--od1j; ; xn--c8e5919u.xn--od1j; [B2, B3, V6] # ᡌ.𣃔
+\u200C𞥍ᡌ.𣃔; ; [B1, C1, V6]; xn--c8e180bqz13b.xn--od1j; ; xn--c8e5919u.xn--od1j; [B2, B3, V6] # ᡌ.𣃔
+xn--c8e5919u.xn--od1j; 𞥍ᡌ.𣃔; [B2, B3, V6]; xn--c8e5919u.xn--od1j; ; ; # ᡌ.𣃔
+xn--c8e180bqz13b.xn--od1j; \u200C𞥍ᡌ.𣃔; [B1, C1, V6]; xn--c8e180bqz13b.xn--od1j; ; ; # ᡌ.𣃔
+\u07D0򜬝-񡢬。\u0FA0Ⴛ𞷏𝆬; \u07D0򜬝-񡢬.\u0FA0Ⴛ𞷏𝆬; [B1, B2, B3, V5, V6]; xn----8bd11730jefvw.xn--wfd08cd265hgsxa; ; ; # ߐ-.ྠႻ𝆬
+\u07D0򜬝-񡢬。\u0FA0ⴛ𞷏𝆬; \u07D0򜬝-񡢬.\u0FA0ⴛ𞷏𝆬; [B1, B2, B3, V5, V6]; xn----8bd11730jefvw.xn--wfd802mpm20agsxa; ; ; # ߐ-.ྠⴛ𝆬
+xn----8bd11730jefvw.xn--wfd802mpm20agsxa; \u07D0򜬝-񡢬.\u0FA0ⴛ𞷏𝆬; [B1, B2, B3, V5, V6]; xn----8bd11730jefvw.xn--wfd802mpm20agsxa; ; ; # ߐ-.ྠⴛ𝆬
+xn----8bd11730jefvw.xn--wfd08cd265hgsxa; \u07D0򜬝-񡢬.\u0FA0Ⴛ𞷏𝆬; [B1, B2, B3, V5, V6]; xn----8bd11730jefvw.xn--wfd08cd265hgsxa; ; ; # ߐ-.ྠႻ𝆬
+𝨥。⫟𑈾; 𝨥.⫟𑈾; [V5]; xn--n82h.xn--63iw010f; ; ; # 𝨥.⫟𑈾
+xn--n82h.xn--63iw010f; 𝨥.⫟𑈾; [V5]; xn--n82h.xn--63iw010f; ; ; # 𝨥.⫟𑈾
+⾛\u0753.Ⴕ𞠬\u0604\u200D; 走\u0753.Ⴕ𞠬\u0604\u200D; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb785czmm0y85b; ; xn--6ob9779d.xn--mfb785ck569a; [B5, B6, V6] # 走ݓ.Ⴕ𞠬
+走\u0753.Ⴕ𞠬\u0604\u200D; ; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb785czmm0y85b; ; xn--6ob9779d.xn--mfb785ck569a; [B5, B6, V6] # 走ݓ.Ⴕ𞠬
+走\u0753.ⴕ𞠬\u0604\u200D; ; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb444k5gjt754b; ; xn--6ob9779d.xn--mfb511rxu80a; [B5, B6, V6] # 走ݓ.ⴕ𞠬
+xn--6ob9779d.xn--mfb511rxu80a; 走\u0753.ⴕ𞠬\u0604; [B5, B6, V6]; xn--6ob9779d.xn--mfb511rxu80a; ; ; # 走ݓ.ⴕ𞠬
+xn--6ob9779d.xn--mfb444k5gjt754b; 走\u0753.ⴕ𞠬\u0604\u200D; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb444k5gjt754b; ; ; # 走ݓ.ⴕ𞠬
+xn--6ob9779d.xn--mfb785ck569a; 走\u0753.Ⴕ𞠬\u0604; [B5, B6, V6]; xn--6ob9779d.xn--mfb785ck569a; ; ; # 走ݓ.Ⴕ𞠬
+xn--6ob9779d.xn--mfb785czmm0y85b; 走\u0753.Ⴕ𞠬\u0604\u200D; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb785czmm0y85b; ; ; # 走ݓ.Ⴕ𞠬
+⾛\u0753.ⴕ𞠬\u0604\u200D; 走\u0753.ⴕ𞠬\u0604\u200D; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb444k5gjt754b; ; xn--6ob9779d.xn--mfb511rxu80a; [B5, B6, V6] # 走ݓ.ⴕ𞠬
+-ᢗ\u200C🄄.𑜢; ; [C1, V3, V5, V6]; xn----pck312bx563c.xn--9h2d; ; xn----pck1820x.xn--9h2d; [V3, V5, V6] # -ᢗ🄄.𑜢
+-ᢗ\u200C3,.𑜢; ; [C1, V3, V5, V6]; xn---3,-3eu051c.xn--9h2d; ; xn---3,-3eu.xn--9h2d; [V3, V5, V6] # -ᢗ3,.𑜢
+xn---3,-3eu.xn--9h2d; -ᢗ3,.𑜢; [V3, V5, V6]; xn---3,-3eu.xn--9h2d; ; ; # -ᢗ3,.𑜢
+xn---3,-3eu051c.xn--9h2d; -ᢗ\u200C3,.𑜢; [C1, V3, V5, V6]; xn---3,-3eu051c.xn--9h2d; ; ; # -ᢗ3,.𑜢
+xn----pck1820x.xn--9h2d; -ᢗ🄄.𑜢; [V3, V5, V6]; xn----pck1820x.xn--9h2d; ; ; # -ᢗ🄄.𑜢
+xn----pck312bx563c.xn--9h2d; -ᢗ\u200C🄄.𑜢; [C1, V3, V5, V6]; xn----pck312bx563c.xn--9h2d; ; ; # -ᢗ🄄.𑜢
+≠𐸁𹏁\u200C.Ⴚ򳄠; ; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ynd49496l; ; xn--1ch2293gv3nr.xn--ynd49496l; [B1, V6] # ≠.Ⴚ
+=\u0338𐸁𹏁\u200C.Ⴚ򳄠; ≠𐸁𹏁\u200C.Ⴚ򳄠; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ynd49496l; ; xn--1ch2293gv3nr.xn--ynd49496l; [B1, V6] # ≠.Ⴚ
+=\u0338𐸁𹏁\u200C.ⴚ򳄠; ≠𐸁𹏁\u200C.ⴚ򳄠; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ilj23531g; ; xn--1ch2293gv3nr.xn--ilj23531g; [B1, V6] # ≠.ⴚ
+≠𐸁𹏁\u200C.ⴚ򳄠; ; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ilj23531g; ; xn--1ch2293gv3nr.xn--ilj23531g; [B1, V6] # ≠.ⴚ
+xn--1ch2293gv3nr.xn--ilj23531g; ≠𐸁𹏁.ⴚ򳄠; [B1, V6]; xn--1ch2293gv3nr.xn--ilj23531g; ; ; # ≠.ⴚ
+xn--0ug83gn618a21ov.xn--ilj23531g; ≠𐸁𹏁\u200C.ⴚ򳄠; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ilj23531g; ; ; # ≠.ⴚ
+xn--1ch2293gv3nr.xn--ynd49496l; ≠𐸁𹏁.Ⴚ򳄠; [B1, V6]; xn--1ch2293gv3nr.xn--ynd49496l; ; ; # ≠.Ⴚ
+xn--0ug83gn618a21ov.xn--ynd49496l; ≠𐸁𹏁\u200C.Ⴚ򳄠; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ynd49496l; ; ; # ≠.Ⴚ
+\u0669。󠇀𑇊; \u0669.𑇊; [B1, V5]; xn--iib.xn--6d1d; ; ; # ٩.𑇊
+\u0669。󠇀𑇊; \u0669.𑇊; [B1, V5]; xn--iib.xn--6d1d; ; ; # ٩.𑇊
+xn--iib.xn--6d1d; \u0669.𑇊; [B1, V5]; xn--iib.xn--6d1d; ; ; # ٩.𑇊
+\u1086𞶀≯⒍。-; \u1086𞶀≯⒍.-; [B1, V3, V5, V6]; xn--hmd482gqqb8730g.-; ; ; # ႆ≯⒍.-
+\u1086𞶀>\u0338⒍。-; \u1086𞶀≯⒍.-; [B1, V3, V5, V6]; xn--hmd482gqqb8730g.-; ; ; # ႆ≯⒍.-
+\u1086𞶀≯6.。-; \u1086𞶀≯6..-; [B1, V3, V5, V6, X4_2]; xn--6-oyg968k7h74b..-; [B1, V3, V5, V6, A4_2]; ; # ႆ≯6..-
+\u1086𞶀>\u03386.。-; \u1086𞶀≯6..-; [B1, V3, V5, V6, X4_2]; xn--6-oyg968k7h74b..-; [B1, V3, V5, V6, A4_2]; ; # ႆ≯6..-
+xn--6-oyg968k7h74b..-; \u1086𞶀≯6..-; [B1, V3, V5, V6, X4_2]; xn--6-oyg968k7h74b..-; [B1, V3, V5, V6, A4_2]; ; # ႆ≯6..-
+xn--hmd482gqqb8730g.-; \u1086𞶀≯⒍.-; [B1, V3, V5, V6]; xn--hmd482gqqb8730g.-; ; ; # ႆ≯⒍.-
+\u17B4.쮇-; ; [V3, V5, V6]; xn--z3e.xn----938f; ; ; # .쮇-
+\u17B4.쮇-; \u17B4.쮇-; [V3, V5, V6]; xn--z3e.xn----938f; ; ; # .쮇-
+xn--z3e.xn----938f; \u17B4.쮇-; [V3, V5, V6]; xn--z3e.xn----938f; ; ; # .쮇-
+\u200C𑓂。⒈-􀪛; \u200C𑓂.⒈-􀪛; [C1, V6]; xn--0ugy057g.xn----dcp29674o; ; xn--wz1d.xn----dcp29674o; [V5, V6] # 𑓂.⒈-
+\u200C𑓂。1.-􀪛; \u200C𑓂.1.-􀪛; [C1, V3, V6]; xn--0ugy057g.1.xn----rg03o; ; xn--wz1d.1.xn----rg03o; [V3, V5, V6] # 𑓂.1.-
+xn--wz1d.1.xn----rg03o; 𑓂.1.-􀪛; [V3, V5, V6]; xn--wz1d.1.xn----rg03o; ; ; # 𑓂.1.-
+xn--0ugy057g.1.xn----rg03o; \u200C𑓂.1.-􀪛; [C1, V3, V6]; xn--0ugy057g.1.xn----rg03o; ; ; # 𑓂.1.-
+xn--wz1d.xn----dcp29674o; 𑓂.⒈-􀪛; [V5, V6]; xn--wz1d.xn----dcp29674o; ; ; # 𑓂.⒈-
+xn--0ugy057g.xn----dcp29674o; \u200C𑓂.⒈-􀪛; [C1, V6]; xn--0ugy057g.xn----dcp29674o; ; ; # 𑓂.⒈-
+⒈\uFEAE\u200C。\u20E9🖞\u200C𖬴; ⒈\u0631\u200C.\u20E9🖞\u200C𖬴; [B1, C1, V5, V6]; xn--wgb253kmfd.xn--0ugz6a8040fty5d; ; xn--wgb746m.xn--c1g6021kg18c; [B1, V5, V6] # ⒈ر.⃩🖞𖬴
+1.\u0631\u200C。\u20E9🖞\u200C𖬴; 1.\u0631\u200C.\u20E9🖞\u200C𖬴; [B1, B3, C1, V5]; 1.xn--wgb253k.xn--0ugz6a8040fty5d; ; 1.xn--wgb.xn--c1g6021kg18c; [B1, V5] # 1.ر.⃩🖞𖬴
+1.xn--wgb.xn--c1g6021kg18c; 1.\u0631.\u20E9🖞𖬴; [B1, V5]; 1.xn--wgb.xn--c1g6021kg18c; ; ; # 1.ر.⃩🖞𖬴
+1.xn--wgb253k.xn--0ugz6a8040fty5d; 1.\u0631\u200C.\u20E9🖞\u200C𖬴; [B1, B3, C1, V5]; 1.xn--wgb253k.xn--0ugz6a8040fty5d; ; ; # 1.ر.⃩🖞𖬴
+xn--wgb746m.xn--c1g6021kg18c; ⒈\u0631.\u20E9🖞𖬴; [B1, V5, V6]; xn--wgb746m.xn--c1g6021kg18c; ; ; # ⒈ر.⃩🖞𖬴
+xn--wgb253kmfd.xn--0ugz6a8040fty5d; ⒈\u0631\u200C.\u20E9🖞\u200C𖬴; [B1, C1, V5, V6]; xn--wgb253kmfd.xn--0ugz6a8040fty5d; ; ; # ⒈ر.⃩🖞𖬴
+󌭇。𝟐\u1BA8\u07D4; 󌭇.2\u1BA8\u07D4; [B1, V6]; xn--xm89d.xn--2-icd143m; ; ; # .2ᮨߔ
+󌭇。2\u1BA8\u07D4; 󌭇.2\u1BA8\u07D4; [B1, V6]; xn--xm89d.xn--2-icd143m; ; ; # .2ᮨߔ
+xn--xm89d.xn--2-icd143m; 󌭇.2\u1BA8\u07D4; [B1, V6]; xn--xm89d.xn--2-icd143m; ; ; # .2ᮨߔ
+\uFD8F򫳺.ς\u200D𐹷; \u0645\u062E\u0645򫳺.ς\u200D𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--3xa006lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, V6] # مخم.ς𐹷
+\u0645\u062E\u0645򫳺.ς\u200D𐹷; ; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--3xa006lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, V6] # مخم.ς𐹷
+\u0645\u062E\u0645򫳺.Σ\u200D𐹷; \u0645\u062E\u0645򫳺.σ\u200D𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, V6] # مخم.σ𐹷
+\u0645\u062E\u0645򫳺.σ\u200D𐹷; ; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, V6] # مخم.σ𐹷
+xn--tgb9bb64691z.xn--4xa6667k; \u0645\u062E\u0645򫳺.σ𐹷; [B2, B3, B5, B6, V6]; xn--tgb9bb64691z.xn--4xa6667k; ; ; # مخم.σ𐹷
+xn--tgb9bb64691z.xn--4xa895lrp7n; \u0645\u062E\u0645򫳺.σ\u200D𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; ; # مخم.σ𐹷
+xn--tgb9bb64691z.xn--3xa006lrp7n; \u0645\u062E\u0645򫳺.ς\u200D𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--3xa006lrp7n; ; ; # مخم.ς𐹷
+\uFD8F򫳺.Σ\u200D𐹷; \u0645\u062E\u0645򫳺.σ\u200D𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, V6] # مخم.σ𐹷
+\uFD8F򫳺.σ\u200D𐹷; \u0645\u062E\u0645򫳺.σ\u200D𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, V6] # مخم.σ𐹷
+⒎\u06C1\u0605。\uAAF6۵𐇽; ⒎\u06C1\u0605.\uAAF6۵𐇽; [B1, V5, V6]; xn--nfb98ai25e.xn--imb3805fxt8b; ; ; # ⒎ہ.꫶۵𐇽
+7.\u06C1\u0605。\uAAF6۵𐇽; 7.\u06C1\u0605.\uAAF6۵𐇽; [B1, V5, V6]; 7.xn--nfb98a.xn--imb3805fxt8b; ; ; # 7.ہ.꫶۵𐇽
+7.xn--nfb98a.xn--imb3805fxt8b; 7.\u06C1\u0605.\uAAF6۵𐇽; [B1, V5, V6]; 7.xn--nfb98a.xn--imb3805fxt8b; ; ; # 7.ہ.꫶۵𐇽
+xn--nfb98ai25e.xn--imb3805fxt8b; ⒎\u06C1\u0605.\uAAF6۵𐇽; [B1, V5, V6]; xn--nfb98ai25e.xn--imb3805fxt8b; ; ; # ⒎ہ.꫶۵𐇽
+-ᡥ᠆󍲭。\u0605\u1A5D𐹡; -ᡥ᠆󍲭.\u0605\u1A5D𐹡; [B1, V3, V6]; xn----f3j6s87156i.xn--nfb035hoo2p; ; ; # -ᡥ᠆.ᩝ𐹡
+xn----f3j6s87156i.xn--nfb035hoo2p; -ᡥ᠆󍲭.\u0605\u1A5D𐹡; [B1, V3, V6]; xn----f3j6s87156i.xn--nfb035hoo2p; ; ; # -ᡥ᠆.ᩝ𐹡
+\u200D.\u06BD\u0663\u0596; ; [B1, C2]; xn--1ug.xn--hcb32bni; ; .xn--hcb32bni; [A4_2] # .ڽ٣֖
+.xn--hcb32bni; .\u06BD\u0663\u0596; [X4_2]; .xn--hcb32bni; [A4_2]; ; # .ڽ٣֖
+xn--1ug.xn--hcb32bni; \u200D.\u06BD\u0663\u0596; [B1, C2]; xn--1ug.xn--hcb32bni; ; ; # .ڽ٣֖
+xn--hcb32bni; \u06BD\u0663\u0596; ; xn--hcb32bni; ; ; # ڽ٣֖
+\u06BD\u0663\u0596; ; ; xn--hcb32bni; ; ; # ڽ٣֖
+㒧۱.Ⴚ\u0678\u200D; 㒧۱.Ⴚ\u064A\u0674\u200D; [B5, B6, C2, V6]; xn--emb715u.xn--mhb8f817ao2p; ; xn--emb715u.xn--mhb8f817a; [B5, B6, V6] # 㒧۱.Ⴚيٴ
+㒧۱.Ⴚ\u064A\u0674\u200D; ; [B5, B6, C2, V6]; xn--emb715u.xn--mhb8f817ao2p; ; xn--emb715u.xn--mhb8f817a; [B5, B6, V6] # 㒧۱.Ⴚيٴ
+㒧۱.ⴚ\u064A\u0674\u200D; ; [B5, B6, C2]; xn--emb715u.xn--mhb8f960g03l; ; xn--emb715u.xn--mhb8fy26k; [B5, B6] # 㒧۱.ⴚيٴ
+xn--emb715u.xn--mhb8fy26k; 㒧۱.ⴚ\u064A\u0674; [B5, B6]; xn--emb715u.xn--mhb8fy26k; ; ; # 㒧۱.ⴚيٴ
+xn--emb715u.xn--mhb8f960g03l; 㒧۱.ⴚ\u064A\u0674\u200D; [B5, B6, C2]; xn--emb715u.xn--mhb8f960g03l; ; ; # 㒧۱.ⴚيٴ
+xn--emb715u.xn--mhb8f817a; 㒧۱.Ⴚ\u064A\u0674; [B5, B6, V6]; xn--emb715u.xn--mhb8f817a; ; ; # 㒧۱.Ⴚيٴ
+xn--emb715u.xn--mhb8f817ao2p; 㒧۱.Ⴚ\u064A\u0674\u200D; [B5, B6, C2, V6]; xn--emb715u.xn--mhb8f817ao2p; ; ; # 㒧۱.Ⴚيٴ
+㒧۱.ⴚ\u0678\u200D; 㒧۱.ⴚ\u064A\u0674\u200D; [B5, B6, C2]; xn--emb715u.xn--mhb8f960g03l; ; xn--emb715u.xn--mhb8fy26k; [B5, B6] # 㒧۱.ⴚيٴ
+\u0F94ꡋ-.-𖬴; \u0F94ꡋ-.-𖬴; [V3, V5]; xn----ukg9938i.xn----4u5m; ; ; # ྔꡋ-.-𖬴
+\u0F94ꡋ-.-𖬴; ; [V3, V5]; xn----ukg9938i.xn----4u5m; ; ; # ྔꡋ-.-𖬴
+xn----ukg9938i.xn----4u5m; \u0F94ꡋ-.-𖬴; [V3, V5]; xn----ukg9938i.xn----4u5m; ; ; # ྔꡋ-.-𖬴
+񿒳-⋢\u200C.标-; 񿒳-⋢\u200C.标-; [C1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [V3, V6] # -⋢.标-
+񿒳-⊑\u0338\u200C.标-; 񿒳-⋢\u200C.标-; [C1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [V3, V6] # -⋢.标-
+񿒳-⋢\u200C.标-; ; [C1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [V3, V6] # -⋢.标-
+񿒳-⊑\u0338\u200C.标-; 񿒳-⋢\u200C.标-; [C1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [V3, V6] # -⋢.标-
+xn----9mo67451g.xn----qj7b; 񿒳-⋢.标-; [V3, V6]; xn----9mo67451g.xn----qj7b; ; ; # -⋢.标-
+xn----sgn90kn5663a.xn----qj7b; 񿒳-⋢\u200C.标-; [C1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; ; # -⋢.标-
+\u0671.ς\u07DC; \u0671.ς\u07DC; [B5, B6]; xn--qib.xn--3xa41s; ; xn--qib.xn--4xa21s; # ٱ.ςߜ
+\u0671.ς\u07DC; ; [B5, B6]; xn--qib.xn--3xa41s; ; xn--qib.xn--4xa21s; # ٱ.ςߜ
+\u0671.Σ\u07DC; \u0671.σ\u07DC; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+\u0671.σ\u07DC; ; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+xn--qib.xn--4xa21s; \u0671.σ\u07DC; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+xn--qib.xn--3xa41s; \u0671.ς\u07DC; [B5, B6]; xn--qib.xn--3xa41s; ; ; # ٱ.ςߜ
+\u0671.Σ\u07DC; \u0671.σ\u07DC; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+\u0671.σ\u07DC; \u0671.σ\u07DC; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+񼈶\u0605.\u08C1\u200D𑑂𱼱; 񼈶\u0605.\u08C1\u200D𑑂𱼱; [B2, B3, B5, B6, C2, V6]; xn--nfb17942h.xn--nzb240jv06otevq; ; xn--nfb17942h.xn--nzb6708kx3pn; [B2, B3, B5, B6, V6] # .ࣁ𑑂𱼱
+񼈶\u0605.\u08C1\u200D𑑂𱼱; ; [B2, B3, B5, B6, C2, V6]; xn--nfb17942h.xn--nzb240jv06otevq; ; xn--nfb17942h.xn--nzb6708kx3pn; [B2, B3, B5, B6, V6] # .ࣁ𑑂𱼱
+xn--nfb17942h.xn--nzb6708kx3pn; 񼈶\u0605.\u08C1𑑂𱼱; [B2, B3, B5, B6, V6]; xn--nfb17942h.xn--nzb6708kx3pn; ; ; # .ࣁ𑑂𱼱
+xn--nfb17942h.xn--nzb240jv06otevq; 񼈶\u0605.\u08C1\u200D𑑂𱼱; [B2, B3, B5, B6, C2, V6]; xn--nfb17942h.xn--nzb240jv06otevq; ; ; # .ࣁ𑑂𱼱
+𐹾𐋩𞵜。\u1BF2; 𐹾𐋩𞵜.\u1BF2; [B1, V5, V6]; xn--d97cn8rn44p.xn--0zf; ; ; # 𐹾𐋩.᯲
+𐹾𐋩𞵜。\u1BF2; 𐹾𐋩𞵜.\u1BF2; [B1, V5, V6]; xn--d97cn8rn44p.xn--0zf; ; ; # 𐹾𐋩.᯲
+xn--d97cn8rn44p.xn--0zf; 𐹾𐋩𞵜.\u1BF2; [B1, V5, V6]; xn--d97cn8rn44p.xn--0zf; ; ; # 𐹾𐋩.᯲
+6\u1160\u1C33󠸧.򟜊锰\u072Cς; ; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--3xa16ohw6pk078g; ; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; # 6ᰳ.锰ܬς
+6\u1160\u1C33󠸧.򟜊锰\u072CΣ; 6\u1160\u1C33󠸧.򟜊锰\u072Cσ; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; ; ; # 6ᰳ.锰ܬσ
+6\u1160\u1C33󠸧.򟜊锰\u072Cσ; ; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; ; ; # 6ᰳ.锰ܬσ
+xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; 6\u1160\u1C33󠸧.򟜊锰\u072Cσ; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; ; ; # 6ᰳ.锰ܬσ
+xn--6-5bh476ewr517a.xn--3xa16ohw6pk078g; 6\u1160\u1C33󠸧.򟜊锰\u072Cς; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--3xa16ohw6pk078g; ; ; # 6ᰳ.锰ܬς
+\u06B3\uFE04񅎦𝟽。𐹽; \u06B3񅎦7.𐹽; [B1, B2, V6]; xn--7-yuc34665f.xn--1o0d; ; ; # ڳ7.𐹽
+\u06B3\uFE04񅎦7。𐹽; \u06B3񅎦7.𐹽; [B1, B2, V6]; xn--7-yuc34665f.xn--1o0d; ; ; # ڳ7.𐹽
+xn--7-yuc34665f.xn--1o0d; \u06B3񅎦7.𐹽; [B1, B2, V6]; xn--7-yuc34665f.xn--1o0d; ; ; # ڳ7.𐹽
+𞮧.\u200C⫞; 𞮧.\u200C⫞; [B1, C1, V6]; xn--pw6h.xn--0ug283b; ; xn--pw6h.xn--53i; [B1, V6] # .⫞
+𞮧.\u200C⫞; ; [B1, C1, V6]; xn--pw6h.xn--0ug283b; ; xn--pw6h.xn--53i; [B1, V6] # .⫞
+xn--pw6h.xn--53i; 𞮧.⫞; [B1, V6]; xn--pw6h.xn--53i; ; ; # .⫞
+xn--pw6h.xn--0ug283b; 𞮧.\u200C⫞; [B1, C1, V6]; xn--pw6h.xn--0ug283b; ; ; # .⫞
+-񕉴.\u06E0ᢚ-; ; [V3, V5, V6]; xn----qi38c.xn----jxc827k; ; ; # -.۠ᢚ-
+xn----qi38c.xn----jxc827k; -񕉴.\u06E0ᢚ-; [V3, V5, V6]; xn----qi38c.xn----jxc827k; ; ; # -.۠ᢚ-
+⌁\u200D𑄴.\u200C𝟩\u066C; ⌁\u200D𑄴.\u200C7\u066C; [B1, C1, C2]; xn--1ug38i2093a.xn--7-xqc297q; ; xn--nhh5394g.xn--7-xqc; [B1] # ⌁𑄴.7٬
+⌁\u200D𑄴.\u200C7\u066C; ; [B1, C1, C2]; xn--1ug38i2093a.xn--7-xqc297q; ; xn--nhh5394g.xn--7-xqc; [B1] # ⌁𑄴.7٬
+xn--nhh5394g.xn--7-xqc; ⌁𑄴.7\u066C; [B1]; xn--nhh5394g.xn--7-xqc; ; ; # ⌁𑄴.7٬
+xn--1ug38i2093a.xn--7-xqc297q; ⌁\u200D𑄴.\u200C7\u066C; [B1, C1, C2]; xn--1ug38i2093a.xn--7-xqc297q; ; ; # ⌁𑄴.7٬
+︒\uFD05\u0E37\uFEFC。岓\u1BF2󠾃ᡂ; ︒\u0635\u0649\u0E37\u0644\u0627.岓\u1BF2󠾃ᡂ; [B1, V6]; xn--mgb1a7bt462hf267a.xn--17e10qe61f9r71s; ; ; # ︒صىืلا.岓᯲ᡂ
+。\u0635\u0649\u0E37\u0644\u0627。岓\u1BF2󠾃ᡂ; .\u0635\u0649\u0E37\u0644\u0627.岓\u1BF2󠾃ᡂ; [V6, X4_2]; .xn--mgb1a7bt462h.xn--17e10qe61f9r71s; [V6, A4_2]; ; # .صىืلا.岓᯲ᡂ
+.xn--mgb1a7bt462h.xn--17e10qe61f9r71s; .\u0635\u0649\u0E37\u0644\u0627.岓\u1BF2󠾃ᡂ; [V6, X4_2]; .xn--mgb1a7bt462h.xn--17e10qe61f9r71s; [V6, A4_2]; ; # .صىืلا.岓᯲ᡂ
+xn--mgb1a7bt462hf267a.xn--17e10qe61f9r71s; ︒\u0635\u0649\u0E37\u0644\u0627.岓\u1BF2󠾃ᡂ; [B1, V6]; xn--mgb1a7bt462hf267a.xn--17e10qe61f9r71s; ; ; # ︒صىืلا.岓᯲ᡂ
+𐹨。8𑁆; 𐹨.8𑁆; [B1]; xn--go0d.xn--8-yu7i; ; ; # 𐹨.8𑁆
+xn--go0d.xn--8-yu7i; 𐹨.8𑁆; [B1]; xn--go0d.xn--8-yu7i; ; ; # 𐹨.8𑁆
+𞀕\u0D43.ꡚ\u08FA𐹰\u0D44; 𞀕\u0D43.ꡚ\u08FA𐹰\u0D44; [B1, B5, B6, V5]; xn--mxc5210v.xn--90b01t8u2p1ltd; ; ; # 𞀕ൃ.ꡚࣺ𐹰ൄ
+𞀕\u0D43.ꡚ\u08FA𐹰\u0D44; ; [B1, B5, B6, V5]; xn--mxc5210v.xn--90b01t8u2p1ltd; ; ; # 𞀕ൃ.ꡚࣺ𐹰ൄ
+xn--mxc5210v.xn--90b01t8u2p1ltd; 𞀕\u0D43.ꡚ\u08FA𐹰\u0D44; [B1, B5, B6, V5]; xn--mxc5210v.xn--90b01t8u2p1ltd; ; ; # 𞀕ൃ.ꡚࣺ𐹰ൄ
+󆩏𐦹\u0303。󠍅; 󆩏𐦹\u0303.󠍅; [B1, B5, B6, V6]; xn--nsa1265kp9z9e.xn--xt36e; ; ; # ̃.
+󆩏𐦹\u0303。󠍅; 󆩏𐦹\u0303.󠍅; [B1, B5, B6, V6]; xn--nsa1265kp9z9e.xn--xt36e; ; ; # ̃.
+xn--nsa1265kp9z9e.xn--xt36e; 󆩏𐦹\u0303.󠍅; [B1, B5, B6, V6]; xn--nsa1265kp9z9e.xn--xt36e; ; ; # ̃.
+ᢌ.-\u085A; ᢌ.-\u085A; [V3]; xn--59e.xn----5jd; ; ; # ᢌ.-࡚
+ᢌ.-\u085A; ; [V3]; xn--59e.xn----5jd; ; ; # ᢌ.-࡚
+xn--59e.xn----5jd; ᢌ.-\u085A; [V3]; xn--59e.xn----5jd; ; ; # ᢌ.-࡚
+𥛛𑘶。𐹬𐲸\u0BCD; 𥛛𑘶.𐹬𐲸\u0BCD; [B1, V6]; xn--jb2dj685c.xn--xmc5562kmcb; ; ; # 𥛛𑘶.𐹬்
+𥛛𑘶。𐹬𐲸\u0BCD; 𥛛𑘶.𐹬𐲸\u0BCD; [B1, V6]; xn--jb2dj685c.xn--xmc5562kmcb; ; ; # 𥛛𑘶.𐹬்
+xn--jb2dj685c.xn--xmc5562kmcb; 𥛛𑘶.𐹬𐲸\u0BCD; [B1, V6]; xn--jb2dj685c.xn--xmc5562kmcb; ; ; # 𥛛𑘶.𐹬்
+Ⴐ\u077F.\u200C; Ⴐ\u077F.\u200C; [B1, B5, B6, C1, V6]; xn--gqb918b.xn--0ug; ; xn--gqb918b.; [B5, B6, V6] # Ⴐݿ.
+Ⴐ\u077F.\u200C; ; [B1, B5, B6, C1, V6]; xn--gqb918b.xn--0ug; ; xn--gqb918b.; [B5, B6, V6] # Ⴐݿ.
+ⴐ\u077F.\u200C; ; [B1, B5, B6, C1]; xn--gqb743q.xn--0ug; ; xn--gqb743q.; [B5, B6] # ⴐݿ.
+xn--gqb743q.; ⴐ\u077F.; [B5, B6]; xn--gqb743q.; ; ; # ⴐݿ.
+xn--gqb743q.xn--0ug; ⴐ\u077F.\u200C; [B1, B5, B6, C1]; xn--gqb743q.xn--0ug; ; ; # ⴐݿ.
+xn--gqb918b.; Ⴐ\u077F.; [B5, B6, V6]; xn--gqb918b.; ; ; # Ⴐݿ.
+xn--gqb918b.xn--0ug; Ⴐ\u077F.\u200C; [B1, B5, B6, C1, V6]; xn--gqb918b.xn--0ug; ; ; # Ⴐݿ.
+ⴐ\u077F.\u200C; ⴐ\u077F.\u200C; [B1, B5, B6, C1]; xn--gqb743q.xn--0ug; ; xn--gqb743q.; [B5, B6] # ⴐݿ.
+🄅𑲞-⒈。\u200Dᠩ\u06A5; 🄅𑲞-⒈.\u200Dᠩ\u06A5; [B1, C2, V6]; xn----ecp8796hjtvg.xn--7jb180gexf; ; xn----ecp8796hjtvg.xn--7jb180g; [B1, B5, B6, V6] # 🄅𑲞-⒈.ᠩڥ
+4,𑲞-1.。\u200Dᠩ\u06A5; 4,𑲞-1..\u200Dᠩ\u06A5; [B1, C2, V6, X4_2]; xn--4,-1-w401a..xn--7jb180gexf; [B1, C2, V6, A4_2]; xn--4,-1-w401a..xn--7jb180g; [B1, B5, B6, V6, A4_2] # 4,𑲞-1..ᠩڥ
+xn--4,-1-w401a..xn--7jb180g; 4,𑲞-1..ᠩ\u06A5; [B1, B5, B6, V6, X4_2]; xn--4,-1-w401a..xn--7jb180g; [B1, B5, B6, V6, A4_2]; ; # 4,𑲞-1..ᠩڥ
+xn--4,-1-w401a..xn--7jb180gexf; 4,𑲞-1..\u200Dᠩ\u06A5; [B1, C2, V6, X4_2]; xn--4,-1-w401a..xn--7jb180gexf; [B1, C2, V6, A4_2]; ; # 4,𑲞-1..ᠩڥ
+xn----ecp8796hjtvg.xn--7jb180g; 🄅𑲞-⒈.ᠩ\u06A5; [B1, B5, B6, V6]; xn----ecp8796hjtvg.xn--7jb180g; ; ; # 🄅𑲞-⒈.ᠩڥ
+xn----ecp8796hjtvg.xn--7jb180gexf; 🄅𑲞-⒈.\u200Dᠩ\u06A5; [B1, C2, V6]; xn----ecp8796hjtvg.xn--7jb180gexf; ; ; # 🄅𑲞-⒈.ᠩڥ
+񗀤。𞤪򮿋; 񗀤.𞤪򮿋; [B2, B3, V6]; xn--4240a.xn--ie6h83808a; ; ; # .𞤪
+񗀤。𞤈򮿋; 񗀤.𞤪򮿋; [B2, B3, V6]; xn--4240a.xn--ie6h83808a; ; ; # .𞤪
+xn--4240a.xn--ie6h83808a; 񗀤.𞤪򮿋; [B2, B3, V6]; xn--4240a.xn--ie6h83808a; ; ; # .𞤪
+\u05C1۲。𐮊\u066C𝨊鄨; \u05C1۲.𐮊\u066C𝨊鄨; [B1, B2, B3, V5]; xn--pdb42d.xn--lib6412enztdwv6h; ; ; # ׁ۲.𐮊٬𝨊鄨
+\u05C1۲。𐮊\u066C𝨊鄨; \u05C1۲.𐮊\u066C𝨊鄨; [B1, B2, B3, V5]; xn--pdb42d.xn--lib6412enztdwv6h; ; ; # ׁ۲.𐮊٬𝨊鄨
+xn--pdb42d.xn--lib6412enztdwv6h; \u05C1۲.𐮊\u066C𝨊鄨; [B1, B2, B3, V5]; xn--pdb42d.xn--lib6412enztdwv6h; ; ; # ׁ۲.𐮊٬𝨊鄨
+𞭳-ꡁ。\u1A69\u0BCD-; 𞭳-ꡁ.\u1A69\u0BCD-; [B1, B2, B3, V3, V5, V6]; xn----be4e4276f.xn----lze333i; ; ; # -ꡁ.ᩩ்-
+xn----be4e4276f.xn----lze333i; 𞭳-ꡁ.\u1A69\u0BCD-; [B1, B2, B3, V3, V5, V6]; xn----be4e4276f.xn----lze333i; ; ; # -ꡁ.ᩩ்-
+\u1039-𚮭🞢.ß; \u1039-𚮭🞢.ß; [V5, V6]; xn----9tg11172akr8b.xn--zca; ; xn----9tg11172akr8b.ss; # ္-🞢.ß
+\u1039-𚮭🞢.ß; ; [V5, V6]; xn----9tg11172akr8b.xn--zca; ; xn----9tg11172akr8b.ss; # ္-🞢.ß
+\u1039-𚮭🞢.SS; \u1039-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+\u1039-𚮭🞢.ss; ; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+\u1039-𚮭🞢.Ss; \u1039-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+xn----9tg11172akr8b.ss; \u1039-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+xn----9tg11172akr8b.xn--zca; \u1039-𚮭🞢.ß; [V5, V6]; xn----9tg11172akr8b.xn--zca; ; ; # ္-🞢.ß
+\u1039-𚮭🞢.SS; \u1039-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+\u1039-𚮭🞢.ss; \u1039-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+\u1039-𚮭🞢.Ss; \u1039-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+\uFCF2-\u200C。Ⴟ\u200C␣; \u0640\u064E\u0651-\u200C.Ⴟ\u200C␣; [B3, B6, C1, V6]; xn----eoc6bm0504a.xn--3nd849e05c; ; xn----eoc6bm.xn--3nd240h; [B3, B6, V3, V6] # ـَّ-.Ⴟ␣
+\u0640\u064E\u0651-\u200C。Ⴟ\u200C␣; \u0640\u064E\u0651-\u200C.Ⴟ\u200C␣; [B3, B6, C1, V6]; xn----eoc6bm0504a.xn--3nd849e05c; ; xn----eoc6bm.xn--3nd240h; [B3, B6, V3, V6] # ـَّ-.Ⴟ␣
+\u0640\u064E\u0651-\u200C。ⴟ\u200C␣; \u0640\u064E\u0651-\u200C.ⴟ\u200C␣; [B3, B6, C1]; xn----eoc6bm0504a.xn--0ug13nd0j; ; xn----eoc6bm.xn--xph904a; [B3, B6, V3] # ـَّ-.ⴟ␣
+xn----eoc6bm.xn--xph904a; \u0640\u064E\u0651-.ⴟ␣; [B3, B6, V3]; xn----eoc6bm.xn--xph904a; ; ; # ـَّ-.ⴟ␣
+xn----eoc6bm0504a.xn--0ug13nd0j; \u0640\u064E\u0651-\u200C.ⴟ\u200C␣; [B3, B6, C1]; xn----eoc6bm0504a.xn--0ug13nd0j; ; ; # ـَّ-.ⴟ␣
+xn----eoc6bm.xn--3nd240h; \u0640\u064E\u0651-.Ⴟ␣; [B3, B6, V3, V6]; xn----eoc6bm.xn--3nd240h; ; ; # ـَّ-.Ⴟ␣
+xn----eoc6bm0504a.xn--3nd849e05c; \u0640\u064E\u0651-\u200C.Ⴟ\u200C␣; [B3, B6, C1, V6]; xn----eoc6bm0504a.xn--3nd849e05c; ; ; # ـَّ-.Ⴟ␣
+\uFCF2-\u200C。ⴟ\u200C␣; \u0640\u064E\u0651-\u200C.ⴟ\u200C␣; [B3, B6, C1]; xn----eoc6bm0504a.xn--0ug13nd0j; ; xn----eoc6bm.xn--xph904a; [B3, B6, V3] # ـَّ-.ⴟ␣
+\u0D4D-\u200D\u200C。񥞧₅≠; \u0D4D-\u200D\u200C.񥞧5≠; [C1, C2, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [V3, V5, V6] # ്-.5≠
+\u0D4D-\u200D\u200C。񥞧₅=\u0338; \u0D4D-\u200D\u200C.񥞧5≠; [C1, C2, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [V3, V5, V6] # ്-.5≠
+\u0D4D-\u200D\u200C。񥞧5≠; \u0D4D-\u200D\u200C.񥞧5≠; [C1, C2, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [V3, V5, V6] # ്-.5≠
+\u0D4D-\u200D\u200C。񥞧5=\u0338; \u0D4D-\u200D\u200C.񥞧5≠; [C1, C2, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [V3, V5, V6] # ്-.5≠
+xn----jmf.xn--5-ufo50192e; \u0D4D-.񥞧5≠; [V3, V5, V6]; xn----jmf.xn--5-ufo50192e; ; ; # ്-.5≠
+xn----jmf215lda.xn--5-ufo50192e; \u0D4D-\u200D\u200C.񥞧5≠; [C1, C2, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; ; # ്-.5≠
+锣。\u0A4D󠘻󠚆; 锣.\u0A4D󠘻󠚆; [V5, V6]; xn--gc5a.xn--ybc83044ppga; ; ; # 锣.੍
+xn--gc5a.xn--ybc83044ppga; 锣.\u0A4D󠘻󠚆; [V5, V6]; xn--gc5a.xn--ybc83044ppga; ; ; # 锣.੍
+\u063D𑈾.\u0649\u200D\uA92B; \u063D𑈾.\u0649\u200D\uA92B; [B3, C2]; xn--8gb2338k.xn--lhb603k060h; ; xn--8gb2338k.xn--lhb0154f; [] # ؽ𑈾.ى꤫
+\u063D𑈾.\u0649\u200D\uA92B; ; [B3, C2]; xn--8gb2338k.xn--lhb603k060h; ; xn--8gb2338k.xn--lhb0154f; [] # ؽ𑈾.ى꤫
+xn--8gb2338k.xn--lhb0154f; \u063D𑈾.\u0649\uA92B; ; xn--8gb2338k.xn--lhb0154f; ; ; # ؽ𑈾.ى꤫
+\u063D𑈾.\u0649\uA92B; ; ; xn--8gb2338k.xn--lhb0154f; ; ; # ؽ𑈾.ى꤫
+xn--8gb2338k.xn--lhb603k060h; \u063D𑈾.\u0649\u200D\uA92B; [B3, C2]; xn--8gb2338k.xn--lhb603k060h; ; ; # ؽ𑈾.ى꤫
+\u0666⁴Ⴅ.\u08BD\u200C; \u06664Ⴅ.\u08BD\u200C; [B1, B3, C1, V6]; xn--4-kqc489e.xn--jzb840j; ; xn--4-kqc489e.xn--jzb; [B1, V6] # ٦4Ⴅ.ࢽ
+\u06664Ⴅ.\u08BD\u200C; ; [B1, B3, C1, V6]; xn--4-kqc489e.xn--jzb840j; ; xn--4-kqc489e.xn--jzb; [B1, V6] # ٦4Ⴅ.ࢽ
+\u06664ⴅ.\u08BD\u200C; ; [B1, B3, C1]; xn--4-kqc6770a.xn--jzb840j; ; xn--4-kqc6770a.xn--jzb; [B1] # ٦4ⴅ.ࢽ
+xn--4-kqc6770a.xn--jzb; \u06664ⴅ.\u08BD; [B1]; xn--4-kqc6770a.xn--jzb; ; ; # ٦4ⴅ.ࢽ
+xn--4-kqc6770a.xn--jzb840j; \u06664ⴅ.\u08BD\u200C; [B1, B3, C1]; xn--4-kqc6770a.xn--jzb840j; ; ; # ٦4ⴅ.ࢽ
+xn--4-kqc489e.xn--jzb; \u06664Ⴅ.\u08BD; [B1, V6]; xn--4-kqc489e.xn--jzb; ; ; # ٦4Ⴅ.ࢽ
+xn--4-kqc489e.xn--jzb840j; \u06664Ⴅ.\u08BD\u200C; [B1, B3, C1, V6]; xn--4-kqc489e.xn--jzb840j; ; ; # ٦4Ⴅ.ࢽ
+\u0666⁴ⴅ.\u08BD\u200C; \u06664ⴅ.\u08BD\u200C; [B1, B3, C1]; xn--4-kqc6770a.xn--jzb840j; ; xn--4-kqc6770a.xn--jzb; [B1] # ٦4ⴅ.ࢽ
+ჁႱ6\u0318。ß\u1B03; ჁႱ6\u0318.ß\u1B03; [V6]; xn--6-8cb555h2b.xn--zca894k; ; xn--6-8cb555h2b.xn--ss-2vq; # ჁႱ6̘.ßᬃ
+ⴡⴑ6\u0318。ß\u1B03; ⴡⴑ6\u0318.ß\u1B03; ; xn--6-8cb7433a2ba.xn--zca894k; ; xn--6-8cb7433a2ba.xn--ss-2vq; # ⴡⴑ6̘.ßᬃ
+ჁႱ6\u0318。SS\u1B03; ჁႱ6\u0318.ss\u1B03; [V6]; xn--6-8cb555h2b.xn--ss-2vq; ; ; # ჁႱ6̘.ssᬃ
+ⴡⴑ6\u0318。ss\u1B03; ⴡⴑ6\u0318.ss\u1B03; ; xn--6-8cb7433a2ba.xn--ss-2vq; ; ; # ⴡⴑ6̘.ssᬃ
+Ⴡⴑ6\u0318。Ss\u1B03; Ⴡⴑ6\u0318.ss\u1B03; [V6]; xn--6-8cb306hms1a.xn--ss-2vq; ; ; # Ⴡⴑ6̘.ssᬃ
+xn--6-8cb306hms1a.xn--ss-2vq; Ⴡⴑ6\u0318.ss\u1B03; [V6]; xn--6-8cb306hms1a.xn--ss-2vq; ; ; # Ⴡⴑ6̘.ssᬃ
+xn--6-8cb7433a2ba.xn--ss-2vq; ⴡⴑ6\u0318.ss\u1B03; ; xn--6-8cb7433a2ba.xn--ss-2vq; ; ; # ⴡⴑ6̘.ssᬃ
+ⴡⴑ6\u0318.ss\u1B03; ; ; xn--6-8cb7433a2ba.xn--ss-2vq; ; ; # ⴡⴑ6̘.ssᬃ
+ჁႱ6\u0318.SS\u1B03; ჁႱ6\u0318.ss\u1B03; [V6]; xn--6-8cb555h2b.xn--ss-2vq; ; ; # ჁႱ6̘.ssᬃ
+Ⴡⴑ6\u0318.Ss\u1B03; Ⴡⴑ6\u0318.ss\u1B03; [V6]; xn--6-8cb306hms1a.xn--ss-2vq; ; ; # Ⴡⴑ6̘.ssᬃ
+xn--6-8cb555h2b.xn--ss-2vq; ჁႱ6\u0318.ss\u1B03; [V6]; xn--6-8cb555h2b.xn--ss-2vq; ; ; # ჁႱ6̘.ssᬃ
+xn--6-8cb7433a2ba.xn--zca894k; ⴡⴑ6\u0318.ß\u1B03; ; xn--6-8cb7433a2ba.xn--zca894k; ; ; # ⴡⴑ6̘.ßᬃ
+ⴡⴑ6\u0318.ß\u1B03; ; ; xn--6-8cb7433a2ba.xn--zca894k; ; xn--6-8cb7433a2ba.xn--ss-2vq; # ⴡⴑ6̘.ßᬃ
+xn--6-8cb555h2b.xn--zca894k; ჁႱ6\u0318.ß\u1B03; [V6]; xn--6-8cb555h2b.xn--zca894k; ; ; # ჁႱ6̘.ßᬃ
+򋡐。≯𑋪; 򋡐.≯𑋪; [V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+򋡐。>\u0338𑋪; 򋡐.≯𑋪; [V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+򋡐。≯𑋪; 򋡐.≯𑋪; [V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+򋡐。>\u0338𑋪; 򋡐.≯𑋪; [V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+xn--eo08b.xn--hdh3385g; 򋡐.≯𑋪; [V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+\u065A۲。\u200C-\u1BF3\u08E2; \u065A۲.\u200C-\u1BF3\u08E2; [B1, C1, V5, V6]; xn--2hb81a.xn----xrd657l30d; ; xn--2hb81a.xn----xrd657l; [B1, V3, V5, V6] # ٚ۲.-᯳
+xn--2hb81a.xn----xrd657l; \u065A۲.-\u1BF3\u08E2; [B1, V3, V5, V6]; xn--2hb81a.xn----xrd657l; ; ; # ٚ۲.-᯳
+xn--2hb81a.xn----xrd657l30d; \u065A۲.\u200C-\u1BF3\u08E2; [B1, C1, V5, V6]; xn--2hb81a.xn----xrd657l30d; ; ; # ٚ۲.-᯳
+󠄏𖬴󠲽。\uFFA0; 𖬴󠲽.\uFFA0; [V5, V6]; xn--619ep9154c.xn--cl7c; ; ; # 𖬴.
+󠄏𖬴󠲽。\u1160; 𖬴󠲽.\u1160; [V5, V6]; xn--619ep9154c.xn--psd; ; ; # 𖬴.
+xn--619ep9154c.xn--psd; 𖬴󠲽.\u1160; [V5, V6]; xn--619ep9154c.xn--psd; ; ; # 𖬴.
+xn--619ep9154c.xn--cl7c; 𖬴󠲽.\uFFA0; [V5, V6]; xn--619ep9154c.xn--cl7c; ; ; # 𖬴.
+ß⒈\u0760\uD7AE.􉖲󠅄\u0605򉔯; ß⒈\u0760\uD7AE.􉖲\u0605򉔯; [B5, V6]; xn--zca444a0s1ao12n.xn--nfb09923ifkyyb; ; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; # ß⒈ݠ.
+ß1.\u0760\uD7AE.􉖲󠅄\u0605򉔯; ß1.\u0760\uD7AE.􉖲\u0605򉔯; [B2, B3, B5, V6]; xn--1-pfa.xn--kpb6677h.xn--nfb09923ifkyyb; ; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; # ß1.ݠ.
+SS1.\u0760\uD7AE.􉖲󠅄\u0605򉔯; ss1.\u0760\uD7AE.􉖲\u0605򉔯; [B2, B3, B5, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+ss1.\u0760\uD7AE.􉖲󠅄\u0605򉔯; ss1.\u0760\uD7AE.􉖲\u0605򉔯; [B2, B3, B5, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+Ss1.\u0760\uD7AE.􉖲󠅄\u0605򉔯; ss1.\u0760\uD7AE.􉖲\u0605򉔯; [B2, B3, B5, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ss1.\u0760\uD7AE.􉖲\u0605򉔯; [B2, B3, B5, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+xn--1-pfa.xn--kpb6677h.xn--nfb09923ifkyyb; ß1.\u0760\uD7AE.􉖲\u0605򉔯; [B2, B3, B5, V6]; xn--1-pfa.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ß1.ݠ.
+SS⒈\u0760\uD7AE.􉖲󠅄\u0605򉔯; ss⒈\u0760\uD7AE.􉖲\u0605򉔯; [B5, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+ss⒈\u0760\uD7AE.􉖲󠅄\u0605򉔯; ss⒈\u0760\uD7AE.􉖲\u0605򉔯; [B5, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+Ss⒈\u0760\uD7AE.􉖲󠅄\u0605򉔯; ss⒈\u0760\uD7AE.􉖲\u0605򉔯; [B5, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ss⒈\u0760\uD7AE.􉖲\u0605򉔯; [B5, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+xn--zca444a0s1ao12n.xn--nfb09923ifkyyb; ß⒈\u0760\uD7AE.􉖲\u0605򉔯; [B5, V6]; xn--zca444a0s1ao12n.xn--nfb09923ifkyyb; ; ; # ß⒈ݠ.
+󠭔.𐋱₂; 󠭔.𐋱2; [V6]; xn--vi56e.xn--2-w91i; ; ; # .𐋱2
+󠭔.𐋱2; ; [V6]; xn--vi56e.xn--2-w91i; ; ; # .𐋱2
+xn--vi56e.xn--2-w91i; 󠭔.𐋱2; [V6]; xn--vi56e.xn--2-w91i; ; ; # .𐋱2
+\u0716\u0947。-ß\u06A5\u200C; \u0716\u0947.-ß\u06A5\u200C; [B1, C1, V3]; xn--gnb63i.xn----qfa845bhx4a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ßڥ
+\u0716\u0947。-SS\u06A5\u200C; \u0716\u0947.-ss\u06A5\u200C; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ssڥ
+\u0716\u0947。-ss\u06A5\u200C; \u0716\u0947.-ss\u06A5\u200C; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ssڥ
+\u0716\u0947。-Ss\u06A5\u200C; \u0716\u0947.-ss\u06A5\u200C; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ssڥ
+xn--gnb63i.xn---ss-4ef; \u0716\u0947.-ss\u06A5; [B1, V3]; xn--gnb63i.xn---ss-4ef; ; ; # ܖे.-ssڥ
+xn--gnb63i.xn---ss-4ef9263a; \u0716\u0947.-ss\u06A5\u200C; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; ; # ܖे.-ssڥ
+xn--gnb63i.xn----qfa845bhx4a; \u0716\u0947.-ß\u06A5\u200C; [B1, C1, V3]; xn--gnb63i.xn----qfa845bhx4a; ; ; # ܖे.-ßڥ
+\u1BA9\u200D\u062A񡚈.\u1CD5䷉Ⴡ; \u1BA9\u200D\u062A񡚈.\u1CD5䷉Ⴡ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--5nd792dgv3b; ; xn--pgb911izv33i.xn--5nd792dgv3b; [B1, V5, V6] # ᮩت.᳕䷉Ⴡ
+\u1BA9\u200D\u062A񡚈.\u1CD5䷉Ⴡ; ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--5nd792dgv3b; ; xn--pgb911izv33i.xn--5nd792dgv3b; [B1, V5, V6] # ᮩت.᳕䷉Ⴡ
+\u1BA9\u200D\u062A񡚈.\u1CD5䷉ⴡ; ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--i6f270etuy; ; xn--pgb911izv33i.xn--i6f270etuy; [B1, V5, V6] # ᮩت.᳕䷉ⴡ
+xn--pgb911izv33i.xn--i6f270etuy; \u1BA9\u062A񡚈.\u1CD5䷉ⴡ; [B1, V5, V6]; xn--pgb911izv33i.xn--i6f270etuy; ; ; # ᮩت.᳕䷉ⴡ
+xn--pgb911imgdrw34r.xn--i6f270etuy; \u1BA9\u200D\u062A񡚈.\u1CD5䷉ⴡ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--i6f270etuy; ; ; # ᮩت.᳕䷉ⴡ
+xn--pgb911izv33i.xn--5nd792dgv3b; \u1BA9\u062A񡚈.\u1CD5䷉Ⴡ; [B1, V5, V6]; xn--pgb911izv33i.xn--5nd792dgv3b; ; ; # ᮩت.᳕䷉Ⴡ
+xn--pgb911imgdrw34r.xn--5nd792dgv3b; \u1BA9\u200D\u062A񡚈.\u1CD5䷉Ⴡ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--5nd792dgv3b; ; ; # ᮩت.᳕䷉Ⴡ
+\u1BA9\u200D\u062A񡚈.\u1CD5䷉ⴡ; \u1BA9\u200D\u062A񡚈.\u1CD5䷉ⴡ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--i6f270etuy; ; xn--pgb911izv33i.xn--i6f270etuy; [B1, V5, V6] # ᮩت.᳕䷉ⴡ
+\u2DBF.ß\u200D; ; [C2, V6]; xn--7pj.xn--zca870n; ; xn--7pj.ss; [V6] # .ß
+\u2DBF.SS\u200D; \u2DBF.ss\u200D; [C2, V6]; xn--7pj.xn--ss-n1t; ; xn--7pj.ss; [V6] # .ss
+\u2DBF.ss\u200D; ; [C2, V6]; xn--7pj.xn--ss-n1t; ; xn--7pj.ss; [V6] # .ss
+\u2DBF.Ss\u200D; \u2DBF.ss\u200D; [C2, V6]; xn--7pj.xn--ss-n1t; ; xn--7pj.ss; [V6] # .ss
+xn--7pj.ss; \u2DBF.ss; [V6]; xn--7pj.ss; ; ; # .ss
+xn--7pj.xn--ss-n1t; \u2DBF.ss\u200D; [C2, V6]; xn--7pj.xn--ss-n1t; ; ; # .ss
+xn--7pj.xn--zca870n; \u2DBF.ß\u200D; [C2, V6]; xn--7pj.xn--zca870n; ; ; # .ß
+\u1BF3︒.\u062A≯ꡂ; ; [B2, B3, B6, V5, V6]; xn--1zf8957g.xn--pgb885lry5g; ; ; # ᯳︒.ت≯ꡂ
+\u1BF3︒.\u062A>\u0338ꡂ; \u1BF3︒.\u062A≯ꡂ; [B2, B3, B6, V5, V6]; xn--1zf8957g.xn--pgb885lry5g; ; ; # ᯳︒.ت≯ꡂ
+\u1BF3。.\u062A≯ꡂ; \u1BF3..\u062A≯ꡂ; [B2, B3, V5, X4_2]; xn--1zf..xn--pgb885lry5g; [B2, B3, V5, A4_2]; ; # ᯳..ت≯ꡂ
+\u1BF3。.\u062A>\u0338ꡂ; \u1BF3..\u062A≯ꡂ; [B2, B3, V5, X4_2]; xn--1zf..xn--pgb885lry5g; [B2, B3, V5, A4_2]; ; # ᯳..ت≯ꡂ
+xn--1zf..xn--pgb885lry5g; \u1BF3..\u062A≯ꡂ; [B2, B3, V5, X4_2]; xn--1zf..xn--pgb885lry5g; [B2, B3, V5, A4_2]; ; # ᯳..ت≯ꡂ
+xn--1zf8957g.xn--pgb885lry5g; \u1BF3︒.\u062A≯ꡂ; [B2, B3, B6, V5, V6]; xn--1zf8957g.xn--pgb885lry5g; ; ; # ᯳︒.ت≯ꡂ
+≮≠񏻃。-𫠆\u06B7𐹪; ≮≠񏻃.-𫠆\u06B7𐹪; [B1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+<\u0338=\u0338񏻃。-𫠆\u06B7𐹪; ≮≠񏻃.-𫠆\u06B7𐹪; [B1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+≮≠񏻃。-𫠆\u06B7𐹪; ≮≠񏻃.-𫠆\u06B7𐹪; [B1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+<\u0338=\u0338񏻃。-𫠆\u06B7𐹪; ≮≠񏻃.-𫠆\u06B7𐹪; [B1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+xn--1ch1a29470f.xn----7uc5363rc1rn; ≮≠񏻃.-𫠆\u06B7𐹪; [B1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+𐹡\u0777。ꡂ; 𐹡\u0777.ꡂ; [B1]; xn--7pb5275k.xn--bc9a; ; ; # 𐹡ݷ.ꡂ
+xn--7pb5275k.xn--bc9a; 𐹡\u0777.ꡂ; [B1]; xn--7pb5275k.xn--bc9a; ; ; # 𐹡ݷ.ꡂ
+Ⴉ𝆅񔻅\u0619.ß𐧦𐹳\u0775; ; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--zca684a699vf2d; ; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; # Ⴉؙ𝆅.ß𐧦𐹳ݵ
+ⴉ𝆅񔻅\u0619.ß𐧦𐹳\u0775; ; [B5, B6, V6]; xn--7fb940rwt3z7xvz.xn--zca684a699vf2d; ; xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; # ⴉؙ𝆅.ß𐧦𐹳ݵ
+Ⴉ𝆅񔻅\u0619.SS𐧦𐹳\u0775; Ⴉ𝆅񔻅\u0619.ss𐧦𐹳\u0775; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; ; ; # Ⴉؙ𝆅.ss𐧦𐹳ݵ
+ⴉ𝆅񔻅\u0619.ss𐧦𐹳\u0775; ; [B5, B6, V6]; xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; ; ; # ⴉؙ𝆅.ss𐧦𐹳ݵ
+Ⴉ𝆅񔻅\u0619.Ss𐧦𐹳\u0775; Ⴉ𝆅񔻅\u0619.ss𐧦𐹳\u0775; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; ; ; # Ⴉؙ𝆅.ss𐧦𐹳ݵ
+xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; Ⴉ𝆅񔻅\u0619.ss𐧦𐹳\u0775; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; ; ; # Ⴉؙ𝆅.ss𐧦𐹳ݵ
+xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; ⴉ𝆅񔻅\u0619.ss𐧦𐹳\u0775; [B5, B6, V6]; xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; ; ; # ⴉؙ𝆅.ss𐧦𐹳ݵ
+xn--7fb940rwt3z7xvz.xn--zca684a699vf2d; ⴉ𝆅񔻅\u0619.ß𐧦𐹳\u0775; [B5, B6, V6]; xn--7fb940rwt3z7xvz.xn--zca684a699vf2d; ; ; # ⴉؙ𝆅.ß𐧦𐹳ݵ
+xn--7fb125cjv87a7xvz.xn--zca684a699vf2d; Ⴉ𝆅񔻅\u0619.ß𐧦𐹳\u0775; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--zca684a699vf2d; ; ; # Ⴉؙ𝆅.ß𐧦𐹳ݵ
+\u200D\u0643𐧾↙.񊽡; ; [B1, C2, V6]; xn--fhb713k87ag053c.xn--7s4w; ; xn--fhb011lnp8n.xn--7s4w; [B3, V6] # ك𐧾↙.
+xn--fhb011lnp8n.xn--7s4w; \u0643𐧾↙.񊽡; [B3, V6]; xn--fhb011lnp8n.xn--7s4w; ; ; # ك𐧾↙.
+xn--fhb713k87ag053c.xn--7s4w; \u200D\u0643𐧾↙.񊽡; [B1, C2, V6]; xn--fhb713k87ag053c.xn--7s4w; ; ; # ك𐧾↙.
+梉。\u200C; 梉.\u200C; [C1]; xn--7zv.xn--0ug; ; xn--7zv.; [] # 梉.
+xn--7zv.; 梉.; ; xn--7zv.; ; ; # 梉.
+梉.; ; ; xn--7zv.; ; ; # 梉.
+xn--7zv.xn--0ug; 梉.\u200C; [C1]; xn--7zv.xn--0ug; ; ; # 梉.
+ꡣ-≠.\u200D𞤗𐅢Ↄ; ꡣ-≠.\u200D𞤹𐅢Ↄ; [B1, B6, C2, V6]; xn----ufo9661d.xn--1ug79cm620c71sh; ; xn----ufo9661d.xn--q5g0929fhm4f; [B2, B3, B6, V6] # ꡣ-≠.𞤹𐅢Ↄ
+ꡣ-=\u0338.\u200D𞤗𐅢Ↄ; ꡣ-≠.\u200D𞤹𐅢Ↄ; [B1, B6, C2, V6]; xn----ufo9661d.xn--1ug79cm620c71sh; ; xn----ufo9661d.xn--q5g0929fhm4f; [B2, B3, B6, V6] # ꡣ-≠.𞤹𐅢Ↄ
+ꡣ-=\u0338.\u200D𞤹𐅢ↄ; ꡣ-≠.\u200D𞤹𐅢ↄ; [B1, B6, C2]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6] # ꡣ-≠.𞤹𐅢ↄ
+ꡣ-≠.\u200D𞤹𐅢ↄ; ; [B1, B6, C2]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6] # ꡣ-≠.𞤹𐅢ↄ
+ꡣ-≠.\u200D𞤗𐅢ↄ; ꡣ-≠.\u200D𞤹𐅢ↄ; [B1, B6, C2]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6] # ꡣ-≠.𞤹𐅢ↄ
+ꡣ-=\u0338.\u200D𞤗𐅢ↄ; ꡣ-≠.\u200D𞤹𐅢ↄ; [B1, B6, C2]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6] # ꡣ-≠.𞤹𐅢ↄ
+xn----ufo9661d.xn--r5gy929fhm4f; ꡣ-≠.𞤹𐅢ↄ; [B2, B3, B6]; xn----ufo9661d.xn--r5gy929fhm4f; ; ; # ꡣ-≠.𞤹𐅢ↄ
+xn----ufo9661d.xn--1ug99cj620c71sh; ꡣ-≠.\u200D𞤹𐅢ↄ; [B1, B6, C2]; xn----ufo9661d.xn--1ug99cj620c71sh; ; ; # ꡣ-≠.𞤹𐅢ↄ
+xn----ufo9661d.xn--q5g0929fhm4f; ꡣ-≠.𞤹𐅢Ↄ; [B2, B3, B6, V6]; xn----ufo9661d.xn--q5g0929fhm4f; ; ; # ꡣ-≠.𞤹𐅢Ↄ
+xn----ufo9661d.xn--1ug79cm620c71sh; ꡣ-≠.\u200D𞤹𐅢Ↄ; [B1, B6, C2, V6]; xn----ufo9661d.xn--1ug79cm620c71sh; ; ; # ꡣ-≠.𞤹𐅢Ↄ
+ς⒐𝆫⸵。𐱢🄊𝟳; ς⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--3xa019nwtghi25b.xn--7-075iy877c; ; xn--4xa809nwtghi25b.xn--7-075iy877c; # ς⒐𝆫⸵.🄊7
+ς9.𝆫⸵。𐱢9,7; ς9.𝆫⸵.𐱢9,7; [B1, V5, V6]; xn--9-xmb.xn--ltj1535k.xn--9,7-r67t; ; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; # ς9.𝆫⸵.9,7
+Σ9.𝆫⸵。𐱢9,7; σ9.𝆫⸵.𐱢9,7; [B1, V5, V6]; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; ; ; # σ9.𝆫⸵.9,7
+σ9.𝆫⸵。𐱢9,7; σ9.𝆫⸵.𐱢9,7; [B1, V5, V6]; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; ; ; # σ9.𝆫⸵.9,7
+xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; σ9.𝆫⸵.𐱢9,7; [B1, V5, V6]; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; ; ; # σ9.𝆫⸵.9,7
+xn--9-xmb.xn--ltj1535k.xn--9,7-r67t; ς9.𝆫⸵.𐱢9,7; [B1, V5, V6]; xn--9-xmb.xn--ltj1535k.xn--9,7-r67t; ; ; # ς9.𝆫⸵.9,7
+Σ⒐𝆫⸵。𐱢🄊𝟳; σ⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--4xa809nwtghi25b.xn--7-075iy877c; ; ; # σ⒐𝆫⸵.🄊7
+σ⒐𝆫⸵。𐱢🄊𝟳; σ⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--4xa809nwtghi25b.xn--7-075iy877c; ; ; # σ⒐𝆫⸵.🄊7
+xn--4xa809nwtghi25b.xn--7-075iy877c; σ⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--4xa809nwtghi25b.xn--7-075iy877c; ; ; # σ⒐𝆫⸵.🄊7
+xn--3xa019nwtghi25b.xn--7-075iy877c; ς⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--3xa019nwtghi25b.xn--7-075iy877c; ; ; # ς⒐𝆫⸵.🄊7
+\u0853.\u200Cß; \u0853.\u200Cß; [B1, C1]; xn--iwb.xn--zca570n; ; xn--iwb.ss; [] # ࡓ.ß
+\u0853.\u200Cß; ; [B1, C1]; xn--iwb.xn--zca570n; ; xn--iwb.ss; [] # ࡓ.ß
+\u0853.\u200CSS; \u0853.\u200Css; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+\u0853.\u200Css; ; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+xn--iwb.ss; \u0853.ss; ; xn--iwb.ss; ; ; # ࡓ.ss
+\u0853.ss; ; ; xn--iwb.ss; ; ; # ࡓ.ss
+\u0853.SS; \u0853.ss; ; xn--iwb.ss; ; ; # ࡓ.ss
+xn--iwb.xn--ss-i1t; \u0853.\u200Css; [B1, C1]; xn--iwb.xn--ss-i1t; ; ; # ࡓ.ss
+xn--iwb.xn--zca570n; \u0853.\u200Cß; [B1, C1]; xn--iwb.xn--zca570n; ; ; # ࡓ.ß
+\u0853.\u200CSS; \u0853.\u200Css; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+\u0853.\u200Css; \u0853.\u200Css; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+\u0853.\u200CSs; \u0853.\u200Css; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+\u0853.\u200CSs; \u0853.\u200Css; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+񯶣-.\u200D\u074E\uA94D󠻨; ; [B1, B6, C2, V3, V6]; xn----s116e.xn--1ob387jy90hq459k; ; xn----s116e.xn--1ob6504fmf40i; [B3, B6, V3, V6] # -.ݎꥍ
+xn----s116e.xn--1ob6504fmf40i; 񯶣-.\u074E\uA94D󠻨; [B3, B6, V3, V6]; xn----s116e.xn--1ob6504fmf40i; ; ; # -.ݎꥍ
+xn----s116e.xn--1ob387jy90hq459k; 񯶣-.\u200D\u074E\uA94D󠻨; [B1, B6, C2, V3, V6]; xn----s116e.xn--1ob387jy90hq459k; ; ; # -.ݎꥍ
+䃚蟥-。-񽒘⒈; 䃚蟥-.-񽒘⒈; [V3, V6]; xn----n50a258u.xn----ecp33805f; ; ; # 䃚蟥-.-⒈
+䃚蟥-。-񽒘1.; 䃚蟥-.-񽒘1.; [V3, V6]; xn----n50a258u.xn---1-up07j.; ; ; # 䃚蟥-.-1.
+xn----n50a258u.xn---1-up07j.; 䃚蟥-.-񽒘1.; [V3, V6]; xn----n50a258u.xn---1-up07j.; ; ; # 䃚蟥-.-1.
+xn----n50a258u.xn----ecp33805f; 䃚蟥-.-񽒘⒈; [V3, V6]; xn----n50a258u.xn----ecp33805f; ; ; # 䃚蟥-.-⒈
+𐹸䚵-ꡡ。⺇; 𐹸䚵-ꡡ.⺇; [B1]; xn----bm3an932a1l5d.xn--xvj; ; ; # 𐹸䚵-ꡡ.⺇
+xn----bm3an932a1l5d.xn--xvj; 𐹸䚵-ꡡ.⺇; [B1]; xn----bm3an932a1l5d.xn--xvj; ; ; # 𐹸䚵-ꡡ.⺇
+𑄳。\u1ADC𐹻; 𑄳.\u1ADC𐹻; [B1, B5, B6, V5, V6]; xn--v80d.xn--2rf1154i; ; ; # 𑄳.𐹻
+xn--v80d.xn--2rf1154i; 𑄳.\u1ADC𐹻; [B1, B5, B6, V5, V6]; xn--v80d.xn--2rf1154i; ; ; # 𑄳.𐹻
+≮𐹻.⒎𑂵\u06BA\u0602; ; [B1, V6]; xn--gdhx904g.xn--kfb18a325efm3s; ; ; # ≮𐹻.⒎𑂵ں
+<\u0338𐹻.⒎𑂵\u06BA\u0602; ≮𐹻.⒎𑂵\u06BA\u0602; [B1, V6]; xn--gdhx904g.xn--kfb18a325efm3s; ; ; # ≮𐹻.⒎𑂵ں
+≮𐹻.7.𑂵\u06BA\u0602; ; [B1, V5, V6]; xn--gdhx904g.7.xn--kfb18an307d; ; ; # ≮𐹻.7.𑂵ں
+<\u0338𐹻.7.𑂵\u06BA\u0602; ≮𐹻.7.𑂵\u06BA\u0602; [B1, V5, V6]; xn--gdhx904g.7.xn--kfb18an307d; ; ; # ≮𐹻.7.𑂵ں
+xn--gdhx904g.7.xn--kfb18an307d; ≮𐹻.7.𑂵\u06BA\u0602; [B1, V5, V6]; xn--gdhx904g.7.xn--kfb18an307d; ; ; # ≮𐹻.7.𑂵ں
+xn--gdhx904g.xn--kfb18a325efm3s; ≮𐹻.⒎𑂵\u06BA\u0602; [B1, V6]; xn--gdhx904g.xn--kfb18a325efm3s; ; ; # ≮𐹻.⒎𑂵ں
+ᢔ≠􋉂.\u200D𐋢; ; [C2, V6]; xn--ebf031cf7196a.xn--1ug9540g; ; xn--ebf031cf7196a.xn--587c; [V6] # ᢔ≠.𐋢
+ᢔ=\u0338􋉂.\u200D𐋢; ᢔ≠􋉂.\u200D𐋢; [C2, V6]; xn--ebf031cf7196a.xn--1ug9540g; ; xn--ebf031cf7196a.xn--587c; [V6] # ᢔ≠.𐋢
+xn--ebf031cf7196a.xn--587c; ᢔ≠􋉂.𐋢; [V6]; xn--ebf031cf7196a.xn--587c; ; ; # ᢔ≠.𐋢
+xn--ebf031cf7196a.xn--1ug9540g; ᢔ≠􋉂.\u200D𐋢; [C2, V6]; xn--ebf031cf7196a.xn--1ug9540g; ; ; # ᢔ≠.𐋢
+𐩁≮񣊛≯.\u066C𞵕⳿; 𐩁≮񣊛≯.\u066C𞵕⳿; [B1, B2, B3, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+𐩁<\u0338񣊛>\u0338.\u066C𞵕⳿; 𐩁≮񣊛≯.\u066C𞵕⳿; [B1, B2, B3, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+𐩁≮񣊛≯.\u066C𞵕⳿; ; [B1, B2, B3, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+𐩁<\u0338񣊛>\u0338.\u066C𞵕⳿; 𐩁≮񣊛≯.\u066C𞵕⳿; [B1, B2, B3, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+xn--gdhc0519o0y27b.xn--lib468q0d21a; 𐩁≮񣊛≯.\u066C𞵕⳿; [B1, B2, B3, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+-。⺐; -.⺐; [V3]; -.xn--6vj; ; ; # -.⺐
+-。⺐; -.⺐; [V3]; -.xn--6vj; ; ; # -.⺐
+-.xn--6vj; -.⺐; [V3]; -.xn--6vj; ; ; # -.⺐
+󠰩𑲬.\u065C; 󠰩𑲬.\u065C; [V5, V6]; xn--sn3d59267c.xn--4hb; ; ; # 𑲬.ٜ
+󠰩𑲬.\u065C; ; [V5, V6]; xn--sn3d59267c.xn--4hb; ; ; # 𑲬.ٜ
+xn--sn3d59267c.xn--4hb; 󠰩𑲬.\u065C; [V5, V6]; xn--sn3d59267c.xn--4hb; ; ; # 𑲬.ٜ
+𐍺.񚇃\u200C; ; [C1, V5, V6]; xn--ie8c.xn--0ug03366c; ; xn--ie8c.xn--2g51a; [V5, V6] # 𐍺.
+xn--ie8c.xn--2g51a; 𐍺.񚇃; [V5, V6]; xn--ie8c.xn--2g51a; ; ; # 𐍺.
+xn--ie8c.xn--0ug03366c; 𐍺.񚇃\u200C; [C1, V5, V6]; xn--ie8c.xn--0ug03366c; ; ; # 𐍺.
+\u063D\u06E3.𐨎; ; [B1, V5]; xn--8gb64a.xn--mr9c; ; ; # ؽۣ.𐨎
+xn--8gb64a.xn--mr9c; \u063D\u06E3.𐨎; [B1, V5]; xn--8gb64a.xn--mr9c; ; ; # ؽۣ.𐨎
+漦Ⴙς.񡻀𐴄; ; [B5, B6, V6]; xn--3xa157d717e.xn--9d0d3162t; ; xn--4xa947d717e.xn--9d0d3162t; # 漦Ⴙς.𐴄
+漦ⴙς.񡻀𐴄; ; [B5, B6, V6]; xn--3xa972sl47b.xn--9d0d3162t; ; xn--4xa772sl47b.xn--9d0d3162t; # 漦ⴙς.𐴄
+漦ႹΣ.񡻀𐴄; 漦Ⴙσ.񡻀𐴄; [B5, B6, V6]; xn--4xa947d717e.xn--9d0d3162t; ; ; # 漦Ⴙσ.𐴄
+漦ⴙσ.񡻀𐴄; ; [B5, B6, V6]; xn--4xa772sl47b.xn--9d0d3162t; ; ; # 漦ⴙσ.𐴄
+漦Ⴙσ.񡻀𐴄; ; [B5, B6, V6]; xn--4xa947d717e.xn--9d0d3162t; ; ; # 漦Ⴙσ.𐴄
+xn--4xa947d717e.xn--9d0d3162t; 漦Ⴙσ.񡻀𐴄; [B5, B6, V6]; xn--4xa947d717e.xn--9d0d3162t; ; ; # 漦Ⴙσ.𐴄
+xn--4xa772sl47b.xn--9d0d3162t; 漦ⴙσ.񡻀𐴄; [B5, B6, V6]; xn--4xa772sl47b.xn--9d0d3162t; ; ; # 漦ⴙσ.𐴄
+xn--3xa972sl47b.xn--9d0d3162t; 漦ⴙς.񡻀𐴄; [B5, B6, V6]; xn--3xa972sl47b.xn--9d0d3162t; ; ; # 漦ⴙς.𐴄
+xn--3xa157d717e.xn--9d0d3162t; 漦Ⴙς.񡻀𐴄; [B5, B6, V6]; xn--3xa157d717e.xn--9d0d3162t; ; ; # 漦Ⴙς.𐴄
+𐹫踧\u0CCD򫚇.󜀃⒈𝨤; ; [B1, V6]; xn--8tc1437dro0d6q06h.xn--tsh2611ncu71e; ; ; # 𐹫踧್.⒈𝨤
+𐹫踧\u0CCD򫚇.󜀃1.𝨤; ; [B1, V5, V6]; xn--8tc1437dro0d6q06h.xn--1-p948l.xn--m82h; ; ; # 𐹫踧್.1.𝨤
+xn--8tc1437dro0d6q06h.xn--1-p948l.xn--m82h; 𐹫踧\u0CCD򫚇.󜀃1.𝨤; [B1, V5, V6]; xn--8tc1437dro0d6q06h.xn--1-p948l.xn--m82h; ; ; # 𐹫踧್.1.𝨤
+xn--8tc1437dro0d6q06h.xn--tsh2611ncu71e; 𐹫踧\u0CCD򫚇.󜀃⒈𝨤; [B1, V6]; xn--8tc1437dro0d6q06h.xn--tsh2611ncu71e; ; ; # 𐹫踧್.⒈𝨤
+\u200D≮.󠟪𹫏-; \u200D≮.󠟪𹫏-; [C2, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [V3, V6] # ≮.-
+\u200D<\u0338.󠟪𹫏-; \u200D≮.󠟪𹫏-; [C2, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [V3, V6] # ≮.-
+\u200D≮.󠟪𹫏-; ; [C2, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [V3, V6] # ≮.-
+\u200D<\u0338.󠟪𹫏-; \u200D≮.󠟪𹫏-; [C2, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [V3, V6] # ≮.-
+xn--gdh.xn----cr99a1w710b; ≮.󠟪𹫏-; [V3, V6]; xn--gdh.xn----cr99a1w710b; ; ; # ≮.-
+xn--1ug95g.xn----cr99a1w710b; \u200D≮.󠟪𹫏-; [C2, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; ; # ≮.-
+\u200D\u200D襔。Ⴜ5ꡮ񵝏; \u200D\u200D襔.Ⴜ5ꡮ񵝏; [C2, V6]; xn--1uga7691f.xn--5-r1g7167ipfw8d; ; xn--2u2a.xn--5-r1g7167ipfw8d; [V6] # 襔.Ⴜ5ꡮ
+\u200D\u200D襔。ⴜ5ꡮ񵝏; \u200D\u200D襔.ⴜ5ꡮ񵝏; [C2, V6]; xn--1uga7691f.xn--5-uws5848bpf44e; ; xn--2u2a.xn--5-uws5848bpf44e; [V6] # 襔.ⴜ5ꡮ
+xn--2u2a.xn--5-uws5848bpf44e; 襔.ⴜ5ꡮ񵝏; [V6]; xn--2u2a.xn--5-uws5848bpf44e; ; ; # 襔.ⴜ5ꡮ
+xn--1uga7691f.xn--5-uws5848bpf44e; \u200D\u200D襔.ⴜ5ꡮ񵝏; [C2, V6]; xn--1uga7691f.xn--5-uws5848bpf44e; ; ; # 襔.ⴜ5ꡮ
+xn--2u2a.xn--5-r1g7167ipfw8d; 襔.Ⴜ5ꡮ񵝏; [V6]; xn--2u2a.xn--5-r1g7167ipfw8d; ; ; # 襔.Ⴜ5ꡮ
+xn--1uga7691f.xn--5-r1g7167ipfw8d; \u200D\u200D襔.Ⴜ5ꡮ񵝏; [C2, V6]; xn--1uga7691f.xn--5-r1g7167ipfw8d; ; ; # 襔.Ⴜ5ꡮ
+𐫜𑌼\u200D.婀; 𐫜𑌼\u200D.婀; [B3, C2]; xn--1ugx063g1if.xn--q0s; ; xn--ix9c26l.xn--q0s; [] # 𐫜𑌼.婀
+𐫜𑌼\u200D.婀; ; [B3, C2]; xn--1ugx063g1if.xn--q0s; ; xn--ix9c26l.xn--q0s; [] # 𐫜𑌼.婀
+xn--ix9c26l.xn--q0s; 𐫜𑌼.婀; ; xn--ix9c26l.xn--q0s; ; ; # 𐫜𑌼.婀
+𐫜𑌼.婀; ; ; xn--ix9c26l.xn--q0s; ; ; # 𐫜𑌼.婀
+xn--1ugx063g1if.xn--q0s; 𐫜𑌼\u200D.婀; [B3, C2]; xn--1ugx063g1if.xn--q0s; ; ; # 𐫜𑌼.婀
+󠅽︒︒𐹯。⬳\u1A78; ︒︒𐹯.⬳\u1A78; [B1, V6]; xn--y86ca186j.xn--7of309e; ; ; # ︒︒𐹯.⬳᩸
+󠅽。。𐹯。⬳\u1A78; ..𐹯.⬳\u1A78; [B1, X4_2]; ..xn--no0d.xn--7of309e; [B1, A4_2]; ; # ..𐹯.⬳᩸
+..xn--no0d.xn--7of309e; ..𐹯.⬳\u1A78; [B1, X4_2]; ..xn--no0d.xn--7of309e; [B1, A4_2]; ; # ..𐹯.⬳᩸
+xn--y86ca186j.xn--7of309e; ︒︒𐹯.⬳\u1A78; [B1, V6]; xn--y86ca186j.xn--7of309e; ; ; # ︒︒𐹯.⬳᩸
+𝟖ß.󠄐-?Ⴏ; 8ß.-?Ⴏ; [V3, V6]; xn--8-qfa.xn---?-gfk; ; 8ss.xn---?-gfk; # 8ß.-?Ⴏ
+8ß.󠄐-?Ⴏ; 8ß.-?Ⴏ; [V3, V6]; xn--8-qfa.xn---?-gfk; ; 8ss.xn---?-gfk; # 8ß.-?Ⴏ
+8ß.󠄐-?ⴏ; 8ß.-?ⴏ; [V3, V6]; xn--8-qfa.xn---?-261a; ; 8ss.xn---?-261a; # 8ß.-?ⴏ
+8SS.󠄐-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.󠄐-?ⴏ; 8ss.-?ⴏ; [V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+8ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.xn---?-gfk; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.xn---?-261a; 8ss.-?ⴏ; [V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+xn--8-qfa.xn---?-261a; 8ß.-?ⴏ; [V3, V6]; xn--8-qfa.xn---?-261a; ; ; # 8ß.-?ⴏ
+xn--8-qfa.xn---?-gfk; 8ß.-?Ⴏ; [V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+𝟖ß.󠄐-?ⴏ; 8ß.-?ⴏ; [V3, V6]; xn--8-qfa.xn---?-261a; ; 8ss.xn---?-261a; # 8ß.-?ⴏ
+𝟖SS.󠄐-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+𝟖ss.󠄐-?ⴏ; 8ss.-?ⴏ; [V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+𝟖ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.-?Ⴏ; ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.-?ⴏ; ; [V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+8SS.-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+xn--8-qfa.-?ⴏ; 8ß.-?ⴏ; [V3, V6]; xn--8-qfa.xn---?-261a; ; ; # 8ß.-?ⴏ
+XN--8-QFA.-?Ⴏ; 8ß.-?Ⴏ; [V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+Xn--8-Qfa.-?Ⴏ; 8ß.-?Ⴏ; [V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+xn--8-qfa.-?Ⴏ; 8ß.-?Ⴏ; [V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+𝟖Ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8Ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+-\u200D󠋟.\u200C𐹣Ⴅ; ; [B1, C1, C2, V3, V6]; xn----ugnv7071n.xn--dnd999e4j4p; ; xn----s721m.xn--dnd9201k; [B1, V3, V6] # -.𐹣Ⴅ
+-\u200D󠋟.\u200C𐹣ⴅ; ; [B1, C1, C2, V3, V6]; xn----ugnv7071n.xn--0ugz32cgr0p; ; xn----s721m.xn--wkj1423e; [B1, V3, V6] # -.𐹣ⴅ
+xn----s721m.xn--wkj1423e; -󠋟.𐹣ⴅ; [B1, V3, V6]; xn----s721m.xn--wkj1423e; ; ; # -.𐹣ⴅ
+xn----ugnv7071n.xn--0ugz32cgr0p; -\u200D󠋟.\u200C𐹣ⴅ; [B1, C1, C2, V3, V6]; xn----ugnv7071n.xn--0ugz32cgr0p; ; ; # -.𐹣ⴅ
+xn----s721m.xn--dnd9201k; -󠋟.𐹣Ⴅ; [B1, V3, V6]; xn----s721m.xn--dnd9201k; ; ; # -.𐹣Ⴅ
+xn----ugnv7071n.xn--dnd999e4j4p; -\u200D󠋟.\u200C𐹣Ⴅ; [B1, C1, C2, V3, V6]; xn----ugnv7071n.xn--dnd999e4j4p; ; ; # -.𐹣Ⴅ
+\uA9B9\u200D큷𻶡。₂; \uA9B9\u200D큷𻶡.2; [C2, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [V5, V6] # ꦹ큷.2
+\uA9B9\u200D큷𻶡。₂; \uA9B9\u200D큷𻶡.2; [C2, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [V5, V6] # ꦹ큷.2
+\uA9B9\u200D큷𻶡。2; \uA9B9\u200D큷𻶡.2; [C2, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [V5, V6] # ꦹ큷.2
+\uA9B9\u200D큷𻶡。2; \uA9B9\u200D큷𻶡.2; [C2, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [V5, V6] # ꦹ큷.2
+xn--0m9as84e2e21c.2; \uA9B9큷𻶡.2; [V5, V6]; xn--0m9as84e2e21c.2; ; ; # ꦹ큷.2
+xn--1ug1435cfkyaoi04d.2; \uA9B9\u200D큷𻶡.2; [C2, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; ; # ꦹ큷.2
+?.🄄𞯘; ; [B1, V6]; ?.xn--3x6hx6f; ; ; # ?.🄄
+?.3,𞯘; ; [B1, V6]; ?.xn--3,-tb22a; ; ; # ?.3,
+?.xn--3,-tb22a; ?.3,𞯘; [B1, V6]; ?.xn--3,-tb22a; ; ; # ?.3,
+?.xn--3x6hx6f; ?.🄄𞯘; [B1, V6]; ?.xn--3x6hx6f; ; ; # ?.🄄
+𝨖𐩙。\u06DD󀡶\uA8C5⒈; 𝨖𐩙.\u06DD󀡶\uA8C5⒈; [B1, V5, V6]; xn--rt9cl956a.xn--tlb403mxv4g06s9i; ; ; # 𝨖.ꣅ⒈
+𝨖𐩙。\u06DD󀡶\uA8C51.; 𝨖𐩙.\u06DD󀡶\uA8C51.; [B1, V5, V6]; xn--rt9cl956a.xn--1-dxc8545j0693i.; ; ; # 𝨖.ꣅ1.
+xn--rt9cl956a.xn--1-dxc8545j0693i.; 𝨖𐩙.\u06DD󀡶\uA8C51.; [B1, V5, V6]; xn--rt9cl956a.xn--1-dxc8545j0693i.; ; ; # 𝨖.ꣅ1.
+xn--rt9cl956a.xn--tlb403mxv4g06s9i; 𝨖𐩙.\u06DD󀡶\uA8C5⒈; [B1, V5, V6]; xn--rt9cl956a.xn--tlb403mxv4g06s9i; ; ; # 𝨖.ꣅ⒈
+򒈣\u05E1\u06B8。Ⴈ\u200D; 򒈣\u05E1\u06B8.Ⴈ\u200D; [B5, B6, C2, V6]; xn--meb44b57607c.xn--gnd699e; ; xn--meb44b57607c.xn--gnd; [B5, B6, V6] # סڸ.Ⴈ
+򒈣\u05E1\u06B8。ⴈ\u200D; 򒈣\u05E1\u06B8.ⴈ\u200D; [B5, B6, C2, V6]; xn--meb44b57607c.xn--1ug232c; ; xn--meb44b57607c.xn--zkj; [B5, B6, V6] # סڸ.ⴈ
+xn--meb44b57607c.xn--zkj; 򒈣\u05E1\u06B8.ⴈ; [B5, B6, V6]; xn--meb44b57607c.xn--zkj; ; ; # סڸ.ⴈ
+xn--meb44b57607c.xn--1ug232c; 򒈣\u05E1\u06B8.ⴈ\u200D; [B5, B6, C2, V6]; xn--meb44b57607c.xn--1ug232c; ; ; # סڸ.ⴈ
+xn--meb44b57607c.xn--gnd; 򒈣\u05E1\u06B8.Ⴈ; [B5, B6, V6]; xn--meb44b57607c.xn--gnd; ; ; # סڸ.Ⴈ
+xn--meb44b57607c.xn--gnd699e; 򒈣\u05E1\u06B8.Ⴈ\u200D; [B5, B6, C2, V6]; xn--meb44b57607c.xn--gnd699e; ; ; # סڸ.Ⴈ
+󀚶𝨱\u07E6⒈.𑗝髯\u200C; 󀚶𝨱\u07E6⒈.𑗝髯\u200C; [B1, B5, C1, V5, V6]; xn--etb477lq931a1f58e.xn--0ugx259bocxd; ; xn--etb477lq931a1f58e.xn--uj6at43v; [B1, B5, V5, V6] # 𝨱ߦ⒈.𑗝髯
+󀚶𝨱\u07E61..𑗝髯\u200C; ; [B1, B5, C1, V5, V6, X4_2]; xn--1-idd62296a1fr6e..xn--0ugx259bocxd; [B1, B5, C1, V5, V6, A4_2]; xn--1-idd62296a1fr6e..xn--uj6at43v; [B1, B5, V5, V6, A4_2] # 𝨱ߦ1..𑗝髯
+xn--1-idd62296a1fr6e..xn--uj6at43v; 󀚶𝨱\u07E61..𑗝髯; [B1, B5, V5, V6, X4_2]; xn--1-idd62296a1fr6e..xn--uj6at43v; [B1, B5, V5, V6, A4_2]; ; # 𝨱ߦ1..𑗝髯
+xn--1-idd62296a1fr6e..xn--0ugx259bocxd; 󀚶𝨱\u07E61..𑗝髯\u200C; [B1, B5, C1, V5, V6, X4_2]; xn--1-idd62296a1fr6e..xn--0ugx259bocxd; [B1, B5, C1, V5, V6, A4_2]; ; # 𝨱ߦ1..𑗝髯
+xn--etb477lq931a1f58e.xn--uj6at43v; 󀚶𝨱\u07E6⒈.𑗝髯; [B1, B5, V5, V6]; xn--etb477lq931a1f58e.xn--uj6at43v; ; ; # 𝨱ߦ⒈.𑗝髯
+xn--etb477lq931a1f58e.xn--0ugx259bocxd; 󀚶𝨱\u07E6⒈.𑗝髯\u200C; [B1, B5, C1, V5, V6]; xn--etb477lq931a1f58e.xn--0ugx259bocxd; ; ; # 𝨱ߦ⒈.𑗝髯
+𐫀.\u0689𑌀; 𐫀.\u0689𑌀; ; xn--pw9c.xn--fjb8658k; ; ; # 𐫀.ډ𑌀
+𐫀.\u0689𑌀; ; ; xn--pw9c.xn--fjb8658k; ; ; # 𐫀.ډ𑌀
+xn--pw9c.xn--fjb8658k; 𐫀.\u0689𑌀; ; xn--pw9c.xn--fjb8658k; ; ; # 𐫀.ډ𑌀
+𑋪.𐳝; 𑋪.𐳝; [B1, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+𑋪.𐳝; ; [B1, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+𑋪.𐲝; 𑋪.𐳝; [B1, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+xn--fm1d.xn--5c0d; 𑋪.𐳝; [B1, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+𑋪.𐲝; 𑋪.𐳝; [B1, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+≠膣。\u0F83; ≠膣.\u0F83; [V5]; xn--1chy468a.xn--2ed; ; ; # ≠膣.ྃ
+=\u0338膣。\u0F83; ≠膣.\u0F83; [V5]; xn--1chy468a.xn--2ed; ; ; # ≠膣.ྃ
+xn--1chy468a.xn--2ed; ≠膣.\u0F83; [V5]; xn--1chy468a.xn--2ed; ; ; # ≠膣.ྃ
+񰀎-\u077D。ß; 񰀎-\u077D.ß; [B5, B6, V6]; xn----j6c95618k.xn--zca; ; xn----j6c95618k.ss; # -ݽ.ß
+񰀎-\u077D。ß; 񰀎-\u077D.ß; [B5, B6, V6]; xn----j6c95618k.xn--zca; ; xn----j6c95618k.ss; # -ݽ.ß
+񰀎-\u077D。SS; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-\u077D。ss; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-\u077D。Ss; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+xn----j6c95618k.ss; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+xn----j6c95618k.xn--zca; 񰀎-\u077D.ß; [B5, B6, V6]; xn----j6c95618k.xn--zca; ; ; # -ݽ.ß
+񰀎-\u077D。SS; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-\u077D。ss; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-\u077D。Ss; 񰀎-\u077D.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+ς𐹠ᡚ𑄳.⾭𐹽𽐖𐫜; ς𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; # ς𐹠ᡚ𑄳.靑𐹽𐫜
+ς𐹠ᡚ𑄳.靑𐹽𽐖𐫜; ; [B5, B6, V6]; xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; # ς𐹠ᡚ𑄳.靑𐹽𐫜
+Σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; ; [B5, B6, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ς𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ; ; # ς𐹠ᡚ𑄳.靑𐹽𐫜
+Σ𐹠ᡚ𑄳.⾭𐹽𽐖𐫜; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+σ𐹠ᡚ𑄳.⾭𐹽𽐖𐫜; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+𐋷。\u200D; 𐋷.\u200D; [C2]; xn--r97c.xn--1ug; ; xn--r97c.; [] # 𐋷.
+xn--r97c.; 𐋷.; ; xn--r97c.; ; ; # 𐋷.
+𐋷.; ; ; xn--r97c.; ; ; # 𐋷.
+xn--r97c.xn--1ug; 𐋷.\u200D; [C2]; xn--r97c.xn--1ug; ; ; # 𐋷.
+𑰳𑈯。⥪; 𑰳𑈯.⥪; [V5]; xn--2g1d14o.xn--jti; ; ; # 𑰳𑈯.⥪
+xn--2g1d14o.xn--jti; 𑰳𑈯.⥪; [V5]; xn--2g1d14o.xn--jti; ; ; # 𑰳𑈯.⥪
+𑆀䁴񤧣.Ⴕ𝟜\u200C\u0348; 𑆀䁴񤧣.Ⴕ4\u200C\u0348; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h32o; ; xn--1mnx647cg3x1b.xn--4-zfb324h; [V5, V6] # 𑆀䁴.Ⴕ4͈
+𑆀䁴񤧣.Ⴕ4\u200C\u0348; ; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h32o; ; xn--1mnx647cg3x1b.xn--4-zfb324h; [V5, V6] # 𑆀䁴.Ⴕ4͈
+𑆀䁴񤧣.ⴕ4\u200C\u0348; ; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb502tlsl; ; xn--1mnx647cg3x1b.xn--4-zfb5123a; [V5, V6] # 𑆀䁴.ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb5123a; 𑆀䁴񤧣.ⴕ4\u0348; [V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb5123a; ; ; # 𑆀䁴.ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb502tlsl; 𑆀䁴񤧣.ⴕ4\u200C\u0348; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb502tlsl; ; ; # 𑆀䁴.ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb324h; 𑆀䁴񤧣.Ⴕ4\u0348; [V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h; ; ; # 𑆀䁴.Ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb324h32o; 𑆀䁴񤧣.Ⴕ4\u200C\u0348; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h32o; ; ; # 𑆀䁴.Ⴕ4͈
+𑆀䁴񤧣.ⴕ𝟜\u200C\u0348; 𑆀䁴񤧣.ⴕ4\u200C\u0348; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb502tlsl; ; xn--1mnx647cg3x1b.xn--4-zfb5123a; [V5, V6] # 𑆀䁴.ⴕ4͈
+憡?\u200CႴ.𐋮\u200D≠; ; [C1, C2, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1chz659f; [V6] # 憡?Ⴔ.𐋮≠
+憡?\u200CႴ.𐋮\u200D=\u0338; 憡?\u200CႴ.𐋮\u200D≠; [C1, C2, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1chz659f; [V6] # 憡?Ⴔ.𐋮≠
+憡?\u200Cⴔ.𐋮\u200D=\u0338; 憡?\u200Cⴔ.𐋮\u200D≠; [C1, C2, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; xn--?-fwsr13r.xn--1chz659f; [V6] # 憡?ⴔ.𐋮≠
+憡?\u200Cⴔ.𐋮\u200D≠; ; [C1, C2, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; xn--?-fwsr13r.xn--1chz659f; [V6] # 憡?ⴔ.𐋮≠
+xn--?-fwsr13r.xn--1chz659f; 憡?ⴔ.𐋮≠; [V6]; xn--?-fwsr13r.xn--1chz659f; ; ; # 憡?ⴔ.𐋮≠
+xn--?-sgn310doh5c.xn--1ug73gl146a; 憡?\u200Cⴔ.𐋮\u200D≠; [C1, C2, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; ; # 憡?ⴔ.𐋮≠
+xn--?-c1g3623d.xn--1chz659f; 憡?Ⴔ.𐋮≠; [V6]; xn--?-c1g3623d.xn--1chz659f; ; ; # 憡?Ⴔ.𐋮≠
+xn--?-c1g798iy27d.xn--1ug73gl146a; 憡?\u200CႴ.𐋮\u200D≠; [C1, C2, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
+憡?ⴔ.xn--1chz659f; 憡?ⴔ.𐋮≠; [V6]; xn--?-fwsr13r.xn--1chz659f; ; ; # 憡?ⴔ.𐋮≠
+憡?Ⴔ.XN--1CHZ659F; 憡?Ⴔ.𐋮≠; [V6]; xn--?-c1g3623d.xn--1chz659f; ; ; # 憡?Ⴔ.𐋮≠
+憡?Ⴔ.xn--1chz659f; 憡?Ⴔ.𐋮≠; [V6]; xn--?-c1g3623d.xn--1chz659f; ; ; # 憡?Ⴔ.𐋮≠
+憡?\u200Cⴔ.xn--1ug73gl146a; 憡?\u200Cⴔ.𐋮\u200D≠; [C1, C2, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; xn--?-fwsr13r.xn--1ug73gl146a; [C2, V6] # 憡?ⴔ.𐋮≠
+憡?\u200CႴ.XN--1UG73GL146A; 憡?\u200CႴ.𐋮\u200D≠; [C1, C2, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1ug73gl146a; [C2, V6] # 憡?Ⴔ.𐋮≠
+憡?\u200CႴ.xn--1ug73gl146a; 憡?\u200CႴ.𐋮\u200D≠; [C1, C2, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1ug73gl146a; [C2, V6] # 憡?Ⴔ.𐋮≠
+xn--?-c1g3623d.xn--1ug73gl146a; 憡?Ⴔ.𐋮\u200D≠; [C2, V6]; xn--?-c1g3623d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
+xn--?-fwsr13r.xn--1ug73gl146a; 憡?ⴔ.𐋮\u200D≠; [C2, V6]; xn--?-fwsr13r.xn--1ug73gl146a; ; ; # 憡?ⴔ.𐋮≠
+憡?Ⴔ.xn--1ug73gl146a; 憡?Ⴔ.𐋮\u200D≠; [C2, V6]; xn--?-c1g3623d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
+憡?ⴔ.xn--1ug73gl146a; 憡?ⴔ.𐋮\u200D≠; [C2, V6]; xn--?-fwsr13r.xn--1ug73gl146a; ; ; # 憡?ⴔ.𐋮≠
+憡?Ⴔ.XN--1UG73GL146A; 憡?Ⴔ.𐋮\u200D≠; [C2, V6]; xn--?-c1g3623d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
diff --git a/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp b/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp
new file mode 100644
index 0000000000..d163ed19bf
--- /dev/null
+++ b/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp
@@ -0,0 +1,154 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QUrl>
+#include <QtCore/QFile>
+#include <QTest>
+#include <QSet>
+#include <QByteArray>
+#include <algorithm>
+
+class tst_QUrlUts46 : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void idnaTestV2_data();
+ void idnaTestV2();
+
+private:
+ // All error codes in UTR #46 revision 31 (Unicode 15.1):
+ // A4_1, A4_2,
+ // B1, B2, B3, B4, B5, B6,
+ // C1, C2,
+ // P4,
+ // V1, V2, V3, V5, V6,
+ // X4_2
+ //
+ // NOTE: moving this inside idnaTestV2_data() results in ICE with MSVC 2019
+ static const QSet<QByteArray> fatalErrors;
+};
+
+const QSet<QByteArray> tst_QUrlUts46::fatalErrors = {
+ "A4_2", // Empty ASCII label
+};
+
+/**
+ * Replace \uXXXX escapes in test case fields.
+ */
+static QString unescapeField(const QString &field)
+{
+ static const QRegularExpression re(R"(\\u([[:xdigit:]]{4}))");
+
+ QString result;
+ qsizetype lastIdx = 0;
+
+ for (const auto &match : re.globalMatch(field)) {
+ // Add stuff before the match
+ result.append(field.mid(lastIdx, match.capturedStart() - lastIdx));
+ bool ok = false;
+ auto c = match.captured(1).toUInt(&ok, 16);
+ if (!ok) {
+ qFatal("Failed to parse a Unicode escape: %s", qPrintable(match.captured(1)));
+ }
+
+ result.append(QChar(c));
+ lastIdx = match.capturedEnd();
+ }
+
+ // Append the unescaped end
+ result.append(field.mid(lastIdx));
+
+ return result;
+}
+
+void tst_QUrlUts46::idnaTestV2_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<QString>("toUnicode");
+ QTest::addColumn<bool>("toUnicodeOk");
+ QTest::addColumn<QString>("toAsciiN");
+ QTest::addColumn<bool>("toAsciiNOk");
+ QTest::addColumn<QString>("toAsciiT");
+ QTest::addColumn<bool>("toAsciiTOk");
+
+ QFile dataFile(QFINDTESTDATA("testdata/IdnaTestV2.txt"));
+ qDebug() << "Data file:" << dataFile.fileName();
+ QVERIFY(dataFile.open(QFile::ReadOnly));
+
+ auto isToAsciiOk = [](const QByteArray &s, bool ifEmpty) {
+ if (s.isEmpty())
+ return ifEmpty;
+
+ Q_ASSERT(s.startsWith('[') && s.endsWith(']'));
+
+ const auto errors = s.sliced(1, s.size() - 2).split(',');
+ // NOTE: empty string is not in fatalErrors and it's ok
+ return std::all_of(errors.begin(), errors.end(),
+ [](auto &e) { return !fatalErrors.contains(e.trimmed()); });
+ };
+
+ for (unsigned int lineNo = 1; !dataFile.atEnd(); lineNo++) {
+ auto line = dataFile.readLine().trimmed();
+
+ int commentIdx = line.indexOf('#');
+ if (commentIdx != -1)
+ line = line.left(commentIdx).trimmed();
+ if (line.isEmpty())
+ continue;
+
+ auto fields = line.split(';');
+ Q_ASSERT(fields.size() == 7);
+
+ for (auto &field : fields)
+ field = unescapeField(field.trimmed()).toUtf8();
+
+ const QString &source = fields[0];
+ QString toUnicode = fields[1].isEmpty() ? source : fields[1];
+ bool toUnicodeOk = fields[2].isEmpty();
+ bool toUnicodeOkForAscii = isToAsciiOk(fields[2], true);
+ QString toAsciiN = fields[3].isEmpty() ? toUnicode : fields[3];
+ bool toAsciiNOk = isToAsciiOk(fields[4], toUnicodeOkForAscii);
+ QString toAsciiT = fields[5].isEmpty() ? toAsciiN : fields[5];
+ bool toAsciiTOk = isToAsciiOk(fields[6], toAsciiNOk);
+
+ QTest::addRow("line %u", lineNo) << source << toUnicode << toUnicodeOk << toAsciiN
+ << toAsciiNOk << toAsciiT << toAsciiTOk;
+ }
+}
+
+void tst_QUrlUts46::idnaTestV2()
+{
+ QFETCH(QString, source);
+ QFETCH(QString, toUnicode);
+ QFETCH(bool, toUnicodeOk);
+ QFETCH(QString, toAsciiN);
+ QFETCH(bool, toAsciiNOk);
+ QFETCH(QString, toAsciiT);
+ QFETCH(bool, toAsciiTOk);
+
+ QString toAceN = QUrl::toAce(source);
+ if (toUnicodeOk && toAsciiNOk)
+ QCOMPARE(toAceN, toAsciiN);
+ else if (toAsciiNOk)
+ QVERIFY(toAceN.isEmpty() || toAceN == toAsciiN);
+ else
+ QCOMPARE(toAceN, QString());
+
+ QString toAceT = QUrl::toAce(source, QUrl::AceTransitionalProcessing);
+ if (toUnicodeOk && toAsciiTOk)
+ QCOMPARE(toAceT, toAsciiT);
+ else if (toAsciiTOk)
+ QVERIFY(toAceT.isEmpty() || toAceT == toAsciiT);
+ else
+ QCOMPARE(toAceT, QString());
+
+ QString normalized = QUrl::fromAce(toAceN.toUtf8(), QUrl::IgnoreIDNWhitelist);
+ if (toUnicodeOk && !toAceN.isEmpty())
+ QCOMPARE(normalized, toUnicode);
+ else
+ QCOMPARE(normalized, toAceN);
+}
+
+QTEST_APPLESS_MAIN(tst_QUrlUts46)
+
+#include "tst_qurluts46.moc"
diff --git a/tests/auto/corelib/io/qzip/.gitignore b/tests/auto/corelib/io/qzip/.gitignore
new file mode 100644
index 0000000000..2d7dfbe70c
--- /dev/null
+++ b/tests/auto/corelib/io/qzip/.gitignore
@@ -0,0 +1 @@
+tst_qzip
diff --git a/tests/auto/corelib/io/qzip/CMakeLists.txt b/tests/auto/corelib/io/qzip/CMakeLists.txt
new file mode 100644
index 0000000000..df562c5e34
--- /dev/null
+++ b/tests/auto/corelib/io/qzip/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qzip Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qzip LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+file(GLOB_RECURSE test_data
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ testdata/*
+)
+
+qt_internal_add_test(tst_qzip
+ SOURCES
+ tst_qzip.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/corelib/io/qzip/testdata/symlink.zip b/tests/auto/corelib/io/qzip/testdata/symlink.zip
new file mode 100644
index 0000000000..027f96477a
--- /dev/null
+++ b/tests/auto/corelib/io/qzip/testdata/symlink.zip
Binary files differ
diff --git a/tests/auto/corelib/io/qzip/testdata/test.zip b/tests/auto/corelib/io/qzip/testdata/test.zip
new file mode 100644
index 0000000000..a57ba4e2a9
--- /dev/null
+++ b/tests/auto/corelib/io/qzip/testdata/test.zip
Binary files differ
diff --git a/tests/auto/corelib/io/qzip/tst_qzip.cpp b/tests/auto/corelib/io/qzip/tst_qzip.cpp
new file mode 100644
index 0000000000..971e8f86c3
--- /dev/null
+++ b/tests/auto/corelib/io/qzip/tst_qzip.cpp
@@ -0,0 +1,116 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QDebug>
+#include <QBuffer>
+
+#include <private/qzipwriter_p.h>
+#include <private/qzipreader_p.h>
+
+class tst_QZip : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void basicUnpack();
+ void symlinks();
+ void readTest();
+ void createArchive();
+};
+
+void tst_QZip::basicUnpack()
+{
+ QZipReader zip(QFINDTESTDATA("/testdata/test.zip"), QIODevice::ReadOnly);
+ QList<QZipReader::FileInfo> files = zip.fileInfoList();
+ QCOMPARE(files.size(), 2);
+
+ QZipReader::FileInfo fi = files.at(0);
+ QVERIFY(fi.isValid());
+ QCOMPARE(fi.filePath, QString("test"));
+ QCOMPARE(uint(fi.isDir), (uint) 1);
+ QCOMPARE(uint(fi.isFile), (uint) 0);
+ QCOMPARE(uint(fi.isSymLink), (uint) 0);
+
+ QCOMPARE(fi.permissions,QFile::Permissions( QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner
+ | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser ));
+
+ QCOMPARE(fi.lastModified, QDateTime::fromString("2005.11.11 13:08:02", "yyyy.MM.dd HH:mm:ss"));
+
+ fi = files.at(1);
+ QVERIFY(fi.isValid());
+ QCOMPARE(fi.filePath, QString("test/test.txt"));
+ QCOMPARE(uint(fi.isDir), (uint) 0);
+ QCOMPARE(uint(fi.isFile), (uint) 1);
+ QCOMPARE(uint(fi.isSymLink), (uint) 0);
+
+ QVERIFY(fi.permissions == QFile::Permissions( QFile::ReadOwner | QFile::WriteOwner
+ | QFile::ReadUser | QFile::WriteUser ));
+
+ QCOMPARE(fi.lastModified, QDateTime::fromString("2005.11.11 13:08:02", "yyyy.MM.dd HH:mm:ss"));
+
+ QCOMPARE(zip.fileData("test/test.txt"), QByteArray("content\n"));
+
+ fi = zip.entryInfoAt(-1);
+ QVERIFY(!fi.isValid());
+}
+
+void tst_QZip::symlinks()
+{
+ QZipReader zip(QFINDTESTDATA("/testdata/symlink.zip"), QIODevice::ReadOnly);
+ QList<QZipReader::FileInfo> files = zip.fileInfoList();
+ QCOMPARE(files.size(), 2);
+
+ QZipReader::FileInfo fi = files.at(0);
+ QVERIFY(fi.isValid());
+ QCOMPARE(fi.filePath, QString("symlink"));
+ QVERIFY(!fi.isDir);
+ QVERIFY(!fi.isFile);
+ QVERIFY(fi.isSymLink);
+
+ QCOMPARE(zip.fileData("symlink"), QByteArray("destination"));
+
+ fi = files.at(1);
+ QVERIFY(fi.isValid());
+ QCOMPARE(fi.filePath, QString("destination"));
+ QVERIFY(!fi.isDir);
+ QVERIFY(fi.isFile);
+ QVERIFY(!fi.isSymLink);
+}
+
+void tst_QZip::readTest()
+{
+ QZipReader zip("foobar.zip", QIODevice::ReadOnly); // non existing file.
+ QList<QZipReader::FileInfo> files = zip.fileInfoList();
+ QCOMPARE(files.size(), 0);
+ QByteArray b = zip.fileData("foobar");
+ QCOMPARE(b.size(), 0);
+}
+
+void tst_QZip::createArchive()
+{
+ QBuffer buffer;
+ QZipWriter zip(&buffer);
+ QByteArray fileContents("simple file contents\nline2\n");
+ zip.addFile("My Filename", fileContents);
+ zip.close();
+ QByteArray zipFile = buffer.buffer();
+
+ // QFile f("createArchiveTest.zip"); f.open(QIODevice::WriteOnly); f.write(zipFile); f.close();
+
+ QBuffer buffer2(&zipFile);
+ QZipReader zip2(&buffer2);
+ QList<QZipReader::FileInfo> files = zip2.fileInfoList();
+ QCOMPARE(files.size(), 1);
+ QZipReader::FileInfo file = files.at(0);
+ QCOMPARE(file.filePath, QString("My Filename"));
+ QCOMPARE(uint(file.isDir), (uint) 0);
+ QCOMPARE(uint(file.isFile), (uint) 1);
+ QCOMPARE(uint(file.isSymLink), (uint) 0);
+ QCOMPARE(file.permissions, QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser) );
+ QCOMPARE(file.size, (long long) 27);
+ QCOMPARE(zip2.fileData("My Filename"), fileContents);
+}
+
+QTEST_MAIN(tst_QZip)
+#include "tst_qzip.moc"
diff --git a/tests/auto/corelib/ipc/CMakeLists.txt b/tests/auto/corelib/ipc/CMakeLists.txt
new file mode 100644
index 0000000000..751d093788
--- /dev/null
+++ b/tests/auto/corelib/ipc/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 Intel Corporation.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT ANDROID AND NOT UIKIT)
+ if(QT_FEATURE_sharedmemory OR QT_FEATURE_systemsemaphore)
+ add_subdirectory(qnativeipckey)
+ endif()
+ if(QT_FEATURE_sharedmemory)
+ add_subdirectory(qsharedmemory)
+ endif()
+ if(QT_FEATURE_systemsemaphore)
+ add_subdirectory(qsystemsemaphore)
+ endif()
+endif()
diff --git a/tests/auto/corelib/ipc/ipctestcommon.h b/tests/auto/corelib/ipc/ipctestcommon.h
new file mode 100644
index 0000000000..25c7b8ce44
--- /dev/null
+++ b/tests/auto/corelib/ipc/ipctestcommon.h
@@ -0,0 +1,83 @@
+// Copyright (C) 2022 Intel Corporation.
+
+#include <QtTest/QTest>
+#include <QtCore/QNativeIpcKey>
+
+namespace IpcTestCommon {
+static QList<QNativeIpcKey::Type> supportedKeyTypes;
+
+template <typename IpcClass> void addGlobalTestRows()
+{
+ qDebug() << "Default key type is" << QNativeIpcKey::DefaultTypeForOs
+ << "and legacy key type is" << QNativeIpcKey::legacyDefaultTypeForOs();
+
+#if defined(Q_OS_FREEBSD) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
+ // only enforce that IPC works on the platforms above; other platforms may
+ // have no working backends (notably, Android)
+ QVERIFY(IpcClass::isKeyTypeSupported(QNativeIpcKey::DefaultTypeForOs));
+ QVERIFY(IpcClass::isKeyTypeSupported(QNativeIpcKey::legacyDefaultTypeForOs()));
+#endif
+
+ auto addRowIfSupported = [](const char *name, QNativeIpcKey::Type type) {
+ if (IpcClass::isKeyTypeSupported(type)) {
+ supportedKeyTypes << type;
+ QTest::newRow(name) << type;
+ }
+ };
+
+ QTest::addColumn<QNativeIpcKey::Type>("keyType");
+
+ addRowIfSupported("Windows", QNativeIpcKey::Type::Windows);
+ addRowIfSupported("POSIX", QNativeIpcKey::Type::PosixRealtime);
+ addRowIfSupported("SystemV-Q", QNativeIpcKey::Type::SystemV);
+ addRowIfSupported("SystemV-T", QNativeIpcKey::Type('T'));
+
+ if (supportedKeyTypes.isEmpty())
+ QSKIP("System reports no supported IPC types.");
+}
+
+// rotate through the supported types and find another
+inline QNativeIpcKey::Type nextKeyType(QNativeIpcKey::Type type)
+{
+ qsizetype idx = supportedKeyTypes.indexOf(type);
+ Q_ASSERT(idx >= 0);
+
+ ++idx;
+ if (idx == supportedKeyTypes.size())
+ idx = 0;
+ return supportedKeyTypes.at(idx);
+}
+} // namespace IpcTestCommon
+
+QT_BEGIN_NAMESPACE
+namespace QTest {
+template<> inline char *toString(const QNativeIpcKey::Type &type)
+{
+ switch (type) {
+ case QNativeIpcKey::Type::SystemV: return qstrdup("SystemV");
+ case QNativeIpcKey::Type::PosixRealtime: return qstrdup("PosixRealTime");
+ case QNativeIpcKey::Type::Windows: return qstrdup("Windows");
+ }
+ if (type == QNativeIpcKey::Type{})
+ return qstrdup("Invalid");
+
+ char buf[32];
+ qsnprintf(buf, sizeof(buf), "%u", unsigned(type));
+ return qstrdup(buf);
+}
+
+template<> inline char *toString(const QNativeIpcKey &key)
+{
+ if (!key.isValid())
+ return qstrdup("<invalid>");
+
+ const char *type = toString(key.type());
+ const char *text = toString(key.nativeKey());
+ char buf[256];
+ qsnprintf(buf, sizeof(buf), "QNativeIpcKey(%s, %s)", text, type);
+ delete[] type;
+ delete[] text;
+ return qstrdup(buf);
+}
+} // namespace QTest
+QT_END_NAMESPACE
diff --git a/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt b/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt
new file mode 100644
index 0000000000..0cc6a7b18b
--- /dev/null
+++ b/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 Intel Corporation.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qnativeipckey LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qnativeipckey
+ SOURCES
+ tst_qnativeipckey.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp b/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp
new file mode 100644
index 0000000000..a01a108591
--- /dev/null
+++ b/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp
@@ -0,0 +1,442 @@
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QNativeIpcKey>
+#include <QtTest/QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+
+#include "../ipctestcommon.h"
+
+#if QT_CONFIG(sharedmemory)
+# include <qsharedmemory.h>
+#endif
+#if QT_CONFIG(systemsemaphore)
+# include <qsystemsemaphore.h>
+#endif
+
+#if QT_CONFIG(sharedmemory)
+static const auto makeLegacyKey = QSharedMemory::legacyNativeKey;
+#else
+static const auto makeLegacyKey = QSystemSemaphore::legacyNativeKey;
+#endif
+
+using namespace Qt::StringLiterals;
+
+class tst_QNativeIpcKey : public QObject
+{
+ Q_OBJECT
+private slots:
+ void compareCompiles();
+ void defaultTypes();
+ void construct();
+ void getSetCheck();
+ void equality();
+ void hash();
+ void swap();
+ void toString_data();
+ void toString();
+ void fromString_data();
+ void fromString();
+ void legacyKeys_data();
+ void legacyKeys();
+};
+
+void tst_QNativeIpcKey::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QNativeIpcKey>();
+}
+
+void tst_QNativeIpcKey::defaultTypes()
+{
+ auto isKnown = [](QNativeIpcKey::Type t) {
+ switch (t) {
+ case QNativeIpcKey::Type::SystemV:
+ case QNativeIpcKey::Type::PosixRealtime:
+ case QNativeIpcKey::Type::Windows:
+ return true;
+ }
+ return false;
+ };
+
+ // because the letter Q looked nice in Håvard's Emacs font back in the 1990s
+ static_assert(qToUnderlying(QNativeIpcKey::Type::SystemV) == 'Q',
+ "QNativeIpcKey::Type::SystemV must be equal to the letter Q");
+
+ auto type = QNativeIpcKey::DefaultTypeForOs;
+ auto legacy = QNativeIpcKey::legacyDefaultTypeForOs();
+ QVERIFY(isKnown(type));
+ QVERIFY(isKnown(legacy));
+
+#ifdef Q_OS_WIN
+ QCOMPARE(type, QNativeIpcKey::Type::Windows);
+#else
+ QCOMPARE(type, QNativeIpcKey::Type::PosixRealtime);
+#endif
+
+#if defined(Q_OS_WIN)
+ QCOMPARE(legacy, QNativeIpcKey::Type::Windows);
+#elif defined(QT_POSIX_IPC)
+ QCOMPARE(legacy, QNativeIpcKey::Type::PosixRealtime);
+#elif !defined(Q_OS_DARWIN)
+ QCOMPARE(legacy, QNativeIpcKey::Type::SystemV);
+#endif
+}
+
+void tst_QNativeIpcKey::construct()
+{
+ {
+ QNativeIpcKey invalid(QNativeIpcKey::Type{});
+ QVERIFY(!invalid.isValid());
+ }
+
+ {
+ QNativeIpcKey key;
+ QVERIFY(key.nativeKey().isEmpty());
+ QVERIFY(key.isEmpty());
+ QVERIFY(key.isValid());
+ QCOMPARE(key.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ QNativeIpcKey copy(key);
+ QVERIFY(copy.nativeKey().isEmpty());
+ QVERIFY(copy.isEmpty());
+ QVERIFY(copy.isValid());
+ QCOMPARE(copy.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ QNativeIpcKey moved(std::move(copy));
+ QVERIFY(moved.nativeKey().isEmpty());
+ QVERIFY(moved.isEmpty());
+ QVERIFY(moved.isValid());
+ QCOMPARE(moved.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ key.setType({});
+ key.setNativeKey("something else");
+ key = std::move(moved);
+ QVERIFY(key.nativeKey().isEmpty());
+ QVERIFY(key.isEmpty());
+ QVERIFY(key.isValid());
+ QCOMPARE(key.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ copy.setType({});
+ copy.setNativeKey("something else");
+ copy = key;
+ QVERIFY(copy.nativeKey().isEmpty());
+ QVERIFY(copy.isEmpty());
+ QVERIFY(copy.isValid());
+ QCOMPARE(copy.type(), QNativeIpcKey::DefaultTypeForOs);
+ }
+
+ {
+ QNativeIpcKey key("dummy");
+ QCOMPARE(key.nativeKey(), "dummy");
+ QVERIFY(!key.isEmpty());
+ QVERIFY(key.isValid());
+ QCOMPARE(key.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ QNativeIpcKey copy(key);
+ QCOMPARE(key.nativeKey(), "dummy");
+ QCOMPARE(copy.nativeKey(), "dummy");
+ QVERIFY(!copy.isEmpty());
+ QVERIFY(copy.isValid());
+ QCOMPARE(copy.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ QNativeIpcKey moved(std::move(copy));
+ QCOMPARE(key.nativeKey(), "dummy");
+ QCOMPARE(moved.nativeKey(), "dummy");
+ QVERIFY(!moved.isEmpty());
+ QVERIFY(moved.isValid());
+ QCOMPARE(moved.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ key.setType({});
+ key.setNativeKey("something else");
+ key = std::move(moved);
+ QCOMPARE(key.nativeKey(), "dummy");
+ QVERIFY(!key.isEmpty());
+ QVERIFY(key.isValid());
+ QCOMPARE(key.type(), QNativeIpcKey::DefaultTypeForOs);
+
+ copy.setType({});
+ copy.setNativeKey("something else");
+ copy = key;
+ QCOMPARE(key.nativeKey(), "dummy");
+ QCOMPARE(copy.nativeKey(), "dummy");
+ QVERIFY(!copy.isEmpty());
+ QVERIFY(copy.isValid());
+ QCOMPARE(copy.type(), QNativeIpcKey::DefaultTypeForOs);
+ }
+}
+
+void tst_QNativeIpcKey::getSetCheck()
+{
+ QNativeIpcKey key("key1", QNativeIpcKey::Type::Windows);
+ QVERIFY(key.isValid());
+ QVERIFY(!key.isEmpty());
+ QCOMPARE(key.nativeKey(), "key1");
+ QCOMPARE(key.type(), QNativeIpcKey::Type::Windows);
+
+ key.setType(QNativeIpcKey::Type::SystemV);
+ QVERIFY(key.isValid());
+ QVERIFY(!key.isEmpty());
+ QCOMPARE(key.type(), QNativeIpcKey::Type::SystemV);
+
+ key.setNativeKey("key2");
+ QCOMPARE(key.nativeKey(), "key2");
+}
+
+void tst_QNativeIpcKey::equality()
+{
+ QNativeIpcKey key1, key2;
+ QCOMPARE(key1, key2);
+ QVERIFY(!(key1 != key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, true);
+
+ key1.setNativeKey("key1");
+ QCOMPARE_NE(key1, key2);
+ QVERIFY(!(key1 == key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, false);
+
+ key2.setType({});
+ QCOMPARE_NE(key1, key2);
+ QVERIFY(!(key1 == key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, false);
+
+ key2.setNativeKey(key1.nativeKey());
+ QCOMPARE_NE(key1, key2);
+ QVERIFY(!(key1 == key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, false);
+
+ key2.setType(QNativeIpcKey::DefaultTypeForOs);
+ QCOMPARE(key1, key2);
+ QVERIFY(!(key1 != key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, true);
+
+ key1 = makeLegacyKey("key1", QNativeIpcKey::DefaultTypeForOs);
+ QCOMPARE_NE(key1, key2);
+ QVERIFY(!(key1 == key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, false);
+
+ key2 = key1;
+ QCOMPARE(key1, key2);
+ QVERIFY(!(key1 != key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, true);
+
+ // just setting the native key won't make them equal again!
+ key2.setNativeKey(key1.nativeKey());
+ QCOMPARE_NE(key1, key2);
+ QVERIFY(!(key1 == key2));
+ QT_TEST_EQUALITY_OPS(key1, key2, false);
+}
+
+void tst_QNativeIpcKey::hash()
+{
+ QNativeIpcKey key1("key1", QNativeIpcKey::DefaultTypeForOs);
+ QNativeIpcKey key2(key1);
+ QCOMPARE_EQ(qHash(key1), qHash(key2));
+ QCOMPARE_EQ(qHash(key1, 123), qHash(key2, 123));
+}
+
+void tst_QNativeIpcKey::swap()
+{
+ QNativeIpcKey key1("key1", QNativeIpcKey::Type::PosixRealtime);
+ QNativeIpcKey key2("key2", QNativeIpcKey::Type::Windows);
+
+ // self-swaps
+ key1.swap(key1);
+ key2.swap(key2);
+ QCOMPARE(key1.nativeKey(), "key1");
+ QCOMPARE(key1.type(), QNativeIpcKey::Type::PosixRealtime);
+ QCOMPARE(key2.nativeKey(), "key2");
+ QCOMPARE(key2.type(), QNativeIpcKey::Type::Windows);
+
+ key1.swap(key2);
+ QCOMPARE(key2.nativeKey(), "key1");
+ QCOMPARE(key2.type(), QNativeIpcKey::Type::PosixRealtime);
+ QCOMPARE(key1.nativeKey(), "key2");
+ QCOMPARE(key1.type(), QNativeIpcKey::Type::Windows);
+
+ key1.swap(key2);
+ QCOMPARE(key1.nativeKey(), "key1");
+ QCOMPARE(key1.type(), QNativeIpcKey::Type::PosixRealtime);
+ QCOMPARE(key2.nativeKey(), "key2");
+ QCOMPARE(key2.type(), QNativeIpcKey::Type::Windows);
+
+ key1 = makeLegacyKey("key1", QNativeIpcKey::DefaultTypeForOs);
+ QCOMPARE(key1.type(), QNativeIpcKey::DefaultTypeForOs);
+ key1.swap(key2);
+ QCOMPARE(key1.type(), QNativeIpcKey::Type::Windows);
+ QCOMPARE(key2.type(), QNativeIpcKey::DefaultTypeForOs);
+}
+
+void tst_QNativeIpcKey::toString_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QNativeIpcKey>("key");
+
+ QTest::newRow("invalid") << QString() << QNativeIpcKey(QNativeIpcKey::Type(0));
+
+ auto addRow = [](const char *prefix, QNativeIpcKey::Type type) {
+ auto add = [=](const char *name, QLatin1StringView key, QLatin1StringView encoded = {}) {
+ if (encoded.isNull())
+ encoded = key;
+ QTest::addRow("%s-%s", prefix, name)
+ << prefix + u":"_s + encoded << QNativeIpcKey(key, type);
+ };
+ add("empty", {});
+ add("text", "foobar"_L1);
+ add("pathlike", "/sometext"_L1);
+ add("objectlike", "Global\\sometext"_L1);
+ add("colon-slash", ":/"_L1);
+ add("slash-colon", "/:"_L1);
+ add("percent", "%"_L1, "%25"_L1);
+ add("question-hash", "?#"_L1, "%3F%23"_L1);
+ add("hash-question", "#?"_L1, "%23%3F"_L1);
+ add("double-slash", "//"_L1, "/%2F"_L1);
+ add("triple-slash", "///"_L1, "/%2F/"_L1);
+ add("non-ascii", "\xe9"_L1);
+ add("non-utf8", "\xa0\xff"_L1);
+ QTest::addRow("%s-%s", prefix, "non-latin1")
+ << prefix + u":\u0100.\u2000.\U00010000"_s
+ << QNativeIpcKey(u"\u0100.\u2000.\U00010000"_s, type);
+ };
+ addRow("systemv", QNativeIpcKey::Type::SystemV);
+ addRow("posix", QNativeIpcKey::Type::PosixRealtime);
+ addRow("windows", QNativeIpcKey::Type::Windows);
+
+ addRow("systemv-1", QNativeIpcKey::Type(1));
+ addRow("systemv-84", QNativeIpcKey::Type('T'));
+ addRow("systemv-255", QNativeIpcKey::Type(0xff));
+}
+
+void tst_QNativeIpcKey::toString()
+{
+ QFETCH(QString, string);
+ QFETCH(QNativeIpcKey, key);
+
+ QCOMPARE(key.toString(), string);
+}
+
+void tst_QNativeIpcKey::fromString_data()
+{
+ toString_data();
+ QTest::addRow("systemv-alias") << "systemv-81:" << QNativeIpcKey(QNativeIpcKey::Type::SystemV);
+ QTest::addRow("systemv-zeropadded") << "systemv-009:" << QNativeIpcKey(QNativeIpcKey::Type(9));
+
+ QNativeIpcKey valid("/foo", QNativeIpcKey::Type::PosixRealtime);
+ QNativeIpcKey invalid(QNativeIpcKey::Type(0));
+
+ // percent-decoding
+ QTest::addRow("percent-encoded") << "posix:%2f%66o%6f" << valid;
+ QTest::addRow("percent-utf8")
+ << "posix:%C4%80.%E2%80%80.%F0%90%80%80"
+ << QNativeIpcKey(u"\u0100.\u2000.\U00010000"_s, QNativeIpcKey::Type::PosixRealtime);
+
+ // fragments are ignored
+ QTest::addRow("with-fragment") << "posix:/foo#bar" << valid;
+ QTest::addRow("with-fragmentquery") << "posix:/foo#bar?baz" << valid;
+
+ // but unknown query items are not
+ QTest::addRow("with-query") << "posix:/foo?bar" << invalid;
+ QTest::addRow("with-queryfragment") << "posix:/foo?bar#baz" << invalid;
+
+ // add some ones that won't parse well
+ QTest::addRow("positive-number") << "81" << invalid;
+ QTest::addRow("negative-number") << "-81" << invalid;
+ QTest::addRow("invalidprefix") << "invalidprefix:" << invalid;
+ QTest::addRow("systemv-nodash") << "systemv255" << invalid;
+ QTest::addRow("systemv-doubledash") << "systemv--255:" << invalid;
+ QTest::addRow("systemv-plus") << "systemv+255" << invalid;
+ QTest::addRow("systemv-hex") << "systemv-0x01:" << invalid;
+ QTest::addRow("systemv-too-low") << "systemv-0:" << invalid;
+ QTest::addRow("systemv-too-high") << "systemv-256" << invalid;
+ QTest::addRow("systemv-overflow-15bit") << "systemv-32769:" << invalid;
+ QTest::addRow("systemv-overflow-16bit") << "systemv-65537:" << invalid;
+ QTest::addRow("systemv-overflow-31bit") << "systemv-2147483649:" << invalid;
+ QTest::addRow("systemv-overflow-32bit") << "systemv-4294967297:" << invalid;
+
+ auto addRows = [=](const char *name) {
+ QTest::addRow("%s-nocolon", name) << name << invalid;
+ QTest::addRow("%s-junk", name) << name + u"junk"_s << invalid;
+ QTest::addRow("junk-%s-colon", name) << u"junk:"_s + name + u':' << invalid;
+ };
+ addRows("systemv");
+ addRows("posix");
+ addRows("windows");
+ addRows("systemv-1");
+ addRows("systemv-255");
+}
+
+void tst_QNativeIpcKey::fromString()
+{
+ QFETCH(QString, string);
+ QFETCH(QNativeIpcKey, key);
+
+ QCOMPARE(QNativeIpcKey::fromString(string), key);
+}
+
+void tst_QNativeIpcKey::legacyKeys_data()
+{
+ QTest::addColumn<QNativeIpcKey::Type>("type");
+ QTest::addColumn<QString>("legacyKey");
+ auto addRows = [](QNativeIpcKey::Type type) {
+ const char *label = "<unknown-type>";
+ switch (type) {
+ case QNativeIpcKey::Type::SystemV:
+ label = "systemv";
+ break;
+ case QNativeIpcKey::Type::PosixRealtime:
+ label = "posix";
+ break;
+ case QNativeIpcKey::Type::Windows:
+ label = "windows";
+ break;
+ }
+ auto add = [=](const char *name, const QString &legacyKey) {
+ QTest::addRow("%s-%s", label, name) << type << legacyKey;
+ };
+ add("empty", {});
+ add("text", "foobar"_L1);
+ add("pathlike", "/sometext"_L1);
+ add("objectlike", "Global\\sometext"_L1);
+ add("colon-slash", ":/"_L1);
+ add("slash-colon", "/:"_L1);
+ add("percent", "%"_L1);
+ add("question-hash", "?#"_L1);
+ add("hash-question", "#?"_L1);
+ add("double-slash", "//"_L1);
+ add("triple-slash", "///"_L1);
+ add("non-ascii", "\xe9"_L1);
+ add("non-utf8", "\xa0\xff"_L1);
+ add("non-latin1", u":\u0100.\u2000.\U00010000"_s);
+ };
+
+ addRows(QNativeIpcKey::DefaultTypeForOs);
+ if (auto type = QNativeIpcKey::legacyDefaultTypeForOs();
+ type != QNativeIpcKey::DefaultTypeForOs)
+ addRows(type);
+}
+
+void tst_QNativeIpcKey::legacyKeys()
+{
+ QFETCH(QNativeIpcKey::Type, type);
+ QFETCH(QString, legacyKey);
+
+ QNativeIpcKey key = makeLegacyKey(legacyKey, type);
+ QCOMPARE(key.type(), type);
+
+ QString string = key.toString();
+ QNativeIpcKey key2 = QNativeIpcKey::fromString(string);
+ QCOMPARE(key2, key);
+ QT_TEST_EQUALITY_OPS(key, key2, true);
+
+ if (!legacyKey.isEmpty()) {
+ // confirm it shows up in the encoded form
+ Q_ASSERT(!legacyKey.contains(u'&')); // needs extra encoding
+ QUrl u;
+ u.setQuery("legacyKey="_L1 + legacyKey, QUrl::DecodedMode);
+ QString encodedLegacyKey = u.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority
+ | QUrl::DecodeReserved);
+ QVERIFY2(string.contains(encodedLegacyKey), qPrintable(string));
+ }
+}
+
+QTEST_MAIN(tst_QNativeIpcKey)
+#include "tst_qnativeipckey.moc"
diff --git a/tests/auto/corelib/ipc/qsharedmemory/CMakeLists.txt b/tests/auto/corelib/ipc/qsharedmemory/CMakeLists.txt
new file mode 100644
index 0000000000..e49c8d7828
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsharedmemory/CMakeLists.txt
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsharedmemory LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsharedmemory
+ SOURCES
+ tst_qsharedmemory.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qsharedmemory CONDITION LINUX
+ LIBRARIES
+ rt
+)
+add_subdirectory(producerconsumer)
+if(QT_FEATURE_process)
+ add_dependencies(tst_qsharedmemory producerconsumer_helper)
+endif()
diff --git a/tests/auto/corelib/ipc/qsharedmemory/producerconsumer/CMakeLists.txt b/tests/auto/corelib/ipc/qsharedmemory/producerconsumer/CMakeLists.txt
new file mode 100644
index 0000000000..bd039837e3
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsharedmemory/producerconsumer/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## producerconsumer_helper Binary:
+#####################################################################
+
+qt_internal_add_test_helper(producerconsumer_helper
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Test
+)
diff --git a/tests/auto/corelib/ipc/qsharedmemory/producerconsumer/main.cpp b/tests/auto/corelib/ipc/qsharedmemory/producerconsumer/main.cpp
new file mode 100644
index 0000000000..102d505485
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsharedmemory/producerconsumer/main.cpp
@@ -0,0 +1,174 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QSharedMemory>
+#include <QStringList>
+#include <QDebug>
+#include <QTest>
+#include <stdio.h>
+
+void set(QSharedMemory &sm, int pos, char value)
+{
+ ((char*)sm.data())[pos] = value;
+}
+
+QChar get(QSharedMemory &sm, int i)
+{
+ return QChar::fromLatin1(((char*)sm.data())[i]);
+}
+
+int readonly_segfault(const QNativeIpcKey &key)
+{
+ QSharedMemory sharedMemory(key);
+ sharedMemory.create(1024, QSharedMemory::ReadOnly);
+ sharedMemory.lock();
+ set(sharedMemory, 0, 'a');
+ sharedMemory.unlock();
+ return EXIT_SUCCESS;
+}
+
+int producer(const QNativeIpcKey &key)
+{
+ QSharedMemory producer(key);
+
+ int size = 1024;
+ if (!producer.create(size)) {
+ if (producer.error() == QSharedMemory::AlreadyExists) {
+ if (!producer.attach()) {
+ qWarning() << "Could not attach to" << producer.key();
+ return EXIT_FAILURE;
+ }
+ } else {
+ qWarning() << "Could not create" << producer.key();
+ return EXIT_FAILURE;
+ }
+ }
+ // tell parent we're ready
+ //qDebug("producer created and attached");
+ puts("");
+ fflush(stdout);
+
+ if (!producer.lock()) {
+ qWarning() << "Could not lock" << producer.key();
+ return EXIT_FAILURE;
+ }
+ set(producer, 0, 'Q');
+ if (!producer.unlock()) {
+ qWarning() << "Could not lock" << producer.key();
+ return EXIT_FAILURE;
+ }
+
+ int i = 0;
+ while (i < 5) {
+ if (!producer.lock()) {
+ qWarning() << "Could not lock" << producer.key();
+ return EXIT_FAILURE;
+ }
+ if (get(producer, 0) == 'Q') {
+ if (!producer.unlock()) {
+ qWarning() << "Could not unlock" << producer.key();
+ return EXIT_FAILURE;
+ }
+ QTest::qSleep(1);
+ continue;
+ }
+ //qDebug() << "producer:" << i);
+ ++i;
+ set(producer, 0, 'Q');
+ if (!producer.unlock()) {
+ qWarning() << "Could not unlock" << producer.key();
+ return EXIT_FAILURE;
+ }
+ QTest::qSleep(1);
+ }
+ if (!producer.lock()) {
+ qWarning() << "Could not lock" << producer.key();
+ return EXIT_FAILURE;
+ }
+ set(producer, 0, 'E');
+ if (!producer.unlock()) {
+ qWarning() << "Could not unlock" << producer.key();
+ return EXIT_FAILURE;
+ }
+
+ //qDebug("producer done");
+
+ // Sleep for a bit to let all consumers exit
+ getchar();
+ return EXIT_SUCCESS;
+}
+
+int consumer(const QNativeIpcKey &key)
+{
+ QSharedMemory consumer(key);
+
+ //qDebug("consumer starting");
+ int tries = 0;
+ while (!consumer.attach()) {
+ if (tries == 5000) {
+ qWarning() << "consumer exiting, waiting too long";
+ return EXIT_FAILURE;
+ }
+ ++tries;
+ QTest::qSleep(1);
+ }
+ //qDebug("consumer attached");
+
+
+ int i = 0;
+ while (true) {
+ if (!consumer.lock()) {
+ qWarning() << "Could not lock" << consumer.key();
+ return EXIT_FAILURE;
+ }
+ if (get(consumer, 0) == 'Q') {
+ set(consumer, 0, ++i);
+ //qDebug() << "consumer sets" << i;
+ }
+ if (get(consumer, 0) == 'E') {
+ if (!consumer.unlock()) {
+ qWarning() << "Could not unlock" << consumer.key();
+ return EXIT_FAILURE;
+ }
+ break;
+ }
+ if (!consumer.unlock()) {
+ qWarning() << "Could not unlock" << consumer.key();
+ return EXIT_FAILURE;
+ }
+ QTest::qSleep(10);
+ }
+
+ //qDebug("consumer detaching");
+ if (!consumer.detach()) {
+ qWarning() << "Could not detach" << consumer.key();
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QStringList arguments = app.arguments();
+ if (app.arguments().size() != 3) {
+ fprintf(stderr, "Usage: %s <mode> <key>\n"
+ "<mode> is one of: readonly_segfault, producer, consumer\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+ QString function = arguments.at(1);
+ QNativeIpcKey key = QNativeIpcKey::fromString(arguments.at(2));
+
+ if (function == QLatin1String("readonly_segfault"))
+ return readonly_segfault(key);
+ else if (function == QLatin1String("producer"))
+ return producer(key);
+ else if (function == QLatin1String("consumer"))
+ return consumer(key);
+ else
+ qWarning() << "Unknown function" << arguments.at(1);
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/auto/corelib/ipc/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/corelib/ipc/qsharedmemory/tst_qsharedmemory.cpp
new file mode 100644
index 0000000000..73578a3bab
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsharedmemory/tst_qsharedmemory.cpp
@@ -0,0 +1,966 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QDebug>
+#include <QFile>
+#if QT_CONFIG(process)
+# include <QProcess>
+#endif
+#include <QSharedMemory>
+#include <QTest>
+#include <QThread>
+#include <QElapsedTimer>
+
+#include <errno.h>
+#include <stdio.h>
+#ifdef Q_OS_UNIX
+# include <unistd.h>
+#endif
+
+#include "private/qtcore-config_p.h"
+#include "../ipctestcommon.h"
+
+#define EXISTING_SIZE 1024
+
+Q_DECLARE_METATYPE(QSharedMemory::SharedMemoryError)
+Q_DECLARE_METATYPE(QSharedMemory::AccessMode)
+
+using namespace Qt::StringLiterals;
+
+class tst_QSharedMemory : public QObject
+{
+ Q_OBJECT
+
+public Q_SLOTS:
+ void initTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ // basics
+ void constructor();
+ void nativeKey_data();
+ void nativeKey();
+ void legacyKey_data() { nativeKey_data(); }
+ void legacyKey();
+ void create_data();
+ void create();
+ void attach_data();
+ void attach();
+ void changeKeyType_data() { attach_data(); }
+ void changeKeyType();
+ void lock();
+
+ // custom edge cases
+ void removeWhileAttached();
+ void emptyMemory();
+ void readOnly();
+ void attachBeforeCreate_data();
+ void attachBeforeCreate();
+
+ // basics all together
+ void simpleProducerConsumer_data();
+ void simpleProducerConsumer();
+ void simpleDoubleProducerConsumer();
+
+ // with threads
+ void simpleThreadedProducerConsumer_data();
+ void simpleThreadedProducerConsumer();
+
+ // with processes
+ void simpleProcessProducerConsumer_data();
+ void simpleProcessProducerConsumer();
+
+ // extreme cases
+ void useTooMuchMemory();
+ void attachTooMuch();
+
+ // unique keys
+ void uniqueKey_data();
+ void uniqueKey();
+
+ // legacy
+ void createWithSameKey();
+
+protected:
+ void remove(const QNativeIpcKey &key);
+
+ QString mangleKey(QStringView key)
+ {
+ if (key.isEmpty())
+ return key.toString();
+ return u"tstshm_%1-%2_%3"_s.arg(QCoreApplication::applicationPid())
+ .arg(seq).arg(key);
+ }
+
+ QNativeIpcKey platformSafeKey(const QString &key)
+ {
+ QFETCH_GLOBAL(QNativeIpcKey::Type, keyType);
+ return QSharedMemory::platformSafeKey(mangleKey(key), keyType);
+ }
+
+ QNativeIpcKey rememberKey(const QString &key)
+ {
+ QNativeIpcKey ipcKey = platformSafeKey(key);
+ if (!keys.contains(ipcKey)) {
+ keys.append(ipcKey);
+ remove(ipcKey);
+ }
+ return ipcKey;
+ }
+
+ QList<QNativeIpcKey> keys;
+ QList<QSharedMemory*> jail;
+ QSharedMemory *existingSharedMemory = nullptr;
+ int seq = 0;
+
+private:
+ const QString m_helperBinary = "./producerconsumer_helper";
+};
+
+void tst_QSharedMemory::initTestCase()
+{
+ IpcTestCommon::addGlobalTestRows<QSharedMemory>();
+}
+
+void tst_QSharedMemory::init()
+{
+ QNativeIpcKey key = platformSafeKey("existing");
+ existingSharedMemory = new QSharedMemory(key);
+ if (!existingSharedMemory->create(EXISTING_SIZE)) {
+ QCOMPARE(existingSharedMemory->error(), QSharedMemory::AlreadyExists);
+ }
+ keys.append(key);
+}
+
+void tst_QSharedMemory::cleanup()
+{
+ delete existingSharedMemory;
+ qDeleteAll(jail.begin(), jail.end());
+ jail.clear();
+
+ for (int i = 0; i < keys.size(); ++i) {
+ QSharedMemory sm(keys.at(i));
+ if (!sm.create(1024)) {
+ //if (sm.error() != QSharedMemory::KeyError)
+ // qWarning() << "test cleanup: remove failed:" << keys.at(i) << sm.error() << sm.errorString();
+ sm.attach();
+ sm.detach();
+ }
+ remove(keys.at(i));
+ }
+ ++seq;
+}
+
+#if QT_CONFIG(posix_shm)
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+#if QT_CONFIG(sysv_shm)
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
+void tst_QSharedMemory::remove(const QNativeIpcKey &key)
+{
+ // On Unix, the shared memory might exist from a previously failed test
+ // or segfault, remove it it does
+ if (key.isEmpty())
+ return;
+
+ switch (key.type()) {
+ case QNativeIpcKey::Type::Windows:
+ return;
+
+ case QNativeIpcKey::Type::PosixRealtime:
+#if QT_CONFIG(posix_shm)
+ if (shm_unlink(QFile::encodeName(key.nativeKey()).constData()) == -1) {
+ if (errno != ENOENT) {
+ perror("shm_unlink");
+ return;
+ }
+ }
+#endif
+ return;
+
+ case QNativeIpcKey::Type::SystemV:
+ break;
+ }
+
+#if QT_CONFIG(sysv_shm)
+ // ftok requires that an actual file exists somewhere
+ QString fileName = key.nativeKey();
+ if (!QFile::exists(fileName)) {
+ //qDebug() << "exits failed";
+ return;
+ }
+
+ int unix_key = ftok(fileName.toLatin1().constData(), int(key.type()));
+ if (-1 == unix_key) {
+ perror("ftok");
+ return;
+ }
+
+ int id = shmget(unix_key, 0, 0600);
+ if (-1 == id) {
+ if (errno != ENOENT)
+ perror("shmget");
+ return;
+ }
+
+ struct shmid_ds shmid_ds;
+ if (-1 == shmctl(id, IPC_RMID, &shmid_ds)) {
+ perror("shmctl");
+ return;
+ }
+
+ QFile::remove(fileName);
+#endif // Q_OS_WIN
+}
+
+/*!
+ Tests the default values
+ */
+void tst_QSharedMemory::constructor()
+{
+ QSharedMemory sm;
+ QVERIFY(!sm.isAttached());
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.nativeKey(), QString());
+ QCOMPARE(sm.nativeIpcKey(), QNativeIpcKey());
+ QCOMPARE(sm.size(), 0);
+ QCOMPARE(sm.error(), QSharedMemory::NoError);
+ QCOMPARE(sm.errorString(), QString());
+
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+ QCOMPARE(sm.key(), QString());
+ QT_WARNING_POP
+}
+
+void tst_QSharedMemory::nativeKey_data()
+{
+ QTest::addColumn<QString>("constructorKey");
+ QTest::addColumn<QString>("setKey");
+ QTest::addColumn<QString>("setNativeKey"); // only used in the legacyKey test
+
+ QTest::newRow("null, null, null") << QString() << QString() << QString();
+ QTest::newRow("one, null, null") << QString("one") << QString() << QString();
+ QTest::newRow("null, one, null") << QString() << QString("one") << QString();
+ QTest::newRow("null, null, one") << QString() << QString() << QString("one");
+ QTest::newRow("one, two, null") << QString("one") << QString("two") << QString();
+ QTest::newRow("one, null, two") << QString("one") << QString() << QString("two");
+ QTest::newRow("null, one, two") << QString() << QString("one") << QString("two");
+ QTest::newRow("one, two, three") << QString("one") << QString("two") << QString("three");
+ QTest::newRow("invalid") << QString("o/e") << QString("t/o") << QString("|x");
+}
+
+/*!
+ Basic key testing
+ */
+void tst_QSharedMemory::nativeKey()
+{
+ QFETCH(QString, constructorKey);
+ QFETCH(QString, setKey);
+ QFETCH(QString, setNativeKey);
+
+ QNativeIpcKey constructorIpcKey = platformSafeKey(constructorKey);
+ QNativeIpcKey setIpcKey = platformSafeKey(setKey);
+
+ QSharedMemory sm(constructorIpcKey);
+ QCOMPARE(sm.nativeIpcKey(), constructorIpcKey);
+ QCOMPARE(sm.nativeKey(), constructorIpcKey.nativeKey());
+ sm.setNativeKey(setIpcKey);
+ QCOMPARE(sm.nativeIpcKey(), setIpcKey);
+ QCOMPARE(sm.nativeKey(), setIpcKey.nativeKey());
+
+ QCOMPARE(sm.isAttached(), false);
+
+ QCOMPARE(sm.error(), QSharedMemory::NoError);
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+
+ QCOMPARE(sm.detach(), false);
+
+ // change the key type
+ QNativeIpcKey::Type nextKeyType = IpcTestCommon::nextKeyType(setIpcKey.type());
+ if (nextKeyType != setIpcKey.type()) {
+ QNativeIpcKey setIpcKey2 = QSharedMemory::platformSafeKey(setKey, nextKeyType);
+ sm.setNativeKey(setIpcKey2);
+
+ QCOMPARE(sm.nativeIpcKey(), setIpcKey2);
+ QCOMPARE(sm.nativeKey(), setIpcKey2.nativeKey());
+
+ QCOMPARE(sm.isAttached(), false);
+
+ QCOMPARE(sm.error(), QSharedMemory::NoError);
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+
+ QCOMPARE(sm.detach(), false);
+ }
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QSharedMemory::legacyKey()
+{
+ QFETCH(QString, constructorKey);
+ QFETCH(QString, setKey);
+ QFETCH(QString, setNativeKey);
+
+#ifdef Q_OS_QNX
+ QSKIP("The legacy native key type is incorrectly set on QNX");
+#endif
+ QSharedMemory sm(constructorKey);
+ QCOMPARE(sm.key(), constructorKey);
+ QCOMPARE(sm.nativeKey().isEmpty(), constructorKey.isEmpty());
+ sm.setKey(setKey);
+ QCOMPARE(sm.key(), setKey);
+ QCOMPARE(sm.nativeKey().isEmpty(), setKey.isEmpty());
+ sm.setNativeKey(setNativeKey);
+ QVERIFY(sm.key().isNull());
+ QCOMPARE(sm.nativeKey(), setNativeKey);
+ QCOMPARE(sm.isAttached(), false);
+
+ QCOMPARE(sm.error(), QSharedMemory::NoError);
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+
+ QCOMPARE(sm.detach(), false);
+}
+QT_WARNING_POP
+
+void tst_QSharedMemory::create_data()
+{
+ QTest::addColumn<QString>("key");
+ QTest::addColumn<int>("size");
+ QTest::addColumn<bool>("canCreate");
+ QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
+
+ QTest::newRow("null key") << QString() << 1024
+ << false << QSharedMemory::KeyError;
+ QTest::newRow("-1 size") << QString("negsize") << -1
+ << false << QSharedMemory::InvalidSize;
+ QTest::newRow("nor size") << QString("norsize") << 1024
+ << true << QSharedMemory::NoError;
+ QTest::newRow("existing") << QString("existing") << EXISTING_SIZE
+ << false << QSharedMemory::AlreadyExists;
+}
+
+/*!
+ Basic create testing
+ */
+void tst_QSharedMemory::create()
+{
+ QFETCH(QString, key);
+ QFETCH(int, size);
+ QFETCH(bool, canCreate);
+ QFETCH(QSharedMemory::SharedMemoryError, error);
+
+ QNativeIpcKey nativeKey = rememberKey(key);
+ QSharedMemory sm(nativeKey);
+ QCOMPARE(sm.create(size), canCreate);
+ if (sm.error() != error)
+ qDebug() << sm.errorString();
+ QCOMPARE(sm.nativeIpcKey(), nativeKey);
+ if (canCreate) {
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(sm.data() != 0);
+ QVERIFY(sm.size() != 0);
+ } else {
+ QVERIFY(!sm.data());
+ QVERIFY(sm.errorString() != QString());
+ }
+}
+
+void tst_QSharedMemory::attach_data()
+{
+ QTest::addColumn<QString>("key");
+ QTest::addColumn<bool>("exists");
+ QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
+
+ QTest::newRow("null") << QString() << false << QSharedMemory::KeyError;
+ QTest::newRow("doesntexists") << QString("doesntexist") << false << QSharedMemory::NotFound;
+
+ QTest::newRow("existing") << QString("existing") << true << QSharedMemory::NoError;
+}
+
+/*!
+ Basic attach/detach testing
+ */
+void tst_QSharedMemory::attach()
+{
+ QFETCH(QString, key);
+ QFETCH(bool, exists);
+ QFETCH(QSharedMemory::SharedMemoryError, error);
+
+ QNativeIpcKey nativeKey = platformSafeKey(key);
+ QSharedMemory sm(nativeKey);
+ QCOMPARE(sm.attach(), exists);
+ QCOMPARE(sm.isAttached(), exists);
+ QCOMPARE(sm.error(), error);
+ QCOMPARE(sm.nativeIpcKey(), nativeKey);
+ if (exists) {
+ QVERIFY(sm.data() != 0);
+ QVERIFY(sm.size() != 0);
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(sm.detach());
+ // Make sure detach doesn't screw up something and we can't re-attach.
+ QVERIFY(sm.attach());
+ QVERIFY(sm.data() != 0);
+ QVERIFY(sm.size() != 0);
+ QVERIFY(sm.detach());
+ QCOMPARE(sm.size(), 0);
+ QVERIFY(!sm.data());
+ } else {
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+ QVERIFY(sm.errorString() != QString());
+ QVERIFY(!sm.detach());
+ }
+}
+
+void tst_QSharedMemory::changeKeyType()
+{
+ QFETCH(QString, key);
+ QFETCH(bool, exists);
+ QFETCH(QSharedMemory::SharedMemoryError, error);
+
+ QNativeIpcKey nativeKey = platformSafeKey(key);
+ QNativeIpcKey::Type nextKeyType = IpcTestCommon::nextKeyType(nativeKey.type());
+ if (nextKeyType == nativeKey.type())
+ QSKIP("System only supports one key type");
+// qDebug() << "Changing from" << nativeKey.type() << "to" << nextKeyType;
+
+ QSharedMemory sm(nativeKey);
+ QCOMPARE(sm.attach(), exists);
+ QCOMPARE(sm.error(), error);
+
+ QNativeIpcKey nextKey =
+ QSharedMemory::platformSafeKey(mangleKey(key), nextKeyType);
+ sm.setNativeKey(nextKey);
+ QCOMPARE(sm.isAttached(), false);
+ QVERIFY(!sm.attach());
+
+ if (exists)
+ QCOMPARE(sm.error(), QSharedMemory::NotFound);
+ else
+ QCOMPARE(sm.error(), error);
+}
+
+void tst_QSharedMemory::lock()
+{
+ QSharedMemory shm;
+ QVERIFY(!shm.lock());
+ QCOMPARE(shm.error(), QSharedMemory::LockError);
+
+ shm.setNativeKey(rememberKey(QLatin1String("qsharedmemory")));
+
+ QVERIFY(!shm.lock());
+ QCOMPARE(shm.error(), QSharedMemory::LockError);
+
+ QVERIFY(shm.create(100));
+ QVERIFY(shm.lock());
+ QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
+ QVERIFY(shm.lock());
+ // we didn't unlock(), so ignore the warning from auto-detach in destructor
+ QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
+}
+
+/*!
+ Other shared memory are allowed to be attached after we remove,
+ but new shared memory are not allowed to attach after a remove.
+ */
+// HPUX doesn't allow for multiple attaches per process.
+void tst_QSharedMemory::removeWhileAttached()
+{
+ rememberKey("one");
+
+ // attach 1
+ QNativeIpcKey keyOne = platformSafeKey("one");
+ QSharedMemory *smOne = new QSharedMemory(keyOne);
+ QVERIFY(smOne->create(1024));
+ QVERIFY(smOne->isAttached());
+
+ // attach 2
+ QSharedMemory *smTwo = new QSharedMemory(platformSafeKey("one"));
+ QVERIFY(smTwo->attach());
+ QVERIFY(smTwo->isAttached());
+
+ // detach 1 and remove, remove one first to catch another error.
+ delete smOne;
+ delete smTwo;
+
+ if (keyOne.type() == QNativeIpcKey::Type::PosixRealtime) {
+ // POSIX IPC doesn't guarantee that the shared memory is removed
+ remove(keyOne);
+ }
+
+ // three shouldn't be able to attach
+ QSharedMemory smThree(keyOne);
+ QVERIFY(!smThree.attach());
+ QCOMPARE(smThree.error(), QSharedMemory::NotFound);
+}
+
+/*!
+ The memory should be set to 0 after created.
+ */
+void tst_QSharedMemory::emptyMemory()
+{
+ QSharedMemory sm(rememberKey(QLatin1String("voidland")));
+ int size = 1024;
+ QVERIFY(sm.create(size, QSharedMemory::ReadOnly));
+ char *get = (char*)sm.data();
+ char null = 0;
+ for (int i = 0; i < size; ++i)
+ QCOMPARE(get[i], null);
+}
+
+/*!
+ Verify that attach with ReadOnly is actually read only
+ by writing to data and causing a segfault.
+*/
+void tst_QSharedMemory::readOnly()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#elif defined(Q_OS_MACOS)
+ QSKIP("QTBUG-59936: Times out on macOS", SkipAll);
+#elif defined(Q_OS_WIN)
+ QSKIP("This test opens a crash dialog on Windows.");
+#elif defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+ QSKIP("ASan prevents the crash this test is looking for.", SkipAll);
+#else
+ QNativeIpcKey key = rememberKey("readonly_segfault");
+
+ // ### on windows disable the popup somehow
+ QProcess p;
+ p.setProcessChannelMode(QProcess::ForwardedChannels);
+ p.start(m_helperBinary, { "readonly_segfault", key.toString() });
+ p.waitForFinished();
+ QCOMPARE(p.error(), QProcess::Crashed);
+#endif
+}
+
+void tst_QSharedMemory::attachBeforeCreate_data()
+{
+ QTest::addColumn<bool>("legacy");
+
+ QTest::addRow("legacy") << true;
+ QTest::addRow("non-legacy") << false;
+}
+
+void tst_QSharedMemory::attachBeforeCreate()
+{
+ QFETCH_GLOBAL(const QNativeIpcKey::Type, keyType);
+ QFETCH(const bool, legacy);
+ const QString keyStr(u"test"_s);
+ QNativeIpcKey key;
+ if (legacy) {
+ key = QSharedMemory::legacyNativeKey(keyStr, keyType);
+ // same as rememberKey(), but with legacy
+ if (!keys.contains(key)) {
+ keys.append(key);
+ remove(key);
+ }
+ } else {
+ key = rememberKey(keyStr);
+ }
+ const qsizetype sz = 100;
+ QSharedMemory mem(key);
+ QVERIFY(!mem.attach());
+ QVERIFY(mem.create(sz));
+}
+
+/*!
+ Keep making shared memory until the kernel stops us.
+ */
+void tst_QSharedMemory::useTooMuchMemory()
+{
+ if (QSysInfo::productType() == QLatin1String("Debian")
+ || QSysInfo::productType() == QLatin1String("debian"))
+ QSKIP("This test is unstable: QTBUG-119321");
+
+#ifdef Q_OS_LINUX
+ bool success = true;
+ int count = 0;
+ while (success) {
+ QString key = QLatin1String("maxmemorytest_") + QString::number(count++);
+ QNativeIpcKey nativeKey = rememberKey(key);
+ QSharedMemory *sm = new QSharedMemory(nativeKey);
+ QVERIFY(sm);
+ jail.append(sm);
+ int size = 32768 * 1024;
+ success = sm->create(size);
+ if (!success && sm->error() == QSharedMemory::AlreadyExists) {
+ // left over from a crash, clean it up
+ sm->attach();
+ sm->detach();
+ success = sm->create(size);
+ }
+
+ if (!success) {
+ QVERIFY(!sm->isAttached());
+ QCOMPARE(sm->nativeIpcKey(), nativeKey);
+ QCOMPARE(sm->size(), 0);
+ QVERIFY(!sm->data());
+ if (sm->error() != QSharedMemory::OutOfResources)
+ qDebug() << sm->error() << sm->errorString();
+ // ### Linux won't return OutOfResources if there are not enough semaphores to use.
+ QVERIFY(sm->error() == QSharedMemory::OutOfResources
+ || sm->error() == QSharedMemory::LockError);
+ QVERIFY(sm->errorString() != QString());
+ QVERIFY(!sm->attach());
+ QVERIFY(!sm->detach());
+ } else {
+ QVERIFY(sm->isAttached());
+ }
+ }
+#endif
+}
+
+/*!
+ Create one shared memory (government) and see how many other shared memories (wars) we can
+ attach before the system runs out of resources.
+ */
+void tst_QSharedMemory::attachTooMuch()
+{
+ QSKIP("disabled");
+
+ QSharedMemory government(rememberKey("government"));
+ QVERIFY(government.create(1024));
+ while (true) {
+ QSharedMemory *war = new QSharedMemory(government.nativeIpcKey());
+ QVERIFY(war);
+ jail.append(war);
+ if (!war->attach()) {
+ QVERIFY(!war->isAttached());
+ QCOMPARE(war->nativeIpcKey(), government.nativeIpcKey());
+ QCOMPARE(war->size(), 0);
+ QVERIFY(!war->data());
+ QCOMPARE(war->error(), QSharedMemory::OutOfResources);
+ QVERIFY(war->errorString() != QString());
+ QVERIFY(!war->detach());
+ break;
+ } else {
+ QVERIFY(war->isAttached());
+ }
+ }
+}
+
+void tst_QSharedMemory::simpleProducerConsumer_data()
+{
+ QTest::addColumn<QSharedMemory::AccessMode>("mode");
+
+ QTest::newRow("readonly") << QSharedMemory::ReadOnly;
+ QTest::newRow("readwrite") << QSharedMemory::ReadWrite;
+}
+
+/*!
+ The basic consumer producer that rounds out the basic testing.
+ If this fails then any muli-threading/process might fail (but be
+ harder to debug)
+
+ This doesn't require nor test any locking system.
+ */
+void tst_QSharedMemory::simpleProducerConsumer()
+{
+ QFETCH(QSharedMemory::AccessMode, mode);
+
+ rememberKey(QLatin1String("market"));
+ QSharedMemory producer(platformSafeKey("market"));
+ QSharedMemory consumer(platformSafeKey("market"));
+ int size = 512;
+ QVERIFY(producer.create(size));
+ QVERIFY(consumer.attach(mode));
+
+ char *put = (char*)producer.data();
+ char *get = (char*)consumer.data();
+ // On Windows CE you always have ReadWrite access. Thus
+ // ViewMapOfFile returns the same pointer
+ QVERIFY(put != get);
+ for (int i = 0; i < size; ++i) {
+ put[i] = 'Q';
+ QCOMPARE(get[i], 'Q');
+ }
+ QVERIFY(consumer.detach());
+}
+
+void tst_QSharedMemory::simpleDoubleProducerConsumer()
+{
+ QNativeIpcKey nativeKey = rememberKey(QLatin1String("market"));
+ QSharedMemory producer(nativeKey);
+ int size = 512;
+ QVERIFY(producer.create(size));
+ QVERIFY(producer.detach());
+
+ if (nativeKey.type() == QNativeIpcKey::Type::PosixRealtime) {
+ // POSIX IPC doesn't guarantee that the shared memory is removed
+ remove(nativeKey);
+ }
+
+ QVERIFY(producer.create(size));
+
+ {
+ QSharedMemory consumer(nativeKey);
+ QVERIFY(consumer.attach());
+ }
+}
+
+class Consumer : public QThread
+{
+public:
+ QNativeIpcKey nativeKey;
+ Consumer(const QNativeIpcKey &nativeKey) : nativeKey(nativeKey) {}
+
+ void run() override
+ {
+ QSharedMemory consumer(nativeKey);
+ while (!consumer.attach()) {
+ if (consumer.error() != QSharedMemory::NotFound)
+ qDebug() << "consumer: failed to connect" << consumer.error() << consumer.errorString();
+ QVERIFY(consumer.error() == QSharedMemory::NotFound || consumer.error() == QSharedMemory::KeyError);
+ QTest::qWait(1);
+ }
+
+ char *memory = (char*)consumer.data();
+
+ int i = 0;
+ while (true) {
+ if (!consumer.lock())
+ break;
+ if (memory[0] == 'Q')
+ memory[0] = ++i;
+ if (memory[0] == 'E') {
+ memory[1]++;
+ QVERIFY(consumer.unlock());
+ break;
+ }
+ QVERIFY(consumer.unlock());
+ QTest::qWait(1);
+ }
+
+ QVERIFY(consumer.detach());
+ }
+};
+
+class Producer : public QThread
+{
+public:
+ Producer(const QNativeIpcKey &nativeKey) : producer(nativeKey)
+ {
+ int size = 1024;
+ if (!producer.create(size)) {
+ // left over from a crash...
+ if (producer.error() == QSharedMemory::AlreadyExists) {
+ producer.attach();
+ producer.detach();
+ QVERIFY(producer.create(size));
+ }
+ }
+ }
+
+ void run() override
+ {
+
+ char *memory = (char*)producer.data();
+ memory[1] = '0';
+ QElapsedTimer timer;
+ timer.start();
+ int i = 0;
+ while (i < 5 && timer.elapsed() < 5000) {
+ QVERIFY(producer.lock());
+ if (memory[0] == 'Q') {
+ QVERIFY(producer.unlock());
+ QTest::qWait(1);
+ continue;
+ }
+ ++i;
+ memory[0] = 'Q';
+ QVERIFY(producer.unlock());
+ QTest::qWait(1);
+ }
+
+ // tell everyone to quit
+ QVERIFY(producer.lock());
+ memory[0] = 'E';
+ QVERIFY(producer.unlock());
+
+ }
+
+ QSharedMemory producer;
+private:
+
+};
+
+void tst_QSharedMemory::simpleThreadedProducerConsumer_data()
+{
+ QTest::addColumn<bool>("producerIsThread");
+ QTest::addColumn<int>("threads");
+ for (int i = 0; i < 5; ++i) {
+ QTest::newRow("1 consumer, producer is thread") << true << 1;
+ QTest::newRow("1 consumer, producer is this") << false << 1;
+ QTest::newRow("5 consumers, producer is thread") << true << 5;
+ QTest::newRow("5 consumers, producer is this") << false << 5;
+ }
+}
+
+/*!
+ The basic producer/consumer, but this time using threads.
+ */
+void tst_QSharedMemory::simpleThreadedProducerConsumer()
+{
+ QFETCH(bool, producerIsThread);
+ QFETCH(int, threads);
+ QNativeIpcKey nativeKey = rememberKey(QLatin1String("market"));
+
+ Producer p(nativeKey);
+ QVERIFY(p.producer.isAttached());
+ if (producerIsThread)
+ p.start();
+
+ QList<Consumer*> consumers;
+ for (int i = 0; i < threads; ++i) {
+ consumers.append(new Consumer(nativeKey));
+ consumers.last()->start();
+ }
+
+ if (!producerIsThread)
+ p.run();
+
+ p.wait(5000);
+ while (!consumers.isEmpty()) {
+ Consumer *c = consumers.first();
+ QVERIFY(c->isFinished() || c->wait(5000));
+ delete consumers.takeFirst();
+ }
+}
+
+void tst_QSharedMemory::simpleProcessProducerConsumer_data()
+{
+#if QT_CONFIG(process)
+ QTest::addColumn<int>("processes");
+ int tries = 5;
+ for (int i = 0; i < tries; ++i) {
+ QTest::newRow("1 process") << 1;
+ QTest::newRow("5 processes") << 5;
+ }
+#endif
+}
+
+/*!
+ Create external processes that produce and consume.
+ */
+void tst_QSharedMemory::simpleProcessProducerConsumer()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QFETCH(int, processes);
+
+ QSKIP("This test is unstable: QTBUG-25655");
+
+ QNativeIpcKey nativeKey = rememberKey("market");
+
+ QProcess producer;
+ producer.start(m_helperBinary, { "producer", nativeKey.toString() });
+ QVERIFY2(producer.waitForStarted(), "Could not start helper binary");
+ QVERIFY2(producer.waitForReadyRead(), "Helper process failed to create shared memory segment: " +
+ producer.readAllStandardError());
+
+ QList<QProcess*> consumers;
+ unsigned int failedProcesses = 0;
+ QStringList consumerArguments = { "consumer", nativeKey.toString() };
+ for (int i = 0; i < processes; ++i) {
+ QProcess *p = new QProcess;
+ p->setProcessChannelMode(QProcess::ForwardedChannels);
+ p->start(m_helperBinary, consumerArguments);
+ if (p->waitForStarted(2000))
+ consumers.append(p);
+ else
+ ++failedProcesses;
+ }
+
+ bool consumerFailed = false;
+
+ while (!consumers.isEmpty()) {
+ QVERIFY(consumers.first()->waitForFinished(3000));
+ if (consumers.first()->state() == QProcess::Running ||
+ consumers.first()->exitStatus() != QProcess::NormalExit ||
+ consumers.first()->exitCode() != 0) {
+ consumerFailed = true;
+ }
+ delete consumers.takeFirst();
+ }
+ QCOMPARE(consumerFailed, false);
+ QCOMPARE(failedProcesses, (unsigned int)(0));
+
+ // tell the producer to exit now
+ producer.write("", 1);
+ producer.waitForBytesWritten();
+ QVERIFY(producer.waitForFinished(5000));
+#endif
+}
+
+void tst_QSharedMemory::uniqueKey_data()
+{
+ QTest::addColumn<QString>("key1");
+ QTest::addColumn<QString>("key2");
+
+ QTest::newRow("null == null") << QString() << QString();
+ QTest::newRow("key == key") << QString("key") << QString("key");
+ QTest::newRow("key1 == key1") << QString("key1") << QString("key1");
+ QTest::newRow("key != key1") << QString("key") << QString("key1");
+ QTest::newRow("ke1y != key1") << QString("ke1y") << QString("key1");
+ QTest::newRow("key1 != key2") << QString("key1") << QString("key2");
+ QTest::newRow("Noël -> Nol") << QString::fromUtf8("N\xc3\xabl") << QString("Nol");
+}
+
+void tst_QSharedMemory::uniqueKey()
+{
+ QFETCH(QString, key1);
+ QFETCH(QString, key2);
+
+ QSharedMemory sm1(platformSafeKey(key1));
+ QSharedMemory sm2(platformSafeKey(key2));
+
+ bool setEqual = (key1 == key2);
+ bool keyEqual = (sm1.nativeIpcKey() == sm2.nativeIpcKey());
+ bool nativeEqual = (sm1.nativeKey() == sm2.nativeKey());
+
+ QCOMPARE(keyEqual, setEqual);
+ QCOMPARE(nativeEqual, setEqual);
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QSharedMemory::createWithSameKey()
+{
+ const QString key = u"legacy_key"_s;
+ const qsizetype sz = 100;
+ QSharedMemory mem1(key);
+ QVERIFY(mem1.create(sz));
+
+ {
+ QSharedMemory mem2(key);
+ QVERIFY(!mem2.create(sz));
+ QVERIFY(mem2.attach());
+ }
+ // and the second create() should fail as well, QTBUG-111855
+ {
+ QSharedMemory mem2(key);
+ QVERIFY(!mem2.create(sz));
+ QVERIFY(mem2.attach());
+ }
+}
+QT_WARNING_POP
+
+QTEST_MAIN(tst_QSharedMemory)
+#include "tst_qsharedmemory.moc"
+
diff --git a/tests/auto/corelib/ipc/qsystemsemaphore/CMakeLists.txt b/tests/auto/corelib/ipc/qsystemsemaphore/CMakeLists.txt
new file mode 100644
index 0000000000..a0f29ad18a
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsystemsemaphore/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsystemsemaphore Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsystemsemaphore LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsystemsemaphore
+ SOURCES
+ tst_qsystemsemaphore.cpp
+)
+
+add_subdirectory(acquirerelease)
+if(QT_FEATURE_process)
+ add_dependencies(tst_qsystemsemaphore acquirerelease_helper)
+endif()
diff --git a/tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/CMakeLists.txt b/tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/CMakeLists.txt
new file mode 100644
index 0000000000..a0a7d84b17
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## acquirerelease_helper Binary:
+#####################################################################
+
+qt_internal_add_test_helper(acquirerelease_helper
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Test
+)
diff --git a/tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/main.cpp b/tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/main.cpp
new file mode 100644
index 0000000000..3cae7ad466
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsystemsemaphore/acquirerelease/main.cpp
@@ -0,0 +1,80 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QStringList>
+#include <QSystemSemaphore>
+
+int acquire(const QNativeIpcKey &key, int count = 1)
+{
+ QSystemSemaphore sem(key);
+
+ for (int i = 0; i < count; ++i) {
+ if (!sem.acquire()) {
+ qWarning() << "Could not acquire" << sem.key();
+ return EXIT_FAILURE;
+ }
+ }
+ qDebug("done aquiring");
+ return EXIT_SUCCESS;
+}
+
+int release(const QNativeIpcKey &key)
+{
+ QSystemSemaphore sem(key);
+ if (!sem.release()) {
+ qWarning() << "Could not release" << sem.key();
+ return EXIT_FAILURE;
+ }
+ qDebug("done releasing");
+ return EXIT_SUCCESS;
+}
+
+int acquirerelease(const QNativeIpcKey &key)
+{
+ QSystemSemaphore sem(key);
+ if (!sem.acquire()) {
+ qWarning() << "Could not acquire" << sem.key();
+ return EXIT_FAILURE;
+ }
+ if (!sem.release()) {
+ qWarning() << "Could not release" << sem.key();
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QStringList arguments = app.arguments();
+ // binary name is not used here
+ arguments.takeFirst();
+ if (arguments.size() < 2) {
+ fprintf(stderr,
+ "Usage: %s <acquire|release|acquirerelease> <key> [other args...]\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ QString function = arguments.takeFirst();
+ QNativeIpcKey key = QNativeIpcKey::fromString(arguments.takeFirst());
+ if (function == QLatin1String("acquire")) {
+ int count = 1;
+ bool ok = true;
+ if (arguments.size())
+ count = arguments.takeFirst().toInt(&ok);
+ if (!ok)
+ count = 1;
+ return acquire(key, count);
+ } else if (function == QLatin1String("release")) {
+ return release(key);
+ } else if (function == QLatin1String("acquirerelease")) {
+ return acquirerelease(key);
+ } else {
+ qWarning() << "Unknown function" << function;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/tests/auto/corelib/ipc/qsystemsemaphore/tst_qsystemsemaphore.cpp b/tests/auto/corelib/ipc/qsystemsemaphore/tst_qsystemsemaphore.cpp
new file mode 100644
index 0000000000..2c053b91f6
--- /dev/null
+++ b/tests/auto/corelib/ipc/qsystemsemaphore/tst_qsystemsemaphore.cpp
@@ -0,0 +1,368 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
+
+#include <QtCore/QList>
+#include <QtCore/QSystemSemaphore>
+#include <QtCore/QTemporaryDir>
+
+#include "../ipctestcommon.h"
+
+#define HELPERWAITTIME 10000
+
+using namespace Qt::StringLiterals;
+
+class tst_QSystemSemaphore : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSystemSemaphore();
+
+ QString mangleKey(QStringView key)
+ {
+ if (key.isEmpty())
+ return key.toString();
+ return u"tstsyssem_%1-%2_%3"_s.arg(QCoreApplication::applicationPid())
+ .arg(seq).arg(key);
+ }
+
+ QNativeIpcKey platformSafeKey(const QString &key)
+ {
+ QFETCH_GLOBAL(QNativeIpcKey::Type, keyType);
+ return QSystemSemaphore::platformSafeKey(mangleKey(key), keyType);
+ }
+
+public Q_SLOTS:
+ void initTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void nativeKey_data();
+ void nativeKey();
+ void legacyKey_data() { nativeKey_data(); }
+ void legacyKey();
+
+ void changeKeyType();
+ void basicacquire();
+ void complexacquire();
+ void release();
+ void twoSemaphores();
+
+ void basicProcesses();
+
+ void processes_data();
+ void processes();
+
+ void undo();
+ void initialValue();
+
+private:
+ int seq = 0;
+ QSystemSemaphore *existingLock;
+
+ const QString m_helperBinary;
+};
+
+tst_QSystemSemaphore::tst_QSystemSemaphore()
+ : m_helperBinary("./acquirerelease_helper")
+{
+}
+
+void tst_QSystemSemaphore::initTestCase()
+{
+ IpcTestCommon::addGlobalTestRows<QSystemSemaphore>();
+}
+
+void tst_QSystemSemaphore::init()
+{
+ QNativeIpcKey key = platformSafeKey("existing");
+ existingLock = new QSystemSemaphore(key, 1, QSystemSemaphore::Create);
+}
+
+void tst_QSystemSemaphore::cleanup()
+{
+ delete existingLock;
+ ++seq;
+}
+
+void tst_QSystemSemaphore::nativeKey_data()
+{
+ QTest::addColumn<QString>("constructorKey");
+ QTest::addColumn<QString>("setKey");
+
+ QTest::newRow("null, null") << QString() << QString();
+ QTest::newRow("null, one") << QString() << QString("one");
+ QTest::newRow("one, two") << QString("one") << QString("two");
+}
+
+/*!
+ Basic key testing
+ */
+void tst_QSystemSemaphore::nativeKey()
+{
+ QFETCH(QString, constructorKey);
+ QFETCH(QString, setKey);
+ QNativeIpcKey constructorIpcKey = platformSafeKey(constructorKey);
+ QNativeIpcKey setIpcKey = platformSafeKey(setKey);
+
+ QSystemSemaphore sem(constructorIpcKey);
+ QCOMPARE(sem.nativeIpcKey(), constructorIpcKey);
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+
+ sem.setNativeKey(setIpcKey);
+ QCOMPARE(sem.nativeIpcKey(), setIpcKey);
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+
+ // change the key type
+ QNativeIpcKey::Type nextKeyType = IpcTestCommon::nextKeyType(setIpcKey.type());
+ if (nextKeyType != setIpcKey.type()) {
+ QNativeIpcKey setIpcKey2 = QSystemSemaphore::platformSafeKey(setKey, nextKeyType);
+ sem.setNativeKey(setIpcKey2);
+ QCOMPARE(sem.nativeIpcKey(), setIpcKey2);
+ }
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QSystemSemaphore::legacyKey()
+{
+ QFETCH(QString, constructorKey);
+ QFETCH(QString, setKey);
+
+ QSystemSemaphore sem(constructorKey);
+ QCOMPARE(sem.key(), constructorKey);
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+
+ sem.setKey(setKey);
+ QCOMPARE(sem.key(), setKey);
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+QT_WARNING_POP
+
+void tst_QSystemSemaphore::changeKeyType()
+{
+ QString keyName = "changeKeyType";
+ QNativeIpcKey key = platformSafeKey(keyName);
+ QNativeIpcKey otherKey =
+ QSystemSemaphore::platformSafeKey(mangleKey(keyName), IpcTestCommon::nextKeyType(key.type()));
+ if (key == otherKey)
+ QSKIP("System only supports one key type");
+
+ QSystemSemaphore sem1(key, 1, QSystemSemaphore::Create);
+ QSystemSemaphore sem2(otherKey);
+ sem1.setNativeKey(otherKey);
+ sem2.setNativeKey(key);
+}
+
+void tst_QSystemSemaphore::basicacquire()
+{
+ QNativeIpcKey key = platformSafeKey("basicacquire");
+ QSystemSemaphore sem(key, 1, QSystemSemaphore::Create);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::complexacquire()
+{
+ QNativeIpcKey key = platformSafeKey("complexacquire");
+ QSystemSemaphore sem(key, 2, QSystemSemaphore::Create);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::release()
+{
+ QNativeIpcKey key = platformSafeKey("release");
+ QSystemSemaphore sem(key, 0, QSystemSemaphore::Create);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::twoSemaphores()
+{
+ QNativeIpcKey key = platformSafeKey("twoSemaphores");
+ QSystemSemaphore sem1(key, 1, QSystemSemaphore::Create);
+ QSystemSemaphore sem2(key);
+ QVERIFY(sem1.acquire());
+ QVERIFY(sem2.release());
+ QVERIFY(sem1.acquire());
+ QVERIFY(sem2.release());
+}
+
+void tst_QSystemSemaphore::basicProcesses()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QNativeIpcKey key = platformSafeKey("store");
+ QSystemSemaphore sem(key, 0, QSystemSemaphore::Create);
+
+ QProcess acquire;
+ acquire.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ QProcess release;
+ release.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ acquire.start(m_helperBinary, { "acquire", key.toString() });
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QCOMPARE(acquire.state(), QProcess::Running);
+ acquire.kill();
+ release.start(m_helperBinary, { "release", key.toString() });
+ QVERIFY2(release.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ release.waitForFinished(HELPERWAITTIME);
+ QCOMPARE(acquire.state(), QProcess::NotRunning);
+#endif
+}
+
+void tst_QSystemSemaphore::processes_data()
+{
+ QTest::addColumn<int>("processes");
+ for (int i = 0; i < 5; ++i) {
+ QTest::addRow("1 process (%d)", i) << 1;
+ QTest::addRow("3 process (%d)", i) << 3;
+ QTest::addRow("10 process (%d)", i) << 10;
+ }
+}
+
+void tst_QSystemSemaphore::processes()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QNativeIpcKey key = platformSafeKey("store");
+ QSystemSemaphore sem(key, 1, QSystemSemaphore::Create);
+
+ QFETCH(int, processes);
+ QList<QString> scripts(processes, "acquirerelease");
+
+ QList<QProcess*> consumers;
+ for (int i = 0; i < scripts.size(); ++i) {
+ QProcess *p = new QProcess;
+ p->setProcessChannelMode(QProcess::ForwardedChannels);
+ consumers.append(p);
+ p->start(m_helperBinary, { scripts.at(i), key.toString() });
+ }
+
+ while (!consumers.isEmpty()) {
+ consumers.first()->waitForFinished();
+ QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
+ QCOMPARE(consumers.first()->exitCode(), 0);
+ delete consumers.takeFirst();
+ }
+#endif
+}
+
+void tst_QSystemSemaphore::undo()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QNativeIpcKey key = platformSafeKey("store");
+ switch (key.type()) {
+ case QNativeIpcKey::Type::PosixRealtime:
+ case QNativeIpcKey::Type::Windows:
+ QSKIP("This test only checks a System V behavior.");
+
+ case QNativeIpcKey::Type::SystemV:
+ break;
+ }
+
+ QSystemSemaphore sem(key, 1, QSystemSemaphore::Create);
+
+ QStringList acquireArguments = { "acquire", key.toString() };
+ QProcess acquire;
+ acquire.setProcessChannelMode(QProcess::ForwardedChannels);
+ acquire.start(m_helperBinary, acquireArguments);
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+
+ // At process exit the kernel should auto undo
+
+ acquire.start(m_helperBinary, acquireArguments);
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+#endif
+}
+
+void tst_QSystemSemaphore::initialValue()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QNativeIpcKey key = platformSafeKey("store");
+ QSystemSemaphore sem(key, 1, QSystemSemaphore::Create);
+
+ QStringList acquireArguments = { "acquire", key.toString() };
+ QStringList releaseArguments = { "release", key.toString() };
+ QProcess acquire;
+ acquire.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ QProcess release;
+ release.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ acquire.start(m_helperBinary, acquireArguments);
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+
+ acquire.start(m_helperBinary, acquireArguments << QLatin1String("2"));
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::Running);
+ acquire.kill();
+
+ release.start(m_helperBinary, releaseArguments);
+ QVERIFY2(release.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ release.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+#endif
+}
+
+QTEST_MAIN(tst_QSystemSemaphore)
+#include "tst_qsystemsemaphore.moc"
+
diff --git a/tests/auto/corelib/itemmodels/CMakeLists.txt b/tests/auto/corelib/itemmodels/CMakeLists.txt
new file mode 100644
index 0000000000..90211669d9
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qstringlistmodel)
+if(TARGET Qt::Gui)
+ add_subdirectory(qabstractitemmodel)
+ add_subdirectory(qabstractproxymodel)
+ add_subdirectory(qconcatenatetablesproxymodel)
+ add_subdirectory(qidentityproxymodel)
+ add_subdirectory(qitemselectionmodel)
+ add_subdirectory(qsortfilterproxymodel_recursive)
+ add_subdirectory(qsortfilterproxymodel_regularexpression)
+ add_subdirectory(qtransposeproxymodel)
+endif()
+if(TARGET Qt::Widgets)
+ add_subdirectory(qsortfilterproxymodel)
+endif()
+if(TARGET Qt::Sql AND TARGET Qt::Widgets)
+ add_subdirectory(qitemmodel)
+endif()
diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro
deleted file mode 100644
index cca350ad43..0000000000
--- a/tests/auto/corelib/itemmodels/itemmodels.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TEMPLATE=subdirs
-
-SUBDIRS = qstringlistmodel
-
-qtHaveModule(gui): SUBDIRS += \
- qabstractitemmodel \
- qabstractproxymodel \
- qidentityproxymodel \
- qitemselectionmodel \
- qsortfilterproxymodel_recursive \
-
-qtHaveModule(widgets) {
- SUBDIRS += \
- qsortfilterproxymodel_regexp \
- qsortfilterproxymodel_regularexpression
-
- qtHaveModule(sql): SUBDIRS += \
- qitemmodel
-}
diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qabstractitemmodel/CMakeLists.txt
new file mode 100644
index 0000000000..e5c7c08fc8
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qabstractitemmodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractitemmodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qabstractitemmodel
+ SOURCES
+ ../../../other/qabstractitemmodelutils/dynamictreemodel.cpp ../../../other/qabstractitemmodelutils/dynamictreemodel.h
+ tst_qabstractitemmodel.cpp
+ INCLUDE_DIRECTORIES
+ ../../../other/qabstractitemmodelutils
+ LIBRARIES
+ Qt::Gui
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro
deleted file mode 100644
index da1f87e76a..0000000000
--- a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qabstractitemmodel
-QT = core testlib gui
-
-mtdir = ../../../other/qabstractitemmodelutils
-INCLUDEPATH += $$PWD/$${mtdir}
-SOURCES = tst_qabstractitemmodel.cpp $${mtdir}/dynamictreemodel.cpp
-HEADERS = $${mtdir}/dynamictreemodel.h
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp
index b960ca9220..36eb9320a4 100644
--- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp
@@ -1,40 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QCoreApplication>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+
+#include <QtCore/QCoreApplication>
#include <QtCore/QSortFilterProxyModel>
#include <QtCore/QStringListModel>
#include <QtGui/QStandardItemModel>
#include "dynamictreemodel.h"
+// for testing QModelRoleDataSpan construction
+#include <QVarLengthArray>
+#include <QSignalSpy>
+#include <QMimeData>
+
+#include <array>
+#include <vector>
+#include <deque>
+#include <list>
+
/*!
Note that this doesn't test models, but any functionality that QAbstractItemModel should provide
*/
@@ -71,6 +58,7 @@ private slots:
void reset();
void complexChangesWithPersistent();
+ void modelIndexComparisons();
void testMoveSameParentUp_data();
void testMoveSameParentUp();
@@ -108,6 +96,10 @@ private slots:
void checkIndex();
+ void modelRoleDataSpanConstruction();
+ void modelRoleDataSpan();
+
+ void multiData();
private:
DynamicTreeModel *m_model;
};
@@ -121,32 +113,32 @@ private:
class QtTestModel: public QAbstractItemModel
{
public:
- QtTestModel(int rows, int columns, QObject *parent = 0);
- QtTestModel(const QVector<QVector<QString> > tbl, QObject *parent = 0);
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex &) const;
- int rowCount(const QModelIndex &parent) const;
- int columnCount(const QModelIndex &parent) const;
- bool hasChildren(const QModelIndex &) const;
- QVariant data(const QModelIndex &idx, int) const;
- bool setData(const QModelIndex &idx, const QVariant &value, int);
- bool insertRows(int row, int count, const QModelIndex &parent= QModelIndex());
- bool insertColumns(int column, int count, const QModelIndex &parent= QModelIndex());
+ QtTestModel(int rows, int columns, QObject *parent = nullptr);
+ QtTestModel(const QList<QList<QString> > tbl, QObject *parent = nullptr);
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &) const override;
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ bool hasChildren(const QModelIndex &) const override;
+ QVariant data(const QModelIndex &idx, int) const override;
+ bool setData(const QModelIndex &idx, const QVariant &value, int) override;
+ bool insertRows(int row, int count, const QModelIndex &parent= QModelIndex()) override;
+ bool insertColumns(int column, int count, const QModelIndex &parent= QModelIndex()) override;
void setPersistent(const QModelIndex &from, const QModelIndex &to);
- bool removeRows ( int row, int count, const QModelIndex & parent = QModelIndex() );
- bool removeColumns( int column, int count, const QModelIndex & parent = QModelIndex());
+ bool removeRows ( int row, int count, const QModelIndex & parent = QModelIndex()) override;
+ bool removeColumns( int column, int count, const QModelIndex & parent = QModelIndex()) override;
bool moveRows (const QModelIndex &sourceParent, int sourceRow, int count,
- const QModelIndex &destinationParent, int destinationChild);
+ const QModelIndex &destinationParent, int destinationChild) override;
bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count,
- const QModelIndex &destinationParent, int destinationChild);
+ const QModelIndex &destinationParent, int destinationChild) override;
void reset();
bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent) const;
+ int row, int column, const QModelIndex &parent) const override;
int cCount, rCount;
mutable bool wrongIndex;
- QVector<QVector<QString> > table;
+ QList<QList<QString> > table;
};
Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint);
@@ -163,12 +155,12 @@ QtTestModel::QtTestModel(int rows, int columns, QObject *parent)
}
}
-QtTestModel::QtTestModel(const QVector<QVector<QString> > tbl, QObject *parent)
+QtTestModel::QtTestModel(const QList<QList<QString> > tbl, QObject *parent)
: QAbstractItemModel(parent), wrongIndex(false)
{
table = tbl;
- rCount = tbl.count();
- cCount = tbl.at(0).count();
+ rCount = tbl.size();
+ cCount = tbl.at(0).size();
}
QModelIndex QtTestModel::index(int row, int column, const QModelIndex &parent) const
@@ -201,8 +193,8 @@ bool QtTestModel::insertRows(int row, int count, const QModelIndex &parent)
{
QAbstractItemModel::beginInsertRows(parent, row, row + count - 1);
int cc = columnCount(parent);
- table.insert(row, count, QVector<QString>(cc));
- rCount = table.count();
+ table.insert(row, count, QList<QString>(cc));
+ rCount = table.size();
QAbstractItemModel::endInsertRows();
return true;
}
@@ -213,7 +205,7 @@ bool QtTestModel::insertColumns(int column, int count, const QModelIndex &parent
int rc = rowCount(parent);
for (int i = 0; i < rc; ++i)
table[i].insert(column, 1, "");
- cCount = table.at(0).count();
+ cCount = table.at(0).size();
QAbstractItemModel::endInsertColumns();
return true;
}
@@ -229,7 +221,7 @@ bool QtTestModel::removeRows( int row, int count, const QModelIndex & parent)
for (int r = row+count-1; r >= row; --r)
table.remove(r);
- rCount = table.count();
+ rCount = table.size();
QAbstractItemModel::endRemoveRows();
return true;
@@ -243,7 +235,7 @@ bool QtTestModel::removeColumns(int column, int count, const QModelIndex & paren
for (int r = 0; r < rCount; ++r)
table[r].remove(c);
- cCount = table.at(0).count();
+ cCount = table.at(0).size();
QAbstractItemModel::endRemoveColumns();
return true;
@@ -256,7 +248,7 @@ bool QtTestModel::moveRows(const QModelIndex &sourceParent, int src, int cnt,
destinationParent, dst))
return false;
- QVector<QString> buf;
+ QList<QString> buf;
if (dst < src) {
for (int i = 0; i < cnt; ++i) {
buf.swap(table[src + i]);
@@ -271,7 +263,7 @@ bool QtTestModel::moveRows(const QModelIndex &sourceParent, int src, int cnt,
}
}
- rCount = table.count();
+ rCount = table.size();
QAbstractItemModel::endMoveRows();
return true;
@@ -301,7 +293,7 @@ bool QtTestModel::moveColumns(const QModelIndex &sourceParent, int src, int cnt,
}
}
- cCount = table.at(0).count();
+ cCount = table.at(0).size();
QAbstractItemModel::endMoveColumns();
return true;
@@ -309,7 +301,8 @@ bool QtTestModel::moveColumns(const QModelIndex &sourceParent, int src, int cnt,
void QtTestModel::reset()
{
- QAbstractItemModel::reset();
+ QAbstractItemModel::beginResetModel();
+ QAbstractItemModel::endResetModel();
}
bool QtTestModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
@@ -424,11 +417,11 @@ void tst_QAbstractItemModel::itemFlags()
void tst_QAbstractItemModel::match()
{
- QtTestModel model(4, 1);
+ QtTestModel model(5, 1);
QModelIndex start = model.index(0, 0, QModelIndex());
QVERIFY(start.isValid());
QModelIndexList res = model.match(start, Qt::DisplayRole, QVariant("1"), 3);
- QCOMPARE(res.count(), 1);
+ QCOMPARE(res.size(), 1);
QModelIndex idx = model.index(1, 0, QModelIndex());
bool areEqual = (idx == res.first());
QVERIFY(areEqual);
@@ -437,32 +430,61 @@ void tst_QAbstractItemModel::match()
model.setData(model.index(1, 0, QModelIndex()), "cat", Qt::DisplayRole);
model.setData(model.index(2, 0, QModelIndex()), "dog", Qt::DisplayRole);
model.setData(model.index(3, 0, QModelIndex()), "boar", Qt::DisplayRole);
+ model.setData(model.index(4, 0, QModelIndex()), "bo/a/r", Qt::DisplayRole); // QTBUG-104585
res = model.match(start, Qt::DisplayRole, QVariant("dog"), -1, Qt::MatchExactly);
- QCOMPARE(res.count(), 1);
+ QCOMPARE(res.size(), 1);
res = model.match(start, Qt::DisplayRole, QVariant("a"), -1, Qt::MatchContains);
- QCOMPARE(res.count(), 3);
+ QCOMPARE(res.size(), 4);
res = model.match(start, Qt::DisplayRole, QVariant("b"), -1, Qt::MatchStartsWith);
- QCOMPARE(res.count(), 2);
+ QCOMPARE(res.size(), 3);
res = model.match(start, Qt::DisplayRole, QVariant("t"), -1, Qt::MatchEndsWith);
- QCOMPARE(res.count(), 2);
+ QCOMPARE(res.size(), 2);
res = model.match(start, Qt::DisplayRole, QVariant("*a*"), -1, Qt::MatchWildcard);
- QCOMPARE(res.count(), 3);
- res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1, Qt::MatchRegExp);
- QCOMPARE(res.count(), 2);
- res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1, Qt::MatchRegExp | Qt::MatchCaseSensitive);
- QCOMPARE(res.count(), 0);
+ QCOMPARE(res.size(), 4);
+ res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1, Qt::MatchRegularExpression);
+ QCOMPARE(res.size(), 3);
+ res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1, Qt::MatchRegularExpression | Qt::MatchCaseSensitive);
+ QCOMPARE(res.size(), 0);
res = model.match(start, Qt::DisplayRole, QVariant("BOAR"), -1, Qt::MatchFixedString);
- QCOMPARE(res.count(), 1);
+ QCOMPARE(res.size(), 1);
res = model.match(start, Qt::DisplayRole, QVariant("bat"), -1,
Qt::MatchFixedString | Qt::MatchCaseSensitive);
- QCOMPARE(res.count(), 1);
+ QCOMPARE(res.size(), 1);
+
+ res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1,
+ Qt::MatchRegularExpression);
+ QCOMPARE(res.size(), 3);
+ res = model.match(start, Qt::DisplayRole, QVariant(".*O.*"), -1,
+ Qt::MatchRegularExpression | Qt::MatchCaseSensitive);
+ QCOMPARE(res.size(), 0);
+
+ res = model.match(start, Qt::DisplayRole, QVariant(QRegularExpression(".*O.*")),
+ -1, Qt::MatchRegularExpression);
+ QCOMPARE(res.size(), 0);
+ res = model.match(start,
+ Qt::DisplayRole,
+ QVariant(QRegularExpression(".*O.*",
+ QRegularExpression::CaseInsensitiveOption)),
+ -1,
+ Qt::MatchRegularExpression);
+ QCOMPARE(res.size(), 3);
+
+ // Ensure that the case sensitivity is properly ignored when passing a
+ // QRegularExpression object.
+ res = model.match(start,
+ Qt::DisplayRole,
+ QVariant(QRegularExpression(".*O.*",
+ QRegularExpression::CaseInsensitiveOption)),
+ -1,
+ Qt::MatchRegularExpression | Qt::MatchCaseSensitive);
+ QCOMPARE(res.size(), 3);
}
typedef QPair<int, int> Position;
-typedef QVector<QPair<int, int> > Selection;
-typedef QVector<QVector<QString> > StringTable;
-typedef QVector<QString> StringTableRow;
+typedef QList<QPair<int, int> > Selection;
+typedef QList<QList<QString> > StringTable;
+typedef QList<QString> StringTableRow;
static StringTableRow qStringTableRow(const QString &s1, const QString &s2, const QString &s3)
{
@@ -739,7 +761,7 @@ void tst_QAbstractItemModel::dropMimeData()
// get the mimeData from the "selected" indexes
QModelIndexList selectedIndexes;
- for (int i = 0; i < selection.count(); ++i)
+ for (int i = 0; i < selection.size(); ++i)
selectedIndexes << src.index(selection.at(i).first, selection.at(i).second, QModelIndex());
QMimeData *md = src.mimeData(selectedIndexes);
// do the drop
@@ -810,8 +832,8 @@ void tst_QAbstractItemModel::removeRows()
QVERIFY(rowsRemovedSpy.isValid());
QCOMPARE(model.removeRows(6, 4), true);
- QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
- QCOMPARE(rowsRemovedSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeRemovedSpy.size(), 1);
+ QCOMPARE(rowsRemovedSpy.size(), 1);
}
void tst_QAbstractItemModel::removeColumns()
@@ -825,8 +847,8 @@ void tst_QAbstractItemModel::removeColumns()
QVERIFY(columnsRemovedSpy.isValid());
QCOMPARE(model.removeColumns(6, 4), true);
- QCOMPARE(columnsAboutToBeRemovedSpy.count(), 1);
- QCOMPARE(columnsRemovedSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeRemovedSpy.size(), 1);
+ QCOMPARE(columnsRemovedSpy.size(), 1);
}
void tst_QAbstractItemModel::insertRows()
@@ -840,8 +862,8 @@ void tst_QAbstractItemModel::insertRows()
QVERIFY(rowsInsertedSpy.isValid());
QCOMPARE(model.insertRows(6, 4), true);
- QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1);
- QCOMPARE(rowsInsertedSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeInsertedSpy.size(), 1);
+ QCOMPARE(rowsInsertedSpy.size(), 1);
}
void tst_QAbstractItemModel::insertColumns()
@@ -855,8 +877,8 @@ void tst_QAbstractItemModel::insertColumns()
QVERIFY(columnsInsertedSpy.isValid());
QCOMPARE(model.insertColumns(6, 4), true);
- QCOMPARE(columnsAboutToBeInsertedSpy.count(), 1);
- QCOMPARE(columnsInsertedSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeInsertedSpy.size(), 1);
+ QCOMPARE(columnsInsertedSpy.size(), 1);
}
void tst_QAbstractItemModel::moveRows()
@@ -870,8 +892,8 @@ void tst_QAbstractItemModel::moveRows()
QVERIFY(rowsMovedSpy.isValid());
QCOMPARE(model.moveRows(QModelIndex(), 6, 4, QModelIndex(), 1), true);
- QCOMPARE(rowsAboutToBeMovedSpy.count(), 1);
- QCOMPARE(rowsMovedSpy.count(), 1);
+ QCOMPARE(rowsAboutToBeMovedSpy.size(), 1);
+ QCOMPARE(rowsMovedSpy.size(), 1);
}
void tst_QAbstractItemModel::moveColumns()
@@ -885,12 +907,12 @@ void tst_QAbstractItemModel::moveColumns()
QVERIFY(columnsMovedSpy.isValid());
QCOMPARE(model.moveColumns(QModelIndex(), 6, 4, QModelIndex(), 1), true);
- QCOMPARE(columnsAboutToBeMovedSpy.count(), 1);
- QCOMPARE(columnsMovedSpy.count(), 1);
+ QCOMPARE(columnsAboutToBeMovedSpy.size(), 1);
+ QCOMPARE(columnsMovedSpy.size(), 1);
QCOMPARE(model.moveColumn(QModelIndex(), 4, QModelIndex(), 1), true);
- QCOMPARE(columnsAboutToBeMovedSpy.count(), 2);
- QCOMPARE(columnsMovedSpy.count(), 2);
+ QCOMPARE(columnsAboutToBeMovedSpy.size(), 2);
+ QCOMPARE(columnsMovedSpy.size(), 2);
}
void tst_QAbstractItemModel::reset()
@@ -900,7 +922,7 @@ void tst_QAbstractItemModel::reset()
QSignalSpy resetSpy(&model, &QtTestModel::modelReset);
QVERIFY(resetSpy.isValid());
model.reset();
- QCOMPARE(resetSpy.count(), 1);
+ QCOMPARE(resetSpy.size(), 1);
}
void tst_QAbstractItemModel::complexChangesWithPersistent()
@@ -965,6 +987,27 @@ void tst_QAbstractItemModel::complexChangesWithPersistent()
QVERIFY(e[i] == model.index(2, i-2 , QModelIndex()));
}
+void tst_QAbstractItemModel::modelIndexComparisons()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QModelIndex>();
+ QTestPrivate::testEqualityOperatorsCompile<QPersistentModelIndex>();
+ QTestPrivate::testEqualityOperatorsCompile<QPersistentModelIndex, QModelIndex>();
+
+ QtTestModel model(3, 3);
+
+ QModelIndex mi11 = model.index(1, 1);
+ QModelIndex mi22 = model.index(2, 2);
+ QPersistentModelIndex pmi11 = mi11;
+ QPersistentModelIndex pmi22 = mi22;
+
+ QT_TEST_EQUALITY_OPS(mi11, mi11, true);
+ QT_TEST_EQUALITY_OPS(mi11, mi22, false);
+ QT_TEST_EQUALITY_OPS(pmi11, pmi11, true);
+ QT_TEST_EQUALITY_OPS(pmi11, pmi22, false);
+ QT_TEST_EQUALITY_OPS(pmi11, mi11, true);
+ QT_TEST_EQUALITY_OPS(pmi11, mi22, false);
+}
+
void tst_QAbstractItemModel::testMoveSameParentDown_data()
{
QTest::addColumn<int>("startRow");
@@ -1785,13 +1828,12 @@ class ModelWithCustomRole : public QStringListModel
{
Q_OBJECT
public:
- ModelWithCustomRole(QObject *parent = 0)
- : QStringListModel(parent)
- {
- QHash<int, QByteArray> roleNames_ = roleNames();
- roleNames_.insert(Qt::UserRole + 1, "custom");
- setRoleNames(roleNames_);
- }
+ using QStringListModel::QStringListModel;
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return {{Qt::UserRole + 1, QByteArrayLiteral("custom")}};
+ }
};
ListenerObject::ListenerObject(QAbstractProxyModel *parent)
@@ -1830,7 +1872,7 @@ void ListenerObject::slotAboutToBeReset()
void ListenerObject::slotReset()
{
- foreach (const QModelIndex &idx, m_persistentIndexes) {
+ for (const auto &idx : std::as_const(m_persistentIndexes)) {
QVERIFY(!idx.isValid());
}
}
@@ -1901,7 +1943,7 @@ public:
UserRole
};
- CustomRoleModel(QObject *parent = 0)
+ CustomRoleModel(QObject *parent = nullptr)
: QStringListModel(QStringList() << "a" << "b" << "c", parent)
{
}
@@ -1912,8 +1954,8 @@ public:
const QModelIndex bottom = index(2, 0);
emit dataChanged(top, bottom);
- emit dataChanged(top, bottom, QVector<int>() << Qt::ToolTipRole);
- emit dataChanged(top, bottom, QVector<int>() << Qt::ToolTipRole << Custom1);
+ emit dataChanged(top, bottom, QList<int>() << Qt::ToolTipRole);
+ emit dataChanged(top, bottom, QList<int>() << Qt::ToolTipRole << Custom1);
}
};
@@ -1935,8 +1977,8 @@ void tst_QAbstractItemModel::testDataChanged()
const QVariantList secondEmission = withRoles.at(1);
const QVariantList thirdEmission = withRoles.at(2);
- const QVector<int> secondRoles = secondEmission.at(2).value<QVector<int> >();
- const QVector<int> thirdRoles = thirdEmission.at(2).value<QVector<int> >();
+ const QList<int> secondRoles = secondEmission.at(2).value<QList<int> >();
+ const QList<int> thirdRoles = thirdEmission.at(2).value<QList<int> >();
QCOMPARE(secondRoles.size(), 1);
QVERIFY(secondRoles.contains(Qt::ToolTipRole));
@@ -1952,7 +1994,7 @@ class SignalArgumentChecker : public QObject
{
Q_OBJECT
public:
- SignalArgumentChecker(const QModelIndex &p1, const QModelIndex &p2, QObject *parent = 0)
+ SignalArgumentChecker(const QModelIndex &p1, const QModelIndex &p2, QObject *parent = nullptr)
: QObject(parent), m_p1(p1), m_p2(p2), m_p1Persistent(p1), m_p2Persistent(p2)
{
connect(p1.model(), SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>)), SLOT(layoutAboutToBeChanged(QList<QPersistentModelIndex>)));
@@ -2126,20 +2168,20 @@ class OverrideRoleNamesAndDragActions : public QStringListModel
{
Q_OBJECT
public:
- OverrideRoleNamesAndDragActions(QObject *parent = 0)
+ OverrideRoleNamesAndDragActions(QObject *parent = nullptr)
: QStringListModel(parent)
{
}
- QHash<int, QByteArray> roleNames() const
+ QHash<int, QByteArray> roleNames() const override
{
QHash<int, QByteArray> roles = QStringListModel::roleNames();
roles.insert(Qt::UserRole + 2, "custom");
return roles;
}
- Qt::DropActions supportedDragActions() const
+ Qt::DropActions supportedDragActions() const override
{
return QStringListModel::supportedDragActions() | Qt::MoveAction;
}
@@ -2165,7 +2207,7 @@ class OverrideDropActions : public QStringListModel
{
Q_OBJECT
public:
- OverrideDropActions(QObject *parent = 0)
+ OverrideDropActions(QObject *parent = nullptr)
: QStringListModel(parent)
{
}
@@ -2186,7 +2228,7 @@ class SignalConnectionTester : public QObject
{
Q_OBJECT
public:
- SignalConnectionTester(QObject *parent = 0)
+ SignalConnectionTester(QObject *parent = nullptr)
: QObject(parent), testPassed(false)
{
@@ -2356,5 +2398,135 @@ void tst_QAbstractItemModel::checkIndex()
QVERIFY(!model.checkIndex(topLevelIndex, QAbstractItemModel::CheckIndexOption::IndexIsValid));
}
+template <typename T>
+inline constexpr bool CanConvertToSpan = std::is_convertible_v<T, QModelRoleDataSpan>;
+
+void tst_QAbstractItemModel::modelRoleDataSpanConstruction()
+{
+ // Compile time test
+ static_assert(CanConvertToSpan<QModelRoleData &>);
+ static_assert(CanConvertToSpan<QModelRoleData (&)[123]>);
+ static_assert(CanConvertToSpan<QVector<QModelRoleData> &>);
+ static_assert(CanConvertToSpan<QVarLengthArray<QModelRoleData> &>);
+ static_assert(CanConvertToSpan<std::vector<QModelRoleData> &>);
+ static_assert(CanConvertToSpan<std::array<QModelRoleData, 123> &>);
+
+ static_assert(!CanConvertToSpan<QModelRoleData>);
+ static_assert(!CanConvertToSpan<QVector<QModelRoleData>>);
+ static_assert(!CanConvertToSpan<const QVector<QModelRoleData> &>);
+ static_assert(!CanConvertToSpan<std::vector<QModelRoleData>>);
+ static_assert(!CanConvertToSpan<std::deque<QModelRoleData>>);
+ static_assert(!CanConvertToSpan<std::deque<QModelRoleData> &>);
+ static_assert(!CanConvertToSpan<std::list<QModelRoleData> &>);
+ static_assert(!CanConvertToSpan<std::list<QModelRoleData>>);
+}
+
+void tst_QAbstractItemModel::modelRoleDataSpan()
+{
+ QModelRoleData data[3] = {
+ QModelRoleData(Qt::DisplayRole),
+ QModelRoleData(Qt::DecorationRole),
+ QModelRoleData(Qt::EditRole)
+ };
+ QModelRoleData *dataPtr = data;
+
+ QModelRoleDataSpan span(data);
+
+ QCOMPARE(span.size(), 3);
+ QCOMPARE(span.length(), 3);
+ QCOMPARE(span.data(), dataPtr);
+ QCOMPARE(span.begin(), dataPtr);
+ QCOMPARE(span.end(), dataPtr + 3);
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(span[i].role(), data[i].role());
+
+ data[0].setData(42);
+ data[1].setData(QStringLiteral("a string"));
+ data[2].setData(123.5);
+
+ QCOMPARE(span.dataForRole(Qt::DisplayRole)->toInt(), 42);
+ QCOMPARE(span.dataForRole(Qt::DecorationRole)->toString(), "a string");
+ QCOMPARE(span.dataForRole(Qt::EditRole)->toDouble(), 123.5);
+}
+
+// model implementing data(), but not multiData(); check that the
+// default implementation of multiData() does the right thing
+class NonMultiDataRoleModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ int rowCount(const QModelIndex &) const override
+ {
+ return 1000;
+ }
+
+ // We handle roles <= 10. All such roles return a QVariant(int) containing
+ // the same value as the role, except for 10 which returns a string.
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ Q_ASSERT(checkIndex(index, CheckIndexOption::IndexIsValid));
+
+ if (role < 10)
+ return QVariant::fromValue(role);
+ else if (role == 10)
+ return QVariant::fromValue(QStringLiteral("Hello!"));
+
+ return QVariant();
+ }
+};
+
+void tst_QAbstractItemModel::multiData()
+{
+ QModelRoleData data[] = {
+ QModelRoleData(1),
+ QModelRoleData(42),
+ QModelRoleData(5),
+ QModelRoleData(2),
+ QModelRoleData(12),
+ QModelRoleData(2),
+ QModelRoleData(10),
+ QModelRoleData(-123)
+ };
+
+ QModelRoleDataSpan span(data);
+
+ for (const auto &roledata : span)
+ QVERIFY(roledata.data().isNull());
+
+ NonMultiDataRoleModel model;
+ const QModelIndex index = model.index(0, 0);
+ QVERIFY(index.isValid());
+
+ const auto check = [&]() {
+ for (auto &roledata : span) {
+ const auto role = roledata.role();
+ if (role < 10) {
+ QVERIFY(!roledata.data().isNull());
+ QVERIFY(roledata.data().userType() == qMetaTypeId<int>());
+ QCOMPARE(roledata.data().toInt(), role);
+ } else if (role == 10) {
+ QVERIFY(!roledata.data().isNull());
+ QVERIFY(roledata.data().userType() == qMetaTypeId<QString>());
+ QCOMPARE(roledata.data().toString(), QStringLiteral("Hello!"));
+ } else {
+ QVERIFY(roledata.data().isNull());
+ }
+ }
+ };
+
+ model.multiData(index, span);
+ check();
+
+ model.multiData(index, span);
+ check();
+
+ for (auto &roledata : span)
+ roledata.clearData();
+
+ model.multiData(index, span);
+ check();
+}
+
QTEST_MAIN(tst_QAbstractItemModel)
#include "tst_qabstractitemmodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qabstractproxymodel/CMakeLists.txt
new file mode 100644
index 0000000000..8799814324
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qabstractproxymodel/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qabstractproxymodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractproxymodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qabstractproxymodel
+ SOURCES
+ tst_qabstractproxymodel.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/qabstractproxymodel.pro b/tests/auto/corelib/itemmodels/qabstractproxymodel/qabstractproxymodel.pro
deleted file mode 100644
index 19aec43072..0000000000
--- a/tests/auto/corelib/itemmodels/qabstractproxymodel/qabstractproxymodel.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qabstractproxymodel
-QT += testlib
-SOURCES += tst_qabstractproxymodel.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp
index 886941bff6..62512889fd 100644
--- a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
#include <qabstractproxymodel.h>
#include <QItemSelection>
#include <qstandarditemmodel.h>
@@ -43,6 +19,7 @@ private slots:
void flags();
void headerData_data();
void headerData();
+ void headerDataInBounds();
void itemData_data();
void itemData();
void mapFromSource_data();
@@ -60,6 +37,7 @@ private slots:
void testRoleNames();
void testSwappingRowsProxy();
void testDragAndDrop();
+ void sourceModelBinding();
};
// Subclass that exposes the protected functions.
@@ -67,29 +45,29 @@ class SubQAbstractProxyModel : public QAbstractProxyModel
{
public:
// QAbstractProxyModel::mapFromSource is a pure virtual function.
- QModelIndex mapFromSource(QModelIndex const& sourceIndex) const
+ QModelIndex mapFromSource(QModelIndex const& sourceIndex) const override
{ Q_UNUSED(sourceIndex); return QModelIndex(); }
// QAbstractProxyModel::mapToSource is a pure virtual function.
- QModelIndex mapToSource(QModelIndex const& proxyIndex) const
+ QModelIndex mapToSource(QModelIndex const& proxyIndex) const override
{ Q_UNUSED(proxyIndex); return QModelIndex(); }
- QModelIndex index(int, int, const QModelIndex&) const
+ QModelIndex index(int, int, const QModelIndex&) const override
{
return QModelIndex();
}
- QModelIndex parent(const QModelIndex&) const
+ QModelIndex parent(const QModelIndex&) const override
{
return QModelIndex();
}
- int rowCount(const QModelIndex&) const
+ int rowCount(const QModelIndex&) const override
{
return 0;
}
- int columnCount(const QModelIndex&) const
+ int columnCount(const QModelIndex&) const override
{
return 0;
}
@@ -136,7 +114,7 @@ void tst_QAbstractProxyModel::flags_data()
{
QTest::addColumn<QModelIndex>("index");
QTest::addColumn<Qt::ItemFlags>("flags");
- QTest::newRow("null") << QModelIndex() << (Qt::ItemFlags)0;
+ QTest::newRow("null") << QModelIndex() << Qt::ItemFlags{};
}
// public Qt::ItemFlags flags(QModelIndex const& index) const
@@ -172,6 +150,133 @@ void tst_QAbstractProxyModel::headerData()
QCOMPARE(model.headerData(section, orientation, role), headerData);
}
+class SimpleTableReverseColumnsProxy : public QAbstractProxyModel
+{
+public:
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
+ {
+ if (parent.isValid())
+ return {};
+
+ if (row < 0 || row >= rowCount() || column < 0 || column >= columnCount())
+ qFatal("error"); // cannot QFAIL here
+
+ return createIndex(row, column);
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ if (parent.isValid())
+ return 0;
+ return sourceModel()->rowCount();
+ }
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ if (parent.isValid())
+ return 0;
+ return sourceModel()->columnCount();
+ }
+
+ QModelIndex parent(const QModelIndex &) const override
+ {
+ return QModelIndex();
+ }
+
+ QModelIndex mapToSource(const QModelIndex &idx) const override
+ {
+ if (!idx.isValid())
+ return QModelIndex();
+ return sourceModel()->index(idx.row(), columnCount() - 1 - idx.column());
+ }
+
+ QModelIndex mapFromSource(const QModelIndex &idx) const override
+ {
+ if (idx.parent().isValid())
+ return QModelIndex();
+ return createIndex(idx.row(), columnCount() - 1 - idx.column());
+ }
+};
+
+void tst_QAbstractProxyModel::headerDataInBounds()
+{
+ QStandardItemModel qsim(0, 5);
+ qsim.setHorizontalHeaderLabels({"Col1", "Col2", "Col3", "Col4", "Col5"});
+
+ SimpleTableReverseColumnsProxy proxy;
+ QSignalSpy headerDataChangedSpy(&proxy, &QAbstractItemModel::headerDataChanged);
+ QVERIFY(headerDataChangedSpy.isValid());
+ proxy.setSourceModel(&qsim);
+ QCOMPARE(proxy.rowCount(), 0);
+ QCOMPARE(proxy.columnCount(), 5);
+
+ for (int i = 0; i < proxy.columnCount(); ++i) {
+ QString expected = QString("Col%1").arg(i + 1);
+ QCOMPARE(proxy.headerData(i, Qt::Horizontal).toString(), expected);
+ }
+
+ qsim.appendRow({
+ new QStandardItem("A"),
+ new QStandardItem("B"),
+ new QStandardItem("C"),
+ new QStandardItem("D"),
+ new QStandardItem("E")
+ });
+
+ QCOMPARE(proxy.rowCount(), 1);
+ QCOMPARE(proxy.columnCount(), 5);
+ QTRY_COMPARE(headerDataChangedSpy.size(), 1);
+ QCOMPARE(headerDataChangedSpy[0][0].value<Qt::Orientation>(), Qt::Horizontal);
+ QCOMPARE(headerDataChangedSpy[0][1].value<int>(), 0);
+ QCOMPARE(headerDataChangedSpy[0][2].value<int>(), 4);
+
+ for (int i = 0; i < proxy.columnCount(); ++i) {
+ QString expected = QString("Col%1").arg(proxy.columnCount() - i);
+ QCOMPARE(proxy.headerData(i, Qt::Horizontal).toString(), expected);
+ }
+
+ qsim.appendRow({
+ new QStandardItem("A"),
+ new QStandardItem("B"),
+ new QStandardItem("C"),
+ new QStandardItem("D"),
+ new QStandardItem("E")
+ });
+ QCOMPARE(proxy.rowCount(), 2);
+ QCOMPARE(proxy.columnCount(), 5);
+ QCOMPARE(headerDataChangedSpy.size(), 1);
+
+ for (int i = 0; i < proxy.columnCount(); ++i) {
+ QString expected = QString("Col%1").arg(proxy.columnCount() - i);
+ QCOMPARE(proxy.headerData(i, Qt::Horizontal).toString(), expected);
+ }
+
+ QVERIFY(qsim.removeRows(0, 1));
+
+ QCOMPARE(proxy.rowCount(), 1);
+ QCOMPARE(proxy.columnCount(), 5);
+ QCOMPARE(headerDataChangedSpy.size(), 1);
+
+ for (int i = 0; i < proxy.columnCount(); ++i) {
+ QString expected = QString("Col%1").arg(proxy.columnCount() - i);
+ QCOMPARE(proxy.headerData(i, Qt::Horizontal).toString(), expected);
+ }
+
+ QVERIFY(qsim.removeRows(0, 1));
+
+ QCOMPARE(proxy.rowCount(), 0);
+ QCOMPARE(proxy.columnCount(), 5);
+ QTRY_COMPARE(headerDataChangedSpy.size(), 2);
+ QCOMPARE(headerDataChangedSpy[1][0].value<Qt::Orientation>(), Qt::Horizontal);
+ QCOMPARE(headerDataChangedSpy[1][1].value<int>(), 0);
+ QCOMPARE(headerDataChangedSpy[1][2].value<int>(), 4);
+
+ for (int i = 0; i < proxy.columnCount(); ++i) {
+ QString expected = QString("Col%1").arg(i + 1);
+ QCOMPARE(proxy.headerData(i, Qt::Horizontal).toString(), expected);
+ }
+}
+
void tst_QAbstractProxyModel::itemData_data()
{
QTest::addColumn<QModelIndex>("index");
@@ -186,7 +291,7 @@ void tst_QAbstractProxyModel::itemData()
QFETCH(QModelIndex, index);
QFETCH(int, count);
SubQAbstractProxyModel model;
- QCOMPARE(model.itemData(index).count(), count);
+ QCOMPARE(model.itemData(index).size(), count);
}
void tst_QAbstractProxyModel::mapFromSource_data()
@@ -313,11 +418,12 @@ public:
CustomRole2
};
- StandardItemModelWithCustomRoleNames() {
- QHash<int, QByteArray> _roleNames = roleNames();
- _roleNames.insert(CustomRole1, "custom1");
- _roleNames.insert(CustomRole2, "custom2");
- setRoleNames(_roleNames);
+ QHash<int, QByteArray> roleNames() const override
+ {
+ auto result = QStandardItemModel::roleNames();
+ result.insert(CustomRole1, QByteArrayLiteral("custom1"));
+ result.insert(CustomRole2, QByteArrayLiteral("custom2"));
+ return result;
}
};
@@ -329,11 +435,10 @@ public:
AnotherCustomRole2
};
- AnotherStandardItemModelWithCustomRoleNames() {
- QHash<int, QByteArray> _roleNames = roleNames();
- _roleNames.insert(AnotherCustomRole1, "another_custom1");
- _roleNames.insert(AnotherCustomRole2, "another_custom2");
- setRoleNames(_roleNames);
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return {{AnotherCustomRole1, QByteArrayLiteral("another_custom1")},
+ {AnotherCustomRole2, QByteArrayLiteral("another_custom2")}};
}
};
@@ -399,7 +504,7 @@ class SwappingProxy : public QAbstractProxyModel
}
}
public:
- virtual QModelIndex index(int row, int column, const QModelIndex &parentIdx) const
+ virtual QModelIndex index(int row, int column, const QModelIndex &parentIdx) const override
{
if (!sourceModel())
return QModelIndex();
@@ -412,28 +517,28 @@ public:
return createIndex(row, column, parentIdx.internalPointer());
}
- virtual QModelIndex parent(const QModelIndex &parentIdx) const
+ virtual QModelIndex parent(const QModelIndex &parentIdx) const override
{
// well, we're a 2D model
Q_UNUSED(parentIdx);
return QModelIndex();
}
- virtual int rowCount(const QModelIndex &parentIdx) const
+ virtual int rowCount(const QModelIndex &parentIdx) const override
{
if (parentIdx.isValid() || !sourceModel())
return 0;
return sourceModel()->rowCount();
}
- virtual int columnCount(const QModelIndex &parentIdx) const
+ virtual int columnCount(const QModelIndex &parentIdx) const override
{
if (parentIdx.isValid() || !sourceModel())
return 0;
return sourceModel()->rowCount();
}
- virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
+ virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
{
if (!proxyIndex.isValid())
return QModelIndex();
@@ -443,7 +548,7 @@ public:
return sourceModel()->index(swapRow(proxyIndex.row()), proxyIndex.column(), QModelIndex());
}
- virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
+ virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
{
if (!sourceIndex.isValid())
return QModelIndex();
@@ -485,9 +590,9 @@ void tst_QAbstractProxyModel::testSwappingRowsProxy()
class StandardItemModelWithCustomDragAndDrop : public QStandardItemModel
{
public:
- QStringList mimeTypes() const { return QStringList() << QStringLiteral("foo/mimetype"); }
- Qt::DropActions supportedDragActions() const { return Qt::CopyAction | Qt::LinkAction; }
- Qt::DropActions supportedDropActions() const { return Qt::MoveAction; }
+ QStringList mimeTypes() const override { return QStringList() << QStringLiteral("foo/mimetype"); }
+ Qt::DropActions supportedDragActions() const override { return Qt::CopyAction | Qt::LinkAction; }
+ Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; }
};
void tst_QAbstractProxyModel::testDragAndDrop()
@@ -500,6 +605,34 @@ void tst_QAbstractProxyModel::testDragAndDrop()
QCOMPARE(proxy.supportedDropActions(), sourceModel.supportedDropActions());
}
+void tst_QAbstractProxyModel::sourceModelBinding()
+{
+ SubQAbstractProxyModel proxy;
+ QStandardItemModel model1;
+ QStandardItemModel model2;
+ QTestPrivate::testReadWritePropertyBasics<SubQAbstractProxyModel, QAbstractItemModel *>(
+ proxy, &model1, &model2, "sourceModel");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed model - model test");
+ return;
+ }
+
+ proxy.setSourceModel(&model2);
+ QTestPrivate::testReadWritePropertyBasics<SubQAbstractProxyModel, QAbstractItemModel *>(
+ proxy, &model1, nullptr, "sourceModel");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed model - nullptr test");
+ return;
+ }
+
+ proxy.setSourceModel(&model1);
+ QTestPrivate::testReadWritePropertyBasics<SubQAbstractProxyModel, QAbstractItemModel *>(
+ proxy, nullptr, &model2, "sourceModel");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed nullptr - model test");
+ return;
+ }
+}
QTEST_MAIN(tst_QAbstractProxyModel)
#include "tst_qabstractproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/CMakeLists.txt
new file mode 100644
index 0000000000..37a74470af
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qconcatenatetablesproxymodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qconcatenatetablesproxymodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qconcatenatetablesproxymodel
+ SOURCES
+ tst_qconcatenatetablesproxymodel.cpp
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
new file mode 100644
index 0000000000..989a57b30f
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qconcatenatetablesproxymodel/tst_qconcatenatetablesproxymodel.cpp
@@ -0,0 +1,867 @@
+// Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QSignalSpy>
+#include <QSortFilterProxyModel>
+#include <QTest>
+#include <QStandardItemModel>
+#include <QIdentityProxyModel>
+#include <QItemSelectionModel>
+#include <QMimeData>
+#include <QStringListModel>
+#include <QAbstractItemModelTester>
+
+#include <qconcatenatetablesproxymodel.h>
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+// Extracts a full row from a model as a string
+// Works best if every cell contains only one character
+static QString extractRowTexts(QAbstractItemModel *model, int row, const QModelIndex &parent = QModelIndex())
+{
+ QString result;
+ const int colCount = model->columnCount();
+ for (int col = 0; col < colCount; ++col) {
+ const QString txt = model->index(row, col, parent).data().toString();
+ result += txt.isEmpty() ? QStringLiteral(" ") : txt;
+ }
+ return result;
+}
+
+// Extracts a full column from a model as a string
+// Works best if every cell contains only one character
+static QString extractColumnTexts(QAbstractItemModel *model, int column, const QModelIndex &parent = QModelIndex())
+{
+ QString result;
+ const int rowCount = model->rowCount();
+ for (int row = 0; row < rowCount; ++row) {
+ const QString txt = model->index(row, column, parent).data().toString();
+ result += txt.isEmpty() ? QStringLiteral(" ") : txt;
+ }
+ return result;
+}
+
+static QString rowSpyToText(const QSignalSpy &spy)
+{
+ if (!spy.isValid())
+ return QStringLiteral("THE SIGNALSPY IS INVALID!");
+ QString str;
+ for (int i = 0; i < spy.size(); ++i) {
+ str += spy.at(i).at(1).toString() + QLatin1Char(',') + spy.at(i).at(2).toString();
+ if (i + 1 < spy.size())
+ str += QLatin1Char(';');
+ }
+ return str;
+}
+
+class tst_QConcatenateTablesProxyModel : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void init();
+ void shouldAggregateTwoModelsCorrectly();
+ void shouldAggregateThenRemoveTwoEmptyModelsCorrectly();
+ void shouldAggregateTwoEmptyModelsWhichThenGetFilled();
+ void shouldHandleDataChanged();
+ void shouldHandleSetData();
+ void shouldHandleSetItemData();
+ void shouldHandleRowInsertionAndRemoval();
+ void shouldAggregateAnotherModelThenRemoveModels();
+ void shouldUseSmallestColumnCount();
+ void shouldIncreaseColumnCountWhenRemovingFirstModel();
+ void shouldHandleColumnInsertionAndRemoval();
+ void shouldPropagateLayoutChanged();
+ void shouldReactToModelReset();
+ void shouldUpdateColumnsOnModelReset();
+ void shouldPropagateDropOnItem_data();
+ void shouldPropagateDropOnItem();
+ void shouldPropagateDropBetweenItems();
+ void shouldPropagateDropBetweenItemsAtModelBoundary();
+ void shouldPropagateDropAfterLastRow_data();
+ void shouldPropagateDropAfterLastRow();
+ void qtbug91788();
+ void qtbug91878();
+ void createPersistentOnLayoutAboutToBeChanged();
+private:
+ QStandardItemModel mod;
+ QStandardItemModel mod2;
+ QStandardItemModel mod3;
+};
+
+void tst_QConcatenateTablesProxyModel::init()
+{
+ // Prepare some source models to use later on
+ mod.clear();
+ mod.appendRow({ new QStandardItem(QStringLiteral("A")), new QStandardItem(QStringLiteral("B")), new QStandardItem(QStringLiteral("C")) });
+ mod.setHorizontalHeaderLabels(QStringList() << QStringLiteral("H1") << QStringLiteral("H2") << QStringLiteral("H3"));
+ mod.setVerticalHeaderLabels(QStringList() << QStringLiteral("One"));
+
+ mod2.clear();
+ mod2.appendRow({ new QStandardItem(QStringLiteral("D")), new QStandardItem(QStringLiteral("E")), new QStandardItem(QStringLiteral("F")) });
+ mod2.setHorizontalHeaderLabels(QStringList() << QStringLiteral("H1") << QStringLiteral("H2") << QStringLiteral("H3"));
+ mod2.setVerticalHeaderLabels(QStringList() << QStringLiteral("Two"));
+
+ mod3.clear();
+ mod3.appendRow({ new QStandardItem(QStringLiteral("1")), new QStandardItem(QStringLiteral("2")), new QStandardItem(QStringLiteral("3")) });
+ mod3.appendRow({ new QStandardItem(QStringLiteral("4")), new QStandardItem(QStringLiteral("5")), new QStandardItem(QStringLiteral("6")) });
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateTwoModelsCorrectly()
+{
+ // Given a combining proxy
+ QConcatenateTablesProxyModel pm;
+
+ // When adding two source models
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ // Then the proxy should show 2 rows
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // ... and correct headers
+ QCOMPARE(pm.headerData(0, Qt::Horizontal).toString(), QStringLiteral("H1"));
+ QCOMPARE(pm.headerData(1, Qt::Horizontal).toString(), QStringLiteral("H2"));
+ QCOMPARE(pm.headerData(2, Qt::Horizontal).toString(), QStringLiteral("H3"));
+ QCOMPARE(pm.headerData(0, Qt::Vertical).toString(), QStringLiteral("One"));
+ QCOMPARE(pm.headerData(1, Qt::Vertical).toString(), QStringLiteral("Two"));
+
+ QVERIFY(!pm.canFetchMore(QModelIndex()));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateThenRemoveTwoEmptyModelsCorrectly()
+{
+ // Given a combining proxy
+ QConcatenateTablesProxyModel pm;
+
+ // When adding two empty models
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QIdentityProxyModel i1, i2;
+ pm.addSourceModel(&i1);
+ pm.addSourceModel(&i2);
+
+ // Then the proxy should still be empty (and no signals emitted)
+ QCOMPARE(pm.rowCount(), 0);
+ QCOMPARE(pm.columnCount(), 0);
+ QCOMPARE(rowATBISpy.size(), 0);
+ QCOMPARE(rowInsertedSpy.size(), 0);
+
+ // When removing the empty models
+ pm.removeSourceModel(&i1);
+ pm.removeSourceModel(&i2);
+
+ // Then the proxy should still be empty (and no signals emitted)
+ QCOMPARE(pm.rowCount(), 0);
+ QCOMPARE(pm.columnCount(), 0);
+ QCOMPARE(rowATBRSpy.size(), 0);
+ QCOMPARE(rowRemovedSpy.size(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateTwoEmptyModelsWhichThenGetFilled()
+{
+ // Given a combining proxy with two empty models
+ QConcatenateTablesProxyModel pm;
+ QIdentityProxyModel i1, i2;
+ pm.addSourceModel(&i1);
+ pm.addSourceModel(&i2);
+
+ // When filling them afterwards
+ i1.setSourceModel(&mod);
+ i2.setSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ // Then the proxy should show 2 rows
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // ... and correct headers
+ QCOMPARE(pm.headerData(0, Qt::Horizontal).toString(), QStringLiteral("H1"));
+ QCOMPARE(pm.headerData(1, Qt::Horizontal).toString(), QStringLiteral("H2"));
+ QCOMPARE(pm.headerData(2, Qt::Horizontal).toString(), QStringLiteral("H3"));
+ QCOMPARE(pm.headerData(0, Qt::Vertical).toString(), QStringLiteral("One"));
+ QCOMPARE(pm.headerData(1, Qt::Vertical).toString(), QStringLiteral("Two"));
+
+ QVERIFY(!pm.canFetchMore(QModelIndex()));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleDataChanged()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When a cell in a source model changes
+ mod.item(0, 0)->setData("a", Qt::EditRole);
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("aBC"));
+
+ // Same test with the other model
+ mod2.item(0, 2)->setData("f", Qt::EditRole);
+
+ QCOMPARE(dataChangedSpy.size(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEf"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleSetData()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When changing a cell using setData
+ pm.setData(pm.index(0, 0), "a");
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("aBC"));
+
+ // Same test with the other model
+ pm.setData(pm.index(1, 2), "f");
+
+ QCOMPARE(dataChangedSpy.size(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEf"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleSetItemData()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ // When changing a cell using setData
+ pm.setItemData(pm.index(0, 0), QMap<int, QVariant>{ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("X")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 88) });
+
+ // Then the change should be notified to the proxy
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("XBC"));
+ QCOMPARE(pm.index(0, 0).data(Qt::UserRole).toInt(), 88);
+
+ // Same test with the other model
+ pm.setItemData(pm.index(1, 2), QMap<int, QVariant>{ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("Y")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 89) });
+
+ QCOMPARE(dataChangedSpy.size(), 2);
+ QCOMPARE(dataChangedSpy.at(1).at(0).toModelIndex(), pm.index(1, 2));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEY"));
+ QCOMPARE(pm.index(1, 2).data(Qt::UserRole).toInt(), 89);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleRowInsertionAndRemoval()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+ // When a source model inserts a new row
+ QList<QStandardItem *> row;
+ row.append(new QStandardItem(QStringLiteral("1")));
+ row.append(new QStandardItem(QStringLiteral("2")));
+ row.append(new QStandardItem(QStringLiteral("3")));
+ mod2.insertRow(0, row);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(rowATBISpy), QStringLiteral("1,1"));
+ QCOMPARE(rowSpyToText(rowInsertedSpy), QStringLiteral("1,1"));
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When removing that row
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ mod2.removeRow(0);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowATBRSpy.size(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.size(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // When removing the last row from mod2
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ mod2.removeRow(0);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowATBRSpy.size(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.size(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldAggregateAnotherModelThenRemoveModels()
+{
+ // Given two models combined, and a third model
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+
+ // When adding the new source model
+ pm.addSourceModel(&mod3);
+
+ // Then the proxy should notify its users about the two rows inserted
+ QCOMPARE(rowSpyToText(rowATBISpy), QStringLiteral("2,3"));
+ QCOMPARE(rowSpyToText(rowInsertedSpy), QStringLiteral("2,3"));
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("456"));
+
+ // When removing that source model again
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ pm.removeSourceModel(&mod3);
+
+ // Then the proxy should notify its users about the row removed
+ QCOMPARE(rowATBRSpy.size(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 2);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 3);
+ QCOMPARE(rowRemovedSpy.size(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 2);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 3);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // When removing model 2
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ pm.removeSourceModel(&mod2);
+ QCOMPARE(rowATBRSpy.size(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.size(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 1);
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+
+ // When removing model 1
+ rowATBRSpy.clear();
+ rowRemovedSpy.clear();
+ pm.removeSourceModel(&mod);
+ QCOMPARE(rowATBRSpy.size(), 1);
+ QCOMPARE(rowATBRSpy.at(0).at(1).toInt(), 0);
+ QCOMPARE(rowATBRSpy.at(0).at(2).toInt(), 0);
+ QCOMPARE(rowRemovedSpy.size(), 1);
+ QCOMPARE(rowRemovedSpy.at(0).at(1).toInt(), 0);
+ QCOMPARE(rowRemovedSpy.at(0).at(2).toInt(), 0);
+ QCOMPARE(pm.rowCount(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldUseSmallestColumnCount()
+{
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ pm.addSourceModel(&mod2);
+ mod2.setColumnCount(1);
+ pm.addSourceModel(&mod3);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(pm.columnCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("A"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("D"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("1"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("4"));
+
+ const QModelIndex indexA = pm.mapFromSource(mod.index(0, 0));
+ QVERIFY(indexA.isValid());
+ QCOMPARE(indexA, pm.index(0, 0));
+
+ const QModelIndex indexB = pm.mapFromSource(mod.index(0, 1));
+ QVERIFY(!indexB.isValid());
+
+ const QModelIndex indexD = pm.mapFromSource(mod2.index(0, 0));
+ QVERIFY(indexD.isValid());
+ QCOMPARE(indexD, pm.index(1, 0));
+
+ // Test setData in an ignored column (QTBUG-91253)
+ QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+ mod.setData(mod.index(0, 1), "b");
+ QCOMPARE(dataChangedSpy.size(), 0);
+
+ // Test dataChanged across all columns, some visible, some ignored
+ mod.dataChanged(mod.index(0, 0), mod.index(0, 2));
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(dataChangedSpy.at(0).at(0).toModelIndex(), pm.index(0, 0));
+ QCOMPARE(dataChangedSpy.at(0).at(1).toModelIndex(), pm.index(0, 0));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldIncreaseColumnCountWhenRemovingFirstModel()
+{
+ // Given a model with 2 columns and one with 3 columns
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+ mod.setColumnCount(2);
+ pm.addSourceModel(&mod2);
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 2);
+
+ QSignalSpy colATBISpy(&pm, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy colInsertedSpy(&pm, SIGNAL(columnsInserted(QModelIndex,int,int)));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+
+ // When removing the first source model
+ pm.removeSourceModel(&mod);
+
+ // Then the proxy should notify its users about the row removed, and the column added
+ QCOMPARE(pm.rowCount(), 1);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(rowSpyToText(rowATBRSpy), QStringLiteral("0,0"));
+ QCOMPARE(rowSpyToText(rowRemovedSpy), QStringLiteral("0,0"));
+ QCOMPARE(rowSpyToText(colATBISpy), QStringLiteral("2,2"));
+ QCOMPARE(rowSpyToText(colInsertedSpy), QStringLiteral("2,2"));
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("DEF"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldHandleColumnInsertionAndRemoval()
+{
+ // Given two models combined, one with 2 columns and one with 3
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+ mod.setColumnCount(2);
+ pm.addSourceModel(&mod2);
+ QSignalSpy colATBISpy(&pm, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy colInsertedSpy(&pm, SIGNAL(columnsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+
+ // When the first source model inserts a new column
+ QCOMPARE(mod.columnCount(), 2);
+ mod.setColumnCount(3);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(colATBISpy), QStringLiteral("2,2"));
+ QCOMPARE(rowSpyToText(colInsertedSpy), QStringLiteral("2,2"));
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("AB "));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+
+ // And when removing two columns
+ mod.setColumnCount(1);
+
+ // Then the proxy should notify its users and show changes
+ QCOMPARE(rowSpyToText(colATBRSpy), QStringLiteral("1,2"));
+ QCOMPARE(rowSpyToText(colRemovedSpy), QStringLiteral("1,2"));
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(pm.columnCount(), 1);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("A"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("D"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateLayoutChanged()
+{
+ // Given two source models, the second one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+
+ // And a selection (row 1)
+ QItemSelectionModel selection(&pm);
+ selection.select(pm.index(1, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ const QModelIndexList lst = selection.selectedIndexes();
+ QCOMPARE(lst.size(), 3);
+ for (int col = 0; col < lst.size(); ++col) {
+ QCOMPARE(lst.at(col).row(), 1);
+ QCOMPARE(lst.at(col).column(), col);
+ }
+
+ QSignalSpy layoutATBCSpy(&pm, SIGNAL(layoutAboutToBeChanged()));
+ QSignalSpy layoutChangedSpy(&pm, SIGNAL(layoutChanged()));
+
+ // When changing the sorting in the QSFPM
+ qsfpm.sort(0, Qt::DescendingOrder);
+
+ // Then the proxy should emit the layoutChanged signals, and show re-sorted data
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(layoutATBCSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+
+ // And the selection should be updated accordingly (it became row 2)
+ const QModelIndexList lstAfter = selection.selectedIndexes();
+ QCOMPARE(lstAfter.size(), 3);
+ for (int col = 0; col < lstAfter.size(); ++col) {
+ QCOMPARE(lstAfter.at(col).row(), 2);
+ QCOMPARE(lstAfter.at(col).column(), col);
+ }
+}
+
+void tst_QConcatenateTablesProxyModel::shouldReactToModelReset()
+{
+ // Given two source models, the second one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+ QSignalSpy modelATBResetSpy(&pm, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy modelResetSpy(&pm, SIGNAL(modelReset()));
+
+ // When changing the source model of the QSFPM
+ qsfpm.setSourceModel(&mod2);
+
+ // Then the proxy should emit the reset signals, and show the new data
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("ABC"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(rowATBRSpy.size(), 0);
+ QCOMPARE(rowRemovedSpy.size(), 0);
+ QCOMPARE(rowATBISpy.size(), 0);
+ QCOMPARE(rowInsertedSpy.size(), 0);
+ QCOMPARE(colATBRSpy.size(), 0);
+ QCOMPARE(colRemovedSpy.size(), 0);
+ QCOMPARE(modelATBResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldUpdateColumnsOnModelReset()
+{
+ // Given two source models, the first one being a QSFPM
+ QConcatenateTablesProxyModel pm;
+
+ QSortFilterProxyModel qsfpm;
+ qsfpm.setSourceModel(&mod3);
+ pm.addSourceModel(&qsfpm);
+ pm.addSourceModel(&mod);
+ QAbstractItemModelTester modelTest(&pm, this);
+
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("ABC"));
+
+ // ... and a model with only 2 columns
+ QStandardItemModel mod2Columns;
+ mod2Columns.appendRow({ new QStandardItem(QStringLiteral("W")), new QStandardItem(QStringLiteral("X")) });
+
+ QSignalSpy rowATBRSpy(&pm, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy rowRemovedSpy(&pm, SIGNAL(rowsRemoved(QModelIndex,int,int)));
+ QSignalSpy rowATBISpy(&pm, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
+ QSignalSpy rowInsertedSpy(&pm, SIGNAL(rowsInserted(QModelIndex,int,int)));
+ QSignalSpy colATBRSpy(&pm, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
+ QSignalSpy colRemovedSpy(&pm, SIGNAL(columnsRemoved(QModelIndex,int,int)));
+ QSignalSpy modelATBResetSpy(&pm, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy modelResetSpy(&pm, SIGNAL(modelReset()));
+
+ // When changing the source model of the QSFPM
+ qsfpm.setSourceModel(&mod2Columns);
+
+ // Then the proxy should reset, and show the new data
+ QCOMPARE(modelATBResetSpy.size(), 1);
+ QCOMPARE(modelResetSpy.size(), 1);
+ QCOMPARE(rowATBRSpy.size(), 0);
+ QCOMPARE(rowRemovedSpy.size(), 0);
+ QCOMPARE(rowATBISpy.size(), 0);
+ QCOMPARE(rowInsertedSpy.size(), 0);
+ QCOMPARE(colATBRSpy.size(), 0);
+ QCOMPARE(colRemovedSpy.size(), 0);
+
+ QCOMPARE(pm.rowCount(), 2);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("WX"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("AB"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropOnItem_data()
+{
+ QTest::addColumn<int>("sourceRow");
+ QTest::addColumn<int>("destRow");
+ QTest::addColumn<QString>("expectedResult");
+
+ QTest::newRow("0-3") << 0 << 3 << QStringLiteral("ABCA");
+ QTest::newRow("1-2") << 1 << 2 << QStringLiteral("ABBD");
+ QTest::newRow("2-1") << 2 << 1 << QStringLiteral("ACCD");
+ QTest::newRow("3-0") << 3 << 0 << QStringLiteral("DBCD");
+
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropOnItem()
+{
+ // Given two source models who handle drops
+
+ // Note: QStandardItemModel handles drop onto items by inserting child rows,
+ // which is good for QTreeView but not for QTableView or QConcatenateTablesProxyModel.
+ // So we use QStringListModel here instead.
+ QConcatenateTablesProxyModel pm;
+ QStringListModel model1({QStringLiteral("A"), QStringLiteral("B")});
+ QStringListModel model2({QStringLiteral("C"), QStringLiteral("D")});
+ pm.addSourceModel(&model1);
+ pm.addSourceModel(&model2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(extractColumnTexts(&pm, 0), QStringLiteral("ABCD"));
+
+ // When dragging one item
+ QFETCH(int, sourceRow);
+ QMimeData* mimeData = pm.mimeData({pm.index(sourceRow, 0)});
+ QVERIFY(mimeData);
+
+ // and dropping onto another item
+ QFETCH(int, destRow);
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, -1, -1, pm.index(destRow, 0)));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, -1, -1, pm.index(destRow, 0)));
+ delete mimeData;
+
+ // Then the result should be as expected
+ QFETCH(QString, expectedResult);
+ QCOMPARE(extractColumnTexts(&pm, 0), expectedResult);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropBetweenItems()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the last row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(2, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it before row 1
+ const int destRow = 1;
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("DEF"));
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropBetweenItemsAtModelBoundary()
+{
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the first row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(0, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it before row 2
+ const int destRow = 2;
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("DEF"));
+
+ // and it should be part of the second model
+ QCOMPARE(mod2.rowCount(), 2);
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow_data()
+{
+ QTest::addColumn<int>("destRow");
+
+ // Dropping after the last row is documented to be done with destRow == -1.
+ QTest::newRow("-1") << -1;
+ // However, sometimes QTreeView calls dropMimeData with destRow == rowCount...
+ // Not sure if that's a bug or not, but let's support it in the model, just in case.
+ QTest::newRow("3") << 3;
+}
+
+void tst_QConcatenateTablesProxyModel::shouldPropagateDropAfterLastRow()
+{
+ QFETCH(int, destRow);
+
+ // Given two models combined
+ QConcatenateTablesProxyModel pm;
+ pm.addSourceModel(&mod3);
+ pm.addSourceModel(&mod2);
+ QAbstractItemModelTester modelTest(&pm, this);
+ QCOMPARE(pm.rowCount(), 3);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+
+ // When dragging the second row
+ QModelIndexList indexes;
+ indexes.reserve(pm.columnCount());
+ for (int col = 0; col < pm.columnCount(); ++col) {
+ indexes.append(pm.index(1, col));
+ }
+ QMimeData* mimeData = pm.mimeData(indexes);
+ QVERIFY(mimeData);
+
+ // and dropping it after the last row
+ QVERIFY(pm.canDropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ QVERIFY(pm.dropMimeData(mimeData, Qt::CopyAction, destRow, 0, QModelIndex()));
+ delete mimeData;
+
+ // Then a new row should be inserted at the end
+ QCOMPARE(pm.rowCount(), 4);
+ QCOMPARE(extractRowTexts(&pm, 0), QStringLiteral("123"));
+ QCOMPARE(extractRowTexts(&pm, 1), QStringLiteral("456"));
+ QCOMPARE(extractRowTexts(&pm, 2), QStringLiteral("DEF"));
+ QCOMPARE(extractRowTexts(&pm, 3), QStringLiteral("456"));
+
+}
+
+void tst_QConcatenateTablesProxyModel::qtbug91788()
+{
+ QConcatenateTablesProxyModel proxyConcat;
+ QStringList strList{QString("one"),QString("two")};
+ QStringListModel strListModelA(strList);
+ QSortFilterProxyModel proxyFilter;
+ proxyFilter.setSourceModel(&proxyConcat);
+
+ proxyConcat.addSourceModel(&strListModelA);
+ proxyConcat.removeSourceModel(&strListModelA); // This should not assert
+ QCOMPARE(proxyConcat.columnCount(), 0);
+}
+
+void tst_QConcatenateTablesProxyModel::qtbug91878()
+{
+ QStandardItemModel m;
+ m.setRowCount(4);
+ m.setColumnCount(4);
+
+ QConcatenateTablesProxyModel pm;
+ QSortFilterProxyModel proxyFilter;
+ proxyFilter.setSourceModel(&pm);
+ proxyFilter.setFilterFixedString("something");
+ pm.addSourceModel(&m); // This should not assert
+
+ QCOMPARE(pm.columnCount(), 4);
+ QCOMPARE(pm.rowCount(), 4);
+}
+
+void tst_QConcatenateTablesProxyModel::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QStandardItemModel model1(3, 1);
+ QStandardItemModel model2(3, 1);
+ for (int row = 0; row < 3; ++row) {
+ model1.setData(model1.index(row, 0), row);
+ model2.setData(model2.index(row, 0), row + 5);
+ }
+ QConcatenateTablesProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.addSourceModel(&model1);
+ proxy.addSourceModel(&model2);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
+ connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &proxy](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(proxy.index(row, 0));
+ });
+ connect(&proxy, &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ QVERIFY(model1.setData(model1.index(1, 0), -1));
+ model1.sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+QTEST_GUILESS_MAIN(tst_QConcatenateTablesProxyModel)
+
+#include "tst_qconcatenatetablesproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qidentityproxymodel/CMakeLists.txt
new file mode 100644
index 0000000000..87a2cdcba1
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qidentityproxymodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qidentityproxymodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qidentityproxymodel
+ SOURCES
+ ../../../other/qabstractitemmodelutils/dynamictreemodel.cpp ../../../other/qabstractitemmodelutils/dynamictreemodel.h
+ tst_qidentityproxymodel.cpp
+ INCLUDE_DIRECTORIES
+ ../../../other/qabstractitemmodelutils
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/qidentityproxymodel.pro b/tests/auto/corelib/itemmodels/qidentityproxymodel/qidentityproxymodel.pro
deleted file mode 100644
index ddec0d2354..0000000000
--- a/tests/auto/corelib/itemmodels/qidentityproxymodel/qidentityproxymodel.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qidentityproxymodel
-
-mtdir = ../../../other/qabstractitemmodelutils
-INCLUDEPATH += $$PWD/$${mtdir}
-QT += testlib
-SOURCES += tst_qidentityproxymodel.cpp $${mtdir}/dynamictreemodel.cpp
-HEADERS += $${mtdir}/dynamictreemodel.h
diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
index c76052a38b..99b74bc09a 100644
--- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QAbstractItemModelTester>
#include <QCoreApplication>
@@ -32,6 +7,7 @@
#include <QStandardItemModel>
#include <QStringListModel>
#include <QTest>
+#include <QTransposeProxyModel>
#include <QLoggingCategory>
#include "dynamictreemodel.h"
@@ -42,15 +18,25 @@ Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels")
class DataChangedModel : public QAbstractListModel
{
public:
- int rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : 1; }
- QVariant data(const QModelIndex&, int) const { return QVariant(); }
- QModelIndex index(int row, int column, const QModelIndex &) const { return createIndex(row, column); }
+ int rowCount(const QModelIndex &parent) const override { return parent.isValid() ? 0 : 1; }
+ QVariant data(const QModelIndex&, int) const override { return QVariant(); }
+ QModelIndex index(int row, int column, const QModelIndex &) const override { return createIndex(row, column); }
void changeData()
{
const QModelIndex idx = index(0, 0, QModelIndex());
- Q_EMIT dataChanged(idx, idx, QVector<int>() << 1);
+ Q_EMIT dataChanged(idx, idx, QList<int>() << 1);
}
+
+ // Workaround QObject::isSignalConnected() being a protected method
+ bool isConnected(const QMetaMethod &m) const { return isSignalConnected(m); }
+};
+
+class IdentityProxyModel : public QIdentityProxyModel
+{
+public:
+ // The name has to be different than the method from the base class
+ void setHandleSLC(bool b) { setHandleSourceLayoutChanges(b); }
};
class tst_QIdentityProxyModel : public QObject
@@ -69,12 +55,16 @@ private slots:
void insertRows();
void removeRows();
void moveRows();
+ void moveColumns();
void reset();
void dataChanged();
void itemData();
void persistIndexOnLayoutChange();
+ void createPersistentOnLayoutAboutToBeChanged();
+
+ void testSetHandleLayoutChanges();
protected:
void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex());
@@ -92,7 +82,7 @@ tst_QIdentityProxyModel::tst_QIdentityProxyModel()
void tst_QIdentityProxyModel::initTestCase()
{
- qRegisterMetaType<QVector<int> >();
+ qRegisterMetaType<QList<int> >();
m_model = new QStandardItemModel(0, 1);
m_proxy = new QIdentityProxyModel();
m_modelTest = new QAbstractItemModelTester(m_proxy, this);
@@ -235,47 +225,24 @@ void tst_QIdentityProxyModel::removeRows()
void tst_QIdentityProxyModel::moveRows()
{
- DynamicTreeModel model;
-
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(QList<int>() << 5);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
+ QStringListModel model({"A", "B", "C", "D", "E", "F"});
m_proxy->setSourceModel(&model);
verifyIdentity(&model);
- QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
- QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
- QSignalSpy proxyBeforeSpy(m_proxy, &QIdentityProxyModel::rowsAboutToBeMoved);
- QSignalSpy proxyAfterSpy(m_proxy, &QIdentityProxyModel::rowsMoved);
+ QSignalSpy modelBeforeSpy(&model, &QAbstractItemModel::rowsAboutToBeMoved);
+ QSignalSpy modelAfterSpy(&model, &QAbstractItemModel::rowsMoved);
+ QSignalSpy proxyBeforeSpy(m_proxy, &QAbstractItemModel::rowsAboutToBeMoved);
+ QSignalSpy proxyAfterSpy(m_proxy, &QAbstractItemModel::rowsMoved);
- QVERIFY(modelBeforeSpy.isValid());
- QVERIFY(modelAfterSpy.isValid());
- QVERIFY(proxyBeforeSpy.isValid());
- QVERIFY(proxyAfterSpy.isValid());
-
- {
- ModelMoveCommand moveCommand(&model, 0);
- moveCommand.setAncestorRowNumbers(QList<int>() << 5);
- moveCommand.setStartRow(3);
- moveCommand.setEndRow(4);
- moveCommand.setDestRow(1);
- moveCommand.doCommand();
- }
+ QVERIFY(m_proxy->moveRows(QModelIndex(), 1, 2, QModelIndex(), 5));
+ QCOMPARE(model.stringList(), QStringList({"A", "D", "E", "B", "C", "F"}));
- QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size());
- QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size());
+ QCOMPARE(modelBeforeSpy.size(), 1);
+ QCOMPARE(proxyBeforeSpy.size(), 1);
+ QCOMPARE(modelAfterSpy.size(), 1);
+ QCOMPARE(proxyAfterSpy.size(), 1);
QCOMPARE(modelBeforeSpy.first().first().value<QModelIndex>(), m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>()));
QCOMPARE(modelBeforeSpy.first().at(1), proxyBeforeSpy.first().at(1));
@@ -289,9 +256,62 @@ void tst_QIdentityProxyModel::moveRows()
QCOMPARE(modelAfterSpy.first().at(3).value<QModelIndex>(), m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>()));
QCOMPARE(modelAfterSpy.first().at(4), proxyAfterSpy.first().at(4));
+ QVERIFY(m_proxy->moveRows(QModelIndex(), 3, 2, QModelIndex(), 1));
+ QCOMPARE(model.stringList(), QStringList({"A", "B", "C", "D", "E", "F"}));
+ QVERIFY(m_proxy->moveRows(QModelIndex(), 0, 3, QModelIndex(), 6));
+ QCOMPARE(model.stringList(), QStringList({"D", "E", "F", "A", "B", "C"}));
+
verifyIdentity(&model);
- m_proxy->setSourceModel(0);
+ m_proxy->setSourceModel(nullptr);
+}
+
+void tst_QIdentityProxyModel::moveColumns()
+{
+ // QStringListModel implements moveRows but not moveColumns
+ // so we have to use a QTransposeProxyModel inbetween to check if
+ // QIdentityProxyModel::moveColumns works as expected
+ QStringListModel model({"A", "B", "C", "D", "E", "F"});
+ QTransposeProxyModel tpm;
+ tpm.setSourceModel(&model);
+
+ m_proxy->setSourceModel(&tpm);
+
+ verifyIdentity(&tpm);
+
+ QSignalSpy modelBeforeSpy(&tpm, &QAbstractItemModel::columnsAboutToBeMoved);
+ QSignalSpy modelAfterSpy(&tpm, &QAbstractItemModel::columnsMoved);
+ QSignalSpy proxyBeforeSpy(m_proxy, &QAbstractItemModel::columnsAboutToBeMoved);
+ QSignalSpy proxyAfterSpy(m_proxy, &QAbstractItemModel::columnsMoved);
+
+ QVERIFY(m_proxy->moveColumns(QModelIndex(), 1, 2, QModelIndex(), 5));
+ QCOMPARE(model.stringList(), QStringList({"A", "D", "E", "B", "C", "F"}));
+
+ QCOMPARE(proxyBeforeSpy.size(), 1);
+ QCOMPARE(modelBeforeSpy.size(), 1);
+ QCOMPARE(modelAfterSpy.size(), 1);
+ QCOMPARE(proxyAfterSpy.size(), 1);
+
+ QCOMPARE(modelBeforeSpy.first().first().value<QModelIndex>(), m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>()));
+ QCOMPARE(modelBeforeSpy.first().at(1), proxyBeforeSpy.first().at(1));
+ QCOMPARE(modelBeforeSpy.first().at(2), proxyBeforeSpy.first().at(2));
+ QCOMPARE(modelBeforeSpy.first().at(3).value<QModelIndex>(), m_proxy->mapToSource(proxyBeforeSpy.first().at(3).value<QModelIndex>()));
+ QCOMPARE(modelBeforeSpy.first().at(4), proxyBeforeSpy.first().at(4));
+
+ QCOMPARE(modelAfterSpy.first().first().value<QModelIndex>(), m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>()));
+ QCOMPARE(modelAfterSpy.first().at(1), proxyAfterSpy.first().at(1));
+ QCOMPARE(modelAfterSpy.first().at(2), proxyAfterSpy.first().at(2));
+ QCOMPARE(modelAfterSpy.first().at(3).value<QModelIndex>(), m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>()));
+ QCOMPARE(modelAfterSpy.first().at(4), proxyAfterSpy.first().at(4));
+
+ QVERIFY(m_proxy->moveColumns(QModelIndex(), 3, 2, QModelIndex(), 1));
+ QCOMPARE(model.stringList(), QStringList({"A", "B", "C", "D", "E", "F"}));
+ QVERIFY(m_proxy->moveColumns(QModelIndex(), 0, 3, QModelIndex(), 6));
+ QCOMPARE(model.stringList(), QStringList({"D", "E", "F", "A", "B", "C"}));
+
+ verifyIdentity(&tpm);
+
+ m_proxy->setSourceModel(nullptr);
}
void tst_QIdentityProxyModel::reset()
@@ -357,7 +377,7 @@ void tst_QIdentityProxyModel::dataChanged()
model.changeData();
- QCOMPARE(modelSpy.first().at(2).value<QVector<int> >(), QVector<int>() << 1);
+ QCOMPARE(modelSpy.first().at(2).value<QList<int> >(), QList<int>() << 1);
QCOMPARE(modelSpy.first().at(2), proxySpy.first().at(2));
verifyIdentity(&model);
@@ -367,13 +387,22 @@ void tst_QIdentityProxyModel::dataChanged()
class AppendStringProxy : public QIdentityProxyModel
{
public:
- QVariant data(const QModelIndex &index, int role) const
+ QVariant data(const QModelIndex &index, int role) const override
{
const QVariant result = QIdentityProxyModel::data(index, role);
if (role != Qt::DisplayRole)
return result;
- return result.toString() + "_appended";
+ return result.toString() + QLatin1String("_appended");
}
+ QMap<int, QVariant> itemData(const QModelIndex &index) const override
+ {
+ QMap<int, QVariant> result = QIdentityProxyModel::itemData(index);
+ auto displayIter = result.find(Qt::DisplayRole);
+ if (displayIter != result.end())
+ displayIter.value() = displayIter.value().toString() + QLatin1String("_appended");
+ return result;
+ }
+
};
void tst_QIdentityProxyModel::itemData()
@@ -462,5 +491,62 @@ void tst_QIdentityProxyModel::persistIndexOnLayoutChange()
QVERIFY(persistentIndex.isValid());
}
+void tst_QIdentityProxyModel::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QStandardItemModel model(3, 1);
+ for (int row = 0; row < 3; ++row)
+ model.setData(model.index(row, 0), row, Qt::UserRole);
+ model.setSortRole(Qt::UserRole);
+ QIdentityProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
+ connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &proxy](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(proxy.index(row, 0));
+ });
+ connect(&proxy, &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data(Qt::UserRole).toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data(Qt::UserRole).toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data(Qt::UserRole).toInt(), 2);
+ });
+ model.setData(model.index(1, 0), -1, Qt::UserRole);
+ model.sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+void tst_QIdentityProxyModel::testSetHandleLayoutChanges()
+{
+ const std::array layoutSignals = {
+ QMetaMethod::fromSignal(&QAbstractItemModel::layoutChanged),
+ QMetaMethod::fromSignal(&QAbstractItemModel::layoutAboutToBeChanged),
+ };
+
+ DataChangedModel model;
+ IdentityProxyModel proxy;
+ proxy.setSourceModel(&model);
+ for (const auto &m : layoutSignals)
+ QVERIFY(model.isConnected(m)); // Connected by default
+
+ proxy.setSourceModel(nullptr);
+
+ // Disable handling (connecting to layotu signals) of source model layout changes
+ proxy.setHandleSLC(false);
+ proxy.setSourceModel(&model);
+ for (const auto &m : layoutSignals)
+ QVERIFY(!model.isConnected(m));
+}
+
QTEST_MAIN(tst_QIdentityProxyModel)
#include "tst_qidentityproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qitemmodel/CMakeLists.txt
new file mode 100644
index 0000000000..57d9ba4913
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qitemmodel/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qitemmodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qitemmodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qitemmodel
+ SOURCES
+ tst_qitemmodel.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::Sql
+ Qt::Widgets
+)
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp b/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp
index 6ea7a38137..b2d507875d 100644
--- a/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp
+++ b/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <QtCore/QCoreApplication>
#include <QtSql/QtSql>
#include <QtWidgets/QtWidgets>
@@ -83,14 +58,13 @@ private:
Add new tests, they can be the same model, but in a different state.
The name of the model is passed to createModel
- If readOnly is true the remove tests will be skipped. Example: QDirModel is disabled.
- If createModel returns an empty model. Example: QDirModel does not
+ If readOnly is true the remove tests will be skipped. Example: QSqlQueryModel is disabled.
+ If createModel returns an empty model.
*/
ModelsToTest::ModelsToTest()
{
setupDatabase();
- tests.append(test("QDirModel", ReadOnly, HasData));
tests.append(test("QStringListModel", ReadWrite, HasData));
tests.append(test("QStringListModelEmpty", ReadWrite, Empty));
@@ -143,34 +117,28 @@ QAbstractItemModel *ModelsToTest::createModel(const QString &modelType)
if (modelType == "QSortFilterProxyModelEmpty") {
QSortFilterProxyModel *model = new QSortFilterProxyModel;
- QStandardItemModel *standardItemModel = new QStandardItemModel;
+ QStandardItemModel *standardItemModel = new QStandardItemModel(model);
model->setSourceModel(standardItemModel);
return model;
}
if (modelType == "QSortFilterProxyModelRegExp") {
QSortFilterProxyModel *model = new QSortFilterProxyModel;
- QStandardItemModel *standardItemModel = new QStandardItemModel;
+ QStandardItemModel *standardItemModel = new QStandardItemModel(model);
model->setSourceModel(standardItemModel);
populateTestArea(model);
- model->setFilterRegExp(QRegExp("(^$|I.*)"));
+ model->setFilterRegularExpression(QRegularExpression("(^$|I.*)"));
return model;
}
if (modelType == "QSortFilterProxyModel") {
QSortFilterProxyModel *model = new QSortFilterProxyModel;
- QStandardItemModel *standardItemModel = new QStandardItemModel;
+ QStandardItemModel *standardItemModel = new QStandardItemModel(model);
model->setSourceModel(standardItemModel);
populateTestArea(model);
return model;
}
- if (modelType == "QDirModel") {
- QDirModel *model = new QDirModel();
- model->setReadOnly(false);
- return model;
- }
-
if (modelType == "QSqlQueryModel") {
QSqlQueryModel *model = new QSqlQueryModel();
populateTestArea(model);
@@ -251,7 +219,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model)
QString val = xval + QString::number(y) + QString::number(i);
QModelIndex index = model->index(x, y, parent);
model->setData(index, val);
- model->setData(index, blue, Qt::TextColorRole);
+ model->setData(index, blue, Qt::ForegroundRole);
}
}
*/
@@ -276,7 +244,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model)
QString val = xval + QString::number(y) + QString::number(i);
QModelIndex index = realModel->index(x, y, parent);
realModel->setData(index, val);
- realModel->setData(index, blue, Qt::TextColorRole);
+ realModel->setData(index, blue, Qt::ForegroundRole);
}
}
*/
@@ -287,23 +255,6 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model)
return returnIndex;
}
- if (QDirModel *dirModel = qobject_cast<QDirModel *>(model)) {
- m_dirModelTempDir.reset(new QTemporaryDir);
- if (!m_dirModelTempDir->isValid())
- qFatal("Cannot create temporary directory \"%s\": %s",
- qPrintable(QDir::toNativeSeparators(m_dirModelTempDir->path())),
- qPrintable(m_dirModelTempDir->errorString()));
-
- QDir tempDir(m_dirModelTempDir->path());
- for (int i = 0; i < 26; ++i) {
- const QString subdir = QLatin1String("foo_") + QString::number(i);
- if (!tempDir.mkdir(subdir))
- qFatal("Cannot create directory %s",
- qPrintable(QDir::toNativeSeparators(tempDir.path() + QLatin1Char('/') +subdir)));
- }
- return dirModel->index(tempDir.path());
- }
-
if (QSqlQueryModel *queryModel = qobject_cast<QSqlQueryModel *>(model)) {
QSqlQuery q;
q.exec("CREATE TABLE test(id int primary key, name varchar(30))");
@@ -359,11 +310,8 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model)
*/
void ModelsToTest::cleanupTestArea(QAbstractItemModel *model)
{
- if (qobject_cast<QDirModel *>(model)) {
- m_dirModelTempDir.reset();
- } else if (qobject_cast<QSqlQueryModel *>(model)) {
+ if (qobject_cast<QSqlQueryModel *>(model))
QSqlQuery q("DROP TABLE test");
- }
}
void ModelsToTest::setupDatabase()
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/qitemmodel.pro b/tests/auto/corelib/itemmodels/qitemmodel/qitemmodel.pro
deleted file mode 100644
index ff21d6afa5..0000000000
--- a/tests/auto/corelib/itemmodels/qitemmodel/qitemmodel.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qitemmodel
-QT += widgets sql testlib
-SOURCES = tst_qitemmodel.cpp
diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
index af52852b99..b1f91fe9a3 100644
--- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
#include <QtCore/QCoreApplication>
#include <qdebug.h>
#include "modelstotest.cpp"
@@ -577,12 +553,12 @@ void tst_QItemModel::data()
alignment == Qt::AlignJustify);
}
- QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundColorRole);
+ QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundRole);
if (colorVariant.isValid()) {
QVERIFY(colorVariant.canConvert<QColor>());
}
- colorVariant = currentModel->data(currentModel->index(0,0), Qt::TextColorRole);
+ colorVariant = currentModel->data(currentModel->index(0,0), Qt::ForegroundRole);
if (colorVariant.isValid()) {
QVERIFY(colorVariant.canConvert<QColor>());
}
@@ -611,7 +587,7 @@ void tst_QItemModel::setData()
QVERIFY(currentModel);
QSignalSpy spy(currentModel, &QAbstractItemModel::dataChanged);
QVERIFY(spy.isValid());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QFETCH(bool, isEmpty);
if (isEmpty)
@@ -635,7 +611,7 @@ void tst_QItemModel::setData()
// Changing the text shouldn't change the layout, parent, pointer etc.
QModelIndex changedIndex = currentModel->index(0, 0, topIndex);
QCOMPARE(changedIndex, index);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QItemModel::setHeaderData_data()
@@ -685,7 +661,7 @@ void tst_QItemModel::setHeaderData()
++signalCount;
}
}
- QCOMPARE(spy.count(), signalCount);
+ QCOMPARE(spy.size(), signalCount);
}
void tst_QItemModel::sort_data()
@@ -716,7 +692,7 @@ void tst_QItemModel::sort()
for (int i=-1; i < 10; ++i){
currentModel->sort(i);
if (index != currentModel->index(0, 0, topIndex)){
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
index = currentModel->index(0, 0, topIndex);
spy.clear();
}
@@ -882,7 +858,7 @@ void tst_QItemModel::remove()
if (shouldSucceed && dyingIndex.isValid())
QCOMPARE(dyingIndex.row(), start + 1);
- if (rowsAboutToBeRemovedSpy.count() > 0){
+ if (rowsAboutToBeRemovedSpy.size() > 0){
QList<QVariant> arguments = rowsAboutToBeRemovedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -892,7 +868,7 @@ void tst_QItemModel::remove()
QVERIFY(parentOfRemoved == parent);
}
- if (rowsRemovedSpy.count() > 0){
+ if (rowsRemovedSpy.size() > 0){
QList<QVariant> arguments = rowsRemovedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -903,26 +879,26 @@ void tst_QItemModel::remove()
}
// Only the row signals should have been emitted
- if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >=1 ){
- QCOMPARE(columnsAboutToBeRemovedSpy.count(), 0);
- QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
- QCOMPARE(columnsRemovedSpy.count(), 0);
- QCOMPARE(rowsRemovedSpy.count(), 0);
+ if (modelResetSpy.size() >= 1 || modelLayoutChangedSpy.size() >=1 ){
+ QCOMPARE(columnsAboutToBeRemovedSpy.size(), 0);
+ QCOMPARE(rowsAboutToBeRemovedSpy.size(), 0);
+ QCOMPARE(columnsRemovedSpy.size(), 0);
+ QCOMPARE(rowsRemovedSpy.size(), 0);
}
else {
- QCOMPARE(columnsAboutToBeRemovedSpy.count(), 0);
- QCOMPARE(rowsAboutToBeRemovedSpy.count(), numberOfRowsAboutToBeRemovedSignals);
- QCOMPARE(columnsRemovedSpy.count(), 0);
- QCOMPARE(rowsRemovedSpy.count(), numberOfRowsRemovedSignals);
+ QCOMPARE(columnsAboutToBeRemovedSpy.size(), 0);
+ QCOMPARE(rowsAboutToBeRemovedSpy.size(), numberOfRowsAboutToBeRemovedSignals);
+ QCOMPARE(columnsRemovedSpy.size(), 0);
+ QCOMPARE(rowsRemovedSpy.size(), numberOfRowsRemovedSignals);
}
// The row count should only change *after* rowsAboutToBeRemoved has been emitted
if (shouldSucceed) {
- if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0){
+ if (modelResetSpy.size() == 0 && modelLayoutChangedSpy.size() == 0){
QCOMPARE(afterAboutToRemoveRowCount, beforeRemoveRowCount);
QCOMPARE(afterRemoveRowCount, beforeRemoveRowCount-count-(numberOfRowsRemovedSignals-1));
}
- if (modelResetSpy.count() == 0 )
+ if (modelResetSpy.size() == 0 )
QCOMPARE(currentModel->rowCount(parentOfRemoved), beforeRemoveRowCount-count-(numberOfRowsRemovedSignals-1));
}
else {
@@ -937,7 +913,7 @@ void tst_QItemModel::remove()
disconnect(currentModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(slot_rowsRemoved(QModelIndex)));
modelResetSpy.clear();
- QCOMPARE(modelResetSpy.count(), 0);
+ QCOMPARE(modelResetSpy.size(), 0);
//
// Test remove column
@@ -952,26 +928,26 @@ void tst_QItemModel::remove()
if (currentModel->removeColumns(start, count, parentOfRemoved)) {
currentModel->submit();
// Didn't reset the rows, so they should still be at the same value
- if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >= 1){
- QCOMPARE(columnsAboutToBeRemovedSpy.count(), 0);
+ if (modelResetSpy.size() >= 1 || modelLayoutChangedSpy.size() >= 1){
+ QCOMPARE(columnsAboutToBeRemovedSpy.size(), 0);
//QCOMPARE(rowsAboutToBeRemovedSpy.count(), numberOfRowsAboutToBeRemovedSignals);
- QCOMPARE(columnsRemovedSpy.count(), 0);
+ QCOMPARE(columnsRemovedSpy.size(), 0);
//QCOMPARE(rowsRemovedSpy.count(), numberOfRowsRemovedSignals);
}
else {
- QCOMPARE(columnsAboutToBeRemovedSpy.count(), numberOfColumnsAboutToBeRemovedSignals);
- QCOMPARE(rowsAboutToBeRemovedSpy.count(), numberOfRowsAboutToBeRemovedSignals);
- QCOMPARE(columnsRemovedSpy.count(), numberOfColumnsRemovedSignals);
- QCOMPARE(rowsRemovedSpy.count(), numberOfRowsRemovedSignals);
+ QCOMPARE(columnsAboutToBeRemovedSpy.size(), numberOfColumnsAboutToBeRemovedSignals);
+ QCOMPARE(rowsAboutToBeRemovedSpy.size(), numberOfRowsAboutToBeRemovedSignals);
+ QCOMPARE(columnsRemovedSpy.size(), numberOfColumnsRemovedSignals);
+ QCOMPARE(rowsRemovedSpy.size(), numberOfRowsRemovedSignals);
}
// The column count should only change *after* rowsAboutToBeRemoved has been emitted
if (shouldSucceed) {
- if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0){
+ if (modelResetSpy.size() == 0 && modelLayoutChangedSpy.size() == 0){
QCOMPARE(afterAboutToRemoveColumnCount, beforeRemoveColumnCount);
QCOMPARE(afterRemoveColumnCount, beforeRemoveColumnCount-count-(numberOfColumnsRemovedSignals-1));
}
- if (modelResetSpy.count() == 0)
+ if (modelResetSpy.size() == 0)
QCOMPARE(currentModel->columnCount(parentOfRemoved), beforeRemoveColumnCount-count-(numberOfColumnsRemovedSignals-1));
}
else
@@ -982,7 +958,7 @@ void tst_QItemModel::remove()
disconnect(currentModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
this, SLOT(slot_columnsRemoved(QModelIndex)));
- if (columnsAboutToBeRemovedSpy.count() > 0){
+ if (columnsAboutToBeRemovedSpy.size() > 0){
QList<QVariant> arguments = columnsAboutToBeRemovedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -992,7 +968,7 @@ void tst_QItemModel::remove()
QVERIFY(parentOfRemoved == parent);
}
- if (columnsRemovedSpy.count() > 0){
+ if (columnsRemovedSpy.size() > 0){
QList<QVariant> arguments = columnsRemovedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -1221,7 +1197,7 @@ void tst_QItemModel::insert()
QCOMPARE(currentModel->insertRows(start, count, parentOfInserted), shouldSucceed);
currentModel->submit();
- if (rowsAboutToBeInsertedSpy.count() > 0){
+ if (rowsAboutToBeInsertedSpy.size() > 0){
QList<QVariant> arguments = rowsAboutToBeInsertedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -1231,7 +1207,7 @@ void tst_QItemModel::insert()
QVERIFY(parentOfInserted == parent);
}
- if (rowsInsertedSpy.count() > 0){
+ if (rowsInsertedSpy.size() > 0){
QList<QVariant> arguments = rowsInsertedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -1242,25 +1218,25 @@ void tst_QItemModel::insert()
}
// Only the row signals should have been emitted
- if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >= 1) {
- QCOMPARE(columnsAboutToBeInsertedSpy.count(), 0);
- QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
- QCOMPARE(columnsInsertedSpy.count(), 0);
- QCOMPARE(rowsInsertedSpy.count(), 0);
+ if (modelResetSpy.size() >= 1 || modelLayoutChangedSpy.size() >= 1) {
+ QCOMPARE(columnsAboutToBeInsertedSpy.size(), 0);
+ QCOMPARE(rowsAboutToBeInsertedSpy.size(), 0);
+ QCOMPARE(columnsInsertedSpy.size(), 0);
+ QCOMPARE(rowsInsertedSpy.size(), 0);
}
else {
- QCOMPARE(columnsAboutToBeInsertedSpy.count(), 0);
- QCOMPARE(rowsAboutToBeInsertedSpy.count(), numberOfRowsAboutToBeInsertedSignals);
- QCOMPARE(columnsInsertedSpy.count(), 0);
- QCOMPARE(rowsInsertedSpy.count(), numberOfRowsInsertedSignals);
+ QCOMPARE(columnsAboutToBeInsertedSpy.size(), 0);
+ QCOMPARE(rowsAboutToBeInsertedSpy.size(), numberOfRowsAboutToBeInsertedSignals);
+ QCOMPARE(columnsInsertedSpy.size(), 0);
+ QCOMPARE(rowsInsertedSpy.size(), numberOfRowsInsertedSignals);
}
// The row count should only change *after* rowsAboutToBeInserted has been emitted
if (shouldSucceed) {
- if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0) {
+ if (modelResetSpy.size() == 0 && modelLayoutChangedSpy.size() == 0) {
QCOMPARE(afterAboutToInsertRowCount, beforeInsertRowCount);
QCOMPARE(afterInsertRowCount, beforeInsertRowCount+count+(numberOfRowsInsertedSignals-1));
}
- if (modelResetSpy.count() == 0)
+ if (modelResetSpy.size() == 0)
QCOMPARE(currentModel->rowCount(parentOfInserted), beforeInsertRowCount+count+(numberOfRowsInsertedSignals-1));
}
else {
@@ -1288,27 +1264,27 @@ void tst_QItemModel::insert()
// Some models don't let you insert the column, only row
if (currentModel->insertColumns(start, count, parentOfInserted)) {
currentModel->submit();
- if (modelResetSpy.count() >= 1 || modelLayoutChangedSpy.count() >= 1) {
+ if (modelResetSpy.size() >= 1 || modelLayoutChangedSpy.size() >= 1) {
// Didn't reset the rows, so they should still be at the same value
- QCOMPARE(columnsAboutToBeInsertedSpy.count(), 0);
+ QCOMPARE(columnsAboutToBeInsertedSpy.size(), 0);
//QCOMPARE(rowsAboutToBeInsertedSpy.count(), numberOfRowsAboutToBeInsertedSignals);
- QCOMPARE(columnsInsertedSpy.count(), 0);
+ QCOMPARE(columnsInsertedSpy.size(), 0);
//QCOMPARE(rowsInsertedSpy.count(), numberOfRowsInsertedSignals);
}
else {
// Didn't reset the rows, so they should still be at the same value
- QCOMPARE(columnsAboutToBeInsertedSpy.count(), numberOfColumnsAboutToBeInsertedSignals);
- QCOMPARE(rowsAboutToBeInsertedSpy.count(), numberOfRowsAboutToBeInsertedSignals);
- QCOMPARE(columnsInsertedSpy.count(), numberOfColumnsInsertedSignals);
- QCOMPARE(rowsInsertedSpy.count(), numberOfRowsInsertedSignals);
+ QCOMPARE(columnsAboutToBeInsertedSpy.size(), numberOfColumnsAboutToBeInsertedSignals);
+ QCOMPARE(rowsAboutToBeInsertedSpy.size(), numberOfRowsAboutToBeInsertedSignals);
+ QCOMPARE(columnsInsertedSpy.size(), numberOfColumnsInsertedSignals);
+ QCOMPARE(rowsInsertedSpy.size(), numberOfRowsInsertedSignals);
}
// The column count should only change *after* rowsAboutToBeInserted has been emitted
if (shouldSucceed) {
- if (modelResetSpy.count() == 0 && modelLayoutChangedSpy.count() == 0) {
+ if (modelResetSpy.size() == 0 && modelLayoutChangedSpy.size() == 0) {
QCOMPARE(afterAboutToInsertColumnCount, beforeInsertColumnCount);
QCOMPARE(afterInsertColumnCount, beforeInsertColumnCount+count+(numberOfColumnsInsertedSignals-1));
}
- if (modelResetSpy.count() == 0)
+ if (modelResetSpy.size() == 0)
QCOMPARE(currentModel->columnCount(parentOfInserted), beforeInsertColumnCount+count+(numberOfColumnsInsertedSignals-1));
}
else
@@ -1319,7 +1295,7 @@ void tst_QItemModel::insert()
disconnect(currentModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
this, SLOT(slot_columnsInserted(QModelIndex)));
- if (columnsAboutToBeInsertedSpy.count() > 0){
+ if (columnsAboutToBeInsertedSpy.size() > 0){
QList<QVariant> arguments = columnsAboutToBeInsertedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
@@ -1329,7 +1305,7 @@ void tst_QItemModel::insert()
QVERIFY(parentOfInserted == parent);
}
- if (columnsInsertedSpy.count() > 0){
+ if (columnsInsertedSpy.size() > 0){
QList<QVariant> arguments = columnsInsertedSpy.at(0);
QModelIndex parent = (qvariant_cast<QModelIndex>(arguments.at(0)));
int first = arguments.at(1).toInt();
diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qitemselectionmodel/CMakeLists.txt
new file mode 100644
index 0000000000..88ec493305
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qitemselectionmodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qitemselectionmodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qitemselectionmodel
+ SOURCES
+ tst_qitemselectionmodel.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/qitemselectionmodel.pro b/tests/auto/corelib/itemmodels/qitemselectionmodel/qitemselectionmodel.pro
deleted file mode 100644
index 4dcddc8feb..0000000000
--- a/tests/auto/corelib/itemmodels/qitemselectionmodel/qitemselectionmodel.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qitemselectionmodel
-QT += testlib
-SOURCES += tst_qitemselectionmodel.cpp
diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
index 6fbaa28d69..45f7a6c08d 100644
--- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
@@ -1,37 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QtTest/private/qpropertytesthelper_p.h>
+#include <QSignalSpy>
#include <QtGui/QtGui>
#include <algorithm>
+Q_DECLARE_METATYPE(QItemSelectionModel::SelectionFlag)
+Q_DECLARE_METATYPE(Qt::SortOrder)
+
class tst_QItemSelectionModel : public QObject
{
Q_OBJECT
@@ -44,6 +25,7 @@ public slots:
void cleanupTestCase();
void init();
private slots:
+ void compareCompiles();
void clear_data();
void clear();
void clearAndSelect();
@@ -79,10 +61,10 @@ private slots:
void layoutChangedWithAllSelected2();
void layoutChangedTreeSelection();
void deselectRemovedMiddleRange();
- void rangeOperatorLessThan_data();
- void rangeOperatorLessThan();
void setModel();
+ void bindableModel();
+
void testDifferentModels();
void testValidRangesInSelectionsAfterReset();
@@ -98,11 +80,19 @@ private slots:
void QTBUG18001_data();
void QTBUG18001();
+ void QTBUG93305();
+
+ void testSignalsDisconnection();
+ void destroyModel();
+
private:
+ static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
QAbstractItemModel *model;
QItemSelectionModel *selection;
};
+QT_BEGIN_NAMESPACE
+
QDataStream &operator<<(QDataStream &, const QModelIndex &);
QDataStream &operator>>(QDataStream &, QModelIndex &);
QDataStream &operator<<(QDataStream &, const QModelIndexList &);
@@ -122,17 +112,17 @@ public:
return helper.QAbstractItemModel::createIndex(row, column, data);
}
- QModelIndex index(int, int, const QModelIndex&) const
+ QModelIndex index(int, int, const QModelIndex&) const override
{ return QModelIndex(); }
- QModelIndex parent(const QModelIndex&) const
+ QModelIndex parent(const QModelIndex&) const override
{ return QModelIndex(); }
- int rowCount(const QModelIndex & = QModelIndex()) const
+ int rowCount(const QModelIndex & = QModelIndex()) const override
{ return 0; }
- int columnCount(const QModelIndex & = QModelIndex()) const
+ int columnCount(const QModelIndex & = QModelIndex()) const override
{ return 0; }
- QVariant data(const QModelIndex &, int = Qt::DisplayRole) const
+ QVariant data(const QModelIndex &, int = Qt::DisplayRole) const override
{ return QVariant(); }
- bool hasChildren(const QModelIndex &) const
+ bool hasChildren(const QModelIndex &) const override
{ return false; }
};
@@ -157,8 +147,8 @@ QDataStream &operator>>(QDataStream &s, QModelIndex &output)
QDataStream &operator<<(QDataStream &s, const QModelIndexList &input)
{
- s << input.count();
- for (int i=0; i<input.count(); ++i)
+ s << input.size();
+ for (int i=0; i<input.size(); ++i)
s << input.at(i);
return s;
}
@@ -175,6 +165,8 @@ QDataStream &operator>>(QDataStream &s, QModelIndexList &output)
return s;
}
+QT_END_NAMESPACE
+
tst_QItemSelectionModel::tst_QItemSelectionModel()
: model(0), selection(0)
{
@@ -223,6 +215,11 @@ void tst_QItemSelectionModel::init()
model->insertRow(0, QModelIndex());
}
+void tst_QItemSelectionModel::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QItemSelectionRange>();
+}
+
void tst_QItemSelectionModel::clear_data()
{
QTest::addColumn<QModelIndexList>("indexList");
@@ -292,7 +289,7 @@ void tst_QItemSelectionModel::clear()
QFETCH(IntList, commandList);
// do selections
- for (int i=0; i<indexList.count(); ++i) {
+ for (int i=0; i<indexList.size(); ++i) {
selection->select(indexList.at(i), (QItemSelectionModel::SelectionFlags)commandList.at(i));
}
// test that we have selected items
@@ -306,7 +303,7 @@ void tst_QItemSelectionModel::clearAndSelect()
{
// populate selectionmodel
selection->select(model->index(1, 1, QModelIndex()), QItemSelectionModel::Select);
- QCOMPARE(selection->selectedIndexes().count(), 1);
+ QCOMPARE(selection->selectedIndexes().size(), 1);
QVERIFY(selection->hasSelection());
// ClearAndSelect with empty selection
@@ -324,26 +321,26 @@ void tst_QItemSelectionModel::toggleSelection()
//and hasSelection returns the correct value
selection->clearSelection();
- QCOMPARE(selection->selectedIndexes().count(), 0);
+ QCOMPARE(selection->selectedIndexes().size(), 0);
QVERIFY(selection->hasSelection()==false);
QModelIndex index=model->index(1, 1, QModelIndex());
// populate selectionmodel
selection->select(index, QItemSelectionModel::Toggle);
- QCOMPARE(selection->selectedIndexes().count(), 1);
+ QCOMPARE(selection->selectedIndexes().size(), 1);
QVERIFY(selection->hasSelection()==true);
selection->select(index, QItemSelectionModel::Toggle);
- QCOMPARE(selection->selectedIndexes().count(), 0);
+ QCOMPARE(selection->selectedIndexes().size(), 0);
QVERIFY(selection->hasSelection()==false);
// populate selectionmodel with rows
selection->select(index, QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
- QCOMPARE(selection->selectedIndexes().count(), model->columnCount());
+ QCOMPARE(selection->selectedIndexes().size(), model->columnCount());
QVERIFY(selection->hasSelection()==true);
selection->select(index, QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
- QCOMPARE(selection->selectedIndexes().count(), 0);
+ QCOMPARE(selection->selectedIndexes().size(), 0);
QVERIFY(selection->hasSelection()==false);
}
@@ -1235,7 +1232,7 @@ void tst_QItemSelectionModel::select()
int lastCommand = 0;
// do selections
- for (int i = 0; i<commandList.count(); ++i) {
+ for (int i = 0; i<commandList.size(); ++i) {
if (useRanges) {
selection->select(QItemSelection(indexList.at(2*i), indexList.at(2*i+1)),
(QItemSelectionModel::SelectionFlags)commandList.at(i));
@@ -1252,13 +1249,13 @@ void tst_QItemSelectionModel::select()
QVERIFY(selection->hasSelection()!=selectedList.isEmpty());
// test that the number of indices are as expected
- QVERIFY2(selectedList.count() == expectedList.count(),
+ QVERIFY2(selectedList.size() == expectedList.size(),
QString("expected indices: %1 actual indices: %2")
- .arg(expectedList.count())
- .arg(selectedList.count()).toLatin1());
+ .arg(expectedList.size())
+ .arg(selectedList.size()).toLatin1());
// test existence of each index
- for (int i=0; i<expectedList.count(); ++i) {
+ for (int i=0; i<expectedList.size(); ++i) {
QVERIFY2(selectedList.contains(expectedList.at(i)),
QString("expected index(%1, %2) not found in selectedIndexes()")
.arg(expectedList.at(i).row())
@@ -1266,7 +1263,7 @@ void tst_QItemSelectionModel::select()
}
// test that isSelected agrees
- for (int i=0; i<indexList.count(); ++i) {
+ for (int i=0; i<indexList.size(); ++i) {
QModelIndex idx = indexList.at(i);
QVERIFY2(selection->isSelected(idx) == selectedList.contains(idx),
QString("isSelected(index: %1, %2) does not match selectedIndexes()")
@@ -1277,7 +1274,7 @@ void tst_QItemSelectionModel::select()
//for now we assume Rows/Columns flag is the same for all commands, therefore we just check lastCommand
// test that isRowSelected agrees
if (lastCommand & QItemSelectionModel::Rows) {
- for (int i=0; i<selectedList.count(); ++i)
+ for (int i=0; i<selectedList.size(); ++i)
QVERIFY2(selection->isRowSelected(selectedList.at(i).row(),
model->parent(selectedList.at(i))),
QString("isRowSelected(row: %1) does not match selectedIndexes()")
@@ -1286,7 +1283,7 @@ void tst_QItemSelectionModel::select()
// test that isColumnSelected agrees
if (lastCommand & QItemSelectionModel::Columns) {
- for (int i=0; i<selectedList.count(); ++i)
+ for (int i=0; i<selectedList.size(); ++i)
QVERIFY2(selection->isColumnSelected(selectedList.at(i).column(),
model->parent(selectedList.at(i))),
QString("isColumnSelected(column: %1) does not match selectedIndexes()")
@@ -1463,15 +1460,15 @@ void tst_QItemSelectionModel::persistentselections()
QFETCH(IntList, insertColumns);
QFETCH(IntList, deleteRows);
QFETCH(IntList, deleteColumns);
- QFETCH(PairList, expectedList);
+ QFETCH(const PairList, expectedList);
// make sure the model is sane (5x5)
QCOMPARE(model->rowCount(QModelIndex()), 5);
QCOMPARE(model->columnCount(QModelIndex()), 5);
// do selections
- for (int i=0; i<commandList.count(); ++i) {
- if (indexList.count() == commandList.count()) {
+ for (int i=0; i<commandList.size(); ++i) {
+ if (indexList.size() == commandList.size()) {
QModelIndex index = model->index(indexList.at(i).first,
indexList.at(i).second,
QModelIndex());
@@ -1492,19 +1489,19 @@ void tst_QItemSelectionModel::persistentselections()
QVERIFY(selection->hasSelection());
// insert/delete row and/or columns
- if (insertRows.count() > 1)
+ if (insertRows.size() > 1)
model->insertRows(insertRows.at(0), insertRows.at(1), QModelIndex());
- if (insertColumns.count() > 1)
+ if (insertColumns.size() > 1)
model->insertColumns(insertColumns.at(0), insertColumns.at(1), QModelIndex());
- if (deleteRows.count() > 1)
+ if (deleteRows.size() > 1)
model->removeRows(deleteRows.at(0), deleteRows.at(1), QModelIndex());
- if (deleteColumns.count() > 1)
+ if (deleteColumns.size() > 1)
model->removeColumns(deleteColumns.at(0), deleteColumns.at(1), QModelIndex());
// check that the selected items are the correct number and indexes
QModelIndexList selectedList = selection->selectedIndexes();
- QCOMPARE(selectedList.count(), expectedList.count());
- foreach(IntPair pair, expectedList) {
+ QCOMPARE(selectedList.size(), expectedList.size());
+ for (const auto &pair : expectedList) {
QModelIndex index = model->index(pair.first, pair.second, QModelIndex());
QVERIFY(selectedList.contains(index));
}
@@ -1529,7 +1526,7 @@ void tst_QItemSelectionModel::resetModel()
selectionModel->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
model.reset();
@@ -1538,8 +1535,8 @@ void tst_QItemSelectionModel::resetModel()
selectionModel->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select);
- QCOMPARE(spy.count(), 2);
- QCOMPARE(spy.at(1).count(), 2);
+ QCOMPARE(spy.size(), 2);
+ QCOMPARE(spy.at(1).size(), 2);
// make sure we don't get an "old selection"
QCOMPARE(spy.at(1).at(1).userType(), qMetaTypeId<QItemSelection>());
QVERIFY(qvariant_cast<QItemSelection>(spy.at(1).at(1)).isEmpty());
@@ -1594,14 +1591,14 @@ void tst_QItemSelectionModel::removeRows()
QModelIndex br = model.index(selectBottom, selectRight);
selections.select(QItemSelection(tl, br), QItemSelectionModel::ClearAndSelect);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(selections.isSelected(tl));
QVERIFY(selections.isSelected(br));
QVERIFY(selections.hasSelection());
model.removeRows(removeTop, removeBottom - removeTop + 1);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
tl = model.index(expectedTop, expectedLeft);
br = model.index(expectedBottom, expectedRight);
QVERIFY(selections.isSelected(tl));
@@ -1657,14 +1654,14 @@ void tst_QItemSelectionModel::removeColumns()
QModelIndex br = model.index(selectBottom, selectRight);
selections.select(QItemSelection(tl, br), QItemSelectionModel::ClearAndSelect);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(selections.isSelected(tl));
QVERIFY(selections.isSelected(br));
QVERIFY(selections.hasSelection());
model.removeColumns(removeLeft, removeRight - removeLeft + 1);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
tl = model.index(expectedTop, expectedLeft);
br = model.index(expectedBottom, expectedRight);
QVERIFY(selections.isSelected(tl));
@@ -1679,7 +1676,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
{
QTest::addColumn<IntListList>("items");
QTest::addColumn<IntPairPairList>("initialSelectedRanges");
- QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
QTest::addColumn<int>("sortColumn");
QTest::addColumn<IntPairPairList>("expectedSelectedRanges");
@@ -1689,7 +1686,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntList() << 3 << 2 << 1 << 0))
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(3, 1)))
- << int(Qt::DescendingOrder)
+ << Qt::DescendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(3, 1)));
@@ -1699,7 +1696,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntList() << 3 << 2 << 1 << 0))
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(1, 1)))
- << int(Qt::DescendingOrder)
+ << Qt::DescendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(2, 0), IntPair(3, 1)));
@@ -1709,7 +1706,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntList() << 3 << 2 << 1 << 0))
<< (IntPairPairList()
<< IntPairPair(IntPair(1, 0), IntPair(2, 1)))
- << int(Qt::DescendingOrder)
+ << Qt::DescendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(1, 0), IntPair(2, 1)));
@@ -1720,7 +1717,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntPairPairList()
<< IntPairPair(IntPair(1, 0), IntPair(1, 1))
<< IntPairPair(IntPair(3, 0), IntPair(3, 1)))
- << int(Qt::AscendingOrder)
+ << Qt::AscendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(0, 1))
@@ -1730,12 +1727,12 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
void tst_QItemSelectionModel::modelLayoutChanged()
{
QFETCH(IntListList, items);
- QFETCH(IntPairPairList, initialSelectedRanges);
- QFETCH(int, sortOrder);
+ QFETCH(const IntPairPairList, initialSelectedRanges);
+ QFETCH(Qt::SortOrder, sortOrder);
QFETCH(int, sortColumn);
QFETCH(IntPairPairList, expectedSelectedRanges);
- MyStandardItemModel model(items.at(0).count(), items.count());
+ MyStandardItemModel model(items.at(0).size(), items.size());
// initialize model data
for (int i = 0; i < model.rowCount(); ++i) {
for (int j = 0; j < model.columnCount(); ++j) {
@@ -1746,9 +1743,9 @@ void tst_QItemSelectionModel::modelLayoutChanged()
// select initial ranges
QItemSelectionModel selectionModel(&model);
- foreach (IntPairPair range, initialSelectedRanges) {
- IntPair tl = range.first;
- IntPair br = range.second;
+ for (const auto &range : initialSelectedRanges) {
+ const auto &tl = range.first;
+ const auto &br = range.second;
QItemSelection selection(
model.index(tl.first, tl.second),
model.index(br.first, br.second));
@@ -1756,14 +1753,14 @@ void tst_QItemSelectionModel::modelLayoutChanged()
}
// sort the model
- model.sort(sortColumn, Qt::SortOrder(sortOrder));
+ model.sort(sortColumn, sortOrder);
// verify that selection is as expected
QItemSelection selection = selectionModel.selection();
- QCOMPARE(selection.count(), expectedSelectedRanges.count());
+ QCOMPARE(selection.size(), expectedSelectedRanges.size());
QCOMPARE(selectionModel.hasSelection(), !expectedSelectedRanges.isEmpty());
- for (int i = 0; i < expectedSelectedRanges.count(); ++i) {
+ for (int i = 0; i < expectedSelectedRanges.size(); ++i) {
IntPairPair expectedRange = expectedSelectedRanges.at(i);
IntPair expectedTl = expectedRange.first;
IntPair expectedBr = expectedRange.second;
@@ -1817,21 +1814,21 @@ void tst_QItemSelectionModel::selectedRows()
MyStandardItemModel model(rowCount, columnCount);
QItemSelectionModel selectionModel(&model);
- for (int i = 0; i < selectRows.count(); ++i)
+ for (int i = 0; i < selectRows.size(); ++i)
selectionModel.select(model.index(selectRows.at(i), 0),
QItemSelectionModel::Select
|QItemSelectionModel::Rows);
- for (int j = 0; j < selectRows.count(); ++j)
+ for (int j = 0; j < selectRows.size(); ++j)
QVERIFY(selectionModel.isRowSelected(expectedRows.at(j), QModelIndex()));
- for (int k = 0; k < selectRows.count(); ++k)
+ for (int k = 0; k < selectRows.size(); ++k)
QVERIFY(!selectionModel.isRowSelected(unexpectedRows.at(k), QModelIndex()));
QModelIndexList selectedRowIndexes = selectionModel.selectedRows(column);
- QCOMPARE(selectedRowIndexes.count(), expectedRows.count());
+ QCOMPARE(selectedRowIndexes.size(), expectedRows.size());
std::sort(selectedRowIndexes.begin(), selectedRowIndexes.end());
- for (int l = 0; l < selectedRowIndexes.count(); ++l) {
+ for (int l = 0; l < selectedRowIndexes.size(); ++l) {
QCOMPARE(selectedRowIndexes.at(l).row(), expectedRows.at(l));
QCOMPARE(selectedRowIndexes.at(l).column(), column);
}
@@ -1877,21 +1874,21 @@ void tst_QItemSelectionModel::selectedColumns()
MyStandardItemModel model(rowCount, columnCount);
QItemSelectionModel selectionModel(&model);
- for (int i = 0; i < selectColumns.count(); ++i)
+ for (int i = 0; i < selectColumns.size(); ++i)
selectionModel.select(model.index(0, selectColumns.at(i)),
QItemSelectionModel::Select
|QItemSelectionModel::Columns);
- for (int j = 0; j < selectColumns.count(); ++j)
+ for (int j = 0; j < selectColumns.size(); ++j)
QVERIFY(selectionModel.isColumnSelected(expectedColumns.at(j), QModelIndex()));
- for (int k = 0; k < selectColumns.count(); ++k)
+ for (int k = 0; k < selectColumns.size(); ++k)
QVERIFY(!selectionModel.isColumnSelected(unexpectedColumns.at(k), QModelIndex()));
QModelIndexList selectedColumnIndexes = selectionModel.selectedColumns(row);
- QCOMPARE(selectedColumnIndexes.count(), expectedColumns.count());
+ QCOMPARE(selectedColumnIndexes.size(), expectedColumns.size());
std::sort(selectedColumnIndexes.begin(), selectedColumnIndexes.end());
- for (int l = 0; l < selectedColumnIndexes.count(); ++l) {
+ for (int l = 0; l < selectedColumnIndexes.size(); ++l) {
QCOMPARE(selectedColumnIndexes.at(l).column(), expectedColumns.at(l));
QCOMPARE(selectedColumnIndexes.at(l).row(), row);
}
@@ -1922,18 +1919,18 @@ void tst_QItemSelectionModel::setCurrentIndex()
treemodel->index(0, 0, treemodel->index(1, 0)),
QItemSelectionModel::SelectCurrent);
- QCOMPARE(currentSpy.count(), 1);
- QCOMPARE(rowSpy.count(), 1);
- QCOMPARE(columnSpy.count(), 1);
+ QCOMPARE(currentSpy.size(), 1);
+ QCOMPARE(rowSpy.size(), 1);
+ QCOMPARE(columnSpy.size(), 1);
// Select another row in the same parent
selectionModel.setCurrentIndex(
treemodel->index(1, 0, treemodel->index(1, 0)),
QItemSelectionModel::SelectCurrent);
- QCOMPARE(currentSpy.count(), 2);
- QCOMPARE(rowSpy.count(), 2);
- QCOMPARE(columnSpy.count(), 1);
+ QCOMPARE(currentSpy.size(), 2);
+ QCOMPARE(rowSpy.size(), 2);
+ QCOMPARE(columnSpy.size(), 1);
}
void tst_QItemSelectionModel::splitOnInsert()
@@ -2034,12 +2031,16 @@ void tst_QItemSelectionModel::rowIntersectsSelection3()
QModelIndex parent;
QVERIFY(!selectionModel.rowIntersectsSelection(0, parent));
+ QVERIFY(!selectionModel.columnIntersectsSelection(0, parent));
parent = model.index(0, 0, parent);
QVERIFY(selectionModel.rowIntersectsSelection(0, parent));
+ QVERIFY(selectionModel.columnIntersectsSelection(0, parent));
parent = model.index(0, 0, parent);
QVERIFY(!selectionModel.rowIntersectsSelection(0, parent));
+ QVERIFY(!selectionModel.columnIntersectsSelection(0, parent));
parent = model.index(0, 0, parent);
QVERIFY(!selectionModel.rowIntersectsSelection(0, parent));
+ QVERIFY(!selectionModel.columnIntersectsSelection(0, parent));
}
void tst_QItemSelectionModel::unselectable()
@@ -2053,12 +2054,14 @@ void tst_QItemSelectionModel::unselectable()
}
QItemSelectionModel selectionModel(&model);
selectionModel.select(QItemSelection(model.index(0, 0), model.index(9, 0)), QItemSelectionModel::Select);
- QCOMPARE(selectionModel.selectedIndexes().count(), 10);
- QCOMPARE(selectionModel.selectedRows().count(), 10);
+ QCOMPARE(selectionModel.selectedIndexes().size(), 10);
+ QCOMPARE(selectionModel.selectedRows().size(), 10);
+ QVERIFY(selectionModel.hasSelection());
for (int j = 0; j < 10; ++j)
- model.item(j)->setFlags(0);
- QCOMPARE(selectionModel.selectedIndexes().count(), 0);
- QCOMPARE(selectionModel.selectedRows().count(), 0);
+ model.item(j)->setFlags({ });
+ QVERIFY(!selectionModel.hasSelection());
+ QCOMPARE(selectionModel.selectedIndexes().size(), 0);
+ QCOMPARE(selectionModel.selectedRows().size(), 0);
}
void tst_QItemSelectionModel::selectedIndexes()
@@ -2072,8 +2075,8 @@ void tst_QItemSelectionModel::selectedIndexes()
//we select the 1st row
selectionModel.select(selection, QItemSelectionModel::Rows | QItemSelectionModel::Select);
- QCOMPARE(selectionModel.selectedRows().count(), 1);
- QCOMPARE(selectionModel.selectedIndexes().count(), model.columnCount());
+ QCOMPARE(selectionModel.selectedRows().size(), 1);
+ QCOMPARE(selectionModel.selectedIndexes().size(), model.columnCount());
}
@@ -2081,18 +2084,18 @@ class QtTestTableModel: public QAbstractTableModel
{
Q_OBJECT
public:
- QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0)
+ QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = nullptr)
: QAbstractTableModel(parent)
, row_count(rows)
, column_count(columns)
{
}
- int rowCount(const QModelIndex& = QModelIndex()) const { return row_count; }
- int columnCount(const QModelIndex& = QModelIndex()) const { return column_count; }
+ int rowCount(const QModelIndex& = QModelIndex()) const override { return row_count; }
+ int columnCount(const QModelIndex& = QModelIndex()) const override { return column_count; }
bool isEditable(const QModelIndex &) const { return true; }
- QVariant data(const QModelIndex &idx, int role) const
+ QVariant data(const QModelIndex &idx, int role) const override
{
if (role == Qt::DisplayRole || role == Qt::EditRole)
return QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',')
@@ -2111,14 +2114,14 @@ void tst_QItemSelectionModel::layoutChanged()
QtTestTableModel model(1,1);
QItemSelectionModel selectionModel(&model);
selectionModel.select(model.index(0,0), QItemSelectionModel::Select);
- QCOMPARE(selectionModel.selectedIndexes().count() , 1);
+ QCOMPARE(selectionModel.selectedIndexes().size() , 1);
emit model.layoutAboutToBeChanged();
model.row_count = 5;
emit model.layoutChanged();
//The selection should not change.
- QCOMPARE(selectionModel.selectedIndexes().count() , 1);
+ QCOMPARE(selectionModel.selectedIndexes().size() , 1);
QCOMPARE(selectionModel.selectedIndexes().first() , model.index(0,0));
}
@@ -2126,43 +2129,43 @@ void tst_QItemSelectionModel::merge_data()
{
QTest::addColumn<QItemSelection>("init");
QTest::addColumn<QItemSelection>("other");
- QTest::addColumn<int>("command");
+ QTest::addColumn<QItemSelectionModel::SelectionFlag>("command");
QTest::addColumn<QItemSelection>("result");
QTest::newRow("Simple select")
<< QItemSelection()
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Select)
+ << QItemSelectionModel::Select
<< QItemSelection(model->index(2, 1) , model->index(3, 4));
QTest::newRow("Simple deselect")
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Deselect)
+ << QItemSelectionModel::Deselect
<< QItemSelection();
QTest::newRow("Simple Toggle deselect")
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Toggle)
+ << QItemSelectionModel::Toggle
<< QItemSelection();
QTest::newRow("Simple Toggle select")
<< QItemSelection()
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Toggle)
+ << QItemSelectionModel::Toggle
<< QItemSelection(model->index(2, 1) , model->index(3, 4));
QTest::newRow("Add select")
<< QItemSelection(model->index(2, 1) , model->index(3, 3))
<< QItemSelection(model->index(2, 2) , model->index(3, 4))
- << int(QItemSelectionModel::Select)
+ << QItemSelectionModel::Select
<< QItemSelection(model->index(2, 1) , model->index(3, 4));
QTest::newRow("Deselect")
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
<< QItemSelection(model->index(2, 2) , model->index(3, 4))
- << int(QItemSelectionModel::Deselect)
+ << QItemSelectionModel::Deselect
<< QItemSelection(model->index(2, 1) , model->index(3, 1));
QItemSelection r1(model->index(2, 1) , model->index(3, 1));
@@ -2170,7 +2173,7 @@ void tst_QItemSelectionModel::merge_data()
QTest::newRow("Toggle")
<< QItemSelection(model->index(2, 1) , model->index(3, 3))
<< QItemSelection(model->index(2, 2) , model->index(3, 4))
- << int(QItemSelectionModel::Toggle)
+ << QItemSelectionModel::Toggle
<< r1;
}
@@ -2178,15 +2181,18 @@ void tst_QItemSelectionModel::merge()
{
QFETCH(QItemSelection, init);
QFETCH(QItemSelection, other);
- QFETCH(int, command);
+ QFETCH(QItemSelectionModel::SelectionFlag, command);
QFETCH(QItemSelection, result);
- init.merge(other, QItemSelectionModel::SelectionFlags(command));
+ init.merge(other, command);
- foreach(const QModelIndex &idx, init.indexes())
- QVERIFY(result.contains(idx));
- foreach(const QModelIndex &idx, result.indexes())
- QVERIFY(init.contains(idx));
+ auto verify = [](const QModelIndexList &a, const QItemSelection &b)
+ {
+ for (const QModelIndex &idx : a)
+ QVERIFY(b.contains(idx));
+ };
+ verify(init.indexes(), result);
+ verify(result.indexes(), init);
}
void tst_QItemSelectionModel::isRowSelected()
@@ -2195,7 +2201,7 @@ void tst_QItemSelectionModel::isRowSelected()
model.setData(model.index(0,0), 0, Qt::UserRole - 1);
QItemSelectionModel sel(&model);
sel.select( QItemSelection(model.index(0,0), model.index(0, 1)), QItemSelectionModel::Select);
- QCOMPARE(sel.selectedIndexes().count(), 1);
+ QCOMPARE(sel.selectedIndexes().size(), 1);
QVERIFY(sel.isRowSelected(0, QModelIndex()));
}
@@ -2211,8 +2217,8 @@ void tst_QItemSelectionModel::childrenDeselectionSignal()
}
QModelIndex root = model.index(0,0);
- QModelIndex par = root.child(0,0);
- QModelIndex sel = par.child(0,0);
+ QModelIndex par = model.index(0, 0, root);
+ QModelIndex sel = model.index(0, 0, par);
QItemSelectionModel selectionModel(&model);
selectionModel.select(sel, QItemSelectionModel::SelectCurrent);
@@ -2220,7 +2226,7 @@ void tst_QItemSelectionModel::childrenDeselectionSignal()
QSignalSpy deselectSpy(&selectionModel, &QItemSelectionModel::selectionChanged);
QVERIFY(deselectSpy.isValid());
model.removeRows(0, 1, root);
- QCOMPARE(deselectSpy.count(), 1);
+ QCOMPARE(deselectSpy.size(), 1);
// More testing stress for the patch.
model.clear();
@@ -2240,16 +2246,16 @@ void tst_QItemSelectionModel::childrenDeselectionSignal()
}
}
- sel = model.index(0, 0).child(0, 0);
+ sel = model.index(0, 0, model.index(0, 0));
selectionModel.select(sel, QItemSelectionModel::Select);
- QModelIndex sel2 = model.index(1, 0).child(0, 0);
+ QModelIndex sel2 = model.index(0, 0, model.index(1, 0));
selectionModel.select(sel2, QItemSelectionModel::Select);
QVERIFY(selectionModel.selection().contains(sel));
QVERIFY(selectionModel.selection().contains(sel2));
deselectSpy.clear();
model.removeRow(0, model.index(0, 0));
- QCOMPARE(deselectSpy.count(), 1);
+ QCOMPARE(deselectSpy.size(), 1);
QVERIFY(!selectionModel.selection().contains(sel));
QVERIFY(selectionModel.selection().contains(sel2));
}
@@ -2264,24 +2270,23 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected1()
QCOMPARE(model.rowCount(), 3);
QCOMPARE(proxy.rowCount(), 3);
- proxy.setFilterRegExp( QRegExp("f"));
+ proxy.setFilterRegularExpression(QRegularExpression("f"));
QCOMPARE(proxy.rowCount(), 2);
- QList<QPersistentModelIndex> indexList;
- indexList << proxy.index(0,0) << proxy.index(1,0);
- selection.select( QItemSelection(indexList.first(), indexList.last()), QItemSelectionModel::Select);
+ const QList<QPersistentModelIndex> indexList({proxy.index(0,0), proxy.index(1,0)});
+ selection.select(QItemSelection(indexList.first(), indexList.last()), QItemSelectionModel::Select);
//let's check the selection hasn't changed
- QCOMPARE(selection.selectedIndexes().count(), indexList.count());
- foreach(QPersistentModelIndex index, indexList)
+ QCOMPARE(selection.selectedIndexes().size(), indexList.size());
+ for (const auto &index : indexList)
QVERIFY(selection.isSelected(index));
- proxy.setFilterRegExp(QRegExp());
+ proxy.setFilterRegularExpression(QRegularExpression());
QCOMPARE(proxy.rowCount(), 3);
//let's check the selection hasn't changed
- QCOMPARE(selection.selectedIndexes().count(), indexList.count());
- foreach(QPersistentModelIndex index, indexList)
+ QCOMPARE(selection.selectedIndexes().size(), indexList.size());
+ for (const auto &index : indexList)
QVERIFY(selection.isSelected(index));
}
@@ -2292,7 +2297,7 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected2()
struct MyFilterModel : public QSortFilterProxyModel
{ // Override sort filter proxy to remove even numbered rows.
bool filtering;
- virtual bool filterAcceptsRow( int source_row, const QModelIndex& /* source_parent */) const
+ virtual bool filterAcceptsRow( int source_row, const QModelIndex& /* source_parent */) const override
{
return !filtering || !( source_row & 1 );
}
@@ -2321,17 +2326,16 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected2()
selection.select( QItemSelection(proxy.index(0,0), proxy.index(proxy.rowCount() - 1, proxy.columnCount() - 1)), QItemSelectionModel::Select);
- QList<QPersistentModelIndex> indexList;
- foreach(const QModelIndex &id, selection.selectedIndexes())
- indexList << id;
+ const auto selIndexes = selection.selectedIndexes();
+ const QList<QPersistentModelIndex> indexList(selIndexes.begin(), selIndexes.end());
proxy.filtering = false;
proxy.invalidate();
QCOMPARE(proxy.rowCount(), int(cNumRows));
//let's check the selection hasn't changed
- QCOMPARE(selection.selectedIndexes().count(), indexList.count());
- foreach(QPersistentModelIndex index, indexList)
+ QCOMPARE(selection.selectedIndexes().size(), indexList.size());
+ for (const auto &index : indexList)
QVERIFY(selection.isSelected(index));
}
@@ -2354,11 +2358,11 @@ void tst_QItemSelectionModel::layoutChangedTreeSelection()
selModel.select(sub23.index(), QItemSelectionModel::Select);
QModelIndexList list = selModel.selectedIndexes();
- QCOMPARE(list.count(), 4);
+ QCOMPARE(list.size(), 4);
model.sort(0); //this will provoke a relayout
- QCOMPARE(selModel.selectedIndexes().count(), 4);
+ QCOMPARE(selModel.selectedIndexes().size(), 4);
}
class RemovalObserver : public QObject
@@ -2375,7 +2379,8 @@ public:
public slots:
void selectionChanged(const QItemSelection & /* selected */, const QItemSelection &deselected)
{
- foreach(const QModelIndex &index, deselected.indexes()) {
+ const auto deselIndexes = deselected.indexes();
+ for (const auto &index : deselIndexes) {
QVERIFY(!m_itemSelectionModel->selection().contains(index));
}
QCOMPARE(m_itemSelectionModel->selection().size(), 2);
@@ -2408,165 +2413,6 @@ void tst_QItemSelectionModel::deselectRemovedMiddleRange()
QCOMPARE(spy.size(), 1);
}
-static QStandardItemModel* getModel(QObject *parent)
-{
- QStandardItemModel *model = new QStandardItemModel(parent);
-
- for (int i = 0; i < 4; ++i) {
- QStandardItem *parentItem = model->invisibleRootItem();
- QList<QStandardItem*> list;
- const QString prefix = QLatin1String("item ") + QString::number(i) + QLatin1String(", ");
- for (int j = 0; j < 4; ++j) {
- list.append(new QStandardItem(prefix + QString::number(j)));
- }
- parentItem->appendRow(list);
- parentItem = list.first();
- for (int j = 0; j < 4; ++j) {
- QList<QStandardItem*> list;
- for (int k = 0; k < 4; ++k) {
- list.append(new QStandardItem(prefix + QString::number(j)));
- }
- parentItem->appendRow(list);
- }
- }
- return model;
-}
-
-enum Result {
- LessThan,
- NotLessThan,
- NotEqual
-};
-
-Q_DECLARE_METATYPE(Result);
-
-void tst_QItemSelectionModel::rangeOperatorLessThan_data()
-{
- QTest::addColumn<int>("parent1");
- QTest::addColumn<int>("top1");
- QTest::addColumn<int>("left1");
- QTest::addColumn<int>("bottom1");
- QTest::addColumn<int>("right1");
- QTest::addColumn<int>("parent2");
- QTest::addColumn<int>("top2");
- QTest::addColumn<int>("left2");
- QTest::addColumn<int>("bottom2");
- QTest::addColumn<int>("right2");
- QTest::addColumn<Result>("result");
-
- QTest::newRow("lt01") << -1 << 0 << 0 << 3 << 3
- << -1 << 0 << 0 << 3 << 3 << NotLessThan;
-
- QTest::newRow("lt02") << -1 << 0 << 0 << 2 << 3
- << -1 << 0 << 0 << 3 << 3 << LessThan;
- QTest::newRow("lt03") << -1 << 0 << 0 << 3 << 2
- << -1 << 0 << 0 << 3 << 3 << LessThan;
- QTest::newRow("lt04") << -1 << 0 << 0 << 2 << 2
- << -1 << 0 << 0 << 3 << 3 << LessThan;
-
- QTest::newRow("lt05") << -1 << 0 << 0 << 3 << 3
- << -1 << 0 << 0 << 2 << 3 << NotLessThan;
- QTest::newRow("lt06") << -1 << 0 << 0 << 3 << 3
- << -1 << 0 << 0 << 3 << 2 << NotLessThan;
- QTest::newRow("lt07") << -1 << 0 << 0 << 3 << 3
- << -1 << 0 << 0 << 2 << 2 << NotLessThan;
-
- QTest::newRow("lt08") << -1 << 0 << 0 << 3 << 3
- << 0 << 0 << 0 << 3 << 3 << NotEqual;
- QTest::newRow("lt09") << 1 << 0 << 0 << 3 << 3
- << 0 << 0 << 0 << 3 << 3 << NotEqual;
- QTest::newRow("lt10") << 1 << 0 << 0 << 1 << 1
- << 0 << 2 << 2 << 3 << 3 << NotEqual;
- QTest::newRow("lt11") << 1 << 2 << 2 << 3 << 3
- << 0 << 0 << 0 << 1 << 1 << NotEqual;
-
- QTest::newRow("lt12") << -1 << 0 << 0 << 1 << 1
- << -1 << 2 << 2 << 3 << 3 << LessThan;
- QTest::newRow("lt13") << -1 << 2 << 2 << 3 << 3
- << -1 << 0 << 0 << 1 << 1 << NotLessThan;
- QTest::newRow("lt14") << 1 << 0 << 0 << 1 << 1
- << 1 << 2 << 2 << 3 << 3 << LessThan;
- QTest::newRow("lt15") << 1 << 2 << 2 << 3 << 3
- << 1 << 0 << 0 << 1 << 1 << NotLessThan;
-
- QTest::newRow("lt16") << -1 << 0 << 0 << 2 << 2
- << -1 << 1 << 1 << 3 << 3 << LessThan;
- QTest::newRow("lt17") << -1 << 1 << 1 << 3 << 3
- << -1 << 0 << 0 << 2 << 2 << NotLessThan;
- QTest::newRow("lt18") << 1 << 0 << 0 << 2 << 2
- << 1 << 1 << 1 << 3 << 3 << LessThan;
- QTest::newRow("lt19") << 1 << 1 << 1 << 3 << 3
- << 1 << 0 << 0 << 2 << 2 << NotLessThan;
-}
-
-void tst_QItemSelectionModel::rangeOperatorLessThan()
-{
- QStandardItemModel *model1 = getModel(this);
- QStandardItemModel *model2 = getModel(this);
-
- QFETCH(int, parent1);
- QFETCH(int, top1);
- QFETCH(int, left1);
- QFETCH(int, bottom1);
- QFETCH(int, right1);
- QFETCH(int, parent2);
- QFETCH(int, top2);
- QFETCH(int, left2);
- QFETCH(int, bottom2);
- QFETCH(int, right2);
- QFETCH(Result, result);
-
- QModelIndex p1 = model1->index(parent1, 0);
-
- QModelIndex tl1 = model1->index(top1, left1, p1);
- QModelIndex br1 = model1->index(bottom1, right1, p1);
-
- QItemSelectionRange r1(tl1, br1);
-
- QModelIndex p2 = model1->index(parent2, 0);
-
- QModelIndex tl2 = model1->index(top2, left2, p2);
- QModelIndex br2 = model1->index(bottom2, right2, p2);
-
- QItemSelectionRange r2(tl2, br2);
-
- if (result == LessThan)
- QVERIFY(r1 < r2);
- else if (result == NotLessThan)
- QVERIFY(!(r1 < r2));
- else if (result == NotEqual)
- if (!(r1 < r2))
- QVERIFY(r2 < r1);
-
- // Ranges in different models are always non-equal
-
- QModelIndex p3 = model2->index(parent1, 0);
-
- QModelIndex tl3 = model2->index(top1, left1, p3);
- QModelIndex br3 = model2->index(bottom1, right1, p3);
-
- QItemSelectionRange r3(tl3, br3);
-
- if (!(r1 < r3))
- QVERIFY(r3 < r1);
-
- if (!(r2 < r3))
- QVERIFY(r3 < r2);
-
- QModelIndex p4 = model2->index(parent2, 0);
-
- QModelIndex tl4 = model2->index(top2, left2, p4);
- QModelIndex br4 = model2->index(bottom2, right2, p4);
-
- QItemSelectionRange r4(tl4, br4);
-
- if (!(r1 < r4))
- QVERIFY(r4 < r1);
-
- if (!(r2 < r4))
- QVERIFY(r4 < r2);
-}
-
void tst_QItemSelectionModel::setModel()
{
QItemSelectionModel sel;
@@ -2575,13 +2421,36 @@ void tst_QItemSelectionModel::setModel()
QStringListModel model(QStringList() << "Blah" << "Blah" << "Blah");
sel.setModel(&model);
QCOMPARE(sel.model(), &model);
- QCOMPARE(modelChangedSpy.count(), 1);
+ QCOMPARE(modelChangedSpy.size(), 1);
sel.select(model.index(0), QItemSelectionModel::Select);
QVERIFY(!sel.selection().isEmpty());
sel.setModel(0);
QVERIFY(sel.selection().isEmpty());
}
+void tst_QItemSelectionModel::bindableModel()
+{
+ QItemSelectionModel sel;
+ QVERIFY(!sel.model());
+
+ std::unique_ptr<QStringListModel> firstModel(
+ new QStringListModel(QStringList { "Some", "random", "content" }));
+ std::unique_ptr<QStringListModel> changedModel(
+ new QStringListModel(QStringList { "Other", "random", "content" }));
+
+ QTestPrivate::testReadWritePropertyBasics<QItemSelectionModel, QAbstractItemModel *>(
+ sel, firstModel.get(), changedModel.get(), "model");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QItemSelectionModel::model");
+ return;
+ }
+
+ // check that model is set to nullptr when the object pointed to is deleted:
+ sel.setModel(firstModel.get());
+ firstModel.reset();
+ QCOMPARE(sel.model(), nullptr);
+}
+
void tst_QItemSelectionModel::testDifferentModels()
{
QStandardItemModel model1;
@@ -2611,7 +2480,7 @@ class SelectionObserver : public QObject
{
Q_OBJECT
public:
- SelectionObserver(QAbstractItemModel *model, QObject *parent = 0)
+ SelectionObserver(QAbstractItemModel *model, QObject *parent = nullptr)
: QObject(parent), m_model(model), m_selectionModel(0)
{
connect(model, SIGNAL(modelReset()), SLOT(modelReset()));
@@ -2633,9 +2502,9 @@ private slots:
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
- foreach(const QItemSelectionRange &range, selected)
+ for (const auto &range : selected)
QVERIFY(range.isValid());
- foreach(const QItemSelectionRange &range, deselected)
+ for (const auto &range : deselected)
QVERIFY(range.isValid());
}
@@ -2675,12 +2544,12 @@ class DuplicateItemSelectionModel : public QItemSelectionModel
{
Q_OBJECT
public:
- DuplicateItemSelectionModel(QItemSelectionModel *target, QAbstractItemModel *model, QObject *parent = 0)
+ DuplicateItemSelectionModel(QItemSelectionModel *target, QAbstractItemModel *model, QObject *parent = nullptr)
: QItemSelectionModel(model, parent), m_target(target)
{
}
- void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
+ void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override
{
QItemSelectionModel::select(selection, command);
m_target->select(selection, command);
@@ -2688,13 +2557,13 @@ public:
using QItemSelectionModel::select;
- void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
+ void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) override
{
QItemSelectionModel::setCurrentIndex(index, command);
m_target->setCurrentIndex(index, command);
}
- void clearCurrentIndex()
+ void clearCurrentIndex() override
{
QItemSelectionModel::clearCurrentIndex();
m_target->clearCurrentIndex();
@@ -2852,6 +2721,9 @@ void tst_QItemSelectionModel::QTBUG48402()
model.removeRows(removeTop, removeBottom - removeTop + 1);
QCOMPARE(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(dtl, dbr));
+ QT_TEST_EQUALITY_OPS(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(dtl, dbr), true);
+ QT_TEST_EQUALITY_OPS(QItemSelectionRange(), QItemSelectionRange(), true);
+ QT_TEST_EQUALITY_OPS(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(), false);
}
void tst_QItemSelectionModel::QTBUG58851_data()
@@ -2919,7 +2791,7 @@ void tst_QItemSelectionModel::QTBUG58851()
QVERIFY(selections.isSelected(i));
}
proxy.sort(1, Qt::DescendingOrder);
- QCOMPARE(selections.selectedIndexes().count(), (int)expectedSelectedIndexes.size());
+ QCOMPARE(selections.selectedIndexes().size(), (int)expectedSelectedIndexes.size());
for (const QPersistentModelIndex &i : expectedSelectedIndexes) {
QVERIFY(selections.isSelected(i));
}
@@ -2993,12 +2865,12 @@ void tst_QItemSelectionModel::QTBUG18001()
QItemSelectionModel selectionModel(&model);
- for (int i = 0; i < indexesToSelect.count(); ++i) {
+ for (int i = 0; i < indexesToSelect.size(); ++i) {
QModelIndex idx = model.index( indexesToSelect.at(i).first, indexesToSelect.at(i).second );
selectionModel.select(idx, QItemSelectionModel::SelectionFlag(selectionCommands.at(i)));
}
- for (int i = 0; i < expectedSelectedRows.count(); ++i) {
+ for (int i = 0; i < expectedSelectedRows.size(); ++i) {
const bool expected = expectedSelectedRows.at(i);
const bool actual = selectionModel.isRowSelected(i, QModelIndex());
QByteArray description = QByteArray("Row ") + QByteArray::number(i)
@@ -3007,7 +2879,7 @@ void tst_QItemSelectionModel::QTBUG18001()
QVERIFY2(expected == actual, description.data());
}
- for (int i = 0; i < expectedSelectedColums.count(); ++i) {
+ for (int i = 0; i < expectedSelectedColums.size(); ++i) {
const bool expected = expectedSelectedColums.at(i);
const bool actual = selectionModel.isColumnSelected(i, QModelIndex());
QByteArray description = QByteArray("Col ") + QByteArray::number(i)
@@ -3018,5 +2890,94 @@ void tst_QItemSelectionModel::QTBUG18001()
}
+void tst_QItemSelectionModel::QTBUG93305()
+{
+ // make sure the model is sane (5x5)
+ QCOMPARE(model->rowCount(QModelIndex()), 5);
+ QCOMPARE(model->columnCount(QModelIndex()), 5);
+
+ QSignalSpy spy(selection, &QItemSelectionModel::selectionChanged);
+
+ // select in row 1
+ QModelIndex index = model->index(1, 0, QModelIndex());
+ selection->select(index, QItemSelectionModel::ClearAndSelect);
+ QVERIFY(selection->hasSelection());
+ QCOMPARE(spy.size(), 1);
+
+ // removing row 0 does not change which cells are selected, but it
+ // does change the row number of the selected cells. Thus it changes
+ // what selectedIndexes() returns.
+ // The property selectedIndexes() has selectionChanged() as its
+ // NOTIFY signal, so selectionChanged() should be emitted.
+
+ // delete row 0
+ model->removeRows(0, 1, QModelIndex());
+ QVERIFY(selection->hasSelection());
+ QCOMPARE(spy.size(), 2);
+
+ // inserting a row before the first row again does not change which cells
+ // are selected, but does change the row number of the selected cells.
+ // This changes what selectedIndexes() returns and should thus trigger
+ // a selectionChanged() signal
+
+ // insert row 0 again
+ model->insertRows(0, 1, QModelIndex());
+ QVERIFY(selection->hasSelection());
+ QCOMPARE(spy.size(), 3);
+
+ // test for inserting multiple (6) rows
+ model->insertRows(0, 6, QModelIndex());
+ QVERIFY(selection->hasSelection());
+ QCOMPARE(spy.size(), 4);
+}
+
+static void (*oldMessageHandler)(QtMsgType, const QMessageLogContext&, const QString&);
+static bool signalError = false;
+
+// detect disconnect warning:
+// qt.core.qobject.connect: QObject::disconnect: No such signal
+void tst_QItemSelectionModel::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ Q_ASSERT(oldMessageHandler);
+
+ if (type == QtWarningMsg
+ && QString(context.category) == "qt.core.qobject.connect"
+ && msg.contains("No such")) {
+ signalError = true;
+ }
+
+ return oldMessageHandler(type, context, msg);
+}
+
+void tst_QItemSelectionModel::testSignalsDisconnection()
+{
+ oldMessageHandler = qInstallMessageHandler(messageHandler);
+ auto resetMessageHandler = qScopeGuard([] { qInstallMessageHandler(oldMessageHandler); });
+ auto *newModel = new QStandardItemModel(model);
+ selection->setModel(newModel);
+ QSignalSpy spy(newModel, &QObject::destroyed);
+ delete newModel;
+ QTRY_COMPARE(spy.count(), 1);
+ qDebug() << spy;
+ selection->setModel(nullptr);
+ QVERIFY(!signalError);
+}
+
+void tst_QItemSelectionModel::destroyModel()
+{
+ auto itemModel = std::make_unique<QStandardItemModel>(5, 5);
+ auto selectionModel = std::make_unique<QItemSelectionModel>();
+ selectionModel->setModel(itemModel.get());
+ selectionModel->select(itemModel->index(0, 0), QItemSelectionModel::Select);
+ QVERIFY(!selectionModel->selection().isEmpty());
+ selectionModel->setCurrentIndex(itemModel->index(1, 0), QItemSelectionModel::Select);
+ QVERIFY(selectionModel->currentIndex().isValid());
+
+ QTest::failOnWarning(QRegularExpression(".*"));
+ itemModel.reset();
+ QVERIFY(!selectionModel->currentIndex().isValid());
+ QVERIFY(selectionModel->selection().isEmpty());
+}
+
QTEST_MAIN(tst_QItemSelectionModel)
#include "tst_qitemselectionmodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/CMakeLists.txt
new file mode 100644
index 0000000000..5427c52e78
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsortfilterproxymodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsortfilterproxymodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsortfilterproxymodel
+ SOURCES
+ ../../../other/qabstractitemmodelutils/dynamictreemodel.cpp ../../../other/qabstractitemmodelutils/dynamictreemodel.h
+ tst_qsortfilterproxymodel.cpp
+ INCLUDE_DIRECTORIES
+ ../../../other/qabstractitemmodelutils
+ LIBRARIES
+ Qt::Gui
+ Qt::Widgets
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
new file mode 100644
index 0000000000..0e027461aa
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -0,0 +1,5501 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "tst_qsortfilterproxymodel.h"
+#include "dynamictreemodel.h"
+
+#include <QDebug>
+#include <QComboBox>
+#include <QSortFilterProxyModel>
+#include <QStandardItem>
+#include <QStringListModel>
+#include <QTableView>
+#include <QTreeView>
+#include <QTest>
+#include <QStack>
+#include <QSignalSpy>
+#include <QAbstractItemModelTester>
+#include <QtTest/private/qpropertytesthelper_p.h>
+
+Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels")
+
+using IntPair = QPair<int, int>;
+using IntList = QList<int>;
+using IntPairList = QList<IntPair>;
+
+// Testing get/set functions
+void tst_QSortFilterProxyModel::getSetCheck()
+{
+ QSortFilterProxyModel obj1;
+ QCOMPARE(obj1.sourceModel(), nullptr);
+ // int QSortFilterProxyModel::filterKeyColumn()
+ // void QSortFilterProxyModel::setFilterKeyColumn(int)
+ obj1.setFilterKeyColumn(0);
+ QCOMPARE(0, obj1.filterKeyColumn());
+ obj1.setFilterKeyColumn(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.filterKeyColumn());
+ obj1.setFilterKeyColumn(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.filterKeyColumn());
+}
+
+Q_DECLARE_METATYPE(Qt::MatchFlag)
+void tst_QSortFilterProxyModel::initTestCase()
+{
+ qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
+ qRegisterMetaType<QList<QPersistentModelIndex> >();
+ qRegisterMetaType<Qt::MatchFlag>();
+ m_model = new QStandardItemModel(0, 1);
+ m_proxy = new QSortFilterProxyModel();
+ m_proxy->setSourceModel(m_model);
+ new QAbstractItemModelTester(m_proxy, this);
+}
+
+void tst_QSortFilterProxyModel::cleanupTestCase()
+{
+ delete m_proxy;
+ delete m_model;
+}
+
+void tst_QSortFilterProxyModel::cleanup()
+{
+ m_proxy->setFilterRegularExpression(QRegularExpression());
+ m_proxy->sort(-1, Qt::AscendingOrder);
+ m_model->clear();
+ m_model->insertColumns(0, 1);
+ QCoreApplication::processEvents(); // cleanup possibly queued events
+}
+
+/*
+ tests
+*/
+
+void tst_QSortFilterProxyModel::sort_data()
+{
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<Qt::CaseSensitivity>("sortCaseSensitivity");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat descending") << Qt::DescendingOrder
+ << Qt::CaseSensitive
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima"
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel"
+ << "uniform"
+ << "alpha"
+ << "echo"
+ << "golf"
+ << "quebec"
+ << "foxtrot"
+ << "india"
+ << "romeo"
+ << "november"
+ << "oskar"
+ << "zulu"
+ << "kilo"
+ << "whiskey"
+ << "mike"
+ << "papa"
+ << "sierra"
+ << "xray"
+ << "viktor")
+ << (QStringList()
+ << "zulu"
+ << "yankee"
+ << "xray"
+ << "whiskey"
+ << "viktor"
+ << "uniform"
+ << "tango"
+ << "sierra"
+ << "romeo"
+ << "quebec"
+ << "papa"
+ << "oskar"
+ << "november"
+ << "mike"
+ << "lima"
+ << "kilo"
+ << "juliet"
+ << "india"
+ << "hotel"
+ << "golf"
+ << "foxtrot"
+ << "echo"
+ << "delta"
+ << "charlie"
+ << "bravo"
+ << "alpha");
+ QTest::newRow("flat ascending") << Qt::AscendingOrder
+ << Qt::CaseSensitive
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima"
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel"
+ << "uniform"
+ << "alpha"
+ << "echo"
+ << "golf"
+ << "quebec"
+ << "foxtrot"
+ << "india"
+ << "romeo"
+ << "november"
+ << "oskar"
+ << "zulu"
+ << "kilo"
+ << "whiskey"
+ << "mike"
+ << "papa"
+ << "sierra"
+ << "xray"
+ << "viktor")
+ << (QStringList()
+ << "alpha"
+ << "bravo"
+ << "charlie"
+ << "delta"
+ << "echo"
+ << "foxtrot"
+ << "golf"
+ << "hotel"
+ << "india"
+ << "juliet"
+ << "kilo"
+ << "lima"
+ << "mike"
+ << "november"
+ << "oskar"
+ << "papa"
+ << "quebec"
+ << "romeo"
+ << "sierra"
+ << "tango"
+ << "uniform"
+ << "viktor"
+ << "whiskey"
+ << "xray"
+ << "yankee"
+ << "zulu");
+ QTest::newRow("case insensitive") << Qt::AscendingOrder
+ << Qt::CaseInsensitive
+ << (QStringList()
+ << "alpha" << "BETA" << "Gamma" << "delta")
+ << (QStringList()
+ << "alpha" << "BETA" << "delta" << "Gamma");
+ QTest::newRow("case sensitive") << Qt::AscendingOrder
+ << Qt::CaseSensitive
+ << (QStringList()
+ << "alpha" << "BETA" << "Gamma" << "delta")
+ << (QStringList()
+ << "BETA" << "Gamma" << "alpha" << "delta");
+
+ QStringList list;
+ for (int i = 10000; i < 20000; ++i)
+ list.append(QStringLiteral("Number: ") + QString::number(i));
+ QTest::newRow("large set ascending") << Qt::AscendingOrder << Qt::CaseSensitive << list << list;
+}
+
+void tst_QSortFilterProxyModel::sort()
+{
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(Qt::CaseSensitivity, sortCaseSensitivity);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+
+ // prepare model
+ QStandardItem *root = m_model->invisibleRootItem ();
+ QList<QStandardItem *> items;
+ for (int i = 0; i < initial.size(); ++i) {
+ items.append(new QStandardItem(initial.at(i)));
+ }
+ root->insertRows(0, items);
+ QCOMPARE(m_model->rowCount(QModelIndex()), initial.size());
+ QCOMPARE(m_model->columnCount(QModelIndex()), 1);
+
+ // make sure the proxy is unsorted
+ QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
+ QCOMPARE(m_proxy->rowCount(QModelIndex()), initial.size());
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ // sort
+ m_proxy->sort(0, sortOrder);
+ m_proxy->setSortCaseSensitivity(sortCaseSensitivity);
+
+ // make sure the model is unchanged
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+ // make sure the proxy is sorted
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ // restore the unsorted order in the given order
+ m_proxy->sort(-1, sortOrder);
+
+ // make sure the proxy is sorted by source row in the given order
+ int sourceIndex = sortOrder == Qt::AscendingOrder ? 0 : initial.size() - 1;
+ int adjustmentValue = sortOrder == Qt::AscendingOrder ? 1 : -1;
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(sourceIndex));
+ sourceIndex += adjustmentValue;
+ }
+}
+
+void tst_QSortFilterProxyModel::sortHierarchy_data()
+{
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat ascending")
+ << Qt::AscendingOrder
+ << (QStringList()
+ << "c" << "f" << "d" << "e" << "a" << "b")
+ << (QStringList()
+ << "a" << "b" << "c" << "d" << "e" << "f");
+
+ QTest::newRow("simple hierarchy")
+ << Qt::AscendingOrder
+ << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">")
+ << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">");
+
+ QTest::newRow("hierarchical ascending")
+ << Qt::AscendingOrder
+ << (QStringList()
+ << "c"
+ << "<"
+ << "h"
+ << "<"
+ << "2"
+ << "0"
+ << "1"
+ << ">"
+ << "g"
+ << "i"
+ << ">"
+ << "b"
+ << "<"
+ << "l"
+ << "k"
+ << "<"
+ << "8"
+ << "7"
+ << "9"
+ << ">"
+ << "m"
+ << ">"
+ << "a"
+ << "<"
+ << "z"
+ << "y"
+ << "x"
+ << ">")
+ << (QStringList()
+ << "a"
+ << "<"
+ << "x"
+ << "y"
+ << "z"
+ << ">"
+ << "b"
+ << "<"
+ << "k"
+ << "<"
+ << "7"
+ << "8"
+ << "9"
+ << ">"
+ << "l"
+ << "m"
+ << ">"
+ << "c"
+ << "<"
+ << "g"
+ << "h"
+ << "<"
+ << "0"
+ << "1"
+ << "2"
+ << ">"
+ << "i"
+ << ">");
+}
+
+void tst_QSortFilterProxyModel::sortHierarchy()
+{
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+
+ buildHierarchy(initial, m_model);
+ checkHierarchy(initial, m_model);
+ checkHierarchy(initial, m_proxy);
+ m_proxy->sort(0, sortOrder);
+ checkHierarchy(initial, m_model);
+ checkHierarchy(expected, m_proxy);
+}
+
+void tst_QSortFilterProxyModel::insertRows_data()
+{
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+ QTest::addColumn<QStringList>("insert");
+ QTest::addColumn<int>("position");
+
+ QTest::newRow("insert one row in the middle")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "Three")
+ << 2;
+
+ QTest::newRow("insert one row in the beginning")
+ << (QStringList()
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "One")
+ << 0;
+
+ QTest::newRow("insert one row in the end")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ <<"Five")
+ << 4;
+}
+
+void tst_QSortFilterProxyModel::insertRows()
+{
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+ QFETCH(QStringList, insert);
+ QFETCH(int, position);
+ // prepare model
+ m_model->insertRows(0, initial.size(), QModelIndex());
+ //m_model->insertColumns(0, 1, QModelIndex());
+ QCOMPARE(m_model->columnCount(QModelIndex()), 1);
+ QCOMPARE(m_model->rowCount(QModelIndex()), initial.size());
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ m_model->setData(index, initial.at(row), Qt::DisplayRole);
+ }
+ // make sure the model correct before insert
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+ // make sure the proxy is correct before insert
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ // insert the row
+ m_proxy->insertRows(position, insert.size(), QModelIndex());
+ QCOMPARE(m_model->rowCount(QModelIndex()), expected.size());
+ QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.size());
+
+ // set the data for the inserted row
+ for (int i = 0; i < insert.size(); ++i) {
+ QModelIndex index = m_proxy->index(position + i, 0, QModelIndex());
+ m_proxy->setData(index, insert.at(i), Qt::DisplayRole);
+ }
+
+ // make sure the model correct after insert
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ // make sure the proxy is correct after insert
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::prependRow()
+{
+ //this tests that data is correctly handled by the sort filter when prepending a row
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QStandardItem item("root");
+ model.appendRow(&item);
+
+ QStandardItem sub("sub");
+ item.appendRow(&sub);
+
+ sub.appendRow(new QStandardItem("test1"));
+ sub.appendRow(new QStandardItem("test2"));
+
+ QStandardItem sub2("sub2");
+ sub2.appendRow(new QStandardItem("sub3"));
+ item.insertRow(0, &sub2);
+
+ QModelIndex index_sub2 = proxy.mapFromSource(model.indexFromItem(&sub2));
+
+ QCOMPARE(sub2.rowCount(), proxy.rowCount(index_sub2));
+ QCOMPARE(proxy.rowCount(QModelIndex()), 1); //only the "root" item is there
+}
+
+void tst_QSortFilterProxyModel::appendRowFromCombobox_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QString>("newitem");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("filter_out_second_last_item")
+ << "^[0-9]*$"
+ << (QStringList() << "a" << "1")
+ << "2"
+ << (QStringList() << "a" << "1" << "2");
+
+ QTest::newRow("filter_out_everything")
+ << "^c*$"
+ << (QStringList() << "a" << "b")
+ << "c"
+ << (QStringList() << "a" << "b" << "c");
+
+ QTest::newRow("no_filter")
+ << ""
+ << (QStringList() << "0" << "1")
+ << "2"
+ << (QStringList() << "0" << "1" << "2");
+
+ QTest::newRow("filter_out_last_item")
+ << "^[a-z]*$"
+ << (QStringList() << "a" << "1")
+ << "b"
+ << (QStringList() << "a" << "1" << "b");
+}
+
+void tst_QSortFilterProxyModel::appendRowFromCombobox()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(QString, newitem);
+ QFETCH(QStringList, expected);
+
+ QStringListModel model(initial);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setFilterRegularExpression(pattern);
+
+ QComboBox comboBox;
+ comboBox.setModel(&proxy);
+ comboBox.addItem(newitem);
+
+ QCOMPARE(model.stringList(), expected);
+}
+
+void tst_QSortFilterProxyModel::removeRows_data()
+{
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<int>("position");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<bool>("success");
+ QTest::addColumn<QStringList>("expectedProxy");
+ QTest::addColumn<QStringList>("expectedSource");
+
+ QTest::newRow("remove one row in the middle [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove one row in the beginning [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 0 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove one row in the end [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 4 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four");
+
+ QTest::newRow("remove all [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 0 // position
+ << 5 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << QStringList(); // expectedSource
+
+ QTest::newRow("remove one row past the end [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 5 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove row -1 [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << -1 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove three rows in the middle [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 1 // position
+ << 3 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Five");
+
+ QTest::newRow("remove one row in the middle [ascending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QString() // no filter
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "2"
+ << "4");
+
+ QTest::newRow("remove two rows in the middle [ascending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QString() // no filter
+ << 2 // position
+ << 2 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "2");
+
+ QTest::newRow("remove two rows in the middle [descending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::DescendingOrder)
+ << QString() // no filter
+ << 2 // position
+ << 2 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "5"
+ << "4"
+ << "1")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "4");
+
+ QTest::newRow("remove one row in the middle [no sorting, filter=5|2|3]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << -1 // no sorting
+ << QString("5|2|3")
+ << 1 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "5"
+ << "3")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "4"
+ << "3");
+
+ QTest::newRow("remove all [ascending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QString() // no filter
+ << 0 // position
+ << 5 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << QStringList(); // expectedSource
+}
+
+void tst_QSortFilterProxyModel::removeRows()
+{
+ QFETCH(const QStringList, initial);
+ QFETCH(int, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(int, position);
+ QFETCH(int, count);
+ QFETCH(bool, success);
+ QFETCH(QStringList, expectedProxy);
+ QFETCH(QStringList, expectedSource);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ // prepare model
+ for (const auto &s : initial)
+ model.appendRow(new QStandardItem(s));
+
+ if (sortOrder != -1)
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+
+ if (!filter.isEmpty())
+ setupFilter(&proxy, filter);
+
+ // remove the rows
+ QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
+ QCOMPARE(model.rowCount(QModelIndex()), expectedSource.size());
+ QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxy.size());
+
+ // make sure the model is correct after remove
+ for (int row = 0; row < model.rowCount(QModelIndex()); ++row)
+ QCOMPARE(model.item(row)->text(), expectedSource.at(row));
+
+ // make sure the proxy is correct after remove
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedProxy.at(row));
+ }
+}
+
+class MyFilteredColumnProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ MyFilteredColumnProxyModel(QObject *parent = nullptr) :
+ QSortFilterProxyModel(parent)
+ { }
+
+protected:
+ bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const override
+ {
+ QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString();
+ return key.contains(filterRegularExpression());
+ }
+};
+
+void tst_QSortFilterProxyModel::removeColumns_data()
+{
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<int>("position");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<bool>("success");
+ QTest::addColumn<QStringList>("expectedProxy");
+ QTest::addColumn<QStringList>("expectedSource");
+
+ QTest::newRow("remove one column in the middle [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove one column in the end [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 4 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "3"
+ << "4")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4");
+
+ QTest::newRow("remove one column past the end [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 5 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove column -1 [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << -1 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove all columns [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 0 // position
+ << 5 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << QStringList(); // expectedSource
+
+ QTest::newRow("remove one column in the middle [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 1 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove one column in the end [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "3")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4");
+
+ QTest::newRow("remove one column past the end [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 3 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "3"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove all columns [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 0 // position
+ << 3 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << (QStringList() // expectedSource
+ << "2"
+ << "4");
+}
+
+void tst_QSortFilterProxyModel::removeColumns()
+{
+ QFETCH(QStringList, initial);
+ QFETCH(QString, filter);
+ QFETCH(int, position);
+ QFETCH(int, count);
+ QFETCH(bool, success);
+ QFETCH(QStringList, expectedProxy);
+ QFETCH(QStringList, expectedSource);
+
+ QStandardItemModel model;
+ MyFilteredColumnProxyModel proxy;
+ proxy.setSourceModel(&model);
+ if (!filter.isEmpty())
+ setupFilter(&proxy, filter);
+
+ // prepare model
+ model.setHorizontalHeaderLabels(initial);
+
+ // remove the columns
+ QCOMPARE(proxy.removeColumns(position, count, QModelIndex()), success);
+ QCOMPARE(model.columnCount(QModelIndex()), expectedSource.size());
+ QCOMPARE(proxy.columnCount(QModelIndex()), expectedProxy.size());
+
+ // make sure the model is correct after remove
+ for (int col = 0; col < model.columnCount(QModelIndex()); ++col)
+ QCOMPARE(model.horizontalHeaderItem(col)->text(), expectedSource.at(col));
+
+ // make sure the proxy is correct after remove
+ for (int col = 0; col < proxy.columnCount(QModelIndex()); ++col) {
+ QCOMPARE(proxy.headerData(col, Qt::Horizontal, Qt::DisplayRole).toString(),
+ expectedProxy.at(col));
+ }
+}
+
+void tst_QSortFilterProxyModel::filterColumns_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<bool>("data");
+
+ QTest::newRow("all") << "a"
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima")
+ << true;
+ QTest::newRow("some") << "lie"
+ << (QStringList()
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel")
+ << true;
+
+ QTest::newRow("nothing") << "zoo"
+ << (QStringList()
+ << "foxtrot"
+ << "uniform"
+ << "alpha"
+ << "golf")
+ << false;
+}
+
+void tst_QSortFilterProxyModel::filterColumns()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(bool, data);
+ // prepare model
+ m_model->setColumnCount(initial.size());
+ m_model->setRowCount(1);
+ QCoreApplication::processEvents(); // QAbstractProxyModel queues the headerDataChanged() signal
+ QCOMPARE(m_model->columnCount(QModelIndex()), initial.size());
+ QCOMPARE(m_model->rowCount(QModelIndex()), 1);
+ // set data
+ QCOMPARE(m_model->rowCount(QModelIndex()), 1);
+ for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
+ QModelIndex index = m_model->index(0, col, QModelIndex());
+ m_model->setData(index, initial.at(col), Qt::DisplayRole);
+ }
+ setupFilter(m_proxy, pattern);
+
+ m_proxy->setFilterKeyColumn(-1);
+ // make sure the model is unchanged
+ for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
+ QModelIndex index = m_model->index(0, col, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(col));
+ }
+ // make sure the proxy is filtered
+ QModelIndex index = m_proxy->index(0, 0, QModelIndex());
+ QCOMPARE(index.isValid(), data);
+}
+
+void tst_QSortFilterProxyModel::filter_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat") << "e"
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima"
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel"
+ << "uniform"
+ << "alpha"
+ << "echo"
+ << "golf"
+ << "quebec"
+ << "foxtrot"
+ << "india"
+ << "romeo"
+ << "november"
+ << "oskar"
+ << "zulu"
+ << "kilo"
+ << "whiskey"
+ << "mike"
+ << "papa"
+ << "sierra"
+ << "xray"
+ << "viktor")
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "charlie"
+ << "juliet"
+ << "hotel"
+ << "echo"
+ << "quebec"
+ << "romeo"
+ << "november"
+ << "whiskey"
+ << "mike"
+ << "sierra");
+}
+
+void tst_QSortFilterProxyModel::filter()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+
+ // prepare model
+ QVERIFY(m_model->insertRows(0, initial.size(), QModelIndex()));
+ QCOMPARE(m_model->rowCount(QModelIndex()), initial.size());
+ // set data
+ QCOMPARE(m_model->columnCount(QModelIndex()), 1);
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ m_model->setData(index, initial.at(row), Qt::DisplayRole);
+ }
+ setupFilter(m_proxy, pattern);
+ // make sure the proxy is unfiltered
+ QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
+ QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.size());
+ // make sure the model is unchanged
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+ // make sure the proxy is filtered
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::filterHierarchy_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat") << ".*oo"
+ << (QStringList()
+ << "foo" << "boo" << "baz" << "moo" << "laa" << "haa")
+ << (QStringList()
+ << "foo" << "boo" << "moo");
+
+ QTest::newRow("simple hierarchy") << "b.*z"
+ << (QStringList() << "baz" << "<" << "boz" << "<" << "moo" << ">" << ">")
+ << (QStringList() << "baz" << "<" << "boz" << ">");
+}
+
+void tst_QSortFilterProxyModel::filterHierarchy()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+ buildHierarchy(initial, m_model);
+ setupFilter(m_proxy, pattern);
+ checkHierarchy(initial, m_model);
+ checkHierarchy(expected, m_proxy);
+}
+
+void tst_QSortFilterProxyModel::buildHierarchy(const QStringList &l, QAbstractItemModel *m)
+{
+ int row = 0;
+ QStack<int> row_stack;
+ QModelIndex parent;
+ QStack<QModelIndex> parent_stack;
+ for (int i = 0; i < l.size(); ++i) {
+ QString token = l.at(i);
+ if (token == QLatin1String("<")) { // start table
+ parent_stack.push(parent);
+ row_stack.push(row);
+ parent = m->index(row - 1, 0, parent);
+ row = 0;
+ QVERIFY(m->insertColumns(0, 1, parent)); // add column
+ } else if (token == QLatin1String(">")) { // end table
+ parent = parent_stack.pop();
+ row = row_stack.pop();
+ } else { // append row
+ QVERIFY(m->insertRows(row, 1, parent));
+ QModelIndex index = m->index(row, 0, parent);
+ QVERIFY(index.isValid());
+ m->setData(index, token, Qt::DisplayRole);
+ ++row;
+ }
+ }
+}
+
+void tst_QSortFilterProxyModel::checkHierarchy(const QStringList &l, const QAbstractItemModel *m)
+{
+ int row = 0;
+ QStack<int> row_stack;
+ QModelIndex parent;
+ QStack<QModelIndex> parent_stack;
+ for (int i = 0; i < l.size(); ++i) {
+ QString token = l.at(i);
+ if (token == QLatin1String("<")) { // start table
+ parent_stack.push(parent);
+ row_stack.push(row);
+ parent = m->index(row - 1, 0, parent);
+ QVERIFY(parent.isValid());
+ row = 0;
+ } else if (token == QLatin1String(">")) { // end table
+ parent = parent_stack.pop();
+ row = row_stack.pop();
+ } else { // compare row
+ QModelIndex index = m->index(row, 0, parent);
+ QVERIFY(index.isValid());
+ QString str = m->data(index, Qt::DisplayRole).toString();
+ QCOMPARE(str, token);
+ ++row;
+ }
+ }
+}
+
+void tst_QSortFilterProxyModel::setupFilter(QSortFilterProxyModel *model, const QString& pattern)
+{
+ model->setFilterRegularExpression(pattern);
+}
+
+class TestModel: public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ int rowCount(const QModelIndex &) const override { return 10000; }
+ int columnCount(const QModelIndex &) const override { return 1; }
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (role != Qt::DisplayRole)
+ return QVariant();
+ return QString::number(index.row());
+ }
+};
+
+void tst_QSortFilterProxyModel::filterTable()
+{
+ TestModel model;
+ QSortFilterProxyModel filter;
+ filter.setSourceModel(&model);
+ setupFilter(&filter, QLatin1String("9"));
+
+ for (int i = 0; i < filter.rowCount(); ++i)
+ QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9')));
+}
+
+void tst_QSortFilterProxyModel::insertAfterSelect()
+{
+ QStandardItemModel model(10, 2);
+ for (int i = 0; i<10;i++)
+ model.setData(model.index(i, 0), QVariant(i));
+ QSortFilterProxyModel filter;
+ filter.setSourceModel(&model);
+ QTreeView view;
+ view.setModel(&filter);
+ view.show();
+ QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
+ QCOMPARE(firstIndex.model(), view.model());
+ QVERIFY(firstIndex.isValid());
+ int itemOffset = view.visualRect(firstIndex).width() / 2;
+ QPoint p(itemOffset, 1);
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
+ model.insertRows(5, 1, QModelIndex());
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
+}
+
+void tst_QSortFilterProxyModel::removeAfterSelect()
+{
+ QStandardItemModel model(10, 2);
+ for (int i = 0; i<10;i++)
+ model.setData(model.index(i, 0), QVariant(i));
+ QSortFilterProxyModel filter;
+ filter.setSourceModel(&model);
+ QTreeView view;
+ view.setModel(&filter);
+ view.show();
+ QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
+ QCOMPARE(firstIndex.model(), view.model());
+ QVERIFY(firstIndex.isValid());
+ int itemOffset = view.visualRect(firstIndex).width() / 2;
+ QPoint p(itemOffset, 1);
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
+ model.removeRows(5, 1, QModelIndex());
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
+}
+
+void tst_QSortFilterProxyModel::filterCurrent()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("AAA"));
+ model.setData(model.index(1, 0), QString("BBB"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ QTreeView view;
+
+ view.show();
+ view.setModel(&proxy);
+ QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
+ QVERIFY(spy.isValid());
+
+ view.setCurrentIndex(proxy.index(0, 0));
+ QCOMPARE(spy.size(), 1);
+ setupFilter(&proxy, QLatin1String("^B"));
+ QCOMPARE(spy.size(), 2);
+}
+
+void tst_QSortFilterProxyModel::filter_qtbug30662()
+{
+ QStringListModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ // make sure the filter does not match any entry
+ setupFilter(&proxy, QLatin1String("[0-9]+"));
+
+ QStringList slSource;
+ slSource << "z" << "x" << "a" << "b";
+
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+ model.setStringList(slSource);
+
+ // without fix for QTBUG-30662 this will make all entries visible - but unsorted
+ setupFilter(&proxy, QLatin1String("[a-z]+"));
+
+ QStringList slResult;
+ for (int i = 0; i < proxy.rowCount(); ++i)
+ slResult.append(proxy.index(i, 0).data().toString());
+
+ slSource.sort();
+ QCOMPARE(slResult, slSource);
+}
+
+void tst_QSortFilterProxyModel::changeSourceLayout()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("b"));
+ model.setData(model.index(1, 0), QString("a"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QList<QPersistentModelIndex> persistentSourceIndexes;
+ QList<QPersistentModelIndex> persistentProxyIndexes;
+ for (int row = 0; row < model.rowCount(); ++row) {
+ persistentSourceIndexes.append(model.index(row, 0));
+ persistentProxyIndexes.append(proxy.index(row, 0));
+ }
+
+ // change layout of source model
+ model.sort(0, Qt::AscendingOrder);
+
+ for (int row = 0; row < model.rowCount(); ++row) {
+ QCOMPARE(persistentProxyIndexes.at(row).row(),
+ persistentSourceIndexes.at(row).row());
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("b"));
+ model.setData(model.index(1, 0), QString("a"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ int beforeSortFilter = proxy.rowCount();
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ // Filter everything out
+ setupFilter(&proxy, QLatin1String("c"));
+
+ QCOMPARE(removeSpy.size(), 1);
+ QCOMPARE(0, proxy.rowCount());
+
+ // change layout of source model
+ model.sort(0, Qt::AscendingOrder);
+
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ // Remove filter; we expect an insert
+ setupFilter(&proxy, "");
+
+ QCOMPARE(insertSpy.size(), 1);
+ QCOMPARE(beforeSortFilter, proxy.rowCount());
+}
+
+void tst_QSortFilterProxyModel::removeSourceRows_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
+ QTest::addColumn<QStringList>("expectedProxyItems");
+
+ QTest::newRow("remove one, no sorting")
+ << (QStringList() << "a" << "b") // sourceItems
+ << 0 // start
+ << 1 // count
+ << -1 // sortOrder (no sorting)
+ << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+ QTest::newRow("remove one, ascending sort (same order)")
+ << (QStringList() << "a" << "b") // sourceItems
+ << 0 // start
+ << 1 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+ QTest::newRow("remove one, ascending sort (reverse order)")
+ << (QStringList() << "b" << "a") // sourceItems
+ << 0 // start
+ << 1 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(1, 1)) // expectedRemovedIntervals
+ << (QStringList() << "a") // expectedProxyItems
+ ;
+ QTest::newRow("remove two, multiple proxy intervals")
+ << (QStringList() << "c" << "d" << "a" << "b") // sourceItems
+ << 1 // start
+ << 2 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(3, 3) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b" << "c") // expectedProxyItems
+ ;
+ QTest::newRow("remove three, multiple proxy intervals")
+ << (QStringList() << "b" << "d" << "f" << "a" << "c" << "e") // sourceItems
+ << 3 // start
+ << 3 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(4, 4) << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b" << "d" << "f") // expectedProxyItems
+ ;
+ QTest::newRow("remove all, single proxy intervals")
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
+ << 0 // start
+ << 6 // count
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << (IntPairList() << IntPair(0, 5)) // expectedRemovedIntervals
+ << QStringList() // expectedProxyItems
+ ;
+}
+
+// Check that correct proxy model rows are removed when rows are removed
+// from the source model
+void tst_QSortFilterProxyModel::removeSourceRows()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, start);
+ QFETCH(int, count);
+ QFETCH(int, sortOrder);
+ QFETCH(IntPairList, expectedRemovedProxyIntervals);
+ QFETCH(QStringList, expectedProxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.size());
+
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex sindex = model.index(i, 0, QModelIndex());
+ model.setData(sindex, sourceItems.at(i), Qt::DisplayRole);
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
+ }
+
+ if (sortOrder != -1)
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
+ QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
+
+ QVERIFY(removeSpy.isValid());
+ QVERIFY(insertSpy.isValid());
+ QVERIFY(aboutToRemoveSpy.isValid());
+ QVERIFY(aboutToInsertSpy.isValid());
+
+ model.removeRows(start, count, QModelIndex());
+
+ QCOMPARE(aboutToRemoveSpy.size(), expectedRemovedProxyIntervals.size());
+ for (int i = 0; i < aboutToRemoveSpy.size(); ++i) {
+ const auto &args = aboutToRemoveSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+ QCOMPARE(removeSpy.size(), expectedRemovedProxyIntervals.size());
+ for (int i = 0; i < removeSpy.size(); ++i) {
+ const auto &args = removeSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+
+ QCOMPARE(insertSpy.size(), 0);
+ QCOMPARE(aboutToInsertSpy.size(), 0);
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.size());
+ for (int i = 0; i < expectedProxyItems.size(); ++i) {
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::insertSourceRows_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<QStringList>("newItems");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<QStringList>("proxyItems");
+
+ QTest::newRow("insert (1)")
+ << (QStringList() << "c" << "b") // sourceItems
+ << 1 // start
+ << (QStringList() << "a") // newItems
+ << Qt::AscendingOrder // sortOrder
+ << (QStringList() << "a" << "b" << "c") // proxyItems
+ ;
+
+ QTest::newRow("insert (2)")
+ << (QStringList() << "d" << "b" << "c") // sourceItems
+ << 3 // start
+ << (QStringList() << "a") // newItems
+ << Qt::DescendingOrder // sortOrder
+ << (QStringList() << "d" << "c" << "b" << "a") // proxyItems
+ ;
+}
+
+// Check that rows are inserted at correct position in proxy model when
+// rows are inserted into the source model
+void tst_QSortFilterProxyModel::insertSourceRows()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, start);
+ QFETCH(QStringList, newItems);
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(QStringList, proxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.size());
+
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, sortOrder);
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ model.insertRows(start, newItems.size(), QModelIndex());
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.size());
+ for (int i = 0; i < newItems.size(); ++i) {
+ QModelIndex index = model.index(start + i, 0, QModelIndex());
+ model.setData(index, newItems.at(i), Qt::DisplayRole);
+ }
+
+ for (int i = 0; i < proxyItems.size(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::changeFilter_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<QString>("initialFilter");
+ QTest::addColumn<IntPairList>("initialRemoveIntervals");
+ QTest::addColumn<QStringList>("initialProxyItems");
+ QTest::addColumn<QString>("finalFilter");
+ QTest::addColumn<IntPairList>("finalRemoveIntervals");
+ QTest::addColumn<IntPairList>("insertIntervals");
+ QTest::addColumn<QStringList>("finalProxyItems");
+
+ QTest::newRow("filter (1)")
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a|b|c" // initialFilter
+ << (IntPairList() << IntPair(3, 5)) // initialRemoveIntervals
+ << (QStringList() << "a" << "b" << "c") // initialProxyItems
+ << "b|d|f" // finalFilter
+ << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // finalRemoveIntervals
+ << (IntPairList() << IntPair(1, 2)) // insertIntervals
+ << (QStringList() << "b" << "d" << "f") // finalProxyItems
+ ;
+
+ QTest::newRow("filter (2)")
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a|c|e" // initialFilter
+ << (IntPairList() << IntPair(5, 5) << IntPair(3, 3) << IntPair(1, 1)) // initialRemoveIntervals
+ << (QStringList() << "a" << "c" << "e") // initialProxyItems
+ << "" // finalFilter
+ << IntPairList() // finalRemoveIntervals
+ << (IntPairList() << IntPair(3, 3) << IntPair(2, 2) << IntPair(1, 1)) // insertIntervals
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // finalProxyItems
+ ;
+
+ QTest::newRow("filter (3)")
+ << (QStringList() << "a" << "b" << "c") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a" // initialFilter
+ << (IntPairList() << IntPair(1, 2)) // initialRemoveIntervals
+ << (QStringList() << "a") // initialProxyItems
+ << "a" // finalFilter
+ << IntPairList() // finalRemoveIntervals
+ << IntPairList() // insertIntervals
+ << (QStringList() << "a") // finalProxyItems
+ ;
+}
+
+// Check that rows are added/removed when filter changes
+void tst_QSortFilterProxyModel::changeFilter()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(QString, initialFilter);
+ QFETCH(IntPairList, initialRemoveIntervals);
+ QFETCH(QStringList, initialProxyItems);
+ QFETCH(QString, finalFilter);
+ QFETCH(IntPairList, finalRemoveIntervals);
+ QFETCH(IntPairList, insertIntervals);
+ QFETCH(QStringList, finalProxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.size());
+
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, sortOrder);
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ QSignalSpy initialRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy initialInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(initialRemoveSpy.isValid());
+ QVERIFY(initialInsertSpy.isValid());
+
+ setupFilter(&proxy, initialFilter);
+
+ QCOMPARE(initialRemoveSpy.size(), initialRemoveIntervals.size());
+ QCOMPARE(initialInsertSpy.size(), 0);
+ for (int i = 0; i < initialRemoveSpy.size(); ++i) {
+ const auto &args = initialRemoveSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), initialRemoveIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), initialRemoveIntervals.at(i).second);
+ }
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), initialProxyItems.size());
+ for (int i = 0; i < initialProxyItems.size(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initialProxyItems.at(i));
+ }
+
+ QSignalSpy finalRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy finalInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(finalRemoveSpy.isValid());
+ QVERIFY(finalInsertSpy.isValid());
+
+ setupFilter(&proxy, finalFilter);
+
+ QCOMPARE(finalRemoveSpy.size(), finalRemoveIntervals.size());
+ for (int i = 0; i < finalRemoveSpy.size(); ++i) {
+ const auto &args = finalRemoveSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), finalRemoveIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), finalRemoveIntervals.at(i).second);
+ }
+
+ QCOMPARE(finalInsertSpy.size(), insertIntervals.size());
+ for (int i = 0; i < finalInsertSpy.size(); ++i) {
+ const auto &args = finalInsertSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
+ }
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), finalProxyItems.size());
+ for (int i = 0; i < finalProxyItems.size(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), finalProxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceData_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<QStringList>("expectedInitialProxyItems");
+ QTest::addColumn<bool>("dynamic");
+ QTest::addColumn<int>("row");
+ QTest::addColumn<QString>("newValue");
+ QTest::addColumn<IntPairList>("removeIntervals");
+ QTest::addColumn<IntPairList>("insertIntervals");
+ QTest::addColumn<int>("expectedDataChangedRow"); // -1 if no dataChanged signal expected
+ QTest::addColumn<bool>("expectedLayoutChanged");
+ QTest::addColumn<QStringList>("proxyItems");
+
+ QTest::newRow("move_to_end_ascending")
+ << (QStringList() << "c" << "b" << "a") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "" // filter
+ << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 2 // row
+ << "z" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
+ << true // layoutChanged
+ << (QStringList() << "b" << "c" << "z") // proxyItems
+ ;
+
+ QTest::newRow("move_to_end_descending")
+ << (QStringList() << "b" << "c" << "z") // sourceItems
+ << Qt::DescendingOrder // sortOrder
+ << "" // filter
+ << (QStringList() << "z" << "c" << "b") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "a" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
+ << true // layoutChanged
+ << (QStringList() << "z" << "b" << "a") // proxyItems
+ ;
+
+ QTest::newRow("no_op_change")
+ << (QStringList() << "a" << "b") // sourceItems
+ << Qt::DescendingOrder // sortOrder
+ << "" // filter
+ << (QStringList() << "b" << "a") // expectedInitialProxyItems
+ << true // dynamic
+ << 0 // row
+ << "a" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "b" << "a") // proxyItems
+ ;
+
+ QTest::newRow("no_effect_on_filtering")
+ << (QStringList() << "a" << "b") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "" // filter
+ << (QStringList() << "a" << "b") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "z" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 1 // expectedDataChangedRow
+ << false // layoutChanged
+ << (QStringList() << "a" << "z") // proxyItems
+ ;
+
+ QTest::newRow("filtered_out_value_stays_out")
+ << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a|c" // filter
+ << (QStringList() << "a" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "x" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "a" << "c") // proxyItems
+ ;
+
+ QTest::newRow("filtered_out_now_matches")
+ << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a|c|x" // filter
+ << (QStringList() << "a" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "x" // newValue
+ << IntPairList() // removeIntervals
+ << (IntPairList() << IntPair(2, 2)) // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "a" << "c" << "x") // proxyItems
+ ;
+
+ QTest::newRow("value_is_now_filtered_out")
+ << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a|c" // filter
+ << (QStringList() << "a" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 2 // row
+ << "x" // newValue
+ << (IntPairList() << IntPair(1, 1)) // removeIntervals
+ << IntPairList() // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "a") // proxyItems
+ ;
+
+ QTest::newRow("non_dynamic_filter_does_not_update_sort")
+ << (QStringList() << "c" << "b" << "a") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "" // filter
+ << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
+ << false // dynamic
+ << 2 // row
+ << "x" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 0 // expectedDataChangedRow
+ << false // layoutChanged
+ << (QStringList() << "x" << "b" << "c") // proxyItems
+ ;
+}
+
+void tst_QSortFilterProxyModel::changeSourceData()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(QStringList, expectedInitialProxyItems);
+ QFETCH(bool, dynamic);
+ QFETCH(int, row);
+ QFETCH(QString, newValue);
+ QFETCH(IntPairList, removeIntervals);
+ QFETCH(IntPairList, insertIntervals);
+ QFETCH(int, expectedDataChangedRow);
+ QFETCH(bool, expectedLayoutChanged);
+ QFETCH(QStringList, proxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setDynamicSortFilter(dynamic);
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.size());
+
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, sortOrder);
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ setupFilter(&proxy, filter);
+
+ QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.size());
+ for (int i = 0; i < expectedInitialProxyItems.size(); ++i) {
+ const QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedInitialProxyItems.at(i));
+ }
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ QSignalSpy dataChangedSpy(&proxy, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(removeSpy.isValid());
+ QVERIFY(insertSpy.isValid());
+ QVERIFY(dataChangedSpy.isValid());
+ QVERIFY(layoutChangedSpy.isValid());
+
+ {
+ QModelIndex index = model.index(row, 0, QModelIndex());
+ model.setData(index, newValue, Qt::DisplayRole);
+ }
+
+ QCOMPARE(removeSpy.size(), removeIntervals.size());
+ for (int i = 0; i < removeSpy.size(); ++i) {
+ const auto &args = removeSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), removeIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), removeIntervals.at(i).second);
+ }
+
+ QCOMPARE(insertSpy.size(), insertIntervals.size());
+ for (int i = 0; i < insertSpy.size(); ++i) {
+ const auto &args = insertSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
+ }
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.size());
+ for (int i = 0; i < proxyItems.size(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
+ }
+
+ if (expectedDataChangedRow == -1) {
+ QCOMPARE(dataChangedSpy.size(), 0);
+ } else {
+ QCOMPARE(dataChangedSpy.size(), 1);
+ const QModelIndex idx = dataChangedSpy.at(0).at(0).value<QModelIndex>();
+ QCOMPARE(idx.row(), expectedDataChangedRow);
+ QCOMPARE(idx.column(), 0);
+ }
+
+ QCOMPARE(layoutChangedSpy.size(), expectedLayoutChanged ? 1 : 0);
+}
+
+// Checks that the model is a table, and that each and every row is like this:
+// i-th row: ( rows.at(i), i )
+static void checkSortedTableModel(const QAbstractItemModel *model, const QStringList &rows)
+{
+ QCOMPARE(model->rowCount(), rows.size());
+ QCOMPARE(model->columnCount(), 2);
+
+ for (int row = 0; row < model->rowCount(); ++row) {
+ const QString column0 = model->index(row, 0).data().toString();
+ const int column1 = model->index(row, 1).data().toString().toInt();
+
+ QCOMPARE(column0, rows.at(row));
+ QCOMPARE(column1, row);
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548()
+{
+ // Check that emitting dataChanged from the source model
+ // for a change of a role which is not the sorting role
+ // doesn't alter the sorting. In this case, we sort on the DisplayRole,
+ // and play with other roles.
+
+ const QStringList rows({"a", "b", "b", "b", "c", "c", "x"});
+
+ // Build a table of pairs (string, #row) in each row
+ QStandardItemModel model(0, 2);
+
+ for (int rowNumber = 0; rowNumber < rows.size(); ++rowNumber) {
+ QStandardItem *column0 = new QStandardItem(rows.at(rowNumber));
+ column0->setCheckable(true);
+ column0->setCheckState(Qt::Unchecked);
+
+ QStandardItem *column1 = new QStandardItem(QString::number(rowNumber));
+ model.appendRow({column0, column1});
+ }
+
+ checkSortedTableModel(&model, rows);
+
+ // Build the proxy model
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+
+ // The proxy is now sorted by the first column, check that the sorting
+ // * is correct (the input is already sorted, so it must not have changed)
+ // * was stable (by looking at the second column)
+ checkSortedTableModel(&model, rows);
+
+ // Change the check status of an item. That must not break the stable sorting
+ // changes the middle "b"
+ model.item(2)->setCheckState(Qt::Checked);
+ checkSortedTableModel(&model, rows);
+
+ // changes the starting "a"
+ model.item(0)->setCheckState(Qt::Checked);
+ checkSortedTableModel(&model, rows);
+
+ // change the background color of the first "c"
+ model.item(4)->setBackground(Qt::red);
+ checkSortedTableModel(&model, rows);
+
+ // change the background color of the second "c"
+ model.item(5)->setBackground(Qt::red);
+ checkSortedTableModel(&model, rows);
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataForwardsRoles_qtbug35440()
+{
+ QStringList strings;
+ for (int i = 0; i < 100; ++i)
+ strings << QString::number(i);
+
+ QStringListModel model(strings);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.sort(0, Qt::AscendingOrder);
+
+ QSignalSpy spy(&proxy, &QAbstractItemModel::dataChanged);
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.size(), 0);
+
+ QModelIndex index;
+
+ // QStringListModel doesn't distinguish between edit and display roles,
+ // so changing one always changes the other, too.
+ QList<int> expectedChangedRoles;
+ expectedChangedRoles.append(Qt::DisplayRole);
+ expectedChangedRoles.append(Qt::EditRole);
+
+ index = model.index(0, 0);
+ QVERIFY(index.isValid());
+ model.setData(index, QStringLiteral("teststring"), Qt::DisplayRole);
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(spy.at(0).at(2).value<QList<int> >(), expectedChangedRoles);
+
+ index = model.index(1, 0);
+ QVERIFY(index.isValid());
+ model.setData(index, QStringLiteral("teststring2"), Qt::EditRole);
+ QCOMPARE(spy.size(), 2);
+ QCOMPARE(spy.at(1).at(2).value<QList<int> >(), expectedChangedRoles);
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataProxySendDataChanged_qtbug87781()
+{
+ QStandardItemModel baseModel;
+ QSortFilterProxyModel proxyModelBefore;
+ QSortFilterProxyModel proxyModelAfter;
+
+ QSignalSpy baseDataChangedSpy(&baseModel, &QStandardItemModel::dataChanged);
+ QSignalSpy beforeDataChangedSpy(&proxyModelBefore, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy afterDataChangedSpy(&proxyModelAfter, &QSortFilterProxyModel::dataChanged);
+
+ QVERIFY(baseDataChangedSpy.isValid());
+ QVERIFY(beforeDataChangedSpy.isValid());
+ QVERIFY(afterDataChangedSpy.isValid());
+
+ proxyModelBefore.setSourceModel(&baseModel);
+ baseModel.insertRows(0, 1);
+ baseModel.insertColumns(0, 1);
+ proxyModelAfter.setSourceModel(&baseModel);
+
+ QCOMPARE(baseDataChangedSpy.size(), 0);
+ QCOMPARE(beforeDataChangedSpy.size(), 0);
+ QCOMPARE(afterDataChangedSpy.size(), 0);
+
+ baseModel.setData(baseModel.index(0, 0), QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(baseDataChangedSpy.size(), 1);
+ QCOMPARE(beforeDataChangedSpy.size(), 1);
+ QCOMPARE(afterDataChangedSpy.size(), 1);
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataTreeModel()
+{
+ QStandardItemModel treeModel;
+ QSortFilterProxyModel treeProxyModelBefore;
+ QSortFilterProxyModel treeProxyModelAfter;
+
+ QSignalSpy treeBaseDataChangedSpy(&treeModel, &QStandardItemModel::dataChanged);
+ QSignalSpy treeBeforeDataChangedSpy(&treeProxyModelBefore, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy treeAfterDataChangedSpy(&treeProxyModelAfter, &QSortFilterProxyModel::dataChanged);
+
+ QVERIFY(treeBaseDataChangedSpy.isValid());
+ QVERIFY(treeBeforeDataChangedSpy.isValid());
+ QVERIFY(treeAfterDataChangedSpy.isValid());
+
+ treeProxyModelBefore.setSourceModel(&treeModel);
+ QStandardItem treeNode1("data1");
+ QStandardItem treeNode11("data11");
+ QStandardItem treeNode111("data111");
+
+ treeNode1.appendRow(&treeNode11);
+ treeNode11.appendRow(&treeNode111);
+ treeModel.appendRow(&treeNode1);
+ treeProxyModelAfter.setSourceModel(&treeModel);
+
+ QCOMPARE(treeBaseDataChangedSpy.size(), 0);
+ QCOMPARE(treeBeforeDataChangedSpy.size(), 0);
+ QCOMPARE(treeAfterDataChangedSpy.size(), 0);
+
+ treeNode111.setData(QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(treeBaseDataChangedSpy.size(), 1);
+ QCOMPARE(treeBeforeDataChangedSpy.size(), 1);
+ QCOMPARE(treeAfterDataChangedSpy.size(), 1);
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataProxyFilterSingleColumn()
+{
+ enum modelRow { Row0, Row1, RowCount };
+ enum modelColumn { Column0, Column1, Column2, Column3, Column4, Column5, ColumnCount };
+
+ class FilterProxyModel : public QSortFilterProxyModel
+ {
+ public:
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override {
+ Q_UNUSED(source_parent);
+ switch (source_column) {
+ case Column2:
+ case Column4:
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+
+ QStandardItemModel model;
+ FilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ model.insertRows(0, RowCount);
+ model.insertColumns(0, ColumnCount);
+
+ QSignalSpy modelDataChangedSpy(&model, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy proxyDataChangedSpy(&proxy, &FilterProxyModel::dataChanged);
+
+ QVERIFY(modelDataChangedSpy.isValid());
+ QVERIFY(proxyDataChangedSpy.isValid());
+
+ modelDataChangedSpy.clear();
+ proxyDataChangedSpy.clear();
+ model.setData(model.index(Row0, Column1), QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyDataChangedSpy.size(), 0);
+
+ modelDataChangedSpy.clear();
+ proxyDataChangedSpy.clear();
+ model.setData(model.index(Row0, Column2), QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyDataChangedSpy.size(), 1);
+
+ modelDataChangedSpy.clear();
+ proxyDataChangedSpy.clear();
+ model.setData(model.index(Row0, Column3), QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyDataChangedSpy.size(), 0);
+
+ modelDataChangedSpy.clear();
+ proxyDataChangedSpy.clear();
+ model.setData(model.index(Row0, Column4), QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyDataChangedSpy.size(), 1);
+
+ modelDataChangedSpy.clear();
+ proxyDataChangedSpy.clear();
+ model.setData(model.index(Row0, Column5), QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyDataChangedSpy.size(), 0);
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataProxyFilterMultipleColumns()
+{
+ class FilterProxyModel : public QSortFilterProxyModel
+ {
+ public:
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override {
+ Q_UNUSED(source_parent);
+ switch (source_column) {
+ case 2:
+ case 4:
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+
+ class MyTableModel : public QAbstractTableModel
+ {
+ public:
+ explicit MyTableModel() = default;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override {
+ Q_UNUSED(parent)
+ return 10;
+ }
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override {
+ Q_UNUSED(parent)
+ return 10;
+ }
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
+ Q_UNUSED(index)
+ Q_UNUSED(role)
+ return QString("testData");
+ }
+
+ void testDataChanged(const int topLeftRow, const int topLeftColumn, const int bottomRightRow, const int bottomRightColumn) {
+ QModelIndex topLeft = index(topLeftRow, topLeftColumn);
+ QModelIndex bottomRight = index(bottomRightRow, bottomRightColumn);
+ QVERIFY(topLeft.isValid());
+ QVERIFY(bottomRight.isValid());
+ emit dataChanged(topLeft, bottomRight);
+ }
+ };
+
+ MyTableModel baseModel;
+ FilterProxyModel proxyModel;
+
+ proxyModel.setSourceModel(&baseModel);
+
+ QSignalSpy baseModelDataChangedSpy(&baseModel, &MyTableModel::dataChanged);
+ QSignalSpy proxyModelDataChangedSpy(&proxyModel, &FilterProxyModel::dataChanged);
+
+ connect(&proxyModel, &FilterProxyModel::dataChanged, [=](const QModelIndex &topLeft, const QModelIndex &bottomRight) {
+ QVERIFY(topLeft.isValid());
+ QVERIFY(bottomRight.isValid());
+
+ //make sure every element is valid
+ int topLeftRow = topLeft.row();
+ int topLeftColumn = topLeft.column();
+ int bottomRightRow = bottomRight.row();
+ int bottomRightColumn = bottomRight.column();
+ for (int row = topLeftRow; row <= bottomRightRow; ++row) {
+ for (int column = topLeftColumn; column <= bottomRightColumn; ++column) {
+ QModelIndex index = topLeft.model()->index(row, column);
+ QVERIFY(index.isValid());
+ }
+ }
+ });
+
+ QVERIFY(baseModelDataChangedSpy.isValid());
+ QVERIFY(proxyModelDataChangedSpy.isValid());
+
+ baseModelDataChangedSpy.clear();
+ proxyModelDataChangedSpy.clear();
+ baseModel.testDataChanged(0, 0, 1, 1);
+ QCOMPARE(baseModelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyModelDataChangedSpy.size(), 0);
+
+ baseModelDataChangedSpy.clear();
+ proxyModelDataChangedSpy.clear();
+ baseModel.testDataChanged(0, 0, 1, 2);
+ QCOMPARE(baseModelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyModelDataChangedSpy.size(), 1);
+
+ baseModelDataChangedSpy.clear();
+ proxyModelDataChangedSpy.clear();
+ baseModel.testDataChanged(0, 3, 1, 3);
+ QCOMPARE(baseModelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyModelDataChangedSpy.size(), 0);
+
+ baseModelDataChangedSpy.clear();
+ proxyModelDataChangedSpy.clear();
+ baseModel.testDataChanged(0, 3, 1, 5);
+ QCOMPARE(baseModelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyModelDataChangedSpy.size(), 1);
+
+ baseModelDataChangedSpy.clear();
+ proxyModelDataChangedSpy.clear();
+ baseModel.testDataChanged(0, 0, 1, 5);
+ QCOMPARE(baseModelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyModelDataChangedSpy.size(), 1);
+}
+
+void tst_QSortFilterProxyModel::sortFilterRole()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+
+ const QList<QPair<QVariant, QVariant>>
+ sourceItems({QPair<QVariant, QVariant>("b", 3),
+ QPair<QVariant, QVariant>("c", 2),
+ QPair<QVariant, QVariant>("a", 1)});
+
+ const QList<int> orderedItems({2, 1});
+
+ model.insertRows(0, sourceItems.size());
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i).first, Qt::DisplayRole);
+ model.setData(index, sourceItems.at(i).second, Qt::UserRole);
+ }
+
+ setupFilter(&proxy, QLatin1String("2"));
+
+ QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
+
+ proxy.setFilterRole(Qt::UserRole);
+ QCOMPARE(proxy.rowCount(), 1);
+
+ proxy.setFilterRole(Qt::DisplayRole);
+ QCOMPARE(proxy.rowCount(), 0);
+
+ setupFilter(&proxy, QLatin1String("1|2|3"));
+
+ QCOMPARE(proxy.rowCount(), 0);
+
+ proxy.setFilterRole(Qt::UserRole);
+ QCOMPARE(proxy.rowCount(), 3);
+
+ proxy.sort(0, Qt::AscendingOrder);
+ QCOMPARE(proxy.rowCount(), 3);
+
+ proxy.setSortRole(Qt::UserRole);
+ proxy.setFilterRole(Qt::DisplayRole);
+ setupFilter(&proxy, QLatin1String("a|c"));
+
+ QCOMPARE(proxy.rowCount(), orderedItems.size());
+ for (int i = 0; i < proxy.rowCount(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole), sourceItems.at(orderedItems.at(i)).first);
+ }
+}
+
+void tst_QSortFilterProxyModel::selectionFilteredOut()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("AAA"));
+ model.setData(model.index(1, 0), QString("BBB"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ QTreeView view;
+
+ view.show();
+ view.setModel(&proxy);
+ QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
+ QVERIFY(spy.isValid());
+
+ view.setCurrentIndex(proxy.index(0, 0));
+ QCOMPARE(spy.size(), 1);
+
+ setupFilter(&proxy, QLatin1String("^B"));
+ QCOMPARE(spy.size(), 2);
+}
+
+void tst_QSortFilterProxyModel::match_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<int>("proxyStartRow");
+ QTest::addColumn<QString>("what");
+ QTest::addColumn<Qt::MatchFlag>("matchFlags");
+ QTest::addColumn<IntList>("expectedProxyItems");
+ QTest::newRow("1")
+ << (QStringList() << "a") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "" // filter
+ << 0 // proxyStartRow
+ << "a" // what
+ << Qt::MatchExactly // matchFlags
+ << (IntList() << 0); // expectedProxyItems
+ QTest::newRow("2")
+ << (QStringList() << "a" << "b") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "" // filter
+ << 0 // proxyStartRow
+ << "b" // what
+ << Qt::MatchExactly // matchFlags
+ << (IntList() << 1); // expectedProxyItems
+ QTest::newRow("3")
+ << (QStringList() << "a" << "b") // sourceItems
+ << Qt::DescendingOrder // sortOrder
+ << "" // filter
+ << 0 // proxyStartRow
+ << "a" // what
+ << Qt::MatchExactly // matchFlags
+ << (IntList() << 1); // expectedProxyItems
+ QTest::newRow("4")
+ << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "" // filter
+ << 1 // proxyStartRow
+ << "a" // what
+ << Qt::MatchExactly // matchFlags
+ << IntList(); // expectedProxyItems
+ QTest::newRow("5")
+ << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "a|b" // filter
+ << 0 // proxyStartRow
+ << "c" // what
+ << Qt::MatchExactly // matchFlags
+ << IntList(); // expectedProxyItems
+ QTest::newRow("6")
+ << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
+ << Qt::DescendingOrder // sortOrder
+ << "a|b" // filter
+ << 0 // proxyStartRow
+ << "b" // what
+ << Qt::MatchExactly // matchFlags
+ << (IntList() << 0); // expectedProxyItems
+}
+
+void tst_QSortFilterProxyModel::match()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(int, proxyStartRow);
+ QFETCH(QString, what);
+ QFETCH(Qt::MatchFlag, matchFlags);
+ QFETCH(IntList, expectedProxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.size());
+
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, sortOrder);
+ setupFilter(&proxy, filter);
+
+ QModelIndex startIndex = proxy.index(proxyStartRow, 0);
+ QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
+ expectedProxyItems.size(),
+ matchFlags);
+ QCOMPARE(indexes.size(), expectedProxyItems.size());
+ for (int i = 0; i < indexes.size(); ++i)
+ QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
+}
+
+QList<QStandardItem *> createStandardItemList(const QString &prefix, int n)
+{
+ QList<QStandardItem *> result;
+ for (int i = 0; i < n; ++i)
+ result.append(new QStandardItem(prefix + QString::number(i)));
+ return result;
+}
+
+// QTBUG-73864, recursive search in a tree model.
+
+void tst_QSortFilterProxyModel::matchTree()
+{
+ QStandardItemModel model(0, 2);
+ // Header00 Header01
+ // Header10 Header11
+ // Item00 Item01
+ // Item10 Item11
+ model.appendRow(createStandardItemList(QLatin1String("Header0"), 2));
+ auto headerRow = createStandardItemList(QLatin1String("Header1"), 2);
+ model.appendRow(headerRow);
+ headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item0"), 2));
+ headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item1"), 2));
+
+ auto item11 = model.match(model.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20,
+ Qt::MatchRecursive).value(0);
+ QVERIFY(item11.isValid());
+ QCOMPARE(item11.data().toString(), QLatin1String("Item11"));
+
+ // Repeat in proxy model
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ auto proxyItem11 = proxy.match(proxy.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20,
+ Qt::MatchRecursive).value(0);
+ QVERIFY(proxyItem11.isValid());
+ QCOMPARE(proxyItem11.data().toString(), QLatin1String("Item11"));
+
+ QCOMPARE(proxy.mapToSource(proxyItem11).internalId(), item11.internalId());
+}
+
+void tst_QSortFilterProxyModel::insertIntoChildrenlessItem()
+{
+ QStandardItemModel model;
+ QStandardItem *itemA = new QStandardItem("a");
+ model.appendRow(itemA);
+ QStandardItem *itemB = new QStandardItem("b");
+ model.appendRow(itemB);
+ QStandardItem *itemC = new QStandardItem("c");
+ model.appendRow(itemC);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QSignalSpy colsInsertedSpy(&proxy, &QSortFilterProxyModel::columnsInserted);
+ QSignalSpy rowsInsertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(colsInsertedSpy.isValid());
+ QVERIFY(rowsInsertedSpy.isValid());
+
+ (void)proxy.rowCount(QModelIndex()); // force mapping of "a", "b", "c"
+ QCOMPARE(colsInsertedSpy.size(), 0);
+ QCOMPARE(rowsInsertedSpy.size(), 0);
+
+ // now add a child to itemB ==> should get insert notification from the proxy
+ itemB->appendRow(new QStandardItem("a.0"));
+ QCOMPARE(colsInsertedSpy.size(), 1);
+ QCOMPARE(rowsInsertedSpy.size(), 1);
+
+ QVariantList args = colsInsertedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
+ QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
+ QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
+
+ args = rowsInsertedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
+ QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
+ QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
+}
+
+void tst_QSortFilterProxyModel::invalidateMappedChildren()
+{
+ QStandardItemModel model;
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QStandardItem *itemA = new QStandardItem("a");
+ model.appendRow(itemA);
+ QStandardItem *itemB = new QStandardItem("b");
+ itemA->appendRow(itemB);
+
+ QStandardItem *itemC = new QStandardItem("c");
+ itemB->appendRow(itemC);
+ itemC->appendRow(new QStandardItem("d"));
+
+ // force mappings
+ (void)proxy.hasChildren(QModelIndex());
+ (void)proxy.hasChildren(proxy.mapFromSource(itemA->index()));
+ (void)proxy.hasChildren(proxy.mapFromSource(itemB->index()));
+ (void)proxy.hasChildren(proxy.mapFromSource(itemC->index()));
+
+ itemB->removeRow(0); // should invalidate mapping of itemC
+ itemC = new QStandardItem("c");
+ itemA->appendRow(itemC);
+ itemC->appendRow(new QStandardItem("d"));
+
+ itemA->removeRow(1); // should invalidate mapping of itemC
+ itemC = new QStandardItem("c");
+ itemB->appendRow(itemC);
+ itemC->appendRow(new QStandardItem("d"));
+
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemA->index())), 1);
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemB->index())), 1);
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemC->index())), 1);
+}
+
+class EvenOddFilterModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ bool filterAcceptsRow(int srcRow, const QModelIndex &srcParent) const override
+ {
+ if (srcParent.isValid())
+ return (srcParent.row() % 2) ^ !(srcRow % 2);
+ return (srcRow % 2);
+ }
+};
+
+void tst_QSortFilterProxyModel::insertRowIntoFilteredParent()
+{
+ QStandardItemModel model;
+ EvenOddFilterModel proxy;
+ proxy.setSourceModel(&model);
+
+ QSignalSpy spy(&proxy, &EvenOddFilterModel::rowsInserted);
+ QVERIFY(spy.isValid());
+
+ QStandardItem *itemA = new QStandardItem();
+ model.appendRow(itemA); // A will be filtered
+ QStandardItem *itemB = new QStandardItem();
+ itemA->appendRow(itemB);
+
+ QCOMPARE(spy.size(), 0);
+
+ itemA->removeRow(0);
+
+ QCOMPARE(spy.size(), 0);
+}
+
+void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ setupFilter(&proxy, QLatin1String("A|B"));
+
+ QStandardItem *itemA = new QStandardItem("A");
+ model.appendRow(itemA); // not filtered
+ QStandardItem *itemB = new QStandardItem("B");
+ itemA->appendRow(itemB); // not filtered
+ QStandardItem *itemC = new QStandardItem("C");
+ itemA->appendRow(itemC); // filtered
+
+ QSignalSpy removedSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(removedSpy.isValid());
+ QVERIFY(insertedSpy.isValid());
+
+ setupFilter(&proxy, QLatin1String("C")); // A and B will be filtered out, C filtered in
+
+ // we should now have been notified that the subtree represented by itemA has been removed
+ QCOMPARE(removedSpy.size(), 1);
+ // we should NOT get any inserts; itemC should be filtered because its parent (itemA) is
+ QCOMPARE(insertedSpy.size(), 0);
+}
+
+void tst_QSortFilterProxyModel::sourceInsertRows()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ model.insertColumns(0, 1, QModelIndex());
+ model.insertRows(0, 2, QModelIndex());
+
+ {
+ QModelIndex parent = model.index(0, 0, QModelIndex());
+ model.insertColumns(0, 1, parent);
+ model.insertRows(0, 1, parent);
+ }
+
+ {
+ QModelIndex parent = model.index(1, 0, QModelIndex());
+ model.insertColumns(0, 1, parent);
+ model.insertRows(0, 1, parent);
+ }
+
+ model.insertRows(0, 1, QModelIndex());
+ model.insertRows(0, 1, QModelIndex());
+
+ QVERIFY(true); // if you got here without asserting, it's all good
+}
+
+void tst_QSortFilterProxyModel::sourceModelDeletion()
+{
+ QSortFilterProxyModel proxyModel;
+ {
+ QStandardItemModel model;
+ proxyModel.setSourceModel(&model);
+ QCOMPARE(proxyModel.sourceModel(), &model);
+ }
+ QCOMPARE(proxyModel.sourceModel(), nullptr);
+}
+
+void tst_QSortFilterProxyModel::sortColumnTracking1()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ model.insertColumns(0, 10);
+ model.insertRows(0, 10);
+
+ proxyModel.sort(1);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.insertColumn(8);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.removeColumn(8);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.insertColumn(2);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.removeColumn(2);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.insertColumn(1);
+ QCOMPARE(proxyModel.sortColumn(), 2);
+
+ model.removeColumn(1);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.removeColumn(1);
+ QCOMPARE(proxyModel.sortColumn(), -1);
+}
+
+void tst_QSortFilterProxyModel::sortColumnTracking2()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.setSourceModel(&model);
+
+ proxyModel.sort(0);
+ QCOMPARE(proxyModel.sortColumn(), 0);
+
+ QList<QStandardItem *> items; // Stable sorting: Items with invalid data should move to the end
+ items << new QStandardItem << new QStandardItem("foo") << new QStandardItem("bar")
+ << new QStandardItem("some") << new QStandardItem("others") << new QStandardItem("item")
+ << new QStandardItem("aa") << new QStandardItem("zz") << new QStandardItem;
+
+ model.insertColumn(0,items);
+ QCOMPARE(proxyModel.sortColumn(), 0);
+ QCOMPARE(proxyModel.data(proxyModel.index(0,0)).toString(),QString::fromLatin1("aa"));
+ const int zzIndex = items.size() - 3; // 2 invalid at end.
+ QCOMPARE(proxyModel.data(proxyModel.index(zzIndex,0)).toString(),QString::fromLatin1("zz"));
+}
+
+void tst_QSortFilterProxyModel::sortStable()
+{
+ QStandardItemModel model(5, 2);
+ for (int r = 0; r < 5; r++) {
+ const QString prefix = QLatin1String("Row:") + QString::number(r) + QLatin1String(", Column:");
+ for (int c = 0; c < 2; c++) {
+ QStandardItem* item = new QStandardItem(prefix + QString::number(c));
+ for (int i = 0; i < 3; i++) {
+ QStandardItem* child = new QStandardItem(QLatin1String("Item ") + QString::number(i));
+ item->appendRow( child );
+ }
+ model.setItem(r, c, item);
+ }
+ }
+ model.setHorizontalHeaderItem( 0, new QStandardItem( "Name" ));
+ model.setHorizontalHeaderItem( 1, new QStandardItem( "Value" ));
+
+ QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(&model);
+ filterModel->setSourceModel(&model);
+
+ QTreeView view;
+ view.setModel(filterModel);
+ QModelIndex firstRoot = filterModel->index(0,0);
+ view.expand(firstRoot);
+ view.setSortingEnabled(true);
+
+ view.model()->sort(1, Qt::DescendingOrder);
+ QVariant lastItemData =filterModel->index(2,0, firstRoot).data();
+ view.model()->sort(1, Qt::DescendingOrder);
+ QCOMPARE(lastItemData, filterModel->index(2,0, firstRoot).data());
+}
+
+void tst_QSortFilterProxyModel::hiddenColumns()
+{
+ class MyStandardItemModel : public QStandardItemModel
+ {
+ public:
+ MyStandardItemModel() : QStandardItemModel(0,5) {}
+ void reset()
+ { beginResetModel(); endResetModel(); }
+ friend class tst_QSortFilterProxyModel;
+ } model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QTableView view;
+ view.setModel(&proxy);
+
+ view.hideColumn(0);
+
+ QVERIFY(view.isColumnHidden(0));
+ model.blockSignals(true);
+ model.setRowCount(1);
+ model.blockSignals(false);
+ model.reset();
+
+ // In the initial bug report that spawned this test, this would be false
+ // because resetting model would also reset the hidden columns.
+ QVERIFY(view.isColumnHidden(0));
+}
+
+void tst_QSortFilterProxyModel::insertRowsSort()
+{
+ QStandardItemModel model(2,2);
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ proxyModel.sort(0);
+ QCOMPARE(proxyModel.sortColumn(), 0);
+
+ model.insertColumns(0, 3, model.index(0,0));
+ QCOMPARE(proxyModel.sortColumn(), 0);
+
+ model.removeColumns(0, 3, model.index(0,0));
+ QCOMPARE(proxyModel.sortColumn(), 0);
+}
+
+void tst_QSortFilterProxyModel::staticSorting()
+{
+ QStandardItemModel model(0, 1);
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(false);
+ QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
+
+ // prepare model
+ QStandardItem *root = model.invisibleRootItem ();
+ QList<QStandardItem *> items;
+ for (int i = 0; i < initial.size(); ++i) {
+ items.append(new QStandardItem(initial.at(i)));
+ }
+ root->insertRows(0, items);
+ QCOMPARE(model.rowCount(QModelIndex()), initial.size());
+ QCOMPARE(model.columnCount(QModelIndex()), 1);
+
+ // make sure the proxy is unsorted
+ QCOMPARE(proxy.columnCount(QModelIndex()), 1);
+ QCOMPARE(proxy.rowCount(QModelIndex()), initial.size());
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ // sort
+ proxy.sort(0);
+
+ QStringList expected = initial;
+ expected.sort();
+ // make sure the proxy is sorted
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ //update one item.
+ items.first()->setData("girafe", Qt::DisplayRole);
+
+ // make sure the proxy is updated but not sorted
+ expected.replaceInStrings("bateau", "girafe");
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ // sort again
+ proxy.sort(0);
+ expected.sort();
+
+ // make sure the proxy is sorted
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::dynamicSorting()
+{
+ QStringListModel model1;
+ const QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
+ model1.setStringList(initial);
+ QSortFilterProxyModel proxy1;
+ proxy1.setDynamicSortFilter(false);
+ proxy1.sort(0);
+ proxy1.setSourceModel(&model1);
+
+ QCOMPARE(proxy1.columnCount(QModelIndex()), 1);
+ //the model should not be sorted because sorting has not been set to dynamic yet.
+ QCOMPARE(proxy1.rowCount(QModelIndex()), initial.size());
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ proxy1.setDynamicSortFilter(true);
+
+ //now the model should be sorted.
+ QStringList expected = initial;
+ expected.sort();
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ QStringList initial2 = initial;
+ initial2.replaceInStrings("bateau", "girafe");
+ model1.setStringList(initial2); //this will cause a reset
+
+ QStringList expected2 = initial2;
+ expected2.sort();
+
+ //now the model should still be sorted.
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected2.at(row));
+ }
+
+ QStringListModel model2(initial);
+ proxy1.setSourceModel(&model2);
+
+ //the model should again be sorted
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ //set up the sorting before seting the model up
+ QSortFilterProxyModel proxy2;
+ proxy2.sort(0);
+ proxy2.setSourceModel(&model2);
+ for (int row = 0; row < proxy2.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy2.index(row, 0, QModelIndex());
+ QCOMPARE(proxy2.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+class QtTestModel: public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ QtTestModel(int _rows, int _cols, QObject *parent = nullptr)
+ : QAbstractItemModel(parent)
+ , rows(_rows)
+ , cols(_cols)
+ , wrongIndex(false)
+ {
+ }
+
+ bool canFetchMore(const QModelIndex &idx) const override
+ {
+ return !fetched.contains(idx);
+ }
+
+ void fetchMore(const QModelIndex &idx) override
+ {
+ if (fetched.contains(idx))
+ return;
+ beginInsertRows(idx, 0, rows-1);
+ fetched.insert(idx);
+ endInsertRows();
+ }
+
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const override
+ {
+ Q_UNUSED(parent);
+ return true;
+ }
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override
+ {
+ return fetched.contains(parent) ? rows : 0;
+ }
+
+ int columnCount(const QModelIndex& parent = QModelIndex()) const override
+ {
+ Q_UNUSED(parent);
+ return cols;
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
+ {
+ if (row < 0 || column < 0 || column >= cols || row >= rows) {
+ return QModelIndex();
+ }
+ QModelIndex i = createIndex(row, column, int(parent.internalId() + 1));
+ parentHash[i] = parent;
+ return i;
+ }
+
+ QModelIndex parent(const QModelIndex &index) const override
+ {
+ if (!parentHash.contains(index))
+ return QModelIndex();
+ return parentHash[index];
+ }
+
+ QVariant data(const QModelIndex &idx, int role) const override
+ {
+ if (!idx.isValid())
+ return QVariant();
+
+ if (role == Qt::DisplayRole) {
+ if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
+ wrongIndex = true;
+ qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(),
+ idx.internalPointer());
+ }
+ return QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',')
+ + QString::number(idx.column()) + QLatin1Char(']');
+ }
+ return QVariant();
+ }
+
+ QSet<QModelIndex> fetched;
+ int rows, cols;
+ mutable bool wrongIndex;
+ mutable QMap<QModelIndex,QModelIndex> parentHash;
+};
+
+void tst_QSortFilterProxyModel::fetchMore()
+{
+ QtTestModel model(10,10);
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.canFetchMore(QModelIndex()));
+ QVERIFY(proxy.hasChildren());
+ while (proxy.canFetchMore(QModelIndex()))
+ proxy.fetchMore(QModelIndex());
+ QCOMPARE(proxy.rowCount(), 10);
+ QCOMPARE(proxy.columnCount(), 10);
+
+ QModelIndex idx = proxy.index(1,1);
+ QVERIFY(idx.isValid());
+ QVERIFY(proxy.canFetchMore(idx));
+ QVERIFY(proxy.hasChildren(idx));
+ while (proxy.canFetchMore(idx))
+ proxy.fetchMore(idx);
+ QCOMPARE(proxy.rowCount(idx), 10);
+ QCOMPARE(proxy.columnCount(idx), 10);
+}
+
+void tst_QSortFilterProxyModel::hiddenChildren()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(true);
+
+ QStandardItem *itemA = new QStandardItem("A VISIBLE");
+ model.appendRow(itemA);
+ QStandardItem *itemB = new QStandardItem("B VISIBLE");
+ itemA->appendRow(itemB);
+ QStandardItem *itemC = new QStandardItem("C");
+ itemA->appendRow(itemC);
+ setupFilter(&proxy, QLatin1String("VISIBLE"));
+
+ QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
+ QPersistentModelIndex indexA = proxy.index(0,0);
+ QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
+
+ QCOMPARE(proxy.rowCount(indexA) , 1);
+ QPersistentModelIndex indexB = proxy.index(0, 0, indexA);
+ QCOMPARE(proxy.data(indexB).toString(), QString::fromLatin1("B VISIBLE"));
+
+ itemA->setText("A");
+ QCOMPARE(proxy.rowCount(QModelIndex()), 0);
+ QVERIFY(!indexA.isValid());
+ QVERIFY(!indexB.isValid());
+
+ itemB->setText("B");
+ itemA->setText("A VISIBLE");
+ itemC->setText("C VISIBLE");
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), 1);
+ indexA = proxy.index(0,0);
+ QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
+
+ QCOMPARE(proxy.rowCount(indexA) , 1);
+ QModelIndex indexC = proxy.index(0, 0, indexA);
+ QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
+
+ setupFilter(&proxy, QLatin1String("C"));
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), 0);
+ itemC->setText("invisible");
+ itemA->setText("AC");
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), 1);
+ indexA = proxy.index(0,0);
+ QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("AC"));
+ QCOMPARE(proxy.rowCount(indexA) , 0);
+}
+
+void tst_QSortFilterProxyModel::mapFromToSource()
+{
+ QtTestModel source(10,10);
+ source.fetchMore(QModelIndex());
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&source);
+ QCOMPARE(proxy.mapFromSource(source.index(5, 4)), proxy.index(5, 4));
+ QCOMPARE(proxy.mapToSource(proxy.index(3, 2)), source.index(3, 2));
+ QCOMPARE(proxy.mapFromSource(QModelIndex()), QModelIndex());
+ QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex());
+
+ // Will assert in debug, so only test in release
+#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
+ QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource");
+ QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex());
+ QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource");
+ QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex());
+#endif
+}
+
+static QStandardItem *addEntry(QStandardItem* pParent, const QString &description)
+{
+ QStandardItem* pItem = new QStandardItem(description);
+ pParent->appendRow(pItem);
+ return pItem;
+}
+
+void tst_QSortFilterProxyModel::removeRowsRecursive()
+{
+ QStandardItemModel pModel;
+ QStandardItem *pItem1 = new QStandardItem("root");
+ pModel.appendRow(pItem1);
+ QList<QStandardItem *> items;
+
+ QStandardItem *pItem11 = addEntry(pItem1,"Sub-heading");
+ items << pItem11;
+ QStandardItem *pItem111 = addEntry(pItem11,"A");
+ items << pItem111;
+ items << addEntry(pItem111,"A1");
+ items << addEntry(pItem111,"A2");
+ QStandardItem *pItem112 = addEntry(pItem11,"B");
+ items << pItem112;
+ items << addEntry(pItem112,"B1");
+ items << addEntry(pItem112,"B2");
+ QStandardItem *pItem1123 = addEntry(pItem112,"B3");
+ items << pItem1123;
+ items << addEntry(pItem1123,"B3-");
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&pModel);
+
+ QList<QPersistentModelIndex> sourceIndexes;
+ QList<QPersistentModelIndex> proxyIndexes;
+ for (const auto item : std::as_const(items)) {
+ QModelIndex idx = item->index();
+ sourceIndexes << idx;
+ proxyIndexes << proxy.mapFromSource(idx);
+ }
+
+ for (const auto &pidx : std::as_const(sourceIndexes))
+ QVERIFY(pidx.isValid());
+ for (const auto &pidx : std::as_const(proxyIndexes))
+ QVERIFY(pidx.isValid());
+
+ QList<QStandardItem*> itemRow = pItem1->takeRow(0);
+
+ QCOMPARE(itemRow.size(), 1);
+ QCOMPARE(itemRow.first(), pItem11);
+
+ for (const auto &pidx : std::as_const(sourceIndexes))
+ QVERIFY(!pidx.isValid());
+ for (const auto &pidx : std::as_const(proxyIndexes))
+ QVERIFY(!pidx.isValid());
+
+ delete pItem11;
+}
+
+void tst_QSortFilterProxyModel::doubleProxySelectionSetSourceModel()
+{
+ QStandardItemModel model1;
+ QStandardItem *parentItem = model1.invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *item = new QStandardItem(QLatin1String("model1 item ") + QString::number(i));
+ parentItem->appendRow(item);
+ parentItem = item;
+ }
+
+ QStandardItemModel model2;
+ QStandardItem *parentItem2 = model2.invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *item = new QStandardItem(QLatin1String("model2 item ") + QString::number(i));
+ parentItem2->appendRow(item);
+ parentItem2 = item;
+ }
+
+ QSortFilterProxyModel toggleProxy;
+ toggleProxy.setSourceModel(&model1);
+
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&toggleProxy);
+
+ QModelIndex mi = proxyModel.index(0, 0, proxyModel.index(0, 0, proxyModel.index(0, 0)));
+ QItemSelectionModel ism(&proxyModel);
+ ism.select(mi, QItemSelectionModel::Select);
+ QModelIndexList mil = ism.selectedIndexes();
+ QCOMPARE(mil.size(), 1);
+ QCOMPARE(mil.first(), mi);
+
+ toggleProxy.setSourceModel(&model2);
+ // No crash, it's good news!
+ QVERIFY(ism.selection().isEmpty());
+}
+
+void tst_QSortFilterProxyModel::appearsAndSort()
+{
+ class PModel : public QSortFilterProxyModel
+ {
+ protected:
+ bool filterAcceptsRow(int, const QModelIndex &) const override
+ {
+ return mVisible;
+ }
+
+ public:
+ void updateXX()
+ {
+ mVisible = true;
+ invalidate();
+ }
+ private:
+ bool mVisible = false;
+ } proxyModel;
+
+ QStringListModel sourceModel;
+ sourceModel.setStringList({"b", "a", "c"});
+
+ proxyModel.setSourceModel(&sourceModel);
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.sort(0, Qt::AscendingOrder);
+
+ QApplication::processEvents();
+ QCOMPARE(sourceModel.rowCount(), 3);
+ QCOMPARE(proxyModel.rowCount(), 0); //all rows are hidden at first;
+
+ QSignalSpy spyAbout1(&proxyModel, &PModel::layoutAboutToBeChanged);
+ QSignalSpy spyChanged1(&proxyModel, &PModel::layoutChanged);
+
+ QVERIFY(spyAbout1.isValid());
+ QVERIFY(spyChanged1.isValid());
+
+ //introducing secondProxyModel to test the layoutChange when many items appears at once
+ QSortFilterProxyModel secondProxyModel;
+ secondProxyModel.setSourceModel(&proxyModel);
+ secondProxyModel.setDynamicSortFilter(true);
+ secondProxyModel.sort(0, Qt::DescendingOrder);
+ QCOMPARE(secondProxyModel.rowCount(), 0); //all rows are hidden at first;
+ QSignalSpy spyAbout2(&secondProxyModel, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy spyChanged2(&secondProxyModel, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(spyAbout2.isValid());
+ QVERIFY(spyChanged2.isValid());
+
+ proxyModel.updateXX();
+ QApplication::processEvents();
+ //now rows should be visible, and sorted
+ QCOMPARE(proxyModel.rowCount(), 3);
+ QCOMPARE(proxyModel.data(proxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
+ QCOMPARE(proxyModel.data(proxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
+ QCOMPARE(proxyModel.data(proxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
+
+ //now rows should be visible, and sorted
+ QCOMPARE(secondProxyModel.rowCount(), 3);
+ QCOMPARE(secondProxyModel.data(secondProxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
+ QCOMPARE(secondProxyModel.data(secondProxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
+ QCOMPARE(secondProxyModel.data(secondProxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
+
+ QCOMPARE(spyAbout1.size(), 1);
+ QCOMPARE(spyChanged1.size(), 1);
+ QCOMPARE(spyAbout2.size(), 1);
+ QCOMPARE(spyChanged2.size(), 1);
+}
+
+void tst_QSortFilterProxyModel::unnecessaryDynamicSorting()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(false);
+ proxy.setSourceModel(&model);
+ proxy.sort(Qt::AscendingOrder);
+
+ //append two rows
+ int maxrows = proxy.rowCount(QModelIndex());
+ model.insertRows(maxrows, 2);
+ model.setData(model.index(maxrows, 0), QString("alpha"));
+ model.setData(model.index(maxrows + 1, 0), QString("fondue"));
+
+ //append new items to the initial string list and compare with model
+ QStringList expected = initial;
+ expected << QString("alpha") << QString("fondue");
+
+ //if bug 7716 is present, new rows were prepended, when they should have been appended
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+class SelectionProxyModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+public:
+ QModelIndex mapFromSource(QModelIndex const&) const override
+ { return QModelIndex(); }
+
+ QModelIndex mapToSource(QModelIndex const&) const override
+ { return QModelIndex(); }
+
+ QModelIndex index(int, int, const QModelIndex&) const override
+ { return QModelIndex(); }
+
+ QModelIndex parent(const QModelIndex&) const override
+ { return QModelIndex(); }
+
+ int rowCount(const QModelIndex&) const override
+ { return 0; }
+
+ int columnCount(const QModelIndex&) const override
+ { return 0; }
+
+ void setSourceModel(QAbstractItemModel *sourceModel) override
+ {
+ beginResetModel();
+ disconnect(sourceModel, &QAbstractItemModel::modelAboutToBeReset,
+ this, &SelectionProxyModel::sourceModelAboutToBeReset);
+ QAbstractProxyModel::setSourceModel( sourceModel );
+ connect(sourceModel, &QAbstractItemModel::modelAboutToBeReset,
+ this, &SelectionProxyModel::sourceModelAboutToBeReset);
+ endResetModel();
+ }
+
+ void setSelectionModel(QItemSelectionModel *_selectionModel)
+ {
+ selectionModel = _selectionModel;
+ }
+
+private slots:
+ void sourceModelAboutToBeReset()
+ {
+ QVERIFY( selectionModel->selectedIndexes().size() == 1 );
+ beginResetModel();
+ }
+
+ void sourceModelReset()
+ {
+ endResetModel();
+ }
+
+private:
+ QItemSelectionModel *selectionModel = nullptr;
+};
+
+void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel( &model );
+
+ SelectionProxyModel proxy1;
+ QSortFilterProxyModel proxy2;
+
+ // Note that the order here matters. The order of the sourceAboutToBeReset
+ // exposes the bug in QSortFilterProxyModel.
+ proxy2.setSourceModel( &proxy );
+ proxy1.setSourceModel( &proxy );
+
+ QItemSelectionModel selectionModel(&proxy2);
+ proxy1.setSelectionModel( &selectionModel );
+
+ selectionModel.select( proxy2.index( 0, 0 ), QItemSelectionModel::Select );
+
+ // trick the proxy into emitting begin/end reset signals.
+ proxy.setSourceModel(nullptr);
+}
+
+static bool isValid(const QItemSelection &selection)
+{
+ return std::all_of(selection.begin(), selection.end(),
+ [](const QItemSelectionRange &range) { return range.isValid(); });
+}
+
+void tst_QSortFilterProxyModel::mapSelectionFromSource()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ setupFilter(&proxy, QLatin1String("d.*"));
+
+ proxy.setSourceModel(&model);
+
+ // Only "delta" remains.
+ QCOMPARE(proxy.rowCount(), 1);
+
+ QItemSelection selection;
+ QModelIndex charlie = model.index(1, 0);
+ selection.append(QItemSelectionRange(charlie, charlie));
+ QModelIndex delta = model.index(2, 0);
+ selection.append(QItemSelectionRange(delta, delta));
+ QModelIndex echo = model.index(3, 0);
+ selection.append(QItemSelectionRange(echo, echo));
+
+ QVERIFY(isValid(selection));
+
+ QItemSelection proxiedSelection = proxy.mapSelectionFromSource(selection);
+
+ // Only "delta" is in the mapped result.
+ QCOMPARE(proxiedSelection.size(), 1);
+ QVERIFY(isValid(proxiedSelection));
+}
+
+class Model10287 : public QStandardItemModel
+{
+ Q_OBJECT
+
+public:
+ Model10287(QObject *parent = nullptr)
+ : QStandardItemModel(0, 1, parent)
+ {
+ parentItem = new QStandardItem("parent");
+ parentItem->setData(false, Qt::UserRole);
+ appendRow(parentItem);
+
+ childItem = new QStandardItem("child");
+ childItem->setData(true, Qt::UserRole);
+ parentItem->appendRow(childItem);
+
+ childItem2 = new QStandardItem("child2");
+ childItem2->setData(true, Qt::UserRole);
+ parentItem->appendRow(childItem2);
+ }
+
+ void removeChild()
+ {
+ childItem2->setData(false, Qt::UserRole);
+ parentItem->removeRow(0);
+ }
+
+private:
+ QStandardItem *parentItem, *childItem, *childItem2;
+};
+
+class Proxy10287 : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ Proxy10287(QAbstractItemModel *model, QObject *parent = nullptr)
+ : QSortFilterProxyModel(parent)
+ {
+ setSourceModel(model);
+ setDynamicSortFilter(true);
+ }
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
+ {
+ // Filter based on UserRole in model
+ QModelIndex i = sourceModel()->index(source_row, 0, source_parent);
+ return i.data(Qt::UserRole).toBool();
+ }
+};
+
+void tst_QSortFilterProxyModel::unnecessaryMapCreation()
+{
+ Model10287 m;
+ Proxy10287 p(&m);
+ m.removeChild();
+ // No assert failure, it passes.
+}
+
+class FilteredColumnProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ using QSortFilterProxyModel::QSortFilterProxyModel;
+protected:
+ bool filterAcceptsColumn(int column, const QModelIndex &) const override
+ {
+ return column % 2 != 0;
+ }
+};
+
+void tst_QSortFilterProxyModel::filteredColumns()
+{
+ DynamicTreeModel *model = new DynamicTreeModel(this);
+
+ FilteredColumnProxyModel *proxy = new FilteredColumnProxyModel(this);
+ proxy->setSourceModel(model);
+
+ new QAbstractItemModelTester(proxy, this);
+
+ ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
+ insertCommand->setNumCols(2);
+ insertCommand->setStartRow(0);
+ insertCommand->setEndRow(0);
+ // Parent is QModelIndex()
+ insertCommand->doCommand();
+}
+
+class ChangableHeaderData : public QStringListModel
+{
+ Q_OBJECT
+public:
+ using QStringListModel::QStringListModel;
+ void emitHeaderDataChanged()
+ {
+ headerDataChanged(Qt::Vertical, 0, rowCount() - 1);
+ }
+};
+
+
+void tst_QSortFilterProxyModel::headerDataChanged()
+{
+ ChangableHeaderData *model = new ChangableHeaderData(this);
+
+ QStringList numbers;
+ for (int i = 0; i < 10; ++i)
+ numbers.append(QString::number(i));
+ model->setStringList(numbers);
+
+ QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
+ proxy->setSourceModel(model);
+
+ new QAbstractItemModelTester(proxy, this);
+
+ model->emitHeaderDataChanged();
+}
+
+void tst_QSortFilterProxyModel::resetInvalidate_data()
+{
+ QTest::addColumn<int>("test");
+ QTest::addColumn<bool>("works");
+
+ QTest::newRow("nothing") << 0 << false;
+ QTest::newRow("reset") << 1 << true;
+ QTest::newRow("invalidate") << 2 << true;
+ QTest::newRow("invalidate_filter") << 3 << true;
+}
+
+void tst_QSortFilterProxyModel::resetInvalidate()
+{
+ QFETCH(int, test);
+ QFETCH(bool, works);
+
+ struct Proxy : QSortFilterProxyModel {
+ QString pattern;
+ bool filterAcceptsRow(int source_row, const QModelIndex&) const override
+ {
+ return sourceModel()->data(sourceModel()->index(source_row, 0)).toString().contains(pattern);
+ }
+ void notifyChange(int test)
+ {
+ switch (test) {
+ case 0: break;
+ case 1:
+ beginResetModel();
+ endResetModel();
+ break;
+ case 2: invalidate(); break;
+ case 3: invalidateFilter(); break;
+ }
+ }
+ };
+
+ QStringListModel sourceModel({"Poisson", "Vache", "Brebis",
+ "Elephant", "Cochon", "Serpent",
+ "Mouton", "Ecureuil", "Mouche"});
+ Proxy proxy;
+ proxy.pattern = QString::fromLatin1("n");
+ proxy.setSourceModel(&sourceModel);
+
+ QCOMPARE(proxy.rowCount(), 5);
+ for (int i = 0; i < proxy.rowCount(); i++)
+ QVERIFY(proxy.data(proxy.index(i,0)).toString().contains('n'));
+
+ proxy.pattern = QString::fromLatin1("o");
+ proxy.notifyChange(test);
+
+ QCOMPARE(proxy.rowCount(), works ? 4 : 5);
+ bool ok = true;
+ for (int i = 0; i < proxy.rowCount(); i++) {
+ if (!proxy.data(proxy.index(i,0)).toString().contains('o'))
+ ok = false;
+ }
+ QCOMPARE(ok, works);
+}
+
+/**
+ * A proxy which changes the background color for items ending in 'y' or 'r'
+ */
+class CustomDataProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ CustomDataProxy(QObject *parent = nullptr)
+ : QSortFilterProxyModel(parent)
+ {
+ setDynamicSortFilter(true);
+ }
+
+ void setSourceModel(QAbstractItemModel *sourceModel) override
+ {
+ // It would be possible to use only the modelReset signal of the source model to clear
+ // the data in *this, however, this requires that the slot is connected
+ // before QSortFilterProxyModel::setSourceModel is called, and even then depends
+ // on the order of invocation of slots being the same as the order of connection.
+ // ie, not reliable.
+// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
+ QSortFilterProxyModel::setSourceModel(sourceModel);
+ // Making the connect after the setSourceModel call clears the data too late.
+// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
+
+ // This could be done in data(), but the point is to need to cache something in the proxy
+ // which needs to be cleared on reset.
+ for (int i = 0; i < sourceModel->rowCount(); ++i)
+ {
+ if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y')))
+ m_backgroundColours.insert(i, Qt::blue);
+ else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r')))
+ m_backgroundColours.insert(i, Qt::red);
+ }
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (role != Qt::BackgroundRole)
+ return QSortFilterProxyModel::data(index, role);
+ return m_backgroundColours.value(index.row());
+ }
+
+private slots:
+ void resetInternalData() override
+ {
+ m_backgroundColours.clear();
+ }
+
+private:
+ QHash<int, QColor> m_backgroundColours;
+};
+
+class ModelObserver : public QObject
+{
+ Q_OBJECT
+public:
+ ModelObserver(QAbstractItemModel *model, QObject *parent = nullptr)
+ : QObject(parent), m_model(model)
+ {
+ connect(m_model, &QAbstractItemModel::modelAboutToBeReset,
+ this, &ModelObserver::modelAboutToBeReset);
+ connect(m_model, &QAbstractItemModel::modelReset,
+ this, &ModelObserver::modelReset);
+ }
+
+public slots:
+ void modelAboutToBeReset()
+ {
+ int reds = 0, blues = 0;
+ for (int i = 0; i < m_model->rowCount(); ++i)
+ {
+ QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
+ if (color == Qt::blue)
+ ++blues;
+ else if (color == Qt::red)
+ ++reds;
+ }
+ QCOMPARE(blues, 11);
+ QCOMPARE(reds, 4);
+ }
+
+ void modelReset()
+ {
+ int reds = 0, blues = 0;
+ for (int i = 0; i < m_model->rowCount(); ++i)
+ {
+ QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
+ if (color == Qt::blue)
+ ++blues;
+ else if (color == Qt::red)
+ ++reds;
+ }
+ QCOMPARE(reds, 0);
+ QCOMPARE(blues, 0);
+ }
+
+private:
+ QAbstractItemModel * const m_model;
+
+};
+
+void tst_QSortFilterProxyModel::testResetInternalData()
+{
+ QStringListModel model({"Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "Saturday",
+ "June",
+ "Sunday",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"});
+
+ CustomDataProxy proxy;
+ proxy.setSourceModel(&model);
+
+ ModelObserver observer(&proxy);
+
+ // Cause the source model to reset.
+ model.setStringList({"Spam", "Eggs"});
+
+}
+
+void tst_QSortFilterProxyModel::testParentLayoutChanged()
+{
+ QStandardItemModel model;
+ QStandardItem *parentItem = model.invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ {
+ QStandardItem *item = new QStandardItem(QLatin1String("item ") + QString::number(i));
+ parentItem->appendRow(item);
+ }
+ {
+ QStandardItem *item = new QStandardItem(QLatin1String("item 1") + QString::number(i));
+ parentItem->appendRow(item);
+ parentItem = item;
+ }
+ }
+ // item 0
+ // item 10
+ // - item 1
+ // - item 11
+ // - item 2
+ // - item 12
+ // ...
+
+ QSortFilterProxyModel proxy;
+ proxy.sort(0, Qt::AscendingOrder);
+ proxy.setDynamicSortFilter(true);
+
+ proxy.setSourceModel(&model);
+ proxy.setObjectName("proxy");
+
+ // When Proxy1 emits layoutChanged(QList<QPersistentModelIndex>) this
+ // one will too, with mapped indexes.
+ QSortFilterProxyModel proxy2;
+ proxy2.sort(0, Qt::AscendingOrder);
+ proxy2.setDynamicSortFilter(true);
+
+ proxy2.setSourceModel(&proxy);
+ proxy2.setObjectName("proxy2");
+
+ QSignalSpy dataChangedSpy(&model, &QSortFilterProxyModel::dataChanged);
+
+ QVERIFY(dataChangedSpy.isValid());
+
+ // Verify that the no-arg signal is still emitted.
+ QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(layoutAboutToBeChangedSpy.isValid());
+ QVERIFY(layoutChangedSpy.isValid());
+
+ QSignalSpy parentsAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy parentsChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(parentsAboutToBeChangedSpy.isValid());
+ QVERIFY(parentsChangedSpy.isValid());
+
+ QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxy2ParentsChangedSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(proxy2ParentsAboutToBeChangedSpy.isValid());
+ QVERIFY(proxy2ParentsChangedSpy.isValid());
+
+ QStandardItem *item = model.invisibleRootItem()->child(1)->child(1);
+ QCOMPARE(item->text(), QStringLiteral("item 11"));
+
+ // Ensure mapped:
+ proxy.mapFromSource(model.indexFromItem(item));
+
+ item->setText("Changed");
+
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+ QCOMPARE(parentsAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(parentsChangedSpy.size(), 1);
+ QCOMPARE(proxy2ParentsAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(proxy2ParentsChangedSpy.size(), 1);
+
+ QVariantList beforeSignal = parentsAboutToBeChangedSpy.first();
+ QVariantList afterSignal = parentsChangedSpy.first();
+
+ QCOMPARE(beforeSignal.size(), 2);
+ QCOMPARE(afterSignal.size(), 2);
+
+ QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >();
+ QList<QPersistentModelIndex> afterParents = afterSignal.first().value<QList<QPersistentModelIndex> >();
+
+ QCOMPARE(beforeParents.size(), 1);
+ QCOMPARE(afterParents.size(), 1);
+
+ QVERIFY(beforeParents.first().isValid());
+ QVERIFY(beforeParents.first() == afterParents.first());
+
+ QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1))));
+
+ const QList<QPersistentModelIndex> proxy2BeforeList =
+ proxy2ParentsAboutToBeChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
+ const QList<QPersistentModelIndex> proxy2AfterList =
+ proxy2ParentsChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
+
+ QCOMPARE(proxy2BeforeList.size(), beforeParents.size());
+ QCOMPARE(proxy2AfterList.size(), afterParents.size());
+ for (const QPersistentModelIndex &idx : proxy2BeforeList)
+ QVERIFY(beforeParents.contains(proxy2.mapToSource(idx)));
+ for (const QPersistentModelIndex &idx : proxy2AfterList)
+ QVERIFY(afterParents.contains(proxy2.mapToSource(idx)));
+}
+
+class SignalArgumentChecker : public QObject
+{
+ Q_OBJECT
+public:
+ SignalArgumentChecker(QAbstractItemModel *model, QAbstractProxyModel *proxy, QObject *parent = nullptr)
+ : QObject(parent), m_proxy(proxy)
+ {
+ connect(model, &QAbstractItemModel::rowsAboutToBeMoved,
+ this, &SignalArgumentChecker::rowsAboutToBeMoved);
+ connect(model, &QAbstractItemModel::rowsMoved,
+ this, &SignalArgumentChecker::rowsMoved);
+ connect(proxy, &QAbstractProxyModel::layoutAboutToBeChanged,
+ this, &SignalArgumentChecker::layoutAboutToBeChanged);
+ connect(proxy, &QAbstractProxyModel::layoutChanged,
+ this, &SignalArgumentChecker::layoutChanged);
+ }
+
+private slots:
+ void rowsAboutToBeMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
+ {
+ m_p1PersistentBefore = source;
+ m_p2PersistentBefore = destination;
+ m_p2FirstProxyChild = m_proxy->index(0, 0, m_proxy->mapFromSource(destination));
+ }
+
+ void rowsMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
+ {
+ m_p1PersistentAfter = source;
+ m_p2PersistentAfter = destination;
+ }
+
+ void layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents)
+ {
+ QVERIFY(m_p1PersistentBefore.isValid());
+ QVERIFY(m_p2PersistentBefore.isValid());
+ QCOMPARE(parents.size(), 2);
+ QVERIFY(parents.first() != parents.at(1));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentBefore)));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentBefore)));
+ }
+
+ void layoutChanged(const QList<QPersistentModelIndex> &parents)
+ {
+ QVERIFY(m_p1PersistentAfter.isValid());
+ QVERIFY(m_p2PersistentAfter.isValid());
+ QCOMPARE(parents.size(), 2);
+ QVERIFY(parents.first() != parents.at(1));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentAfter)));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentAfter)));
+
+ // In the source model, the rows were moved to row 1 in the parent.
+ // m_p2FirstProxyChild was created with row 0 in the proxy.
+ // The moved rows in the proxy do not appear at row 1 because of sorting.
+ // Sorting causes them to appear at row 0 instead, pushing what used to
+ // be row 0 in the proxy down by two rows.
+ QCOMPARE(m_p2FirstProxyChild.row(), 2);
+ }
+
+private:
+ QAbstractProxyModel *m_proxy;
+ QPersistentModelIndex m_p1PersistentBefore;
+ QPersistentModelIndex m_p2PersistentBefore;
+ QPersistentModelIndex m_p1PersistentAfter;
+ QPersistentModelIndex m_p2PersistentAfter;
+
+ QPersistentModelIndex m_p2FirstProxyChild;
+};
+
+void tst_QSortFilterProxyModel::moveSourceRows()
+{
+ DynamicTreeModel model;
+
+ {
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(9);
+ insertCommand.doCommand();
+ }
+ {
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setAncestorRowNumbers(QList<int>() << 2);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(9);
+ insertCommand.doCommand();
+ }
+ {
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setAncestorRowNumbers(QList<int>() << 5);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(9);
+ insertCommand.doCommand();
+ }
+
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0, Qt::AscendingOrder);
+
+ // We need to check the arguments at emission time
+ SignalArgumentChecker checker(&model, &proxy);
+
+ proxy.setSourceModel(&model);
+
+ QSortFilterProxyModel filterProxy;
+ filterProxy.setDynamicSortFilter(true);
+ filterProxy.sort(0, Qt::AscendingOrder);
+ filterProxy.setSourceModel(&proxy);
+ setupFilter(&filterProxy, QLatin1String("6")); // One of the parents
+
+ QSortFilterProxyModel filterBothProxy;
+ filterBothProxy.setDynamicSortFilter(true);
+ filterBothProxy.sort(0, Qt::AscendingOrder);
+ filterBothProxy.setSourceModel(&proxy);
+ setupFilter(&filterBothProxy, QLatin1String("5")); // The parents are 6 and 3. This filters both out.
+
+ QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
+ QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
+ QSignalSpy proxyBeforeMoveSpy(m_proxy, &QSortFilterProxyModel::rowsAboutToBeMoved);
+ QSignalSpy proxyAfterMoveSpy(m_proxy, &QSortFilterProxyModel::rowsMoved);
+ QSignalSpy proxyBeforeParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxyAfterParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+ QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy filterAfterParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutChanged);
+ QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(modelBeforeSpy.isValid());
+ QVERIFY(modelAfterSpy.isValid());
+ QVERIFY(proxyBeforeMoveSpy.isValid());
+ QVERIFY(proxyAfterMoveSpy.isValid());
+ QVERIFY(proxyBeforeParentLayoutSpy.isValid());
+ QVERIFY(proxyAfterParentLayoutSpy.isValid());
+ QVERIFY(filterBeforeParentLayoutSpy.isValid());
+ QVERIFY(filterAfterParentLayoutSpy.isValid());
+ QVERIFY(filterBothBeforeParentLayoutSpy.isValid());
+ QVERIFY(filterBothAfterParentLayoutSpy.isValid());
+
+ {
+ ModelMoveCommand moveCommand(&model, nullptr);
+ moveCommand.setAncestorRowNumbers(QList<int>() << 2);
+ moveCommand.setDestAncestors(QList<int>() << 5);
+ moveCommand.setStartRow(3);
+ moveCommand.setEndRow(4);
+ moveCommand.setDestRow(1);
+ moveCommand.doCommand();
+ }
+
+ // Proxy notifies layout change
+ QCOMPARE(modelBeforeSpy.size(), 1);
+ QCOMPARE(proxyBeforeParentLayoutSpy.size(), 1);
+ QCOMPARE(modelAfterSpy.size(), 1);
+ QCOMPARE(proxyAfterParentLayoutSpy.size(), 1);
+
+ // But it doesn't notify a move.
+ QCOMPARE(proxyBeforeMoveSpy.size(), 0);
+ QCOMPARE(proxyAfterMoveSpy.size(), 0);
+
+ QCOMPARE(filterBeforeParentLayoutSpy.size(), 1);
+ QCOMPARE(filterAfterParentLayoutSpy.size(), 1);
+
+ QList<QPersistentModelIndex> filterBeforeParents = filterBeforeParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
+ QList<QPersistentModelIndex> filterAfterParents = filterAfterParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
+
+ QCOMPARE(filterBeforeParents.size(), 1);
+ QCOMPARE(filterAfterParents.size(), 1);
+
+ QCOMPARE(
+ filterBeforeParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+ QCOMPARE(filterAfterParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+
+ QCOMPARE(filterBothBeforeParentLayoutSpy.size(), 0);
+ QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0);
+}
+
+class FilterProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ using QSortFilterProxyModel::QSortFilterProxyModel;
+public slots:
+ void setMode(bool on)
+ {
+ mode = on;
+ invalidateFilter();
+ }
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
+ {
+ if (mode) {
+ if (!source_parent.isValid())
+ return true;
+ else
+ return (source_row % 2) != 0;
+ } else {
+ if (!source_parent.isValid())
+ return source_row >= 2 && source_row < 10;
+ else
+ return true;
+ }
+ }
+
+private:
+ bool mode = false;
+};
+
+void tst_QSortFilterProxyModel::hierarchyFilterInvalidation()
+{
+ QStandardItemModel model;
+ for (int i = 0; i < 10; ++i) {
+ const QString rowText = QLatin1String("Row ") + QString::number(i);
+ QStandardItem *child = new QStandardItem(rowText);
+ for (int j = 0; j < 1; ++j) {
+ child->appendRow(new QStandardItem(rowText + QLatin1Char('/') + QString::number(j)));
+ }
+ model.appendRow(child);
+ }
+
+ FilterProxy proxy;
+ proxy.setSourceModel(&model);
+
+ QTreeView view;
+ view.setModel(&proxy);
+
+ view.setCurrentIndex(proxy.index(0, 0, proxy.index(2, 0)));
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ proxy.setMode(true);
+}
+
+class FilterProxy2 : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ using QSortFilterProxyModel::QSortFilterProxyModel;
+public slots:
+ void setMode(bool on)
+ {
+ mode = on;
+ invalidateFilter();
+ }
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
+ {
+ if (source_parent.isValid())
+ return true;
+ if (0 == source_row)
+ return true;
+ return !mode;
+ }
+
+private:
+ bool mode = false;
+};
+
+void tst_QSortFilterProxyModel::simpleFilterInvalidation()
+{
+ QStandardItemModel model;
+ for (int i = 0; i < 2; ++i) {
+ QStandardItem *child = new QStandardItem(QLatin1String("Row ") + QString::number(i));
+ child->appendRow(new QStandardItem("child"));
+ model.appendRow(child);
+ }
+
+ FilterProxy2 proxy;
+ proxy.setSourceModel(&model);
+
+ QTreeView view;
+ view.setModel(&proxy);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ proxy.setMode(true);
+ model.insertRow(0, new QStandardItem("extra"));
+}
+
+class CustomRoleNameModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ using QAbstractListModel::QAbstractListModel;
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ Q_UNUSED(index);
+ Q_UNUSED(role);
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ Q_UNUSED(parent);
+ return 0;
+ }
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ QHash<int, QByteArray> rn = QAbstractListModel::roleNames();
+ rn[Qt::UserRole + 1] = "custom";
+ return rn;
+ }
+};
+
+void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
+{
+ QSortFilterProxyModel proxy1;
+ QSortFilterProxyModel proxy2;
+ CustomRoleNameModel customModel;
+
+ proxy2.setSourceModel(&proxy1);
+
+ // changing the sourceModel of proxy1 must also update roleNames of proxy2
+ proxy1.setSourceModel(&customModel);
+ QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
+}
+
+// A source model with ABABAB rows, where only A rows accept drops.
+// It will then be sorted by a QSFPM.
+class DropOnOddRows : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ using QAbstractListModel::QAbstractListModel;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (role == Qt::DisplayRole)
+ return (index.row() % 2 == 0) ? "A" : "B";
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ Q_UNUSED(parent);
+ return 10;
+ }
+
+ bool canDropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int column, const QModelIndex &parent) const override
+ {
+ Q_UNUSED(row);
+ Q_UNUSED(column);
+ return parent.row() % 2 == 0;
+ }
+};
+
+class SourceAssertion : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ using QSortFilterProxyModel::QSortFilterProxyModel;
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
+ {
+ Q_ASSERT(sourceModel());
+ return QSortFilterProxyModel::mapToSource(proxyIndex);
+ }
+};
+
+void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
+{
+ SourceAssertion proxy;
+ QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
+
+ proxy.setSourceModel(model);
+
+ // Create mappings
+ QPersistentModelIndex persistent = proxy.index(0, 0);
+
+ QVERIFY(persistent.isValid());
+
+ delete model;
+
+ QVERIFY(!persistent.isValid());
+}
+
+// QTBUG-39549, test whether canDropMimeData(), dropMimeData() are proxied as well
+// by invoking them on a QSortFilterProxyModel proxying a QStandardItemModel that allows drops
+// on row #1, filtering for that row.
+class DropTestModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ explicit DropTestModel(QObject *parent = nullptr) : QStandardItemModel(0, 1, parent)
+ {
+ appendRow(new QStandardItem(QStringLiteral("Row0")));
+ appendRow(new QStandardItem(QStringLiteral("Row1")));
+ }
+
+ bool canDropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int /* column */, const QModelIndex & /* parent */) const override
+ { return row == 1; }
+
+ bool dropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int /* column */, const QModelIndex & /* parent */) override
+ { return row == 1; }
+};
+
+void tst_QSortFilterProxyModel::forwardDropApi()
+{
+ QSortFilterProxyModel model;
+ model.setSourceModel(new DropTestModel(&model));
+ model.setFilterFixedString(QStringLiteral("Row1"));
+ QCOMPARE(model.rowCount(), 1);
+ QVERIFY(model.canDropMimeData(nullptr, Qt::CopyAction, 0, 0, QModelIndex()));
+ QVERIFY(model.dropMimeData(nullptr, Qt::CopyAction, 0, 0, QModelIndex()));
+}
+
+static QString rowTexts(QAbstractItemModel *model)
+{
+ QString str;
+ for (int row = 0 ; row < model->rowCount(); ++row)
+ str += model->index(row, 0).data().toString();
+ return str;
+}
+
+void tst_QSortFilterProxyModel::canDropMimeData()
+{
+ // Given a source model which only supports dropping on even rows
+ DropOnOddRows sourceModel;
+ QCOMPARE(rowTexts(&sourceModel), QString("ABABABABAB"));
+
+ // and a proxy model that sorts the rows
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&sourceModel);
+ proxy.sort(0, Qt::AscendingOrder);
+ QCOMPARE(rowTexts(&proxy), QString("AAAAABBBBB"));
+
+ // the proxy should correctly map canDropMimeData to the source model,
+ // i.e. accept drops on the first 5 rows and refuse drops on the next 5.
+ for (int row = 0; row < proxy.rowCount(); ++row)
+ QCOMPARE(proxy.canDropMimeData(nullptr, Qt::CopyAction, -1, -1, proxy.index(row, 0)), row < 5);
+}
+
+void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels()
+{
+ QStandardItemModel *treeModel = new QStandardItemModel(this);
+ QStandardItem *e1 = new QStandardItem("Loading...");
+ e1->appendRow(new QStandardItem("entry10"));
+ treeModel->appendRow(e1);
+ QStandardItem *e0 = new QStandardItem("Loading...");
+ e0->appendRow(new QStandardItem("entry00"));
+ e0->appendRow(new QStandardItem("entry01"));
+ treeModel->appendRow(e0);
+
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+ proxy.setSourceModel(treeModel);
+
+ QAbstractItemModelTester modelTester(&proxy);
+
+ QCOMPARE(proxy.rowCount(), 2);
+ e1->setText("entry1");
+ e0->setText("entry0");
+
+ QModelIndex pi0 = proxy.index(0, 0);
+ QCOMPARE(pi0.data().toString(), QString("entry0"));
+ QCOMPARE(proxy.rowCount(pi0), 2);
+
+ QModelIndex pi01 = proxy.index(1, 0, pi0);
+ QCOMPARE(pi01.data().toString(), QString("entry01"));
+
+ QModelIndex pi1 = proxy.index(1, 0);
+ QCOMPARE(pi1.data().toString(), QString("entry1"));
+ QCOMPARE(proxy.rowCount(pi1), 1);
+}
+
+void tst_QSortFilterProxyModel::filterHint()
+{
+ // test that a filtering model does not emit layoutChanged with a hint
+ QStringListModel model({"one", "two", "three", "four", "five", "six"});
+ QSortFilterProxyModel proxy1;
+ proxy1.setSourceModel(&model);
+ proxy1.setSortRole(Qt::DisplayRole);
+ proxy1.setDynamicSortFilter(true);
+ proxy1.sort(0);
+
+ QSortFilterProxyModel proxy2;
+ proxy2.setSourceModel(&proxy1);
+ proxy2.setFilterRole(Qt::DisplayRole);
+ setupFilter(&proxy2, QLatin1String("^[^ ]*$"));
+ proxy2.setDynamicSortFilter(true);
+
+ QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxy1AfterSpy(&proxy1, &QSortFilterProxyModel::layoutChanged);
+ QSignalSpy proxy2BeforeSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxy2AfterSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
+
+ model.setData(model.index(2), QStringLiteral("modified three"), Qt::DisplayRole);
+
+ // The first proxy was re-sorted as one item as changed.
+ QCOMPARE(proxy1BeforeSpy.size(), 1);
+ QCOMPARE(proxy1BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::VerticalSortHint);
+ QCOMPARE(proxy1AfterSpy.size(), 1);
+ QCOMPARE(proxy1AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::VerticalSortHint);
+
+ // But the second proxy must not have the VerticalSortHint since an item was filtered
+ QCOMPARE(proxy2BeforeSpy.size(), 1);
+ QCOMPARE(proxy2BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+ QCOMPARE(proxy2AfterSpy.size(), 1);
+ QCOMPARE(proxy2AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+}
+
+/**
+
+ Creates a model where each item has one child, to a set depth,
+ and the last item has no children. For a model created with
+ setDepth(4):
+
+ - 1
+ - - 2
+ - - - 3
+ - - - - 4
+*/
+class StepTreeModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ using QAbstractItemModel::QAbstractItemModel;
+
+ int columnCount(const QModelIndex& = QModelIndex()) const override { return 1; }
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override
+ {
+ quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
+ return (parentId < m_depth) ? 1 : 0;
+ }
+
+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override
+ {
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ return QString::number(index.internalId());
+ }
+
+ QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override
+ {
+ // QTBUG-44962: Would we always expect the parent to belong to the model
+ qCDebug(lcItemModels) << parent.model() << this;
+ Q_ASSERT(!parent.isValid() || parent.model() == this);
+
+ quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
+ if (parentId >= m_depth)
+ return QModelIndex();
+
+ return createIndex(0, 0, parentId + 1);
+ }
+
+ QModelIndex parent(const QModelIndex& index) const override
+ {
+ if (index.internalId() == 0)
+ return QModelIndex();
+
+ return createIndex(0, 0, index.internalId() - 1);
+ }
+
+ void setDepth(quintptr depth)
+ {
+ quintptr parentIdWithLayoutChange = (m_depth < depth) ? m_depth : depth;
+
+ QList<QPersistentModelIndex> parentsOfLayoutChange;
+ parentsOfLayoutChange.push_back(createIndex(0, 0, parentIdWithLayoutChange));
+
+ layoutAboutToBeChanged(parentsOfLayoutChange);
+
+ auto existing = persistentIndexList();
+
+ QList<QModelIndex> updated;
+
+ for (auto idx : existing) {
+ if (indexDepth(idx) <= depth)
+ updated.push_back(idx);
+ else
+ updated.push_back({});
+ }
+
+ m_depth = depth;
+
+ changePersistentIndexList(existing, updated);
+
+ layoutChanged(parentsOfLayoutChange);
+ }
+
+private:
+ static quintptr indexDepth(QModelIndex const& index)
+ {
+ return (index.isValid()) ? 1 + indexDepth(index.parent()) : 0;
+ }
+
+private:
+ quintptr m_depth = 0;
+};
+
+void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
+{
+ StepTreeModel model;
+ Q_SET_OBJECT_NAME(model);
+ model.setDepth(4);
+
+ QSortFilterProxyModel proxy1;
+ proxy1.setSourceModel(&model);
+ Q_SET_OBJECT_NAME(proxy1);
+ setupFilter(&proxy1, QLatin1String("1|2"));
+
+ // The current state of things:
+ // model proxy
+ // - 1 - 1
+ // - - 2 - - 2
+ // - - - 3
+ // - - - - 4
+
+ // The setDepth call below removes '4' with a layoutChanged call.
+ // Because the proxy filters that out anyway, the proxy doesn't need
+ // to emit any signals or update persistent indexes.
+
+ QPersistentModelIndex persistentIndex = proxy1.index(0, 0, proxy1.index(0, 0));
+
+ model.setDepth(3);
+
+ // Calling parent() causes the internalPointer to be used.
+ // Before fixing QTBUG-47711, that could be a dangling pointer.
+ // The use of qDebug here makes sufficient use of the heap to
+ // cause corruption at runtime with normal use on linux (before
+ // the fix). valgrind confirms the fix.
+ qCDebug(lcItemModels) << persistentIndex.parent();
+ QVERIFY(persistentIndex.parent().isValid());
+}
+
+void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes()
+{
+ DynamicTreeModel model;
+ Q_SET_OBJECT_NAME(model);
+
+ QList<int> ancestors;
+ for (auto i = 0; i < 5; ++i)
+ {
+ Q_UNUSED(i);
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setAncestorRowNumbers(ancestors);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(0);
+ insertCommand.doCommand();
+ ancestors.push_back(0);
+ }
+
+ QSortFilterProxyModel proxy1;
+ proxy1.setSourceModel(&model);
+ Q_SET_OBJECT_NAME(proxy1);
+
+ setupFilter(&proxy1, QLatin1String("1|2"));
+
+ auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first();
+ auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first();
+
+ Q_ASSERT(item5.isValid());
+ Q_ASSERT(item3.isValid());
+
+ QPersistentModelIndex persistentIndex = proxy1.match(proxy1.index(0, 0), Qt::DisplayRole, "2", 1, Qt::MatchRecursive).first();
+
+ ModelMoveCommand moveCommand(&model, nullptr);
+ moveCommand.setAncestorRowNumbers(QList<int>{0, 0, 0, 0});
+ moveCommand.setStartRow(0);
+ moveCommand.setEndRow(0);
+ moveCommand.setDestRow(0);
+ moveCommand.setDestAncestors(QList<int>{0, 0, 0});
+ moveCommand.doCommand();
+
+ // Calling parent() causes the internalPointer to be used.
+ // Before fixing QTBUG-47711 (moveRows case), that could be
+ // a dangling pointer.
+ QVERIFY(persistentIndex.parent().isValid());
+}
+
+void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged_data()
+{
+ QTest::addColumn<int>("changedRow");
+ QTest::addColumn<Qt::ItemDataRole>("changedRole");
+ QTest::addColumn<QString>("newData");
+ QTest::addColumn<QString>("expectedSourceRowTexts");
+ QTest::addColumn<QString>("expectedProxyRowTexts");
+ QTest::addColumn<int>("expectedLayoutChanged");
+
+ // Starting point:
+ // a source model with 8,7,6,5,4,3,2,1
+ // a proxy model keeping only even rows and sorting them, therefore showing 2,4,6,8
+
+ // When setData changes ordering, layoutChanged should be emitted
+ QTest::newRow("ordering_change") << 0 << Qt::DisplayRole << "0" << "07654321" << "0246" << 1;
+
+ // When setData on visible row doesn't change ordering, layoutChanged should not be emitted
+ QTest::newRow("no_ordering_change") << 6 << Qt::DisplayRole << "0" << "87654301" << "0468" << 0;
+
+ // When setData happens on a filtered out row, layoutChanged should not be emitted
+ QTest::newRow("filtered_out") << 1 << Qt::DisplayRole << "9" << "89654321" << "2468" << 0;
+
+ // When setData makes a row visible, layoutChanged should not be emitted (rowsInserted is emitted instead)
+ QTest::newRow("make_row_visible") << 7 << Qt::DisplayRole << "0" << "87654320" << "02468" << 0;
+
+ // When setData makes a row hidden, layoutChanged should not be emitted (rowsRemoved is emitted instead)
+ QTest::newRow("make_row_hidden") << 4 << Qt::DisplayRole << "1" << "87651321" << "268" << 0;
+
+ // When setData happens on an unrelated role, layoutChanged should not be emitted
+ QTest::newRow("unrelated_role") << 0 << Qt::DecorationRole << "" << "87654321" << "2468" << 0;
+
+ // When many changes happen together... and trigger removal, insertion, and layoutChanged
+ QTest::newRow("many_changes") << -1 << Qt::DisplayRole << "3,4,2,5,6,0,7,9" << "34256079" << "0246" << 1;
+
+ // When many changes happen together... and trigger removal, insertion, but no change in ordering of visible rows => no layoutChanged
+ QTest::newRow("many_changes_no_layoutChanged") << -1 << Qt::DisplayRole << "7,5,4,3,2,1,0,8" << "75432108" << "0248" << 0;
+}
+
+// Custom version of QStringListModel which supports emitting dataChanged for many rows at once
+class CustomStringListModel : public QAbstractListModel
+{
+public:
+ bool setData(const QModelIndex &index, const QVariant &value, int role) override
+ {
+ if (index.row() >= 0 && index.row() < lst.size()
+ && (role == Qt::EditRole || role == Qt::DisplayRole)) {
+ lst.replace(index.row(), value.toString());
+ emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole });
+ return true;
+ }
+ return false;
+ }
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (role == Qt::DisplayRole || role == Qt::EditRole)
+ return lst.at(index.row());
+ return QVariant();
+ }
+ int rowCount(const QModelIndex & = QModelIndex()) const override { return lst.size(); }
+
+ void replaceData(const QStringList &newData)
+ {
+ lst = newData;
+ emit dataChanged(index(0, 0), index(rowCount() - 1, 0), { Qt::DisplayRole, Qt::EditRole });
+ }
+
+ void emitDecorationChangedSignal()
+ {
+ const QModelIndex idx = index(0, 0);
+ emit dataChanged(idx, idx, { Qt::DecorationRole });
+ }
+
+private:
+ QStringList lst;
+};
+
+void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged()
+{
+ QFETCH(int, changedRow);
+ QFETCH(QString, newData);
+ QFETCH(Qt::ItemDataRole, changedRole);
+ QFETCH(QString, expectedSourceRowTexts);
+ QFETCH(QString, expectedProxyRowTexts);
+ QFETCH(int, expectedLayoutChanged);
+
+ CustomStringListModel model;
+ QStringList strings;
+ for (auto i = 8; i >= 1; --i)
+ strings.append(QString::number(i));
+ model.replaceData(strings);
+ QCOMPARE(rowTexts(&model), QStringLiteral("87654321"));
+
+ class FilterEvenRowsProxyModel : public QSortFilterProxyModel
+ {
+ public:
+ bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const override
+ {
+ return sourceModel()->index(srcRow, 0, srcParent).data().toInt() % 2 == 0;
+ }
+ };
+
+ FilterEvenRowsProxyModel proxy;
+ proxy.sort(0);
+ proxy.setSourceModel(&model);
+ QCOMPARE(rowTexts(&proxy), QStringLiteral("2468"));
+
+ QSignalSpy modelDataChangedSpy(&model, &QAbstractItemModel::dataChanged);
+ QSignalSpy proxyLayoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
+
+ if (changedRole == Qt::DecorationRole)
+ model.emitDecorationChangedSignal();
+ else if (changedRow == -1)
+ model.replaceData(newData.split(QLatin1Char(',')));
+ else
+ model.setData(model.index(changedRow, 0), newData, changedRole);
+
+ QCOMPARE(rowTexts(&model), expectedSourceRowTexts);
+ QCOMPARE(rowTexts(&proxy), expectedProxyRowTexts);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyLayoutChangedSpy.size(), expectedLayoutChanged);
+}
+
+void tst_QSortFilterProxyModel::removeIntervals_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<QStringList>("replacementSourceItems");
+ QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
+ QTest::addColumn<QStringList>("expectedProxyItems");
+
+ QTest::newRow("filter all, sort ascending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "x"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(0, 2)) // expectedRemovedIntervals
+ << QStringList() // expectedProxyItems
+ ;
+
+ QTest::newRow("filter all, sort descending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << Qt::DescendingOrder // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "x"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(0, 2)) // expectedRemovedIntervals
+ << QStringList() // expectedProxyItems
+ ;
+
+ QTest::newRow("filter first and last, sort ascending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << Qt::AscendingOrder // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "b"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+
+ QTest::newRow("filter first and last, sort descending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << Qt::DescendingOrder // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "b"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+}
+
+void tst_QSortFilterProxyModel::removeIntervals()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(Qt::SortOrder, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(QStringList, replacementSourceItems);
+ QFETCH(IntPairList, expectedRemovedProxyIntervals);
+ QFETCH(QStringList, expectedProxyItems);
+
+ CustomStringListModel model;
+ QSortFilterProxyModel proxy;
+
+ model.replaceData(sourceItems);
+ proxy.setSourceModel(&model);
+
+ for (int i = 0; i < sourceItems.size(); ++i) {
+ QModelIndex sindex = model.index(i, 0, QModelIndex());
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
+ }
+
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0, sortOrder);
+ if (!filter.isEmpty())
+ setupFilter(&proxy, filter);
+
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
+ QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
+
+ QVERIFY(removeSpy.isValid());
+ QVERIFY(insertSpy.isValid());
+ QVERIFY(aboutToRemoveSpy.isValid());
+ QVERIFY(aboutToInsertSpy.isValid());
+
+ model.replaceData(replacementSourceItems);
+
+ QCOMPARE(aboutToRemoveSpy.size(), expectedRemovedProxyIntervals.size());
+ for (int i = 0; i < aboutToRemoveSpy.size(); ++i) {
+ const auto &args = aboutToRemoveSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+ QCOMPARE(removeSpy.size(), expectedRemovedProxyIntervals.size());
+ for (int i = 0; i < removeSpy.size(); ++i) {
+ const auto &args = removeSpy.at(i);
+ QCOMPARE(args.at(1).userType(), QMetaType::Int);
+ QCOMPARE(args.at(2).userType(), QMetaType::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+
+ QCOMPARE(insertSpy.size(), 0);
+ QCOMPARE(aboutToInsertSpy.size(), 0);
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.size());
+ for (int i = 0; i < expectedProxyItems.size(); ++i) {
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::dynamicFilterWithoutSort()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ proxy.setSourceModel(&model);
+
+ QSignalSpy layoutChangeSpy(&proxy, &QAbstractItemModel::layoutChanged);
+ QSignalSpy resetSpy(&proxy, &QAbstractItemModel::modelReset);
+
+ QVERIFY(layoutChangeSpy.isValid());
+ QVERIFY(resetSpy.isValid());
+
+ model.setStringList(QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
+
+ QVERIFY(layoutChangeSpy.isEmpty());
+
+ QCOMPARE(model.stringList(), QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
+
+ QCOMPARE(resetSpy.size(), 1);
+}
+
+void tst_QSortFilterProxyModel::checkSetNewModel()
+{
+ QTreeView tv;
+ StepTreeModel model1;
+ model1.setDepth(4);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model1);
+ tv.setModel(&proxy);
+ tv.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tv));
+ tv.expandAll();
+ {
+ StepTreeModel model2;
+ model2.setDepth(4);
+ proxy.setSourceModel(&model2);
+ tv.expandAll();
+ proxy.setSourceModel(&model1);
+ tv.expandAll();
+ // the destruction of model2 here caused a proxy model reset due to
+ // missing disconnect in setSourceModel()
+ }
+ // handle repaint events, will assert when qsortfilterproxymodel is in wrong state
+ QCoreApplication::processEvents();
+}
+
+enum ColumnFilterMode {
+ FilterNothing,
+ FilterOutMiddle,
+ FilterOutBeginEnd,
+ FilterAll
+};
+Q_DECLARE_METATYPE(ColumnFilterMode)
+
+void tst_QSortFilterProxyModel::filterAndInsertColumn_data()
+{
+
+ QTest::addColumn<int>("insertCol");
+ QTest::addColumn<ColumnFilterMode>("filterMode");
+ QTest::addColumn<QStringList>("expectedModelList");
+ QTest::addColumn<QStringList>("expectedProxyModelList");
+
+ QTest::newRow("at_beginning_filter_out_middle")
+ << 0
+ << FilterOutMiddle
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ << QStringList{{"", "D1"}}
+ ;
+ QTest::newRow("at_end_filter_out_middle")
+ << 2
+ << FilterOutMiddle
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"A1", ""}}
+ ;
+ QTest::newRow("in_the_middle_filter_out_middle")
+ << 1
+ << FilterOutMiddle
+ << QStringList{{"A1", "B1", "C1", "", "D1"}}
+ << QStringList{{"A1", "D1"}}
+ ;
+ QTest::newRow("at_beginning_filter_out_begin_and_end")
+ << 0
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "", "B1", "C1", "D1"}}
+ << QStringList{{"", "B1", "C1"}}
+ ;
+ QTest::newRow("at_end_filter_out_begin_and_end")
+ << 2
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"B1", "C1", "D1"}}
+ ;
+ QTest::newRow("in_the_middle_filter_out_begin_and_end")
+ << 1
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ << QStringList{{"B1", "", "C1"}}
+ ;
+
+ QTest::newRow("at_beginning_filter_nothing")
+ << 0
+ << FilterAll
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ ;
+ QTest::newRow("at_end_filter_nothing")
+ << 4
+ << FilterAll
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ ;
+ QTest::newRow("in_the_middle_nothing")
+ << 2
+ << FilterAll
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ ;
+
+ QTest::newRow("filter_all")
+ << 0
+ << FilterNothing
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{}
+ ;
+}
+void tst_QSortFilterProxyModel::filterAndInsertColumn()
+{
+
+ class ColumnFilterProxy : public QSortFilterProxyModel
+ {
+ ColumnFilterMode filerMode;
+ public:
+ ColumnFilterProxy(ColumnFilterMode mode)
+ : filerMode(mode)
+ {}
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
+ {
+ Q_UNUSED(source_parent);
+ switch (filerMode){
+ case FilterAll:
+ return true;
+ case FilterNothing:
+ return false;
+ case FilterOutMiddle:
+ return source_column == 0 || source_column == sourceModel()->columnCount() - 1;
+ case FilterOutBeginEnd:
+ return source_column > 0 && source_column< sourceModel()->columnCount() - 1;
+ }
+ Q_UNREACHABLE();
+ }
+ };
+ QFETCH(int, insertCol);
+ QFETCH(ColumnFilterMode, filterMode);
+ QFETCH(QStringList, expectedModelList);
+ QFETCH(QStringList, expectedProxyModelList);
+ QStandardItemModel model;
+ model.insertColumns(0, 4);
+ model.insertRows(0, 1);
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j)
+ model.setData(model.index(i, j), QString(QChar('A' + j)) + QString::number(i + 1));
+ }
+ ColumnFilterProxy proxy(filterMode);
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.insertColumn(insertCol));
+ proxy.invalidate();
+ QStringList modelStringList;
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j)
+ modelStringList.append(model.index(i, j).data().toString());
+ }
+ QCOMPARE(expectedModelList, modelStringList);
+ modelStringList.clear();
+ for (int i = 0; i < proxy.rowCount(); ++i) {
+ for (int j = 0; j < proxy.columnCount(); ++j)
+ modelStringList.append(proxy.index(i, j).data().toString());
+ }
+ QCOMPARE(expectedProxyModelList, modelStringList);
+}
+
+void tst_QSortFilterProxyModel::filterAndInsertRow_data()
+{
+ QTest::addColumn<QStringList>("initialModelList");
+ QTest::addColumn<int>("row");
+ QTest::addColumn<QString>("filterRegExp");
+ QTest::addColumn<QStringList>("expectedModelList");
+ QTest::addColumn<QStringList>("expectedProxyModelList");
+
+ QTest::newRow("at_beginning_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "^A"
+ << QStringList{{"", "A5", "B5", "B6", "A7"}}
+ << QStringList{{"A5", "A7"}};
+ QTest::newRow("at_end_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << "^A"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"A5", "A7"}};
+ QTest::newRow("in_the_middle_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 1
+ << "^A"
+ << QStringList{{"A5", "B5", "B6", "", "A7"}}
+ << QStringList{{"A5", "A7"}};
+
+ QTest::newRow("at_beginning_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "^B"
+ << QStringList{{"A5", "", "B5", "B6", "A7"}}
+ << QStringList{{"B5", "B6"}};
+ QTest::newRow("at_end_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << "^B"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"B5", "B6"}};
+ QTest::newRow("in_the_middle_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 1
+ << "^B"
+ << QStringList{{"A5", "B5", "", "B6", "A7"}}
+ << QStringList{{"B5", "B6"}};
+
+ QTest::newRow("at_beginning_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << ".*"
+ << QStringList{{"", "A5", "B5", "B6", "A7"}}
+ << QStringList{{"", "A5", "B5", "B6", "A7"}};
+ QTest::newRow("at_end_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 4
+ << ".*"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"A5", "B5", "B6", "A7", ""}};
+ QTest::newRow("in_the_middle_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << ".*"
+ << QStringList{{"A5", "B5", "", "B6", "A7"}}
+ << QStringList{{"A5", "B5", "", "B6", "A7"}};
+
+ QTest::newRow("filter_all")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "$a"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{};
+}
+
+void tst_QSortFilterProxyModel::filterAndInsertRow()
+{
+ QFETCH(QStringList, initialModelList);
+ QFETCH(int, row);
+ QFETCH(QString, filterRegExp);
+ QFETCH(QStringList, expectedModelList);
+ QFETCH(QStringList, expectedProxyModelList);
+ QStringListModel model;
+ QSortFilterProxyModel proxyModel;
+
+ model.setStringList(initialModelList);
+ proxyModel.setSourceModel(&model);
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.setFilterRegularExpression(filterRegExp);
+
+ QVERIFY(proxyModel.insertRow(row));
+ QCOMPARE(model.stringList(), expectedModelList);
+ QCOMPARE(proxyModel.rowCount(), expectedProxyModelList.size());
+ for (int r = 0; r < proxyModel.rowCount(); ++r) {
+ QModelIndex index = proxyModel.index(r, 0);
+ QVERIFY(index.isValid());
+ QCOMPARE(proxyModel.data(index).toString(), expectedProxyModelList.at(r));
+ }
+}
+
+
+namespace CheckFilteredIndexes {
+class TableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ static const int s_rowCount = 1000;
+ static const int s_columnCount = 1;
+ TableModel(QObject *parent = nullptr) : QAbstractTableModel(parent)
+ {
+ m_data.resize(s_rowCount);
+ for (int r = 0; r < s_rowCount; ++r) {
+ auto &curRow = m_data[r];
+ curRow.resize(s_columnCount);
+ for (int c = 0; c < s_columnCount; ++c) {
+ curRow[c] = QVariant(QString::number(r % 100) +
+ QLatin1Char('_') + QString::number(r / 100) +
+ QString::number(c));
+ }
+ }
+ }
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ return parent.isValid() ? 0 : s_rowCount;
+ }
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ return parent.isValid() ? 0 : s_columnCount;
+ }
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (role != Qt::DisplayRole || !index.isValid())
+ return QVariant();
+ return m_data[index.row()][index.column()];
+ }
+ QList<QList<QVariant>> m_data;
+};
+
+class SortFilterProxyModel final : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ using QSortFilterProxyModel::QSortFilterProxyModel;
+ using QSortFilterProxyModel::invalidateFilter;
+
+ void setSourceModel(QAbstractItemModel *m) override
+ {
+ m_sourceModel = qobject_cast<TableModel*>(m);
+ QSortFilterProxyModel::setSourceModel(m);
+ }
+ bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
+ {
+ if (!left.isValid() || !right.isValid() || !m_sourceModel)
+ return QSortFilterProxyModel::lessThan(left, right);
+ return m_sourceModel->m_data.at(left.row()).at(left.column()).toString() <
+ m_sourceModel->m_data.at(right.row()).at(right.column()).toString();
+ }
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
+ {
+ if (m_filteredRows == 0 || source_parent.isValid())
+ return true;
+ return (source_row % m_filteredRows) != 0;
+ }
+
+ TableModel *m_sourceModel = nullptr;
+ int m_filteredRows = 0;
+ bool m_bInverseFilter = false;
+};
+}
+
+void tst_QSortFilterProxyModel::checkFilteredIndexes()
+{
+ using namespace CheckFilteredIndexes;
+ auto checkIndexes = [](const SortFilterProxyModel &s)
+ {
+ for (int r = 0; r < s.rowCount(); ++r) {
+ const QModelIndex idxSFPM = s.index(r, 0);
+ const QModelIndex idxTM = s.mapToSource(idxSFPM);
+ QVERIFY(idxTM.isValid());
+ QVERIFY(idxTM.row() % s.m_filteredRows != 0);
+ }
+ };
+
+ TableModel m;
+ SortFilterProxyModel s;
+ s.m_filteredRows = 2; // every 2nd row is filtered
+ s.setSourceModel(&m);
+ s.sort(0);
+
+ s.invalidateFilter();
+ checkIndexes(s);
+
+ s.m_filteredRows = 5; // every 5th row is filtered
+ s.invalidateFilter();
+ checkIndexes(s);
+
+ s.m_filteredRows = 3; // every 3rd row is filtered
+ s.invalidateFilter();
+ checkIndexes(s);
+}
+
+void tst_QSortFilterProxyModel::invalidateColumnsOrRowsFilter()
+{
+ class FilterProxy : public QSortFilterProxyModel
+ {
+ public:
+ FilterProxy()
+ {}
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
+ {
+ rowFiltered++;
+
+ if (sourceModel()->data(sourceModel()->index(source_row, 0, source_parent)).toString() == QLatin1String("A1"))
+ return !rejectA1;
+ return true;
+ }
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
+ {
+ Q_UNUSED(source_column);
+ Q_UNUSED(source_parent);
+
+ columnFiltered++;
+ return true;
+ }
+
+ mutable int rowFiltered = 0;
+ mutable int columnFiltered = 0;
+ bool rejectA1 = false;
+
+ using QSortFilterProxyModel::invalidateFilter;
+ using QSortFilterProxyModel::invalidateRowsFilter;
+ using QSortFilterProxyModel::invalidateColumnsFilter;
+ };
+ QStandardItemModel model(10, 4);
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j) {
+ model.setItem(i, j, new QStandardItem(QString(QChar('A' + j)) + QString::number(i + 1)));
+ model.item(i, 0)->appendColumn({ new QStandardItem(QString("child col %0").arg(j)) });
+ }
+ }
+ FilterProxy proxy;
+ proxy.setSourceModel(&model);
+
+ QTreeView view;
+ view.setModel(&proxy);
+ view.expandAll();
+
+ QCOMPARE(proxy.rowFiltered, 20); //10 parents + 10 children
+ QCOMPARE(proxy.columnFiltered, 44); // 4 parents + 4 * 10 children
+
+ proxy.rowFiltered = proxy.columnFiltered = 0;
+ proxy.invalidateFilter();
+
+ QCOMPARE(proxy.rowFiltered, 20);
+ QCOMPARE(proxy.columnFiltered, 44);
+
+ proxy.rowFiltered = proxy.columnFiltered = 0;
+ proxy.invalidateRowsFilter();
+
+ QCOMPARE(proxy.rowFiltered, 20);
+ QCOMPARE(proxy.columnFiltered, 0);
+
+ proxy.rowFiltered = proxy.columnFiltered = 0;
+ proxy.invalidateColumnsFilter();
+
+ QCOMPARE(proxy.rowFiltered, 0);
+ QCOMPARE(proxy.columnFiltered, 44);
+
+ QCOMPARE(proxy.rowCount(), 10);
+ proxy.rejectA1 = true;
+ proxy.rowFiltered = proxy.columnFiltered = 0;
+ proxy.invalidateRowsFilter();
+ QCOMPARE(proxy.rowCount(), 9);
+ QCOMPARE(proxy.rowFiltered, 19); // it will not check the child row of A1
+
+ proxy.rowFiltered = proxy.columnFiltered = 0;
+ proxy.setRecursiveFilteringEnabled(true); // this triggers invalidateRowsFilter()
+ QCOMPARE(proxy.rowCount(), 10);
+ QCOMPARE(proxy.rowFiltered, 20);
+}
+
+void tst_QSortFilterProxyModel::filterKeyColumnBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.filterKeyColumn(), 0);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, int>(proxyModel, 10, 5,
+ "filterKeyColumn");
+}
+
+void tst_QSortFilterProxyModel::dynamicSortFilterBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.dynamicSortFilter(), true);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, bool>(proxyModel, false, true,
+ "dynamicSortFilter");
+}
+
+void tst_QSortFilterProxyModel::sortCaseSensitivityBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.sortCaseSensitivity(), Qt::CaseSensitive);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, Qt::CaseSensitivity>(
+ proxyModel, Qt::CaseInsensitive, Qt::CaseSensitive, "sortCaseSensitivity");
+}
+
+void tst_QSortFilterProxyModel::isSortLocaleAwareBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.isSortLocaleAware(), false);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, bool>(proxyModel, true, false,
+ "isSortLocaleAware");
+}
+
+void tst_QSortFilterProxyModel::sortRoleBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.sortRole(), Qt::DisplayRole);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, int>(
+ proxyModel, Qt::TextAlignmentRole, Qt::ToolTipRole, "sortRole");
+}
+
+void tst_QSortFilterProxyModel::filterRoleBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.filterRole(), Qt::DisplayRole);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, int>(
+ proxyModel, Qt::DecorationRole, Qt::CheckStateRole, "filterRole");
+}
+
+void tst_QSortFilterProxyModel::recursiveFilteringEnabledBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.isRecursiveFilteringEnabled(), false);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, bool>(
+ proxyModel, true, false, "recursiveFilteringEnabled");
+}
+
+void tst_QSortFilterProxyModel::autoAcceptChildRowsBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.autoAcceptChildRows(), false);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, bool>(proxyModel, true, false,
+ "autoAcceptChildRows");
+}
+
+void tst_QSortFilterProxyModel::filterCaseSensitivityBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive);
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, Qt::CaseSensitivity>(
+ proxyModel, Qt::CaseInsensitive, Qt::CaseSensitive, "filterCaseSensitivity");
+ if (QTest::currentTestFailed())
+ return;
+
+ // Make sure that setting QRegularExpression updates filterCaseSensitivity
+ // and invalidates its binding.
+ QProperty<Qt::CaseSensitivity> setter(Qt::CaseSensitive);
+ proxyModel.bindableFilterCaseSensitivity().setBinding(Qt::makePropertyBinding(setter));
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive);
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+
+ QSignalSpy spy(&proxyModel, &QSortFilterProxyModel::filterCaseSensitivityChanged);
+ QRegularExpression regExp("pattern", QRegularExpression::CaseInsensitiveOption);
+ proxyModel.setFilterRegularExpression(regExp);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(spy.size(), 1);
+ QVERIFY(!proxyModel.bindableFilterCaseSensitivity().hasBinding());
+}
+
+void tst_QSortFilterProxyModel::filterRegularExpressionBinding()
+{
+ QSortFilterProxyModel proxyModel;
+ QCOMPARE(proxyModel.filterRegularExpression(), QRegularExpression());
+ const QRegularExpression initial("initial", QRegularExpression::CaseInsensitiveOption);
+ const QRegularExpression changed("changed");
+ QTestPrivate::testReadWritePropertyBasics<QSortFilterProxyModel, QRegularExpression>(
+ proxyModel, initial, changed, "filterRegularExpression");
+ if (QTest::currentTestFailed())
+ return;
+
+ // Make sure that setting filterCaseSensitivity updates QRegularExpression
+ // and invalidates its binding.
+ QProperty<QRegularExpression> setter(initial);
+ proxyModel.bindableFilterRegularExpression().setBinding(Qt::makePropertyBinding(setter));
+ QCOMPARE(proxyModel.filterRegularExpression(), initial);
+ QVERIFY(proxyModel.bindableFilterRegularExpression().hasBinding());
+
+ int counter = 0;
+ auto handler = proxyModel.bindableFilterRegularExpression().onValueChanged(
+ [&counter]() { ++counter; });
+ Q_UNUSED(handler);
+ proxyModel.setFilterCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(proxyModel.filterRegularExpression(), QRegularExpression(initial.pattern()));
+ QCOMPARE(counter, 1);
+ QVERIFY(!proxyModel.bindableFilterRegularExpression().hasBinding());
+
+ QProperty<Qt::CaseSensitivity> csSetter(Qt::CaseInsensitive);
+ // Make sure that setting filter string updates QRegularExpression, but does
+ // not break the binding for case sensitivity.
+ proxyModel.setFilterRegularExpression(initial);
+ proxyModel.bindableFilterCaseSensitivity().setBinding(Qt::makePropertyBinding(csSetter));
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+
+ counter = 0;
+ proxyModel.setFilterRegularExpression("ch(ang|opp)ed");
+ // The pattern has changed, but the case sensitivity options are the same.
+ QCOMPARE(proxyModel.filterRegularExpression(),
+ QRegularExpression("ch(ang|opp)ed", QRegularExpression::CaseInsensitiveOption));
+ QCOMPARE(counter, 1);
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+
+ // Make sure that setting filter wildcard updates QRegularExpression, but
+ // does not break the binding for case sensitivity.
+ proxyModel.setFilterRegularExpression(initial);
+ proxyModel.bindableFilterCaseSensitivity().setBinding(Qt::makePropertyBinding(csSetter));
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+
+ counter = 0;
+ proxyModel.setFilterWildcard("*.jpeg");
+ const QString wildcardStr = QRegularExpression::wildcardToRegularExpression(
+ "*.jpeg", QRegularExpression::UnanchoredWildcardConversion);
+ // The pattern has changed, but the case sensitivity options are the same.
+ QCOMPARE(proxyModel.filterRegularExpression(),
+ QRegularExpression(wildcardStr, QRegularExpression::CaseInsensitiveOption));
+ QCOMPARE(counter, 1);
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+
+ // Make sure that setting filter fixed string updates QRegularExpression,
+ // but does not break the binding for case sensitivity.
+ proxyModel.setFilterRegularExpression(initial);
+ proxyModel.bindableFilterCaseSensitivity().setBinding(Qt::makePropertyBinding(csSetter));
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+
+ counter = 0;
+ proxyModel.setFilterFixedString("test");
+ // The pattern has changed, but the case sensitivity options are the same.
+ QCOMPARE(proxyModel.filterRegularExpression(),
+ QRegularExpression("test", QRegularExpression::CaseInsensitiveOption));
+ QCOMPARE(counter, 1);
+ QVERIFY(proxyModel.bindableFilterCaseSensitivity().hasBinding());
+}
+
+void tst_QSortFilterProxyModel::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QStandardItemModel model(3, 1);
+ for (int row = 0; row < 3; ++row)
+ model.setData(model.index(row, 0), row, Qt::UserRole);
+ QSortFilterProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ proxy.setSortRole(Qt::UserRole);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
+ connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &proxy](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(proxy.index(row, 0));
+ });
+ connect(&proxy, &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data(Qt::UserRole).toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data(Qt::UserRole).toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data(Qt::UserRole).toInt(), 2);
+ });
+ model.setData(model.index(1, 0), -1, Qt::UserRole);
+ proxy.sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+QTEST_MAIN(tst_QSortFilterProxyModel)
+#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h
new file mode 100644
index 0000000000..088a5b552e
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.h
@@ -0,0 +1,173 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef TST_QSORTFILTERPROXYMODEL_H
+#define TST_QSORTFILTERPROXYMODEL_H
+
+#include "dynamictreemodel.h"
+#include <QLoggingCategory>
+#include <QSortFilterProxyModel>
+#include <QStandardItemModel>
+
+enum class FilterType {
+ RegExp,
+ RegularExpression
+};
+
+Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
+
+class tst_QSortFilterProxyModel : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void sort_data();
+ void sort();
+ void sortHierarchy_data();
+ void sortHierarchy();
+ void createPersistentOnLayoutAboutToBeChanged();
+
+ void insertRows_data();
+ void insertRows();
+ void prependRow();
+ void appendRowFromCombobox_data();
+ void appendRowFromCombobox();
+ void removeRows_data();
+ void removeRows();
+ void removeColumns_data();
+ void removeColumns();
+ void insertAfterSelect();
+ void removeAfterSelect();
+ void filter_data();
+ void filter();
+ void filterHierarchy_data();
+ void filterHierarchy();
+ void filterColumns_data();
+ void filterColumns();
+
+ void filterTable();
+ void filterCurrent();
+ void filter_qtbug30662();
+
+ void changeSourceLayout();
+ void changeSourceLayoutFilteredOut();
+ void removeSourceRows_data();
+ void removeSourceRows();
+ void insertSourceRows_data();
+ void insertSourceRows();
+ void changeFilter_data();
+ void changeFilter();
+ void changeSourceData_data();
+ void changeSourceData();
+ void changeSourceDataKeepsStableSorting_qtbug1548();
+ void changeSourceDataForwardsRoles_qtbug35440();
+ void changeSourceDataProxySendDataChanged_qtbug87781();
+ void changeSourceDataTreeModel();
+ void changeSourceDataProxyFilterSingleColumn();
+ void changeSourceDataProxyFilterMultipleColumns();
+ void resortingDoesNotBreakTreeModels();
+ void dynamicFilterWithoutSort();
+ void sortFilterRole();
+ void selectionFilteredOut();
+ void match_data();
+ void match();
+ void matchTree();
+ void insertIntoChildrenlessItem();
+ void invalidateMappedChildren();
+ void insertRowIntoFilteredParent();
+ void filterOutParentAndFilterInChild();
+
+ void sourceInsertRows();
+ void sourceModelDeletion();
+
+ void sortColumnTracking1();
+ void sortColumnTracking2();
+
+ void sortStable();
+
+ void hiddenColumns();
+ void insertRowsSort();
+ void staticSorting();
+ void dynamicSorting();
+ void fetchMore();
+ void hiddenChildren();
+ void mapFromToSource();
+ void removeRowsRecursive();
+ void doubleProxySelectionSetSourceModel();
+ void appearsAndSort();
+ void unnecessaryDynamicSorting();
+ void unnecessaryMapCreation();
+ void resetInvalidate_data();
+ void resetInvalidate();
+
+ void testMultipleProxiesWithSelection();
+ void mapSelectionFromSource();
+ void testResetInternalData();
+ void filteredColumns();
+ void headerDataChanged();
+
+ void testParentLayoutChanged();
+ void moveSourceRows();
+
+ void hierarchyFilterInvalidation();
+ void simpleFilterInvalidation();
+
+ void chainedProxyModelRoleNames();
+
+ void noMapAfterSourceDelete();
+ void forwardDropApi();
+ void canDropMimeData();
+ void filterHint();
+
+ void sourceLayoutChangeLeavesValidPersistentIndexes();
+ void rowMoveLeavesValidPersistentIndexes();
+
+ void emitLayoutChangedOnlyIfSortingChanged_data();
+ void emitLayoutChangedOnlyIfSortingChanged();
+
+ void checkSetNewModel();
+ void filterAndInsertRow_data();
+ void filterAndInsertRow();
+ void filterAndInsertColumn_data();
+ void filterAndInsertColumn();
+
+ void removeIntervals_data();
+ void removeIntervals();
+
+ void checkFilteredIndexes();
+ void invalidateColumnsOrRowsFilter();
+
+ void filterKeyColumnBinding();
+ void dynamicSortFilterBinding();
+ void sortCaseSensitivityBinding();
+ void isSortLocaleAwareBinding();
+ void sortRoleBinding();
+ void filterRoleBinding();
+ void recursiveFilteringEnabledBinding();
+ void autoAcceptChildRowsBinding();
+ void filterCaseSensitivityBinding();
+ void filterRegularExpressionBinding();
+
+protected:
+ void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
+ void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
+ void setupFilter(QSortFilterProxyModel *model, const QString& pattern);
+
+protected:
+ FilterType m_filterType;
+
+private:
+ QStandardItemModel *m_model = nullptr;
+ QSortFilterProxyModel *m_proxy = nullptr;
+};
+
+Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
+
+Q_DECLARE_LOGGING_CATEGORY(lcItemModels)
+
+#endif // TST_QSORTFILTERPROXYMODEL_H
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
deleted file mode 100644
index ccce5a44e5..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
+++ /dev/null
@@ -1,4991 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "tst_qsortfilterproxymodel.h"
-#include "dynamictreemodel.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtGui/QStandardItem>
-#include <QtWidgets/QComboBox>
-#include <QtWidgets/QTreeView>
-#include <QtWidgets/QTableView>
-
-#include <qdebug.h>
-
-Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels")
-
-// Testing get/set functions
-void tst_QSortFilterProxyModel::getSetCheck()
-{
- QSortFilterProxyModel obj1;
- QCOMPARE(obj1.sourceModel(), (QAbstractItemModel *)0);
- // int QSortFilterProxyModel::filterKeyColumn()
- // void QSortFilterProxyModel::setFilterKeyColumn(int)
- obj1.setFilterKeyColumn(0);
- QCOMPARE(0, obj1.filterKeyColumn());
- obj1.setFilterKeyColumn(INT_MIN);
- QCOMPARE(INT_MIN, obj1.filterKeyColumn());
- obj1.setFilterKeyColumn(INT_MAX);
- QCOMPARE(INT_MAX, obj1.filterKeyColumn());
-}
-
-tst_QSortFilterProxyModel::tst_QSortFilterProxyModel()
- : m_model(0), m_proxy(0)
-{
- qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
-}
-
-void tst_QSortFilterProxyModel::initTestCase()
-{
- qRegisterMetaType<QList<QPersistentModelIndex> >();
- m_model = new QStandardItemModel(0, 1);
- m_proxy = new QSortFilterProxyModel();
- m_proxy->setSourceModel(m_model);
-}
-
-void tst_QSortFilterProxyModel::cleanupTestCase()
-{
- delete m_proxy;
- delete m_model;
-}
-
-void tst_QSortFilterProxyModel::cleanup()
-{
- switch (m_filterType) {
- case FilterType::RegExp:
- m_proxy->setFilterRegExp(QRegExp());
- break;
- case FilterType::RegularExpression:
- m_proxy->setFilterRegularExpression(QRegularExpression());
- break;
- }
-
- m_proxy->sort(-1, Qt::AscendingOrder);
- m_model->clear();
- m_model->insertColumns(0, 1);
-}
-
-/*
- tests
-*/
-
-void tst_QSortFilterProxyModel::sort_data()
-{
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<int>("sortCaseSensitivity");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat descending") << static_cast<int>(Qt::DescendingOrder)
- << int(Qt::CaseSensitive)
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima"
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel"
- << "uniform"
- << "alpha"
- << "echo"
- << "golf"
- << "quebec"
- << "foxtrot"
- << "india"
- << "romeo"
- << "november"
- << "oskar"
- << "zulu"
- << "kilo"
- << "whiskey"
- << "mike"
- << "papa"
- << "sierra"
- << "xray"
- << "viktor")
- << (QStringList()
- << "zulu"
- << "yankee"
- << "xray"
- << "whiskey"
- << "viktor"
- << "uniform"
- << "tango"
- << "sierra"
- << "romeo"
- << "quebec"
- << "papa"
- << "oskar"
- << "november"
- << "mike"
- << "lima"
- << "kilo"
- << "juliet"
- << "india"
- << "hotel"
- << "golf"
- << "foxtrot"
- << "echo"
- << "delta"
- << "charlie"
- << "bravo"
- << "alpha");
- QTest::newRow("flat ascending") << static_cast<int>(Qt::AscendingOrder)
- << int(Qt::CaseSensitive)
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima"
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel"
- << "uniform"
- << "alpha"
- << "echo"
- << "golf"
- << "quebec"
- << "foxtrot"
- << "india"
- << "romeo"
- << "november"
- << "oskar"
- << "zulu"
- << "kilo"
- << "whiskey"
- << "mike"
- << "papa"
- << "sierra"
- << "xray"
- << "viktor")
- << (QStringList()
- << "alpha"
- << "bravo"
- << "charlie"
- << "delta"
- << "echo"
- << "foxtrot"
- << "golf"
- << "hotel"
- << "india"
- << "juliet"
- << "kilo"
- << "lima"
- << "mike"
- << "november"
- << "oskar"
- << "papa"
- << "quebec"
- << "romeo"
- << "sierra"
- << "tango"
- << "uniform"
- << "viktor"
- << "whiskey"
- << "xray"
- << "yankee"
- << "zulu");
- QTest::newRow("case insensitive") << static_cast<int>(Qt::AscendingOrder)
- << int(Qt::CaseInsensitive)
- << (QStringList()
- << "alpha" << "BETA" << "Gamma" << "delta")
- << (QStringList()
- << "alpha" << "BETA" << "delta" << "Gamma");
- QTest::newRow("case sensitive") << static_cast<int>(Qt::AscendingOrder)
- << int(Qt::CaseSensitive)
- << (QStringList()
- << "alpha" << "BETA" << "Gamma" << "delta")
- << (QStringList()
- << "BETA" << "Gamma" << "alpha" << "delta");
-
- QStringList list;
- for (int i = 10000; i < 20000; ++i)
- list.append(QStringLiteral("Number: ") + QString::number(i));
- QTest::newRow("large set ascending") << static_cast<int>(Qt::AscendingOrder) << int(Qt::CaseSensitive) << list << list;
-}
-
-void tst_QSortFilterProxyModel::sort()
-{
- QFETCH(int, sortOrder);
- QFETCH(int, sortCaseSensitivity);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
-
- // prepare model
- QStandardItem *root = m_model->invisibleRootItem ();
- QList<QStandardItem *> items;
- for (int i = 0; i < initial.count(); ++i) {
- items.append(new QStandardItem(initial.at(i)));
- }
- root->insertRows(0, items);
- QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
- QCOMPARE(m_model->columnCount(QModelIndex()), 1);
-
- // make sure the proxy is unsorted
- QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
- QCOMPARE(m_proxy->rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- // sort
- m_proxy->sort(0, static_cast<Qt::SortOrder>(sortOrder));
- m_proxy->setSortCaseSensitivity(static_cast<Qt::CaseSensitivity>(sortCaseSensitivity));
-
- // make sure the model is unchanged
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
- // make sure the proxy is sorted
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- // restore the unsorted order
- m_proxy->sort(-1);
-
- // make sure the proxy is unsorted again
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::sortHierarchy_data()
-{
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat ascending")
- << static_cast<int>(Qt::AscendingOrder)
- << (QStringList()
- << "c" << "f" << "d" << "e" << "a" << "b")
- << (QStringList()
- << "a" << "b" << "c" << "d" << "e" << "f");
-
- QTest::newRow("simple hierarchy")
- << static_cast<int>(Qt::AscendingOrder)
- << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">")
- << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">");
-
- QTest::newRow("hierarchical ascending")
- << static_cast<int>(Qt::AscendingOrder)
- << (QStringList()
- << "c"
- << "<"
- << "h"
- << "<"
- << "2"
- << "0"
- << "1"
- << ">"
- << "g"
- << "i"
- << ">"
- << "b"
- << "<"
- << "l"
- << "k"
- << "<"
- << "8"
- << "7"
- << "9"
- << ">"
- << "m"
- << ">"
- << "a"
- << "<"
- << "z"
- << "y"
- << "x"
- << ">")
- << (QStringList()
- << "a"
- << "<"
- << "x"
- << "y"
- << "z"
- << ">"
- << "b"
- << "<"
- << "k"
- << "<"
- << "7"
- << "8"
- << "9"
- << ">"
- << "l"
- << "m"
- << ">"
- << "c"
- << "<"
- << "g"
- << "h"
- << "<"
- << "0"
- << "1"
- << "2"
- << ">"
- << "i"
- << ">");
-}
-
-void tst_QSortFilterProxyModel::sortHierarchy()
-{
- QFETCH(int, sortOrder);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
-
- buildHierarchy(initial, m_model);
- checkHierarchy(initial, m_model);
- checkHierarchy(initial, m_proxy);
- m_proxy->sort(0, static_cast<Qt::SortOrder>(sortOrder));
- checkHierarchy(initial, m_model);
- checkHierarchy(expected, m_proxy);
-}
-
-void tst_QSortFilterProxyModel::insertRows_data()
-{
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
- QTest::addColumn<QStringList>("insert");
- QTest::addColumn<int>("position");
-
- QTest::newRow("insert one row in the middle")
- << (QStringList()
- << "One"
- << "Two"
- << "Four"
- << "Five")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- << "Three")
- << 2;
-
- QTest::newRow("insert one row in the beginning")
- << (QStringList()
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- << "One")
- << 0;
-
- QTest::newRow("insert one row in the end")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- <<"Five")
- << 4;
-}
-
-void tst_QSortFilterProxyModel::insertRows()
-{
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
- QFETCH(QStringList, insert);
- QFETCH(int, position);
- // prepare model
- m_model->insertRows(0, initial.count(), QModelIndex());
- //m_model->insertColumns(0, 1, QModelIndex());
- QCOMPARE(m_model->columnCount(QModelIndex()), 1);
- QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- m_model->setData(index, initial.at(row), Qt::DisplayRole);
- }
- // make sure the model correct before insert
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
- // make sure the proxy is correct before insert
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- // insert the row
- m_proxy->insertRows(position, insert.count(), QModelIndex());
- QCOMPARE(m_model->rowCount(QModelIndex()), expected.count());
- QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
-
- // set the data for the inserted row
- for (int i = 0; i < insert.count(); ++i) {
- QModelIndex index = m_proxy->index(position + i, 0, QModelIndex());
- m_proxy->setData(index, insert.at(i), Qt::DisplayRole);
- }
-
- // make sure the model correct after insert
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- // make sure the proxy is correct after insert
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::prependRow()
-{
- //this tests that data is correctly handled by the sort filter when prepending a row
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QStandardItem item("root");
- model.appendRow(&item);
-
- QStandardItem sub("sub");
- item.appendRow(&sub);
-
- sub.appendRow(new QStandardItem("test1"));
- sub.appendRow(new QStandardItem("test2"));
-
- QStandardItem sub2("sub2");
- sub2.appendRow(new QStandardItem("sub3"));
- item.insertRow(0, &sub2);
-
- QModelIndex index_sub2 = proxy.mapFromSource(model.indexFromItem(&sub2));
-
- QCOMPARE(sub2.rowCount(), proxy.rowCount(index_sub2));
- QCOMPARE(proxy.rowCount(QModelIndex()), 1); //only the "root" item is there
-}
-
-void tst_QSortFilterProxyModel::appendRowFromCombobox_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QString>("newitem");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("filter_out_second_last_item")
- << "^[0-9]*$"
- << (QStringList() << "a" << "1")
- << "2"
- << (QStringList() << "a" << "1" << "2");
-
- QTest::newRow("filter_out_everything")
- << "^c*$"
- << (QStringList() << "a" << "b")
- << "c"
- << (QStringList() << "a" << "b" << "c");
-
- QTest::newRow("no_filter")
- << ""
- << (QStringList() << "0" << "1")
- << "2"
- << (QStringList() << "0" << "1" << "2");
-
- QTest::newRow("filter_out_last_item")
- << "^[a-z]*$"
- << (QStringList() << "a" << "1")
- << "b"
- << (QStringList() << "a" << "1" << "b");
-}
-
-void tst_QSortFilterProxyModel::appendRowFromCombobox()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(QString, newitem);
- QFETCH(QStringList, expected);
-
- QStringListModel model(initial);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setFilterRegExp(pattern);
-
- QComboBox comboBox;
- comboBox.setModel(&proxy);
- comboBox.addItem(newitem);
-
- QCOMPARE(model.stringList(), expected);
-}
-
-void tst_QSortFilterProxyModel::removeRows_data()
-{
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<int>("position");
- QTest::addColumn<int>("count");
- QTest::addColumn<bool>("success");
- QTest::addColumn<QStringList>("expectedProxy");
- QTest::addColumn<QStringList>("expectedSource");
-
- QTest::newRow("remove one row in the middle [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Four"
- << "Five");
-
- QTest::newRow("remove one row in the beginning [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 0 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "Two"
- << "Three"
- << "Four"
- << "Five");
-
- QTest::newRow("remove one row in the end [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 4 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Three"
- << "Four")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Three"
- << "Four");
-
- QTest::newRow("remove all [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 0 // position
- << 5 // count
- << true // success
- << QStringList() // expectedProxy
- << QStringList(); // expectedSource
-
- QTest::newRow("remove one row past the end [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 5 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five");
-
- QTest::newRow("remove row -1 [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << -1 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five");
-
- QTest::newRow("remove three rows in the middle [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 1 // position
- << 3 // count
- << true // success
- << (QStringList() // expectedProxy
- << "One"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Five");
-
- QTest::newRow("remove one row in the middle [ascending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::AscendingOrder)
- << QString() // no filter
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "2"
- << "4");
-
- QTest::newRow("remove two rows in the middle [ascending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::AscendingOrder)
- << QString() // no filter
- << 2 // position
- << 2 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "2");
-
- QTest::newRow("remove two rows in the middle [descending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::DescendingOrder)
- << QString() // no filter
- << 2 // position
- << 2 // count
- << true // success
- << (QStringList() // expectedProxy
- << "5"
- << "4"
- << "1")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "4");
-
- QTest::newRow("remove one row in the middle [no sorting, filter=5|2|3]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << -1 // no sorting
- << QString("5|2|3")
- << 1 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "5"
- << "3")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "4"
- << "3");
-
- QTest::newRow("remove all [ascending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::AscendingOrder)
- << QString() // no filter
- << 0 // position
- << 5 // count
- << true // success
- << QStringList() // expectedProxy
- << QStringList(); // expectedSource
-}
-
-void tst_QSortFilterProxyModel::removeRows()
-{
- QFETCH(QStringList, initial);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(int, position);
- QFETCH(int, count);
- QFETCH(bool, success);
- QFETCH(QStringList, expectedProxy);
- QFETCH(QStringList, expectedSource);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- // prepare model
- foreach (QString s, initial)
- model.appendRow(new QStandardItem(s));
-
- if (sortOrder != -1)
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
-
- if (!filter.isEmpty())
- setupFilter(&proxy, filter);
-
- // remove the rows
- QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
- QCOMPARE(model.rowCount(QModelIndex()), expectedSource.count());
- QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxy.count());
-
- // make sure the model is correct after remove
- for (int row = 0; row < model.rowCount(QModelIndex()); ++row)
- QCOMPARE(model.item(row)->text(), expectedSource.at(row));
-
- // make sure the proxy is correct after remove
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedProxy.at(row));
- }
-}
-
-class MyFilteredColumnProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- MyFilteredColumnProxyModel(FilterType filterType, QObject *parent = 0) :
- QSortFilterProxyModel(parent),
- m_filterType(filterType)
- { }
-
-protected:
- bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const
- {
- QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString();
- bool result = false;
- switch (m_filterType) {
- case FilterType::RegExp:
- result = key.contains(filterRegExp());
- break;
- case FilterType::RegularExpression:
- result = key.contains(filterRegularExpression());
- break;
- }
- return result;
- }
-
-private:
- FilterType m_filterType;
-};
-
-void tst_QSortFilterProxyModel::removeColumns_data()
-{
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<int>("position");
- QTest::addColumn<int>("count");
- QTest::addColumn<bool>("success");
- QTest::addColumn<QStringList>("expectedProxy");
- QTest::addColumn<QStringList>("expectedSource");
-
- QTest::newRow("remove one column in the middle [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "4"
- << "5");
-
- QTest::newRow("remove one column in the end [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 4 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "3"
- << "4")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4");
-
- QTest::newRow("remove one column past the end [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 5 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4"
- << "5");
-
- QTest::newRow("remove column -1 [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << -1 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4"
- << "5");
-
- QTest::newRow("remove all columns [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 0 // position
- << 5 // count
- << true // success
- << QStringList() // expectedProxy
- << QStringList(); // expectedSource
-
- QTest::newRow("remove one column in the middle [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 1 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "4"
- << "5");
-
- QTest::newRow("remove one column in the end [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "3")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4");
-
- QTest::newRow("remove one column past the end [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 3 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "1"
- << "3"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4"
- << "5");
-
- QTest::newRow("remove all columns [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 0 // position
- << 3 // count
- << true // success
- << QStringList() // expectedProxy
- << (QStringList() // expectedSource
- << "2"
- << "4");
-}
-
-void tst_QSortFilterProxyModel::removeColumns()
-{
- QFETCH(QStringList, initial);
- QFETCH(QString, filter);
- QFETCH(int, position);
- QFETCH(int, count);
- QFETCH(bool, success);
- QFETCH(QStringList, expectedProxy);
- QFETCH(QStringList, expectedSource);
-
- QStandardItemModel model;
- MyFilteredColumnProxyModel proxy(m_filterType);
- proxy.setSourceModel(&model);
- if (!filter.isEmpty())
- setupFilter(&proxy, filter);
-
- // prepare model
- model.setHorizontalHeaderLabels(initial);
-
- // remove the columns
- QCOMPARE(proxy.removeColumns(position, count, QModelIndex()), success);
- QCOMPARE(model.columnCount(QModelIndex()), expectedSource.count());
- QCOMPARE(proxy.columnCount(QModelIndex()), expectedProxy.count());
-
- // make sure the model is correct after remove
- for (int col = 0; col < model.columnCount(QModelIndex()); ++col)
- QCOMPARE(model.horizontalHeaderItem(col)->text(), expectedSource.at(col));
-
- // make sure the proxy is correct after remove
- for (int col = 0; col < proxy.columnCount(QModelIndex()); ++col) {
- QCOMPARE(proxy.headerData(col, Qt::Horizontal, Qt::DisplayRole).toString(),
- expectedProxy.at(col));
- }
-}
-
-void tst_QSortFilterProxyModel::filterColumns_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<bool>("data");
-
- QTest::newRow("all") << "a"
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima")
- << true;
-
- QTest::newRow("some") << "lie"
- << (QStringList()
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel")
- << true;
-
- QTest::newRow("nothing") << "zoo"
- << (QStringList()
- << "foxtrot"
- << "uniform"
- << "alpha"
- << "golf")
- << false;
-}
-
-void tst_QSortFilterProxyModel::filterColumns()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(bool, data);
- // prepare model
- m_model->setColumnCount(initial.count());
- m_model->setRowCount(1);
- QCOMPARE(m_model->columnCount(QModelIndex()), initial.count());
- QCOMPARE(m_model->rowCount(QModelIndex()), 1);
- // set data
- QCOMPARE(m_model->rowCount(QModelIndex()), 1);
- for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
- QModelIndex index = m_model->index(0, col, QModelIndex());
- m_model->setData(index, initial.at(col), Qt::DisplayRole);
- }
- setupFilter(m_proxy, pattern);
-
- m_proxy->setFilterKeyColumn(-1);
- // make sure the model is unchanged
- for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
- QModelIndex index = m_model->index(0, col, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(col));
- }
- // make sure the proxy is filtered
- QModelIndex index = m_proxy->index(0, 0, QModelIndex());
- QCOMPARE(index.isValid(), data);
-}
-
-void tst_QSortFilterProxyModel::filter_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat") << "e"
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima"
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel"
- << "uniform"
- << "alpha"
- << "echo"
- << "golf"
- << "quebec"
- << "foxtrot"
- << "india"
- << "romeo"
- << "november"
- << "oskar"
- << "zulu"
- << "kilo"
- << "whiskey"
- << "mike"
- << "papa"
- << "sierra"
- << "xray"
- << "viktor")
- << (QStringList()
- << "delta"
- << "yankee"
- << "charlie"
- << "juliet"
- << "hotel"
- << "echo"
- << "quebec"
- << "romeo"
- << "november"
- << "whiskey"
- << "mike"
- << "sierra");
-}
-
-void tst_QSortFilterProxyModel::filter()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
-
- // prepare model
- QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex()));
- QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
- // set data
- QCOMPARE(m_model->columnCount(QModelIndex()), 1);
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- m_model->setData(index, initial.at(row), Qt::DisplayRole);
- }
- setupFilter(m_proxy, pattern);
- // make sure the proxy is unfiltered
- QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
- QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
- // make sure the model is unchanged
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
- // make sure the proxy is filtered
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::filterHierarchy_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat") << ".*oo"
- << (QStringList()
- << "foo" << "boo" << "baz" << "moo" << "laa" << "haa")
- << (QStringList()
- << "foo" << "boo" << "moo");
-
- QTest::newRow("simple hierarchy") << "b.*z"
- << (QStringList() << "baz" << "<" << "boz" << "<" << "moo" << ">" << ">")
- << (QStringList() << "baz" << "<" << "boz" << ">");
-}
-
-void tst_QSortFilterProxyModel::filterHierarchy()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
- buildHierarchy(initial, m_model);
- setupFilter(m_proxy, pattern);
- checkHierarchy(initial, m_model);
- checkHierarchy(expected, m_proxy);
-}
-
-void tst_QSortFilterProxyModel::buildHierarchy(const QStringList &l, QAbstractItemModel *m)
-{
- int ind = 0;
- int row = 0;
- QStack<int> row_stack;
- QModelIndex parent;
- QStack<QModelIndex> parent_stack;
- for (int i = 0; i < l.count(); ++i) {
- QString token = l.at(i);
- if (token == QLatin1String("<")) { // start table
- ++ind;
- parent_stack.push(parent);
- row_stack.push(row);
- parent = m->index(row - 1, 0, parent);
- row = 0;
- QVERIFY(m->insertColumns(0, 1, parent)); // add column
- } else if (token == QLatin1String(">")) { // end table
- --ind;
- parent = parent_stack.pop();
- row = row_stack.pop();
- } else { // append row
- QVERIFY(m->insertRows(row, 1, parent));
- QModelIndex index = m->index(row, 0, parent);
- QVERIFY(index.isValid());
- m->setData(index, token, Qt::DisplayRole);
- ++row;
- }
- }
-}
-
-void tst_QSortFilterProxyModel::checkHierarchy(const QStringList &l, const QAbstractItemModel *m)
-{
- int row = 0;
- int indent = 0;
- QStack<int> row_stack;
- QModelIndex parent;
- QStack<QModelIndex> parent_stack;
- for (int i = 0; i < l.count(); ++i) {
- QString token = l.at(i);
- if (token == QLatin1String("<")) { // start table
- ++indent;
- parent_stack.push(parent);
- row_stack.push(row);
- parent = m->index(row - 1, 0, parent);
- QVERIFY(parent.isValid());
- row = 0;
- } else if (token == QLatin1String(">")) { // end table
- --indent;
- parent = parent_stack.pop();
- row = row_stack.pop();
- } else { // compare row
- QModelIndex index = m->index(row, 0, parent);
- QVERIFY(index.isValid());
- QString str = m->data(index, Qt::DisplayRole).toString();
- QCOMPARE(str, token);
- ++row;
- }
- }
-}
-
-void tst_QSortFilterProxyModel::setupFilter(QSortFilterProxyModel *model, const QString& pattern)
-{
- switch (m_filterType) {
- case FilterType::RegExp:
- model->setFilterRegExp(pattern);
- break;
- case FilterType::RegularExpression:
- model->setFilterRegularExpression(pattern);
- break;
- }
-}
-
-class TestModel: public QAbstractTableModel
-{
-public:
- int rowCount(const QModelIndex &) const { return 10000; }
- int columnCount(const QModelIndex &) const { return 1; }
- QVariant data(const QModelIndex &index, int role) const
- {
- if (role != Qt::DisplayRole)
- return QVariant();
- return QString::number(index.row());
- }
-};
-
-void tst_QSortFilterProxyModel::filterTable()
-{
- TestModel model;
- QSortFilterProxyModel filter;
- filter.setSourceModel(&model);
- setupFilter(&filter, QLatin1String("9"));
-
- for (int i = 0; i < filter.rowCount(); ++i)
- QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9')));
-}
-
-void tst_QSortFilterProxyModel::insertAfterSelect()
-{
- QStandardItemModel model(10, 2);
- for (int i = 0; i<10;i++)
- model.setData(model.index(i, 0), QVariant(i));
- QSortFilterProxyModel filter;
- filter.setSourceModel(&model);
- QTreeView view;
- view.setModel(&filter);
- view.show();
- QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
- QCOMPARE(firstIndex.model(), (const QAbstractItemModel *)view.model());
- QVERIFY(firstIndex.isValid());
- int itemOffset = view.visualRect(firstIndex).width() / 2;
- QPoint p(itemOffset, 1);
- QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
- model.insertRows(5, 1, QModelIndex());
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
-}
-
-void tst_QSortFilterProxyModel::removeAfterSelect()
-{
- QStandardItemModel model(10, 2);
- for (int i = 0; i<10;i++)
- model.setData(model.index(i, 0), QVariant(i));
- QSortFilterProxyModel filter;
- filter.setSourceModel(&model);
- QTreeView view;
- view.setModel(&filter);
- view.show();
- QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
- QCOMPARE(firstIndex.model(), (const QAbstractItemModel *)view.model());
- QVERIFY(firstIndex.isValid());
- int itemOffset = view.visualRect(firstIndex).width() / 2;
- QPoint p(itemOffset, 1);
- QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
- model.removeRows(5, 1, QModelIndex());
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
-}
-
-void tst_QSortFilterProxyModel::filterCurrent()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("AAA"));
- model.setData(model.index(1, 0), QString("BBB"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- QTreeView view;
-
- view.show();
- view.setModel(&proxy);
- QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
- QVERIFY(spy.isValid());
-
- view.setCurrentIndex(proxy.index(0, 0));
- QCOMPARE(spy.count(), 1);
- setupFilter(&proxy, QLatin1String("^B"));
- QCOMPARE(spy.count(), 2);
-}
-
-void tst_QSortFilterProxyModel::filter_qtbug30662()
-{
- QStringListModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- // make sure the filter does not match any entry
- setupFilter(&proxy, QLatin1String("[0-9]+"));
-
- QStringList slSource;
- slSource << "z" << "x" << "a" << "b";
-
- proxy.setDynamicSortFilter(true);
- proxy.sort(0);
- model.setStringList(slSource);
-
- // without fix for QTBUG-30662 this will make all entries visible - but unsorted
- setupFilter(&proxy, QLatin1String("[a-z]+"));
-
- QStringList slResult;
- for (int i = 0; i < proxy.rowCount(); ++i)
- slResult.append(proxy.index(i, 0).data().toString());
-
- slSource.sort();
- QCOMPARE(slResult, slSource);
-}
-
-void tst_QSortFilterProxyModel::changeSourceLayout()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("b"));
- model.setData(model.index(1, 0), QString("a"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QList<QPersistentModelIndex> persistentSourceIndexes;
- QList<QPersistentModelIndex> persistentProxyIndexes;
- for (int row = 0; row < model.rowCount(); ++row) {
- persistentSourceIndexes.append(model.index(row, 0));
- persistentProxyIndexes.append(proxy.index(row, 0));
- }
-
- // change layout of source model
- model.sort(0, Qt::AscendingOrder);
-
- for (int row = 0; row < model.rowCount(); ++row) {
- QCOMPARE(persistentProxyIndexes.at(row).row(),
- persistentSourceIndexes.at(row).row());
- }
-}
-
-void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("b"));
- model.setData(model.index(1, 0), QString("a"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- int beforeSortFilter = proxy.rowCount();
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- // Filter everything out
- setupFilter(&proxy, QLatin1String("c"));
-
- QCOMPARE(removeSpy.count(), 1);
- QCOMPARE(0, proxy.rowCount());
-
- // change layout of source model
- model.sort(0, Qt::AscendingOrder);
-
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- // Remove filter; we expect an insert
- setupFilter(&proxy, "");
-
- QCOMPARE(insertSpy.count(), 1);
- QCOMPARE(beforeSortFilter, proxy.rowCount());
-}
-
-void tst_QSortFilterProxyModel::removeSourceRows_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("start");
- QTest::addColumn<int>("count");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
- QTest::addColumn<QStringList>("expectedProxyItems");
-
- QTest::newRow("remove one, no sorting")
- << (QStringList() << "a" << "b") // sourceItems
- << 0 // start
- << 1 // count
- << -1 // sortOrder (no sorting)
- << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b") // expectedProxyItems
- ;
- QTest::newRow("remove one, ascending sort (same order)")
- << (QStringList() << "a" << "b") // sourceItems
- << 0 // start
- << 1 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b") // expectedProxyItems
- ;
- QTest::newRow("remove one, ascending sort (reverse order)")
- << (QStringList() << "b" << "a") // sourceItems
- << 0 // start
- << 1 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(1, 1)) // expectedRemovedIntervals
- << (QStringList() << "a") // expectedProxyItems
- ;
- QTest::newRow("remove two, multiple proxy intervals")
- << (QStringList() << "c" << "d" << "a" << "b") // sourceItems
- << 1 // start
- << 2 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(3, 3) << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b" << "c") // expectedProxyItems
- ;
- QTest::newRow("remove three, multiple proxy intervals")
- << (QStringList() << "b" << "d" << "f" << "a" << "c" << "e") // sourceItems
- << 3 // start
- << 3 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(4, 4) << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b" << "d" << "f") // expectedProxyItems
- ;
- QTest::newRow("remove all, single proxy intervals")
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
- << 0 // start
- << 6 // count
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << (IntPairList() << IntPair(0, 5)) // expectedRemovedIntervals
- << QStringList() // expectedProxyItems
- ;
-}
-
-// Check that correct proxy model rows are removed when rows are removed
-// from the source model
-void tst_QSortFilterProxyModel::removeSourceRows()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, start);
- QFETCH(int, count);
- QFETCH(int, sortOrder);
- QFETCH(IntPairList, expectedRemovedProxyIntervals);
- QFETCH(QStringList, expectedProxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex sindex = model.index(i, 0, QModelIndex());
- model.setData(sindex, sourceItems.at(i), Qt::DisplayRole);
- QModelIndex pindex = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
- }
-
- if (sortOrder != -1)
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
- QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
-
- QVERIFY(removeSpy.isValid());
- QVERIFY(insertSpy.isValid());
- QVERIFY(aboutToRemoveSpy.isValid());
- QVERIFY(aboutToInsertSpy.isValid());
-
- model.removeRows(start, count, QModelIndex());
-
- QCOMPARE(aboutToRemoveSpy.count(), expectedRemovedProxyIntervals.count());
- for (int i = 0; i < aboutToRemoveSpy.count(); ++i) {
- QList<QVariant> args = aboutToRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
- }
- QCOMPARE(removeSpy.count(), expectedRemovedProxyIntervals.count());
- for (int i = 0; i < removeSpy.count(); ++i) {
- QList<QVariant> args = removeSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
- }
-
- QCOMPARE(insertSpy.count(), 0);
- QCOMPARE(aboutToInsertSpy.count(), 0);
-
- QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.count());
- for (int i = 0; i < expectedProxyItems.count(); ++i) {
- QModelIndex pindex = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::insertSourceRows_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("start");
- QTest::addColumn<QStringList>("newItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QStringList>("proxyItems");
-
- QTest::newRow("insert (1)")
- << (QStringList() << "c" << "b") // sourceItems
- << 1 // start
- << (QStringList() << "a") // newItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (QStringList() << "a" << "b" << "c") // proxyItems
- ;
-
- QTest::newRow("insert (2)")
- << (QStringList() << "d" << "b" << "c") // sourceItems
- << 3 // start
- << (QStringList() << "a") // newItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << (QStringList() << "d" << "c" << "b" << "a") // proxyItems
- ;
-}
-
-// Check that rows are inserted at correct position in proxy model when
-// rows are inserted into the source model
-void tst_QSortFilterProxyModel::insertSourceRows()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, start);
- QFETCH(QStringList, newItems);
- QFETCH(int, sortOrder);
- QFETCH(QStringList, proxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- model.insertRows(start, newItems.size(), QModelIndex());
-
- QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.count());
- for (int i = 0; i < newItems.count(); ++i) {
- QModelIndex index = model.index(start + i, 0, QModelIndex());
- model.setData(index, newItems.at(i), Qt::DisplayRole);
- }
-
- for (int i = 0; i < proxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::changeFilter_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("initialFilter");
- QTest::addColumn<IntPairList>("initialRemoveIntervals");
- QTest::addColumn<QStringList>("initialProxyItems");
- QTest::addColumn<QString>("finalFilter");
- QTest::addColumn<IntPairList>("finalRemoveIntervals");
- QTest::addColumn<IntPairList>("insertIntervals");
- QTest::addColumn<QStringList>("finalProxyItems");
-
- QTest::newRow("filter (1)")
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|b|c" // initialFilter
- << (IntPairList() << IntPair(3, 5)) // initialRemoveIntervals
- << (QStringList() << "a" << "b" << "c") // initialProxyItems
- << "b|d|f" // finalFilter
- << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // finalRemoveIntervals
- << (IntPairList() << IntPair(1, 2)) // insertIntervals
- << (QStringList() << "b" << "d" << "f") // finalProxyItems
- ;
-
- QTest::newRow("filter (2)")
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c|e" // initialFilter
- << (IntPairList() << IntPair(5, 5) << IntPair(3, 3) << IntPair(1, 1)) // initialRemoveIntervals
- << (QStringList() << "a" << "c" << "e") // initialProxyItems
- << "" // finalFilter
- << IntPairList() // finalRemoveIntervals
- << (IntPairList() << IntPair(3, 3) << IntPair(2, 2) << IntPair(1, 1)) // insertIntervals
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // finalProxyItems
- ;
-
- QTest::newRow("filter (3)")
- << (QStringList() << "a" << "b" << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a" // initialFilter
- << (IntPairList() << IntPair(1, 2)) // initialRemoveIntervals
- << (QStringList() << "a") // initialProxyItems
- << "a" // finalFilter
- << IntPairList() // finalRemoveIntervals
- << IntPairList() // insertIntervals
- << (QStringList() << "a") // finalProxyItems
- ;
-}
-
-// Check that rows are added/removed when filter changes
-void tst_QSortFilterProxyModel::changeFilter()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, initialFilter);
- QFETCH(IntPairList, initialRemoveIntervals);
- QFETCH(QStringList, initialProxyItems);
- QFETCH(QString, finalFilter);
- QFETCH(IntPairList, finalRemoveIntervals);
- QFETCH(IntPairList, insertIntervals);
- QFETCH(QStringList, finalProxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- QSignalSpy initialRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy initialInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(initialRemoveSpy.isValid());
- QVERIFY(initialInsertSpy.isValid());
-
- setupFilter(&proxy, initialFilter);
-
- QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count());
- QCOMPARE(initialInsertSpy.count(), 0);
- for (int i = 0; i < initialRemoveSpy.count(); ++i) {
- QList<QVariant> args = initialRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), initialRemoveIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), initialRemoveIntervals.at(i).second);
- }
-
- QCOMPARE(proxy.rowCount(QModelIndex()), initialProxyItems.count());
- for (int i = 0; i < initialProxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initialProxyItems.at(i));
- }
-
- QSignalSpy finalRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy finalInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(finalRemoveSpy.isValid());
- QVERIFY(finalInsertSpy.isValid());
-
- setupFilter(&proxy, finalFilter);
-
- QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count());
- for (int i = 0; i < finalRemoveSpy.count(); ++i) {
- QList<QVariant> args = finalRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), finalRemoveIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), finalRemoveIntervals.at(i).second);
- }
-
- QCOMPARE(finalInsertSpy.count(), insertIntervals.count());
- for (int i = 0; i < finalInsertSpy.count(); ++i) {
- QList<QVariant> args = finalInsertSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
- }
-
- QCOMPARE(proxy.rowCount(QModelIndex()), finalProxyItems.count());
- for (int i = 0; i < finalProxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), finalProxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::changeSourceData_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<QStringList>("expectedInitialProxyItems");
- QTest::addColumn<bool>("dynamic");
- QTest::addColumn<int>("row");
- QTest::addColumn<QString>("newValue");
- QTest::addColumn<IntPairList>("removeIntervals");
- QTest::addColumn<IntPairList>("insertIntervals");
- QTest::addColumn<int>("expectedDataChangedRow"); // -1 if no dataChanged signal expected
- QTest::addColumn<bool>("expectedLayoutChanged");
- QTest::addColumn<QStringList>("proxyItems");
-
- QTest::newRow("move_to_end_ascending")
- << (QStringList() << "c" << "b" << "a") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 2 // row
- << "z" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
- << true // layoutChanged
- << (QStringList() << "b" << "c" << "z") // proxyItems
- ;
-
- QTest::newRow("move_to_end_descending")
- << (QStringList() << "b" << "c" << "z") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "z" << "c" << "b") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "a" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
- << true // layoutChanged
- << (QStringList() << "z" << "b" << "a") // proxyItems
- ;
-
- QTest::newRow("no_op_change")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "b" << "a") // expectedInitialProxyItems
- << true // dynamic
- << 0 // row
- << "a" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "b" << "a") // proxyItems
- ;
-
- QTest::newRow("no_effect_on_filtering")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "a" << "b") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "z" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 1 // expectedDataChangedRow
- << false // layoutChanged
- << (QStringList() << "a" << "z") // proxyItems
- ;
-
- QTest::newRow("filtered_out_value_stays_out")
- << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c" // filter
- << (QStringList() << "a" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "x" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "a" << "c") // proxyItems
- ;
-
- QTest::newRow("filtered_out_now_matches")
- << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c|x" // filter
- << (QStringList() << "a" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "x" // newValue
- << IntPairList() // removeIntervals
- << (IntPairList() << IntPair(2, 2)) // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "a" << "c" << "x") // proxyItems
- ;
-
- QTest::newRow("value_is_now_filtered_out")
- << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c" // filter
- << (QStringList() << "a" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 2 // row
- << "x" // newValue
- << (IntPairList() << IntPair(1, 1)) // removeIntervals
- << IntPairList() // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "a") // proxyItems
- ;
-
- QTest::newRow("non_dynamic_filter_does_not_update_sort")
- << (QStringList() << "c" << "b" << "a") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
- << false // dynamic
- << 2 // row
- << "x" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 0 // expectedDataChangedRow
- << false // layoutChanged
- << (QStringList() << "x" << "b" << "c") // proxyItems
- ;
-}
-
-void tst_QSortFilterProxyModel::changeSourceData()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(QStringList, expectedInitialProxyItems);
- QFETCH(bool, dynamic);
- QFETCH(int, row);
- QFETCH(QString, newValue);
- QFETCH(IntPairList, removeIntervals);
- QFETCH(IntPairList, insertIntervals);
- QFETCH(int, expectedDataChangedRow);
- QFETCH(bool, expectedLayoutChanged);
- QFETCH(QStringList, proxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setDynamicSortFilter(dynamic);
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- setupFilter(&proxy, filter);
-
- QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count());
- for (int i = 0; i < expectedInitialProxyItems.count(); ++i) {
- const QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedInitialProxyItems.at(i));
- }
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- QSignalSpy dataChangedSpy(&proxy, &QSortFilterProxyModel::dataChanged);
- QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(removeSpy.isValid());
- QVERIFY(insertSpy.isValid());
- QVERIFY(dataChangedSpy.isValid());
- QVERIFY(layoutChangedSpy.isValid());
-
- {
- QModelIndex index = model.index(row, 0, QModelIndex());
- model.setData(index, newValue, Qt::DisplayRole);
- }
-
- QCOMPARE(removeSpy.count(), removeIntervals.count());
- for (int i = 0; i < removeSpy.count(); ++i) {
- QList<QVariant> args = removeSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), removeIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), removeIntervals.at(i).second);
- }
-
- QCOMPARE(insertSpy.count(), insertIntervals.count());
- for (int i = 0; i < insertSpy.count(); ++i) {
- QList<QVariant> args = insertSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
- }
-
- QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.count());
- for (int i = 0; i < proxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
- }
-
- if (expectedDataChangedRow == -1) {
- QCOMPARE(dataChangedSpy.count(), 0);
- } else {
- QCOMPARE(dataChangedSpy.count(), 1);
- const QModelIndex idx = dataChangedSpy.at(0).at(0).value<QModelIndex>();
- QCOMPARE(idx.row(), expectedDataChangedRow);
- QCOMPARE(idx.column(), 0);
- }
-
- QCOMPARE(layoutChangedSpy.count(), expectedLayoutChanged ? 1 : 0);
-}
-
-// Checks that the model is a table, and that each and every row is like this:
-// i-th row: ( rows.at(i), i )
-static void checkSortedTableModel(const QAbstractItemModel *model, const QStringList &rows)
-{
- QCOMPARE(model->rowCount(), rows.length());
- QCOMPARE(model->columnCount(), 2);
-
- for (int row = 0; row < model->rowCount(); ++row) {
- const QString column0 = model->index(row, 0).data().toString();
- const int column1 = model->index(row, 1).data().toString().toInt();
-
- QCOMPARE(column0, rows.at(row));
- QCOMPARE(column1, row);
- }
-}
-
-void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548()
-{
- // Check that emitting dataChanged from the source model
- // for a change of a role which is not the sorting role
- // doesn't alter the sorting. In this case, we sort on the DisplayRole,
- // and play with other roles.
-
- static const QStringList rows
- = QStringList() << "a" << "b" << "b" << "b" << "c" << "c" << "x";
-
- // Build a table of pairs (string, #row) in each row
- QStandardItemModel model(0, 2);
-
- for (int rowNumber = 0; rowNumber < rows.length(); ++rowNumber) {
- QStandardItem *column0 = new QStandardItem(rows.at(rowNumber));
- column0->setCheckable(true);
- column0->setCheckState(Qt::Unchecked);
-
- QStandardItem *column1 = new QStandardItem(QString::number(rowNumber));
-
- const QList<QStandardItem *> row
- = QList<QStandardItem *>() << column0 << column1;
-
- model.appendRow(row);
- }
-
- checkSortedTableModel(&model, rows);
-
- // Build the proxy model
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setDynamicSortFilter(true);
- proxy.sort(0);
-
- // The proxy is now sorted by the first column, check that the sorting
- // * is correct (the input is already sorted, so it must not have changed)
- // * was stable (by looking at the second column)
- checkSortedTableModel(&model, rows);
-
- // Change the check status of an item. That must not break the stable sorting
- // changes the middle "b"
- model.item(2)->setCheckState(Qt::Checked);
- checkSortedTableModel(&model, rows);
-
- // changes the starting "a"
- model.item(0)->setCheckState(Qt::Checked);
- checkSortedTableModel(&model, rows);
-
- // change the background color of the first "c"
- model.item(4)->setBackground(Qt::red);
- checkSortedTableModel(&model, rows);
-
- // change the background color of the second "c"
- model.item(5)->setBackground(Qt::red);
- checkSortedTableModel(&model, rows);
-}
-
-void tst_QSortFilterProxyModel::changeSourceDataForwardsRoles_qtbug35440()
-{
- QStringList strings;
- for (int i = 0; i < 100; ++i)
- strings << QString::number(i);
-
- QStringListModel model(strings);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.sort(0, Qt::AscendingOrder);
-
- QSignalSpy spy(&proxy, &QAbstractItemModel::dataChanged);
- QVERIFY(spy.isValid());
- QCOMPARE(spy.length(), 0);
-
- QModelIndex index;
-
- // QStringListModel doesn't distinguish between edit and display roles,
- // so changing one always changes the other, too.
- QVector<int> expectedChangedRoles;
- expectedChangedRoles.append(Qt::DisplayRole);
- expectedChangedRoles.append(Qt::EditRole);
-
- index = model.index(0, 0);
- QVERIFY(index.isValid());
- model.setData(index, QStringLiteral("teststring"), Qt::DisplayRole);
- QCOMPARE(spy.length(), 1);
- QCOMPARE(spy.at(0).at(2).value<QVector<int> >(), expectedChangedRoles);
-
- index = model.index(1, 0);
- QVERIFY(index.isValid());
- model.setData(index, QStringLiteral("teststring2"), Qt::EditRole);
- QCOMPARE(spy.length(), 2);
- QCOMPARE(spy.at(1).at(2).value<QVector<int> >(), expectedChangedRoles);
-}
-
-void tst_QSortFilterProxyModel::sortFilterRole()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
-
- QList<QPair<QVariant, QVariant> > sourceItems;
- sourceItems = QList<QPair<QVariant, QVariant> >()
- << QPair<QVariant, QVariant>("b", 3)
- << QPair<QVariant, QVariant>("c", 2)
- << QPair<QVariant, QVariant>("a", 1);
-
- QList<int> orderedItems;
- orderedItems = QList<int>()
- << 2 << 1;
-
- model.insertRows(0, sourceItems.count());
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i).first, Qt::DisplayRole);
- model.setData(index, sourceItems.at(i).second, Qt::UserRole);
- }
-
- setupFilter(&proxy, QLatin1String("2"));
-
- QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
-
- proxy.setFilterRole(Qt::UserRole);
- QCOMPARE(proxy.rowCount(), 1);
-
- proxy.setFilterRole(Qt::DisplayRole);
- QCOMPARE(proxy.rowCount(), 0);
-
- setupFilter(&proxy, QLatin1String("1|2|3"));
-
- QCOMPARE(proxy.rowCount(), 0);
-
- proxy.setFilterRole(Qt::UserRole);
- QCOMPARE(proxy.rowCount(), 3);
-
- proxy.sort(0, Qt::AscendingOrder);
- QCOMPARE(proxy.rowCount(), 3);
-
- proxy.setSortRole(Qt::UserRole);
- proxy.setFilterRole(Qt::DisplayRole);
- setupFilter(&proxy, QLatin1String("a|c"));
-
- QCOMPARE(proxy.rowCount(), orderedItems.count());
- for (int i = 0; i < proxy.rowCount(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole), sourceItems.at(orderedItems.at(i)).first);
- }
-}
-
-void tst_QSortFilterProxyModel::selectionFilteredOut()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("AAA"));
- model.setData(model.index(1, 0), QString("BBB"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- QTreeView view;
-
- view.show();
- view.setModel(&proxy);
- QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
- QVERIFY(spy.isValid());
-
- view.setCurrentIndex(proxy.index(0, 0));
- QCOMPARE(spy.count(), 1);
-
- setupFilter(&proxy, QLatin1String("^B"));
- QCOMPARE(spy.count(), 2);
-}
-
-void tst_QSortFilterProxyModel::match_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<int>("proxyStartRow");
- QTest::addColumn<QString>("what");
- QTest::addColumn<int>("matchFlags");
- QTest::addColumn<IntList>("expectedProxyItems");
- QTest::newRow("1")
- << (QStringList() << "a") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << 0 // proxyStartRow
- << "a" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 0); // expectedProxyItems
- QTest::newRow("2")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << 0 // proxyStartRow
- << "b" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 1); // expectedProxyItems
- QTest::newRow("3")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "" // filter
- << 0 // proxyStartRow
- << "a" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 1); // expectedProxyItems
- QTest::newRow("4")
- << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << 1 // proxyStartRow
- << "a" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << IntList(); // expectedProxyItems
- QTest::newRow("5")
- << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|b" // filter
- << 0 // proxyStartRow
- << "c" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << IntList(); // expectedProxyItems
- QTest::newRow("6")
- << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "a|b" // filter
- << 0 // proxyStartRow
- << "b" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 0); // expectedProxyItems
-}
-
-void tst_QSortFilterProxyModel::match()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(int, proxyStartRow);
- QFETCH(QString, what);
- QFETCH(int, matchFlags);
- QFETCH(IntList, expectedProxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- setupFilter(&proxy, filter);
-
- QModelIndex startIndex = proxy.index(proxyStartRow, 0);
- QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
- expectedProxyItems.count(),
- Qt::MatchFlags(matchFlags));
- QCOMPARE(indexes.count(), expectedProxyItems.count());
- for (int i = 0; i < indexes.count(); ++i)
- QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
-}
-
-QList<QStandardItem *> createStandardItemList(const QString &prefix, int n)
-{
- QList<QStandardItem *> result;
- for (int i = 0; i < n; ++i)
- result.append(new QStandardItem(prefix + QString::number(i)));
- return result;
-}
-
-// QTBUG-73864, recursive search in a tree model.
-
-void tst_QSortFilterProxyModel::matchTree()
-{
- QStandardItemModel model(0, 2);
- // Header00 Header01
- // Header10 Header11
- // Item00 Item01
- // Item10 Item11
- model.appendRow(createStandardItemList(QLatin1String("Header0"), 2));
- auto headerRow = createStandardItemList(QLatin1String("Header1"), 2);
- model.appendRow(headerRow);
- headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item0"), 2));
- headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item1"), 2));
-
- auto item11 = model.match(model.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20,
- Qt::MatchRecursive).value(0);
- QVERIFY(item11.isValid());
- QCOMPARE(item11.data().toString(), QLatin1String("Item11"));
-
- // Repeat in proxy model
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- auto proxyItem11 = proxy.match(proxy.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20,
- Qt::MatchRecursive).value(0);
- QVERIFY(proxyItem11.isValid());
- QCOMPARE(proxyItem11.data().toString(), QLatin1String("Item11"));
-
- QCOMPARE(proxy.mapToSource(proxyItem11).internalId(), item11.internalId());
-}
-
-void tst_QSortFilterProxyModel::insertIntoChildrenlessItem()
-{
- QStandardItemModel model;
- QStandardItem *itemA = new QStandardItem("a");
- model.appendRow(itemA);
- QStandardItem *itemB = new QStandardItem("b");
- model.appendRow(itemB);
- QStandardItem *itemC = new QStandardItem("c");
- model.appendRow(itemC);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QSignalSpy colsInsertedSpy(&proxy, &QSortFilterProxyModel::columnsInserted);
- QSignalSpy rowsInsertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(colsInsertedSpy.isValid());
- QVERIFY(rowsInsertedSpy.isValid());
-
- (void)proxy.rowCount(QModelIndex()); // force mapping of "a", "b", "c"
- QCOMPARE(colsInsertedSpy.count(), 0);
- QCOMPARE(rowsInsertedSpy.count(), 0);
-
- // now add a child to itemB ==> should get insert notification from the proxy
- itemB->appendRow(new QStandardItem("a.0"));
- QCOMPARE(colsInsertedSpy.count(), 1);
- QCOMPARE(rowsInsertedSpy.count(), 1);
-
- QVariantList args = colsInsertedSpy.takeFirst();
- QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
- QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
- QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
-
- args = rowsInsertedSpy.takeFirst();
- QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
- QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
- QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
-}
-
-void tst_QSortFilterProxyModel::invalidateMappedChildren()
-{
- QStandardItemModel model;
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QStandardItem *itemA = new QStandardItem("a");
- model.appendRow(itemA);
- QStandardItem *itemB = new QStandardItem("b");
- itemA->appendRow(itemB);
-
- QStandardItem *itemC = new QStandardItem("c");
- itemB->appendRow(itemC);
- itemC->appendRow(new QStandardItem("d"));
-
- // force mappings
- (void)proxy.hasChildren(QModelIndex());
- (void)proxy.hasChildren(proxy.mapFromSource(itemA->index()));
- (void)proxy.hasChildren(proxy.mapFromSource(itemB->index()));
- (void)proxy.hasChildren(proxy.mapFromSource(itemC->index()));
-
- itemB->removeRow(0); // should invalidate mapping of itemC
- itemC = new QStandardItem("c");
- itemA->appendRow(itemC);
- itemC->appendRow(new QStandardItem("d"));
-
- itemA->removeRow(1); // should invalidate mapping of itemC
- itemC = new QStandardItem("c");
- itemB->appendRow(itemC);
- itemC->appendRow(new QStandardItem("d"));
-
- QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemA->index())), 1);
- QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemB->index())), 1);
- QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemC->index())), 1);
-}
-
-class EvenOddFilterModel : public QSortFilterProxyModel
-{
-public:
- virtual bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const
- {
- if (srcParent.isValid())
- return (srcParent.row() % 2) ^ !(srcRow % 2);
- return (srcRow % 2);
- }
-};
-
-void tst_QSortFilterProxyModel::insertRowIntoFilteredParent()
-{
- QStandardItemModel model;
- EvenOddFilterModel proxy;
- proxy.setSourceModel(&model);
-
- QSignalSpy spy(&proxy, &EvenOddFilterModel::rowsInserted);
- QVERIFY(spy.isValid());
-
- QStandardItem *itemA = new QStandardItem();
- model.appendRow(itemA); // A will be filtered
- QStandardItem *itemB = new QStandardItem();
- itemA->appendRow(itemB);
-
- QCOMPARE(spy.count(), 0);
-
- itemA->removeRow(0);
-
- QCOMPARE(spy.count(), 0);
-}
-
-void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- setupFilter(&proxy, QLatin1String("A|B"));
-
- QStandardItem *itemA = new QStandardItem("A");
- model.appendRow(itemA); // not filtered
- QStandardItem *itemB = new QStandardItem("B");
- itemA->appendRow(itemB); // not filtered
- QStandardItem *itemC = new QStandardItem("C");
- itemA->appendRow(itemC); // filtered
-
- QSignalSpy removedSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(removedSpy.isValid());
- QVERIFY(insertedSpy.isValid());
-
- setupFilter(&proxy, QLatin1String("C")); // A and B will be filtered out, C filtered in
-
- // we should now have been notified that the subtree represented by itemA has been removed
- QCOMPARE(removedSpy.count(), 1);
- // we should NOT get any inserts; itemC should be filtered because its parent (itemA) is
- QCOMPARE(insertedSpy.count(), 0);
-}
-
-void tst_QSortFilterProxyModel::sourceInsertRows()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxyModel;
- proxyModel.setSourceModel(&model);
-
- model.insertColumns(0, 1, QModelIndex());
- model.insertRows(0, 2, QModelIndex());
-
- {
- QModelIndex parent = model.index(0, 0, QModelIndex());
- model.insertColumns(0, 1, parent);
- model.insertRows(0, 1, parent);
- }
-
- {
- QModelIndex parent = model.index(1, 0, QModelIndex());
- model.insertColumns(0, 1, parent);
- model.insertRows(0, 1, parent);
- }
-
- model.insertRows(0, 1, QModelIndex());
- model.insertRows(0, 1, QModelIndex());
-
- QVERIFY(true); // if you got here without asserting, it's all good
-}
-
-void tst_QSortFilterProxyModel::sourceModelDeletion()
-{
- QSortFilterProxyModel proxyModel;
- {
- QStandardItemModel model;
- proxyModel.setSourceModel(&model);
- QCOMPARE(proxyModel.sourceModel(), static_cast<QAbstractItemModel*>(&model));
- }
- QCOMPARE(proxyModel.sourceModel(), static_cast<QAbstractItemModel*>(0));
-}
-
-void tst_QSortFilterProxyModel::sortColumnTracking1()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxyModel;
- proxyModel.setSourceModel(&model);
-
- model.insertColumns(0, 10);
- model.insertRows(0, 10);
-
- proxyModel.sort(1);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.insertColumn(8);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.removeColumn(8);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.insertColumn(2);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.removeColumn(2);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.insertColumn(1);
- QCOMPARE(proxyModel.sortColumn(), 2);
-
- model.removeColumn(1);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.removeColumn(1);
- QCOMPARE(proxyModel.sortColumn(), -1);
-}
-
-void tst_QSortFilterProxyModel::sortColumnTracking2()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxyModel;
- proxyModel.setDynamicSortFilter(true);
- proxyModel.setSourceModel(&model);
-
- proxyModel.sort(0);
- QCOMPARE(proxyModel.sortColumn(), 0);
-
- QList<QStandardItem *> items; // Stable sorting: Items with invalid data should move to the end
- items << new QStandardItem << new QStandardItem("foo") << new QStandardItem("bar")
- << new QStandardItem("some") << new QStandardItem("others") << new QStandardItem("item")
- << new QStandardItem("aa") << new QStandardItem("zz") << new QStandardItem;
-
- model.insertColumn(0,items);
- QCOMPARE(proxyModel.sortColumn(), 0);
- QCOMPARE(proxyModel.data(proxyModel.index(0,0)).toString(),QString::fromLatin1("aa"));
- const int zzIndex = items.count() - 3; // 2 invalid at end.
- QCOMPARE(proxyModel.data(proxyModel.index(zzIndex,0)).toString(),QString::fromLatin1("zz"));
-}
-
-void tst_QSortFilterProxyModel::sortStable()
-{
- QStandardItemModel* model = new QStandardItemModel(5, 2);
- for (int r = 0; r < 5; r++) {
- const QString prefix = QLatin1String("Row:") + QString::number(r) + QLatin1String(", Column:");
- for (int c = 0; c < 2; c++) {
- QStandardItem* item = new QStandardItem(prefix + QString::number(c));
- for (int i = 0; i < 3; i++) {
- QStandardItem* child = new QStandardItem(QLatin1String("Item ") + QString::number(i));
- item->appendRow( child );
- }
- model->setItem(r, c, item);
- }
- }
- model->setHorizontalHeaderItem( 0, new QStandardItem( "Name" ));
- model->setHorizontalHeaderItem( 1, new QStandardItem( "Value" ));
-
- QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(model);
- filterModel->setSourceModel(model);
-
- QTreeView *view = new QTreeView;
- view->setModel(filterModel);
- QModelIndex firstRoot = filterModel->index(0,0);
- view->expand(firstRoot);
- view->setSortingEnabled(true);
-
- view->model()->sort(1, Qt::DescendingOrder);
- QVariant lastItemData =filterModel->index(2,0, firstRoot).data();
- view->model()->sort(1, Qt::DescendingOrder);
- QCOMPARE(lastItemData, filterModel->index(2,0, firstRoot).data());
-}
-
-void tst_QSortFilterProxyModel::hiddenColumns()
-{
- class MyStandardItemModel : public QStandardItemModel
- {
- public:
- MyStandardItemModel() : QStandardItemModel(0,5) {}
- void reset()
- { beginResetModel(); endResetModel(); }
- friend class tst_QSortFilterProxyModel;
- } model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QTableView view;
- view.setModel(&proxy);
-
- view.hideColumn(0);
-
- QVERIFY(view.isColumnHidden(0));
- model.blockSignals(true);
- model.setRowCount(1);
- model.blockSignals(false);
- model.reset();
-
- // In the initial bug report that spawned this test, this would be false
- // because resetting model would also reset the hidden columns.
- QVERIFY(view.isColumnHidden(0));
-}
-
-void tst_QSortFilterProxyModel::insertRowsSort()
-{
- QStandardItemModel model(2,2);
- QSortFilterProxyModel proxyModel;
- proxyModel.setSourceModel(&model);
-
- proxyModel.sort(0);
- QCOMPARE(proxyModel.sortColumn(), 0);
-
- model.insertColumns(0, 3, model.index(0,0));
- QCOMPARE(proxyModel.sortColumn(), 0);
-
- model.removeColumns(0, 3, model.index(0,0));
- QCOMPARE(proxyModel.sortColumn(), 0);
-}
-
-void tst_QSortFilterProxyModel::staticSorting()
-{
- QStandardItemModel model(0, 1);
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setDynamicSortFilter(false);
- QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
-
- // prepare model
- QStandardItem *root = model.invisibleRootItem ();
- QList<QStandardItem *> items;
- for (int i = 0; i < initial.count(); ++i) {
- items.append(new QStandardItem(initial.at(i)));
- }
- root->insertRows(0, items);
- QCOMPARE(model.rowCount(QModelIndex()), initial.count());
- QCOMPARE(model.columnCount(QModelIndex()), 1);
-
- // make sure the proxy is unsorted
- QCOMPARE(proxy.columnCount(QModelIndex()), 1);
- QCOMPARE(proxy.rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- // sort
- proxy.sort(0);
-
- QStringList expected = initial;
- expected.sort();
- // make sure the proxy is sorted
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- //update one item.
- items.first()->setData("girafe", Qt::DisplayRole);
-
- // make sure the proxy is updated but not sorted
- expected.replaceInStrings("bateau", "girafe");
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- // sort again
- proxy.sort(0);
- expected.sort();
-
- // make sure the proxy is sorted
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::dynamicSorting()
-{
- QStringListModel model1;
- const QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
- model1.setStringList(initial);
- QSortFilterProxyModel proxy1;
- proxy1.setDynamicSortFilter(false);
- proxy1.sort(0);
- proxy1.setSourceModel(&model1);
-
- QCOMPARE(proxy1.columnCount(QModelIndex()), 1);
- //the model should not be sorted because sorting has not been set to dynamic yet.
- QCOMPARE(proxy1.rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- proxy1.setDynamicSortFilter(true);
-
- //now the model should be sorted.
- QStringList expected = initial;
- expected.sort();
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- QStringList initial2 = initial;
- initial2.replaceInStrings("bateau", "girafe");
- model1.setStringList(initial2); //this will cause a reset
-
- QStringList expected2 = initial2;
- expected2.sort();
-
- //now the model should still be sorted.
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected2.at(row));
- }
-
- QStringListModel model2(initial);
- proxy1.setSourceModel(&model2);
-
- //the model should again be sorted
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- //set up the sorting before seting the model up
- QSortFilterProxyModel proxy2;
- proxy2.sort(0);
- proxy2.setSourceModel(&model2);
- for (int row = 0; row < proxy2.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy2.index(row, 0, QModelIndex());
- QCOMPARE(proxy2.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-class QtTestModel: public QAbstractItemModel
-{
-public:
- QtTestModel(int _rows, int _cols, QObject *parent = 0)
- : QAbstractItemModel(parent)
- , rows(_rows)
- , cols(_cols)
- , wrongIndex(false)
- {
- }
-
- bool canFetchMore(const QModelIndex &idx) const
- {
- return !fetched.contains(idx);
- }
-
- void fetchMore(const QModelIndex &idx)
- {
- if (fetched.contains(idx))
- return;
- beginInsertRows(idx, 0, rows-1);
- fetched.insert(idx);
- endInsertRows();
- }
-
- bool hasChildren(const QModelIndex & = QModelIndex()) const
- {
- return true;
- }
-
- int rowCount(const QModelIndex& parent = QModelIndex()) const
- {
- return fetched.contains(parent) ? rows : 0;
- }
-
- int columnCount(const QModelIndex& parent = QModelIndex()) const
- {
- Q_UNUSED(parent);
- return cols;
- }
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
- {
- if (row < 0 || column < 0 || column >= cols || row >= rows) {
- return QModelIndex();
- }
- QModelIndex i = createIndex(row, column, int(parent.internalId() + 1));
- parentHash[i] = parent;
- return i;
- }
-
- QModelIndex parent(const QModelIndex &index) const
- {
- if (!parentHash.contains(index))
- return QModelIndex();
- return parentHash[index];
- }
-
- QVariant data(const QModelIndex &idx, int role) const
- {
- if (!idx.isValid())
- return QVariant();
-
- if (role == Qt::DisplayRole) {
- if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
- wrongIndex = true;
- qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(),
- idx.internalPointer());
- }
- return QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',')
- + QString::number(idx.column()) + QLatin1Char(']');
- }
- return QVariant();
- }
-
- QSet<QModelIndex> fetched;
- int rows, cols;
- mutable bool wrongIndex;
- mutable QMap<QModelIndex,QModelIndex> parentHash;
-};
-
-void tst_QSortFilterProxyModel::fetchMore()
-{
- QtTestModel model(10,10);
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- QVERIFY(proxy.canFetchMore(QModelIndex()));
- QVERIFY(proxy.hasChildren());
- while (proxy.canFetchMore(QModelIndex()))
- proxy.fetchMore(QModelIndex());
- QCOMPARE(proxy.rowCount(), 10);
- QCOMPARE(proxy.columnCount(), 10);
-
- QModelIndex idx = proxy.index(1,1);
- QVERIFY(idx.isValid());
- QVERIFY(proxy.canFetchMore(idx));
- QVERIFY(proxy.hasChildren(idx));
- while (proxy.canFetchMore(idx))
- proxy.fetchMore(idx);
- QCOMPARE(proxy.rowCount(idx), 10);
- QCOMPARE(proxy.columnCount(idx), 10);
-}
-
-void tst_QSortFilterProxyModel::hiddenChildren()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setDynamicSortFilter(true);
-
- QStandardItem *itemA = new QStandardItem("A VISIBLE");
- model.appendRow(itemA);
- QStandardItem *itemB = new QStandardItem("B VISIBLE");
- itemA->appendRow(itemB);
- QStandardItem *itemC = new QStandardItem("C");
- itemA->appendRow(itemC);
- setupFilter(&proxy, QLatin1String("VISIBLE"));
-
- QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
- QPersistentModelIndex indexA = proxy.index(0,0);
- QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
-
- QCOMPARE(proxy.rowCount(indexA) , 1);
- QPersistentModelIndex indexB = proxy.index(0, 0, indexA);
- QCOMPARE(proxy.data(indexB).toString(), QString::fromLatin1("B VISIBLE"));
-
- itemA->setText("A");
- QCOMPARE(proxy.rowCount(QModelIndex()), 0);
- QVERIFY(!indexA.isValid());
- QVERIFY(!indexB.isValid());
-
- itemB->setText("B");
- itemA->setText("A VISIBLE");
- itemC->setText("C VISIBLE");
-
- QCOMPARE(proxy.rowCount(QModelIndex()), 1);
- indexA = proxy.index(0,0);
- QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
-
- QCOMPARE(proxy.rowCount(indexA) , 1);
- QModelIndex indexC = proxy.index(0, 0, indexA);
- QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
-
- setupFilter(&proxy, QLatin1String("C"));
-
- QCOMPARE(proxy.rowCount(QModelIndex()), 0);
- itemC->setText("invisible");
- itemA->setText("AC");
-
- QCOMPARE(proxy.rowCount(QModelIndex()), 1);
- indexA = proxy.index(0,0);
- QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("AC"));
- QCOMPARE(proxy.rowCount(indexA) , 0);
-}
-
-void tst_QSortFilterProxyModel::mapFromToSource()
-{
- QtTestModel source(10,10);
- source.fetchMore(QModelIndex());
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&source);
- QCOMPARE(proxy.mapFromSource(source.index(5, 4)), proxy.index(5, 4));
- QCOMPARE(proxy.mapToSource(proxy.index(3, 2)), source.index(3, 2));
- QCOMPARE(proxy.mapFromSource(QModelIndex()), QModelIndex());
- QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex());
-
-#ifdef QT_NO_DEBUG //if Qt is compiled in debug mode, this will assert
- QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource");
- QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex());
- QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource");
- QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex());
-#endif
-}
-
-static QStandardItem *addEntry(QStandardItem* pParent, const QString &description)
-{
- QStandardItem* pItem = new QStandardItem(description);
- pParent->appendRow(pItem);
- return pItem;
-}
-
-void tst_QSortFilterProxyModel::removeRowsRecursive()
-{
- QStandardItemModel pModel;
- QStandardItem *pItem1 = new QStandardItem("root");
- pModel.appendRow(pItem1);
- QList<QStandardItem *> items;
-
- QStandardItem *pItem11 = addEntry(pItem1,"Sub-heading");
- items << pItem11;
- QStandardItem *pItem111 = addEntry(pItem11,"A");
- items << pItem111;
- items << addEntry(pItem111,"A1");
- items << addEntry(pItem111,"A2");
- QStandardItem *pItem112 = addEntry(pItem11,"B");
- items << pItem112;
- items << addEntry(pItem112,"B1");
- items << addEntry(pItem112,"B2");
- QStandardItem *pItem1123 = addEntry(pItem112,"B3");
- items << pItem1123;
- items << addEntry(pItem1123,"B3-");
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&pModel);
-
- QList<QPersistentModelIndex> sourceIndexes;
- QList<QPersistentModelIndex> proxyIndexes;
- foreach (QStandardItem *item, items) {
- QModelIndex idx = item->index();
- sourceIndexes << idx;
- proxyIndexes << proxy.mapFromSource(idx);
- }
-
- foreach (const QPersistentModelIndex &pidx, sourceIndexes)
- QVERIFY(pidx.isValid());
- foreach (const QPersistentModelIndex &pidx, proxyIndexes)
- QVERIFY(pidx.isValid());
-
- QList<QStandardItem*> itemRow = pItem1->takeRow(0);
-
- QCOMPARE(itemRow.count(), 1);
- QCOMPARE(itemRow.first(), pItem11);
-
- foreach (const QPersistentModelIndex &pidx, sourceIndexes)
- QVERIFY(!pidx.isValid());
- foreach (const QPersistentModelIndex &pidx, proxyIndexes)
- QVERIFY(!pidx.isValid());
-
- delete pItem11;
-}
-
-void tst_QSortFilterProxyModel::doubleProxySelectionSetSourceModel()
-{
- QStandardItemModel *model1 = new QStandardItemModel;
- QStandardItem *parentItem = model1->invisibleRootItem();
- for (int i = 0; i < 4; ++i) {
- QStandardItem *item = new QStandardItem(QLatin1String("model1 item ") + QString::number(i));
- parentItem->appendRow(item);
- parentItem = item;
- }
-
- QStandardItemModel *model2 = new QStandardItemModel;
- QStandardItem *parentItem2 = model2->invisibleRootItem();
- for (int i = 0; i < 4; ++i) {
- QStandardItem *item = new QStandardItem(QLatin1String("model2 item ") + QString::number(i));
- parentItem2->appendRow(item);
- parentItem2 = item;
- }
-
- QSortFilterProxyModel *toggleProxy = new QSortFilterProxyModel;
- toggleProxy->setSourceModel(model1);
-
- QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel;
- proxyModel->setSourceModel(toggleProxy);
-
- QModelIndex mi = proxyModel->index(0, 0, proxyModel->index(0, 0, proxyModel->index(0, 0)));
- QItemSelectionModel ism(proxyModel);
- ism.select(mi, QItemSelectionModel::Select);
- QModelIndexList mil = ism.selectedIndexes();
- QCOMPARE(mil.count(), 1);
- QCOMPARE(mil.first(), mi);
-
- toggleProxy->setSourceModel(model2);
- // No crash, it's good news!
- QVERIFY(ism.selection().isEmpty());
-}
-
-void tst_QSortFilterProxyModel::appearsAndSort()
-{
- class PModel : public QSortFilterProxyModel
- {
- public:
- PModel() : mVisible(false) {};
- protected:
- bool filterAcceptsRow(int, const QModelIndex &) const
- {
- return mVisible;
- }
-
- public:
- void updateXX()
- {
- mVisible = true;
- invalidate();
- }
- private:
- bool mVisible;
- } proxyModel;
-
- QStringListModel sourceModel;
- QStringList list;
- list << "b" << "a" << "c";
- sourceModel.setStringList(list);
-
- proxyModel.setSourceModel(&sourceModel);
- proxyModel.setDynamicSortFilter(true);
- proxyModel.sort(0, Qt::AscendingOrder);
-
- QApplication::processEvents();
- QCOMPARE(sourceModel.rowCount(), 3);
- QCOMPARE(proxyModel.rowCount(), 0); //all rows are hidden at first;
-
- QSignalSpy spyAbout1(&proxyModel, &PModel::layoutAboutToBeChanged);
- QSignalSpy spyChanged1(&proxyModel, &PModel::layoutChanged);
-
- QVERIFY(spyAbout1.isValid());
- QVERIFY(spyChanged1.isValid());
-
- //introducing secondProxyModel to test the layoutChange when many items appears at once
- QSortFilterProxyModel secondProxyModel;
- secondProxyModel.setSourceModel(&proxyModel);
- secondProxyModel.setDynamicSortFilter(true);
- secondProxyModel.sort(0, Qt::DescendingOrder);
- QCOMPARE(secondProxyModel.rowCount(), 0); //all rows are hidden at first;
- QSignalSpy spyAbout2(&secondProxyModel, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy spyChanged2(&secondProxyModel, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(spyAbout2.isValid());
- QVERIFY(spyChanged2.isValid());
-
- proxyModel.updateXX();
- QApplication::processEvents();
- //now rows should be visible, and sorted
- QCOMPARE(proxyModel.rowCount(), 3);
- QCOMPARE(proxyModel.data(proxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
- QCOMPARE(proxyModel.data(proxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
- QCOMPARE(proxyModel.data(proxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
-
- //now rows should be visible, and sorted
- QCOMPARE(secondProxyModel.rowCount(), 3);
- QCOMPARE(secondProxyModel.data(secondProxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
- QCOMPARE(secondProxyModel.data(secondProxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
- QCOMPARE(secondProxyModel.data(secondProxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
-
- QCOMPARE(spyAbout1.count(), 1);
- QCOMPARE(spyChanged1.count(), 1);
- QCOMPARE(spyAbout2.count(), 1);
- QCOMPARE(spyChanged2.count(), 1);
-}
-
-void tst_QSortFilterProxyModel::unnecessaryDynamicSorting()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(false);
- proxy.setSourceModel(&model);
- proxy.sort(Qt::AscendingOrder);
-
- //append two rows
- int maxrows = proxy.rowCount(QModelIndex());
- model.insertRows(maxrows, 2);
- model.setData(model.index(maxrows, 0), QString("alpha"));
- model.setData(model.index(maxrows + 1, 0), QString("fondue"));
-
- //append new items to the initial string list and compare with model
- QStringList expected = initial;
- expected << QString("alpha") << QString("fondue");
-
- //if bug 7716 is present, new rows were prepended, when they should have been appended
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-class SelectionProxyModel : QAbstractProxyModel
-{
- Q_OBJECT
-public:
- SelectionProxyModel()
- : QAbstractProxyModel(), selectionModel(0)
- {
- }
-
- QModelIndex mapFromSource(QModelIndex const&) const
- { return QModelIndex(); }
-
- QModelIndex mapToSource(QModelIndex const&) const
- { return QModelIndex(); }
-
- QModelIndex index(int, int, const QModelIndex&) const
- { return QModelIndex(); }
-
- QModelIndex parent(const QModelIndex&) const
- { return QModelIndex(); }
-
- int rowCount(const QModelIndex&) const
- { return 0; }
-
- int columnCount(const QModelIndex&) const
- { return 0; }
-
- void setSourceModel( QAbstractItemModel *sourceModel )
- {
- beginResetModel();
- disconnect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
- QAbstractProxyModel::setSourceModel( sourceModel );
- connect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
- endResetModel();
- }
-
- void setSelectionModel( QItemSelectionModel *_selectionModel )
- {
- selectionModel = _selectionModel;
- }
-
-private slots:
- void sourceModelAboutToBeReset()
- {
- QVERIFY( selectionModel->selectedIndexes().size() == 1 );
- beginResetModel();
- }
-
- void sourceModelReset()
- {
- endResetModel();
- }
-
-private:
- QItemSelectionModel *selectionModel;
-};
-
-void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel( &model );
-
- SelectionProxyModel proxy1;
- QSortFilterProxyModel proxy2;
-
- // Note that the order here matters. The order of the sourceAboutToBeReset
- // exposes the bug in QSortFilterProxyModel.
- proxy2.setSourceModel( &proxy );
- proxy1.setSourceModel( &proxy );
-
- QItemSelectionModel selectionModel(&proxy2);
- proxy1.setSelectionModel( &selectionModel );
-
- selectionModel.select( proxy2.index( 0, 0 ), QItemSelectionModel::Select );
-
- // trick the proxy into emitting begin/end reset signals.
- proxy.setSourceModel(0);
-}
-
-static bool isValid(const QItemSelection &selection)
-{
- foreach (const QItemSelectionRange &range, selection)
- if (!range.isValid())
- return false;
- return true;
-}
-
-void tst_QSortFilterProxyModel::mapSelectionFromSource()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
-
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- setupFilter(&proxy, QLatin1String("d.*"));
-
- proxy.setSourceModel(&model);
-
- // Only "delta" remains.
- QCOMPARE(proxy.rowCount(), 1);
-
- QItemSelection selection;
- QModelIndex charlie = model.index(1, 0);
- selection.append(QItemSelectionRange(charlie, charlie));
- QModelIndex delta = model.index(2, 0);
- selection.append(QItemSelectionRange(delta, delta));
- QModelIndex echo = model.index(3, 0);
- selection.append(QItemSelectionRange(echo, echo));
-
- QVERIFY(isValid(selection));
-
- QItemSelection proxiedSelection = proxy.mapSelectionFromSource(selection);
-
- // Only "delta" is in the mapped result.
- QCOMPARE(proxiedSelection.size(), 1);
- QVERIFY(isValid(proxiedSelection));
-}
-
-class Model10287 : public QStandardItemModel
-{
- Q_OBJECT
-
-public:
- Model10287(QObject *parent = 0)
- : QStandardItemModel(0, 1, parent)
- {
- parentItem = new QStandardItem("parent");
- parentItem->setData(false, Qt::UserRole);
- appendRow(parentItem);
-
- childItem = new QStandardItem("child");
- childItem->setData(true, Qt::UserRole);
- parentItem->appendRow(childItem);
-
- childItem2 = new QStandardItem("child2");
- childItem2->setData(true, Qt::UserRole);
- parentItem->appendRow(childItem2);
- }
-
- void removeChild()
- {
- childItem2->setData(false, Qt::UserRole);
- parentItem->removeRow(0);
- }
-
-private:
- QStandardItem *parentItem, *childItem, *childItem2;
-};
-
-class Proxy10287 : public QSortFilterProxyModel
-{
- Q_OBJECT
-
-public:
- Proxy10287(QAbstractItemModel *model, QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
- setSourceModel(model);
- setDynamicSortFilter(true);
- }
-
-protected:
- virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
- {
- // Filter based on UserRole in model
- QModelIndex i = sourceModel()->index(source_row, 0, source_parent);
- return i.data(Qt::UserRole).toBool();
- }
-};
-
-void tst_QSortFilterProxyModel::unnecessaryMapCreation()
-{
- Model10287 m;
- Proxy10287 p(&m);
- m.removeChild();
- // No assert failure, it passes.
-}
-
-class FilteredColumnProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilteredColumnProxyModel(QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
- }
-
-protected:
- bool filterAcceptsColumn(int column, const QModelIndex & /* source_parent */) const
- {
- return column % 2 != 0;
- }
-};
-
-void tst_QSortFilterProxyModel::filteredColumns()
-{
- DynamicTreeModel *model = new DynamicTreeModel(this);
-
- FilteredColumnProxyModel *proxy = new FilteredColumnProxyModel(this);
- proxy->setSourceModel(model);
-
- new QAbstractItemModelTester(proxy, this);
-
- ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
- insertCommand->setNumCols(2);
- insertCommand->setStartRow(0);
- insertCommand->setEndRow(0);
- // Parent is QModelIndex()
- insertCommand->doCommand();
-}
-
-class ChangableHeaderData : public QStringListModel
-{
- Q_OBJECT
-public:
- explicit ChangableHeaderData(QObject *parent = 0)
- : QStringListModel(parent)
- {
-
- }
-
- void emitHeaderDataChanged()
- {
- headerDataChanged(Qt::Vertical, 0, rowCount() - 1);
- }
-};
-
-
-void tst_QSortFilterProxyModel::headerDataChanged()
-{
- ChangableHeaderData *model = new ChangableHeaderData(this);
-
- QStringList numbers;
- for (int i = 0; i < 10; ++i)
- numbers.append(QString::number(i));
- model->setStringList(numbers);
-
- QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
- proxy->setSourceModel(model);
-
- new QAbstractItemModelTester(proxy, this);
-
- model->emitHeaderDataChanged();
-}
-
-void tst_QSortFilterProxyModel::resetInvalidate_data()
-{
- QTest::addColumn<int>("test");
- QTest::addColumn<bool>("works");
-
- QTest::newRow("nothing") << 0 << false;
- QTest::newRow("reset") << 1 << true;
- QTest::newRow("invalidate") << 2 << true;
- QTest::newRow("invalidate_filter") << 3 << true;
-}
-
-void tst_QSortFilterProxyModel::resetInvalidate()
-{
- QFETCH(int, test);
- QFETCH(bool, works);
-
- struct Proxy : QSortFilterProxyModel {
- QString pattern;
- virtual bool filterAcceptsRow(int source_row, const QModelIndex&) const
- {
- return sourceModel()->data(sourceModel()->index(source_row, 0)).toString().contains(pattern);
- }
- void notifyChange(int test)
- {
- switch (test) {
- case 0: break;
- case 1:
- beginResetModel();
- endResetModel();
- break;
- case 2: invalidate(); break;
- case 3: invalidateFilter(); break;
- }
- }
- };
-
- QStringListModel sourceModel(QStringList() << "Poisson" << "Vache" << "Brebis"
- << "Elephant" << "Cochon" << "Serpent"
- << "Mouton" << "Ecureuil" << "Mouche");
- Proxy proxy;
- proxy.pattern = QString::fromLatin1("n");
- proxy.setSourceModel(&sourceModel);
-
- QCOMPARE(proxy.rowCount(), 5);
- for (int i = 0; i < proxy.rowCount(); i++) {
- QVERIFY(proxy.data(proxy.index(i,0)).toString().contains('n'));
- }
-
- proxy.pattern = QString::fromLatin1("o");
- proxy.notifyChange(test);
-
- QCOMPARE(proxy.rowCount(), works ? 4 : 5);
- bool ok = true;
- for (int i = 0; i < proxy.rowCount(); i++) {
- if (!proxy.data(proxy.index(i,0)).toString().contains('o'))
- ok = false;
- }
- QCOMPARE(ok, works);
-}
-
-/**
- * A proxy which changes the background color for items ending in 'y' or 'r'
- */
-class CustomDataProxy : public QSortFilterProxyModel
-{
- Q_OBJECT
-
-public:
- CustomDataProxy(QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
- setDynamicSortFilter(true);
- }
-
- void setSourceModel(QAbstractItemModel *sourceModel)
- {
- // It would be possible to use only the modelReset signal of the source model to clear
- // the data in *this, however, this requires that the slot is connected
- // before QSortFilterProxyModel::setSourceModel is called, and even then depends
- // on the order of invocation of slots being the same as the order of connection.
- // ie, not reliable.
-// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
- QSortFilterProxyModel::setSourceModel(sourceModel);
- // Making the connect after the setSourceModel call clears the data too late.
-// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
-
- // This could be done in data(), but the point is to need to cache something in the proxy
- // which needs to be cleared on reset.
- for (int i = 0; i < sourceModel->rowCount(); ++i)
- {
- if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y')))
- {
- m_backgroundColours.insert(i, Qt::blue);
- } else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r')))
- {
- m_backgroundColours.insert(i, Qt::red);
- }
- }
- }
-
- QVariant data(const QModelIndex &index, int role) const
- {
- if (role != Qt::BackgroundRole)
- return QSortFilterProxyModel::data(index, role);
- return m_backgroundColours.value(index.row());
- }
-
-private slots:
- void resetInternalData()
- {
- m_backgroundColours.clear();
- }
-
-private:
- QHash<int, QColor> m_backgroundColours;
-};
-
-class ModelObserver : public QObject
-{
- Q_OBJECT
-public:
- ModelObserver(QAbstractItemModel *model, QObject *parent = 0)
- : QObject(parent), m_model(model)
- {
- connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToBeReset()));
- connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
- }
-
-public slots:
- void modelAboutToBeReset()
- {
- int reds = 0, blues = 0;
- for (int i = 0; i < m_model->rowCount(); ++i)
- {
- QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
- if (color == Qt::blue)
- ++blues;
- if (color == Qt::red)
- ++reds;
- }
- QCOMPARE(blues, 11);
- QCOMPARE(reds, 4);
- }
-
- void modelReset()
- {
- int reds = 0, blues = 0;
- for (int i = 0; i < m_model->rowCount(); ++i)
- {
- QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
- if (color == Qt::blue)
- ++blues;
- if (color == Qt::red)
- ++reds;
- }
- QCOMPARE(reds, 0);
- QCOMPARE(blues, 0);
- }
-
-private:
- QAbstractItemModel * const m_model;
-
-};
-
-void tst_QSortFilterProxyModel::testResetInternalData()
-{
-
- QStringListModel model(QStringList() << "Monday"
- << "Tuesday"
- << "Wednesday"
- << "Thursday"
- << "Friday"
- << "January"
- << "February"
- << "March"
- << "April"
- << "May"
- << "Saturday"
- << "June"
- << "Sunday"
- << "July"
- << "August"
- << "September"
- << "October"
- << "November"
- << "December");
-
- CustomDataProxy proxy;
- proxy.setSourceModel(&model);
-
- ModelObserver observer(&proxy);
-
- // Cause the source model to reset.
- model.setStringList(QStringList() << "Spam" << "Eggs");
-
-}
-
-void tst_QSortFilterProxyModel::testParentLayoutChanged()
-{
- QStandardItemModel model;
- QStandardItem *parentItem = model.invisibleRootItem();
- for (int i = 0; i < 4; ++i) {
- {
- QStandardItem *item = new QStandardItem(QLatin1String("item ") + QString::number(i));
- parentItem->appendRow(item);
- }
- {
- QStandardItem *item = new QStandardItem(QLatin1String("item 1") + QString::number(i));
- parentItem->appendRow(item);
- parentItem = item;
- }
- }
- // item 0
- // item 10
- // - item 1
- // - item 11
- // - item 2
- // - item 12
- // ...
-
- QSortFilterProxyModel proxy;
- proxy.sort(0, Qt::AscendingOrder);
- proxy.setDynamicSortFilter(true);
-
- proxy.setSourceModel(&model);
- proxy.setObjectName("proxy");
-
- // When Proxy1 emits layoutChanged(QList<QPersistentModelIndex>) this
- // one will too, with mapped indexes.
- QSortFilterProxyModel proxy2;
- proxy2.sort(0, Qt::AscendingOrder);
- proxy2.setDynamicSortFilter(true);
-
- proxy2.setSourceModel(&proxy);
- proxy2.setObjectName("proxy2");
-
- QSignalSpy dataChangedSpy(&model, &QSortFilterProxyModel::dataChanged);
-
- QVERIFY(dataChangedSpy.isValid());
-
- // Verify that the no-arg signal is still emitted.
- QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(layoutAboutToBeChangedSpy.isValid());
- QVERIFY(layoutChangedSpy.isValid());
-
- QSignalSpy parentsAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy parentsChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(parentsAboutToBeChangedSpy.isValid());
- QVERIFY(parentsChangedSpy.isValid());
-
- QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxy2ParentsChangedSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(proxy2ParentsAboutToBeChangedSpy.isValid());
- QVERIFY(proxy2ParentsChangedSpy.isValid());
-
- QStandardItem *item = model.invisibleRootItem()->child(1)->child(1);
- QCOMPARE(item->text(), QStringLiteral("item 11"));
-
- // Ensure mapped:
- proxy.mapFromSource(model.indexFromItem(item));
-
- item->setText("Changed");
-
- QCOMPARE(dataChangedSpy.size(), 1);
- QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
- QCOMPARE(layoutChangedSpy.size(), 1);
- QCOMPARE(parentsAboutToBeChangedSpy.size(), 1);
- QCOMPARE(parentsChangedSpy.size(), 1);
- QCOMPARE(proxy2ParentsAboutToBeChangedSpy.size(), 1);
- QCOMPARE(proxy2ParentsChangedSpy.size(), 1);
-
- QVariantList beforeSignal = parentsAboutToBeChangedSpy.first();
- QVariantList afterSignal = parentsChangedSpy.first();
-
- QCOMPARE(beforeSignal.size(), 2);
- QCOMPARE(afterSignal.size(), 2);
-
- QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> afterParents = afterSignal.first().value<QList<QPersistentModelIndex> >();
-
- QCOMPARE(beforeParents.size(), 1);
- QCOMPARE(afterParents.size(), 1);
-
- QVERIFY(beforeParents.first().isValid());
- QVERIFY(beforeParents.first() == afterParents.first());
-
- QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1))));
-
- QList<QPersistentModelIndex> proxy2BeforeList = proxy2ParentsAboutToBeChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> proxy2AfterList = proxy2ParentsChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
-
- QCOMPARE(proxy2BeforeList.size(), beforeParents.size());
- QCOMPARE(proxy2AfterList.size(), afterParents.size());
- foreach (const QPersistentModelIndex &idx, proxy2BeforeList)
- QVERIFY(beforeParents.contains(proxy2.mapToSource(idx)));
- foreach (const QPersistentModelIndex &idx, proxy2AfterList)
- QVERIFY(afterParents.contains(proxy2.mapToSource(idx)));
-}
-
-class SignalArgumentChecker : public QObject
-{
- Q_OBJECT
-public:
- SignalArgumentChecker(QAbstractItemModel *model, QAbstractProxyModel *proxy, QObject *parent = 0)
- : QObject(parent), m_proxy(proxy)
- {
- connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
- connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
- connect(proxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>)), SLOT(layoutAboutToBeChanged(QList<QPersistentModelIndex>)));
- connect(proxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>)), SLOT(layoutChanged(QList<QPersistentModelIndex>)));
- }
-
-private slots:
- void rowsAboutToBeMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
- {
- m_p1PersistentBefore = source;
- m_p2PersistentBefore = destination;
- m_p2FirstProxyChild = m_proxy->index(0, 0, m_proxy->mapFromSource(destination));
- }
-
- void rowsMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
- {
- m_p1PersistentAfter = source;
- m_p2PersistentAfter = destination;
- }
-
- void layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents)
- {
- QVERIFY(m_p1PersistentBefore.isValid());
- QVERIFY(m_p2PersistentBefore.isValid());
- QCOMPARE(parents.size(), 2);
- QVERIFY(parents.first() != parents.at(1));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentBefore)));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentBefore)));
- }
-
- void layoutChanged(const QList<QPersistentModelIndex> &parents)
- {
- QVERIFY(m_p1PersistentAfter.isValid());
- QVERIFY(m_p2PersistentAfter.isValid());
- QCOMPARE(parents.size(), 2);
- QVERIFY(parents.first() != parents.at(1));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentAfter)));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentAfter)));
-
- // In the source model, the rows were moved to row 1 in the parent.
- // m_p2FirstProxyChild was created with row 0 in the proxy.
- // The moved rows in the proxy do not appear at row 1 because of sorting.
- // Sorting causes them to appear at row 0 instead, pushing what used to
- // be row 0 in the proxy down by two rows.
- QCOMPARE(m_p2FirstProxyChild.row(), 2);
- }
-
-private:
- QAbstractProxyModel *m_proxy;
- QPersistentModelIndex m_p1PersistentBefore;
- QPersistentModelIndex m_p2PersistentBefore;
- QPersistentModelIndex m_p1PersistentAfter;
- QPersistentModelIndex m_p2PersistentAfter;
-
- QPersistentModelIndex m_p2FirstProxyChild;
-};
-
-void tst_QSortFilterProxyModel::moveSourceRows()
-{
- DynamicTreeModel model;
-
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(QList<int>() << 2);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(QList<int>() << 5);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
-
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.sort(0, Qt::AscendingOrder);
-
- // We need to check the arguments at emission time
- SignalArgumentChecker checker(&model, &proxy);
-
- proxy.setSourceModel(&model);
-
- QSortFilterProxyModel filterProxy;
- filterProxy.setDynamicSortFilter(true);
- filterProxy.sort(0, Qt::AscendingOrder);
- filterProxy.setSourceModel(&proxy);
- setupFilter(&filterProxy, QLatin1String("6")); // One of the parents
-
- QSortFilterProxyModel filterBothProxy;
- filterBothProxy.setDynamicSortFilter(true);
- filterBothProxy.sort(0, Qt::AscendingOrder);
- filterBothProxy.setSourceModel(&proxy);
- setupFilter(&filterBothProxy, QLatin1String("5")); // The parents are 6 and 3. This filters both out.
-
- QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
- QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
- QSignalSpy proxyBeforeMoveSpy(m_proxy, &QSortFilterProxyModel::rowsAboutToBeMoved);
- QSignalSpy proxyAfterMoveSpy(m_proxy, &QSortFilterProxyModel::rowsMoved);
- QSignalSpy proxyBeforeParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxyAfterParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
- QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy filterAfterParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutChanged);
- QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(modelBeforeSpy.isValid());
- QVERIFY(modelAfterSpy.isValid());
- QVERIFY(proxyBeforeMoveSpy.isValid());
- QVERIFY(proxyAfterMoveSpy.isValid());
- QVERIFY(proxyBeforeParentLayoutSpy.isValid());
- QVERIFY(proxyAfterParentLayoutSpy.isValid());
- QVERIFY(filterBeforeParentLayoutSpy.isValid());
- QVERIFY(filterAfterParentLayoutSpy.isValid());
- QVERIFY(filterBothBeforeParentLayoutSpy.isValid());
- QVERIFY(filterBothAfterParentLayoutSpy.isValid());
-
- {
- ModelMoveCommand moveCommand(&model, 0);
- moveCommand.setAncestorRowNumbers(QList<int>() << 2);
- moveCommand.setDestAncestors(QList<int>() << 5);
- moveCommand.setStartRow(3);
- moveCommand.setEndRow(4);
- moveCommand.setDestRow(1);
- moveCommand.doCommand();
- }
-
- // Proxy notifies layout change
- QCOMPARE(modelBeforeSpy.size(), 1);
- QCOMPARE(proxyBeforeParentLayoutSpy.size(), 1);
- QCOMPARE(modelAfterSpy.size(), 1);
- QCOMPARE(proxyAfterParentLayoutSpy.size(), 1);
-
- // But it doesn't notify a move.
- QCOMPARE(proxyBeforeMoveSpy.size(), 0);
- QCOMPARE(proxyAfterMoveSpy.size(), 0);
-
- QCOMPARE(filterBeforeParentLayoutSpy.size(), 1);
- QCOMPARE(filterAfterParentLayoutSpy.size(), 1);
-
- QList<QPersistentModelIndex> filterBeforeParents = filterBeforeParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> filterAfterParents = filterAfterParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
-
- QCOMPARE(filterBeforeParents.size(), 1);
- QCOMPARE(filterAfterParents.size(), 1);
-
- QCOMPARE(
- filterBeforeParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
- QCOMPARE(filterAfterParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
-
- QCOMPARE(filterBothBeforeParentLayoutSpy.size(), 0);
- QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0);
-}
-
-class FilterProxy : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilterProxy(QObject *parent = 0)
- : QSortFilterProxyModel(parent),
- mode(false)
- {
-
- }
-
-public slots:
- void setMode(bool on)
- {
- mode = on;
- invalidateFilter();
- }
-
-protected:
- virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
- {
- if (mode) {
- if (!source_parent.isValid()) {
- return true;
- } else {
- return (source_row % 2) != 0;
- }
- } else {
- if (!source_parent.isValid()) {
- return source_row >= 2 && source_row < 10;
- } else {
- return true;
- }
- }
- }
-
-private:
- bool mode;
-};
-
-void tst_QSortFilterProxyModel::hierarchyFilterInvalidation()
-{
- QStandardItemModel model;
- for (int i = 0; i < 10; ++i) {
- const QString rowText = QLatin1String("Row ") + QString::number(i);
- QStandardItem *child = new QStandardItem(rowText);
- for (int j = 0; j < 1; ++j) {
- child->appendRow(new QStandardItem(rowText + QLatin1Char('/') + QString::number(j)));
- }
- model.appendRow(child);
- }
-
- FilterProxy proxy;
- proxy.setSourceModel(&model);
-
- QTreeView view;
- view.setModel(&proxy);
-
- view.setCurrentIndex(proxy.index(2, 0).child(0, 0));
-
- view.show();
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- proxy.setMode(true);
-}
-
-class FilterProxy2 : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilterProxy2(QObject *parent = 0)
- : QSortFilterProxyModel(parent),
- mode(false)
- {
-
- }
-
-public slots:
- void setMode(bool on)
- {
- mode = on;
- invalidateFilter();
- }
-
-protected:
- virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
- {
- if (source_parent.isValid()) {
- return true;
- } else {
- if (0 == source_row) {
- return true;
- } else {
- return !mode;
- }
- }
- }
-
-private:
- bool mode;
-};
-
-void tst_QSortFilterProxyModel::simpleFilterInvalidation()
-{
- QStandardItemModel model;
- for (int i = 0; i < 2; ++i) {
- QStandardItem *child = new QStandardItem(QLatin1String("Row ") + QString::number(i));
- child->appendRow(new QStandardItem("child"));
- model.appendRow(child);
- }
-
- FilterProxy2 proxy;
- proxy.setSourceModel(&model);
-
- QTreeView view;
- view.setModel(&proxy);
-
- view.show();
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- proxy.setMode(true);
- model.insertRow(0, new QStandardItem("extra"));
-}
-
-class CustomRoleNameModel : public QAbstractListModel
-{
- Q_OBJECT
-public:
- CustomRoleNameModel(QObject *parent = 0) : QAbstractListModel(parent) {}
-
- QVariant data(const QModelIndex &index, int role) const
- {
- Q_UNUSED(index);
- Q_UNUSED(role);
- return QVariant();
- }
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- Q_UNUSED(parent);
- return 0;
- }
-
- QHash<int, QByteArray> roleNames() const
- {
- QHash<int, QByteArray> rn = QAbstractListModel::roleNames();
- rn[Qt::UserRole + 1] = "custom";
- return rn;
- }
-};
-
-void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
-{
- QSortFilterProxyModel proxy1;
- QSortFilterProxyModel proxy2;
- CustomRoleNameModel customModel;
-
- proxy2.setSourceModel(&proxy1);
-
- // changing the sourceModel of proxy1 must also update roleNames of proxy2
- proxy1.setSourceModel(&customModel);
- QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
-}
-
-// A source model with ABABAB rows, where only A rows accept drops.
-// It will then be sorted by a QSFPM.
-class DropOnOddRows : public QAbstractListModel
-{
- Q_OBJECT
-public:
- DropOnOddRows(QObject *parent = 0) : QAbstractListModel(parent) {}
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if (role == Qt::DisplayRole)
- return (index.row() % 2 == 0) ? "A" : "B";
- return QVariant();
- }
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override
- {
- Q_UNUSED(parent);
- return 10;
- }
-
- bool canDropMimeData(const QMimeData *, Qt::DropAction,
- int row, int column, const QModelIndex &parent) const override
- {
- Q_UNUSED(row);
- Q_UNUSED(column);
- return parent.row() % 2 == 0;
- }
-};
-
-class SourceAssertion : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- explicit SourceAssertion(QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
-
- }
-
- QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
- {
- Q_ASSERT(sourceModel());
- return QSortFilterProxyModel::mapToSource(proxyIndex);
- }
-};
-
-void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
-{
- SourceAssertion proxy;
- QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
-
- proxy.setSourceModel(model);
-
- // Create mappings
- QPersistentModelIndex persistent = proxy.index(0, 0);
-
- QVERIFY(persistent.isValid());
-
- delete model;
-
- QVERIFY(!persistent.isValid());
-}
-
-// QTBUG-39549, test whether canDropMimeData(), dropMimeData() are proxied as well
-// by invoking them on a QSortFilterProxyModel proxying a QStandardItemModel that allows drops
-// on row #1, filtering for that row.
-class DropTestModel : public QStandardItemModel {
-public:
- explicit DropTestModel(QObject *parent = 0) : QStandardItemModel(0, 1, parent)
- {
- appendRow(new QStandardItem(QStringLiteral("Row0")));
- appendRow(new QStandardItem(QStringLiteral("Row1")));
- }
-
- bool canDropMimeData(const QMimeData *, Qt::DropAction,
- int row, int /* column */, const QModelIndex & /* parent */) const override
- { return row == 1; }
-
- bool dropMimeData(const QMimeData *, Qt::DropAction,
- int row, int /* column */, const QModelIndex & /* parent */) override
- { return row == 1; }
-};
-
-void tst_QSortFilterProxyModel::forwardDropApi()
-{
- QSortFilterProxyModel model;
- model.setSourceModel(new DropTestModel(&model));
- model.setFilterFixedString(QStringLiteral("Row1"));
- QCOMPARE(model.rowCount(), 1);
- QVERIFY(model.canDropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
- QVERIFY(model.dropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
-}
-
-static QString rowTexts(QAbstractItemModel *model) {
- QString str;
- for (int row = 0 ; row < model->rowCount(); ++row)
- str += model->index(row, 0).data().toString();
- return str;
-}
-
-void tst_QSortFilterProxyModel::canDropMimeData()
-{
- // Given a source model which only supports dropping on even rows
- DropOnOddRows sourceModel;
- QCOMPARE(rowTexts(&sourceModel), QString("ABABABABAB"));
-
- // and a proxy model that sorts the rows
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&sourceModel);
- proxy.sort(0, Qt::AscendingOrder);
- QCOMPARE(rowTexts(&proxy), QString("AAAAABBBBB"));
-
- // the proxy should correctly map canDropMimeData to the source model,
- // i.e. accept drops on the first 5 rows and refuse drops on the next 5.
- for (int row = 0; row < proxy.rowCount(); ++row)
- QCOMPARE(proxy.canDropMimeData(0, Qt::CopyAction, -1, -1, proxy.index(row, 0)), row < 5);
-}
-
-void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels()
-{
- QStandardItemModel *treeModel = new QStandardItemModel(this);
- QStandardItem *e1 = new QStandardItem("Loading...");
- e1->appendRow(new QStandardItem("entry10"));
- treeModel->appendRow(e1);
- QStandardItem *e0 = new QStandardItem("Loading...");
- e0->appendRow(new QStandardItem("entry00"));
- e0->appendRow(new QStandardItem("entry01"));
- treeModel->appendRow(e0);
-
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.sort(0);
- proxy.setSourceModel(treeModel);
-
- QAbstractItemModelTester modelTester(&proxy);
-
- QCOMPARE(proxy.rowCount(), 2);
- e1->setText("entry1");
- e0->setText("entry0");
-
- QModelIndex pi0 = proxy.index(0, 0);
- QCOMPARE(pi0.data().toString(), QString("entry0"));
- QCOMPARE(proxy.rowCount(pi0), 2);
-
- QModelIndex pi01 = proxy.index(1, 0, pi0);
- QCOMPARE(pi01.data().toString(), QString("entry01"));
-
- QModelIndex pi1 = proxy.index(1, 0);
- QCOMPARE(pi1.data().toString(), QString("entry1"));
- QCOMPARE(proxy.rowCount(pi1), 1);
-}
-
-void tst_QSortFilterProxyModel::filterHint()
-{
- // test that a filtering model does not emit layoutChanged with a hint
- QStringListModel model(QStringList() << "one"
- << "two"
- << "three"
- << "four"
- << "five"
- << "six");
- QSortFilterProxyModel proxy1;
- proxy1.setSourceModel(&model);
- proxy1.setSortRole(Qt::DisplayRole);
- proxy1.setDynamicSortFilter(true);
- proxy1.sort(0);
-
- QSortFilterProxyModel proxy2;
- proxy2.setSourceModel(&proxy1);
- proxy2.setFilterRole(Qt::DisplayRole);
- setupFilter(&proxy2, QLatin1String("^[^ ]*$"));
- proxy2.setDynamicSortFilter(true);
-
- QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxy1AfterSpy(&proxy1, &QSortFilterProxyModel::layoutChanged);
- QSignalSpy proxy2BeforeSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxy2AfterSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
-
- model.setData(model.index(2), QStringLiteral("modified three"), Qt::DisplayRole);
-
- // The first proxy was re-sorted as one item as changed.
- QCOMPARE(proxy1BeforeSpy.size(), 1);
- QCOMPARE(proxy1BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::VerticalSortHint);
- QCOMPARE(proxy1AfterSpy.size(), 1);
- QCOMPARE(proxy1AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::VerticalSortHint);
-
- // But the second proxy must not have the VerticalSortHint since an item was filtered
- QCOMPARE(proxy2BeforeSpy.size(), 1);
- QCOMPARE(proxy2BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
- QCOMPARE(proxy2AfterSpy.size(), 1);
- QCOMPARE(proxy2AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
-}
-
-/**
-
- Creates a model where each item has one child, to a set depth,
- and the last item has no children. For a model created with
- setDepth(4):
-
- - 1
- - - 2
- - - - 3
- - - - - 4
-*/
-class StepTreeModel : public QAbstractItemModel
-{
- Q_OBJECT
-public:
- StepTreeModel(QObject * parent = 0)
- : QAbstractItemModel(parent), m_depth(0) {}
-
- int columnCount(const QModelIndex& = QModelIndex()) const override { return 1; }
-
- int rowCount(const QModelIndex& parent = QModelIndex()) const override
- {
- quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
- return (parentId < m_depth) ? 1 : 0;
- }
-
- QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override
- {
- if (role != Qt::DisplayRole)
- return QVariant();
-
- return QString::number(index.internalId());
- }
-
- QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override
- {
- // QTBUG-44962: Would we always expect the parent to belong to the model
- qCDebug(lcItemModels) << parent.model() << this;
- Q_ASSERT(!parent.isValid() || parent.model() == this);
-
- quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
- if (parentId >= m_depth)
- return QModelIndex();
-
- return createIndex(0, 0, parentId + 1);
- }
-
- QModelIndex parent(const QModelIndex& index) const override
- {
- if (index.internalId() == 0)
- return QModelIndex();
-
- return createIndex(0, 0, index.internalId() - 1);
- }
-
- void setDepth(quintptr depth)
- {
- int parentIdWithLayoutChange = (m_depth < depth) ? m_depth : depth;
-
- QList<QPersistentModelIndex> parentsOfLayoutChange;
- parentsOfLayoutChange.push_back(createIndex(0, 0, parentIdWithLayoutChange));
-
- layoutAboutToBeChanged(parentsOfLayoutChange);
-
- auto existing = persistentIndexList();
-
- QList<QModelIndex> updated;
-
- for (auto idx : existing) {
- if (indexDepth(idx) <= depth)
- updated.push_back(idx);
- else
- updated.push_back({});
- }
-
- m_depth = depth;
-
- changePersistentIndexList(existing, updated);
-
- layoutChanged(parentsOfLayoutChange);
- }
-
-private:
- static quintptr indexDepth(QModelIndex const& index)
- {
- return (index.isValid()) ? 1 + indexDepth(index.parent()) : 0;
- }
-
-private:
- quintptr m_depth;
-};
-
-void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
-{
- StepTreeModel model;
- Q_SET_OBJECT_NAME(model);
- model.setDepth(4);
-
- QSortFilterProxyModel proxy1;
- proxy1.setSourceModel(&model);
- Q_SET_OBJECT_NAME(proxy1);
- setupFilter(&proxy1, QLatin1String("1|2"));
-
- // The current state of things:
- // model proxy
- // - 1 - 1
- // - - 2 - - 2
- // - - - 3
- // - - - - 4
-
- // The setDepth call below removes '4' with a layoutChanged call.
- // Because the proxy filters that out anyway, the proxy doesn't need
- // to emit any signals or update persistent indexes.
-
- QPersistentModelIndex persistentIndex = proxy1.index(0, 0, proxy1.index(0, 0));
-
- model.setDepth(3);
-
- // Calling parent() causes the internalPointer to be used.
- // Before fixing QTBUG-47711, that could be a dangling pointer.
- // The use of qDebug here makes sufficient use of the heap to
- // cause corruption at runtime with normal use on linux (before
- // the fix). valgrind confirms the fix.
- qCDebug(lcItemModels) << persistentIndex.parent();
- QVERIFY(persistentIndex.parent().isValid());
-}
-
-void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes()
-{
- DynamicTreeModel model;
- Q_SET_OBJECT_NAME(model);
-
- QList<int> ancestors;
- for (auto i = 0; i < 5; ++i)
- {
- Q_UNUSED(i);
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(ancestors);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(0);
- insertCommand.doCommand();
- ancestors.push_back(0);
- }
-
- QSortFilterProxyModel proxy1;
- proxy1.setSourceModel(&model);
- Q_SET_OBJECT_NAME(proxy1);
-
- setupFilter(&proxy1, QLatin1String("1|2"));
-
- auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first();
- auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first();
-
- Q_ASSERT(item5.isValid());
- Q_ASSERT(item3.isValid());
-
- QPersistentModelIndex persistentIndex = proxy1.match(proxy1.index(0, 0), Qt::DisplayRole, "2", 1, Qt::MatchRecursive).first();
-
- ModelMoveCommand moveCommand(&model, 0);
- moveCommand.setAncestorRowNumbers(QList<int>{0, 0, 0, 0});
- moveCommand.setStartRow(0);
- moveCommand.setEndRow(0);
- moveCommand.setDestRow(0);
- moveCommand.setDestAncestors(QList<int>{0, 0, 0});
- moveCommand.doCommand();
-
- // Calling parent() causes the internalPointer to be used.
- // Before fixing QTBUG-47711 (moveRows case), that could be
- // a dangling pointer.
- QVERIFY(persistentIndex.parent().isValid());
-}
-
-void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged_data()
-{
- QTest::addColumn<int>("changedRow");
- QTest::addColumn<Qt::ItemDataRole>("changedRole");
- QTest::addColumn<QString>("newData");
- QTest::addColumn<QString>("expectedSourceRowTexts");
- QTest::addColumn<QString>("expectedProxyRowTexts");
- QTest::addColumn<int>("expectedLayoutChanged");
-
- // Starting point:
- // a source model with 8,7,6,5,4,3,2,1
- // a proxy model keeping only even rows and sorting them, therefore showing 2,4,6,8
-
- // When setData changes ordering, layoutChanged should be emitted
- QTest::newRow("ordering_change") << 0 << Qt::DisplayRole << "0" << "07654321" << "0246" << 1;
-
- // When setData on visible row doesn't change ordering, layoutChanged should not be emitted
- QTest::newRow("no_ordering_change") << 6 << Qt::DisplayRole << "0" << "87654301" << "0468" << 0;
-
- // When setData happens on a filtered out row, layoutChanged should not be emitted
- QTest::newRow("filtered_out") << 1 << Qt::DisplayRole << "9" << "89654321" << "2468" << 0;
-
- // When setData makes a row visible, layoutChanged should not be emitted (rowsInserted is emitted instead)
- QTest::newRow("make_row_visible") << 7 << Qt::DisplayRole << "0" << "87654320" << "02468" << 0;
-
- // When setData makes a row hidden, layoutChanged should not be emitted (rowsRemoved is emitted instead)
- QTest::newRow("make_row_hidden") << 4 << Qt::DisplayRole << "1" << "87651321" << "268" << 0;
-
- // When setData happens on an unrelated role, layoutChanged should not be emitted
- QTest::newRow("unrelated_role") << 0 << Qt::DecorationRole << "" << "87654321" << "2468" << 0;
-
- // When many changes happen together... and trigger removal, insertion, and layoutChanged
- QTest::newRow("many_changes") << -1 << Qt::DisplayRole << "3,4,2,5,6,0,7,9" << "34256079" << "0246" << 1;
-
- // When many changes happen together... and trigger removal, insertion, but no change in ordering of visible rows => no layoutChanged
- QTest::newRow("many_changes_no_layoutChanged") << -1 << Qt::DisplayRole << "7,5,4,3,2,1,0,8" << "75432108" << "0248" << 0;
-}
-
-// Custom version of QStringListModel which supports emitting dataChanged for many rows at once
-class CustomStringListModel : public QAbstractListModel
-{
-public:
- bool setData(const QModelIndex &index, const QVariant &value, int role) override
- {
- if (index.row() >= 0 && index.row() < lst.size()
- && (role == Qt::EditRole || role == Qt::DisplayRole)) {
- lst.replace(index.row(), value.toString());
- emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole });
- return true;
- }
- return false;
- }
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if (role == Qt::DisplayRole || role == Qt::EditRole)
- return lst.at(index.row());
- return QVariant();
- }
- int rowCount(const QModelIndex & = QModelIndex()) const override { return lst.count(); }
-
- void replaceData(const QStringList &newData)
- {
- lst = newData;
- emit dataChanged(index(0, 0), index(rowCount() - 1, 0), { Qt::DisplayRole, Qt::EditRole });
- }
-
- void emitDecorationChangedSignal()
- {
- const QModelIndex idx = index(0, 0);
- emit dataChanged(idx, idx, { Qt::DecorationRole });
- }
-
-private:
- QStringList lst;
-};
-
-void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged()
-{
- QFETCH(int, changedRow);
- QFETCH(QString, newData);
- QFETCH(Qt::ItemDataRole, changedRole);
- QFETCH(QString, expectedSourceRowTexts);
- QFETCH(QString, expectedProxyRowTexts);
- QFETCH(int, expectedLayoutChanged);
-
- CustomStringListModel model;
- QStringList strings;
- for (auto i = 8; i >= 1; --i)
- strings.append(QString::number(i));
- model.replaceData(strings);
- QCOMPARE(rowTexts(&model), QStringLiteral("87654321"));
-
- class FilterEvenRowsProxyModel : public QSortFilterProxyModel
- {
- public:
- bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const override
- {
- return sourceModel()->index(srcRow, 0, srcParent).data().toInt() % 2 == 0;
- }
- };
-
- FilterEvenRowsProxyModel proxy;
- proxy.sort(0);
- proxy.setSourceModel(&model);
- QCOMPARE(rowTexts(&proxy), QStringLiteral("2468"));
-
- QSignalSpy modelDataChangedSpy(&model, &QAbstractItemModel::dataChanged);
- QSignalSpy proxyLayoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
-
- if (changedRole == Qt::DecorationRole)
- model.emitDecorationChangedSignal();
- else if (changedRow == -1)
- model.replaceData(newData.split(QLatin1Char(',')));
- else
- model.setData(model.index(changedRow, 0), newData, changedRole);
-
- QCOMPARE(rowTexts(&model), expectedSourceRowTexts);
- QCOMPARE(rowTexts(&proxy), expectedProxyRowTexts);
- QCOMPARE(modelDataChangedSpy.size(), 1);
- QCOMPARE(proxyLayoutChangedSpy.size(), expectedLayoutChanged);
-}
-
-void tst_QSortFilterProxyModel::removeIntervals_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<QStringList>("replacementSourceItems");
- QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
- QTest::addColumn<QStringList>("expectedProxyItems");
-
- QTest::newRow("filter all, sort ascending")
- << (QStringList() << "a"
- << "b"
- << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "[^x]" // filter
- << (QStringList() << "x"
- << "x"
- << "x") // replacementSourceItems
- << (IntPairList() << IntPair(0, 2)) // expectedRemovedIntervals
- << QStringList() // expectedProxyItems
- ;
-
- QTest::newRow("filter all, sort descending")
- << (QStringList() << "a"
- << "b"
- << "c") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "[^x]" // filter
- << (QStringList() << "x"
- << "x"
- << "x") // replacementSourceItems
- << (IntPairList() << IntPair(0, 2)) // expectedRemovedIntervals
- << QStringList() // expectedProxyItems
- ;
-
- QTest::newRow("filter first and last, sort ascending")
- << (QStringList() << "a"
- << "b"
- << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "[^x]" // filter
- << (QStringList() << "x"
- << "b"
- << "x") // replacementSourceItems
- << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b") // expectedProxyItems
- ;
-
- QTest::newRow("filter first and last, sort descending")
- << (QStringList() << "a"
- << "b"
- << "c") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "[^x]" // filter
- << (QStringList() << "x"
- << "b"
- << "x") // replacementSourceItems
- << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b") // expectedProxyItems
- ;
-}
-
-void tst_QSortFilterProxyModel::removeIntervals()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(QStringList, replacementSourceItems);
- QFETCH(IntPairList, expectedRemovedProxyIntervals);
- QFETCH(QStringList, expectedProxyItems);
-
- CustomStringListModel model;
- QSortFilterProxyModel proxy;
-
- model.replaceData(sourceItems);
- proxy.setSourceModel(&model);
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex sindex = model.index(i, 0, QModelIndex());
- QModelIndex pindex = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
- }
-
- proxy.setDynamicSortFilter(true);
-
- if (sortOrder != -1)
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- if (!filter.isEmpty())
- setupFilter(&proxy, filter);
-
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
- QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
-
- QVERIFY(removeSpy.isValid());
- QVERIFY(insertSpy.isValid());
- QVERIFY(aboutToRemoveSpy.isValid());
- QVERIFY(aboutToInsertSpy.isValid());
-
- model.replaceData(replacementSourceItems);
-
- QCOMPARE(aboutToRemoveSpy.count(), expectedRemovedProxyIntervals.count());
- for (int i = 0; i < aboutToRemoveSpy.count(); ++i) {
- QList<QVariant> args = aboutToRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
- }
- QCOMPARE(removeSpy.count(), expectedRemovedProxyIntervals.count());
- for (int i = 0; i < removeSpy.count(); ++i) {
- QList<QVariant> args = removeSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
- }
-
- QCOMPARE(insertSpy.count(), 0);
- QCOMPARE(aboutToInsertSpy.count(), 0);
-
- QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.count());
- for (int i = 0; i < expectedProxyItems.count(); ++i) {
- QModelIndex pindex = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::dynamicFilterWithoutSort()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.setSourceModel(&model);
-
- QSignalSpy layoutChangeSpy(&proxy, &QAbstractItemModel::layoutChanged);
- QSignalSpy resetSpy(&proxy, &QAbstractItemModel::modelReset);
-
- QVERIFY(layoutChangeSpy.isValid());
- QVERIFY(resetSpy.isValid());
-
- model.setStringList(QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
-
- QVERIFY(layoutChangeSpy.isEmpty());
-
- QCOMPARE(model.stringList(), QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
-
- QCOMPARE(resetSpy.count(), 1);
-}
-
-void tst_QSortFilterProxyModel::checkSetNewModel()
-{
- QTreeView tv;
- StepTreeModel model1;
- model1.setDepth(4);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model1);
- tv.setModel(&proxy);
- tv.show();
- QVERIFY(QTest::qWaitForWindowExposed(&tv));
- tv.expandAll();
- {
- StepTreeModel model2;
- model2.setDepth(4);
- proxy.setSourceModel(&model2);
- tv.expandAll();
- proxy.setSourceModel(&model1);
- tv.expandAll();
- // the destruction of model2 here caused a proxy model reset due to
- // missing disconnect in setSourceModel()
- }
- // handle repaint events, will assert when qsortfilterproxymodel is in wrong state
- QCoreApplication::processEvents();
-}
-
-enum ColumnFilterMode {
- FilterNothing,
- FilterOutMiddle,
- FilterOutBeginEnd,
- FilterAll
-};
-Q_DECLARE_METATYPE(ColumnFilterMode)
-
-void tst_QSortFilterProxyModel::filterAndInsertColumn_data()
-{
-
- QTest::addColumn<int>("insertCol");
- QTest::addColumn<ColumnFilterMode>("filterMode");
- QTest::addColumn<QStringList>("expectedModelList");
- QTest::addColumn<QStringList>("expectedProxyModelList");
-
- QTest::newRow("at_beginning_filter_out_middle")
- << 0
- << FilterOutMiddle
- << QStringList{{"", "A1", "B1", "C1", "D1"}}
- << QStringList{{"", "D1"}}
- ;
- QTest::newRow("at_end_filter_out_middle")
- << 2
- << FilterOutMiddle
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{{"A1", ""}}
- ;
- QTest::newRow("in_the_middle_filter_out_middle")
- << 1
- << FilterOutMiddle
- << QStringList{{"A1", "B1", "C1", "", "D1"}}
- << QStringList{{"A1", "D1"}}
- ;
- QTest::newRow("at_beginning_filter_out_begin_and_end")
- << 0
- << FilterOutBeginEnd
- << QStringList{{"A1", "", "B1", "C1", "D1"}}
- << QStringList{{"", "B1", "C1"}}
- ;
- QTest::newRow("at_end_filter_out_begin_and_end")
- << 2
- << FilterOutBeginEnd
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{{"B1", "C1", "D1"}}
- ;
- QTest::newRow("in_the_middle_filter_out_begin_and_end")
- << 1
- << FilterOutBeginEnd
- << QStringList{{"A1", "B1", "", "C1", "D1"}}
- << QStringList{{"B1", "", "C1"}}
- ;
-
- QTest::newRow("at_beginning_filter_nothing")
- << 0
- << FilterAll
- << QStringList{{"", "A1", "B1", "C1", "D1"}}
- << QStringList{{"", "A1", "B1", "C1", "D1"}}
- ;
- QTest::newRow("at_end_filter_nothing")
- << 4
- << FilterAll
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- ;
- QTest::newRow("in_the_middle_nothing")
- << 2
- << FilterAll
- << QStringList{{"A1", "B1", "", "C1", "D1"}}
- << QStringList{{"A1", "B1", "", "C1", "D1"}}
- ;
-
- QTest::newRow("filter_all")
- << 0
- << FilterNothing
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{}
- ;
-}
-void tst_QSortFilterProxyModel::filterAndInsertColumn()
-{
-
- class ColumnFilterProxy : public QSortFilterProxyModel {
- Q_DISABLE_COPY(ColumnFilterProxy)
- ColumnFilterMode filerMode;
- public:
- ColumnFilterProxy(ColumnFilterMode mode)
- : filerMode(mode)
- {}
- bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
- {
- Q_UNUSED(source_parent)
- switch (filerMode){
- case FilterAll:
- return true;
- case FilterNothing:
- return false;
- case FilterOutMiddle:
- return source_column == 0 || source_column == sourceModel()->columnCount() - 1;
- case FilterOutBeginEnd:
- return source_column > 0 && source_column< sourceModel()->columnCount() - 1;
- }
- Q_UNREACHABLE();
- }
- };
- QFETCH(int, insertCol);
- QFETCH(ColumnFilterMode, filterMode);
- QFETCH(QStringList, expectedModelList);
- QFETCH(QStringList, expectedProxyModelList);
- QStandardItemModel model;
- model.insertColumns(0, 4);
- model.insertRows(0, 1);
- for (int i = 0; i < model.rowCount(); ++i) {
- for (int j = 0; j < model.columnCount(); ++j)
- model.setData(model.index(i, j), QString('A' + j) + QString::number(i + 1));
- }
- ColumnFilterProxy proxy(filterMode);
- proxy.setSourceModel(&model);
- QVERIFY(proxy.insertColumn(insertCol));
- proxy.invalidate();
- QStringList modelStringList;
- for (int i = 0; i < model.rowCount(); ++i) {
- for (int j = 0; j < model.columnCount(); ++j)
- modelStringList.append(model.index(i, j).data().toString());
- }
- QCOMPARE(expectedModelList, modelStringList);
- modelStringList.clear();
- for (int i = 0; i < proxy.rowCount(); ++i) {
- for (int j = 0; j < proxy.columnCount(); ++j)
- modelStringList.append(proxy.index(i, j).data().toString());
- }
- QCOMPARE(expectedProxyModelList, modelStringList);
-}
-
-void tst_QSortFilterProxyModel::filterAndInsertRow_data()
-{
- QTest::addColumn<QStringList>("initialModelList");
- QTest::addColumn<int>("row");
- QTest::addColumn<QString>("filterRegExp");
- QTest::addColumn<QStringList>("expectedModelList");
- QTest::addColumn<QStringList>("expectedProxyModelList");
-
- QTest::newRow("at_beginning_filter_out_middle")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << "^A"
- << QStringList{{"", "A5", "B5", "B6", "A7"}}
- << QStringList{{"A5", "A7"}};
- QTest::newRow("at_end_filter_out_middle")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 2
- << "^A"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{{"A5", "A7"}};
- QTest::newRow("in_the_middle_filter_out_middle")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 1
- << "^A"
- << QStringList{{"A5", "B5", "B6", "", "A7"}}
- << QStringList{{"A5", "A7"}};
-
- QTest::newRow("at_beginning_filter_out_first_and_last")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << "^B"
- << QStringList{{"A5", "", "B5", "B6", "A7"}}
- << QStringList{{"B5", "B6"}};
- QTest::newRow("at_end_filter_out_first_and_last")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 2
- << "^B"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{{"B5", "B6"}};
- QTest::newRow("in_the_middle_filter_out_first_and_last")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 1
- << "^B"
- << QStringList{{"A5", "B5", "", "B6", "A7"}}
- << QStringList{{"B5", "B6"}};
-
- QTest::newRow("at_beginning_no_filter")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << ".*"
- << QStringList{{"", "A5", "B5", "B6", "A7"}}
- << QStringList{{"", "A5", "B5", "B6", "A7"}};
- QTest::newRow("at_end_no_filter")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 4
- << ".*"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{{"A5", "B5", "B6", "A7", ""}};
- QTest::newRow("in_the_middle_no_filter")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 2
- << ".*"
- << QStringList{{"A5", "B5", "", "B6", "A7"}}
- << QStringList{{"A5", "B5", "", "B6", "A7"}};
-
- QTest::newRow("filter_all")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << "$a"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{};
-}
-
-void tst_QSortFilterProxyModel::filterAndInsertRow()
-{
- QFETCH(QStringList, initialModelList);
- QFETCH(int, row);
- QFETCH(QString, filterRegExp);
- QFETCH(QStringList, expectedModelList);
- QFETCH(QStringList, expectedProxyModelList);
- QStringListModel model;
- QSortFilterProxyModel proxyModel;
-
- model.setStringList(initialModelList);
- proxyModel.setSourceModel(&model);
- proxyModel.setDynamicSortFilter(true);
- proxyModel.setFilterRegExp(filterRegExp);
-
- QVERIFY(proxyModel.insertRow(row));
- QCOMPARE(model.stringList(), expectedModelList);
- QCOMPARE(proxyModel.rowCount(), expectedProxyModelList.count());
- for (int r = 0; r < proxyModel.rowCount(); ++r) {
- QModelIndex index = proxyModel.index(r, 0);
- QVERIFY(index.isValid());
- QCOMPARE(proxyModel.data(index).toString(), expectedProxyModelList.at(r));
- }
-}
-
-#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
deleted file mode 100644
index 8ae97165b8..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef TST_QSORTFILTERPROXYMODEL_H
-#define TST_QSORTFILTERPROXYMODEL_H
-
-#include <QtTest/QtTest>
-#include "dynamictreemodel.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtGui/QStandardItem>
-#include <QtWidgets/QTreeView>
-#include <QtWidgets/QTableView>
-
-#include <qdebug.h>
-
-typedef QList<int> IntList;
-typedef QPair<int, int> IntPair;
-typedef QList<IntPair> IntPairList;
-
-enum class FilterType {
- RegExp,
- RegularExpression
-};
-
-Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
-
-class tst_QSortFilterProxyModel : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QSortFilterProxyModel();
-
-public slots:
- void initTestCase();
- void cleanupTestCase();
- void cleanup();
-
-private slots:
- void getSetCheck();
- void sort_data();
- void sort();
- void sortHierarchy_data();
- void sortHierarchy();
-
- void insertRows_data();
- void insertRows();
- void prependRow();
- void appendRowFromCombobox_data();
- void appendRowFromCombobox();
- void removeRows_data();
- void removeRows();
- void removeColumns_data();
- void removeColumns();
- void insertAfterSelect();
- void removeAfterSelect();
- void filter_data();
- void filter();
- void filterHierarchy_data();
- void filterHierarchy();
- void filterColumns_data();
- void filterColumns();
-
- void filterTable();
- void filterCurrent();
- void filter_qtbug30662();
-
- void changeSourceLayout();
- void changeSourceLayoutFilteredOut();
- void removeSourceRows_data();
- void removeSourceRows();
- void insertSourceRows_data();
- void insertSourceRows();
- void changeFilter_data();
- void changeFilter();
- void changeSourceData_data();
- void changeSourceData();
- void changeSourceDataKeepsStableSorting_qtbug1548();
- void changeSourceDataForwardsRoles_qtbug35440();
- void resortingDoesNotBreakTreeModels();
- void dynamicFilterWithoutSort();
- void sortFilterRole();
- void selectionFilteredOut();
- void match_data();
- void match();
- void matchTree();
- void insertIntoChildrenlessItem();
- void invalidateMappedChildren();
- void insertRowIntoFilteredParent();
- void filterOutParentAndFilterInChild();
-
- void sourceInsertRows();
- void sourceModelDeletion();
-
- void sortColumnTracking1();
- void sortColumnTracking2();
-
- void sortStable();
-
- void hiddenColumns();
- void insertRowsSort();
- void staticSorting();
- void dynamicSorting();
- void fetchMore();
- void hiddenChildren();
- void mapFromToSource();
- void removeRowsRecursive();
- void doubleProxySelectionSetSourceModel();
- void appearsAndSort();
- void unnecessaryDynamicSorting();
- void unnecessaryMapCreation();
- void resetInvalidate_data();
- void resetInvalidate();
-
- void testMultipleProxiesWithSelection();
- void mapSelectionFromSource();
- void testResetInternalData();
- void filteredColumns();
- void headerDataChanged();
-
- void testParentLayoutChanged();
- void moveSourceRows();
-
- void hierarchyFilterInvalidation();
- void simpleFilterInvalidation();
-
- void chainedProxyModelRoleNames();
-
- void noMapAfterSourceDelete();
- void forwardDropApi();
- void canDropMimeData();
- void filterHint();
-
- void sourceLayoutChangeLeavesValidPersistentIndexes();
- void rowMoveLeavesValidPersistentIndexes();
-
- void emitLayoutChangedOnlyIfSortingChanged_data();
- void emitLayoutChangedOnlyIfSortingChanged();
-
- void checkSetNewModel();
- void filterAndInsertRow_data();
- void filterAndInsertRow();
- void filterAndInsertColumn_data();
- void filterAndInsertColumn();
-
- void removeIntervals_data();
- void removeIntervals();
-
-protected:
- void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
- void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
- void setupFilter(QSortFilterProxyModel *model, const QString& pattern);
-
-protected:
- FilterType m_filterType;
-
-private:
- QStandardItemModel *m_model;
- QSortFilterProxyModel *m_proxy;
-};
-
-Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
-
-Q_DECLARE_LOGGING_CATEGORY(lcItemModels)
-
-#endif // TST_QSORTFILTERPROXYMODEL_H
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/CMakeLists.txt b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/CMakeLists.txt
new file mode 100644
index 0000000000..2f08bf1b26
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsortfilterproxymodel_recursive Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsfpm_recursive LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsfpm_recursive
+ SOURCES
+ tst_qsortfilterproxymodel_recursive.cpp
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro
deleted file mode 100644
index a8b793dbc6..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/qsortfilterproxymodel_recursive.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-CONFIG += parallel_test
-TARGET = tst_qsortfilterproxymodel_recursive
-
-QT += testlib
-
-SOURCES += tst_qsortfilterproxymodel_recursive.cpp
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp
index 7cae554963..c6b24a489a 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_recursive/tst_qsortfilterproxymodel_recursive.cpp
@@ -1,36 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, authors Filipe Azevedo <filipe.azevedo@kdab.com> and David Faure <david.faure@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, authors Filipe Azevedo <filipe.azevedo@kdab.com> and David Faure <david.faure@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QSignalSpy>
-
-#include <QtCore/QSortFilterProxyModel>
-#include <QtGui/QStandardItem>
+#include <QSortFilterProxyModel>
+#include <QStandardItem>
Q_DECLARE_METATYPE(QModelIndex)
@@ -143,9 +117,9 @@ static QString treeAsString(const QAbstractItemModel &model, const QModelIndex &
static void fillModel(QStandardItemModel &model, const QString &str)
{
QCOMPARE(str.count('['), str.count(']'));
- QStandardItem *item = 0;
+ QStandardItem *item = nullptr;
QString data;
- for ( int i = 0 ; i < str.length() ; ++i ) {
+ for ( int i = 0 ; i < str.size() ; ++i ) {
const QChar ch = str.at(i);
if ((ch == '[' || ch == ']' || ch == ' ') && !data.isEmpty()) {
if (data.endsWith('*')) {
@@ -716,6 +690,38 @@ private Q_SLOTS:
}
+ void testChildrenFiltering_data()
+ {
+ QTest::addColumn<QString>("sourceStr");
+ QTest::addColumn<QString>("noChildrenProxyStr");
+ QTest::addColumn<QString>("childrenProxyStr");
+ QTest::addColumn<QString>("noParentProxyStr");
+
+ QTest::newRow("filter_parent") << "[1*[1.1 1.2[1.2.1]]]" << "[1*]" << "[1*[1.1 1.2[1.2.1]]]" << "[1*[1.1 1.2[1.2.1]]]";
+ QTest::newRow("filter_child") << "[1[1.1 1.2*[1.2.1]]]" << "[1[1.2*]]" << "[1[1.2*[1.2.1]]]" << "";
+
+ }
+
+ void testChildrenFiltering()
+ {
+ QFETCH(QString, sourceStr);
+ QFETCH(QString, noChildrenProxyStr);
+ QFETCH(QString, childrenProxyStr);
+ QFETCH(QString, noParentProxyStr);
+
+ QStandardItemModel model;
+ fillModel(model, sourceStr);
+
+ TestModel proxy(&model);
+ QCOMPARE(treeAsString(proxy), noChildrenProxyStr);
+
+ proxy.setAutoAcceptChildRows(true);
+ QCOMPARE(treeAsString(proxy), childrenProxyStr);
+
+ proxy.setRecursiveFilteringEnabled(false);
+ QCOMPARE(treeAsString(proxy), noParentProxyStr);
+ }
+
private:
QStandardItem *itemByText(const QStandardItemModel& model, const QString &text) const {
QModelIndexList list = model.match(model.index(0, 0), Qt::DisplayRole, text, 1, Qt::MatchRecursive);
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore
deleted file mode 100644
index 4fdaebc09d..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qsortfilterproxymodel_regexp
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro
deleted file mode 100644
index 7c510930f4..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsortfilterproxymodel_regexp
-
-QT += widgets testlib
-mtdir = ../../../other/qabstractitemmodelutils
-qsfpmdir = ../qsortfilterproxymodel_common
-
-INCLUDEPATH += $$PWD/$${mtdir} $$PWD/$${qsfpmdir}
-SOURCES += \
- tst_qsortfilterproxymodel_regexp.cpp \
- $${qsfpmdir}/tst_qsortfilterproxymodel.cpp \
- $${mtdir}/dynamictreemodel.cpp
-
-HEADERS += \
- $${qsfpmdir}/tst_qsortfilterproxymodel.h \
- $${mtdir}/dynamictreemodel.h
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp
deleted file mode 100644
index 38607f1378..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include "tst_qsortfilterproxymodel.h"
-
-class tst_QSortFilterProxyModelRegExp : public tst_QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- tst_QSortFilterProxyModelRegExp();
-private slots:
- void tst_invalid();
- void tst_caseSensitivity();
-};
-
-tst_QSortFilterProxyModelRegExp::tst_QSortFilterProxyModelRegExp() :
- tst_QSortFilterProxyModel()
-{
- m_filterType = FilterType::RegExp;
-}
-
-void tst_QSortFilterProxyModelRegExp::tst_invalid()
-{
- const QLatin1String pattern("test");
- QSortFilterProxyModel model;
- model.setFilterRegExp(pattern);
- QCOMPARE(model.filterRegExp(), QRegExp(pattern));
- model.setFilterRegularExpression(pattern);
- QCOMPARE(model.filterRegExp(), QRegExp());
-}
-
-void tst_QSortFilterProxyModelRegExp::tst_caseSensitivity()
-{
- const QLatin1String pattern("test");
- QSortFilterProxyModel model;
- model.setFilterCaseSensitivity(Qt::CaseInsensitive);
- model.setFilterRegExp(pattern);
- QCOMPARE(model.filterCaseSensitivity(), Qt::CaseInsensitive);
-}
-
-QTEST_MAIN(tst_QSortFilterProxyModelRegExp)
-#include "tst_qsortfilterproxymodel_regexp.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/CMakeLists.txt b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/CMakeLists.txt
new file mode 100644
index 0000000000..d82c2118b5
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsortfilterproxymodel_regularexpression Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsfpm_regex LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsfpm_regex
+ SOURCES
+ tst_qsortfilterproxymodel_regularexpression.cpp
+ INCLUDE_DIRECTORIES
+ ../../../other/qabstractitemmodelutils
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro
deleted file mode 100644
index e993d07126..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsortfilterproxymodel_regularexpression
-
-QT += widgets testlib
-mtdir = ../../../other/qabstractitemmodelutils
-qsfpmdir = ../qsortfilterproxymodel_common
-
-INCLUDEPATH += $$PWD/$${mtdir} $${qsfpmdir}
-SOURCES += \
- tst_qsortfilterproxymodel_regularexpression.cpp \
- $${qsfpmdir}/tst_qsortfilterproxymodel.cpp \
- $${mtdir}/dynamictreemodel.cpp
-
-HEADERS += \
- $${qsfpmdir}/tst_qsortfilterproxymodel.h \
- $${mtdir}/dynamictreemodel.h
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp
index 821e199bcb..729da48c5e 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp
@@ -1,58 +1,129 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include "tst_qsortfilterproxymodel.h"
-
-class tst_QSortFilterProxyModelRegularExpression : public tst_QSortFilterProxyModel
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QStringListModel>
+#include <QSortFilterProxyModel>
+
+class tst_QSortFilterProxyModelRegularExpression : public QObject
{
Q_OBJECT
-public:
- tst_QSortFilterProxyModelRegularExpression();
private slots:
void tst_invalid();
+ void tst_caseSensitivity();
+ void tst_keepCaseSensitivity_QTBUG_92260();
+ void tst_keepPatternOptions_QTBUG_92260();
+ void tst_regexCaseSensitivityNotification();
};
-tst_QSortFilterProxyModelRegularExpression::tst_QSortFilterProxyModelRegularExpression() :
- tst_QSortFilterProxyModel()
-{
- m_filterType = FilterType::RegularExpression;
-}
-
void tst_QSortFilterProxyModelRegularExpression::tst_invalid()
{
const QLatin1String pattern("test");
QSortFilterProxyModel model;
model.setFilterRegularExpression(pattern);
QCOMPARE(model.filterRegularExpression(), QRegularExpression(pattern));
- model.setFilterRegExp(pattern);
- QCOMPARE(model.filterRegularExpression(), QRegularExpression());
+}
+
+void tst_QSortFilterProxyModelRegularExpression::tst_caseSensitivity()
+{
+ const QLatin1String pattern("test");
+ QStringListModel model({ "test", "TesT" });
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
+ proxyModel.setFilterRegularExpression(pattern);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(proxyModel.rowCount(), 2);
+
+ proxyModel.setFilterCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(proxyModel.rowCount(), 1);
+ proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(proxyModel.rowCount(), 2);
+}
+
+/*!
+ This test ensures that when a string pattern is passed to setRegularEpxression,
+ the options are properly reseted but that the case sensitivity is kept as is.
+
+ */
+void tst_QSortFilterProxyModelRegularExpression::tst_keepCaseSensitivity_QTBUG_92260()
+{
+ const QLatin1String pattern("test");
+ QStringListModel model({ "test", "TesT" });
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ QRegularExpression patternWithOptions("Dummy",
+ QRegularExpression::MultilineOption
+ | QRegularExpression::CaseInsensitiveOption);
+
+ proxyModel.setFilterRegularExpression(patternWithOptions);
+ QCOMPARE(proxyModel.filterRegularExpression(), patternWithOptions);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive);
+
+ proxyModel.setFilterRegularExpression(pattern);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(proxyModel.filterRegularExpression().patternOptions(),
+ QRegularExpression::CaseInsensitiveOption);
+
+ patternWithOptions.setPatternOptions(QRegularExpression::MultilineOption);
+ proxyModel.setFilterRegularExpression(patternWithOptions);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(proxyModel.filterRegularExpression(), patternWithOptions);
+
+ proxyModel.setFilterRegularExpression(pattern);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(proxyModel.filterRegularExpression().patternOptions(),
+ QRegularExpression::NoPatternOption);
+}
+
+/*!
+ This test ensures that when the case sensitivity is changed, it does not nuke
+ the pattern options that were set before.
+ */
+void tst_QSortFilterProxyModelRegularExpression::tst_keepPatternOptions_QTBUG_92260()
+{
+ QStringListModel model({ "test", "TesT" });
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ QRegularExpression patternWithOptions("Dummy",
+ QRegularExpression::MultilineOption
+ | QRegularExpression::CaseInsensitiveOption);
+
+ proxyModel.setFilterRegularExpression(patternWithOptions);
+ QCOMPARE(proxyModel.filterRegularExpression(), patternWithOptions);
+
+ proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(proxyModel.filterRegularExpression().patternOptions(),
+ patternWithOptions.patternOptions());
+
+ proxyModel.setFilterCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(proxyModel.filterCaseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(proxyModel.filterRegularExpression().patternOptions(),
+ QRegularExpression::MultilineOption);
+}
+
+/*!
+ This test ensures that if the case sensitivity is changed during a call to
+ setFilterRegularExpression, the notification signal will be emitted
+*/
+void tst_QSortFilterProxyModelRegularExpression::tst_regexCaseSensitivityNotification()
+{
+ QSortFilterProxyModel proxy;
+ QSignalSpy spy(&proxy, &QSortFilterProxyModel::filterCaseSensitivityChanged);
+ proxy.setFilterCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(spy.size(), 1);
+ QRegularExpression re("regex");
+ QVERIFY(!re.patternOptions().testFlag(QRegularExpression::CaseInsensitiveOption));
+ proxy.setFilterRegularExpression(re);
+ QCOMPARE(proxy.filterCaseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(spy.size(), 2);
}
QTEST_MAIN(tst_QSortFilterProxyModelRegularExpression)
diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qstringlistmodel/CMakeLists.txt
new file mode 100644
index 0000000000..8a00d1cd42
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qstringlistmodel/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringlistmodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringlistmodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringlistmodel
+ SOURCES
+ qmodellistener.h
+ tst_qstringlistmodel.cpp
+)
diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/qmodellistener.h b/tests/auto/corelib/itemmodels/qstringlistmodel/qmodellistener.h
index e08a0bdb1f..ecf7214ba4 100644
--- a/tests/auto/corelib/itemmodels/qstringlistmodel/qmodellistener.h
+++ b/tests/auto/corelib/itemmodels/qstringlistmodel/qmodellistener.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QObject>
#include <QModelIndex>
diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/qstringlistmodel.pro b/tests/auto/corelib/itemmodels/qstringlistmodel/qstringlistmodel.pro
deleted file mode 100644
index 91a4cf306c..0000000000
--- a/tests/auto/corelib/itemmodels/qstringlistmodel/qstringlistmodel.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringlistmodel
-QT = core testlib
-HEADERS += qmodellistener.h
-SOURCES += tst_qstringlistmodel.cpp
diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
index 1b40e77648..8ec2aeabe5 100644
--- a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
#include <qabstractitemmodel.h>
#include <qcoreapplication.h>
#include <qmap.h>
@@ -84,8 +60,114 @@ private slots:
void setData_emits_on_change_only();
void supportedDragDropActions();
+
+ void moveRows_data();
+ void moveRows();
+ void moveRowsInvalid_data();
+ void moveRowsInvalid();
+
+ void itemData();
+ void setItemData();
+ void createPersistentOnLayoutAboutToBeChanged();
};
+void tst_QStringListModel::moveRowsInvalid_data()
+{
+ QTest::addColumn<QStringListModel*>("baseModel");
+ QTest::addColumn<QModelIndex>("startParent");
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QModelIndex>("destinationParent");
+ QTest::addColumn<int>("destination");
+
+ const auto createModel = [this]() {
+ return new QStringListModel(QStringList{"A", "B", "C", "D", "E", "F"}, this);
+ };
+ constexpr int rowCount = 6;
+
+ QTest::addRow("destination_equal_source") << createModel() << QModelIndex() << 0 << 1 << QModelIndex() << 0;
+ QTest::addRow("count_equal_0") << createModel() << QModelIndex() << 0 << 0 << QModelIndex() << 2;
+ QStringListModel *tempModel = createModel();
+ QTest::addRow("move_child") << tempModel << tempModel->index(0, 0) << 0 << 1 << QModelIndex() << 2;
+ tempModel = createModel();
+ QTest::addRow("move_to_child") << tempModel << QModelIndex() << 0 << 1 << tempModel->index(0, 0) << 2;
+ QTest::addRow("negative_count") << createModel() << QModelIndex() << 0 << -1 << QModelIndex() << 2;
+ QTest::addRow("negative_source_row") << createModel() << QModelIndex() << -1 << 1 << QModelIndex() << 2;
+ QTest::addRow("negative_destination_row") << createModel() << QModelIndex() << 0 << 1 << QModelIndex() << -1;
+ QTest::addRow("source_row_equal_rowCount") << createModel() << QModelIndex() << rowCount << 1 << QModelIndex() << 1;
+ QTest::addRow("source_row_equal_destination_row") << createModel() << QModelIndex() << 2 << 1 << QModelIndex() << 2;
+ QTest::addRow("source_row_equal_destination_row_plus_1") << createModel() << QModelIndex() << 2 << 1 << QModelIndex() << 3;
+ QTest::addRow("destination_row_greater_rowCount") << createModel() << QModelIndex() << 0 << 1 << QModelIndex() << rowCount + 1;
+ QTest::addRow("move_row_within_source_range") << createModel() << QModelIndex() << 0 << 3 << QModelIndex() << 2;
+}
+
+void tst_QStringListModel::moveRowsInvalid()
+{
+ QFETCH(QStringListModel* const, baseModel);
+ QFETCH(const QModelIndex, startParent);
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const QModelIndex, destinationParent);
+ QFETCH(const int, destination);
+
+ QSignalSpy rowMovedSpy(baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(rowMovedSpy.isValid());
+ QVERIFY(rowAboutMovedSpy.isValid());
+ QVERIFY(!baseModel->moveRows(startParent, startRow, count, destinationParent, destination));
+ QCOMPARE(rowMovedSpy.size(), 0);
+ QCOMPARE(rowAboutMovedSpy.size(), 0);
+ delete baseModel;
+}
+
+void tst_QStringListModel::moveRows_data()
+{
+ QTest::addColumn<int>("startRow");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("destination");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("1_Item_from_top_to_middle") << 0 << 1 << 3 << QStringList{"B", "C", "A", "D", "E", "F"};
+ QTest::newRow("1_Item_from_top_to_bottom") << 0 << 1 << 6 << QStringList{"B", "C", "D", "E", "F", "A"};
+ QTest::newRow("1_Item_from_middle_to_top") << 2 << 1 << 0 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_bottom_to_middle") << 5 << 1 << 2 << QStringList{"A", "B", "F", "C", "D", "E"};
+ QTest::newRow("1_Item_from_bottom to_top") << 5 << 1 << 0 << QStringList{"F", "A", "B", "C", "D", "E"};
+ QTest::newRow("1_Item_from_middle_to_bottom") << 2 << 1 << 6 << QStringList{"A", "B", "D", "E", "F", "C"};
+ QTest::newRow("1_Item_from_middle_to_middle_before") << 2 << 1 << 1 << QStringList{"A", "C", "B", "D", "E", "F"};
+ QTest::newRow("1_Item_from_middle_to_middle_after") << 2 << 1 << 4 << QStringList{"A", "B", "D", "C", "E", "F"};
+
+ QTest::newRow("2_Items_from_top_to_middle") << 0 << 2 << 3 << QStringList{"C", "A", "B", "D", "E", "F"};
+ QTest::newRow("2_Items_from_top_to_bottom") << 0 << 2 << 6 << QStringList{"C", "D", "E", "F", "A", "B"};
+ QTest::newRow("2_Items_from_middle_to_top") << 2 << 2 << 0 << QStringList{"C", "D", "A", "B", "E", "F"};
+ QTest::newRow("2_Items_from_bottom_to_middle") << 4 << 2 << 2 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_bottom_to_top") << 4 << 2 << 0 << QStringList{"E", "F", "A", "B", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_bottom") << 2 << 2 << 6 << QStringList{"A", "B", "E", "F", "C", "D"};
+ QTest::newRow("2_Items_from_middle_to_middle_before") << 3 << 2 << 1 << QStringList{"A", "D", "E", "B", "C", "F"};
+ QTest::newRow("2_Items_from_middle_to_middle_after") << 1 << 2 << 5 << QStringList{"A", "D", "E", "B", "C", "F"};
+}
+
+void tst_QStringListModel::moveRows()
+{
+ QFETCH(const int, startRow);
+ QFETCH(const int, count);
+ QFETCH(const int, destination);
+ QFETCH(const QStringList, expected);
+ QStringListModel baseModel(QStringList{"A", "B", "C", "D", "E", "F"});
+ QSignalSpy rowMovedSpy(&baseModel, &QAbstractItemModel::rowsMoved);
+ QSignalSpy rowAboutMovedSpy(&baseModel, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(baseModel.moveRows(QModelIndex(), startRow, count, QModelIndex(), destination));
+ QCOMPARE(baseModel.stringList(), expected);
+ QCOMPARE(rowMovedSpy.size(), 1);
+ QCOMPARE(rowAboutMovedSpy.size(), 1);
+ for (const QList<QVariant> &signalArgs : {rowMovedSpy.first(), rowAboutMovedSpy.first()}){
+ QVERIFY(!signalArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(1).toInt(), startRow);
+ QCOMPARE(signalArgs.at(2).toInt(), startRow + count - 1);
+ QVERIFY(!signalArgs.at(3).value<QModelIndex>().isValid());
+ QCOMPARE(signalArgs.at(4).toInt(), destination);
+ }
+}
+
void tst_QStringListModel::rowsAboutToBeRemoved_rowsRemoved_data()
{
QTest::addColumn<QStringList>("input");
@@ -225,7 +307,7 @@ template <class C>
C sorted(C c)
{
std::sort(c.begin(), c.end());
- return qMove(c);
+ return c;
}
void tst_QStringListModel::setData_emits_both_roles()
@@ -235,7 +317,7 @@ void tst_QStringListModel::setData_emits_both_roles()
QFETCH(int, role);
QStringListModel model(QStringList() << "one" << "two");
- QVector<int> expected;
+ QList<int> expected;
expected.reserve(2);
expected.append(Qt::DisplayRole);
expected.append(Qt::EditRole);
@@ -244,10 +326,78 @@ void tst_QStringListModel::setData_emits_both_roles()
QVERIFY(spy.isValid());
model.setData(model.index(row, 0), data, role);
QCOMPARE(spy.size(), 1);
- QCOMPARE(sorted(spy.at(0).at(2).value<QVector<int> >()),
+ QCOMPARE(sorted(spy.at(0).at(2).value<QList<int> >()),
expected);
}
+void tst_QStringListModel::itemData()
+{
+ QStringListModel testModel{ QStringList {
+ QStringLiteral("One"),
+ QStringLiteral("Two"),
+ QStringLiteral("Three"),
+ QStringLiteral("Four"),
+ QStringLiteral("Five")
+ }};
+ QMap<int, QVariant> compareMap;
+ QCOMPARE(testModel.itemData(QModelIndex()), compareMap);
+ compareMap.insert(Qt::DisplayRole, QStringLiteral("Two"));
+ compareMap.insert(Qt::EditRole, QStringLiteral("Two"));
+ QCOMPARE(testModel.itemData(testModel.index(1, 0)), compareMap);
+}
+
+void tst_QStringListModel::setItemData()
+{
+ QStringListModel testModel{ QStringList {
+ QStringLiteral("One"),
+ QStringLiteral("Two"),
+ QStringLiteral("Three"),
+ QStringLiteral("Four"),
+ QStringLiteral("Five")
+ }};
+ QSignalSpy dataChangedSpy(&testModel, &QAbstractItemModel::dataChanged);
+ QModelIndex changeIndex = testModel.index(1, 0);
+ const QList<int> changeRoles{Qt::DisplayRole, Qt::EditRole};
+ const QString changedString("Changed");
+ QMap<int, QVariant> newItemData{std::make_pair<int>(Qt::DisplayRole, changedString)};
+ // invalid index does nothing and returns false
+ QVERIFY(!testModel.setItemData(QModelIndex(), newItemData));
+ // valid data is set, return value is true and dataChanged is emitted once
+ QVERIFY(testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), changedString);
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), changedString);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QVariantList dataChangedArguments = dataChangedSpy.takeFirst();
+ QCOMPARE(dataChangedArguments.at(0).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(1).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(2).value<QList<int> >(), changeRoles);
+ // Unsupported roles do nothing return false
+ newItemData.clear();
+ newItemData.insert(Qt::UserRole, changedString);
+ QVERIFY(!testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(dataChangedSpy.size(), 0);
+ // If some but not all the roles are supported it returns false and does nothing
+ newItemData.insert(Qt::EditRole, changedString);
+ changeIndex = testModel.index(2, 0);
+ QVERIFY(!testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), QStringLiteral("Three"));
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), QStringLiteral("Three"));
+ QCOMPARE(dataChangedSpy.size(), 0);
+ // Qt::EditRole and Qt::DisplayRole are both set, Qt::EditRole takes precedence
+ newItemData.clear();
+ newItemData.insert(Qt::EditRole, changedString);
+ newItemData.insert(Qt::DisplayRole, QStringLiteral("Ignored"));
+ changeIndex = testModel.index(3, 0);
+ QVERIFY(testModel.setItemData(changeIndex, newItemData));
+ QCOMPARE(changeIndex.data(Qt::DisplayRole).toString(), changedString);
+ QCOMPARE(changeIndex.data(Qt::EditRole).toString(), changedString);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ dataChangedArguments = dataChangedSpy.takeFirst();
+ QCOMPARE(dataChangedArguments.at(0).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(1).value<QModelIndex>(), changeIndex);
+ QCOMPARE(dataChangedArguments.at(2).value<QList<int> >(), changeRoles);
+}
+
void tst_QStringListModel::setData_emits_on_change_only()
{
QStringListModel model(QStringList{QStringLiteral("one"), QStringLiteral("two")});
@@ -256,12 +406,12 @@ void tst_QStringListModel::setData_emits_on_change_only()
const QModelIndex modelIdx = model.index(0, 0);
const QString newStringData = QStringLiteral("test");
QVERIFY(model.setData(modelIdx, newStringData));
- QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.size(), 1);
const QList<QVariant> spyList = dataChangedSpy.takeFirst();
QCOMPARE(spyList.at(0).value<QModelIndex>(), modelIdx);
QCOMPARE(spyList.at(1).value<QModelIndex>(), modelIdx);
- const QVector<int> expectedRoles{Qt::DisplayRole, Qt::EditRole};
- QCOMPARE(spyList.at(2).value<QVector<int> >(), expectedRoles);
+ const QList<int> expectedRoles{Qt::DisplayRole, Qt::EditRole};
+ QCOMPARE(spyList.at(2).value<QList<int> >(), expectedRoles);
QVERIFY(model.setData(modelIdx, newStringData));
QVERIFY(dataChangedSpy.isEmpty());
}
@@ -273,5 +423,34 @@ void tst_QStringListModel::supportedDragDropActions()
QCOMPARE(model.supportedDropActions(), Qt::CopyAction | Qt::MoveAction);
}
+void tst_QStringListModel::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QStringListModel model(QStringList{QStringLiteral("1"), QStringLiteral("2"), QStringLiteral("3")});
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(&model, &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&model, &QAbstractItemModel::layoutChanged);
+ connect(&model, &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &model](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(model.index(row, 0));
+ });
+ connect(&model, &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toString(), QStringLiteral("1"));
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toString(), QStringLiteral("0"));
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toString(), QStringLiteral("3"));
+ });
+ model.setData(model.index(1, 0), QStringLiteral("0"));
+ model.sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
QTEST_MAIN(tst_QStringListModel)
#include "tst_qstringlistmodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qtransposeproxymodel/CMakeLists.txt b/tests/auto/corelib/itemmodels/qtransposeproxymodel/CMakeLists.txt
new file mode 100644
index 0000000000..b8ad00ca00
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qtransposeproxymodel/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtransposeproxymodel Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtransposeproxymodel LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtransposeproxymodel
+ SOURCES
+ tst_qtransposeproxymodel.cpp
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp b/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp
new file mode 100644
index 0000000000..127b5c6ba0
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp
@@ -0,0 +1,962 @@
+// Copyright (C) 2018 Luca Beldi <v.ronin@yahoo.it>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QStandardItemModel>
+#include <QStringListModel>
+#include <QAbstractItemModelTester>
+#include <random>
+
+#include <qtransposeproxymodel.h>
+
+class tst_QTransposeProxyModel : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void initTestCase();
+ void index();
+ void data();
+ void setData_data();
+ void setData();
+ void parent();
+ void mapToSource();
+ void mapFromSource();
+ void basicTest_data();
+ void basicTest();
+ void sort();
+ void insertRowBase_data();
+ void insertRowBase();
+ void insertColumnBase_data();
+ void insertColumnBase();
+ void insertColumnProxy_data();
+ void insertColumnProxy();
+ void insertRowProxy_data();
+ void insertRowProxy();
+ void removeRowBase_data();
+ void removeRowBase();
+ void removeColumnBase_data();
+ void removeColumnBase();
+ void removeColumnProxy_data();
+ void removeColumnProxy();
+ void removeRowProxy_data();
+ void removeRowProxy();
+ void headerData();
+ void setHeaderData();
+ void span();
+ void itemData();
+ void setItemData();
+ void moveRowsBase();
+ void moveColumnsProxy();
+ void sortPersistentIndex();
+ void createPersistentOnLayoutAboutToBeChanged();
+private:
+ void testTransposed(
+ const QAbstractItemModel *const baseModel,
+ const QAbstractItemModel *const transposed,
+ const QModelIndex &baseParent = QModelIndex(),
+ const QModelIndex &transposedParent = QModelIndex()
+ );
+ QAbstractItemModel *createListModel(QObject *parent);
+ QAbstractItemModel *createTableModel(QObject *parent);
+ QAbstractItemModel *createTreeModel(QObject *parent);
+};
+
+QAbstractItemModel *tst_QTransposeProxyModel::createListModel(QObject *parent)
+{
+ QStringList sequence;
+ sequence.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ sequence.append(QString::number(i));
+ return new QStringListModel(sequence, parent);
+}
+
+QAbstractItemModel *tst_QTransposeProxyModel::createTableModel(QObject *parent)
+{
+ QAbstractItemModel *model = new QStandardItemModel(parent);
+ model->insertRows(0, 5);
+ model->insertColumns(0, 4);
+ for (int i = 0; i < model->rowCount(); ++i) {
+ for (int j = 0; j < model->columnCount(); ++j) {
+ model->setData(model->index(i, j), QStringLiteral("%1,%2").arg(i).arg(j), Qt::EditRole);
+ model->setData(model->index(i, j), i, Qt::UserRole);
+ model->setData(model->index(i, j), j, Qt::UserRole + 1);
+ }
+ }
+ return model;
+}
+
+QAbstractItemModel *tst_QTransposeProxyModel::createTreeModel(QObject *parent)
+{
+ QAbstractItemModel *model = new QStandardItemModel(parent);
+ model->insertRows(0, 5);
+ model->insertColumns(0, 4);
+ for (int i = 0; i < model->rowCount(); ++i) {
+ for (int j = 0; j < model->columnCount(); ++j) {
+ const QModelIndex parIdx = model->index(i, j);
+ model->setData(parIdx, QStringLiteral("%1,%2").arg(i).arg(j), Qt::EditRole);
+ model->setData(parIdx, i, Qt::UserRole);
+ model->setData(parIdx, j, Qt::UserRole + 1);
+ model->insertRows(0, 3, parIdx);
+ model->insertColumns(0, 2, parIdx);
+ for (int h = 0; h < model->rowCount(parIdx); ++h) {
+ for (int k = 0; k < model->columnCount(parIdx); ++k) {
+ const QModelIndex childIdx = model->index(h, k, parIdx);
+ model->setData(childIdx, QStringLiteral("%1,%2,%3,%4").arg(i).arg(j).arg(h).arg(k), Qt::EditRole);
+ model->setData(childIdx, i, Qt::UserRole);
+ model->setData(childIdx, j, Qt::UserRole + 1);
+ model->setData(childIdx, h, Qt::UserRole + 2);
+ model->setData(childIdx, k, Qt::UserRole + 3);
+ }
+ }
+ }
+ }
+ return model;
+}
+
+void tst_QTransposeProxyModel::testTransposed(
+ const QAbstractItemModel *const baseModel,
+ const QAbstractItemModel *const transposed,
+ const QModelIndex &baseParent,
+ const QModelIndex &transposedParent
+)
+{
+ QCOMPARE(transposed->hasChildren(transposedParent), baseModel->hasChildren(baseParent));
+ QCOMPARE(transposed->columnCount(transposedParent), baseModel->rowCount(baseParent));
+ QCOMPARE(transposed->rowCount(transposedParent), baseModel->columnCount(baseParent));
+ for (int i = 0, maxRow = baseModel->rowCount(baseParent); i < maxRow; ++i) {
+ for (int j = 0, maxCol = baseModel->columnCount(baseParent); j < maxCol; ++j) {
+ const QModelIndex baseIdx = baseModel->index(i, j, baseParent);
+ const QModelIndex transIdx = transposed->index(j, i, transposedParent);
+ QCOMPARE(transIdx.data(), baseIdx.data());
+ QCOMPARE(transIdx.data(Qt::UserRole), baseIdx.data(Qt::UserRole));
+ QCOMPARE(transIdx.data(Qt::UserRole + 1), baseIdx.data(Qt::UserRole + 1));
+ QCOMPARE(transIdx.data(Qt::UserRole + 2), baseIdx.data(Qt::UserRole + 2));
+ QCOMPARE(transIdx.data(Qt::UserRole + 3), baseIdx.data(Qt::UserRole + 3));
+ if (baseModel->hasChildren(baseIdx)) {
+ testTransposed(baseModel, transposed, baseIdx, transIdx);
+ }
+ }
+ }
+}
+
+void tst_QTransposeProxyModel::initTestCase()
+{
+ qRegisterMetaType<QList<QPersistentModelIndex> >();
+ qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
+}
+
+void tst_QTransposeProxyModel::index()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QVERIFY(!proxy.index(0, -1).isValid());
+ QVERIFY(!proxy.index(0, -1).isValid());
+ QVERIFY(!proxy.index(-1, -1).isValid());
+ QVERIFY(!proxy.index(0, proxy.columnCount()).isValid());
+ QVERIFY(!proxy.index(proxy.rowCount(), 0).isValid());
+ QVERIFY(!proxy.index(proxy.rowCount(), proxy.columnCount()).isValid());
+ QModelIndex tempIdx = proxy.index(0, 1);
+ QVERIFY(tempIdx.isValid());
+ QCOMPARE(tempIdx.row(), 0);
+ QCOMPARE(tempIdx.column(), 1);
+ tempIdx = proxy.index(0, 1, tempIdx);
+ QVERIFY(tempIdx.isValid());
+ QCOMPARE(tempIdx.row(), 0);
+ QCOMPARE(tempIdx.column(), 1);
+ delete model;
+}
+
+void tst_QTransposeProxyModel::data()
+{
+ QStringListModel model{QStringList{"A", "B"}};
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QCOMPARE(proxy.index(0, 1).data().toString(), QStringLiteral("B"));
+}
+
+void tst_QTransposeProxyModel::parent()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const QModelIndex parentIdx = proxy.index(0, 0);
+ const QModelIndex childIdx = proxy.index(0, 0, parentIdx);
+ QVERIFY(parentIdx.isValid());
+ QVERIFY(childIdx.isValid());
+ QCOMPARE(childIdx.parent(), parentIdx);
+ delete model;
+}
+
+void tst_QTransposeProxyModel::mapToSource()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QVERIFY(!proxy.mapToSource(QModelIndex()).isValid());
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 0)), model->index(0, 0));
+ QCOMPARE(proxy.mapToSource(proxy.index(1, 0)), model->index(0, 1));
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 1)), model->index(1, 0));
+ const QModelIndex proxyParent = proxy.index(1, 0);
+ const QModelIndex sourceParent = model->index(0, 1);
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 0, proxyParent)), model->index(0, 0, sourceParent));
+ QCOMPARE(proxy.mapToSource(proxy.index(1, 0, proxyParent)), model->index(0, 1, sourceParent));
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 1, proxyParent)), model->index(1, 0, sourceParent));
+ delete model;
+}
+
+void tst_QTransposeProxyModel::mapFromSource()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QVERIFY(!proxy.mapFromSource(QModelIndex()).isValid());
+ QCOMPARE(proxy.mapFromSource(model->index(0, 0)), proxy.index(0, 0));
+ QCOMPARE(proxy.mapFromSource(model->index(0, 1)), proxy.index(1, 0));
+ QCOMPARE(proxy.mapFromSource(model->index(1, 0)), proxy.index(0, 1));
+ const QModelIndex proxyParent = proxy.index(1, 0);
+ const QModelIndex sourceParent = model->index(0, 1);
+ QCOMPARE(proxy.mapToSource(proxy.index(0, 0, proxyParent)), model->index(0, 0, sourceParent));
+ QCOMPARE(proxy.mapFromSource(model->index(1, 0, sourceParent)), proxy.index(0, 1, proxyParent));
+ QCOMPARE(proxy.mapFromSource(model->index(0, 1, sourceParent)), proxy.index(1, 0, proxyParent));
+ delete model;
+}
+
+void tst_QTransposeProxyModel::basicTest_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::newRow("List") << createListModel(this);
+ QTest::newRow("Table") << createTableModel(this);
+ QTest::newRow("Tree") << createTreeModel(this);
+}
+
+void tst_QTransposeProxyModel::basicTest()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ testTransposed(model, &proxy);
+ delete model;
+}
+
+void tst_QTransposeProxyModel::sort()
+{
+ QStringList sequence;
+ sequence.reserve(100);
+ for (int i = 0; i < 100; ++i)
+ sequence.append(QStringLiteral("%1").arg(i, 3, 10, QLatin1Char('0')));
+ std::shuffle(sequence.begin(), sequence.end(), std::mt19937(88));
+ const QString firstItemBeforeSort = sequence.first();
+ QStringListModel baseModel(sequence);
+ QTransposeProxyModel proxyModel;
+ new QAbstractItemModelTester(&proxyModel, &proxyModel);
+ proxyModel.setSourceModel(&baseModel);
+ QSignalSpy layoutChangedSpy(&proxyModel, &QAbstractItemModel::layoutChanged);
+ QVERIFY(layoutChangedSpy.isValid());
+ QSignalSpy layoutAboutToBeChangedSpy(&proxyModel, &QAbstractItemModel::layoutAboutToBeChanged);
+ QVERIFY(layoutAboutToBeChangedSpy.isValid());
+ QPersistentModelIndex firstIndexBeforeSort = proxyModel.index(0, 0);
+ baseModel.sort(0, Qt::AscendingOrder);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.takeFirst().at(1).toInt(), int(QAbstractItemModel::HorizontalSortHint));
+ QCOMPARE(firstIndexBeforeSort.data().toString(), firstItemBeforeSort);
+ for (int i = 0; i < 100; ++i)
+ QCOMPARE(proxyModel.index(0, i).data().toInt(), i);
+}
+
+void tst_QTransposeProxyModel::removeColumnBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::removeColumnBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy rowRemoveSpy(&proxy, &QAbstractItemModel::rowsRemoved);
+ QVERIFY(rowRemoveSpy.isValid());
+ QSignalSpy rowAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::rowsAboutToBeRemoved);
+ QVERIFY(rowAboutToBeRemoveSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldRowCount = proxy.rowCount(proxy.mapFromSource(parent));
+ const QVariant expectedNewVal = model->index(0, 2, parent).data();
+ QVERIFY(model->removeColumn(1, parent));
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(parent)), oldRowCount - 1);
+ QCOMPARE(proxy.index(1, 0, proxy.mapFromSource(parent)).data(), expectedNewVal);
+ QCOMPARE(rowRemoveSpy.size(), 1);
+ QCOMPARE(rowAboutToBeRemoveSpy.size(), 1);
+ for (const auto &spyArgs : {rowRemoveSpy.takeFirst(),
+ rowAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::sortPersistentIndex()
+{
+ QStringListModel model(QStringList{QStringLiteral("Alice"), QStringLiteral("Charlie"), QStringLiteral("Bob")});
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QPersistentModelIndex aliceIdx = proxy.index(0, 0);
+ QPersistentModelIndex bobIdx = proxy.index(0, 2);
+ QPersistentModelIndex charlieIdx = proxy.index(0, 1);
+ connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, this, [&aliceIdx, &bobIdx, &charlieIdx](){
+ QCOMPARE(aliceIdx.row(), 0);
+ QCOMPARE(aliceIdx.column(), 0);
+ QCOMPARE(aliceIdx.data().toString(), QStringLiteral("Alice"));
+ QCOMPARE(bobIdx.row(), 0);
+ QCOMPARE(bobIdx.column(), 2);
+ QCOMPARE(bobIdx.data().toString(), QStringLiteral("Bob"));
+ QCOMPARE(charlieIdx.row(), 0);
+ QCOMPARE(charlieIdx.column(), 1);
+ QCOMPARE(charlieIdx.data().toString(), QStringLiteral("Charlie"));
+ });
+ connect(&proxy, &QAbstractItemModel::layoutChanged, this, [&aliceIdx, &bobIdx, &charlieIdx](){
+ QCOMPARE(aliceIdx.row(), 0);
+ QCOMPARE(aliceIdx.column(), 0);
+ QCOMPARE(aliceIdx.data().toString(), QStringLiteral("Alice"));
+ QCOMPARE(bobIdx.row(), 0);
+ QCOMPARE(bobIdx.column(), 1);
+ QCOMPARE(bobIdx.data().toString(), QStringLiteral("Bob"));
+ QCOMPARE(charlieIdx.row(), 0);
+ QCOMPARE(charlieIdx.column(), 2);
+ QCOMPARE(charlieIdx.data().toString(), QStringLiteral("Charlie"));
+ });
+ model.sort(0);
+ QCOMPARE(aliceIdx.row(), 0);
+ QCOMPARE(aliceIdx.column(), 0);
+ QCOMPARE(aliceIdx.data().toString(), QStringLiteral("Alice"));
+ QCOMPARE(bobIdx.row(), 0);
+ QCOMPARE(bobIdx.column(), 1);
+ QCOMPARE(bobIdx.data().toString(), QStringLiteral("Bob"));
+ QCOMPARE(charlieIdx.row(), 0);
+ QCOMPARE(charlieIdx.column(), 2);
+ QCOMPARE(charlieIdx.data().toString(), QStringLiteral("Charlie"));
+}
+
+void tst_QTransposeProxyModel::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QStandardItemModel model(3, 1);
+ for (int row = 0; row < 3; ++row)
+ model.setData(model.index(row, 0), row, Qt::UserRole);
+ model.setSortRole(Qt::UserRole);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
+ connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &proxy](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(proxy.index(0, row));
+ });
+ connect(&proxy, &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 0);
+ QCOMPARE(idxList.at(0).column(), 1);
+ QCOMPARE(idxList.at(0).data(Qt::UserRole).toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data(Qt::UserRole).toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 0);
+ QCOMPARE(idxList.at(2).column(), 2);
+ QCOMPARE(idxList.at(2).data(Qt::UserRole).toInt(), 2);
+ });
+ model.setData(model.index(1, 0), -1, Qt::UserRole);
+ model.sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+void tst_QTransposeProxyModel::insertColumnBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::insertColumnBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy rowInsertSpy(&proxy, &QAbstractItemModel::rowsInserted);
+ QVERIFY(rowInsertSpy.isValid());
+ QSignalSpy rowAboutToBeInsertSpy(&proxy, &QAbstractItemModel::rowsAboutToBeInserted);
+ QVERIFY(rowAboutToBeInsertSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldRowCount = proxy.rowCount(proxy.mapFromSource(parent));
+ QVERIFY(model->insertColumn(1, parent));
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(parent)), oldRowCount + 1);
+ QVERIFY(!proxy.index(1, 0, proxy.mapFromSource(parent)).data().isValid());
+ QCOMPARE(rowInsertSpy.size(), 1);
+ QCOMPARE(rowAboutToBeInsertSpy.size(), 1);
+ for (const auto &spyArgs : {rowInsertSpy.takeFirst(),
+ rowAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::removeRowBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("List") << createListModel(this) << QModelIndex();
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::removeRowBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy columnsRemoveSpy(&proxy, &QAbstractItemModel::columnsRemoved);
+ QVERIFY(columnsRemoveSpy.isValid());
+ QSignalSpy columnsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeRemoved);
+ QVERIFY(columnsAboutToBeRemoveSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldColCount = proxy.columnCount(proxy.mapFromSource(parent));
+ const QVariant expectedNewVal = model->index(2, 0, parent).data();
+ QVERIFY(model->removeRow(1, parent));
+ QCOMPARE(proxy.columnCount(proxy.mapFromSource(parent)), oldColCount - 1);
+ QCOMPARE(proxy.index(0, 1, proxy.mapFromSource(parent)).data(), expectedNewVal);
+ QCOMPARE(columnsRemoveSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeRemoveSpy.size(), 1);
+ for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(),
+ columnsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertRowBase_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<QModelIndex>("parent");
+ QTest::newRow("List") << createListModel(this) << QModelIndex();
+ QTest::newRow("Table") << createTableModel(this) << QModelIndex();
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex();
+ QAbstractItemModel *model = createTreeModel(this);
+ QTest::newRow("Tree_Child_Item") << model << model->index(0, 0);
+}
+
+void tst_QTransposeProxyModel::insertRowBase()
+{
+ QFETCH(QAbstractItemModel * const, model);
+ QFETCH(const QModelIndex, parent);
+ QTransposeProxyModel proxy;
+ QSignalSpy columnsInsertSpy(&proxy, &QAbstractItemModel::columnsInserted);
+ QVERIFY(columnsInsertSpy.isValid());
+ QSignalSpy columnsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::columnsAboutToBeInserted);
+ QVERIFY(columnsAboutToBeInsertSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ const int oldColCount = proxy.columnCount(proxy.mapFromSource(parent));
+ QVERIFY(model->insertRow(1, parent));
+ QCOMPARE(proxy.columnCount(proxy.mapFromSource(parent)), oldColCount + 1);
+ QVariant result = proxy.index(0, 1, proxy.mapFromSource(parent)).data();
+ QVERIFY(result.isNull() || (result.metaType().id() == QMetaType::QString && result.toString().isNull()));
+ QCOMPARE(columnsInsertSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeInsertSpy.size(), 1);
+ for (const auto &spyArgs : {columnsInsertSpy.takeFirst(),
+ columnsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxy.mapFromSource(parent));
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::removeColumnProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("List") << createListModel(this) << true;
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::removeColumnProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy columnsRemoveSpy(&proxy, &QAbstractItemModel::columnsRemoved);
+ QVERIFY(columnsRemoveSpy.isValid());
+ QSignalSpy columnsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeRemoved);
+ QVERIFY(columnsAboutToBeRemoveSpy.isValid());
+ QSignalSpy rowsRemoveSpy(model, &QAbstractItemModel::rowsRemoved);
+ QVERIFY(rowsRemoveSpy.isValid());
+ QSignalSpy rowsAboutToBeRemoveSpy(model, &QAbstractItemModel::rowsAboutToBeRemoved);
+ QVERIFY(rowsAboutToBeRemoveSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldColCount = proxy.columnCount(proxyParent);
+ const int oldRowCount = model->rowCount(sourceParent);
+ const QVariant expectedNewVal = proxy.index(0, 2, proxyParent).data();
+ QVERIFY(proxy.removeColumn(1, proxyParent));
+ QCOMPARE(proxy.columnCount(proxyParent), oldColCount - 1);
+ QCOMPARE(model->rowCount(sourceParent), oldRowCount - 1);
+ QCOMPARE(proxy.index(0, 1, proxyParent).data(), expectedNewVal);
+ QCOMPARE(model->index(1, 0, sourceParent).data(), expectedNewVal);
+ QCOMPARE(columnsRemoveSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeRemoveSpy.size(), 1);
+ QCOMPARE(rowsRemoveSpy.size(), 1);
+ QCOMPARE(rowsAboutToBeRemoveSpy.size(), 1);
+ for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(),
+ columnsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsRemoveSpy.takeFirst(),
+ rowsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertColumnProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("List") << createListModel(this) << true;
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::insertColumnProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy columnsInsertSpy(&proxy, &QAbstractItemModel::columnsInserted);
+ QVERIFY(columnsInsertSpy.isValid());
+ QSignalSpy columnsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::columnsAboutToBeInserted);
+ QVERIFY(columnsAboutToBeInsertSpy.isValid());
+ QSignalSpy rowsInsertSpy(model, &QAbstractItemModel::rowsInserted);
+ QVERIFY(rowsInsertSpy.isValid());
+ QSignalSpy rowsAboutToBeInsertSpy(model, &QAbstractItemModel::rowsAboutToBeInserted);
+ QVERIFY(rowsAboutToBeInsertSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldColCount = proxy.columnCount(proxyParent);
+ const int oldRowCount = model->rowCount(sourceParent);
+ QVERIFY(proxy.insertColumn(1, proxyParent));
+ QCOMPARE(proxy.columnCount(proxyParent), oldColCount + 1);
+ QCOMPARE(model->rowCount(sourceParent), oldRowCount + 1);
+ QVariant result = proxy.index(0, 1, proxyParent).data();
+ QVERIFY(result.isNull() || (result.metaType().id() == QMetaType::QString && result.toString().isNull()));
+ result = model->index(1, 0, sourceParent).data();
+ QVERIFY(result.isNull() || (result.metaType().id() == QMetaType::QString && result.toString().isNull()));
+ QCOMPARE(columnsInsertSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeInsertSpy.size(), 1);
+ QCOMPARE(rowsInsertSpy.size(), 1);
+ QCOMPARE(rowsAboutToBeInsertSpy.size(), 1);
+ for (const auto &spyArgs : {columnsInsertSpy.takeFirst(),
+ columnsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsInsertSpy.takeFirst(),
+ rowsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::removeRowProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::removeRowProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy rowsRemoveSpy(&proxy, &QAbstractItemModel::rowsRemoved);
+ QVERIFY(rowsRemoveSpy.isValid());
+ QSignalSpy rowsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::rowsAboutToBeRemoved);
+ QVERIFY(rowsAboutToBeRemoveSpy.isValid());
+ QSignalSpy columnsRemoveSpy(model, &QAbstractItemModel::columnsRemoved);
+ QVERIFY(columnsRemoveSpy.isValid());
+ QSignalSpy columnsAboutToBeRemoveSpy(model, &QAbstractItemModel::columnsAboutToBeRemoved);
+ QVERIFY(columnsAboutToBeRemoveSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldRowCount = proxy.rowCount(proxyParent);
+ const int oldColCount = model->columnCount(sourceParent);
+ const QVariant expectedNewVal = proxy.index(2, 0, proxyParent).data();
+ QVERIFY(proxy.removeRow(1, proxyParent));
+ QCOMPARE(proxy.rowCount(proxyParent), oldRowCount - 1);
+ QCOMPARE(model->columnCount(sourceParent), oldColCount - 1);
+ QCOMPARE(proxy.index(1, 0, proxyParent).data(), expectedNewVal);
+ QCOMPARE(model->index(0, 1, sourceParent).data(), expectedNewVal);
+ QCOMPARE(columnsRemoveSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeRemoveSpy.size(), 1);
+ QCOMPARE(rowsRemoveSpy.size(), 1);
+ QCOMPARE(rowsAboutToBeRemoveSpy.size(), 1);
+ for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(),
+ columnsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsRemoveSpy.takeFirst(),
+ rowsAboutToBeRemoveSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::insertRowProxy_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::newRow("Table") << createTableModel(this) << true;
+ QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true;
+ QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false;
+}
+
+void tst_QTransposeProxyModel::insertRowProxy()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy rowsInsertSpy(&proxy, &QAbstractItemModel::rowsInserted);
+ QVERIFY(rowsInsertSpy.isValid());
+ QSignalSpy rowsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::rowsAboutToBeInserted);
+ QVERIFY(rowsAboutToBeInsertSpy.isValid());
+ QSignalSpy columnsInsertSpy(model, &QAbstractItemModel::columnsInserted);
+ QVERIFY(columnsInsertSpy.isValid());
+ QSignalSpy columnsAboutToBeInsertSpy(model, &QAbstractItemModel::columnsAboutToBeInserted);
+ QVERIFY(columnsAboutToBeInsertSpy.isValid());
+ proxy.setSourceModel(model);
+ const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1);
+ const QModelIndex sourceParent = proxy.mapToSource(proxyParent);
+ const int oldRowCount = proxy.rowCount(proxyParent);
+ const int oldColCount = model->columnCount(sourceParent);
+ QVERIFY(proxy.insertRow(1, proxyParent));
+ QCOMPARE(proxy.rowCount(proxyParent), oldRowCount + 1);
+ QCOMPARE(model->columnCount(sourceParent), oldColCount + 1);
+ QVERIFY(proxy.index(1, 0, proxyParent).data().isNull());
+ QVERIFY(model->index(0, 1, sourceParent).data().isNull());
+ QCOMPARE(columnsInsertSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeInsertSpy.size(), 1);
+ QCOMPARE(rowsInsertSpy.size(), 1);
+ QCOMPARE(rowsAboutToBeInsertSpy.size(), 1);
+ for (const auto &spyArgs : {columnsInsertSpy.takeFirst(),
+ columnsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), sourceParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ for (const auto &spyArgs : {rowsInsertSpy.takeFirst(),
+ rowsAboutToBeInsertSpy.takeFirst()}) {
+ QCOMPARE(spyArgs.at(0).value<QModelIndex>(), proxyParent);
+ QCOMPARE(spyArgs.at(1).toInt(), 1);
+ QCOMPARE(spyArgs.at(2).toInt(), 1);
+ }
+ delete model;
+}
+
+void tst_QTransposeProxyModel::headerData()
+{
+ QStandardItemModel model;
+ model.insertRows(0, 3);
+ model.insertColumns(0, 5);
+ for (int i = 0; i < model.rowCount(); ++i)
+ model.setHeaderData(i, Qt::Horizontal, QChar('A' + i));
+ for (int i = 1; i <= model.columnCount(); ++i)
+ model.setHeaderData(i, Qt::Vertical, i);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ for (int i = 0; i < model.rowCount(); ++i)
+ QCOMPARE(model.headerData(i, Qt::Horizontal), proxy.headerData(i, Qt::Vertical));
+ for (int i = 0; i < model.columnCount(); ++i)
+ QCOMPARE(model.headerData(i, Qt::Vertical), proxy.headerData(i, Qt::Horizontal));
+}
+
+void tst_QTransposeProxyModel::setHeaderData()
+{
+ QStandardItemModel model;
+ model.insertRows(0, 3);
+ model.insertColumns(0, 5);
+ for (int i = 0; i < model.rowCount(); ++i)
+ model.setHeaderData(i, Qt::Horizontal, QChar('A' + i));
+ for (int i = 1; i <= model.columnCount(); ++i)
+ model.setHeaderData(i, Qt::Vertical, i);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.setHeaderData(1, Qt::Horizontal, 99));
+ QCOMPARE(model.headerData(1, Qt::Vertical).toInt(), 99);
+ QVERIFY(proxy.setHeaderData(1, Qt::Vertical, QChar('Z')));
+ QCOMPARE(model.headerData(1, Qt::Horizontal).toChar(), QChar('Z'));
+}
+
+void tst_QTransposeProxyModel::span()
+{
+ class SpanModel : public QStandardItemModel
+ {
+ Q_DISABLE_COPY(SpanModel)
+ public:
+ SpanModel(int rows, int columns, QObject *parent = nullptr)
+ : QStandardItemModel(rows, columns, parent)
+ {}
+ QSize span(const QModelIndex &index) const override
+ {
+ Q_UNUSED(index);
+ return QSize(2, 1);
+ }
+ };
+ SpanModel model(3, 5);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ QCOMPARE(proxy.span(proxy.index(0, 0)), QSize(1, 2));
+}
+
+void tst_QTransposeProxyModel::itemData()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QMap<int, QVariant> itmData = proxy.itemData(proxy.index(0, 1));
+ QCOMPARE(itmData.value(Qt::DisplayRole).toString(), QStringLiteral("1,0"));
+ QCOMPARE(itmData.value(Qt::UserRole).toInt(), 1);
+ QCOMPARE(itmData.value(Qt::UserRole + 1).toInt(), 0);
+ itmData = proxy.itemData(proxy.index(1, 2, proxy.index(0, 1)));
+ QCOMPARE(itmData.value(Qt::DisplayRole).toString(), QStringLiteral("1,0,2,1"));
+ QCOMPARE(itmData.value(Qt::UserRole).toInt(), 1);
+ QCOMPARE(itmData.value(Qt::UserRole + 1).toInt(), 0);
+ QCOMPARE(itmData.value(Qt::UserRole + 2).toInt(), 2);
+ QCOMPARE(itmData.value(Qt::UserRole + 3).toInt(), 1);
+ QVERIFY(proxy.itemData(QModelIndex()).isEmpty());
+ delete model;
+}
+
+void tst_QTransposeProxyModel::setItemData()
+{
+ QAbstractItemModel *model = createTreeModel(this);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QSignalSpy sourceDataChangeSpy(model, &QAbstractItemModel::dataChanged);
+ QVERIFY(sourceDataChangeSpy.isValid());
+ QSignalSpy proxyDataChangeSpy(&proxy, &QAbstractItemModel::dataChanged);
+ QVERIFY(proxyDataChangeSpy.isValid());
+ const QMap<int, QVariant> itmData = {
+ std::make_pair<int, QVariant>(Qt::DisplayRole, QStringLiteral("Test")),
+ std::make_pair<int, QVariant>(Qt::UserRole, 88),
+ std::make_pair<int, QVariant>(Qt::UserRole + 1, 99),
+ };
+ QModelIndex idx = proxy.index(0, 1);
+ QVERIFY(proxy.setItemData(idx, itmData));
+ QCOMPARE(idx.data(Qt::DisplayRole).toString(), QStringLiteral("Test"));
+ QCOMPARE(idx.data(Qt::UserRole).toInt(), 88);
+ QCOMPARE(idx.data(Qt::UserRole + 1).toInt(), 99);
+ QCOMPARE(sourceDataChangeSpy.size(), 1);
+ QCOMPARE(proxyDataChangeSpy.size(), 1);
+ auto signalData = proxyDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), idx);
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), idx);
+ const QList<int> expectedRoles{Qt::DisplayRole, Qt::UserRole, Qt::EditRole, Qt::UserRole + 1};
+ QList<int> receivedRoles = signalData.at(2).value<QList<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ signalData = sourceDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), proxy.mapToSource(idx));
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), proxy.mapToSource(idx));
+ receivedRoles = signalData.at(2).value<QList<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ idx = proxy.index(1, 2, proxy.index(0, 1));
+ QVERIFY(proxy.setItemData(idx, itmData));
+ QCOMPARE(idx.data(Qt::DisplayRole).toString(), QStringLiteral("Test"));
+ QCOMPARE(idx.data(Qt::UserRole).toInt(), 88);
+ QCOMPARE(idx.data(Qt::UserRole + 1).toInt(), 99);
+ QCOMPARE(idx.data(Qt::UserRole + 2).toInt(), 2);
+ QCOMPARE(idx.data(Qt::UserRole + 3).toInt(), 1);
+ QCOMPARE(sourceDataChangeSpy.size(), 1);
+ QCOMPARE(proxyDataChangeSpy.size(), 1);
+ signalData = proxyDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), idx);
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), idx);
+ receivedRoles = signalData.at(2).value<QList<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ signalData = sourceDataChangeSpy.takeFirst();
+ QCOMPARE(signalData.at(0).value<QModelIndex>(), proxy.mapToSource(idx));
+ QCOMPARE(signalData.at(1).value<QModelIndex>(), proxy.mapToSource(idx));
+ receivedRoles = signalData.at(2).value<QList<int> >();
+ QCOMPARE(receivedRoles.size(), expectedRoles.size());
+ for (int role : expectedRoles)
+ QVERIFY(receivedRoles.contains(role));
+ QVERIFY(!proxy.setItemData(QModelIndex(), itmData));
+ delete model;
+}
+
+void tst_QTransposeProxyModel::moveRowsBase()
+{
+ QStringListModel model{QStringList{"A", "B", "C", "D"}};
+ QTransposeProxyModel proxy;
+ QSignalSpy columnsMoveSpy(&proxy, &QAbstractItemModel::columnsMoved);
+ QVERIFY(columnsMoveSpy.isValid());
+ QSignalSpy columnsAboutToBeMoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved);
+ QVERIFY(columnsAboutToBeMoveSpy.isValid());
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(&model);
+ const QStringList expectedNewVal = {"B", "A", "C", "D"};
+ QVERIFY(model.moveRows(QModelIndex(), 0, 1, QModelIndex(), 2));
+ for (int i = 0; i < expectedNewVal.size(); ++i)
+ QCOMPARE(proxy.index(0, i).data(), expectedNewVal.at(i));
+ QCOMPARE(columnsMoveSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeMoveSpy.size(), 1);
+ for (const auto &spyArgs : {columnsMoveSpy.takeFirst(),
+ columnsAboutToBeMoveSpy.takeFirst()}) {
+ QVERIFY(!spyArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(spyArgs.at(1).toInt(), 0);
+ QCOMPARE(spyArgs.at(2).toInt(), 0);
+ QVERIFY(!spyArgs.at(3).value<QModelIndex>().isValid());
+ QCOMPARE(spyArgs.at(4).toInt(), 2);
+ }
+}
+
+void tst_QTransposeProxyModel::moveColumnsProxy()
+{
+ QStringListModel model{QStringList{"A", "B", "C", "D"}};
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ QSignalSpy columnsMoveSpy(&proxy, &QAbstractItemModel::columnsMoved);
+ QVERIFY(columnsMoveSpy.isValid());
+ QSignalSpy columnsAboutToBeMoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved);
+ QVERIFY(columnsAboutToBeMoveSpy.isValid());
+ QSignalSpy rowsMoveSpy(&model, &QAbstractItemModel::rowsMoved);
+ QVERIFY(rowsMoveSpy.isValid());
+ QSignalSpy rowsAboutToBeMoveSpy(&model, &QAbstractItemModel::rowsAboutToBeMoved);
+ QVERIFY(rowsAboutToBeMoveSpy.isValid());
+ proxy.setSourceModel(&model);
+ const QStringList expectedNewVal = {"B", "A", "C", "D"};
+ QVERIFY(proxy.moveColumns(QModelIndex(), 0, 1, QModelIndex(), 2));
+ for (int i = 0; i < expectedNewVal.size(); ++i)
+ QCOMPARE(proxy.index(0, i).data(), expectedNewVal.at(i));
+ for (int i = 0; i < expectedNewVal.size(); ++i)
+ QCOMPARE(model.index(i, 0).data(), expectedNewVal.at(i));
+ QCOMPARE(columnsMoveSpy.size(), 1);
+ QCOMPARE(columnsAboutToBeMoveSpy.size(), 1);
+ QCOMPARE(rowsMoveSpy.size(), 1);
+ QCOMPARE(rowsAboutToBeMoveSpy.size(), 1);
+ for (const auto &spyArgs : {columnsMoveSpy.takeFirst(),
+ columnsAboutToBeMoveSpy.takeFirst(),
+ rowsMoveSpy.takeFirst(),rowsAboutToBeMoveSpy.takeFirst()}) {
+ QVERIFY(!spyArgs.at(0).value<QModelIndex>().isValid());
+ QCOMPARE(spyArgs.at(1).toInt(), 0);
+ QCOMPARE(spyArgs.at(2).toInt(), 0);
+ QVERIFY(!spyArgs.at(3).value<QModelIndex>().isValid());
+ }
+}
+
+void tst_QTransposeProxyModel::setData_data()
+{
+ QTest::addColumn<QAbstractItemModel *>("model");
+ QTest::addColumn<bool>("rootItem");
+ QTest::addColumn<bool>("viaProxy");
+ QTest::newRow("List_via_Base") << createListModel(this) << true << false;
+ QTest::newRow("Table_via_Base") << createTableModel(this) << true << false;
+ QTest::newRow("Tree_via_Base_Root_Item") << createTreeModel(this) << true << false;
+ QTest::newRow("Tree_via_Base_Child_Item") << createTreeModel(this) << false << false;
+ QTest::newRow("List_via_Proxy") << createListModel(this) << true << true;
+ QTest::newRow("Table_via_Proxy") << createTableModel(this) << true << true;
+ QTest::newRow("Tree_via_Proxy_Root_Item") << createTreeModel(this) << true << true;
+ QTest::newRow("Tree_via_Proxy_Child_Item") << createTreeModel(this) << false << true;
+}
+
+void tst_QTransposeProxyModel::setData()
+{
+ QFETCH(QAbstractItemModel *, model);
+ QFETCH(bool, rootItem);
+ QFETCH(bool, viaProxy);
+ QTransposeProxyModel proxy;
+ new QAbstractItemModelTester(&proxy, &proxy);
+ proxy.setSourceModel(model);
+ QSignalSpy sourceDataChangeSpy(model, &QAbstractItemModel::dataChanged);
+ QVERIFY(sourceDataChangeSpy.isValid());
+ QSignalSpy proxyDataChangeSpy(&proxy, &QAbstractItemModel::dataChanged);
+ QVERIFY(proxyDataChangeSpy.isValid());
+ const QString testData = QStringLiteral("TestingSetData");
+ if (viaProxy) {
+ const QModelIndex parIdx = rootItem ? QModelIndex() : proxy.index(0, 1);
+ QVERIFY(proxy.setData(proxy.index(0, 1, parIdx), testData));
+ QCOMPARE(model->index(1, 0, proxy.mapToSource(parIdx)).data().toString(), testData);
+ } else {
+ const QModelIndex parIdx = rootItem ? QModelIndex() : model->index(1, 0);
+ QVERIFY(model->setData(model->index(1, 0, parIdx), testData));
+ QCOMPARE(proxy.index(0, 1, proxy.mapFromSource(parIdx)).data().toString(), testData);
+ }
+ QCOMPARE(sourceDataChangeSpy.size(), 1);
+ QCOMPARE(proxyDataChangeSpy.size(), 1);
+ delete model;
+}
+
+QTEST_GUILESS_MAIN(tst_QTransposeProxyModel)
+
+#include "tst_qtransposeproxymodel.moc"
diff --git a/tests/auto/corelib/kernel/CMakeLists.txt b/tests/auto/corelib/kernel/CMakeLists.txt
new file mode 100644
index 0000000000..c2feb38641
--- /dev/null
+++ b/tests/auto/corelib/kernel/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qapplicationstatic)
+add_subdirectory(qchronotimer)
+add_subdirectory(qcoreapplication)
+add_subdirectory(qdeadlinetimer)
+add_subdirectory(qelapsedtimer)
+add_subdirectory(qmath)
+add_subdirectory(qmetacontainer)
+add_subdirectory(qmetaobject)
+add_subdirectory(qmetaobjectbuilder)
+add_subdirectory(qmetamethod)
+add_subdirectory(qmetaproperty)
+add_subdirectory(qmetaenum)
+add_subdirectory(qsignalblocker)
+add_subdirectory(qsignalmapper)
+add_subdirectory(qtimer)
+add_subdirectory(qtranslator)
+# QTBUG-88135
+if(NOT ANDROID)
+ add_subdirectory(qeventdispatcher)
+endif()
+if(TARGET Qt::Network)
+ add_subdirectory(qeventloop)
+endif()
+if(TARGET Qt::Gui)
+ add_subdirectory(qmetatype)
+ add_subdirectory(qmimedata)
+ add_subdirectory(qpointer)
+ add_subdirectory(qvariant)
+endif()
+if(TARGET Qt::Network AND NOT ANDROID AND NOT UIKIT)
+ add_subdirectory(qobject)
+endif()
+if(QT_FEATURE_private_tests AND TARGET Qt::Network)
+ add_subdirectory(qsocketnotifier)
+endif()
+if(WIN32)
+ add_subdirectory(qwineventnotifier)
+ add_subdirectory(qwinregistrykey)
+endif()
+if(QT_FEATURE_permissions)
+ add_subdirectory(qpermission)
+endif()
+if(QT_FEATURE_private_tests)
+ add_subdirectory(qproperty)
+endif()
+if(ANDROID)
+ add_subdirectory(qjnienvironment)
+ add_subdirectory(qjniobject)
+ add_subdirectory(qjnitypes)
+ add_subdirectory(qjniarray)
+endif()
diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro
deleted file mode 100644
index 09074a9e8a..0000000000
--- a/tests/auto/corelib/kernel/kernel.pro
+++ /dev/null
@@ -1,46 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qcoreapplication \
- qdeadlinetimer \
- qelapsedtimer \
- qeventdispatcher \
- qeventloop \
- qmath \
- qmetaobject \
- qmetaobjectbuilder \
- qmetamethod \
- qmetaproperty \
- qmetatype \
- qmetaenum \
- qmimedata \
- qobject \
- qpointer \
- qsharedmemory \
- qsignalblocker \
- qsignalmapper \
- qsocketnotifier \
- qsystemsemaphore \
- qtimer \
- qtranslator \
- qvariant \
- qwineventnotifier
-
-!qtHaveModule(gui): SUBDIRS -= \
- qmimedata
-
-!qtHaveModule(network): SUBDIRS -= \
- qeventloop \
- qobject \
- qsocketnotifier
-
-!qtConfig(private_tests): SUBDIRS -= \
- qsocketnotifier \
- qsharedmemory
-
-# This test is only applicable on Windows
-!win32*|winrt: SUBDIRS -= qwineventnotifier
-
-android|uikit: SUBDIRS -= qobject qsharedmemory qsystemsemaphore
-
-!qtConfig(systemsemaphore): SUBDIRS -= \
- qsystemsemaphore
diff --git a/tests/auto/corelib/kernel/qapplicationstatic/CMakeLists.txt b/tests/auto/corelib/kernel/qapplicationstatic/CMakeLists.txt
new file mode 100644
index 0000000000..9332b6ecd0
--- /dev/null
+++ b/tests/auto/corelib/kernel/qapplicationstatic/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qapplicationstatic Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qapplicationstatic LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qapplicationstatic
+ SOURCES
+ tst_qapplicationstatic.cpp
+ )
diff --git a/tests/auto/corelib/kernel/qapplicationstatic/tst_qapplicationstatic.cpp b/tests/auto/corelib/kernel/qapplicationstatic/tst_qapplicationstatic.cpp
new file mode 100644
index 0000000000..dd9a415a52
--- /dev/null
+++ b/tests/auto/corelib/kernel/qapplicationstatic/tst_qapplicationstatic.cpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QPointer>
+#include "QtCore/qapplicationstatic.h"
+
+Q_APPLICATION_STATIC(QObject, tstObject)
+
+class tst_qapplicationstatic : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testCreateMultipleApplications() const;
+};
+
+void tst_qapplicationstatic::testCreateMultipleApplications() const
+{
+ for (int i = 0; i < 5; i++) {
+ int argc = 1;
+ char *argv[] = { (char *)"tst_qapplicationstatic" };
+ auto app = new QCoreApplication(argc, argv);
+
+ QVERIFY(tstObject);
+
+ QPointer<QObject> tstObjectPointer(tstObject);
+ QVERIFY(tstObjectPointer.get());
+
+ QVERIFY2(tstObject->objectName().isEmpty(), "Got QObject from previous iteration, not correctly recreated");
+ tstObject->setObjectName(QStringLiteral("tstObject"));
+ QVERIFY(!tstObject->objectName().isEmpty());
+
+ delete app;
+ QVERIFY2(!tstObjectPointer.get(), "QObject wasn't destroyed on QCoreApplication destruction");
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_qapplicationstatic)
+#include "tst_qapplicationstatic.moc"
diff --git a/tests/auto/corelib/kernel/qchronotimer/.gitignore b/tests/auto/corelib/kernel/qchronotimer/.gitignore
new file mode 100644
index 0000000000..254f7a0281
--- /dev/null
+++ b/tests/auto/corelib/kernel/qchronotimer/.gitignore
@@ -0,0 +1 @@
+tst_qchronotimer
diff --git a/tests/auto/corelib/kernel/qchronotimer/CMakeLists.txt b/tests/auto/corelib/kernel/qchronotimer/CMakeLists.txt
new file mode 100644
index 0000000000..43164858c5
--- /dev/null
+++ b/tests/auto/corelib/kernel/qchronotimer/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qchronotimer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if (NOT QT_FEATURE_thread)
+ return()
+endif()
+
+function(addChronoTimerTest test)
+ qt_internal_add_test(${test}
+ SOURCES
+ tst_qchronotimer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+ )
+endfunction()
+
+addChronoTimerTest(tst_qchronotimer)
+
+if(QT_FEATURE_glib AND UNIX)
+ addChronoTimerTest(tst_qchronotimer_no_glib)
+ qt_internal_extend_target(tst_qchronotimer_no_glib
+ DEFINES
+ DISABLE_GLIB
+ tst_QChronoTimer=tst_QChronoTimer_no_glib # Class name in the unittest
+ )
+endif()
diff --git a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp
new file mode 100644
index 0000000000..62c402ae24
--- /dev/null
+++ b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp
@@ -0,0 +1,1266 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifdef QT_GUI_LIB
+# include <QtGui/QGuiApplication>
+#else
+# include <QtCore/QCoreApplication>
+#endif
+
+#include <QtCore/private/qglobal_p.h>
+#include <QTest>
+#include <QSignalSpy>
+#include <QtTest/private/qpropertytesthelper_p.h>
+
+#include <qbasictimer.h>
+#include <qchronotimer.h>
+#include <qthread.h>
+#include <qtimer.h>
+#include <qelapsedtimer.h>
+#include <qproperty.h>
+
+#if defined Q_OS_UNIX
+#include <unistd.h>
+#endif
+
+using namespace std::chrono_literals;
+
+#ifdef DISABLE_GLIB
+static bool glibDisabled = []() {
+ qputenv("QT_NO_GLIB", "1");
+ return true;
+}();
+#endif
+
+class tst_QChronoTimer : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void zeroTimer();
+ void singleShotTimeout(); // Non-static singleShot()
+ void timeout();
+ void sequentialTimers_data();
+ void sequentialTimers();
+ void remainingTime();
+ void remainingTimeInitial_data();
+ void remainingTimeInitial();
+ void remainingTimeDuringActivation_data();
+ void remainingTimeDuringActivation();
+ void basic_chrono();
+ void livelock_data();
+ void livelock();
+ void timerInfiniteRecursion_data();
+ void timerInfiniteRecursion();
+ void recurringTimer_data();
+ void recurringTimer();
+ void deleteLaterOnQChronoTimer(); // long name, don't want to shadow QObject::deleteLater()
+ void moveToThread();
+ void restartedTimerFiresTooSoon();
+ void timerFiresOnlyOncePerProcessEvents_data();
+ void timerFiresOnlyOncePerProcessEvents();
+ void timerIdPersistsAfterThreadExit();
+ void cancelLongTimer();
+ void recurseOnTimeoutAndStopTimer();
+ void timerOrder();
+ void timerOrder_data();
+ void timerOrderBackgroundThread();
+ void timerOrderBackgroundThread_data() { timerOrder_data(); }
+ void timerPrecision();
+
+ void dontBlockEvents();
+ void postedEventsShouldNotStarveTimers();
+ void callOnTimeout();
+
+ void bindToTimer();
+ void bindTimer();
+ void automatedBindingTests();
+
+ void negativeInterval();
+};
+
+void tst_QChronoTimer::zeroTimer()
+{
+ QChronoTimer timer;
+ QVERIFY(!timer.isSingleShot());
+ timer.setInterval(0ns);
+ timer.setSingleShot(true);
+ QVERIFY(timer.isSingleShot());
+
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ timer.start();
+
+ // Pass timeout to work round glib issue, see QTBUG-84291.
+ QCoreApplication::processEvents(QEventLoop::AllEvents, INT_MAX);
+
+ QCOMPARE(timeoutSpy.size(), 1);
+}
+
+void tst_QChronoTimer::singleShotTimeout()
+{
+ QChronoTimer timer;
+ QVERIFY(!timer.isSingleShot());
+ timer.setSingleShot(true);
+ QVERIFY(timer.isSingleShot());
+
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ timer.setInterval(100ms);
+ timer.start();
+
+ QVERIFY(timeoutSpy.wait(500ms));
+ QCOMPARE(timeoutSpy.size(), 1);
+ QTest::qWait(500ms);
+ QCOMPARE(timeoutSpy.size(), 1);
+}
+
+static constexpr auto Timeout_Interval = 200ms;
+
+void tst_QChronoTimer::timeout()
+{
+ QChronoTimer timer{100ms};
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ timer.start();
+
+ QCOMPARE(timeoutSpy.size(), 0);
+
+ QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.size() > 0, Timeout_Interval);
+ const qsizetype oldCount = timeoutSpy.size();
+
+ QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.size() > oldCount, Timeout_Interval);
+}
+
+void tst_QChronoTimer::sequentialTimers_data()
+{
+#ifdef Q_OS_WIN
+ QSKIP("The API used by QEventDispatcherWin32 doesn't respect the order");
+#endif
+ QTest::addColumn<QList<std::chrono::milliseconds>>("timeouts");
+ auto addRow = [](const QList<std::chrono::milliseconds> &l) {
+ Q_ASSERT_X(std::is_sorted(l.begin(), l.end()),
+ "tst_QChronoTimer", "input list must be sorted");
+ QByteArray name;
+ for (auto msec : l)
+ name += QByteArray::number(msec.count()) + ',';
+ name.chop(1);
+ QTest::addRow("%s", name.constData()) << l;
+ };
+ // PreciseTimers
+ addRow({0ms, 0ms, 0ms, 0ms, 0ms, 0ms});
+ addRow({0ms, 1ms, 2ms});
+ addRow({1ms, 1ms, 1ms, 2ms, 2ms, 2ms, 2ms});
+ addRow({1ms, 2ms, 3ms});
+ addRow({19ms, 19ms, 19ms});
+ // CoarseTimer for setinterval
+ addRow({20ms, 20ms, 20ms, 20ms, 20ms});
+ addRow({25ms, 25ms, 25ms, 25ms, 25ms, 25ms, 50ms});
+}
+
+void tst_QChronoTimer::sequentialTimers()
+{
+ QFETCH(const QList<std::chrono::milliseconds>, timeouts);
+ QByteArray result, expected;
+ std::vector<std::unique_ptr<QChronoTimer>> timers;
+ expected.resize(timeouts.size());
+ result.reserve(timeouts.size());
+ timers.reserve(timeouts.size());
+ for (int i = 0; i < timeouts.size(); ++i) {
+ auto timer = std::make_unique<QChronoTimer>(timeouts[i]);
+ timer->setSingleShot(true);
+
+ char c = 'A' + i;
+ expected[i] = c;
+ QObject::connect(timer.get(), &QChronoTimer::timeout, this, [&result, c = c]() {
+ result.append(c);
+ });
+ timers.push_back(std::move(timer));
+ }
+
+ // start the timers
+ for (auto &timer : timers)
+ timer->start();
+
+ QTestEventLoop::instance().enterLoop(timeouts.last() * 2 + 10ms);
+
+ QCOMPARE(result, expected);
+}
+
+void tst_QChronoTimer::remainingTime()
+{
+ QChronoTimer tested;
+ tested.setTimerType(Qt::PreciseTimer);
+
+ QChronoTimer tester;
+ tester.setTimerType(Qt::PreciseTimer);
+ tester.setSingleShot(true);
+
+ constexpr auto tested_interval = 200ms;
+ constexpr auto tester_interval = 50ms;
+ constexpr auto expectedRemainingTime = tested_interval - tester_interval;
+
+ int testIteration = 0;
+ const int desiredTestCount = 2;
+
+ // We let tested (which isn't a single-shot) run repeatedly, to verify
+ // it *does* repeat, and check that the single-shot tester, starting
+ // at the same time, does finish first each time, by about the right duration.
+ auto connection = QObject::connect(&tested, &QChronoTimer::timeout,
+ &tester, &QChronoTimer::start);
+
+ QObject::connect(&tester, &QChronoTimer::timeout, this, [&]() {
+ const std::chrono::nanoseconds remainingTime = tested.remainingTime();
+ // We expect that remainingTime is at most 150 and not overdue.
+ const bool remainingTimeInRange = remainingTime > 0ns
+ && remainingTime <= expectedRemainingTime;
+ if (remainingTimeInRange)
+ ++testIteration;
+ else
+ testIteration = desiredTestCount; // We are going to fail on QVERIFY2()
+ // below, so we don't want to iterate
+ // anymore and quickly exit the QTRY_...()
+ // with this failure.
+ if (testIteration == desiredTestCount)
+ QObject::disconnect(connection); // Last iteration, don't start tester again.
+ QVERIFY2(remainingTimeInRange, qPrintable("Remaining time "
+ + QByteArray::number(remainingTime.count()) + "ms outside expected range (0ns, "
+ + QByteArray::number(expectedRemainingTime.count()) + "ms]"));
+ });
+
+ tested.setInterval(tested_interval);
+ tested.start();
+ tester.setInterval(tester_interval);
+ tester.start(); // Start tester for the 1st time.
+
+ // Test it desiredTestCount times, give it reasonable amount of time
+ // (twice as much as needed).
+ const auto tryTimeout = tested_interval * desiredTestCount * 2;
+ QTRY_COMPARE_WITH_TIMEOUT(testIteration, desiredTestCount, tryTimeout);
+}
+
+void tst_QChronoTimer::remainingTimeInitial_data()
+{
+ using namespace std::chrono;
+
+ QTest::addColumn<nanoseconds>("startTimeNs");
+ QTest::addColumn<Qt::TimerType>("timerType");
+
+ QTest::addRow("precisetiemr-0ns") << 0ns << Qt::PreciseTimer;
+ QTest::addRow("precisetimer-1ms") << nanoseconds{1ms} << Qt::PreciseTimer;
+ QTest::addRow("precisetimer-10ms") <<nanoseconds{10ms} << Qt::PreciseTimer;
+
+ QTest::addRow("coarsetimer-0ns") << 0ns << Qt::CoarseTimer;
+ QTest::addRow("coarsetimer-1ms") << nanoseconds{1ms} << Qt::CoarseTimer;
+ QTest::addRow("coarsetimer-10ms") << nanoseconds{10ms} << Qt::CoarseTimer;
+}
+
+void tst_QChronoTimer::remainingTimeInitial()
+{
+ QFETCH(std::chrono::nanoseconds, startTimeNs);
+ QFETCH(Qt::TimerType, timerType);
+
+ QChronoTimer timer;
+ QCOMPARE(timer.timerType(), Qt::CoarseTimer);
+ timer.setTimerType(timerType);
+ QCOMPARE(timer.timerType(), timerType);
+ timer.setInterval(startTimeNs);
+ timer.start();
+
+ const std::chrono::nanoseconds rt = timer.remainingTime();
+ QCOMPARE_GE(rt, 0ns);
+ QCOMPARE_LE(rt, startTimeNs);
+}
+
+void tst_QChronoTimer::remainingTimeDuringActivation_data()
+{
+ QTest::addColumn<bool>("singleShot");
+ QTest::newRow("repeating") << false;
+ QTest::newRow("single-shot") << true;
+}
+
+void tst_QChronoTimer::remainingTimeDuringActivation()
+{
+ QFETCH(bool, singleShot);
+
+ QChronoTimer timer;
+ timer.setSingleShot(singleShot);
+
+ auto remainingTime = 0ns; // not the expected value in either case
+ connect(&timer, &QChronoTimer::timeout, this, [&]() { remainingTime = timer.remainingTime(); });
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ // 20 ms is short enough and should not round down to 0 in any timer mode
+ constexpr auto timeout = 20ms;
+ timer.setInterval(timeout);
+ timer.start();
+
+ QVERIFY(timeoutSpy.wait());
+ if (singleShot)
+ QCOMPARE_LT(remainingTime, 0ns); // timer not running
+ else {
+ QCOMPARE_LE(remainingTime, timeout);
+ QCOMPARE_GT(remainingTime, 0ns);
+ }
+
+ if (!singleShot) {
+ // do it again - see QTBUG-46940
+ remainingTime = std::chrono::milliseconds::min();
+ QVERIFY(timeoutSpy.wait());
+ QCOMPARE_LE(remainingTime, timeout);
+ QCOMPARE_GT(remainingTime, 0ns);
+ }
+}
+
+namespace {
+ template <typename T>
+ auto to_ms(T t)
+ {
+ using namespace std::chrono;
+ return duration_cast<milliseconds>(t);
+ }
+} // unnamed namespace
+
+void tst_QChronoTimer::basic_chrono()
+{
+ // duplicates zeroTimer, singleShotTimeout, interval and remainingTime
+ using namespace std::chrono;
+ QChronoTimer timer;
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ timer.start();
+ QCOMPARE(timer.interval(), 0ns);
+ QCOMPARE(timer.remainingTime(), 0ns);
+
+ QCoreApplication::processEvents();
+
+ QCOMPARE(timeoutSpy.size(), 1);
+
+ timeoutSpy.clear();
+ timer.setInterval(100ms);
+ timer.start();
+ QCOMPARE(timeoutSpy.size(), 0);
+
+ QVERIFY(timeoutSpy.wait(Timeout_Interval));
+ QVERIFY(timeoutSpy.size() > 0);
+ const qsizetype oldCount = timeoutSpy.size();
+
+ QVERIFY(timeoutSpy.wait(Timeout_Interval));
+ QVERIFY(timeoutSpy.size() > oldCount);
+
+ timeoutSpy.clear();
+ timer.setInterval(200ms);
+ timer.start();
+ QCOMPARE(timer.interval(), 200ms);
+ QTest::qWait(50ms);
+ QCOMPARE(timeoutSpy.size(), 0);
+
+ nanoseconds rt = timer.remainingTime();
+ QCOMPARE_GE(rt, 50ms);
+ QCOMPARE_LE(rt, 200ms);
+
+ timeoutSpy.clear();
+ timer.setSingleShot(true);
+ timer.setInterval(100ms);
+ timer.start();
+ QVERIFY(timeoutSpy.wait(Timeout_Interval));
+ QCOMPARE(timeoutSpy.size(), 1);
+ QTest::qWait(500ms);
+ QCOMPARE(timeoutSpy.size(), 1);
+}
+
+void tst_QChronoTimer::livelock_data()
+{
+ QTest::addColumn<std::chrono::nanoseconds>("interval");
+ QTest::newRow("zero-timer") << 0ns;
+ QTest::newRow("non-zero-timer") << std::chrono::nanoseconds{1ms};
+ QTest::newRow("longer-than-sleep") << std::chrono::nanoseconds{20ms};
+}
+
+/*!
+ *
+ * DO NOT "FIX" THIS TEST! it is written like this for a reason, do
+ * not *change it without first dicussing it with its maintainers.
+ *
+*/
+class LiveLockTester : public QObject
+{
+ static constexpr QEvent::Type PostEventType = static_cast<QEvent::Type>(4002);
+public:
+ LiveLockTester(std::chrono::nanoseconds i)
+ : interval(i)
+ {
+ firstTimerId = startTimer(interval);
+ extraTimerId = startTimer(interval + 80ms);
+ secondTimerId = -1; // started later
+ }
+
+ bool event(QEvent *e) override
+ {
+ if (e->type() == PostEventType) {
+ // got the posted event
+ if (timeoutsForFirst == 1 && timeoutsForSecond == 0)
+ postEventAtRightTime = true;
+ return true;
+ }
+ return QObject::event(e);
+ }
+
+ void timerEvent(QTimerEvent *te) override
+ {
+ if (te->timerId() == firstTimerId) {
+ if (++timeoutsForFirst == 1) {
+ killTimer(extraTimerId);
+ extraTimerId = -1;
+ QCoreApplication::postEvent(this, new QEvent(PostEventType));
+ secondTimerId = startTimer(interval);
+ }
+ } else if (te->timerId() == secondTimerId) {
+ ++timeoutsForSecond;
+ } else if (te->timerId() == extraTimerId) {
+ ++timeoutsForExtra;
+ }
+
+ // sleep for 2ms
+ QTest::qSleep(2);
+ killTimer(te->timerId());
+ }
+
+ const std::chrono::nanoseconds interval;
+ int firstTimerId = -1;
+ int secondTimerId = -1;
+ int extraTimerId = -1;
+ int timeoutsForFirst = 0;
+ int timeoutsForExtra = 0;
+ int timeoutsForSecond = 0;
+ bool postEventAtRightTime = false;
+};
+
+void tst_QChronoTimer::livelock()
+{
+ /*
+ New timers created in timer event handlers should not be sent
+ until the next iteration of the eventloop. Note: this test
+ depends on the fact that we send posted events before timer
+ events (since new posted events are not sent until the next
+ iteration of the eventloop either).
+ */
+ QFETCH(std::chrono::nanoseconds, interval);
+ LiveLockTester tester(interval);
+ QTest::qWait(180ms); // we have to use wait here, since we're testing timers with a non-zero timeout
+ QTRY_COMPARE(tester.timeoutsForFirst, 1);
+ QCOMPARE(tester.timeoutsForExtra, 0);
+ QTRY_COMPARE(tester.timeoutsForSecond, 1);
+ QVERIFY(tester.postEventAtRightTime);
+}
+
+class TimerInfiniteRecursionObject : public QObject
+{
+public:
+ bool inTimerEvent = false;
+ bool timerEventRecursed = false;
+ std::chrono::nanoseconds interval;
+
+ TimerInfiniteRecursionObject(std::chrono::nanoseconds interval)
+ : interval(interval)
+ { }
+
+ void timerEvent(QTimerEvent *timerEvent) override
+ {
+ timerEventRecursed = inTimerEvent;
+ if (timerEventRecursed) {
+ // bug detected!
+ return;
+ }
+
+ inTimerEvent = true;
+
+ QEventLoop eventLoop;
+ QChronoTimer::singleShot(std::max<std::chrono::nanoseconds>(100ms, interval * 2),
+ &eventLoop, &QEventLoop::quit);
+ eventLoop.exec();
+
+ inTimerEvent = false;
+
+ killTimer(timerEvent->timerId());
+ }
+};
+
+void tst_QChronoTimer::timerInfiniteRecursion_data()
+{
+ QTest::addColumn<std::chrono::nanoseconds>("interval");
+ QTest::newRow("zero timer") << 0ns;
+ QTest::newRow("non-zero timer") << std::chrono::nanoseconds{1ms};
+ QTest::newRow("10ms timer") << std::chrono::nanoseconds{10ms};
+ QTest::newRow("11ms timer") << std::chrono::nanoseconds{11ms};
+ QTest::newRow("100ms timer") << std::chrono::nanoseconds{100ms};
+ QTest::newRow("1s timer") << std::chrono::nanoseconds{1000ms};
+}
+
+
+void tst_QChronoTimer::timerInfiniteRecursion()
+{
+ QFETCH(std::chrono::nanoseconds, interval);
+ TimerInfiniteRecursionObject object(interval);
+ (void) object.startTimer(interval);
+
+ QEventLoop eventLoop;
+ QChronoTimer::singleShot(std::max<std::chrono::nanoseconds>(100ms, interval * 2), &eventLoop,
+ &QEventLoop::quit);
+ eventLoop.exec();
+
+ QVERIFY(!object.timerEventRecursed);
+}
+
+class RecurringTimerObject : public QObject
+{
+Q_OBJECT
+public:
+ int times;
+ int target;
+ bool recurse;
+
+ RecurringTimerObject(int target)
+ : times(0), target(target), recurse(false)
+ { }
+
+ void timerEvent(QTimerEvent *timerEvent) override
+ {
+ if (++times == target) {
+ killTimer(timerEvent->timerId());
+ Q_EMIT done();
+ } if (recurse) {
+ QEventLoop eventLoop;
+ QChronoTimer::singleShot(100ms, &eventLoop, &QEventLoop::quit);
+ eventLoop.exec();
+ }
+ }
+
+signals:
+ void done();
+};
+
+void tst_QChronoTimer::recurringTimer_data()
+{
+ QTest::addColumn<std::chrono::nanoseconds>("interval");
+ QTest::addColumn<bool>("recurse");
+ // make sure that eventloop recursion doesn't affect timer recurrence
+ QTest::newRow("zero timer, don't recurse") << 0ns << false;
+ QTest::newRow("zero timer, recurse") << 0ns << true;
+ QTest::newRow("non-zero timer, don't recurse") << std::chrono::nanoseconds{1ms} << false;
+ QTest::newRow("non-zero timer, recurse") << std::chrono::nanoseconds{1ms} << true;
+}
+
+void tst_QChronoTimer::recurringTimer()
+{
+ const int target = 5;
+ QFETCH(std::chrono::nanoseconds, interval);
+ QFETCH(bool, recurse);
+
+ RecurringTimerObject object(target);
+ object.recurse = recurse;
+ QSignalSpy doneSpy(&object, &RecurringTimerObject::done);
+
+ (void) object.startTimer(interval);
+ QVERIFY(doneSpy.wait());
+
+ QCOMPARE(object.times, target);
+}
+
+void tst_QChronoTimer::deleteLaterOnQChronoTimer()
+{
+ QChronoTimer *timer = new QChronoTimer;
+ connect(timer, &QChronoTimer::timeout, timer, &QObject::deleteLater);
+ QSignalSpy destroyedSpy(timer, &QObject::destroyed);
+ timer->setInterval(1ms);
+ timer->setSingleShot(true);
+ timer->start();
+ QPointer<QChronoTimer> pointer = timer;
+ QVERIFY(destroyedSpy.wait());
+ QVERIFY(pointer.isNull());
+}
+
+namespace {
+int operator&(Qt::TimerId id, int i) { return qToUnderlying(id) & i; }
+}
+
+static constexpr auto MoveToThread_Timeout = 200ms;
+static constexpr auto MoveToThread_Wait = 300ms;
+
+void tst_QChronoTimer::moveToThread()
+{
+#if defined(Q_OS_WIN32)
+ QSKIP("Does not work reliably on Windows :(");
+#elif defined(Q_OS_MACOS)
+ QSKIP("Does not work reliably on macOS 10.12+ (QTBUG-59679)");
+#endif
+ QChronoTimer timer1{MoveToThread_Timeout};
+ QChronoTimer timer2{MoveToThread_Timeout};
+ timer1.setSingleShot(true);
+ timer1.start();
+ timer2.start();
+ QVERIFY((timer1.id() & 0xffffff) != (timer2.id() & 0xffffff));
+ QThread tr;
+ timer1.moveToThread(&tr);
+ connect(&timer1, &QChronoTimer::timeout, &tr, &QThread::quit);
+ tr.start();
+ QChronoTimer ti3{MoveToThread_Timeout};
+ ti3.start();
+ QVERIFY((ti3.id() & 0xffffff) != (timer2.id() & 0xffffff));
+ QVERIFY((ti3.id() & 0xffffff) != (timer1.id() & 0xffffff));
+ QTest::qWait(MoveToThread_Wait);
+ QVERIFY(tr.wait());
+ timer2.stop();
+ QChronoTimer ti4{MoveToThread_Timeout};
+ ti4.start();
+ ti3.stop();
+ timer2.setInterval(MoveToThread_Timeout);
+ timer2.start();
+ ti3.setInterval(MoveToThread_Timeout);
+ ti3.start();
+ QVERIFY((ti4.id() & 0xffffff) != (timer2.id() & 0xffffff));
+ QVERIFY((ti3.id() & 0xffffff) != (timer2.id() & 0xffffff));
+ QVERIFY((ti3.id() & 0xffffff) != (timer1.id() & 0xffffff));
+}
+
+class RestartedTimerFiresTooSoonObject : public QObject
+{
+ Q_OBJECT
+
+public:
+ QBasicTimer m_timer;
+
+ std::chrono::milliseconds m_interval = 0ms;
+ QElapsedTimer m_elapsedTimer;
+ QEventLoop eventLoop;
+
+ RestartedTimerFiresTooSoonObject() = default;
+
+ void timerFired()
+ {
+ static std::chrono::milliseconds interval = 1s;
+
+ m_interval = interval;
+ m_elapsedTimer.start();
+ m_timer.start(interval, this);
+
+ // alternate between single-shot and 1 sec
+ interval = interval > 0ms ? 0ms : 1s;
+ }
+
+ void timerEvent(QTimerEvent* ev) override
+ {
+ if (ev->timerId() != m_timer.timerId())
+ return;
+
+ m_timer.stop();
+
+ std::chrono::nanoseconds elapsed = m_elapsedTimer.durationElapsed();
+
+ if (elapsed < m_interval / 2) {
+ // severely too early!
+ m_timer.stop();
+ eventLoop.exit(-1);
+ return;
+ }
+
+ timerFired();
+
+ // don't do this forever
+ static int count = 0;
+ if (count++ > 20) {
+ m_timer.stop();
+ eventLoop.quit();
+ return;
+ }
+ }
+};
+
+void tst_QChronoTimer::restartedTimerFiresTooSoon()
+{
+ RestartedTimerFiresTooSoonObject object;
+ object.timerFired();
+ QCOMPARE(object.eventLoop.exec(), 0);
+}
+
+class LongLastingSlotClass : public QObject
+{
+ Q_OBJECT
+
+public:
+ LongLastingSlotClass(QChronoTimer *timer) : timer(timer) { }
+
+public slots:
+ void longLastingSlot()
+ {
+ // Don't use QChronoTimer for this, because we are testing it.
+ QElapsedTimer control;
+ control.start();
+ while (control.durationElapsed() < 200ms) {
+ for (int c = 0; c < 100'000; c++) {} // Mindless looping.
+ }
+ if (++count >= 2) {
+ timer->stop();
+ }
+ }
+
+public:
+ int count = 0;
+ QChronoTimer *timer;
+};
+
+void tst_QChronoTimer::timerFiresOnlyOncePerProcessEvents_data()
+{
+ QTest::addColumn<std::chrono::nanoseconds>("interval");
+ QTest::newRow("zero-timer") << 0ns;
+ QTest::newRow("non-zero-timer") << std::chrono::nanoseconds{10ms};
+}
+
+void tst_QChronoTimer::timerFiresOnlyOncePerProcessEvents()
+{
+ QFETCH(std::chrono::nanoseconds, interval);
+
+ QChronoTimer t{interval};
+ LongLastingSlotClass longSlot(&t);
+ t.start();
+ connect(&t, &QChronoTimer::timeout, &longSlot, &LongLastingSlotClass::longLastingSlot);
+ // Loop because there may be other events pending.
+ while (longSlot.count == 0)
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
+
+ QCOMPARE(longSlot.count, 1);
+}
+
+class TimerIdPersistsAfterThreadExitThread : public QThread
+{
+public:
+ std::unique_ptr<QChronoTimer> timer;
+ Qt::TimerId timerId = Qt::TimerId::Invalid;
+ int returnValue = -1;
+
+ void run() override
+ {
+ QEventLoop eventLoop;
+ timer = std::make_unique<QChronoTimer>();
+ connect(timer.get(), &QChronoTimer::timeout, &eventLoop, &QEventLoop::quit);
+ timer->setInterval(100ms);
+ timer->start();
+ timerId = timer->id();
+ returnValue = eventLoop.exec();
+ }
+};
+
+void tst_QChronoTimer::timerIdPersistsAfterThreadExit()
+{
+ TimerIdPersistsAfterThreadExitThread thread;
+ thread.start();
+ QVERIFY(thread.wait(30s));
+ QCOMPARE(thread.returnValue, 0);
+
+ // even though the thread has exited, and the event dispatcher destroyed, the timer is still
+ // "active", meaning the timer id should NOT be reused (i.e. the event dispatcher should not
+ // have unregistered it)
+ int timerId = thread.startTimer(100ms);
+ QVERIFY((timerId & 0xffffff) != (thread.timerId & 0xffffff));
+}
+
+void tst_QChronoTimer::cancelLongTimer()
+{
+ QChronoTimer timer{1h};
+ timer.setSingleShot(true);
+ timer.start();
+ QCoreApplication::processEvents();
+ // If the timer completes immediately with an error, then this will fail
+ QVERIFY(timer.isActive());
+ timer.stop();
+ QVERIFY(!timer.isActive());
+}
+
+class TimeoutCounter : public QObject
+{
+ Q_OBJECT
+public slots:
+ void timeout() { ++count; };
+public:
+ int count = 0;
+};
+
+class RecursOnTimeoutAndStopTimerTimer : public QObject
+{
+ Q_OBJECT
+
+public:
+ QChronoTimer *one;
+ QChronoTimer *two;
+
+public slots:
+ void onetrigger()
+ {
+ QCoreApplication::processEvents();
+ }
+
+ void twotrigger()
+ {
+ one->stop();
+ }
+};
+
+void tst_QChronoTimer::recurseOnTimeoutAndStopTimer()
+{
+ QEventLoop eventLoop;
+ QChronoTimer::singleShot(1s, &eventLoop, &QEventLoop::quit);
+
+ RecursOnTimeoutAndStopTimerTimer t;
+ t.one = new QChronoTimer(&t);
+ t.two = new QChronoTimer(&t);
+
+ QObject::connect(t.one, SIGNAL(timeout()), &t, SLOT(onetrigger()));
+ QObject::connect(t.two, SIGNAL(timeout()), &t, SLOT(twotrigger()));
+
+ t.two->setSingleShot(true);
+
+ t.one->start();
+ t.two->start();
+
+ (void) eventLoop.exec();
+
+ QVERIFY(!t.one->isActive());
+ QVERIFY(!t.two->isActive());
+}
+
+struct CountedStruct
+{
+ CountedStruct(int *count, QThread *t = nullptr) : count(count), thread(t) { }
+ ~CountedStruct() { }
+ void operator()() const { ++(*count); if (thread) QCOMPARE(QThread::currentThread(), thread); }
+
+ int *count;
+ QThread *thread;
+};
+
+static QScopedPointer<QEventLoop> _e;
+static QThread *_t = nullptr;
+
+class StaticEventLoop
+{
+public:
+ static void quitEventLoop()
+ {
+ quitEventLoop_noexcept();
+ }
+
+ static void quitEventLoop_noexcept() noexcept
+ {
+ QVERIFY(!_e.isNull());
+ _e->quit();
+ if (_t)
+ QCOMPARE(QThread::currentThread(), _t);
+ }
+};
+
+class DontBlockEvents : public QObject
+{
+ Q_OBJECT
+public:
+ DontBlockEvents();
+ void timerEvent(QTimerEvent*) override;
+
+ int count;
+ int total;
+ QBasicTimer m_timer;
+
+public slots:
+ void paintEvent();
+
+};
+
+DontBlockEvents::DontBlockEvents()
+{
+ count = 0;
+ total = 0;
+
+ const std::chrono::milliseconds intervals[] = {2s, 2500ms, 3s, 5s, 1s, 2s};
+ // need a few unrelated timers running to reproduce the bug.
+ for (auto dur : intervals) {
+ auto *t = new QChronoTimer(dur, this);
+ t->start();
+ }
+
+ m_timer.start(1ms, this);
+}
+
+void DontBlockEvents::timerEvent(QTimerEvent* event)
+{
+ if (event->timerId() == m_timer.timerId()) {
+ QMetaObject::invokeMethod(this, &DontBlockEvents::paintEvent, Qt::QueuedConnection);
+ m_timer.start(0ms, this);
+ count++;
+ QCOMPARE(count, 1);
+ total++;
+ }
+}
+
+void DontBlockEvents::paintEvent()
+{
+ count--;
+ QCOMPARE(count, 0);
+}
+
+// This is a regression test for QTBUG-13633, where a timer with a zero
+// timeout that was restarted by the event handler could starve other timers.
+void tst_QChronoTimer::dontBlockEvents()
+{
+ DontBlockEvents t;
+ QTest::qWait(60ms);
+ QTRY_VERIFY(t.total > 2);
+}
+
+class SlotRepeater : public QObject {
+ Q_OBJECT
+public:
+ SlotRepeater() {}
+
+public slots:
+ void repeatThisSlot()
+ {
+ QMetaObject::invokeMethod(this, &SlotRepeater::repeatThisSlot, Qt::QueuedConnection);
+ }
+};
+
+void tst_QChronoTimer::postedEventsShouldNotStarveTimers()
+{
+ QChronoTimer timer;
+ timer.setInterval(0ns);
+ timer.setSingleShot(false);
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ timer.start();
+ SlotRepeater slotRepeater;
+ slotRepeater.repeatThisSlot();
+ QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.size() > 5, 100);
+}
+
+struct DummyFunctor {
+ static QThread *callThread;
+ void operator()() {
+ callThread = QThread::currentThread();
+ callThread->quit();
+ }
+};
+QThread *DummyFunctor::callThread = nullptr;
+
+void tst_QChronoTimer::callOnTimeout()
+{
+ QChronoTimer timer;
+ QSignalSpy timeoutSpy(&timer, &QChronoTimer::timeout);
+ timer.start();
+
+ auto context = std::make_unique<QObject>();
+
+ int count = 0;
+ timer.callOnTimeout([&count] { count++; });
+ QMetaObject::Connection connection = timer.callOnTimeout(context.get(), [&count] { count++; });
+ timer.callOnTimeout(&timer, &QChronoTimer::stop);
+
+
+ QTest::qWait(100ms);
+ QCOMPARE(count, 2);
+ QCOMPARE(timeoutSpy.size(), 1);
+
+ // Test that connection is bound to context lifetime
+ QVERIFY(connection);
+ context.reset();
+ QVERIFY(!connection);
+}
+
+void tst_QChronoTimer::bindToTimer()
+{
+ QChronoTimer timer;
+
+ // singleShot property
+ QProperty<bool> singleShot;
+ singleShot.setBinding(timer.bindableSingleShot().makeBinding());
+ QCOMPARE(timer.isSingleShot(), singleShot);
+
+ timer.setSingleShot(true);
+ QVERIFY(singleShot);
+ timer.setSingleShot(false);
+ QVERIFY(!singleShot);
+
+ // interval property
+ QProperty<std::chrono::nanoseconds> interval;
+ interval.setBinding([&](){ return timer.interval(); });
+ QCOMPARE(timer.interval(), interval.value());
+
+ timer.setInterval(10ms);
+ QCOMPARE(interval.value(), 10ms);
+ timer.setInterval(100ms);
+ QCOMPARE(interval.value(), 100ms);
+
+ // timerType property
+ QProperty<Qt::TimerType> timerType;
+ timerType.setBinding(timer.bindableTimerType().makeBinding());
+ QCOMPARE(timer.timerType(), timerType);
+
+ timer.setTimerType(Qt::PreciseTimer);
+ QCOMPARE(timerType, Qt::PreciseTimer);
+
+ timer.setTimerType(Qt::VeryCoarseTimer);
+ QCOMPARE(timerType, Qt::VeryCoarseTimer);
+
+ // active property
+ QProperty<bool> active;
+ active.setBinding([&](){ return timer.isActive(); });
+ QCOMPARE(active, timer.isActive());
+
+ timer.setInterval(1s);
+ timer.start();
+ QVERIFY(active);
+
+ timer.stop();
+ QVERIFY(!active);
+
+ // Also test that using negative interval updates the binding correctly
+ timer.setInterval(100ms);
+ timer.start();
+ QVERIFY(active);
+
+ auto ignoreMsg = [] {
+ QTest::ignoreMessage(QtWarningMsg,
+ "QObject::startTimer: Timers cannot have negative intervals");
+ };
+
+ ignoreMsg();
+ timer.setInterval(-100ms);
+ ignoreMsg();
+ timer.start();
+ QVERIFY(!active);
+
+ timer.setInterval(100ms);
+ timer.start();
+ QVERIFY(active);
+
+ ignoreMsg();
+ timer.setInterval(-100ms);
+ ignoreMsg();
+ timer.start();
+ QVERIFY(!active);
+}
+
+void tst_QChronoTimer::bindTimer()
+{
+ QChronoTimer timer;
+
+ // singleShot property
+ QVERIFY(!timer.isSingleShot());
+
+ QProperty<bool> singleShot;
+ timer.bindableSingleShot().setBinding(Qt::makePropertyBinding(singleShot));
+
+ singleShot = true;
+ QVERIFY(timer.isSingleShot());
+ singleShot = false;
+ QVERIFY(!timer.isSingleShot());
+
+ // interval property
+ QCOMPARE(timer.interval(), 0ns);
+
+ QProperty<std::chrono::nanoseconds> interval;
+ timer.bindableInterval().setBinding(Qt::makePropertyBinding(interval));
+
+ interval = 10ms;
+ QCOMPARE(timer.interval(), 10ms);
+ interval = 100ms;
+ QCOMPARE(timer.interval(), 100ms);
+ timer.setInterval(50ms);
+ QCOMPARE(timer.interval(), 50ms);
+ interval = 30ms;
+ QCOMPARE(timer.interval(), 50ms);
+
+ // timerType property
+ QCOMPARE(timer.timerType(), Qt::CoarseTimer);
+
+ QProperty<Qt::TimerType> timerType;
+ timer.bindableTimerType().setBinding(Qt::makePropertyBinding(timerType));
+
+ timerType = Qt::PreciseTimer;
+ QCOMPARE(timer.timerType(), Qt::PreciseTimer);
+ timerType = Qt::VeryCoarseTimer;
+ QCOMPARE(timer.timerType(), Qt::VeryCoarseTimer);
+}
+
+void tst_QChronoTimer::automatedBindingTests()
+{
+ QChronoTimer timer;
+
+ QVERIFY(!timer.isSingleShot());
+ QTestPrivate::testReadWritePropertyBasics(timer, true, false, "singleShot");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QChronoTimer::singleShot");
+ return;
+ }
+
+ QCOMPARE_NE(timer.interval(), 10ms);
+ using NSec = std::chrono::nanoseconds;
+ QTestPrivate::testReadWritePropertyBasics(timer, NSec{10ms}, NSec{20ms}, "interval");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QChronoTimer::interval");
+ return;
+ }
+
+ QCOMPARE_NE(timer.timerType(), Qt::PreciseTimer);
+ QTestPrivate::testReadWritePropertyBasics(timer, Qt::PreciseTimer, Qt::CoarseTimer,
+ "timerType");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QChronoTimer::timerType");
+ return;
+ }
+
+ timer.setInterval(1s);
+ timer.start();
+ QVERIFY(timer.isActive());
+ QTestPrivate::testReadOnlyPropertyBasics(timer, true, false, "active",
+ [&timer]() { timer.stop(); });
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QChronoTimer::active");
+ return;
+ }
+}
+
+void tst_QChronoTimer::negativeInterval()
+{
+ QChronoTimer timer;
+
+ auto ignoreMsg = [] {
+ QTest::ignoreMessage(QtWarningMsg,
+ "QObject::startTimer: Timers cannot have negative intervals");
+ };
+
+ ignoreMsg();
+ // Setting a negative interval does not change the active state.
+ timer.setInterval(-100ms);
+ ignoreMsg();
+ timer.start();
+ QVERIFY(!timer.isActive());
+
+ // Starting a timer that has a positive interval, the active state is changed
+ timer.setInterval(100ms);
+ timer.start();
+ QVERIFY(timer.isActive());
+
+ ignoreMsg();
+ // Setting a negative interval on an already running timer...
+ timer.setInterval(-100ms);
+ // ... the timer is stopped and the active state is changed
+ QVERIFY(!timer.isActive());
+
+ // Calling start on a timer that has a negative interval, does not change the active state
+ timer.start();
+ QVERIFY(!timer.isActive());
+}
+
+class OrderHelper : public QObject
+{
+ Q_OBJECT
+public:
+ enum CallType
+ {
+ String,
+ PMF,
+ Functor,
+ FunctorNoCtx
+ };
+ Q_ENUM(CallType)
+ QList<CallType> calls;
+
+ void triggerCall(CallType callType)
+ {
+ switch (callType)
+ {
+ case String:
+ QChronoTimer::singleShot(0ns, this, SLOT(stringSlot()));
+ break;
+ case PMF:
+ QChronoTimer::singleShot(0ns, this, &OrderHelper::pmfSlot);
+ break;
+ case Functor:
+ QChronoTimer::singleShot(0ns, this, [this]() { functorSlot(); });
+ break;
+ case FunctorNoCtx:
+ QChronoTimer::singleShot(0ns, [this]() { functorNoCtxSlot(); });
+ break;
+ }
+ }
+
+public slots:
+ void stringSlot() { calls << String; }
+ void pmfSlot() { calls << PMF; }
+ void functorSlot() { calls << Functor; }
+ void functorNoCtxSlot() { calls << FunctorNoCtx; }
+};
+
+Q_DECLARE_METATYPE(OrderHelper::CallType)
+
+void tst_QChronoTimer::timerOrder()
+{
+ QFETCH(QList<OrderHelper::CallType>, calls);
+
+ OrderHelper helper;
+
+ for (const auto call : calls)
+ helper.triggerCall(call);
+
+ QTRY_COMPARE(helper.calls, calls);
+}
+
+void tst_QChronoTimer::timerOrder_data()
+{
+ QTest::addColumn<QList<OrderHelper::CallType>>("calls");
+
+ QList<OrderHelper::CallType> calls = {
+ OrderHelper::String, OrderHelper::PMF,
+ OrderHelper::Functor, OrderHelper::FunctorNoCtx
+ };
+ std::sort(calls.begin(), calls.end());
+
+ int permutation = 0;
+ do {
+ QTest::addRow("permutation=%d", permutation) << calls;
+ ++permutation;
+ } while (std::next_permutation(calls.begin(), calls.end()));
+}
+
+void tst_QChronoTimer::timerOrderBackgroundThread()
+{
+ auto *thread = QThread::create([this]() { timerOrder(); });
+ thread->start();
+ QVERIFY(thread->wait());
+ delete thread;
+}
+
+void tst_QChronoTimer::timerPrecision()
+{
+ using namespace std::chrono;
+ steady_clock::time_point t1{};
+ steady_clock::time_point t2{};
+
+ QEventLoop loop;
+
+ QChronoTimer zeroTimer{0ns};
+ zeroTimer.setTimerType(Qt::PreciseTimer);
+ zeroTimer.setSingleShot(true);
+ connect(&zeroTimer, &QChronoTimer::timeout, this, [&t1] { t1 = steady_clock::now(); });
+
+ QChronoTimer oneNSecTimer{1ns};
+ oneNSecTimer.setTimerType(Qt::PreciseTimer);
+ oneNSecTimer.setSingleShot(true);
+ connect(&oneNSecTimer, &QChronoTimer::timeout, this, [&t2, &loop] {
+ t2 = steady_clock::now();
+ loop.quit();
+ });
+
+ zeroTimer.start();
+ oneNSecTimer.start();
+ loop.exec();
+ QCOMPARE_GT(t2, t1);
+ // qDebug() << "t2 - t1" << duration<double, std::chrono::milliseconds::period>{t2 - t1};
+}
+
+QTEST_MAIN(tst_QChronoTimer)
+
+#include "tst_qchronotimer.moc"
diff --git a/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt b/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt
new file mode 100644
index 0000000000..8f9783088c
--- /dev/null
+++ b/tests/auto/corelib/kernel/qcoreapplication/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcoreapplication LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if(NOT QT_FEATURE_private_tests)
+ return()
+endif()
+
+#####################################################################
+## tst_qcoreapplication Test:
+#####################################################################
+
+if (WIN32)
+ set(target_version "1.2.3.4")
+else()
+ set(target_version "1.2.3")
+endif()
+
+qt_internal_add_test(tst_qcoreapplication
+ VERSION ${target_version}
+ SOURCES
+ tst_qcoreapplication.cpp tst_qcoreapplication.h
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+if (APPLE)
+ set_property(TARGET tst_qcoreapplication PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist")
+ set_property(TARGET tst_qcoreapplication PROPERTY PROPERTY MACOSX_BUNDLE TRUE)
+endif()
+
+if (ANDROID)
+ set_property(TARGET tst_qcoreapplication PROPERTY QT_ANDROID_VERSION_NAME ${target_version})
+endif()
diff --git a/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro b/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro
deleted file mode 100644
index 1a76085c1b..0000000000
--- a/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qcoreapplication
-QT = core testlib core-private
-SOURCES = tst_qcoreapplication.cpp
-HEADERS = tst_qcoreapplication.h
-win32: VERSION = 1.2.3.4
-else: VERSION = 1.2.3
-QMAKE_INFO_PLIST = $$PWD/Info.plist
-requires(qtConfig(private_tests))
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
index 6adb393ddd..8f8ab33e64 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
@@ -1,41 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "tst_qcoreapplication.h"
#include <QtCore/QtCore>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <private/qabstracteventdispatcher_p.h> // for qGlobalPostedEventsCount()
#include <private/qcoreapplication_p.h>
+#include <private/qcoreevent_p.h>
#include <private/qeventloop_p.h>
#include <private/qthread_p.h>
+#ifdef Q_OS_WIN
+#include <QtCore/qt_windows.h>
+#endif
+
typedef QCoreApplication TestApplication;
class EventSpy : public QObject
@@ -44,9 +25,12 @@ class EventSpy : public QObject
public:
QList<int> recordedEvents;
- bool eventFilter(QObject *, QEvent *event)
+ std::function<void(QObject *, QEvent *)> eventCallback;
+ bool eventFilter(QObject *target, QEvent *event) override
{
recordedEvents.append(event->type());
+ if (eventCallback)
+ eventCallback(target, event);
return false;
}
};
@@ -119,7 +103,7 @@ void tst_QCoreApplication::getSetCheck()
void tst_QCoreApplication::qAppName()
{
-#ifdef QT_GUI_LIB
+#ifdef QT_QGUIAPPLICATIONTEST
const char* appName = "tst_qguiapplication";
#else
const char* appName = "tst_qcoreapplication";
@@ -155,9 +139,7 @@ void tst_QCoreApplication::qAppName()
void tst_QCoreApplication::qAppVersion()
{
-#if defined(Q_OS_WINRT)
- const char appVersion[] = "1.0.0.0";
-#elif defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
const char appVersion[] = "1.2.3.4";
#elif defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID)
const char appVersion[] = "1.2.3";
@@ -192,15 +174,12 @@ void tst_QCoreApplication::qAppVersion()
void tst_QCoreApplication::argc()
{
-#if defined(Q_OS_WINRT)
- QSKIP("QCoreApplication::arguments() parses arguments from actual command line on this platform.");
-#endif
{
int argc = 1;
char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
TestApplication app(argc, argv);
QCOMPARE(argc, 1);
- QCOMPARE(app.arguments().count(), 1);
+ QCOMPARE(app.arguments().size(), 1);
}
{
@@ -211,7 +190,7 @@ void tst_QCoreApplication::argc()
const_cast<char*>("arg3") };
TestApplication app(argc, argv);
QCOMPARE(argc, 4);
- QCOMPARE(app.arguments().count(), 4);
+ QCOMPARE(app.arguments().size(), 4);
}
{
@@ -219,7 +198,7 @@ void tst_QCoreApplication::argc()
char **argv = 0;
TestApplication app(argc, argv);
QCOMPARE(argc, 0);
- QCOMPARE(app.arguments().count(), 0);
+ QCOMPARE(app.arguments().size(), 0);
}
{
@@ -228,7 +207,7 @@ void tst_QCoreApplication::argc()
const_cast<char*>("-qmljsdebugger=port:3768,block") };
TestApplication app(argc, argv);
QCOMPARE(argc, 1);
- QCOMPARE(app.arguments().count(), 1);
+ QCOMPARE(app.arguments().size(), 1);
}
}
@@ -239,7 +218,7 @@ class EventGenerator : public QObject
public:
QObject *other;
- bool event(QEvent *e)
+ bool event(QEvent *e) override
{
if (e->type() == QEvent::MaxUser) {
QCoreApplication::sendPostedEvents(other, 0);
@@ -429,7 +408,7 @@ signals:
void progress(int);
protected:
- void run()
+ void run() override
{
emit progress(1);
emit progress(2);
@@ -497,7 +476,7 @@ public slots:
}
public:
- bool event(QEvent *event)
+ bool event(QEvent *event) override
{
switch (event->type()) {
case QEvent::User:
@@ -539,18 +518,15 @@ void tst_QCoreApplication::applicationPid()
QVERIFY(QCoreApplication::applicationPid() > 0);
}
-QT_BEGIN_NAMESPACE
-Q_CORE_EXPORT uint qGlobalPostedEventsCount();
-QT_END_NAMESPACE
-
+#ifdef QT_BUILD_INTERNAL
class GlobalPostedEventsCountObject : public QObject
{
Q_OBJECT
public:
- QList<int> globalPostedEventsCount;
+ QList<qsizetype> globalPostedEventsCount;
- bool event(QEvent *event)
+ bool event(QEvent *event) override
{
if (event->type() == QEvent::User)
globalPostedEventsCount.append(qGlobalPostedEventsCount());
@@ -565,7 +541,7 @@ void tst_QCoreApplication::globalPostedEventsCount()
TestApplication app(argc, argv);
QCoreApplication::sendPostedEvents();
- QCOMPARE(qGlobalPostedEventsCount(), 0u);
+ QCOMPARE(qGlobalPostedEventsCount(), qsizetype(0));
GlobalPostedEventsCountObject x;
QCoreApplication::postEvent(&x, new QEvent(QEvent::User));
@@ -573,19 +549,15 @@ void tst_QCoreApplication::globalPostedEventsCount()
QCoreApplication::postEvent(&x, new QEvent(QEvent::User));
QCoreApplication::postEvent(&x, new QEvent(QEvent::User));
QCoreApplication::postEvent(&x, new QEvent(QEvent::User));
- QCOMPARE(qGlobalPostedEventsCount(), 5u);
+ QCOMPARE(qGlobalPostedEventsCount(), qsizetype(5));
QCoreApplication::sendPostedEvents();
- QCOMPARE(qGlobalPostedEventsCount(), 0u);
-
- QList<int> expected = QList<int>()
- << 4
- << 3
- << 2
- << 1
- << 0;
+ QCOMPARE(qGlobalPostedEventsCount(), qsizetype(0));
+
+ const QList<qsizetype> expected = {4, 3, 2, 1, 0};
QCOMPARE(x.globalPostedEventsCount, expected);
}
+#endif // QT_BUILD_INTERNAL
class ProcessEventsAlwaysSendsPostedEventsObject : public QObject
{
@@ -596,7 +568,7 @@ public:
: counter(0)
{ }
- bool event(QEvent *event)
+ bool event(QEvent *event) override
{
if (event->type() == QEvent::User)
++counter;
@@ -611,7 +583,7 @@ void tst_QCoreApplication::processEventsAlwaysSendsPostedEvents()
TestApplication app(argc, argv);
ProcessEventsAlwaysSendsPostedEventsObject object;
- QTime t;
+ QElapsedTimer t;
t.start();
int i = 1;
do {
@@ -622,6 +594,108 @@ void tst_QCoreApplication::processEventsAlwaysSendsPostedEvents()
} while (t.elapsed() < 1000);
}
+#ifdef Q_OS_WIN
+void tst_QCoreApplication::sendPostedEventsInNativeLoop()
+{
+ int argc = 1;
+ char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
+ TestApplication app(argc, argv);
+
+ bool signalReceived = false;
+
+ // Post a message to the queue
+ QMetaObject::invokeMethod(this, [&signalReceived]() {
+ signalReceived = true;
+ }, Qt::QueuedConnection);
+
+ QElapsedTimer elapsedTimer;
+ elapsedTimer.start();
+
+ // Exec own message loop
+ MSG msg;
+ forever {
+ if (elapsedTimer.hasExpired(3000) || signalReceived)
+ break;
+
+ if (!::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ QThread::msleep(100);
+ continue;
+ }
+
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+
+ QVERIFY(signalReceived);
+}
+#endif // Q_OS_WIN
+
+class QuitBlocker : public QObject
+{
+ Q_OBJECT
+
+public:
+ bool eventFilter(QObject *, QEvent *event) override
+ {
+ if (event->type() == QEvent::Quit) {
+ event->ignore();
+ return true;
+ }
+
+ return false;
+ }
+};
+
+void tst_QCoreApplication::quit()
+{
+ TestApplication::quit(); // Should not do anything
+
+ {
+ int argc = 1;
+ char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
+ TestApplication app(argc, argv);
+
+ EventSpy spy;
+ app.installEventFilter(&spy);
+
+ {
+ QTimer::singleShot(0, &app, SLOT(quit()));
+ app.exec();
+ QVERIFY(spy.recordedEvents.contains(QEvent::Quit));
+ }
+
+ spy.recordedEvents.clear();
+
+ {
+ QTimer::singleShot(0, qApp, SLOT(quit()));
+ app.exec();
+ QVERIFY(spy.recordedEvents.contains(QEvent::Quit));
+ }
+
+ spy.recordedEvents.clear();
+
+ {
+ QTimer::singleShot(0, [&]{ TestApplication::quit(); });
+ app.exec();
+ QVERIFY(spy.recordedEvents.contains(QEvent::Quit));
+ }
+
+ spy.recordedEvents.clear();
+
+ {
+ QuitBlocker quitBlocker;
+ app.installEventFilter(&quitBlocker);
+
+ QTimer::singleShot(0, [&]{ TestApplication::quit(); });
+ QTimer::singleShot(200, [&]{ TestApplication::exit(); });
+ app.exec();
+ QVERIFY(!spy.recordedEvents.contains(QEvent::Quit));
+ }
+ }
+
+ TestApplication::quit(); // Should not do anything
+}
+
void tst_QCoreApplication::reexec()
{
int argc = 1;
@@ -667,25 +741,21 @@ void tst_QCoreApplication::eventLoopExecAfterExit()
class DummyEventDispatcher : public QAbstractEventDispatcher {
public:
DummyEventDispatcher() : QAbstractEventDispatcher(), visited(false) {}
- bool processEvents(QEventLoop::ProcessEventsFlags) {
+ bool processEvents(QEventLoop::ProcessEventsFlags) override {
visited = true;
emit awake();
QCoreApplication::sendPostedEvents();
return false;
}
- bool hasPendingEvents() {
- return qGlobalPostedEventsCount();
- }
- void registerSocketNotifier(QSocketNotifier *) {}
- void unregisterSocketNotifier(QSocketNotifier *) {}
- void registerTimer(int , int , Qt::TimerType, QObject *) {}
- bool unregisterTimer(int ) { return false; }
- bool unregisterTimers(QObject *) { return false; }
- QList<TimerInfo> registeredTimers(QObject *) const { return QList<TimerInfo>(); }
- int remainingTime(int) { return 0; }
- void wakeUp() {}
- void interrupt() {}
- void flush() {}
+ void registerSocketNotifier(QSocketNotifier *) override {}
+ void unregisterSocketNotifier(QSocketNotifier *) override {}
+ void registerTimer(int , qint64 , Qt::TimerType, QObject *) override {}
+ bool unregisterTimer(int ) override { return false; }
+ bool unregisterTimers(QObject *) override { return false; }
+ QList<TimerInfo> registeredTimers(QObject *) const override { return QList<TimerInfo>(); }
+ int remainingTime(int) override { return 0; }
+ void wakeUp() override {}
+ void interrupt() override {}
#ifdef Q_OS_WIN
bool registerEventNotifier(QWinEventNotifier *) { return false; }
@@ -727,13 +797,13 @@ class JobObject : public QObject
Q_OBJECT
public:
- explicit JobObject(QEventLoop *loop, QObject *parent = 0)
+ explicit JobObject(QEventLoop *loop, QObject *parent = nullptr)
: QObject(parent), locker(loop)
{
QTimer::singleShot(1000, this, SLOT(timeout()));
}
- explicit JobObject(QObject *parent = 0)
+ explicit JobObject(QObject *parent = nullptr)
: QObject(parent)
{
QTimer::singleShot(1000, this, SLOT(timeout()));
@@ -763,7 +833,7 @@ class QuitTester : public QObject
{
Q_OBJECT
public:
- QuitTester(QObject *parent = 0)
+ QuitTester(QObject *parent = nullptr)
: QObject(parent)
{
QTimer::singleShot(0, this, SLOT(doTest()));
@@ -775,49 +845,49 @@ private slots:
QCoreApplicationPrivate *privateClass = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
{
- QCOMPARE(privateClass->quitLockRef.load(), 0);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 0);
// Test with a lock active so that the refcount doesn't drop to zero during these tests, causing a quit.
// (until we exit the scope)
QEventLoopLocker locker;
- QCOMPARE(privateClass->quitLockRef.load(), 1);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 1);
JobObject *job1 = new JobObject(this);
- QCOMPARE(privateClass->quitLockRef.load(), 2);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 2);
delete job1;
- QCOMPARE(privateClass->quitLockRef.load(), 1);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 1);
job1 = new JobObject(this);
- QCOMPARE(privateClass->quitLockRef.load(), 2);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 2);
JobObject *job2 = new JobObject(this);
- QCOMPARE(privateClass->quitLockRef.load(), 3);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 3);
delete job1;
- QCOMPARE(privateClass->quitLockRef.load(), 2);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 2);
JobObject *job3 = new JobObject(job2);
Q_UNUSED(job3);
- QCOMPARE(privateClass->quitLockRef.load(), 3);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 3);
JobObject *job4 = new JobObject(job2);
Q_UNUSED(job4);
- QCOMPARE(privateClass->quitLockRef.load(), 4);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 4);
delete job2;
- QCOMPARE(privateClass->quitLockRef.load(), 1);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 1);
}
- QCOMPARE(privateClass->quitLockRef.load(), 0);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 0);
}
};
@@ -955,7 +1025,7 @@ void tst_QCoreApplication::addRemoveLibPaths()
TestApplication app(argc, argv);
// If libraryPaths only contains currentDir, neither will be in libraryPaths now.
- if (paths.length() != 1 && currentDir != paths[0]) {
+ if (paths.size() != 1 && currentDir != paths[0]) {
// Check that modifications stay alive across the creation of an application.
QVERIFY(QCoreApplication::libraryPaths().contains(currentDir));
QVERIFY(!QCoreApplication::libraryPaths().contains(paths[0]));
@@ -968,20 +1038,128 @@ void tst_QCoreApplication::addRemoveLibPaths()
}
#endif
+static bool theMainThreadIsSet()
+{
+ // QCoreApplicationPrivate::mainThread() has a Q_ASSERT we'd trigger
+ return QCoreApplicationPrivate::theMainThreadId.loadRelaxed() != nullptr;
+}
+
+static bool theMainThreadWasUnset = !theMainThreadIsSet(); // global static
+void tst_QCoreApplication::theMainThread()
+{
+ QVERIFY2(theMainThreadWasUnset, "Something set the theMainThread before main()");
+ QVERIFY(theMainThreadIsSet()); // we have at LEAST one QObject alive: tst_QCoreApplication
+
+ int argc = 1;
+ char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
+ TestApplication app(argc, argv);
+ QVERIFY(QCoreApplicationPrivate::theMainThreadId.loadRelaxed());
+ QVERIFY(QThread::isMainThread());
+ QCOMPARE(app.thread(), thread());
+ QCOMPARE(app.thread(), QThread::currentThread());
+}
+
static void createQObjectOnDestruction()
{
- // Make sure that we can create a QObject after the last QObject has been
- // destroyed (especially after QCoreApplication has).
- //
+ // Make sure that we can create a QObject (and thus have an associated
+ // QThread) after the last QObject has been destroyed (especially after
+ // QCoreApplication has).
+
+#if !defined(QT_QGUIAPPLICATIONTEST) && !defined(Q_OS_WIN)
+ // QCoreApplicationData's global static destructor has run and cleaned up
+ // the QAdoptedThread.
+ if (theMainThreadIsSet())
+ qFatal("theMainThreadIsSet() returned true; some QObject must have leaked");
+#endif
+
// Before the fixes, this would cause a dangling pointer dereference. If
// the problem comes back, it's possible that the following causes no
// effect.
QObject obj;
obj.thread()->setProperty("testing", 1);
+ if (!theMainThreadIsSet())
+ qFatal("theMainThreadIsSet() returned false");
+
+ // because we created a QObject after QCoreApplicationData was destroyed,
+ // the QAdoptedThread won't get cleaned up
}
Q_DESTRUCTOR_FUNCTION(createQObjectOnDestruction)
-#ifndef QT_GUI_LIB
+void tst_QCoreApplication::testDeleteLaterFromBeforeOutermostEventLoop()
+{
+ int argc = 0;
+ QCoreApplication app(argc, nullptr);
+
+ EventSpy *spy = new EventSpy();
+ QPointer<QObject> spyPointer = spy;
+
+ app.installEventFilter(spy);
+ spy->eventCallback = [spy](QObject *, QEvent *event) {
+ if (event->type() == QEvent::User + 1)
+ spy->deleteLater();
+ };
+
+ QCoreApplication::postEvent(&app, new QEvent(QEvent::Type(QEvent::User + 1)));
+ QCoreApplication::processEvents();
+
+ QEventLoop loop;
+ QTimer::singleShot(0, &loop, &QEventLoop::quit);
+ loop.exec();
+ QVERIFY(!spyPointer);
+}
+
+void tst_QCoreApplication::setIndividualAttributes_data()
+{
+ QTest::addColumn<Qt::ApplicationAttribute>("attribute");
+
+ const QMetaEnum &metaEnum = Qt::staticMetaObject.enumerator(Qt::staticMetaObject.indexOfEnumerator("ApplicationAttribute"));
+ // - 1 to avoid AA_AttributeCount.
+ for (int i = 0; i < metaEnum.keyCount(); ++i) {
+ const auto attribute = static_cast<Qt::ApplicationAttribute>(metaEnum.value(i));
+ if (attribute == Qt::AA_AttributeCount)
+ continue;
+
+ QTest::addRow("%s", metaEnum.key(i)) << attribute;
+ }
+}
+
+void tst_QCoreApplication::setIndividualAttributes()
+{
+ QFETCH(Qt::ApplicationAttribute, attribute);
+
+ const auto originalValue = QCoreApplication::testAttribute(attribute);
+ auto cleanup = qScopeGuard([=]() {
+ QCoreApplication::setAttribute(attribute, originalValue);
+ });
+
+ QCoreApplication::setAttribute(attribute, true);
+ QVERIFY(QCoreApplication::testAttribute(attribute));
+
+ QCoreApplication::setAttribute(attribute, false);
+ QVERIFY(!QCoreApplication::testAttribute(attribute));
+}
+
+void tst_QCoreApplication::setMultipleAttributes()
+{
+ const auto originalDontUseNativeMenuWindowsValue = QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows);
+ const auto originalDisableSessionManagerValue = QCoreApplication::testAttribute(Qt::AA_DisableSessionManager);
+ auto cleanup = qScopeGuard([=]() {
+ QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, originalDontUseNativeMenuWindowsValue);
+ QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, originalDisableSessionManagerValue);
+ });
+
+ QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, true);
+ QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, true);
+ QVERIFY(QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows));
+ QVERIFY(QCoreApplication::testAttribute(Qt::AA_DisableSessionManager));
+
+ QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false);
+ QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, false);
+ QVERIFY(!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows));
+ QVERIFY(!QCoreApplication::testAttribute(Qt::AA_DisableSessionManager));
+}
+
+#ifndef QT_QGUIAPPLICATIONTEST
QTEST_APPLESS_MAIN(tst_QCoreApplication)
#endif
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
index 2a23cf0751..1c25f63534 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TST_QCOREAPPLICATION_H
#define TST_QCOREAPPLICATION_H
@@ -47,8 +22,14 @@ private slots:
void deliverInDefinedOrder();
#endif
void applicationPid();
+#ifdef QT_BUILD_INTERNAL
void globalPostedEventsCount();
+#endif
void processEventsAlwaysSendsPostedEvents();
+#ifdef Q_OS_WIN
+ void sendPostedEventsInNativeLoop();
+#endif
+ void quit();
void reexec();
void execAfterExit();
void eventLoopExecAfterExit();
@@ -63,6 +44,11 @@ private slots:
#if QT_CONFIG(library)
void addRemoveLibPaths();
#endif
+ void theMainThread();
+ void testDeleteLaterFromBeforeOutermostEventLoop();
+ void setIndividualAttributes_data();
+ void setIndividualAttributes();
+ void setMultipleAttributes();
};
#endif // TST_QCOREAPPLICATION_H
diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/BLACKLIST b/tests/auto/corelib/kernel/qdeadlinetimer/BLACKLIST
new file mode 100644
index 0000000000..8c6c88c444
--- /dev/null
+++ b/tests/auto/corelib/kernel/qdeadlinetimer/BLACKLIST
@@ -0,0 +1,2 @@
+[stdchrono]
+windows clang ci
diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt b/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt
new file mode 100644
index 0000000000..2031cd9d48
--- /dev/null
+++ b/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdeadlinetimer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdeadlinetimer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdeadlinetimer
+ SOURCES
+ tst_qdeadlinetimer.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/qdeadlinetimer.pro b/tests/auto/corelib/kernel/qdeadlinetimer/qdeadlinetimer.pro
deleted file mode 100644
index 12ad7dabc2..0000000000
--- a/tests/auto/corelib/kernel/qdeadlinetimer/qdeadlinetimer.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdeadlinetimer
-QT = core testlib
-SOURCES = tst_qdeadlinetimer.cpp
-
diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
index 4ca68550b9..79416faaf9 100644
--- a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
+++ b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
@@ -1,51 +1,42 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QString>
#include <QtCore/QTime>
#include <QtCore/QDeadlineTimer>
#include <QtCore/QElapsedTimer>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QTimer>
-#if QT_HAS_INCLUDE(<chrono>)
-# include <chrono>
-#endif
+#include <chrono>
+#include <inttypes.h>
static const int minResolution = 400; // the minimum resolution for the tests
-Q_DECLARE_METATYPE(Qt::TimerType)
+QT_BEGIN_NAMESPACE
+namespace QTest {
+template<> char *toString(const QDeadlineTimer &dt)
+{
+ if (dt.isForever())
+ return qstrdup("QDeadlineTimer::Forever");
+
+ qint64 deadline = dt.deadlineNSecs();
+ char *buf = new char[256];
+ qsnprintf(buf, 256, "%lld.%09d%s",
+ deadline / 1000 / 1000 / 1000, qAbs(deadline) % (1000 * 1000 * 1000),
+ dt.hasExpired() ? " (expired)" : "");
+ return buf;
+}
+}
+QT_END_NAMESPACE
class tst_QDeadlineTimer : public QObject
{
Q_OBJECT
private Q_SLOTS:
- void initTestCase_data();
+ void compareCompiles();
void basics();
void foreverness();
void current();
@@ -56,12 +47,11 @@ private Q_SLOTS:
void stdchrono();
};
-void tst_QDeadlineTimer::initTestCase_data()
+static constexpr auto timerType = Qt::PreciseTimer;
+
+void tst_QDeadlineTimer::compareCompiles()
{
- qRegisterMetaType<Qt::TimerType>();
- QTest::addColumn<Qt::TimerType>("timerType");
- QTest::newRow("precise") << Qt::PreciseTimer;
- QTest::newRow("coarse") << Qt::CoarseTimer;
+ QTestPrivate::testAllComparisonOperatorsCompile<QDeadlineTimer>();
}
void tst_QDeadlineTimer::basics()
@@ -69,20 +59,22 @@ void tst_QDeadlineTimer::basics()
QDeadlineTimer deadline;
QCOMPARE(deadline.timerType(), Qt::CoarseTimer);
- QFETCH_GLOBAL(Qt::TimerType, timerType);
deadline = QDeadlineTimer(timerType);
QCOMPARE(deadline.timerType(), timerType);
QVERIFY(!deadline.isForever());
QCOMPARE(deadline, QDeadlineTimer(timerType));
QVERIFY(!(deadline != QDeadlineTimer(timerType)));
QVERIFY(!(deadline < QDeadlineTimer()));
- QVERIFY(deadline <= QDeadlineTimer());
- QVERIFY(deadline >= QDeadlineTimer());
+ QCOMPARE_LE(deadline, QDeadlineTimer());
+ QCOMPARE_GE(deadline, QDeadlineTimer());
QVERIFY(!(deadline > QDeadlineTimer()));
QVERIFY(!(deadline < deadline));
- QVERIFY(deadline <= deadline);
- QVERIFY(deadline >= deadline);
+ QCOMPARE_LE(deadline, deadline);
+ QCOMPARE_GE(deadline, deadline);
QVERIFY(!(deadline > deadline));
+ QT_TEST_ALL_COMPARISON_OPS(deadline, QDeadlineTimer(timerType), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, QDeadlineTimer(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QDeadlineTimer(), QDeadlineTimer(), Qt::strong_ordering::equal);
// should have expired, but we may be running too early after boot
QTRY_VERIFY_WITH_TIMEOUT(deadline.hasExpired(), 100);
@@ -95,18 +87,18 @@ void tst_QDeadlineTimer::basics()
deadline.setRemainingTime(0, timerType);
QCOMPARE(deadline.remainingTime(), qint64(0));
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
deadline.setPreciseRemainingTime(0, 0, timerType);
QCOMPARE(deadline.remainingTime(), qint64(0));
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
deadline.setDeadline(0, timerType);
QCOMPARE(deadline.remainingTime(), qint64(0));
@@ -123,9 +115,6 @@ void tst_QDeadlineTimer::basics()
void tst_QDeadlineTimer::foreverness()
{
- QFETCH_GLOBAL(Qt::TimerType, timerType);
- // we don't check whether timerType() is our type since it's possible it detects it's forever
-
QDeadlineTimer deadline = QDeadlineTimer::Forever;
QCOMPARE(deadline.timerType(), Qt::CoarseTimer);
QVERIFY(deadline.isForever());
@@ -185,9 +174,10 @@ void tst_QDeadlineTimer::foreverness()
QCOMPARE(deadline, deadline);
QVERIFY(!(deadline < deadline));
- QVERIFY(deadline <= deadline);
- QVERIFY(deadline >= deadline);
+ QCOMPARE_LE(deadline, deadline);
+ QCOMPARE_GE(deadline, deadline);
QVERIFY(!(deadline > deadline));
+ QT_TEST_ALL_COMPARISON_OPS(deadline, deadline, Qt::strong_ordering::equal);
// adding to forever must still be forever
QDeadlineTimer deadline2 = deadline + 1;
@@ -202,9 +192,10 @@ void tst_QDeadlineTimer::foreverness()
QCOMPARE(deadline2 - deadline, qint64(0));
QCOMPARE(deadline2, deadline);
QVERIFY(!(deadline2 < deadline));
- QVERIFY(deadline2 <= deadline);
- QVERIFY(deadline2 >= deadline);
+ QCOMPARE_LE(deadline2, deadline);
+ QCOMPARE_GE(deadline2, deadline);
QVERIFY(!(deadline2 > deadline));
+ QT_TEST_ALL_COMPARISON_OPS(deadline2, deadline, Qt::strong_ordering::equal);
// subtracting from forever is *also* forever
deadline2 = deadline - 1;
@@ -219,33 +210,34 @@ void tst_QDeadlineTimer::foreverness()
QCOMPARE(deadline2 - deadline, qint64(0));
QCOMPARE(deadline2, deadline);
QVERIFY(!(deadline2 < deadline));
- QVERIFY(deadline2 <= deadline);
- QVERIFY(deadline2 >= deadline);
+ QCOMPARE_LE(deadline2, deadline);
+ QCOMPARE_GE(deadline2, deadline);
QVERIFY(!(deadline2 > deadline));
+ QT_TEST_ALL_COMPARISON_OPS(deadline2, deadline, Qt::strong_ordering::equal);
// compare and order against a default-constructed object
QDeadlineTimer expired;
QVERIFY(!(deadline == expired));
- QVERIFY(deadline != expired);
+ QCOMPARE_NE(deadline, expired);
QVERIFY(!(deadline < expired));
QVERIFY(!(deadline <= expired));
- QVERIFY(deadline >= expired);
- QVERIFY(deadline > expired);
+ QCOMPARE_GE(deadline, expired);
+ QCOMPARE_GT(deadline, expired);
+ QT_TEST_EQUALITY_OPS(deadline, expired, false);
}
void tst_QDeadlineTimer::current()
{
- QFETCH_GLOBAL(Qt::TimerType, timerType);
auto deadline = QDeadlineTimer::current(timerType);
QVERIFY(deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
QCOMPARE(deadline.remainingTime(), qint64(0));
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
// subtracting from current should be "more expired"
QDeadlineTimer earlierDeadline = deadline - 1;
@@ -254,122 +246,123 @@ void tst_QDeadlineTimer::current()
QCOMPARE(earlierDeadline.timerType(), timerType);
QCOMPARE(earlierDeadline.remainingTime(), qint64(0));
QCOMPARE(earlierDeadline.remainingTimeNSecs(), qint64(0));
- QVERIFY(earlierDeadline.deadline() != 0);
- QVERIFY(earlierDeadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(earlierDeadline.deadlineNSecs() != 0);
- QVERIFY(earlierDeadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(earlierDeadline.deadline(), 0);
+ QCOMPARE_NE(earlierDeadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(earlierDeadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(earlierDeadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
QCOMPARE(earlierDeadline.deadline(), deadline.deadline() - 1);
QCOMPARE(earlierDeadline.deadlineNSecs(), deadline.deadlineNSecs() - 1000*1000);
QCOMPARE(earlierDeadline - deadline, qint64(-1));
- QVERIFY(earlierDeadline != deadline);
- QVERIFY(earlierDeadline < deadline);
- QVERIFY(earlierDeadline <= deadline);
+ QCOMPARE_NE(earlierDeadline, deadline);
+ QCOMPARE_LT(earlierDeadline, deadline);
+ QCOMPARE_LE(earlierDeadline, deadline);
QVERIFY(!(earlierDeadline >= deadline));
QVERIFY(!(earlierDeadline > deadline));
+ QT_TEST_ALL_COMPARISON_OPS(earlierDeadline, deadline, Qt::strong_ordering::less);
}
void tst_QDeadlineTimer::deadlines()
{
- QFETCH_GLOBAL(Qt::TimerType, timerType);
-
QDeadlineTimer deadline(4 * minResolution, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTime() > (3 * minResolution));
- QVERIFY(deadline.remainingTime() <= (4 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_GT(deadline.remainingTime(), (3 * minResolution));
+ QCOMPARE_LE(deadline.remainingTime(), (4 * minResolution));
+ QCOMPARE_GT(deadline.remainingTimeNSecs(), (3000000 * minResolution));
+ QCOMPARE_LE(deadline.remainingTimeNSecs(), (4000000 * minResolution));
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
deadline.setRemainingTime(4 * minResolution, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTime() > (3 * minResolution));
- QVERIFY(deadline.remainingTime() <= (4 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_GT(deadline.remainingTime(), (3 * minResolution));
+ QCOMPARE_LE(deadline.remainingTime(), (4 * minResolution));
+ QCOMPARE_GT(deadline.remainingTimeNSecs(), (3000000 * minResolution));
+ QCOMPARE_LE(deadline.remainingTimeNSecs(), (4000000 * minResolution));
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
deadline.setPreciseRemainingTime(0, 4000000 * minResolution, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTime() > (3 * minResolution));
- QVERIFY(deadline.remainingTime() <= (4 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_GT(deadline.remainingTime(), (3 * minResolution));
+ QCOMPARE_LE(deadline.remainingTime(), (4 * minResolution));
+ QCOMPARE_GT(deadline.remainingTimeNSecs(), (3000000 * minResolution));
+ QCOMPARE_LE(deadline.remainingTimeNSecs(), (4000000 * minResolution));
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
deadline.setPreciseRemainingTime(1, 0, timerType); // 1 sec
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTime() > (1000 - minResolution));
- QVERIFY(deadline.remainingTime() <= 1000);
- QVERIFY(deadline.remainingTimeNSecs() > (1000 - minResolution)*1000*1000);
- QVERIFY(deadline.remainingTimeNSecs() <= (1000*1000*1000));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_GT(deadline.remainingTime(), (1000 - minResolution));
+ QCOMPARE_LE(deadline.remainingTime(), 1000);
+ QCOMPARE_GT(deadline.remainingTimeNSecs(), (1000 - minResolution)*1000*1000);
+ QCOMPARE_LE(deadline.remainingTimeNSecs(), (1000*1000*1000));
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
// adding to a future deadline must still be further in the future
QDeadlineTimer laterDeadline = deadline + 1;
QVERIFY(!laterDeadline.hasExpired());
QVERIFY(!laterDeadline.isForever());
QCOMPARE(laterDeadline.timerType(), timerType);
- QVERIFY(laterDeadline.remainingTime() > (1000 - minResolution));
- QVERIFY(laterDeadline.remainingTime() <= 1001);
- QVERIFY(laterDeadline.remainingTimeNSecs() > (1001 - minResolution)*1000*1000);
- QVERIFY(laterDeadline.remainingTimeNSecs() <= (1001*1000*1000));
- QVERIFY(laterDeadline.deadline() != 0);
- QVERIFY(laterDeadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(laterDeadline.deadlineNSecs() != 0);
- QVERIFY(laterDeadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_GT(laterDeadline.remainingTime(), (1000 - minResolution));
+ QCOMPARE_LE(laterDeadline.remainingTime(), 1001);
+ QCOMPARE_GT(laterDeadline.remainingTimeNSecs(), (1001 - minResolution)*1000*1000);
+ QCOMPARE_LE(laterDeadline.remainingTimeNSecs(), (1001*1000*1000));
+ QCOMPARE_NE(laterDeadline.deadline(), 0);
+ QCOMPARE_NE(laterDeadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(laterDeadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(laterDeadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
QCOMPARE(laterDeadline.deadline(), deadline.deadline() + 1);
QCOMPARE(laterDeadline.deadlineNSecs(), deadline.deadlineNSecs() + 1000*1000);
QCOMPARE(laterDeadline - deadline, qint64(1));
- QVERIFY(laterDeadline != deadline);
+ QCOMPARE_NE(laterDeadline, deadline);
QVERIFY(!(laterDeadline < deadline));
QVERIFY(!(laterDeadline <= deadline));
- QVERIFY(laterDeadline >= deadline);
- QVERIFY(laterDeadline > deadline);
+ QCOMPARE_GE(laterDeadline, deadline);
+ QCOMPARE_GT(laterDeadline, deadline);
+ QT_TEST_ALL_COMPARISON_OPS(laterDeadline, deadline, Qt::strong_ordering::greater);
// compare and order against a default-constructed object
QDeadlineTimer expired;
QVERIFY(!(deadline == expired));
- QVERIFY(deadline != expired);
+ QCOMPARE_NE(deadline, expired);
QVERIFY(!(deadline < expired));
QVERIFY(!(deadline <= expired));
- QVERIFY(deadline >= expired);
- QVERIFY(deadline > expired);
+ QCOMPARE_GE(deadline, expired);
+ QCOMPARE_GT(deadline, expired);
+ QT_TEST_EQUALITY_OPS(deadline, expired, false);
// compare and order against a forever deadline
QDeadlineTimer forever_(QDeadlineTimer::Forever);
+ QT_TEST_EQUALITY_OPS(deadline, forever_, false);
QVERIFY(!(deadline == forever_));
- QVERIFY(deadline != forever_);
- QVERIFY(deadline < forever_);
- QVERIFY(deadline <= forever_);
+ QCOMPARE_NE(deadline, forever_);
+ QCOMPARE_LT(deadline, forever_);
+ QCOMPARE_LE(deadline, forever_);
QVERIFY(!(deadline >= forever_));
QVERIFY(!(deadline > forever_));
}
void tst_QDeadlineTimer::setDeadline()
{
- QFETCH_GLOBAL(Qt::TimerType, timerType);
auto now = QDeadlineTimer::current(timerType);
QDeadlineTimer deadline;
@@ -397,10 +390,10 @@ void tst_QDeadlineTimer::setDeadline()
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTime() > (3 * minResolution));
- QVERIFY(deadline.remainingTime() <= (4 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
+ QCOMPARE_GT(deadline.remainingTime(), (3 * minResolution));
+ QCOMPARE_LE(deadline.remainingTime(), (4 * minResolution));
+ QCOMPARE_GT(deadline.remainingTimeNSecs(), (3000000 * minResolution));
+ QCOMPARE_LE(deadline.remainingTimeNSecs(), (4000000 * minResolution));
QCOMPARE(deadline.deadline(), now.deadline() + 4 * minResolution); // yes, it's exact
// don't check deadlineNSecs!
@@ -411,17 +404,16 @@ void tst_QDeadlineTimer::setDeadline()
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTime() > (3 * minResolution));
- QVERIFY(deadline.remainingTime() <= (4 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() > (3000000 * minResolution));
- QVERIFY(deadline.remainingTimeNSecs() <= (4000000 * minResolution));
+ QCOMPARE_GT(deadline.remainingTime(), (3 * minResolution));
+ QCOMPARE_LE(deadline.remainingTime(), (4 * minResolution));
+ QCOMPARE_GT(deadline.remainingTimeNSecs(), (3000000 * minResolution));
+ QCOMPARE_LE(deadline.remainingTimeNSecs(), (4000000 * minResolution));
QCOMPARE(deadline.deadline(), nsec / (1000 * 1000));
QCOMPARE(deadline.deadlineNSecs(), nsec);
}
void tst_QDeadlineTimer::overflow()
{
- QFETCH_GLOBAL(Qt::TimerType, timerType);
// Check the constructor for overflows (should also cover saturating the result of the deadline() method if overflowing)
QDeadlineTimer now = QDeadlineTimer::current(timerType), deadline(std::numeric_limits<qint64>::max() - 1, timerType);
QVERIFY(deadline.isForever() || deadline.deadline() >= now.deadline());
@@ -479,27 +471,48 @@ void tst_QDeadlineTimer::overflow()
// However we are tracking the elapsed time, so it shouldn't be a problem.
deadline.setPreciseRemainingTime(1, -1000, timerType);
qint64 difference = (deadline.deadlineNSecs() - nsDeadline) - nsExpected;
- QVERIFY(difference >= 0); // Should always be true, but just in case
- QVERIFY(difference <= callTimer.nsecsElapsed()); // Ideally difference should be 0 exactly
+ QCOMPARE_GE(difference, 0); // Should always be true, but just in case
+ QCOMPARE_LE(difference, callTimer.nsecsElapsed()); // Ideally difference should be 0 exactly
// Make sure setRemainingTime underflows gracefully
deadline.setPreciseRemainingTime(std::numeric_limits<qint64>::min() / 10, 0, timerType);
- QVERIFY(!deadline.isForever()); // On Win/macOS the above underflows, make sure we don't saturate to Forever
- QVERIFY(deadline.remainingTime() == 0);
+ QVERIFY(deadline.isForever()); // The above could underflow, so make sure we did set to Forever
+ QCOMPARE(deadline.remainingTimeNSecs(), -1);
+ QCOMPARE(deadline.remainingTime(), -1);
// If the timer is saturated we don't want to get a valid number of milliseconds
- QVERIFY(deadline.deadline() == std::numeric_limits<qint64>::min());
+ QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
// Check that the conversion to milliseconds and nanoseconds underflows gracefully
deadline.setPreciseDeadline(std::numeric_limits<qint64>::min() / 10, 0, timerType);
- QVERIFY(!deadline.isForever()); // On Win/macOS the above underflows, make sure we don't saturate to Forever
+ QVERIFY(!deadline.isForever()); // The above underflows, make sure we don't saturate to Forever
QVERIFY(deadline.deadline() == std::numeric_limits<qint64>::min());
QVERIFY(deadline.deadlineNSecs() == std::numeric_limits<qint64>::min());
+
+ // Check that subtracting max() twice doesn't make it become positive
+ deadline.setPreciseDeadline(0);
+ deadline -= std::numeric_limits<qint64>::max();
+ deadline -= std::numeric_limits<qint64>::max();
+ QVERIFY(!deadline.isForever());
+ QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::min());
+ QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::min());
+
+ // Ditto for adding max()
+ deadline.setPreciseDeadline(0);
+ deadline += std::numeric_limits<qint64>::max();
+ deadline += std::numeric_limits<qint64>::max();
+ QVERIFY(deadline.isForever()); // it's so far in the future it's effectively forever
+ QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
+
+ // But we don't un-become forever after saturation
+ deadline -= std::numeric_limits<qint64>::max();
+ QVERIFY(deadline.isForever());
+ QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
}
void tst_QDeadlineTimer::expire()
{
- QFETCH_GLOBAL(Qt::TimerType, timerType);
-
QDeadlineTimer deadline(minResolution, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
@@ -510,20 +523,17 @@ void tst_QDeadlineTimer::expire()
QCOMPARE(deadline.remainingTime(), qint64(0));
QCOMPARE(deadline.remainingTimeNSecs(), qint64(0));
- QVERIFY(deadline.deadline() != 0);
- QVERIFY(deadline.deadline() != std::numeric_limits<qint64>::max());
- QVERIFY(deadline.deadlineNSecs() != 0);
- QVERIFY(deadline.deadlineNSecs() != std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadline(), 0);
+ QCOMPARE_NE(deadline.deadline(), std::numeric_limits<qint64>::max());
+ QCOMPARE_NE(deadline.deadlineNSecs(), 0);
+ QCOMPARE_NE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
QCOMPARE(deadline.deadlineNSecs(), previousDeadline);
}
void tst_QDeadlineTimer::stdchrono()
{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("std::chrono not found on this system");
-#else
using namespace std::chrono;
- QFETCH_GLOBAL(Qt::TimerType, timerType);
+ using namespace std::chrono_literals;
// create some forevers
QDeadlineTimer deadline = milliseconds::max();
@@ -573,130 +583,157 @@ void tst_QDeadlineTimer::stdchrono()
QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::zero());
+ QDeadlineTimer now;
+ bool timersExecuted = false;
+
auto steady_before = steady_clock::now();
auto system_before = system_clock::now();
- QTest::qSleep(minResolution);
- auto now = QDeadlineTimer::current(timerType);
- QTest::qSleep(minResolution);
+ decltype(steady_before) steady_after, steady_deadline;
+ decltype(system_before) system_after, system_deadline;
- auto steady_after = steady_clock::now();
- auto system_after = system_clock::now();
+ QTimer::singleShot(minResolution, Qt::PreciseTimer, [&]() {
+ now = QDeadlineTimer::current(timerType);
+ QTimer::singleShot(minResolution, Qt::PreciseTimer, [&]() {
+ steady_deadline = now.deadline<steady_clock>();
+ system_deadline = now.deadline<system_clock>();
+ steady_after = steady_clock::now();
+ system_after = system_clock::now();
+ timersExecuted = true;
+ });
+ });
+
+ QTRY_VERIFY2_WITH_TIMEOUT(timersExecuted,
+ "Looks like timers didn't fire on time.", 4 * minResolution);
+
+ {
+ qint64 before = duration_cast<nanoseconds>(steady_before.time_since_epoch()).count();
+ qint64 after = duration_cast<nanoseconds>(steady_after.time_since_epoch()).count();
+ QCOMPARE_GT(now.deadlineNSecs(), before);
+ QCOMPARE_LT(now.deadlineNSecs(), after);
+ }
{
- auto diff = duration_cast<milliseconds>(steady_after - now.deadline<steady_clock>());
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
+ auto diff = duration_cast<milliseconds>(steady_after - steady_deadline);
+ QCOMPARE_GT(diff.count(), minResolution / 2);
+ QCOMPARE_LT(diff.count(), 3 * minResolution / 2);
QDeadlineTimer dt_after(steady_after, timerType);
- QVERIFY2(now < dt_after,
- ("now = " + QLocale().toString(now.deadlineNSecs()) +
- "; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
+ QCOMPARE_LT(now, dt_after);
+ QT_TEST_ALL_COMPARISON_OPS(now, dt_after, Qt::strong_ordering::less);
- diff = duration_cast<milliseconds>(now.deadline<steady_clock>() - steady_before);
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
+ diff = duration_cast<milliseconds>(steady_deadline - steady_before);
+ QCOMPARE_GT(diff.count(), minResolution / 2);
+ QCOMPARE_LT(diff.count(), 3 * minResolution / 2);
QDeadlineTimer dt_before(steady_before, timerType);
- QVERIFY2(now > dt_before,
- ("now = " + QLocale().toString(now.deadlineNSecs()) +
- "; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
+ QCOMPARE_GT(now, dt_before);
+ QT_TEST_ALL_COMPARISON_OPS(now, dt_before, Qt::strong_ordering::greater);
}
{
- auto diff = duration_cast<milliseconds>(system_after - now.deadline<system_clock>());
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
+ auto diff = duration_cast<milliseconds>(system_after - system_deadline);
+ QCOMPARE_GT(diff.count(), minResolution / 2);
+ QCOMPARE_LT(diff.count(), 3 * minResolution / 2);
QDeadlineTimer dt_after(system_after, timerType);
- QVERIFY2(now < dt_after,
- ("now = " + QLocale().toString(now.deadlineNSecs()) +
- "; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
+ QCOMPARE_LT(now, dt_after);
+ QT_TEST_ALL_COMPARISON_OPS(now, dt_after, Qt::strong_ordering::less);
- diff = duration_cast<milliseconds>(now.deadline<system_clock>() - system_before);
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
+ diff = duration_cast<milliseconds>(system_deadline - system_before);
+ QCOMPARE_GT(diff.count(), minResolution / 2);
+ QCOMPARE_LT(diff.count(), 3 * minResolution / 2);
QDeadlineTimer dt_before(system_before, timerType);
- QVERIFY2(now > dt_before,
- ("now = " + QLocale().toString(now.deadlineNSecs()) +
- "; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
+ QCOMPARE_GT(now, dt_before);
+ QT_TEST_ALL_COMPARISON_OPS(now, dt_before, Qt::strong_ordering::greater);
}
// make it regular
now = QDeadlineTimer::current(timerType);
- deadline.setRemainingTime(milliseconds(4 * minResolution), timerType);
+ deadline.setRemainingTime(4ms * minResolution, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTimeAsDuration() > milliseconds(3 * minResolution));
- QVERIFY(deadline.remainingTimeAsDuration() < milliseconds(5 * minResolution));
- QVERIFY(deadline.remainingTimeAsDuration() > nanoseconds(3000000 * minResolution));
- QVERIFY(deadline.remainingTimeAsDuration() < nanoseconds(5000000 * minResolution));
- QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + milliseconds(3 * minResolution)));
- QVERIFY(deadline.deadline<steady_clock>() < (steady_clock::now() + milliseconds(5 * minResolution)));
- QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + milliseconds(3 * minResolution)));
- QVERIFY(deadline.deadline<system_clock>() < (system_clock::now() + milliseconds(5 * minResolution)));
- if (timerType == Qt::CoarseTimer) {
- QVERIFY(deadline > (now + milliseconds(3 * minResolution)));
- QVERIFY(deadline < (now + milliseconds(5 * minResolution)));
- QVERIFY(deadline > (now + nanoseconds(3000000 * minResolution)));
- QVERIFY(deadline < (now + nanoseconds(5000000 * minResolution)));
- QVERIFY(deadline > milliseconds(3 * minResolution));
- QVERIFY(deadline < milliseconds(5 * minResolution));
- QVERIFY(deadline > nanoseconds(3000000 * minResolution));
- QVERIFY(deadline < nanoseconds(5000000 * minResolution));
- QVERIFY(deadline >= steady_clock::now());
- QVERIFY(deadline >= system_clock::now());
- }
+ QCOMPARE_GT(deadline.remainingTimeAsDuration(), 3ms * minResolution);
+ QCOMPARE_LT(deadline.remainingTimeAsDuration(), 5ms * minResolution);
+ QCOMPARE_GT(deadline.remainingTimeAsDuration(), 3'000'000ns * minResolution);
+ QCOMPARE_LT(deadline.remainingTimeAsDuration(), 5'000'000ns * minResolution);
+ QCOMPARE_GT(deadline.deadline<steady_clock>(), (steady_clock::now() + 3ms * minResolution));
+ QCOMPARE_LT(deadline.deadline<steady_clock>(), (steady_clock::now() + 5ms * minResolution));
+ QCOMPARE_GT(deadline.deadline<system_clock>(), (system_clock::now() + 3ms * minResolution));
+ QCOMPARE_LT(deadline.deadline<system_clock>(), (system_clock::now() + 5ms * minResolution));
+ QCOMPARE_GT((deadline.deadline<steady_clock, milliseconds>()),
+ steady_clock::now() + 3ms * minResolution);
+ QCOMPARE_LT((deadline.deadline<steady_clock, milliseconds>()),
+ steady_clock::now() + 5ms * minResolution);
+ QCOMPARE_GT((deadline.deadline<system_clock, milliseconds>()),
+ system_clock::now() + 3ms * minResolution);
+ QCOMPARE_LT((deadline.deadline<system_clock, milliseconds>()),
+ system_clock::now() + 5ms * minResolution);
+ QCOMPARE_GT(deadline, now + 3ms * minResolution);
+ QCOMPARE_LT(deadline, now + 5ms * minResolution);
+ QCOMPARE_GT(deadline, now + 3000000ns * minResolution);
+ QCOMPARE_LT(deadline, now + 5000000ns * minResolution);
+ QCOMPARE_GT(deadline, 3ms * minResolution);
+ QCOMPARE_LT(deadline, 5ms * minResolution);
+ QCOMPARE_GT(deadline, 3000000ns * minResolution);
+ QCOMPARE_LT(deadline, 5000000ns * minResolution);
+ QCOMPARE_GE(deadline, steady_clock::now());
+ QCOMPARE_GE(deadline, system_clock::now());
+ QT_TEST_ALL_COMPARISON_OPS(deadline, now + 3ms * minResolution, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, now + 5ms * minResolution, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, now + 3000000ns * minResolution, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, now + 5000000ns * minResolution, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, 3ms * minResolution, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, 5ms * minResolution, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, steady_clock::now(), Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(deadline, system_clock::now(), Qt::strong_ordering::greater);
now = QDeadlineTimer::current(timerType);
- deadline = QDeadlineTimer(seconds(1), timerType);
+ deadline = QDeadlineTimer(1s, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTimeAsDuration() > (seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.remainingTimeAsDuration() <= seconds(1));
- QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + seconds(1) + milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + seconds(1) + milliseconds(minResolution)));
- if (timerType == Qt::CoarseTimer) {
- QVERIFY(deadline > (seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline <= seconds(1));
- }
+ QCOMPARE_GT(deadline.remainingTimeAsDuration(), 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.remainingTimeAsDuration(), 1s);
+ QCOMPARE_GT(deadline.deadline<steady_clock>(), steady_clock::now() + 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<steady_clock>(), steady_clock::now() + 1s + 1ms * minResolution);
+ QCOMPARE_GT(deadline.deadline<system_clock>(), system_clock::now() + 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<system_clock>(), system_clock::now() + 1s + 1ms * minResolution);
+ QCOMPARE_GT(deadline, 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline, 1s);
now = QDeadlineTimer::current(timerType);
- deadline.setRemainingTime(hours(1), timerType);
+ deadline.setRemainingTime(1h, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTimeAsDuration() > (hours(1) - milliseconds(minResolution)));
- QVERIFY(deadline.remainingTimeAsDuration() <= hours(1));
- QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + hours(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + hours(1) + milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + hours(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + hours(1) + milliseconds(minResolution)));
+ QCOMPARE_GT(deadline.remainingTimeAsDuration(), 1h - 1ms * minResolution);
+ QCOMPARE_LE(deadline.remainingTimeAsDuration(), 1h);
+ QCOMPARE_GT(deadline.deadline<steady_clock>(), steady_clock::now() + 1h - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<steady_clock>(), steady_clock::now() + 1h + 1ms * minResolution);
+ QCOMPARE_GT(deadline.deadline<system_clock>(), system_clock::now() + 1h - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<system_clock>(), system_clock::now() + 1h + 1ms * minResolution);
now = QDeadlineTimer::current(timerType);
- deadline.setDeadline(system_clock::now() + seconds(1), timerType);
+ deadline.setDeadline(system_clock::now() + 1s, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTimeAsDuration() > (seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.remainingTimeAsDuration() <= seconds(1));
- QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + seconds(1) + milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + seconds(1) + milliseconds(minResolution)));
+ QCOMPARE_GT(deadline.remainingTimeAsDuration(), 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.remainingTimeAsDuration(), 1s);
+ QCOMPARE_GT(deadline.deadline<steady_clock>(), steady_clock::now() + 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<steady_clock>(), steady_clock::now() + 1s + 1ms * minResolution);
+ QCOMPARE_GT(deadline.deadline<system_clock>(), system_clock::now() + 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<system_clock>(), system_clock::now() + 1s + 1ms * minResolution);
now = QDeadlineTimer::current(timerType);
- deadline.setDeadline(steady_clock::now() + seconds(1), timerType);
+ deadline.setDeadline(steady_clock::now() + 1s, timerType);
QVERIFY(!deadline.hasExpired());
QVERIFY(!deadline.isForever());
QCOMPARE(deadline.timerType(), timerType);
- QVERIFY(deadline.remainingTimeAsDuration() > (seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.remainingTimeAsDuration() <= seconds(1));
- QVERIFY(deadline.deadline<steady_clock>() > (steady_clock::now() + seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<steady_clock>() <= (steady_clock::now() + seconds(1) + milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() > (system_clock::now() + seconds(1) - milliseconds(minResolution)));
- QVERIFY(deadline.deadline<system_clock>() <= (system_clock::now() + seconds(1) + milliseconds(minResolution)));
-#endif
+ QCOMPARE_GT(deadline.remainingTimeAsDuration(), 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.remainingTimeAsDuration(), 1s);
+ QCOMPARE_GT(deadline.deadline<steady_clock>(), steady_clock::now() + 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<steady_clock>(), steady_clock::now() + 1s + 1ms * minResolution);
+ QCOMPARE_GT(deadline.deadline<system_clock>(), system_clock::now() + 1s - 1ms * minResolution);
+ QCOMPARE_LE(deadline.deadline<system_clock>(), system_clock::now() + 1s + 1ms * minResolution);
}
QTEST_MAIN(tst_QDeadlineTimer)
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
deleted file mode 100644
index 4dd71ca9f4..0000000000
--- a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
+++ /dev/null
@@ -1,4 +0,0 @@
-[elapsed]
-windows
-osx-10.12
-osx-10.13
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt b/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt
new file mode 100644
index 0000000000..9a40a2f905
--- /dev/null
+++ b/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qelapsedtimer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qelapsedtimer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qelapsedtimer
+ SOURCES
+ tst_qelapsedtimer.cpp
+)
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/qelapsedtimer.pro b/tests/auto/corelib/kernel/qelapsedtimer/qelapsedtimer.pro
deleted file mode 100644
index 657a63a5d7..0000000000
--- a/tests/auto/corelib/kernel/qelapsedtimer/qelapsedtimer.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qelapsedtimer
-QT = core testlib
-SOURCES = tst_qelapsedtimer.cpp
-
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp
index 4ee3ca361f..7623fd2e43 100644
--- a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp
+++ b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp
@@ -1,43 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QtCore/QDateTime>
#include <QtCore/QString>
-#include <QtCore/QTime>
#include <QtCore/QElapsedTimer>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QTimer>
static const int minResolution = 100; // the minimum resolution for the tests
+QT_BEGIN_NAMESPACE
QDebug operator<<(QDebug s, const QElapsedTimer &t)
{
s.nospace() << "(" << t.msecsSinceReference() << ")";
return s.space();
}
+QT_END_NAMESPACE
class tst_QElapsedTimer : public QObject
{
@@ -48,15 +26,30 @@ private Q_SLOTS:
void validity();
void basics();
void elapsed();
+ void msecsTo();
};
void tst_QElapsedTimer::statics()
{
- qDebug() << "Clock type is" << QElapsedTimer::clockType();
- qDebug() << "Said clock is" << (QElapsedTimer::isMonotonic() ? "monotonic" : "not monotonic");
+ // these have been required since Qt 6.6
+ QCOMPARE(QElapsedTimer::clockType(), QElapsedTimer::MonotonicClock);
+ QVERIFY(QElapsedTimer::isMonotonic());
+
QElapsedTimer t;
t.start();
- qDebug() << "Current time is" << t.msecsSinceReference();
+ qint64 system_now = QDateTime::currentMSecsSinceEpoch();
+
+ auto setprecision = +[](QTextStream &s) -> QTextStream & {
+ s.setRealNumberNotation(QTextStream::FixedNotation);
+ s.setRealNumberPrecision(3);
+ return s;
+ };
+ qDebug() << setprecision
+ << "Current monotonic time is" << (t.msecsSinceReference() / 1000.)
+ << "s and current system time is" << (system_now / 1000.) << 's';
+ if (qAbs(system_now - t.msecsSinceReference()) < 5 * minResolution)
+ qWarning() << "The monotonic clock is awfully close to the system clock"
+ " (it may not be monotonic at all!)";
}
void tst_QElapsedTimer::validity()
@@ -104,34 +97,59 @@ void tst_QElapsedTimer::basics()
void tst_QElapsedTimer::elapsed()
{
+ qint64 nsecs = 0;
+ qint64 msecs = 0;
+ bool expired1 = false;
+ bool expired8 = false;
+ bool expiredInf = false;
+ qint64 elapsed = 0;
+ bool timerExecuted = false;
+
QElapsedTimer t1;
t1.start();
- QTest::qSleep(2*minResolution);
+ QTimer::singleShot(2 * minResolution, Qt::PreciseTimer, [&](){
+ nsecs = t1.nsecsElapsed();
+ msecs = t1.elapsed();
+ expired1 = t1.hasExpired(minResolution);
+ expired8 = t1.hasExpired(8 * minResolution);
+ expiredInf = t1.hasExpired(-1);
+ elapsed = t1.restart();
+ timerExecuted = true;
+ });
+
+ QTRY_VERIFY2_WITH_TIMEOUT(timerExecuted,
+ "Looks like timer didn't fire on time.", 4 * minResolution);
+
+ QVERIFY(nsecs > 0);
+ QVERIFY(msecs > 0);
+ // the number of elapsed nanoseconds and milliseconds should match
+ QVERIFY(nsecs - msecs * 1000000 < 1000000);
+
+ QVERIFY(expired1);
+ QVERIFY(!expired8);
+ QVERIFY(!expiredInf);
+
+ QVERIFY(elapsed >= msecs);
+ QVERIFY(elapsed < msecs + 3 * minResolution);
+}
+
+void tst_QElapsedTimer::msecsTo()
+{
+ QElapsedTimer t1;
+ t1.start();
+ QTest::qSleep(minResolution);
QElapsedTimer t2;
t2.start();
QVERIFY(t1 != t2);
QVERIFY(!(t1 == t2));
QVERIFY(t1 < t2);
- QVERIFY(t1.msecsTo(t2) > 0);
- QVERIFY(t1.nsecsElapsed() > 0);
- QVERIFY(t1.elapsed() > 0);
- // the number of elapsed nanoseconds and milliseconds should match
- QVERIFY(t1.nsecsElapsed() - t1.elapsed() * 1000000 < 1000000);
- QVERIFY(t1.hasExpired(minResolution));
- QVERIFY(!t1.hasExpired(8*minResolution));
- QVERIFY(!t2.hasExpired(minResolution));
-
- QVERIFY(!t1.hasExpired(-1));
- QVERIFY(!t2.hasExpired(-1));
-
- qint64 elapsed = t1.restart();
- QVERIFY(elapsed > minResolution);
- QVERIFY(elapsed < 3*minResolution);
- qint64 diff = t2.msecsTo(t1);
- QVERIFY(diff < minResolution);
+ auto diff = t1.msecsTo(t2);
+ QVERIFY2(diff > 0, QString("difference t1 and t2 is %1").arg(diff).toLatin1());
+ diff = t2.msecsTo(t1);
+ QVERIFY2(diff < 0, QString("difference t2 and t1 is %1").arg(diff).toLatin1());
}
QTEST_MAIN(tst_QElapsedTimer);
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
deleted file mode 100644
index 06588188d4..0000000000
--- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
+++ /dev/null
@@ -1,6 +0,0 @@
-[sendPostedEvents]
-windows
-[registerTimer]
-windows
-winrt
-osx
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/CMakeLists.txt b/tests/auto/corelib/kernel/qeventdispatcher/CMakeLists.txt
new file mode 100644
index 0000000000..1f9cfb9449
--- /dev/null
+++ b/tests/auto/corelib/kernel/qeventdispatcher/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qeventdispatcher Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qeventdispatcher LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+set(test_names "tst_qeventdispatcher")
+if(QT_FEATURE_glib AND UNIX)
+ list(APPEND test_names "tst_qeventdispatcher_no_glib")
+endif()
+
+foreach(test ${test_names})
+ qt_internal_add_test(${test}
+ NO_BATCH
+ SOURCES
+ tst_qeventdispatcher.cpp
+ )
+endforeach()
+
+if (TARGET tst_qeventdispatcher_no_glib)
+ qt_internal_extend_target(tst_qeventdispatcher_no_glib
+ DEFINES
+ DISABLE_GLIB
+ tst_QEventDispatcher=tst_QEventDispatcher_no_glib
+ )
+endif()
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro b/tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro
deleted file mode 100644
index ff048d0429..0000000000
--- a/tests/auto/corelib/kernel/qeventdispatcher/qeventdispatcher.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qeventdispatcher
-QT = core testlib
-SOURCES += tst_qeventdispatcher.cpp
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp
index 49c10c6a24..285d080960 100644
--- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp
+++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp
@@ -1,72 +1,91 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifdef QT_GUI_LIB
# include <QtGui/QGuiApplication>
-# define tst_QEventDispatcher tst_QGuiEventDispatcher
#else
# include <QtCore/QCoreApplication>
#endif
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QAbstractEventDispatcher>
+#include <QTimer>
+#include <QThreadPool>
+
+#ifdef DISABLE_GLIB
+static bool glibDisabled = []() {
+ qputenv("QT_NO_GLIB", "1");
+ return true;
+}();
+#endif
-enum {
- PreciseTimerInterval = 10,
- CoarseTimerInterval = 200,
- VeryCoarseTimerInterval = 1000
-};
+#include <chrono>
+
+using namespace std::chrono_literals;
+
+static constexpr auto PreciseTimerInterval = 10ms;
+static constexpr auto CoarseTimerInterval = 200ms;
+static constexpr auto VeryCoarseTimerInterval = 1s;
+
+static constexpr
+std::chrono::nanoseconds fudgeInterval(std::chrono::nanoseconds interval, Qt::TimerType timerType)
+{
+ // Make the intervals have have fractions of milliseconds so we can check
+ // that they have been rounded & stored properly (where applicable).
+ switch (timerType) {
+ case Qt::VeryCoarseTimer:
+ // rounds down (floor) to seconds
+ return interval + 1010us;
+ case Qt::CoarseTimer:
+ // rounds up (ceil) to milliseconds
+ return interval - 10us;
+ case Qt::PreciseTimer:
+ // not rounded using QAbstractEventDispatcherV2; rounded up (ceil) on V1
+ return interval - 10us;
+ }
+ Q_UNREACHABLE_RETURN(std::chrono::nanoseconds::min());
+}
class tst_QEventDispatcher : public QObject
{
Q_OBJECT
QAbstractEventDispatcher *eventDispatcher;
- int receivedEventType;
- int timerIdFromEvent;
+
+ int receivedEventType = -1;
+ int timerIdFromEvent = -1;
+ bool doubleTimer = false;
protected:
- bool event(QEvent *e);
+ bool event(QEvent *e) override;
public:
inline tst_QEventDispatcher()
: QObject(),
eventDispatcher(QAbstractEventDispatcher::instance(thread())),
- receivedEventType(-1),
- timerIdFromEvent(-1)
+ isGuiEventDispatcher(QCoreApplication::instance()->inherits("QGuiApplication"))
{ }
private slots:
void initTestCase();
+ void cleanup();
+
void registerTimer();
+
/* void registerSocketNotifier(); */ // Not implemented here, see tst_QSocketNotifier instead
/* void registerEventNotifiier(); */ // Not implemented here, see tst_QWinEventNotifier instead
void sendPostedEvents_data();
void sendPostedEvents();
void processEventsOnlySendsQueuedEvents();
+ // these two tests need to run before postedEventsPingPong
+ void postEventFromThread();
+ void postEventFromEventHandler();
+ // these tests don't leave the event dispatcher in a reliable state
+ void postedEventsPingPong();
+ void eventLoopExit();
+ void interruptTrampling();
+
+private:
+ const bool isGuiEventDispatcher;
};
bool tst_QEventDispatcher::event(QEvent *e)
@@ -74,6 +93,9 @@ bool tst_QEventDispatcher::event(QEvent *e)
switch (receivedEventType = e->type()) {
case QEvent::Timer:
{
+ // sometimes, two timers fire during a single QTRY_xxx wait loop
+ if (timerIdFromEvent != -1)
+ doubleTimer = true;
timerIdFromEvent = static_cast<QTimerEvent *>(e)->timerId();
return true;
}
@@ -86,11 +108,15 @@ bool tst_QEventDispatcher::event(QEvent *e)
// drain the system event queue after the test starts to avoid destabilizing the test functions
void tst_QEventDispatcher::initTestCase()
{
- QElapsedTimer elapsedTimer;
- elapsedTimer.start();
- while (!elapsedTimer.hasExpired(CoarseTimerInterval) && eventDispatcher->processEvents(QEventLoop::AllEvents)) {
- ;
- }
+ QDeadlineTimer deadline(CoarseTimerInterval);
+ while (!deadline.hasExpired() && eventDispatcher->processEvents(QEventLoop::AllEvents))
+ ;
+}
+
+// consume pending posted events to avoid impact on the next test function
+void tst_QEventDispatcher::cleanup()
+{
+ eventDispatcher->processEvents(QEventLoop::AllEvents);
}
class TimerManager {
@@ -111,35 +137,36 @@ public:
TimerManager(TimerManager &&) = delete;
TimerManager &operator=(TimerManager &&) = delete;
- int preciseTimerId() const { return m_preciseTimerId; }
- int coarseTimerId() const { return m_coarseTimerId; }
- int veryCoarseTimerId() const { return m_veryCoarseTimerId; }
+ int preciseTimerId() const { return int(m_preciseTimerId); }
+ int coarseTimerId() const { return int(m_coarseTimerId); }
+ int veryCoarseTimerId() const { return int(m_veryCoarseTimerId); }
- bool foundPrecise() const { return m_preciseTimerId > 0; }
- bool foundCoarse() const { return m_coarseTimerId > 0; }
- bool foundVeryCoarse() const { return m_veryCoarseTimerId > 0; }
+ bool foundPrecise() const { return preciseTimerId() > 0; }
+ bool foundCoarse() const { return coarseTimerId() > 0; }
+ bool foundVeryCoarse() const { return veryCoarseTimerId() > 0; }
- QList<QAbstractEventDispatcher::TimerInfo> registeredTimers() const
+ QList<QAbstractEventDispatcher::TimerInfoV2> registeredTimers() const
{
- return m_eventDispatcher->registeredTimers(m_parent);
+ return m_eventDispatcher->timersForObject(m_parent);
}
void registerAll()
{
// start 3 timers, each with the different timer types and different intervals
- m_preciseTimerId = m_eventDispatcher->registerTimer(
- PreciseTimerInterval, Qt::PreciseTimer, m_parent);
- m_coarseTimerId = m_eventDispatcher->registerTimer(
- CoarseTimerInterval, Qt::CoarseTimer, m_parent);
- m_veryCoarseTimerId = m_eventDispatcher->registerTimer(
- VeryCoarseTimerInterval, Qt::VeryCoarseTimer, m_parent);
- QVERIFY(m_preciseTimerId > 0);
- QVERIFY(m_coarseTimerId > 0);
- QVERIFY(m_veryCoarseTimerId > 0);
+ auto registerTimer = [&](std::chrono::milliseconds interval, Qt::TimerType timerType) {
+ return m_eventDispatcher->registerTimer(fudgeInterval(interval, timerType), timerType,
+ m_parent);
+ };
+ m_preciseTimerId = registerTimer(PreciseTimerInterval, Qt::PreciseTimer);
+ m_coarseTimerId = registerTimer(CoarseTimerInterval, Qt::CoarseTimer);
+ m_veryCoarseTimerId = registerTimer(VeryCoarseTimerInterval, Qt::VeryCoarseTimer);
+ QVERIFY(foundPrecise());
+ QVERIFY(foundCoarse());
+ QVERIFY(foundVeryCoarse());
findTimers();
}
- void unregister(int timerId)
+ void unregister(Qt::TimerId timerId)
{
m_eventDispatcher->unregisterTimer(timerId);
findTimers();
@@ -157,36 +184,43 @@ private:
bool foundPrecise = false;
bool foundCoarse = false;
bool foundVeryCoarse = false;
- const QList<QAbstractEventDispatcher::TimerInfo> timers = registeredTimers();
- for (int i = 0; i < timers.count(); ++i) {
- const QAbstractEventDispatcher::TimerInfo &timerInfo = timers.at(i);
+ const QList<QAbstractEventDispatcher::TimerInfoV2> timers = registeredTimers();
+ for (const QAbstractEventDispatcher::TimerInfoV2 &timerInfo : timers) {
if (timerInfo.timerId == m_preciseTimerId) {
- QCOMPARE(timerInfo.interval, int(PreciseTimerInterval));
+ // For precise timers, we expect the fudge factor to be present
+ QAbstractEventDispatcher::Duration interval =
+ fudgeInterval(PreciseTimerInterval, Qt::PreciseTimer);
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ if (!qobject_cast<QAbstractEventDispatcherV2 *>(m_eventDispatcher))
+ interval = PreciseTimerInterval;
+#endif
+ QCOMPARE(timerInfo.interval, interval);
QCOMPARE(timerInfo.timerType, Qt::PreciseTimer);
foundPrecise = true;
} else if (timerInfo.timerId == m_coarseTimerId) {
- QCOMPARE(timerInfo.interval, int(CoarseTimerInterval));
+ // For other timers, the fudge factors ought to have been rounded away
+ QCOMPARE(timerInfo.interval, CoarseTimerInterval);
QCOMPARE(timerInfo.timerType, Qt::CoarseTimer);
foundCoarse = true;
} else if (timerInfo.timerId == m_veryCoarseTimerId) {
- QCOMPARE(timerInfo.interval, int(VeryCoarseTimerInterval));
+ QCOMPARE(timerInfo.interval, VeryCoarseTimerInterval);
QCOMPARE(timerInfo.timerType, Qt::VeryCoarseTimer);
foundVeryCoarse = true;
}
}
if (!foundPrecise)
- m_preciseTimerId = -1;
+ m_preciseTimerId = Qt::TimerId::Invalid;
if (!foundCoarse)
- m_coarseTimerId = -1;
+ m_coarseTimerId = Qt::TimerId::Invalid;
if (!foundVeryCoarse)
- m_veryCoarseTimerId = -1;
+ m_veryCoarseTimerId = Qt::TimerId::Invalid;
}
QAbstractEventDispatcher *m_eventDispatcher = nullptr;
- int m_preciseTimerId = -1;
- int m_coarseTimerId = -1;
- int m_veryCoarseTimerId = -1;
+ Qt::TimerId m_preciseTimerId = Qt::TimerId::Invalid;
+ Qt::TimerId m_coarseTimerId = Qt::TimerId::Invalid;
+ Qt::TimerId m_veryCoarseTimerId = Qt::TimerId::Invalid;
QObject *m_parent = nullptr;
};
@@ -200,21 +234,42 @@ void tst_QEventDispatcher::registerTimer()
return;
// check that all 3 are present in the eventDispatcher's registeredTimer() list
- QCOMPARE(timers.registeredTimers().count(), 3);
+ QCOMPARE(timers.registeredTimers().size(), 3);
QVERIFY(timers.foundPrecise());
QVERIFY(timers.foundCoarse());
QVERIFY(timers.foundVeryCoarse());
+#ifdef Q_OS_DARWIN
+ /*
+ We frequently experience flaky failures on macOS. Assumption is that this is
+ due to undeterministic VM scheduling, making us process events for significantly
+ longer than expected and resulting in timers firing in undefined order.
+ To detect this condition, we use a QElapsedTimer, and skip the test.
+ */
+ QElapsedTimer elapsedTimer;
+ elapsedTimer.start();
+#endif
+
// process events, waiting for the next event... this should only fire the precise timer
receivedEventType = -1;
timerIdFromEvent = -1;
+ doubleTimer = false;
QTRY_COMPARE_WITH_TIMEOUT(receivedEventType, int(QEvent::Timer), PreciseTimerInterval * 2);
+
+#ifdef Q_OS_DARWIN
+ if (doubleTimer)
+ QSKIP("Double timer during a single timeout - aborting test as flaky on macOS");
+ if (timerIdFromEvent != timers.preciseTimerId()
+ && elapsedTimer.durationElapsed() > PreciseTimerInterval * 3)
+ QSKIP("Ignore flaky test behavior due to VM scheduling on macOS");
+#endif
+
QCOMPARE(timerIdFromEvent, timers.preciseTimerId());
// now unregister it and make sure it's gone
- timers.unregister(timers.preciseTimerId());
+ timers.unregister(Qt::TimerId(timers.preciseTimerId()));
if (QTest::currentTestFailed())
return;
- QCOMPARE(timers.registeredTimers().count(), 2);
+ QCOMPARE(timers.registeredTimers().size(), 2);
QVERIFY(!timers.foundPrecise());
QVERIFY(timers.foundCoarse());
QVERIFY(timers.foundVeryCoarse());
@@ -222,13 +277,23 @@ void tst_QEventDispatcher::registerTimer()
// do the same again for the coarse timer
receivedEventType = -1;
timerIdFromEvent = -1;
+ doubleTimer = false;
QTRY_COMPARE_WITH_TIMEOUT(receivedEventType, int(QEvent::Timer), CoarseTimerInterval * 2);
+
+#ifdef Q_OS_DARWIN
+ if (doubleTimer)
+ QSKIP("Double timer during a single timeout - aborting test as flaky on macOS");
+ if (timerIdFromEvent != timers.coarseTimerId()
+ && elapsedTimer.durationElapsed() > CoarseTimerInterval * 3)
+ QSKIP("Ignore flaky test behavior due to VM scheduling on macOS");
+#endif
+
QCOMPARE(timerIdFromEvent, timers.coarseTimerId());
// now unregister it and make sure it's gone
- timers.unregister(timers.coarseTimerId());
+ timers.unregister(Qt::TimerId(timers.coarseTimerId()));
if (QTest::currentTestFailed())
return;
- QCOMPARE(timers.registeredTimers().count(), 1);
+ QCOMPARE(timers.registeredTimers().size(), 1);
QVERIFY(!timers.foundPrecise());
QVERIFY(!timers.foundCoarse());
QVERIFY(timers.foundVeryCoarse());
@@ -254,9 +319,8 @@ void tst_QEventDispatcher::sendPostedEvents()
QFETCH(int, processEventsFlagsInt);
QEventLoop::ProcessEventsFlags processEventsFlags = QEventLoop::ProcessEventsFlags(processEventsFlagsInt);
- QElapsedTimer elapsedTimer;
- elapsedTimer.start();
- while (!elapsedTimer.hasExpired(200)) {
+ QDeadlineTimer deadline(200ms);
+ while (!deadline.hasExpired()) {
receivedEventType = -1;
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
@@ -278,7 +342,7 @@ public:
inline ProcessEventsOnlySendsQueuedEvents() : eventsReceived(0) {}
- bool event(QEvent *event)
+ bool event(QEvent *event) override
{
++eventsReceived;
@@ -314,5 +378,190 @@ void tst_QEventDispatcher::processEventsOnlySendsQueuedEvents()
QCOMPARE(object.eventsReceived, 4);
}
+void tst_QEventDispatcher::postEventFromThread()
+{
+ QThreadPool *threadPool = QThreadPool::globalInstance();
+ QAtomicInt hadToQuit = false;
+ QAtomicInt done = false;
+
+ threadPool->start([&]{
+ int loop = 1000 / 10; // give it a second
+ while (!done && --loop)
+ QThread::sleep(std::chrono::milliseconds{10});
+ if (done)
+ return;
+ hadToQuit = true;
+ QCoreApplication::eventDispatcher()->wakeUp();
+ });
+
+ struct EventReceiver : public QObject {
+ bool event(QEvent* event) override {
+ if (event->type() == QEvent::User)
+ return true;
+ return QObject::event(event);
+ }
+ } receiver;
+
+ int count = 500;
+ while (!hadToQuit && --count) {
+ threadPool->start([&receiver]{
+ QCoreApplication::postEvent(&receiver, new QEvent(QEvent::User));
+ });
+
+ QAbstractEventDispatcher::instance()->processEvents(QEventLoop::WaitForMoreEvents);
+ }
+ done = true;
+
+ QVERIFY(!hadToQuit);
+ QVERIFY(threadPool->waitForDone());
+}
+
+void tst_QEventDispatcher::postEventFromEventHandler()
+{
+ QThreadPool *threadPool = QThreadPool::globalInstance();
+ QAtomicInt hadToQuit = false;
+ QAtomicInt done = false;
+
+ threadPool->start([&]{
+ int loop = 250 / 10; // give it 250ms
+ while (!done && --loop)
+ QThread::sleep(std::chrono::milliseconds{10});
+ if (done)
+ return;
+ hadToQuit = true;
+ QCoreApplication::eventDispatcher()->wakeUp();
+ });
+
+ struct EventReceiver : public QObject {
+ int i = 0;
+ bool event(QEvent* event) override
+ {
+ if (event->type() == QEvent::User) {
+ ++i;
+ if (i < 2)
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ return true;
+ }
+ return QObject::event(event);
+ }
+ } receiver;
+ QCoreApplication::postEvent(&receiver, new QEvent(QEvent::User));
+ while (receiver.i < 2)
+ QAbstractEventDispatcher::instance()->processEvents(QEventLoop::WaitForMoreEvents);
+ done = true;
+
+ const QByteArrayView eventDispatcherName(QAbstractEventDispatcher::instance()->metaObject()->className());
+ qDebug() << eventDispatcherName;
+ // QXcbUnixEventDispatcher and QEventDispatcherUNIX do not do this correctly on any platform;
+ // both Windows event dispatchers fail as well.
+ const bool knownToFail = eventDispatcherName.contains("UNIX")
+ || eventDispatcherName.contains("Unix")
+ || eventDispatcherName.contains("Win32")
+ || eventDispatcherName.contains("WindowsGui")
+ || eventDispatcherName.contains("Android");
+
+ if (knownToFail)
+ QEXPECT_FAIL("", eventDispatcherName.constData(), Continue);
+
+ QVERIFY(!hadToQuit);
+ QVERIFY(threadPool->waitForDone());
+}
+
+
+void tst_QEventDispatcher::postedEventsPingPong()
+{
+ QEventLoop mainLoop;
+
+ // We need to have at least two levels of nested loops
+ // for the posted event to get stuck (QTBUG-85981).
+ QMetaObject::invokeMethod(this, [this, &mainLoop]() {
+ QMetaObject::invokeMethod(this, [&mainLoop]() {
+ // QEventLoop::quit() should be invoked on the next
+ // iteration of mainLoop.exec().
+ QMetaObject::invokeMethod(&mainLoop, &QEventLoop::quit,
+ Qt::QueuedConnection);
+ }, Qt::QueuedConnection);
+ mainLoop.processEvents();
+ }, Qt::QueuedConnection);
+
+ // We should use Qt::CoarseTimer on Windows, to prevent event
+ // dispatcher from sending a posted event.
+ QTimer::singleShot(500, Qt::CoarseTimer, &mainLoop, [&mainLoop]() {
+ mainLoop.exit(1);
+ });
+
+ QCOMPARE(mainLoop.exec(), 0);
+}
+
+void tst_QEventDispatcher::eventLoopExit()
+{
+ // This test was inspired by QTBUG-79477. A particular
+ // implementation detail in QCocoaEventDispatcher allowed
+ // QEventLoop::exit() to fail to really exit the event loop.
+ // Thus this test is a part of the dispatcher auto-test.
+
+ // Imitates QApplication::exec():
+ QEventLoop mainLoop;
+ // The test itself is a lambda:
+ QTimer::singleShot(0, &mainLoop, [&mainLoop]() {
+ // Two more single shots, both will be posted as events
+ // (zero timeout) and supposed to be processes by the
+ // mainLoop:
+
+ QTimer::singleShot(0, &mainLoop, [&mainLoop]() {
+ // wakeUp triggers QCocoaEventDispatcher into incrementing
+ // its 'serialNumber':
+ mainLoop.wakeUp();
+ // QCocoaEventDispatcher::processEvents() will process
+ // posted events and execute the second lambda defined below:
+ QCoreApplication::processEvents();
+ });
+
+ QTimer::singleShot(0, &mainLoop, [&mainLoop]() {
+ // With QCocoaEventDispatcher this is executed while in the
+ // processEvents (see above) and would fail to actually
+ // interrupt the loop.
+ mainLoop.exit();
+ });
+ });
+
+ bool timeoutObserved = false;
+ QTimer::singleShot(500, &mainLoop, [&timeoutObserved, &mainLoop]() {
+ // In case the QEventLoop::exit above failed, we have to bail out
+ // early, not wasting time:
+ mainLoop.exit();
+ timeoutObserved = true;
+ });
+
+ mainLoop.exec();
+ QVERIFY(!timeoutObserved);
+}
+
+// Based on QTBUG-91539: In the event dispatcher on Windows we overwrite the
+// interrupt once we start processing events (this pattern is also in the 'unix' dispatcher)
+// which would lead the dispatcher to accidentally ignore certain interrupts and,
+// as in the bug report, would not quit, leaving the thread alive and running.
+void tst_QEventDispatcher::interruptTrampling()
+{
+ class WorkerThread : public QThread
+ {
+ void run() override {
+ auto dispatcher = eventDispatcher();
+ QVERIFY(dispatcher);
+ dispatcher->processEvents(QEventLoop::AllEvents);
+ QTimer::singleShot(0, dispatcher, [dispatcher]() {
+ dispatcher->wakeUp();
+ });
+ dispatcher->processEvents(QEventLoop::WaitForMoreEvents);
+ dispatcher->interrupt();
+ dispatcher->processEvents(QEventLoop::WaitForMoreEvents);
+ }
+ };
+ WorkerThread thread;
+ thread.start();
+ QVERIFY(thread.wait(1000));
+ QVERIFY(thread.isFinished());
+}
+
QTEST_MAIN(tst_QEventDispatcher)
#include "tst_qeventdispatcher.moc"
diff --git a/tests/auto/corelib/kernel/qeventloop/BLACKLIST b/tests/auto/corelib/kernel/qeventloop/BLACKLIST
index 6ea6314b0a..772ec3312c 100644
--- a/tests/auto/corelib/kernel/qeventloop/BLACKLIST
+++ b/tests/auto/corelib/kernel/qeventloop/BLACKLIST
@@ -1,2 +1,2 @@
-[testQuitLock]
-windows
+[processEvents]
+qnx # QTBUG-119359
diff --git a/tests/auto/corelib/kernel/qeventloop/CMakeLists.txt b/tests/auto/corelib/kernel/qeventloop/CMakeLists.txt
new file mode 100644
index 0000000000..5d90f97b21
--- /dev/null
+++ b/tests/auto/corelib/kernel/qeventloop/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qeventloop Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qeventloop LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qeventloop
+ SOURCES
+ tst_qeventloop.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qeventloop CONDITION WIN32
+ LIBRARIES
+ user32
+)
+
+qt_internal_extend_target(tst_qeventloop CONDITION QT_FEATURE_glib
+ DEFINES
+ HAVE_GLIB
+)
diff --git a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro
deleted file mode 100644
index 295a42aa9c..0000000000
--- a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qeventloop
-QT = core network testlib core-private
-SOURCES = $$PWD/tst_qeventloop.cpp
-
-win32:!winrt: LIBS += -luser32
-
-qtConfig(glib): DEFINES += HAVE_GLIB
diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
index 482ed8d130..06175e6f2f 100644
--- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
+++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qabstracteventdispatcher.h>
#include <qcoreapplication.h>
@@ -34,7 +9,9 @@
#include <qeventloop.h>
#include <private/qeventloop_p.h>
#if defined(Q_OS_UNIX)
- #include <private/qeventdispatcher_unix_p.h>
+ #if !defined(Q_OS_WASM)
+ #include <private/qeventdispatcher_unix_p.h>
+ #endif
#include <QtCore/private/qcore_unix_p.h>
#if defined(HAVE_GLIB)
#include <private/qeventdispatcher_glib_p.h>
@@ -46,6 +23,7 @@
#include <qwaitcondition.h>
#include <QTcpServer>
#include <QTcpSocket>
+#include <QSignalSpy>
class EventLoopExiter : public QObject
{
@@ -77,7 +55,7 @@ signals:
void checkPoint();
public:
QEventLoop *eventLoop;
- void run();
+ void run() override;
};
void EventLoopThread::run()
@@ -86,7 +64,7 @@ void EventLoopThread::run()
emit checkPoint();
(void) eventLoop->exec();
delete eventLoop;
- eventLoop = 0;
+ eventLoop = nullptr;
}
class MultipleExecThread : public QThread
@@ -101,7 +79,7 @@ public:
volatile int result2;
MultipleExecThread() : result1(0xdead), result2(0xbeef) {}
- void run()
+ void run() override
{
QMutexLocker locker(&mutex);
// this exec should work
@@ -126,7 +104,7 @@ public:
class StartStopEvent: public QEvent
{
public:
- explicit StartStopEvent(int type, QEventLoop *loop = 0)
+ explicit StartStopEvent(int type, QEventLoop *loop = nullptr)
: QEvent(Type(type)), el(loop)
{ }
@@ -162,6 +140,7 @@ class tst_QEventLoop : public QObject
Q_OBJECT
private slots:
// This test *must* run first. See the definition for why.
+ void processEvents_data();
void processEvents();
void exec();
void reexec();
@@ -180,11 +159,24 @@ private slots:
void testQuitLock();
protected:
- void customEvent(QEvent *e);
+ void customEvent(QEvent *e) override;
};
+void tst_QEventLoop::processEvents_data()
+{
+ QTest::addColumn<QString>("mode");
+
+#ifdef QT_GUI_LIB
+ QTest::addRow("gui") << "gui";
+#else
+ QTest::addRow("core") << "core";
+#endif
+}
+
void tst_QEventLoop::processEvents()
{
+ QFETCH(QString, mode);
+
QSignalSpy aboutToBlockSpy(QAbstractEventDispatcher::instance(), &QAbstractEventDispatcher::aboutToBlock);
QSignalSpy awakeSpy(QAbstractEventDispatcher::instance(), &QAbstractEventDispatcher::awake);
@@ -198,8 +190,8 @@ void tst_QEventLoop::processEvents()
// process posted events, QEventLoop::processEvents() should return
// true
QVERIFY(eventLoop.processEvents());
- QCOMPARE(aboutToBlockSpy.count(), 0);
- QCOMPARE(awakeSpy.count(), 1);
+ QCOMPARE(aboutToBlockSpy.size(), 0);
+ QCOMPARE(awakeSpy.size(), 1);
// allow any session manager to complete its handshake, so that
// there are no pending events left. This tests that we are able
@@ -220,8 +212,8 @@ void tst_QEventLoop::processEvents()
// processEvents is entered. There is no guarantee that that the
// processEvents call actually blocked, since the OS may introduce
// native events at any time.
- QVERIFY(awakeSpy.count() > 0);
- QVERIFY(awakeSpy.count() >= aboutToBlockSpy.count());
+ QVERIFY(awakeSpy.size() > 0);
+ QVERIFY(awakeSpy.size() >= aboutToBlockSpy.size());
killTimer(timerId);
}
@@ -264,7 +256,7 @@ void tst_QEventLoop::exec()
QVERIFY(spy.isValid());
thread.cond.wakeOne();
thread.cond.wait(&thread.mutex);
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
int v = thread.result1;
QCOMPARE(v, 0);
@@ -273,7 +265,7 @@ void tst_QEventLoop::exec()
thread.cond.wakeOne();
thread.mutex.unlock();
thread.wait();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
v = thread.result2;
QCOMPARE(v, -1);
}
@@ -331,7 +323,7 @@ void tst_QEventLoop::wakeUp()
QTimer::singleShot(1000, &eventLoop, SLOT(quit()));
(void) eventLoop.exec();
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
thread.quit();
(void) eventLoop.exec();
@@ -424,8 +416,8 @@ public slots:
dataSent = serverSocket->waitForBytesWritten(-1);
if (dataSent) {
- pollfd pfd = qt_make_pollfd(socket->socketDescriptor(), POLLIN);
- dataReadable = (1 == qt_safe_poll(&pfd, 1, nullptr));
+ pollfd pfd = qt_make_pollfd(int(socket->socketDescriptor()), POLLIN);
+ dataReadable = (1 == qt_safe_poll(&pfd, 1, QDeadlineTimer::Forever));
}
if (!dataReadable) {
@@ -446,7 +438,7 @@ class SocketTestThread : public QThread
Q_OBJECT
public:
SocketTestThread():QThread(0),testResult(false){};
- void run()
+ void run() override
{
SocketEventsTester *tester = new SocketEventsTester();
if (tester->init())
@@ -489,7 +481,7 @@ public:
: QObject(), gotTimerEvent(-1)
{ }
- void timerEvent(QTimerEvent *event)
+ void timerEvent(QTimerEvent *event) override
{
gotTimerEvent = event->timerId();
}
@@ -510,7 +502,7 @@ void tst_QEventLoop::processEventsExcludeTimers()
// but not if we exclude timers
eventLoop.processEvents(QEventLoop::X11ExcludeTimers);
-#if defined(Q_OS_UNIX)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
if (!qobject_cast<QEventDispatcherUNIX *>(eventDispatcher)
#if defined(HAVE_GLIB)
@@ -546,7 +538,7 @@ namespace DeliverInDefinedOrder {
}
int lastReceived[NbEventQueue];
int count;
- virtual void customEvent(QEvent* e) {
+ virtual void customEvent(QEvent* e) override {
QVERIFY(e->type() >= QEvent::User);
QVERIFY(e->type() < QEvent::User + 5);
uint idx = e->type() - QEvent::User;
@@ -569,7 +561,8 @@ void tst_QEventLoop::deliverInDefinedOrder()
using namespace DeliverInDefinedOrder;
qMetaTypeId<QThread*>();
QThread threads[NbThread];
- Object objects[NbObject];
+ // GHS compiler needs the namespace prefix, despite using above.
+ DeliverInDefinedOrder::Object objects[NbObject];
for (int t = 0; t < NbThread; t++) {
threads[t].start();
}
@@ -602,12 +595,12 @@ class JobObject : public QObject
Q_OBJECT
public:
- explicit JobObject(QEventLoop *loop, QObject *parent = 0)
+ explicit JobObject(QEventLoop *loop, QObject *parent = nullptr)
: QObject(parent), locker(loop)
{
}
- explicit JobObject(QObject *parent = 0)
+ explicit JobObject(QObject *parent = nullptr)
: QObject(parent)
{
}
@@ -638,16 +631,16 @@ void tst_QEventLoop::testQuitLock()
QEventLoopPrivate* privateClass = static_cast<QEventLoopPrivate*>(QObjectPrivate::get(&eventLoop));
- QCOMPARE(privateClass->quitLockRef.load(), 0);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 0);
JobObject *job1 = new JobObject(&eventLoop, this);
job1->start(500);
- QCOMPARE(privateClass->quitLockRef.load(), 1);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 1);
eventLoop.exec();
- QCOMPARE(privateClass->quitLockRef.load(), 0);
+ QCOMPARE(privateClass->quitLockRef.loadRelaxed(), 0);
job1 = new JobObject(&eventLoop, this);
diff --git a/tests/auto/corelib/kernel/qjniarray/CMakeLists.txt b/tests/auto/corelib/kernel/qjniarray/CMakeLists.txt
new file mode 100644
index 0000000000..308b2c6427
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjniarray/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qjnitypes LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qjniarray
+ SOURCES
+ tst_qjniarray.cpp
+)
diff --git a/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp b/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp
new file mode 100644
index 0000000000..b7b1f95b39
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp
@@ -0,0 +1,165 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest>
+
+#include <QtCore/qjnitypes.h>
+#include <QtCore/qjniarray.h>
+
+using namespace Qt::StringLiterals;
+
+class tst_QJniArray : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QJniArray() = default;
+
+private slots:
+ void construct();
+ void size();
+ void operators();
+};
+
+using namespace QtJniTypes;
+
+// fake type so that we can compile-time test and assert correct type mappings
+Q_DECLARE_JNI_CLASS(List, "qt/test/List");
+
+// verify that we get the return type we expect for the specified return type
+#define VERIFY_RETURN_FOR_TYPE(In, Out) \
+static_assert(std::is_same_v<decltype(List::callStaticMethod<In>("toByteArray")), Out>)
+
+VERIFY_RETURN_FOR_TYPE(jobjectArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jobject[], QJniArray<jobject>);
+//VERIFY_RETURN_FOR_TYPE(QList<QJniObject>, QList<QJniObject>);
+VERIFY_RETURN_FOR_TYPE(QList<jobject>, QList<jobject>);
+
+VERIFY_RETURN_FOR_TYPE(jbyteArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jbyte[], QJniArray<jbyte>);
+VERIFY_RETURN_FOR_TYPE(QByteArray, QByteArray);
+
+VERIFY_RETURN_FOR_TYPE(jbooleanArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jboolean[], QJniArray<jboolean>);
+VERIFY_RETURN_FOR_TYPE(QList<jboolean>, QList<jboolean>);
+VERIFY_RETURN_FOR_TYPE(QList<bool>, QList<jboolean>);
+
+VERIFY_RETURN_FOR_TYPE(jcharArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jchar[], QJniArray<jchar>);
+VERIFY_RETURN_FOR_TYPE(QList<jchar>, QList<jchar>);
+
+VERIFY_RETURN_FOR_TYPE(jshortArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jshort[], QJniArray<jshort>);
+VERIFY_RETURN_FOR_TYPE(QList<jshort>, QList<jshort>);
+VERIFY_RETURN_FOR_TYPE(QList<short>, QList<short>);
+
+VERIFY_RETURN_FOR_TYPE(jintArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jint[], QJniArray<jint>);
+VERIFY_RETURN_FOR_TYPE(QList<jint>, QList<jint>);
+VERIFY_RETURN_FOR_TYPE(QList<int>, QList<int>);
+
+VERIFY_RETURN_FOR_TYPE(jlongArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jlong[], QJniArray<jlong>);
+VERIFY_RETURN_FOR_TYPE(QList<jlong>, QList<jlong>);
+// VERIFY_RETURN_FOR_TYPE(QList<long>, QList<long>); // assumes long is 64bit
+
+VERIFY_RETURN_FOR_TYPE(jfloatArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jfloat[], QJniArray<jfloat>);
+VERIFY_RETURN_FOR_TYPE(QList<jfloat>, QList<jfloat>);
+VERIFY_RETURN_FOR_TYPE(QList<float>, QList<float>);
+
+VERIFY_RETURN_FOR_TYPE(jdoubleArray, QJniObject);
+VERIFY_RETURN_FOR_TYPE(jdouble[], QJniArray<jdouble>);
+VERIFY_RETURN_FOR_TYPE(QList<jdouble>, QList<jdouble>);
+VERIFY_RETURN_FOR_TYPE(QList<double>, QList<double>);
+
+VERIFY_RETURN_FOR_TYPE(QString, QString);
+
+VERIFY_RETURN_FOR_TYPE(List, List);
+VERIFY_RETURN_FOR_TYPE(List[], QJniArray<List>);
+VERIFY_RETURN_FOR_TYPE(QJniArray<List>, QJniArray<List>);
+
+void tst_QJniArray::construct()
+{
+ {
+ QStringList strings;
+ for (int i = 0; i < 10000; ++i)
+ strings << QString::number(i);
+ QJniArray<QString> list(strings);
+ QCOMPARE(list.size(), 10000);
+ }
+ {
+ QJniArray<jint> list{1, 2, 3};
+ QCOMPARE(list.size(), 3);
+ }
+ {
+ QJniArray<jint> list(QList<int>{1, 2, 3});
+ QCOMPARE(list.size(), 3);
+ }
+ {
+ QJniArray<jint> list{QList<int>{1, 2, 3}};
+ QCOMPARE(list.size(), 3);
+ }
+}
+
+void tst_QJniArray::size()
+{
+ QJniArray<jint> array;
+ QVERIFY(!array.isValid());
+ QCOMPARE(array.size(), 0);
+
+ QList<int> intList;
+ intList.resize(10);
+ auto intArray = QJniArrayBase::fromContainer(intList);
+ QCOMPARE(intArray.size(), 10);
+}
+
+void tst_QJniArray::operators()
+{
+ QByteArray bytes("abcde");
+ QJniArray<jbyte> array(bytes);
+ QVERIFY(array.isValid());
+
+ {
+ auto it = array.begin();
+ QCOMPARE(*it, 'a');
+ QCOMPARE(*++it, 'b');
+ QCOMPARE(*it++, 'b');
+ QCOMPARE(*it, 'c');
+ ++it;
+ it++;
+ QCOMPARE(*it, 'e');
+ QCOMPARE(++it, array.end());
+ }
+ {
+ auto it = array.rbegin();
+ QCOMPARE(*it, 'e');
+ QCOMPARE(*++it, 'd');
+ QCOMPARE(*it++, 'd');
+ QCOMPARE(*it, 'c');
+ ++it;
+ it++;
+ QCOMPARE(*it, 'a');
+ QCOMPARE(++it, array.rend());
+ }
+ {
+ QJniArray<jbyte>::const_iterator it = {};
+ QCOMPARE(it, QJniArray<jbyte>::const_iterator{});
+ QCOMPARE_NE(array.begin(), array.end());
+
+ it = array.begin();
+ QCOMPARE(it, array.begin());
+ }
+
+ QCOMPARE(std::distance(array.begin(), array.end()), array.size());
+
+ qsizetype index = 0;
+ for (const auto &value : array) {
+ QCOMPARE(value, bytes.at(index));
+ ++index;
+ }
+}
+
+QTEST_MAIN(tst_QJniArray)
+
+#include "tst_qjniarray.moc"
diff --git a/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt b/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt
new file mode 100644
index 0000000000..f405438314
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qjnienvironment Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qjnienvironment LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qjnienvironment
+ SOURCES
+ tst_qjnienvironment.cpp
+)
+
+if(ANDROID)
+ set_property(TARGET tst_qjnienvironment APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR}/testdata
+ )
+endif()
diff --git a/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java b/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java
new file mode 100644
index 0000000000..4f307b3bc7
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjnienvironment/testdata/src/org/qtproject/qt/android/testdata/QtJniEnvironmentTestClass.java
@@ -0,0 +1,60 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.qt.android.testdatapackage;
+
+public class QtJniEnvironmentTestClass
+{
+ private static native void callbackFromJava(String message);
+ private static native void namedCallbackFromJava(String message);
+ private static native void memberCallbackFromJava(String message);
+ private static native void namedMemberCallbackFromJava(String message);
+ private static native void namespaceCallbackFromJava(String message);
+ private static native void intCallbackFromJava(int value);
+
+ public final int INT_FIELD = 123;
+ public static final int S_INT_FIELD = 321;
+
+ QtJniEnvironmentTestClass() {}
+
+ public static void appendJavaToString(String message)
+ {
+ callbackFromJava("From Java: " + message);
+ }
+
+ public static void namedAppendJavaToString(String message)
+ {
+ namedCallbackFromJava("From Java (named): " + message);
+ }
+
+ public static void memberAppendJavaToString(String message)
+ {
+ memberCallbackFromJava("From Java (member): " + message);
+ }
+
+ public static void namedMemberAppendJavaToString(String message)
+ {
+ namedMemberCallbackFromJava("From Java (named member): " + message);
+ }
+
+ public static void namespaceAppendJavaToString(String message)
+ {
+ namespaceCallbackFromJava("From Java (namespace): " + message);
+ }
+
+ public static void convertToInt(String message)
+ {
+ intCallbackFromJava(Integer.parseInt(message));
+ }
+}
+
+class QtJniEnvironmentTestClassNoCtor
+{
+ private static native void callbackFromJavaNoCtor(String message);
+
+ public static void appendJavaToString(String message)
+ {
+ callbackFromJavaNoCtor("From Java (no ctor): " + message);
+ }
+}
+
diff --git a/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp
new file mode 100644
index 0000000000..95748f46f7
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjnienvironment/tst_qjnienvironment.cpp
@@ -0,0 +1,379 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <jni.h>
+
+#include <QtCore/QJniEnvironment>
+#include <QtCore/QJniObject>
+#include <QtTest/QtTest>
+
+static const char javaTestClass[] =
+ "org/qtproject/qt/android/testdatapackage/QtJniEnvironmentTestClass";
+static const char javaTestClassNoCtor[] =
+ "org/qtproject/qt/android/testdatapackage/QtJniEnvironmentTestClassNoCtor";
+
+static QString registerNativesString = QStringLiteral("Qt");
+static int registerNativeInteger = 0;
+
+class tst_QJniEnvironment : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+ void jniEnv();
+ void javaVM();
+ void registerNativeMethods();
+ void registerNativeMethodsByJclass();
+ void findMethod();
+ void findStaticMethod();
+ void findField();
+ void findStaticField();
+};
+
+void tst_QJniEnvironment::init()
+{
+ // Unless explicitly ignored to test error handling, warning messages
+ // in this test about a failure to look up a field, method, or class
+ // make the test fail.
+ QTest::failOnWarning(QRegularExpression("java.lang.NoSuch.*Error"));
+}
+
+void tst_QJniEnvironment::jniEnv()
+{
+ QJniEnvironment env;
+ JavaVM *javaVM = env.javaVM();
+ QVERIFY(javaVM);
+
+ {
+ // JNI environment should now be attached to the current thread
+ JNIEnv *jni = 0;
+ QCOMPARE(javaVM->GetEnv((void**)&jni, JNI_VERSION_1_6), JNI_OK);
+
+ JNIEnv *e = env.jniEnv();
+ QVERIFY(e);
+
+ QCOMPARE(env->GetVersion(), JNI_VERSION_1_6);
+
+ // try to find an existing class
+ QVERIFY(env->FindClass("java/lang/Object"));
+ QVERIFY(!env->ExceptionCheck());
+
+ // try to find a nonexistent class
+ QVERIFY(!env->FindClass("this/doesnt/Exist"));
+ QVERIFY(env->ExceptionCheck());
+ env->ExceptionClear();
+
+ QVERIFY(env->FindClass("java/lang/Object"));
+ QVERIFY(!QJniEnvironment::checkAndClearExceptions(env.jniEnv()));
+
+ // try to find a nonexistent class
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*"));
+ QVERIFY(!env->FindClass("this/doesnt/Exist"));
+ QVERIFY(QJniEnvironment::checkAndClearExceptions(env.jniEnv()));
+
+ // try to find an existing class with QJniEnvironment
+ QJniEnvironment env;
+ QVERIFY(env.findClass("java/lang/Object"));
+ QVERIFY(env.findClass<jstring>());
+
+ // try to find a nonexistent class
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*"));
+ QVERIFY(!env.findClass("this/doesnt/Exist"));
+
+ // clear exception with member function
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException: .*"));
+ QVERIFY(!env->FindClass("this/doesnt/Exist"));
+ QVERIFY(env.checkAndClearExceptions());
+ }
+
+ // The env does not detach automatically, even if it goes out of scope. The only way it can
+ // be detached is if it's done explicitly, or if the thread we attached to gets killed (TLS clean-up).
+ JNIEnv *jni = nullptr;
+ QCOMPARE(javaVM->GetEnv((void**)&jni, JNI_VERSION_1_6), JNI_OK);
+}
+
+void tst_QJniEnvironment::javaVM()
+{
+ QJniEnvironment env;
+ JavaVM *javaVM = env.javaVM();
+ QVERIFY(javaVM);
+
+ QCOMPARE(env.javaVM(), javaVM);
+
+ JavaVM *vm = 0;
+ QCOMPARE(env->GetJavaVM(&vm), JNI_OK);
+ QCOMPARE(env.javaVM(), vm);
+}
+
+static void callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value)
+{
+ Q_UNUSED(env)
+ registerNativesString = QJniObject(value).toString();
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJava);
+
+static void tediouslyLongNamed_callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value)
+{
+ Q_UNUSED(env)
+ registerNativesString = QJniObject(value).toString();
+}
+Q_DECLARE_JNI_NATIVE_METHOD(tediouslyLongNamed_callbackFromJava, namedCallbackFromJava)
+
+static void callbackFromJavaNoCtor(JNIEnv *env, jobject /*thiz*/, jstring value)
+{
+ Q_UNUSED(env)
+ registerNativesString = QJniObject(value).toString();
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackFromJavaNoCtor);
+
+class CallbackClass {
+public:
+ static void memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value)
+ {
+ Q_UNUSED(env)
+ registerNativesString = QJniObject(value).toString();
+ }
+ Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(memberCallbackFromJava)
+
+ static void tediouslyLongNamed_memberCallbackFromJava(JNIEnv *env, jobject /*thiz*/,
+ jstring value)
+ {
+ Q_UNUSED(env)
+ registerNativesString = QJniObject(value).toString();
+ }
+ Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(tediouslyLongNamed_memberCallbackFromJava,
+ namedMemberCallbackFromJava)
+};
+
+namespace CallbackNamespace {
+ static void namespaceCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value)
+ {
+ Q_UNUSED(env)
+ registerNativesString = QJniObject(value).toString();
+ }
+ Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(namespaceCallbackFromJava)
+}
+
+void tst_QJniEnvironment::registerNativeMethods()
+{
+ QJniObject QtString = QJniObject::fromString(registerNativesString);
+ QJniEnvironment env;
+
+ {
+ QVERIFY(env.registerNativeMethods(javaTestClass, {
+ Q_JNI_NATIVE_METHOD(callbackFromJava)
+ }));
+
+ QJniObject::callStaticMethod<void>(javaTestClass,
+ "appendJavaToString",
+ "(Ljava/lang/String;)V",
+ QtString.object<jstring>());
+ QTest::qWait(200);
+ QVERIFY(registerNativesString == QStringLiteral("From Java: Qt"));
+ }
+
+ // Named native function
+ {
+ QVERIFY(env.registerNativeMethods(javaTestClass, {
+ Q_JNI_NATIVE_METHOD(tediouslyLongNamed_callbackFromJava)
+ }));
+
+ QJniObject::callStaticMethod<void>(javaTestClass,
+ "namedAppendJavaToString",
+ "(Ljava/lang/String;)V",
+ QtString.object<jstring>());
+ QTest::qWait(200);
+ QVERIFY(registerNativesString == QStringLiteral("From Java (named): Qt"));
+ }
+
+ // Static class member as callback
+ {
+ QVERIFY(env.registerNativeMethods(javaTestClass, {
+ Q_JNI_NATIVE_SCOPED_METHOD(memberCallbackFromJava, CallbackClass)
+ }));
+
+ QJniObject::callStaticMethod<void>(javaTestClass,
+ "memberAppendJavaToString",
+ "(Ljava/lang/String;)V",
+ QtString.object<jstring>());
+ QTest::qWait(200);
+ QVERIFY(registerNativesString == QStringLiteral("From Java (member): Qt"));
+ }
+
+ // Static named class member as callback
+ {
+ QVERIFY(env.registerNativeMethods(javaTestClass, {
+ Q_JNI_NATIVE_SCOPED_METHOD(tediouslyLongNamed_memberCallbackFromJava,
+ CallbackClass)
+ }));
+
+ QJniObject::callStaticMethod<void>(javaTestClass,
+ "namedMemberAppendJavaToString",
+ "(Ljava/lang/String;)V",
+ QtString.object<jstring>());
+ QTest::qWait(200);
+ QVERIFY(registerNativesString == QStringLiteral("From Java (named member): Qt"));
+ }
+
+ // Function generally just in namespace as callback
+ {
+ QVERIFY(env.registerNativeMethods(javaTestClass, {
+ Q_JNI_NATIVE_SCOPED_METHOD(namespaceCallbackFromJava, CallbackNamespace)
+ }));
+
+ QJniObject::callStaticMethod<void>(javaTestClass,
+ "namespaceAppendJavaToString",
+ "(Ljava/lang/String;)V",
+ QtString.object<jstring>());
+ QTest::qWait(200);
+ QVERIFY(registerNativesString == QStringLiteral("From Java (namespace): Qt"));
+ }
+
+ // No default constructor in class
+ {
+ QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, {
+ Q_JNI_NATIVE_METHOD(callbackFromJavaNoCtor)
+ }));
+
+ QJniObject::callStaticMethod<void>(javaTestClassNoCtor,
+ "appendJavaToString",
+ "(Ljava/lang/String;)V",
+ QtString.object<jstring>());
+ QTest::qWait(200);
+ QVERIFY(registerNativesString == QStringLiteral("From Java (no ctor): Qt"));
+ }
+}
+
+static void intCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jint value)
+{
+ Q_UNUSED(env)
+ registerNativeInteger = static_cast<int>(value);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(intCallbackFromJava);
+
+void tst_QJniEnvironment::registerNativeMethodsByJclass()
+{
+ QJniEnvironment env;
+ jclass clazz = env.findClass(javaTestClass);
+ QVERIFY(clazz != 0);
+ QVERIFY(env.registerNativeMethods(clazz, {
+ Q_JNI_NATIVE_METHOD(intCallbackFromJava)
+ }));
+
+ QCOMPARE(registerNativeInteger, 0);
+
+ QJniObject parameter = QJniObject::fromString(QString("123"));
+ QJniObject::callStaticMethod<void>(clazz, "convertToInt", "(Ljava/lang/String;)V",
+ parameter.object<jstring>());
+ QTest::qWait(200);
+ QCOMPARE(registerNativeInteger, 123);
+}
+
+void tst_QJniEnvironment::findMethod()
+{
+ QJniEnvironment env;
+ jclass clazz = env.findClass("java/lang/Integer");
+ QVERIFY(clazz != nullptr);
+
+ // existing method
+ jmethodID methodId = env.findMethod(clazz, "toString", "()Ljava/lang/String;");
+ QVERIFY(methodId != nullptr);
+
+ // existing method
+ methodId = env.findMethod<jstring>(clazz, "toString");
+ QVERIFY(methodId != nullptr);
+
+ // invalid signature
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*"));
+ jmethodID invalid = env.findMethod(clazz, "unknown", "()I");
+ QVERIFY(invalid == nullptr);
+ // check that all exceptions are already cleared
+ QVERIFY(!env.checkAndClearExceptions());
+}
+
+void tst_QJniEnvironment::findStaticMethod()
+{
+ QJniEnvironment env;
+ jclass clazz = env.findClass("java/lang/Integer");
+ QVERIFY(clazz != nullptr);
+
+ // existing method
+ jmethodID staticMethodId = env.findStaticMethod(clazz, "parseInt", "(Ljava/lang/String;)I");
+ QVERIFY(staticMethodId != nullptr);
+
+ // existing method
+ staticMethodId = env.findStaticMethod<jint, jstring>(clazz, "parseInt");
+ QVERIFY(staticMethodId != nullptr);
+
+ QJniObject parameter = QJniObject::fromString("123");
+ jint result = QJniObject::callStaticMethod<jint>(clazz, staticMethodId,
+ parameter.object<jstring>());
+ QCOMPARE(result, 123);
+
+ // invalid method
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*"));
+ jmethodID invalid = env.findStaticMethod(clazz, "unknown", "()I");
+ QVERIFY(invalid == nullptr);
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchMethodError: .*"));
+ invalid = env.findStaticMethod<jint>(clazz, "unknown");
+ QVERIFY(invalid == nullptr);
+ // check that all exceptions are already cleared
+ QVERIFY(!env.checkAndClearExceptions());
+}
+
+void tst_QJniEnvironment::findField()
+{
+ QJniEnvironment env;
+ jclass clazz = env.findClass(javaTestClass);
+ QVERIFY(clazz != nullptr);
+
+ // valid field
+ jfieldID validId = env.findField(clazz, "INT_FIELD", "I");
+ QVERIFY(validId != nullptr);
+ validId = env.findField<jint>(clazz, "INT_FIELD");
+ QVERIFY(validId != nullptr);
+
+ jmethodID constructorId = env.findMethod(clazz, "<init>", "()V");
+ QVERIFY(constructorId != nullptr);
+ jobject obj = env->NewObject(clazz, constructorId);
+ QVERIFY(!env.checkAndClearExceptions());
+ int value = env->GetIntField(obj, validId);
+ QVERIFY(!env.checkAndClearExceptions());
+ QVERIFY(value == 123);
+
+ // invalid signature
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchFieldError: .*"));
+ jfieldID invalidId = env.findField(clazz, "unknown", "I");
+ QVERIFY(invalidId == nullptr);
+ // check that all exceptions are already cleared
+ QVERIFY(!env.checkAndClearExceptions());
+}
+
+void tst_QJniEnvironment::findStaticField()
+{
+ QJniEnvironment env;
+ jclass clazz = env.findClass(javaTestClass);
+ QVERIFY(clazz != nullptr);
+
+ // valid field
+ jfieldID validId = env.findStaticField(clazz, "S_INT_FIELD", "I");
+ QVERIFY(validId != nullptr);
+ validId = env.findStaticField<jint>(clazz, "S_INT_FIELD");
+ QVERIFY(validId != nullptr);
+
+ int size = env->GetStaticIntField(clazz, validId);
+ QVERIFY(!env.checkAndClearExceptions());
+ QVERIFY(size == 321);
+
+ // invalid signature
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.NoSuchFieldError: .*"));
+ jfieldID invalidId = env.findStaticField(clazz, "unknown", "I");
+ QVERIFY(invalidId == nullptr);
+ // check that all exceptions are already cleared
+ QVERIFY(!env.checkAndClearExceptions());
+}
+
+QTEST_MAIN(tst_QJniEnvironment)
+
+#include "tst_qjnienvironment.moc"
diff --git a/tests/auto/corelib/kernel/qjniobject/CMakeLists.txt b/tests/auto/corelib/kernel/qjniobject/CMakeLists.txt
new file mode 100644
index 0000000000..98509dc0e5
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjniobject/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qjniobject Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qjniobject LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qjniobject
+ SOURCES
+ tst_qjniobject.cpp
+)
+
+if(ANDROID)
+ set_property(TARGET tst_qjniobject APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR}/testdata
+ )
+endif()
diff --git a/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java b/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java
new file mode 100644
index 0000000000..07a94d1cac
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java
@@ -0,0 +1,345 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+package org.qtproject.qt.android.testdatapackage;
+
+public class QtJniObjectTestClass
+{
+ static final byte A_BYTE_VALUE = 127;
+ static final short A_SHORT_VALUE = 32767;
+ static final int A_INT_VALUE = 060701;
+ static final long A_LONG_VALUE = 060701;
+ static final float A_FLOAT_VALUE = 1.0f;
+ static final double A_DOUBLE_VALUE = 1.0;
+ static final boolean A_BOOLEAN_VALUE = true;
+ static final char A_CHAR_VALUE = 'Q';
+ static final String A_STRING_OBJECT = "TEST_DATA_STRING";
+ static final Class A_CLASS_OBJECT = QtJniObjectTestClass.class;
+ static final Object A_OBJECT_OBJECT = new QtJniObjectTestClass();
+ static final Throwable A_THROWABLE_OBJECT = new Throwable(A_STRING_OBJECT);
+
+ // --------------------------------------------------------------------------------------------
+
+ final int INT_FIELD = 123;
+ final boolean BOOL_FIELD = true;
+
+ byte BYTE_VAR;
+ short SHORT_VAR;
+ int INT_VAR;
+ long LONG_VAR;
+ float FLOAT_VAR;
+ double DOUBLE_VAR;
+ boolean BOOLEAN_VAR;
+ char CHAR_VAR;
+ String STRING_OBJECT_VAR;
+
+ static byte S_BYTE_VAR;
+ static short S_SHORT_VAR;
+ static int S_INT_VAR;
+ static long S_LONG_VAR;
+ static float S_FLOAT_VAR;
+ static double S_DOUBLE_VAR;
+ static boolean S_BOOLEAN_VAR;
+ static char S_CHAR_VAR;
+ static String S_STRING_OBJECT_VAR;
+
+ // --------------------------------------------------------------------------------------------
+ public static void staticVoidMethod() { return; }
+ public static void staticVoidMethodWithArgs(int a, boolean b, char c) { return; }
+
+ public void voidMethod() { return; }
+ public void voidMethodWithArgs(int a, boolean b, char c) { return; }
+
+ // --------------------------------------------------------------------------------------------
+ public static boolean staticBooleanMethod() { return A_BOOLEAN_VALUE; }
+ public static boolean staticBooleanMethodWithArgs(boolean a, boolean b, boolean c)
+ { return staticBooleanMethod(); }
+
+ public boolean booleanMethod() { return staticBooleanMethod(); }
+ public boolean booleanMethodWithArgs(boolean a, boolean b, boolean c)
+ { return staticBooleanMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static byte staticByteMethod() { return A_BYTE_VALUE; }
+ public static byte staticByteMethodWithArgs(byte a, byte b, byte c) { return staticByteMethod(); }
+
+ public byte byteMethod() { return staticByteMethod(); }
+ public byte byteMethodWithArgs(byte a, byte b, byte c)
+ { return staticByteMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static char staticCharMethod() { return A_CHAR_VALUE; }
+ public static char staticCharMethodWithArgs(char a, char b, char c) { return staticCharMethod(); }
+
+ public char charMethod() { return staticCharMethod(); }
+ public char charMethodWithArgs(char a, char b, char c)
+ { return staticCharMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static short staticShortMethod() { return A_SHORT_VALUE; }
+ public static short staticShortMethodWithArgs(short a, short b, short c) { return staticShortMethod(); }
+
+ public short shortMethod() { return staticShortMethod(); }
+ public short shortMethodWithArgs(short a, short b, short c)
+ { return staticShortMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static int staticIntMethod() { return A_INT_VALUE; }
+ public static int staticIntMethodWithArgs(int a, int b, int c) { return staticIntMethod(); }
+
+ public int intMethod() { return staticIntMethod(); }
+ public int intMethodWithArgs(int a, int b, int c) { return staticIntMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static long staticLongMethod() { return A_LONG_VALUE; }
+ public static long staticLongMethodWithArgs(long a, long b, long c) { return staticLongMethod(); }
+
+ public long longMethod() { return staticLongMethod(); }
+ public long longMethodWithArgs(long a, long b, long c)
+ { return staticLongMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static float staticFloatMethod() { return A_FLOAT_VALUE; }
+ public static float staticFloatMethodWithArgs(float a, float b, float c) { return staticFloatMethod(); }
+
+ public float floatMethod() { return staticFloatMethod(); }
+ public float floatMethodWithArgs(float a, float b, float c)
+ { return staticFloatMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static double staticDoubleMethod() { return A_DOUBLE_VALUE; }
+ public static double staticDoubleMethodWithArgs(double a, double b, double c)
+ { return staticDoubleMethod(); }
+
+ public double doubleMethod() { return staticDoubleMethod(); }
+ public double doubleMethodWithArgs(double a, double b, double c)
+ { return staticDoubleMethodWithArgs(a, b, c); }
+
+ // --------------------------------------------------------------------------------------------
+ public static Object staticObjectMethod() { return A_OBJECT_OBJECT; }
+ public Object objectMethod() { return staticObjectMethod(); }
+
+ // --------------------------------------------------------------------------------------------
+ public static Class staticClassMethod() { return A_CLASS_OBJECT; }
+ public Class classMethod() { return staticClassMethod(); }
+
+ // --------------------------------------------------------------------------------------------
+ public static String staticStringMethod() { return A_STRING_OBJECT; }
+ public String stringMethod() { return staticStringMethod(); }
+
+ // --------------------------------------------------------------------------------------------
+ public static String staticEchoMethod(String value) { return value; }
+
+ // --------------------------------------------------------------------------------------------
+ public static Throwable staticThrowableMethod() { return A_THROWABLE_OBJECT; }
+ public Throwable throwableMethod() { return staticThrowableMethod(); }
+
+ // --------------------------------------------------------------------------------------------
+ public static Object[] staticObjectArrayMethod()
+ { Object[] array = { new Object(), new Object(), new Object() }; return array; }
+ public Object[] objectArrayMethod() { return staticObjectArrayMethod(); }
+ public static Object[] staticReverseObjectArray(Object[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ Object old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public Object[] reverseObjectArray(Object[] array)
+ { return staticReverseObjectArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static boolean[] staticBooleanArrayMethod()
+ { boolean[] array = { true, true, true }; return array; }
+ public boolean[] booleanArrayMethod() { return staticBooleanArrayMethod(); }
+ public static boolean[] staticReverseBooleanArray(boolean[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ boolean old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public boolean[] reverseBooleanArray(boolean[] array)
+ { return staticReverseBooleanArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static byte[] staticByteArrayMethod()
+ { byte[] array = { 'a', 'b', 'c' }; return array; }
+ public byte[] byteArrayMethod() { return staticByteArrayMethod(); }
+ public static byte[] staticReverseByteArray(byte[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ byte old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public byte[] reverseByteArray(byte[] array)
+ { return staticReverseByteArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static char[] staticCharArrayMethod()
+ { char[] array = { 'a', 'b', 'c' }; return array; }
+ public char[] charArrayMethod() { return staticCharArrayMethod(); }
+ public static char[] staticReverseCharArray(char[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ char old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public char[] reverseCharArray(char[] array)
+ { return staticReverseCharArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static short[] staticShortArrayMethod() { short[] array = { 3, 2, 1 }; return array; }
+ public short[] shortArrayMethod() { return staticShortArrayMethod(); }
+ public static short[] staticReverseShortArray(short[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ short old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public short[] reverseShortArray(short[] array)
+ { return staticReverseShortArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static int[] staticIntArrayMethod() { int[] array = { 3, 2, 1 }; return array; }
+ public int[] intArrayMethod() { return staticIntArrayMethod(); }
+ public static int[] staticReverseIntArray(int[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ int old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public int[] reverseIntArray(int[] array)
+ { return staticReverseIntArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static long[] staticLongArrayMethod()
+ { long[] array = { 3, 2, 1 }; return array; }
+ public long[] longArrayMethod() { return staticLongArrayMethod(); }
+ public static long[] staticReverseLongArray(long[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ long old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public long[] reverseLongArray(long[] array)
+ { return staticReverseLongArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static float[] staticFloatArrayMethod()
+ { float[] array = { 1.0f, 2.0f, 3.0f }; return array; }
+ public float[] floatArrayMethod() { return staticFloatArrayMethod(); }
+ public static float[] staticReverseFloatArray(float[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ float old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public float[] reverseFloatArray(float[] array)
+ { return staticReverseFloatArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ public static double[] staticDoubleArrayMethod()
+ { double[] array = { 3.0, 2.0, 1.0 }; return array; }
+ public double[] doubleArrayMethod() { return staticDoubleArrayMethod(); }
+ public static double[] staticReverseDoubleArray(double[] array)
+ {
+ for (int i = 0; i < array.length / 2; ++i) {
+ double old = array[array.length - i - 1];
+ array[array.length - i - 1] = array[i];
+ array[i] = old;
+ }
+ return array;
+ }
+ public double[] reverseDoubleArray(double[] array)
+ { return staticReverseDoubleArray(array); }
+
+ // --------------------------------------------------------------------------------------------
+ native public int callbackWithObject(QtJniObjectTestClass that);
+ native public int callbackWithObjectRef(QtJniObjectTestClass that);
+ native public int callbackWithString(String string);
+ native public int callbackWithByte(byte value);
+ native public int callbackWithBoolean(boolean value);
+ native public int callbackWithInt(int value);
+ native public int callbackWithDouble(double value);
+ native public int callbackWithJniArray(double[] value);
+ native public int callbackWithQList(double[] value);
+ native public int callbackWithStringList(String[] value);
+
+ public int callMeBackWithObject(QtJniObjectTestClass that)
+ {
+ return callbackWithObject(that);
+ }
+
+ public int callMeBackWithObjectRef(QtJniObjectTestClass that)
+ {
+ return callbackWithObjectRef(that);
+ }
+
+ public int callMeBackWithString(String string)
+ {
+ return callbackWithString(string);
+ }
+
+ public int callMeBackWithByte(byte value)
+ {
+ return callbackWithByte(value);
+ }
+
+ public int callMeBackWithBoolean(boolean value)
+ {
+ return callbackWithBoolean(value);
+ }
+
+ public int callMeBackWithInt(int value)
+ {
+ return callbackWithInt(value);
+ }
+
+ public int callMeBackWithDouble(double value)
+ {
+ return callbackWithDouble(value);
+ }
+ public int callMeBackWithJniArray(double[] value)
+ {
+ return callbackWithJniArray(value);
+ }
+ public int callMeBackWithQList(double[] value)
+ {
+ return callbackWithQList(value);
+ }
+ public int callMeBackWithStringList(String[] value)
+ {
+ return callbackWithStringList(value);
+ }
+
+ public Object callMethodThrowsException() throws Exception {
+ throw new Exception();
+ }
+
+ public static Object callStaticMethodThrowsException() throws Exception {
+ throw new Exception();
+ }
+}
diff --git a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
new file mode 100644
index 0000000000..64b464e002
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
@@ -0,0 +1,2108 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <jni.h>
+
+#include <QString>
+#include <QtCore/QJniEnvironment>
+#include <QtCore/QJniObject>
+#include <QtTest>
+
+using namespace Qt::StringLiterals;
+
+static constexpr const char testClassName[] = "org/qtproject/qt/android/testdatapackage/QtJniObjectTestClass";
+Q_DECLARE_JNI_CLASS(QtJniObjectTestClass, testClassName)
+using TestClass = QtJniTypes::QtJniObjectTestClass;
+
+static const jbyte A_BYTE_VALUE = 127;
+static const jshort A_SHORT_VALUE = 32767;
+static const jint A_INT_VALUE = 060701;
+static const jlong A_LONG_VALUE = 060701;
+static const jfloat A_FLOAT_VALUE = 1.0;
+static const jdouble A_DOUBLE_VALUE = 1.0;
+static const jchar A_CHAR_VALUE = 'Q';
+
+static QString A_STRING_OBJECT()
+{
+ return QStringLiteral("TEST_DATA_STRING");
+}
+
+class tst_QJniObject : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QJniObject();
+
+private slots:
+ void initTestCase();
+ void init();
+
+ void ctor();
+ void callMethodTest();
+ void callMethodThrowsException();
+ void callObjectMethodTest();
+ void stringConvertionTest();
+ void compareOperatorTests();
+ void className();
+ void callStaticMethodThrowsException();
+ void callStaticObjectMethodClassName();
+ void callStaticObjectMethod();
+ void callStaticObjectMethodById();
+ void callStaticBooleanMethodClassName();
+ void callStaticBooleanMethod();
+ void callStaticBooleanMethodById();
+ void callStaticCharMethodClassName();
+ void callStaticCharMethod();
+ void callStaticCharMethodById();
+ void callStaticIntMethodClassName();
+ void callStaticIntMethod();
+ void callStaticIntMethodById();
+ void callStaticByteMethodClassName();
+ void callStaticByteMethod();
+ void callStaticByteMethodById();
+ void callStaticDoubleMethodClassName();
+ void callStaticDoubleMethod();
+ void callStaticDoubleMethodById();
+ void callStaticFloatMethodClassName();
+ void callStaticFloatMethod();
+ void callStaticFloatMethodById();
+ void callStaticLongMethodClassName();
+ void callStaticLongMethod();
+ void callStaticLongMethodById();
+ void callStaticShortMethodClassName();
+ void callStaticShortMethod();
+ void callStaticShortMethodById();
+ void getStaticObjectFieldClassName();
+ void getStaticObjectField();
+ void getStaticIntFieldClassName();
+ void getStaticIntField();
+ void getStaticByteFieldClassName();
+ void getStaticByteField();
+ void getStaticBooleanField();
+ void getStaticLongFieldClassName();
+ void getStaticLongField();
+ void getStaticDoubleFieldClassName();
+ void getStaticDoubleField();
+ void getStaticFloatFieldClassName();
+ void getStaticFloatField();
+ void getStaticShortFieldClassName();
+ void getStaticShortField();
+ void getStaticCharFieldClassName();
+ void getStaticCharField();
+ void getBooleanField();
+ void getIntField();
+
+ void setIntField();
+ void setByteField();
+ void setLongField();
+ void setDoubleField();
+ void setFloatField();
+ void setShortField();
+ void setCharField();
+ void setBooleanField();
+ void setObjectField();
+ void setStaticIntField();
+ void setStaticByteField();
+ void setStaticLongField();
+ void setStaticDoubleField();
+ void setStaticFloatField();
+ void setStaticShortField();
+ void setStaticCharField();
+ void setStaticBooleanField();
+ void setStaticObjectField();
+
+ void templateApiCheck();
+ void isClassAvailable();
+ void fromLocalRef();
+ void largeObjectArray();
+
+ void callback_data();
+ void callback();
+ void callStaticOverloadResolution();
+
+ void cleanupTestCase();
+};
+
+tst_QJniObject::tst_QJniObject()
+{
+}
+
+void tst_QJniObject::initTestCase()
+{
+}
+
+void tst_QJniObject::init()
+{
+ // Unless explicitly ignored to test error handling, warning messages
+ // in this test about a failure to look up a field, method, or class
+ // make the test fail.
+ QTest::failOnWarning(QRegularExpression("java.lang.NoSuch.*Error"));
+}
+
+void tst_QJniObject::cleanupTestCase()
+{
+}
+
+void tst_QJniObject::ctor()
+{
+ {
+ QJniObject object;
+ QVERIFY(!object.isValid());
+ }
+
+ {
+ QJniObject object("java/lang/String");
+ QVERIFY(object.isValid());
+ }
+
+ {
+ QJniObject object = QJniObject::construct<jstring>();
+ QVERIFY(object.isValid());
+ }
+
+ {
+ // from Qt 6.7 on we can construct declared classes through the helper type
+ QJniObject object = TestClass::construct();
+ QVERIFY(object.isValid());
+
+ // or even directly
+ TestClass testObject;
+ QVERIFY(testObject.isValid());
+ }
+
+ {
+ QJniObject string = QJniObject::fromString(QLatin1String("Hello, Java"));
+ QJniObject object("java/lang/String", "(Ljava/lang/String;)V", string.object<jstring>());
+ QVERIFY(object.isValid());
+ QCOMPARE(string.toString(), object.toString());
+ }
+
+ {
+ QJniObject string = QJniObject::fromString(QLatin1String("Hello, Java"));
+ QJniObject object = QJniObject::construct<jstring>(string.object<jstring>());
+ QVERIFY(object.isValid());
+ QCOMPARE(string.toString(), object.toString());
+ }
+
+ {
+ QJniEnvironment env;
+ jclass javaStringClass = env->FindClass("java/lang/String");
+ QJniObject string(javaStringClass);
+ QVERIFY(string.isValid());
+ }
+
+ {
+ QJniEnvironment env;
+ const QString qString = QLatin1String("Hello, Java");
+ jclass javaStringClass = env->FindClass("java/lang/String");
+ QJniObject string = QJniObject::fromString(qString);
+ QJniObject stringCpy(javaStringClass, "(Ljava/lang/String;)V", string.object<jstring>());
+ QVERIFY(stringCpy.isValid());
+ QCOMPARE(qString, stringCpy.toString());
+ }
+
+ {
+ QJniEnvironment env;
+ const QString qString = QLatin1String("Hello, Java");
+ jclass javaStringClass = env->FindClass("java/lang/String");
+ QJniObject string = QJniObject::fromString(qString);
+ QJniObject stringCpy(javaStringClass, string.object<jstring>());
+ QVERIFY(stringCpy.isValid());
+ QCOMPARE(qString, stringCpy.toString());
+ }
+}
+
+void tst_QJniObject::callMethodTest()
+{
+ {
+ const QString qString1 = u"Hello, Java"_s;
+ const QString qString2 = u"hELLO, jAVA"_s;
+ QJniObject jString1 = QJniObject::fromString(qString1);
+ QJniObject jString2 = QJniObject::fromString(qString2);
+ QVERIFY(jString1 != jString2);
+
+ const jboolean isEmpty = jString1.callMethod<jboolean>("isEmpty");
+ QVERIFY(!isEmpty);
+
+ jint ret = jString1.callMethod<jint>("compareToIgnoreCase",
+ "(Ljava/lang/String;)I",
+ jString2.object<jstring>());
+ QVERIFY(0 == ret);
+
+ ret = jString1.callMethod<jint>("compareToIgnoreCase", jString2.object<jstring>());
+ QVERIFY(0 == ret);
+
+ // as of Qt 6.7, we can pass QString directly
+ ret = jString1.callMethod<jint>("compareToIgnoreCase", qString2);
+ QVERIFY(0 == ret);
+ }
+
+ {
+ jlong jLong = 100;
+ QJniObject longObject("java/lang/Long", "(J)V", jLong);
+ jlong ret = longObject.callMethod<jlong>("longValue");
+ QCOMPARE(ret, jLong);
+ }
+
+ // as of Qt 6.4, callMethod works with an object type as well!
+ {
+ const QString qString = QLatin1String("Hello, Java");
+ QJniObject jString = QJniObject::fromString(qString);
+ const QString qStringRet = jString.callMethod<jstring>("toUpperCase").toString();
+ QCOMPARE(qString.toUpper(), qStringRet);
+
+ QJniObject subString = jString.callMethod<jstring>("substring", 0, 4);
+ QCOMPARE(subString.toString(), qString.mid(0, 4));
+
+ // and as of Qt 6.7, we can return and take QString directly
+ QCOMPARE(jString.callMethod<QString>("substring", 0, 4), qString.mid(0, 4));
+
+ QCOMPARE(jString.callMethod<jstring>("substring", 0, 7)
+ .callMethod<jstring>("toUpperCase")
+ .callMethod<QString>("concat", u"C++"_s), u"HELLO, C++"_s);
+ }
+}
+
+void tst_QJniObject::callMethodThrowsException()
+{
+ QtJniTypes::QtJniObjectTestClass instance;
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.Exception"));
+ auto res = instance.callMethod<jobject>("callMethodThrowsException");
+ QVERIFY(!res.isValid());
+ QVERIFY(!QJniEnvironment().checkAndClearExceptions());
+}
+
+void tst_QJniObject::callObjectMethodTest()
+{
+ const QString qString = QLatin1String("Hello, Java");
+ QJniObject jString = QJniObject::fromString(qString);
+ const QString qStringRet = jString.callObjectMethod<jstring>("toUpperCase").toString();
+ QCOMPARE(qString.toUpper(), qStringRet);
+
+ QJniObject subString = jString.callObjectMethod("substring",
+ "(II)Ljava/lang/String;",
+ 0, 4);
+ QCOMPARE(subString.toString(), qString.mid(0, 4));
+
+ subString = jString.callObjectMethod<jstring>("substring", 0, 4);
+ QCOMPARE(subString.toString(), qString.mid(0, 4));
+
+}
+
+void tst_QJniObject::stringConvertionTest()
+{
+ const QString qString(QLatin1String("Hello, Java"));
+ QJniObject jString = QJniObject::fromString(qString);
+ QVERIFY(jString.isValid());
+ QString qStringRet = jString.toString();
+ QCOMPARE(qString, qStringRet);
+}
+
+void tst_QJniObject::compareOperatorTests()
+{
+ QString str("hello!");
+ QJniObject stringObject = QJniObject::fromString(str);
+
+ jobject obj = stringObject.object();
+ jobject jobj = stringObject.object<jobject>();
+ jstring jsobj = stringObject.object<jstring>();
+
+ QVERIFY(obj == stringObject);
+ QVERIFY(jobj == stringObject);
+ QVERIFY(stringObject == jobj);
+ QVERIFY(jsobj == stringObject);
+ QVERIFY(stringObject == jsobj);
+
+ QJniObject stringObject3 = stringObject.object<jstring>();
+ QVERIFY(stringObject3 == stringObject);
+
+ QJniObject stringObject2 = QJniObject::fromString(str);
+ QVERIFY(stringObject != stringObject2);
+
+ jstring jstrobj = nullptr;
+ QJniObject invalidStringObject;
+ QVERIFY(invalidStringObject == jstrobj);
+
+ QVERIFY(jstrobj != stringObject);
+ QVERIFY(stringObject != jstrobj);
+ QVERIFY(!invalidStringObject.isValid());
+}
+
+void tst_QJniObject::className()
+{
+ const QString str("Hello!");
+ QJniObject jString = QJniObject::fromString(str);
+ {
+ QCOMPARE(jString.className(), "java/lang/String");
+ QCOMPARE(jString.toString(), str);
+ }
+
+ {
+ QJniObject strObject = QJniObject("java/lang/String", str);
+ QCOMPARE(strObject.className(), "java/lang/String");
+ QCOMPARE(strObject.toString(), str);
+ }
+
+ {
+ TestClass test;
+ QCOMPARE(test.className(), testClassName);
+ }
+}
+
+void tst_QJniObject::callStaticMethodThrowsException()
+{
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.Exception"));
+ auto res = QtJniTypes::QtJniObjectTestClass::callStaticMethod<jobject>(
+ "callStaticMethodThrowsException");
+ QVERIFY(!res.isValid());
+ QVERIFY(!QJniEnvironment().checkAndClearExceptions());
+}
+
+void tst_QJniObject::callStaticObjectMethodClassName()
+{
+ QJniObject formatString = QJniObject::fromString(QLatin1String("test format"));
+ QVERIFY(formatString.isValid());
+
+ QVERIFY(QJniObject::isClassAvailable("java/lang/String"));
+ QJniObject returnValue = QJniObject::callStaticObjectMethod("java/lang/String",
+ "format",
+ "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+
+ QString returnedString = returnValue.toString();
+
+ QCOMPARE(returnedString, QString::fromLatin1("test format"));
+
+ returnValue = QJniObject::callStaticObjectMethod<jstring>("java/lang/String",
+ "format",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+
+ returnedString = returnValue.toString();
+
+ QCOMPARE(returnedString, QString::fromLatin1("test format"));
+}
+
+void tst_QJniObject::callStaticObjectMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/String");
+ QVERIFY(cls != 0);
+
+ const QString string = u"test format"_s;
+ QJniObject formatString = QJniObject::fromString(string);
+ QVERIFY(formatString.isValid());
+
+ QJniObject returnValue = QJniObject::callStaticObjectMethod(cls,
+ "format",
+ "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+ QCOMPARE(returnValue.toString(), string);
+
+ returnValue = QJniObject::callStaticObjectMethod<jstring>(cls,
+ "format",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+ QCOMPARE(returnValue.toString(), string);
+
+ // from 6.4 on we can use callStaticMethod
+ returnValue = QJniObject::callStaticMethod<jstring>(cls,
+ "format",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+ QCOMPARE(returnValue.toString(), string);
+
+ // from 6.7 we can use callStaticMethod without specifying the class string
+ returnValue = QJniObject::callStaticMethod<jstring, jstring>("format",
+ formatString.object<jstring>(),
+ jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+ QCOMPARE(returnValue.toString(), string);
+
+ // from 6.7 we can pass QString directly, both as parameters and return type
+ QString result = QJniObject::callStaticMethod<jstring, QString>("format",
+ string,
+ jobjectArray(0));
+ QCOMPARE(result, string);
+}
+
+void tst_QJniObject::callStaticObjectMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/String");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(
+ cls, "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
+ QVERIFY(id != 0);
+
+ QJniObject formatString = QJniObject::fromString(QLatin1String("test format"));
+ QVERIFY(formatString.isValid());
+
+ QJniObject returnValue = QJniObject::callStaticObjectMethod(
+ cls, id, formatString.object<jstring>(), jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+
+ QString returnedString = returnValue.toString();
+
+ QCOMPARE(returnedString, QString::fromLatin1("test format"));
+
+ // from Qt 6.4 on we can use callStaticMethod as well
+ returnValue = QJniObject::callStaticMethod<jstring>(
+ cls, id, formatString.object<jstring>(), jobjectArray(0));
+ QVERIFY(returnValue.isValid());
+
+ returnedString = returnValue.toString();
+
+ QCOMPARE(returnedString, QString::fromLatin1("test format"));
+}
+
+void tst_QJniObject::callStaticBooleanMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Boolean");
+ QVERIFY(cls != 0);
+
+ {
+ QJniObject parameter = QJniObject::fromString("true");
+ QVERIFY(parameter.isValid());
+
+ jboolean b = QJniObject::callStaticMethod<jboolean>(cls,
+ "parseBoolean",
+ "(Ljava/lang/String;)Z",
+ parameter.object<jstring>());
+ QVERIFY(b);
+
+ b = QJniObject::callStaticMethod<jboolean>(cls, "parseBoolean", parameter.object<jstring>());
+ QVERIFY(b);
+ }
+
+ {
+ QJniObject parameter = QJniObject::fromString("false");
+ QVERIFY(parameter.isValid());
+
+ jboolean b = QJniObject::callStaticMethod<jboolean>(cls,
+ "parseBoolean",
+ "(Ljava/lang/String;)Z",
+ parameter.object<jstring>());
+ QVERIFY(!b);
+
+ b = QJniObject::callStaticMethod<jboolean>(cls, "parseBoolean", parameter.object<jstring>());
+ QVERIFY(!b);
+ }
+}
+
+void tst_QJniObject::callStaticBooleanMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Boolean");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseBoolean", "(Ljava/lang/String;)Z");
+ QVERIFY(id != 0);
+
+ {
+ QJniObject parameter = QJniObject::fromString("true");
+ QVERIFY(parameter.isValid());
+
+ jboolean b = QJniObject::callStaticMethod<jboolean>(cls, id, parameter.object<jstring>());
+ QVERIFY(b);
+ }
+
+ {
+ QJniObject parameter = QJniObject::fromString("false");
+ QVERIFY(parameter.isValid());
+
+ jboolean b = QJniObject::callStaticMethod<jboolean>(cls, id, parameter.object<jstring>());
+ QVERIFY(!b);
+ }
+}
+
+void tst_QJniObject::callStaticBooleanMethodClassName()
+{
+ {
+ QJniObject parameter = QJniObject::fromString("true");
+ QVERIFY(parameter.isValid());
+
+ jboolean b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
+ "parseBoolean",
+ "(Ljava/lang/String;)Z",
+ parameter.object<jstring>());
+ QVERIFY(b);
+ b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
+ "parseBoolean",
+ parameter.object<jstring>());
+ QVERIFY(b);
+ }
+
+ {
+ QJniObject parameter = QJniObject::fromString("false");
+ QVERIFY(parameter.isValid());
+
+ jboolean b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
+ "parseBoolean",
+ "(Ljava/lang/String;)Z",
+ parameter.object<jstring>());
+ QVERIFY(!b);
+ b = QJniObject::callStaticMethod<jboolean>("java/lang/Boolean",
+ "parseBoolean",
+ parameter.object<jstring>());
+ QVERIFY(!b);
+ }
+}
+
+void tst_QJniObject::callStaticByteMethodClassName()
+{
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jbyte returnValue = QJniObject::callStaticMethod<jbyte>("java/lang/Byte",
+ "parseByte",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, jbyte(number.toInt()));
+}
+
+void tst_QJniObject::callStaticByteMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Byte");
+ QVERIFY(cls != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jbyte returnValue = QJniObject::callStaticMethod<jbyte>(cls,
+ "parseByte",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, jbyte(number.toInt()));
+}
+
+void tst_QJniObject::callStaticByteMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Byte");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseByte", "(Ljava/lang/String;)B");
+ QVERIFY(id != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jbyte returnValue = QJniObject::callStaticMethod<jbyte>(cls, id, parameter.object<jstring>());
+ QCOMPARE(returnValue, jbyte(number.toInt()));
+}
+
+void tst_QJniObject::callStaticIntMethodClassName()
+{
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jint returnValue = QJniObject::callStaticMethod<jint>("java/lang/Integer",
+ "parseInt",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toInt());
+}
+
+
+void tst_QJniObject::callStaticIntMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Integer");
+ QVERIFY(cls != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jint returnValue = QJniObject::callStaticMethod<jint>(cls,
+ "parseInt",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toInt());
+}
+
+void tst_QJniObject::callStaticIntMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Integer");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseInt", "(Ljava/lang/String;)I");
+ QVERIFY(id != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jint returnValue = QJniObject::callStaticMethod<jint>(cls, id, parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toInt());
+}
+
+void tst_QJniObject::callStaticCharMethodClassName()
+{
+ jchar returnValue = QJniObject::callStaticMethod<jchar>("java/lang/Character",
+ "toUpperCase",
+ jchar('a'));
+ QCOMPARE(returnValue, jchar('A'));
+}
+
+
+void tst_QJniObject::callStaticCharMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Character");
+ QVERIFY(cls != 0);
+
+ jchar returnValue = QJniObject::callStaticMethod<jchar>(cls,
+ "toUpperCase",
+ jchar('a'));
+ QCOMPARE(returnValue, jchar('A'));
+}
+
+void tst_QJniObject::callStaticCharMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Character");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "toUpperCase", "(C)C");
+ QVERIFY(id != 0);
+
+ jchar returnValue = QJniObject::callStaticMethod<jchar>(cls, id, jchar('a'));
+ QCOMPARE(returnValue, jchar('A'));
+}
+
+void tst_QJniObject::callStaticDoubleMethodClassName ()
+{
+ QString number = QString::number(123.45);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jdouble returnValue = QJniObject::callStaticMethod<jdouble>("java/lang/Double",
+ "parseDouble",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toDouble());
+}
+
+
+void tst_QJniObject::callStaticDoubleMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Double");
+ QVERIFY(cls != 0);
+
+ QString number = QString::number(123.45);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jdouble returnValue = QJniObject::callStaticMethod<jdouble>(cls,
+ "parseDouble",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toDouble());
+}
+
+void tst_QJniObject::callStaticDoubleMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Double");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseDouble", "(Ljava/lang/String;)D");
+ QVERIFY(id != 0);
+
+ QString number = QString::number(123.45);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jdouble returnValue =
+ QJniObject::callStaticMethod<jdouble>(cls, id, parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toDouble());
+}
+
+void tst_QJniObject::callStaticFloatMethodClassName()
+{
+ QString number = QString::number(123.45);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jfloat returnValue = QJniObject::callStaticMethod<jfloat>("java/lang/Float",
+ "parseFloat",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toFloat());
+}
+
+
+void tst_QJniObject::callStaticFloatMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Float");
+ QVERIFY(cls != 0);
+
+ QString number = QString::number(123.45);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jfloat returnValue = QJniObject::callStaticMethod<jfloat>(cls,
+ "parseFloat",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toFloat());
+}
+
+void tst_QJniObject::callStaticFloatMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Float");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseFloat", "(Ljava/lang/String;)F");
+ QVERIFY(id != 0);
+
+ QString number = QString::number(123.45);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jfloat returnValue = QJniObject::callStaticMethod<jfloat>(cls, id, parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toFloat());
+}
+
+void tst_QJniObject::callStaticShortMethodClassName()
+{
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jshort returnValue = QJniObject::callStaticMethod<jshort>("java/lang/Short",
+ "parseShort",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toShort());
+}
+
+
+void tst_QJniObject::callStaticShortMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Short");
+ QVERIFY(cls != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jshort returnValue = QJniObject::callStaticMethod<jshort>(cls,
+ "parseShort",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toShort());
+}
+
+void tst_QJniObject::callStaticShortMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Short");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseShort", "(Ljava/lang/String;)S");
+ QVERIFY(id != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jshort returnValue = QJniObject::callStaticMethod<jshort>(cls, id, parameter.object<jstring>());
+ QCOMPARE(returnValue, number.toShort());
+}
+
+void tst_QJniObject::callStaticLongMethodClassName()
+{
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jlong returnValue = QJniObject::callStaticMethod<jlong>("java/lang/Long",
+ "parseLong",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, jlong(number.toLong()));
+}
+
+void tst_QJniObject::callStaticLongMethod()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Long");
+ QVERIFY(cls != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jlong returnValue = QJniObject::callStaticMethod<jlong>(cls,
+ "parseLong",
+ parameter.object<jstring>());
+ QCOMPARE(returnValue, jlong(number.toLong()));
+}
+
+void tst_QJniObject::callStaticLongMethodById()
+{
+ QJniEnvironment env;
+ jclass cls = env.findClass("java/lang/Long");
+ QVERIFY(cls != 0);
+
+ jmethodID id = env.findStaticMethod(cls, "parseLong", "(Ljava/lang/String;)J");
+ QVERIFY(id != 0);
+
+ QString number = QString::number(123);
+ QJniObject parameter = QJniObject::fromString(number);
+
+ jlong returnValue = QJniObject::callStaticMethod<jlong>(cls, id, parameter.object<jstring>());
+ QCOMPARE(returnValue, jlong(number.toLong()));
+}
+
+void tst_QJniObject::getStaticObjectFieldClassName()
+{
+ {
+ QJniObject boolObject = QJniObject::getStaticObjectField("java/lang/Boolean",
+ "FALSE",
+ "Ljava/lang/Boolean;");
+ QVERIFY(boolObject.isValid());
+
+ jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
+ QVERIFY(!booleanValue);
+ }
+
+ {
+ QJniObject boolObject = QJniObject::getStaticObjectField("java/lang/Boolean",
+ "TRUE",
+ "Ljava/lang/Boolean;");
+ QVERIFY(boolObject.isValid());
+
+ jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
+ QVERIFY(booleanValue);
+ }
+
+ {
+ QJniObject boolObject = QJniObject::getStaticObjectField("java/lang/Boolean",
+ "FALSE",
+ "Ljava/lang/Boolean;");
+ QVERIFY(boolObject.isValid());
+ jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
+ QVERIFY(!booleanValue);
+ }
+}
+
+void tst_QJniObject::getStaticObjectField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Boolean");
+ QVERIFY(cls != 0);
+
+ {
+ QJniObject boolObject = QJniObject::getStaticObjectField(cls,
+ "FALSE",
+ "Ljava/lang/Boolean;");
+ QVERIFY(boolObject.isValid());
+
+ jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
+ QVERIFY(!booleanValue);
+ }
+
+ {
+ QJniObject boolObject = QJniObject::getStaticObjectField(cls,
+ "TRUE",
+ "Ljava/lang/Boolean;");
+ QVERIFY(boolObject.isValid());
+
+ jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
+ QVERIFY(booleanValue);
+ }
+
+ {
+ QJniObject boolObject = QJniObject::getStaticObjectField(cls,
+ "FALSE",
+ "Ljava/lang/Boolean;");
+ QVERIFY(boolObject.isValid());
+
+ jboolean booleanValue = boolObject.callMethod<jboolean>("booleanValue");
+ QVERIFY(!booleanValue);
+ }
+}
+
+void tst_QJniObject::getStaticIntFieldClassName()
+{
+ jint i = QJniObject::getStaticField<jint>("java/lang/Double", "SIZE");
+ QCOMPARE(i, 64);
+}
+
+void tst_QJniObject::getStaticIntField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Double");
+ QVERIFY(cls != 0);
+
+ jint i = QJniObject::getStaticField<jint>(cls, "SIZE");
+ QCOMPARE(i, 64);
+
+ enum class Enum { SIZE = 64 };
+ Enum e = QJniObject::getStaticField<Enum>(cls, "SIZE");
+ QCOMPARE(e, Enum::SIZE);
+}
+
+void tst_QJniObject::getStaticByteFieldClassName()
+{
+ jbyte i = QJniObject::getStaticField<jbyte>("java/lang/Byte", "MAX_VALUE");
+ QCOMPARE(i, jbyte(127));
+}
+
+void tst_QJniObject::getStaticByteField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Byte");
+ QVERIFY(cls != 0);
+
+ jbyte i = QJniObject::getStaticField<jbyte>(cls, "MAX_VALUE");
+ QCOMPARE(i, jbyte(127));
+
+ enum class Enum : jbyte { MAX_VALUE = 127 };
+ Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE");
+ QCOMPARE(e, Enum::MAX_VALUE);
+}
+
+void tst_QJniObject::getStaticBooleanField()
+{
+ QCOMPARE(TestClass::getStaticField<jboolean>("S_BOOLEAN_VAR"),
+ TestClass::getStaticField<bool>("S_BOOLEAN_VAR"));
+}
+
+void tst_QJniObject::getStaticLongFieldClassName()
+{
+ jlong i = QJniObject::getStaticField<jlong>("java/lang/Long", "MAX_VALUE");
+ QCOMPARE(i, jlong(9223372036854775807L));
+}
+
+void tst_QJniObject::getStaticLongField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Long");
+ QVERIFY(cls != 0);
+
+ jlong i = QJniObject::getStaticField<jlong>(cls, "MAX_VALUE");
+ QCOMPARE(i, jlong(9223372036854775807L));
+
+ enum class Enum : jlong { MAX_VALUE = 9223372036854775807L };
+ Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE");
+ QCOMPARE(e, Enum::MAX_VALUE);
+}
+
+void tst_QJniObject::getStaticDoubleFieldClassName()
+{
+ jdouble i = QJniObject::getStaticField<jdouble>("java/lang/Double", "NaN");
+ jlong *k = reinterpret_cast<jlong*>(&i);
+ QCOMPARE(*k, jlong(0x7ff8000000000000L));
+}
+
+void tst_QJniObject::getStaticDoubleField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Double");
+ QVERIFY(cls != 0);
+
+ jdouble i = QJniObject::getStaticField<jdouble>(cls, "NaN");
+ jlong *k = reinterpret_cast<jlong*>(&i);
+ QCOMPARE(*k, jlong(0x7ff8000000000000L));
+}
+
+void tst_QJniObject::getStaticFloatFieldClassName()
+{
+ jfloat i = QJniObject::getStaticField<jfloat>("java/lang/Float", "NaN");
+ unsigned *k = reinterpret_cast<unsigned*>(&i);
+ QCOMPARE(*k, unsigned(0x7fc00000));
+}
+
+void tst_QJniObject::getStaticFloatField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Float");
+ QVERIFY(cls != 0);
+
+ jfloat i = QJniObject::getStaticField<jfloat>(cls, "NaN");
+ unsigned *k = reinterpret_cast<unsigned*>(&i);
+ QCOMPARE(*k, unsigned(0x7fc00000));
+}
+
+void tst_QJniObject::getStaticShortFieldClassName()
+{
+ jshort i = QJniObject::getStaticField<jshort>("java/lang/Short", "MAX_VALUE");
+ QCOMPARE(i, jshort(32767));
+}
+
+void tst_QJniObject::getStaticShortField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Short");
+ QVERIFY(cls != 0);
+
+ jshort i = QJniObject::getStaticField<jshort>(cls, "MAX_VALUE");
+ QCOMPARE(i, jshort(32767));
+ enum class Enum : jshort { MAX_VALUE = 32767 };
+ Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE");
+ QCOMPARE(e, Enum::MAX_VALUE);
+}
+
+void tst_QJniObject::getStaticCharFieldClassName()
+{
+ jchar i = QJniObject::getStaticField<jchar>("java/lang/Character", "MAX_VALUE");
+ QCOMPARE(i, jchar(0xffff));
+}
+
+void tst_QJniObject::getStaticCharField()
+{
+ QJniEnvironment env;
+ jclass cls = env->FindClass("java/lang/Character");
+ QVERIFY(cls != 0);
+
+ jchar i = QJniObject::getStaticField<jchar>(cls, "MAX_VALUE");
+ QCOMPARE(i, jchar(0xffff));
+
+ enum class Enum : jchar { MAX_VALUE = 0xffff };
+ Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE");
+ QCOMPARE(e, Enum::MAX_VALUE);
+}
+
+
+void tst_QJniObject::getBooleanField()
+{
+ QJniObject obj(testClassName);
+
+ QVERIFY(obj.isValid());
+ QVERIFY(obj.getField<jboolean>("BOOL_FIELD"));
+ QVERIFY(obj.getField<bool>("BOOL_FIELD"));
+}
+
+void tst_QJniObject::getIntField()
+{
+ QJniObject obj(testClassName);
+
+ QVERIFY(obj.isValid());
+ jint res = obj.getField<jint>("INT_FIELD");
+ QCOMPARE(res, 123);
+}
+
+template <typename T>
+void setField(const char *fieldName, T testValue)
+{
+ QJniObject obj(testClassName);
+ QVERIFY(obj.isValid());
+
+ obj.setField(fieldName, testValue);
+
+ T res = obj.getField<T>(fieldName);
+ QCOMPARE(res, testValue);
+}
+
+void tst_QJniObject::setIntField()
+{
+ setField("INT_VAR", 555);
+ enum class Enum : jint { VALUE = 555 };
+ setField("INT_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setByteField()
+{
+ setField("BYTE_VAR", jbyte(123));
+ enum class Enum : jbyte { VALUE = 123 };
+ setField("BYTE_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setLongField()
+{
+ setField("LONG_VAR", jlong(9223372036847758232L));
+ enum class Enum : jlong { VALUE = 9223372036847758232L };
+ setField("LONG_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setDoubleField()
+{
+ setField("DOUBLE_VAR", jdouble(1.2));
+}
+
+void tst_QJniObject::setFloatField()
+{
+ setField("FLOAT_VAR", jfloat(1.2));
+}
+
+void tst_QJniObject::setShortField()
+{
+ setField("SHORT_VAR", jshort(555));
+ enum class Enum : jshort { VALUE = 555 };
+ setField("SHORT_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setCharField()
+{
+ setField("CHAR_VAR", jchar('A'));
+ enum class Enum : jchar { VALUE = 'A' };
+ setField("CHAR_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setBooleanField()
+{
+ setField("BOOLEAN_VAR", jboolean(true));
+ setField("BOOLEAN_VAR", true);
+}
+
+void tst_QJniObject::setObjectField()
+{
+ QJniObject obj(testClassName);
+ QVERIFY(obj.isValid());
+
+ const QString qString = u"Hello"_s;
+ QJniObject testValue = QJniObject::fromString(qString);
+ obj.setField("STRING_OBJECT_VAR", testValue.object<jstring>());
+
+ QJniObject res = obj.getObjectField<jstring>("STRING_OBJECT_VAR");
+ QCOMPARE(res.toString(), testValue.toString());
+
+ // as of Qt 6.7, we can set and get strings directly
+ obj.setField("STRING_OBJECT_VAR", qString);
+ QCOMPARE(obj.getField<QString>("STRING_OBJECT_VAR"), qString);
+}
+
+template <typename T>
+void setStaticField(const char *fieldName, T testValue)
+{
+ QJniObject::setStaticField(testClassName, fieldName, testValue);
+
+ T res = QJniObject::getStaticField<T>(testClassName, fieldName);
+ QCOMPARE(res, testValue);
+
+ // use template overload to reset to default
+ T defaultValue = {};
+ TestClass::setStaticField(fieldName, defaultValue);
+ res = TestClass::getStaticField<T>(fieldName);
+ QCOMPARE(res, defaultValue);
+}
+
+void tst_QJniObject::setStaticIntField()
+{
+ setStaticField("S_INT_VAR", 555);
+ enum class Enum : jint { VALUE = 555 };
+ setStaticField("S_INT_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setStaticByteField()
+{
+ setStaticField("S_BYTE_VAR", jbyte(123));
+ enum class Enum : jbyte { VALUE = 123 };
+ setStaticField("S_BYTE_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setStaticLongField()
+{
+ setStaticField("S_LONG_VAR", jlong(9223372036847758232L));
+ enum class Enum : jlong { VALUE = 9223372036847758232L };
+ setStaticField("S_LONG_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setStaticDoubleField()
+{
+ setStaticField("S_DOUBLE_VAR", jdouble(1.2));
+}
+
+void tst_QJniObject::setStaticFloatField()
+{
+ setStaticField("S_FLOAT_VAR", jfloat(1.2));
+}
+
+void tst_QJniObject::setStaticShortField()
+{
+ setStaticField("S_SHORT_VAR", jshort(555));
+ enum class Enum : jshort { VALUE = 555 };
+ setStaticField("S_SHORT_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setStaticCharField()
+{
+ setStaticField("S_CHAR_VAR", jchar('A'));
+ enum class Enum : jchar { VALUE = 'A' };
+ setStaticField("S_CHAR_VAR", Enum::VALUE);
+}
+
+void tst_QJniObject::setStaticBooleanField()
+{
+ setStaticField("S_BOOLEAN_VAR", jboolean(true));
+ setStaticField("S_BOOLEAN_VAR", true);
+}
+
+void tst_QJniObject::setStaticObjectField()
+{
+ const QString qString = u"Hello"_s;
+ QJniObject testValue = QJniObject::fromString(qString);
+ QJniObject::setStaticField(testClassName, "S_STRING_OBJECT_VAR", testValue.object<jstring>());
+
+ QJniObject res = QJniObject::getStaticObjectField<jstring>(testClassName, "S_STRING_OBJECT_VAR");
+ QCOMPARE(res.toString(), testValue.toString());
+
+ // as of Qt 6.7, we can set and get strings directly
+ using namespace QtJniTypes;
+ QtJniObjectTestClass::setStaticField("S_STRING_OBJECT_VAR", qString);
+ QCOMPARE(QtJniObjectTestClass::getStaticField<QString>("S_STRING_OBJECT_VAR"), qString);
+}
+
+void tst_QJniObject::templateApiCheck()
+{
+ QJniObject testClass(testClassName);
+ QVERIFY(testClass.isValid());
+
+ // void ---------------------------------------------------------------------------------------
+ QJniObject::callStaticMethod<void>(testClassName, "staticVoidMethod");
+ QJniObject::callStaticMethod<void>(testClassName,
+ "staticVoidMethodWithArgs",
+ "(IZC)V",
+ 1,
+ true,
+ 'c');
+ QJniObject::callStaticMethod<void>(testClassName,
+ "staticVoidMethodWithArgs",
+ 1,
+ true,
+ 'c');
+
+ testClass.callMethod<void>("voidMethod");
+ testClass.callMethod<void>("voidMethodWithArgs", "(IZC)V", 1, true, 'c');
+ testClass.callMethod<void>("voidMethodWithArgs", 1, true, 'c');
+
+ // jboolean -----------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName, "staticBooleanMethod"));
+ QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName,
+ "staticBooleanMethodWithArgs",
+ "(ZZZ)Z",
+ true,
+ true,
+ true));
+ QVERIFY(QJniObject::callStaticMethod<jboolean>(testClassName,
+ "staticBooleanMethodWithArgs",
+ true,
+ true,
+ true));
+
+ QVERIFY(testClass.callMethod<jboolean>("booleanMethod"));
+ QVERIFY(testClass.callMethod<jboolean>("booleanMethodWithArgs",
+ "(ZZZ)Z",
+ true,
+ true,
+ true));
+ QVERIFY(testClass.callMethod<jboolean>("booleanMethodWithArgs",
+ true,
+ true,
+ true));
+
+ // jbyte --------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
+ "staticByteMethod") == A_BYTE_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
+ "staticByteMethodWithArgs",
+ "(BBB)B",
+ 1,
+ 1,
+ 1) == A_BYTE_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jbyte>(testClassName,
+ "staticByteMethodWithArgs",
+ jbyte(1),
+ jbyte(1),
+ jbyte(1)) == A_BYTE_VALUE);
+
+ QVERIFY(testClass.callMethod<jbyte>("byteMethod") == A_BYTE_VALUE);
+ QVERIFY(testClass.callMethod<jbyte>("byteMethodWithArgs", "(BBB)B", 1, 1, 1) == A_BYTE_VALUE);
+ QVERIFY(testClass.callMethod<jbyte>("byteMethodWithArgs", jbyte(1), jbyte(1), jbyte(1)) == A_BYTE_VALUE);
+
+ // jchar --------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
+ "staticCharMethod") == A_CHAR_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
+ "staticCharMethodWithArgs",
+ "(CCC)C",
+ jchar(1),
+ jchar(1),
+ jchar(1)) == A_CHAR_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jchar>(testClassName,
+ "staticCharMethodWithArgs",
+ jchar(1),
+ jchar(1),
+ jchar(1)) == A_CHAR_VALUE);
+
+ QVERIFY(testClass.callMethod<jchar>("charMethod") == A_CHAR_VALUE);
+ QVERIFY(testClass.callMethod<jchar>("charMethodWithArgs",
+ "(CCC)C",
+ jchar(1),
+ jchar(1),
+ jchar(1)) == A_CHAR_VALUE);
+ QVERIFY(testClass.callMethod<jchar>("charMethodWithArgs",
+ jchar(1),
+ jchar(1),
+ jchar(1)) == A_CHAR_VALUE);
+
+ // jshort -------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
+ "staticShortMethod") == A_SHORT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
+ "staticShortMethodWithArgs",
+ "(SSS)S",
+ jshort(1),
+ jshort(1),
+ jshort(1)) == A_SHORT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jshort>(testClassName,
+ "staticShortMethodWithArgs",
+ jshort(1),
+ jshort(1),
+ jshort(1)) == A_SHORT_VALUE);
+
+ QVERIFY(testClass.callMethod<jshort>("shortMethod") == A_SHORT_VALUE);
+ QVERIFY(testClass.callMethod<jshort>("shortMethodWithArgs",
+ "(SSS)S",
+ jshort(1),
+ jshort(1),
+ jshort(1)) == A_SHORT_VALUE);
+ QVERIFY(testClass.callMethod<jshort>("shortMethodWithArgs",
+ jshort(1),
+ jshort(1),
+ jshort(1)) == A_SHORT_VALUE);
+
+ // jint ---------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
+ "staticIntMethod") == A_INT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
+ "staticIntMethodWithArgs",
+ "(III)I",
+ jint(1),
+ jint(1),
+ jint(1)) == A_INT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jint>(testClassName,
+ "staticIntMethodWithArgs",
+ jint(1),
+ jint(1),
+ jint(1)) == A_INT_VALUE);
+
+ QVERIFY(testClass.callMethod<jint>("intMethod") == A_INT_VALUE);
+ QVERIFY(testClass.callMethod<jint>("intMethodWithArgs",
+ "(III)I",
+ jint(1),
+ jint(1),
+ jint(1)) == A_INT_VALUE);
+ QVERIFY(testClass.callMethod<jint>("intMethodWithArgs",
+ jint(1),
+ jint(1),
+ jint(1)) == A_INT_VALUE);
+
+ // jlong --------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
+ "staticLongMethod") == A_LONG_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
+ "staticLongMethodWithArgs",
+ "(JJJ)J",
+ jlong(1),
+ jlong(1),
+ jlong(1)) == A_LONG_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jlong>(testClassName,
+ "staticLongMethodWithArgs",
+ jlong(1),
+ jlong(1),
+ jlong(1)) == A_LONG_VALUE);
+
+ QVERIFY(testClass.callMethod<jlong>("longMethod") == A_LONG_VALUE);
+ QVERIFY(testClass.callMethod<jlong>("longMethodWithArgs",
+ "(JJJ)J",
+ jlong(1),
+ jlong(1),
+ jlong(1)) == A_LONG_VALUE);
+ QVERIFY(testClass.callMethod<jlong>("longMethodWithArgs",
+ jlong(1),
+ jlong(1),
+ jlong(1)) == A_LONG_VALUE);
+
+ // jfloat -------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
+ "staticFloatMethod") == A_FLOAT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
+ "staticFloatMethodWithArgs",
+ "(FFF)F",
+ jfloat(1.1),
+ jfloat(1.1),
+ jfloat(1.1)) == A_FLOAT_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jfloat>(testClassName,
+ "staticFloatMethodWithArgs",
+ jfloat(1.1),
+ jfloat(1.1),
+ jfloat(1.1)) == A_FLOAT_VALUE);
+
+ QVERIFY(testClass.callMethod<jfloat>("floatMethod") == A_FLOAT_VALUE);
+ QVERIFY(testClass.callMethod<jfloat>("floatMethodWithArgs",
+ "(FFF)F",
+ jfloat(1.1),
+ jfloat(1.1),
+ jfloat(1.1)) == A_FLOAT_VALUE);
+ QVERIFY(testClass.callMethod<jfloat>("floatMethodWithArgs",
+ jfloat(1.1),
+ jfloat(1.1),
+ jfloat(1.1)) == A_FLOAT_VALUE);
+
+ // jdouble ------------------------------------------------------------------------------------
+ QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
+ "staticDoubleMethod") == A_DOUBLE_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
+ "staticDoubleMethodWithArgs",
+ "(DDD)D",
+ jdouble(1.1),
+ jdouble(1.1),
+ jdouble(1.1)) == A_DOUBLE_VALUE);
+ QVERIFY(QJniObject::callStaticMethod<jdouble>(testClassName,
+ "staticDoubleMethodWithArgs",
+ jdouble(1.1),
+ jdouble(1.1),
+ jdouble(1.1)) == A_DOUBLE_VALUE);
+
+ QVERIFY(testClass.callMethod<jdouble>("doubleMethod") == A_DOUBLE_VALUE);
+ QVERIFY(testClass.callMethod<jdouble>("doubleMethodWithArgs",
+ "(DDD)D",
+ jdouble(1.1),
+ jdouble(1.1),
+ jdouble(1.1)) == A_DOUBLE_VALUE);
+ QVERIFY(testClass.callMethod<jdouble>("doubleMethodWithArgs",
+ jdouble(1.1),
+ jdouble(1.1),
+ jdouble(1.1)) == A_DOUBLE_VALUE);
+
+ // jobject ------------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jobject>(testClassName,
+ "staticObjectMethod");
+ QVERIFY(res.isValid());
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jobject>("objectMethod");
+ QVERIFY(res.isValid());
+ }
+
+ // jclass -------------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jclass>(testClassName,
+ "staticClassMethod");
+ QVERIFY(res.isValid());
+ QJniEnvironment env;
+ QVERIFY(env->IsInstanceOf(testClass.object(), res.object<jclass>()));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jclass>("classMethod");
+ QVERIFY(res.isValid());
+ QJniEnvironment env;
+ QVERIFY(env->IsInstanceOf(testClass.object(), res.object<jclass>()));
+ }
+ // jstring ------------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jstring>(testClassName,
+ "staticStringMethod");
+ QVERIFY(res.isValid());
+ QVERIFY(res.toString() == A_STRING_OBJECT());
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jstring>("stringMethod");
+ QVERIFY(res.isValid());
+ QVERIFY(res.toString() == A_STRING_OBJECT());
+
+ }
+ // jthrowable ---------------------------------------------------------------------------------
+ {
+ // The Throwable object the same message (see: "getMessage()") as A_STRING_OBJECT
+ QJniObject res = QJniObject::callStaticObjectMethod<jthrowable>(testClassName,
+ "staticThrowableMethod");
+ QVERIFY(res.isValid());
+ QVERIFY(res.callObjectMethod<jstring>("getMessage").toString() == A_STRING_OBJECT());
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jthrowable>("throwableMethod");
+ QVERIFY(res.isValid());
+ QVERIFY(res.callObjectMethod<jstring>("getMessage").toString() == A_STRING_OBJECT());
+ }
+
+ // jobjectArray -------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jobjectArray>(testClassName,
+ "staticObjectArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jobject[]>("staticObjectArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+
+ QJniArray<jobject> newArray(QList<QJniObject>{QJniObject::fromString(u"one"_s),
+ QJniObject::fromString(u"two"_s),
+ QJniObject::fromString(u"three"_s)});
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jobject[]>("staticReverseObjectArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.size(), 3);
+ QCOMPARE(QJniObject(reverse.at(0)).toString(), u"three"_s);
+ QCOMPARE(QJniObject(reverse.at(1)).toString(), u"two"_s);
+ QCOMPARE(QJniObject(reverse.at(2)).toString(), u"one"_s);
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jobjectArray>("objectArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jobject[]>("objectArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+
+ QJniArray<jobject> newArray(QList<QJniObject>{QJniObject::fromString(u"one"_s),
+ QJniObject::fromString(u"two"_s),
+ QJniObject::fromString(u"three"_s)});
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jobject[]>("reverseObjectArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.size(), 3);
+ // QJniArray::at returns a jobject that's a local reference; make sure we don't free it twice
+ QCOMPARE(QJniObject::fromLocalRef(reverse.at(0)).toString(), u"three"_s);
+ QCOMPARE(QJniObject::fromLocalRef(reverse.at(1)).toString(), u"two"_s);
+ QCOMPARE(QJniObject::fromLocalRef(reverse.at(2)).toString(), u"one"_s);
+ }
+
+ // jbooleanArray ------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jbooleanArray>(testClassName,
+ "staticBooleanArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jboolean[]>("staticBooleanArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jboolean>{true, true, true}));
+
+ QJniArray<jboolean> newArray(QList<jboolean>{true, false, false});
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jboolean[]>("staticReverseBooleanArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jboolean>{false, false, true}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jbooleanArray>("booleanArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jboolean[]>("booleanArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jboolean>{true, true, true}));
+
+ QJniArray<jboolean> newArray(QList<jboolean>{true, false, false});
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jboolean[]>("reverseBooleanArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jboolean>{false, false, true}));
+ }
+
+ // jbyteArray ---------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jbyteArray>(testClassName,
+ "staticByteArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jbyte[]>("staticByteArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), "abc");
+
+ QJniArray<jbyte> newArray(QByteArray{"cba"});
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jbyte[]>("staticReverseByteArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), "abc");
+
+ const QByteArray reverse2 = TestClass::callStaticMethod<QByteArray>("staticReverseByteArray",
+ QByteArray("abc"));
+ QCOMPARE(reverse2, "cba");
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jbyteArray>("byteArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jbyte[]>("byteArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), "abc");
+
+ QJniArray<jbyte> newArray = QJniArrayBase::fromContainer(QByteArray{"cba"});
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jbyte[]>("reverseByteArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), "abc");
+ }
+
+ // jcharArray ---------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jcharArray>(testClassName,
+ "staticCharArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jchar[]>("staticCharArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jchar>{u'a', u'b', u'c'}));
+
+ QJniArray<jchar> newArray = {u'c', u'b', u'a'};
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jchar[]>("staticReverseCharArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jchar>{u'a', u'b', u'c'}));
+
+ const QList<jchar> reverse2 = TestClass::callStaticMethod<QList<jchar>>("staticReverseCharArray",
+ (QList<jchar>{u'c', u'b', u'a'}));
+ QCOMPARE(reverse2, (QList<jchar>{u'a', u'b', u'c'}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jcharArray>("charArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jchar[]>("charArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jchar>{u'a', u'b', u'c'}));
+
+ QJniArray<jchar> newArray = {u'c', u'b', u'a'};
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jchar[]>("reverseCharArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jchar>{u'a', u'b', u'c'}));
+ }
+
+ // jshortArray --------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jshortArray>(testClassName,
+ "staticShortArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jshort[]>("staticShortArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jshort>{3, 2, 1}));
+
+ QJniArray<jshort> newArray = {3, 2, 1};
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jshort[]>("staticReverseShortArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jshort>{1, 2, 3}));
+
+ const QList<jshort> reverse2 = TestClass::callStaticMethod<QList<jshort>>("staticReverseShortArray",
+ (QList<jshort>{1, 2, 3}));
+ QCOMPARE(reverse2, (QList<jshort>{3, 2, 1}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jshortArray>("shortArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jshort[]>("shortArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jshort>{3, 2, 1}));
+
+ QJniArray<jshort> newArray = {3, 2, 1};
+ static_assert(std::is_same_v<decltype(newArray)::Type, jshort>);
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jshort[]>("reverseShortArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jshort>{1, 2, 3}));
+ }
+
+ // jintArray ----------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jintArray>(testClassName,
+ "staticIntArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jint[]>("staticIntArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jint>{3, 2, 1}));
+
+ QJniArray<jint> newArray = {3, 2, 1};
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jint[]>("staticReverseIntArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jint>{1, 2, 3}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jintArray>("intArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jint[]>("intArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jint>{3, 2, 1}));
+
+ QJniArray<jint> newArray = {3, 2, 1};
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jint[]>("reverseIntArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jint>{1, 2, 3}));
+ }
+
+ // jlongArray ---------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jlongArray>(testClassName,
+ "staticLongArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jlong[]>("staticLongArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jlong>{3, 2, 1}));
+
+ QJniArray<jlong> newArray = {3, 2, 1};
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jlong[]>("staticReverseLongArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jlong>{1, 2, 3}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jlongArray>("longArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jlong[]>("longArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jlong>{3, 2, 1}));
+
+ QJniArray<jlong> newArray = {3, 2, 1};
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jlong[]>("reverseLongArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jlong>{1, 2, 3}));
+ }
+
+ // jfloatArray --------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jfloatArray>(testClassName,
+ "staticFloatArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jfloat[]>("staticFloatArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jfloat>{1.0f, 2.0f, 3.0f}));
+
+ QJniArray<jfloat> newArray = {3.0f, 2.0f, 1.0f};
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jfloat[]>("staticReverseFloatArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jfloat>{1.0f, 2.0f, 3.0f}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jfloatArray>("floatArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jfloat[]>("floatArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jfloat>{1.0f, 2.0f, 3.0f}));
+
+ QJniArray<jfloat> newArray = {3.0f, 2.0f, 1.0f};
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jfloat[]>("reverseFloatArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jfloat>{1.0f, 2.0f, 3.0f}));
+ }
+
+ // jdoubleArray -------------------------------------------------------------------------------
+ {
+ QJniObject res = QJniObject::callStaticObjectMethod<jdoubleArray>(testClassName,
+ "staticDoubleArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = TestClass::callStaticMethod<jdouble[]>("staticDoubleArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jdouble>{3.0, 2.0, 1.0}));
+
+ QJniArray<jdouble> newArray = {3.0, 2.0, 1.0};
+ QVERIFY(newArray.isValid());
+ const auto reverse = TestClass::callStaticMethod<jdouble[]>("staticReverseDoubleArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jdouble>{1.0, 2.0, 3.0}));
+ }
+
+ {
+ QJniObject res = testClass.callObjectMethod<jdoubleArray>("doubleArrayMethod");
+ QVERIFY(res.isValid());
+
+ const auto array = testClass.callMethod<jdouble[]>("doubleArrayMethod");
+ QVERIFY(array.isValid());
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.toContainer(), (QList<jdouble>{3.0, 2.0, 1.0}));
+
+ QJniArray<jdouble> newArray = {3.0, 2.0, 1.0};
+ QVERIFY(newArray.isValid());
+ const auto reverse = testClass.callMethod<jdouble[]>("reverseDoubleArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.toContainer(), (QList<jdouble>{1.0, 2.0, 3.0}));
+ }
+
+}
+
+void tst_QJniObject::isClassAvailable()
+{
+ QVERIFY(QJniObject::isClassAvailable("java/lang/String"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.ClassNotFoundException"));
+ QVERIFY(!QJniObject::isClassAvailable("class/not/Available"));
+ QVERIFY(QJniObject::isClassAvailable("org/qtproject/qt/android/QtActivityDelegate"));
+}
+
+void tst_QJniObject::fromLocalRef()
+{
+ const int limit = 512 + 1;
+ QJniEnvironment env;
+ for (int i = 0; i != limit; ++i)
+ QJniObject o = QJniObject::fromLocalRef(env->FindClass("java/lang/String"));
+}
+
+void tst_QJniObject::largeObjectArray()
+{
+ QJniArray<jobject> newArray(QList<QJniObject>{QJniObject::fromString(u"one"_s),
+ QJniObject::fromString(u"two"_s),
+ QJniObject::fromString(u"three"_s)});
+ QVERIFY(newArray.isValid());
+ const QJniArray<QJniObject> reverse = TestClass::callStaticMethod<jobject[]>(
+ "staticReverseObjectArray", newArray);
+ QVERIFY(reverse.isValid());
+ QCOMPARE(reverse.size(), 3);
+
+ // make sure we don't leak local references
+ for (int i = 0; i < 10000; ++i) {
+ QVERIFY(reverse.at(0).isValid());
+ QVERIFY(reverse.at(1).isValid());
+ QVERIFY(reverse.at(2).isValid());
+ }
+}
+
+enum class CallbackParameterType
+{
+ Object,
+ ObjectRef,
+ String,
+ Byte,
+ Boolean,
+ Int,
+ Double,
+ JniArray,
+ QList,
+ QStringList,
+};
+
+static std::optional<TestClass> calledWithObject;
+static int callbackWithObject(JNIEnv *, jobject, TestClass that)
+{
+ calledWithObject.emplace(that);
+ return int(CallbackParameterType::Object);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithObject)
+static int callbackWithObjectRef(JNIEnv *, jobject, const TestClass &that)
+{
+ calledWithObject.emplace(that);
+ return int(CallbackParameterType::ObjectRef);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithObjectRef)
+
+static std::optional<QString> calledWithString;
+static int callbackWithString(JNIEnv *, jobject, const QString &string)
+{
+ calledWithString.emplace(string);
+ return int(CallbackParameterType::String);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithString)
+
+static std::optional<jbyte> calledWithByte;
+static int callbackWithByte(JNIEnv *, jobject, jbyte value)
+{
+ calledWithByte.emplace(value);
+ return int(CallbackParameterType::Byte);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithByte)
+
+static std::optional<jbyte> calledWithBoolean;
+static int callbackWithBoolean(JNIEnv *, jobject, bool value)
+{
+ calledWithBoolean.emplace(value);
+ return int(CallbackParameterType::Boolean);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithBoolean)
+
+static std::optional<int> calledWithInt;
+static int callbackWithInt(JNIEnv *, jobject, int value)
+{
+ calledWithInt.emplace(value);
+ return int(CallbackParameterType::Int);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithInt)
+
+static std::optional<double> calledWithDouble;
+static int callbackWithDouble(JNIEnv *, jobject, double value)
+{
+ calledWithDouble.emplace(value);
+ return int(CallbackParameterType::Double);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithDouble)
+
+static std::optional<QJniArray<jdouble>> calledWithJniArray;
+static int callbackWithJniArray(JNIEnv *, jobject, const QJniArray<jdouble> &value)
+{
+ calledWithJniArray.emplace(value);
+ return int(CallbackParameterType::JniArray);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithJniArray)
+
+static std::optional<QList<double>> calledWithQList;
+static int callbackWithQList(JNIEnv *, jobject, const QList<double> &value)
+{
+ calledWithQList.emplace(value);
+ return int(CallbackParameterType::QList);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithQList)
+
+static std::optional<QStringList> calledWithStringList;
+static int callbackWithStringList(JNIEnv *, jobject, const QStringList &value)
+{
+ calledWithStringList.emplace(value);
+ return int(CallbackParameterType::QStringList);
+}
+Q_DECLARE_JNI_NATIVE_METHOD(callbackWithStringList)
+
+void tst_QJniObject::callback_data()
+{
+ QTest::addColumn<CallbackParameterType>("parameterType");
+
+ QTest::addRow("Object") << CallbackParameterType::Object;
+ QTest::addRow("ObjectRef") << CallbackParameterType::ObjectRef;
+ QTest::addRow("String") << CallbackParameterType::String;
+ QTest::addRow("Byte") << CallbackParameterType::Byte;
+ QTest::addRow("Boolean") << CallbackParameterType::Boolean;
+ QTest::addRow("Int") << CallbackParameterType::Int;
+ QTest::addRow("Double") << CallbackParameterType::Double;
+ QTest::addRow("JniArray") << CallbackParameterType::JniArray;
+ QTest::addRow("QList") << CallbackParameterType::QList;
+ QTest::addRow("QStringList") << CallbackParameterType::QStringList;
+}
+
+void tst_QJniObject::callback()
+{
+ QFETCH(const CallbackParameterType, parameterType);
+
+ TestClass testObject;
+ int result = -1;
+
+ switch (parameterType) {
+ case CallbackParameterType::Object:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithObject)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithObject", testObject);
+ QVERIFY(calledWithObject);
+ QCOMPARE(calledWithObject.value(), testObject);
+ break;
+ case CallbackParameterType::ObjectRef:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithObjectRef)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithObjectRef", testObject);
+ QVERIFY(calledWithObject);
+ QCOMPARE(calledWithObject.value(), testObject);
+ break;
+ case CallbackParameterType::String:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithString)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithString", QString::number(123));
+ QVERIFY(calledWithString);
+ QCOMPARE(calledWithString.value(), "123");
+ break;
+ case CallbackParameterType::Byte:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithByte)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithByte", jbyte(123));
+ QVERIFY(calledWithByte);
+ QCOMPARE(calledWithByte.value(), 123);
+ break;
+ case CallbackParameterType::Boolean:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithBoolean)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithBoolean", true);
+ QVERIFY(calledWithBoolean);
+ QCOMPARE(calledWithBoolean.value(), true);
+ break;
+ case CallbackParameterType::Int:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithInt)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithInt", 12345);
+ QVERIFY(calledWithInt);
+ QCOMPARE(calledWithInt.value(), 12345);
+ break;
+ case CallbackParameterType::Double:
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithDouble)
+ }));
+ result = testObject.callMethod<int>("callMeBackWithDouble", 1.2345);
+ QVERIFY(calledWithDouble);
+ QCOMPARE(calledWithDouble.value(), 1.2345);
+ break;
+ case CallbackParameterType::JniArray: {
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithJniArray)
+ }));
+ const QJniArray<double> doubles = { 1.2, 3.4, 5.6 };
+ result = testObject.callMethod<int>("callMeBackWithJniArray", doubles);
+ QVERIFY(calledWithJniArray);
+ QCOMPARE(calledWithJniArray, doubles);
+ break;
+ }
+ case CallbackParameterType::QList: {
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithQList)
+ }));
+ const QList<double> doubles = { 1.2, 3.4, 5.6 };
+ result = testObject.callMethod<int>("callMeBackWithQList", doubles);
+ QVERIFY(calledWithQList);
+ QCOMPARE(calledWithQList.value(), doubles);
+ break;
+ }
+ case CallbackParameterType::QStringList: {
+ QVERIFY(TestClass::registerNativeMethods({
+ Q_JNI_NATIVE_METHOD(callbackWithStringList)
+ }));
+ const QStringList strings = { "one", "two" };
+ result = testObject.callMethod<int>("callMeBackWithStringList", strings);
+ QVERIFY(calledWithStringList);
+ QCOMPARE(calledWithStringList.value(), strings);
+ break;
+ }
+ }
+ QCOMPARE(result, int(parameterType));
+}
+
+// Make sure the new callStaticMethod overload taking a class, return type,
+// and argument as template parameters, doesn't break overload resolution
+// and that the class name doesn't get interpreted as the function name.
+void tst_QJniObject::callStaticOverloadResolution()
+{
+ const QString value = u"Hello World"_s;
+ QJniObject str = QJniObject::fromString(value);
+ const auto result = QJniObject::callStaticMethod<jstring, jstring>(
+ QtJniTypes::Traits<TestClass>::className(),
+ "staticEchoMethod", str.object<jstring>()).toString();
+ QCOMPARE(result, value);
+}
+
+QTEST_MAIN(tst_QJniObject)
+
+#include "tst_qjniobject.moc"
diff --git a/tests/auto/corelib/kernel/qjnitypes/CMakeLists.txt b/tests/auto/corelib/kernel/qjnitypes/CMakeLists.txt
new file mode 100644
index 0000000000..104b039d4d
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjnitypes/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qjnitypes LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qjnitypes
+ SOURCES
+ tst_qjnitypes.cpp
+)
diff --git a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp
new file mode 100644
index 0000000000..bf582041f3
--- /dev/null
+++ b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp
@@ -0,0 +1,284 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest>
+
+#include <QtCore/qjnitypes.h>
+#include <QtCore/qjniarray.h>
+
+using namespace Qt::StringLiterals;
+
+class tst_QJniTypes : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QJniTypes() = default;
+
+ static void nativeClassMethod(JNIEnv *, jclass, int);
+ Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(nativeClassMethod);
+
+private slots:
+ void initTestCase();
+ void nativeMethod();
+ void construct();
+ void stringTypeCantBeArgument();
+};
+
+struct QtJavaWrapper {};
+template<>
+struct QtJniTypes::Traits<QtJavaWrapper>
+{
+ static constexpr auto signature()
+ {
+ return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtJavaWrapper;");
+ }
+};
+
+template<>
+struct QtJniTypes::Traits<QJniObject>
+{
+ static constexpr auto signature()
+ {
+ return QtJniTypes::CTString("Ljava/lang/Object;");
+ }
+};
+
+struct QtCustomJniObject : QJniObject {};
+
+template<>
+struct QtJniTypes::Traits<QtCustomJniObject>
+{
+ static constexpr auto signature()
+ {
+ return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtCustomJniObject;");
+ }
+};
+
+static_assert(QtJniTypes::Traits<QtJavaWrapper>::signature() == "Lorg/qtproject/qt/android/QtJavaWrapper;");
+static_assert(QtJniTypes::Traits<QtJavaWrapper>::signature() != "Ljava/lang/Object;");
+static_assert(!(QtJniTypes::Traits<QtJavaWrapper>::signature() == "X"));
+
+Q_DECLARE_JNI_CLASS(JavaType, "org/qtproject/qt/JavaType");
+static_assert(QtJniTypes::Traits<QtJniTypes::JavaType>::signature() == "Lorg/qtproject/qt/JavaType;");
+static_assert(QtJniTypes::Traits<QtJniTypes::JavaType[]>::signature() == "[Lorg/qtproject/qt/JavaType;");
+
+Q_DECLARE_JNI_CLASS(String, "java/lang/String");
+static_assert(QtJniTypes::Traits<jstring>::className() == "java/lang/String");
+static_assert(QtJniTypes::Traits<QtJniTypes::String>::className() == "java/lang/String");
+static_assert(QtJniTypes::Traits<QtJniTypes::String>::signature() == "Ljava/lang/String;");
+static_assert(QtJniTypes::Traits<QtJniTypes::String[]>::signature() == "[Ljava/lang/String;");
+
+Q_DECLARE_JNI_CLASS(QtTextToSpeech, "org/qtproject/qt/android/speech/QtTextToSpeech")
+static_assert(QtJniTypes::Traits<QtJniTypes::QtTextToSpeech>::className() == "org/qtproject/qt/android/speech/QtTextToSpeech");
+
+static_assert(QtJniTypes::fieldSignature<jint>() == "I");
+static_assert(QtJniTypes::fieldSignature<jint[]>() == "[I");
+static_assert(QtJniTypes::fieldSignature<jint>() != "X");
+static_assert(QtJniTypes::fieldSignature<jint>() != "Ljava/lang/Object;");
+static_assert(QtJniTypes::fieldSignature<jlong>() == "J");
+static_assert(QtJniTypes::fieldSignature<jstring>() == "Ljava/lang/String;");
+static_assert(QtJniTypes::fieldSignature<jobject>() == "Ljava/lang/Object;");
+static_assert(QtJniTypes::fieldSignature<jobject[]>() == "[Ljava/lang/Object;");
+static_assert(QtJniTypes::fieldSignature<jobjectArray>() == "[Ljava/lang/Object;");
+static_assert(QtJniTypes::fieldSignature<QJniObject>() == "Ljava/lang/Object;");
+static_assert(QtJniTypes::fieldSignature<QtJavaWrapper>() == "Lorg/qtproject/qt/android/QtJavaWrapper;");
+static_assert(QtJniTypes::fieldSignature<QtJavaWrapper[]>() == "[Lorg/qtproject/qt/android/QtJavaWrapper;");
+static_assert(QtJniTypes::fieldSignature<QtCustomJniObject>() == "Lorg/qtproject/qt/android/QtCustomJniObject;");
+
+static_assert(QtJniTypes::methodSignature<void>() == "()V");
+static_assert(QtJniTypes::methodSignature<void>() != "()X");
+static_assert(QtJniTypes::methodSignature<void, jint>() == "(I)V");
+static_assert(QtJniTypes::methodSignature<void, jint, jstring>() == "(ILjava/lang/String;)V");
+static_assert(QtJniTypes::methodSignature<jlong, jint, jclass>() == "(ILjava/lang/Class;)J");
+static_assert(QtJniTypes::methodSignature<jobject, jint, jstring>() == "(ILjava/lang/String;)Ljava/lang/Object;");
+static_assert(QtJniTypes::methodSignature<QtJniTypes::JavaType, jint, jstring>()
+ == "(ILjava/lang/String;)Lorg/qtproject/qt/JavaType;");
+
+static_assert(QtJniTypes::isPrimitiveType<jint>());
+static_assert(QtJniTypes::isPrimitiveType<void>());
+static_assert(!QtJniTypes::isPrimitiveType<jobject>());
+static_assert(!QtJniTypes::isPrimitiveType<QtCustomJniObject>());
+
+static_assert(!QtJniTypes::isObjectType<jint>());
+static_assert(!QtJniTypes::isObjectType<void>());
+static_assert(QtJniTypes::isObjectType<jobject>());
+static_assert(QtJniTypes::isObjectType<jobjectArray>());
+static_assert(QtJniTypes::isObjectType<QtCustomJniObject>());
+
+static_assert(!QtJniTypes::isArrayType<jint>());
+static_assert(QtJniTypes::isArrayType<jint[]>());
+static_assert(QtJniTypes::isArrayType<jobject[]>());
+static_assert(QtJniTypes::isArrayType<jobjectArray>());
+static_assert(QtJniTypes::isArrayType<QtJavaWrapper[]>());
+
+static_assert(QtJniTypes::CTString("ABCDE").startsWith("ABC"));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith("A"));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith("ABCDE"));
+static_assert(!QtJniTypes::CTString("ABCDE").startsWith("ABCDEF"));
+static_assert(!QtJniTypes::CTString("ABCDE").startsWith("9AB"));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith('A'));
+static_assert(!QtJniTypes::CTString("ABCDE").startsWith('B'));
+
+static_assert(QtJniTypes::Traits<QJniArray<jobject>>::signature() == "[Ljava/lang/Object;");
+static_assert(QtJniTypes::Traits<QJniArray<jbyte>>::signature() == "[B");
+static_assert(QtJniTypes::isObjectType<QJniArray<jbyte>>());
+
+static_assert(QtJniTypes::CTString("ABCDE").endsWith("CDE"));
+static_assert(QtJniTypes::CTString("ABCDE").endsWith("E"));
+static_assert(QtJniTypes::CTString("ABCDE").endsWith("ABCDE"));
+static_assert(!QtJniTypes::CTString("ABCDE").endsWith("DEF"));
+static_assert(!QtJniTypes::CTString("ABCDE").endsWith("ABCDEF"));
+static_assert(QtJniTypes::CTString("ABCDE").endsWith('E'));
+static_assert(!QtJniTypes::CTString("ABCDE").endsWith('F'));
+
+enum UnscopedEnum {};
+enum class ScopedEnum {};
+enum class IntEnum : int {};
+enum class UnsignedEnum : unsigned {};
+enum class Int8Enum : int8_t {};
+enum class ShortEnum : short {};
+enum class LongEnum : quint64 {};
+enum class JIntEnum : jint {};
+
+static_assert(QtJniTypes::Traits<UnscopedEnum>::signature() == "I");
+static_assert(QtJniTypes::Traits<ScopedEnum>::signature() == "I");
+static_assert(QtJniTypes::Traits<IntEnum>::signature() == "I");
+static_assert(QtJniTypes::Traits<UnsignedEnum>::signature() == "I");
+static_assert(QtJniTypes::Traits<Int8Enum>::signature() == "B");
+static_assert(QtJniTypes::Traits<LongEnum>::signature() == "J");
+static_assert(QtJniTypes::Traits<JIntEnum>::signature() == "I");
+
+void tst_QJniTypes::initTestCase()
+{
+
+}
+
+static bool nativeFunction(JNIEnv *, jclass, int, jstring, quint64)
+{
+ return true;
+}
+Q_DECLARE_JNI_NATIVE_METHOD(nativeFunction)
+
+static_assert(QtJniTypes::nativeMethodSignature(nativeFunction) == "(ILjava/lang/String;J)Z");
+
+static QString nativeFunctionStrings(JNIEnv *, jclass, const QString &, const QtJniTypes::String &)
+{
+ return QString();
+}
+Q_DECLARE_JNI_NATIVE_METHOD(nativeFunctionStrings)
+
+static_assert(QtJniTypes::nativeMethodSignature(nativeFunctionStrings)
+ == "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+
+static int forwardDeclaredNativeFunction(JNIEnv *, jobject, bool);
+Q_DECLARE_JNI_NATIVE_METHOD(forwardDeclaredNativeFunction)
+static int forwardDeclaredNativeFunction(JNIEnv *, jobject, bool) { return 0; }
+static_assert(QtJniTypes::nativeMethodSignature(forwardDeclaredNativeFunction) == "(Z)I");
+
+static_assert(QtJniTypes::nativeMethodSignature(tst_QJniTypes::nativeClassMethod) == "(I)V");
+void tst_QJniTypes::nativeClassMethod(JNIEnv *, jclass, int) {}
+
+void tst_QJniTypes::nativeMethod()
+{
+ {
+ const auto method = Q_JNI_NATIVE_METHOD(nativeFunction);
+ QVERIFY(method.fnPtr == QtJniMethods::va_nativeFunction);
+ QCOMPARE(method.name, "nativeFunction");
+ QCOMPARE(method.signature, "(ILjava/lang/String;J)Z");
+ }
+
+ {
+ const auto method = Q_JNI_NATIVE_METHOD(forwardDeclaredNativeFunction);
+ QVERIFY(method.fnPtr == QtJniMethods::va_forwardDeclaredNativeFunction);
+ }
+
+ {
+ const auto method = Q_JNI_NATIVE_SCOPED_METHOD(nativeClassMethod, tst_QJniTypes);
+ QVERIFY(method.fnPtr == va_nativeClassMethod);
+ }
+}
+
+void tst_QJniTypes::construct()
+{
+ using namespace QtJniTypes;
+
+ const QString text = u"Java String"_s;
+ String str(text);
+ QVERIFY(str.isValid());
+ QCOMPARE(str.toString(), text);
+
+ jobject jref = nullptr; // must be jobject, not jstring
+ {
+ // if jref would be a jstring, then this would call the
+ // Java String copy constructor!
+ String jstr(jref);
+ QVERIFY(!jstr.isValid());
+ }
+ jref = str.object<jstring>();
+ {
+ String jstr(jref);
+ QVERIFY(jstr.isValid());
+ QCOMPARE(jstr.toString(), text);
+ }
+
+ String str2 = str;
+ QCOMPARE(str.toString(), text);
+ String str3 = std::move(str2);
+ QCOMPARE(str3.toString(), text);
+}
+
+template <typename ...Arg>
+static constexpr bool isValidArgument(Arg &&...) noexcept
+{
+ return QtJniTypes::ValidSignatureTypesDetail<q20::remove_cvref_t<Arg>...>;
+}
+
+enum class Overload
+{
+ ClassNameAndMethod,
+ OnlyMethod,
+};
+
+template <typename Ret, typename ...Args
+#ifndef Q_QDOC
+ , QtJniTypes::IfValidSignatureTypes<Ret, Args...> = true
+#endif
+>
+static constexpr auto callStaticMethod(const char *className, const char *methodName, Args &&...)
+{
+ Q_UNUSED(className);
+ Q_UNUSED(methodName);
+ return Overload::ClassNameAndMethod;
+}
+
+template <typename Klass, typename Ret, typename ...Args
+#ifndef Q_QDOC
+ , QtJniTypes::IfValidSignatureTypes<Ret, Args...> = true
+#endif
+>
+static constexpr auto callStaticMethod(const char *methodName, Args &&...)
+{
+ Q_UNUSED(methodName);
+ return Overload::OnlyMethod;
+}
+
+void tst_QJniTypes::stringTypeCantBeArgument()
+{
+ const char *methodName = "staticEchoMethod";
+
+ static_assert(!isValidArgument(QtJniTypes::Traits<QtJniTypes::JavaType>::className()));
+ static_assert(!isValidArgument("someFunctionName"));
+ static_assert(!isValidArgument(methodName));
+ static_assert(!isValidArgument(QtJniTypes::Traits<QtJniTypes::JavaType>::className(),
+ "someFunctionName", methodName, 42));
+
+ static_assert(callStaticMethod<jstring, jint>("class name", "method name", 42)
+ == Overload::ClassNameAndMethod);
+ static_assert(callStaticMethod<QtJniTypes::JavaType, jint>("method name", 42)
+ == Overload::OnlyMethod);
+}
+
+QTEST_MAIN(tst_QJniTypes)
+
+#include "tst_qjnitypes.moc"
diff --git a/tests/auto/corelib/kernel/qmath/CMakeLists.txt b/tests/auto/corelib/kernel/qmath/CMakeLists.txt
new file mode 100644
index 0000000000..39a5a8b6df
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmath/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmath Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmath LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmath
+ SOURCES
+ tst_qmath.cpp
+)
diff --git a/tests/auto/corelib/kernel/qmath/qmath.pro b/tests/auto/corelib/kernel/qmath/qmath.pro
deleted file mode 100644
index 703c530e35..0000000000
--- a/tests/auto/corelib/kernel/qmath/qmath.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmath
-QT = core testlib
-SOURCES = tst_qmath.cpp
diff --git a/tests/auto/corelib/kernel/qmath/tst_qmath.cpp b/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
index feb704e0aa..1961b71d83 100644
--- a/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
+++ b/tests/auto/corelib/kernel/qmath/tst_qmath.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2013 Laszlo Papp <lpapp@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qmath.h>
+#include <qfloat16.h>
class tst_QMath : public QObject
{
@@ -39,6 +15,11 @@ private slots:
void degreesToRadians();
void radiansToDegrees_data();
void radiansToDegrees();
+ void trigonometry_data();
+ void trigonometry();
+ void hypotenuse();
+ void funcs_data();
+ void funcs();
void qNextPowerOfTwo32S_data();
void qNextPowerOfTwo32S();
void qNextPowerOfTwo64S_data();
@@ -131,6 +112,143 @@ void tst_QMath::radiansToDegrees()
QCOMPARE(qRadiansToDegrees(radiansDouble), degreesDouble);
}
+void tst_QMath::trigonometry_data()
+{
+ QTest::addColumn<double>("x");
+ QTest::addColumn<double>("y");
+ QTest::addColumn<double>("angle");
+
+ QTest::newRow("zero") << 1.0 << 0.0 << 0.0;
+ QTest::newRow("turn/4") << 0.0 << 1.0 << M_PI_2;
+ QTest::newRow("turn/2") << -1.0 << 0.0 << M_PI;
+ QTest::newRow("3*turn/4") << 0.0 << -1.0 << -M_PI_2;
+}
+
+void tst_QMath::trigonometry()
+{
+ QFETCH(const double, x);
+ QFETCH(const double, y);
+ QFETCH(const double, angle);
+ const double hypot = qHypot(x, y);
+ QVERIFY(hypot > 0);
+ QCOMPARE(qAtan2(y, x), angle);
+ QCOMPARE(qSin(angle), y / hypot);
+ if (x >= 0 && (y || x)) // aSin() always in right half-plane
+ QCOMPARE(qAsin(y / hypot), angle);
+ QCOMPARE(qCos(angle), x / hypot);
+ if (y >= 0 && (y || x)) // aCos() always in upper half-plane
+ QCOMPARE(qAcos(x / hypot), angle);
+ if (x > 0) {
+ QCOMPARE(qTan(angle), y / x);
+ QCOMPARE(qAtan(y / x), angle);
+ }
+}
+
+void tst_QMath::hypotenuse()
+{
+ // Correct return-types, particularly when qfloat16 is involved:
+ static_assert(std::is_same<decltype(qHypot(qfloat16(1), qfloat16(1), qfloat16(1),
+ qfloat16(1), qfloat16(1), qfloat16(1),
+ qfloat16(1), qfloat16(1), qfloat16(1))),
+ qfloat16>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), qfloat16(4), qfloat16(12))),
+ qfloat16>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), qfloat16(4), 12.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0f, qfloat16(12))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, qfloat16(4), qfloat16(12))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0f, 12.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, qfloat16(4), 12.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0f, qfloat16(12))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), qfloat16(4))), qfloat16>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, qfloat16(4))), float>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, qfloat16(4))), double>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, qfloat16(4))), double>::value);
+ static_assert(std::is_same<decltype(qHypot(qfloat16(3), 4.0L)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0L, qfloat16(4))), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0f)), float>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0f, 4.0L)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4.0f)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, 4.0f)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0L, 4.0f)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4.0L)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0L, 4.0)), long double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, 4.0)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3.0, 4)), double>::value);
+ static_assert(std::is_same<decltype(qHypot(3, 4)), double>::value);
+
+ // Works for all numeric types:
+ QCOMPARE(qHypot(3, 4), 5);
+ QCOMPARE(qHypot(qfloat16(5), qfloat16(12)), qfloat16(13));
+ QCOMPARE(qHypot(3.0f, 4.0f, 12.0f), 13.0f);
+ QCOMPARE(qHypot(3.0, 4.0, 12.0, 84.0), 85.0);
+ QCOMPARE(qHypot(3.0f, 4.0f, 12.0f, 84.0f, 720.0f), 725.0f);
+ QCOMPARE(qHypot(3.0, 4.0, 12.0, 84.0, 3612.0), 3613.0);
+ // Integral gets promoted to double:
+ QCOMPARE(qHypot(1, 1), M_SQRT2);
+ // Caller can mix types freely:
+ QCOMPARE(qHypot(3.0f, 4, 12.0, 84.0f, qfloat16(720), 10500), 10525);
+ // NaN wins over any finite:
+ QCOMPARE(qHypot(3, 4.0, 12.0f, qQNaN()), qQNaN());
+ QCOMPARE(qHypot(3, 4.0, qQNaN(), 12.0f), qQNaN());
+ QCOMPARE(qHypot(3, qQNaN(), 4.0, 12.0f), qQNaN());
+ QCOMPARE(qHypot(qQNaN(), 3, 4.0, 12.0f), qQNaN());
+ // but Infinity beats NaN:
+ QCOMPARE(qHypot(3, 4.0f, -qInf(), qQNaN()), qInf());
+ QCOMPARE(qHypot(3, -qInf(), 4.0f, qQNaN()), qInf());
+ QCOMPARE(qHypot(-qInf(), 3, 4.0f, qQNaN()), qInf());
+ QCOMPARE(qHypot(qQNaN(), 3, -qInf(), 4.0f), qInf());
+ QCOMPARE(qHypot(3, qQNaN(), 4.0f, -qInf()), qInf());
+ QCOMPARE(qHypot(3, 4.0f, qQNaN(), -qInf()), qInf());
+ // Components whose squares sum to zero don't change the end result:
+ const double minD = std::numeric_limits<double>::min();
+ QVERIFY(minD * minD + minD * minD == 0); // *NOT* QCOMPARE
+ QCOMPARE(qHypot(minD, minD, 12.0), 12.0);
+ const float minF = std::numeric_limits<float>::min();
+ QVERIFY(minF * minF + minF * minF == 0.0f); // *NOT* QCOMPARE
+ QCOMPARE(qHypot(minF, minF, 12.0f), 12.0f);
+ const qfloat16 minF16 = std::numeric_limits<qfloat16>::min();
+ QVERIFY(minF16 * minF16 + minF16 * minF16 == qfloat16(0)); // *NOT* QCOMPARE
+ QCOMPARE(qHypot(minF16, minF16, qfloat16(12)), qfloat16(12));
+}
+
+void tst_QMath::funcs_data()
+{
+ QTest::addColumn<double>("value");
+ QTest::addColumn<int>("floor");
+ QTest::addColumn<int>("ceil");
+ QTest::addColumn<double>("abs");
+ QTest::addColumn<double>("sqrt");
+ QTest::addColumn<double>("log");
+ QTest::addColumn<double>("exp");
+ QTest::addColumn<double>("cube");
+ const double nan = qQNaN();
+
+ QTest::newRow("0") << 0.0 << 0 << 0 << 0.0 << 0.0 << nan << 1.0 << 0.0;
+ QTest::newRow("1.44")
+ << 1.44 << 1 << 2 << 1.44 << 1.2 << 0.36464311358790924 << 4.220695816996552 << 2.985984;
+ QTest::newRow("-1.44")
+ << -1.44 << -2 << -1 << 1.44 << nan << nan << 0.23692775868212176 << -2.985984;
+}
+
+void tst_QMath::funcs()
+{
+ QFETCH(double, value);
+ QTEST(qFloor(value), "floor");
+ QTEST(qCeil(value), "ceil");
+ QTEST(qFabs(value), "abs");
+ if (value >= 0)
+ QTEST(qSqrt(value), "sqrt");
+ if (value > 0)
+ QTEST(qLn(value), "log");
+ QTEST(qExp(value), "exp");
+ QTEST(qPow(value, 3), "cube");
+}
void tst_QMath::qNextPowerOfTwo32S_data()
{
@@ -147,9 +265,6 @@ void tst_QMath::qNextPowerOfTwo32S_data()
QTest::newRow("2^30") << (1 << 30) << (1U << 31);
QTest::newRow("2^30 + 1") << (1 << 30) + 1 << (1U << 31);
QTest::newRow("2^31 - 1") << 0x7FFFFFFF << (1U<<31);
- QTest::newRow("-1") << -1 << 0U;
- QTest::newRow("-128") << -128 << 0U;
- QTest::newRow("-(2^31)") << int(0x80000000) << 0U;
}
void tst_QMath::qNextPowerOfTwo32S()
@@ -175,8 +290,6 @@ void tst_QMath::qNextPowerOfTwo32U_data()
QTest::newRow("2^30") << (1U << 30) << (1U << 31);
QTest::newRow("2^30 + 1") << (1U << 30) + 1 << (1U << 31);
QTest::newRow("2^31 - 1") << 2147483647U << 2147483648U;
- QTest::newRow("2^31") << 2147483648U << 0U;
- QTest::newRow("2^31 + 1") << 2147483649U << 0U;
}
void tst_QMath::qNextPowerOfTwo32U()
@@ -203,10 +316,6 @@ void tst_QMath::qNextPowerOfTwo64S_data()
QTest::newRow("2^31") << Q_INT64_C(2147483648) << Q_UINT64_C(0x100000000);
QTest::newRow("2^31 + 1") << Q_INT64_C(2147483649) << Q_UINT64_C(0x100000000);
QTest::newRow("2^63 - 1") << Q_INT64_C(0x7FFFFFFFFFFFFFFF) << Q_UINT64_C(0x8000000000000000);
- QTest::newRow("-1") << Q_INT64_C(-1) << Q_UINT64_C(0);
- QTest::newRow("-128") << Q_INT64_C(-128) << Q_UINT64_C(0);
- QTest::newRow("-(2^31)") << -Q_INT64_C(0x80000000) << Q_UINT64_C(0);
- QTest::newRow("-(2^63)") << (qint64)Q_INT64_C(0x8000000000000000) << Q_UINT64_C(0);
}
void tst_QMath::qNextPowerOfTwo64S()
@@ -230,8 +339,6 @@ void tst_QMath::qNextPowerOfTwo64U_data()
QTest::newRow("65535") << Q_UINT64_C(65535) << Q_UINT64_C(65536);
QTest::newRow("65536") << Q_UINT64_C(65536) << Q_UINT64_C(131072);
QTest::newRow("2^63 - 1") << Q_UINT64_C(0x7FFFFFFFFFFFFFFF) << Q_UINT64_C(0x8000000000000000);
- QTest::newRow("2^63") << Q_UINT64_C(0x8000000000000000) << Q_UINT64_C(0);
- QTest::newRow("2^63 + 1") << Q_UINT64_C(0x8000000000000001) << Q_UINT64_C(0);
}
void tst_QMath::qNextPowerOfTwo64U()
diff --git a/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt b/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt
new file mode 100644
index 0000000000..fb58aebe73
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmetacontainer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetacontainer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmetacontainer
+ SOURCES
+ tst_qmetacontainer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp b/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp
new file mode 100644
index 0000000000..cc1d8baa8e
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp
@@ -0,0 +1,749 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest/qtest.h>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QtCore/qcontainerinfo.h>
+#include <QtCore/qmetacontainer.h>
+#include <QtCore/QMap>
+#include <QtCore/QHash>
+
+#include <QtCore/qvector.h>
+#include <QtCore/qset.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qbytearray.h>
+
+#include <vector>
+#include <set>
+#include <forward_list>
+#include <unordered_map>
+
+namespace CheckContainerTraits
+{
+struct NotAContainer {};
+
+static_assert(QContainerInfo::has_size_v<QVector<int>>);
+static_assert(QContainerInfo::has_size_v<QSet<int>>);
+static_assert(!QContainerInfo::has_size_v<NotAContainer>);
+static_assert(QContainerInfo::has_size_v<std::vector<int>>);
+static_assert(QContainerInfo::has_size_v<std::set<int>>);
+static_assert(!QContainerInfo::has_size_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_clear_v<QVector<int>>);
+static_assert(QContainerInfo::has_clear_v<QSet<int>>);
+static_assert(!QContainerInfo::has_clear_v<NotAContainer>);
+static_assert(QContainerInfo::has_clear_v<std::vector<int>>);
+static_assert(QContainerInfo::has_clear_v<std::set<int>>);
+static_assert(QContainerInfo::has_clear_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_at_index_v<QVector<int>>);
+static_assert(!QContainerInfo::has_at_index_v<QSet<int>>);
+static_assert(!QContainerInfo::has_at_index_v<NotAContainer>);
+static_assert(QContainerInfo::has_at_index_v<std::vector<int>>);
+static_assert(!QContainerInfo::has_at_index_v<std::set<int>>);
+static_assert(!QContainerInfo::has_at_index_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::can_get_at_index_v<QVector<int>>);
+static_assert(!QContainerInfo::can_get_at_index_v<QSet<int>>);
+static_assert(!QContainerInfo::can_get_at_index_v<NotAContainer>);
+static_assert(QContainerInfo::can_get_at_index_v<std::vector<int>>);
+static_assert(!QContainerInfo::can_get_at_index_v<std::set<int>>);
+static_assert(!QContainerInfo::can_get_at_index_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::can_set_at_index_v<QVector<int>>);
+static_assert(!QContainerInfo::can_set_at_index_v<QSet<int>>);
+static_assert(!QContainerInfo::can_set_at_index_v<NotAContainer>);
+static_assert(QContainerInfo::can_set_at_index_v<std::vector<int>>);
+static_assert(!QContainerInfo::can_set_at_index_v<std::set<int>>);
+static_assert(!QContainerInfo::can_set_at_index_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_push_back_v<QVector<int>>);
+static_assert(!QContainerInfo::has_push_back_v<QSet<int>>);
+static_assert(!QContainerInfo::has_push_back_v<NotAContainer>);
+static_assert(QContainerInfo::has_push_back_v<std::vector<int>>);
+static_assert(!QContainerInfo::has_push_back_v<std::set<int>>);
+static_assert(!QContainerInfo::has_push_back_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_push_front_v<QVector<int>>);
+static_assert(!QContainerInfo::has_push_front_v<QSet<int>>);
+static_assert(!QContainerInfo::has_push_front_v<NotAContainer>);
+static_assert(!QContainerInfo::has_push_front_v<std::vector<int>>);
+static_assert(!QContainerInfo::has_push_front_v<std::set<int>>);
+static_assert(QContainerInfo::has_push_front_v<std::forward_list<int>>);
+
+static_assert(!QContainerInfo::has_insert_v<QVector<int>>);
+static_assert(QContainerInfo::has_insert_v<QSet<int>>);
+static_assert(!QContainerInfo::has_insert_v<NotAContainer>);
+static_assert(!QContainerInfo::has_insert_v<std::vector<int>>);
+static_assert(QContainerInfo::has_insert_v<std::set<int>>);
+static_assert(!QContainerInfo::has_insert_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_pop_back_v<QVector<int>>);
+static_assert(!QContainerInfo::has_pop_back_v<QSet<int>>);
+static_assert(!QContainerInfo::has_pop_back_v<NotAContainer>);
+static_assert(QContainerInfo::has_pop_back_v<std::vector<int>>);
+static_assert(!QContainerInfo::has_pop_back_v<std::set<int>>);
+static_assert(!QContainerInfo::has_pop_back_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_pop_front_v<QVector<int>>);
+static_assert(!QContainerInfo::has_pop_front_v<QSet<int>>);
+static_assert(!QContainerInfo::has_pop_front_v<NotAContainer>);
+static_assert(!QContainerInfo::has_pop_front_v<std::vector<int>>);
+static_assert(!QContainerInfo::has_pop_front_v<std::set<int>>);
+static_assert(QContainerInfo::has_pop_front_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_iterator_v<QVector<int>>);
+static_assert(QContainerInfo::has_iterator_v<QSet<int>>);
+static_assert(!QContainerInfo::has_iterator_v<NotAContainer>);
+static_assert(QContainerInfo::has_iterator_v<std::vector<int>>);
+static_assert(QContainerInfo::has_iterator_v<std::set<int>>);
+static_assert(QContainerInfo::has_iterator_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::has_const_iterator_v<QVector<int>>);
+static_assert(QContainerInfo::has_const_iterator_v<QSet<int>>);
+static_assert(!QContainerInfo::has_const_iterator_v<NotAContainer>);
+static_assert(QContainerInfo::has_const_iterator_v<std::vector<int>>);
+static_assert(QContainerInfo::has_const_iterator_v<std::set<int>>);
+static_assert(QContainerInfo::has_const_iterator_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::iterator_dereferences_to_value_v<QVector<int>>);
+static_assert(QContainerInfo::iterator_dereferences_to_value_v<QSet<int>>);
+static_assert(!QContainerInfo::iterator_dereferences_to_value_v<NotAContainer>);
+static_assert(QContainerInfo::iterator_dereferences_to_value_v<std::vector<int>>);
+static_assert(QContainerInfo::iterator_dereferences_to_value_v<std::set<int>>);
+static_assert(QContainerInfo::iterator_dereferences_to_value_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::can_set_value_at_iterator_v<QVector<int>>);
+static_assert(!QContainerInfo::can_set_value_at_iterator_v<QSet<int>>);
+static_assert(!QContainerInfo::can_set_value_at_iterator_v<NotAContainer>);
+static_assert(QContainerInfo::can_set_value_at_iterator_v<std::vector<int>>);
+static_assert(!QContainerInfo::can_set_value_at_iterator_v<std::set<int>>);
+static_assert(QContainerInfo::can_set_value_at_iterator_v<std::forward_list<int>>);
+
+static_assert(QContainerInfo::can_insert_value_at_iterator_v<QVector<int>>);
+static_assert(QContainerInfo::can_insert_value_at_iterator_v<QSet<int>>);
+static_assert(!QContainerInfo::can_insert_value_at_iterator_v<NotAContainer>);
+static_assert(QContainerInfo::can_insert_value_at_iterator_v<std::vector<int>>);
+static_assert(!QContainerInfo::can_insert_value_at_iterator_v<std::forward_list<int>>);
+
+// The iterator is only a hint, but syntactically indistinguishable from others.
+// It's explicitly there to be signature compatible with std::vector::insert, though.
+// Also, inserting into a set is not guaranteed to actually do anything.
+static_assert(QContainerInfo::can_insert_value_at_iterator_v<std::set<int>>);
+
+static_assert(QContainerInfo::can_erase_at_iterator_v<QVector<int>>);
+static_assert(QContainerInfo::can_erase_at_iterator_v<QSet<int>>);
+static_assert(!QContainerInfo::can_erase_at_iterator_v<NotAContainer>);
+static_assert(QContainerInfo::can_erase_at_iterator_v<std::vector<int>>);
+static_assert(QContainerInfo::can_erase_at_iterator_v<std::set<int>>);
+static_assert(!QContainerInfo::can_erase_at_iterator_v<std::forward_list<int>>);
+
+}
+
+class tst_QMetaContainer: public QObject
+{
+ Q_OBJECT
+
+private:
+ QVector<QMetaType> qvector;
+ std::vector<QString> stdvector;
+ QSet<QByteArray> qset;
+ std::set<int> stdset;
+ std::forward_list<QMetaSequence> forwardList;
+
+ QHash<int, QMetaType> qhash;
+ QMap<QByteArray, bool> qmap;
+ std::map<QString, int> stdmap;
+ std::unordered_map<int, QMetaAssociation> stdunorderedmap;
+
+private slots:
+ void init();
+ void compareCompiles();
+ void testSequence_data();
+ void testSequence();
+
+ void testAssociation_data();
+ void testAssociation();
+
+ void cleanup();
+};
+
+void tst_QMetaContainer::init()
+{
+ qvector = { QMetaType(), QMetaType::fromType<QString>(), QMetaType::fromType<int>() };
+ stdvector = { QStringLiteral("foo"), QStringLiteral("bar"), QStringLiteral("baz") };
+ qset = { "aaa", "bbb", "ccc" };
+ stdset = { 1, 2, 3, 42, 45, 11 };
+ forwardList = {
+ QMetaSequence::fromContainer<QVector<QMetaType>>(),
+ QMetaSequence::fromContainer<std::vector<QString>>(),
+ QMetaSequence::fromContainer<QSet<QByteArray>>(),
+ QMetaSequence::fromContainer<std::set<int>>(),
+ QMetaSequence::fromContainer<std::forward_list<QMetaSequence>>()
+ };
+ qhash = {
+ { 233, QMetaType() },
+ { 11, QMetaType::fromType<QByteArray>() },
+ { 6626, QMetaType::fromType<bool>() }
+ };
+ qmap = {
+ { "eins", true },
+ { "zwei", false },
+ { "elfundvierzig", true }
+ };
+
+ stdmap = {
+ { QStringLiteral("dkdkdkd"), 58583 },
+ { QStringLiteral("ooo30393"), 12 },
+ { QStringLiteral("2dddd30393"), 999999 },
+ };
+ stdunorderedmap = {
+ { 11, QMetaAssociation::fromContainer<QHash<int, QMetaType>>() },
+ { 12, QMetaAssociation::fromContainer<QMap<QByteArray, bool>>() },
+ { 393, QMetaAssociation::fromContainer<std::map<QString, int>>() },
+ { 293, QMetaAssociation::fromContainer<std::unordered_map<int, QMetaAssociation>>() }
+ };
+}
+
+void tst_QMetaContainer::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QMetaSequence>();
+ QTestPrivate::testEqualityOperatorsCompile<QMetaAssociation>();
+}
+
+void tst_QMetaContainer::cleanup()
+{
+ qvector.clear();
+ stdvector.clear();
+ qset.clear();
+ stdset.clear();
+ forwardList.clear();
+ qhash.clear();
+ qmap.clear();
+ stdmap.clear();
+ stdunorderedmap.clear();
+}
+
+void tst_QMetaContainer::testSequence_data()
+{
+ QTest::addColumn<void *>("container");
+ QTest::addColumn<QMetaSequence>("metaSequence");
+ QTest::addColumn<QMetaType>("metaType");
+ QTest::addColumn<bool>("hasSize");
+ QTest::addColumn<bool>("isIndexed");
+ QTest::addColumn<bool>("canRemove");
+ QTest::addColumn<bool>("hasBidirectionalIterator");
+ QTest::addColumn<bool>("hasRandomAccessIterator");
+ QTest::addColumn<bool>("canInsertAtIterator");
+ QTest::addColumn<bool>("canEraseAtIterator");
+ QTest::addColumn<bool>("isSortable");
+
+ QTest::addRow("QVector")
+ << static_cast<void *>(&qvector)
+ << QMetaSequence::fromContainer<QVector<QMetaType>>()
+ << QMetaType::fromType<QMetaType>()
+ << true << true << true << true << true << true << true << true;
+ QTest::addRow("std::vector")
+ << static_cast<void *>(&stdvector)
+ << QMetaSequence::fromContainer<std::vector<QString>>()
+ << QMetaType::fromType<QString>()
+ << true << true << true << true << true << true << true << true;
+ QTest::addRow("QSet")
+ << static_cast<void *>(&qset)
+ << QMetaSequence::fromContainer<QSet<QByteArray>>()
+ << QMetaType::fromType<QByteArray>()
+ << true << false << false << false << false << true << true << false;
+ QTest::addRow("std::set")
+ << static_cast<void *>(&stdset)
+ << QMetaSequence::fromContainer<std::set<int>>()
+ << QMetaType::fromType<int>()
+ << true << false << false << true << false << true << true << false;
+ QTest::addRow("std::forward_list")
+ << static_cast<void *>(&forwardList)
+ << QMetaSequence::fromContainer<std::forward_list<QMetaSequence>>()
+ << QMetaType::fromType<QMetaSequence>()
+ << false << false << true << false << false << false << false << true;
+}
+
+void tst_QMetaContainer::testSequence()
+{
+ QFETCH(void *, container);
+ QFETCH(QMetaSequence, metaSequence);
+ QFETCH(QMetaType, metaType);
+ QFETCH(bool, hasSize);
+ QFETCH(bool, isIndexed);
+ QFETCH(bool, canRemove);
+ QFETCH(bool, hasBidirectionalIterator);
+ QFETCH(bool, hasRandomAccessIterator);
+ QFETCH(bool, canInsertAtIterator);
+ QFETCH(bool, canEraseAtIterator);
+ QFETCH(bool, isSortable);
+
+ QVERIFY(metaSequence.canAddValue());
+ QCOMPARE(metaSequence.hasSize(), hasSize);
+ QCOMPARE(metaSequence.canGetValueAtIndex(), isIndexed);
+ QCOMPARE(metaSequence.canSetValueAtIndex(), isIndexed);
+ QCOMPARE(metaSequence.canRemoveValue(), canRemove);
+ QCOMPARE(metaSequence.hasBidirectionalIterator(), hasBidirectionalIterator);
+ QCOMPARE(metaSequence.hasRandomAccessIterator(), hasRandomAccessIterator);
+ QCOMPARE(metaSequence.canInsertValueAtIterator(), canInsertAtIterator);
+ QCOMPARE(metaSequence.canEraseValueAtIterator(), canEraseAtIterator);
+ QCOMPARE(metaSequence.isSortable(), isSortable);
+
+ QVariant var1(metaType);
+ QVariant var2(metaType);
+ QVariant var3(metaType);
+
+ if (hasSize) {
+ const qsizetype size = metaSequence.size(container);
+
+ // var1 is invalid, and our sets do not contain an invalid value so far.
+ metaSequence.addValue(container, var1.constData());
+ QCOMPARE(metaSequence.size(container), size + 1);
+ if (canRemove) {
+ metaSequence.removeValue(container);
+ QCOMPARE(metaSequence.size(container), size);
+ }
+ } else {
+ metaSequence.addValue(container, var1.constData());
+ if (canRemove)
+ metaSequence.removeValue(container);
+ }
+
+ if (isIndexed) {
+ QVERIFY(hasSize);
+ const qsizetype size = metaSequence.size(container);
+ for (qsizetype i = 0; i < size; ++i) {
+ metaSequence.valueAtIndex(container, i, var1.data());
+ metaSequence.valueAtIndex(container, size - i - 1, var2.data());
+
+ metaSequence.setValueAtIndex(container, i, var2.constData());
+ metaSequence.setValueAtIndex(container, size - i - 1, var1.constData());
+
+ metaSequence.valueAtIndex(container, i, var3.data());
+ QCOMPARE(var3, var2);
+
+ metaSequence.valueAtIndex(container, size - i - 1, var3.data());
+ QCOMPARE(var3, var1);
+ }
+ }
+
+ QVERIFY(metaSequence.hasIterator());
+ QVERIFY(metaSequence.hasConstIterator());
+ QVERIFY(metaSequence.canGetValueAtIterator());
+ QVERIFY(metaSequence.canGetValueAtConstIterator());
+
+ void *it = metaSequence.begin(container);
+ void *end = metaSequence.end(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ void *constIt = metaSequence.constBegin(container);
+ void *constEnd = metaSequence.constEnd(container);
+ QVERIFY(constIt);
+ QVERIFY(constEnd);
+
+ const qsizetype size = metaSequence.diffIterator(end, it);
+ QCOMPARE(size, metaSequence.diffConstIterator(constEnd, constIt));
+ if (hasSize)
+ QCOMPARE(size, metaSequence.size(container));
+
+ qsizetype count = 0;
+ for (; !metaSequence.compareIterator(it, end);
+ metaSequence.advanceIterator(it, 1), metaSequence.advanceConstIterator(constIt, 1)) {
+ metaSequence.valueAtIterator(it, var1.data());
+ if (isIndexed) {
+ metaSequence.valueAtIndex(container, count, var2.data());
+ QCOMPARE(var1, var2);
+ }
+ metaSequence.valueAtConstIterator(constIt, var3.data());
+ QCOMPARE(var3, var1);
+ ++count;
+ }
+
+ QCOMPARE(count, size);
+ QVERIFY(metaSequence.compareConstIterator(constIt, constEnd));
+
+ metaSequence.destroyIterator(it);
+ metaSequence.destroyIterator(end);
+ metaSequence.destroyConstIterator(constIt);
+ metaSequence.destroyConstIterator(constEnd);
+
+ if (metaSequence.canSetValueAtIterator()) {
+ void *it = metaSequence.begin(container);
+ void *end = metaSequence.end(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ for (; !metaSequence.compareIterator(it, end); metaSequence.advanceIterator(it, 1)) {
+ metaSequence.valueAtIterator(it, var1.data());
+ metaSequence.setValueAtIterator(it, var2.constData());
+ metaSequence.valueAtIterator(it, var3.data());
+ QCOMPARE(var2, var3);
+ var2 = var1;
+ }
+
+ metaSequence.destroyIterator(it);
+ metaSequence.destroyIterator(end);
+ }
+
+ if (metaSequence.hasBidirectionalIterator()) {
+ void *it = metaSequence.end(container);
+ void *end = metaSequence.begin(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ void *constIt = metaSequence.constEnd(container);
+ void *constEnd = metaSequence.constBegin(container);
+ QVERIFY(constIt);
+ QVERIFY(constEnd);
+
+ qsizetype size = 0;
+ if (metaSequence.hasRandomAccessIterator()) {
+ size = metaSequence.diffIterator(end, it);
+ QCOMPARE(size, metaSequence.diffConstIterator(constEnd, constIt));
+ } else {
+ size = -metaSequence.diffIterator(it, end);
+ }
+
+ if (hasSize)
+ QCOMPARE(size, -metaSequence.size(container));
+
+ qsizetype count = 0;
+ do {
+ metaSequence.advanceIterator(it, -1);
+ metaSequence.advanceConstIterator(constIt, -1);
+ --count;
+
+ metaSequence.valueAtIterator(it, var1.data());
+ if (isIndexed) {
+ metaSequence.valueAtIndex(container, count - size, var2.data());
+ QCOMPARE(var1, var2);
+ }
+ metaSequence.valueAtConstIterator(constIt, var3.data());
+ QCOMPARE(var3, var1);
+ } while (!metaSequence.compareIterator(it, end));
+
+ QCOMPARE(count, size);
+ QVERIFY(metaSequence.compareConstIterator(constIt, constEnd));
+
+ metaSequence.destroyIterator(it);
+ metaSequence.destroyIterator(end);
+ metaSequence.destroyConstIterator(constIt);
+ metaSequence.destroyConstIterator(constEnd);
+ }
+
+ if (canInsertAtIterator) {
+ void *it = metaSequence.begin(container);
+ void *end = metaSequence.end(container);
+
+ const qsizetype size = metaSequence.diffIterator(end, it);
+ metaSequence.destroyIterator(end);
+
+ metaSequence.insertValueAtIterator(container, it, var1.constData());
+ metaSequence.destroyIterator(it);
+ it = metaSequence.begin(container);
+ metaSequence.insertValueAtIterator(container, it, var2.constData());
+ metaSequence.destroyIterator(it);
+ it = metaSequence.begin(container);
+ metaSequence.insertValueAtIterator(container, it, var3.constData());
+
+ metaSequence.destroyIterator(it);
+
+ it = metaSequence.begin(container);
+ end = metaSequence.end(container);
+
+ const qsizetype newSize = metaSequence.diffIterator(end, it);
+
+ if (metaSequence.isSortable()) {
+ QCOMPARE(newSize, size + 3);
+ QVariant var4(metaType);
+ metaSequence.valueAtIterator(it, var4.data());
+ QCOMPARE(var4, var3);
+ metaSequence.advanceIterator(it, 1);
+ metaSequence.valueAtIterator(it, var4.data());
+ QCOMPARE(var4, var2);
+ metaSequence.advanceIterator(it, 1);
+ metaSequence.valueAtIterator(it, var4.data());
+ QCOMPARE(var4, var1);
+ } else {
+ QVERIFY(newSize >= size);
+ }
+
+ if (canEraseAtIterator) {
+ for (int i = 0; i < newSize; ++i) {
+ metaSequence.destroyIterator(it);
+ it = metaSequence.begin(container);
+ metaSequence.eraseValueAtIterator(container, it);
+ }
+
+ metaSequence.destroyIterator(it);
+ it = metaSequence.begin(container);
+ metaSequence.destroyIterator(end);
+ end = metaSequence.end(container);
+ QVERIFY(metaSequence.compareIterator(it, end));
+
+ metaSequence.addValue(container, var1.constData());
+ metaSequence.addValue(container, var2.constData());
+ metaSequence.addValue(container, var3.constData());
+ }
+
+ metaSequence.destroyIterator(end);
+ metaSequence.destroyIterator(it);
+ }
+
+ QVERIFY(metaSequence.canClear());
+ constIt = metaSequence.constBegin(container);
+ constEnd = metaSequence.constEnd(container);
+ QVERIFY(!metaSequence.compareConstIterator(constIt, constEnd));
+ metaSequence.destroyConstIterator(constIt);
+ metaSequence.destroyConstIterator(constEnd);
+
+ metaSequence.clear(container);
+ constIt = metaSequence.constBegin(container);
+ constEnd = metaSequence.constEnd(container);
+ QVERIFY(metaSequence.compareConstIterator(constIt, constEnd));
+ metaSequence.destroyConstIterator(constIt);
+ metaSequence.destroyConstIterator(constEnd);
+
+ QVERIFY(metaSequence.iface() != nullptr);
+ QMetaSequence defaultConstructed;
+ QVERIFY(defaultConstructed.iface() == nullptr);
+ QT_TEST_EQUALITY_OPS(QMetaSequence(), defaultConstructed, true);
+ QT_TEST_EQUALITY_OPS(QMetaSequence(), QMetaSequence(), true);
+ QT_TEST_EQUALITY_OPS(defaultConstructed, metaSequence, false);
+}
+
+void tst_QMetaContainer::testAssociation_data()
+{
+ QTest::addColumn<void *>("container");
+ QTest::addColumn<QMetaAssociation>("metaAssociation");
+ QTest::addColumn<QMetaType>("keyType");
+ QTest::addColumn<QMetaType>("mappedType");
+ QTest::addColumn<bool>("hasSize");
+ QTest::addColumn<bool>("canRemove");
+ QTest::addColumn<bool>("canSetMapped");
+ QTest::addColumn<bool>("hasBidirectionalIterator");
+ QTest::addColumn<bool>("hasRandomAccessIterator");
+
+ QTest::addRow("QHash")
+ << static_cast<void *>(&qhash)
+ << QMetaAssociation::fromContainer<QHash<int, QMetaType>>()
+ << QMetaType::fromType<int>()
+ << QMetaType::fromType<QMetaType>()
+ << true << true << true << false << false;
+ QTest::addRow("QMap")
+ << static_cast<void *>(&qmap)
+ << QMetaAssociation::fromContainer<QMap<QByteArray, bool>>()
+ << QMetaType::fromType<QByteArray>()
+ << QMetaType::fromType<bool>()
+ << true << true << true << true << false;
+ QTest::addRow("std::map")
+ << static_cast<void *>(&stdmap)
+ << QMetaAssociation::fromContainer<std::map<QString, int>>()
+ << QMetaType::fromType<QString>()
+ << QMetaType::fromType<int>()
+ << true << true << true << true << false;
+ QTest::addRow("std::unorderedmap")
+ << static_cast<void *>(&stdunorderedmap)
+ << QMetaAssociation::fromContainer<std::unordered_map<int, QMetaAssociation>>()
+ << QMetaType::fromType<int>()
+ << QMetaType::fromType<QMetaAssociation>()
+ << true << true << true << false << false;
+ QTest::addRow("QSet")
+ << static_cast<void *>(&qset)
+ << QMetaAssociation::fromContainer<QSet<QByteArray>>()
+ << QMetaType::fromType<QByteArray>()
+ << QMetaType()
+ << true << true << false << false << false;
+ QTest::addRow("std::set")
+ << static_cast<void *>(&stdset)
+ << QMetaAssociation::fromContainer<std::set<int>>()
+ << QMetaType::fromType<int>()
+ << QMetaType()
+ << true << true << false << true << false;
+}
+
+void tst_QMetaContainer::testAssociation()
+{
+ QFETCH(void *, container);
+ QFETCH(QMetaAssociation, metaAssociation);
+ QFETCH(QMetaType, keyType);
+ QFETCH(QMetaType, mappedType);
+ QFETCH(bool, hasSize);
+ QFETCH(bool, canRemove);
+ QFETCH(bool, canSetMapped);
+ QFETCH(bool, hasBidirectionalIterator);
+ QFETCH(bool, hasRandomAccessIterator);
+
+ QCOMPARE(metaAssociation.hasSize(), hasSize);
+ QCOMPARE(metaAssociation.canRemoveKey(), canRemove);
+ QCOMPARE(metaAssociation.canSetMappedAtKey(), canSetMapped);
+ QCOMPARE(metaAssociation.canSetMappedAtIterator(), canSetMapped);
+
+ // Apparently implementations can choose to provide "better" iterators than required by the std.
+ if (hasBidirectionalIterator)
+ QCOMPARE(metaAssociation.hasBidirectionalIterator(), hasBidirectionalIterator);
+ if (hasRandomAccessIterator)
+ QCOMPARE(metaAssociation.hasRandomAccessIterator(), hasRandomAccessIterator);
+
+ QVariant key1(keyType);
+ QVariant key2(keyType);
+ QVariant key3(keyType);
+
+ QVariant mapped1(mappedType);
+ QVariant mapped2(mappedType);
+ QVariant mapped3(mappedType);
+
+ if (hasSize) {
+ const qsizetype size = metaAssociation.size(container);
+
+ QVERIFY(metaAssociation.canInsertKey());
+
+ // var1 is invalid, and our containers do not contain an invalid key so far.
+ metaAssociation.insertKey(container, key1.constData());
+ QCOMPARE(metaAssociation.size(container), size + 1);
+ metaAssociation.removeKey(container, key1.constData());
+ QCOMPARE(metaAssociation.size(container), size);
+ } else {
+ metaAssociation.insertKey(container, key1.constData());
+ metaAssociation.removeKey(container, key1.constData());
+ }
+
+ QVERIFY(metaAssociation.hasIterator());
+ QVERIFY(metaAssociation.hasConstIterator());
+ QVERIFY(metaAssociation.canGetKeyAtIterator());
+ QVERIFY(metaAssociation.canGetKeyAtConstIterator());
+
+ void *it = metaAssociation.begin(container);
+ void *end = metaAssociation.end(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ void *constIt = metaAssociation.constBegin(container);
+ void *constEnd = metaAssociation.constEnd(container);
+ QVERIFY(constIt);
+ QVERIFY(constEnd);
+
+ const qsizetype size = metaAssociation.diffIterator(end, it);
+ QCOMPARE(size, metaAssociation.diffConstIterator(constEnd, constIt));
+ if (hasSize)
+ QCOMPARE(size, metaAssociation.size(container));
+
+ qsizetype count = 0;
+ for (; !metaAssociation.compareIterator(it, end);
+ metaAssociation.advanceIterator(it, 1), metaAssociation.advanceConstIterator(constIt, 1)) {
+ metaAssociation.keyAtIterator(it, key1.data());
+ metaAssociation.keyAtConstIterator(constIt, key3.data());
+ QCOMPARE(key3, key1);
+ ++count;
+ }
+
+ QCOMPARE(count, size);
+ QVERIFY(metaAssociation.compareConstIterator(constIt, constEnd));
+
+ metaAssociation.destroyIterator(it);
+ metaAssociation.destroyIterator(end);
+ metaAssociation.destroyConstIterator(constIt);
+ metaAssociation.destroyConstIterator(constEnd);
+
+ if (metaAssociation.canSetMappedAtIterator()) {
+ void *it = metaAssociation.begin(container);
+ void *end = metaAssociation.end(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ for (; !metaAssociation.compareIterator(it, end); metaAssociation.advanceIterator(it, 1)) {
+ metaAssociation.mappedAtIterator(it, mapped1.data());
+ metaAssociation.setMappedAtIterator(it, mapped2.constData());
+ metaAssociation.mappedAtIterator(it, mapped3.data());
+ QCOMPARE(mapped2, mapped3);
+ mapped2 = mapped1;
+ }
+
+ metaAssociation.destroyIterator(it);
+ metaAssociation.destroyIterator(end);
+
+ it = metaAssociation.constBegin(container);
+ end = metaAssociation.constEnd(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ for (; !metaAssociation.compareConstIterator(it, end); metaAssociation.advanceConstIterator(it, 1)) {
+ metaAssociation.mappedAtConstIterator(it, mapped1.data());
+ metaAssociation.keyAtConstIterator(it, key1.data());
+ metaAssociation.setMappedAtKey(container, key1.constData(), mapped2.constData());
+ metaAssociation.mappedAtConstIterator(it, mapped3.data());
+ QCOMPARE(mapped2, mapped3);
+ mapped2 = mapped1;
+ }
+
+ metaAssociation.destroyConstIterator(it);
+ metaAssociation.destroyConstIterator(end);
+ }
+
+ if (metaAssociation.hasBidirectionalIterator()) {
+ void *it = metaAssociation.end(container);
+ void *end = metaAssociation.begin(container);
+ QVERIFY(it);
+ QVERIFY(end);
+
+ void *constIt = metaAssociation.constEnd(container);
+ void *constEnd = metaAssociation.constBegin(container);
+ QVERIFY(constIt);
+ QVERIFY(constEnd);
+
+ qsizetype size = 0;
+ if (metaAssociation.hasRandomAccessIterator()) {
+ size = metaAssociation.diffIterator(end, it);
+ QCOMPARE(size, metaAssociation.diffConstIterator(constEnd, constIt));
+ } else {
+ size = -metaAssociation.diffIterator(it, end);
+ }
+
+ if (hasSize)
+ QCOMPARE(size, -metaAssociation.size(container));
+
+ qsizetype count = 0;
+ do {
+ metaAssociation.advanceIterator(it, -1);
+ metaAssociation.advanceConstIterator(constIt, -1);
+ --count;
+
+ metaAssociation.keyAtIterator(it, key1.data());
+ metaAssociation.keyAtConstIterator(constIt, key3.data());
+ QCOMPARE(key3, key1);
+ } while (!metaAssociation.compareIterator(it, end));
+
+ QCOMPARE(count, size);
+ QVERIFY(metaAssociation.compareConstIterator(constIt, constEnd));
+
+ metaAssociation.destroyIterator(it);
+ metaAssociation.destroyIterator(end);
+ metaAssociation.destroyConstIterator(constIt);
+ metaAssociation.destroyConstIterator(constEnd);
+ }
+
+ QVERIFY(metaAssociation.canClear());
+ constIt = metaAssociation.constBegin(container);
+ constEnd = metaAssociation.constEnd(container);
+ QVERIFY(!metaAssociation.compareConstIterator(constIt, constEnd));
+ metaAssociation.destroyConstIterator(constIt);
+ metaAssociation.destroyConstIterator(constEnd);
+
+ metaAssociation.clear(container);
+ constIt = metaAssociation.constBegin(container);
+ constEnd = metaAssociation.constEnd(container);
+ QVERIFY(metaAssociation.compareConstIterator(constIt, constEnd));
+ metaAssociation.destroyConstIterator(constIt);
+ metaAssociation.destroyConstIterator(constEnd);
+
+ QVERIFY(metaAssociation.iface() != nullptr);
+ QMetaAssociation defaultConstructed;
+ QVERIFY(defaultConstructed.iface() == nullptr);
+ QT_TEST_EQUALITY_OPS(QMetaAssociation(), QMetaAssociation(), true);
+ QT_TEST_EQUALITY_OPS(QMetaAssociation(), metaAssociation, false);
+}
+
+QTEST_MAIN(tst_QMetaContainer)
+#include "tst_qmetacontainer.moc"
diff --git a/tests/auto/corelib/kernel/qmetaenum/CMakeLists.txt b/tests/auto/corelib/kernel/qmetaenum/CMakeLists.txt
new file mode 100644
index 0000000000..46f3ece069
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetaenum/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmetaenum Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetaenum LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmetaenum
+ SOURCES
+ tst_qmetaenum.cpp
+)
diff --git a/tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro b/tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro
deleted file mode 100644
index 718f2b51de..0000000000
--- a/tests/auto/corelib/kernel/qmetaenum/qmetaenum.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmetaenum
-QT = core testlib
-SOURCES = tst_qmetaenum.cpp
diff --git a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp
index 6ed0a6caa9..3d958a78fe 100644
--- a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp
+++ b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <QtCore/qobject.h>
#include <QtCore/qmetaobject.h>
@@ -98,6 +73,9 @@ void tst_QMetaEnum::valuesToKeys()
QMetaEnum me = QMetaEnum::fromType<Qt::WindowFlags>();
QCOMPARE(me.valueToKeys(windowFlags), expected);
+ bool ok = false;
+ QCOMPARE(uint(me.keysToValue(expected, &ok)), windowFlags.toInt());
+ QVERIFY(ok);
}
void tst_QMetaEnum::defaultConstructed()
@@ -109,13 +87,13 @@ void tst_QMetaEnum::defaultConstructed()
QCOMPARE(e.name(), QByteArray());
}
-Q_STATIC_ASSERT(QtPrivate::IsQEnumHelper<tst_QMetaEnum::SuperEnum>::Value);
-Q_STATIC_ASSERT(QtPrivate::IsQEnumHelper<Qt::WindowFlags>::Value);
-Q_STATIC_ASSERT(QtPrivate::IsQEnumHelper<Qt::Orientation>::Value);
-Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper<int>::Value);
-Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper<QObject>::Value);
-Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper<QObject*>::Value);
-Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper<void>::Value);
+static_assert(QtPrivate::IsQEnumHelper<tst_QMetaEnum::SuperEnum>::Value);
+static_assert(QtPrivate::IsQEnumHelper<Qt::WindowFlags>::Value);
+static_assert(QtPrivate::IsQEnumHelper<Qt::Orientation>::Value);
+static_assert(!QtPrivate::IsQEnumHelper<int>::Value);
+static_assert(!QtPrivate::IsQEnumHelper<QObject>::Value);
+static_assert(!QtPrivate::IsQEnumHelper<QObject*>::Value);
+static_assert(!QtPrivate::IsQEnumHelper<void>::Value);
QTEST_MAIN(tst_QMetaEnum)
#include "tst_qmetaenum.moc"
diff --git a/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt b/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt
new file mode 100644
index 0000000000..0d46aef8bd
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmetamethod Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetamethod LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmetamethod
+ SOURCES
+ tst_qmetamethod.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro b/tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro
deleted file mode 100644
index 9dfa29b0fc..0000000000
--- a/tests/auto/corelib/kernel/qmetamethod/qmetamethod.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmetamethod
-QT = core testlib
-SOURCES = tst_qmetamethod.cpp
diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
index 4584b6ce31..59fb747524 100644
--- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
+++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp
@@ -1,34 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QTypeRevision>
#include <qobject.h>
#include <qmetaobject.h>
@@ -38,6 +15,7 @@ class tst_QMetaMethod : public QObject
Q_OBJECT
private slots:
+ void compareCompiles();
void method_data();
void method();
@@ -46,8 +24,20 @@ private slots:
void comparisonOperators();
void fromSignal();
+ void fromSignalOfNullSignalIsInvalid();
void gadget();
+ void revision();
+
+ void returnMetaType();
+ void parameterMetaType();
+
+ void parameterTypeName();
+
+ void isConst();
+
+ void methodIndexes_data();
+ void methodIndexes();
};
struct CustomType { };
@@ -75,7 +65,7 @@ public:
uchar ucharArg, float floatArg);
Q_INVOKABLE MethodTestObject(bool, int);
- Q_INVOKABLE void voidInvokable();
+ Q_INVOKABLE void voidInvokable() const;
Q_INVOKABLE void voidInvokableInt(int voidInvokableIntArg);
Q_INVOKABLE void voidInvokableQReal(qreal voidInvokableQRealArg);
Q_INVOKABLE void voidInvokableQString(const QString &voidInvokableQStringArg);
@@ -136,7 +126,7 @@ MethodTestObject::MethodTestObject(bool, int, uint, qlonglong, qulonglong,
uchar, float) {}
MethodTestObject::MethodTestObject(bool, int) {}
-void MethodTestObject::voidInvokable() {}
+void MethodTestObject::voidInvokable() const {}
void MethodTestObject::voidInvokableInt(int) {}
void MethodTestObject::voidInvokableQReal(qreal) {}
void MethodTestObject::voidInvokableQString(const QString &) {}
@@ -178,6 +168,11 @@ QVariant MethodTestObject::qvariantSlotBoolIntUIntLonglongULonglongDoubleLongSho
}
void MethodTestObject::voidSlotNoParameterNames(bool, int) {}
+void tst_QMetaMethod::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QMetaMethod>();
+}
+
void tst_QMetaMethod::method_data()
{
QTest::addColumn<QByteArray>("signature");
@@ -378,10 +373,11 @@ void tst_QMetaMethod::method_data()
<< QMetaMethod::Public
<< QMetaMethod::Constructor;
+ // since Qt 6.0, parameter types get automatically registered
QTest::newRow("voidSignalCustomUnregisteredType")
<< QByteArray("voidSignalCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void")
- << (QList<int>() << 0)
+ << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSignalCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@@ -390,7 +386,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidInvokableCustomUnregisteredType")
<< QByteArray("voidInvokableCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void")
- << (QList<int>() << 0)
+ << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidInvokableCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@@ -399,7 +395,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("voidSlotCustomUnregisteredType")
<< QByteArray("voidSlotCustomUnregisteredType(CustomUnregisteredType)")
<< int(QMetaType::Void) << QByteArray("void")
- << (QList<int>() << 0)
+ << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("voidSlotCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@@ -408,7 +404,7 @@ void tst_QMetaMethod::method_data()
QTest::newRow("MethodTestObject(CustomUnregisteredType)")
<< QByteArray("MethodTestObject(CustomUnregisteredType)")
<< int(QMetaType::UnknownType) << QByteArray("")
- << (QList<int>() << 0)
+ << (QList<int>() << QMetaType::fromType<CustomUnregisteredType>().id())
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
<< (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
<< QMetaMethod::Public
@@ -624,7 +620,13 @@ void tst_QMetaMethod::method()
QVERIFY(method.typeName() != 0);
if (QByteArray(method.typeName()) != returnTypeName) {
// QMetaMethod should always produce a semantically equivalent typename
- QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName));
+ QCOMPARE(QMetaType::fromName(method.typeName()), QMetaType::fromName(returnTypeName));
+ }
+
+ // check that parameterNames and parameterTypeName agree
+ const auto methodParmaterTypes = method.parameterTypes();
+ for (int i = 0; i< methodParmaterTypes.size(); ++i) {
+ QCOMPARE(methodParmaterTypes[i], method.parameterTypeName(i));
}
if (method.parameterTypes() != parameterTypeNames) {
@@ -632,8 +634,8 @@ void tst_QMetaMethod::method()
QList<QByteArray> actualTypeNames = method.parameterTypes();
QCOMPARE(actualTypeNames.size(), parameterTypeNames.size());
for (int i = 0; i < parameterTypeNames.size(); ++i) {
- QCOMPARE(QMetaType::type(actualTypeNames.at(i)),
- QMetaType::type(parameterTypeNames.at(i)));
+ QCOMPARE(QMetaType::fromName(actualTypeNames.at(i)),
+ QMetaType::fromName(parameterTypeNames.at(i)));
}
}
QCOMPARE(method.parameterNames(), parameterNames);
@@ -643,7 +645,7 @@ void tst_QMetaMethod::method()
QCOMPARE(method.parameterType(i), parameterTypes.at(i));
{
- QVector<int> actualParameterTypes(parameterTypes.size());
+ QList<int> actualParameterTypes(parameterTypes.size());
method.getParameterTypes(actualParameterTypes.data());
for (int i = 0; i < parameterTypes.size(); ++i)
QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i));
@@ -652,6 +654,8 @@ void tst_QMetaMethod::method()
// Bogus indexes
QCOMPARE(method.parameterType(-1), 0);
QCOMPARE(method.parameterType(parameterTypes.size()), 0);
+ QT_TEST_EQUALITY_OPS(method, QMetaMethod(), false);
+ QT_TEST_EQUALITY_OPS(QMetaMethod(), QMetaMethod(), true);
}
void tst_QMetaMethod::invalidMethod()
@@ -664,6 +668,9 @@ void tst_QMetaMethod::invalidMethod()
QMetaMethod method3 = staticMetaObject.method(-1);
QVERIFY(!method3.isValid());
+ QT_TEST_EQUALITY_OPS(method, method2, true);
+ QT_TEST_EQUALITY_OPS(method2, method3, true);
+ QT_TEST_EQUALITY_OPS(method, method3, true);
}
void tst_QMetaMethod::comparisonOperators()
@@ -678,16 +685,9 @@ void tst_QMetaMethod::comparisonOperators()
QMetaMethod other = x ? mo->constructor(j) : mo->method(j);
bool expectedEqual = ((methodMo == other.enclosingMetaObject())
&& (i == j));
- QCOMPARE(method == other, expectedEqual);
- QCOMPARE(method != other, !expectedEqual);
- QCOMPARE(other == method, expectedEqual);
- QCOMPARE(other != method, !expectedEqual);
+ QT_TEST_EQUALITY_OPS(method, other, expectedEqual);
}
-
- QVERIFY(method != QMetaMethod());
- QVERIFY(QMetaMethod() != method);
- QVERIFY(!(method == QMetaMethod()));
- QVERIFY(!(QMetaMethod() == method));
+ QT_TEST_EQUALITY_OPS(method, QMetaMethod(), false);
}
}
@@ -696,8 +696,7 @@ void tst_QMetaMethod::comparisonOperators()
for (int i = 0; i < qMin(mo->methodCount(), mo->constructorCount()); ++i) {
QMetaMethod method = mo->method(i);
QMetaMethod constructor = mo->constructor(i);
- QVERIFY(method != constructor);
- QVERIFY(!(method == constructor));
+ QT_TEST_EQUALITY_OPS(method, constructor, false);
}
}
@@ -725,6 +724,12 @@ void tst_QMetaMethod::fromSignal()
#undef FROMSIGNAL_HELPER
}
+void tst_QMetaMethod::fromSignalOfNullSignalIsInvalid()
+{
+ constexpr decltype(&QObject::destroyed) ptr = nullptr;
+ QVERIFY(!QMetaMethod::fromSignal(ptr).isValid());
+}
+
class MyGadget {
Q_GADGET
public:
@@ -747,6 +752,7 @@ void tst_QMetaMethod::gadget()
QMetaMethod getValueMethod = MyGadget::staticMetaObject.method(idx);
QVERIFY(getValueMethod.isValid());
+ QT_TEST_EQUALITY_OPS(setValueMethod, getValueMethod, false);
{
MyGadget gadget;
QString string;
@@ -770,6 +776,143 @@ void tst_QMetaMethod::gadget()
}
}
+class MyTestClass : public QObject
+{
+ Q_OBJECT
+
+public:
+ MyTestClass() {};
+public Q_SLOTS:
+ Q_REVISION(42) MyGadget doStuff(int, float, MyGadget) {return {};}
+Q_SIGNALS:
+ QObject *mySignal();
+};
+
+void tst_QMetaMethod::revision()
+{
+ auto mo = MyTestClass::staticMetaObject;
+ const auto normalized = QMetaObject::normalizedSignature("doStuff(int, float, MyGadget)");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ QVERIFY(mm.isValid());
+ QCOMPARE(QTypeRevision::fromEncodedVersion(mm.revision()), QTypeRevision::fromMinorVersion(42));
+}
+
+void tst_QMetaMethod::returnMetaType()
+{
+ {
+ QMetaMethod mm = QMetaMethod::fromSignal(&MyTestClass::mySignal);
+ QCOMPARE(mm.returnMetaType(), QMetaType::fromType<QObject*>());
+ }
+ auto mo = MyTestClass::staticMetaObject;
+ {
+ const auto normalized = QMetaObject::normalizedSignature("doStuff(int, float, MyGadget)");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ QVERIFY(mm.isValid());
+ QCOMPARE(mm.returnMetaType(), QMetaType::fromType<MyGadget>());
+ }
+ {
+ // access of parent class meta methods works, too
+ const auto normalized = QMetaObject::normalizedSignature("deleteLater()");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ QVERIFY(mm.isValid());
+ QCOMPARE(mm.returnMetaType(), QMetaType::fromType<void>());
+ }
+}
+
+void tst_QMetaMethod::parameterMetaType()
+{
+ auto mo = MyTestClass::staticMetaObject;
+ const auto normalized = QMetaObject::normalizedSignature("doStuff(int, float, MyGadget)");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ {
+ QVERIFY(!mm.parameterMetaType(-1).isValid());
+ QVERIFY(!mm.parameterMetaType(3).isValid());
+ }
+ {
+ QCOMPARE(mm.parameterMetaType(0), QMetaType::fromType<int>());
+ QCOMPARE(mm.parameterMetaType(1), QMetaType::fromType<float>());
+ QCOMPARE(mm.parameterMetaType(2), QMetaType::fromType<MyGadget>());
+ }
+}
+
+
+void tst_QMetaMethod::parameterTypeName()
+{
+ auto mo = MyTestClass::staticMetaObject;
+ const auto normalized = QMetaObject::normalizedSignature("doStuff(int, float, MyGadget)");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ {
+ // check invalid indices
+ QVERIFY(mm.parameterTypeName(-1).isEmpty());
+ QVERIFY(mm.parameterTypeName(3).isEmpty());
+ }
+ {
+ QCOMPARE(mm.parameterTypeName(0), QByteArray("int"));
+ QCOMPARE(mm.parameterTypeName(1), QByteArray("float"));
+ QCOMPARE(mm.parameterTypeName(2), QByteArray("MyGadget"));
+ }
+}
+
+void tst_QMetaMethod::isConst()
+{
+ auto mo = MethodTestObject::staticMetaObject;
+ {
+ const auto normalized = QMetaObject::normalizedSignature("qrealInvokable()");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ QVERIFY(mm.isValid());
+ QCOMPARE(mm.isConst(), false);
+ }
+ {
+ const auto normalized = QMetaObject::normalizedSignature("voidInvokable()");
+ const int idx = mo.indexOfSlot(normalized);
+ QMetaMethod mm = mo.method(idx);
+ QVERIFY(mm.isValid());
+ QCOMPARE(mm.isConst(), true);
+ }
+}
+
+void tst_QMetaMethod::methodIndexes_data()
+{
+ QTest::addColumn<QByteArray>("signature");
+ QTest::addColumn<QMetaMethod::MethodType>("methodType");
+
+ QTest::newRow("constructor1") << QByteArray("MethodTestObject()") << QMetaMethod::Constructor;
+ QTest::newRow("constructor5") << QByteArray("MethodTestObject(CustomUnregisteredType)")
+ << QMetaMethod::Constructor;
+ QTest::newRow("method0") << QByteArray("voidInvokable()") << QMetaMethod::Method;
+ QTest::newRow("method6") << QByteArray("boolInvokable()") << QMetaMethod::Method;
+}
+
+void tst_QMetaMethod::methodIndexes()
+{
+ QFETCH(QByteArray, signature);
+ QFETCH(QMetaMethod::MethodType, methodType);
+
+ const bool isConstructor = methodType == QMetaMethod::Constructor;
+
+ // roundtrip: index = QMetaObject::indexOfConstructor/Method()
+ // <-> method = QMetaObject::constructor/method()
+ // <-> indexThatShouldBeEqualToAboveIndex = QMetaMethod::methodIndex()
+
+ const QMetaObject *mo = &MethodTestObject::staticMetaObject;
+ const int index =
+ isConstructor ? mo->indexOfConstructor(signature) : mo->indexOfMethod(signature);
+ QVERIFY(index != -1);
+
+ QMetaMethod methodFromMetaObject =
+ mo->method(index); // should work on all methods (constructors, signals, ...)
+ const int absoluteMethodIndex =
+ methodFromMetaObject
+ .methodIndex(); // should work on all methods (constructors, signals, ...)
+
+ QCOMPARE(absoluteMethodIndex, index);
+}
QTEST_MAIN(tst_QMetaMethod)
#include "tst_qmetamethod.moc"
diff --git a/tests/auto/corelib/kernel/qmetaobject/CMakeLists.txt b/tests/auto/corelib/kernel/qmetaobject/CMakeLists.txt
new file mode 100644
index 0000000000..d17773ada6
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetaobject/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetaobject LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+set(tst_qmetaobject_SOURCES
+ tst_qmetaobject.cpp
+ forwarddeclared.h
+ forwarddeclared.cpp
+)
+
+
+#####################################################################
+## tst_qmetaobject Test:
+#####################################################################
+
+qt_internal_add_test(tst_qmetaobject
+ SOURCES
+ ${tst_qmetaobject_SOURCES}
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+qt_internal_add_test(tst_qmetaobject_compat
+ SOURCES
+ ${tst_qmetaobject_SOURCES}
+ DEFINES
+ USE_COMPAT_Q_ARG=1
+ LIBRARIES
+ Qt::CorePrivate
+ NO_BATCH
+)
diff --git a/tests/auto/corelib/kernel/qmetaobject/forwarddeclared.cpp b/tests/auto/corelib/kernel/qmetaobject/forwarddeclared.cpp
new file mode 100644
index 0000000000..c736a63227
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetaobject/forwarddeclared.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "forwarddeclared.h"
+
+struct MyForwardDeclaredType { };
+static MyForwardDeclaredType t;
+
+const MyForwardDeclaredType &getForwardDeclaredType() noexcept
+{
+ return t;
+}
+
+MyForwardDeclaredType *getForwardDeclaredPointer() noexcept
+{
+ return &t;
+}
diff --git a/tests/auto/corelib/kernel/qmetaobject/forwarddeclared.h b/tests/auto/corelib/kernel/qmetaobject/forwarddeclared.h
new file mode 100644
index 0000000000..a0158f19cd
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetaobject/forwarddeclared.h
@@ -0,0 +1,12 @@
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef FORWARDDECLARED_H
+#define FORWARDDECLARED_H
+
+struct MyForwardDeclaredType; // and ONLY forward-declared
+
+const MyForwardDeclaredType &getForwardDeclaredType() noexcept;
+MyForwardDeclaredType *getForwardDeclaredPointer() noexcept;
+
+#endif // FORWARDDECLARED_H
diff --git a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
deleted file mode 100644
index 980c247ab5..0000000000
--- a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-qtConfig(c++14): CONFIG += c++14
-TARGET = tst_qmetaobject
-QT = core-private testlib
-SOURCES = tst_qmetaobject.cpp
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index ac0731b883..ee13c32353 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QSortFilterProxyModel>
#include <qobject.h>
#include <qmetaobject.h>
@@ -35,6 +12,27 @@
Q_DECLARE_METATYPE(const QMetaObject *)
+#include "forwarddeclared.h"
+
+#ifdef USE_COMPAT_Q_ARG
+# define tst_QMetaObject tst_QMetaObject_CompatQArg
+# if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
+# error "This is a Qt 6 compatibility check test"
+# endif
+
+# undef Q_ARG
+# undef Q_RETURN_ARG
+# define Q_ARG(type, data) QArgument<type >(#type, data)
+# define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data)
+# define Q_NO_ARG , QGenericArgument()
+#else
+// This macro is used to force the overload selection to the compat
+// (non-variadic) code above
+# define Q_NO_ARG
+#endif
+
+using namespace Qt::StringLiterals;
+
struct MyStruct
{
int i;
@@ -90,7 +88,7 @@ namespace MyNamespace {
MyFlags myFlags() const { return m_flags; }
void setMyFlags(MyFlags val) { m_flags = val; }
- MyClass(QObject *parent = 0)
+ MyClass(QObject *parent = nullptr)
: QObject(parent),
m_enum(MyEnum1),
m_flags(MyFlag1|MyFlag2)
@@ -139,7 +137,7 @@ namespace MyNamespace {
MyFlags myFlags() const { return m_flags; }
void setMyFlags(MyFlags val) { m_flags = val; }
- MyClass2(QObject *parent = 0)
+ MyClass2(QObject *parent = nullptr)
: QObject(parent),
m_enum(MyEnum1),
m_flags(MyFlag1|MyFlag2)
@@ -238,8 +236,7 @@ namespace MyNamespace {
int m_value2 = 0;
int m_value3 = 0;
};
-}
-
+} // namespace MyNamespace
class tst_QMetaObject : public QObject
{
@@ -288,39 +285,53 @@ public:
QList<QVariant> value4;
QVariantList value5;
+ tst_QMetaObject();
+
private slots:
void connectSlotsByName();
void invokeMetaMember();
+ void invokeMetaMemberNoMacros();
void invokePointer();
void invokeQueuedMetaMember();
+ void invokeQueuedMetaMemberNoMacro();
void invokeQueuedPointer();
void invokeBlockingQueuedMetaMember();
+ void invokeBlockingQueuedMetaMemberNoMacros();
void invokeBlockingQueuedPointer();
void invokeCustomTypes();
void invokeMetaConstructor();
+ void invokeMetaConstructorNoMacro();
void invokeTypedefTypes();
void invokeException();
void invokeQueuedAutoRegister();
+ void invokeFreeFunction();
+ void invokeBind();
void qtMetaObjectInheritance();
void normalizedSignature_data();
void normalizedSignature();
void normalizedType_data();
void normalizedType();
void customPropertyType();
- void checkScope_data();
- void checkScope();
+ void keysToValue_data();
+ void keysToValue(); // Also keyToValue()
void propertyNotify();
void propertyConstant();
void propertyFinal();
+ void metaType();
+
void stdSet();
void classInfo();
void metaMethod();
+ void metaMethodNoMacro();
void indexOfMethod_data();
void indexOfMethod();
+ void firstMethod_data();
+ void firstMethod();
+
void indexOfMethodPMF();
void signalOffset_data();
@@ -331,6 +342,7 @@ private slots:
void signal();
void signalIndex_data();
void signalIndex();
+ void enumDebugStream_data();
void enumDebugStream();
void inherits_data();
@@ -418,6 +430,11 @@ private slots:
#define FUNCTION(x) "QMetaObject::" x ": "
+tst_QMetaObject::tst_QMetaObject()
+{
+ qRegisterMetaType<qlonglong *>();
+}
+
void tst_QMetaObject::connectSlotsByName()
{
CTestObject obj;
@@ -452,8 +469,6 @@ void tst_QMetaObject::connectSlotsByName()
QCOMPARE(obj2.invokeCount2, 1);
}
-struct MyUnregisteredType { };
-
static int countedStructObjectsCount = 0;
struct CountedStruct
{
@@ -476,6 +491,8 @@ public:
QtTestObject();
QtTestObject(const QString &s) : slotResult(s) {}
Q_INVOKABLE QtTestObject(QObject *parent);
+ Q_INVOKABLE QtTestObject(QObject *parent, int, int);
+ Q_INVOKABLE QtTestObject(QObject *parent, int);
public slots:
void sl0();
@@ -496,16 +513,24 @@ public slots:
const char *sl12();
QList<QString> sl13(QList<QString> l1);
qint64 sl14();
- void testSender();
+ qlonglong *sl15(qlonglong *);
+ MyForwardDeclaredType *sl16(MyForwardDeclaredType *);
- void testReference(QString &str);
+ void sl17(int *i) { *i = 242; }
+
+ void overloadedSlot();
+ void overloadedSlot(int, int);
+ void overloadedSlot(int);
+ void testSender();
+ void testReference(QString &str);
void testLongLong(qint64 ll1, quint64 ll2);
void moveToThread(QThread *t)
{ QObject::moveToThread(t); }
- void slotWithUnregisteredParameterType(MyUnregisteredType);
+ void slotWithUnregisteredParameterType(const MyForwardDeclaredType &);
+ void slotWithOneUnregisteredParameterType(QString a1, const MyForwardDeclaredType &a2);
CountedStruct throwingSlot(const CountedStruct &, CountedStruct s2) {
#ifndef QT_NO_EXCEPTIONS
@@ -516,10 +541,10 @@ public slots:
void slotWithRegistrableArgument(QtTestObject *o1, QPointer<QtTestObject> o2,
QSharedPointer<QtTestObject> o3, QWeakPointer<QtTestObject> o4,
- QVector<QtTestObject *> o5, QList<QtTestObject *> o6)
+ QList<QtTestObject *> o5, QList<QtTestObject *> o6)
{
slotResult = QLatin1String("slotWithRegistrableArgument:") + o1->slotResult + o2->slotResult
- + o3->slotResult + o4.data()->slotResult + QString::number(o5.size())
+ + o3->slotResult + o4.toStrongRef()->slotResult + QString::number(o5.size())
+ QString::number(o6.size());
}
@@ -556,6 +581,14 @@ QtTestObject::QtTestObject(QObject *parent)
{
}
+QtTestObject::QtTestObject(QObject *parent, int, int)
+ : QObject(parent)
+{ slotResult = "ii"; }
+
+QtTestObject::QtTestObject(QObject *parent, int)
+ : QObject(parent)
+{ slotResult = "i"; }
+
void QtTestObject::sl0() { slotResult = "sl0"; };
QString QtTestObject::sl1(QString s1) { slotResult = "sl1:" + s1; return "yessir"; }
void QtTestObject::sl2(QString s1, QString s2) { slotResult = "sl2:" + s1 + s2; }
@@ -588,6 +621,27 @@ QList<QString> QtTestObject::sl13(QList<QString> l1)
{ slotResult = "sl13"; return l1; }
qint64 QtTestObject::sl14()
{ slotResult = "sl14"; return Q_INT64_C(123456789)*123456789; }
+qlonglong *QtTestObject::sl15(qlonglong *ptr)
+{ slotResult = "sl15"; return ptr; }
+MyForwardDeclaredType *QtTestObject::sl16(MyForwardDeclaredType *ptr)
+{
+ slotResult = "sl16:";
+ if (ptr) {
+ slotResult += "notnull";
+ return nullptr;
+ }
+ slotResult += "null";
+ return getForwardDeclaredPointer();
+}
+
+void QtTestObject::overloadedSlot()
+{ slotResult = "overloadedSlot"; }
+
+void QtTestObject::overloadedSlot(int x, int y)
+{ slotResult = "overloadedSlot:" + QString::number(x) + ',' + QString::number(y); }
+
+void QtTestObject::overloadedSlot(int x)
+{ slotResult = "overloadedSlot:" + QString::number(x); }
void QtTestObject::testReference(QString &str)
{ slotResult = "testReference:" + str; str = "gotcha"; }
@@ -600,9 +654,12 @@ void QtTestObject::testSender()
slotResult = QString::asprintf("%p", sender());
}
-void QtTestObject::slotWithUnregisteredParameterType(MyUnregisteredType)
+void QtTestObject::slotWithUnregisteredParameterType(const MyForwardDeclaredType &)
{ slotResult = "slotWithUnregisteredReturnType"; }
+void QtTestObject::slotWithOneUnregisteredParameterType(QString a1, const MyForwardDeclaredType &)
+{ slotResult = "slotWithUnregisteredReturnType-" + a1; }
+
void QtTestObject::staticFunction0()
{
staticResult = "staticFunction0";
@@ -611,6 +668,7 @@ void QtTestObject::staticFunction0()
qint64 QtTestObject::staticFunction1()
{ staticResult = "staticFunction1"; return Q_INT64_C(123456789)*123456789; }
+// this test is duplicated below
void tst_QMetaObject::invokeMetaMember()
{
QtTestObject obj;
@@ -621,17 +679,17 @@ void tst_QMetaObject::invokeMetaMember()
// Test nullptr
char *nullCharArray = nullptr;
const char *nullConstCharArray = nullptr;
- QVERIFY(!QMetaObject::invokeMethod(nullptr, nullCharArray));
- QVERIFY(!QMetaObject::invokeMethod(nullptr, nullConstCharArray));
- QVERIFY(!QMetaObject::invokeMethod(nullptr, "sl0"));
- QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray));
- QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray));
- QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray, Qt::AutoConnection));
- QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray, Qt::AutoConnection));
+ QVERIFY(!QMetaObject::invokeMethod(nullptr, nullCharArray Q_NO_ARG));
+ QVERIFY(!QMetaObject::invokeMethod(nullptr, nullConstCharArray Q_NO_ARG));
+ QVERIFY(!QMetaObject::invokeMethod(nullptr, "sl0" Q_NO_ARG));
+ QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray Q_NO_ARG));
+ QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray Q_NO_ARG));
+ QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray, Qt::AutoConnection Q_NO_ARG));
+ QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray, Qt::AutoConnection Q_NO_ARG));
QVERIFY(!QMetaObject::invokeMethod(&obj, nullCharArray, Qt::AutoConnection, QGenericReturnArgument()));
QVERIFY(!QMetaObject::invokeMethod(&obj, nullConstCharArray, Qt::AutoConnection, QGenericReturnArgument()));
- QVERIFY(QMetaObject::invokeMethod(&obj, "sl0"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl0" Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("sl0"));
QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(QString, t1)));
@@ -670,16 +728,23 @@ void tst_QMetaObject::invokeMetaMember()
Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9)));
QCOMPARE(obj.slotResult, QString("sl9:123456789"));
- QVERIFY(QMetaObject::invokeMethod(&obj, "sl11"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11" Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("sl11"));
- QVERIFY(QMetaObject::invokeMethod(&obj, "testSender"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "testSender" Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("0x0"));
QString refStr("whatever");
+#ifdef USE_COMPAT_Q_ARG
QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", QGenericArgument("QString&", &refStr)));
QCOMPARE(obj.slotResult, QString("testReference:whatever"));
QCOMPARE(refStr, QString("gotcha"));
+ obj.slotResult.clear();
+#endif
+ refStr = "whatever";
+ QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", Q_ARG(QString&, refStr)));
+ QCOMPARE(obj.slotResult, QString("testReference:whatever"));
+ QCOMPARE(refStr, QString("gotcha"));
qint64 ll1 = -1;
quint64 ll2 = 0;
@@ -694,24 +759,24 @@ void tst_QMetaObject::invokeMetaMember()
QCOMPARE(exp, QString("yessir"));
QCOMPARE(obj.slotResult, QString("sl1:bubu"));
- QObject *ptr = 0;
+ QObject *ptr = nullptr;
QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Q_RETURN_ARG(QObject*,ptr)));
QCOMPARE(ptr, (QObject *)&obj);
QCOMPARE(obj.slotResult, QString("sl11"));
// try again with a space:
- ptr = 0;
+ ptr = nullptr;
QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Q_RETURN_ARG(QObject * , ptr)));
QCOMPARE(ptr, (QObject *)&obj);
QCOMPARE(obj.slotResult, QString("sl11"));
- const char *ptr2 = 0;
+ const char *ptr2 = nullptr;
QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Q_RETURN_ARG(const char*, ptr2)));
- QVERIFY(ptr2 != 0);
+ QVERIFY(ptr2 != nullptr);
QCOMPARE(obj.slotResult, QString("sl12"));
// try again with a space:
- ptr2 = 0;
+ ptr2 = nullptr;
QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Q_RETURN_ARG(char const * , ptr2)));
- QVERIFY(ptr2 != 0);
+ QVERIFY(ptr2 != nullptr);
QCOMPARE(obj.slotResult, QString("sl12"));
// test w/ template args
@@ -730,8 +795,37 @@ void tst_QMetaObject::invokeMetaMember()
QCOMPARE(return64, Q_INT64_C(123456789)*123456789);
QCOMPARE(obj.slotResult, QString("sl14"));
+ // pointers
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Q_ARG(qlonglong*, &return64)));
+ QCOMPARE(obj.slotResult, QString("sl15"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Q_ARG(MyForwardDeclaredType*, getForwardDeclaredPointer())));
+ QCOMPARE(obj.slotResult, QString("sl16:notnull"));
+
+ obj.slotResult.clear();
+ qint64 *return64Ptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Q_RETURN_ARG(qlonglong*, return64Ptr), Q_ARG(qlonglong*, &return64)));
+ QCOMPARE(return64Ptr, &return64);
+ QCOMPARE(obj.slotResult, QString("sl15"));
+
+ obj.slotResult.clear();
+ MyForwardDeclaredType *forwardPtr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Q_RETURN_ARG(MyForwardDeclaredType*, forwardPtr),
+ Q_ARG(MyForwardDeclaredType*, nullptr)));
+ QCOMPARE(forwardPtr, getForwardDeclaredPointer());
+ QCOMPARE(obj.slotResult, QString("sl16:null"));
+
+#ifndef QT_NO_DATA_RELOCATION // this doesn't work with the new API on Windows
+#endif
+ // test overloads
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot" Q_NO_ARG));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Q_ARG(int, 1)));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Q_ARG(int, 1), Q_ARG(int, 42)));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1,42"));
+
//test signals
- QVERIFY(QMetaObject::invokeMethod(&obj, "sig0"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig0" Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("sl0"));
QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Q_ARG(QString, "baba")));
@@ -752,6 +846,175 @@ void tst_QMetaObject::invokeMetaMember()
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n"
"Candidates are:\n sl1(QString)");
QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(QString, "arg"), Q_ARG(QString, "arg"), Q_ARG(QString, "arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::testReference(QString)\n"
+ "Candidates are:\n testReference(QString&)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", Q_ARG(QString, exp)));
+
+ //should not have changed since last test.
+ QCOMPARE(exp, QString("yessir"));
+ QCOMPARE(obj.slotResult, QString("sl1:hehe"));
+}
+
+// this is a copy-paste-adapt of the above
+void tst_QMetaObject::invokeMetaMemberNoMacros()
+{
+ QtTestObject obj;
+
+ QString t1("1"); QString t2("2"); QString t3("3"); QString t4("4"); QString t5("5");
+ QString t6("6"); QString t7("7"); QString t8("8"); QString t9("9"); QString t10("X");
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl0"));
+ QCOMPARE(obj.slotResult, QString("sl0"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", t1));
+ QCOMPARE(obj.slotResult, QString("sl1:1"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl2", std::as_const(t1), t2));
+ QCOMPARE(obj.slotResult, QString("sl2:12"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl3", t1, t2, t3));
+ QCOMPARE(obj.slotResult, QString("sl3:123"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl4", t1, t2, t3,
+ t4));
+ QCOMPARE(obj.slotResult, QString("sl4:1234"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl5", t1, t2, t3,
+ t4, QStringLiteral("5")));
+ QCOMPARE(obj.slotResult, QString("sl5:12345"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl6", t1, t2, t3,
+ t4, t5, t6));
+ QCOMPARE(obj.slotResult, QString("sl6:123456"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl7", t1, t2, t3,
+ t4, t5, t6,
+ t7));
+ QCOMPARE(obj.slotResult, QString("sl7:1234567"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl8", t1, t2, t3,
+ t4, t5, t6,
+ t7, t8));
+ QCOMPARE(obj.slotResult, QString("sl8:12345678"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", t1, t2, t3,
+ t4, t5, t6,
+ t7, t8, t9));
+ QCOMPARE(obj.slotResult, QString("sl9:123456789"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11"));
+ QCOMPARE(obj.slotResult, QString("sl11"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "testSender"));
+ QCOMPARE(obj.slotResult, QString("0x0"));
+
+ // this is not working for now
+// QString refStr("whatever");
+// QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", refStr));
+// QCOMPARE(obj.slotResult, QString("testReference:whatever"));
+// QCOMPARE(refStr, QString("gotcha"));
+
+ qint64 ll1 = -1;
+ quint64 ll2 = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj,
+ "testLongLong",
+ ll1,
+ ll2));
+ QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
+
+ QString exp;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", qReturnArg(exp), QStringLiteral("bubu")));
+ QCOMPARE(exp, QString("yessir"));
+ QCOMPARE(obj.slotResult, QString("sl1:bubu"));
+
+ QObject *ptr = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", qReturnArg(ptr)));
+ QCOMPARE(ptr, (QObject *)&obj);
+ QCOMPARE(obj.slotResult, QString("sl11"));
+ // try again with a space:
+ ptr = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", qReturnArg(ptr)));
+ QCOMPARE(ptr, (QObject *)&obj);
+ QCOMPARE(obj.slotResult, QString("sl11"));
+
+ const char *ptr2 = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", qReturnArg(ptr2)));
+ QVERIFY(ptr2 != nullptr);
+ QCOMPARE(obj.slotResult, QString("sl12"));
+ // try again with a space:
+ ptr2 = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", qReturnArg(ptr2)));
+ QVERIFY(ptr2 != nullptr);
+ QCOMPARE(obj.slotResult, QString("sl12"));
+
+ // test w/ template args
+ QList<QString> returnValue, argument;
+ argument << QString("one") << QString("two") << QString("three");
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl13",
+ qReturnArg(returnValue),
+ argument));
+ QCOMPARE(returnValue, argument);
+ QCOMPARE(obj.slotResult, QString("sl13"));
+
+ // return qint64
+ qint64 return64;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl14",
+ qReturnArg(return64)));
+ QCOMPARE(return64, Q_INT64_C(123456789)*123456789);
+ QCOMPARE(obj.slotResult, QString("sl14"));
+
+ // pointers
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", &return64));
+ QCOMPARE(obj.slotResult, QString("sl15"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", getForwardDeclaredPointer()));
+ QCOMPARE(obj.slotResult, QString("sl16:notnull"));
+
+ obj.slotResult.clear();
+ qint64 *return64Ptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", qReturnArg(return64Ptr), &return64));
+ QCOMPARE(return64Ptr, &return64);
+ QCOMPARE(obj.slotResult, QString("sl15"));
+
+ obj.slotResult.clear();
+ MyForwardDeclaredType *forwardPtr = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", qReturnArg(forwardPtr),
+ forwardPtr));
+ QCOMPARE(forwardPtr, getForwardDeclaredPointer());
+ QCOMPARE(obj.slotResult, QString("sl16:null"));
+
+ // test overloads
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot"));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", 1));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", 1, 42));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1,42"));
+
+ //test signals
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig0"));
+ QCOMPARE(obj.slotResult, QString("sl0"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", QStringLiteral("baba")));
+ QCOMPARE(obj.slotResult, QString("sl1:baba"));
+
+ exp.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", qReturnArg(exp), QStringLiteral("hehe")));
+ QCOMPARE(exp, QString("yessir"));
+ QCOMPARE(obj.slotResult, QString("sl1:hehe"));
+
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist"));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", QStringLiteral("arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n"
+ "Candidates are:\n sl3(QString,QString,QString)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", QStringLiteral("arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n"
+ "Candidates are:\n sl1(QString)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", QStringLiteral("arg"), QStringLiteral("arg"), QStringLiteral("arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::testReference(QString)\n"
+ "Candidates are:\n testReference(QString&)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", exp));
//should not have changed since last test.
QCOMPARE(exp, QString("yessir"));
@@ -815,7 +1078,6 @@ void tst_QMetaObject::invokePointer()
QCOMPARE(obj.slotResult, QString("sl1:bubu"));
}
QCOMPARE(countedStructObjectsCount, 0);
-#ifdef __cpp_init_captures
{
CountedStruct str;
std::unique_ptr<int> ptr( new int );
@@ -823,14 +1085,123 @@ void tst_QMetaObject::invokePointer()
QCOMPARE(obj.slotResult, QString("sl1:1"));
}
QCOMPARE(countedStructObjectsCount, 0);
-#endif
+
+ // Invoking with parameters
+ QString result;
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl1, qReturnArg(result), u"bubu"_s));
+ QCOMPARE(obj.slotResult, u"sl1:bubu");
+ QCOMPARE(result, u"yessir");
+
+ // without taking return value
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl1, u"bubu"_s));
+ QCOMPARE(obj.slotResult, u"sl1:bubu");
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl1, Qt::DirectConnection, qReturnArg(result),
+ u"byebye"_s));
+ QCOMPARE(obj.slotResult, u"sl1:byebye");
+ QCOMPARE(result, u"yessir");
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, qOverload<int, int>(&QtTestObject::overloadedSlot), 1, 2));
+ QCOMPARE(obj.slotResult, u"overloadedSlot:1,2");
+
+ // non-const ref parameter
+ QString original = u"bubu"_s;
+ QString &ref = original;
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl1, qReturnArg(result), ref));
+ QCOMPARE(obj.slotResult, u"sl1:bubu");
+ QCOMPARE(result, u"yessir");
+
+ struct R {
+ bool operator()(int) { return true; }
+ int operator()(char) { return 15; }
+ int operator()(QString = {}, int = {}, int = {}) { return 242; }
+ } r;
+
+ // Test figuring out which operator() to call:
+ {
+ bool res = false;
+ QVERIFY(QMetaObject::invokeMethod(&obj, r, qReturnArg(res), 1));
+ QCOMPARE(res, true);
+ }
+ {
+ int res;
+ QVERIFY(QMetaObject::invokeMethod(&obj, r, qReturnArg(res), 'c'));
+ QCOMPARE(res, 15);
+ }
+ {
+ int res;
+ QVERIFY(QMetaObject::invokeMethod(&obj, r, qReturnArg(res)));
+ QCOMPARE(res, 242);
+ res = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, r, qReturnArg(res), u"bu"_s));
+ QCOMPARE(res, 242);
+ res = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, r, qReturnArg(res), u"bu"_s, 1));
+ QCOMPARE(res, 242);
+ res = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, r, qReturnArg(res), u"bu"_s, 1, 2));
+ QCOMPARE(res, 242);
+ }
+
+ {
+ auto lambda = [](const QString &s) { return s + s; };
+ QVERIFY(QMetaObject::invokeMethod(&obj, lambda, qReturnArg(result), u"bu"_s));
+ QCOMPARE(result, u"bubu");
+ }
+
+ {
+ auto lambda = [](const QString &s = u"bu"_s) { return s + s; };
+ QVERIFY(QMetaObject::invokeMethod(&obj, lambda, qReturnArg(result)));
+ QCOMPARE(result, u"bubu");
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, lambda, qReturnArg(result), u"bye"_s));
+ QCOMPARE(result, u"byebye");
+ }
+
+ {
+ auto lambda = [](const QString &s, qint64 a, qint16 b, qint8 c) {
+ return s + QString::number(a) + QString::number(b) + QString::number(c);
+ };
+ // Testing mismatching argument (int for qint64). The other arguments
+ // would static_assert for potential truncation if they were ints.
+ QVERIFY(QMetaObject::invokeMethod(&obj, lambda, qReturnArg(result), u"bu"_s, 1, qint16(2), qint8(3)));
+ QCOMPARE(result, u"bu123");
+ }
+ {
+ // Testing deduction
+ auto lambda = [](const QString &s, auto a) { return s + a; };
+ QVERIFY(QMetaObject::invokeMethod(&obj, lambda, qReturnArg(result), u"bu"_s, "bu"_L1));
+ QCOMPARE(result, u"bubu");
+
+ auto variadic = [](const QString &s, auto... a) { return s + (QString::number(a) + ...); };
+ QVERIFY(QMetaObject::invokeMethod(&obj, variadic, qReturnArg(result), u"bu"_s, 1, 2, 3, 4, 5, 6));
+ QCOMPARE(result, u"bu123456");
+ }
+ {
+ // Testing a functor returning void and accepting a pointer,
+ // this may trigger the pointer to be interpreted as the old void*
+ // return parameter.
+ bool invoked = false;
+ auto lambda = [&invoked](void *ptr) -> void {
+ Q_UNUSED(ptr);
+ invoked = true;
+ };
+ int i = 242;
+ QVERIFY(QMetaObject::invokeMethod(&obj, lambda, &i));
+ QVERIFY(invoked);
+
+ // member fn
+ i = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl17, &i));
+ QCOMPARE(i, 242);
+ }
}
void tst_QMetaObject::invokeQueuedMetaMember()
{
QtTestObject obj;
- QVERIFY(QMetaObject::invokeMethod(&obj, "sl0", Qt::QueuedConnection));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl0", Qt::QueuedConnection Q_NO_ARG));
QVERIFY(obj.slotResult.isEmpty());
qApp->processEvents(QEventLoop::AllEvents);
QCOMPARE(obj.slotResult, QString("sl0"));
@@ -850,10 +1221,36 @@ void tst_QMetaObject::invokeQueuedMetaMember()
qApp->processEvents(QEventLoop::AllEvents);
QCOMPARE(obj.slotResult, QString("sl9:123456789"));
+ // pointers
+ qint64 return64;
+ obj.slotResult.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Qt::QueuedConnection, Q_ARG(qlonglong*, &return64)));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl15"));
+
+ // since Qt 6.5, this works even for pointers to forward-declared types
+ obj.slotResult.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Qt::QueuedConnection, Q_ARG(MyForwardDeclaredType*, getForwardDeclaredPointer())));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl16:notnull"));
+
+#ifndef QT_NO_DATA_RELOCATION // this doesn't work with the new API on Windows
+#endif
+ // test overloads
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::QueuedConnection Q_NO_ARG));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("overloadedSlot"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::QueuedConnection, Q_ARG(int, 1)));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::QueuedConnection, Q_ARG(int, 1), Q_ARG(int, 42)));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1,42"));
+
// signals
obj.slotResult.clear();
- QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::QueuedConnection));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::QueuedConnection Q_NO_ARG));
QVERIFY(obj.slotResult.isEmpty());
qApp->processEvents(QEventLoop::AllEvents);
QCOMPARE(obj.slotResult, QString("sl0"));
@@ -877,13 +1274,142 @@ void tst_QMetaObject::invokeQueuedMetaMember()
qApp->processEvents(QEventLoop::AllEvents);
QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::testReference(QString)\n"
+ "Candidates are:\n testReference(QString&)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", Qt::QueuedConnection, Q_ARG(QString, exp)));
+
+ QString refStr = "whatever";
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'QString&'");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", Qt::QueuedConnection, Q_ARG(QString&, refStr)));
+ QCOMPARE(refStr, "whatever");
+
+#ifdef USE_COMPAT_Q_ARG // this doesn't compile with the new API
+ obj.slotResult.clear();
+ {
+ const MyForwardDeclaredType &t = getForwardDeclaredType();
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyForwardDeclaredType'");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithUnregisteredParameterType", Qt::QueuedConnection, Q_ARG(MyForwardDeclaredType, t)));
+ QVERIFY(obj.slotResult.isEmpty());
+ }
+
+ obj.slotResult.clear();
+ {
+ QString a1("Cannot happen");
+ const MyForwardDeclaredType &t = getForwardDeclaredType();
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyForwardDeclaredType'");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithOneUnregisteredParameterType", Qt::QueuedConnection,
+ Q_ARG(QString, a1), Q_ARG(MyForwardDeclaredType, t)));
+ QVERIFY(obj.slotResult.isEmpty());
+ }
+#endif
+}
+
+// this is a copy-paste-adapt of the above
+void tst_QMetaObject::invokeQueuedMetaMemberNoMacro()
+{
+ QtTestObject obj;
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl0", Qt::QueuedConnection));
+ QVERIFY(obj.slotResult.isEmpty());
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl0"));
+ obj.slotResult = QString();
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::QueuedConnection, QString("hallo")));
+ QVERIFY(obj.slotResult.isEmpty());
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl1:hallo"));
+ obj.slotResult = QString();
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", Qt::QueuedConnection, QStringLiteral("1"), QStringLiteral("2"),
+ QStringLiteral("3"), QStringLiteral("4"), QStringLiteral("5"),
+ QStringLiteral("6"), QStringLiteral("7"), QStringLiteral("8"),
+ QStringLiteral("9")));
+ QVERIFY(obj.slotResult.isEmpty());
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl9:123456789"));
+
+ // pointers
+ qint64 return64;
+ obj.slotResult.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Qt::QueuedConnection, &return64));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl15"));
+
+ obj.slotResult.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Qt::QueuedConnection, getForwardDeclaredPointer()));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl16:notnull"));
+
+ // test overloads
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::QueuedConnection));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("overloadedSlot"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::QueuedConnection, 1));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::QueuedConnection, 1, 42));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1,42"));
+
+ // signals
+
+ obj.slotResult.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::QueuedConnection));
+ QVERIFY(obj.slotResult.isEmpty());
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl0"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::QueuedConnection, QStringLiteral("gogo")));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("sl1:gogo"));
+
+ QString exp;
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to invoke methods with return values in queued connections");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sig1", Qt::QueuedConnection, qReturnArg(exp),
+ QStringLiteral("nono")));
+
+ qint64 ll1 = -1;
+ quint64 ll2 = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj,
+ "testLongLong",
+ Qt::QueuedConnection,
+ ll1,
+ ll2));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
+
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::testReference(QString)\n"
+ "Candidates are:\n testReference(QString&)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", exp));
+ QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
+ QVERIFY(exp.isEmpty());
+
+ // this doesn't work yet
+// QString refStr = "whatever";
+// QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'QString&'");
+// QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", Qt::QueuedConnection, Q_ARG(QString&, refStr)));
+// QCOMPARE(refStr, "whatever");
+
+#if 0 // this won't even compile any more
obj.slotResult.clear();
{
- MyUnregisteredType t;
- QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyUnregisteredType'");
- QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithUnregisteredParameterType", Qt::QueuedConnection, Q_ARG(MyUnregisteredType, t)));
+ const MyForwardDeclaredType &t = getForwardDeclaredType();
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyForwardDeclaredType'");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithUnregisteredParameterType", Qt::QueuedConnection, t));
QVERIFY(obj.slotResult.isEmpty());
}
+
+ obj.slotResult.clear();
+ {
+ QString a1("Cannot happen");
+ const MyForwardDeclaredType &t = getForwardDeclaredType();
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: Unable to handle unregistered datatype 'MyForwardDeclaredType'");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "slotWithOneUnregisteredParameterType", Qt::QueuedConnection,
+ a1, t));
+ QVERIFY(obj.slotResult.isEmpty());
+ }
+#endif
}
void tst_QMetaObject::invokeQueuedPointer()
@@ -933,9 +1459,15 @@ void tst_QMetaObject::invokeQueuedPointer()
QCOMPARE(var, 0);
}
QCOMPARE(countedStructObjectsCount, 0);
-}
+ // Invoking with parameters
+ using namespace Qt::StringLiterals;
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl1, Qt::QueuedConnection, u"bubu"_s));
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult, u"sl1:bubu");
+}
+// this test is duplicated below
void tst_QMetaObject::invokeBlockingQueuedMetaMember()
{
QThread t;
@@ -982,16 +1514,23 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
Q_ARG(QString, t7), Q_ARG(QString, t8), Q_ARG(QString, t9)));
QCOMPARE(obj.slotResult, QString("sl9:123456789"));
- QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("sl11"));
- QVERIFY(QMetaObject::invokeMethod(&obj, "testSender", Qt::BlockingQueuedConnection));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "testSender", Qt::BlockingQueuedConnection Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("0x0"));
QString refStr("whatever");
+#ifdef USE_COMPAT_Q_ARG
QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, QGenericArgument("QString&", &refStr)));
QCOMPARE(obj.slotResult, QString("testReference:whatever"));
QCOMPARE(refStr, QString("gotcha"));
+ obj.slotResult.clear();
+#endif
+ refStr = "whatever";
+ QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, Q_ARG(QString&, refStr)));
+ QCOMPARE(obj.slotResult, QString("testReference:whatever"));
+ QCOMPARE(refStr, QString("gotcha"));
qint64 ll1 = -1;
quint64 ll2 = 0;
@@ -1007,12 +1546,12 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
QCOMPARE(exp, QString("yessir"));
QCOMPARE(obj.slotResult, QString("sl1:bubu"));
- QObject *ptr = 0;
+ QObject *ptr = nullptr;
QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject*,ptr)));
QCOMPARE(ptr, (QObject *)&obj);
QCOMPARE(obj.slotResult, QString("sl11"));
// try again with a space:
- ptr = 0;
+ ptr = nullptr;
QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QObject * , ptr)));
QCOMPARE(ptr, (QObject *)&obj);
QCOMPARE(obj.slotResult, QString("sl11"));
@@ -1036,8 +1575,44 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
QCOMPARE(returnValue, argument);
QCOMPARE(obj.slotResult, QString("sl13"));
+ // return qint64
+ qint64 return64;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl14", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(qint64, return64)));
+ QCOMPARE(return64, Q_INT64_C(123456789)*123456789);
+ QCOMPARE(obj.slotResult, QString("sl14"));
+
+ // pointers
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Qt::BlockingQueuedConnection, Q_ARG(qlonglong*, &return64)));
+ QCOMPARE(obj.slotResult, QString("sl15"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Qt::BlockingQueuedConnection, Q_ARG(MyForwardDeclaredType*, getForwardDeclaredPointer())));
+ QCOMPARE(obj.slotResult, QString("sl16:notnull"));
+
+ obj.slotResult.clear();
+ qint64 *return64Ptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Qt::BlockingQueuedConnection, Q_RETURN_ARG(qlonglong*, return64Ptr), Q_ARG(qlonglong*, &return64)));
+ QCOMPARE(return64Ptr, &return64);
+ QCOMPARE(obj.slotResult, QString("sl15"));
+
+ obj.slotResult.clear();
+ MyForwardDeclaredType *forwardPtr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Qt::BlockingQueuedConnection, Q_RETURN_ARG(MyForwardDeclaredType*, forwardPtr),
+ Q_ARG(MyForwardDeclaredType*, nullptr)));
+ QCOMPARE(forwardPtr, getForwardDeclaredPointer());
+ QCOMPARE(obj.slotResult, QString("sl16:null"));
+
+#ifndef QT_NO_DATA_RELOCATION // this doesn't work with the new API on Windows
+#endif
+ // test overloads
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::BlockingQueuedConnection Q_NO_ARG));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, 1)));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, 1), Q_ARG(int, 42)));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1,42"));
+
//test signals
- QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::BlockingQueuedConnection));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::BlockingQueuedConnection Q_NO_ARG));
QCOMPARE(obj.slotResult, QString("sl0"));
QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, Q_ARG(QString, "baba")));
@@ -1049,7 +1624,7 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
QCOMPARE(obj.slotResult, QString("sl1:hehe"));
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()");
- QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist", Qt::BlockingQueuedConnection));
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist", Qt::BlockingQueuedConnection Q_NO_ARG));
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)");
QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg")));
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n"
@@ -1058,6 +1633,9 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n"
"Candidates are:\n sl1(QString)");
QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, Q_ARG(QString, "arg"), Q_ARG(QString, "arg"), Q_ARG(QString, "arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::testReference(QString)\n"
+ "Candidates are:\n testReference(QString&)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, Q_ARG(QString, exp)));
//should not have changed since last test.
QCOMPARE(exp, QString("yessir"));
@@ -1066,7 +1644,177 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
QVERIFY(QMetaObject::invokeMethod(&obj, "moveToThread", Qt::BlockingQueuedConnection, Q_ARG(QThread*, QThread::currentThread())));
t.quit();
QVERIFY(t.wait());
+}
+
+// this is a copy-paste-adapt of the above
+void tst_QMetaObject::invokeBlockingQueuedMetaMemberNoMacros()
+{
+ QThread t;
+ t.start();
+ QtTestObject obj;
+ obj.moveToThread(&t);
+
+ QString t1("1"); QString t2("2"); QString t3("3"); QString t4("4"); QString t5("5");
+ QString t6("6"); QString t7("7"); QString t8("8"); QString t9("9"); QString t10("X");
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, t1));
+ QCOMPARE(obj.slotResult, QString("sl1:1"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl2", Qt::BlockingQueuedConnection, t1, t2));
+ QCOMPARE(obj.slotResult, QString("sl2:12"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, t1, t2, t3));
+ QCOMPARE(obj.slotResult, QString("sl3:123"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl4", Qt::BlockingQueuedConnection, t1, t2,
+ t3, t4));
+ QCOMPARE(obj.slotResult, QString("sl4:1234"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl5", Qt::BlockingQueuedConnection, t1, t2,
+ t3, t4, QStringLiteral("5")));
+ QCOMPARE(obj.slotResult, QString("sl5:12345"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl6", Qt::BlockingQueuedConnection, t1, t2,
+ t3, t4, t5, t6));
+ QCOMPARE(obj.slotResult, QString("sl6:123456"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl7", Qt::BlockingQueuedConnection, t1, t2,
+ t3, t4, t5, t6,
+ t7));
+ QCOMPARE(obj.slotResult, QString("sl7:1234567"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl8", Qt::BlockingQueuedConnection, t1, t2,
+ t3, t4, t5, t6,
+ t7, t8));
+ QCOMPARE(obj.slotResult, QString("sl8:12345678"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl9", Qt::BlockingQueuedConnection, t1, t2,
+ t3, t4, t5, t6,
+ t7, t8, t9));
+ QCOMPARE(obj.slotResult, QString("sl9:123456789"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection));
+ QCOMPARE(obj.slotResult, QString("sl11"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "testSender", Qt::BlockingQueuedConnection));
+ QCOMPARE(obj.slotResult, QString("0x0"));
+
+ // this is not working
+// QString refStr("whatever");
+// QVERIFY(QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, refStr));
+// QCOMPARE(obj.slotResult, QString("testReference:whatever"));
+// QCOMPARE(refStr, QString("gotcha"));
+
+ qint64 ll1 = -1;
+ quint64 ll2 = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj,
+ "testLongLong",
+ Qt::BlockingQueuedConnection,
+ ll1,
+ ll2));
+ QCOMPARE(obj.slotResult, QString("testLongLong:-1,0"));
+
+ QString exp;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, qReturnArg(exp), QStringLiteral("bubu")));
+ QCOMPARE(exp, QString("yessir"));
+ QCOMPARE(obj.slotResult, QString("sl1:bubu"));
+
+ QObject *ptr = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, qReturnArg(ptr)));
+ QCOMPARE(ptr, (QObject *)&obj);
+ QCOMPARE(obj.slotResult, QString("sl11"));
+ // try again with a space:
+ ptr = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl11", Qt::BlockingQueuedConnection, qReturnArg(ptr)));
+ QCOMPARE(ptr, (QObject *)&obj);
+ QCOMPARE(obj.slotResult, QString("sl11"));
+
+ const char *ptr2 = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Qt::BlockingQueuedConnection, qReturnArg(ptr2)));
+ QVERIFY(ptr2 != 0);
+ QCOMPARE(obj.slotResult, QString("sl12"));
+ // try again with a space:
+ ptr2 = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl12", Qt::BlockingQueuedConnection, qReturnArg(ptr2)));
+ QVERIFY(ptr2 != 0);
+ QCOMPARE(obj.slotResult, QString("sl12"));
+
+ // test w/ template args
+ QList<QString> returnValue, argument;
+ argument << QString("one") << QString("two") << QString("three");
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl13", Qt::BlockingQueuedConnection,
+ qReturnArg(returnValue),
+ argument));
+ QCOMPARE(returnValue, argument);
+ QCOMPARE(obj.slotResult, QString("sl13"));
+
+ // return qint64
+ qint64 return64;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl14", Qt::BlockingQueuedConnection,
+ qReturnArg(return64)));
+ QCOMPARE(return64, Q_INT64_C(123456789)*123456789);
+ QCOMPARE(obj.slotResult, QString("sl14"));
+
+ // pointers
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Qt::BlockingQueuedConnection, &return64));
+ QCOMPARE(obj.slotResult, QString("sl15"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Qt::BlockingQueuedConnection, getForwardDeclaredPointer()));
+ QCOMPARE(obj.slotResult, QString("sl16:notnull"));
+ obj.slotResult.clear();
+ qint64 *return64Ptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl15", Qt::BlockingQueuedConnection, qReturnArg(return64Ptr), &return64));
+ QCOMPARE(return64Ptr, &return64);
+ QCOMPARE(obj.slotResult, QString("sl15"));
+
+ obj.slotResult.clear();
+ MyForwardDeclaredType *forwardPtr = nullptr;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl16", Qt::BlockingQueuedConnection, qReturnArg(forwardPtr),
+ forwardPtr));
+ QCOMPARE(forwardPtr, getForwardDeclaredPointer());
+ QCOMPARE(obj.slotResult, QString("sl16:null"));
+
+ // test overloads
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::BlockingQueuedConnection));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::BlockingQueuedConnection, 1));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1"));
+ QVERIFY(QMetaObject::invokeMethod(&obj, "overloadedSlot", Qt::BlockingQueuedConnection, 1, 42));
+ QCOMPARE(obj.slotResult, QString("overloadedSlot:1,42"));
+
+ //test signals
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig0", Qt::BlockingQueuedConnection));
+ QCOMPARE(obj.slotResult, QString("sl0"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, QStringLiteral("baba")));
+ QCOMPARE(obj.slotResult, QString("sl1:baba"));
+
+ exp.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Qt::BlockingQueuedConnection, qReturnArg(exp), QStringLiteral("hehe")));
+ QCOMPARE(exp, QString("yessir"));
+ QCOMPARE(obj.slotResult, QString("sl1:hehe"));
+
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist", Qt::BlockingQueuedConnection));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", Qt::BlockingQueuedConnection, QStringLiteral("arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)\n"
+ "Candidates are:\n sl3(QString,QString,QString)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", Qt::BlockingQueuedConnection, QStringLiteral("arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)\n"
+ "Candidates are:\n sl1(QString)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Qt::BlockingQueuedConnection, QStringLiteral("arg"), QStringLiteral("arg"), QStringLiteral("arg")));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::testReference(QString)\n"
+ "Candidates are:\n testReference(QString&)");
+ QVERIFY(!QMetaObject::invokeMethod(&obj, "testReference", Qt::BlockingQueuedConnection, exp));
+
+ //should not have changed since last test.
+ QCOMPARE(exp, QString("yessir"));
+ QCOMPARE(obj.slotResult, QString("sl1:hehe"));
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, "moveToThread", Qt::BlockingQueuedConnection, QThread::currentThread()));
+ t.quit();
+ QVERIFY(t.wait());
}
void tst_QMetaObject::invokeBlockingQueuedPointer()
@@ -1129,7 +1877,6 @@ void tst_QMetaObject::invokeBlockingQueuedPointer()
QCOMPARE(exp, QString("yessir"));
QCOMPARE(obj.slotResult, QString("sl1:bubu"));
}
-#ifdef __cpp_init_captures
{
std::unique_ptr<int> ptr(new int);
QVERIFY(QMetaObject::invokeMethod(&obj,
@@ -1137,7 +1884,18 @@ void tst_QMetaObject::invokeBlockingQueuedPointer()
Qt::BlockingQueuedConnection));
QCOMPARE(obj.slotResult, QString("sl1:hehe"));
}
-#endif
+
+ // Test with parameters
+ QString result;
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl1, Qt::BlockingQueuedConnection,
+ qReturnArg(result), u"bubu"_s));
+ QCOMPARE(result, u"yessir");
+ QCOMPARE(obj.slotResult, u"sl1:bubu");
+
+ QVERIFY(QMetaObject::invokeMethod(&obj, &QtTestObject::sl2, Qt::BlockingQueuedConnection,
+ u"bubu"_s, u"baba"_s));
+ QCOMPARE(obj.slotResult, u"sl2:bububaba");
+
QVERIFY(QMetaObject::invokeMethod(&obj, [&](){obj.moveToThread(QThread::currentThread());}, Qt::BlockingQueuedConnection));
t.quit();
QVERIFY(t.wait());
@@ -1194,6 +1952,10 @@ void tst_QMetaObject::invokeCustomTypes()
QCOMPARE(obj.sum, 0);
QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(MyType, tp)));
QCOMPARE(obj.sum, 3);
+
+ obj.sum = 0;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sl1", tp));
+ QCOMPARE(obj.sum, 3);
}
namespace NamespaceWithConstructibleClass
@@ -1203,19 +1965,22 @@ class ConstructibleClass : public QObject
{
Q_OBJECT
public:
- Q_INVOKABLE ConstructibleClass(QObject *parent = 0)
+ Q_INVOKABLE ConstructibleClass(QObject *parent = nullptr)
: QObject(parent) {}
};
}
+// this test is duplicated below
void tst_QMetaObject::invokeMetaConstructor()
{
const QMetaObject *mo = &QtTestObject::staticMetaObject;
+#ifdef USE_COMPAT_Q_ARG
{
- QObject *obj = mo->newInstance();
+ QObject *obj = mo->newInstance(QGenericArgument());
QVERIFY(!obj);
}
+#endif
{
QtTestObject obj;
QObject *obj2 = mo->newInstance(Q_ARG(QObject*, &obj));
@@ -1238,6 +2003,56 @@ void tst_QMetaObject::invokeMetaConstructor()
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::newInstance: type MyGadget does not inherit QObject");
QVERIFY(!MyGadget::staticMetaObject.newInstance());
}
+
+ // overloaded constructors
+ QObject parent;
+ {
+ QObject *obj = mo->newInstance(Q_ARG(QObject*, &parent));
+ QVERIFY(obj);
+ QCOMPARE(static_cast<QtTestObject*>(obj)->slotResult, "");
+ }
+ {
+ QObject *obj = mo->newInstance(Q_ARG(QObject*, &parent), Q_ARG(int, 1));
+ QVERIFY(obj);
+ QCOMPARE(static_cast<QtTestObject*>(obj)->slotResult, "i");
+ }
+ {
+ QObject *obj = mo->newInstance(Q_ARG(QObject*, &parent), Q_ARG(int, 1), Q_ARG(int, 42));
+ QVERIFY(obj);
+ QCOMPARE(static_cast<QtTestObject*>(obj)->slotResult, "ii");
+ }
+}
+
+// this is a copy-paste-adapt of the above
+void tst_QMetaObject::invokeMetaConstructorNoMacro()
+{
+ const QMetaObject *mo = &QtTestObject::staticMetaObject;
+ {
+ QObject *obj = mo->newInstance();
+ QVERIFY(!obj);
+ }
+ {
+ QtTestObject obj;
+ QObject *obj2 = mo->newInstance(static_cast<QObject *>(&obj));
+ QVERIFY(obj2 != 0);
+ QCOMPARE(obj2->parent(), (QObject*)&obj);
+ QVERIFY(qobject_cast<QtTestObject*>(obj2) != 0);
+ }
+ // class in namespace
+ const QMetaObject *nsmo = &NamespaceWithConstructibleClass::ConstructibleClass::staticMetaObject;
+ {
+ QtTestObject obj;
+ QObject *obj2 = nsmo->newInstance(static_cast<QObject *>(&obj));
+ QVERIFY(obj2 != 0);
+ QCOMPARE(obj2->parent(), (QObject*)&obj);
+ QVERIFY(qobject_cast<NamespaceWithConstructibleClass::ConstructibleClass*>(obj2) != 0);
+ }
+ // gadget shouldn't return a valid pointer
+ {
+ QCOMPARE(MyGadget::staticMetaObject.constructorCount(), 1);
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::newInstance: type MyGadget does not inherit QObject");
+ QVERIFY(!MyGadget::staticMetaObject.newInstance());
+ }
}
void tst_QMetaObject::invokeTypedefTypes()
@@ -1247,11 +2062,17 @@ void tst_QMetaObject::invokeTypedefTypes()
QSignalSpy spy(&obj, &QtTestCustomObject::sig_custom);
QVERIFY(spy.isValid());
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
CustomString arg("hello");
QVERIFY(QMetaObject::invokeMethod(&obj, "sig_custom", Q_ARG(CustomString, arg)));
- QCOMPARE(spy.count(), 1);
- QCOMPARE(spy.at(0).count(), 1);
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(spy.at(0).size(), 1);
+ QCOMPARE(spy.at(0).at(0), QVariant(arg));
+
+ spy.clear();
+ QVERIFY(QMetaObject::invokeMethod(&obj, "sig_custom", arg));
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(spy.at(0).size(), 1);
QCOMPARE(spy.at(0).at(0), QVariant(arg));
}
@@ -1267,6 +2088,14 @@ void tst_QMetaObject::invokeException()
QFAIL("Did not throw");
} catch(ObjectException &) {}
QCOMPARE(countedStructObjectsCount, 0);
+
+ try {
+ CountedStruct s;
+ QVERIFY(QMetaObject::invokeMethod(&obj, "throwingSlot", qReturnArg(s),
+ s, s));
+ QFAIL("Did not throw");
+ } catch(ObjectException &) {}
+ QCOMPARE(countedStructObjectsCount, 0);
#else
QSKIP("Needs exceptions");
#endif
@@ -1282,12 +2111,67 @@ void tst_QMetaObject::invokeQueuedAutoRegister()
&obj, "slotWithRegistrableArgument", Qt::QueuedConnection,
Q_ARG(QtTestObject *, shared.data()), Q_ARG(QPointer<QtTestObject>, shared.data()),
Q_ARG(QSharedPointer<QtTestObject>, shared), Q_ARG(QWeakPointer<QtTestObject>, shared),
- Q_ARG(QVector<QtTestObject *>, QVector<QtTestObject *>()),
+ Q_ARG(QList<QtTestObject *>, QList<QtTestObject *>()),
Q_ARG(QList<QtTestObject *>, QList<QtTestObject *>())));
QVERIFY(obj.slotResult.isEmpty());
qApp->processEvents(QEventLoop::AllEvents);
QCOMPARE(obj.slotResult,
QString("slotWithRegistrableArgument:myShared-myShared-myShared-myShared-00"));
+
+ obj.slotResult.clear();
+ QVERIFY(QMetaObject::invokeMethod(
+ &obj, "slotWithRegistrableArgument", Qt::QueuedConnection,
+ shared.data(), QPointer<QtTestObject>(shared.data()),
+ QSharedPointer<QtTestObject>(shared), QWeakPointer<QtTestObject>(shared),
+ QList<QtTestObject *>(),
+ QList<QtTestObject *>()));
+ QVERIFY(obj.slotResult.isEmpty());
+ qApp->processEvents(QEventLoop::AllEvents);
+ QCOMPARE(obj.slotResult,
+ QString("slotWithRegistrableArgument:myShared-myShared-myShared-myShared-00"));
+}
+
+namespace FunctionTest {
+ static void function0() {}
+ static int functionNoExcept() noexcept
+ {
+ return 42;
+ }
+}
+
+void tst_QMetaObject::invokeFreeFunction()
+{
+ using namespace FunctionTest;
+ QtTestObject obj;
+ QMetaObject::invokeMethod(&obj, function0);
+ int retInt = -1;
+ QMetaObject::invokeMethod(&obj, functionNoExcept, &retInt);
+ QCOMPARE(retInt, functionNoExcept());
+}
+
+void tst_QMetaObject::invokeBind()
+{
+ QtTestObject obj;
+
+ struct {
+ int number;
+ QString string;
+ } results;
+
+ const auto function = [&results](int number, const QString &string) -> bool {
+ results.number = number;
+ results.string = string;
+ return true;
+ };
+
+ const int number = 42;
+ const QString string("Test");
+ const auto binding = std::bind(function, number, string);
+ bool ret = false;
+ QMetaObject::invokeMethod(&obj, binding, &ret);
+ QVERIFY(ret);
+ QCOMPARE(results.number, number);
+ QCOMPARE(results.string, string);
}
void tst_QMetaObject::normalizedSignature_data()
@@ -1317,7 +2201,7 @@ void tst_QMetaObject::normalizedSignature_data()
QTest::newRow("const ref") << "const QString &foo()" << "const QString&foo()";
QTest::newRow("reference") << "QString &foo()" << "QString&foo()";
QTest::newRow("const1") << "void foo(QString const *)" << "void foo(const QString*)";
- QTest::newRow("const2") << "void foo(QString * const)" << "void foo(QString*const)";
+ QTest::newRow("const2") << "void foo(QString * const)" << "void foo(QString*)";
QTest::newRow("const3") << "void foo(QString const &)" << "void foo(QString)";
QTest::newRow("const4") << "void foo(const int)" << "void foo(int)";
QTest::newRow("const5") << "void foo(const int, int const, const int &, int const &)"
@@ -1327,10 +2211,16 @@ void tst_QMetaObject::normalizedSignature_data()
QTest::newRow("const8") << "void foo(QList<int const*>)" << "void foo(QList<const int*>)";
QTest::newRow("const9") << "void foo(const Foo<Bar>)" << "void foo(Foo<Bar>)";
QTest::newRow("const10") << "void foo(Foo<Bar>const)" << "void foo(Foo<Bar>)";
- QTest::newRow("const11") << "void foo(Foo<Bar> *const)" << "void foo(Foo<Bar>*const)";
- QTest::newRow("const12") << "void foo(Foo<Bar>const*const *const)" << "void foo(Foo<Bar>*const*const)";
+ QTest::newRow("const11") << "void foo(Foo<Bar> *const)" << "void foo(Foo<Bar>*)";
+ QTest::newRow("const12") << "void foo(Foo<Bar>const*const *const)" << "void foo(const Foo<Bar>*const*)";
QTest::newRow("const13") << "void foo(const Foo<Bar>&)" << "void foo(Foo<Bar>)";
QTest::newRow("const14") << "void foo(Foo<Bar>const&)" << "void foo(Foo<Bar>)";
+ QTest::newRow("QVector") << "void foo(QVector<int>)" << "void foo(QList<int>)";
+ QTest::newRow("QVector1") << "void foo(const Template<QVector, MyQList const>)"
+ << "void foo(Template<QList,const MyQList>)";
+
+ QTest::newRow("refref") << "const char* foo(const X &&,X const &&, const X* &&) && "
+ << "const char*foo(const X&&,const X&&,const X*&&)&&";
QTest::newRow("invalid1") << "a( b" << "a(b";
}
@@ -1356,22 +2246,61 @@ void tst_QMetaObject::normalizedType_data()
QTest::newRow("template2") << "QList<const int *>" << "QList<const int*>";
QTest::newRow("template3") << "QMap<QString, int>" << "QMap<QString,int>";
QTest::newRow("template4") << "const QMap<QString, int> &" << "QMap<QString,int>";
- QTest::newRow("template5") << "QList< ::Foo::Bar>" << "QList< ::Foo::Bar>";
+ QTest::newRow("template5") << "QList< ::Foo::Bar>" << "QList<::Foo::Bar>";
QTest::newRow("template6") << "QList<::Foo::Bar>" << "QList<::Foo::Bar>";
- QTest::newRow("template7") << "QList<QList<int> >" << "QList<QList<int> >";
+ QTest::newRow("template7") << "QList<QList<int> >" << "QList<QList<int>>";
QTest::newRow("template8") << "QMap<const int, const short*>" << "QMap<const int,const short*>";
- QTest::newRow("template9") << "QPair<const QPair<int, int const *> , QPair<QHash<int, const char*> > >" << "QPair<const QPair<int,const int*>,QPair<QHash<int,const char*> > >";
+ QTest::newRow("template9") << "QPair<const QPair<int, int const *> , QPair<QHash<int, const char*> > >"
+ << "std::pair<const std::pair<int,const int*>,std::pair<QHash<int,const char*>>>";
+ QTest::newRow("template10") << "QVector<int const * const> const" << "QList<const int*const>";
+ QTest::newRow("template11") << " QSharedPointer<QVarLengthArray< QString const, ( 16>> 2 )> > const & "
+ << "QSharedPointer<QVarLengthArray<const QString,(16>>2)>>";
+ QTest::newRow("template_sub") << "X<( Y < 8), (Y >6)> const & " << "X<(Y<8),(Y>6)>";
QTest::newRow("value1") << "const QString &" << "QString";
QTest::newRow("value2") << "QString const &" << "QString";
QTest::newRow("constInName1") << "constconst" << "constconst";
QTest::newRow("constInName2") << "constconst*" << "constconst*";
QTest::newRow("constInName3") << "const constconst&" << "constconst";
- QTest::newRow("constInName4") << "constconst const*const" << "constconst*const";
+ QTest::newRow("constInName4") << "constconst const*const" << "const constconst*";
QTest::newRow("class") << "const class foo&" << "foo";
QTest::newRow("struct") << "const struct foo*" << "const foo*";
QTest::newRow("struct2") << "struct foo const*" << "const foo*";
QTest::newRow("enum") << "enum foo" << "foo";
QTest::newRow("void") << "void" << "void";
+ QTest::newRow("QList") << "QList<int>" << "QList<int>";
+ QTest::newRow("QVector") << "QVector<int>" << "QList<int>";
+ QTest::newRow("refref") << "X const*const&&" << "const X*const&&";
+ QTest::newRow("refref2") << "const X<T const&&>&&" << "const X<const T&&>&&";
+ QTest::newRow("long1") << "long unsigned int long" << "qulonglong";
+ QTest::newRow("long2") << "int signed long" << "long";
+ QTest::newRow("long3") << "long unsigned" << "ulong";
+ QTest::newRow("long double") << " long double" << "long double";
+ QTest::newRow("signed char") << "char signed" << "signed char";
+ QTest::newRow("unsigned char") << "char unsigned" << "uchar";
+ QTest::newRow("signed short") << "short signed" << "short";
+ QTest::newRow("unsigned short") << "unsigned short" << "ushort";
+ QTest::newRow("short unsigned") << "short unsigned" << "ushort";
+ QTest::newRow("array1") << "unsigned int [4]" << "uint[4]";
+ QTest::newRow("array2") << "unsigned int const [4][5]" << "const uint[4][5]";
+ QTest::newRow("array3") << "unsigned[] const" << "uint[]";
+ QTest::newRow("nttp1") << "S<'>', int const> const"
+ << "S<'>',const int>";
+ QTest::newRow("nttp2") << "S< \"> \\\">const * \\\\\" , int const> const"
+ << "S<\"> \\\">const * \\\\\",const int>";
+ QTest::newRow("nttp3") << "S<\"Q <\" , int const> const*"
+ << "const S<\"Q <\",const int>*";
+ QTest::newRow("nttp4") << "S< 1'2 , int const> const"
+ << "S<1'2,const int>";
+ QTest::newRow("invalid") << "'const"
+ << "'const";
+ QTest::newRow("anonym1") << "XX::<unnamed struct>"
+ << "XX::<unnamed struct>";
+ QTest::newRow("anonym2") << "XX::{unnamed type#1}"
+ << "XX::{unnamed type#1}";
+ QTest::newRow("anonym3") << "struct XX::<unnamed-type-s>"
+ << "XX::<unnamed-type-s>";
+ QTest::newRow("anonym4") << "XX::(anonymous struct at ./example.cpp:10:13)"
+ << "XX::(anonymous struct at./example.cpp:10:13)";
}
void tst_QMetaObject::normalizedType()
@@ -1380,26 +2309,37 @@ void tst_QMetaObject::normalizedType()
QFETCH(QString, result);
QCOMPARE(QMetaObject::normalizedType(type.toLatin1()), result.toLatin1());
+ QCOMPARE(QMetaObject::normalizedType(result.toLatin1()), result.toLatin1());
}
void tst_QMetaObject::customPropertyType()
{
QMetaProperty prop = metaObject()->property(metaObject()->indexOfProperty("value3"));
+#if QT_DEPRECATED_SINCE(6, 0)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+
QCOMPARE(prop.type(), QVariant::UserType);
- QCOMPARE(prop.userType(), 0);
+
+ QT_WARNING_POP
+#endif
+
+ QCOMPARE(prop.userType(), QMetaType::fromType<MyStruct>().id());
+ QCOMPARE(prop.metaType(), QMetaType::fromType<MyStruct>());
qRegisterMetaType<MyStruct>("MyStruct");
- QCOMPARE(prop.userType(), QMetaType::type("MyStruct"));
+ QCOMPARE(prop.userType(), QMetaType::fromName("MyStruct").id());
prop = metaObject()->property(metaObject()->indexOfProperty("value4"));
- QCOMPARE(prop.type(), QVariant::List);
+ QCOMPARE(prop.metaType().id(), QMetaType::QVariantList);
+ QCOMPARE(prop.metaType(), QMetaType::fromType<QList<QVariant>>());
prop = metaObject()->property(metaObject()->indexOfProperty("value5"));
- QCOMPARE(prop.type(), QVariant::List);
+ QCOMPARE(prop.metaType().id(), QMetaType::QVariantList);
}
-void tst_QMetaObject::checkScope_data()
+void tst_QMetaObject::keysToValue_data()
{
QTest::addColumn<QObject *>("object");
QTest::addColumn<QByteArray>("name");
@@ -1413,7 +2353,7 @@ void tst_QMetaObject::checkScope_data()
}
-void tst_QMetaObject::checkScope()
+void tst_QMetaObject::keysToValue()
{
QFETCH(QObject *, object);
QFETCH(QByteArray, name);
@@ -1426,6 +2366,8 @@ void tst_QMetaObject::checkScope()
QVERIFY(!me.isFlag());
QCOMPARE(QByteArray(me.scope()), QByteArray("MyNamespace::" + name));
QCOMPARE(me.keyToValue("MyNamespace::" + name + "::MyEnum2", &ok), 1);
+ // Fully qualified unscoped enumerator
+ QCOMPARE(me.keyToValue("MyNamespace::" + name + "::MyEnum::MyEnum2", &ok), 1);
QCOMPARE(ok, true);
QCOMPARE(me.keyToValue(name + "::MyEnum2", &ok), -1);
QCOMPARE(ok, false);
@@ -1455,6 +2397,9 @@ void tst_QMetaObject::checkScope()
QCOMPARE(QByteArray(mf.scope()), QByteArray("MyNamespace::" + name));
QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag2", &ok), 2);
QCOMPARE(ok, true);
+ // Fully qualified
+ QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag::MyFlag2", &ok), 2);
+ QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue(name + "::MyFlag2", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(mf.keysToValue("MyNamespace::MyFlag2", &ok), -1);
@@ -1464,7 +2409,12 @@ void tst_QMetaObject::checkScope()
QCOMPARE(mf.keysToValue("MyFlag", &ok), -1);
QCOMPARE(ok, false);
QCOMPARE(QLatin1String(mf.valueToKey(2)), QLatin1String("MyFlag2"));
- QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag1|MyNamespace::" + name + "::MyFlag2", &ok), 3);
+
+ const QByteArray prefix = "MyNamespace::" + name;
+ QCOMPARE(mf.keysToValue(prefix + "::MyFlag1|" + prefix + "::MyFlag2", &ok), 3);
+ QCOMPARE(ok, true);
+ // Fully qualified
+ QCOMPARE(mf.keysToValue(prefix + "::MyFlag::MyFlag1|" + prefix + "::MyFlag::MyFlag2", &ok), 3);
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue(name + "::MyFlag1|" + name + "::MyFlag2", &ok), -1);
QCOMPARE(ok, false);
@@ -1476,9 +2426,34 @@ void tst_QMetaObject::checkScope()
QCOMPARE(ok, true);
QCOMPARE(mf.keysToValue("MyFlag1|MyNamespace::" + name + "::MyFlag2", &ok), 3);
QCOMPARE(ok, true);
- QCOMPARE(mf.keysToValue("MyNamespace::" + name + "::MyFlag2|MyNamespace::" + name + "::MyFlag2", &ok), 2);
+ QCOMPARE(mf.keysToValue(prefix + "::MyFlag2|" + prefix + "::MyFlag2", &ok), 2);
+ QCOMPARE(ok, true);
+ // Fully qualified
+ QCOMPARE(mf.keysToValue(prefix + "::MyFlag::MyFlag2|" + prefix + "::MyFlag::MyFlag2", &ok), 2);
QCOMPARE(ok, true);
QCOMPARE(QLatin1String(mf.valueToKeys(3)), QLatin1String("MyFlag1|MyFlag2"));
+
+ // Test flags with extra '|'
+ QTest::ignoreMessage(QtWarningMsg,
+ QRegularExpression(u"QMetaEnum::keysToValue: malformed keys string, ends with '|'.+"_s));
+ QCOMPARE(mf.keysToValue("MyFlag1|MyFlag2|", &ok), -1);
+ QCOMPARE(ok, false);
+
+ QTest::ignoreMessage(QtWarningMsg,
+ QRegularExpression(u"QMetaEnum::keysToValue: malformed keys string, starts with '|'.+"_s));
+ QCOMPARE(mf.keysToValue("|MyFlag1|MyFlag2|", &ok), -1);
+ QCOMPARE(ok, false);
+
+ QTest::ignoreMessage(QtWarningMsg,
+ QRegularExpression(
+ u"QMetaEnum::keysToValue: malformed keys string, has two consecutive '|'.+"_s));
+ QCOMPARE(mf.keysToValue("MyFlag1||MyFlag2", &ok), -1);
+ QCOMPARE(ok, false);
+
+ // Test empty string
+ QTest::ignoreMessage(QtWarningMsg, "QMetaEnum::keysToValue: empty keys string.");
+ QCOMPARE(mf.keysToValue("", &ok), -1);
+ QCOMPARE(ok, false);
}
void tst_QMetaObject::propertyNotify()
@@ -1536,6 +2511,15 @@ void tst_QMetaObject::propertyFinal()
QVERIFY(!prop.isFinal());
}
+void tst_QMetaObject::metaType()
+{
+ QCOMPARE(QObject::staticMetaObject.metaType(), QMetaType::fromType<QObject>());
+ QCOMPARE(MyGadget::staticMetaObject.metaType(), QMetaType::fromType<MyGadget>());
+ QCOMPARE(QAbstractProxyModel::staticMetaObject.metaType(), QMetaType::fromType<QAbstractProxyModel>());
+ auto qtNameSpaceMetaType = Qt::staticMetaObject.metaType();
+ QVERIFY2(!qtNameSpaceMetaType.isValid(), qtNameSpaceMetaType.name());
+}
+
class ClassInfoTestObjectA : public QObject
{
Q_OBJECT
@@ -1556,6 +2540,7 @@ void tst_QMetaObject::classInfo()
QCOMPARE(QLatin1String(b.metaObject()->classInfo(index).value()), QLatin1String("Christopher Pike"));
}
+// this test is duplicated below
void tst_QMetaObject::metaMethod()
{
QString str("foo");
@@ -1575,9 +2560,13 @@ void tst_QMetaObject::metaMethod()
QVERIFY(index > 0);
method = QtTestObject::staticMetaObject.method(index);
//wrong args
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: too few arguments (5) in call to QtTestObject::sl5(QString,QString,QString,QString,QString)");
QVERIFY(!method.invoke(&obj, Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4")));
//QVERIFY(!method.invoke(&obj, Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(QString, "5"), Q_ARG(QString, "6")));
//QVERIFY(!method.invoke(&obj, Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(int, 5)));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invokeMethod: return type mismatch for method "
+ "QtTestObject::sl5(QString,QString,QString,QString,QString): "
+ "cannot convert from void to QString during invocation");
QVERIFY(!method.invoke(&obj, Q_RETURN_ARG(QString, ret), Q_ARG(QString, "1"), Q_ARG(QString, "2"), Q_ARG(QString, "3"), Q_ARG(QString, "4"), Q_ARG(QString, "5")));
//wrong object
@@ -1597,13 +2586,66 @@ void tst_QMetaObject::metaMethod()
//wrong object
//QVERIFY(!sl13.invoke(this, Q_RETURN_ARG(QList<QString>, returnValue), Q_ARG(QList<QString>, argument)));
QVERIFY(!sl13.invoke(0, Q_RETURN_ARG(QList<QString>, returnValue), Q_ARG(QList<QString>, argument)));
- QCOMPARE(returnValue, QList<QString>());
+ QVERIFY(returnValue.isEmpty());
QVERIFY(sl13.invoke(&obj, Q_RETURN_ARG(QList<QString>, returnValue), Q_ARG(QList<QString>, argument)));
QCOMPARE(returnValue, argument);
QCOMPARE(obj.slotResult, QString("sl13"));
}
+// this is a copy-paste-adapt of the above
+void tst_QMetaObject::metaMethodNoMacro()
+{
+ QString str("foo");
+ QString ret("bar");
+ QMetaMethod method;
+ QVERIFY(!method.invoke(this));
+ QVERIFY(!method.invoke(this, str));
+ QVERIFY(!method.invoke(this, qReturnArg(ret), str));
+ QCOMPARE(str, QString("foo"));
+ QCOMPARE(ret, QString("bar"));
+
+ QtTestObject obj;
+ QString t1("1"); QString t2("2"); QString t3("3"); QString t4("4"); QString t5("5");
+ QString t6("6"); QString t7("7"); QString t8("8"); QString t9("9"); QString t10("X");
+
+ int index = QtTestObject::staticMetaObject.indexOfMethod("sl5(QString,QString,QString,QString,QString)");
+ QVERIFY(index > 0);
+ method = QtTestObject::staticMetaObject.method(index);
+ //wrong args
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invoke: too few arguments (5) in call to QtTestObject::sl5(QString,QString,QString,QString,QString)");
+ QVERIFY(!method.invoke(&obj, QStringLiteral("1"), QStringLiteral("2"), QStringLiteral("3"), QStringLiteral("4")));
+ //QVERIFY(!method.invoke(&obj, "1", "2", "3", "4", "5", "6"));
+ //QVERIFY(!method.invoke(&obj, "1", "2", "3", "4", 5));
+ QTest::ignoreMessage(QtWarningMsg, "QMetaMethod::invokeMethod: return type mismatch for method "
+ "QtTestObject::sl5(QString,QString,QString,QString,QString): "
+ "cannot convert from void to QString during invocation");
+ QVERIFY(!method.invoke(&obj, qReturnArg(ret), QStringLiteral("1"), QStringLiteral("2"), QStringLiteral("3"), QStringLiteral("4"), QStringLiteral("5")));
+
+ //wrong object
+ //QVERIFY(!method.invoke(this, "1", "2", "3", "4", "5"));
+ QVERIFY(!method.invoke(0, QStringLiteral("1"), QStringLiteral("2"), QStringLiteral("3"), QStringLiteral("4"), QStringLiteral("5")));
+ QCOMPARE(ret, QString("bar"));
+ QCOMPARE(obj.slotResult, QString());
+
+ QVERIFY(method.invoke(&obj, QStringLiteral("1"), QStringLiteral("2"), QStringLiteral("3"), QStringLiteral("4"), QStringLiteral("5")));
+ QCOMPARE(obj.slotResult, QString("sl5:12345"));
+
+ index = QtTestObject::staticMetaObject.indexOfMethod("sl13(QList<QString>)");
+ QVERIFY(index > 0);
+ QMetaMethod sl13 = QtTestObject::staticMetaObject.method(index);
+ QList<QString> returnValue, argument;
+ argument << QString("one") << QString("two") << QString("three");
+ //wrong object
+ //QVERIFY(!sl13.invoke(this, qReturnArg(returnValue), argument));
+ QVERIFY(!sl13.invoke(0, qReturnArg(returnValue), argument));
+ QVERIFY(returnValue.isEmpty());
+
+ QVERIFY(sl13.invoke(&obj, qReturnArg(returnValue), argument));
+ QCOMPARE(returnValue, argument);
+ QCOMPARE(obj.slotResult, QString("sl13"));
+}
+
void tst_QMetaObject::indexOfMethod_data()
{
QTest::addColumn<QObject *>("object");
@@ -1629,6 +2671,42 @@ void tst_QMetaObject::indexOfMethod()
QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx);
}
+class Base : public QObject {
+ Q_OBJECT
+public slots:
+ int test() {return 0;}
+ int baseOnly() {return 0;}
+};
+
+class Derived : public Base {
+ Q_OBJECT
+
+public slots:
+ int test() {return 1;}
+};
+
+void tst_QMetaObject::firstMethod_data()
+{
+ QTest::addColumn<QByteArray>("name");
+ QTest::addColumn<QMetaMethod>("method");
+
+ const QMetaObject &derived = Derived::staticMetaObject;
+ const QMetaObject &base = Base::staticMetaObject;
+
+ QTest::newRow("own method") << QByteArray("test") << derived.method(derived.indexOfMethod("test()"));
+ QTest::newRow("parent method") << QByteArray("baseOnly") << derived.method(base.indexOfMethod("baseOnly()"));
+ QTest::newRow("invalid") << QByteArray("invalid") << QMetaMethod();
+}
+
+void tst_QMetaObject::firstMethod()
+{
+ QFETCH(QByteArray, name);
+ QFETCH(QMetaMethod, method);
+
+ QMetaMethod firstMethod = QMetaObjectPrivate::firstMethod(&Derived::staticMetaObject, name);
+ QCOMPARE(firstMethod, method);
+}
+
void tst_QMetaObject::indexOfMethodPMF()
{
#define INDEXOFMETHODPMF_HELPER(ObjectType, Name, Arguments) { \
@@ -1772,37 +2850,104 @@ void tst_QMetaObject::signalIndex()
SignalTestHelper::signalIndex(mm));
}
+void tst_QMetaObject::enumDebugStream_data()
+{
+ QTest::addColumn<int>("verbosity");
+ QTest::addColumn<QString>("normalEnumMsg");
+ QTest::addColumn<QString>("scopedEnumMsg");
+ QTest::addColumn<QString>("globalEnumMsg");
+ QTest::addColumn<QString>("normalFlagMsg");
+ QTest::addColumn<QString>("normalFlagsMsg");
+ QTest::addColumn<QString>("scopedFlagMsg");
+ QTest::addColumn<QString>("scopedFlagsMsg");
+ QTest::addColumn<QString>("flagAsEnumMsg");
+
+ QTest::newRow("verbosity=0") << 0
+ << "hello MyEnum2 world"
+ << "hello MyScopedEnum::Enum3 scoped world"
+ << "WindowTitleHint Window Desktop WindowSystemMenuHint"
+ << "hello MyFlag1 world"
+ << "MyFlag1 MyFlag2|MyFlag3"
+ << "MyScopedFlag(MyFlag2)"
+ << "MyScopedFlag(MyFlag2|MyFlag3)"
+ << "MyFlag1";
+
+ QTest::newRow("verbosity=1") << 1
+ << "hello MyEnum::MyEnum2 world"
+ << "hello MyScopedEnum::Enum3 scoped world"
+ << "WindowType::WindowTitleHint WindowType::Window WindowType::Desktop WindowType::WindowSystemMenuHint"
+ << "hello MyFlag(MyFlag1) world"
+ << "MyFlag(MyFlag1) MyFlag(MyFlag2|MyFlag3)"
+ << "MyScopedFlag(MyFlag2)"
+ << "MyScopedFlag(MyFlag2|MyFlag3)"
+ << "MyFlag::MyFlag1";
+
+ QTest::newRow("verbosity=2") << 2
+ << "hello MyNamespace::MyClass::MyEnum2 world"
+ << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world"
+ << "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint"
+ << "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world"
+ << "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)"
+ << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)"
+ << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)"
+ << "MyNamespace::MyClass::MyFlag1";
+
+ QTest::newRow("verbosity=3") << 3
+ << "hello MyNamespace::MyClass::MyEnum::MyEnum2 world"
+ << "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world"
+ << "Qt::WindowType::WindowTitleHint Qt::WindowType::Window Qt::WindowType::Desktop Qt::WindowType::WindowSystemMenuHint"
+ << "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world"
+ << "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)"
+ << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)"
+ << "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)"
+ << "MyNamespace::MyClass::MyFlag::MyFlag1";
+}
+
void tst_QMetaObject::enumDebugStream()
{
- QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyEnum2 world ");
- qDebug() << "hello" << MyNamespace::MyClass::MyEnum2 << "world";
+ QFETCH(int, verbosity);
+
+ QFETCH(QString, normalEnumMsg);
+ QFETCH(QString, scopedEnumMsg);
+ QFETCH(QString, globalEnumMsg);
+
+ QFETCH(QString, normalFlagMsg);
+ QFETCH(QString, normalFlagsMsg);
+ QFETCH(QString, scopedFlagMsg);
+ QFETCH(QString, scopedFlagsMsg);
+ QFETCH(QString, flagAsEnumMsg);
+
+ // Enums
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(normalEnumMsg));
+ qDebug().verbosity(verbosity) << "hello" << MyNamespace::MyClass::MyEnum2 << "world";
- QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world ");
- qDebug() << "hello" << MyNamespace::MyClass::MyScopedEnum::Enum3 << "scoped world";
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(scopedEnumMsg));
+ qDebug().verbosity(verbosity) << "hello" << MyNamespace::MyClass::MyScopedEnum::Enum3 << "scoped world";
- QTest::ignoreMessage(QtDebugMsg, "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint");
- qDebug() << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint;
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(globalEnumMsg));
+ qDebug().verbosity(verbosity) << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint;
- QTest::ignoreMessage(QtDebugMsg, "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world");
+ // Flags
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(normalFlagMsg));
MyNamespace::MyClass::MyFlags f1 = MyNamespace::MyClass::MyFlag1;
- qDebug() << "hello" << f1 << "world";
+ qDebug().verbosity(verbosity) << "hello" << f1 << "world";
MyNamespace::MyClass::MyFlags f2 = MyNamespace::MyClass::MyFlag2 | MyNamespace::MyClass::MyFlag3;
- QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)");
- qDebug() << f1 << f2;
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(normalFlagsMsg));
+ qDebug().verbosity(verbosity) << f1 << f2;
- QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)");
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(scopedFlagMsg));
MyNamespace::MyClass::MyScopedFlags f3 = MyNamespace::MyClass::MyScopedFlag::MyFlag2;
- qDebug() << f3;
+ qDebug().verbosity(verbosity) << f3;
- QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)");
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(scopedFlagsMsg));
f3 |= MyNamespace::MyClass::MyScopedFlag::MyFlag3;
- qDebug() << f3;
+ qDebug().verbosity(verbosity) << f3;
// Single flag recognized as enum:
- QTest::ignoreMessage(QtDebugMsg, "MyNamespace::MyClass::MyFlag1");
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(flagAsEnumMsg));
MyNamespace::MyClass::MyFlag f4 = MyNamespace::MyClass::MyFlag1;
- qDebug() << f4;
+ qDebug().verbosity(verbosity) << f4;
}
void tst_QMetaObject::inherits_data()
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/CMakeLists.txt b/tests/auto/corelib/kernel/qmetaobjectbuilder/CMakeLists.txt
new file mode 100644
index 0000000000..8551749db3
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmetaobjectbuilder Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetaobjectbuilder LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmetaobjectbuilder
+ SOURCES
+ tst_qmetaobjectbuilder.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro b/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro
deleted file mode 100644
index 4da90c1096..0000000000
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmetaobjectbuilder
-QT = core-private testlib
-SOURCES = tst_qmetaobjectbuilder.cpp
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 56623773a2..18e4e2a4a9 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
#include <QtCore/qlocale.h>
#include <private/qmetaobjectbuilder_p.h>
@@ -50,8 +26,6 @@ private slots:
void relatedMetaObject();
void staticMetacall();
void copyMetaObject();
- void serialize();
- void relocatableData();
void removeNotifySignal();
void usage_signal();
@@ -64,13 +38,28 @@ private slots:
void classNameFirstInStringData();
+ void propertyMetaType();
+
+ void cleanupTestCase();
+
+ void ownMetaTypeNoProperties();
+
private:
static bool checkForSideEffects
(const QMetaObjectBuilder& builder,
QMetaObjectBuilder::AddMembers members);
- static bool sameMetaObject
- (const QMetaObject *meta1, const QMetaObject *meta2);
+ QList<QMetaObject *> dynamicMetaObjectsPendingFree;
+};
+
+struct MetaObjectComparison {
+ bool isSame = false;
+ QString details;
+ operator bool() {return isSame;}
+
+ static inline auto Ok() {return MetaObjectComparison{true, QString()}; }
+ static inline auto Failed(QStringView message) {return MetaObjectComparison{false, message.toString()}; }
};
+MetaObjectComparison sameMetaObject(const QMetaObject *meta1, const QMetaObject *meta2);
// Dummy class that has something of every type of thing moc can generate.
class SomethingOfEverything : public QObject
@@ -85,7 +74,7 @@ class SomethingOfEverything : public QObject
Q_PROPERTY(SomethingFlagEnum fprop READ fprop)
Q_PROPERTY(QLocale::Language language READ language)
Q_ENUMS(SomethingEnum)
- Q_FLAGS(SomethingFlagEnum)
+ Q_FLAGS(SomethingFlag)
public:
Q_INVOKABLE SomethingOfEverything() {}
~SomethingOfEverything() {}
@@ -101,6 +90,7 @@ public:
XYZ = 1,
UVW = 8
};
+ Q_DECLARE_FLAGS(SomethingFlag, SomethingFlagEnum)
Q_INVOKABLE Q_SCRIPTABLE void method1() {}
@@ -121,7 +111,7 @@ private slots:
protected slots:
Q_SCRIPTABLE void slot4(int) {}
- void slot5(int a, const QString& b) { Q_UNUSED(a); Q_UNUSED(b); }
+ void slot5(int, const QString &) {}
signals:
void sig1();
@@ -193,8 +183,8 @@ void tst_QMetaObjectBuilder::flags()
QCOMPARE(builder.flags(), 0);
// Set flags
- builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
- QCOMPARE(builder.flags(), QMetaObjectBuilder::DynamicMetaObject);
+ builder.setFlags(DynamicMetaObject);
+ QCOMPARE(builder.flags(), DynamicMetaObject);
}
void tst_QMetaObjectBuilder::method()
@@ -556,7 +546,6 @@ void tst_QMetaObjectBuilder::property()
QVERIFY(!nullProp.isDesignable());
QVERIFY(!nullProp.isScriptable());
QVERIFY(!nullProp.isStored());
- QVERIFY(!nullProp.isEditable());
QVERIFY(!nullProp.isUser());
QVERIFY(!nullProp.hasStdCppSet());
QVERIFY(!nullProp.isEnumOrFlag());
@@ -576,7 +565,6 @@ void tst_QMetaObjectBuilder::property()
QVERIFY(!prop1.isDesignable());
QVERIFY(prop1.isScriptable());
QVERIFY(!prop1.isStored());
- QVERIFY(!prop1.isEditable());
QVERIFY(!prop1.isUser());
QVERIFY(!prop1.hasStdCppSet());
QVERIFY(!prop1.isEnumOrFlag());
@@ -597,7 +585,6 @@ void tst_QMetaObjectBuilder::property()
QVERIFY(!prop2.isDesignable());
QVERIFY(prop2.isScriptable());
QVERIFY(!prop2.isStored());
- QVERIFY(!prop2.isEditable());
QVERIFY(!prop2.isUser());
QVERIFY(!prop2.hasStdCppSet());
QVERIFY(!prop2.isEnumOrFlag());
@@ -621,7 +608,6 @@ void tst_QMetaObjectBuilder::property()
prop1.setDesignable(true);
prop1.setScriptable(false);
prop1.setStored(true);
- prop1.setEditable(true);
prop1.setUser(true);
prop1.setStdCppSet(true);
prop1.setEnumOrFlag(true);
@@ -638,7 +624,6 @@ void tst_QMetaObjectBuilder::property()
QVERIFY(prop1.isDesignable());
QVERIFY(!prop1.isScriptable());
QVERIFY(prop1.isStored());
- QVERIFY(prop1.isEditable());
QVERIFY(prop1.isUser());
QVERIFY(prop1.hasStdCppSet());
QVERIFY(prop1.isEnumOrFlag());
@@ -653,7 +638,6 @@ void tst_QMetaObjectBuilder::property()
QVERIFY(!prop2.isDesignable());
QVERIFY(prop2.isScriptable());
QVERIFY(!prop2.isStored());
- QVERIFY(!prop2.isEditable());
QVERIFY(!prop2.isUser());
QVERIFY(!prop2.hasStdCppSet());
QVERIFY(!prop2.isEnumOrFlag());
@@ -671,7 +655,6 @@ void tst_QMetaObjectBuilder::property()
QVERIFY(!prop2.isDesignable());
QVERIFY(prop2.isScriptable());
QVERIFY(!prop2.isStored());
- QVERIFY(!prop2.isEditable());
QVERIFY(!prop2.isUser());
QVERIFY(!prop2.hasStdCppSet());
QVERIFY(!prop2.isEnumOrFlag());
@@ -697,7 +680,6 @@ void tst_QMetaObjectBuilder::property()
prop2.setDesignable(false); \
prop2.setScriptable(false); \
prop2.setStored(false); \
- prop2.setEditable(false); \
prop2.setUser(false); \
prop2.setStdCppSet(false); \
prop2.setEnumOrFlag(false); \
@@ -711,7 +693,6 @@ void tst_QMetaObjectBuilder::property()
(prop2.isDesignable() ? 1 : 0) + \
(prop2.isScriptable() ? 1 : 0) + \
(prop2.isStored() ? 1 : 0) + \
- (prop2.isEditable() ? 1 : 0) + \
(prop2.isUser() ? 1 : 0) + \
(prop2.hasStdCppSet() ? 1 : 0) + \
(prop2.isEnumOrFlag() ? 1 : 0) + \
@@ -731,7 +712,6 @@ void tst_QMetaObjectBuilder::property()
CHECK_FLAG(setDesignable, isDesignable);
CHECK_FLAG(setScriptable, isScriptable);
CHECK_FLAG(setStored, isStored);
- CHECK_FLAG(setEditable, isEditable);
CHECK_FLAG(setUser, isUser);
CHECK_FLAG(setStdCppSet, hasStdCppSet);
CHECK_FLAG(setEnumOrFlag, isEnumOrFlag);
@@ -757,13 +737,12 @@ void tst_QMetaObjectBuilder::variantProperty()
QMetaObjectBuilder builder;
builder.addProperty("variant", "const QVariant &");
QMetaObject *meta = builder.toMetaObject();
+ dynamicMetaObjectsPendingFree.push_back(meta);
QMetaProperty prop = meta->property(meta->propertyOffset());
- QCOMPARE(QMetaType::Type(prop.type()), QMetaType::QVariant);
+ QCOMPARE(QMetaType::Type(prop.userType()), QMetaType::QVariant);
QCOMPARE(QMetaType::Type(prop.userType()), QMetaType::QVariant);
QCOMPARE(QByteArray(prop.typeName()), QByteArray("QVariant"));
-
- free(meta);
}
void tst_QMetaObjectBuilder::notifySignal()
@@ -800,6 +779,26 @@ void tst_QMetaObjectBuilder::notifySignal()
void tst_QMetaObjectBuilder::enumerator()
{
+ static const QtPrivate::QMetaTypeInterface fooFlagMetaType = {
+ 0,
+ 8,
+ 8,
+ QMetaType::IsEnumeration | QMetaType::IsUnsignedEnumeration | QMetaType::RelocatableType,
+ {},
+ nullptr,
+ "fooFlag",
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ };
+
QMetaObjectBuilder builder;
// Add an enumerator and check its attributes.
@@ -831,6 +830,7 @@ void tst_QMetaObjectBuilder::enumerator()
enum1.setIsFlag(true);
enum1.setIsScoped(true);
enum1.setEnumName(QByteArrayLiteral("fooFlag"));
+ enum1.setMetaType(QMetaType(&fooFlagMetaType));
QCOMPARE(enum1.addKey("ABC", 0), 0);
QCOMPARE(enum1.addKey("DEF", 1), 1);
QCOMPARE(enum1.addKey("GHI", -1), 2);
@@ -840,6 +840,7 @@ void tst_QMetaObjectBuilder::enumerator()
QVERIFY(enum1.isFlag());
QVERIFY(enum1.isScoped());
QCOMPARE(enum1.enumName(), QByteArray("fooFlag"));
+ QCOMPARE(enum1.metaType(), QMetaType(&fooFlagMetaType));
QCOMPARE(enum1.keyCount(), 3);
QCOMPARE(enum1.index(), 0);
QCOMPARE(enum1.key(0), QByteArray("ABC"));
@@ -1007,106 +1008,23 @@ void tst_QMetaObjectBuilder::copyMetaObject()
{
QMetaObjectBuilder builder(&QObject::staticMetaObject);
QMetaObject *meta = builder.toMetaObject();
- QVERIFY(sameMetaObject(meta, &QObject::staticMetaObject));
- free(meta);
+ dynamicMetaObjectsPendingFree.push_back(meta);
+ auto compared = sameMetaObject(meta, &QObject::staticMetaObject);
+ QVERIFY2(compared, qPrintable(compared.details));
QMetaObjectBuilder builder2(&staticMetaObject);
meta = builder2.toMetaObject();
- QVERIFY(sameMetaObject(meta, &staticMetaObject));
- free(meta);
+ dynamicMetaObjectsPendingFree.push_back(meta);
+ compared = sameMetaObject(meta, &staticMetaObject);
+ QVERIFY2(compared, qPrintable(compared.details));
QMetaObjectBuilder builder3(&SomethingOfEverything::staticMetaObject);
meta = builder3.toMetaObject();
- QVERIFY(sameMetaObject(meta, &SomethingOfEverything::staticMetaObject));
- free(meta);
-}
-
-// Serialize and deserialize a meta object and check that
-// it round-trips to the exact same value.
-void tst_QMetaObjectBuilder::serialize()
-{
- // Full QMetaObjectBuilder
- {
- QMetaObjectBuilder builder(&SomethingOfEverything::staticMetaObject);
- QMetaObject *meta = builder.toMetaObject();
-
- QByteArray data;
- QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
- builder.serialize(stream);
-
- QMetaObjectBuilder builder2;
- QDataStream stream2(data);
- QMap<QByteArray, const QMetaObject *> references;
- references.insert(QByteArray("QLocale"), &QLocale::staticMetaObject);
- builder2.deserialize(stream2, references);
- builder2.setStaticMetacallFunction(builder.staticMetacallFunction());
- QMetaObject *meta2 = builder2.toMetaObject();
-
- QVERIFY(sameMetaObject(meta, meta2));
- free(meta);
- free(meta2);
- }
-
- // Partial QMetaObjectBuilder
- {
- QMetaObjectBuilder builder;
- builder.setClassName("Test");
- builder.addProperty("foo", "int");
-
- QByteArray data;
- QDataStream stream(&data, QIODevice::WriteOnly | QIODevice::Append);
- builder.serialize(stream);
-
- QMetaObjectBuilder builder2;
- QDataStream stream2(data);
- builder2.deserialize(stream2, QMap<QByteArray, const QMetaObject *>());
-
- QCOMPARE(builder.superClass(), builder2.superClass());
- QCOMPARE(builder.className(), builder2.className());
- QCOMPARE(builder.propertyCount(), builder2.propertyCount());
- QCOMPARE(builder.property(0).name(), builder2.property(0).name());
- QCOMPARE(builder.property(0).type(), builder2.property(0).type());
- }
+ dynamicMetaObjectsPendingFree.push_back(meta);
+ compared = sameMetaObject(meta, &SomethingOfEverything::staticMetaObject);
+ QVERIFY2(compared, qPrintable(compared.details));
}
-void tst_QMetaObjectBuilder::relocatableData()
-{
- QMetaObjectBuilder builder;
- builder.setClassName("TestObject");
-
- QMetaMethodBuilder intPropChanged = builder.addSignal("intPropChanged(int)");
- intPropChanged.setParameterNames(QList<QByteArray>() << "newIntPropValue");
-
- QMetaPropertyBuilder prop = builder.addProperty("intProp", "int");
- prop.setNotifySignal(intPropChanged);
-
- QMetaMethodBuilder voidSlotInt = builder.addSlot("voidSlotInt(int)");
- voidSlotInt.setParameterNames(QList<QByteArray>() << "slotIntArg");
-
- QMetaMethodBuilder listInvokableQRealQString = builder.addMethod("listInvokableQRealQString(qreal,QString)");
- listInvokableQRealQString.setReturnType("QVariantList");
- listInvokableQRealQString.setParameterNames(QList<QByteArray>() << "qrealArg" << "qstringArg");
-
- bool ok = false;
- QByteArray data = builder.toRelocatableData(&ok);
- QVERIFY(ok);
-
- QMetaObjectBuilder builder2;
- QMetaObject meta2;
- builder2.fromRelocatableData(&meta2, &QObject::staticMetaObject, data);
-
- QMetaObject *meta = builder.toMetaObject();
-
- QVERIFY(sameMetaObject(meta, &meta2));
-
- QVERIFY(!meta2.d.extradata);
- QVERIFY(!meta2.d.relatedMetaObjects);
- QVERIFY(!meta2.d.static_metacall);
-
- free(meta);
-}
-
-
// Check that removing a method updates notify signals appropriately
void tst_QMetaObjectBuilder::removeNotifySignal()
{
@@ -1217,13 +1135,13 @@ static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
return true;
}
-static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
+static MetaObjectComparison sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
{
if (QByteArray(prop1.name()) != QByteArray(prop2.name()))
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Property names differ: %1 vs %2").arg(prop1.name(), prop2.name()));
if (QByteArray(prop1.typeName()) != QByteArray(prop2.typeName()))
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Property type names differ: %1 vs %2").arg(prop1.typeName(), prop2.typeName()));
if (prop1.isReadable() != prop2.isReadable() ||
prop1.isWritable() != prop2.isWritable() ||
@@ -1231,23 +1149,26 @@ static bool sameProperty(const QMetaProperty& prop1, const QMetaProperty& prop2)
prop1.isDesignable() != prop2.isDesignable() ||
prop1.isScriptable() != prop2.isScriptable() ||
prop1.isStored() != prop2.isStored() ||
- prop1.isEditable() != prop2.isEditable() ||
prop1.isUser() != prop2.isUser() ||
prop1.isFlagType() != prop2.isFlagType() ||
prop1.isEnumType() != prop2.isEnumType() ||
prop1.hasNotifySignal() != prop2.hasNotifySignal() ||
prop1.hasStdCppSet() != prop2.hasStdCppSet())
- return false;
+ return MetaObjectComparison::Failed(u"Flags differ");
if (prop1.hasNotifySignal()) {
if (prop1.notifySignalIndex() != prop2.notifySignalIndex())
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Notify signal index differ: %1 vs %2").arg(
+ QString::number(prop1.notifySignalIndex()),
+ QString::number(prop2.notifySignalIndex())));
}
- if (prop1.revision() != prop2.revision())
- return false;
+ const int revision1 = prop1.revision();
+ const int revision2 = prop2.revision();
+ if (revision1 != revision2)
+ return MetaObjectComparison::Failed(QStringLiteral("Revisions differ: %1 vs %2").arg(QString::number(revision1), QString::number(revision2)));
- return true;
+ return MetaObjectComparison::Ok();
}
static bool sameEnumerator(const QMetaEnum& enum1, const QMetaEnum& enum2)
@@ -1275,69 +1196,89 @@ static bool sameEnumerator(const QMetaEnum& enum1, const QMetaEnum& enum2)
}
// Determine if two meta objects are identical.
-bool tst_QMetaObjectBuilder::sameMetaObject
- (const QMetaObject *meta1, const QMetaObject *meta2)
+MetaObjectComparison sameMetaObject(const QMetaObject *meta1, const QMetaObject *meta2)
{
int index;
- if (strcmp(meta1->className(), meta2->className()) != 0)
- return false;
+ if (strcmp(meta1->className(), meta2->className()) != 0) {
+ QString message = QLatin1String("Class names differ: %1 %2").arg(meta1->className(), meta2->className());
+ return MetaObjectComparison::Failed(message);
+ }
if (meta1->superClass() != meta2->superClass())
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Super classes differ"));
- if (meta1->constructorCount() != meta2->constructorCount() ||
- meta1->methodCount() != meta2->methodCount() ||
- meta1->enumeratorCount() != meta2->enumeratorCount() ||
- meta1->propertyCount() != meta2->propertyCount() ||
- meta1->classInfoCount() != meta2->classInfoCount())
- return false;
+ auto numCompare = [](int num1, int num2, const QString &message) {
+ if (num1 != num2)
+ return MetaObjectComparison::Failed(message.arg(QString::number(num1), QString::number(num2)));
+ return MetaObjectComparison::Ok();
+ };
+
+ auto compared = numCompare(meta1->constructorCount(), meta2->constructorCount(), QStringLiteral("Construct counts differ: %1 %2"));
+ if (!compared.isSame)
+ return compared;
+ compared = numCompare(meta1->methodCount(), meta2->methodCount(), QStringLiteral("Method counts differ: %1 %2"));
+ if (!compared.isSame)
+ return compared;
+ compared = numCompare(meta1->enumeratorCount(), meta2->enumeratorCount(), QStringLiteral("Enumerator counts differ: %1 %2"));
+ if (!compared.isSame)
+ return compared;
+ compared = numCompare(meta1->propertyCount(), meta2->propertyCount(), QStringLiteral("Property counts differ: %1 %2"));
+ if (!compared.isSame)
+ return compared;
+ compared = numCompare(meta1->classInfoCount(), meta2->classInfoCount(), QStringLiteral("ClassInfo counts differ: %1 %2"));
+ if (!compared.isSame)
+ return compared;
for (index = 0; index < meta1->constructorCount(); ++index) {
if (!sameMethod(meta1->constructor(index), meta2->constructor(index)))
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Constructors difer at index %1").arg(index));
}
for (index = 0; index < meta1->methodCount(); ++index) {
if (!sameMethod(meta1->method(index), meta2->method(index)))
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Methods difer at index %1").arg(index));
}
for (index = 0; index < meta1->propertyCount(); ++index) {
- if (!sameProperty(meta1->property(index), meta2->property(index)))
- return false;
+ if (auto compared = sameProperty(meta1->property(index), meta2->property(index)); !compared) {
+ compared.details += QStringLiteral(" at index %1").arg(index);
+ return compared;
+ }
}
for (index = 0; index < meta1->enumeratorCount(); ++index) {
if (!sameEnumerator(meta1->enumerator(index), meta2->enumerator(index)))
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Enumerators difer at index %1").arg(index));
}
for (index = 0; index < meta1->classInfoCount(); ++index) {
- if (QByteArray(meta1->classInfo(index).name()) !=
- QByteArray(meta2->classInfo(index).name()))
- return false;
- if (QByteArray(meta1->classInfo(index).value()) !=
- QByteArray(meta2->classInfo(index).value()))
- return false;
+ const auto name1= QByteArray(meta1->classInfo(index).name());
+ const auto name2= QByteArray(meta1->classInfo(index).name());
+ if (name1 != name2)
+ return MetaObjectComparison::Failed(QStringLiteral("Class infos difer at index %1: %2 vs %3").arg(QString::number(index), name1, name2));
+ const auto value1 = QByteArray(meta1->classInfo(index).value());
+ const auto value2= QByteArray(meta2->classInfo(index).value());
+ if ( value1 != value2)
+ return MetaObjectComparison::Failed(QStringLiteral("Class infos difer at index %1: %2 vs %3").arg(QString::number(index), value1, value2));
}
- const QMetaObject * const *objects1 = meta1->d.relatedMetaObjects;
- const QMetaObject * const *objects2 = meta2->d.relatedMetaObjects;
+ const auto *objects1 = meta1->d.relatedMetaObjects;
+ const auto *objects2 = meta2->d.relatedMetaObjects;
if (objects1 && !objects2)
- return false;
+ return MetaObjectComparison::Failed(u"Metaobject 1 had related metaobjects, but Metaoject 2 did not");
if (objects2 && !objects1)
- return false;
+ return MetaObjectComparison::Failed(u"Metaobject 2 had related metaobjects, but Metaoject 1 did not");
if (objects1 && objects2) {
while (*objects1 != 0 && *objects2 != 0) {
if (*objects1 != *objects2)
- return false;
+ return MetaObjectComparison::Failed(QStringLiteral("Related metaobjects differ at index %1").arg(index));
++objects1;
++objects2;
}
}
- return true;
+ return MetaObjectComparison::Ok();
}
@@ -1352,17 +1293,16 @@ class TestObject : public QObject
{
// Manually expanded from Q_OBJECT macro
public:
- Q_OBJECT_CHECK
static QMetaObject staticMetaObject;
- virtual const QMetaObject *metaObject() const;
- virtual void *qt_metacast(const char *);
- virtual int qt_metacall(QMetaObject::Call, int, void **);
+ virtual const QMetaObject *metaObject() const override;
+ virtual void *qt_metacast(const char *) override;
+ virtual int qt_metacall(QMetaObject::Call, int, void **) override;
private:
Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
//Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
public:
- TestObject(QObject *parent = 0); // Q_INVOKABLE
+ TestObject(QObject *parent = nullptr); // Q_INVOKABLE
~TestObject();
// Property accessors
@@ -1391,7 +1331,7 @@ private:
};
QMetaObject TestObject::staticMetaObject = {
- { 0, 0, 0, 0, 0, 0 }
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}
};
TestObject::TestObject(QObject *parent)
@@ -1541,9 +1481,7 @@ int TestObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < ownMethodCount)
qt_static_metacall(this, _c, _id, _a);
_id -= ownMethodCount;
- }
-#ifndef QT_NO_PROPERTIES
- else if (_c == QMetaObject::ReadProperty) {
+ } else if (_c == QMetaObject::ReadProperty) {
void *_v = _a[0];
switch (_id) {
case 0: *reinterpret_cast< int*>(_v) = intProp(); break;
@@ -1565,18 +1503,7 @@ int TestObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
_id -= ownPropertyCount;
} else if (_c == QMetaObject::ResetProperty) {
_id -= ownPropertyCount;
- } else if (_c == QMetaObject::QueryPropertyDesignable) {
- _id -= ownPropertyCount;
- } else if (_c == QMetaObject::QueryPropertyScriptable) {
- _id -= ownPropertyCount;
- } else if (_c == QMetaObject::QueryPropertyStored) {
- _id -= ownPropertyCount;
- } else if (_c == QMetaObject::QueryPropertyEditable) {
- _id -= ownPropertyCount;
- } else if (_c == QMetaObject::QueryPropertyUser) {
- _id -= ownPropertyCount;
}
-#endif // QT_NO_PROPERTIES
return _id;
}
@@ -1594,8 +1521,8 @@ void tst_QMetaObjectBuilder::usage_signal()
QSignalSpy propChangedSpy(testObject.data(), &TestObject::intPropChanged);
testObject->emitIntPropChanged();
- QCOMPARE(propChangedSpy.count(), 1);
- QCOMPARE(propChangedSpy.at(0).count(), 1);
+ QCOMPARE(propChangedSpy.size(), 1);
+ QCOMPARE(propChangedSpy.at(0).size(), 1);
QCOMPARE(propChangedSpy.at(0).at(0).toInt(), testObject->intProp());
}
@@ -1604,15 +1531,15 @@ void tst_QMetaObjectBuilder::usage_property()
QScopedPointer<TestObject> testObject(new TestObject);
QVariant prop = testObject->property("intProp");
- QCOMPARE(prop.type(), QVariant::Int);
+ QCOMPARE(prop.metaType(), QMetaType(QMetaType::Int));
QCOMPARE(prop.toInt(), testObject->intProp());
QSignalSpy propChangedSpy(testObject.data(), &TestObject::intPropChanged);
QVERIFY(testObject->intProp() != 123);
testObject->setProperty("intProp", 123);
- QCOMPARE(propChangedSpy.count(), 1);
+ QCOMPARE(propChangedSpy.size(), 1);
prop = testObject->property("intProp");
- QCOMPARE(prop.type(), QVariant::Int);
+ QCOMPARE(prop.metaType(), QMetaType(QMetaType::Int));
QCOMPARE(prop.toInt(), 123);
}
@@ -1640,9 +1567,9 @@ void tst_QMetaObjectBuilder::usage_method()
QVERIFY(listInvokableQRealQString.invoke(testObject.data(), Q_RETURN_ARG(QVariantList, list),
Q_ARG(qreal, 123.0), Q_ARG(QString, "ciao")));
QCOMPARE(list.size(), 2);
- QCOMPARE(list.at(0).type(), QVariant::Type(QMetaType::QReal));
+ QCOMPARE(list.at(0).metaType(), QMetaType(QMetaType::QReal));
QCOMPARE(list.at(0).toDouble(), double(123));
- QCOMPARE(list.at(1).type(), QVariant::String);
+ QCOMPARE(list.at(1).metaType(), QMetaType(QMetaType::QString));
QCOMPARE(list.at(1).toString(), QString::fromLatin1("ciao"));
}
@@ -1702,13 +1629,50 @@ void tst_QMetaObjectBuilder::classNameFirstInStringData()
builder.setClassName(QByteArrayLiteral("TestClass"));
QMetaObject *mo = builder.toMetaObject();
- QByteArrayDataPtr header;
- header.ptr = const_cast<QByteArrayData*>(mo->d.stringdata);
- QCOMPARE(QByteArray(header), QByteArrayLiteral("TestClass"));
+ uint offset = mo->d.stringdata[0];
+ uint len = mo->d.stringdata[1];
+ QByteArray className(reinterpret_cast<const char *>(mo->d.stringdata) + offset, len);
+ QCOMPARE(className, QByteArrayLiteral("TestClass"));
free(mo);
}
+struct MyFoo {};
+struct myParameter {};
+
+void tst_QMetaObjectBuilder::propertyMetaType()
+{
+ qRegisterMetaType<myParameter>();
+ QMetaType meta = QMetaType::fromType<MyFoo>();
+ auto metaId = meta.id();
+ QMetaObjectBuilder builder;
+ builder.setClassName("Test");
+ builder.addProperty("myParameter", "MyFoo");
+ auto mo = builder.toMetaObject();
+
+ QMetaProperty metaProp = mo->property(mo->indexOfProperty("myParameter"));
+ QCOMPARE(metaProp.typeName(), meta.name());
+ QCOMPARE(metaProp.typeId(), metaId);
+ QCOMPARE(metaProp.metaType(), meta);
+ free(mo);
+}
+
+void tst_QMetaObjectBuilder::ownMetaTypeNoProperties()
+{
+ QMetaObjectBuilder builder;
+ builder.setClassName("NoProperties");
+ auto mo = builder.toMetaObject();
+ auto cleanup = qScopeGuard([&](){ free(mo); });
+ // own metatype should be invalid, as the dynamic metaobject has not been registered
+ QVERIFY(!mo->metaType().isValid());// should not crash
+}
+
+void tst_QMetaObjectBuilder::cleanupTestCase()
+{
+ for (QMetaObject *obj: dynamicMetaObjectsPendingFree)
+ free(obj);
+}
+
QTEST_MAIN(tst_QMetaObjectBuilder)
#include "tst_qmetaobjectbuilder.moc"
diff --git a/tests/auto/corelib/kernel/qmetaproperty/CMakeLists.txt b/tests/auto/corelib/kernel/qmetaproperty/CMakeLists.txt
new file mode 100644
index 0000000000..49c07afd87
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetaproperty/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmetaproperty Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetaproperty LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmetaproperty
+ SOURCES
+ tst_qmetaproperty.cpp
+)
diff --git a/tests/auto/corelib/kernel/qmetaproperty/qmetaproperty.pro b/tests/auto/corelib/kernel/qmetaproperty/qmetaproperty.pro
deleted file mode 100644
index 1f338a909b..0000000000
--- a/tests/auto/corelib/kernel/qmetaproperty/qmetaproperty.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmetaproperty
-QT = core testlib
-SOURCES = tst_qmetaproperty.cpp
diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp
index 681a5d0146..c8053ca43a 100644
--- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp
+++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp
@@ -1,37 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <qobject.h>
#include <qmetaobject.h>
+#include <QMap>
+#include <QString>
struct CustomType
{
@@ -45,7 +22,14 @@ struct CustomType
Q_DECLARE_METATYPE(CustomType)
-class tst_QMetaProperty : public QObject
+class Base : public QObject
+{
+ Q_OBJECT
+signals:
+ void baseSignal(int);
+};
+
+class tst_QMetaProperty : public Base
{
Q_OBJECT
Q_PROPERTY(EnumType value WRITE setValue READ getValue)
@@ -56,6 +40,7 @@ class tst_QMetaProperty : public QObject
Q_PROPERTY(int value10 READ value10 FINAL)
Q_PROPERTY(QMap<int, int> map MEMBER map)
Q_PROPERTY(CustomType custom MEMBER custom)
+ Q_PROPERTY(int propWithInheritedSig READ propWithInheritedSig NOTIFY baseSignal)
private slots:
void hasStdCppSet();
@@ -65,6 +50,8 @@ private slots:
void readAndWriteWithLazyRegistration();
void mapProperty();
void conversion();
+ void enumsFlags();
+ void notifySignalIndex();
public:
enum EnumType { EnumType1 };
@@ -79,6 +66,8 @@ public:
int value9() const { return 1; }
int value10() const { return 1; }
+ int propWithInheritedSig() const { return 0; }
+
QString value7;
QMap<int, int> map;
CustomType custom;
@@ -130,7 +119,7 @@ public:
QString m_value;
void setValue(const QString &value) { m_value = value; }
QString getValue() { return m_value; }
- void resetValue() { m_value = QLatin1Literal("reset"); }
+ void resetValue() { m_value = QLatin1String("reset"); }
};
void tst_QMetaProperty::gadget()
@@ -138,9 +127,10 @@ void tst_QMetaProperty::gadget()
const QMetaObject *mo = &MyGadget::staticMetaObject;
QMetaProperty valueProp = mo->property(mo->indexOfProperty("value"));
QVERIFY(valueProp.isValid());
+ QCOMPARE(valueProp.metaType(), QMetaType::fromType<QString>());
{
MyGadget g;
- QString hello = QLatin1Literal("hello");
+ QString hello = QLatin1String("hello");
QVERIFY(valueProp.writeOnGadget(&g, hello));
QCOMPARE(g.m_value, QLatin1String("hello"));
QCOMPARE(valueProp.readOnGadget(&g), QVariant(hello));
@@ -180,22 +170,49 @@ public:
{}
};
+class EnumFlagsTester : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(TestEnum enumProperty READ enumProperty WRITE setEnumProperty)
+ Q_PROPERTY(TestFlags flagProperty READ flagProperty WRITE setFlagProperty)
+public:
+ enum TestEnum { e1, e2 };
+ Q_ENUM(TestEnum)
+
+ enum TestFlag { flag1 = 0x1, flag2 = 0x2 };
+ Q_DECLARE_FLAGS(TestFlags, TestFlag)
+
+ using QObject::QObject;
+
+ TestEnum enumProperty() const { return m_enum; }
+ void setEnumProperty(TestEnum e) { m_enum = e; }
+
+ TestFlags flagProperty() const { return m_flags; }
+ void setFlagProperty(TestFlags f) { m_flags = f; }
+
+private:
+ TestEnum m_enum = e1;
+ TestFlags m_flags;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(EnumFlagsTester::TestFlags)
+
void tst_QMetaProperty::readAndWriteWithLazyRegistration()
{
- QCOMPARE(QMetaType::type("CustomReadObject*"), int(QMetaType::UnknownType));
- QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType));
+ QVERIFY(!QMetaType::fromName("CustomReadObject*").isValid());
+ QVERIFY(!QMetaType::fromName("CustomWriteObject*").isValid());
TypeLazyRegistration o;
QVERIFY(o.property("read").isValid());
- QVERIFY(QMetaType::type("CustomReadObject*") != QMetaType::UnknownType);
- QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType));
+ QVERIFY(QMetaType::fromName("CustomReadObject*").isValid());
+ QVERIFY(!QMetaType::fromName("CustomWriteObject*").isValid());
CustomWriteObjectChild data;
QVariant value = QVariant::fromValue(&data); // this register CustomWriteObjectChild
// check if base classes are not registered automatically, otherwise this test would be meaningless
- QCOMPARE(QMetaType::type("CustomWriteObject*"), int(QMetaType::UnknownType));
+ QVERIFY(!QMetaType::fromName("CustomWriteObject*").isValid());
QVERIFY(o.setProperty("write", value));
- QVERIFY(QMetaType::type("CustomWriteObject*") != QMetaType::UnknownType);
+ QVERIFY(QMetaType::fromName("CustomWriteObject*").isValid());
QCOMPARE(o.property("write").value<CustomWriteObjectChild*>(), &data);
}
@@ -242,7 +259,45 @@ void tst_QMetaProperty::conversion()
QCOMPARE(custom.str, QString());
// or reset resetable
QVERIFY(value7P.write(this, QVariant()));
- QCOMPARE(value7, QLatin1Literal("reset"));
+ QCOMPARE(value7, QLatin1String("reset"));
+}
+
+void tst_QMetaProperty::enumsFlags()
+{
+ // QTBUG-83689, verify that enumerations and flags can be assigned from int,
+ // which is important for Qt Designer.
+ EnumFlagsTester t;
+
+ auto mo = t.metaObject();
+
+ const int enumIndex = mo->indexOfProperty("enumProperty");
+ QVERIFY(enumIndex >= 0);
+ auto enumProperty = mo->property(enumIndex);
+ QVERIFY(enumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration));
+ QVERIFY(enumProperty.write(&t, QVariant(int(EnumFlagsTester::e2))));
+ QCOMPARE(t.enumProperty(), EnumFlagsTester::e2);
+
+ const int flagsIndex = mo->indexOfProperty("flagProperty");
+ QVERIFY(flagsIndex >= 0);
+ auto flagsProperty = mo->property(flagsIndex);
+ QVERIFY(flagsProperty.metaType().flags().testFlag(QMetaType::IsEnumeration));
+ QVERIFY(flagsProperty.write(&t, QVariant(int(EnumFlagsTester::flag2))));
+ QCOMPARE(t.flagProperty(), EnumFlagsTester::flag2);
+}
+
+
+void tst_QMetaProperty::notifySignalIndex()
+{
+ auto mo = this->metaObject();
+ auto propIndex = mo->indexOfProperty("propWithInheritedSig");
+ auto propWithInheritedSig = mo->property(propIndex);
+ QVERIFY(propWithInheritedSig.isValid());
+ QVERIFY(propWithInheritedSig.hasNotifySignal());
+ QVERIFY(propWithInheritedSig.notifySignalIndex() != -1);
+ QMetaMethod notifySignal = propWithInheritedSig.notifySignal();
+ QVERIFY(notifySignal.isValid());
+ QCOMPARE(notifySignal.name(), "baseSignal");
+ QCOMPARE(notifySignal.parameterCount(), 1);
}
QTEST_MAIN(tst_QMetaProperty)
diff --git a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt
new file mode 100644
index 0000000000..b93d961109
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmetatype Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmetatype LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "./typeFlags.bin")
+
+qt_internal_add_cmake_library(qmetatype_lib1
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qmetatype"
+ SOURCES
+ lib1.cpp
+ PUBLIC_LIBRARIES
+ Qt::Core
+)
+qt_internal_add_cmake_library(qmetatype_lib2
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qmetatype"
+ SOURCES
+ lib2.cpp
+ PUBLIC_LIBRARIES
+ Qt::Core
+)
+set_target_properties(qmetatype_lib1 PROPERTIES
+ VERSION 1.0.0
+ SOVERSION 0
+ C_VISIBILITY_PRESET "hidden"
+ CXX_VISIBILITY_PRESET "hidden"
+ VISIBILITY_INLINES_HIDDEN ON
+)
+set_target_properties(qmetatype_lib2 PROPERTIES
+ VERSION 1.0.0
+ SOVERSION 0
+ C_VISIBILITY_PRESET "hidden"
+ CXX_VISIBILITY_PRESET "hidden"
+ VISIBILITY_INLINES_HIDDEN ON
+)
+
+qt_internal_add_test(tst_qmetatype
+ SOURCES
+ tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp
+ tst_qmetatype3.cpp
+ INCLUDE_DIRECTORIES
+ ../../../other/qvariant_common
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ qmetatype_lib1
+ qmetatype_lib2
+ TESTDATA ${test_data}
+)
+
+qt_internal_extend_target(tst_qmetatype CONDITION MSVC
+ COMPILE_OPTIONS
+ /bigobj
+)
diff --git a/tests/auto/corelib/kernel/qmetatype/lib1.cpp b/tests/auto/corelib/kernel/qmetatype/lib1.cpp
new file mode 100644
index 0000000000..e5478f87d9
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/lib1.cpp
@@ -0,0 +1,5 @@
+// Copyright (C) 2022 Intel Corporation
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#define LIB_NAMESPACE Lib1
+#include "lib_common.cpp"
diff --git a/tests/auto/corelib/kernel/qmetatype/lib2.cpp b/tests/auto/corelib/kernel/qmetatype/lib2.cpp
new file mode 100644
index 0000000000..0a905e669a
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/lib2.cpp
@@ -0,0 +1,5 @@
+// Copyright (C) 2022 Intel Corporation
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#define LIB_NAMESPACE Lib2
+#include "lib_common.cpp"
diff --git a/tests/auto/corelib/kernel/qmetatype/lib_common.cpp b/tests/auto/corelib/kernel/qmetatype/lib_common.cpp
new file mode 100644
index 0000000000..179f539ccc
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/lib_common.cpp
@@ -0,0 +1,13 @@
+// Copyright (C) 2022 Intel Corporation
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <qcollator.h>
+#include "tst_qmetatype_libs.h"
+
+#define DECLARE_FUNCTION(TYPE, ID) \
+ Q_DECL_EXPORT QMetaType metatype_ ## TYPE() \
+ { return QMetaType::fromType<TYPE>(); }
+
+namespace LIB_NAMESPACE {
+FOR_EACH_METATYPE_LIBS(DECLARE_FUNCTION)
+}
diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
deleted file mode 100644
index 56b8c071c3..0000000000
--- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmetatype
-QT = core-private testlib
-INCLUDEPATH += $$PWD/../../../other/qvariant_common
-SOURCES = tst_qmetatype.cpp
-TESTDATA=./typeFlags.bin
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-
-msvc|winrt {
- # Prevents "fatal error C1128: number of sections exceeded object file format limit".
- QMAKE_CXXFLAGS += /bigobj
- # Reduce compile time
- winrt {
- QMAKE_CXXFLAGS_RELEASE -= -O2
- QMAKE_CFLAGS_RELEASE -= -O2
- }
-}
-
-clang {
- # clang has some performance problems with the test. Especially
- # with automaticTemplateRegistration which creates few thousands
- # template instantiations (QTBUG-37237). Removing -O2 and -g
- # improves the situation, but it is not solving the problem.
- QMAKE_CXXFLAGS_RELEASE -= -O2
- QMAKE_CFLAGS_RELEASE -= -O2
- QMAKE_CXXFLAGS_RELEASE -= -g
- QMAKE_CFLAGS_RELEASE -= -g
-
- # Building for ARM (eg iOS) is affected so much that we disable
- #the template part of the test
- contains(QT_ARCH, arm): DEFINES += TST_QMETATYPE_BROKEN_COMPILER
-}
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index e6fac74ccc..81bf5d5ea8 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -1,38 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtCore>
-#include <QtTest/QtTest>
-#include <QtCore/private/qmetaobjectbuilder_p.h>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "tst_qmetatype.h"
-#include "tst_qvariant_common.h"
+
+#include <QtCore/private/qmetaobjectbuilder_p.h>
#ifdef Q_OS_LINUX
# include <pthread.h>
@@ -40,95 +11,144 @@
#include <algorithm>
#include <memory>
+#include <vector>
-// mingw gcc 4.8 also takes way too long, letting the CI system abort the test
-#if defined(__MINGW32__)
-# define TST_QMETATYPE_BROKEN_COMPILER
-#endif
+#include <QtCore/qflags.h>
Q_DECLARE_METATYPE(QMetaType::Type)
+Q_DECLARE_METATYPE(QPartialOrdering)
-class tst_QMetaType: public QObject
+namespace CheckTypeTraits
{
- Q_OBJECT
- Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
-
-public:
- struct GadgetPropertyType {
- QByteArray type;
- QByteArray name;
- QVariant testData;
- };
-
- tst_QMetaType() { propList << 42 << "Hello"; }
-
- QList<QVariant> prop() const { return propList; }
- void setProp(const QList<QVariant> &list) { propList = list; }
-
-private:
- void registerGadget(const char * name, const QVector<GadgetPropertyType> &gadgetProperties);
- QList<QVariant> propList;
-
-private slots:
- void defined();
- void threadSafety();
- void namespaces();
- void qMetaTypeId();
- void properties();
- void normalizedTypes();
- void typeName_data();
- void typeName();
- void type_data();
- void type();
- void type_fromSubString_data();
- void type_fromSubString();
- void create_data();
- void create();
- void createCopy_data();
- void createCopy();
- void sizeOf_data();
- void sizeOf();
- void sizeOfStaticLess_data();
- void sizeOfStaticLess();
- void flags_data();
- void flags();
- void flagsStaticLess_data();
- void flagsStaticLess();
- void flagsBinaryCompatibility5_0_data();
- void flagsBinaryCompatibility5_0();
- void construct_data();
- void construct();
- void typedConstruct();
- void constructCopy_data();
- void constructCopy();
- void typedefs();
- void registerType();
- void isRegistered_data();
- void isRegistered();
- void isRegisteredStaticLess_data();
- void isRegisteredStaticLess();
- void isEnum();
- void registerStreamBuiltin();
- void automaticTemplateRegistration();
- void saveAndLoadBuiltin_data();
- void saveAndLoadBuiltin();
- void saveAndLoadCustom();
- void metaObject_data();
- void metaObject();
- void constexprMetaTypeIds();
- void constRefs();
- void convertCustomType_data();
- void convertCustomType();
- void compareCustomType_data();
- void compareCustomType();
- void compareCustomEqualOnlyType();
- void customDebugStream();
- void unknownType();
+struct NoOperators
+{
+ int x;
};
+using Nested = QVector<std::pair<int, QMap<QStringList, QVariant>>>;
+using Nested2 = QVector<std::pair<int, QVector<QPair<QStringList, QVariant>>>>;
+
+// basic types
+static_assert(QTypeTraits::has_operator_equal_v<bool>);
+static_assert(QTypeTraits::has_operator_less_than_v<bool>);
+static_assert(QTypeTraits::has_operator_equal_v<int>);
+static_assert(QTypeTraits::has_operator_less_than_v<int>);
+static_assert(QTypeTraits::has_operator_equal_v<double>);
+static_assert(QTypeTraits::has_operator_less_than_v<double>);
+
+// no comparison operators
+static_assert(!QTypeTraits::has_operator_equal_v<NoOperators>);
+static_assert(!QTypeTraits::has_operator_less_than_v<NoOperators>);
+
+// standard Qt types
+static_assert(QTypeTraits::has_operator_equal_v<QString>);
+static_assert(QTypeTraits::has_operator_less_than_v<QString>);
+static_assert(QTypeTraits::has_operator_equal_v<QVariant>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QVariant>);
+
+// QList
+static_assert(QTypeTraits::has_operator_equal_v<QStringList>);
+static_assert(QTypeTraits::has_operator_less_than_v<QStringList>);
+static_assert(!QTypeTraits::has_operator_equal_v<QList<NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QList<NoOperators>>);
+static_assert(QTypeTraits::has_operator_equal_v<QList<QVariant>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QList<QVariant>>);
+
+// QPair
+static_assert(QTypeTraits::has_operator_equal_v<QPair<int, QString>>);
+static_assert(QTypeTraits::has_operator_less_than_v<QPair<int, QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<QPair<int, NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QPair<int, NoOperators>>);
+
+// QMap
+static_assert(QTypeTraits::has_operator_equal_v<QMap<int, QString>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QMap<int, QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<QMap<int, NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QMap<int, NoOperators>>);
+
+// QHash
+static_assert(QTypeTraits::has_operator_equal_v<QHash<int, QString>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QHash<int, QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<QHash<int, NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<QHash<int, NoOperators>>);
+
+// QSharedPointer
+static_assert(QTypeTraits::has_operator_equal_v<QSharedPointer<QString>>);
+// smart pointer equality doesn't depend on T
+static_assert(QTypeTraits::has_operator_equal_v<QSharedPointer<NoOperators>>);
+
+// std::vector
+static_assert(QTypeTraits::has_operator_equal_v<std::vector<QString>>);
+static_assert(QTypeTraits::has_operator_less_than_v<std::vector<QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::vector<NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::vector<NoOperators>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::vector<QVariant>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::vector<QVariant>>);
+
+// std::pair
+static_assert(QTypeTraits::has_operator_equal_v<std::pair<int, QString>>);
+static_assert(QTypeTraits::has_operator_less_than_v<std::pair<int, QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::pair<int, NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::pair<int, NoOperators>>);
+
+// std::tuple
+static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, QString, double>>);
+static_assert(QTypeTraits::has_operator_less_than_v<std::tuple<int, QString, double>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::tuple<int, QString, NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, QString, NoOperators>>);
+
+// std::map
+static_assert(QTypeTraits::has_operator_equal_v<std::map<int, QString>>);
+static_assert(QTypeTraits::has_operator_less_than_v<std::map<int, QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::map<int, NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::map<int, NoOperators>>);
+
+// std::optional
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<QString>>);
+static_assert(QTypeTraits::has_operator_less_than_v<std::optional<QString>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::optional<NoOperators>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<NoOperators>>);
+
+// nested types
+static_assert(QTypeTraits::has_operator_equal_v<Nested>);
+static_assert(!QTypeTraits::has_operator_less_than_v<Nested>);
+static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested>>);
+
+static_assert(QTypeTraits::has_operator_equal_v<Nested2>);
+static_assert(!QTypeTraits::has_operator_less_than_v<Nested2>);
+static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested2>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested2>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::tuple<int, Nested2>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::tuple<int, Nested2>>);
+
+// optionals of nesteds
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<std::variant<QString>>>);
+static_assert(QTypeTraits::has_operator_less_than_v<std::optional<std::variant<QString>>>);
+static_assert(!QTypeTraits::has_operator_equal_v<std::optional<std::variant<NoOperators>>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<std::variant<NoOperators>>>);
+
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<Nested>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<Nested>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<std::tuple<int, Nested>>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<std::tuple<int, Nested>>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<std::tuple<int, Nested>>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<std::tuple<int, Nested>>>);
+
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<Nested2>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<Nested2>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<std::tuple<int, Nested2>>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<std::tuple<int, Nested2>>>);
+static_assert(QTypeTraits::has_operator_equal_v<std::optional<std::tuple<int, Nested2>>>);
+static_assert(!QTypeTraits::has_operator_less_than_v<std::optional<std::tuple<int, Nested2>>>);
+
+}
struct BaseGenericType
{
int m_typeId = -1;
+ QMetaType m_metatype;
virtual void *constructor(int typeId, void *where, const void *copy) = 0;
virtual void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) = 0;
virtual void saveOperator(QDataStream & out) const = 0;
@@ -156,13 +176,13 @@ struct GenericGadgetType : BaseGenericType
if (_c == QMetaObject::ReadProperty) {
if (_id < properties.size()) {
const auto &prop = properties.at(_id);
- QMetaType::destruct(int(prop.userType()), _a[0]);
- QMetaType::construct(int(prop.userType()), _a[0], prop.constData());
+ prop.metaType().destruct(_a[0]);
+ prop.metaType().construct(_a[0], prop.constData());
}
} else if (_c == QMetaObject::WriteProperty) {
if (_id < properties.size()) {
auto & prop = properties[_id];
- prop = QVariant(prop.userType(), _a[0]);
+ prop = QVariant(prop.metaType(), _a[0]);
}
}
}
@@ -178,7 +198,7 @@ struct GenericGadgetType : BaseGenericType
for (auto &prop : properties)
in >> prop;
}
- QVector<QVariant> properties;
+ QList<QVariant> properties;
};
struct GenericPODType : BaseGenericType
@@ -216,6 +236,12 @@ struct GenericPODType : BaseGenericType
QByteArray podData;
};
+// The order of the next two statics matters!
+//
+// need to use shared_ptr, for its template ctor, since QMetaTypeInterface isn't polymorphic,
+// but the test derives from it
+static std::vector<std::shared_ptr<QtPrivate::QMetaTypeInterface>> s_metaTypeInterfaces;
+
using RegisteredType = QPair<std::shared_ptr<BaseGenericType>, std::shared_ptr<QMetaObject>>;
static QHash<int, RegisteredType> s_managedTypes;
@@ -238,12 +264,12 @@ static void *GadgetTypedConstructor(int type, void *where, const void *copy)
return it->first->constructor(type, where, copy);
}
-static void GadgetSaveOperator(QDataStream & out, const void *data)
+static void GadgetSaveOperator(const QtPrivate::QMetaTypeInterface *, QDataStream & out, const void *data)
{
reinterpret_cast<const BaseGenericType *>(data)->saveOperator(out);
}
-static void GadgetLoadOperator(QDataStream &in, void *data)
+static void GadgetLoadOperator(const QtPrivate::QMetaTypeInterface *, QDataStream &in, void *data)
{
reinterpret_cast<BaseGenericType *>(data)->loadOperator(in);
}
@@ -255,7 +281,7 @@ class CustomQObject : public QObject
{
Q_OBJECT
public:
- CustomQObject(QObject *parent = 0)
+ CustomQObject(QObject *parent = nullptr)
: QObject(parent)
{
}
@@ -282,16 +308,16 @@ class GadgetDerivedAndTyped : public CustomGadget {};
Q_DECLARE_METATYPE(GadgetDerivedAndTyped<int>)
Q_DECLARE_METATYPE(GadgetDerivedAndTyped<int>*)
-void tst_QMetaType::registerGadget(const char *name, const QVector<GadgetPropertyType> &gadgetProperties)
+void tst_QMetaType::registerGadget(const char *name, const QList<GadgetPropertyType> &gadgetProperties)
{
QMetaObjectBuilder gadgetBuilder;
gadgetBuilder.setClassName(name);
- QMetaObjectBuilder::MetaObjectFlags metaObjectflags = QMetaObjectBuilder::DynamicMetaObject | QMetaObjectBuilder::PropertyAccessInStaticMetaCall;
+ MetaObjectFlags metaObjectflags = DynamicMetaObject | PropertyAccessInStaticMetaCall;
gadgetBuilder.setFlags(metaObjectflags);
auto dynamicGadgetProperties = std::make_shared<GenericGadgetType>();
for (const auto &prop : gadgetProperties) {
- int propertyType = QMetaType::type(prop.type);
- dynamicGadgetProperties->properties.push_back(QVariant(QVariant::Type(propertyType)));
+ int propertyType = QMetaType::fromName(prop.type).id();
+ dynamicGadgetProperties->properties.push_back(QVariant(QMetaType(propertyType)));
auto dynamicPropery = gadgetBuilder.addProperty(prop.name, prop.type);
dynamicPropery.setWritable(true);
dynamicPropery.setReadable(true);
@@ -299,14 +325,36 @@ void tst_QMetaType::registerGadget(const char *name, const QVector<GadgetPropert
auto meta = gadgetBuilder.toMetaObject();
meta->d.static_metacall = &GadgetsStaticMetacallFunction;
meta->d.superdata = nullptr;
- const auto flags = QMetaType::WasDeclaredAsMetaType | QMetaType::IsGadget | QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
- int gadgetTypeId = QMetaType::registerType(name,
- &GadgetTypedDestructor,
- &GadgetTypedConstructor,
- sizeof(GenericGadgetType),
- flags, meta);
+ const auto flags = QMetaType::IsGadget | QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
+ struct TypeInfo : public QtPrivate::QMetaTypeInterface
+ {
+ QMetaObject *mo;
+ };
+
+ auto typeInfo = s_metaTypeInterfaces.emplace_back(new TypeInfo {
+ {
+ 0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0,
+ [](const QtPrivate::QMetaTypeInterface *self) -> const QMetaObject * {
+ return reinterpret_cast<const TypeInfo *>(self)->mo;
+ },
+ name,
+ [](const QtPrivate::QMetaTypeInterface *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); },
+ [](const QtPrivate::QMetaTypeInterface *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
+ [](const QtPrivate::QMetaTypeInterface *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
+ [](const QtPrivate::QMetaTypeInterface *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); },
+ nullptr,
+ nullptr,
+ nullptr,
+ GadgetSaveOperator,
+ GadgetLoadOperator,
+ nullptr
+ },
+ meta
+ }).get();
+ QMetaType gadgetMetaType(typeInfo);
+ dynamicGadgetProperties->m_metatype = gadgetMetaType;
+ int gadgetTypeId = QMetaType(typeInfo).id();
QVERIFY(gadgetTypeId > 0);
- QMetaType::registerStreamOperators(gadgetTypeId, &GadgetSaveOperator, &GadgetLoadOperator);
s_managedTypes[gadgetTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{meta, [](QMetaObject *ptr){ ::free(ptr); }});
}
@@ -342,6 +390,7 @@ struct Bar
++failureCount;
}
}
+ ~Bar() {}
public:
static int failureCount;
@@ -349,11 +398,12 @@ public:
int Bar::failureCount = 0;
+#if QT_CONFIG(thread)
class MetaTypeTorturer: public QThread
{
Q_OBJECT
protected:
- void run()
+ void run() override
{
Bar space[1];
space[0].~Bar();
@@ -365,67 +415,70 @@ protected:
const QByteArray name = "Bar" + QByteArray::number(i) + postFix;
const char *nm = name.constData();
int tp = qRegisterMetaType<Bar>(nm);
-#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
- pthread_yield();
-#endif
QMetaType info(tp);
if (!info.isValid()) {
++failureCount;
qWarning() << "Wrong typeInfo returned for" << tp;
}
- if (!info.isRegistered()) {
+ if (info.flags() != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction |
+ QMetaType::NeedsCopyConstruction | QMetaType::NeedsMoveConstruction)) {
++failureCount;
- qWarning() << name << "is not a registered metatype";
+ qWarning() << "Wrong typeInfo returned for" << tp << "got"
+ << Qt::showbase << Qt::hex << info.flags();
}
- if (QMetaType::typeFlags(tp) != (QMetaType::NeedsConstruction | QMetaType::NeedsDestruction)) {
+ if (!info.isRegistered()) {
++failureCount;
- qWarning() << "Wrong typeInfo returned for" << tp;
+ qWarning() << name << "is not a registered metatype";
}
if (!QMetaType::isRegistered(tp)) {
++failureCount;
qWarning() << name << "is not a registered metatype";
}
- if (QMetaType::type(nm) != tp) {
+ if (QMetaType::fromName(nm).id() != tp) {
++failureCount;
qWarning() << "Wrong metatype returned for" << name;
}
- if (QMetaType::typeName(tp) != name) {
- ++failureCount;
- qWarning() << "Wrong typeName returned for" << tp;
- }
- void *buf1 = QMetaType::create(tp, 0);
- void *buf2 = QMetaType::create(tp, buf1);
- void *buf3 = info.create(tp, 0);
- void *buf4 = info.create(tp, buf1);
- QMetaType::construct(tp, space, 0);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *buf1 = QMetaType::create(tp, nullptr);
+ void *buf2 = QMetaType::create(tp, buf1);
+ QMetaType::construct(tp, space, nullptr);
QMetaType::destruct(tp, space);
QMetaType::construct(tp, space, buf1);
QMetaType::destruct(tp, space);
- info.construct(space, 0);
- info.destruct(space);
- info.construct(space, buf1);
- info.destruct(space);
-
if (!buf1) {
++failureCount;
- qWarning() << "Null buffer returned by QMetaType::create(tp, 0)";
+ qWarning() << "Null buffer returned by QMetaType::create(tp, nullptr)";
}
if (!buf2) {
++failureCount;
qWarning() << "Null buffer returned by QMetaType::create(tp, buf)";
}
+
+ QMetaType::destroy(tp, buf1);
+ QMetaType::destroy(tp, buf2);
+QT_WARNING_POP
+#endif
+
+ void *buf3 = info.create(nullptr);
+ void *buf4 = info.create(buf3);
+
+ info.construct(space, nullptr);
+ info.destruct(space);
+ info.construct(space, buf3);
+ info.destruct(space);
+
if (!buf3) {
++failureCount;
- qWarning() << "Null buffer returned by info.create(tp, 0)";
+ qWarning() << "Null buffer returned by info.create(nullptr)";
}
if (!buf4) {
++failureCount;
- qWarning() << "Null buffer returned by infocreate(tp, buf)";
+ qWarning() << "Null buffer returned by info.create(buf)";
}
- QMetaType::destroy(tp, buf1);
- QMetaType::destroy(tp, buf2);
+
info.destroy(buf3);
info.destroy(buf4);
}
@@ -455,10 +508,11 @@ void tst_QMetaType::threadSafety()
QCOMPARE(t3.failureCount, 0);
QCOMPARE(Bar::failureCount, 0);
}
+#endif
namespace TestSpace
{
- struct Foo { double d; };
+ struct Foo { double d; public: ~Foo() {} };
struct QungTfu {};
}
Q_DECLARE_METATYPE(TestSpace::Foo)
@@ -473,20 +527,27 @@ void tst_QMetaType::namespaces()
QCOMPARE(qvariant_cast<TestSpace::Foo>(v).d, 11.12);
int qungTfuId = qRegisterMetaType<ADD_TESTSPACE(QungTfu)>();
- QCOMPARE(QMetaType::typeName(qungTfuId), "TestSpace::QungTfu");
+ QCOMPARE(QMetaType(qungTfuId).name(), "TestSpace::QungTfu");
+}
+
+void tst_QMetaType::id()
+{
+ QCOMPARE(QMetaType(QMetaType::QString).id(), QMetaType::QString);
+ QCOMPARE(QMetaType(::qMetaTypeId<TestSpace::Foo>()).id(), ::qMetaTypeId<TestSpace::Foo>());
+ QCOMPARE(QMetaType::fromType<TestSpace::Foo>().id(), ::qMetaTypeId<TestSpace::Foo>());
}
void tst_QMetaType::qMetaTypeId()
{
QCOMPARE(::qMetaTypeId<QString>(), int(QMetaType::QString));
QCOMPARE(::qMetaTypeId<int>(), int(QMetaType::Int));
- QCOMPARE(::qMetaTypeId<TestSpace::Foo>(), QMetaType::type("TestSpace::Foo"));
+ QCOMPARE(::qMetaTypeId<TestSpace::Foo>(), QMetaType::fromType<TestSpace::Foo>().id());
- QCOMPARE(::qMetaTypeId<char>(), QMetaType::type("char"));
- QCOMPARE(::qMetaTypeId<uchar>(), QMetaType::type("unsigned char"));
- QCOMPARE(::qMetaTypeId<signed char>(), QMetaType::type("signed char"));
+ QCOMPARE(::qMetaTypeId<char>(), QMetaType::fromType<char>().id());
+ QCOMPARE(::qMetaTypeId<uchar>(), QMetaType::fromType<unsigned char>().id());
+ QCOMPARE(::qMetaTypeId<signed char>(), QMetaType::fromType<signed char>().id());
QVERIFY(::qMetaTypeId<signed char>() != ::qMetaTypeId<char>());
- QCOMPARE(::qMetaTypeId<qint8>(), QMetaType::type("qint8"));
+ QCOMPARE(::qMetaTypeId<qint8>(), QMetaType::fromType<qint8>().id());
}
void tst_QMetaType::properties()
@@ -498,34 +559,28 @@ void tst_QMetaType::properties()
QCOMPARE(v.typeName(), "QVariantList");
QList<QVariant> values = v.toList();
- QCOMPARE(values.count(), 2);
+ QCOMPARE(values.size(), 2);
QCOMPARE(values.at(0).toInt(), 42);
values << 43 << "world";
QVERIFY(setProperty("prop", values));
v = property("prop");
- QCOMPARE(v.toList().count(), 4);
+ QCOMPARE(v.toList().size(), 4);
}
-template <typename T>
-struct Whity { T t; };
-
-Q_DECLARE_METATYPE( Whity < int > )
-Q_DECLARE_METATYPE(Whity<double>)
-
void tst_QMetaType::normalizedTypes()
{
int WhityIntId = ::qMetaTypeId<Whity<int> >();
int WhityDoubleId = ::qMetaTypeId<Whity<double> >();
- QCOMPARE(QMetaType::type("Whity<int>"), WhityIntId);
- QCOMPARE(QMetaType::type(" Whity < int > "), WhityIntId);
- QCOMPARE(QMetaType::type("Whity<int >"), WhityIntId);
+ QCOMPARE(QMetaType::fromName("Whity<int>").id(), WhityIntId);
+ QCOMPARE(QMetaType::fromName(" Whity < int > ").id(), WhityIntId);
+ QCOMPARE(QMetaType::fromName("Whity<int >").id(), WhityIntId);
- QCOMPARE(QMetaType::type("Whity<double>"), WhityDoubleId);
- QCOMPARE(QMetaType::type(" Whity< double > "), WhityDoubleId);
- QCOMPARE(QMetaType::type("Whity<double >"), WhityDoubleId);
+ QCOMPARE(QMetaType::fromName("Whity<double>").id(), WhityDoubleId);
+ QCOMPARE(QMetaType::fromName(" Whity< double > ").id(), WhityDoubleId);
+ QCOMPARE(QMetaType::fromName("Whity<double >").id(), WhityDoubleId);
QCOMPARE(qRegisterMetaType<Whity<int> >(" Whity < int > "), WhityIntId);
QCOMPARE(qRegisterMetaType<Whity<int> >("Whity<int>"), WhityIntId);
@@ -539,6 +594,21 @@ void tst_QMetaType::normalizedTypes()
#define TYPENAME_DATA(MetaTypeName, MetaTypeId, RealType)\
QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << #RealType;
+namespace enumerations {
+ enum Test { a = 0 };
+}
+
+static void ignoreInvalidMetaTypeWarning(int typeId)
+{
+ if (typeId < 0 || typeId > QMetaType::User + 500 ||
+ (typeId > QMetaType::LastCoreType && typeId < QMetaType::FirstGuiType) ||
+ (typeId > QMetaType::LastGuiType && typeId < QMetaType::FirstWidgetsType) ||
+ (typeId > QMetaType::LastWidgetsType && typeId < QMetaType::User)) {
+ QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: "
+ + QByteArray::number(typeId));
+ }
+}
+
void tst_QMetaType::typeName_data()
{
QTest::addColumn<int>("aType");
@@ -558,11 +628,13 @@ void tst_QMetaType::typeName_data()
QTest::newRow("124125534") << 124125534 << QString();
// automatic registration
- QTest::newRow("QList<int>") << ::qMetaTypeId<QList<int> >() << QString::fromLatin1("QList<int>");
- QTest::newRow("QHash<int,int>") << ::qMetaTypeId<QHash<int, int> >() << QString::fromLatin1("QHash<int,int>");
- QTest::newRow("QMap<int,int>") << ::qMetaTypeId<QMap<int, int> >() << QString::fromLatin1("QMap<int,int>");
- QTest::newRow("QVector<QList<int>>") << ::qMetaTypeId<QVector<QList<int> > >() << QString::fromLatin1("QVector<QList<int> >");
- QTest::newRow("QVector<QMap<int,int>>") << ::qMetaTypeId<QVector<QMap<int, int> > >() << QString::fromLatin1("QVector<QMap<int,int> >");
+ QTest::newRow("QHash<int,int>") << ::qMetaTypeId<QHash<int, int>>() << QString::fromLatin1("QHash<int,int>");
+ QTest::newRow("QMap<int,int>") << ::qMetaTypeId<QMap<int, int>>() << QString::fromLatin1("QMap<int,int>");
+ QTest::newRow("QList<QMap<int,int>>") << ::qMetaTypeId<QList<QMap<int, int>>>() << QString::fromLatin1("QList<QMap<int,int>>");
+
+ // automatic registration with automatic QList to QList aliasing
+ QTest::newRow("QList<int>") << ::qMetaTypeId<QList<int>>() << QString::fromLatin1("QList<int>");
+ QTest::newRow("QList<QList<int>>") << ::qMetaTypeId<QList<QList<int>>>() << QString::fromLatin1("QList<QList<int>>");
QTest::newRow("CustomQObject*") << ::qMetaTypeId<CustomQObject*>() << QString::fromLatin1("CustomQObject*");
QTest::newRow("CustomGadget") << ::qMetaTypeId<CustomGadget>() << QString::fromLatin1("CustomGadget");
@@ -573,6 +645,8 @@ void tst_QMetaType::typeName_data()
// template instance class derived from Q_GADGET enabled class
QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << QString::fromLatin1("GadgetDerivedAndTyped<int>");
QTest::newRow("GadgetDerivedAndTyped<int>*") << ::qMetaTypeId<GadgetDerivedAndTyped<int>*>() << QString::fromLatin1("GadgetDerivedAndTyped<int>*");
+
+ QTest::newRow("msvcKeywordPartOfName") << ::qMetaTypeId<enumerations::Test>() << QString::fromLatin1("enumerations::Test");
}
void tst_QMetaType::typeName()
@@ -580,12 +654,23 @@ void tst_QMetaType::typeName()
QFETCH(int, aType);
QFETCH(QString, aTypeName);
- const char *rawname = QMetaType::typeName(aType);
+ if (aType >= QMetaType::FirstWidgetsType)
+ QSKIP("The test doesn't link against QtWidgets.");
+
+ ignoreInvalidMetaTypeWarning(aType);
+ const char *rawname = QMetaType(aType).name();
QString name = QString::fromLatin1(rawname);
QCOMPARE(name, aTypeName);
QCOMPARE(name.toLatin1(), QMetaObject::normalizedType(name.toLatin1().constData()));
QCOMPARE(rawname == nullptr, aTypeName.isNull());
+
+ ignoreInvalidMetaTypeWarning(aType);
+ QMetaType mt(aType);
+ if (mt.isValid()) { // Gui type are not valid
+ QCOMPARE(QString::fromLatin1(QMetaType(aType).name()), aTypeName);
+ }
+
}
void tst_QMetaType::type_data()
@@ -612,10 +697,10 @@ void tst_QMetaType::type()
QFETCH(int, aType);
QFETCH(QByteArray, aTypeName);
- // QMetaType::type(QByteArray)
- QCOMPARE(QMetaType::type(aTypeName), aType);
- // QMetaType::type(const char *)
- QCOMPARE(QMetaType::type(aTypeName.constData()), aType);
+ if (aType >= QMetaType::FirstWidgetsType)
+ QSKIP("The test doesn't link against QtWidgets.");
+ QCOMPARE(QMetaType::fromName(aTypeName).id(), aType);
+ QCOMPARE(QMetaType::fromName(aTypeName.constData()).id(), aType);
}
void tst_QMetaType::type_fromSubString_data()
@@ -640,33 +725,34 @@ void tst_QMetaType::type_fromSubString()
QFETCH(int, size);
QFETCH(int, expectedType);
QByteArray ba = QByteArray::fromRawData(types + offset, size);
- QCOMPARE(QMetaType::type(ba), expectedType);
+ QCOMPARE(QMetaType::fromName(ba).id(), expectedType);
}
namespace {
template <typename T>
struct static_assert_trigger {
- Q_STATIC_ASSERT(( QMetaTypeId2<T>::IsBuiltIn ));
+ static_assert(( QMetaTypeId2<T>::IsBuiltIn ));
enum { value = true };
};
}
#define CHECK_BUILTIN(MetaTypeName, MetaTypeId, RealType) static_assert_trigger< RealType >::value &&
-Q_STATIC_ASSERT(( FOR_EACH_CORE_METATYPE(CHECK_BUILTIN) true ));
+static_assert(( FOR_EACH_CORE_METATYPE(CHECK_BUILTIN) true ));
#undef CHECK_BUILTIN
-Q_STATIC_ASSERT(( QMetaTypeId2<QList<QVariant> >::IsBuiltIn));
-Q_STATIC_ASSERT(( QMetaTypeId2<QMap<QString,QVariant> >::IsBuiltIn));
-Q_STATIC_ASSERT(( QMetaTypeId2<QObject*>::IsBuiltIn));
-Q_STATIC_ASSERT((!QMetaTypeId2<tst_QMetaType*>::IsBuiltIn)); // QObject subclass
-Q_STATIC_ASSERT((!QMetaTypeId2<QList<int> >::IsBuiltIn));
-Q_STATIC_ASSERT((!QMetaTypeId2<QMap<int,int> >::IsBuiltIn));
-Q_STATIC_ASSERT((!QMetaTypeId2<QMetaType::Type>::IsBuiltIn));
+static_assert(( QMetaTypeId2<QList<QVariant> >::IsBuiltIn));
+static_assert(( QMetaTypeId2<QMap<QString,QVariant> >::IsBuiltIn));
+static_assert(( QMetaTypeId2<QObject*>::IsBuiltIn));
+static_assert((!QMetaTypeId2<tst_QMetaType*>::IsBuiltIn)); // QObject subclass
+static_assert((!QMetaTypeId2<QList<int> >::IsBuiltIn));
+static_assert((!QMetaTypeId2<QMap<int,int> >::IsBuiltIn));
+static_assert((!QMetaTypeId2<QMetaType::Type>::IsBuiltIn));
void tst_QMetaType::create_data()
{
QTest::addColumn<int>("type");
+ QTest::newRow("unknown-type") << int(QMetaType::UnknownType);
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
- QTest::newRow(QMetaType::typeName(QMetaType::MetaTypeName)) << int(QMetaType::MetaTypeName);
+ QTest::newRow(QMetaType(QMetaType::MetaTypeName).name()) << int(QMetaType::MetaTypeName);
FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
#undef ADD_METATYPE_TEST_ROW
}
@@ -675,27 +761,36 @@ template<int ID>
static void testCreateHelper()
{
typedef typename MetaEnumToType<ID>::Type Type;
- QMetaType info(ID);
+ auto expected = std::unique_ptr<Type>(DefaultValueFactory<ID>::create());
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
void *actual1 = QMetaType::create(ID);
+ auto cleanup1 = qScopeGuard([actual1]() {
+ QMetaType::destroy(ID, actual1);
+ });
+ QCOMPARE(*static_cast<Type *>(actual1), *expected);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QMetaType info(ID);
void *actual2 = info.create();
- if (DefaultValueTraits<ID>::IsInitialized) {
- Type *expected = DefaultValueFactory<ID>::create();
- QCOMPARE(*static_cast<Type *>(actual1), *expected);
- QCOMPARE(*static_cast<Type *>(actual2), *expected);
- delete expected;
- }
- QMetaType::destroy(ID, actual1);
- info.destroy(actual2);
+ auto cleanup2 = qScopeGuard([&info, actual2]() {
+ info.destroy(actual2);
+ });
+ QCOMPARE(*static_cast<Type *>(actual2), *expected);
}
template<>
void testCreateHelper<QMetaType::Void>()
{
- void *actual = QMetaType::create(QMetaType::Void);
- if (DefaultValueTraits<QMetaType::Void>::IsInitialized) {
- QVERIFY(DefaultValueFactory<QMetaType::Void>::create());
- }
- QMetaType::destroy(QMetaType::Void, actual);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *actual1 = QMetaType::create(QMetaType::Void);
+ QMetaType::destroy(QMetaType::Void, actual1);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QMetaType info(QMetaType::Void);
+ void *actual2 = info.create();
+ info.destroy(actual2);
}
@@ -708,6 +803,10 @@ void tst_QMetaType::create()
static TypeTestFunction get(int type)
{
switch (type) {
+ case QMetaType::UnknownType:
+ return []() {
+ QCOMPARE(QMetaType().create(), nullptr);
+ };
#define RETURN_CREATE_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
case QMetaType::MetaTypeName: \
return testCreateHelper<QMetaType::MetaTypeName>;
@@ -726,15 +825,22 @@ template<int ID>
static void testCreateCopyHelper()
{
typedef typename MetaEnumToType<ID>::Type Type;
- Type *expected = TestValueFactory<ID>::create();
- QMetaType info(ID);
- void *actual1 = QMetaType::create(ID, expected);
- void *actual2 = info.create(expected);
+ auto expected = std::unique_ptr<Type>(TestValueFactory<ID>::create());
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *actual1 = QMetaType::create(ID, expected.get());
+ auto cleanup1 = qScopeGuard([actual1]() {
+ QMetaType::destroy(ID, actual1);
+ });
QCOMPARE(*static_cast<Type *>(actual1), *expected);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QMetaType info(ID);
+ void *actual2 = info.create(expected.get());
+ auto cleanup2 = qScopeGuard([&info, actual2]() {
+ info.destroy(actual2);
+ });
QCOMPARE(*static_cast<Type *>(actual2), *expected);
- QMetaType::destroy(ID, actual1);
- info.destroy(actual2);
- delete expected;
}
template<>
@@ -742,9 +848,22 @@ void testCreateCopyHelper<QMetaType::Void>()
{
typedef MetaEnumToType<QMetaType::Void>::Type Type;
Type *expected = TestValueFactory<QMetaType::Void>::create();
- void *actual = QMetaType::create(QMetaType::Void, expected);
- QCOMPARE(static_cast<Type *>(actual), expected);
- QMetaType::destroy(QMetaType::Void, actual);
+ QCOMPARE(expected, nullptr); // we do not need to delete it
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *actual1 = QMetaType::create(QMetaType::Void, expected);
+ auto cleanup1 = qScopeGuard([actual1]() {
+ QMetaType::destroy(QMetaType::Void, actual1);
+ });
+ QCOMPARE(static_cast<Type *>(actual1), expected);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QMetaType info(QMetaType::Void);
+ void *actual2 = info.create(expected);
+ auto cleanup2 = qScopeGuard([&info, actual2]() {
+ info.destroy(actual2);
+ });
+ QCOMPARE(static_cast<Type *>(actual2), expected);
}
void tst_QMetaType::createCopy_data()
@@ -759,6 +878,11 @@ void tst_QMetaType::createCopy()
static TypeTestFunction get(int type)
{
switch (type) {
+ case QMetaType::UnknownType:
+ return []() {
+ char buf[1] = {};
+ QCOMPARE(QMetaType().create(&buf), nullptr);
+ };
#define RETURN_CREATE_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
case QMetaType::MetaTypeName: \
return testCreateCopyHelper<QMetaType::MetaTypeName>;
@@ -773,6 +897,11 @@ FOR_EACH_CORE_METATYPE(RETURN_CREATE_COPY_FUNCTION)
TypeTestFunctionGetter::get(type)();
}
+template<typename T>
+constexpr size_t getSize = sizeof(T);
+template<>
+constexpr size_t getSize<void> = 0;
+
void tst_QMetaType::sizeOf_data()
{
QTest::addColumn<int>("type");
@@ -780,7 +909,7 @@ void tst_QMetaType::sizeOf_data()
QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << size_t(0);
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
- QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << size_t(QTypeInfo<RealType>::sizeOf);
+ QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << getSize<RealType>;
FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
#undef ADD_METATYPE_TEST_ROW
@@ -797,7 +926,9 @@ void tst_QMetaType::sizeOf()
{
QFETCH(int, type);
QFETCH(size_t, size);
- QCOMPARE(size_t(QMetaType::sizeOf(type)), size);
+ ignoreInvalidMetaTypeWarning(type);
+ QMetaType metaType(type);
+ QCOMPARE(size_t(metaType.sizeOf()), size);
}
void tst_QMetaType::sizeOfStaticLess_data()
@@ -809,20 +940,52 @@ void tst_QMetaType::sizeOfStaticLess()
{
QFETCH(int, type);
QFETCH(size_t, size);
+ ignoreInvalidMetaTypeWarning(type);
QCOMPARE(size_t(QMetaType(type).sizeOf()), size);
}
-struct CustomMovable {};
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(CustomMovable, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-Q_DECLARE_METATYPE(CustomMovable);
+template <typename T>
+auto getAlignOf()
+{
+ if constexpr (std::is_same_v<T, void>)
+ return 0;
+ else
+ return alignof(T);
+}
+
+void tst_QMetaType::alignOf_data()
+{
+ QTest::addColumn<int>("type");
+ QTest::addColumn<size_t>("size");
+
+ QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << size_t(0);
+#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
+ QTest::newRow(#RealType) << int(QMetaType::MetaTypeName) << size_t(getAlignOf<RealType>());
+FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
+#undef ADD_METATYPE_TEST_ROW
+
+ QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << alignof(Whity<double>);
+ QTest::newRow("Whity<int>") << ::qMetaTypeId<Whity<int> >() << alignof(Whity<int>);
+ QTest::newRow("Testspace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << alignof(TestSpace::Foo);
+
+ QTest::newRow("-1") << -1 << size_t(0);
+ QTest::newRow("-124125534") << -124125534 << size_t(0);
+ QTest::newRow("124125534") << 124125534 << size_t(0);
+}
+
+void tst_QMetaType::alignOf()
+{
+ QFETCH(int, type);
+ QFETCH(size_t, size);
+ ignoreInvalidMetaTypeWarning(type);
+ QCOMPARE(size_t(QMetaType(type).alignOf()), size);
+}
class CustomObject : public QObject
{
Q_OBJECT
public:
- CustomObject(QObject *parent = 0)
+ CustomObject(QObject *parent = nullptr)
: QObject(parent)
{
@@ -836,7 +999,7 @@ class CustomMultiInheritanceObject : public QObject, SecondBase
{
Q_OBJECT
public:
- CustomMultiInheritanceObject(QObject *parent = 0)
+ CustomMultiInheritanceObject(QObject *parent = nullptr)
: QObject(parent)
{
@@ -844,13 +1007,15 @@ public:
};
Q_DECLARE_METATYPE(CustomMultiInheritanceObject*);
-class C { char _[4]; };
-class M { char _[4]; };
-class P { char _[4]; };
+class C { Q_DECL_UNUSED_MEMBER char _[4]; public: C() = default; C(const C&) {} };
+class M { Q_DECL_UNUSED_MEMBER char _[4]; public: M() {} };
+class P { Q_DECL_UNUSED_MEMBER char _[4]; };
QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(M, Q_MOVABLE_TYPE);
+#if defined(Q_CC_GNU) && Q_CC_GNU < 501
+Q_DECLARE_TYPEINFO(M, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(P, Q_PRIMITIVE_TYPE);
+#endif
QT_END_NAMESPACE
// avoid the comma:
@@ -877,121 +1042,214 @@ Q_DECLARE_METATYPE(QPairPP)
enum FlagsDataEnum {};
Q_DECLARE_METATYPE(FlagsDataEnum);
+template <typename T> void addFlagsRow(const char *name, int id = qMetaTypeId<T>())
+{
+ QTest::newRow(name)
+ << id
+ << bool(QTypeInfo<T>::isRelocatable)
+ << bool(!std::is_default_constructible_v<T> || !QTypeInfo<T>::isValueInitializationBitwiseZero)
+ << bool(!std::is_trivially_copy_constructible_v<T>)
+ << bool(!std::is_trivially_destructible_v<T>)
+ << bool(QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value)
+ << bool(std::is_enum<T>::value)
+ << false;
+}
+
void tst_QMetaType::flags_data()
{
QTest::addColumn<int>("type");
- QTest::addColumn<bool>("isMovable");
- QTest::addColumn<bool>("isComplex");
+ QTest::addColumn<bool>("isRelocatable");
+ QTest::addColumn<bool>("needsConstruction");
+ QTest::addColumn<bool>("needsCopyConstruction");
+ QTest::addColumn<bool>("needsDestruction");
QTest::addColumn<bool>("isPointerToQObject");
QTest::addColumn<bool>("isEnum");
+ QTest::addColumn<bool>("isQmlList");
+
+ // invalid ids.
+ QTest::newRow("-1") << -1 << false << false << false << false << false << false << false;
+ QTest::newRow("-124125534") << -124125534 << false << false << false << false << false << false << false;
+ QTest::newRow("124125534") << 124125534 << false << false << false << false << false << false << false;
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
- QTest::newRow(#RealType) << MetaTypeId \
- << bool(QTypeInfoQuery<RealType>::isRelocatable) \
- << bool(QTypeInfoQuery<RealType>::isComplex) \
- << bool(QtPrivate::IsPointerToTypeDerivedFromQObject<RealType>::Value) \
- << bool(std::is_enum<RealType>::value);
+ addFlagsRow<RealType>(#RealType, MetaTypeId);
+QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(ADD_METATYPE_TEST_ROW)
QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW)
QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW)
QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW)
#undef ADD_METATYPE_TEST_ROW
- QTest::newRow("TestSpace::Foo") << ::qMetaTypeId<TestSpace::Foo>() << false << true << false << false;
- QTest::newRow("Whity<double>") << ::qMetaTypeId<Whity<double> >() << false << true << false << false;
- QTest::newRow("CustomMovable") << ::qMetaTypeId<CustomMovable>() << true << true << false << false;
- QTest::newRow("CustomObject*") << ::qMetaTypeId<CustomObject*>() << true << false << true << false;
- QTest::newRow("CustomMultiInheritanceObject*") << ::qMetaTypeId<CustomMultiInheritanceObject*>() << true << false << true << false;
- QTest::newRow("QPair<C,C>") << ::qMetaTypeId<QPair<C,C> >() << false << true << false << false;
- QTest::newRow("QPair<C,M>") << ::qMetaTypeId<QPair<C,M> >() << false << true << false << false;
- QTest::newRow("QPair<C,P>") << ::qMetaTypeId<QPair<C,P> >() << false << true << false << false;
- QTest::newRow("QPair<M,C>") << ::qMetaTypeId<QPair<M,C> >() << false << true << false << false;
- QTest::newRow("QPair<M,M>") << ::qMetaTypeId<QPair<M,M> >() << true << true << false << false;
- QTest::newRow("QPair<M,P>") << ::qMetaTypeId<QPair<M,P> >() << true << true << false << false;
- QTest::newRow("QPair<P,C>") << ::qMetaTypeId<QPair<P,C> >() << false << true << false << false;
- QTest::newRow("QPair<P,M>") << ::qMetaTypeId<QPair<P,M> >() << true << true << false << false;
- QTest::newRow("QPair<P,P>") << ::qMetaTypeId<QPair<P,P> >() << true << false << false << false;
- QTest::newRow("FlagsDataEnum") << ::qMetaTypeId<FlagsDataEnum>() << true << false << false << true;
-
- // invalid ids.
- QTest::newRow("-1") << -1 << false << false << false << false;
- QTest::newRow("-124125534") << -124125534 << false << false << false << false;
- QTest::newRow("124125534") << 124125534 << false << false << false << false;
+ addFlagsRow<TestSpace::Foo>("TestSpace::Foo");
+ addFlagsRow<Whity<double> >("Whity<double> ");
+ addFlagsRow<CustomMovable>("CustomMovable");
+ addFlagsRow<CustomObject*>("CustomObject*");
+ addFlagsRow<CustomMultiInheritanceObject*>("CustomMultiInheritanceObject*");
+ addFlagsRow<QPair<C,C> >("QPair<C,C>");
+ addFlagsRow<QPair<C,M> >("QPair<C,M>");
+ addFlagsRow<QPair<C,P> >("QPair<C,P>");
+ addFlagsRow<QPair<M,C> >("QPair<M,C>");
+ addFlagsRow<QPair<M,M> >("QPair<M,M>");
+ addFlagsRow<QPair<M,P> >("QPair<M,P>");
+ addFlagsRow<QPair<P,C> >("QPair<P,C>");
+ addFlagsRow<QPair<P,M> >("QPair<P,M>");
+ addFlagsRow<QPair<P,P> >("QPair<P,P>");
+ addFlagsRow<FlagsDataEnum>("FlagsDataEnum");
}
void tst_QMetaType::flags()
{
QFETCH(int, type);
- QFETCH(bool, isMovable);
- QFETCH(bool, isComplex);
+ QFETCH(bool, isRelocatable);
+ QFETCH(bool, needsConstruction);
+ QFETCH(bool, needsCopyConstruction);
+ QFETCH(bool, needsDestruction);
QFETCH(bool, isPointerToQObject);
QFETCH(bool, isEnum);
+ QFETCH(bool, isQmlList);
- QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsConstruction), isComplex);
- QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::NeedsDestruction), isComplex);
- QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::MovableType), isMovable);
- QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::PointerToQObject), isPointerToQObject);
- QCOMPARE(bool(QMetaType::typeFlags(type) & QMetaType::IsEnumeration), isEnum);
+ ignoreInvalidMetaTypeWarning(type);
+ QMetaType meta(type);
+
+ QCOMPARE(bool(meta.flags() & QMetaType::NeedsConstruction), needsConstruction);
+ QCOMPARE(bool(meta.flags() & QMetaType::NeedsCopyConstruction), needsCopyConstruction);
+ QCOMPARE(bool(meta.flags() & QMetaType::NeedsDestruction), needsDestruction);
+ QCOMPARE(bool(meta.flags() & QMetaType::RelocatableType), isRelocatable);
+ QCOMPARE(bool(meta.flags() & QMetaType::PointerToQObject), isPointerToQObject);
+ QCOMPARE(bool(meta.flags() & QMetaType::IsEnumeration), isEnum);
+ QCOMPARE(bool(meta.flags() & QMetaType::IsQmlList), isQmlList);
}
-void tst_QMetaType::flagsStaticLess_data()
+class NonDefaultConstructible
{
- flags_data();
-}
+ NonDefaultConstructible(int) {}
+};
-void tst_QMetaType::flagsStaticLess()
+struct MoveOnly
{
- QFETCH(int, type);
- QFETCH(bool, isMovable);
- QFETCH(bool, isComplex);
-
- int flags = QMetaType(type).flags();
- QCOMPARE(bool(flags & QMetaType::NeedsConstruction), isComplex);
- QCOMPARE(bool(flags & QMetaType::NeedsDestruction), isComplex);
- QCOMPARE(bool(flags & QMetaType::MovableType), isMovable);
-}
-
-void tst_QMetaType::flagsBinaryCompatibility5_0_data()
-{
- // Changing traits of a built-in type is illegal from BC point of view.
- // Traits are saved in code of an application and in the Qt library which means
- // that there may be a mismatch.
- // The test is loading data generated by this code:
- //
- // QByteArray buffer;
- // buffer.reserve(2 * QMetaType::User);
- // for (quint32 i = 0; i < QMetaType::User; ++i) {
- // if (QMetaType::isRegistered(i)) {
- // buffer.append(i);
- // buffer.append(quint32(QMetaType::typeFlags(i)));
- // }
- // }
- // QFile file("/tmp/typeFlags.bin");
- // file.open(QIODevice::WriteOnly);
- // file.write(buffer);
- // file.close();
+ MoveOnly() = default;
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly(MoveOnly &&) = default;
+ MoveOnly &operator=(const MoveOnly &) = delete;
+ MoveOnly &operator=(MoveOnly &&) = default;
+};
+
+class Indestructible
+{
+protected:
+ ~Indestructible() {}
+};
+
+template <typename T> static void addFlags2Row(QMetaType metaType = QMetaType::fromType<T>())
+{
+ QTest::newRow(metaType.name() ? metaType.name() : "UnknownType")
+ << metaType
+ << std::is_default_constructible_v<T>
+ << std::is_copy_constructible_v<T>
+ << std::is_move_constructible_v<T>
+ << std::is_destructible_v<T>
+ << (QTypeTraits::has_operator_equal<T>::value || QTypeTraits::has_operator_less_than<T>::value)
+ << QTypeTraits::has_operator_less_than<T>::value;
+};
+
+void tst_QMetaType::flags2_data()
+{
+ QTest::addColumn<QMetaType>("type");
+ QTest::addColumn<bool>("isDefaultConstructible");
+ QTest::addColumn<bool>("isCopyConstructible");
+ QTest::addColumn<bool>("isMoveConstructible");
+ QTest::addColumn<bool>("isDestructible");
+ QTest::addColumn<bool>("isEqualityComparable");
+ QTest::addColumn<bool>("isOrdered");
+
+ addFlags2Row<void>(QMetaType());
+ addFlags2Row<void>();
+
+#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
+ addFlags2Row<RealType>();
+ QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(ADD_METATYPE_TEST_ROW)
+ QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW)
+ QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW)
+ QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW)
+#undef ADD_METATYPE_TEST_ROW
+
+ addFlags2Row<NonDefaultConstructible>();
+ addFlags2Row<MoveOnly>();
+ addFlags2Row<QObject>();
+ addFlags2Row<Indestructible>();
+}
+
+void tst_QMetaType::flags2()
+{
+ QFETCH(QMetaType, type);
+ QFETCH(bool, isDefaultConstructible);
+ QFETCH(bool, isCopyConstructible);
+ QFETCH(bool, isMoveConstructible);
+ QFETCH(bool, isDestructible);
+ QFETCH(bool, isEqualityComparable);
+ QFETCH(bool, isOrdered);
+
+ QCOMPARE(type.isDefaultConstructible(), isDefaultConstructible);
+ QCOMPARE(type.isCopyConstructible(), isCopyConstructible);
+ QCOMPARE(type.isMoveConstructible(), isMoveConstructible);
+ QCOMPARE(type.isDestructible(), isDestructible);
+ QCOMPARE(type.isEqualityComparable(), isEqualityComparable);
+ QCOMPARE(type.isOrdered(), isOrdered);
+}
+
+void tst_QMetaType::flagsBinaryCompatibility6_0_data()
+{
+// Changing traits of a built-in type is illegal from BC point of view.
+// Traits are saved in code of an application and in the Qt library which means
+// that there may be a mismatch.
+// The test is loading data generated by this code:
+//
+// QList<quint32> buffer;
+// buffer.reserve(2 * QMetaType::User);
+// for (quint32 i = 0; i < QMetaType::LastCoreType; ++i) {
+// if (QMetaType::isRegistered(i)) {
+// buffer.append(i);
+// buffer.append(quint32(QMetaType::typeFlags(i)));
+// }
+// }
+// QFile file("/tmp/typeFlags.bin");
+// file.open(QIODevice::WriteOnly);
+// QDataStream ds(&file);
+// ds << buffer;
+// file.close();
QTest::addColumn<quint32>("id");
QTest::addColumn<quint32>("flags");
QFile file(QFINDTESTDATA("typeFlags.bin"));
- file.open(QIODevice::ReadOnly);
- QByteArray buffer = file.readAll();
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QList<quint32> buffer;
+ QDataStream ds(&file);
+ ds >> buffer;
for (int i = 0; i < buffer.size(); i+=2) {
const quint32 id = buffer.at(i);
const quint32 flags = buffer.at(i + 1);
+ if (id > QMetaType::LastCoreType)
+ continue; // We do not link against QtGui, so we do longer consider such type as registered
QVERIFY2(QMetaType::isRegistered(id), "A type could not be removed in BC way");
- QTest::newRow(QMetaType::typeName(id)) << id << flags;
+ QTest::newRow(QMetaType(id).name()) << id << flags;
}
}
-void tst_QMetaType::flagsBinaryCompatibility5_0()
+void tst_QMetaType::flagsBinaryCompatibility6_0()
{
QFETCH(quint32, id);
QFETCH(quint32, flags);
- quint32 mask_5_0 = 0x1fb; // Only compare the values that were already defined in 5.0
+ const auto currentFlags = QMetaType(id).flags();
+ auto expectedFlags = QMetaType::TypeFlags(flags);
- QCOMPARE(quint32(QMetaType::typeFlags(id)) & mask_5_0, flags & mask_5_0);
+ // Only compare the values that were already defined in 5.0.
+ // In 6.5, some types lost NeedsConstruction and NeedsDestruction, but
+ // that's acceptable if that's because they were trivial
+ quint32 mask_5_0 = 0x1ff & ~quint32(QMetaType::NeedsConstruction | QMetaType::NeedsDestruction
+ | QMetaType::RelocatableType);
+
+ QCOMPARE(quint32(currentFlags) & mask_5_0, quint32(expectedFlags) & mask_5_0);
}
void tst_QMetaType::construct_data()
@@ -1003,47 +1261,61 @@ template<int ID>
static void testConstructHelper()
{
typedef typename MetaEnumToType<ID>::Type Type;
+ auto expected = std::unique_ptr<Type>(DefaultValueFactory<ID>::create());
QMetaType info(ID);
int size = info.sizeOf();
- void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type));
- void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/0);
- void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type));
- void *actual2 = info.construct(storage2, /*copy=*/0);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *storage1 = qMallocAligned(size, alignof(Type));
+ void *actual1 = QMetaType::construct(ID, storage1, /*copy=*/nullptr);
+ auto cleanup1 = qScopeGuard([storage1, actual1]() {
+ QMetaType::destruct(ID, actual1);
+ qFreeAligned(storage1);
+ });
QCOMPARE(actual1, storage1);
+ QCOMPARE(*static_cast<Type *>(actual1), *expected);
+ QCOMPARE(QMetaType::construct(ID, nullptr, /*copy=*/nullptr), nullptr);
+ QMetaType::destruct(ID, nullptr);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ void *storage2 = qMallocAligned(size, alignof(Type));
+ void *actual2 = info.construct(storage2, /*copy=*/nullptr);
+ auto cleanup2 = qScopeGuard([&info, storage2, actual2]() {
+ info.destruct(actual2);
+ qFreeAligned(storage2);
+ });
QCOMPARE(actual2, storage2);
- if (DefaultValueTraits<ID>::IsInitialized) {
- Type *expected = DefaultValueFactory<ID>::create();
- QCOMPARE(*static_cast<Type *>(actual1), *expected);
- QCOMPARE(*static_cast<Type *>(actual2), *expected);
- delete expected;
- }
- QMetaType::destruct(ID, actual1);
- qFreeAligned(storage1);
- info.destruct(actual2);
- qFreeAligned(storage2);
-
- QVERIFY(QMetaType::construct(ID, 0, /*copy=*/0) == 0);
- QMetaType::destruct(ID, 0);
-
- QVERIFY(info.construct(0, /*copy=*/0) == 0);
- info.destruct(0);
+ QCOMPARE(*static_cast<Type *>(actual2), *expected);
+ QCOMPARE(info.construct(nullptr, /*copy=*/nullptr), nullptr);
+ info.destruct(nullptr);
}
template<>
void testConstructHelper<QMetaType::Void>()
{
- /*int size = */ QMetaType::sizeOf(QMetaType::Void);
- void *storage = 0;
- void *actual = QMetaType::construct(QMetaType::Void, storage, /*copy=*/0);
- QCOMPARE(actual, storage);
- if (DefaultValueTraits<QMetaType::Void>::IsInitialized) {
- QVERIFY(DefaultValueFactory<QMetaType::Void>::create());
- }
- QMetaType::destruct(QMetaType::Void, actual);
- qFreeAligned(storage);
-
- QVERIFY(QMetaType::construct(QMetaType::Void, 0, /*copy=*/0) == 0);
- QMetaType::destruct(QMetaType::Void, 0);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *storage1 = nullptr;
+ void *actual1 = QMetaType::construct(QMetaType::Void, storage1, /*copy=*/nullptr);
+ auto cleanup1 = qScopeGuard([storage1, actual1]() {
+ QMetaType::destruct(QMetaType::Void, actual1);
+ qFreeAligned(storage1);
+ });
+ QCOMPARE(actual1, storage1);
+ QCOMPARE(QMetaType::construct(QMetaType::Void, nullptr, /*copy=*/nullptr), nullptr);
+ QMetaType::destruct(QMetaType::Void, nullptr);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QMetaType info(QMetaType::Void);
+ void *storage2 = nullptr;
+ void *actual2 = info.construct(storage2, /*copy=*/nullptr);
+ auto cleanup2 = qScopeGuard([&info, storage2, actual2]() {
+ info.destruct(actual2);
+ qFreeAligned(storage2);
+ });
+ QCOMPARE(actual2, storage2);
+ QVERIFY(info.construct(nullptr, /*copy=*/nullptr) == nullptr);
+ info.destruct(nullptr);
}
void tst_QMetaType::construct()
@@ -1053,6 +1325,11 @@ void tst_QMetaType::construct()
static TypeTestFunction get(int type)
{
switch (type) {
+ case QMetaType::UnknownType:
+ return []() {
+ char buf[1];
+ QCOMPARE(QMetaType().construct(&buf), nullptr);
+ };
#define RETURN_CONSTRUCT_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
case QMetaType::MetaTypeName: \
return testConstructHelper<QMetaType::MetaTypeName>;
@@ -1067,11 +1344,137 @@ FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_FUNCTION)
TypeTestFunctionGetter::get(type)();
}
+
+namespace TriviallyConstructibleTests {
+
+enum Enum0 {};
+enum class Enum1 {};
+
+static_assert(QTypeInfo<int>::isValueInitializationBitwiseZero);
+static_assert(QTypeInfo<double>::isValueInitializationBitwiseZero);
+static_assert(QTypeInfo<Enum0>::isValueInitializationBitwiseZero);
+static_assert(QTypeInfo<Enum1>::isValueInitializationBitwiseZero);
+static_assert(QTypeInfo<int *>::isValueInitializationBitwiseZero);
+static_assert(QTypeInfo<void *>::isValueInitializationBitwiseZero);
+static_assert(QTypeInfo<std::nullptr_t>::isValueInitializationBitwiseZero);
+
+struct A {};
+struct B { B() {} };
+struct C { ~C() {} };
+struct D { D(int) {} };
+struct E { E() {} ~E() {} };
+struct F { int i; };
+struct G { G() : i(0) {} int i; };
+struct H { constexpr H() : i(0) {} int i; };
+struct I { I() : i(42) {} int i; };
+struct J { constexpr J() : i(42) {} int i; };
+struct K { K() : i(0) {} ~K() {} int i; };
+
+static_assert(!QTypeInfo<A>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<B>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<C>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<D>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<E>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<F>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<G>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<H>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<I>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<J>::isValueInitializationBitwiseZero);
+static_assert(!QTypeInfo<K>::isValueInitializationBitwiseZero);
+
+} // namespace TriviallyConstructibleTests
+
+// Value-initializing these trivially constructible types cannot be achieved by
+// memset(0) into their storage. For instance, on Itanium, a pointer to a data
+// member needs to be value-initialized by setting it to -1.
+
+// Fits into QVariant
+struct TrivialTypeNotZeroInitableSmall {
+ int TrivialTypeNotZeroInitableSmall::*pdm;
+};
+
+static_assert(std::is_trivially_default_constructible_v<TrivialTypeNotZeroInitableSmall>);
+static_assert(!QTypeInfo<TrivialTypeNotZeroInitableSmall>::isValueInitializationBitwiseZero);
+static_assert(sizeof(TrivialTypeNotZeroInitableSmall) < sizeof(QVariant)); // also checked more thoroughly below
+
+// Does not fit into QVariant internal storage
+struct TrivialTypeNotZeroInitableBig {
+ int a;
+ double b;
+ char c;
+ int array[42];
+ void (TrivialTypeNotZeroInitableBig::*pmf)();
+ int TrivialTypeNotZeroInitableBig::*pdm;
+};
+
+static_assert(std::is_trivially_default_constructible_v<TrivialTypeNotZeroInitableBig>);
+static_assert(!QTypeInfo<TrivialTypeNotZeroInitableSmall>::isValueInitializationBitwiseZero);
+static_assert(sizeof(TrivialTypeNotZeroInitableBig) > sizeof(QVariant)); // also checked more thoroughly below
+
+void tst_QMetaType::defaultConstructTrivial_QTBUG_109594()
+{
+ // MSVC miscompiles value-initialization of pointers to data members,
+ // https://developercommunity.visualstudio.com/t/Pointer-to-data-member-is-not-initialize/10238905
+ {
+ QMetaType mt = QMetaType::fromType<TrivialTypeNotZeroInitableSmall>();
+ QVERIFY(mt.isDefaultConstructible());
+ auto ptr = static_cast<TrivialTypeNotZeroInitableSmall *>(mt.create());
+ const auto cleanup = qScopeGuard([=] {
+ mt.destroy(ptr);
+ });
+#ifdef Q_CC_MSVC_ONLY
+ QEXPECT_FAIL("", "MSVC compiler bug", Continue);
+#endif
+ QCOMPARE(ptr->pdm, nullptr);
+
+ QVariant v(mt);
+ QVERIFY(QVariant::Private::canUseInternalSpace(mt.iface()));
+ auto obj = v.value<TrivialTypeNotZeroInitableSmall>();
+#ifdef Q_CC_MSVC_ONLY
+ QEXPECT_FAIL("", "MSVC compiler bug", Continue);
+#endif
+ QCOMPARE(obj.pdm, nullptr);
+ }
+
+ {
+ QMetaType mt = QMetaType::fromType<TrivialTypeNotZeroInitableBig>();
+ QVERIFY(mt.isDefaultConstructible());
+ auto ptr = static_cast<TrivialTypeNotZeroInitableBig *>(mt.create());
+ const auto cleanup = qScopeGuard([=] {
+ mt.destroy(ptr);
+ });
+ QCOMPARE(ptr->a, 0);
+ QCOMPARE(ptr->b, 0.0);
+ QCOMPARE(ptr->c, '\0');
+ QCOMPARE(ptr->pmf, nullptr);
+ for (int i : ptr->array)
+ QCOMPARE(i, 0);
+#ifdef Q_CC_MSVC_ONLY
+ QEXPECT_FAIL("", "MSVC compiler bug", Continue);
+#endif
+ QCOMPARE(ptr->pdm, nullptr);
+
+ QVariant v(mt);
+ QVERIFY(!QVariant::Private::canUseInternalSpace(mt.iface()));
+ auto obj = v.value<TrivialTypeNotZeroInitableBig>();
+ QCOMPARE(obj.a, 0);
+ QCOMPARE(obj.b, 0.0);
+ QCOMPARE(obj.c, '\0');
+ QCOMPARE(obj.pmf, nullptr);
+ for (int i : obj.array)
+ QCOMPARE(i, 0);
+#ifdef Q_CC_MSVC_ONLY
+ QEXPECT_FAIL("", "MSVC compiler bug", Continue);
+#endif
+ QCOMPARE(obj.pdm, nullptr);
+ }
+}
+
void tst_QMetaType::typedConstruct()
{
- auto testMetaObjectWriteOnGadget = [](QVariant &gadget, const QVector<GadgetPropertyType> &properties)
+ auto testMetaObjectWriteOnGadget = [](QVariant &gadget, const QList<GadgetPropertyType> &properties)
{
- auto metaObject = QMetaType::metaObjectForType(gadget.userType());
+ auto metaObject = QMetaType(gadget.userType()).metaObject();
QVERIFY(metaObject != nullptr);
QCOMPARE(metaObject->methodCount(), 0);
QCOMPARE(metaObject->propertyCount(), properties.size());
@@ -1083,9 +1486,9 @@ void tst_QMetaType::typedConstruct()
}
};
- auto testMetaObjectReadOnGadget = [](QVariant gadget, const QVector<GadgetPropertyType> &properties)
+ auto testMetaObjectReadOnGadget = [](QVariant gadget, const QList<GadgetPropertyType> &properties)
{
- auto metaObject = QMetaType::metaObjectForType(gadget.userType());
+ auto metaObject = QMetaType(gadget.userType()).metaObject();
QVERIFY(metaObject != nullptr);
QCOMPARE(metaObject->methodCount(), 0);
QCOMPARE(metaObject->propertyCount(), properties.size());
@@ -1093,34 +1496,34 @@ void tst_QMetaType::typedConstruct()
auto prop = metaObject->property(i);
QCOMPARE(properties[i].name, prop.name());
QCOMPARE(properties[i].type, prop.typeName());
- if (!QMetaType::typeFlags(prop.userType()).testFlag(QMetaType::IsGadget))
+ if (!QMetaType(prop.userType()).flags().testFlag(QMetaType::IsGadget))
QCOMPARE(properties[i].testData, prop.readOnGadget(gadget.constData()));
}
};
- QVector<GadgetPropertyType> dynamicGadget1 = {
+ QList<GadgetPropertyType> dynamicGadget1 = {
{"int", "int_prop", 34526},
{"float", "float_prop", 1.23f},
{"QString", "string_prop", QString{"Test QString"}}
};
registerGadget("DynamicGadget1", dynamicGadget1);
- QVariant testGadget1(QVariant::Type(QMetaType::type("DynamicGadget1")));
+ QVariant testGadget1(QMetaType::fromName("DynamicGadget1"));
testMetaObjectWriteOnGadget(testGadget1, dynamicGadget1);
testMetaObjectReadOnGadget(testGadget1, dynamicGadget1);
- QVector<GadgetPropertyType> dynamicGadget2 = {
+ QList<GadgetPropertyType> dynamicGadget2 = {
{"int", "int_prop", 512},
{"double", "double_prop", 4.56},
{"QString", "string_prop", QString{"Another String"}},
{"DynamicGadget1", "dynamicGadget1_prop", testGadget1}
};
registerGadget("DynamicGadget2", dynamicGadget2);
- QVariant testGadget2(QVariant::Type(QMetaType::type("DynamicGadget2")));
+ QVariant testGadget2(QMetaType::fromName("DynamicGadget2"));
testMetaObjectWriteOnGadget(testGadget2, dynamicGadget2);
testMetaObjectReadOnGadget(testGadget2, dynamicGadget2);
- auto g2mo = QMetaType::metaObjectForType(testGadget2.userType());
+ auto g2mo = QMetaType(testGadget2.userType()).metaObject();
auto dynamicGadget1_prop = g2mo->property(g2mo->indexOfProperty("dynamicGadget1_prop"));
testMetaObjectReadOnGadget(dynamicGadget1_prop.readOnGadget(testGadget2.constData()), dynamicGadget1);
@@ -1131,18 +1534,29 @@ void tst_QMetaType::typedConstruct()
auto dynamicGadgetProperties = std::make_shared<GenericPODType>();
dynamicGadgetProperties->podData = myPodTesData;
const auto flags = QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
- int podTypeId = QMetaType::registerType(podTypeName,
- &GadgetTypedDestructor,
- &GadgetTypedConstructor,
- sizeof(GenericGadgetType),
- flags, nullptr);
+ using TypeInfo = QtPrivate::QMetaTypeInterface;
+ auto typeInfo = s_metaTypeInterfaces.emplace_back(new TypeInfo {
+ 0, alignof(GenericGadgetType), sizeof(GenericGadgetType), uint(flags), 0, nullptr, podTypeName,
+ [](const TypeInfo *self, void *where) { GadgetTypedConstructor(self->typeId, where, nullptr); },
+ [](const TypeInfo *self, void *where, const void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
+ [](const TypeInfo *self, void *where, void *copy) { GadgetTypedConstructor(self->typeId, where, copy); },
+ [](const TypeInfo *self, void *ptr) { GadgetTypedDestructor(self->typeId, ptr); },
+ nullptr,
+ nullptr,
+ nullptr,
+ GadgetSaveOperator,
+ GadgetLoadOperator,
+ nullptr
+ }).get();
+ QMetaType metatype(typeInfo);
+ dynamicGadgetProperties->m_metatype = metatype;
+ int podTypeId = metatype.id();
QVERIFY(podTypeId > 0);
- QMetaType::registerStreamOperators(podTypeId, &GadgetSaveOperator, &GadgetLoadOperator);
s_managedTypes[podTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{});
// Test POD
- QCOMPARE(podTypeId, QMetaType::type(podTypeName));
- QVariant podVariant{QVariant::Type(podTypeId)};
+ QCOMPARE(podTypeId, QMetaType::fromName(podTypeName).id());
+ QVariant podVariant{QMetaType(podTypeId)};
QCOMPARE(myPodTesData, static_cast<const GenericPODType *>(reinterpret_cast<const BaseGenericType *>(podVariant.constData()))->podData);
QVariant podVariant1{podVariant};
@@ -1155,27 +1569,32 @@ template<int ID>
static void testConstructCopyHelper()
{
typedef typename MetaEnumToType<ID>::Type Type;
- Type *expected = TestValueFactory<ID>::create();
+ auto expected = std::unique_ptr<Type>(TestValueFactory<ID>::create());
QMetaType info(ID);
- int size = QMetaType::sizeOf(ID);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ const int size = QMetaType::sizeOf(ID);
QCOMPARE(info.sizeOf(), size);
- void *storage1 = qMallocAligned(size, Q_ALIGNOF(Type));
- void *actual1 = QMetaType::construct(ID, storage1, expected);
- void *storage2 = qMallocAligned(size, Q_ALIGNOF(Type));
- void *actual2 = info.construct(storage2, expected);
+ void *storage1 = qMallocAligned(size, alignof(Type));
+ void *actual1 = QMetaType::construct(ID, storage1, expected.get());
+ auto cleanup1 = qScopeGuard([storage1, actual1]() {
+ QMetaType::destruct(ID, actual1);
+ qFreeAligned(storage1);
+ });
QCOMPARE(actual1, storage1);
- QCOMPARE(actual2, storage2);
QCOMPARE(*static_cast<Type *>(actual1), *expected);
+ QCOMPARE(QMetaType::construct(ID, nullptr, nullptr), nullptr);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ void *storage2 = qMallocAligned(info.sizeOf(), alignof(Type));
+ void *actual2 = info.construct(storage2, expected.get());
+ auto cleanup2 = qScopeGuard([&info, storage2, actual2]() {
+ info.destruct(actual2);
+ qFreeAligned(storage2);
+ });
+ QCOMPARE(actual2, storage2);
QCOMPARE(*static_cast<Type *>(actual2), *expected);
- QMetaType::destruct(ID, actual1);
- qFreeAligned(storage1);
- info.destruct(actual2);
- qFreeAligned(storage2);
-
- QVERIFY(QMetaType::construct(ID, 0, expected) == 0);
- QVERIFY(info.construct(0, expected) == 0);
-
- delete expected;
+ QCOMPARE(info.construct(nullptr, expected.get()), nullptr);
}
template<>
@@ -1183,14 +1602,28 @@ void testConstructCopyHelper<QMetaType::Void>()
{
typedef MetaEnumToType<QMetaType::Void>::Type Type;
Type *expected = TestValueFactory<QMetaType::Void>::create();
- /* int size = */QMetaType::sizeOf(QMetaType::Void);
- void *storage = 0;
- void *actual = QMetaType::construct(QMetaType::Void, storage, expected);
- QCOMPARE(actual, storage);
- QMetaType::destruct(QMetaType::Void, actual);
- qFreeAligned(storage);
-
- QVERIFY(QMetaType::construct(QMetaType::Void, 0, expected) == 0);
+ QCOMPARE(expected, nullptr); // we do not need to delete it
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ void *storage1 = nullptr;
+ void *actual1 = QMetaType::construct(QMetaType::Void, storage1, expected);
+ auto cleanup1 = qScopeGuard([storage1, actual1]() {
+ QMetaType::destruct(QMetaType::Void, actual1);
+ qFreeAligned(storage1);
+ });
+ QCOMPARE(actual1, storage1);
+ QCOMPARE(QMetaType::construct(QMetaType::Void, nullptr, nullptr), nullptr);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QMetaType info(QMetaType::Void);
+ void *storage2 = nullptr;
+ void *actual2 = info.construct(storage2, expected);
+ auto cleanup2 = qScopeGuard([&info, storage2, actual2]() {
+ info.destruct(actual2);
+ qFreeAligned(storage2);
+ });
+ QCOMPARE(actual2, storage2);
+ QCOMPARE(info.construct(nullptr, expected), nullptr);
}
void tst_QMetaType::constructCopy_data()
@@ -1205,6 +1638,11 @@ void tst_QMetaType::constructCopy()
static TypeTestFunction get(int type)
{
switch (type) {
+ case QMetaType::UnknownType:
+ return []() {
+ char buf[1], buf2[1] = {};
+ QCOMPARE(QMetaType().construct(&buf, &buf2), nullptr);
+ };
#define RETURN_CONSTRUCT_COPY_FUNCTION(MetaTypeName, MetaTypeId, RealType) \
case QMetaType::MetaTypeName: \
return testConstructCopyHelper<QMetaType::MetaTypeName>;
@@ -1219,47 +1657,106 @@ FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_COPY_FUNCTION)
TypeTestFunctionGetter::get(type)();
}
+void tst_QMetaType::selfCompare_data()
+{
+ qRegisterMetaType<QPartialOrdering>();
+ QTest::addColumn<int>("type");
+ QTest::addColumn<QPartialOrdering>("order");
+
+ auto orderingFor = [](QMetaType::Type t) {
+ if (t == QMetaType::UnknownType || t == QMetaType::Void)
+ return QPartialOrdering::Unordered;
+ return QPartialOrdering::Equivalent;
+ };
+
+ QTest::newRow("unknown-type") << int(QMetaType::UnknownType) << orderingFor(QMetaType::UnknownType);
+
+#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
+ QTest::newRow(QMetaType(QMetaType::MetaTypeName).name()) << int(QMetaType::MetaTypeName) << orderingFor(QMetaType::MetaTypeName);
+FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
+#undef ADD_METATYPE_TEST_ROW
+}
+
+void tst_QMetaType::selfCompare()
+{
+ QFETCH(int, type);
+ QFETCH(QPartialOrdering, order);
+
+ QMetaType t(type);
+ void *v1 = t.create(nullptr);
+ void *v2 = t.create(nullptr);
+ auto scope = qScopeGuard([=] {
+ t.destroy(v1);
+ t.destroy(v2);
+ });
+
+ // all these types have an equality comparator
+ QCOMPARE(t.equals(v1, v2), order == QPartialOrdering::Equivalent);
+
+ if (t.iface() && t.iface()->lessThan)
+ QCOMPARE(t.compare(v1, v2), order);
+
+ // for the primitive types, do a memcmp() too
+ switch (type) {
+ default:
+ break;
+
+#define ADD_METATYPE_CASE(MetaTypeName, MetaTypeId, RealType) \
+ case QMetaType::MetaTypeName:
+FOR_EACH_PRIMITIVE_METATYPE(ADD_METATYPE_CASE)
+#undef ADD_METATYPE_CASE
+ QCOMPARE(memcmp(v1, v2, t.sizeOf()), 0);
+ }
+}
+
typedef QString CustomString;
Q_DECLARE_METATYPE(CustomString) //this line is useless
void tst_QMetaType::typedefs()
{
- QCOMPARE(QMetaType::type("long long"), int(QMetaType::LongLong));
- QCOMPARE(QMetaType::type("unsigned long long"), int(QMetaType::ULongLong));
- QCOMPARE(QMetaType::type("qint8"), int(QMetaType::SChar));
- QCOMPARE(QMetaType::type("quint8"), int(QMetaType::UChar));
- QCOMPARE(QMetaType::type("qint16"), int(QMetaType::Short));
- QCOMPARE(QMetaType::type("quint16"), int(QMetaType::UShort));
- QCOMPARE(QMetaType::type("qint32"), int(QMetaType::Int));
- QCOMPARE(QMetaType::type("quint32"), int(QMetaType::UInt));
- QCOMPARE(QMetaType::type("qint64"), int(QMetaType::LongLong));
- QCOMPARE(QMetaType::type("quint64"), int(QMetaType::ULongLong));
+ QCOMPARE(QMetaType::fromName("long long").id(), int(QMetaType::LongLong));
+ QCOMPARE(QMetaType::fromName("unsigned long long").id(), int(QMetaType::ULongLong));
+ QCOMPARE(QMetaType::fromName("qint8").id(), int(QMetaType::SChar));
+ QCOMPARE(QMetaType::fromName("quint8").id(), int(QMetaType::UChar));
+ QCOMPARE(QMetaType::fromName("qint16").id(), int(QMetaType::Short));
+ QCOMPARE(QMetaType::fromName("quint16").id(), int(QMetaType::UShort));
+ QCOMPARE(QMetaType::fromName("qint32").id(), int(QMetaType::Int));
+ QCOMPARE(QMetaType::fromName("quint32").id(), int(QMetaType::UInt));
+ QCOMPARE(QMetaType::fromName("qint64").id(), int(QMetaType::LongLong));
+ QCOMPARE(QMetaType::fromName("quint64").id(), int(QMetaType::ULongLong));
// make sure the qreal typeId is the type id of the type it's defined to
- QCOMPARE(QMetaType::type("qreal"), ::qMetaTypeId<qreal>());
+ QCOMPARE(QMetaType::fromName("qreal").id(), ::qMetaTypeId<qreal>());
qRegisterMetaType<CustomString>("CustomString");
- QCOMPARE(QMetaType::type("CustomString"), ::qMetaTypeId<CustomString>());
+ QCOMPARE(QMetaType::fromName("CustomString").id(), ::qMetaTypeId<CustomString>());
typedef Whity<double> WhityDouble;
qRegisterMetaType<WhityDouble>("WhityDouble");
- QCOMPARE(QMetaType::type("WhityDouble"), ::qMetaTypeId<WhityDouble>());
+ QCOMPARE(QMetaType::fromName("WhityDouble").id(), ::qMetaTypeId<WhityDouble>());
}
+struct RegisterTypeType {};
+
void tst_QMetaType::registerType()
{
// Built-in
QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
QCOMPARE(qRegisterMetaType<QString>("QString"), int(QMetaType::QString));
+ qRegisterMetaType(QMetaType::fromType<QString>());
// Custom
int fooId = qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo");
QVERIFY(fooId >= int(QMetaType::User));
QCOMPARE(qRegisterMetaType<TestSpace::Foo>("TestSpace::Foo"), fooId);
+ qRegisterMetaType(QMetaType::fromType<TestSpace::Foo>());
int movableId = qRegisterMetaType<CustomMovable>("CustomMovable");
QVERIFY(movableId >= int(QMetaType::User));
QCOMPARE(qRegisterMetaType<CustomMovable>("CustomMovable"), movableId);
+ qRegisterMetaType(QMetaType::fromType<CustomMovable>());
+
+ // Aliases are deprecated
// Alias to built-in
typedef QString MyString;
@@ -1267,7 +1764,7 @@ void tst_QMetaType::registerType()
QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
QCOMPARE(qRegisterMetaType<MyString>("MyString"), int(QMetaType::QString));
- QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString));
+ QCOMPARE(QMetaType::fromType<MyString>().id(), int(QMetaType::QString));
// Alias to custom type
typedef CustomMovable MyMovable;
@@ -1276,60 +1773,29 @@ void tst_QMetaType::registerType()
QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
QCOMPARE(qRegisterMetaType<MyMovable>("MyMovable"), movableId);
- QCOMPARE(QMetaType::type("MyMovable"), movableId);
+ QCOMPARE(QMetaType::fromType<MyMovable>().id(), movableId);
QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
QCOMPARE(qRegisterMetaType<MyFoo>("MyFoo"), fooId);
- QCOMPARE(QMetaType::type("MyFoo"), fooId);
-
- // cannot unregister built-in types
- QVERIFY(!QMetaType::unregisterType(QMetaType::QString));
- QCOMPARE(QMetaType::type("QString"), int(QMetaType::QString));
- QCOMPARE(QMetaType::type("MyString"), int(QMetaType::QString));
-
- // cannot unregister declared types
- QVERIFY(!QMetaType::unregisterType(fooId));
- QCOMPARE(QMetaType::type("TestSpace::Foo"), fooId);
- QCOMPARE(QMetaType::type("MyFoo"), fooId);
-
- // test unregistration of dynamic types (used by Qml)
- int unregId = QMetaType::registerType("UnregisterMe",
- 0,
- 0,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
- 0, QMetaType::TypeFlags(), 0);
- QCOMPARE(QMetaType::registerTypedef("UnregisterMeTypedef", unregId), unregId);
- int unregId2 = QMetaType::registerType("UnregisterMe2",
- 0,
- 0,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
- 0, QMetaType::TypeFlags(), 0);
- QVERIFY(unregId >= int(QMetaType::User));
- QCOMPARE(unregId2, unregId + 2);
-
- QVERIFY(QMetaType::unregisterType(unregId));
- QCOMPARE(QMetaType::type("UnregisterMe"), 0);
- QCOMPARE(QMetaType::type("UnregisterMeTypedef"), 0);
- QCOMPARE(QMetaType::type("UnregisterMe2"), unregId2);
- QVERIFY(QMetaType::unregisterType(unregId2));
- QCOMPARE(QMetaType::type("UnregisterMe2"), 0);
-
- // re-registering should always return the lowest free index
- QCOMPARE(QMetaType::registerType("UnregisterMe2",
- 0,
- 0,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
- 0, QMetaType::TypeFlags(), 0), unregId);
- QCOMPARE(QMetaType::registerType("UnregisterMe",
- 0,
- 0,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct,
- 0, QMetaType::TypeFlags(), 0), unregId + 1);
+ QCOMPARE(QMetaType::fromType<MyFoo>().id(), fooId);
+
+ // this portion of the test can only be run once
+ static bool typeWasRegistered = false;
+ if (!typeWasRegistered) {
+ QMetaType mt = QMetaType::fromType<RegisterTypeType>();
+ QVERIFY(mt.isValid());
+ QCOMPARE_NE(mt.name(), nullptr);
+
+ QVERIFY(!mt.isRegistered());
+ QVERIFY(!QMetaType::fromName(mt.name()).isValid());
+
+ QCOMPARE_GT(qRegisterMetaType(mt), 0);
+ typeWasRegistered = true;
+
+ QVERIFY(mt.isRegistered());
+ QVERIFY(QMetaType::fromName(mt.name()).isValid());
+ }
}
class IsRegisteredDummyType { };
@@ -1350,7 +1816,7 @@ void tst_QMetaType::isRegistered_data()
// unknown types
QTest::newRow("-1") << -1 << false;
QTest::newRow("-42") << -42 << false;
- QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
+ QTest::newRow("IsRegisteredDummyType + 1000") << (dummyTypeId + 1000) << false;
QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false;
}
@@ -1373,25 +1839,77 @@ Q_DECLARE_METATYPE(isEnumTest_Enum1)
void tst_QMetaType::isEnum()
{
int type0 = qRegisterMetaType<int>("int");
- QVERIFY((QMetaType::typeFlags(type0) & QMetaType::IsEnumeration) == 0);
+ QVERIFY((QMetaType(type0).flags() & QMetaType::IsEnumeration) == 0);
int type1 = qRegisterMetaType<isEnumTest_Enum0>("isEnumTest_Enum0");
- QVERIFY((QMetaType::typeFlags(type1) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
+ QVERIFY((QMetaType(type1).flags() & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
int type2 = qRegisterMetaType<isEnumTest_Struct0>("isEnumTest_Struct0");
- QVERIFY((QMetaType::typeFlags(type2) & QMetaType::IsEnumeration) == 0);
+ QVERIFY((QMetaType(type2).flags() & QMetaType::IsEnumeration) == 0);
int type3 = qRegisterMetaType<isEnumTest_Enum0 *>("isEnumTest_Enum0 *");
- QVERIFY((QMetaType::typeFlags(type3) & QMetaType::IsEnumeration) == 0);
+ QVERIFY((QMetaType(type3).flags() & QMetaType::IsEnumeration) == 0);
int type4 = qRegisterMetaType<isEnumTest_Struct0::A>("isEnumTest_Struct0::A");
- QVERIFY((QMetaType::typeFlags(type4) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
+ QVERIFY((QMetaType(type4).flags() & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
int type5 = ::qMetaTypeId<isEnumTest_Struct1>();
- QVERIFY((QMetaType::typeFlags(type5) & QMetaType::IsEnumeration) == 0);
+ QVERIFY((QMetaType(type5).flags() & QMetaType::IsEnumeration) == 0);
int type6 = ::qMetaTypeId<isEnumTest_Enum1>();
- QVERIFY((QMetaType::typeFlags(type6) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
+ QVERIFY((QMetaType(type6).flags() & QMetaType::IsEnumeration) == QMetaType::IsEnumeration);
+}
+
+enum E1 : unsigned char {};
+enum E2 : qlonglong {};
+enum class E3 : unsigned short {};
+
+namespace myflags {
+
+ Q_NAMESPACE
+
+ enum Flag1 : int { A, B };
+ enum Flag2 : short { X, Y };
+
+ Q_DECLARE_FLAGS(Flags1, myflags::Flag1);
+ Q_FLAG_NS(Flags1)
+ Q_DECLARE_FLAGS(Flags2, myflags::Flag2);
+ Q_FLAG_NS(Flags2)
+
+}
+
+template <typename T>
+using getUnderlyingTypeNormalized = std::conditional_t<
+ std::is_signed_v<std::underlying_type_t<T>>,
+ typename QIntegerForSize<sizeof(T)>::Signed,
+ typename QIntegerForSize<sizeof(T)>::Unsigned
+>;
+
+void tst_QMetaType::underlyingType_data()
+{
+ QTest::addColumn<QMetaType>("source");
+ QTest::addColumn<QMetaType>("underlying");
+
+ QTest::newRow("invalid") << QMetaType() << QMetaType();
+ QTest::newRow("plain") << QMetaType::fromType<isEnumTest_Enum1>()
+ << QMetaType::fromType<getUnderlyingTypeNormalized<isEnumTest_Enum1>>();
+ QTest::newRow("uchar") << QMetaType::fromType<E1>()
+ << QMetaType::fromType<getUnderlyingTypeNormalized<E1>>();
+ QTest::newRow("long") << QMetaType::fromType<E2>()
+ << QMetaType::fromType<getUnderlyingTypeNormalized<E2>>();
+ QTest::newRow("class_ushort") << QMetaType::fromType<E3>()
+ << QMetaType::fromType<getUnderlyingTypeNormalized<E3>>();
+ QTest::newRow("flags_int") << QMetaType::fromType<myflags::Flags1>()
+ << QMetaType::fromType<int>();
+ QTest::newRow("flags_short") << QMetaType::fromType<myflags::Flags2>()
+ << QMetaType::fromType<int>(); // sic, not short!
+}
+
+void tst_QMetaType::underlyingType()
+{
+ QFETCH(QMetaType, source);
+ QFETCH(QMetaType, underlying);
+ QCOMPARE(source.underlyingType(), underlying);
}
void tst_QMetaType::isRegisteredStaticLess_data()
@@ -1403,14 +1921,14 @@ void tst_QMetaType::isRegisteredStaticLess()
{
QFETCH(int, typeId);
QFETCH(bool, registered);
+ ignoreInvalidMetaTypeWarning(typeId);
QCOMPARE(QMetaType(typeId).isRegistered(), registered);
}
-void tst_QMetaType::registerStreamBuiltin()
+struct NotARegisteredType {};
+void tst_QMetaType::isNotRegistered()
{
- //should not crash;
- qRegisterMetaTypeStreamOperators<QString>("QString");
- qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
+ QVERIFY(!QMetaType::fromType<NotARegisteredType>().isRegistered());
}
typedef QHash<int, uint> IntUIntHash;
@@ -1447,7 +1965,7 @@ class AutoMetaTypeObject : public QObject
Q_PROPERTY(IntIntHash someHash READ someHash CONSTANT)
Q_PROPERTY(NaturalNumber someInt READ someInt CONSTANT)
public:
- AutoMetaTypeObject(QObject *parent = 0)
+ AutoMetaTypeObject(QObject *parent = nullptr)
: QObject(parent), m_int(42)
{
m_hash.insert(4, 2);
@@ -1472,7 +1990,7 @@ class MyObject : public QObject
{
Q_OBJECT
public:
- MyObject(QObject *parent = 0)
+ MyObject(QObject *parent = nullptr)
: QObject(parent)
{
}
@@ -1480,39 +1998,16 @@ public:
typedef MyObject* MyObjectPtr;
Q_DECLARE_METATYPE(MyObjectPtr)
-#if defined(Q_COMPILER_VARIADIC_MACROS) && !defined(TST_QMETATYPE_BROKEN_COMPILER)
-static QByteArray createTypeName(const char *begin, const char *va)
-{
- QByteArray tn(begin);
- const QList<QByteArray> args = QByteArray(va).split(',');
- tn += args.first().trimmed();
- if (args.size() > 1) {
- QList<QByteArray>::const_iterator it = args.constBegin() + 1;
- const QList<QByteArray>::const_iterator end = args.constEnd();
- for (; it != end; ++it) {
- tn += ",";
- tn += it->trimmed();
- }
- }
- if (tn.endsWith('>'))
- tn += ' ';
- tn += '>';
- return tn;
-}
-#endif
-
-Q_DECLARE_METATYPE(const void*)
-
-void tst_QMetaType::automaticTemplateRegistration()
+void tst_QMetaType::automaticTemplateRegistration_1()
{
#define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE) \
{ \
CONTAINER<VALUE_TYPE> innerContainer; \
innerContainer.push_back(42); \
QVERIFY(*QVariant::fromValue(innerContainer).value<CONTAINER<VALUE_TYPE> >().begin() == 42); \
- QVector<CONTAINER<VALUE_TYPE> > outerContainer; \
+ QList<CONTAINER<VALUE_TYPE> > outerContainer; \
outerContainer << innerContainer; \
- QVERIFY(*QVariant::fromValue(outerContainer).value<QVector<CONTAINER<VALUE_TYPE> > >().first().begin() == 42); \
+ QVERIFY(*QVariant::fromValue(outerContainer).value<QList<CONTAINER<VALUE_TYPE> > >().first().begin() == 42); \
}
TEST_SEQUENTIAL_CONTAINER(QList, int)
@@ -1524,19 +2019,19 @@ void tst_QMetaType::automaticTemplateRegistration()
vecbool.push_back(true);
vecbool.push_back(false);
vecbool.push_back(true);
- QVERIFY(QVariant::fromValue(vecbool).value<std::vector<bool> >().front() == true);
- QVector<std::vector<bool> > vectorList;
+ QVERIFY(QVariant::fromValue(vecbool).value<std::vector<bool>>().front() == true);
+ QList<std::vector<bool>> vectorList;
vectorList << vecbool;
- QVERIFY(QVariant::fromValue(vectorList).value<QVector<std::vector<bool> > >().first().front() == true);
+ QVERIFY(QVariant::fromValue(vectorList).value<QList<std::vector<bool>>>().first().front() == true);
}
{
QList<unsigned> unsignedList;
unsignedList << 123;
- QVERIFY(QVariant::fromValue(unsignedList).value<QList<unsigned> >().first() == 123);
- QVector<QList<unsigned> > vectorList;
+ QVERIFY(QVariant::fromValue(unsignedList).value<QList<unsigned>>().first() == 123);
+ QList<QList<unsigned>> vectorList;
vectorList << unsignedList;
- QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<unsigned> > >().first().first() == 123);
+ QVERIFY(QVariant::fromValue(vectorList).value<QList<QList<unsigned>>>().first().first() == 123);
}
QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList);
@@ -1550,10 +2045,10 @@ void tst_QMetaType::automaticTemplateRegistration()
QList<QSharedPointer<QObject> > sharedPointerList;
QObject *testObject = new QObject;
sharedPointerList << QSharedPointer<QObject>(testObject);
- QVERIFY(QVariant::fromValue(sharedPointerList).value<QList<QSharedPointer<QObject> > >().first() == testObject);
- QVector<QList<QSharedPointer<QObject> > > vectorList;
+ QVERIFY(QVariant::fromValue(sharedPointerList).value<QList<QSharedPointer<QObject>>>().first() == testObject);
+ QList<QList<QSharedPointer<QObject>>> vectorList;
vectorList << sharedPointerList;
- QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QSharedPointer<QObject> > > >().first().first() == testObject);
+ QVERIFY(QVariant::fromValue(vectorList).value<QList<QList<QSharedPointer<QObject>>>>().first().first() == testObject);
}
{
IntIntHash intIntHash;
@@ -1623,7 +2118,7 @@ void tst_QMetaType::automaticTemplateRegistration()
{
typedef std::map<int, CustomObject*> StdMapIntCustomObject ;
StdMapIntCustomObject intComparableMap;
- CustomObject *o = 0;
+ CustomObject *o = nullptr;
intComparableMap[4] = o;
QCOMPARE(QVariant::fromValue(intComparableMap).value<StdMapIntCustomObject >()[4], o);
}
@@ -1640,7 +2135,7 @@ void tst_QMetaType::automaticTemplateRegistration()
QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2);
}
{
- IntUIntPair intUIntPair = qMakePair<int, uint>(4, 2);
+ IntUIntPair intUIntPair = qMakePair(4, 2u);
QCOMPARE(QVariant::fromValue(intUIntPair).value<IntUIntPair>().first, 4);
QCOMPARE(QVariant::fromValue(intUIntPair).value<IntUIntPair>().second, (uint)2);
}
@@ -1664,7 +2159,7 @@ void tst_QMetaType::automaticTemplateRegistration()
}
{
typedef std::pair<int, CustomQObject*> StdIntComparablePair;
- CustomQObject* o = 0;
+ CustomQObject *o = nullptr;
StdIntComparablePair intComparablePair = std::make_pair(4, o);
QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().first, 4);
QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().second, o);
@@ -1678,65 +2173,6 @@ void tst_QMetaType::automaticTemplateRegistration()
QVERIFY(qRegisterMetaType<UnregisteredTypeList>("UnregisteredTypeList") > 0);
}
-#if defined(Q_COMPILER_VARIADIC_MACROS) && !defined(TST_QMETATYPE_BROKEN_COMPILER)
-
- #define FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
- F(bool) \
- F(int) \
- F(qulonglong) \
- F(double) \
- F(short) \
- F(char) \
- F(ulong) \
- F(uchar) \
- F(float) \
- F(QObject*) \
- F(QString) \
- F(CustomMovable)
-
- #define FOR_EACH_STATIC_PRIMITIVE_TYPE2(F, SecondaryRealName) \
- F(uint, SecondaryRealName) \
- F(qlonglong, SecondaryRealName) \
- F(char, SecondaryRealName) \
- F(uchar, SecondaryRealName) \
- F(QObject*, SecondaryRealName)
-
- #define CREATE_AND_VERIFY_CONTAINER(CONTAINER, ...) \
- { \
- CONTAINER< __VA_ARGS__ > t; \
- const QVariant v = QVariant::fromValue(t); \
- QByteArray tn = createTypeName(#CONTAINER "<", #__VA_ARGS__); \
- const int type = QMetaType::type(tn); \
- const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \
- QCOMPARE(type, expectedType); \
- }
-
- #define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \
- F(QList, TYPE) \
- F(QVector, TYPE) \
- F(QLinkedList, TYPE) \
- F(QVector, TYPE) \
- F(QVector, TYPE) \
- F(QQueue, TYPE) \
- F(QStack, TYPE) \
- F(QSet, TYPE)
-
- #define PRINT_1ARG_TEMPLATE(RealName) \
- FOR_EACH_1ARG_TEMPLATE_TYPE(CREATE_AND_VERIFY_CONTAINER, RealName)
-
- #define FOR_EACH_2ARG_TEMPLATE_TYPE(F, RealName1, RealName2) \
- F(QHash, RealName1, RealName2) \
- F(QMap, RealName1, RealName2) \
- F(QPair, RealName1, RealName2)
-
- #define PRINT_2ARG_TEMPLATE_INTERNAL(RealName1, RealName2) \
- FOR_EACH_2ARG_TEMPLATE_TYPE(CREATE_AND_VERIFY_CONTAINER, RealName1, RealName2)
-
- #define PRINT_2ARG_TEMPLATE(RealName) \
- FOR_EACH_STATIC_PRIMITIVE_TYPE2(PRINT_2ARG_TEMPLATE_INTERNAL, RealName)
-
- #define REGISTER_TYPEDEF(TYPE, ARG1, ARG2) \
- qRegisterMetaType<TYPE <ARG1, ARG2> >(#TYPE "<" #ARG1 "," #ARG2 ">");
REGISTER_TYPEDEF(QHash, int, uint)
REGISTER_TYPEDEF(QMap, int, uint)
@@ -1745,27 +2181,22 @@ void tst_QMetaType::automaticTemplateRegistration()
FOR_EACH_STATIC_PRIMITIVE_TYPE(
PRINT_1ARG_TEMPLATE
)
- FOR_EACH_STATIC_PRIMITIVE_TYPE(
- PRINT_2ARG_TEMPLATE
- )
- CREATE_AND_VERIFY_CONTAINER(QList, QList<QMap<int, QHash<char, QVariantList> > >)
- CREATE_AND_VERIFY_CONTAINER(QVector, void*)
- CREATE_AND_VERIFY_CONTAINER(QVector, const void*)
+ CREATE_AND_VERIFY_CONTAINER(QList, QList<QMap<int, QHash<char, QList<QVariant>>>>)
CREATE_AND_VERIFY_CONTAINER(QList, void*)
- CREATE_AND_VERIFY_CONTAINER(QPair, void*, void*)
+ CREATE_AND_VERIFY_CONTAINER(QList, const void*)
+ CREATE_AND_VERIFY_CONTAINER(QList, void*)
+ CREATE_AND_VERIFY_CONTAINER(std::pair, void*, void*)
CREATE_AND_VERIFY_CONTAINER(QHash, void*, void*)
CREATE_AND_VERIFY_CONTAINER(QHash, const void*, const void*)
-#endif // Q_COMPILER_VARIADIC_MACROS
-
#define TEST_OWNING_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE, FLAG_TEST, FROMVARIANTFUNCTION) \
{ \
SMARTPOINTER < ELEMENT_TYPE > sp(new ELEMENT_TYPE); \
sp.data()->setObjectName("Test name"); \
QVariant v = QVariant::fromValue(sp); \
QCOMPARE(v.typeName(), #SMARTPOINTER "<" #ELEMENT_TYPE ">"); \
- QVERIFY(QMetaType::typeFlags(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()) & QMetaType::FLAG_TEST); \
+ QVERIFY(QMetaType(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()).flags() & QMetaType::FLAG_TEST); \
SMARTPOINTER < QObject > extractedPtr = FROMVARIANTFUNCTION<QObject>(v); \
QCOMPARE(extractedPtr.data()->objectName(), sp.data()->objectName()); \
}
@@ -1783,21 +2214,34 @@ void tst_QMetaType::automaticTemplateRegistration()
sp.data()->setObjectName("Test name"); \
QVariant v = QVariant::fromValue(sp); \
QCOMPARE(v.typeName(), #SMARTPOINTER "<" #ELEMENT_TYPE ">"); \
- QVERIFY(QMetaType::typeFlags(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()) & QMetaType::FLAG_TEST); \
+ QVERIFY(QMetaType(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()).flags() & QMetaType::FLAG_TEST); \
SMARTPOINTER < QObject > extractedPtr = FROMVARIANTFUNCTION<QObject>(v); \
QCOMPARE(extractedPtr.data()->objectName(), sp.data()->objectName()); \
}
- TEST_NONOWNING_SMARTPOINTER(QWeakPointer, QObject, WeakPointerToQObject, qWeakPointerFromVariant)
- TEST_NONOWNING_SMARTPOINTER(QWeakPointer, QFile, WeakPointerToQObject, qWeakPointerFromVariant)
- TEST_NONOWNING_SMARTPOINTER(QWeakPointer, QTemporaryFile, WeakPointerToQObject, qWeakPointerFromVariant)
- TEST_NONOWNING_SMARTPOINTER(QWeakPointer, MyObject, WeakPointerToQObject, qWeakPointerFromVariant)
-
TEST_NONOWNING_SMARTPOINTER(QPointer, QObject, TrackingPointerToQObject, qPointerFromVariant)
TEST_NONOWNING_SMARTPOINTER(QPointer, QFile, TrackingPointerToQObject, qPointerFromVariant)
TEST_NONOWNING_SMARTPOINTER(QPointer, QTemporaryFile, TrackingPointerToQObject, qPointerFromVariant)
TEST_NONOWNING_SMARTPOINTER(QPointer, MyObject, TrackingPointerToQObject, qPointerFromVariant)
#undef TEST_NONOWNING_SMARTPOINTER
+
+
+#define TEST_WEAK_SMARTPOINTER(ELEMENT_TYPE, FLAG_TEST) \
+ { \
+ ELEMENT_TYPE elem; \
+ QSharedPointer < ELEMENT_TYPE > shared(new ELEMENT_TYPE); \
+ QWeakPointer < ELEMENT_TYPE > sp(shared); \
+ sp.toStrongRef()->setObjectName("Test name"); \
+ QVariant v = QVariant::fromValue(sp); \
+ QCOMPARE(v.typeName(), "QWeakPointer<" #ELEMENT_TYPE ">"); \
+ QVERIFY(QMetaType(::qMetaTypeId<QWeakPointer < ELEMENT_TYPE > >()).flags() & QMetaType::FLAG_TEST); \
+ }
+
+ TEST_WEAK_SMARTPOINTER(QObject, WeakPointerToQObject)
+ TEST_WEAK_SMARTPOINTER(QFile, WeakPointerToQObject)
+ TEST_WEAK_SMARTPOINTER(QTemporaryFile, WeakPointerToQObject)
+ TEST_WEAK_SMARTPOINTER(MyObject, WeakPointerToQObject)
+#undef TEST_WEAK_SMARTPOINTER
}
template <typename T>
@@ -1815,21 +2259,9 @@ DECLARE_NONSTREAMABLE(void)
DECLARE_NONSTREAMABLE(void*)
DECLARE_NONSTREAMABLE(QModelIndex)
DECLARE_NONSTREAMABLE(QPersistentModelIndex)
-DECLARE_NONSTREAMABLE(QJsonValue)
-DECLARE_NONSTREAMABLE(QJsonObject)
-DECLARE_NONSTREAMABLE(QJsonArray)
-DECLARE_NONSTREAMABLE(QJsonDocument)
-DECLARE_NONSTREAMABLE(QCborValue)
-DECLARE_NONSTREAMABLE(QCborArray)
-DECLARE_NONSTREAMABLE(QCborMap)
DECLARE_NONSTREAMABLE(QObject*)
DECLARE_NONSTREAMABLE(QWidget*)
-#define DECLARE_GUI_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \
- DECLARE_NONSTREAMABLE(RealType)
-QT_FOR_EACH_STATIC_GUI_CLASS(DECLARE_GUI_CLASS_NONSTREAMABLE)
-#undef DECLARE_GUI_CLASS_NONSTREAMABLE
-
#define DECLARE_WIDGETS_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \
DECLARE_NONSTREAMABLE(RealType)
QT_FOR_EACH_STATIC_WIDGETS_CLASS(DECLARE_WIDGETS_CLASS_NONSTREAMABLE)
@@ -1842,6 +2274,8 @@ void tst_QMetaType::saveAndLoadBuiltin_data()
QTest::addColumn<int>("type");
QTest::addColumn<bool>("isStreamable");
+ QTest::newRow("unknown-type") << int(QMetaType::UnknownType) << false;
+
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
QTest::newRow(#RealType) << MetaTypeId << bool(StreamingTraits<RealType>::isStreamable);
QT_FOR_EACH_STATIC_TYPE(ADD_METATYPE_TEST_ROW)
@@ -1853,42 +2287,45 @@ void tst_QMetaType::saveAndLoadBuiltin()
QFETCH(int, type);
QFETCH(bool, isStreamable);
- void *value = QMetaType::create(type);
+ QMetaType metaType(type);
+ void *value = metaType.create();
QByteArray ba;
QDataStream stream(&ba, QIODevice::ReadWrite);
- QCOMPARE(QMetaType::save(stream, type, value), isStreamable);
+ QCOMPARE(metaType.save(stream, value), isStreamable);
QCOMPARE(stream.status(), QDataStream::Ok);
if (isStreamable) {
- QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
+ QVERIFY(metaType.hasRegisteredDataStreamOperators());
+ QVERIFY(metaType.load(stream, value)); // Hmmm, shouldn't it return false?
// std::nullptr_t is nullary: it doesn't actually read anything
if (type != QMetaType::Nullptr)
QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+ } else {
+ QVERIFY(!metaType.hasRegisteredDataStreamOperators());
}
stream.device()->seek(0);
stream.resetStatus();
- QCOMPARE(QMetaType::load(stream, type, value), isStreamable);
+ QCOMPARE(metaType.load(stream, value), isStreamable);
QCOMPARE(stream.status(), QDataStream::Ok);
if (isStreamable) {
- QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
+ QVERIFY(metaType.load(stream, value)); // Hmmm, shouldn't it return false?
// std::nullptr_t is nullary: it doesn't actually read anything
if (type != QMetaType::Nullptr)
QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
}
- QMetaType::destroy(type, value);
+ metaType.destroy(value);
}
struct CustomStreamableType
{
int a;
};
-Q_DECLARE_METATYPE(CustomStreamableType)
QDataStream &operator<<(QDataStream &out, const CustomStreamableType &t)
{
@@ -1903,6 +2340,7 @@ QDataStream &operator>>(QDataStream &in, CustomStreamableType &t)
t.a = a;
return in;
}
+Q_DECLARE_METATYPE(CustomStreamableType)
void tst_QMetaType::saveAndLoadCustom()
{
@@ -1910,30 +2348,27 @@ void tst_QMetaType::saveAndLoadCustom()
t.a = 123;
int id = ::qMetaTypeId<CustomStreamableType>();
+ QMetaType metaType(id);
+
QByteArray ba;
QDataStream stream(&ba, QIODevice::ReadWrite);
- QVERIFY(!QMetaType::save(stream, id, &t));
- QCOMPARE(stream.status(), QDataStream::Ok);
- QVERIFY(!QMetaType::load(stream, id, &t));
- QCOMPARE(stream.status(), QDataStream::Ok);
- qRegisterMetaTypeStreamOperators<CustomStreamableType>("CustomStreamableType");
- QVERIFY(QMetaType::save(stream, id, &t));
+ QVERIFY(metaType.save(stream, &t));
QCOMPARE(stream.status(), QDataStream::Ok);
CustomStreamableType t2;
t2.a = -1;
- QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false?
+ QVERIFY(metaType.load(stream, &t2)); // Hmmm, shouldn't it return false?
QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
QCOMPARE(t2.a, -1);
stream.device()->seek(0);
stream.resetStatus();
- QVERIFY(QMetaType::load(stream, id, &t2));
+ QVERIFY(metaType.load(stream, &t2));
QCOMPARE(stream.status(), QDataStream::Ok);
QCOMPARE(t2.a, t.a);
- QVERIFY(QMetaType::load(stream, id, &t2)); // Hmmm, shouldn't it return false?
+ QVERIFY(metaType.load(stream, &t2)); // Hmmm, shouldn't it return false?
QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
}
@@ -1948,7 +2383,7 @@ class MyQObjectFromGadget : public QObject, public MyGadget
{
Q_OBJECT
public:
- MyQObjectFromGadget(QObject *parent = 0)
+ MyQObjectFromGadget(QObject *parent = nullptr)
: QObject(parent)
{}
};
@@ -1968,15 +2403,17 @@ void tst_QMetaType::metaObject_data()
QTest::addColumn<bool>("isGadgetPtr");
QTest::addColumn<bool>("isQObjectPtr");
+ QTest::newRow("unknown-type") << int(QMetaType::UnknownType) << static_cast<const QMetaObject *>(0) << false << false << false;
QTest::newRow("QObject") << int(QMetaType::QObjectStar) << &QObject::staticMetaObject << false << false << true;
QTest::newRow("QFile*") << ::qMetaTypeId<QFile*>() << &QFile::staticMetaObject << false << false << true;
+ QTest::newRow("MyObject") << ::qMetaTypeId<MyObject>() << &MyObject::staticMetaObject << false << false << false;
QTest::newRow("MyObject*") << ::qMetaTypeId<MyObject*>() << &MyObject::staticMetaObject << false << false << true;
QTest::newRow("int") << int(QMetaType::Int) << static_cast<const QMetaObject *>(0) << false << false << false;
QTest::newRow("QEasingCurve") << ::qMetaTypeId<QEasingCurve>() << &QEasingCurve::staticMetaObject << true << false << false;
QTest::newRow("MyGadget") << ::qMetaTypeId<MyGadget>() << &MyGadget::staticMetaObject << true << false << false;
QTest::newRow("MyGadget*") << ::qMetaTypeId<MyGadget*>() << &MyGadget::staticMetaObject << false << true << false;
QTest::newRow("MyEnum") << ::qMetaTypeId<MyGadget::MyEnum>() << &MyGadget::staticMetaObject << false << false << false;
- QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &QObject::staticQtMetaObject << false << false << false;
+ QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId<Qt::ScrollBarPolicy>() << &Qt::staticMetaObject << false << false << false;
QTest::newRow("MyQObjectFromGadget*") << ::qMetaTypeId<MyQObjectFromGadget*>() << &MyQObjectFromGadget::staticMetaObject << false << false << true;
QTest::newRow("GadgetDerivedAndTyped<int>") << ::qMetaTypeId<GadgetDerivedAndTyped<int>>() << &GadgetDerivedAndTyped<int>::staticMetaObject << true << false << false;
@@ -1992,7 +2429,6 @@ void tst_QMetaType::metaObject()
QFETCH(bool, isGadgetPtr);
QFETCH(bool, isQObjectPtr);
- QCOMPARE(QMetaType::metaObjectForType(type), result);
QMetaType mt(type);
QCOMPARE(mt.metaObject(), result);
QCOMPARE(!!(mt.flags() & QMetaType::IsGadget), isGadget);
@@ -2030,7 +2466,6 @@ struct RegisterMetaTypeStruct<qRegisterMetaType< Name >()> \
enum { Value = qRegisterMetaType< Name >() }; \
};
-#if defined(Q_COMPILER_CONSTEXPR)
QT_FOR_EACH_STATIC_TYPE(METATYPE_ID_STRUCT)
QT_FOR_EACH_STATIC_TYPE(REGISTER_METATYPE_STRUCT)
@@ -2045,11 +2480,9 @@ struct RegisterMetaTypeStructDefaultTemplateValue
{
enum { Value };
};
-#endif
void tst_QMetaType::constexprMetaTypeIds()
{
-#if defined(Q_COMPILER_CONSTEXPR)
int id = 0;
int metaType;
@@ -2065,497 +2498,17 @@ void tst_QMetaType::constexprMetaTypeIds()
default:;
}
Q_UNUSED(metaType);
-#else
- QSKIP("The test needs a compiler supporting constexpr");
-#endif
-}
-
-void tst_QMetaType::constRefs()
-{
- QCOMPARE(::qMetaTypeId<const int &>(), ::qMetaTypeId<int>());
- QCOMPARE(::qMetaTypeId<const QString &>(), ::qMetaTypeId<QString>());
- QCOMPARE(::qMetaTypeId<const CustomMovable &>(), ::qMetaTypeId<CustomMovable>());
- QCOMPARE(::qMetaTypeId<const QList<CustomMovable> &>(), ::qMetaTypeId<QList<CustomMovable> >());
-#if defined(Q_COMPILER_CONSTEXPR)
- Q_STATIC_ASSERT(::qMetaTypeId<const int &>() == ::qMetaTypeId<int>());
-#endif
-}
-
-struct CustomConvertibleType
-{
- explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {}
- virtual ~CustomConvertibleType() {}
- QString toString() const { return m_foo.toString(); }
- operator QPoint() const { return QPoint(12, 34); }
- template<typename To>
- To convert() const { return s_value.value<To>();}
- template<typename To>
- To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
-
- QVariant m_foo;
- static QVariant s_value;
- static bool s_ok;
-};
-
-bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
-{ return lhs.m_foo < rhs.m_foo; }
-bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
-{ return lhs.m_foo == rhs.m_foo; }
-bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
-{ return !operator==(lhs, rhs); }
-
-QVariant CustomConvertibleType::s_value;
-bool CustomConvertibleType::s_ok = true;
-
-struct CustomConvertibleType2
-{
- // implicit
- CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType())
- : m_foo(t.m_foo) {}
- virtual ~CustomConvertibleType2() {}
-
- QVariant m_foo;
-};
-
-struct CustomDebugStreamableType
-{
- QString toString() const { return "test"; }
-};
-
-QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&)
-{
- return dbg << "string-content";
}
-bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
-{ return lhs.m_foo == rhs.m_foo; }
-bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
-{ return !operator==(lhs, rhs); }
-
-
-struct CustomEqualsOnlyType
-{
- explicit CustomEqualsOnlyType(int value = 0) : val(value) {}
- virtual ~CustomEqualsOnlyType() {}
-
- int val;
+struct S {
+ using value_type = S; // used to cause compilation error with Qt6
+ int begin();
+ int end();
};
-bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
-{ return lhs.val == rhs.val;}
-bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
-{ return !operator==(lhs, rhs); }
-
-Q_DECLARE_METATYPE(CustomConvertibleType);
-Q_DECLARE_METATYPE(CustomConvertibleType2);
-Q_DECLARE_METATYPE(CustomDebugStreamableType);
-Q_DECLARE_METATYPE(CustomEqualsOnlyType);
-template<typename T, typename U>
-U convert(const T &t)
-{
- return t;
-}
-
-template<typename From>
-struct ConvertFunctor
-{
- CustomConvertibleType operator()(const From& f) const
- {
- return CustomConvertibleType(QVariant::fromValue(f));
- }
-};
-
-template<typename From, typename To>
-bool hasRegisteredConverterFunction()
-{
- return QMetaType::hasRegisteredConverterFunction<From, To>();
-}
-
-template<typename From, typename To>
-void testCustomTypeNotYetConvertible()
-{
- QVERIFY((!hasRegisteredConverterFunction<From, To>()));
- QVERIFY((!QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<To>())));
-}
-
-template<typename From, typename To>
-void testCustomTypeConvertible()
-{
- QVERIFY((hasRegisteredConverterFunction<From, To>()));
- QVERIFY((QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<To>())));
-}
-
-void customTypeNotYetConvertible()
-{
- testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
- testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
- testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
-}
-
-void registerCustomTypeConversions()
-{
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
- QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>())));
- QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
- QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>())));
- QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
- QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>())));
- QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
- QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>())));
- QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
- QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>())));
- QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
- QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>())));
- QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
- QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>())));
- QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
- QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
- QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
- QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
-}
-
-void tst_QMetaType::convertCustomType_data()
-{
- customTypeNotYetConvertible();
- registerCustomTypeConversions();
-
- QTest::addColumn<bool>("ok");
- QTest::addColumn<QString>("testQString");
- QTest::addColumn<bool>("testBool");
- QTest::addColumn<int>("testInt");
- QTest::addColumn<double>("testDouble");
- QTest::addColumn<float>("testFloat");
- QTest::addColumn<QRect>("testQRect");
- QTest::addColumn<QRectF>("testQRectF");
- QTest::addColumn<QPoint>("testQPoint");
- QTest::addColumn<QPointF>("testQPointF");
- QTest::addColumn<QSize>("testQSize");
- QTest::addColumn<QSizeF>("testQSizeF");
- QTest::addColumn<QLine>("testQLine");
- QTest::addColumn<QLineF>("testQLineF");
- QTest::addColumn<QChar>("testQChar");
- QTest::addColumn<CustomConvertibleType>("testCustom");
-
- QTest::newRow("default") << true
- << QString::fromLatin1("string") << true << 15
- << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
- << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
- << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
- << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0)
- << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test"));
- QTest::newRow("not ok") << false
- << QString::fromLatin1("string") << true << 15
- << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
- << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
- << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
- << QLine(3, 9, 29, 4) << QLineF()
- << QChar('Q') << CustomConvertibleType(42);
-}
-
-void tst_QMetaType::convertCustomType()
-{
- QFETCH(bool, ok);
- CustomConvertibleType::s_ok = ok;
-
- CustomConvertibleType t;
- QVariant v = QVariant::fromValue(t);
- QFETCH(QString, testQString);
- CustomConvertibleType::s_value = testQString;
- QCOMPARE(v.toString(), ok ? testQString : QString());
- QCOMPARE(v.value<QString>(), ok ? testQString : QString());
- QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString);
-
- QFETCH(bool, testBool);
- CustomConvertibleType::s_value = testBool;
- QCOMPARE(v.toBool(), testBool);
- QCOMPARE(v.value<bool>(), testBool);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
-
- QFETCH(int, testInt);
- CustomConvertibleType::s_value = testInt;
- QCOMPARE(v.toInt(), ok ? testInt : 0);
- QCOMPARE(v.value<int>(), ok ? testInt : 0);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt);
-
- QFETCH(double, testDouble);
- CustomConvertibleType::s_value = testDouble;
- QCOMPARE(v.toDouble(), testDouble);
- QCOMPARE(v.value<double>(), testDouble);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
-
- QFETCH(float, testFloat);
- CustomConvertibleType::s_value = testFloat;
- QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
- QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat);
-
- QFETCH(QRect, testQRect);
- CustomConvertibleType::s_value = testQRect;
- QCOMPARE(v.toRect(), testQRect);
- QCOMPARE(v.value<QRect>(), testQRect);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
-
- QFETCH(QRectF, testQRectF);
- CustomConvertibleType::s_value = testQRectF;
- QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
- QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF);
-
- QFETCH(QPoint, testQPoint);
- CustomConvertibleType::s_value = testQPoint;
- QCOMPARE(v.toPoint(), testQPoint);
- QCOMPARE(v.value<QPoint>(), testQPoint);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
-
- QFETCH(QPointF, testQPointF);
- CustomConvertibleType::s_value = testQPointF;
- QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
- QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF);
-
- QFETCH(QSize, testQSize);
- CustomConvertibleType::s_value = testQSize;
- QCOMPARE(v.toSize(), testQSize);
- QCOMPARE(v.value<QSize>(), testQSize);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
-
- QFETCH(QSizeF, testQSizeF);
- CustomConvertibleType::s_value = testQSizeF;
- QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
- QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF);
-
- QFETCH(QLine, testQLine);
- CustomConvertibleType::s_value = testQLine;
- QCOMPARE(v.toLine(), testQLine);
- QCOMPARE(v.value<QLine>(), testQLine);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
-
- QFETCH(QLineF, testQLineF);
- CustomConvertibleType::s_value = testQLineF;
- QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
- QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF);
-
- QFETCH(QChar, testQChar);
- CustomConvertibleType::s_value = testQChar;
- QCOMPARE(v.toChar(), testQChar);
- QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
-
- QFETCH(CustomConvertibleType, testCustom);
- v = QVariant::fromValue(testCustom);
- QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>()));
- QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
-}
-
-void tst_QMetaType::compareCustomType_data()
-{
- QMetaType::registerComparators<CustomConvertibleType>();
-
- QTest::addColumn<QVariantList>("unsorted");
- QTest::addColumn<QVariantList>("sorted");
-
- QTest::newRow("int") << (QVariantList() << 37 << 458 << 1 << 243 << -4 << 383)
- << (QVariantList() << -4 << 1 << 37 << 243 << 383 << 458);
-
- QTest::newRow("dobule") << (QVariantList() << 4934.93 << 0.0 << 302.39 << -39.0)
- << (QVariantList() << -39.0 << 0.0 << 302.39 << 4934.93);
-
- QTest::newRow("QString") << (QVariantList() << "Hello" << "World" << "this" << "is" << "a" << "test")
- << (QVariantList() << "a" << "Hello" << "is" << "test" << "this" << "World");
-
- QTest::newRow("QTime") << (QVariantList() << QTime(14, 39) << QTime(0, 0) << QTime(18, 18) << QTime(9, 27))
- << (QVariantList() << QTime(0, 0) << QTime(9, 27) << QTime(14, 39) << QTime(18, 18));
-
- QTest::newRow("QDate") << (QVariantList() << QDate(2013, 3, 23) << QDate(1900, 12, 1) << QDate(2001, 2, 2) << QDate(1982, 12, 16))
- << (QVariantList() << QDate(1900, 12, 1) << QDate(1982, 12, 16) << QDate(2001, 2, 2) << QDate(2013, 3, 23));
-
- QTest::newRow("mixed") << (QVariantList() << "Hello" << "World" << QChar('a') << 38 << QChar('z') << -39 << 4.6)
- << (QVariantList() << -39 << 4.6 << 38 << QChar('a') << "Hello" << "World" << QChar('z'));
-
- QTest::newRow("custom") << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(100)) << QVariant::fromValue(CustomConvertibleType(50)))
- << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(50)) << QVariant::fromValue(CustomConvertibleType(100)));
-}
-
-void tst_QMetaType::compareCustomType()
-{
- QFETCH(QVariantList, unsorted);
- QFETCH(QVariantList, sorted);
- std::sort(unsorted.begin(), unsorted.end());
- QCOMPARE(unsorted, sorted);
-}
-
-void tst_QMetaType::compareCustomEqualOnlyType()
-{
- int metaTypeId = qRegisterMetaType<CustomEqualsOnlyType>();
- QMetaType::registerEqualsComparator<CustomEqualsOnlyType>();
- int result;
-
- CustomEqualsOnlyType val50(50);
- CustomEqualsOnlyType val100(100);
- CustomEqualsOnlyType val100x(100);
-
- QVariant variant50 = QVariant::fromValue(val50);
- QVariant variant100 = QVariant::fromValue(val100);
- QVariant variant100x = QVariant::fromValue(val100x);
-
- QVERIFY(variant50 != variant100);
- QVERIFY(variant50 != variant100x);
- QVERIFY(variant100 != variant50);
- QVERIFY(variant100x != variant50);
- QCOMPARE(variant100, variant100x);
- QCOMPARE(variant100, variant100);
-
- // compare always fails
- QVERIFY(!(variant50 < variant50));
- QVERIFY(!(variant50 < variant100));
- QVERIFY(!(variant100 < variant50));
-
- // check QMetaType::compare works/doesn't crash for equals only comparators
- bool wasSuccess = QMetaType::compare(variant50.constData(), variant50.constData(),
- metaTypeId, &result);
- QCOMPARE(result, 0);
- QVERIFY(wasSuccess);
- wasSuccess = QMetaType::compare(variant100.constData(), variant100x.constData(),
- metaTypeId, &result);
- QCOMPARE(result, 0);
- QVERIFY(wasSuccess);
-
- wasSuccess = QMetaType::compare(variant50.constData(), variant100.constData(),
- metaTypeId, &result);
- QVERIFY(!wasSuccess);
-
- // check QMetaType::equals works for equals only comparator
- wasSuccess = QMetaType::equals(variant50.constData(), variant50.constData(),
- metaTypeId, &result);
- QCOMPARE(result, 0);
- QVERIFY(wasSuccess);
- wasSuccess = QMetaType::equals(variant100.constData(), variant100.constData(),
- metaTypeId, &result);
- QCOMPARE(result, 0);
- QVERIFY(wasSuccess);
- wasSuccess = QMetaType::equals(variant100x.constData(), variant100x.constData(),
- metaTypeId, &result);
- QCOMPARE(result, 0);
- QVERIFY(wasSuccess);
- wasSuccess = QMetaType::equals(variant100.constData(), variant100x.constData(),
- metaTypeId, &result);
- QCOMPARE(result, 0);
- QVERIFY(wasSuccess);
- wasSuccess = QMetaType::equals(variant50.constData(), variant100.constData(),
- metaTypeId, &result);
- QCOMPARE(result, -1);
- QVERIFY(wasSuccess);
- wasSuccess = QMetaType::equals(variant50.constData(), variant100x.constData(),
- metaTypeId, &result);
- QCOMPARE(result, -1);
- QVERIFY(wasSuccess);
-
- //check QMetaType::equals for type w/o equals comparator being registered
- CustomMovable movable1;
- CustomMovable movable2;
- wasSuccess = QMetaType::equals(&movable1, &movable2,
- qRegisterMetaType<CustomMovable>(), &result);
- QVERIFY(!wasSuccess);
-
-}
-
-struct MessageHandlerCustom : public MessageHandler
-{
- MessageHandlerCustom(const int typeId)
- : MessageHandler(typeId, handler)
- {}
- static void handler(QtMsgType, const QMessageLogContext &, const QString &msg)
- {
- QCOMPARE(msg.trimmed(), expectedMessage.trimmed());
- }
- static QString expectedMessage;
-};
-
-QString MessageHandlerCustom::expectedMessage;
-
-void tst_QMetaType::customDebugStream()
-{
- MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
- QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
- handler.expectedMessage = "QVariant(CustomDebugStreamableType, )";
- qDebug() << v1;
-
- QMetaType::registerConverter<CustomDebugStreamableType, QString>(&CustomDebugStreamableType::toString);
- handler.expectedMessage = "QVariant(CustomDebugStreamableType, \"test\")";
- qDebug() << v1;
-
- QMetaType::registerDebugStreamOperator<CustomDebugStreamableType>();
- handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
- qDebug() << v1;
-}
-
-void tst_QMetaType::unknownType()
-{
- QMetaType invalid(QMetaType::UnknownType);
- QVERIFY(!invalid.create());
- QVERIFY(!invalid.sizeOf());
- QVERIFY(!invalid.metaObject());
- int buffer = 0xBAD;
- invalid.construct(&buffer);
- QCOMPARE(buffer, 0xBAD);
-}
-// Compile-time test, it should be possible to register function pointer types
-class Undefined;
-
-typedef Undefined (*UndefinedFunction0)();
-typedef Undefined (*UndefinedFunction1)(Undefined);
-typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
-typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
-typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined);
-
-Q_DECLARE_METATYPE(UndefinedFunction0);
-Q_DECLARE_METATYPE(UndefinedFunction1);
-Q_DECLARE_METATYPE(UndefinedFunction2);
-Q_DECLARE_METATYPE(UndefinedFunction3);
-#ifdef Q_COMPILER_VARIADIC_TEMPLATES
-Q_DECLARE_METATYPE(UndefinedFunction4);
-#endif
+// should not cause a compilation failure
+// used to cause issues due to S being equal to S::value_type
+Q_DECLARE_METATYPE(S)
QTEST_MAIN(tst_QMetaType)
#include "tst_qmetatype.moc"
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
index 6bda9638f7..1694e49491 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
@@ -1,298 +1,326 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// Used by both tst_qmetatype and tst_qsettings
-
-#ifndef TST_QMETATYPE_H
-#define TST_QMETATYPE_H
-
-#include <qmetatype.h>
-#include <float.h>
-
-#define FOR_EACH_PRIMITIVE_METATYPE(F) \
- QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
- QT_FOR_EACH_STATIC_CORE_POINTER(F) \
-
-#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
- QT_FOR_EACH_STATIC_CORE_CLASS(F) \
- QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
-
-#define FOR_EACH_CORE_METATYPE(F) \
- FOR_EACH_PRIMITIVE_METATYPE(F) \
- FOR_EACH_COMPLEX_CORE_METATYPE(F) \
-
-template <int ID>
-struct MetaEnumToType {};
-
-#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
-template<> \
-struct MetaEnumToType<QMetaType::MetaTypeName> { \
- typedef RealType Type; \
-};
-FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
-#undef DEFINE_META_ENUM_TO_TYPE
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include "tst_qmetatype_common.h"
+#include "tst_qvariant_common.h"
-template <int ID>
-struct DefaultValueFactory
+struct Derived : QObject
{
- typedef typename MetaEnumToType<ID>::Type Type;
- static Type *create() { return new Type; }
+ Q_OBJECT
};
-template <>
-struct DefaultValueFactory<QMetaType::Void>
+struct MessageHandlerCustom : public MessageHandler
{
- typedef MetaEnumToType<QMetaType::Void>::Type Type;
- static Type *create() { return 0; }
+ MessageHandlerCustom(const int typeId)
+ : MessageHandler(typeId, handler)
+ {}
+ static void handler(QtMsgType, const QMessageLogContext &, const QString &msg)
+ {
+ QCOMPARE(msg.trimmed(), expectedMessage.trimmed());
+ }
+ inline static QString expectedMessage;
};
-template <int ID>
-struct DefaultValueTraits
+class tst_QMetaType: public QObject
{
- // By default we assume that a default-constructed value (new T) is
- // initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
- enum { IsInitialized = true };
-};
+ Q_OBJECT
+ Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
-#define DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS(MetaTypeName, MetaTypeId, RealType) \
-template<> struct DefaultValueTraits<QMetaType::MetaTypeName> { \
- enum { IsInitialized = false }; \
-};
-// Primitive types (int et al) aren't initialized
-FOR_EACH_PRIMITIVE_METATYPE(DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS)
-#undef DEFINE_NON_INITIALIZED_DEFAULT_VALUE_TRAITS
+public:
+ struct GadgetPropertyType {
+ QByteArray type;
+ QByteArray name;
+ QVariant testData;
+ };
-template <int ID>
-struct TestValueFactory {};
+ tst_QMetaType() { propList << 42 << "Hello"; }
-template<> struct TestValueFactory<QMetaType::Void> {
- static void *create() { return 0; }
-};
+ QList<QVariant> prop() const { return propList; }
+ void setProp(const QList<QVariant> &list) { propList = list; }
-template<> struct TestValueFactory<QMetaType::QString> {
- static QString *create() { return new QString(QString::fromLatin1("QString")); }
-};
-template<> struct TestValueFactory<QMetaType::Int> {
- static int *create() { return new int(INT_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::UInt> {
- static uint *create() { return new uint(UINT_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::Bool> {
- static bool *create() { return new bool(true); }
-};
-template<> struct TestValueFactory<QMetaType::Double> {
- static double *create() { return new double(DBL_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::QByteArray> {
- static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
-};
-template<> struct TestValueFactory<QMetaType::QByteArrayList> {
- static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); }
-};
-template<> struct TestValueFactory<QMetaType::QVariantMap> {
- static QVariantMap *create() { return new QVariantMap(); }
-};
-template<> struct TestValueFactory<QMetaType::QVariantHash> {
- static QVariantHash *create() { return new QVariantHash(); }
-};
-template<> struct TestValueFactory<QMetaType::QVariantList> {
- static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); }
-};
-template<> struct TestValueFactory<QMetaType::QChar> {
- static QChar *create() { return new QChar(QChar('q')); }
-};
-template<> struct TestValueFactory<QMetaType::Long> {
- static long *create() { return new long(LONG_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::Short> {
- static short *create() { return new short(SHRT_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::Char> {
- static char *create() { return new char('c'); }
-};
-template<> struct TestValueFactory<QMetaType::ULong> {
- static ulong *create() { return new ulong(ULONG_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::UShort> {
- static ushort *create() { return new ushort(USHRT_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::SChar> {
- static signed char *create() { return new signed char(CHAR_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::UChar> {
- static uchar *create() { return new uchar(UCHAR_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::Float> {
- static float *create() { return new float(FLT_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::QObjectStar> {
- static QObject * *create() { return new QObject *(0); }
-};
-template<> struct TestValueFactory<QMetaType::VoidStar> {
- static void * *create() { return new void *(0); }
-};
-template<> struct TestValueFactory<QMetaType::LongLong> {
- static qlonglong *create() { return new qlonglong(LLONG_MIN); }
-};
-template<> struct TestValueFactory<QMetaType::ULongLong> {
- static qulonglong *create() { return new qulonglong(ULLONG_MAX); }
-};
-template<> struct TestValueFactory<QMetaType::QStringList> {
- static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
-};
-template<> struct TestValueFactory<QMetaType::QBitArray> {
- static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
-};
-template<> struct TestValueFactory<QMetaType::QDate> {
- static QDate *create() { return new QDate(QDate::currentDate()); }
-};
-template<> struct TestValueFactory<QMetaType::QTime> {
- static QTime *create() { return new QTime(QTime::currentTime()); }
-};
-template<> struct TestValueFactory<QMetaType::QDateTime> {
- static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
-};
-template<> struct TestValueFactory<QMetaType::QUrl> {
- static QUrl *create() { return new QUrl("http://www.example.org"); }
-};
-template<> struct TestValueFactory<QMetaType::QLocale> {
- static QLocale *create() { return new QLocale(QLocale::c()); }
-};
-template<> struct TestValueFactory<QMetaType::QRect> {
- static QRect *create() { return new QRect(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QRectF> {
- static QRectF *create() { return new QRectF(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QSize> {
- static QSize *create() { return new QSize(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QSizeF> {
- static QSizeF *create() { return new QSizeF(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QLine> {
- static QLine *create() { return new QLine(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QLineF> {
- static QLineF *create() { return new QLineF(10, 20, 30, 40); }
-};
-template<> struct TestValueFactory<QMetaType::QPoint> {
- static QPoint *create() { return new QPoint(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QPointF> {
- static QPointF *create() { return new QPointF(10, 20); }
-};
-template<> struct TestValueFactory<QMetaType::QEasingCurve> {
- static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
-};
-template<> struct TestValueFactory<QMetaType::QUuid> {
- static QUuid *create() { return new QUuid(); }
-};
-template<> struct TestValueFactory<QMetaType::QModelIndex> {
- static QModelIndex *create() { return new QModelIndex(); }
-};
-template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> {
- static QPersistentModelIndex *create() { return new QPersistentModelIndex(); }
-};
-template<> struct TestValueFactory<QMetaType::Nullptr> {
- static std::nullptr_t *create() { return new std::nullptr_t; }
-};
-template<> struct TestValueFactory<QMetaType::QRegExp> {
- static QRegExp *create()
- {
-#ifndef QT_NO_REGEXP
- return new QRegExp("A*");
-#else
- return 0;
+private:
+ void registerGadget(const char * name, const QList<GadgetPropertyType> &gadgetProperties);
+ QList<QVariant> propList;
+
+private slots:
+ void defined();
+#if QT_CONFIG(thread)
+ void threadSafety();
+#endif
+ void namespaces();
+ void id();
+ void qMetaTypeId();
+ void properties();
+ void normalizedTypes();
+ void typeName_data();
+ void typeName();
+ void type_data();
+ void type();
+ void type_fromSubString_data();
+ void type_fromSubString();
+ void create_data();
+ void create();
+ void createCopy_data();
+ void createCopy();
+ void sizeOf_data();
+ void sizeOf();
+ void sizeOfStaticLess_data();
+ void sizeOfStaticLess();
+ void alignOf_data();
+ void alignOf();
+ void flags_data();
+ void flags();
+ void flags2_data();
+ void flags2();
+ void flagsBinaryCompatibility6_0_data();
+ void flagsBinaryCompatibility6_0();
+ void construct_data();
+ void construct();
+ void defaultConstructTrivial_QTBUG_109594();
+ void typedConstruct();
+ void constructCopy_data();
+ void constructCopy();
+ void selfCompare_data();
+ void selfCompare();
+ void typedefs();
+ void registerType();
+ void isRegistered_data();
+ void isRegistered();
+ void isRegisteredStaticLess_data();
+ void isRegisteredStaticLess();
+ void isNotRegistered();
+ void isEnum();
+ void underlyingType_data();
+ void underlyingType();
+ void automaticTemplateRegistration_1();
+ void automaticTemplateRegistration_2(); // defined in tst_qmetatype3.cpp
+ void saveAndLoadBuiltin_data();
+ void saveAndLoadBuiltin();
+ void saveAndLoadCustom();
+ void metaObject_data();
+ void metaObject();
+ void constexprMetaTypeIds();
+
+ // tst_qmetatype2.cpp
+ void constRefs();
+ void convertCustomType_data();
+ void convertCustomType();
+ void convertConstNonConst();
+ void compareCustomEqualOnlyType();
+ void customDebugStream();
+ void unknownType();
+ void fromType();
+ void operatorEq_data();
+ void operatorEq();
+ void operatorEq2_data();
+ void operatorEq2();
+ void operatorEqAcrossLibs_data();
+ void operatorEqAcrossLibs();
+ void typesWithInaccessibleDTors();
+ void voidIsNotUnknown();
+ void typeNameNormalization();
+ void typeNameInQtPrivate();
+
+ // Tests for deprecated APIs
+#if QT_DEPRECATED_SINCE(6, 0)
+ void testDeprecatedGetters_data() { type_data(); }
+ void testDeprecatedGetters();
+ void testDeprecatedLoadSave_data() { saveAndLoadBuiltin_data(); }
+ void testDeprecatedLoadSave();
#endif
- }
};
-template<> struct TestValueFactory<QMetaType::QRegularExpression> {
- static QRegularExpression *create()
- {
-#ifndef QT_NO_REGEXP
- return new QRegularExpression("abc.*def");
-#else
- return 0;
+
+template <typename T>
+struct Whity { T t; Whity() {} };
+
+Q_DECLARE_METATYPE(Whity<int>)
+Q_DECLARE_METATYPE(Whity<double>)
+
+#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(Whity<double>, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
#endif
- }
+
+struct CustomConvertibleType
+{
+ explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {}
+ virtual ~CustomConvertibleType() {}
+ QString toString() const { return m_foo.toString(); }
+ operator QPoint() const { return QPoint(12, 34); }
+ template<typename To>
+ To convert() const { return s_value.value<To>();}
+ template<typename To>
+ To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();}
+
+ QVariant m_foo;
+ inline static QVariant s_value;
+ inline static bool s_ok = true;
+
+ friend bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+ { return lhs.m_foo.toString() < rhs.m_foo.toString(); }
+ friend bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+ { return lhs.m_foo == rhs.m_foo; }
+ friend bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs)
+ { return !operator==(lhs, rhs); }
};
-template<> struct TestValueFactory<QMetaType::QJsonValue> {
- static QJsonValue *create() { return new QJsonValue(123.); }
+
+struct CustomConvertibleType2
+{
+ // implicit
+ CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType())
+ : m_foo(t.m_foo) {}
+ virtual ~CustomConvertibleType2() {}
+
+ QVariant m_foo;
+
+ friend bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
+ { return lhs.m_foo == rhs.m_foo; }
+ friend bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs)
+ { return !operator==(lhs, rhs); }
};
-template<> struct TestValueFactory<QMetaType::QJsonObject> {
- static QJsonObject *create() {
- QJsonObject *o = new QJsonObject();
- o->insert("a", 123.);
- o->insert("b", true);
- o->insert("c", QJsonValue::Null);
- o->insert("d", QLatin1String("ciao"));
- return o;
+
+struct CustomDebugStreamableType
+{
+ QString toString() const { return "test"; }
+
+ friend QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&)
+ {
+ return dbg << "string-content";
}
};
-template<> struct TestValueFactory<QMetaType::QJsonArray> {
- static QJsonArray *create() {
- QJsonArray *a = new QJsonArray();
- a->append(123.);
- a->append(true);
- a->append(QJsonValue::Null);
- a->append(QLatin1String("ciao"));
- return a;
- }
+
+struct CustomDebugStreamableType2
+{
+ QString toString() const { return "test"; }
};
-template<> struct TestValueFactory<QMetaType::QJsonDocument> {
- static QJsonDocument *create() {
- return new QJsonDocument(
- QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
- );
- }
+
+struct CustomEqualsOnlyType
+{
+ explicit CustomEqualsOnlyType(int value = 0) : val(value) {}
+ virtual ~CustomEqualsOnlyType() {}
+
+ int val;
+
+ friend bool operator==(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
+ { return lhs.val == rhs.val;}
+ friend bool operator!=(const CustomEqualsOnlyType &lhs, const CustomEqualsOnlyType &rhs)
+ { return !operator==(lhs, rhs); }
};
-template<> struct TestValueFactory<QMetaType::QCborSimpleType> {
- static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
+static_assert(QTypeTraits::has_operator_equal_v<CustomEqualsOnlyType>);
+static_assert(!QTypeTraits::has_operator_less_than_v<CustomEqualsOnlyType>);
+
+struct BaseGadgetType
+{
+ Q_GADGET
+public:
+ explicit BaseGadgetType(QVariant foo = QVariant()) : m_foo(std::move(foo)) {}
+ QVariant m_foo;
};
-template<> struct TestValueFactory<QMetaType::QCborValue> {
- static QCborValue *create() { return new QCborValue(123.); }
+
+struct DerivedGadgetType : public BaseGadgetType
+{
+ Q_GADGET
+public:
+ explicit DerivedGadgetType(QVariant foo = QVariant()) : BaseGadgetType(std::move(foo)) {}
+ int bar = 25;
};
-template<> struct TestValueFactory<QMetaType::QCborMap> {
- static QCborMap *create() {
- return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
- }
+
+Q_DECLARE_METATYPE(CustomConvertibleType);
+Q_DECLARE_METATYPE(CustomConvertibleType2);
+Q_DECLARE_METATYPE(CustomDebugStreamableType);
+Q_DECLARE_METATYPE(CustomEqualsOnlyType);
+
+struct CustomMovable {
+ CustomMovable() {}
+
+ friend bool operator==(const CustomMovable &, const CustomMovable &) { return true; }
+ // needed for QSet<CustomMovable>. We actually check that it makes sense.
+ friend qsizetype qHash(const CustomMovable &, qsizetype seed = 0) { return seed; }
};
-template<> struct TestValueFactory<QMetaType::QCborArray> {
- static QCborArray *create() {
- return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
+
+#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(CustomMovable, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+#endif
+
+Q_DECLARE_METATYPE(CustomMovable);
+
+#define FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
+ F(bool) \
+ F(int) \
+ F(qulonglong) \
+ F(double) \
+ F(short) \
+ F(char) \
+ F(ulong) \
+ F(uchar) \
+ F(float) \
+ F(QObject*) \
+ F(QString) \
+ F(CustomMovable)
+
+#define FOR_EACH_STATIC_PRIMITIVE_TYPE2(F, SecondaryRealName) \
+ F(uint, SecondaryRealName) \
+ F(qlonglong, SecondaryRealName) \
+ F(char, SecondaryRealName) \
+ F(uchar, SecondaryRealName) \
+ F(QObject*, SecondaryRealName)
+
+#define CREATE_AND_VERIFY_CONTAINER(CONTAINER, ...) \
+ { \
+ CONTAINER< __VA_ARGS__ > t; \
+ const QVariant v = QVariant::fromValue(t); \
+ QByteArray tn = createTypeName(#CONTAINER "<", #__VA_ARGS__); \
+ const int expectedType = ::qMetaTypeId<CONTAINER< __VA_ARGS__ > >(); \
+ const int type = QMetaType::fromName(tn).id(); \
+ QCOMPARE(type, expectedType); \
+ QCOMPARE((QMetaType::fromType<CONTAINER< __VA_ARGS__ >>().id()), expectedType); \
}
-};
-template<> struct TestValueFactory<QMetaType::QVariant> {
- static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
-};
+#define FOR_EACH_1ARG_TEMPLATE_TYPE(F, TYPE) \
+ F(QList, TYPE) \
+ F(QQueue, TYPE) \
+ F(QStack, TYPE) \
+ F(QSet, TYPE)
+
+#define PRINT_1ARG_TEMPLATE(RealName) \
+ FOR_EACH_1ARG_TEMPLATE_TYPE(CREATE_AND_VERIFY_CONTAINER, RealName)
+
+#define FOR_EACH_2ARG_TEMPLATE_TYPE(F, RealName1, RealName2) \
+ F(QHash, RealName1, RealName2) \
+ F(QMap, RealName1, RealName2) \
+ F(std::pair, RealName1, RealName2)
+
+#define PRINT_2ARG_TEMPLATE_INTERNAL(RealName1, RealName2) \
+ FOR_EACH_2ARG_TEMPLATE_TYPE(CREATE_AND_VERIFY_CONTAINER, RealName1, RealName2)
+
+#define PRINT_2ARG_TEMPLATE(RealName) \
+ FOR_EACH_STATIC_PRIMITIVE_TYPE2(PRINT_2ARG_TEMPLATE_INTERNAL, RealName)
+
+#define REGISTER_TYPEDEF(TYPE, ARG1, ARG2) \
+ qRegisterMetaType<TYPE <ARG1, ARG2>>(#TYPE "<" #ARG1 "," #ARG2 ">");
+
+static inline QByteArray createTypeName(const char *begin, const char *va)
+{
+ QByteArray tn(begin);
+ const QList<QByteArray> args = QByteArray(va).split(',');
+ tn += args.first().trimmed();
+ if (args.size() > 1) {
+ QList<QByteArray>::const_iterator it = args.constBegin() + 1;
+ const QList<QByteArray>::const_iterator end = args.constEnd();
+ for (; it != end; ++it) {
+ tn += ",";
+ tn += it->trimmed();
+ }
+ }
+ if (tn.endsWith('>'))
+ tn += ' ';
+ tn += '>';
+ return tn;
+}
-#endif // TST_QMETATYPE_H
+Q_DECLARE_METATYPE(const void*)
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
new file mode 100644
index 0000000000..68bcb53056
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
@@ -0,0 +1,733 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "tst_qmetatype.h"
+#include "tst_qmetatype_libs.h"
+
+#include <QtCore/private/qmetaobjectbuilder_p.h>
+
+void tst_QMetaType::constRefs()
+{
+ QCOMPARE(::qMetaTypeId<const int &>(), ::qMetaTypeId<int>());
+ QCOMPARE(::qMetaTypeId<const QString &>(), ::qMetaTypeId<QString>());
+ QCOMPARE(::qMetaTypeId<const CustomMovable &>(), ::qMetaTypeId<CustomMovable>());
+ QCOMPARE(::qMetaTypeId<const QList<CustomMovable> &>(), ::qMetaTypeId<QList<CustomMovable> >());
+ static_assert(::qMetaTypeId<const int &>() == ::qMetaTypeId<int>());
+}
+
+template<typename T, typename U>
+U convert(const T &t)
+{
+ return t;
+}
+
+template<typename From>
+struct ConvertFunctor
+{
+ CustomConvertibleType operator()(const From& f) const
+ {
+ return CustomConvertibleType(QVariant::fromValue(f));
+ }
+};
+
+template<typename T>
+struct OptionalWrapper
+{
+ std::optional<T> operator()(const T& t) const
+ {
+ if (!CustomConvertibleType::s_ok)
+ return std::nullopt;
+
+ return t;
+ }
+};
+
+template<typename From>
+struct ConvertFunctorWithOptional
+{
+ std::optional<CustomConvertibleType> operator()(const From& f) const
+ {
+ if (!CustomConvertibleType::s_ok)
+ return std::nullopt;
+
+ return CustomConvertibleType(QVariant::fromValue(f));
+ }
+};
+
+template<typename From, typename To>
+bool hasRegisteredConverterFunction()
+{
+ return QMetaType::hasRegisteredConverterFunction<From, To>();
+}
+
+template<typename From, typename To>
+void testCustomTypeNotYetConvertible()
+{
+ QVERIFY((!hasRegisteredConverterFunction<From, To>()));
+ QVERIFY((!QVariant::fromValue<From>(From()).template canConvert<To>()));
+}
+
+template<typename From, typename To>
+void testCustomTypeConvertible()
+{
+ QVERIFY((hasRegisteredConverterFunction<From, To>()));
+ QVERIFY((QVariant::fromValue<From>(From()).template canConvert<To>()));
+}
+
+void customTypeNotYetConvertible()
+{
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QString>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, bool>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, int>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, double>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, float>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>();
+ testCustomTypeNotYetConvertible<QString, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<bool, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<int, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<double, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<float, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>();
+ testCustomTypeNotYetConvertible<CustomConvertibleType, std::optional<CustomConvertibleType>>();
+}
+
+void registerCustomTypeConversions()
+{
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>)));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>)));
+ QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctorWithOptional<QString>())));
+ QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>())));
+ QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctorWithOptional<int>())));
+ QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>())));
+ QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctorWithOptional<float>())));
+ QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>())));
+ QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctorWithOptional<QRectF>())));
+ QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>())));
+ QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctorWithOptional<QPointF>())));
+ QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>())));
+ QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctorWithOptional<QSizeF>())));
+ QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>())));
+ QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctorWithOptional<QLineF>())));
+ QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>())));
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, std::optional<CustomConvertibleType>>(OptionalWrapper<CustomConvertibleType>())));
+
+ QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
+ QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2");
+ QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>()));
+}
+
+void tst_QMetaType::convertCustomType_data()
+{
+ customTypeNotYetConvertible();
+ registerCustomTypeConversions();
+
+ QTest::addColumn<bool>("ok");
+ QTest::addColumn<QString>("testQString");
+ QTest::addColumn<bool>("testBool");
+ QTest::addColumn<int>("testInt");
+ QTest::addColumn<double>("testDouble");
+ QTest::addColumn<float>("testFloat");
+ QTest::addColumn<QRect>("testQRect");
+ QTest::addColumn<QRectF>("testQRectF");
+ QTest::addColumn<QPoint>("testQPoint");
+ QTest::addColumn<QPointF>("testQPointF");
+ QTest::addColumn<QSize>("testQSize");
+ QTest::addColumn<QSizeF>("testQSizeF");
+ QTest::addColumn<QLine>("testQLine");
+ QTest::addColumn<QLineF>("testQLineF");
+ QTest::addColumn<QChar>("testQChar");
+ QTest::addColumn<CustomConvertibleType>("testCustom");
+ QTest::addColumn<DerivedGadgetType>("testDerived");
+
+ QTest::newRow("default") << true
+ << QString::fromLatin1("string") << true << 15
+ << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
+ << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
+ << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
+ << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0)
+ << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test"))
+ << DerivedGadgetType(QString::fromLatin1("test"));
+ QTest::newRow("not ok") << false
+ << QString::fromLatin1("string") << true << 15
+ << double(3.14) << float(3.6) << QRect(1, 2, 3, 4)
+ << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34)
+ << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8)
+ << QLine(3, 9, 29, 4) << QLineF()
+ << QChar('Q') << CustomConvertibleType(42)
+ << DerivedGadgetType(42);
+}
+
+void tst_QMetaType::convertCustomType()
+{
+ QFETCH(bool, ok);
+ CustomConvertibleType::s_ok = ok;
+
+ CustomConvertibleType t;
+ QVariant v = QVariant::fromValue(t);
+ QFETCH(QString, testQString);
+ CustomConvertibleType::s_value = testQString;
+ QCOMPARE(v.toString(), ok ? testQString : QString());
+ QCOMPARE(v.value<QString>(), ok ? testQString : QString());
+ QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), ok ? testQString : QString());
+
+ QFETCH(bool, testBool);
+ CustomConvertibleType::s_value = testBool;
+ QCOMPARE(v.toBool(), testBool);
+ QCOMPARE(v.value<bool>(), testBool);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool);
+
+ QFETCH(int, testInt);
+ CustomConvertibleType::s_value = testInt;
+ QCOMPARE(v.toInt(), ok ? testInt : 0);
+ QCOMPARE(v.value<int>(), ok ? testInt : 0);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), ok ? testInt : 0);
+
+ QFETCH(double, testDouble);
+ CustomConvertibleType::s_value = testDouble;
+ QCOMPARE(v.toDouble(), testDouble);
+ QCOMPARE(v.value<double>(), testDouble);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble);
+
+ QFETCH(float, testFloat);
+ CustomConvertibleType::s_value = testFloat;
+ QCOMPARE(v.toFloat(), ok ? testFloat : 0.0);
+ QCOMPARE(v.value<float>(), ok ? testFloat : 0.0);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), ok ? testFloat : 0);
+
+ QFETCH(QRect, testQRect);
+ CustomConvertibleType::s_value = testQRect;
+ QCOMPARE(v.toRect(), testQRect);
+ QCOMPARE(v.value<QRect>(), testQRect);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect);
+
+ QFETCH(QRectF, testQRectF);
+ CustomConvertibleType::s_value = testQRectF;
+ QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF());
+ QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), ok ? testQRectF : QRectF());
+
+ QFETCH(QPoint, testQPoint);
+ CustomConvertibleType::s_value = testQPoint;
+ QCOMPARE(v.toPoint(), testQPoint);
+ QCOMPARE(v.value<QPoint>(), testQPoint);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint);
+
+ QFETCH(QPointF, testQPointF);
+ CustomConvertibleType::s_value = testQPointF;
+ QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF());
+ QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), ok ? testQPointF : QPointF());
+
+ QFETCH(QSize, testQSize);
+ CustomConvertibleType::s_value = testQSize;
+ QCOMPARE(v.toSize(), testQSize);
+ QCOMPARE(v.value<QSize>(), testQSize);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize);
+
+ QFETCH(QSizeF, testQSizeF);
+ CustomConvertibleType::s_value = testQSizeF;
+ QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF());
+ QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), ok ? testQSizeF : QSizeF());
+
+ QFETCH(QLine, testQLine);
+ CustomConvertibleType::s_value = testQLine;
+ QCOMPARE(v.toLine(), testQLine);
+ QCOMPARE(v.value<QLine>(), testQLine);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine);
+
+ QFETCH(QLineF, testQLineF);
+ CustomConvertibleType::s_value = testQLineF;
+ QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF());
+ QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF());
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), ok ? testQLineF : QLineF());
+
+ QFETCH(QChar, testQChar);
+ CustomConvertibleType::s_value = testQChar;
+ QCOMPARE(v.toChar(), testQChar);
+ QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar);
+
+ QFETCH(CustomConvertibleType, testCustom);
+ v = QVariant::fromValue(testCustom);
+ QVERIFY(v.canConvert(QMetaType(::qMetaTypeId<CustomConvertibleType2>())));
+ QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo);
+
+ // Check that converters that actually convert to std::optional<T> are not
+ // taken to indicate success or failure of the conversion. In these cases,
+ // the conversion must always succeed, even if the converter has returned a
+ // nullopt.
+ v = QVariant::fromValue(testCustom);
+ QVERIFY(v.canConvert(QMetaType::fromType<std::optional<CustomConvertibleType>>()));
+ QVERIFY(v.convert(QMetaType::fromType<std::optional<CustomConvertibleType>>()));
+ QCOMPARE(v.value<std::optional<CustomConvertibleType>>().has_value(), ok);
+ if (ok) {
+ QCOMPARE(v.value<std::optional<CustomConvertibleType>>().value().m_foo, testCustom.m_foo);
+ }
+
+ QFETCH(DerivedGadgetType, testDerived);
+ v = QVariant::fromValue(testDerived);
+ QCOMPARE(v.metaType(), QMetaType::fromType<DerivedGadgetType>());
+ QCOMPARE(v.value<DerivedGadgetType>().m_foo, testDerived.m_foo);
+ QVERIFY(v.canConvert(QMetaType::fromType<BaseGadgetType>()));
+ QVERIFY(v.convert(QMetaType::fromType<BaseGadgetType>()));
+ QCOMPARE(v.metaType(), QMetaType::fromType<BaseGadgetType>());
+ QCOMPARE(v.value<BaseGadgetType>().m_foo, testDerived.m_foo);
+}
+
+void tst_QMetaType::convertConstNonConst()
+{
+ auto mtConstObj = QMetaType::fromType<QObject const*>();
+ auto mtObj = QMetaType::fromType<QObject *>();
+ auto mtConstDerived = QMetaType::fromType<Derived const*>();
+ auto mtDerived = QMetaType::fromType<Derived *>();
+
+ QVERIFY(QMetaType::canConvert(mtConstObj, mtObj));
+ QVERIFY(QMetaType::canConvert(mtObj, mtConstObj)); // casting const away is allowed (but can lead to UB)
+ QVERIFY(QMetaType::canConvert(mtConstDerived, mtObj));
+ QVERIFY(QMetaType::canConvert(mtDerived, mtConstObj));
+ QVERIFY(QMetaType::canConvert(mtObj, mtConstDerived));
+}
+
+void tst_QMetaType::compareCustomEqualOnlyType()
+{
+ QMetaType type = QMetaType::fromType<CustomEqualsOnlyType>();
+
+ CustomEqualsOnlyType val50(50);
+ CustomEqualsOnlyType val100(100);
+ CustomEqualsOnlyType val100x(100);
+
+ QVariant variant50 = QVariant::fromValue(val50);
+ QVariant variant100 = QVariant::fromValue(val100);
+ QVariant variant100x = QVariant::fromValue(val100x);
+
+ QVERIFY(variant50 != variant100);
+ QVERIFY(variant50 != variant100x);
+ QVERIFY(variant100 != variant50);
+ QVERIFY(variant100x != variant50);
+ QCOMPARE(variant100, variant100x);
+ QCOMPARE(variant100, variant100);
+
+ // check QMetaType::compare works/doesn't crash for equals only comparators
+ auto cmp = type.compare(variant50.constData(), variant50.constData());
+ QCOMPARE(cmp, QPartialOrdering::Unordered);
+ bool equals = type.equals(variant50.constData(), variant50.constData());
+ QVERIFY(equals);
+
+ cmp = type.compare(variant100.constData(), variant100x.constData());
+ QCOMPARE(cmp, QPartialOrdering::Unordered);
+ equals = type.equals(variant100.constData(), variant100x.constData());
+ QVERIFY(equals);
+
+ cmp = type.compare(variant50.constData(), variant100.constData());
+ QCOMPARE(cmp, QPartialOrdering::Unordered);
+ equals = type.equals(variant50.constData(), variant100.constData());
+ QVERIFY(!equals);
+
+ //check QMetaType::equals for type w/o equals comparator being registered
+ CustomMovable movable1;
+ CustomMovable movable2;
+ type = QMetaType::fromType<CustomMovable>();
+ equals = type.equals(&movable1, &movable2);
+}
+
+void tst_QMetaType::customDebugStream()
+{
+ MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
+ QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
+ handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
+ qDebug() << v1;
+
+ MessageHandlerCustom handler2(::qMetaTypeId<CustomDebugStreamableType2>());
+ QMetaType::registerConverter<CustomDebugStreamableType2, QString>(&CustomDebugStreamableType2::toString);
+ handler2.expectedMessage = "QVariant(CustomDebugStreamableType2, \"test\")";
+ QVariant v2 = QVariant::fromValue(CustomDebugStreamableType2());
+ qDebug() << v2;
+}
+
+void tst_QMetaType::unknownType()
+{
+ QMetaType invalid(QMetaType::UnknownType);
+ QVERIFY(!invalid.create());
+ QVERIFY(!invalid.sizeOf());
+ QVERIFY(!invalid.metaObject());
+ int buffer = 0xBAD;
+ invalid.construct(&buffer);
+ QCOMPARE(buffer, 0xBAD);
+}
+
+void tst_QMetaType::fromType()
+{
+ #define FROMTYPE_CHECK(MetaTypeName, MetaTypeId, RealType) \
+ QCOMPARE(QMetaType::fromType<RealType>(), QMetaType(MetaTypeId)); \
+ QVERIFY(QMetaType::fromType<RealType>() == QMetaType(MetaTypeId)); \
+ QVERIFY(!(QMetaType::fromType<RealType>() != QMetaType(MetaTypeId))); \
+ if (MetaTypeId != QMetaType::Void) \
+ QCOMPARE(QMetaType::fromType<RealType>().id(), MetaTypeId);
+
+ FOR_EACH_CORE_METATYPE(FROMTYPE_CHECK)
+
+ QVERIFY(QMetaType::fromType<QString>() != QMetaType());
+ QCOMPARE(QMetaType(), QMetaType());
+ QCOMPARE(QMetaType(QMetaType::UnknownType), QMetaType());
+
+ FROMTYPE_CHECK(_, ::qMetaTypeId<Whity<int>>(), Whity<int>)
+ #undef FROMTYPE_CHECK
+}
+
+template<char X, typename T = void>
+struct CharTemplate
+{
+ struct
+ {
+ int a;
+ } x;
+
+ union
+ {
+ int a;
+ } y;
+};
+
+void tst_QMetaType::operatorEq_data()
+{
+ QTest::addColumn<QMetaType>("typeA");
+ QTest::addColumn<QMetaType>("typeB");
+ QTest::addColumn<bool>("eq");
+ QTest::newRow("String") << QMetaType(QMetaType::QString)
+ << QMetaType::fromType<const QString &>() << true;
+ QTest::newRow("void1") << QMetaType(QMetaType::UnknownType) << QMetaType::fromType<void>()
+ << false;
+ QTest::newRow("void2") << QMetaType::fromType<const void>() << QMetaType::fromType<void>()
+ << true;
+ QTest::newRow("list1") << QMetaType::fromType<QList<const int *>>()
+ << QMetaType::fromType<QList<const int *>>() << true;
+ QTest::newRow("list2") << QMetaType::fromType<QList<const int *>>()
+ << QMetaType::fromType<QList<int *>>() << false;
+ QTest::newRow("char1") << QMetaType::fromType<CharTemplate<'>'>>()
+ << QMetaType::fromType<CharTemplate<'>', void>>() << true;
+ QTest::newRow("annon1") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>()
+ << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>() << true;
+ QTest::newRow("annon2") << QMetaType::fromType<decltype(CharTemplate<'>'>::x)>()
+ << QMetaType::fromType<decltype(CharTemplate<'<'>::x)>() << false;
+}
+
+void tst_QMetaType::operatorEq()
+{
+ QFETCH(QMetaType, typeA);
+ QFETCH(QMetaType, typeB);
+ QFETCH(bool, eq);
+
+ QCOMPARE(typeA == typeB, eq);
+ QCOMPARE(typeB == typeA, eq);
+ QCOMPARE(typeA != typeB, !eq);
+ QCOMPARE(typeB != typeA, !eq);
+
+#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
+ // for built-in types or locally-defined types, this must also hold true
+ if (eq)
+ QCOMPARE(typeA.iface(), typeB.iface());
+#endif
+}
+
+void tst_QMetaType::operatorEq2_data()
+{
+ create_data();
+}
+
+void tst_QMetaType::operatorEq2()
+{
+ QFETCH(int, type);
+ QMetaType fromType1, fromType2;
+ QMetaType fromId1(type), fromId2(type);
+
+ switch (type) {
+ case QMetaType::UnknownType:
+ break;
+#define GET_METATYPE_FROM_TYPE(MetaTypeName, MetaTypeId, RealType) \
+ case QMetaType::MetaTypeName: \
+ fromType1 = QMetaType::fromType<RealType>(); \
+ fromType2 = QMetaType::fromType<RealType>(); \
+ break;
+FOR_EACH_CORE_METATYPE(GET_METATYPE_FROM_TYPE)
+#undef GET_METATYPE_FROM_TYPE
+ }
+
+ // sanity check
+ QCOMPARE(fromId1.id(), type);
+ QCOMPARE(fromId2.id(), type);
+
+ // confirm that they're all equal
+ QCOMPARE(fromId1, fromId2);
+ QCOMPARE(fromType1, fromType2);
+ QCOMPARE(fromType1, fromId1);
+ QCOMPARE(fromType2, fromId2);
+
+#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
+ // for built-in types (other than void), this must be true
+ if (type != QMetaType::Void) {
+ QCOMPARE(fromType1.iface(), fromId1.iface());
+ QCOMPARE(fromType2.iface(), fromId1.iface());
+ }
+#endif
+}
+
+#define DECLARE_LIB_FUNCTION(TYPE, ID) \
+ Q_DECL_IMPORT QMetaType metatype_ ## TYPE();
+namespace Lib1 { FOR_EACH_METATYPE_LIBS(DECLARE_LIB_FUNCTION) }
+namespace Lib2 { FOR_EACH_METATYPE_LIBS(DECLARE_LIB_FUNCTION) }
+#undef DECLARE_LIB_FUNCTION
+
+using LibMetatypeFunction = QMetaType (*)();
+void tst_QMetaType::operatorEqAcrossLibs_data()
+{
+ QTest::addColumn<int>("builtinTypeId");
+ QTest::addColumn<QMetaType>("localType");
+ QTest::addColumn<LibMetatypeFunction>("lib1Function");
+ QTest::addColumn<LibMetatypeFunction>("lib2Function");
+
+#define ADD_ROW(TYPE, ID) \
+ QTest::addRow(QT_STRINGIFY(TYPE)) << int(ID) \
+ << QMetaType::fromType<TYPE>() \
+ << &Lib1::metatype_ ## TYPE \
+ << &Lib2::metatype_ ## TYPE;
+FOR_EACH_METATYPE_LIBS(ADD_ROW)
+#undef ADD_ROW
+}
+
+void tst_QMetaType::operatorEqAcrossLibs()
+{
+ QFETCH(int, builtinTypeId);
+ QFETCH(QMetaType, localType);
+ QFETCH(LibMetatypeFunction, lib1Function);
+ QFETCH(LibMetatypeFunction, lib2Function);
+
+ QMetaType lib1Type = lib1Function();
+ QMetaType lib2Type = lib2Function();
+
+ const QtPrivate::QMetaTypeInterface *localIface = localType.iface();
+ const QtPrivate::QMetaTypeInterface *lib1Iface = lib1Type.iface();
+ const QtPrivate::QMetaTypeInterface *lib2Iface = lib2Type.iface();
+
+ // DO THIS FIRST:
+ // if this isn't a built-in type, then the QMetaTypeInterface::typeId is
+ // initially set to 0
+ QCOMPARE(lib1Type, lib2Type);
+
+ int actualTypeId = localType.id();
+ bool builtinTypeExpected = builtinTypeId != QMetaType::UnknownType;
+ bool builtinTypeActually = actualTypeId < QMetaType::User;
+
+ qDebug() << "QMetaType for type" << QByteArray(localType.name())
+ << "(type ID" << (actualTypeId >= 0x1000 ? Qt::hex : Qt::dec) << actualTypeId << ')'
+ << (builtinTypeActually ? "IS" : "is NOT") << "a built-in type;"
+ << "local interface:" << static_cast<const void *>(localIface)
+ << "lib1 interface:" << static_cast<const void *>(lib1Iface)
+ << "lib2 interface:" << static_cast<const void *>(lib2Iface);
+
+ QCOMPARE(builtinTypeActually, builtinTypeExpected);
+ QCOMPARE(lib1Type.id(), actualTypeId);
+ QCOMPARE(lib2Type.id(), actualTypeId);
+ QCOMPARE(QByteArray(lib1Type.name()), QByteArray(localType.name()));
+ QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name()));
+ QCOMPARE(lib1Type, localType);
+ QCOMPARE(lib2Type, localType);
+
+#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
+ if (actualTypeId < QMetaType::FirstGuiType && actualTypeId != QMetaType::Void) {
+ // for built-in QtCore types, we expect the interfaces to be the same too
+ QCOMPARE(lib1Iface, localIface);
+ QCOMPARE(lib2Iface, localIface);
+ }
+#endif
+}
+
+class WithPrivateDTor {
+ ~WithPrivateDTor(){};
+};
+
+struct WithDeletedDtor {
+ ~WithDeletedDtor() = delete;
+};
+
+void tst_QMetaType::typesWithInaccessibleDTors()
+{
+ // should compile
+ Q_UNUSED(QMetaType::fromType<WithPrivateDTor>());
+ Q_UNUSED(QMetaType::fromType<WithDeletedDtor>());
+}
+
+void tst_QMetaType::voidIsNotUnknown()
+{
+ QMetaType voidType = QMetaType::fromType<void>();
+ QMetaType voidType2 = QMetaType(QMetaType::Void);
+ QCOMPARE(voidType, voidType2);
+ QVERIFY(voidType != QMetaType(QMetaType::UnknownType));
+}
+
+void tst_QMetaType::typeNameNormalization()
+{
+ // check the we normalize types the right way
+#define CHECK_TYPE_NORMALIZATION(Normalized, ...) \
+ do { \
+ /*QCOMPARE(QtPrivate::typenameHelper<Type>(), Normalized);*/ \
+ QByteArray typeName = QMetaObject::normalizedType(#__VA_ARGS__); \
+ QCOMPARE(typeName, Normalized); \
+ typeName = QMetaType::fromType<__VA_ARGS__>().name(); \
+ QCOMPARE(typeName, Normalized); \
+ } while (0)
+
+ CHECK_TYPE_NORMALIZATION("QList<QString*const>", QList<QString * const>);
+ CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<const QString * >);
+ CHECK_TYPE_NORMALIZATION("QList<const QString*const>", QList<const QString * const>);
+ CHECK_TYPE_NORMALIZATION("QList<const QString*>", QList<QString const *>);
+ CHECK_TYPE_NORMALIZATION("QList<signed char>", QList<signed char>);
+ CHECK_TYPE_NORMALIZATION("QList<uint>", QList<unsigned>);
+ CHECK_TYPE_NORMALIZATION("uint", uint);
+ CHECK_TYPE_NORMALIZATION("QList<QHash<uint,QString*>>", QList<QHash<unsigned, QString *>>);
+ CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<qlonglong>);
+ CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<qulonglong>);
+ CHECK_TYPE_NORMALIZATION("QList<qlonglong>", QList<long long>);
+ CHECK_TYPE_NORMALIZATION("QList<qulonglong>", QList<unsigned long long>);
+ CHECK_TYPE_NORMALIZATION("QList<qulonglong*>", QList<unsigned long long *>);
+ CHECK_TYPE_NORMALIZATION("QList<ulong>", QList<long unsigned >);
+#ifdef Q_CC_MSVC
+ CHECK_TYPE_NORMALIZATION("qulonglong", __int64 unsigned);
+#endif
+ CHECK_TYPE_NORMALIZATION("std::pair<const QString&&,short>", QPair<const QString &&, signed short>);
+
+ // The string based normalization doesn't handle aliases, QMetaType::fromType() does
+// CHECK_TYPE_NORMALIZATION("qulonglong", quint64);
+ QCOMPARE(QMetaType::fromType<quint64>().name(), "qulonglong");
+
+ // noramlizedType and metatype name agree
+ {
+ auto type = QMetaType::fromType<decltype(CharTemplate<'<'>::x)>();
+ QCOMPARE(type.name(), QMetaObject::normalizedType(type.name()));
+ }
+ {
+ auto type = QMetaType::fromType<decltype(CharTemplate<'<'>::y)>();
+ QCOMPARE(type.name(), QMetaObject::normalizedType(type.name()));
+ }
+}
+
+QT_BEGIN_NAMESPACE
+namespace QtPrivate { struct tst_QMetaType_TestType {}; }
+QT_END_NAMESPACE
+
+void tst_QMetaType::typeNameInQtPrivate()
+{
+ using T = QT_PREPEND_NAMESPACE(QtPrivate::tst_QMetaType_TestType);
+
+ // some compilers (GCC) are known to suppress the namespace prefix if the
+ // type and the function where it is expanded on are on the same namespace
+ static constexpr char expectedName[] = "QtPrivate::tst_QMetaType_TestType";
+ QMetaType mt = QMetaType::fromType<T>();
+ QCOMPARE(mt.name(), expectedName);
+}
+
+#if QT_DEPRECATED_SINCE(6, 0)
+void tst_QMetaType::testDeprecatedGetters()
+{
+ QFETCH(int, aType);
+ QFETCH(QByteArray, aTypeName);
+
+ if (aType >= QMetaType::FirstWidgetsType)
+ QSKIP("The test doesn't link against QtWidgets.");
+
+ // QMetaType::type("name") -> QMetaType::fromName("name").id()
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(QMetaType::type(aTypeName),
+ QMetaType::fromName(aTypeName).id());)
+ // QMetaType::typeName(int) -> QMetaType(int).name()
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(QLatin1String(QMetaType::typeName(aType)),
+ QLatin1String(QMetaType(aType).name()));)
+ // QMetaType::typeFlags(int) -> QMetaType(int).flags()
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(QMetaType::typeFlags(aType),
+ QMetaType(aType).flags());)
+ // QMetaType::metaObjectForType(int) -> QMetaType(int).metaObject()
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(QMetaType::metaObjectForType(aType),
+ QMetaType(aType).metaObject());)
+}
+
+void tst_QMetaType::testDeprecatedLoadSave()
+{
+ QFETCH(int, type);
+ QFETCH(bool, isStreamable);
+
+ if (!isStreamable)
+ return;
+
+ QMetaType metaType(type);
+ void *value = metaType.create();
+ auto cleanup = qScopeGuard([&metaType, value]() {
+ metaType.destroy(value);
+ });
+
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::ReadWrite);
+
+ // Write using deprecated API
+ QT_IGNORE_DEPRECATIONS(QVERIFY(QMetaType::save(stream, type, value));)
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ // Read using non-deprecated API
+ stream.device()->seek(0);
+ QVERIFY(metaType.load(stream, value));
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ // Write using non-deprecated API
+ stream.device()->seek(0);
+ ba.clear();
+ QVERIFY(metaType.save(stream, value));
+ QCOMPARE(stream.status(), QDataStream::Ok);
+
+ // Read using deprecated API
+ stream.device()->seek(0);
+ QT_IGNORE_DEPRECATIONS(QVERIFY(QMetaType::load(stream, type, value));)
+ QCOMPARE(stream.status(), QDataStream::Ok);
+}
+#endif // QT_DEPRECATED_SINCE(6, 0)
+
+// Compile-time test, it should be possible to register function pointer types
+class Undefined;
+
+typedef Undefined (*UndefinedFunction0)();
+typedef Undefined (*UndefinedFunction1)(Undefined);
+typedef Undefined (*UndefinedFunction2)(Undefined, Undefined);
+typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined);
+typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined);
+
+Q_DECLARE_METATYPE(UndefinedFunction0);
+Q_DECLARE_METATYPE(UndefinedFunction1);
+Q_DECLARE_METATYPE(UndefinedFunction2);
+Q_DECLARE_METATYPE(UndefinedFunction3);
+Q_DECLARE_METATYPE(UndefinedFunction4);
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype3.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype3.cpp
new file mode 100644
index 0000000000..779044589c
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype3.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "tst_qmetatype.h"
+
+#include <QtCore/private/qmetaobjectbuilder_p.h>
+
+
+void tst_QMetaType::automaticTemplateRegistration_2()
+{
+ FOR_EACH_STATIC_PRIMITIVE_TYPE(
+ PRINT_2ARG_TEMPLATE
+ )
+}
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h
new file mode 100644
index 0000000000..ea59b5cd02
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_common.h
@@ -0,0 +1,269 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+// Used by both tst_qmetatype and tst_qsettings
+
+#ifndef TST_QMETATYPE_H
+#define TST_QMETATYPE_H
+
+#include <QtCore>
+
+#include <float.h>
+
+#define FOR_EACH_PRIMITIVE_METATYPE(F) \
+ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
+ QT_FOR_EACH_STATIC_CORE_POINTER(F) \
+
+#define FOR_EACH_COMPLEX_CORE_METATYPE(F) \
+ QT_FOR_EACH_STATIC_CORE_CLASS(F) \
+ QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
+
+#define FOR_EACH_CORE_METATYPE(F) \
+ FOR_EACH_PRIMITIVE_METATYPE(F) \
+ FOR_EACH_COMPLEX_CORE_METATYPE(F) \
+
+template <int ID>
+struct MetaEnumToType {};
+
+#define DEFINE_META_ENUM_TO_TYPE(MetaTypeName, MetaTypeId, RealType) \
+template<> \
+struct MetaEnumToType<QMetaType::MetaTypeName> { \
+ typedef RealType Type; \
+};
+FOR_EACH_CORE_METATYPE(DEFINE_META_ENUM_TO_TYPE)
+#undef DEFINE_META_ENUM_TO_TYPE
+
+template <int ID>
+struct DefaultValueFactory
+{
+ typedef typename MetaEnumToType<ID>::Type Type;
+ static Type *create() { return new Type(); }
+};
+
+template <>
+struct DefaultValueFactory<QMetaType::Void>
+{
+ typedef MetaEnumToType<QMetaType::Void>::Type Type;
+ static Type *create() { return nullptr; }
+};
+
+template <int ID>
+struct DefaultValueTraits
+{
+ // By default we assume that a default-constructed value (new T) is
+ // initialized; e.g. QCOMPARE(*(new T), *(new T)) should succeed
+ enum { IsInitialized = true };
+};
+
+template <int ID>
+struct TestValueFactory {};
+
+template<> struct TestValueFactory<QMetaType::Void> {
+ static void *create() { return 0; }
+};
+
+template<> struct TestValueFactory<QMetaType::QString> {
+ static QString *create() { return new QString(QString::fromLatin1("QString")); }
+};
+template<> struct TestValueFactory<QMetaType::Int> {
+ static int *create() { return new int(INT_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::UInt> {
+ static uint *create() { return new uint(UINT_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::Bool> {
+ static bool *create() { return new bool(true); }
+};
+template<> struct TestValueFactory<QMetaType::Double> {
+ static double *create() { return new double(DBL_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::QByteArray> {
+ static QByteArray *create() { return new QByteArray(QByteArray("QByteArray")); }
+};
+template<> struct TestValueFactory<QMetaType::QByteArrayList> {
+ static QByteArrayList *create() { return new QByteArrayList(QByteArrayList() << "Q" << "Byte" << "Array" << "List"); }
+};
+template<> struct TestValueFactory<QMetaType::QVariantMap> {
+ static QVariantMap *create() { return new QVariantMap(); }
+};
+template<> struct TestValueFactory<QMetaType::QVariantHash> {
+ static QVariantHash *create() { return new QVariantHash(); }
+};
+template<> struct TestValueFactory<QMetaType::QVariantPair> {
+ static QVariantPair *create() { return new QVariantPair(); }
+};
+
+template<> struct TestValueFactory<QMetaType::QVariantList> {
+ static QVariantList *create() { return new QVariantList(QVariantList() << 123 << "Q" << "Variant" << "List"); }
+};
+template<> struct TestValueFactory<QMetaType::QChar> {
+ static QChar *create() { return new QChar(QChar('q')); }
+};
+template<> struct TestValueFactory<QMetaType::Long> {
+ static long *create() { return new long(LONG_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::Short> {
+ static short *create() { return new short(SHRT_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::Char> {
+ static char *create() { return new char('c'); }
+};
+template<> struct TestValueFactory<QMetaType::Char16> {
+ static char16_t *create() { return new char16_t('c'); }
+};
+template<> struct TestValueFactory<QMetaType::Char32> {
+ static char32_t *create() { return new char32_t('c'); }
+};
+template<> struct TestValueFactory<QMetaType::ULong> {
+ static ulong *create() { return new ulong(ULONG_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::UShort> {
+ static ushort *create() { return new ushort(USHRT_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::SChar> {
+ static signed char *create() { return new signed char(CHAR_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::UChar> {
+ static uchar *create() { return new uchar(UCHAR_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::Float> {
+ static float *create() { return new float(FLT_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::Float16> {
+ static auto create() { return new qfloat16(std::numeric_limits<qfloat16>::min()); }
+};
+template<> struct TestValueFactory<QMetaType::QObjectStar> {
+ static QObject * *create() { return new QObject *(0); }
+};
+template<> struct TestValueFactory<QMetaType::VoidStar> {
+ static void * *create() { return new void *(0); }
+};
+template<> struct TestValueFactory<QMetaType::LongLong> {
+ static qlonglong *create() { return new qlonglong(LLONG_MIN); }
+};
+template<> struct TestValueFactory<QMetaType::ULongLong> {
+ static qulonglong *create() { return new qulonglong(ULLONG_MAX); }
+};
+template<> struct TestValueFactory<QMetaType::QStringList> {
+ static QStringList *create() { return new QStringList(QStringList() << "Q" << "t"); }
+};
+template<> struct TestValueFactory<QMetaType::QBitArray> {
+ static QBitArray *create() { return new QBitArray(QBitArray(256, true)); }
+};
+template<> struct TestValueFactory<QMetaType::QDate> {
+ static QDate *create() { return new QDate(QDate::currentDate()); }
+};
+template<> struct TestValueFactory<QMetaType::QTime> {
+ static QTime *create() { return new QTime(QTime::currentTime()); }
+};
+template<> struct TestValueFactory<QMetaType::QDateTime> {
+ static QDateTime *create() { return new QDateTime(QDateTime::currentDateTime()); }
+};
+template<> struct TestValueFactory<QMetaType::QUrl> {
+ static QUrl *create() { return new QUrl("http://www.example.org"); }
+};
+template<> struct TestValueFactory<QMetaType::QLocale> {
+ static QLocale *create() { return new QLocale(QLocale::c()); }
+};
+template<> struct TestValueFactory<QMetaType::QRect> {
+ static QRect *create() { return new QRect(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QRectF> {
+ static QRectF *create() { return new QRectF(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QSize> {
+ static QSize *create() { return new QSize(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QSizeF> {
+ static QSizeF *create() { return new QSizeF(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QLine> {
+ static QLine *create() { return new QLine(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QLineF> {
+ static QLineF *create() { return new QLineF(10, 20, 30, 40); }
+};
+template<> struct TestValueFactory<QMetaType::QPoint> {
+ static QPoint *create() { return new QPoint(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QPointF> {
+ static QPointF *create() { return new QPointF(10, 20); }
+};
+template<> struct TestValueFactory<QMetaType::QEasingCurve> {
+ static QEasingCurve *create() { return new QEasingCurve(QEasingCurve::InOutElastic); }
+};
+template<> struct TestValueFactory<QMetaType::QUuid> {
+ static QUuid *create() { return new QUuid(); }
+};
+template<> struct TestValueFactory<QMetaType::QModelIndex> {
+ static QModelIndex *create() { return new QModelIndex(); }
+};
+template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> {
+ static QPersistentModelIndex *create() { return new QPersistentModelIndex(); }
+};
+template<> struct TestValueFactory<QMetaType::Nullptr> {
+ static std::nullptr_t *create() { return new std::nullptr_t; }
+};
+template<> struct TestValueFactory<QMetaType::QRegularExpression> {
+ static QRegularExpression *create()
+ {
+#if QT_CONFIG(regularexpression)
+ return new QRegularExpression("abc.*def");
+#else
+ return 0;
+#endif
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonValue> {
+ static QJsonValue *create() { return new QJsonValue(123.); }
+};
+template<> struct TestValueFactory<QMetaType::QJsonObject> {
+ static QJsonObject *create() {
+ QJsonObject *o = new QJsonObject();
+ o->insert("a", 123.);
+ o->insert("b", true);
+ o->insert("c", QJsonValue::Null);
+ o->insert("d", QLatin1String("ciao"));
+ return o;
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonArray> {
+ static QJsonArray *create() {
+ QJsonArray *a = new QJsonArray();
+ a->append(123.);
+ a->append(true);
+ a->append(QJsonValue::Null);
+ a->append(QLatin1String("ciao"));
+ return a;
+ }
+};
+template<> struct TestValueFactory<QMetaType::QJsonDocument> {
+ static QJsonDocument *create() {
+ return new QJsonDocument(
+ QJsonDocument::fromJson("{ 'foo': 123, 'bar': [true, null, 'ciao'] }")
+ );
+ }
+};
+
+template<> struct TestValueFactory<QMetaType::QCborSimpleType> {
+ static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
+};
+template<> struct TestValueFactory<QMetaType::QCborValue> {
+ static QCborValue *create() { return new QCborValue(123.); }
+};
+template<> struct TestValueFactory<QMetaType::QCborMap> {
+ static QCborMap *create() {
+ return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
+ }
+};
+template<> struct TestValueFactory<QMetaType::QCborArray> {
+ static QCborArray *create() {
+ return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
+ }
+};
+
+template<> struct TestValueFactory<QMetaType::QVariant> {
+ static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
+};
+
+#endif // TST_QMETATYPE_H
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h
new file mode 100644
index 0000000000..673fc9083c
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2022 Intel Corporation
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef TST_QMETATYPE_LIBS_H
+#define TST_QMETATYPE_LIBS_H
+
+#include <qmetatype.h>
+
+#include <stdlib.h> // for div_t
+
+// void: builtin metatype, special
+// int: builtin metatype, primitive type
+// QString: builtin metatype, class
+// QCollator: not builtin, class, Q_CORE_EXPORT
+// div_t: not builtin, class, no export
+#define FOR_EACH_METATYPE_LIBS(F) \
+ F(void, QMetaType::Void) \
+ F(int, QMetaType::Int) \
+ F(QString, QMetaType::QString) \
+ F(QCollator, QMetaType::UnknownType) \
+ F(div_t, QMetaType::UnknownType) \
+ /**/
+
+#endif // TST_QMETATYPE_LIBS_H
diff --git a/tests/auto/corelib/kernel/qmetatype/typeFlags.bin b/tests/auto/corelib/kernel/qmetatype/typeFlags.bin
index 7009be98a2..7d5d9c7a50 100644
--- a/tests/auto/corelib/kernel/qmetatype/typeFlags.bin
+++ b/tests/auto/corelib/kernel/qmetatype/typeFlags.bin
Binary files differ
diff --git a/tests/auto/corelib/kernel/qmimedata/CMakeLists.txt b/tests/auto/corelib/kernel/qmimedata/CMakeLists.txt
new file mode 100644
index 0000000000..ba1d5e12cd
--- /dev/null
+++ b/tests/auto/corelib/kernel/qmimedata/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmimedata Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmimedata LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmimedata
+ SOURCES
+ tst_qmimedata.cpp
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/kernel/qmimedata/qmimedata.pro b/tests/auto/corelib/kernel/qmimedata/qmimedata.pro
deleted file mode 100644
index 502ec78024..0000000000
--- a/tests/auto/corelib/kernel/qmimedata/qmimedata.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmimedata
-QT += testlib
-SOURCES = tst_qmimedata.cpp
diff --git a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp
index e3b2399456..e28a2e98cc 100644
--- a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp
+++ b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QMimeData>
@@ -96,13 +71,28 @@ void tst_QMimeData::data() const
// set text, verify
mimeData.setData("text/plain", "pirates");
QCOMPARE(mimeData.data("text/plain"), QByteArray("pirates"));
- QCOMPARE(mimeData.data("text/html").length(), 0);
+ QCOMPARE(mimeData.data("text/html").size(), 0);
+ QCOMPARE(mimeData.data("text/markdown").size(), 0);
// html time
mimeData.setData("text/html", "ninjas");
QCOMPARE(mimeData.data("text/html"), QByteArray("ninjas"));
QCOMPARE(mimeData.data("text/plain"), QByteArray("pirates")); // make sure text not damaged
QCOMPARE(mimeData.data("text/html"), mimeData.html().toLatin1());
+
+ // markdown time
+ mimeData.setData("text/markdown", "vikings");
+ QCOMPARE(mimeData.data("text/markdown"), QByteArray("vikings"));
+ QCOMPARE(mimeData.data("text/html"), QByteArray("ninjas"));
+ QCOMPARE(mimeData.data("text/plain"), QByteArray("pirates"));
+
+ // URI list
+ QByteArray list = "https://example.com/\r\nhttps://example.net/\r\nhttps://example.org/\r\n";
+ mimeData.setData("text/uri-list", list);
+ QCOMPARE(mimeData.data("text/uri-list"), list);
+
+ mimeData.setData("text/uri-list", list.chopped(2)); // without the ending CRLF
+ QCOMPARE(mimeData.data("text/uri-list"), list);
}
void tst_QMimeData::formats() const
@@ -117,6 +107,10 @@ void tst_QMimeData::formats() const
mimeData.setData("text/html", "ninjas");
QCOMPARE(mimeData.formats(), QStringList() << "text/plain" << "text/html");
+ // set markdown, verify
+ mimeData.setData("text/markdown", "vikings");
+ QCOMPARE(mimeData.formats(), QStringList() << "text/plain" << "text/html" << "text/markdown");
+
// clear, verify
mimeData.clear();
QCOMPARE(mimeData.formats(), QStringList());
@@ -324,10 +318,11 @@ void tst_QMimeData::setUrls() const
QCOMPARE(mimeData.text(), QString("http://qt-project.org\nhttp://www.google.com\n"));
// test and verify that setData doesn't corrupt url content
- foreach (const QString &format, mimeData.formats()) {
- QVariant before = mimeData.retrieveData(format, QVariant::ByteArray);
+ const auto allFormats = mimeData.formats();
+ for (const QString &format : allFormats) {
+ QVariant before = mimeData.retrieveData(format, QMetaType(QMetaType::QByteArray));
mimeData.setData(format, mimeData.data(format));
- QVariant after = mimeData.retrieveData(format, QVariant::ByteArray);
+ QVariant after = mimeData.retrieveData(format, QMetaType(QMetaType::QByteArray));
QCOMPARE(after, before);
}
diff --git a/tests/auto/corelib/kernel/qobject/BLACKLIST b/tests/auto/corelib/kernel/qobject/BLACKLIST
deleted file mode 100644
index 0887a73b4c..0000000000
--- a/tests/auto/corelib/kernel/qobject/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[moveToThread]
-windows
diff --git a/tests/auto/corelib/kernel/qobject/CMakeLists.txt b/tests/auto/corelib/kernel/qobject/CMakeLists.txt
new file mode 100644
index 0000000000..46b8e2d238
--- /dev/null
+++ b/tests/auto/corelib/kernel/qobject/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qobject Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qobject LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qobject
+ SOURCES
+ tst_qobject.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
+add_subdirectory(signalbug)
+add_dependencies(tst_qobject signalbug_helper)
diff --git a/tests/auto/corelib/kernel/qobject/qobject.pro b/tests/auto/corelib/kernel/qobject/qobject.pro
deleted file mode 100644
index 75ad7b5f14..0000000000
--- a/tests/auto/corelib/kernel/qobject/qobject.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += test.pro
-!winrt: SUBDIRS += signalbug
diff --git a/tests/auto/corelib/kernel/qobject/signalbug/CMakeLists.txt b/tests/auto/corelib/kernel/qobject/signalbug/CMakeLists.txt
new file mode 100644
index 0000000000..aefa1554b6
--- /dev/null
+++ b/tests/auto/corelib/kernel/qobject/signalbug/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## signalbug_helper Binary:
+#####################################################################
+
+qt_internal_add_test_helper(signalbug_helper
+ SOURCES
+ signalbug.cpp signalbug.h
+)
diff --git a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.cpp b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.cpp
index 57fb1eb836..bb8d7984f4 100644
--- a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.cpp
+++ b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "signalbug.h"
diff --git a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.h b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.h
index e6e40c35d9..ac124c2a1c 100644
--- a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.h
+++ b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef SIGNAL_BUG_H
#define SIGNAL_BUG_H
diff --git a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro
deleted file mode 100644
index d21b3a62a9..0000000000
--- a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-QT = core
-
-HEADERS += signalbug.h
-SOURCES += signalbug.cpp
-
-load(qt_test_helper)
diff --git a/tests/auto/corelib/kernel/qobject/test.pro b/tests/auto/corelib/kernel/qobject/test.pro
deleted file mode 100644
index af5203e152..0000000000
--- a/tests/auto/corelib/kernel/qobject/test.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-CONFIG += testcase console
-
-QT = core-private network testlib
-TARGET = tst_qobject
-SOURCES = tst_qobject.cpp
-
-# Force C++17 if available (needed due to P0012R1)
-contains(QT_CONFIG, c++1z): CONFIG += c++1z
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 06254091cd..6c387fde96 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -1,38 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2020 Olivier Goffart <ogoffart@woboq.com>
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+// This test actually wants to practice narrowing conditions, so never define this.
+#ifdef QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
+#undef QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
+#endif
+
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
+#include <QStringListModel>
+#include <QAbstractEventDispatcher>
+#include <QScopedValueRollback>
#include <qcoreapplication.h>
#include <qpointer.h>
+#include <qproperty.h>
#include <qtimer.h>
-#include <qregexp.h>
#include <qregularexpression.h>
#include <qmetaobject.h>
#include <qvariant.h>
@@ -41,6 +26,7 @@
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
+#include <QScopedPointer>
#if QT_CONFIG(process)
# include <QProcess>
#endif
@@ -49,8 +35,12 @@
#include <private/qobject_p.h>
#endif
+#include <functional>
+
#include <math.h>
+using namespace Qt::StringLiterals;
+
class tst_QObject : public QObject
{
Q_OBJECT
@@ -69,6 +59,8 @@ private slots:
void disconnectNotify_metaObjConnection();
void connectNotify_connectSlotsByName();
void connectDisconnectNotify_shadowing();
+ void connectReferenceToIncompleteTypes();
+ void connectAutoQueuedIncomplete();
void emitInDefinedOrder();
void customTypes();
void streamCustomTypes();
@@ -81,7 +73,6 @@ private slots:
void senderTest();
void declareInterface();
void qpointerResetBeforeDestroyedSignal();
- void testUserData();
void childDeletesItsSibling();
void dynamicProperties();
void floatProperty();
@@ -91,10 +82,13 @@ private slots:
void signalBlocking();
void blockingQueuedConnection();
void childEvents();
+ void parentEvents();
void installEventFilter();
+ void installEventFilterOrder();
void deleteSelfInSlot();
void disconnectSelfInSlotAndDeleteAfterEmit();
void dumpObjectInfo();
+ void dumpObjectTree();
void connectToSender();
void qobjectConstCast();
void uniqConnection();
@@ -147,12 +141,19 @@ private slots:
void connectBase();
void connectWarnings();
void qmlConnect();
+ void qmlConnectToQObjectReceiver();
void exceptions();
- void noDeclarativeParentChangedOnDestruction();
void deleteLaterInAboutToBlockHandler();
void mutableFunctor();
void checkArgumentsForNarrowing();
void nullReceiver();
+ void functorReferencesConnection();
+ void disconnectDisconnects();
+ void singleShotConnection();
+ void objectNameBinding();
+ void emitToDestroyedClass();
+ void declarativeData();
+ void asyncCallbackHelper();
};
struct QObjectCreatedOnShutdown
@@ -206,7 +207,11 @@ protected:
Q_INVOKABLE QT_MOC_COMPAT void invoke2(int){}
Q_SCRIPTABLE QT_MOC_COMPAT void sinvoke2(){}
private:
- Q_INVOKABLE void invoke3(int hinz = 0, int kunz = 0){Q_UNUSED(hinz) Q_UNUSED(kunz)}
+ Q_INVOKABLE void invoke3(int hinz = 0, int kunz = 0)
+ {
+ Q_UNUSED(hinz);
+ Q_UNUSED(kunz);
+ }
Q_SCRIPTABLE void sinvoke3(){}
int recursionCount;
@@ -285,104 +290,100 @@ static void playWithObjects()
void tst_QObject::disconnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
- connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
- connect( s, SIGNAL(signal2()), r1, SLOT(slot2()) );
- connect( s, SIGNAL(signal3()), r1, SLOT(slot3()) );
- connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) );
+ connect(&s, SIGNAL(signal2()), &r1, SLOT(slot2()));
+ connect(&s, SIGNAL(signal3()), &r1, SLOT(slot3()));
+ connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()));
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(r1->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(r1.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// usual disconnect with all parameters given
- bool ret = QObject::disconnect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
+ bool ret = QObject::disconnect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
- s->emitSignal1();
+ s.emitSignal1();
- QVERIFY(!r1->called(1));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ r1.reset();
QVERIFY(ret);
- ret = QObject::disconnect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
+ ret = QObject::disconnect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
QVERIFY(!ret);
// disconnect all signals from s from all slots from r1
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(!r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(!r1.called(4));
+ r1.reset();
- connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
- connect( s, SIGNAL(signal1()), r1, SLOT(slot2()) );
- connect( s, SIGNAL(signal1()), r1, SLOT(slot3()) );
- connect( s, SIGNAL(signal2()), r1, SLOT(slot4()) );
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot2()));
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot3()));
+ connect(&s, SIGNAL(signal2()), &r1, SLOT(slot4()));
// disconnect s's signal1() from all slots of r1
- QObject::disconnect( s, SIGNAL(signal1()), r1, 0 );
+ QObject::disconnect(&s, SIGNAL(signal1()), &r1, 0);
- s->emitSignal1();
- s->emitSignal2();
+ s.emitSignal1();
+ s.emitSignal2();
- QVERIFY(!r1->called(1));
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// make sure all is disconnected again
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) );
- connect( s, SIGNAL(signal1()), r2, SLOT(slot1()) );
- connect( s, SIGNAL(signal2()), r1, SLOT(slot2()) );
- connect( s, SIGNAL(signal2()), r2, SLOT(slot2()) );
- connect( s, SIGNAL(signal3()), r1, SLOT(slot3()) );
- connect( s, SIGNAL(signal3()), r2, SLOT(slot3()) );
+ connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()));
+ connect(&s, SIGNAL(signal1()), &r2, SLOT(slot1()));
+ connect(&s, SIGNAL(signal2()), &r1, SLOT(slot2()));
+ connect(&s, SIGNAL(signal2()), &r2, SLOT(slot2()));
+ connect(&s, SIGNAL(signal3()), &r1, SLOT(slot3()));
+ connect(&s, SIGNAL(signal3()), &r2, SLOT(slot3()));
// disconnect signal1() from all receivers
- QObject::disconnect( s, SIGNAL(signal1()), 0, 0 );
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
+ QObject::disconnect(&s, SIGNAL(signal1()), 0, 0);
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
- QVERIFY(!r1->called(1));
- QVERIFY(!r2->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r2.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
// disconnect all signals of s from all receivers
- QObject::disconnect( s, 0, 0, 0 );
+ QObject::disconnect(&s, 0, 0, 0);
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
-
- delete r2;
- delete r1;
- delete s;
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
}
class AutoConnectSender : public QObject
@@ -429,15 +430,12 @@ public:
public slots:
void on_Sender_signalNoParams() { called_slots << 1; }
- void on_Sender_signalWithParams(int i = 0) { called_slots << 2; Q_UNUSED(i); }
- void on_Sender_signalWithParams(int i, QString string) { called_slots << 3; Q_UNUSED(i);Q_UNUSED(string); }
+ void on_Sender_signalWithParams(int = 0) { called_slots << 2; }
+ void on_Sender_signalWithParams(int, QString) { called_slots << 3; }
void on_Sender_signalManyParams() { called_slots << 4; }
- void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff)
- { called_slots << 5; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); }
- void on_Sender_signalManyParams(int i1, int i2, int i3, QString string, bool onoff, bool dummy)
- { called_slots << 6; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); Q_UNUSED(dummy);}
- void on_Sender_signalManyParams2(int i1, int i2, int i3, QString string, bool onoff)
- { called_slots << 7; Q_UNUSED(i1);Q_UNUSED(i2);Q_UNUSED(i3);Q_UNUSED(string);Q_UNUSED(onoff); }
+ void on_Sender_signalManyParams(int, int, int, QString, bool) { called_slots << 5; }
+ void on_Sender_signalManyParams(int, int, int, QString, bool, bool) { called_slots << 6; }
+ void on_Sender_signalManyParams2(int, int, int, QString, bool) { called_slots << 7; }
void slotLoopBack() { called_slots << 8; }
void on_Receiver_signalNoParams() { called_slots << 9; }
void on_Receiver_signal_with_underscore() { called_slots << 10; }
@@ -463,7 +461,7 @@ void tst_QObject::connectSlotsByName()
sender.setObjectName("Sender");
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: No matching signal for on_child_signal()");
- QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: Connecting slot on_Sender_signalManyParams() with the first of the following compatible signals: (\"signalManyParams(int,int,int,QString,bool)\", \"signalManyParams(int,int,int,QString,bool,bool)\")");
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: Connecting slot on_Sender_signalManyParams() with the first of the following compatible signals: QList(\"signalManyParams(int,int,int,QString,bool)\", \"signalManyParams(int,int,int,QString,bool,bool)\")");
QMetaObject::connectSlotsByName(&receiver);
receiver.called_slots.clear();
@@ -504,16 +502,21 @@ void tst_QObject::connectSlotsByName()
void tst_QObject::qobject_castTemplate()
{
- QObject *o = 0;
- QVERIFY( !::qobject_cast<QObject*>(o) );
+ QScopedPointer<QObject> o;
+ QVERIFY(!::qobject_cast<QObject*>(o.data()));
- o = new SenderObject;
- QVERIFY( ::qobject_cast<SenderObject*>(o) );
- QVERIFY( ::qobject_cast<QObject*>(o) );
- QVERIFY( !::qobject_cast<ReceiverObject*>(o) );
- delete o;
+ o.reset(new SenderObject);
+ QVERIFY(::qobject_cast<SenderObject*>(o.data()));
+ QVERIFY(::qobject_cast<QObject*>(o.data()));
+ QVERIFY(!::qobject_cast<ReceiverObject*>(o.data()));
}
+class DerivedObj : public QObject {
+ Q_OBJECT
+public:
+ using QObject::QObject;
+};
+
void tst_QObject::findChildren()
{
QObject o;
@@ -526,6 +529,10 @@ void tst_QObject::findChildren()
QTimer t1(&o);
QTimer t121(&o12);
QTimer emptyname(&o);
+ QObject oo;
+ QObject o21(&oo);
+ QObject o22(&oo);
+ QObject o23(&oo);
Q_SET_OBJECT_NAME(o);
Q_SET_OBJECT_NAME(o1);
@@ -536,94 +543,122 @@ void tst_QObject::findChildren()
Q_SET_OBJECT_NAME(t1);
Q_SET_OBJECT_NAME(t121);
emptyname.setObjectName("");
+ Q_SET_OBJECT_NAME(oo);
+ const QUtf8StringView utf8_name = u8"utf8 ⁎ obj";
+ o21.setObjectName(utf8_name);
+ const QStringView utf16_name = u"utf16 ⁎ obj";
+ o22.setObjectName(utf16_name);
+ constexpr QLatin1StringView L1_name("L1 ⁎ obj");
+ o23.setObjectName(L1_name);
- QObject *op = 0;
+ QObject *op = nullptr;
- op = qFindChild<QObject*>(&o, "o1");
+ op = o.findChild<QObject*>("o1");
QCOMPARE(op, &o1);
- op = qFindChild<QObject*>(&o, "o2");
+ op = o.findChild<QObject*>("o2");
QCOMPARE(op, &o2);
- op = qFindChild<QObject*>(&o, "o11");
+ op = o.findChild<QObject*>("o11");
QCOMPARE(op, &o11);
- op = qFindChild<QObject*>(&o, "o12");
+ op = o.findChild<QObject*>("o12");
QCOMPARE(op, &o12);
- op = qFindChild<QObject*>(&o, "o111");
+ op = o.findChild<QObject*>("o111");
QCOMPARE(op, &o111);
- op = qFindChild<QObject*>(&o, "t1");
+ op = o.findChild<QObject*>("t1");
QCOMPARE(op, static_cast<QObject *>(&t1));
- op = qFindChild<QObject*>(&o, "t121");
+ op = o.findChild<QObject*>("t121");
QCOMPARE(op, static_cast<QObject *>(&t121));
- op = qFindChild<QTimer*>(&o, "t1");
+ op = o.findChild<QTimer*>("t1");
QCOMPARE(op, static_cast<QObject *>(&t1));
- op = qFindChild<QTimer*>(&o, "t121");
+ op = o.findChild<QTimer*>("t121");
QCOMPARE(op, static_cast<QObject *>(&t121));
- op = qFindChild<QTimer*>(&o, "o12");
+ op = o.findChild<QTimer*>("o12");
QCOMPARE(op, static_cast<QObject *>(0));
- op = qFindChild<QObject*>(&o, "o");
+ op = o.findChild<QObject*>("o");
QCOMPARE(op, static_cast<QObject *>(0));
- op = qFindChild<QObject*>(&o, "harry");
+ op = o.findChild<QObject*>("harry");
QCOMPARE(op, static_cast<QObject *>(0));
- op = qFindChild<QObject*>(&o, "o1");
+ op = o.findChild<QObject*>("o1");
QCOMPARE(op, &o1);
+ op = oo.findChild<QObject*>(utf8_name);
+ QCOMPARE(op, &o21);
+ op = oo.findChild<QObject*>(utf8_name.chopped(1));
+ QCOMPARE(op, nullptr);
+ const QUtf8StringView utf8_name_with_trailing_data = u8"utf8 ⁎ obj_data";
+ op = oo.findChild<QObject*>(utf8_name_with_trailing_data.chopped(5));
+ QCOMPARE(op, &o21);
+ op = oo.findChild<QObject*>(utf16_name);
+ QCOMPARE(op, &o22);
+ op = oo.findChild<QObject*>(utf16_name.chopped(1));
+ QCOMPARE(op, nullptr);
+ const QStringView utf16_name_with_trailing_data = u"utf16 ⁎ obj_data";
+ op = oo.findChild<QObject*>(utf16_name_with_trailing_data.chopped(5));
+ QCOMPARE(op, &o22);
+ op = oo.findChild<QObject*>(L1_name);
+ QCOMPARE(op, &o23);
+ op = oo.findChild<QObject*>(L1_name.chopped(1));
+ QCOMPARE(op, nullptr);
+ op = oo.findChild<QObject*>((L1_name + "_data"_L1).chopped(5));
+ QCOMPARE(op, &o23);
+
QList<QObject*> l;
QList<QTimer*> tl;
- l = qFindChildren<QObject*>(&o, "o1");
+ l = o.findChildren<QObject*>("o1");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o1);
- l = qFindChildren<QObject*>(&o, "o2");
+ l = o.findChildren<QObject*>("o2");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o2);
- l = qFindChildren<QObject*>(&o, "o11");
+ l = o.findChildren<QObject*>("o11");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o11);
- l = qFindChildren<QObject*>(&o, "o12");
+ l = o.findChildren<QObject*>("o12");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o12);
- l = qFindChildren<QObject*>(&o, "o111");
+ l = o.findChildren<QObject*>("o111");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o111);
- l = qFindChildren<QObject*>(&o, "t1");
+ l = o.findChildren<QObject*>("t1");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), static_cast<QObject *>(&t1));
- l = qFindChildren<QObject*>(&o, "t121");
+ l = o.findChildren<QObject*>("t121");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), static_cast<QObject *>(&t121));
- tl = qFindChildren<QTimer*>(&o, "t1");
+ tl = o.findChildren<QTimer*>("t1");
QCOMPARE(tl.size(), 1);
QCOMPARE(tl.at(0), &t1);
- tl = qFindChildren<QTimer*>(&o, "t121");
+ tl = o.findChildren<QTimer*>("t121");
QCOMPARE(tl.size(), 1);
QCOMPARE(tl.at(0), &t121);
- l = qFindChildren<QObject*>(&o, "o");
+ l = o.findChildren<QObject*>("o");
QCOMPARE(l.size(), 0);
- l = qFindChildren<QObject*>(&o, "harry");
+ l = o.findChildren<QObject*>("harry");
QCOMPARE(l.size(), 0);
- tl = qFindChildren<QTimer*>(&o, "o12");
+ tl = o.findChildren<QTimer*>("o12");
QCOMPARE(tl.size(), 0);
- l = qFindChildren<QObject*>(&o, "o1");
+ l = o.findChildren<QObject*>("o1");
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o1);
- l = qFindChildren<QObject*>(&o, QRegExp("o.*"));
+ l = o.findChildren<QObject*>(QRegularExpression("^o.*$"));
QCOMPARE(l.size(), 5);
QVERIFY(l.contains(&o1));
QVERIFY(l.contains(&o2));
QVERIFY(l.contains(&o11));
QVERIFY(l.contains(&o12));
QVERIFY(l.contains(&o111));
- l = qFindChildren<QObject*>(&o, QRegExp("t.*"));
+ l = o.findChildren<QObject*>(QRegularExpression("t.*"));
QCOMPARE(l.size(), 2);
QVERIFY(l.contains(&t1));
QVERIFY(l.contains(&t121));
- tl = qFindChildren<QTimer*>(&o, QRegExp(".*"));
+ tl = o.findChildren<QTimer*>(QRegularExpression("^.*$"));
QCOMPARE(tl.size(), 3);
QVERIFY(tl.contains(&t1));
QVERIFY(tl.contains(&t121));
- tl = qFindChildren<QTimer*>(&o, QRegExp("o.*"));
+ tl = o.findChildren<QTimer*>(QRegularExpression("^o.*$"));
QCOMPARE(tl.size(), 0);
- l = qFindChildren<QObject*>(&o, QRegExp("harry"));
+ l = o.findChildren<QObject*>(QRegularExpression("^harry$"));
QCOMPARE(l.size(), 0);
l = o.findChildren<QObject*>(QRegularExpression("o.*"));
@@ -647,18 +682,18 @@ void tst_QObject::findChildren()
QCOMPARE(l.size(), 0);
// empty and null string check
- op = qFindChild<QObject*>(&o);
+ op = o.findChild<QObject*>();
QCOMPARE(op, &o1);
- op = qFindChild<QObject*>(&o, "");
+ op = o.findChild<QObject*>("");
QCOMPARE(op, &unnamed);
- op = qFindChild<QObject*>(&o, "unnamed");
+ op = o.findChild<QObject*>("unnamed");
QCOMPARE(op, static_cast<QObject *>(0));
- l = qFindChildren<QObject*>(&o);
+ l = o.findChildren<QObject*>();
QCOMPARE(l.size(), 9);
- l = qFindChildren<QObject*>(&o, "");
+ l = o.findChildren<QObject*>("");
QCOMPARE(l.size(), 2);
- l = qFindChildren<QObject*>(&o, "unnamed");
+ l = o.findChildren<QObject*>("unnamed");
QCOMPARE(l.size(), 0);
tl = o.findChildren<QTimer *>("t1");
@@ -726,22 +761,35 @@ void tst_QObject::findChildren()
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o1);
- l = o.findChildren<QObject*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly);
+ l = o.findChildren<QObject*>(QRegularExpression("^o.*$"), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 2);
QVERIFY(l.contains(&o1));
QVERIFY(l.contains(&o2));
- l = o.findChildren<QObject*>(QRegExp("t.*"), Qt::FindDirectChildrenOnly);
+ l = o.findChildren<QObject*>(QRegularExpression("^t.*$"), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 1);
QVERIFY(l.contains(&t1));
- tl = o.findChildren<QTimer*>(QRegExp(".*"), Qt::FindDirectChildrenOnly);
+ tl = o.findChildren<QTimer*>(QRegularExpression("^.*$"), Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 2);
QVERIFY(tl.contains(&t1));
- tl = o.findChildren<QTimer*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly);
+ tl = o.findChildren<QTimer*>(QRegularExpression("^o.*$"), Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 0);
- l = o.findChildren<QObject*>(QRegExp("harry"), Qt::FindDirectChildrenOnly);
+ l = o.findChildren<QObject*>(QRegularExpression("^harry$"), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
+ DerivedObj dr1(&o111);
+ DerivedObj dr2(&o111);
+ Q_SET_OBJECT_NAME(dr1);
+ Q_SET_OBJECT_NAME(dr2);
+
// empty and null string check
+ op = o.findChild<QObject*>(Qt::FindDirectChildrenOnly);
+ QCOMPARE(op, &o1);
+ op = o.findChild<QTimer*>(Qt::FindDirectChildrenOnly);
+ QCOMPARE(op, &t1);
+ op = o.findChild<DerivedObj*>(Qt::FindDirectChildrenOnly);
+ QCOMPARE(op, nullptr);
+ op = o.findChild<DerivedObj*>(Qt::FindChildrenRecursively);
+ QCOMPARE(op, &dr1);
op = o.findChild<QObject*>(QString(), Qt::FindDirectChildrenOnly);
QCOMPARE(op, &o1);
op = o.findChild<QObject*>("", Qt::FindDirectChildrenOnly);
@@ -749,6 +797,8 @@ void tst_QObject::findChildren()
op = o.findChild<QObject*>("unnamed", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
+ l = o.findChildren<QObject*>(Qt::FindDirectChildrenOnly);
+ QCOMPARE(l.size(), 5);
l = o.findChildren<QObject*>(QString(), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 5);
l = o.findChildren<QObject*>("", Qt::FindDirectChildrenOnly);
@@ -776,9 +826,9 @@ public:
disconnectedSignals.clear();
}
protected:
- void connectNotify(const QMetaMethod &signal)
+ void connectNotify(const QMetaMethod &signal) override
{ connectedSignals.append(signal); }
- void disconnectNotify(const QMetaMethod &signal)
+ void disconnectNotify(const QMetaMethod &signal) override
{ disconnectedSignals.append(signal); }
};
@@ -798,192 +848,252 @@ void tst_QObject::connectDisconnectNotify_data()
void tst_QObject::connectDisconnectNotify()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
+ NotifyObject s;
+ NotifyObject r;
QFETCH(QString, a_signal);
QFETCH(QString, a_slot);
// Obtaining meta methods
- int signalIndx = ((SenderObject*)s)->metaObject()->indexOfSignal(
+ int signalIndx = ((SenderObject &)s).metaObject()->indexOfSignal(
QMetaObject::normalizedSignature(a_signal.toLatin1().constData()+1).constData());
- int methodIndx = ((ReceiverObject*)r)->metaObject()->indexOfMethod(
+ int methodIndx = ((ReceiverObject &)r).metaObject()->indexOfMethod(
QMetaObject::normalizedSignature(a_slot.toLatin1().constData()+1).constData());
- QMetaMethod signal = ((SenderObject*)s)->metaObject()->method(signalIndx);
- QMetaMethod method = ((ReceiverObject*)r)->metaObject()->method(methodIndx);
+ QMetaMethod signal = ((SenderObject &)s).metaObject()->method(signalIndx);
+ QMetaMethod method = ((ReceiverObject &)r).metaObject()->method(methodIndx);
QVERIFY(signal.isValid());
QVERIFY(method.isValid());
// Test connectNotify
- QVERIFY(QObject::connect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ QVERIFY(QObject::connect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify
- QVERIFY(QObject::disconnect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify for a complete disconnect
- QVERIFY(((SenderObject*)s)->disconnect((ReceiverObject*)r));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod());
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(((SenderObject *)&s)->disconnect((ReceiverObject *)&r));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod());
+ QCOMPARE(s.connectedSignals.size(), 1);
// Test connectNotify when connecting by QMetaMethod
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, signal, (ReceiverObject*)r, method));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, signal, (ReceiverObject *)&r, method));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify when disconnecting by QMetaMethod
- QVERIFY(QObject::disconnect((SenderObject*)s, signal, (ReceiverObject*)r, method));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, signal, (ReceiverObject *)&r, method));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, a_signal.toLatin1(), (ReceiverObject*)r, a_slot.toLatin1()));
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, a_signal.toLatin1(),
+ (ReceiverObject *)&r, a_slot.toLatin1()));
// Test disconnectNotify for a complete disconnect by QMetaMethod
- QVERIFY(QObject::disconnect((SenderObject*)s, QMetaMethod(), 0, QMetaMethod()));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod());
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, QMetaMethod(), 0, QMetaMethod()));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod());
+ QCOMPARE(s.connectedSignals.size(), 1);
// Test connectNotify when connecting by index
- s->clearNotifications();
- QVERIFY(QMetaObject::connect((SenderObject*)s, signalIndx, (ReceiverObject*)r, methodIndx));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QMetaObject::connect((SenderObject *)&s, signalIndx, (ReceiverObject *)&r, methodIndx));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify when disconnecting by index
- QVERIFY(QMetaObject::disconnect((SenderObject*)s, signalIndx, (ReceiverObject*)r, methodIndx));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QMetaObject::disconnect((SenderObject *)&s, signalIndx,
+ (ReceiverObject *)&r, methodIndx));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
+}
- delete s;
- delete r;
+struct Incomplete;
+class QObjectWithIncomplete : public QObject {
+ Q_OBJECT
+
+public:
+ QObjectWithIncomplete(QObject *parent=nullptr) : QObject(parent) {}
+signals:
+ void signalWithIncomplete(const Incomplete &);
+public slots:
+ void slotWithIncomplete(const Incomplete &) {}
+};
+
+void tst_QObject::connectReferenceToIncompleteTypes() {
+ QObjectWithIncomplete withIncomplete;
+ auto connection = QObject::connect(&withIncomplete, &QObjectWithIncomplete::signalWithIncomplete,
+ &withIncomplete, &QObjectWithIncomplete::slotWithIncomplete);
+ QVERIFY(connection);
+}
+
+struct Incomplete2;
+class QObjectWithIncomplete2 : public QObject {
+ Q_OBJECT
+
+public:
+ QObjectWithIncomplete2(QObject *parent=nullptr) : QObject(parent) {}
+signals:
+ void signalWithIncomplete(Incomplete2 *ptr);
+public slots:
+ void slotWithIncomplete(Incomplete2 *) { calledSlot = true; }
+ void run() { Q_EMIT signalWithIncomplete(nullptr); }
+public:
+ bool calledSlot = false;
+};
+
+void tst_QObject::connectAutoQueuedIncomplete()
+{
+ auto objectWithIncomplete1 = new QObjectWithIncomplete2();
+ auto objectWithIncomplete2 = new QObjectWithIncomplete2();
+ auto t = new QThread(this);
+ auto cleanup = qScopeGuard([&](){
+ t->quit();
+ QVERIFY(t->wait());
+ delete objectWithIncomplete1;
+ delete objectWithIncomplete2;
+ });
+
+ t->start();
+ objectWithIncomplete2->moveToThread(t);
+
+ connect(objectWithIncomplete2, &QObjectWithIncomplete2::signalWithIncomplete,
+ objectWithIncomplete1, &QObjectWithIncomplete2::slotWithIncomplete);
+ QMetaObject::invokeMethod(objectWithIncomplete2, "run", Qt::QueuedConnection);
+ QTRY_VERIFY(objectWithIncomplete1->calledSlot);
}
static void connectDisconnectNotifyTestSlot() {}
void tst_QObject::connectDisconnectNotifyPMF()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
+ NotifyObject s;
+ NotifyObject r;
QMetaMethod signal = QMetaMethod::fromSignal(&SenderObject::signal1);
// Test connectNotify
- QVERIFY(QObject::connect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ QVERIFY(QObject::connect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify
- QVERIFY(QObject::disconnect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, &ReceiverObject::slot1));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
// Test disconnectNotify with wildcard slot
- QVERIFY(QObject::disconnect((SenderObject*)s, &SenderObject::signal1, (ReceiverObject*)r, 0));
- QCOMPARE(s->disconnectedSignals.size(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), signal);
- QCOMPARE(s->connectedSignals.size(), 1);
+ QVERIFY(QObject::disconnect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, 0));
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), signal);
+ QCOMPARE(s.connectedSignals.size(), 1);
// Reconnect
- s->clearNotifications();
- QMetaObject::Connection conn = connect((SenderObject*)s, &SenderObject::signal1,
- (ReceiverObject*)r, &ReceiverObject::slot1);
+ s.clearNotifications();
+ QMetaObject::Connection conn = connect((SenderObject *)&s, &SenderObject::signal1,
+ (ReceiverObject *)&r, &ReceiverObject::slot1);
QVERIFY(conn);
// Test disconnectNotify when disconnecting by QMetaObject::Connection
QVERIFY(QObject::disconnect(conn));
- QVERIFY(!s->disconnectedSignals.isEmpty());
+ QVERIFY(!s.disconnectedSignals.isEmpty());
// Test connectNotify when connecting by function pointer
- s->clearNotifications();
- QVERIFY(QObject::connect((SenderObject*)s, &SenderObject::signal1, connectDisconnectNotifyTestSlot));
- QCOMPARE(s->connectedSignals.size(), 1);
- QCOMPARE(s->connectedSignals.at(0), signal);
- QVERIFY(s->disconnectedSignals.isEmpty());
-
- delete s;
- delete r;
+ s.clearNotifications();
+ QVERIFY(QObject::connect((SenderObject *)&s, &SenderObject::signal1,
+ connectDisconnectNotifyTestSlot));
+ QCOMPARE(s.connectedSignals.size(), 1);
+ QCOMPARE(s.connectedSignals.at(0), signal);
+ QVERIFY(s.disconnectedSignals.isEmpty());
}
void tst_QObject::disconnectNotify_receiverDestroyed()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
+ NotifyObject s;
- QVERIFY(QObject::connect((SenderObject*)s, SIGNAL(signal1()), (ReceiverObject*)r, SLOT(slot1())));
-
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
-
- s->disconnectedSignals.clear();
- r = new NotifyObject;
+ {
+ NotifyObject r;
+ QVERIFY(QObject::connect((SenderObject *)&s, SIGNAL(signal1()),
+ (ReceiverObject *)&r, SLOT(slot1())));
+ }
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
- QVERIFY(QObject::connect((SenderObject*)s, SIGNAL(signal3()), (ReceiverObject*)r, SLOT(slot3())));
+ s.disconnectedSignals.clear();
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal3));
+ {
+ NotifyObject r;
+ QVERIFY(QObject::connect((SenderObject *)&s, SIGNAL(signal3()),
+ (ReceiverObject *)&r, SLOT(slot3())));
+ }
- s->disconnectedSignals.clear();
- r = new NotifyObject;
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal3));
- QVERIFY(QObject::connect((SenderObject*)s, SIGNAL(destroyed()), (ReceiverObject*)r, SLOT(slot3())));
+ s.disconnectedSignals.clear();
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&QObject::destroyed));
+ {
+ NotifyObject r;
+ QVERIFY(QObject::connect((SenderObject *)&s, SIGNAL(destroyed()), (ReceiverObject *)&r, SLOT(slot3())));
+ }
- delete s;
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&QObject::destroyed));
}
void tst_QObject::disconnectNotify_metaObjConnection()
{
- NotifyObject *s = new NotifyObject;
- NotifyObject *r = new NotifyObject;
-
- QMetaObject::Connection c = QObject::connect((SenderObject*)s, SIGNAL(signal1()),
- (ReceiverObject*)r, SLOT(slot1()));
- QVERIFY(c);
- QVERIFY(QObject::disconnect(c));
+ NotifyObject s;
+ {
+ NotifyObject r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
- QCOMPARE(s->disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
+ QMetaObject::Connection c = QObject::connect((SenderObject *)&s, SIGNAL(signal1()),
+ (ReceiverObject *)&r, SLOT(slot1()));
+ QVERIFY(c);
+ QVERIFY(QObject::disconnect(c));
- delete r;
- QCOMPARE(s->disconnectedSignals.count(), 1);
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ QCOMPARE(s.disconnectedSignals.at(0), QMetaMethod::fromSignal(&SenderObject::signal1));
- delete s;
+ QCOMPARE(s.disconnectedSignals.size(), 1);
+ }
}
class ConnectByNameNotifySenderObject : public QObject
@@ -998,9 +1108,9 @@ public:
disconnectedSignals.clear();
}
protected:
- void connectNotify(const QMetaMethod &signal)
+ void connectNotify(const QMetaMethod &signal) override
{ connectedSignals.append(signal); }
- void disconnectNotify(const QMetaMethod &signal)
+ void disconnectNotify(const QMetaMethod &signal) override
{ disconnectedSignals.append(signal); }
Q_SIGNALS:
void signal1();
@@ -1032,18 +1142,16 @@ public Q_SLOTS:
void tst_QObject::connectNotify_connectSlotsByName()
{
ConnectByNameNotifyReceiverObject testObject;
- QList<ConnectByNameNotifySenderObject *> senders =
- qFindChildren<ConnectByNameNotifySenderObject *>(&testObject);
- for (int i = 0; i < senders.size(); ++i) {
- ConnectByNameNotifySenderObject *o = senders.at(i);
+ const QList<ConnectByNameNotifySenderObject *> senders =
+ testObject.findChildren<ConnectByNameNotifySenderObject *>();
+ for (ConnectByNameNotifySenderObject *o : senders) {
QVERIFY(o->connectedSignals.isEmpty());
QVERIFY(o->disconnectedSignals.isEmpty());
}
QMetaObject::connectSlotsByName(&testObject);
- for (int i = 0; i < senders.size(); ++i) {
- ConnectByNameNotifySenderObject *o = senders.at(i);
+ for (ConnectByNameNotifySenderObject *o : senders) {
QCOMPARE(o->connectedSignals.size(), 1);
QCOMPARE(o->connectedSignals.at(0), QMetaMethod::fromSignal(&ConnectByNameNotifySenderObject::signal1));
QVERIFY(o->disconnectedSignals.isEmpty());
@@ -1399,11 +1507,26 @@ struct CustomType
CustomType(const CustomType &other): i1(other.i1), i2(other.i2), i3(other.i3)
{ ++instanceCount; playWithObjects(); }
~CustomType() { --instanceCount; playWithObjects(); }
+ CustomType &operator=(const CustomType &) = default;
int i1, i2, i3;
int value() { return i1 + i2 + i3; }
};
+QDataStream &operator<<(QDataStream &stream, const CustomType &ct)
+{
+ stream << ct.i1 << ct.i2 << ct.i3;
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, CustomType &ct)
+{
+ stream >> ct.i1;
+ stream >> ct.i2;
+ stream >> ct.i3;
+ return stream;
+}
+
Q_DECLARE_METATYPE(CustomType*)
Q_DECLARE_METATYPE(CustomType)
@@ -1412,7 +1535,7 @@ class QCustomTypeChecker: public QObject
Q_OBJECT
public:
- QCustomTypeChecker(QObject *parent = 0): QObject(parent) {}
+ QCustomTypeChecker(QObject *parent = nullptr): QObject(parent) {}
void doEmit(CustomType ct)
{ emit signal1(ct); }
@@ -1451,8 +1574,7 @@ void tst_QObject::customTypes()
QCOMPARE(checker.received.value(), t1.value());
checker.received = t0;
- int idx = qRegisterMetaType<CustomType>("CustomType");
- QCOMPARE(QMetaType::type("CustomType"), idx);
+ qRegisterMetaType<CustomType>();
checker.disconnect();
connect(&checker, SIGNAL(signal1(CustomType)), &checker, SLOT(slot1(CustomType)),
@@ -1465,41 +1587,23 @@ void tst_QObject::customTypes()
QCoreApplication::processEvents();
QCOMPARE(checker.received.value(), t2.value());
QCOMPARE(instanceCount, 4);
-
- QVERIFY(QMetaType::isRegistered(idx));
- QCOMPARE(qRegisterMetaType<CustomType>("CustomType"), idx);
- QCOMPARE(QMetaType::type("CustomType"), idx);
- QVERIFY(QMetaType::isRegistered(idx));
}
QCOMPARE(instanceCount, 3);
}
-QDataStream &operator<<(QDataStream &stream, const CustomType &ct)
-{
- stream << ct.i1 << ct.i2 << ct.i3;
- return stream;
-}
-
-QDataStream &operator>>(QDataStream &stream, CustomType &ct)
-{
- stream >> ct.i1;
- stream >> ct.i2;
- stream >> ct.i3;
- return stream;
-}
-
void tst_QObject::streamCustomTypes()
{
QByteArray ba;
- int idx = qRegisterMetaType<CustomType>("CustomType");
- qRegisterMetaTypeStreamOperators<CustomType>("CustomType");
+ qRegisterMetaType<CustomType>();
+
+ QMetaType metaType = QMetaType::fromType<CustomType>();
{
CustomType t1(1, 2, 3);
QCOMPARE(instanceCount, 1);
QDataStream stream(&ba, (QIODevice::OpenMode)QIODevice::WriteOnly);
- QMetaType::save(stream, idx, &t1);
+ metaType.save(stream, &t1);
}
QCOMPARE(instanceCount, 0);
@@ -1508,7 +1612,7 @@ void tst_QObject::streamCustomTypes()
CustomType t2;
QCOMPARE(instanceCount, 1);
QDataStream stream(&ba, (QIODevice::OpenMode)QIODevice::ReadOnly);
- QMetaType::load(stream, idx, &t2);
+ metaType.load(stream, &t2);
QCOMPARE(instanceCount, 1);
QCOMPARE(t2.i1, 1);
QCOMPARE(t2.i2, 2);
@@ -1603,7 +1707,7 @@ class TestThread : public QThread
{
Q_OBJECT
public:
- inline void run()
+ inline void run() override
{
*object = new QObject;
*child = new QObject(*object);
@@ -1628,19 +1732,19 @@ void tst_QObject::thread()
QObject object;
// thread affinity for objects with no parent should be the
// current thread
- QVERIFY(object.thread() != 0);
+ QVERIFY(object.thread() != nullptr);
QCOMPARE(object.thread(), currentThread);
// children inherit their parent's thread
QObject child(&object);
QCOMPARE(child.thread(), object.thread());
}
- QObject *object = 0;
- QObject *child = 0;
+ QObject *object = nullptr;
+ QObject *child = nullptr;
{
TestThread thr;
- QVERIFY(thr.thread() != 0);
+ QVERIFY(thr.thread() != nullptr);
QCOMPARE(thr.thread(), currentThread);
thr.object = &object;
@@ -1678,15 +1782,15 @@ class MoveToThreadObject : public QObject
{
Q_OBJECT
public:
- QThread *timerEventThread;
- QThread *customEventThread;
- QThread *slotThread;
+ QThread *timerEventThread = nullptr;
+ QThread *customEventThread = nullptr;
+ QThread *slotThread = nullptr;
- MoveToThreadObject(QObject *parent = 0)
- : QObject(parent), timerEventThread(0), customEventThread(0), slotThread(0)
+ MoveToThreadObject(QObject *parent = nullptr)
+ : QObject(parent)
{ }
- void customEvent(QEvent *)
+ void customEvent(QEvent *) override
{
if (customEventThread)
qFatal("%s: customEventThread should be null", Q_FUNC_INFO);
@@ -1694,7 +1798,7 @@ public:
emit theSignal();
}
- void timerEvent(QTimerEvent *)
+ void timerEvent(QTimerEvent *) override
{
if (timerEventThread)
qFatal("%s: timerEventThread should be null", Q_FUNC_INFO);
@@ -1733,7 +1837,7 @@ public:
// wait for thread to start
(void) eventLoop.exec();
}
- void run()
+ void run() override
{ (void) exec(); }
};
@@ -1767,13 +1871,15 @@ void tst_QObject::moveToThread()
QObject *child = new QObject(object);
QCOMPARE(object->thread(), currentThread);
QCOMPARE(child->thread(), currentThread);
- object->moveToThread(0);
+ QVERIFY(object->moveToThread(nullptr));
QCOMPARE(object->thread(), (QThread *)0);
QCOMPARE(child->thread(), (QThread *)0);
- object->moveToThread(currentThread);
+ QVERIFY(object->moveToThread(currentThread));
QCOMPARE(object->thread(), currentThread);
QCOMPARE(child->thread(), currentThread);
- object->moveToThread(0);
+ QTest::ignoreMessage(QtWarningMsg, "QObject::moveToThread: Cannot move objects with a parent");
+ QVERIFY(!child->moveToThread(nullptr));
+ QVERIFY(object->moveToThread(nullptr));
QCOMPARE(object->thread(), (QThread *)0);
QCOMPARE(child->thread(), (QThread *)0);
// can delete an object with no thread anywhere
@@ -1799,8 +1905,8 @@ void tst_QObject::moveToThread()
QMetaObject::invokeMethod(object, "deleteLater", Qt::QueuedConnection);
thread.wait();
- QVERIFY(opointer == 0);
- QVERIFY(cpointer == 0);
+ QVERIFY(opointer == nullptr);
+ QVERIFY(cpointer == nullptr);
}
{
@@ -1862,8 +1968,6 @@ void tst_QObject::moveToThread()
thread.wait();
}
- // WinRT does not allow connection to localhost
-#ifndef Q_OS_WINRT
{
// make sure socket notifiers are moved with the object
MoveToThreadThread thread;
@@ -1899,7 +2003,6 @@ void tst_QObject::moveToThread()
QMetaObject::invokeMethod(socket, "deleteLater", Qt::QueuedConnection);
thread.wait();
}
-#endif
}
@@ -1913,8 +2016,8 @@ void tst_QObject::property()
QVERIFY(mo->indexOfProperty("alpha") != -1);
property = mo->property(mo->indexOfProperty("alpha"));
QVERIFY(property.isEnumType());
- QCOMPARE(property.typeName(), "Alpha");
- QCOMPARE(property.type(), QVariant::Int);
+ QCOMPARE(property.typeName(), "PropertyObject::Alpha");
+ QCOMPARE(property.userType(), QMetaType::fromType<PropertyObject::Alpha>().id());
QVariant var = object.property("alpha");
QVERIFY(!var.isNull());
@@ -1925,7 +2028,8 @@ void tst_QObject::property()
QCOMPARE(object.property("alpha").toInt(), int(PropertyObject::Alpha2));
QVERIFY(object.setProperty("alpha", "Alpha1"));
QCOMPARE(object.property("alpha").toInt(), int(PropertyObject::Alpha1));
- QVERIFY(!object.setProperty("alpha", QVariant()));
+ QVERIFY(object.setProperty("alpha", QVariant()));
+ QCOMPARE(object.property("alpha").toInt(), 0);
QVERIFY(mo->indexOfProperty("number") != -1);
QCOMPARE(object.property("number").toInt(), 0);
@@ -1946,7 +2050,7 @@ void tst_QObject::property()
const int idx = mo->indexOfProperty("variant");
QVERIFY(idx != -1);
- QCOMPARE(QMetaType::Type(mo->property(idx).type()), QMetaType::QVariant);
+ QCOMPARE(mo->property(idx).userType(), QMetaType::QVariant);
QCOMPARE(object.property("variant"), QVariant());
QVariant variant1(42);
QVariant variant2("string");
@@ -1965,10 +2069,10 @@ void tst_QObject::property()
QVERIFY(!property.isEnumType());
QCOMPARE(property.typeName(), "CustomType*");
qRegisterMetaType<CustomType*>();
- QCOMPARE(property.type(), QVariant::UserType);
+ QCOMPARE_GE(property.typeId(), QMetaType::User);
QCOMPARE(property.userType(), qMetaTypeId<CustomType*>());
- CustomType *customPointer = 0;
+ CustomType *customPointer = nullptr;
QVariant customVariant = object.property("custom");
customPointer = qvariant_cast<CustomType *>(customVariant);
QCOMPARE(customPointer, object.custom());
@@ -1980,7 +2084,7 @@ void tst_QObject::property()
property = mo->property(mo->indexOfProperty("custom"));
QVERIFY(property.isWritable());
QCOMPARE(property.typeName(), "CustomType*");
- QCOMPARE(property.type(), QVariant::UserType);
+ QCOMPARE_GE(property.typeId(), QMetaType::User);
QCOMPARE(property.userType(), qMetaTypeId<CustomType*>());
QVERIFY(object.setProperty("custom", customVariant));
@@ -1994,8 +2098,8 @@ void tst_QObject::property()
QVERIFY(mo->indexOfProperty("priority") != -1);
property = mo->property(mo->indexOfProperty("priority"));
QVERIFY(property.isEnumType());
- QCOMPARE(property.typeName(), "Priority");
- QCOMPARE(property.type(), QVariant::Int);
+ QCOMPARE(property.typeName(), "PropertyObject::Priority");
+ QCOMPARE(property.userType(), QMetaType::fromType<PropertyObject::Priority>().id());
var = object.property("priority");
QVERIFY(!var.isNull());
@@ -2006,16 +2110,17 @@ void tst_QObject::property()
QCOMPARE(object.property("priority").toInt(), int(PropertyObject::VeryHigh));
QVERIFY(object.setProperty("priority", "High"));
QCOMPARE(object.property("priority").toInt(), int(PropertyObject::High));
- QVERIFY(!object.setProperty("priority", QVariant()));
+ QVERIFY(object.setProperty("priority", QVariant()));
+ QCOMPARE(object.property("priority").toInt(), 0);
// now it's registered, so it works as expected
- int priorityMetaTypeId = qRegisterMetaType<PropertyObject::Priority>("PropertyObject::Priority");
+ int priorityMetaTypeId = qRegisterMetaType<PropertyObject::Priority>();
QVERIFY(mo->indexOfProperty("priority") != -1);
property = mo->property(mo->indexOfProperty("priority"));
QVERIFY(property.isEnumType());
- QCOMPARE(property.typeName(), "Priority");
- QCOMPARE(property.type(), QVariant::UserType);
+ QCOMPARE(property.typeName(), "PropertyObject::Priority");
+ QCOMPARE_GE(property.typeId(), QMetaType::User);
QCOMPARE(property.userType(), priorityMetaTypeId);
var = object.property("priority");
@@ -2028,7 +2133,8 @@ void tst_QObject::property()
QCOMPARE(qvariant_cast<PropertyObject::Priority>(object.property("priority")), PropertyObject::VeryHigh);
QVERIFY(object.setProperty("priority", "High"));
QCOMPARE(qvariant_cast<PropertyObject::Priority>(object.property("priority")), PropertyObject::High);
- QVERIFY(!object.setProperty("priority", QVariant()));
+ QVERIFY(object.setProperty("priority", QVariant()));
+ QCOMPARE(object.property("priority").toInt(), 0);
var = object.property("priority");
QCOMPARE(qvariant_cast<PropertyObject::Priority>(var), PropertyObject::High);
@@ -2037,7 +2143,7 @@ void tst_QObject::property()
object.setProperty("priority", var);
QCOMPARE(qvariant_cast<PropertyObject::Priority>(object.property("priority")), PropertyObject::High);
- qRegisterMetaType<CustomString>("CustomString");
+ qRegisterMetaType<CustomString>();
QVERIFY(mo->indexOfProperty("customString") != -1);
QCOMPARE(object.property("customString").toString(), QString());
object.setCustomString("String1");
@@ -2110,18 +2216,18 @@ void tst_QObject::metamethod()
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
m = mobj->method(mobj->indexOfMethod("invoke1()"));
- QCOMPARE(m.parameterNames().count(), 0);
- QCOMPARE(m.parameterTypes().count(), 0);
+ QCOMPARE(m.parameterNames().size(), 0);
+ QCOMPARE(m.parameterTypes().size(), 0);
m = mobj->method(mobj->indexOfMethod("invoke2(int)"));
- QCOMPARE(m.parameterNames().count(), 1);
- QCOMPARE(m.parameterTypes().count(), 1);
+ QCOMPARE(m.parameterNames().size(), 1);
+ QCOMPARE(m.parameterTypes().size(), 1);
QCOMPARE(m.parameterTypes().at(0), QByteArray("int"));
QVERIFY(m.parameterNames().at(0).isEmpty());
m = mobj->method(mobj->indexOfMethod("invoke3(int,int)"));
- QCOMPARE(m.parameterNames().count(), 2);
- QCOMPARE(m.parameterTypes().count(), 2);
+ QCOMPARE(m.parameterNames().size(), 2);
+ QCOMPARE(m.parameterTypes().size(), 2);
QCOMPARE(m.parameterTypes().at(0), QByteArray("int"));
QCOMPARE(m.parameterNames().at(0), QByteArray("hinz"));
QCOMPARE(m.parameterTypes().at(1), QByteArray("int"));
@@ -2163,7 +2269,7 @@ public:
SuperObject()
{
- theSender = 0;
+ theSender = nullptr;
theSignalId = 0;
}
@@ -2227,7 +2333,7 @@ void tst_QObject::senderTest()
QCOMPARE(receiver->sender(), (QObject *)0);
QCOMPARE(receiver->senderSignalIndex(), -1);
- receiver->theSender = 0;
+ receiver->theSender = nullptr;
receiver->theSignalId = -1;
thread.start();
emit sender->theSignal();
@@ -2308,7 +2414,7 @@ class FooObject: public QObject, public Foo::Bar
Q_OBJECT
Q_INTERFACES(Foo::Bar)
public:
- int rtti() const { return 42; }
+ int rtti() const override { return 42; }
};
class BlehObject : public QObject, public Foo::Bleh
@@ -2316,7 +2422,7 @@ class BlehObject : public QObject, public Foo::Bleh
Q_OBJECT
Q_INTERFACES(Foo::Bleh)
public:
- int rtti() const { return 43; }
+ int rtti() const override { return 43; }
};
void tst_QObject::declareInterface()
@@ -2338,49 +2444,6 @@ void tst_QObject::declareInterface()
}
-class CustomData : public QObjectUserData
-{
-public:
- int id;
-};
-
-void tst_QObject::testUserData()
-{
- const int USER_DATA_COUNT = 100;
- int user_data_ids[USER_DATA_COUNT];
-
- // Register a few
- for (int i=0; i<USER_DATA_COUNT; ++i) {
- user_data_ids[i] = QObject::registerUserData();
- }
-
- // Randomize the table a bit
- for (int i=0; i<100; ++i) {
- int p1 = QRandomGenerator::global()->bounded(USER_DATA_COUNT);
- int p2 = QRandomGenerator::global()->bounded(USER_DATA_COUNT);
-
- int tmp = user_data_ids[p1];
- user_data_ids[p1] = user_data_ids[p2];
- user_data_ids[p2] = tmp;
- }
-
- // insert the user data into an object
- QObject my_test_object;
- for (int i=0; i<USER_DATA_COUNT; ++i) {
- CustomData *data = new CustomData;
- data->id = user_data_ids[i];
- my_test_object.setUserData(data->id, data);
- }
-
- // verify that all ids and positions are matching
- for (int i=0; i<USER_DATA_COUNT; ++i) {
- int id = user_data_ids[i];
- CustomData *data = static_cast<CustomData *>(my_test_object.userData(id));
- QVERIFY(data != 0);
- QCOMPARE(data->id, id);
- }
-}
-
class DestroyedListener : public QObject
{
Q_OBJECT
@@ -2919,7 +2982,7 @@ void tst_QObject::floatProperty()
QVERIFY(idx > 0);
QMetaProperty prop = obj.metaObject()->property(idx);
QVERIFY(prop.isValid());
- QCOMPARE(int(prop.type()), QMetaType::type("float"));
+ QCOMPARE(prop.typeId(), QMetaType::fromType<float>().id());
QVERIFY(!prop.write(&obj, QVariant("Hello")));
QVERIFY(prop.write(&obj, QVariant::fromValue(128.0f)));
QVariant v = prop.read(&obj);
@@ -2934,7 +2997,7 @@ void tst_QObject::qrealProperty()
QVERIFY(idx > 0);
QMetaProperty prop = obj.metaObject()->property(idx);
QVERIFY(prop.isValid());
- QCOMPARE(int(prop.type()), QMetaType::type("qreal"));
+ QCOMPARE(prop.typeId(), QMetaType::fromType<qreal>().id());
QVERIFY(!prop.write(&obj, QVariant("Hello")));
QVERIFY(prop.write(&obj, QVariant::fromValue(128.0f)));
@@ -2953,7 +3016,7 @@ class DynamicPropertyObject : public PropertyObject
public:
inline DynamicPropertyObject() {}
- inline virtual bool event(QEvent *e) {
+ inline virtual bool event(QEvent *e) override {
if (e->type() == QEvent::DynamicPropertyChange) {
changedDynamicProperties.append(static_cast<QDynamicPropertyChangeEvent *>(e)->propertyName());
}
@@ -2979,31 +3042,31 @@ void tst_QObject::dynamicProperties()
// set a dynamic property
QVERIFY(!obj.setProperty("myuserproperty", "Hello"));
- QCOMPARE(obj.changedDynamicProperties.count(), 1);
+ QCOMPARE(obj.changedDynamicProperties.size(), 1);
QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty"));
//check if there is no redundant DynamicPropertyChange events
QVERIFY(!obj.setProperty("myuserproperty", "Hello"));
- QCOMPARE(obj.changedDynamicProperties.count(), 1);
+ QCOMPARE(obj.changedDynamicProperties.size(), 1);
- QCOMPARE(obj.property("myuserproperty").type(), QVariant::String);
+ QCOMPARE(obj.property("myuserproperty").typeId(), QMetaType::QString);
QCOMPARE(obj.property("myuserproperty").toString(), QString("Hello"));
- QCOMPARE(obj.dynamicPropertyNames().count(), 1);
+ QCOMPARE(obj.dynamicPropertyNames().size(), 1);
QCOMPARE(obj.dynamicPropertyNames().first(), QByteArray("myuserproperty"));
// change type of the dynamic property
obj.changedDynamicProperties.clear();
QVERIFY(!obj.setProperty("myuserproperty", QByteArray("Hello")));
- QCOMPARE(obj.changedDynamicProperties.count(), 1);
+ QCOMPARE(obj.changedDynamicProperties.size(), 1);
QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty"));
- QCOMPARE(obj.property("myuserproperty").type(), QVariant::ByteArray);
+ QCOMPARE(obj.property("myuserproperty").typeId(), QMetaType::QByteArray);
QCOMPARE(obj.property("myuserproperty").toString(), QByteArray("Hello"));
// unset the property
obj.changedDynamicProperties.clear();
QVERIFY(!obj.setProperty("myuserproperty", QVariant()));
- QCOMPARE(obj.changedDynamicProperties.count(), 1);
+ QCOMPARE(obj.changedDynamicProperties.size(), 1);
QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty"));
obj.changedDynamicProperties.clear();
@@ -3019,7 +3082,7 @@ void tst_QObject::recursiveSignalEmission()
#else
QProcess proc;
// signalbug helper app should always be next to this test binary
- const QString path = QStringLiteral("signalbug_helper");
+ const QString path = QCoreApplication::applicationDirPath() + QDir::separator() + QStringLiteral("signalbug_helper");
proc.start(path);
QVERIFY2(proc.waitForStarted(), qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, proc.errorString())));
QVERIFY(proc.waitForFinished());
@@ -3079,6 +3142,8 @@ void tst_QObject::blockingQueuedConnection()
}
}
+static int s_eventSpyCounter = -1;
+
class EventSpy : public QObject
{
Q_OBJECT
@@ -3086,7 +3151,7 @@ class EventSpy : public QObject
public:
typedef QList<QPair<QObject *, QEvent::Type> > EventList;
- EventSpy(QObject *parent = 0)
+ EventSpy(QObject *parent = nullptr)
: QObject(parent)
{ }
@@ -3098,14 +3163,17 @@ public:
void clear()
{
events.clear();
+ thisCounter = -1;
}
- bool eventFilter(QObject *object, QEvent *event)
+ bool eventFilter(QObject *object, QEvent *event) override
{
events.append(qMakePair(object, event->type()));
+ thisCounter = ++s_eventSpyCounter;
return false;
}
+ int thisCounter = -1;
private:
EventList events;
};
@@ -3194,6 +3262,78 @@ void tst_QObject::childEvents()
}
}
+void tst_QObject::parentEvents()
+{
+#ifdef QT_BUILD_INTERNAL
+ EventSpy::EventList expected;
+
+ {
+ // Parent events not enabled
+ QObject parent;
+ QObject child;
+
+ EventSpy spy;
+ child.installEventFilter(&spy);
+
+ QCoreApplication::postEvent(&child, new QEvent(QEvent::Type(QEvent::User + 1)));
+
+ child.setParent(&parent);
+
+ QCoreApplication::postEvent(&child, new QEvent(QEvent::Type(QEvent::User + 2)));
+
+ expected =
+ EventSpy::EventList();
+ QCOMPARE(spy.eventList(), expected);
+ spy.clear();
+
+ QCoreApplication::processEvents();
+
+ expected =
+ EventSpy::EventList()
+ << qMakePair(&child, QEvent::Type(QEvent::User + 1))
+ << qMakePair(&child, QEvent::Type(QEvent::User + 2));
+ QCOMPARE(spy.eventList(), expected);
+ }
+
+ {
+ // Parent events enabled
+ QObject parent;
+ QObject child;
+ auto *childPrivate = QObjectPrivate::get(&child);
+ childPrivate->receiveParentEvents = true;
+
+ EventSpy spy;
+ child.installEventFilter(&spy);
+
+ QCoreApplication::postEvent(&child, new QEvent(QEvent::Type(QEvent::User + 1)));
+
+ child.setParent(&parent);
+ child.setParent(nullptr);
+
+ QCoreApplication::postEvent(&child, new QEvent(QEvent::Type(QEvent::User + 2)));
+
+ expected =
+ EventSpy::EventList()
+ << qMakePair(&child, QEvent::ParentAboutToChange)
+ << qMakePair(&child, QEvent::ParentChange)
+ << qMakePair(&child, QEvent::ParentAboutToChange)
+ << qMakePair(&child, QEvent::ParentChange);
+ QCOMPARE(spy.eventList(), expected);
+ spy.clear();
+
+ QCoreApplication::processEvents();
+
+ expected =
+ EventSpy::EventList()
+ << qMakePair(&child, QEvent::Type(QEvent::User + 1))
+ << qMakePair(&child, QEvent::Type(QEvent::User + 2));
+ QCOMPARE(spy.eventList(), expected);
+ }
+#else
+ QSKIP("Needs QT_BUILD_INTERNAL");
+#endif
+}
+
void tst_QObject::installEventFilter()
{
QEvent event(QEvent::User);
@@ -3235,10 +3375,74 @@ void tst_QObject::installEventFilter()
QVERIFY(spy.eventList().isEmpty());
}
+#define CHECK_FAIL(message) \
+do {\
+ if (QTest::currentTestFailed())\
+ QFAIL("failed one line above on " message);\
+} while (false)
+
+void tst_QObject::installEventFilterOrder()
+{
+ // installEventFilter() adds new objects to d_func()->extraData->eventFilters, which
+ // affects the order of calling each object's eventFilter() when processing the events.
+
+ QObject object;
+ EventSpy spy1, spy2, spy3;
+
+ auto clearSignalSpies = [&] {
+ for (auto *s : {&spy1, &spy2, &spy3})
+ s->clear();
+ s_eventSpyCounter = -1;
+ };
+
+ const EventSpy::EventList expected = { { &object, QEvent::Type(QEvent::User + 1) } };
+
+ // Call Order: from first to last
+ auto checkCallOrder = [&expected](const QList<EventSpy *> &spies) {
+ for (int i = 0; i < spies.size(); ++i) {
+ EventSpy *spy = spies.at(i);
+ QVERIFY2(spy->eventList() == expected,
+ QString("The spy %1 wasn't triggered exactly once.").arg(i).toLatin1());
+ QCOMPARE(spy->thisCounter, i);
+ }
+ };
+
+ // Install event filters and check the order of invocations:
+ // The last installed = the first called.
+ object.installEventFilter(&spy1);
+ object.installEventFilter(&spy2);
+ object.installEventFilter(&spy3);
+ clearSignalSpies();
+ QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
+ QCoreApplication::processEvents();
+ checkCallOrder({ &spy3, &spy2, &spy1 });
+ CHECK_FAIL("checkCallOrder() - 1st round");
+
+ // Install event filter for `spy1` again, which reorders spy1 in `eventFilters`
+ // (the list doesn't have duplicates).
+ object.installEventFilter(&spy1);
+ clearSignalSpies();
+ QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
+ QCoreApplication::processEvents();
+ checkCallOrder({ &spy1, &spy3, &spy2 });
+ CHECK_FAIL("checkCallOrder() - 2nd round");
+
+ // Remove event filter for `spy3`, ensure it's not called anymore and the
+ // existing filters order is preserved.
+ object.removeEventFilter(&spy3);
+ clearSignalSpies();
+ QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1)));
+ QCoreApplication::processEvents();
+ checkCallOrder({ &spy1, &spy2 });
+ CHECK_FAIL("checkCallOrder() - 3rd round");
+ QVERIFY(spy3.eventList().isEmpty());
+ QCOMPARE(spy3.thisCounter, -1);
+}
+
class EmitThread : public QThread
{ Q_OBJECT
public:
- void run(void) {
+ void run(void) override {
emit work();
}
signals:
@@ -3408,17 +3612,42 @@ void tst_QObject::disconnectSelfInSlotAndDeleteAfterEmit()
void tst_QObject::dumpObjectInfo()
{
QObject a, b;
- QObject::connect(&a, SIGNAL(destroyed(QObject*)), &b, SLOT(deleteLater()));
- a.disconnect(&b);
+ QObject::connect(&a, &QObject::destroyed, &b, &QObject::deleteLater);
QTest::ignoreMessage(QtDebugMsg, "OBJECT QObject::unnamed");
QTest::ignoreMessage(QtDebugMsg, " SIGNALS OUT");
QTest::ignoreMessage(QtDebugMsg, " signal: destroyed(QObject*)");
- QTest::ignoreMessage(QtDebugMsg, " <Disconnected receiver>");
+ QTest::ignoreMessage(QtDebugMsg, " <functor or function pointer>");
QTest::ignoreMessage(QtDebugMsg, " SIGNALS IN");
QTest::ignoreMessage(QtDebugMsg, " <None>");
a.dumpObjectInfo(); // should not crash
}
+void tst_QObject::dumpObjectTree()
+{
+ QObject a;
+ Q_SET_OBJECT_NAME(a);
+
+ QTimer b(&a);
+ Q_SET_OBJECT_NAME(b);
+
+ QObject c(&b);
+ Q_SET_OBJECT_NAME(c);
+
+ QFile f(&a);
+ Q_SET_OBJECT_NAME(f);
+
+ const char * const output[] = {
+ "QObject::a ",
+ " QTimer::b ",
+ " QObject::c ",
+ " QFile::f ",
+ };
+ for (const char *line : output)
+ QTest::ignoreMessage(QtDebugMsg, line);
+
+ a.dumpObjectTree();
+}
+
class ConnectToSender : public QObject
{ Q_OBJECT
public slots:
@@ -3463,130 +3692,131 @@ void tst_QObject::qobjectConstCast()
void tst_QObject::uniqConnection()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, SIGNAL(signal1()), r1, SLOT(slot1()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal1()), r2, SLOT(slot1()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal1()), r1, SLOT(slot3()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal3()), r1, SLOT(slot3()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal1()), &r1, SLOT(slot1()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal1()), &r2, SLOT(slot1()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal1()), &r1, SLOT(slot3()) , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, SIGNAL(signal3()), &r1, SLOT(slot3()) , Qt::UniqueConnection) );
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 2 );
- QCOMPARE( r1->count_slot4, 0 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
- QCOMPARE( r2->count_slot4, 0 );
- QCOMPARE( r1->sequence_slot1, 1 );
- QCOMPARE( r2->sequence_slot1, 2 );
- QCOMPARE( r1->sequence_slot3, 4 );
-
- r1->reset();
- r2->reset();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 2);
+ QCOMPARE(r1.count_slot4, 0);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ QCOMPARE(r2.count_slot4, 0);
+ QCOMPARE(r1.sequence_slot1, 1);
+ QCOMPARE(r2.sequence_slot1, 2);
+ QCOMPARE(r1.sequence_slot3, 4);
+
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal4()), r2, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY(!connect( s, SIGNAL(signal4()), r2, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY( connect( s, SIGNAL(signal1()), r2, SLOT(slot4()) , Qt::UniqueConnection) );
- QVERIFY(!connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) , Qt::UniqueConnection) );
+ QVERIFY( connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY( connect(&s, SIGNAL(signal4()), &r2, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY(!connect(&s, SIGNAL(signal4()), &r2, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY( connect(&s, SIGNAL(signal1()), &r2, SLOT(slot4()) , Qt::UniqueConnection));
+ QVERIFY(!connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()) , Qt::UniqueConnection));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 1 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 1 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 1);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 1);
+ QCOMPARE(r2.sequence_slot4, 2);
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- connect( s, SIGNAL(signal4()), r1, SLOT(slot4()) );
+ connect(&s, SIGNAL(signal4()), &r1, SLOT(slot4()));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 2 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 3 );
- QCOMPARE( r2->sequence_slot4, 2 );
-
- delete s;
- delete r1;
- delete r2;
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 2);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 3);
+ QCOMPARE(r2.sequence_slot4, 2);
}
void tst_QObject::uniqConnectionPtr()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot1 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot3 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal3, r1, &ReceiverObject::slot3 , Qt::UniqueConnection) );
+ QVERIFY(connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1 ,
+ Qt::UniqueConnection));
+ QVERIFY(connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot1 ,
+ Qt::UniqueConnection));
+ QVERIFY(connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot3 ,
+ Qt::UniqueConnection));
+ QVERIFY(connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot3 ,
+ Qt::UniqueConnection));
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 2 );
- QCOMPARE( r1->count_slot4, 0 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
- QCOMPARE( r2->count_slot4, 0 );
- QCOMPARE( r1->sequence_slot1, 1 );
- QCOMPARE( r2->sequence_slot1, 2 );
- QCOMPARE( r1->sequence_slot3, 4 );
-
- r1->reset();
- r2->reset();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 2);
+ QCOMPARE(r1.count_slot4, 0);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ QCOMPARE(r2.count_slot4, 0);
+ QCOMPARE(r1.sequence_slot1, 1);
+ QCOMPARE(r2.sequence_slot1, 2);
+ QCOMPARE(r1.sequence_slot3, 4);
+
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal4, r2, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY(!connect( s, &SenderObject::signal4, r2, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY( connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot4 , Qt::UniqueConnection) );
- QVERIFY(!connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 , Qt::UniqueConnection) );
+ QVERIFY( connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY( connect(&s, &SenderObject::signal4, &r2, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY(!connect(&s, &SenderObject::signal4, &r2, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY( connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
+ QVERIFY(!connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4 ,
+ Qt::UniqueConnection));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 1 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 1 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 1);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 1);
+ QCOMPARE(r2.sequence_slot4, 2);
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 );
-
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 2 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 3 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4);
- delete s;
- delete r1;
- delete r2;
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 2);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 3);
+ QCOMPARE(r2.sequence_slot4, 2);
}
void tst_QObject::interfaceIid()
@@ -3595,8 +3825,6 @@ void tst_QObject::interfaceIid()
QByteArray(Bleh_iid));
QCOMPARE(QByteArray(qobject_interface_iid<Foo::Bar *>()),
QByteArray("com.qtest.foobar"));
- QCOMPARE(QByteArray(qobject_interface_iid<FooObject *>()),
- QByteArray());
}
void tst_QObject::deleteQObjectWhenDeletingEvent()
@@ -3622,9 +3850,9 @@ class OverloadObject : public QObject
signals:
void sig(int i, char c, qreal m = 12);
void sig(int i, int j = 12);
- void sig(QObject *o, QObject *p, QObject *q = 0, QObject *r = 0) const;
+ void sig(QObject *o, QObject *p, QObject *q = nullptr, QObject *r = nullptr) const;
void other(int a = 0);
- void sig(QObject *o, OverloadObject *p = 0, QObject *q = 0, QObject *r = 0);
+ void sig(QObject *o, OverloadObject *p = nullptr, QObject *q = nullptr, QObject *r = nullptr);
void sig(double r = 0.5);
public slots:
void slo(int i, int j = 43)
@@ -3890,217 +4118,214 @@ void tst_QObject::isSignalConnectedAfterDisconnection()
void tst_QObject::qMetaObjectConnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
- ReceiverObject::sequence = 0;
-
- int signal1Index = s->metaObject()->indexOfSignal("signal1()");
- int signal3Index = s->metaObject()->indexOfSignal("signal3()");
- int slot1Index = r1->metaObject()->indexOfSlot("slot1()");
- int slot2Index = r1->metaObject()->indexOfSlot("slot2()");
- int slot3Index = r1->metaObject()->indexOfSlot("slot3()");
-
- QVERIFY(slot1Index > 0);
- QVERIFY(slot2Index > 0);
- QVERIFY(slot3Index > 0);
-
- QVERIFY( QMetaObject::connect( s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::connect( s, signal3Index, r2, slot3Index) );
- QVERIFY( QMetaObject::connect( s, -1, r2, slot2Index) );
-
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
-
- s->emitSignal1();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 1 );
- QCOMPARE( r2->count_slot3, 0 );
-
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 4 );
- QCOMPARE( r2->count_slot3, 1 );
-
- QVERIFY( QMetaObject::disconnect( s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnect( s, signal3Index, r2, slot3Index) );
- QVERIFY( QMetaObject::disconnect( s, -1, r2, slot2Index) );
-
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 4 );
- QCOMPARE( r2->count_slot3, 1 );
-
- //some "dynamic" signal
- QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 20, r1, slot3Index) );
- QVERIFY( QMetaObject::connect( s, s->metaObject()->methodOffset() + 35, r2, slot1Index) );
- QVERIFY( QMetaObject::connect( s, -1, r1, slot2Index) );
-
- r1->reset();
- r2->reset();
-
- void *args[] = { 0 , 0 };
- QMetaObject::activate(s, s->metaObject()->methodOffset() + 20, args);
- QMetaObject::activate(s, s->metaObject()->methodOffset() + 48, args);
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 2 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
-
- QMetaObject::activate(s, s->metaObject()->methodOffset() + 35, args);
- s->emitSignal1();
- s->emitSignal2();
-
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 5 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
+ ReceiverObject r1;
+ ReceiverObject r2;
+ int slot1Index, slot2Index, slot3Index;
+ {
+ SenderObject s;
+ r1.reset();
+ r2.reset();
+ ReceiverObject::sequence = 0;
+
+ int signal1Index = s.metaObject()->indexOfSignal("signal1()");
+ int signal3Index = s.metaObject()->indexOfSignal("signal3()");
+ slot1Index = r1.metaObject()->indexOfSlot("slot1()");
+ slot2Index = r1.metaObject()->indexOfSlot("slot2()");
+ slot3Index = r1.metaObject()->indexOfSlot("slot3()");
+
+ QVERIFY(slot1Index > 0);
+ QVERIFY(slot2Index > 0);
+ QVERIFY(slot3Index > 0);
+
+ QVERIFY(QMetaObject::connect(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r2, slot3Index));
+ QVERIFY(QMetaObject::connect(&s, -1, &r2, slot2Index));
+
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+
+ s.emitSignal1();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 1);
+ QCOMPARE(r2.count_slot3, 0);
+
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 4);
+ QCOMPARE(r2.count_slot3, 1);
+
+ QVERIFY(QMetaObject::disconnect(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::disconnect(&s, signal3Index, &r2, slot3Index));
+ QVERIFY(QMetaObject::disconnect(&s, -1, &r2, slot2Index));
+
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 4);
+ QCOMPARE(r2.count_slot3, 1);
+
+ //some "dynamic" signal
+ QVERIFY(QMetaObject::connect(&s, s.metaObject()->methodOffset() + 20, &r1, slot3Index));
+ QVERIFY(QMetaObject::connect(&s, s.metaObject()->methodOffset() + 35, &r2, slot1Index));
+ QVERIFY(QMetaObject::connect(&s, -1, &r1, slot2Index));
+
+ r1.reset();
+ r2.reset();
+
+ void *args[] = { 0 , 0 };
+ QMetaObject::activate(&s, s.metaObject()->methodOffset() + 20, args);
+ QMetaObject::activate(&s, s.metaObject()->methodOffset() + 48, args);
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 2);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+
+ QMetaObject::activate(&s, s.metaObject()->methodOffset() + 35, args);
+ s.emitSignal1();
+ s.emitSignal2();
+
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 5);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ }
- delete s;
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
#define SIGNAL_INDEX(S) obj1.metaObject()->indexOfSignal(QMetaObject::normalizedSignature(#S))
OverloadObject obj1;
QObject obj2, obj3;
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int)) , r1, slot1Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *)) , r2, slot1Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int)) , &r1, slot1Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *)) ,
+ &r2, slot1Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *, QObject *)) , r1, slot2Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *)) , r2, slot2Index);
- QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int, int)) , r1, slot3Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *, QObject *, QObject *, QObject *)) ,
+ &r1, slot2Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(QObject *)) , &r2, slot2Index);
+ QMetaObject::connect(&obj1, SIGNAL_INDEX(sig(int, int)) , &r1, slot3Index);
emit obj1.sig(0.5); //connected to nothing
emit obj1.sig(1, 'a'); //connected to nothing
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 0 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 0);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
emit obj1.sig(1); //this signal is connected
emit obj1.sig(&obj2);
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 0 );
- QCOMPARE( r2->count_slot2, 1 );
- QCOMPARE( r2->count_slot3, 0 );
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 0);
+ QCOMPARE(r2.count_slot2, 1);
+ QCOMPARE(r2.count_slot3, 0);
emit obj1.sig(&obj2, &obj3); //this signal is connected
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 1 );
- QCOMPARE( r1->count_slot3, 1 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 1 );
- QCOMPARE( r2->count_slot3, 0 );
-
- delete r1;
- delete r2;
-
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 1);
+ QCOMPARE(r1.count_slot3, 1);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 1);
+ QCOMPARE(r2.count_slot3, 0);
}
void tst_QObject::qMetaObjectDisconnectOne()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
- int signal1Index = s->metaObject()->indexOfSignal("signal1()");
- int signal3Index = s->metaObject()->indexOfSignal("signal3()");
- int slot1Index = r1->metaObject()->indexOfSlot("slot1()");
- int slot2Index = r1->metaObject()->indexOfSlot("slot2()");
+ int signal1Index = s.metaObject()->indexOfSignal("signal1()");
+ int signal3Index = s.metaObject()->indexOfSignal("signal3()");
+ int slot1Index = r1.metaObject()->indexOfSlot("slot1()");
+ int slot2Index = r1.metaObject()->indexOfSlot("slot2()");
QVERIFY(signal1Index > 0);
QVERIFY(signal3Index > 0);
QVERIFY(slot1Index > 0);
QVERIFY(slot2Index > 0);
- QVERIFY( QMetaObject::connect(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) );
- QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) );
- QVERIFY( QMetaObject::connect(s, signal3Index, r1, slot2Index) );
-
- r1->reset();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ QVERIFY(QMetaObject::connect(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r1, slot2Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r1, slot2Index));
+ QVERIFY(QMetaObject::connect(&s, signal3Index, &r1, slot2Index));
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 3 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
- r1->reset();
- QVERIFY( QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 3);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QVERIFY(QMetaObject::disconnectOne(&s, signal1Index, &r1, slot1Index));
+ QVERIFY(QMetaObject::disconnectOne(&s, signal3Index, &r1, slot2Index));
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 2 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- r1->reset();
- QVERIFY( false == QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 2);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QVERIFY(!QMetaObject::disconnectOne(&s, signal1Index, &r1, slot1Index));
+ QVERIFY( QMetaObject::disconnectOne(&s, signal3Index, &r1, slot2Index));
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 1 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- r1->reset();
- QVERIFY( false == QMetaObject::disconnectOne(s, signal1Index, r1, slot1Index) );
- QVERIFY( QMetaObject::disconnectOne(s, signal3Index, r1, slot2Index) );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 1);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QVERIFY(!QMetaObject::disconnectOne(&s, signal1Index, &r1, slot1Index));
+ QVERIFY( QMetaObject::disconnectOne(&s, signal3Index, &r1, slot2Index));
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- delete s;
- delete r1;
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
}
class ConfusingObject : public SenderObject
@@ -4222,106 +4447,95 @@ void tst_QObject::connectConstructorByMetaMethod()
void tst_QObject::disconnectByMetaMethod()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
-
- QMetaMethod signal1 = s->metaObject()->method(
- s->metaObject()->indexOfMethod("signal1()"));
- QMetaMethod signal2 = s->metaObject()->method(
- s->metaObject()->indexOfMethod("signal2()"));
- QMetaMethod signal3 = s->metaObject()->method(
- s->metaObject()->indexOfMethod("signal3()"));
-
- QMetaMethod slot1 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot1()"));
- QMetaMethod slot2 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot2()"));
- QMetaMethod slot3 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot3()"));
- QMetaMethod slot4 = r1->metaObject()->method(
- r1->metaObject()->indexOfMethod("slot4()"));
-
- connect(s, signal1, r1, slot1);
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
- s->emitSignal1();
+ QMetaMethod signal1 = s.metaObject()->method(s.metaObject()->indexOfMethod("signal1()"));
+ QMetaMethod signal2 = s.metaObject()->method(s.metaObject()->indexOfMethod("signal2()"));
+ QMetaMethod signal3 = s.metaObject()->method(s.metaObject()->indexOfMethod("signal3()"));
+
+ QMetaMethod slot1 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot1()"));
+ QMetaMethod slot2 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot2()"));
+ QMetaMethod slot3 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot3()"));
+ QMetaMethod slot4 = r1.metaObject()->method(r1.metaObject()->indexOfMethod("slot4()"));
- QVERIFY(r1->called(1));
- r1->reset();
+ connect(&s, signal1, &r1, slot1);
+
+ s.emitSignal1();
+
+ QVERIFY(r1.called(1));
+ r1.reset();
// usual disconnect with all parameters given
- bool ret = QObject::disconnect(s, signal1, r1, slot1);
+ bool ret = QObject::disconnect(&s, signal1, &r1, slot1);
- s->emitSignal1();
+ s.emitSignal1();
- QVERIFY(!r1->called(1));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ r1.reset();
QVERIFY(ret);
- ret = QObject::disconnect(s, signal1, r1, slot1);
+ ret = QObject::disconnect(&s, signal1, &r1, slot1);
QVERIFY(!ret);
- r1->reset();
+ r1.reset();
- connect( s, signal1, r1, slot1 );
- connect( s, signal1, r1, slot2 );
- connect( s, signal1, r1, slot3 );
- connect( s, signal2, r1, slot4 );
+ connect(&s, signal1, &r1, slot1);
+ connect(&s, signal1, &r1, slot2);
+ connect(&s, signal1, &r1, slot3);
+ connect(&s, signal2, &r1, slot4);
// disconnect s's signal1() from all slots of r1
- QObject::disconnect(s, signal1, r1, QMetaMethod());
+ QObject::disconnect(&s, signal1, &r1, QMetaMethod());
- s->emitSignal1();
- s->emitSignal2();
+ s.emitSignal1();
+ s.emitSignal2();
- QVERIFY(!r1->called(1));
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// make sure all is disconnected again
- QObject::disconnect(s, 0, r1, 0);
+ QObject::disconnect(&s, 0, &r1, 0);
- connect(s, signal1, r1, slot1);
- connect(s, signal1, r2, slot1);
- connect(s, signal2, r1, slot2);
- connect(s, signal2, r2, slot2);
- connect(s, signal3, r1, slot3);
- connect(s, signal3, r2, slot3);
+ connect(&s, signal1, &r1, slot1);
+ connect(&s, signal1, &r2, slot1);
+ connect(&s, signal2, &r1, slot2);
+ connect(&s, signal2, &r2, slot2);
+ connect(&s, signal3, &r1, slot3);
+ connect(&s, signal3, &r2, slot3);
// disconnect signal1() from all receivers
- QObject::disconnect(s, signal1, 0, QMetaMethod());
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
+ QObject::disconnect(&s, signal1, 0, QMetaMethod());
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
- QVERIFY(!r1->called(1));
- QVERIFY(!r2->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r2.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
// disconnect all signals of s from all receivers
- QObject::disconnect( s, 0, 0, 0 );
+ QObject::disconnect(&s, 0, 0, 0);
- connect( s, signal1, r1, slot1 );
- connect( s, signal1, r2, slot1 );
+ connect(&s, signal1, &r1, slot1);
+ connect(&s, signal1, &r2, slot1);
// disconnect all signals from slot1 of r1
- QObject::disconnect(s, QMetaMethod(), r1, slot1);
-
- s->emitSignal1();
+ QObject::disconnect(&s, QMetaMethod(), &r1, slot1);
- QVERIFY(!r1->called(1));
- QVERIFY(r2->called(1));
+ s.emitSignal1();
- delete r2;
- delete r1;
- delete s;
+ QVERIFY(!r1.called(1));
+ QVERIFY(r2.called(1));
}
void tst_QObject::disconnectNotSignalMetaMethod()
@@ -4346,7 +4560,7 @@ public:
ThreadAffinityThread(SenderObject *sender)
: sender(sender)
{ }
- void run()
+ void run() override
{
sender->emitSignal1();
}
@@ -4459,63 +4673,64 @@ void tst_QObject::baseDestroyed()
void tst_QObject::pointerConnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
- r1->reset();
- r2->reset();
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
QTimer timer;
- QVERIFY( connect( s, &SenderObject::signal1 , r1, &ReceiverObject::slot1 ) );
- QVERIFY( connect( s, &SenderObject::signal1 , r2, &ReceiverObject::slot1 ) );
- QVERIFY( connect( s, &SenderObject::signal1 , r1, &ReceiverObject::slot3 ) );
- QVERIFY( connect( s, &SenderObject::signal3 , r1, &ReceiverObject::slot3 ) );
- QVERIFY2( connect( &timer, &QTimer::timeout, r1, &ReceiverObject::deleteLater ),
- "Signal connection failed most likely due to failing comparison of pointers to member functions caused by problems with -reduce-relocations on this platform.");
+ QVERIFY(connect(&s, &SenderObject::signal1 , &r1, &ReceiverObject::slot1));
+ QVERIFY(connect(&s, &SenderObject::signal1 , &r2, &ReceiverObject::slot1));
+ QVERIFY(connect(&s, &SenderObject::signal1 , &r1, &ReceiverObject::slot3));
+ QVERIFY(connect(&s, &SenderObject::signal3 , &r1, &ReceiverObject::slot3));
+ QVERIFY2(connect(&timer, &QTimer::timeout, &r1, &ReceiverObject::deleteLater),
+ "Signal connection failed most likely due to failing comparison of pointers to member "
+ "functions caused by problems with -reduce-relocations on this platform.");
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
-
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
- QCOMPARE( r1->count_slot3, 2 );
- QCOMPARE( r1->count_slot4, 0 );
- QCOMPARE( r2->count_slot1, 1 );
- QCOMPARE( r2->count_slot2, 0 );
- QCOMPARE( r2->count_slot3, 0 );
- QCOMPARE( r2->count_slot4, 0 );
- QCOMPARE( r1->sequence_slot1, 1 );
- QCOMPARE( r2->sequence_slot1, 2 );
- QCOMPARE( r1->sequence_slot3, 4 );
-
- r1->reset();
- r2->reset();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
+
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
+ QCOMPARE(r1.count_slot3, 2);
+ QCOMPARE(r1.count_slot4, 0);
+ QCOMPARE(r2.count_slot1, 1);
+ QCOMPARE(r2.count_slot2, 0);
+ QCOMPARE(r2.count_slot3, 0);
+ QCOMPARE(r2.count_slot4, 0);
+ QCOMPARE(r1.sequence_slot1, 1);
+ QCOMPARE(r2.sequence_slot1, 2);
+ QCOMPARE(r1.sequence_slot3, 4);
+
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- QVERIFY( connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 ) );
- QVERIFY( connect( s, &SenderObject::signal4, r2, &ReceiverObject::slot4 ) );
- QVERIFY( connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot4 ) );
+ QVERIFY(connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4));
+ QVERIFY(connect(&s, &SenderObject::signal4, &r2, &ReceiverObject::slot4));
+ QVERIFY(connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot4));
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 1 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 1 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 1);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 1);
+ QCOMPARE(r2.sequence_slot4, 2);
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
ReceiverObject::sequence = 0;
- connect( s, &SenderObject::signal4 , r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal4 , &r1, &ReceiverObject::slot4);
- s->emitSignal4();
- QCOMPARE( r1->count_slot4, 2 );
- QCOMPARE( r2->count_slot4, 1 );
- QCOMPARE( r1->sequence_slot4, 3 );
- QCOMPARE( r2->sequence_slot4, 2 );
+ s.emitSignal4();
+ QCOMPARE(r1.count_slot4, 2);
+ QCOMPARE(r2.count_slot4, 1);
+ QCOMPARE(r1.sequence_slot4, 3);
+ QCOMPARE(r2.sequence_slot4, 2);
QMetaObject::Connection con;
QVERIFY(!con);
@@ -4523,116 +4738,118 @@ void tst_QObject::pointerConnect()
//connect a slot to a signal (== error)
QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in ReceiverObject");
- con = connect(r1, &ReceiverObject::slot4 , s, &SenderObject::signal4 );
+ con = connect(&r1, &ReceiverObject::slot4 , &s, &SenderObject::signal4);
QVERIFY(!con);
QVERIFY(!QObject::disconnect(con));
- delete s;
- delete r1;
- delete r2;
+ //connect an arbitrary PMF to a slot
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in ReceiverObject");
+ con = connect(&r1, &ReceiverObject::reset, &r1, &ReceiverObject::slot1);
+ QVERIFY(!con);
+ QVERIFY(!QObject::disconnect(con));
+
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in ReceiverObject");
+ con = connect(&r1, &ReceiverObject::reset, &r1, [](){});
+ QVERIFY(!con);
+ QVERIFY(!QObject::disconnect(con));
}
void tst_QObject::pointerDisconnect()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
- ReceiverObject *r2 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
+ ReceiverObject r2;
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
- connect( s, &SenderObject::signal2, r1, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal3, r1, &ReceiverObject::slot3 );
- connect( s, &SenderObject::signal4, r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal2, &r1, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot3);
+ connect(&s, &SenderObject::signal4, &r1, &ReceiverObject::slot4);
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(r1->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(r1.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// usual disconnect with all parameters given
- bool ret = QObject::disconnect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
+ bool ret = QObject::disconnect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
- s->emitSignal1();
+ s.emitSignal1();
- QVERIFY(!r1->called(1));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ r1.reset();
QVERIFY(ret);
- ret = QObject::disconnect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
+ ret = QObject::disconnect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
QVERIFY(!ret);
// disconnect all signals from s from all slots from r1
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- s->emitSignal2();
- s->emitSignal3();
- s->emitSignal4();
+ s.emitSignal2();
+ s.emitSignal3();
+ s.emitSignal4();
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(!r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(!r1.called(4));
+ r1.reset();
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot3 );
- connect( s, &SenderObject::signal2, r1, &ReceiverObject::slot4 );
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot3);
+ connect(&s, &SenderObject::signal2, &r1, &ReceiverObject::slot4);
// disconnect s's signal1() from all slots of r1
- QObject::disconnect( s, &SenderObject::signal1, r1, 0 );
+ QObject::disconnect(&s, &SenderObject::signal1, &r1, 0);
- s->emitSignal1();
- s->emitSignal2();
+ s.emitSignal1();
+ s.emitSignal2();
- QVERIFY(!r1->called(1));
- QVERIFY(!r1->called(2));
- QVERIFY(!r1->called(3));
- QVERIFY(r1->called(4));
- r1->reset();
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r1.called(3));
+ QVERIFY(r1.called(4));
+ r1.reset();
// make sure all is disconnected again
- QObject::disconnect( s, 0, r1, 0 );
+ QObject::disconnect(&s, 0, &r1, 0);
- connect( s, &SenderObject::signal1, r1, &ReceiverObject::slot1 );
- connect( s, &SenderObject::signal1, r2, &ReceiverObject::slot1 );
- connect( s, &SenderObject::signal2, r1, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal2, r2, &ReceiverObject::slot2 );
- connect( s, &SenderObject::signal3, r1, &ReceiverObject::slot3 );
- connect( s, &SenderObject::signal3, r2, &ReceiverObject::slot3 );
+ connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+ connect(&s, &SenderObject::signal1, &r2, &ReceiverObject::slot1);
+ connect(&s, &SenderObject::signal2, &r1, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal2, &r2, &ReceiverObject::slot2);
+ connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot3);
+ connect(&s, &SenderObject::signal3, &r2, &ReceiverObject::slot3);
// disconnect signal1() from all receivers
- QObject::disconnect( s, &SenderObject::signal1, 0, 0 );
- s->emitSignal1();
- s->emitSignal2();
- s->emitSignal3();
+ QObject::disconnect(&s, &SenderObject::signal1, 0, 0);
+ s.emitSignal1();
+ s.emitSignal2();
+ s.emitSignal3();
- QVERIFY(!r1->called(1));
- QVERIFY(!r2->called(1));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
- QVERIFY(r1->called(2));
- QVERIFY(r2->called(2));
+ QVERIFY(!r1.called(1));
+ QVERIFY(!r2.called(1));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
+ QVERIFY(r1.called(2));
+ QVERIFY(r2.called(2));
- r1->reset();
- r2->reset();
+ r1.reset();
+ r2.reset();
// disconnect all signals of s from all receivers
- QObject::disconnect( s, 0, 0, 0 );
-
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
- QVERIFY(!r1->called(2));
- QVERIFY(!r2->called(2));
-
- delete r2;
- delete r1;
- delete s;
+ QObject::disconnect(&s, 0, 0, 0);
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
+ QVERIFY(!r1.called(2));
+ QVERIFY(!r2.called(2));
}
@@ -4717,8 +4934,7 @@ void tst_QObject::customTypesPointer()
checker.disconnect();
- int idx = qRegisterMetaType<CustomType>("CustomType");
- QCOMPARE(QMetaType::type("CustomType"), idx);
+ qRegisterMetaType<CustomType>();
connect(&checker, &QCustomTypeChecker::signal1, &checker, &QCustomTypeChecker::slot1,
Qt::QueuedConnection);
@@ -4731,11 +4947,6 @@ void tst_QObject::customTypesPointer()
QCOMPARE(checker.received.value(), t2.value());
QCOMPARE(instanceCount, 4);
- QVERIFY(QMetaType::isRegistered(idx));
- QCOMPARE(qRegisterMetaType<CustomType>("CustomType"), idx);
- QCOMPARE(QMetaType::type("CustomType"), idx);
- QVERIFY(QMetaType::isRegistered(idx));
-
// Test auto registered type (QList<CustomType>)
QList<CustomType> list;
QCOMPARE(instanceCount, 4);
@@ -4756,35 +4967,32 @@ void tst_QObject::customTypesPointer()
void tst_QObject::connectCxx0x()
{
- SenderObject *s = new SenderObject;
- ReceiverObject *r1 = new ReceiverObject;
+ SenderObject s;
+ ReceiverObject r1;
- QObject::connect(s, &SenderObject::signal1, r1, &ReceiverObject::slot1);
- QObject::connect(s, &SenderObject::signal3, r1, &ReceiverObject::slot2);
- QObject::connect(s, &SenderObject::signal3, r1, &ReceiverObject::slot2);
- QObject::connect(s, &SenderObject::signal3, r1, &ReceiverObject::slot2);
+ QObject::connect(&s, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+ QObject::connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot2);
+ QObject::connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot2);
+ QObject::connect(&s, &SenderObject::signal3, &r1, &ReceiverObject::slot2);
- r1->reset();
- QCOMPARE( r1->count_slot1, 0 );
- QCOMPARE( r1->count_slot2, 0 );
+ r1.reset();
+ QCOMPARE(r1.count_slot1, 0);
+ QCOMPARE(r1.count_slot2, 0);
- s->emitSignal1();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 0 );
+ s.emitSignal1();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 0);
- s->emitSignal3();
- QCOMPARE( r1->count_slot1, 1 );
- QCOMPARE( r1->count_slot2, 3 );
+ s.emitSignal3();
+ QCOMPARE(r1.count_slot1, 1);
+ QCOMPARE(r1.count_slot2, 3);
// connect signal to signal
- QObject::connect(s, &SenderObject::signal2, s, &SenderObject::signal1);
-
- r1->reset();
- s->emitSignal2();
- QCOMPARE( r1->count_slot1, 1 );
+ QObject::connect(&s, &SenderObject::signal2, &s, &SenderObject::signal1);
- delete s;
- delete r1;
+ r1.reset();
+ s.emitSignal2();
+ QCOMPARE(r1.count_slot1, 1);
}
int receivedCount;
@@ -4816,13 +5024,13 @@ class LotsOfSignalsAndSlots: public QObject
public slots:
void slot_v() {}
- void slot_v_noexcept() Q_DECL_NOTHROW {}
+ void slot_v_noexcept() noexcept {}
void slot_vi(int) {}
- void slot_vi_noexcept() Q_DECL_NOTHROW {}
+ void slot_vi_noexcept() noexcept {}
void slot_vii(int, int) {}
void slot_viii(int, int, int) {}
int slot_i() { return 0; }
- int slot_i_noexcept() Q_DECL_NOTHROW { return 0; }
+ int slot_i_noexcept() noexcept { return 0; }
int slot_ii(int) { return 0; }
int slot_iii(int, int) { return 0; }
int slot_iiii(int, int, int) { return 0; }
@@ -4836,18 +5044,18 @@ class LotsOfSignalsAndSlots: public QObject
void slot_vPFvvE(fptr) {}
void const_slot_v() const {};
- void const_slot_v_noexcept() const Q_DECL_NOTHROW {}
+ void const_slot_v_noexcept() const noexcept {}
void const_slot_vi(int) const {};
- void const_slot_vi_noexcept(int) const Q_DECL_NOTHROW {}
+ void const_slot_vi_noexcept(int) const noexcept {}
static void static_slot_v() {}
- static void static_slot_v_noexcept() Q_DECL_NOTHROW {}
+ static void static_slot_v_noexcept() noexcept {}
static void static_slot_vi(int) {}
- static void static_slot_vi_noexcept(int) Q_DECL_NOTHROW {}
+ static void static_slot_vi_noexcept(int) noexcept {}
static void static_slot_vii(int, int) {}
static void static_slot_viii(int, int, int) {}
static int static_slot_i() { return 0; }
- static int static_slot_i_noexcept() Q_DECL_NOTHROW { return 0; }
+ static int static_slot_i_noexcept() noexcept { return 0; }
static int static_slot_ii(int) { return 0; }
static int static_slot_iii(int, int) { return 0; }
static int static_slot_iiii(int, int, int) { return 0; }
@@ -5010,11 +5218,11 @@ void tst_QObject::connectCxx0xTypeMatching()
}
-void receiverFunction_noexcept() Q_DECL_NOTHROW {}
-struct Functor_noexcept { void operator()() Q_DECL_NOTHROW {} };
+void receiverFunction_noexcept() noexcept {}
+struct Functor_noexcept { void operator()() noexcept {} };
void tst_QObject::connectCxx17Noexcept()
{
- // this is about connecting signals to slots with the Q_DECL_NOTHROW qualifier
+ // this is about connecting signals to slots with the noexcept qualifier
// as semantics changed due to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html
typedef LotsOfSignalsAndSlots Foo;
Foo obj;
@@ -5259,7 +5467,7 @@ namespace ManyArgumentNamespace {
}
};
- struct Funct6 {
+ struct Funct6 final {
void operator()(const QString &a, const QString &b, const QString &c, const QString&d, const QString&e, const QString&f) {
MANYARGUMENT_COMPARE(a); MANYARGUMENT_COMPARE(b); MANYARGUMENT_COMPARE(c);
MANYARGUMENT_COMPARE(d); MANYARGUMENT_COMPARE(e); MANYARGUMENT_COMPARE(f);
@@ -5343,6 +5551,8 @@ void tst_QObject::connectForwardDeclare()
QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection));
}
+class ForwardDeclared {}; // complete definition for moc
+
class NoDefaultConstructor
{
Q_GADGET
@@ -5718,7 +5928,7 @@ signals:
class VirtualSlotsObject : public VirtualSlotsObjectBase {
Q_OBJECT
public slots:
- virtual void slot1() {
+ virtual void slot1() override {
derived_counter1++;
}
public:
@@ -5767,8 +5977,8 @@ public:
public slots:
void regularSlot() { ++regular_call_count; }
- virtual void slot1() { ++derived_counter2; }
- virtual void slot2() { ++virtual_base_count; }
+ virtual void slot1() override { ++derived_counter2; }
+ virtual void slot2() override { ++virtual_base_count; }
};
struct NormalBase
@@ -5971,10 +6181,10 @@ class ConnectToPrivateSlotPrivate;
class ConnectToPrivateSlot :public QObject {
Q_OBJECT
+ Q_DECLARE_PRIVATE(ConnectToPrivateSlot)
public:
ConnectToPrivateSlot();
void test(SenderObject *obj1) ;
- Q_DECLARE_PRIVATE(ConnectToPrivateSlot)
};
class ConnectToPrivateSlotPrivate : public QObjectPrivate {
@@ -5991,6 +6201,8 @@ public:
receivedCount++;
receivedValue = v;
};
+
+ void testFromPrivate(SenderObject *obj);
};
ConnectToPrivateSlot::ConnectToPrivateSlot(): QObject(*new ConnectToPrivateSlotPrivate) {}
@@ -6004,7 +6216,7 @@ void ConnectToPrivateSlot::test(SenderObject* obj1) {
obj1->signal1();
QCOMPARE(d->receivedCount, 1);
QCOMPARE(d->receivedValue, QVariant());
- obj1->signal7(666, QLatin1Literal("_"));
+ obj1->signal7(666, QLatin1String("_"));
QCOMPARE(d->receivedCount, 2);
QCOMPARE(d->receivedValue, QVariant(666));
QVERIFY(QObjectPrivate::connect(obj1, &SenderObject::signal2, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot, Qt::UniqueConnection));
@@ -6017,6 +6229,14 @@ void ConnectToPrivateSlot::test(SenderObject* obj1) {
QVERIFY(!QObjectPrivate::disconnect(obj1, &SenderObject::signal2, d, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot));
}
+// Compile test to verify that we can use QObjectPrivate::connect in
+// the code of the private class, even if Q_DECLARE_PUBLIC is used in the
+// private section of the private class.
+void ConnectToPrivateSlotPrivate::testFromPrivate(SenderObject *obj)
+{
+ QVERIFY(QObjectPrivate::connect(obj, &SenderObject::signal1, this, &ConnectToPrivateSlotPrivate::thisIsAPrivateSlot));
+}
+
void tst_QObject::connectPrivateSlots()
{
SenderObject sender;
@@ -6051,15 +6271,14 @@ void tst_QObject::connectFunctorArgDifference()
QStringListModel model;
connect(&model, &QStringListModel::rowsInserted, SlotFunctor());
-#if defined(Q_COMPILER_LAMBDA)
connect(&timer, &QTimer::timeout, [=](){});
connect(&timer, &QTimer::objectNameChanged, [=](const QString &){});
+ connect(&timer, &QTimer::objectNameChanged, this, [](){});
connect(qApp, &QCoreApplication::aboutToQuit, [=](){});
connect(&timer, &QTimer::objectNameChanged, [=](){});
connect(&model, &QStringListModel::rowsInserted, [=](){});
connect(&model, &QStringListModel::rowsInserted, [=](const QModelIndex &){});
-#endif
QVERIFY(true);
}
@@ -6097,7 +6316,6 @@ void tst_QObject::connectFunctorQueued()
e.exec();
QCOMPARE(status, 2);
-#if defined(Q_COMPILER_LAMBDA)
status = 1;
connect(&obj, &SenderObject::signal1, this, [&status] { status = 2; }, Qt::QueuedConnection);
@@ -6105,7 +6323,6 @@ void tst_QObject::connectFunctorQueued()
QCOMPARE(status, 1);
e.exec();
QCOMPARE(status, 2);
-#endif
}
void tst_QObject::connectFunctorWithContext()
@@ -6124,13 +6341,41 @@ void tst_QObject::connectFunctorWithContext()
connect(context, &QObject::destroyed, &obj, &SenderObject::signal1, Qt::QueuedConnection);
context->deleteLater();
- QCOMPARE(status, 1);
+ obj.emitSignal1();
+ QCOMPARE(status, 2);
e.exec();
- QCOMPARE(status, 1);
+ QCOMPARE(status, 2);
+
+ // Check disconnect with the context object as "receiver" argument, all signals
+ context = new ContextObject;
+ status = 1;
+ connect(&obj, &SenderObject::signal1, context, SlotArgFunctor(&status));
+
+ obj.emitSignal1();
+ QCOMPARE(status, 2);
+ QObject::disconnect(&obj, nullptr, context, nullptr);
+ obj.emitSignal1();
+ QCOMPARE(status, 2);
+
+ delete context;
+
+ // Check disconnect with the context object as "receiver" argument, specific signal
+ context = new ContextObject;
+ status = 1;
+ connect(&obj, &SenderObject::signal1, context, SlotArgFunctor(&status));
+
+ obj.emitSignal1();
+ QCOMPARE(status, 2);
+ QObject::disconnect(&obj, &SenderObject::signal1, context, nullptr);
+ obj.emitSignal1();
+ QCOMPARE(status, 2);
+
+ delete context;
// Check the sender arg is set correctly in the context
context = new ContextObject;
+ status = 1;
connect(&obj, &SenderObject::signal1, context,
SlotArgFunctor(context, &obj, &status), Qt::QueuedConnection);
@@ -6139,7 +6384,6 @@ void tst_QObject::connectFunctorWithContext()
e.exec();
QCOMPARE(status, 2);
-#if defined(Q_COMPILER_LAMBDA)
status = 1;
connect(&obj, &SenderObject::signal1, this, [this, &status, &obj] { status = 2; QCOMPARE(sender(), &obj); }, Qt::QueuedConnection);
@@ -6147,10 +6391,8 @@ void tst_QObject::connectFunctorWithContext()
QCOMPARE(status, 1);
e.exec();
QCOMPARE(status, 2);
-#endif
- // Free
- context->deleteLater();
+ delete context;
}
class StatusChanger : public QObject
@@ -6202,7 +6444,7 @@ public slots:
{
if (abouttoblock) {
abouttoblock->deleteLater();
- abouttoblock = 0;
+ abouttoblock = nullptr;
}
++m_aboutToBlocks;
}
@@ -6210,7 +6452,7 @@ public slots:
{
if (awake) {
awake->deleteLater();
- awake = 0;
+ awake = nullptr;
}
++m_awakes;
@@ -6256,13 +6498,49 @@ void tst_QObject::connectFunctorWithContextUnique()
SenderObject sender;
ReceiverObject receiver;
- QObject::connect(&sender, &SenderObject::signal1, &receiver, &ReceiverObject::slot1);
+ QVERIFY(QObject::connect(&sender, &SenderObject::signal1, &receiver, &ReceiverObject::slot1));
receiver.count_slot1 = 0;
- QObject::connect(&sender, &SenderObject::signal1, &receiver, SlotFunctor(), Qt::UniqueConnection);
+ QVERIFY(QObject::connect(&sender, &SenderObject::signal2, &receiver, &ReceiverObject::slot2));
+ receiver.count_slot2 = 0;
+
+ const auto oredType = Qt::ConnectionType(Qt::DirectConnection | Qt::UniqueConnection);
+
+ // Will assert in debug builds, so only test in release builds
+#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
+ auto ignoreMsg = [] {
+ QTest::ignoreMessage(QtWarningMsg,
+ "QObject::connect(SenderObject, ReceiverObject): unique connections "
+ "require a pointer to member function of a QObject subclass");
+ };
+
+ ignoreMsg();
+ QVERIFY(!QObject::connect(&sender, &SenderObject::signal1, &receiver, [&](){ receiver.slot1(); }, Qt::UniqueConnection));
+
+ ignoreMsg();
+ QVERIFY(!QObject::connect(
+ &sender, &SenderObject::signal2, &receiver, [&]() { receiver.slot2(); }, oredType));
+#endif
sender.emitSignal1();
QCOMPARE(receiver.count_slot1, 1);
+
+ sender.emitSignal2();
+ QCOMPARE(receiver.count_slot2, 1);
+
+ // Check connecting to PMF doesn't hit the assert
+
+ QVERIFY(QObject::connect(&sender, &SenderObject::signal3, &receiver, &ReceiverObject::slot3,
+ Qt::UniqueConnection));
+ receiver.count_slot3 = 0;
+ sender.emitSignal3();
+ QCOMPARE(receiver.count_slot3, 1);
+
+ QVERIFY(QObject::connect(&sender, &SenderObject::signal4, &receiver, &ReceiverObject::slot4,
+ oredType));
+ receiver.count_slot4 = 0;
+ sender.emitSignal4();
+ QCOMPARE(receiver.count_slot4, 1);
}
class MyFunctor
@@ -6457,7 +6735,7 @@ void connectFunctorOverload_impl(Signal signal, int expOverload, QList<QVariant>
void tst_QObject::connectFunctorOverloads()
{
-#if defined (Q_COMPILER_DECLTYPE) && defined (Q_COMPILER_VARIADIC_TEMPLATES)
+#if defined (Q_COMPILER_VARIADIC_TEMPLATES)
connectFunctorOverload_impl<ComplexFunctor>(&FunctorArgDifferenceObject::signal_ii, 1,
(QList<QVariant>() << 1 << 2));
connectFunctorOverload_impl<ComplexFunctor>(&FunctorArgDifferenceObject::signal_iiS, 1,
@@ -6631,7 +6909,6 @@ void tst_QObject::disconnectDoesNotLeakFunctor()
}
QCOMPARE(countedStructObjectsCount, 0);
{
-#if defined(Q_COMPILER_LAMBDA)
CountedStruct s;
QCOMPARE(countedStructObjectsCount, 1);
QTimer timer;
@@ -6641,7 +6918,6 @@ void tst_QObject::disconnectDoesNotLeakFunctor()
QCOMPARE(countedStructObjectsCount, 2);
QVERIFY(QObject::disconnect(c));
QCOMPARE(countedStructObjectsCount, 1);
-#endif // Q_COMPILER_LAMBDA
}
QCOMPARE(countedStructObjectsCount, 0);
}
@@ -6689,7 +6965,6 @@ void tst_QObject::contextDoesNotLeakFunctor()
}
QCOMPARE(countedStructObjectsCount, 0);
{
-#if defined(Q_COMPILER_LAMBDA)
CountedStruct s;
QEventLoop e;
ContextObject *context = new ContextObject;
@@ -6702,7 +6977,6 @@ void tst_QObject::contextDoesNotLeakFunctor()
context->deleteLater();
e.exec();
QCOMPARE(countedStructObjectsCount, 1);
-#endif // Q_COMPILER_LAMBDA
}
QCOMPARE(countedStructObjectsCount, 0);
}
@@ -6749,16 +7023,16 @@ void tst_QObject::connectWarnings()
ReceiverObject r1;
r1.reset();
- QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter");
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid nullptr parameter");
connect(static_cast<const SenderObject *>(nullptr), &SubSender::signal1, &r1, &ReceiverObject::slot1);
- QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SubSender, Unknown): invalid null parameter");
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SubSender, Unknown): invalid nullptr parameter");
connect(&sub, &SubSender::signal1, static_cast<ReceiverObject *>(nullptr), &ReceiverObject::slot1);
- QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter");
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid nullptr parameter");
connect(static_cast<const SenderObject *>(nullptr), &SenderObject::signal1, &r1, &ReceiverObject::slot1);
- QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, Unknown): invalid null parameter");
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, Unknown): invalid nullptr parameter");
connect(&obj, &SenderObject::signal1, static_cast<ReceiverObject *>(nullptr), &ReceiverObject::slot1);
}
@@ -6773,7 +7047,11 @@ struct QmlReceiver : public QtPrivate::QSlotObjectBase
, magic(0)
{}
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
static void impl(int which, QSlotObjectBase *this_, QObject *, void **metaArgs, bool *ret)
+#else
+ static void impl(QSlotObjectBase *this_, QObject *, void **metaArgs, int which, bool *ret)
+#endif
{
switch (which) {
case Destroy: delete static_cast<QmlReceiver*>(this_); return;
@@ -6813,6 +7091,33 @@ void tst_QObject::qmlConnect()
#endif
}
+void tst_QObject::qmlConnectToQObjectReceiver()
+{
+#ifdef QT_BUILD_INTERNAL
+ SenderObject sender;
+ QScopedPointer<QObject> receiver(new QObject);
+ QmlReceiver *slotObject = new QmlReceiver;
+ slotObject->magic = slotObject;
+ slotObject->ref(); // extra ref so that slot object is not implicitly deleted
+
+ QVERIFY(QObjectPrivate::connect(&sender, sender.metaObject()->indexOfSignal("signal1()"),
+ receiver.get(), slotObject, Qt::AutoConnection));
+
+ QCOMPARE(slotObject->callCount, 0);
+ sender.emitSignal1();
+ QCOMPARE(slotObject->callCount, 1);
+
+ receiver.reset(); // this should disconnect the slotObject
+
+ sender.emitSignal1();
+ QCOMPARE(slotObject->callCount, 1);
+
+ slotObject->destroyIfLastRef();
+#else
+ QSKIP("Needs QT_BUILD_INTERNAL");
+#endif
+}
+
#ifndef QT_NO_EXCEPTIONS
class ObjectException : public std::exception { };
@@ -6850,8 +7155,11 @@ public:
explicit CountedExceptionThrower(bool throwException, QObject *parent = nullptr)
: QObject(parent)
{
+ Q_UNUSED(throwException);
+#ifndef QT_NO_EXCEPTIONS
if (throwException)
throw ObjectException();
+#endif
++counter;
}
@@ -6985,43 +7293,6 @@ void tst_QObject::exceptions()
#endif
}
-#ifdef QT_BUILD_INTERNAL
-static bool parentChangeCalled = false;
-
-static void testParentChanged(QAbstractDeclarativeData *, QObject *, QObject *)
-{
- parentChangeCalled = true;
-}
-#endif
-
-void tst_QObject::noDeclarativeParentChangedOnDestruction()
-{
-#ifdef QT_BUILD_INTERNAL
- typedef void (*ParentChangedCallback)(QAbstractDeclarativeData *, QObject *, QObject *);
- QScopedValueRollback<ParentChangedCallback> rollback(QAbstractDeclarativeData::parentChanged);
- QAbstractDeclarativeData::parentChanged = testParentChanged;
-
- QObject *parent = new QObject;
- QObject *child = new QObject;
-
- QAbstractDeclarativeDataImpl dummy;
- dummy.ownedByQml1 = false;
- QObjectPrivate::get(child)->declarativeData = &dummy;
-
- parentChangeCalled = false;
- child->setParent(parent);
-
- QVERIFY(parentChangeCalled);
- parentChangeCalled = false;
-
- delete child;
- QVERIFY(!parentChangeCalled);
-
- delete parent;
-#else
- QSKIP("Needs QT_BUILD_INTERNAL");
-#endif
-}
struct MutableFunctor {
int count;
@@ -7043,24 +7314,34 @@ void tst_QObject::mutableFunctor()
void tst_QObject::checkArgumentsForNarrowing()
{
- enum UnscopedEnum {};
- enum SignedUnscopedEnum { SignedUnscopedEnumV1 = -1, SignedUnscopedEnumV2 = 1 };
+ // Clang and ICC masquerade as GCC, so introduce a more strict define
+ // for exactly GCC (to exclude/include it from some tests).
+#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+#define Q_CC_EXACTLY_GCC Q_CC_GNU
+#endif
+
+ enum UnscopedEnum { UnscopedEnumV1 = INT_MAX, UnscopedEnumV2 };
+ enum SignedUnscopedEnum { SignedUnscopedEnumV1 = INT_MIN, SignedUnscopedEnumV2 = INT_MAX };
- // a constexpr would suffice, but MSVC2013 RTM doesn't support them...
-#define IS_UNSCOPED_ENUM_SIGNED (std::is_signed<typename std::underlying_type<UnscopedEnum>::type>::value)
+ static constexpr bool IsUnscopedEnumSigned = std::is_signed_v<std::underlying_type_t<UnscopedEnum>>;
-#define NARROWS_IF(x, y, test) Q_STATIC_ASSERT((QtPrivate::AreArgumentsNarrowedBase<x, y>::value) == (test))
-#define FITS_IF(x, y, test) Q_STATIC_ASSERT((QtPrivate::AreArgumentsNarrowedBase<x, y>::value) != (test))
+#define NARROWS_IF(x, y, test) static_assert((QtPrivate::AreArgumentsConvertibleWithoutNarrowingBase<x, y>::value) != (test))
+#define FITS_IF(x, y, test) static_assert((QtPrivate::AreArgumentsConvertibleWithoutNarrowingBase<x, y>::value) == (test))
#define NARROWS(x, y) NARROWS_IF(x, y, true)
#define FITS(x, y) FITS_IF(x, y, true)
- Q_STATIC_ASSERT(sizeof(UnscopedEnum) <= sizeof(int));
- Q_STATIC_ASSERT(sizeof(SignedUnscopedEnum) <= sizeof(int));
+ static_assert(sizeof(UnscopedEnum) <= sizeof(int));
+ static_assert(sizeof(SignedUnscopedEnum) <= sizeof(int));
// floating point to integral
+
+ // GCC < 9 does not consider floating point to bool to be narrowing,
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65043
+#if !defined(Q_CC_EXACTLY_GCC) || Q_CC_EXACTLY_GCC >= 900
NARROWS(float, bool);
NARROWS(double, bool);
NARROWS(long double, bool);
+#endif
NARROWS(float, char);
NARROWS(double, char);
@@ -7084,12 +7365,19 @@ void tst_QObject::checkArgumentsForNarrowing()
// floating point to a smaller floating point
- NARROWS_IF(double, float, (sizeof(double) > sizeof(float)));
- NARROWS_IF(long double, float, (sizeof(long double) > sizeof(float)));
+ NARROWS(double, float);
+ NARROWS(long double, float);
FITS(float, double);
FITS(float, long double);
- NARROWS_IF(long double, double, (sizeof(long double) > sizeof(double)));
+ // GCC < 11 thinks this is narrowing only on architectures where
+ // sizeof(long double) > sizeof(double)
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94590
+#if defined(Q_CC_EXACTLY_GCC) && (Q_CC_EXACTLY_GCC < 1100)
+ NARROWS_IF(long double, double, sizeof(long double) > sizeof(double));
+#else
+ NARROWS(long double, double);
+#endif
FITS(double, long double);
@@ -7235,11 +7523,14 @@ void tst_QObject::checkArgumentsForNarrowing()
// integral to integral with different signedness. smaller ones tested above
NARROWS(signed char, unsigned char);
+
+ // Issue is reported to Green Hills, 2021-09-14.
+#if !defined(Q_CC_GHS)
NARROWS(signed char, unsigned short);
NARROWS(signed char, unsigned int);
NARROWS(signed char, unsigned long);
NARROWS(signed char, unsigned long long);
-
+#endif // Q_CC_GHS
NARROWS(unsigned char, signed char);
FITS(unsigned char, short);
FITS(unsigned char, int);
@@ -7247,19 +7538,23 @@ void tst_QObject::checkArgumentsForNarrowing()
FITS(unsigned char, long long);
NARROWS(short, unsigned short);
+#if !defined(Q_CC_GHS)
NARROWS(short, unsigned int);
NARROWS(short, unsigned long);
- NARROWS(short, unsigned long long);
+ NARROWS(short, unsigned long long);
+#endif // Q_CC_GHS
NARROWS(unsigned short, short);
+
FITS(unsigned short, int);
FITS(unsigned short, long);
FITS(unsigned short, long long);
NARROWS(int, unsigned int);
+#if !defined(Q_CC_GHS)
NARROWS(int, unsigned long);
NARROWS(int, unsigned long long);
-
+#endif // Q_CC_GHS
NARROWS(unsigned int, int);
NARROWS_IF(unsigned int, long, (sizeof(int) >= sizeof(long)));
FITS(unsigned int, long long);
@@ -7278,23 +7573,23 @@ void tst_QObject::checkArgumentsForNarrowing()
FITS(UnscopedEnum, UnscopedEnum);
FITS(SignedUnscopedEnum, SignedUnscopedEnum);
- NARROWS_IF(UnscopedEnum, char, ((sizeof(UnscopedEnum) > sizeof(char)) || (sizeof(UnscopedEnum) == sizeof(char) && IS_UNSCOPED_ENUM_SIGNED == std::is_signed<char>::value)));
- NARROWS_IF(UnscopedEnum, signed char, ((sizeof(UnscopedEnum) > sizeof(char)) || (sizeof(UnscopedEnum) == sizeof(char) && !IS_UNSCOPED_ENUM_SIGNED)));
- NARROWS_IF(UnscopedEnum, unsigned char, ((sizeof(UnscopedEnum) > sizeof(char)) || IS_UNSCOPED_ENUM_SIGNED));
+ NARROWS_IF(UnscopedEnum, char, ((sizeof(UnscopedEnum) > sizeof(char)) || (sizeof(UnscopedEnum) == sizeof(char) && IsUnscopedEnumSigned == std::is_signed<char>::value)));
+ NARROWS_IF(UnscopedEnum, signed char, ((sizeof(UnscopedEnum) > sizeof(char)) || (sizeof(UnscopedEnum) == sizeof(char) && !IsUnscopedEnumSigned)));
+ NARROWS_IF(UnscopedEnum, unsigned char, ((sizeof(UnscopedEnum) > sizeof(char)) || IsUnscopedEnumSigned));
- NARROWS_IF(UnscopedEnum, short, ((sizeof(UnscopedEnum) > sizeof(short)) || (sizeof(UnscopedEnum) == sizeof(short) && !IS_UNSCOPED_ENUM_SIGNED)));
- NARROWS_IF(UnscopedEnum, unsigned short, ((sizeof(UnscopedEnum) > sizeof(short)) || IS_UNSCOPED_ENUM_SIGNED));
+ NARROWS_IF(UnscopedEnum, short, ((sizeof(UnscopedEnum) > sizeof(short)) || (sizeof(UnscopedEnum) == sizeof(short) && !IsUnscopedEnumSigned)));
+ NARROWS_IF(UnscopedEnum, unsigned short, ((sizeof(UnscopedEnum) > sizeof(short)) || IsUnscopedEnumSigned));
- NARROWS_IF(UnscopedEnum, int, (sizeof(UnscopedEnum) == sizeof(int) && !IS_UNSCOPED_ENUM_SIGNED));
- NARROWS_IF(UnscopedEnum, unsigned int, IS_UNSCOPED_ENUM_SIGNED);
+ NARROWS_IF(UnscopedEnum, int, sizeof(UnscopedEnum) > sizeof(int) || (sizeof(UnscopedEnum) == sizeof(int) && !IsUnscopedEnumSigned));
+ NARROWS_IF(UnscopedEnum, unsigned int, IsUnscopedEnumSigned);
- NARROWS_IF(UnscopedEnum, long, (sizeof(UnscopedEnum) == sizeof(long) && !IS_UNSCOPED_ENUM_SIGNED));
- NARROWS_IF(UnscopedEnum, unsigned long, IS_UNSCOPED_ENUM_SIGNED);
+ NARROWS_IF(UnscopedEnum, long, sizeof(UnscopedEnum) > sizeof(long) || (sizeof(UnscopedEnum) == sizeof(long) && !IsUnscopedEnumSigned));
+ NARROWS_IF(UnscopedEnum, unsigned long, IsUnscopedEnumSigned);
- NARROWS_IF(UnscopedEnum, long long, (sizeof(UnscopedEnum) == sizeof(long long) && !IS_UNSCOPED_ENUM_SIGNED));
- NARROWS_IF(UnscopedEnum, unsigned long long, IS_UNSCOPED_ENUM_SIGNED);
+ NARROWS_IF(UnscopedEnum, long long, sizeof(UnscopedEnum) > sizeof(long long) || (sizeof(UnscopedEnum) == sizeof(long long) && !IsUnscopedEnumSigned));
+ NARROWS_IF(UnscopedEnum, unsigned long long, IsUnscopedEnumSigned);
- Q_STATIC_ASSERT(std::is_signed<typename std::underlying_type<SignedUnscopedEnum>::type>::value);
+ static_assert(std::is_signed<typename std::underlying_type<SignedUnscopedEnum>::type>::value);
NARROWS_IF(SignedUnscopedEnum, signed char, (sizeof(SignedUnscopedEnum) > sizeof(char)));
NARROWS_IF(SignedUnscopedEnum, short, (sizeof(SignedUnscopedEnum) > sizeof(short)));
@@ -7302,202 +7597,73 @@ void tst_QObject::checkArgumentsForNarrowing()
FITS(SignedUnscopedEnum, long);
FITS(SignedUnscopedEnum, long long);
-
- enum class ScopedEnumBackedBySChar : signed char { A };
- enum class ScopedEnumBackedByUChar : unsigned char { A };
- enum class ScopedEnumBackedByShort : short { A };
- enum class ScopedEnumBackedByUShort : unsigned short { A };
- enum class ScopedEnumBackedByInt : int { A };
- enum class ScopedEnumBackedByUInt : unsigned int { A };
- enum class ScopedEnumBackedByLong : long { A };
- enum class ScopedEnumBackedByULong : unsigned long { A };
- enum class ScopedEnumBackedByLongLong : long long { A };
- enum class ScopedEnumBackedByULongLong : unsigned long long { A };
-
- FITS(ScopedEnumBackedBySChar, ScopedEnumBackedBySChar);
- FITS(ScopedEnumBackedByUChar, ScopedEnumBackedByUChar);
- FITS(ScopedEnumBackedByShort, ScopedEnumBackedByShort);
- FITS(ScopedEnumBackedByUShort, ScopedEnumBackedByUShort);
- FITS(ScopedEnumBackedByInt, ScopedEnumBackedByInt);
- FITS(ScopedEnumBackedByUInt, ScopedEnumBackedByUInt);
- FITS(ScopedEnumBackedByLong, ScopedEnumBackedByLong);
- FITS(ScopedEnumBackedByULong, ScopedEnumBackedByULong);
- FITS(ScopedEnumBackedByLongLong, ScopedEnumBackedByLongLong);
- FITS(ScopedEnumBackedByULongLong, ScopedEnumBackedByULongLong);
-
- FITS(ScopedEnumBackedBySChar, signed char);
- FITS(ScopedEnumBackedByUChar, unsigned char);
- FITS(ScopedEnumBackedByShort, short);
- FITS(ScopedEnumBackedByUShort, unsigned short);
- FITS(ScopedEnumBackedByInt, int);
- FITS(ScopedEnumBackedByUInt, unsigned int);
- FITS(ScopedEnumBackedByLong, long);
- FITS(ScopedEnumBackedByULong, unsigned long);
- FITS(ScopedEnumBackedByLongLong, long long);
- FITS(ScopedEnumBackedByULongLong, unsigned long long);
-
- FITS(ScopedEnumBackedBySChar, signed char);
- FITS(ScopedEnumBackedBySChar, short);
- FITS(ScopedEnumBackedBySChar, int);
- FITS(ScopedEnumBackedBySChar, long);
- FITS(ScopedEnumBackedBySChar, long long);
-
- FITS(ScopedEnumBackedByUChar, unsigned char);
- FITS(ScopedEnumBackedByUChar, unsigned short);
- FITS(ScopedEnumBackedByUChar, unsigned int);
- FITS(ScopedEnumBackedByUChar, unsigned long);
- FITS(ScopedEnumBackedByUChar, unsigned long long);
-
- NARROWS_IF(ScopedEnumBackedByShort, char, (sizeof(short) > sizeof(char) || std::is_unsigned<char>::value));
- NARROWS_IF(ScopedEnumBackedByUShort, char, (sizeof(short) > sizeof(char) || std::is_signed<char>::value));
- NARROWS_IF(ScopedEnumBackedByInt, char, (sizeof(int) > sizeof(char) || std::is_unsigned<char>::value));
- NARROWS_IF(ScopedEnumBackedByUInt, char, (sizeof(int) > sizeof(char) || std::is_signed<char>::value));
- NARROWS_IF(ScopedEnumBackedByLong, char, (sizeof(long) > sizeof(char) || std::is_unsigned<char>::value));
- NARROWS_IF(ScopedEnumBackedByULong, char, (sizeof(long) > sizeof(char) || std::is_signed<char>::value));
- NARROWS_IF(ScopedEnumBackedByLongLong, char, (sizeof(long long) > sizeof(char) || std::is_unsigned<char>::value));
- NARROWS_IF(ScopedEnumBackedByULongLong, char, (sizeof(long long) > sizeof(char) || std::is_signed<char>::value));
-
- NARROWS_IF(ScopedEnumBackedByShort, signed char, (sizeof(short) > sizeof(char)));
- NARROWS(ScopedEnumBackedByUShort, signed char);
- NARROWS_IF(ScopedEnumBackedByInt, signed char, (sizeof(int) > sizeof(char)));
- NARROWS(ScopedEnumBackedByUInt, signed char);
- NARROWS_IF(ScopedEnumBackedByLong, signed char, (sizeof(long) > sizeof(char)));
- NARROWS(ScopedEnumBackedByULong, signed char);
- NARROWS_IF(ScopedEnumBackedByLongLong, signed char, (sizeof(long long) > sizeof(char)));
- NARROWS(ScopedEnumBackedByULongLong, signed char);
-
- NARROWS(ScopedEnumBackedByShort, unsigned char);
- NARROWS_IF(ScopedEnumBackedByUShort, unsigned char, (sizeof(short) > sizeof(char)));
- NARROWS(ScopedEnumBackedByInt, unsigned char);
- NARROWS_IF(ScopedEnumBackedByUInt, unsigned char, (sizeof(int) > sizeof(char)));
- NARROWS(ScopedEnumBackedByLong, unsigned char);
- NARROWS_IF(ScopedEnumBackedByULong, unsigned char, (sizeof(long) > sizeof(char)));
- NARROWS(ScopedEnumBackedByLongLong, unsigned char);
- NARROWS_IF(ScopedEnumBackedByULongLong, unsigned char, (sizeof(long long) > sizeof(char)));
-
- NARROWS_IF(ScopedEnumBackedByInt, short, (sizeof(int) > sizeof(short)));
- NARROWS(ScopedEnumBackedByUInt, short);
- NARROWS_IF(ScopedEnumBackedByLong, short, (sizeof(long) > sizeof(short)));
- NARROWS(ScopedEnumBackedByULong, short);
- NARROWS_IF(ScopedEnumBackedByLongLong, short, (sizeof(long long) > sizeof(short)));
- NARROWS(ScopedEnumBackedByULongLong, short);
-
- NARROWS(ScopedEnumBackedByInt, unsigned short);
- NARROWS_IF(ScopedEnumBackedByUInt, unsigned short, (sizeof(int) > sizeof(short)));
- NARROWS(ScopedEnumBackedByLong, unsigned short);
- NARROWS_IF(ScopedEnumBackedByULong, unsigned short, (sizeof(long) > sizeof(short)));
- NARROWS(ScopedEnumBackedByLongLong, unsigned short);
- NARROWS_IF(ScopedEnumBackedByULongLong, unsigned short, (sizeof(long long) > sizeof(short)));
-
- NARROWS_IF(ScopedEnumBackedByLong, int, (sizeof(long) > sizeof(int)));
- NARROWS(ScopedEnumBackedByULong, int);
- NARROWS_IF(ScopedEnumBackedByLongLong, int, (sizeof(long long) > sizeof(int)));
- NARROWS(ScopedEnumBackedByULongLong, int);
-
- NARROWS(ScopedEnumBackedByLong, unsigned int);
- NARROWS_IF(ScopedEnumBackedByULong, unsigned int, (sizeof(long) > sizeof(int)));
- NARROWS(ScopedEnumBackedByLongLong, unsigned int);
- NARROWS_IF(ScopedEnumBackedByULongLong, unsigned int, (sizeof(long long) > sizeof(int)));
-
- NARROWS_IF(ScopedEnumBackedByLongLong, long, (sizeof(long long) > sizeof(long)));
- NARROWS(ScopedEnumBackedByULongLong, long);
-
- NARROWS(ScopedEnumBackedByLongLong, unsigned long);
- NARROWS_IF(ScopedEnumBackedByULongLong, unsigned long, (sizeof(long long) > sizeof(long)));
-
- // different signedness of the underlying type
- NARROWS(SignedUnscopedEnum, unsigned char);
- NARROWS(SignedUnscopedEnum, unsigned short);
- NARROWS(SignedUnscopedEnum, unsigned int);
- NARROWS(SignedUnscopedEnum, unsigned long);
- NARROWS(SignedUnscopedEnum, unsigned long long);
-
- NARROWS(ScopedEnumBackedBySChar, unsigned char);
- NARROWS(ScopedEnumBackedBySChar, unsigned short);
- NARROWS(ScopedEnumBackedBySChar, unsigned int);
- NARROWS(ScopedEnumBackedBySChar, unsigned long);
- NARROWS(ScopedEnumBackedBySChar, unsigned long long);
-
- NARROWS(ScopedEnumBackedByShort, unsigned char);
- NARROWS(ScopedEnumBackedByShort, unsigned short);
- NARROWS(ScopedEnumBackedByShort, unsigned int);
- NARROWS(ScopedEnumBackedByShort, unsigned long);
- NARROWS(ScopedEnumBackedByShort, unsigned long long);
-
- NARROWS(ScopedEnumBackedByInt, unsigned char);
- NARROWS(ScopedEnumBackedByInt, unsigned short);
- NARROWS(ScopedEnumBackedByInt, unsigned int);
- NARROWS(ScopedEnumBackedByInt, unsigned long);
- NARROWS(ScopedEnumBackedByInt, unsigned long long);
-
- NARROWS(ScopedEnumBackedByLong, unsigned char);
- NARROWS(ScopedEnumBackedByLong, unsigned short);
- NARROWS(ScopedEnumBackedByLong, unsigned int);
- NARROWS(ScopedEnumBackedByLong, unsigned long);
- NARROWS(ScopedEnumBackedByLong, unsigned long long);
-
- NARROWS(ScopedEnumBackedByLongLong, unsigned char);
- NARROWS(ScopedEnumBackedByLongLong, unsigned short);
- NARROWS(ScopedEnumBackedByLongLong, unsigned int);
- NARROWS(ScopedEnumBackedByLongLong, unsigned long);
- NARROWS(ScopedEnumBackedByLongLong, unsigned long long);
-
- NARROWS(ScopedEnumBackedByUChar, signed char);
- FITS_IF(ScopedEnumBackedByUChar, short, (sizeof(char) < sizeof(short)));
- FITS_IF(ScopedEnumBackedByUChar, int, (sizeof(char) < sizeof(int)));
- FITS_IF(ScopedEnumBackedByUChar, long, (sizeof(char) < sizeof(long)));
- FITS_IF(ScopedEnumBackedByUChar, long long, (sizeof(char) < sizeof(long long)));
-
- NARROWS(ScopedEnumBackedByUShort, signed char);
- NARROWS(ScopedEnumBackedByUShort, short);
- FITS_IF(ScopedEnumBackedByUShort, int, (sizeof(short) < sizeof(int)));
- FITS_IF(ScopedEnumBackedByUShort, long, (sizeof(short) < sizeof(long)));
- FITS_IF(ScopedEnumBackedByUShort, long long, (sizeof(short) < sizeof(long long)));
-
- NARROWS(ScopedEnumBackedByUInt, signed char);
- NARROWS(ScopedEnumBackedByUInt, short);
- NARROWS(ScopedEnumBackedByUInt, int);
- FITS_IF(ScopedEnumBackedByUInt, long, (sizeof(ScopedEnumBackedByUInt) < sizeof(long)));
- FITS(ScopedEnumBackedByUInt, long long);
-
- NARROWS(ScopedEnumBackedByULong, signed char);
- NARROWS(ScopedEnumBackedByULong, short);
- NARROWS(ScopedEnumBackedByULong, int);
- NARROWS(ScopedEnumBackedByULong, long);
- FITS_IF(ScopedEnumBackedByULong, long long, (sizeof(ScopedEnumBackedByULong) < sizeof(long long)));
-
- NARROWS(ScopedEnumBackedByULongLong, signed char);
- NARROWS(ScopedEnumBackedByULongLong, short);
- NARROWS(ScopedEnumBackedByULongLong, int);
- NARROWS(ScopedEnumBackedByULongLong, long);
- NARROWS(ScopedEnumBackedByULongLong, long long);
-
// other types which should be always unaffected
FITS(void *, void *);
FITS(QString, QString);
- FITS(QString &, QString &);
- FITS(const QString &, const QString &);
-
FITS(QObject, QObject);
FITS(QObject *, QObject *);
FITS(const QObject *, const QObject *);
FITS(std::nullptr_t, std::nullptr_t);
- FITS(QString, QObject);
- FITS(QString, QVariant);
- FITS(QString, void *);
- FITS(QString, long long);
- FITS(bool, const QObject *&);
- FITS(int (*)(bool), void (QObject::*)());
+ // classes with conversion operators undergoing implicit conversions
+ struct ConvertingToDouble {
+ /* implicit */ operator double() const { return 42.0; }
+ };
+
+#if !defined(Q_CC_GHS)
+ NARROWS(ConvertingToDouble, char);
+ NARROWS(ConvertingToDouble, short);
+ NARROWS(ConvertingToDouble, int);
+ NARROWS(ConvertingToDouble, long);
+ NARROWS(ConvertingToDouble, long long);
+ NARROWS(ConvertingToDouble, float);
+#endif // Q_CC_GHS
+ FITS(ConvertingToDouble, double);
+ FITS(ConvertingToDouble, long double);
+
+
+ // GCC, GHS and clang don't implement this properly yet:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99625
+ // https://bugs.llvm.org/show_bug.cgi?id=49676
+#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) // at least since VS2017
+ struct ConstructibleFromInt {
+ /* implicit */ ConstructibleFromInt(int) {}
+ };
+
+ FITS(char, ConstructibleFromInt);
+ FITS(short, ConstructibleFromInt);
+ FITS(int, ConstructibleFromInt);
+ NARROWS(unsigned int, ConstructibleFromInt);
+ NARROWS_IF(long, ConstructibleFromInt, sizeof(long) > sizeof(int));
+ NARROWS_IF(long long, ConstructibleFromInt, sizeof(long long) > sizeof(int));
+ NARROWS(float, ConstructibleFromInt);
+ NARROWS(double, ConstructibleFromInt);
+#endif
+
+ // forward declared classes must work
+ class ForwardDeclared;
+ FITS(ForwardDeclared, ForwardDeclared);
-#undef IS_UNSCOPED_ENUM_SIGNED
+#if (defined(Q_CC_EXACTLY_GCC) && Q_CC_EXACTLY_GCC >= 1100) \
+ || (defined(Q_CC_CLANG) && Q_CC_CLANG >= 1100) \
+ || defined(Q_CC_MSVC) // at least since VS2017
+ {
+ // wg21.link/P1957
+ NARROWS(char*, bool);
+ NARROWS(void (QObject::*)(), bool);
+ }
+#endif
#undef NARROWS_IF
#undef FITS_IF
#undef NARROWS
#undef FITS
+
+#ifdef Q_CC_EXACTLY_GCC
+#undef Q_CC_EXACTLY_GCC
+#endif
}
void tst_QObject::nullReceiver()
@@ -7510,9 +7676,1158 @@ void tst_QObject::nullReceiver()
QVERIFY(!connect(&o, SIGNAL(destroyed()), nullObj, SLOT(deleteLater())));
}
+void tst_QObject::functorReferencesConnection()
+{
+ countedStructObjectsCount = 0;
+ QMetaObject::Connection globalCon;
+ {
+ GetSenderObject obj;
+ CountedStruct counted(&obj);
+ QCOMPARE(countedStructObjectsCount, 1);
+ auto c = QSharedPointer<QMetaObject::Connection>::create();
+ int slotCalled = 0;
+ *c = connect(&obj, &GetSenderObject::aSignal, &obj, [&slotCalled, c, counted] {
+ QObject::disconnect(*c);
+ slotCalled++;
+ });
+ globalCon = *c; // keep a handle to the connection somewhere;
+ QVERIFY(globalCon);
+ QCOMPARE(countedStructObjectsCount, 2);
+ obj.triggerSignal();
+ QCOMPARE(slotCalled, 1);
+ QCOMPARE(countedStructObjectsCount, 1);
+ QVERIFY(!globalCon);
+ obj.triggerSignal();
+ QCOMPARE(slotCalled, 1);
+ QCOMPARE(countedStructObjectsCount, 1);
+ }
+ QCOMPARE(countedStructObjectsCount, 0);
+
+ {
+ GetSenderObject obj;
+ CountedStruct counted(&obj);
+ QCOMPARE(countedStructObjectsCount, 1);
+ auto *rec = new QObject;
+ int slotCalled = 0;
+ globalCon = connect(&obj, &GetSenderObject::aSignal, rec, [&slotCalled, rec, counted] {
+ delete rec;
+ slotCalled++;
+ });
+ QCOMPARE(countedStructObjectsCount, 2);
+ obj.triggerSignal();
+ QCOMPARE(slotCalled, 1);
+ QCOMPARE(countedStructObjectsCount, 1);
+ QVERIFY(!globalCon);
+ obj.triggerSignal();
+ QCOMPARE(slotCalled, 1);
+ QCOMPARE(countedStructObjectsCount, 1);
+ }
+ QCOMPARE(countedStructObjectsCount, 0);
+ {
+ int slotCalled = 0;
+ QEventLoop eventLoop;
+ {
+ // Sender will be destroyed when the labda goes out of scope lambda, so it will exit the event loop
+ auto sender = QSharedPointer<GetSenderObject>::create();
+ connect(sender.data(), &QObject::destroyed, &eventLoop, &QEventLoop::quit, Qt::QueuedConnection);
+ globalCon = connect(sender.data(), &GetSenderObject::aSignal, this, [&slotCalled, sender, &globalCon, this] {
+ ++slotCalled;
+ // This signal will be connected, but should never be called as the sender will be destroyed before
+ auto c2 = connect(sender.data(), &GetSenderObject::aSignal, [] { QFAIL("Should not be called"); });
+ QVERIFY(c2);
+ QVERIFY(QObject::disconnect(sender.data(), nullptr, this, nullptr));
+ QVERIFY(!globalCon); // this connection has been disconnected
+ QVERIFY(c2); // sender should not have been deleted yet, only after the emission is done
+ });
+ QMetaObject::invokeMethod(sender.data(), &GetSenderObject::triggerSignal, Qt::QueuedConnection);
+ QMetaObject::invokeMethod(sender.data(), &GetSenderObject::triggerSignal, Qt::QueuedConnection);
+ QMetaObject::invokeMethod(sender.data(), &GetSenderObject::triggerSignal, Qt::QueuedConnection);
+ }
+ eventLoop.exec();
+ QCOMPARE(slotCalled, 1);
+ }
+
+ {
+ GetSenderObject obj;
+ CountedStruct counted(&obj);
+ QCOMPARE(countedStructObjectsCount, 1);
+ auto c1 = QSharedPointer<QMetaObject::Connection>::create();
+ auto c2 = QSharedPointer<QMetaObject::Connection>::create();
+ int slot1Called = 0;
+ int slot3Called = 0;
+ *c1 = connect(&obj, &GetSenderObject::aSignal, &obj, [&slot1Called, &slot3Called, &obj, c1, c2, counted] {
+ auto c3 = connect(&obj, &GetSenderObject::aSignal, [counted, &slot3Called] {
+ slot3Called++;
+ });
+ // top-level + the one in the 3 others lambdas
+ QCOMPARE(countedStructObjectsCount, 4);
+ QObject::disconnect(*c2);
+ slot1Called++;
+ });
+ connect(&obj, &GetSenderObject::aSignal, [] {}); // just a dummy signal to fill the connection list
+ *c2 = connect(&obj, &GetSenderObject::aSignal, [counted, c2] { QFAIL("should not be called"); });
+ QVERIFY(c1 && c2);
+ QCOMPARE(countedStructObjectsCount, 3); // top-level + c1 + c2
+ obj.triggerSignal();
+ QCOMPARE(slot1Called, 1);
+ QCOMPARE(slot3Called, 0);
+ QCOMPARE(countedStructObjectsCount, 3); // top-level + c1 + c3
+ QObject::disconnect(*c1);
+ QCOMPARE(countedStructObjectsCount, 2); // top-level + c3
+ obj.triggerSignal();
+ QCOMPARE(slot1Called, 1);
+ QCOMPARE(slot3Called, 1);
+ }
+ {
+ struct DestroyEmit {
+ Q_DISABLE_COPY(DestroyEmit);
+ explicit DestroyEmit(SenderObject *obj) : obj(obj) {}
+ SenderObject *obj;
+ ~DestroyEmit() {
+ obj->emitSignal1();
+ }
+ };
+ SenderObject obj;
+ int slot1Called = 0;
+ int slot2Called = 0;
+ int slot3Called = 0;
+ auto c1 = QSharedPointer<QMetaObject::Connection>::create();
+ auto de = QSharedPointer<DestroyEmit>::create(&obj);
+ *c1 = connect(&obj, &SenderObject::signal1, [&slot1Called, &slot3Called, de, c1, &obj] {
+ connect(&obj, &SenderObject::signal1, [&slot3Called] { slot3Called++; });
+ slot1Called++;
+ QObject::disconnect(*c1);
+ });
+ de.clear();
+ connect(&obj, &SenderObject::signal1, [&slot2Called] { slot2Called++; });
+ obj.emitSignal1();
+ QCOMPARE(slot1Called, 1);
+ QCOMPARE(slot2Called, 2); // because also called from ~DestroyEmit
+ QCOMPARE(slot3Called, 1);
+ }
+}
+
+void tst_QObject::disconnectDisconnects()
+{
+ // Test what happens if the destructor of an functor slot also disconnects more slot;
+
+ SenderObject s1;
+ QScopedPointer<QObject> receiver(new QObject);
+
+ auto s2 = QSharedPointer<SenderObject>::create();
+ QPointer<QObject> s2_tracker = s2.data();
+ int count = 0;
+ connect(&s1, &SenderObject::signal1, [&count] { count++; }); // α
+ connect(&s1, &SenderObject::signal1, receiver.data(), [s2] { QFAIL("!!"); }); // β
+ connect(s2.data(), &SenderObject::signal1, receiver.data(), [] { QFAIL("!!"); });
+ connect(&s1, &SenderObject::signal2, receiver.data(), [] { QFAIL("!!"); });
+ connect(s2.data(), &SenderObject::signal2, receiver.data(), [] { QFAIL("!!"); });
+ connect(&s1, &SenderObject::signal1, [&count] { count++; }); // γ
+ connect(&s1, &SenderObject::signal2, [&count] { count++; }); // δ
+ s2.clear();
+
+ QVERIFY(s2_tracker);
+ receiver
+ .reset(); // this will delete the receiver which must also delete s2 as β is disconnected
+ QVERIFY(!s2_tracker);
+ // test that the data structures are still in order
+ s1.emitSignal1();
+ QCOMPARE(count, 2); // α + γ
+ s1.emitSignal2();
+ QCOMPARE(count, 3); // + δ
+}
+
+class ReceiverDisconnecting : public QObject
+{
+ Q_OBJECT
+
+public:
+ SenderObject *sender;
+ int slotCalledCount = 0;
+
+public slots:
+ void aSlotByName()
+ {
+ ++slotCalledCount;
+ QVERIFY(!disconnect(sender, SIGNAL(signal1()), this, SLOT(aSlotByName())));
+ }
+
+ void aSlotByPtr()
+ {
+ ++slotCalledCount;
+ QVERIFY(!disconnect(sender, &SenderObject::signal1, this, &ReceiverDisconnecting::aSlotByPtr));
+ }
+};
+
+class DeleteThisReceiver : public QObject
+{
+ Q_OBJECT
+
+public:
+ static int counter;
+
+public slots:
+ void deleteThis()
+ {
+ ++counter;
+ delete this;
+ }
+};
+
+int DeleteThisReceiver::counter = 0;
+
+void tst_QObject::singleShotConnection()
+{
+ {
+ // Non single shot behavior: slot called every time the signal is emitted
+ SenderObject sender;
+ QMetaObject::Connection c = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot);
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 3);
+ }
+
+ {
+ // Non single shot behavior: multiple connections cause multiple invocations
+ SenderObject sender;
+ QMetaObject::Connection c = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot);
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ QMetaObject::Connection c2 = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot);
+ QVERIFY(c);
+ QVERIFY(c2);
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QVERIFY(c);
+ QVERIFY(c2);
+ QCOMPARE(sender.aPublicSlotCalled, 4);
+
+ sender.emitSignal1();
+ QVERIFY(c);
+ QVERIFY(c2);
+ QCOMPARE(sender.aPublicSlotCalled, 6);
+ }
+
+ {
+ // Single shot behavior: slot called only once
+ SenderObject sender;
+ QMetaObject::Connection c = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ }
+
+ {
+ // Same, without holding a Connection object
+ SenderObject sender;
+ bool ok = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(ok);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ }
+
+ {
+ // Single shot, disconnect before emitting
+ SenderObject sender;
+ QMetaObject::Connection c = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QVERIFY(QObject::disconnect(c));
+ QVERIFY(!c);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+ }
+
+ {
+ // Single shot together with another connection
+ SenderObject sender;
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot));
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 4);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 5);
+ }
+
+ {
+ // Two single shot, from the same signal, to the same slot
+ SenderObject sender;
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+ }
+
+ {
+ // Two single shot, from different signals, to the same slot
+ SenderObject sender;
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+ QVERIFY(connect(&sender, &SenderObject::signal2,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal2();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal2();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+ }
+
+ {
+ // Same signal, different connections
+ SenderObject sender;
+ ReceiverObject receiver1, receiver2;
+ receiver1.reset();
+ receiver2.reset();
+
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &receiver1, &ReceiverObject::slot1));
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &receiver2, &ReceiverObject::slot1,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+ QCOMPARE(receiver1.count_slot1, 0);
+ QCOMPARE(receiver2.count_slot1, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver1.count_slot1, 1);
+ QCOMPARE(receiver2.count_slot1, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver1.count_slot1, 2);
+ QCOMPARE(receiver2.count_slot1, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver1.count_slot1, 3);
+ QCOMPARE(receiver2.count_slot1, 1);
+
+ // Reestablish a single shot
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &receiver2, &ReceiverObject::slot1,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+ QCOMPARE(receiver1.count_slot1, 3);
+ QCOMPARE(receiver2.count_slot1, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver1.count_slot1, 4);
+ QCOMPARE(receiver2.count_slot1, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver1.count_slot1, 5);
+ QCOMPARE(receiver2.count_slot1, 2);
+ }
+
+ {
+ // Check that the slot is invoked with the connection already disconnected
+ SenderObject sender;
+ QMetaObject::Connection c;
+ auto breakSlot = [&]() {
+ QVERIFY(!c);
+ ++sender.aPublicSlotCalled;
+ };
+
+ c = connect(&sender, &SenderObject::signal1,
+ &sender, breakSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ QVERIFY(!c);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ QVERIFY(!c);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ QVERIFY(!c);
+ }
+
+ {
+ // Same
+ SenderObject sender;
+ ReceiverDisconnecting receiver;
+ receiver.sender = &sender;
+ bool ok = connect(&sender, SIGNAL(signal1()),
+ &receiver, SLOT(aSlotByName()),
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(ok);
+ QCOMPARE(receiver.slotCalledCount, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 1);
+
+ // reconnect
+ ok = connect(&sender, SIGNAL(signal1()),
+ &receiver, SLOT(aSlotByName()),
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(ok);
+ QCOMPARE(receiver.slotCalledCount, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 2);
+ }
+
+ {
+ // Same
+ SenderObject sender;
+ ReceiverDisconnecting receiver;
+ receiver.sender = &sender;
+ bool ok = connect(&sender, &SenderObject::signal1,
+ &receiver, &ReceiverDisconnecting::aSlotByPtr,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+
+ QVERIFY(ok);
+ QCOMPARE(receiver.slotCalledCount, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 1);
+
+ // reconnect
+ ok = connect(&sender, &SenderObject::signal1,
+ &receiver, &ReceiverDisconnecting::aSlotByPtr,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(ok);
+ QCOMPARE(receiver.slotCalledCount, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(receiver.slotCalledCount, 2);
+ }
+
+ {
+ // Reconnect from inside the slot
+ SenderObject sender;
+ std::function<void()> reconnectingSlot;
+ bool reconnect = false;
+ reconnectingSlot = [&]() {
+ ++sender.aPublicSlotCalled;
+ if (reconnect) {
+ QObject::connect(&sender, &SenderObject::signal1,
+ &sender, reconnectingSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ }
+ };
+
+ bool ok = connect(&sender, &SenderObject::signal1,
+ &sender, reconnectingSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(ok);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ reconnect = true;
+ ok = connect(&sender, &SenderObject::signal1,
+ &sender, reconnectingSlot,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));
+ QVERIFY(ok);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 2);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 3);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 4);
+
+ reconnect = false;
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 5);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 5);
+ }
+
+ {
+ // Delete the receiver from inside the slot
+ SenderObject sender;
+ QPointer<DeleteThisReceiver> p = new DeleteThisReceiver;
+ DeleteThisReceiver::counter = 0;
+
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ p.get(), &DeleteThisReceiver::deleteThis,
+ static_cast<Qt::ConnectionType>(Qt::SingleShotConnection)));
+
+ QVERIFY(p);
+ QCOMPARE(DeleteThisReceiver::counter, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(DeleteThisReceiver::counter, 1);
+ QVERIFY(!p);
+
+ sender.emitSignal1();
+ QCOMPARE(DeleteThisReceiver::counter, 1);
+ QVERIFY(!p);
+ }
+
+ {
+ // Queued, non single shot
+ SenderObject sender;
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::QueuedConnection)));
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QTRY_COMPARE(sender.aPublicSlotCalled, 3);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 3);
+
+ QTRY_COMPARE(sender.aPublicSlotCalled, 4);
+ }
+
+ {
+ // Queued, single shot
+ SenderObject sender;
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection)));
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QTRY_COMPARE(sender.aPublicSlotCalled, 1);
+ QTest::qWait(0);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ }
+
+ {
+ // Queued, single shot, checking the connection handle
+ SenderObject sender;
+ QMetaObject::Connection c = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QTRY_COMPARE(sender.aPublicSlotCalled, 1);
+ QVERIFY(!c);
+ QTest::qWait(0);
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 1);
+ }
+
+ {
+ // Queued, single shot, disconnect before emitting
+ SenderObject sender;
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection)));
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QVERIFY(QObject::disconnect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot));
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QTest::qWait(0);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+ }
+
+ {
+ // Queued, single shot, disconnect before emitting by using the connection handle
+ SenderObject sender;
+ QMetaObject::Connection c = connect(&sender, &SenderObject::signal1,
+ &sender, &SenderObject::aPublicSlot,
+ static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
+ QVERIFY(c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QVERIFY(QObject::disconnect(c));
+ QVERIFY(!c);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ sender.emitSignal1();
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+
+ QTest::qWait(0);
+ QVERIFY(!c);
+ QCOMPARE(sender.aPublicSlotCalled, 0);
+ }
+
+ {
+ // Queued, single shot, delete the receiver from inside the slot
+ SenderObject sender;
+ QPointer<DeleteThisReceiver> p = new DeleteThisReceiver;
+ DeleteThisReceiver::counter = 0;
+
+ QVERIFY(connect(&sender, &SenderObject::signal1,
+ p.get(), &DeleteThisReceiver::deleteThis,
+ static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection)));
+ QCOMPARE(DeleteThisReceiver::counter, 0);
+
+ sender.emitSignal1();
+ QVERIFY(p);
+ QCOMPARE(DeleteThisReceiver::counter, 0);
+
+ sender.emitSignal1();
+ QVERIFY(p);
+ QCOMPARE(DeleteThisReceiver::counter, 0);
+
+ sender.emitSignal1();
+ QVERIFY(p);
+ QCOMPARE(DeleteThisReceiver::counter, 0);
+
+ QTRY_COMPARE(DeleteThisReceiver::counter, 1);
+ QVERIFY(!p);
+ QTest::qWait(0);
+ QCOMPARE(DeleteThisReceiver::counter, 1);
+ QVERIFY(!p);
+ }
+}
+
+void tst_QObject::objectNameBinding()
+{
+ QObject obj;
+ QTestPrivate::testReadWritePropertyBasics<QObject, QString>(obj, "test1", "test2",
+ "objectName");
+}
+
+namespace EmitToDestroyedClass {
+static int assertionCallCount = 0;
+static int wouldHaveAssertedCount = 0;
+struct WouldAssert : std::exception {};
+class Base : public QObject
+{
+ Q_OBJECT
+public:
+ ~Base()
+ {
+ try {
+ emit theSignal();
+ } catch (const WouldAssert &) {
+ ++wouldHaveAssertedCount;
+ }
+ }
+
+signals:
+ void theSignal();
+};
+
+class Derived : public Base
+{
+ Q_OBJECT
+public:
+ ~Derived() { }
+
+public slots:
+ void doNothing() {}
+};
+} // namespace EmitToDestroyedClass
+
+QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+template<> void assertObjectType<EmitToDestroyedClass::Derived>(QObject *o)
+{
+ // override the assertion so we don't assert and so something does happen
+ // when assertions are disabled. By throwing, we also prevent the UB from
+ // happening.
+ using namespace EmitToDestroyedClass;
+ ++assertionCallCount;
+ if (!qobject_cast<Derived *>(o))
+ throw WouldAssert();
+}
+}
+QT_END_NAMESPACE
+
+void tst_QObject::emitToDestroyedClass()
+{
+ using namespace EmitToDestroyedClass;
+ std::unique_ptr ptr = std::make_unique<Derived>();
+ QObject::connect(ptr.get(), &Base::theSignal, ptr.get(), &Derived::doNothing);
+ QCOMPARE(assertionCallCount, 0);
+ QCOMPARE(wouldHaveAssertedCount, 0);
+
+ // confirm our replacement function did get called
+ emit ptr->theSignal();
+ QCOMPARE(assertionCallCount, 1);
+ QCOMPARE(wouldHaveAssertedCount, 0);
+
+ ptr.reset();
+ QCOMPARE(assertionCallCount, 2);
+ QCOMPARE(wouldHaveAssertedCount, 1);
+}
+
// Test for QtPrivate::HasQ_OBJECT_Macro
-Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
-Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+static_assert(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value);
+static_assert(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value);
+
+Q_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)
+Q_DECLARE_SMART_POINTER_METATYPE(std::unique_ptr)
+
+
+// QTBUG-103741: OK to use smart pointers to const QObject in signals/slots
+class SenderWithSharedPointerConstQObject : public QObject
+{
+ Q_OBJECT
+
+signals:
+ void aSignal1(const QSharedPointer<const QObject> &);
+ void aSignal2(const QWeakPointer<const QObject> &);
+ void aSignal3(const QPointer<const QObject> &);
+ void aSignal4(const std::shared_ptr<const QObject> &);
+ void aSignal5(const std::unique_ptr<const QObject> &);
+};
+
+#ifdef QT_BUILD_INTERNAL
+/*
+ Since QObjectPrivate stores the declarativeData pointer in a union with the pointer
+ to the currently destroyed child, calls to the QtDeclarative handlers need to be
+ correctly guarded. QTBUG-105286
+*/
+namespace QtDeclarative {
+static QAbstractDeclarativeData *theData;
+
+static void destroyed(QAbstractDeclarativeData *data, QObject *)
+{
+ QCOMPARE(data, theData);
+}
+static void signalEmitted(QAbstractDeclarativeData *data, QObject *, int, void **)
+{
+ QCOMPARE(data, theData);
+}
+// we can't use QCOMPARE in the next two functions, as they don't return void
+static int receivers(QAbstractDeclarativeData *data, const QObject *, int)
+{
+ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
+ return 0;
+}
+static bool isSignalConnected(QAbstractDeclarativeData *data, const QObject *, int)
+{
+ QTest::qCompare(data, theData, "data", "theData", __FILE__, __LINE__);
+ return true;
+}
+
+class Object : public QObject
+{
+ Q_OBJECT
+public:
+ using QObject::QObject;
+ ~Object()
+ {
+ if (Object *p = static_cast<Object *>(parent()))
+ p->emitSignal();
+ }
+
+ void emitSignal()
+ {
+ emit theSignal();
+ }
+
+signals:
+ void theSignal();
+};
+
+}
+#endif
+
+void tst_QObject::declarativeData()
+{
+#ifdef QT_BUILD_INTERNAL
+ QScopedValueRollback destroyed(QAbstractDeclarativeData::destroyed,
+ QtDeclarative::destroyed);
+ QScopedValueRollback signalEmitted(QAbstractDeclarativeData::signalEmitted,
+ QtDeclarative::signalEmitted);
+ QScopedValueRollback receivers(QAbstractDeclarativeData::receivers,
+ QtDeclarative::receivers);
+ QScopedValueRollback isSignalConnected(QAbstractDeclarativeData::isSignalConnected,
+ QtDeclarative::isSignalConnected);
+
+ QtDeclarative::Object p;
+ QObjectPrivate *priv = QObjectPrivate::get(&p);
+ priv->declarativeData = QtDeclarative::theData = new QAbstractDeclarativeData;
+
+ connect(&p, &QtDeclarative::Object::theSignal, &p, []{
+ });
+
+ QtDeclarative::Object *child = new QtDeclarative::Object;
+ child->setParent(&p);
+#endif
+}
+
+/*
+ Compile-time test for the helpers in qobjectdefs_impl.h.
+*/
+class AsyncCaller : public QObject
+{
+ Q_OBJECT
+public:
+ ~AsyncCaller()
+ {
+ if (slotObject)
+ slotObject->destroyIfLastRef();
+ }
+ void callback0() {}
+ void callback1(const QString &) {}
+ void callbackInt(int) {}
+ int returnInt() const { return 0; }
+
+ static int staticCallback0() { return 0; }
+ static void staticCallback1(const QString &) {}
+
+ using Prototype0 = int(*)();
+ using Prototype1 = void(*)(QString);
+
+ template<typename Functor>
+ bool callMe0(const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *, Functor &&func)
+ {
+ if (slotObject) {
+ slotObject->destroyIfLastRef();
+ slotObject = nullptr;
+ }
+ QtPrivate::AssertCompatibleFunctions<Prototype0, Functor>();
+ slotObject = QtPrivate::makeCallableObject<Prototype0>(std::forward<Functor>(func));
+ return true;
+ }
+
+ template<typename Functor>
+ bool callMe0(Functor &&func)
+ {
+ return callMe0(nullptr, std::forward<Functor>(func));
+ }
+
+ template<typename Functor>
+ bool callMe1(const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *, Functor &&func)
+ {
+ if (slotObject) {
+ slotObject->destroyIfLastRef();
+ slotObject = nullptr;
+ }
+ QtPrivate::AssertCompatibleFunctions<Prototype1, Functor>();
+ slotObject = QtPrivate::makeCallableObject<Prototype1>(std::forward<Functor>(func));
+ return true;
+ }
+
+ template<typename Functor>
+ bool callMe1(Functor &&func)
+ {
+ return callMe1(nullptr, std::forward<Functor>(func));
+ }
+
+ QtPrivate::QSlotObjectBase *slotObject = nullptr;
+};
+
+static void freeFunction0() {}
+static void freeFunction1(QString) {}
+static void freeFunctionVariant(QVariant) {}
+
+template<typename Prototype, typename Functor>
+inline constexpr bool compiles(Functor &&) {
+ return QtPrivate::AreFunctionsCompatible<Prototype, Functor>::value;
+}
+
+void tst_QObject::asyncCallbackHelper()
+{
+ int result = 0;
+ QString arg1 = "Parameter";
+ void *argv[] = { &result, &arg1 };
+
+ auto lambda0 = []{};
+ auto lambda1 = [](const QString &) {};
+ auto lambda2 = [](const QString &, int) {};
+ const auto constLambda = [](const QString &) {};
+ auto moveOnlyLambda = [u = std::unique_ptr<int>()]{};
+ auto moveOnlyLambda1 = [u = std::unique_ptr<int>()](const QString &){};
+
+ SlotFunctor functor0;
+ SlotFunctorString functor1;
+
+ // no parameters provided or needed
+ static_assert(compiles<AsyncCaller::Prototype0>(&AsyncCaller::callback0));
+ static_assert(compiles<AsyncCaller::Prototype0>(&AsyncCaller::staticCallback0));
+ static_assert(compiles<AsyncCaller::Prototype0>(lambda0));
+ static_assert(compiles<AsyncCaller::Prototype0>(std::move(moveOnlyLambda)));
+ static_assert(compiles<AsyncCaller::Prototype0>(freeFunction0));
+ static_assert(compiles<AsyncCaller::Prototype0>(functor0));
+
+ // more parameters than needed
+ static_assert(compiles<AsyncCaller::Prototype1>(&AsyncCaller::callback0));
+ static_assert(compiles<AsyncCaller::Prototype1>(&AsyncCaller::staticCallback0));
+ static_assert(compiles<AsyncCaller::Prototype1>(lambda0));
+ static_assert(compiles<AsyncCaller::Prototype1>(freeFunction0));
+ static_assert(compiles<AsyncCaller::Prototype1>(functor0));
+
+ // matching parameter
+ static_assert(compiles<AsyncCaller::Prototype1>(&AsyncCaller::callback1));
+ static_assert(compiles<AsyncCaller::Prototype1>(&AsyncCaller::staticCallback1));
+ static_assert(compiles<AsyncCaller::Prototype1>(lambda1));
+ static_assert(compiles<AsyncCaller::Prototype1>(std::move(moveOnlyLambda1)));
+ static_assert(compiles<AsyncCaller::Prototype1>(constLambda));
+ static_assert(compiles<AsyncCaller::Prototype1>(freeFunction1));
+ static_assert(compiles<AsyncCaller::Prototype1>(functor1));
+
+ // not enough parameters
+ static_assert(!compiles<AsyncCaller::Prototype0>(&AsyncCaller::callback1));
+ static_assert(!compiles<AsyncCaller::Prototype0>(&AsyncCaller::staticCallback1));
+ static_assert(!compiles<AsyncCaller::Prototype0>(lambda1));
+ static_assert(!compiles<AsyncCaller::Prototype0>(constLambda));
+ static_assert(!compiles<AsyncCaller::Prototype0>(lambda2));
+ static_assert(!compiles<AsyncCaller::Prototype0>(freeFunction1));
+ static_assert(!compiles<AsyncCaller::Prototype0>(functor1));
+
+ // wrong parameter type
+ static_assert(!compiles<AsyncCaller::Prototype1>(&AsyncCaller::callbackInt));
+
+ // old-style slot name
+ static_assert(!compiles<AsyncCaller::Prototype0>("callback1"));
+
+ // slot with return value is ok, we just don't pass
+ // the return value through to anything.
+ static_assert(compiles<AsyncCaller::Prototype0>(&AsyncCaller::returnInt));
+
+ static_assert(compiles<AsyncCaller::Prototype1>(freeFunctionVariant));
+
+ std::function<int()> stdFunction0(&AsyncCaller::staticCallback0);
+ std::function<void(QString)> stdFunction1(&AsyncCaller::staticCallback1);
+ static_assert(compiles<AsyncCaller::Prototype0>(stdFunction0));
+ static_assert(compiles<AsyncCaller::Prototype1>(stdFunction1));
+
+ AsyncCaller caller;
+ // with context
+ QVERIFY(caller.callMe0(&caller, &AsyncCaller::callback0));
+ QVERIFY(caller.callMe0(&caller, &AsyncCaller::returnInt));
+ QVERIFY(caller.callMe0(&caller, &AsyncCaller::staticCallback0));
+ QVERIFY(caller.callMe0(&caller, lambda0));
+ QVERIFY(caller.callMe0(&caller, freeFunction0));
+ QVERIFY(caller.callMe0(&caller, std::move(moveOnlyLambda)));
+ QVERIFY(caller.callMe0(&caller, stdFunction0));
+
+ QVERIFY(caller.callMe1(&caller, &AsyncCaller::callback1));
+ QVERIFY(caller.callMe1(&caller, &AsyncCaller::staticCallback1));
+ QVERIFY(caller.callMe1(&caller, lambda1));
+ QVERIFY(caller.callMe1(&caller, freeFunction1));
+ QVERIFY(caller.callMe1(&caller, constLambda));
+ QVERIFY(caller.callMe1(&caller, stdFunction1));
+
+ // without context
+ QVERIFY(caller.callMe0(&AsyncCaller::staticCallback0));
+ QVERIFY(caller.callMe0(lambda0));
+ QVERIFY(caller.callMe0(freeFunction0));
+ QVERIFY(caller.callMe0(stdFunction0));
+
+ QVERIFY(caller.callMe1(&AsyncCaller::staticCallback1));
+ QVERIFY(caller.callMe1(lambda1));
+ QVERIFY(caller.callMe1(constLambda));
+ QVERIFY(caller.callMe1(std::move(moveOnlyLambda1)));
+ QVERIFY(caller.callMe1(freeFunction1));
+ QVERIFY(caller.callMe1(stdFunction1));
+
+ static const char *expectedPayload = "Hello World!";
+ {
+ struct MoveOnlyFunctor {
+ MoveOnlyFunctor() = default;
+ MoveOnlyFunctor(MoveOnlyFunctor &&) = default;
+ MoveOnlyFunctor(const MoveOnlyFunctor &) = delete;
+ ~MoveOnlyFunctor() = default;
+
+ int operator()() const {
+ qDebug().noquote() << payload;
+ return int(payload.length());
+ }
+ QString payload = expectedPayload;
+ } moveOnlyFunctor;
+ QVERIFY(caller.callMe0(std::move(moveOnlyFunctor)));
+ }
+ QTest::ignoreMessage(QtDebugMsg, expectedPayload);
+ caller.slotObject->call(nullptr, argv);
+ QCOMPARE(result, QLatin1String(expectedPayload).length());
+
+ // mutable lambda; same behavior as mutableFunctor - we copy the functor
+ // in the QCallableObject, so the original is not modified
+ int status = 0;
+ auto mutableLambda1 = [&status, calls = 0]() mutable { status = ++calls; };
+
+ mutableLambda1();
+ QCOMPARE(status, 1);
+ QVERIFY(caller.callMe0(mutableLambda1)); // this copies the lambda with count == 1
+ caller.slotObject->call(nullptr, argv); // this doesn't change mutableLambda1, but the copy
+ QCOMPARE(status, 2);
+ mutableLambda1();
+ QCOMPARE(status, 2); // and we are still at two
+
+ auto mutableLambda2 = [calls = 0]() mutable { return ++calls; };
+ QCOMPARE(mutableLambda2(), 1);
+ QVERIFY(caller.callMe0(mutableLambda2)); // this copies the lambda
+ caller.slotObject->call(nullptr, argv); // this call doesn't change mutableLambda2
+ QCOMPARE(mutableLambda2(), 2); // so we are still at 2
+
+ {
+ int called = -1;
+ struct MutableFunctor {
+ void operator()() { called = 0; }
+ int &called;
+ };
+ struct ConstFunctor
+ {
+ void operator()() const { called = 1; }
+ int &called;
+ };
+
+ MutableFunctor mf{called};
+ QMetaObject::invokeMethod(this, mf);
+ QCOMPARE(called, 0);
+ ConstFunctor cf{called};
+ QMetaObject::invokeMethod(this, cf);
+ QCOMPARE(called, 1);
+ QMetaObject::invokeMethod(this, [&called, u = std::unique_ptr<int>()]{ called = 2; });
+ QCOMPARE(called, 2);
+ QMetaObject::invokeMethod(this, [&called, count = 0]() mutable {
+ if (!count)
+ called = 3;
+ ++count;
+ });
+ QCOMPARE(called, 3);
+ }
+}
QTEST_MAIN(tst_QObject)
#include "tst_qobject.moc"
diff --git a/tests/auto/corelib/kernel/qpermission/.gitignore b/tests/auto/corelib/kernel/qpermission/.gitignore
new file mode 100644
index 0000000000..56a6bf0795
--- /dev/null
+++ b/tests/auto/corelib/kernel/qpermission/.gitignore
@@ -0,0 +1 @@
+tst_qpermission
diff --git a/tests/auto/corelib/kernel/qpermission/CMakeLists.txt b/tests/auto/corelib/kernel/qpermission/CMakeLists.txt
new file mode 100644
index 0000000000..1af0331186
--- /dev/null
+++ b/tests/auto/corelib/kernel/qpermission/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpermission LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if (NOT QT_FEATURE_permissions)
+ return()
+endif()
+
+qt_internal_add_test(tst_qpermission
+ SOURCES
+ tst_qpermission.cpp
+ LIBRARIES
+ Qt::Core
+)
diff --git a/tests/auto/corelib/kernel/qpermission/tst_qpermission.cpp b/tests/auto/corelib/kernel/qpermission/tst_qpermission.cpp
new file mode 100644
index 0000000000..dbf1d2dd84
--- /dev/null
+++ b/tests/auto/corelib/kernel/qpermission/tst_qpermission.cpp
@@ -0,0 +1,284 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QPermission>
+
+#include <QTest>
+
+struct DummyPermission // a minimal QPermission-compatible type
+{
+ using QtPermissionHelper = void;
+ int state = 0;
+};
+Q_DECLARE_METATYPE(DummyPermission)
+
+class tst_QPermission : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void converting_Dummy() const { return converting_impl<DummyPermission>(); }
+ void converting_Location() const { return converting_impl<QLocationPermission>(); }
+ void converting_Calendar() const { return converting_impl<QCalendarPermission>(); }
+ void converting_Contacts() const { return converting_impl<QContactsPermission>(); }
+ void converting_Camera() const { return converting_impl<QCameraPermission>(); }
+ void converting_Microphone() const { return converting_impl<QMicrophonePermission>(); }
+ void converting_Bluetooth() const { return converting_impl<QBluetoothPermission>(); }
+
+ void conversionMaintainsState() const;
+
+ void functorWithoutContext();
+ void functorWithContextInThread();
+ void receiverInThread();
+ void destroyedContextObject();
+private:
+ template <typename T>
+ void converting_impl() const;
+};
+
+template <typename T>
+void tst_QPermission::converting_impl() const
+{
+ T concrete;
+ const T cconcrete = concrete;
+ const auto metaType = QMetaType::fromType<T>();
+
+ // construction is implicit:
+ // from rvalue:
+ {
+ QPermission p = T();
+ QCOMPARE_EQ(p.type(), metaType);
+ }
+ // from mutable lvalue:
+ {
+ QPermission p = concrete;
+ QCOMPARE_EQ(p.type(), metaType);
+ }
+ // from const lvalue:
+ {
+ QPermission p = cconcrete;
+ QCOMPARE_EQ(p.type(), metaType);
+ }
+
+ // value<>() compiles:
+ {
+ const QPermission p = concrete;
+ auto v = p.value<T>();
+ static_assert(std::is_same_v<decltype(v), std::optional<T>>);
+ QCOMPARE_NE(v, std::nullopt);
+ }
+}
+
+void tst_QPermission::conversionMaintainsState() const
+{
+ DummyPermission dummy{42}, dummy_default;
+ QCOMPARE_NE(dummy.state, dummy_default.state);
+
+ QLocationPermission loc, loc_default;
+ QCOMPARE_EQ(loc_default.accuracy(), QLocationPermission::Accuracy::Approximate);
+ QCOMPARE_EQ(loc_default.availability(), QLocationPermission::Availability::WhenInUse);
+
+ loc.setAccuracy(QLocationPermission::Accuracy::Precise);
+ loc.setAvailability(QLocationPermission::Availability::Always);
+
+ QCOMPARE_EQ(loc.accuracy(), QLocationPermission::Accuracy::Precise);
+ QCOMPARE_EQ(loc.availability(), QLocationPermission::Availability::Always);
+
+ QCalendarPermission cal, cal_default;
+ QCOMPARE_EQ(cal_default.accessMode(), QCalendarPermission::AccessMode::ReadOnly);
+
+ cal.setAccessMode(QCalendarPermission::AccessMode::ReadWrite);
+
+ QCOMPARE_EQ(cal.accessMode(), QCalendarPermission::AccessMode::ReadWrite);
+
+ QContactsPermission con, con_default;
+ QCOMPARE_EQ(con_default.accessMode(), QContactsPermission::AccessMode::ReadOnly);
+
+ con.setAccessMode(QContactsPermission::AccessMode::ReadWrite);
+
+ QCOMPARE_EQ(con.accessMode(), QContactsPermission::AccessMode::ReadWrite);
+
+ //
+ // QCameraPermission, QMicrophonePermission, QBluetoothPermission don't have
+ // state at the time of writing
+ //
+
+ QPermission p; // maintain state between the blocks below to test reset behavior
+
+ {
+ p = dummy;
+ auto v = p.value<DummyPermission>();
+ QCOMPARE_NE(v, std::nullopt);
+ auto &r = *v;
+ QCOMPARE_EQ(r.state, dummy.state);
+ // check mismatched returns nullopt:
+ QCOMPARE_EQ(p.value<QCalendarPermission>(), std::nullopt);
+ }
+
+ {
+ p = loc;
+ auto v = p.value<QLocationPermission>();
+ QCOMPARE_NE(v, std::nullopt);
+ auto &r = *v;
+ QCOMPARE_EQ(r.accuracy(), loc.accuracy());
+ QCOMPARE_EQ(r.availability(), loc.availability());
+ // check mismatched returns nullopt:
+ QCOMPARE_EQ(p.value<DummyPermission>(), std::nullopt);
+ }
+
+ {
+ p = con;
+ auto v = p.value<QContactsPermission>();
+ QCOMPARE_NE(v, std::nullopt);
+ auto &r = *v;
+ QCOMPARE_EQ(r.accessMode(), con.accessMode());
+ // check mismatched returns nullopt:
+ QCOMPARE_EQ(p.value<QLocationPermission>(), std::nullopt);
+ }
+
+ {
+ p = cal;
+ auto v = p.value<QCalendarPermission>();
+ QCOMPARE_NE(v, std::nullopt);
+ auto &r = *v;
+ QCOMPARE_EQ(r.accessMode(), cal.accessMode());
+ // check mismatched returns nullopt:
+ QCOMPARE_EQ(p.value<QContactsPermission>(), std::nullopt);
+ }
+}
+
+template <typename Func,
+ typename T = std::void_t<decltype(qApp->requestPermission(std::declval<DummyPermission>(),
+ std::declval<Func>()))>
+ >
+void wrapRequestPermission(const QPermission &p, Func &&f)
+{
+ qApp->requestPermission(p, std::forward<Func>(f));
+}
+
+template <typename Functor>
+using CompatibleTest = decltype(wrapRequestPermission(std::declval<QPermission>(), std::declval<Functor>()));
+
+
+// Compile test for context-less functor overloads
+void tst_QPermission::functorWithoutContext()
+{
+ int argc = 0;
+ char *argv = nullptr;
+ QCoreApplication app(argc, &argv);
+
+ DummyPermission dummy;
+#ifdef Q_OS_DARWIN
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*Could not find permission plugin for DummyPermission.*"));
+#endif
+
+ qApp->requestPermission(dummy, [](const QPermission &permission){
+ QVERIFY(permission.value<DummyPermission>());
+ });
+ wrapRequestPermission(dummy, [](const QPermission &permission){
+ QVERIFY(permission.value<DummyPermission>());
+ });
+
+ auto compatible = [](const QPermission &) {};
+ using Compatible = decltype(compatible);
+ auto incompatible = [](const QString &) {};
+ using Incompatible = decltype(incompatible);
+
+ static_assert(qxp::is_detected_v<CompatibleTest, Compatible>);
+ static_assert(!qxp::is_detected_v<CompatibleTest, Incompatible>);
+}
+
+void tst_QPermission::functorWithContextInThread()
+{
+ int argc = 0;
+ char *argv = nullptr;
+ QCoreApplication app(argc, &argv);
+ QThread::currentThread()->setObjectName("main thread");
+ QThread receiverThread;
+ receiverThread.setObjectName("receiverThread");
+ QObject receiver;
+ receiver.moveToThread(&receiverThread);
+ receiverThread.start();
+ auto guard = qScopeGuard([&receiverThread]{
+ receiverThread.quit();
+ QVERIFY(receiverThread.wait(1000));
+ });
+
+ DummyPermission dummy;
+#ifdef Q_OS_DARWIN
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*Could not find permission plugin for DummyPermission.*"));
+#endif
+ QThread *permissionReceiverThread = nullptr;
+ qApp->requestPermission(dummy, &receiver, [&](const QPermission &permission){
+ auto dummy = permission.value<DummyPermission>();
+ QVERIFY(dummy);
+ permissionReceiverThread = QThread::currentThread();
+ });
+ QTRY_COMPARE(permissionReceiverThread, &receiverThread);
+}
+
+void tst_QPermission::receiverInThread()
+{
+ int argc = 0;
+ char *argv = nullptr;
+ QCoreApplication app(argc, &argv);
+ QThread::currentThread()->setObjectName("main thread");
+ QThread receiverThread;
+ receiverThread.setObjectName("receiverThread");
+ class Receiver : public QObject
+ {
+ public:
+ using QObject::QObject;
+ void handlePermission(const QPermission &permission)
+ {
+ auto dummy = permission.value<DummyPermission>();
+ QVERIFY(dummy);
+ permissionReceiverThread = QThread::currentThread();
+ }
+
+ QThread *permissionReceiverThread = nullptr;
+ } receiver;
+ receiver.moveToThread(&receiverThread);
+ receiverThread.start();
+ auto guard = qScopeGuard([&receiverThread]{
+ receiverThread.quit();
+ QVERIFY(receiverThread.wait(1000));
+ });
+
+ DummyPermission dummy;
+#ifdef Q_OS_DARWIN
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*Could not find permission plugin for DummyPermission.*"));
+#endif
+
+ qApp->requestPermission(dummy, &receiver, &Receiver::handlePermission);
+ QTRY_COMPARE(receiver.permissionReceiverThread, &receiverThread);
+
+ // compile tests: none of these work and the error output isn't horrible
+ // qApp->requestPermission(dummy, &receiver, "&tst_QPermission::receiverInThread");
+ // qApp->requestPermission(dummy, &receiver, &tst_QPermission::receiverInThread);
+ // qApp->requestPermission(dummy, &receiver, &QObject::destroyed);
+}
+
+void tst_QPermission::destroyedContextObject()
+{
+ int argc = 0;
+ char *argv = nullptr;
+ QCoreApplication app(argc, &argv);
+
+ QObject *context = new QObject;
+
+ DummyPermission dummy;
+#ifdef Q_OS_DARWIN
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*Could not find permission plugin for DummyPermission.*"));
+#endif
+ bool permissionReceived = false;
+ qApp->requestPermission(dummy, context, [&]{
+ permissionReceived = true;
+ });
+ QVERIFY2(!permissionReceived, "Permission received synchronously");
+ delete context;
+ QTest::qWait(100);
+ QVERIFY(!permissionReceived);
+}
+
+QTEST_APPLESS_MAIN(tst_QPermission)
+#include "tst_qpermission.moc"
diff --git a/tests/auto/corelib/kernel/qpointer/CMakeLists.txt b/tests/auto/corelib/kernel/qpointer/CMakeLists.txt
new file mode 100644
index 0000000000..b1570b8cef
--- /dev/null
+++ b/tests/auto/corelib/kernel/qpointer/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpointer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpointer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if (NOT QT_FEATURE_thread)
+ return()
+endif()
+
+qt_internal_add_test(tst_qpointer
+ SOURCES
+ tst_qpointer.cpp
+ LIBRARIES
+ Qt::Gui
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qpointer CONDITION TARGET Qt::Widgets
+ LIBRARIES
+ Qt::Widgets
+)
diff --git a/tests/auto/corelib/kernel/qpointer/qpointer.pro b/tests/auto/corelib/kernel/qpointer/qpointer.pro
deleted file mode 100644
index 02765efdbd..0000000000
--- a/tests/auto/corelib/kernel/qpointer/qpointer.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qpointer
-QT = core testlib
-qtHaveModule(widgets): QT += widgets
-SOURCES = tst_qpointer.cpp
diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp
index 914f9e2b9b..7365fee819 100644
--- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp
+++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QRunnable>
+#include <QThreadPool>
#include <QPointer>
#ifndef QT_NO_WIDGETS
@@ -42,6 +19,8 @@ public:
private slots:
void constructors();
+ void ctad();
+ void conversion();
void destructor();
void assignment_operators();
void equality_operators();
@@ -57,14 +36,114 @@ private slots:
void constQPointer();
};
+// check that nullptr QPointer construction is Q_CONSTINIT:
+[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file1;
+[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file2 = {};
+[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file3 = nullptr;
+[[maybe_unused]] Q_CONSTINIT static QPointer<QFile> s_file4 = 0; // legacy nullptr
+
void tst_QPointer::constructors()
{
+ struct Derived : QObject {};
+ Derived derived;
+
QPointer<QObject> p1;
QPointer<QObject> p2(this);
QPointer<QObject> p3(p2);
+ QPointer<QObject> p4 = &derived;
QCOMPARE(p1, QPointer<QObject>(0));
QCOMPARE(p2, QPointer<QObject>(this));
QCOMPARE(p3, QPointer<QObject>(this));
+ QCOMPARE(p4, &derived);
+}
+
+void tst_QPointer::ctad()
+{
+
+ {
+ QObject o;
+ QPointer po = &o;
+ static_assert(std::is_same_v<decltype(po), QPointer<QObject>>);
+ QPointer poc = po;
+ static_assert(std::is_same_v<decltype(poc), QPointer<QObject>>);
+ QPointer pom = std::move(po);
+ static_assert(std::is_same_v<decltype(pom), QPointer<QObject>>);
+ }
+ {
+ const QObject co;
+ QPointer pco = &co;
+ static_assert(std::is_same_v<decltype(pco), QPointer<const QObject>>);
+ QPointer pcoc = pco;
+ static_assert(std::is_same_v<decltype(pcoc), QPointer<const QObject>>);
+ QPointer pcom = std::move(pco);
+ static_assert(std::is_same_v<decltype(pcom), QPointer<const QObject>>);
+ }
+ {
+ QFile f;
+ QPointer pf = &f;
+ static_assert(std::is_same_v<decltype(pf), QPointer<QFile>>);
+ QPointer pfc = pf;
+ static_assert(std::is_same_v<decltype(pfc), QPointer<QFile>>);
+ QPointer pfm = std::move(pf);
+ static_assert(std::is_same_v<decltype(pfm), QPointer<QFile>>);
+ }
+ {
+ const QFile cf;
+ QPointer pcf = &cf;
+ static_assert(std::is_same_v<decltype(pcf), QPointer<const QFile>>);
+ QPointer pcfc = pcf;
+ static_assert(std::is_same_v<decltype(pcfc), QPointer<const QFile>>);
+ QPointer pcfm = std::move(pcf);
+ static_assert(std::is_same_v<decltype(pcfm), QPointer<const QFile>>);
+ }
+}
+
+void tst_QPointer::conversion()
+{
+ // copy-conversion:
+ {
+ QFile file;
+ QPointer<QFile> pf = &file;
+ QCOMPARE_EQ(pf, &file);
+ QPointer<const QIODevice> pio = pf;
+ QCOMPARE_EQ(pio, &file);
+ QCOMPARE_EQ(pio.get(), &file);
+ QCOMPARE_EQ(pio, pf);
+ QCOMPARE_EQ(pio.get(), pf.get());
+
+ // reset
+ pio = nullptr;
+ QCOMPARE_EQ(pio, nullptr);
+ QCOMPARE_EQ(pio.get(), nullptr);
+
+ // copy-assignment
+ QCOMPARE_EQ(pf, &file);
+ pio = pf;
+ QCOMPARE_EQ(pio, &file);
+ QCOMPARE_EQ(pio.get(), &file);
+ QCOMPARE_EQ(pio, pf);
+ QCOMPARE_EQ(pio.get(), pf.get());
+ }
+ // move-conversion:
+ {
+ QFile file;
+ QPointer<QFile> pf = &file;
+ QCOMPARE_EQ(pf, &file);
+ QPointer<const QIODevice> pio = std::move(pf);
+ QCOMPARE_EQ(pf, nullptr);
+ QCOMPARE_EQ(pio, &file);
+ QCOMPARE_EQ(pio.get(), &file);
+
+ // reset
+ pio = nullptr;
+ QCOMPARE_EQ(pio, nullptr);
+ QCOMPARE_EQ(pio.get(), nullptr);
+
+ // move-assignment
+ pio = QPointer<QFile>(&file);
+ QCOMPARE_EQ(pio, &file);
+ QCOMPARE_EQ(pio.get(), &file);
+ }
}
void tst_QPointer::destructor()
@@ -98,7 +177,7 @@ void tst_QPointer::assignment_operators()
QCOMPARE(p1, QPointer<QObject>(p2));
// Test assignment with a null pointer
- p1 = 0;
+ p1 = nullptr;
p2 = p1;
QCOMPARE(p1, QPointer<QObject>(0));
QCOMPARE(p2, QPointer<QObject>(0));
@@ -131,9 +210,9 @@ void tst_QPointer::equality_operators()
QVERIFY(p1 == p2);
- QObject *object = 0;
+ QObject *object = nullptr;
#ifndef QT_NO_WIDGETS
- QWidget *widget = 0;
+ QWidget *widget = nullptr;
#endif
p1 = object;
@@ -149,11 +228,15 @@ void tst_QPointer::equality_operators()
QVERIFY(p1 == p2);
// compare to zero
- p1 = 0;
+ p1 = nullptr;
QVERIFY(p1 == 0);
QVERIFY(0 == p1);
QVERIFY(p2 != 0);
QVERIFY(0 != p2);
+ QVERIFY(p1 == nullptr);
+ QVERIFY(nullptr == p1);
+ QVERIFY(p2 != nullptr);
+ QVERIFY(nullptr != p2);
QVERIFY(p1 == object);
QVERIFY(object == p1);
QVERIFY(p2 != object);
@@ -188,7 +271,7 @@ void tst_QPointer::isNull()
QVERIFY(p1.isNull());
p1 = this;
QVERIFY(!p1.isNull());
- p1 = 0;
+ p1 = nullptr;
QVERIFY(p1.isNull());
}
@@ -327,7 +410,8 @@ void tst_QPointer::castDuringDestruction()
}
class TestRunnable : public QObject, public QRunnable {
- void run() {
+ void run() override
+ {
QPointer<QObject> obj1 = new QObject;
QPointer<QObject> obj2 = new QObject;
obj1->moveToThread(thread()); // this is the owner thread
diff --git a/tests/auto/corelib/kernel/qproperty/CMakeLists.txt b/tests/auto/corelib/kernel/qproperty/CMakeLists.txt
new file mode 100644
index 0000000000..177465d2ee
--- /dev/null
+++ b/tests/auto/corelib/kernel/qproperty/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qproperty Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qproperty LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qproperty
+ SOURCES
+ tst_qproperty.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
new file mode 100644
index 0000000000..cc7edb8bf2
--- /dev/null
+++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
@@ -0,0 +1,2582 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QObject>
+#include <QSignalSpy>
+#include <qtest.h>
+#include <qproperty.h>
+#include <private/qproperty_p.h>
+#include <private/qobject_p.h>
+
+#if __has_include(<source_location>) && __cplusplus >= 202002L && !defined(Q_QDOC)
+#include <source_location>
+#define QT_SOURCE_LOCATION_NAMESPACE std
+#elif __has_include(<experimental/source_location>) && !defined(Q_QDOC)
+#include <experimental/source_location>
+#define QT_SOURCE_LOCATION_NAMESPACE std::experimental
+#endif
+
+using namespace QtPrivate;
+using namespace Qt::StringLiterals;
+
+struct DtorCounter {
+ static inline int counter = 0;
+ bool shouldIncrement = false;
+ ~DtorCounter() {if (shouldIncrement) ++counter;}
+};
+
+class tst_QProperty : public QObject
+{
+ Q_OBJECT
+private slots:
+ void inheritQUntypedPropertyData();
+ void functorBinding();
+ void basicDependencies();
+ void multipleDependencies();
+ void bindingWithDeletedDependency();
+ void dependencyChangeDuringDestruction();
+ void recursiveDependency();
+ void bindingAfterUse();
+ void bindingFunctionDtorCalled();
+ void switchBinding();
+ void avoidDependencyAllocationAfterFirstEval();
+ void boolProperty();
+ void takeBinding();
+ void stickyBinding();
+ void replaceBinding();
+ void changeHandler();
+ void propertyChangeHandlerApi();
+ void subscribe();
+ void changeHandlerThroughBindings();
+ void dontTriggerDependenciesIfUnchangedValue();
+ void bindingSourceLocation();
+ void bindingError();
+ void bindingLoop();
+ void realloc();
+ void changePropertyFromWithinChangeHandler();
+ void changePropertyFromWithinChangeHandlerThroughDependency();
+ void changePropertyFromWithinChangeHandler2();
+ void settingPropertyValueDoesRemoveBinding();
+ void genericPropertyBinding();
+ void genericPropertyBindingBool();
+ void setBindingFunctor();
+ void multipleObservers();
+ void arrowAndStarOperator();
+ void notifiedProperty();
+ void typeNoOperatorEqual();
+ void bindingValueReplacement();
+ void quntypedBindableApi();
+ void readonlyConstQBindable();
+ void qobjectBindableManualNotify();
+ void qobjectBindableReallocatedBindingStorage();
+ void qobjectBindableSignalTakingNewValue();
+
+ void testNewStuff();
+ void qobjectObservers();
+ void compatBindings();
+ void metaProperty();
+
+ void modifyObserverListWhileIterating();
+ void noDoubleCapture();
+ void compatPropertyNoDobuleNotification();
+ void compatPropertySignals();
+
+ void noFakeDependencies();
+#if QT_CONFIG(thread)
+ void threadSafety();
+ void threadSafety2();
+#endif // QT_CONFIG(thread)
+
+ void bindablePropertyWithInitialization();
+ void noDoubleNotification();
+ void groupedNotifications();
+ void groupedNotificationConsistency();
+ void bindingGroupMovingBindingData();
+ void bindingGroupBindingDeleted();
+ void uninstalledBindingDoesNotEvaluate();
+
+ void notify();
+
+ void bindableInterfaceOfCompatPropertyUsesSetter();
+
+ void selfBindingShouldNotCrash();
+
+ void qpropertyAlias();
+ void scheduleNotify();
+
+ void notifyAfterAllDepsGone();
+
+ void propertyAdaptorBinding();
+ void propertyUpdateViaSignaledProperty();
+
+ void derefFromObserver();
+};
+
+namespace {
+template <class T>
+constexpr auto isDerivedFromQUntypedPropertyData = std::is_base_of_v<QUntypedPropertyData, T>;
+
+template <typename Property>
+constexpr auto isDerivedFromQUntypedPropertyDataFunc(const Property &property)
+{
+ Q_UNUSED(property);
+ return isDerivedFromQUntypedPropertyData<Property>;
+}
+
+template <typename Property>
+constexpr auto isDerivedFromQUntypedPropertyDataFunc(Property *property)
+{
+ Q_UNUSED(property);
+ return isDerivedFromQUntypedPropertyData<Property>;
+}
+} // namespace
+
+void tst_QProperty::inheritQUntypedPropertyData()
+{
+ class propertyPublic : public QUntypedPropertyData
+ {
+ };
+ class propertyPrivate : private QUntypedPropertyData
+ {
+ };
+
+ // Compile time test
+ static_assert(isDerivedFromQUntypedPropertyData<propertyPublic>);
+ static_assert(isDerivedFromQUntypedPropertyData<propertyPrivate>);
+ static_assert(isDerivedFromQUntypedPropertyData<QPropertyData<int>>);
+ static_assert(isDerivedFromQUntypedPropertyData<QProperty<int>>);
+
+ // Run time test
+ propertyPublic _propertyPublic;
+ propertyPrivate _propertyPrivate;
+ QPropertyData<int> qpropertyData;
+ QProperty<int> qproperty;
+ std::unique_ptr<propertyPublic> _propertyPublicPtr{ new propertyPublic };
+ std::unique_ptr<propertyPrivate> _propertyPrivatePtr{ new propertyPrivate };
+ std::unique_ptr<QPropertyData<int>> qpropertyDataPtr{ new QPropertyData<int> };
+ std::unique_ptr<QProperty<int>> qpropertyPtr{ new QProperty<int> };
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(_propertyPublic));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(_propertyPrivate));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(qpropertyData));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(qproperty));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(_propertyPublicPtr.get()));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(_propertyPrivatePtr.get()));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(qpropertyDataPtr.get()));
+ QVERIFY(isDerivedFromQUntypedPropertyDataFunc(qpropertyPtr.get()));
+}
+
+void tst_QProperty::functorBinding()
+{
+ QProperty<int> property([]() { return 42; });
+ QCOMPARE(property.value(), int(42));
+ property.setBinding([]() { return 100; });
+ QCOMPARE(property.value(), int(100));
+ property.setBinding([]() { return 50; });
+ QCOMPARE(property.value(), int(50));
+}
+
+void tst_QProperty::basicDependencies()
+{
+ QProperty<int> right(100);
+
+ QProperty<int> left(Qt::makePropertyBinding(right));
+
+ QCOMPARE(left.value(), int(100));
+
+ right = 42;
+
+ QCOMPARE(left.value(), int(42));
+}
+
+void tst_QProperty::multipleDependencies()
+{
+ QProperty<int> firstDependency(1);
+ QProperty<int> secondDependency(2);
+
+ QProperty<int> sum;
+ sum.setBinding([&]() { return firstDependency + secondDependency; });
+
+ QCOMPARE(QPropertyBindingDataPointer::get(firstDependency).observerCount(), 1);
+ QCOMPARE(QPropertyBindingDataPointer::get(secondDependency).observerCount(), 1);
+
+ QCOMPARE(sum.value(), int(3));
+ QCOMPARE(QPropertyBindingDataPointer::get(firstDependency).observerCount(), 1);
+ QCOMPARE(QPropertyBindingDataPointer::get(secondDependency).observerCount(), 1);
+
+ firstDependency = 10;
+
+ QCOMPARE(sum.value(), int(12));
+ QCOMPARE(QPropertyBindingDataPointer::get(firstDependency).observerCount(), 1);
+ QCOMPARE(QPropertyBindingDataPointer::get(secondDependency).observerCount(), 1);
+
+ secondDependency = 20;
+
+ QCOMPARE(sum.value(), int(30));
+ QCOMPARE(QPropertyBindingDataPointer::get(firstDependency).observerCount(), 1);
+ QCOMPARE(QPropertyBindingDataPointer::get(secondDependency).observerCount(), 1);
+
+ firstDependency = 1;
+ secondDependency = 1;
+ QCOMPARE(sum.value(), int(2));
+ QCOMPARE(QPropertyBindingDataPointer::get(firstDependency).observerCount(), 1);
+ QCOMPARE(QPropertyBindingDataPointer::get(secondDependency).observerCount(), 1);
+}
+
+void tst_QProperty::bindingWithDeletedDependency()
+{
+ QScopedPointer<QProperty<int>> dynamicProperty(new QProperty<int>(100));
+
+ QProperty<int> staticProperty(1000);
+
+ QProperty<bool> bindingReturnsDynamicProperty(false);
+
+ QProperty<int> propertySelector([&]() {
+ if (bindingReturnsDynamicProperty && !dynamicProperty.isNull())
+ return dynamicProperty->value();
+ else
+ return staticProperty.value();
+ });
+
+ QCOMPARE(propertySelector.value(), staticProperty.value());
+
+ bindingReturnsDynamicProperty = true;
+
+ QCOMPARE(propertySelector.value(), dynamicProperty->value());
+
+ dynamicProperty.reset();
+
+ QCOMPARE(propertySelector.value(), 100);
+
+ bindingReturnsDynamicProperty = false;
+
+ QCOMPARE(propertySelector.value(), staticProperty.value());
+}
+
+class ChangeDuringDtorTester : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int prop READ prop WRITE setProp BINDABLE bindableProp)
+
+public:
+ void setProp(int i) { m_prop = i;}
+ int prop() const { return m_prop; }
+ QBindable<int> bindableProp() { return &m_prop; }
+private:
+ Q_OBJECT_COMPAT_PROPERTY(ChangeDuringDtorTester, int, m_prop, &ChangeDuringDtorTester::setProp)
+};
+
+void tst_QProperty::dependencyChangeDuringDestruction()
+{
+ auto tester = std::make_unique<ChangeDuringDtorTester>();
+ QProperty<int> iprop {42};
+ tester->bindableProp().setBinding(Qt::makePropertyBinding(iprop));
+ QObject::connect(tester.get(), &QObject::destroyed, [&](){
+ iprop = 12;
+ });
+ bool failed = false;
+ auto handler = tester->bindableProp().onValueChanged([&](){
+ failed = true;
+ });
+ tester.reset();
+ QVERIFY(!failed);
+}
+
+void tst_QProperty::recursiveDependency()
+{
+ QProperty<int> first(1);
+
+ QProperty<int> second;
+ second.setBinding(Qt::makePropertyBinding(first));
+
+ QProperty<int> third;
+ third.setBinding(Qt::makePropertyBinding(second));
+
+ QCOMPARE(third.value(), int(1));
+
+ first = 2;
+
+ QCOMPARE(third.value(), int(2));
+}
+
+void tst_QProperty::bindingAfterUse()
+{
+ QProperty<int> propWithBindingLater(1);
+
+ QProperty<int> propThatUsesFirstProp;
+ propThatUsesFirstProp.setBinding(Qt::makePropertyBinding(propWithBindingLater));
+
+ QCOMPARE(propThatUsesFirstProp.value(), int(1));
+ QCOMPARE(QPropertyBindingDataPointer::get(propWithBindingLater).observerCount(), 1);
+
+ QProperty<int> injectedValue(42);
+ propWithBindingLater.setBinding(Qt::makePropertyBinding(injectedValue));
+
+ QCOMPARE(propThatUsesFirstProp.value(), int(42));
+ QCOMPARE(QPropertyBindingDataPointer::get(propWithBindingLater).observerCount(), 1);
+}
+
+void tst_QProperty::bindingFunctionDtorCalled()
+{
+ DtorCounter::counter = 0;
+ DtorCounter dc;
+ {
+ QProperty<int> prop;
+ prop.setBinding([dc]() mutable {
+ dc.shouldIncrement = true;
+ return 42;
+ });
+ QCOMPARE(prop.value(), 42);
+ }
+ QCOMPARE(DtorCounter::counter, 1);
+}
+
+void tst_QProperty::switchBinding()
+{
+ QProperty<int> first(1);
+
+ QProperty<int> propWithChangingBinding;
+ propWithChangingBinding.setBinding(Qt::makePropertyBinding(first));
+
+ QCOMPARE(propWithChangingBinding.value(), 1);
+
+ QProperty<int> output;
+ output.setBinding(Qt::makePropertyBinding(propWithChangingBinding));
+ QCOMPARE(output.value(), 1);
+
+ QProperty<int> second(2);
+ propWithChangingBinding.setBinding(Qt::makePropertyBinding(second));
+ QCOMPARE(output.value(), 2);
+}
+
+void tst_QProperty::avoidDependencyAllocationAfterFirstEval()
+{
+ QProperty<int> firstDependency(1);
+ QProperty<int> secondDependency(10);
+
+ QProperty<int> propWithBinding([&]() { return firstDependency + secondDependency; });
+
+ QCOMPARE(propWithBinding.value(), int(11));
+
+ QVERIFY(QPropertyBindingDataPointer::get(propWithBinding).binding());
+ QCOMPARE(QPropertyBindingDataPointer::get(propWithBinding).binding()->dependencyObserverCount, 2u);
+
+ firstDependency = 100;
+ QCOMPARE(propWithBinding.value(), int(110));
+ QCOMPARE(QPropertyBindingDataPointer::get(propWithBinding).binding()->dependencyObserverCount, 2u);
+}
+
+void tst_QProperty::boolProperty()
+{
+ QProperty<bool> first(true);
+ QProperty<bool> second(false);
+ QProperty<bool> all([&]() { return first && second; });
+
+ QCOMPARE(all.value(), false);
+
+ second = true;
+
+ QCOMPARE(all.value(), true);
+}
+
+void tst_QProperty::takeBinding()
+{
+ QPropertyBinding<int> existingBinding;
+ QVERIFY(existingBinding.isNull());
+
+ QProperty<int> first(100);
+ QProperty<int> second(Qt::makePropertyBinding(first));
+
+ QCOMPARE(second.value(), int(100));
+
+ existingBinding = second.takeBinding();
+ QVERIFY(!existingBinding.isNull());
+
+ first = 10;
+ QCOMPARE(second.value(), int(100));
+
+ second = 25;
+ QCOMPARE(second.value(), int(25));
+
+ second.setBinding(existingBinding);
+ QCOMPARE(second.value(), int(10));
+ QVERIFY(!existingBinding.isNull());
+}
+
+void tst_QProperty::stickyBinding()
+{
+ QProperty<int> prop;
+ QProperty<int> prop2 {2};
+ prop.setBinding([&](){ return prop2.value(); });
+ QCOMPARE(prop.value(), 2);
+ auto privBinding = QPropertyBindingPrivate::get(prop.binding());
+ // If we make a binding sticky,
+ privBinding->setSticky();
+ // then writing to the property does not remove it
+ prop = 1;
+ QVERIFY(prop.hasBinding());
+ // but the value still changes.
+ QCOMPARE(prop.value(), 1);
+ // The binding continues to work normally.
+ prop2 = 3;
+ QCOMPARE(prop.value(), 3);
+ // If we remove the stickiness
+ privBinding->setSticky(false);
+ // the binding goes away on the next write
+ prop = 42;
+ QVERIFY(!prop.hasBinding());
+}
+
+void tst_QProperty::replaceBinding()
+{
+ QProperty<int> first(100);
+ QProperty<int> second(Qt::makePropertyBinding(first));
+
+ QCOMPARE(second.value(), 100);
+
+ auto constantBinding = Qt::makePropertyBinding([]() { return 42; });
+ auto oldBinding = second.setBinding(constantBinding);
+ QCOMPARE(second.value(), 42);
+
+ second.setBinding(oldBinding);
+ QCOMPARE(second.value(), 100);
+}
+
+void tst_QProperty::changeHandler()
+{
+ QProperty<int> testProperty(0);
+ QList<int> recordedValues;
+
+ {
+ auto handler = testProperty.onValueChanged([&]() {
+ recordedValues << testProperty;
+ });
+
+ testProperty = 1;
+ testProperty = 2;
+ }
+ testProperty = 3;
+
+ QCOMPARE(recordedValues.size(), 2);
+ QCOMPARE(recordedValues.at(0), 1);
+ QCOMPARE(recordedValues.at(1), 2);
+}
+
+void tst_QProperty::propertyChangeHandlerApi()
+{
+ int changeHandlerCallCount = 0;
+ QPropertyChangeHandler handler([&changeHandlerCallCount]() {
+ ++changeHandlerCallCount;
+ });
+
+ QProperty<int> source1;
+ QProperty<int> source2;
+
+ handler.setSource(source1);
+
+ source1 = 100;
+ QCOMPARE(changeHandlerCallCount, 1);
+
+ handler.setSource(source2);
+ source1 = 101;
+ QCOMPARE(changeHandlerCallCount, 1);
+
+ source2 = 200;
+ QCOMPARE(changeHandlerCallCount, 2);
+}
+
+void tst_QProperty::subscribe()
+{
+ QProperty<int> testProperty(42);
+ QList<int> recordedValues;
+
+ {
+ auto handler = testProperty.subscribe([&]() {
+ recordedValues << testProperty;
+ });
+
+ testProperty = 1;
+ testProperty = 2;
+ }
+ testProperty = 3;
+
+ QCOMPARE(recordedValues.size(), 3);
+ QCOMPARE(recordedValues.at(0), 42);
+ QCOMPARE(recordedValues.at(1), 1);
+ QCOMPARE(recordedValues.at(2), 2);
+}
+
+void tst_QProperty::changeHandlerThroughBindings()
+{
+ QProperty<bool> trigger(false);
+ QProperty<bool> blockTrigger(false);
+ QProperty<bool> condition([&]() {
+ bool triggerValue = trigger;
+ bool blockTriggerValue = blockTrigger;
+ return triggerValue && !blockTriggerValue;
+ });
+ bool changeHandlerCalled = false;
+ auto handler = condition.onValueChanged([&]() {
+ changeHandlerCalled = true;
+ });
+
+ QVERIFY(!condition);
+ QVERIFY(!changeHandlerCalled);
+
+ trigger = true;
+
+ QVERIFY(condition);
+ QVERIFY(changeHandlerCalled);
+ changeHandlerCalled = false;
+
+ trigger = false;
+
+ QVERIFY(!condition);
+ QVERIFY(changeHandlerCalled);
+ changeHandlerCalled = false;
+
+ blockTrigger = true;
+
+ QVERIFY(!condition);
+ QVERIFY(!changeHandlerCalled);
+}
+
+void tst_QProperty::dontTriggerDependenciesIfUnchangedValue()
+{
+ QProperty<int> property(42);
+
+ bool triggered = false;
+ QProperty<int> observer([&]() { triggered = true; return property.value(); });
+
+ QCOMPARE(observer.value(), 42);
+ QVERIFY(triggered);
+ triggered = false;
+ property = 42;
+ QCOMPARE(observer.value(), 42);
+ QVERIFY(!triggered);
+}
+
+void tst_QProperty::bindingSourceLocation()
+{
+#if defined(QT_PROPERTY_COLLECT_BINDING_LOCATION)
+ auto bindingLine = QT_SOURCE_LOCATION_NAMESPACE::source_location::current().line() + 1;
+ auto binding = Qt::makePropertyBinding([]() { return 42; });
+ QCOMPARE(QPropertyBindingPrivate::get(binding)->sourceLocation().line, bindingLine);
+#else
+ QSKIP("Skipping this in the light of missing binding source location support");
+#endif
+}
+
+void tst_QProperty::bindingError()
+{
+ QProperty<int> prop([]() -> int {
+ QPropertyBindingError error(QPropertyBindingError::UnknownError, QLatin1String("my error"));
+ QPropertyBindingPrivate::currentlyEvaluatingBinding()->setError(std::move(error));
+ return 0;
+ });
+ QCOMPARE(prop.value(), 0);
+ QCOMPARE(prop.binding().error().description(), QString("my error"));
+}
+
+
+
+class BindingLoopTester : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int eagerProp READ eagerProp WRITE setEagerProp BINDABLE bindableEagerProp)
+ Q_PROPERTY(int eagerProp2 READ eagerProp2 WRITE setEagerProp2 BINDABLE bindableEagerProp2)
+ public:
+ BindingLoopTester(QProperty<int> *i, QObject *parent = nullptr) : QObject(parent) {
+ eagerData.setBinding(Qt::makePropertyBinding([&](){ return eagerData2.value() + i->value(); } ) );
+ eagerData2.setBinding(Qt::makePropertyBinding([&](){ return eagerData.value() + 1; } ) );
+ i->setValue(42);
+ }
+ BindingLoopTester() {}
+
+ int eagerProp() {return eagerData.value();}
+ void setEagerProp(int i) { eagerData.setValue(i); eagerData.notify(); }
+ QBindable<int> bindableEagerProp() {return QBindable<int>(&eagerData);}
+ Q_OBJECT_COMPAT_PROPERTY(BindingLoopTester, int, eagerData, &BindingLoopTester::setEagerProp)
+
+ int eagerProp2() {return eagerData2.value();}
+ void setEagerProp2(int i) { eagerData2.setValue(i); eagerData2.notify(); }
+ QBindable<int> bindableEagerProp2() {return QBindable<int>(&eagerData2);}
+ Q_OBJECT_COMPAT_PROPERTY(BindingLoopTester, int, eagerData2, &BindingLoopTester::setEagerProp2)
+};
+
+void tst_QProperty::bindingLoop()
+{
+ QProperty<int> firstProp;
+
+ QProperty<int> secondProp([&]() -> int {
+ return firstProp.value();
+ });
+
+ QProperty<int> thirdProp([&]() -> int {
+ return secondProp.value();
+ });
+
+ firstProp.setBinding([&]() -> int {
+ return secondProp.value() + thirdProp.value();
+ });
+
+ thirdProp.setValue(10);
+ QCOMPARE(firstProp.binding().error().type(), QPropertyBindingError::BindingLoop);
+
+
+ {
+ QProperty<int> i;
+ BindingLoopTester tester(&i);
+ QCOMPARE(tester.bindableEagerProp().binding().error().type(), QPropertyBindingError::BindingLoop);
+ QCOMPARE(tester.bindableEagerProp2().binding().error().type(), QPropertyBindingError::BindingLoop);
+ }
+ {
+ BindingLoopTester tester;
+ auto handler = tester.bindableEagerProp().onValueChanged([&]() {
+ tester.bindableEagerProp().setBinding([](){return 42;});
+ });
+ tester.bindableEagerProp().setBinding([]() {return 42;});
+ QCOMPARE(tester.bindableEagerProp().binding().error().type(), QPropertyBindingError::BindingLoop);
+ QCOMPARE(tester.bindableEagerProp().binding().error().description(), "Binding set during binding evaluation!");
+ }
+}
+
+class ReallocTester : public QObject
+{
+ /*
+ * This class and the realloc test rely on the fact that the internal property hashmap has an
+ * initial capacity of 8 and a load factor of 0.5. Thus, it is necessary to cause actions which
+ * allocate 5 different QPropertyBindingData
+ * */
+ Q_OBJECT
+ Q_PROPERTY(int prop1 READ prop1 WRITE setProp1 BINDABLE bindableProp1)
+ Q_PROPERTY(int prop2 READ prop2 WRITE setProp2 BINDABLE bindableProp2)
+ Q_PROPERTY(int prop3 READ prop3 WRITE setProp3 BINDABLE bindableProp3)
+ Q_PROPERTY(int prop4 READ prop4 WRITE setProp4 BINDABLE bindableProp4)
+ Q_PROPERTY(int prop5 READ prop5 WRITE setProp5 BINDABLE bindableProp5)
+public:
+ ReallocTester(QObject *parent = nullptr) : QObject(parent) {}
+
+
+#define GEN(N) \
+ int prop##N() {return propData##N.value();} \
+ void setProp##N(int i) { if (i == propData##N) return; propData##N.setValue(i); propData##N.notify(); } \
+ QBindable<int> bindableProp##N() {return QBindable<int>(&propData##N);} \
+ Q_OBJECT_COMPAT_PROPERTY(ReallocTester, int, propData##N, &ReallocTester::setProp##N)
+ GEN(1)
+ GEN(2)
+ GEN(3)
+ GEN(4)
+ GEN(5)
+#undef GEN
+};
+
+void tst_QProperty::realloc()
+{
+ {
+ // Triggering a reallocation does not crash
+ ReallocTester tester;
+ tester.bindableProp1().setBinding([&](){return tester.prop5();});
+ tester.bindableProp2().setBinding([&](){return tester.prop5();});
+ tester.bindableProp3().setBinding([&](){return tester.prop5();});
+ tester.bindableProp4().setBinding([&](){return tester.prop5();});
+ tester.bindableProp5().setBinding([&]() -> int{return 42;});
+ QCOMPARE(tester.prop1(), 42);
+ }
+ {
+ // After a reallocation, property observers still work
+ ReallocTester tester;
+ int modificationCount = 0;
+ QPropertyChangeHandler observer {[&](){ ++modificationCount; }};
+ tester.bindableProp1().observe(&observer);
+ tester.setProp1(12);
+ QCOMPARE(modificationCount, 1);
+ QCOMPARE(tester.prop1(), 12);
+
+ tester.bindableProp1().setBinding([&](){return tester.prop5();});
+ QCOMPARE(modificationCount, 2);
+ tester.bindableProp2().setBinding([&](){return tester.prop5();});
+ tester.bindableProp3().setBinding([&](){return tester.prop5();});
+ tester.bindableProp4().setBinding([&](){return tester.prop5();});
+ tester.bindableProp5().setBinding([&]() -> int{return 42;});
+ QCOMPARE(modificationCount, 3);
+ }
+};
+
+void tst_QProperty::changePropertyFromWithinChangeHandler()
+{
+ QProperty<int> property(100);
+ bool resetPropertyOnChange = false;
+ int changeHandlerCallCount = 0;
+
+ auto handler = property.onValueChanged([&]() {
+ ++changeHandlerCallCount;
+ if (resetPropertyOnChange)
+ property = 100;
+ });
+
+ QCOMPARE(property.value(), 100);
+
+ resetPropertyOnChange = true;
+ property = 42;
+ QCOMPARE(property.value(), 100);
+ // changing the property value inside the change handler won't result in the change
+ // handler being called again.
+ QCOMPARE(changeHandlerCallCount, 1);
+ changeHandlerCallCount = 0;
+}
+
+void tst_QProperty::changePropertyFromWithinChangeHandlerThroughDependency()
+{
+ QProperty<int> sourceProperty(100);
+ QProperty<int> property(Qt::makePropertyBinding(sourceProperty));
+ bool resetPropertyOnChange = false;
+ int changeHandlerCallCount = 0;
+
+ auto handler = property.onValueChanged([&]() {
+ ++changeHandlerCallCount;
+ if (resetPropertyOnChange)
+ sourceProperty = 100;
+ });
+
+ QCOMPARE(property.value(), 100);
+
+ resetPropertyOnChange = true;
+ sourceProperty = 42;
+ QVERIFY(property.value() == 100 || property.value() == 42);
+ QVERIFY(property.binding().error().type() == QPropertyBindingError::BindingLoop);
+ // changing the property value inside the change handler won't result in the change
+ // handler being called again.
+ QCOMPARE(changeHandlerCallCount, 1);
+ changeHandlerCallCount = 0;
+}
+
+void tst_QProperty::changePropertyFromWithinChangeHandler2()
+{
+ QProperty<int> property(100);
+ int changeHandlerCallCount = 0;
+
+ auto handler = property.onValueChanged([&]() {
+ ++changeHandlerCallCount;
+ property = property.value() + 1;
+ });
+
+ QCOMPARE(property.value(), 100);
+
+ property = 42;
+ QCOMPARE(property.value(), 43);
+ QVERIFY(!property.hasBinding()); // setting the value in the change handler removed the binding
+}
+
+void tst_QProperty::settingPropertyValueDoesRemoveBinding()
+{
+ QProperty<int> source(42);
+
+ QProperty<int> property(Qt::makePropertyBinding(source));
+
+ QCOMPARE(property.value(), 42);
+ QVERIFY(!property.binding().isNull());
+
+ property = 100;
+ QCOMPARE(property.value(), 100);
+ QVERIFY(property.binding().isNull());
+
+ source = 1;
+ QCOMPARE(property.value(), 100);
+ QVERIFY(property.binding().isNull());
+}
+
+void tst_QProperty::genericPropertyBinding()
+{
+ QProperty<int> property;
+
+ {
+ QUntypedPropertyBinding doubleBinding(QMetaType::fromType<double>(),
+ [](QMetaType , void *) -> bool {
+ Q_ASSERT(false);
+ return true;
+ }, QPropertyBindingSourceLocation());
+ QVERIFY(!property.setBinding(doubleBinding));
+ }
+
+ QUntypedPropertyBinding intBinding(QMetaType::fromType<int>(),
+ [](QMetaType metaType, void *dataPtr) -> bool {
+ Q_ASSERT(metaType.id() == qMetaTypeId<int>());
+
+ int *intPtr = reinterpret_cast<int*>(dataPtr);
+ *intPtr = 100;
+ return true;
+ }, QPropertyBindingSourceLocation());
+
+ QVERIFY(property.setBinding(intBinding));
+
+ QCOMPARE(property.value(), 100);
+}
+
+void tst_QProperty::genericPropertyBindingBool()
+{
+ QProperty<bool> property;
+
+ QVERIFY(!property.value());
+
+ QUntypedPropertyBinding boolBinding(QMetaType::fromType<bool>(),
+ [](QMetaType, void *dataPtr) -> bool {
+ auto boolPtr = reinterpret_cast<bool *>(dataPtr);
+ *boolPtr = true;
+ return true;
+ }, QPropertyBindingSourceLocation());
+ QVERIFY(property.setBinding(boolBinding));
+
+ QVERIFY(property.value());
+}
+
+void tst_QProperty::setBindingFunctor()
+{
+ QProperty<int> property;
+ QProperty<int> injectedValue(100);
+ // Make sure that this picks the setBinding overload that takes a functor and
+ // moves it correctly.
+ property.setBinding([&injectedValue]() { return injectedValue.value(); });
+ injectedValue = 200;
+ QCOMPARE(property.value(), 200);
+}
+
+void tst_QProperty::multipleObservers()
+{
+ QProperty<int> property;
+ property.setValue(5);
+ QCOMPARE(property.value(), 5);
+
+ int value1 = 1;
+ auto changeHandler = property.onValueChanged([&]() { value1 = property.value(); });
+ QCOMPARE(value1, 1);
+
+ int value2 = 2;
+ auto subscribeHandler = property.subscribe([&]() { value2 = property.value(); });
+ QCOMPARE(value2, 5);
+
+ property.setValue(6);
+ QCOMPARE(property.value(), 6);
+ QCOMPARE(value1, 6);
+ QCOMPARE(value2, 6);
+
+ property.setBinding([]() { return 12; });
+ QCOMPARE(value1, 12);
+ QCOMPARE(value2, 12);
+ QCOMPARE(property.value(), 12);
+
+ property.setBinding(QPropertyBinding<int>());
+ QCOMPARE(value1, 12);
+ QCOMPARE(value2, 12);
+ QCOMPARE(property.value(), 12);
+
+ property.setValue(22);
+ QCOMPARE(value1, 22);
+ QCOMPARE(value2, 22);
+ QCOMPARE(property.value(), 22);
+}
+
+void tst_QProperty::arrowAndStarOperator()
+{
+ QString str("Hello");
+ QProperty<QString *> prop(&str);
+
+ QCOMPARE(prop->size(), str.size());
+ QCOMPARE(**prop, str);
+
+ struct Dereferenceable {
+ QString x;
+ QString *operator->() { return &x; }
+ const QString *operator->() const { return &x; }
+ };
+ static_assert(QTypeTraits::is_dereferenceable_v<Dereferenceable>);
+
+ QProperty<Dereferenceable> prop2(Dereferenceable{str});
+ QCOMPARE(prop2->size(), str.size());
+ QCOMPARE(**prop, str);
+
+ QObject *object = new QObject;
+ object->setObjectName("Hello");
+ QProperty<QSharedPointer<QObject>> prop3(QSharedPointer<QObject>{object});
+
+ QCOMPARE(prop3->objectName(), str);
+ QCOMPARE(*prop3, object);
+
+}
+
+struct ClassWithNotifiedProperty : public QObject
+{
+ QList<int> recordedValues;
+
+ void callback() { recordedValues << property.value(); }
+ int getProp() { return 0; }
+
+ Q_OBJECT_BINDABLE_PROPERTY(ClassWithNotifiedProperty, int, property, &ClassWithNotifiedProperty::callback);
+};
+
+void tst_QProperty::notifiedProperty()
+{
+ ClassWithNotifiedProperty instance;
+ std::array<QProperty<int>, 5> otherProperties = {
+ QProperty<int>([&]() { return instance.property + 1; }),
+ QProperty<int>([&]() { return instance.property + 2; }),
+ QProperty<int>([&]() { return instance.property + 3; }),
+ QProperty<int>([&]() { return instance.property + 4; }),
+ QProperty<int>([&]() { return instance.property + 5; }),
+ };
+
+ auto check = [&] {
+ const int val = instance.property.value();
+ for (int i = 0; i < int(otherProperties.size()); ++i)
+ QCOMPARE(otherProperties[i].value(), val + i + 1);
+ };
+
+ QVERIFY(instance.recordedValues.isEmpty());
+ check();
+
+ instance.property.setValue(42);
+ QCOMPARE(instance.recordedValues.size(), 1);
+ QCOMPARE(instance.recordedValues.at(0), 42);
+ instance.recordedValues.clear();
+ check();
+
+ instance.property.setValue(42);
+ QVERIFY(instance.recordedValues.isEmpty());
+ check();
+
+ int subscribedCount = 0;
+ QProperty<int> injectedValue(100);
+ instance.property.setBinding([&injectedValue]() { return injectedValue.value(); });
+ auto subscriber = [&] { ++subscribedCount; };
+ std::array<QPropertyChangeHandler<decltype (subscriber)>, 10> subscribers = {
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber),
+ instance.property.subscribe(subscriber)
+ };
+
+ QCOMPARE(subscribedCount, 10);
+ subscribedCount = 0;
+
+ QCOMPARE(instance.property.value(), 100);
+ QCOMPARE(instance.recordedValues.size(), 1);
+ QCOMPARE(instance.recordedValues.at(0), 100);
+ instance.recordedValues.clear();
+ check();
+ QCOMPARE(subscribedCount, 0);
+
+ injectedValue = 200;
+ QCOMPARE(instance.property.value(), 200);
+ QCOMPARE(instance.recordedValues.size(), 1);
+ QCOMPARE(instance.recordedValues.at(0), 200);
+ instance.recordedValues.clear();
+ check();
+ QCOMPARE(subscribedCount, 10);
+ subscribedCount = 0;
+
+ injectedValue = 400;
+ QCOMPARE(instance.property.value(), 400);
+ QCOMPARE(instance.recordedValues.size(), 1);
+ QCOMPARE(instance.recordedValues.at(0), 400);
+ instance.recordedValues.clear();
+ check();
+ QCOMPARE(subscribedCount, 10);
+}
+
+void tst_QProperty::typeNoOperatorEqual()
+{
+ struct Uncomparable
+ {
+ int data = -1;
+ bool changedCalled = false;
+
+ Uncomparable(int value = 0)
+ : data(value)
+ {}
+ Uncomparable(const Uncomparable &other)
+ {
+ data = other.data;
+ changedCalled = false;
+ }
+ Uncomparable(Uncomparable &&other)
+ {
+ data = other.data;
+ changedCalled = false;
+ other.data = -1;
+ other.changedCalled = false;
+ }
+ Uncomparable &operator=(const Uncomparable &other)
+ {
+ data = other.data;
+ return *this;
+ }
+ Uncomparable &operator=(Uncomparable &&other)
+ {
+ data = other.data;
+ changedCalled = false;
+ other.data = -1;
+ other.changedCalled = false;
+ return *this;
+ }
+ bool operator==(const Uncomparable&) = delete;
+ bool operator!=(const Uncomparable&) = delete;
+
+ void changed()
+ {
+ changedCalled = true;
+ }
+ };
+
+ Uncomparable u1 = { 13 };
+ Uncomparable u2 = { 27 };
+
+ QProperty<Uncomparable> p1;
+ QProperty<Uncomparable> p2(Qt::makePropertyBinding(p1));
+
+ QCOMPARE(p1.value().data, p2.value().data);
+ p1.setValue(u1);
+ QCOMPARE(p1.value().data, u1.data);
+ QCOMPARE(p1.value().data, p2.value().data);
+ p2.setValue(u2);
+ QCOMPARE(p1.value().data, u1.data);
+ QCOMPARE(p2.value().data, u2.data);
+
+ QProperty<Uncomparable> p3(Qt::makePropertyBinding(p1));
+ p1.setValue(u1);
+ QCOMPARE(p1.value().data, p3.value().data);
+
+// QNotifiedProperty<Uncomparable, &Uncomparable::changed> np;
+// QVERIFY(np.value().data != u1.data);
+// np.setValue(&u1, u1);
+// QVERIFY(u1.changedCalled);
+// u1.changedCalled = false;
+// QCOMPARE(np.value().data, u1.data);
+// np.setValue(&u1, u1);
+// QVERIFY(u1.changedCalled);
+}
+
+
+//struct Test {
+// void notify() {};
+// bool bindText(int);
+// bool bindIconText(int);
+// QProperty<int> text;
+// QNotifiedProperty<int, &Test::notify, &Test::bindIconText> iconText;
+//};
+
+//bool Test::bindIconText(int) {
+// Q_UNUSED(iconText.value()); // force read
+// if (!iconText.hasBinding()) {
+// iconText.setBinding(this, [=]() { return 0; });
+// }
+// return true;
+//}
+
+void tst_QProperty::bindingValueReplacement()
+{
+// Test test;
+// test.text = 0;
+// test.bindIconText(0);
+// test.iconText.setValue(&test, 42); // should not crash
+// QCOMPARE(test.iconText.value(), 42);
+// test.text = 1;
+// QCOMPARE(test.iconText.value(), 42);
+}
+
+void tst_QProperty::quntypedBindableApi()
+{
+ QProperty<int> iprop;
+ QUntypedBindable bindable(&iprop);
+ QVERIFY(!bindable.hasBinding());
+ QVERIFY(bindable.binding().isNull());
+ bindable.setBinding(Qt::makePropertyBinding([]() -> int {return 42;}));
+ QVERIFY(bindable.hasBinding());
+ QVERIFY(!bindable.binding().isNull());
+ QUntypedPropertyBinding binding = bindable.takeBinding();
+ QVERIFY(!bindable.hasBinding());
+ bindable.setBinding(binding);
+ QCOMPARE(iprop.value(), 42);
+ QUntypedBindable propLess;
+ QVERIFY(propLess.takeBinding().isNull());
+
+ QUntypedBindable invalidBindable;
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "setBinding: Could not set binding via bindable interface. The QBindable is invalid.");
+#endif
+ invalidBindable.setBinding(Qt::makePropertyBinding(iprop));
+
+ QUntypedBindable readOnlyBindable(static_cast<const QProperty<int> *>(&iprop) );
+ QVERIFY(readOnlyBindable.isReadOnly());
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "setBinding: Could not set binding via bindable interface. The QBindable is read-only.");
+#endif
+ readOnlyBindable.setBinding(Qt::makePropertyBinding(iprop));
+
+ QProperty<float> fprop;
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "setBinding: Could not set binding as the property expects it to be of type int but got float instead.");
+#endif
+ bindable.setBinding(Qt::makePropertyBinding(fprop));
+}
+
+void tst_QProperty::readonlyConstQBindable()
+{
+ QProperty<int> i {42};
+ const QBindable<int> bindableI(const_cast<const QProperty<int> *>(&i));
+
+ // check that read-only operations work with a const QBindable
+ QVERIFY(bindableI.isReadOnly());
+ QVERIFY(!bindableI.hasBinding());
+ // we can still create a binding to a read only bindable through the interface
+ QProperty<int> j;
+ j.setBinding(bindableI.makeBinding());
+ QCOMPARE(j.value(), bindableI.value());
+ int counter = 0;
+ auto observer = bindableI.subscribe([&](){++counter;});
+ QCOMPARE(counter, 1);
+ auto observer2 = bindableI.onValueChanged([&](){++counter;});
+ i = 0;
+ QCOMPARE(counter, 3);
+}
+
+class MyQObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int foo READ foo WRITE setFoo BINDABLE bindableFoo NOTIFY fooChanged)
+ Q_PROPERTY(int bar READ bar WRITE setBar BINDABLE bindableBar NOTIFY barChanged)
+ Q_PROPERTY(int read READ read)
+ Q_PROPERTY(int computed READ computed STORED false)
+ Q_PROPERTY(int compat READ compat WRITE setCompat NOTIFY compatChanged)
+
+signals:
+ void fooChanged(int newFoo);
+ void barChanged();
+ void compatChanged();
+
+public slots:
+ void fooHasChanged() { fooChangedCount++; }
+ void barHasChanged() { barChangedCount++; }
+ void compatHasChanged() { compatChangedCount++; }
+
+public:
+ int foo() const { return fooData.value(); }
+ void setFoo(int i) { fooData.setValue(i); }
+ int bar() const { return barData.value(); }
+ void setBar(int i) { barData.setValue(i); }
+ int read() const { return readData.value(); }
+ int computed() const { return readData.value(); }
+ int compat() const { return compatData; }
+ void setCompat(int i)
+ {
+ if (compatData == i)
+ return;
+ // implement some side effect and clamping
+ ++setCompatCalled;
+ if (i < 0)
+ i = 0;
+ compatData.setValue(i);
+ compatData.notify();
+ emit compatChanged();
+ }
+
+ QBindable<int> bindableFoo() { return QBindable<int>(&fooData); }
+ const QBindable<int> bindableFoo() const { return QBindable<int>(&fooData); }
+ QBindable<int> bindableBar() { return QBindable<int>(&barData); }
+ QBindable<int> bindableRead() { return QBindable<int>(&readData); }
+ QBindable<int> bindableComputed() { return QBindable<int>(&computedData); }
+ QBindable<int> bindableCompat() { return QBindable<int>(&compatData); }
+
+public:
+ int fooChangedCount = 0;
+ int barChangedCount = 0;
+ int compatChangedCount = 0;
+ int setCompatCalled = 0;
+
+ Q_OBJECT_BINDABLE_PROPERTY(MyQObject, int, fooData, &MyQObject::fooChanged);
+ Q_OBJECT_BINDABLE_PROPERTY(MyQObject, int, barData, &MyQObject::barChanged);
+ Q_OBJECT_BINDABLE_PROPERTY(MyQObject, int, readData);
+ Q_OBJECT_COMPUTED_PROPERTY(MyQObject, int, computedData, &MyQObject::computed);
+ Q_OBJECT_COMPAT_PROPERTY(MyQObject, int, compatData, &MyQObject::setCompat)
+};
+
+
+void tst_QProperty::qobjectBindableManualNotify()
+{
+ // Given an object of type MyQObject,
+ MyQObject object;
+ // track its foo property's change count
+ auto bindable = object.bindableFoo();
+ int fooChangeCount = 0;
+ auto changeHandler = bindable.onValueChanged([&](){++fooChangeCount;});
+ // and how many changed signals it emits.
+ QSignalSpy fooChangedSpy(&object, &MyQObject::fooChanged);
+
+ // If we bypass the bindings system,
+ object.fooData.setValueBypassingBindings(42);
+ // there is no change.
+ QCOMPARE(fooChangeCount, 0);
+ QCOMPARE(fooChangedSpy.size(), 0);
+ // Once we notify manually
+ object.fooData.notify();
+ // observers are notified and the signal arrives.
+ QCOMPARE(fooChangeCount, 1);
+ QCOMPARE(fooChangedSpy.size(), 1);
+
+ // If we set a binding
+ int i = 1;
+ object.fooData.setBinding([&](){return i;});
+ // then the value changes
+ QCOMPARE(object.foo(), 1);
+ // and the change and signal count are incremented.
+ QCOMPARE(fooChangeCount, 2);
+ QCOMPARE(fooChangedSpy.size(), 2);
+ // Changing a non-property won't trigger any notification.
+ i = 2;
+ QCOMPARE(fooChangeCount, 2);
+ QCOMPARE(fooChangedSpy.size(), 2);
+ // Manually triggering the notification
+ object.fooData.notify();
+ // increments the change count
+ QCOMPARE(fooChangeCount, 3);
+ QCOMPARE(fooChangedSpy.size(), 3);
+ // but doesn't actually cause a binding reevaluation.
+ QCOMPARE(object.foo(), 1);
+}
+
+
+struct ReallocObject : QObject {
+ ReallocObject()
+ { v.setBinding([this] { return x.value() + y.value() + z.value(); }); }
+ Q_OBJECT_BINDABLE_PROPERTY(ReallocObject, int, v)
+ Q_OBJECT_BINDABLE_PROPERTY(ReallocObject, int, x)
+ Q_OBJECT_BINDABLE_PROPERTY(ReallocObject, int, y)
+ Q_OBJECT_BINDABLE_PROPERTY(ReallocObject, int, z)
+};
+
+void tst_QProperty::qobjectBindableReallocatedBindingStorage()
+{
+ ReallocObject object;
+ object.x = 1;
+ QCOMPARE(object.v.value(), 1);
+}
+
+void tst_QProperty::qobjectBindableSignalTakingNewValue()
+{
+ // Given an object of type MyQObject,
+ MyQObject object;
+ // and tracking the values emitted via its fooChanged signal,
+ int newValue = -1;
+ QObject::connect(&object, &MyQObject::fooChanged, [&](int i){ newValue = i; } );
+
+ // when we change the property's value via the bindable interface
+ object.bindableFoo().setValue(1);
+ // we obtain the newly set value.
+ QCOMPARE(newValue, 1);
+
+ // The same holds true when we set a binding
+ QProperty<int> i {2};
+ object.bindableFoo().setBinding(Qt::makePropertyBinding(i));
+ QCOMPARE(newValue, 2);
+ // and when the binding gets reevaluated to a new value
+ i = 3;
+ QCOMPARE(newValue, 3);
+}
+
+void tst_QProperty::testNewStuff()
+{
+ MyQObject testReadOnly;
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "setBinding: Could not set binding via bindable interface. The QBindable is read-only.");
+#endif
+ testReadOnly.bindableFoo().setBinding([](){return 42;});
+ auto bindable = const_cast<const MyQObject&>(testReadOnly).bindableFoo();
+ QVERIFY(bindable.hasBinding());
+ QVERIFY(bindable.isReadOnly());
+
+ MyQObject object;
+ QVERIFY(!object.bindableFoo().isReadOnly());
+ QObject::connect(&object, &MyQObject::fooChanged, &object, &MyQObject::fooHasChanged);
+ QObject::connect(&object, &MyQObject::barChanged, &object, &MyQObject::barHasChanged);
+
+ QCOMPARE(object.fooChangedCount, 0);
+ object.setFoo(10);
+ QCOMPARE(object.fooChangedCount, 1);
+ QCOMPARE(object.foo(), 10);
+
+ auto f = [&object]() -> int {
+ return object.barData;
+ };
+ QCOMPARE(object.barChangedCount, 0);
+ object.setBar(42);
+ QCOMPARE(object.barChangedCount, 1);
+ QCOMPARE(object.fooChangedCount, 1);
+ object.fooData.setBinding(f);
+ QCOMPARE(object.fooChangedCount, 2);
+ QCOMPARE(object.fooData.value(), 42);
+ object.setBar(666);
+ QCOMPARE(object.fooChangedCount, 3);
+ QCOMPARE(object.barChangedCount, 2);
+ QCOMPARE(object.fooData.value(), 666);
+ QCOMPARE(object.fooChangedCount, 3);
+
+ auto f2 = [&object]() -> int {
+ return object.barData / 2;
+ };
+
+ object.bindableFoo().setBinding(Qt::makePropertyBinding(f2));
+ QVERIFY(object.bindableFoo().hasBinding());
+ QCOMPARE(object.foo(), 333);
+ auto oldBinding = object.bindableFoo().setBinding(QPropertyBinding<int>());
+ QVERIFY(!object.bindableFoo().hasBinding());
+ QVERIFY(!oldBinding.isNull());
+ QCOMPARE(object.foo(), 333);
+ object.setBar(222);
+ QCOMPARE(object.foo(), 333);
+ object.bindableFoo().setBinding(oldBinding);
+ QCOMPARE(object.foo(), 111);
+
+ auto b = object.bindableRead().makeBinding();
+ object.bindableFoo().setBinding(b);
+ QCOMPARE(object.foo(), 0);
+ object.readData.setValue(10);
+ QCOMPARE(object.foo(), 10);
+
+ QCOMPARE(object.computed(), 10);
+ object.readData.setValue(42);
+ QCOMPARE(object.computed(), 42);
+
+ object.bindableBar().setBinding(object.bindableComputed().makeBinding());
+ QCOMPARE(object.computed(), 42);
+ object.readData.setValue(111);
+ QCOMPARE(object.computed(), 111);
+
+ object.bindableComputed().setBinding(object.bindableBar().makeBinding());
+ QCOMPARE(object.computed(), 111);
+ object.bindableComputed().setValue(10);
+ QCOMPARE(object.computed(), 111);
+
+ QCOMPARE(object.bindableFoo().value(), 111);
+ object.bindableFoo().setValue(24);
+ QCOMPARE(object.foo(), 24);
+
+ auto isCurrentlyEvaluatingBinding = []() {
+ return QtPrivate::isAnyBindingEvaluating();
+ };
+ QVERIFY(!isCurrentlyEvaluatingBinding());
+ QProperty<bool> evaluationDetector {false};
+ evaluationDetector.setBinding(isCurrentlyEvaluatingBinding);
+ QVERIFY(evaluationDetector.value());
+ QVERIFY(!isCurrentlyEvaluatingBinding());
+}
+
+void tst_QProperty::qobjectObservers()
+{
+ MyQObject object;
+ int onValueChangedCalled = 0;
+ {
+ auto handler = object.bindableFoo().onValueChanged([&onValueChangedCalled]() {
+ ++onValueChangedCalled;
+ });
+ QCOMPARE(onValueChangedCalled, 0);
+
+ object.setFoo(10);
+ QCOMPARE(onValueChangedCalled, 1);
+
+ object.bindableFoo().setBinding(object.bindableBar().makeBinding());
+ QCOMPARE(onValueChangedCalled, 2);
+
+ object.setBar(42);
+ QCOMPARE(onValueChangedCalled, 3);
+ }
+ object.setBar(0);
+ QCOMPARE(onValueChangedCalled, 3);
+}
+
+void tst_QProperty::compatBindings()
+{
+ MyQObject object;
+ QObject::connect(&object, &MyQObject::fooChanged, &object, &MyQObject::fooHasChanged);
+ QObject::connect(&object, &MyQObject::barChanged, &object, &MyQObject::barHasChanged);
+ QObject::connect(&object, &MyQObject::compatChanged, &object, &MyQObject::compatHasChanged);
+
+ QCOMPARE(object.compatData, 0);
+ // setting data through the private interface should not call the changed signal or the public setter
+ object.compatData.setValue(10);
+ QCOMPARE(object.compatChangedCount, 0);
+ QCOMPARE(object.setCompatCalled, 0);
+ // going through the public API should emit the signal
+ object.setCompat(42);
+ QCOMPARE(object.compatChangedCount, 1);
+ QCOMPARE(object.setCompatCalled, 1);
+
+ // setting the same value again does nothing
+ object.setCompat(42);
+ QCOMPARE(object.compatChangedCount, 1);
+ QCOMPARE(object.setCompatCalled, 1);
+
+ object.setFoo(111);
+ // just setting the binding. For a compat property, this should already trigger evaluation
+ object.compatData.setBinding(object.bindableFoo().makeBinding());
+ QCOMPARE(object.compatData.valueBypassingBindings(), 111);
+ QCOMPARE(object.compatChangedCount, 2);
+ QCOMPARE(object.setCompatCalled, 2);
+
+ QCOMPARE(object.compat(), 111);
+ QCOMPARE(object.compatChangedCount, 2);
+ QCOMPARE(object.setCompatCalled, 2);
+
+ object.setFoo(666);
+ QCOMPARE(object.compatData.valueBypassingBindings(), 666);
+ QCOMPARE(object.compatChangedCount, 3);
+ QCOMPARE(object.setCompatCalled, 3);
+
+ QCOMPARE(object.compat(), 666);
+ QCOMPARE(object.compatChangedCount, 3);
+ QCOMPARE(object.setCompatCalled, 3);
+
+ object.setFoo(-42);
+ QCOMPARE(object.compatChangedCount, 4);
+ QCOMPARE(object.setCompatCalled, 4);
+
+ QCOMPARE(object.compat(), 0);
+ QCOMPARE(object.compatChangedCount, 4);
+ QCOMPARE(object.setCompatCalled, 4);
+
+ object.setCompat(0);
+ QCOMPARE(object.compat(), 0);
+ QCOMPARE(object.compatChangedCount, 4);
+ QCOMPARE(object.setCompatCalled, 4);
+}
+
+void tst_QProperty::metaProperty()
+{
+ MyQObject object;
+ QObject::connect(&object, &MyQObject::fooChanged, &object, &MyQObject::fooHasChanged);
+ QObject::connect(&object, &MyQObject::barChanged, &object, &MyQObject::barHasChanged);
+ QObject::connect(&object, &MyQObject::compatChanged, &object, &MyQObject::compatHasChanged);
+
+ QCOMPARE(object.fooChangedCount, 0);
+ object.setFoo(10);
+ QCOMPARE(object.fooChangedCount, 1);
+ QCOMPARE(object.foo(), 10);
+
+ auto f = [&object]() -> int {
+ return object.barData;
+ };
+ QCOMPARE(object.barChangedCount, 0);
+ object.setBar(42);
+ QCOMPARE(object.barChangedCount, 1);
+ QCOMPARE(object.fooChangedCount, 1);
+ int fooIndex = object.metaObject()->indexOfProperty("foo");
+ QVERIFY(fooIndex >= 0);
+ QMetaProperty fooProp = object.metaObject()->property(fooIndex);
+ QVERIFY(fooProp.isValid());
+ auto fooBindable = fooProp.bindable(&object);
+ QVERIFY(fooBindable.isValid());
+ QVERIFY(fooBindable.isBindable());
+ QVERIFY(!fooBindable.hasBinding());
+ fooBindable.setBinding(Qt::makePropertyBinding(f));
+ QVERIFY(fooBindable.hasBinding());
+ QCOMPARE(object.fooChangedCount, 2);
+ QCOMPARE(object.fooData.value(), 42);
+ object.setBar(666);
+ QCOMPARE(object.fooChangedCount, 3);
+ QCOMPARE(object.barChangedCount, 2);
+ QCOMPARE(object.fooData.value(), 666);
+ QCOMPARE(object.fooChangedCount, 3);
+
+ fooBindable.setBinding(QUntypedPropertyBinding());
+ QVERIFY(!fooBindable.hasBinding());
+ QCOMPARE(object.fooData.value(), 666);
+
+ object.setBar(0);
+ QCOMPARE(object.fooData.value(), 666);
+ object.setFoo(1);
+ QCOMPARE(object.fooData.value(), 1);
+}
+
+void tst_QProperty::modifyObserverListWhileIterating()
+{
+ struct DestructingObserver : QPropertyObserver {
+ DestructingObserver() : QPropertyObserver([](QPropertyObserver *self, QUntypedPropertyData *) {
+ auto This = static_cast<DestructingObserver *>(self);
+ (*This)();
+ }), m_target(this){}
+ void operator()() {
+ (*counter)++;
+ std::destroy_at(m_target);
+ }
+ DestructingObserver *m_target;
+ int *counter = nullptr;
+ };
+ union ObserverOrUninit {
+ DestructingObserver observer = {};
+ char* memory;
+ ~ObserverOrUninit() {}
+ ObserverOrUninit() {}
+ };
+ {
+ // observer deletes itself while running the notification
+ // while explicitly calling the destructor is rather unusual
+ // it is completely plausible for this to happen because the object to which a
+ // propertyobserver belongs has been destroyed
+ ObserverOrUninit data;
+ int counter = 0;
+ data.observer.counter = &counter;
+ QProperty<int> prop;
+ QUntypedBindable bindableProp(&prop);
+ bindableProp.observe(&data.observer);
+ prop = 42; // should not crash
+ QCOMPARE(counter, 1);
+ }
+ {
+ // observer deletes the next observer in the list
+ ObserverOrUninit data1;
+ ObserverOrUninit data2;
+ QProperty<int> prop;
+ QUntypedBindable bindableProp(&prop);
+ bindableProp.observe(&data1.observer);
+ bindableProp.observe(&data2.observer);
+ int counter = 0;
+ data1.observer.m_target = &data2.observer;
+ data1.observer.counter = &counter;
+ data2.observer.m_target = &data1.observer;
+ data2.observer.counter = &counter;
+ prop = 42; // should not crash
+ QCOMPARE(counter, 1); // only one trigger should run as the other has been deleted
+ }
+}
+
+void tst_QProperty::noDoubleCapture()
+{
+ QProperty<long long> size;
+ size = 3;
+ QProperty<int> max;
+ max.setBinding([&size]() -> int {
+ // each loop run attempts to capture size
+ for (int i = 0; i < size; ++i) {}
+ return size.value();
+ });
+ auto bindingPriv = QPropertyBindingPrivate::get(max.binding());
+ QCOMPARE(bindingPriv->dependencyObserverCount, 1U);
+ size = 4; // should not crash
+ QCOMPARE(max.value(), 4);
+}
+
+class CompatPropertyTester : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int prop1 READ prop1 WRITE setProp1 BINDABLE bindableProp1)
+ Q_PROPERTY(int prop2 READ prop2 WRITE setProp2 NOTIFY prop2Changed BINDABLE bindableProp2)
+ Q_PROPERTY(int prop3 READ prop3 WRITE setProp3 NOTIFY prop3Changed BINDABLE bindableProp3)
+ Q_PROPERTY(int prop4 READ prop4 WRITE setProp4 NOTIFY prop4Changed BINDABLE bindableProp4)
+public:
+ CompatPropertyTester(QObject *parent = nullptr) : QObject(parent) { }
+
+ int prop1() {return prop1Data.value();}
+ void setProp1(int i) { if (i == prop1Data) return; prop1Data.setValue(i); prop1Data.notify(); }
+ QBindable<int> bindableProp1() {return QBindable<int>(&prop1Data);}
+
+ int prop2() { return prop2Data.value(); }
+ void setProp2(int i)
+ {
+ if (i == prop2Data)
+ return;
+ prop2Data.setValue(i);
+ prop2Data.notify();
+ }
+ QBindable<int> bindableProp2() { return QBindable<int>(&prop2Data); }
+
+ int prop3() { return prop3Data.value(); }
+ void setProp3(int i)
+ {
+ if (i == prop3Data)
+ return;
+ prop3Data.setValue(i);
+ prop3Data.notify();
+ }
+ QBindable<int> bindableProp3() { return QBindable<int>(&prop3Data); }
+
+ int prop4() const
+ {
+ auto val = prop4Data.value();
+ return val == 0 ? 42 : val;
+ }
+
+ void setProp4(int i)
+ {
+ if (i == prop4Data)
+ return;
+ prop4Data.setValue(i);
+ prop4Data.notify();
+ }
+ QBindable<int> bindableProp4() { return QBindable<int>(&prop4Data); }
+
+signals:
+ void prop2Changed(int value);
+ void prop3Changed();
+ void prop4Changed(int value);
+
+private:
+ Q_OBJECT_COMPAT_PROPERTY(CompatPropertyTester, int, prop1Data, &CompatPropertyTester::setProp1)
+ Q_OBJECT_COMPAT_PROPERTY(CompatPropertyTester, int, prop2Data, &CompatPropertyTester::setProp2,
+ &CompatPropertyTester::prop2Changed)
+ Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(CompatPropertyTester, int, prop3Data,
+ &CompatPropertyTester::setProp3,
+ &CompatPropertyTester::prop3Changed, 1)
+ Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(CompatPropertyTester, int, prop4Data,
+ &CompatPropertyTester::setProp4,
+ &CompatPropertyTester::prop4Changed,
+ &CompatPropertyTester::prop4, 0)
+};
+
+void tst_QProperty::compatPropertyNoDobuleNotification()
+{
+ CompatPropertyTester tester;
+ int counter = 0;
+ QProperty<int> iprop {1};
+ tester.bindableProp1().setBinding([&]() -> int {return iprop;});
+ auto observer = tester.bindableProp1().onValueChanged([&](){++counter;});
+ iprop.setValue(2);
+ QCOMPARE(counter, 1);
+}
+
+void tst_QProperty::compatPropertySignals()
+{
+ CompatPropertyTester tester;
+
+ // Compat property with signal. Signal has parameter.
+ QProperty<int> prop2Observer;
+ prop2Observer.setBinding(tester.bindableProp2().makeBinding());
+
+ QSignalSpy prop2Spy(&tester, &CompatPropertyTester::prop2Changed);
+
+ tester.setProp2(10);
+
+ QCOMPARE(prop2Observer.value(), 10);
+ QCOMPARE(prop2Spy.size(), 1);
+ QList<QVariant> arguments = prop2Spy.takeFirst();
+ QCOMPARE(arguments.size(), 1);
+ QCOMPARE(arguments.at(0).metaType().id(), QMetaType::Int);
+ QCOMPARE(arguments.at(0).toInt(), 10);
+
+ // Compat property with signal and default value. Signal has no parameter.
+ QProperty<int> prop3Observer;
+ prop3Observer.setBinding(tester.bindableProp3().makeBinding());
+ QCOMPARE(prop3Observer.value(), 1);
+
+ QSignalSpy prop3Spy(&tester, &CompatPropertyTester::prop3Changed);
+
+ tester.setProp3(5);
+
+ QCOMPARE(prop3Observer.value(), 5);
+ QCOMPARE(prop3Spy.size(), 1);
+
+ // Compat property with signal, default value, and custom setter. Signal has parameter.
+ QProperty<int> prop4Observer;
+ prop4Observer.setBinding(tester.bindableProp4().makeBinding());
+ QCOMPARE(prop4Observer.value(), 42);
+
+ QSignalSpy prop4Spy(&tester, &CompatPropertyTester::prop4Changed);
+
+ tester.setProp4(10);
+
+ QCOMPARE(prop4Observer.value(), 10);
+ QCOMPARE(prop4Spy.size(), 1);
+ arguments = prop4Spy.takeFirst();
+ QCOMPARE(arguments.size(), 1);
+ QCOMPARE(arguments.at(0).metaType().id(), QMetaType::Int);
+ QCOMPARE(arguments.at(0).toInt(), 10);
+
+ tester.setProp4(42);
+
+ QCOMPARE(prop4Observer.value(), 42);
+ QCOMPARE(prop4Spy.size(), 1);
+ arguments = prop4Spy.takeFirst();
+ QCOMPARE(arguments.size(), 1);
+ QCOMPARE(arguments.at(0).metaType().id(), QMetaType::Int);
+ QCOMPARE(arguments.at(0).toInt(), 42);
+
+ tester.setProp4(0);
+
+ QCOMPARE(prop4Observer.value(), 42);
+ QCOMPARE(prop4Spy.size(), 1);
+ arguments = prop4Spy.takeFirst();
+ QCOMPARE(arguments.size(), 1);
+ QCOMPARE(arguments.at(0).metaType().id(), QMetaType::Int);
+ QCOMPARE(arguments.at(0).toInt(), 42);
+}
+
+class FakeDependencyCreator : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int prop1 READ prop1 WRITE setProp1 NOTIFY prop1Changed BINDABLE bindableProp1)
+ Q_PROPERTY(int prop2 READ prop2 WRITE setProp2 NOTIFY prop2Changed BINDABLE bindableProp2)
+ Q_PROPERTY(int prop3 READ prop3 WRITE setProp3 NOTIFY prop3Changed BINDABLE bindableProp3)
+
+signals:
+ void prop1Changed();
+ void prop2Changed();
+ void prop3Changed();
+
+public:
+ void setProp1(int val) { prop1Data.setValue(val); prop1Data.notify();}
+ void setProp2(int val) { prop2Data.setValue(val); prop2Data.notify();}
+ void setProp3(int val) { prop3Data.setValue(val); prop3Data.notify();}
+
+ int prop1() { return prop1Data; }
+ int prop2() { return prop2Data; }
+ int prop3() { return prop3Data; }
+
+ QBindable<int> bindableProp1() { return QBindable<int>(&prop1Data); }
+ QBindable<int> bindableProp2() { return QBindable<int>(&prop2Data); }
+ QBindable<int> bindableProp3() { return QBindable<int>(&prop3Data); }
+
+private:
+ Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop1Data, &FakeDependencyCreator::setProp1, &FakeDependencyCreator::prop1Changed);
+ Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop2Data, &FakeDependencyCreator::setProp2, &FakeDependencyCreator::prop2Changed);
+ Q_OBJECT_COMPAT_PROPERTY(FakeDependencyCreator, int, prop3Data, &FakeDependencyCreator::setProp3, &FakeDependencyCreator::prop3Changed);
+};
+
+void tst_QProperty::noFakeDependencies()
+{
+ FakeDependencyCreator fdc;
+ int bindingFunctionCalled = 0;
+ fdc.bindableProp1().setBinding([&]() -> int {++bindingFunctionCalled; return fdc.prop2();});
+ fdc.setProp2(42);
+ QCOMPARE(fdc.prop1(), 42); // basic binding works
+
+ int slotCounter = 0;
+ QObject::connect(&fdc, &FakeDependencyCreator::prop1Changed, &fdc, [&](){ (void) fdc.prop3(); ++slotCounter;});
+ fdc.setProp2(13);
+ QCOMPARE(slotCounter, 1); // sanity check
+ int old = bindingFunctionCalled;
+ fdc.setProp3(100);
+ QCOMPARE(old, bindingFunctionCalled);
+}
+
+class PropertyAdaptorTester : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int foo READ foo WRITE setFoo NOTIFY fooChanged)
+ Q_PROPERTY(int foo1 READ foo WRITE setFoo)
+
+signals:
+ void dummySignal1();
+ void dummySignal2();
+ void dummySignal3();
+ void dummySignal4();
+ void dummySignal5();
+ void dummySignal6();
+ void dummySignal7();
+ void dummySignal8();
+ void fooChanged(int newFoo);
+
+public slots:
+ void fooHasChanged() { fooChangedCount++; }
+
+public:
+ int foo() const { return fooData; }
+ void setFoo(int i)
+ {
+ if (i != fooData) {
+ fooData = i;
+ fooChanged(fooData);
+ }
+ }
+
+public:
+ int fooData = 0;
+ int fooChangedCount = 0;
+};
+
+void tst_QProperty::propertyAdaptorBinding()
+{
+ QProperty<int> source { 5 };
+ QProperty<int> dest1 { 99 };
+ QProperty<int> dest2 { 98 };
+
+ // Check binding of non BINDABLE property
+ PropertyAdaptorTester object;
+ // set up a dummy connection (needed to verify that the QBindable avoids an out-of-bounds read)
+ QObject::connect(&object, &PropertyAdaptorTester::dummySignal1, [](){});
+ QBindable<int> binding(&object, "foo");
+ QObject::connect(&object, &PropertyAdaptorTester::fooChanged, &object,
+ &PropertyAdaptorTester::fooHasChanged);
+ binding.setBinding([&]() { return source + 1; });
+ QCOMPARE(object.foo(), 6);
+ QCOMPARE(object.fooChangedCount, 1);
+
+ struct MyBindable : QBindable<int> {
+ using QBindable<int>::QBindable;
+ QtPrivate::QPropertyAdaptorSlotObject* data() {
+ return static_cast<QtPrivate::QPropertyAdaptorSlotObject*>(QUntypedBindable::data);
+ }
+ } dataBinding(&object, "foo");
+ QPropertyBindingDataPointer data{&dataBinding.data()->bindingData()};
+
+ QCOMPARE(data.observerCount(), 0);
+ dest1.setBinding(binding.makeBinding());
+ QCOMPARE(data.observerCount(), 1);
+ dest2.setBinding([=]() { return binding.value() + 1; });
+ binding = {};
+ QCOMPARE(data.observerCount(), 2);
+
+ // Check addNotifer
+ {
+ int local_foo = 0;
+ auto notifier = QBindable<int>(&object, "foo").addNotifier([&]() { local_foo++; });
+ QCOMPARE(data.observerCount(), 3);
+ QCOMPARE(object.foo(), 6);
+ QCOMPARE(dest1.value(), 6);
+ QCOMPARE(dest2.value(), 7);
+ QCOMPARE(local_foo, 0);
+ QCOMPARE(object.fooChangedCount, 1);
+
+ source = 7;
+ QCOMPARE(object.foo(), 8);
+ QCOMPARE(dest1.value(), 8);
+ QCOMPARE(dest2.value(), 9);
+ QCOMPARE(local_foo, 1);
+ QCOMPARE(object.fooChangedCount, 2);
+ }
+
+ QCOMPARE(data.observerCount(), 2);
+
+ // Check a new QBindable object can override the existing binding
+ QBindable<int>(&object, "foo").setValue(10);
+ QCOMPARE(object.foo(), 10);
+ QCOMPARE(dest1.value(), 10);
+ QCOMPARE(dest2.value(), 11);
+ QCOMPARE(object.fooChangedCount, 3);
+ source.setValue(99);
+ QCOMPARE(object.foo(), 10);
+ QCOMPARE(dest1.value(), 10);
+ QCOMPARE(dest2.value(), 11);
+ QCOMPARE(object.fooChangedCount, 3);
+ object.setFoo(12);
+ QCOMPARE(object.foo(), 12);
+ QCOMPARE(dest1.value(), 12);
+ QCOMPARE(dest2.value(), 13);
+ QCOMPARE(object.fooChangedCount, 4);
+
+ // Check binding multiple notifiers
+ QProperty<int> source2 { 20 };
+ source.setValue(21);
+ binding = QBindable<int>(&object, "foo");
+ binding.setBinding([&]() { return source + source2; });
+ QCOMPARE(object.foo(), 41);
+ QCOMPARE(dest1.value(), 41);
+ QCOMPARE(object.fooChangedCount, 5);
+ source.setValue(22);
+ QCOMPARE(object.foo(), 42);
+ QCOMPARE(dest1.value(), 42);
+ QCOMPARE(object.fooChangedCount, 6);
+ source2.setValue(21);
+ QCOMPARE(object.foo(), 43);
+ QCOMPARE(dest1.value(), 43);
+ QCOMPARE(object.fooChangedCount, 7);
+
+ // Check update group
+ {
+ const QScopedPropertyUpdateGroup guard;
+ source.setValue(23);
+ source2.setValue(22);
+ QCOMPARE(object.foo(), 43);
+ QCOMPARE(dest1.value(), 43);
+ QCOMPARE(object.fooChangedCount, 7);
+ }
+ QCOMPARE(object.foo(), 45);
+ QCOMPARE(dest1.value(), 45);
+ QCOMPARE(object.fooChangedCount, 8);
+
+ PropertyAdaptorTester object2;
+ PropertyAdaptorTester object3;
+
+ // Check multiple observers
+ QBindable<int> binding2(&object2, "foo");
+ QBindable<int> binding3(&object3, "foo");
+ binding.setBinding([=]() { return binding2.value(); });
+ binding3.setBinding([=]() { return binding.value(); });
+ QCOMPARE(object.foo(), 0);
+ QCOMPARE(object2.foo(), 0);
+ QCOMPARE(object3.foo(), 0);
+ QCOMPARE(dest1.value(), 0);
+ object2.setFoo(1);
+ QCOMPARE(object.foo(), 1);
+ QCOMPARE(object2.foo(), 1);
+ QCOMPARE(object3.foo(), 1);
+ QCOMPARE(dest1.value(), 1);
+
+ // Check interoperation with BINDABLE properties
+ MyQObject bindableObject;
+ bindableObject.fooData.setBinding([]() { return 5; });
+ QVERIFY(bindableObject.fooData.hasBinding());
+ QVERIFY(!bindableObject.barData.hasBinding());
+ QVERIFY(QBindable<int>(&bindableObject, "foo").hasBinding());
+ QBindable<int> bindableBar(&bindableObject, "bar");
+ QVERIFY(!bindableBar.hasBinding());
+ bindableBar.setBinding([]() { return 6; });
+ QVERIFY(bindableBar.hasBinding());
+ QVERIFY(bindableObject.barData.hasBinding());
+
+ // Check bad arguments
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QUntypedBindable: Property is not valid");
+#endif
+ QVERIFY(!QBindable<int>(&object, QMetaProperty{}).isValid());
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QUntypedBindable: Property foo1 has no notify signal");
+#endif
+ QVERIFY(!QBindable<int>(&object, "foo1").isValid());
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QUntypedBindable: Property foo of type int does not match requested type bool");
+#endif
+ QVERIFY(!QBindable<bool>(&object, "foo").isValid());
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg,
+ "QUntypedBindable: Property foo does not belong to this object");
+#endif
+ QObject qobj;
+ QVERIFY(!QBindable<int>(
+ &qobj,
+ object.metaObject()->property(object.metaObject()->indexOfProperty("foo")))
+ .isValid());
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QUntypedBindable: No property named fizz");
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QUntypedBindable: Property is not valid");
+#endif
+ QVERIFY(!QBindable<int>(&object, "fizz").isValid());
+}
+
+#if QT_CONFIG(thread)
+struct ThreadSafetyTester : public QObject
+{
+ Q_OBJECT
+
+public:
+ ThreadSafetyTester(QObject *parent = nullptr) : QObject(parent) {}
+
+ Q_INVOKABLE bool hasCorrectStatus() const
+ {
+ return qGetBindingStorage(this)->status({}) == QtPrivate::getBindingStatus({});
+ }
+
+ Q_INVOKABLE bool bindingTest()
+ {
+ QProperty<QString> name(u"inThread"_s);
+ bindableObjectName().setBinding([&]() -> QString { return name; });
+ name = u"inThreadChanged"_s;
+ const bool nameChangedCorrectly = objectName() == name;
+ bindableObjectName().takeBinding();
+ return nameChangedCorrectly;
+ }
+};
+
+
+void tst_QProperty::threadSafety()
+{
+ QThread workerThread;
+ auto cleanup = qScopeGuard([&](){
+ QMetaObject::invokeMethod(&workerThread, "quit");
+ workerThread.wait();
+ });
+ QScopedPointer<ThreadSafetyTester> scopedObj1(new ThreadSafetyTester);
+ auto obj1 = scopedObj1.data();
+ auto child1 = new ThreadSafetyTester(obj1);
+ obj1->moveToThread(&workerThread);
+ const auto mainThreadBindingStatus = QtPrivate::getBindingStatus({});
+ QCOMPARE(qGetBindingStorage(child1)->status({}), nullptr);
+ workerThread.start();
+
+ bool correctStatus = false;
+ bool ok = QMetaObject::invokeMethod(obj1, "hasCorrectStatus", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, correctStatus));
+ QVERIFY(ok);
+ QVERIFY(correctStatus);
+
+ bool bindingWorks = false;
+ ok = QMetaObject::invokeMethod(obj1, "bindingTest", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, bindingWorks));
+ QVERIFY(ok);
+ QVERIFY(bindingWorks);
+
+ correctStatus = false;
+ ok = QMetaObject::invokeMethod(child1, "hasCorrectStatus", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, correctStatus));
+ QVERIFY(ok);
+ QVERIFY(correctStatus);
+
+ QScopedPointer scopedObj2(new ThreadSafetyTester);
+ auto obj2 = scopedObj2.data();
+ QCOMPARE(qGetBindingStorage(obj2)->status({}), mainThreadBindingStatus);
+
+ obj2->setObjectName("moved");
+ QCOMPARE(obj2->objectName(), "moved");
+
+ obj2->moveToThread(&workerThread);
+ correctStatus = false;
+ ok = QMetaObject::invokeMethod(obj2, "hasCorrectStatus", Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, correctStatus));
+
+ QVERIFY(ok);
+ QVERIFY(correctStatus);
+ // potentially unsafe, but should still work (no writes in owning thread)
+ QCOMPARE(obj2->objectName(), "moved");
+
+
+ QScopedPointer scopedObj3(new ThreadSafetyTester);
+ auto obj3 = scopedObj3.data();
+ obj3->setObjectName("moved");
+ QCOMPARE(obj3->objectName(), "moved");
+ obj3->moveToThread(nullptr);
+ QCOMPARE(obj2->objectName(), "moved");
+ obj3->setObjectName("moved again");
+ QCOMPARE(obj3->objectName(), "moved again");
+}
+
+class QPropertyUsingThread : public QThread
+{
+public:
+ QPropertyUsingThread(QObject **dest, QThread *destThread) : dest(dest), destThread(destThread) {}
+ void run() override
+ {
+ scopedObj1.reset(new ThreadSafetyTester());
+ scopedObj1->setObjectName("test");
+ QObject *child = new ThreadSafetyTester(scopedObj1.get());
+ child->setObjectName("child");
+ exec();
+ scopedObj1->moveToThread(destThread);
+ *dest = scopedObj1.release();
+ }
+ std::unique_ptr<ThreadSafetyTester> scopedObj1;
+ QObject **dest;
+ QThread *destThread;
+};
+
+void tst_QProperty::threadSafety2()
+{
+ std::unique_ptr<QObject> movedObj;
+ {
+ QObject *tmp = nullptr;
+ QPropertyUsingThread workerThread(&tmp, QThread::currentThread());
+ workerThread.start();
+ workerThread.quit();
+ workerThread.wait();
+ movedObj.reset(tmp);
+ }
+
+ QCOMPARE(movedObj->objectName(), "test");
+ QCOMPARE(movedObj->children().first()->objectName(), "child");
+}
+#endif // QT_CONFIG(thread)
+
+struct CustomType
+{
+ CustomType() = default;
+ CustomType(int val) : value(val) { }
+ CustomType(int val, int otherVal) : value(val), anotherValue(otherVal) { }
+ CustomType(const CustomType &) = default;
+ CustomType(CustomType &&) = default;
+ ~CustomType() = default;
+ CustomType &operator=(const CustomType &) = default;
+ CustomType &operator=(CustomType &&) = default;
+ bool operator==(const CustomType &other) const
+ {
+ return (value == other.value) && (anotherValue == other.anotherValue);
+ }
+
+ int value = 0;
+ int anotherValue = 0;
+};
+
+class PropertyWithInitializationTester : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int prop1 READ prop1 WRITE setProp1 NOTIFY prop1Changed BINDABLE bindableProp1)
+ Q_PROPERTY(CustomType prop2 READ prop2 WRITE setProp2 BINDABLE bindableProp2)
+ Q_PROPERTY(CustomType prop3 READ prop3 WRITE setProp3 BINDABLE bindableProp3)
+signals:
+ void prop1Changed();
+
+public:
+ PropertyWithInitializationTester(QObject *parent = nullptr) : QObject(parent) { }
+
+ int prop1() { return prop1Data.value(); }
+ void setProp1(int i) { prop1Data = i; }
+ QBindable<int> bindableProp1() { return QBindable<int>(&prop1Data); }
+
+ CustomType prop2() { return prop2Data.value(); }
+ void setProp2(CustomType val) { prop2Data = val; }
+ QBindable<CustomType> bindableProp2() { return QBindable<CustomType>(&prop2Data); }
+
+ CustomType prop3() { return prop3Data.value(); }
+ void setProp3(CustomType val) { prop3Data.setValue(val); }
+ QBindable<CustomType> bindableProp3() { return QBindable<CustomType>(&prop3Data); }
+
+ Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(PropertyWithInitializationTester, int, prop1Data, 5,
+ &PropertyWithInitializationTester::prop1Changed)
+ Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(PropertyWithInitializationTester, CustomType, prop2Data,
+ CustomType(5))
+ Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(PropertyWithInitializationTester, CustomType, prop3Data,
+ &PropertyWithInitializationTester::setProp3,
+ CustomType(10, 20))
+};
+
+void tst_QProperty::bindablePropertyWithInitialization()
+{
+ PropertyWithInitializationTester tester;
+
+ QCOMPARE(tester.prop1(), 5);
+ QCOMPARE(tester.prop2().value, 5);
+ QCOMPARE(tester.prop3().value, 10);
+ QCOMPARE(tester.prop3().anotherValue, 20);
+}
+
+void tst_QProperty::noDoubleNotification()
+{
+ /* dependency graph for this test
+ x --> y means y depends on x
+ a-->b-->d
+ \ ^
+ \->c--/
+ */
+ QProperty<int> a(0);
+ QProperty<int> b;
+ b.setBinding([&](){ return a.value(); });
+ QProperty<int> c;
+ c.setBinding([&](){ return a.value(); });
+ QProperty<int> d;
+ d.setBinding([&](){ return b.value() + c.value(); });
+ int nNotifications = 0;
+ int expected = 0;
+ auto connection = d.subscribe([&](){
+ ++nNotifications;
+ QCOMPARE(d.value(), expected);
+ });
+ QCOMPARE(nNotifications, 1);
+ expected = 2;
+ a = 1;
+ QCOMPARE(nNotifications, 2);
+ expected = 4;
+ a = 2;
+ QCOMPARE(nNotifications, 3);
+}
+
+void tst_QProperty::groupedNotifications()
+{
+ QProperty<int> a(0);
+ QProperty<int> b;
+ b.setBinding([&](){ return a.value(); });
+ QProperty<int> c;
+ c.setBinding([&](){ return a.value(); });
+ QProperty<int> d;
+ QProperty<int> e;
+ e.setBinding([&](){ return b.value() + c.value() + d.value(); });
+ int nNotifications = 0;
+ int expected = 0;
+ auto connection = e.subscribe([&](){
+ ++nNotifications;
+ QCOMPARE(e.value(), expected);
+ });
+ QCOMPARE(nNotifications, 1);
+
+ expected = 2;
+ {
+ const QScopedPropertyUpdateGroup guard;
+ a = 1;
+ QCOMPARE(b.value(), 0);
+ QCOMPARE(c.value(), 0);
+ QCOMPARE(d.value(), 0);
+ QCOMPARE(nNotifications, 1);
+ }
+ QCOMPARE(b.value(), 1);
+ QCOMPARE(c.value(), 1);
+ QCOMPARE(e.value(), 2);
+ QCOMPARE(nNotifications, 2);
+
+ expected = 7;
+ {
+ const QScopedPropertyUpdateGroup guard;
+ a = 2;
+ d = 3;
+ QCOMPARE(b.value(), 1);
+ QCOMPARE(c.value(), 1);
+ QCOMPARE(d.value(), 3);
+ QCOMPARE(nNotifications, 2);
+ }
+ QCOMPARE(b.value(), 2);
+ QCOMPARE(c.value(), 2);
+ QCOMPARE(e.value(), 7);
+ QCOMPARE(nNotifications, 3);
+
+
+}
+
+void tst_QProperty::groupedNotificationConsistency()
+{
+ QProperty<int> i(0);
+ QProperty<int> j(0);
+ bool areEqual = true;
+
+ auto observer = i.onValueChanged([&](){
+ areEqual = i == j;
+ });
+
+ i = 1;
+ j = 1;
+ QVERIFY(!areEqual); // value changed runs before j = 1
+
+ {
+ const QScopedPropertyUpdateGroup guard;
+ i = 2;
+ j = 2;
+ }
+ QVERIFY(areEqual); // value changed runs after everything has been evaluated
+}
+
+void tst_QProperty::bindingGroupMovingBindingData()
+{
+ auto tester = std::make_unique<ClassWithNotifiedProperty>();
+ auto testerPriv = QObjectPrivate::get(tester.get());
+
+ auto dummyNotifier = tester->property.addNotifier([](){});
+ auto bindingData = testerPriv->bindingStorage.bindingData(&tester->property);
+ QVERIFY(bindingData); // we have a notifier, so there should be binding data
+
+ Qt::beginPropertyUpdateGroup();
+ auto cleanup = qScopeGuard([](){ Qt::endPropertyUpdateGroup(); });
+ tester->property = 42;
+ QCOMPARE(testerPriv->bindingStorage.bindingData(&tester->property), bindingData);
+ auto proxyData = QPropertyBindingDataPointer::proxyData(bindingData);
+ // as we've modified the property, we now should have a proxy for the delayed notification
+ QVERIFY(proxyData);
+ // trigger binding data reallocation
+ std::array<QUntypedPropertyData, 10> propertyDataArray;
+ for (auto&& data: propertyDataArray)
+ testerPriv->bindingStorage.bindingData(&data, true);
+ // binding data has moved
+ QVERIFY(testerPriv->bindingStorage.bindingData(&tester->property) != bindingData);
+ bindingData = testerPriv->bindingStorage.bindingData(&tester->property);
+ // the proxy data has been updated
+ QCOMPARE(proxyData->originalBindingData, bindingData);
+
+ tester.reset();
+ // the property data is gone, proxyData should have been informed
+ QCOMPARE(proxyData->originalBindingData, nullptr);
+ QVERIFY(proxyData);
+}
+
+void tst_QProperty::bindingGroupBindingDeleted()
+{
+ auto deleter = std::make_unique<ClassWithNotifiedProperty>();
+ auto toBeDeleted = std::make_unique<ClassWithNotifiedProperty>();
+
+ bool calledHandler = false;
+ deleter->property.setBinding([&](){
+ int newValue = toBeDeleted->property;
+ if (newValue == 42)
+ toBeDeleted.reset();
+ return newValue;
+ });
+ auto handler = toBeDeleted->property.onValueChanged([&]() { calledHandler = true; } );
+ {
+ Qt::beginPropertyUpdateGroup();
+ auto cleanup = qScopeGuard([](){ Qt::endPropertyUpdateGroup(); });
+ QVERIFY(toBeDeleted);
+ toBeDeleted->property = 42;
+ // ASAN should not complain here
+ }
+ QVERIFY(!toBeDeleted);
+ // the change notification is sent, even if the binding is deleted during evaluation
+ QVERIFY(calledHandler);
+}
+
+void tst_QProperty::uninstalledBindingDoesNotEvaluate()
+{
+ QProperty<int> i;
+ QProperty<int> j;
+ int bindingEvaluationCounter = 0;
+ i.setBinding([&](){
+ bindingEvaluationCounter++;
+ return j.value();
+ });
+ QCOMPARE(bindingEvaluationCounter, 1);
+ // Sanity check: if we force a binding reevaluation,
+ j = 42;
+ // the binding function will be called again.
+ QCOMPARE(bindingEvaluationCounter, 2);
+ // If we keep referencing the binding
+ auto keptBinding = i.binding();
+ // but have it not installed on a property
+ i = 10;
+ QVERIFY(!i.hasBinding());
+ QVERIFY(!keptBinding.isNull());
+ // then changing a dependency
+ j = 12;
+ // does not lead to the binding being reevaluated.
+ QCOMPARE(bindingEvaluationCounter, 2);
+}
+
+void tst_QProperty::notify()
+{
+ QProperty<int> testProperty(0);
+ QList<int> recordedValues;
+ int value = 0;
+ QPropertyNotifier notifier;
+
+ {
+ QPropertyNotifier handler = testProperty.addNotifier([&]() {
+ recordedValues << testProperty;
+ });
+ notifier = testProperty.addNotifier([&]() {
+ value = testProperty;
+ });
+
+ testProperty = 1;
+ testProperty = 2;
+ }
+ QCOMPARE(value, 2);
+ testProperty = 3;
+ QCOMPARE(value, 3);
+ notifier = {};
+ testProperty = 4;
+ QCOMPARE(value, 3);
+
+ QCOMPARE(recordedValues.size(), 2);
+ QCOMPARE(recordedValues.at(0), 1);
+ QCOMPARE(recordedValues.at(1), 2);
+}
+
+void tst_QProperty::bindableInterfaceOfCompatPropertyUsesSetter()
+{
+ MyQObject obj;
+ QBindable<int> bindable = obj.bindableCompat();
+ QCOMPARE(obj.setCompatCalled, 0);
+ bindable.setValue(42);
+ QCOMPARE(obj.setCompatCalled, 1);
+}
+
+void tst_QProperty::selfBindingShouldNotCrash()
+{
+ QProperty<int> i;
+ i.setBinding([&](){ return i+1; });
+ QVERIFY(i.binding().error().hasError());
+}
+
+void tst_QProperty::qpropertyAlias()
+{
+#if QT_DEPRECATED_SINCE(6, 6)
+ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ std::unique_ptr<QProperty<int>> i {new QProperty<int>};
+ QPropertyAlias<int> alias(i.get());
+ QVERIFY(alias.isValid());
+ alias.setValue(42);
+ QCOMPARE(i->value(), 42);
+ QProperty<int> j;
+ bool notifierCalled = false;
+ auto myNotifier = alias.addNotifier([&](){notifierCalled = true;});
+ i->setBinding([&]() -> int { return j; });
+ QVERIFY(notifierCalled);
+ j.setValue(42);
+ QCOMPARE(alias.value(), 42);
+ i.reset();
+ QVERIFY(!alias.isValid());
+ QT_WARNING_POP
+#endif
+}
+
+void tst_QProperty::scheduleNotify()
+{
+ int notifications = 0;
+ QProperty<int> p;
+ QCOMPARE(p.value(), 0);
+ const auto handler = p.addNotifier([&](){ ++notifications; });
+ QCOMPARE(notifications, 0);
+ QPropertyBinding<int> b([]() { return 0; }, QPropertyBindingSourceLocation());
+ QPropertyBindingPrivate::get(b)->scheduleNotify();
+ QCOMPARE(notifications, 0);
+ p.setBinding(b);
+ QCOMPARE(notifications, 1);
+ QCOMPARE(p.value(), 0);
+}
+
+void tst_QProperty::notifyAfterAllDepsGone()
+{
+ bool b = true;
+ QProperty<int> iprop;
+ QProperty<int> jprop(42);
+ iprop.setBinding([&](){
+ if (b)
+ return jprop.value();
+ return 13;
+ });
+ int changeCounter = 0;
+ auto keepAlive = iprop.onValueChanged([&](){ changeCounter++; });
+ QCOMPARE(iprop.value(), 42);
+ jprop = 44;
+ QCOMPARE(iprop.value(), 44);
+ QCOMPARE(changeCounter, 1);
+ b = false;
+ jprop = 43;
+ QCOMPARE(iprop.value(), 13);
+ QCOMPARE(changeCounter, 2);
+}
+
+class TestObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int signaled READ signaled WRITE setSignaled NOTIFY signaledChanged FINAL)
+ Q_PROPERTY(int bindable1 READ bindable1 WRITE setBindable1 BINDABLE bindable1Bindable NOTIFY bindable1Changed FINAL)
+ Q_PROPERTY(int bindable2 READ bindable2 WRITE setBindable2 BINDABLE bindable2Bindable NOTIFY bindable2Changed FINAL)
+
+public:
+ int signaled() const
+ {
+ return m_signaled;
+ }
+
+ void setSignaled(int newSignaled)
+ {
+ if (m_signaled == newSignaled)
+ return;
+ m_signaled = newSignaled;
+ emit signaledChanged();
+ }
+
+ int bindable1() const
+ {
+ return m_bindable1;
+ }
+
+ void setBindable1(int newBindable1)
+ {
+ if (m_bindable1 == newBindable1)
+ return;
+ m_bindable1 = newBindable1;
+ emit bindable1Changed();
+ }
+
+ QBindable<int> bindable1Bindable()
+ {
+ return QBindable<int>(&m_bindable1);
+ }
+
+ int bindable2() const
+ {
+ return m_bindable2;
+ }
+
+ void setBindable2(int newBindable2)
+ {
+ if (m_bindable2 == newBindable2)
+ return;
+ m_bindable2 = newBindable2;
+ emit bindable2Changed();
+ }
+
+ QBindable<int> bindable2Bindable()
+ {
+ return QBindable<int>(&m_bindable2);
+ }
+
+signals:
+ void signaledChanged();
+ void bindable1Changed();
+ void bindable2Changed();
+
+private:
+ int m_signaled = 0;
+ Q_OBJECT_COMPAT_PROPERTY(TestObject, int, m_bindable1, &TestObject::setBindable1, &TestObject::bindable1Changed);
+ Q_OBJECT_COMPAT_PROPERTY(TestObject, int, m_bindable2, &TestObject::setBindable2, &TestObject::bindable2Changed);
+};
+
+void tst_QProperty::propertyUpdateViaSignaledProperty()
+{
+ TestObject o;
+ QProperty<int> rootTrigger;
+ QProperty<int> signalTrigger;
+
+ o.bindable1Bindable().setBinding([&]() {
+ return rootTrigger.value();
+ });
+
+ QObject::connect(&o, &TestObject::bindable1Changed, &o, [&]() {
+ // Signaled changes only once, doesn't actually depend on bindable1.
+ // In reality, there could be some complicated calculation behind this that changes
+ // on certain checkpoints, but not on every iteration.
+ o.setSignaled(40);
+ });
+
+ o.bindable2Bindable().setBinding([&]() {
+ return signalTrigger.value() - o.bindable1();
+ });
+
+ QObject::connect(&o, &TestObject::signaledChanged, &o, [&]() {
+ signalTrigger.setValue(o.signaled());
+ });
+
+ rootTrigger.setValue(2);
+ QCOMPARE(o.bindable1(), 2);
+ QCOMPARE(o.bindable2(), 38);
+ rootTrigger.setValue(3);
+ QCOMPARE(o.bindable1(), 3);
+ QCOMPARE(o.bindable2(), 37);
+ rootTrigger.setValue(4);
+ QCOMPARE(o.bindable1(), 4);
+ QCOMPARE(o.bindable2(), 36);
+}
+
+void tst_QProperty::derefFromObserver()
+{
+ int triggered = 0;
+ QProperty<int> source(11);
+
+ DtorCounter::counter = 0;
+ DtorCounter dc;
+
+ QProperty<int> target([&triggered, &source, dc]() mutable {
+ dc.shouldIncrement = true;
+ return ++triggered + source.value();
+ });
+ QCOMPARE(triggered, 1);
+
+ {
+ auto propObserver = std::make_unique<QPropertyObserver>();
+ QPropertyObserverPointer propObserverPtr { propObserver.get() };
+ propObserverPtr.setBindingToNotify(QPropertyBindingPrivate::get(target.binding()));
+
+ QBindingObserverPtr bindingPtr(propObserver.get());
+
+ QCOMPARE(triggered, 1);
+ source = 25;
+ QCOMPARE(triggered, 2);
+ QCOMPARE(target, 27);
+
+ target.setBinding([]() { return 8; });
+ QCOMPARE(target, 8);
+
+ // The QBindingObserverPtr still holds on to the binding.
+ QCOMPARE(dc.counter, 0);
+ }
+
+ // The binding is actually gone now.
+ QCOMPARE(dc.counter, 1);
+
+ source = 26;
+ QCOMPARE(triggered, 2);
+ QCOMPARE(target, 8);
+}
+
+QTEST_MAIN(tst_QProperty);
+
+#undef QT_SOURCE_LOCATION_NAMESPACE
+
+#include "tst_qproperty.moc"
diff --git a/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp b/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp
deleted file mode 100644
index ffbad37d82..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QSharedMemory>
-#include <QStringList>
-#include <QDebug>
-#include <QTest>
-#include <stdio.h>
-
-void set(QSharedMemory &sm, int pos, QChar value)
-{
- ((char*)sm.data())[pos] = value.toLatin1();
-}
-
-QChar get(QSharedMemory &sm, int i)
-{
- return QChar::fromLatin1(((char*)sm.data())[i]);
-}
-
-int readonly_segfault()
-{
- QSharedMemory sharedMemory;
- sharedMemory.setKey("readonly_segfault");
- sharedMemory.create(1024, QSharedMemory::ReadOnly);
- sharedMemory.lock();
- set(sharedMemory, 0, 'a');
- sharedMemory.unlock();
- return EXIT_SUCCESS;
-}
-
-int producer()
-{
- QSharedMemory producer;
- producer.setKey("market");
-
- int size = 1024;
- if (!producer.create(size)) {
- if (producer.error() == QSharedMemory::AlreadyExists) {
- if (!producer.attach()) {
- qWarning() << "Could not attach to" << producer.key();
- return EXIT_FAILURE;
- }
- } else {
- qWarning() << "Could not create" << producer.key();
- return EXIT_FAILURE;
- }
- }
- // tell parent we're ready
- //qDebug("producer created and attached");
- puts("");
- fflush(stdout);
-
- if (!producer.lock()) {
- qWarning() << "Could not lock" << producer.key();
- return EXIT_FAILURE;
- }
- set(producer, 0, 'Q');
- if (!producer.unlock()) {
- qWarning() << "Could not lock" << producer.key();
- return EXIT_FAILURE;
- }
-
- int i = 0;
- while (i < 5) {
- if (!producer.lock()) {
- qWarning() << "Could not lock" << producer.key();
- return EXIT_FAILURE;
- }
- if (get(producer, 0) == 'Q') {
- if (!producer.unlock()) {
- qWarning() << "Could not unlock" << producer.key();
- return EXIT_FAILURE;
- }
- QTest::qSleep(1);
- continue;
- }
- //qDebug() << "producer:" << i);
- ++i;
- set(producer, 0, 'Q');
- if (!producer.unlock()) {
- qWarning() << "Could not unlock" << producer.key();
- return EXIT_FAILURE;
- }
- QTest::qSleep(1);
- }
- if (!producer.lock()) {
- qWarning() << "Could not lock" << producer.key();
- return EXIT_FAILURE;
- }
- set(producer, 0, 'E');
- if (!producer.unlock()) {
- qWarning() << "Could not unlock" << producer.key();
- return EXIT_FAILURE;
- }
-
- //qDebug("producer done");
-
- // Sleep for a bit to let all consumers exit
- getchar();
- return EXIT_SUCCESS;
-}
-
-int consumer()
-{
- QSharedMemory consumer;
- consumer.setKey("market");
-
- //qDebug("consumer starting");
- int tries = 0;
- while (!consumer.attach()) {
- if (tries == 5000) {
- qWarning() << "consumer exiting, waiting too long";
- return EXIT_FAILURE;
- }
- ++tries;
- QTest::qSleep(1);
- }
- //qDebug("consumer attached");
-
-
- int i = 0;
- while (true) {
- if (!consumer.lock()) {
- qWarning() << "Could not lock" << consumer.key();
- return EXIT_FAILURE;
- }
- if (get(consumer, 0) == 'Q') {
- set(consumer, 0, ++i);
- //qDebug() << "consumer sets" << i;
- }
- if (get(consumer, 0) == 'E') {
- if (!consumer.unlock()) {
- qWarning() << "Could not unlock" << consumer.key();
- return EXIT_FAILURE;
- }
- break;
- }
- if (!consumer.unlock()) {
- qWarning() << "Could not unlock" << consumer.key();
- return EXIT_FAILURE;
- }
- QTest::qSleep(10);
- }
-
- //qDebug("consumer detaching");
- if (!consumer.detach()) {
- qWarning() << "Could not detach" << consumer.key();
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
-int main(int argc, char *argv[])
-{
- QCoreApplication app(argc, argv);
-
- QStringList arguments = app.arguments();
- if (app.arguments().count() != 2) {
- qWarning("Please call the helper with the function to call as argument");
- return EXIT_FAILURE;
- }
- QString function = arguments.at(1);
- if (function == QLatin1String("readonly_segfault"))
- return readonly_segfault();
- else if (function == QLatin1String("producer"))
- return producer();
- else if (function == QLatin1String("consumer"))
- return consumer();
- else
- qWarning() << "Unknown function" << arguments.at(1);
-
- return EXIT_SUCCESS;
-}
diff --git a/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro b/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro
deleted file mode 100644
index a6156ed5b6..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-QT = core testlib
-
-SOURCES += main.cpp
-
-load(qt_test_helper)
diff --git a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro
deleted file mode 100644
index 323d5bbd37..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TEMPLATE = subdirs
-
-qtConfig(sharedmemory) {
- !winrt: SUBDIRS = producerconsumer
- SUBDIRS += test.pro
-}
diff --git a/tests/auto/corelib/kernel/qsharedmemory/test.pro b/tests/auto/corelib/kernel/qsharedmemory/test.pro
deleted file mode 100644
index 8b3badadb0..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/test.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-
-QT = core-private testlib
-
-TARGET = tst_qsharedmemory
-SOURCES += tst_qsharedmemory.cpp
-
-linux: LIBS += -lrt
diff --git a/tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp
deleted file mode 100644
index 55deb8eb1a..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp
+++ /dev/null
@@ -1,821 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-#include <QFile>
-#if QT_CONFIG(process)
-# include <QProcess>
-#endif
-#include <QSharedMemory>
-#include <QTest>
-#include <QThread>
-
-#define EXISTING_SHARE "existing"
-#define EXISTING_SIZE 1024
-
-Q_DECLARE_METATYPE(QSharedMemory::SharedMemoryError)
-Q_DECLARE_METATYPE(QSharedMemory::AccessMode)
-
-class tst_QSharedMemory : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QSharedMemory();
- virtual ~tst_QSharedMemory();
-
-public Q_SLOTS:
- void init();
- void cleanup();
-
-
-private slots:
- // basics
- void constructor();
- void key_data();
- void key();
- void create_data();
- void create();
- void attach_data();
- void attach();
- void lock();
-
- // custom edge cases
-#ifndef Q_OS_HPUX
- void removeWhileAttached();
-#endif
- void emptyMemory();
-#if !defined(Q_OS_WIN)
- void readOnly();
-#endif
-
- // basics all together
-#ifndef Q_OS_HPUX
- void simpleProducerConsumer_data();
- void simpleProducerConsumer();
- void simpleDoubleProducerConsumer();
-#endif
-
- // with threads
- void simpleThreadedProducerConsumer_data();
- void simpleThreadedProducerConsumer();
-
- // with processes
- void simpleProcessProducerConsumer_data();
- void simpleProcessProducerConsumer();
-
- // extreme cases
- void useTooMuchMemory();
-#if !defined(Q_OS_HPUX)
- void attachTooMuch();
-#endif
-
- // unique keys
- void uniqueKey_data();
- void uniqueKey();
-
-protected:
- int remove(const QString &key);
-
- QString rememberKey(const QString &key)
- {
- if (key == EXISTING_SHARE)
- return key;
- if (!keys.contains(key)) {
- keys.append(key);
- remove(key);
- }
- return key;
- }
-
- QStringList keys;
- QList<QSharedMemory*> jail;
- QSharedMemory *existingSharedMemory;
-
-private:
- const QString m_helperBinary;
-};
-
-tst_QSharedMemory::tst_QSharedMemory()
- : existingSharedMemory(0)
- , m_helperBinary("producerconsumer_helper")
-{
-}
-
-tst_QSharedMemory::~tst_QSharedMemory()
-{
-}
-
-void tst_QSharedMemory::init()
-{
- existingSharedMemory = new QSharedMemory(EXISTING_SHARE);
- if (!existingSharedMemory->create(EXISTING_SIZE)) {
- QCOMPARE(existingSharedMemory->error(), QSharedMemory::AlreadyExists);
- }
-}
-
-void tst_QSharedMemory::cleanup()
-{
- delete existingSharedMemory;
- qDeleteAll(jail.begin(), jail.end());
- jail.clear();
-
- keys.append(EXISTING_SHARE);
- for (int i = 0; i < keys.count(); ++i) {
- QSharedMemory sm(keys.at(i));
- if (!sm.create(1024)) {
- //if (sm.error() != QSharedMemory::KeyError)
- // qWarning() << "test cleanup: remove failed:" << keys.at(i) << sm.error() << sm.errorString();
- sm.attach();
- sm.detach();
- remove(keys.at(i));
- }
- }
-}
-
-#ifndef Q_OS_WIN
-#include <private/qsharedmemory_p.h>
-#include <sys/types.h>
-#ifndef QT_POSIX_IPC
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#else
-#include <sys/mman.h>
-#endif // QT_POSIX_IPC
-#include <errno.h>
-#endif
-
-int tst_QSharedMemory::remove(const QString &key)
-{
-#ifdef Q_OS_WIN
- Q_UNUSED(key);
- return 0;
-#else
- // On unix the shared memory might exists from a previously failed test
- // or segfault, remove it it does
- if (key.isEmpty())
- return -1;
-
- // ftok requires that an actual file exists somewhere
- QString fileName = QSharedMemoryPrivate::makePlatformSafeKey(key);
- if (!QFile::exists(fileName)) {
- //qDebug() << "exits failed";
- return -2;
- }
-
-#ifndef QT_POSIX_IPC
- int unix_key = ftok(fileName.toLatin1().constData(), 'Q');
- if (-1 == unix_key) {
- qDebug() << "ftok failed";
- return -3;
- }
-
- int id = shmget(unix_key, 0, 0600);
- if (-1 == id) {
- qDebug() << "shmget failed" << strerror(errno);
- return -4;
- }
-
- struct shmid_ds shmid_ds;
- if (-1 == shmctl(id, IPC_RMID, &shmid_ds)) {
- qDebug() << "shmctl failed";
- return -5;
- }
-#else
- if (shm_unlink(QFile::encodeName(fileName).constData()) == -1) {
- qDebug() << "shm_unlink failed";
- return -5;
- }
-#endif // QT_POSIX_IPC
-
- return QFile::remove(fileName);
-#endif // Q_OS_WIN
-}
-
-/*!
- Tests the default values
- */
-void tst_QSharedMemory::constructor()
-{
- QSharedMemory sm;
- QCOMPARE(sm.key(), QString());
- QVERIFY(!sm.isAttached());
- QVERIFY(!sm.data());
- QCOMPARE(sm.size(), 0);
- QCOMPARE(sm.error(), QSharedMemory::NoError);
- QCOMPARE(sm.errorString(), QString());
-}
-
-void tst_QSharedMemory::key_data()
-{
- QTest::addColumn<QString>("constructorKey");
- QTest::addColumn<QString>("setKey");
- QTest::addColumn<QString>("setNativeKey");
-
- QTest::newRow("null, null, null") << QString() << QString() << QString();
- QTest::newRow("one, null, null") << QString("one") << QString() << QString();
- QTest::newRow("null, one, null") << QString() << QString("one") << QString();
- QTest::newRow("null, null, one") << QString() << QString() << QString("one");
- QTest::newRow("one, two, null") << QString("one") << QString("two") << QString();
- QTest::newRow("one, null, two") << QString("one") << QString() << QString("two");
- QTest::newRow("null, one, two") << QString() << QString("one") << QString("two");
- QTest::newRow("one, two, three") << QString("one") << QString("two") << QString("three");
- QTest::newRow("invalid") << QString("o/e") << QString("t/o") << QString("|x");
-}
-
-/*!
- Basic key testing
- */
-void tst_QSharedMemory::key()
-{
- QFETCH(QString, constructorKey);
- QFETCH(QString, setKey);
- QFETCH(QString, setNativeKey);
-
- QSharedMemory sm(constructorKey);
- QCOMPARE(sm.key(), constructorKey);
- QCOMPARE(sm.nativeKey().isEmpty(), constructorKey.isEmpty());
- sm.setKey(setKey);
- QCOMPARE(sm.key(), setKey);
- QCOMPARE(sm.nativeKey().isEmpty(), setKey.isEmpty());
- sm.setNativeKey(setNativeKey);
- QVERIFY(sm.key().isNull());
- QCOMPARE(sm.nativeKey(), setNativeKey);
- QCOMPARE(sm.isAttached(), false);
-
- QCOMPARE(sm.error(), QSharedMemory::NoError);
- QCOMPARE(sm.errorString(), QString());
- QVERIFY(!sm.data());
- QCOMPARE(sm.size(), 0);
-
- QCOMPARE(sm.detach(), false);
-}
-
-void tst_QSharedMemory::create_data()
-{
- QTest::addColumn<QString>("key");
- QTest::addColumn<int>("size");
- QTest::addColumn<bool>("canCreate");
- QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
-
- QTest::newRow("null key") << QString() << 1024
- << false << QSharedMemory::KeyError;
- QTest::newRow("-1 size") << QString("negsize") << -1
- << false << QSharedMemory::InvalidSize;
- QTest::newRow("nor size") << QString("norsize") << 1024
- << true << QSharedMemory::NoError;
- QTest::newRow("already exists") << QString(EXISTING_SHARE) << EXISTING_SIZE
- << false << QSharedMemory::AlreadyExists;
-}
-
-/*!
- Basic create testing
- */
-void tst_QSharedMemory::create()
-{
- QFETCH(QString, key);
- QFETCH(int, size);
- QFETCH(bool, canCreate);
- QFETCH(QSharedMemory::SharedMemoryError, error);
-
- QSharedMemory sm(rememberKey(key));
- QCOMPARE(sm.create(size), canCreate);
- if (sm.error() != error)
- qDebug() << sm.errorString();
- QCOMPARE(sm.key(), key);
- if (canCreate) {
- QCOMPARE(sm.errorString(), QString());
- QVERIFY(sm.data() != 0);
- QVERIFY(sm.size() != 0);
- } else {
- QVERIFY(!sm.data());
- QVERIFY(sm.errorString() != QString());
- }
-}
-
-void tst_QSharedMemory::attach_data()
-{
- QTest::addColumn<QString>("key");
- QTest::addColumn<bool>("exists");
- QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
-
- QTest::newRow("null key") << QString() << false << QSharedMemory::KeyError;
- QTest::newRow("doesn't exists") << QString("doesntexists") << false << QSharedMemory::NotFound;
-
- // HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
- QTest::newRow("already exists") << QString(EXISTING_SHARE) << true << QSharedMemory::NoError;
-#endif
-}
-
-/*!
- Basic attach/detach testing
- */
-void tst_QSharedMemory::attach()
-{
- QFETCH(QString, key);
- QFETCH(bool, exists);
- QFETCH(QSharedMemory::SharedMemoryError, error);
-
- QSharedMemory sm(key);
- QCOMPARE(sm.attach(), exists);
- QCOMPARE(sm.isAttached(), exists);
- QCOMPARE(sm.error(), error);
- QCOMPARE(sm.key(), key);
- if (exists) {
- QVERIFY(sm.data() != 0);
- QVERIFY(sm.size() != 0);
- QCOMPARE(sm.errorString(), QString());
- QVERIFY(sm.detach());
- // Make sure detach doesn't screw up something and we can't re-attach.
- QVERIFY(sm.attach());
- QVERIFY(sm.data() != 0);
- QVERIFY(sm.size() != 0);
- QVERIFY(sm.detach());
- QCOMPARE(sm.size(), 0);
- QVERIFY(!sm.data());
- } else {
- QVERIFY(!sm.data());
- QCOMPARE(sm.size(), 0);
- QVERIFY(sm.errorString() != QString());
- QVERIFY(!sm.detach());
- }
-}
-
-void tst_QSharedMemory::lock()
-{
- QSharedMemory shm;
- QVERIFY(!shm.lock());
- QCOMPARE(shm.error(), QSharedMemory::LockError);
-
- shm.setKey(QLatin1String("qsharedmemory"));
-
- QVERIFY(!shm.lock());
- QCOMPARE(shm.error(), QSharedMemory::LockError);
-
- QVERIFY(shm.create(100));
- QVERIFY(shm.lock());
- QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
- QVERIFY(shm.lock());
- // we didn't unlock(), so ignore the warning from auto-detach in destructor
- QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
-}
-
-/*!
- Other shared memory are allowed to be attached after we remove,
- but new shared memory are not allowed to attach after a remove.
- */
-// HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
-void tst_QSharedMemory::removeWhileAttached()
-{
- rememberKey("one");
-
- // attach 1
- QSharedMemory *smOne = new QSharedMemory(QLatin1String("one"));
- QVERIFY(smOne->create(1024));
- QVERIFY(smOne->isAttached());
-
- // attach 2
- QSharedMemory *smTwo = new QSharedMemory(QLatin1String("one"));
- QVERIFY(smTwo->attach());
- QVERIFY(smTwo->isAttached());
-
- // detach 1 and remove, remove one first to catch another error.
- delete smOne;
- delete smTwo;
-
- // three shouldn't be able to attach
- QSharedMemory smThree(QLatin1String("one"));
- QVERIFY(!smThree.attach());
- QCOMPARE(smThree.error(), QSharedMemory::NotFound);
-}
-#endif
-
-/*!
- The memory should be set to 0 after created.
- */
-void tst_QSharedMemory::emptyMemory()
-{
- QSharedMemory sm(rememberKey(QLatin1String("voidland")));
- int size = 1024;
- QVERIFY(sm.create(size, QSharedMemory::ReadOnly));
- char *get = (char*)sm.data();
- char null = 0;
- for (int i = 0; i < size; ++i)
- QCOMPARE(get[i], null);
-}
-
-/*!
- Verify that attach with ReadOnly is actually read only
- by writing to data and causing a segfault.
-*/
-// This test opens a crash dialog on Windows.
-#if !defined(Q_OS_WIN)
-void tst_QSharedMemory::readOnly()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#elif defined(Q_OS_MACOS)
- QSKIP("QTBUG-59936: Times out on macOS", SkipAll);
-#else
- rememberKey("readonly_segfault");
- // ### on windows disable the popup somehow
- QProcess p;
- p.start(m_helperBinary, QStringList("readonly_segfault"));
- p.setProcessChannelMode(QProcess::ForwardedChannels);
- p.waitForFinished();
- QCOMPARE(p.error(), QProcess::Crashed);
-#endif
-}
-#endif
-
-/*!
- Keep making shared memory until the kernel stops us.
- */
-void tst_QSharedMemory::useTooMuchMemory()
-{
-#ifdef Q_OS_LINUX
- bool success = true;
- int count = 0;
- while (success) {
- QString key = QLatin1String("maxmemorytest_") + QString::number(count++);
- QSharedMemory *sm = new QSharedMemory(rememberKey(key));
- QVERIFY(sm);
- jail.append(sm);
- int size = 32768 * 1024;
- success = sm->create(size);
- if (!success && sm->error() == QSharedMemory::AlreadyExists) {
- // left over from a crash, clean it up
- sm->attach();
- sm->detach();
- success = sm->create(size);
- }
-
- if (!success) {
- QVERIFY(!sm->isAttached());
- QCOMPARE(sm->key(), key);
- QCOMPARE(sm->size(), 0);
- QVERIFY(!sm->data());
- if (sm->error() != QSharedMemory::OutOfResources)
- qDebug() << sm->error() << sm->errorString();
- // ### Linux won't return OutOfResources if there are not enough semaphores to use.
- QVERIFY(sm->error() == QSharedMemory::OutOfResources
- || sm->error() == QSharedMemory::LockError);
- QVERIFY(sm->errorString() != QString());
- QVERIFY(!sm->attach());
- QVERIFY(!sm->detach());
- } else {
- QVERIFY(sm->isAttached());
- }
- }
-#endif
-}
-
-/*!
- Create one shared memory (government) and see how many other shared memories (wars) we can
- attach before the system runs out of resources.
- */
-// HPUX doesn't allow for multiple attaches per process.
-#if !defined(Q_OS_HPUX)
-void tst_QSharedMemory::attachTooMuch()
-{
- QSKIP("disabled");
-
- QSharedMemory government(rememberKey("government"));
- QVERIFY(government.create(1024));
- while (true) {
- QSharedMemory *war = new QSharedMemory(government.key());
- QVERIFY(war);
- jail.append(war);
- if (!war->attach()) {
- QVERIFY(!war->isAttached());
- QCOMPARE(war->key(), government.key());
- QCOMPARE(war->size(), 0);
- QVERIFY(!war->data());
- QCOMPARE(war->error(), QSharedMemory::OutOfResources);
- QVERIFY(war->errorString() != QString());
- QVERIFY(!war->detach());
- break;
- } else {
- QVERIFY(war->isAttached());
- }
- }
-}
-#endif
-
-// HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
-void tst_QSharedMemory::simpleProducerConsumer_data()
-{
- QTest::addColumn<QSharedMemory::AccessMode>("mode");
-
- QTest::newRow("readonly") << QSharedMemory::ReadOnly;
- QTest::newRow("readwrite") << QSharedMemory::ReadWrite;
-}
-
-/*!
- The basic consumer producer that rounds out the basic testing.
- If this fails then any muli-threading/process might fail (but be
- harder to debug)
-
- This doesn't require nor test any locking system.
- */
-void tst_QSharedMemory::simpleProducerConsumer()
-{
- QFETCH(QSharedMemory::AccessMode, mode);
-
- rememberKey(QLatin1String("market"));
- QSharedMemory producer(QLatin1String("market"));
- QSharedMemory consumer(QLatin1String("market"));
- int size = 512;
- QVERIFY(producer.create(size));
- QVERIFY(consumer.attach(mode));
-
- char *put = (char*)producer.data();
- char *get = (char*)consumer.data();
- // On Windows CE you always have ReadWrite access. Thus
- // ViewMapOfFile returns the same pointer
- QVERIFY(put != get);
- for (int i = 0; i < size; ++i) {
- put[i] = 'Q';
- QCOMPARE(get[i], 'Q');
- }
- QVERIFY(consumer.detach());
-}
-#endif
-
-// HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
-void tst_QSharedMemory::simpleDoubleProducerConsumer()
-{
- rememberKey(QLatin1String("market"));
- QSharedMemory producer(QLatin1String("market"));
- int size = 512;
- QVERIFY(producer.create(size));
- QVERIFY(producer.detach());
- QVERIFY(producer.create(size));
-
- {
- QSharedMemory consumer(QLatin1String("market"));
- QVERIFY(consumer.attach());
- }
-}
-#endif
-
-class Consumer : public QThread
-{
-
-public:
- void run()
- {
- QSharedMemory consumer(QLatin1String("market"));
- while (!consumer.attach()) {
- if (consumer.error() != QSharedMemory::NotFound)
- qDebug() << "consumer: failed to connect" << consumer.error() << consumer.errorString();
- QVERIFY(consumer.error() == QSharedMemory::NotFound || consumer.error() == QSharedMemory::KeyError);
- QTest::qWait(1);
- }
-
- char *memory = (char*)consumer.data();
-
- int i = 0;
- while (true) {
- if (!consumer.lock())
- break;
- if (memory[0] == 'Q')
- memory[0] = ++i;
- if (memory[0] == 'E') {
- memory[1]++;
- QVERIFY(consumer.unlock());
- break;
- }
- QVERIFY(consumer.unlock());
- QTest::qWait(1);
- }
-
- QVERIFY(consumer.detach());
- }
-};
-
-class Producer : public QThread
-{
-
-public:
- Producer() : producer(QLatin1String("market"))
- {
- int size = 1024;
- if (!producer.create(size)) {
- // left over from a crash...
- if (producer.error() == QSharedMemory::AlreadyExists) {
- producer.attach();
- producer.detach();
- QVERIFY(producer.create(size));
- }
- }
- }
-
- void run()
- {
-
- char *memory = (char*)producer.data();
- memory[1] = '0';
- QTime timer;
- timer.start();
- int i = 0;
- while (i < 5 && timer.elapsed() < 5000) {
- QVERIFY(producer.lock());
- if (memory[0] == 'Q') {
- QVERIFY(producer.unlock());
- QTest::qWait(1);
- continue;
- }
- ++i;
- memory[0] = 'Q';
- QVERIFY(producer.unlock());
- QTest::qWait(1);
- }
-
- // tell everyone to quit
- QVERIFY(producer.lock());
- memory[0] = 'E';
- QVERIFY(producer.unlock());
-
- }
-
- QSharedMemory producer;
-private:
-
-};
-
-void tst_QSharedMemory::simpleThreadedProducerConsumer_data()
-{
- QTest::addColumn<bool>("producerIsThread");
- QTest::addColumn<int>("threads");
- for (int i = 0; i < 5; ++i) {
- QTest::newRow("1 consumer, producer is thread") << true << 1;
- QTest::newRow("1 consumer, producer is this") << false << 1;
- QTest::newRow("5 consumers, producer is thread") << true << 5;
- QTest::newRow("5 consumers, producer is this") << false << 5;
- }
-}
-
-/*!
- The basic producer/consumer, but this time using threads.
- */
-void tst_QSharedMemory::simpleThreadedProducerConsumer()
-{
- QFETCH(bool, producerIsThread);
- QFETCH(int, threads);
- rememberKey(QLatin1String("market"));
-
-#if defined Q_OS_HPUX && defined __ia64
- QSKIP("This test locks up on gravlaks.troll.no");
-#endif
-
- Producer p;
- QVERIFY(p.producer.isAttached());
- if (producerIsThread)
- p.start();
-
- QList<Consumer*> consumers;
- for (int i = 0; i < threads; ++i) {
- consumers.append(new Consumer());
- consumers.last()->start();
- }
-
- if (!producerIsThread)
- p.run();
-
- p.wait(5000);
- while (!consumers.isEmpty()) {
- Consumer *c = consumers.first();
- QVERIFY(c->isFinished() || c->wait(5000));
- delete consumers.takeFirst();
- }
-}
-
-void tst_QSharedMemory::simpleProcessProducerConsumer_data()
-{
-#if QT_CONFIG(process)
- QTest::addColumn<int>("processes");
- int tries = 5;
- for (int i = 0; i < tries; ++i) {
- QTest::newRow("1 process") << 1;
- QTest::newRow("5 processes") << 5;
- }
-#endif
-}
-
-/*!
- Create external processes that produce and consume.
- */
-void tst_QSharedMemory::simpleProcessProducerConsumer()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QFETCH(int, processes);
-
- QSKIP("This test is unstable: QTBUG-25655");
-
- rememberKey("market");
-
- QProcess producer;
- producer.start(m_helperBinary, QStringList("producer"));
- QVERIFY2(producer.waitForStarted(), "Could not start helper binary");
- QVERIFY2(producer.waitForReadyRead(), "Helper process failed to create shared memory segment: " +
- producer.readAllStandardError());
-
- QList<QProcess*> consumers;
- unsigned int failedProcesses = 0;
- const QStringList consumerArguments = QStringList("consumer");
- for (int i = 0; i < processes; ++i) {
- QProcess *p = new QProcess;
- p->setProcessChannelMode(QProcess::ForwardedChannels);
- p->start(m_helperBinary, consumerArguments);
- if (p->waitForStarted(2000))
- consumers.append(p);
- else
- ++failedProcesses;
- }
-
- bool consumerFailed = false;
-
- while (!consumers.isEmpty()) {
- QVERIFY(consumers.first()->waitForFinished(3000));
- if (consumers.first()->state() == QProcess::Running ||
- consumers.first()->exitStatus() != QProcess::NormalExit ||
- consumers.first()->exitCode() != 0) {
- consumerFailed = true;
- }
- delete consumers.takeFirst();
- }
- QCOMPARE(consumerFailed, false);
- QCOMPARE(failedProcesses, (unsigned int)(0));
-
- // tell the producer to exit now
- producer.write("", 1);
- producer.waitForBytesWritten();
- QVERIFY(producer.waitForFinished(5000));
-#endif
-}
-
-void tst_QSharedMemory::uniqueKey_data()
-{
- QTest::addColumn<QString>("key1");
- QTest::addColumn<QString>("key2");
-
- QTest::newRow("null == null") << QString() << QString();
- QTest::newRow("key == key") << QString("key") << QString("key");
- QTest::newRow("key1 == key1") << QString("key1") << QString("key1");
- QTest::newRow("key != key1") << QString("key") << QString("key1");
- QTest::newRow("ke1y != key1") << QString("ke1y") << QString("key1");
- QTest::newRow("key1 != key2") << QString("key1") << QString("key2");
- QTest::newRow("Noël -> Nol") << QString::fromUtf8("N\xc3\xabl") << QString("Nol");
-}
-
-void tst_QSharedMemory::uniqueKey()
-{
- QFETCH(QString, key1);
- QFETCH(QString, key2);
-
- QSharedMemory sm1(key1);
- QSharedMemory sm2(key2);
-
- bool setEqual = (key1 == key2);
- bool keyEqual = (sm1.key() == sm2.key());
- bool nativeEqual = (sm1.nativeKey() == sm2.nativeKey());
-
- QCOMPARE(keyEqual, setEqual);
- QCOMPARE(nativeEqual, setEqual);
-}
-
-QTEST_MAIN(tst_QSharedMemory)
-#include "tst_qsharedmemory.moc"
-
diff --git a/tests/auto/corelib/kernel/qsignalblocker/CMakeLists.txt b/tests/auto/corelib/kernel/qsignalblocker/CMakeLists.txt
new file mode 100644
index 0000000000..0effacb018
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsignalblocker/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsignalblocker Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsignalblocker LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsignalblocker
+ SOURCES
+ tst_qsignalblocker.cpp
+)
diff --git a/tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro b/tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro
deleted file mode 100644
index 6e4913db5d..0000000000
--- a/tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase console
-TARGET = tst_qsignalblocker
-QT = core testlib
-SOURCES = tst_qsignalblocker.cpp
-
diff --git a/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp b/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp
index fd18f00cd0..bd1f149a3f 100644
--- a/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp
+++ b/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@woboq.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2013 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@woboq.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include "qobject.h"
@@ -36,6 +11,7 @@ class tst_QSignalBlocker : public QObject
private slots:
void signalBlocking();
void moveAssignment();
+ void dismiss();
};
void tst_QSignalBlocker::signalBlocking()
@@ -66,7 +42,6 @@ void tst_QSignalBlocker::signalBlocking()
void tst_QSignalBlocker::moveAssignment()
{
-#ifdef Q_COMPILER_RVALUE_REFS
QObject o1, o2;
// move-assignment: both block other objects
@@ -157,10 +132,16 @@ void tst_QSignalBlocker::moveAssignment()
QVERIFY(!o1.signalsBlocked());
QVERIFY(!o2.signalsBlocked());
+}
-#else
- QSKIP("This compiler is not in C++11 mode or doesn't support move semantics");
-#endif // Q_COMPILER_RVALUE_REFS
+void tst_QSignalBlocker::dismiss()
+{
+ QObject obj;
+ {
+ QSignalBlocker blocker(obj);
+ blocker.dismiss();
+ }
+ QVERIFY(obj.signalsBlocked());
}
QTEST_MAIN(tst_QSignalBlocker)
diff --git a/tests/auto/corelib/kernel/qsignalmapper/CMakeLists.txt b/tests/auto/corelib/kernel/qsignalmapper/CMakeLists.txt
new file mode 100644
index 0000000000..b5de408ea8
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsignalmapper/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsignalmapper Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsignalmapper LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsignalmapper
+ SOURCES
+ tst_qsignalmapper.cpp
+)
diff --git a/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro b/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro
deleted file mode 100644
index 418d6dce62..0000000000
--- a/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsignalmapper
-QT = core testlib
-SOURCES = tst_qsignalmapper.cpp
diff --git a/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp b/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp
index c03e3e8e9f..de54cd5adc 100644
--- a/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp
+++ b/tests/auto/corelib/kernel/qsignalmapper/tst_qsignalmapper.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qsignalmapper.h>
@@ -41,8 +16,8 @@ class QtTestObject : public QObject
{
Q_OBJECT
public slots:
- void myslot(int id);
- void myslot(const QString &str);
+ void myIntSlot(int id);
+ void myStringSlot(const QString &str);
signals:
void mysignal(int);
@@ -54,12 +29,12 @@ public:
QString str;
};
-void QtTestObject::myslot(int id)
+void QtTestObject::myIntSlot(int id)
{
this->id = id;
}
-void QtTestObject::myslot(const QString &str)
+void QtTestObject::myStringSlot(const QString &str)
{
this->str = str;
}
@@ -71,7 +46,7 @@ void QtTestObject::emit_mysignal(int value)
void tst_QSignalMapper::mapped()
{
- QSignalMapper mapper(0);
+ QSignalMapper mapper;
QtTestObject target;
QtTestObject src1;
@@ -88,8 +63,8 @@ void tst_QSignalMapper::mapped()
mapper.setMapping(&src2, "two");
mapper.setMapping(&src3, "three");
- connect(&mapper, SIGNAL(mapped(int)), &target, SLOT(myslot(int)));
- connect(&mapper, SIGNAL(mapped(QString)), &target, SLOT(myslot(QString)));
+ connect(&mapper, &QSignalMapper::mappedInt, &target, &QtTestObject::myIntSlot);
+ connect(&mapper, &QSignalMapper::mappedString, &target, &QtTestObject::myStringSlot);
src1.emit_mysignal(20);
QCOMPARE(target.id, 1);
diff --git a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST
deleted file mode 100644
index e68bf84268..0000000000
--- a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[unexpectedDisconnection]
-windows
-osx
diff --git a/tests/auto/corelib/kernel/qsocketnotifier/CMakeLists.txt b/tests/auto/corelib/kernel/qsocketnotifier/CMakeLists.txt
new file mode 100644
index 0000000000..2a802b5f4d
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsocketnotifier/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsocketnotifier LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if(NOT QT_FEATURE_private_tests)
+ return()
+endif()
+
+#####################################################################
+## tst_qsocketnotifier Test:
+#####################################################################
+
+qt_internal_add_test(tst_qsocketnotifier
+ SOURCES
+ tst_qsocketnotifier.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+ Qt::NetworkPrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qsocketnotifier CONDITION WIN32
+ LIBRARIES
+ ws2_32
+)
diff --git a/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro b/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro
deleted file mode 100644
index 04806de5f7..0000000000
--- a/tests/auto/corelib/kernel/qsocketnotifier/qsocketnotifier.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsocketnotifier
-QT = core-private network-private testlib
-SOURCES = tst_qsocketnotifier.cpp
-
-requires(qtConfig(private_tests))
-
-include(../../../network/socket/platformsocketengine/platformsocketengine.pri)
diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp
index e3f45df27d..17bba73dab 100644
--- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp
+++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QTest>
#include <QtTest/QSignalSpy>
@@ -36,11 +11,7 @@
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QUdpSocket>
-#ifndef Q_OS_WINRT
#include <private/qnativesocketengine_p.h>
-#else
-#include <private/qnativesocketengine_winrt_p.h>
-#endif
#define NATIVESOCKETENGINE QNativeSocketEngine
#ifdef Q_OS_UNIX
#include <private/qnet_unix_p.h>
@@ -53,16 +24,22 @@
# undef min
#endif // Q_CC_MSVC
+using namespace std::chrono_literals;
+
class tst_QSocketNotifier : public QObject
{
Q_OBJECT
private slots:
+ void constructing();
void unexpectedDisconnection();
void mixingWithTimers();
#ifdef Q_OS_UNIX
void posixSockets();
#endif
void asyncMultipleDatagram();
+ void activationReason_data();
+ void activationReason();
+ void legacyConnect();
protected slots:
void async_readDatagramSlot();
@@ -85,6 +62,51 @@ static QHostAddress makeNonAny(const QHostAddress &address,
return address;
}
+void tst_QSocketNotifier::constructing()
+{
+ const qintptr fd = 15;
+
+ // Test constructing with no descriptor assigned.
+ {
+ QSocketNotifier notifier(QSocketNotifier::Read);
+
+ QVERIFY(!notifier.isValid());
+ QCOMPARE(notifier.socket(), Q_INT64_C(-1));
+ QCOMPARE(notifier.type(), QSocketNotifier::Read);
+ QVERIFY(!notifier.isEnabled());
+
+ notifier.setEnabled(true);
+ QVERIFY(!notifier.isEnabled());
+
+ notifier.setSocket(fd);
+ QVERIFY(notifier.isValid());
+ QCOMPARE(notifier.socket(), fd);
+ QVERIFY(!notifier.isEnabled());
+ notifier.setEnabled(true);
+ QVERIFY(notifier.isEnabled());
+ }
+
+ // Test constructing with the notifications enabled by default.
+ {
+ QSocketNotifier notifier(fd, QSocketNotifier::Write);
+
+ QVERIFY(notifier.isValid());
+ QCOMPARE(notifier.socket(), fd);
+ QCOMPARE(notifier.type(), QSocketNotifier::Write);
+ QVERIFY(notifier.isEnabled());
+
+ notifier.setSocket(fd);
+ QVERIFY(!notifier.isEnabled());
+
+ notifier.setEnabled(true);
+ QVERIFY(notifier.isEnabled());
+ notifier.setSocket(-1);
+ QVERIFY(!notifier.isValid());
+ QCOMPARE(notifier.socket(), Q_INT64_C(-1));
+ QVERIFY(!notifier.isEnabled());
+ }
+}
+
class UnexpectedDisconnectTester : public QObject
{
Q_OBJECT
@@ -97,10 +119,10 @@ public:
{
QSocketNotifier *notifier1 =
new QSocketNotifier(readEnd1->socketDescriptor(), QSocketNotifier::Read, this);
- connect(notifier1, SIGNAL(activated(int)), SLOT(handleActivated()));
+ connect(notifier1, SIGNAL(activated(QSocketDescriptor)), SLOT(handleActivated()));
QSocketNotifier *notifier2 =
new QSocketNotifier(readEnd2->socketDescriptor(), QSocketNotifier::Read, this);
- connect(notifier2, SIGNAL(activated(int)), SLOT(handleActivated()));
+ connect(notifier2, SIGNAL(activated(QSocketDescriptor)), SLOT(handleActivated()));
}
public slots:
@@ -110,11 +132,11 @@ public slots:
++sequence;
if (sequence == 1) {
// read from both ends
- (void) readEnd1->read(data1, sizeof(data1));
- (void) readEnd2->read(data2, sizeof(data2));
+ QCOMPARE(readEnd1->read(data1, sizeof(data1)), 1);
+ QCOMPARE(readEnd2->read(data2, sizeof(data2)), 1);
emit finished();
} else if (sequence == 2) {
- // we should never get here
+ // check that we can't read now because we've read our byte
QCOMPARE(readEnd2->read(data2, sizeof(data2)), qint64(-2));
QVERIFY(readEnd2->isValid());
}
@@ -126,15 +148,11 @@ signals:
void tst_QSocketNotifier::unexpectedDisconnection()
{
-#ifdef Q_OS_WINRT
- // WinRT does not allow a connection to the localhost
- QSKIP("Local connection not allowed", SkipAll);
-#else
/*
Given two sockets and two QSocketNotifiers registered on each
their socket. If both sockets receive data, and the first slot
invoked by one of the socket notifiers empties both sockets, the
- other notifier will also emit activated(). This results in
+ other notifier will also emit activated(). This was causing an
unexpected disconnection in QAbstractSocket.
The use case is that somebody calls one of the
@@ -151,7 +169,7 @@ void tst_QSocketNotifier::unexpectedDisconnection()
readEnd1.connectToHost(server.serverAddress(), server.serverPort());
QVERIFY(readEnd1.waitForWrite());
QCOMPARE(readEnd1.state(), QAbstractSocket::ConnectedState);
- QVERIFY(server.waitForNewConnection());
+ QVERIFY(server.waitForNewConnection(5000));
QTcpSocket *writeEnd1 = server.nextPendingConnection();
QVERIFY(writeEnd1 != 0);
@@ -160,7 +178,7 @@ void tst_QSocketNotifier::unexpectedDisconnection()
readEnd2.connectToHost(server.serverAddress(), server.serverPort());
QVERIFY(readEnd2.waitForWrite());
QCOMPARE(readEnd2.state(), QAbstractSocket::ConnectedState);
- QVERIFY(server.waitForNewConnection());
+ QVERIFY(server.waitForNewConnection(5000));
QTcpSocket *writeEnd2 = server.nextPendingConnection();
QVERIFY(writeEnd2 != 0);
@@ -170,8 +188,9 @@ void tst_QSocketNotifier::unexpectedDisconnection()
writeEnd1->waitForBytesWritten();
writeEnd2->waitForBytesWritten();
- writeEnd1->flush();
- writeEnd2->flush();
+ // ensure both read ends are ready for reading, before the event loop
+ QVERIFY(readEnd1.waitForRead(5s));
+ QVERIFY(readEnd2.waitForRead(5s));
UnexpectedDisconnectTester tester(&readEnd1, &readEnd2);
@@ -195,7 +214,6 @@ void tst_QSocketNotifier::unexpectedDisconnection()
writeEnd1->close();
writeEnd2->close();
server.close();
-#endif // !Q_OS_WINRT
}
class MixingWithTimersHelper : public QObject
@@ -234,9 +252,6 @@ void MixingWithTimersHelper::socketFired()
void tst_QSocketNotifier::mixingWithTimers()
{
-#ifdef Q_OS_WINRT
- QSKIP("WinRT does not allow connection to localhost", SkipAll);
-#else
QTimer timer;
timer.setInterval(0);
timer.start();
@@ -261,7 +276,6 @@ void tst_QSocketNotifier::mixingWithTimers()
QCOMPARE(helper.timerActivated, true);
QTRY_COMPARE(helper.socketActivated, true);
-#endif // !Q_OS_WINRT
}
#ifdef Q_OS_UNIX
@@ -284,12 +298,12 @@ void tst_QSocketNotifier::posixSockets()
{
QSocketNotifier rn(posixSocket, QSocketNotifier::Read);
- connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ connect(&rn, SIGNAL(activated(QSocketDescriptor)), &QTestEventLoop::instance(), SLOT(exitLoop()));
QSignalSpy readSpy(&rn, &QSocketNotifier::activated);
QVERIFY(readSpy.isValid());
// No write notifier, some systems trigger write notification on socket creation, but not all
QSocketNotifier en(posixSocket, QSocketNotifier::Exception);
- connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ connect(&en, SIGNAL(activated(QSocketDescriptor)), &QTestEventLoop::instance(), SLOT(exitLoop()));
QSignalSpy errorSpy(&en, &QSocketNotifier::activated);
QVERIFY(errorSpy.isValid());
@@ -297,8 +311,8 @@ void tst_QSocketNotifier::posixSockets()
passive->waitForBytesWritten(5000);
QTestEventLoop::instance().enterLoop(3);
- QCOMPARE(readSpy.count(), 1);
- QCOMPARE(errorSpy.count(), 0);
+ QCOMPARE(readSpy.size(), 1);
+ QCOMPARE(errorSpy.size(), 0);
char buffer[100];
int r = qt_safe_read(posixSocket, buffer, 100);
@@ -306,15 +320,15 @@ void tst_QSocketNotifier::posixSockets()
QCOMPARE(buffer, "hello");
QSocketNotifier wn(posixSocket, QSocketNotifier::Write);
- connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ connect(&wn, SIGNAL(activated(QSocketDescriptor)), &QTestEventLoop::instance(), SLOT(exitLoop()));
QSignalSpy writeSpy(&wn, &QSocketNotifier::activated);
QVERIFY(writeSpy.isValid());
qt_safe_write(posixSocket, "goodbye", 8);
QTestEventLoop::instance().enterLoop(3);
- QCOMPARE(readSpy.count(), 1);
- QCOMPARE(writeSpy.count(), 1);
- QCOMPARE(errorSpy.count(), 0);
+ QCOMPARE(readSpy.size(), 1);
+ QCOMPARE(writeSpy.size(), 1);
+ QCOMPARE(errorSpy.size(), 0);
// Write notifier may have fired before the read notifier inside
// QTcpSocket, give QTcpSocket a chance to see the incoming data
@@ -350,9 +364,6 @@ void tst_QSocketNotifier::async_writeDatagramSlot()
void tst_QSocketNotifier::asyncMultipleDatagram()
{
-#ifdef Q_OS_WINRT
- QSKIP("WinRT does not allow connection to localhost", SkipAll);
-#else
m_asyncSender = new QUdpSocket;
m_asyncReceiver = new QUdpSocket;
@@ -365,7 +376,7 @@ void tst_QSocketNotifier::asyncMultipleDatagram()
&tst_QSocketNotifier::async_readDatagramSlot);
// activate socket notifiers
- QTestEventLoop::instance().enterLoopMSecs(100);
+ QTestEventLoop::instance().enterLoop(100ms);
m_asyncSender->writeDatagram("1", makeNonAny(m_asyncReceiver->localAddress()), port);
m_asyncSender->writeDatagram("2", makeNonAny(m_asyncReceiver->localAddress()), port);
@@ -378,12 +389,67 @@ void tst_QSocketNotifier::asyncMultipleDatagram()
QTestEventLoop::instance().enterLoop(1);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
delete m_asyncSender;
delete m_asyncReceiver;
- #endif // !Q_OS_WINRT
}
+void tst_QSocketNotifier::activationReason_data()
+{
+ QTest::addColumn<QSocketNotifier::Type>("type");
+ QTest::addRow("read") << QSocketNotifier::Read;
+ QTest::addRow("write") << QSocketNotifier::Write;
+ QTest::addRow("exception") << QSocketNotifier::Exception;
+}
+void tst_QSocketNotifier::activationReason()
+{
+ QSocketDescriptor fd = 15;
+
+ QFETCH(QSocketNotifier::Type, type);
+
+ QSocketNotifier notifier(fd, type);
+ auto activation = new QEvent(QEvent::SockAct);
+ QCoreApplication::postEvent(&notifier, activation);
+
+ QSocketNotifier::Type notifierType;
+ connect(&notifier, &QSocketNotifier::activated, this,
+ [&notifierType, fd](QSocketDescriptor sockfd, QSocketNotifier::Type sntype) {
+ if (sockfd == fd)
+ notifierType = sntype;
+ else
+ qWarning() << "Got an unexpected socket file descriptor:" << qintptr(sockfd);
+ });
+
+ QCoreApplication::processEvents();
+ QCOMPARE(notifierType, type);
+}
+
+// This test ensures that we can connect QSocketNotifier::activated to a slot taking an integer
+// or qintptr.
+void tst_QSocketNotifier::legacyConnect()
+{
+ qintptr fd = 15;
+ QSocketNotifier notifier(fd, QSocketNotifier::Read);
+ auto activation = new QEvent(QEvent::SockAct);
+ QCoreApplication::postEvent(&notifier, activation);
+
+ bool receivedQIntPtr = false;
+ connect(&notifier, &QSocketNotifier::activated, this, [&receivedQIntPtr, fd](qintptr q){
+ if (q == fd)
+ receivedQIntPtr = true;
+ });
+ bool receivedInt = false;
+ connect(&notifier, &QSocketNotifier::activated, this, [&receivedInt, fd](int q){
+ if (q == fd)
+ receivedInt = true;
+ });
+
+ QCoreApplication::processEvents();
+ QVERIFY(receivedQIntPtr);
+ QVERIFY(receivedInt);
+}
+
+
QTEST_MAIN(tst_QSocketNotifier)
#include <tst_qsocketnotifier.moc>
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro b/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro
deleted file mode 100644
index a6156ed5b6..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-QT = core testlib
-
-SOURCES += main.cpp
-
-load(qt_test_helper)
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp
deleted file mode 100644
index 7bfb6b16cc..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QCoreApplication>
-#include <QDebug>
-#include <QStringList>
-#include <QSystemSemaphore>
-
-int acquire(int count = 1)
-{
- QSystemSemaphore sem("store");
-
- for (int i = 0; i < count; ++i) {
- if (!sem.acquire()) {
- qWarning() << "Could not acquire" << sem.key();
- return EXIT_FAILURE;
- }
- }
- qDebug("done aquiring");
- return EXIT_SUCCESS;
-}
-
-int release()
-{
- QSystemSemaphore sem("store");
- if (!sem.release()) {
- qWarning() << "Could not release" << sem.key();
- return EXIT_FAILURE;
- }
- qDebug("done releasing");
- return EXIT_SUCCESS;
-}
-
-int acquirerelease()
-{
- QSystemSemaphore sem("store");
- if (!sem.acquire()) {
- qWarning() << "Could not acquire" << sem.key();
- return EXIT_FAILURE;
- }
- if (!sem.release()) {
- qWarning() << "Could not release" << sem.key();
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
-int main(int argc, char *argv[])
-{
- QCoreApplication app(argc, argv);
-
- QStringList arguments = app.arguments();
- // binary name is not used here
- arguments.takeFirst();
- if (arguments.count() < 1) {
- qWarning("Please call the helper with the function to call as argument");
- return EXIT_FAILURE;
- }
- QString function = arguments.takeFirst();
- if (function == QLatin1String("acquire")) {
- int count = 1;
- bool ok = true;
- if (arguments.count())
- count = arguments.takeFirst().toInt(&ok);
- if (!ok)
- count = 1;
- return acquire(count);
- } else if (function == QLatin1String("release")) {
- return release();
- } else if (function == QLatin1String("acquirerelease")) {
- return acquirerelease();
- } else {
- qWarning() << "Unknown function" << function;
- }
- return EXIT_SUCCESS;
-}
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro b/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro
deleted file mode 100644
index 70526426aa..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS = acquirerelease test.pro
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test.pro b/tests/auto/corelib/kernel/qsystemsemaphore/test.pro
deleted file mode 100644
index 13bd1fa270..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/test.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-QT = core testlib
-
-SOURCES += tst_qsystemsemaphore.cpp
-TARGET = tst_qsystemsemaphore
-
-win32: CONFIG += console
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp
deleted file mode 100644
index 5f010ae3d1..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QSystemSemaphore>
-#include <QtCore/QVector>
-#include <QtCore/QTemporaryDir>
-
-#define EXISTING_SHARE "existing"
-#define HELPERWAITTIME 10000
-
-class tst_QSystemSemaphore : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QSystemSemaphore();
-
-public Q_SLOTS:
- void init();
- void cleanup();
-
-private slots:
- void key_data();
- void key();
-
- void basicacquire();
- void complexacquire();
- void release();
-
- void basicProcesses();
-
- void processes_data();
- void processes();
-
-#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
- void undo();
-#endif
- void initialValue();
-
-private:
- QSystemSemaphore *existingLock;
-
- const QString m_helperBinary;
-};
-
-tst_QSystemSemaphore::tst_QSystemSemaphore()
- : m_helperBinary("acquirerelease_helper")
-{
-}
-
-void tst_QSystemSemaphore::init()
-{
- existingLock = new QSystemSemaphore(EXISTING_SHARE, 1, QSystemSemaphore::Create);
-}
-
-void tst_QSystemSemaphore::cleanup()
-{
- delete existingLock;
-}
-
-void tst_QSystemSemaphore::key_data()
-{
- QTest::addColumn<QString>("constructorKey");
- QTest::addColumn<QString>("setKey");
-
- QTest::newRow("null, null") << QString() << QString();
- QTest::newRow("null, one") << QString() << QString("one");
- QTest::newRow("one, two") << QString("one") << QString("two");
-}
-
-/*!
- Basic key testing
- */
-void tst_QSystemSemaphore::key()
-{
- QFETCH(QString, constructorKey);
- QFETCH(QString, setKey);
-
- QSystemSemaphore sem(constructorKey);
- QCOMPARE(sem.key(), constructorKey);
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-
- sem.setKey(setKey);
- QCOMPARE(sem.key(), setKey);
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::basicacquire()
-{
- QSystemSemaphore sem("QSystemSemaphore_basicacquire", 1, QSystemSemaphore::Create);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::complexacquire()
-{
- QSystemSemaphore sem("QSystemSemaphore_complexacquire", 2, QSystemSemaphore::Create);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::release()
-{
- QSystemSemaphore sem("QSystemSemaphore_release", 0, QSystemSemaphore::Create);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::basicProcesses()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 0, QSystemSemaphore::Create);
-
- QProcess acquire;
- acquire.setProcessChannelMode(QProcess::ForwardedChannels);
-
- QProcess release;
- release.setProcessChannelMode(QProcess::ForwardedChannels);
-
- acquire.start(m_helperBinary, QStringList("acquire"));
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QCOMPARE(acquire.state(), QProcess::Running);
- acquire.kill();
- release.start(m_helperBinary, QStringList("release"));
- QVERIFY2(release.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- release.waitForFinished(HELPERWAITTIME);
- QCOMPARE(acquire.state(), QProcess::NotRunning);
-#endif
-}
-
-void tst_QSystemSemaphore::processes_data()
-{
- QTest::addColumn<int>("processes");
- for (int i = 0; i < 5; ++i) {
- QTest::newRow("1 process") << 1;
- QTest::newRow("3 process") << 3;
- QTest::newRow("10 process") << 10;
- }
-}
-
-void tst_QSystemSemaphore::processes()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
-
- QFETCH(int, processes);
- QVector<QString> scripts(processes, "acquirerelease");
-
- QList<QProcess*> consumers;
- for (int i = 0; i < scripts.count(); ++i) {
- QProcess *p = new QProcess;
- p->setProcessChannelMode(QProcess::ForwardedChannels);
- consumers.append(p);
- p->start(m_helperBinary, QStringList(scripts.at(i)));
- }
-
- while (!consumers.isEmpty()) {
- consumers.first()->waitForFinished();
- QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
- QCOMPARE(consumers.first()->exitCode(), 0);
- delete consumers.takeFirst();
- }
-#endif
-}
-
-// This test only checks a system v unix behavior.
-#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
-void tst_QSystemSemaphore::undo()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
-
- QStringList acquireArguments = QStringList("acquire");
- QProcess acquire;
- acquire.setProcessChannelMode(QProcess::ForwardedChannels);
- acquire.start(m_helperBinary, acquireArguments);
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-
- // At process exit the kernel should auto undo
-
- acquire.start(m_helperBinary, acquireArguments);
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-#endif
-}
-#endif
-
-void tst_QSystemSemaphore::initialValue()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
-
- QStringList acquireArguments = QStringList("acquire");
- QStringList releaseArguments = QStringList("release");
- QProcess acquire;
- acquire.setProcessChannelMode(QProcess::ForwardedChannels);
-
- QProcess release;
- release.setProcessChannelMode(QProcess::ForwardedChannels);
-
- acquire.start(m_helperBinary, acquireArguments);
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-
- acquire.start(m_helperBinary, acquireArguments << QLatin1String("2"));
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::Running);
- acquire.kill();
-
- release.start(m_helperBinary, releaseArguments);
- QVERIFY2(release.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- release.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-#endif
-}
-
-QTEST_MAIN(tst_QSystemSemaphore)
-#include "tst_qsystemsemaphore.moc"
-
diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST
deleted file mode 100644
index 16cbab4587..0000000000
--- a/tests/auto/corelib/kernel/qtimer/BLACKLIST
+++ /dev/null
@@ -1,5 +0,0 @@
-[remainingTime]
-windows
-osx
-[basic_chrono]
-osx
diff --git a/tests/auto/corelib/kernel/qtimer/CMakeLists.txt b/tests/auto/corelib/kernel/qtimer/CMakeLists.txt
new file mode 100644
index 0000000000..6bb3b15850
--- /dev/null
+++ b/tests/auto/corelib/kernel/qtimer/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtimer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if (NOT QT_FEATURE_thread)
+ return()
+endif()
+
+function(addTimerTest test)
+ qt_internal_add_test(${test}
+ SOURCES
+ tst_qtimer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+ )
+endfunction()
+
+addTimerTest(tst_qtimer)
+
+if(QT_FEATURE_glib AND UNIX)
+ addTimerTest(tst_qtimer_no_glib)
+ qt_internal_extend_target(tst_qtimer_no_glib
+ DEFINES
+ DISABLE_GLIB
+ tst_QTimer=tst_QTimer_no_glib # Class name in the unittest
+ )
+endif()
+
diff --git a/tests/auto/corelib/kernel/qtimer/qtimer.pro b/tests/auto/corelib/kernel/qtimer/qtimer.pro
deleted file mode 100644
index 710dfea682..0000000000
--- a/tests/auto/corelib/kernel/qtimer/qtimer.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtimer
-QT = core core-private testlib
-SOURCES = tst_qtimer.cpp
-
-# Force C++17 if available
-contains(QT_CONFIG, c++1z): CONFIG += c++1z
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
index 8d194dafc1..40190ca465 100644
--- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
+++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
@@ -1,56 +1,66 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+/* WARNING: this source-code is reused by another test.
+
+ As Qt built with GUI support may use a different backend for its event loops
+ and other timer-related matters, it is important to test it in that form, as
+ well as in its GUI-less form. So this source file is reused by a build config
+ in the GUI module. Similarly, testing with and without glib is supported,
+ where relevant (see DISABLE_GLIB below).
+*/
#ifdef QT_GUI_LIB
+// When compiled as tests/auto/gui/kernel/qguitimer/'s source-code:
# include <QtGui/QGuiApplication>
#else
+// When compiled as tests/auto/corelib/kernel/qtimer/'s source-code:
# include <QtCore/QCoreApplication>
#endif
#include <QtCore/private/qglobal_p.h>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QSignalSpy>
+#include <QtTest/private/qpropertytesthelper_p.h>
#include <qtimer.h>
#include <qthread.h>
+#include <qelapsedtimer.h>
+#include <qproperty.h>
#if defined Q_OS_UNIX
#include <unistd.h>
#endif
+#ifdef DISABLE_GLIB
+static bool glibDisabled = []() {
+ qputenv("QT_NO_GLIB", "1");
+ return true;
+}();
+#endif
+
+using namespace std::chrono_literals;
+
class tst_QTimer : public QObject
{
Q_OBJECT
+public:
+ static void initMain();
+
private slots:
+ void cleanupTestCase();
void zeroTimer();
void singleShotTimeout();
void timeout();
+ void singleShotNormalizes_data();
+ void singleShotNormalizes();
+ void sequentialTimers_data();
+ void sequentialTimers();
+ void singleShotSequentialTimers_data();
+ void singleShotSequentialTimers();
void remainingTime();
+ void remainingTimeInitial_data();
+ void remainingTimeInitial();
void remainingTimeDuringActivation_data();
void remainingTimeDuringActivation();
void basic_chrono();
@@ -71,38 +81,57 @@ private slots:
void recurseOnTimeoutAndStopTimer();
void singleShotToFunctors();
void singleShot_chrono();
+ void singleShot_static();
+ void crossThreadSingleShotToFunctor_data();
void crossThreadSingleShotToFunctor();
+ void timerOrder();
+ void timerOrder_data();
+ void timerOrderBackgroundThread();
+ void timerOrderBackgroundThread_data() { timerOrder_data(); }
void dontBlockEvents();
void postedEventsShouldNotStarveTimers();
void callOnTimeout();
+
+ void bindToTimer();
+ void bindTimer();
+ void automatedBindingTests();
+
+ void negativeInterval();
+ void testTimerId();
};
void tst_QTimer::zeroTimer()
{
QTimer timer;
+ QVERIFY(!timer.isSingleShot());
timer.setInterval(0);
+ timer.setSingleShot(true);
+ QVERIFY(timer.isSingleShot());
QSignalSpy timeoutSpy(&timer, &QTimer::timeout);
timer.start();
- QCoreApplication::processEvents();
+ // Pass timeout to work round glib issue, see QTBUG-84291.
+ QCoreApplication::processEvents(QEventLoop::AllEvents, INT_MAX);
- QCOMPARE(timeoutSpy.count(), 1);
+ QCOMPARE(timeoutSpy.size(), 1);
}
void tst_QTimer::singleShotTimeout()
{
QTimer timer;
+ QVERIFY(!timer.isSingleShot());
timer.setSingleShot(true);
+ QVERIFY(timer.isSingleShot());
QSignalSpy timeoutSpy(&timer, &QTimer::timeout);
timer.start(100);
QVERIFY(timeoutSpy.wait(500));
- QCOMPARE(timeoutSpy.count(), 1);
+ QCOMPARE(timeoutSpy.size(), 1);
QTest::qWait(500);
- QCOMPARE(timeoutSpy.count(), 1);
+ QCOMPARE(timeoutSpy.size(), 1);
}
#define TIMEOUT_TIMEOUT 200
@@ -113,34 +142,227 @@ void tst_QTimer::timeout()
QSignalSpy timeoutSpy(&timer, &QTimer::timeout);
timer.start(100);
- QCOMPARE(timeoutSpy.count(), 0);
+ QCOMPARE(timeoutSpy.size(), 0);
+
+ QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.size() > 0, TIMEOUT_TIMEOUT);
+ int oldCount = timeoutSpy.size();
+
+ QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.size() > oldCount, TIMEOUT_TIMEOUT);
+}
+
+void tst_QTimer::singleShotNormalizes_data()
+{
+ QTest::addColumn<QByteArray>("slotName");
+
+ QTest::newRow("normalized") << QByteArray(SLOT(exitLoop()));
+
+ QTest::newRow("space-before") << QByteArray(SLOT( exitLoop()));
+ QTest::newRow("space-after") << QByteArray(SLOT(exitLoop ()));
+ QTest::newRow("space-around") << QByteArray(SLOT( exitLoop ()));
+ QTest::newRow("spaces-before") << QByteArray(SLOT( exitLoop()));
+ QTest::newRow("spaces-after") << QByteArray(SLOT(exitLoop ()));
+ QTest::newRow("spaces-around") << QByteArray(SLOT( exitLoop ()));
+
+ QTest::newRow("space-in-parens") << QByteArray(SLOT(exitLoop( )));
+ QTest::newRow("spaces-in-parens") << QByteArray(SLOT(exitLoop( )));
+ QTest::newRow("space-after-parens") << QByteArray(SLOT(exitLoop() ));
+ QTest::newRow("spaces-after-parens") << QByteArray(SLOT(exitLoop() ));
+}
+
+void tst_QTimer::singleShotNormalizes()
+{
+ static constexpr auto TestTimeout = 250ms;
+ QFETCH(QByteArray, slotName);
+ QEventLoop loop;
+
+ // control test: regular connection
+ {
+ QTimer timer;
+ QVERIFY(QObject::connect(&timer, SIGNAL(timeout()), &QTestEventLoop::instance(), slotName));
+ timer.setSingleShot(true);
+ timer.start(1);
+ QTestEventLoop::instance().enterLoop(TestTimeout);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ }
+
+ // non-zero time
+ QTimer::singleShot(1, &QTestEventLoop::instance(), slotName);
+ QTestEventLoop::instance().enterLoop(TestTimeout);
+ QVERIFY(!QTestEventLoop::instance().timeout());
- QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.count() > 0, TIMEOUT_TIMEOUT);
- int oldCount = timeoutSpy.count();
+ QTimer::singleShot(1ms, &QTestEventLoop::instance(), slotName);
+ QTestEventLoop::instance().enterLoop(TestTimeout);
+ QVERIFY(!QTestEventLoop::instance().timeout());
- QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.count() > oldCount, TIMEOUT_TIMEOUT);
+ // zero time
+ QTimer::singleShot(0, &QTestEventLoop::instance(), slotName);
+ QTestEventLoop::instance().enterLoop(TestTimeout);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QTimer::singleShot(0ms, &QTestEventLoop::instance(), slotName);
+ QTestEventLoop::instance().enterLoop(TestTimeout);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+}
+
+void tst_QTimer::sequentialTimers_data()
+{
+#ifdef Q_OS_WIN
+ QSKIP("The API used by QEventDispatcherWin32 doesn't respect the order");
+#endif
+ QTest::addColumn<QList<int>>("timeouts");
+ auto addRow = [](const QList<int> &l) {
+ QByteArray name;
+ int last = -1;
+ for (int i = 0; i < l.size(); ++i) {
+ Q_ASSERT_X(l[i] >= last, "tst_QTimer", "input list must be sorted");
+ name += QByteArray::number(l[i]) + ',';
+ }
+ name.chop(1);
+ QTest::addRow("%s", name.constData()) << l;
+ };
+ // PreciseTimers
+ addRow({0, 0, 0, 0, 0, 0});
+ addRow({0, 1, 2});
+ addRow({1, 1, 1, 2, 2, 2, 2});
+ addRow({1, 2, 3});
+ addRow({19, 19, 19});
+ // CoarseTimer for setInterval
+ addRow({20, 20, 20, 20, 20});
+ addRow({25, 25, 25, 25, 25, 25, 50});
+}
+
+void tst_QTimer::sequentialTimers()
+{
+ QFETCH(const QList<int>, timeouts);
+ QByteArray result, expected;
+ std::vector<std::unique_ptr<QTimer>> timers;
+ expected.resize(timeouts.size());
+ result.reserve(timeouts.size());
+ timers.reserve(timeouts.size());
+ for (int i = 0; i < timeouts.size(); ++i) {
+ auto timer = std::make_unique<QTimer>();
+ timer->setSingleShot(true);
+ timer->setInterval(timeouts[i]);
+
+ char c = 'A' + i;
+ expected[i] = c;
+ QObject::connect(timer.get(), &QTimer::timeout, this, [&result, c = c]() {
+ result.append(c);
+ });
+ timers.push_back(std::move(timer));
+ }
+
+ // start the timers
+ for (auto &timer : timers)
+ timer->start();
+
+ QTestEventLoop::instance().enterLoopMSecs(timeouts.last() * 2 + 10);
+
+ QCOMPARE(result, expected);
+}
+
+void tst_QTimer::singleShotSequentialTimers_data()
+{
+ sequentialTimers_data();
+}
+
+void tst_QTimer::singleShotSequentialTimers()
+{
+ QFETCH(const QList<int>, timeouts);
+ QByteArray result, expected;
+ expected.resize(timeouts.size());
+ result.reserve(timeouts.size());
+ for (int i = 0; i < timeouts.size(); ++i) {
+ char c = 'A' + i;
+ expected[i] = c;
+ QTimer::singleShot(timeouts[i], this, [&result, c = c]() {
+ result.append(c);
+ });
+ }
+
+ QTestEventLoop::instance().enterLoopMSecs(timeouts.last() * 2 + 10);
+
+ QCOMPARE(result, expected);
}
void tst_QTimer::remainingTime()
{
- QTimer timer;
- QSignalSpy timeoutSpy(&timer, &QTimer::timeout);
- timer.setTimerType(Qt::PreciseTimer);
- timer.start(200);
+ QTimer tested;
+ tested.setTimerType(Qt::PreciseTimer);
+
+ QTimer tester;
+ tester.setTimerType(Qt::PreciseTimer);
+ tester.setSingleShot(true);
+
+ const int testedInterval = 200;
+ const int testerInterval = 50;
+ const int expectedRemainingTime = testedInterval - testerInterval;
+
+ int testIteration = 0;
+ const int desiredTestCount = 2;
+
+ auto connection = QObject::connect(&tested, &QTimer::timeout, [&tester]() {
+ // We let tested (which isn't a single-shot) run repeatedly, to verify
+ // it *does* repeat, and check that the single-shot tester, starting
+ // at the same time, does finish first each time, by about the right duration.
+ tester.start(); // Start tester again.
+ });
+
+ QObject::connect(&tester, &QTimer::timeout, [&]() {
+ const int remainingTime = tested.remainingTime();
+ // We expect that remainingTime is at most 150 and not overdue.
+ const bool remainingTimeInRange = remainingTime > 0
+ && remainingTime <= expectedRemainingTime;
+ if (remainingTimeInRange)
+ ++testIteration;
+ else
+ testIteration = desiredTestCount; // We are going to fail on QVERIFY2()
+ // below, so we don't want to iterate
+ // anymore and quickly exit the QTRY_...()
+ // with this failure.
+ if (testIteration == desiredTestCount)
+ QObject::disconnect(connection); // Last iteration, don't start tester again.
+ QVERIFY2(remainingTimeInRange, qPrintable("Remaining time "
+ + QByteArray::number(remainingTime) + "ms outside expected range (0ms, "
+ + QByteArray::number(expectedRemainingTime) + "ms]"));
+ });
+
+ tested.start(testedInterval);
+ tester.start(testerInterval); // Start tester for the 1st time.
+
+ // Test it desiredTestCount times, give it reasonable amount of time
+ // (twice as much as needed).
+ QTRY_COMPARE_WITH_TIMEOUT(testIteration, desiredTestCount,
+ testedInterval * desiredTestCount * 2);
+}
- QCOMPARE(timeoutSpy.count(), 0);
- QTest::qWait(50);
- QCOMPARE(timeoutSpy.count(), 0);
+void tst_QTimer::remainingTimeInitial_data()
+{
+ QTest::addColumn<int>("startTimeMs");
+ QTest::addColumn<Qt::TimerType>("timerType");
- int remainingTime = timer.remainingTime();
- QVERIFY2(qAbs(remainingTime - 150) < 50, qPrintable(QString::number(remainingTime)));
+ QTest::addRow("precise time 0ms") << 0 << Qt::PreciseTimer;
+ QTest::addRow("precise time 1ms") << 1 << Qt::PreciseTimer;
+ QTest::addRow("precise time 10ms") << 10 << Qt::PreciseTimer;
- QVERIFY(timeoutSpy.wait());
- QCOMPARE(timeoutSpy.count(), 1);
+ QTest::addRow("coarse time 0ms") << 0 << Qt::CoarseTimer;
+ QTest::addRow("coarse time 1ms") << 1 << Qt::CoarseTimer;
+ QTest::addRow("coarse time 10ms") << 10 << Qt::CoarseTimer;
+}
+
+void tst_QTimer::remainingTimeInitial()
+{
+ QFETCH(int, startTimeMs);
+ QFETCH(Qt::TimerType, timerType);
- // the timer is still active, so it should have a non-zero remaining time
- remainingTime = timer.remainingTime();
- QVERIFY2(remainingTime > 150, qPrintable(QString::number(remainingTime)));
+ QTimer timer;
+ QCOMPARE(timer.timerType(), Qt::CoarseTimer);
+ timer.setTimerType(timerType);
+ QCOMPARE(timer.timerType(), timerType);
+ timer.start(startTimeMs);
+
+ const int rt = timer.remainingTime();
+ QVERIFY2(rt >= 0 && rt <= startTimeMs, qPrintable(QString::number(rt)));
}
void tst_QTimer::remainingTimeDuringActivation_data()
@@ -184,19 +406,14 @@ void tst_QTimer::remainingTimeDuringActivation()
namespace {
-#if QT_HAS_INCLUDE(<chrono>)
template <typename T>
std::chrono::milliseconds to_ms(T t)
{ return std::chrono::duration_cast<std::chrono::milliseconds>(t); }
-#endif
} // unnamed namespace
void tst_QTimer::basic_chrono()
{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires C++11 <chrono> support");
-#else
// duplicates zeroTimer, singleShotTimeout, interval and remainingTime
using namespace std::chrono;
QTimer timer;
@@ -208,36 +425,35 @@ void tst_QTimer::basic_chrono()
QCoreApplication::processEvents();
- QCOMPARE(timeoutSpy.count(), 1);
+ QCOMPARE(timeoutSpy.size(), 1);
timeoutSpy.clear();
timer.start(milliseconds(100));
- QCOMPARE(timeoutSpy.count(), 0);
+ QCOMPARE(timeoutSpy.size(), 0);
QVERIFY(timeoutSpy.wait(TIMEOUT_TIMEOUT));
- QVERIFY(timeoutSpy.count() > 0);
- int oldCount = timeoutSpy.count();
+ QVERIFY(timeoutSpy.size() > 0);
+ int oldCount = timeoutSpy.size();
QVERIFY(timeoutSpy.wait(TIMEOUT_TIMEOUT));
- QVERIFY(timeoutSpy.count() > oldCount);
+ QVERIFY(timeoutSpy.size() > oldCount);
timeoutSpy.clear();
timer.start(to_ms(microseconds(200000)));
QCOMPARE(timer.intervalAsDuration().count(), milliseconds::rep(200));
QTest::qWait(50);
- QCOMPARE(timeoutSpy.count(), 0);
+ QCOMPARE(timeoutSpy.size(), 0);
milliseconds rt = timer.remainingTimeAsDuration();
- QVERIFY2(qAbs(rt.count() - 150) < 50, qPrintable(QString::number(rt.count())));
+ QVERIFY2(rt.count() >= 50 && rt.count() <= 200, qPrintable(QString::number(rt.count())));
timeoutSpy.clear();
timer.setSingleShot(true);
timer.start(milliseconds(100));
QVERIFY(timeoutSpy.wait(TIMEOUT_TIMEOUT));
- QCOMPARE(timeoutSpy.count(), 1);
+ QCOMPARE(timeoutSpy.size(), 1);
QTest::qWait(500);
- QCOMPARE(timeoutSpy.count(), 1);
-#endif
+ QCOMPARE(timeoutSpy.size(), 1);
}
void tst_QTimer::livelock_data()
@@ -267,7 +483,8 @@ public:
secondTimerId = -1; // started later
}
- bool event(QEvent *e) {
+ bool event(QEvent *e) override
+ {
if (e->type() == 4002) {
// got the posted event
if (timeoutsForFirst == 1 && timeoutsForSecond == 0)
@@ -277,7 +494,8 @@ public:
return QObject::event(e);
}
- void timerEvent(QTimerEvent *te) {
+ void timerEvent(QTimerEvent *te) override
+ {
if (te->timerId() == firstTimerId) {
if (++timeoutsForFirst == 1) {
killTimer(extraTimerId);
@@ -335,7 +553,7 @@ public:
: inTimerEvent(false), timerEventRecursed(false), interval(interval)
{ }
- void timerEvent(QTimerEvent *timerEvent)
+ void timerEvent(QTimerEvent *timerEvent) override
{
timerEventRecursed = inTimerEvent;
if (timerEventRecursed) {
@@ -392,7 +610,7 @@ public:
: times(0), target(target), recurse(false)
{ }
- void timerEvent(QTimerEvent *timerEvent)
+ void timerEvent(QTimerEvent *timerEvent) override
{
if (++times == target) {
killTimer(timerEvent->timerId());
@@ -460,6 +678,7 @@ void tst_QTimer::moveToThread()
#endif
QTimer ti1;
QTimer ti2;
+ ti1.setSingleShot(true);
ti1.start(MOVETOTHREAD_TIMEOUT);
ti2.start(MOVETOTHREAD_TIMEOUT);
QVERIFY((ti1.timerId() & 0xffffff) != (ti2.timerId() & 0xffffff));
@@ -492,7 +711,7 @@ public:
QBasicTimer m_timer;
int m_interval;
- QTime m_startedTime;
+ QElapsedTimer m_elapsedTimer;
QEventLoop eventLoop;
inline RestartedTimerFiresTooSoonObject()
@@ -504,21 +723,21 @@ public:
static int interval = 1000;
m_interval = interval;
- m_startedTime.start();
+ m_elapsedTimer.start();
m_timer.start(interval, this);
// alternate between single-shot and 1 sec
interval = interval ? 0 : 1000;
}
- void timerEvent(QTimerEvent* ev)
+ void timerEvent(QTimerEvent* ev) override
{
if (ev->timerId() != m_timer.timerId())
return;
m_timer.stop();
- int elapsed = m_startedTime.elapsed();
+ int elapsed = m_elapsedTimer.elapsed();
if (elapsed < m_interval / 2) {
// severely too early!
@@ -556,10 +775,10 @@ public:
public slots:
void longLastingSlot()
{
- // Don't use timers for this, because we are testing them.
- QTime time;
- time.start();
- while (time.elapsed() < 200) {
+ // Don't use QTimer for this, because we are testing it.
+ QElapsedTimer control;
+ control.start();
+ while (control.elapsed() < 200) {
for (int c = 0; c < 100000; c++) {} // Mindless looping.
}
if (++count >= 2) {
@@ -598,28 +817,30 @@ void tst_QTimer::timerFiresOnlyOncePerProcessEvents()
class TimerIdPersistsAfterThreadExitThread : public QThread
{
public:
- QTimer *timer;
- int timerId, returnValue;
+ QTimer *timer = nullptr;
+ Qt::TimerId timerId = Qt::TimerId::Invalid;
+ int returnValue = -1;
- TimerIdPersistsAfterThreadExitThread()
- : QThread(), timer(0), timerId(-1), returnValue(-1)
- { }
~TimerIdPersistsAfterThreadExitThread()
{
delete timer;
}
- void run()
+ void run() override
{
QEventLoop eventLoop;
timer = new QTimer;
connect(timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
timer->start(100);
- timerId = timer->timerId();
+ timerId = timer->id();
returnValue = eventLoop.exec();
}
};
+namespace {
+int operator&(Qt::TimerId id, int i) { return qToUnderlying(id) & i; }
+}
+
void tst_QTimer::timerIdPersistsAfterThreadExit()
{
TimerIdPersistsAfterThreadExitThread thread;
@@ -645,6 +866,19 @@ void tst_QTimer::cancelLongTimer()
QVERIFY(!timer.isActive());
}
+void tst_QTimer::testTimerId()
+{
+ QTimer timer;
+ timer.start(100ms);
+ QVERIFY(timer.isActive());
+ QCOMPARE_GT(timer.timerId(), 0);
+ QCOMPARE_GT(timer.id(), Qt::TimerId::Invalid);
+ timer.stop();
+ QVERIFY(!timer.isActive());
+ QCOMPARE(timer.timerId(), -1);
+ QCOMPARE(timer.id(), Qt::TimerId::Invalid);
+}
+
class TimeoutCounter : public QObject
{
Q_OBJECT
@@ -739,7 +973,7 @@ public:
quitEventLoop_noexcept();
}
- static void quitEventLoop_noexcept() Q_DECL_NOTHROW
+ static void quitEventLoop_noexcept() noexcept
{
QVERIFY(!_e.isNull());
_e->quit();
@@ -819,7 +1053,7 @@ void tst_QTimer::singleShotToFunctors()
thread.wait();
struct MoveOnly : CountedStruct {
- Q_DISABLE_COPY(MoveOnly);
+ Q_DISABLE_COPY(MoveOnly)
MoveOnly(MoveOnly &&o) : CountedStruct(std::move(o)) {};
MoveOnly(int *c) : CountedStruct(c) {}
};
@@ -832,9 +1066,6 @@ void tst_QTimer::singleShotToFunctors()
void tst_QTimer::singleShot_chrono()
{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires C++11 <chrono> support");
-#else
// duplicates singleShotStaticFunctionZeroTimeout and singleShotToFunctors
using namespace std::chrono;
{
@@ -871,7 +1102,6 @@ void tst_QTimer::singleShot_chrono()
QTRY_COMPARE(count, 3);
_e.reset();
-#endif
}
class DontBlockEvents : public QObject
@@ -879,7 +1109,7 @@ class DontBlockEvents : public QObject
Q_OBJECT
public:
DontBlockEvents();
- void timerEvent(QTimerEvent*);
+ void timerEvent(QTimerEvent*) override;
int count;
int total;
@@ -953,30 +1183,57 @@ void tst_QTimer::postedEventsShouldNotStarveTimers()
timer.start();
SlotRepeater slotRepeater;
slotRepeater.repeatThisSlot();
- QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.count() > 5, 100);
+ QTRY_VERIFY_WITH_TIMEOUT(timeoutSpy.size() > 5, 100);
}
struct DummyFunctor {
- void operator()() {}
+ static QThread *callThread;
+ void operator()() {
+ callThread = QThread::currentThread();
+ callThread->quit();
+ }
};
+QThread *DummyFunctor::callThread = nullptr;
+
+void tst_QTimer::crossThreadSingleShotToFunctor_data()
+{
+ QTest::addColumn<int>("timeout");
+
+ QTest::addRow("zero-timer") << 0;
+ QTest::addRow("1ms") << 1;
+}
void tst_QTimer::crossThreadSingleShotToFunctor()
{
- // We're testing for crashes here, so the test simply running to
- // completion is considered a success
- QThread t;
- t.start();
+ QFETCH(int, timeout);
+ // We're also testing for crashes here, so the test simply running to
+ // completion is part of the success
+ DummyFunctor::callThread = nullptr;
- QObject* o = new QObject();
+ QThread t;
+ std::unique_ptr<QObject> o(new QObject());
o->moveToThread(&t);
- for (int i = 0; i < 10000; i++) {
- QTimer::singleShot(0, o, DummyFunctor());
- }
+ QTimer::singleShot(timeout, o.get(), DummyFunctor());
- t.quit();
+ // wait enough time for the timer to have timed out before the timer
+ // could be start in the receiver's thread.
+ QTest::qWait(10 + timeout * 10);
+ t.start();
t.wait();
- delete o;
+ QCOMPARE(DummyFunctor::callThread, &t);
+
+ // continue with a stress test - the calling thread is busy, the
+ // timer should still fire and no crashes.
+ DummyFunctor::callThread = nullptr;
+ t.start();
+ for (int i = 0; i < 10000; i++)
+ QTimer::singleShot(timeout, o.get(), DummyFunctor());
+
+ t.wait();
+ o.reset();
+
+ QCOMPARE(DummyFunctor::callThread, &t);
}
void tst_QTimer::callOnTimeout()
@@ -996,7 +1253,7 @@ void tst_QTimer::callOnTimeout()
QTest::qWait(100);
QCOMPARE(count, 2);
- QCOMPARE(timeoutSpy.count(), 1);
+ QCOMPARE(timeoutSpy.size(), 1);
// Test that connection is bound to context lifetime
QVERIFY(connection);
@@ -1004,5 +1261,295 @@ void tst_QTimer::callOnTimeout()
QVERIFY(!connection);
}
+void tst_QTimer::bindToTimer()
+{
+ QTimer timer;
+
+ // singleShot property
+ QProperty<bool> singleShot;
+ singleShot.setBinding(timer.bindableSingleShot().makeBinding());
+ QCOMPARE(timer.isSingleShot(), singleShot);
+
+ timer.setSingleShot(true);
+ QVERIFY(singleShot);
+ timer.setSingleShot(false);
+ QVERIFY(!singleShot);
+
+ // interval property
+ QProperty<int> interval;
+ interval.setBinding([&](){ return timer.interval(); });
+ QCOMPARE(timer.interval(), interval);
+
+ timer.setInterval(10);
+ QCOMPARE(interval, 10);
+ timer.setInterval(100);
+ QCOMPARE(interval, 100);
+
+ // timerType property
+ QProperty<Qt::TimerType> timerType;
+ timerType.setBinding(timer.bindableTimerType().makeBinding());
+ QCOMPARE(timer.timerType(), timerType);
+
+ timer.setTimerType(Qt::PreciseTimer);
+ QCOMPARE(timerType, Qt::PreciseTimer);
+
+ timer.setTimerType(Qt::VeryCoarseTimer);
+ QCOMPARE(timerType, Qt::VeryCoarseTimer);
+
+ // active property
+ QProperty<bool> active;
+ active.setBinding([&](){ return timer.isActive(); });
+ QCOMPARE(active, timer.isActive());
+
+ timer.start(1000);
+ QVERIFY(active);
+
+ timer.stop();
+ QVERIFY(!active);
+
+ auto ignoreMsg = [] {
+ QTest::ignoreMessage(QtWarningMsg,
+ "QObject::startTimer: Timers cannot have negative intervals");
+ };
+
+ // also test that using negative interval updates the binding correctly
+ timer.start(100);
+ QVERIFY(active);
+ ignoreMsg();
+ timer.setInterval(-100);
+ QVERIFY(!active);
+ timer.start(100);
+ QVERIFY(active);
+ ignoreMsg();
+ timer.start(-100);
+ QVERIFY(!active);
+}
+
+void tst_QTimer::bindTimer()
+{
+ QTimer timer;
+
+ // singleShot property
+ QVERIFY(!timer.isSingleShot());
+
+ QProperty<bool> singleShot;
+ timer.bindableSingleShot().setBinding(Qt::makePropertyBinding(singleShot));
+
+ singleShot = true;
+ QVERIFY(timer.isSingleShot());
+ singleShot = false;
+ QVERIFY(!timer.isSingleShot());
+
+ // interval property
+ QCOMPARE(timer.interval(), 0);
+
+ QProperty<int> interval;
+ timer.bindableInterval().setBinding(Qt::makePropertyBinding(interval));
+
+ interval = 10;
+ QCOMPARE(timer.interval(), 10);
+ interval = 100;
+ QCOMPARE(timer.interval(), 100);
+ timer.setInterval(50);
+ QCOMPARE(timer.interval(), 50);
+ interval = 30;
+ QCOMPARE(timer.interval(), 50);
+
+ // timerType property
+ QCOMPARE(timer.timerType(), Qt::CoarseTimer);
+
+ QProperty<Qt::TimerType> timerType;
+ timer.bindableTimerType().setBinding(Qt::makePropertyBinding(timerType));
+
+ timerType = Qt::PreciseTimer;
+ QCOMPARE(timer.timerType(), Qt::PreciseTimer);
+ timerType = Qt::VeryCoarseTimer;
+ QCOMPARE(timer.timerType(), Qt::VeryCoarseTimer);
+}
+
+void tst_QTimer::automatedBindingTests()
+{
+ QTimer timer;
+
+ QVERIFY(!timer.isSingleShot());
+ QTestPrivate::testReadWritePropertyBasics(timer, true, false, "singleShot");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QTimer::singleShot");
+ return;
+ }
+
+ QCOMPARE_NE(timer.interval(), 10);
+ QTestPrivate::testReadWritePropertyBasics(timer, 10, 20, "interval");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QTimer::interval");
+ return;
+ }
+
+ QCOMPARE_NE(timer.timerType(), Qt::PreciseTimer);
+ QTestPrivate::testReadWritePropertyBasics(timer, Qt::PreciseTimer, Qt::CoarseTimer,
+ "timerType");
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QTimer::timerType");
+ return;
+ }
+
+ timer.start(1000);
+ QVERIFY(timer.isActive());
+ QTestPrivate::testReadOnlyPropertyBasics(timer, true, false, "active",
+ [&timer]() { timer.stop(); });
+ if (QTest::currentTestFailed()) {
+ qDebug("Failed property test for QTimer::active");
+ return;
+ }
+}
+
+void tst_QTimer::negativeInterval()
+{
+ auto ignoreMsg = [] {
+ QTest::ignoreMessage(QtWarningMsg,
+ "QObject::startTimer: Timers cannot have negative intervals");
+ };
+
+ QTimer timer;
+
+ // Starting with a negative interval does not change active state.
+ ignoreMsg();
+ timer.start(-100ms);
+ QVERIFY(!timer.isActive());
+
+ // Updating the interval to a negative value stops the timer and changes
+ // the active state.
+ timer.start(100ms);
+ QVERIFY(timer.isActive());
+ ignoreMsg();
+ timer.setInterval(-100);
+ QVERIFY(!timer.isActive());
+
+ // Starting with a negative interval when already started leads to stop
+ // and inactive state.
+ timer.start(100);
+ QVERIFY(timer.isActive());
+ ignoreMsg();
+ timer.start(-100ms);
+ QVERIFY(!timer.isActive());
+}
+
+class OrderHelper : public QObject
+{
+ Q_OBJECT
+public:
+ enum CallType
+ {
+ String,
+ PMF,
+ Functor,
+ FunctorNoCtx
+ };
+ Q_ENUM(CallType)
+ QList<CallType> calls;
+
+ void triggerCall(CallType callType)
+ {
+ switch (callType)
+ {
+ case String:
+ QTimer::singleShot(0, this, SLOT(stringSlot()));
+ break;
+ case PMF:
+ QTimer::singleShot(0, this, &OrderHelper::pmfSlot);
+ break;
+ case Functor:
+ QTimer::singleShot(0, this, [this]() { functorSlot(); });
+ break;
+ case FunctorNoCtx:
+ QTimer::singleShot(0, [this]() { functorNoCtxSlot(); });
+ break;
+ }
+ }
+
+public slots:
+ void stringSlot() { calls << String; }
+ void pmfSlot() { calls << PMF; }
+ void functorSlot() { calls << Functor; }
+ void functorNoCtxSlot() { calls << FunctorNoCtx; }
+};
+
+Q_DECLARE_METATYPE(OrderHelper::CallType)
+
+void tst_QTimer::timerOrder()
+{
+ QFETCH(QList<OrderHelper::CallType>, calls);
+
+ OrderHelper helper;
+
+ for (const auto call : calls)
+ helper.triggerCall(call);
+
+ QTRY_COMPARE(helper.calls, calls);
+}
+
+void tst_QTimer::timerOrder_data()
+{
+ QTest::addColumn<QList<OrderHelper::CallType>>("calls");
+
+ QList<OrderHelper::CallType> calls = {
+ OrderHelper::String, OrderHelper::PMF,
+ OrderHelper::Functor, OrderHelper::FunctorNoCtx
+ };
+ std::sort(calls.begin(), calls.end());
+
+ int permutation = 0;
+ do {
+ QTest::addRow("permutation=%d", permutation) << calls;
+ ++permutation;
+ } while (std::next_permutation(calls.begin(), calls.end()));
+}
+
+void tst_QTimer::timerOrderBackgroundThread()
+{
+ auto *thread = QThread::create([this]() { timerOrder(); });
+ thread->start();
+ QVERIFY(thread->wait());
+ delete thread;
+}
+
+struct StaticSingleShotUser
+{
+ StaticSingleShotUser()
+ {
+ for (auto call : calls())
+ helper.triggerCall(call);
+ }
+ OrderHelper helper;
+
+ static QList<OrderHelper::CallType> calls()
+ {
+ return {OrderHelper::String, OrderHelper::PMF,
+ OrderHelper::Functor, OrderHelper::FunctorNoCtx};
+ }
+};
+
+// NOTE: to prevent any static initialization order fiasco, we implement
+// initMain() to instantiate staticSingleShotUser before qApp
+
+static StaticSingleShotUser *s_staticSingleShotUser = nullptr;
+
+void tst_QTimer::initMain()
+{
+ s_staticSingleShotUser = new StaticSingleShotUser;
+}
+
+void tst_QTimer::cleanupTestCase()
+{
+ delete s_staticSingleShotUser;
+}
+
+void tst_QTimer::singleShot_static()
+{
+ QCoreApplication::processEvents();
+ QCOMPARE(s_staticSingleShotUser->helper.calls, s_staticSingleShotUser->calls());
+}
+
QTEST_MAIN(tst_QTimer)
+
#include "tst_qtimer.moc"
diff --git a/tests/auto/corelib/kernel/qtranslator/CMakeLists.txt b/tests/auto/corelib/kernel/qtranslator/CMakeLists.txt
new file mode 100644
index 0000000000..92b6edb17c
--- /dev/null
+++ b/tests/auto/corelib/kernel/qtranslator/CMakeLists.txt
@@ -0,0 +1,56 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtranslator Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtranslator LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if (NOT QT_FEATURE_thread)
+ return()
+endif()
+
+qt_internal_add_test(tst_qtranslator
+ SOURCES
+ tst_qtranslator.cpp
+)
+
+# Resources:
+set(qtranslator_resource_files
+ "dependencies_la.qm"
+ "hellotr_empty.qm"
+ "hellotr_la.qm"
+ "msgfmt_from_po.qm"
+)
+
+qt_internal_add_resource(tst_qtranslator "qtranslator"
+ PREFIX
+ "/tst_qtranslator"
+ FILES
+ ${qtranslator_resource_files}
+)
+
+## Scopes:
+#####################################################################
+
+if(ANDROID)
+ # Resources:
+ set(android_testdata_resource_files
+ "dependencies_la.qm"
+ "hellotr_empty.qm"
+ "hellotr_la.qm"
+ "msgfmt_from_po.qm"
+ )
+
+ qt_internal_add_resource(tst_qtranslator "android_testdata"
+ PREFIX
+ "/android_testdata"
+ FILES
+ ${android_testdata_resource_files}
+ )
+endif()
diff --git a/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc b/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc
deleted file mode 100644
index 39b85db664..0000000000
--- a/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
- <qresource prefix="/android_testdata">
- <file>hellotr_la.qm</file>
- <file>hellotr_empty.qm</file>
- <file>msgfmt_from_po.qm</file>
- <file>dependencies_la.qm</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm b/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm
index cc42afe05c..25c0aad583 100644
--- a/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm
+++ b/tests/auto/corelib/kernel/qtranslator/hellotr_la.qm
Binary files differ
diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro
deleted file mode 100644
index a985f35a14..0000000000
--- a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtranslator
-QT = core testlib
-SOURCES = tst_qtranslator.cpp
-RESOURCES += qtranslator.qrc
-
-android:!android-embedded: RESOURCES += android_testdata.qrc
-else: TESTDATA += dependencies_la.qm hellotr_empty.qm hellotr_la.qm msgfmt_from_po.qm
-
diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc b/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc
deleted file mode 100644
index cb82c6cc95..0000000000
--- a/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
- <qresource prefix="/tst_qtranslator">
- <file>hellotr_la.qm</file>
- <file>hellotr_empty.qm</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp
index 40a29c723c..c76500ea11 100644
--- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp
+++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp
@@ -1,34 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QWaitCondition>
+#include <QMutex>
+#include <QStandardPaths>
#include <qtranslator.h>
#include <qfile.h>
+#include <qtemporarydir.h>
+
+#ifdef Q_OS_ANDROID
+#include <QDirIterator>
+#endif
class tst_QTranslator : public QObject
{
@@ -37,12 +20,14 @@ class tst_QTranslator : public QObject
public:
tst_QTranslator();
protected:
- bool eventFilter(QObject *obj, QEvent *event);
+ bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void initTestCase();
+ void init();
void load_data();
void load();
+ void loadLocale();
void threadLoad();
void testLanguageChange();
void plural();
@@ -64,38 +49,14 @@ tst_QTranslator::tst_QTranslator()
void tst_QTranslator::initTestCase()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- QString sourceDir(":/android_testdata/");
- QDirIterator it(sourceDir, QDirIterator::Subdirectories);
- while (it.hasNext()) {
- it.next();
-
- QFileInfo sourceFileInfo = it.fileInfo();
- if (!sourceFileInfo.isDir()) {
- QFileInfo destinationFileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/') + sourceFileInfo.filePath().mid(sourceDir.length()));
-
- if (!destinationFileInfo.exists()) {
- QVERIFY(QDir().mkpath(destinationFileInfo.path()));
- QVERIFY(QFile::copy(sourceFileInfo.filePath(), destinationFileInfo.filePath()));
- }
- }
- }
-
- QDir::setCurrent(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
-#endif
-
- // chdir into the directory containing our testdata,
- // to make the code simpler (load testdata via relative paths)
-#ifdef Q_OS_WINRT
- // ### TODO: Use this for all platforms in 5.7
- dataDir = QEXTRACTTESTDATA(QStringLiteral("/"));
+ dataDir = QEXTRACTTESTDATA(QStringLiteral("/tst_qtranslator"));
QVERIFY2(!dataDir.isNull(), qPrintable("Could not extract test data"));
- QVERIFY2(QDir::setCurrent(dataDir->path()), qPrintable("Could not chdir to " + dataDir->path()));
-#else // !Q_OS_WINRT
- QString testdata_dir = QFileInfo(QFINDTESTDATA("hellotr_la.qm")).absolutePath();
- QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
-#endif // !Q_OS_WINRT
+}
+void tst_QTranslator::init()
+{
+ QVERIFY2(QDir::setCurrent(dataDir->path()),
+ qPrintable("Could not chdir to " + dataDir->path()));
}
bool tst_QTranslator::eventFilter(QObject *, QEvent *event)
@@ -110,9 +71,10 @@ void tst_QTranslator::load_data()
QTest::addColumn<QString>("filepath");
QTest::addColumn<bool>("isEmpty");
QTest::addColumn<QString>("translation");
+ QTest::addColumn<QString>("language");
- QTest::newRow("hellotr_la") << "hellotr_la.qm" << false << "Hallo Welt!";
- QTest::newRow("hellotr_empty") << "hellotr_empty.qm" << true << "";
+ QTest::newRow("hellotr_la") << "hellotr_la.qm" << false << "Hallo Welt!" << "de";
+ QTest::newRow("hellotr_empty") << "hellotr_empty.qm" << true << "" << "";
}
void tst_QTranslator::load()
@@ -120,37 +82,112 @@ void tst_QTranslator::load()
QFETCH(QString, filepath);
QFETCH(bool, isEmpty);
QFETCH(QString, translation);
+ QFETCH(QString, language);
{
QTranslator tor;
QVERIFY(tor.load(QFileInfo(filepath).baseName()));
QCOMPARE(tor.isEmpty(), isEmpty);
QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation);
+ QCOMPARE(tor.filePath(), filepath);
+ QCOMPARE(tor.language(), language);
}
{
QFile file(filepath);
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QByteArray data = file.readAll();
QTranslator tor;
QVERIFY(tor.load((const uchar *)data.constData(), data.length()));
QCOMPARE(tor.isEmpty(), isEmpty);
QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation);
+ QCOMPARE(tor.filePath(), "");
+ QCOMPARE(tor.language(), language);
}
{
QTranslator tor;
- QVERIFY(tor.load(QString(":/tst_qtranslator/%1").arg(filepath)));
+ QString path = QString(":/tst_qtranslator/%1").arg(filepath);
+ QVERIFY(tor.load(path));
QCOMPARE(tor.isEmpty(), isEmpty);
QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation);
+ QCOMPARE(tor.filePath(), path);
+ QCOMPARE(tor.language(), language);
+ }
+}
+
+void tst_QTranslator::loadLocale()
+{
+ QLocale locale;
+ auto localeName = locale.uiLanguages(QLocale::TagSeparator::Underscore).value(0);
+ if (localeName.isEmpty())
+ QSKIP("This test requires at least one available UI language.");
+
+ QByteArray ba;
+ {
+ QFile file(":/tst_qtranslator/hellotr_la.qm");
+ QVERIFY2(file.open(QFile::ReadOnly), qPrintable(file.errorString()));
+ ba = file.readAll();
+ QVERIFY(!ba.isEmpty());
+ }
+
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+
+ auto path = dir.path();
+ QFile file(path + "/dummy");
+ QVERIFY2(file.open(QFile::WriteOnly), qPrintable(file.errorString()));
+ QCOMPARE(file.write(ba), ba.size());
+ file.close();
+
+ /*
+ Test the following order:
+
+ /tmp/tmpDir/foo-en_US.qm
+ /tmp/tmpDir/foo-en_US
+ /tmp/tmpDir/foo-en.qm
+ /tmp/tmpDir/foo-en
+ /tmp/tmpDir/foo.qm
+ /tmp/tmpDir/foo-
+ /tmp/tmpDir/foo
+ */
+
+ QStringList files;
+ while (true) {
+ files.append(path + "/foo-" + localeName + ".qm");
+ QVERIFY2(file.copy(files.last()), qPrintable(file.errorString()));
+
+ files.append(path + "/foo-" + localeName);
+ QVERIFY2(file.copy(files.last()), qPrintable(file.errorString()));
+
+ int rightmost = localeName.lastIndexOf(QLatin1Char('_'));
+ if (rightmost <= 0)
+ break;
+ localeName.truncate(rightmost);
+ }
+
+ files.append(path + "/foo.qm");
+ QVERIFY2(file.copy(files.last()), qPrintable(file.errorString()));
+
+ files.append(path + "/foo-");
+ QVERIFY2(file.copy(files.last()), qPrintable(file.errorString()));
+
+ files.append(path + "/foo");
+ QVERIFY2(file.rename(files.last()), qPrintable(file.errorString()));
+
+ QTranslator tor;
+ for (const auto &filePath : files) {
+ QVERIFY(tor.load(locale, "foo", "-", path, ".qm"));
+ QCOMPARE(tor.filePath(), filePath);
+ QVERIFY2(file.remove(filePath), qPrintable(file.errorString()));
}
}
class TranslatorThread : public QThread
{
- void run() {
+ void run() override {
QTranslator tor( 0 );
- tor.load("hellotr_la");
+ (void)tor.load("hellotr_la");
if (tor.isEmpty())
qFatal("Could not load translation");
@@ -172,17 +209,17 @@ void tst_QTranslator::testLanguageChange()
languageChangeEventCounter = 0;
QTranslator *tor = new QTranslator;
- tor->load("hellotr_la.qm");
+ QVERIFY(tor->load("hellotr_la.qm"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 0);
- tor->load("doesn't exist, same as clearing");
+ QVERIFY(!tor->load("doesn't exist, same as clearing"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 0);
- tor->load("hellotr_la.qm");
+ QVERIFY(tor->load("hellotr_la.qm"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 0);
@@ -192,12 +229,12 @@ void tst_QTranslator::testLanguageChange()
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 1);
- tor->load("doesn't exist, same as clearing");
+ QVERIFY(!tor->load("doesn't exist, same as clearing"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 2);
- tor->load("hellotr_la.qm");
+ QVERIFY(tor->load("hellotr_la.qm"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 3);
@@ -207,7 +244,7 @@ void tst_QTranslator::testLanguageChange()
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 4);
- tor->load("doesn't exist, same as clearing");
+ QVERIFY(!tor->load("doesn't exist, same as clearing"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 4);
@@ -217,7 +254,7 @@ void tst_QTranslator::testLanguageChange()
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 4);
- tor->load("hellotr_la.qm");
+ QVERIFY(tor->load("hellotr_la.qm"));
qApp->sendPostedEvents();
qApp->sendPostedEvents();
QCOMPARE(languageChangeEventCounter, 5);
@@ -234,7 +271,7 @@ void tst_QTranslator::plural()
{
QTranslator tor( 0 );
- tor.load("hellotr_la");
+ QVERIFY(tor.load("hellotr_la"));
QVERIFY(!tor.isEmpty());
QCoreApplication::installTranslator(&tor);
QCOMPARE(QCoreApplication::translate("QPushButton", "Hello %n world(s)!", 0, 0), QLatin1String("Hallo 0 Welten!"));
@@ -245,7 +282,7 @@ void tst_QTranslator::plural()
void tst_QTranslator::translate_qm_file_generated_with_msgfmt()
{
QTranslator translator;
- translator.load("msgfmt_from_po");
+ QVERIFY(translator.load("msgfmt_from_po"));
qApp->installTranslator(&translator);
QCOMPARE(QCoreApplication::translate("", "Intro"), QLatin1String("Einleitung"));
@@ -266,7 +303,7 @@ void tst_QTranslator::loadDirectory()
QVERIFY(QFileInfo("../" + current_base).isDir());
QTranslator tor;
- tor.load(current_base, "..");
+ QVERIFY(!tor.load(current_base, ".."));
QVERIFY(tor.isEmpty());
}
@@ -275,7 +312,7 @@ void tst_QTranslator::dependencies()
{
// load
QTranslator tor;
- tor.load("dependencies_la");
+ QVERIFY(tor.load("dependencies_la"));
QVERIFY(!tor.isEmpty());
QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!"));
@@ -292,12 +329,21 @@ void tst_QTranslator::dependencies()
{
QTranslator tor( 0 );
QFile file("dependencies_la.qm");
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QByteArray data = file.readAll();
- tor.load((const uchar *)data.constData(), data.length());
+ QVERIFY(tor.load((const uchar *)data.constData(), data.length()));
QVERIFY(!tor.isEmpty());
QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!"));
}
+
+ {
+ // Test resolution of paths relative to main file
+ const QString absoluteFile = QFileInfo("dependencies_la").absoluteFilePath();
+ QDir::setCurrent(QDir::tempPath());
+ QTranslator tor;
+ QVERIFY(tor.load(absoluteFile));
+ QVERIFY(!tor.isEmpty());
+ }
}
struct TranslateThread : public QThread
@@ -307,10 +353,10 @@ struct TranslateThread : public QThread
QMutex startupLock;
QWaitCondition runningCondition;
- void run() {
+ void run() override {
bool startSignalled = false;
- while (terminate.load() == 0) {
+ while (terminate.loadRelaxed() == 0) {
const QString result = QCoreApplication::translate("QPushButton", "Hello %n world(s)!", 0, 0);
if (!startSignalled) {
@@ -337,9 +383,9 @@ void tst_QTranslator::translationInThreadWhileInstallingTranslator()
thread.runningCondition.wait(&thread.startupLock);
- QTranslator *tor = new QTranslator;
- tor->load("hellotr_la");
- QCoreApplication::installTranslator(tor);
+ QTranslator tor;
+ QVERIFY(tor.load("hellotr_la"));
+ QVERIFY(QCoreApplication::installTranslator(&tor));
++thread.terminate;
diff --git a/tests/auto/corelib/kernel/qvariant/CMakeLists.txt b/tests/auto/corelib/kernel/qvariant/CMakeLists.txt
new file mode 100644
index 0000000000..eae9c0d30e
--- /dev/null
+++ b/tests/auto/corelib/kernel/qvariant/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qvariant Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qvariant LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Resources:
+set(qvariant_resource_files
+ "stream/qt4.9/"
+ "stream/qt5.0/"
+)
+
+qt_internal_add_test(tst_qvariant
+ SOURCES
+ tst_qvariant.cpp
+ INCLUDE_DIRECTORIES
+ ../../../other/qvariant_common
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::TestPrivate
+ TESTDATA ${qvariant_resource_files}
+ BUILTIN_TESTDATA
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qvariant CONDITION MSVC
+ COMPILE_OPTIONS
+ /bigobj
+)
+
+qt_internal_extend_target(tst_qvariant CONDITION NOT QT_FEATURE_doubleconversion AND NOT QT_FEATURE_system_doubleconversion
+ DEFINES
+ QT_NO_DOUBLECONVERSION
+)
diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro
deleted file mode 100644
index a620be0091..0000000000
--- a/tests/auto/corelib/kernel/qvariant/qvariant.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qvariant
-QT = core-private testlib
-INCLUDEPATH += $$PWD/../../../other/qvariant_common
-SOURCES = tst_qvariant.cpp
-RESOURCES += qvariant.qrc
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-qtConfig(c++14): CONFIG += c++14
-qtConfig(c++1z): CONFIG += c++1z
-!qtConfig(doubleconversion):!qtConfig(system-doubleconversion) {
- DEFINES += QT_NO_DOUBLECONVERSION
-}
diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.qrc b/tests/auto/corelib/kernel/qvariant/qvariant.qrc
deleted file mode 100644
index e6f7bdac80..0000000000
--- a/tests/auto/corelib/kernel/qvariant/qvariant.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>stream/qt4.9/</file>
- <file>stream/qt5.0/</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt4.9/qregexp.bin b/tests/auto/corelib/kernel/qvariant/stream/qt4.9/qregexp.bin
deleted file mode 100644
index db8518e064..0000000000
--- a/tests/auto/corelib/kernel/qvariant/stream/qt4.9/qregexp.bin
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregexp.bin b/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregexp.bin
deleted file mode 100644
index db8518e064..0000000000
--- a/tests/auto/corelib/kernel/qvariant/stream/qt5.0/qregexp.bin
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 4da34c407e..23d41cafb2 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -1,79 +1,149 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qvariant.h>
-#include <qbitarray.h>
-#include <qbytearraylist.h>
-#include <qdatetime.h>
-#include <qmap.h>
-#include <qiodevice.h>
-#include <qurl.h>
-#include <qlocale.h>
-#include <qdebug.h>
-#include <qjsondocument.h>
-#include <quuid.h>
-
-#include <limits.h>
+
+// don't assume <type_traits>
+template <typename T, typename U>
+constexpr inline bool my_is_same_v = false;
+template <typename T>
+constexpr inline bool my_is_same_v<T, T> = true;
+
+#define CHECK_IMPL(func, arg, Variant, cvref, R) \
+ static_assert(my_is_same_v<decltype( func < arg >(std::declval< Variant cvref >())), R cvref >)
+
+#define CHECK_GET_IF(Variant, cvref) \
+ CHECK_IMPL(get_if, int, Variant, cvref *, int)
+
+#define CHECK_GET(Variant, cvref) \
+ CHECK_IMPL(get, int, Variant, cvref, int)
+
+CHECK_GET_IF(QVariant, /* unadorned */);
+CHECK_GET_IF(QVariant, const);
+
+CHECK_GET(QVariant, &);
+CHECK_GET(QVariant, const &);
+CHECK_GET(QVariant, &&);
+CHECK_GET(QVariant, const &&);
+
+// check for a type derived from QVariant:
+
+struct MyVariant : QVariant
+{
+ using QVariant::QVariant;
+};
+
+CHECK_GET_IF(MyVariant, /* unadorned */);
+CHECK_GET_IF(MyVariant, const);
+
+CHECK_GET(MyVariant, &);
+CHECK_GET(MyVariant, const &);
+CHECK_GET(MyVariant, &&);
+CHECK_GET(MyVariant, const &&);
+
+#undef CHECK_GET_IF
+#undef CHECK_GET
+#undef CHECK_IMPL
+
+#include <QTest>
+
+// Please stick to alphabetic order.
+#include <QAssociativeIterable>
+#include <QBitArray>
+#include <QBuffer>
+#include <QByteArrayList>
+#include <QDateTime>
+#include <QDebug>
+#include <QDir>
+#include <QEasingCurve>
+#include <QMap>
+#include <QIODevice>
+#include <QHash>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QLocale>
+#include <QQueue>
+#include <QRegularExpression>
+#include <QScopeGuard>
+#include <QSequentialIterable>
+#include <QSet>
+#include <QStack>
+#include <QTimeZone>
+#include <QtNumeric>
+#include <QUrl>
+#include <QUuid>
+
+#include <private/qcomparisontesthelper_p.h>
+#include <private/qlocale_p.h>
+#include <private/qmetatype_p.h>
+#include "tst_qvariant_common.h"
+
+#include <limits>
#include <float.h>
#include <cmath>
-#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
#include <variant>
-#endif
-#include <QLinkedList>
-#include <QRegularExpression>
-#include <QDir>
-#include <QBuffer>
-#include "qnumeric.h"
+#include <unordered_map>
-#include <private/qlocale_p.h>
-#include "tst_qvariant_common.h"
+using namespace Qt::StringLiterals;
class CustomNonQObject;
+struct NonDefaultConstructible;
-#if defined(Q_COMPILER_CLASS_ENUM)
-#define ENUM_SIZE(X) : X
-#else
-#define ENUM_SIZE(X)
-#endif
+template<typename T, typename = void>
+struct QVariantFromValueCompiles
+{
+ static inline constexpr bool value = false;
+};
+
+template<typename T>
+struct QVariantFromValueCompiles<T, std::void_t<decltype (QVariant::fromValue(std::declval<T>()))>>
+{
+ static inline constexpr bool value = true;
+};
+
+static_assert(QVariantFromValueCompiles<int>::value);
+static_assert(!QVariantFromValueCompiles<QObject>::value);
+
+enum EnumTest_Enum0 { EnumTest_Enum0_value = 42, EnumTest_Enum0_negValue = -8 };
+Q_DECLARE_METATYPE(EnumTest_Enum0)
+enum EnumTest_Enum1 : qint64 { EnumTest_Enum1_value = 42, EnumTest_Enum1_bigValue = (Q_INT64_C(1) << 33) + 50 };
+Q_DECLARE_METATYPE(EnumTest_Enum1)
+
+enum EnumTest_Enum3 : qint64 { EnumTest_Enum3_value = -47, EnumTest_Enum3_bigValue = (Q_INT64_C(1) << 56) + 5 };
+Q_DECLARE_METATYPE(EnumTest_Enum3)
+enum EnumTest_Enum4 : quint64 { EnumTest_Enum4_value = 47, EnumTest_Enum4_bigValue = (Q_INT64_C(1) << 52) + 45 };
+Q_DECLARE_METATYPE(EnumTest_Enum4)
+enum EnumTest_Enum5 : uint { EnumTest_Enum5_value = 47 };
+Q_DECLARE_METATYPE(EnumTest_Enum5)
+enum EnumTest_Enum6 : uchar { EnumTest_Enum6_value = 47 };
+Q_DECLARE_METATYPE(EnumTest_Enum6)
+enum class EnumTest_Enum7 { EnumTest_Enum7_value = 47, ensureSignedEnum7 = -1 };
+Q_DECLARE_METATYPE(EnumTest_Enum7)
+enum EnumTest_Enum8 : short { EnumTest_Enum8_value = 47 };
+Q_DECLARE_METATYPE(EnumTest_Enum8)
+
+template <typename T> int qToUnderlying(QFlags<T> f)
+{
+ return f.toInt();
+}
class tst_QVariant : public QObject
{
Q_OBJECT
+ static void runTestFunction()
+ {
+ QFETCH(QFunctionPointer, testFunction);
+ testFunction();
+ }
+
public:
- tst_QVariant(QObject *parent = 0)
+ tst_QVariant(QObject *parent = nullptr)
: QObject(parent), customNonQObjectPointer(0)
{
-
}
@@ -82,15 +152,15 @@ public:
enum MetaEnumTest_Enum1 : qint64 { MetaEnumTest_Enum1_value = 42, MetaEnumTest_Enum1_bigValue = (Q_INT64_C(1) << 33) + 50 };
Q_ENUM(MetaEnumTest_Enum1)
- enum MetaEnumTest_Enum3 ENUM_SIZE(qint64) { MetaEnumTest_Enum3_value = -47, MetaEnumTest_Enum3_bigValue = (Q_INT64_C(1) << 56) + 5, MetaEnumTest_Enum3_bigNegValue = -(Q_INT64_C(1) << 56) - 3 };
+ enum MetaEnumTest_Enum3 : qint64 { MetaEnumTest_Enum3_value = -47, MetaEnumTest_Enum3_bigValue = (Q_INT64_C(1) << 56) + 5, MetaEnumTest_Enum3_bigNegValue = -(Q_INT64_C(1) << 56) - 3 };
Q_ENUM(MetaEnumTest_Enum3)
- enum MetaEnumTest_Enum4 ENUM_SIZE(quint64) { MetaEnumTest_Enum4_value = 47, MetaEnumTest_Enum4_bigValue = (Q_INT64_C(1) << 52) + 45 };
+ enum MetaEnumTest_Enum4 : quint64 { MetaEnumTest_Enum4_value = 47, MetaEnumTest_Enum4_bigValue = (Q_INT64_C(1) << 52) + 45 };
Q_ENUM(MetaEnumTest_Enum4)
- enum MetaEnumTest_Enum5 ENUM_SIZE(uint) { MetaEnumTest_Enum5_value = 47 };
+ enum MetaEnumTest_Enum5 : uint { MetaEnumTest_Enum5_value = 47 };
Q_ENUM(MetaEnumTest_Enum5)
- enum MetaEnumTest_Enum6 ENUM_SIZE(uchar) { MetaEnumTest_Enum6_value = 47 };
+ enum MetaEnumTest_Enum6 : uchar { MetaEnumTest_Enum6_value = 47 };
Q_ENUM(MetaEnumTest_Enum6)
- enum MetaEnumTest_Enum8 ENUM_SIZE(short) { MetaEnumTest_Enum8_value = 47 };
+ enum MetaEnumTest_Enum8 : short { MetaEnumTest_Enum8_value = 47 };
Q_ENUM(MetaEnumTest_Enum8)
private slots:
@@ -106,6 +176,13 @@ private slots:
void canConvert_data();
void canConvert();
+ void canConvertAndConvert_ReturnFalse_WhenConvertingBetweenPointerAndValue_data();
+ void canConvertAndConvert_ReturnFalse_WhenConvertingBetweenPointerAndValue();
+
+ void canConvertAndConvert_ReturnFalse_WhenConvertingQObjectBetweenPointerAndValue();
+
+ void convert();
+
void toSize_data();
void toSize();
@@ -174,10 +251,10 @@ private slots:
void qvariant_cast_QObject_derived();
void qvariant_cast_QObject_wrapper();
void qvariant_cast_QSharedPointerQObject();
+ void qvariant_cast_const();
void toLocale();
- void toRegExp();
void toRegularExpression();
void url();
@@ -194,13 +271,12 @@ private slots:
void operator_eq_eq_data();
void operator_eq_eq();
- void operator_eq_eq_rhs();
- void compareNumbers_data() const;
- void compareNumbers() const;
+#if QT_DEPRECATED_SINCE(6, 0)
void typeName_data();
void typeName();
void typeToName();
+#endif
void streamInvalidVariant();
@@ -215,6 +291,9 @@ private slots:
void variantHash();
void convertToQUint8() const;
+ void compareCompiles() const;
+ void compareNumerics_data() const;
+ void compareNumerics() const;
void comparePointers() const;
void voidStar() const;
void dataStar() const;
@@ -228,14 +307,17 @@ private slots:
void loadBrokenUserType();
void invalidDate() const;
+ void compareCustomTypes_data() const;
void compareCustomTypes() const;
void timeToDateTime() const;
void copyingUserTypes() const;
+ void valueClassHierarchyConversion() const;
void convertBoolToByteArray() const;
void convertBoolToByteArray_data() const;
void convertByteArrayToBool() const;
void convertByteArrayToBool_data() const;
void convertIterables() const;
+ void convertConstNonConst() const;
void toIntFromQString() const;
void toIntFromDouble() const;
void setValue();
@@ -253,8 +335,10 @@ private slots:
void forwardDeclare();
void debugStream_data();
void debugStream();
+#if QT_DEPRECATED_SINCE(6, 0)
void debugStreamType_data();
void debugStreamType();
+#endif
void loadQt4Stream_data();
void loadQt4Stream();
@@ -270,28 +354,73 @@ private slots:
void implicitConstruction();
+ void iterateSequentialContainerElements_data();
+ void iterateSequentialContainerElements() { runTestFunction(); }
+ void iterateAssociativeContainerElements_data();
+ void iterateAssociativeContainerElements() { runTestFunction(); }
void iterateContainerElements();
- void pairElements();
+ void pairElements_data();
+ void pairElements() { runTestFunction(); }
- void enums();
- void metaEnums();
- void compareSanity_data();
- void compareSanity();
- void compareRich();
+ void enums_data();
+ void enums() { runTestFunction(); }
+ void metaEnums_data();
+ void metaEnums() { runTestFunction(); }
void nullConvert();
void accessSequentialContainerKey();
-
+ void shouldDeleteVariantDataWorksForSequential();
+ void shouldDeleteVariantDataWorksForAssociative();
void fromStdVariant();
+ void qt4UuidDataStream();
+ void sequentialIterableEndianessSanityCheck();
+ void sequentialIterableAppend();
+
+ void preferDirectConversionOverInterfaces();
+ void mutableView();
+
+ void canViewAndView_ReturnFalseAndDefault_WhenConvertingBetweenPointerAndValue();
+
+ void moveOperations();
+ void equalsWithoutMetaObject();
+
+ void constructFromIncompatibleMetaType_data();
+ void constructFromIncompatibleMetaType();
+ void constructFromQtLT65MetaType();
+ void copyNonDefaultConstructible();
+
+ void inplaceConstruct();
+ void emplace();
+
+ void getIf_int() { getIf_impl(42); }
+ void getIf_QString() { getIf_impl(u"string"_s); };
+ void getIf_NonDefaultConstructible();
+ void getIfSpecial();
+
+ void get_int() { get_impl(42); }
+ void get_QString() { get_impl(u"string"_s); }
+ void get_NonDefaultConstructible();
private:
+ using StdVariant = std::variant<std::monostate,
+ // list here all the types with which we instantiate getIf_impl:
+ int,
+ QString,
+ NonDefaultConstructible
+ >;
+ template <typename T>
+ void getIf_impl(T t) const;
+ template <typename T>
+ void get_impl(T t) const;
+ template<typename T>
+ void canViewAndView_ReturnFalseAndDefault_WhenConvertingBetweenPointerAndValue_impl(const QByteArray &typeName);
void dataStream_data(QDataStream::Version version);
void loadQVariantFromDataStream(QDataStream::Version version);
void saveQVariantFromDataStream(QDataStream::Version version);
CustomNonQObject *customNonQObjectPointer;
- QVector<QObject*> objectPointerTestData;
+ QList<QObject*> objectPointerTestData;
};
const qlonglong intMax1 = (qlonglong)INT_MAX + 1;
@@ -311,29 +440,39 @@ void tst_QVariant::constructor()
QVariant varll2(varll);
QCOMPARE(varll2, varll);
- QVariant var3(QVariant::String);
+ QVariant var3 {QMetaType::fromType<QString>()};
QCOMPARE(var3.typeName(), "QString");
QVERIFY(var3.isNull());
QVERIFY(var3.isValid());
- QVariant var4(QVariant::Invalid);
- QCOMPARE(var4.type(), QVariant::Invalid);
+ QVariant var3a = QVariant::fromMetaType(QMetaType::fromType<QString>());
+ QCOMPARE(var3a.typeName(), "QString");
+ QVERIFY(var3a.isNull());
+ QVERIFY(var3a.isValid());
+
+ QVariant var4 {QMetaType()};
+ QCOMPARE(var4.typeId(), QMetaType::UnknownType);
QVERIFY(var4.isNull());
QVERIFY(!var4.isValid());
+ QVariant var4a = QVariant::fromMetaType(QMetaType());
+ QCOMPARE(var4a.typeId(), QMetaType::UnknownType);
+ QVERIFY(var4a.isNull());
+ QVERIFY(!var4a.isValid());
+
QVariant var5(QLatin1String("hallo"));
- QCOMPARE(var5.type(), QVariant::String);
+ QCOMPARE(var5.typeId(), QMetaType::QString);
QCOMPARE(var5.typeName(), "QString");
QVariant var6(qlonglong(0));
- QCOMPARE(var6.type(), QVariant::LongLong);
+ QCOMPARE(var6.typeId(), QMetaType::LongLong);
QCOMPARE(var6.typeName(), "qlonglong");
QVariant var7 = 5;
QVERIFY(var7.isValid());
QVERIFY(!var7.isNull());
QVariant var8;
- var8.setValue<int>(5);
+ var8.setValue(5);
QVERIFY(var8.isValid());
QVERIFY(!var8.isNull());
}
@@ -354,24 +493,35 @@ void tst_QVariant::constructor_invalid()
QFETCH(uint, typeId);
{
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:"));
- QVariant variant(static_cast<QVariant::Type>(typeId));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type"));
+ QVariant variant {QMetaType(typeId)};
+ QVERIFY(!variant.isValid());
+ QVERIFY(variant.isNull());
+ QCOMPARE(variant.typeId(), int(QMetaType::UnknownType));
+ QCOMPARE(variant.userType(), int(QMetaType::UnknownType));
+ }
+ {
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type"));
+ QVariant variant = QVariant::fromMetaType(QMetaType(typeId));
QVERIFY(!variant.isValid());
+ QVERIFY(variant.isNull());
+ QCOMPARE(variant.typeId(), int(QMetaType::UnknownType));
QCOMPARE(variant.userType(), int(QMetaType::UnknownType));
}
{
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type, type id:"));
- QVariant variant(typeId, /* copy */ 0);
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type"));
+ QVariant variant(QMetaType(typeId), /* copy */ nullptr);
QVERIFY(!variant.isValid());
+ QVERIFY(variant.isNull());
QCOMPARE(variant.userType(), int(QMetaType::UnknownType));
}
}
void tst_QVariant::copy_constructor()
{
- QVariant var7(QVariant::Int);
+ QVariant var7 {QMetaType::fromType<int>()};
QVariant var8(var7);
- QCOMPARE(var8.type(), QVariant::Int);
+ QCOMPARE(var8.typeId(), QMetaType::Int);
QVERIFY(var8.isNull());
}
@@ -382,64 +532,65 @@ void tst_QVariant::isNull()
QVariant var;
QVERIFY( var.isNull() );
- QString str1;
- QVariant var1( str1 );
- QVERIFY( var1.isNull() );
-
- QVariant var2( QString::null );
- QVERIFY( var2.isNull() );
+ QVariant empty = QString();
+ QVERIFY(empty.toString().isNull());
+ QVERIFY(!empty.isNull());
+ QVERIFY(empty.isValid());
+ QCOMPARE(empty.typeName(), "QString");
QVariant var3( QString( "blah" ) );
QVERIFY( !var3.isNull() );
+ var3 = QVariant(QMetaType::fromType<QString>());
+ QVERIFY( var3.isNull() );
+
QVariant var4( 0 );
QVERIFY( !var4.isNull() );
QVariant var5 = QString();
- QVERIFY( var5.isNull() );
+ QVERIFY( !var5.isNull() );
QVariant var6( QString( "blah" ) );
QVERIFY( !var6.isNull() );
var6 = QVariant();
QVERIFY( var6.isNull() );
- var6.convert( QVariant::String );
+ var6.convert(QMetaType::fromType<QString>());
QVERIFY( var6.isNull() );
QVariant varLL( (qlonglong)0 );
QVERIFY( !varLL.isNull() );
- QVariant var7(QString::null);
- QVERIFY(var7.isNull());
- var7 = QVariant::fromValue<QString>(QString::null);
- QVERIFY(var7.isNull());
- QVariant var8(QMetaType::Nullptr, nullptr);
+ QVariant var8(QMetaType::fromType<std::nullptr_t>(), nullptr);
QVERIFY(var8.isNull());
var8 = QVariant::fromValue<std::nullptr_t>(nullptr);
QVERIFY(var8.isNull());
QVariant var9 = QVariant(QJsonValue(QJsonValue::Null));
- QVERIFY(var9.isNull());
+ QVERIFY(!var9.isNull());
var9 = QVariant::fromValue<QJsonValue>(QJsonValue(QJsonValue::Null));
- QVERIFY(var9.isNull());
+ QVERIFY(!var9.isNull());
- QVariant var10(QMetaType::VoidStar, nullptr);
+ QVariant var10(QMetaType::fromType<void*>(), nullptr);
QVERIFY(var10.isNull());
var10 = QVariant::fromValue<void*>(nullptr);
QVERIFY(var10.isNull());
- QVariant var11(QMetaType::QObjectStar, nullptr);
+ QVariant var11(QMetaType::fromType<QObject*>(), nullptr);
QVERIFY(var11.isNull());
var11 = QVariant::fromValue<QObject*>(nullptr);
QVERIFY(var11.isNull());
QVERIFY(QVariant::fromValue<int*>(nullptr).isNull());
+
+ QVariant var12(QVariant::fromValue<QString>(QString()));
+ QVERIFY(!var12.isNull());
}
void tst_QVariant::swap()
{
QVariant v1 = 1, v2 = 2.0;
v1.swap(v2);
- QCOMPARE(v1.type(),QVariant::Double);
+ QCOMPARE(v1.typeId(), QMetaType::Double);
QCOMPARE(v1.toDouble(),2.0);
- QCOMPARE(v2.type(),QVariant::Int);
+ QCOMPARE(v2.typeId(), QMetaType::Int);
QCOMPARE(v2.toInt(),1);
}
@@ -464,7 +615,7 @@ void tst_QVariant::canConvert_data()
<< var << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N;
var = QVariant(QByteArray());
QTest::newRow("ByteArray")
- << var << N << N << Y << N << Y << Y << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
+ << var << N << N << Y << N << Y << Y << N << N << N << Y << N << N << Y << N << N << Y << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
var = QVariant(QDate());
QTest::newRow("Date")
<< var << N << N << N << N << N << N << N << Y << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N;
@@ -482,7 +633,7 @@ void tst_QVariant::canConvert_data()
<< var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
var = QVariant();
QTest::newRow("Invalid")
- << var << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N;
+ << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N;
var = QVariant(QList<QVariant>());
QTest::newRow("List")
<< var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N;
@@ -503,7 +654,7 @@ void tst_QVariant::canConvert_data()
<< var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N;
var = QVariant(QString());
QTest::newRow("String")
- << var << N << N << Y << N << Y << Y << N << Y << Y << Y << Y << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << Y << Y << Y << Y;
+ << var << N << N << Y << N << Y << Y << N << Y << Y << Y << Y << N << Y << N << Y << Y << Y << N << N << N << N << N << N << N << N << N << Y << Y << Y << Y << Y;
var = QVariant(QStringList("entry"));
QTest::newRow("StringList")
<< var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << Y << Y << N << N << N;
@@ -513,9 +664,6 @@ void tst_QVariant::canConvert_data()
var = QVariant((uint)1);
QTest::newRow("UInt")
<< var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
- var = QVariant((int)1);
- QTest::newRow("Int")
- << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
var = QVariant((qulonglong)1);
QTest::newRow("ULongLong")
<< var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
@@ -525,12 +673,12 @@ void tst_QVariant::canConvert_data()
var = QVariant::fromValue<signed char>(-1);
QTest::newRow("SChar")
<< var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
- var = QVariant((short)-3);
+ var = QVariant::fromValue((short)-3);
QTest::newRow("Short")
- << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
- var = QVariant((ushort)7);
+ << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
+ var = QVariant::fromValue((ushort)7);
QTest::newRow("UShort")
- << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
+ << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
var = QVariant::fromValue<QJsonValue>(QJsonValue(QStringLiteral("hello")));
QTest::newRow("JsonValue")
<< var << N << N << Y << N << N << N << N << N << N << Y << N << N << Y << N << N << Y << Y << Y << N << N << N << N << N << N << N << N << Y << N << N << Y << Y;
@@ -549,13 +697,131 @@ void tst_QVariant::canConvert()
{
TST_QVARIANT_CANCONVERT_FETCH_DATA
+ // This test links against QtGui but not QtWidgets, so QSizePolicy isn't real for it.
+ QTest::ignoreMessage(QtWarningMsg, // QSizePolicy's id is 0x2000, a.k.a. 8192
+ "Trying to construct an instance of an invalid type, type id: 8192");
TST_QVARIANT_CANCONVERT_COMPARE_DATA
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
// Invalid type ids
+ QTest::ignoreMessage(QtWarningMsg,
+ "Trying to construct an instance of an invalid type, type id: -1");
QCOMPARE(val.canConvert(-1), false);
+ QTest::ignoreMessage(QtWarningMsg,
+ "Trying to construct an instance of an invalid type, type id: -23");
QCOMPARE(val.canConvert(-23), false);
+ QTest::ignoreMessage(QtWarningMsg,
+ "Trying to construct an instance of an invalid type, type id: -23876");
QCOMPARE(val.canConvert(-23876), false);
+ QTest::ignoreMessage(QtWarningMsg,
+ "Trying to construct an instance of an invalid type, type id: 23876");
QCOMPARE(val.canConvert(23876), false);
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+}
+
+namespace {
+
+// Used for testing canConvert/convert of QObject derived types
+struct QObjectDerived : QObject
+{
+ Q_OBJECT
+};
+
+// Adds a test table row for checking value <-> pointer conversion
+// If type is a pointer, the target type is value type and vice versa.
+template<typename T>
+void addRowForPointerValueConversion()
+{
+ using ValueType = std::remove_pointer_t<T>;
+ if constexpr (!std::is_same_v<ValueType, std::nullptr_t>) {
+
+ static ValueType instance{}; // static since we may need a pointer to a valid object
+
+ QVariant variant;
+ if constexpr (std::is_pointer_v<T>)
+ variant = QVariant::fromValue(&instance);
+ else
+ variant = QVariant::fromValue(instance);
+
+ // Toggle pointer/value type
+ using TargetType = std::conditional_t<std::is_pointer_v<T>, ValueType, T *>;
+
+ const QMetaType fromType = QMetaType::fromType<T>();
+ const QMetaType toType = QMetaType::fromType<TargetType>();
+
+ QTest::addRow("%s->%s", fromType.name(), toType.name())
+ << variant << QMetaType::fromType<TargetType>();
+ }
+}
+
+} // namespace
+
+void tst_QVariant::canConvertAndConvert_ReturnFalse_WhenConvertingBetweenPointerAndValue_data()
+{
+ QTest::addColumn<QVariant>("variant");
+ QTest::addColumn<QMetaType>("targetType");
+
+#define ADD_ROW(typeName, typeNameId, realType) \
+ addRowForPointerValueConversion<realType>(); \
+ addRowForPointerValueConversion<realType *>();
+
+ // Add rows for static primitive types
+ QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(ADD_ROW)
+
+ // Add rows for static core types
+ QT_FOR_EACH_STATIC_CORE_CLASS(ADD_ROW)
+#undef ADD_ROW
+
+}
+
+void tst_QVariant::canConvertAndConvert_ReturnFalse_WhenConvertingBetweenPointerAndValue()
+{
+ QFETCH(QVariant, variant);
+ QFETCH(QMetaType, targetType);
+
+ QVERIFY(!variant.canConvert(targetType));
+
+ QVERIFY(!variant.convert(targetType));
+
+ // As per the documentation, when QVariant::convert fails, the
+ // QVariant is cleared and changed to the requested type.
+ QVERIFY(variant.isNull());
+ QCOMPARE(variant.metaType(), targetType);
+}
+
+void tst_QVariant::canConvertAndConvert_ReturnFalse_WhenConvertingQObjectBetweenPointerAndValue()
+{
+ // Types derived from QObject are non-copyable and require their own test.
+ // We only test pointer -> value conversion, because constructing a QVariant
+ // from a non-copyable object will just set the QVariant to null.
+
+ QObjectDerived object;
+ QVariant variant = QVariant::fromValue(&object);
+
+ constexpr QMetaType targetType = QMetaType::fromType<QObjectDerived>();
+ QVERIFY(!variant.canConvert(targetType));
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ QRegularExpression(".*does not support destruction and copy construction"));
+
+ QVERIFY(!variant.convert(targetType));
+
+ // When the QVariant::convert fails, the QVariant is cleared, and since the target type is
+ // invalid for QVariant, the QVariant's type is also cleared to an unknown type.
+ QVERIFY(variant.isNull());
+ QCOMPARE(variant.metaType(), QMetaType());
+}
+
+void tst_QVariant::convert()
+{
+ // verify that after convert(), the variant's type has been changed
+ QVariant var = QVariant::fromValue(QString("A string"));
+ var.convert(QMetaType::fromType<int>());
+ QCOMPARE(var.metaType(), QMetaType::fromType<int>());
+ QCOMPARE(var.toInt(), 0);
}
void tst_QVariant::toInt_data()
@@ -601,12 +867,19 @@ void tst_QVariant::toInt_data()
QTest::newRow("undefined-QJsonValue") << QVariant(QJsonValue(QJsonValue::Undefined)) << 0 << false;
}
+#if QT_DEPRECATED_SINCE(6, 0)
+# define EXEC_DEPRECATED_CALL(x) QT_IGNORE_DEPRECATIONS(x)
+#else
+# define EXEC_DEPRECATED_CALL(x)
+#endif
+
void tst_QVariant::toInt()
{
QFETCH( QVariant, value );
QFETCH( int, result );
QFETCH( bool, valueOK );
- QVERIFY( value.isValid() == value.canConvert( QVariant::Int ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.isValid() == value.canConvert( QVariant::Int ) );)
+ QVERIFY( value.isValid() == value.canConvert(QMetaType::fromType<int>()) );
bool ok;
int i = value.toInt( &ok );
QCOMPARE( i, result );
@@ -655,7 +928,8 @@ void tst_QVariant::toUInt()
QFETCH( uint, result );
QFETCH( bool, valueOK );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::UInt ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::UInt ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<uint>()) );
bool ok;
uint i = value.toUInt( &ok );
@@ -679,7 +953,8 @@ void tst_QVariant::toSize()
QFETCH( QVariant, value );
QFETCH( QSize, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Size ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Size ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QSize>()) );
QSize i = value.toSize();
QCOMPARE( i, result );
@@ -700,7 +975,8 @@ void tst_QVariant::toSizeF()
QFETCH( QVariant, value );
QFETCH( QSizeF, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::SizeF ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::SizeF ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QSizeF>()) );
QSizeF i = value.toSizeF();
QCOMPARE( i, result );
@@ -721,7 +997,8 @@ void tst_QVariant::toLine()
QFETCH( QVariant, value );
QFETCH( QLine, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Line ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Line ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QLine>()) );
QLine i = value.toLine();
QCOMPARE( i, result );
@@ -742,7 +1019,8 @@ void tst_QVariant::toLineF()
QFETCH( QVariant, value );
QFETCH( QLineF, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::LineF ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::LineF ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QLineF>()) );
QLineF i = value.toLineF();
QCOMPARE( i, result );
@@ -764,7 +1042,8 @@ void tst_QVariant::toPoint()
QFETCH( QVariant, value );
QFETCH( QPoint, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Point ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Point ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QPoint>()) );
QPoint i = value.toPoint();
QCOMPARE( i, result );
}
@@ -785,7 +1064,8 @@ void tst_QVariant::toRect()
QFETCH( QVariant, value );
QFETCH( QRect, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Rect ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Rect ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QRect>()) );
QRect i = value.toRect();
QCOMPARE( i, result );
}
@@ -803,7 +1083,8 @@ void tst_QVariant::toChar()
QFETCH( QVariant, value );
QFETCH( QChar, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Char ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Char ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QChar>()) );
QChar i = value.toChar();
QCOMPARE( i, result );
@@ -841,7 +1122,8 @@ void tst_QVariant::toBool()
QFETCH( QVariant, value );
QFETCH( bool, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Bool ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Bool ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<bool>()) );
bool i = value.toBool();
QCOMPARE( i, result );
@@ -860,7 +1142,8 @@ void tst_QVariant::toPointF()
QFETCH( QVariant, value );
QFETCH( QPointF, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::PointF ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::PointF ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QPointF>()) );
QPointF d = value.toPointF();
QCOMPARE( d, result );
}
@@ -880,7 +1163,8 @@ void tst_QVariant::toRectF()
QFETCH( QVariant, value );
QFETCH( QRectF, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::RectF ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::RectF ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QRectF>()) );
QRectF d = value.toRectF();
QCOMPARE( d, result );
}
@@ -907,7 +1191,8 @@ void tst_QVariant::toDouble()
QFETCH( double, result );
QFETCH( bool, valueOK );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Double ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Double ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<double>()) );
bool ok;
double d = value.toDouble( &ok );
QCOMPARE( d, result );
@@ -936,7 +1221,8 @@ void tst_QVariant::toFloat()
QFETCH(float, result);
QFETCH(bool, valueOK);
QVERIFY(value.isValid());
- QVERIFY(value.canConvert(QMetaType::Float));
+ EXEC_DEPRECATED_CALL(QVERIFY(value.canConvert(QMetaType::Float));)
+ QVERIFY(value.canConvert(QMetaType::fromType<float>()));
bool ok;
float d = value.toFloat(&ok);
QCOMPARE(d, result);
@@ -987,7 +1273,8 @@ void tst_QVariant::toLongLong()
QFETCH( qlonglong, result );
QFETCH( bool, valueOK );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::LongLong ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::LongLong ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<qlonglong>()) );
bool ok;
qlonglong ll = value.toLongLong( &ok );
QCOMPARE( ll, result );
@@ -1042,7 +1329,8 @@ void tst_QVariant::toULongLong()
QFETCH( qulonglong, result );
QFETCH( bool, valueOK );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::ULongLong ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::ULongLong ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<qulonglong>()) );
bool ok;
qulonglong ll = value.toULongLong( &ok );
QCOMPARE( ll, result );
@@ -1082,14 +1370,13 @@ void tst_QVariant::toByteArray()
QFETCH( QVariant, value );
QFETCH( QByteArray, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::ByteArray ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::ByteArray ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QByteArray>()) );
QByteArray ba = value.toByteArray();
QCOMPARE( ba.isNull(), result.isNull() );
QCOMPARE( ba, result );
- QVERIFY( value.convert( QVariant::ByteArray ) );
- QCOMPARE( value.isNull(), result.isNull() );
- QCOMPARE( value.toByteArray().isNull(), result.isNull() );
+ QVERIFY( value.convert(QMetaType::fromType<QByteArray>()) );
QCOMPARE( value.toByteArray(), result );
}
@@ -1126,14 +1413,13 @@ void tst_QVariant::toString()
QFETCH( QVariant, value );
QFETCH( QString, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::String ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::String ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QString>()) );
QString str = value.toString();
QCOMPARE( str.isNull(), result.isNull() );
QCOMPARE( str, result );
- QVERIFY( value.convert( QVariant::String ) );
- QCOMPARE( value.isNull(), result.isNull() );
- QCOMPARE( value.toString().isNull(), result.isNull() );
+ QVERIFY( value.convert(QMetaType::fromType<QString>()) );
QCOMPARE( value.toString(), result );
}
@@ -1152,7 +1438,8 @@ void tst_QVariant::toDate()
QFETCH( QVariant, value );
QFETCH( QDate, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Date ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Date ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QDate>()) );
QCOMPARE( value.toDate(), result );
}
@@ -1172,7 +1459,8 @@ void tst_QVariant::toTime()
QFETCH( QVariant, value );
QFETCH( QTime, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::Time ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::Time ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QTime>()) );
QCOMPARE( value.toTime(), result );
}
@@ -1185,8 +1473,9 @@ void tst_QVariant::toDateTime_data()
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) );
QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
- QTest::newRow( "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) )
- << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC );
+ QTest::newRow("qstring-utc")
+ << QVariant(QString("2002-10-10T12:34:56Z"))
+ << QDateTime(QDate(2002, 10, 10), QTime(12, 34, 56), QTimeZone::UTC);
QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) )
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) );
}
@@ -1196,10 +1485,13 @@ void tst_QVariant::toDateTime()
QFETCH( QVariant, value );
QFETCH( QDateTime, result );
QVERIFY( value.isValid() );
- QVERIFY( value.canConvert( QVariant::DateTime ) );
+ EXEC_DEPRECATED_CALL(QVERIFY( value.canConvert( QVariant::DateTime ) );)
+ QVERIFY( value.canConvert(QMetaType::fromType<QDateTime>()) );
QCOMPARE( value.toDateTime(), result );
}
+#undef EXEC_DEPRECATED_CALL
+
void tst_QVariant::toLocale()
{
QVariant variant;
@@ -1208,14 +1500,6 @@ void tst_QVariant::toLocale()
loc = variant.toLocale();
}
-void tst_QVariant::toRegExp()
-{
- QVariant variant;
- QRegExp rx = variant.toRegExp();
- variant = QRegExp("foo");
- rx = variant.toRegExp();
-}
-
void tst_QVariant::toRegularExpression()
{
QVariant variant;
@@ -1239,7 +1523,6 @@ struct CustomStreamableClass
return i == other.i;
}
};
-Q_DECLARE_METATYPE(CustomStreamableClass);
QDataStream &operator<<(QDataStream &out, const CustomStreamableClass &myObj)
{
@@ -1250,11 +1533,10 @@ QDataStream &operator>>(QDataStream &in, CustomStreamableClass &myObj)
{
return in >> myObj.i;
}
+Q_DECLARE_METATYPE(CustomStreamableClass);
void tst_QVariant::writeToReadFromDataStream_data()
{
- qRegisterMetaTypeStreamOperators<CustomStreamableClass>();
-
QTest::addColumn<QVariant>("writeVariant");
QTest::addColumn<bool>("isNull");
{
@@ -1265,14 +1547,16 @@ void tst_QVariant::writeToReadFromDataStream_data()
}
QTest::newRow( "invalid" ) << QVariant() << true;
- QTest::newRow( "bitarray_invalid" ) << QVariant( QBitArray() ) << true;
+ QTest::newRow( "bitarray_invalid" ) << QVariant(QMetaType::fromType<QBitArray>()) << true;
+ QTest::newRow( "bitarray_empty" ) << QVariant( QBitArray() ) << false;
QBitArray bitarray( 3 );
bitarray[0] = 0;
bitarray[1] = 1;
bitarray[2] = 0;
QTest::newRow( "bitarray_valid" ) << QVariant( bitarray ) << false;
- QTest::newRow( "bytearray_invalid" ) << QVariant( QByteArray() ) << true;
- QTest::newRow( "int_invalid") << QVariant(QVariant::Int) << true;
+ QTest::newRow( "bytearray_invalid" ) << QVariant(QMetaType::fromType<QByteArray>()) << true;
+ QTest::newRow( "bytearray_empty" ) << QVariant( QByteArray() ) << false;
+ QTest::newRow( "int_invalid") << QVariant(QMetaType::fromType<int>()) << true;
QByteArray bytearray(5, ' ');
bytearray[0] = 'T';
bytearray[1] = 'e';
@@ -1280,9 +1564,11 @@ void tst_QVariant::writeToReadFromDataStream_data()
bytearray[3] = 't';
bytearray[4] = '\0';
QTest::newRow( "bytearray_valid" ) << QVariant( bytearray ) << false;
- QTest::newRow( "date_invalid" ) << QVariant( QDate() ) << true;
+ QTest::newRow( "date_invalid" ) << QVariant(QMetaType::fromType<QDate>()) << true;
+ QTest::newRow( "date_empty" ) << QVariant( QDate() ) << false;
QTest::newRow( "date_valid" ) << QVariant( QDate( 2002, 07, 06 ) ) << false;
- QTest::newRow( "datetime_invalid" ) << QVariant( QDateTime() ) << true;
+ QTest::newRow( "datetime_invalid" ) << QVariant(QMetaType::fromType<QDateTime>()) << true;
+ QTest::newRow( "datetime_empty" ) << QVariant( QDateTime() ) << false;
QTest::newRow( "datetime_valid" ) << QVariant( QDateTime( QDate( 2002, 07, 06 ), QTime( 14, 0, 0 ) ) ) << false;
QTest::newRow( "double_valid" ) << QVariant( 123.456 ) << false;
QTest::newRow( "float_valid" ) << QVariant( 123.456f ) << false;
@@ -1293,49 +1579,52 @@ void tst_QVariant::writeToReadFromDataStream_data()
vMap.insert( "double", QVariant( 3.45 ) );
vMap.insert( "float", QVariant( 3.45f ) );
QTest::newRow( "map_valid" ) << QVariant( vMap ) << false;
- QTest::newRow( "point_invalid" ) << QVariant::fromValue( QPoint() ) << true;
+ QTest::newRow( "point_invalid" ) << QVariant(QMetaType::fromType<QPoint>()) << true;
+ QTest::newRow( "point_empty" ) << QVariant::fromValue( QPoint() ) << false;
QTest::newRow( "point_valid" ) << QVariant::fromValue( QPoint( 10, 10 ) ) << false;
- QTest::newRow( "rect_invalid" ) << QVariant( QRect() ) << true;
+ QTest::newRow( "rect_invalid" ) << QVariant(QMetaType::fromType<QRect>()) << true;
+ QTest::newRow( "rect_empty" ) << QVariant( QRect() ) << false;
QTest::newRow( "rect_valid" ) << QVariant( QRect( 10, 10, 20, 20 ) ) << false;
- QTest::newRow( "size_invalid" ) << QVariant( QSize( 0, 0 ) ) << true;
+ QTest::newRow( "size_invalid" ) << QVariant(QMetaType::fromType<QSize>()) << true;
+ QTest::newRow( "size_empty" ) << QVariant( QSize( 0, 0 ) ) << false;
QTest::newRow( "size_valid" ) << QVariant( QSize( 10, 10 ) ) << false;
- QTest::newRow( "string_invalid" ) << QVariant( QString() ) << true;
+ QTest::newRow( "string_invalid" ) << QVariant(QMetaType::fromType<QString>()) << true;
+ QTest::newRow( "string_empty" ) << QVariant( QString() ) << false;
QTest::newRow( "string_valid" ) << QVariant( QString( "Test" ) ) << false;
QStringList stringlist;
stringlist << "One" << "Two" << "Three";
QTest::newRow( "stringlist_valid" ) << QVariant( stringlist ) << false;
- QTest::newRow( "time_invalid" ) << QVariant( QTime() ) << true;
+ QTest::newRow( "time_invalid" ) << QVariant(QMetaType::fromType<QTime>()) << true;
+ QTest::newRow( "time_empty" ) << QVariant( QTime() ) << false;
QTest::newRow( "time_valid" ) << QVariant( QTime( 14, 0, 0 ) ) << false;
QTest::newRow( "uint_valid" ) << QVariant( (uint)123 ) << false;
QTest::newRow( "qchar" ) << QVariant(QChar('a')) << false;
- QTest::newRow( "qchar_null" ) << QVariant(QChar(0)) << true;
- QTest::newRow( "regexp" ) << QVariant(QRegExp("foo", Qt::CaseInsensitive)) << false;
- QTest::newRow( "regexp_empty" ) << QVariant(QRegExp()) << false;
+ QTest::newRow( "qchar_null" ) << QVariant(QChar(0)) << false;
QTest::newRow( "regularexpression" ) << QVariant(QRegularExpression("abc.*def")) << false;
QTest::newRow( "regularexpression_empty" ) << QVariant(QRegularExpression()) << false;
// types known to QMetaType, but not part of QVariant::Type
- QTest::newRow("QMetaType::Long invalid") << QVariant(QMetaType::Long, (void *) 0) << false;
+ QTest::newRow("QMetaType::Long invalid") << QVariant(QMetaType::fromType<long>(), nullptr) << true;
long longInt = -1l;
- QTest::newRow("QMetaType::Long") << QVariant(QMetaType::Long, &longInt) << false;
- QTest::newRow("QMetaType::Short invalid") << QVariant(QMetaType::Short, (void *) 0) << false;
+ QTest::newRow("QMetaType::Long") << QVariant(QMetaType::fromType<long>(), &longInt) << false;
+ QTest::newRow("QMetaType::Short invalid") << QVariant(QMetaType::fromType<short>(), nullptr) << true;
short shortInt = 1;
- QTest::newRow("QMetaType::Short") << QVariant(QMetaType::Short, &shortInt) << false;
- QTest::newRow("QMetaType::Char invalid") << QVariant(QMetaType::Char, (void *) 0) << false;
+ QTest::newRow("QMetaType::Short") << QVariant(QMetaType::fromType<short>(), &shortInt) << false;
+ QTest::newRow("QMetaType::Char invalid") << QVariant(QMetaType::fromType<QChar>(), nullptr) << true;
char ch = 'c';
- QTest::newRow("QMetaType::Char") << QVariant(QMetaType::Char, &ch) << false;
- QTest::newRow("QMetaType::ULong invalid") << QVariant(QMetaType::ULong, (void *) 0) << false;
+ QTest::newRow("QMetaType::Char") << QVariant(QMetaType::fromType<char>(), &ch) << false;
+ QTest::newRow("QMetaType::ULong invalid") << QVariant(QMetaType::fromType<ulong>(), nullptr) << true;
ulong ulongInt = 1ul;
- QTest::newRow("QMetaType::ULong") << QVariant(QMetaType::ULong, &ulongInt) << false;
- QTest::newRow("QMetaType::UShort invalid") << QVariant(QMetaType::UShort, (void *) 0) << false;
+ QTest::newRow("QMetaType::ULong") << QVariant(QMetaType::fromType<ulong>(), &ulongInt) << false;
+ QTest::newRow("QMetaType::UShort invalid") << QVariant(QMetaType::fromType<ushort>(), nullptr) << true;
ushort ushortInt = 1u;
- QTest::newRow("QMetaType::UShort") << QVariant(QMetaType::UShort, &ushortInt) << false;
- QTest::newRow("QMetaType::UChar invalid") << QVariant(QMetaType::UChar, (void *) 0) << false;
+ QTest::newRow("QMetaType::UShort") << QVariant(QMetaType::fromType<ushort>(), &ushortInt) << false;
+ QTest::newRow("QMetaType::UChar invalid") << QVariant(QMetaType::fromType<uchar>(), nullptr) << true;
uchar uch = 0xf0;
- QTest::newRow("QMetaType::UChar") << QVariant(QMetaType::UChar, &uch) << false;
- QTest::newRow("QMetaType::Float invalid") << QVariant(QMetaType::Float, (void *) 0) << false;
+ QTest::newRow("QMetaType::UChar") << QVariant(QMetaType::fromType<uchar>(), &uch) << false;
+ QTest::newRow("QMetaType::Float invalid") << QVariant(QMetaType::fromType<float>(), nullptr) << true;
float f = 1.234f;
- QTest::newRow("QMetaType::Float") << QVariant(QMetaType::Float, &f) << false;
+ QTest::newRow("QMetaType::Float") << QVariant(QMetaType::fromType<float>(), &f) << false;
CustomStreamableClass custom = {123};
QTest::newRow("Custom type") << QVariant::fromValue(custom) << false;
}
@@ -1357,10 +1646,11 @@ void tst_QVariant::writeToReadFromDataStream()
// Since only a few won't match since the serial numbers are different
// I won't bother adding another bool in the data test.
const int writeType = writeVariant.userType();
- if (writeType == qMetaTypeId<CustomStreamableClass>())
- QCOMPARE(qvariant_cast<CustomStreamableClass>(readVariant), qvariant_cast<CustomStreamableClass>(writeVariant));
- else if ( writeType != QVariant::Invalid && writeType != QVariant::Bitmap && writeType != QVariant::Pixmap
- && writeType != QVariant::Image) {
+ if (writeType == qMetaTypeId<CustomStreamableClass>()) {
+ QCOMPARE(qvariant_cast<CustomStreamableClass>(readVariant),
+ qvariant_cast<CustomStreamableClass>(writeVariant));
+ } else if ( writeType != QMetaType::UnknownType && writeType != QMetaType::QBitmap
+ && writeType != QMetaType::QPixmap && writeType != QMetaType::QImage) {
switch (writeType) {
default:
QCOMPARE( readVariant, writeVariant );
@@ -1422,12 +1712,9 @@ void tst_QVariant::checkDataStream()
const int typeId = QMetaType::LastCoreType + 1;
QVERIFY(!QMetaType::isRegistered(typeId));
- QByteArray errorMessage("Trying to construct an instance of an invalid type, type id: ");
- errorMessage.append(QString::number(typeId, 10));
-
- QTest::ignoreMessage(QtWarningMsg, errorMessage.constData());
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type"));
QByteArray settingsHex("000000");
- settingsHex.append(QString::number(typeId, 16));
+ settingsHex.append(QByteArray::number(typeId, 16));
settingsHex.append("ffffffffff");
const QByteArray settings = QByteArray::fromHex(settingsHex);
QDataStream in(settings);
@@ -1438,7 +1725,7 @@ void tst_QVariant::checkDataStream()
// constructed. However, it might be worth considering changing that behavior
// in the future.
// QCOMPARE(in.status(), QDataStream::ReadCorruptData);
- QCOMPARE(v.type(), QVariant::Invalid);
+ QCOMPARE(v.typeId(), QMetaType::UnknownType);
}
void tst_QVariant::operator_eq_eq_data()
@@ -1455,7 +1742,7 @@ void tst_QVariant::operator_eq_eq_data()
// Int
QTest::newRow( "int1int1" ) << i1 << i1 << true;
QTest::newRow( "int1int0" ) << i1 << i0 << false;
- QTest::newRow( "nullint" ) << i0 << QVariant(QVariant::Int) << true;
+ QTest::newRow( "nullint" ) << i0 << QVariant(QMetaType::fromType<int>()) << true;
// LongLong and ULongLong
QVariant ll1( (qlonglong)1 );
@@ -1473,6 +1760,10 @@ void tst_QVariant::operator_eq_eq_data()
QVariant mIntString(QByteArray("-42"));
QVariant mIntQString(QString("-42"));
+ QVariant mIntZero(0);
+ QVariant mIntStringZero(QByteArray("0"));
+ QVariant mIntQStringZero(QString("0"));
+
QVariant mUInt(42u);
QVariant mUIntString(QByteArray("42"));
QVariant mUIntQString(QString("42"));
@@ -1513,40 +1804,63 @@ void tst_QVariant::operator_eq_eq_data()
QVariant mBoolString(QByteArray("false"));
QVariant mBoolQString(QString("false"));
+ QVariant mTextString(QByteArray("foobar"));
+ QVariant mTextQString(QString("foobar"));
+
QTest::newRow( "double_int" ) << QVariant(42.0) << QVariant(42) << true;
QTest::newRow( "float_int" ) << QVariant(42.f) << QVariant(42) << true;
- QTest::newRow( "mInt_mIntString" ) << mInt << mIntString << true;
- QTest::newRow( "mIntString_mInt" ) << mIntString << mInt << true;
+ QTest::newRow( "mInt_mIntString" ) << mInt << mIntString << false;
+ QTest::newRow( "mIntString_mInt" ) << mIntString << mInt << false;
QTest::newRow( "mInt_mIntQString" ) << mInt << mIntQString << true;
QTest::newRow( "mIntQString_mInt" ) << mIntQString << mInt << true;
- QTest::newRow( "mUInt_mUIntString" ) << mUInt << mUIntString << true;
- QTest::newRow( "mUIntString_mUInt" ) << mUIntString << mUInt << true;
+ QTest::newRow( "mIntZero_mIntStringZero" ) << mIntZero << mIntStringZero << false;
+ QTest::newRow( "mIntStringZero_mIntZero" ) << mIntStringZero << mIntZero << false;
+ QTest::newRow( "mIntZero_mIntQStringZero" ) << mIntZero << mIntQStringZero << true;
+ QTest::newRow( "mIntQStringZero_mIntZero" ) << mIntQStringZero << mIntZero << true;
+
+ QTest::newRow( "mInt_mTextString" ) << mInt << mTextString << false;
+ QTest::newRow( "mTextString_mInt" ) << mTextString << mInt << false;
+ QTest::newRow( "mInt_mTextQString" ) << mInt << mTextQString << false;
+ QTest::newRow( "mTextQString_mInt" ) << mTextQString << mInt << false;
+
+ QTest::newRow( "mIntZero_mTextString" ) << mIntZero << mTextString << false;
+ QTest::newRow( "mTextString_mIntZero" ) << mTextString << mIntZero << false;
+ QTest::newRow( "mIntZero_mTextQString" ) << mIntZero << mTextQString << false;
+ QTest::newRow( "mTextQString_mIntZero" ) << mTextQString << mIntZero << false;
+
+ QTest::newRow( "mUInt_mUIntString" ) << mUInt << mUIntString << false;
+ QTest::newRow( "mUIntString_mUInt" ) << mUIntString << mUInt << false;
QTest::newRow( "mUInt_mUIntQString" ) << mUInt << mUIntQString << true;
QTest::newRow( "mUIntQString_mUInt" ) << mUIntQString << mUInt << true;
- QTest::newRow( "mDouble_mDoubleString" ) << mDouble << mDoubleString << true;
- QTest::newRow( "mDoubleString_mDouble" ) << mDoubleString << mDouble << true;
+ QTest::newRow( "mDouble_mDoubleString" ) << mDouble << mDoubleString << false;
+ QTest::newRow( "mDoubleString_mDouble" ) << mDoubleString << mDouble << false;
QTest::newRow( "mDouble_mDoubleQString" ) << mDouble << mDoubleQString << true;
QTest::newRow( "mDoubleQString_mDouble" ) << mDoubleQString << mDouble << true;
- QTest::newRow( "mFloat_mFloatString" ) << mFloat << mFloatString << true;
- QTest::newRow( "mFloatString_mFloat" ) << mFloatString << mFloat << true;
+ QTest::newRow( "mDouble_mTextString" ) << mDouble << mTextString << false;
+ QTest::newRow( "mTextString_mDouble" ) << mTextString << mDouble << false;
+ QTest::newRow( "mDouble_mTextQString" ) << mDouble << mTextQString << false;
+ QTest::newRow( "mTextQString_mDouble" ) << mTextQString << mDouble << false;
+
+ QTest::newRow( "mFloat_mFloatString" ) << mFloat << mFloatString << false;
+ QTest::newRow( "mFloatString_mFloat" ) << mFloatString << mFloat << false;
QTest::newRow( "mFloat_mFloatQString" ) << mFloat << mFloatQString << true;
QTest::newRow( "mFloatQString_mFloat" ) << mFloatQString << mFloat << true;
- QTest::newRow( "mLongLong_mLongLongString" ) << mLongLong << mLongLongString << true;
- QTest::newRow( "mLongLongString_mLongLong" ) << mLongLongString << mLongLong << true;
+ QTest::newRow( "mLongLong_mLongLongString" ) << mLongLong << mLongLongString << false;
+ QTest::newRow( "mLongLongString_mLongLong" ) << mLongLongString << mLongLong << false;
QTest::newRow( "mLongLong_mLongLongQString" ) << mLongLong << mLongLongQString << true;
QTest::newRow( "mLongLongQString_mLongLong" ) << mLongLongQString << mLongLong << true;
- QTest::newRow( "mULongLong_mULongLongString" ) << mULongLong << mULongLongString << true;
- QTest::newRow( "mULongLongString_mULongLong" ) << mULongLongString << mULongLong << true;
+ QTest::newRow( "mULongLong_mULongLongString" ) << mULongLong << mULongLongString << false;
+ QTest::newRow( "mULongLongString_mULongLong" ) << mULongLongString << mULongLong << false;
QTest::newRow( "mULongLong_mULongLongQString" ) << mULongLong << mULongLongQString << true;
QTest::newRow( "mULongLongQString_mULongLong" ) << mULongLongQString << mULongLong << true;
- QTest::newRow( "mBool_mBoolString" ) << mBool << mBoolString << true;
- QTest::newRow( "mBoolString_mBool" ) << mBoolString << mBool << true;
+ QTest::newRow( "mBool_mBoolString" ) << mBool << mBoolString << false;
+ QTest::newRow( "mBoolString_mBool" ) << mBoolString << mBool << false;
QTest::newRow( "mBool_mBoolQString" ) << mBool << mBoolQString << true;
QTest::newRow( "mBoolQString_mBool" ) << mBoolQString << mBool << true;
@@ -1555,16 +1869,16 @@ void tst_QVariant::operator_eq_eq_data()
QTest::newRow("char_char") << QVariant(QChar('a')) << QVariant(QChar('a')) << true;
QTest::newRow("char_char2") << QVariant(QChar('a')) << QVariant(QChar('b')) << false;
- QTest::newRow("invalidConversion") << QVariant(QString("bubu")) << QVariant(0) << false;
- QTest::newRow("invalidConversionR") << QVariant(0) << QVariant(QString("bubu")) << false;
+ QTest::newRow("invalidConversion") << QVariant(QString("bubu")) << QVariant() << false;
+ QTest::newRow("invalidConversionR") << QVariant() << QVariant(QString("bubu")) << false;
// ### many other combinations missing
{
QUuid uuid(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
- QTest::newRow("uuidstring") << QVariant(uuid) << QVariant(uuid.toString()) << true;
- QTest::newRow("stringuuid") << QVariant(uuid.toString()) << QVariant(uuid) << true;
- QTest::newRow("uuidbytearray") << QVariant(uuid) << QVariant(uuid.toByteArray()) << true;
- QTest::newRow("bytearrayuuid") << QVariant(uuid.toByteArray()) << QVariant(uuid) << true;
+ QTest::newRow("uuidstring") << QVariant(uuid) << QVariant(uuid.toString()) << false;
+ QTest::newRow("stringuuid") << QVariant(uuid.toString()) << QVariant(uuid) << false;
+ QTest::newRow("uuidbytearray") << QVariant(uuid) << QVariant(uuid.toByteArray()) << false;
+ QTest::newRow("bytearrayuuid") << QVariant(uuid.toByteArray()) << QVariant(uuid) << false;
}
{
@@ -1696,363 +2010,11 @@ void tst_QVariant::operator_eq_eq()
QFETCH( QVariant, left );
QFETCH( QVariant, right );
QFETCH( bool, equal );
- QCOMPARE( left == right, equal );
-}
-
-void tst_QVariant::operator_eq_eq_rhs()
-{
- QVariant v = 42;
-
- QVERIFY(v == 42);
- QVERIFY(42 == v);
-
-#if 0
- /* This should _not_ compile */
- QStringList list;
- QDateTime dt;
-
- QVERIFY(dt == list);
-#endif
-}
-
-void tst_QVariant::compareNumbers_data() const
-{
- typedef signed char schar;
- QTest::addColumn<QVariant>("v1");
- QTest::addColumn<QVariant>("v2");
- QTest::addColumn<int>("expected");
-
- // sanity checking: same types
- QTest::newRow("bool1") << QVariant(false) << QVariant(false) << 0;
- QTest::newRow("bool2") << QVariant(true) << QVariant(true) << 0;
- QTest::newRow("bool3") << QVariant(false) << QVariant(true) << -1;
- QTest::newRow("bool4") << QVariant(true) << QVariant(false) << +1;
-
- QTest::newRow("char1") << qVariantFromValue(char(0)) << qVariantFromValue(char(0)) << 0;
- QTest::newRow("char2") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(CHAR_MAX) << 0;
- QTest::newRow("char3") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(CHAR_MIN) << 0;
- QTest::newRow("char4") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(CHAR_MAX) << -1;
- QTest::newRow("char5") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(CHAR_MIN) << +1;
-
- QTest::newRow("schar1") << qVariantFromValue(schar(0)) << qVariantFromValue(schar(0)) << 0;
- QTest::newRow("schar2") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(SCHAR_MAX) << 0;
- QTest::newRow("schar3") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(SCHAR_MIN) << 0;
- QTest::newRow("schar4") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(SCHAR_MAX) << -1;
- QTest::newRow("schar5") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(SCHAR_MIN) << +1;
-
- QTest::newRow("uchar1") << qVariantFromValue(uchar(0)) << qVariantFromValue(uchar(0)) << 0;
- QTest::newRow("uchar2") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(UCHAR_MAX) << 0;
- QTest::newRow("uchar3") << qVariantFromValue(uchar(0)) << qVariantFromValue(UCHAR_MAX) << -1;
- QTest::newRow("uchar4") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(uchar(0)) << +1;
-
- QTest::newRow("short1") << qVariantFromValue(short(0)) << qVariantFromValue(short(0)) << 0;
- QTest::newRow("short2") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(SHRT_MAX) << 0;
- QTest::newRow("short3") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(SHRT_MIN) << 0;
- QTest::newRow("short4") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(SHRT_MAX) << -1;
- QTest::newRow("short5") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(SHRT_MIN) << +1;
-
- QTest::newRow("ushort1") << qVariantFromValue(ushort(0)) << qVariantFromValue(ushort(0)) << 0;
- QTest::newRow("ushort2") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(USHRT_MAX) << 0;
- QTest::newRow("ushort3") << qVariantFromValue(ushort(0)) << qVariantFromValue(USHRT_MAX) << -1;
- QTest::newRow("ushort4") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(ushort(0)) << +1;
-
- QTest::newRow("int1") << qVariantFromValue(int(0)) << qVariantFromValue(int(0)) << 0;
- QTest::newRow("int2") << qVariantFromValue(INT_MAX) << qVariantFromValue(INT_MAX) << 0;
- QTest::newRow("int3") << qVariantFromValue(INT_MIN) << qVariantFromValue(INT_MIN) << 0;
- QTest::newRow("int4") << qVariantFromValue(INT_MIN) << qVariantFromValue(INT_MAX) << -1;
- QTest::newRow("int5") << qVariantFromValue(INT_MAX) << qVariantFromValue(INT_MIN) << +1;
-
- QTest::newRow("uint1") << qVariantFromValue(uint(0)) << qVariantFromValue(uint(0)) << 0;
- QTest::newRow("uint2") << qVariantFromValue(UINT_MAX) << qVariantFromValue(UINT_MAX) << 0;
- QTest::newRow("uint3") << qVariantFromValue(uint(0)) << qVariantFromValue(UINT_MAX) << -1;
- QTest::newRow("uint4") << qVariantFromValue(UINT_MAX) << qVariantFromValue(uint(0)) << +1;
-
- QTest::newRow("long1") << qVariantFromValue(long(0)) << qVariantFromValue(long(0)) << 0;
- QTest::newRow("long2") << qVariantFromValue(LONG_MAX) << qVariantFromValue(LONG_MAX) << 0;
- QTest::newRow("long3") << qVariantFromValue(LONG_MIN) << qVariantFromValue(LONG_MIN) << 0;
- QTest::newRow("long4") << qVariantFromValue(LONG_MIN) << qVariantFromValue(LONG_MAX) << -1;
- QTest::newRow("long5") << qVariantFromValue(LONG_MAX) << qVariantFromValue(LONG_MIN) << +1;
-
- QTest::newRow("ulong1") << qVariantFromValue(ulong(0)) << qVariantFromValue(ulong(0)) << 0;
- QTest::newRow("ulong2") << qVariantFromValue(ULONG_MAX) << qVariantFromValue(ULONG_MAX) << 0;
- QTest::newRow("ulong3") << qVariantFromValue(ulong(0)) << qVariantFromValue(ULONG_MAX) << -1;
- QTest::newRow("ulong4") << qVariantFromValue(ULONG_MAX) << qVariantFromValue(ulong(0)) << +1;
-
- QTest::newRow("llong1") << qVariantFromValue(qlonglong(0)) << qVariantFromValue(qlonglong(0)) << 0;
- QTest::newRow("llong2") << qVariantFromValue(LLONG_MAX) << qVariantFromValue(LLONG_MAX) << 0;
- QTest::newRow("llong3") << qVariantFromValue(LLONG_MIN) << qVariantFromValue(LLONG_MIN) << 0;
- QTest::newRow("llong4") << qVariantFromValue(LLONG_MIN) << qVariantFromValue(LLONG_MAX) << -1;
- QTest::newRow("llong5") << qVariantFromValue(LLONG_MAX) << qVariantFromValue(LLONG_MIN) << +1;
-
- QTest::newRow("ullong1") << qVariantFromValue(qulonglong(0)) << qVariantFromValue(qulonglong(0)) << 0;
- QTest::newRow("ullong2") << qVariantFromValue(ULLONG_MAX) << qVariantFromValue(ULLONG_MAX) << 0;
- QTest::newRow("ullong3") << qVariantFromValue(qulonglong(0)) << qVariantFromValue(ULLONG_MAX) << -1;
- QTest::newRow("ullong4") << qVariantFromValue(ULLONG_MAX) << qVariantFromValue(qulonglong(0)) << +1;
-
- QTest::newRow("float1") << qVariantFromValue(0.f) << qVariantFromValue(0.f) << 0;
- QTest::newRow("float2") << qVariantFromValue(-1.f) << qVariantFromValue(0.f) << -1;
- QTest::newRow("float3") << qVariantFromValue(0.f) << qVariantFromValue(-1.f) << +1;
- QTest::newRow("float4") << qVariantFromValue(-float(qInf())) << qVariantFromValue(0.f) << -1;
- QTest::newRow("float5") << qVariantFromValue(0.f) << qVariantFromValue(-float(qInf())) << +1;
- QTest::newRow("float6") << qVariantFromValue(-float(qInf())) << qVariantFromValue(-float(qInf())) << 0;
- QTest::newRow("float7") << qVariantFromValue(float(qInf())) << qVariantFromValue(float(qInf())) << 0;
-
- QTest::newRow("double1") << qVariantFromValue(0.) << qVariantFromValue(0.) << 0;
- QTest::newRow("double2") << qVariantFromValue(-1.) << qVariantFromValue(0.) << -1;
- QTest::newRow("double3") << qVariantFromValue(0.) << qVariantFromValue(-1.) << +1;
- QTest::newRow("double4") << qVariantFromValue(-qInf()) << qVariantFromValue(0.) << -1;
- QTest::newRow("double5") << qVariantFromValue(0.) << qVariantFromValue(-qInf()) << +1;
- QTest::newRow("double6") << qVariantFromValue(-double(qInf())) << qVariantFromValue(-qInf()) << 0;
- QTest::newRow("double7") << qVariantFromValue(qInf()) << qVariantFromValue(qInf()) << 0;
- QTest::newRow("double8") << qVariantFromValue(-qInf()) << qVariantFromValue(qInf()) << -1;
- QTest::newRow("double9") << qVariantFromValue(qQNaN()) << qVariantFromValue(0.) << INT_MAX;
- QTest::newRow("double10") << qVariantFromValue(0.) << qVariantFromValue(qQNaN()) << INT_MAX;
- QTest::newRow("double11") << qVariantFromValue(qQNaN()) << qVariantFromValue(qQNaN()) << INT_MAX;
-
- // mixed comparisons
- // fp + fp
- QTest::newRow("float+double1") << qVariantFromValue(0.f) << qVariantFromValue(0.) << 0;
- QTest::newRow("float+double2") << qVariantFromValue(-1.f) << qVariantFromValue(0.) << -1;
- QTest::newRow("float+double3") << qVariantFromValue(0.f) << qVariantFromValue(-1.) << +1;
- QTest::newRow("float+double4") << qVariantFromValue(-float(qInf())) << qVariantFromValue(0.) << -1;
- QTest::newRow("float+double5") << qVariantFromValue(0.f) << qVariantFromValue(-qInf()) << +1;
- QTest::newRow("float+double6") << qVariantFromValue(-float(qInf())) << qVariantFromValue(-qInf()) << 0;
- QTest::newRow("float+double7") << qVariantFromValue(float(qInf())) << qVariantFromValue(qInf()) << 0;
- QTest::newRow("float+double8") << qVariantFromValue(-float(qInf())) << qVariantFromValue(qInf()) << -1;
- QTest::newRow("float+double9") << qVariantFromValue(qQNaN()) << qVariantFromValue(0.) << INT_MAX;
- QTest::newRow("float+double10") << qVariantFromValue(0.) << qVariantFromValue(qQNaN()) << INT_MAX;
- QTest::newRow("float+double11") << qVariantFromValue(qQNaN()) << qVariantFromValue(qQNaN()) << INT_MAX;
-
- // fp + int
- QTest::newRow("float+int1") << qVariantFromValue(0.f) << qVariantFromValue(0) << 0;
- QTest::newRow("double+int1") << qVariantFromValue(0.) << qVariantFromValue(0) << 0;
- QTest::newRow("float+int2") << qVariantFromValue(-1.f) << qVariantFromValue(0) << -1;
- QTest::newRow("double+int2") << qVariantFromValue(-1.) << qVariantFromValue(0) << -1;
- QTest::newRow("float+int3") << qVariantFromValue(0.f) << qVariantFromValue(-1) << +1;
- QTest::newRow("double+int3") << qVariantFromValue(0.) << qVariantFromValue(-1) << +1;
- QTest::newRow("float+int4") << qVariantFromValue(1.5f) << qVariantFromValue(1) << +1;
- QTest::newRow("double+int4") << qVariantFromValue(1.5) << qVariantFromValue(1) << +1;
- QTest::newRow("double+int5") << qVariantFromValue(qInf()) << qVariantFromValue(1) << +1;
-
- // fp + uint
- QTest::newRow("float+uint1") << qVariantFromValue(0.f) << qVariantFromValue(0U) << 0;
- QTest::newRow("double+uint1") << qVariantFromValue(0.) << qVariantFromValue(0U) << 0;
- QTest::newRow("float+uint2") << qVariantFromValue(-1.f) << qVariantFromValue(0U) << -1;
- QTest::newRow("double+uint2") << qVariantFromValue(-1.) << qVariantFromValue(0U) << -1;
- QTest::newRow("float+uint3") << qVariantFromValue(0.f) << qVariantFromValue(1U) << -1;
- QTest::newRow("double+uint3") << qVariantFromValue(0.) << qVariantFromValue(1U) << -1;
- QTest::newRow("float+uint4") << qVariantFromValue(1.5f) << qVariantFromValue(1U) << +1;
- QTest::newRow("double+uint4") << qVariantFromValue(1.5) << qVariantFromValue(1U) << +1;
-
- // lower ranked + int
- QTest::newRow("bool+int1") << qVariantFromValue(false) << qVariantFromValue(0) << 0;
- QTest::newRow("bool+int2") << qVariantFromValue(false) << qVariantFromValue(1) << -1;
- QTest::newRow("bool+int3") << qVariantFromValue(true) << qVariantFromValue(0) << +1;
- QTest::newRow("bool+int4") << qVariantFromValue(true) << qVariantFromValue(1) << 0;
- QTest::newRow("bool+int5") << qVariantFromValue(true) << qVariantFromValue(2) << -1;
-
- QTest::newRow("char+int1") << qVariantFromValue(char(0)) << qVariantFromValue(0) << 0;
- QTest::newRow("char+int2") << qVariantFromValue(char(0)) << qVariantFromValue(1) << -1;
- QTest::newRow("char+int3") << qVariantFromValue(char(1)) << qVariantFromValue(0) << +1;
- QTest::newRow("char+int4") << qVariantFromValue(char(1)) << qVariantFromValue(1) << 0;
- if (std::numeric_limits<char>::is_signed) {
- QTest::newRow("char+int5") << qVariantFromValue(char(-1)) << qVariantFromValue(0) << -1;
- QTest::newRow("char+int6") << qVariantFromValue(char(-1)) << qVariantFromValue(-1) << 0;
- }
-
- QTest::newRow("schar+int1") << qVariantFromValue(schar(0)) << qVariantFromValue(0) << 0;
- QTest::newRow("schar+int2") << qVariantFromValue(schar(0)) << qVariantFromValue(1) << -1;
- QTest::newRow("schar+int3") << qVariantFromValue(schar(1)) << qVariantFromValue(0) << +1;
- QTest::newRow("schar+int4") << qVariantFromValue(schar(1)) << qVariantFromValue(1) << 0;
- QTest::newRow("schar+int5") << qVariantFromValue(schar(-1)) << qVariantFromValue(0) << -1;
- QTest::newRow("schar+int6") << qVariantFromValue(schar(-1)) << qVariantFromValue(-1) << 0;
-
- QTest::newRow("uchar+int1") << qVariantFromValue(uchar(0)) << qVariantFromValue(0) << 0;
- QTest::newRow("uchar+int2") << qVariantFromValue(uchar(0)) << qVariantFromValue(1) << -1;
- QTest::newRow("uchar+int3") << qVariantFromValue(uchar(1)) << qVariantFromValue(0) << +1;
- QTest::newRow("uchar+int4") << qVariantFromValue(uchar(1)) << qVariantFromValue(1) << 0;
-
- QTest::newRow("short+int1") << qVariantFromValue(short(0)) << qVariantFromValue(0) << 0;
- QTest::newRow("short+int2") << qVariantFromValue(short(0)) << qVariantFromValue(1) << -1;
- QTest::newRow("short+int3") << qVariantFromValue(short(1)) << qVariantFromValue(0) << +1;
- QTest::newRow("short+int4") << qVariantFromValue(short(1)) << qVariantFromValue(1) << 0;
- QTest::newRow("short+int5") << qVariantFromValue(short(-1)) << qVariantFromValue(0) << -1;
- QTest::newRow("short+int6") << qVariantFromValue(short(-1)) << qVariantFromValue(-1) << 0;
-
- QTest::newRow("ushort+int1") << qVariantFromValue(ushort(0)) << qVariantFromValue(0) << 0;
- QTest::newRow("ushort+int2") << qVariantFromValue(ushort(0)) << qVariantFromValue(1) << -1;
- QTest::newRow("ushort+int3") << qVariantFromValue(ushort(1)) << qVariantFromValue(0) << +1;
- QTest::newRow("ushort+int4") << qVariantFromValue(ushort(1)) << qVariantFromValue(1) << 0;
-
- // lower ranked + uint (without sign change)
- QTest::newRow("bool+uint1") << qVariantFromValue(false) << qVariantFromValue(0U) << 0;
- QTest::newRow("bool+uint2") << qVariantFromValue(false) << qVariantFromValue(1U) << -1;
- QTest::newRow("bool+uint3") << qVariantFromValue(true) << qVariantFromValue(0U) << +1;
- QTest::newRow("bool+uint4") << qVariantFromValue(true) << qVariantFromValue(1U) << 0;
- QTest::newRow("bool+uint5") << qVariantFromValue(true) << qVariantFromValue(2U) << -1;
-
- QTest::newRow("char+uint1") << qVariantFromValue(char(0)) << qVariantFromValue(0U) << 0;
- QTest::newRow("char+uint2") << qVariantFromValue(char(0)) << qVariantFromValue(1U) << -1;
- QTest::newRow("char+uint3") << qVariantFromValue(char(1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("char+uint4") << qVariantFromValue(char(1)) << qVariantFromValue(1U) << 0;
-
- QTest::newRow("schar+uint1") << qVariantFromValue(schar(0)) << qVariantFromValue(0U) << 0;
- QTest::newRow("schar+uint2") << qVariantFromValue(schar(0)) << qVariantFromValue(1U) << -1;
- QTest::newRow("schar+uint3") << qVariantFromValue(schar(1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("schar+uint4") << qVariantFromValue(schar(1)) << qVariantFromValue(1U) << 0;
-
- QTest::newRow("uchar+uint1") << qVariantFromValue(uchar(0)) << qVariantFromValue(0U) << 0;
- QTest::newRow("uchar+uint2") << qVariantFromValue(uchar(0)) << qVariantFromValue(1U) << -1;
- QTest::newRow("uchar+uint3") << qVariantFromValue(uchar(1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("uchar+uint4") << qVariantFromValue(uchar(1)) << qVariantFromValue(1U) << 0;
-
- QTest::newRow("short+uint1") << qVariantFromValue(short(0)) << qVariantFromValue(0U) << 0;
- QTest::newRow("short+uint2") << qVariantFromValue(short(0)) << qVariantFromValue(1U) << -1;
- QTest::newRow("short+uint3") << qVariantFromValue(short(1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("short+uint4") << qVariantFromValue(short(1)) << qVariantFromValue(1U) << 0;
-
- QTest::newRow("ushort+uint1") << qVariantFromValue(ushort(0)) << qVariantFromValue(0U) << 0;
- QTest::newRow("ushort+uint2") << qVariantFromValue(ushort(0)) << qVariantFromValue(1U) << -1;
- QTest::newRow("ushort+uint3") << qVariantFromValue(ushort(1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("ushort+uint4") << qVariantFromValue(ushort(1)) << qVariantFromValue(1U) << 0;
-
- // int + qlonglong
- QTest::newRow("int+qlonglong1") << qVariantFromValue(0) << qVariantFromValue(Q_INT64_C(0)) << 0;
- QTest::newRow("int+qlonglong2") << qVariantFromValue(1) << qVariantFromValue(Q_INT64_C(0)) << +1;
- QTest::newRow("int+qlonglong3") << qVariantFromValue(0) << qVariantFromValue(Q_INT64_C(1)) << -1;
- QTest::newRow("int+qlonglong4") << qVariantFromValue(1) << qVariantFromValue(Q_INT64_C(1)) << 0;
- QTest::newRow("int+qlonglong5") << qVariantFromValue(0) << qVariantFromValue(Q_INT64_C(-1)) << +1;
- QTest::newRow("int+qlonglong6") << qVariantFromValue(-1) << qVariantFromValue(Q_INT64_C(0)) << -1;
- QTest::newRow("int+qlonglong7") << qVariantFromValue(-1) << qVariantFromValue(Q_INT64_C(-1)) << 0;
-
- // uint + qulonglong
- QTest::newRow("uint+qulonglong1") << qVariantFromValue(0U) << qVariantFromValue(Q_UINT64_C(0)) << 0;
- QTest::newRow("uint+qulonglong2") << qVariantFromValue(1U) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("uint+qulonglong3") << qVariantFromValue(0U) << qVariantFromValue(Q_UINT64_C(1)) << -1;
- QTest::newRow("uint+qulonglong4") << qVariantFromValue(1U) << qVariantFromValue(Q_UINT64_C(1)) << 0;
-
- // int + uint (without sign change)
- QTest::newRow("int+uint1") << qVariantFromValue(0) << qVariantFromValue(0U) << 0;
- QTest::newRow("int+uint2") << qVariantFromValue(1) << qVariantFromValue(0U) << +1;
- QTest::newRow("int+uint3") << qVariantFromValue(0) << qVariantFromValue(1U) << -1;
- QTest::newRow("int+uint4") << qVariantFromValue(1) << qVariantFromValue(1U) << 0;
-
- // uint + qlonglong
- QTest::newRow("uint+qlonglong1") << qVariantFromValue(0U) << qVariantFromValue(Q_INT64_C(0)) << 0;
- QTest::newRow("uint+qlonglong2") << qVariantFromValue(1U) << qVariantFromValue(Q_INT64_C(0)) << +1;
- QTest::newRow("uint+qlonglong3") << qVariantFromValue(0U) << qVariantFromValue(Q_INT64_C(1)) << -1;
- QTest::newRow("uint+qlonglong4") << qVariantFromValue(1U) << qVariantFromValue(Q_INT64_C(1)) << 0;
- QTest::newRow("uint+qlonglong5") << qVariantFromValue(0U) << qVariantFromValue(Q_INT64_C(-1)) << +1;
-
- // boundary conditions
- QTest::newRow("charmax+intmax") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(INT_MAX) << -1;
- QTest::newRow("charmax+uintmax") << qVariantFromValue(CHAR_MAX) << qVariantFromValue(UINT_MAX) << -1;
- QTest::newRow("scharmax+intmax") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(INT_MAX) << -1;
- QTest::newRow("scharmax+uintmax") << qVariantFromValue(SCHAR_MAX) << qVariantFromValue(UINT_MAX) << -1;
- QTest::newRow("ucharmax+intmax") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(INT_MAX) << -1;
- QTest::newRow("ucharmax+uintmax") << qVariantFromValue(UCHAR_MAX) << qVariantFromValue(UINT_MAX) << -1;
- QTest::newRow("shortmax+intmax") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(INT_MAX) << -1;
- QTest::newRow("shortmax+uintmax") << qVariantFromValue(SHRT_MAX) << qVariantFromValue(UINT_MAX) << -1;
- QTest::newRow("ushortmax+intmax") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(INT_MAX) << -1;
- QTest::newRow("ushortmax+uintmax") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(UINT_MAX) << -1;
-
- QTest::newRow("intmin+qlonglongmin") << qVariantFromValue(INT_MIN) << qVariantFromValue(LLONG_MIN) << +1;
- QTest::newRow("intmax+uintmax") << qVariantFromValue(INT_MAX) << qVariantFromValue(UINT_MAX) << -1;
- QTest::newRow("intmax+qlonglongmax") << qVariantFromValue(INT_MAX) << qVariantFromValue(LLONG_MAX) << -1;
- QTest::newRow("uintmax+qlonglongmax") << qVariantFromValue(UINT_MAX) << qVariantFromValue(LLONG_MAX) << -1;
- QTest::newRow("intmax+qulonglongmax") << qVariantFromValue(INT_MAX) << qVariantFromValue(ULLONG_MAX) << -1;
- QTest::newRow("qlonglongmax+qulonglongmax") << qVariantFromValue(LLONG_MAX) << qVariantFromValue(ULLONG_MAX) << -1;
- QTest::newRow("uintmax+qlonglongmin") << qVariantFromValue(UINT_MAX) << qVariantFromValue(LLONG_MIN) << +1;
-
- // check for no sign-extension issues
- QTest::newRow("ushortmax+intzero") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(0) << +1;
- QTest::newRow("ushortmax+qlonglongzero") << qVariantFromValue(USHRT_MAX) << qVariantFromValue(Q_INT64_C(0)) << +1;
- QTest::newRow("uintmax+qlonglongzero") << qVariantFromValue(UINT_MAX) << qVariantFromValue(Q_INT64_C(0)) << +1;
-
- // sign changes
- // the tests below check that a signed negative number sign-changes to a non-zero unsigned number and that
- // signed -1 sign-changes to unsigned maximum (all bits set, ~0). This works on two's complement machines
- // (all that Qt supports), and would also work on one's complement.
- if (std::numeric_limits<char>::is_signed) {
- QTest::newRow("signchange-char+uint") << qVariantFromValue(char(-1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-char+uintmax") << qVariantFromValue(char(-1)) << qVariantFromValue(UINT_MAX) << 0;
- QTest::newRow("signchange-charmin+uint") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-char+qulonglong") << qVariantFromValue(char(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-char+qulonglongmax") << qVariantFromValue(char(-1)) << qVariantFromValue(ULLONG_MAX) << 0;
- QTest::newRow("signchange-charmin+qulonglong") << qVariantFromValue(CHAR_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- }
- QTest::newRow("signchange-schar+uint") << qVariantFromValue(schar(-1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-schar+uintmax") << qVariantFromValue(schar(-1)) << qVariantFromValue(UINT_MAX) << 0;
- QTest::newRow("signchange-scharmin+uint") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-schar+qulonglong") << qVariantFromValue(schar(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-schar+qulonglongmax") << qVariantFromValue(schar(-1)) << qVariantFromValue(ULLONG_MAX) << 0;
- QTest::newRow("signchange-scharmin+qulonglong") << qVariantFromValue(SCHAR_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-short+uint") << qVariantFromValue(short(-1)) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-short+uintmax") << qVariantFromValue(short(-1)) << qVariantFromValue(UINT_MAX) << 0;
- QTest::newRow("signchange-shortmin+uint") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-short+qulonglong") << qVariantFromValue(short(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-short+qulonglongmax") << qVariantFromValue(short(-1)) << qVariantFromValue(ULLONG_MAX) << 0;
- QTest::newRow("signchange-shortmin+qulonglong") << qVariantFromValue(SHRT_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-int+uint") << qVariantFromValue(-1) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-int+uintmax") << qVariantFromValue(-1) << qVariantFromValue(UINT_MAX) << 0;
- QTest::newRow("signchange-intmin+uint") << qVariantFromValue(INT_MIN) << qVariantFromValue(0U) << +1;
- QTest::newRow("signchange-int+qulonglong") << qVariantFromValue(-1) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-int+qulonglongmax") << qVariantFromValue(-1) << qVariantFromValue(ULLONG_MAX) << 0;
- QTest::newRow("signchange-intmin+qulonglong") << qVariantFromValue(INT_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- // no qlonglong+uint, since that should promote to qlonglong and then the comparison is signed (tested above)
- QTest::newRow("signchange-qlonglong+qulonglong") << qVariantFromValue(Q_INT64_C(-1)) << qVariantFromValue(Q_UINT64_C(0)) << +1;
- QTest::newRow("signchange-qlonglong+qulonglongmax") << qVariantFromValue(Q_INT64_C(-1)) << qVariantFromValue(ULLONG_MAX) << 0;
- QTest::newRow("signchange-qlonglongmin+qulonglong") << qVariantFromValue(LLONG_MIN) << qVariantFromValue(Q_UINT64_C(0)) << +1;
-}
-
-void tst_QVariant::compareNumbers() const
-{
- QFETCH(QVariant, v1);
- QFETCH(QVariant, v2);
- QFETCH(int, expected);
-
- if (expected == -1) {
- QVERIFY(v1 < v2);
- QVERIFY(v1 <= v2);
- QVERIFY(!(v1 == v2));
- QVERIFY(!(v1 > v2));
- QVERIFY(!(v1 >= v2));
-
- QVERIFY(!(v2 < v1));
- QVERIFY(!(v2 <= v1));
- QVERIFY(!(v2 == v1));
- QVERIFY(v2 >= v1);
- QVERIFY(v2 > v1);
- } else if (expected == 0) {
- QVERIFY(!(v1 < v2));
- QVERIFY(v1 <= v2);
- QCOMPARE(v1, v2);
- QVERIFY(!(v1 > v2));
- QVERIFY(v1 >= v2);
-
- QVERIFY(!(v2 < v1));
- QVERIFY(v2 <= v1);
- QCOMPARE(v2, v1);
- QVERIFY(v2 >= v1);
- QVERIFY(!(v2 > v1));
- } else if (expected == +1) {
- QVERIFY(!(v1 < v2));
- QVERIFY(!(v1 <= v2));
- QVERIFY(!(v1 == v2));
- QVERIFY(v1 > v2);
- QVERIFY(v1 >= v2);
-
- QVERIFY(v2 < v1);
- QVERIFY(v2 <= v1);
- QVERIFY(!(v2 == v1));
- QVERIFY(!(v2 >= v1));
- QVERIFY(!(v2 > v1));
- } else {
- // unorderable (NaN)
- QVERIFY(!(v1 == v2));
- }
+ QT_TEST_EQUALITY_OPS(left, right, equal);
}
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
void tst_QVariant::typeName_data()
{
QTest::addColumn<int>("type");
@@ -2080,7 +2042,8 @@ void tst_QVariant::typeName_data()
QTest::newRow("20") << int(QVariant::Region) << QByteArray("QRegion");
QTest::newRow("21") << int(QVariant::Bitmap) << QByteArray("QBitmap");
QTest::newRow("22") << int(QVariant::Cursor) << QByteArray("QCursor");
- QTest::newRow("23") << int(QVariant::SizePolicy) << QByteArray("QSizePolicy");
+ // The test below doesn't work as long as we don't link against widgets
+// QTest::newRow("23") << int(QVariant::SizePolicy) << QByteArray("QSizePolicy");
QTest::newRow("24") << int(QVariant::Date) << QByteArray("QDate");
QTest::newRow("25") << int(QVariant::Time) << QByteArray("QTime");
QTest::newRow("26") << int(QVariant::DateTime) << QByteArray("QDateTime");
@@ -2098,8 +2061,6 @@ void tst_QVariant::typeName_data()
QTest::newRow("38") << int(QVariant::LineF) << QByteArray("QLineF");
QTest::newRow("39") << int(QVariant::RectF) << QByteArray("QRectF");
QTest::newRow("40") << int(QVariant::PointF) << QByteArray("QPointF");
- QTest::newRow("41") << int(QVariant::RegExp) << QByteArray("QRegExp");
- QTest::newRow("43") << int(QVariant::Matrix) << QByteArray("QMatrix");
QTest::newRow("44") << int(QVariant::Transform) << QByteArray("QTransform");
QTest::newRow("45") << int(QVariant::Hash) << QByteArray("QVariantHash");
QTest::newRow("46") << int(QVariant::Matrix4x4) << QByteArray("QMatrix4x4");
@@ -2126,17 +2087,23 @@ void tst_QVariant::typeToName()
// assumes that QVariant::Type contains consecutive values
int max = QVariant::LastGuiType;
- for ( int t = 1; t <= max; t++ ) {
+ for (int t = 1; t <= max; ++t) {
+ if (!QMetaType::isRegistered(t)) {
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "^Trying to construct an instance of an invalid type"));
+ }
const char *n = QVariant::typeToName( (QVariant::Type)t );
if (n)
QCOMPARE( int(QVariant::nameToType( n )), t );
-
}
+
QCOMPARE(QVariant::typeToName(QVariant::Int), "int");
// not documented but we return 0 if the type is out of range
// by testing this we catch cases where QVariant is extended
// but type_map is not updated accordingly
- QCOMPARE( QVariant::typeToName( QVariant::Type(max+1) ), (char*)0 );
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "^Trying to construct an instance of an invalid type"));
+ QCOMPARE(QVariant::typeToName(QVariant::Type(max + 1)), (const char *)nullptr);
// invalid type names
QVERIFY( QVariant::nameToType( 0 ) == QVariant::Invalid );
QVERIFY( QVariant::nameToType( "" ) == QVariant::Invalid );
@@ -2150,6 +2117,8 @@ void tst_QVariant::typeToName()
QCOMPARE(QVariant::nameToType("Q_LLONG"), QVariant::Invalid);
QCOMPARE(QVariant::nameToType("Q_ULLONG"), QVariant::Invalid);
}
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
void tst_QVariant::streamInvalidVariant()
{
@@ -2160,7 +2129,7 @@ void tst_QVariant::streamInvalidVariant()
QVariant writeVariant;
QVariant readVariant;
- QVERIFY( writeVariant.type() == QVariant::Invalid );
+ QVERIFY( writeVariant.typeId() == QMetaType::UnknownType );
QByteArray data;
QDataStream writeStream( &data, QIODevice::WriteOnly );
@@ -2172,7 +2141,7 @@ void tst_QVariant::streamInvalidVariant()
QVERIFY( readX == writeX );
// Two invalid QVariant's aren't necessarily the same, so == will
// return false if one is invalid, so check the type() instead
- QVERIFY( readVariant.type() == QVariant::Invalid );
+ QVERIFY( readVariant.typeId() == QMetaType::UnknownType );
QVERIFY( readY == writeY );
}
@@ -2189,6 +2158,12 @@ struct MyType
{
++instanceCount;
}
+ MyType &operator=(const MyType &other)
+ {
+ number = other.number;
+ text = other.text;
+ return *this;
+ }
~MyType()
{
--instanceCount;
@@ -2196,6 +2171,8 @@ struct MyType
int number;
const char *text;
};
+bool operator==(const MyType &a, const MyType &b) { return a.number == b.number && a.text == b.text; }
+static_assert(QTypeTraits::has_operator_equal_v<MyType>);
Q_DECLARE_METATYPE(MyType)
Q_DECLARE_METATYPE(MyType*)
@@ -2210,11 +2187,13 @@ void tst_QVariant::userType()
QVariant userVar;
userVar.setValue(data);
- QCOMPARE(userVar.type(), QVariant::UserType);
+ QVERIFY(QMetaType::fromName("MyType").isValid());
+ QCOMPARE(QMetaType::fromName("MyType"), QMetaType::fromType<MyType>());
+ QVERIFY(userVar.typeId() > QMetaType::User);
QCOMPARE(userVar.userType(), qMetaTypeId<MyType>());
QCOMPARE(userVar.typeName(), "MyType");
QVERIFY(!userVar.isNull());
- QVERIFY(!userVar.canConvert(QVariant::String));
+ QVERIFY(!userVar.canConvert<QString>());
QVariant userVar2(userVar);
QCOMPARE(userVar, userVar2);
@@ -2239,11 +2218,11 @@ void tst_QVariant::userType()
QVariant userVar;
userVar.setValue(&data);
- QCOMPARE(userVar.type(), QVariant::UserType);
+ QVERIFY(userVar.typeId() > QMetaType::User);
QCOMPARE(userVar.userType(), qMetaTypeId<MyType*>());
QCOMPARE(userVar.typeName(), "MyType*");
QVERIFY(!userVar.isNull());
- QVERIFY(!userVar.canConvert(QVariant::String));
+ QVERIFY(!userVar.canConvert<QString>());
QVariant userVar2(userVar);
QCOMPARE(userVar, userVar2);
@@ -2333,7 +2312,15 @@ void tst_QVariant::podUserType()
pod.a = 10;
pod.b = 20;
+ // one of these two must register the type
+ // (QVariant::fromValue calls QMetaType::fromType)
QVariant pod_as_variant = QVariant::fromValue(pod);
+ QMetaType mt = QMetaType::fromType<MyTypePOD>();
+ QCOMPARE(pod_as_variant.metaType(), mt);
+ QCOMPARE(pod_as_variant.metaType().name(), mt.name());
+ QCOMPARE(QMetaType::fromName(mt.name()), mt);
+ QCOMPARE_NE(pod_as_variant.typeId(), 0);
+
MyTypePOD pod2 = qvariant_cast<MyTypePOD>(pod_as_variant);
QCOMPARE(pod.a, pod2.a);
@@ -2351,37 +2338,37 @@ void tst_QVariant::basicUserType()
QVariant v;
{
int i = 7;
- v = QVariant(QMetaType::Int, &i);
+ v = QVariant(QMetaType::fromType<int>(), &i);
}
- QCOMPARE(v.type(), QVariant::Int);
+ QCOMPARE(v.typeId(), QMetaType::Int);
QCOMPARE(v.toInt(), 7);
{
QString s("foo");
- v = QVariant(QMetaType::QString, &s);
+ v = QVariant(QMetaType::fromType<QString>(), &s);
}
- QCOMPARE(v.type(), QVariant::String);
+ QCOMPARE(v.typeId(), QMetaType::QString);
QCOMPARE(v.toString(), QString("foo"));
{
double d = 4.4;
- v = QVariant(QMetaType::Double, &d);
+ v = QVariant(QMetaType::fromType<double>(), &d);
}
- QCOMPARE(v.type(), QVariant::Double);
+ QCOMPARE(v.typeId(), QMetaType::Double);
QCOMPARE(v.toDouble(), 4.4);
{
float f = 4.5f;
- v = QVariant(QMetaType::Float, &f);
+ v = QVariant(QMetaType::fromType<float>(), &f);
}
QCOMPARE(v.userType(), int(QMetaType::Float));
QCOMPARE(v.toDouble(), 4.5);
{
QByteArray ba("bar");
- v = QVariant(QMetaType::QByteArray, &ba);
+ v = QVariant(QMetaType::fromType<QByteArray>(), &ba);
}
- QCOMPARE(v.type(), QVariant::ByteArray);
+ QCOMPARE(v.typeId(), QMetaType::QByteArray);
QCOMPARE(v.toByteArray(), QByteArray("bar"));
}
@@ -2542,13 +2529,11 @@ void tst_QVariant::saveLoadCustomTypes()
QByteArray data;
Blah i = { 42 };
- int tp = qRegisterMetaType<Blah>("Blah");
+ auto tp = QMetaType::fromType<Blah>();
QVariant v = QVariant(tp, &i);
- qRegisterMetaTypeStreamOperators<Blah>("Blah");
-
- QCOMPARE(v.userType(), tp);
- QCOMPARE(v.type(), QVariant::UserType);
+ QCOMPARE(v.userType(), tp.id());
+ QVERIFY(v.typeId() > QMetaType::User);
{
QDataStream stream(&data, QIODevice::WriteOnly);
stream << v;
@@ -2561,7 +2546,7 @@ void tst_QVariant::saveLoadCustomTypes()
stream >> v;
}
- QCOMPARE(int(v.userType()), QMetaType::type("Blah"));
+ QCOMPARE(int(v.userType()), QMetaType::fromName("Blah").id());
int value = *(int*)v.constData();
QCOMPARE(value, 42);
}
@@ -2600,23 +2585,15 @@ void tst_QVariant::variantMap()
QCOMPARE(map2.value("test").toInt(), 42);
QCOMPARE(map2, map);
- QVariant v2 = QVariant(QMetaType::type("QVariantMap"), &map);
+ QVariant v2 = QVariant(QMetaType::fromType<QVariantMap>(), &map);
QCOMPARE(qvariant_cast<QVariantMap>(v2).value("test").toInt(), 42);
- QVariant v3 = QVariant(QMetaType::type("QMap<QString, QVariant>"), &map);
+ QVariant v3 = QVariant(QMetaType::fromType<QMap<QString, QVariant>>(), &map);
QCOMPARE(qvariant_cast<QVariantMap>(v3).value("test").toInt(), 42);
- QCOMPARE(v, QVariant(v.toHash()));
-
- // multi-keys
- map.insertMulti("test", 47);
- v = map;
- map2 = qvariant_cast<QVariantMap>(v);
- QCOMPARE(map2, map);
- map2 = v.toMap();
- QCOMPARE(map2, map);
-
- QCOMPARE(v, QVariant(v.toHash()));
+ QHash<QString, QVariant> hash;
+ hash["test"] = 42;
+ QCOMPARE(hash, v.toHash());
}
void tst_QVariant::variantHash()
@@ -2633,29 +2610,21 @@ void tst_QVariant::variantHash()
QCOMPARE(hash2.value("test").toInt(), 42);
QCOMPARE(hash2, hash);
- QVariant v2 = QVariant(QMetaType::type("QVariantHash"), &hash);
+ QVariant v2 = QVariant(QMetaType::fromType<QVariantHash>(), &hash);
QCOMPARE(qvariant_cast<QVariantHash>(v2).value("test").toInt(), 42);
- QVariant v3 = QVariant(QMetaType::type("QHash<QString, QVariant>"), &hash);
+ QVariant v3 = QVariant(QMetaType::fromType<QHash<QString, QVariant>>(), &hash);
QCOMPARE(qvariant_cast<QVariantHash>(v3).value("test").toInt(), 42);
- QCOMPARE(v, QVariant(v.toMap()));
-
- // multi-keys
- hash.insertMulti("test", 47);
- v = hash;
- hash2 = qvariant_cast<QVariantHash>(v);
- QCOMPARE(hash2, hash);
- hash2 = v.toHash();
- QCOMPARE(hash2, hash);
-
- QCOMPARE(v, QVariant(v.toMap()));
+ QMap<QString, QVariant> map;
+ map["test"] = 42;
+ QCOMPARE(map, v.toMap());
}
class CustomQObject : public QObject {
Q_OBJECT
public:
- CustomQObject(QObject *parent = 0) : QObject(parent) {}
+ CustomQObject(QObject *parent = nullptr) : QObject(parent) {}
};
Q_DECLARE_METATYPE(CustomQObject*)
@@ -2676,7 +2645,7 @@ void tst_QVariant::qvariant_cast_QObject_data()
QTest::addColumn<bool>("isNull");
QObject *obj = new QObject;
obj->setObjectName(QString::fromLatin1("Hello"));
- QTest::newRow("from QObject") << QVariant(QMetaType::QObjectStar, &obj) << true << false;
+ QTest::newRow("from QObject") << QVariant(QMetaType::fromType<QObject*>(), &obj) << true << false;
QTest::newRow("from QObject2") << QVariant::fromValue(obj) << true << false;
QTest::newRow("from String") << QVariant(QLatin1String("1, 2, 3")) << false << false;
QTest::newRow("from int") << QVariant((int) 123) << false << false;
@@ -2706,39 +2675,37 @@ void tst_QVariant::qvariant_cast_QObject()
QFETCH(bool, isNull);
QObject *o = qvariant_cast<QObject *>(data);
- QCOMPARE(o != 0, success && !isNull);
+ QCOMPARE(o != nullptr, success && !isNull);
if (success) {
if (!isNull)
QCOMPARE(o->objectName(), QString::fromLatin1("Hello"));
QVERIFY(data.canConvert<QObject*>());
- QVERIFY(data.canConvert(QMetaType::QObjectStar));
- QVERIFY(data.canConvert(::qMetaTypeId<QObject*>()));
- QCOMPARE(data.value<QObject*>() == 0, isNull);
- QCOMPARE(data.isNull(), isNull);
- QVERIFY(data.convert(QMetaType::QObjectStar));
+ QVERIFY(data.canConvert(QMetaType::fromType<QObject*>()));
+ QVERIFY(data.canConvert(QMetaType(::qMetaTypeId<QObject*>())));
+ QCOMPARE(data.value<QObject*>() == nullptr, isNull);
+ QVERIFY(data.convert(QMetaType::fromType<QObject*>()));
QCOMPARE(data.userType(), int(QMetaType::QObjectStar));
} else {
QVERIFY(!data.canConvert<QObject*>());
- QVERIFY(!data.canConvert(QMetaType::QObjectStar));
- QVERIFY(!data.canConvert(::qMetaTypeId<QObject*>()));
- QCOMPARE(data.isNull(), isNull);
+ QVERIFY(!data.canConvert(QMetaType::fromType<QObject*>()));
+ QVERIFY(!data.canConvert(QMetaType(::qMetaTypeId<QObject*>())));
QVERIFY(!data.value<QObject*>());
- QVERIFY(!data.convert(QMetaType::QObjectStar));
QVERIFY(data.userType() != QMetaType::QObjectStar);
+ QVERIFY(!data.convert(QMetaType::fromType<QObject*>()));
}
}
class CustomQObjectDerived : public CustomQObject {
Q_OBJECT
public:
- CustomQObjectDerived(QObject *parent = 0) : CustomQObject(parent) {}
+ CustomQObjectDerived(QObject *parent = nullptr) : CustomQObject(parent) {}
};
Q_DECLARE_METATYPE(CustomQObjectDerived*)
class CustomQObjectDerivedNoMetaType : public CustomQObject {
Q_OBJECT
public:
- CustomQObjectDerivedNoMetaType(QObject *parent = 0) : CustomQObject(parent) {}
+ CustomQObjectDerivedNoMetaType(QObject *parent = nullptr) : CustomQObject(parent) {}
};
void tst_QVariant::qvariant_cast_QObject_derived()
@@ -2761,11 +2728,19 @@ void tst_QVariant::qvariant_cast_QObject_derived()
QCOMPARE(data.value<CustomQObjectDerived *>(), object);
QCOMPARE(data.value<CustomQObject *>(), object);
}
+ {
+ QObject *object = new CustomQObjectDerivedNoMetaType(this);
+ QVariant data = QVariant::fromValue(object);
+ QVERIFY(data.canConvert<CustomQObjectDerivedNoMetaType*>());
+ QVERIFY(data.convert(QMetaType(qMetaTypeId<CustomQObjectDerivedNoMetaType*>())));
+ QCOMPARE(data.value<CustomQObjectDerivedNoMetaType*>(), object);
+ QCOMPARE(data.isNull(), false);
+ }
}
struct QObjectWrapper
{
- explicit QObjectWrapper(QObject *o = 0) : obj(o) {}
+ explicit QObjectWrapper(QObject *o = nullptr) : obj(o) {}
QObject* getObject() const {
return obj;
@@ -2794,7 +2769,7 @@ class SmartPointer
T* pointer;
public:
typedef T element_type;
- explicit SmartPointer(T *t = 0)
+ explicit SmartPointer(T *t = nullptr)
: pointer(t)
{
}
@@ -2837,7 +2812,7 @@ void tst_QVariant::qvariant_cast_QObject_wrapper()
QObjectWrapper wrapper(object);
QVariant v = QVariant::fromValue(wrapper);
QCOMPARE(v.value<QObject*>(), object);
- v.convert(qMetaTypeId<QObject*>());
+ v.convert(QMetaType(qMetaTypeId<QObject*>()));
QCOMPARE(v.value<QObject*>(), object);
MyNS::SequentialContainer<int> sc;
@@ -2863,10 +2838,11 @@ void tst_QVariant::qvariant_cast_QObject_wrapper()
}
{
QFile *f = new QFile(this);
- QWeakPointer<QFile> sp(f);
- QVariant spVar = QVariant::fromValue(sp);
- QVERIFY(spVar.canConvert<QObject*>());
- QCOMPARE(f, spVar.value<QObject*>());
+ QSharedPointer<QObject> sp(f);
+ QWeakPointer<QObject> wp = sp;
+ QVariant wpVar = QVariant::fromValue(wp);
+ QVERIFY(wpVar.canConvert<QObject*>());
+ QCOMPARE(f, wpVar.value<QObject*>());
}
{
QFile *f = new QFile(this);
@@ -2939,6 +2915,17 @@ void tst_QVariant::qvariant_cast_QSharedPointerQObject()
qRegisterMetaType<QSharedPointer<QObject> >();
}
+void tst_QVariant::qvariant_cast_const()
+{
+ int i = 42;
+ QVariant v = QVariant::fromValue(&i);
+ QVariant vConst = QVariant::fromValue(const_cast<const int*>(&i));
+ QCOMPARE(v.value<int *>(), &i);
+ QCOMPARE(v.value<const int *>(), &i);
+ QCOMPARE(vConst.value<int *>(), nullptr);
+ QCOMPARE(vConst.value<const int *>(), &i);
+}
+
void tst_QVariant::convertToQUint8() const
{
/* qint8. */
@@ -2996,18 +2983,289 @@ void tst_QVariant::convertToQUint8() const
}
}
-void tst_QVariant::comparePointers() const
+void tst_QVariant::compareCompiles() const
{
- class MyClass
- {
+ QTestPrivate::testEqualityOperatorsCompile<QVariant>();
+}
+
+void tst_QVariant::compareNumerics_data() const
+{
+ QTest::addColumn<QVariant>("v1");
+ QTest::addColumn<QVariant>("v2");
+ QTest::addColumn<QPartialOrdering>("result");
+
+ QTest::addRow("invalid-invalid")
+ << QVariant() << QVariant() << QPartialOrdering::Unordered;
+
+ static const auto asString = [](const QVariant &v) {
+ if (v.isNull())
+ return QStringLiteral("null");
+ if (v.metaType().flags() & QMetaType::IsEnumeration)
+ return v.metaType().flags() & QMetaType::IsUnsignedEnumeration ?
+ QString::number(v.toULongLong()) :
+ QString::number(v.toLongLong());
+ switch (v.typeId()) {
+ case QMetaType::Char16:
+ return QString::number(qvariant_cast<char16_t>(v));
+ case QMetaType::Char32:
+ return QString::number(qvariant_cast<char32_t>(v));
+ case QMetaType::Char:
+ case QMetaType::UChar:
+ return QString::number(v.toUInt());
+ case QMetaType::SChar:
+ return QString::number(v.toInt());
+ }
+ return v.toString();
+ };
+
+ auto addCompareToInvalid = [](auto value) {
+ QVariant v = QVariant::fromValue(value);
+ QTest::addRow("invalid-%s(%s)", v.typeName(), qPrintable(asString(v)))
+ << QVariant() << v << QPartialOrdering::Unordered;
+ QTest::addRow("%s(%s)-invalid", v.typeName(), qPrintable(asString(v)))
+ << v << QVariant() << QPartialOrdering::Unordered;
+ };
+ addCompareToInvalid(false);
+ addCompareToInvalid(true);
+ addCompareToInvalid(char(0));
+ addCompareToInvalid(qint8(0));
+ addCompareToInvalid(quint8(0));
+ addCompareToInvalid(short(0));
+ addCompareToInvalid(ushort(0));
+ addCompareToInvalid(int(0));
+ addCompareToInvalid(uint(0));
+ addCompareToInvalid(long(0));
+ addCompareToInvalid(ulong(0));
+ addCompareToInvalid(qint64(0));
+ addCompareToInvalid(quint64(0));
+ addCompareToInvalid(0.f);
+ addCompareToInvalid(0.0);
+ addCompareToInvalid(QCborSimpleType{});
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wsign-compare")
+QT_WARNING_DISABLE_GCC("-Wsign-compare")
+QT_WARNING_DISABLE_MSVC(4018) // '<': signed/unsigned mismatch
+ static const auto addComparePairWithResult = [](auto value1, auto value2, QPartialOrdering order) {
+ QVariant v1 = QVariant::fromValue(value1);
+ QVariant v2 = QVariant::fromValue(value2);
+ QTest::addRow("%s(%s)-%s(%s)", v1.typeName(), qPrintable(asString(v1)),
+ v2.typeName(), qPrintable(asString(v2)))
+ << v1 << v2 << order;
+ };
+
+ static const auto addComparePair = [](auto value1, auto value2) {
+ QPartialOrdering order = QPartialOrdering::Unordered;
+ if (value1 == value2)
+ order = QPartialOrdering::Equivalent;
+ else if (value1 < value2)
+ order = QPartialOrdering::Less;
+ else if (value1 > value2)
+ order = QPartialOrdering::Greater;
+ addComparePairWithResult(value1, value2, order);
+ };
+QT_WARNING_POP
+
+ // homogeneous first
+ static const auto addList = [](auto list) {
+ for (auto v1 : list)
+ for (auto v2 : list)
+ addComparePair(v1, v2);
};
- MyClass myClass;
+ auto addSingleType = [](auto zero) {
+ using T = decltype(zero);
+ T one = T(zero + 1);
+ T min = std::numeric_limits<T>::min();
+ T max = std::numeric_limits<T>::max();
+ T mid = max / 2 + 1;
+ if (min != zero)
+ addList(std::array{zero, one, min, mid, max});
+ else
+ addList(std::array{zero, one, mid, max});
+ };
+ addList(std::array{ false, true });
+ addList(std::array{ QCborSimpleType{}, QCborSimpleType::False, QCborSimpleType(0xff) });
+ addSingleType(char(0));
+ addSingleType(char16_t(0));
+ addSingleType(char32_t(0));
+ addSingleType(qint8(0));
+ addSingleType(quint8(0));
+ addSingleType(qint16(0));
+ addSingleType(quint16(0));
+ addSingleType(qint32(0));
+ addSingleType(quint32(0));
+ addSingleType(qint64(0));
+ addSingleType(quint64(0));
+ addSingleType(0.f);
+ addSingleType(0.0);
+ addList(std::array{ EnumTest_Enum0{}, EnumTest_Enum0_value, EnumTest_Enum0_negValue });
+ addList(std::array{ EnumTest_Enum1{}, EnumTest_Enum1_value, EnumTest_Enum1_bigValue });
+ addList(std::array{ EnumTest_Enum7{}, EnumTest_Enum7::EnumTest_Enum7_value, EnumTest_Enum7::ensureSignedEnum7 });
+ addList(std::array{ Qt::AlignRight|Qt::AlignHCenter, Qt::AlignCenter|Qt::AlignVCenter });
+
+ // heterogeneous
+ addComparePair(char(0), qint8(-127));
+ addComparePair(char(127), qint8(127));
+ addComparePair(char(127), quint8(127));
+ addComparePair(qint8(-1), quint8(255));
+ addComparePair(char16_t(256), qint8(-1));
+ addComparePair(char16_t(256), short(-1));
+ addComparePair(char16_t(256), int(-1));
+ addComparePair(char32_t(256), int(-1));
+ addComparePair(0U, -1);
+ addComparePair(~0U, -1);
+ addComparePair(Q_UINT64_C(0), -1);
+ addComparePair(~Q_UINT64_C(0), -1);
+ addComparePair(Q_UINT64_C(0), Q_INT64_C(-1));
+ addComparePair(~Q_UINT64_C(0), Q_INT64_C(-1));
+ addComparePair(INT_MAX, uint(INT_MAX));
+ addComparePair(INT_MAX, qint64(INT_MAX) + 1);
+ addComparePair(INT_MAX, UINT_MAX);
+ addComparePair(INT_MAX, qint64(UINT_MAX));
+ addComparePair(INT_MAX, qint64(UINT_MAX) + 1);
+ addComparePair(INT_MAX, quint64(UINT_MAX));
+ addComparePair(INT_MAX, quint64(UINT_MAX) + 1);
+ addComparePair(INT_MAX, LONG_MIN);
+ addComparePair(INT_MAX, LONG_MAX);
+ addComparePair(INT_MAX, LLONG_MIN);
+ addComparePair(INT_MAX, LLONG_MAX);
+ addComparePair(INT_MIN, uint(INT_MIN));
+ addComparePair(INT_MIN, uint(INT_MIN) + 1);
+ addComparePair(INT_MIN + 1, uint(INT_MIN));
+ addComparePair(INT_MIN + 1, uint(INT_MIN) + 1);
+ addComparePair(INT_MIN, qint64(INT_MIN) - 1);
+ addComparePair(INT_MIN + 1, qint64(INT_MIN) + 1);
+ addComparePair(INT_MIN + 1, qint64(INT_MIN) - 1);
+ addComparePair(INT_MIN, UINT_MAX);
+ addComparePair(INT_MIN, qint64(UINT_MAX));
+ addComparePair(INT_MIN, qint64(UINT_MAX) + 1);
+ addComparePair(INT_MIN, quint64(UINT_MAX));
+ addComparePair(INT_MIN, quint64(UINT_MAX) + 1);
+ addComparePair(UINT_MAX, qint64(UINT_MAX) + 1);
+ addComparePair(UINT_MAX, quint64(UINT_MAX) + 1);
+ addComparePair(UINT_MAX, qint64(INT_MIN) - 1);
+ addComparePair(UINT_MAX, quint64(INT_MIN) + 1);
+ addComparePair(LLONG_MAX, quint64(LLONG_MAX));
+ addComparePair(LLONG_MAX, quint64(LLONG_MAX) + 1);
+ addComparePair(LLONG_MIN, quint64(LLONG_MAX));
+ addComparePair(LLONG_MIN, quint64(LLONG_MAX) + 1);
+ addComparePair(LLONG_MIN, quint64(LLONG_MIN) + 1);
+ addComparePair(LLONG_MIN + 1, quint64(LLONG_MIN) + 1);
+ addComparePair(LLONG_MIN, LLONG_MAX - 1);
+ // addComparePair(LLONG_MIN, LLONG_MAX); // already added by addSingleType()
+
+ // floating point
+ addComparePair(0.f, 0);
+ addComparePair(0.f, 0U);
+ addComparePair(0.f, Q_INT64_C(0));
+ addComparePair(0.f, Q_UINT64_C(0));
+ addComparePair(0.f, 0.);
+ addComparePair(0.f, 1.);
+ addComparePair(float(1 << 24), 1 << 24);
+ addComparePair(float(1 << 24) - 1, (1 << 24) - 1);
+ addComparePair(-float(1 << 24), 1 << 24);
+ addComparePair(-float(1 << 24) + 1, -(1 << 24) + 1);
+ addComparePair(HUGE_VALF, qInf());
+ addComparePair(HUGE_VALF, -qInf());
+ addComparePair(qQNaN(), std::numeric_limits<float>::quiet_NaN());
+ if (sizeof(qreal) == sizeof(double)) {
+ addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::min());
+ addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::max());
+ addComparePair(std::numeric_limits<float>::max(), std::numeric_limits<double>::min());
+ addComparePair(std::numeric_limits<float>::max(), std::numeric_limits<double>::max());
+ addComparePair(double(Q_INT64_C(1) << 53), Q_INT64_C(1) << 53);
+ addComparePair(double(Q_INT64_C(1) << 53) - 1, (Q_INT64_C(1) << 53) - 1);
+ addComparePair(-double(Q_INT64_C(1) << 53), Q_INT64_C(1) << 53);
+ addComparePair(-double(Q_INT64_C(1) << 53) + 1, (Q_INT64_C(1) << 53) + 1);
+ }
+
+ // enums vs integers
+ addComparePair(EnumTest_Enum0_value, 0);
+ addComparePair(EnumTest_Enum0_value, 0U);
+ addComparePair(EnumTest_Enum0_value, 0LL);
+ addComparePair(EnumTest_Enum0_value, 0ULL);
+ addComparePair(EnumTest_Enum0_value, int(EnumTest_Enum0_value));
+ addComparePair(EnumTest_Enum0_value, qint64(EnumTest_Enum0_value));
+ addComparePair(EnumTest_Enum0_value, quint64(EnumTest_Enum0_value));
+ addComparePair(EnumTest_Enum0_negValue, int(EnumTest_Enum0_value));
+ addComparePair(EnumTest_Enum0_negValue, qint64(EnumTest_Enum0_value));
+ addComparePair(EnumTest_Enum0_negValue, quint64(EnumTest_Enum0_value));
+ addComparePair(EnumTest_Enum0_negValue, int(EnumTest_Enum0_negValue));
+ addComparePair(EnumTest_Enum0_negValue, qint64(EnumTest_Enum0_negValue));
+ addComparePair(EnumTest_Enum0_negValue, quint64(EnumTest_Enum0_negValue));
+
+ addComparePair(EnumTest_Enum1_value, 0);
+ addComparePair(EnumTest_Enum1_value, 0U);
+ addComparePair(EnumTest_Enum1_value, 0LL);
+ addComparePair(EnumTest_Enum1_value, 0ULL);
+ addComparePair(EnumTest_Enum1_value, int(EnumTest_Enum1_value));
+ addComparePair(EnumTest_Enum1_value, qint64(EnumTest_Enum1_value));
+ addComparePair(EnumTest_Enum1_value, quint64(EnumTest_Enum1_value));
+ addComparePair(EnumTest_Enum1_bigValue, int(EnumTest_Enum1_value));
+ addComparePair(EnumTest_Enum1_bigValue, qint64(EnumTest_Enum1_value));
+ addComparePair(EnumTest_Enum1_bigValue, quint64(EnumTest_Enum1_value));
+ addComparePair(EnumTest_Enum1_bigValue, int(EnumTest_Enum1_bigValue));
+ addComparePair(EnumTest_Enum1_bigValue, qint64(EnumTest_Enum1_bigValue));
+ addComparePair(EnumTest_Enum1_bigValue, quint64(EnumTest_Enum1_bigValue));
+
+ addComparePair(EnumTest_Enum3_value, 0);
+ addComparePair(EnumTest_Enum3_value, 0U);
+ addComparePair(EnumTest_Enum3_value, 0LL);
+ addComparePair(EnumTest_Enum3_value, 0ULL);
+ addComparePair(EnumTest_Enum3_value, int(EnumTest_Enum3_value));
+ addComparePair(EnumTest_Enum3_value, qint64(EnumTest_Enum3_value));
+ addComparePair(EnumTest_Enum3_value, quint64(EnumTest_Enum3_value));
+ addComparePair(EnumTest_Enum3_bigValue, int(EnumTest_Enum3_value));
+ addComparePair(EnumTest_Enum3_bigValue, qint64(EnumTest_Enum3_value));
+ addComparePair(EnumTest_Enum3_bigValue, quint64(EnumTest_Enum3_value));
+ addComparePair(EnumTest_Enum3_bigValue, int(EnumTest_Enum3_bigValue));
+ addComparePair(EnumTest_Enum3_bigValue, qint64(EnumTest_Enum3_bigValue));
+ addComparePair(EnumTest_Enum3_bigValue, quint64(EnumTest_Enum3_bigValue));
+
+ // enums of different types always compare as unordered
+ addComparePairWithResult(EnumTest_Enum0_value, EnumTest_Enum1_value, QPartialOrdering::Unordered);
+}
+
+void tst_QVariant::compareNumerics() const
+{
+ QFETCH(QVariant, v1);
+ QFETCH(QVariant, v2);
+ QFETCH(QPartialOrdering, result);
+ QCOMPARE(QVariant::compare(v1, v2), result);
+
+ QEXPECT_FAIL("invalid-invalid", "needs fixing", Abort);
+ QT_TEST_EQUALITY_OPS(v1, v2, is_eq(result));
+}
+
+void tst_QVariant::comparePointers() const
+{
+ class NonQObjectClass {};
+ const std::array<NonQObjectClass, 2> arr{ NonQObjectClass{}, NonQObjectClass{} };
+
+ const QVariant nonObjV1 = QVariant::fromValue<const void*>(&arr[0]);
+ const QVariant nonObjV2 = QVariant::fromValue<const void*>(&arr[1]);
+
+ Qt::partial_ordering expectedOrdering = Qt::partial_ordering::equivalent;
+ QCOMPARE(QVariant::compare(nonObjV1, nonObjV1), expectedOrdering);
+ QT_TEST_EQUALITY_OPS(nonObjV1, nonObjV1, is_eq(expectedOrdering));
+
+ expectedOrdering = Qt::partial_ordering::less;
+ QCOMPARE(QVariant::compare(nonObjV1, nonObjV2), expectedOrdering);
+ QT_TEST_EQUALITY_OPS(nonObjV1, nonObjV2, is_eq(expectedOrdering));
- QVariant v = QVariant::fromValue<void *>(&myClass);
- QVariant v2 = QVariant::fromValue<void *>(&myClass);
+ class QObjectClass : public QObject
+ {
+ public:
+ QObjectClass(QObject *parent = nullptr) : QObject(parent) {}
+ };
+ const QObjectClass c1;
+ const QObjectClass c2;
- QCOMPARE(v, v2);
+ const QVariant objV1 = QVariant::fromValue(&c1);
+ const QVariant objV2 = QVariant::fromValue(&c2);
+ QT_TEST_EQUALITY_OPS(objV1, objV1, true);
+ QT_TEST_EQUALITY_OPS(objV1, objV2, false);
}
struct Data {};
@@ -3027,7 +3285,7 @@ void tst_QVariant::voidStar() const
v2 = QVariant::fromValue(p2);
QCOMPARE(v1, v2);
- p2 = 0;
+ p2 = nullptr;
v2 = QVariant::fromValue(p2);
QVERIFY(v1 != v2);
}
@@ -3057,7 +3315,7 @@ void tst_QVariant::canConvertQStringList() const
QVariant v(input);
- QCOMPARE(v.canConvert(QVariant::String), canConvert);
+ QCOMPARE(v.canConvert<QString>(), canConvert);
QCOMPARE(v.toString(), result);
}
@@ -3067,23 +3325,23 @@ void tst_QVariant::canConvertQStringList_data() const
QTest::addColumn<QStringList>("input");
QTest::addColumn<QString>("result");
- QTest::newRow("An empty list") << false << QStringList() << QString();
+ QTest::newRow("An empty list") << true << QStringList() << QString();
QTest::newRow("A single item") << true << QStringList(QLatin1String("foo")) << QString::fromLatin1("foo");
QTest::newRow("A single, but empty item") << true << QStringList(QString()) << QString();
QStringList l;
l << "a" << "b";
- QTest::newRow("Two items") << false << l << QString();
+ QTest::newRow("Two items") << true << l << QString();
l << "c";
- QTest::newRow("Three items") << false << l << QString();
+ QTest::newRow("Three items") << true << l << QString();
}
template<typename T> void convertMetaType()
{
QVERIFY(QVariant::fromValue<T>(10).isValid());
- QVERIFY(QVariant::fromValue<T>(10).canConvert(QVariant::Int));
+ QVERIFY(QVariant::fromValue<T>(10).template canConvert<int>());
QCOMPARE(QVariant::fromValue<T>(10).toInt(), 10);
QCOMPARE(QVariant::fromValue<T>(10), QVariant::fromValue<T>(10));
}
@@ -3124,7 +3382,7 @@ void tst_QVariant::variantToDateTimeWithoutWarnings() const
{
QVariant v1(QLatin1String("xyz"));
- v1.convert(QVariant::DateTime);
+ v1.convert(QMetaType::fromType<QDateTime>());
QVariant v2(QLatin1String("xyz"));
QDateTime dt1(v2.toDateTime());
@@ -3138,7 +3396,7 @@ void tst_QVariant::invalidDateTime() const
{
QVariant variant(QString::fromLatin1("Invalid date time string"));
QVERIFY(!variant.toDateTime().isValid());
- QVERIFY(!variant.convert(QVariant::DateTime));
+ QVERIFY(!variant.convert(QMetaType::fromType<QDateTime>()));
}
struct MyClass
@@ -3154,7 +3412,7 @@ void tst_QVariant::loadUnknownUserType()
qRegisterMetaType<MyClass>("MyClass");
QTest::ignoreMessage(QtWarningMsg, "QVariant::load: unable to load type "
+ QByteArray::number(qMetaTypeId<MyClass>()) +".");
- char data[] = {0, 0, QMetaType::User >> 8 , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0};
+ char data[] = {0, QMetaType::User >> 16, char(QMetaType::User >> 8) , char(QMetaType::User), 0, 0, 0, 0, 8, 'M', 'y', 'C', 'l', 'a', 's', 's', 0};
QByteArray ba(data, sizeof(data));
QDataStream ds(&ba, QIODevice::ReadOnly);
@@ -3165,7 +3423,7 @@ void tst_QVariant::loadUnknownUserType()
void tst_QVariant::loadBrokenUserType()
{
- QTest::ignoreMessage(QtWarningMsg, "Trying to construct an instance of an invalid type, type id: 127");
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Trying to construct an instance of an invalid type"));
char data[] = {0, 0, 0, 127, 0 };
QByteArray ba(data, sizeof(data));
@@ -3179,52 +3437,81 @@ void tst_QVariant::invalidDate() const
{
QString foo("Hello");
QVariant variant(foo);
- QVERIFY(!variant.convert(QVariant::Date));
+ QVERIFY(!variant.convert(QMetaType::fromType<QDate>()));
variant = foo;
- QVERIFY(!variant.convert(QVariant::DateTime));
+ QVERIFY(!variant.convert(QMetaType::fromType<QDateTime>()));
variant = foo;
- QVERIFY(!variant.convert(QVariant::Time));
+ QVERIFY(!variant.convert(QMetaType::fromType<QTime>()));
variant = foo;
- QVERIFY(!variant.convert(QVariant::Int));
+ QVERIFY(!variant.convert(QMetaType::fromType<int>()));
variant = foo;
- QVERIFY(!variant.convert(QVariant::Double));
+ QVERIFY(!variant.convert(QMetaType::fromType<double>()));
variant = foo;
- QVERIFY(!variant.convert(QVariant::Type(QMetaType::Float)));
+ QVERIFY(!variant.convert(QMetaType::fromType<float>()));
}
struct WontCompare
{
- int x,y,z,q,w,e,r,t;
+ int x;
};
Q_DECLARE_METATYPE(WontCompare);
-void tst_QVariant::compareCustomTypes() const
+struct WillCompare
{
- qRegisterMetaType<WontCompare>("WontCompare");
+ int x;
- WontCompare f1;
- f1.x = 0;
- const QVariant variant1(QVariant::fromValue(f1));
+ friend bool operator==(const WillCompare &a, const WillCompare &b)
+ { return a.x == b.x; }
+ friend bool operator<(const WillCompare &a, const WillCompare &b)
+ { return a.x < b.x; }
+};
+Q_DECLARE_METATYPE(WillCompare);
- WontCompare f2;
- f2.x = 0;
- const QVariant variant2(QVariant::fromValue(f2));
+void tst_QVariant::compareCustomTypes_data() const
+{
+ QTest::addColumn<QVariant>("v1");
+ QTest::addColumn<QVariant>("v2");
+ QTest::addColumn<Qt::partial_ordering>("expectedOrdering");
- /* We compare pointers. */
- QVERIFY(variant1 != variant2);
- QCOMPARE(variant1, variant1);
- QCOMPARE(variant2, variant2);
+ QTest::newRow("same_uncomparable")
+ << QVariant::fromValue(WontCompare{0})
+ << QVariant::fromValue(WontCompare{0})
+ << Qt::partial_ordering::unordered;
+
+ QTest::newRow("same_comparable")
+ << QVariant::fromValue(WillCompare{0})
+ << QVariant::fromValue(WillCompare{0})
+ << Qt::partial_ordering::equivalent;
+
+ QTest::newRow("different_comparable")
+ << QVariant::fromValue(WillCompare{1})
+ << QVariant::fromValue(WillCompare{0})
+ << Qt::partial_ordering::greater;
+
+ QTest::newRow("qdatetime_vs_comparable")
+ << QVariant::fromValue(QDateTime::currentDateTimeUtc())
+ << QVariant::fromValue(WillCompare{0})
+ << Qt::partial_ordering::unordered;
}
+void tst_QVariant::compareCustomTypes() const
+{
+ QFETCH(const QVariant, v1);
+ QFETCH(const QVariant, v2);
+ QFETCH(const Qt::partial_ordering, expectedOrdering);
+
+ QCOMPARE(QVariant::compare(v1, v2), expectedOrdering);
+ QT_TEST_EQUALITY_OPS(v1, v2, is_eq(expectedOrdering));
+}
void tst_QVariant::timeToDateTime() const
{
const QVariant val(QTime::currentTime());
- QVERIFY(!val.canConvert(QVariant::DateTime));
+ QVERIFY(!val.canConvert<QDateTime>());
QVERIFY(!val.toDateTime().isValid());
}
@@ -3252,6 +3539,43 @@ void tst_QVariant::copyingUserTypes() const
QCOMPARE(copiedType.myValue, 42);
}
+
+struct NonQObjectBase {};
+struct NonQObjectDerived : NonQObjectBase {};
+
+void tst_QVariant::valueClassHierarchyConversion() const
+{
+
+ {
+ // QVariant allows downcasting
+ QScopedPointer<CustomQObjectDerived> derived {new CustomQObjectDerived};
+ QVariant var = QVariant::fromValue(derived.get());
+ CustomQObject *object = var.value<CustomQObject *>();
+ QVERIFY(object);
+ }
+ {
+ // QVariant supports upcasting to the correct dynamic type for QObjects
+ QScopedPointer<CustomQObjectDerived> derived {new CustomQObjectDerived};
+ QVariant var = QVariant::fromValue<CustomQObject *>(derived.get());
+ CustomQObjectDerived *object = var.value<CustomQObjectDerived *>();
+ QVERIFY(object);
+ }
+ {
+ // QVariant forbids unsafe upcasting
+ QScopedPointer<CustomQObject> base {new CustomQObject};
+ QVariant var = QVariant::fromValue(base.get());
+ CustomQObjectDerived *object = var.value<CustomQObjectDerived *>();
+ QVERIFY(!object);
+ }
+ {
+ // QVariant does not support upcastingfor non-QObjects
+ QScopedPointer<NonQObjectDerived> derived {new NonQObjectDerived};
+ QVariant var = QVariant::fromValue<NonQObjectBase *>(derived.get());
+ NonQObjectDerived *object = var.value<NonQObjectDerived *>();
+ QVERIFY(!object);
+ }
+}
+
void tst_QVariant::convertBoolToByteArray() const
{
QFETCH(QByteArray, input);
@@ -3326,7 +3650,7 @@ void tst_QVariant::convertByteArrayToBool() const
QFETCH(QByteArray, output);
const QVariant variant(input);
- QCOMPARE(variant.type(), QVariant::Bool);
+ QCOMPARE(variant.typeId(), QMetaType::Bool);
QCOMPARE(variant.toBool(), input);
QVERIFY(variant.canConvert<bool>());
@@ -3352,60 +3676,88 @@ void tst_QVariant::convertIterables() const
{
QStringList list;
list.append("Hello");
- QCOMPARE(QVariant::fromValue(list).value<QVariantList>().count(), list.count());
+ QCOMPARE(QVariant::fromValue(list).value<QVariantList>().size(), list.size());
}
{
QByteArrayList list;
list.append("Hello");
- QCOMPARE(QVariant::fromValue(list).value<QVariantList>().count(), list.count());
+ QCOMPARE(QVariant::fromValue(list).value<QVariantList>().size(), list.size());
}
{
QVariantList list;
list.append("World");
- QCOMPARE(QVariant::fromValue(list).value<QVariantList>().count(), list.count());
+ QCOMPARE(QVariant::fromValue(list).value<QVariantList>().size(), list.size());
}
{
QMap<QString, int> map;
map.insert("3", 4);
- QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count());
- QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count());
+ QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().size(), map.size());
+ QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().size(), map.size());
- map.insertMulti("3", 5);
- QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count());
- QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count());
+ map.insert("4", 5);
+ QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().size(), map.size());
+ QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().size(), map.size());
}
{
QVariantMap map;
map.insert("3", 4);
- QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count());
- QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count());
+ QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().size(), map.size());
+ QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().size(), map.size());
- map.insertMulti("3", 5);
- QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().count(), map.count());
- QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().count(), map.count());
+ map.insert("4", 5);
+ QCOMPARE(QVariant::fromValue(map).value<QVariantHash>().size(), map.size());
+ QCOMPARE(QVariant::fromValue(map).value<QVariantMap>().size(), map.size());
}
{
QHash<QString, int> hash;
hash.insert("3", 4);
- QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count());
- QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count());
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().size(), hash.size());
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().size(), hash.size());
- hash.insertMulti("3", 5);
- QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count());
- QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count());
+ hash.insert("4", 5);
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().size(), hash.size());
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().size(), hash.size());
}
{
QVariantHash hash;
hash.insert("3", 4);
- QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count());
- QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count());
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().size(), hash.size());
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().size(), hash.size());
- hash.insertMulti("3", 5);
- QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().count(), hash.count());
- QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().count(), hash.count());
+ hash.insert("4", 5);
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantHash>().size(), hash.size());
+ QCOMPARE(QVariant::fromValue(hash).value<QVariantMap>().size(), hash.size());
}
}
+struct Derived : QObject
+{
+ Q_OBJECT
+};
+
+void tst_QVariant::convertConstNonConst() const
+{
+ Derived *derived = new Derived;
+ QObject *obj = derived;
+ QObject const *unrelatedConstObj = new QObject;
+ auto cleanUp = qScopeGuard([&] {
+ delete unrelatedConstObj;
+ delete derived;
+ });
+ QObject const *constObj = obj;
+ Derived const *constDerived = derived;
+ QCOMPARE(QVariant::fromValue(constObj).value<QObject *>(), obj);
+ QCOMPARE(QVariant::fromValue(obj).value<QObject const *>(), constObj);
+
+ QCOMPARE(QVariant::fromValue(constDerived).value<QObject *>(), derived);
+ QCOMPARE(QVariant::fromValue(derived).value<QObject const *>(), derived);
+
+ QObject const *derivedAsConstObject = derived;
+ // up cast and remove const is possible, albeit dangerous
+ QCOMPARE(QVariant::fromValue(derivedAsConstObject).value<Derived *>(), derived);
+ QCOMPARE(QVariant::fromValue(unrelatedConstObj).value<Derived *>(), nullptr);
+}
+
/*!
We verify that:
1. Converting the string "9.9" to int fails. This is the behavior of
@@ -3444,7 +3796,7 @@ void tst_QVariant::toIntFromDouble() const
QCOMPARE((int)d, 2147483630);
QVariant var(d);
- QVERIFY( var.canConvert( QVariant::Int ) );
+ QVERIFY(var.canConvert<int>());
bool ok;
int result = var.toInt(&ok);
@@ -3466,13 +3818,13 @@ void tst_QVariant::fpStringRoundtrip() const
QFETCH(QVariant, number);
QVariant converted = number;
- QVERIFY(converted.convert(QVariant::String));
- QVERIFY(converted.convert(number.type()));
+ QVERIFY(converted.convert(QMetaType::fromType<QString>()));
+ QVERIFY(converted.convert(QMetaType(number.typeId())));
QCOMPARE(converted, number);
converted = number;
- QVERIFY(converted.convert(QVariant::ByteArray));
- QVERIFY(converted.convert(number.type()));
+ QVERIFY(converted.convert(QMetaType::fromType<QByteArray>()));
+ QVERIFY(converted.convert(QMetaType(number.typeId())));
QCOMPARE(converted, number);
}
@@ -3510,7 +3862,7 @@ void tst_QVariant::numericalConvert()
}
switch (v.userType())
{
- case QVariant::Double:
+ case QMetaType::Double:
QCOMPARE(v.toString() , QString::number(num, 'g', QLocale::FloatingPointShortest));
break;
case QMetaType::Float:
@@ -3533,7 +3885,7 @@ template<class T> void playWithVariant(const T &orig, bool isNull, const QString
{
QVariant v2 = v;
- if (!(QTypeInfo<T>::isStatic && QTypeInfo<T>::isComplex)) {
+ if (QTypeInfo<T>::isRelocatable) {
// Type is movable so standard comparison algorithm in QVariant should work
// In a custom type QVariant is not aware of ==operator so it won't be called,
// which may cause problems especially visible when using a not-movable type
@@ -3550,7 +3902,7 @@ template<class T> void playWithVariant(const T &orig, bool isNull, const QString
v = QVariant();
QCOMPARE(v3, v);
v = v2;
- if (!(QTypeInfo<T>::isStatic && QTypeInfo<T>::isComplex)) {
+ if (QTypeInfo<T>::isRelocatable) {
// Type is movable so standard comparison algorithm in QVariant should work
// In a custom type QVariant is not aware of ==operator so it won't be called,
// which may cause problems especially visible when using a not-movable type
@@ -3575,10 +3927,8 @@ template<class T> void playWithVariant(const T &orig, bool isNull, const QString
QCOMPARE(v.toBool(), toBool);
QCOMPARE(qvariant_cast<T>(v), orig);
- if (qMetaTypeId<T>() != qMetaTypeId<QVariant>()) {
+ if (qMetaTypeId<T>() != qMetaTypeId<QVariant>())
QCOMPARE(v.userType(), qMetaTypeId<T>());
- QCOMPARE(QVariant::typeToName(QVariant::Type(v.userType())), QMetaType::typeName(qMetaTypeId<T>()));
- }
}
#define PLAY_WITH_VARIANT(Orig, IsNull, ToString, ToDouble, ToBool) \
@@ -3632,6 +3982,7 @@ struct MyMovable
MyMovable() { v = count++; }
~MyMovable() { count--; }
MyMovable(const MyMovable &o) : v(o.v) { count++; }
+ MyMovable &operator=(const MyMovable &o) { v = o.v; return *this; }
bool operator==(const MyMovable &o) const
{
@@ -3662,6 +4013,8 @@ struct MyNotMovable
if (!ok) qFatal("MyNotMovable has been moved");
return ok;
}
+ // Make it too big to store it in the variant itself
+ void *dummy[4];
};
int MyNotMovable::count = 0;
@@ -3671,7 +4024,7 @@ struct MyShared : QSharedData {
};
QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(MyMovable, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
Q_DECLARE_METATYPE(MyPrimitive)
@@ -3710,7 +4063,7 @@ void tst_QVariant::moreCustomTypes()
{
QString str;
- PLAY_WITH_VARIANT(str, true, QString(), 0, false);
+ PLAY_WITH_VARIANT(str, false, QString(), 0, false);
str = QString::fromLatin1("123456789.123");
PLAY_WITH_VARIANT(str, false, str, 123456789.123, true);
}
@@ -3776,17 +4129,12 @@ void tst_QVariant::moreCustomTypes()
// Float is converted to double, adding insignificant bits
PLAY_WITH_VARIANT(12.12f, false, "12.119999885559082", 12.12f, true);
- PLAY_WITH_VARIANT('a', false, "a", 'a', true);
- PLAY_WITH_VARIANT((unsigned char)('a'), false, "a", 'a', true);
- PLAY_WITH_VARIANT( quint8(12), false, "\xc", 12, true);
- PLAY_WITH_VARIANT( qint8(13), false, "\xd", 13, true);
PLAY_WITH_VARIANT(quint16(14), false, "14", 14, true);
PLAY_WITH_VARIANT( qint16(15), false, "15", 15, true);
PLAY_WITH_VARIANT(quint32(16), false, "16", 16, true);
PLAY_WITH_VARIANT( qint32(17), false, "17", 17, true);
PLAY_WITH_VARIANT(quint64(18), false, "18", 18, true);
PLAY_WITH_VARIANT( qint64(19), false, "19", 19, true);
- PLAY_WITH_VARIANT( qint8(-12), false, QLatin1String("\xf4"), -12, true); // qint8 is char, so it gets converted via QChar
PLAY_WITH_VARIANT( qint16(-13), false, "-13", -13, true);
PLAY_WITH_VARIANT( qint32(-14), false, "-14", -14, true);
PLAY_WITH_VARIANT( qint64(-15), false, "-15", -15, true);
@@ -3834,9 +4182,9 @@ void tst_QVariant::moreCustomTypes()
}
{
- QList<QVector<int> > data;
+ QList<QList<int> > data;
PLAY_WITH_VARIANT(data, false, QString(), 0, false);
- data << (QVector<int>() << 42);
+ data << (QList<int>() << 42);
PLAY_WITH_VARIANT(data, false, QString(), 0, false);
}
@@ -3846,13 +4194,6 @@ void tst_QVariant::moreCustomTypes()
data << (QSet<int>() << 42);
PLAY_WITH_VARIANT(data, false, QString(), 0, false);
}
-
- {
- QList<QLinkedList<int> > data;
- PLAY_WITH_VARIANT(data, false, QString(), 0, false);
- data << (QLinkedList<int>() << 42);
- PLAY_WITH_VARIANT(data, false, QString(), 0, false);
- }
}
void tst_QVariant::movabilityTest()
@@ -3865,11 +4206,11 @@ void tst_QVariant::movabilityTest()
// prepare destination memory space to which variant will be moved
QVariant buffer[1];
- QCOMPARE(buffer[0].type(), QVariant::Invalid);
+ QCOMPARE(buffer[0].typeId(), QMetaType::UnknownType);
buffer[0].~QVariant();
- memcpy(buffer, &variant, sizeof(QVariant));
- QCOMPARE(buffer[0].type(), QVariant::UserType);
+ memcpy(static_cast<void *>(buffer), static_cast<void *>(&variant), sizeof(QVariant));
+ QVERIFY(buffer[0].typeId() > QMetaType::User);
QCOMPARE(buffer[0].userType(), qMetaTypeId<MyNotMovable>());
MyNotMovable tmp(buffer[0].value<MyNotMovable>());
@@ -3881,24 +4222,24 @@ void tst_QVariant::movabilityTest()
void tst_QVariant::variantInVariant()
{
QVariant var1 = 5;
- QCOMPARE(var1.type(), QVariant::Int);
+ QCOMPARE(var1.typeId(), QMetaType::Int);
QVariant var2 = var1;
QCOMPARE(var2, var1);
- QCOMPARE(var2.type(), QVariant::Int);
+ QCOMPARE(var2.typeId(), QMetaType::Int);
QVariant var3 = QVariant::fromValue(var1);
QCOMPARE(var3, var1);
- QCOMPARE(var3.type(), QVariant::Int);
+ QCOMPARE(var3.typeId(), QMetaType::Int);
QVariant var4 = qvariant_cast<QVariant>(var1);
QCOMPARE(var4, var1);
- QCOMPARE(var4.type(), QVariant::Int);
+ QCOMPARE(var4.typeId(), QMetaType::Int);
QVariant var5;
var5 = var1;
QCOMPARE(var5, var1);
- QCOMPARE(var5.type(), QVariant::Int);
+ QCOMPARE(var5.typeId(), QMetaType::Int);
QVariant var6;
var6.setValue(var1);
QCOMPARE(var6, var1);
- QCOMPARE(var6.type(), QVariant::Int);
+ QCOMPARE(var6.typeId(), QMetaType::Int);
QCOMPARE(QVariant::fromValue(var1), QVariant::fromValue(var2));
QCOMPARE(qvariant_cast<QVariant>(var3), QVariant::fromValue(var4));
@@ -3906,10 +4247,10 @@ void tst_QVariant::variantInVariant()
QString str("hello");
QVariant var8 = qvariant_cast<QVariant>(QVariant::fromValue(QVariant::fromValue(str)));
- QCOMPARE((int)var8.type(), (int)QVariant::String);
+ QCOMPARE(var8.typeId(), QMetaType::QString);
QCOMPARE(qvariant_cast<QString>(QVariant(qvariant_cast<QVariant>(var8))), str);
- QVariant var9(qMetaTypeId<QVariant>(), &var1);
+ QVariant var9(QMetaType::fromType<QVariant>(), &var1);
QCOMPARE(var9.userType(), qMetaTypeId<QVariant>());
QCOMPARE(qvariant_cast<QVariant>(var9), var1);
}
@@ -3925,15 +4266,14 @@ Q_DECLARE_METATYPE(Convertible);
struct BigConvertible {
double d;
- double dummy;
- double dummy2;
+ double dummy[sizeof(QVariant) / sizeof(double)];
operator int() const { return (int)d; }
operator double() const { return d; }
operator QString() const { return QString::number(d); }
};
Q_DECLARE_METATYPE(BigConvertible);
-Q_STATIC_ASSERT(sizeof(BigConvertible) > sizeof(QVariant));
+static_assert(sizeof(BigConvertible) > sizeof(QVariant));
void tst_QVariant::userConversion()
{
@@ -3943,7 +4283,7 @@ void tst_QVariant::userConversion()
QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, Convertible>()));
Convertible c = { 123 };
- QVariant v = qVariantFromValue(c);
+ QVariant v = QVariant::fromValue(c);
bool ok;
v.toInt(&ok);
@@ -3976,8 +4316,8 @@ void tst_QVariant::userConversion()
QVERIFY(!(QMetaType::hasRegisteredConverterFunction<double, BigConvertible>()));
QVERIFY(!(QMetaType::hasRegisteredConverterFunction<QString, BigConvertible>()));
- BigConvertible c = { 123, 0, 0 };
- QVariant v = qVariantFromValue(c);
+ BigConvertible c = { 123, { 0, 0 } };
+ QVariant v = QVariant::fromValue(c);
bool ok;
v.toInt(&ok);
@@ -4009,12 +4349,12 @@ void tst_QVariant::userConversion()
void tst_QVariant::modelIndexConversion()
{
QVariant modelIndexVariant = QModelIndex();
- QVERIFY(modelIndexVariant.canConvert(QMetaType::QPersistentModelIndex));
- QVERIFY(modelIndexVariant.convert(QMetaType::QPersistentModelIndex));
- QCOMPARE(modelIndexVariant.type(), QVariant::PersistentModelIndex);
- QVERIFY(modelIndexVariant.canConvert(QMetaType::QModelIndex));
- QVERIFY(modelIndexVariant.convert(QMetaType::QModelIndex));
- QCOMPARE(modelIndexVariant.type(), QVariant::ModelIndex);
+ QVERIFY(modelIndexVariant.canConvert<QPersistentModelIndex>());
+ QVERIFY(modelIndexVariant.convert(QMetaType::fromType<QPersistentModelIndex>()));
+ QCOMPARE(modelIndexVariant.typeId(), QMetaType::QPersistentModelIndex);
+ QVERIFY(modelIndexVariant.canConvert(QMetaType::fromType<QModelIndex>()));
+ QVERIFY(modelIndexVariant.convert(QMetaType::fromType<QModelIndex>()));
+ QCOMPARE(modelIndexVariant.typeId(), QMetaType::QModelIndex);
}
class Forward;
@@ -4023,7 +4363,7 @@ Q_DECLARE_METATYPE(Forward*)
void tst_QVariant::forwardDeclare()
{
- Forward *f = 0;
+ Forward *f = nullptr;
QVariant v = QVariant::fromValue(f);
QCOMPARE(qvariant_cast<Forward*>(v), f);
}
@@ -4087,7 +4427,8 @@ void tst_QVariant::dataStream_data(QDataStream::Version version)
path = path.prepend(":/stream/").append("/");
QDir dir(path);
uint i = 0;
- foreach (const QFileInfo &fileInfo, dir.entryInfoList(QStringList() << "*.bin")) {
+ const auto entries = dir.entryInfoList(QStringList{u"*.bin"_s});
+ for (const QFileInfo &fileInfo : entries) {
QTest::newRow((path + fileInfo.fileName()).toLatin1()) << fileInfo.filePath();
i += 1;
}
@@ -4108,15 +4449,15 @@ void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version)
QVariant loadedVariant;
stream >> typeName >> loadedVariant;
- const int id = QMetaType::type(typeName.toLatin1());
+ const int id = QMetaType::fromName(typeName.toLatin1()).id();
if (id == QMetaType::Void) {
// Void type is not supported by QVariant
return;
}
- QVariant constructedVariant(static_cast<QVariant::Type>(id));
+ QVariant constructedVariant {QMetaType(id)};
QCOMPARE(constructedVariant.userType(), id);
- QCOMPARE(QMetaType::typeName(loadedVariant.userType()), typeName.toLatin1().constData());
+ QCOMPARE(QMetaType(loadedVariant.userType()).name(), typeName.toLatin1().constData());
QCOMPARE(loadedVariant.userType(), constructedVariant.userType());
}
@@ -4131,7 +4472,7 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version)
QString typeName;
dataFileStream >> typeName;
QByteArray data = file.readAll();
- const int id = QMetaType::type(typeName.toLatin1());
+ const int id = QMetaType::fromName(typeName.toLatin1()).id();
if (id == QMetaType::Void) {
// Void type is not supported by QVariant
return;
@@ -4142,7 +4483,7 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version)
QDataStream stream(&buffer);
stream.setVersion(version);
- QVariant constructedVariant(static_cast<QVariant::Type>(id));
+ QVariant constructedVariant {QMetaType(id)};
QCOMPARE(constructedVariant.userType(), id);
stream << constructedVariant;
@@ -4160,16 +4501,17 @@ void tst_QVariant::debugStream_data()
QTest::addColumn<QVariant>("variant");
QTest::addColumn<int>("typeId");
for (int id = 0; id < QMetaType::LastCoreType + 1; ++id) {
- const char *tagName = QMetaType::typeName(id);
- if (!tagName)
- continue;
- if (id != QMetaType::Void) {
- QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
+ if (id && !QMetaType::isRegistered(id)) {
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "^Trying to construct an instance of an invalid type"));
}
+ const char *tagName = QMetaType(id).name();
+ if (tagName && id != QMetaType::Void)
+ QTest::newRow(tagName) << QVariant(QMetaType(id)) << id;
}
QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>();
- QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
- QTest::newRow("MyClass") << QVariant(qMetaTypeId<MyClass>(), 0) << qMetaTypeId<MyClass>();
+ QTest::newRow("CustomStreamableClass") << QVariant(QMetaType::fromType<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
+ QTest::newRow("MyClass") << QVariant(QMetaType::fromType<MyClass>(), 0) << qMetaTypeId<MyClass>();
QTest::newRow("InvalidVariant") << QVariant() << int(QMetaType::UnknownType);
QTest::newRow("CustomQObject") << QVariant::fromValue(this) << qMetaTypeId<tst_QVariant*>();
}
@@ -4184,6 +4526,7 @@ void tst_QVariant::debugStream()
QVERIFY(msgHandler.testPassed());
}
+#if QT_DEPRECATED_SINCE(6, 0)
struct MessageHandlerType : public MessageHandler
{
MessageHandlerType(const int typeId)
@@ -4194,9 +4537,11 @@ struct MessageHandlerType : public MessageHandler
// Format itself is not important, but basic data as a type name should be included in the output
ok = msg.startsWith("QVariant::");
QVERIFY2(ok, (QString::fromLatin1("Message is not started correctly: '") + msg + '\'').toLatin1().constData());
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
ok &= (currentId == QMetaType::UnknownType
? msg.contains("Invalid")
: msg.contains(QMetaType::typeName(currentId)));
+QT_WARNING_POP
QVERIFY2(ok, (QString::fromLatin1("Message doesn't contain type name: '") + msg + '\'').toLatin1().constData());
}
};
@@ -4212,9 +4557,10 @@ void tst_QVariant::debugStreamType()
QFETCH(int, typeId);
MessageHandlerType msgHandler(typeId);
- qDebug() << QVariant::Type(typeId);
+ QT_IGNORE_DEPRECATIONS(qDebug() << QVariant::Type(typeId);)
QVERIFY(msgHandler.testPassed());
}
+#endif // QT_DEPRECATED_SINCE(6, 0)
void tst_QVariant::implicitConstruction()
{
@@ -4240,7 +4586,6 @@ void tst_QVariant::implicitConstruction()
F(LineF) \
F(Point) \
F(PointF) \
- F(RegExp) \
F(EasingCurve) \
F(Uuid) \
F(ModelIndex) \
@@ -4370,6 +4715,42 @@ struct ContainerAPI<Container, QByteArray>
}
};
+template<typename Container>
+struct ContainerAPI<Container, QChar>
+{
+ static void insert(Container &container, int value)
+ {
+ container.push_back(QChar::fromLatin1(char(value) + '0'));
+ }
+
+ static bool compare(const QVariant &variant, QChar value)
+ {
+ return variant.value<QChar>() == value;
+ }
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
+template<typename Container>
+struct ContainerAPI<Container, char>
+{
+ static void insert(Container &container, int value)
+ {
+ container.push_back(char(value) + '0');
+ }
+
+ static bool compare(const QVariant &variant, char value)
+ {
+ return variant.value<char>() == value;
+ }
+ static bool compare(QVariant variant, const QVariant &value)
+ {
+ return variant == value;
+ }
+};
+
#ifdef __has_include
# if __has_include(<forward_list>)
# define TEST_FORWARD_LIST
@@ -4457,11 +4838,6 @@ struct KeyGetter<std::map<T, U> >
};
-// We have no built-in defines to check the stdlib features.
-// #define TEST_UNORDERED_MAP
-
-#ifdef TEST_UNORDERED_MAP
-#include <unordered_map>
typedef std::unordered_map<int, bool> StdUnorderedMap_int_bool;
Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::unordered_map)
@@ -4480,98 +4856,254 @@ struct KeyGetter<std::unordered_map<T, U> >
return it->second;
}
};
-#endif
-void tst_QVariant::iterateContainerElements()
+template<typename Iterator>
+void sortIterable(QSequentialIterable *iterable)
{
-#ifdef Q_COMPILER_RANGE_FOR
+ std::sort(Iterator(iterable->mutableBegin()), Iterator(iterable->mutableEnd()),
+ [&](const QVariant &a, const QVariant &b) {
+ return a.toInt() < b.toInt();
+ });
+}
-#define TEST_RANGE_FOR(CONTAINER) \
- numSeen = 0; \
- containerIter = intList.begin(); \
- for (QVariant v : listIter) { \
- QVERIFY(ContainerAPI<CONTAINER >::compare(v, *containerIter)); \
- QVERIFY(ContainerAPI<CONTAINER >::compare(v, varList.at(numSeen))); \
- ++containerIter; \
- ++numSeen; \
- } \
- QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end()));
+template<typename Container>
+static void testSequentialIteration()
+{
+ int numSeen = 0;
+ Container sequence;
+ ContainerAPI<Container>::insert(sequence, 1);
+ ContainerAPI<Container>::insert(sequence, 2);
+ ContainerAPI<Container>::insert(sequence, 3);
+
+ QVariant listVariant = QVariant::fromValue(sequence);
+ QVERIFY(listVariant.canConvert<QVariantList>());
+ QVariantList varList = listVariant.value<QVariantList>();
+ QCOMPARE(varList.size(), (int)std::distance(sequence.begin(), sequence.end()));
+ QSequentialIterable listIter = listVariant.view<QSequentialIterable>();
+ QCOMPARE(varList.size(), listIter.size());
+
+ typename Container::iterator containerIter = sequence.begin();
+ const typename Container::iterator containerEnd = sequence.end();
+ for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen)
+ {
+ QVERIFY(ContainerAPI<Container >::compare(listIter.at(i), *containerIter));
+ QVERIFY(ContainerAPI<Container >::compare(listIter.at(i), varList.at(i)));
+ }
+ QCOMPARE(numSeen, (int)std::distance(sequence.begin(), sequence.end()));
+ QCOMPARE(containerIter, containerEnd);
+
+ numSeen = 0;
+ containerIter = sequence.begin();
+ for (QVariant v : listIter) {
+ QVERIFY(ContainerAPI<Container>::compare(v, *containerIter));
+ QVERIFY(ContainerAPI<Container>::compare(v, varList.at(numSeen)));
+ ++containerIter;
+ ++numSeen;
+ }
+ QCOMPARE(numSeen, (int)std::distance(sequence.begin(), sequence.end()));
+
+ auto compareLists = [&]() {
+ int numSeen = 0;
+ auto varList = listVariant.value<QVariantList>();
+ auto varIter = varList.begin();
+ for (const QVariant &v : std::as_const(listIter)) {
+ QVERIFY(ContainerAPI<Container>::compare(v, *varIter));
+ ++varIter;
+ ++numSeen;
+ }
+ QCOMPARE(varIter, varList.end());
+ numSeen = 0;
+ auto constVarIter = varList.constBegin();
+ for (QVariant v : listIter) {
+ QVERIFY(ContainerAPI<Container>::compare(v, *constVarIter));
+ ++constVarIter;
+ ++numSeen;
+ }
+ QCOMPARE(numSeen, (int)std::distance(varList.begin(), varList.end()));
+ };
+ compareLists();
+
+ QVariant first = listIter.at(0);
+ QVariant second = listIter.at(1);
+ QVariant third = listIter.at(2);
+ compareLists();
+ listIter.addValue(third);
+ compareLists();
+ listIter.addValue(second);
+ compareLists();
+ listIter.addValue(first);
+ compareLists();
+
+ QCOMPARE(listIter.size(), 6);
+
+ if (listIter.canRandomAccessIterate())
+ sortIterable<QSequentialIterable::RandomAccessIterator>(&listIter);
+ else if (listIter.canReverseIterate())
+ sortIterable<QSequentialIterable::BidirectionalIterator>(&listIter);
+ else if (listIter.canForwardIterate())
+ return; // std::sort cannot sort with only forward iterators.
+ else
+ QFAIL("The container has no meaningful iterators");
+
+ compareLists();
+ QCOMPARE(listIter.size(), 6);
+ QCOMPARE(listIter.at(0), first);
+ QCOMPARE(listIter.at(1), first);
+ QCOMPARE(listIter.at(2), second);
+ QCOMPARE(listIter.at(3), second);
+ QCOMPARE(listIter.at(4), third);
+ QCOMPARE(listIter.at(5), third);
+
+ if (listIter.metaContainer().canRemoveValue()) {
+ listIter.removeValue();
+ compareLists();
+ QCOMPARE(listIter.size(), 5);
+ QCOMPARE(listIter.at(0), first);
+ QCOMPARE(listIter.at(1), first);
+ QCOMPARE(listIter.at(2), second);
+ QCOMPARE(listIter.at(3), second);
+ QCOMPARE(listIter.at(4), third);
+ } else {
+ // QString and QByteArray have no pop_back or pop_front and it's unclear what other
+ // method we should use to remove an item.
+ QVERIFY((std::is_same_v<Container, QString> || std::is_same_v<Container, QByteArray>));
+ }
-#else
+ auto i = listIter.mutableBegin();
+ QVERIFY(i != listIter.mutableEnd());
-#define TEST_RANGE_FOR(CONTAINER)
+ *i = QStringLiteral("17");
+ if (listIter.metaContainer().valueMetaType() == QMetaType::fromType<int>())
+ QCOMPARE(listIter.at(0).toInt(), 17);
+ else if (listIter.metaContainer().valueMetaType() == QMetaType::fromType<bool>())
+ QCOMPARE(listIter.at(0).toBool(), false);
-#endif
+ *i = QStringLiteral("true");
+ if (listIter.metaContainer().valueMetaType() == QMetaType::fromType<int>())
+ QCOMPARE(listIter.at(0).toInt(), 0);
+ else if (listIter.metaContainer().valueMetaType() == QMetaType::fromType<bool>())
+ QCOMPARE(listIter.at(0).toBool(), true);
+}
-#define TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(CONTAINER) \
- { \
- int numSeen = 0; \
- CONTAINER intList; \
- ContainerAPI<CONTAINER >::insert(intList, 1); \
- ContainerAPI<CONTAINER >::insert(intList, 2); \
- ContainerAPI<CONTAINER >::insert(intList, 3); \
- \
- QVariant listVariant = QVariant::fromValue(intList); \
- QVERIFY(listVariant.canConvert<QVariantList>()); \
- QVariantList varList = listVariant.value<QVariantList>(); \
- QCOMPARE(varList.size(), (int)std::distance(intList.begin(), intList.end())); \
- QSequentialIterable listIter = listVariant.value<QSequentialIterable>(); \
- QCOMPARE(varList.size(), listIter.size()); \
- \
- CONTAINER::iterator containerIter = intList.begin(); \
- const CONTAINER::iterator containerEnd = intList.end(); \
- for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen) \
- { \
- QVERIFY(ContainerAPI<CONTAINER >::compare(listIter.at(i), *containerIter)); \
- QVERIFY(ContainerAPI<CONTAINER >::compare(listIter.at(i), varList.at(i))); \
- } \
- QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \
- QCOMPARE(containerIter, containerEnd); \
- \
- containerIter = intList.begin(); \
- numSeen = 0; \
- Q_FOREACH (const QVariant &v, listIter) { \
- QVERIFY(ContainerAPI<CONTAINER >::compare(v, *containerIter)); \
- QVERIFY(ContainerAPI<CONTAINER >::compare(v, varList.at(numSeen))); \
- ++containerIter; \
- ++numSeen; \
- } \
- QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \
- TEST_RANGE_FOR(CONTAINER) \
- }
-
-#define TEST_SEQUENTIAL_ITERATION(CONTAINER, VALUE_TYPE) \
- TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(CONTAINER<VALUE_TYPE > )
-
-
- TEST_SEQUENTIAL_ITERATION(QVector, int)
- TEST_SEQUENTIAL_ITERATION(QVector, QVariant)
- TEST_SEQUENTIAL_ITERATION(QVector, QString)
- TEST_SEQUENTIAL_ITERATION(QQueue, int)
- TEST_SEQUENTIAL_ITERATION(QQueue, QVariant)
- TEST_SEQUENTIAL_ITERATION(QQueue, QString)
- TEST_SEQUENTIAL_ITERATION(QList, int)
- TEST_SEQUENTIAL_ITERATION(QList, QVariant)
- TEST_SEQUENTIAL_ITERATION(QList, QString)
- TEST_SEQUENTIAL_ITERATION(QList, QByteArray)
- TEST_SEQUENTIAL_ITERATION(QStack, int)
- TEST_SEQUENTIAL_ITERATION(QStack, QVariant)
- TEST_SEQUENTIAL_ITERATION(QStack, QString)
- TEST_SEQUENTIAL_ITERATION(std::vector, int)
- TEST_SEQUENTIAL_ITERATION(std::vector, QVariant)
- TEST_SEQUENTIAL_ITERATION(std::vector, QString)
- TEST_SEQUENTIAL_ITERATION(std::list, int)
- TEST_SEQUENTIAL_ITERATION(std::list, QVariant)
- TEST_SEQUENTIAL_ITERATION(std::list, QString)
- TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(QStringList)
- TEST_SEQUENTIAL_ITERATION_ON_FULL_NAME(QByteArrayList)
+template<typename Container>
+static void testAssociativeIteration()
+{
+ using Key = typename Container::key_type;
+ using Mapped = typename Container::mapped_type;
+
+ int numSeen = 0;
+ Container mapping;
+ mapping[5] = true;
+ mapping[15] = false;
+
+ QVariant mappingVariant = QVariant::fromValue(mapping);
+ QVariantMap varMap = mappingVariant.value<QVariantMap>();
+ QVariantMap varHash = mappingVariant.value<QVariantMap>();
+ QAssociativeIterable mappingIter = mappingVariant.view<QAssociativeIterable>();
+
+ typename Container::const_iterator containerIter = mapping.begin();
+ const typename Container::const_iterator containerEnd = mapping.end();
+ for ( ;containerIter != containerEnd; ++containerIter, ++numSeen)
+ {
+ Mapped expected = KeyGetter<Container>::value(containerIter);
+ Key key = KeyGetter<Container>::get(containerIter);
+ Mapped actual = qvariant_cast<Mapped>(mappingIter.value(key));
+ QCOMPARE(qvariant_cast<Mapped>(varMap.value(QString::number(key))), expected);
+ QCOMPARE(qvariant_cast<Mapped>(varHash.value(QString::number(key))), expected);
+ QCOMPARE(actual, expected);
+ const QAssociativeIterable::const_iterator it = mappingIter.find(key);
+ QVERIFY(it != mappingIter.end());
+ QCOMPARE(it.value().value<Mapped>(), expected);
+ }
+ QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end()));
+ QCOMPARE(containerIter, containerEnd);
+ QVERIFY(mappingIter.find(10) == mappingIter.end());
+
+ auto i = mappingIter.mutableFind(QStringLiteral("nonono"));
+ QCOMPARE(i, mappingIter.mutableEnd());
+ i = mappingIter.mutableFind(QStringLiteral("5"));
+ QVERIFY(i != mappingIter.mutableEnd());
+
+ *i = QStringLiteral("17");
+
+ if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<int>())
+ QCOMPARE(mappingIter.value(5).toInt(), 17);
+ else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<bool>())
+ QCOMPARE(mappingIter.value(5).toBool(), true);
+
+ *i = QStringLiteral("true");
+ if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<int>())
+ QCOMPARE(mappingIter.value(5).toInt(), 0);
+ else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<bool>())
+ QCOMPARE(mappingIter.value(5).toBool(), true);
+
+ QVERIFY(mappingIter.containsKey("5"));
+ mappingIter.removeKey(QStringLiteral("5"));
+ QCOMPARE(mappingIter.find(5), mappingIter.end());
+
+ mappingIter.setValue(5, 44);
+ if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<int>())
+ QCOMPARE(mappingIter.value(5).toInt(), 44);
+ else if (mappingIter.metaContainer().mappedMetaType() == QMetaType::fromType<bool>())
+ QCOMPARE(mappingIter.value(5).toBool(), true);
+
+ // Test that find() does not coerce
+ auto container = Container();
+ container[0] = true;
+
+ QVariant containerVariant = QVariant::fromValue(container);
+ QAssociativeIterable iter = containerVariant.value<QAssociativeIterable>();
+ auto f = iter.constFind(QStringLiteral("anything"));
+ QCOMPARE(f, iter.constEnd());
+}
+
+void tst_QVariant::iterateSequentialContainerElements_data()
+{
+ QTest::addColumn<QFunctionPointer>("testFunction");
+#define ADD(T) QTest::newRow(#T) << &testSequentialIteration<T>
+ ADD(QQueue<int>);
+ ADD(QQueue<QVariant>);
+ ADD(QQueue<QString>);
+ ADD(QList<int>);
+ ADD(QList<QVariant>);
+ ADD(QList<QString>);
+ ADD(QList<QByteArray>);
+ ADD(QStack<int>);
+ ADD(QStack<QVariant>);
+ ADD(QStack<QString>);
+ ADD(std::vector<int>);
+ ADD(std::vector<QVariant>);
+ ADD(std::vector<QString>);
+ ADD(std::list<int>);
+ ADD(std::list<QVariant>);
+ ADD(std::list<QString>);
+ ADD(QStringList);
+ ADD(QByteArrayList);
+ ADD(QString);
+ ADD(QByteArray);
#ifdef TEST_FORWARD_LIST
- TEST_SEQUENTIAL_ITERATION(std::forward_list, int)
- TEST_SEQUENTIAL_ITERATION(std::forward_list, QVariant)
- TEST_SEQUENTIAL_ITERATION(std::forward_list, QString)
+ ADD(std::forward_list<int>);
+ ADD(std::forward_list<QVariant>);
+ ADD(std::forward_list<QString>);
#endif
+#undef ADD
+}
+
+void tst_QVariant::iterateAssociativeContainerElements_data()
+{
+ QTest::addColumn<QFunctionPointer>("testFunction");
+#define ADD(C, K, V) QTest::newRow(#C #K #V) << &testAssociativeIteration<C<K, V>>;
+ ADD(QHash, int, bool);
+ ADD(QHash, int, int);
+ ADD(QMap, int, bool);
+ ADD(std::map, int, bool);
+ ADD(std::unordered_map, int, bool);
+#undef ADD
+}
+void tst_QVariant::iterateContainerElements()
+{
{
QVariantList ints;
ints << 1 << 2 << 3;
@@ -4594,44 +5126,6 @@ void tst_QVariant::iterateContainerElements()
QCOMPARE(ints, intsCopy);
}
-#define TEST_ASSOCIATIVE_ITERATION(CONTAINER, KEY_TYPE, MAPPED_TYPE) \
- { \
- int numSeen = 0; \
- CONTAINER<KEY_TYPE, MAPPED_TYPE> mapping; \
- mapping[5] = true; \
- mapping[15] = false; \
- \
- QVariant mappingVariant = QVariant::fromValue(mapping); \
- QVariantMap varMap = mappingVariant.value<QVariantMap>(); \
- QVariantMap varHash = mappingVariant.value<QVariantMap>(); \
- QAssociativeIterable mappingIter = mappingVariant.value<QAssociativeIterable>(); \
- \
- CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerIter = mapping.begin(); \
- const CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerEnd = mapping.end(); \
- for ( ; containerIter != containerEnd; ++containerIter, ++numSeen) \
- { \
- MAPPED_TYPE expected = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::value(containerIter); \
- KEY_TYPE key = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::get(containerIter); \
- MAPPED_TYPE actual = mappingIter.value(key).value<MAPPED_TYPE >(); \
- QCOMPARE(varMap.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \
- QCOMPARE(varHash.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \
- QCOMPARE(actual, expected); \
- const QAssociativeIterable::const_iterator it = mappingIter.find(key); \
- QVERIFY(it != mappingIter.end()); \
- QCOMPARE(it.value().value<MAPPED_TYPE>(), expected); \
- } \
- QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end())); \
- QCOMPARE(containerIter, containerEnd); \
- QVERIFY(mappingIter.find(10) == mappingIter.end()); \
- }
-
- TEST_ASSOCIATIVE_ITERATION(QHash, int, bool)
- TEST_ASSOCIATIVE_ITERATION(QMap, int, bool)
- TEST_ASSOCIATIVE_ITERATION(std::map, int, bool)
-#ifdef TEST_UNORDERED_MAP
- TEST_ASSOCIATIVE_ITERATION(std::unordered_map, int, bool)
-#endif
-
{
QMap<int, QString> mapping;
mapping.insert(1, "one");
@@ -4641,10 +5135,10 @@ void tst_QVariant::iterateContainerElements()
QAssociativeIterable iter = var.value<QAssociativeIterable>();
QAssociativeIterable::const_iterator it = iter.begin();
QAssociativeIterable::const_iterator end = iter.end();
- QCOMPARE(*(mapping.begin() + 1), (*(it + 1)).toString());
+ QCOMPARE(*(++mapping.begin()), (*(it + 1)).toString());
int i = 0;
for ( ; it != end; ++it, ++i) {
- QCOMPARE(*(mapping.begin() + i), (*it).toString());
+ QCOMPARE(*(std::next(mapping.begin(), i)), (*it).toString());
}
QVariantList nums;
@@ -4658,60 +5152,77 @@ void tst_QVariant::iterateContainerElements()
numsCopy << *(it++);
QCOMPARE(nums, numsCopy);
}
+
+ {
+ auto container = QVariantMap();
+
+ container["one"] = 1;
+
+ auto containerVariant = QVariant::fromValue(container);
+ auto iter = containerVariant.value<QAssociativeIterable>();
+ auto value = iter.value("one");
+ QCOMPARE(value, QVariant(1));
+
+ auto f = iter.constFind("one");
+ QCOMPARE(*f, QVariant(1));
+ }
}
-void tst_QVariant::pairElements()
+template <typename Pair> static void testVariantPairElements()
{
- typedef QPair<QVariant, QVariant> QVariantPair;
+ QFETCH(std::function<void(void *)>, makeValue);
+ Pair p;
+ makeValue(&p);
+ QVariant v = QVariant::fromValue(p);
-#define TEST_PAIR_ELEMENT_ACCESS(PAIR, T1, T2, VALUE1, VALUE2) \
- { \
- PAIR<T1, T2> p(VALUE1, VALUE2); \
- QVariant v = QVariant::fromValue(p); \
- \
- QVERIFY(v.canConvert<QVariantPair>()); \
- QVariantPair pi = v.value<QVariantPair>(); \
- QCOMPARE(pi.first, QVariant::fromValue(VALUE1)); \
- QCOMPARE(pi.second, QVariant::fromValue(VALUE2)); \
- }
-
- TEST_PAIR_ELEMENT_ACCESS(QPair, int, int, 4, 5)
- TEST_PAIR_ELEMENT_ACCESS(std::pair, int, int, 4, 5)
- TEST_PAIR_ELEMENT_ACCESS(QPair, QString, QString, QStringLiteral("one"), QStringLiteral("two"))
- TEST_PAIR_ELEMENT_ACCESS(std::pair, QString, QString, QStringLiteral("one"), QStringLiteral("two"))
- TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, QVariant, 4, 5)
- TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, QVariant, 4, 5)
- TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, int, 41, 15)
- TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, int, 34, 65)
- TEST_PAIR_ELEMENT_ACCESS(QPair, int, QVariant, 24, 25)
- TEST_PAIR_ELEMENT_ACCESS(std::pair, int, QVariant, 44, 15)
+ QVERIFY(v.canConvert<QVariantPair>());
+ QVariantPair pi = v.value<QVariantPair>();
+ QCOMPARE(pi.first, QVariant::fromValue(p.first));
+ QCOMPARE(pi.second, QVariant::fromValue(p.second));
}
-enum EnumTest_Enum0 { EnumTest_Enum0_value = 42, EnumTest_Enum0_negValue = -8 };
-Q_DECLARE_METATYPE(EnumTest_Enum0)
-enum EnumTest_Enum1 : qint64 { EnumTest_Enum1_value = 42, EnumTest_Enum1_bigValue = (Q_INT64_C(1) << 33) + 50 };
-Q_DECLARE_METATYPE(EnumTest_Enum1)
+void tst_QVariant::pairElements_data()
+{
+ QTest::addColumn<QFunctionPointer>("testFunction");
+ QTest::addColumn<std::function<void(void *)>>("makeValue");
-#if defined(Q_COMPILER_CLASS_ENUM)
-enum EnumTest_Enum3 : qint64 { EnumTest_Enum3_value = -47, EnumTest_Enum3_bigValue = (Q_INT64_C(1) << 56) + 5 };
-Q_DECLARE_METATYPE(EnumTest_Enum3)
-enum EnumTest_Enum4 : quint64 { EnumTest_Enum4_value = 47, EnumTest_Enum4_bigValue = (Q_INT64_C(1) << 52) + 45 };
-Q_DECLARE_METATYPE(EnumTest_Enum4)
-enum EnumTest_Enum5 : uint { EnumTest_Enum5_value = 47 };
-Q_DECLARE_METATYPE(EnumTest_Enum5)
-enum EnumTest_Enum6 : uchar { EnumTest_Enum6_value = 47 };
-Q_DECLARE_METATYPE(EnumTest_Enum6)
-enum class EnumTest_Enum7 { EnumTest_Enum7_value = 47, ensureSignedEnum7 = -1 };
-Q_DECLARE_METATYPE(EnumTest_Enum7)
-enum EnumTest_Enum8 : short { EnumTest_Enum8_value = 47 };
-Q_DECLARE_METATYPE(EnumTest_Enum8)
-#endif
+ static auto makeString = [](auto &&value) -> QString {
+ using T = std::decay_t<decltype(value)>;
+ if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) {
+ return QString::number(value);
+ } else if constexpr (std::is_same_v<T, QVariant>) {
+ return value.toString();
+ } else {
+ return value;
+ }
+ };
+ auto addRow = [](auto &&first, auto &&second) {
+ using Pair = std::pair<std::decay_t<decltype(first)>, std::decay_t<decltype(second)>>;
+ std::function<void(void *)> makeValue = [=](void *pair) {
+ *static_cast<Pair *>(pair) = Pair{first, second};
+ };
+
+ QTest::addRow("%s", qPrintable(makeString(first) + u',' + makeString(second)))
+ << &testVariantPairElements<Pair> << makeValue;
+ };
+
+ addRow(4, 5);
+ addRow(QStringLiteral("one"), QStringLiteral("two"));
+ addRow(QVariant(4), QVariant(5));
+ addRow(QVariant(41), 65);
+ addRow(41, QVariant(15));
+}
-template<typename Enum> void testVariant(Enum value, bool *ok)
+template <auto value> static void testVariantEnum()
{
- *ok = false;
- QVariant var = QVariant::fromValue(value);
+ using Enum = decltype(value);
+ auto canLosslesslyConvert = [=](auto zero) {
+ return sizeof(value) <= sizeof(zero) ||
+ value == Enum(decltype(zero)(qToUnderlying(value)));
+ };
+ bool losslessConvertToInt = canLosslesslyConvert(int{});
+ QVariant var = QVariant::fromValue(value);
QCOMPARE(var.userType(), qMetaTypeId<Enum>());
QVERIFY(var.canConvert<Enum>());
@@ -4722,25 +5233,27 @@ template<typename Enum> void testVariant(Enum value, bool *ok)
QVERIFY(var.canConvert<qint64>());
QVERIFY(var.canConvert<quint64>());
-
QCOMPARE(var.value<Enum>(), value);
QCOMPARE(var.value<int>(), static_cast<int>(value));
QCOMPARE(var.value<uint>(), static_cast<uint>(value));
QCOMPARE(var.value<short>(), static_cast<short>(value));
QCOMPARE(var.value<unsigned short>(), static_cast<unsigned short>(value));
QCOMPARE(var.value<qint64>(), static_cast<qint64>(value));
- if (sizeof(value) < 8 && static_cast<qint64>(value) < 0) {
- QEXPECT_FAIL("", "The metatype system don't store the sign of enums", Continue);
- // The value is stored internaly with 32 bit. When asked to convert it to 64 bit unsigned,
- // we consider that the value was unsigned, so we don't extent the bit signs
- }
QCOMPARE(var.value<quint64>(), static_cast<quint64>(value));
QVariant var2 = var;
- QVERIFY(var2.convert(QMetaType::Int));
+ QVERIFY(var2.convert(QMetaType::fromType<int>()));
QCOMPARE(var2.value<int>(), static_cast<int>(value));
- if ((static_cast<qint64>(value) <= INT_MAX) && (static_cast<qint64>(value) >= INT_MIN)) {
+ QVariant strVar = QString::number(qToUnderlying(value));
+ QVariant baVar = QByteArray::number(qToUnderlying(value));
+ QCOMPARE(strVar.value<Enum>(), value);
+ QCOMPARE(baVar.value<Enum>(), value);
+ QCOMPARE(var.value<QString>(), strVar);
+ QCOMPARE(var.value<QByteArray>(), baVar);
+
+ // unary + to silence gcc warning
+ if (losslessConvertToInt) {
int intValue = static_cast<int>(value);
QVariant intVar = intValue;
QVERIFY(intVar.canConvert<Enum>());
@@ -4750,73 +5263,126 @@ template<typename Enum> void testVariant(Enum value, bool *ok)
QVERIFY(QVariant(longValue).canConvert<Enum>());
QCOMPARE(QVariant(longValue).value<Enum>(), value);
- *ok = true;
-}
-
-void tst_QVariant::enums()
-{
- bool ok = false;
- testVariant(EnumTest_Enum0_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum0_negValue, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum1_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum1_bigValue, &ok);
- QVERIFY(ok);
-#if defined(Q_COMPILER_CLASS_ENUM)
- testVariant(EnumTest_Enum3::EnumTest_Enum3_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum3::EnumTest_Enum3_bigValue, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum4::EnumTest_Enum4_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum4::EnumTest_Enum4_bigValue, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum5::EnumTest_Enum5_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum6::EnumTest_Enum6_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum7::EnumTest_Enum7_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum8::EnumTest_Enum8_value, &ok);
- QVERIFY(ok);
- testVariant(EnumTest_Enum3::EnumTest_Enum3_value, &ok);
- QVERIFY(ok);
-#endif
-}
-
-template<typename Enum> void testVariantMeta(Enum value, bool *ok, const char *string)
-{
- testVariant<Enum>(value, ok);
- QVERIFY(ok);
- *ok = false;
+ auto value2 = Enum(qToUnderlying(value) + 1);
+ var2 = QVariant::fromValue(value2);
+ QCOMPARE_EQ(var, var);
+ QCOMPARE_NE(var, var2);
+ QCOMPARE(QVariant::compare(var, var), QPartialOrdering::Equivalent);
+ QCOMPARE(QVariant::compare(var, var2), QPartialOrdering::Less);
+ QCOMPARE(QVariant::compare(var2, var), QPartialOrdering::Greater);
+
+ QCOMPARE_EQ(var, static_cast<qint64>(value));
+ QCOMPARE_EQ(var, static_cast<quint64>(value));
+ QCOMPARE_EQ(static_cast<qint64>(value), var);
+ QCOMPARE_EQ(static_cast<quint64>(value), var);
+ QCOMPARE_NE(var2, static_cast<qint64>(value));
+ QCOMPARE_NE(var2, static_cast<quint64>(value));
+ QCOMPARE_NE(static_cast<qint64>(value), var2);
+ QCOMPARE_NE(static_cast<quint64>(value), var2);
+
+ if (losslessConvertToInt) {
+ QCOMPARE_EQ(var, int(value));
+ QCOMPARE_EQ(int(value), var);
+ QCOMPARE_NE(var2, int(value));
+ QCOMPARE_NE(int(value), var2);
+ }
+ if (canLosslesslyConvert(uint{})) {
+ QCOMPARE_EQ(var, uint(value));
+ QCOMPARE_EQ(uint(value), var);
+ QCOMPARE_NE(var2, uint(value));
+ QCOMPARE_NE(uint(value), var2);
+ }
+ if (canLosslesslyConvert(short{})) {
+ QCOMPARE_EQ(var, short(value));
+ QCOMPARE_EQ(short(value), var);
+ QCOMPARE_NE(var2, short(value));
+ QCOMPARE_NE(short(value), var2);
+ }
+ if (canLosslesslyConvert(ushort{})) {
+ QCOMPARE_EQ(var, ushort(value));
+ QCOMPARE_EQ(ushort(value), var);
+ QCOMPARE_NE(var2, ushort(value));
+ QCOMPARE_NE(ushort(value), var2);
+ }
+ if (canLosslesslyConvert(char{})) {
+ QCOMPARE_EQ(var, char(value));
+ QCOMPARE_EQ(char(value), var);
+ QCOMPARE_NE(var2, char(value));
+ QCOMPARE_NE(char(value), var2);
+ }
+ if (canLosslesslyConvert(uchar{})) {
+ QCOMPARE_EQ(var, uchar(value));
+ QCOMPARE_EQ(uchar(value), var);
+ QCOMPARE_NE(var2, uchar(value));
+ QCOMPARE_NE(uchar(value), var2);
+ }
+ if (canLosslesslyConvert(qint8{})) {
+ QCOMPARE_EQ(var, qint8(value));
+ QCOMPARE_EQ(qint8(value), var);
+ QCOMPARE_NE(var2, qint8(value));
+ QCOMPARE_NE(qint8(value), var2);
+ }
+
+ // string compares too (of the values in decimal)
+ QCOMPARE_EQ(var, QString::number(qToUnderlying(value)));
+ QCOMPARE_EQ(QString::number(qToUnderlying(value)), var);
+ QCOMPARE_NE(var, QString::number(qToUnderlying(value2)));
+ QCOMPARE_NE(QString::number(qToUnderlying(value2)), var);
+}
+
+void tst_QVariant::enums_data()
+{
+ QTest::addColumn<QFunctionPointer>("testFunction");
+
+#define ADD(V) QTest::newRow(#V) << &testVariantEnum<V>
+ ADD(EnumTest_Enum0_value);
+ ADD(EnumTest_Enum0_negValue);
+ ADD(EnumTest_Enum1_value);
+ ADD(EnumTest_Enum1_bigValue);
+ ADD(EnumTest_Enum3::EnumTest_Enum3_value);
+ ADD(EnumTest_Enum3::EnumTest_Enum3_bigValue);
+ ADD(EnumTest_Enum4::EnumTest_Enum4_value);
+ ADD(EnumTest_Enum4::EnumTest_Enum4_bigValue);
+ ADD(EnumTest_Enum5::EnumTest_Enum5_value);
+ ADD(EnumTest_Enum6::EnumTest_Enum6_value);
+ ADD(EnumTest_Enum7::EnumTest_Enum7_value);
+ ADD(EnumTest_Enum8::EnumTest_Enum8_value);
+ ADD(EnumTest_Enum3::EnumTest_Enum3_value);
+#undef ADD
+}
+
+// ### C++20: this would be easier if QFlags were a structural type
+template <typename Enum, auto Value> static void testVariantMetaEnum()
+{
+ Enum value(Value);
+ QFETCH(QString, string);
QVariant var = QVariant::fromValue(value);
QVERIFY(var.canConvert<QString>());
QVERIFY(var.canConvert<QByteArray>());
- QCOMPARE(var.value<QString>(), QString::fromLatin1(string));
- QCOMPARE(var.value<QByteArray>(), QByteArray(string));
+ QCOMPARE(var.value<QString>(), string);
+ QCOMPARE(var.value<QByteArray>(), string.toLatin1());
- QVariant strVar = QString::fromLatin1(string);
+ QVariant strVar = string;
QVERIFY(strVar.canConvert<Enum>());
- if ((static_cast<qint64>(value) > INT_MAX) || (static_cast<qint64>(value) < INT_MIN)) {
+ // unary + to silence gcc warning
+ if ((+static_cast<qint64>(value) > INT_MAX) || (+static_cast<qint64>(value) < INT_MIN)) {
QEXPECT_FAIL("", "QMetaEnum api uses 'int' as return type QTBUG-27451", Abort);
- *ok = true;
}
QCOMPARE(strVar.value<Enum>(), value);
- strVar = QByteArray(string);
+ strVar = string.toLatin1();
QVERIFY(strVar.canConvert<Enum>());
QCOMPARE(strVar.value<Enum>(), value);
- *ok = true;
}
-void tst_QVariant::metaEnums()
+void tst_QVariant::metaEnums_data()
{
- bool ok = false;
+ QTest::addColumn<QFunctionPointer>("testFunction");
+ QTest::addColumn<QString>("string");
+
#define METAENUMS_TEST(Value) \
- testVariantMeta(Value, &ok, #Value); QVERIFY(ok)
+ QTest::newRow(#Value) << &testVariantMetaEnum<decltype(Value), Value> << #Value;
METAENUMS_TEST(MetaEnumTest_Enum0_value);
METAENUMS_TEST(MetaEnumTest_Enum1_value);
@@ -4829,113 +5395,27 @@ void tst_QVariant::metaEnums()
METAENUMS_TEST(MetaEnumTest_Enum5_value);
METAENUMS_TEST(MetaEnumTest_Enum6_value);
METAENUMS_TEST(MetaEnumTest_Enum8_value);
-}
-
-void tst_QVariant::compareSanity_data()
-{
- QTest::addColumn<QVariant>("value1");
- QTest::addColumn<QVariant>("value2");
-
- QTest::newRow( "int <>/== QUrl" ) << QVariant( 97 ) << QVariant(QUrl("a"));
- QTest::newRow( "int <>/== QChar" ) << QVariant( 97 ) << QVariant(QChar('a'));
- QTest::newRow( "int <>/== QString" ) << QVariant( 97 ) << QVariant(QString("a"));
- QTest::newRow( "QUrl <>/== QChar" ) << QVariant(QUrl("a")) << QVariant(QChar('a'));
- QTest::newRow( "QUrl <>/== QString" ) << QVariant(QUrl("a")) << QVariant(QString("a"));
- QTest::newRow( "QChar <>/== QString" ) << QVariant(QChar('a')) << QVariant(QString("a"));
-}
-
-void tst_QVariant::compareSanity()
-{
- QFETCH(QVariant, value1);
- QFETCH(QVariant, value2);
-
- if (value1 == value2) {
- QVERIFY(!(value1 < value2) && !(value1 > value2));
- } else {
- QVERIFY(value1 != value2);
- QVERIFY((value1 < value2) || (value1 > value2));
- }
-}
-
-static void richComparison(const QVariant& less, const QVariant& more)
-{
- QVERIFY(less.type() == more.type());
-
- QVERIFY(less < more);
- QVERIFY(!(more < less));
+ { using namespace Qt; METAENUMS_TEST(RichText); }
+#undef METAENUMS_TEST
- QVERIFY(more > less);
- QVERIFY(!(less > more));
-
- QVERIFY(less <= more);
- QVERIFY(!(more <= less));
- QVERIFY(less <= less);
-
- QVERIFY(more >= less);
- QVERIFY(!(less >= more));
- QVERIFY(more >= more);
-}
-
-void tst_QVariant::compareRich()
-{
- richComparison(QUuid("{49d8ad2a-2ee8-4c3d-949f-1b5a3765ddf0}"),
- QUuid("{f6d56824-16e9-4543-a375-add2877c2d05}"));
- richComparison(QByteArray::fromRawData("a", 1),
- QByteArray::fromRawData("b", 1));
- richComparison(QStringLiteral("a"), QStringLiteral("b"));
- richComparison(QLatin1String("a"), QLatin1String("b"));
- richComparison(QChar('a'), QChar('b'));
- richComparison(QDate(2016, 7, 23), QDate(2016, 7, 24));
- richComparison(QTime(0, 0), QTime(0, 1));
- richComparison(QDateTime(QDate(2016, 7, 23), QTime(0, 0)),
- QDateTime(QDate(2016, 7, 23), QTime(0, 1)));
+ QTest::newRow("AlignBottom")
+ << &testVariantMetaEnum<Qt::Alignment, Qt::AlignBottom> << "AlignBottom";
- richComparison(QStringList(), QStringList() << QStringLiteral("a"));
- richComparison(QStringList(), QStringList() << QStringLiteral("a")
- << QStringLiteral("b"));
- richComparison(QStringList() << QStringLiteral("a"),
- QStringList() << QStringLiteral("b"));
- richComparison(QStringList() << QStringLiteral("a"),
- QStringList() << QStringLiteral("b")
- << QStringLiteral("c"));
- richComparison(QStringList() << QStringLiteral("a")
- << QStringLiteral("c"),
- QStringList() << QStringLiteral("b"));
- richComparison(QStringList() << QStringLiteral("a")
- << QStringLiteral("c"),
- QStringList() << QStringLiteral("b")
- << QStringLiteral("d"));
- richComparison(QStringList() << QStringLiteral("a")
- << QStringLiteral("c"),
- QStringList() << QStringLiteral("a")
- << QStringLiteral("d"));
+ constexpr auto AlignHCenterBottom = Qt::AlignmentFlag((Qt::AlignHCenter | Qt::AlignBottom).toInt());
+ QTest::newRow("AlignHCenter|AlignBottom")
+ << &testVariantMetaEnum<Qt::Alignment, AlignHCenterBottom> << "AlignHCenter|AlignBottom";
}
void tst_QVariant::nullConvert()
{
- // Test quirks with QVariants different types of null states.
-
// null variant with no initialized value
- QVariant nullVar(QVariant::String);
+ QVariant nullVar {QMetaType::fromType<QString>()};
QVERIFY(nullVar.isValid());
QVERIFY(nullVar.isNull());
// We can not convert a variant with no value
- QVERIFY(!nullVar.convert(QVariant::Url));
- QCOMPARE(nullVar.type(), QVariant::Url);
+ QVERIFY(!nullVar.convert(QMetaType::fromType<QUrl>()));
+ QCOMPARE(nullVar.typeId(), QMetaType::QUrl);
QVERIFY(nullVar.isNull());
-
- // variant initialized with null value
- QVariant nullStr = QVariant::fromValue(QString());
- QVERIFY(nullStr.isValid());
- QVERIFY(nullStr.isNull());
- // We can convert an initialized null value however
- QVERIFY(nullStr.convert(QVariant::Url));
- QCOMPARE(nullStr.type(), QVariant::Url);
- QVERIFY(nullStr.isValid());
- // QUrl does not have an isNull method
- QVERIFY(!nullStr.isNull());
- // The URL is not valid however
- QVERIFY(!nullStr.toUrl().isValid());
}
void tst_QVariant::accessSequentialContainerKey()
@@ -4962,40 +5442,891 @@ void tst_QVariant::accessSequentialContainerKey()
QCOMPARE(nameResult, QStringLiteral("Seven"));
}
+void tst_QVariant::shouldDeleteVariantDataWorksForSequential()
+{
+ QCOMPARE(instanceCount, 0);
+ {
+ QtMetaContainerPrivate::QMetaSequenceInterface metaSequence {};
+ metaSequence.iteratorCapabilities = QtMetaContainerPrivate::RandomAccessCapability
+ | QtMetaContainerPrivate::BiDirectionalCapability
+ | QtMetaContainerPrivate::ForwardCapability
+ | QtMetaContainerPrivate::InputCapability;
+
+ metaSequence.sizeFn = [](const void *) { return qsizetype(1); };
+ metaSequence.createConstIteratorFn =
+ [](const void *, QtMetaContainerPrivate::QMetaSequenceInterface::Position) -> void* {
+ return nullptr;
+ };
+ metaSequence.addValueFn = [](void *, const void *,
+ QtMetaContainerPrivate::QMetaSequenceInterface::Position) {};
+ metaSequence.advanceConstIteratorFn = [](void *, qsizetype) {};
+ metaSequence.destroyConstIteratorFn = [](const void *){};
+ metaSequence.compareConstIteratorFn = [](const void *, const void *) {
+ return true; // all iterators are nullptr
+ };
+ metaSequence.copyConstIteratorFn = [](void *, const void *){};
+ metaSequence.diffConstIteratorFn = [](const void *, const void *) -> qsizetype {
+ return 0;
+ };
+ metaSequence.valueAtIndexFn = [](const void *, qsizetype, void *dataPtr) -> void {
+ MyType mytype {1, "eins"};
+ *static_cast<MyType *>(dataPtr) = mytype;
+ };
+ metaSequence.valueAtConstIteratorFn = [](const void *, void *dataPtr) -> void {
+ MyType mytype {2, "zwei"};
+ *static_cast<MyType *>(dataPtr) = mytype;
+ };
+ metaSequence.valueMetaType = QtPrivate::qMetaTypeInterfaceForType<MyType>();
+
+ QSequentialIterable iterable(QMetaSequence(&metaSequence), nullptr);
+ QVariant value1 = iterable.at(0);
+ QVERIFY(value1.canConvert<MyType>());
+ QCOMPARE(value1.value<MyType>().number, 1);
+ QVariant value2 = *iterable.begin();
+ QVERIFY(value2.canConvert<MyType>());
+ QCOMPARE(value2.value<MyType>().number, 2);
+ }
+ QCOMPARE(instanceCount, 0);
+}
+
+void tst_QVariant::shouldDeleteVariantDataWorksForAssociative()
+{
+ QCOMPARE(instanceCount, 0);
+ {
+ QtMetaContainerPrivate::QMetaAssociationInterface iterator {};
+
+ iterator.sizeFn = [](const void *) -> qsizetype {return 1;};
+ iterator.mappedMetaType = QtPrivate::qMetaTypeInterfaceForType<MyType>();
+ iterator.keyMetaType = QtPrivate::qMetaTypeInterfaceForType<MyType>();
+ iterator.createConstIteratorFn = [](
+ const void *, QtMetaContainerPrivate::QMetaContainerInterface::Position) -> void * {
+ return nullptr;
+ };
+ iterator.advanceConstIteratorFn = [](void *, qsizetype) {};
+ iterator.destroyConstIteratorFn = [](const void *){};
+ iterator.compareConstIteratorFn = [](const void *, const void *) {
+ return true; /*all iterators are nullptr*/
+ };
+ iterator.createConstIteratorAtKeyFn = [](const void *, const void *) -> void * {
+ return reinterpret_cast<void *>(quintptr(42));
+ };
+ iterator.copyConstIteratorFn = [](void *, const void *) {};
+ iterator.diffConstIteratorFn = [](const void *, const void *) -> qsizetype { return 0; };
+ iterator.keyAtConstIteratorFn = [](const void *iterator, void *dataPtr) -> void {
+ MyType mytype {1, "key"};
+ if (reinterpret_cast<quintptr>(iterator) == 42) {
+ mytype.number = 42;
+ mytype.text = "find_key";
+ }
+ *static_cast<MyType *>(dataPtr) = mytype;
+ };
+ iterator.mappedAtConstIteratorFn = [](const void *iterator, void *dataPtr) -> void {
+ MyType mytype {2, "value"};
+ if (reinterpret_cast<quintptr>(iterator) == 42) {
+ mytype.number = 42;
+ mytype.text = "find_value";
+ }
+ *static_cast<MyType *>(dataPtr) = mytype;
+ };
+ QAssociativeIterable iterable(QMetaAssociation(&iterator), nullptr);
+ auto it = iterable.begin();
+ QVariant value1 = it.key();
+ QVERIFY(value1.canConvert<MyType>());
+ QCOMPARE(value1.value<MyType>().number, 1);
+ QCOMPARE(value1.value<MyType>().text, "key");
+ QVariant value2 = it.value();
+ QVERIFY(value2.canConvert<MyType>());
+ QCOMPARE(value2.value<MyType>().number, 2);
+ auto findIt = iterable.find(QVariant::fromValue(MyType {}));
+ value1 = findIt.key();
+ QCOMPARE(value1.value<MyType>().number, 42);
+ QCOMPARE(value1.value<MyType>().text, "find_key");
+ value2 = findIt.value();
+ QCOMPARE(value2.value<MyType>().number, 42);
+ QCOMPARE(value2.value<MyType>().text, "find_value");
+ }
+ QCOMPARE(instanceCount, 0);
+}
+
void tst_QVariant::fromStdVariant()
{
-#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
+#define CHECK_EQUAL(lhs, rhs, type) do { \
+ QCOMPARE(lhs.typeId(), rhs.typeId()); \
+ if (lhs.isNull()) { \
+ QVERIFY(rhs.isNull()); \
+ } else { \
+ QVERIFY(!rhs.isNull()); \
+ QCOMPARE(get< type >(lhs), get< type >(rhs)); \
+ } \
+ } while (false)
+
{
typedef std::variant<int, bool> intorbool_t;
intorbool_t stdvar = 5;
QVariant qvar = QVariant::fromStdVariant(stdvar);
QVERIFY(!qvar.isNull());
- QCOMPARE(qvar.type(), QVariant::Int);
+ QCOMPARE(qvar.typeId(), QMetaType::Int);
QCOMPARE(qvar.value<int>(), std::get<int>(stdvar));
+ {
+ const auto qv2 = QVariant::fromStdVariant(std::move(stdvar));
+ CHECK_EQUAL(qv2, qvar, int);
+ }
+
stdvar = true;
qvar = QVariant::fromStdVariant(stdvar);
QVERIFY(!qvar.isNull());
- QCOMPARE(qvar.type(), QVariant::Bool);
+ QCOMPARE(qvar.typeId(), QMetaType::Bool);
QCOMPARE(qvar.value<bool>(), std::get<bool>(stdvar));
+ {
+ const auto qv2 = QVariant::fromStdVariant(std::move(stdvar));
+ CHECK_EQUAL(qv2, qvar, bool);
+ }
}
{
std::variant<std::monostate, int> stdvar;
QVariant qvar = QVariant::fromStdVariant(stdvar);
QVERIFY(!qvar.isValid());
+ {
+ const auto qv2 = QVariant::fromStdVariant(std::move(stdvar));
+ CHECK_EQUAL(qv2, qvar, int); // fake type, they're empty
+ }
stdvar = -4;
qvar = QVariant::fromStdVariant(stdvar);
QVERIFY(!qvar.isNull());
- QCOMPARE(qvar.type(), QVariant::Int);
+ QCOMPARE(qvar.typeId(), QMetaType::Int);
QCOMPARE(qvar.value<int>(), std::get<int>(stdvar));
+ {
+ const auto qv2 = QVariant::fromStdVariant(std::move(stdvar));
+ CHECK_EQUAL(qv2, qvar, int);
+ }
}
{
std::variant<int, bool, QChar> stdvar = QChar::fromLatin1(' ');
QVariant qvar = QVariant::fromStdVariant(stdvar);
QVERIFY(!qvar.isNull());
- QCOMPARE(qvar.type(), QVariant::Char);
+ QCOMPARE(qvar.typeId(), QMetaType::QChar);
QCOMPARE(qvar.value<QChar>(), std::get<QChar>(stdvar));
+ {
+ const auto qv2 = QVariant::fromStdVariant(std::move(stdvar));
+ CHECK_EQUAL(qv2, qvar, QChar);
+ }
+ }
+ // rvalue fromStdVariant() actually moves:
+ {
+ const auto foo = u"foo"_s;
+ std::variant<QString, QByteArray> stdvar = foo;
+ QVariant qvar = QVariant::fromStdVariant(std::move(stdvar));
+ const auto ps = get_if<QString>(&stdvar);
+ QVERIFY(ps);
+ QVERIFY(ps->isNull()); // QString was moved from
+ QVERIFY(!qvar.isNull());
+ QCOMPARE(qvar.typeId(), QMetaType::QString);
+ QCOMPARE(get<QString>(qvar), foo);
+ }
+
+#undef CHECK_EQUAL
+}
+
+void tst_QVariant::qt4UuidDataStream()
+{
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_4_8);
+ QUuid source(0x12345678,0x1234,0x1234,0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89);
+ stream << QVariant::fromValue(source);
+ const QByteArray qt4Data = QByteArray::fromHex("0000007f000000000651557569640012345678123412341223344556677889");
+ QCOMPARE(data, qt4Data);
+
+ QDataStream input(&data, QIODevice::ReadOnly);
+ input.setVersion(QDataStream::Qt_4_8);
+ QVariant result;
+ input >> result;
+ QCOMPARE(result.value<QUuid>(), source);
+}
+
+void tst_QVariant::sequentialIterableEndianessSanityCheck()
+{
+ namespace QMTP = QtMetaContainerPrivate;
+ QMTP::IteratorCapabilities oldIteratorCaps
+ = QMTP::InputCapability | QMTP::ForwardCapability
+ | QMTP::BiDirectionalCapability | QMTP::RandomAccessCapability;
+ QMTP::QMetaSequenceInterface seqImpl {};
+ QCOMPARE(seqImpl.revision, 0u);
+ memcpy(&seqImpl.iteratorCapabilities, &oldIteratorCaps, sizeof(oldIteratorCaps));
+ QCOMPARE(seqImpl.revision, 0u);
+}
+
+void tst_QVariant::sequentialIterableAppend()
+{
+ {
+ QList<int> container { 1, 2 };
+ auto variant = QVariant::fromValue(container);
+ QVERIFY(variant.canConvert<QSequentialIterable>());
+ QSequentialIterable asIterable = variant.view<QSequentialIterable>();
+ const int i = 3, j = 4;
+ void *mutableIterable = asIterable.mutableIterable();
+ asIterable.metaContainer().addValueAtEnd(mutableIterable, &i);
+ asIterable.metaContainer().addValueAtEnd(mutableIterable, &j);
+ QCOMPARE(variant.value<QList<int>>(), QList<int> ({ 1, 2, 3, 4 }));
+
+ asIterable.metaContainer().addValueAtBegin(mutableIterable, &i);
+ asIterable.metaContainer().addValueAtBegin(mutableIterable, &j);
+ QCOMPARE(variant.value<QList<int>>(), QList<int> ({ 4, 3, 1, 2, 3, 4 }));
+
+ asIterable.metaContainer().removeValueAtBegin(mutableIterable);
+ QCOMPARE(variant.value<QList<int>>(), QList<int> ({ 3, 1, 2, 3, 4 }));
+ asIterable.metaContainer().removeValueAtEnd(mutableIterable);
+ QCOMPARE(variant.value<QList<int>>(), QList<int> ({ 3, 1, 2, 3 }));
+ }
+ {
+ QSet<QByteArray> container { QByteArray{"hello"}, QByteArray{"world"} };
+ auto variant = QVariant::fromValue(std::move(container));
+ QVERIFY(variant.canConvert<QSequentialIterable>());
+ QSequentialIterable asIterable = variant.view<QSequentialIterable>();
+ QByteArray qba1 {"goodbye"};
+ QByteArray qba2 { "moon" };
+ void *mutableIterable = asIterable.mutableIterable();
+ asIterable.metaContainer().addValue(mutableIterable, &qba1);
+ asIterable.metaContainer().addValue(mutableIterable, &qba2);
+ QSet<QByteArray> reference { "hello", "world", "goodbye", "moon" };
+ QCOMPARE(variant.value<QSet<QByteArray>>(), reference);
+ asIterable.metaContainer().addValue(mutableIterable, &qba1);
+ asIterable.metaContainer().addValue(mutableIterable, &qba2);
+ QCOMPARE(variant.value<QSet<QByteArray>>(), reference);
+ }
+}
+
+void tst_QVariant::preferDirectConversionOverInterfaces()
+{
+ using namespace QtMetaTypePrivate;
+ bool calledCorrectConverter = false;
+ QMetaType::registerConverter<MyType, QSequentialIterable>([](const MyType &) {
+ return QSequentialIterable {};
+ });
+ QMetaType::registerConverter<MyType, QVariantList>([&calledCorrectConverter](const MyType &) {
+ calledCorrectConverter = true;
+ return QVariantList {};
+ });
+ QMetaType::registerConverter<MyType, QAssociativeIterable>([](const MyType &) {
+ return QAssociativeIterable {};
+ });
+ QMetaType::registerConverter<MyType, QVariantHash>([&calledCorrectConverter](const MyType &) {
+ calledCorrectConverter = true;
+ return QVariantHash {};
+ });
+ QMetaType::registerConverter<MyType, QVariantMap>([&calledCorrectConverter](const MyType &) {
+ calledCorrectConverter = true;
+ return QVariantMap {};
+ });
+ auto holder = QVariant::fromValue(MyType {});
+
+ QVERIFY(holder.canConvert<QSequentialIterable>());
+ QVERIFY(holder.canConvert<QVariantList>());
+ QVERIFY(holder.canConvert<QAssociativeIterable>());
+ QVERIFY(holder.canConvert<QVariantHash>());
+ QVERIFY(holder.canConvert<QVariantMap>());
+
+ holder.value<QVariantList>();
+ QVERIFY(calledCorrectConverter);
+ calledCorrectConverter = false;
+
+ holder.value<QVariantHash>();
+ QVERIFY(calledCorrectConverter);
+ calledCorrectConverter = false;
+
+ holder.value<QVariantMap>();
+ QVERIFY(calledCorrectConverter);
+}
+
+struct MyTypeView
+{
+ MyType *data;
+};
+
+void tst_QVariant::mutableView()
+{
+ bool calledView = false;
+ const bool success = QMetaType::registerMutableView<MyType, MyTypeView>([&](MyType &data) {
+ calledView = true;
+ return MyTypeView { &data };
+ });
+ QVERIFY(success);
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "Mutable view on type already registered from type MyType to type MyTypeView");
+ const bool shouldFail = QMetaType::registerMutableView<MyType, MyTypeView>([&](MyType &) {
+ return MyTypeView { nullptr };
+ });
+ QVERIFY(!shouldFail);
+
+ auto original = QVariant::fromValue(MyType {});
+
+ QVERIFY(original.canView<MyTypeView>());
+ QVERIFY(!original.canConvert<MyTypeView>());
+
+ MyTypeView view = original.view<MyTypeView>();
+ QVERIFY(calledView);
+ const char *txt = "lll";
+ view.data->number = 113;
+ view.data->text = txt;
+
+ MyType extracted = original.view<MyType>();
+ QCOMPARE(extracted.number, 0);
+ QCOMPARE(extracted.text, nullptr);
+}
+
+template<typename T>
+void tst_QVariant::canViewAndView_ReturnFalseAndDefault_WhenConvertingBetweenPointerAndValue_impl(
+ const QByteArray &typeName)
+{
+ T instance{};
+
+ // Value -> Pointer
+ QVariant value = QVariant::fromValue(instance);
+ QVERIFY2(!value.canView<T *>(), typeName);
+ QCOMPARE(value.view<T *>(), nullptr); // Expect default constructed pointer
+
+ // Pointer -> Value
+ QVariant pointer = QVariant::fromValue(&instance);
+ QVERIFY2(!pointer.canView<T>(), typeName);
+ QCOMPARE(pointer.view<T>(), T{}); // Expect default constructed. Note: Weak test since instance
+ // is default constructed, but we detect data corruption
+}
+
+void tst_QVariant::canViewAndView_ReturnFalseAndDefault_WhenConvertingBetweenPointerAndValue()
+{
+#define ADD_TEST_IMPL(typeName, typeNameId, realType) \
+ canViewAndView_ReturnFalseAndDefault_WhenConvertingBetweenPointerAndValue_impl<realType>( \
+ #typeName);
+
+ // Add tests for static primitive types
+ QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(ADD_TEST_IMPL)
+
+ // Add tests for static core types
+ QT_FOR_EACH_STATIC_CORE_CLASS(ADD_TEST_IMPL)
+#undef ADD_TEST_IMPL
+}
+
+struct MoveTester
+{
+ bool wasMoved = false;
+ MoveTester() = default;
+ MoveTester(const MoveTester &) {}; // non-trivial on purpose
+ MoveTester(MoveTester &&other) { other.wasMoved = true; }
+ MoveTester& operator=(const MoveTester &) = default;
+ MoveTester& operator=(MoveTester &&other) {other.wasMoved = true; return *this;}
+};
+
+void tst_QVariant::moveOperations()
+{
+ {
+ QString str = "Hello";
+ auto v = QVariant::fromValue(str);
+ QVariant v2(std::move(v));
+ QCOMPARE(v2.toString(), str);
+
+ v = QVariant::fromValue(str);
+ v2 = std::move(v);
+ QCOMPARE(v2.toString(), str);
+ }
+
+ std::list<int> list;
+ auto v = QVariant::fromValue(list);
+ QVariant v2(std::move(v));
+ QVERIFY(v2.value<std::list<int>>() == list);
+
+ v = QVariant::fromValue(list);
+ v2 = std::move(v);
+ QVERIFY(v2.value<std::list<int>>() == list);
+
+ {
+ MoveTester tester;
+ QVariant::fromValue(tester);
+ QVERIFY(!tester.wasMoved);
+ QVariant::fromValue(std::move(tester));
+ QVERIFY(tester.wasMoved);
+ }
+ {
+ const MoveTester tester;
+ QVariant::fromValue(std::move(tester));
+ QVERIFY(!tester.wasMoved); // we don't want to move from const variables
+ }
+ {
+ QVariant var(std::in_place_type<MoveTester>);
+ const auto p = get_if<MoveTester>(&var);
+ QVERIFY(p);
+ auto &tester = *p;
+ QVERIFY(!tester.wasMoved);
+ [[maybe_unused]] auto copy = var.value<MoveTester>();
+ QVERIFY(!tester.wasMoved);
+ [[maybe_unused]] auto moved = std::move(var).value<MoveTester>();
+ QVERIFY(tester.wasMoved);
+ }
+}
+
+class NoMetaObject : public QObject {};
+void tst_QVariant::equalsWithoutMetaObject()
+{
+ using T = NoMetaObject*;
+ QtPrivate::QMetaTypeInterface d = {
+ /*.revision=*/ 0,
+ /*.alignment=*/ alignof(T),
+ /*.size=*/ sizeof(T),
+ /*.flags=*/ QtPrivate::QMetaTypeTypeFlags<T>::Flags,
+ /*.typeId=*/ 0,
+ /*.metaObject=*/ nullptr, // on purpose.
+ /*.name=*/ "NoMetaObject*",
+ /*.defaultCtr=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr) {
+ new (addr) T();
+ },
+ /*.copyCtr=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr, const void *other) {
+ new (addr) T(*reinterpret_cast<const T *>(other));
+ },
+ /*.moveCtr=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr, void *other) {
+ new (addr) T(std::move(*reinterpret_cast<T *>(other)));
+ },
+ /*.dtor=*/ [](const QtPrivate::QMetaTypeInterface *, void *addr) {
+ reinterpret_cast<T *>(addr)->~T();
+ },
+ /*.equals*/ nullptr,
+ /*.lessThan*/ nullptr,
+ /*.debugStream=*/ nullptr,
+ /*.dataStreamOut=*/ nullptr,
+ /*.dataStreamIn=*/ nullptr,
+ /*.legacyRegisterOp=*/ nullptr
+ };
+
+ QMetaType noMetaObjectMetaType(&d);
+ QMetaType qobjectMetaType = QMetaType::fromType<tst_QVariant*>();
+
+ QVERIFY(noMetaObjectMetaType.flags() & QMetaType::PointerToQObject);
+ QVERIFY(qobjectMetaType.flags() & QMetaType::PointerToQObject);
+
+ QVariant noMetaObjectVariant(noMetaObjectMetaType, nullptr);
+ QVariant qobjectVariant(qobjectMetaType, nullptr);
+
+ // Shouldn't crash
+ QVERIFY(noMetaObjectVariant != qobjectVariant);
+ QVERIFY(qobjectVariant != noMetaObjectVariant);
+}
+
+struct NonDefaultConstructible
+{
+ NonDefaultConstructible(int i) :i(i) {}
+ int i;
+ friend bool operator==(NonDefaultConstructible l, NonDefaultConstructible r)
+ { return l.i == r.i; }
+};
+
+template <> char *QTest::toString<NonDefaultConstructible>(const NonDefaultConstructible &ndc)
+{
+ return qstrdup('{' + QByteArray::number(ndc.i) + '}');
+}
+
+struct Indestructible
+{
+ Indestructible() {}
+ Indestructible(const Indestructible &) {}
+ Indestructible &operator=(const Indestructible &) { return *this; }
+private:
+ ~Indestructible() {}
+};
+
+struct NotCopyable
+{
+ NotCopyable() = default;
+ NotCopyable(const NotCopyable&) = delete;
+ NotCopyable &operator=(const NotCopyable &) = delete;
+};
+
+void tst_QVariant::constructFromIncompatibleMetaType_data()
+{
+ QTest::addColumn<QMetaType>("type");
+ auto addRow = [](QMetaType meta) {
+ QTest::newRow(meta.name()) << meta;
+ };
+ addRow(QMetaType::fromType<void>());
+ addRow(QMetaType::fromType<NonDefaultConstructible>());
+ addRow(QMetaType::fromType<QObject>());
+ addRow(QMetaType::fromType<Indestructible>());
+ addRow(QMetaType::fromType<NotCopyable>());
+}
+
+void tst_QVariant::constructFromIncompatibleMetaType()
+{
+ QFETCH(QMetaType, type);
+ const auto anticipate = [type]() {
+ // In that case, we run into a different condition (size == 0), and do not warn
+ if (type == QMetaType::fromType<NonDefaultConstructible>()) {
+ QTest::ignoreMessage(QtWarningMsg,
+ "QVariant: Cannot create type 'NonDefaultConstructible' without a "
+ "default constructor");
+ } else if (type != QMetaType::fromType<void>()) {
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "QVariant: Provided metatype for '" + QByteArray(type.name()) +
+ "' does not support destruction and copy construction");
+ }
+ };
+ anticipate();
+ QVariant var(type, nullptr);
+ QVERIFY(!var.isValid());
+ QVERIFY(!var.metaType().isValid());
+
+ anticipate();
+ QVariant regular(1.0);
+ QVERIFY(!var.canView(type));
+ QVERIFY(!var.canConvert(type));
+ QVERIFY(!QVariant(regular).convert(type));
+}
+
+void tst_QVariant::constructFromQtLT65MetaType()
+{
+ auto qsizeIface = QtPrivate::qMetaTypeInterfaceForType<QSize>();
+
+ QtPrivate::QMetaTypeInterface qsize64Iface = {
+ /*revision*/0,
+ 8,
+ 8,
+ QMetaType::NeedsConstruction | QMetaType::NeedsDestruction,
+ 0,
+ qsizeIface->metaObjectFn,
+ "FakeQSize",
+ qsizeIface->defaultCtr,
+ qsizeIface->copyCtr,
+ qsizeIface->moveCtr,
+ /*dtor =*/ nullptr,
+ qsizeIface->equals,
+ qsizeIface->lessThan,
+ qsizeIface->debugStream,
+ qsizeIface->dataStreamOut,
+ qsizeIface->dataStreamIn,
+ /*legacyregop =*/ nullptr
+ };
+ QVariant var{ QMetaType(&qsize64Iface) };
+ QVERIFY(var.isValid());
+}
+
+void tst_QVariant::copyNonDefaultConstructible()
+{
+ NonDefaultConstructible ndc(42);
+ QVariant var = QVariant::fromValue(ndc);
+ QVERIFY(var.isDetached());
+ QCOMPARE(var.metaType(), QMetaType::fromType<NonDefaultConstructible>());
+ QVERIFY(var.constData() != &ndc);
+
+ // qvariant_cast<T> and QVariant::value<T> don't compile
+ QCOMPARE(get<NonDefaultConstructible>(std::as_const(var)), ndc);
+
+ QVariant var2 = var;
+ var2.detach(); // force another copy
+ QVERIFY(var2.isDetached());
+ QVERIFY(var2.constData() != var.constData());
+ QCOMPARE(get<NonDefaultConstructible>(std::as_const(var2)),
+ get<NonDefaultConstructible>(std::as_const(var)));
+ QCOMPARE(var2, var);
+}
+
+void tst_QVariant::inplaceConstruct()
+{
+ {
+ NonDefaultConstructible ndc(42);
+ QVariant var(std::in_place_type<NonDefaultConstructible>, 42);
+ QVERIFY(get_if<NonDefaultConstructible>(&var));
+ QCOMPARE(get<NonDefaultConstructible>(var), ndc);
+ }
+
+ {
+ std::vector<int> vec {1, 2, 3, 4};
+ QVariant var(std::in_place_type<std::vector<int>>, {1, 2, 3, 4});
+ QVERIFY(get_if<std::vector<int>>(&var));
+ QCOMPARE(get<std::vector<int>>(var), vec);
+ }
+}
+
+struct LargerThanInternalQVariantStorage {
+ char data[6 * sizeof(void *)];
+};
+
+struct alignas(256) LargerThanInternalQVariantStorageOveraligned {
+ char data[6 * sizeof(void *)];
+};
+
+struct alignas(128) SmallerAlignmentEvenLargerSize {
+ char data[17 * sizeof(void *)];
+};
+
+void tst_QVariant::emplace()
+{
+ {
+ // can emplace non default constructible + can emplace on null variant
+ NonDefaultConstructible ndc(42);
+ QVariant var;
+ var.emplace<NonDefaultConstructible>(42);
+ QVERIFY(get_if<NonDefaultConstructible>(&var));
+ QCOMPARE(get<NonDefaultConstructible>(var), ndc);
+ }
+ {
+ // can emplace using ctor taking initializer_list
+ QVariant var;
+ var.emplace<std::vector<int>>({0, 1, 2, 3, 4});
+ auto vecPtr = get_if<std::vector<int>>(&var);
+ QVERIFY(vecPtr);
+ QCOMPARE(vecPtr->size(), 5U);
+ for (int i = 0; i < 5; ++i)
+ QCOMPARE(vecPtr->at(size_t(i)), i);
+ }
+ // prequisites for the test
+ QCOMPARE_LE(sizeof(std::vector<int>), sizeof(std::string));
+ QCOMPARE(alignof(std::vector<int>), alignof(std::string));
+ {
+ // emplace can reuse storage
+ auto var = QVariant::fromValue(std::string{});
+ QVERIFY(var.data_ptr().is_shared);
+ auto data = var.constData();
+ std::vector<int> &vec = var.emplace<std::vector<int>>(3, 42);
+ /* alignment is the same, so the pointer is exactly the same;
+ no offset change */
+ auto expected = std::vector<int>{42, 42, 42};
+ QCOMPARE(get_if<std::vector<int>>(&var), &vec);
+ QCOMPARE(get<std::vector<int>>(var), expected);
+ QCOMPARE(var.constData(), data);
+ }
+ {
+ // emplace can't reuse storage if the variant is shared
+ auto var = QVariant::fromValue(std::string{});
+ [[maybe_unused]] QVariant causesSharing = var;
+ QVERIFY(var.data_ptr().is_shared);
+ auto data = var.constData();
+ var.emplace<std::vector<int>>(3, 42);
+ auto expected = std::vector<int>{42, 42, 42};
+ QVERIFY(get_if<std::vector<int>>(&var));
+ QCOMPARE(get<std::vector<int>>(var), expected);
+ QCOMPARE_NE(var.constData(), data);
+ }
+ {
+ // emplace puts element into the correct place - non-shared
+ QVERIFY(QVariant::Private::canUseInternalSpace(QMetaType::fromType<QString>().iface()));
+ QVariant var;
+ var.emplace<QString>(QChar('x'));
+ QVERIFY(!var.data_ptr().is_shared);
+ }
+ {
+ // emplace puts element into the correct place - shared
+ QVERIFY(!QVariant::Private::canUseInternalSpace(QMetaType::fromType<std::string>().iface()));
+ QVariant var;
+ var.emplace<std::string>(42, 'x');
+ QVERIFY(var.data_ptr().is_shared);
+ }
+ {
+ // emplace does not reuse the storage if alignment is too large
+ auto iface = QMetaType::fromType<LargerThanInternalQVariantStorage>().iface();
+ QVERIFY(!QVariant::Private::canUseInternalSpace(iface));
+ auto var = QVariant::fromValue(LargerThanInternalQVariantStorage{});
+ auto data = var.constData();
+ var.emplace<LargerThanInternalQVariantStorageOveraligned>();
+ QCOMPARE_NE(var.constData(), data);
+ }
+ {
+ // emplace does reuse the storage if new alignment and size are together small enough
+ auto iface = QMetaType::fromType<LargerThanInternalQVariantStorageOveraligned>().iface();
+ QVERIFY(!QVariant::Private::canUseInternalSpace(iface));
+ auto var = QVariant::fromValue(LargerThanInternalQVariantStorageOveraligned{});
+ auto data = var.constData();
+ var.emplace<SmallerAlignmentEvenLargerSize>();
+ // no exact match below - the alignment is after all different
+ QCOMPARE_LE(quintptr(var.constData()), quintptr(data));
+ QCOMPARE_LE(quintptr(var.constData()),
+ quintptr(data) + sizeof(LargerThanInternalQVariantStorageOveraligned));
+ }
+}
+
+void tst_QVariant::getIf_NonDefaultConstructible()
+{
+ getIf_impl(NonDefaultConstructible{42});
+}
+
+void tst_QVariant::getIfSpecial()
+{
+ QVariant v{QString{}}; // used to be a null QVariant in Qt 5
+ QCOMPARE_NE(get_if<QString>(&v), nullptr); // not anymore...
+}
+
+void tst_QVariant::get_NonDefaultConstructible()
+{
+ get_impl(NonDefaultConstructible{42});
+}
+
+template <typename T>
+T mutate(const T &t) { return t + t; }
+template <>
+NonDefaultConstructible mutate(const NonDefaultConstructible &t)
+{
+ return NonDefaultConstructible{t.i + t.i};
+}
+
+template <typename T>
+QVariant make_null_QVariant_of_type()
+{
+ return QVariant(QMetaType::fromType<T>());
+}
+
+template <typename T>
+void tst_QVariant::getIf_impl(T t) const
+{
+ QVariant v = QVariant::fromValue(t);
+
+ QVariant null;
+ QVERIFY(null.isNull());
+
+ [[maybe_unused]]
+ QVariant nulT;
+ if constexpr (std::is_default_constructible_v<T>) {
+ // typed null QVariants don't work with non-default-constuctable types
+ nulT = make_null_QVariant_of_type<T>();
+ QVERIFY(nulT.isNull());
+ }
+
+ QVariant date = QDate(2023, 3, 3);
+ static_assert(!std::is_same_v<T, QDate>);
+
+ // for behavioral comparison:
+ StdVariant stdn = {}, stdv = t;
+
+ // returns nullptr on type mismatch:
+ {
+ // const
+ QCOMPARE_EQ(get_if<T>(&std::as_const(stdn)), nullptr);
+ QCOMPARE_EQ(get_if<T>(&std::as_const(date)), nullptr);
+ // mutable
+ QCOMPARE_EQ(get_if<T>(&stdn), nullptr);
+ QCOMPARE_EQ(get_if<T>(&date), nullptr);
+ }
+
+ // returns nullptr on null variant (QVariant only):
+ {
+ QCOMPARE_EQ(get_if<T>(&std::as_const(null)), nullptr);
+ QCOMPARE_EQ(get_if<T>(&null), nullptr);
+ if constexpr (std::is_default_constructible_v<T>) {
+ // const access return nullptr
+ QCOMPARE_EQ(get_if<T>(&std::as_const(nulT)), nullptr);
+ // but mutable access makes typed null QVariants non-null (like data())
+ QCOMPARE_NE(get_if<T>(&nulT), nullptr);
+ QVERIFY(!nulT.isNull());
+ nulT = make_null_QVariant_of_type<T>(); // reset to null state
+ }
+ }
+
+ // const access:
+ {
+ auto ps = get_if<T>(&std::as_const(stdv));
+ static_assert(std::is_same_v<decltype(ps), const T*>);
+ QCOMPARE_NE(ps, nullptr);
+ QCOMPARE_EQ(*ps, t);
+
+ auto pv = get_if<T>(&std::as_const(v));
+ static_assert(std::is_same_v<decltype(ps), const T*>);
+ QCOMPARE_NE(pv, nullptr);
+ QCOMPARE_EQ(*pv, t);
+ }
+
+ // mutable access:
+ {
+ T t2 = mutate(t);
+
+ auto ps = get_if<T>(&stdv);
+ static_assert(std::is_same_v<decltype(ps), T*>);
+ QCOMPARE_NE(ps, nullptr);
+ QCOMPARE_EQ(*ps, t);
+ *ps = t2;
+ auto ps2 = get_if<T>(&stdv);
+ QCOMPARE_NE(ps2, nullptr);
+ QCOMPARE_EQ(*ps2, t2);
+
+ auto pv = get_if<T>(&v);
+ static_assert(std::is_same_v<decltype(pv), T*>);
+ QCOMPARE_NE(pv, nullptr);
+ QCOMPARE_EQ(*pv, t);
+ *pv = t2;
+ auto pv2 = get_if<T>(&v);
+ QCOMPARE_NE(pv2, nullptr);
+ QCOMPARE_EQ(*pv2, t2);
+
+ // typed null QVariants become non-null (data() behavior):
+ if constexpr (std::is_default_constructible_v<T>) {
+ QVERIFY(nulT.isNull());
+ auto pn = get_if<T>(&nulT);
+ QVERIFY(!nulT.isNull());
+ static_assert(std::is_same_v<decltype(pn), T*>);
+ QCOMPARE_NE(pn, nullptr);
+ QCOMPARE_EQ(*pn, T{});
+ *pn = t2;
+ auto pn2 = get_if<T>(&nulT);
+ QCOMPARE_NE(pn2, nullptr);
+ QCOMPARE_EQ(*pn2, t2);
+ }
+ }
+}
+
+template <typename T>
+void tst_QVariant::get_impl(T t) const
+{
+ QVariant v = QVariant::fromValue(t);
+
+ // for behavioral comparison:
+ StdVariant stdv = t;
+
+ #define FOR_EACH_CVREF(op) \
+ op(/*unadorned*/, &&) \
+ op(&, &) \
+ op(&&, &&) \
+ op(const, const &&) \
+ op(const &, const &) \
+ op(const &&, const &&) \
+ /* end */
+
+
+ #define CHECK_RETURN_TYPE_OF(Variant, cvref_in, cvref_out) \
+ static_assert(std::is_same_v< \
+ decltype(get<T>(std::declval<Variant cvref_in >())), \
+ T cvref_out \
+ >); \
+ /* end */
+ #define CHECK_RETURN_TYPE(cvref_in, cvref_out) \
+ CHECK_RETURN_TYPE_OF(StdVariant, cvref_in, cvref_out) \
+ CHECK_RETURN_TYPE_OF(QVariant, cvref_in, cvref_out) \
+ /* end */
+ FOR_EACH_CVREF(CHECK_RETURN_TYPE)
+ #undef CHECK_RETURN_TYPE
+
+ #undef FOR_EACH_CVREF
+
+ // const access:
+ {
+ auto &&rs = get<T>(std::as_const(stdv));
+ QCOMPARE_EQ(rs, t);
+
+ auto &&rv = get<T>(std::as_const(v));
+ QCOMPARE_EQ(rv, t);
+ }
+
+ // mutable access:
+ {
+ T t2 = mutate(t);
+
+ auto &&rs = get<T>(stdv);
+ QCOMPARE_EQ(rs, t);
+ rs = t2;
+ auto &&rs2 = get<T>(stdv);
+ QCOMPARE_EQ(rs2, t2);
+
+ auto &&rv = get<T>(v);
+ QCOMPARE_EQ(rv, t);
+ rv = t2;
+ auto &&rv2 = get<T>(v);
+ QCOMPARE_EQ(rv2, t2);
}
-#endif
}
QTEST_MAIN(tst_QVariant)
diff --git a/tests/auto/corelib/kernel/qwineventnotifier/CMakeLists.txt b/tests/auto/corelib/kernel/qwineventnotifier/CMakeLists.txt
new file mode 100644
index 0000000000..81b2c9a58c
--- /dev/null
+++ b/tests/auto/corelib/kernel/qwineventnotifier/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qwineventnotifier Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qwineventnotifier LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qwineventnotifier
+ SOURCES
+ tst_qwineventnotifier.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/kernel/qwineventnotifier/qwineventnotifier.pro b/tests/auto/corelib/kernel/qwineventnotifier/qwineventnotifier.pro
deleted file mode 100644
index 20ec7572fb..0000000000
--- a/tests/auto/corelib/kernel/qwineventnotifier/qwineventnotifier.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qwineventnotifier
-QT = core-private testlib
-SOURCES = tst_qwineventnotifier.cpp
diff --git a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
index ac8aaa1327..bf08f85fb5 100644
--- a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
+++ b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
@@ -1,36 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qwineventnotifier.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QTestEventLoop>
+
+#include <qlist.h>
#include <qtimer.h>
#include <qvarlengtharray.h>
-#include <qvector.h>
+#include <qwineventnotifier.h>
#include <qt_windows.h>
#include <algorithm>
@@ -208,7 +185,7 @@ void tst_QWinEventNotifier::manyNotifiers()
}));
}
-using Indices = QVector<int>;
+using Indices = QList<int>;
void tst_QWinEventNotifier::disableNotifiersInActivatedSlot_data()
{
diff --git a/tests/auto/corelib/kernel/qwinregistrykey/.gitignore b/tests/auto/corelib/kernel/qwinregistrykey/.gitignore
new file mode 100644
index 0000000000..3d888e2868
--- /dev/null
+++ b/tests/auto/corelib/kernel/qwinregistrykey/.gitignore
@@ -0,0 +1 @@
+tst_qwinregistrykey
diff --git a/tests/auto/corelib/kernel/qwinregistrykey/CMakeLists.txt b/tests/auto/corelib/kernel/qwinregistrykey/CMakeLists.txt
new file mode 100644
index 0000000000..aeda6f0033
--- /dev/null
+++ b/tests/auto/corelib/kernel/qwinregistrykey/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qwinregistrykey LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qwinregistrykey
+ SOURCES
+ tst_qwinregistrykey.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/kernel/qwinregistrykey/tst_qwinregistrykey.cpp b/tests/auto/corelib/kernel/qwinregistrykey/tst_qwinregistrykey.cpp
new file mode 100644
index 0000000000..a5dca8a3d5
--- /dev/null
+++ b/tests/auto/corelib/kernel/qwinregistrykey/tst_qwinregistrykey.cpp
@@ -0,0 +1,242 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QObject>
+#include <QPair>
+#include <QScopeGuard>
+#include <private/qwinregistry_p.h>
+#include <qt_windows.h>
+
+using namespace Qt::StringLiterals;
+
+static constexpr const wchar_t TEST_KEY[] = LR"(SOFTWARE\tst_qwinregistrykey)";
+
+static const QPair<QStringView, QString> TEST_STRING = qMakePair(u"string", u"string"_s);
+static const QPair<QStringView, QString> TEST_STRING_NULL = qMakePair(u"string_null", QString());
+static const QPair<QStringView, QStringList> TEST_STRINGLIST = qMakePair(u"stringlist", QStringList{ u"element1"_s, u"element2"_s, u"element3"_s });
+static const QPair<QStringView, QStringList> TEST_STRINGLIST_NULL = qMakePair(u"stringlist_null", QStringList());
+static const QPair<QStringView, quint32> TEST_DWORD = qMakePair(u"dword", 123);
+static const QPair<QStringView, quint64> TEST_QWORD = qMakePair(u"qword", 456);
+static const QPair<QStringView, QByteArray> TEST_BINARY = qMakePair(u"binary", "binary\0"_ba);
+static const QPair<QStringView, QVariant> TEST_NOT_EXIST = qMakePair(u"not_exist", QVariant());
+static const QPair<QStringView, QVariant> TEST_DEFAULT = qMakePair(u"", u"default"_s);
+
+[[nodiscard]] static inline bool write(const HKEY key, const QStringView name, const QVariant &value)
+{
+ DWORD type = REG_NONE;
+ QByteArray buf = {};
+
+ switch (value.typeId()) {
+ case QMetaType::QStringList: {
+ // If none of the elements contains '\0', we can use REG_MULTI_SZ, the
+ // native registry string list type. Otherwise we use REG_BINARY.
+ type = REG_MULTI_SZ;
+ const QStringList list = value.toStringList();
+ for (auto it = list.constBegin(); it != list.constEnd(); ++it) {
+ if ((*it).length() == 0 || it->contains(QChar::Null)) {
+ type = REG_BINARY;
+ break;
+ }
+ }
+
+ if (type == REG_BINARY) {
+ const QString str = value.toString();
+ buf = QByteArray(reinterpret_cast<const char *>(str.data()), str.length() * 2);
+ } else {
+ for (auto it = list.constBegin(); it != list.constEnd(); ++it) {
+ const QString &str = *it;
+ buf += QByteArray(reinterpret_cast<const char *>(str.utf16()), (str.length() + 1) * 2);
+ }
+ // According to Microsoft Docs, REG_MULTI_SZ requires double '\0'.
+ buf.append((char)0);
+ buf.append((char)0);
+ }
+ break;
+ }
+
+ case QMetaType::Int:
+ case QMetaType::UInt: {
+ type = REG_DWORD;
+ quint32 num = value.toUInt();
+ buf = QByteArray(reinterpret_cast<const char *>(&num), sizeof(quint32));
+ break;
+ }
+
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong: {
+ type = REG_QWORD;
+ quint64 num = value.toULongLong();
+ buf = QByteArray(reinterpret_cast<const char *>(&num), sizeof(quint64));
+ break;
+ }
+
+ case QMetaType::QByteArray:
+ default: {
+ // If the string does not contain '\0', we can use REG_SZ, the native registry
+ // string type. Otherwise we use REG_BINARY.
+ const QString str = value.toString();
+ type = str.contains(QChar::Null) ? REG_BINARY : REG_SZ;
+ int length = str.length();
+ if (type == REG_SZ)
+ ++length;
+ buf = QByteArray(reinterpret_cast<const char *>(str.utf16()), sizeof(wchar_t) * length);
+ break;
+ }
+ }
+
+ const LONG ret = RegSetValueExW(key, reinterpret_cast<const wchar_t *>(name.utf16()),
+ 0, type, reinterpret_cast<LPBYTE>(buf.data()), buf.size());
+ return ret == ERROR_SUCCESS;
+}
+
+class tst_qwinregistrykey : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void qwinregistrykey();
+
+private:
+ bool m_available = false;
+};
+
+void tst_qwinregistrykey::initTestCase()
+{
+ HKEY key = nullptr;
+ const LONG ret = RegCreateKeyExW(HKEY_CURRENT_USER, TEST_KEY, 0, nullptr, 0,
+ KEY_READ | KEY_WRITE, nullptr, &key, nullptr);
+ if (ret != ERROR_SUCCESS)
+ return;
+ const auto cleanup = qScopeGuard([key](){ RegCloseKey(key); });
+ if (!write(key, TEST_STRING.first, TEST_STRING.second))
+ return;
+ if (!write(key, TEST_STRING_NULL.first, TEST_STRING_NULL.second))
+ return;
+ if (!write(key, TEST_STRINGLIST.first, TEST_STRINGLIST.second))
+ return;
+ if (!write(key, TEST_STRINGLIST_NULL.first, TEST_STRINGLIST_NULL.second))
+ return;
+ if (!write(key, TEST_DWORD.first, TEST_DWORD.second))
+ return;
+ if (!write(key, TEST_QWORD.first, TEST_QWORD.second))
+ return;
+ if (!write(key, TEST_BINARY.first, TEST_BINARY.second))
+ return;
+ if (!write(key, TEST_DEFAULT.first, TEST_DEFAULT.second))
+ return;
+ m_available = true;
+}
+
+void tst_qwinregistrykey::cleanupTestCase()
+{
+ HKEY key = nullptr;
+ const LONG ret = RegOpenKeyExW(HKEY_CURRENT_USER, TEST_KEY, 0, KEY_READ | KEY_WRITE, &key);
+ if (ret != ERROR_SUCCESS)
+ return;
+ #define C_STR(View) reinterpret_cast<const wchar_t *>(View.utf16())
+ RegDeleteValueW(key, C_STR(TEST_STRING.first));
+ RegDeleteValueW(key, C_STR(TEST_STRING_NULL.first));
+ RegDeleteValueW(key, C_STR(TEST_STRINGLIST.first));
+ RegDeleteValueW(key, C_STR(TEST_STRINGLIST_NULL.first));
+ RegDeleteValueW(key, C_STR(TEST_DWORD.first));
+ RegDeleteValueW(key, C_STR(TEST_QWORD.first));
+ RegDeleteValueW(key, C_STR(TEST_BINARY.first));
+ RegDeleteValueW(key, C_STR(TEST_DEFAULT.first));
+ #undef C_STR
+ RegDeleteKeyW(HKEY_CURRENT_USER, TEST_KEY);
+ RegCloseKey(key);
+}
+
+void tst_qwinregistrykey::qwinregistrykey()
+{
+ if (!m_available)
+ QSKIP("The test data is not ready.");
+
+ QWinRegistryKey registry(HKEY_CURRENT_USER, TEST_KEY);
+
+ QVERIFY(registry.isValid());
+
+ QVERIFY(registry.handle() != nullptr);
+
+ {
+ const auto value = registry.value<QString>(TEST_STRING.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(QString()), TEST_STRING.second);
+ }
+
+ {
+ const auto value = registry.value<QString>(TEST_STRING_NULL.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(QString()), TEST_STRING_NULL.second);
+
+ }
+
+ {
+ const auto value = registry.value<QStringList>(TEST_STRINGLIST.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(QStringList()), TEST_STRINGLIST.second);
+ }
+
+ {
+ const auto value = registry.value<QStringList>(TEST_STRINGLIST_NULL.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(QStringList()), TEST_STRINGLIST_NULL.second);
+ }
+
+ {
+ const auto value = registry.value<quint32>(TEST_DWORD.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(0), TEST_DWORD.second);
+ }
+
+ {
+ const auto value = registry.value<quint64>(TEST_QWORD.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(0), TEST_QWORD.second);
+ }
+
+ {
+ const auto value = registry.value<QByteArray>(TEST_BINARY.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(QByteArray()), TEST_BINARY.second);
+ }
+
+ {
+ const auto value = registry.value<QVariant>(TEST_NOT_EXIST.first);
+ QVERIFY(!value.has_value());
+ QCOMPARE(value.value_or(QVariant()), QVariant());
+ }
+
+ {
+ const auto value = registry.value<QString>(TEST_DEFAULT.first);
+ QVERIFY(value.has_value());
+ QCOMPARE(value.value_or(QString()), TEST_DEFAULT.second);
+ }
+
+ {
+ const QString value = registry.stringValue(TEST_STRING.first);
+ QVERIFY(!value.isEmpty());
+ QCOMPARE(value, TEST_STRING.second);
+ }
+
+ QVERIFY(registry.stringValue(TEST_NOT_EXIST.first).isEmpty());
+
+ {
+ const auto value = registry.dwordValue(TEST_DWORD.first);
+ QVERIFY(value.second);
+ QCOMPARE(value.first, TEST_DWORD.second);
+ }
+
+ {
+ const auto value = registry.dwordValue(TEST_NOT_EXIST.first);
+ QVERIFY(!value.second);
+ QCOMPARE(value.first, DWORD(0));
+ }
+}
+
+QTEST_MAIN(tst_qwinregistrykey)
+
+#include "tst_qwinregistrykey.moc"
diff --git a/tests/auto/corelib/mimetypes/CMakeLists.txt b/tests/auto/corelib/mimetypes/CMakeLists.txt
new file mode 100644
index 0000000000..e8c842a410
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(QT_FEATURE_private_tests)
+ add_subdirectory(qmimetype)
+endif()
+add_subdirectory(qmimedatabase)
diff --git a/tests/auto/corelib/mimetypes/mimetypes.pro b/tests/auto/corelib/mimetypes/mimetypes.pro
deleted file mode 100644
index 9dd091374f..0000000000
--- a/tests/auto/corelib/mimetypes/mimetypes.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TEMPLATE=subdirs
-
-SUBDIRS = \
- qmimetype \
- qmimedatabase
-
-!qtConfig(private_tests): SUBDIRS -= \
- qmimetype
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/CMakeLists.txt
new file mode 100644
index 0000000000..26aab786c2
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(TARGET Qt::Concurrent)
+ add_subdirectory(qmimedatabase-xml)
+endif()
+if(TARGET Qt::Concurrent AND UNIX AND NOT APPLE AND NOT QNX)
+ add_subdirectory(qmimedatabase-cache)
+endif()
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml b/tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml
new file mode 100644
index 0000000000..c4141e0f70
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="image/jpeg">
+ <glob pattern="*.jnewext"/>
+ <comment>JPEG Image</comment>
+ </mime-type>
+</mime-info>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml b/tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml
new file mode 100644
index 0000000000..466f039803
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="application/ecmascript">
+ <comment>It's more accurate to say that ECMAScript is a subset of JavaScript</comment>
+ <sub-class-of type="text/javascript"/>
+ <glob pattern="*.js"/>
+ </mime-type>
+ <mime-type type="text/javascript">
+ <comment>than to say that JavaScript is a subset of ECMAScript</comment>
+ <sub-class-of type="application/ecmascript"/>
+ <glob pattern="*.js"/>
+ </mime-type>
+</mime-info>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt
new file mode 100644
index 0000000000..a267640a50
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt
@@ -0,0 +1,86 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmimedatabase LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if(NOT QT_FEATURE_private_tests)
+ return()
+endif()
+
+#####################################################################
+## tst_qmimedatabase-cache Test:
+#####################################################################
+
+qt_internal_add_test(tst_qmimedatabase-cache
+ SOURCES
+ ../tst_qmimedatabase.h
+ tst_qmimedatabase-cache.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Concurrent
+)
+
+# Resources:
+# the freedesktop resources are handled manually below via mimetypes_resources.cmake
+#set(mimetypes_resource_files
+ #"mime/packages/freedesktop.org.xml"
+#)
+set(testdata_resource_files
+ "../add-extension.xml"
+ "../circular-inheritance.xml"
+ "../invalid-magic1.xml"
+ "../invalid-magic2.xml"
+ "../invalid-magic3.xml"
+ "../magic-and-hierarchy.foo"
+ "../magic-and-hierarchy.xml"
+ "../magic-and-hierarchy2.foo"
+ "../qml-again.xml"
+ "../test.qml"
+ "../text-x-objcsrc.xml"
+ "../text-plain-subclass.xml"
+ "../webm-glob-deleteall.xml"
+ "../yast2-metapackage-handler-mimetypes.xml"
+)
+
+qt_internal_add_resource(tst_qmimedatabase-cache "testdata"
+ PREFIX
+ "/qt-project.org/qmime"
+ BASE
+ ".."
+ FILES
+ ${testdata_resource_files}
+)
+
+qt_internal_add_resource(tst_qmimedatabase-cache "testfiles"
+ PREFIX
+ "/files"
+ FILES
+ "../test.txt"
+ "../test.qml"
+)
+
+set(corelib_source_dir ../../../../../../src/corelib)
+include(${corelib_source_dir}/mimetypes/mimetypes_resources.cmake)
+corelib_add_mimetypes_resources(tst_qmimedatabase-cache)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qmimedatabase-cache CONDITION GCC
+ COMPILE_OPTIONS
+ -W
+ -Wall
+ -Wextra
+ -Wno-long-long
+ -Wnon-virtual-dtor
+ -Wshadow
+)
+
+qt_internal_extend_target(tst_qmimedatabase-cache CONDITION UNIX AND NOT APPLE AND NOT QNX
+ DEFINES
+ USE_XDG_DATA_DIRS
+)
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
deleted file mode 100644
index 53bb012f7c..0000000000
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/qmimedatabase-cache.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-
-requires(qtConfig(private_tests))
-
-TARGET = tst_qmimedatabase-cache
-
-QT = core testlib concurrent
-
-SOURCES = tst_qmimedatabase-cache.cpp
-HEADERS = ../tst_qmimedatabase.h
-RESOURCES += $$QT_SOURCE_TREE/src/corelib/mimetypes/mimetypes.qrc
-RESOURCES += ../testdata.qrc
-
-*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Wshadow -Wno-long-long -Wnon-virtual-dtor
-
-unix:!mac:!qnx: DEFINES += USE_XDG_DATA_DIRS
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
index 529c8942b3..e923cc1d50 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/tst_qmimedatabase-cache.cpp
@@ -1,36 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "../tst_qmimedatabase.h"
-#include <QDir>
-#include <QFile>
-#include <QtTest/QtTest>
-#include <qstandardpaths.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "../tst_qmimedatabase.cpp"
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt
new file mode 100644
index 0000000000..729ac3933a
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt
@@ -0,0 +1,86 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmimedatabase LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if(NOT QT_FEATURE_private_tests)
+ return()
+endif()
+
+#####################################################################
+## tst_qmimedatabase-xml Test:
+#####################################################################
+
+qt_internal_add_test(tst_qmimedatabase-xml
+ SOURCES
+ ../tst_qmimedatabase.h
+ tst_qmimedatabase-xml.cpp
+ LIBRARIES
+ Qt::Concurrent
+ Qt::CorePrivate
+)
+
+# Resources:
+# the freedesktop resources are handled manually below via mimetypes_resources.cmake
+#set(mimetypes_resource_files
+ #"mime/packages/freedesktop.org.xml"
+#)
+set(testdata_resource_files
+ "../add-extension.xml"
+ "../circular-inheritance.xml"
+ "../invalid-magic1.xml"
+ "../invalid-magic2.xml"
+ "../invalid-magic3.xml"
+ "../magic-and-hierarchy.foo"
+ "../magic-and-hierarchy.xml"
+ "../magic-and-hierarchy2.foo"
+ "../qml-again.xml"
+ "../test.qml"
+ "../text-x-objcsrc.xml"
+ "../text-plain-subclass.xml"
+ "../webm-glob-deleteall.xml"
+ "../yast2-metapackage-handler-mimetypes.xml"
+)
+
+qt_internal_add_resource(tst_qmimedatabase-xml "testdata"
+ PREFIX
+ "/qt-project.org/qmime"
+ BASE
+ ".."
+ FILES
+ ${testdata_resource_files}
+)
+
+qt_internal_add_resource(tst_qmimedatabase-xml "testfiles"
+ PREFIX
+ "/files"
+ FILES
+ "../test.txt"
+ "../test.qml"
+)
+
+set(corelib_source_dir ../../../../../../src/corelib)
+include(${corelib_source_dir}/mimetypes/mimetypes_resources.cmake)
+corelib_add_mimetypes_resources(tst_qmimedatabase-xml)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qmimedatabase-xml CONDITION GCC
+ COMPILE_OPTIONS
+ -W
+ -Wall
+ -Wextra
+ -Wno-long-long
+ -Wnon-virtual-dtor
+ -Wshadow
+)
+
+qt_internal_extend_target(tst_qmimedatabase-xml CONDITION UNIX AND NOT APPLE AND NOT QNX
+ DEFINES
+ USE_XDG_DATA_DIRS
+)
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
deleted file mode 100644
index 7b27ee4217..0000000000
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/qmimedatabase-xml.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-CONFIG += testcase
-
-requires(qtConfig(private_tests))
-
-TARGET = tst_qmimedatabase-xml
-
-QT = core testlib concurrent
-
-SOURCES += tst_qmimedatabase-xml.cpp
-HEADERS += ../tst_qmimedatabase.h
-
-RESOURCES += $$QT_SOURCE_TREE/src/corelib/mimetypes/mimetypes.qrc
-RESOURCES += ../testdata.qrc
-
-*-g++*:QMAKE_CXXFLAGS += -W -Wall -Wextra -Wshadow -Wno-long-long -Wnon-virtual-dtor
-
-unix:!mac:!qnx: DEFINES += USE_XDG_DATA_DIRS
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
index e403baf714..f86c8b8839 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/tst_qmimedatabase-xml.cpp
@@ -1,36 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include "../tst_qmimedatabase.h"
+#include "../tst_qmimedatabase.cpp"
void tst_QMimeDatabase::initTestCaseInternal()
{
qputenv("QT_NO_MIME_CACHE", "1");
}
-#include "../tst_qmimedatabase.cpp"
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
deleted file mode 100644
index f821702564..0000000000
--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = subdirs
-qtHaveModule(concurrent) {
- SUBDIRS = qmimedatabase-xml
- unix:!darwin:!qnx: SUBDIRS += qmimedatabase-cache
-}
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/test.qml b/tests/auto/corelib/mimetypes/qmimedatabase/test.qml
index 8b7437d2e6..79a6d01a1e 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/test.qml
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/test.qml
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 David Faure <faure@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2012 David Faure <faure@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick 1.1
Item {
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/test.txt b/tests/auto/corelib/mimetypes/qmimedatabase/test.txt
new file mode 100644
index 0000000000..79a6d01a1e
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/test.txt
@@ -0,0 +1,6 @@
+// Copyright (C) 2012 David Faure <faure@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick 1.1
+Item {
+}
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc
deleted file mode 100644
index 1002d0195d..0000000000
--- a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc
+++ /dev/null
@@ -1,14 +0,0 @@
-<RCC>
- <qresource prefix="/qt-project.org/qmime">
- <file alias="yast2-metapackage-handler-mimetypes.xml">yast2-metapackage-handler-mimetypes.xml</file>
- <file alias="qml-again.xml">qml-again.xml</file>
- <file alias="text-x-objcsrc.xml">text-x-objcsrc.xml</file>
- <file alias="test.qml">test.qml</file>
- <file>invalid-magic1.xml</file>
- <file>invalid-magic2.xml</file>
- <file>invalid-magic3.xml</file>
- <file>magic-and-hierarchy.xml</file>
- <file>magic-and-hierarchy.foo</file>
- <file>magic-and-hierarchy2.foo</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml b/tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml
new file mode 100644
index 0000000000..7b5cb7506d
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+ <mime-type type="text/x-microdvd">
+ <comment>MicroDVD subtitles</comment>
+ <sub-class-of type="text/plain"/>
+ <magic priority="50">
+ <match type="string" value="{1}" offset="0"/>
+ <match type="string" value="{0}" offset="0"/>
+ <match type="string" value="}{" offset="0:6"/>
+ </magic>
+ <generic-icon name="text-x-generic"/>
+ <glob pattern="*.sub"/>
+ <glob pattern="*.txt"/>
+ </mime-type>
+</mime-info>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 9df52887f7..9c7f5fa820 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -1,36 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include "tst_qmimedatabase.h"
#include <qmimedatabase.h>
#include "qstandardpaths.h"
#ifdef Q_OS_UNIX
+#include <dirent.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif
@@ -38,25 +16,44 @@
#include <QtCore/QElapsedTimer>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
+#include <QtCore/qspan.h>
#include <QtCore/QStandardPaths>
#include <QtCore/QTemporaryDir>
#include <QtCore/QTextStream>
#include <QtConcurrent/QtConcurrentRun>
+#include <QtCore/private/qduplicatetracker_p.h>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QBuffer>
+#include <QTemporaryFile>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
+
+using namespace Qt::StringLiterals;
+
+static const std::array additionalGlobalMimeFiles = {
+ "yast2-metapackage-handler-mimetypes.xml",
+ "qml-again.xml",
+ "magic-and-hierarchy.xml",
+};
-static const char *const additionalMimeFiles[] = {
+static const std::array additionalLocalMimeFiles = {
+ "add-extension.xml", // adds *.jnewext to image/jpeg
"yast2-metapackage-handler-mimetypes.xml",
"qml-again.xml",
"text-x-objcsrc.xml",
+ "text-plain-subclass.xml",
"invalid-magic1.xml",
"invalid-magic2.xml",
"invalid-magic3.xml",
"magic-and-hierarchy.xml",
- 0
+ "circular-inheritance.xml",
+ "webm-glob-deleteall.xml",
};
-#define RESOURCE_PREFIX ":/qt-project.org/qmime/"
+static const auto s_resourcePrefix = ":/qt-project.org/qmime/"_L1;
+static const auto s_inodeMimetype = "inode/directory"_L1;
void initializeLang()
{
@@ -70,15 +67,15 @@ static inline QString testSuiteWarning()
QString result;
QTextStream str(&result);
- str << "\nCannot find the shared-mime-info test suite\nstarting from: "
+ str << "\nCannot find the shared-mime-info test suite\nin the parent of: "
<< QDir::toNativeSeparators(QDir::currentPath()) << "\n"
"cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n"
- "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-8.zip\n"
- "unzip Release-1-8.zip\n";
+ "wget https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.2/shared-mime-info-2.2.zip\n"
+ "unzip shared-mime-info-2.2.zip\n";
#ifdef Q_OS_WIN
- str << "mkdir testfiles\nxcopy /s Release-1-8 s-m-i\n";
+ str << "mkdir testfiles\nxcopy /s shared-mime-info-2.2 s-m-i\n";
#else
- str << "ln -s Release-1-8 s-m-i\n";
+ str << "ln -s shared-mime-info-2.2 s-m-i\n";
#endif
return result;
}
@@ -133,7 +130,6 @@ void tst_QMimeDatabase::initTestCase()
if (QDir(m_localMimeDir).exists()) {
QVERIFY2(QDir(m_localMimeDir).removeRecursively(), qPrintable(m_localMimeDir + ": " + qt_error_string()));
}
- QString errorMessage;
#ifdef USE_XDG_DATA_DIRS
// Create a temporary "global" XDG data dir for later use
@@ -149,23 +145,16 @@ void tst_QMimeDatabase::initTestCase()
qDebug() << "\nGlobal XDG_DATA_DIRS: " << m_globalXdgDir;
const QString freeDesktopXml = QStringLiteral("freedesktop.org.xml");
- const QString xmlFileName = QLatin1String(RESOURCE_PREFIX "packages/") + freeDesktopXml;
+ const QString xmlFileName = s_resourcePrefix + "packages/"_L1 + freeDesktopXml;
const QString xmlTargetFileName = globalPackageDir + QLatin1Char('/') + freeDesktopXml;
+ QString errorMessage;
QVERIFY2(copyResourceFile(xmlFileName, xmlTargetFileName, &errorMessage), qPrintable(errorMessage));
#endif
- m_testSuite = QFINDTESTDATA("s-m-i/tests");
+ m_testSuite = QFINDTESTDATA("../s-m-i/tests/mime-detection");
if (m_testSuite.isEmpty())
qWarning("%s", qPrintable(testSuiteWarning()));
- errorMessage = QString::fromLatin1("Cannot find '%1'");
- for (uint i = 0; i < sizeof additionalMimeFiles / sizeof additionalMimeFiles[0] - 1; i++) {
- const QString resourceFilePath = QString::fromLatin1(RESOURCE_PREFIX) + QLatin1String(additionalMimeFiles[i]);
- QVERIFY2(QFile::exists(resourceFilePath), qPrintable(errorMessage.arg(resourceFilePath)));
- m_additionalMimeFileNames.append(QLatin1String(additionalMimeFiles[i]));
- m_additionalMimeFilePaths.append(resourceFilePath);
- }
-
initTestCaseInternal();
m_isUsingCacheProvider = !qEnvironmentVariableIsSet("QT_NO_MIME_CACHE");
}
@@ -187,7 +176,7 @@ void tst_QMimeDatabase::mimeTypeForName()
QMimeType s0 = db.mimeTypeForName(QString::fromLatin1("application/x-zerosize"));
QVERIFY(s0.isValid());
QCOMPARE(s0.name(), QString::fromLatin1("application/x-zerosize"));
- QCOMPARE(s0.comment(), QString::fromLatin1("empty document"));
+ QCOMPARE(s0.comment(), QString::fromLatin1("Empty document"));
QMimeType s0Again = db.mimeTypeForName(QString::fromLatin1("application/x-zerosize"));
QCOMPARE(s0Again.name(), s0.name());
@@ -195,7 +184,6 @@ void tst_QMimeDatabase::mimeTypeForName()
QMimeType s1 = db.mimeTypeForName(QString::fromLatin1("text/plain"));
QVERIFY(s1.isValid());
QCOMPARE(s1.name(), QString::fromLatin1("text/plain"));
- //qDebug("Comment is %s", qPrintable(s1.comment()));
QMimeType krita = db.mimeTypeForName(QString::fromLatin1("application/x-krita"));
QVERIFY(krita.isValid());
@@ -207,7 +195,7 @@ void tst_QMimeDatabase::mimeTypeForName()
QMimeType bzip2 = db.mimeTypeForName(QString::fromLatin1("application/x-bzip2"));
QVERIFY(bzip2.isValid());
- QCOMPARE(bzip2.comment(), QString::fromLatin1("Bzip archive"));
+ QCOMPARE(bzip2.comment(), QString::fromLatin1("Bzip2 archive"));
QMimeType defaultMime = db.mimeTypeForName(QString::fromLatin1("application/octet-stream"));
QVERIFY(defaultMime.isValid());
@@ -248,13 +236,15 @@ void tst_QMimeDatabase::mimeTypeForFileName_data()
QTest::newRow("case-sensitive uppercase match") << "textfile.C" << "text/x-c++src";
QTest::newRow("case-sensitive lowercase match") << "textfile.c" << "text/x-csrc";
QTest::newRow("case-sensitive long-extension match") << "foo.PS.gz" << "application/x-gzpostscript";
- QTest::newRow("case-sensitive-only match") << "core" << "application/x-core";
- QTest::newRow("case-sensitive-only match") << "Core" << "application/octet-stream"; // #198477
+ QTest::newRow("case-sensitive-only-match-core") << "core" << "application/x-core";
+ QTest::newRow("case-sensitive-only-match-Core") << "Core" << "application/octet-stream"; // #198477
QTest::newRow("desktop file") << "foo.desktop" << "application/x-desktop";
QTest::newRow("old kdelnk file is x-desktop too") << "foo.kdelnk" << "application/x-desktop";
- QTest::newRow("double-extension file") << "foo.tar.bz2" << "application/x-bzip-compressed-tar";
- QTest::newRow("single-extension file") << "foo.bz2" << "application/x-bzip";
+ QTest::newRow("double-extension file") << "foo.tar.bz2"
+ << "application/x-bzip2-compressed-tar";
+ QTest::newRow("single-extension file") << "foo.bz2"
+ << "application/x-bzip2";
QTest::newRow(".doc should assume msword") << "somefile.doc" << "application/msword"; // #204139
QTest::newRow("glob that uses [] syntax, 1") << "Makefile" << "text/x-makefile";
QTest::newRow("glob that uses [] syntax, 2") << "makefile" << "text/x-makefile";
@@ -265,6 +255,7 @@ void tst_QMimeDatabase::mimeTypeForFileName_data()
// fdo bug 15436, needs shared-mime-info >= 0.40 (and this tests the globs2-parsing code).
QTest::newRow("glob that ends with *, also matches *.pdf. *.pdf has higher weight") << "README.pdf" << "application/pdf";
QTest::newRow("directory") << "/" << "inode/directory";
+ QTest::newRow("resource-directory") << ":/files/" << "inode/directory";
QTest::newRow("doesn't exist, no extension") << "IDontExist" << "application/octet-stream";
QTest::newRow("doesn't exist but has known extension") << "IDontExist.txt" << "text/plain";
QTest::newRow("empty") << "" << "application/octet-stream";
@@ -274,7 +265,7 @@ static inline QByteArray msgMimeTypeForFileNameFailed(const QList<QMimeType> &ac
const QString &expected)
{
QByteArray result = "Actual (";
- foreach (const QMimeType &m, actual) {
+ for (const QMimeType &m : actual) {
result += m.name().toLocal8Bit();
result += ' ';
}
@@ -292,12 +283,12 @@ void tst_QMimeDatabase::mimeTypeForFileName()
QVERIFY(mime.isValid());
QCOMPARE(mime.name(), expectedMimeType);
- QList<QMimeType> mimes = db.mimeTypesForFileName(fileName);
+ const QList<QMimeType> mimes = db.mimeTypesForFileName(fileName);
if (expectedMimeType == "application/octet-stream") {
QVERIFY(mimes.isEmpty());
} else {
QVERIFY2(!mimes.isEmpty(), msgMimeTypeForFileNameFailed(mimes, expectedMimeType).constData());
- QVERIFY2(mimes.count() == 1, msgMimeTypeForFileNameFailed(mimes, expectedMimeType).constData());
+ QVERIFY2(mimes.size() == 1, msgMimeTypeForFileNameFailed(mimes, expectedMimeType).constData());
QCOMPARE(mimes.first().name(), expectedMimeType);
}
}
@@ -314,15 +305,22 @@ void tst_QMimeDatabase::mimeTypesForFileName_data()
QTest::newRow("non_ascii") << QString::fromUtf8("AİİA.pdf") << (QStringList() << "application/pdf");
}
+static QStringList mimeTypeNames(const QList<QMimeType> &mimes)
+{
+ QStringList mimeNames;
+ mimeNames.reserve(mimes.size());
+ for (const auto &mime : mimes)
+ mimeNames.append(mime.name());
+ return mimeNames;
+}
+
void tst_QMimeDatabase::mimeTypesForFileName()
{
QFETCH(QString, fileName);
QFETCH(QStringList, expectedMimeTypes);
QMimeDatabase db;
QList<QMimeType> mimes = db.mimeTypesForFileName(fileName);
- QStringList mimeNames;
- foreach (const QMimeType &mime, mimes)
- mimeNames.append(mime.name());
+ QStringList mimeNames = mimeTypeNames(mimes);
QCOMPARE(mimeNames, expectedMimeTypes);
}
@@ -346,9 +344,9 @@ void tst_QMimeDatabase::inheritance()
QVERIFY(msword.inherits(olestorage.name()));
QVERIFY(msword.inherits(QLatin1String("application/octet-stream")));
- const QMimeType directory = db.mimeTypeForName(QString::fromLatin1("inode/directory"));
+ const QMimeType directory = db.mimeTypeForName(s_inodeMimetype);
QVERIFY(directory.isValid());
- QCOMPARE(directory.parentMimeTypes().count(), 0);
+ QCOMPARE(directory.parentMimeTypes().size(), 0);
QVERIFY(!directory.inherits(QLatin1String("application/octet-stream")));
// Check that text/x-patch knows that it inherits from text/plain (it says so explicitly)
@@ -369,7 +367,7 @@ void tst_QMimeDatabase::inheritance()
const QStringList shellParents = shellscript.parentMimeTypes();
QVERIFY(shellParents.contains(QLatin1String("text/plain")));
QVERIFY(shellParents.contains(QLatin1String("application/x-executable")));
- QCOMPARE(shellParents.count(), 2); // only the above two
+ QCOMPARE(shellParents.size(), 2); // only the above two
const QStringList allShellAncestors = shellscript.allAncestors();
QVERIFY(allShellAncestors.contains(QLatin1String("text/plain")));
QVERIFY(allShellAncestors.contains(QLatin1String("application/x-executable")));
@@ -390,6 +388,13 @@ void tst_QMimeDatabase::inheritance()
const QMimeType mswordTemplate = db.mimeTypeForName(QString::fromLatin1("application/msword-template"));
QVERIFY(mswordTemplate.isValid());
QVERIFY(mswordTemplate.inherits(QLatin1String("application/msword")));
+
+ // Check that buggy type definitions that have circular inheritance don't cause an infinite
+ // loop, especially when resolving a conflict between the file's name and its contents
+ const QMimeType ecmascript = db.mimeTypeForName(QString::fromLatin1("application/ecmascript"));
+ QVERIFY(ecmascript.allAncestors().contains("text/plain"));
+ const QMimeType javascript = db.mimeTypeForFileNameAndData("xml.js", "<?xml?>");
+ QVERIFY(javascript.inherits(QString::fromLatin1("text/javascript")));
}
void tst_QMimeDatabase::aliases()
@@ -427,7 +432,7 @@ void tst_QMimeDatabase::listAliases()
QFETCH(QString, inputMime);
QFETCH(QString, expectedAliases);
QMimeDatabase db;
- QStringList expectedAliasesList = expectedAliases.split(',', QString::SkipEmptyParts);
+ QStringList expectedAliasesList = expectedAliases.split(',', Qt::SkipEmptyParts);
expectedAliasesList.sort();
QMimeType mime = db.mimeTypeForName(inputMime);
QVERIFY(mime.isValid());
@@ -440,7 +445,7 @@ void tst_QMimeDatabase::icons()
{
QMimeDatabase db;
QMimeType directory = db.mimeTypeForFile(QString::fromLatin1("/"));
- QCOMPARE(directory.name(), QString::fromLatin1("inode/directory"));
+ QCOMPARE(directory.name(), s_inodeMimetype);
QCOMPARE(directory.iconName(), QString::fromLatin1("inode-directory"));
QCOMPARE(directory.genericIconName(), QString::fromLatin1("folder"));
@@ -459,10 +464,13 @@ void tst_QMimeDatabase::comment()
QLocale::setDefault(QLocale("de"));
QMimeDatabase db;
- QMimeType directory = db.mimeTypeForName(QStringLiteral("inode/directory"));
+ QMimeType directory = db.mimeTypeForName(s_inodeMimetype);
QCOMPARE(directory.comment(), QStringLiteral("Ordner"));
QLocale::setDefault(QLocale("fr"));
- QCOMPARE(directory.comment(), QStringLiteral("dossier"));
+ // Missing in s-m-i 2.3 due to case changes
+ // QCOMPARE(directory.comment(), QStringLiteral("dossier"));
+ QMimeType cpp = db.mimeTypeForName("text/x-c++src");
+ QCOMPARE(cpp.comment(), QStringLiteral("code source C++"));
}
// In here we do the tests that need some content in a temporary file.
@@ -517,6 +525,42 @@ void tst_QMimeDatabase::mimeTypeForFileWithContent()
QCOMPARE(mime.name(), QString::fromLatin1("application/smil+xml"));
}
+ // Test what happens with Qt resources (file engines in general)
+ {
+ QFile rccFile(":/files/test.txt");
+
+ mime = db.mimeTypeForFile(rccFile.fileName());
+ QCOMPARE(mime.name(), "text/plain"_L1);
+
+ QVERIFY(rccFile.open(QIODevice::ReadOnly));
+ mime = db.mimeTypeForData(&rccFile);
+ QCOMPARE(mime.name(), "text/x-qml"_L1);
+ QVERIFY(rccFile.isOpen());
+
+ mime = db.mimeTypeForFile(rccFile.fileName(), QMimeDatabase::MatchContent);
+ QCOMPARE(mime.name(), "text/x-qml"_L1);
+ }
+
+ // Directories
+ {
+ mime = db.mimeTypeForFile("/");
+ QCOMPARE(mime.name(), "inode/directory"_L1);
+
+ QString dirName = QDir::tempPath();
+ if (!dirName.endsWith(u'/'))
+ dirName += u'/';
+ mime = db.mimeTypeForFile(dirName);
+ QCOMPARE(mime.name(), "inode/directory"_L1);
+
+ while (dirName.endsWith(u'/'))
+ dirName.chop(1);
+ mime = db.mimeTypeForFile(dirName);
+ QCOMPARE(mime.name(), "inode/directory"_L1);
+
+ mime = db.mimeTypeForFile(":/files");
+ QCOMPARE(mime.name(), "inode/directory"_L1);
+ }
+
// Test what happens with an incorrect path
mime = db.mimeTypeForFile(QString::fromLatin1("file:///etc/passwd" /* incorrect code, use a path instead */));
QVERIFY(mime.isDefault());
@@ -566,7 +610,7 @@ void tst_QMimeDatabase::mimeTypeForData()
QCOMPARE(buffer.pos(), qint64(0));
}
-void tst_QMimeDatabase::mimeTypeForFileAndContent_data()
+void tst_QMimeDatabase::mimeTypeForFileNameAndData_data()
{
QTest::addColumn<QString>("name");
QTest::addColumn<QByteArray>("data");
@@ -585,7 +629,7 @@ void tst_QMimeDatabase::mimeTypeForFileAndContent_data()
QTest::newRow("text.xls, found by extension, user is in control") << QString::fromLatin1("text.xls") << oleData << "application/vnd.ms-excel";
}
-void tst_QMimeDatabase::mimeTypeForFileAndContent()
+void tst_QMimeDatabase::mimeTypeForFileNameAndData()
{
QFETCH(QString, name);
QFETCH(QByteArray, data);
@@ -604,6 +648,86 @@ void tst_QMimeDatabase::mimeTypeForFileAndContent()
QCOMPARE(buffer.pos(), qint64(0));
}
+#ifdef Q_OS_UNIX
+void tst_QMimeDatabase::mimeTypeForUnixSpecials_data()
+{
+#ifndef AT_FDCWD
+ QSKIP("fdopendir and fstatat are not available");
+#else
+ QTest::addColumn<QString>("name");
+ QTest::addColumn<QString>("expected");
+
+ static const char * const mimeTypes[] = {
+ "inode/blockdevice",
+ "inode/chardevice",
+ "inode/fifo",
+ "inode/socket",
+ };
+ enum SpecialType {
+ FoundBlock = 0,
+ FoundChar = 1,
+ FoundFifo = 2,
+ FoundSocket = 3,
+ };
+ uint found = 0;
+ auto nothingfound = []() {
+ QSKIP("No special Unix inode types found!");
+ };
+
+ // on a standard Linux system (systemd), /dev/log is a symlink to a socket
+ // and /dev/initctl is a symlink to a FIFO
+ int devfd = open("/dev", O_RDONLY);
+ DIR *devdir = fdopendir(devfd); // takes ownership
+ if (!devdir)
+ return nothingfound();
+
+ while (struct dirent *ent = readdir(devdir)) {
+ struct stat statbuf;
+ if (fstatat(devfd, ent->d_name, &statbuf, 0) < 0)
+ continue;
+
+ SpecialType type;
+ if (S_ISBLK(statbuf.st_mode)) {
+ type = FoundBlock;
+ } else if (S_ISCHR(statbuf.st_mode)) {
+ type = FoundChar;
+ } else if (S_ISFIFO(statbuf.st_mode)) {
+ type = FoundFifo;
+ } else if (S_ISSOCK(statbuf.st_mode)) {
+ type = FoundSocket;
+ } else {
+ if (!S_ISREG(statbuf.st_mode) && !S_ISDIR(statbuf.st_mode))
+ qWarning("Could not tell what file type '%s' is: %#o'",
+ ent->d_name, statbuf.st_mode);
+ continue;
+ }
+
+ if (found & (1U << type))
+ continue; // we've already seen such a type
+
+ const char *mimeType = mimeTypes[type];
+ QTest::addRow("%s", mimeType)
+ << u"/dev/"_s + QFile::decodeName(ent->d_name) << mimeType;
+ found |= (1U << type);
+ }
+ closedir(devdir);
+
+ if (!found)
+ nothingfound();
+#endif
+}
+
+void tst_QMimeDatabase::mimeTypeForUnixSpecials()
+{
+ QFETCH(QString, name);
+ QFETCH(QString, expected);
+
+ qInfo() << "Testing that" << name << "is" << expected;
+ QMimeDatabase db;
+ QCOMPARE(db.mimeTypeForFile(name).name(), expected);
+}
+#endif
+
void tst_QMimeDatabase::allMimeTypes()
{
QMimeDatabase db;
@@ -611,9 +735,9 @@ void tst_QMimeDatabase::allMimeTypes()
QVERIFY(!lst.isEmpty());
// Hardcoding this is the only way to check both providers find the same number of mimetypes.
- QCOMPARE(lst.count(), 749);
+ QCOMPARE(lst.size(), 908);
- foreach (const QMimeType &mime, lst) {
+ for (const QMimeType &mime : lst) {
const QString name = mime.name();
QVERIFY(!name.isEmpty());
QCOMPARE(name.count(QLatin1Char('/')), 1);
@@ -630,17 +754,18 @@ void tst_QMimeDatabase::suffixes_data()
QTest::addColumn<QString>("preferredSuffix");
QTest::newRow("mimetype with a single pattern") << "application/pdf" << "*.pdf" << "pdf";
- QTest::newRow("mimetype with multiple patterns") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
- QTest::newRow("jpeg") << "image/jpeg" << "*.jpe;*.jpg;*.jpeg" << "jpeg";
- //if (KMimeType::sharedMimeInfoVersion() > KDE_MAKE_VERSION(0, 60, 0)) {
- QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
- //}
+ QTest::newRow("mimetype-with-multiple-patterns-kpr") << "application/x-kpresenter" << "*.kpr;*.kpt" << "kpr";
+ // The preferred suffix for image/jpeg is *.jpg, as per https://bugs.kde.org/show_bug.cgi?id=176737
+ QTest::newRow("jpeg") << "image/jpeg"
+ << "*.jfif;*.jpe;*.jpg;*.jpeg"
+ << "jpg";
+ QTest::newRow("mimetype with many patterns") << "application/vnd.wordperfect" << "*.wp;*.wp4;*.wp5;*.wp6;*.wpd;*.wpp" << "wp";
QTest::newRow("oasis text mimetype") << "application/vnd.oasis.opendocument.text" << "*.odt" << "odt";
QTest::newRow("oasis presentation mimetype") << "application/vnd.oasis.opendocument.presentation" << "*.odp" << "odp";
- QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
+ QTest::newRow("mimetype-multiple-patterns-text-plain") << "text/plain" << "*.asc;*.txt;*,v" << "txt";
QTest::newRow("mimetype with uncommon pattern") << "text/x-readme" << "README*" << QString();
QTest::newRow("mimetype with no patterns") << "application/x-ole-storage" << QString() << QString();
- QTest::newRow("default_mimetype") << "application/octet-stream" << "*.bin" << QString();
+ QTest::newRow("default_mimetype") << "application/octet-stream" << QString() << QString();
}
void tst_QMimeDatabase::suffixes()
@@ -667,11 +792,34 @@ void tst_QMimeDatabase::knownSuffix()
QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bz2")), QString::fromLatin1("bz2"));
QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bar.bz2")), QString::fromLatin1("bz2"));
QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.TAR")), QString::fromLatin1("TAR")); // preserve case
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.flatpakrepo")), QString::fromLatin1("flatpakrepo"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.anim2")), QString()); // the glob is anim[0-9], no way to extract the extension without expensive regexp capturing
+}
+
+void tst_QMimeDatabase::filterString_data()
+{
+ QTest::addColumn<QString>("mimeType");
+ QTest::addColumn<QString>("expectedFilterString");
+
+ QTest::newRow("single-pattern") << "application/pdf"
+ << "PDF document (*.pdf)";
+ QTest::newRow("multiple-patterns-text-plain") << "text/plain"
+ << "Plain text document (*.txt *.asc *,v)";
+}
+
+void tst_QMimeDatabase::filterString()
+{
+ QFETCH(QString, mimeType);
+ QFETCH(QString, expectedFilterString);
+
+ QMimeDatabase db;
+ QCOMPARE(db.mimeTypeForName(mimeType).filterString(), expectedFilterString);
}
void tst_QMimeDatabase::symlinkToFifo() // QTBUG-48529
{
-#ifdef Q_OS_UNIX
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
QTemporaryDir tempDir;
QVERIFY(tempDir.isValid());
const QString dir = tempDir.path();
@@ -708,14 +856,16 @@ void tst_QMimeDatabase::findByFileName_data()
QByteArray line(1024, Qt::Uninitialized);
+ QDuplicateTracker<QString, 800> seen;
+
while (!f.atEnd()) {
- int len = f.readLine(line.data(), 1023);
+ const qint64 len = f.readLine(line.data(), 1023);
if (len <= 2 || line.at(0) == '#')
continue;
QString string = QString::fromLatin1(line.constData(), len - 1).trimmed();
- QStringList list = string.split(QLatin1Char(' '), QString::SkipEmptyParts);
+ QStringList list = string.split(QLatin1Char(' '), Qt::SkipEmptyParts);
QVERIFY(list.size() >= 2);
QString filePath = list.at(0);
@@ -723,10 +873,16 @@ void tst_QMimeDatabase::findByFileName_data()
QString xFail;
if (list.size() >= 3)
xFail = list.at(2);
+ QString rowTag = filePath;
+ if (seen.hasSeen(rowTag)) {
+ // Two testcases for the same file, e.g.
+ // test.ogg audio/ogg oxx
+ // test.ogg audio/x-vorbis+ogg x
+ rowTag += "_2";
+ }
- QTest::newRow(filePath.toLatin1().constData())
- << QString(prefix + filePath)
- << mimeTypeType << xFail;
+ QTest::newRow(rowTag.toLatin1().constData())
+ << QString(prefix + filePath) << mimeTypeType << xFail;
}
}
@@ -738,28 +894,11 @@ void tst_QMimeDatabase::findByFileName()
QMimeDatabase database;
- //qDebug() << Q_FUNC_INFO << filePath;
-
const QMimeType resultMimeType(database.mimeTypeForFile(filePath, QMimeDatabase::MatchExtension));
- if (resultMimeType.isValid()) {
- //qDebug() << Q_FUNC_INFO << "MIME type" << resultMimeType.name() << "has generic icon name" << resultMimeType.genericIconName() << "and icon name" << resultMimeType.iconName();
-
-// Loading icons depend on the icon theme, we can't enable this test
-#if 0
- QCOMPARE(resultMimeType.genericIconName(), QIcon::fromTheme(resultMimeType.genericIconName()).name());
- QVERIFY2(!QIcon::fromTheme(resultMimeType.genericIconName()).isNull(), qPrintable(resultMimeType.genericIconName()));
- QVERIFY2(QIcon::hasThemeIcon(resultMimeType.genericIconName()), qPrintable(resultMimeType.genericIconName()));
-
- QCOMPARE(resultMimeType.iconName(), QIcon::fromTheme(resultMimeType.iconName()).name());
- QVERIFY2(!QIcon::fromTheme(resultMimeType.iconName()).isNull(), qPrintable(resultMimeType.iconName()));
- QVERIFY2(QIcon::hasThemeIcon(resultMimeType.iconName()), qPrintable(resultMimeType.iconName()));
-#endif
- }
const QString resultMimeTypeName = resultMimeType.name();
- //qDebug() << Q_FUNC_INFO << "mimeTypeForFile() returned" << resultMimeTypeName;
const bool failed = resultMimeTypeName != mimeTypeName;
- const bool shouldFail = (xFail.length() >= 1 && xFail.at(0) == QLatin1Char('x'));
+ const bool shouldFail = (xFail.size() >= 1 && xFail.at(0) == QLatin1Char('x'));
if (shouldFail != failed) {
// Results are ambiguous when multiple MIME types have the same glob
// -> accept the current result if the found MIME type actually
@@ -769,7 +908,6 @@ void tst_QMimeDatabase::findByFileName()
QVERIFY2(resultMimeType == foundMimeType, qPrintable(resultMimeType.name() + QString::fromLatin1(" vs. ") + foundMimeType.name()));
if (foundMimeType.isValid()) {
const QString extension = QFileInfo(filePath).suffix();
- //qDebug() << Q_FUNC_INFO << "globPatterns:" << foundMimeType.globPatterns() << "- extension:" << QString() + "*." + extension;
if (foundMimeType.globPatterns().contains(QString::fromLatin1("*.") + extension))
return;
}
@@ -784,6 +922,9 @@ void tst_QMimeDatabase::findByFileName()
// Test QFileInfo overload
const QMimeType mimeForFileInfo = database.mimeTypeForFile(QFileInfo(filePath), QMimeDatabase::MatchExtension);
QCOMPARE(mimeForFileInfo.name(), resultMimeTypeName);
+
+ const QString suffix = database.suffixForFileName(filePath);
+ QVERIFY2(filePath.endsWith(suffix), qPrintable(filePath + " does not end with " + suffix));
}
void tst_QMimeDatabase::findByData_data()
@@ -803,7 +944,7 @@ void tst_QMimeDatabase::findByData()
QByteArray data = f.read(16384);
const QString resultMimeTypeName = database.mimeTypeForData(data).name();
- if (xFail.length() >= 2 && xFail.at(1) == QLatin1Char('x')) {
+ if (xFail.size() >= 2 && xFail.at(1) == QLatin1Char('x')) {
// Expected to fail
QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName));
} else {
@@ -833,8 +974,7 @@ void tst_QMimeDatabase::findByFile()
QMimeDatabase database;
const QString resultMimeTypeName = database.mimeTypeForFile(filePath).name();
- //qDebug() << Q_FUNC_INFO << filePath << "->" << resultMimeTypeName;
- if (xFail.length() >= 3 && xFail.at(2) == QLatin1Char('x')) {
+ if (xFail.size() >= 3 && xFail.at(2) == QLatin1Char('x')) {
// Expected to fail
QVERIFY2(resultMimeTypeName != mimeTypeName, qPrintable(resultMimeTypeName));
} else {
@@ -852,14 +992,14 @@ void tst_QMimeDatabase::fromThreads()
QThreadPool tp;
tp.setMaxThreadCount(20);
// Note that data-based tests cannot be used here (QTest::fetchData asserts).
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::mimeTypeForName);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::aliases);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::allMimeTypes);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::icons);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::inheritance);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::knownSuffix);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::mimeTypeForFileWithContent);
- QtConcurrent::run(&tp, this, &tst_QMimeDatabase::allMimeTypes); // a second time
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::mimeTypeForName, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::aliases, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::allMimeTypes, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::icons, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::inheritance, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::knownSuffix, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::mimeTypeForFileWithContent, this));
+ Q_UNUSED(QtConcurrent::run(&tp, &tst_QMimeDatabase::allMimeTypes, this)); // a second time
QVERIFY(tp.waitForDone(60000));
}
@@ -877,7 +1017,7 @@ static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDa
qWarning("%s does not exist.", qPrintable(umdCommand));
return false;
}
-
+#if QT_CONFIG(process)
QElapsedTimer timer;
QProcess proc;
proc.setProcessChannelMode(QProcess::MergedChannels); // silence output
@@ -892,6 +1032,7 @@ static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDa
const bool success = proc.waitForFinished(UpdateMimeDatabaseTimeout);
qDebug().noquote() << "runUpdateMimeDatabase: done,"
<< success << timer.elapsed() << "ms";
+#endif
return true;
}
@@ -900,7 +1041,7 @@ static bool waitAndRunUpdateMimeDatabase(const QString &path)
QFileInfo mimeCacheInfo(path + QString::fromLatin1("/mime.cache"));
if (mimeCacheInfo.exists()) {
// Wait until the beginning of the next second
- while (mimeCacheInfo.lastModified().secsTo(QDateTime::currentDateTime()) == 0) {
+ while (mimeCacheInfo.lastModified(QTimeZone::UTC).secsTo(QDateTime::currentDateTimeUtc()) == 0) {
QTest::qSleep(200);
}
}
@@ -914,7 +1055,8 @@ static void checkHasMimeType(const QString &mimeType)
QVERIFY(db.mimeTypeForName(mimeType).isValid());
bool found = false;
- foreach (const QMimeType &mt, db.allMimeTypes()) {
+ const auto all = db.allMimeTypes();
+ for (const QMimeType &mt : all) {
if (mt.name() == mimeType) {
found = true;
break;
@@ -935,6 +1077,30 @@ QT_BEGIN_NAMESPACE
extern Q_CORE_EXPORT int qmime_secondsBetweenChecks; // see qmimeprovider.cpp
QT_END_NAMESPACE
+void copyFiles(const QSpan<const char *const> &additionalMimeFiles, const QString &destDir)
+{
+ const QString notFoundErrorMessage = QString::fromLatin1("Cannot find '%1'");
+ for (const char *mimeFile : additionalMimeFiles) {
+ const QString resourceFilePath = s_resourcePrefix + QLatin1String(mimeFile);
+ QVERIFY2(QFile::exists(resourceFilePath),
+ qPrintable(notFoundErrorMessage.arg(resourceFilePath)));
+
+ const QString destFile = destDir + QLatin1String(mimeFile);
+ QFile::remove(destFile);
+ QString errorMessage;
+ QVERIFY2(copyResourceFile(resourceFilePath, destFile, &errorMessage),
+ qPrintable(errorMessage));
+ }
+}
+
+void deleteFiles(const QSpan<const char *const> &additionalMimeFiles, const QString &destDir)
+{
+ for (const char *mimeFile : additionalMimeFiles) {
+ const QString destFile = destDir + QLatin1String(mimeFile);
+ QFile::remove(destFile);
+ }
+}
+
void tst_QMimeDatabase::installNewGlobalMimeType()
{
#if !defined(USE_XDG_DATA_DIRS)
@@ -954,42 +1120,28 @@ void tst_QMimeDatabase::installNewGlobalMimeType()
if (!QFileInfo(destDir).isDir())
QVERIFY(QDir(m_globalXdgDir).mkpath(destDir));
- QString errorMessage;
- for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) {
- const QString destFile = destDir + m_additionalMimeFileNames.at(i);
- QFile::remove(destFile);
- QVERIFY2(copyResourceFile(m_additionalMimeFilePaths.at(i), destFile, &errorMessage), qPrintable(errorMessage));
- }
+ copyFiles(additionalGlobalMimeFiles, destDir);
+ QVERIFY(!QTest::currentTestFailed());
if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(mimeDir))
QSKIP("shared-mime-info not found, skipping mime.cache test");
- if (!m_isUsingCacheProvider)
- ignoreInvalidMimetypeWarnings(mimeDir);
-
QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
QString::fromLatin1("text/x-SuSE-ymu"));
QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
checkHasMimeType("text/x-suse-ymp");
// Test that a double-definition of a mimetype doesn't lead to sniffing ("conflicting globs").
- const QString qmlTestFile = QLatin1String(RESOURCE_PREFIX "test.qml");
+ const QString qmlTestFile = s_resourcePrefix + "test.qml"_L1;
QVERIFY2(!qmlTestFile.isEmpty(),
qPrintable(QString::fromLatin1("Cannot find '%1' starting from '%2'").
arg("test.qml", QDir::currentPath())));
QCOMPARE(db.mimeTypeForFile(qmlTestFile).name(),
QString::fromLatin1("text/x-qml"));
- // ensure we can access the empty glob list
- {
- QMimeType objcsrc = db.mimeTypeForName(QStringLiteral("text/x-objcsrc"));
- QVERIFY(objcsrc.isValid());
- qDebug() << objcsrc.globPatterns();
- }
-
- const QString fooTestFile = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy.foo");
+ const QString fooTestFile = s_resourcePrefix + "magic-and-hierarchy.foo"_L1;
QCOMPARE(db.mimeTypeForFile(fooTestFile).name(), QString::fromLatin1("application/foo"));
- const QString fooTestFile2 = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy2.foo");
+ const QString fooTestFile2 = s_resourcePrefix + "magic-and-hierarchy2.foo"_L1;
QCOMPARE(db.mimeTypeForFile(fooTestFile2).name(), QString::fromLatin1("application/vnd.qnx.bar-descriptor"));
// Test if we can use the default comment
@@ -1007,8 +1159,7 @@ void tst_QMimeDatabase::installNewGlobalMimeType()
}
// Now test removing the mimetype definitions again
- for (int i = 0; i < m_additionalMimeFileNames.size(); ++i)
- QFile::remove(destDir + m_additionalMimeFileNames.at(i));
+ deleteFiles(additionalGlobalMimeFiles, destDir);
if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(mimeDir))
QSKIP("shared-mime-info not found, skipping mime.cache test");
QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
@@ -1017,11 +1168,29 @@ void tst_QMimeDatabase::installNewGlobalMimeType()
#endif // QT_CONFIG(process)
}
+void tst_QMimeDatabase::installNewLocalMimeType_data()
+{
+ QTest::addColumn<bool>("useLocalBinaryCache");
+
+ // Test mixing the providers:
+ // * m_isUsingCacheProvider is about the global directory.
+ // ** when true, we'll test both for the local directory.
+ // ** when false, we can't, because QT_NO_MIME_CACHE is set, so it's XML+XML only
+
+#if QT_CONFIG(process)
+ if (m_isUsingCacheProvider)
+ QTest::newRow("with_binary_cache") << true;
+#endif
+ QTest::newRow("without_binary_cache") << false;
+}
+
void tst_QMimeDatabase::installNewLocalMimeType()
{
#if !QT_CONFIG(process)
QSKIP("This test requires QProcess support");
#else
+ QFETCH(bool, useLocalBinaryCache);
+
qmime_secondsBetweenChecks = 0;
QMimeDatabase db;
@@ -1032,19 +1201,16 @@ void tst_QMimeDatabase::installNewLocalMimeType()
const QString destDir = m_localMimeDir + QLatin1String("/packages/");
QVERIFY(QDir().mkpath(destDir));
- QString errorMessage;
- for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) {
- const QString destFile = destDir + m_additionalMimeFileNames.at(i);
- QFile::remove(destFile);
- QVERIFY2(copyResourceFile(m_additionalMimeFilePaths.at(i), destFile, &errorMessage), qPrintable(errorMessage));
- }
- if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(m_localMimeDir)) {
+
+ copyFiles(additionalLocalMimeFiles, destDir);
+ QVERIFY(!QTest::currentTestFailed());
+ if (useLocalBinaryCache && !waitAndRunUpdateMimeDatabase(m_localMimeDir)) {
const QString skipWarning = QStringLiteral("shared-mime-info not found, skipping mime.cache test (")
+ QDir::toNativeSeparators(m_localMimeDir) + QLatin1Char(')');
QSKIP(qPrintable(skipWarning));
}
- if (!m_isUsingCacheProvider)
+ if (!useLocalBinaryCache)
ignoreInvalidMimetypeWarnings(m_localMimeDir);
QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
@@ -1060,14 +1226,38 @@ void tst_QMimeDatabase::installNewLocalMimeType()
QCOMPARE(db.mimeTypeForName(QLatin1String("text/x-SuSE-ymu")).comment(), QString("URL of a YaST Meta Package"));
checkHasMimeType("text/x-suse-ymp");
+ { // QTBUG-85436
+ QMimeType objcsrc = db.mimeTypeForName(QStringLiteral("text/x-objcsrc"));
+ QVERIFY(objcsrc.isValid());
+ QCOMPARE(objcsrc.globPatterns(), QStringList());
+ }
+ QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.txt"), QMimeDatabase::MatchExtension).name(),
+ QString::fromLatin1("text/plain"));
+
// Test that a double-definition of a mimetype doesn't lead to sniffing ("conflicting globs").
- const QString qmlTestFile = QLatin1String(RESOURCE_PREFIX "test.qml");
+ const QString qmlTestFile = s_resourcePrefix + "test.qml"_L1;
QVERIFY2(!qmlTestFile.isEmpty(),
qPrintable(QString::fromLatin1("Cannot find '%1' starting from '%2'").
arg("test.qml", QDir::currentPath())));
QCOMPARE(db.mimeTypeForFile(qmlTestFile).name(),
QString::fromLatin1("text/x-qml"));
+ { // QTBUG-101755
+ QList<QMimeType> mimes = db.mimeTypesForFileName(u"foo.webm"_s);
+ // "*.webm" glob pattern is deleted with "glob-deleteall"
+ QVERIFY2(mimes.isEmpty(), qPrintable(mimeTypeNames(mimes).join(u',')));
+ mimes = db.mimeTypesForFileName(u"foo.videowebm"_s);
+ QCOMPARE(mimes.size(), 1);
+ QCOMPARE(mimes.at(0).globPatterns(), QStringList{ "*.videowebm" });
+ // Custom "*.videowebm" pattern is used instead
+ QCOMPARE(mimes.at(0).name(), u"video/webm");
+ }
+
+ // QTBUG-116905: globPatterns() should merge all locations
+ // add-extension.xml adds *.jnewext
+ const QStringList expectedJpegPatterns{ "*.jpg", "*.jpeg", "*.jpe", "*.jfif", "*.jnewext" };
+ QCOMPARE(db.mimeTypeForName(QStringLiteral("image/jpeg")).globPatterns(), expectedJpegPatterns);
+
// Now that we have two directories with mime definitions, check that everything still works
inheritance();
if (QTest::currentTestFailed())
@@ -1096,7 +1286,7 @@ void tst_QMimeDatabase::installNewLocalMimeType()
// Now test removing local mimetypes
for (int i = 1 ; i <= 3 ; ++i)
QFile::remove(destDir + QStringLiteral("invalid-magic%1.xml").arg(i));
- if (m_isUsingCacheProvider && !waitAndRunUpdateMimeDatabase(m_localMimeDir))
+ if (useLocalBinaryCache && !waitAndRunUpdateMimeDatabase(m_localMimeDir))
QSKIP("shared-mime-info not found, skipping mime.cache test");
QVERIFY(!db.mimeTypeForName(QLatin1String("text/invalid-magic1")).isValid()); // deleted
QVERIFY(db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid()); // still present
@@ -1111,7 +1301,7 @@ void tst_QMimeDatabase::installNewLocalMimeType()
QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.ymu"), QMimeDatabase::MatchExtension).name(),
QString::fromLatin1("application/octet-stream"));
QVERIFY(!db.mimeTypeForName(QLatin1String("text/x-suse-ymp")).isValid());
-#endif // QT_CONFIG(process)
+#endif
}
QTEST_GUILESS_MAIN(tst_QMimeDatabase)
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
index 4918dc6f4a..415c2e3e37 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TST_QMIMEDATABASE_H
#define TST_QMIMEDATABASE_H
@@ -60,12 +35,18 @@ private slots:
void mimeTypeForUrl();
void mimeTypeForData_data();
void mimeTypeForData();
- void mimeTypeForFileAndContent_data();
- void mimeTypeForFileAndContent();
+ void mimeTypeForFileNameAndData_data();
+ void mimeTypeForFileNameAndData();
+#ifdef Q_OS_UNIX
+ void mimeTypeForUnixSpecials_data();
+ void mimeTypeForUnixSpecials();
+#endif
void allMimeTypes();
void suffixes_data();
void suffixes();
void knownSuffix();
+ void filterString_data();
+ void filterString();
void symlinkToFifo();
void fromThreads();
@@ -83,6 +64,7 @@ private slots:
//
void installNewGlobalMimeType();
+ void installNewLocalMimeType_data();
void installNewLocalMimeType();
private:
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/webm-glob-deleteall.xml b/tests/auto/corelib/mimetypes/qmimedatabase/webm-glob-deleteall.xml
new file mode 100644
index 0000000000..05a24de17c
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/webm-glob-deleteall.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="video/webm">
+ <glob-deleteall/>
+ <glob pattern="*.videowebm"/>
+ </mime-type>
+</mime-info>
diff --git a/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt
new file mode 100644
index 0000000000..605cdccc3f
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmimetype Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmimetype LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmimetype
+ SOURCES
+ tst_qmimetype.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro b/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro
deleted file mode 100644
index 1540e75c28..0000000000
--- a/tests/auto/corelib/mimetypes/qmimetype/qmimetype.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmimetype
-QT = core-private testlib
-
-SOURCES = tst_qmimetype.cpp
diff --git a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
index c74bce3b5b..b96e8feffa 100644
--- a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
+++ b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
@@ -1,38 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <private/qmimetype_p.h>
#include <qmimetype.h>
#include <qmimedatabase.h>
+#include <QVariantMap>
-#include <QtTest/QtTest>
-
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
class tst_qmimetype : public QObject
{
@@ -41,11 +17,12 @@ class tst_qmimetype : public QObject
private slots:
void initTestCase();
+ void compareCompiles();
void isValid();
+ void compareQMimetypes();
void name();
void genericIconName();
void iconName();
- void suffixes();
void gadget();
};
@@ -60,62 +37,43 @@ void tst_qmimetype::initTestCase()
static QString qMimeTypeName()
{
- static const QString result ("No name of the MIME type");
+ static const QString result("group/fake-mime");
return result;
}
-static QString qMimeTypeGenericIconName()
-{
- static const QString result ("No file name of an icon image that represents the MIME type");
- return result;
-}
+// ------------------------------------------------------------------------------------------------
-static QString qMimeTypeIconName()
+void tst_qmimetype::compareCompiles()
{
- static const QString result ("No file name of an icon image that represents the MIME type");
- return result;
+ QTestPrivate::testEqualityOperatorsCompile<QMimeType>();
}
-static QStringList buildQMimeTypeFilenameExtensions()
-{
- QStringList result;
- result << QString::fromLatin1("*.png");
- return result;
-}
+// ------------------------------------------------------------------------------------------------
-static QStringList qMimeTypeGlobPatterns()
+void tst_qmimetype::compareQMimetypes()
{
- static const QStringList result (buildQMimeTypeFilenameExtensions());
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
+ QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
+ QMimeType otherQMimeType (instantiatedQMimeType);
+ QMimeType defaultQMimeType;
-#ifndef Q_COMPILER_RVALUE_REFS
-QMIMETYPE_BUILDER
-#else
-QMIMETYPE_BUILDER_FROM_RVALUE_REFS
-#endif
+ QVERIFY(!defaultQMimeType.isValid());
+ QT_TEST_EQUALITY_OPS(defaultQMimeType, QMimeType(), true);
+ QT_TEST_EQUALITY_OPS(QMimeType(), QMimeType(), true);
+ QT_TEST_EQUALITY_OPS(instantiatedQMimeType, QMimeType(), false);
+ QT_TEST_EQUALITY_OPS(otherQMimeType, defaultQMimeType, false);
+}
// ------------------------------------------------------------------------------------------------
void tst_qmimetype::isValid()
{
- QMimeType instantiatedQMimeType (
- buildQMimeType (
- qMimeTypeName(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
-
+ QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
QVERIFY(instantiatedQMimeType.isValid());
QMimeType otherQMimeType (instantiatedQMimeType);
QVERIFY(otherQMimeType.isValid());
- QCOMPARE(instantiatedQMimeType, otherQMimeType);
+ QT_TEST_EQUALITY_OPS(instantiatedQMimeType, otherQMimeType, true);
QMimeType defaultQMimeType;
@@ -126,92 +84,36 @@ void tst_qmimetype::isValid()
void tst_qmimetype::name()
{
- QMimeType instantiatedQMimeType (
- buildQMimeType (
- qMimeTypeName(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
-
- QMimeType otherQMimeType (
- buildQMimeType (
- QString(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
+ QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
+ QMimeType otherQMimeType{ QMimeTypePrivate(QString()) };
// Verify that the Name is part of the equality test:
QCOMPARE(instantiatedQMimeType.name(), qMimeTypeName());
- QVERIFY(instantiatedQMimeType != otherQMimeType);
- QVERIFY(!(instantiatedQMimeType == otherQMimeType));
+ QT_TEST_EQUALITY_OPS(instantiatedQMimeType, otherQMimeType, false);
}
// ------------------------------------------------------------------------------------------------
void tst_qmimetype::genericIconName()
{
- QMimeType instantiatedQMimeType (
- buildQMimeType (
- qMimeTypeName(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
-
- QCOMPARE(instantiatedQMimeType.genericIconName(), qMimeTypeGenericIconName());
+ const QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
+ QCOMPARE(instantiatedQMimeType.genericIconName(), "group-x-generic");
}
// ------------------------------------------------------------------------------------------------
void tst_qmimetype::iconName()
{
- QMimeType instantiatedQMimeType (
- buildQMimeType (
- qMimeTypeName(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
-
- QCOMPARE(instantiatedQMimeType.iconName(), qMimeTypeIconName());
-}
-
-// ------------------------------------------------------------------------------------------------
-
-void tst_qmimetype::suffixes()
-{
- QMimeType instantiatedQMimeType (
- buildQMimeType (
- qMimeTypeName(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
-
- QCOMPARE(instantiatedQMimeType.globPatterns(), qMimeTypeGlobPatterns());
- QCOMPARE(instantiatedQMimeType.suffixes(), QStringList() << QString::fromLatin1("png"));
+ const QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
+ QCOMPARE(instantiatedQMimeType.iconName(), "group-fake-mime");
}
// ------------------------------------------------------------------------------------------------
void tst_qmimetype::gadget()
{
- QMimeType instantiatedQMimeType (
- buildQMimeType (
- qMimeTypeName(),
- qMimeTypeGenericIconName(),
- qMimeTypeIconName(),
- qMimeTypeGlobPatterns()
- )
- );
+ QMimeType instantiatedQMimeType = QMimeDatabase().mimeTypeForName("text/plain");
const QMetaObject *metaObject = &instantiatedQMimeType.staticMetaObject;
diff --git a/tests/auto/corelib/platform/CMakeLists.txt b/tests/auto/corelib/platform/CMakeLists.txt
new file mode 100644
index 0000000000..3455736eab
--- /dev/null
+++ b/tests/auto/corelib/platform/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(ANDROID)
+ add_subdirectory(android)
+ add_subdirectory(android_appless)
+endif()
+if(WIN32)
+ add_subdirectory(windows)
+endif()
diff --git a/tests/auto/corelib/platform/android/CMakeLists.txt b/tests/auto/corelib/platform/android/CMakeLists.txt
new file mode 100644
index 0000000000..6b7e9b2901
--- /dev/null
+++ b/tests/auto/corelib/platform/android/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_android Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_android LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_android
+ SOURCES
+ tst_android.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+ Qt::Widgets
+)
+
+if(ANDROID)
+ set_property(TARGET tst_android APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR}/testdata
+ )
+endif()
diff --git a/tests/auto/corelib/platform/android/testdata/assets/test.txt b/tests/auto/corelib/platform/android/testdata/assets/test.txt
new file mode 100644
index 0000000000..61e2c47c25
--- /dev/null
+++ b/tests/auto/corelib/platform/android/testdata/assets/test.txt
@@ -0,0 +1 @@
+FooBar \ No newline at end of file
diff --git a/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/file_in_top_dir.txt b/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/file_in_top_dir.txt
new file mode 100644
index 0000000000..61e2c47c25
--- /dev/null
+++ b/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/file_in_top_dir.txt
@@ -0,0 +1 @@
+FooBar \ No newline at end of file
diff --git a/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/file_in_sub_dir.txt b/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/file_in_sub_dir.txt
new file mode 100644
index 0000000000..61e2c47c25
--- /dev/null
+++ b/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/file_in_sub_dir.txt
@@ -0,0 +1 @@
+FooBar \ No newline at end of file
diff --git a/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/sub_dir_2/sub_dir_3/file_in_sub_dir_3.txt b/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/sub_dir_2/sub_dir_3/file_in_sub_dir_3.txt
new file mode 100644
index 0000000000..61e2c47c25
--- /dev/null
+++ b/tests/auto/corelib/platform/android/testdata/assets/top_level_dir/sub_dir/sub_dir_2/sub_dir_3/file_in_sub_dir_3.txt
@@ -0,0 +1 @@
+FooBar \ No newline at end of file
diff --git a/tests/auto/corelib/platform/android/tst_android.cpp b/tests/auto/corelib/platform/android/tst_android.cpp
new file mode 100644
index 0000000000..76811a31ad
--- /dev/null
+++ b/tests/auto/corelib/platform/android/tst_android.cpp
@@ -0,0 +1,377 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <jni.h>
+
+#include <QTest>
+#include <QGuiApplication>
+#include <QtCore/qnativeinterface.h>
+#include <QtCore/qjniobject.h>
+#include <QtCore/qdiriterator.h>
+#include <QScreen>
+#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformnativeinterface.h>
+#include <QtCore/qdiriterator.h>
+#include <QWidget>
+#include <QSignalSpy>
+
+using namespace Qt::StringLiterals;
+
+class tst_Android : public QObject
+{
+Q_OBJECT
+private slots:
+ void assetsRead();
+ void assetsNotWritable();
+ void assetsIterating();
+ void testAndroidSdkVersion();
+ void testAndroidActivity();
+ void testRunOnAndroidMainThread();
+ void testFullScreenDimensions();
+ void orientationChange_data();
+ void orientationChange();
+};
+
+void tst_Android::assetsRead()
+{
+ {
+ QFile file(QStringLiteral("assets:/test.txt"));
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QCOMPARE(file.readAll(), QByteArray("FooBar"));
+ }
+
+ {
+ QFile file(QStringLiteral("assets:/test.txt"));
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ QCOMPARE(file.readAll(), QByteArray("FooBar"));
+ }
+}
+
+void tst_Android::assetsNotWritable()
+{
+ QFile file(QStringLiteral("assets:/test.txt"));
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+ QVERIFY(!file.open(QIODevice::ReadWrite));
+ QVERIFY(!file.open(QIODevice::Append));
+}
+
+void tst_Android::assetsIterating()
+{
+ QStringList assets = {"assets:/top_level_dir/file_in_top_dir.txt",
+ "assets:/top_level_dir/sub_dir",
+ "assets:/top_level_dir/sub_dir/file_in_sub_dir.txt",
+ "assets:/top_level_dir/sub_dir/sub_dir_2",
+ "assets:/top_level_dir/sub_dir/sub_dir_2/sub_dir_3",
+ "assets:/top_level_dir/sub_dir/sub_dir_2/sub_dir_3/file_in_sub_dir_3.txt"};
+
+ // Note that we have an "assets:/top_level_dir/sub_dir/empty_sub_dir" in the test's
+ // assets physical directory, but empty folders are not packaged in the built apk,
+ // so it's expected to not have such folder be listed in the assets on runtime
+
+ QDirIterator it("assets:/top_level_dir", QDirIterator::Subdirectories);
+ QStringList iteratorAssets;
+ while (it.hasNext())
+ iteratorAssets.append(it.next());
+
+ QVERIFY(assets == iteratorAssets);
+
+ auto entryList = QDir{"assets:/"_L1}.entryList(QStringList{"*.txt"_L1});
+ QCOMPARE(entryList.size(), 1);
+ QCOMPARE(entryList[0], "test.txt"_L1);
+}
+
+void tst_Android::testAndroidSdkVersion()
+{
+ QVERIFY(QNativeInterface::QAndroidApplication::sdkVersion() > 0);
+}
+
+void tst_Android::testAndroidActivity()
+{
+ QJniObject activity = QNativeInterface::QAndroidApplication::context();
+ QVERIFY(activity.isValid());
+ QVERIFY(activity.callMethod<jboolean>("isTaskRoot"));
+}
+
+void tst_Android::testRunOnAndroidMainThread()
+{
+ // async void
+ {
+ int res = 0;
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{ res = 1; });
+ QTRY_COMPARE(res, 1);
+ }
+
+ // sync void
+ {
+ int res = 0;
+ auto task = QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ res = 1;
+ });
+ task.waitForFinished();
+ QCOMPARE(res, 1);
+ }
+
+ // sync return value
+ {
+ auto task = QNativeInterface::QAndroidApplication::runOnAndroidMainThread([]{
+ return 1;
+ });
+ task.waitForFinished();
+ QVERIFY(task.isResultReadyAt(0));
+ QCOMPARE(task.result().value<int>(), 1);
+ }
+
+ // nested calls
+ {
+ // nested async/async
+ int res = 0;
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ res = 3;
+ });
+ });
+ QTRY_COMPARE(res, 3);
+
+ // nested async/sync
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ res = 5;
+ }).waitForFinished();
+ });
+ QTRY_COMPARE(res, 5);
+
+ // nested sync/sync
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ res = 4;
+ }).waitForFinished();
+ }).waitForFinished();
+ QCOMPARE(res, 4);
+
+
+ // nested sync/async
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([&res]{
+ res = 6;
+ });
+ }).waitForFinished();
+ QCOMPARE(res, 6);
+ }
+
+ // timeouts
+ {
+ auto task = QNativeInterface::QAndroidApplication::runOnAndroidMainThread([]{
+ QThread::msleep(500);
+ return 1;
+ }, QDeadlineTimer(100));
+ task.waitForFinished();
+ QVERIFY(task.isCanceled());
+ QVERIFY(task.isFinished());
+ QVERIFY(!task.isResultReadyAt(0));
+
+ auto task2 = QNativeInterface::QAndroidApplication::runOnAndroidMainThread([]{
+ return 2;
+ }, QDeadlineTimer(0));
+ task2.waitForFinished();
+ QVERIFY(task2.isCanceled());
+ QVERIFY(task2.isFinished());
+ QVERIFY(!task2.isResultReadyAt(0));
+
+ QDeadlineTimer deadline(1000);
+ auto task3 = QNativeInterface::QAndroidApplication::runOnAndroidMainThread([]{
+ return 3;
+ }, QDeadlineTimer(10000));
+ task3.waitForFinished();
+ QVERIFY(deadline.remainingTime() > 0);
+ QVERIFY(task3.isFinished());
+ QVERIFY(!task3.isCanceled());
+ QVERIFY(task3.isResultReadyAt(0));
+ QCOMPARE(task3.result().value<int>(), 3);
+ }
+
+ // cancelled future
+ {
+ auto task = QNativeInterface::QAndroidApplication::runOnAndroidMainThread([]{
+ QThread::msleep(2000);
+ return 1;
+ });
+ task.cancel();
+ QVERIFY(task.isCanceled());
+ task.waitForFinished();
+ QVERIFY(task.isFinished());
+ QVERIFY(!task.isResultReadyAt(0));
+ }
+}
+
+Q_DECLARE_JNI_CLASS(QtActivityDelegateBase, "org/qtproject/qt/android/QtActivityDelegateBase")
+
+void setSystemUiVisibility(int visibility)
+{
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread([visibility] {
+ auto context = QNativeInterface::QAndroidApplication::context();
+ auto activityDelegate = context.callMethod<QtJniTypes::QtActivityDelegateBase>("getActivityDelegate");
+ activityDelegate.callMethod<void>("setSystemUiVisibility", jint(visibility));
+ }).waitForFinished();
+}
+
+// QTBUG-107604
+void tst_Android::testFullScreenDimensions()
+{
+ static int SYSTEM_UI_VISIBILITY_NORMAL = 0;
+ static int SYSTEM_UI_VISIBILITY_FULLSCREEN = 1;
+ static int SYSTEM_UI_VISIBILITY_TRANSLUCENT = 2;
+
+ // this will trigger new layout updates
+ setSystemUiVisibility(SYSTEM_UI_VISIBILITY_FULLSCREEN);
+ setSystemUiVisibility(SYSTEM_UI_VISIBILITY_NORMAL);
+
+ QJniObject activity = QNativeInterface::QAndroidApplication::context();
+ QVERIFY(activity.isValid());
+
+ QJniObject windowManager =
+ activity.callObjectMethod("getWindowManager", "()Landroid/view/WindowManager;");
+ QVERIFY(windowManager.isValid());
+
+ QJniObject display = windowManager.callObjectMethod("getDefaultDisplay", "()Landroid/view/Display;");
+ QVERIFY(display.isValid());
+
+ QJniObject appSize("android/graphics/Point");
+ QVERIFY(appSize.isValid());
+
+ display.callMethod<void>("getSize", "(Landroid/graphics/Point;)V", appSize.object());
+
+ QJniObject realSize("android/graphics/Point");
+ QVERIFY(realSize.isValid());
+
+ display.callMethod<void>("getRealSize", "(Landroid/graphics/Point;)V", realSize.object());
+
+ QPlatformScreen *screen = QGuiApplication::primaryScreen()->handle();
+
+ {
+ // Normal -
+ // available geometry == app size (system bars visible and removed from available geometry)
+ QCoreApplication::processEvents();
+ QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
+ QVERIFY(window.isValid());
+
+ QJniObject decorView = window.callObjectMethod("getDecorView", "()Landroid/view/View;");
+ QVERIFY(decorView.isValid());
+
+ QJniObject insets =
+ decorView.callObjectMethod("getRootWindowInsets", "()Landroid/view/WindowInsets;");
+ QVERIFY(insets.isValid());
+
+ int insetsWidth = insets.callMethod<jint>("getSystemWindowInsetRight")
+ + insets.callMethod<jint>("getSystemWindowInsetLeft");
+
+ int insetsHeight = insets.callMethod<jint>("getSystemWindowInsetTop")
+ + insets.callMethod<jint>("getSystemWindowInsetBottom");
+
+ QTRY_COMPARE(screen->availableGeometry().width(),
+ int(appSize.getField<jint>("x")) - insetsWidth);
+ QTRY_COMPARE(screen->availableGeometry().height(),
+ int(appSize.getField<jint>("y")) - insetsHeight);
+
+ QTRY_COMPARE(screen->geometry().width(), int(realSize.getField<jint>("x")));
+ QTRY_COMPARE(screen->geometry().height(), int(realSize.getField<jint>("y")));
+ }
+
+ {
+ setSystemUiVisibility(SYSTEM_UI_VISIBILITY_FULLSCREEN);
+
+ // Fullscreen
+ // available geometry == full display size (system bars hidden)
+ QCoreApplication::processEvents();
+ QTRY_COMPARE(screen->availableGeometry().width(), int(realSize.getField<jint>("x")));
+ QTRY_COMPARE(screen->availableGeometry().height(), int(realSize.getField<jint>("y")));
+
+ QTRY_COMPARE(screen->geometry().width(), int(realSize.getField<jint>("x")));
+ QTRY_COMPARE(screen->geometry().height(), int(realSize.getField<jint>("y")));
+ }
+
+ {
+ setSystemUiVisibility(SYSTEM_UI_VISIBILITY_TRANSLUCENT);
+
+ // Translucent
+ // available geometry == full display size (system bars visible but drawable under)
+ QCoreApplication::processEvents();
+ QTRY_COMPARE(screen->availableGeometry().width(), int(realSize.getField<jint>("x")));
+ QTRY_COMPARE(screen->availableGeometry().height(), int(realSize.getField<jint>("y")));
+
+ QTRY_COMPARE(screen->geometry().width(), int(realSize.getField<jint>("x")));
+ QTRY_COMPARE(screen->geometry().height(), int(realSize.getField<jint>("y")));
+ }
+}
+
+void tst_Android::orientationChange_data()
+{
+ QTest::addColumn<int>("nativeOrientation");
+ QTest::addColumn<Qt::ScreenOrientation>("expected");
+ QTest::addColumn<QSize>("screenSize");
+
+ const QSize portraitSize = QGuiApplication::primaryScreen()->size();
+ const QSize landscapeSize = QSize(portraitSize.height(), portraitSize.width());
+
+ // Rotations without 180 degree or inverted portrait, assuming that the device is in portrait
+ // position. These are ok for Android 6(API 23), 8 (API 27) and 14 (API 34)
+ QTest::newRow("InvertedLandscape") << 8 << Qt::InvertedLandscapeOrientation << landscapeSize;
+ QTest::newRow("Portrait") << 1 << Qt::PortraitOrientation << portraitSize;
+ QTest::newRow("Landscape") << 0 << Qt::LandscapeOrientation << landscapeSize;
+ QTest::newRow("Portrait2") << 1 << Qt::PortraitOrientation << portraitSize;
+
+ // Rotations over inverted portrait doing only 90 degree turns.
+ QTest::newRow("InvertedLandscape2") << 8 << Qt::InvertedLandscapeOrientation << landscapeSize;
+ QTest::newRow("InvertedPortrait") << 9 << Qt::InvertedPortraitOrientation << portraitSize;
+ QTest::newRow("Landscape2") << 0 << Qt::LandscapeOrientation << landscapeSize;
+ QTest::newRow("InvertedPortrait2") << 9 << Qt::InvertedPortraitOrientation << portraitSize;
+ QTest::newRow("InvertedLandscape3") << 8 << Qt::InvertedLandscapeOrientation << landscapeSize;
+
+ // Rotations with 180 degree turns.
+ // Android 6 (API23) Does not understand these transitions.
+ if (QNativeInterface::QAndroidApplication::sdkVersion() > __ANDROID_API_M__) {
+ QTest::newRow("Landscape3") << 0 << Qt::LandscapeOrientation << landscapeSize;
+ QTest::newRow("InvertedLandscape4")
+ << 8 << Qt::InvertedLandscapeOrientation << landscapeSize;
+ QTest::newRow("Portrait3") << 1 << Qt::PortraitOrientation << portraitSize;
+ } else {
+ qWarning() << "180 degree turn rotation test cases are not run on Android 6 (API 23) and "
+ "below.";
+ }
+ // Android 8 (API 27) does not understand portrait-'inverted portrait'-portrait transition.
+ if (QNativeInterface::QAndroidApplication::sdkVersion() > __ANDROID_API_O_MR1__) {
+ QTest::newRow("InvertedPortrait3") << 9 << Qt::InvertedPortraitOrientation << portraitSize;
+ QTest::newRow("Portrait4") << 1 << Qt::PortraitOrientation << portraitSize;
+ } else {
+ qWarning() << "Portrait-'Inverted portrait'-Portrait rotation test cases are not run on "
+ "Android 8 (API 27) and below.";
+ }
+}
+
+void tst_Android::orientationChange()
+{
+ QFETCH(int, nativeOrientation);
+ QFETCH(Qt::ScreenOrientation, expected);
+ QFETCH(QSize, screenSize);
+
+ if (QNativeInterface::QAndroidApplication::sdkVersion() == __ANDROID_API_P__)
+ QSKIP("Android 9 orientation changes callbacks are buggy (QTBUG-124890).");
+
+ // For QTBUG-94459 to check that the widget size are consistent after orientation changes
+ QWidget widget;
+ widget.show();
+
+ QScreen *screen = QGuiApplication::primaryScreen();
+ QSignalSpy orientationSpy(screen, SIGNAL(orientationChanged(Qt::ScreenOrientation)));
+
+ auto context = QNativeInterface::QAndroidApplication::context();
+ context.callMethod<void>("setRequestedOrientation", nativeOrientation);
+
+ orientationSpy.wait();
+ QTRY_COMPARE(screen->orientation(), expected);
+ QCOMPARE(orientationSpy.size(), 1);
+ QCOMPARE(screen->size(), screenSize);
+ QCOMPARE(widget.size(), screen->availableSize());
+}
+
+QTEST_MAIN(tst_Android)
+#include "tst_android.moc"
diff --git a/tests/auto/corelib/platform/android_appless/CMakeLists.txt b/tests/auto/corelib/platform/android_appless/CMakeLists.txt
new file mode 100644
index 0000000000..bcb7024b29
--- /dev/null
+++ b/tests/auto/corelib/platform/android_appless/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_android_appless Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_android_appless LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_android_appless
+ SOURCES
+ tst_android_appless.cpp
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/platform/android_appless/tst_android_appless.cpp b/tests/auto/corelib/platform/android_appless/tst_android_appless.cpp
new file mode 100644
index 0000000000..cb7ad8875c
--- /dev/null
+++ b/tests/auto/corelib/platform/android_appless/tst_android_appless.cpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QTimer>
+#include <QGuiApplication>
+#include <QWindow>
+
+using namespace Qt::StringLiterals;
+
+class tst_AndroidAppless : public QObject
+{
+ Q_OBJECT
+private slots:
+ void app_data();
+ void app();
+
+};
+
+#define CREATE_DUMMY_ARGC_ARGV() \
+ int argc = 1; \
+ char *argv[] = { const_cast<char *>("tst_android_appless") };
+
+
+void tst_AndroidAppless::app_data()
+{
+ QTest::addColumn<QString>("displayName");
+ QTest::addRow("one") << "The first QGuiApplication instance";
+ QTest::addRow("two") << "The second QGuiApplication instance";
+}
+
+void tst_AndroidAppless::app()
+{
+ QFETCH(const QString, displayName);
+ CREATE_DUMMY_ARGC_ARGV()
+
+ QGuiApplication app(argc, argv);
+ app.setApplicationDisplayName(displayName);
+
+ QWindow window;
+ window.show();
+
+ QTimer::singleShot(1000, &app, QGuiApplication::quit);
+
+ window.show();
+ app.exec();
+}
+
+#undef CREATE_DUMMY_ARGC_ARGV
+
+QTEST_APPLESS_MAIN(tst_AndroidAppless)
+#include "tst_android_appless.moc"
+
diff --git a/tests/auto/corelib/platform/windows/CMakeLists.txt b/tests/auto/corelib/platform/windows/CMakeLists.txt
new file mode 100644
index 0000000000..24b2a69a0e
--- /dev/null
+++ b/tests/auto/corelib/platform/windows/CMakeLists.txt
@@ -0,0 +1,4 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qcomobject)
diff --git a/tests/auto/corelib/platform/windows/qcomobject/CMakeLists.txt b/tests/auto/corelib/platform/windows/qcomobject/CMakeLists.txt
new file mode 100644
index 0000000000..9cdd6b57bc
--- /dev/null
+++ b/tests/auto/corelib/platform/windows/qcomobject/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcomobject Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcomobject LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcomobject
+ SOURCES
+ tst_qcomobject.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp b/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp
new file mode 100644
index 0000000000..5ad961ee66
--- /dev/null
+++ b/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp
@@ -0,0 +1,268 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#ifdef Q_OS_WIN
+
+# include <private/qcomobject_p.h>
+
+# include <wrl/client.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+template <typename T, typename... Args>
+ComPtr<T> makeComObject(Args &&...args)
+{
+ ComPtr<T> p;
+ // Don't use Attach because of MINGW64 bug
+ // #892 Microsoft::WRL::ComPtr::Attach leaks references
+ *p.GetAddressOf() = new T(std::forward<Args>(args)...);
+ return p;
+}
+
+MIDL_INTERFACE("878fab04-7da0-41ea-9c49-058c7fa0d80a")
+IIntermediate : public IUnknown{};
+
+MIDL_INTERFACE("65a29ce9-191c-4182-9185-06dd70aafc5d")
+IDirect : public IIntermediate{};
+
+class ComImplementation : public QComObject<IDirect>
+{
+};
+
+MIDL_INTERFACE("d05397e0-da7f-4055-8563-a5b80f095e6c")
+IMultipleA : public IUnknown{};
+
+MIDL_INTERFACE("67e298c5-ec5f-4c45-a779-bfba2484e142")
+IMultipleB : public IUnknown{};
+
+class MultipleComImplementation : public QComObject<IMultipleA, IMultipleB>
+{
+};
+
+MIDL_INTERFACE("b8278a1b-0c3b-4bbd-99db-1e8a141483fa")
+IOther : public IUnknown{};
+
+# ifdef __CRT_UUID_DECL
+__CRT_UUID_DECL(IIntermediate, 0x878fab04, 0x7da0, 0x41ea, 0x9c, 0x49, 0x05, 0x8c, 0x7f, 0xa0, 0xd8,
+ 0x0a)
+__CRT_UUID_DECL(IDirect, 0x65a29ce9, 0x191c, 0x4182, 0x91, 0x85, 0x06, 0xdd, 0x70, 0xaa, 0xfc, 0x5d)
+__CRT_UUID_DECL(IMultipleA, 0xd05397e0, 0xda7f, 0x4055, 0x85, 0x63, 0xa5, 0xb8, 0x0f, 0x09, 0x5e,
+ 0x6c)
+__CRT_UUID_DECL(IMultipleB, 0x67e298c5, 0xec5f, 0x4c45, 0xa7, 0x79, 0xbf, 0xba, 0x24, 0x84, 0xe1,
+ 0x42)
+__CRT_UUID_DECL(IOther, 0xb8278a1b, 0x0c3b, 0x4bbd, 0x99, 0xdb, 0x1e, 0x8a, 0x14, 0x14, 0x83, 0xfa)
+# endif
+
+namespace QtPrivate {
+
+template <>
+struct QComObjectTraits<IDirect>
+{
+ static constexpr bool isGuidOf(REFIID riid) noexcept
+ {
+ return QComObjectTraits<IDirect, IIntermediate>::isGuidOf(riid);
+ }
+};
+
+} // namespace QtPrivate
+
+class tst_QComObject : public QObject
+{
+ Q_OBJECT
+private slots:
+ void QueryInterface_returnsConvertedPointer_whenIUnknownIsRequested();
+ void QueryInterface_returnsConvertedPointer_whenDirectParentIsRequested();
+ void QueryInterface_returnsConvertedPointer_whenDirectIntermediateIsRequested();
+ void QueryInterface_returnsConvertedPointer_whenIUnknownOfMultipleParentsIsRequested();
+ void QueryInterface_returnsConvertedPointer_whenFirstOfMultipleParentsIsRequested();
+ void QueryInterface_returnsConvertedPointer_whenSecondOfMultipleParentsIsRequested();
+ void QueryInterface_returnsNullPointer_whenNonParentIsRequested();
+ void QueryInterface_returnsNullPointer_whenNullPointerIsPassedForReceivingObject();
+ void QueryInterface_incrementsReferenceCount_whenConvertedPointerIsReturned();
+ void AddRef_incrementsReferenceCountByOne();
+ void Release_decrementsReferenceCountByOne();
+};
+
+void tst_QComObject::QueryInterface_returnsConvertedPointer_whenIUnknownIsRequested()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ ComPtr<IUnknown> unknown;
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IUnknown), &unknown);
+
+ // Assert
+ QCOMPARE(queryResult, S_OK);
+ QCOMPARE(unknown.Get(), implementation.Get());
+}
+
+void tst_QComObject::QueryInterface_returnsConvertedPointer_whenDirectParentIsRequested()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ ComPtr<IDirect> direct;
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IDirect), &direct);
+
+ // Assert
+ QCOMPARE(queryResult, S_OK);
+ QCOMPARE(direct.Get(), implementation.Get());
+}
+
+void tst_QComObject::QueryInterface_returnsConvertedPointer_whenDirectIntermediateIsRequested()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ ComPtr<IIntermediate> intermediate;
+
+ // Act
+ const HRESULT queryResult =
+ implementation->QueryInterface(__uuidof(IIntermediate), &intermediate);
+
+ // Assert
+ QCOMPARE(queryResult, S_OK);
+ QCOMPARE(intermediate.Get(), implementation.Get());
+}
+
+void tst_QComObject::
+ QueryInterface_returnsConvertedPointer_whenIUnknownOfMultipleParentsIsRequested()
+{
+ // Arrange
+ const ComPtr<MultipleComImplementation> implementation =
+ makeComObject<MultipleComImplementation>();
+
+ ComPtr<IUnknown> unknown;
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IUnknown), &unknown);
+
+ // Assert
+ QCOMPARE(queryResult, S_OK);
+
+ // Cast MultipleComImplementation to IMultipleA to prevent ambiguity
+ QCOMPARE(unknown.Get(), static_cast<IMultipleA *>(implementation.Get()));
+}
+
+void tst_QComObject::QueryInterface_returnsConvertedPointer_whenFirstOfMultipleParentsIsRequested()
+{
+ // Arrange
+ const ComPtr<MultipleComImplementation> implementation =
+ makeComObject<MultipleComImplementation>();
+
+ ComPtr<IMultipleA> multiple;
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IMultipleA), &multiple);
+
+ // Assert
+ QCOMPARE(queryResult, S_OK);
+ QCOMPARE(multiple.Get(), implementation.Get());
+}
+
+void tst_QComObject::QueryInterface_returnsConvertedPointer_whenSecondOfMultipleParentsIsRequested()
+{
+ // Arrange
+ const ComPtr<MultipleComImplementation> implementation =
+ makeComObject<MultipleComImplementation>();
+
+ ComPtr<IMultipleB> multiple;
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IMultipleB), &multiple);
+
+ // Assert
+ QCOMPARE(queryResult, S_OK);
+ QCOMPARE(multiple.Get(), implementation.Get());
+}
+
+void tst_QComObject::QueryInterface_returnsNullPointer_whenNonParentIsRequested()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ ComPtr<IOther> other;
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IOther), &other);
+
+ // Assert
+ QCOMPARE(queryResult, E_NOINTERFACE);
+ QCOMPARE(other.Get(), nullptr);
+}
+
+void tst_QComObject::QueryInterface_returnsNullPointer_whenNullPointerIsPassedForReceivingObject()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ // Act
+ const HRESULT queryResult = implementation->QueryInterface(__uuidof(IUnknown), nullptr);
+
+ // Assert
+ QCOMPARE(queryResult, E_POINTER);
+}
+
+void tst_QComObject::QueryInterface_incrementsReferenceCount_whenConvertedPointerIsReturned()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ ComPtr<IUnknown> unknown;
+
+ // Act
+ implementation->QueryInterface(__uuidof(IUnknown), &unknown);
+
+ // As there's no any way to get the current reference count of an object, just add one more
+ // reference and assert against cumulative reference count value
+ const ULONG referenceCount = implementation->AddRef();
+
+ // Assert
+ QCOMPARE(referenceCount, 3);
+}
+
+void tst_QComObject::AddRef_incrementsReferenceCountByOne()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ // Act
+ const ULONG referenceCount1 = implementation->AddRef();
+ const ULONG referenceCount2 = implementation->AddRef();
+
+ // Assert
+ QCOMPARE(referenceCount1, 2);
+ QCOMPARE(referenceCount2, 3);
+}
+
+void tst_QComObject::Release_decrementsReferenceCountByOne()
+{
+ // Arrange
+ const ComPtr<ComImplementation> implementation = makeComObject<ComImplementation>();
+
+ implementation->AddRef();
+ implementation->AddRef();
+
+ // Act
+ const ULONG referenceCount1 = implementation->Release();
+ const ULONG referenceCount2 = implementation->Release();
+
+ // Assert
+ QCOMPARE(referenceCount1, 2);
+ QCOMPARE(referenceCount2, 1);
+}
+
+QTEST_MAIN(tst_QComObject)
+# include "tst_qcomobject.moc"
+
+QT_END_NAMESPACE
+
+#endif // Q_OS_WIN
diff --git a/tests/auto/corelib/plugin/CMakeLists.txt b/tests/auto/corelib/plugin/CMakeLists.txt
new file mode 100644
index 0000000000..5518231ace
--- /dev/null
+++ b/tests/auto/corelib/plugin/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(QT_BUILD_SHARED_LIBS)
+ add_subdirectory(qfactoryloader)
+endif()
+add_subdirectory(quuid)
+if(QT_FEATURE_library)
+ add_subdirectory(qpluginloader)
+ add_subdirectory(qlibrary)
+endif()
+if(QT_BUILD_SHARED_LIBS AND QT_FEATURE_library)
+ add_subdirectory(qplugin)
+endif()
diff --git a/tests/auto/corelib/plugin/plugin.pro b/tests/auto/corelib/plugin/plugin.pro
deleted file mode 100644
index 240608fddf..0000000000
--- a/tests/auto/corelib/plugin/plugin.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qfactoryloader \
- quuid
-
-qtConfig(library): SUBDIRS += \
- qpluginloader \
- qplugin \
- qlibrary
-
-contains(CONFIG, static) {
- message(Disabling tests requiring shared build of Qt)
- SUBDIRS -= qfactoryloader \
- qplugin
-}
diff --git a/tests/auto/corelib/plugin/qfactoryloader/CMakeLists.txt b/tests/auto/corelib/plugin/qfactoryloader/CMakeLists.txt
new file mode 100644
index 0000000000..14174da173
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfactoryloader LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(plugin1)
+add_subdirectory(plugin2)
+add_subdirectory(staticplugin)
+add_subdirectory(test)
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/CMakeLists.txt b/tests/auto/corelib/plugin/qfactoryloader/plugin1/CMakeLists.txt
new file mode 100644
index 0000000000..c7cedd7e0c
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## plugin1 Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(tst_qfactoryloader_plugin1
+ MODULE
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qfactoryloader/bin"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ SOURCES
+ plugin1.cpp plugin1.h
+ LIBRARIES
+ Qt::Core
+)
+
+if(ANDROID)
+ # On Android the plugins must match the following mask:
+ # "libplugins_{suffix}_*.so"
+ # and the testcase uses "bin" as a suffix
+ set_target_properties(tst_qfactoryloader_plugin1 PROPERTIES
+ OUTPUT_NAME "plugins_bin_tst_qfactoryloader_plugin1")
+endif()
+
+qt_internal_extend_target(tst_qfactoryloader_plugin1 CONDITION NOT QT_FEATURE_library
+ DEFINES
+ QT_STATICPLUGIN
+)
+
+qt_autogen_tools_initial_setup(tst_qfactoryloader_plugin1)
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp
index bfa49dc34e..6731d560a7 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qstring.h>
#include "plugin1.h"
@@ -32,3 +7,5 @@ QString Plugin1::pluginName() const
{
return QLatin1String("Plugin1 ok");
}
+
+#include "moc_plugin1.cpp"
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h
index ca2ceed7a9..aba0b5c2f5 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef THEPLUGIN_H
#define THEPLUGIN_H
@@ -35,11 +10,11 @@
class Plugin1 : public QObject, public PluginInterface1
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface1")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface1" FILE "plugin1.json")
Q_INTERFACES(PluginInterface1)
public:
- virtual QString pluginName() const;
+ virtual QString pluginName() const override;
};
#endif // THEPLUGIN_H
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json
new file mode 100644
index 0000000000..ce67846d48
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.json
@@ -0,0 +1,5 @@
+{
+ "Keys": [
+ "plugin1"
+ ]
+}
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro
deleted file mode 100644
index 44ef12db29..0000000000
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TEMPLATE = lib
-QT = core
-CONFIG += plugin
-HEADERS = plugin1.h
-SOURCES = plugin1.cpp
-TARGET = $$qtLibraryTarget(plugin1)
-DESTDIR = ../bin
-winrt:include(../winrt.pri)
-
-!qtConfig(library): DEFINES += QT_STATICPLUGIN
-
-# This is testdata for the tst_qpluginloader test.
-target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin
-INSTALLS += target
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h
index 408e963adf..a652273eb5 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugininterface1.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef PLUGININTERFACE1_H
#define PLUGININTERFACE1_H
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/CMakeLists.txt b/tests/auto/corelib/plugin/qfactoryloader/plugin2/CMakeLists.txt
new file mode 100644
index 0000000000..259d6fb739
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## plugin2 Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(tst_qfactoryloader_plugin2
+ MODULE
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qfactoryloader/bin"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ SOURCES
+ plugin2.cpp plugin2.h
+ LIBRARIES
+ Qt::Core
+)
+
+if(ANDROID)
+ # On Android the plugins must match the following mask:
+ # "libplugins_{suffix}_*.so"
+ # and the testcase uses "bin" as a suffix
+ set_target_properties(tst_qfactoryloader_plugin2 PROPERTIES
+ OUTPUT_NAME "plugins_bin_tst_qfactoryloader_plugin2")
+endif()
+
+qt_internal_extend_target(tst_qfactoryloader_plugin2 CONDITION NOT QT_FEATURE_library
+ DEFINES
+ QT_STATICPLUGIN
+)
+
+qt_autogen_tools_initial_setup(tst_qfactoryloader_plugin2)
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp
index 34a7207f10..c2ac873317 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qstring.h>
#include "plugin2.h"
@@ -32,3 +7,5 @@ QString Plugin2::pluginName() const
{
return QLatin1String("Plugin2 ok");
}
+
+#include "moc_plugin2.cpp"
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h
index 130bf66561..02ef062b77 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef THEPLUGIN_H
#define THEPLUGIN_H
@@ -39,7 +14,7 @@ class Plugin2 : public QObject, public PluginInterface2
Q_INTERFACES(PluginInterface2)
public:
- virtual QString pluginName() const;
+ virtual QString pluginName() const override;
};
#endif // THEPLUGIN_H
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro
deleted file mode 100644
index 5689919108..0000000000
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TEMPLATE = lib
-QT = core
-CONFIG += plugin
-HEADERS = plugin2.h
-SOURCES = plugin2.cpp
-TARGET = $$qtLibraryTarget(plugin2)
-DESTDIR = ../bin
-winrt:include(../winrt.pri)
-
-!qtConfig(library): DEFINES += QT_STATICPLUGIN
-
-# This is testdata for the tst_qpluginloader test.
-target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin
-INSTALLS += target
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h
index e9b7e14048..df30f2ffd3 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugininterface2.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef PLUGININTERFACE2_H
#define PLUGININTERFACE2_H
diff --git a/tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro b/tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro
deleted file mode 100644
index f0430d55e6..0000000000
--- a/tests/auto/corelib/plugin/qfactoryloader/qfactoryloader.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-QT = core-private
-TEMPLATE = subdirs
-
-test.depends = plugin1 plugin2
-SUBDIRS = \
- plugin1 \
- plugin2 \
- test
-
-TARGET = tst_qpluginloader
-
-# no special install rule for subdir
-INSTALLS =
-
-
diff --git a/tests/auto/corelib/plugin/qfactoryloader/staticplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qfactoryloader/staticplugin/CMakeLists.txt
new file mode 100644
index 0000000000..c43a69c707
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/staticplugin/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_cmake_library(tst_qfactoryloader_staticplugin
+ STATIC
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+)
+
+qt_autogen_tools_initial_setup(tst_qfactoryloader_staticplugin)
+
+target_compile_definitions(tst_qfactoryloader_staticplugin PRIVATE QT_STATICPLUGIN)
diff --git a/tests/auto/corelib/plugin/qfactoryloader/staticplugin/main.cpp b/tests/auto/corelib/plugin/qfactoryloader/staticplugin/main.cpp
new file mode 100644
index 0000000000..6506f9cf9b
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/staticplugin/main.cpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QtPlugin>
+#include <QObject>
+
+class StaticPlugin1 : public QObject
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "StaticPlugin1" FILE "plugin.json")
+public:
+ StaticPlugin1() {}
+};
+
+class StaticPlugin2 : public QObject
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "StaticPlugin2" FILE "plugin.json")
+public:
+ StaticPlugin2() {}
+};
+
+#include "main.moc"
diff --git a/tests/auto/corelib/plugin/qfactoryloader/staticplugin/plugin.json b/tests/auto/corelib/plugin/qfactoryloader/staticplugin/plugin.json
new file mode 100644
index 0000000000..7321080fb4
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/staticplugin/plugin.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "Value" ]
+}
diff --git a/tests/auto/corelib/plugin/qfactoryloader/test/CMakeLists.txt b/tests/auto/corelib/plugin/qfactoryloader/test/CMakeLists.txt
new file mode 100644
index 0000000000..fb3b6f5acb
--- /dev/null
+++ b/tests/auto/corelib/plugin/qfactoryloader/test/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfactoryloader Test:
+#####################################################################
+
+qt_internal_add_test(tst_qfactoryloader
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../plugin1/plugininterface1.h
+ ../plugin2/plugininterface2.h
+ ../tst_qfactoryloader.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ tst_qfactoryloader_staticplugin
+)
+
+qt_internal_extend_target(tst_qfactoryloader CONDITION NOT QT_FEATURE_library
+ LIBRARIES
+ tst_qfactoryloader_plugin1
+ tst_qfactoryloader_plugin2
+)
+
+add_dependencies(tst_qfactoryloader tst_qfactoryloader_plugin1 tst_qfactoryloader_plugin2)
+
+if(ANDROID)
+ # QT_ANDROID_EXTRA_PLUGINS requires a list of directories, not files!
+ set_target_properties(tst_qfactoryloader PROPERTIES
+ QT_ANDROID_EXTRA_PLUGINS "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ )
+endif()
diff --git a/tests/auto/corelib/plugin/qfactoryloader/test/test.pro b/tests/auto/corelib/plugin/qfactoryloader/test/test.pro
deleted file mode 100644
index 5e4d65a49f..0000000000
--- a/tests/auto/corelib/plugin/qfactoryloader/test/test.pro
+++ /dev/null
@@ -1,30 +0,0 @@
-CONFIG += testcase
-TARGET = ../tst_qfactoryloader
-QT = core-private testlib
-
-SOURCES = \
- ../tst_qfactoryloader.cpp
-
-HEADERS = \
- ../plugin1/plugininterface1.h \
- ../plugin2/plugininterface2.h
-
-win32 {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qfactoryloader
- } else {
- TARGET = ../../release/tst_qfactoryloader
- }
-}
-
-!qtConfig(library) {
- LIBS += -L ../bin/ -lplugin1 -lplugin2
-}
-
-android {
- libs.prefix = android_test_data
- libs.base = $$OUT_PWD/..
- libs.files += $$OUT_PWD/../bin
-
- RESOURCES += libs
-}
diff --git a/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp
index 9fa61804b3..faec311f2d 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp
+++ b/tests/auto/corelib/plugin/qfactoryloader/tst_qfactoryloader.cpp
@@ -1,36 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/qtest.h>
#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qplugin.h>
+#include <QtCore/qversionnumber.h>
#include <private/qfactoryloader_p.h>
+#include <private/qlibrary_p.h>
#include "plugin1/plugininterface1.h"
#include "plugin2/plugininterface2.h"
@@ -43,54 +20,202 @@ class tst_QFactoryLoader : public QObject
{
Q_OBJECT
-#ifdef Q_OS_ANDROID
- QSharedPointer<QTemporaryDir> directory;
-#endif
-
+ QString binFolder;
public slots:
void initTestCase();
private slots:
void usingTwoFactoriesFromSameDir();
+ void extraSearchPath();
+ void multiplePaths();
+ void staticPlugin_data();
+ void staticPlugin();
};
static const char binFolderC[] = "bin";
void tst_QFactoryLoader::initTestCase()
{
-#ifdef Q_OS_ANDROID
- directory = QEXTRACTTESTDATA("android_test_data");
- QVERIFY(directory);
- QVERIFY(directory->isValid());
- QVERIFY2(QDir::setCurrent(directory->path()), qPrintable("Could not chdir to " + directory->path()));
-#endif
- const QString binFolder = QFINDTESTDATA(binFolderC);
+ // On Android the plugins are bundled into APK's libs subdir
+#ifndef Q_OS_ANDROID
+ binFolder = QFINDTESTDATA(binFolderC);
QVERIFY2(!binFolder.isEmpty(), "Unable to locate 'bin' folder");
-#if QT_CONFIG(library)
- QCoreApplication::setLibraryPaths(QStringList(QFileInfo(binFolder).absolutePath()));
#endif
}
void tst_QFactoryLoader::usingTwoFactoriesFromSameDir()
{
+#if QT_CONFIG(library) && !defined(Q_OS_ANDROID)
+ // set the library path to contain the directory where the 'bin' dir is located
+ QCoreApplication::setLibraryPaths( { QFileInfo(binFolder).absolutePath() });
+#endif
+ auto versionNumber = [](const QCborValue &value) {
+ // Qt plugins only store major & minor versions in the metadata, so
+ // the low 8 bits are always zero.
+ qint64 v = value.toInteger();
+ return QVersionNumber(v >> 16, uchar(v >> 8));
+ };
+ QVersionNumber qtVersion(QT_VERSION_MAJOR, 0);
+
const QString suffix = QLatin1Char('/') + QLatin1String(binFolderC);
QFactoryLoader loader1(PluginInterface1_iid, suffix);
+ const QFactoryLoader::MetaDataList list1 = loader1.metaData();
+ const QList<QCborArray> keys1 = loader1.metaDataKeys();
+ QCOMPARE(list1.size(), 1);
+ QCOMPARE(keys1.size(), 1);
+ QCOMPARE_GE(versionNumber(list1[0].value(QtPluginMetaDataKeys::QtVersion)), qtVersion);
+ QCOMPARE(list1[0].value(QtPluginMetaDataKeys::IID), PluginInterface1_iid);
+ QCOMPARE(list1[0].value(QtPluginMetaDataKeys::ClassName), "Plugin1");
- PluginInterface1 *plugin1 = qobject_cast<PluginInterface1 *>(loader1.instance(0));
+ // plugin1's Q_PLUGIN_METADATA has FILE "plugin1.json"
+ QCborValue metadata1 = list1[0].value(QtPluginMetaDataKeys::MetaData);
+ QCOMPARE(metadata1.type(), QCborValue::Map);
+ QCOMPARE(metadata1["Keys"], QCborArray{ "plugin1" });
+ QCOMPARE(keys1[0], QCborArray{ "plugin1" });
+ QCOMPARE(loader1.indexOf("Plugin1"), 0);
+ QCOMPARE(loader1.indexOf("PLUGIN1"), 0);
+ QCOMPARE(loader1.indexOf("Plugin2"), -1);
+
+ QFactoryLoader loader2(PluginInterface2_iid, suffix);
+ const QFactoryLoader::MetaDataList list2 = loader2.metaData();
+ const QList<QCborArray> keys2 = loader2.metaDataKeys();
+ QCOMPARE(list2.size(), 1);
+ QCOMPARE(keys2.size(), 1);
+ QCOMPARE_GE(versionNumber(list2[0].value(QtPluginMetaDataKeys::QtVersion)), qtVersion);
+ QCOMPARE(list2[0].value(QtPluginMetaDataKeys::IID), PluginInterface2_iid);
+ QCOMPARE(list2[0].value(QtPluginMetaDataKeys::ClassName), "Plugin2");
+
+ // plugin2's Q_PLUGIN_METADATA does not have FILE
+ QCOMPARE(list2[0].value(QtPluginMetaDataKeys::MetaData), QCborValue());
+ QCOMPARE(keys2[0], QCborArray());
+ QCOMPARE(loader2.indexOf("Plugin1"), -1);
+ QCOMPARE(loader2.indexOf("Plugin2"), -1);
+
+ QObject *obj1 = loader1.instance(0);
+ PluginInterface1 *plugin1 = qobject_cast<PluginInterface1 *>(obj1);
QVERIFY2(plugin1,
qPrintable(QString::fromLatin1("Cannot load plugin '%1'")
.arg(QLatin1String(PluginInterface1_iid))));
+ QCOMPARE(obj1->metaObject()->className(), "Plugin1");
- QFactoryLoader loader2(PluginInterface2_iid, suffix);
-
- PluginInterface2 *plugin2 = qobject_cast<PluginInterface2 *>(loader2.instance(0));
+ QObject *obj2 = loader2.instance(0);
+ PluginInterface2 *plugin2 = qobject_cast<PluginInterface2 *>(obj2);
QVERIFY2(plugin2,
qPrintable(QString::fromLatin1("Cannot load plugin '%1'")
.arg(QLatin1String(PluginInterface2_iid))));
+ QCOMPARE(obj2->metaObject()->className(), "Plugin2");
QCOMPARE(plugin1->pluginName(), QLatin1String("Plugin1 ok"));
QCOMPARE(plugin2->pluginName(), QLatin1String("Plugin2 ok"));
}
+void tst_QFactoryLoader::extraSearchPath()
+{
+#if defined(Q_OS_ANDROID) && !QT_CONFIG(library)
+ QSKIP("Test not applicable in this configuration.");
+#else
+#ifdef Q_OS_ANDROID
+ // On Android the libs are not stored in binFolder, but bundled into
+ // APK's libs subdir
+ const QStringList androidLibsPaths = QCoreApplication::libraryPaths();
+ QCOMPARE(androidLibsPaths.size(), 1);
+#endif
+ QCoreApplication::setLibraryPaths(QStringList());
+
+#ifndef Q_OS_ANDROID
+ QString pluginsPath = QFileInfo(binFolder).absoluteFilePath();
+ QFactoryLoader loader1(PluginInterface1_iid, "/nonexistent");
+#else
+ QString pluginsPath = androidLibsPaths.first();
+ // On Android we still need to specify a valid suffix, because it's a part
+ // of a file name, not directory structure
+ const QString suffix = QLatin1Char('/') + QLatin1String(binFolderC);
+ QFactoryLoader loader1(PluginInterface1_iid, suffix);
+#endif
+
+ // it shouldn't have scanned anything because we haven't given it a path yet
+ QVERIFY(loader1.metaData().isEmpty());
+
+ loader1.setExtraSearchPath(pluginsPath);
+ PluginInterface1 *plugin1 = qobject_cast<PluginInterface1 *>(loader1.instance(0));
+ QVERIFY2(plugin1,
+ qPrintable(QString::fromLatin1("Cannot load plugin '%1'")
+ .arg(QLatin1String(PluginInterface1_iid))));
+
+ QCOMPARE(plugin1->pluginName(), QLatin1String("Plugin1 ok"));
+
+ // check that it forgets that plugin
+ loader1.setExtraSearchPath(QString());
+ QVERIFY(loader1.metaData().isEmpty());
+#endif
+}
+
+void tst_QFactoryLoader::multiplePaths()
+{
+#if !QT_CONFIG(library) || !(defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)) || defined(Q_OS_ANDROID)
+ QSKIP("Test not applicable in this configuration.");
+#else
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+
+ QString pluginsPath = QFileInfo(binFolder, binFolderC).absolutePath();
+ QString linkPath = dir.filePath(binFolderC);
+ QVERIFY(QFile::link(pluginsPath, linkPath));
+
+ QCoreApplication::setLibraryPaths({ QFileInfo(binFolder).absolutePath(), dir.path() });
+
+ const QString suffix = QLatin1Char('/') + QLatin1String(binFolderC);
+ QFactoryLoader loader1(PluginInterface1_iid, suffix);
+
+ QLibraryPrivate *library1 = loader1.library("plugin1");
+ QVERIFY(library1);
+ QCOMPARE(library1->loadHints(), QLibrary::PreventUnloadHint);
+#endif
+}
+
+Q_IMPORT_PLUGIN(StaticPlugin1)
+Q_IMPORT_PLUGIN(StaticPlugin2)
+constexpr bool IsDebug =
+#ifdef QT_NO_DEBUG
+ false &&
+#endif
+ true;
+
+void tst_QFactoryLoader::staticPlugin_data()
+{
+ QTest::addColumn<QString>("iid");
+ auto addRow = [](const char *iid) {
+ QTest::addRow("%s", iid) << QString(iid);
+ };
+ addRow("StaticPlugin1");
+ addRow("StaticPlugin2");
+}
+
+void tst_QFactoryLoader::staticPlugin()
+{
+ QFETCH(QString, iid);
+ QFactoryLoader loader(iid.toLatin1(), "/irrelevant");
+ QFactoryLoader::MetaDataList list = loader.metaData();
+ QCOMPARE(list.size(), 1);
+
+ QCborMap map = list.at(0).toCbor();
+ QCOMPARE(map[int(QtPluginMetaDataKeys::QtVersion)],
+ QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, 0));
+ QCOMPARE(map[int(QtPluginMetaDataKeys::IID)], iid);
+ QCOMPARE(map[int(QtPluginMetaDataKeys::ClassName)], iid);
+ QCOMPARE(map[int(QtPluginMetaDataKeys::IsDebug)], IsDebug);
+
+ QCborValue metaData = map[int(QtPluginMetaDataKeys::MetaData)];
+ QVERIFY(metaData.isMap());
+ QCOMPARE(metaData["Keys"], QCborArray{ "Value" });
+ QCOMPARE(loader.metaDataKeys(), QList{ QCborArray{ "Value" } });
+ QCOMPARE(loader.indexOf("Value"), 0);
+
+ // instantiate
+ QObject *instance = loader.instance(0);
+ QVERIFY(instance);
+ QCOMPARE(instance->metaObject()->className(), iid);
+}
+
QTEST_MAIN(tst_QFactoryLoader)
#include "tst_qfactoryloader.moc"
diff --git a/tests/auto/corelib/plugin/qfactoryloader/winrt.pri b/tests/auto/corelib/plugin/qfactoryloader/winrt.pri
deleted file mode 100644
index 31602634b2..0000000000
--- a/tests/auto/corelib/plugin/qfactoryloader/winrt.pri
+++ /dev/null
@@ -1,9 +0,0 @@
-# We cannot use TESTDATA as plugins have to reside physically
-# inside the package directory
-winrt {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug/bin
- } else {
- DESTDIR = ../release/bin
- }
-}
diff --git a/tests/auto/corelib/plugin/qlibrary/CMakeLists.txt b/tests/auto/corelib/plugin/qlibrary/CMakeLists.txt
new file mode 100644
index 0000000000..b8f4af5aa8
--- /dev/null
+++ b/tests/auto/corelib/plugin/qlibrary/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlibrary LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(lib)
+add_subdirectory(lib2)
+add_subdirectory(tst)
diff --git a/tests/auto/corelib/plugin/qlibrary/lib/CMakeLists.txt b/tests/auto/corelib/plugin/qlibrary/lib/CMakeLists.txt
new file mode 100644
index 0000000000..1a318e1483
--- /dev/null
+++ b/tests/auto/corelib/plugin/qlibrary/lib/CMakeLists.txt
@@ -0,0 +1,75 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## mylib Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(mylib
+ SHARED
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qlibrary"
+ SOURCES
+ mylib.c
+ LIBRARIES
+ Qt::Core
+)
+
+set_target_properties(mylib PROPERTIES
+ VERSION 1.0.0
+ SOVERSION 1
+ C_VISIBILITY_PRESET "default"
+ CXX_VISIBILITY_PRESET "default"
+)
+
+if(WIN32)
+ # CMake sets for Windows-GNU platforms the suffix "lib"
+ set_property(TARGET mylib PROPERTY PREFIX "")
+endif()
+
+if(UNIX)
+ if(APPLE)
+ add_custom_command(TARGET mylib POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib>
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.1.0.0.dylib"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.1.0.0.dylib"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.1.dylib"
+ VERBATIM)
+ elseif(NOT ANDROID)
+ add_custom_command(TARGET mylib POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib>
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so.1.0.0"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.so.1.0.0"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so.1"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.so.1.0.0"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so1"
+ VERBATIM)
+ else()
+ # Android does not use symlinks. Also, according to our conventions,
+ # libraries on Android MUST be named in the following pattern:
+ # lib*.so
+ add_custom_command(TARGET mylib POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib>
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so"
+ VERBATIM)
+ endif()
+else() #Win32
+ add_custom_command(TARGET mylib POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib>
+ "${CMAKE_CURRENT_BINARY_DIR}/../mylib.dll"
+ VERBATIM)
+endif()
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(mylib CONDITION MSVC
+ DEFINES
+ WIN32_MSVC
+)
diff --git a/tests/auto/corelib/plugin/qlibrary/lib/lib.pro b/tests/auto/corelib/plugin/qlibrary/lib/lib.pro
deleted file mode 100644
index c44cd46597..0000000000
--- a/tests/auto/corelib/plugin/qlibrary/lib/lib.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-TEMPLATE = lib
-CONFIG += dll
-CONFIG -= staticlib
-SOURCES = mylib.c
-TARGET = mylib
-DESTDIR = ../
-QT = core
-
-msvc: DEFINES += WIN32_MSVC
-
-# This project is testdata for tst_qlibrary
-target.path = $$[QT_INSTALL_TESTS]/tst_qlibrary
-INSTALLS += target
-
-win32 {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug/
- } else {
- DESTDIR = ../release/
- }
-}
diff --git a/tests/auto/corelib/plugin/qlibrary/lib/mylib.c b/tests/auto/corelib/plugin/qlibrary/lib/mylib.c
index 419c22a446..61fe52d182 100644
--- a/tests/auto/corelib/plugin/qlibrary/lib/mylib.c
+++ b/tests/auto/corelib/plugin/qlibrary/lib/mylib.c
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qglobal.h>
diff --git a/tests/auto/corelib/plugin/qlibrary/lib2/CMakeLists.txt b/tests/auto/corelib/plugin/qlibrary/lib2/CMakeLists.txt
new file mode 100644
index 0000000000..f6bdeb453a
--- /dev/null
+++ b/tests/auto/corelib/plugin/qlibrary/lib2/CMakeLists.txt
@@ -0,0 +1,110 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## mylib Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(mylib2
+ SHARED
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}tst_qlibrary"
+ #OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ mylib.c
+ LIBRARIES
+ Qt::Core
+)
+
+# This test is very "annoying" to get working with CMake as it involves having
+# two targets with the same name on the parent scope, which is not possible with
+# CMake. Furthermore, on UNIX, this version of the library should override the
+# root symlink (libmylib.so) to point to version 2.
+# Since we can't build two targets with the same name and in the same directory,
+# we build mylib2 in it's own directory and manually copy and create the
+# symlinks in the parent directory.
+# Finally we also need to create a libmylib.so2 file in the parent directory.
+#
+set_target_properties(mylib2 PROPERTIES
+ OUTPUT_NAME mylib
+)
+set_target_properties(mylib2 PROPERTIES
+ VERSION 2.0.0
+ SOVERSION 2
+ C_VISIBILITY_PRESET "default"
+ CXX_VISIBILITY_PRESET "default"
+)
+
+if(WIN32)
+ # CMake sets for Windows-GNU platforms the suffix "lib"
+ set_property(TARGET mylib2 PROPERTY PREFIX "")
+endif()
+
+if(UNIX)
+ if(APPLE)
+ add_custom_command(TARGET mylib2 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../system.qt.test.mylib.so.dylib"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.2.0.0.dylib"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.2.0.0.dylib"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.2.dylib"
+ COMMAND ${CMAKE_COMMAND} -E remove
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.dylib"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.2.0.0.dylib"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.dylib"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.2.0.0.dylib"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so2.dylib"
+ VERBATIM)
+ elseif(NOT ANDROID)
+ add_custom_command(TARGET mylib2 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../system.qt.test.mylib.so"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so.2.0.0"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.so.2.0.0"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so.2"
+ COMMAND ${CMAKE_COMMAND} -E remove
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.so.2.0.0"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "libmylib.so.2.0.0"
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so2"
+ VERBATIM)
+ else()
+ # Android does not use symlinks. Also, according to our conventions,
+ # libraries on Android MUST be named in the following pattern:
+ # lib*.so
+ add_custom_command(TARGET mylib2 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../libsystem.qt.test.mylib.so"
+ VERBATIM)
+ endif()
+else() #Win32
+ add_custom_command(TARGET mylib2 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../system.qt.test.mylib.dll"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:mylib2>
+ "${CMAKE_CURRENT_BINARY_DIR}/../mylib.dl2"
+ VERBATIM)
+endif()
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(mylib2 CONDITION MSVC
+ DEFINES
+ WIN32_MSVC
+)
diff --git a/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro b/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro
deleted file mode 100644
index bfda0e0194..0000000000
--- a/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro
+++ /dev/null
@@ -1,47 +0,0 @@
-TEMPLATE = lib
-CONFIG += dll
-CONFIG -= staticlib
-SOURCES = mylib.c
-TARGET = mylib
-DESTDIR = ../
-VERSION = 2
-QT = core
-
-msvc: DEFINES += WIN32_MSVC
-
-# Force a copy of the library to have an extension that is non-standard.
-# We want to test if we can load a shared library with *any* filename...
-
-win32 {
- CONFIG(debug, debug|release) {
- BUILD_FOLDER = debug
- } else {
- BUILD_FOLDER = release
- }
- DESTDIR = ../$$BUILD_FOLDER/
-
- # vcproj and Makefile generators refer to target differently
- contains(TEMPLATE,vc.*) {
- src = $(TargetPath)
- } else {
- src = $(DESTDIR_TARGET)
- }
- files = $$BUILD_FOLDER$${QMAKE_DIR_SEP}mylib.dl2 $$BUILD_FOLDER$${QMAKE_DIR_SEP}system.qt.test.mylib.dll
-} else {
- src = $(DESTDIR)$(TARGET)
- files = libmylib.so2 system.qt.test.mylib.so
-}
-
-# This project is testdata for tst_qlibrary
-target.path = $$[QT_INSTALL_TESTS]$${QMAKE_DIR_SEP}tst_qlibrary
-renamed_target.path = $$target.path
-
-for(file, files) {
- QMAKE_POST_LINK += $$QMAKE_COPY $$src ..$$QMAKE_DIR_SEP$$file &&
- renamed_target.extra += $$QMAKE_COPY $$src $(INSTALL_ROOT)$${target.path}$$QMAKE_DIR_SEP$$file &&
- CLEAN_FILES += ..$$QMAKE_DIR_SEP$$file
-}
-renamed_target.extra = $$member(renamed_target.extra, 0, -2)
-QMAKE_POST_LINK = $$member(QMAKE_POST_LINK, 0, -2)
-
-INSTALLS += target renamed_target
diff --git a/tests/auto/corelib/plugin/qlibrary/lib2/mylib.c b/tests/auto/corelib/plugin/qlibrary/lib2/mylib.c
index 74eb68b2ac..5312a9355b 100644
--- a/tests/auto/corelib/plugin/qlibrary/lib2/mylib.c
+++ b/tests/auto/corelib/plugin/qlibrary/lib2/mylib.c
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qglobal.h>
diff --git a/tests/auto/corelib/plugin/qlibrary/qlibrary.pro b/tests/auto/corelib/plugin/qlibrary/qlibrary.pro
deleted file mode 100644
index ec230601c4..0000000000
--- a/tests/auto/corelib/plugin/qlibrary/qlibrary.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-QT = core
-TEMPLATE = subdirs
-
-tst.depends = lib lib2
-# lib2 has to be installed after lib, so that plain libmylib.so symlink points
-# to version 2 as expected by the test
-lib2.depends = lib
-
-SUBDIRS = lib \
- lib2 \
- tst
-TARGET = tst_qlibrary
-
-# no special install rule for subdir
-INSTALLS =
diff --git a/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt b/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt
new file mode 100644
index 0000000000..fc452f37f5
--- /dev/null
+++ b/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qlibrary Test:
+#####################################################################
+
+# Collect test data
+list(APPEND test_data "../library_path/invalid.so")
+
+qt_internal_add_test(tst_qlibrary
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../tst_qlibrary.cpp
+ TESTDATA ${test_data}
+ LIBRARIES mylib mylib2
+)
+
+add_dependencies(tst_qlibrary mylib mylib2)
+
+if(ANDROID)
+ list(APPEND extra_libs
+ "${CMAKE_CURRENT_BINARY_DIR}/../libmylib.so")
+ list(APPEND extra_libs
+ "${CMAKE_CURRENT_BINARY_DIR}/../libsystem.qt.test.mylib.so")
+ set_target_properties(tst_qlibrary PROPERTIES
+ QT_ANDROID_EXTRA_LIBS "${extra_libs}")
+endif()
diff --git a/tests/auto/corelib/plugin/qlibrary/tst/tst.pro b/tests/auto/corelib/plugin/qlibrary/tst/tst.pro
deleted file mode 100644
index 56bef14405..0000000000
--- a/tests/auto/corelib/plugin/qlibrary/tst/tst.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-CONFIG += testcase
-TARGET = ../tst_qlibrary
-QT = core testlib
-SOURCES = ../tst_qlibrary.cpp
-
-win32 {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qlibrary
- } else {
- TARGET = ../../release/tst_qlibrary
- }
-}
-
-TESTDATA += ../library_path/invalid.so
-
-android {
- libs.prefix = android_test_data
- libs.base = $$OUT_PWD/..
- libs.files += $$OUT_PWD/../libmylib.so \
- $$OUT_PWD/../libmylib.so2 \
- $$OUT_PWD/../libmylib.prl \
- $$OUT_PWD/../system.qt.test.mylib.so
-
- RESOURCES += libs
-}
diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
index c9c9202a80..28f4581997 100644
--- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
+++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
@@ -1,36 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <qdir.h>
#include <qlibrary.h>
-#include <QtCore/QRegExp>
+#include <QtCore/QRegularExpression>
// Helper macros to let us know if some suffixes and prefixes are valid
@@ -104,24 +79,27 @@ enum QLibraryOperation {
QString sys_qualifiedLibraryName(const QString &fileName);
QString directory;
-#ifdef Q_OS_ANDROID
- QSharedPointer<QTemporaryDir> temporaryDir;
-#endif
private slots:
void initTestCase();
+ void cleanup();
- void load();
void load_data();
- void library_data();
+ void load();
void resolve_data();
void resolve();
void unload_data();
void unload();
void unload_after_implicit_load();
+ void setFilenameAfterFailedLoad();
+ void loadAfterFailedLoad();
void isLibrary_data();
void isLibrary();
void version_data();
void version();
+ void loadTwoVersions();
+ void setFileNameAndVersionTwice();
+ void setFileNameAndVersionAfterFailedLoad_data() { version_data(); }
+ void setFileNameAndVersionAfterFailedLoad();
void errorString_data();
void errorString();
void loadHints();
@@ -141,34 +119,49 @@ typedef int (*VersionFunction)(void);
void tst_QLibrary::initTestCase()
{
#ifdef Q_OS_ANDROID
- auto tempDir = QEXTRACTTESTDATA("android_test_data");
-
- QVERIFY2(QDir::setCurrent(tempDir->path()), qPrintable("Could not chdir to " + tempDir->path()));
-
- // copy :/library_path into ./library_path
- QVERIFY(QDir().mkdir("library_path"));
- QDirIterator iterator(":/library_path", QDirIterator::Subdirectories);
- while (iterator.hasNext()) {
- iterator.next();
- QFileInfo sourceFileInfo(iterator.path());
- QFileInfo targetFileInfo("./library_path/" + sourceFileInfo.fileName());
- if (!targetFileInfo.exists()) {
- QDir().mkpath(targetFileInfo.path());
- QVERIFY(QFile::copy(sourceFileInfo.filePath(), targetFileInfo.filePath()));
- }
- }
- directory = tempDir->path();
- temporaryDir = std::move(tempDir);
-#elif !defined(Q_OS_WINRT)
+ const QStringList paths = QCoreApplication::libraryPaths();
+ QVERIFY(!paths.isEmpty());
+ directory = paths.first();
+#else
// chdir to our testdata directory, and use relative paths in some tests.
QString testdatadir = QFileInfo(QFINDTESTDATA("library_path")).absolutePath();
QVERIFY2(QDir::setCurrent(testdatadir), qPrintable("Could not chdir to " + testdatadir));
directory = QCoreApplication::applicationDirPath();
-#elif defined(Q_OS_WINRT)
- directory = QCoreApplication::applicationDirPath();
#endif
}
+void tst_QLibrary::cleanup()
+{
+ // unload the libraries, if they are still loaded after the test ended
+ // (probably in a failure)
+
+ static struct {
+ QString name;
+ int version = -1;
+ } libs[] = {
+ { directory + "/mylib" },
+ { directory + "/mylib", 1 },
+ { directory + "/mylib", 2 },
+ { sys_qualifiedLibraryName("mylib") },
+
+ // stuff that load_data() succeeds with
+ { directory + "/" PREFIX "mylib" },
+ { directory + "/" PREFIX "mylib" SUFFIX },
+#if defined(Q_OS_WIN32)
+ { directory + "/mylib.dl2" },
+ { directory + "/system.qt.test.mylib.dll" },
+#elif !defined(Q_OS_ANDROID)
+ // .so even on macOS
+ { directory + "/libmylib.so2" },
+ { directory + "/system.qt.test.mylib.so" },
+#endif
+
+ };
+ for (const auto &entry : libs) {
+ do {} while (QLibrary(entry.name, entry.version).unload());
+ }
+}
+
void tst_QLibrary::version_data()
{
#ifdef Q_OS_ANDROID
@@ -205,6 +198,70 @@ void tst_QLibrary::version()
#endif
}
+void tst_QLibrary::loadTwoVersions()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_WIN)
+ QSKIP("Versioned files are not generated for this OS, so this test is not applicable.");
+#endif
+
+ QLibrary lib1(directory + "/mylib", 1);
+ QLibrary lib2(directory + "/mylib", 2);
+ QVERIFY(!lib1.isLoaded());
+ QVERIFY(!lib2.isLoaded());
+
+ // load the first one
+ QVERIFY(lib1.load());
+ QVERIFY(lib1.isLoaded());
+
+ // let's see if we can load the second one too
+ QVERIFY(lib2.load());
+ QVERIFY(lib2.isLoaded());
+
+ auto p1 = (VersionFunction)lib1.resolve("mylibversion");
+ QVERIFY(p1);
+
+ auto p2 = (VersionFunction)lib2.resolve("mylibversion");
+ QVERIFY(p2);
+
+ QCOMPARE_NE(p1(), p2());
+
+ lib2.unload();
+ lib1.unload();
+}
+
+void tst_QLibrary::setFileNameAndVersionTwice()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_WIN)
+ QSKIP("Versioned files are not generated for this OS, so this test is not applicable.");
+#endif
+
+ QLibrary library(directory + "/mylib", 1);
+ QVERIFY(library.load());
+ QVERIFY(library.isLoaded());
+
+ auto p1 = (VersionFunction)library.resolve("mylibversion");
+ QVERIFY(p1);
+ // don't .unload()
+
+ library.setFileNameAndVersion(directory + "/mylib", 2);
+ QVERIFY(!library.isLoaded());
+ QVERIFY(library.load());
+ QVERIFY(library.isLoaded());
+
+ auto p2 = (VersionFunction)library.resolve("mylibversion");
+ QVERIFY(p2);
+ QCOMPARE_NE(p1(), p2());
+
+ QVERIFY(library.unload());
+ QVERIFY(!library.isLoaded());
+
+ // set back
+ // it'll look like it isn't loaded, but it is and we can't unload it!
+ library.setFileNameAndVersion(directory + "/mylib", 1);
+ QVERIFY(!library.isLoaded());
+ QVERIFY(!library.unload());
+}
+
void tst_QLibrary::load_data()
{
QTest::addColumn<QString>("lib");
@@ -216,7 +273,7 @@ void tst_QLibrary::load_data()
QTest::newRow( "notexist" ) << appDir + "/nolib" << false;
QTest::newRow( "badlibrary" ) << appDir + "/qlibrary.pro" << false;
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
QTest::newRow("ok (libmylib ver. 1)") << appDir + "/libmylib" <<true;
#endif
@@ -226,7 +283,10 @@ void tst_QLibrary::load_data()
QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.dll" << true;
# elif defined Q_OS_UNIX
QTest::newRow( "ok01 (with suffix)" ) << appDir + "/libmylib" SUFFIX << true;
+#ifndef Q_OS_ANDROID
+ // We do not support non-standard suffixes on Android
QTest::newRow( "ok02 (with non-standard suffix)" ) << appDir + "/libmylib.so2" << true;
+#endif
QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.so" << true;
# endif // Q_OS_UNIX
}
@@ -282,6 +342,76 @@ void tst_QLibrary::unload_after_implicit_load()
QCOMPARE(library.isLoaded(), false);
}
+void tst_QLibrary::setFilenameAfterFailedLoad()
+{
+#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+ QSKIP("### FIXME: The helper libraries are currently messed up in the CMakeLists.txt");
+#endif
+
+ QLibrary library(directory + "/nolib");
+ QVERIFY(!library.load());
+ QVERIFY(!library.isLoaded());
+ QVERIFY(!library.load());
+ QVERIFY(!library.isLoaded());
+
+ library.setFileName(directory + "/mylib");
+ QVERIFY(library.load());
+ QVERIFY(library.isLoaded());
+ auto p = (VersionFunction)library.resolve("mylibversion");
+ QVERIFY(p);
+ QCOMPARE(p(), 2);
+ library.unload();
+}
+
+void tst_QLibrary::setFileNameAndVersionAfterFailedLoad()
+{
+ QLibrary library(directory + "/nolib");
+ QVERIFY(!library.load());
+ QVERIFY(!library.isLoaded());
+ QVERIFY(!library.load());
+ QVERIFY(!library.isLoaded());
+
+#if !defined(Q_OS_AIX) && !defined(Q_OS_WIN)
+ QFETCH(QString, lib);
+ QFETCH(int, loadversion);
+ QFETCH(int, resultversion);
+
+ library.setFileNameAndVersion(directory + '/' + lib, loadversion);
+ QVERIFY(library.load());
+ QVERIFY(library.isLoaded());
+ auto p = (VersionFunction)library.resolve("mylibversion");
+ QVERIFY(p);
+ QCOMPARE(p(), resultversion);
+ library.unload();
+#endif
+}
+
+void tst_QLibrary::loadAfterFailedLoad()
+{
+#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+ QSKIP("### FIXME: The helper libraries are currently messed up in the CMakeLists.txt");
+#endif
+
+ QTemporaryDir dir;
+ QLibrary library(dir.path() + "/mylib");
+ QVERIFY(!library.load());
+ QVERIFY(!library.isLoaded());
+ QVERIFY(!library.load());
+ QVERIFY(!library.isLoaded());
+
+ // now copy the actual lib file into our dir
+ QString actualLib = PREFIX "mylib" SUFFIX;
+ QVERIFY(QFile::copy(directory + '/' + actualLib, dir.filePath(actualLib)));
+
+ // try again, must succeed now
+ QVERIFY(library.load());
+ QVERIFY(library.isLoaded());
+ auto p = (VersionFunction)library.resolve("mylibversion");
+ QVERIFY(p);
+ QCOMPARE(p(), 2);
+ library.unload();
+}
+
void tst_QLibrary::resolve_data()
{
QTest::addColumn<QString>("lib");
@@ -302,21 +432,27 @@ void tst_QLibrary::resolve()
QFETCH( QString, symbol );
QFETCH( bool, goodPointer );
- QLibrary library( lib );
- testFunc func = (testFunc) library.resolve( symbol.toLatin1() );
- if ( goodPointer ) {
- QVERIFY( func != 0 );
+ QLibrary library(lib);
+ QVERIFY(!library.isLoaded());
+ testFunc func = (testFunc) library.resolve(symbol.toLatin1());
+
+ if (goodPointer) {
+ QVERIFY(library.isLoaded());
+ QVERIFY(func);
+
+ QLibrary lib2(lib);
+ QVERIFY(!lib2.isLoaded());
+ QVERIFY(lib2.load());
+
+ // this unload() won't unload and it must still be loaded
+ QVERIFY(!lib2.unload());
+ func(); // doesn't crash
} else {
- QVERIFY( func == 0 );
+ QVERIFY(func == nullptr);
}
library.unload();
}
-void tst_QLibrary::library_data()
-{
- QTest::addColumn<QString>("lib");
-}
-
void tst_QLibrary::isLibrary_data()
{
QTest::addColumn<QString>("filename");
@@ -337,7 +473,7 @@ void tst_QLibrary::isLibrary_data()
QTest::newRow("version+.so+version") << QString("liboil-0.3.so.0.1.0") << so_VALID;
// special tests:
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
QTest::newRow("good (libmylib.1.0.0.dylib)") << QString("libmylib.1.0.0.dylib") << true;
QTest::newRow("good (libmylib.dylib)") << QString("libmylib.dylib") << true;
QTest::newRow("good (libmylib.so)") << QString("libmylib.so") << true;
@@ -368,13 +504,13 @@ void tst_QLibrary::errorString_data()
QTest::newRow("bad load()") << (int)Load << QString("nosuchlib") << false << QString("Cannot load library nosuchlib: .*");
QTest::newRow("call errorString() on QLibrary with no d-pointer (crashtest)") << (int)(Load | DontSetFileName) << QString() << false << QString("Unknown error");
- QTest::newRow("bad resolve") << (int)Resolve << appDir + "/mylib" << false << QString("Cannot resolve symbol \"nosuchsymbol\" in \\S+: .*");
+ QTest::newRow("bad resolve") << (int)Resolve << appDir + "/mylib" << false << QString("Unknown error");
QTest::newRow("good resolve") << (int)Resolve << appDir + "/mylib" << true << QString("Unknown error");
#ifdef Q_OS_WIN
QTest::newRow("bad load() with .dll suffix") << (int)Load << QString("nosuchlib.dll") << false << QString("Cannot load library nosuchlib.dll: The specified module could not be found.");
// QTest::newRow("bad unload") << (int)Unload << QString("nosuchlib.dll") << false << QString("QLibrary::unload_sys: Cannot unload nosuchlib.dll (The specified module could not be found.)");
-#elif defined Q_OS_MAC
+#elif defined Q_OS_DARWIN
#else
QTest::newRow("load invalid file") << (int)Load << QFINDTESTDATA("library_path/invalid.so") << false << QString("Cannot load library.*");
#endif
@@ -414,10 +550,12 @@ void tst_QLibrary::errorString()
QFAIL(qPrintable(QString("Unknown operation: %1").arg(operation)));
break;
}
- QRegExp re(errorString);
+#if QT_CONFIG(regularexpression)
+ QRegularExpression re(QRegularExpression::anchoredPattern(errorString));
QString libErrorString = lib.errorString();
+ QVERIFY2(re.match(libErrorString).hasMatch(), qPrintable(libErrorString));
+#endif
QVERIFY(!lib.isLoaded() || lib.unload());
- QVERIFY2(re.exactMatch(libErrorString), qPrintable(libErrorString));
QCOMPARE(ok, success);
}
@@ -432,13 +570,16 @@ void tst_QLibrary::loadHints_data()
QString appDir = directory;
lh |= QLibrary::ResolveAllSymbolsHint;
-# if defined(Q_OS_WIN32) || defined(Q_OS_WINRT)
+# if defined(Q_OS_WIN32)
QTest::newRow( "ok01 (with suffix)" ) << appDir + "/mylib.dll" << int(lh) << true;
QTest::newRow( "ok02 (with non-standard suffix)" ) << appDir + "/mylib.dl2" << int(lh) << true;
QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.dll" << int(lh) << true;
# elif defined Q_OS_UNIX
QTest::newRow( "ok01 (with suffix)" ) << appDir + "/libmylib" SUFFIX << int(lh) << true;
+#ifndef Q_OS_ANDROID
+ // We do not support non-standard suffixes on Android
QTest::newRow( "ok02 (with non-standard suffix)" ) << appDir + "/libmylib.so2" << int(lh) << true;
+#endif
QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.so" << int(lh) << true;
# endif // Q_OS_UNIX
}
@@ -484,7 +625,7 @@ void tst_QLibrary::fileName_data()
QTest::newRow( "ok02" ) << sys_qualifiedLibraryName(QLatin1String("mylib"))
<< sys_qualifiedLibraryName(QLatin1String("mylib"));
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN)
QTest::newRow( "ok03" ) << "user32"
<< "USER32.dll";
#endif
@@ -517,7 +658,7 @@ void tst_QLibrary::multipleInstancesForOneLibrary()
QCOMPARE(lib2.isLoaded(), false);
lib1.load();
QCOMPARE(lib1.isLoaded(), true);
- QCOMPARE(lib2.isLoaded(), true);
+ QCOMPARE(lib2.isLoaded(), false); // lib2 didn't call load()
QCOMPARE(lib1.unload(), true);
QCOMPARE(lib1.isLoaded(), false);
QCOMPARE(lib2.isLoaded(), false);
@@ -526,7 +667,7 @@ void tst_QLibrary::multipleInstancesForOneLibrary()
QCOMPARE(lib1.isLoaded(), true);
QCOMPARE(lib2.isLoaded(), true);
QCOMPARE(lib1.unload(), false);
- QCOMPARE(lib1.isLoaded(), true);
+ QCOMPARE(lib1.isLoaded(), false); // lib1 did call unload()
QCOMPARE(lib2.isLoaded(), true);
QCOMPARE(lib2.unload(), true);
QCOMPARE(lib1.isLoaded(), false);
@@ -535,17 +676,6 @@ void tst_QLibrary::multipleInstancesForOneLibrary()
// Finally; unload on that is already unloaded
QCOMPARE(lib1.unload(), false);
}
-
- //now let's try with a 3rd one that will go out of scope
- {
- QLibrary lib1(lib);
- QCOMPARE(lib1.isLoaded(), false);
- lib1.load();
- QCOMPARE(lib1.isLoaded(), true);
- }
- QLibrary lib2(lib);
- //lib2 should be loaded because lib1 was loaded and never unloaded
- QCOMPARE(lib2.isLoaded(), true);
}
QTEST_MAIN(tst_QLibrary)
diff --git a/tests/auto/corelib/plugin/qplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qplugin/CMakeLists.txt
new file mode 100644
index 0000000000..d0e8736e09
--- /dev/null
+++ b/tests/auto/corelib/plugin/qplugin/CMakeLists.txt
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qplugin LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(invalidplugin)
+add_subdirectory(debugplugin)
+add_subdirectory(releaseplugin)
+
+qt_internal_add_test(tst_qplugin
+ SOURCES
+ tst_qplugin.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+if(NOT ANDROID)
+ # Collect test data
+ file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ plugins/*)
+ list(APPEND test_data ${test_data_glob})
+ set_target_properties(tst_qplugin PROPERTIES TESTDATA "${test_data}")
+else()
+ # On Android the plugins must be located in the libs subdir of the APK.
+ # Use QT_ANDROID_EXTRA_LIBS to achieve that.
+ set(plugins
+ invalidplugin
+ debugplugin
+ releaseplugin
+ )
+ set(extra_libs)
+ foreach(plugin IN LISTS plugins)
+ list(APPEND extra_libs
+ "${CMAKE_CURRENT_BINARY_DIR}/plugins/lib${plugin}_${CMAKE_ANDROID_ARCH_ABI}.so")
+ endforeach()
+ set_target_properties(tst_qplugin PROPERTIES
+ QT_ANDROID_EXTRA_LIBS "${extra_libs}"
+ )
+endif()
+
+target_compile_definitions(tst_qplugin PRIVATE CMAKE_BUILD=1)
+
+add_dependencies(tst_qplugin invalidplugin debugplugin releaseplugin)
diff --git a/tests/auto/corelib/plugin/qplugin/debugplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qplugin/debugplugin/CMakeLists.txt
new file mode 100644
index 0000000000..230282f175
--- /dev/null
+++ b/tests/auto/corelib/plugin/qplugin/debugplugin/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## debugplugin Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(debugplugin
+ MODULE
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins"
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+)
+
+qt_autogen_tools_initial_setup(debugplugin)
diff --git a/tests/auto/corelib/plugin/qplugin/debugplugin/debugplugin.pro b/tests/auto/corelib/plugin/qplugin/debugplugin/debugplugin.pro
deleted file mode 100644
index ca47df22bd..0000000000
--- a/tests/auto/corelib/plugin/qplugin/debugplugin/debugplugin.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TEMPLATE = lib
-CONFIG += plugin debug
-CONFIG -= release debug_and_release
-SOURCES = main.cpp
-QT = core
-DESTDIR = ../plugins
diff --git a/tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp b/tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp
index c610bfdc46..fe25c44d87 100644
--- a/tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp
+++ b/tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtPlugin>
#include <QObject>
diff --git a/tests/auto/corelib/plugin/qplugin/invalidplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qplugin/invalidplugin/CMakeLists.txt
new file mode 100644
index 0000000000..0b12e9c0f0
--- /dev/null
+++ b/tests/auto/corelib/plugin/qplugin/invalidplugin/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## invalidplugin Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(invalidplugin
+ MODULE
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins"
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+)
+
+# TEMPLATE = "lib"
+
+qt_autogen_tools_initial_setup(invalidplugin)
diff --git a/tests/auto/corelib/plugin/qplugin/invalidplugin/invalidplugin.pro b/tests/auto/corelib/plugin/qplugin/invalidplugin/invalidplugin.pro
deleted file mode 100644
index d953c6d367..0000000000
--- a/tests/auto/corelib/plugin/qplugin/invalidplugin/invalidplugin.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-QT = core
-TEMPLATE = lib
-CONFIG += plugin
-SOURCES = main.cpp
-DESTDIR = ../plugins
diff --git a/tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp b/tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp
index e6603ec89f..10b6131857 100644
--- a/tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp
+++ b/tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp
@@ -1,33 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qplugin.h>
+// be careful when updating to V2, the header is different on ELF systems
QT_PLUGIN_METADATA_SECTION
static const char pluginMetaData[512] = {
'q', 'p', 'l', 'u', 'g', 'i', 'n', ' ',
diff --git a/tests/auto/corelib/plugin/qplugin/qplugin.pro b/tests/auto/corelib/plugin/qplugin/qplugin.pro
deleted file mode 100644
index 96fc704c07..0000000000
--- a/tests/auto/corelib/plugin/qplugin/qplugin.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-TEMPLATE = subdirs
-TESTPLUGINS = invalidplugin
-
-win32 {
- contains(QT_CONFIG, debug): TESTPLUGINS += debugplugin
- contains(QT_CONFIG, release): TESTPLUGINS += releaseplugin
-} else:osx {
- CONFIG(debug, debug|release): TESTPLUGINS += debugplugin
- CONFIG(release, debug|release): TESTPLUGINS += releaseplugin
-} else {
- TESTPLUGINS += debugplugin releaseplugin
-}
-
-SUBDIRS += main $$TESTPLUGINS
-main.file = tst_qplugin.pro
-main.depends = $$TESTPLUGINS
-
diff --git a/tests/auto/corelib/plugin/qplugin/releaseplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qplugin/releaseplugin/CMakeLists.txt
new file mode 100644
index 0000000000..3ec89eb4c6
--- /dev/null
+++ b/tests/auto/corelib/plugin/qplugin/releaseplugin/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## releaseplugin Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(releaseplugin
+ MODULE
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins"
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+)
+
+qt_autogen_tools_initial_setup(releaseplugin)
diff --git a/tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp b/tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp
index dd936f7da1..ee14da8384 100644
--- a/tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp
+++ b/tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtPlugin>
#include <QObject>
diff --git a/tests/auto/corelib/plugin/qplugin/releaseplugin/releaseplugin.pro b/tests/auto/corelib/plugin/qplugin/releaseplugin/releaseplugin.pro
deleted file mode 100644
index b7dea67894..0000000000
--- a/tests/auto/corelib/plugin/qplugin/releaseplugin/releaseplugin.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TEMPLATE = lib
-CONFIG += plugin release
-CONFIG -= debug debug_and_release
-SOURCES = main.cpp
-QT = core
-DESTDIR = ../plugins
diff --git a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
index a290c012df..3d3cb8330d 100644
--- a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
+++ b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QTest>
#include <QCoreApplication>
#include <QDebug>
@@ -41,7 +16,6 @@ class tst_QPlugin : public QObject
Q_OBJECT
QDir dir;
- QString invalidPluginName;
public:
tst_QPlugin();
@@ -55,8 +29,15 @@ private slots:
};
tst_QPlugin::tst_QPlugin()
- : dir(QFINDTESTDATA("plugins"))
{
+ // On Android the plugins must be located in the APK's libs subdir
+#ifndef Q_OS_ANDROID
+ dir = QFINDTESTDATA("plugins");
+#else
+ const QStringList paths = QCoreApplication::libraryPaths();
+ if (!paths.isEmpty())
+ dir = paths.first();
+#endif
}
void tst_QPlugin::initTestCase()
@@ -64,25 +45,27 @@ void tst_QPlugin::initTestCase()
QVERIFY2(dir.exists(),
qPrintable(QString::fromLatin1("Cannot find the 'plugins' directory starting from '%1'").
arg(QDir::toNativeSeparators(QDir::currentPath()))));
-
- const auto fileNames = dir.entryList({"*invalid*"}, QDir::Files);
- if (!fileNames.isEmpty())
- invalidPluginName = dir.absoluteFilePath(fileNames.first());
}
void tst_QPlugin::loadDebugPlugin()
{
const auto fileNames = dir.entryList(QStringList() << "*debug*", QDir::Files);
+ if (fileNames.isEmpty())
+ QSKIP("No debug plugins found - skipping test");
+
for (const QString &fileName : fileNames) {
if (!QLibrary::isLibrary(fileName))
continue;
QPluginLoader loader(dir.filePath(fileName));
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
// we can always load a plugin on unix
QVERIFY(loader.load());
QObject *object = loader.instance();
QVERIFY(object != 0);
#else
+# if defined(CMAKE_BUILD) && defined(QT_NO_DEBUG)
+ QSKIP("Skipping test as it is not possible to disable build targets based on configuration with CMake");
+# endif
// loading a plugin is dependent on which lib we are running against
# if defined(QT_NO_DEBUG)
// release build, we cannot load debug plugins
@@ -100,16 +83,22 @@ void tst_QPlugin::loadDebugPlugin()
void tst_QPlugin::loadReleasePlugin()
{
const auto fileNames = dir.entryList(QStringList() << "*release*", QDir::Files);
+ if (fileNames.isEmpty())
+ QSKIP("No release plugins found - skipping test");
+
for (const QString &fileName : fileNames) {
if (!QLibrary::isLibrary(fileName))
continue;
QPluginLoader loader(dir.filePath(fileName));
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
// we can always load a plugin on unix
QVERIFY(loader.load());
QObject *object = loader.instance();
QVERIFY(object != 0);
#else
+# if defined(CMAKE_BUILD) && !defined(QT_NO_DEBUG)
+ QSKIP("Skipping test as it is not possible to disable build targets based on configuration with CMake");
+# endif
// loading a plugin is dependent on which lib we are running against
# if defined(QT_NO_DEBUG)
// release build, we can load debug plugins
@@ -130,49 +119,10 @@ void tst_QPlugin::scanInvalidPlugin_data()
QTest::addColumn<bool>("loads");
QTest::addColumn<QString>("errMsg");
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- // Binary JSON metadata
- QByteArray prefix = "QTMETADATA ";
-
- {
- QJsonObject obj;
- obj.insert("IID", "org.qt-project.tst_qplugin");
- obj.insert("className", "tst");
- obj.insert("version", int(QT_VERSION));
-#ifdef QT_NO_DEBUG
- obj.insert("debug", false);
-#else
- obj.insert("debug", true);
-#endif
- obj.insert("MetaData", QJsonObject());
- QTest::newRow("json-control") << (prefix + QJsonDocument(obj).toBinaryData()) << true << "";
- }
-
- QTest::newRow("json-zeroes") << prefix << false << " ";
-
- prefix += "qbjs";
- QTest::newRow("bad-json-version0") << prefix << false << " ";
- QTest::newRow("bad-json-version2") << (prefix + QByteArray("\2\0\0\0", 4)) << false << " ";
-
- // valid qbjs version 1
- prefix += QByteArray("\1\0\0\0");
-
- // too large for the file (100 MB)
- QTest::newRow("bad-json-size-large1") << (prefix + QByteArray("\0\0\x40\x06")) << false << " ";
-
- // too large for binary JSON (512 MB)
- QTest::newRow("bad-json-size-large2") << (prefix + QByteArray("\0\0\0\x20")) << false << " ";
-
- // could overflow
- QTest::newRow("bad-json-size-large3") << (prefix + "\xff\xff\xff\x7f") << false << " ";
-#endif
-
// CBOR metadata
- QByteArray cprefix = "QTMETADATA !1234";
- cprefix[12] = 0; // current version
- cprefix[13] = QT_VERSION_MAJOR;
- cprefix[14] = QT_VERSION_MINOR;
- cprefix[15] = qPluginArchRequirements();
+ static constexpr QPluginMetaData::MagicHeader header = {};
+ static constexpr qsizetype MagicLen = sizeof(header.magic);
+ QByteArray cprefix(reinterpret_cast<const char *>(&header), sizeof(header));
QByteArray cborValid = [] {
QCborMap m;
@@ -183,27 +133,27 @@ void tst_QPlugin::scanInvalidPlugin_data()
}();
QTest::newRow("cbor-control") << (cprefix + cborValid) << true << "";
- cprefix[12] = 1;
- QTest::newRow("cbor-major-too-new") << (cprefix + cborValid) << false
- << " Invalid metadata version";
-
- cprefix[12] = 0;
- cprefix[13] = QT_VERSION_MAJOR + 1;
+ cprefix[MagicLen + 1] = QT_VERSION_MAJOR + 1;
QTest::newRow("cbor-major-too-new") << (cprefix + cborValid) << false << "";
- cprefix[13] = QT_VERSION_MAJOR - 1;
+ cprefix[MagicLen + 1] = QT_VERSION_MAJOR - 1;
QTest::newRow("cbor-major-too-old") << (cprefix + cborValid) << false << "";
- cprefix[13] = QT_VERSION_MAJOR;
- cprefix[14] = QT_VERSION_MINOR + 1;
+ cprefix[MagicLen + 1] = QT_VERSION_MAJOR;
+ cprefix[MagicLen + 2] = QT_VERSION_MINOR + 1;
QTest::newRow("cbor-minor-too-new") << (cprefix + cborValid) << false << "";
+ cprefix[MagicLen + 2] = QT_VERSION_MINOR;
QTest::newRow("cbor-invalid") << (cprefix + "\xff") << false
<< " Metadata parsing error: Invalid CBOR stream: unexpected 'break' byte";
QTest::newRow("cbor-not-map1") << (cprefix + "\x01") << false
<< " Unexpected metadata contents";
QTest::newRow("cbor-not-map2") << (cprefix + "\x81\x01") << false
<< " Unexpected metadata contents";
+
+ ++cprefix[MagicLen + 0];
+ QTest::newRow("cbor-major-too-new-invalid")
+ << (cprefix + cborValid) << false << " Invalid metadata version";
}
static const char invalidPluginSignature[] = "qplugin testfile";
@@ -227,7 +177,16 @@ static qsizetype locateMetadata(const uchar *data, qsizetype len)
void tst_QPlugin::scanInvalidPlugin()
{
- QVERIFY(!invalidPluginName.isEmpty());
+#if defined(Q_OS_MACOS) && defined(Q_PROCESSOR_ARM)
+ QSKIP("This test crashes on ARM macOS");
+#endif
+ const auto fileNames = dir.entryList({"*invalid*"}, QDir::Files);
+ QString invalidPluginName;
+ if (fileNames.isEmpty())
+ QSKIP("No invalid plugin found - skipping test");
+ else
+ invalidPluginName = dir.absoluteFilePath(fileNames.first());
+
// copy the file
QFileInfo fn(invalidPluginName);
@@ -257,13 +216,14 @@ void tst_QPlugin::scanInvalidPlugin()
memset(data + offset + metadata.size(), 0, 512 - metadata.size());
}
+#if defined(Q_OS_QNX)
+ // On QNX plugin access is still too early
+ QTest::qSleep(1000);
+#endif
+
// now try to load this
QFETCH(bool, loads);
QFETCH(QString, errMsg);
- if (!errMsg.isEmpty())
- QTest::ignoreMessage(QtWarningMsg,
- "Found invalid metadata in lib " + QFile::encodeName(newName) +
- ":" + errMsg.toUtf8());
QPluginLoader loader(newName);
QCOMPARE(loader.load(), loads);
if (loads)
diff --git a/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro b/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro
deleted file mode 100644
index 4432ee20c1..0000000000
--- a/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qplugin
-QT = core-private testlib
-SOURCES = tst_qplugin.cpp
-
-TESTDATA += plugins/*
diff --git a/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt
new file mode 100644
index 0000000000..592b8632fa
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpluginloader LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(lib)
+add_subdirectory(staticplugin)
+add_subdirectory(theplugin)
+add_subdirectory(tst)
+if(UNIX AND NOT ANDROID AND NOT APPLE)
+ add_subdirectory(almostplugin)
+endif()
+if(MACOS AND QT_FEATURE_private_tests AND TARGET Qt::Gui)
+ add_subdirectory(machtest)
+endif()
diff --git a/tests/auto/corelib/plugin/qpluginloader/almostplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/almostplugin/CMakeLists.txt
new file mode 100644
index 0000000000..15ae79dfb1
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/almostplugin/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## almostplugin Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(almostplugin
+ MODULE
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qpluginloader/bin"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ SOURCES
+ almostplugin.cpp almostplugin.h
+ LIBRARIES
+ Qt::Core
+)
+
+qt_autogen_tools_initial_setup(almostplugin)
diff --git a/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.cpp b/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.cpp
index 75806dd285..29b6df2683 100644
--- a/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QString>
#include "almostplugin.h"
#include <QtCore/qplugin.h>
diff --git a/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.h b/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.h
index 6071d0c4d7..dea26875c2 100644
--- a/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.h
+++ b/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef ALMOSTPLUGIN_H
#define ALMOSTPLUGIN_H
@@ -39,7 +14,7 @@ class AlmostPlugin : public QObject, public PluginInterface
Q_INTERFACES(PluginInterface)
public:
- QString pluginName() const;
+ QString pluginName() const override;
void unresolvedSymbol() const;
};
diff --git a/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.pro b/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.pro
deleted file mode 100644
index abfc70883e..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/almostplugin/almostplugin.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TEMPLATE = lib
-CONFIG += plugin
-HEADERS = almostplugin.h
-SOURCES = almostplugin.cpp
-TARGET = almostplugin
-DESTDIR = ../bin
-QT = core
-*-g++*:QMAKE_LFLAGS -= -Wl,--no-undefined
-
-# This is testdata for the tst_qpluginloader test.
-target.path = $$[QT_INSTALL_TESTS]/tst_qpluginloader/bin
-INSTALLS += target
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt1.elf64.so b/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt1.elf64.so
deleted file mode 100644
index 12ce7362dc..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt1.elf64.so
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt2.elf64.so b/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt2.elf64.so
deleted file mode 100644
index 11fdc2c118..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt2.elf64.so
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt3.elf64.so b/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt3.elf64.so
deleted file mode 100644
index 94a2bc3560..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/corrupt3.elf64.so
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage1.so b/tests/auto/corelib/plugin/qpluginloader/elftest/garbage1.so
deleted file mode 100644
index 0c7453077f..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage1.so
+++ /dev/null
@@ -1,4 +0,0 @@
-pcdL+&&e=
-oÒʎI ٝmg]!Z
-L')t
-N(e P)Y8G 6-y "Zk4?^n5$Y=#y \ No newline at end of file
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage2.so b/tests/auto/corelib/plugin/qpluginloader/elftest/garbage2.so
deleted file mode 100644
index c06338e0c8..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage2.so
+++ /dev/null
@@ -1 +0,0 @@
-v.YtKW3 \ No newline at end of file
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage3.so b/tests/auto/corelib/plugin/qpluginloader/elftest/garbage3.so
deleted file mode 100644
index a24c523a77..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage3.so
+++ /dev/null
@@ -1 +0,0 @@
-ȂT-ڥ 쾜i8_xI׮x=4@[BKS$ \ No newline at end of file
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage4.so b/tests/auto/corelib/plugin/qpluginloader/elftest/garbage4.so
deleted file mode 100644
index 4f45cf5157..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage4.so
+++ /dev/null
@@ -1 +0,0 @@
- !\~Uu:9T+91QEǚxng5zh^t'mm*ˈdXH;vw+G 9L0! \ No newline at end of file
diff --git a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage5.so b/tests/auto/corelib/plugin/qpluginloader/elftest/garbage5.so
deleted file mode 100644
index f8c0a1d544..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/elftest/garbage5.so
+++ /dev/null
@@ -1,2 +0,0 @@
-Q
--9 \ No newline at end of file
diff --git a/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp b/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp
index 9e7a1f750b..e84bfa6dbc 100644
--- a/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp
@@ -1,36 +1,57 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#ifndef QT_VERSION_MAJOR
+# include <QtCore/qglobal.h>
+#endif
-#include <QtCore/qplugin.h>
+extern "C" void *qt_plugin_instance()
+{
+ return nullptr;
+}
-#if QT_POINTER_SIZE == 8
-QT_PLUGIN_METADATA_SECTION void *const pluginSection = (void*)(0xc0ffeec0ffeeL);
+#ifdef QT_DEBUG
+static constexpr bool IsDebug = true;
#else
-QT_PLUGIN_METADATA_SECTION void *const pluginSection = (void*)0xc0ffee;
+static constexpr bool IsDebug = false;
+#endif
+
+#ifndef PLUGIN_VERSION
+# define PLUGIN_VERSION (QT_VERSION_MAJOR >= 7 ? 1 : 0)
+#endif
+#if PLUGIN_VERSION == 1
+# define PLUGIN_HEADER 1, QT_VERSION_MAJOR, 0, IsDebug ? 0x80 : 0
+#else
+# define PLUGIN_HEADER 0, QT_VERSION_MAJOR, 0, IsDebug
+#endif
+
+#if defined(__ELF__) && PLUGIN_VERSION >= 1
+// GCC will produce:
+// fakeplugin.cpp:64:3: warning: ‘no_sanitize’ attribute ignored [-Wattributes]
+__attribute__((section(".note.qt.metadata"), used, no_sanitize("address"), aligned(sizeof(void*))))
+static const struct {
+ unsigned n_namesz = sizeof(name);
+ unsigned n_descsz = sizeof(payload);
+ unsigned n_type = 0x74510001;
+ char name[12] = "qt-project!";
+ alignas(unsigned) unsigned char payload[2 + 4] = {
+ PLUGIN_HEADER,
+ 0xbf,
+ 0xff,
+ };
+} qtnotemetadata;
+#elif PLUGIN_VERSION >= 0
+# ifdef _MSC_VER
+# pragma section(".qtmetadata",read,shared)
+__declspec(allocate(".qtmetadata"))
+# elif defined(__APPLE__)
+__attribute__ ((section ("__TEXT,qtmetadata"), used))
+# else
+__attribute__ ((section(".qtmetadata"), used))
+# endif
+static const unsigned char qtmetadata[] = {
+ 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',
+ PLUGIN_HEADER,
+ 0xbf,
+ 0xff,
+};
#endif
-QT_PLUGIN_METADATA_SECTION const char message[] = "QTMETADATA";
diff --git a/tests/auto/corelib/plugin/qpluginloader/lib/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/lib/CMakeLists.txt
new file mode 100644
index 0000000000..283bdb1352
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/lib/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpluginloaderlib Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(tst_qpluginloaderlib
+ SHARED
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qpluginloader/bin"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ SOURCES
+ mylib.c
+ LIBRARIES
+ Qt::Core
+)
+
+if(WIN32)
+ # CMake sets for Windows-GNU platforms the suffix "lib"
+ set_property(TARGET tst_qpluginloaderlib PROPERTY PREFIX "")
+endif()
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qpluginloaderlib CONDITION MSVC
+ DEFINES
+ WIN32_MSVC
+)
+
+set_target_properties(tst_qpluginloaderlib PROPERTIES
+ C_VISIBILITY_PRESET "default"
+ CXX_VISIBILITY_PRESET "default"
+)
diff --git a/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro b/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro
deleted file mode 100644
index 9fc76a4201..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TEMPLATE = lib
-CONFIG += dll
-CONFIG -= staticlib
-SOURCES = mylib.c
-TARGET = tst_qpluginloaderlib
-DESTDIR = ../bin
-winrt:include(../winrt.pri)
-QT = core
-
-msvc: DEFINES += WIN32_MSVC
-
-# This is testdata for the tst_qpluginloader test.
-target.path = $$[QT_INSTALL_TESTS]/tst_qpluginloader/bin
-INSTALLS += target
diff --git a/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c b/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c
index 8d23b999c4..3f1fe03114 100644
--- a/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c
+++ b/tests/auto/corelib/plugin/qpluginloader/lib/mylib.c
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qglobal.h>
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt
new file mode 100644
index 0000000000..6cb69fc46d
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt
@@ -0,0 +1,138 @@
+set_directory_properties(PROPERTIES
+ _qt_good_targets ""
+ _qt_stub_targets ""
+)
+
+function(add_plugin_binary)
+ set(no_value_options "")
+ set(single_value_options NAME ARCH OUT_TARGET)
+ set(multi_value_options SOURCES)
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ set(output_name ${arg_NAME}.${arg_ARCH})
+ set(target tst_qpluginloader.${output_name})
+ set(${arg_OUT_TARGET} ${target} PARENT_SCOPE)
+ set_property(DIRECTORY APPEND PROPERTY _qt_${arg_NAME}_targets ${target})
+ add_library(${target} MODULE ${arg_SOURCES})
+ add_dependencies(tst_qpluginloader ${target})
+ set_target_properties(${target} PROPERTIES
+ OUTPUT_NAME ${output_name}
+ PREFIX ""
+ SUFFIX ".dylib"
+ DEBUG_POSTFIX ""
+ OSX_ARCHITECTURES ${arg_ARCH}
+ )
+endfunction()
+
+function(add_good_binary)
+ set(no_value_options "")
+ set(single_value_options ARCH)
+ set(multi_value_options "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ add_plugin_binary(
+ NAME good
+ ARCH ${arg_ARCH}
+ SOURCES ../fakeplugin.cpp
+ OUT_TARGET target
+ )
+
+ # We cannot link against Qt6::Core, because the architecture might not match.
+ # Extract the include directories from Qt6::Core.
+ get_target_property(incdirs Qt6::Core INTERFACE_INCLUDE_DIRECTORIES)
+ target_include_directories(${target} PRIVATE ${incdirs})
+
+ # Extract the compile definitions from Qt6::Core and disable version tagging.
+ get_target_property(compdefs Qt6::Core INTERFACE_COMPILE_DEFINITIONS)
+ target_compile_definitions(${target} PRIVATE
+ ${compdefs}
+ QT_NO_VERSION_TAGGING
+ )
+endfunction()
+
+function(add_stub_binary)
+ set(no_value_options "")
+ set(single_value_options ARCH)
+ set(multi_value_options "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ add_plugin_binary(
+ NAME stub
+ ARCH ${arg_ARCH}
+ SOURCES stub.cpp
+ )
+endfunction()
+
+function(add_fat_binary)
+ set(no_value_options "")
+ set(single_value_options NAME OUT_TARGET)
+ set(multi_value_options TARGETS)
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ set(arch_args "")
+ foreach(dependency IN LISTS arg_TARGETS)
+ get_target_property(arch ${dependency} OSX_ARCHITECTURES)
+ list(APPEND arch_args -arch ${arch} $<TARGET_FILE_NAME:${dependency}>)
+ endforeach()
+
+ set(output_name good.fat.${arg_NAME})
+ set(output_file ${output_name}.dylib)
+ set(target tst_qpluginloader.${output_name})
+ set(${arg_OUT_TARGET} ${target} PARENT_SCOPE)
+ add_custom_command(
+ OUTPUT ${output_file}
+ COMMAND lipo -create -output ${output_file} ${arch_args}
+ DEPENDS ${arg_TARGETS}
+ )
+ add_custom_target(${target}
+ DEPENDS ${output_file}
+ )
+ add_dependencies(tst_qpluginloader ${target})
+endfunction()
+
+set(archs_to_test arm64 x86_64)
+foreach(arch IN LISTS archs_to_test)
+ add_good_binary(ARCH ${arch})
+ add_stub_binary(ARCH ${arch})
+endforeach()
+
+get_directory_property(good_targets _qt_good_targets)
+add_fat_binary(NAME all TARGETS ${good_targets})
+
+set(targets ${good_targets})
+list(FILTER targets EXCLUDE REGEX "\\.arm64$")
+add_fat_binary(NAME no-arm64 TARGETS ${targets})
+
+set(targets ${good_targets})
+list(FILTER targets EXCLUDE REGEX "\\.x86_64$")
+add_fat_binary(NAME no-x86_64 TARGETS ${targets})
+
+get_directory_property(stub_targets _qt_stub_targets)
+set(targets ${stub_targets})
+list(FILTER targets INCLUDE REGEX "\\.arm64$")
+add_fat_binary(NAME stub-arm64 TARGETS ${targets})
+
+set(targets ${stub_targets})
+list(FILTER targets INCLUDE REGEX "\\.x86_64$")
+add_fat_binary(NAME stub-x86_64 TARGETS ${targets})
+
+set(bad_binary_names "")
+foreach(i RANGE 1 13)
+ list(APPEND bad_binary_names "bad${i}.dylib")
+endforeach()
+add_custom_command(
+ OUTPUT ${bad_binary_names}
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate-bad.pl
+)
+add_custom_target(tst_qpluginloader_generate_bad_binaries
+ DEPENDS ${bad_binary_names}
+)
+add_dependencies(tst_qpluginloader tst_qpluginloader_generate_bad_binaries)
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl b/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl
index 4fed135049..3de1eb581a 100755
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl
@@ -1,31 +1,6 @@
#!/usr/bin/perl
-#############################################################################
-##
-## Copyright (C) 2016 Intel Corporation.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is the build configuration utility of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 Intel Corporation.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
use strict;
use constant FAT_MAGIC => 0xcafebabe;
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri
deleted file mode 100644
index ca4a0a07e9..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri
+++ /dev/null
@@ -1,13 +0,0 @@
-TEMPLATE = aux
-
-# Needs explicit load()ing due to aux template. Relies on QT being non-empty.
-load(qt)
-
-goodlib.target = good.$${QMAKE_APPLE_DEVICE_ARCHS}.dylib
-goodlib.commands = $(CXX) $(CXXFLAGS) -shared -o $@ -I$(INCPATH) $<
-goodlib.depends += $$PWD/../fakeplugin.cpp
-
-all.depends += goodlib
-
-QMAKE_EXTRA_TARGETS += goodlib all
-QMAKE_CLEAN += $$goodlib.target
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
deleted file mode 100644
index 795dd89895..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS = \
- machtest_i386.pro \
- machtest_x86_64.pro \
- machtest_ppc64.pro \
- machtest_fat.pro
-
-machtest_fat-pro.depends = \
- machtest_i386.pro \
- machtest_x86_64.pro \
- machtest_ppc64.pro
-
-machtest_ppc64-pro.depends = \
- machtest_x86_64.pro
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
deleted file mode 100644
index 8daa343e2b..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
+++ /dev/null
@@ -1,41 +0,0 @@
-TEMPLATE = aux
-OTHER_FILES += generate-bad.pl
-
-# Needs explicit load()ing due to aux template. Relies on QT being non-empty.
-load(qt)
-
-# Generate a fat binary with three architectures
-fat_all.target = good.fat.all.dylib
-fat_all.commands = lipo -create -output $@ \
- -arch ppc64 good.ppc64.dylib \
- -arch i386 good.i386.dylib \
- -arch x86_64 good.x86_64.dylib
-fat_all.depends += good.i386.dylib good.x86_64.dylib good.ppc64.dylib
-
-fat_no_i386.target = good.fat.no-i386.dylib
-fat_no_i386.commands = lipo -create -output $@ -arch x86_64 good.x86_64.dylib -arch ppc64 good.ppc64.dylib
-fat_no_i386.depends += good.x86_64.dylib good.ppc64.dylib
-
-fat_no_x86_64.target = good.fat.no-x86_64.dylib
-fat_no_x86_64.commands = lipo -create -output $@ -arch i386 good.i386.dylib -arch ppc64 good.ppc64.dylib
-fat_no_x86_64.depends += good.i386.dylib good.ppc64.dylib
-
-fat_stub_i386.target = good.fat.stub-i386.dylib
-fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch_blank i386
-fat_stub_i386.depends += good.x86_64.dylib good.ppc64.dylib
-
-fat_stub_x86_64.target = good.fat.stub-x86_64.dylib
-fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch_blank x86_64
-fat_stub_x86_64.depends += good.i386.dylib good.ppc64.dylib
-
-bad.commands = $$PWD/generate-bad.pl
-bad.depends += $$PWD/generate-bad.pl
-
-MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \
- fat_stub_i386 fat_stub_x86_64 bad
-all.depends += $$MYTARGETS
-QMAKE_EXTRA_TARGETS += $$MYTARGETS all
-
-QMAKE_CLEAN += $$fat_all.target $$fat_no_i386.target $$fat_no_x86_64.target \
- $$fat_stub_i386.target $$fat_stub_x86_64.target \
- "bad*.dylib"
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro
deleted file mode 100644
index bfb2e0930c..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = i386
-include(machtest.pri)
-
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro
deleted file mode 100644
index a73f97ccc6..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = ppc64
-include(machtest.pri)
-
-OTHER_FILES += ppcconverter.pl
-
-# Current macOS toolchains have no compiler for PPC anymore
-# So we fake it by converting an x86-64 binary to (little-endian!) PPC64
-goodlib.commands = $$PWD/ppcconverter.pl $< $@
-goodlib.depends = good.x86_64.dylib $$PWD/ppcconverter.pl
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro
deleted file mode 100644
index 9dbae5c4ee..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-include(machtest.pri)
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl b/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl
deleted file mode 100755
index 7242d7596b..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/perl
-#############################################################################
-##
-## Copyright (C) 2016 Intel Corporation.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is the build configuration utility of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-# Changes the Mach-O file type header to PowerPC.
-#
-# The header is (from mach-o/loader.h):
-# struct mach_header {
-# uint32_t magic; /* mach magic number identifier */
-# cpu_type_t cputype; /* cpu specifier */
-# cpu_subtype_t cpusubtype; /* machine specifier */
-# uint32_t filetype; /* type of file */
-# uint32_t ncmds; /* number of load commands */
-# uint32_t sizeofcmds; /* the size of all the load commands */
-# uint32_t flags; /* flags */
-# };
-#
-# The 64-bit header is identical in the first three fields, except for a different
-# magic number. We will not touch the magic number, we'll just reset the cputype
-# field to the PowerPC type and the subtype field to zero.
-#
-# We will not change the file's endianness. That means we might create a little-endian
-# PowerPC binary, which could not be run in real life.
-#
-# We will also not change the 64-bit ABI flag, which is found in the cputype's high
-# byte. That means we'll create a PPC64 binary if fed a 64-bit input.
-#
-use strict;
-use constant MH_MAGIC => 0xfeedface;
-use constant MH_CIGAM => 0xcefaedfe;
-use constant MH_MAGIC_64 => 0xfeedfacf;
-use constant MH_CIGAM_64 => 0xcffaedfe;
-use constant CPU_TYPE_POWERPC => 18;
-use constant CPU_SUBTYPE_POWERPC_ALL => 0;
-
-my $infile = shift @ARGV or die("Missing input filename");
-my $outfile = shift @ARGV or die("Missing output filename");
-
-open IN, "<$infile" or die("Can't open $infile for reading: $!\n");
-open OUT, ">$outfile" or die("Can't open $outfile for writing: $!\n");
-
-binmode IN;
-binmode OUT;
-
-# Read the first 12 bytes, which includes the interesting fields of the header
-my $buffer;
-read(IN, $buffer, 12);
-
-my $magic = vec($buffer, 0, 32);
-if ($magic == MH_MAGIC || $magic == MH_MAGIC_64) {
- # Big endian
- # The low byte of cputype is at offset 7
- vec($buffer, 7, 8) = CPU_TYPE_POWERPC;
-} elsif ($magic == MH_CIGAM || $magic == MH_CIGAM_64) {
- # Little endian
- # The low byte of cpytype is at offset 4
- vec($buffer, 4, 8) = CPU_TYPE_POWERPC;
-} else {
- $magic = '';
- $magic .= sprintf("%02X ", $_) for unpack("CCCC", $buffer);
- die("Invalid input. Unknown magic $magic\n");
-}
-vec($buffer, 2, 32) = CPU_SUBTYPE_POWERPC_ALL;
-
-print OUT $buffer;
-
-# Copy the rest
-while (!eof(IN)) {
- read(IN, $buffer, 4096) and
- print OUT $buffer or
- die("Problem copying: $!\n");
-}
-close(IN);
-close(OUT);
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp b/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp
new file mode 100644
index 0000000000..24bac391fb
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp
@@ -0,0 +1 @@
+void dummy() {}
diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
deleted file mode 100644
index 3745782dfc..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-QT = core
-TEMPLATE = subdirs
-
-tst.depends = lib theplugin
-SUBDIRS = lib \
- theplugin \
- tst
-!android:!win32:!darwin {
- tst.depends += almostplugin
- SUBDIRS += almostplugin
-}
-macos:qtConfig(private_tests):qtHaveModule(gui) {
- tst.depends += machtest
- SUBDIRS += machtest
-}
-
-# no special install rule for subdir
-INSTALLS =
-
-
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore b/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore
new file mode 100644
index 0000000000..26f7ecd506
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/.gitignore
@@ -0,0 +1,3 @@
+*staticplugin.prl
+libstaticplugin.a
+staticplugin.lib
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/staticplugin/CMakeLists.txt
new file mode 100644
index 0000000000..647c8ac207
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## staticplugin Generic Library:
+#####################################################################
+
+qt_internal_add_cmake_library(staticplugin
+ STATIC
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Core
+ MOC_OPTIONS
+ "-M"
+ "ExtraMetaData=StaticPlugin"
+ "-M"
+ "ExtraMetaData=foo"
+)
+
+# TEMPLATE = "lib"
+
+qt_autogen_tools_initial_setup(staticplugin)
+
+target_compile_definitions(staticplugin PRIVATE QT_STATICPLUGIN)
diff --git a/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp
new file mode 100644
index 0000000000..208096b425
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/staticplugin/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QtPlugin>
+#include <QObject>
+
+class StaticPlugin : public QObject
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "SomeIID" URI "qt.test.pluginloader.staticplugin")
+public:
+ StaticPlugin() {}
+};
+
+#include "main.moc"
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/theplugin/CMakeLists.txt
new file mode 100644
index 0000000000..dfce9d6a52
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_cmake_library(theplugin
+ MODULE
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qpluginloader/bin"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ SOURCES
+ theplugin.cpp theplugin.h
+ LIBRARIES
+ Qt::Core
+)
+qt_autogen_tools_initial_setup(theplugin)
+
+if (UNIX AND NOT APPLE)
+ qt_internal_add_cmake_library(theoldplugin
+ MODULE
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qpluginloader/bin"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
+ SOURCES
+ theoldplugin.cpp theoldplugin.h
+ LIBRARIES
+ Qt::Core
+ )
+ qt_autogen_tools_initial_setup(theoldplugin)
+
+ # Force unoptimized builds with debugging information so some "QTMETADATA !"
+ # strings appear elsewhere in the binary.
+ target_compile_options(theplugin PRIVATE -O0 -g3)
+ target_compile_options(theoldplugin PRIVATE -O0 -g3)
+endif()
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/plugininterface.h b/tests/auto/corelib/plugin/qpluginloader/theplugin/plugininterface.h
index 12285ba016..3fd6c384a4 100644
--- a/tests/auto/corelib/plugin/qpluginloader/theplugin/plugininterface.h
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/plugininterface.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.cpp b/tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.cpp
new file mode 100644
index 0000000000..20e65b4bb0
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.cpp
@@ -0,0 +1,80 @@
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include "theoldplugin.h"
+#include <QtCore/QString>
+#include <QtCore/qplugin.h>
+
+QString TheOldPlugin::pluginName() const
+{
+ return QLatin1String("Plugin ok");
+}
+
+static int pluginVariable = 0xc0ffee;
+extern "C" Q_DECL_EXPORT int *pointerAddress()
+{
+ return &pluginVariable;
+}
+
+// This hardcodes the old plugin metadata from before Qt 6.2
+QT_PLUGIN_METADATA_SECTION
+static constexpr unsigned char qt_pluginMetaData_ThePlugin[] = {
+ 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',
+ // metadata version, Qt version, architectural requirements
+ 0, QT_VERSION_MAJOR, QT_VERSION_MINOR, qPluginArchRequirements(),
+ 0xbf,
+ // "IID"
+ 0x02, 0x78, 0x2b, 'o', 'r', 'g', '.', 'q',
+ 't', '-', 'p', 'r', 'o', 'j', 'e', 'c',
+ 't', '.', 'Q', 't', '.', 'a', 'u', 't',
+ 'o', 't', 'e', 's', 't', 's', '.', 'p',
+ 'l', 'u', 'g', 'i', 'n', 'i', 'n', 't',
+ 'e', 'r', 'f', 'a', 'c', 'e',
+ // "className"
+ 0x03, 0x69, 'T', 'h', 'e', 'P', 'l', 'u',
+ 'g', 'i', 'n',
+ // "MetaData"
+ 0x04, 0xa2, 0x67, 'K', 'P', 'l', 'u', 'g',
+ 'i', 'n', 0xa8, 0x64, 'N', 'a', 'm', 'e',
+ 0x6e, 'W', 'i', 'n', 'd', 'o', 'w', 'G',
+ 'e', 'o', 'm', 'e', 't', 'r', 'y', 0x68,
+ 'N', 'a', 'm', 'e', '[', 'm', 'r', ']',
+ 0x78, 0x1f, uchar('\xe0'), uchar('\xa4'), uchar('\x9a'), uchar('\xe0'), uchar('\xa5'), uchar('\x8c'),
+ uchar('\xe0'), uchar('\xa4'), uchar('\x95'), uchar('\xe0'), uchar('\xa4'), uchar('\x9f'), ' ', uchar('\xe0'),
+ uchar('\xa4'), uchar('\xad'), uchar('\xe0'), uchar('\xa5'), uchar('\x82'), uchar('\xe0'), uchar('\xa4'), uchar('\xae'),
+ uchar('\xe0'), uchar('\xa4'), uchar('\xbf'), uchar('\xe0'), uchar('\xa4'), uchar('\xa4'), uchar('\xe0'), uchar('\xa5'),
+ uchar('\x80'), 0x68, 'N', 'a', 'm', 'e', '[', 'p',
+ 'a', ']', 0x78, 0x24, uchar('\xe0'), uchar('\xa8'), uchar('\xb5'), uchar('\xe0'),
+ uchar('\xa8'), uchar('\xbf'), uchar('\xe0'), uchar('\xa9'), uchar('\xb0'), uchar('\xe0'), uchar('\xa8'), uchar('\xa1'),
+ uchar('\xe0'), uchar('\xa9'), uchar('\x8b'), uchar('\xe0'), uchar('\xa8'), uchar('\x9c'), uchar('\xe0'), uchar('\xa9'),
+ uchar('\x81'), uchar('\xe0'), uchar('\xa8'), uchar('\xae'), uchar('\xe0'), uchar('\xa9'), uchar('\x88'), uchar('\xe0'),
+ uchar('\xa8'), uchar('\x9f'), uchar('\xe0'), uchar('\xa8'), uchar('\xb0'), uchar('\xe0'), uchar('\xa9'), uchar('\x80'),
+ 0x68, 'N', 'a', 'm', 'e', '[', 't', 'h',
+ ']', 0x78, 0x39, uchar('\xe0'), uchar('\xb8'), uchar('\xa1'), uchar('\xe0'), uchar('\xb8'),
+ uchar('\xb4'), uchar('\xe0'), uchar('\xb8'), uchar('\x95'), uchar('\xe0'), uchar('\xb8'), uchar('\xb4'), uchar('\xe0'),
+ uchar('\xb8'), uchar('\x82'), uchar('\xe0'), uchar('\xb8'), uchar('\x99'), uchar('\xe0'), uchar('\xb8'), uchar('\xb2'),
+ uchar('\xe0'), uchar('\xb8'), uchar('\x94'), uchar('\xe0'), uchar('\xb8'), uchar('\x82'), uchar('\xe0'), uchar('\xb8'),
+ uchar('\xad'), uchar('\xe0'), uchar('\xb8'), uchar('\x87'), uchar('\xe0'), uchar('\xb8'), uchar('\xab'), uchar('\xe0'),
+ uchar('\xb8'), uchar('\x99'), uchar('\xe0'), uchar('\xb9'), uchar('\x89'), uchar('\xe0'), uchar('\xb8'), uchar('\xb2'),
+ uchar('\xe0'), uchar('\xb8'), uchar('\x95'), uchar('\xe0'), uchar('\xb9'), uchar('\x88'), uchar('\xe0'), uchar('\xb8'),
+ uchar('\xb2'), uchar('\xe0'), uchar('\xb8'), uchar('\x87'), 0x68, 'N', 'a', 'm',
+ 'e', '[', 'u', 'k', ']', 0x78, 0x19, uchar('\xd0'),
+ uchar('\xa0'), uchar('\xd0'), uchar('\xbe'), uchar('\xd0'), uchar('\xb7'), uchar('\xd0'), uchar('\xbc'), uchar('\xd1'),
+ uchar('\x96'), uchar('\xd1'), uchar('\x80'), uchar('\xd0'), uchar('\xb8'), ' ', uchar('\xd0'), uchar('\xb2'),
+ uchar('\xd1'), uchar('\x96'), uchar('\xd0'), uchar('\xba'), uchar('\xd0'), uchar('\xbd'), uchar('\xd0'), uchar('\xb0'),
+ 0x6b, 'N', 'a', 'm', 'e', '[', 'z', 'h',
+ '_', 'C', 'N', ']', 0x6c, uchar('\xe7'), uchar('\xaa'), uchar('\x97'),
+ uchar('\xe5'), uchar('\x8f'), uchar('\xa3'), uchar('\xe5'), uchar('\xbd'), uchar('\xa2'), uchar('\xe7'), uchar('\x8a'),
+ uchar('\xb6'), 0x6b, 'N', 'a', 'm', 'e', '[', 'z',
+ 'h', '_', 'T', 'W', ']', 0x6c, uchar('\xe8'), uchar('\xa6'),
+ uchar('\x96'), uchar('\xe7'), uchar('\xaa'), uchar('\x97'), uchar('\xe4'), uchar('\xbd'), uchar('\x8d'), uchar('\xe7'),
+ uchar('\xbd'), uchar('\xae'), 0x6c, 'S', 'e', 'r', 'v', 'i',
+ 'c', 'e', 'T', 'y', 'p', 'e', 's', 0x81,
+ 0x68, 'K', 'C', 'M', 'o', 'd', 'u', 'l',
+ 'e', 0x76, 'X', '-', 'K', 'D', 'E', '-',
+ 'P', 'a', 'r', 'e', 'n', 't', 'C', 'o',
+ 'm', 'p', 'o', 'n', 'e', 'n', 't', 's',
+ 0x81, 0x6e, 'w', 'i', 'n', 'd', 'o', 'w',
+ 'g', 'e', 'o', 'm', 'e', 't', 'r', 'y',
+ 0xff,
+};
+QT_MOC_EXPORT_PLUGIN(TheOldPlugin, ThePlugin)
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.h b/tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.h
new file mode 100644
index 0000000000..786ce3f618
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theoldplugin.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2021 Intel Corportaion.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#ifndef THEOLDPLUGIN_H
+#define THEOLDPLUGIN_H
+
+#include <QObject>
+#include <QtPlugin>
+#include "plugininterface.h"
+
+class TheOldPlugin : public QObject, public PluginInterface
+{
+ Q_OBJECT
+ // Q_PLUGIN_METADATA intentionally missing
+ Q_INTERFACES(PluginInterface)
+
+public:
+ virtual QString pluginName() const override;
+};
+
+#endif // THEOLDPLUGIN_H
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp
index 01563c3dc9..bfa45c7c48 100644
--- a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QString>
#include "theplugin.h"
#include <QtCore/qplugin.h>
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h
index ac349c2f75..a6b7e4a083 100644
--- a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef THEPLUGIN_H
#define THEPLUGIN_H
@@ -39,7 +14,7 @@ class ThePlugin : public QObject, public PluginInterface
Q_INTERFACES(PluginInterface)
public:
- virtual QString pluginName() const;
+ virtual QString pluginName() const override;
};
#endif // THEPLUGIN_H
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro
deleted file mode 100644
index 6aa8161699..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TEMPLATE = lib
-CONFIG += plugin
-HEADERS = theplugin.h
-SOURCES = theplugin.cpp
-# Use a predictable name for the plugin, no debug extension. Just like most apps do.
-#TARGET = $$qtLibraryTarget(theplugin)
-TARGET = theplugin
-DESTDIR = ../bin
-winrt:include(../winrt.pri)
-QT = core
-
-# This is testdata for the tst_qpluginloader test.
-target.path = $$[QT_INSTALL_TESTS]/tst_qpluginloader/bin
-INSTALLS += target
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/tst/CMakeLists.txt
new file mode 100644
index 0000000000..16dd1cf9cf
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/tst/CMakeLists.txt
@@ -0,0 +1,71 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpluginloader Test:
+#####################################################################
+
+# Collect test data
+list(APPEND test_data "../elftest")
+list(APPEND test_data "../machtest")
+
+qt_internal_add_test(tst_qpluginloader
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../fakeplugin.cpp
+ ../theplugin/plugininterface.h
+ ../tst_qpluginloader.cpp
+ LIBRARIES
+ staticplugin
+ TESTDATA ${test_data}
+)
+
+add_dependencies(tst_qpluginloader tst_qpluginloaderlib staticplugin theplugin)
+if (UNIX)
+ if(NOT APPLE)
+ add_dependencies(tst_qpluginloader theoldplugin)
+ endif()
+ if (NOT ANDROID AND NOT APPLE)
+ add_dependencies(tst_qpluginloader almostplugin)
+ endif()
+endif()
+
+if(ANDROID)
+ add_compile_definitions(ANDROID_ARCH="${CMAKE_ANDROID_ARCH_ABI}")
+ set(plugins
+ theplugin
+ theoldplugin
+ tst_qpluginloaderlib
+ )
+ set(extra_libs)
+ foreach(plugin IN LISTS plugins)
+ list(APPEND extra_libs
+ "${CMAKE_CURRENT_BINARY_DIR}/../bin/lib${plugin}_${CMAKE_ANDROID_ARCH_ABI}.so")
+ endforeach()
+ set_target_properties(tst_qpluginloader PROPERTIES
+ QT_ANDROID_EXTRA_LIBS "${extra_libs}"
+ )
+endif()
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qpluginloader CONDITION QT_FEATURE_private_tests
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+qt_internal_extend_target(tst_qpluginloader CONDITION CMAKE_BUILD_TYPE STREQUAL Debug AND WIN32 AND debug_and_release
+ LIBRARIES
+ # Remove: L../staticplugin/debug
+)
+
+qt_internal_extend_target(tst_qpluginloader CONDITION WIN32 AND debug_and_release AND NOT CMAKE_BUILD_TYPE STREQUAL Debug
+ LIBRARIES
+ # Remove: L../staticplugin/release
+)
+
+qt_internal_extend_target(tst_qpluginloader CONDITION UNIX OR NOT debug_and_release
+ LIBRARIES
+ # Remove: L../staticplugin
+)
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
deleted file mode 100644
index c20e56ba4c..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = ../tst_qpluginloader
-QT = core testlib
-qtConfig(private_tests): QT += core-private
-SOURCES = ../tst_qpluginloader.cpp ../fakeplugin.cpp
-HEADERS = ../theplugin/plugininterface.h
-
-win32 {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qpluginloader
- } else {
- TARGET = ../../release/tst_qpluginloader
- }
-}
-
-TESTDATA += ../elftest ../machtest
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index c517c0809a..f4ecf5bfb3 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -1,41 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSignalSpy>
+#include <QJsonArray>
#include <qdir.h>
+#include <qendian.h>
#include <qpluginloader.h>
+#include <qtemporaryfile.h>
+#include <QScopeGuard>
#include "theplugin/plugininterface.h"
#if defined(QT_BUILD_INTERNAL) && defined(Q_OF_MACH_O)
# include <QtCore/private/qmachparser_p.h>
#endif
+using namespace Qt::StringLiterals;
+
// Helper macros to let us know if some suffixes are valid
#define bundle_VALID false
#define dylib_VALID false
@@ -51,11 +33,11 @@
# define bundle_VALID true
# define dylib_VALID true
# define so_VALID true
-//# ifdef QT_NO_DEBUG
+# ifdef QT_NO_DEBUG
# define SUFFIX ".dylib"
-//# else
-//# define SUFFIX "_debug.dylib"
-//#endif
+# else
+# define SUFFIX "_debug.dylib"
+# endif
# define PREFIX "lib"
#elif defined(Q_OS_HPUX) && !defined(__ia64)
@@ -89,14 +71,113 @@
# define PREFIX "lib"
#endif
+#if defined(Q_OF_ELF)
+#if __has_include(<elf.h>)
+# include <elf.h>
+#else
+# include <sys/elf.h>
+#endif
+# include <memory>
+# include <functional>
+
+# ifdef _LP64
+using ElfHeader = Elf64_Ehdr;
+using ElfPhdr = Elf64_Phdr;
+using ElfNhdr = Elf64_Nhdr;
+using ElfShdr = Elf64_Shdr;
+# else
+using ElfHeader = Elf32_Ehdr;
+using ElfPhdr = Elf32_Phdr;
+using ElfNhdr = Elf32_Nhdr;
+using ElfShdr = Elf32_Shdr;
+# endif
+
+struct ElfPatcher
+{
+ using FullPatcher = void(ElfHeader *, QFile *);
+ FullPatcher *f;
+
+ ElfPatcher(FullPatcher *f = nullptr) : f(f) {}
+
+ template <typename T> using IsSingleArg = std::is_invocable<T, ElfHeader *>;
+ template <typename T> static std::enable_if_t<IsSingleArg<T>::value, ElfPatcher> fromLambda(T &&t)
+ {
+ using WithoutQFile = void(*)(ElfHeader *);
+ static const WithoutQFile f = t;
+ return { [](ElfHeader *h, QFile *) { f(h);} };
+ }
+ template <typename T> static std::enable_if_t<!IsSingleArg<T>::value, ElfPatcher> fromLambda(T &&t)
+ {
+ return { t };
+ }
+};
+
+Q_DECLARE_METATYPE(ElfPatcher)
+
+static std::unique_ptr<QTemporaryFile> patchElf(const QString &source, ElfPatcher patcher)
+{
+ std::unique_ptr<QTemporaryFile> tmplib;
+
+ bool ok = false;
+ [&]() {
+ QFile srclib(source);
+ QVERIFY2(srclib.open(QIODevice::ReadOnly), qPrintable(srclib.errorString()));
+ qint64 srcsize = srclib.size();
+ const uchar *srcdata = srclib.map(0, srcsize, QFile::MapPrivateOption);
+ QVERIFY2(srcdata, qPrintable(srclib.errorString()));
+
+ // copy our source plugin so we can modify it
+ const char *basename = QTest::currentDataTag();
+ if (!basename)
+ basename = QTest::currentTestFunction();
+ tmplib.reset(new QTemporaryFile(QDir::currentPath() + u'/' + basename + u".XXXXXX" SUFFIX ""_s));
+ QVERIFY2(tmplib->open(), qPrintable(tmplib->errorString()));
+
+ // sanity-check
+ QByteArray magic = QByteArray::fromRawData(reinterpret_cast<const char *>(srcdata), SELFMAG);
+ QCOMPARE(magic, QByteArray(ELFMAG));
+
+ // copy everything via mmap()
+ QVERIFY2(tmplib->resize(srcsize), qPrintable(tmplib->errorString()));
+ uchar *dstdata = tmplib->map(0, srcsize);
+ memcpy(dstdata, srcdata, srcsize);
+
+ // now patch the file
+ patcher.f(reinterpret_cast<ElfHeader *>(dstdata), tmplib.get());
+
+ ok = true;
+ }();
+ if (!ok)
+ tmplib.reset();
+ return tmplib;
+}
+
+// All ELF systems are expected to support GCC expression statements
+#define patchElf(source, patcher) __extension__({ \
+ auto r = patchElf(source, patcher); \
+ if (QTest::currentTestFailed()) return; \
+ std::move(r); \
+ })
+#endif // Q_OF_ELF
+
static QString sys_qualifiedLibraryName(const QString &fileName)
{
+#ifdef Q_OS_ANDROID
+ // On Android all the libraries must be located in the APK's libs subdir
+ const QStringList paths = QCoreApplication::libraryPaths();
+ if (!paths.isEmpty()) {
+ return QLatin1String("%1/%2%3_%4%5").arg(paths.first(), PREFIX, fileName,
+ ANDROID_ARCH, SUFFIX);
+ }
+ return fileName;
+#else
QString name = QLatin1String("bin/") + QLatin1String(PREFIX) + fileName + QLatin1String(SUFFIX);
const QString libname = QFINDTESTDATA(name);
QFileInfo fi(libname);
if (fi.exists())
return fi.canonicalFilePath();
return libname;
+#endif
}
QT_FORWARD_DECLARE_CLASS(QPluginLoader)
@@ -109,20 +190,29 @@ private slots:
void errorString();
void loadHints();
void deleteinstanceOnUnload();
+#if defined (Q_OF_ELF)
void loadDebugObj();
+ void loadCorruptElf_data();
void loadCorruptElf();
+# if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ void loadCorruptElfOldPlugin_data();
+ void loadCorruptElfOldPlugin();
+# endif
+#endif
void loadMachO_data();
void loadMachO();
-#if defined (Q_OS_UNIX)
- void loadGarbage();
-#endif
void relativePath();
void absolutePath();
void reloadPlugin();
+ void loadSectionTableStrippedElf();
void preloadedPlugin_data();
void preloadedPlugin();
+ void staticPlugins();
+ void reregisteredStaticPlugins();
};
+Q_IMPORT_PLUGIN(StaticPlugin)
+
void tst_QPluginLoader::cleanup()
{
// check if the library/plugin was leaked
@@ -190,7 +280,9 @@ void tst_QPluginLoader::errorString()
QVERIFY(!unloaded);
}
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_HPUX)
+// A bug in QNX causes the test to crash on exit after attempting to load
+// a shared library with undefined symbols (tracked as QTBUG-114682).
+#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) && !defined(Q_OS_HPUX) && !defined(Q_OS_QNX)
{
QPluginLoader loader( sys_qualifiedLibraryName("almostplugin")); //a plugin with unresolved symbols
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
@@ -208,29 +300,36 @@ void tst_QPluginLoader::errorString()
}
#endif
- {
- QPluginLoader loader( sys_qualifiedLibraryName("theplugin")); //a plugin
-
- // Check metadata
- const QJsonObject metaData = loader.metaData();
- QCOMPARE(metaData.value("IID").toString(), QStringLiteral("org.qt-project.Qt.autotests.plugininterface"));
- const QJsonObject kpluginObject = metaData.value("MetaData").toObject().value("KPlugin").toObject();
- QCOMPARE(kpluginObject.value("Name[mr]").toString(), QString::fromUtf8("चौकट भूमिती"));
-
- // Load
- QCOMPARE(loader.load(), true);
- QCOMPARE(loader.errorString(), unknown);
-
- QVERIFY(loader.instance() != static_cast<QObject*>(0));
- QCOMPARE(loader.errorString(), unknown);
-
- // Make sure that plugin really works
- PluginInterface* theplugin = qobject_cast<PluginInterface*>(loader.instance());
- QString pluginName = theplugin->pluginName();
- QCOMPARE(pluginName, QLatin1String("Plugin ok"));
-
- QCOMPARE(loader.unload(), true);
- QCOMPARE(loader.errorString(), unknown);
+ static constexpr std::initializer_list<const char *> validplugins = {
+ "theplugin",
+#if defined(Q_OF_ELF) && QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ "theoldplugin"
+#endif
+ };
+ for (const char *basename : validplugins) {
+ QPluginLoader loader( sys_qualifiedLibraryName(basename)); //a plugin
+
+ // Check metadata
+ const QJsonObject metaData = loader.metaData();
+ QVERIFY2(!metaData.isEmpty(), "No metadata from " + loader.fileName().toLocal8Bit());
+ QCOMPARE(metaData.value("IID").toString(), QStringLiteral("org.qt-project.Qt.autotests.plugininterface"));
+ const QJsonObject kpluginObject = metaData.value("MetaData").toObject().value("KPlugin").toObject();
+ QCOMPARE(kpluginObject.value("Name[mr]").toString(), QString::fromUtf8("चौकट भूमिती"));
+
+ // Load
+ QVERIFY2(loader.load(), qPrintable(loader.errorString()));
+ QCOMPARE(loader.errorString(), unknown);
+
+ QVERIFY(loader.instance() != static_cast<QObject*>(0));
+ QCOMPARE(loader.errorString(), unknown);
+
+ // Make sure that plugin really works
+ PluginInterface* theplugin = qobject_cast<PluginInterface*>(loader.instance());
+ QString pluginName = theplugin->pluginName();
+ QCOMPARE(pluginName, QLatin1String("Plugin ok"));
+
+ QCOMPARE(loader.unload(), true);
+ QCOMPARE(loader.errorString(), unknown);
}
}
@@ -240,10 +339,37 @@ void tst_QPluginLoader::loadHints()
QSKIP("This test requires Qt to create shared libraries.");
#endif
QPluginLoader loader;
- QCOMPARE(loader.loadHints(), (QLibrary::LoadHints)0); //Do not crash
+ QCOMPARE(loader.loadHints(), QLibrary::PreventUnloadHint); //Do not crash
+ loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
+ QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
+ // We can clear load hints when file name is not set.
+ loader.setLoadHints(QLibrary::LoadHints{});
+ QCOMPARE(loader.loadHints(), QLibrary::LoadHints{});
+ // Set the hints again
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
+ QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
loader.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin
QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
+
+ QPluginLoader loader4;
+ QCOMPARE(loader4.loadHints(), QLibrary::PreventUnloadHint);
+ loader4.setLoadHints(QLibrary::LoadHints{});
+ QCOMPARE(loader4.loadHints(), QLibrary::LoadHints{});
+ loader4.setFileName(sys_qualifiedLibraryName("theplugin"));
+ // Hints are merged with hints from the previous loader.
+ QCOMPARE(loader4.loadHints(), QLibrary::ResolveAllSymbolsHint);
+ // We cannot clear load hints after associating the loader with a file.
+ loader.setLoadHints(QLibrary::LoadHints{});
+ QCOMPARE(loader.loadHints(), QLibrary::ResolveAllSymbolsHint);
+
+ QPluginLoader loader2;
+ QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint);
+ loader2.setFileName(sys_qualifiedLibraryName("theplugin"));
+ // Hints are merged with hints from previous loaders.
+ QCOMPARE(loader2.loadHints(), QLibrary::PreventUnloadHint | QLibrary::ResolveAllSymbolsHint);
+
+ QPluginLoader loader3(sys_qualifiedLibraryName("theplugin"));
+ QCOMPARE(loader3.loadHints(), QLibrary::PreventUnloadHint | QLibrary::ResolveAllSymbolsHint);
}
void tst_QPluginLoader::deleteinstanceOnUnload()
@@ -273,92 +399,485 @@ void tst_QPluginLoader::deleteinstanceOnUnload()
QVERIFY(spy2.isValid());
if (pass == 0) {
QCOMPARE(loader2.unload(), false); // refcount not reached 0, not really unloaded
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 0);
+ QCOMPARE(spy1.size(), 0);
+ QCOMPARE(spy2.size(), 0);
}
QCOMPARE(instance1->pluginName(), QLatin1String("Plugin ok"));
QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok"));
QVERIFY(loader1.unload()); // refcount reached 0, did really unload
- QCOMPARE(spy1.count(), 1);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy1.size(), 1);
+ QCOMPARE(spy2.size(), 1);
}
}
+#if defined(Q_OF_ELF)
+
void tst_QPluginLoader::loadDebugObj()
{
#if !defined(QT_SHARED)
QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
#endif
-#if defined (__ELF__)
QVERIFY(QFile::exists(QFINDTESTDATA("elftest/debugobj.so")));
QPluginLoader lib1(QFINDTESTDATA("elftest/debugobj.so"));
QCOMPARE(lib1.load(), false);
+}
+
+template <typename Lambda>
+static void newRow(const char *rowname, QString &&snippet, Lambda &&patcher)
+{
+ QTest::newRow(rowname)
+ << std::move(snippet) << ElfPatcher::fromLambda(std::forward<Lambda>(patcher));
+}
+
+static ElfPhdr *getProgramEntry(ElfHeader *h, int index)
+{
+ auto phdr = reinterpret_cast<ElfPhdr *>(h->e_phoff + reinterpret_cast<uchar *>(h));
+ return phdr + index;
+}
+
+static void loadCorruptElfCommonRows()
+{
+ QTest::addColumn<QString>("snippet");
+ QTest::addColumn<ElfPatcher>("patcher");
+
+ using H = ElfHeader *; // because I'm lazy
+ newRow("not-elf", "invalid signature", [](H h) {
+ h->e_ident[EI_MAG0] = 'Q';
+ h->e_ident[EI_MAG1] = 't';
+ });
+
+ newRow("wrong-word-size", "file is for a different word size", [](H h) {
+ h->e_ident[EI_CLASS] = sizeof(void *) == 8 ? ELFCLASS32 : ELFCLASS64;
+
+ // unnecessary, but we're doing it anyway
+# ifdef _LP64
+ Elf32_Ehdr o;
+ o.e_phentsize = sizeof(Elf32_Phdr);
+ o.e_shentsize = sizeof(Elf32_Shdr);
+# else
+ Elf64_Ehdr o;
+ o.e_phentsize = sizeof(Elf64_Phdr);
+ o.e_shentsize = sizeof(Elf64_Shdr);
+# endif
+ memcpy(o.e_ident, h->e_ident, EI_NIDENT);
+ o.e_type = h->e_type;
+ o.e_machine = h->e_machine;
+ o.e_version = h->e_version;
+ o.e_entry = h->e_entry;
+ o.e_phoff = h->e_phoff;
+ o.e_shoff = h->e_shoff;
+ o.e_flags = h->e_flags;
+ o.e_ehsize = sizeof(o);
+ o.e_phnum = h->e_phnum;
+ o.e_shnum = h->e_shnum;
+ o.e_shstrndx = h->e_shstrndx;
+ memcpy(h, &o, sizeof(o));
+ });
+ newRow("invalid-word-size", "file is for a different word size", [](H h) {
+ h->e_ident[EI_CLASS] = ELFCLASSNONE;
+ });
+ newRow("unknown-word-size", "file is for a different word size", [](H h) {
+ h->e_ident[EI_CLASS] |= 0x40;
+ });
+
+ newRow("wrong-endian", "file is for the wrong endianness", [](H h) {
+ h->e_ident[EI_DATA] = QSysInfo::ByteOrder == QSysInfo::LittleEndian ? ELFDATA2MSB : ELFDATA2LSB;
+
+ // unnecessary, but we're doing it anyway
+ h->e_type = qbswap(h->e_type);
+ h->e_machine = qbswap(h->e_machine);
+ h->e_version = qbswap(h->e_version);
+ h->e_entry = qbswap(h->e_entry);
+ h->e_phoff = qbswap(h->e_phoff);
+ h->e_shoff = qbswap(h->e_shoff);
+ h->e_flags = qbswap(h->e_flags);
+ h->e_ehsize = qbswap(h->e_ehsize);
+ h->e_phnum = qbswap(h->e_phnum);
+ h->e_phentsize = qbswap(h->e_phentsize);
+ h->e_shnum = qbswap(h->e_shnum);
+ h->e_shentsize = qbswap(h->e_shentsize);
+ h->e_shstrndx = qbswap(h->e_shstrndx);
+ });
+ newRow("invalid-endian", "file is for the wrong endianness", [](H h) {
+ h->e_ident[EI_DATA] = ELFDATANONE;
+ });
+ newRow("unknown-endian", "file is for the wrong endianness", [](H h) {
+ h->e_ident[EI_DATA] |= 0x40;
+ });
+
+ newRow("elf-version-0", "file has an unknown ELF version", [](H h) {
+ --h->e_ident[EI_VERSION];
+ });
+ newRow("elf-version-2", "file has an unknown ELF version", [](H h) {
+ ++h->e_ident[EI_VERSION];
+ });
+
+ newRow("executable", "file is not a shared object", [](H h) {
+ h->e_type = ET_EXEC;
+ });
+ newRow("relocatable", "file is not a shared object", [](H h) {
+ h->e_type = ET_REL;
+ });
+ newRow("core-file", "file is not a shared object", [](H h) {
+ h->e_type = ET_CORE;
+ });
+ newRow("invalid-type", "file is not a shared object", [](H h) {
+ h->e_type |= 0x100;
+ });
+
+ newRow("wrong-arch", "file is for a different processor", [](H h) {
+ // could just ++h->e_machine...
+# if defined(Q_PROCESSOR_X86_64)
+ h->e_machine = EM_AARCH64;
+# elif defined(Q_PROCESSOR_ARM_64)
+ h->e_machine = EM_X86_64;
+# elif defined(Q_PROCESSOR_X86_32)
+ h->e_machine = EM_ARM;
+# elif defined(Q_PROCESSOR_ARM)
+ h->e_machine = EM_386;
+# elif defined(Q_PROCESSOR_MIPS_64)
+ h->e_machine = EM_PPC64;
+# elif defined(Q_PROCESSOR_MIPS_32)
+ h->e_machine = EM_PPC;
+# elif defined(Q_PROCESSOR_POWER_64)
+ h->e_machine = EM_S390;
+# elif defined(Q_PROCESSOR_POWER_32)
+ h->e_machine = EM_MIPS;
+# endif
+ });
+
+ newRow("file-version-0", "file has an unknown ELF version", [](H h) {
+ --h->e_version;
+ });
+ newRow("file-version-2", "file has an unknown ELF version", [](H h) {
+ ++h->e_version;
+ });
+
+ newRow("program-entry-size-zero", "unexpected program header entry size", [](H h) {
+ h->e_phentsize = 0;
+ });
+ newRow("program-entry-small", "unexpected program header entry size", [](H h) {
+ h->e_phentsize = alignof(ElfPhdr);
+ });
+
+ newRow("program-table-starts-past-eof", "program header table extends past the end of the file",
+ [](H h, QFile *f) {
+ h->e_phoff = f->size();
+ });
+ newRow("program-table-ends-past-eof", "program header table extends past the end of the file",
+ [](H h, QFile *f) {
+ h->e_phoff = f->size() + 1- h->e_phentsize * h->e_phnum;
+ });
+
+ newRow("segment-starts-past-eof", "a program header entry extends past the end of the file",
+ [](H h, QFile *f) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_LOAD)
+ continue;
+ p->p_offset = f->size();
+ break;
+ }
+ });
+ newRow("segment-ends-past-eof", "a program header entry extends past the end of the file",
+ [](H h, QFile *f) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_LOAD)
+ continue;
+ p->p_filesz = f->size() + 1 - p->p_offset;
+ break;
+ }
+ });
+ newRow("segment-bounds-overflow", "a program header entry extends past the end of the file",
+ [](H h) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_LOAD)
+ continue;
+ p->p_filesz = ~size_t(0); // -1
+ break;
+ }
+ });
+
+ newRow("no-code", "file has no code", [](H h) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type == PT_LOAD)
+ p->p_flags &= ~PF_X;
+ }
+ });
+}
+
+void tst_QPluginLoader::loadCorruptElf_data()
+{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
#endif
+ loadCorruptElfCommonRows();
+ using H = ElfHeader *; // because I'm lazy
+
+ // PT_NOTE tests
+ // general validity is tested in the common rows, for all segments
+
+ newRow("misaligned-note-segment", "note segment start is not properly aligned", [](H h) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type == PT_NOTE)
+ ++p->p_offset;
+ }
+ });
+
+ static const auto getFirstNote = [](void *header, ElfPhdr *phdr) {
+ return reinterpret_cast<ElfNhdr *>(static_cast<uchar *>(header) + phdr->p_offset);
+ };
+ static const auto getNextNote = [](void *header, ElfPhdr *phdr, ElfNhdr *n) {
+ // how far into the segment are we?
+ size_t offset = reinterpret_cast<uchar *>(n) - static_cast<uchar *>(header) - phdr->p_offset;
+
+ size_t delta = sizeof(*n) + n->n_namesz + phdr->p_align - 1;
+ delta &= -phdr->p_align;
+ delta += n->n_descsz + phdr->p_align - 1;
+ delta &= -phdr->p_align;
+
+ offset += delta;
+ if (offset < phdr->p_filesz)
+ n = reinterpret_cast<ElfNhdr *>(reinterpret_cast<uchar *>(n) + delta);
+ else
+ n = nullptr;
+ return n;
+ };
+
+ // all the intra-note errors cause the notes simply to be skipped
+ auto newNoteRow = [](const char *rowname, auto &&lambda) {
+ newRow(rowname, "is not a Qt plugin (metadata not found)", std::move(lambda));
+ };
+ newNoteRow("no-notes", [](H h) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type == PT_NOTE)
+ p->p_type = PT_NULL;
+ }
+ });
+
+ newNoteRow("note-larger-than-segment-nonqt", [](H h) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_NOTE)
+ continue;
+ ElfNhdr *n = getFirstNote(h, p);
+ n->n_descsz = p->p_filesz;
+ n->n_type = 0; // ensure it's not the Qt note
+ }
+ });
+ newNoteRow("note-larger-than-segment-qt", [](H h) {
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_NOTE || p->p_align != alignof(QPluginMetaData::ElfNoteHeader))
+ continue;
+
+ // find the Qt metadata note
+ constexpr QPluginMetaData::ElfNoteHeader header(0);
+ ElfNhdr *n = getFirstNote(h, p);
+ for ( ; n; n = getNextNote(h, p, n)) {
+ if (n->n_type == header.n_type && n->n_namesz == header.n_namesz) {
+ if (memcmp(n + 1, header.name, sizeof(header.name)) == 0)
+ break;
+ }
+ }
+
+ if (!n)
+ break;
+ n->n_descsz = p->p_filesz;
+ return;
+ }
+ qWarning("Could not find the Qt metadata note in this file. Test will fail.");
+ });
+ newNoteRow("note-size-overflow1", [](H h) {
+ // due to limited range, this will not overflow on 64-bit
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_NOTE)
+ continue;
+ ElfNhdr *n = getFirstNote(h, p);
+ n->n_namesz = ~decltype(n->n_namesz)(0);
+ }
+ });
+ newNoteRow("note-size-overflow2", [](H h) {
+ // due to limited range, this will not overflow on 64-bit
+ for (int i = 0; i < h->e_phnum; ++i) {
+ ElfPhdr *p = getProgramEntry(h, i);
+ if (p->p_type != PT_NOTE)
+ continue;
+ ElfNhdr *n = getFirstNote(h, p);
+ n->n_namesz = ~decltype(n->n_namesz)(0) / 2;
+ n->n_descsz = ~decltype(n->n_descsz)(0) / 2;
+ }
+ });
+}
+
+static void loadCorruptElf_helper(const QString &origLibrary)
+{
+ QFETCH(QString, snippet);
+ QFETCH(ElfPatcher, patcher);
+
+ std::unique_ptr<QTemporaryFile> tmplib = patchElf(origLibrary, patcher);
+
+ QPluginLoader lib(tmplib->fileName());
+ QVERIFY(!lib.load());
+ QVERIFY2(lib.errorString().contains(snippet), qPrintable(lib.errorString()));
}
void tst_QPluginLoader::loadCorruptElf()
{
+ loadCorruptElf_helper(sys_qualifiedLibraryName("theplugin"));
+}
+
+# if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+void tst_QPluginLoader::loadCorruptElfOldPlugin_data()
+{
#if !defined(QT_SHARED)
QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
#endif
-#if defined (__ELF__)
- if (sizeof(void*) == 8) {
- QVERIFY(QFile::exists(QFINDTESTDATA("elftest/corrupt1.elf64.so")));
-
- QPluginLoader lib1(QFINDTESTDATA("elftest/corrupt1.elf64.so"));
- QCOMPARE(lib1.load(), false);
- QVERIFY2(lib1.errorString().contains("not an ELF object"), qPrintable(lib1.errorString()));
-
- QPluginLoader lib2(QFINDTESTDATA("elftest/corrupt2.elf64.so"));
- QCOMPARE(lib2.load(), false);
- QVERIFY2(lib2.errorString().contains("invalid"), qPrintable(lib2.errorString()));
-
- QPluginLoader lib3(QFINDTESTDATA("elftest/corrupt3.elf64.so"));
- QCOMPARE(lib3.load(), false);
- QVERIFY2(lib3.errorString().contains("invalid"), qPrintable(lib3.errorString()));
- } else if (sizeof(void*) == 4) {
- QPluginLoader libW(QFINDTESTDATA("elftest/corrupt3.elf64.so"));
- QCOMPARE(libW.load(), false);
- QVERIFY2(libW.errorString().contains("architecture"), qPrintable(libW.errorString()));
- } else {
- QFAIL("Please port QElfParser to this platform or blacklist this test.");
- }
-#endif
+ loadCorruptElfCommonRows();
+ using H = ElfHeader *; // because I'm lazy
+
+ newRow("section-entry-size-zero", "unexpected section entry size", [](H h) {
+ h->e_shentsize = 0;
+ });
+ newRow("section-entry-small", "unexpected section entry size", [](H h) {
+ h->e_shentsize = alignof(ElfShdr);
+ });
+ newRow("section-entry-misaligned", "unexpected section entry size", [](H h) {
+ ++h->e_shentsize;
+ });
+ newRow("no-sections", "is not a Qt plugin (metadata not found)", [](H h){
+ h->e_shnum = h->e_shoff = h->e_shstrndx = 0;
+ });
+
+ // section table tests
+ newRow("section-table-starts-past-eof", "section table extends past the end of the file",
+ [](H h, QFile *f) {
+ h->e_shoff = f->size();
+ });
+ newRow("section-table-ends-past-eof", "section table extends past the end of the file",
+ [](H h, QFile *f) {
+ h->e_shoff = f->size() + 1 - h->e_shentsize * h->e_shnum;
+ });
+
+ static auto getSection = +[](H h, int index) {
+ auto sections = reinterpret_cast<ElfShdr *>(h->e_shoff + reinterpret_cast<uchar *>(h));
+ return sections + index;
+ };
+
+ // arbitrary section bounds checks
+ // section index = 0 is usually a NULL section, so we try 1
+ newRow("section1-starts-past-eof", "section contents extend past the end of the file",
+ [](H h, QFile *f) {
+ ElfShdr *s = getSection(h, 1);
+ s->sh_offset = f->size();
+ });
+ newRow("section1-ends-past-eof", "section contents extend past the end of the file",
+ [](H h, QFile *f) {
+ ElfShdr *s = getSection(h, 1);
+ s->sh_size = f->size() + 1 - s->sh_offset;
+ });
+ newRow("section1-bounds-overflow", "section contents extend past the end of the file", [](H h) {
+ ElfShdr *s = getSection(h, 1);
+ s->sh_size = -sizeof(*s);
+ });
+
+ // section header string table tests
+ newRow("shstrndx-invalid", "e_shstrndx greater than the number of sections", [](H h) {
+ h->e_shstrndx = h->e_shnum;
+ });
+ newRow("shstrtab-starts-past-eof", "section header string table extends past the end of the file",
+ [](H h, QFile *f) {
+ ElfShdr *s = getSection(h, h->e_shstrndx);
+ s->sh_offset = f->size();
+ });
+ newRow("shstrtab-ends-past-eof", "section header string table extends past the end of the file",
+ [](H h, QFile *f) {
+ ElfShdr *s = getSection(h, h->e_shstrndx);
+ s->sh_size = f->size() + 1 - s->sh_offset;
+ });
+ newRow("shstrtab-bounds-overflow", "section header string table extends past the end of the file", [](H h) {
+ ElfShdr *s = getSection(h, h->e_shstrndx);
+ s->sh_size = -sizeof(*s);
+ });
+ newRow("section-name-past-eof", "section name extends past the end of the file", [](H h, QFile *f) {
+ ElfShdr *section1 = getSection(h, 1);
+ ElfShdr *shstrtab = getSection(h, h->e_shstrndx);
+ section1->sh_name = f->size() - shstrtab->sh_offset;
+ });
+ newRow("section-name-past-end-of-shstrtab", "section name extends past the end of the file", [](H h) {
+ ElfShdr *section1 = getSection(h, 1);
+ ElfShdr *shstrtab = getSection(h, h->e_shstrndx);
+ section1->sh_name = shstrtab->sh_size;
+ });
+
+ newRow("debug-symbols", "metadata not found", [](H h) {
+ // attempt to make it look like extracted debug info
+ for (int i = 1; i < h->e_shnum; ++i) {
+ ElfShdr *s = getSection(h, i);
+ if (s->sh_type == SHT_NOBITS)
+ break;
+ if (s->sh_type != SHT_NOTE && s->sh_flags & SHF_ALLOC)
+ s->sh_type = SHT_NOBITS;
+ }
+ });
+
+ // we don't know which section is .qtmetadata, so we just apply to all of them
+ static auto applyToAllSectionFlags = +[](H h, int flag) {
+ for (int i = 0; i < h->e_shnum; ++i)
+ getSection(h, i)->sh_flags |= flag;
+ };
+ newRow("qtmetadata-executable", ".qtmetadata section is executable", [](H h) {
+ applyToAllSectionFlags(h, SHF_EXECINSTR);
+ });
+ newRow("qtmetadata-writable", ".qtmetadata section is writable", [](H h) {
+ applyToAllSectionFlags(h, SHF_WRITE);
+ });
}
+void tst_QPluginLoader::loadCorruptElfOldPlugin()
+{
+ // ### Qt7: don't forget to remove theoldplugin from the build
+ loadCorruptElf_helper(sys_qualifiedLibraryName("theoldplugin"));
+}
+# endif // Qt 7
+#endif // Q_OF_ELF
+
void tst_QPluginLoader::loadMachO_data()
{
#if defined(QT_BUILD_INTERNAL) && defined(Q_OF_MACH_O)
- QTest::addColumn<int>("parseResult");
+ QTest::addColumn<bool>("success");
- QTest::newRow("/dev/null") << int(QMachOParser::NotSuitable);
- QTest::newRow("elftest/debugobj.so") << int(QMachOParser::NotSuitable);
- QTest::newRow("tst_qpluginloader.cpp") << int(QMachOParser::NotSuitable);
- QTest::newRow("tst_qpluginloader") << int(QMachOParser::NotSuitable);
+ QTest::newRow("/dev/null") << false;
+ QTest::newRow("elftest/debugobj.so") << false;
+ QTest::newRow("tst_qpluginloader.cpp") << false;
+ QTest::newRow("tst_qpluginloader") << false;
# ifdef Q_PROCESSOR_X86_64
- QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
- QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::QtMetaDataSection);
-# elif defined(Q_PROCESSOR_X86_32)
- QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::QtMetaDataSection);
- QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
-# endif
-# ifndef Q_PROCESSOR_POWER_64
- QTest::newRow("machtest/good.ppc64.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.x86_64.dylib") << true;
+ QTest::newRow("machtest/good.arm64.dylib") << false;
+ QTest::newRow("machtest/good.fat.no-x86_64.dylib") << false;
+ QTest::newRow("machtest/good.fat.no-arm64.dylib") << true;
+# elif defined(Q_PROCESSOR_ARM)
+ QTest::newRow("machtest/good.arm64.dylib") << true;
+ QTest::newRow("machtest/good.x86_64.dylib") << false;
+ QTest::newRow("machtest/good.fat.no-arm64.dylib") << false;
+ QTest::newRow("machtest/good.fat.no-x86_64.dylib") << true;
# endif
- QTest::newRow("machtest/good.fat.all.dylib") << int(QMachOParser::QtMetaDataSection);
- QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.stub-i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.all.dylib") << true;
+ QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << false;
+ QTest::newRow("machtest/good.fat.stub-arm64.dylib") << false;
QDir d(QFINDTESTDATA("machtest"));
- QStringList badlist = d.entryList(QStringList() << "bad*.dylib");
- foreach (const QString &bad, badlist)
- QTest::newRow(qPrintable("machtest/" + bad)) << int(QMachOParser::NotSuitable);
+ const QStringList badlist = d.entryList(QStringList() << "bad*.dylib");
+ for (const QString &bad : badlist)
+ QTest::newRow(qPrintable("machtest/" + bad)) << false;
#endif
}
@@ -369,60 +888,49 @@ void tst_QPluginLoader::loadMachO()
QVERIFY(f.open(QIODevice::ReadOnly));
QByteArray data = f.readAll();
- qsizetype pos;
- qsizetype len;
- QString errorString;
- int r = QMachOParser::parse(data.constData(), data.size(), f.fileName(), &errorString, &pos, &len);
-
- QFETCH(int, parseResult);
- QCOMPARE(r, parseResult);
+ QString errorString = f.fileName();
+ QLibraryScanResult r = QMachOParser::parse(data.constData(), data.size(), &errorString);
- if (r == QMachOParser::NotSuitable)
+ QFETCH(bool, success);
+ if (success) {
+ QVERIFY(r.length != 0);
+ } else {
+ QCOMPARE(r.length, 0);
return;
+ }
- QVERIFY(pos > 0);
- QVERIFY(len >= sizeof(void*));
- QVERIFY(pos + long(len) < data.size());
- QCOMPARE(pos & (sizeof(void*) - 1), 0UL);
-
- void *value = *(void**)(data.constData() + pos);
- QCOMPARE(value, sizeof(void*) > 4 ? (void*)(0xc0ffeec0ffeeL) : (void*)0xc0ffee);
+ QVERIFY(r.pos > 0);
+ QVERIFY(r.pos + r.length < data.size());
// now that we know it's valid, let's try to make it invalid
- ulong offeredlen = pos;
+ ulong offeredlen = r.pos;
do {
--offeredlen;
- r = QMachOParser::parse(data.constData(), offeredlen, f.fileName(), &errorString, &pos, &len);
- QVERIFY2(r == QMachOParser::NotSuitable, qPrintable(QString("Failed at size 0x%1").arg(offeredlen, 0, 16)));
+ errorString = f.fileName();
+ r = QMachOParser::parse(data.constData(), offeredlen, &errorString);
+ QVERIFY2(r.length == 0, qPrintable(QString("Failed at size 0x%1").arg(offeredlen, 0, 16)));
} while (offeredlen);
#endif
}
-#if defined (Q_OS_UNIX)
-void tst_QPluginLoader::loadGarbage()
-{
-#if !defined(QT_SHARED)
- QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
-#endif
- for (int i=0; i<5; i++) {
- const QString name = QLatin1String("elftest/garbage") + QString::number(i + 1) + QLatin1String(".so");
- QPluginLoader lib(QFINDTESTDATA(name));
- QCOMPARE(lib.load(), false);
- QVERIFY(lib.errorString() != QString("Unknown error"));
- }
-}
-#endif
-
void tst_QPluginLoader::relativePath()
{
#if !defined(QT_SHARED)
QSKIP("This test requires Qt to create shared libraries.");
#endif
+#ifdef Q_OS_ANDROID
+ // On Android we do not need to explicitly set library paths, as they are
+ // already set.
+ // But we need to use ARCH suffix in pulgin name
+ const QString pluginName("theplugin_" ANDROID_ARCH SUFFIX);
+#else
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
QCoreApplication::addLibraryPath(binDir);
- QPluginLoader loader("theplugin");
+ const QString pluginName("theplugin" SUFFIX);
+#endif
+ QPluginLoader loader(pluginName);
loader.load(); // not recommended, instance() should do the job.
PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance());
QVERIFY(instance);
@@ -435,13 +943,27 @@ void tst_QPluginLoader::absolutePath()
#if !defined(QT_SHARED)
QSKIP("This test requires Qt to create shared libraries.");
#endif
+#ifdef Q_OS_ANDROID
+ // On Android we need to clear library paths to make sure that the absolute
+ // path works
+ const QStringList libraryPaths = QCoreApplication::libraryPaths();
+ QVERIFY(!libraryPaths.isEmpty());
+ QCoreApplication::setLibraryPaths(QStringList());
+ const QString pluginPath(libraryPaths.first() + "/" PREFIX "theplugin_" ANDROID_ARCH SUFFIX);
+#else
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
QVERIFY(QDir::isAbsolutePath(binDir));
- QPluginLoader loader(binDir + "/theplugin");
+ const QString pluginPath(binDir + "/" PREFIX "theplugin" SUFFIX);
+#endif
+ QPluginLoader loader(pluginPath);
loader.load(); // not recommended, instance() should do the job.
PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance());
+#ifdef Q_OS_ANDROID
+ // Restore library paths
+ QCoreApplication::setLibraryPaths(libraryPaths);
+#endif
QVERIFY(instance);
QCOMPARE(instance->pluginName(), QLatin1String("Plugin ok"));
QVERIFY(loader.unload());
@@ -462,7 +984,7 @@ void tst_QPluginLoader::reloadPlugin()
QSignalSpy spy(loader.instance(), &QObject::destroyed);
QVERIFY(spy.isValid());
QVERIFY(loader.unload()); // refcount reached 0, did really unload
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
// reload plugin
QVERIFY(loader.load());
@@ -475,6 +997,54 @@ void tst_QPluginLoader::reloadPlugin()
QVERIFY(loader.unload());
}
+void tst_QPluginLoader::loadSectionTableStrippedElf()
+{
+#ifdef Q_OS_ANDROID
+ if (QNativeInterface::QAndroidApplication::sdkVersion() >= 24)
+ QSKIP("Android 7+ (API 24+) linker doesn't allow missing or bad section header");
+#endif
+#if !defined(QT_SHARED)
+ QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
+#elif !defined(Q_OF_ELF)
+ QSKIP("Test specific to the ELF file format");
+#else
+ ElfPatcher patcher { [](ElfHeader *header, QFile *f) {
+ // modify the header to make it look like the section table was stripped
+ header->e_shoff = header->e_shnum = header->e_shstrndx = 0;
+
+ // and append a bad header at the end
+ QPluginMetaData::MagicHeader badHeader = {};
+ --badHeader.header.qt_major_version;
+ f->seek(f->size());
+ f->write(reinterpret_cast<const char *>(&badHeader), sizeof(badHeader));
+ } };
+
+ QString tmpLibName;
+ {
+ std::unique_ptr<QTemporaryFile> tmplib =
+ patchElf(sys_qualifiedLibraryName("theplugin"), patcher);
+
+ tmpLibName = tmplib->fileName();
+ tmplib->setAutoRemove(false);
+ }
+#if defined(Q_OS_QNX)
+ // On QNX plugin access is still too early, even when QTemporaryFile is closed
+ QTest::qSleep(1000);
+#endif
+ auto removeTmpLib = qScopeGuard([=]{
+ QFile::remove(tmpLibName);
+ });
+
+ // now attempt to load it
+ QPluginLoader loader(tmpLibName);
+ QVERIFY2(loader.load(), qPrintable(loader.errorString()));
+ PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance());
+ QVERIFY(instance);
+ QCOMPARE(instance->pluginName(), QLatin1String("Plugin ok"));
+ QVERIFY(loader.unload());
+#endif
+}
+
void tst_QPluginLoader::preloadedPlugin_data()
{
QTest::addColumn<bool>("doLoad");
@@ -520,5 +1090,50 @@ void tst_QPluginLoader::preloadedPlugin()
QVERIFY(lib.unload());
}
+void tst_QPluginLoader::staticPlugins()
+{
+ const QObjectList instances = QPluginLoader::staticInstances();
+ QVERIFY(instances.size());
+
+ // ensure the our plugin only shows up once
+ int foundCount = std::count_if(instances.begin(), instances.end(), [](QObject *obj) {
+ return obj->metaObject()->className() == QLatin1String("StaticPlugin");
+ });
+ QCOMPARE(foundCount, 1);
+
+ const auto plugins = QPluginLoader::staticPlugins();
+ QCOMPARE(plugins.size(), instances.size());
+
+ // find the metadata
+ QJsonObject metaData;
+ bool found = false;
+ for (const auto &p : plugins) {
+ metaData = p.metaData();
+ found = metaData.value("className").toString() == QLatin1String("StaticPlugin");
+ if (found)
+ break;
+ }
+ QVERIFY(found);
+
+ // We don't store the patch release version anymore (since 5.13)
+ QCOMPARE(metaData.value("version").toInt() / 0x100, QT_VERSION / 0x100);
+ QCOMPARE(metaData.value("IID").toString(), "SomeIID");
+ QCOMPARE(metaData.value("ExtraMetaData"), QJsonArray({ "StaticPlugin", "foo" }));
+ QCOMPARE(metaData.value("URI").toString(), "qt.test.pluginloader.staticplugin");
+}
+
+void tst_QPluginLoader::reregisteredStaticPlugins()
+{
+ // the Q_IMPORT_PLUGIN macro will have already done this
+ qRegisterStaticPluginFunction(qt_static_plugin_StaticPlugin());
+ staticPlugins();
+ if (QTest::currentTestFailed())
+ return;
+
+ qRegisterStaticPluginFunction(qt_static_plugin_StaticPlugin());
+ staticPlugins();
+}
+
+
QTEST_MAIN(tst_QPluginLoader)
#include "tst_qpluginloader.moc"
diff --git a/tests/auto/corelib/plugin/qpluginloader/winrt.pri b/tests/auto/corelib/plugin/qpluginloader/winrt.pri
deleted file mode 100644
index 31602634b2..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/winrt.pri
+++ /dev/null
@@ -1,9 +0,0 @@
-# We cannot use TESTDATA as plugins have to reside physically
-# inside the package directory
-winrt {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug/bin
- } else {
- DESTDIR = ../release/bin
- }
-}
diff --git a/tests/auto/corelib/plugin/quuid/CMakeLists.txt b/tests/auto/corelib/plugin/quuid/CMakeLists.txt
new file mode 100644
index 0000000000..be90dc1849
--- /dev/null
+++ b/tests/auto/corelib/plugin/quuid/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_quuid LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(testProcessUniqueness)
+add_subdirectory(test)
diff --git a/tests/auto/corelib/plugin/quuid/quuid.pro b/tests/auto/corelib/plugin/quuid/quuid.pro
deleted file mode 100644
index 25e24561ae..0000000000
--- a/tests/auto/corelib/plugin/quuid/quuid.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS = testProcessUniqueness
-
-SUBDIRS += test
-
diff --git a/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt b/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt
new file mode 100644
index 0000000000..1e1e820b14
--- /dev/null
+++ b/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_quuid Test:
+#####################################################################
+
+qt_internal_add_test(tst_quuid
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../tst_quuid.cpp
+)
+
+## Scopes:
+
+qt_internal_extend_target(tst_quuid CONDITION APPLE
+ SOURCES
+ ../tst_quuid_darwin.mm
+ LIBRARIES
+ Qt::CorePrivate
+ ${FWFoundation}
+)
+
+if(QT_FEATURE_process AND NOT ANDROID)
+ add_dependencies(tst_quuid testProcessUniqueness)
+endif()
diff --git a/tests/auto/corelib/plugin/quuid/test/test.pro b/tests/auto/corelib/plugin/quuid/test/test.pro
deleted file mode 100644
index 562bfbdc25..0000000000
--- a/tests/auto/corelib/plugin/quuid/test/test.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-CONFIG += testcase
-TARGET = tst_quuid
-QT = core testlib
-SOURCES = ../tst_quuid.cpp
-
-darwin {
- OBJECTIVE_SOURCES = ../tst_quuid_darwin.mm
- LIBS += -framework Foundation
-}
-
-CONFIG(debug_and_release_target) {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug
- } else {
- DESTDIR = ../release
- }
-} else {
- DESTDIR = ..
-}
diff --git a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/CMakeLists.txt b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/CMakeLists.txt
new file mode 100644
index 0000000000..f207cdaa3a
--- /dev/null
+++ b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessUniqueness Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessUniqueness
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_quuid/testProcessUniqueness"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
+
+set_target_properties(testProcessUniqueness PROPERTIES MACOSX_BUNDLE TRUE)
diff --git a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp
index d1e138d8eb..93d1201631 100644
--- a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp
+++ b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
#include <QUuid>
@@ -32,8 +7,8 @@
// This is a testcase for QTBUG-11213
int main(int argc, char **argv)
{
- Q_UNUSED(argc)
- Q_UNUSED(argv)
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
// Now print a few uuids.
printf("%s", qPrintable(QUuid::createUuid().toString()));
diff --git a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro
deleted file mode 100644
index 5ee7b1a21f..0000000000
--- a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-SOURCES = main.cpp
-QT = core
-CONFIG += console
-
-DESTDIR = ./
-
-# This app is testdata for tst_quuid
-target.path = $$[QT_INSTALL_TESTS]/tst_quuid/$$TARGET
-INSTALLS += target
diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
index 16552059dd..c5ce490b61 100644
--- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
+++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp
@@ -1,33 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
#include <qcoreapplication.h>
#include <quuid.h>
@@ -47,6 +25,8 @@ private slots:
void fromByteArray();
void toRfc4122();
void fromRfc4122();
+ void id128();
+ void uint128();
void createUuidV3OrV5();
void check_QDataStream();
void isNull();
@@ -120,7 +100,7 @@ void tst_QUuid::fromChar()
QCOMPARE(QUuid(), QUuid("fc69b59e-cc34-"));
QCOMPARE(QUuid(), QUuid("fc69b59e-cc34"));
QCOMPARE(QUuid(), QUuid("cc34"));
- QCOMPARE(QUuid(), QUuid(NULL));
+ QCOMPARE(QUuid(), QUuid(nullptr));
QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")));
}
@@ -157,7 +137,7 @@ void tst_QUuid::fromString_data()
ROW(uuidA, "{fc69b59e-cc34-4436-a43c-ee95d128b8c56"); // too long (not an error!)
ROW(invalid, "{fc69b59e-cc34-4436-a43c-ee95d128b8c" ); // premature end (within length limits)
ROW(invalid, " fc69b59e-cc34-4436-a43c-ee95d128b8c5}"); // leading space
- ROW(uuidA, "{fc69b59e-cc34-4436-a43c-ee95d128b8c5 "); // trailing space (not an error!)
+ ROW(uuidB, "{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b "); // trailing space (not an error!)
ROW(invalid, "{gc69b59e-cc34-4436-a43c-ee95d128b8c5}"); // non-hex digit in 1st group
ROW(invalid, "{fc69b59e-cp34-4436-a43c-ee95d128b8c5}"); // non-hex digit in 2nd group
ROW(invalid, "{fc69b59e-cc34-44r6-a43c-ee95d128b8c5}"); // non-hex digit in 3rd group
@@ -192,6 +172,11 @@ void tst_QUuid::fromString()
const auto longerInputL1 = inputL1 + '5'; // the '5' makes the premature end check incorrectly succeed
const auto inputL1S = QLatin1String(longerInputL1.data(), inputL1.size());
QCOMPARE(expected, QUuid::fromString(inputL1S));
+
+ // for QUtf8StringView, too:
+ const auto longerInputU8 = inputU8 + '5'; // the '5' makes the premature end check incorrectly succeed
+ const auto inputU8S = QUtf8StringView(longerInputU8.data(), inputU8.size());
+ QCOMPARE(expected, QUuid::fromString(inputU8S));
}
void tst_QUuid::toByteArray()
@@ -234,6 +219,78 @@ void tst_QUuid::fromRfc4122()
QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")));
}
+void tst_QUuid::id128()
+{
+ constexpr QUuid::Id128Bytes bytesA = { {
+ 0xfc, 0x69, 0xb5, 0x9e,
+ 0xcc, 0x34,
+ 0x44, 0x36,
+ 0xa4, 0x3c, 0xee, 0x95, 0xd1, 0x28, 0xb8, 0xc5,
+ } };
+ constexpr QUuid::Id128Bytes bytesB = { {
+ 0x1a, 0xb6, 0xe9, 0x3a,
+ 0xb1, 0xcb,
+ 0x4a, 0x87,
+ 0xba, 0x47, 0xec, 0x7e, 0x99, 0x03, 0x9a, 0x7b,
+ } };
+
+ QCOMPARE(QUuid(bytesA), uuidA);
+ QCOMPARE(QUuid(bytesB), uuidB);
+ QVERIFY(memcmp(uuidA.toBytes().data, bytesA.data, sizeof(QUuid::Id128Bytes)) == 0);
+ QVERIFY(memcmp(uuidB.toBytes().data, bytesB.data, sizeof(QUuid::Id128Bytes)) == 0);
+
+ QUuid::Id128Bytes leBytesA = {};
+ for (int i = 0; i < 16; i++)
+ leBytesA.data[15 - i] = bytesA.data[i];
+ QCOMPARE(QUuid(leBytesA, QSysInfo::LittleEndian), uuidA);
+ QVERIFY(memcmp(uuidA.toBytes(QSysInfo::LittleEndian).data, leBytesA.data, sizeof(leBytesA)) == 0);
+
+ // check the new q{To,From}{Big,Little}Endian() overloads
+ QUuid::Id128Bytes roundtrip = qFromLittleEndian(qToLittleEndian(bytesA));
+ QVERIFY(memcmp(roundtrip.data, bytesA.data, sizeof(bytesA)) == 0);
+ roundtrip = qFromBigEndian(qToBigEndian(bytesA));
+ QVERIFY(memcmp(roundtrip.data, bytesA.data, sizeof(bytesA)) == 0);
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ const QUuid::Id128Bytes beBytesA = qToBigEndian(leBytesA);
+ QVERIFY(memcmp(beBytesA.data, bytesA.data, sizeof(beBytesA)) == 0);
+ const QUuid::Id128Bytes otherLeBytesA = qFromBigEndian(bytesA);
+ QVERIFY(memcmp(otherLeBytesA.data, leBytesA.data, sizeof(leBytesA)) == 0);
+#else // Q_BIG_ENDIAN
+ const QUuid::Id128Bytes otherLeBytesA = qToLittleEndian(bytesA);
+ QVERIFY(memcmp(otherLeBytesA.data, leBytesA.data, sizeof(leBytesA)) == 0);
+ const QUuid::Id128Bytes beBytesA = qFromLittleEndian(leBytesA);
+ QVERIFY(memcmp(beBytesA.data, bytesA.data, sizeof(beBytesA)) == 0);
+#endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+}
+
+void tst_QUuid::uint128()
+{
+#ifdef QT_SUPPORTS_INT128
+ constexpr quint128 u = Q_UINT128_C(0xfc69b59e'cc344436'a43cee95'd128b8c5); // This is LE
+ constexpr quint128 be = qToBigEndian(u);
+ constexpr QUuid uuid = QUuid::fromUInt128(be);
+ static_assert(uuid.toUInt128() == be, "Round-trip through QUuid failed");
+
+ QCOMPARE(uuid, uuidA);
+ QCOMPARE(uuid.toUInt128(), be);
+
+ quint128 le = qFromBigEndian(be);
+ QCOMPARE(uuid.toUInt128(QSysInfo::LittleEndian), le);
+ QCOMPARE(QUuid::fromUInt128(le, QSysInfo::LittleEndian), uuidA);
+
+ QUuid::Id128Bytes bytes = { .data128 = { qToBigEndian(u) } };
+ QUuid uuid2(bytes);
+ QCOMPARE(uuid2, uuid);
+
+ // verify that toBytes() and toUInt128() provide bytewise similar result
+ constexpr quint128 val = uuid.toUInt128();
+ bytes = uuid.toBytes();
+ QVERIFY(memcmp(&val, bytes.data, sizeof(val)) == 0);
+#else
+ QSKIP("This platform has no support for 128-bit integer");
+#endif
+}
+
void tst_QUuid::createUuidV3OrV5()
{
//"www.widgets.com" is also from RFC4122
@@ -302,8 +359,8 @@ void tst_QUuid::notEqual()
void tst_QUuid::cpp11() {
#ifdef Q_COMPILER_UNIFORM_INIT
// "{fc69b59e-cc34-4436-a43c-ee95d128b8c5}" cf, initTestCase
- Q_DECL_CONSTEXPR QUuid u1{0xfc69b59e, 0xcc34, 0x4436, 0xa4, 0x3c, 0xee, 0x95, 0xd1, 0x28, 0xb8, 0xc5};
- Q_DECL_CONSTEXPR QUuid u2 = {0xfc69b59e, 0xcc34, 0x4436, 0xa4, 0x3c, 0xee, 0x95, 0xd1, 0x28, 0xb8, 0xc5};
+ constexpr QUuid u1{0xfc69b59e, 0xcc34, 0x4436, 0xa4, 0x3c, 0xee, 0x95, 0xd1, 0x28, 0xb8, 0xc5};
+ constexpr QUuid u2 = {0xfc69b59e, 0xcc34, 0x4436, 0xa4, 0x3c, 0xee, 0x95, 0xd1, 0x28, 0xb8, 0xc5};
Q_UNUSED(u1);
Q_UNUSED(u2);
#else
@@ -358,7 +415,7 @@ void tst_QUuid::variants()
QVERIFY( uuidA.variant() == QUuid::DCE );
QVERIFY( uuidB.variant() == QUuid::DCE );
- QUuid NCS = "{3a2f883c-4000-000d-0000-00fb40000000}";
+ QUuid NCS("{3a2f883c-4000-000d-0000-00fb40000000}");
QVERIFY( NCS.variant() == QUuid::NCS );
}
@@ -368,10 +425,10 @@ void tst_QUuid::versions()
QVERIFY( uuidA.version() == QUuid::Random );
QVERIFY( uuidB.version() == QUuid::Random );
- QUuid DCE_time= "{406c45a0-3b7e-11d0-80a3-0000c08810a7}";
+ QUuid DCE_time("{406c45a0-3b7e-11d0-80a3-0000c08810a7}");
QVERIFY( DCE_time.version() == QUuid::Time );
- QUuid NCS = "{3a2f883c-4000-000d-0000-00fb40000000}";
+ QUuid NCS("{3a2f883c-4000-000d-0000-00fb40000000}");
QVERIFY( NCS.version() == QUuid::VerUnknown );
}
@@ -380,7 +437,7 @@ class UuidThread : public QThread
public:
QUuid uuid;
- void run()
+ void run() override
{
uuid = QUuid::createUuid();
}
@@ -388,14 +445,14 @@ public:
void tst_QUuid::threadUniqueness()
{
- QVector<UuidThread *> threads(qMax(2, QThread::idealThreadCount()));
- for (int i = 0; i < threads.count(); ++i)
+ QList<UuidThread *> threads(qMax(2, QThread::idealThreadCount()));
+ for (int i = 0; i < threads.size(); ++i)
threads[i] = new UuidThread;
- for (int i = 0; i < threads.count(); ++i)
+ for (int i = 0; i < threads.size(); ++i)
threads[i]->start();
- for (int i = 0; i < threads.count(); ++i)
+ for (int i = 0; i < threads.size(); ++i)
QVERIFY(threads[i]->wait(1000));
- for (int i = 1; i < threads.count(); ++i)
+ for (int i = 1; i < threads.size(); ++i)
QVERIFY(threads[0]->uuid != threads[i]->uuid);
qDeleteAll(threads);
}
@@ -413,7 +470,7 @@ void tst_QUuid::processUniqueness()
QString processTwoOutput;
// Start it once
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
process.start("testProcessUniqueness/testProcessUniqueness.app");
#elif defined(Q_OS_ANDROID)
process.start("libtestProcessUniqueness.so");
@@ -424,7 +481,7 @@ void tst_QUuid::processUniqueness()
processOneOutput = process.readAllStandardOutput();
// Start it twice
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
process.start("testProcessUniqueness/testProcessUniqueness.app");
#elif defined(Q_OS_ANDROID)
process.start("libtestProcessUniqueness.so");
@@ -441,7 +498,7 @@ void tst_QUuid::processUniqueness()
void tst_QUuid::hash()
{
- uint h = qHash(uuidA);
+ size_t h = qHash(uuidA);
QCOMPARE(qHash(uuidA), h);
QCOMPARE(qHash(QUuid(uuidA.toString())), h);
}
@@ -451,7 +508,7 @@ void tst_QUuid::qvariant()
QUuid uuid = QUuid::createUuid();
QVariant v = QVariant::fromValue(uuid);
QVERIFY(!v.isNull());
- QCOMPARE(v.type(), QVariant::Uuid);
+ QCOMPARE(v.metaType(), QMetaType(QMetaType::QUuid));
QUuid uuid2 = v.value<QUuid>();
QVERIFY(!uuid2.isNull());
@@ -478,14 +535,14 @@ void tst_QUuid::qvariant_conversion()
// try reverse conversion QString -> QUuid
QVariant sv = QVariant::fromValue(uuid.toString());
- QCOMPARE(sv.type(), QVariant::String);
+ QCOMPARE(sv.metaType(), QMetaType(QMetaType::QString));
QVERIFY(sv.canConvert<QUuid>());
QCOMPARE(sv.value<QUuid>(), uuid);
// QString -> QUuid
{
QVariant sv = QVariant::fromValue(uuid.toByteArray());
- QCOMPARE(sv.type(), QVariant::ByteArray);
+ QCOMPARE(sv.metaType(), QMetaType(QMetaType::QByteArray));
QVERIFY(sv.canConvert<QUuid>());
QCOMPARE(sv.value<QUuid>(), uuid);
}
diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid_darwin.mm b/tests/auto/corelib/plugin/quuid/tst_quuid_darwin.mm
index 41ccece115..c3fc809b1f 100644
--- a/tests/auto/corelib/plugin/quuid/tst_quuid_darwin.mm
+++ b/tests/auto/corelib/plugin/quuid/tst_quuid_darwin.mm
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QUuid>
-#include <QtTest/QtTest>
+#include <QTest>
+
+#include <QtCore/private/qcore_mac_p.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
diff --git a/tests/auto/corelib/serialization/CMakeLists.txt b/tests/auto/corelib/serialization/CMakeLists.txt
new file mode 100644
index 0000000000..3792336255
--- /dev/null
+++ b/tests/auto/corelib/serialization/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(json)
+add_subdirectory(qcborstreamreader)
+add_subdirectory(qcborstreamwriter)
+if(NOT WASM)
+ add_subdirectory(qcborvalue)
+endif()
+add_subdirectory(qcborvalue_json)
+if(TARGET Qt::Gui)
+ add_subdirectory(qdatastream)
+ add_subdirectory(qdatastream_core_pixmap)
+endif()
+if(TARGET Qt::Network AND NOT WASM)
+ add_subdirectory(qtextstream)
+endif()
+if(TARGET Qt::Gui AND TARGET Qt::Network AND TARGET Qt::Xml AND NOT INTEGRITY AND NOT QNX AND NOT WASM)
+ add_subdirectory(qxmlstream)
+endif()
diff --git a/tests/auto/corelib/serialization/cborlargedatavalidation.cpp b/tests/auto/corelib/serialization/cborlargedatavalidation.cpp
new file mode 100644
index 0000000000..2fe1012f12
--- /dev/null
+++ b/tests/auto/corelib/serialization/cborlargedatavalidation.cpp
@@ -0,0 +1,120 @@
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtEndian>
+
+#include <cbor.h>
+
+namespace {
+// A QIODevice that supplies a fixed header followed by a large sequence of
+// null bytes up until a pre-determined size.
+class LargeIODevice final : public QIODevice
+{
+public:
+ qint64 realSize;
+ QByteArray start;
+
+ LargeIODevice(const QByteArray &start, qint64 size, QObject *parent = nullptr)
+ : QIODevice(parent), realSize(size), start(start)
+ {}
+
+ qint64 size() const override { return realSize; }
+ bool isSequential() const override { return false; }
+
+protected:
+ qint64 readData(char *data, qint64 maxlen) override;
+ qint64 writeData(const char *, qint64) override { return -1; }
+};
+
+qint64 LargeIODevice::readData(char *data, qint64 maxlen)
+{
+ qint64 p = pos();
+ if (maxlen > realSize - p)
+ maxlen = realSize - p;
+ memset(data, '\0', qMin(maxlen, qint64(32 * 1024)));
+
+ qint64 fromstart = start.size() - p;
+ if (fromstart > maxlen)
+ fromstart = maxlen;
+ else if (fromstart < 0)
+ fromstart = 0;
+ if (fromstart)
+ memcpy(data, start.constData() + p, fromstart);
+ return maxlen;
+}
+
+void addValidationLargeData(qsizetype minInvalid, qsizetype maxInvalid)
+{
+ char toolong[1 + sizeof(qsizetype)];
+ for (qsizetype v = maxInvalid; v >= minInvalid; --v) {
+ // 0x5a for 32-bit, 0x5b for 64-bit
+ toolong[0] = sizeof(v) > 4 ? 0x5b : 0x5a;
+ qToBigEndian(v, toolong + 1);
+
+ bool overflows = v > std::numeric_limits<qsizetype>::max() - 1 - qsizetype(sizeof(v));
+ CborError err = overflows ? CborErrorDataTooLarge : CborErrorUnexpectedEOF;
+
+ QTest::addRow("bytearray-too-big-for-qbytearray-%zx", size_t(v))
+ << QByteArray(toolong, sizeof(toolong)) << 0 << err;
+ QTest::addRow("bytearray-chunked-too-big-for-qbytearray-%zx", size_t(v))
+ << ('\x5f' + QByteArray(toolong, sizeof(toolong)) + '\xff')
+ << 0 << err;
+ QTest::addRow("bytearray-2chunked-too-big-for-qbytearray-%zx", size_t(v))
+ << ("\x5f\x40" + QByteArray(toolong, sizeof(toolong)) + '\xff')
+ << 0 << err;
+ toolong[0] |= 0x20;
+
+ // QCborStreamReader::readString copies to a QByteArray first
+ QTest::addRow("string-too-big-for-qbytearray-%zx", size_t(v))
+ << QByteArray(toolong, sizeof(toolong)) << 0 << err;
+ QTest::addRow("string-chunked-too-big-for-qbytearray-%zx", size_t(v))
+ << ('\x7f' + QByteArray(toolong, sizeof(toolong)) + '\xff')
+ << 0 << err;
+ QTest::addRow("string-2chunked-too-big-for-qbytearray-%zx", size_t(v))
+ << ("\x7f\x60" + QByteArray(toolong, sizeof(toolong)) + '\xff')
+ << 0 << err;
+ }
+}
+
+void addValidationHugeDevice(qsizetype byteArrayInvalid, qsizetype stringInvalid)
+{
+ qRegisterMetaType<QSharedPointer<QIODevice>>();
+ QTest::addColumn<QSharedPointer<QIODevice>>("device");
+ QTest::addColumn<CborError>("expectedError");
+ QTest::addColumn<CborError>("expectedValidationError");
+
+ char buf[1 + sizeof(quint64)];
+ auto device = [&buf](QCborStreamReader::Type t, quint64 size) {
+ buf[0] = quint8(t) | 0x1b;
+ qToBigEndian(size, buf + 1);
+ size += sizeof(buf);
+ QSharedPointer<QIODevice> p =
+ QSharedPointer<LargeIODevice>::create(QByteArray(buf, sizeof(buf)), size);
+ return p;
+ };
+
+ // do the exact limits
+ QTest::newRow("bytearray-just-too-big")
+ << device(QCborStreamReader::ByteArray, byteArrayInvalid)
+ << CborErrorDataTooLarge << CborNoError;
+ QTest::newRow("string-just-too-big")
+ << device(QCborStreamReader::String, stringInvalid)
+ << CborErrorDataTooLarge << CborErrorDataTooLarge;
+
+ auto addSize = [=](const char *sizename, qint64 size) {
+ if (byteArrayInvalid < size)
+ QTest::addRow("bytearray-%s", sizename)
+ << device(QCborStreamReader::ByteArray, size)
+ << CborErrorDataTooLarge << CborNoError;
+ if (stringInvalid < size)
+ QTest::addRow("string-%s", sizename)
+ << device(QCborStreamReader::String, size)
+ << CborErrorDataTooLarge << CborErrorDataTooLarge;
+ };
+ addSize("1GB", quint64(1) << 30);
+ addSize("2GB", quint64(1) << 31);
+ addSize("4GB", quint64(1) << 32);
+ addSize("max", std::numeric_limits<qint64>::max() - sizeof(buf));
+}
+} // namespace
diff --git a/tests/auto/corelib/serialization/json/CMakeLists.txt b/tests/auto/corelib/serialization/json/CMakeLists.txt
new file mode 100644
index 0000000000..c73a99a3b8
--- /dev/null
+++ b/tests/auto/corelib/serialization/json/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_json Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_json LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+set(json_resource_files
+ "bom.json"
+ "test.json"
+ "test2.json"
+ "test3.json"
+ "simple.duplicates.json"
+ "test.duplicates.json"
+ "test3.duplicates.json"
+)
+
+qt_internal_add_test(tst_json
+ SOURCES
+ tst_qtjson.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+ TESTDATA ${json_resource_files}
+)
+
+qt_internal_extend_target(tst_json CONDITION NOT QT_FEATURE_doubleconversion AND NOT QT_FEATURE_system_doubleconversion
+ DEFINES
+ QT_NO_DOUBLECONVERSION
+)
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/10.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/10.bjson
deleted file mode 100644
index 12b29b7aa5..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/10.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/11.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/11.bjson
deleted file mode 100644
index cf2b612111..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/11.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/12.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/12.bjson
deleted file mode 100644
index 9c2403350e..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/12.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/13.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/13.bjson
deleted file mode 100644
index db6308b1fd..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/13.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/14.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/14.bjson
deleted file mode 100644
index 347da4572c..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/14.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/15.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/15.bjson
deleted file mode 100644
index c6c5558934..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/15.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/16.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/16.bjson
deleted file mode 100644
index ae8b57446d..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/16.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/17.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/17.bjson
deleted file mode 100644
index 32f0cc0e23..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/17.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/18.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/18.bjson
deleted file mode 100644
index 50c89169eb..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/18.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/19.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/19.bjson
deleted file mode 100644
index b922212f45..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/19.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/20.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/20.bjson
deleted file mode 100644
index c965a0d294..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/20.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/21.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/21.bjson
deleted file mode 100644
index 98165ee40c..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/21.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/22.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/22.bjson
deleted file mode 100644
index 151f773a81..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/22.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/23.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/23.bjson
deleted file mode 100644
index 6eb5269470..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/23.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/24.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/24.bjson
deleted file mode 100644
index c55a2a3e3b..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/24.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/25.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/25.bjson
deleted file mode 100644
index 6c619f2ae1..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/25.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/26.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/26.bjson
deleted file mode 100644
index 3bf303215a..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/26.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/27.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/27.bjson
deleted file mode 100644
index d2656c2287..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/27.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/28.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/28.bjson
deleted file mode 100644
index 6797cf8c40..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/28.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/29.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/29.bjson
deleted file mode 100644
index 0645dfc3b2..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/29.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/30.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/30.bjson
deleted file mode 100644
index f77fe1efd0..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/30.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/31.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/31.bjson
deleted file mode 100644
index d9840b6582..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/31.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/32.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/32.bjson
deleted file mode 100644
index 1de4cb829f..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/32.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/33.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/33.bjson
deleted file mode 100644
index 532a31dc08..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/33.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/34.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/34.bjson
deleted file mode 100644
index f498558eff..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/34.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/35.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/35.bjson
deleted file mode 100644
index 8701210755..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/35.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/36.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/36.bjson
deleted file mode 100644
index ef5864e911..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/36.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/37.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/37.bjson
deleted file mode 100644
index f4dd4ae12f..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/37.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/39.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/39.bjson
deleted file mode 100644
index c6025aa9eb..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/39.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/40.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/40.bjson
deleted file mode 100644
index 277096f8cb..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/40.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/41.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/41.bjson
deleted file mode 100644
index 0b5940ab95..0000000000
--- a/tests/auto/corelib/serialization/json/invalidBinaryData/41.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/json.pro b/tests/auto/corelib/serialization/json/json.pro
deleted file mode 100644
index 8fa17c5c38..0000000000
--- a/tests/auto/corelib/serialization/json/json.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TARGET = tst_json
-QT = core-private testlib
-CONFIG += testcase
-
-!android:TESTDATA += bom.json test.json test.bjson test3.json test2.json
- else:RESOURCES += json.qrc
-
-!qtConfig(doubleconversion):!qtConfig(system-doubleconversion) {
- DEFINES += QT_NO_DOUBLECONVERSION
-}
-
-SOURCES += tst_qtjson.cpp
diff --git a/tests/auto/corelib/serialization/json/json.qrc b/tests/auto/corelib/serialization/json/json.qrc
deleted file mode 100644
index eb122a1779..0000000000
--- a/tests/auto/corelib/serialization/json/json.qrc
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/">
- <file>bom.json</file>
- <file>test2.json</file>
- <file>test3.json</file>
- <file>test.json</file>
- <file>test.bjson</file>
-</qresource>
-</RCC>
diff --git a/tests/auto/corelib/serialization/json/simple.duplicates.json b/tests/auto/corelib/serialization/json/simple.duplicates.json
new file mode 100644
index 0000000000..6f989e8aa9
--- /dev/null
+++ b/tests/auto/corelib/serialization/json/simple.duplicates.json
@@ -0,0 +1 @@
+{"":{"":0},"":0}
diff --git a/tests/auto/corelib/serialization/json/test.bjson b/tests/auto/corelib/serialization/json/test.bjson
deleted file mode 100644
index 137b4dfeff..0000000000
--- a/tests/auto/corelib/serialization/json/test.bjson
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/json/test.duplicates.json b/tests/auto/corelib/serialization/json/test.duplicates.json
new file mode 100644
index 0000000000..0d5af8ef74
--- /dev/null
+++ b/tests/auto/corelib/serialization/json/test.duplicates.json
@@ -0,0 +1,66 @@
+[
+ "JSON Test Pattern pass1",
+ {"a":["array with 1 element"]},
+ {},
+ [],
+ -42,
+ true,
+ false,
+ null,
+ {
+ "a": 1234567890,
+ "a": -9876.543210,
+ "a": 0.123456789e-12,
+ "a": 1.234567890E+34,
+ "a": 23456789012E66,
+ "a": 0,
+ "a": 1,
+ "a": " ",
+ "a": "\"",
+ "a": "\\",
+ "a": "\b\f\n\r\t",
+ "a": "/ & \/",
+ "a": "abcdefghijklmnopqrstuvwxyz",
+ "a": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "a": "0123456789",
+ "a": "digit",
+ "a": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+ "a": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+ "a": true,
+ "a": false,
+ "a": null,
+ "a":[ ],
+ "a":{ },
+ "a": "50 St. James Street",
+ "a": "nix",
+ "a": "// /* <!-- --",
+ "a": " ",
+ "a":[1,2 , 3
+
+,
+
+4 , 5 , 6 ,7 ],"a":[1,2,3,4,5,6,7],
+ "a": "\"a:[\"array with 1 element\"]}",
+ "a": "&#34; \u0022 %22 0x22 034 &#x22;",
+ "a": "A key can be any string"
+ },
+ 0.5 ,98.6
+,
+99.44
+,
+
+1066,
+1e1,
+0.1e1,
+1e-1,
+1e00,
+2e+00,
+2e-00,
+"rosebud",
+{"a": "bar"},
+{"a":{"a":1000,"a":{"a":"nix"}},"a":{"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$4,833.99","a":483399}},"a":[{"a":"PRODUCT","a":"Silicone c","a":"Elite Hori","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":310711221747712.000000,"a":{"a":{"a":"$1.56","a":156},"a":{"a":"$29.99","a":2999},"a":14},"a":1968262863,"a":8515},{"a":"PRODUCT","a":"Nonslip Ch","a":"Specificat","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":175580930637824.000000,"a":{"a":{"a":"$0.45","a":45},"a":{"a":"$194.95","a":19495},"a":34},"a":2534935499,"a":8515},{"a":"PRODUCT","a":"Plastic Ca","a":"Descriptio","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":132488642953216.000000,"a":{"a":{"a":"$0.99","a":99},"a":{"a":"$303.68","a":30368},"a":33},"a":2305624670,"a":8515},{"a":"PRODUCT","a":"Protective","a":"Made of hi","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":108614681362432.000000,"a":{"a":{"a":"$1.70","a":170},"a":{"a":"$99.99","a":9999},"a":11},"a":2120981405,"a":8515},{"a":"PRODUCT","a":"P® 4","a":"Do more th","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":96203484168192.000000,"a":{"a":{"a":"$2.49","a":249},"a":{"a":"$79.95","a":7995},"a":16},"a":2203798762,"a":8515},{"a":"PRODUCT","a":"Case Refle","a":"NCAA iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":84727583211520.000000,"a":{"a":{"a":"$0.69","a":69},"a":{"a":"$75.52","a":7552},"a":59},"a":1114627445,"a":8515},{"a":"PRODUCT","a":"Infuse Pro","a":"Protect an","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":80831066406912.000000,"a":{"a":{"a":"$0.59","a":59},"a":{"a":"$79.00","a":7900},"a":24},"a":2557462717,"a":8515},{"a":"PRODUCT","a":"Dragonfly ","a":"d","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":70900229603328.000000,"a":{"a":{"a":"$1.05","a":105},"a":{"a":"$94.49","a":9449},"a":30},"a":2442061740,"a":8515},{"a":"PRODUCT","a":"Pho","a":"Snap on Ap","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":65194915004416.000000,"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$414.99","a":41499},"a":39},"a":2004746863,"a":8515},{"a":"PRODUCT","a":"Otterbox i","a":"Your iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":61515478597632.000000,"a":{"a":{"a":"$3.28","a":328},"a":{"a":"$110.65","a":11065},"a":25},"a":2584611575,"a":8515}],"a":10,"a":2000}},
+{"a":{"a":1000,"a":{"a":"nix"}},"a":{"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$4,833.99","a":483399}},"a":[{"a":"PRODUCT","a":"Silicone c","a":"Elite Hori","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":310711221747712.000000,"a":{"a":{"a":"$1.56","a":156},"a":{"a":"$29.99","a":2999},"a":14},"a":1968262863,"a":8515},{"a":"PRODUCT","a":"Nonslip Ch","a":"Specificat","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":175580930637824.000000,"a":{"a":{"a":"$0.45","a":45},"a":{"a":"$194.95","a":19495},"a":34},"a":2534935499,"a":8515},{"a":"PRODUCT","a":"Plastic Ca","a":"Descriptio","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":132488642953216.000000,"a":{"a":{"a":"$0.99","a":99},"a":{"a":"$303.68","a":30368},"a":33},"a":2305624670,"a":8515},{"a":"PRODUCT","a":"Protective","a":"Made of hi","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":108614681362432.000000,"a":{"a":{"a":"$1.70","a":170},"a":{"a":"$99.99","a":9999},"a":11},"a":2120981405,"a":8515},{"a":"PRODUCT","a":"P® 4","a":"Do more th","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":96203484168192.000000,"a":{"a":{"a":"$2.49","a":249},"a":{"a":"$79.95","a":7995},"a":16},"a":2203798762,"a":8515},{"a":"PRODUCT","a":"Case Refle","a":"NCAA iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":84727583211520.000000,"a":{"a":{"a":"$0.69","a":69},"a":{"a":"$75.52","a":7552},"a":59},"a":1114627445,"a":8515},{"a":"PRODUCT","a":"Infuse Pro","a":"Protect an","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":80831066406912.000000,"a":{"a":{"a":"$0.59","a":59},"a":{"a":"$79.00","a":7900},"a":24},"a":2557462717,"a":8515},{"a":"PRODUCT","a":"Dragonfly ","a":"d","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":70900229603328.000000,"a":{"a":{"a":"$1.05","a":105},"a":{"a":"$94.49","a":9449},"a":30},"a":2442061740,"a":8515},{"a":"PRODUCT","a":"Pho","a":"Snap on Ap","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":65194915004416.000000,"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$414.99","a":41499},"a":39},"a":2004746863,"a":8515},{"a":"PRODUCT","a":"Otterbox i","a":"Your iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":61515478597632.000000,"a":{"a":{"a":"$3.28","a":328},"a":{"a":"$110.65","a":11065},"a":25},"a":2584611575,"a":8515}],"a":10,"a":2000}},
+{"a":{"a":1000,"a":{"a":"nix"}},"a":{"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$4,833.99","a":483399}},"a":[{"a":"PRODUCT","a":"Silicone c","a":"Elite Hori","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":310711221747712.000000,"a":{"a":{"a":"$1.56","a":156},"a":{"a":"$29.99","a":2999},"a":14},"a":1968262863,"a":8515},{"a":"PRODUCT","a":"Nonslip Ch","a":"Specificat","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":175580930637824.000000,"a":{"a":{"a":"$0.45","a":45},"a":{"a":"$194.95","a":19495},"a":34},"a":2534935499,"a":8515},{"a":"PRODUCT","a":"Plastic Ca","a":"Descriptio","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":132488642953216.000000,"a":{"a":{"a":"$0.99","a":99},"a":{"a":"$303.68","a":30368},"a":33},"a":2305624670,"a":8515},{"a":"PRODUCT","a":"Protective","a":"Made of hi","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":108614681362432.000000,"a":{"a":{"a":"$1.70","a":170},"a":{"a":"$99.99","a":9999},"a":11},"a":2120981405,"a":8515},{"a":"PRODUCT","a":"P® 4","a":"Do more th","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":96203484168192.000000,"a":{"a":{"a":"$2.49","a":249},"a":{"a":"$79.95","a":7995},"a":16},"a":2203798762,"a":8515},{"a":"PRODUCT","a":"Case Refle","a":"NCAA iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":84727583211520.000000,"a":{"a":{"a":"$0.69","a":69},"a":{"a":"$75.52","a":7552},"a":59},"a":1114627445,"a":8515},{"a":"PRODUCT","a":"Infuse Pro","a":"Protect an","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":80831066406912.000000,"a":{"a":{"a":"$0.59","a":59},"a":{"a":"$79.00","a":7900},"a":24},"a":2557462717,"a":8515},{"a":"PRODUCT","a":"Dragonfly ","a":"d","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":70900229603328.000000,"a":{"a":{"a":"$1.05","a":105},"a":{"a":"$94.49","a":9449},"a":30},"a":2442061740,"a":8515},{"a":"PRODUCT","a":"Pho","a":"Snap on Ap","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":65194915004416.000000,"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$414.99","a":41499},"a":39},"a":2004746863,"a":8515},{"a":"PRODUCT","a":"Otterbox i","a":"Your iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":61515478597632.000000,"a":{"a":{"a":"$3.28","a":328},"a":{"a":"$110.65","a":11065},"a":25},"a":2584611575,"a":8515}],"a":10,"a":2000}},
+{"a":{"a":1000,"a":{"a":"nix"}},"a":{"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$4,833.99","a":483399}},"a":[{"a":"PRODUCT","a":"Silicone c","a":"Elite Hori","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":310711221747712.000000,"a":{"a":{"a":"$1.56","a":156},"a":{"a":"$29.99","a":2999},"a":14},"a":1968262863,"a":8515},{"a":"PRODUCT","a":"Nonslip Ch","a":"Specificat","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":175580930637824.000000,"a":{"a":{"a":"$0.45","a":45},"a":{"a":"$194.95","a":19495},"a":34},"a":2534935499,"a":8515},{"a":"PRODUCT","a":"Plastic Ca","a":"Descriptio","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":132488642953216.000000,"a":{"a":{"a":"$0.99","a":99},"a":{"a":"$303.68","a":30368},"a":33},"a":2305624670,"a":8515},{"a":"PRODUCT","a":"Protective","a":"Made of hi","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":108614681362432.000000,"a":{"a":{"a":"$1.70","a":170},"a":{"a":"$99.99","a":9999},"a":11},"a":2120981405,"a":8515},{"a":"PRODUCT","a":"P® 4","a":"Do more th","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":96203484168192.000000,"a":{"a":{"a":"$2.49","a":249},"a":{"a":"$79.95","a":7995},"a":16},"a":2203798762,"a":8515},{"a":"PRODUCT","a":"Case Refle","a":"NCAA iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":84727583211520.000000,"a":{"a":{"a":"$0.69","a":69},"a":{"a":"$75.52","a":7552},"a":59},"a":1114627445,"a":8515},{"a":"PRODUCT","a":"Infuse Pro","a":"Protect an","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":80831066406912.000000,"a":{"a":{"a":"$0.59","a":59},"a":{"a":"$79.00","a":7900},"a":24},"a":2557462717,"a":8515},{"a":"PRODUCT","a":"Dragonfly ","a":"d","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":70900229603328.000000,"a":{"a":{"a":"$1.05","a":105},"a":{"a":"$94.49","a":9449},"a":30},"a":2442061740,"a":8515},{"a":"PRODUCT","a":"Pho","a":"Snap on Ap","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":65194915004416.000000,"a":{"a":{"a":"$0.01","a":1},"a":{"a":"$414.99","a":41499},"a":39},"a":2004746863,"a":8515},{"a":"PRODUCT","a":"Otterbox i","a":"Your iPhon","a":"someone","a":{"a":"nix"},"a":{"a":[{"a":"nix","a":60,"a":60},{"a":"nix","a":100,"a":100},{"a":"nix","a":160,"a":160},{"a":"nix","a":400,"a":400}]},"a":61515478597632.000000,"a":{"a":{"a":"$3.28","a":328},"a":{"a":"$110.65","a":11065},"a":25},"a":2584611575,"a":8515}],"a":10,"a":2000}}
+]
+
diff --git a/tests/auto/corelib/serialization/json/test3.duplicates.json b/tests/auto/corelib/serialization/json/test3.duplicates.json
new file mode 100644
index 0000000000..c635a2523f
--- /dev/null
+++ b/tests/auto/corelib/serialization/json/test3.duplicates.json
@@ -0,0 +1,15 @@
+{
+ "a": "John",
+ "a": "Smith",
+ "a": 25,
+ "a": {
+ "a": "21 2nd Street",
+ "a": "New York",
+ "a": "NY",
+ "a": "10021"
+ },
+ "a": [
+ { "a": "home", "a": "212 555-1234" },
+ { "a": "fax", "a": "646 555-4567" }
+ ]
+}
diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
index 4651258ef3..54ef9be4f2 100644
--- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
@@ -1,38 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QMap>
+#include <QVariantList>
+
+QT_WARNING_DISABLE_DEPRECATED
#include "qjsonarray.h"
#include "qjsonobject.h"
#include "qjsonvalue.h"
#include "qjsondocument.h"
#include "qregularexpression.h"
+#include "private/qnumeric_p.h"
#include <limits>
#define INVALID_UNICODE "\xCE\xBA\xE1"
@@ -46,24 +28,33 @@ class tst_QtJson: public QObject
private Q_SLOTS:
void initTestCase();
+ void compareCompiles();
void testValueSimple();
void testNumbers();
void testNumbers_2();
void testNumbers_3();
void testNumbers_4();
+ void testNumberComparisons();
+
void testObjectSimple();
+ void testObjectTakeDetach();
void testObjectSmallKeys();
+ void testObjectInsertCopies();
void testArraySimple();
+ void testArrayInsertCopies();
void testValueObject();
void testValueArray();
void testObjectNested();
void testArrayNested();
void testArrayNestedEmpty();
void testArrayComfortOperators();
+ void testArrayEquality_data();
+ void testArrayEquality();
void testObjectNestedEmpty();
void testValueRef();
+ void testValueRefComparison();
void testObjectIteration();
void testArrayIteration();
@@ -76,6 +67,7 @@ private Q_SLOTS:
void nullObject();
void constNullObject();
+ void keySorting_data();
void keySorting();
void undefinedValues();
@@ -95,30 +87,24 @@ private Q_SLOTS:
void toJson();
void toJsonSillyNumericValues();
void toJsonLargeNumericValues();
+ void toJsonDenormalValues();
void fromJson();
void fromJsonErrors();
- void fromBinary();
- void toAndFromBinary_data();
- void toAndFromBinary();
- void invalidBinaryData();
void parseNumbers();
void parseStrings();
void parseDuplicateKeys();
void testParser();
- void compactArray();
- void compactObject();
-
- void validation();
-
void assignToDocument();
void testDuplicateKeys();
void testCompaction();
void testDebugStream();
- void testCompactionError();
- void parseUnicodeEscapes();
+ void parseEscapes_data();
+ void parseEscapes();
+ void makeEscapes_data();
+ void makeEscapes();
void assignObjects();
void assignArrays();
@@ -132,6 +118,8 @@ private Q_SLOTS:
void objectEquals();
void arrayEquals_data();
void arrayEquals();
+ void documentEquals_data();
+ void documentEquals();
void bom();
void nesting();
@@ -153,6 +141,27 @@ private Q_SLOTS:
void implicitValueType();
void implicitDocumentType();
+ void streamSerializationQJsonDocument_data();
+ void streamSerializationQJsonDocument();
+ void streamSerializationQJsonArray_data();
+ void streamSerializationQJsonArray();
+ void streamSerializationQJsonObject_data();
+ void streamSerializationQJsonObject();
+ void streamSerializationQJsonValue_data();
+ void streamSerializationQJsonValue();
+ void streamSerializationQJsonValueEmpty();
+ void streamVariantSerialization();
+ void escapeSurrogateCodePoints_data();
+ void escapeSurrogateCodePoints();
+
+ void fromToVariantConversions_data();
+ void fromToVariantConversions();
+
+ void testIteratorComparison();
+
+ void noLeakOnNameClash_data();
+ void noLeakOnNameClash();
+
private:
QString testDataDir;
};
@@ -164,6 +173,31 @@ void tst_QtJson::initTestCase()
testDataDir = QCoreApplication::applicationDirPath();
}
+void tst_QtJson::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QJsonArray>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QJsonArray::iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QJsonArray::const_iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QJsonArray::iterator,
+ QJsonArray::const_iterator>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonDocument>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject::iterator>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject::const_iterator>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValueConstRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValueRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValue>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValueConstRef>();
+ QTestPrivate::testEqualityOperatorsCompile<QJsonObject::iterator,
+ QJsonObject::const_iterator>();
+}
+
void tst_QtJson::testValueSimple()
{
QJsonObject object;
@@ -206,26 +240,32 @@ void tst_QtJson::testNumbers()
{
int numbers[] = {
0,
- -1,
1,
+ 2,
+ -1,
+ -2,
+ (1<<25),
(1<<26),
(1<<27),
(1<<28),
+ -(1<<25),
-(1<<26),
-(1<<27),
-(1<<28),
(1<<26) - 1,
(1<<27) - 1,
(1<<28) - 1,
+ (1<<29) - 1,
-((1<<26) - 1),
-((1<<27) - 1),
- -((1<<28) - 1)
+ -((1<<28) - 1),
+ -((1<<29) - 1)
};
int n = sizeof(numbers)/sizeof(int);
QJsonArray array;
for (int i = 0; i < n; ++i)
- array.append((double)numbers[i]);
+ array.append(numbers[i]);
QByteArray serialized = QJsonDocument(array).toJson();
QJsonDocument json = QJsonDocument::fromJson(serialized);
@@ -234,8 +274,10 @@ void tst_QtJson::testNumbers()
QCOMPARE(array.size(), array2.size());
for (int i = 0; i < array.size(); ++i) {
QCOMPARE(array.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array.at(i).toInt(), numbers[i]);
QCOMPARE(array.at(i).toDouble(), (double)numbers[i]);
QCOMPARE(array2.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array2.at(i).toInt(), numbers[i]);
QCOMPARE(array2.at(i).toDouble(), (double)numbers[i]);
}
}
@@ -243,8 +285,10 @@ void tst_QtJson::testNumbers()
{
qint64 numbers[] = {
0,
- -1,
1,
+ 2,
+ -1,
+ -2,
(1ll<<54),
(1ll<<55),
(1ll<<56),
@@ -254,15 +298,21 @@ void tst_QtJson::testNumbers()
(1ll<<54) - 1,
(1ll<<55) - 1,
(1ll<<56) - 1,
+ (1ll<<57) - 1,
+ (1ll<<58) - 1,
+ (1ll<<59) + 1001,
-((1ll<<54) - 1),
-((1ll<<55) - 1),
- -((1ll<<56) - 1)
+ -((1ll<<56) - 1),
+ -((1ll<<57) - 1),
+ -((1ll<<58) - 1),
+ -((1ll<<59) + 1001),
};
int n = sizeof(numbers)/sizeof(qint64);
QJsonArray array;
for (int i = 0; i < n; ++i)
- array.append((double)numbers[i]);
+ array.append(QJsonValue(numbers[i]));
QByteArray serialized = QJsonDocument(array).toJson();
QJsonDocument json = QJsonDocument::fromJson(serialized);
@@ -271,8 +321,10 @@ void tst_QtJson::testNumbers()
QCOMPARE(array.size(), array2.size());
for (int i = 0; i < array.size(); ++i) {
QCOMPARE(array.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array.at(i).toInteger(), numbers[i]);
QCOMPARE(array.at(i).toDouble(), (double)numbers[i]);
QCOMPARE(array2.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array2.at(i).toInteger(), numbers[i]);
QCOMPARE(array2.at(i).toDouble(), (double)numbers[i]);
}
}
@@ -345,24 +397,24 @@ void tst_QtJson::testNumbers_2()
QJsonDocument jDocument2(QJsonDocument::fromJson(ba));
for (int power = 0; power <= 1075; power++) {
floatValues_1[power] = jDocument2.object().value(QString::number(power)).toDouble();
-#ifdef Q_OS_QNX
- if (power >= 970)
- QEXPECT_FAIL("", "See QTBUG-37066", Abort);
-#endif
QVERIFY2(floatValues[power] == floatValues_1[power], QString("floatValues[%1] != floatValues_1[%1]").arg(power).toLatin1());
}
+ QT_TEST_EQUALITY_OPS(jDocument1, jDocument2, true);
// The last value is below min denorm and should round to 0, everything else should contain a value
QVERIFY2(floatValues_1[1075] == 0, "Value after min denorm should round to 0");
// Validate the last actual value is min denorm
QVERIFY2(floatValues_1[1074] == 4.9406564584124654417656879286822e-324, QString("Min denorm value is incorrect: %1").arg(floatValues_1[1074]).toLatin1());
- // Validate that every value is half the value before it up to 1
- for (int index = 1074; index > 0; index--) {
- QVERIFY2(floatValues_1[index] != 0, QString("2**- %1 should not be 0").arg(index).toLatin1());
-
- QVERIFY2(floatValues_1[index - 1] == (floatValues_1[index] * 2), QString("Value should be double adjacent value at index %1").arg(index).toLatin1());
+ if constexpr (std::numeric_limits<double>::has_denorm == std::denorm_present) {
+ // Validate that every value is half the value before it up to 1
+ for (int index = 1074; index > 0; index--) {
+ QVERIFY2(floatValues_1[index] != 0, QString("2**- %1 should not be 0").arg(index).toLatin1());
+ QVERIFY2(floatValues_1[index - 1] == (floatValues_1[index] * 2), QString("Value should be double adjacent value at index %1").arg(index).toLatin1());
+ }
+ } else {
+ qInfo("Skipping denormal test as this system's double type lacks support");
}
}
@@ -380,6 +432,10 @@ void tst_QtJson::testNumbers_3()
QJsonDocument jDocument2(QJsonDocument::fromJson(ba));
+ QT_TEST_EQUALITY_OPS(jDocument1, jDocument2, true);
+ QT_TEST_EQUALITY_OPS(jDocument1, QJsonDocument(), false);
+ QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(), true);
+
double d1_1(jDocument2.object().value("d1").toDouble());
double d2_1(jDocument2.object().value("d2").toDouble());
QVERIFY(d1_1 != d2_1);
@@ -397,7 +453,8 @@ void tst_QtJson::testNumbers_4()
array << QJsonValue(-9223372036854775808.0);
array << QJsonValue(+18446744073709551616.0);
array << QJsonValue(-18446744073709551616.0);
- const QByteArray json(QJsonDocument(array).toJson());
+ QJsonDocument doc1 = QJsonDocument(array);
+ const QByteArray json(doc1.toJson());
const QByteArray expected =
"[\n"
" 1000000000000000,\n"
@@ -410,6 +467,49 @@ void tst_QtJson::testNumbers_4()
" -18446744073709552000\n"
"]\n";
QCOMPARE(json, expected);
+
+ QJsonArray array2;
+ array2 << QJsonValue(Q_INT64_C(+1000000000000000));
+ array2 << QJsonValue(Q_INT64_C(-1000000000000000));
+ array2 << QJsonValue(Q_INT64_C(+9007199254740992));
+ array2 << QJsonValue(Q_INT64_C(-9007199254740992));
+ array2 << QJsonValue(Q_INT64_C(+9223372036854775807));
+ array2 << QJsonValue(Q_INT64_C(-9223372036854775807));
+ QJsonDocument doc2 = QJsonDocument(array2);
+ const QByteArray json2(doc2.toJson());
+ const QByteArray expected2 =
+ "[\n"
+ " 1000000000000000,\n"
+ " -1000000000000000,\n"
+ " 9007199254740992,\n"
+ " -9007199254740992,\n"
+ " 9223372036854775807,\n"
+ " -9223372036854775807\n"
+ "]\n";
+ QCOMPARE(json2, expected2);
+
+ QT_TEST_EQUALITY_OPS(doc1, doc2, false);
+}
+
+void tst_QtJson::testNumberComparisons()
+{
+ // QJsonValues created using doubles only have double precision
+ QJsonValue llMinDbl(-9223372036854775807.0);
+ QJsonValue llMinPlus1Dbl(-9223372036854775806.0);
+ QCOMPARE(llMinDbl == llMinPlus1Dbl, -9223372036854775807.0 == -9223372036854775806.0); // true
+
+ // QJsonValues created using qint64 have full qint64 precision
+ QJsonValue llMin(Q_INT64_C(-9223372036854775807));
+ QJsonValue llMinPlus1(Q_INT64_C(-9223372036854775806));
+ QCOMPARE(llMin == llMinPlus1, Q_INT64_C(-9223372036854775807) == Q_INT64_C(-9223372036854775806)); // false
+
+ // The different storage formats should be able to compare as their C++ versions (all true)
+ QCOMPARE(llMin == llMinDbl, Q_INT64_C(-9223372036854775807) == -9223372036854775807.0);
+ QCOMPARE(llMinDbl == llMin, -9223372036854775807.0 == Q_INT64_C(-9223372036854775807));
+ QCOMPARE(llMinPlus1 == llMinPlus1Dbl, Q_INT64_C(-9223372036854775806) == -9223372036854775806.0);
+ QCOMPARE(llMinPlus1Dbl == llMinPlus1, -9223372036854775806.0 == Q_INT64_C(-9223372036854775806));
+ QCOMPARE(llMinPlus1 == llMinDbl, Q_INT64_C(-9223372036854775806) == -9223372036854775807.0);
+ QCOMPARE(llMinPlus1Dbl == llMin, -9223372036854775806.0 == Q_INT64_C(-9223372036854775807));
}
void tst_QtJson::testObjectSimple()
@@ -424,6 +524,8 @@ void tst_QtJson::testObjectSimple()
object.insert("boolean", true);
QCOMPARE(object.value("boolean").toBool(), true);
QCOMPARE(object.value(QLatin1String("boolean")).toBool(), true);
+ QJsonObject object2 = object;
+ QJsonObject object3 = object;
QStringList keys = object.keys();
QVERIFY2(keys.contains("number"), "key number not found");
@@ -435,6 +537,7 @@ void tst_QtJson::testObjectSimple()
QJsonValue value(QLatin1String("foo"));
object.insert("value", value);
QCOMPARE(object.value("value"), value);
+ QT_TEST_EQUALITY_OPS(object.value("value"), value, true);
int size = object.size();
object.remove("boolean");
@@ -443,12 +546,47 @@ void tst_QtJson::testObjectSimple()
QJsonValue taken = object.take("value");
QCOMPARE(taken, value);
+ QT_TEST_EQUALITY_OPS(taken, value, true);
QVERIFY2(!object.contains("value"), "key value should have been removed");
QString before = object.value("string").toString();
object.insert("string", QString::fromLatin1("foo"));
QVERIFY2(object.value(QLatin1String("string")).toString() != before, "value should have been updated");
+ // same tests again but with QStringView keys
+ object2.insert(QStringView(u"value"), value);
+ QCOMPARE(object2.value("value"), value);
+
+ size = object2.size();
+ object2.remove(QStringView(u"boolean"));
+ QCOMPARE(object2.size(), size - 1);
+ QVERIFY2(!object2.contains(QStringView(u"boolean")), "key boolean should have been removed");
+
+ taken = object2.take(QStringView(u"value"));
+ QCOMPARE(taken, value);
+ QVERIFY2(!object2.contains("value"), "key value should have been removed");
+
+ before = object2.value("string").toString();
+ object2.insert(QStringView(u"string"), QString::fromLatin1("foo"));
+ QVERIFY2(object2.value(QStringView(u"string")).toString() != before, "value should have been updated");
+
+ // same tests again but with QLatin1String keys
+ object3.insert(QLatin1String("value"), value);
+ QCOMPARE(object3.value("value"), value);
+
+ size = object3.size();
+ object3.remove(QLatin1String("boolean"));
+ QCOMPARE(object3.size(), size - 1);
+ QVERIFY2(!object3.contains("boolean"), "key boolean should have been removed");
+
+ taken = object3.take(QLatin1String("value"));
+ QCOMPARE(taken, value);
+ QVERIFY2(!object3.contains("value"), "key value should have been removed");
+
+ before = object3.value("string").toString();
+ object3.insert(QLatin1String("string"), QString::fromLatin1("foo"));
+ QVERIFY2(object3.value(QLatin1String("string")).toString() != before, "value should have been updated");
+
size = object.size();
QJsonObject subobject;
subobject.insert("number", 42);
@@ -465,6 +603,24 @@ void tst_QtJson::testObjectSimple()
QCOMPARE(subvalue.toObject(), subobject);
}
+void tst_QtJson::testObjectTakeDetach()
+{
+ QJsonObject object1, object2;
+ object1["key1"] = 1;
+ object1["key2"] = 2;
+ object2 = object1;
+
+ object1.take("key2");
+ object1.remove("key1");
+ QVERIFY(!object1.contains("key1"));
+ QVERIFY(object2.contains("key1"));
+ QVERIFY(object2.value("key1").isDouble());
+
+ QVERIFY(!object1.contains("key2"));
+ QVERIFY(object2.contains("key2"));
+ QVERIFY(object2.value("key2").isDouble());
+}
+
void tst_QtJson::testObjectSmallKeys()
{
QJsonObject data1;
@@ -479,6 +635,78 @@ void tst_QtJson::testObjectSmallKeys()
QVERIFY(data1.contains(QStringLiteral("123")));
QCOMPARE(data1.value(QStringLiteral("123")).type(), QJsonValue::Double);
QCOMPARE(data1.value(QStringLiteral("123")).toDouble(), (double)323);
+ QCOMPARE(data1.constEnd() - data1.constBegin(), 3);
+ QCOMPARE(data1.end() - data1.begin(), 3);
+}
+
+void tst_QtJson::testObjectInsertCopies()
+{
+ {
+ QJsonObject obj;
+ obj["prop1"] = "TEST";
+ QCOMPARE(obj.size(), 1);
+ QCOMPARE(obj.value("prop1"), "TEST");
+
+ obj["prop2"] = obj.value("prop1");
+ QCOMPARE(obj.size(), 2);
+ QCOMPARE(obj.value("prop1"), "TEST");
+ QCOMPARE(obj.value("prop2"), "TEST");
+ }
+ {
+ // see QTBUG-83366
+ QJsonObject obj;
+ obj["value"] = "TEST";
+ QCOMPARE(obj.size(), 1);
+ QCOMPARE(obj.value("value"), "TEST");
+
+ obj["prop2"] = obj.value("value");
+ QCOMPARE(obj.size(), 2);
+ QCOMPARE(obj.value("value"), "TEST");
+ QCOMPARE(obj.value("prop2"), "TEST");
+ }
+ {
+ QJsonObject obj;
+ obj["value"] = "TEST";
+ QCOMPARE(obj.size(), 1);
+ QCOMPARE(obj.value("value"), "TEST");
+
+ // same as previous, but this is a QJsonValueRef
+ QJsonValueRef rv = obj["prop2"];
+ rv = obj["value"];
+ QCOMPARE(obj.size(), 2);
+ QCOMPARE(obj.value("value"), "TEST");
+ QCOMPARE(obj.value("prop2"), "TEST");
+ QT_TEST_EQUALITY_OPS(rv, obj["value"].toObject(), true);
+ }
+ {
+ QJsonObject obj;
+ obj["value"] = "TEST";
+ QCOMPARE(obj.size(), 1);
+ QCOMPARE(obj.value("value"), "TEST");
+
+ // same as previous, but this is a QJsonValueRef
+ QJsonValueRef rv = obj["value"];
+ obj["prop2"] = rv;
+ QCOMPARE(obj.size(), 2);
+ QCOMPARE(obj.value("value"), "TEST");
+ QEXPECT_FAIL("", "QTBUG-83398: design flaw: the obj[] call invalidates the QJsonValueRef", Continue);
+ QCOMPARE(obj.value("prop2"), "TEST");
+ }
+ {
+ QJsonObject obj;
+ obj["value"] = "TEST";
+ QCOMPARE(obj.size(), 1);
+ QCOMPARE(obj.value("value"), "TEST");
+
+ QJsonValueRef v = obj["value"];
+ QJsonObject obj2 = obj;
+ obj.insert("prop2", v);
+ QCOMPARE(obj.size(), 2);
+ QCOMPARE(obj.value("value"), "TEST");
+ QCOMPARE(obj.value("prop2"), "TEST");
+ QCOMPARE(obj2.size(), 1);
+ QCOMPARE(obj2.value("value"), "TEST");
+ }
}
void tst_QtJson::testArraySimple()
@@ -534,6 +762,32 @@ void tst_QtJson::testArraySimple()
QCOMPARE(array.at(1), QJsonValue(QLatin1String("test")));
}
+void tst_QtJson::testArrayInsertCopies()
+{
+ {
+ QJsonArray array;
+ array.append("TEST");
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0), "TEST");
+
+ array.append(array.at(0));
+ QCOMPARE(array.size(), 2);
+ QCOMPARE(array.at(0), "TEST");
+ QCOMPARE(array.at(1), "TEST");
+ }
+ {
+ QJsonArray array;
+ array.append("TEST");
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0), "TEST");
+
+ array.prepend(array.at(0));
+ QCOMPARE(array.size(), 2);
+ QCOMPARE(array.at(0), "TEST");
+ QCOMPARE(array.at(1), "TEST");
+ }
+}
+
void tst_QtJson::testValueObject()
{
QJsonObject object;
@@ -555,15 +809,20 @@ void tst_QtJson::testValueObject()
void tst_QtJson::testValueArray()
{
QJsonArray array;
+ QJsonArray otherArray = {"wrong value"};
+ QJsonValue value(array);
+ QCOMPARE(value.toArray(), array);
+ QCOMPARE(value.toArray(otherArray), array);
+
array.append(999.);
array.append(QLatin1String("test"));
array.append(true);
-
- QJsonValue value(array);
+ value = array;
// if we don't modify the original JsonArray, toArray()
// on the JsonValue should return the same object (non-detached).
QCOMPARE(value.toArray(), array);
+ QCOMPARE(value.toArray(otherArray), array);
// if we modify the original array, it should detach
array.append(QLatin1String("test"));
@@ -573,14 +832,28 @@ void tst_QtJson::testValueArray()
void tst_QtJson::testObjectNested()
{
QJsonObject inner, outer;
+ QJsonObject otherObject = {{"wrong key", "wrong value"}};
+ QJsonValue v = inner;
+ QCOMPARE(v.toObject(), inner);
+ QCOMPARE(v.toObject(otherObject), inner);
+ QT_TEST_EQUALITY_OPS(v.toObject(), inner, true);
+ QT_TEST_EQUALITY_OPS(v.toObject(otherObject), inner, true);
+
inner.insert("number", 999.);
outer.insert("nested", inner);
+ QT_TEST_EQUALITY_OPS(outer, inner, false);
// if we don't modify the original JsonObject, value()
// should return the same object (non-detached).
QJsonObject value = outer.value("nested").toObject();
+ v = value;
QCOMPARE(value, inner);
QCOMPARE(value.value("number").toDouble(), 999.);
+ QCOMPARE(v.toObject(), inner);
+ QCOMPARE(v.toObject(otherObject), inner);
+ QT_TEST_EQUALITY_OPS(v.toObject(), inner, true);
+ QT_TEST_EQUALITY_OPS(v.toObject(otherObject), inner, true);
+ QCOMPARE(v["number"].toDouble(), 999.);
// if we modify the original object, it should detach and not
// affect the nested object
@@ -605,6 +878,7 @@ void tst_QtJson::testObjectNested()
QCOMPARE(outer.value("nested").toObject().value("nested").toObject(), twoDeep);
QCOMPARE(outer.value("nested").toObject().value("nested").toObject().value("boolean").toBool(),
true);
+ QT_TEST_EQUALITY_OPS(outer.value("nested").toObject().value("nested").toObject(), twoDeep, true);
}
void tst_QtJson::testArrayNested()
@@ -630,6 +904,7 @@ void tst_QtJson::testArrayNested()
object.insert("boolean", true);
outer.append(object);
QCOMPARE(outer.last().toObject(), object);
+ QT_TEST_EQUALITY_OPS(outer.last().toObject(), object, true);
QCOMPARE(outer.last().toObject().value("boolean").toBool(), true);
// two deep arrays
@@ -649,14 +924,13 @@ void tst_QtJson::testArrayNestedEmpty()
QJsonValue val = object.value("inner");
QJsonArray value = object.value("inner").toArray();
QVERIFY(QJsonDocument(value).isArray());
+ QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0);
QCOMPARE(value, inner);
QCOMPARE(value.size(), 0);
object.insert("count", 0.);
QCOMPARE(object.value("inner").toArray().size(), 0);
QVERIFY(object.value("inner").toArray().isEmpty());
- QJsonDocument(object).toBinaryData();
- QCOMPARE(object.value("inner").toArray().size(), 0);
}
void tst_QtJson::testObjectNestedEmpty()
@@ -668,21 +942,44 @@ void tst_QtJson::testObjectNestedEmpty()
object.insert("inner2", inner2);
QJsonObject value = object.value("inner").toObject();
QVERIFY(QJsonDocument(value).isObject());
+ QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0);
QCOMPARE(value, inner);
+ QT_TEST_EQUALITY_OPS(value, inner, true);
QCOMPARE(value.size(), 0);
object.insert("count", 0.);
QCOMPARE(object.value("inner").toObject().size(), 0);
QCOMPARE(object.value("inner").type(), QJsonValue::Object);
- QJsonDocument(object).toBinaryData();
- QVERIFY(object.value("inner").toObject().isEmpty());
- QVERIFY(object.value("inner2").toObject().isEmpty());
- QJsonDocument doc = QJsonDocument::fromBinaryData(QJsonDocument(object).toBinaryData());
- QVERIFY(!doc.isNull());
- QJsonObject reconstituted(doc.object());
- QCOMPARE(reconstituted.value("inner").toObject().size(), 0);
- QCOMPARE(reconstituted.value("inner").type(), QJsonValue::Object);
- QCOMPARE(reconstituted.value("inner2").type(), QJsonValue::Object);
+}
+
+void tst_QtJson::testArrayEquality_data()
+{
+ QTest::addColumn<QJsonArray>("array1");
+ QTest::addColumn<QJsonArray>("array2");
+ QTest::addColumn<bool>("expectedResult");
+ QTest::addRow("QJsonArray(), QJsonArray{665, 666, 667}")
+ << QJsonArray() << QJsonArray{665, 666, 667} << false;
+ QTest::addRow("QJsonArray(), QJsonArray{}")
+ << QJsonArray() << QJsonArray{} <<true;
+ QTest::addRow("QJsonArray(), QJsonArray{123, QLatin1String(\"foo\")}")
+ << QJsonArray() << QJsonArray{123, QLatin1String("foo")} << false;
+ QTest::addRow(
+ "QJsonArray{123,QLatin1String(\"foo\")}, QJsonArray{123,QLatin1String(\"foo\")}")
+ << QJsonArray{123, QLatin1String("foo")}
+ << QJsonArray{123, QLatin1String("foo")}
+ << true;
+}
+
+void tst_QtJson::testArrayEquality()
+{
+ QFETCH(QJsonArray, array1);
+ QFETCH(QJsonArray, array2);
+ QFETCH(bool, expectedResult);
+
+ QJsonValue value = QJsonValue(array1);
+
+ QT_TEST_EQUALITY_OPS(array1, array2, expectedResult);
+ QT_TEST_EQUALITY_OPS(value, array2, expectedResult);
}
void tst_QtJson::testArrayComfortOperators()
@@ -724,7 +1021,7 @@ void tst_QtJson::testValueRef()
QCOMPARE(object.value(QLatin1String("null")), QJsonValue());
object[QLatin1String("null")] = 100.;
QCOMPARE(object.value(QLatin1String("null")).type(), QJsonValue::Double);
- QJsonValue val = qAsConst(object)[QLatin1String("null")];
+ QJsonValue val = std::as_const(object)[QLatin1String("null")];
QCOMPARE(val.toDouble(), 100.);
QCOMPARE(object.size(), 2);
@@ -734,21 +1031,79 @@ void tst_QtJson::testValueRef()
QCOMPARE(object.value(QLatin1String("key")), QJsonValue(42));
}
+void tst_QtJson::testValueRefComparison()
+{
+ QJsonValue a0 = 42.;
+ QJsonValue a1 = QStringLiteral("142");
+
+#define CHECK_IMPL(lhs, rhs, ineq) \
+ QCOMPARE(lhs, rhs); \
+ QVERIFY(!(lhs != rhs)); \
+ QVERIFY(lhs != ineq); \
+ QVERIFY(!(lhs == ineq)); \
+ QVERIFY(ineq != rhs); \
+ QVERIFY(!(ineq == rhs)); \
+ /* end */
+
+#define CHECK(lhs, rhs, ineq) \
+ do { \
+ CHECK_IMPL(lhs, rhs, ineq) \
+ CHECK_IMPL(std::as_const(lhs), rhs, ineq) \
+ CHECK_IMPL(lhs, std::as_const(rhs), ineq) \
+ CHECK_IMPL(std::as_const(lhs), std::as_const(rhs), ineq) \
+ } while (0)
+
+ // check that the (in)equality operators aren't ambiguous in C++20:
+ QJsonArray a = {a0, a1};
+
+ static_assert(std::is_same_v<decltype(a[0]), QJsonValueRef>);
+
+ auto r0 = a.begin()[0];
+ auto r1 = a.begin()[1];
+ auto c0 = std::as_const(a).begin()[0];
+ // ref <> ref
+ CHECK(r0, r0, r1);
+ // cref <> ref
+ CHECK(c0, r0, r1);
+ // ref <> cref
+ CHECK(r0, c0, r1);
+ // ref <> val
+ CHECK(r0, a0, r1);
+ // cref <> val
+ CHECK(c0, a0, r1);
+ // val <> ref
+ CHECK(a0, r0, a1);
+ // val <> cref
+ CHECK(a0, c0, a1);
+ // val <> val
+ CHECK(a0, a0, a1);
+
+ QT_TEST_EQUALITY_OPS(r0, r1, false);
+ QT_TEST_EQUALITY_OPS(r0, c0, true);
+ QT_TEST_EQUALITY_OPS(c0, r1, false);
+ QT_TEST_EQUALITY_OPS(a0, c0, true);
+ QT_TEST_EQUALITY_OPS(a0, r1, false);
+
+#undef CHECK
+#undef CHECK_IMPL
+}
+
void tst_QtJson::testObjectIteration()
{
QJsonObject object;
for (QJsonObject::iterator it = object.begin(); it != object.end(); ++it)
- QVERIFY(false);
+ QFAIL("Iterator of default-initialized object should be empty");
const QString property = "kkk";
object.insert(property, 11);
object.take(property);
for (QJsonObject::iterator it = object.begin(); it != object.end(); ++it)
- QVERIFY(false);
+ QFAIL("Iterator after property add-and-remove should be empty");
- for (int i = 0; i < 10; ++i)
- object[QString::number(i)] = (double)i;
+ // insert in weird order to confirm keys are sorted
+ for (int i : {0, 9, 5, 7, 8, 2, 1, 3, 6, 4})
+ object[QString::number(i)] = double(i);
QCOMPARE(object.size(), 10);
@@ -757,37 +1112,79 @@ void tst_QtJson::testObjectIteration()
for (QJsonObject::iterator it = object.begin(); it != object.end(); ++it) {
QJsonValue value = it.value();
QCOMPARE((double)it.key().toInt(), value.toDouble());
+ QT_TEST_EQUALITY_OPS(it, QJsonObject::iterator(), false);
}
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
+ QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonValue val = *object2.begin();
- object2.erase(object2.begin());
+ auto next = object2.erase(object2.begin());
QCOMPARE(object.size(), 10);
QCOMPARE(object2.size(), 9);
+ QVERIFY(next == object2.begin());
+ QT_TEST_EQUALITY_OPS(next, object2.begin(), true);
+
+ double d = 1; // we erased the first item
+ for (auto it = object2.constBegin(); it != object2.constEnd(); ++it, d += 1) {
+ QJsonValue value = it.value();
+ QVERIFY(it.value() != val);
+ QCOMPARE(it.value(), d);
+ QCOMPARE(it.value().toDouble(), d);
+ QCOMPARE(it.key().toInt(), value.toDouble());
+ }
+ }
+
+ {
+ QJsonObject object2 = object;
+ QCOMPARE(object, object2);
+ QT_TEST_EQUALITY_OPS(object, object2, true);
- for (QJsonObject::const_iterator it = object2.constBegin(); it != object2.constEnd(); ++it) {
+ QJsonValue val = *(object2.end() - 1);
+ auto next = object2.erase(object2.end() - 1);
+ QCOMPARE(object.size(), 10);
+ QCOMPARE(object2.size(), 9);
+ QVERIFY(next == object2.end());
+ double d = 0;
+ for (auto it = object2.constBegin(); it != object2.constEnd(); ++it, d += 1) {
QJsonValue value = it.value();
QVERIFY(it.value() != val);
- QCOMPARE((double)it.key().toInt(), value.toDouble());
+ QCOMPARE(it.value(), d);
+ QCOMPARE(it.value().toDouble(), d);
+ QCOMPARE(it.key().toInt(), value.toDouble());
}
}
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
+ QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonObject::iterator it = object2.find(QString::number(5));
- object2.erase(it);
+ QJsonValue val = *it;
+ auto next = object2.erase(it);
QCOMPARE(object.size(), 10);
QCOMPARE(object2.size(), 9);
+ QCOMPARE(*next, 6);
+
+ int i = 0;
+ for (auto it = object2.constBegin(); it != object2.constEnd(); ++it, ++i) {
+ if (i == 5)
+ ++i;
+ QJsonValue value = it.value();
+ QVERIFY(it.value() != val);
+ QCOMPARE(it.value(), i);
+ QCOMPARE(it.value().toInt(), i);
+ QCOMPARE(it.key().toInt(), value.toDouble());
+ }
}
{
QJsonObject::Iterator it = object.begin();
it += 5;
+ QT_TEST_ALL_COMPARISON_OPS(it, object.begin(), Qt::strong_ordering::greater);
QCOMPARE(QJsonValue(it.value()).toDouble(), 5.);
it -= 3;
QCOMPARE(QJsonValue(it.value()).toDouble(), 2.);
@@ -802,10 +1199,14 @@ void tst_QtJson::testObjectIteration()
it += 5;
QCOMPARE(QJsonValue(it.value()).toDouble(), 5.);
it -= 3;
+ QT_TEST_ALL_COMPARISON_OPS(object.constBegin(), it, Qt::strong_ordering::less);
QCOMPARE(QJsonValue(it.value()).toDouble(), 2.);
QJsonObject::ConstIterator it2 = it + 5;
+ QT_TEST_EQUALITY_OPS(it, it2, false);
QCOMPARE(QJsonValue(it2.value()).toDouble(), 7.);
it2 = it - 1;
+ QT_TEST_ALL_COMPARISON_OPS(it2, it, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it2, it - 2, Qt::strong_ordering::greater);
QCOMPARE(QJsonValue(it2.value()).toDouble(), 1.);
}
@@ -814,6 +1215,17 @@ void tst_QtJson::testObjectIteration()
it = object.erase(it);
QCOMPARE(object.size() , 0);
QCOMPARE(it, object.end());
+ QT_TEST_ALL_COMPARISON_OPS(it, object.end(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(it, object.constEnd(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(it, object.begin(),
+ Qt::strong_ordering::equal); // because object is empty
+ QT_TEST_ALL_COMPARISON_OPS(it, object.constBegin(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QJsonObject::Iterator(),
+ QJsonObject::Iterator(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QJsonObject::ConstIterator(),
+ QJsonObject::Iterator(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(QJsonObject::ConstIterator(),
+ QJsonObject::ConstIterator(), Qt::strong_ordering::equal);
}
void tst_QtJson::testArrayIteration()
@@ -827,7 +1239,11 @@ void tst_QtJson::testArrayIteration()
int i = 0;
for (QJsonArray::iterator it = array.begin(); it != array.end(); ++it, ++i) {
QJsonValue value = (*it);
+ QJsonArray::iterator it1 = it;
QCOMPARE((double)i, value.toDouble());
+ QT_TEST_EQUALITY_OPS(QJsonArray::iterator(), QJsonArray::iterator(), true);
+ QT_TEST_EQUALITY_OPS(QJsonArray::iterator(), it, false);
+ QT_TEST_EQUALITY_OPS(it1, it, true);
}
QCOMPARE(array.begin()->toDouble(), array.constBegin()->toDouble());
@@ -837,14 +1253,38 @@ void tst_QtJson::testArrayIteration()
QCOMPARE(array, array2);
QJsonValue val = *array2.begin();
- array2.erase(array2.begin());
+ auto next = array2.erase(array2.begin());
QCOMPARE(array.size(), 10);
QCOMPARE(array2.size(), 9);
+ QVERIFY(next == array2.begin());
i = 1;
- for (QJsonArray::const_iterator it = array2.constBegin(); it != array2.constEnd(); ++it, ++i) {
+ for (auto it = array2.constBegin(); it != array2.constEnd(); ++it, ++i) {
+ QJsonValue value = (*it);
+ QCOMPARE(value.toInt(), i);
+ QCOMPARE(value.toDouble(), i);
+ QCOMPARE(it->toInt(), i);
+ QCOMPARE(it->toDouble(), i);
+ }
+ }
+
+ {
+ QJsonArray array2 = array;
+ QCOMPARE(array, array2);
+
+ QJsonValue val = array2.last();
+ auto next = array2.erase(array2.end() - 1);
+ QCOMPARE(array.size(), 10);
+ QCOMPARE(array2.size(), 9);
+ QVERIFY(next == array2.end());
+
+ i = 0;
+ for (auto it = array2.constBegin(); it != array2.constEnd(); ++it, ++i) {
QJsonValue value = (*it);
- QCOMPARE((double)i, value.toDouble());
+ QCOMPARE(value.toInt(), i);
+ QCOMPARE(value.toDouble(), i);
+ QCOMPARE(it->toInt(), i);
+ QCOMPARE(it->toDouble(), i);
}
}
@@ -858,6 +1298,13 @@ void tst_QtJson::testArrayIteration()
QCOMPARE(QJsonValue(*it2).toDouble(), 7.);
it2 = it - 1;
QCOMPARE(QJsonValue(*it2).toDouble(), 1.);
+ QT_TEST_EQUALITY_OPS(it, it2, false);
+ it = array.begin();
+ QT_TEST_EQUALITY_OPS(it, array.begin(), true);
+ it2 = it + 5;
+ QT_TEST_ALL_COMPARISON_OPS(it2, it, Qt::strong_ordering::greater);
+ it += 5;
+ QT_TEST_EQUALITY_OPS(it, it2, true);
}
{
@@ -877,6 +1324,26 @@ void tst_QtJson::testArrayIteration()
it = array.erase(it);
QCOMPARE(array.size() , 0);
QCOMPARE(it, array.end());
+ QT_TEST_EQUALITY_OPS(it, array.end(), true);
+
+ {
+ int i = 0;
+ for (QJsonArray::const_iterator it = array.constBegin();
+ it != array.constEnd(); ++it, ++i) {
+ QJsonArray::const_iterator it1 = it;
+ QT_TEST_EQUALITY_OPS(QJsonArray::const_iterator(), QJsonArray::const_iterator(), true);
+ QT_TEST_EQUALITY_OPS(QJsonArray::const_iterator(), it, false);
+ QT_TEST_EQUALITY_OPS(it1, it, true);
+ }
+ }
+
+ {
+ QJsonArray::iterator nonConstIt = array.begin();
+ QJsonArray::const_iterator it = array.constBegin();
+ QT_TEST_EQUALITY_OPS(nonConstIt, it, true);
+ it+=1;
+ QT_TEST_ALL_COMPARISON_OPS(nonConstIt, it, Qt::strong_ordering::less);
+ }
}
void tst_QtJson::testObjectFind()
@@ -890,14 +1357,12 @@ void tst_QtJson::testObjectFind()
QJsonObject::iterator it = object.find(QLatin1String("1"));
QCOMPARE((*it).toDouble(), 1.);
it = object.find(QString("11"));
- QCOMPARE((*it).type(), QJsonValue::Undefined);
QCOMPARE(it, object.end());
QJsonObject::const_iterator cit = object.constFind(QLatin1String("1"));
QCOMPARE((*cit).toDouble(), 1.);
cit = object.constFind(QString("11"));
- QCOMPARE((*it).type(), QJsonValue::Undefined);
- QCOMPARE(it, object.end());
+ QCOMPARE(cit, object.constEnd());
}
void tst_QtJson::testDocument()
@@ -972,6 +1437,8 @@ void tst_QtJson::testDocument()
QCOMPARE(doc5.isObject(), false);
QCOMPARE(doc5.array().size(), 1);
QCOMPARE(doc5.array().at(0), QJsonValue(23));
+
+ QT_TEST_EQUALITY_OPS(doc2, doc3, true);
}
void tst_QtJson::nullValues()
@@ -1062,21 +1529,55 @@ void tst_QtJson::constNullObject()
QCOMPARE(nullObject["foo"], QJsonValue(QJsonValue::Undefined));
}
-void tst_QtJson::keySorting()
+void tst_QtJson::keySorting_data()
{
+ QTest::addColumn<QString>("json");
+ QTest::addColumn<QStringList>("sortedKeys");
+
+ QStringList list = {"A", "B"};
+ QTest::newRow("sorted-ascii-2") << R"({ "A": false, "B": true })" << list;
const char *json = "{ \"B\": true, \"A\": false }";
- QJsonDocument doc = QJsonDocument::fromJson(json);
+ QTest::newRow("unsorted-ascii-2") << json << list;
+
+ list = QStringList{"A", "B", "C", "D", "E"};
+ QTest::newRow("sorted-ascii-5") << R"({"A": 1, "B": 2, "C": 3, "D": 4, "E": 5})" << list;
+ QTest::newRow("unsorted-ascii-5") << R"({"A": 1, "C": 3, "D": 4, "B": 2, "E": 5})" << list;
+ QTest::newRow("inverse-sorted-ascii-5") << R"({"E": 5, "D": 4, "C": 3, "B": 2, "A": 1})" << list;
+
+ list = QStringList{"á", "é", "í", "ó", "ú"};
+ QTest::newRow("sorted-latin1") << R"({"á": 1, "é": 2, "í": 3, "ó": 4, "ú": 5})" << list;
+ QTest::newRow("unsorted-latin1") << R"({"á": 1, "í": 3, "ó": 4, "é": 2, "ú": 5})" << list;
+ QTest::newRow("inverse-sorted-latin1") << R"({"ú": 5, "ó": 4, "í": 3, "é": 2, "á": 1})" << list;
+
+ QTest::newRow("sorted-escaped-latin1") << R"({"\u00e1": 1, "\u00e9": 2, "\u00ed": 3, "\u00f3": 4, "\u00fa": 5})" << list;
+ QTest::newRow("unsorted-escaped-latin1") << R"({"\u00e1": 1, "\u00ed": 3, "\u00f3": 4, "\u00e9": 2, "\u00fa": 5})" << list;
+ QTest::newRow("inverse-sorted-escaped-latin1") << R"({"\u00fa": 5, "\u00f3": 4, "\u00ed": 3, "\u00e9": 2, "\u00e1": 1})" << list;
+
+ list = QStringList{"A", "α", "Я", "€", "测"};
+ QTest::newRow("sorted") << R"({"A": 1, "α": 2, "Я": 3, "€": 4, "测": 5})" << list;
+ QTest::newRow("unsorted") << R"({"A": 1, "Я": 3, "€": 4, "α": 2, "测": 5})" << list;
+ QTest::newRow("inverse-sorted") << R"({"测": 5, "€": 4, "Я": 3, "α": 2, "A": 1})" << list;
+
+ QTest::newRow("sorted-escaped") << R"({"A": 1, "\u03b1": 2, "\u042f": 3, "\u20ac": 4, "\u6d4b": 5})" << list;
+ QTest::newRow("unsorted-escaped") << R"({"A": 1, "\u042f": 3, "\u20ac": 4, "\u03b1": 2, "\u6d4b": 5})" << list;
+ QTest::newRow("inverse-sorted-escaped") << R"({"\u6d4b": 5, "\u20ac": 4, "\u042f": 3, "\u03b1": 2, "A": 1})" << list;
+}
+
+void tst_QtJson::keySorting()
+{
+ QFETCH(QString, json);
+ QFETCH(QStringList, sortedKeys);
+ QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
QCOMPARE(doc.isObject(), true);
QJsonObject o = doc.object();
- QCOMPARE(o.size(), 2);
+ QCOMPARE(o.size(), sortedKeys.size());
+ QCOMPARE(o.keys(), sortedKeys);
QJsonObject::const_iterator it = o.constBegin();
- QCOMPARE(it.key(), QLatin1String("A"));
- ++it;
- QCOMPARE(it.key(), QLatin1String("B"));
-
- QCOMPARE(o.keys(), QStringList() << QLatin1String("A") << QLatin1String("B"));
+ QStringList::const_iterator it2 = sortedKeys.constBegin();
+ for ( ; it != o.constEnd(); ++it, ++it2)
+ QCOMPARE(it.key(), *it2);
}
void tst_QtJson::undefinedValues()
@@ -1084,6 +1585,8 @@ void tst_QtJson::undefinedValues()
QJsonObject object;
object.insert("Key", QJsonValue(QJsonValue::Undefined));
QCOMPARE(object.size(), 0);
+ object["Key"] = QJsonValue(QJsonValue::Undefined);
+ QCOMPARE(object.size(), 0);
object.insert("Key", QLatin1String("Value"));
QCOMPARE(object.size(), 1);
@@ -1110,8 +1613,8 @@ void tst_QtJson::fromVariant_data()
bool boolValue = true;
int intValue = -1;
uint uintValue = 1;
- long long longlongValue = -2;
- unsigned long long ulonglongValue = 2;
+ qlonglong longlongValue = -2;
+ qulonglong ulonglongValue = 2;
float floatValue = 3.3f;
double doubleValue = 4.4;
QString stringValue("str");
@@ -1130,6 +1633,7 @@ void tst_QtJson::fromVariant_data()
variantList.append(stringValue);
variantList.append(stringList);
variantList.append(QVariant::fromValue(nullptr));
+ variantList.append(QVariant());
QJsonArray jsonArray_variant;
jsonArray_variant.append(boolValue);
jsonArray_variant.append(floatValue);
@@ -1137,27 +1641,35 @@ void tst_QtJson::fromVariant_data()
jsonArray_variant.append(stringValue);
jsonArray_variant.append(jsonArray_string);
jsonArray_variant.append(QJsonValue(QJsonValue::Null));
+ jsonArray_variant.append(QJsonValue());
QVariantMap variantMap;
variantMap["bool"] = boolValue;
variantMap["float"] = floatValue;
variantMap["string"] = stringValue;
variantMap["array"] = variantList;
+ variantMap["null"] = QVariant::fromValue(nullptr);
+ variantMap["default"] = QVariant();
QVariantHash variantHash;
variantHash["bool"] = boolValue;
variantHash["float"] = floatValue;
variantHash["string"] = stringValue;
variantHash["array"] = variantList;
+ variantHash["null"] = QVariant::fromValue(nullptr);
+ variantHash["default"] = QVariant();
QJsonObject jsonObject;
jsonObject["bool"] = boolValue;
jsonObject["float"] = floatValue;
jsonObject["string"] = stringValue;
jsonObject["array"] = jsonArray_variant;
+ jsonObject["null"] = QJsonValue::Null;
+ jsonObject["default"] = QJsonValue();
+ QTest::newRow("default") << QVariant() << QJsonValue();
QTest::newRow("nullptr") << QVariant::fromValue(nullptr) << QJsonValue(QJsonValue::Null);
QTest::newRow("bool") << QVariant(boolValue) << QJsonValue(boolValue);
QTest::newRow("int") << QVariant(intValue) << QJsonValue(intValue);
- QTest::newRow("uint") << QVariant(uintValue) << QJsonValue(static_cast<double>(uintValue));
+ QTest::newRow("uint") << QVariant(uintValue) << QJsonValue(static_cast<qint64>(uintValue));
QTest::newRow("longlong") << QVariant(longlongValue) << QJsonValue(longlongValue);
QTest::newRow("ulonglong") << QVariant(ulonglongValue) << QJsonValue(static_cast<double>(ulonglongValue));
QTest::newRow("float") << QVariant(floatValue) << QJsonValue(floatValue);
@@ -1169,13 +1681,55 @@ void tst_QtJson::fromVariant_data()
QTest::newRow("variantHash") << QVariant(variantHash) << QJsonValue(jsonObject);
}
+// replaces QVariant() with QVariant(nullptr)
+static QVariant normalizedVariant(const QVariant &v)
+{
+ switch (v.userType()) {
+ case QMetaType::UnknownType:
+ return QVariant::fromValue(nullptr);
+ case QMetaType::QVariantList: {
+ const QVariantList in = v.toList();
+ QVariantList out;
+ out.reserve(in.size());
+ for (const QVariant &v : in)
+ out << normalizedVariant(v);
+ return out;
+ }
+ case QMetaType::QStringList: {
+ const QStringList in = v.toStringList();
+ QVariantList out;
+ out.reserve(in.size());
+ for (const QString &v : in)
+ out << v;
+ return out;
+ }
+ case QMetaType::QVariantMap: {
+ const QVariantMap in = v.toMap();
+ QVariantMap out;
+ for (auto it = in.begin(); it != in.end(); ++it)
+ out.insert(it.key(), normalizedVariant(it.value()));
+ return out;
+ }
+ case QMetaType::QVariantHash: {
+ const QVariantHash in = v.toHash();
+ QVariantMap out;
+ for (auto it = in.begin(); it != in.end(); ++it)
+ out.insert(it.key(), normalizedVariant(it.value()));
+ return out;
+ }
+
+ default:
+ return v;
+ }
+}
+
void tst_QtJson::fromVariant()
{
QFETCH( QVariant, variant );
QFETCH( QJsonValue, jsonvalue );
QCOMPARE(QJsonValue::fromVariant(variant), jsonvalue);
- QCOMPARE(variant.toJsonValue(), jsonvalue);
+ QCOMPARE(normalizedVariant(variant).toJsonValue(), jsonvalue);
}
void tst_QtJson::fromVariantSpecial_data()
@@ -1208,7 +1762,7 @@ void tst_QtJson::toVariant()
QFETCH( QVariant, variant );
QFETCH( QJsonValue, jsonvalue );
- QCOMPARE(jsonvalue.toVariant(), variant);
+ QCOMPARE(jsonvalue.toVariant(), normalizedVariant(variant));
}
void tst_QtJson::fromVariantMap()
@@ -1256,7 +1810,8 @@ void tst_QtJson::fromVariantHash()
void tst_QtJson::toVariantMap()
{
- QCOMPARE(QMetaType::Type(QJsonValue(QJsonObject()).toVariant().type()), QMetaType::QVariantMap); // QTBUG-32524
+ QCOMPARE(QMetaType::Type(QJsonValue(QJsonObject()).toVariant().typeId()),
+ QMetaType::QVariantMap); // QTBUG-32524
QJsonObject object;
QVariantMap map = object.toVariantMap();
@@ -1276,7 +1831,7 @@ void tst_QtJson::toVariantMap()
QCOMPARE(map.size(), 3);
QCOMPARE(map.value("Key"), QVariant(QString("Value")));
QCOMPARE(map.value("null"), QVariant::fromValue(nullptr));
- QCOMPARE(map.value("Array").type(), QVariant::List);
+ QCOMPARE(map.value("Array").typeId(), QMetaType::QVariantList);
QVariantList list = map.value("Array").toList();
QCOMPARE(list.size(), 4);
QCOMPARE(list.at(0), QVariant(true));
@@ -1305,7 +1860,7 @@ void tst_QtJson::toVariantHash()
QCOMPARE(hash.size(), 3);
QCOMPARE(hash.value("Key"), QVariant(QString("Value")));
QCOMPARE(hash.value("null"), QVariant::fromValue(nullptr));
- QCOMPARE(hash.value("Array").type(), QVariant::List);
+ QCOMPARE(hash.value("Array").typeId(), QMetaType::QVariantList);
QVariantList list = hash.value("Array").toList();
QCOMPARE(list.size(), 4);
QCOMPARE(list.at(0), QVariant(true));
@@ -1316,7 +1871,8 @@ void tst_QtJson::toVariantHash()
void tst_QtJson::toVariantList()
{
- QCOMPARE(QMetaType::Type(QJsonValue(QJsonArray()).toVariant().type()), QMetaType::QVariantList); // QTBUG-32524
+ QCOMPARE(QMetaType::Type(QJsonValue(QJsonArray()).toVariant().typeId()),
+ QMetaType::QVariantList); // QTBUG-32524
QJsonArray array;
QVariantList list = array.toVariantList();
@@ -1336,7 +1892,7 @@ void tst_QtJson::toVariantList()
QCOMPARE(list.size(), 3);
QCOMPARE(list[0], QVariant(QString("Value")));
QCOMPARE(list[1], QVariant::fromValue(nullptr));
- QCOMPARE(list[2].type(), QVariant::List);
+ QCOMPARE(list[2].typeId(), QMetaType::QVariantList);
QVariantList vlist = list[2].toList();
QCOMPARE(vlist.size(), 4);
QCOMPARE(vlist.at(0), QVariant(true));
@@ -1458,16 +2014,13 @@ void tst_QtJson::toJsonLargeNumericValues()
QJsonArray array;
array.append(QJsonValue(1.234567)); // actual precision bug in Qt 5.0.0
array.append(QJsonValue(1.7976931348623157e+308)); // JS Number.MAX_VALUE
- array.append(QJsonValue(5e-324)); // JS Number.MIN_VALUE
array.append(QJsonValue(std::numeric_limits<double>::min()));
array.append(QJsonValue(std::numeric_limits<double>::max()));
array.append(QJsonValue(std::numeric_limits<double>::epsilon()));
- array.append(QJsonValue(std::numeric_limits<double>::denorm_min()));
array.append(QJsonValue(0.0));
array.append(QJsonValue(-std::numeric_limits<double>::min()));
array.append(QJsonValue(-std::numeric_limits<double>::max()));
array.append(QJsonValue(-std::numeric_limits<double>::epsilon()));
- array.append(QJsonValue(-std::numeric_limits<double>::denorm_min()));
array.append(QJsonValue(-0.0));
array.append(QJsonValue(9007199254740992LL)); // JS Number max integer
array.append(QJsonValue(-9007199254740992LL)); // JS Number min integer
@@ -1481,27 +2034,21 @@ void tst_QtJson::toJsonLargeNumericValues()
" 1.234567,\n"
" 1.7976931348623157e+308,\n"
#ifdef QT_NO_DOUBLECONVERSION // "shortest" double conversion is not very short then
- " 4.9406564584124654e-324,\n"
" 2.2250738585072014e-308,\n"
" 1.7976931348623157e+308,\n"
" 2.2204460492503131e-16,\n"
- " 4.9406564584124654e-324,\n"
" 0,\n"
" -2.2250738585072014e-308,\n"
" -1.7976931348623157e+308,\n"
" -2.2204460492503131e-16,\n"
- " -4.9406564584124654e-324,\n"
#else
- " 5e-324,\n"
" 2.2250738585072014e-308,\n"
" 1.7976931348623157e+308,\n"
" 2.220446049250313e-16,\n"
- " 5e-324,\n"
" 0,\n"
" -2.2250738585072014e-308,\n"
" -1.7976931348623157e+308,\n"
" -2.220446049250313e-16,\n"
- " -5e-324,\n"
#endif
" 0,\n"
" 9007199254740992,\n"
@@ -1509,20 +2056,50 @@ void tst_QtJson::toJsonLargeNumericValues()
" ]\n"
"}\n";
-#ifdef Q_OS_QNX
- QEXPECT_FAIL("", "See QTBUG-37066", Continue);
-#endif
QCOMPARE(json, expected);
QJsonDocument doc;
doc.setObject(object);
json = doc.toJson();
-#ifdef Q_OS_QNX
- QEXPECT_FAIL("", "See QTBUG-37066", Continue);
-#endif
QCOMPARE(json, expected);
}
+void tst_QtJson::toJsonDenormalValues()
+{
+ if constexpr (std::numeric_limits<double>::has_denorm == std::denorm_present) {
+ QJsonObject object;
+ QJsonArray array;
+ array.append(QJsonValue(5e-324)); // JS Number.MIN_VALUE
+ array.append(QJsonValue(std::numeric_limits<double>::denorm_min()));
+ array.append(QJsonValue(-std::numeric_limits<double>::denorm_min()));
+ object.insert("Array", array);
+
+ QByteArray json = QJsonDocument(object).toJson();
+ QByteArray expected =
+ "{\n"
+ " \"Array\": [\n"
+#ifdef QT_NO_DOUBLECONVERSION // "shortest" double conversion is not very short then
+ " 4.9406564584124654e-324,\n"
+ " 4.9406564584124654e-324,\n"
+ " -4.9406564584124654e-324\n"
+#else
+ " 5e-324,\n"
+ " 5e-324,\n"
+ " -5e-324\n"
+#endif
+ " ]\n"
+ "}\n";
+
+ QCOMPARE(json, expected);
+ QJsonDocument doc;
+ doc.setObject(object);
+ json = doc.toJson();
+ QCOMPARE(json, expected);
+ } else {
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+}
+
void tst_QtJson::fromJson()
{
{
@@ -1813,64 +2390,6 @@ void tst_QtJson::fromJsonErrors()
}
}
-void tst_QtJson::fromBinary()
-{
- QFile file(testDataDir + "/test.json");
- file.open(QFile::ReadOnly);
- QByteArray testJson = file.readAll();
-
- QJsonDocument doc = QJsonDocument::fromJson(testJson);
- QJsonDocument outdoc = QJsonDocument::fromBinaryData(doc.toBinaryData());
- QVERIFY(!outdoc.isNull());
- QCOMPARE(doc, outdoc);
-
- QFile bfile(testDataDir + "/test.bjson");
- bfile.open(QFile::ReadOnly);
- QByteArray binary = bfile.readAll();
-
- QJsonDocument bdoc = QJsonDocument::fromBinaryData(binary);
- QVERIFY(!bdoc.isNull());
- QCOMPARE(doc.toVariant(), bdoc.toVariant());
- QCOMPARE(doc, bdoc);
-}
-
-void tst_QtJson::toAndFromBinary_data()
-{
- QTest::addColumn<QString>("filename");
- QTest::newRow("test.json") << (testDataDir + "/test.json");
- QTest::newRow("test2.json") << (testDataDir + "/test2.json");
-}
-
-void tst_QtJson::toAndFromBinary()
-{
- QFETCH(QString, filename);
- QFile file(filename);
- QVERIFY(file.open(QFile::ReadOnly));
- QByteArray data = file.readAll();
-
- QJsonDocument doc = QJsonDocument::fromJson(data);
- QVERIFY(!doc.isNull());
- QJsonDocument outdoc = QJsonDocument::fromBinaryData(doc.toBinaryData());
- QVERIFY(!outdoc.isNull());
- QCOMPARE(doc, outdoc);
-}
-
-void tst_QtJson::invalidBinaryData()
-{
- QDir dir(testDataDir + "/invalidBinaryData");
- QFileInfoList files = dir.entryInfoList();
- for (int i = 0; i < files.size(); ++i) {
- if (!files.at(i).isFile())
- continue;
- QFile file(files.at(i).filePath());
- file.open(QIODevice::ReadOnly);
- QByteArray bytes = file.readAll();
- bytes.squeeze();
- QJsonDocument document = QJsonDocument::fromRawData(bytes.constData(), bytes.size());
- QVERIFY(document.isNull());
- }
-}
-
void tst_QtJson::parseNumbers()
{
{
@@ -1903,12 +2422,12 @@ void tst_QtJson::parseNumbers()
QCOMPARE(val.toDouble(), (double)numbers[i].n);
}
}
+ // test number parsing
+ struct Numbers {
+ const char *str;
+ double n;
+ };
{
- // test number parsing
- struct Numbers {
- const char *str;
- double n;
- };
Numbers numbers [] = {
{ "0", 0 },
{ "1", 1 },
@@ -1924,8 +2443,6 @@ void tst_QtJson::parseNumbers()
{ "1.1e10", 1.1e10 },
{ "1.1e308", 1.1e308 },
{ "-1.1e308", -1.1e308 },
- { "1.1e-308", 1.1e-308 },
- { "-1.1e-308", -1.1e-308 },
{ "1.1e+308", 1.1e+308 },
{ "-1.1e+308", -1.1e+308 },
{ "1.e+308", 1.e+308 },
@@ -1937,10 +2454,6 @@ void tst_QtJson::parseNumbers()
json += numbers[i].str;
json += " ]";
QJsonDocument doc = QJsonDocument::fromJson(json);
-#ifdef Q_OS_QNX
- if (0 == QString::compare(numbers[i].str, "1.1e-308"))
- QEXPECT_FAIL("", "See QTBUG-37066", Abort);
-#endif
QVERIFY(!doc.isEmpty());
QCOMPARE(doc.isArray(), true);
QCOMPARE(doc.isObject(), false);
@@ -1951,6 +2464,29 @@ void tst_QtJson::parseNumbers()
QCOMPARE(val.toDouble(), numbers[i].n);
}
}
+ if constexpr (std::numeric_limits<double>::has_denorm == std::denorm_present) {
+ Numbers numbers [] = {
+ { "1.1e-308", 1.1e-308 },
+ { "-1.1e-308", -1.1e-308 }
+ };
+ int size = sizeof(numbers)/sizeof(Numbers);
+ for (int i = 0; i < size; ++i) {
+ QByteArray json = "[ ";
+ json += numbers[i].str;
+ json += " ]";
+ QJsonDocument doc = QJsonDocument::fromJson(json);
+ QVERIFY(!doc.isEmpty());
+ QCOMPARE(doc.isArray(), true);
+ QCOMPARE(doc.isObject(), false);
+ QJsonArray array = doc.array();
+ QCOMPARE(array.size(), 1);
+ QJsonValue val = array.at(0);
+ QCOMPARE(val.type(), QJsonValue::Double);
+ QCOMPARE(val.toDouble(), numbers[i].n);
+ }
+ } else {
+ qInfo("Skipping denormal test as this system's double type lacks support");
+ }
}
void tst_QtJson::parseStrings()
@@ -2040,136 +2576,11 @@ void tst_QtJson::parseDuplicateKeys()
void tst_QtJson::testParser()
{
QFile file(testDataDir + "/test.json");
- file.open(QFile::ReadOnly);
- QByteArray testJson = file.readAll();
-
- QJsonDocument doc = QJsonDocument::fromJson(testJson);
- QVERIFY(!doc.isEmpty());
-}
-
-void tst_QtJson::compactArray()
-{
- QJsonArray array;
- array.append(QLatin1String("First Entry"));
- array.append(QLatin1String("Second Entry"));
- array.append(QLatin1String("Third Entry"));
- QJsonDocument doc(array);
- int s = doc.toBinaryData().size();
- array.removeAt(1);
- doc.setArray(array);
- QVERIFY(s > doc.toBinaryData().size());
- s = doc.toBinaryData().size();
- QCOMPARE(doc.toJson(),
- QByteArray("[\n"
- " \"First Entry\",\n"
- " \"Third Entry\"\n"
- "]\n"));
-
- array.removeAt(0);
- doc.setArray(array);
- QVERIFY(s > doc.toBinaryData().size());
- s = doc.toBinaryData().size();
- QCOMPARE(doc.toJson(),
- QByteArray("[\n"
- " \"Third Entry\"\n"
- "]\n"));
-
- array.removeAt(0);
- doc.setArray(array);
- QVERIFY(s > doc.toBinaryData().size());
- s = doc.toBinaryData().size();
- QCOMPARE(doc.toJson(),
- QByteArray("[\n"
- "]\n"));
-
-}
-
-void tst_QtJson::compactObject()
-{
- QJsonObject object;
- object.insert(QLatin1String("Key1"), QLatin1String("First Entry"));
- object.insert(QLatin1String("Key2"), QLatin1String("Second Entry"));
- object.insert(QLatin1String("Key3"), QLatin1String("Third Entry"));
- QJsonDocument doc(object);
- int s = doc.toBinaryData().size();
- object.remove(QLatin1String("Key2"));
- doc.setObject(object);
- QVERIFY(s > doc.toBinaryData().size());
- s = doc.toBinaryData().size();
- QCOMPARE(doc.toJson(),
- QByteArray("{\n"
- " \"Key1\": \"First Entry\",\n"
- " \"Key3\": \"Third Entry\"\n"
- "}\n"));
-
- object.remove(QLatin1String("Key1"));
- doc.setObject(object);
- QVERIFY(s > doc.toBinaryData().size());
- s = doc.toBinaryData().size();
- QCOMPARE(doc.toJson(),
- QByteArray("{\n"
- " \"Key3\": \"Third Entry\"\n"
- "}\n"));
-
- object.remove(QLatin1String("Key3"));
- doc.setObject(object);
- QVERIFY(s > doc.toBinaryData().size());
- s = doc.toBinaryData().size();
- QCOMPARE(doc.toJson(),
- QByteArray("{\n"
- "}\n"));
-
-}
-
-void tst_QtJson::validation()
-{
- // this basically tests that we don't crash on corrupt data
- QFile file(testDataDir + "/test.json");
QVERIFY(file.open(QFile::ReadOnly));
QByteArray testJson = file.readAll();
- QVERIFY(!testJson.isEmpty());
QJsonDocument doc = QJsonDocument::fromJson(testJson);
- QVERIFY(!doc.isNull());
-
- QByteArray binary = doc.toBinaryData();
-
- // only test the first 1000 bytes. Testing the full file takes too long
- for (int i = 0; i < 1000; ++i) {
- QByteArray corrupted = binary;
- corrupted[i] = char(0xff);
- QJsonDocument doc = QJsonDocument::fromBinaryData(corrupted);
- if (doc.isNull())
- continue;
- QByteArray json = doc.toJson();
- }
-
-
- QFile file2(testDataDir + "/test3.json");
- file2.open(QFile::ReadOnly);
- testJson = file2.readAll();
- QVERIFY(!testJson.isEmpty());
-
- doc = QJsonDocument::fromJson(testJson);
- QVERIFY(!doc.isNull());
-
- binary = doc.toBinaryData();
-
- for (int i = 0; i < binary.size(); ++i) {
- QByteArray corrupted = binary;
- corrupted[i] = char(0xff);
- QJsonDocument doc = QJsonDocument::fromBinaryData(corrupted);
- if (doc.isNull())
- continue;
- QByteArray json = doc.toJson();
-
- corrupted = binary;
- corrupted[i] = 0x00;
- doc = QJsonDocument::fromBinaryData(corrupted);
- if (doc.isNull())
- continue;
- json = doc.toJson();
- }
+ QVERIFY(!doc.isEmpty());
}
void tst_QtJson::assignToDocument()
@@ -2222,12 +2633,12 @@ void tst_QtJson::testCompaction()
QCOMPARE(obj.size(), 1);
QCOMPARE(obj.value(QLatin1String("foo")).toString(), QLatin1String("bar"));
- QJsonDocument doc = QJsonDocument::fromBinaryData(QJsonDocument(obj).toBinaryData());
- QVERIFY(!doc.isNull());
- QVERIFY(!doc.isEmpty());
- QCOMPARE(doc.isArray(), false);
- QCOMPARE(doc.isObject(), true);
- QCOMPARE(doc.object(), obj);
+ QJsonObject obj2;
+
+ QT_TEST_EQUALITY_OPS(obj, obj2, false);
+ QT_TEST_EQUALITY_OPS(QJsonObject(), obj2, true);
+ obj2 = obj;
+ QT_TEST_EQUALITY_OPS(obj, obj2, true);
}
void tst_QtJson::testDebugStream()
@@ -2317,48 +2728,128 @@ void tst_QtJson::testDebugStream()
}
}
-void tst_QtJson::testCompactionError()
+void tst_QtJson::parseEscapes_data()
{
- QJsonObject schemaObject;
- schemaObject.insert("_Type", QLatin1String("_SchemaType"));
- schemaObject.insert("name", QLatin1String("Address"));
- schemaObject.insert("schema", QJsonObject());
- {
- QJsonObject content(schemaObject);
- QJsonDocument doc(content);
- QVERIFY(!doc.isNull());
- QByteArray hash = QCryptographicHash::hash(doc.toBinaryData(), QCryptographicHash::Md5).toHex();
- schemaObject.insert("_Version", QString::fromLatin1(hash.constData(), hash.size()));
- }
+ QTest::addColumn<QByteArray>("json");
+ QTest::addColumn<QString>("result");
+
+ auto addUnicodeRow = [](char32_t u) {
+ char buf[32]; // more than enough
+ char *ptr = buf;
+ const QString result = QString::fromUcs4(&u, 1);
+ for (QChar c : result)
+ ptr += snprintf(ptr, std::end(buf) - ptr, "\\u%04x", c.unicode());
+ QTest::addRow("U+%04X", u) << "[\"" + QByteArray(buf) + "\"]" << result;
+ };
- QJsonObject schema;
- schema.insert("streetNumber", schema.value("number").toObject());
- schemaObject.insert("schema", schema);
- {
- QJsonObject content(schemaObject);
- content.remove("_Uuid");
- content.remove("_Version");
- QJsonDocument doc(content);
- QVERIFY(!doc.isNull());
- QByteArray hash = QCryptographicHash::hash(doc.toBinaryData(), QCryptographicHash::Md5).toHex();
- schemaObject.insert("_Version", QString::fromLatin1(hash.constData(), hash.size()));
+ char singleCharJson[] = R"(["\x"])";
+ Q_ASSERT(singleCharJson[3] == 'x');
+ auto makeSingleCharEscape = [&singleCharJson](char c) {
+ singleCharJson[3] = char(c);
+ return QByteArray(singleCharJson, std::size(singleCharJson) - 1);
+ };
+
+ QTest::addRow("quote") << makeSingleCharEscape('"') << "\"";
+ QTest::addRow("backslash") << makeSingleCharEscape('\\') << "\\";
+ QTest::addRow("slash") << makeSingleCharEscape('/') << "/";
+ QTest::addRow("backspace") << makeSingleCharEscape('b') << "\b";
+ QTest::addRow("form-feed") << makeSingleCharEscape('f') << "\f";
+ QTest::addRow("newline") << makeSingleCharEscape('n') << "\n";
+ QTest::addRow("carriage-return") << makeSingleCharEscape('r') << "\r";
+ QTest::addRow("tab") << makeSingleCharEscape('t') << "\t";
+
+ // we're not going to exhaustively test all Unicode possibilities
+ for (char16_t c = 0; c < 0x21; ++c)
+ addUnicodeRow(c);
+ addUnicodeRow(u'\u007f');
+ addUnicodeRow(u'\u0080');
+ addUnicodeRow(u'\u00ff');
+ addUnicodeRow(u'\u0100');
+ addUnicodeRow(char16_t(0xd800));
+ addUnicodeRow(char16_t(0xdc00));
+ addUnicodeRow(u'\ufffe');
+ addUnicodeRow(u'\uffff');
+ addUnicodeRow(U'\U00010000');
+ addUnicodeRow(U'\U00100000');
+ addUnicodeRow(U'\U0010ffff');
+
+ QTest::addRow("mojibake-utf8") << QByteArrayLiteral(R"(["A\u00e4\u00C4"])")
+ << QStringLiteral(u"A\u00e4\u00C4");
+
+ // characters for which, preceded by backslash, it is a valid (recognized)
+ // escape sequence (should match the above list)
+ static const char validEscapes[] = "\"\\/bfnrtu";
+ for (int i = 0; i <= 0xff; ++i) {
+ if (i && strchr(validEscapes, i))
+ continue;
+ QTest::addRow("invalid-uchar-0x%02x", i) << makeSingleCharEscape(i) << QString(char16_t(i));
}
}
-void tst_QtJson::parseUnicodeEscapes()
+void tst_QtJson::parseEscapes()
{
- const QByteArray json = "[ \"A\\u00e4\\u00C4\" ]";
+ QFETCH(QByteArray, json);
+ QFETCH(QString, result);
QJsonDocument doc = QJsonDocument::fromJson(json);
QJsonArray array = doc.array();
- QString result = QLatin1String("A");
- result += QChar(0xe4);
- result += QChar(0xc4);
-
QCOMPARE(array.first().toString(), result);
}
+void tst_QtJson::makeEscapes_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QByteArray>("result");
+
+ auto addUnicodeRow = [](char16_t c) {
+ char buf[32]; // more than enough
+ snprintf(buf, std::size(buf), "\\u%04x", c);
+ QTest::addRow("U+%04X", c) << QString(c) << QByteArray(buf);
+ };
+
+
+ QTest::addRow("quote") << "\"" << QByteArray(R"(\")");
+ QTest::addRow("backslash") << "\\" << QByteArray(R"(\\)");
+ //QTest::addRow("slash") << "/" << QByteArray(R"(\/)"); // does not get escaped
+ QTest::addRow("backspace") << "\b" << QByteArray(R"(\b)");
+ QTest::addRow("form-feed") << "\f" << QByteArray(R"(\f)");
+ QTest::addRow("newline") << "\n" << QByteArray(R"(\n)");
+ QTest::addRow("carriage-return") << "\r" << QByteArray(R"(\r)");
+ QTest::addRow("tab") << "\t" << QByteArray(R"(\t)");
+
+ // control characters other than the above
+ for (char16_t c = 0; c < 0x20; ++c) {
+ if (c && strchr("\b\f\n\r\t", c))
+ continue;
+ addUnicodeRow(c);
+ }
+ // unpaired surrogates
+ addUnicodeRow(char16_t(0xd800));
+ addUnicodeRow(char16_t(0xdc00));
+
+ QString improperlyPaired;
+ improperlyPaired.append(char16_t(0xdc00));
+ improperlyPaired.append(char16_t(0xd800));
+ QTest::addRow("inverted-surrogates") << improperlyPaired << QByteArray("\\udc00\\ud800");
+}
+
+void tst_QtJson::makeEscapes()
+{
+ QFETCH(QString, input);
+ QFETCH(QByteArray, result);
+
+ QJsonArray array = { input };
+ QByteArray json = QJsonDocument(array).toJson(QJsonDocument::Compact);
+
+ QVERIFY(json.startsWith("[\""));
+ result.prepend("[\"");
+ QVERIFY(json.endsWith("\"]"));
+ result.append("\"]");
+
+ QCOMPARE(json, result);
+}
+
void tst_QtJson::assignObjects()
{
const char *json =
@@ -2427,57 +2918,57 @@ void tst_QtJson::testDetachBug()
void tst_QtJson::valueEquals()
{
QCOMPARE(QJsonValue(), QJsonValue());
- QVERIFY(QJsonValue() != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue() != QJsonValue(true));
- QVERIFY(QJsonValue() != QJsonValue(1.));
- QVERIFY(QJsonValue() != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue() != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(true), QJsonValue(true));
- QVERIFY(QJsonValue(true) != QJsonValue(false));
- QVERIFY(QJsonValue(true) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(true) != QJsonValue());
- QVERIFY(QJsonValue(true) != QJsonValue(1.));
- QVERIFY(QJsonValue(true) != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue(true) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(false), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(1), QJsonValue(1));
- QVERIFY(QJsonValue(1) != QJsonValue(2));
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(2), false);
QCOMPARE(QJsonValue(1), QJsonValue(1.));
- QVERIFY(QJsonValue(1) != QJsonValue(1.1));
- QVERIFY(QJsonValue(1) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(1) != QJsonValue());
- QVERIFY(QJsonValue(1) != QJsonValue(true));
- QVERIFY(QJsonValue(1) != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue(1) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(1.1), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(1.), QJsonValue(1.));
- QVERIFY(QJsonValue(1.) != QJsonValue(2.));
- QVERIFY(QJsonValue(1.) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(1.) != QJsonValue());
- QVERIFY(QJsonValue(1.) != QJsonValue(true));
- QVERIFY(QJsonValue(1.) != QJsonValue(QJsonArray()));
- QVERIFY(QJsonValue(1.) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(2.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonArray()), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(QJsonArray()), QJsonValue(QJsonArray()));
QJsonArray nonEmptyArray;
nonEmptyArray.append(true);
- QVERIFY(QJsonValue(QJsonArray()) != nonEmptyArray);
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue());
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(true));
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(1.));
- QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(QJsonObject()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), nonEmptyArray, false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(QJsonObject()), false);
QCOMPARE(QJsonValue(QJsonObject()), QJsonValue(QJsonObject()));
QJsonObject nonEmptyObject;
nonEmptyObject.insert("Key", true);
- QVERIFY(QJsonValue(QJsonObject()) != nonEmptyObject);
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonValue::Undefined));
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue());
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(true));
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(1.));
- QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonArray()));
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), nonEmptyObject, false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(QJsonValue::Undefined), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(true), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(1.), false);
+ QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(QJsonArray()), false);
QCOMPARE(QJsonValue("foo"), QJsonValue(QLatin1String("foo")));
QCOMPARE(QJsonValue("foo"), QJsonValue(QString("foo")));
@@ -2553,6 +3044,12 @@ void tst_QtJson::objectEquals()
QCOMPARE(QJsonValue(left) != QJsonValue(right), !result);
QCOMPARE(QJsonValue(right) == QJsonValue(left), result);
QCOMPARE(QJsonValue(right) != QJsonValue(left), !result);
+
+ // The same, but from a QJsonDocument perspective
+ QCOMPARE(QJsonDocument(left) == QJsonDocument(right), result);
+ QCOMPARE(QJsonDocument(left) != QJsonDocument(right), !result);
+ QCOMPARE(QJsonDocument(right) == QJsonDocument(left), result);
+ QCOMPARE(QJsonDocument(right) != QJsonDocument(left), !result);
}
void tst_QtJson::arrayEquals_data()
@@ -2606,12 +3103,65 @@ void tst_QtJson::arrayEquals()
QCOMPARE(QJsonValue(left) != QJsonValue(right), !result);
QCOMPARE(QJsonValue(right) == QJsonValue(left), result);
QCOMPARE(QJsonValue(right) != QJsonValue(left), !result);
+
+ // The same but from QJsonDocument perspective
+ QCOMPARE(QJsonDocument(left) == QJsonDocument(right), result);
+ QCOMPARE(QJsonDocument(left) != QJsonDocument(right), !result);
+ QCOMPARE(QJsonDocument(right) == QJsonDocument(left), result);
+ QCOMPARE(QJsonDocument(right) != QJsonDocument(left), !result);
+}
+
+void tst_QtJson::documentEquals_data()
+{
+ QTest::addColumn<QJsonDocument>("left");
+ QTest::addColumn<QJsonDocument>("right");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("two defaults") << QJsonDocument() << QJsonDocument() << true;
+
+ QJsonDocument emptyobj(QJsonObject{});
+ QJsonDocument emptyarr(QJsonArray{});
+ QTest::newRow("emptyarray vs default") << emptyarr << QJsonDocument() << false;
+ QTest::newRow("emptyobject vs default") << emptyobj << QJsonDocument() << false;
+ QTest::newRow("emptyarray vs emptyobject") << emptyarr << emptyobj << false;
+
+ QJsonDocument array1(QJsonArray{1});
+ QJsonDocument array2(QJsonArray{2});
+ QTest::newRow("emptyarray vs emptyarray") << emptyarr << emptyarr << true;
+ QTest::newRow("emptyarray vs array") << emptyarr << array1 << false;
+ QTest::newRow("array vs array") << array1 << array1 << true;
+ QTest::newRow("array vs otherarray") << array1 << array2 << false;
+
+ QJsonDocument object1(QJsonObject{{"hello", "world"}});
+ QJsonDocument object2(QJsonObject{{"hello", 2}});
+ QTest::newRow("emptyobject vs emptyobject") << emptyobj << emptyobj << true;
+ QTest::newRow("emptyobject vs object") << emptyobj << object1 << false;
+ QTest::newRow("object vs object") << object1 << object1 << true;
+ QTest::newRow("object vs otherobject") << object1 << object2 << false;
+
+ QTest::newRow("object vs array") << array1 << object1 << false;
+}
+
+void tst_QtJson::documentEquals()
+{
+ QFETCH(QJsonDocument, left);
+ QFETCH(QJsonDocument, right);
+ QFETCH(bool, result);
+
+ QCOMPARE(left == right, result);
+ QCOMPARE(right == left, result);
+
+ // invariants checks
+ QCOMPARE(left, left);
+ QCOMPARE(right, right);
+ QCOMPARE(left != right, !result);
+ QCOMPARE(right != left, !result);
}
void tst_QtJson::bom()
{
QFile file(testDataDir + "/bom.json");
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QByteArray json = file.readAll();
// Import json document into a QJsonDocument
@@ -2686,6 +3236,8 @@ void tst_QtJson::longStrings()
// test around 15 and 16 bit boundaries, as these are limits
// in the data structures (for Latin1String in qjson_p.h)
QString s(0x7ff0, 'a');
+ QByteArray ba(0x7ff0, 'a');
+ ba.append(0x8010 - 0x7ff0, 'c');
for (int i = 0x7ff0; i < 0x8010; i++) {
s.append(QLatin1Char('c'));
@@ -2702,9 +3254,21 @@ void tst_QtJson::longStrings()
/* ... and a QByteArray from the QJsonDocument */
QByteArray a2 = d2.toJson();
QCOMPARE(a1, a2);
+
+ // Test long keys
+ QJsonObject o1, o2;
+ o1[s] = 42;
+ o2[QLatin1String(ba.data(), i + 1)] = 42;
+ d1.setObject(o1);
+ d2.setObject(o2);
+ a1 = d1.toJson();
+ a2 = d2.toJson();
+ QCOMPARE(a1, a2);
}
s = QString(0xfff0, 'a');
+ ba = QByteArray(0xfff0, 'a');
+ ba.append(0x10010 - 0xfff0, 'c');
for (int i = 0xfff0; i < 0x10010; i++) {
s.append(QLatin1Char('c'));
@@ -2721,6 +3285,16 @@ void tst_QtJson::longStrings()
/* ... and a QByteArray from the QJsonDocument */
QByteArray a2 = d2.toJson();
QCOMPARE(a1, a2);
+
+ // Test long keys
+ QJsonObject o1, o2;
+ o1[s] = 42;
+ o2[QLatin1String(ba.data(), i + 1)] = 42;
+ d1.setObject(o1);
+ d2.setObject(o2);
+ a1 = d1.toJson();
+ a2 = d2.toJson();
+ QCOMPARE(a1, a2);
}
}
@@ -2743,9 +3317,6 @@ void tst_QtJson::testJsonValueRefDefault()
void tst_QtJson::arrayInitializerList()
{
-#ifndef Q_COMPILER_INITIALIZER_LISTS
- QSKIP("initializer_list is enabled only with c++11 support");
-#else
QVERIFY(QJsonArray{}.isEmpty());
QCOMPARE(QJsonArray{"one"}.count(), 1);
QCOMPARE(QJsonArray{1}.count(), 1);
@@ -2791,14 +3362,10 @@ void tst_QtJson::arrayInitializerList()
QCOMPARE(QJsonValue(a43["one"]), QJsonValue(1));
}
}
-#endif
}
void tst_QtJson::objectInitializerList()
{
-#ifndef Q_COMPILER_INITIALIZER_LISTS
- QSKIP("initializer_list is enabled only with c++11 support");
-#else
QVERIFY(QJsonObject{}.isEmpty());
{ // one property
@@ -2838,7 +3405,6 @@ void tst_QtJson::objectInitializerList()
QCOMPARE(QJsonValue(nested[0]), QJsonValue("innerValue"));
QCOMPARE(QJsonValue(nested[1]), QJsonValue(2.1));
}
-#endif
}
void tst_QtJson::unicodeKeys()
@@ -2916,7 +3482,7 @@ void tst_QtJson::documentFromVariant()
// As JSON arrays they should be equal.
QCOMPARE(da1.array(), da2.array());
-
+ QT_TEST_EQUALITY_OPS(da1, da2, true);
QMap <QString, QVariant> map;
map["key"] = string;
@@ -2932,6 +3498,7 @@ void tst_QtJson::documentFromVariant()
// As JSON objects they should be equal.
QCOMPARE(do1.object(), do2.object());
+ QT_TEST_EQUALITY_OPS(do1, do2, true);
}
void tst_QtJson::parseErrorOffset_data()
@@ -3011,5 +3578,420 @@ void tst_QtJson::implicitDocumentType()
QCOMPARE(arrayDocument[-1].toInt(123), 123);
}
+void tst_QtJson::streamSerializationQJsonDocument_data()
+{
+ QTest::addColumn<QJsonDocument>("document");
+ QTest::newRow("empty") << QJsonDocument();
+ QTest::newRow("object") << QJsonDocument(QJsonObject{{"value", 42}});
+}
+
+void tst_QtJson::streamSerializationQJsonDocument()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ QFETCH(QJsonDocument, document);
+ QJsonDocument output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << document;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, document);
+ QT_TEST_EQUALITY_OPS(output, document, true);
+}
+
+void tst_QtJson::streamSerializationQJsonArray_data()
+{
+ QTest::addColumn<QJsonArray>("array");
+ QTest::newRow("empty") << QJsonArray();
+ QTest::newRow("values") << QJsonArray{665, 666, 667};
+}
+
+void tst_QtJson::streamSerializationQJsonArray()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ QFETCH(QJsonArray, array);
+ QJsonArray output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << array;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, array);
+}
+
+void tst_QtJson::streamSerializationQJsonObject_data()
+{
+ QTest::addColumn<QJsonObject>("object");
+ QTest::newRow("empty") << QJsonObject();
+ QTest::newRow("non-empty") << QJsonObject{{"foo", 665}, {"bar", 666}};
+}
+
+void tst_QtJson::streamSerializationQJsonObject()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ QFETCH(QJsonObject, object);
+ QJsonObject output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << object;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, object);
+}
+
+void tst_QtJson::streamSerializationQJsonValue_data()
+{
+ QTest::addColumn<QJsonValue>("value");
+ QTest::newRow("double") << QJsonValue{665};
+ QTest::newRow("bool") << QJsonValue{true};
+ QTest::newRow("string") << QJsonValue{QStringLiteral("bum")};
+ QTest::newRow("array") << QJsonValue{QJsonArray{12,1,5,6,7}};
+ QTest::newRow("object") << QJsonValue{QJsonObject{{"foo", 665}, {"bar", 666}}};
+ // test json escape sequence
+ QTest::newRow("array with 0xD800") << QJsonValue(QJsonArray{QString(QChar(0xD800))});
+ QTest::newRow("array with 0xDF06,0xD834") << QJsonValue(QJsonArray{QString(QChar(0xDF06)).append(QChar(0xD834))});
+}
+
+void tst_QtJson::streamSerializationQJsonValue()
+{
+ QByteArray buffer;
+ QFETCH(QJsonValue, value);
+ QJsonValue output;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << value;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output, value);
+}
+
+void tst_QtJson::streamSerializationQJsonValueEmpty()
+{
+ QByteArray buffer;
+ {
+ QJsonValue undef{QJsonValue::Undefined};
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << undef;
+ QDataStream load(buffer);
+ QJsonValue output;
+ load >> output;
+ QVERIFY(output.isUndefined());
+ }
+ {
+ QJsonValue null{QJsonValue::Null};
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << null;
+ QDataStream load(buffer);
+ QJsonValue output;
+ load >> output;
+ QVERIFY(output.isNull());
+ }
+}
+
+void tst_QtJson::streamVariantSerialization()
+{
+ // Check interface only, implementation is tested through to and from
+ // json functions.
+ QByteArray buffer;
+ {
+ QJsonDocument objectDoc(QJsonArray{665, 666, 667});
+ QVariant output;
+ QVariant variant(objectDoc);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonDocument);
+ QCOMPARE(output.toJsonDocument(), objectDoc);
+ }
+ {
+ QJsonArray array{665, 666, 667};
+ QVariant output;
+ QVariant variant(array);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonArray);
+ QCOMPARE(output.toJsonArray(), array);
+ }
+ {
+ QJsonObject obj{{"foo", 42}};
+ QVariant output;
+ QVariant variant(obj);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonObject);
+ QCOMPARE(output.toJsonObject(), obj);
+ }
+ {
+ QJsonValue value{42};
+ QVariant output;
+ QVariant variant(value);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QJsonValue);
+ QCOMPARE(output.toJsonValue(), value);
+ }
+}
+
+void tst_QtJson::escapeSurrogateCodePoints_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<QByteArray>("escStr");
+ QTest::newRow("0xD800") << QString(QChar(0xD800)) << QByteArray("\\ud800");
+ QTest::newRow("0xDF06,0xD834") << QString(QChar(0xDF06)).append(QChar(0xD834)) << QByteArray("\\udf06\\ud834");
+}
+
+void tst_QtJson::escapeSurrogateCodePoints()
+{
+ QFETCH(QString, str);
+ QFETCH(QByteArray, escStr);
+ QJsonArray array;
+ array.append(str);
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << array;
+ // verify the buffer has escaped values
+ QVERIFY(buffer.contains(escStr));
+}
+
+void tst_QtJson::fromToVariantConversions_data()
+{
+ QTest::addColumn<QVariant>("variant");
+ QTest::addColumn<QJsonValue>("json");
+ QTest::addColumn<QVariant>("jsonToVariant");
+
+ QByteArray utf8("\xC4\x90\xC4\x81\xC5\xA3\xC3\xA2"); // Đāţâ
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUuid uuid = QUuid::createUuid();
+
+ constexpr qlonglong maxInt = std::numeric_limits<qlonglong>::max();
+ constexpr qlonglong minInt = std::numeric_limits<qlonglong>::min();
+ constexpr double maxDouble = std::numeric_limits<double>::max();
+ constexpr double minDouble = std::numeric_limits<double>::min();
+
+ QTest::newRow("default") << QVariant() << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+ QTest::newRow("nullptr") << QVariant::fromValue(nullptr) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+ QTest::newRow("bool") << QVariant(true) << QJsonValue(true) << QVariant(true);
+ QTest::newRow("int pos") << QVariant(123) << QJsonValue(123) << QVariant(qlonglong(123));
+ QTest::newRow("int neg") << QVariant(-123) << QJsonValue(-123) << QVariant(qlonglong(-123));
+ QTest::newRow("int big pos") << QVariant((1ll << 55) +1) << QJsonValue((1ll << 55) + 1)
+ << QVariant(qlonglong((1ll << 55) + 1));
+ QTest::newRow("int big neg") << QVariant(-(1ll << 55) + 1) << QJsonValue(-(1ll << 55) + 1)
+ << QVariant(qlonglong(-(1ll << 55) + 1));
+ QTest::newRow("int max") << QVariant(maxInt) << QJsonValue(maxInt) << QVariant(maxInt);
+ QTest::newRow("int min") << QVariant(minInt) << QJsonValue(minInt) << QVariant(minInt);
+ QTest::newRow("double pos") << QVariant(123.) << QJsonValue(123.) << QVariant(qlonglong(123.));
+ QTest::newRow("double neg") << QVariant(-123.) << QJsonValue(-123.)
+ << QVariant(qlonglong(-123.));
+ QTest::newRow("double big") << QVariant(maxDouble - 1000) << QJsonValue(maxDouble - 1000)
+ << QVariant(maxDouble - 1000);
+ QTest::newRow("double max") << QVariant(maxDouble) << QJsonValue(maxDouble)
+ << QVariant(maxDouble);
+ QTest::newRow("double min") << QVariant(minDouble) << QJsonValue(minDouble)
+ << QVariant(minDouble);
+ QTest::newRow("double big neg") << QVariant(1000 - maxDouble) << QJsonValue(1000 - maxDouble)
+ << QVariant(1000 - maxDouble);
+ QTest::newRow("double max neg") << QVariant(-maxDouble) << QJsonValue(-maxDouble)
+ << QVariant(-maxDouble);
+ QTest::newRow("double min neg") << QVariant(-minDouble) << QJsonValue(-minDouble)
+ << QVariant(-minDouble);
+
+ QTest::newRow("string null") << QVariant(QString()) << QJsonValue(QString())
+ << QVariant(QString());
+ QTest::newRow("string empty") << QVariant(QString("")) << QJsonValue(QString(""))
+ << QVariant(QString(""));
+ QTest::newRow("string ascii") << QVariant(QString("Data")) << QJsonValue(QString("Data"))
+ << QVariant(QString("Data"));
+ QTest::newRow("string utf8") << QVariant(QString(utf8)) << QJsonValue(QString(utf8))
+ << QVariant(QString(utf8));
+
+ QTest::newRow("bytearray null") << QVariant(QByteArray()) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+ QTest::newRow("bytearray empty") << QVariant(QByteArray()) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+ QTest::newRow("bytearray ascii") << QVariant(QByteArray("Data")) << QJsonValue(QString("Data"))
+ << QVariant(QString("Data"));
+ QTest::newRow("bytearray utf8") << QVariant(utf8) << QJsonValue(QString(utf8))
+ << QVariant(QString(utf8));
+
+ QTest::newRow("datetime") << QVariant(dt) << QJsonValue(dt.toString(Qt::ISODateWithMs))
+ << QVariant(dt.toString(Qt::ISODateWithMs));
+ QTest::newRow("url") << QVariant(QUrl("http://example.com/{q}"))
+ << QJsonValue("http://example.com/%7Bq%7D")
+ << QVariant(QString("http://example.com/%7Bq%7D"));
+ QTest::newRow("uuid") << QVariant(QUuid(uuid))
+ << QJsonValue(uuid.toString(QUuid::WithoutBraces))
+ << QVariant(uuid.toString(QUuid::WithoutBraces));
+ QTest::newRow("regexp") << QVariant(QRegularExpression(".")) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+
+ QTest::newRow("inf") << QVariant(qInf()) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+ QTest::newRow("-inf") << QVariant(-qInf()) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+ QTest::newRow("NaN") << QVariant(qQNaN()) << QJsonValue(QJsonValue::Null)
+ << QVariant::fromValue(nullptr);
+
+ static_assert(std::numeric_limits<double>::digits <= 63,
+ "double is too big on this platform, this test would fail");
+ constexpr quint64 Threshold = Q_UINT64_C(1) << 63;
+ const qulonglong ulongValue = qulonglong(Threshold) + 1;
+ const double uLongToDouble = Threshold;
+ QTest::newRow("ulonglong") << QVariant(ulongValue) << QJsonValue(uLongToDouble)
+ << QVariant(uLongToDouble);
+}
+
+void tst_QtJson::fromToVariantConversions()
+{
+ QFETCH(QVariant, variant);
+ QFETCH(QJsonValue, json);
+ QFETCH(QVariant, jsonToVariant);
+
+ QVariant variantFromJson(json);
+ QVariant variantFromJsonArray(QJsonArray { json });
+ QVariant variantFromJsonObject(QVariantMap { { "foo", variant } });
+
+ QJsonObject object { QPair<QString, QJsonValue>("foo", json) };
+
+ // QJsonValue <> QVariant
+ {
+ QCOMPARE(QJsonValue::fromVariant(variant), json);
+
+ // test the same for QVariant from QJsonValue/QJsonArray/QJsonObject
+ QCOMPARE(QJsonValue::fromVariant(variantFromJson), json);
+ QCOMPARE(QJsonValue::fromVariant(variantFromJsonArray), QJsonArray { json });
+ QCOMPARE(QJsonValue::fromVariant(variantFromJsonObject), object);
+
+ // QJsonValue to variant
+ QCOMPARE(json.toVariant(), jsonToVariant);
+ QCOMPARE(json.toVariant().userType(), jsonToVariant.userType());
+
+ // variant to QJsonValue
+ QCOMPARE(QVariant(json).toJsonValue(), json);
+ }
+
+ // QJsonArray <> QVariantList
+ {
+ QCOMPARE(QJsonArray::fromVariantList(QVariantList { variant }), QJsonArray { json });
+
+ // test the same for QVariantList from QJsonValue/QJsonArray/QJsonObject
+ QCOMPARE(QJsonArray::fromVariantList(QVariantList { variantFromJson }),
+ QJsonArray { json });
+ QCOMPARE(QJsonArray::fromVariantList(QVariantList { variantFromJsonArray }),
+ QJsonArray {{ QJsonArray { json } }});
+ QCOMPARE(QJsonArray::fromVariantList(QVariantList { variantFromJsonObject }),
+ QJsonArray { object });
+
+ // QJsonArray to variant
+ QCOMPARE(QJsonArray { json }.toVariantList(), QVariantList { jsonToVariant });
+ // variant to QJsonArray
+ QCOMPARE(QVariant(QJsonArray { json }).toJsonArray(), QJsonArray { json });
+ }
+
+ // QJsonObject <> QVariantMap
+ {
+ QCOMPARE(QJsonObject::fromVariantMap(QVariantMap { { "foo", variant } }), object);
+
+ // test the same for QVariantMap from QJsonValue/QJsonArray/QJsonObject
+ QCOMPARE(QJsonObject::fromVariantMap(QVariantMap { { "foo", variantFromJson } }), object);
+
+ QJsonObject nestedArray { QPair<QString, QJsonArray>("bar", QJsonArray { json }) };
+ QJsonObject nestedObject { QPair<QString, QJsonObject>("bar", object) };
+ QCOMPARE(QJsonObject::fromVariantMap(QVariantMap { { "bar", variantFromJsonArray } }),
+ nestedArray);
+ QCOMPARE(QJsonObject::fromVariantMap(QVariantMap { { "bar", variantFromJsonObject } }),
+ nestedObject);
+
+ // QJsonObject to variant
+ QCOMPARE(object.toVariantMap(), QVariantMap({ { "foo", jsonToVariant } }));
+ // variant to QJsonObject
+ QCOMPARE(QVariant(object).toJsonObject(), object);
+ }
+}
+
+void tst_QtJson::testIteratorComparison()
+{
+ QJsonObject t = QJsonObject::fromVariantHash({
+ { QStringLiteral("a"), QVariant(12) },
+ { QStringLiteral("b"), QVariant(13) }
+ });
+
+ QVERIFY(t.begin() == t.begin());
+ QVERIFY(t.begin() <= t.begin());
+ QVERIFY(t.begin() >= t.begin());
+ QVERIFY(!(t.begin() != t.begin()));
+ QVERIFY(!(t.begin() < t.begin()));
+ QVERIFY(!(t.begin() > t.begin()));
+
+ QVERIFY(!(t.begin() == t.end()));
+ QVERIFY(t.begin() <= t.end());
+ QVERIFY(!(t.begin() >= t.end()));
+ QVERIFY(t.begin() != t.end());
+ QVERIFY(t.begin() < t.end());
+ QVERIFY(!(t.begin() > t.end()));
+
+ QVERIFY(!(t.end() == t.begin()));
+ QVERIFY(!(t.end() <= t.begin()));
+ QVERIFY(t.end() >= t.begin());
+ QVERIFY(t.end() != t.begin());
+ QVERIFY(!(t.end() < t.begin()));
+ QVERIFY(t.end() > t.begin());
+}
+
+void tst_QtJson::noLeakOnNameClash_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QByteArray>("result");
+ QTest::addRow("simple")
+ << QStringLiteral("simple.duplicates.json")
+ << QByteArray(R"({"": 0})");
+ QTest::addRow("test")
+ << QStringLiteral("test.duplicates.json")
+ << QByteArray(R"([
+ "JSON Test Pattern pass1", {"a": ["array with 1 element"]}, {}, [], -42, true,
+ false, null, {"a": "A key can be any string"}, 0.5, 98.6, 99.44, 1066, 10, 1,
+ 0.1, 1, 2, 2, "rosebud", {"a": "bar"}, {"a": {"a": 2000}}, {"a": {"a": 2000}},
+ {"a": {"a": 2000}}, {"a": {"a": 2000}}
+ ])");
+ QTest::addRow("test3")
+ << QStringLiteral("test3.duplicates.json")
+ << QByteArray(R"({"a": [{"a": "212 555-1234"}, {"a": "646 555-4567"}]})");
+}
+
+void tst_QtJson::noLeakOnNameClash()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QByteArray, result);
+
+ QFile file(testDataDir + u'/' + fileName);
+ QVERIFY(file.open(QFile::ReadOnly));
+ QByteArray testJson = file.readAll();
+ QVERIFY(!testJson.isEmpty());
+
+ QJsonParseError error;
+
+ // Retains the last one of each set of duplicate keys.
+ QJsonDocument doc = QJsonDocument::fromJson(testJson, &error);
+ QVERIFY2(!doc.isNull(), qPrintable(error.errorString()));
+ QJsonDocument expected = QJsonDocument::fromJson(result, &error);
+ QVERIFY2(!expected.isNull(), qPrintable(error.errorString()));
+
+ QCOMPARE(doc, expected);
+ QT_TEST_EQUALITY_OPS(doc, expected, true);
+
+ // It should not leak.
+ // In particular it should not forget to deref the container for the inner objects.
+}
+
QTEST_MAIN(tst_QtJson)
#include "tst_qtjson.moc"
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt b/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt
new file mode 100644
index 0000000000..29a935977b
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborstreamreader/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcborstreamreader Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborstreamreader LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcborstreamreader
+ SOURCES
+ tst_qcborstreamreader.cpp
+ INCLUDE_DIRECTORIES
+ ../../../../../src/3rdparty/tinycbor/src
+ ../../../../../src/3rdparty/tinycbor/tests
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro b/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro
deleted file mode 100644
index 5df331314a..0000000000
--- a/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-QT = core testlib
-TARGET = tst_qcborstreamreader
-CONFIG += testcase
-SOURCES += \
- tst_qcborstreamreader.cpp
-
-INCLUDEPATH += \
- ../../../../../src/3rdparty/tinycbor/src \
- ../../../../../src/3rdparty/tinycbor/tests/parser
-
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
index 3dd4b5114c..63cfbce75f 100644
--- a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
+++ b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
@@ -1,44 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcborstream.h>
-#include <QtTest>
+#include <QTest>
+#include <QBuffer>
class tst_QCborStreamReader : public QObject
{
@@ -73,6 +38,8 @@ private Q_SLOTS:
void next();
void validation_data();
void validation();
+ void hugeDeviceValidation_data();
+ void hugeDeviceValidation();
void recursionLimit_data();
void recursionLimit();
@@ -80,6 +47,11 @@ private Q_SLOTS:
void addData_singleElement();
void addData_complex_data() { arrays_data(); }
void addData_complex();
+
+ void duplicatedData_data() { arrays_data(); }
+ void duplicatedData();
+ void extraData_data() { arrays_data(); }
+ void extraData();
};
#define FOR_CBOR_TYPE(F) \
@@ -114,7 +86,7 @@ template<> char *toString<QCborStreamReader::Type>(const QCborStreamReader::Type
QT_END_NAMESPACE
// Get the data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp)
-#include "data.cpp"
+#include "parser/data.cpp"
void tst_QCborStreamReader::initTestCase_data()
{
@@ -288,7 +260,10 @@ void tst_QCborStreamReader::integers()
void escapedAppendTo(QString &result, const QByteArray &data)
{
- result += "h'" + QString::fromLatin1(data.toHex()) + '\'';
+ QByteArray hex =
+ data.size() < 512*1024 ? data.toHex() :
+ "data of size " + QByteArray::number(data.size());
+ result += "h'" + QString::fromLatin1(hex) + '\'';
}
void escapedAppendTo(QString &result, const QString &data)
@@ -354,7 +329,7 @@ template <typename T> static inline bool canConvertTo(double v)
// integrals to floating-point with loss of precision has implementation-
// defined behavior whether the next higher or next lower is returned;
// converting FP to integral is UB if it can't be represented.;
- Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
+ static_assert(std::numeric_limits<T>::is_integer);
double supremum = ldexp(1, std::numeric_limits<T>::digits);
if (v >= supremum)
@@ -480,6 +455,28 @@ static QString parseOne(QCborStreamReader &reader)
return result;
}
+static QString parse(QCborStreamReader &reader, const QByteArray &data)
+{
+ qint64 oldPos = 0;
+ if (QIODevice *dev = reader.device())
+ oldPos = dev->pos();
+
+ QString r = parseOne(reader);
+ if (r.isEmpty())
+ return r;
+
+ if (reader.currentOffset() - oldPos != data.size())
+ r = QString("Number of parsed bytes (%1) not expected (%2)")
+ .arg(reader.currentOffset()).arg(data.size());
+ if (QIODevice *dev = reader.device()) {
+ if (dev->pos() - oldPos != data.size())
+ r = QString("QIODevice not advanced (%1) as expected (%2)")
+ .arg(dev->pos()).arg(data.size());
+ }
+
+ return r;
+}
+
bool parseNonRecursive(QString &result, bool &printingStringChunks, QCborStreamReader &reader)
{
while (reader.lastError() == QCborError::NoError) {
@@ -612,13 +609,13 @@ void tst_QCborStreamReader::fixed()
}
QVERIFY(reader.isValid());
QCOMPARE(reader.lastError(), QCborError::NoError);
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
// verify that we can re-read
reader.reset();
QVERIFY(reader.isValid());
QCOMPARE(reader.lastError(), QCborError::NoError);
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
}
void tst_QCborStreamReader::strings_data()
@@ -658,6 +655,7 @@ void tst_QCborStreamReader::strings()
QCOMPARE(reader.currentStringChunkSize(), qsizetype(reader.length()));
int chunks = 0;
+ QByteArray fullString;
forever {
QCborStreamReader::StringResult<QByteArray> controlData;
if (reader.isString()) {
@@ -668,6 +666,7 @@ void tst_QCborStreamReader::strings()
controlData = controlReader.readByteArray();
}
QVERIFY(controlData.status != QCborStreamReader::Error);
+ fullString += controlData.data;
for (int i = 0; i < 10; ++i) {
// this call must work several times with the same result
@@ -690,6 +689,43 @@ void tst_QCborStreamReader::strings()
if (!isChunked)
QCOMPARE(chunks, 1);
+
+ // Now re-do and compare with toString() and toByteArray(), against
+ // the control data we calculated above
+ reader.reset();
+ QVERIFY(reader.isString() || reader.isByteArray());
+ if (reader.isByteArray()) {
+ QByteArray prefix("some prefix");
+ QByteArray ba = prefix;
+ QVERIFY(reader.readAndAppendToByteArray(ba));
+ QCOMPARE(ba, prefix + fullString);
+ } else {
+ QString prefix("some prefix");
+ QString str = prefix;
+ QVERIFY(reader.readAndAppendToString(str));
+ QCOMPARE(str, prefix + QString::fromUtf8(fullString));
+ }
+
+ // Re-do again using the UTF-8 interface.
+ reader.reset();
+ QVERIFY(reader.isString() || reader.isByteArray());
+ if (reader.isString()) {
+ QByteArray prefix("some prefix");
+ QByteArray utf8 = prefix;
+ QVERIFY(reader.readAndAppendToUtf8String(utf8));
+ QCOMPARE(utf8, prefix + fullString);
+
+ reader.reset();
+ fullString = prefix;
+ forever {
+ auto r = reader.readUtf8String();
+ QCOMPARE_NE(r.status, QCborStreamReader::Error);
+ fullString += r.data;
+ if (r.status == QCborStreamReader::EndOfString)
+ break;
+ }
+ QCOMPARE(fullString, utf8);
+ }
}
void tst_QCborStreamReader::tags_data()
@@ -721,7 +757,7 @@ void tst_QCborStreamReader::emptyContainers()
QCOMPARE(reader.lastError(), QCborError::NoError);
if (reader.isLengthKnown())
QCOMPARE(reader.length(), 0U);
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
// verify that we can re-read
reader.reset();
@@ -729,7 +765,7 @@ void tst_QCborStreamReader::emptyContainers()
QCOMPARE(reader.lastError(), QCborError::NoError);
if (reader.isLengthKnown())
QCOMPARE(reader.length(), 0U);
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
}
void tst_QCborStreamReader::arrays_data()
@@ -758,7 +794,7 @@ static void checkContainer(int len, const QByteArray &data, const QString &expec
QVERIFY(reader.isLengthKnown());
QCOMPARE(reader.length(), uint(len));
}
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
// verify that we can re-read
reader.reset();
@@ -768,7 +804,7 @@ static void checkContainer(int len, const QByteArray &data, const QString &expec
QVERIFY(reader.isLengthKnown());
QCOMPARE(reader.length(), uint(len));
}
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
}
void tst_QCborStreamReader::arrays()
@@ -875,16 +911,26 @@ void tst_QCborStreamReader::next()
QVERIFY(doit("\xbf\x9f\1\xff\x9f" + data + "\xff\xff"));
}
+#include "../cborlargedatavalidation.cpp"
+
void tst_QCborStreamReader::validation_data()
{
+ // Add QCborStreamReader-specific limitations due to use of QByteArray and
+ // QString, which are allocated by QArrayData::allocate().
+ const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max();
+ const qsizetype MinInvalid = QByteArray::max_size() + 1;
+
addValidationColumns();
- addValidationData();
+ addValidationData(MinInvalid);
+ addValidationLargeData(MinInvalid, MaxInvalid);
}
void tst_QCborStreamReader::validation()
{
QFETCH_GLOBAL(bool, useDevice);
QFETCH(QByteArray, data);
+ QFETCH(CborError, expectedError);
+ QCborError error = { QCborError::Code(expectedError) };
QBuffer buffer(&data);
QCborStreamReader reader(data);
@@ -892,13 +938,103 @@ void tst_QCborStreamReader::validation()
buffer.open(QIODevice::ReadOnly);
reader.setDevice(&buffer);
}
- parseOne(reader);
- QVERIFY(reader.lastError() != QCborError::NoError);
+ parse(reader, data);
+ QCOMPARE(reader.lastError(), error);
// next() should fail
reader.reset();
QVERIFY(!reader.next());
- QVERIFY(reader.lastError() != QCborError::NoError);
+ QCOMPARE(reader.lastError(), error);
+
+ // check toString() and toByteArray() too
+ if (reader.isString() || reader.isByteArray()) {
+ reader.reset();
+ if (reader.isString()) {
+ QString prefix = "some prefix";
+ QString str = prefix;
+ QVERIFY(!reader.readAndAppendToString(str));
+ QVERIFY(str.startsWith(prefix)); // but may have decoded some
+ } else if (reader.isByteArray()) {
+ QByteArray prefix = "some prefix";
+ QByteArray ba = prefix;
+ QVERIFY(!reader.readAndAppendToByteArray(ba));
+ QVERIFY(ba.startsWith(prefix)); // but may have decoded some
+ }
+ QCOMPARE(reader.lastError(), error);
+
+ reader.reset();
+ if (reader.isString())
+ QVERIFY(reader.readAllString().isNull());
+ else
+ QVERIFY(reader.readAllByteArray().isNull());
+ }
+
+ reader.reset();
+
+ // and the UTF-8 API
+ if (reader.isString()) {
+ QByteArray prefix = "some prefix";
+ QByteArray ba = prefix;
+ QVERIFY(!reader.readAndAppendToUtf8String(ba));
+ QVERIFY(ba.startsWith(prefix)); // but may have decoded some
+ QCOMPARE(reader.lastError(), error);
+
+ reader.reset();
+ QVERIFY(reader.readAllUtf8String().isNull());
+
+ reader.reset();
+ auto r = reader.readUtf8String();
+ for ( ; r.status == QCborStreamReader::Ok; r = reader.readUtf8String()) {
+ // while the data is valid...
+ QVERIFY(!r.data.isNull());
+ }
+ QCOMPARE_NE(r.status, QCborStreamReader::EndOfString);
+ QCOMPARE(reader.lastError(), error);
+ }
+}
+
+void tst_QCborStreamReader::hugeDeviceValidation_data()
+{
+ addValidationHugeDevice(QByteArray::max_size() + 1, QString::max_size() + 1);
+}
+
+void tst_QCborStreamReader::hugeDeviceValidation()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ if (!useDevice)
+ return;
+
+#if (defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
+ if ( qstrcmp(QTest::currentDataTag(), "bytearray-just-too-big") == 0
+ || qstrcmp(QTest::currentDataTag(), "string-just-too-big") == 0)
+ QSKIP("This test tries to allocate a huge memory buffer,"
+ " which Address Sanitizer flags as a problem");
+#endif
+#if defined(Q_OS_WASM)
+ QSKIP("This test tries to allocate a huge memory buffer,"
+ " causes problem on WebAssembly platform which has limited resources.");
+#endif // Q_OS_WASM
+
+ QFETCH(QSharedPointer<QIODevice>, device);
+ QFETCH(CborError, expectedError);
+ QFETCH(CborError, expectedValidationError);
+ QCborError error = { QCborError::Code(expectedError) };
+
+ device->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+ QCborStreamReader reader(device.data());
+
+ QVERIFY(parseOne(reader).isEmpty());
+ QCOMPARE(reader.lastError(), error);
+
+ reader.reset();
+ error = { QCborError::Code(expectedValidationError) };
+ if (error == QCborError{}) {
+ // this test actually succeeds, so don't do it to avoid large memory consumption
+ } else {
+ // next() should fail
+ QVERIFY(!reader.next());
+ QCOMPARE(reader.lastError(), error);
+ }
}
static const int Recursions = 3;
@@ -997,7 +1133,7 @@ void tst_QCborStreamReader::addData_singleElement()
reader.addData(data.constData() + i, 1);
}
- parseOne(reader);
+ parse(reader, data);
QCOMPARE(reader.lastError(), QCborError::EndOfFile);
}
@@ -1009,7 +1145,7 @@ void tst_QCborStreamReader::addData_singleElement()
reader.addData(data.right(1));
}
QCOMPARE(reader.lastError(), QCborError::NoError);
- QCOMPARE(parseOne(reader), expected);
+ QCOMPARE(parse(reader, data), expected);
}
void tst_QCborStreamReader::addData_complex()
@@ -1085,6 +1221,69 @@ void tst_QCborStreamReader::addData_complex()
"{1, [" + expected + ", " + expected + "]}");
}
+void tst_QCborStreamReader::duplicatedData()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ // double the data up
+ QByteArray doubledata = data + data;
+
+ QBuffer buffer(&doubledata);
+ QCborStreamReader reader(doubledata);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QCOMPARE(parse(reader, data), expected); // yes, data
+
+ QVERIFY(reader.currentOffset() < doubledata.size());
+ if (useDevice) {
+ reader.setDevice(&buffer);
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QCOMPARE(parse(reader, data), expected);
+ QCOMPARE(buffer.pos(), doubledata.size());
+ } else {
+ // there's no reader.setData()
+ }
+}
+
+void tst_QCborStreamReader::extraData()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ QByteArray extension(9, '\0');
+
+ // stress test everything with extra bytes (just one byte changing;
+ // TinyCBOR used to have a bug where the next byte got sometimes read)
+ for (int c = '\0'; c < 0x100; ++c) {
+ extension[0] = c;
+ QByteArray extendeddata = data + extension;
+
+ QBuffer buffer(&extendeddata);
+ QCborStreamReader reader(extendeddata);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QCOMPARE(parse(reader, data), expected); // yes, data
+
+ // if we were a parser, we could parse the next payload
+ if (useDevice)
+ QCOMPARE(buffer.readAll(), extension);
+ }
+}
+
QTEST_MAIN(tst_QCborStreamReader)
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt b/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt
new file mode 100644
index 0000000000..c1a9a87677
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborstreamwriter/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcborstreamwriter Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborstreamwriter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcborstreamwriter
+ SOURCES
+ tst_qcborstreamwriter.cpp
+ INCLUDE_DIRECTORIES
+ ../../../../../src/3rdparty/tinycbor/tests
+)
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro b/tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro
deleted file mode 100644
index 3391b5a296..0000000000
--- a/tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT = core testlib
-TARGET = tst_qcborstreamwriter
-CONFIG += testcase
-SOURCES += \
- tst_qcborstreamwriter.cpp
-
-INCLUDEPATH += ../../../../../src/3rdparty/tinycbor/tests/encoder
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp b/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
index 6995b4d08b..45e241ef5c 100644
--- a/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
+++ b/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
@@ -1,43 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QCborStreamWriter>
+#include <QBuffer>
class tst_QCborStreamWriter : public QObject
{
@@ -63,39 +29,39 @@ private Q_SLOTS:
// Get the data from TinyCBOR (see src/3rdparty/tinycbor/tests/encoder/data.cpp)
typedef quint64 CborTag;
-#include "data.cpp"
+#include "encoder/data.cpp"
void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
{
int type = v.userType();
switch (type) {
- case QVariant::Int:
- case QVariant::LongLong:
+ case QMetaType::Int:
+ case QMetaType::LongLong:
return writer.append(v.toLongLong());
- case QVariant::UInt:
- case QVariant::ULongLong:
+ case QMetaType::UInt:
+ case QMetaType::ULongLong:
return writer.append(v.toULongLong());
- case QVariant::Bool:
+ case QMetaType::Bool:
return writer.append(v.toBool());
- case QVariant::Invalid:
+ case QMetaType::UnknownType:
return writer.appendUndefined();
case QMetaType::VoidStar:
return writer.append(nullptr);
- case QVariant::Double:
+ case QMetaType::Double:
return writer.append(v.toDouble());
case QMetaType::Float:
return writer.append(v.toFloat());
- case QVariant::String:
+ case QMetaType::QString:
return writer.append(v.toString());
- case QVariant::ByteArray:
+ case QMetaType::QByteArray:
return writer.append(v.toByteArray());
default:
@@ -109,15 +75,15 @@ void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
writer.append(QCborTag(v.value<Tag>().tag));
return encodeVariant(writer, v.value<Tag>().tagged);
}
- if (type == QVariant::List || type == qMetaTypeId<IndeterminateLengthArray>()) {
+ if (type == QMetaType::QVariantList || type == qMetaTypeId<IndeterminateLengthArray>()) {
QVariantList list = v.toList();
if (type == qMetaTypeId<IndeterminateLengthArray>()) {
list = v.value<IndeterminateLengthArray>();
writer.startArray();
} else {
- writer.startArray(list.length());
+ writer.startArray(list.size());
}
- for (const QVariant &v2 : qAsConst(list))
+ for (const QVariant &v2 : std::as_const(list))
encodeVariant(writer, v2);
QVERIFY(writer.endArray());
return;
@@ -128,9 +94,9 @@ void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
map = v.value<IndeterminateLengthMap>();
writer.startMap();
} else {
- writer.startMap(map.length());
+ writer.startMap(map.size());
}
- for (auto pair : qAsConst(map)) {
+ for (auto pair : std::as_const(map)) {
encodeVariant(writer, pair.first);
encodeVariant(writer, pair.second);
}
@@ -191,7 +157,7 @@ void tst_QCborStreamWriter::nonAsciiStrings_data()
QTest::addColumn<QString>("input");
QTest::addColumn<bool>("isLatin1");
- QByteArray latin1 = u8"Résumé";
+ QByteArray latin1 = "Résumé";
QTest::newRow("shortlatin1")
<< ("\x68" + latin1) << QString::fromUtf8(latin1) << true;
@@ -200,7 +166,7 @@ void tst_QCborStreamWriter::nonAsciiStrings_data()
QTest::newRow("longlatin1")
<< ("\x78\x28" + latin1) << QString::fromUtf8(latin1) << true;
- QByteArray nonlatin1 = u8"Χαίρετε";
+ QByteArray nonlatin1 = "Χαίρετε";
QTest::newRow("shortnonlatin1")
<< ("\x6e" + nonlatin1) << QString::fromUtf8(nonlatin1) << false;
diff --git a/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt
new file mode 100644
index 0000000000..4b72396489
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborvalue/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcborvalue Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborvalue LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcborvalue
+ SOURCES
+ tst_qcborvalue.cpp
+ INCLUDE_DIRECTORIES
+ ../../../../../src/3rdparty/tinycbor/src
+ ../../../../../src/3rdparty/tinycbor/tests/parser
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro
deleted file mode 100644
index 9dd67da1f0..0000000000
--- a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-QT = core testlib
-TARGET = tst_qcborvalue
-CONFIG += testcase
-SOURCES += \
- tst_qcborvalue.cpp
-
-INCLUDEPATH += \
- ../../../../../src/3rdparty/tinycbor/src \
- ../../../../../src/3rdparty/tinycbor/tests/parser
-
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
index 4b753eab6b..23b25834b9 100644
--- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -1,48 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcborvalue.h>
-#include <QtTest>
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QBuffer>
+#include <QCborStreamReader>
+#include <QCborStreamWriter>
+#include <QDateTime>
+#include <QtEndian>
+#include <QTimeZone>
+
+Q_DECLARE_METATYPE(QCborKnownTags)
Q_DECLARE_METATYPE(QCborValue)
Q_DECLARE_METATYPE(QCborValue::EncodingOptions)
+using namespace Qt::StringLiterals;
+
class tst_QCborValue : public QObject
{
Q_OBJECT
@@ -54,15 +29,21 @@ private slots:
void tagged();
void extendedTypes_data();
void extendedTypes();
+ void compareCompiles();
void copyCompare_data() { basics_data(); }
void copyCompare();
void arrayDefaultInitialization();
void arrayEmptyInitializerList();
void arrayEmptyDetach();
+ void arrayNonEmptyDetach();
void arrayInitializerList();
void arrayMutation();
+ void arrayMutateWithCopies();
void arrayPrepend();
+ void arrayValueRef_data() { basics_data(); }
+ void arrayValueRef();
+ void arrayValueRefLargeKey();
void arrayInsertRemove_data() { basics_data(); }
void arrayInsertRemove();
void arrayInsertTagged_data() { basics_data(); }
@@ -70,14 +51,25 @@ private slots:
void arrayStringElements();
void arraySelfAssign_data() { basics_data(); }
void arraySelfAssign();
+ void arrayNested();
void mapDefaultInitialization();
void mapEmptyInitializerList();
void mapEmptyDetach();
+ void mapNonEmptyDetach();
void mapSimpleInitializerList();
+ void mapFromArrayLargeIntKey_data() { basics_data(); }
+ void mapFromArrayLargeIntKey();
+ void mapFromArrayNegativeIntKey_data() { basics_data(); }
+ void mapFromArrayNegativeIntKey();
+ void mapFromArrayStringKey_data() { basics_data(); }
+ void mapFromArrayStringKey();
void mapMutation();
+ void mapMutateWithCopies();
void mapStringValues();
void mapStringKeys();
+ void mapValueRef_data() { basics_data(); }
+ void mapValueRef();
void mapInsertRemove_data() { basics_data(); }
void mapInsertRemove();
void mapInsertTagged_data() { basics_data(); }
@@ -86,19 +78,134 @@ private slots:
void mapSelfAssign();
void mapComplexKeys_data() { basics_data(); }
void mapComplexKeys();
+ void mapNested();
+ void sorting_data();
void sorting();
+ void comparisonMap_data();
+ void comparisonMap();
void toCbor_data();
void toCbor();
+ void toCborStreamWriter_data() { toCbor_data(); }
+ void toCborStreamWriter();
void fromCbor_data();
void fromCbor();
+ void fromCborStreamReaderByteArray_data() { fromCbor_data(); }
+ void fromCborStreamReaderByteArray();
+ void fromCborStreamReaderIODevice_data() { fromCbor_data(); }
+ void fromCborStreamReaderIODevice();
void validation_data();
void validation();
+ void extendedTypeValidation_data();
+ void extendedTypeValidation();
+ void hugeDeviceValidation_data();
+ void hugeDeviceValidation();
+ void recursionLimit_data();
+ void recursionLimit();
void toDiagnosticNotation_data();
void toDiagnosticNotation();
+
+ void cborValueRef_data();
+ void cborValueRef();
+ void cborValueConstRef_data() { cborValueRef_data(); }
+ void cborValueConstRef();
+ void cborValueRefMutatingArray_data() { cborValueRef_data(); }
+ void cborValueRefMutatingArray();
+ void cborValueRefMutatingMapIntKey_data() { cborValueRef_data(); }
+ void cborValueRefMutatingMapIntKey();
+ void cborValueRefMutatingMapLatin1StringKey_data() { cborValueRef_data(); }
+ void cborValueRefMutatingMapLatin1StringKey();
+ void cborValueRefMutatingMapStringKey_data() { cborValueRef_data(); }
+ void cborValueRefMutatingMapStringKey();
+
+ void datastreamSerialization_data();
+ void datastreamSerialization();
+ void streamVariantSerialization();
+ void debugOutput_data();
+ void debugOutput();
+ void testlibFormatting_data();
+ void testlibFormatting();
};
+namespace SimpleEncodeToCbor {
+inline size_t lengthOf(int)
+{
+ return 1; // encode as byte
+}
+
+template <unsigned N> inline size_t lengthOf(const char (&)[N])
+{
+ return N - 1;
+}
+
+
+inline size_t lengthOf(const char *str)
+{
+ return strlen(str);
+}
+
+template <typename T> inline size_t lengthOf(T)
+{
+ return sizeof(T);
+}
+
+static void encodeOneAt(char *ptr, int v, size_t)
+{
+ // encode as byte
+ *ptr = char(v);
+}
+
+static void encodeOneAt(char *ptr, const char *v, size_t size)
+{
+ memcpy(ptr, v, size);
+}
+
+template <typename T>
+static typename std::enable_if<std::is_unsigned<T>::value>::type
+encodeOneAt(char *ptr, T v, size_t)
+{
+ qToBigEndian(v, ptr);
+}
+
+template <typename T>
+static typename std::enable_if<std::is_floating_point<T>::value ||
+ std::is_same<T, qfloat16>::value>::type
+encodeOneAt(char *ptr, T v, size_t)
+{
+ typename QIntegerForSizeof<T>::Unsigned u;
+ memcpy(&u, &v, sizeof(u));
+ qToBigEndian(u, ptr);
+}
+
+static char *encodeAt(char *ptr)
+{
+ return ptr;
+}
+
+template <typename Arg0, typename... Args>
+static char *encodeAt(char *ptr, Arg0 a0, Args... a)
+{
+ encodeOneAt(ptr, a0, lengthOf(a0));
+ return encodeAt(ptr + lengthOf(a0), a...);
+}
+
+} // namespace SimpleEncodetoCbor
+
+template <typename... Args>
+static QByteArray encode(Args... a)
+{
+ // this would be much easier with C++17 fold expressions...
+ using namespace SimpleEncodeToCbor;
+ using namespace std;
+ size_t lengths[] = { lengthOf(a)... };
+ size_t total = accumulate(begin(lengths), end(lengths), size_t(0), plus<size_t>{});
+ QByteArray result(QByteArray::size_type(total), Qt::Uninitialized);
+ char *ptr = result.data();
+ encodeAt(ptr, a...);
+ return result;
+}
+
// Get the validation data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp)
#include "data.cpp"
@@ -128,7 +235,7 @@ void tst_QCborValue::basics_data()
if (t == QCborValue::Double)
return QTest::addRow("Double:%g", exp.toDouble());
if (t == QCborValue::ByteArray || t == QCborValue::String)
- return QTest::addRow("%s:%d", typeString, exp.toString().size());
+ return QTest::addRow("%s:%zd", typeString, size_t(exp.toString().size()));
return QTest::newRow(typeString);
};
addRow() << t << v << exp;
@@ -192,6 +299,7 @@ static void basicTypeCheck(QCborValue::Type type, const QCborValue &v, const QVa
QCOMPARE(v.isDouble(), type == QCborValue::Double);
QCOMPARE(v.isDateTime(), type == QCborValue::DateTime);
QCOMPARE(v.isUrl(), type == QCborValue::Url);
+ QCOMPARE(v.isRegularExpression(), type == QCborValue::RegularExpression);
QCOMPARE(v.isUuid(), type == QCborValue::Uuid);
QCOMPARE(v.isInvalid(), type == QCborValue::Invalid);
QCOMPARE(v.isContainer(), type == QCborValue::Array || type == QCborValue::Map);
@@ -284,36 +392,109 @@ void tst_QCborValue::tagged()
void tst_QCborValue::extendedTypes_data()
{
QTest::addColumn<QCborValue>("extended");
- QTest::addColumn<QCborValue>("tagged");
+ QTest::addColumn<QCborKnownTags>("tag");
+ QTest::addColumn<QCborValue>("taggedValue");
+ QTest::addColumn<QCborValue>("correctedTaggedValue");
+ QCborValue v(QCborValue::Invalid);
QDateTime dt = QDateTime::currentDateTimeUtc();
+ QDateTime dtTzOffset(dt.date(), dt.time(), QTimeZone::fromSecondsAheadOfUtc(dt.offsetFromUtc()));
QUuid uuid = QUuid::createUuid();
+ // non-correcting extended types (tagged value remains unchanged)
QTest::newRow("DateTime") << QCborValue(dt)
- << QCborValue(QCborKnownTags::DateTimeString, dt.toString(Qt::ISODateWithMs));
+ << QCborKnownTags::DateTimeString << QCborValue(dt.toString(Qt::ISODateWithMs)) << v;
+ QTest::newRow("DateTime:TzOffset") << QCborValue(dtTzOffset)
+ << QCborKnownTags::DateTimeString << QCborValue(dtTzOffset.toString(Qt::ISODateWithMs)) << v;
QTest::newRow("Url:Empty") << QCborValue(QUrl())
- << QCborValue(QCborKnownTags::Url, QString());
+ << QCborKnownTags::Url << QCborValue(QString()) << v;
QTest::newRow("Url:Authority") << QCborValue(QUrl("https://example.com"))
- << QCborValue(QCborKnownTags::Url, "https://example.com");
+ << QCborKnownTags::Url << QCborValue("https://example.com") << v;
QTest::newRow("Url:Path") << QCborValue(QUrl("file:///tmp/none"))
- << QCborValue(QCborKnownTags::Url, "file:///tmp/none");
+ << QCborKnownTags::Url << QCborValue("file:///tmp/none") << v;
QTest::newRow("Url:QueryFragment") << QCborValue(QUrl("whatever:?a=b&c=d#e"))
- << QCborValue(QCborKnownTags::Url, "whatever:?a=b&c=d#e");
+ << QCborKnownTags::Url << QCborValue("whatever:?a=b&c=d#e") << v;
QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression())
- << QCborValue(QCborKnownTags::RegularExpression, QString());
+ << QCborKnownTags::RegularExpression << QCborValue(QString()) << v;
QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$"))
- << QCborValue(QCborKnownTags::RegularExpression, QString("^.*$"));
+ << QCborKnownTags::RegularExpression << QCborValue(QString("^.*$")) << v;
QTest::newRow("Uuid") << QCborValue(uuid)
- << QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122());
+ << QCborKnownTags::Uuid << QCborValue(uuid.toRfc4122()) << v;
+
+ // correcting extended types
+ QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), QTimeZone::UTC);
+ QUrl url("https://example.com/\xc2\xa9 ");
+ QTest::newRow("UnixTime_t:Integer") << QCborValue(dtNoMsecs) << QCborKnownTags::UnixTime_t
+ << QCborValue(dtNoMsecs.toSecsSinceEpoch())
+ << QCborValue(dtNoMsecs.toString(Qt::ISODateWithMs));
+ QTest::newRow("UnixTime_t:Double") << QCborValue(dt) << QCborKnownTags::UnixTime_t
+ << QCborValue(dt.toMSecsSinceEpoch() / 1000.)
+ << QCborValue(dt.toString(Qt::ISODateWithMs));
+ QTest::newRow("DateTime::JustDate") << QCborValue(QDateTime({2018, 1, 1}, {}))
+ << QCborKnownTags::DateTimeString
+ << QCborValue("2018-01-01") << QCborValue("2018-01-01T00:00:00.000");
+ QTest::newRow("DateTime::TzOffset")
+ << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::UTC))
+ << QCborKnownTags::DateTimeString
+ << QCborValue("2018-01-01T09:00:00.000+00:00")
+ << QCborValue("2018-01-01T09:00:00.000Z");
+ QTest::newRow("Url:NotNormalized") << QCborValue(url) << QCborKnownTags::Url
+ << QCborValue("HTTPS://EXAMPLE.COM/%c2%a9%20")
+ << QCborValue(url.toString());
+ QTest::newRow("Uuid:Zero") << QCborValue(QUuid()) << QCborKnownTags::Uuid
+ << QCborValue(QByteArray())
+ << QCborValue(QByteArray(sizeof(QUuid), 0));
+ QTest::newRow("Uuid:TooShort") << QCborValue(QUuid(0x12345678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ << QCborKnownTags::Uuid
+ << QCborValue(raw("\x12\x34\x56\x78"))
+ << QCborValue(raw("\x12\x34\x56\x78" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0"));
+ QTest::newRow("Uuid:TooLong") << QCborValue(uuid) << QCborKnownTags::Uuid
+ << QCborValue(uuid.toRfc4122() + "\1\2\3\4") << QCborValue(uuid.toRfc4122());
+}
+
+void tst_QCborValue::compareCompiles()
+{
+ // homogeneous types
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::Iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::ConstIterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap::Iterator>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap::ConstIterator>();
+
+ // QCborValue, Ref and ConstRef
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef, QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueConstRef, QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef, QCborValue>();
+
+ // QCbor{Array,Map} <=> QCborValue{,Ref,ConstRef}
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray, QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray, QCborValueRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray, QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValue>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValueRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValueConstRef>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::Iterator,
+ QCborArray::ConstIterator>();
}
void tst_QCborValue::extendedTypes()
{
QFETCH(QCborValue, extended);
- QFETCH(QCborValue, tagged);
+ QFETCH(QCborKnownTags, tag);
+ QFETCH(QCborValue, taggedValue);
+ QFETCH(QCborValue, correctedTaggedValue);
+ if (correctedTaggedValue.isInvalid())
+ correctedTaggedValue = taggedValue;
+
+ QCborValue tagged(tag, taggedValue);
QVERIFY(extended.isTag());
QVERIFY(tagged.isTag());
- QVERIFY(extended == tagged);
- QVERIFY(tagged == extended);
+ QCOMPARE(tagged.taggedValue(), correctedTaggedValue);
+ QCOMPARE(tagged, extended);
+ QCOMPARE(extended, tagged);
QCOMPARE(extended.tag(), tagged.tag());
QCOMPARE(extended.taggedValue(), tagged.taggedValue());
@@ -323,26 +504,36 @@ void tst_QCborValue::copyCompare()
{
QFETCH(QCborValue, v);
QCborValue other = v;
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-move")
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1301
+QT_WARNING_DISABLE_GCC("-Wself-move")
+#endif
+ // self-moving
+ v = std::move(v);
+ QCOMPARE(v, other); // make sure it's still valid
+ QT_TEST_ALL_COMPARISON_OPS(v, other, Qt::strong_ordering::equal);
+QT_WARNING_POP
+
+ // moving
+ v = std::move(other);
+ other = std::move(v);
+
+ // normal copying
+ other = v;
other = v;
v = other;
QCOMPARE(v.compare(other), 0);
- QCOMPARE(v, other);
- QVERIFY(!(v != other));
- QVERIFY(!(v < other));
-#if 0 && QT_HAS_INCLUDE(<compare>)
- QVERIFY(v <= other);
- QVERIFY(v >= other);
- QVERIFY(!(v > other));
-#endif
+ QT_TEST_ALL_COMPARISON_OPS(v, other, Qt::strong_ordering::equal);
if (v.isUndefined())
other = nullptr;
else
other = {};
QVERIFY(v.type() != other.type());
- QVERIFY(!(v == other));
- QVERIFY(v != other);
+ QT_TEST_EQUALITY_OPS(v, other, false);
// they're different types, so they can't compare equal
QVERIFY(v.compare(other) != 0);
@@ -372,19 +563,24 @@ void tst_QCborValue::arrayDefaultInitialization()
QVERIFY(a.at(0).isUndefined());
QCOMPARE(a.constBegin(), a.constEnd());
- QVERIFY(a == a);
- QVERIFY(a == QCborArray());
- QVERIFY(QCborArray() == a);
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray(), true);
QCborValue v(a);
QVERIFY(v.isArray());
QVERIFY(!v.isMap());
QVERIFY(!v.isTag());
- QVERIFY(v[0].isUndefined());
QCborArray a2 = v.toArray();
QVERIFY(a2.isEmpty());
- QCOMPARE(a2, a);
+ QT_TEST_EQUALITY_OPS(a2, a, true);
+ auto front = v[0];
+ QVERIFY(front.isUndefined());
+ front = 1;
+ QCOMPARE(v[0], 1);
+ QVERIFY(a2.isEmpty());
+ a2 = v.toArray();
+ QCOMPARE(a2.size(), 1);
}
void tst_QCborValue::mapDefaultInitialization()
@@ -417,11 +613,10 @@ void tst_QCborValue::mapDefaultInitialization()
QVERIFY(m.value("Hello").isUndefined());
#endif
- QVERIFY(m == m);
- QVERIFY(m == QCborMap{});
- QVERIFY(QCborMap{} == m);
+ QT_TEST_EQUALITY_OPS(m, m, true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap{}, true);
- QCborValue v(m);
+ const QCborValue v(m);
QVERIFY(v.isMap());
QVERIFY(!v.isArray());
QVERIFY(!v.isTag());
@@ -432,7 +627,7 @@ void tst_QCborValue::mapDefaultInitialization()
QCborMap m2 = v.toMap();
QVERIFY(m2.isEmpty());
QCOMPARE(m2.size(), 0);
- QCOMPARE(m2, m);
+ QT_TEST_EQUALITY_OPS(m2, m, true);
}
void tst_QCborValue::arrayEmptyInitializerList()
@@ -440,9 +635,8 @@ void tst_QCborValue::arrayEmptyInitializerList()
QCborArray a{};
QVERIFY(a.isEmpty());
QCOMPARE(a.size(), 0);
- QVERIFY(a == a);
- QVERIFY(a == QCborArray());
- QVERIFY(QCborArray() == a);
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray(), true);
}
void tst_QCborValue::mapEmptyInitializerList()
@@ -450,9 +644,8 @@ void tst_QCborValue::mapEmptyInitializerList()
QCborMap m{};
QVERIFY(m.isEmpty());
QCOMPARE(m.size(), 0);
- QVERIFY(m == m);
- QVERIFY(m == QCborMap{});
- QVERIFY(QCborMap{} == m);
+ QT_TEST_EQUALITY_OPS(m, m, true);
+ QT_TEST_EQUALITY_OPS(QCborMap{}, m, true);
}
void tst_QCborValue::arrayEmptyDetach()
@@ -462,9 +655,8 @@ void tst_QCborValue::arrayEmptyDetach()
QVERIFY(a.isEmpty());
QCOMPARE(a.size(), 0);
- QVERIFY(a == a);
- QVERIFY(a == QCborArray());
- QVERIFY(QCborArray() == a);
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray(), true);
QCborValue v(a);
QVERIFY(v.isArray());
@@ -483,9 +675,8 @@ void tst_QCborValue::mapEmptyDetach()
QVERIFY(m.isEmpty());
QCOMPARE(m.size(), 0);
- QVERIFY(m == m);
- QVERIFY(m == QCborMap{});
- QVERIFY(QCborMap{} == m);
+ QT_TEST_EQUALITY_OPS(m, m, true);
+ QT_TEST_EQUALITY_OPS(QCborMap{}, m, true);
QCborValue v(m);
QVERIFY(v.isMap());
@@ -494,7 +685,74 @@ void tst_QCborValue::mapEmptyDetach()
QCborMap m2 = v.toMap();
QVERIFY(m2.isEmpty());
- QCOMPARE(m2, m);
+ QT_TEST_EQUALITY_OPS(m2, m, true);
+}
+
+void tst_QCborValue::arrayNonEmptyDetach()
+{
+ QCborArray a;
+ a.append(1);
+ a.append(2);
+
+ QCOMPARE(a.first(), 1);
+ QCOMPARE(a.last(), 2);
+ QVERIFY(!a.contains(3));
+ QVERIFY(a.constBegin() != a.constEnd());
+ QVERIFY(a.begin() != a.end());
+
+ // now the same, with an active copy
+ { QCborArray copy(a); QCOMPARE(a.first(), 1); }
+ { QCborArray copy(a); QCOMPARE(a.last(), 2); }
+ { QCborArray copy(a); QVERIFY(!a.contains(3)); }
+ { QCborArray copy(a); QVERIFY(a.constBegin() != a.constEnd()); }
+ { QCborArray copy(a); QVERIFY(a.begin() != a.end()); }
+}
+
+void tst_QCborValue::mapNonEmptyDetach()
+{
+ QCborMap m;
+ m.insert(1, {});
+ m.insert(2, nullptr);
+ QVERIFY(!m.contains(3));
+ QVERIFY(m.constBegin() != m.constEnd());
+ QVERIFY(m.begin() != m.end());
+ // test all 4 overloads of find()
+ QVERIFY(m.constFind(3) == m.constEnd());
+ QVERIFY(m.constFind(QLatin1String("3")) == m.constEnd());
+ QVERIFY(m.constFind(QString("3")) == m.constEnd());
+ QVERIFY(m.constFind(QCborValue(3)) == m.constEnd());
+ QVERIFY(m.find(3) == m.end());
+ QVERIFY(m.find(QLatin1String("3")) == m.end());
+ QVERIFY(m.find(QString("3")) == m.end());
+ QVERIFY(m.find(QCborValue(3)) == m.end());
+ { auto it = m.find(3); QVERIFY(it == m.end()); }
+ { auto it = m.find(QLatin1String("3")); QVERIFY(it == m.end()); }
+ { auto it = m.find(QString("3")); QVERIFY(it == m.end()); }
+ { auto it = m.find(QCborValue(3)); QVERIFY(it == m.end()); }
+
+ // now the same, with an active copy
+ { QCborMap copy(m); QVERIFY(!m.contains(3)); }
+ { QCborMap copy(m); QVERIFY(m.constBegin() != m.constEnd()); }
+ { QCborMap copy(m); QVERIFY(m.begin() != m.end()); }
+ { QCborMap copy(m); QVERIFY(m.constFind(3) == m.constEnd()); }
+ { QCborMap copy(m); QVERIFY(m.constFind(QLatin1String("3")) == m.constEnd()); }
+ { QCborMap copy(m); QVERIFY(m.constFind(QString("3")) == m.constEnd()); }
+ { QCborMap copy(m); QVERIFY(m.constFind(QCborValue(3)) == m.constEnd()); }
+ { QCborMap copy(m); QVERIFY(m.find(3) == m.end()); }
+ { QCborMap copy(m); QVERIFY(m.find(QLatin1String("3")) == m.end()); }
+ { QCborMap copy(m); QVERIFY(m.find(QString("3")) == m.end()); }
+ { QCborMap copy(m); QVERIFY(m.find(QCborValue(3)) == m.end()); }\
+ { QCborMap copy(m); auto it = m.find(3); QVERIFY(it == m.end()); }
+ { QCborMap copy(m); auto it = m.find(QLatin1String("3")); QVERIFY(it == m.end()); }
+ { QCborMap copy(m); auto it = m.find(QString("3")); QVERIFY(it == m.end()); }
+ { QCborMap copy(m); auto it = m.find(QCborValue(3)); QVERIFY(it == m.end()); }
+
+ QT_TEST_EQUALITY_OPS(m.constBegin(), m.constEnd(), false);
+ QT_TEST_EQUALITY_OPS(m.begin(), m.end(), false);
+ QT_TEST_EQUALITY_OPS(m.constFind(3), m.constEnd(), true);
+ QT_TEST_EQUALITY_OPS(m.find(3), m.end(), true);
+ QT_TEST_EQUALITY_OPS(m.find(3), m.constEnd(), true);
+ QT_TEST_EQUALITY_OPS(m.constFind(3), m.end(), true);
}
void tst_QCborValue::arrayInitializerList()
@@ -510,10 +768,9 @@ void tst_QCborValue::arrayInitializerList()
QCOMPARE(a.at(5), QCborValue(QCborValue::Undefined));
QCOMPARE(a.at(6), QCborValue(1.0));
- QVERIFY(a == a);
- QVERIFY(a != QCborArray{});
- QVERIFY(QCborArray{} != a);
- QVERIFY(a == QCborArray({0, -1, false, true, nullptr, {}, 1.0}));
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray{}, false);
+ QT_TEST_EQUALITY_OPS(a, QCborArray({0, -1, false, true, nullptr, {}, 1.0}), true);
QCborValue v = a;
QCOMPARE(v[0], QCborValue(0));
@@ -542,12 +799,17 @@ void tst_QCborValue::arrayInitializerList()
// iterators
auto it = a.constBegin();
auto end = a.constEnd();
+ QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less);
QCOMPARE(end - it, 7);
QCOMPARE(it + 7, end);
+ QT_TEST_EQUALITY_OPS(it + 7, end, true);
QVERIFY(it->isInteger());
QCOMPARE(*it, QCborValue(0));
QCOMPARE(it[1], QCborValue(-1));
QCOMPARE(*(it + 2), QCborValue(false));
+ QT_TEST_EQUALITY_OPS(*it, QCborValue(0), true);
+ QT_TEST_EQUALITY_OPS(it[1], QCborValue(-1), true);
+ QT_TEST_EQUALITY_OPS(*(it + 2), QCborValue(false), true);
it += 3;
QCOMPARE(*it, QCborValue(true));
++it;
@@ -558,10 +820,28 @@ void tst_QCborValue::arrayInitializerList()
QCOMPARE(*end, QCborValue(1.0));
end--;
QCOMPARE(it, end);
+ QT_TEST_EQUALITY_OPS(it, end, true);
+ QT_TEST_EQUALITY_OPS(it, QCborArray::ConstIterator(), false);
+ QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), end, false);
+ QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::ConstIterator(), true);
+ QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::Iterator(), true);
+
+ {
+ auto it = a.begin();
+ auto it1 = a.constBegin();
+ auto end = a.end();
+ QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it1, end, Qt::strong_ordering::less);
+ QT_TEST_EQUALITY_OPS(it + 7, end, true);
+ QT_TEST_EQUALITY_OPS(it1 + 7, end, true);
+ QT_TEST_EQUALITY_OPS(it, QCborArray::Iterator(), false);
+ QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), end, false);
+ QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), QCborArray::ConstIterator(), true);
+ }
// range for
int i = 0;
- for (const QCborValue &v : qAsConst(a)) {
+ for (const QCborValue v : std::as_const(a)) {
QVERIFY(!v.isInvalid());
QCOMPARE(v.isUndefined(), i == 5); // 6th element is Undefined
++i;
@@ -573,10 +853,9 @@ void tst_QCborValue::mapSimpleInitializerList()
{
QCborMap m{{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}};
QCOMPARE(m.size(), 6);
- QVERIFY(m == m);
- QVERIFY(m != QCborMap{});
- QVERIFY(QCborMap{} != m);
- QVERIFY(m == QCborMap({{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}}));
+ QT_TEST_EQUALITY_OPS(m, m, true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap{}, false);
+ QT_TEST_EQUALITY_OPS(m, QCborMap({{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}}), true);
QCborValue vmap = m;
{
@@ -661,7 +940,7 @@ void tst_QCborValue::mapSimpleInitializerList()
// range for
int i = 0;
- for (auto pair : qAsConst(m)) {
+ for (auto pair : std::as_const(m)) {
QVERIFY(!pair.first.isUndefined());
QVERIFY(!pair.second.isUndefined());
++i;
@@ -669,6 +948,55 @@ void tst_QCborValue::mapSimpleInitializerList()
QCOMPARE(i, m.size());
}
+template <typename T> static void mapFromArray_template(T key)
+{
+ QFETCH(QCborValue::Type, type);
+ QFETCH(QCborValue, v);
+ if (v.isMap())
+ return; // already a map, nothing will happen
+
+ // verify forced conversions work
+ // (our only Array row is an empty array, so it doesn't produce the warning)
+ QCborValue v2 = v;
+ QVERIFY(v2[key].isUndefined());
+ QCOMPARE(v2.type(), QCborValue::Map);
+ QCOMPARE(v.type(), type);
+ QCborMap m = v2.toMap();
+ QCOMPARE(m.size(), 1);
+ QCOMPARE(m.begin().key(), QCborValue(key));
+
+ // non-empty array conversions
+ QCborValue va = QCborArray{v};
+ v2 = va;
+ QTest::ignoreMessage(QtWarningMsg, "Using CBOR array as map forced conversion");
+ QVERIFY(v2[key].isUndefined());
+ QCOMPARE(v2.type(), QCborValue::Map);
+ QCOMPARE(va.type(), QCborValue::Array);
+ m = v2.toMap();
+ QCOMPARE(m.size(), 2);
+ auto it = m.constBegin();
+ QCOMPARE(it.key(), QCborValue(0));
+ QCOMPARE(it.value(), v);
+ ++it;
+ QCOMPARE(it.key(), QCborValue(key));
+ QCOMPARE(it.value(), QCborValue());
+}
+
+void tst_QCborValue::mapFromArrayLargeIntKey()
+{
+ mapFromArray_template(Q_INT64_C(1) << 20);
+}
+
+void tst_QCborValue::mapFromArrayNegativeIntKey()
+{
+ mapFromArray_template(-1);
+}
+
+void tst_QCborValue::mapFromArrayStringKey()
+{
+ mapFromArray_template(QLatin1String("Hello"));
+}
+
void tst_QCborValue::arrayMutation()
{
QCborArray a{42};
@@ -687,8 +1015,8 @@ void tst_QCborValue::arrayMutation()
QVERIFY(v == a.at(0));
}
- QVERIFY(a == a);
- QVERIFY(a == QCborArray{true});
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray{true}, true);
QCborArray a2 = a;
a.append(nullptr);
@@ -723,6 +1051,76 @@ void tst_QCborValue::arrayMutation()
QCOMPARE(a.at(1), QCborValue(-1));
QCOMPARE(a2.at(1), QCborValue(nullptr));
QCOMPARE(++it, end);
+
+ // Array accessed via value:
+ QCborValue val(a);
+ val[2] = QCborArray{2, 3, 5, 7};
+ QCOMPARE(a.size(), 2); // Unchanged
+ QVERIFY(val.isArray());
+ QCOMPARE(val.toArray().size(), 3);
+ val[2][4] = 17;
+ QVERIFY(val.isArray());
+ QVERIFY(val[2].isArray());
+ QCOMPARE(val[2].toArray().size(), 5);
+ QCOMPARE(val[2][4], 17);
+ QCOMPARE(val.toArray().size(), 3);
+ val[3] = 42;
+ QVERIFY(val.isArray());
+ QCOMPARE(val.toArray().size(), 4);
+ QCOMPARE(val[3], 42);
+}
+
+void tst_QCborValue::arrayMutateWithCopies()
+{
+ {
+ QCborArray array;
+ array.append("TEST");
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0), "TEST");
+
+ array.append(array.at(0));
+ QCOMPARE(array.size(), 2);
+ QCOMPARE(array.at(0), "TEST");
+ QCOMPARE(array.at(1), "TEST");
+ }
+ {
+ QCborArray array;
+ array.append("TEST");
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0), "TEST");
+
+ // same as previous, but with prepend() not append()
+ array.prepend(array.at(0));
+ QCOMPARE(array.size(), 2);
+ QCOMPARE(array.at(0), "TEST");
+ QCOMPARE(array.at(1), "TEST");
+ }
+ {
+ QCborArray array;
+ array.append("TEST");
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0), "TEST");
+
+ // same as previous, but using a QCborValueRef
+ QCborValueRef rv = array[0];
+ array.prepend(rv);
+ QCOMPARE(array.size(), 2);
+ QCOMPARE(array.at(0), "TEST");
+ QCOMPARE(array.at(1), "TEST");
+ }
+ {
+ QCborArray array;
+ array.append("TEST");
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0), "TEST");
+
+ // same as previous, but now extending the array
+ QCborValueRef rv = array[0];
+ array[2] = rv;
+ QCOMPARE(array.size(), 3);
+ QCOMPARE(array.at(0), "TEST");
+ QCOMPARE(array.at(2), "TEST");
+ }
}
void tst_QCborValue::mapMutation()
@@ -736,12 +1134,39 @@ void tst_QCborValue::mapMutation()
QVERIFY(v.isUndefined());
// now mutate the list
+ // simple -> HasByteData
+ const QString strValue = QStringLiteral("value");
+ v = strValue;
+ QVERIFY(v.isString());
+ QT_TEST_EQUALITY_OPS(v, QCborValue(strValue), true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap({{42, strValue}}), true);
+
+ // HasByteData -> HasByteData
+ const QLatin1String otherStrValue("othervalue");
+ v = otherStrValue;
+ QVERIFY(v.isString());
+ QT_TEST_EQUALITY_OPS(v, QCborValue(otherStrValue), true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap({{42, otherStrValue}}), true);
+
+ // HasByteData -> simple
+ v = 42;
+ QVERIFY(v.isInteger());
+ QT_TEST_EQUALITY_OPS(v, QCborValue(42), true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap({{42, 42}}), true);
+
+ // simple -> container
+ v = QCborArray{1, 2, 3};
+ QVERIFY(v.isArray());
+ QT_TEST_EQUALITY_OPS(v, QCborArray({1, 2, 3}), true);
+ QT_TEST_EQUALITY_OPS(m, QCborMap({{42, QCborArray{1, 2, 3}}}), true);
+
+ // container -> simple
v = true;
QVERIFY(v.isBool());
QVERIFY(v.isTrue());
+ QCOMPARE(m, QCborMap({{42, true}}));
QVERIFY(m.begin()->isTrue());
- QVERIFY(m.begin().value() == v);
- QVERIFY(v == m.begin().value());
+ QT_TEST_EQUALITY_OPS(m.begin().value(), v, true);
}
QVERIFY(m == QCborMap({{42, true}}));
@@ -763,21 +1188,128 @@ void tst_QCborValue::mapMutation()
m2 = m;
auto it = m.begin(); // detaches again
auto end = m.end();
+ auto it1 = m.constBegin(); // detaches again
+ auto end2 = m.constEnd();
QCOMPARE(end - it, 2);
+ QT_TEST_ALL_COMPARISON_OPS(it, it + 1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it, it1 + 1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(it, it - 1, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(it, it1 - 1, Qt::strong_ordering::greater);
+ QT_TEST_EQUALITY_OPS(it, it1, true);
QCOMPARE(it + 2, end);
- QCOMPARE(it.key(), QCborValue(42));
- QCOMPARE(it.value(), QCborValue(2.5));
- QCOMPARE((++it).value(), QCborValue(nullptr));
- QCOMPARE(it.key(), QCborValue(nullptr));
- QVERIFY(m2 == m);
- QVERIFY(m == m2);
+ QT_TEST_EQUALITY_OPS(it + 2, end, true);
+ QT_TEST_EQUALITY_OPS(it + 2, end2, true);
+ QT_TEST_EQUALITY_OPS(it1 + 2, end2, true);
+ QT_TEST_EQUALITY_OPS(it.key(), QCborValue(42), true);
+ QT_TEST_EQUALITY_OPS(it.value(), QCborValue(2.5), true);
+ QT_TEST_EQUALITY_OPS((++it).value(), QCborValue(nullptr), true);
+ QT_TEST_EQUALITY_OPS(it.key(), QCborValue(nullptr), true);
+ QT_TEST_EQUALITY_OPS(m2, m, true);
it.value() = -1;
- QCOMPARE(it.key(), QCborValue(nullptr));
- QCOMPARE(it.value(), QCborValue(-1));
+ QT_TEST_EQUALITY_OPS(it.key(), QCborValue(nullptr), true);
+ QT_TEST_EQUALITY_OPS(it.value(), QCborValue(-1), true);
QCOMPARE((m.end() - 1)->toInteger(), -1);
QVERIFY((m2.end() - 1)->isNull());
QCOMPARE(++it, end);
+
+ // Map accessed via value:
+ QCborValue val(m);
+ val[7] = QCborMap({{0, 2}, {1, 3}, {2, 5}});
+ QCOMPARE(m.size(), 2); // Unchanged
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 3);
+ val[7][3] = 11;
+ QVERIFY(val.isMap());
+ QVERIFY(val[7].isMap());
+ QCOMPARE(val[7].toMap().size(), 4);
+ val[14] = 42;
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 4);
+
+ const QLatin1String any("any");
+ const QString hello(QStringLiteral("Hello World"));
+ val[any][3][hello] = any;
+ QVERIFY(val.isMap());
+ QCOMPARE(val.toMap().size(), 5);
+ QVERIFY(val[any].isMap());
+ QCOMPARE(val[any].toMap().size(), 1);
+ QVERIFY(val[any][3].isMap());
+ QCOMPARE(val[any][3].toMap().size(), 1);
+}
+
+void tst_QCborValue::mapMutateWithCopies()
+{
+ {
+ QCborMap map;
+ map[QLatin1String("prop1")] = "TEST";
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map.value("prop1"), "TEST");
+
+ map[QLatin1String("prop2")] = map.value("prop1");
+ QCOMPARE(map.size(), 2);
+ QCOMPARE(map.value("prop1"), "TEST");
+ QCOMPARE(map.value("prop2"), "TEST");
+ }
+ {
+ // see QTBUG-83366
+ QCborMap map;
+ map[QLatin1String("value")] = "TEST";
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("value")], "TEST", true);
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map.value("value"), "TEST");
+
+ QCborValue v = map.value("value");
+ map[QLatin1String("prop2")] = v;
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("prop2")], v, true);
+ QCOMPARE(map.size(), 2);
+ QCOMPARE(map.value("value"), "TEST");
+ QCOMPARE(map.value("prop2"), "TEST");
+ }
+ {
+ QCborMap map;
+ map[QLatin1String("value")] = "TEST";
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map.value("value"), "TEST");
+
+ // same as previous, but this is a QJsonValueRef
+ QCborValueRef rv = map[QLatin1String("prop2")];
+ rv = map[QLatin1String("value")];
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("value")], rv, true);
+ QCOMPARE(map.size(), 2);
+ QCOMPARE(map.value("value"), "TEST");
+ QCOMPARE(map.value("prop2"), "TEST");
+ }
+ {
+ QCborMap map;
+ map[QLatin1String("value")] = "TEST";
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map.value("value"), "TEST");
+
+ // same as previous, but now we call the operator[] that reallocates
+ // after we create the source QCborValueRef
+ QCborValueRef rv = map[QLatin1String("value")];
+ map[QLatin1String("prop2")] = rv;
+ QT_TEST_EQUALITY_OPS(map[QLatin1String("prop2")], rv, true);
+ QCOMPARE(map.size(), 2);
+ QCOMPARE(map.value("value"), "TEST");
+ QCOMPARE(map.value("prop2"), "TEST");
+ }
+ {
+ QCborMap map;
+ map[QLatin1String("value")] = "TEST";
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map.value("value"), "TEST");
+
+ QCborValueRef v = map[QLatin1String("value")];
+ QCborMap map2 = map;
+ map.insert(QLatin1String("prop2"), v);
+ QCOMPARE(map.size(), 2);
+ QCOMPARE(map.value("value"), "TEST");
+ QCOMPARE(map.value("prop2"), "TEST");
+ QCOMPARE(map2.size(), 1);
+ QCOMPARE(map2.value("value"), "TEST");
+ }
}
void tst_QCborValue::arrayPrepend()
@@ -785,11 +1317,102 @@ void tst_QCborValue::arrayPrepend()
QCborArray a;
a.prepend(0);
a.prepend(nullptr);
- QCOMPARE(a.at(1), QCborValue(0));
- QCOMPARE(a.at(0), QCborValue(nullptr));
+ QT_TEST_EQUALITY_OPS(a.at(1), QCborValue(0), true);
+ QT_TEST_EQUALITY_OPS(a.at(0), QCborValue(nullptr), true);
QCOMPARE(a.size(), 2);
}
+void tst_QCborValue::arrayValueRef()
+{
+ QFETCH(QCborValue, v);
+ QCborArray a = { v };
+
+ // methods that return QCborValueRef
+ QT_TEST_EQUALITY_OPS(a.first(), v, true);
+ QT_TEST_EQUALITY_OPS(a.last(), v, true);
+ QT_TEST_EQUALITY_OPS(a[0], v, true);
+ QVERIFY(v == a.first());
+ QVERIFY(v == a.last());
+ QVERIFY(v == a[0]);
+ QT_TEST_EQUALITY_OPS(a.first(), v, true);
+ QT_TEST_EQUALITY_OPS(a.last(), v, true);
+
+ auto iteratorCheck = [&v](auto it) {
+ QT_TEST_EQUALITY_OPS(*it, v, true);
+ QCOMPARE(it->type(), v.type()); // just to test operator->
+ QT_TEST_EQUALITY_OPS(it[0], v, true);
+ };
+
+ iteratorCheck(a.begin());
+ if (QTest::currentTestFailed())
+ return;
+ iteratorCheck(a.constBegin());
+}
+
+void tst_QCborValue::arrayValueRefLargeKey()
+{
+ // make sure the access via QCborValue & QCborValueRef don't convert this
+ // array to a map
+ constexpr qsizetype LargeKey = 0x10000;
+ QCborArray a;
+ a[LargeKey + 1] = 123;
+
+ QCborValue v(a);
+ QT_TEST_EQUALITY_OPS(std::as_const(v)[LargeKey], QCborValue(), true);
+ QCOMPARE(std::as_const(v)[LargeKey + 1], 123);
+ QT_TEST_EQUALITY_OPS(v[LargeKey], QCborValue(), true);
+ QCOMPARE(v[LargeKey + 1], 123);
+ QCOMPARE(v.type(), QCborValue::Array);
+
+ QCborArray outer = { QCborValue(a) };
+ QCborValueRef ref = outer[0];
+ QT_TEST_EQUALITY_OPS(std::as_const(ref)[LargeKey], QCborValue(), true);
+ QCOMPARE(std::as_const(ref)[LargeKey + 1], 123);
+ QT_TEST_EQUALITY_OPS(ref[LargeKey], QCborValue(), true);
+ QCOMPARE(ref[LargeKey + 1], 123);
+ QCOMPARE(ref.type(), QCborValue::Array);
+}
+
+void tst_QCborValue::mapValueRef()
+{
+ QFETCH(QCborValue, v);
+ QLatin1String stringKey("other string");
+ qint64 intKey = 47;
+ Q_ASSERT(v != stringKey);
+ Q_ASSERT(v != intKey);
+
+ QCborMap m = { { v, v }, { stringKey, v }, { intKey, v } };
+ QCOMPARE(m.size(), 3);
+
+ // methods that return QCborValueRef
+ QT_TEST_EQUALITY_OPS(m[intKey], v, true);
+ QT_TEST_EQUALITY_OPS(m[stringKey], v, true);
+ QT_TEST_EQUALITY_OPS(m[v], v, true);
+ QVERIFY(v == m[intKey]);
+ QVERIFY(v == m[stringKey]);
+ QVERIFY(v == m[v]);
+
+ auto iteratorCheck = [=](auto it) {
+ QCOMPARE((*it).second, v);
+ QCOMPARE(it[0].second, v);
+ QCOMPARE(it[1].second, v);
+ QCOMPARE(it[2].second, v);
+ QCOMPARE(it.value(), v);
+ QCOMPARE(it->type(), v.type()); // just to test operator->
+
+ // compare keys too
+ QCOMPARE((*it).first, v);
+ QCOMPARE(it.key(), v);
+ QCOMPARE((it + 1).key(), stringKey);
+ QCOMPARE((it + 2).key(), intKey);
+ };
+
+ iteratorCheck(m.begin());
+ if (QTest::currentTestFailed())
+ return;
+ iteratorCheck(m.constBegin());
+}
+
void tst_QCborValue::arrayInsertRemove()
{
QFETCH(QCborValue, v);
@@ -797,28 +1420,28 @@ void tst_QCborValue::arrayInsertRemove()
a.append(42);
a.append(v);
a.insert(1, QCborValue(nullptr));
- QCOMPARE(a.at(0), QCborValue(42));
- QCOMPARE(a.at(1), QCborValue(nullptr));
- QCOMPARE(a.at(2), v);
+ QT_TEST_EQUALITY_OPS(a.at(0), QCborValue(42), true);
+ QT_TEST_EQUALITY_OPS(a.at(1), QCborValue(nullptr), true);
+ QT_TEST_EQUALITY_OPS(a.at(2), v, true);
// remove 42
a.removeAt(0);
QCOMPARE(a.size(), 2);
- QCOMPARE(a.at(0), QCborValue(nullptr));
- QCOMPARE(a.at(1), v);
+ QT_TEST_EQUALITY_OPS(a.at(0), QCborValue(nullptr), true);
+ QT_TEST_EQUALITY_OPS(a.at(1), v, true);
auto it = a.begin();
it = a.erase(it); // removes nullptr
QCOMPARE(a.size(), 1);
- QCOMPARE(a.at(0), v);
+ QT_TEST_EQUALITY_OPS(a.at(0), v, true);
it = a.erase(it);
QVERIFY(a.isEmpty());
- QCOMPARE(it, a.end());
+ QT_TEST_EQUALITY_OPS(it, a.end(), true);
// reinsert the element so we can take it
a.append(v);
- QCOMPARE(a.takeAt(0), v);
+ QT_TEST_EQUALITY_OPS(a.takeAt(0), v, true);
QVERIFY(a.isEmpty());
}
@@ -827,14 +1450,15 @@ void tst_QCborValue::arrayStringElements()
QCborArray a{"Hello"};
a.append(QByteArray("Hello"));
a.append(QLatin1String("World"));
- QVERIFY(a == a);
- QVERIFY(a == QCborArray({QLatin1String("Hello"),
- QByteArray("Hello"), QStringLiteral("World")}));
+
+ QT_TEST_EQUALITY_OPS(a, a, true);
+ QT_TEST_EQUALITY_OPS(a, QCborArray({QLatin1String("Hello"),
+ QByteArray("Hello"), QStringLiteral("World")}), true);
QCborValueRef r1 = a[0];
QCOMPARE(r1.toString(), "Hello");
QCOMPARE(r1.operator QCborValue(), QCborValue("Hello"));
- QVERIFY(r1 == QCborValue("Hello"));
+ QT_TEST_EQUALITY_OPS(r1, QCborValue("Hello"), true);
QCborValue v2 = a.at(1);
QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
@@ -843,11 +1467,11 @@ void tst_QCborValue::arrayStringElements()
// v2 must continue to be valid after the entry getting removed
a.removeAt(1);
QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
- QCOMPARE(v2, QCborValue(QByteArray("Hello")));
+ QT_TEST_EQUALITY_OPS(v2, QCborValue(QByteArray("Hello")), true);
v2 = a.at(1);
QCOMPARE(v2.toString(), "World");
- QCOMPARE(v2, QCborValue("World"));
+ QT_TEST_EQUALITY_OPS(v2, QCborValue("World"), true);
QCOMPARE(a.takeAt(1).toString(), "World");
QCOMPARE(a.takeAt(0).toString(), "Hello");
@@ -859,12 +1483,12 @@ void tst_QCborValue::mapStringValues()
QCborMap m{{0, "Hello"}};
m.insert({1, QByteArray("Hello")});
m.insert({2, QLatin1String("World")});
- QVERIFY(m == m);
+ QT_TEST_EQUALITY_OPS(m, m, true);
QCborValueRef r1 = m[0];
QCOMPARE(r1.toString(), "Hello");
QCOMPARE(r1.operator QCborValue(), QCborValue("Hello"));
- QVERIFY(r1 == QCborValue("Hello"));
+ QT_TEST_EQUALITY_OPS(r1, QCborValue("Hello"), true);
QCborValue v2 = m.value(1);
QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
@@ -873,7 +1497,7 @@ void tst_QCborValue::mapStringValues()
// v2 must continue to be valid after the entry getting removed
m.erase(m.constFind(1));
QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
- QCOMPARE(v2, QCborValue(QByteArray("Hello")));
+ QT_TEST_EQUALITY_OPS(v2, QCborValue(QByteArray("Hello")), true);
v2 = (m.begin() + 1).value();
QCOMPARE(v2.toString(), "World");
@@ -891,14 +1515,12 @@ void tst_QCborValue::mapStringKeys()
QCOMPARE(m.value(QLatin1String("World")), QCborValue(2));
QCborMap m2 = m;
- QVERIFY(m2 == m);
- QVERIFY(m == m2);
+ QT_TEST_EQUALITY_OPS(m2, m, true);
m.insert({QByteArray("foo"), "bar"});
QCOMPARE(m.size(), 3);
QCOMPARE(m2.size(), 2);
- QVERIFY(m2 != m);
- QVERIFY(m != m2);
+ QT_TEST_EQUALITY_OPS(m2, m, false);
QVERIFY(m2.value(QCborValue(QByteArray("foo"))).isUndefined());
QVERIFY(m.value(QCborValue(QLatin1String("foo"))).isUndefined());
@@ -916,8 +1538,7 @@ void tst_QCborValue::mapInsertRemove()
m.insert(2, v);
QVERIFY(m.contains(2));
- QVERIFY(m[2] == v);
- QVERIFY(v == m[2]);
+ QT_TEST_EQUALITY_OPS(m[2], v, true);
auto it = m.find(2);
it = m.erase(it);
@@ -930,10 +1551,8 @@ void tst_QCborValue::mapInsertRemove()
r = v;
it = m.find(42);
- QVERIFY(it.value() == v);
- QVERIFY(v == it.value());
- QVERIFY(it.value() == r);
- QVERIFY(r == it.value());
+ QT_TEST_EQUALITY_OPS(it.value(), v, true);
+ QT_TEST_EQUALITY_OPS(it.value(), r, true);
QCOMPARE(m.extract(it), v);
QVERIFY(!m.contains(42));
@@ -954,12 +1573,12 @@ void tst_QCborValue::arrayInsertTagged()
QCborArray a{tagged};
a.insert(1, tagged);
QCOMPARE(a.size(), 2);
- QCOMPARE(a.at(0), tagged);
- QCOMPARE(a.at(1), tagged);
- QCOMPARE(a.at(0).taggedValue(), v);
- QCOMPARE(a.at(1).taggedValue(), v);
- QCOMPARE(a.takeAt(0).taggedValue(), v);
- QCOMPARE(a.takeAt(0).taggedValue(), v);
+ QT_TEST_EQUALITY_OPS(a.at(0), tagged, true);
+ QT_TEST_EQUALITY_OPS(a.at(1), tagged, true);
+ QT_TEST_EQUALITY_OPS(a.at(0).taggedValue(), v, true);
+ QT_TEST_EQUALITY_OPS(a.at(1).taggedValue(), v, true);
+ QT_TEST_EQUALITY_OPS(a.takeAt(0).taggedValue(), v, true);
+ QT_TEST_EQUALITY_OPS(a.takeAt(0).taggedValue(), v, true);
QVERIFY(a.isEmpty());
}
@@ -973,13 +1592,13 @@ void tst_QCborValue::mapInsertTagged()
QCborMap m{{11, tagged}};
m.insert({-21, tagged});
QCOMPARE(m.size(), 2);
- QCOMPARE(m.constBegin().value(), tagged);
- QCOMPARE(m.value(-21), tagged);
- QCOMPARE(m.value(11).taggedValue(), v);
- QCOMPARE((m.end() - 1).value().taggedValue(), v);
- QCOMPARE(m.extract(m.end() - 1).taggedValue(), v);
+ QT_TEST_EQUALITY_OPS(m.constBegin().value(), tagged, true);
+ QT_TEST_EQUALITY_OPS(m.value(-21), tagged, true);
+ QT_TEST_EQUALITY_OPS(m.value(11).taggedValue(), v, true);
+ QT_TEST_EQUALITY_OPS((m.end() - 1).value().taggedValue(), v, true);
+ QT_TEST_EQUALITY_OPS(m.extract(m.end() - 1).taggedValue(), v, true);
QVERIFY(!m.contains(-21));
- QCOMPARE(m.take(11).taggedValue(), v);
+ QT_TEST_EQUALITY_OPS(m.take(11).taggedValue(), v, true);
QVERIFY(m.isEmpty());
}
@@ -1008,7 +1627,7 @@ void tst_QCborValue::arraySelfAssign()
QCOMPARE(a.size(), 2);
QCOMPARE(it->toArray().size(), 2);
- QCOMPARE(it->toArray().last(), QCborValue(36));
+ QT_TEST_EQUALITY_OPS(it->toArray().last(), QCborValue(36), true);
}
}
@@ -1026,12 +1645,12 @@ void tst_QCborValue::mapSelfAssign()
QCborValue vm = m;
m[1] = vm; // self-assign
QCOMPARE(m.size(), 2);
- QCOMPARE(m.value(0), v);
+ QT_TEST_EQUALITY_OPS(m.value(0), v, true);
QCborMap m2 = m.value(1).toMap();
// there mustn't be an element with key 1
QCOMPARE(m2.size(), 1);
- QCOMPARE(m2.value(0), v);
+ QT_TEST_EQUALITY_OPS(m2.value(0), v, true);
QVERIFY(!m2.contains(1));
}
@@ -1043,14 +1662,14 @@ void tst_QCborValue::mapSelfAssign()
QCborValueRef rv = m[1];
rv = m; // self-assign (implicit QCborValue creation)
QCOMPARE(m.size(), 2);
- QCOMPARE(m.value(0), v);
+ QT_TEST_EQUALITY_OPS(m.value(0), v, true);
QCborMap m2 = m.value(1).toMap();
// there must be an element with key 1
QCOMPARE(m2.size(), 2);
- QCOMPARE(m2.value(0), v);
+ QT_TEST_EQUALITY_OPS(m2.value(0), v, true);
QVERIFY(m2.contains(1));
- QCOMPARE(m2.value(1), QCborValue());
+ QT_TEST_EQUALITY_OPS(m2.value(1), QCborValue(), true);
}
m = {{0, v}};
@@ -1074,8 +1693,8 @@ void tst_QCborValue::mapSelfAssign()
QCOMPARE(m.size(), 2);
auto it = m.constEnd() - 1;
- QCOMPARE(it.value(), v);
- QCOMPARE(it.key(), QCborMap({{0, v}}));
+ QT_TEST_EQUALITY_OPS(it.value(), v, true);
+ QT_TEST_EQUALITY_OPS(it.key(), QCborMap({{0, v}}), true);
}
}
@@ -1148,8 +1767,125 @@ void tst_QCborValue::mapComplexKeys()
QVERIFY(!m.contains(tagged));
}
-void tst_QCborValue::sorting()
+void tst_QCborValue::arrayNested()
{
+ const QCborArray wrongArray = { false, nullptr, QCborValue() };
+ {
+ QCborArray a1 = { 42, 47 };
+ QCborArray a2 = { QCborValue(a1) };
+ QCborArray a3 = { 41, 47 };
+ QCborArray a4 = { 41, 47, 87 };
+ QCOMPARE(a2.size(), 1);
+ const QCborValue &first = std::as_const(a2).first();
+ QVERIFY(first.isArray());
+ QCOMPARE(first.toArray(wrongArray).size(), 2);
+ QCOMPARE(first.toArray(wrongArray).first(), 42);
+ QCOMPARE(first.toArray(wrongArray).last(), 47);
+ QT_TEST_ALL_COMPARISON_OPS(a1, a3, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a4, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a2, Qt::strong_ordering::greater);
+ }
+ {
+ QCborArray a1 = { 42, 47 };
+ QCborArray a2 = { QCborValue(a1) };
+ QCborArray a3 = { 41, 47 };
+ QCborArray a4 = { 41, 47, 87 };
+ QCOMPARE(a2.size(), 1);
+ QCborValueRef first = a2.first();
+ QVERIFY(first.isArray());
+ QCOMPARE(first.toArray(wrongArray).size(), 2);
+ QCOMPARE(first.toArray(wrongArray).first(), 42);
+ QCOMPARE(first.toArray(wrongArray).last(), 47);
+ QT_TEST_ALL_COMPARISON_OPS(a1, a3, Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a1, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a4, Qt::strong_ordering::less);
+ QT_TEST_ALL_COMPARISON_OPS(a3, a2, Qt::strong_ordering::greater);
+ }
+
+ {
+ QCborArray a1;
+ a1 = { QCborValue(a1) }; // insert it into itself
+ QCOMPARE(a1.size(), 1);
+ const QCborValue &first = std::as_const(a1).first();
+ QVERIFY(first.isArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
+ }
+ {
+ QCborArray a1;
+ a1 = { QCborValue(a1) }; // insert it into itself
+ QCborValueRef first = a1.first();
+ QVERIFY(first.isArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
+ }
+ {
+ QCborArray a1;
+ a1.append(a1); // insert into itself
+ QCOMPARE(a1.size(), 1);
+ const QCborValue &first = std::as_const(a1).first();
+ QVERIFY(first.isArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
+ }
+ {
+ QCborArray a1;
+ a1.append(a1); // insert into itself
+ QCborValueRef first = a1.first();
+ QVERIFY(first.isArray());
+ QT_TEST_ALL_COMPARISON_OPS(first, QCborArray(), Qt::strong_ordering::equal);
+ QT_TEST_ALL_COMPARISON_OPS(first.toArray(wrongArray), QCborArray(),
+ Qt::strong_ordering::equal);
+ }
+}
+
+void tst_QCborValue::mapNested()
+{
+ const QCborMap wrongMap = { { -1, false }, {-2, nullptr }, { -3, QCborValue() } };
+ {
+ QCborMap m1 = { {1, 42}, {2, 47} };
+ QCborMap m2 = { { QString(), m1 } };
+ QCOMPARE(m2.size(), 1);
+ const QCborValue &first = m2.constBegin().value();
+ QVERIFY(first.isMap());
+ QCOMPARE(first.toMap(wrongMap).size(), 2);
+ QCOMPARE(first.toMap(wrongMap).begin().key(), 1);
+ QCOMPARE(first.toMap(wrongMap).begin().value(), 42);
+ }
+
+ {
+ QCborMap m1;
+ m1 = { { QString(), QCborValue(m1) } }; // insert it into itself
+ QCOMPARE(m1.size(), 1);
+ const QCborValue &first = m1.constBegin().value();
+ QVERIFY(first.isMap());
+ QCOMPARE(first, QCborMap());
+ QCOMPARE(first.toMap(wrongMap), QCborMap());
+ }
+}
+
+void tst_QCborValue::sorting_data()
+{
+ // CBOR data comparisons are done as if we were comparing their canonically
+ // (deterministic) encoded forms in the byte stream, including the Major
+ // Type. That has a few surprises noted below:
+ // 1) because the length of a string precedes it, effectively strings are
+ // sorted by their UTF-8 length before their contents
+ // 2) because negative integers are stored in negated form, they sort in
+ // descending order (i.e. by absolute value)
+ // 3) negative integers (Major Type 1) sort after all positive integers
+ // (Major Type 0)
+ // Effectively, this means integers are sorted as sign+magnitude.
+ // 4) floating point types (Major Type 7) sort after all integers
+
+ QTest::addColumn<QCborValue>("lhs");
+ QTest::addColumn<QCborValue>("rhs");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrdering");
+
QCborValue vundef, vnull(nullptr);
QCborValue vtrue(true), vfalse(false);
QCborValue vint1(1), vint2(2);
@@ -1158,73 +1894,272 @@ void tst_QCborValue::sorting()
QCborValue vs2("Hello"), vs3("World"), vs1("foo");
QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0});
QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}});
- QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)), vdt2(QDateTime::currentDateTimeUtc());
- QCborValue vtagged1(QCborKnownTags::UnixTime_t, 0), vtagged2(QCborKnownTags::UnixTime_t, 0.0),
- vtagged3(QCborKnownTags::Signature, 0), vtagged4(QCborTag(-2), 0), vtagged5(QCborTag(-1), 0);
+ QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC));
+ QCborValue vdt2(QDateTime::currentDateTimeUtc());
+ QCborValue vtagged1(QCborKnownTags::PositiveBignum, QByteArray()),
+ vtagged2(QCborKnownTags::PositiveBignum, 0.0), // bignums are supposed to have byte arrays...
+ vtagged3(QCborKnownTags::Signature, 0),
+ vtagged4(QCborTag(-2), 0),
+ vtagged5(QCborTag(-1), 0);
QCborValue vurl1(QUrl("https://example.net")), vurl2(QUrl("https://example.com/"));
QCborValue vuuid1{QUuid()}, vuuid2(QUuid::createUuid());
QCborValue vsimple1(QCborSimpleType(1)), vsimple32(QCborSimpleType(32)), vsimple255(QCborSimpleType(255));
- QCborValue vdouble1(1.5), vdouble2(qInf());
+ QCborValue vdouble1(1.5), vdouble2(qInf()), vdouble3(qQNaN());
QCborValue vndouble1(-1.5), vndouble2(-qInf());
-#define CHECK_ORDER(v1, v2) \
- QVERIFY(v1 < v2); \
- QVERIFY(!(v2 < v2))
+ auto addRow = [](QCborValue lhs, QCborValue rhs, Qt::strong_ordering order) {
+ QTest::addRow("%s-cmp-%s", qPrintable(lhs.toDiagnosticNotation()),
+ qPrintable(rhs.toDiagnosticNotation()))
+ << lhs << rhs << order;
+ };
+ auto addSelfCmp = [](QCborValue v) {
+ QTest::addRow("self-%s", qPrintable(v.toDiagnosticNotation()))
+ << v << v << Qt::strong_ordering::equal;
+ };
+
+ // self compares
+ addSelfCmp(vundef);
+ addSelfCmp(vnull);
+ addSelfCmp(vfalse);
+ addSelfCmp(vtrue);
+ addSelfCmp(vint1);
+ addSelfCmp(vint2);
+ addSelfCmp(vneg1);
+ addSelfCmp(vneg2);
+ addSelfCmp(vba1);
+ addSelfCmp(vba2);
+ addSelfCmp(vba3);
+ addSelfCmp(vs1);
+ addSelfCmp(vs2);
+ addSelfCmp(vs3);
+ addSelfCmp(va1);
+ addSelfCmp(va2);
+ addSelfCmp(va3);
+ addSelfCmp(vm1);
+ addSelfCmp(vm2);
+ addSelfCmp(vm3);
+ addSelfCmp(vdt1);
+ addSelfCmp(vdt2);
+ addSelfCmp(vtagged1);
+ addSelfCmp(vtagged2);
+ addSelfCmp(vtagged3);
+ addSelfCmp(vtagged4);
+ addSelfCmp(vtagged5);
+ addSelfCmp(vurl1);
+ addSelfCmp(vurl2);
+ addSelfCmp(vuuid1);
+ addSelfCmp(vuuid2);
+ addSelfCmp(vsimple1);
+ addSelfCmp(vsimple32);
+ addSelfCmp(vsimple255);
+ addSelfCmp(vdouble1);
+ addSelfCmp(vdouble2);
+ addSelfCmp(vdouble3); // surprise: NaNs do compare
+ addSelfCmp(vndouble1);
+ addSelfCmp(vndouble2);
// intra-type comparisons
- CHECK_ORDER(vfalse, vtrue);
- CHECK_ORDER(vsimple1, vsimple32);
- CHECK_ORDER(vsimple32, vsimple255);
- CHECK_ORDER(vint1, vint2);
- CHECK_ORDER(vdouble1, vdouble2);
- CHECK_ORDER(vndouble1, vndouble2);
- // note: shorter length sorts first
- CHECK_ORDER(vba1, vba2);
- CHECK_ORDER(vba2, vba3);
- CHECK_ORDER(vs1, vs2);
- CHECK_ORDER(vs2, vs3);
- CHECK_ORDER(va1, va2);
- CHECK_ORDER(va2, va3);
- CHECK_ORDER(vm1, vm2);
- CHECK_ORDER(vm2, vm3);
- CHECK_ORDER(vdt1, vdt2);
- CHECK_ORDER(vtagged1, vtagged2);
- CHECK_ORDER(vtagged2, vtagged3);
- CHECK_ORDER(vtagged3, vtagged4);
- CHECK_ORDER(vtagged4, vtagged5);
- CHECK_ORDER(vurl1, vurl2);
- CHECK_ORDER(vuuid1, vuuid2);
-
- // surprise 1: CBOR sorts integrals by absolute value
- CHECK_ORDER(vneg1, vneg2);
-
- // surprise 2: CBOR sorts negatives after positives (sign+magnitude)
- CHECK_ORDER(vint2, vneg1);
- QVERIFY(vint2.toInteger() > vneg1.toInteger());
- CHECK_ORDER(vdouble2, vndouble1);
- QVERIFY(vdouble2.toDouble() > vndouble1.toDouble());
+ addRow(vfalse, vtrue, Qt::strong_ordering::less);
+ addRow(vsimple1, vsimple32, Qt::strong_ordering::less);
+ addRow(vsimple32, vsimple255, Qt::strong_ordering::less);
+ addRow(vint1, vint2, Qt::strong_ordering::less);
+ addRow(vdouble1, vdouble2, Qt::strong_ordering::less);
+ addRow(vdouble2, vdouble3, Qt::strong_ordering::less); // surprise: NaNs do compare
+ addRow(vndouble1, vndouble2, Qt::strong_ordering::less); // surprise: -1.5 < -inf
+ addRow(va1, va2, Qt::strong_ordering::less);
+ addRow(va2, va3, Qt::strong_ordering::less);
+ addRow(vm1, vm2, Qt::strong_ordering::less);
+ addRow(vm2, vm3, Qt::strong_ordering::less);
+ addRow(vdt1, vdt2, Qt::strong_ordering::less);
+ addRow(vtagged1, vtagged2, Qt::strong_ordering::less);
+ addRow(vtagged2, vtagged3, Qt::strong_ordering::less);
+ addRow(vtagged3, vtagged4, Qt::strong_ordering::less);
+ addRow(vtagged4, vtagged5, Qt::strong_ordering::less);
+ addRow(vurl1, vurl2, Qt::strong_ordering::less);
+ addRow(vuuid1, vuuid2, Qt::strong_ordering::less);
+
+ // surprise 1: CBOR sorts strings by length first
+ addRow(vba1, vba2, Qt::strong_ordering::less);
+ addRow(vba2, vba3, Qt::strong_ordering::less);
+ addRow(vs1, vs2, Qt::strong_ordering::less);
+ addRow(vs2, vs3, Qt::strong_ordering::less);
+
+ // surprise 2: CBOR sorts integrals by absolute value
+ addRow(vneg1, vneg2, Qt::strong_ordering::less);
+
+ // surprise 3: CBOR sorts negatives after positives (sign+magnitude)
+ addRow(vint2, vneg1, Qt::strong_ordering::less);
+ addRow(vdouble2, vndouble1, Qt::strong_ordering::less);
// inter-type comparisons
- CHECK_ORDER(vneg2, vba1);
- CHECK_ORDER(vba3, vs1);
- CHECK_ORDER(vs3, va1);
- CHECK_ORDER(va2, vm1);
- CHECK_ORDER(vm2, vdt1);
- CHECK_ORDER(vdt2, vtagged1);
- CHECK_ORDER(vtagged2, vurl1);
- CHECK_ORDER(vurl1, vuuid1);
- CHECK_ORDER(vuuid2, vtagged3);
- CHECK_ORDER(vtagged4, vsimple1);
- CHECK_ORDER(vsimple1, vfalse);
- CHECK_ORDER(vtrue, vnull);
- CHECK_ORDER(vnull, vundef);
- CHECK_ORDER(vundef, vsimple32);
- CHECK_ORDER(vsimple255, vdouble1);
+ addRow(vneg2, vba1, Qt::strong_ordering::less);
+ addRow(vba3, vs1, Qt::strong_ordering::less);
+ addRow(vs3, va1, Qt::strong_ordering::less);
+ addRow(va2, vm1, Qt::strong_ordering::less);
+ addRow(vm2, vdt1, Qt::strong_ordering::less);
+ addRow(vdt2, vtagged1, Qt::strong_ordering::less);
+ addRow(vtagged2, vurl1, Qt::strong_ordering::less);
+ addRow(vurl1, vuuid1, Qt::strong_ordering::less);
+ addRow(vuuid2, vtagged3, Qt::strong_ordering::less);
+ addRow(vtagged4, vsimple1, Qt::strong_ordering::less);
+ addRow(vsimple1, vfalse, Qt::strong_ordering::less);
+ addRow(vtrue, vnull, Qt::strong_ordering::less);
+ addRow(vnull, vundef, Qt::strong_ordering::less);
+ addRow(vundef, vsimple32, Qt::strong_ordering::less);
+ addRow(vsimple255, vdouble1, Qt::strong_ordering::less);
// which shows all doubles sorted after integrals
- CHECK_ORDER(vint2, vdouble1);
- QVERIFY(vint2.toInteger() > vdouble1.toDouble());
-#undef CHECK_ORDER
+ addRow(vint2, vdouble1, Qt::strong_ordering::less);
+
+ // Add some non-US-ASCII strings. In the current implementation, QCborValue
+ // can store a string as either US-ASCII, UTF-8, or UTF-16, so let's exercise
+ // those comparisons.
+
+ // we don't have a QUtf8StringView constructor, so work around it
+ auto utf8string = [](QByteArray str) {
+ Q_ASSERT(str.size() < 24);
+ str.prepend(char(QCborValue::String) + str.size());
+ return QCborValue::fromCbor(str);
+ };
+
+ auto addStringCmp = [&](const char *prefix, const char *tag, QUtf8StringView lhs,
+ QUtf8StringView rhs) {
+ // CBOR orders strings by UTF-8 length
+ auto order = Qt::compareThreeWay(lhs.size(), rhs.size());
+ if (is_eq(order))
+ order = compareThreeWay(lhs, rhs);
+ Q_ASSERT(is_eq(order) || is_lt(order)); // please keep lhs <= rhs!
+
+ QCborValue lhs_utf8 = utf8string(QByteArrayView(lhs).toByteArray());
+ QCborValue rhs_utf8 = utf8string(QByteArrayView(rhs).toByteArray());
+ QCborValue lhs_utf16 = QString::fromUtf8(lhs);
+ QCborValue rhs_utf16 = QString::fromUtf8(rhs);
+
+ QTest::addRow("string-%s%s:utf8-utf8", prefix, tag) << lhs_utf8 << rhs_utf8 << order;
+ QTest::addRow("string-%s%s:utf8-utf16", prefix, tag) << lhs_utf8 << rhs_utf16 << order;
+ QTest::addRow("string-%s%s:utf16-utf8", prefix, tag) << lhs_utf16 << rhs_utf8 << order;
+ QTest::addRow("string-%s%s:utf16-utf16", prefix, tag) << lhs_utf16 << rhs_utf16 << order;
+ };
+ auto addStringCmpSameLength = [&](const char *tag, QUtf8StringView lhs, QUtf8StringView rhs) {
+ Q_ASSERT(lhs.size() == rhs.size());
+ addStringCmp("samelength-", tag, lhs, rhs);
+ };
+ auto addStringCmpShorter = [&](const char *tag, QUtf8StringView lhs, QUtf8StringView rhs) {
+ Q_ASSERT(lhs.size() < rhs.size());
+ addStringCmp("shorter-", tag, lhs, rhs);
+ };
+
+ // ascii-only is already tested
+ addStringCmp("equal-", "1continuation", "ab\u00A0c", "ab\u00A0c");
+ addStringCmp("equal-", "2continuation", "ab\u0800", "ab\u0800");
+ addStringCmp("equal-", "3continuation", "a\U00010000", "a\U00010000");
+
+ // these strings all have the same UTF-8 length (5 bytes)
+ addStringCmpSameLength("less-ascii", "abcde", "ab\u00A0c");
+ addStringCmpSameLength("less-1continuation", "ab\u00A0c", "ab\u07FFc");
+ addStringCmpSameLength("less-2continuation", "ab\u0800", "ab\uFFFC");
+ addStringCmpSameLength("less-3continuation", "a\U00010000", "a\U0010FFFC");
+ addStringCmpSameLength("less-0-vs-1continuation", "abcde", "ab\u00A0c");
+ addStringCmpSameLength("less-0-vs-2continuation", "abcde", "ab\u0800");
+ addStringCmpSameLength("less-0-vs-3continuation", "abcde", "a\U00010000");
+ addStringCmpSameLength("less-1-vs-2continuation", "ab\u00A0c", "ab\uFFFC");
+ addStringCmpSameLength("less-1-vs-3continuation", "ab\u00A0c", "a\U00010000");
+ addStringCmpSameLength("less-2-vs-3continuation", "ab\u0800", "a\U00010000");
+ addStringCmpSameLength("less-2-vs-3continuation_surrogate", "a\uFFFCz", "a\U00010000"); // even though U+D800 < U+FFFC
+
+ // these strings have different lengths in UTF-8
+ // (0continuation already tested)
+ addStringCmpShorter("1continuation", "ab\u00A0", "ab\u00A0c");
+ addStringCmpShorter("2continuation", "ab\u0800", "ab\u0800c");
+ addStringCmpShorter("3continuation", "ab\U00010000", "ab\U00010000c");
+ // most of these have the same length in UTF-16!
+ addStringCmpShorter("0-vs-1continuation", "abc", "ab\u00A0");
+ addStringCmpShorter("0-vs-2continuation", "abcd", "ab\u0800");
+ addStringCmpShorter("0-vs-3continuation", "abcde", "ab\U00010000");
+ addStringCmpShorter("1-vs-2continuation", "ab\u00A0", "ab\u0800");
+ addStringCmpShorter("1-vs-3continuation", "abc\u00A0", "ab\U00010000");
+ addStringCmpShorter("2-vs-3continuation", "ab\u0800", "ab\U00010000");
+
+ // lhs is 4xUTF-16 and 8xUTF-8; rhs is 3xUTF-16 but 9xUTF-8
+ addStringCmpShorter("3x2-vs-2x3continuation", "\U00010000\U00010000", "\u0800\u0800\u0800");
+
+ // slight surprising because normally rhs would sort first ("aa" vs "ab" prefix)
+ // (0continuation_surprise already tested)
+ addStringCmpShorter("1continuation_surprise", "ab\u00A0", "aa\u00A0c");
+ addStringCmpShorter("2continuation_surprise", "ab\u0800", "aa\u0800c");
+ addStringCmpShorter("3continuation_surprise", "ab\U00010000", "aa\U00010000c");
+ addStringCmpShorter("0-vs-1continuation_surprise", "abc", "aa\u00A0");
+ addStringCmpShorter("0-vs-2continuation_surprise", "abcd", "aa\u0800");
+ addStringCmpShorter("0-vs-3continuation_surprise", "abcde", "aa\U00010000");
+ addStringCmpShorter("1-vs-2continuation_surprise", "ab\u00A0", "aa\u0800");
+ addStringCmpShorter("1-vs-3continuation_surprise", "abc\u00A0", "aa\U00010000");
+ addStringCmpShorter("2-vs-3continuation_surprise", "ab\u0800", "aa\U00010000");
+}
+
+void tst_QCborValue::sorting()
+{
+ QFETCH(QCborValue, lhs);
+ QFETCH(QCborValue, rhs);
+ QFETCH(Qt::strong_ordering, expectedOrdering);
+
+ // do a QCOMPARE first so we get a proper QTest error in case QCborValue is
+ // broken
+ if (expectedOrdering == Qt::strong_ordering::equal)
+ QCOMPARE_EQ(lhs, rhs);
+ else if (expectedOrdering == Qt::strong_ordering::less)
+ QCOMPARE_LT(lhs, rhs);
+ else if (expectedOrdering == Qt::strong_ordering::greater)
+ QCOMPARE_GT(lhs, rhs);
+
+ QCborArray array{lhs, rhs};
+
+ QCborValueConstRef lhsCRef = array.constBegin()[0];
+ QCborValueConstRef rhsCRef = array.constBegin()[1];
+ QCborValueRef lhsRef = array[0];
+ QCborValueRef rhsRef = array[1];
+
+ // QCborValue vs QCborValue
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, expectedOrdering);
+ // QCborValueConstRef vs QCborValueConstRef
+ QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsCRef, expectedOrdering);
+ // QCborValueRef vs QCborValueRef
+ QT_TEST_ALL_COMPARISON_OPS(lhsRef, rhsRef, expectedOrdering);
+ // QCborValue vs QCborValueConstRef (and reverse)
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhsCRef, expectedOrdering);
+ // QCborValue vs QCborValueRef (and reverse)
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhsRef, expectedOrdering);
+ // QCborValueConstRef vs QCborValueRef (and reverse)
+ QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsRef, expectedOrdering);
+}
+
+void tst_QCborValue::comparisonMap_data()
+{
+ QTest::addColumn<QCborMap>("left");
+ QTest::addColumn<QCborMap>("right");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrdering");
+
+ QTest::addRow("map{{0, 1}, {10, 0}}, map{{10, 1}, {10, 0}}")
+ << QCborMap{{0, 1}, {10, 0}}
+ << QCborMap{{10, 1}, {10, 0}}
+ << Qt::strong_ordering::greater;
+
+ QTest::addRow("map{{0, 1}, {0, 0}}, map{{0, 1}, {0, 0}}")
+ << QCborMap{{0, 1}, {0, 0}}
+ << QCborMap{{0, 1}, {0, 0}}
+ << Qt::strong_ordering::equivalent;
+
+ QTest::addRow("map{{0, 1}, {10, 0}}, map{{10, 1}, {10, 0}, {10, 0}}")
+ << QCborMap{{10, 1}, {10, 0}}
+ << QCborMap{{0, 1}, {10, 0}, {10, 0}}
+ << Qt::strong_ordering::less;
+}
+
+void tst_QCborValue::comparisonMap()
+{
+ QFETCH(QCborMap, left);
+ QFETCH(QCborMap, right);
+ QFETCH(Qt::strong_ordering, expectedOrdering);
+ QT_TEST_ALL_COMPARISON_OPS(left, right, expectedOrdering);
}
static void addCommonCborData()
@@ -1250,7 +2185,6 @@ static void addCommonCborData()
QTest::newRow("simple0") << QCborValue(QCborValue::SimpleType) << raw("\xe0") << noxfrm;
QTest::newRow("simple1") << QCborValue(QCborSimpleType(1)) << raw("\xe1") << noxfrm;
- QTest::newRow("simple255") << QCborValue(QCborSimpleType(255)) << raw("\xf8\xff") << noxfrm;
QTest::newRow("Undefined") << QCborValue() << raw("\xf7") << noxfrm;
QTest::newRow("Null") << QCborValue(nullptr) << raw("\xf6") << noxfrm;
QTest::newRow("True") << QCborValue(true) << raw("\xf5") << noxfrm;
@@ -1313,19 +2247,23 @@ static void addCommonCborData()
QTest::newRow("DateTime") << QCborValue(dt) // this is UTC
<< "\xc0\x78\x18" + dt.toString(Qt::ISODateWithMs).toLatin1()
<< noxfrm;
- QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC))
+ QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::UTC))
<< raw("\xc0\x78\x18" "2018-01-01T09:00:00.000Z")
<< noxfrm;
- QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::LocalTime))
+ QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0}))
<< raw("\xc0\x77" "2018-01-01T09:00:00.000")
<< noxfrm;
- QTest::newRow("DateTime+01:00") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::OffsetFromUTC, 3600))
- << raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00")
- << noxfrm;
+ QTest::newRow("DateTime+01:00")
+ << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::fromSecondsAheadOfUtc(3600)))
+ << raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00")
+ << noxfrm;
QTest::newRow("Url:Empty") << QCborValue(QUrl()) << raw("\xd8\x20\x60") << noxfrm;
QTest::newRow("Url") << QCborValue(QUrl("HTTPS://example.com/{%30%31}?q=%3Ca+b%20%C2%A9%3E&%26"))
<< raw("\xd8\x20\x78\x27" "https://example.com/{01}?q=<a+b \xC2\xA9>&%26")
<< noxfrm;
+ QTest::newRow("Url:NonAscii") << QCborValue(QUrl("https://example.com/\xc2\xa0"))
+ << raw("\xd8\x20\x76" "https://example.com/\xc2\xa0")
+ << noxfrm;
QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression()) << raw("\xd8\x23\x60") << noxfrm;
QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$"))
<< raw("\xd8\x23\x64" "^.*$") << noxfrm;
@@ -1348,10 +2286,12 @@ void tst_QCborValue::toCbor_data()
// The rest of these tests are conversions whose decoding does not yield
// back the same QCborValue.
+#if QT_CONFIG(signaling_nan)
// Signalling NaN get normalized to quiet ones
QTest::newRow("Double:snan") << QCborValue(qSNaN()) << raw("\xfb\x7f\xf8\0""\0\0\0\0\0") << QCborValue::EncodingOptions();
QTest::newRow("Float:snan") << QCborValue(qSNaN()) << raw("\xfa\x7f\xc0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
QTest::newRow("Float16:snan") << QCborValue(qSNaN()) << raw("\xf9\x7e\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+#endif
// Floating point written as integers are read back as integers
QTest::newRow("UseInteger:0") << QCborValue(0.) << raw("\x00") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
@@ -1395,6 +2335,22 @@ void tst_QCborValue::toCbor()
"\xa1\x01\xd9\xd9\xf7" + result);
}
+void tst_QCborValue::toCborStreamWriter()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QByteArray, result);
+ QFETCH(QCborValue::EncodingOptions, options);
+
+ QByteArray output;
+ QBuffer buffer(&output);
+ buffer.open(QIODevice::WriteOnly);
+ QCborStreamWriter writer(&buffer);
+
+ v.toCbor(writer, options);
+ QCOMPARE(buffer.pos(), result.size());
+ QCOMPARE(output, result);
+}
+
void tst_QCborValue::fromCbor_data()
{
addCommonCborData();
@@ -1408,12 +2364,29 @@ void tst_QCborValue::fromCbor_data()
QTest::newRow("String:Chunked:Empty") << QCborValue(QString())
<< raw("\x7f\xff");
- QTest::newRow("DateTime:NoMilli") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC))
- << raw("\xc0\x74" "2018-01-10T06:24:37Z");
- QTest::newRow("UnixTime_t:Integer") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC))
- << raw("\xc1\x1a\x5a\x55\xb1\xa5");
- QTest::newRow("UnixTime_t:Double") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC))
- << raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00");
+ QTest::newRow("DateTime:NoMilli")
+ << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, QTimeZone::UTC))
+ << raw("\xc0\x74" "2018-01-10T06:24:37Z");
+ // date-only is only permitted local time
+ QTest::newRow("DateTime:NoTime:Local")
+ << QCborValue(QDateTime(QDate(2020, 4, 15), QTime(0, 0)))
+ << raw("\xc0\x6a" "2020-04-15");
+ QTest::newRow("DateTime:24:00:00")
+ << QCborValue(QDateTime(QDate(2020, 4, 16), QTime(0, 0), QTimeZone::UTC))
+ << raw("\xc0\x74" "2020-04-15T24:00:00Z");
+ QTest::newRow("DateTime:+00:00")
+ << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, QTimeZone::UTC))
+ << raw("\xc0\x78\x1d" "2018-01-10T06:24:37.125+00:00");
+ QTest::newRow("DateTime:+01:00")
+ << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125,
+ QTimeZone::fromSecondsAheadOfUtc(60 * 60)))
+ << raw("\xc0\x78\x1d" "2018-01-10T07:24:37.125+01:00");
+ QTest::newRow("UnixTime_t:Integer")
+ << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, QTimeZone::UTC))
+ << raw("\xc1\x1a\x5a\x55\xb1\xa5");
+ QTest::newRow("UnixTime_t:Double")
+ << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, QTimeZone::UTC))
+ << raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00");
QTest::newRow("Url:NotNormalized") << QCborValue(QUrl("https://example.com/\xc2\xa9 "))
<< raw("\xd8\x20\x78\x1dHTTPS://EXAMPLE.COM/%c2%a9%20");
@@ -1425,20 +2398,11 @@ void tst_QCborValue::fromCbor_data()
<< raw("\xd8\x25\x51" "\1\2\3\4""\4\3\2\0""\0\0\0\0""\0\0\0\1""\2");
}
-void tst_QCborValue::fromCbor()
+void fromCbor_common(void (*doCheck)(const QCborValue &, const QByteArray &))
{
QFETCH(QCborValue, v);
QFETCH(QByteArray, result);
- auto doCheck = [](const QCborValue &v, const QByteArray &result) {
- QCborParserError error;
- QCborValue decoded = QCborValue::fromCbor(result, &error);
- QVERIFY2(error.error == QCborError(), qPrintable(error.errorString()));
- QCOMPARE(error.offset, result.size());
- QVERIFY(decoded == v);
- QVERIFY(v == decoded);
- };
-
doCheck(v, result);
if (QTest::currentTestFailed())
return;
@@ -1489,39 +2453,304 @@ void tst_QCborValue::fromCbor()
return;
}
+void tst_QCborValue::fromCbor()
+{
+ auto doCheck = [](const QCborValue &v, const QByteArray &result) {
+ QCborParserError error;
+ QCborValue decoded = QCborValue::fromCbor(result, &error);
+ QVERIFY2(error.error == QCborError(), qPrintable(error.errorString()));
+ QCOMPARE(error.offset, result.size());
+ QVERIFY(decoded == v);
+ QVERIFY(v == decoded);
+ };
+
+ fromCbor_common(doCheck);
+}
+
+void tst_QCborValue::fromCborStreamReaderByteArray()
+{
+ auto doCheck = [](const QCborValue &expected, const QByteArray &data) {
+ QCborStreamReader reader(data);
+ QCborValue decoded = QCborValue::fromCbor(reader);
+ QCOMPARE(reader.lastError(), QCborError());
+ QCOMPARE(reader.currentOffset(), data.size());
+ QVERIFY(decoded == expected);
+ QVERIFY(expected == decoded);
+ };
+
+ fromCbor_common(doCheck);
+}
+
+void tst_QCborValue::fromCborStreamReaderIODevice()
+{
+ auto doCheck = [](const QCborValue &expected, const QByteArray &data) {
+ QBuffer buffer;
+ buffer.setData(data);
+ buffer.open(QIODevice::ReadOnly);
+ QCborStreamReader reader(&buffer);
+ QCborValue decoded = QCborValue::fromCbor(reader);
+ QCOMPARE(reader.lastError(), QCborError());
+ QCOMPARE(reader.currentOffset(), data.size());
+ QVERIFY(decoded == expected);
+ QVERIFY(expected == decoded);
+ QCOMPARE(buffer.pos(), reader.currentOffset());
+ };
+
+ fromCbor_common(doCheck);
+}
+
+#include "../cborlargedatavalidation.cpp"
+
void tst_QCborValue::validation_data()
{
+ // Add QCborStreamReader-specific limitations due to use of QByteArray and
+ // QString, which are allocated by QArrayData::allocate().
+ const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max();
+ const qsizetype MinInvalid = QByteArray::max_size() + 1 - sizeof(QByteArray::size_type);
addValidationColumns();
- addValidationData();
+ addValidationData(MinInvalid);
+ addValidationLargeData(MinInvalid, MaxInvalid);
+
+ // Chunked strings whose total overflows the limit, but each individual
+ // chunk doesn't. 0x5a for 32-bit, 0x5b for 64-bit.
+ char toolong[1 + sizeof(qsizetype)];
+ toolong[0] = sizeof(MinInvalid) > 4 ? 0x5b : 0x5a;
+ qToBigEndian(MinInvalid - 1, toolong + 1);
+ QTest::addRow("bytearray-2chunked+1-too-big-for-qbytearray-%llx", MinInvalid)
+ << ("\x5f\x41z" + QByteArray(toolong, sizeof(toolong)) + '\xff')
+ << 0 << CborErrorUnexpectedEOF;
+ toolong[0] |= 0x20;
+ QTest::addRow("string-2chunked+1-too-big-for-qbytearray-%llx", MinInvalid)
+ << ("\x7f\x61z" + QByteArray(toolong, sizeof(toolong)) + '\xff')
+ << 0 << CborErrorUnexpectedEOF;
// These tests say we have arrays and maps with very large item counts.
// They are meant to ensure we don't pre-allocate a lot of memory
// unnecessarily and possibly crash the application. The actual number of
// elements in the stream is only 2, so we should get an unexpected EOF
- // error. QCborValue internally uses 16 bytes per element, so we get to
- // 2 GB at 2^27 elements.
- QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0");
- QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0");
-
- // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements
- QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0");
+ // error. QCborValue internally uses 16 bytes per element, so we get to 2
+ // GB at 2^27 elements (32-bit) or, theoretically, 2^63 bytes at 2^59
+ // elements (64-bit).
+ if (sizeof(QList<int>::size_type) == sizeof(int)) {
+ // 32-bit sizes (Qt 5 and 32-bit platforms)
+ QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0") << 0 << CborErrorUnexpectedEOF;
+ QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0") << 0 << CborErrorUnexpectedEOF;
+
+ // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements
+ QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0") << 0 << CborErrorDataTooLarge;
+ } else {
+ // 64-bit Qt 6
+ QTest::addRow("very-large-array-no-overflow") << raw("\x9b\x07\xff\xff\xff" "\xff\xff\xff\xff" "\0\0") << 0 << CborErrorDataTooLarge;
+ QTest::addRow("very-large-array-overflow") << raw("\x9b\x40\0\0\0" "\0\0\0\0" "\0\0") << 0 << CborErrorDataTooLarge;
+ }
}
void tst_QCborValue::validation()
{
QFETCH(QByteArray, data);
+ QFETCH(CborError, expectedError);
+ QCborError error = { QCborError::Code(expectedError) };
- QCborParserError error;
- QCborValue decoded = QCborValue::fromCbor(data, &error);
- QVERIFY(error.error != QCborError{});
+ QCborParserError parserError;
+ QCborValue decoded = QCborValue::fromCbor(data, &parserError);
+ QCOMPARE(parserError.error, error);
if (data.startsWith('\x81')) {
// decode without the array prefix
- decoded = QCborValue::fromCbor(data.mid(1), &error);
- QVERIFY(error.error != QCborError{});
+ char *ptr = const_cast<char *>(data.constData());
+ QByteArray mid = QByteArray::fromRawData(ptr + 1, data.size() - 1);
+ decoded = QCborValue::fromCbor(mid, &parserError);
+ QCOMPARE(parserError.error, error);
}
}
+void tst_QCborValue::extendedTypeValidation_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QCborValue>("expected");
+
+ // QDateTime currently stores time in milliseconds, so make sure
+ // we don't overflow
+ {
+ quint64 limit = std::numeric_limits<quint64>::max() / 1000;
+ QTest::newRow("UnixTime_t:integer-overflow-positive")
+ << encode(0xc1, 0x1b, limit + 1)
+ << QCborValue(QCborKnownTags::UnixTime_t, qint64(limit) + 1);
+ QTest::newRow("UnixTime_t:integer-overflow-negative")
+ << encode(0xc1, 0x3b, limit)
+ << QCborValue(QCborKnownTags::UnixTime_t, -qint64(limit) - 1);
+
+ double fplimit = std::numeric_limits<qint64>::min() / (-1000.); // 2^63 ms
+ QTest::newRow("UnixTime_t:fp-overflow-positive")
+ << encode(0xc1, 0xfb, fplimit)
+ << QCborValue(QCborKnownTags::UnixTime_t, fplimit);
+ QTest::newRow("UnixTime_t:fp-overflow-negative")
+ << encode(0xc1, 0xfb, -fplimit)
+ << QCborValue(QCborKnownTags::UnixTime_t, -fplimit);
+ }
+
+ // But in fact, QCborValue stores date/times as their ISO textual
+ // representation, which means it can't represent dates before year 1 or
+ // after year 9999.
+ {
+ QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), QTimeZone::UTC);
+ QTest::newRow("UnixTime_t:negative-year")
+ << encode(0xc1, 0x3b, quint64(-dt.toSecsSinceEpoch()) - 1)
+ << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch());
+
+ dt.setDate(QDate(10000, 1, 1));
+ QTest::newRow("UnixTime_t:year10k")
+ << encode(0xc1, 0x1b, quint64(dt.toSecsSinceEpoch()))
+ << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch());
+ }
+
+ // Invalid ISO date/time strings
+ {
+ auto add = [](const char *tag, const char *str) {
+ QByteArray raw;
+ if (strlen(str) < 0x18)
+ raw = encode(0xc0, 0x60 + int(strlen(str)), str);
+ else
+ raw = encode(0xc0, 0x78, quint8(strlen(str)), str);
+ QTest::addRow("DateTime:%s", tag)
+ << raw << QCborValue(QCborKnownTags::DateTimeString, QString(str));
+ };
+ // tst_QDateTime::fromStringDateFormat has more tests
+ add("junk", "jjj");
+ add("zoned-date-only", "2020-04-15Z");
+ add("month-13", "2020-13-01T00:00:00Z");
+ add("negative-month", "2020--1-01T00:00:00Z");
+ add("jan-32", "2020-01-32T00:00:00Z");
+ add("apr-31", "2020-04-31T00:00:00Z");
+ add("feb-30", "2020-02-30T00:00:00Z");
+ add("feb-29-nonleap", "2021-02-29T00:00:00Z");
+ add("negative-day", "2020-01--1T00:00:00Z");
+ add("bad-separator", "2020-04-15j13:30:59Z");
+ add("hour-25", "2020-04-15T25:00:00Z");
+ add("negative-hour", "2020-04-15T-1:00:00Z");
+ add("minute-60", "2020-04-15T23:60:00Z");
+ add("negative-minute", "2020-04-15T23:-1:00Z");
+ add("second-60", "2020-04-15T23:59:60Z"); // not a leap second
+ add("negative-second", "2020-04-15T23:59:-1Z");
+ add("negative-milli", "2020-04-15T23.59:59.-1Z");
+
+ // walking null
+ char dt[] = "2020-04-15T17:33:32.125Z";
+ quint8 len = quint8(strlen(dt));
+ for (quint8 i = 0; i < len; ++i) {
+ char c = '\0';
+ qSwap(c, dt[i]);
+ QTest::addRow("DateTime:Null-at-%d", i)
+ << encode(0xc0, 0x78, len) + QByteArray(dt, len)
+ << QCborValue(QCborKnownTags::DateTimeString, QLatin1String(dt, len));
+ qSwap(c, dt[i]);
+ }
+ }
+
+ // Improperly-encoded URLs
+ {
+ const char badurl[] = "%zz";
+ QTest::newRow("Url:Invalid")
+ << encode(0xd8, int(QCborKnownTags::Url), 0x60 + int(strlen(badurl)), badurl)
+ << QCborValue(QCborKnownTags::Url, QLatin1String(badurl));
+ }
+}
+
+void tst_QCborValue::extendedTypeValidation()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QCborValue, expected);
+
+ QCborParserError error;
+ QCborValue decoded = QCborValue::fromCbor(data, &error);
+ QVERIFY2(error.error == QCborError(), qPrintable(error.errorString()));
+ QCOMPARE(error.offset, data.size());
+ QT_TEST_EQUALITY_OPS(decoded, expected, true);
+
+ QByteArray encoded = decoded.toCbor();
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ // behavior change, see qdatetime.cpp:fromIsoTimeString
+ QEXPECT_FAIL("DateTime:Null-at-19", "QDateTime parsing fixed, but only in 6.0", Abort);
+#endif
+ QCOMPARE(encoded, data);
+}
+
+void tst_QCborValue::hugeDeviceValidation_data()
+{
+ // because QCborValue will attempt to retain the original string in UTF-8,
+ // the size which it can't store is actually the byte array size
+ addValidationHugeDevice(QByteArray::max_size() + 1, QByteArray::max_size() + 1);
+}
+
+void tst_QCborValue::hugeDeviceValidation()
+{
+#if defined(Q_OS_WASM)
+ QSKIP("This test tries to allocate a huge memory buffer,"
+ " causes problem on WebAssembly platform which has limited resources.");
+#endif // Q_OS_WASM
+
+ QFETCH(QSharedPointer<QIODevice>, device);
+ QFETCH(CborError, expectedError);
+ QCborError error = { QCborError::Code(expectedError) };
+
+ device->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+ QCborStreamReader reader(device.data());
+ QCborValue decoded = QCborValue::fromCbor(reader);
+ QCOMPARE(reader.lastError(), error);
+}
+
+void tst_QCborValue::recursionLimit_data()
+{
+ constexpr int RecursionAttempts = 4096;
+ QTest::addColumn<QByteArray>("data");
+ QByteArray arrays(RecursionAttempts, char(0x81));
+ QByteArray _arrays(RecursionAttempts, char(0x9f));
+ QByteArray maps(RecursionAttempts, char(0xa1));
+ QByteArray _maps(RecursionAttempts, char(0xbf));
+ QByteArray tags(RecursionAttempts, char(0xc0));
+
+ QTest::newRow("array-nesting-too-deep") << arrays;
+ QTest::newRow("_array-nesting-too-deep") << _arrays;
+ QTest::newRow("map-nesting-too-deep") << maps;
+ QTest::newRow("_map-nesting-too-deep") << _maps;
+ QTest::newRow("tag-nesting-too-deep") << tags;
+
+ QByteArray mixed(5 * RecursionAttempts, Qt::Uninitialized);
+ char *ptr = mixed.data();
+ for (int i = 0; i < RecursionAttempts; ++i) {
+ quint8 type = qBound(quint8(QCborStreamReader::Array), quint8(i & 0x80), quint8(QCborStreamReader::Tag));
+ quint8 additional_info = i & 0x1f;
+ if (additional_info == 0x1f)
+ (void)additional_info; // leave it
+ else if (additional_info > 0x1a)
+ additional_info = 0x1a;
+ else if (additional_info < 1)
+ additional_info = 1;
+
+ *ptr++ = type | additional_info;
+ if (additional_info == 0x18) {
+ *ptr++ = uchar(i);
+ } else if (additional_info == 0x19) {
+ qToBigEndian(ushort(i), ptr);
+ ptr += 2;
+ } else if (additional_info == 0x1a) {
+ qToBigEndian(uint(i), ptr);
+ ptr += 4;
+ }
+ }
+
+ QTest::newRow("mixed-nesting-too-deep") << mixed;
+}
+
+void tst_QCborValue::recursionLimit()
+{
+ QFETCH(QByteArray, data);
+
+ QCborParserError error;
+ QCborValue decoded = QCborValue::fromCbor(data, &error);
+ QCOMPARE(error.error, QCborError::NestingTooDeep);
+}
+
void tst_QCborValue::toDiagnosticNotation_data()
{
QTest::addColumn<QCborValue>("v");
@@ -1539,9 +2768,9 @@ void tst_QCborValue::toDiagnosticNotation_data()
if (t == QCborValue::Double)
return QTest::addRow("%sDouble:%g", prefix, v.toDouble());
if (t == QCborValue::ByteArray)
- return QTest::addRow("%sByteArray:%d", prefix, v.toByteArray().size());
+ return QTest::addRow("%sByteArray:%zd", prefix, size_t(v.toByteArray().size()));
if (t == QCborValue::String)
- return QTest::addRow("%sString:%d", prefix, v.toString().size());
+ return QTest::addRow("%sString:%zd", prefix, size_t(v.toString().size()));
QByteArray typeString = me.valueToKey(t);
Q_ASSERT(!typeString.isEmpty());
@@ -1690,6 +2919,449 @@ void tst_QCborValue::toDiagnosticNotation()
QCOMPARE(result, expected);
}
+void tst_QCborValue::cborValueRef_data()
+{
+ basics_data();
+
+ // Add tagged data and non-empty containers (non-basic)
+ QTest::newRow("Array:nonempty") << QCborValue::Array << QCborValue(QCborArray{0});
+ QTest::newRow("Map:nonempty") << QCborValue::Map << QCborValue(QCborMap{ { 0, 1 } });
+ QTest::newRow("Tagged") << QCborValue::Tag << QCborValue(QCborKnownTags::Base64, QByteArray());
+}
+
+template <typename ValueRef> static void cborValueRef_template()
+{
+ const QCborArray otherArray = {2};
+ const QCborMap otherMap = { { 2, 21 } };
+ const QDateTime otherDateTime = QDateTime::fromSecsSinceEpoch(1636654201);
+ const QUrl otherUrl("http://example.org");
+ const QRegularExpression otherRE("[.]*");
+ const QUuid otherUuid = QUuid::createUuid();
+
+ QFETCH(QCborValue, v);
+ QCborArray a = { v };
+ const ValueRef ref = a[0];
+
+ QT_TEST_EQUALITY_OPS(ref, v, true);
+ QVERIFY(ref.compare(v) == 0);
+ QVERIFY(v.compare(ref) == 0);
+
+ // compare properties of the QCborValueRef against the QCborValue it represents
+ QCOMPARE(ref.type(), v.type());
+ QCOMPARE(ref.isInteger(), v.isInteger());
+ QCOMPARE(ref.isByteArray(), v.isByteArray());
+ QCOMPARE(ref.isString(), v.isString());
+ QCOMPARE(ref.isArray(), v.isArray());
+ QCOMPARE(ref.isMap(), v.isMap());
+ QCOMPARE(ref.isFalse(), v.isFalse());
+ QCOMPARE(ref.isTrue(), v.isTrue());
+ QCOMPARE(ref.isBool(), v.isBool());
+ QCOMPARE(ref.isNull(), v.isNull());
+ QCOMPARE(ref.isUndefined(), v.isUndefined());
+ QCOMPARE(ref.isDouble(), v.isDouble());
+ QCOMPARE(ref.isDateTime(), v.isDateTime());
+ QCOMPARE(ref.isUrl(), v.isUrl());
+ QCOMPARE(ref.isRegularExpression(), v.isRegularExpression());
+ QCOMPARE(ref.isUuid(), v.isUuid());
+ QCOMPARE(ref.isInvalid(), v.isInvalid());
+ QCOMPARE(ref.isContainer(), v.isContainer());
+ QCOMPARE(ref.isSimpleType(), v.isSimpleType());
+ QCOMPARE(ref.isSimpleType(QCborSimpleType::False), v.isSimpleType(QCborSimpleType::False));
+ QCOMPARE(ref.isSimpleType(QCborSimpleType::True), v.isSimpleType(QCborSimpleType::True));
+ QCOMPARE(ref.isSimpleType(QCborSimpleType::Null), v.isSimpleType(QCborSimpleType::Null));
+ QCOMPARE(ref.isSimpleType(QCborSimpleType::Undefined), v.isSimpleType(QCborSimpleType::Undefined));
+ QCOMPARE(ref.isSimpleType(QCborSimpleType(255)), v.isSimpleType(QCborSimpleType(255)));
+
+ QCOMPARE(ref.tag(), v.tag());
+ QCOMPARE(ref.taggedValue(), v.taggedValue());
+
+ QCOMPARE(ref.toBool(false), v.toBool(false));
+ QCOMPARE(ref.toBool(true), v.toBool(true));
+ QCOMPARE(ref.toInteger(47), v.toInteger(47));
+ QCOMPARE(ref.toDouble(47), v.toDouble(47));
+ QCOMPARE(ref.toByteArray("other"), v.toByteArray("other"));
+ QCOMPARE(ref.toString("other"), v.toString("other"));
+ QCOMPARE(ref.toArray(otherArray), v.toArray(otherArray));
+ QCOMPARE(ref.toMap(otherMap), v.toMap(otherMap));
+ QCOMPARE(ref.toDateTime(otherDateTime), v.toDateTime(otherDateTime));
+ QCOMPARE(ref.toRegularExpression(otherRE), v.toRegularExpression(otherRE));
+ QCOMPARE(ref.toUrl(otherUrl), v.toUrl(otherUrl));
+ QCOMPARE(ref.toUuid(otherUuid), v.toUuid(otherUuid));
+ QCOMPARE(ref.toSimpleType(QCborSimpleType(254)), v.toSimpleType(QCborSimpleType(254)));
+
+ QCOMPARE(ref.toArray().isEmpty(), v.toArray().isEmpty());
+ QCOMPARE(ref.toMap().isEmpty(), v.toMap().isEmpty());
+ QCOMPARE(ref[0], std::as_const(v)[0]);
+ QCOMPARE(ref[QLatin1String("other")], std::as_const(v)[QLatin1String("other")]);
+ QCOMPARE(ref[QString("other")], std::as_const(v)[QString("other")]);
+
+ if (qIsNaN(v.toDouble()))
+ QCOMPARE(qIsNaN(ref.toVariant().toDouble()), qIsNaN(v.toVariant().toDouble()));
+ else
+ QCOMPARE(ref.toVariant(), v.toVariant());
+ QCOMPARE(ref.toJsonValue(), v.toJsonValue());
+ QCOMPARE(ref.toCbor(), v.toCbor());
+ QCOMPARE(ref.toDiagnosticNotation(), v.toDiagnosticNotation());
+}
+
+void tst_QCborValue::cborValueRef()
+{
+ cborValueRef_template<QCborValueRef>();
+}
+
+void tst_QCborValue::cborValueConstRef()
+{
+ cborValueRef_template<QCborValueConstRef>();
+}
+
+void tst_QCborValue::cborValueRefMutatingArray()
+{
+ // complements arrayMutation()
+ QFETCH(QCborValue, v);
+
+ {
+ QCborArray origArray = { 123 };
+ QCborArray a = { QCborValue(origArray) };
+ QCborValueRef ref = a[0];
+ QVERIFY(ref.isArray());
+ QVERIFY(!ref.toArray().isEmpty());
+
+ // this will force the array to grow
+ ref[1] = v;
+
+ QCborValue va = a.at(0);
+ QVERIFY(va.isArray());
+ QCOMPARE(va.toArray().size(), 2);
+ QCOMPARE(va.toArray().first(), 123);
+ QT_TEST_EQUALITY_OPS(va.toArray().last(), v, true);
+
+ // ensure the array didn't get modified
+ QT_TEST_EQUALITY_OPS(origArray, QCborArray{123}, true);
+ }
+ {
+ QCborArray emptyArray;
+ QCborArray a = { QCborValue(emptyArray) };
+ QCborValueRef ref = a[0];
+ QVERIFY(ref.isArray());
+ QVERIFY(ref.toArray().isEmpty());
+
+ // this will force the array to become non-empty
+ ref[1] = v;
+
+ QCborValue va = a.at(0);
+ QVERIFY(va.isArray());
+ QCOMPARE(va.toArray().size(), 2);
+ QT_TEST_EQUALITY_OPS(va.toArray().first(), QCborValue(), true);
+ QT_TEST_EQUALITY_OPS(va.toArray().last(), v, true);
+
+ // ensure the array didn't get modified
+ QT_TEST_EQUALITY_OPS(emptyArray, QCborArray(), true);
+ }
+ {
+ QCborArray emptyArray = { 123, 456 };
+ emptyArray.takeFirst();
+ emptyArray.takeFirst();
+ QCborArray a = { QCborValue(emptyArray) };
+ QCborValueRef ref = a[0];
+ QVERIFY(ref.isArray());
+ QVERIFY(ref.toArray().isEmpty());
+
+ // this will force the array to become non-empty
+ ref[1] = v;
+
+ QCborValue va = a.at(0);
+ QVERIFY(va.isArray());
+ QCOMPARE(va.toArray().size(), 2);
+ QT_TEST_EQUALITY_OPS(va.toArray().first(), QCborValue(), true);
+ QT_TEST_EQUALITY_OPS(va.toArray().last(), v, true);
+
+ // ensure the array didn't get modified
+ QT_TEST_EQUALITY_OPS(emptyArray, QCborArray(), true);
+ }
+}
+
+void tst_QCborValue::cborValueRefMutatingMapIntKey()
+{
+ // complements mapMutation()
+ QFETCH(QCborValue, v);
+ QCborValue::Type type = v.type();
+
+ auto executeTest = [=](qint64 index) {
+ QCborArray a = { v };
+ QCborValueRef ref = a[0];
+
+ if (type == QCborValue::Array && !v.toArray().isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, "Using CBOR array as map forced conversion");
+ ref[index] = v;
+
+ QCborValue vm = a.at(0);
+ QVERIFY(vm.isMap());
+ QCOMPARE(vm.toMap()[index].type(), type);
+ QCOMPARE(vm.toMap()[index], v);
+
+ if (type == QCborValue::Array && !v.toArray().isEmpty())
+ QCOMPARE(vm.toMap()[0], v.toArray()[0]);
+ else if (type == QCborValue::Map && !v.toMap().isEmpty())
+ QCOMPARE(vm.toMap()[0], v.toMap()[0]);
+ };
+ // accessing a negative index causes it to become a map
+ executeTest(-1);
+ if (QTest::currentTestFailed())
+ return;
+
+ // if the index is bigger than 0x10000, the array becomes a map
+ executeTest(0x10000);
+ if (QTest::currentTestFailed())
+ return;
+
+ if (type != QCborValue::Array)
+ executeTest(5);
+}
+
+template <typename String> static void cborValueRefMutatingMapStringKey_template(const String &key)
+{
+ // complements mapMutation() too
+ QFETCH(QCborValue, v);
+ QCborValue::Type type = v.type();
+ QCborArray a = { v };
+ QCborValueRef ref = a[0];
+
+ if (type == QCborValue::Array && !v.toArray().isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, "Using CBOR array as map forced conversion");
+
+ // force conversion to map
+ ref[key] = v;
+
+ QCborValue vm = a.at(0);
+ QVERIFY(vm.isMap());
+ QCOMPARE(vm.toMap()[key].type(), type);
+ QCOMPARE(vm.toMap()[key], v);
+
+ if (type == QCborValue::Array && !v.toArray().isEmpty())
+ QCOMPARE(vm.toMap()[0], v.toArray()[0]);
+ else if (type == QCborValue::Map && !v.toMap().isEmpty())
+ QCOMPARE(vm.toMap()[0], v.toMap()[0]);
+}
+
+void tst_QCborValue::cborValueRefMutatingMapLatin1StringKey()
+{
+ cborValueRefMutatingMapStringKey_template(QLatin1String("other"));
+}
+
+void tst_QCborValue::cborValueRefMutatingMapStringKey()
+{
+ cborValueRefMutatingMapStringKey_template(QString("other"));
+}
+
+void tst_QCborValue::datastreamSerialization_data()
+{
+ addCommonCborData();
+}
+
+void tst_QCborValue::datastreamSerialization()
+{
+ QFETCH(QCborValue, v);
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << v;
+ QDataStream load(buffer);
+ QCborValue output;
+ load >> output;
+ QCOMPARE(output, v);
+ }
+ if (v.isArray()) {
+ QCborArray array = v.toArray();
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << array;
+ QDataStream load(buffer);
+ QCborValue output;
+ load >> output;
+ QCOMPARE(output, array);
+ } else if (v.isMap()) {
+ QCborMap map = v.toMap();
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << map;
+ QDataStream load(buffer);
+ QCborValue output;
+ load >> output;
+ QCOMPARE(output, map);
+ }
+}
+
+void tst_QCborValue::streamVariantSerialization()
+{
+ // Check interface only, implementation is tested through to and from
+ // cbor functions.
+ QByteArray buffer;
+ {
+ QCborArray array{665, 666, 667};
+ QVariant output;
+ QVariant variant = QVariant::fromValue(array);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QCborArray);
+ QCOMPARE(qvariant_cast<QCborArray>(output), array);
+ QT_TEST_EQUALITY_OPS(qvariant_cast<QCborArray>(output), array, true);
+ }
+ {
+ QCborMap obj{{"foo", 42}};
+ QVariant output;
+ QVariant variant = QVariant::fromValue(obj);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QCborMap);
+ QCOMPARE(qvariant_cast<QCborMap>(output), obj);
+ }
+ {
+ QCborValue value{42};
+ QVariant output;
+ QVariant variant = QVariant::fromValue(value);
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << variant;
+ QDataStream load(buffer);
+ load >> output;
+ QCOMPARE(output.userType(), QMetaType::QCborValue);
+ QCOMPARE(qvariant_cast<QCborValue>(output), value);
+ }
+}
+
+void tst_QCborValue::debugOutput_data()
+{
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QString>("expected");
+
+ QDateTime dt(QDate(2020, 4, 18), QTime(13, 41, 22, 123), QTimeZone::UTC);
+ QBitArray bits = QBitArray::fromBits("\x79\x03", 11);
+
+ QTest::newRow("Undefined") << QCborValue() << "QCborValue()";
+ QTest::newRow("Null") << QCborValue(nullptr) << "QCborValue(nullptr)";
+ QTest::newRow("False") << QCborValue(false) << "QCborValue(false)";
+ QTest::newRow("True") << QCborValue(true) << "QCborValue(true)";
+ QTest::newRow("simpletype")
+ << QCborValue(QCborSimpleType(0)) << "QCborValue(QCborSimpleType(0))";
+ QTest::newRow("Integer:0") << QCborValue(0) << "QCborValue(0)";
+ QTest::newRow("Double:0") << QCborValue(0.) << "QCborValue(0.0)";
+ QTest::newRow("ByteArray")
+ << QCborValue(raw("Hello\0World")) << "QCborValue(QByteArray(\"Hello\\x00World\"))";
+ QTest::newRow("String")
+ << QCborValue("Hello\x7fWorld") << "QCborValue(\"Hello\\u007FWorld\")";
+ QTest::newRow("DateTime")
+ << QCborValue(dt) << "QCborValue(QDateTime(2020-04-18 13:41:22.123 UTC Qt::UTC))";
+ QTest::newRow("Url")
+ << QCborValue(QUrl("http://example.com")) << "QCborValue(QUrl(\"http://example.com\"))";
+ QTest::newRow("RegularExpression")
+ << QCborValue(QRegularExpression("^.*$"))
+ << "QCborValue(QRegularExpression(\"^.*$\", QRegularExpression::PatternOptions(\"NoPatternOption\")))";
+ QTest::newRow("Uuid")
+ << QCborValue(QUuid()) << "QCborValue(QUuid(\"{00000000-0000-0000-0000-000000000000}\"))";
+
+ QTest::newRow("Tag-1387671238")
+ << QCborValue(QCborTag(1387671238), QCborValue())
+ << "QCborValue(QCborTag(1387671238), QCborValue())";
+ QTest::newRow("Tag-55799")
+ << QCborValue(QCborKnownTags::Signature, QCborValue("Signature"))
+ << "QCborValue(QCborKnownTags::Signature, QCborValue(\"Signature\"))";
+
+ // arrays and maps
+ QTest::newRow("Array:Empty") << QCborValue(QCborArray()) << "QCborValue(QCborArray{})";
+ QTest::newRow("Map:Empty") << QCborValue(QCborMap()) << "QCborValue(QCborMap{})";
+ QTest::newRow("Array")
+ << QCborValue(QCborArray{1, 2., nullptr})
+ << "QCborValue(QCborArray{QCborValue(1), QCborValue(2.0), QCborValue(nullptr)})";
+ QTest::newRow("Map")
+ << QCborValue(QCborMap{{1, 2.}, {nullptr, "Hello"}, {"World", QCborArray()}})
+ << "QCborValue(QCborMap{"
+ "{QCborValue(1), QCborValue(2.0)}, "
+ "{QCborValue(nullptr), QCborValue(\"Hello\")}, "
+ "{QCborValue(\"World\"), QCborValue(QCborArray{})}"
+ "})";
+
+ // usually impossible types
+ QTest::newRow("Unknown-Basic")
+ << QCborValue(QCborValue::Type(0xfb)) << "QCborValue(<unknown type 0xfb>)";
+ QTest::newRow("Unknown-Extended")
+ << QCborValue(QCborValue::Type(0x10000 + 21)) << "QCborValue(<unknown type 0x10015>)";
+ QTest::newRow("Invalid") << QCborValue(QCborValue::Invalid) << "QCborValue(<invalid>)";
+}
+
+void tst_QCborValue::debugOutput()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QString, expected);
+
+ QTest::ignoreMessage(QtDebugMsg, expected.toUtf8());
+ qDebug() << v;
+}
+
+void tst_QCborValue::testlibFormatting_data()
+{
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QString>("expected");
+
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+
+ QTest::newRow("Undefined") << QCborValue() << "QCborValue()";
+ QTest::newRow("Null") << QCborValue(nullptr) << "QCborValue(nullptr)";
+ QTest::newRow("False") << QCborValue(false) << "QCborValue(false)";
+ QTest::newRow("True") << QCborValue(true) << "QCborValue(true)";
+ QTest::newRow("simpletype")
+ << QCborValue(QCborSimpleType(0)) << "QCborValue(QCborSimpleType(0))";
+ QTest::newRow("Integer:0") << QCborValue(0) << "QCborValue(Integer, 0)";
+ QTest::newRow("Double:0") << QCborValue(0.) << "QCborValue(Double, 0)"; // must be integer!
+ QTest::newRow("ByteArray")
+ << QCborValue(raw("Hello\0World")) << "QCborValue(ByteArray, \"Hello\\x00World\")";
+ QTest::newRow("String")
+ << QCborValue("Hej v\xc3\xa4rlden") << "QCborValue(String, \"Hej v\\u00E4rlden\")";
+ QTest::newRow("DateTime")
+ << QCborValue(dt) << QString("QCborValue(DateTime, \"%1\")").arg(dt.toString(Qt::ISODateWithMs));
+ QTest::newRow("Url")
+ << QCborValue(QUrl("http://example.com")) << "QCborValue(Url, \"http://example.com\")";
+ QTest::newRow("RegularExpression")
+ << QCborValue(QRegularExpression("^.*$")) << "QCborValue(RegularExpression, \"^.*$\")";
+ QTest::newRow("Uuid")
+ << QCborValue(QUuid()) << "QCborValue(Uuid, {00000000-0000-0000-0000-000000000000})";
+
+ QTest::newRow("Tag")
+ << QCborValue(QCborKnownTags::Signature, QCborValue())
+ << "QCborValue(QCborTag(55799), QCborValue())";
+
+ // arrays and maps
+ QTest::newRow("Array:Empty") << QCborValue(QCborArray()) << "QCborValue(Array, [])";
+ QTest::newRow("Map:Empty") << QCborValue(QCborMap()) << "QCborValue(Map, {})";
+ QTest::newRow("Array")
+ << QCborValue(QCborArray{1, 2., nullptr})
+ << "QCborValue(Array, [QCborValue(Integer, 1), QCborValue(Double, 2), QCborValue(nullptr)])";
+ QTest::newRow("Map")
+ << QCborValue(QCborMap{{1, 2.}, {nullptr, "Hello"}, {"World", QCborArray()}})
+ << "QCborValue(Map, {"
+ "QCborValue(Integer, 1): QCborValue(Double, 2), "
+ "QCborValue(nullptr): QCborValue(String, \"Hello\"), "
+ "QCborValue(String, \"World\"): QCborValue(Array, [])"
+ "})";
+
+ // usually impossible types
+ QTest::newRow("Unknown-Basic")
+ << QCborValue(QCborValue::Type(0xfb)) << "QCborValue(<unknown type 0xfb>)";
+ QTest::newRow("Unknown-Extended")
+ << QCborValue(QCborValue::Type(0x10000 + 21)) << "QCborValue(<unknown type 0x10015>)";
+ QTest::newRow("Invalid") << QCborValue(QCborValue::Invalid) << "QCborValue(<invalid>)";
+}
+
+void tst_QCborValue::testlibFormatting()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QString, expected);
+
+ QScopedArrayPointer<char> hold(QTest::toString(v));
+ QString actual = hold.get();
+ QCOMPARE(actual, expected);
+}
+
QTEST_MAIN(tst_QCborValue)
#include "tst_qcborvalue.moc"
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt b/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt
new file mode 100644
index 0000000000..14ac0514f9
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborvalue_json/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcborvalue_json Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcborvalue_json LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcborvalue_json
+ SOURCES
+ tst_qcborvalue_json.cpp
+)
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro b/tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro
deleted file mode 100644
index c11000b7c2..0000000000
--- a/tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-QT = core testlib
-TARGET = tst_qcborvalue_json
-CONFIG += testcase
-SOURCES += \
- tst_qcborvalue_json.cpp
-
-DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
index 56245a7173..941bfa4008 100644
--- a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
@@ -1,44 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcborvalue.h>
-#include <QtTest>
+#include <QTest>
+#include <QJsonValue>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QVariant>
+#include <QVariantMap>
+#include <QVariantList>
Q_DECLARE_METATYPE(QCborValue)
@@ -80,7 +50,7 @@ void tst_QCborValue_Json::toVariant_data()
if (v.type() == QCborValue::Double)
return QTest::addRow("Double:%g", exp.toDouble());
if (v.type() == QCborValue::ByteArray || v.type() == QCborValue::String)
- return QTest::addRow("%s:%d", typeString, exp.toString().size());
+ return QTest::addRow("%s:%zd", typeString, size_t(exp.toString().size()));
if (v.type() >= 0x10000)
return QTest::newRow(exp.typeName());
return QTest::newRow(typeString);
@@ -89,7 +59,7 @@ void tst_QCborValue_Json::toVariant_data()
};
// good JSON matching:
- add(QCborValue(), QVariant(), QJsonValue::Undefined);
+ add(QCborValue(), QVariant(), QJsonValue::Null);
add(nullptr, QVariant::fromValue(nullptr), QJsonValue::Null);
add(false, false, false);
add(true, true, true);
@@ -97,9 +67,12 @@ void tst_QCborValue_Json::toVariant_data()
add(1, 1, 1);
add(-1, -1, -1);
add(0., 0., 0.);
+ add(2., 2., 2.);
add(1.25, 1.25, 1.25);
add(-1.25, -1.25, -1.25);
add("Hello", "Hello", "Hello");
+ add(std::numeric_limits<qint64>::max(), std::numeric_limits<qint64>::max(), std::numeric_limits<qint64>::max());
+ add(std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min());
// converts to string in JSON:
add(QByteArray("Hello"), QByteArray("Hello"), "SGVsbG8");
@@ -123,14 +96,6 @@ void tst_QCborValue_Json::toVariant_data()
<< QVariant(qQNaN())
<< QJsonValue();
- // large integral values lose precision in JSON
- QTest::newRow("Integer:max") << QCborValue(std::numeric_limits<qint64>::max())
- << QVariant(std::numeric_limits<qint64>::max())
- << QJsonValue(std::numeric_limits<qint64>::max());
- QTest::newRow("Integer:min") << QCborValue(std::numeric_limits<qint64>::min())
- << QVariant(std::numeric_limits<qint64>::min())
- << QJsonValue(std::numeric_limits<qint64>::min());
-
// empty arrays and maps
add(QCborArray(), QVariantList(), QJsonArray());
add(QCborMap(), QVariantMap(), QJsonObject());
@@ -153,8 +118,8 @@ void tst_QCborValue_Json::toVariant()
QCOMPARE(v.toVariant(), variant);
if (variant.isValid()) {
QVariant variant2 = QVariant::fromValue(v);
- QVERIFY(variant2.canConvert(variant.userType()));
- QVERIFY(variant2.convert(variant.userType()));
+ QVERIFY(variant2.canConvert(variant.metaType()));
+ QVERIFY(variant2.convert(variant.metaType()));
QCOMPARE(variant2, variant);
}
@@ -229,7 +194,7 @@ void tst_QCborValue_Json::fromVariant()
QCOMPARE(QCborArray::fromVariantList({variant}), QCborArray{v});
QCOMPARE(QCborArray::fromVariantList({variant, variant}), QCborArray({v, v}));
- if (variant.type() == QVariant::String) {
+ if (variant.metaType() == QMetaType(QMetaType::QString)) {
QString s = variant.toString();
QCOMPARE(QCborArray::fromStringList({s}), QCborArray{v});
QCOMPARE(QCborArray::fromStringList({s, s}), QCborArray({v, v}));
@@ -257,6 +222,10 @@ void tst_QCborValue_Json::fromJson_data()
QTest::newRow("0") << QCborValue(0) << QJsonValue(0.);
QTest::newRow("1") << QCborValue(1) << QJsonValue(1);
QTest::newRow("1.5") << QCborValue(1.5) << QJsonValue(1.5);
+ QTest::newRow("Integer:max") << QCborValue(std::numeric_limits<qint64>::max())
+ << QJsonValue(std::numeric_limits<qint64>::max());
+ QTest::newRow("Integer:min") << QCborValue(std::numeric_limits<qint64>::min())
+ << QJsonValue(std::numeric_limits<qint64>::min());
QTest::newRow("string") << QCborValue("Hello") << QJsonValue("Hello");
QTest::newRow("array") << QCborValue(QCborValue::Array) << QJsonValue(QJsonValue::Array);
QTest::newRow("map") << QCborValue(QCborValue::Map) << QJsonValue(QJsonValue::Object);
diff --git a/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt b/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt
new file mode 100644
index 0000000000..ebbb232362
--- /dev/null
+++ b/tests/auto/corelib/serialization/qdatastream/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdatastream Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatastream LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "datastream.q42")
+list(APPEND test_data "typedef.q5")
+
+qt_internal_add_test(tst_qdatastream
+ SOURCES
+ tst_qdatastream.cpp
+ LIBRARIES
+ Qt::Gui
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp b/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp
new file mode 100644
index 0000000000..6cc2755d8a
--- /dev/null
+++ b/tests/auto/corelib/serialization/qdatastream/gen_typedefq5.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QDataStream>
+#include <QPair>
+#include <QFile>
+#include <QVariant>
+#include <QDebug>
+
+using CustomPair = QPair<int, int>;
+QDataStream &operator<<(QDataStream &ds, CustomPair pd)
+{ return ds << pd.first << pd.second; }
+QDataStream &operator>>(QDataStream &ds, CustomPair &pd)
+{ return ds >> pd.first >> pd.second; }
+Q_DECLARE_METATYPE(CustomPair)
+
+
+int main() {
+ qRegisterMetaTypeStreamOperators<CustomPair>();
+ QFile out("typedef.q5");
+ out.open(QIODevice::ReadWrite);
+ QDataStream stream(&out);
+ stream.setVersion(QDataStream::Qt_5_15);
+ CustomPair p {42, 100};
+ qDebug() << p.first << p.second;
+ stream << QVariant::fromValue(p);
+}
diff --git a/tests/auto/corelib/serialization/qdatastream/qdatastream.pro b/tests/auto/corelib/serialization/qdatastream/qdatastream.pro
deleted file mode 100644
index 25f8b889a0..0000000000
--- a/tests/auto/corelib/serialization/qdatastream/qdatastream.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdatastream
-QT += testlib
-SOURCES = tst_qdatastream.cpp
-
-TESTDATA += datastream.q42
-
-android:!android-embedded {
- RESOURCES += \
- testdata.qrc
-}
diff --git a/tests/auto/corelib/serialization/qdatastream/testdata.qrc b/tests/auto/corelib/serialization/qdatastream/testdata.qrc
deleted file mode 100644
index fb63cb3438..0000000000
--- a/tests/auto/corelib/serialization/qdatastream/testdata.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>datastream.q42</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
index 041d9d7a09..77ca884897 100644
--- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
+++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
@@ -1,39 +1,33 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QBuffer>
+#include <QEasingCurve>
+#include <QJsonValue>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QtEndian>
+
#include <QtGui/QBitmap>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
#include <QtGui/QPalette>
-#include <QtGui/QPixmap>
+#include <QtGui/QPen>
#include <QtGui/QPicture>
+#include <QtGui/QPixmap>
#include <QtGui/QTextLength>
-#include <QtGui/QPainter>
-#include <QtGui/QPen>
+
+using namespace Qt::StringLiterals;
+
+static_assert(QTypeTraits::has_ostream_operator_v<QDataStream, int>);
+static_assert(QTypeTraits::has_ostream_operator_v<QDataStream, QList<int>>);
+static_assert(QTypeTraits::has_ostream_operator_v<QDataStream, QMap<int, QString>>);
+struct NonStreamable {};
+static_assert(!QTypeTraits::has_ostream_operator_v<QDataStream, NonStreamable>);
+static_assert(!QTypeTraits::has_ostream_operator_v<QDataStream, QList<NonStreamable>>);
+static_assert(!QTypeTraits::has_ostream_operator_v<QDataStream, QMap<int, NonStreamable>>);
class tst_QDataStream : public QObject
{
@@ -110,15 +104,23 @@ private slots:
void stream_QString_data();
void stream_QString();
- void stream_QRegExp_data();
- void stream_QRegExp();
+#if QT_CONFIG(regularexpression)
+ void stream_QRegularExpression_data();
+ void stream_QRegularExpression();
+#endif
void stream_Map_data();
void stream_Map();
+ void stream_MultiMap_data();
+ void stream_MultiMap();
+
void stream_Hash_data();
void stream_Hash();
+ void stream_MultiHash_data();
+ void stream_MultiHash();
+
void stream_qint64_data();
void stream_qint64();
@@ -132,9 +134,19 @@ private slots:
void stream_atEnd();
void stream_writeError();
+ void stream_writeSizeLimitExceeded();
void stream_QByteArray2();
+ void stream_QJsonDocument();
+ void stream_QJsonArray();
+ void stream_QJsonObject();
+ void stream_QJsonValue();
+
+ void stream_QCborArray();
+ void stream_QCborMap();
+ void stream_QCborValue();
+
void setVersion_data();
void setVersion();
@@ -166,12 +178,14 @@ private slots:
void status_QHash_QMap();
- void status_QLinkedList_QList_QVector();
+ void status_QList_QVector();
void streamToAndFromQByteArray();
void streamRealDataTypes();
+ void enumTest();
+
void floatingPointPrecision();
void compatibility_Qt5();
@@ -185,6 +199,8 @@ private slots:
void nestedTransactionsResult_data();
void nestedTransactionsResult();
+ void typedefQt5Compat();
+
private:
void writebool(QDataStream *s);
void writeQBitArray(QDataStream *s);
@@ -209,9 +225,13 @@ private:
void writeQRegion(QDataStream *s);
void writeQSize(QDataStream *s);
void writeQString(QDataStream* dev);
- void writeQRegExp(QDataStream* dev);
+#if QT_CONFIG(regularexpression)
+ void writeQRegularExpression(QDataStream *dev);
+#endif
void writeMap(QDataStream* dev);
+ void writeMultiMap(QDataStream* dev);
void writeHash(QDataStream* dev);
+ void writeMultiHash(QDataStream* dev);
void writeqint64(QDataStream *s);
void writeQIcon(QDataStream *s);
void writeQEasingCurve(QDataStream *s);
@@ -238,9 +258,13 @@ private:
void readQRegion(QDataStream *s);
void readQSize(QDataStream *s);
void readQString(QDataStream *s);
- void readQRegExp(QDataStream *s);
+#if QT_CONFIG(regularexpression)
+ void readQRegularExpression(QDataStream *s);
+#endif
void readMap(QDataStream *s);
+ void readMultiMap(QDataStream *s);
void readHash(QDataStream *s);
+ void readMultiHash(QDataStream *s);
void readqint64(QDataStream *s);
void readQIcon(QDataStream *s);
void readQEasingCurve(QDataStream *s);
@@ -270,7 +294,10 @@ static int NColorRoles[] = {
QPalette::ToolTipText + 1, // Qt_5_4, Qt_5_5
QPalette::ToolTipText + 1, // Qt_5_6, Qt_5_7, Qt_5_8, Qt_5_9, Qt_5_10, Qt_5_11
QPalette::PlaceholderText + 1, // Qt_5_12
- QPalette::PlaceholderText + 1, // Qt_5_13
+ QPalette::PlaceholderText + 1, // Qt_5_13, Qt_5_14, Qt_5_15
+ QPalette::PlaceholderText + 1, // Qt_6_0
+ QPalette::Accent + 1, // Qt_6_6
+ QPalette::Accent + 1, // Qt_6_7
0 // add the correct value for Qt_5_14 here later
};
@@ -485,39 +512,35 @@ void tst_QDataStream::readQString(QDataStream *s)
// ************************************
-static QRegExp QRegExpData(int index)
+#if QT_CONFIG(regularexpression)
+static QRegularExpression QRegularExpressionData(int index)
{
switch (index) {
- case 0: return QRegExp();
- case 1: return QRegExp("");
- case 2: return QRegExp("A", Qt::CaseInsensitive);
- case 3: return QRegExp("ABCDE FGHI", Qt::CaseSensitive, QRegExp::Wildcard);
- case 4: return QRegExp("This is a long string", Qt::CaseInsensitive, QRegExp::FixedString);
- case 5: return QRegExp("And again a string with a \nCRLF", Qt::CaseInsensitive, QRegExp::RegExp);
- case 6:
- {
- QRegExp rx("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/");
- rx.setMinimal(true);
- return rx;
- }
+ case 0: return QRegularExpression();
+ case 1: return QRegularExpression("");
+ case 2: return QRegularExpression("A", QRegularExpression::CaseInsensitiveOption);
+ case 3: return QRegularExpression(QRegularExpression::wildcardToRegularExpression("ABCDE FGHI"));
+ case 4: return QRegularExpression(QRegularExpression::anchoredPattern("This is a long string"), QRegularExpression::CaseInsensitiveOption);
+ case 5: return QRegularExpression("And again a string with a \nCRLF", QRegularExpression::CaseInsensitiveOption);
+ case 6: return QRegularExpression("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/", QRegularExpression::InvertedGreedinessOption);
}
- return QRegExp("foo");
+ return QRegularExpression("foo");
}
-#define MAX_QREGEXP_DATA 7
+#define MAX_QREGULAREXPRESSION_DATA 7
-void tst_QDataStream::stream_QRegExp_data()
+void tst_QDataStream::stream_QRegularExpression_data()
{
- stream_data(MAX_QREGEXP_DATA);
+ stream_data(MAX_QREGULAREXPRESSION_DATA);
}
-void tst_QDataStream::stream_QRegExp()
+void tst_QDataStream::stream_QRegularExpression()
{
- STREAM_IMPL(QRegExp);
+ STREAM_IMPL(QRegularExpression);
}
-void tst_QDataStream::writeQRegExp(QDataStream* s)
+void tst_QDataStream::writeQRegularExpression(QDataStream* s)
{
- QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag())));
+ QRegularExpression test(QRegularExpressionData(dataIndex(QTest::currentDataTag())));
*s << test;
*s << QString("Her er det noe tekst");
*s << test;
@@ -526,14 +549,15 @@ void tst_QDataStream::writeQRegExp(QDataStream* s)
*s << QVariant(test);
}
-void tst_QDataStream::readQRegExp(QDataStream *s)
+void tst_QDataStream::readQRegularExpression(QDataStream *s)
{
- QRegExp R;
+ QRegularExpression R;
QString S;
QVariant V;
- QRegExp test(QRegExpData(dataIndex(QTest::currentDataTag())));
+ QRegularExpression test(QRegularExpressionData(dataIndex(QTest::currentDataTag())));
*s >> R;
+
QCOMPARE(R, test);
*s >> S;
QCOMPARE(S, QString("Her er det noe tekst"));
@@ -544,9 +568,10 @@ void tst_QDataStream::readQRegExp(QDataStream *s)
*s >> R;
QCOMPARE(R, test);
*s >> V;
- QCOMPARE(V.type(), QVariant::RegExp);
- QCOMPARE(V.toRegExp(), test);
+ QCOMPARE(V.userType(), QMetaType::QRegularExpression);
+ QCOMPARE(V.toRegularExpression(), test);
}
+#endif //QT_CONFIG(regularexpression)
// ************************************
@@ -565,16 +590,10 @@ static Map MapData(int index)
map.insert(2, "bbb");
map.insert(3, "cccccc");
break;
- case 2:
- map.insert(1, "a");
- map.insert(2, "one");
- map.insertMulti(2, "two");
- map.insertMulti(2, "three");
- map.insert(3, "cccccc");
}
return map;
}
-#define MAX_MAP_DATA 3
+#define MAX_MAP_DATA 2
void tst_QDataStream::stream_Map_data()
{
@@ -604,6 +623,60 @@ void tst_QDataStream::readMap(QDataStream *s)
QCOMPARE(S, test);
}
+typedef QMultiMap<int, QString> MultiMap;
+
+static MultiMap MultiMapData(int index)
+{
+ MultiMap map;
+
+ switch (index) {
+ case 0:
+ default:
+ break;
+ case 1:
+ map.insert(1, "a");
+ map.insert(2, "bbb");
+ map.insert(3, "cccccc");
+ break;
+ case 2:
+ map.insert(1, "a");
+ map.insert(2, "one");
+ map.insert(2, "two");
+ map.insert(2, "three");
+ map.insert(3, "cccccc");
+ }
+ return map;
+}
+#define MAX_MULTIMAP_DATA 3
+
+void tst_QDataStream::stream_MultiMap_data()
+{
+ stream_data(MAX_MULTIMAP_DATA);
+}
+
+void tst_QDataStream::stream_MultiMap()
+{
+ STREAM_IMPL(MultiMap);
+}
+
+void tst_QDataStream::writeMultiMap(QDataStream* s)
+{
+ MultiMap test(MultiMapData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+ *s << test;
+}
+
+void tst_QDataStream::readMultiMap(QDataStream *s)
+{
+ MultiMap S;
+ MultiMap test(MultiMapData(dataIndex(QTest::currentDataTag())));
+
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QCOMPARE(S, test);
+}
+
// ************************************
typedef QHash<int, QString> Hash;
@@ -621,16 +694,10 @@ static Hash HashData(int index)
map.insert(2, "bbb");
map.insert(3, "cccccc");
break;
- case 2:
- map.insert(1, "a");
- map.insert(2, "one");
- map.insertMulti(2, "two");
- map.insertMulti(2, "three");
- map.insert(3, "cccccc");
}
return map;
}
-#define MAX_HASH_DATA 3
+#define MAX_HASH_DATA 2
void tst_QDataStream::stream_Hash_data()
{
@@ -660,6 +727,60 @@ void tst_QDataStream::readHash(QDataStream *s)
QCOMPARE(S, test);
}
+typedef QMultiHash<int, QString> MultiHash;
+
+static MultiHash MultiHashData(int index)
+{
+ MultiHash map;
+
+ switch (index) {
+ case 0:
+ default:
+ break;
+ case 1:
+ map.insert(1, "a");
+ map.insert(2, "bbb");
+ map.insert(3, "cccccc");
+ break;
+ case 2:
+ map.insert(1, "a");
+ map.insert(2, "one");
+ map.insert(2, "two");
+ map.insert(2, "three");
+ map.insert(3, "cccccc");
+ }
+ return map;
+}
+#define MAX_MULTIHASH_DATA 3
+
+void tst_QDataStream::stream_MultiHash_data()
+{
+ stream_data(MAX_HASH_DATA);
+}
+
+void tst_QDataStream::stream_MultiHash()
+{
+ STREAM_IMPL(MultiHash);
+}
+
+void tst_QDataStream::writeMultiHash(QDataStream* s)
+{
+ MultiHash test(MultiHashData(dataIndex(QTest::currentDataTag())));
+ *s << test;
+ *s << test;
+}
+
+void tst_QDataStream::readMultiHash(QDataStream *s)
+{
+ MultiHash S;
+ MultiHash test(MultiHashData(dataIndex(QTest::currentDataTag())));
+
+ *s >> S;
+ QCOMPARE(S, test);
+ *s >> S;
+ QCOMPARE(S, test);
+}
+
// ************************************
static QEasingCurve QEasingCurveData(int index)
@@ -842,10 +963,10 @@ static void QBitArrayData(QBitArray *b, int index)
case 18: filler = "1111111111111111111111111111111111111111111111111111111111111111"; break;
}
- b->resize(filler.length());
+ b->resize(filler.size());
b->fill(0); // reset all bits to zero
- for (int i = 0; i < filler.length(); ++i) {
+ for (int i = 0; i < filler.size(); ++i) {
if (filler.at(i) == '1')
b->setBit(i, true);
}
@@ -1045,7 +1166,7 @@ static QCursor qCursorData(int index)
case 3: return QCursor(Qt::BlankCursor);
case 4: return QCursor(Qt::BlankCursor);
case 5: return QCursor(QPixmap(open_xpm), 1, 1);
- case 6: { QPixmap pm(open_xpm); return QCursor(QBitmap(pm), pm.mask(), 3, 4); }
+ case 6: { QPixmap pm(open_xpm); return QCursor(QBitmap::fromPixmap(pm), pm.mask(), 3, 4); }
case 7: return QCursor(QPixmap(open_xpm), -1, 5);
case 8: return QCursor(QPixmap(open_xpm), 5, -1);
}
@@ -1085,18 +1206,18 @@ void tst_QDataStream::readQCursor(QDataStream *s)
QVERIFY(d5.shape() == test.shape()); //## lacks operator==
QCOMPARE(d5.hotSpot(), test.hotSpot());
- QVERIFY((d5.bitmap() != 0 && test.bitmap() != 0) || (d5.bitmap() == 0 && test.bitmap() == 0));
- if (d5.bitmap() != 0) {
- QPixmap actual = *(d5.bitmap());
- QPixmap expected = *(test.bitmap());
- QCOMPARE(actual, expected);
- }
- QVERIFY((d5.mask() != 0 && test.mask() != 0) || (d5.mask() == 0 && test.mask() == 0));
- if (d5.mask() != 0) {
- QPixmap actual = *(d5.mask());
- QPixmap expected = *(test.mask());
- QCOMPARE(actual, expected);
- }
+
+ // Comparing non-null QBitmaps will fail. Upcast them first to pass.
+ QCOMPARE(d5.bitmap().isNull(), test.bitmap().isNull());
+ QCOMPARE(
+ static_cast<QPixmap>(d5.bitmap()),
+ static_cast<QPixmap>(test.bitmap())
+ );
+ QCOMPARE(d5.mask().isNull(), test.mask().isNull());
+ QCOMPARE(
+ static_cast<QPixmap>(d5.mask()),
+ static_cast<QPixmap>(test.mask())
+ );
}
#endif
@@ -2024,7 +2145,7 @@ void tst_QDataStream::stream_atEnd()
class FakeBuffer : public QBuffer
{
protected:
- qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); }
+ qint64 writeData(const char *c, qint64 i) override { return m_lock ? 0 : QBuffer::writeData(c, i); }
public:
FakeBuffer(bool locked = false) : m_lock(locked) {}
void setLocked(bool locked) { m_lock = locked; }
@@ -2070,6 +2191,19 @@ void tst_QDataStream::stream_writeError()
TEST_WRITE_ERROR(.writeRawData("test", 4))
}
+void tst_QDataStream::stream_writeSizeLimitExceeded()
+{
+ QByteArray ba;
+ QDataStream ds(&ba, QDataStream::ReadWrite);
+ // Set the version that supports only 32-bit data size
+ ds.setVersion(QDataStream::Qt_6_6);
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ const qint64 size = qint64(std::numeric_limits<quint32>::max()) + 1;
+ ds.writeBytes("", size);
+ QCOMPARE(ds.status(), QDataStream::SizeLimitExceeded);
+ QVERIFY(ba.isEmpty());
+}
+
void tst_QDataStream::stream_QByteArray2()
{
QByteArray ba;
@@ -2096,6 +2230,138 @@ void tst_QDataStream::stream_QByteArray2()
}
}
+void tst_QDataStream::stream_QJsonDocument()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << QByteArrayLiteral("invalidJson");
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonDocument doc;
+ load >> doc;
+ QVERIFY(doc.isEmpty());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonDocument docSave(QJsonArray{1,2,3});
+ save << docSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonDocument docLoad;
+ load >> docLoad;
+ QCOMPARE(docLoad, docSave);
+ }
+}
+
+void tst_QDataStream::stream_QJsonArray()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << QByteArrayLiteral("invalidJson");
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonArray array;
+ load >> array;
+ QVERIFY(array.isEmpty());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonArray arraySave(QJsonArray{1,2,3});
+ save << arraySave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonArray arrayLoad;
+ load >> arrayLoad;
+ QCOMPARE(arrayLoad, arraySave);
+ }
+}
+
+void tst_QDataStream::stream_QJsonObject()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << QByteArrayLiteral("invalidJson");
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonObject object;
+ load >> object;
+ QVERIFY(object.isEmpty());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonObject objSave{{"foo", 1}, {"bar", 2}};
+ save << objSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonObject objLoad;
+ load >> objLoad;
+ QCOMPARE(objLoad, objSave);
+ }
+}
+
+void tst_QDataStream::stream_QJsonValue()
+{
+ QByteArray buffer;
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ save << quint8(42);
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonValue value;
+ load >> value;
+ QVERIFY(value.isUndefined());
+ QVERIFY(load.status() != QDataStream::Ok);
+ QCOMPARE(load.status(), QDataStream::ReadCorruptData);
+ }
+ {
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QJsonValue valueSave{42};
+ save << valueSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QJsonValue valueLoad;
+ load >> valueLoad;
+ QCOMPARE(valueLoad, valueSave);
+ }
+}
+
+void tst_QDataStream::stream_QCborArray()
+{
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QCborArray arraySave({1, 2, 3});
+ save << arraySave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QCborArray arrayLoad;
+ load >> arrayLoad;
+ QCOMPARE(arrayLoad, arraySave);
+}
+
+void tst_QDataStream::stream_QCborMap()
+{
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QCborMap objSave{{"foo", 1}, {"bar", 2}};
+ save << objSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QCborMap objLoad;
+ load >> objLoad;
+ QCOMPARE(objLoad, objSave);
+}
+
+void tst_QDataStream::stream_QCborValue()
+{
+ QByteArray buffer;
+ QDataStream save(&buffer, QIODevice::WriteOnly);
+ QCborValue valueSave{42};
+ save << valueSave;
+ QDataStream load(&buffer, QIODevice::ReadOnly);
+ QCborValue valueLoad;
+ load >> valueLoad;
+ QCOMPARE(valueLoad, valueSave);
+}
+
void tst_QDataStream::setVersion_data()
{
QTest::addColumn<int>("vers");
@@ -2110,6 +2376,7 @@ void tst_QDataStream::setVersion()
QDataStream latest;
QFETCH(int, vers);
+#if QT_CONFIG(shortcut)
/*
Test QKeySequence.
*/
@@ -2134,14 +2401,15 @@ void tst_QDataStream::setVersion()
}
QCOMPARE(deadbeef, 0xDEADBEEF);
}
+#endif // QT_CONFIG(shortcut)
/*
Test QPalette.
*/
// revise the test if new color roles or color groups are added
- QVERIFY(QPalette::NColorRoles == QPalette::PlaceholderText + 1);
- QCOMPARE(int(QPalette::NColorGroups), 3);
+ QCOMPARE(QPalette::NColorRoles, QPalette::Accent + 1);
+ QCOMPARE(static_cast<int>(QPalette::NColorGroups), 3);
QByteArray ba2;
QPalette pal1, pal2;
@@ -2174,10 +2442,10 @@ void tst_QDataStream::setVersion()
if (vers == 1) {
for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
- QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Foreground)
- == inPal1.color((QPalette::ColorGroup)grp, QPalette::Foreground));
- QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Background)
- == inPal1.color((QPalette::ColorGroup)grp, QPalette::Background));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::WindowText)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::WindowText));
+ QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Window)
+ == inPal1.color((QPalette::ColorGroup)grp, QPalette::Window));
QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Light)
== inPal1.color((QPalette::ColorGroup)grp, QPalette::Light));
QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Dark)
@@ -2261,7 +2529,7 @@ void tst_QDataStream::skipRawData()
QFETCH(char, expect);
qint8 dummy;
- QIODevice *dev = 0;
+ QIODevice *dev = nullptr;
if (deviceType == "sequential") {
dev = new SequentialBuffer(&data);
} else if (deviceType == "random-access") {
@@ -2542,7 +2810,6 @@ void tst_QDataStream::status_charptr_QByteArray_data()
QTest::newRow("badsize 1MB+1") << QByteArray("\x00\x10\x00\x01", 4) + oneMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
QTest::newRow("badsize 3MB") << QByteArray("\x00\x30\x00\x00", 4) + threeMbMinus1 << (int) QDataStream::ReadPastEnd << QByteArray();
QTest::newRow("badsize 3MB+1") << QByteArray("\x00\x30\x00\x01", 4) + threeMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
- QTest::newRow("size -1") << QByteArray("\xff\xff\xff\xff", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
QTest::newRow("size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
}
@@ -2565,17 +2832,35 @@ void tst_QDataStream::status_charptr_QByteArray()
{
QDataStream stream(&data, QIODevice::ReadOnly);
char *buf;
- uint len;
+ qint64 len;
stream.readBytes(buf, len);
- QCOMPARE((int)len, expectedString.size());
+ QCOMPARE(len, qint64(expectedString.size()));
QCOMPARE(QByteArray(buf, len), expectedString);
QCOMPARE(int(stream.status()), expectedStatus);
delete [] buf;
}
+#if QT_DEPRECATED_SINCE(6, 11)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
{
+ // check that old overload still works as expected
QDataStream stream(&data, QIODevice::ReadOnly);
- QByteArray buf;
+ char *buf;
+ auto cleanup = qScopeGuard([&buf] {
+ delete [] buf;
+ });
+ uint len;
+ stream.readBytes(buf, len);
+
+ QCOMPARE(len, expectedString.size());
+ QCOMPARE(QByteArray(buf, len), expectedString);
+ QCOMPARE(int(stream.status()), expectedStatus);
+ }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 11)
+ {
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ QByteArray buf = "Content to be overwritten";
stream >> buf;
if (data.startsWith("\xff\xff\xff\xff")) {
@@ -2609,7 +2894,7 @@ void tst_QDataStream::status_QString_data()
QString oneMbMinus1;
oneMbMinus1.resize(1024 * 1024 - 1);
for (int i = 0; i < oneMbMinus1.size(); ++i)
- oneMbMinus1[i] = 0x1 | (8 * ((uchar)i / 9));
+ oneMbMinus1[i] = QChar(0x1 | (8 * ((uchar)i / 9)));
QString threeMbMinus1 = oneMbMinus1 + QChar('j') + oneMbMinus1 + QChar('k') + oneMbMinus1;
QByteArray threeMbMinus1Data = qstring2qbytearray(threeMbMinus1);
@@ -2644,12 +2929,20 @@ void tst_QDataStream::status_QString_data()
QTest::newRow("badsize 1MB+1") << QByteArray("\x00\x20\x00\x02", 4) + oneMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
QTest::newRow("badsize 3MB") << QByteArray("\x00\x60\x00\x00", 4) + threeMbMinus1Data << (int) QDataStream::ReadPastEnd << QString();
QTest::newRow("badsize 3MB+1") << QByteArray("\x00\x60\x00\x02", 4) + threeMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
- QTest::newRow("size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
- QTest::newRow("size MAX") << QByteArray("\x7f\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
+ QTest::newRow("32 bit size should be 64 bit") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
- // corrupt data
+#if QT_POINTER_SIZE != 4
+ // past end on 64 bit platforms
+ QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::ReadPastEnd << QString();
+#else
+ // too big for 32 bit platforms
+ QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::SizeLimitExceeded << QString();
+#endif
+ // too big on both 32 and 64 bit platforms because qsizetype is signed
+ QTest::newRow("64 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xfe", 12) << (int) QDataStream::SizeLimitExceeded << QString();
+
+ // corrupt data because QChar is 16 bit => even size required
QTest::newRow("corrupt1") << QByteArray("yyyy") << (int) QDataStream::ReadCorruptData << QString();
- QTest::newRow("size -3") << QByteArray("\xff\xff\xff\xfd", 4) << (int) QDataStream::ReadCorruptData << QString();
}
void tst_QDataStream::status_QString()
@@ -2659,7 +2952,7 @@ void tst_QDataStream::status_QString()
QFETCH(QString, expectedString);
QDataStream stream(&data, QIODevice::ReadOnly);
- QString str;
+ QString str = "Content to be overwritten";
stream >> str;
QCOMPARE(str.size(), expectedString.size());
@@ -2677,72 +2970,90 @@ static QBitArray bitarray(const QString &str)
void tst_QDataStream::status_QBitArray_data()
{
+ QTest::addColumn<QDataStream::Version>("version");
QTest::addColumn<QByteArray>("data");
QTest::addColumn<int>("expectedStatus");
QTest::addColumn<QBitArray>("expectedString");
// ok
- QTest::newRow("size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QBitArray();
- QTest::newRow("size 1a") << QByteArray("\x00\x00\x00\x01\x00", 5) << (int) QDataStream::Ok << bitarray("0");
- QTest::newRow("size 1b") << QByteArray("\x00\x00\x00\x01\x01", 5) << (int) QDataStream::Ok << bitarray("1");
- QTest::newRow("size 2") << QByteArray("\x00\x00\x00\x02\x03", 5) << (int) QDataStream::Ok << bitarray("11");
- QTest::newRow("size 3") << QByteArray("\x00\x00\x00\x03\x07", 5) << (int) QDataStream::Ok << bitarray("111");
- QTest::newRow("size 4") << QByteArray("\x00\x00\x00\x04\x0f", 5) << (int) QDataStream::Ok << bitarray("1111");
- QTest::newRow("size 5") << QByteArray("\x00\x00\x00\x05\x1f", 5) << (int) QDataStream::Ok << bitarray("11111");
- QTest::newRow("size 6") << QByteArray("\x00\x00\x00\x06\x3f", 5) << (int) QDataStream::Ok << bitarray("111111");
- QTest::newRow("size 7a") << QByteArray("\x00\x00\x00\x07\x7f", 5) << (int) QDataStream::Ok << bitarray("1111111");
- QTest::newRow("size 7b") << QByteArray("\x00\x00\x00\x07\x7e", 5) << (int) QDataStream::Ok << bitarray("0111111");
- QTest::newRow("size 7c") << QByteArray("\x00\x00\x00\x07\x00", 5) << (int) QDataStream::Ok << bitarray("0000000");
- QTest::newRow("size 7d") << QByteArray("\x00\x00\x00\x07\x39", 5) << (int) QDataStream::Ok << bitarray("1001110");
- QTest::newRow("size 8") << QByteArray("\x00\x00\x00\x08\xff", 5) << (int) QDataStream::Ok << bitarray("11111111");
- QTest::newRow("size 9") << QByteArray("\x00\x00\x00\x09\xff\x01", 6) << (int) QDataStream::Ok << bitarray("111111111");
- QTest::newRow("size 15") << QByteArray("\x00\x00\x00\x0f\xff\x7f", 6) << (int) QDataStream::Ok << bitarray("111111111111111");
- QTest::newRow("size 16") << QByteArray("\x00\x00\x00\x10\xff\xff", 6) << (int) QDataStream::Ok << bitarray("1111111111111111");
- QTest::newRow("size 17") << QByteArray("\x00\x00\x00\x11\xff\xff\x01", 7) << (int) QDataStream::Ok << bitarray("11111111111111111");
- QTest::newRow("size 32") << QByteArray("\x00\x00\x00\x20\xff\xff\xff\xff", 8) << (int) QDataStream::Ok << bitarray("11111111111111111111111111111111");
+ QTest::newRow("size 0") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QBitArray();
+ QTest::newRow("size 1a") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x00", 5) << (int) QDataStream::Ok << bitarray("0");
+ QTest::newRow("size 1b") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x01", 5) << (int) QDataStream::Ok << bitarray("1");
+ QTest::newRow("size 2") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x02\x03", 5) << (int) QDataStream::Ok << bitarray("11");
+ QTest::newRow("size 3") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x03\x07", 5) << (int) QDataStream::Ok << bitarray("111");
+ QTest::newRow("size 4") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x04\x0f", 5) << (int) QDataStream::Ok << bitarray("1111");
+ QTest::newRow("size 5") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x05\x1f", 5) << (int) QDataStream::Ok << bitarray("11111");
+ QTest::newRow("size 6") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x06\x3f", 5) << (int) QDataStream::Ok << bitarray("111111");
+ QTest::newRow("size 7a") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x07\x7f", 5) << (int) QDataStream::Ok << bitarray("1111111");
+ QTest::newRow("size 7b") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x07\x7e", 5) << (int) QDataStream::Ok << bitarray("0111111");
+ QTest::newRow("size 7c") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x07\x00", 5) << (int) QDataStream::Ok << bitarray("0000000");
+ QTest::newRow("size 7d") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x07\x39", 5) << (int) QDataStream::Ok << bitarray("1001110");
+ QTest::newRow("size 8") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x08\xff", 5) << (int) QDataStream::Ok << bitarray("11111111");
+ QTest::newRow("size 9") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x09\xff\x01", 6) << (int) QDataStream::Ok << bitarray("111111111");
+ QTest::newRow("size 15") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x0f\xff\x7f", 6) << (int) QDataStream::Ok << bitarray("111111111111111");
+ QTest::newRow("size 16") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x10\xff\xff", 6) << (int) QDataStream::Ok << bitarray("1111111111111111");
+ QTest::newRow("size 17") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x11\xff\xff\x01", 7) << (int) QDataStream::Ok << bitarray("11111111111111111");
+ QTest::newRow("size 32") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x20\xff\xff\xff\xff", 8) << (int) QDataStream::Ok << bitarray("11111111111111111111111111111111");
+
+
+ QTest::newRow("new size 0") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << QBitArray();
+ QTest::newRow("new size 1a") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x01\x00", 9) << (int) QDataStream::Ok << bitarray("0");
+ QTest::newRow("new size 1b") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x01\x01", 9) << (int) QDataStream::Ok << bitarray("1");
+ QTest::newRow("new size 32") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x20\xff\xff\xff\xff", 12) << (int) QDataStream::Ok << bitarray("11111111111111111111111111111111");
// past end
- QTest::newRow("empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 0a") << QByteArray("\x00", 1) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 0b") << QByteArray("\x00\x00", 2) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 0c") << QByteArray("\x00\x00\x00", 3) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 1") << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 2") << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 3") << QByteArray("\x00\x00\x00\x03", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("badsize 7") << QByteArray("\x00\x00\x00\x04", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("size 8") << QByteArray("\x00\x00\x00\x08", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("size 9") << QByteArray("\x00\x00\x00\x09\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("size 15") << QByteArray("\x00\x00\x00\x0f\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("size 16") << QByteArray("\x00\x00\x00\x10\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("size 17") << QByteArray("\x00\x00\x00\x11\xff\xff", 6) << (int) QDataStream::ReadPastEnd << QBitArray();
- QTest::newRow("size 32") << QByteArray("\x00\x00\x00\x20\xff\xff\xff", 7) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("empty") << QDataStream::Qt_5_15 << QByteArray() << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 0a") << QDataStream::Qt_5_15 << QByteArray("\x00", 1) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 0b") << QDataStream::Qt_5_15 << QByteArray("\x00\x00", 2) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 0c") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00", 3) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 1") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 2") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 3") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x03", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 7") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x07", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 8") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x08", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 9") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x09\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 15") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x0f\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 16") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x10\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 17") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x11\xff\xff", 6) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize 32") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x20\xff\xff\xff", 7) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("badsize INT_MAX") << QDataStream::Qt_5_15 << QByteArray("\x7f\xff\xff\xff\xff\xff\xff", 7) << int(QDataStream::ReadPastEnd) << QBitArray(); // size accepted
+ QTest::addRow("badsize INT_MAX + 1") << QDataStream::Qt_5_15 << QByteArray("\x80\x00\x00\x01" "\xff\xff\xff", 7) << int(QDataStream::ReadCorruptData) << QBitArray(); // size rejected
+ QTest::newRow("new badsize 0") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("new badsize 9") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x09\xff", 9) << (int) QDataStream::ReadPastEnd << QBitArray();
+ QTest::newRow("new badsize 0x10000") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00", 9) << (int) QDataStream::ReadPastEnd << QBitArray();
// corrupt data
- QTest::newRow("junk 1a") << QByteArray("\x00\x00\x00\x01\x02", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 1b") << QByteArray("\x00\x00\x00\x01\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 1c") << QByteArray("\x00\x00\x00\x01\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 1d") << QByteArray("\x00\x00\x00\x01\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 1e") << QByteArray("\x00\x00\x00\x01\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 1f") << QByteArray("\x00\x00\x00\x01\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 1g") << QByteArray("\x00\x00\x00\x01\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 2") << QByteArray("\x00\x00\x00\x02\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 3") << QByteArray("\x00\x00\x00\x03\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 4") << QByteArray("\x00\x00\x00\x04\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 5") << QByteArray("\x00\x00\x00\x05\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 6") << QByteArray("\x00\x00\x00\x06\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
- QTest::newRow("junk 7") << QByteArray("\x00\x00\x00\x07\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1a") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x02", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1b") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1c") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1d") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1e") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1f") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 1g") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x01\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 2") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x02\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 3") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x03\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 4") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x04\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 5") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x05\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 6") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x06\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
+ QTest::newRow("junk 7") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x07\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
}
void tst_QDataStream::status_QBitArray()
{
+ QFETCH(QDataStream::Version, version);
QFETCH(QByteArray, data);
QFETCH(int, expectedStatus);
QFETCH(QBitArray, expectedString);
QDataStream stream(&data, QIODevice::ReadOnly);
- QBitArray str;
+ stream.setVersion(version);
+ QBitArray str(255, true);
stream >> str;
+ if (sizeof(qsizetype) == sizeof(int))
+ QEXPECT_FAIL("new badsize 0x10000", "size > INT_MAX fails on 32bit system (QTBUG-87660)",
+ Continue);
+
QCOMPARE(int(stream.status()), expectedStatus);
QCOMPARE(str.size(), expectedString.size());
QCOMPARE(str, expectedString);
@@ -2803,7 +3114,9 @@ void tst_QDataStream::status_QHash_QMap()
hash2.insert("L", "MN");
// ok
+ hash = hash2;
MAP_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, StringHash());
+ hash = hash2;
MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 12), QDataStream::Ok, QDataStream::Ok, hash1);
MAP_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J\x00\x00\x00\x02\x00K"
"\x00\x00\x00\x02\x00L\x00\x00\x00\x04\x00M\x00N", 30), QDataStream::Ok, QDataStream::Ok, hash2);
@@ -2847,24 +3160,6 @@ void tst_QDataStream::status_QHash_QMap()
} \
} \
{ \
- LinkedList expectedLinkedList; \
- for (int i = 0; i < expectedList.count(); ++i) \
- expectedLinkedList << expectedList.at(i); \
- QByteArray ba = byteArray; \
- QDataStream stream(&ba, QIODevice::ReadOnly); \
- if (inTransaction) \
- stream.startTransaction(); \
- stream.setStatus(initialStatus); \
- stream >> linkedList; \
- QCOMPARE((int)stream.status(), (int)expectedStatus); \
- if (!inTransaction || stream.commitTransaction()) { \
- QCOMPARE(linkedList.size(), expectedLinkedList.size()); \
- QCOMPARE(linkedList, expectedLinkedList); \
- } else { \
- QVERIFY(linkedList.isEmpty()); \
- } \
- } \
- { \
Vector expectedVector; \
for (int i = 0; i < expectedList.count(); ++i) \
expectedVector << expectedList.at(i); \
@@ -2886,12 +3181,10 @@ void tst_QDataStream::status_QHash_QMap()
break; \
}
-void tst_QDataStream::status_QLinkedList_QList_QVector()
+void tst_QDataStream::status_QList_QVector()
{
- typedef QLinkedList<QString> LinkedList;
typedef QList<QString> List;
- typedef QVector<QString> Vector;
- LinkedList linkedList;
+ typedef QList<QString> Vector;
List list;
Vector vector;
@@ -2904,7 +3197,9 @@ void tst_QDataStream::status_QLinkedList_QList_QVector()
someList.append("J");
someList.append("MN");
+ list = someList;
LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, List());
+ list = someList;
LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::Ok, QDataStream::Ok, listWithEmptyString);
LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J"
"\x00\x00\x00\x04\x00M\x00N", 18), QDataStream::Ok, QDataStream::Ok, someList);
@@ -2972,6 +3267,13 @@ void tst_QDataStream::streamRealDataTypes()
path.arcTo(4, 5, 6, 7, 8, 9);
path.quadTo(1, 2, 3, 4);
+ QPainterPath otherPath;
+ otherPath.arcTo(10, 4, 5, 6, 7, 8);
+ otherPath.lineTo(9, 0);
+ otherPath.cubicTo(0, 0, 10, 10, 20, 20);
+ otherPath.quadTo(2, 4, 5, 6);
+ QCOMPARE(otherPath.elementCount(), 12);
+
QColor color(64, 64, 64);
color.setAlphaF(0.5);
QRadialGradient radialGradient(5, 6, 7, 8, 9);
@@ -2992,7 +3294,7 @@ void tst_QDataStream::streamRealDataTypes()
stream.setVersion(QDataStream::Qt_4_2);
stream << qreal(0) << qreal(1.0) << qreal(1.1) << qreal(3.14) << qreal(-3.14) << qreal(-1);
stream << QPointF(3, 5) << QRectF(-1, -2, 3, 4) << (QPolygonF() << QPointF(0, 0) << QPointF(1, 2));
- stream << QMatrix().rotate(90).scale(2, 2);
+ stream << QTransform().rotate(90).scale(2, 2).asAffineMatrix();
stream << path;
stream << picture;
stream << QTextLength(QTextLength::VariableLength, 1.5);
@@ -3003,17 +3305,17 @@ void tst_QDataStream::streamRealDataTypes()
file.close();
}
- QPointF point;
- QRectF rect;
- QPolygonF polygon;
- QMatrix matrix;
- QPainterPath p;
+ QPointF point(1, 2);
+ QRectF rect(1, 2, 5, 6);
+ QPolygonF polygon {{3, 4}, {5, 6}};
+ QTransform transform;
+ QPainterPath p = otherPath;
QPicture pict;
- QTextLength textLength;
- QColor col;
- QBrush rGrad;
- QBrush cGrad;
- QPen pen;
+ QTextLength textLength(QTextLength::FixedLength, 2.5);
+ QColor col(128, 128, 127);
+ QBrush rGrad(Qt::CrossPattern);
+ QBrush cGrad(Qt::CrossPattern);
+ QPen pen(conicalBrush, 10);
QVERIFY(file.open(QIODevice::ReadOnly));
QDataStream stream(&file);
@@ -3055,9 +3357,10 @@ void tst_QDataStream::streamRealDataTypes()
stream >> rect;
QCOMPARE(rect, QRectF(-1, -2, 3, 4));
stream >> polygon;
- QCOMPARE((QVector<QPointF> &)polygon, (QPolygonF() << QPointF(0, 0) << QPointF(1, 2)));
+ QCOMPARE((QList<QPointF> &)polygon, (QPolygonF() << QPointF(0, 0) << QPointF(1, 2)));
+ auto matrix = transform.asAffineMatrix();
stream >> matrix;
- QCOMPARE(matrix, QMatrix().rotate(90).scale(2, 2));
+ QCOMPARE(transform, QTransform().rotate(90).scale(2, 2));
stream >> p;
QCOMPARE(p, path);
if (i == 1) {
@@ -3079,7 +3382,7 @@ void tst_QDataStream::streamRealDataTypes()
QCOMPARE(col, color);
stream >> rGrad;
QCOMPARE(rGrad.style(), radialBrush.style());
- QCOMPARE(rGrad.matrix(), radialBrush.matrix());
+ QCOMPARE(rGrad.transform(), radialBrush.transform());
QCOMPARE(rGrad.gradient()->type(), radialBrush.gradient()->type());
QCOMPARE(rGrad.gradient()->stops(), radialBrush.gradient()->stops());
QCOMPARE(rGrad.gradient()->spread(), radialBrush.gradient()->spread());
@@ -3088,7 +3391,7 @@ void tst_QDataStream::streamRealDataTypes()
QCOMPARE(((QRadialGradient *)rGrad.gradient())->radius(), ((QRadialGradient *)radialBrush.gradient())->radius());
stream >> cGrad;
QCOMPARE(cGrad.style(), conicalBrush.style());
- QCOMPARE(cGrad.matrix(), conicalBrush.matrix());
+ QCOMPARE(cGrad.transform(), conicalBrush.transform());
QCOMPARE(cGrad.gradient()->type(), conicalBrush.gradient()->type());
QCOMPARE(cGrad.gradient()->stops(), conicalBrush.gradient()->stops());
QCOMPARE(cGrad.gradient()->spread(), conicalBrush.gradient()->spread());
@@ -3300,6 +3603,90 @@ void tst_QDataStream::floatingPointNaN()
}
}
+void tst_QDataStream::enumTest()
+{
+ QByteArray ba;
+
+ enum class E1 : qint8
+ {
+ A,
+ B,
+ C
+ };
+ {
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << E1::A;
+ QCOMPARE(ba.size(), int(sizeof(E1)));
+ }
+ {
+ QDataStream stream(ba);
+ E1 e;
+ stream >> e;
+ QCOMPARE(e, E1::A);
+ }
+ ba.clear();
+
+ enum class E2 : qint16
+ {
+ A,
+ B,
+ C
+ };
+ {
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << E2::B;
+ QCOMPARE(ba.size(), int(sizeof(E2)));
+ }
+ {
+ QDataStream stream(ba);
+ E2 e;
+ stream >> e;
+ QCOMPARE(e, E2::B);
+ }
+ ba.clear();
+
+ enum class E4 : qint32
+ {
+ A,
+ B,
+ C
+ };
+ {
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << E4::C;
+ QCOMPARE(ba.size(), int(sizeof(E4)));
+ }
+ {
+ QDataStream stream(ba);
+ E4 e;
+ stream >> e;
+ QCOMPARE(e, E4::C);
+ }
+ ba.clear();
+
+
+ enum E
+ {
+ A,
+ B,
+ C,
+ D
+ };
+ {
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+ stream << E::D;
+ QCOMPARE(ba.size(), 4);
+ }
+ {
+ QDataStream stream(ba);
+ E e;
+ stream >> e;
+ QCOMPARE(e, E::D);
+ }
+ ba.clear();
+
+}
+
void tst_QDataStream::floatingPointPrecision()
{
QByteArray ba;
@@ -3518,6 +3905,49 @@ void tst_QDataStream::nestedTransactionsResult()
QCOMPARE(int(stream.status()), expectedStatus);
}
+using CustomPair = QPair<int, int>;
+QDataStream &operator<<(QDataStream &ds, CustomPair pd)
+{ return ds << pd.first << pd.second; }
+QDataStream &operator>>(QDataStream &ds, CustomPair &pd)
+{ return ds >> pd.first >> pd.second; }
+
+
+void tst_QDataStream::typedefQt5Compat()
+{
+ qRegisterMetaType<CustomPair>("CustomPair");
+ QByteArray qt5Data;
+ {
+ // we can read the qt5 version
+ QFile in(QFINDTESTDATA("typedef.q5"));
+ QVERIFY(in.open(QIODevice::ReadOnly));
+ qt5Data = in.readAll();
+ QVERIFY(in.seek(0));
+ QDataStream stream(&in);
+ stream.setVersion(QDataStream::Qt_5_15);
+ QVariant var;
+ stream >> var;
+ QCOMPARE(stream.status(), QDataStream::Ok);
+ CustomPair p = var.value<CustomPair>();
+ QCOMPARE(p.first, 42);
+ QCOMPARE(p.second, 100);
+ }
+ {
+ // writing in Qt 6 results in the same file
+ QTemporaryDir dir;
+ QVERIFY(dir.isValid());
+ QFile file(dir.filePath(u"typedef.q6"_s));
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QDataStream stream(&file);
+ stream.setVersion(QDataStream::Qt_5_15);
+ CustomPair p {42, 100};
+ stream << QVariant::fromValue(p);
+ file.close();
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QCOMPARE(file.readAll(), qt5Data);
+ }
+}
+
QTEST_MAIN(tst_QDataStream)
+
#include "tst_qdatastream.moc"
diff --git a/tests/auto/corelib/serialization/qdatastream/typedef.q5 b/tests/auto/corelib/serialization/qdatastream/typedef.q5
new file mode 100644
index 0000000000..c6b5e8a4df
--- /dev/null
+++ b/tests/auto/corelib/serialization/qdatastream/typedef.q5
Binary files differ
diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt b/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt
new file mode 100644
index 0000000000..d0622c642c
--- /dev/null
+++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdatastream_core_pixmap Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatastream_core_pixmap LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdatastream_core_pixmap
+ SOURCES
+ tst_qdatastream_core_pixmap.cpp
+ LIBRARIES
+ Qt::Gui
+)
diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro b/tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro
deleted file mode 100644
index 7e003304af..0000000000
--- a/tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdatastream_core_pixmap
-QT += testlib
-SOURCES = tst_qdatastream_core_pixmap.cpp
diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp
index c931016a61..f17da27f1c 100644
--- a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp
+++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp
@@ -1,56 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
-#include <QtGui/QBitmap>
-#include <QtGui/QPalette>
+#include <QTest>
#include <QtGui/QPixmap>
-#include <QtGui/QPicture>
-#include <QtGui/QTextLength>
-#include <QtGui/QPainter>
-#include <QtGui/QPen>
+#include <QtGui/QImage>
-class tst_QDataStream : public QObject
+class tst_QDataStreamPixmap : public QObject
{
Q_OBJECT
private slots:
void stream_with_pixmap();
-
};
-void tst_QDataStream::stream_with_pixmap()
+void tst_QDataStreamPixmap::stream_with_pixmap()
{
// This is a QVariantMap with a 3x3 red QPixmap and two strings inside
- const QByteArray ba = QByteArray::fromBase64("AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5HDQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBhAAAACgAAAAAKAGgAZQBsAGwAbw==");
+ const QByteArray ba = QByteArray::fromBase64(
+ "AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5H"
+ "DQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUr"
+ "DhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBh"
+ "AAAACgAAAAAKAGgAZQBsAGwAbw==");
QImage dummy; // Needed to make sure qtGui is loaded
- QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
+ QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: "
+ "QPixmap cannot be created without a QGuiApplication");
QVariantMap map;
QDataStream d(ba);
@@ -58,11 +32,11 @@ void tst_QDataStream::stream_with_pixmap()
d >> map;
QCOMPARE(map["a"].toString(), QString("hello"));
- QCOMPARE(map["p"].value<QPixmap>(), QPixmap()); // the pixmap is null because this is not a QGuiApplication
+ // The pixmap is null because this is not a QGuiApplication:
+ QCOMPARE(map["p"].value<QPixmap>(), QPixmap());
QCOMPARE(map["z"].toString(), QString("there"));
}
-QTEST_GUILESS_MAIN(tst_QDataStream)
+QTEST_GUILESS_MAIN(tst_QDataStreamPixmap)
#include "tst_qdatastream_core_pixmap.moc"
-
diff --git a/tests/auto/corelib/serialization/qtextstream/BLACKLIST b/tests/auto/corelib/serialization/qtextstream/BLACKLIST
index b54b53cd74..cb76e0454d 100644
--- a/tests/auto/corelib/serialization/qtextstream/BLACKLIST
+++ b/tests/auto/corelib/serialization/qtextstream/BLACKLIST
@@ -1,3 +1,7 @@
-[stillOpenWhenAtEnd]
-windows
-winrt
+# QTBUG-87410
+[readStdin]
+android
+[readAllFromStdin]
+android
+[readLineFromStdin]
+android
diff --git a/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt
new file mode 100644
index 0000000000..ac3dc91555
--- /dev/null
+++ b/tests/auto/corelib/serialization/qtextstream/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextstream LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(test)
+add_subdirectory(stdinProcess)
+add_subdirectory(readAllStdinProcess)
+add_subdirectory(readLineStdinProcess)
diff --git a/tests/auto/corelib/serialization/qtextstream/qtextstream.pro b/tests/auto/corelib/serialization/qtextstream/qtextstream.pro
deleted file mode 100644
index 19853b74ad..0000000000
--- a/tests/auto/corelib/serialization/qtextstream/qtextstream.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = test stdinProcess readAllStdinProcess readLineStdinProcess
diff --git a/tests/auto/corelib/serialization/qtextstream/qtextstream_integrity.qrc b/tests/auto/corelib/serialization/qtextstream/qtextstream_integrity.qrc
new file mode 100644
index 0000000000..620fddcd45
--- /dev/null
+++ b/tests/auto/corelib/serialization/qtextstream/qtextstream_integrity.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>rfc3261.txt</file>
+ <file>task113817.txt</file>
+ <file>tst_qtextstream.cpp</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt
new file mode 100644
index 0000000000..bcfb0aaf4e
--- /dev/null
+++ b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## readAllStdinProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(readAllStdinProcess
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qtextstream/readAllStdinProcess"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp
index 08d2bf8183..01f47d758f 100644
--- a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/main.cpp
@@ -1,33 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QTextStream>
+#include <QtCore/QString>
#include <stdio.h>
int main(int, char**)
diff --git a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro
deleted file mode 100644
index f2b5aa619f..0000000000
--- a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCES += main.cpp
-QT = core
-CONFIG += cmdline
-DESTDIR = ./
-
-# This app is testdata for tst_qtextstream
-target.path = $$[QT_INSTALL_TESTS]/tst_qtextstream/$$TARGET
-INSTALLS += target
diff --git a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt
new file mode 100644
index 0000000000..39af3a3048
--- /dev/null
+++ b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## readLineStdinProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(readLineStdinProcess
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qtextstream/readLineStdinProcess"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp
index 41ea5e56f0..8f81f5a720 100644
--- a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
@@ -41,7 +16,7 @@ int main(int argc, char **argv)
do {
line = qin.readLine();
if (!line.isNull())
- qerr << line << flush;
+ qerr << line << Qt::flush;
} while (!line.isNull());
return 0;
}
diff --git a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro
deleted file mode 100644
index f2b5aa619f..0000000000
--- a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCES += main.cpp
-QT = core
-CONFIG += cmdline
-DESTDIR = ./
-
-# This app is testdata for tst_qtextstream
-target.path = $$[QT_INSTALL_TESTS]/tst_qtextstream/$$TARGET
-INSTALLS += target
diff --git a/tests/auto/corelib/serialization/qtextstream/shift-jis.txt b/tests/auto/corelib/serialization/qtextstream/shift-jis.txt
deleted file mode 100644
index 51f161ab1a..0000000000
--- a/tests/auto/corelib/serialization/qtextstream/shift-jis.txt
+++ /dev/null
@@ -1,764 +0,0 @@
-Shift-JISeLXg𐳂
-ŋ߂̍XV
-2005-03-26: uŏɁvAXML{vt@C2łɊÂA኱NjLB
-2005-03-09: uŏɁvA͂኱CB
-2003-06-24: Shift-JIS̊܂ރt@C/pX
-2003-05-31: uŏɁvAuVtgJISvȂǂ̕\Lɂ‚āB
-2003-05-24: CP932d`̕ϊ
-2002-08-30: Perl 5.8.0 ɂ‚āB
-2002-01-17: ɑ΂鐳K\
-2001-12-15: ShiftJIS::Collate overrideCJK p[^p~Ƃɔ {ꕶёւ̏B
-肪ȃG[
-G[ԈႢh΍
-񃊃e̍
-K\ƃ}b`
-O[o}b`
-At@xbg̑啶Ə
-ɑ΂鐳K\
-O̕ϊ
-CP932d`̕ϊ
-𐔂
-Pʂɕ
-낢ȕ
-̒Ő؂肻낦
-{ꕶёւ
-Shift-JIS̊܂ރt@C/pX
-{̕R[hɂ͂‚̂̂gĂ܂BxʓIȂ̂ȂAǂgĂ悢ł傤iǂ̕R[hŕĂ邩̏񂪎ꂳȂ΁jB
-Ⴆ΁A{Windowsł́AłDOSłShift-JISgĂ܂BꍇA̓rł킴킴EUC-JPUTF-8ɕϊƂʓ|łBfobÔƂAu̒iKł͂̕ϐɂ͉Ă̂vo͂ē_̂͂悭s܂ÂƂEUC-JPƂĎ߂ĂAƂ͎Ԃǂł傤B͂o͂Shift-JISōs‚ȂȂŜShift-JIŜ܂܈炫ƕ֗ł傤B
-F "VtgJIS", "Shift_JIS", "Shift-JIS" Ȃǂ̕\L̈Ⴂɂ‚Ă͂悭킩Ă܂B̂Ƃ땪Ă邱Ƃ́F
-JIS X 0208:1997̕1iVtg\jɂ́AuQlvƂāu̕\͒ʏgVtgJISR[hhƌĂ΂Ăv̋Lq܂B
-IANA CHARACTER SETS ɂ́AShift_JIS Windows-31J Ƃʂɓo^Ă܂B܂AShift_JISɂ‚āAuCCSiWjJIS X0201:1997JIS X0208:1997łASȒ`JIS X 0208:1997̕1ɎĂBvƋLĂ܂B
-W3C XML Japanese Profile ɂ́AShift-JISUnicodeւ̕ϊ\|̋Lڂ܂BXML Japanese Profile (Second Edition)ł́AUnicode ConsortiumŌJĂMicrosoft CP932̕ϊ\ɂcharset̖ "x-sjis-cp932" "Windows-31J" ɕύXĂ܂B
-MicrosoftЂ Global Dev ł́ACodepage 932 "Japanese Shift-JIS" ƒLĂ܂B
-AShift-JISɂ͂̕ȂāAƂƂoOG[╶̌ƂȂ܂BȂƂȂȂ̂ł傤B
-Perl͐䕶i܂ރoCif[^ł琳ł悤ɐ݌vĂ̂ŁAXNvgeLXgShift-JISŏ炢ŖɂȂ邱Ƃ͂܂B
-AperlXNvg߂Ƃ́iʏjoCgPʂŒׂ̂ŁAShift-JIŜ悤ȃ}`oCg܂ޕ͂̂܂܂ł͒ڗł܂B
-Ƃ΁AShift-JIS '' Ƃ́A16i82 A0ƂQoCgŕ\܂B "\x82\xA0" ƏĂperlɂƂĂ͓łBꂪ{́icountryj{́ilanguagejłƂAShift-JISŏĂicharsetjƂ͂ǂɂ܂܂Ă܂B
-̂߁AShift-JISŏƂɂ́Aperľ󂯂Ȃ悤ɏĂȂ΂Ȃ܂B̔źAvO}ĂȂ΂Ȃ܂B̋̕Lq́Â悤ȎԂĂAShift-JISp邱ƂɈӋ`ƍlĂlɂ͎QlɂȂ邩܂B
-ȎԂ|ȂĺA
-Perl 5.8.xȍ~gB
-_Fperl5-porters@perl.org ŃT|[gĂB
-_FƓ̍lA]̓{ꏈƂ͑eȂƂ낪iƂÂċCɂȂȂȂ邩ȂjB
-jperlgB
-_FShift-JIS 𕶎ƂĒڈƂłB
-_F݁AێlȂB
-R[hUTF-8EUC-JPɕϊĂ珈B
-_FPerl 5.8.xȍ~łȂĂ삷ϊp̃W[(.pm)⃉Cu(.pl)낢”\B
-_FShift-JISقLjȂɂĂA}`oCgVOoCgƋʂAƂɈꕶƂď͖̂ʓ|łB
- ƂΏƂق悢ł傤B̃vO͗LȂ̂ŁAT΂‚ł傤A͂ɂ͎܂B
-ȂA̕ɏĂ鎖Ał߂Ȃ@Ȃ̂ŁÁ‚łǂ݉B̕@ɂ‚ĉ^₪ƂĂAɂ‚đ̂ƂŎ₷ƁAłȂĂ̂ƁAƔł傤BƂāAɂuȂʼnB
-Shift-JISgƂɂ肪ȁiHjG[
-Shift-JISɂ́AQoCg [@-~]iASCII 10i64-126j͈̔͂ɓ̂܂BASCIÍAperlɂƂēʂȈӖ‚Ƃ邽߁A΂΃G[̌ƂȂ܂BShift-JISł́AQoCg̑QoCǵA[\x40-\x7E\x80-\xFC])͈̔͂ɂ邽߁A18863AR̂P̕炩̖NƂ܂B
-ɁAShift-JISgƂɋN肪ȃG[Ƃ̌܂BG[bZ[Wperl̈Ⴂio[Wǂ̃vbgtH[p̂̂ł邩jɂ葽̈Ⴂ邩܂B
-G[ɂȂȂĂAA҂悤ȓȂŁA܂ȂƂ܂B̏ꍇAG[oȂAŒTȂ΂ȂȂȂ邽߃oO͂΂΍łB
-ł̓G[ɑ΂΍͒񎦂܂B΍͂Ƃł܂Ƃ߂ď܂B
-ȂAɂ͕R[hEUC-JPɂĂN悤ȖG[͎܂B{IɁAEUC-JPȂNȂAShift-JIŜƂɂ͋N悤ȎɌ܂B
-G[ɂ͂ȂȂǕiPj
-Ⴆ΁A"\" Ƃ "\" ƂeN܂B "" Ƃ "" ɂȂ܂B́A"\" "\"̑̕QoCg \ ł邽߁A_uNI[g̒ł͎̃̕GXP[v邱ƂɂȂ̂ŁA\ 0x955C8EA6 łĂANI[ǧʂ "\" 0x958EA6 ƂȂ邩łB'\' ƂΕ͋N܂񂪁AVONI[głhȂG[܂ijB
-G[ɂ͂ȂȂǕiQj
-Ⴆ΁A"~\\500" Ƃeł́A\ EĂ܂܂B́A'~\\500' q(~\\500) ȂǂƂĂhƂł܂B \\ ƂA \ P‚ɂȂĂ܂ƂK邩łB
-NI[gNI[gZq̒ł́AɃNI[gƓ܂߂悤ɁA\ ɂGXP[vt΃NI[g̏I[ł͂ȂÄꕔƂ݂Ȃ܂B̂߁A\\ \ ̕\GXP[vɂȂ܂B̓NI[g̎n[EI[ɂĂƂłB
-G[ɂ͂ȂȂǕiRj
-Ⴆ΁A"ۏ\net" ƂeN܂B "ۥ
-et" ̂悤ɓrʼnsĂ܂܂B́A"\" ̑QoCg \ ł邽߁A_uNI[g̒ł͎ 'n' ƍ킹\n̂Ȃ킿s\^Ƃĉ߂邩łB
-G[ɂ͂ȂȂǕiSj
-Ⴆ΁A"@ARGV" ƂeN܂B́A"@"iSpXy[Xj̑QoCg @ ł邽߁A_uNI[g̒ł͎ ARGV ƍ킹 "@ARGV" ƂzƂĕϐWJsłB@ARGV̂悤ɕK`悤ȔzȂAWJ܂Aʂ̏ꍇł̓G[ɂȂ邩܂i͎QƁjB
-In string, @dog now must be written as \@dog (Perl 5.6.0܂)
-u̒ł́A@dog͍\@dogƏȂ΂ȂȂv
-Oł݂悤ɁASpXy[X "@"̑QoCg @ ł邽߁A̕ƍ킹Ĕzł邩̂悤ɉ߂悤Ƃ܂B"@dog" ̂悤ȏꍇA@dog Ƃz񂪒`Ă΂pĕϐWJ܂A`ĂȂꍇAG[bZ[Wo܂B
-``now must be written as''u͂Ȃ΂ȂȂvƂ́APerl4܂ł͔z̕ϐWJ͍sȂ߁A"hoge@foo.bar" ̂悤ȏ邱Ƃł̂A Perlł @foo WJĂ܂̂ŁAӂN邽߃G[o悤ɂĂ悤łiPerl̂z̓WJT|[gĂAG[oƂȂAقēWJ邾܂BQƁjB
-"@\dog" Ƃ΂Ƃӌ܂A\d ^ƂēʈӖȂ߂ɂ܂̂łāiPerl 5.6ȍ~ł́Ax Unrecognized escape \d passed through uFłȂGXP[v \d nꂽvN܂jAႦ "ԁ@\flower" ̂Ƃ́A\f y[WƂĉ߂A܂B
-Possible unintended interpolation of @dog in string (Perl 5.6.1ȍ~)
-̒ŁA@dog\ɓWJ
-OƓA"@dog" łAPerl 5.6.1iActivePerl 626jȍ~ł́A`ĂȂzłقēWJ܂Bz @dog WĴŁA"\x81" ƓɂȂ܂B
-̓G[ł͂ȂAxɂȂ܂B
-Can't find string terminator '"' anywhere before EOF
-uI[ '"'t@C̏I EOF ܂łɌ‚Ȃv
-Ⴆ΁A"Ή\" ̂悤ȃeł́A'\' ̑QoCg \ ł邽߁A " GXP[vĂ܂܂B̂perĺA " ̓NI[g̏I[Ƃ݂͂ȂɁA񂪂ɑƍlĂ܂܂Bȍ~AXNvg̒ " ̕S܂܂Ȃ΁Â悤ɃG[񍐂܂B
-qq{ "{" }̂悤ȏꍇɂӂȂ΂Ȃ܂B"{" ̑oCg { Ȃ̂ŁÂ܂܂ł { }̃lXgĂ܂Al̃G[܂B
-Bareword found where operator expected
-ǔꂪZqĂقʒuɌ‚v
-Ⴆ΁Aprint "<img alt=\"Ή\\" height=115 width=150>"; ̂悤ȏꍇA\" ɂp̃GXP[v́A\ ̑QoCg\̂߁A\\ " Ƃgݍ킹ɂȂAGXP[vłĂ܂B̂߁ÃéAperl猩ƁA"<img alt=\"Ή\\" ŏIĂ܂B̂߁AěɁAheight ƂǔviNI[gň͂܂ĂȂj悤ɂ݂āAɂ͗̌ł͂ȂAZqׂł͂ȂHperl͍l܂B
-Unrecognized character \x82
-uFȂ \x82v
-́AASCII₻̑̕ǔvɂƂɏo郁bZ[WłB"Ή\" ̂悤ȃeāÂƂ "Ȃł" ̂悤ȃeƂAOƓRN̂łB
-܂Aq{}b`} ̂悤ȏꍇɂA'}' ̑oCg } Ȃ̂ŁA{ } ̃JbR͂ŏIĂ܂AlȃG[ɂȂ܂B
-}b`Ȃ͂Ȃ̂Ƀ}b`iPj
-"J" =~ /|bg/ ̓}b`܂B́A'|' ̑oCg | Ȃ̂ŁA/|bg/ /\x83|bg/ Ƃ݂ȂA\x83 }b`΂悢łB
-}b`Ȃ͂Ȃ̂Ƀ}b`iQj
-"Z" =~ /Z/ ̓}b`܂B́A'Z' ̑oCg 'Z' łBoCgAt@xbgɂȂ镶ɂ͒ӂKvłB
-}b`͂Ȃ̂Ƀ}b`ȂiPj
-"^]Ƌ" =~ /^]/ ̓}b`܂B́A'^' ̑oCg '^'Ȃ̂ŁA/^]/ /\x89^]/ Ƃ݂ȂA̎n ^ ̑O \x89 ͂ȂłB
-Search pattern not terminated
-uT[`p^[IȂv
-́A/\/ ̂悤ɁAoCg \ ł镶ŃT[`p^[I点悤ƂƂɋN܂B}b`Zq̏I[ / GXP[vĂ܂̂ŁAT[`p^[ɐɑ悤ɉ߂܂B̐ɂx/͂܂H
-ƂŁAʂ̃G[ł傤B
-Substitution replacement not terminated
-uu̒u񂪏IȂv
-uZq s/PATTERN/REPLACEMENT/̌`Ƃ˂΂Ȃ܂B s/\//; ̂悤ɁAoCg \ ł镶PATTERNI点悤ƂƂɂ̃G[N܂B}b`Zq̏I[ / GXP[vĂ܂̂ŁAPATTERNɐɑ悤ɉ߂܂B̂perĺAPATTERN \/ ̕łƍlARԖڂ/̐REPLACEMENTɈႢȂƎv̂łA̐ɂx/͂܂H
-ƂŁAʂ̃G[ł傤B
-unmatched [ ] in regexp
-uK\Ƀ}b`Ȃ [ ] v
-Ⴆ΁A/v[/ ł̓G[N܂B '[' ̑oCg [ Ȃ̂ŁA/v[/ /v\x81[\x83\x8B/ Ƃ݂ȂAperl͕NX̂ł͂ȂƎv܂BNX̏I ] ‚Ȃ̂ŃG[ɂȂ܂B
-G[ɂ͂ȂȂǕiTj
-Ⴆ΁Alc('ACEGI')́A'acegi'Ԃ܂BShift-JIŜQoCg̒ɂ́AQoCgASCIIʼnpɓ̂܂Bڂ̓At@xbg̑啶ƏB
-G[ԈႢh΍
-ȏ̂悤ȃG[hɂ͂܂܂ȕ@l܂BႦ΁A"\\" Ə΂ȂǂƂĂ܂B񂻂ł܂܂B̂߂ɂ͂ǂ̌̕ \ ΂mKv܂B͕R[h\ΈꔭŖ炩łB
-cȂǂƂʓ|ȂƂɂȂȂlAR[h\Ȃ񂩁iȂƂɂȂ悤ȕ炢́jËLĂ܂΂Ƃ悤ȐlɂƂẮAmɂʼnɂȂƎv܂BÂ悤Ȑlɂ́Aȃy[WɂKvq}Ȃł傤B
-ŁÂ悤ȃy[W킴킴ɂ悤ȐĺAR[h\ׂȂЂƂƉ肵܂BʂɂƂĔ邱Ƃ͂܂BAԂɂނ܂ԈvO𕽋CōĂẮAɃN[pCԂ‚Ăd܂B
-񃊃e̍
-悭mĂ˂΂ȂȂƂ́A\ ƂGXP[vṕ̕AϐWJ⃁^̉߂肸ƑO̒iKł܂܂ȉeyڂƂƂłB̂߁Aǂf[^mɕϐ̒Ɏ߂邩lKv܂Bϐ̓Ɏ߂Ă܂΁APerlf[^K؂ɊǗĂ܂B悭mĂ $str = "\" ̕Aϐ$strɑȑOA_uNH[gň͂񂾎_łłɕĂƍlׂłBłɕf[^āADʂ͂܂B
-qAhLg͈S̍@łBAI[VONH[gň͂łȂĂ͂Ȃ܂B_uNH[gň͂񂾂ANH[gtȂł́A\ʕϐWJ⃁^̉߂hƂł܂B
-VONH[gŏI[͂񂾃qAhLgł́AϐWJ⃁^̉߂͉N܂BAI[ȉꍇ "\nEOF\n"jTƂs܂BqAhLggƕɉs‚܂AchompŏƂł傤B
-̗ $str = 'ɃeLXg' Ɠ悤ɓ܂A̓eɂĖ肪N܂BƂɃełƊ҂ł܂B
-TvR[h
-chomp($str = << 'EOF');
-ɃeLXg
-EOF
-
-$src = << 'EOF';
- $path = "C:\\path\\file";
- open FH, $path;
-EOF
-
-̕xɍ肽΁AsplitŕƗeՂɍ܂B
-TvR[h
-($name, $career, $age, $memo) = split "\n", << 'EOF';
-cY
-vO}
-O\
-啟DłB ͂܂ۂ܂ȂB
-EOF
-
-Ȍɏ΁A󔒕A\iQoCgɊ܂܂Ă͍̂\ȂjAуJbR܂܂ȂƂŁAqw() gƂł܂BႦ΁A@str = qw(\ Ή\ );̂悤ɋ󔒂ăJbR̃GXP[vh܂B@str = qw(\ Ή\);̂悤ɋ󔒂ȂƃG[̌łB
-P‚̕鎞łAӂۃJbRň͂ŃXgReLXgAEӂXCXɂ邩Ȃ΂Ȃ܂B́Aił́jqw// split(' ', q//) ̗LƂĎĂ邩łBȂAPerl 5.6ł̓XgƓɂȂĂ悤łB
-TvR[h
-($str) = qw(SO\ );
- $str = (qw/SO\ /)[0];
- $str = qw/SO\ /; # Perl 5.6
-
-K\ƃ}b`
-K\̃^͑̂ŁAK\̒Shift-JIS̕𖄂߂ނ͓̂ł͂܂BႦ΁A/\QΉ\/ ł̓G[ɂȂ܂B́A/ / ͈̔͂̌肪^ɍsA̎_ŃG[̂ŁA\Q ̌ʂyڂƂłȂłB܂A/\QΉ\\E/ ͍Is܂B́AΉ\\E Ƃ܂ނ̂ɂ}b`܂B́A\\ ƂA邽߁A\E FȂł傤iԂjB
-̂߁AϐɓāA}b`ZquZq̒œWJƂ낵łB̂Ƃ{ꕶ͗\quotemeta ֐ŏĂ܂B
-TvR[h
-$pat = quotemeta +(qw/ \ /)[0];
-$str =~ /$pat\d+/; # \1, \2, ..ȂǂɃ}b`
- # $str = '\\1' ł}b`i̖͌qj
-
-̂悤ȏ͊mɏXłˁBNI[g̒ \Q \E ǵA񂪓ĂϐƈꏏɂȂ肪N܂B邱ƂŁA\Q \E ͈̔͂mɂȂ邩łB̍́AOq̃e̍肩QlɂĉB
-TvR[h
-$pat = "(?:\Q$str1\E|\Q$str2\E)*";
-$str =~ /$pat/;
-
-# ͏͎̕̕ƓB
-# $pat = "(?:" . quotemeta($str1) . "|" . quotemeta($str2) . ")*";
-
-eNH[g̒ɒږ߂ނƂ܂sȂƂ܂B́Aperl \E Ƃ^𔭌悤Ƃ̂AShift-JISW邽߂łB
-"\Q\\E"ł́A\EɃ}b`鐳K\ɂȂ܂B\̑oCg \ Ǝ \킳̂ŁAperlɂ\Q \x95 \\ Ȇgݍ킹ł悤Ɏv܂B \Q̍p̌ʂ\\x95\\x5cEɂȂ܂B̂߁A\EɃ}b`܂B
-"\Q\"͂ǂł傤B̏ꍇ́A" " ͈̔͂߂ƂɁA\̑oCg̃NH[gGXP[vĂ܂̂ŁA͈̔͂҂悤ɂ͒܂炸AG[ɂȂ܂B̃G[\Q̌ʂlOɔ̂ŁAh悤܂B
-"\Q\\\E"͂ǂł傤BmShift-JISł͖肠܂BXNvgEUC-JPUTF-8ɕϊƂɂ͖肪܂B\\EƗ]ȂQ镶łȂƃ}b`܂BǂɂA\ǂɓY邩lKv̂ŁA̎|ɍ܂B
-K\͗Ⴆ΁Â悤ɂ܂B񂱂Shift-JIŜ݂ɗLłB
- $digit = '(?:[0-9]|\x82[\x4F-\x58])'; # ipƑSpj
- $upper = '(?:[A-Z]|\x82[\x60-\x79])'; # At@xbg啶ipƑSpj
- $lower = '(?:[a-z]|\x82[\x81-\x9A])'; # At@xbgipƑSpj
- $space = '(?:[\ \n\r\t\f]|\x81\x40)'; # 󔒕ipƑSpj
- $ascii = '[\x00-\x7F]'; # ASCII
-
- # Spi_E_Ex莚܂ށj
- $hiraZ = '(?:\x82[\x9F-\xF1]|\x81[\x4A\x4B\x54\x55])';
-
- # SpЉiE_E_Ex莚܂ށj
- $kataZ = '(?:\x83[\x40-\x7E\x80-\x96]|\x81[\x5B\x4A\x4B\x52\x53])';
-
- # pЉipEǓ_܂ށj
- $kataH = '[\xA1-\xDF]';
-
- $onebyte = '[\x00-\x7F\xA1-\xDF]';
- $twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
- $char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
- # JIS
- $all_JIS = '(?:[\x00-\x7f\xa1-\xdf]|'.
- . '\x81[\x40-\x7e\x80-\xac\xb8-\xbf\xc8-\xce\xda-\xe8\xf0-\xf7\xfc]|'
- . '\x82[\x4f-\x58\x60-\x79\x81-\x9a\x9f-\xf1]|'
- . '\x83[\x40-\x7e\x80-\x96\x9f-\xb6\xbf-\xd6]|'
- . '\x84[\x40-\x60\x70-\x7e\x80-\x91\x9f-\xbe]|'
- . '\x88[\x9f-\xfc]|\x98[\x40-\x72\x9f-\xfc]|\xea[\x40-\x7e\x80-\xa4]|'
- . '[\x89-\x97\x99-\x9f\xe0-\xe9][\x40-\x7e\x80-\xfc])';
-
- # x_`
-
- # NECꕶ
- $NEC_special = '(?:\x87[\x40-\x5d\x5f-\x75\x7e\x80-\x9c])';
-
- # NECIIBMg
- $NEC_IBM_ext = '(?:\xed[\x40-\x7e\x80-\xfc]|\xee[\x40-\x7e\x80-\xec\xef-\xfc])';
-
- # IBMg
- $IBM_ext = '(?:[\xfa-\xfb][\x40-\x7e\x80-\xfc]|\xfc[\x40-\x4b])';
-
-
-Shift-JISŃ}b`sɂ́AQ‚̖肪܂B
-oCgASCIÏ̗ɓ镶̂ŁAASCII܂ރp^[Ƀ}b`”\B
-镶̑oCgƎ̑̕oCgPł邩̂悤Ƀ}b`Ă܂B
-҂EUC-JPłN肤łiUTF-8ȂNȂA͂ꂪȂ̂ł͂ȂjBO҂EUC-JPł͋NȂAShift-JISł͋N肤łBh@́AǓƂłAK\̒ɁAɐ擪܂܂邱ƂłB
-TvR[h
-# 擪}b`
-$str =~ /^$char*?(?:$pat)/;
-
-̃}b`ł͂܂sȂƂ܂B"E" =~ /E$/lΏ\ł傤B܂A"\x8E" x 30 . "E"$str = "E"ł邪A"\x8E" x 31 . "E"$str = "E"ł܂AShift-JIS납؂蕪K؂ȕ@͂Ȃƍl܂B
-ȂƂAQoCg\ȂoCg [\x00-\x3F\x7F] ‚鏊܂ŁAɒ[ȏꍇ͕̍ŏ܂ŃXLȂƂ킩炸Aǂ lookbehind ̐K\ (?<=PATTERN)͍̏As蒷ɂł܂i(?<=(?:\A|[\x00-\x3F\x7F])$char*) Ƃ͂łȂĵŁA擪當Pʂł΂炵Ă珈̂Aǂ͊ȕւȂ̂܂B
-O[o}b`
-O[o}b` /g ̏ꍇ́A\Gg܂傤B\G͑O}b`̖w܂B
-̗ł́AuȂ̂]܂̂łA\GȂ̂ŁA擪JnĕŜ܂ʼnтă}b`ȂƁA߂Đ擪PoCgi񂾈ʒuXLĊĴŁAꂽʒuȂ̂Ƀ}b`ƍlĂ܂܂B\GgȂƁAԈʒuɃ}b`邩ȂɁA]vȍČ̂ŁAԂ܂B
-TvR[h
- $str = 'EE';
- $pat = 'E';
- $str =~ s/\G($char*?)($pat)/${1}E/og;
- # 'EE' ̂܂܁ijB
-
-\GtȂꍇ
-
- $str = 'EE';
- $pat = 'E';
- $str =~ s/($char*?)($pat)/${1}E/og; # 'E' 'E' ɒu
- print $str;
- # 'EE' ɂȂĂ܂ijB
-
-@@@@EE
-Pځ@// i}b`Ȃj
-Qځ@|||||||||| i}b`̂Œuj
-Rځ@|||||||||/ i}b`Ȃj
-Sځ@|||||||||| i}b`̂Œuj
-
-@}F @$charQoCgɃ}b`
-@@@@@/@$charPoCgɃ}b`
-@@@@ ˁ@$pat}b`
-@@@@@|@XL͈̔͊O
-
-Ap^[[Ƀ}b`ꍇɂ́AӂKvłB̗́AuAv̑O 'Z' ̂łBP͕̂i'A' : 0x8341ɑ΂'A' : 0x8B8341ă}b`jhł܂BQ́A̕@ŁuvhƂ̂łAZ ւ̒uAċNĂ܂B
-͑R̂悤ɂKv܂B́AQł́uȂHvɏ悤ɁAu邩ƍl܂B
-TvR[h
-$str = "ACEGAACEAA";
-
-print +($temp = $str) =~ s/(?=A)/Z/g, $temp;
-
-print +($temp = $str) =~ s/\G($char*?)(?=A)/${1}Z/g, $temp;
-
-print +($temp = $str) =~ s/\G(\A|$char+?)(?=A)/${1}Z/g, $temp;
-
-
-5 ZACEGZAZACEZAZA
-7 ZACEGZZAZZACEZZAA
-4 ZACEGZAZACEZAA
-
-ȂH
- A C E G A A C E A A
-1 \G Z
-2 \G$char$char$char$char Z
-3 \G Z
-4 \G$char Z
-5 ȉAȗ
-
-‚܂AO[o}b`ł́A}b`[łȂp^[̑Oɂ\G($char*?)A[łp^[̑Oɂ\G(\A|$char+?)Kv܂B
-AłiHj}b`Ȃꍇ܂B
-TvR[h
-$str = "0123000123";
-
-print +($temp = $str) =~ s/0*/Z/g, $temp;
-
-print +($temp = $str) =~ s/\G($char*?)0*/${1}Z/g, $temp;
-
-print +($temp = $str) =~ s/\G(\A|$char+?)0*/${1}Z/g, $temp;
-__END__
- 9 ZZ1Z2Z3ZZ1Z2Z3Z
-14 ZZ1ZZ2ZZ3ZZ1ZZ2ZZ3ZZ
- 7 Z1Z2Z3Z1Z2Z3Z
-
-́Ap^[[Ƀ}b`̂łƁA/g̏Ŗɑ݂ďIȂȂ̂h߁AperĺA}b`Iɐi߂Ă̂łicf. perlre, Repeated patterns matching zero-length substringjA̐iߕ̐^ioCgPʂł͂ȂAPʂŐiނ́jA\G($char*?)\G(\A|$char+?)ł́A܂łȂłBƂ}b`邱Ƃ́AقƂǂȂƍl܂̂ŁACɂKv͂Ȃ̂m܂iɂ݁jB
-At@xbg̑啶Ə
-Shift-JIŜQoCg̒ɂ́AQoCgASCIIʼnpɓ̂܂B̂߁A֐ uc, lc A^ \U, \LQoCg̈ꕔϊĂ܂i֐ ucfirst, lcfirst ^ \u, \l ͖ƂȂȂjAm//i s///iȂǂ /iCqɂĈႤȂ̂Ƀ}b`Ă܂肷邱Ƃ܂B
-Shift-JISɊ܂܂ASCIỈp啶܂͏ɑȂAႦ΁Â悤ȃTu[`Ύł܂B
-TvR[h
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-lc("PERLvO~O"); # 'perlvo~o'
-tolower("PERLvO~O"); # 'perlvO~O'
-
-sub tolower {
- my $str = $_[0];
- $str =~ s/\G($char*?)([A-Z]+)/$1\L$2/g;
- $str;
-}
-
-sub toupper {
- my $str = $_[0];
- $str =~ s/\G($char*?)([a-z]+)/$1\U$2/g;
- $str;
-}
-
-P[X̃}b` /i ̏ꍇ́AႦ 'G'̑oCg 'G' łA'g'̑oCg 'g' ł邱ƂA'G' =~ /g/i̓}b`܂BłAShift-JISŐmȃ}b`΁A/iCq͎gƂł܂B
-ɁAɊ܂܂At@xbgioCg̑QoCgɂ̂ji܂͑啶Aǂ炩jɓꂵă}b`܂Btolower̒`͏B
-TvR[h
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-$lcstr = tolower($str);
-$lckey = tolower(quotemeta $key);
-
-if ($lcstr =~ /^$char*?$lckey/) {
- print "matched";
-}
-else {
- print "not matched";
-}
-
-܂͖ߍݏCq (?ismx-ismx) pĂDʂ𓾂܂B
-TvR[h
-"PPerluk̂ē" =~ /^$char*?PERLuK/i # }b`ij
-"QPerluk̂ē" =~ /^$char*?((?i)PERL)uK/ # }b`Ȃiǂj
-"RPerluK̂ē" =~ /^$char*?((?i)PERL)uK/ # }b`iǂj
-
-SpQoCgAt@xbg̃P[X́AIɂł܂iAςρjB'`'̑QoCg '`' Ȃ̂Aƒӂłim`` Ȃǂ̂ƂvIG[ɂȂBobNNH[ggӖ͓ɂȂjBIɂ̓e}b`ZquZqɒږߍނ͔̂łB
-TvR[h
-/(?:o|)(?:d|)(?:q|)(?:k|)/;
-
-̑ɂȃTu[`Ă݂Ă悢܂B
-TvR[h
-$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-$pat = make_regexp_ignorecase("odqkuK");
-print "TouK" =~ /^$char*?$pat/ ? "OK": "NOT";
-
-sub make_regexp_ignorecase {
- my $str = $_[0];
- $str =~ s/\G([A-Za-z]+|$CharRE)/
- my $c = ord $1;
- if($c == 0x82) {
- my $v = vec($1,1,8);
- 0x81 <= $v && $v <= 0x9A ? sprintf('\\x82[\\x%2x\\x%2x]', $v, $v-33) :
- 0x60 <= $v && $v <= 0x79 ? sprintf('\\x82[\\x%2x\\x%2x]', $v, $v+33) :
- quotemeta($1);
- }
- elsif(0x41 <= $c && $c <= 0x5A || 0x61 <= $c && $c <= 0x7A) {"(?:(?i)$1)"}
- else {quotemeta($1)}
- /geo;
- $str;
-}
-
-ɑ΂鐳K\
-K\́APerl ɂƂČȂ݂Ƃ܂BK\̐ƂāA*, +, {min,max} Ȃǂ̗ʎwq}b`JԂ񐔂̏Ƃ肪܂B(ڍׂ perlre QƂ̂)B̂߁A$char*? ƂK\ɂ́A댯܂B
-Ⴆ΁Â悤ȃ}b`OlČ܂傤B$stŕAuv10AƂɁAuACABCvAꂽłB̂悤ȕiAuwx10AvƂƂ͕炸ACӂ Shift-JIS eLXgł낤ƂƂɂ܂jApAt@xbgA‚Ƃ܂傤BƁA܂ł̍l炷ƁÂ悤ɂ΂悢Ǝv܂B
-TvR[h
-my $char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-my $str = ('' x 100000) . 'ACABC';
-$str =~ /^$char*?([A-Z]+)/o;
-print $1;
-
-ÁA‹ɂẮA傫ȃG[N܂BႦ΁AWindows 98 Active Perl 522 pꍇAError: Runtime exception Ƃ Perl ̃G[ɂȂ܂B܂AWindows 98VC++ 6.0ŃRpCꂽ Perl 5.6.1 ƁAũvO͕sȏŝŋI܂B`vȂǂƂG[ɂȂ܂B
-̂悤Ȗł邾h߂ɂ́Â悤ɂ܂B‚܂A̐擪璲ׂĂꍇAoCg̕EԈႦ̂́AoCg̑oCg̒𕶎EƌFłBShift-JISł́AoCg̑oCǵA[\x81-\x9F\xE0-\xFC] łB邢́AEUC-JP ɕϊ”\ȗ̈悾l΁A[\x81-\x9F\xE0-\xEF] ƂƂł܂BȊÕoCg̒́AႦ΁A0x41 ̒́A'A' ̒ォA'A' ̒ォ͕܂񂪁AmɕEɂȂ܂B]āA[\x81-\x9F\xE0-\xFC]+ i܂ [\x81-\x9F\xE0-\xEF]+ j̃oCgioCgjAƂ낾ɒӂ΂悢ƂɂȂ܂B
-̂߁Aȉ̂悤ɁA^$char*? ̑ $Apad gA\G$char*? ̑ $Gpad p΁AoCgAoCĝoCg [\x40-\x7E\x80\xA0-\xDF] ŏÎAȂƂKȊԊuŁiɒBȂɁjo΁AG[ɂȂ炸ɏ邱Ƃł܂BimIȖł̂ŁASł͂܂Bj
-TvR[h
-# 񂾂}b`
-my $Apad = '(?:(?:\A|[\x00-\x80\xA0-\xDF])(?:[\x81-\x9F\xE0-\xFC]{2})*?)';
-my $str1 = ('' x 100000) . 'ACABC';
-$str1 =~ /$Apad([A-Z]+)/o;
-print "$1\n"; # "ABC" ƕ\B
-
-# O[o}b`
-my $Gpad = '(?:(?:\G|[\x00-\x80\xA0-\xDF])(?:[\x81-\x9F\xE0-\xFC]{2})*?)';
-
-my $str2 = '' x 100000 . 'ACABC'. '' x 100000 . 'XYZ';
-my @array = $str2 =~ /$Gpad([A-Z]+)/go;
-print "@array\n"; # "ABC XYZ" ƕ\B
-
-O̕ϊ
-x_`⃆[U`܂ޕ𑼂̊‹łpł悤ɂɂ́AK؂ȕϊKvłi_A܂̗̂p͂قƂǖ]߂A炭͗ގ╶ɕϊ邱ƂɂȂł傤jBPerlł͒uZq s/// gΔrIeՂɎł܂B
-炩߁Aǂ̊Oǂϊ邩`ϊe[upӂȂĂ͂Ȃ܂BPerlł̓nbVɂĂƂ̌̏yɂȂ܂Bł́A'w932_gai.txt'Œ`AWindows codepage-932R[hɊÂ@ˑ́iIjϊe[ugƂɂ܂B
-̃R[hł́APƒ}b`A̕ϊnbṼL[ɂΑΉl̕ɒuAłȂ΂̂܂܎c܂B
-TvR[h
-require 'w932_gai.txt'; # %table̒`isSIj
-
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-$str =~ s/($char)/exists $table{$1} ? $table{$1} : $1/geo;
-
-lȏ́A‚̂悤ȏłł܂AOɃ}b`鐳K\ $gaijipӂKv܂Bꂽ}b`Ȃ߂ɁA̐K\ɂ \G KvłBႦ΁A$str = '@';̌QoCg "\x87\x40" łA΃}b`Sz܂B܂A~}b` ($char*?)g $char OɃ}b`Ȃ悤ύXKv͂܂B
-TvR[h
-require 'w932_gai.txt'; # %table̒`isSIj
-
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-$gaiji = '(?:[\x87][\x40-\x9c])';
-
-$str =~ s/\G($char*?)($gaiji)/$1$table{$2}/g;
-
-CP932d`̕ϊ
-Microsoft Windows {łňʓIɎgpĂR[hy[W 932 (CP932) ł́A‚̕dĒ`ꂽԂɂȂĂ܂BŁAd`ĂƂ́AUnicode̓ʒuɑΉtĂ邱ƂƂ܂B
-Ⴆ΁ACP932 -> Unicode -> CP932 ̏ŕϊƁAd`́Aǂꂩ‚ɑ܂B̗D揇ʂ JIS X 0208, NECꕶ (13)AIBMg (115`119)ANECIIBMg (89`92) ̏łBƂāA'' ̏ꍇANECꕶ "\x87\x9A" IBMg "\xFA\x5B" ́AJIS X 0208 "\x81\xE6" ɂȂ܂B
-ACP-932 ̃eLXgAd`ǂꂩɑĂȂƂ܂BႦ "\x87\x9A" "\xFA\x5B" ܂܂ĂƁAeLXgڂŌƈႢȂ̂ɁA"\x81\xE6" ŌÂȂƂɂȂ܂B
-d`𑵂郂W[ƂāAShiftJIS/CP932/Correct.pm ܂BƎgPerl̃y[Wɖ߂Ό‚܂B
-܂AShiftJIS/String.pm strtr() ܂ trclosure() g@܂BƎgPerl̃y[Wɖ߂Ό‚܂B
-TvR[h
-
-# (1) $necJIS -> $jisNEC (9)
- $necJIS = "\x87\x90\x87\x91\x87\x92\x87\x95\x87\x96\x87\x97\x87\x9A\x87\x9B\x87\x9C";
- # NECꕶ̂AJISɕϊׂ񊿎
- $jisNEC = "\x81\xE0\x81\xDF\x81\xE7\x81\xE3\x81\xDB\x81\xDA\x81\xE6\x81\xBF\x81\xBE";
- # JIŜANECꕶɏd`Ă񊿎
-
-# (2) $necibmJIS -> $jisNECIBM (1)
- $necibmJIS = "\xEE\xF9";
- # NECIIBMĝAJISɕϊׂ񊿎
- $jisNECIBM = "\x81\xCA";
- # JIŜANECIIBMgɏd`Ă񊿎
-
-# (3) $ibmJIS -> $jisIBM (2)
- $ibmJIS = "\xFA\x54\xFA\x5B";
- # IBMĝAJISɕϊׂ񊿎
- $jisIBM = "\x81\xCA\x81\xE6";
- # JIŜAIBMgɏd`Ă񊿎
-
-# (4) $ibmNEC -> $necIBM (13)
- $ibmNEC = "\xFA\x4A-\xFA\x53\xFA\x58\xFA\x59\xFA\x5A";
- # IBMĝANECꕶɕϊׂ񊿎
- $necIBM = "\x87\x54-\x87\x5D\x87\x8A\x87\x82\x87\x84";
- # NECꕶ̂AIBMgɏd`Ă񊿎
-
-# (5) $necibmIBM -> $ibmNECIBM (13)
- $necibmIBM = "\xEE\xEF-\xEE\xF8\xEE\xFA\xEE\xFB\xEE\xFC";
- # NECIIBMĝAIBMgɕϊׂ񊿎
- $ibmNECIBM = "\xFA\x40-\xFA\x49\xFA\x55\xFA\x56\xFA\x57";
- # IBMĝANECIIBMgɏd`Ă񊿎
-
-# (6) $necibmCJK -> $ibmCJK (360)
- $necibmCJK = "\xED\x40-\xEE\xEC";
- # NECIIBMg̊
- $ibmCJK = "\xFA\x5C-\xFC\x4B";
- # IBMg̊
-
-use ShiftJIS::String qw(trclosure);
-
-# ϊpN[W̐
-$correctCP932 = trclosure(
- $necJIS.$necibmJIS.$ibmJIS.$ibmNEC.$necibmIBM.$necibmCJK, # from
- $jisNEC.$jisNECIBM.$jisIBM.$necIBM.$ibmNECIBM.$ibmCJK # to
-);
-
-$result = $correctCP932->($source); # $source ϊ $result 𓾂
-
-𐔂
-Shift-JIS̕𐔂ɂ́A}b`Zq𗘗pȂXJ[ReLXgŐ኱łBAuZq𗘗pقƂ킩܂B
-ƂXSŏقƑłB܂AXSUB͖ɗpȂĂ悢ł傤B
-TvR[h
-use Benchmark;
-
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-$s = "\0ACeXg -";
-
-timethese (100000, {
- le => q{
- ($str = $s) =~ s/$char/0/go;
- $le = length $str;
- },
- sg => q{
- $sg = ($str = $s) =~ s/$char//go;
- },
- ab => q{
- $ab = 0;
- $ab++ while $s =~ /[^\x81-\x9F\xE0-\xFC]|../g;
- },
- ar => q{
- $ar = @{[ $s =~ /$char/go ]};
- },
- gr => q{
- $gr = grep defined, $s =~ /$char/go;
- },
- wh => q{
- $wh = 0;
- $wh++ while $s =~ /$char/go;
- },
- sj => q{
- $sj = sjslen($s);
- },
- xs => q{
- $xs = sjlength($s);
- },
-});
-
-sub sjslen {
- my($str,$len,$i,$c,$blen);
- $str = shift;
- $blen = length $str;
- while ($i < $blen) {
- $c = vec($str, $i, 8);
- if (0x81 <= $c && $c <= 0x9F || 0xE0 <= $c && $c <= 0xFC){ $i++ }
- $i++,$len++;
- }
- $len;
-}
-
-
-Benchmark: timing 100000 iterations of ab, ar, gr, le, sg, sj, wh, xs...
- ab: 4 wallclock secs ( 3.46 usr + 0.00 sys = 3.46 CPU) @ 28901.73/s
- ar: 6 wallclock secs ( 5.98 usr + 0.00 sys = 5.98 CPU) @ 16722.41/s
- gr: 6 wallclock secs ( 5.50 usr + 0.00 sys = 5.50 CPU) @ 18181.82/s
- le: 3 wallclock secs ( 2.09 usr + 0.00 sys = 2.09 CPU) @ 47846.89/s
- sg: 2 wallclock secs ( 1.92 usr + 0.00 sys = 1.92 CPU) @ 52083.33/s
- sj: 9 wallclock secs ( 8.57 usr + 0.00 sys = 8.57 CPU) @ 11668.61/s
- wh: 5 wallclock secs ( 4.78 usr + 0.00 sys = 4.78 CPU) @ 20920.50/s
- xs: 1 wallclock secs ( 0.38 usr + 0.00 sys = 0.38 CPU) @ 263157.89/s
- (warning: too few iterations for a reliable count)
-
-XSUB
-int
-sjlength(arg)
- SV* arg
- PROTOTYPE: $
- PREINIT:
- unsigned char *str, *p, *e;
- STRLEN byte, len = 0;
- CODE:
- p = str = (unsigned char *)SvPV(arg, byte);
- e = str + byte;
- while (p < e) {
- if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC)
- ++p;
- ++p, ++len;
- }
- RETVAL = len;
- OUTPUT:
- RETVAL
-
-Pʂɕ
-Shift-JIS𕶎Pʂɕ܂傤B̏ꍇ́AXS𗘗pĂ܂葬Ȃ܂łBԂl̃Xgpӂ̂ɎԂ̂A͂Perl̐K\̏͂Ȃ葬̂ƂƂł傤B
-TvR[h
-use Benchmark;
-
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-$s = "{ݺ\0ABC" x 100;
-
-timethese (1000, {
- re => q{
- @re = $s =~ /$char/go;
- },
- xs => q{
- @xs = sjsplit($s);
- },
-});
-
-
-Benchmark: timing 1000 iterations of re, xs...
- re: 7 wallclock secs ( 6.65 usr + 0.00 sys = 6.65 CPU) @ 150.38/s
- xs: 6 wallclock secs ( 5.33 usr + 0.00 sys = 5.33 CPU) @ 187.62/s
-
-XSUB
-void
-sjsplit(arg)
- SV* arg
- PROTOTYPE: $
- PREINIT:
- unsigned char *str, *p, *e;
- STRLEN ch, byte, len = 0;
- PPCODE:
- str = (unsigned char *)SvPV(arg,byte);
- e = str + byte;
- for (p = str; p < e; p++) {
- if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC) ++p;
- ++len;
- }
- EXTEND(SP,len);
- for (p = str; p < e; p += ch) {
- ch = (0x81 <= *p && *p <= 0x9F || 0xE0 < *p && *p <= 0xFC) ? 2 : 1;
- PUSHs(sv_2mortal(newSVpv(p,ch)));
- }
-
-FXȕ
-ŕł݂悤ɁA𕪊ɂ́Am//g֗łB
-TvR[h
-$onebyte = '[\x00-\x7F\xA1-\xDF]';
-$twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-#PoCg̉ƂQoCg̉ɕB
- while ($str =~ /\G($onebyte*)($twobyte*)/g) {
- push @one, $1 if $1 ne '';
- push @two, $2 if $2 ne '';
- }
-
-#_Ō̕ƂȂ悤ɕB
-# 'B' ł͂AɂĂ͒ӂKvB
- @sentences = $str =~ /\G$char*?(?:B|D|$)/g;
-
-̒Ő؂肻낦
-̒ioCgjŐ؂肻낦ȂÂ悤ɂĂł܂B
-TvR[h
-$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-$str = '킴킴EUC-JPɕϊȂŁAShift-JIŜ܂܏'.
- 'ł炢񂾂ǁAȂȂʓ|˂B';
-
-print join "\n", bytebreak($str,15);
-
-sub bytebreak{
- my($byte,$bmax,$ch,@lines);
- my $str = shift;
- $byte = $bmax = shift;
- foreach $ch ($str =~ /$char/go) {
- $byte += length $ch; # ̕p
- if ($byte <= $bmax) {
- $lines[-1] .= $ch; # ȂΌp
- } else {
- $byte = length $ch;
- push @lines, $ch; # ȂΎ̍s
- }
- }
- return @lines;
- # ȂꍇɁAEXy[XŖ߂΁B
- # return map {$_ .= ' ' x ($bmax - length)} @lines;
-}
-
-֑́AႦΎ̂悤ɂčs܂BPȍlł́Á֑A(i) s֑̒OʼnsȂG(ii) s֑̒ʼnsȂGƂƂɂȂ܂B܂A"(a)"̂悤ɁAs֑ƍs֑̊ԂɂPȂÁȂ̕ŜsɂȂ_ɂz܂B
-̗ł͕̒oCg length ŋK肵Ă܂AƃoCg͕KႵ܂̂ŁAꍇɂẮiMVA͔pɂƂA܂̓v|[VȉꍇƂAUTF-8̏ꍇƂjԂ width ̂悤Ȋ֐`Kvł傤B
-܂Â̗ł́A֑ɂ閳sňs蒷Ȃꍇ́A݂͂h܂BꂪȂA֑̗OƂčs𕪂iႦ$next̒$bmax𒴂Ȃ悤ɂjuKvł傤B
-TvR[h
-$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])';
-
-# s֑iꕔj
-$NotAtBegin = q/)]}fhvxjnp!,.:;?ABXJKICDFGH/;
-# s֑iꕔj
-$NotAtEnd = q/([{eguwimo/;
-
-# nbV
-@NotAtBegin{$NotAtBegin =~ m/$CharRE/g} = ();
-@NotAtEnd{ $NotAtEnd =~ m/$CharRE/g} = ();
-
-$Str = '킴킴EUC-JPɕϊȂŁAShift-JIŜ܂܏'.
- 'ł炢񂾂ǁAȂȂʓ|˂B';
-
-print join "\n", linebreak($Str,16);
-
-sub linebreak{
- my($byte,$i,@chars,$next,@lines);
- my($str, $bmax, $pad) = @_;
-
- # $byte͎̕pƂ̒
- $byte = $bmax; # sł邽߂̏lB
-
- # Pʂɂ΂炷
- @chars = $str =~ /$CharRE/go;
-
- for ($i=0; $i<@chars; $i++) {
- $next .= $chars[$i]; # ̕
- $byte += length $chars[$i]; # ̕p
-
- # ̕ŝ֑Ƃ
- next if $i+1 < @chars && exists $NotAtEnd{ $chars[$i] };
- # ̎̕ŝ֑Ƃ
- next if $i+1 < @chars && exists $NotAtBegin{ $chars[$i+1] };
-
- # s̐U蕪
- # ȂΌp
- if ($byte <= $bmax) {
- $lines[-1] .= $next;
- }
- # ȂΎ̍s
- else {
- push @lines, $next;
- $byte = length $next;# Vs̒
- }
- $next = '';
- }
- return defined $pad && 1 == length $pad # lߕ
- ? map {$_ .= $pad x ($bmax - length)} @lines
- : @lines;
-}
-
-Ԃ牺֑̏ꍇi$bmin $bmax͈̔͂jB
- $bmin = $bmax - 2; # Ⴆ΁B
-
- # s̐U蕪
- # ȂΌp
- if ($byte <= $bmax && @lines && length $lines[-1] < $bmin){
- $lines[-1] .= $next;
- }
- # ȂΎ̍s
- else {
- push @lines, $next;
- $byte = length $next;# Vs̒
- }
-
-{ꕶёւ
-܏\Ƀ\[g郂W[ƂāAShiftJIS/Collate.pm ܂BƎgPerl̃y[Wɖ߂Ό‚܂B
-uǂ݁E\Lƍv͎̂悤ɂčs܂BsortYomi\bh̎󂯎郊Xg̊evf́A[ \L, ǂݗ ]Ƃz񃊃t@XłȂ΂Ȃ܂B
-TvR[h
-use ShiftJIS::Collate;
-
-my @data = (
- [qw/ R /],
- [qw/ c Ȃ /],
- [qw/ c Ȃ /],
- [qw/ /],
- [qw/ /],
- [qw/ /],
- [qw/ R /],
- [qw/ /],
- [qw/ /],
- [qw/ Rc ܂ /],
- [qw/ ic Ȃ /],
-);
-
-@sort = ShiftJIS::Collate->new()->sortYomi(@data);
-
-uȈՑ\ǂݏƍv͎̂悤ɂčs܂BsortDaihyo\bh̎󂯎郊Xg̊evf́A[ \L, ǂݗ ]Ƃz񃊃t@XłȂ΂Ȃ܂B
-TvR[h
-
-#!perl
-use ShiftJIS::Collate;
-
-my @data = (
- [qw/ ɌvZ ނ /],
- [qw/ JISԍ ΂񂲂 /],
- [qw/ B /],
- [qw/ ǂ /],
- [qw/ ͐ /],
- [qw/ ͓ 킿 /],
- [qw/ pc /],
- [qw/ pc ǂ /],
- [qw/ @ 炬 /],
- [qw/ ͓ /],
- [qw/ KR /],
- [qw/ KR /],
- [qw/ Ƃ /],
- [qw/ ac 킾 /],
- [qw/ 킵 /],
- [qw/ c 킾 /],
- [qw/ Vc 킾 /],
- [qw/ pc ‚̂ /],
- [qw/ ƈ ‚ /],
- [qw/ y ‚ /],
- [qw/ y ‚ /],
- [qw/ ˈ Ƃ /],
- [qw/ ˓c Ƃ /],
- [qw/ y ǂ /],
- [qw/ y ǂ /],
- [qw/ y Ƃ /],
- [qw/ c ₷ /],
-);
-
-@sort = ShiftJIS::Collate->new()->sortDaihyo(@data);
-
-
-Shift-JIS̊܂ރt@C/pX
-{ڂ́A̍ڂɑāAs[̂܂܋LqĂ܂̂ŁAQlɂ悤ƎvꍇA\ɒӂ̏A[ł܂ł̍Ɗ‹ŃeXgĂB
-Windows (95/98/NT/2000Ȃ) ŁAt@CpXił͓oCg̈ӖŎgĂ܂̂ŁALȂǂ܂݂܂Bj܂ޏꍇAPerlňۂɖ肪”\܂B
-oCg "\x5C" ̊ƒt@C/pX
-fBNg֐imkdir, rmdir, opendir, -d ȂǁjAt@C֐iopen, unlink, -f ȂǁjŁAANZXłȂƂ܂B
-t@C̏ꍇ́AɔpXy[XYƃANZXłꍇ܂iႦ΁A-f '\ ' ܂ -f "\x95\x5C\x20" ȂǁjB
-fBNg̏ꍇ́A / \ YƃANZXłꍇ܂iႦ΁A-d '\/' ܂ -d "\x95\x5C/" ȂǁjBɓY镶𔼊pXy[XƂĂA܂ANZXłꍇ܂BY镶̌ƂāAOނ̕iXbVA~LA󔒁j܂Aǂ̕悢́A֐ɂĈقȂꍇ悤łBgpOɏ\ɃeXgĂB
-ȂAfBNg̖ / \ YꍇAƂƖ / \ tĂꍇɂ́AdɕtƂ܂sȂꂪ܂̂ŁAȂOɌق悢ł傤B
-ǂĂsŐMłȂꍇ́A`` ܂ qx// system()֐ȂǂʂWindows̃R}hĂԂ̂ǂƎv܂B
- Shift-JIS ŏꂽ POD Perl 5.8.1, 5.8.2 Pod::Html HTML ɕϊꍇAAJ[̖ÓA pƉ [0xA6..0xDF] A ̊eoCg͉i'_'jɕϊ悤łB ̓Iɂ́Ause locale; ŁAlc s/\W/_/g s (cf. Pod::Html::anchorify) ɂȂ܂B
-[2003-11-18]
-Perl̃y[W
diff --git a/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt
new file mode 100644
index 0000000000..7e964bbfb2
--- /dev/null
+++ b/tests/auto/corelib/serialization/qtextstream/stdinProcess/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## stdinProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(stdinProcess
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qtextstream/stdinProcess"
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp b/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp
index a3c1fc525b..b8a274ed0f 100644
--- a/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/stdinProcess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QTextStream>
diff --git a/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro b/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro
deleted file mode 100644
index f2b5aa619f..0000000000
--- a/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCES += main.cpp
-QT = core
-CONFIG += cmdline
-DESTDIR = ./
-
-# This app is testdata for tst_qtextstream
-target.path = $$[QT_INSTALL_TESTS]/tst_qtextstream/$$TARGET
-INSTALLS += target
diff --git a/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt b/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt
new file mode 100644
index 0000000000..588a49fcf0
--- /dev/null
+++ b/tests/auto/corelib/serialization/qtextstream/test/CMakeLists.txt
@@ -0,0 +1,49 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtextstream Test:
+#####################################################################
+
+# Collect test data
+list(APPEND test_data "../rfc3261.txt")
+list(APPEND test_data "../task113817.txt")
+list(APPEND test_data "../qtextstream.qrc")
+list(APPEND test_data "../qtextstream_integrity.qrc")
+list(APPEND test_data "../tst_qtextstream.cpp")
+list(APPEND test_data "../resources")
+list(APPEND test_data "../BLACKLIST")
+
+qt_internal_add_test(tst_qtextstream
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../tst_qtextstream.cpp
+ LIBRARIES
+ Qt::Network
+ Qt::TestPrivate
+ TESTDATA ${test_data}
+ QT_TEST_SERVER_LIST "cyrus"
+)
+
+if(QT_FEATURE_sanitize_address)
+ set_property(TEST tst_qtextstream APPEND PROPERTY ENVIRONMENT "QTEST_FUNCTION_TIMEOUT=900000")
+endif()
+
+# Resources:
+set(qtextstream_resource_files
+ "../resources/big_endian/"
+ "../resources/little_endian/"
+)
+
+qt_internal_add_resource(tst_qtextstream "qtextstream"
+ PREFIX
+ "/tst_textstream/"
+ BASE
+ ".."
+ FILES
+ ${qtextstream_resource_files}
+)
+
+if(QT_FEATURE_process)
+ add_dependencies(tst_qtextstream stdinProcess readAllStdinProcess readLineStdinProcess)
+endif()
diff --git a/tests/auto/corelib/serialization/qtextstream/test/test.pro b/tests/auto/corelib/serialization/qtextstream/test/test.pro
deleted file mode 100644
index 0f289a5ce1..0000000000
--- a/tests/auto/corelib/serialization/qtextstream/test/test.pro
+++ /dev/null
@@ -1,28 +0,0 @@
-CONFIG += testcase
-TARGET = ../tst_qtextstream
-QT = core network testlib
-SOURCES = ../tst_qtextstream.cpp
-RESOURCES += ../qtextstream.qrc
-INCLUDEPATH += ../../../../../shared/
-HEADERS += ../../../../../shared/emulationdetector.h
-
-win32 {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qtextstream
- } else {
- TARGET = ../../release/tst_qtextstream
- }
-}
-
-TESTDATA += \
- ../rfc3261.txt \
- ../shift-jis.txt \
- ../task113817.txt \
- ../qtextstream.qrc \
- ../tst_qtextstream.cpp \
- ../resources \
- ../BLACKLIST
-
-builtin_testdata {
- DEFINES += BUILTIN_TESTDATA
-}
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index 159fbd7b03..411084a36c 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#ifdef Q_OS_UNIX
#include <locale.h>
@@ -35,16 +10,18 @@
#include <QBuffer>
#include <QByteArray>
#include <QDebug>
+#include <QElapsedTimer>
#include <QFile>
+#include <QTemporaryFile>
+#include <QStringConverter>
#include <QTcpSocket>
#include <QTemporaryDir>
#include <QTextStream>
-#include <QTextCodec>
#if QT_CONFIG(process)
# include <QProcess>
#endif
#include "../../../network-settings.h"
-#include "emulationdetector.h"
+#include <QtTest/private/qemulationdetector_p.h>
QT_BEGIN_NAMESPACE
template<> struct QMetaTypeId<QIODevice::OpenModeFlag>
@@ -93,6 +70,8 @@ private slots:
// char operators
void QChar_operators_FromDevice_data();
void QChar_operators_FromDevice();
+ void char16_t_operators_FromDevice_data();
+ void char16_t_operators_FromDevice();
void char_operators_FromDevice_data();
void char_operators_FromDevice();
@@ -220,10 +199,13 @@ private slots:
// Regression tests for old bugs
void alignAccountingStyle();
- void setCodec();
+ void setEncoding();
void textModeOnEmptyRead();
+ void autodetectUnicode_data();
+ void autodetectUnicode();
+
private:
void generateLineData(bool for_QString);
void generateAllData(bool for_QString);
@@ -239,20 +221,18 @@ private:
QSharedPointer<QTemporaryDir> m_dataDir;
#endif
const QString m_rfc3261FilePath;
- const QString m_shiftJisFilePath;
};
void runOnExit()
{
QByteArray buffer;
- QTextStream(&buffer) << "This will try to use QTextCodec::codecForLocale" << endl;
+ QTextStream(&buffer) << "This will try to use QStringConverter::Utf8" << Qt::endl;
}
Q_DESTRUCTOR_FUNCTION(runOnExit)
tst_QTextStream::tst_QTextStream()
: tempDir(QDir::tempPath() + "/tst_qtextstream.XXXXXX")
, m_rfc3261FilePath(QFINDTESTDATA("rfc3261.txt"))
- , m_shiftJisFilePath(QFINDTESTDATA("shift-jis.txt"))
{
}
@@ -260,7 +240,6 @@ void tst_QTextStream::initTestCase()
{
QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString()));
QVERIFY(!m_rfc3261FilePath.isEmpty());
- QVERIFY(!m_shiftJisFilePath.isEmpty());
testFileName = tempDir.path() + "/testfile";
@@ -279,13 +258,12 @@ void tst_QTextStream::getSetCheck()
{
// Initialize codecs
QTextStream obj1;
- // QTextCodec * QTextStream::codec()
- // void QTextStream::setCodec(QTextCodec *)
- QTextCodec *var1 = QTextCodec::codecForName("en");
- obj1.setCodec(var1);
- QCOMPARE(var1, obj1.codec());
- obj1.setCodec((QTextCodec *)0);
- QCOMPARE((QTextCodec *)0, obj1.codec());
+ // QTextStream::encoding()
+ // QTextStream::setEncoding()
+ obj1.setEncoding(QStringConverter::Utf32BE);
+ QCOMPARE(QStringConverter::Utf32BE, obj1.encoding());
+ obj1.setEncoding(QStringConverter::Utf8);
+ QCOMPARE(QStringConverter::Utf8, obj1.encoding());
// bool QTextStream::autoDetectUnicode()
// void QTextStream::setAutoDetectUnicode(bool)
@@ -405,7 +383,7 @@ void tst_QTextStream::cleanupTestCase()
void tst_QTextStream::construction()
{
QTextStream stream;
- QCOMPARE(stream.codec(), QTextCodec::codecForLocale());
+ QCOMPARE(stream.encoding(), QStringConverter::Utf8);
QCOMPARE(stream.device(), static_cast<QIODevice *>(0));
QCOMPARE(stream.string(), static_cast<QString *>(0));
@@ -572,11 +550,11 @@ void tst_QTextStream::readLineMaxlen()
QFile::remove("testfile");
QFile file("testfile");
if (useDevice) {
- file.open(QIODevice::ReadWrite);
+ QVERIFY(file.open(QIODevice::ReadWrite));
file.write(input.toUtf8());
file.seek(0);
stream.setDevice(&file);
- stream.setCodec("utf-8");
+ stream.setEncoding(QStringConverter::Utf8);
} else {
stream.setString(&input);
}
@@ -612,15 +590,15 @@ class ErrorDevice : public QIODevice
protected:
qint64 readData(char *data, qint64 maxlen) override
{
- Q_UNUSED(data)
- Q_UNUSED(maxlen)
+ Q_UNUSED(data);
+ Q_UNUSED(maxlen);
return -1;
}
qint64 writeData(const char *data, qint64 len) override
{
- Q_UNUSED(data)
- Q_UNUSED(len)
+ Q_UNUSED(data);
+ Q_UNUSED(len);
return -1;
}
};
@@ -957,7 +935,8 @@ void tst_QTextStream::lineCount_data()
QTest::newRow("buffersize+1 line") << QByteArray(16384, '\n') << 16384;
QTest::newRow("buffersize+2 line") << QByteArray(16385, '\n') << 16385;
- QFile file(m_rfc3261FilePath); file.open(QFile::ReadOnly);
+ QFile file(m_rfc3261FilePath);
+ QVERIFY(file.open(QFile::ReadOnly));
QTest::newRow("rfc3261") << file.readAll() << 15067;
}
@@ -968,7 +947,7 @@ void tst_QTextStream::lineCount()
QFETCH(int, lineCount);
QFile out("out.txt");
- out.open(QFile::WriteOnly);
+ QVERIFY(out.open(QFile::WriteOnly));
QTextStream lineReader(data);
int lines = 0;
@@ -996,7 +975,7 @@ struct CompareIndicesForArray
void tst_QTextStream::performance()
{
// Phase #1 - test speed of reading a huge text file with QFile.
- QTime stopWatch;
+ QElapsedTimer stopWatch;
const int N = 3;
const char * readMethods[N] = {
@@ -1102,7 +1081,7 @@ void tst_QTextStream::hexTest()
QByteArray array;
QTextStream stream(&array);
- stream << showbase << hex << number;
+ stream << Qt::showbase << Qt::hex << number;
stream.flush();
QCOMPARE(array, data);
}
@@ -1132,7 +1111,7 @@ void tst_QTextStream::binTest()
QByteArray array;
QTextStream stream(&array);
- stream << showbase << bin << number;
+ stream << Qt::showbase << Qt::bin << number;
stream.flush();
QCOMPARE(array.constData(), data.constData());
}
@@ -1155,7 +1134,7 @@ void tst_QTextStream::octTest()
QByteArray array;
QTextStream stream(&array);
- stream << showbase << oct << number;
+ stream << Qt::showbase << Qt::oct << number;
stream.flush();
QCOMPARE(array, data);
}
@@ -1196,7 +1175,7 @@ void tst_QTextStream::ws_manipulator()
QTextStream stream(&string);
char a, b, c, d;
- stream >> a >> ws >> b >> ws >> c >> ws >> d;
+ stream >> a >> Qt::ws >> b >> Qt::ws >> c >> Qt::ws >> d;
QCOMPARE(a, 'a');
QCOMPARE(b, 'b');
QCOMPARE(c, 'c');
@@ -1214,11 +1193,16 @@ void tst_QTextStream::stillOpenWhenAtEnd()
while (!stream.readLine().isNull()) {}
QVERIFY(file.isOpen());
+#ifdef QT_TEST_SERVER
+ if (!QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143))
+ QSKIP("No network test server available");
+#else
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
+#endif
QTcpSocket socket;
- socket.connectToHost(QtNetworkSettings::serverName(), 143);
+ socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
QVERIFY(socket.waitForReadyRead(5000));
QTextStream stream2(&socket);
@@ -1377,46 +1361,6 @@ void tst_QTextStream::pos()
QCOMPARE(stream.pos(), qint64(2607));
QCOMPARE(strtmp, QString("locations"));
}
- {
- // Shift-JIS device
- for (int i = 0; i < 2; ++i) {
- QFile file(m_shiftJisFilePath);
- if (i == 0)
- QVERIFY(file.open(QIODevice::ReadOnly));
- else
- QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
-
- QTextStream stream(&file);
- stream.setCodec("Shift-JIS");
- QVERIFY(stream.codec());
-
- QCOMPARE(stream.pos(), qint64(0));
- for (int i = 0; i <= file.size(); i += 7) {
- QVERIFY(stream.seek(i));
- QCOMPARE(stream.pos(), qint64(i));
- }
- for (int j = file.size(); j >= 0; j -= 7) {
- QVERIFY(stream.seek(j));
- QCOMPARE(stream.pos(), qint64(j));
- }
-
- stream.seek(2089);
- QString strtmp;
- stream >> strtmp;
- QCOMPARE(strtmp, QString("AUnicode"));
- QCOMPARE(stream.pos(), qint64(2097));
-
- stream.seek(43325);
- stream >> strtmp;
- QCOMPARE(strtmp, QString("Shift-JIS"));
- stream >> strtmp;
- QCOMPARE(strtmp, QString::fromUtf8("\343\201\247\346\233\270\343\201\213\343\202\214\343\201\237"));
- QCOMPARE(stream.pos(), qint64(43345));
- stream >> strtmp;
- QCOMPARE(strtmp, QString("POD"));
- QCOMPARE(stream.pos(), qint64(43349));
- }
- }
}
// ------------------------------------------------------------------------------
@@ -1460,23 +1404,23 @@ void tst_QTextStream::pos2()
// ------------------------------------------------------------------------------
void tst_QTextStream::pos3LargeFile()
{
- if (EmulationDetector::isRunningArmOnX86())
+ if (QTestPrivate::isRunningArmOnX86())
QSKIP("Running QTextStream::pos() in tight loop is too slow on emulator");
{
QFile file(testFileName);
- file.open(QIODevice::WriteOnly | QIODevice::Text);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
QTextStream out( &file );
// NOTE: The unusual spacing is to ensure non-1-character whitespace.
QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n";
// Approximate 50kb text file
- const int NbLines = (50*1024) / lineString.length() + 1;
+ const int NbLines = (50*1024) / lineString.size() + 1;
for (int line = 0; line < NbLines; ++line)
out << lineString;
// File is automatically flushed and closed on destruction.
}
QFile file(testFileName);
- file.open(QIODevice::ReadOnly | QIODevice::Text);
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream in( &file );
const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int value;
@@ -1506,9 +1450,9 @@ void tst_QTextStream::readStdin()
stdinProcess.setReadChannel(QProcess::StandardError);
QTextStream stream(&stdinProcess);
- stream << "1" << endl;
- stream << "2" << endl;
- stream << "3" << endl;
+ stream << "1" << Qt::endl;
+ stream << "2" << Qt::endl;
+ stream << "3" << Qt::endl;
stdinProcess.closeWriteChannel();
@@ -1529,12 +1473,12 @@ void tst_QTextStream::readAllFromStdin()
QSKIP("No qprocess support", SkipAll);
#else
QProcess stdinProcess;
- stdinProcess.start("readAllStdinProcess/readAllStdinProcess", QIODevice::ReadWrite | QIODevice::Text);
+ stdinProcess.start("readAllStdinProcess/readAllStdinProcess", {}, QIODevice::ReadWrite | QIODevice::Text);
stdinProcess.setReadChannel(QProcess::StandardError);
QTextStream stream(&stdinProcess);
- stream.setCodec("ISO-8859-1");
- stream << "hello world" << flush;
+ stream.setEncoding(QStringConverter::Latin1);
+ stream << "hello world" << Qt::flush;
stdinProcess.closeWriteChannel();
@@ -1550,7 +1494,7 @@ void tst_QTextStream::readLineFromStdin()
QSKIP("No qprocess support", SkipAll);
#else
QProcess stdinProcess;
- stdinProcess.start("readLineStdinProcess/readLineStdinProcess", QIODevice::ReadWrite | QIODevice::Text);
+ stdinProcess.start("readLineStdinProcess/readLineStdinProcess", {}, QIODevice::ReadWrite | QIODevice::Text);
stdinProcess.setReadChannel(QProcess::StandardError);
stdinProcess.write("abc\n");
@@ -1573,7 +1517,7 @@ void tst_QTextStream::read()
{
QFile::remove("testfile");
QFile file("testfile");
- file.open(QFile::WriteOnly);
+ QVERIFY(file.open(QFile::WriteOnly));
file.write("4.15 abc ole");
file.close();
@@ -1595,7 +1539,7 @@ void tst_QTextStream::read()
// File larger than QTEXTSTREAM_BUFFERSIZE
QFile::remove("testfile");
QFile file("testfile");
- file.open(QFile::WriteOnly);
+ QVERIFY(file.open(QFile::WriteOnly));
for (int i = 0; i < 16384 / 8; ++i)
file.write("01234567");
file.write("0");
@@ -1623,18 +1567,18 @@ void tst_QTextStream::forcePoint()
{
QString str;
QTextStream stream(&str);
- stream << fixed << forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1;
+ stream << Qt::fixed << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1;
QCOMPARE(str, QString("1.000000 1 0 -1.000000 -1"));
str.clear();
stream.seek(0);
- stream << scientific << forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1;
+ stream << Qt::scientific << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1;
QCOMPARE(str, QString("1.000000e+00 1 0 -1.000000e+00 -1"));
str.clear();
stream.seek(0);
stream.setRealNumberNotation(QTextStream::SmartNotation);
- stream << forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1;
+ stream << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1;
QCOMPARE(str, QString("1.00000 1 0 -1.00000 -1"));
}
@@ -1644,15 +1588,15 @@ void tst_QTextStream::forceSign()
{
QString str;
QTextStream stream(&str);
- stream << forcesign << 1.2 << ' ' << -1.2 << ' ' << 0;
+ stream << Qt::forcesign << 1.2 << ' ' << -1.2 << ' ' << 0;
QCOMPARE(str, QString("+1.2 -1.2 +0"));
}
// ------------------------------------------------------------------------------
void tst_QTextStream::read0d0d0a()
{
- QFile file("task113817.txt");
- file.open(QIODevice::ReadOnly | QIODevice::Text);
+ QFile file(QFINDTESTDATA("task113817.txt"));
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream stream(&file);
while (!stream.atEnd())
@@ -1663,19 +1607,22 @@ void tst_QTextStream::read0d0d0a()
Q_DECLARE_METATYPE(QTextStreamFunction);
+// Also tests that we can have namespaces that conflict with our QTextStream constants.
+namespace ws {
QTextStream &noop(QTextStream &s) { return s; }
+}
void tst_QTextStream::numeralCase_data()
{
- QTextStreamFunction noop_ = noop;
- QTextStreamFunction bin_ = bin;
- QTextStreamFunction oct_ = oct;
- QTextStreamFunction hex_ = hex;
- QTextStreamFunction base = showbase;
- QTextStreamFunction ucb = uppercasebase;
- QTextStreamFunction lcb = lowercasebase;
- QTextStreamFunction ucd = uppercasedigits;
- QTextStreamFunction lcd = lowercasedigits;
+ QTextStreamFunction noop_ = ws::noop;
+ QTextStreamFunction bin = Qt::bin;
+ QTextStreamFunction oct = Qt::oct;
+ QTextStreamFunction hex = Qt::hex;
+ QTextStreamFunction base = Qt::showbase;
+ QTextStreamFunction ucb = Qt::uppercasebase;
+ QTextStreamFunction lcb = Qt::lowercasebase;
+ QTextStreamFunction ucd = Qt::uppercasedigits;
+ QTextStreamFunction lcd = Qt::lowercasedigits;
QTest::addColumn<QTextStreamFunction>("func1");
QTest::addColumn<QTextStreamFunction>("func2");
@@ -1686,30 +1633,30 @@ void tst_QTextStream::numeralCase_data()
QTest::newRow("dec 1") << noop_ << noop_ << noop_ << noop_ << 31 << "31";
QTest::newRow("dec 2") << noop_ << base << noop_ << noop_ << 31 << "31";
- QTest::newRow("hex 1") << hex_ << noop_ << noop_ << noop_ << 31 << "1f";
- QTest::newRow("hex 2") << hex_ << noop_ << noop_ << lcd << 31 << "1f";
- QTest::newRow("hex 3") << hex_ << noop_ << ucb << noop_ << 31 << "1f";
- QTest::newRow("hex 4") << hex_ << noop_ << noop_ << ucd << 31 << "1F";
- QTest::newRow("hex 5") << hex_ << noop_ << lcb << ucd << 31 << "1F";
- QTest::newRow("hex 6") << hex_ << noop_ << ucb << ucd << 31 << "1F";
- QTest::newRow("hex 7") << hex_ << base << noop_ << noop_ << 31 << "0x1f";
- QTest::newRow("hex 8") << hex_ << base << lcb << lcd << 31 << "0x1f";
- QTest::newRow("hex 9") << hex_ << base << ucb << noop_ << 31 << "0X1f";
- QTest::newRow("hex 10") << hex_ << base << ucb << lcd << 31 << "0X1f";
- QTest::newRow("hex 11") << hex_ << base << noop_ << ucd << 31 << "0x1F";
- QTest::newRow("hex 12") << hex_ << base << lcb << ucd << 31 << "0x1F";
- QTest::newRow("hex 13") << hex_ << base << ucb << ucd << 31 << "0X1F";
-
- QTest::newRow("bin 1") << bin_ << noop_ << noop_ << noop_ << 31 << "11111";
- QTest::newRow("bin 2") << bin_ << base << noop_ << noop_ << 31 << "0b11111";
- QTest::newRow("bin 3") << bin_ << base << lcb << noop_ << 31 << "0b11111";
- QTest::newRow("bin 4") << bin_ << base << ucb << noop_ << 31 << "0B11111";
- QTest::newRow("bin 5") << bin_ << base << noop_ << ucd << 31 << "0b11111";
- QTest::newRow("bin 6") << bin_ << base << lcb << ucd << 31 << "0b11111";
- QTest::newRow("bin 7") << bin_ << base << ucb << ucd << 31 << "0B11111";
-
- QTest::newRow("oct 1") << oct_ << noop_ << noop_ << noop_ << 31 << "37";
- QTest::newRow("oct 2") << oct_ << base << noop_ << noop_ << 31 << "037";
+ QTest::newRow("hex 1") << hex << noop_ << noop_ << noop_ << 31 << "1f";
+ QTest::newRow("hex 2") << hex << noop_ << noop_ << lcd << 31 << "1f";
+ QTest::newRow("hex 3") << hex << noop_ << ucb << noop_ << 31 << "1f";
+ QTest::newRow("hex 4") << hex << noop_ << noop_ << ucd << 31 << "1F";
+ QTest::newRow("hex 5") << hex << noop_ << lcb << ucd << 31 << "1F";
+ QTest::newRow("hex 6") << hex << noop_ << ucb << ucd << 31 << "1F";
+ QTest::newRow("hex 7") << hex << base << noop_ << noop_ << 31 << "0x1f";
+ QTest::newRow("hex 8") << hex << base << lcb << lcd << 31 << "0x1f";
+ QTest::newRow("hex 9") << hex << base << ucb << noop_ << 31 << "0X1f";
+ QTest::newRow("hex 10") << hex << base << ucb << lcd << 31 << "0X1f";
+ QTest::newRow("hex 11") << hex << base << noop_ << ucd << 31 << "0x1F";
+ QTest::newRow("hex 12") << hex << base << lcb << ucd << 31 << "0x1F";
+ QTest::newRow("hex 13") << hex << base << ucb << ucd << 31 << "0X1F";
+
+ QTest::newRow("bin 1") << bin << noop_ << noop_ << noop_ << 31 << "11111";
+ QTest::newRow("bin 2") << bin << base << noop_ << noop_ << 31 << "0b11111";
+ QTest::newRow("bin 3") << bin << base << lcb << noop_ << 31 << "0b11111";
+ QTest::newRow("bin 4") << bin << base << ucb << noop_ << 31 << "0B11111";
+ QTest::newRow("bin 5") << bin << base << noop_ << ucd << 31 << "0b11111";
+ QTest::newRow("bin 6") << bin << base << lcb << ucd << 31 << "0b11111";
+ QTest::newRow("bin 7") << bin << base << ucb << ucd << 31 << "0B11111";
+
+ QTest::newRow("oct 1") << oct << noop_ << noop_ << noop_ << 31 << "37";
+ QTest::newRow("oct 2") << oct << base << noop_ << noop_ << 31 << "037";
}
void tst_QTextStream::numeralCase()
@@ -1782,9 +1729,9 @@ void tst_QTextStream::nanInf()
QString s;
QTextStream out(&s);
out << qInf() << ' ' << -qInf() << ' ' << qQNaN()
- << uppercasedigits << ' '
+ << Qt::uppercasedigits << ' '
<< qInf() << ' ' << -qInf() << ' ' << qQNaN()
- << flush;
+ << Qt::flush;
QCOMPARE(s, QString("inf -inf nan INF -INF NAN"));
}
@@ -1806,7 +1753,6 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary()
QFile::remove(testFileName);
QFile data(testFileName);
- QTextCodec *utf8Codec = QTextCodec::codecForMib(106);
QString lineContents = QString::fromUtf8("\342\200\223" // U+2013 EN DASH
"\342\200\223"
"\342\200\223"
@@ -1814,26 +1760,26 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary()
"\342\200\223"
"\342\200\223");
- data.open(QFile::WriteOnly | QFile::Truncate);
+ QVERIFY(data.open(QFile::WriteOnly | QFile::Truncate));
{
QTextStream out(&data);
- out.setCodec(utf8Codec);
+ out.setEncoding(QStringConverter::Utf8);
out.setFieldWidth(3);
for (int i = 0; i < 1000; ++i) {
- out << i << lineContents << endl;
+ out << i << lineContents << Qt::endl;
}
}
data.close();
- data.open(QFile::ReadOnly);
+ QVERIFY(data.open(QFile::ReadOnly));
QTextStream in(&data);
QFETCH(bool, useLocale);
if (!useLocale)
- in.setCodec(utf8Codec); // QUtf8Codec
+ in.setEncoding(QStringConverter::Utf8);
else
- in.setCodec(QTextCodec::codecForLocale());
+ in.setEncoding(QStringConverter::System);
int i = 0;
do {
@@ -1859,9 +1805,9 @@ void tst_QTextStream::writeSeekWriteNoBOM()
int number = 0;
QString sizeStr = QLatin1String("Size=")
+ QString::number(number).rightJustified(10, QLatin1Char('0'));
- stream << sizeStr << endl;
- stream << "Version=" << QString::number(14) << endl;
- stream << "blah blah blah" << endl;
+ stream << sizeStr << Qt::endl;
+ stream << "Version=" << QString::number(14) << Qt::endl;
+ stream << "blah blah blah" << Qt::endl;
stream.flush();
QCOMPARE(out.buffer().constData(), "Size=0000000000\nVersion=14\nblah blah blah\n");
@@ -1871,7 +1817,7 @@ void tst_QTextStream::writeSeekWriteNoBOM()
stream.seek(0);
sizeStr = QLatin1String("Size=")
+ QString::number(number).rightJustified(10, QLatin1Char('0'));
- stream << sizeStr << endl;
+ stream << sizeStr << Qt::endl;
stream.flush();
// Check buffer is still OK
@@ -1883,7 +1829,7 @@ void tst_QTextStream::writeSeekWriteNoBOM()
QBuffer out16;
out16.open(QIODevice::WriteOnly);
QTextStream stream16(&out16);
- stream16.setCodec("UTF-16");
+ stream16.setEncoding(QStringConverter::Utf16);
stream16 << "one" << "two" << QLatin1String("three");
stream16.flush();
@@ -1937,7 +1883,7 @@ void tst_QTextStream::QChar_operators_FromDevice()
QBuffer buf(&input);
buf.open(QBuffer::ReadOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
QChar tmp;
stream >> tmp;
QCOMPARE(tmp, qchar_output);
@@ -1946,7 +1892,7 @@ void tst_QTextStream::QChar_operators_FromDevice()
writeBuf.open(QBuffer::WriteOnly);
QTextStream writeStream(&writeBuf);
- writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ writeStream.setEncoding(QStringConverter::Latin1);
writeStream << qchar_output;
writeStream.flush();
@@ -1955,6 +1901,40 @@ void tst_QTextStream::QChar_operators_FromDevice()
}
// ------------------------------------------------------------------------------
+void tst_QTextStream::char16_t_operators_FromDevice_data()
+{
+ generateOperatorCharData(false);
+}
+
+// ------------------------------------------------------------------------------
+void tst_QTextStream::char16_t_operators_FromDevice()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(const QChar, qchar_output);
+ QFETCH(const QByteArray, write_output);
+ const char16_t char16_t_output = qchar_output.unicode();
+
+ QBuffer buf(&input);
+ buf.open(QBuffer::ReadOnly);
+ QTextStream stream(&buf);
+ stream.setEncoding(QStringConverter::Latin1);
+ char16_t tmp;
+ stream >> tmp;
+ QCOMPARE(tmp, qchar_output);
+
+ QBuffer writeBuf;
+ writeBuf.open(QBuffer::WriteOnly);
+
+ QTextStream writeStream(&writeBuf);
+ writeStream.setEncoding(QStringConverter::Latin1);
+ writeStream << char16_t_output;
+ writeStream.flush();
+
+ QCOMPARE(writeBuf.buffer().size(), write_output.size());
+ QCOMPARE(writeBuf.buffer().constData(), write_output.constData());
+}
+
+// ------------------------------------------------------------------------------
void tst_QTextStream::char_operators_FromDevice_data()
{
generateOperatorCharData(false);
@@ -1970,7 +1950,7 @@ void tst_QTextStream::char_operators_FromDevice()
QBuffer buf(&input);
buf.open(QBuffer::ReadOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
char tmp;
stream >> tmp;
QCOMPARE(tmp, char_output);
@@ -1979,7 +1959,7 @@ void tst_QTextStream::char_operators_FromDevice()
writeBuf.open(QBuffer::WriteOnly);
QTextStream writeStream(&writeBuf);
- writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ writeStream.setEncoding(QStringConverter::Latin1);
writeStream << char_output;
writeStream.flush();
@@ -2166,9 +2146,9 @@ void tst_QTextStream::generateStringData(bool for_QString)
if (!for_QString) {
QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QByteArray() << QString();
- QTest::newRow("utf16-BE (corrupt)") << QByteArray("\xff", 1) << QByteArray("\xff") << QString::fromLatin1("\xff");
+ QTest::newRow("utf16-BE (corrupt)") << QByteArray("\xff", 1) << QByteArray("\xc3\xbf") << QString::fromUtf8("\xc3\xbf");
QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QByteArray() << QString();
- QTest::newRow("utf16-LE (corrupt)") << QByteArray("\xfe", 1) << QByteArray("\xfe") << QString::fromLatin1("\xfe");
+ QTest::newRow("utf16-LE (corrupt)") << QByteArray("\xfe", 1) << QByteArray("\xc3\xbe") << QString::fromUtf8("\xc3\xbe");
}
}
@@ -2187,7 +2167,7 @@ void tst_QTextStream::charPtr_read_operator_FromDevice()
QBuffer buffer(&input);
buffer.open(QBuffer::ReadOnly);
QTextStream stream(&buffer);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
char buf[1024];
@@ -2211,7 +2191,7 @@ void tst_QTextStream::stringRef_read_operator_FromDevice()
QBuffer buffer(&input);
buffer.open(QBuffer::ReadOnly);
QTextStream stream(&buffer);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
QString tmp;
@@ -2235,7 +2215,7 @@ void tst_QTextStream::byteArray_read_operator_FromDevice()
QBuffer buffer(&input);
buffer.open(QBuffer::ReadOnly);
QTextStream stream(&buffer);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
QByteArray array;
@@ -2445,8 +2425,8 @@ void tst_QTextStream::generateRealNumbersDataWrite()
QTest::newRow("0") << 0.0 << QByteArray("0") << QByteArray("0");
QTest::newRow("3.14") << 3.14 << QByteArray("3.14") << QByteArray("3.14");
QTest::newRow("-3.14") << -3.14 << QByteArray("-3.14") << QByteArray("-3.14");
- QTest::newRow("1.2e+10") << 1.2e+10 << QByteArray("1.2e+10") << QByteArray("1.2e+10");
- QTest::newRow("-1.2e+10") << -1.2e+10 << QByteArray("-1.2e+10") << QByteArray("-1.2e+10");
+ QTest::newRow("1.2e+10") << 1.2e+10 << QByteArray("1.2e+10") << QByteArray("1.2E+10");
+ QTest::newRow("-1.2e+10") << -1.2e+10 << QByteArray("-1.2e+10") << QByteArray("-1.2E+10");
QTest::newRow("12345") << 12345. << QByteArray("12345") << QByteArray("12,345");
}
@@ -2514,7 +2494,7 @@ void tst_QTextStream::string_write_operator_ToDevice()
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream << bytedata.constData();
@@ -2526,7 +2506,7 @@ void tst_QTextStream::string_write_operator_ToDevice()
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream << bytedata;
@@ -2538,7 +2518,7 @@ void tst_QTextStream::string_write_operator_ToDevice()
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream << stringdata;
@@ -2552,7 +2532,7 @@ void tst_QTextStream::latin1String_write_operator_ToDevice()
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream << QLatin1String("No explicit length");
@@ -2566,13 +2546,13 @@ void tst_QTextStream::stringref_write_operator_ToDevice()
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
- const QString expected = "No explicit lengthExplicit length";
+ const QStringView expected = u"No explicit lengthExplicit length";
- stream << expected.leftRef(18);
- stream << expected.midRef(18);
+ stream << expected.left(18);
+ stream << expected.mid(18);
stream.flush();
QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length");
}
@@ -2582,7 +2562,7 @@ void tst_QTextStream::stringview_write_operator_ToDevice()
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
- const QStringView expected = QStringViewLiteral("expectedStringView");
+ const QStringView expected = u"expectedStringView";
stream << expected;
stream.flush();
QCOMPARE(buf.buffer().constData(), "expectedStringView");
@@ -2597,7 +2577,7 @@ void tst_QTextStream::useCase1()
{
QTextStream stream(&file);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream << 4.15 << ' ' << QByteArray("abc") << ' ' << QString("ole");
@@ -2612,7 +2592,7 @@ void tst_QTextStream::useCase1()
QByteArray a;
QString s;
QTextStream stream(&file);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream >> d;
@@ -2633,7 +2613,7 @@ void tst_QTextStream::useCase2()
QVERIFY(file.open(QFile::ReadWrite));
QTextStream stream(&file);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
stream << 4.15 << ' ' << QByteArray("abc") << ' ' << QString("ole");
@@ -2650,7 +2630,7 @@ void tst_QTextStream::useCase2()
QByteArray a;
QString s;
QTextStream stream2(&file);
- stream2.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream2.setEncoding(QStringConverter::Latin1);
stream2.setAutoDetectUnicode(true);
stream2 >> d;
@@ -2665,28 +2645,44 @@ void tst_QTextStream::useCase2()
// ------------------------------------------------------------------------------
void tst_QTextStream::manipulators_data()
{
- QTest::addColumn<int>("flags");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<int>("alignFlag");
+ QTest::addColumn<int>("numberFlag");
QTest::addColumn<int>("width");
QTest::addColumn<double>("realNumber");
QTest::addColumn<int>("intNumber");
QTest::addColumn<QString>("textData");
QTest::addColumn<QByteArray>("result");
- QTest::newRow("no flags") << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
- QTest::newRow("rightadjust") << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray(" 5 5 five");
-
- // ### FIX
-// QTest::newRow("leftadjust") << int(QTextStream::left) << 10 << 5.0 << 5 << QString("five") << QByteArray("5 5 five ");
-// QTest::newRow("showpos") << int(QTextStream::showpos) << 10 << 5.0 << 5 << QString("five") << QByteArray(" +5 +5 five");
-// QTest::newRow("showpos2") << int(QTextStream::showpos) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14 -5 five");
-// QTest::newRow("hex") << int(QTextStream::hex | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
-// QTest::newRow("hex uppercase") << int(QTextStream::hex | QTextStream::uppercase | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
+ QTest::newRow("no flags")
+ << 10 << 0 << 0 << 0 << 5.0 << 5 << QString("five") << QByteArray("55five");
+ QTest::newRow("rightadjust")
+ << 10 << int(QTextStream::AlignRight) << 0 << 10 << 5.0 << 5 << QString("five")
+ << QByteArray(" 5 5 five");
+ QTest::newRow("leftadjust")
+ << 10 << int(QTextStream::AlignLeft) << 0 << 10 << 5.0 << 5 << QString("five")
+ << QByteArray("5 5 five ");
+ QTest::newRow("showpos-wide")
+ << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 10 << 5.0 << 5 <<
+ QString("five") << QByteArray(" +5 +5 five");
+ QTest::newRow("showpos-pi")
+ << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 5 << 3.14 << -5 <<
+ QString("five") << QByteArray("+3.14 -5 five");
+ QTest::newRow("hex-lower")
+ << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase) << 5 << 3.14 << -5 <<
+ QString("five") << QByteArray(" 3.14 -0x5 five");
+ QTest::newRow("hex-upper")
+ << 16 << int(QTextStream::AlignRight)
+ << int(QTextStream::ShowBase | QTextStream::UppercaseBase)
+ << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
}
// ------------------------------------------------------------------------------
void tst_QTextStream::manipulators()
{
-// QFETCH(int, flags);
+ QFETCH(int, base);
+ QFETCH(int, alignFlag);
+ QFETCH(int, numberFlag);
QFETCH(int, width);
QFETCH(double, realNumber);
QFETCH(int, intNumber);
@@ -2697,17 +2693,19 @@ void tst_QTextStream::manipulators()
buffer.open(QBuffer::WriteOnly);
QTextStream stream(&buffer);
- stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
+ stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
-// stream.setFlags(flags);
+ stream.setIntegerBase(base);
+ stream.setFieldAlignment(QTextStream::FieldAlignment(alignFlag));
+ stream.setNumberFlags(QTextStream::NumberFlag(numberFlag));
stream.setFieldWidth(width);
stream << realNumber;
stream << intNumber;
stream << textData;
stream.flush();
- QCOMPARE(buffer.data().constData(), result.constData());
+ QCOMPARE(buffer.data(), result);
}
void tst_QTextStream::generateBOM()
@@ -2718,8 +2716,8 @@ void tst_QTextStream::generateBOM()
QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate));
QTextStream stream(&file);
- stream.setCodec(QTextCodec::codecForName("UTF-16LE"));
- stream << "Hello" << endl;
+ stream.setEncoding(QStringConverter::Utf16LE);
+ stream << "Hello" << Qt::endl;
file.close();
QVERIFY(file.open(QFile::ReadOnly));
@@ -2732,8 +2730,8 @@ void tst_QTextStream::generateBOM()
QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate));
QTextStream stream(&file);
- stream.setCodec(QTextCodec::codecForName("UTF-16LE"));
- stream << bom << "Hello" << endl;
+ stream.setEncoding(QStringConverter::Utf16LE);
+ stream << Qt::bom << "Hello" << Qt::endl;
file.close();
QVERIFY(file.open(QFile::ReadOnly));
@@ -2751,7 +2749,7 @@ void tst_QTextStream::readBomSeekBackReadBomAgain()
QCOMPARE(file.pos(), qint64(0));
QTextStream stream(&file);
- stream.setCodec("UTF-8");
+ stream.setEncoding(QStringConverter::Utf8);
QString Andreas;
stream >> Andreas;
QCOMPARE(Andreas, QString("Andreas"));
@@ -2832,7 +2830,7 @@ void tst_QTextStream::status_word_read()
class FakeBuffer : public QBuffer
{
protected:
- qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); }
+ qint64 writeData(const char *c, qint64 i) override { return m_lock ? 0 : QBuffer::writeData(c, i); }
public:
FakeBuffer(bool locked = false) : m_lock(locked) {}
void setLocked(bool locked) { m_lock = locked; }
@@ -2845,7 +2843,7 @@ void tst_QTextStream::status_write_error()
FakeBuffer fb(false);
QVERIFY(fb.open(QBuffer::ReadWrite));
QTextStream fs(&fb);
- fs.setCodec(QTextCodec::codecForName("latin1"));
+ fs.setEncoding(QStringConverter::Latin1);
/* first write some initial content */
fs << "hello";
fs.flush();
@@ -2908,15 +2906,15 @@ void tst_QTextStream::alignAccountingStyle()
}
}
-void tst_QTextStream::setCodec()
+void tst_QTextStream::setEncoding()
{
QByteArray ba("\xe5 v\xe6r\n\xc3\xa5 v\xc3\xa6r\n");
QString res = QLatin1String("\xe5 v\xe6r");
QTextStream stream(ba);
- stream.setCodec("ISO 8859-1");
+ stream.setEncoding(QStringConverter::Latin1);
QCOMPARE(stream.readLine(),res);
- stream.setCodec("UTF-8");
+ stream.setEncoding(QStringConverter::Utf8);
QCOMPARE(stream.readLine(),res);
}
@@ -3014,7 +3012,7 @@ void tst_QTextStream::int_read_with_locale()
QFETCH(int, output);
QTextStream stream(&input);
- stream.setLocale(locale);
+ stream.setLocale(QLocale(locale));
int result;
stream >> result;
QCOMPARE(result, output);
@@ -3045,7 +3043,7 @@ void tst_QTextStream::int_write_with_locale()
QString result;
QTextStream stream(&result);
- stream.setLocale(locale);
+ stream.setLocale(QLocale(locale));
if (numberFlags)
stream.setNumberFlags(QTextStream::NumberFlags(numberFlags));
stream << input;
@@ -3064,6 +3062,57 @@ void tst_QTextStream::textModeOnEmptyRead()
QVERIFY(file.isTextModeEnabled());
}
+void tst_QTextStream::autodetectUnicode_data()
+{
+ QTest::addColumn<QStringConverter::Encoding>("encoding");
+ QTest::newRow("Utf8") << QStringConverter::Utf8;
+ QTest::newRow("Utf16BE") << QStringConverter::Utf16BE;
+ QTest::newRow("Utf16LE") << QStringConverter::Utf16LE;
+ QTest::newRow("Utf32BE") << QStringConverter::Utf32BE;
+ QTest::newRow("Utf32LE") << QStringConverter::Utf32LE;
+}
+
+void tst_QTextStream::autodetectUnicode()
+{
+ QFETCH(QStringConverter::Encoding, encoding);
+
+ QTemporaryFile file;
+ QVERIFY(file.open());
+
+ QString original("HelloWorld👋");
+
+ {
+ QTextStream out(&file);
+ out.setGenerateByteOrderMark(true);
+ out.setEncoding(encoding);
+ out << original;
+ }
+ file.seek(0);
+ {
+ QTextStream in(&file);
+ QString actual;
+ in >> actual;
+ QCOMPARE(actual, original);
+ QCOMPARE(in.encoding(), encoding);
+ }
+ file.seek(0);
+ // Again, but change order of calls to QTextStream...
+ {
+ QTextStream out(&file);
+ out.setEncoding(encoding);
+ out.setGenerateByteOrderMark(true);
+ out << original;
+ }
+ file.seek(0);
+ {
+ QTextStream in(&file);
+ QString actual;
+ in >> actual;
+ QCOMPARE(actual, original);
+ QCOMPARE(in.encoding(), encoding);
+ }
+}
+
// ------------------------------------------------------------------------------
diff --git a/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt b/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt
new file mode 100644
index 0000000000..30c86491ff
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qxmlstream Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qxmlstream LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+file(GLOB_RECURSE test_data
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/* XML-Test-Suite/*)
+
+file(GLOB_RECURSE tokenError
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ tokenError/*)
+
+qt_internal_add_test(tst_qxmlstream
+ SOURCES
+ tst_qxmlstream.cpp
+ LIBRARIES
+ Qt::Network
+ Qt::CorePrivate
+ Qt::TestPrivate
+ TESTDATA
+ ${test_data}
+ ${tokenError}
+)
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest.zip b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest.zip
new file mode 100644
index 0000000000..14ec3c5988
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest.zip
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Entries
deleted file mode 100644
index 56dc3e5713..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Entries
+++ /dev/null
@@ -1,6 +0,0 @@
-/canonxml.html/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/readme.html/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/xmltest.xml/1.11/Wed Apr 13 19:30:48 2005//
-D/invalid////
-D/not-wf////
-D/valid////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Repository
deleted file mode 100644
index e4b881877e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/canonxml.html b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/canonxml.html
deleted file mode 100644
index 2ba0edf6c6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/canonxml.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<HTML>
-<TITLE>Canonical XML</TITLE>
-<BODY>
-<H1>Canonical XML</H1>
-<P>
-This document defines a subset of XML called canonical XML.
-The intended use of canonical XML is in testing XML processors,
-as a representation of the result of parsing an XML document.
-<P>
-Every well-formed XML document has a unique structurally equivalent
-canonical XML document. Two structurally equivalent XML
-documents have a byte-for-byte identical canonical XML document.
-Canonicalizing an XML document requires only information that an XML
-processor is required to make available to an application.
-<P>
-A canonical XML document conforms to the following grammar:
-<PRE>
-CanonXML ::= Pi* element Pi*
-element ::= Stag (Datachar | Pi | element)* Etag
-Stag ::= '&lt;' Name Atts '&gt;'
-Etag ::= '&lt;/' Name '&gt;'
-Pi ::= '&lt;?' Name ' ' (((Char - S) Char*)? - (Char* '?&gt;' Char*)) '?&gt;'
-Atts ::= (' ' Name '=' '"' Datachar* '"')*
-Datachar ::= '&amp;amp;' | '&amp;lt;' | '&amp;gt;' | '&amp;quot;'
- | '&amp;#9;'| '&amp;#10;'| '&amp;#13;'
- | (Char - ('&amp;' | '&lt;' | '&gt;' | '"' | #x9 | #xA | #xD))
-Name ::= (see XML spec)
-Char ::= (see XML spec)
-S ::= (see XML spec)
-</PRE>
-<P>
-Attributes are in lexicographical order (in Unicode bit order).
-<P>
-A canonical XML document is encoded in UTF-8.
-<P>
-Ignorable white space is considered significant and is treated equivalently
-to data.
-<P>
-<ADDRESS>
-<A HREF="mailto:jjc@jclark.com">James Clark</A>
-</ADDRESS>
-
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.ent
deleted file mode 100644
index 4cb848b438..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY % e "(#PCDATA">
-<!ELEMENT doc %e;)>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.xml
deleted file mode 100644
index 5a3a96d1ab..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/002.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "002.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.ent
deleted file mode 100644
index 85e16474a6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY % e ">">
-<!ELEMENT doc (#PCDATA) %e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.xml
deleted file mode 100644
index 383553d24f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/005.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "005.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.ent
deleted file mode 100644
index 116ca79657..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY % e "(#PCDATA)>">
-<!ELEMENT doc %e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.xml
deleted file mode 100644
index 2f14e839e2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/006.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "006.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Entries
deleted file mode 100644
index 04159c511f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Entries
+++ /dev/null
@@ -1,7 +0,0 @@
-/002.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D/not-sa////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Repository
deleted file mode 100644
index 3df0ffe37c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/invalid
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.ent
deleted file mode 100644
index 26f2d8beb2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY % e "INCLUDE[">
-<!ELEMENT doc (#PCDATA)>
-<![ %e; <!ATTLIST doc a1 CDATA "v1"> ]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.xml
deleted file mode 100644
index b639f2551c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/022.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "022.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Entries
deleted file mode 100644
index 104a6d8a5a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Entries
+++ /dev/null
@@ -1,3 +0,0 @@
-/022.ent/1.1/Tue Feb 26 18:02:12 2002//
-/022.xml/1.1/Tue Feb 26 18:02:12 2002//
-D/out////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Repository
deleted file mode 100644
index f86b20a1d9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/022.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/022.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/022.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Entries
deleted file mode 100644
index 9692ca4b59..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Entries
+++ /dev/null
@@ -1,2 +0,0 @@
-/022.xml/1.1/Tue Feb 26 18:03:20 2002//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Repository
deleted file mode 100644
index 54370965bc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/invalid/not-sa/out/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries
deleted file mode 100644
index 1784810501..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries
+++ /dev/null
@@ -1 +0,0 @@
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries.Log b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries.Log
deleted file mode 100644
index 818f7c93e6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Entries.Log
+++ /dev/null
@@ -1,3 +0,0 @@
-A D/ext-sa////
-A D/not-sa////
-A D/sa////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Repository
deleted file mode 100644
index 18854d8755..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/not-wf
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.ent
deleted file mode 100644
index 378a2074b7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.ent
+++ /dev/null
@@ -1 +0,0 @@
-&e; \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.xml
deleted file mode 100644
index aa624cbe71..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/001.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e SYSTEM "001.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.ent
deleted file mode 100644
index 2cd184a213..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-data
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.xml
deleted file mode 100644
index 9eaf91724f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/002.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "002.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.ent
deleted file mode 100644
index ac292ee2f3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?>
-data
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.xml
deleted file mode 100644
index bb60b663ef..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/003.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "003.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Entries
deleted file mode 100644
index 85dc74e395..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Entries
+++ /dev/null
@@ -1,7 +0,0 @@
-/001.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.ent/1.2/Fri Feb 22 18:52:54 2002//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Repository
deleted file mode 100644
index 702914cf3a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/ext-sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.ent
deleted file mode 100644
index 00096e572e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<![ INCLUDE [
-<!ELEMENT doc (#PCDATA)>
-]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.xml
deleted file mode 100644
index 36188451ae..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/001.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "001.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/002.xml
deleted file mode 100644
index dd73174135..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/002.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "<?xml version='1.0' encoding='UTF-8'?>">
-%e;
-]>
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.ent
deleted file mode 100644
index abf1b1a35e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![ IGNORE [
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.xml
deleted file mode 100644
index dd01f41126..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/003.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "003.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.ent
deleted file mode 100644
index 552e4f520a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![ INCLUDE [
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.xml
deleted file mode 100644
index 20cdf6d0e5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/004.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "004.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.ent
deleted file mode 100644
index 9a369cef12..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-%e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.xml
deleted file mode 100644
index 383553d24f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/005.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "005.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.ent
deleted file mode 100644
index 771daf1915..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<![INCLUDE
-<!ELEMENT doc (#PCDATA)>
-]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.xml
deleted file mode 100644
index 2f14e839e2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/006.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "006.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.ent
deleted file mode 100644
index 9e9866d2ad..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.xml
deleted file mode 100644
index 38897e34ea..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/007.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "007.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.ent
deleted file mode 100644
index f8b1cd3dad..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc ANY>
-<!ENTITY e "100%">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.xml
deleted file mode 100644
index 54351009cd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/008.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "008.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.ent
deleted file mode 100644
index f70eaea9c4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc EMPTY>
-<!ENTITY % e "<!--">
-%e; -->
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.xml
deleted file mode 100644
index 9aa72898c2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/009.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "009.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.ent
deleted file mode 100644
index 54f3c821b8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY % e "<!ELEMENT ">
-%e; doc (#PCDATA)>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.xml
deleted file mode 100644
index 963e4c2f75..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/010.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "010.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.ent
deleted file mode 100644
index aae4cc2929..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY % e1 "<!ELEMENT ">
-<!ENTITY % e2 ">">
-%e1; doc (#PCDATA) %e2;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.xml
deleted file mode 100644
index dd40c958c3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/011.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "011.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Entries
deleted file mode 100644
index bfc0687397..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Entries
+++ /dev/null
@@ -1,22 +0,0 @@
-/001.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.ent/1.1/Mon Mar 25 18:59:43 2002//
-/009.xml/1.1/Mon Mar 25 18:59:17 2002//
-/010.ent/1.1/Mon Mar 25 18:34:47 2002//
-/010.xml/1.1/Mon Mar 25 18:33:57 2002//
-/011.ent/1.1/Mon Mar 25 19:08:52 2002//
-/011.xml/1.1/Mon Mar 25 19:08:40 2002//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Repository
deleted file mode 100644
index 031f3dedd2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/not-sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/001.xml
deleted file mode 100644
index d33ec68dcd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/001.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<doc>
-<doc
-?
-<a</a>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/002.xml
deleted file mode 100644
index 0a64d52428..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/002.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<doc>
-<.doc></.doc>
-</doc>
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/003.xml
deleted file mode 100644
index e0b8bae4a4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/003.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><? ?></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/004.xml
deleted file mode 100644
index e85bc96e56..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/004.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><?target some data></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/005.xml
deleted file mode 100644
index 7cd44ef10c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/005.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><?target some data?</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/006.xml
deleted file mode 100644
index 8594c35cc7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/006.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><!-- a comment -- another --></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/007.xml
deleted file mode 100644
index 286756fdd5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/007.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&amp no refc</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/008.xml
deleted file mode 100644
index 29ef40306b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/008.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&.entity;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/009.xml
deleted file mode 100644
index 8e3ff7de10..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/009.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#RE;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/010.xml
deleted file mode 100644
index a6790846c9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/010.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>A & B</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/011.xml
deleted file mode 100644
index 57eaf9fc48..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/011.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/012.xml
deleted file mode 100644
index 1b2539ffa6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/012.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1=v1></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/013.xml
deleted file mode 100644
index 3540df9143..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/013.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1'></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/014.xml
deleted file mode 100644
index a613115609..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/014.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="<foo>"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/015.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/015.xml
deleted file mode 100644
index f2baf947b5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/015.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1=></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/016.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/016.xml
deleted file mode 100644
index 22d4b2e265..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/016.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1" "v2"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/017.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/017.xml
deleted file mode 100644
index a76f5929e9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/017.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><![CDATA[</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/018.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/018.xml
deleted file mode 100644
index 66e204acc4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/018.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><![CDATA [ stuff]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/019.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/019.xml
deleted file mode 100644
index b835c2d752..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/019.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/020.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/020.xml
deleted file mode 100644
index b30cfcfc10..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/020.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="A & B"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/021.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/021.xml
deleted file mode 100644
index 1bfa84aa64..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/021.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="a&b"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/022.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/022.xml
deleted file mode 100644
index 44c803bf1b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/022.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="&#123:"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/023.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/023.xml
deleted file mode 100644
index b877ae2a6b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/023.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc 12="34"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/024.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/024.xml
deleted file mode 100644
index cf68f2c073..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/024.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<123></123>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/025.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/025.xml
deleted file mode 100644
index 6cba95cd78..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/025.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/026.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/026.xml
deleted file mode 100644
index 347984fa73..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/026.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>]]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/027.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/027.xml
deleted file mode 100644
index cfafaf0d70..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/027.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<!-- abc
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/028.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/028.xml
deleted file mode 100644
index 522714993a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/028.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<doc>
-<?a pi that is not closed
-</doc>
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/029.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/029.xml
deleted file mode 100644
index 9a8008bc9f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/029.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>abc]]]>def</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/030.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/030.xml
deleted file mode 100644
index 25861fa19b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/030.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>A form feed ( ) is not legal in data</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/031.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/031.xml
deleted file mode 100644
index f946536f39..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/031.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><?pi a form feed ( ) is not allowed in a pi?></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/032.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/032.xml
deleted file mode 100644
index 75952017ca..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/032.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><!-- a form feed ( ) is not allowed in a comment --></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/033.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/033.xml
deleted file mode 100644
index afd2328402..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/033.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>abcdef</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/034.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/034.xml
deleted file mode 100644
index d74a77719b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/034.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc >A form-feed is not white space or a name character</doc >
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/035.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/035.xml
deleted file mode 100644
index e1fc920522..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/035.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>1 < 2 but not in XML</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/036.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/036.xml
deleted file mode 100644
index b8ecb21ba1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/036.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<doc></doc>
-Illegal data
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/037.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/037.xml
deleted file mode 100644
index 2e02662926..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/037.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<doc></doc>
-&#32;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/038.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/038.xml
deleted file mode 100644
index 68b2803f82..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/038.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc x="foo" y="bar" x="baz"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/039.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/039.xml
deleted file mode 100644
index 80429e3e40..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/039.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><a></aa></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/040.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/040.xml
deleted file mode 100644
index dc8ba5a434..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/040.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<doc></doc>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/041.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/041.xml
deleted file mode 100644
index 30bcdd6bfe..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/041.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<doc/>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/042.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/042.xml
deleted file mode 100644
index 4ae50efc7b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/042.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc/></doc/>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/043.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/043.xml
deleted file mode 100644
index 41824eee4b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/043.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<doc/>
-Illegal data
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/044.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/044.xml
deleted file mode 100644
index 3fc232dc37..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/044.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc/><doc/>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/045.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/045.xml
deleted file mode 100644
index 00c10f00bf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/045.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<doc>
-<a/
-</doc>
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/046.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/046.xml
deleted file mode 100644
index 265cb15301..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/046.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<a/</a>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/047.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/047.xml
deleted file mode 100644
index d18a4a4440..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/047.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<a / >
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/048.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/048.xml
deleted file mode 100644
index 67419c1ed5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/048.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-</doc>
-<![CDATA[]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/049.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/049.xml
deleted file mode 100644
index 3cf0e79422..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/049.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<doc>
-<a><![CDATA[xyz]]]></a>
-<![CDATA[]]></a>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/051.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/051.xml
deleted file mode 100644
index b52df12cc4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/051.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- a comment -->
-<![CDATA[]]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/052.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/052.xml
deleted file mode 100644
index 8283895990..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/052.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- a comment -->
-&#32;
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/053.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/053.xml
deleted file mode 100644
index 9d7f36920f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/053.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></DOC>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/054.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/054.xml
deleted file mode 100644
index eda553c6d3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/054.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY foo PUBLIC "some public id">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/055.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/055.xml
deleted file mode 100644
index cbb3683a9d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/055.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc [
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/056.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/056.xml
deleted file mode 100644
index a681684c58..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/056.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc -- a comment -- []>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/057.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/057.xml
deleted file mode 100644
index 848d347120..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/057.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "whatever" -- a comment -->
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/058.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/058.xml
deleted file mode 100644
index daba266af2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/058.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 (foo,bar) #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/059.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/059.xml
deleted file mode 100644
index 316083dc25..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/059.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 NMTOKEN v1>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/060.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/060.xml
deleted file mode 100644
index 9a610fd38f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/060.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 NAME #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/061.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/061.xml
deleted file mode 100644
index 59181e706f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/061.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e PUBLIC "whatever""e.ent">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/062.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/062.xml
deleted file mode 100644
index e62e9cd370..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/062.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY foo"some text">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/063.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/063.xml
deleted file mode 100644
index 98675b9040..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/063.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<![INCLUDE[ ]]>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/064.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/064.xml
deleted file mode 100644
index 3888c46b8b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/064.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST e a1 CDATA"foo">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/065.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/065.xml
deleted file mode 100644
index da9cafd137..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/065.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1(foo|bar) #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/066.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/066.xml
deleted file mode 100644
index 9c09eb4e5d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/066.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 (foo|bar)#IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/067.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/067.xml
deleted file mode 100644
index 7e0809bd34..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/067.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 (foo)"foo">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/068.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/068.xml
deleted file mode 100644
index 53a80a83a8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/068.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 NOTATION(foo) #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/069.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/069.xml
deleted file mode 100644
index 6f891dd5e1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/069.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!NOTATION eps SYSTEM "eps.exe">
-<!-- missing space before NDATA -->
-<!ENTITY foo SYSTEM "foo.eps"NDATA eps>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/070.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/070.xml
deleted file mode 100644
index faf4b0ae4c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/070.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!-- a comment ending with three dashes --->
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/071.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/071.xml
deleted file mode 100644
index 5bd3908968..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/071.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e1 "&e2;">
-<!ENTITY e2 "&e3;">
-<!ENTITY e3 "&e1;">
-]>
-<doc>&e1;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/072.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/072.xml
deleted file mode 100644
index 743ba79429..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/072.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&foo;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/073.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/073.xml
deleted file mode 100644
index 2578af42ec..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/073.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "whatever">
-]>
-<doc>&f;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/074.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/074.xml
deleted file mode 100644
index f8abaeb22c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/074.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "</foo><foo>">
-]>
-<doc>
-<foo>&e;</foo>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/075.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/075.xml
deleted file mode 100644
index d3dbf50ed6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/075.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e1 "&e2;">
-<!ENTITY e2 "&e3;">
-<!ENTITY e3 "&e1;">
-]>
-<doc a="&e1;"></doc>
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/076.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/076.xml
deleted file mode 100644
index 60546720e7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/076.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="&foo;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/077.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/077.xml
deleted file mode 100644
index f8ac23a5a2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/077.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY foo "&bar;">
-]>
-<doc a="&foo;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/078.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/078.xml
deleted file mode 100644
index 446cd85ef9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/078.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA "&foo;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/079.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/079.xml
deleted file mode 100644
index da016fd3b2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/079.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e1 "&e2;">
-<!ENTITY e2 "&e3;">
-<!ENTITY e3 "&e1;">
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA "&e1;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/080.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/080.xml
deleted file mode 100644
index fa4b9e428d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/080.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e1 "&e2;">
-<!ENTITY e2 "&e3;">
-<!ENTITY e3 "&e1;">
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #FIXED "&e1;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/081.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/081.xml
deleted file mode 100644
index d676100e8a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/081.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e SYSTEM "nul">
-]>
-<doc a="&e;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/082.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/082.xml
deleted file mode 100644
index 3217d6f8b4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/082.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e SYSTEM "nul">
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA "&e;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/083.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/083.xml
deleted file mode 100644
index 469d43fd42..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/083.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e SYSTEM "nul" NDATA n>
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/084.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/084.xml
deleted file mode 100644
index abbbcdea69..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/084.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e SYSTEM "nul" NDATA n>
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA "&e;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/085.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/085.xml
deleted file mode 100644
index ac0aeca3e4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/085.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc PUBLIC "[" "null.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/086.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/086.xml
deleted file mode 100644
index df6adfd884..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/086.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY foo PUBLIC "[" "null.xml">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/087.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/087.xml
deleted file mode 100644
index ed49492a7a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/087.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!NOTATION foo PUBLIC "[" "null.ent">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/088.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/088.xml
deleted file mode 100644
index da0a68c401..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/088.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-<!ENTITY e '"'>
-]>
-<doc a="&e;></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/089.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/089.xml
deleted file mode 100644
index 0c6cf404c2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/089.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % foo SYSTEM "foo.xml" NDATA bar>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/090.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/090.xml
deleted file mode 100644
index 3fb72f3cc0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/090.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<foo a='&#60;'></foo>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/091.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/091.xml
deleted file mode 100644
index a61d0914f8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/091.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!NOTATION n SYSTEM "n">
-<!ENTITY % foo SYSTEM "foo.xml" NDATA n>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/092.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/092.xml
deleted file mode 100644
index be5266dada..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/092.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<foo a='&#38;'></foo>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/093.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/093.xml
deleted file mode 100644
index 4af61bc645..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/093.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#X58;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/094.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/094.xml
deleted file mode 100644
index bdec7a4660..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/094.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml VERSION="1.0"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/095.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/095.xml
deleted file mode 100644
index 090b8b4eec..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/095.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml encoding="UTF-8" version="1.0"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/096.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/096.xml
deleted file mode 100644
index d806c3b952..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/096.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0"encoding="UTF-8" ?>
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/097.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/097.xml
deleted file mode 100644
index d4def544b0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/097.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0' encoding="UTF-8" ?>
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/098.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/098.xml
deleted file mode 100644
index 9798496aa3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/098.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" version="1.0"?>
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/099.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/099.xml
deleted file mode 100644
index d5be08eff0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/099.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" valid="no" ?>
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/100.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/100.xml
deleted file mode 100644
index 51e06231c2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/100.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" standalone="YES" ?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/101.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/101.xml
deleted file mode 100644
index afa5a455fc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/101.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding=" UTF-8"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/102.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/102.xml
deleted file mode 100644
index 8734adaa6e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/102.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0 " ?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/103.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/103.xml
deleted file mode 100644
index 6c4716798f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/103.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#60;foo>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/104.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/104.xml
deleted file mode 100644
index dd57396239..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/104.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<foo>">
-]>
-<doc>&e;</foo></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/105.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/105.xml
deleted file mode 100644
index 809e705870..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/105.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?pi stuff?>
-<![CDATA[]]>
-<doc>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/106.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/106.xml
deleted file mode 100644
index d32319ef09..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/106.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?pi data?>
-&#32;<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/107.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/107.xml
deleted file mode 100644
index 3dfd8200e2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/107.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<![CDATA[]]>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/108.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/108.xml
deleted file mode 100644
index af5cf50d48..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/108.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<![CDATA [ ]]>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/109.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/109.xml
deleted file mode 100644
index 5afc03e8db..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/109.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<doc></doc>">
-]>
-&e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/110.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/110.xml
deleted file mode 100644
index cf54ebe5c0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/110.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "">
-]>
-<doc></doc>
-&e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/111.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/111.xml
deleted file mode 100644
index 84a469f5d1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/111.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "foo='bar'">
-]>
-<doc &e;></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/112.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/112.xml
deleted file mode 100644
index 0c5c1a4341..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/112.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<![cdata[data]]>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/113.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/113.xml
deleted file mode 100644
index 04fc9d2318..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/113.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % foo "&">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/114.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/114.xml
deleted file mode 100644
index 1261ee49e1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/114.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY foo "&">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/115.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/115.xml
deleted file mode 100644
index f111dbe153..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/115.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#38;">
-]>
-<doc a="&e;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/116.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/116.xml
deleted file mode 100644
index 84bb762fdf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/116.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#38;#9">
-]>
-<doc>&e;7;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/117.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/117.xml
deleted file mode 100644
index e4a5e572ef..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/117.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#38;">
-]>
-<doc>&e;#97;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/118.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/118.xml
deleted file mode 100644
index 494d53d208..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/118.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "#">
-]>
-<doc>&&e;97;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/119.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/119.xml
deleted file mode 100644
index aefaa44a1c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/119.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#38;">
-]>
-<doc>
-&e;#38;
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/120.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/120.xml
deleted file mode 100644
index b7d6ff9ce9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/120.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#38;">
-]>
-<doc>
-&e;
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/121.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/121.xml
deleted file mode 100644
index 2b4adcc6b4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/121.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY #DEFAULT "default">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/122.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/122.xml
deleted file mode 100644
index ef0b057cee..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/122.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a, (b) | c)?>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/123.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/123.xml
deleted file mode 100644
index 06d65f045b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/123.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc ((doc?)))>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/124.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/124.xml
deleted file mode 100644
index 3bbe0f91a6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/124.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (doc|#PCDATA)*>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/125.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/125.xml
deleted file mode 100644
index 5f9c22c0c6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/125.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc ((#PCDATA))>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/126.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/126.xml
deleted file mode 100644
index 13e74d6d5e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/126.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)+>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/127.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/127.xml
deleted file mode 100644
index a379b9e539..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/127.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)?>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/128.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/128.xml
deleted file mode 100644
index dd706bb21f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/128.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc CDATA>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/129.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/129.xml
deleted file mode 100644
index d4e4461a6d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/129.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc - - (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/130.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/130.xml
deleted file mode 100644
index fa7be641f1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/130.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (doc?) +(foo)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/131.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/131.xml
deleted file mode 100644
index f34ed453b5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/131.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (doc?) -(foo)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/132.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/132.xml
deleted file mode 100644
index ab6cc416e9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/132.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a, (b, c), (d, (e, f) | g))?>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/133.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/133.xml
deleted file mode 100644
index d2aa604e9f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/133.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a *)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/134.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/134.xml
deleted file mode 100644
index c8919c5ef8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/134.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a) *>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/135.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/135.xml
deleted file mode 100644
index e639e8b6ea..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/135.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a & b)?>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/136.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/136.xml
deleted file mode 100644
index 499e68bcea..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/136.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc O O (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/137.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/137.xml
deleted file mode 100644
index 723b77f776..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/137.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc(#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/138.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/138.xml
deleted file mode 100644
index 16934cc88e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/138.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (doc*?)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/139.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/139.xml
deleted file mode 100644
index 34df52ed93..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/139.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc ()>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/140.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/140.xml
deleted file mode 100644
index 467d5ed301..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/140.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<&#x309a;></&#x309a;>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/141.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/141.xml
deleted file mode 100644
index 409d0a7568..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/141.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<X&#xe5c;></X&#xe5c;>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/142.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/142.xml
deleted file mode 100644
index 20e88f88b3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/142.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#0;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/143.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/143.xml
deleted file mode 100644
index 0ee1c614f8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/143.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#31;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/144.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/144.xml
deleted file mode 100644
index 437548c0ba..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/144.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#xFFFF;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/145.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/145.xml
deleted file mode 100644
index 71b187a933..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/145.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#xD800;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/146.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/146.xml
deleted file mode 100644
index d0bfbca723..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/146.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#x110000;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/147.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/147.xml
deleted file mode 100644
index 3b6145615f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/147.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-<?xml version="1.0"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/148.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/148.xml
deleted file mode 100644
index 774dce18fd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/148.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- -->
-<?xml version="1.0"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/149.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/149.xml
deleted file mode 100644
index 725eea0dec..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/149.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<?xml version="1.0"?>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/150.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/150.xml
deleted file mode 100644
index 44f6b6df92..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/150.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<?xml version="1.0"?>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/151.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/151.xml
deleted file mode 100644
index fecc4f24e3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/151.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-</doc>
-<?xml version="1.0"?>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/152.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/152.xml
deleted file mode 100644
index b5c5cb26ae..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/152.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml encoding="UTF-8"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/153.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/153.xml
deleted file mode 100644
index 5e2973707e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/153.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "<?xml encoding='UTF-8'?>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/154.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/154.xml
deleted file mode 100644
index 96e01d63f5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/154.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?XML version="1.0"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/155.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/155.xml
deleted file mode 100644
index 4f16d0f163..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/155.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xmL version="1.0"?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/156.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/156.xml
deleted file mode 100644
index c6d93fd312..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/156.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<?xMl version="1.0"?>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/157.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/157.xml
deleted file mode 100644
index 2f058dac3e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/157.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<doc>
-<?xmL?>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/158.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/158.xml
deleted file mode 100644
index 32b90b722d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/158.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!NOTATION gif PUBLIC "image/gif" "">
-<!ATTLIST #NOTATION gif a1 CDATA #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/159.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/159.xml
deleted file mode 100644
index 066244cb91..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/159.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "<![CDATA[Tim & Michael]]>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/160.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/160.xml
deleted file mode 100644
index 85424acb1b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/160.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "">
-<!ENTITY foo "%e;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/161.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/161.xml
deleted file mode 100644
index 4f8a5b7b6b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/161.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e "#PCDATA">
-<!ELEMENT doc (%e;)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/162.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/162.xml
deleted file mode 100644
index efae4b190e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/162.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e1 "">
-<!ENTITY % e2 "%e1;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/163.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/163.xml
deleted file mode 100644
index e14fb76c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/163.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "">
-]>
-%e;
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/164.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/164.xml
deleted file mode 100644
index 98dd267c21..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/164.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "">
-] %e; >
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/165.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/165.xml
deleted file mode 100644
index 36c04618ef..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/165.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY% e "">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml
deleted file mode 100644
index ee2ce28630..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>￿</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/167.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/167.xml
deleted file mode 100644
index 9bdc6c1278..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/167.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>￾</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/168.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/168.xml
deleted file mode 100644
index f83221a3ad..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/168.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/169.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/169.xml
deleted file mode 100644
index 310029b976..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/169.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/170.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/170.xml
deleted file mode 100644
index cfa0aee155..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/170.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/171.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/171.xml
deleted file mode 100644
index 48b5c7d3bc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/171.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!-- ￿ -->
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/172.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/172.xml
deleted file mode 100644
index 6651d4d299..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/172.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?pi ￿?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/173.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/173.xml
deleted file mode 100644
index f9f9f42023..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/173.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="￿"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/174.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/174.xml
deleted file mode 100644
index 42bef861c6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/174.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><![CDATA[￿]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/175.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/175.xml
deleted file mode 100644
index 69912f36d2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/175.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "￿">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/176.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/176.xml
deleted file mode 100644
index 9c8e2e47d1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/176.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/177.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/177.xml
deleted file mode 100644
index 6bc8228879..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/177.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>A￿</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/178.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/178.xml
deleted file mode 100644
index e8f2d18eed..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/178.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="&#34;></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/179.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/179.xml
deleted file mode 100644
index e8f1f419db..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/179.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#34;>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/180.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/180.xml
deleted file mode 100644
index 569d553a8c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/180.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA "&e;">
-<!ENTITY e "v">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/181.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/181.xml
deleted file mode 100644
index 4341d99ee2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/181.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#60;![CDATA[">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&e;]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/182.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/182.xml
deleted file mode 100644
index 920f431666..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/182.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#60;!--">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&e;--></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/183.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/183.xml
deleted file mode 100644
index 7a5677de54..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/183.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA | foo*)* >
-<!ELEMENT foo EMPTY>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/184.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/184.xml
deleted file mode 100644
index 103384a06e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/184.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA | (foo))* >
-<!ELEMENT foo EMPTY>
-]>
-<doc></doc>
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.ent
deleted file mode 100644
index e557426454..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.ent
+++ /dev/null
@@ -1 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.xml
deleted file mode 100644
index 81d5ef4bcd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/185.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<!DOCTYPE doc SYSTEM "185.ent">
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/186.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/186.xml
deleted file mode 100644
index 85b26ec0a2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/186.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE a [
-<!ELEMENT a EMPTY>
-<!ATTLIST a b CDATA #IMPLIED d CDATA #IMPLIED>
-]>
-<a b="c"d="e"/>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Entries
deleted file mode 100644
index aef1bd67df..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Entries
+++ /dev/null
@@ -1,189 +0,0 @@
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/015.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/016.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/017.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/018.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/019.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/020.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/021.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/022.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/023.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/024.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/025.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/026.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/027.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/028.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/029.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/030.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/032.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/033.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/034.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/035.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/036.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/037.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/038.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/039.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/040.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/041.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/042.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/043.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/044.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/045.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/046.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/047.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/048.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/049.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/050.xml/1.1/Mon Feb 11 18:42:19 2002//
-/051.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/052.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/053.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/054.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/055.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/056.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/057.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/058.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/059.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/060.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/061.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/062.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/063.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/064.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/065.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/066.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/067.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/068.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/069.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/070.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/071.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/072.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/073.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/074.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/075.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/076.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/077.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/078.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/079.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/080.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/081.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/082.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/083.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/084.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/085.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/086.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/087.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/088.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/089.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/090.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/091.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/092.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/093.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/094.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/095.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/096.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/097.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/098.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/099.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/100.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/101.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/102.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/103.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/104.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/105.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/106.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/107.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/108.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/109.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/110.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/111.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/112.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/113.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/114.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/115.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/116.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/117.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/118.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/119.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/120.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/121.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/122.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/123.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/124.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/125.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/126.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/127.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/128.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/129.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/130.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/131.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/132.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/133.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/134.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/135.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/136.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/137.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/138.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/139.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/140.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/141.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/142.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/143.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/144.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/145.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/146.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/147.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/148.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/149.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/150.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/151.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/152.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/153.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/154.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/155.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/156.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/157.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/158.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/159.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/160.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/161.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/162.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/163.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/164.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/165.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/166.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/167.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/168.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/169.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/170.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/171.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/172.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/173.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/174.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/175.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/176.xml/1.2/Mon Apr 22 13:20:31 2002//
-/177.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/178.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/179.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/180.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/181.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/182.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/183.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/184.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/185.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/185.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/186.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/null.ent/1.1/Mon Feb 11 18:43:34 2002//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Repository
deleted file mode 100644
index ede48b429c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/not-wf/sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/null.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/null.ent
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/null.ent
+++ /dev/null
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/readme.html b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/readme.html
deleted file mode 100644
index fc7310c68e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/readme.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<HTML>
-<TITLE>XML Test Cases</TITLE>
-<BODY>
-<H1>XML Test Cases version 1998-11-18</H1>
-<P>
-Copyright (C) 1998 James Clark. All rights reserved. Permission is
-granted to copy and modify this collection in any way for internal use
-within a company or organization. Permission is granted to
-redistribute the file <code>xmltest.zip</code> containing this
-collection to third parties provided that no modifications of any kind
-are made to this file. Note that permission to distribute the
-collection in any other form is not granted.
-<P>
-The collection is structured into three directories:
-<DL>
-<DT><CODE>not-wf</CODE>
-<DD>this contains cases that are not well-formed XML documents
-<DT><CODE>valid</CODE>
-<DD>this contains cases that are valid XML documents
-<DT><CODE>invalid</CODE>
-<DD>this contains cases that are well-formed XML documents
-but are not valid XML documents
-</DL>
-<P>
-The <CODE>not-wf</CODE> and <CODE>valid</CODE> directories each have
-three subdirectories:
-<DL>
-<DT>
-<CODE>sa</CODE>
-<DD>
-this contains cases that are standalone (as defined in XML) and do not
-have references to external general entities
-<DT>
-<CODE>ext-sa</CODE>
-<DD>
-this contains case that are standalone and have references to external
-general entities
-<DT>
-<CODE>not-sa</CODE>
-<DD>
-this contains cases that are not standalone
-</DL>
-<P>
-In each directory, files with a <CODE>.xml</CODE> extension are the
-XML document test cases, and files with a <CODE>.ent</CODE> extension
-are external entities referenced by the test cases.
-<P>
-Within the <CODE>valid</CODE> directory, each of these three
-subdirectories has an <CODE>out</CODE> subdirectory which contains an
-equivalent <A HREF="canonxml.html">canonical XML</A> document for each
-of the cases.
-<P>
-<P>
-Bug reports and contributions of new test cases are welcome.
-<P>
-<ADDRESS>
-<A HREF="mailto:jjc@jclark.com">James Clark</A>
-</ADDRESS>
-</BODY>
-</HTML>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries
deleted file mode 100644
index 1784810501..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries
+++ /dev/null
@@ -1 +0,0 @@
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries.Log b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries.Log
deleted file mode 100644
index 818f7c93e6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Entries.Log
+++ /dev/null
@@ -1,3 +0,0 @@
-A D/ext-sa////
-A D/not-sa////
-A D/sa////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Repository
deleted file mode 100644
index 48324028e6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.ent
deleted file mode 100644
index 1cff3fd44f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.ent
+++ /dev/null
@@ -1 +0,0 @@
-Data
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.xml
deleted file mode 100644
index 147d70d2d1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/001.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "001.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.ent
deleted file mode 100644
index 45f6d8e74e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.ent
+++ /dev/null
@@ -1 +0,0 @@
-Data \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.xml
deleted file mode 100644
index 9eaf91724f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/002.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "002.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.ent
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.ent
+++ /dev/null
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.xml
deleted file mode 100644
index bb60b663ef..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/003.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "003.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.ent
deleted file mode 100644
index 3436f20001..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.ent
+++ /dev/null
@@ -1 +0,0 @@
-Data \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.xml
deleted file mode 100644
index 074498ce19..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/004.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "004.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.ent
deleted file mode 100644
index c6e97f821f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.ent
+++ /dev/null
@@ -1 +0,0 @@
-<e/><e/><e/> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.xml
deleted file mode 100644
index 82a6228205..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/005.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (e*)>
-<!ELEMENT e EMPTY>
-<!ENTITY e SYSTEM "005.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.ent
deleted file mode 100644
index 4df2f0c2ac..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.ent
+++ /dev/null
@@ -1,4 +0,0 @@
-Data
-<e/>
-More data
-<e/>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.xml
deleted file mode 100644
index 0b326cad4c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/006.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA|e)*>
-<!ELEMENT e EMPTY>
-<!ENTITY e SYSTEM "006.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.ent
deleted file mode 100644
index ab1d696dd7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.ent
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.xml
deleted file mode 100644
index 825e3b286a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/007.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "007.ent">
-]>
-<doc>X&e;Z</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.ent
deleted file mode 100644
index c6ca61f9c8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.ent
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.xml
deleted file mode 100644
index 3c001b6cb3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/008.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "008.ent">
-]>
-<doc>X&e;Z</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.ent
deleted file mode 100644
index 67c3297611..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.ent
+++ /dev/null
@@ -1 +0,0 @@
- \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.xml
deleted file mode 100644
index a5866e5a77..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/009.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "009.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.ent
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.ent
+++ /dev/null
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.xml
deleted file mode 100644
index 418e9b0141..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/010.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "010.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.ent
deleted file mode 100644
index b19be3a497..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.ent
+++ /dev/null
@@ -1 +0,0 @@
-xyzzy
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.xml
deleted file mode 100644
index 2ceefa1d21..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/011.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e PUBLIC "a not very interesting file" "011.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.ent
deleted file mode 100644
index 8eb1fb9c41..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.ent
+++ /dev/null
@@ -1 +0,0 @@
-&e4; \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.xml
deleted file mode 100644
index 5a8f009b4a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/012.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e1 "&e2;">
-<!ENTITY e2 "&e3;">
-<!ENTITY e3 SYSTEM "012.ent">
-<!ENTITY e4 "&e5;">
-<!ENTITY e5 "(e5)">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&e1;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.ent
deleted file mode 100644
index 7f25c502dd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.ent
+++ /dev/null
@@ -1 +0,0 @@
-<e/> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.xml
deleted file mode 100644
index 7717c97afe..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/013.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (e)>
-<!ELEMENT e (#PCDATA)>
-<!ATTLIST e
- a1 CDATA "a1 default"
- a2 NMTOKENS "a2 default"
->
-<!ENTITY x SYSTEM "013.ent">
-]>
-<doc>&x;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.ent
deleted file mode 100644
index 470fd6fe44..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.ent
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.xml
deleted file mode 100644
index 816fd1e796..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/014.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e SYSTEM "014.ent">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Entries
deleted file mode 100644
index 33a4a0da95..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Entries
+++ /dev/null
@@ -1,29 +0,0 @@
-/001.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D/out////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Repository
deleted file mode 100644
index 3753e3a5c9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/001.xml
deleted file mode 100644
index 0a7acf8ebe..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/001.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>Data&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/002.xml
deleted file mode 100644
index d4a445e555..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/002.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>Data</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/003.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/003.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/004.xml
deleted file mode 100644
index 0a7acf8ebe..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/004.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>Data&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/005.xml
deleted file mode 100644
index 6e293aa70e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/005.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><e></e><e></e><e></e></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/006.xml
deleted file mode 100644
index 04b6fc82ee..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/006.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>Data&#10;<e></e>&#10;More data&#10;<e></e>&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/007.xml
deleted file mode 100644
index ab2a74c9d1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/007.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>XYZ</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/008.xml
deleted file mode 100644
index ab2a74c9d1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/008.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>XYZ</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/009.xml
deleted file mode 100644
index a79dff65fd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/009.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/010.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/010.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/011.xml
deleted file mode 100644
index bf275adb2b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/011.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>xyzzy&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/012.xml
deleted file mode 100644
index 81a251cb4b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/012.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>(e5)</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/013.xml
deleted file mode 100644
index 524d94ee6b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/013.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><e a1="a1 default" a2="a2 default"></e></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/014.xml
deleted file mode 100644
index 71c6dc3e8e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/014.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>data</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Entries
deleted file mode 100644
index 577936756f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Entries
+++ /dev/null
@@ -1,15 +0,0 @@
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Repository
deleted file mode 100644
index 889051e1ae..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/ext-sa/out/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.ent
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.ent
+++ /dev/null
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.xml
deleted file mode 100644
index 2d6f41a137..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/001.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "001.ent" [
-<!ELEMENT doc EMPTY>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.ent
deleted file mode 100644
index 67c3297611..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.ent
+++ /dev/null
@@ -1 +0,0 @@
- \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.xml
deleted file mode 100644
index 023fce8499..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/002.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "002.ent" [
-<!ELEMENT doc EMPTY>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-1.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-1.ent
deleted file mode 100644
index 931f3ad6d8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-1.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc EMPTY>
-<!ENTITY % e SYSTEM "003-2.ent">
-<!ATTLIST doc a1 CDATA %e; "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-2.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-2.ent
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003-2.ent
+++ /dev/null
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003.xml
deleted file mode 100644
index 63a5e8bdfc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/003.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "003-1.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-1.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-1.ent
deleted file mode 100644
index 40f7ff58a2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-1.ent
+++ /dev/null
@@ -1,4 +0,0 @@
-<!ELEMENT doc EMPTY>
-<!ENTITY % e1 SYSTEM "004-2.ent">
-<!ENTITY % e2 "%e1;">
-%e1;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-2.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-2.ent
deleted file mode 100644
index 61def75cb7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004-2.ent
+++ /dev/null
@@ -1 +0,0 @@
-<!ATTLIST doc a1 CDATA "value">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004.xml
deleted file mode 100644
index adc9201496..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/004.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "004-1.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-1.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-1.ent
deleted file mode 100644
index ade9599032..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-1.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc EMPTY>
-<!ENTITY % e SYSTEM "005-2.ent">
-%e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-2.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-2.ent
deleted file mode 100644
index bef50b1f38..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005-2.ent
+++ /dev/null
@@ -1 +0,0 @@
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005.xml
deleted file mode 100644
index 6bd44cfee0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/005.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "005-1.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.ent
deleted file mode 100644
index 8f305a82bd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc EMPTY>
-<!ATTLIST doc a1 CDATA "w1" a2 CDATA "w2">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.xml
deleted file mode 100644
index eb80bb7409..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/006.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "006.ent" [
-<!ATTLIST doc a1 CDATA "v1">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.ent
deleted file mode 100644
index fbf4ca4947..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.xml
deleted file mode 100644
index 38897e34ea..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/007.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "007.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.ent
deleted file mode 100644
index fbf4ca4947..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.xml
deleted file mode 100644
index bf777a7ff2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/008.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc PUBLIC "whatever" "008.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.ent
deleted file mode 100644
index fbf4ca4947..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.xml
deleted file mode 100644
index c17562fe68..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/009.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc PUBLIC "whatever" "009.ent" [
-<!ATTLIST doc a2 CDATA "v2">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.ent
deleted file mode 100644
index 52a28f5deb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v2">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.xml
deleted file mode 100644
index 2786b328f3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/010.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "010.ent" [
-<!ATTLIST doc a1 CDATA "v1">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.ent
deleted file mode 100644
index fbf4ca4947..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.xml
deleted file mode 100644
index 03b482bbb6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/011.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e SYSTEM "011.ent">
-%e;
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.ent
deleted file mode 100644
index 7e372e65e9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.xml
deleted file mode 100644
index 1967edbba7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/012.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e SYSTEM "012.ent">
-%e;
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.ent
deleted file mode 100644
index a3691d9f08..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.ent
+++ /dev/null
@@ -1,4 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![ INCLUDE [
-<!ATTLIST doc a1 CDATA "v1">
-]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.xml
deleted file mode 100644
index cf44f2600a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/013.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "013.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.ent
deleted file mode 100644
index 6eaf779329..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.ent
+++ /dev/null
@@ -1,4 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![ %e; [
-<!ATTLIST doc a1 CDATA "v1">
-]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.xml
deleted file mode 100644
index bd08502489..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/014.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "014.ent" [
-<!ENTITY % e "INCLUDE">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.ent
deleted file mode 100644
index 00d2f30e1d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.ent
+++ /dev/null
@@ -1,5 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![ %e; [
-<!ATTLIST doc a1 CDATA "v1">
-]]>
-<!ATTLIST doc a2 CDATA "v2">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.xml
deleted file mode 100644
index e04e75ffca..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/015.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "015.ent" [
-<!ENTITY % e "IGNORE">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.ent
deleted file mode 100644
index bf77ef8336..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.ent
+++ /dev/null
@@ -1,4 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![%e;[
-<!ATTLIST doc a1 CDATA "v1">
-]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.xml
deleted file mode 100644
index 4ccf4af350..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/016.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc SYSTEM "016.ent" [
-<!ENTITY % e "INCLUDE">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.ent
deleted file mode 100644
index ffd9adde61..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "<!ATTLIST doc a1 CDATA 'v1'>">
-%e;
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.xml
deleted file mode 100644
index 7fe18f4c7a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/017.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "017.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.ent
deleted file mode 100644
index 2d46f76fc3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "'v1'">
-<!ATTLIST doc a1 CDATA %e;>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.xml
deleted file mode 100644
index 31e90f2405..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/018.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "018.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.ent
deleted file mode 100644
index d18201a98b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "'v1'">
-<!ATTLIST doc a1 CDATA%e;>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.xml
deleted file mode 100644
index b7a18faba0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/019.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "019.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.ent
deleted file mode 100644
index 815291c6d2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY % e "doc">
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST%e;a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.xml
deleted file mode 100644
index d70892f7ad..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/020.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "020.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.ent
deleted file mode 100644
index 9f8f2afd2b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY % e "doc a1 CDATA">
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST %e; "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.xml
deleted file mode 100644
index 70c28730db..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/021.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "021.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.ent
deleted file mode 100644
index e3268819f7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.ent
+++ /dev/null
@@ -1,5 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e1 "do">
-<!ENTITY % e2 "c">
-<!ENTITY % e3 "%e1;%e2;">
-<!ATTLIST %e3; a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.xml
deleted file mode 100644
index 1c2484b70b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/023.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "023.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.ent
deleted file mode 100644
index aa6d0eccac..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.ent
+++ /dev/null
@@ -1,4 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e1 "'v1'">
-<!ENTITY % e2 'a1 CDATA %e1;'>
-<!ATTLIST doc %e2;>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.xml
deleted file mode 100644
index 96e1ecb61b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/024.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "024.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.ent
deleted file mode 100644
index 389d259eb1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.ent
+++ /dev/null
@@ -1,5 +0,0 @@
-<!ELEMENT doc EMPTY>
-<!ENTITY % e "x">
-<!ENTITY % e "y">
-<!ENTITY % v "'%e;'">
-<!ATTLIST doc a1 CDATA %v;>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.xml
deleted file mode 100644
index 8fdbc14c47..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/025.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "025.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.ent
deleted file mode 100644
index bdc93af639..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.ent
+++ /dev/null
@@ -1 +0,0 @@
-<!ATTLIST doc a1 CDATA "w1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.xml
deleted file mode 100644
index 7b109c0913..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/026.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc ANY>
-<!ENTITY % e SYSTEM "026.ent">
-%e;
-<!ATTLIST doc a1 CDATA "x1" a2 CDATA "x2">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.ent
deleted file mode 100644
index 712cce3700..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY % e "">
-<!ELEMENT doc (#PCDATA %e;)>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.xml
deleted file mode 100644
index d0c8c7abb5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/027.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "027.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.ent
deleted file mode 100644
index ac249d7b2c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.ent
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![INCLUDE[<!ATTLIST doc a1 CDATA "v1">]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.xml
deleted file mode 100644
index 50e5248cbf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/028.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "028.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.ent
deleted file mode 100644
index df94df5560..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![IGNORE[<!ATTLIST doc a1 CDATA "v1">]]>
-<!ATTLIST doc a1 CDATA "v2">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.xml
deleted file mode 100644
index 07e226c1d7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/029.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "029.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.ent
deleted file mode 100644
index e3864460df..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<![IGNORE[]]>
-<![INCLUDE[]]>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.xml
deleted file mode 100644
index 01fc2be4ca..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/030.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "030.ent">
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-1.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-1.ent
deleted file mode 100644
index f7f94ab152..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-1.ent
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e SYSTEM "031-2.ent">
-<!ENTITY e "<![CDATA[%e;]]>">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-2.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-2.ent
deleted file mode 100644
index bef50b1f38..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031-2.ent
+++ /dev/null
@@ -1 +0,0 @@
-<!ATTLIST doc a1 CDATA "v1">
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031.xml
deleted file mode 100644
index c3fe5fca71..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/031.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE doc SYSTEM "031-1.ent">
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Entries
deleted file mode 100644
index 65ee741d6c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Entries
+++ /dev/null
@@ -1,65 +0,0 @@
-/001.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003-1.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003-2.ent/1.1/Mon Feb 11 18:45:43 2002//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004-1.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004-2.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005-1.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005-2.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/015.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/015.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/016.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/016.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/017.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/017.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/018.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/018.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/019.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/019.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/020.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/020.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/021.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/021.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/023.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/023.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/024.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/024.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/025.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/025.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/026.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/026.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/027.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/027.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/028.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/028.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/029.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/029.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/030.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/030.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031-1.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031-2.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D/out////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Repository
deleted file mode 100644
index b16565a893..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid/not-sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/001.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/001.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/002.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/002.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/003.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/003.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/004.xml
deleted file mode 100644
index bdc39e2224..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/004.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="value"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/005.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/005.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/006.xml
deleted file mode 100644
index d07627d7a3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/006.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1" a2="w2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/007.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/007.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/008.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/008.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/009.xml
deleted file mode 100644
index 7293fb63dc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/009.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1" a2="v2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/010.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/010.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/011.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/011.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/012.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/012.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/013.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/013.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/014.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/014.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/015.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/015.xml
deleted file mode 100644
index 131a32fe69..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/015.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a2="v2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/016.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/016.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/016.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/017.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/017.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/017.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/018.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/018.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/018.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/019.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/019.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/019.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/020.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/020.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/020.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/021.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/021.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/021.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/022.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/022.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/022.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/023.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/023.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/023.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/024.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/024.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/024.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/025.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/025.xml
deleted file mode 100644
index eb3f9674e8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/025.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="x"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/026.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/026.xml
deleted file mode 100644
index 71c02026e4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/026.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="w1" a2="x2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/027.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/027.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/027.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/028.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/028.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/028.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/029.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/029.xml
deleted file mode 100644
index 7ac8b2b89d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/029.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/030.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/030.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/030.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/031.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/031.xml
deleted file mode 100644
index 03a6c3f9cd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/031.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&lt;!ATTLIST doc a1 CDATA &quot;v1&quot;&gt;&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Entries
deleted file mode 100644
index 5c3b4ac876..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Entries
+++ /dev/null
@@ -1,32 +0,0 @@
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/015.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/016.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/017.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/018.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/019.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/020.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/021.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/022.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/023.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/024.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/025.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/026.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/027.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/028.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/029.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/030.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Repository
deleted file mode 100644
index 221d7aeedf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/not-sa/out/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/001.xml
deleted file mode 100644
index 7fbef49502..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/001.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/002.xml
deleted file mode 100644
index 2e3f1d81dd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/002.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc ></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/003.xml
deleted file mode 100644
index c841b81784..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/003.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc >
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/004.xml
deleted file mode 100644
index a9c5756933..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/004.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-]>
-<doc a1="v1"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/005.xml
deleted file mode 100644
index b069efe727..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/005.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-]>
-<doc a1 = "v1"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/006.xml
deleted file mode 100644
index 39a346342f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/006.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-]>
-<doc a1='v1'></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/007.xml
deleted file mode 100644
index cc3dc53166..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/007.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#32;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/008.xml
deleted file mode 100644
index b3370eb1cc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/008.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&amp;&lt;&gt;&quot;&apos;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/009.xml
deleted file mode 100644
index 0fa183eccf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/009.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#x20;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/010.xml
deleted file mode 100644
index eb64d18590..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/010.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-]>
-<doc a1="v1" ></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/011.xml
deleted file mode 100644
index 4cac44b4e4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/011.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED a2 CDATA #IMPLIED>
-]>
-<doc a1="v1" a2="v2"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/012.xml
deleted file mode 100644
index 6ce2a3eae2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/012.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc : CDATA #IMPLIED>
-]>
-<doc :="v1"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/013.xml
deleted file mode 100644
index 2f4aae4e28..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/013.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc _.-0123456789 CDATA #IMPLIED>
-]>
-<doc _.-0123456789="v1"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/014.xml
deleted file mode 100644
index 47f1f723e3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/014.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc abcdefghijklmnopqrstuvwxyz CDATA #IMPLIED>
-]>
-<doc abcdefghijklmnopqrstuvwxyz="v1"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/015.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/015.xml
deleted file mode 100644
index 861df8a610..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/015.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc ABCDEFGHIJKLMNOPQRSTUVWXYZ CDATA #IMPLIED>
-]>
-<doc ABCDEFGHIJKLMNOPQRSTUVWXYZ="v1"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/016.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/016.xml
deleted file mode 100644
index 66b1973c5d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/016.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><?pi?></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/017.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/017.xml
deleted file mode 100644
index 827ba963bf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/017.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><?pi some data ? > <??></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/018.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/018.xml
deleted file mode 100644
index 4570903fee..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/018.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><![CDATA[<foo>]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/019.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/019.xml
deleted file mode 100644
index 3e6b74cbf2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/019.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><![CDATA[<&]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/020.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/020.xml
deleted file mode 100644
index f749551a1b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/020.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><![CDATA[<&]>]]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/021.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/021.xml
deleted file mode 100644
index 13dda8c8a5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/021.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><!-- a comment --></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/022.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/022.xml
deleted file mode 100644
index 41d300e950..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/022.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><!-- a comment ->--></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/023.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/023.xml
deleted file mode 100644
index 3837b831ad..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/023.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/024.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/024.xml
deleted file mode 100644
index b0655c634c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/024.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (foo)>
-<!ELEMENT foo (#PCDATA)>
-<!ENTITY e "&#60;foo></foo>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/025.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/025.xml
deleted file mode 100644
index ed01f36d89..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/025.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (foo*)>
-<!ELEMENT foo (#PCDATA)>
-]>
-<doc><foo/><foo></foo></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/026.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/026.xml
deleted file mode 100644
index 1ba033c1a7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/026.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (foo*)>
-<!ELEMENT foo EMPTY>
-]>
-<doc><foo/><foo></foo></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/027.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/027.xml
deleted file mode 100644
index ee02439051..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/027.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (foo*)>
-<!ELEMENT foo ANY>
-]>
-<doc><foo/><foo></foo></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/028.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/028.xml
deleted file mode 100644
index 3d95747913..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/028.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/029.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/029.xml
deleted file mode 100644
index 909f6ff712..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/029.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/030.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/030.xml
deleted file mode 100644
index 3a7ddaa716..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/030.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version = "1.0"?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/031.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/031.xml
deleted file mode 100644
index a58e05867f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/031.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/032.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/032.xml
deleted file mode 100644
index be55c8d721..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/032.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/033.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/033.xml
deleted file mode 100644
index a3f9053868..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/033.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version='1.0' encoding="UTF-8" standalone='yes'?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/034.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/034.xml
deleted file mode 100644
index 7d52f31c0e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/034.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc/>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/035.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/035.xml
deleted file mode 100644
index f109a8b782..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/035.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc />
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/036.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/036.xml
deleted file mode 100644
index 8ab2b3fb16..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/036.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
-<?pi data?>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/037.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/037.xml
deleted file mode 100644
index f9b2113940..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/037.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
-<!-- comment -->
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/038.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/038.xml
deleted file mode 100644
index d14f41bfe2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/038.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!-- comment -->
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/039.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/039.xml
deleted file mode 100644
index 0897316e46..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/039.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?pi data?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/040.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/040.xml
deleted file mode 100644
index 12c419b65b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/040.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-]>
-<doc a1="&quot;&lt;&amp;&gt;&apos;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/041.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/041.xml
deleted file mode 100644
index a59f536277..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/041.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-]>
-<doc a1="&#65;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/042.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/042.xml
deleted file mode 100644
index 5d7c650944..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/042.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#00000000000000000000000000000000065;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/043.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/043.xml
deleted file mode 100644
index a8095dfe28..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/043.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ATTLIST doc a1 CDATA #IMPLIED>
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc a1="foo
-bar"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/044.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/044.xml
deleted file mode 100644
index bee1d23e1a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/044.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (e*)>
-<!ELEMENT e EMPTY>
-<!ATTLIST e a1 CDATA "v1" a2 CDATA "v2" a3 CDATA #IMPLIED>
-]>
-<doc>
-<e a3="v3"/>
-<e a1="w1"/>
-<e a2="w2" a3="v3"/>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/045.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/045.xml
deleted file mode 100644
index e2567f532d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/045.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
-<!ATTLIST doc a1 CDATA "z1">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/046.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/046.xml
deleted file mode 100644
index c50a2846f9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/046.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "v1">
-<!ATTLIST doc a2 CDATA "v2">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/047.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/047.xml
deleted file mode 100644
index a4c688cf1a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/047.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>X
-Y</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/048.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/048.xml
deleted file mode 100644
index c6b2dedbba..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/048.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>]</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/049.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/049.xml
deleted file mode 100644
index c3cc797b59..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/049.xml
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/050.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/050.xml
deleted file mode 100644
index 12303b1af2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/050.xml
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/051.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/051.xml
deleted file mode 100644
index 7ae8f6c73a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/051.xml
+++ /dev/null
Binary files differ
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/052.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/052.xml
deleted file mode 100644
index 3f33a4c760..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/052.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>𐀀􏿽</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/053.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/053.xml
deleted file mode 100644
index 0d88f28718..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/053.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<e/>">
-<!ELEMENT doc (e)>
-<!ELEMENT e EMPTY>
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/054.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/054.xml
deleted file mode 100644
index 5d1c88b946..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/054.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-
-
-<doc
-></doc
->
-
-
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/055.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/055.xml
deleted file mode 100644
index da0292c5bc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/055.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<?pi data?>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/056.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/056.xml
deleted file mode 100644
index 144871b2a3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/056.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#x0000000000000000000000000000000000000041;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/057.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/057.xml
deleted file mode 100644
index c1ac849ed1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/057.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a*)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/058.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/058.xml
deleted file mode 100644
index 2ff23b233f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/058.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ATTLIST doc a1 NMTOKENS #IMPLIED>
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc a1=" 1 2 "></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/059.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/059.xml
deleted file mode 100644
index 2171480ecf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/059.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (e*)>
-<!ELEMENT e EMPTY>
-<!ATTLIST e a1 CDATA #IMPLIED a2 CDATA #IMPLIED a3 CDATA #IMPLIED>
-]>
-<doc>
-<e a1="v1" a2="v2" a3="v3"/>
-<e a1="w1" a2="v2"/>
-<e a1="v1" a2="w2" a3="v3"/>
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/060.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/060.xml
deleted file mode 100644
index 6cd6b4386b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/060.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>X&#10;Y</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/061.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/061.xml
deleted file mode 100644
index bbdc152492..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/061.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#163;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/062.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/062.xml
deleted file mode 100644
index f4ba53090a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/062.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#xe40;&#xe08;&#xe21;ส์</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/063.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/063.xml
deleted file mode 100644
index 9668f2da73..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/063.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE เจมส์ [
-<!ELEMENT เจมส์ (#PCDATA)>
-]>
-<เจมส์></เจมส์>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/064.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/064.xml
deleted file mode 100644
index 74a97aa431..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/064.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#x10000;&#x10FFFD;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/065.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/065.xml
deleted file mode 100644
index f708f2bc17..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/065.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#60;">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/066.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/066.xml
deleted file mode 100644
index a27340b9a7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/066.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA #IMPLIED>
-<!-- 34 is double quote -->
-<!ENTITY e1 "&#34;">
-]>
-<doc a1="&e1;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/067.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/067.xml
deleted file mode 100644
index a0ccf772a5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/067.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#13;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/068.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/068.xml
deleted file mode 100644
index 8ed806b9a3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/068.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "&#13;">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/069.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/069.xml
deleted file mode 100644
index 2437f60530..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/069.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!NOTATION n PUBLIC "whatever">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/070.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/070.xml
deleted file mode 100644
index eef097df76..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/070.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e "<!ELEMENT doc (#PCDATA)>">
-%e;
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/071.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/071.xml
deleted file mode 100644
index ebfba230a4..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/071.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a ID #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/072.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/072.xml
deleted file mode 100644
index 6ef39dc49e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/072.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a IDREF #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/073.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/073.xml
deleted file mode 100644
index 217476d9a9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/073.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a IDREFS #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/074.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/074.xml
deleted file mode 100644
index 8b2354ff73..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/074.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a ENTITY #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/075.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/075.xml
deleted file mode 100644
index 33c012441a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/075.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a ENTITIES #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/076.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/076.xml
deleted file mode 100644
index 65b731cf6d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/076.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a NOTATION (n1|n2) #IMPLIED>
-<!NOTATION n1 SYSTEM "http://www.w3.org/">
-<!NOTATION n2 SYSTEM "http://www.w3.org/">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/077.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/077.xml
deleted file mode 100644
index e5f301eac8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/077.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a (1|2) #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/078.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/078.xml
deleted file mode 100644
index b31f40f94e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/078.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #REQUIRED>
-]>
-<doc a="v"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/079.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/079.xml
deleted file mode 100644
index a3290d6cbb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/079.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #FIXED "v">
-]>
-<doc a="v"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/080.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/080.xml
deleted file mode 100644
index 3208fa9aa5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/080.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #FIXED "v">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/081.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/081.xml
deleted file mode 100644
index 51ee1a375c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/081.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a, b, c)>
-<!ELEMENT a (a?)>
-<!ELEMENT b (b*)>
-<!ELEMENT c (a | b)+>
-]>
-<doc><a/><b/><c><a/></c></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/082.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/082.xml
deleted file mode 100644
index d5245ac51a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/082.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e SYSTEM "e.dtd">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/083.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/083.xml
deleted file mode 100644
index 937cfc0bdd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/083.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e PUBLIC 'whatever' "e.dtd">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/084.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/084.xml
deleted file mode 100644
index 82760767aa..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/084.xml
+++ /dev/null
@@ -1 +0,0 @@
-<!DOCTYPE doc [<!ELEMENT doc (#PCDATA)>]><doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/085.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/085.xml
deleted file mode 100644
index cf5834f2a5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/085.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e "<foo>">
-<!ENTITY e "">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/086.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/086.xml
deleted file mode 100644
index bbc3080db6..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/086.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "">
-<!ENTITY e "<foo>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/087.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/087.xml
deleted file mode 100644
index 34797a67d7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/087.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "<foo/&#62;">
-<!ELEMENT doc (foo)>
-<!ELEMENT foo EMPTY>
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/088.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/088.xml
deleted file mode 100644
index f97d96848d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/088.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "&lt;foo>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/089.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/089.xml
deleted file mode 100644
index 42ffcb6782..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/089.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e "&#x10000;&#x10FFFD;">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/090.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/090.xml
deleted file mode 100644
index c392c96084..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/090.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ATTLIST e a NOTATION (n) #IMPLIED>
-<!ELEMENT doc (e)*>
-<!ELEMENT e (#PCDATA)>
-<!NOTATION n PUBLIC "whatever">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/091.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/091.xml
deleted file mode 100644
index 7343d0f795..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/091.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!NOTATION n SYSTEM "http://www.w3.org/">
-<!ENTITY e SYSTEM "http://www.w3.org/" NDATA n>
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a ENTITY "e">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/092.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/092.xml
deleted file mode 100644
index 627b74ecdf..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/092.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a)*>
-<!ELEMENT a EMPTY>
-]>
-<doc>
-<a/>
- <a/> <a/>
-
-
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/093.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/093.xml
deleted file mode 100644
index 300578eb5c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/093.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>
-
-
-</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/094.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/094.xml
deleted file mode 100644
index 5726e7db6f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/094.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY % e "foo">
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a1 CDATA "%e;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/095.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/095.xml
deleted file mode 100644
index 1fe69596da..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/095.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ATTLIST doc a1 CDATA #IMPLIED>
-<!ATTLIST doc a1 NMTOKENS #IMPLIED>
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc a1="1 2"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/096.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/096.xml
deleted file mode 100644
index a6f8f43620..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/096.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ATTLIST doc a1 NMTOKENS " 1 2 ">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.ent b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.ent
deleted file mode 100644
index e06554ace2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.ent
+++ /dev/null
@@ -1 +0,0 @@
-<!ATTLIST doc a2 CDATA #IMPLIED>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.xml
deleted file mode 100644
index c606afa97f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/097.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY % e SYSTEM "097.ent">
-<!ATTLIST doc a1 CDATA "v1">
-%e;
-<!ATTLIST doc a2 CDATA "v2">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/098.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/098.xml
deleted file mode 100644
index 33a64ce5ae..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/098.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><?pi x
-y?></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/099.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/099.xml
deleted file mode 100644
index 1b7214a137..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/099.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/100.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/100.xml
deleted file mode 100644
index 5b839e76bc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/100.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ENTITY e PUBLIC ";!*#@$_%" "100.xml">
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/101.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/101.xml
deleted file mode 100644
index f464484bf5..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/101.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "&#34;">
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/102.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/102.xml
deleted file mode 100644
index f239ff5fee..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/102.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="&#34;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/103.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/103.xml
deleted file mode 100644
index 1dbbd5bb7c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/103.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc>&#60;doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/104.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/104.xml
deleted file mode 100644
index 666f43de0f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/104.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="x y"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/105.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/105.xml
deleted file mode 100644
index 6b3af2b847..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/105.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="x&#9;y"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/106.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/106.xml
deleted file mode 100644
index 8757c0a5ae..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/106.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="x&#10;y"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/107.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/107.xml
deleted file mode 100644
index 3d2c2566a7..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/107.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="x&#13;y"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/108.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/108.xml
deleted file mode 100644
index e919bf229a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/108.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "
-">
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="x&e;y"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/109.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/109.xml
deleted file mode 100644
index 33fa38e13b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/109.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a=""></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/110.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/110.xml
deleted file mode 100644
index 0c61c65119..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/110.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "&#13;&#10;">
-<!ATTLIST doc a CDATA #IMPLIED>
-]>
-<doc a="x&e;y"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/111.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/111.xml
deleted file mode 100644
index cb56f264b0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/111.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST doc a NMTOKENS #IMPLIED>
-]>
-<doc a="&#32;x&#32;&#32;y&#32;"></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/112.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/112.xml
deleted file mode 100644
index 27b6a4c793..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/112.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (a | b)>
-<!ELEMENT a (#PCDATA)>
-]>
-<doc><a></a></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/113.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/113.xml
deleted file mode 100644
index d2edd0f01d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/113.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ATTLIST e a CDATA #IMPLIED>
-]>
-<doc></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/114.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/114.xml
deleted file mode 100644
index 52e207096d..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/114.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e "<![CDATA[&foo;]]>">
-]>
-<doc>&e;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/115.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/115.xml
deleted file mode 100644
index d939a67010..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/115.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY e1 "&e2;">
-<!ENTITY e2 "v">
-]>
-<doc>&e1;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/116.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/116.xml
deleted file mode 100644
index 55ab49620b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/116.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-]>
-<doc><![CDATA[
-]]></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/117.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/117.xml
deleted file mode 100644
index e4f02b14c8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/117.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY rsqb "]">
-]>
-<doc>&rsqb;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/118.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/118.xml
deleted file mode 100644
index fba6c44668..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/118.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc (#PCDATA)>
-<!ENTITY rsqb "]]">
-]>
-<doc>&rsqb;</doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/119.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/119.xml
deleted file mode 100644
index 876e74730c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/119.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<!DOCTYPE doc [
-<!ELEMENT doc ANY>
-]>
-<doc><!-- -á --></doc>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Entries
deleted file mode 100644
index 5d10c3447a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Entries
+++ /dev/null
@@ -1,121 +0,0 @@
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/015.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/016.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/017.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/018.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/019.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/020.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/021.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/022.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/023.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/024.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/025.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/026.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/027.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/028.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/029.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/030.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/032.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/033.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/034.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/035.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/036.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/037.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/038.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/039.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/040.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/041.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/042.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/043.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/044.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/045.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/046.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/047.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/048.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/049.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/050.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/051.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/052.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/053.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/054.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/055.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/056.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/057.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/058.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/059.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/060.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/061.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/062.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/063.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/064.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/065.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/066.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/067.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/068.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/069.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/070.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/071.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/072.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/073.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/074.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/075.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/076.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/077.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/078.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/079.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/080.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/081.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/082.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/083.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/084.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/085.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/086.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/087.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/088.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/089.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/090.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/091.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/092.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/093.xml/1.2/Mon Apr 22 13:27:36 2002//
-/094.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/095.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/096.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/097.ent/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/097.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/098.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/099.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/100.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/101.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/102.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/103.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/104.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/105.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/106.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/107.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/108.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/109.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/110.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/111.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/112.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/113.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/114.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/115.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/116.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/117.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/118.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/119.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D/out////
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Repository
deleted file mode 100644
index 7dcbee54f2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid/sa
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/001.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/001.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/001.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/002.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/002.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/002.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/003.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/003.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/003.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/004.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/004.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/004.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/005.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/005.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/005.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/006.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/006.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/006.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/007.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/007.xml
deleted file mode 100644
index 97cf3e3b86..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/007.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc> </doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/008.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/008.xml
deleted file mode 100644
index 3ea232c21a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/008.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&amp;&lt;&gt;&quot;'</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/009.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/009.xml
deleted file mode 100644
index 97cf3e3b86..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/009.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc> </doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/010.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/010.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/010.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/011.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/011.xml
deleted file mode 100644
index 7293fb63dc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/011.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1" a2="v2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/012.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/012.xml
deleted file mode 100644
index 5a0c9831ae..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/012.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc :="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/013.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/013.xml
deleted file mode 100644
index c9c7ec5da8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/013.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc _.-0123456789="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/014.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/014.xml
deleted file mode 100644
index ac6b28f97a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/014.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc abcdefghijklmnopqrstuvwxyz="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/015.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/015.xml
deleted file mode 100644
index 8e216eb99b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/015.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc ABCDEFGHIJKLMNOPQRSTUVWXYZ="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/016.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/016.xml
deleted file mode 100644
index 4fc76928b2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/016.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><?pi ?></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/017.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/017.xml
deleted file mode 100644
index 3b9a2f8d4e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/017.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><?pi some data ? > <??></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/018.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/018.xml
deleted file mode 100644
index a5471011df..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/018.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&lt;foo&gt;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/019.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/019.xml
deleted file mode 100644
index 05d4e2fcf9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/019.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&lt;&amp;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/020.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/020.xml
deleted file mode 100644
index 95ae08a12e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/020.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&lt;&amp;]&gt;]</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/021.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/021.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/021.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/022.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/022.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/022.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/023.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/023.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/023.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/024.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/024.xml
deleted file mode 100644
index a9aa2074ff..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/024.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><foo></foo></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/025.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/025.xml
deleted file mode 100644
index de0f566020..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/025.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><foo></foo><foo></foo></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/026.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/026.xml
deleted file mode 100644
index de0f566020..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/026.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><foo></foo><foo></foo></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/027.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/027.xml
deleted file mode 100644
index de0f566020..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/027.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><foo></foo><foo></foo></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/028.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/028.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/028.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/029.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/029.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/029.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/030.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/030.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/030.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/031.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/031.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/031.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/032.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/032.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/032.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/033.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/033.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/033.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/034.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/034.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/034.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/035.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/035.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/035.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/036.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/036.xml
deleted file mode 100644
index 2bcfb06cf1..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/036.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc><?pi data?> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/037.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/037.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/037.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/038.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/038.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/038.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/039.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/039.xml
deleted file mode 100644
index 82d117d492..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/039.xml
+++ /dev/null
@@ -1 +0,0 @@
-<?pi data?><doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/040.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/040.xml
deleted file mode 100644
index d79cfe1493..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/040.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="&quot;&lt;&amp;&gt;'"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/041.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/041.xml
deleted file mode 100644
index 6f2cd5832e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/041.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="A"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/042.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/042.xml
deleted file mode 100644
index f683039a80..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/042.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>A</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/043.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/043.xml
deleted file mode 100644
index e162b76504..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/043.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="foo bar"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/044.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/044.xml
deleted file mode 100644
index 78028b704b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/044.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#10;<e a1="v1" a2="v2" a3="v3"></e>&#10;<e a1="w1" a2="v2"></e>&#10;<e a1="v1" a2="w2" a3="v3"></e>&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/045.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/045.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/045.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/046.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/046.xml
deleted file mode 100644
index 7293fb63dc..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/046.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1" a2="v2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/047.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/047.xml
deleted file mode 100644
index b327ebd67f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/047.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>X&#10;Y</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/048.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/048.xml
deleted file mode 100644
index ced7d02719..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/048.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>]</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/049.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/049.xml
deleted file mode 100644
index 7cc53f9ea0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/049.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>£</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/050.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/050.xml
deleted file mode 100644
index 33703c7925..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/050.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>เจมส์</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/051.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/051.xml
deleted file mode 100644
index cfeb5a5366..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/051.xml
+++ /dev/null
@@ -1 +0,0 @@
-<เจมส์></เจมส์> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/052.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/052.xml
deleted file mode 100644
index f5a0484791..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/052.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>𐀀􏿽</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/053.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/053.xml
deleted file mode 100644
index c4083843d9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/053.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><e></e></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/054.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/054.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/054.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/055.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/055.xml
deleted file mode 100644
index 82d117d492..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/055.xml
+++ /dev/null
@@ -1 +0,0 @@
-<?pi data?><doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/056.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/056.xml
deleted file mode 100644
index f683039a80..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/056.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>A</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/057.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/057.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/057.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/058.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/058.xml
deleted file mode 100644
index f898cc8c98..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/058.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="1 2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/059.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/059.xml
deleted file mode 100644
index 78028b704b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/059.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#10;<e a1="v1" a2="v2" a3="v3"></e>&#10;<e a1="w1" a2="v2"></e>&#10;<e a1="v1" a2="w2" a3="v3"></e>&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/060.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/060.xml
deleted file mode 100644
index b327ebd67f..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/060.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>X&#10;Y</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/061.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/061.xml
deleted file mode 100644
index 7cc53f9ea0..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/061.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>£</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/062.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/062.xml
deleted file mode 100644
index 33703c7925..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/062.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>เจมส์</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/063.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/063.xml
deleted file mode 100644
index cfeb5a5366..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/063.xml
+++ /dev/null
@@ -1 +0,0 @@
-<เจมส์></เจมส์> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/064.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/064.xml
deleted file mode 100644
index f5a0484791..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/064.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>𐀀􏿽</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/065.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/065.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/065.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/066.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/066.xml
deleted file mode 100644
index 7597d31bf9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/066.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="&quot;"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/067.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/067.xml
deleted file mode 100644
index 4bbdad45ed..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/067.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#13;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/068.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/068.xml
deleted file mode 100644
index 4bbdad45ed..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/068.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#13;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/070.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/070.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/070.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/071.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/071.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/071.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/072.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/072.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/072.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/073.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/073.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/073.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/074.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/074.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/074.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/075.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/075.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/075.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/077.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/077.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/077.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/078.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/078.xml
deleted file mode 100644
index fcab0cd7ff..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/078.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="v"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/079.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/079.xml
deleted file mode 100644
index fcab0cd7ff..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/079.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="v"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/080.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/080.xml
deleted file mode 100644
index fcab0cd7ff..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/080.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="v"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/081.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/081.xml
deleted file mode 100644
index e356e7e4db..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/081.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><a></a><b></b><c><a></a></c></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/082.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/082.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/082.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/083.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/083.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/083.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/084.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/084.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/084.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/085.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/085.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/085.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/086.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/086.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/086.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/087.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/087.xml
deleted file mode 100644
index a9aa2074ff..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/087.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><foo></foo></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/088.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/088.xml
deleted file mode 100644
index a5471011df..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/088.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&lt;foo&gt;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/089.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/089.xml
deleted file mode 100644
index f5a0484791..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/089.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>𐀀􏿽</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/092.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/092.xml
deleted file mode 100644
index 87269f79d9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/092.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#10;<a></a>&#10; <a></a>&#9;<a></a>&#10;&#10;&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/093.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/093.xml
deleted file mode 100644
index 631bfde91e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/093.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#10;&#10;&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/094.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/094.xml
deleted file mode 100644
index 636ab4729a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/094.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="%e;"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/095.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/095.xml
deleted file mode 100644
index a20706ee01..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/095.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="1 2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/096.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/096.xml
deleted file mode 100644
index f898cc8c98..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/096.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="1 2"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/097.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/097.xml
deleted file mode 100644
index e05cfe6c31..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/097.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a1="v1"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/098.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/098.xml
deleted file mode 100644
index f6408de9b8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/098.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<doc><?pi x
-y?></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/099.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/099.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/099.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/100.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/100.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/100.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/101.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/101.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/101.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/102.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/102.xml
deleted file mode 100644
index 6e66b8da21..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/102.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="&quot;"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/103.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/103.xml
deleted file mode 100644
index 96495d45c3..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/103.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&lt;doc&gt;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/104.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/104.xml
deleted file mode 100644
index cc3def3336..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/104.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/105.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/105.xml
deleted file mode 100644
index 5aed3d613b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/105.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x&#9;y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/106.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/106.xml
deleted file mode 100644
index 1197d2ff9c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/106.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x&#10;y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/107.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/107.xml
deleted file mode 100644
index 288f23cdf2..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/107.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x&#13;y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/108.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/108.xml
deleted file mode 100644
index cc3def3336..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/108.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/109.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/109.xml
deleted file mode 100644
index c43bdf9b9c..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/109.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a=""></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/110.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/110.xml
deleted file mode 100644
index a92237b4ec..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/110.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/111.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/111.xml
deleted file mode 100644
index cc3def3336..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/111.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc a="x y"></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/112.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/112.xml
deleted file mode 100644
index c82f47bca8..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/112.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc><a></a></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/113.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/113.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/113.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/114.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/114.xml
deleted file mode 100644
index 8e0722abad..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/114.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&amp;foo;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/115.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/115.xml
deleted file mode 100644
index 682b8140ec..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/115.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>v</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/116.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/116.xml
deleted file mode 100644
index a79dff65fd..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/116.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>&#10;</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/117.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/117.xml
deleted file mode 100644
index ced7d02719..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/117.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>]</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/118.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/118.xml
deleted file mode 100644
index 31e37a9398..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/118.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc>]]</doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/119.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/119.xml
deleted file mode 100644
index 7e8f183484..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/119.xml
+++ /dev/null
@@ -1 +0,0 @@
-<doc></doc> \ No newline at end of file
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Entries b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Entries
deleted file mode 100644
index 06b9ee385a..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Entries
+++ /dev/null
@@ -1,120 +0,0 @@
-/001.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/002.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/003.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/004.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/005.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/006.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/007.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/008.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/009.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/010.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/011.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/012.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/013.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/014.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/015.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/016.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/017.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/018.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/019.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/020.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/021.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/022.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/023.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/024.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/025.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/026.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/027.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/028.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/029.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/030.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/031.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/032.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/033.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/034.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/035.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/036.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/037.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/038.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/039.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/040.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/041.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/042.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/043.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/044.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/045.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/046.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/047.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/048.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/049.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/050.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/051.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/052.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/053.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/054.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/055.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/056.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/057.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/058.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/059.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/060.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/061.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/062.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/063.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/064.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/065.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/066.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/067.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/068.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/069.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/070.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/071.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/072.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/073.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/074.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/075.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/076.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/077.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/078.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/079.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/080.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/081.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/082.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/083.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/084.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/085.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/086.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/087.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/088.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/089.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/090.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/091.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/092.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/093.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/094.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/095.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/096.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/097.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/098.xml/1.2/Thu Feb 7 19:44:42 2002//
-/099.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/100.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/101.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/102.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/103.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/104.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/105.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/106.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/107.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/108.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/109.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/110.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/111.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/112.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/113.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/114.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/115.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/116.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/117.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/118.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-/119.xml/1.1.1.1/Wed Oct 17 09:52:58 2001//
-D
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Repository b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Repository
deleted file mode 100644
index 1e172d2e1b..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-2001/XML-Test-Suite/xmlconf/xmltest/valid/sa/out
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Root b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Root
deleted file mode 100644
index 3c7177e4bb..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/CVS/Root
+++ /dev/null
@@ -1 +0,0 @@
-:pserver:anonymous@dev.w3.org:/sources/public
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/xmltest.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/xmltest.xml
deleted file mode 100644
index bf81c88eb9..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/xmltest.xml
+++ /dev/null
@@ -1,1433 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- @(#)xmltest.xml 1.12 99/02/12
- Copyright 1998-1999 by Sun Microsystems, Inc.
- All Rights Reserved.
--->
-
-<TESTCASES PROFILE="James Clark XMLTEST cases, 18-Nov-1998">
-
-<!-- Start: not-wf/sa -->
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-001"
- URI="not-wf/sa/001.xml" SECTIONS="3.1 [41]">
- Attribute values must start with attribute names, not "?". </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-002"
- URI="not-wf/sa/002.xml" SECTIONS="2.3 [4]">
- Names may not start with "."; it's not a Letter. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-003"
- URI="not-wf/sa/003.xml" SECTIONS="2.6 [16]">
- Processing Instruction target name is required.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-004"
- URI="not-wf/sa/004.xml" SECTIONS="2.6 [16]">
- SGML-ism: processing instructions end in '?&gt;' not '&gt;'. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-005"
- URI="not-wf/sa/005.xml" SECTIONS="2.6 [16]">
- Processing instructions end in '?&gt;' not '?'. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-006"
- URI="not-wf/sa/006.xml" SECTIONS="2.5 [16]">
- XML comments may not contain "--" </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-007"
- URI="not-wf/sa/007.xml" SECTIONS="4.1 [68]">
- General entity references have no whitespace after the
- entity name and before the semicolon. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-008"
- URI="not-wf/sa/008.xml" SECTIONS="2.3 [5]">
- Entity references must include names, which don't begin
- with '.' (it's not a Letter or other name start character). </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-009"
- URI="not-wf/sa/009.xml" SECTIONS="4.1 [66]">
- Character references may have only decimal or numeric strings.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-010"
- URI="not-wf/sa/010.xml" SECTIONS="4.1 [68]">
- Ampersand may only appear as part of a general entity reference.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-011"
- URI="not-wf/sa/011.xml" SECTIONS="3.1 [41]">
- SGML-ism: attribute values must be explicitly assigned a
- value, it can't act as a boolean toggle. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-012"
- URI="not-wf/sa/012.xml" SECTIONS="2.3 [10]">
- SGML-ism: attribute values must be quoted in all cases. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-013"
- URI="not-wf/sa/013.xml" SECTIONS="2.3 [10]">
- The quotes on both ends of an attribute value must match. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-014"
- URI="not-wf/sa/014.xml" SECTIONS="2.3 [10]">
- Attribute values may not contain literal '&lt;' characters. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-015"
- URI="not-wf/sa/015.xml" SECTIONS="3.1 [41]">
- Attribute values need a value, not just an equals sign. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-016"
- URI="not-wf/sa/016.xml" SECTIONS="3.1 [41]">
- Attribute values need an associated name.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-017"
- URI="not-wf/sa/017.xml" SECTIONS="2.7 [18]">
- CDATA sections need a terminating ']]&gt;'. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-018"
- URI="not-wf/sa/018.xml" SECTIONS="2.7 [19]">
- CDATA sections begin with a literal '&lt;![CDATA[', no space.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-019"
- URI="not-wf/sa/019.xml" SECTIONS="3.1 [42]">
- End tags may not be abbreviated as '&lt;/&gt;'.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-020"
- URI="not-wf/sa/020.xml" SECTIONS="2.3 [10]">
- Attribute values may not contain literal '&amp;'
- characters except as part of an entity reference. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-021"
- URI="not-wf/sa/021.xml" SECTIONS="2.3 [10]">
- Attribute values may not contain literal '&amp;'
- characters except as part of an entity reference. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-022"
- URI="not-wf/sa/022.xml" SECTIONS="4.1 [66]">
- Character references end with semicolons, always!</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-023"
- URI="not-wf/sa/023.xml" SECTIONS="2.3 [5]">
- Digits are not valid name start characters. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-024"
- URI="not-wf/sa/024.xml" SECTIONS="2.3 [5]">
- Digits are not valid name start characters. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-025"
- URI="not-wf/sa/025.xml" SECTIONS="2.4 [14]">
- Text may not contain a literal ']]&gt;' sequence. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-026"
- URI="not-wf/sa/026.xml" SECTIONS="2.4 [14]">
- Text may not contain a literal ']]&gt;' sequence. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-027"
- URI="not-wf/sa/027.xml" SECTIONS="2.5 [15]">
- Comments must be terminated with "--&gt;".</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-028"
- URI="not-wf/sa/028.xml" SECTIONS="2.6 [16]">
- Processing instructions must end with '?&gt;'. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-029"
- URI="not-wf/sa/029.xml" SECTIONS="2.4 [14]">
- Text may not contain a literal ']]&gt;' sequence. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-030"
- URI="not-wf/sa/030.xml" SECTIONS="2.2 [2]">
- A form feed is not a legal XML character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-031"
- URI="not-wf/sa/031.xml" SECTIONS="2.2 [2]">
- A form feed is not a legal XML character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-032"
- URI="not-wf/sa/032.xml" SECTIONS="2.2 [2]">
- A form feed is not a legal XML character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-033"
- URI="not-wf/sa/033.xml" SECTIONS="2.2 [2]">
- An ESC (octal 033) is not a legal XML character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-034"
- URI="not-wf/sa/034.xml" SECTIONS="2.2 [2]">
- A form feed is not a legal XML character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-035"
- URI="not-wf/sa/035.xml" SECTIONS="3.1 [43]">
- The '&lt;' character is a markup delimiter and must
- start an element, CDATA section, PI, or comment. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-036"
- URI="not-wf/sa/036.xml" SECTIONS="2.8 [27]">
- Text may not appear after the root element. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-037"
- URI="not-wf/sa/037.xml" SECTIONS="2.8 [27]">
- Character references may not appear after the root element. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-038"
- URI="not-wf/sa/038.xml" SECTIONS="3.1">
- Tests the "Unique Att Spec" WF constraint by providing
- multiple values for an attribute.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-039"
- URI="not-wf/sa/039.xml" SECTIONS="3">
- Tests the Element Type Match WFC - end tag name must
- match start tag name.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-040"
- URI="not-wf/sa/040.xml" SECTIONS="2.8 [27]">
- Provides two document elements.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-041"
- URI="not-wf/sa/041.xml" SECTIONS="2.8 [27]">
- Provides two document elements.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-042"
- URI="not-wf/sa/042.xml" SECTIONS="3.1 [42]">
- Invalid End Tag </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-043"
- URI="not-wf/sa/043.xml" SECTIONS="2.8 [27]">
- Provides #PCDATA text after the document element. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-044"
- URI="not-wf/sa/044.xml" SECTIONS="2.8 [27]">
- Provides two document elements.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-045"
- URI="not-wf/sa/045.xml" SECTIONS="3.1 [44]">
- Invalid Empty Element Tag </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-046"
- URI="not-wf/sa/046.xml" SECTIONS="3.1 [40]">
- This start (or empty element) tag was not terminated correctly. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-047"
- URI="not-wf/sa/047.xml" SECTIONS="3.1 [44]">
- Invalid empty element tag invalid whitespace </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-048"
- URI="not-wf/sa/048.xml" SECTIONS="2.8 [27]">
- Provides a CDATA section after the root element.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-049"
- URI="not-wf/sa/049.xml" SECTIONS="3.1 [40]">
- Missing start tag </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-050"
- URI="not-wf/sa/050.xml" SECTIONS="2.1 [1]">
- Empty document, with no root element. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-051"
- URI="not-wf/sa/051.xml" SECTIONS="2.7 [18]">
- CDATA is invalid at top level of document.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-052"
- URI="not-wf/sa/052.xml" SECTIONS="4.1 [66]">
- Invalid character reference. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-053"
- URI="not-wf/sa/053.xml" SECTIONS="3.1 [42]">
- End tag does not match start tag. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-054"
- URI="not-wf/sa/054.xml" SECTIONS="4.2.2 [75]">
- PUBLIC requires two literals.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-055"
- URI="not-wf/sa/055.xml" SECTIONS="2.8 [28]">
- Invalid Document Type Definition format. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-056"
- URI="not-wf/sa/056.xml" SECTIONS="2.8 [28]">
- Invalid Document Type Definition format - misplaced comment. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-057"
- URI="not-wf/sa/057.xml" SECTIONS="3.2 [45]">
- This isn't SGML; comments can't exist in declarations. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-058"
- URI="not-wf/sa/058.xml" SECTIONS="3.3.1 [54]">
- Invalid character , in ATTLIST enumeration </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-059"
- URI="not-wf/sa/059.xml" SECTIONS="3.3.1 [59]">
- String literal must be in quotes. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-060"
- URI="not-wf/sa/060.xml" SECTIONS="3.3.1 [56]">
- Invalid type NAME defined in ATTLIST.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-061"
- URI="not-wf/sa/061.xml" SECTIONS="4.2.2 [75]">
- External entity declarations require whitespace between public
- and system IDs.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-062"
- URI="not-wf/sa/062.xml" SECTIONS="4.2 [71]">
- Entity declarations need space after the entity name. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-063"
- URI="not-wf/sa/063.xml" SECTIONS="2.8 [29]">
- Conditional sections may only appear in the external
- DTD subset. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-064"
- URI="not-wf/sa/064.xml" SECTIONS="3.3 [53]">
- Space is required between attribute type and default values
- in &lt;!ATTLIST...&gt; declarations. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-065"
- URI="not-wf/sa/065.xml" SECTIONS="3.3 [53]">
- Space is required between attribute name and type
- in &lt;!ATTLIST...&gt; declarations. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-066"
- URI="not-wf/sa/066.xml" SECTIONS="3.3 [52]">
- Required whitespace is missing. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-067"
- URI="not-wf/sa/067.xml" SECTIONS="3.3 [53]">
- Space is required between attribute type and default values
- in &lt;!ATTLIST...&gt; declarations. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-068"
- URI="not-wf/sa/068.xml" SECTIONS="3.3.1 [58]">
- Space is required between NOTATION keyword and list of
- enumerated choices in &lt;!ATTLIST...&gt; declarations. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-069"
- URI="not-wf/sa/069.xml" SECTIONS="4.2.2 [76]">
- Space is required before an NDATA entity annotation.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-070"
- URI="not-wf/sa/070.xml" SECTIONS="2.5 [16]">
- XML comments may not contain "--" </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-071"
- URI="not-wf/sa/071.xml" SECTIONS="4.1 [68]">
- ENTITY can't reference itself directly or indirectly.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-072"
- URI="not-wf/sa/072.xml" SECTIONS="4.1 [68]">
- Undefined ENTITY foo. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-073"
- URI="not-wf/sa/073.xml" SECTIONS="4.1 [68]">
- Undefined ENTITY f. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-074"
- URI="not-wf/sa/074.xml" SECTIONS="4.3.2">
- Internal general parsed entities are only well formed if
- they match the "content" production. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-075"
- URI="not-wf/sa/075.xml" SECTIONS="4.1 [68]">
- ENTITY can't reference itself directly or indirectly. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-076"
- URI="not-wf/sa/076.xml" SECTIONS="4.1 [68]">
- Undefined ENTITY foo. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-077"
- URI="not-wf/sa/077.xml" SECTIONS="41. [68]">
- Undefined ENTITY bar. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-078"
- URI="not-wf/sa/078.xml" SECTIONS="4.1 [68]">
- Undefined ENTITY foo. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-079"
- URI="not-wf/sa/079.xml" SECTIONS="4.1 [68]">
- ENTITY can't reference itself directly or indirectly. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-080"
- URI="not-wf/sa/080.xml" SECTIONS="4.1 [68]">
- ENTITY can't reference itself directly or indirectly. </TEST>
-<TEST TYPE="not-wf" ENTITIES="general" ID="not-wf-sa-081"
- URI="not-wf/sa/081.xml" SECTIONS="3.1">
- This tests the <EM>No External Entity References</EM> WFC,
- since the entity is referred to within an attribute. </TEST>
-<TEST TYPE="not-wf" ENTITIES="general" ID="not-wf-sa-082"
- URI="not-wf/sa/082.xml" SECTIONS="3.1">
- This tests the <EM>No External Entity References</EM> WFC,
- since the entity is referred to within an attribute. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-083"
- URI="not-wf/sa/083.xml" SECTIONS="4.2.2 [76]">
- Undefined NOTATION n. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-084"
- URI="not-wf/sa/084.xml" SECTIONS="4.1">
- Tests the <EM>Parsed Entity</EM> WFC by referring to an
- unparsed entity. (This precedes the error of not declaring
- that entity's notation, which may be detected any time before
- the DTD parsing is completed.) </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-085"
- URI="not-wf/sa/085.xml" SECTIONS="2.3 [13]">
- Public IDs may not contain "[". </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-086"
- URI="not-wf/sa/086.xml" SECTIONS="2.3 [13]">
- Public IDs may not contain "[". </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-087"
- URI="not-wf/sa/087.xml" SECTIONS="2.3 [13]">
- Public IDs may not contain "[". </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-088"
- URI="not-wf/sa/088.xml" SECTIONS="2.3 [10]">
- Attribute values are terminated by literal quote characters,
- and any entity expansion is done afterwards. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-089"
- URI="not-wf/sa/089.xml" SECTIONS="4.2 [74]">
- Parameter entities "are" always parsed; NDATA annotations
- are not permitted.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-090"
- URI="not-wf/sa/090.xml" SECTIONS="2.3 [10]">
- Attributes may not contain a literal "&lt;" character;
- this one has one because of reference expansion. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-091"
- URI="not-wf/sa/091.xml" SECTIONS="4.2 [74]">
- Parameter entities "are" always parsed; NDATA annotations
- are not permitted.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-092"
- URI="not-wf/sa/092.xml" SECTIONS="4.5">
- The replacement text of this entity has an illegal reference,
- because the character reference is expanded immediately. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-093"
- URI="not-wf/sa/093.xml" SECTIONS="4.1 [66]">
- Hexadecimal character references may not use the uppercase 'X'.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-094"
- URI="not-wf/sa/094.xml" SECTIONS="2.8 [24]">
- Prolog VERSION must be lowercase. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-095"
- URI="not-wf/sa/095.xml" SECTIONS="2.8 [23]">
- VersionInfo must come before EncodingDecl. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-096"
- URI="not-wf/sa/096.xml" SECTIONS="2.9 [32]">
- Space is required before the standalone declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-097"
- URI="not-wf/sa/097.xml" SECTIONS="2.8 [24]">
- Both quotes surrounding VersionNum must be the same. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-098"
- URI="not-wf/sa/098.xml" SECTIONS="2.8 [23]">
- Only one "version=..." string may appear in an XML declaration.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-099"
- URI="not-wf/sa/099.xml" SECTIONS="2.8 [23]">
- Only three pseudo-attributes are in the XML declaration,
- and "valid=..." is not one of them. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-100"
- URI="not-wf/sa/100.xml" SECTIONS="2.9 [32]">
- Only "yes" and "no" are permitted as values of "standalone". </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-101"
- URI="not-wf/sa/101.xml" SECTIONS="4.3.3 [81]">
- Space is not permitted in an encoding name. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-102"
- URI="not-wf/sa/102.xml" SECTIONS="2.8 [26]">
- Provides an illegal XML version number; spaces are illegal.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-103"
- URI="not-wf/sa/103.xml" SECTIONS="4.3.2">
- End-tag required for element foo. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-104"
- URI="not-wf/sa/104.xml" SECTIONS="4.3.2">
- Internal general parsed entities are only well formed if
- they match the "content" production. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-105"
- URI="not-wf/sa/105.xml" SECTIONS="2.7 ">
- Invalid placement of CDATA section. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-106"
- URI="not-wf/sa/106.xml" SECTIONS="4.2">
- Invalid placement of entity declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-107"
- URI="not-wf/sa/107.xml" SECTIONS="2.8 [28]">
- Invalid document type declaration. CDATA alone is invalid.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-108"
- URI="not-wf/sa/108.xml" SECTIONS="2.7 [19]">
- No space in '&lt;![CDATA['.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-109"
- URI="not-wf/sa/109.xml" SECTIONS="4.2 [70]">
- Tags invalid within EntityDecl. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-110"
- URI="not-wf/sa/110.xml" SECTIONS="4.1 [68]">
- Entity reference must be in content of element. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-111"
- URI="not-wf/sa/111.xml" SECTIONS="3.1 [43]">
- Entiry reference must be in content of element not Start-tag. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-112"
- URI="not-wf/sa/112.xml" SECTIONS="2.7 [19]">
- CDATA sections start '&lt;![CDATA[', not '&lt;!cdata['.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-113"
- URI="not-wf/sa/113.xml" SECTIONS="2.3 [9]">
- Parameter entity values must use valid reference syntax;
- this reference is malformed.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-114"
- URI="not-wf/sa/114.xml" SECTIONS="2.3 [9]">
- General entity values must use valid reference syntax;
- this reference is malformed.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-115"
- URI="not-wf/sa/115.xml" SECTIONS="4.5">
- The replacement text of this entity is an illegal character
- reference, which must be rejected when it is parsed in the
- context of an attribute value.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-116"
- URI="not-wf/sa/116.xml" SECTIONS="4.3.2">
- Internal general parsed entities are only well formed if
- they match the "content" production. This is a partial
- character reference, not a full one. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-117"
- URI="not-wf/sa/117.xml" SECTIONS="4.3.2">
- Internal general parsed entities are only well formed if
- they match the "content" production. This is a partial
- character reference, not a full one. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-118"
- URI="not-wf/sa/118.xml" SECTIONS="4.1 [68]">
- Entity reference expansion is not recursive.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-119"
- URI="not-wf/sa/119.xml" SECTIONS="4.3.2">
- Internal general parsed entities are only well formed if
- they match the "content" production. This is a partial
- character reference, not a full one. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-120"
- URI="not-wf/sa/120.xml" SECTIONS="4.5">
- Character references are expanded in the replacement text of
- an internal entity, which is then parsed as usual. Accordingly,
- &amp; must be doubly quoted - encoded either as <EM>&amp;amp;</EM>
- or as <EM>&amp;#38;#38;</EM>. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-121"
- URI="not-wf/sa/121.xml" SECTIONS="4.1 [68]">
- A name of an ENTITY was started with an invalid character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-122"
- URI="not-wf/sa/122.xml" SECTIONS="3.2.1 [47]">
- Invalid syntax mixed connectors are used. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-123"
- URI="not-wf/sa/123.xml" SECTIONS="3.2.1 [48]">
- Invalid syntax mismatched parenthesis. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-124"
- URI="not-wf/sa/124.xml" SECTIONS="3.2.2 [51]">
- Invalid format of Mixed-content declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-125"
- URI="not-wf/sa/125.xml" SECTIONS="3.2.2 [51]">
- Invalid syntax extra set of parenthesis not necessary. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-126"
- URI="not-wf/sa/126.xml" SECTIONS="3.2.2 [51]">
- Invalid syntax Mixed-content must be defined as zero or more. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-127"
- URI="not-wf/sa/127.xml" SECTIONS="3.2.2 [51]">
- Invalid syntax Mixed-content must be defined as zero or more. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-128"
- URI="not-wf/sa/128.xml" SECTIONS="2.7 [18]">
- Invalid CDATA syntax. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-129"
- URI="not-wf/sa/129.xml" SECTIONS="3.2 [45]">
- Invalid syntax for Element Type Declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-130"
- URI="not-wf/sa/130.xml" SECTIONS="3.2 [45]">
- Invalid syntax for Element Type Declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-131"
- URI="not-wf/sa/131.xml" SECTIONS="3.2 [45]">
- Invalid syntax for Element Type Declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-132"
- URI="not-wf/sa/132.xml" SECTIONS="3.2.1 [50]">
- Invalid syntax mixed connectors used. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-133"
- URI="not-wf/sa/133.xml" SECTIONS="3.2.1">
- Illegal whitespace before optional character causes syntax error. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-134"
- URI="not-wf/sa/134.xml" SECTIONS="3.2.1">
- Illegal whitespace before optional character causes syntax error. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-135"
- URI="not-wf/sa/135.xml" SECTIONS="3.2.1 [47]">
- Invalid character used as connector. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-136"
- URI="not-wf/sa/136.xml" SECTIONS="3.2 [45]">
- Tag omission is invalid in XML. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-137"
- URI="not-wf/sa/137.xml" SECTIONS="3.2 [45]">
- Space is required before a content model. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-138"
- URI="not-wf/sa/138.xml" SECTIONS="3.2.1 [48]">
- Invalid syntax for content particle. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-139"
- URI="not-wf/sa/139.xml" SECTIONS="3.2.1 [46]">
- The element-content model should not be empty. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-140"
- URI="not-wf/sa/140.xml" SECTIONS="2.3 [4]">
- Character '&amp;#x309a;' is a CombiningChar, not a
- Letter, and so may not begin a name.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-141"
- URI="not-wf/sa/141.xml" SECTIONS="2.3 [5]">
- Character #x0E5C is not legal in XML names. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-142"
- URI="not-wf/sa/142.xml" SECTIONS="2.2 [2]">
- Character #x0000 is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-143"
- URI="not-wf/sa/143.xml" SECTIONS="2.2 [2]">
- Character #x001F is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-144"
- URI="not-wf/sa/144.xml" SECTIONS="2.2 [2]">
- Character #xFFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-145"
- URI="not-wf/sa/145.xml" SECTIONS="2.2 [2]">
- Character #xD800 is not legal anywhere in an XML document. (If it
- appeared in a UTF-16 surrogate pair, it'd represent half of a UCS-4
- character and so wouldn't really be in the document.) </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-146"
- URI="not-wf/sa/146.xml" SECTIONS="2.2 [2]">
- Character references must also refer to legal XML characters;
- #x00110000 is one more than the largest legal character.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-147"
- URI="not-wf/sa/147.xml" SECTIONS="2.8 [22]">
- XML Declaration may not be preceded by whitespace.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-148"
- URI="not-wf/sa/148.xml" SECTIONS="2.8 [22]">
- XML Declaration may not be preceded by comments or whitespace.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-149"
- URI="not-wf/sa/149.xml" SECTIONS="2.8 [28]">
- XML Declaration may not be within a DTD.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-150"
- URI="not-wf/sa/150.xml" SECTIONS="3.1 [43]">
- XML declarations may not be within element content. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-151"
- URI="not-wf/sa/151.xml" SECTIONS="2.8 [27]">
- XML declarations may not follow document content.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-152"
- URI="not-wf/sa/152.xml" SECTIONS="2.8 [22]">
- XML declarations must include the "version=..." string.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-153"
- URI="not-wf/sa/153.xml" SECTIONS="4.3.2">
- Text declarations may not begin internal parsed entities;
- they may only appear at the beginning of external parsed
- (parameter or general) entities. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-154"
- URI="not-wf/sa/154.xml" SECTIONS="2.8 2.6 [23, 17]">
- '&lt;?XML ...?&gt;' is neither an XML declaration
- nor a legal processing instruction target name. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-155"
- URI="not-wf/sa/155.xml" SECTIONS="2.8 2.6 [23, 17]">
- '&lt;?xmL ...?&gt;' is neither an XML declaration
- nor a legal processing instruction target name. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-156"
- URI="not-wf/sa/156.xml" SECTIONS="2.8 2.6 [23, 17]">
- '&lt;?xMl ...?&gt;' is neither an XML declaration
- nor a legal processing instruction target name. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-157"
- URI="not-wf/sa/157.xml" SECTIONS="2.6 [17]">
- '&lt;?xmL ...?&gt;' is not a legal processing instruction
- target name. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-158"
- URI="not-wf/sa/158.xml" SECTIONS="3.3 [52]">
- SGML-ism: "#NOTATION gif" can't have attributes. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-159"
- URI="not-wf/sa/159.xml" SECTIONS="2.3 [9]">
- Uses '&amp;' unquoted in an entity declaration,
- which is illegal syntax for an entity reference.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-160"
- URI="not-wf/sa/160.xml" SECTIONS="2.8">
- Violates the <EM>PEs in Internal Subset</EM> WFC
- by using a PE reference within a declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-161"
- URI="not-wf/sa/161.xml" SECTIONS="2.8">
- Violates the <EM>PEs in Internal Subset</EM> WFC
- by using a PE reference within a declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-162"
- URI="not-wf/sa/162.xml" SECTIONS="2.8">
- Violates the <EM>PEs in Internal Subset</EM> WFC
- by using a PE reference within a declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-163"
- URI="not-wf/sa/163.xml" SECTIONS="4.1 [69]">
- Invalid placement of Parameter entity reference. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-164"
- URI="not-wf/sa/164.xml" SECTIONS="4.1 [69]">
- Invalid placement of Parameter entity reference. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-165"
- URI="not-wf/sa/165.xml" SECTIONS="4.2 [72]">
- Parameter entity declarations must have a space before
- the '%'. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-166"
- URI="not-wf/sa/166.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-167"
- URI="not-wf/sa/167.xml" SECTIONS="2.2 [2]">
- Character FFFE is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-168"
- URI="not-wf/sa/168.xml" SECTIONS="2.2 [2]">
- An unpaired surrogate (D800) is not legal anywhere
- in an XML document.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-169"
- URI="not-wf/sa/169.xml" SECTIONS="2.2 [2]">
- An unpaired surrogate (DC00) is not legal anywhere
- in an XML document.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-170"
- URI="not-wf/sa/170.xml" SECTIONS="2.2 [2]">
- Four byte UTF-8 encodings can encode UCS-4 characters
- which are beyond the range of legal XML characters
- (and can't be expressed in Unicode surrogate pairs).
- This document holds such a character. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-171"
- URI="not-wf/sa/171.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-172"
- URI="not-wf/sa/172.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-173"
- URI="not-wf/sa/173.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-174"
- URI="not-wf/sa/174.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-175"
- URI="not-wf/sa/175.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-176"
- URI="not-wf/sa/176.xml" SECTIONS="3 [39]">
- Start tags must have matching end tags.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-177"
- URI="not-wf/sa/177.xml" SECTIONS="2.2 [2]">
- Character FFFF is not legal anywhere in an XML document. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-178"
- URI="not-wf/sa/178.xml" SECTIONS="3.1 [41]">
- Invalid syntax matching double quote is missing. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-179"
- URI="not-wf/sa/179.xml" SECTIONS="4.1 [66]">
- Invalid syntax matching double quote is missing. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-180"
- URI="not-wf/sa/180.xml" SECTIONS="4.1">
- The <EM>Entity Declared</EM> WFC requires entities to be declared
- before they are used in an attribute list declaration. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-181"
- URI="not-wf/sa/181.xml" SECTIONS="4.3.2">
- Internal parsed entities must match the <EM>content</EM>
- production to be well formed. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-182"
- URI="not-wf/sa/182.xml" SECTIONS="4.3.2">
- Internal parsed entities must match the <EM>content</EM>
- production to be well formed. </TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-183"
- URI="not-wf/sa/183.xml" SECTIONS="3.2.2 [51]">
- Mixed content declarations may not include content particles.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-184"
- URI="not-wf/sa/184.xml" SECTIONS="3.2.2 [51]">
- In mixed content models, element names must not be
- parenthesized. </TEST>
-<TEST TYPE="not-wf" ENTITIES="parameter" ID="not-wf-sa-185"
- URI="not-wf/sa/185.xml" SECTIONS="4.1">
- Tests the <EM>Entity Declared</EM> WFC.
- <EM>Note:</EM> a nonvalidating parser is permitted not to report
- this WFC violation, since it would need to read an external
- parameter entity to distinguish it from a violation of
- the <EM>Standalone Declaration</EM> VC.</TEST>
-<TEST TYPE="not-wf" ENTITIES="none" ID="not-wf-sa-186"
- URI="not-wf/sa/186.xml" SECTIONS="3.1 [44]">
- Whitespace is required between attribute/value pairs. </TEST>
-
-<!-- Start: not-wf/not-sa -->
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-001"
- URI="not-wf/not-sa/001.xml" SECTIONS="3.4 [62]">
- Conditional sections must be properly terminated ("]&gt;" used
- instead of "]]&gt;"). </TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-002"
- URI="not-wf/not-sa/002.xml" SECTIONS="2.6 [17]">
- Processing instruction target names may not be "XML"
- in any combination of cases. </TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-003"
- URI="not-wf/not-sa/003.xml" SECTIONS="3.4 [62]">
- Conditional sections must be properly terminated ("]]&gt;" omitted). </TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-004"
- URI="not-wf/not-sa/004.xml" SECTIONS="3.4 [62]">
- Conditional sections must be properly terminated ("]]&gt;" omitted). </TEST>
-<TEST TYPE="error" ENTITIES="both" ID="not-wf-not-sa-005"
- URI="not-wf/not-sa/005.xml" SECTIONS="4.1">
- Tests the <EM>Entity Declared</EM> VC by referring to an
- undefined parameter entity within an external entity.</TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-006"
- URI="not-wf/not-sa/006.xml" SECTIONS="3.4 [62]">
- Conditional sections need a '[' after the INCLUDE or IGNORE. </TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-007"
- URI="not-wf/not-sa/007.xml" SECTIONS="4.3.2 [79]">
- A &lt;!DOCTYPE ...&gt; declaration may not begin any external
- entity; it's only found once, in the document entity.</TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-008"
- URI="not-wf/not-sa/008.xml" SECTIONS="4.1 [69]">
- In DTDs, the '%' character must be part of a parameter
- entity reference.</TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-not-sa-009"
- URI="not-wf/not-sa/009.xml" SECTIONS="2.8">
- This test violates WFC:PE Between Declarations in Production 28a.
- The last character of a markup declaration is not contained in the same
- parameter-entity text replacement.</TEST>
-<!-- Start: not-wf/ext-sa -->
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-ext-sa-001"
- URI="not-wf/ext-sa/001.xml" SECTIONS="4.1">
- Tests the <EM>No Recursion</EM> WFC by having an external general
- entity be self-recursive.</TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-ext-sa-002"
- URI="not-wf/ext-sa/002.xml" SECTIONS="4.3.1 4.3.2 [77, 78]">
- External entities have "text declarations", which do
- not permit the "standalone=..." attribute that's allowed
- in XML declarations.</TEST>
-<TEST TYPE="not-wf" ENTITIES="both" ID="not-wf-ext-sa-003"
- URI="not-wf/ext-sa/003.xml" SECTIONS="2.6 [17]">
- Only one text declaration is permitted; a second one
- looks like an illegal processing instruction (target names
- of "xml" in any case are not allowed). </TEST>
-
-
-<!-- Start: invalid/ -->
-
-<TEST TYPE="invalid" ENTITIES="both" ID="invalid--002"
- URI="invalid/002.xml" SECTIONS="3.2.1">
- Tests the "Proper Group/PE Nesting" validity constraint by
- fragmenting a content model between two parameter entities.</TEST>
-<TEST TYPE="invalid" ENTITIES="both" ID="invalid--005"
- URI="invalid/005.xml" SECTIONS="2.8">
- Tests the "Proper Declaration/PE Nesting" validity constraint by
- fragmenting an element declaration between two parameter entities.</TEST>
-<TEST TYPE="invalid" ENTITIES="both" ID="invalid--006"
- URI="invalid/006.xml" SECTIONS="2.8">
- Tests the "Proper Declaration/PE Nesting" validity constraint by
- fragmenting an element declaration between two parameter entities.</TEST>
-<TEST TYPE="invalid" ENTITIES="both" ID="invalid-not-sa-022"
- URI="invalid/not-sa/022.xml" SECTIONS="3.4 [62]"
- OUTPUT="invalid/not-sa/out/022.xml">
- Test the "Proper Conditional Section/ PE Nesting" validity constraint. </TEST>
-
-<!-- Start: valid/sa -->
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-001"
- URI="valid/sa/001.xml" SECTIONS="3.2.2 [51]"
- OUTPUT="valid/sa/out/001.xml">
- Test demonstrates an Element Type Declaration with Mixed Content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-002"
- URI="valid/sa/002.xml" SECTIONS="3.1 [40]"
- OUTPUT="valid/sa/out/002.xml">
- Test demonstrates that whitespace is permitted after the tag name in a Start-tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-003"
- URI="valid/sa/003.xml" SECTIONS="3.1 [42]"
- OUTPUT="valid/sa/out/003.xml">
- Test demonstrates that whitespace is permitted after the tag name in an End-tag.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-004"
- URI="valid/sa/004.xml" SECTIONS="3.1 [41]"
- OUTPUT="valid/sa/out/004.xml">
- Test demonstrates a valid attribute specification within a Start-tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-005"
- URI="valid/sa/005.xml" SECTIONS="3.1 [40]"
- OUTPUT="valid/sa/out/005.xml">
- Test demonstrates a valid attribute specification within a Start-tag that
-contains whitespace on both sides of the equal sign. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-006"
- URI="valid/sa/006.xml" SECTIONS="3.1 [41]"
- OUTPUT="valid/sa/out/006.xml">
- Test demonstrates that the AttValue within a Start-tag can use a single quote as a delimter. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-007"
- URI="valid/sa/007.xml" SECTIONS="3.1 4.6 [43]"
- OUTPUT="valid/sa/out/007.xml">
- Test demonstrates numeric character references can be used for element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-008"
- URI="valid/sa/008.xml" SECTIONS="2.4 3.1 [43]"
- OUTPUT="valid/sa/out/008.xml">
- Test demonstrates character references can be used for element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-009"
- URI="valid/sa/009.xml" SECTIONS="2.3 3.1 [43]"
- OUTPUT="valid/sa/out/009.xml">
- Test demonstrates that PubidChar can be used for element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-010"
- URI="valid/sa/010.xml" SECTIONS="3.1 [40]"
- OUTPUT="valid/sa/out/010.xml">
- Test demonstrates that whitespace is valid after the Attribute in a Start-tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-011"
- URI="valid/sa/011.xml" SECTIONS="3.1 [40]"
- OUTPUT="valid/sa/out/011.xml">
- Test demonstrates mutliple Attibutes within the Start-tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-012"
- URI="valid/sa/012.xml" SECTIONS="2.3 [4]"
- OUTPUT="valid/sa/out/012.xml" NAMESPACE="no">
- Uses a legal XML 1.0 name consisting of a single colon
- character (disallowed by the latest XML Namespaces draft).</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-013"
- URI="valid/sa/013.xml" SECTIONS="2.3 3.1 [13] [40]"
- OUTPUT="valid/sa/out/013.xml">
- Test demonstrates that the Attribute in a Start-tag can consist of numerals along with special characters. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-014"
- URI="valid/sa/014.xml" SECTIONS="2.3 3.1 [13] [40]"
- OUTPUT="valid/sa/out/014.xml">
- Test demonstrates that all lower case letters are valid for the Attribute in a Start-tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-015"
- URI="valid/sa/015.xml" SECTIONS="2.3 3.1 [13] [40]"
- OUTPUT="valid/sa/out/015.xml">
- Test demonstrates that all upper case letters are valid for the Attribute in a Start-tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-016"
- URI="valid/sa/016.xml" SECTIONS="2.6 3.1 [16] [43]"
- OUTPUT="valid/sa/out/016.xml">
- Test demonstrates that Processing Instructions are valid element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-017"
- URI="valid/sa/017.xml" SECTIONS="2.6 3.1 [16] [43]"
- OUTPUT="valid/sa/out/017.xml">
- Test demonstrates that Processing Instructions are valid element content and there can be more than one. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-018"
- URI="valid/sa/018.xml" SECTIONS="2.7 3.1 [18] [43]"
- OUTPUT="valid/sa/out/018.xml">
- Test demonstrates that CDATA sections are valid element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-019"
- URI="valid/sa/019.xml" SECTIONS="2.7 3.1 [18] [43]"
- OUTPUT="valid/sa/out/019.xml">
- Test demonstrates that CDATA sections are valid element content and that
-ampersands may occur in their literal form. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-020"
- URI="valid/sa/020.xml" SECTIONS="2.7 3.1 [18] [43]"
- OUTPUT="valid/sa/out/020.xml">
- Test demonstractes that CDATA sections are valid element content and that
-everyting between the CDStart and CDEnd is recognized as character data not markup. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-021"
- URI="valid/sa/021.xml" SECTIONS="2.5 3.1 [15] [43]"
- OUTPUT="valid/sa/out/021.xml">
- Test demonstrates that comments are valid element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-022"
- URI="valid/sa/022.xml" SECTIONS="2.5 3.1 [15] [43]"
- OUTPUT="valid/sa/out/022.xml">
- Test demonstrates that comments are valid element content and that all characters before the double-hypen right angle combination are considered part of thecomment. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-023"
- URI="valid/sa/023.xml" SECTIONS="3.1 [43]"
- OUTPUT="valid/sa/out/023.xml">
- Test demonstrates that Entity References are valid element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-024"
- URI="valid/sa/024.xml" SECTIONS="3.1 4.1 [43] [66]"
- OUTPUT="valid/sa/out/024.xml">
- Test demonstrates that Entity References are valid element content and also demonstrates a valid Entity Declaration. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-025"
- URI="valid/sa/025.xml" SECTIONS="3.2 [46]"
- OUTPUT="valid/sa/out/025.xml">
- Test demonstrates an Element Type Declaration and that the contentspec can be of mixed content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-026"
- URI="valid/sa/026.xml" SECTIONS="3.2 [46]"
- OUTPUT="valid/sa/out/026.xml">
- Test demonstrates an Element Type Declaration and that EMPTY is a valid contentspec. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-027"
- URI="valid/sa/027.xml" SECTIONS="3.2 [46]"
- OUTPUT="valid/sa/out/027.xml">
- Test demonstrates an Element Type Declaration and that ANY is a valid contenspec. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-028"
- URI="valid/sa/028.xml" SECTIONS="2.8 [24]"
- OUTPUT="valid/sa/out/028.xml">
- Test demonstrates a valid prolog that uses double quotes as delimeters around the VersionNum. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-029"
- URI="valid/sa/029.xml" SECTIONS="2.8 [24]"
- OUTPUT="valid/sa/out/029.xml">
- Test demonstrates a valid prolog that uses single quotes as delimters around the VersionNum. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-030"
- URI="valid/sa/030.xml" SECTIONS="2.8 [25]"
- OUTPUT="valid/sa/out/030.xml">
- Test demonstrates a valid prolog that contains whitespace on both sides of the equal sign in the VersionInfo. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-031"
- URI="valid/sa/031.xml" SECTIONS="4.3.3 [80]"
- OUTPUT="valid/sa/out/031.xml">
- Test demonstrates a valid EncodingDecl within the prolog. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-032"
- URI="valid/sa/032.xml" SECTIONS="2.9 [32]"
- OUTPUT="valid/sa/out/032.xml">
- Test demonstrates a valid SDDecl within the prolog. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-033"
- URI="valid/sa/033.xml" SECTIONS="2.8 [23]"
- OUTPUT="valid/sa/out/033.xml">
- Test demonstrates that both a EncodingDecl and SDDecl are valid within the prolog. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-034"
- URI="valid/sa/034.xml" SECTIONS="3.1 [44]"
- OUTPUT="valid/sa/out/034.xml">
- Test demonstrates the correct syntax for an Empty element tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-035"
- URI="valid/sa/035.xml" SECTIONS="3.1 [44]"
- OUTPUT="valid/sa/out/035.xml">
- Test demonstrates that whitespace is permissible after the name in an Empty element tag. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-036"
- URI="valid/sa/036.xml" SECTIONS="2.6 [16]"
- OUTPUT="valid/sa/out/036.xml">
- Test demonstrates a valid processing instruction. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-037"
- URI="valid/sa/037.xml" SECTIONS="2.6 [15]"
- OUTPUT="valid/sa/out/037.xml">
- Test demonstrates a valid comment and that it may appear anywhere in the document including at the end. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-038"
- URI="valid/sa/038.xml" SECTIONS="2.6 [15]"
- OUTPUT="valid/sa/out/038.xml">
- Test demonstrates a valid comment and that it may appear anywhere in the document including the beginning. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-039"
- URI="valid/sa/039.xml" SECTIONS="2.6 [16]"
- OUTPUT="valid/sa/out/039.xml">
- Test demonstrates a valid processing instruction and that it may appear at the beginning of the document. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-040"
- URI="valid/sa/040.xml" SECTIONS="3.3 3.3.1 [52] [54]"
- OUTPUT="valid/sa/out/040.xml">
- Test demonstrates an Attribute List declaration that uses a StringType as the AttType. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-041"
- URI="valid/sa/041.xml" SECTIONS="3.3.1 4.1 [54] [66]"
- OUTPUT="valid/sa/out/041.xml">
- Test demonstrates an Attribute List declaration that uses a StringType as the AttType and also expands the CDATA attribute with a character reference. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-042"
- URI="valid/sa/042.xml" SECTIONS="3.3.1 4.1 [54] [66]"
- OUTPUT="valid/sa/out/042.xml">
- Test demonstrates an Attribute List declaration that uses a StringType as the AttType and also expands the CDATA attribute with a character reference. The test also shows that the leading zeros in the character reference are ignored. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-043"
- URI="valid/sa/043.xml" SECTIONS="3.3"
- OUTPUT="valid/sa/out/043.xml">
- An element's attributes may be declared before its content
- model; and attribute values may contain newlines. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-044"
- URI="valid/sa/044.xml" SECTIONS="3.1 [44]"
- OUTPUT="valid/sa/out/044.xml">
- Test demonstrates that the empty-element tag must be use for an elements that are declared EMPTY. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-045"
- URI="valid/sa/045.xml" SECTIONS="3.3 [52]"
- OUTPUT="valid/sa/out/045.xml">
- Tests whether more than one definition can be provided for the same attribute of a given element type with the first declaration being binding. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-046"
- URI="valid/sa/046.xml" SECTIONS="3.3 [52]"
- OUTPUT="valid/sa/out/046.xml">
- Test demonstrates that when more than one AttlistDecl is provided for a given element type, the contents of all those provided are merged. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-047"
- URI="valid/sa/047.xml" SECTIONS="3.1 [43]"
- OUTPUT="valid/sa/out/047.xml">
- Test demonstrates that extra whitespace is normalized into single space character. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-048"
- URI="valid/sa/048.xml" SECTIONS="2.4 3.1 [14] [43]"
- OUTPUT="valid/sa/out/048.xml">
- Test demonstrates that character data is valid element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-049"
- URI="valid/sa/049.xml" SECTIONS="2.2 [2]"
- OUTPUT="valid/sa/out/049.xml">
- Test demonstrates that characters outside of normal ascii range can be used as element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-050"
- URI="valid/sa/050.xml" SECTIONS="2.2 [2]"
- OUTPUT="valid/sa/out/050.xml">
- Test demonstrates that characters outside of normal ascii range can be used as element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-051"
- URI="valid/sa/051.xml" SECTIONS="2.2 [2]"
- OUTPUT="valid/sa/out/051.xml">
- The document is encoded in UTF-16 and uses some name
- characters well outside of the normal ASCII range.
- </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-052"
- URI="valid/sa/052.xml" SECTIONS="2.2 [2]"
- OUTPUT="valid/sa/out/052.xml">
- The document is encoded in UTF-8 and the text inside the
- root element uses two non-ASCII characters, encoded in UTF-8
- and each of which expands to a Unicode surrogate pair.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-053"
- URI="valid/sa/053.xml" SECTIONS="4.4.2"
- OUTPUT="valid/sa/out/053.xml">
- Tests inclusion of a well-formed internal entity, which
- holds an element required by the content model.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-054"
- URI="valid/sa/054.xml" SECTIONS="3.1 [40] [42]"
- OUTPUT="valid/sa/out/054.xml">
- Test demonstrates that extra whitespace within Start-tags and End-tags are nomalized into single spaces. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-055"
- URI="valid/sa/055.xml" SECTIONS="2.6 2.10 [16]"
- OUTPUT="valid/sa/out/055.xml">
- Test demonstrates that extra whitespace within a processing instruction willnormalized into s single space character. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-056"
- URI="valid/sa/056.xml" SECTIONS="3.3.1 4.1 [54] [66]"
- OUTPUT="valid/sa/out/056.xml">
- Test demonstrates an Attribute List declaration that uses a StringType as the AttType and also expands the CDATA attribute with a character reference. The test also shows that the leading zeros in the character reference are ignored. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-057"
- URI="valid/sa/057.xml" SECTIONS="3.2.1 [47]"
- OUTPUT="valid/sa/out/057.xml">
- Test demonstrates an element content model whose element can occur zero or more times. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-058"
- URI="valid/sa/058.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/058.xml">
- Test demonstrates that extra whitespace be normalized into a single space character in an attribute of type NMTOKENS. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-059"
- URI="valid/sa/059.xml" SECTIONS="3.2 3.3 [46] [53]"
- OUTPUT="valid/sa/out/059.xml">
- Test demonstrates an Element Type Declaration that uses the contentspec of EMPTY. The element cannot have any contents and must always appear as an empty element in the document. The test also shows an Attribute-list declaration with multiple AttDef's. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-060"
- URI="valid/sa/060.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/060.xml">
- Test demonstrates the use of decimal Character References within element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-061"
- URI="valid/sa/061.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/061.xml">
- Test demonstrates the use of decimal Character References within element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-062"
- URI="valid/sa/062.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/062.xml">
- Test demonstrates the use of hexadecimal Character References within element. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-063"
- URI="valid/sa/063.xml" SECTIONS="2.3 [5]"
- OUTPUT="valid/sa/out/063.xml">
- The document is encoded in UTF-8 and the name of the
- root element type uses non-ASCII characters. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-064"
- URI="valid/sa/064.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/064.xml">
- Tests in-line handling of two legal character references, which
- each expand to a Unicode surrogate pair.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-065"
- URI="valid/sa/065.xml" SECTIONS="4.5"
- OUTPUT="valid/sa/out/065.xml">
- Tests ability to define an internal entity which can't
- legally be expanded (contains an unquoted <B>&lt;</B>).</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-066"
- URI="valid/sa/066.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/066.xml">
- Expands a CDATA attribute with a character reference.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-067"
- URI="valid/sa/067.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/067.xml">
- Test demonstrates the use of decimal character references within element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-068"
- URI="valid/sa/068.xml" SECTIONS="2.11, 4.5"
- OUTPUT="valid/sa/out/068.xml">
- Tests definition of an internal entity holding a carriage return character
- reference, which must not be normalized before reporting to the application. Line
- break normalization only occurs when parsing external parsed entities.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-069"
- URI="valid/sa/069.xml" SECTIONS="4.7"
- OUTPUT="valid/sa/out/069.xml">
- Verifies that an XML parser will parse a NOTATION
- declaration; the output phase of this test ensures that
- it's reported to the application. </TEST>
-<TEST TYPE="valid" ENTITIES="parameter" ID="valid-sa-070"
- URI="valid/sa/070.xml" SECTIONS="4.4.8"
- OUTPUT="valid/sa/out/070.xml">
- Verifies that internal parameter entities are correctly
- expanded within the internal subset.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-071"
- URI="valid/sa/071.xml" SECTIONS="3.3 3.3.1 [52] [56]"
- OUTPUT="valid/sa/out/071.xml">
- Test demonstrates that an AttlistDecl can use ID as the TokenizedType within the Attribute type. The test also shows that IMPLIED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-072"
- URI="valid/sa/072.xml" SECTIONS="3.3 3.3.1 [52] [56]"
- OUTPUT="valid/sa/out/072.xml">
- Test demonstrates that an AttlistDecl can use IDREF as the TokenizedType within the Attribute type. The test also shows that IMPLIED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-073"
- URI="valid/sa/073.xml" SECTIONS="3.3 3.3.1 [52] [56]"
- OUTPUT="valid/sa/out/073.xml">
- Test demonstrates that an AttlistDecl can use IDREFS as the TokenizedType within the Attribute type. The test also shows that IMPLIED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-074"
- URI="valid/sa/074.xml" SECTIONS="3.3 3.3.1 [52] [56]"
- OUTPUT="valid/sa/out/074.xml">
- Test demonstrates that an AttlistDecl can use ENTITY as the TokenizedType within the Attribute type. The test also shows that IMPLIED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-075"
- URI="valid/sa/075.xml" SECTIONS="3.3 3.3.1 [52] [56]"
- OUTPUT="valid/sa/out/075.xml">
- Test demonstrates that an AttlistDecl can use ENTITIES as the TokenizedType within the Attribute type. The test also shows that IMPLIED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-076"
- URI="valid/sa/076.xml" SECTIONS="3.3.1"
- OUTPUT="valid/sa/out/076.xml">
- Verifies that an XML parser will parse a NOTATION
- attribute; the output phase of this test ensures that
- both notations are reported to the application. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-077"
- URI="valid/sa/077.xml" SECTIONS="3.3 3.3.1 [52] [54]"
- OUTPUT="valid/sa/out/077.xml">
- Test demonstrates that an AttlistDecl can use an EnumeratedType within the Attribute type. The test also shows that IMPLIED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-078"
- URI="valid/sa/078.xml" SECTIONS="3.3 3.3.1 [52] [54]"
- OUTPUT="valid/sa/out/078.xml">
- Test demonstrates that an AttlistDecl can use an StringType of CDATA within the Attribute type. The test also shows that REQUIRED is a valid DefaultDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-079"
- URI="valid/sa/079.xml" SECTIONS="3.3 3.3.2 [52] [60]"
- OUTPUT="valid/sa/out/079.xml">
- Test demonstrates that an AttlistDecl can use an StringType of CDATA within the Attribute type. The test also shows that FIXED is a valid DefaultDecl and that a value can be given to the attribute in the Start-tag as well as the AttListDecl. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-080"
- URI="valid/sa/080.xml" SECTIONS="3.3 3.3.2 [52] [60]"
- OUTPUT="valid/sa/out/080.xml">
- Test demonstrates that an AttlistDecl can use an StringType of CDATA within the Attribute type. The test also shows that FIXED is a valid DefaultDecl and that an value can be given to the attribute. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-081"
- URI="valid/sa/081.xml" SECTIONS="3.2.1 [50]"
- OUTPUT="valid/sa/out/081.xml">
- Test demonstrates the use of the optional character following a name or list to govern the number of times an element or content particles in the list occur. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-082"
- URI="valid/sa/082.xml" SECTIONS="4.2 [72]"
- OUTPUT="valid/sa/out/082.xml">
- Tests that an external PE may be defined (but not referenced).</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-083"
- URI="valid/sa/083.xml" SECTIONS="4.2 [72]"
- OUTPUT="valid/sa/out/083.xml">
- Tests that an external PE may be defined (but not referenced).</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-084"
- URI="valid/sa/084.xml" SECTIONS="2.10"
- OUTPUT="valid/sa/out/084.xml">
- Test demonstrates that although whitespace can be used to set apart markup for greater readability it is not necessary. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-085"
- URI="valid/sa/085.xml" SECTIONS="4"
- OUTPUT="valid/sa/out/085.xml">
- Parameter and General entities use different namespaces,
- so there can be an entity of each type with a given name.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-086"
- URI="valid/sa/086.xml" SECTIONS="4.2"
- OUTPUT="valid/sa/out/086.xml">
- Tests whether entities may be declared more than once,
- with the first declaration being the binding one. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-087"
- URI="valid/sa/087.xml" SECTIONS="4.5"
- OUTPUT="valid/sa/out/087.xml">
- Tests whether character references in internal entities are
- expanded early enough, by relying on correct handling to
- make the entity be well formed.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-088"
- URI="valid/sa/088.xml" SECTIONS="4.5"
- OUTPUT="valid/sa/out/088.xml">
- Tests whether entity references in internal entities are
- expanded late enough, by relying on correct handling to
- make the expanded text be valid. (If it's expanded too
- early, the entity will parse as an element that's not
- valid in that context.)</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-089"
- URI="valid/sa/089.xml" SECTIONS="4.1 [66]"
- OUTPUT="valid/sa/out/089.xml">
- Tests entity expansion of three legal character references,
- which each expand to a Unicode surrogate pair.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-090"
- URI="valid/sa/090.xml" SECTIONS="3.3.1"
- OUTPUT="valid/sa/out/090.xml">
- Verifies that an XML parser will parse a NOTATION
- attribute; the output phase of this test ensures that
- the notation is reported to the application. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-091"
- URI="valid/sa/091.xml" SECTIONS="3.3.1"
- OUTPUT="valid/sa/out/091.xml">
- Verifies that an XML parser will parse an ENTITY
- attribute; the output phase of this test ensures that
- the notation is reported to the application, and for
- validating parsers it further tests that the entity
- is so reported.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-092"
- URI="valid/sa/092.xml" SECTIONS="2.3 2.10"
- OUTPUT="valid/sa/out/092.xml">
- Test demostrates that extra whitespace is normalized into a single space character. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-093"
- URI="valid/sa/093.xml" SECTIONS="2.10"
- OUTPUT="valid/sa/out/093.xml">
- Test demonstrates that extra whitespace is not intended for inclusion in the delivered version of the document. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-094"
- OUTPUT="valid/sa/out/094.xml"
- URI="valid/sa/094.xml" SECTIONS="2.8">
- Attribute defaults with a DTD have special parsing rules, different
- from other strings. That means that characters found there may look
- like an undefined parameter entity reference "within a markup
- declaration", but they aren't ... so they can't be violating
- the <EM>PEs in Internal Subset</EM> WFC.
- </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-095"
- URI="valid/sa/095.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/095.xml">
- Basically an output test, this requires extra whitespace
- to be normalized into a single space character in an
- attribute of type NMTOKENS.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-096"
- URI="valid/sa/096.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/096.xml">
- Test demonstrates that extra whitespace is normalized into a single space character in an attribute of type NMTOKENS. </TEST>
-<TEST TYPE="valid" ENTITIES="parameter" ID="valid-sa-097"
- URI="valid/sa/097.xml" SECTIONS="3.3"
- OUTPUT="valid/sa/out/097.xml">
- Basically an output test, this tests whether an externally
- defined attribute declaration (with a default) takes proper
- precedence over a subsequent internal declaration.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-098"
- URI="valid/sa/098.xml" SECTIONS="2.6 2.10 [16]"
- OUTPUT="valid/sa/out/098.xml">
- Test demonstrates that extra whitespace within a processing instruction is converted into a single space character.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-099"
- URI="valid/sa/099.xml" SECTIONS="4.3.3 [81]"
- OUTPUT="valid/sa/out/099.xml">
- Test demonstrates the name of the encoding can be composed of lowercase characters. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-100"
- URI="valid/sa/100.xml" SECTIONS="2.3 [12]"
- OUTPUT="valid/sa/out/100.xml">
- Makes sure that PUBLIC identifiers may have some strange
- characters. <EM>NOTE: The XML editors have said that the XML
- specification errata will specify that parameter entity expansion
- does not occur in PUBLIC identifiers, so that the '%' character
- will not flag a malformed parameter entity reference.</EM></TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-101"
- URI="valid/sa/101.xml" SECTIONS="4.5"
- OUTPUT="valid/sa/out/101.xml">
- This tests whether entity expansion is (incorrectly) done
- while processing entity declarations; if it is, the entity
- value literal will terminate prematurely.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-102"
- URI="valid/sa/102.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/102.xml">
- Test demonstrates that a CDATA attribute can pass a double quote as its value. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-103"
- URI="valid/sa/103.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/103.xml">
- Test demonstrates that an attribute can pass a less than sign as its value. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-104"
- URI="valid/sa/104.xml" SECTIONS="3.1 [40]"
- OUTPUT="valid/sa/out/104.xml">
- Test demonstrates that extra whitespace within an Attribute of a Start-tag is normalized to a single space character. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-105"
- URI="valid/sa/105.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/105.xml">
- Basically an output test, this requires a CDATA attribute
- with a tab character to be passed through as one space.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-106"
- URI="valid/sa/106.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/106.xml">
- Basically an output test, this requires a CDATA attribute
- with a newline character to be passed through as one space.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-107"
- URI="valid/sa/107.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/107.xml">
- Basically an output test, this requires a CDATA attribute
- with a return character to be passed through as one space.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-108"
- URI="valid/sa/108.xml" SECTIONS="2.11, 3.3.3"
- OUTPUT="valid/sa/out/108.xml">
- This tests normalization of end-of-line characters (CRLF)
- within entities to LF, primarily as an output test. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-109"
- URI="valid/sa/109.xml" SECTIONS="2.3 3.1 [10][40][41]"
- OUTPUT="valid/sa/out/109.xml">
- Test demonstrates that an attribute can have a null value. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-110"
- URI="valid/sa/110.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/110.xml">
- Basically an output test, this requires that a CDATA
- attribute with a CRLF be normalized to one space.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-111"
- URI="valid/sa/111.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/111.xml">
- Character references expanding to spaces doesn't affect
- treatment of attributes. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-112"
- URI="valid/sa/112.xml" SECTIONS="3.2.1 [48][49]"
- OUTPUT="valid/sa/out/112.xml">
- Test demonstrates shows the use of content particles within the element content. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-113"
- URI="valid/sa/113.xml" SECTIONS="3.3 [52][53]"
- OUTPUT="valid/sa/out/113.xml">
- Test demonstrates that it is not an error to have attributes declared for an element not itself declared.</TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-114"
- URI="valid/sa/114.xml" SECTIONS="2.7 [20]"
- OUTPUT="valid/sa/out/114.xml">
- Test demonstrates that all text within a valid CDATA section is considered text and not recognized as markup. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-115"
- URI="valid/sa/115.xml" SECTIONS="3.3.3"
- OUTPUT="valid/sa/out/115.xml">
- Test demonstrates that an entity reference is processed by recursively processing the replacement text of the entity. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-116"
- URI="valid/sa/116.xml" SECTIONS="2.11"
- OUTPUT="valid/sa/out/116.xml">
- Test demonstrates that a line break within CDATA will be normalized. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-117"
- URI="valid/sa/117.xml" SECTIONS="4.5"
- OUTPUT="valid/sa/out/117.xml">
- Test demonstrates that entity expansion is done while processing entity declarations. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-118"
- URI="valid/sa/118.xml" SECTIONS="4.5"
- OUTPUT="valid/sa/out/118.xml">
- Test demonstrates that entity expansion is done while processing entity declarations. </TEST>
-<TEST TYPE="valid" ENTITIES="none" ID="valid-sa-119"
- URI="valid/sa/119.xml" SECTIONS="2.5"
- OUTPUT="valid/sa/out/119.xml">
- Comments may contain any legal XML characters;
- only the string "--" is disallowed.</TEST>
-
-
-<!-- Start: valid/not-sa -->
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-001"
- URI="valid/not-sa/001.xml" SECTIONS="4.2.2 [75]"
- OUTPUT="valid/not-sa/out/001.xml">
- Test demonstrates the use of an ExternalID within a document type definition. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-002"
- URI="valid/not-sa/002.xml" SECTIONS="4.2.2 [75]"
- OUTPUT="valid/not-sa/out/002.xml">
- Test demonstrates the use of an ExternalID within a document type definition. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-003"
- URI="valid/not-sa/003.xml" SECTIONS="4.1 [69]"
- OUTPUT="valid/not-sa/out/003.xml">
- Test demonstrates the expansion of an external parameter entity that declares an attribute. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-004"
- URI="valid/not-sa/004.xml" SECTIONS="4.1 [69]"
- OUTPUT="valid/not-sa/out/004.xml">
- Expands an external parameter entity in two different ways,
- with one of them declaring an attribute.</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-005"
- URI="valid/not-sa/005.xml" SECTIONS="4.1 [69]"
- OUTPUT="valid/not-sa/out/005.xml">
- Test demonstrates the expansion of an external parameter entity that declares an attribute. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-006"
- URI="valid/not-sa/006.xml" SECTIONS="3.3 [52]"
- OUTPUT="valid/not-sa/out/006.xml">
- Test demonstrates that when more than one definition is provided for the same attribute of a given element type only the first declaration is binding. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-007"
- URI="valid/not-sa/007.xml" SECTIONS="3.3 [52]"
- OUTPUT="valid/not-sa/out/007.xml">
- Test demonstrates the use of an Attribute list declaration within an external entity. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-008"
- URI="valid/not-sa/008.xml" SECTIONS="4.2.2 [75]"
- OUTPUT="valid/not-sa/out/008.xml">
- Test demonstrates that an external identifier may include a public identifier. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-009"
- URI="valid/not-sa/009.xml" SECTIONS="4.2.2 [75]"
- OUTPUT="valid/not-sa/out/009.xml">
- Test demonstrates that an external identifier may include a public identifier. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-010"
- URI="valid/not-sa/010.xml" SECTIONS="3.3 [52]"
- OUTPUT="valid/not-sa/out/010.xml">
- Test demonstrates that when more that one definition is provided for the same attribute of a given element type only the first declaration is binding. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-011"
- URI="valid/not-sa/011.xml" SECTIONS="4.2 4.2.1 [72] [75]"
- OUTPUT="valid/not-sa/out/011.xml">
- Test demonstrates a parameter entity declaration whose parameter entity definition is an ExternalID. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-012"
- URI="valid/not-sa/012.xml" SECTIONS="4.3.1 [77]"
- OUTPUT="valid/not-sa/out/012.xml">
- Test demonstrates an enternal parsed entity that begins with a text declaration. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-013"
- URI="valid/not-sa/013.xml" SECTIONS="3.4 [62]"
- OUTPUT="valid/not-sa/out/013.xml">
- Test demonstrates the use of the conditional section INCLUDE that will include its contents as part of the DTD. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-014"
- URI="valid/not-sa/014.xml" SECTIONS="3.4 [62]"
- OUTPUT="valid/not-sa/out/014.xml">
- Test demonstrates the use of the conditional section INCLUDE that will include its contents as part of the DTD. The keyword is a parameter-entity reference. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-015"
- URI="valid/not-sa/015.xml" SECTIONS="3.4 [63]"
- OUTPUT="valid/not-sa/out/015.xml">
- Test demonstrates the use of the conditonal section IGNORE the will ignore its content from being part of the DTD. The keyword is a parameter-entity reference. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-016"
- URI="valid/not-sa/016.xml" SECTIONS="3.4 [62]"
- OUTPUT="valid/not-sa/out/016.xml">
- Test demonstrates the use of the conditional section INCLUDE that will include its contents as part of the DTD. The keyword is a parameter-entity reference.</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-017"
- URI="valid/not-sa/017.xml" SECTIONS="4.2 [72]"
- OUTPUT="valid/not-sa/out/017.xml">
- Test demonstrates a parameter entity declaration that contains an attribute list declaration. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-018"
- URI="valid/not-sa/018.xml" SECTIONS="4.2.2 [75]"
- OUTPUT="valid/not-sa/out/018.xml">
- Test demonstrates an EnternalID whose contents contain an parameter entity declaration and a attribute list definition. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-019"
- URI="valid/not-sa/019.xml" SECTIONS="4.4.8"
- OUTPUT="valid/not-sa/out/019.xml">
- Test demonstrates that a parameter entity will be expanded with spaces on either side. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-020"
- URI="valid/not-sa/020.xml" SECTIONS="4.4.8"
- OUTPUT="valid/not-sa/out/020.xml">
- Parameter entities expand with spaces on either side.</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-021"
- URI="valid/not-sa/021.xml" SECTIONS="4.2 [72]"
- OUTPUT="valid/not-sa/out/021.xml">
- Test demonstrates a parameter entity declaration that contains a partial attribute list declaration. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-023"
- URI="valid/not-sa/023.xml" SECTIONS="2.3 4.1 [10] [69]"
- OUTPUT="valid/not-sa/out/023.xml">
- Test demonstrates the use of a parameter entity reference within an attribute list declaration.
-</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-024"
- URI="valid/not-sa/024.xml" SECTIONS="2.8, 4.1 [69]"
- OUTPUT="valid/not-sa/out/024.xml">
- Constructs an &lt;!ATTLIST...&gt; declaration from several PEs.</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-025"
- URI="valid/not-sa/025.xml" SECTIONS="4.2"
- OUTPUT="valid/not-sa/out/025.xml">
- Test demonstrates that when more that one definition is provided for the same entity only the first declaration is binding. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-026"
- URI="valid/not-sa/026.xml" SECTIONS="3.3 [52]"
- OUTPUT="valid/not-sa/out/026.xml">
- Test demonstrates that when more that one definition is provided for the same attribute of a given element type only the first declaration is binding. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-027"
- URI="valid/not-sa/027.xml" SECTIONS="4.1 [69]"
- OUTPUT="valid/not-sa/out/027.xml">
- Test demonstrates a parameter entity reference whose value is NULL. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-028"
- URI="valid/not-sa/028.xml" SECTIONS="3.4 [62]"
- OUTPUT="valid/not-sa/out/028.xml">
- Test demonstrates the use of the conditional section INCLUDE that will include its contents. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-029"
- URI="valid/not-sa/029.xml" SECTIONS="3.4 [62]"
- OUTPUT="valid/not-sa/out/029.xml">
- Test demonstrates the use of the conditonal section IGNORE the will ignore its content from being used. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-030"
- URI="valid/not-sa/030.xml" SECTIONS="3.4 [62]"
- OUTPUT="valid/not-sa/out/030.xml">
- Test demonstrates the use of the conditonal section IGNORE the will ignore its content from being used. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-not-sa-031"
- URI="valid/not-sa/031.xml" SECTIONS="2.7"
- OUTPUT="valid/not-sa/out/031.xml">
- Expands a general entity which contains a CDATA section with
- what looks like a markup declaration (but is just text since
- it's in a CDATA section).</TEST>
-
-
-<!-- Start: valid/ext-sa -->
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-001"
- URI="valid/ext-sa/001.xml" SECTIONS="2.11"
- OUTPUT="valid/ext-sa/out/001.xml">
- A combination of carriage return line feed in an external entity must
- be normalized to a single newline. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-002"
- URI="valid/ext-sa/002.xml" SECTIONS="2.11"
- OUTPUT="valid/ext-sa/out/002.xml">
- A carriage return (also CRLF) in an external entity must
- be normalized to a single newline. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-003"
- URI="valid/ext-sa/003.xml" SECTIONS="3.1 4.1 [43] [68]"
- OUTPUT="valid/ext-sa/out/003.xml">
- Test demonstrates that the content of an element can be empty. In this case the external entity is an empty file. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-004"
- URI="valid/ext-sa/004.xml" SECTIONS="2.11"
- OUTPUT="valid/ext-sa/out/004.xml">
- A carriage return (also CRLF) in an external entity must
- be normalized to a single newline. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-005"
- URI="valid/ext-sa/005.xml" SECTIONS="3.2.1 4.2.2 [48] [75]"
- OUTPUT="valid/ext-sa/out/005.xml">
- Test demonstrates the use of optional character and content particles within an element content. The test also show the use of external entity. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-006"
- URI="valid/ext-sa/006.xml" SECTIONS="2.11 3.2.1 3.2.2 4.2.2 [48] [51] [75]"
- OUTPUT="valid/ext-sa/out/006.xml">
- Test demonstrates the use of optional character and content particles within mixed element content. The test also shows the use of an external entity and that a carriage control line feed in an external entity must be normalized to a single newline. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-007"
- URI="valid/ext-sa/007.xml" SECTIONS="4.2.2 4.4.3 [75]"
- OUTPUT="valid/ext-sa/out/007.xml">
- Test demonstrates the use of external entity and how replacement
-text is retrieved and processed. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-008"
- URI="valid/ext-sa/008.xml" SECTIONS="4.2.2 4.3.3. 4.4.3 [75] [80]"
- OUTPUT="valid/ext-sa/out/008.xml"> Test demonstrates the use of external
-entity and how replacement text is retrieved and processed. Also tests the use of an
-EncodingDecl of UTF-16.</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-009"
- URI="valid/ext-sa/009.xml" SECTIONS="2.11"
- OUTPUT="valid/ext-sa/out/009.xml">
- A carriage return (also CRLF) in an external entity must
- be normalized to a single newline. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-011"
- URI="valid/ext-sa/011.xml" SECTIONS="2.11 4.2.2 [75]"
- OUTPUT="valid/ext-sa/out/011.xml">
- Test demonstrates the use of a public identifier with and external entity.
-The test also show that a carriage control line feed combination in an external
-entity must be normalized to a single newline. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-012"
- URI="valid/ext-sa/012.xml" SECTIONS="4.2.1 4.2.2"
- OUTPUT="valid/ext-sa/out/012.xml">
- Test demonstrates both internal and external entities and that processing of entity references may be required to produce the correct replacement text.</TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-013"
- URI="valid/ext-sa/013.xml" SECTIONS="3.3.3"
- OUTPUT="valid/ext-sa/out/013.xml">
- Test demonstrates that whitespace is handled by adding a single whitespace to the normalized value in the attribute list. </TEST>
-<TEST TYPE="valid" ENTITIES="both" ID="valid-ext-sa-014"
- URI="valid/ext-sa/014.xml" SECTIONS="4.1 4.4.3 [68]"
- OUTPUT="valid/ext-sa/out/014.xml">
- Test demonstrates use of characters outside of normal ASCII range.</TEST>
-</TESTCASES>
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/069.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/069.xml
index 41eed46727..41eed46727 100644
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/069.xml
+++ b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/069.xml
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/076.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/076.xml
index b07019e90f..b07019e90f 100644
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/076.xml
+++ b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/076.xml
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/090.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/090.xml
index 41eed46727..41eed46727 100644
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/090.xml
+++ b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/090.xml
diff --git a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/091.xml b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/091.xml
index c55a698bbb..c55a698bbb 100644
--- a/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest/valid/sa/out/091.xml
+++ b/tests/auto/corelib/serialization/qxmlstream/XML-Test-Suite/xmlconf/xmltest_updates/091.xml
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/019.ref b/tests/auto/corelib/serialization/qxmlstream/data/019.ref
index 314efb2b04..9ae28f42e5 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/019.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/019.ref
@@ -3,5 +3,5 @@ Comment( text=" Simple legal case: prefixed element " )
StartElement( name="foo" namespaceUri="http://example.org/namespace" qualifiedName="a:foo" prefix="a"
NamespaceDeclaration( prefix="a" namespaceUri="http://example.org/namespace" )
)
-EndElement( name="foo" namespaceUri="http://example.org/namespace" qualifiedName="a:foo" )
+EndElement( name="foo" namespaceUri="http://example.org/namespace" qualifiedName="a:foo" prefix="a" )
EndDocument( )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/024.ref b/tests/auto/corelib/serialization/qxmlstream/data/024.ref
index 83c3ac5315..43cf2b1faf 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/024.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/024.ref
@@ -8,8 +8,8 @@ Characters( whitespace text="
StartElement( name="foo" namespaceUri="http://example.org/other-namespace" qualifiedName="a:foo" prefix="a"
NamespaceDeclaration( prefix="a" namespaceUri="http://example.org/other-namespace" )
)
-EndElement( name="foo" namespaceUri="http://example.org/other-namespace" qualifiedName="a:foo" )
+EndElement( name="foo" namespaceUri="http://example.org/other-namespace" qualifiedName="a:foo" prefix="a" )
Characters( whitespace text="
" )
-EndElement( name="foo" namespaceUri="http://example.org/namespace" qualifiedName="a:foo" )
+EndElement( name="foo" namespaceUri="http://example.org/namespace" qualifiedName="a:foo" prefix="a" )
EndDocument( )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/039.ref b/tests/auto/corelib/serialization/qxmlstream/data/039.ref
index 63ee6b4def..f7413e5436 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/039.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/039.ref
@@ -16,7 +16,7 @@ StartElement( name="bar" namespaceUri="http://example.org/~kipper" qualifiedName
Attribute( name="attr" qualifiedName="attr" value="2" )
)
-EndElement( name="bar" namespaceUri="http://example.org/~kipper" qualifiedName="b:bar" )
+EndElement( name="bar" namespaceUri="http://example.org/~kipper" qualifiedName="b:bar" prefix="b" )
Characters( whitespace text="
" )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/041.ref b/tests/auto/corelib/serialization/qxmlstream/data/041.ref
index 3e7ca64208..50328feb4a 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/041.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/041.ref
@@ -12,7 +12,7 @@ StartElement( name="bar" namespaceUri="http://example.org/~wilbur" qualifiedName
Attribute( name="attr" qualifiedName="attr" value="2" )
)
-EndElement( name="bar" namespaceUri="http://example.org/~wilbur" qualifiedName="a:bar" )
+EndElement( name="bar" namespaceUri="http://example.org/~wilbur" qualifiedName="a:bar" prefix="a" )
Characters( whitespace text="
" )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/1.ref b/tests/auto/corelib/serialization/qxmlstream/data/1.ref
index 0288cf0e11..41a9febd8e 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/1.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/1.ref
@@ -4,5 +4,5 @@ StartElement( name="doc" namespaceUri="namespaceUri" qualifiedName="ns:doc" pref
NamespaceDeclaration( prefix="ns" namespaceUri="namespaceUri" )
)
-EndElement( name="doc" namespaceUri="namespaceUri" qualifiedName="ns:doc" )
+EndElement( name="doc" namespaceUri="namespaceUri" qualifiedName="ns:doc" prefix="ns" )
EndDocument( )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/2.ref b/tests/auto/corelib/serialization/qxmlstream/data/2.ref
index 95d68efbd6..2fad9844ce 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/2.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/2.ref
@@ -5,5 +5,5 @@ StartElement( name="doc" namespaceUri="namespaceUri" qualifiedName="ns:doc" pref
NamespaceDeclaration( prefix="ns" namespaceUri="namespaceUri" )
)
Characters( text="The world goes round and round" )
-EndElement( name="doc" namespaceUri="namespaceUri" qualifiedName="ns:doc" )
+EndElement( name="doc" namespaceUri="namespaceUri" qualifiedName="ns:doc" prefix="ns" )
EndDocument( )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/21.ref b/tests/auto/corelib/serialization/qxmlstream/data/21.ref
index 1098c6800f..d0e4982eec 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/21.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/21.ref
@@ -33,10 +33,10 @@ Characters( whitespace text="
" )
StartElement( name="title" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:title" prefix="html" )
Characters( text="test file" )
-EndElement( name="title" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:title" )
+EndElement( name="title" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:title" prefix="html" )
Characters( whitespace text="
" )
-EndElement( name="head" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:head" )
+EndElement( name="head" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:head" prefix="html" )
Characters( whitespace text="
" )
StartElement( name="body" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:body" prefix="html" )
@@ -46,11 +46,11 @@ StartElement( name="p" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName
Attribute( name="class" qualifiedName="class" value="visible:false" )
)
Characters( text="bar" )
-EndElement( name="p" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:p" )
+EndElement( name="p" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:p" prefix="html" )
Characters( whitespace text="
" )
-EndElement( name="body" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:body" )
+EndElement( name="body" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:body" prefix="html" )
Characters( whitespace text="
" )
-EndElement( name="html" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:html" )
+EndElement( name="html" namespaceUri="http://www.w3.org/1999/xhtml" qualifiedName="html:html" prefix="html" )
EndDocument( )
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.ref b/tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.ref
new file mode 100644
index 0000000000..a578de8bb4
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.ref
@@ -0,0 +1,8003 @@
+StartDocument( )
+Invalid( name="a" qualifiedName="a"
+ Attribute( name="b" qualifiedName="b" value="1" )
+
+ Attribute( name="b" qualifiedName="b" value="2" )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+
+ Attribute( )
+ )
+ERROR: Attribute 'b' redefined.
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.xml b/tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.xml
new file mode 100644
index 0000000000..5f8b1003e9
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/data/duplicatedattributes.xml
@@ -0,0 +1,1002 @@
+<a
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+b="1" b="2" b="3" b="4"
+/>
diff --git a/tests/auto/corelib/serialization/qxmlstream/data/namespaceCDATA.ref b/tests/auto/corelib/serialization/qxmlstream/data/namespaceCDATA.ref
index 132875f4bb..84538b0230 100644
--- a/tests/auto/corelib/serialization/qxmlstream/data/namespaceCDATA.ref
+++ b/tests/auto/corelib/serialization/qxmlstream/data/namespaceCDATA.ref
@@ -15,7 +15,7 @@ Characters( whitespace text="
StartElement( name="bar" namespaceUri="http://qt-project.org" qualifiedName="pre:bar" prefix="pre"
NamespaceDeclaration( prefix="pre" namespaceUri="http://qt-project.org" )
)
-EndElement( name="bar" namespaceUri="http://qt-project.org" qualifiedName="pre:bar" )
+EndElement( name="bar" namespaceUri="http://qt-project.org" qualifiedName="pre:bar" prefix="pre" )
Characters( whitespace text="
" )
EndElement( name="body" qualifiedName="body" )
diff --git a/tests/auto/corelib/serialization/qxmlstream/qc14n.h b/tests/auto/corelib/serialization/qxmlstream/qc14n.h
index e4056fb0db..5ae87f1a7a 100644
--- a/tests/auto/corelib/serialization/qxmlstream/qc14n.h
+++ b/tests/auto/corelib/serialization/qxmlstream/qc14n.h
@@ -1,42 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-QT_FORWARD_DECLARE_CLASS(QIODevice)
-QT_FORWARD_DECLARE_CLASS(QString)
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QtCore/QDebug>
#include <QtCore/QFlags>
+#include <QtCore/QXmlStreamReader>
+
+#include <algorithm>
class QC14N
{
public:
static bool isEqual(QIODevice *const firstDocument,
QIODevice *const secondDocument,
- QString *const message = 0);
+ QString *const message = nullptr);
private:
static bool isDifferent(const QXmlStreamReader &r1,
@@ -118,18 +94,11 @@ bool QC14N::isAttributesEqual(const QXmlStreamReader &r1,
const QXmlStreamAttributes &attrs1 = r1.attributes();
const QXmlStreamAttributes &attrs2 = r2.attributes();
- const int len = attrs1.size();
-
- if(len != attrs2.size())
+ if (attrs1.size() != attrs2.size())
return false;
- for(int i = 0; i < len; ++i)
- {
- if(!attrs2.contains(attrs1.at(i)))
- return false;
- }
-
- return true;
+ auto existsInOtherList = [&attrs2](const auto &attr) { return attrs2.contains(attr); };
+ return std::all_of(attrs1.cbegin(), attrs1.cend(), existsInOtherList);
}
bool QC14N::isDifferent(const QXmlStreamReader &r1,
diff --git a/tests/auto/corelib/serialization/qxmlstream/qxmlstream.pro b/tests/auto/corelib/serialization/qxmlstream/qxmlstream.pro
deleted file mode 100644
index 0a739f0a0e..0000000000
--- a/tests/auto/corelib/serialization/qxmlstream/qxmlstream.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qxmlstream
-QT = core xml network testlib
-SOURCES = tst_qxmlstream.cpp
-
-TESTDATA += data XML-Test-Suite
diff --git a/tests/auto/corelib/serialization/qxmlstream/setupSuite.sh b/tests/auto/corelib/serialization/qxmlstream/setupSuite.sh
index 8dc9b7d551..3cf842c32a 100755
--- a/tests/auto/corelib/serialization/qxmlstream/setupSuite.sh
+++ b/tests/auto/corelib/serialization/qxmlstream/setupSuite.sh
@@ -1,31 +1,6 @@
#!/bin/sh
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is the build configuration utility of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2016 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#
# Hello!
@@ -42,7 +17,5 @@ cd XML-Test-Suite
export CVSROOT=":pserver:anonymous@dev.w3.org:/sources/public"
cvs -q up -C
-p4 edit ...
-p4 revert `find -name "Entries"` # They only contain CVS timestamps.
+git checkout -- `find -name "Entries"` # They only contain CVS timestamps.
xmllint --valid --noent xmlconf/xmlconf.xml --output xmlconf/finalCatalog.xml
-p4 revert -a ...
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
new file mode 100644
index 0000000000..1c3ca4e271
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/dtdInBody.xml
@@ -0,0 +1,20 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statement, as this is typical DTD content -->
+ <!ENTITY unite "&#x222a;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+ <!-- invalid DTD in XML body follows -->
+ <!DOCTYPE DTDTEST [
+ <!ELEMENT RESULT (CASE+)>
+ <!ATTLIST RESULT OUTPUT CDATA #REQUIRED>
+ ]>
+</TEST>
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
new file mode 100644
index 0000000000..cd398c0f9f
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/multipleDtd.xml
@@ -0,0 +1,20 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION, DATASET, COMMENTS)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statements, as this is typical DTD content -->
+ <!ENTITY iff "&hArr;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<!-- invalid second DTD follows -->
+<!DOCTYPE SECOND [
+ <!ELEMENT SECONDATTRIBUTE (#PCDATA)>
+ <!ENTITY on "&#8728;">
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+</TEST>
diff --git a/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml b/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
new file mode 100644
index 0000000000..1b61a3f062
--- /dev/null
+++ b/tests/auto/corelib/serialization/qxmlstream/tokenError/wellFormed.xml
@@ -0,0 +1,15 @@
+<!DOCTYPE TEST [
+ <!ELEMENT TESTATTRIBUTE (CASE+)>
+ <!ELEMENT CASE (CLASS, FUNCTION, DATASET, COMMENTS)>
+ <!ELEMENT CLASS (#PCDATA)>
+
+ <!-- adding random ENTITY statements, as this is typical DTD content -->
+ <!ENTITY unite "&#x222a;">
+
+ <!ATTLIST CASE CLASS CDATA #REQUIRED>
+]>
+<TEST>
+ <CASE>
+ <CLASS>tst_QXmlStream</CLASS>
+ </CASE>
+</TEST>
diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
index 8fdf91b090..b90d05b0fa 100644
--- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDirIterator>
@@ -32,18 +7,28 @@
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QUrl>
-#include <QXmlDefaultHandler>
#include <QXmlStreamReader>
+#include <QBuffer>
+#include <QStack>
+#include <private/qzipreader_p.h>
#include "qc14n.h"
+using namespace Qt::StringLiterals;
+
Q_DECLARE_METATYPE(QXmlStreamReader::ReadElementTextBehaviour)
static const char *const catalogFile = "XML-Test-Suite/xmlconf/finalCatalog.xml";
static const int expectedRunCount = 1646;
static const int expectedSkipCount = 532;
+static const char *const xmlTestsuiteDir = "XML-Test-Suite";
+static const char *const xmlconfDir = "XML-Test-Suite/xmlconf/";
+static const char *const xmlDatasetName = "xmltest";
+static const char *const updateFilesDir = "xmltest_updates";
+static const char *const destinationFolder = "/valid/sa/out/";
static inline int best(int a, int b)
{
@@ -65,6 +50,28 @@ static inline int best(int a, int b, int c)
return qMin(qMin(a, b), c);
}
+// copied from tst_qmake.cpp
+static void copyDir(const QString &sourceDirPath, const QString &targetDirPath)
+{
+ QDir currentDir;
+ QDirIterator dit(sourceDirPath, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden);
+ while (dit.hasNext()) {
+ dit.next();
+ const QString targetPath = targetDirPath + QLatin1Char('/') + dit.fileName();
+ currentDir.mkpath(targetPath);
+ copyDir(dit.filePath(), targetPath);
+ }
+
+ QDirIterator fit(sourceDirPath, QDir::Files | QDir::Hidden);
+ while (fit.hasNext()) {
+ fit.next();
+ const QString targetPath = targetDirPath + QLatin1Char('/') + fit.fileName();
+ QFile::remove(targetPath); // allowed to fail
+ QFile src(fit.filePath());
+ QVERIFY2(src.copy(targetPath), qPrintable(src.errorString()));
+ }
+}
+
template <typename C>
const C sorted_by_name(C c) { // return by const value so we can feed directly into range-for loops below
using T = typename C::value_type;
@@ -88,8 +95,8 @@ static QByteArray makeCanonical(const QString &filename,
bool testIncremental = false)
{
QFile file(filename);
- file.open(QIODevice::ReadOnly);
-
+ if (!file.open(QIODevice::ReadOnly))
+ qFatal("Could not open file %s", qPrintable(filename));
QXmlStreamReader reader;
QByteArray buffer;
@@ -115,7 +122,7 @@ static QByteArray makeCanonical(const QString &filename,
writeDtd << "<!DOCTYPE ";
writeDtd << docType;
writeDtd << " [";
- writeDtd << endl;
+ writeDtd << Qt::endl;
for (const QXmlStreamNotationDeclaration &notation : sorted_by_name(notationDeclarations)) {
writeDtd << "<!NOTATION ";
writeDtd << notation.name().toString();
@@ -134,11 +141,11 @@ static QByteArray makeCanonical(const QString &filename,
}
}
writeDtd << '>';
- writeDtd << endl;
+ writeDtd << Qt::endl;
}
writeDtd << "]>";
- writeDtd << endl;
+ writeDtd << Qt::endl;
writer.writeDTD(dtd);
}
} else if (reader.isStartElement()) {
@@ -221,7 +228,7 @@ static QString documentElement(const QByteArray &document)
*
* See \l {http://www.w3.org/XML/Test/} {Extensible Markup Language (XML) Conformance Test Suites}
*/
-class TestSuiteHandler : public QXmlDefaultHandler
+class TestSuiteHandler
{
public:
/**
@@ -240,8 +247,8 @@ public:
*/
class MissedBaseline
{
- friend class QVector<MissedBaseline>;
- MissedBaseline() {} // for QVector, don't use
+ friend class QList<MissedBaseline>;
+ MissedBaseline() {} // for QList, don't use
public:
MissedBaseline(const QString &aId,
const QByteArray &aExpected,
@@ -253,7 +260,7 @@ public:
qFatal("%s: aId must not be an empty string", Q_FUNC_INFO);
}
- void swap(MissedBaseline &other) Q_DECL_NOTHROW
+ void swap(MissedBaseline &other) noexcept
{
qSwap(id, other.id);
qSwap(expected, other.expected);
@@ -265,8 +272,8 @@ public:
QByteArray output;
};
- QVector<GeneralFailure> failures;
- QVector<MissedBaseline> missedBaselines;
+ QList<GeneralFailure> failures;
+ QList<MissedBaseline> missedBaselines;
/**
* The count of how many tests that were run.
@@ -286,29 +293,33 @@ public:
m_baseURI.push(baseURI);
}
- virtual bool characters(const QString &chars)
+ bool runTests(QFile *file)
{
- m_ch = chars;
- return true;
+ QXmlStreamReader reader(file);
+ while (!reader.atEnd() && !reader.hasError()) {
+ reader.readNext();
+
+ if (reader.isStartElement() && !startElement(reader.attributes()))
+ return false;
+
+ if (reader.isEndElement() && !endElement(reader.name().toString()))
+ return false;
+ }
+ return !reader.hasError();
}
- virtual bool startElement(const QString &,
- const QString &,
- const QString &,
- const QXmlAttributes &atts)
+ bool startElement(const QXmlStreamAttributes &atts)
{
m_atts.push(atts);
- const int i = atts.index(QLatin1String("xml:base"));
- if(i != -1)
- m_baseURI.push(m_baseURI.top().resolved(atts.value(i)));
+ const auto attr = atts.value(QLatin1String("xml:base"));
+ if (!attr.isEmpty())
+ m_baseURI.push(m_baseURI.top().resolved(attr.toString()));
return true;
}
- virtual bool endElement(const QString &,
- const QString &localName,
- const QString &)
+ bool endElement(const QString &localName)
{
if(localName == QLatin1String("TEST"))
{
@@ -329,19 +340,19 @@ public:
return true;
}
- const QString inputFilePath(m_baseURI.top().resolved(m_atts.top().value(QString(), QLatin1String("URI")))
- .toLocalFile());
- const QString id(m_atts.top().value(QString(), QLatin1String("ID")));
- const QString type(m_atts.top().value(QString(), QLatin1String("TYPE")));
+ const QString inputFilePath(
+ m_baseURI.top()
+ .resolved(
+ m_atts.top().value(QString(), QLatin1String("URI")).toString())
+ .toLocalFile());
+ const QString id(m_atts.top().value(QString(), QLatin1String("ID")).toString());
+ const QString type(m_atts.top().value(QString(), QLatin1String("TYPE")).toString());
QString expectedFilePath;
- const int index = m_atts.top().index(QString(), QLatin1String("OUTPUT"));
- if(index != -1)
- {
- expectedFilePath = m_baseURI.top().resolved(m_atts.top().value(QString(),
- QLatin1String("OUTPUT"))).toLocalFile();
- }
+ const auto attr = m_atts.top().value(QString(), QLatin1String("OUTPUT"));
+ if (!attr.isEmpty())
+ expectedFilePath = m_baseURI.top().resolved(attr.toString()).toLocalFile();
/* testcases.dtd: 'No parser should accept a "not-wf" testcase
* unless it's a nonvalidating parser and the test contains
@@ -349,7 +360,7 @@ public:
*
* We also let this apply to "valid", "invalid" and "error" tests, although
* I'm not fully sure this is correct. */
- const QString ents(m_atts.top().value(QString(), QLatin1String("ENTITIES")));
+ const QString ents(m_atts.top().value(QString(), QLatin1String("ENTITIES")).toString());
m_atts.pop();
if(ents == QLatin1String("both") ||
@@ -393,8 +404,6 @@ public:
return true;
}
- QXmlStreamReader reader(&inputFile);
-
/* See testcases.dtd which reads: 'Nonvalidating parsers
* must also accept "invalid" testcases, but validating ones must reject them.' */
if(type == QLatin1String("invalid") || type == QLatin1String("valid"))
@@ -455,8 +464,8 @@ public:
qFatal("The input catalog is invalid.");
return false;
}
- }
- else if(localName == QLatin1String("TESTCASES") && m_atts.top().index(QLatin1String("xml:base")) != -1)
+ } else if (localName == QLatin1String("TESTCASES")
+ && m_atts.top().hasAttribute(QLatin1String("xml:base")))
m_baseURI.pop();
m_atts.pop();
@@ -516,9 +525,8 @@ public:
}
private:
- QStack<QXmlAttributes> m_atts;
- QString m_ch;
- QStack<QUrl> m_baseURI;
+ QStack<QXmlStreamAttributes> m_atts;
+ QStack<QUrl> m_baseURI;
};
QT_BEGIN_NAMESPACE
Q_DECLARE_SHARED(TestSuiteHandler::MissedBaseline)
@@ -528,13 +536,15 @@ class tst_QXmlStream: public QObject
{
Q_OBJECT
public:
- tst_QXmlStream() : m_handler(QUrl::fromLocalFile(QFINDTESTDATA(catalogFile)))
+ tst_QXmlStream() : m_handler(QUrl::fromLocalFile(m_tempDir.filePath(catalogFile)))
{
}
private slots:
void initTestCase();
void cleanupTestCase();
+ void compareCompiles();
+ void runTestSuite();
void reportFailures() const;
void reportFailures_data();
void checkBaseline() const;
@@ -553,16 +563,23 @@ private slots:
void setEntityResolver();
void readFromQBuffer() const;
void readFromQBufferInvalid() const;
+ void readFromLatin1String() const;
void readNextStartElement() const;
void readElementText() const;
void readElementText_data() const;
void crashInUTF16Codec() const;
void hasAttributeSignature() const;
void hasAttribute() const;
- void writeWithCodec() const;
void writeWithUtf8Codec() const;
- void writeWithUtf16Codec() const;
void writeWithStandalone() const;
+ void writeCharacters_data() const;
+ void writeCharacters() const;
+ void writeAttribute_data() const;
+ void writeAttribute() const;
+ void writeBadCharactersUtf8_data() const;
+ void writeBadCharactersUtf8() const;
+ void writeBadCharactersUtf16_data() const;
+ void writeBadCharactersUtf16() const;
void entitiesAndWhitespace_1() const;
void entitiesAndWhitespace_2() const;
void testFalsePrematureError() const;
@@ -572,36 +589,80 @@ private slots:
void checkCommentIndentation() const;
void checkCommentIndentation_data() const;
void crashInXmlStreamReader() const;
- void write8bitCodec() const;
void invalidStringCharacters_data() const;
void invalidStringCharacters() const;
void hasError() const;
+ void readBack_data() const;
void readBack() const;
void roundTrip() const;
void roundTrip_data() const;
+ void test_fastScanName_data() const;
+ void test_fastScanName() const;
+
+ void entityExpansionLimit() const;
+
+ void tokenErrorHandling_data() const;
+ void tokenErrorHandling() const;
+ void checkStreamNotationDeclarations() const;
+ void checkStreamEntityDeclarations() const;
private:
static QByteArray readFile(const QString &filename);
+ QTemporaryDir m_tempDir;
TestSuiteHandler m_handler;
};
void tst_QXmlStream::initTestCase()
{
- QFile file(QFINDTESTDATA(catalogFile));
- QVERIFY2(file.open(QIODevice::ReadOnly),
- qPrintable(QString::fromLatin1("Failed to open the test suite catalog; %1").arg(file.fileName())));
+ // Due to license restrictions, we need to distribute part of the test
+ // suit as a zip archive. So we need to unzip it before running the tests,
+ // and also update some files there.
+ // We also need to remove the unzipped data during cleanup.
+
+ // On Android, we cannot unzip at the resource location, so we copy
+ // everything to a temporary directory first.
+ const QString XML_Test_Suite_dir = QFINDTESTDATA(xmlTestsuiteDir);
+ const QString XML_Test_Suite_destDir = m_tempDir.filePath(xmlTestsuiteDir);
+ copyDir(XML_Test_Suite_dir, XML_Test_Suite_destDir);
+
+
+ const QString filesDir(m_tempDir.filePath(xmlconfDir));
+ const QString fileName = filesDir + xmlDatasetName + ".zip";
+ QVERIFY(QFile::exists(fileName));
+ QZipReader reader(fileName);
+ QVERIFY(reader.isReadable());
+ QVERIFY(reader.extractAll(filesDir));
+ // update files
+ const auto files =
+ QDir(filesDir + updateFilesDir).entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
+ for (const auto &fileInfo : files) {
+ const QString destinationPath =
+ filesDir + xmlDatasetName + destinationFolder + fileInfo.fileName();
+ QFile::remove(destinationPath); // copy will fail if file exists
+ QVERIFY(QFile::copy(fileInfo.filePath(), destinationPath));
+ }
+}
- QXmlInputSource source(&file);
- QXmlSimpleReader reader;
- reader.setContentHandler(&m_handler);
+void tst_QXmlStream::cleanupTestCase()
+{
+}
- QVERIFY(reader.parse(&source, false));
+void tst_QXmlStream::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamAttribute>();
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamNamespaceDeclaration>();
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamNotationDeclaration>();
+ QTestPrivate::testEqualityOperatorsCompile<QXmlStreamEntityDeclaration>();
}
-void tst_QXmlStream::cleanupTestCase()
+void tst_QXmlStream::runTestSuite()
{
- QFile::remove(QLatin1String("test.xml"));
+ QFile file(m_tempDir.filePath(catalogFile));
+ QVERIFY2(file.open(QIODevice::ReadOnly),
+ qPrintable(QString::fromLatin1("Failed to open the test suite catalog; %1").arg(file.fileName())));
+
+ QVERIFY(m_handler.runTests(&file));
}
void tst_QXmlStream::reportFailures() const
@@ -614,7 +675,7 @@ void tst_QXmlStream::reportFailures() const
void tst_QXmlStream::reportFailures_data()
{
- const int len = m_handler.failures.count();
+ const int len = m_handler.failures.size();
QTest::addColumn<bool>("isError");
QTest::addColumn<QString>("description");
@@ -651,7 +712,7 @@ void tst_QXmlStream::checkBaseline_data() const
QTest::addColumn<QString>("expected");
QTest::addColumn<QString>("output");
- const int len = m_handler.missedBaselines.count();
+ const int len = m_handler.missedBaselines.size();
for(int i = 0; i < len; ++i)
{
@@ -680,7 +741,7 @@ void tst_QXmlStream::reportSuccess_data() const
{
QTest::addColumn<bool>("isError");
- const int len = m_handler.successes.count();
+ const int len = m_handler.successes.size();
for (int i = 0; i < len; ++i) {
const QByteArray testName = QByteArray::number(i) + ". " + m_handler.successes.at(i).toLatin1();
@@ -694,7 +755,8 @@ void tst_QXmlStream::reportSuccess_data() const
QByteArray tst_QXmlStream::readFile(const QString &filename)
{
QFile file(filename);
- file.open(QIODevice::ReadOnly);
+ if (!file.open(QIODevice::ReadOnly))
+ qFatal("Could not open file %s", qPrintable(filename));
QXmlStreamReader reader;
@@ -702,7 +764,7 @@ QByteArray tst_QXmlStream::readFile(const QString &filename)
QByteArray outarray;
QTextStream writer(&outarray);
// We always want UTF-8, and not what the system picks up.
- writer.setCodec("UTF-8");
+ writer.setEncoding(QStringConverter::Utf8);
while (!reader.atEnd()) {
reader.readNext();
@@ -740,7 +802,7 @@ QByteArray tst_QXmlStream::readFile(const QString &filename)
const auto attributes = reader.attributes();
if (attributes.size()) {
for (const QXmlStreamAttribute &attribute : attributes) {
- writer << endl << " Attribute(";
+ writer << Qt::endl << " Attribute(";
if (!attribute.name().isEmpty())
writer << " name=\"" << attribute.name().toString() << '"';
if (!attribute.namespaceUri().isEmpty())
@@ -751,37 +813,37 @@ QByteArray tst_QXmlStream::readFile(const QString &filename)
writer << " prefix=\"" << attribute.prefix().toString() << '"';
if (!attribute.value().isEmpty())
writer << " value=\"" << attribute.value().toString() << '"';
- writer << " )" << endl;
+ writer << " )" << Qt::endl;
}
}
const auto namespaceDeclarations = reader.namespaceDeclarations();
if (namespaceDeclarations.size()) {
for (const QXmlStreamNamespaceDeclaration &namespaceDeclaration : namespaceDeclarations) {
- writer << endl << " NamespaceDeclaration(";
+ writer << Qt::endl << " NamespaceDeclaration(";
if (!namespaceDeclaration.prefix().isEmpty())
writer << " prefix=\"" << namespaceDeclaration.prefix().toString() << '"';
if (!namespaceDeclaration.namespaceUri().isEmpty())
writer << " namespaceUri=\"" << namespaceDeclaration.namespaceUri().toString() << '"';
- writer << " )" << endl;
+ writer << " )" << Qt::endl;
}
}
const auto notationDeclarations = reader.notationDeclarations();
if (notationDeclarations.size()) {
for (const QXmlStreamNotationDeclaration &notationDeclaration : notationDeclarations) {
- writer << endl << " NotationDeclaration(";
+ writer << Qt::endl << " NotationDeclaration(";
if (!notationDeclaration.name().isEmpty())
writer << " name=\"" << notationDeclaration.name().toString() << '"';
if (!notationDeclaration.systemId().isEmpty())
writer << " systemId=\"" << notationDeclaration.systemId().toString() << '"';
if (!notationDeclaration.publicId().isEmpty())
writer << " publicId=\"" << notationDeclaration.publicId().toString() << '"';
- writer << " )" << endl;
+ writer << " )" << Qt::endl;
}
}
const auto entityDeclarations = reader.entityDeclarations();
if (entityDeclarations.size()) {
for (const QXmlStreamEntityDeclaration &entityDeclaration : entityDeclarations) {
- writer << endl << " EntityDeclaration(";
+ writer << Qt::endl << " EntityDeclaration(";
if (!entityDeclaration.name().isEmpty())
writer << " name=\"" << entityDeclaration.name().toString() << '"';
if (!entityDeclaration.notationName().isEmpty())
@@ -792,13 +854,13 @@ QByteArray tst_QXmlStream::readFile(const QString &filename)
writer << " publicId=\"" << entityDeclaration.publicId().toString() << '"';
if (!entityDeclaration.value().isEmpty())
writer << " value=\"" << entityDeclaration.value().toString() << '"';
- writer << " )" << endl;
+ writer << " )" << Qt::endl;
}
}
- writer << " )" << endl;
+ writer << " )" << Qt::endl;
}
if (reader.hasError())
- writer << "ERROR: " << reader.errorString() << endl;
+ writer << "ERROR: " << reader.errorString() << Qt::endl;
return outarray;
}
@@ -845,19 +907,24 @@ void tst_QXmlStream::addExtraNamespaceDeclarations()
}
{
QXmlStreamReader xml(data);
- xml.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("undeclared", "blabla"));
- xml.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("undeclared_too", "foofoo"));
+ QXmlStreamNamespaceDeclaration undeclared("undeclared", "blabla");
+ QXmlStreamNamespaceDeclaration undeclared_too("undeclared_too", "blabla");
+ xml.addExtraNamespaceDeclaration(undeclared);
+ xml.addExtraNamespaceDeclaration(undeclared_too);
while (!xml.atEnd()) {
xml.readNext();
}
QVERIFY2(!xml.hasError(), xml.errorString().toLatin1().constData());
+ QT_TEST_EQUALITY_OPS(undeclared, undeclared_too, false);
+ undeclared = undeclared_too;
+ QT_TEST_EQUALITY_OPS(undeclared, undeclared_too, true);
}
}
class EntityResolver : public QXmlStreamEntityResolver {
public:
- QString resolveUndeclaredEntity(const QString &name) {
+ QString resolveUndeclaredEntity(const QString &name) override {
static int count = 0;
return name.toUpper() + QString::number(++count);
}
@@ -1071,6 +1138,25 @@ void tst_QXmlStream::readFromQBufferInvalid() const
QVERIFY(reader.hasError());
}
+void tst_QXmlStream::readFromLatin1String() const
+{
+ const auto in = "<a>M\xE5rten</a>"_L1;
+ {
+ QXmlStreamReader reader(in);
+ QVERIFY(reader.readNextStartElement());
+ QString text = reader.readElementText();
+ QCOMPARE(text, "M\xE5rten"_L1);
+ }
+ // Same as above, but with addData()
+ {
+ QXmlStreamReader reader;
+ reader.addData(in);
+ QVERIFY(reader.readNextStartElement());
+ QString text = reader.readElementText();
+ QCOMPARE(text, "M\xE5rten"_L1);
+ }
+}
+
void tst_QXmlStream::readNextStartElement() const
{
QLatin1String in("<?xml version=\"1.0\"?><A><!-- blah --><B><C/></B><B attr=\"value\"/>text</A>");
@@ -1087,6 +1173,10 @@ void tst_QXmlStream::readNextStartElement() const
}
QCOMPARE(amountOfB, 2);
+
+ // well-formed document end follows
+ QVERIFY(!reader.readNextStartElement());
+ QCOMPARE(reader.error(), QXmlStreamReader::NoError);
}
void tst_QXmlStream::readElementText() const
@@ -1169,7 +1259,7 @@ int main(int argc, char *argv[])
bool error = false;
QByteArray canonical = makeCanonical(argv[2], "doc", error);
QTextStream myStdOut(stdout);
- myStdOut << canonical << endl;
+ myStdOut << canonical << Qt::endl;
exit(0);
}
@@ -1204,8 +1294,20 @@ void tst_QXmlStream::hasAttributeSignature() const
void tst_QXmlStream::hasAttribute() const
{
- QXmlStreamReader reader(QLatin1String("<e xmlns:p='http://example.com/2' xmlns='http://example.com/' "
- "attr1='value' attr2='value2' p:attr3='value3' emptyAttr=''><noAttributes/></e>"));
+ auto xml = QStringLiteral("<e"
+ " xmlns:p='http://example.com/2'"
+ " xmlns='http://example.com/'"
+ " attr1='value'"
+ " attr2='value2'"
+ " p:attr3='value3'"
+ " emptyAttr=''"
+ " atträbute='meep'"
+ " α='β'"
+ " >"
+ " <noAttributes/>"
+ "</e>");
+
+ QXmlStreamReader reader(xml);
QCOMPARE(reader.readNext(), QXmlStreamReader::StartDocument);
QCOMPARE(reader.readNext(), QXmlStreamReader::StartElement);
@@ -1216,8 +1318,18 @@ void tst_QXmlStream::hasAttribute() const
QVERIFY(atts.hasAttribute(QLatin1String("attr2")));
QVERIFY(atts.hasAttribute(QLatin1String("p:attr3")));
QVERIFY(atts.hasAttribute(QLatin1String("emptyAttr")));
+ QVERIFY(atts.hasAttribute(QLatin1String("attr\xE4""bute")));
+ // α is not representable in L1...
QVERIFY(!atts.hasAttribute(QLatin1String("DOESNOTEXIST")));
+ /* string literals (UTF-8/16) */
+ QVERIFY(atts.hasAttribute(u8"atträbute"));
+ QVERIFY(atts.hasAttribute( u"atträbute"));
+ QVERIFY(atts.hasAttribute(u8"α"));
+ QVERIFY(atts.hasAttribute( u"α"));
+ QVERIFY(!atts.hasAttribute(u8"β"));
+ QVERIFY(!atts.hasAttribute( u"β"));
+
/* Test with an empty & null namespaces. */
QVERIFY(atts.hasAttribute(QString(), QLatin1String("attr2"))); /* A null string. */
QVERIFY(atts.hasAttribute(QLatin1String(""), QLatin1String("attr2"))); /* An empty string. */
@@ -1226,6 +1338,8 @@ void tst_QXmlStream::hasAttribute() const
QVERIFY(atts.hasAttribute(QString::fromLatin1("attr1")));
QVERIFY(atts.hasAttribute(QString::fromLatin1("attr2")));
QVERIFY(atts.hasAttribute(QString::fromLatin1("p:attr3")));
+ QVERIFY(atts.hasAttribute(QStringLiteral("atträbute")));
+ QVERIFY(atts.hasAttribute(QStringLiteral("α")));
QVERIFY(atts.hasAttribute(QString::fromLatin1("emptyAttr")));
QVERIFY(!atts.hasAttribute(QString::fromLatin1("DOESNOTEXIST")));
@@ -1239,6 +1353,7 @@ void tst_QXmlStream::hasAttribute() const
QVERIFY(!atts.hasAttribute(QLatin1String("WRONG_NAMESPACE"), QString::fromLatin1("attr3")));
/* Invoke on an QXmlStreamAttributes that has no attributes at all. */
+ QCOMPARE(reader.readNext(), QXmlStreamReader::Characters);
QCOMPARE(reader.readNext(), QXmlStreamReader::StartElement);
const QXmlStreamAttributes &atts2 = reader.attributes();
@@ -1257,31 +1372,15 @@ void tst_QXmlStream::hasAttribute() const
reader.readNext();
QVERIFY(!reader.hasError());
-}
-
-void tst_QXmlStream::writeWithCodec() const
-{
- QByteArray outarray;
- QXmlStreamWriter writer(&outarray);
- writer.setAutoFormatting(true);
-
- QTextCodec *codec = QTextCodec::codecForName("ISO 8859-15");
- QVERIFY(codec);
- writer.setCodec(codec);
-
- const char *latin2 = "h\xe9 h\xe9";
- const QString string = codec->toUnicode(latin2);
-
-
- writer.writeStartDocument("1.0");
-
- writer.writeTextElement("foo", string);
- writer.writeEndElement();
- writer.writeEndDocument();
-
- QVERIFY(outarray.contains(latin2));
- QVERIFY(outarray.contains(codec->name()));
+ QXmlStreamAttribute attrValue1(QLatin1String("http://example.com/"), QString::fromLatin1("attr1"));
+ QXmlStreamAttribute attrValue2 = atts.at(0);
+ QT_TEST_EQUALITY_OPS(atts.at(0), QXmlStreamAttribute(), false);
+ QT_TEST_EQUALITY_OPS(atts.at(0), attrValue1, false);
+ QT_TEST_EQUALITY_OPS(atts.at(0), attrValue2, true);
+ QT_TEST_EQUALITY_OPS(attrValue1, attrValue2, false);
+ attrValue1 = attrValue2;
+ QT_TEST_EQUALITY_OPS(attrValue1, attrValue2, true);
}
void tst_QXmlStream::writeWithUtf8Codec() const
@@ -1289,36 +1388,11 @@ void tst_QXmlStream::writeWithUtf8Codec() const
QByteArray outarray;
QXmlStreamWriter writer(&outarray);
- QTextCodec *codec = QTextCodec::codecForMib(106); // utf-8
- QVERIFY(codec);
- writer.setCodec(codec);
-
writer.writeStartDocument("1.0");
static const char begin[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
QVERIFY(outarray.startsWith(begin));
}
-void tst_QXmlStream::writeWithUtf16Codec() const
-{
- QByteArray outarray;
- QXmlStreamWriter writer(&outarray);
-
- QTextCodec *codec = QTextCodec::codecForMib(1014); // utf-16LE
- QVERIFY(codec);
- writer.setCodec(codec);
-
- writer.writeStartDocument("1.0");
- static const char begin[] = "<?xml version=\"1.0\" encoding=\"UTF-16"; // skip potential "LE" suffix
- const int count = sizeof(begin) - 1; // don't include 0 terminator
- QByteArray begin_UTF16;
- begin_UTF16.reserve(2*(count));
- for (int i = 0; i < count; ++i) {
- begin_UTF16.append(begin[i]);
- begin_UTF16.append((char)'\0');
- }
- QVERIFY(outarray.startsWith(begin_UTF16));
-}
-
void tst_QXmlStream::writeWithStandalone() const
{
{
@@ -1341,6 +1415,143 @@ void tst_QXmlStream::writeWithStandalone() const
}
}
+static void writeCharacters_data_common()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+
+ QTest::newRow("empty") << QString() << QString();
+
+ // invalid content
+ QTest::newRow("null-character") << u"\0"_s << QString();
+ QTest::newRow("vertical-tab") << "\v" << QString();
+ QTest::newRow("form-feed") << "\f" << QString();
+ QTest::newRow("esc") << "\x1f" << QString();
+ QTest::newRow("U+FFFE") << u"\xfffe"_s << QString();
+ QTest::newRow("U+FFFF") << u"\xffff"_s << QString();
+
+ // simple strings
+ QTest::newRow("us-ascii") << "Hello, world" << "Hello, world";
+ QTest::newRow("latin1") << "Bokmål" << "Bokmål";
+ QTest::newRow("nonlatin1") << "Ελληνικά" << "Ελληνικά";
+ QTest::newRow("nonbmp") << u"\U00010000"_s << u"\U00010000"_s;
+
+ // escaped content
+ QTest::newRow("less-than") << "<" << "&lt;";
+ QTest::newRow("greater-than") << ">" << "&gt;";
+ QTest::newRow("ampersand") << "&" << "&amp;";
+ QTest::newRow("quote") << "\"" << "&quot;";
+}
+
+template <typename Execute, typename Transform>
+static void writeCharacters_common(Execute &&exec, Transform &&transform)
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+ QStringView utf16 = input;
+ QByteArray utf8ba = input.toUtf8();
+ QUtf8StringView utf8(utf8ba);
+
+ // may be invalid if input is not Latin1
+ QByteArray l1ba = input.toLatin1();
+ QLatin1StringView l1(l1ba);
+ if (l1 != input)
+ l1 = {};
+
+ auto write = [&](auto input) -> std::optional<QString> {
+ QString result;
+ QXmlStreamWriter writer(&result);
+ writer.writeStartElement("a");
+ exec(writer, input);
+ writer.writeEndElement();
+ if (writer.hasError())
+ return std::nullopt;
+ return result;
+ };
+
+ if (input.isNull() != output.isNull()) {
+ // error
+ QCOMPARE(write(utf16), std::nullopt);
+ QCOMPARE(write(utf8), std::nullopt);
+ if (!l1.isEmpty())
+ QCOMPARE(write(l1), std::nullopt);
+ } else {
+ output = transform(output);
+ QCOMPARE(write(utf16), output);
+ QCOMPARE(write(utf8), output);
+ if (!l1.isEmpty())
+ QCOMPARE(write(l1), output);
+ }
+}
+
+void tst_QXmlStream::writeCharacters_data() const
+{
+ writeCharacters_data_common();
+ QTest::newRow("tab") << "\t" << "\t";
+ QTest::newRow("newline") << "\n" << "\n";
+ QTest::newRow("carriage-return") << "\r" << "\r";
+}
+
+void tst_QXmlStream::writeCharacters() const
+{
+ auto exec = [](QXmlStreamWriter &writer, auto input) {
+ writer.writeCharacters(input);
+ };
+ auto transform = [](auto output) { return "<a>" + output + "</a>"; };
+ writeCharacters_common(exec, transform);
+}
+
+void tst_QXmlStream::writeAttribute_data() const
+{
+ writeCharacters_data_common();
+ QTest::newRow("tab") << "\t" << "&#9;";
+ QTest::newRow("newline") << "\n" << "&#10;";
+ QTest::newRow("carriage-return") << "\r" << "&#13;";
+}
+
+void tst_QXmlStream::writeAttribute() const
+{
+ auto exec = [](QXmlStreamWriter &writer, auto input) {
+ writer.writeAttribute("b", input);
+ };
+ auto transform = [](auto output) { return "<a b=\"" + output + "\"/>"; };
+ writeCharacters_common(exec, transform);
+}
+
+#include "../../io/qurlinternal/utf8data.cpp"
+void tst_QXmlStream::writeBadCharactersUtf8_data() const
+{
+ QTest::addColumn<QByteArray>("input");
+ loadInvalidUtf8Rows();
+}
+
+void tst_QXmlStream::writeBadCharactersUtf8() const
+{
+ QFETCH(QByteArray, input);
+ QString target;
+ QXmlStreamWriter writer(&target);
+ writer.writeTextElement("a", QUtf8StringView(input));
+ QVERIFY(writer.hasError());
+}
+
+void tst_QXmlStream::writeBadCharactersUtf16_data() const
+{
+ QTest::addColumn<QString>("input");
+ QTest::addRow("low-surrogate") << u"\xdc00"_s;
+ QTest::addRow("high-surrogate") << u"\xd800"_s;
+ QTest::addRow("inverted-surrogate-pair") << u"\xdc00\xd800"_s;
+ QTest::addRow("high-surrogate+non-surrogate") << u"\xd800z"_s;
+}
+
+void tst_QXmlStream::writeBadCharactersUtf16() const
+{
+ QFETCH(QString, input);
+ QString target;
+ QXmlStreamWriter writer(&target);
+ writer.writeTextElement("a", input);
+ QVERIFY(writer.hasError());
+}
+
void tst_QXmlStream::entitiesAndWhitespace_1() const
{
QXmlStreamReader reader(QLatin1String("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><test>&extEnt;</test>"));
@@ -1414,7 +1625,6 @@ void tst_QXmlStream::garbageInXMLPrologUTF8Explicitly() const
QVERIFY(out.open(QIODevice::ReadWrite));
QXmlStreamWriter writer (&out);
- writer.setCodec("UTF-8");
writer.writeStartDocument();
writer.writeEmptyElement("Foo");
writer.writeEndDocument();
@@ -1522,7 +1732,7 @@ void tst_QXmlStream::crashInXmlStreamReader() const
class FakeBuffer : public QBuffer
{
protected:
- qint64 writeData(const char *c, qint64 i)
+ qint64 writeData(const char *c, qint64 i) override
{
qint64 ai = qMin(m_capacity, i);
m_capacity -= ai;
@@ -1603,43 +1813,6 @@ void tst_QXmlStream::hasError() const
}
-void tst_QXmlStream::write8bitCodec() const
-{
- QBuffer outBuffer;
- QVERIFY(outBuffer.open(QIODevice::WriteOnly));
- QXmlStreamWriter writer(&outBuffer);
- writer.setAutoFormatting(false);
-
- QTextCodec *codec = QTextCodec::codecForName("IBM500");
- if (!codec) {
- QSKIP("Encoding IBM500 not available.");
- }
- writer.setCodec(codec);
-
- writer.writeStartDocument();
- writer.writeStartElement("root");
- writer.writeAttribute("attrib", "1");
- writer.writeEndElement();
- writer.writeEndDocument();
- outBuffer.close();
-
- // test 8 bit encoding
- QByteArray values = outBuffer.data();
- QVERIFY(values.size() > 1);
- // check '<'
- QCOMPARE(values[0] & 0x00FF, 0x4c);
- // check '?'
- QCOMPARE(values[1] & 0x00FF, 0x6F);
-
- // convert the start of the XML
- const QString expected = ("<?xml version=\"1.0\" encoding=\"IBM500\"?>");
- QTextDecoder *decoder = codec->makeDecoder();
- QVERIFY(decoder);
- QString decodedText = decoder->toUnicode(values);
- delete decoder;
- QVERIFY(decodedText.startsWith(expected));
-}
-
void tst_QXmlStream::invalidStringCharacters() const
{
// test scan in attributes
@@ -1698,41 +1871,64 @@ void tst_QXmlStream::invalidStringCharacters_data() const
//
}
-static bool isValidSingleTextChar(const ushort c)
+static bool isValidSingleTextChar(char32_t c)
{
- // Conforms to https://www.w3.org/TR/REC-xml/#NT-Char - except for the high range, which is done
- // with surrogates.
+ // Conforms to https://www.w3.org/TR/REC-xml/#NT-Char
// Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
- static const QPair<ushort, ushort> validRanges[] = {
- QPair<ushort, ushort>(0x9, 0xb),
- QPair<ushort, ushort>(0xd, 0xe),
- QPair<ushort, ushort>(0x20, 0xd800),
- QPair<ushort, ushort>(0xe000, 0xfffe)
+ constexpr struct { char32_t lo, hi; } validRanges[] = {
+ {0x9, 0xA},
+ {0xD, 0xD},
+ {0x20, 0xD7ff},
+ {0xE000, 0xFFFD},
+ {0x1'0000, 0x10'FFFF},
};
- for (const QPair<ushort, ushort> &range : validRanges) {
- if (c >= range.first && c < range.second)
+ for (const auto range : validRanges) {
+ if (c >= range.lo && c <= range.hi)
return true;
}
return false;
}
+void tst_QXmlStream::readBack_data() const
+{
+ QTest::addColumn<int>("plane");
+
+ // Check all 17 Unicode planes. Split into separate executions lest the
+ // test function times out in asan builds.
+
+ for (int i = 0; i < 17; ++i)
+ QTest::addRow("plane-%02d", i) << i;
+}
+
void tst_QXmlStream::readBack() const
{
- for (ushort c = 0; c < std::numeric_limits<ushort>::max(); ++c) {
- QBuffer buffer;
+ QFETCH(const int, plane);
+
+ constexpr qsizetype MaxChunkSizeWhenEncoding = 512; // from qxmlstream.cpp
+ QBuffer buffer;
+ QString text = QString(513, 'a'); // one longer than the internal conversion buffer
- QVERIFY(buffer.open(QIODevice::WriteOnly));
+ for (char16_t i = 0; i < (std::numeric_limits<char16_t>::max)(); ++i) {
+
+ const char32_t c = (plane << 16) + i;
+
+ // end chunk in invalid character, split surrogates:
+ const auto pair = QChar::fromUcs4(c);
+ text.resize(MaxChunkSizeWhenEncoding + 1 - pair.size());
+ text += pair;
+
+ QVERIFY(buffer.open(QIODevice::WriteOnly|QIODevice::Truncate));
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
- writer.writeTextElement("a", QString(QChar(c)));
+ writer.writeTextElement("a", text);
writer.writeEndDocument();
buffer.close();
- if (writer.hasError()) {
- QVERIFY2(!isValidSingleTextChar(c), QByteArray::number(c));
+ if (!isValidSingleTextChar(c)) {
+ QVERIFY2(writer.hasError(), QByteArray::number(c));
} else {
- QVERIFY2(isValidSingleTextChar(c), QByteArray::number(c));
+ QVERIFY2(!writer.hasError(), QByteArray::number(c));
QVERIFY(buffer.open(QIODevice::ReadOnly));
QXmlStreamReader reader(&buffer);
do {
@@ -1754,6 +1950,62 @@ void tst_QXmlStream::roundTrip_data() const
"<child xmlns:unknown=\"http://mydomain\">Text</child>"
"</father>"
"</root>\n";
+
+ // When a namespace is introduced by an attribute of an element,
+ // that element can exercise the namespace in its tag.
+ // This used (QTBUG-75456) to lead to the namespace definition
+ // being wrongly duplicated, with a new name.
+ QTest::newRow("QTBUG-75456") <<
+ "<?xml version=\"1.0\"?>"
+ "<abc:root xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:abc=\"ns1\">"
+ "<abc:parent>"
+ "<abc:child xmlns:unknown=\"http://mydomain\">Text</abc:child>"
+ "</abc:parent>"
+ "<def:parent xmlns:def=\"ns2\" id=\"test\">"
+ "<def:child id=\"Timmy\">More text</def:child>"
+ "<def:child id=\"Jimmy\">Even more text</def:child>"
+ "</def:parent>"
+ "</abc:root>\n";
+}
+
+void tst_QXmlStream::entityExpansionLimit() const
+{
+ QString xml = QStringLiteral("<?xml version=\"1.0\"?>"
+ "<!DOCTYPE foo ["
+ "<!ENTITY a \"0123456789\" >"
+ "<!ENTITY b \"&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;\" >"
+ "<!ENTITY c \"&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;\" >"
+ "<!ENTITY d \"&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;\" >"
+ "]>"
+ "<foo>&d;&d;&d;</foo>");
+ {
+ QXmlStreamReader reader(xml);
+ QCOMPARE(reader.entityExpansionLimit(), 4096);
+ do {
+ reader.readNext();
+ } while (!reader.atEnd());
+ QCOMPARE(reader.error(), QXmlStreamReader::NotWellFormedError);
+ }
+
+ // &d; expands to 10k characters, minus the 3 removed (&d;) means it should fail
+ // with a limit of 9996 chars and pass with 9997
+ {
+ QXmlStreamReader reader(xml);
+ reader.setEntityExpansionLimit(9996);
+ do {
+ reader.readNext();
+ } while (!reader.atEnd());
+
+ QCOMPARE(reader.error(), QXmlStreamReader::NotWellFormedError);
+ }
+ {
+ QXmlStreamReader reader(xml);
+ reader.setEntityExpansionLimit(9997);
+ do {
+ reader.readNext();
+ } while (!reader.atEnd());
+ QCOMPARE(reader.error(), QXmlStreamReader::NoError);
+ }
}
void tst_QXmlStream::roundTrip() const
@@ -1773,5 +2025,126 @@ void tst_QXmlStream::roundTrip() const
QCOMPARE(out, in);
}
+void tst_QXmlStream::test_fastScanName_data() const
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QXmlStreamReader::Error>("errorType");
+
+ // 4096 is the limit in QXmlStreamReaderPrivate::fastScanName()
+
+ QByteArray arr = "<a:" + QByteArray("b").repeated(4096 - 1);
+ QTest::newRow("data1") << arr << QXmlStreamReader::PrematureEndOfDocumentError;
+
+ arr = "<a:" + QByteArray("b").repeated(4096);
+ QTest::newRow("data2") << arr << QXmlStreamReader::NotWellFormedError;
+
+ arr = "<" + QByteArray("a").repeated(4000) + ":" + QByteArray("b").repeated(96);
+ QTest::newRow("data3") << arr << QXmlStreamReader::PrematureEndOfDocumentError;
+
+ arr = "<" + QByteArray("a").repeated(4000) + ":" + QByteArray("b").repeated(96 + 1);
+ QTest::newRow("data4") << arr << QXmlStreamReader::NotWellFormedError;
+
+ arr = "<" + QByteArray("a").repeated(4000 + 1) + ":" + QByteArray("b").repeated(96);
+ QTest::newRow("data5") << arr << QXmlStreamReader::NotWellFormedError;
+}
+
+void tst_QXmlStream::test_fastScanName() const
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QXmlStreamReader::Error, errorType);
+
+ QXmlStreamReader reader(data);
+ QXmlStreamReader::TokenType tokenType;
+ while (!reader.atEnd())
+ tokenType = reader.readNext();
+
+ QCOMPARE(tokenType, QXmlStreamReader::Invalid);
+ QCOMPARE(reader.error(), errorType);
+}
+
+void tst_QXmlStream::tokenErrorHandling_data() const
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QXmlStreamReader::Error>("expectedError");
+ QTest::addColumn<QString>("errorKeyWord");
+
+ constexpr auto invalid = QXmlStreamReader::Error::UnexpectedElementError;
+ constexpr auto valid = QXmlStreamReader::Error::NoError;
+ QTest::newRow("DtdInBody") << "dtdInBody.xml" << invalid << "DTD";
+ QTest::newRow("multipleDTD") << "multipleDtd.xml" << invalid << "second DTD";
+ QTest::newRow("wellFormed") << "wellFormed.xml" << valid << "";
+}
+
+void tst_QXmlStream::tokenErrorHandling() const
+{
+ QFETCH(const QString, fileName);
+ QFETCH(const QXmlStreamReader::Error, expectedError);
+ QFETCH(const QString, errorKeyWord);
+
+ const QDir dir(QFINDTESTDATA("tokenError"));
+ QFile file(dir.absoluteFilePath(fileName));
+
+ // Cross-compiling: Files may not be found when running test standalone
+ // QSKIP in that case, because the tested functionality is platform independent.
+ if (!file.exists())
+ QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
+
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QCOMPARE(reader.error(), expectedError);
+ if (expectedError != QXmlStreamReader::Error::NoError)
+ QVERIFY(reader.errorString().contains(errorKeyWord));
+}
+
+void tst_QXmlStream::checkStreamNotationDeclarations() const
+{
+ QString fileName("12.xml");
+ const QDir dir(QFINDTESTDATA("data"));
+ QFile file(dir.absoluteFilePath(fileName));
+ if (!file.exists())
+ QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QVERIFY(!reader.hasError());
+ QXmlStreamNotationDeclaration notation1, notation2, notation3;
+ QT_TEST_EQUALITY_OPS(notation1, notation2, true);
+ const auto notationDeclarations = reader.notationDeclarations();
+ if (notationDeclarations.count() >= 2) {
+ notation1 = notationDeclarations.at(0);
+ notation2 = notationDeclarations.at(1);
+ notation3 = notationDeclarations.at(1);
+ }
+ QT_TEST_EQUALITY_OPS(notation1, notation2, false);
+ QT_TEST_EQUALITY_OPS(notation3, notation2, true);
+}
+
+void tst_QXmlStream::checkStreamEntityDeclarations() const
+{
+ QString fileName("5.xml");
+ const QDir dir(QFINDTESTDATA("data"));
+ QFile file(dir.absoluteFilePath(fileName));
+ if (!file.exists())
+ QSKIP(QObject::tr("Testfile %1 not found.").arg(fileName).toUtf8().constData());
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ QVERIFY(!reader.hasError());
+ QXmlStreamEntityDeclaration entity;
+ QT_TEST_EQUALITY_OPS(entity, QXmlStreamEntityDeclaration(), true);
+
+ const auto entityDeclarations = reader.entityDeclarations();
+ if (entityDeclarations.count() >= 2) {
+ entity = entityDeclarations.at(1);
+ QT_TEST_EQUALITY_OPS(entityDeclarations.at(0), entityDeclarations.at(1), false);
+ QT_TEST_EQUALITY_OPS(entity, entityDeclarations.at(1), true);
+ }
+}
#include "tst_qxmlstream.moc"
-// vim: et:ts=4:sw=4:sts=4
diff --git a/tests/auto/corelib/serialization/serialization.pro b/tests/auto/corelib/serialization/serialization.pro
deleted file mode 100644
index 9638178cdc..0000000000
--- a/tests/auto/corelib/serialization/serialization.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = \
- json \
- qcborstreamreader \
- qcborstreamwriter \
- qcborvalue \
- qcborvalue_json \
- qdatastream \
- qdatastream_core_pixmap \
- qtextstream \
- qxmlstream
-
-!qtHaveModule(gui): SUBDIRS -= \
- qdatastream
-
-!qtHaveModule(network): SUBDIRS -= \
- qtextstream
-
-!qtHaveModule(network)|!qtHaveModule(xml): SUBDIRS -= \
- qxmlstream
diff --git a/tests/auto/corelib/statemachine/qstate/qstate.pro b/tests/auto/corelib/statemachine/qstate/qstate.pro
deleted file mode 100644
index e2251ded9d..0000000000
--- a/tests/auto/corelib/statemachine/qstate/qstate.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstate
-QT = core testlib
-SOURCES = tst_qstate.cpp
diff --git a/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp b/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp
deleted file mode 100644
index bbc3f890bd..0000000000
--- a/tests/auto/corelib/statemachine/qstate/tst_qstate.cpp
+++ /dev/null
@@ -1,374 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include "qstate.h"
-#include "qstatemachine.h"
-#include "qsignaltransition.h"
-
-class tst_QState : public QObject
-{
- Q_OBJECT
-
-private slots:
- void assignProperty();
- void assignPropertyTwice();
- void historyInitialState();
- void transitions();
- void privateSignals();
- void parallelStateAndInitialState();
-};
-
-class TestClass: public QObject
-{
- Q_OBJECT
-public:
- TestClass() : called(false) {}
- bool called;
-
-public slots:
- void slot() { called = true; }
-
-
-};
-
-void tst_QState::assignProperty()
-{
- QStateMachine machine;
-
- QObject object;
- object.setProperty("fooBar", 10);
-
- QState *s1 = new QState(&machine);
- s1->assignProperty(&object, "fooBar", 20);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(object.property("fooBar").toInt(), 20);
-}
-
-void tst_QState::assignPropertyTwice()
-{
- QStateMachine machine;
-
- QObject object;
- object.setProperty("fooBar", 10);
-
- QState *s1 = new QState(&machine);
- s1->assignProperty(&object, "fooBar", 20);
- s1->assignProperty(&object, "fooBar", 30);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(object.property("fooBar").toInt(), 30);
-}
-
-class EventTestTransition: public QAbstractTransition
-{
-public:
- EventTestTransition(QEvent::Type type, QState *targetState)
- : QAbstractTransition(), m_type(type)
- {
- setTargetState(targetState);
- }
-
-protected:
- bool eventTest(QEvent *e)
- {
- return e->type() == m_type;
- }
-
- void onTransition(QEvent *) {}
-
-private:
- QEvent::Type m_type;
-
-};
-
-void tst_QState::historyInitialState()
-{
- QStateMachine machine;
-
- QState *s1 = new QState(&machine);
-
- QState *s2 = new QState(&machine);
- QHistoryState *h1 = new QHistoryState(s2);
-
- s2->setInitialState(h1);
-
- QState *s3 = new QState(s2);
- h1->setDefaultState(s3);
-
- QState *s4 = new QState(s2);
-
- s1->addTransition(new EventTestTransition(QEvent::User, s2));
- s2->addTransition(new EventTestTransition(QEvent::User, s1));
- s3->addTransition(new EventTestTransition(QEvent::Type(QEvent::User+1), s4));
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s3));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s3));
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User+1)));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s4));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s4));
-}
-
-void tst_QState::transitions()
-{
- QState s1;
- QState s2;
-
- QVERIFY(s1.transitions().isEmpty());
-
- QAbstractTransition *t1 = s1.addTransition(this, SIGNAL(destroyed()), &s2);
- QAbstractTransition *t1_1 = s1.addTransition(this, &tst_QState::destroyed, &s2);
- QVERIFY(t1 != 0);
- QVERIFY(t1_1 != 0);
- QCOMPARE(s1.transitions().count(), 2);
- QCOMPARE(s1.transitions().first(), t1);
- QCOMPARE(s1.transitions().last(), t1_1);
- QVERIFY(s2.transitions().isEmpty());
-
- s1.removeTransition(t1);
- s1.removeTransition(t1_1);
- QVERIFY(s1.transitions().isEmpty());
-
- s1.addTransition(t1);
- QCOMPARE(s1.transitions().count(), 1);
- QCOMPARE(s1.transitions().first(), t1);
-
- QAbstractTransition *t2 = new QEventTransition(&s1);
- QCOMPARE(s1.transitions().count(), 2);
- QVERIFY(s1.transitions().contains(t1));
- QVERIFY(s1.transitions().contains(t2));
-
- // Transitions from child states should not be reported.
- QState *s21 = new QState(&s2);
- QAbstractTransition *t3 = s21->addTransition(this, SIGNAL(destroyed()), &s2);
- QVERIFY(s2.transitions().isEmpty());
- QCOMPARE(s21->transitions().count(), 1);
- QCOMPARE(s21->transitions().first(), t3);
-}
-
-class MyState : public QState
-{
- Q_OBJECT
-public:
- MyState(QState *parent = 0)
- : QState(parent)
- {
-
- }
-
- void emitPrivateSignals()
- {
- // These deliberately do not compile
-// emit entered();
-// emit exited();
-//
-// emit entered(QPrivateSignal());
-// emit exited(QPrivateSignal());
-//
-// emit entered(QAbstractState::QPrivateSignal());
-// emit exited(QAbstractState::QPrivateSignal());
- }
-
-};
-
-class MyTransition : public QSignalTransition
-{
- Q_OBJECT
-public:
- MyTransition(QObject * sender, const char * signal, QState *sourceState = 0)
- : QSignalTransition(sender, signal, sourceState)
- {
-
- }
-
- void emitPrivateSignals()
- {
- // These deliberately do not compile
-// emit triggered();
-//
-// emit triggered(QPrivateSignal());
-//
-// emit triggered(QAbstractTransition::QPrivateSignal());
- }
-};
-
-class SignalConnectionTester : public QObject
-{
- Q_OBJECT
-public:
- SignalConnectionTester(QObject *parent = 0)
- : QObject(parent), testPassed(false)
- {
-
- }
-
-public Q_SLOTS:
- void testSlot()
- {
- testPassed = true;
- }
-
-public:
- bool testPassed;
-};
-
-class TestTrigger : public QObject
-{
- Q_OBJECT
-public:
- TestTrigger(QObject *parent = 0)
- : QObject(parent)
- {
-
- }
-
- void emitTrigger()
- {
- emit trigger();
- }
-
-signals:
- void trigger();
-};
-
-void tst_QState::privateSignals()
-{
- QStateMachine machine;
-
- QState *s1 = new QState(&machine);
- MyState *s2 = new MyState(&machine);
-
- TestTrigger testTrigger;
-
- MyTransition *t1 = new MyTransition(&testTrigger, SIGNAL(trigger()), s1);
- s1->addTransition(t1);
- t1->setTargetState(s2);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- SignalConnectionTester s1Tester;
- SignalConnectionTester s2Tester;
- SignalConnectionTester t1Tester;
-
- QObject::connect(s1, &QState::exited, &s1Tester, &SignalConnectionTester::testSlot);
- QObject::connect(s2, &QState::entered, &s2Tester, &SignalConnectionTester::testSlot);
- QObject::connect(t1, &QSignalTransition::triggered, &t1Tester, &SignalConnectionTester::testSlot);
-
- testTrigger.emitTrigger();
-
- QCoreApplication::processEvents();
-
- QVERIFY(s1Tester.testPassed);
- QVERIFY(s2Tester.testPassed);
- QVERIFY(t1Tester.testPassed);
-
-}
-
-void tst_QState::parallelStateAndInitialState()
-{
- QStateMachine machine;
-
- { // setting an initial state on a parallel state:
- QState a(QState::ParallelStates, &machine);
- QState b(&a);
- QVERIFY(!a.initialState());
- const QString warning
- = QString::asprintf("QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", &a);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- a.setInitialState(&b); // should produce a warning and do nothing.
- QVERIFY(!a.initialState());
- }
-
- { // setting the child-mode from ExclusiveStates to ParallelStates should remove the initial state:
- QState a(QState::ExclusiveStates, &machine);
- QState b(&a);
- a.setInitialState(&b);
- QCOMPARE(a.initialState(), &b);
- const QString warning
- = QString::asprintf("QState::setChildMode: setting the child-mode of state %p to "
- "parallel removes the initial state", &a);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- a.setChildMode(QState::ParallelStates); // should produce a warning and remove the initial state
- QVERIFY(!a.initialState());
- QCOMPARE(a.childMode(), QState::ParallelStates);
- }
-}
-
-QTEST_MAIN(tst_QState)
-#include "tst_qstate.moc"
diff --git a/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro b/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro
deleted file mode 100644
index 4f16b2a9ca..0000000000
--- a/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstatemachine
-QT = core-private testlib
-qtHaveModule(widgets): QT += widgets
-SOURCES = tst_qstatemachine.cpp
diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
deleted file mode 100644
index 810698fb4e..0000000000
--- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp
+++ /dev/null
@@ -1,6700 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QCoreApplication>
-#ifndef QT_NO_WIDGETS
-#include <QtWidgets/QPushButton>
-#include <QtWidgets/QGraphicsScene>
-#include <QtWidgets/QGraphicsSceneEvent>
-#include <QtWidgets/QGraphicsTextItem>
-#endif
-
-#include "qstatemachine.h"
-#include "qstate.h"
-#include "qhistorystate.h"
-#ifndef QT_NO_WIDGETS
-#include "qkeyeventtransition.h"
-#include "qmouseeventtransition.h"
-#endif
-#include "private/qstate_p.h"
-#include "private/qstatemachine_p.h"
-
-static int globalTick;
-
-// Run exec for a maximum of TIMEOUT msecs
-#define QCOREAPPLICATION_EXEC(TIMEOUT) \
-{ \
- QTimer timer; \
- timer.setSingleShot(true); \
- timer.setInterval(TIMEOUT); \
- timer.start(); \
- connect(&timer, SIGNAL(timeout()), QCoreApplication::instance(), SLOT(quit())); \
- QCoreApplication::exec(); \
-}
-
-#define TEST_RUNNING_CHANGED(RUNNING) \
-{ \
- QTRY_COMPARE(runningSpy.count(), 1); \
- QList<QVariant> runningArgs = runningSpy.takeFirst(); \
- QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \
- QVERIFY(runningArgs.at(0).toBool() == RUNNING); \
- QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \
-}
-
-#define TEST_RUNNING_CHANGED_STARTED_STOPPED \
-{ \
- QTRY_COMPARE(runningSpy.count(), 2); \
- QList<QVariant> runningArgs = runningSpy.takeFirst(); \
- QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \
- QVERIFY(runningArgs.at(0).toBool() == true); \
- runningArgs = runningSpy.takeFirst(); \
- QVERIFY(runningArgs.at(0).type() == QVariant::Bool); \
- QVERIFY(runningArgs.at(0).toBool() == false); \
- QCOMPARE(machine.isRunning(), runningArgs.at(0).toBool()); \
-}
-
-#define DEFINE_ACTIVE_SPY(VAR) \
- QSignalSpy VAR##_activeSpy(VAR, &QState::activeChanged); \
- QVERIFY(VAR##_activeSpy.isValid());
-
-#define TEST_ACTIVE_CHANGED(VAR, COUNT) \
-{ \
- QTRY_COMPARE(VAR##_activeSpy.count(), COUNT); \
- bool active = true; \
- foreach (const QList<QVariant> &activeArgs, static_cast<QList<QList<QVariant> > >(VAR##_activeSpy)) { \
- QVERIFY(activeArgs.at(0).type() == QVariant::Bool); \
- QVERIFY(activeArgs.at(0).toBool() == active); \
- active = !active; \
- } \
- QCOMPARE(VAR->active(), !active); \
-}
-
-class SignalEmitter : public QObject
-{
-Q_OBJECT
- public:
- SignalEmitter(QObject *parent = 0)
- : QObject(parent) {}
-public Q_SLOTS:
- void emitSignalWithNoArg()
- { emit signalWithNoArg(); }
- void emitSignalWithIntArg(int arg)
- { emit signalWithIntArg(arg); }
- void emitSignalWithStringArg(const QString &arg)
- { emit signalWithStringArg(arg); }
- void emitSignalWithDefaultArg()
- { emit signalWithDefaultArg(); }
-Q_SIGNALS:
- void signalWithNoArg();
- void signalWithIntArg(int);
- void signalWithStringArg(const QString &);
- void signalWithDefaultArg(int i = 42);
-};
-
-class tst_QStateMachine : public QObject
-{
- Q_OBJECT
-private slots:
- void rootState();
- void machineWithParent();
-#ifdef QT_BUILD_INTERNAL
- void addAndRemoveState();
-#endif
- void stateEntryAndExit();
- void assignProperty();
- void assignPropertyWithAnimation();
- void postEvent();
- void cancelDelayedEvent();
- void postDelayedEventAndStop();
- void postDelayedEventFromThread();
- void stopAndPostEvent();
- void stateFinished();
- void parallelStates();
- void parallelRootState();
- void allSourceToTargetConfigurations();
- void signalTransitions();
-#ifndef QT_NO_WIDGETS
- void eventTransitions();
- void graphicsSceneEventTransitions();
-#endif
- void historyStates();
- void startAndStop();
- void setRunning();
- void targetStateWithNoParent();
- void targetStateDeleted();
- void transitionToRootState();
- void transitionFromRootState();
- void transitionEntersParent();
-
- void defaultErrorState();
- void customGlobalErrorState();
- void customLocalErrorStateInBrokenState();
- void customLocalErrorStateInOtherState();
- void customLocalErrorStateInParentOfBrokenState();
- void customLocalErrorStateOverridesParent();
- void errorStateHasChildren();
- void errorStateHasErrors();
- void errorStateIsRootState();
- void errorStateEntersParentFirst();
- void customErrorStateIsNull();
- void clearError();
- void historyStateHasNowhereToGo();
- void historyStateAsInitialState();
- void historyStateAfterRestart();
- void brokenStateIsNeverEntered();
- void customErrorStateNotInGraph();
- void transitionToStateNotInGraph();
- void restoreProperties();
-
- void defaultGlobalRestorePolicy();
- void globalRestorePolicySetToRestore();
- void globalRestorePolicySetToDontRestore();
-
- void noInitialStateForInitialState();
-
- void transitionWithParent();
- void transitionsFromParallelStateWithNoChildren();
- void parallelStateTransition();
- void parallelStateAssignmentsDone();
- void nestedRestoreProperties();
- void nestedRestoreProperties2();
-
- void simpleAnimation();
- void twoAnimations();
- void twoAnimatedTransitions();
- void playAnimationTwice();
- void nestedTargetStateForAnimation();
- void propertiesAssignedSignalTransitionsReuseAnimationGroup();
- void animatedGlobalRestoreProperty();
- void specificTargetValueOfAnimation();
-
- void addDefaultAnimation();
- void addDefaultAnimationWithUnusedAnimation();
- void removeDefaultAnimation();
- void overrideDefaultAnimationWithSpecific();
-
- void nestedStateMachines();
- void goToState();
- void goToStateFromSourceWithTransition();
-
- void clonedSignals();
- void postEventFromOtherThread();
-#ifndef QT_NO_WIDGETS
- void eventFilterForApplication();
-#endif
- void eventClassesExported();
- void stopInTransitionToFinalState();
- void stopInEventTest_data();
- void stopInEventTest();
-
- void testIncrementReceivers();
- void initialStateIsEnteredBeforeStartedEmitted();
- void deletePropertyAssignmentObjectBeforeEntry();
- void deletePropertyAssignmentObjectBeforeRestore();
- void deleteInitialState();
- void setPropertyAfterRestore();
- void transitionWithNoTarget_data();
- void transitionWithNoTarget();
- void initialStateIsFinal();
-
- void restorePropertiesSimple();
- void restoreProperties2();
- void restoreProperties3();
- void restoreProperties4();
- void restorePropertiesSelfTransition();
- void changeStateWhileAnimatingProperty();
- void propertiesAreAssignedBeforeEntryCallbacks_data();
- void propertiesAreAssignedBeforeEntryCallbacks();
-
- void multiTargetTransitionInsideParallelStateGroup();
- void signalTransitionNormalizeSignature();
-#ifdef Q_COMPILER_DELEGATING_CONSTRUCTORS
- void createPointerToMemberSignalTransition();
-#endif
- void createSignalTransitionWhenRunning();
- void createEventTransitionWhenRunning();
- void signalTransitionSenderInDifferentThread();
- void signalTransitionSenderInDifferentThread2();
- void signalTransitionRegistrationThreadSafety();
- void childModeConstructor();
-
- void qtbug_44963();
- void qtbug_44783();
- void internalTransition();
- void conflictingTransition();
- void conflictingTransition2();
- void qtbug_46059();
- void qtbug_46703();
- void postEventFromBeginSelectTransitions();
- void dontProcessSlotsWhenMachineIsNotRunning();
-};
-
-class TestState : public QState
-{
-public:
- enum Event {
- Entry,
- Exit
- };
- TestState(QState *parent, const QString &objectName = QString())
- : QState(parent)
- { setObjectName(objectName); }
- TestState(ChildMode mode, const QString &objectName = QString())
- : QState(mode)
- { setObjectName(objectName); }
- QVector<QPair<int, Event> > events;
-protected:
- virtual void onEntry(QEvent *) {
- events.append(qMakePair(globalTick++, Entry));
- }
- virtual void onExit(QEvent *) {
- events.append(qMakePair(globalTick++, Exit));
- }
-};
-
-class TestTransition : public QAbstractTransition
-{
-public:
- TestTransition(QAbstractState *target, const QString &objectName = QString())
- : QAbstractTransition()
- { setTargetState(target); setObjectName(objectName); }
- QVector<int> triggers;
-protected:
- virtual bool eventTest(QEvent *) {
- return true;
- }
- virtual void onTransition(QEvent *) {
- triggers.append(globalTick++);
- }
-};
-
-class EventTransition : public QAbstractTransition
-{
-public:
- EventTransition(QEvent::Type type, QAbstractState *target, QState *parent = 0)
- : QAbstractTransition(parent), m_type(type)
- { setTargetState(target); }
- EventTransition(QEvent::Type type, const QList<QAbstractState *> &targets, QState *parent = 0)
- : QAbstractTransition(parent), m_type(type)
- { setTargetStates(targets); }
-protected:
- virtual bool eventTest(QEvent *e) {
- return (e->type() == m_type);
- }
- virtual void onTransition(QEvent *) {}
-private:
- QEvent::Type m_type;
-};
-
-void tst_QStateMachine::transitionToRootState()
-{
- QStateMachine machine;
- machine.setObjectName("machine");
-
- QState *initialState = new QState();
- DEFINE_ACTIVE_SPY(initialState);
- initialState->setObjectName("initial");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QAbstractTransition *trans = new EventTransition(QEvent::User, &machine);
- initialState->addTransition(trans);
- QCOMPARE(trans->sourceState(), initialState);
- QCOMPARE(trans->targetState(), static_cast<QAbstractState *>(&machine));
-
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(initialState));
- TEST_ACTIVE_CHANGED(initialState, 1);
-
- machine.postEvent(new QEvent(QEvent::User));
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initial'");
- QCoreApplication::processEvents();
- QVERIFY(machine.configuration().isEmpty());
- QVERIFY(!machine.isRunning());
- TEST_ACTIVE_CHANGED(initialState, 2);
-}
-
-void tst_QStateMachine::transitionFromRootState()
-{
- QStateMachine machine;
- QState *root = &machine;
- QState *s1 = new QState(root);
- EventTransition *trans = new EventTransition(QEvent::User, s1);
- root->addTransition(trans);
- QCOMPARE(trans->sourceState(), root);
- QCOMPARE(trans->targetState(), static_cast<QAbstractState *>(s1));
-}
-
-void tst_QStateMachine::transitionEntersParent()
-{
- QStateMachine machine;
-
- QObject *entryController = new QObject(&machine);
- entryController->setObjectName("entryController");
- entryController->setProperty("greatGrandParentEntered", false);
- entryController->setProperty("grandParentEntered", false);
- entryController->setProperty("parentEntered", false);
- entryController->setProperty("stateEntered", false);
-
- QState *greatGrandParent = new QState();
- greatGrandParent->setObjectName("grandParent");
- greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true);
- machine.addState(greatGrandParent);
- machine.setInitialState(greatGrandParent);
-
- QState *grandParent = new QState(greatGrandParent);
- grandParent->setObjectName("grandParent");
- grandParent->assignProperty(entryController, "grandParentEntered", true);
-
- QState *parent = new QState(grandParent);
- parent->setObjectName("parent");
- parent->assignProperty(entryController, "parentEntered", true);
-
- QState *state = new QState(parent);
- state->setObjectName("state");
- state->assignProperty(entryController, "stateEntered", true);
-
- QState *initialStateOfGreatGrandParent = new QState(greatGrandParent);
- initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent");
- greatGrandParent->setInitialState(initialStateOfGreatGrandParent);
-
- initialStateOfGreatGrandParent->addTransition(new EventTransition(QEvent::User, state));
-
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), true);
- QCOMPARE(entryController->property("grandParentEntered").toBool(), false);
- QCOMPARE(entryController->property("parentEntered").toBool(), false);
- QCOMPARE(entryController->property("stateEntered").toBool(), false);
- QCOMPARE(machine.configuration().count(), 2);
- QVERIFY(machine.configuration().contains(greatGrandParent));
- QVERIFY(machine.configuration().contains(initialStateOfGreatGrandParent));
-
- entryController->setProperty("greatGrandParentEntered", false);
- entryController->setProperty("grandParentEntered", false);
- entryController->setProperty("parentEntered", false);
- entryController->setProperty("stateEntered", false);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), false);
- QCOMPARE(entryController->property("grandParentEntered").toBool(), true);
- QCOMPARE(entryController->property("parentEntered").toBool(), true);
- QCOMPARE(entryController->property("stateEntered").toBool(), true);
- QCOMPARE(machine.configuration().count(), 4);
- QVERIFY(machine.configuration().contains(greatGrandParent));
- QVERIFY(machine.configuration().contains(grandParent));
- QVERIFY(machine.configuration().contains(parent));
- QVERIFY(machine.configuration().contains(state));
-}
-
-void tst_QStateMachine::defaultErrorState()
-{
- QStateMachine machine;
- QCOMPARE(machine.errorState(), reinterpret_cast<QAbstractState *>(0));
-
- QState *brokenState = new QState();
- brokenState->setObjectName("MyInitialState");
-
- machine.addState(brokenState);
- machine.setInitialState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'MyInitialState'");
-
- // initialState has no initial state
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
- QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'MyInitialState'"));
- QCOMPARE(machine.isRunning(), false);
-}
-
-class CustomErrorState: public QState
-{
-public:
- CustomErrorState(QStateMachine *machine, QState *parent = 0)
- : QState(parent), error(QStateMachine::NoError), m_machine(machine)
- {
- }
-
- void onEntry(QEvent *)
- {
- error = m_machine->error();
- errorString = m_machine->errorString();
- }
-
- QStateMachine::Error error;
- QString errorString;
-
-private:
- QStateMachine *m_machine;
-};
-
-void tst_QStateMachine::customGlobalErrorState()
-{
- QStateMachine machine;
-
- CustomErrorState *customErrorState = new CustomErrorState(&machine);
- customErrorState->setObjectName("customErrorState");
- machine.addState(customErrorState);
- machine.setErrorState(customErrorState);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- brokenState->setObjectName("brokenState");
- machine.addState(brokenState);
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.errorState(), static_cast<QAbstractState*>(customErrorState));
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(initialState));
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(initialState));
-
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(customErrorState));
- QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError);
- QCOMPARE(customErrorState->errorString, QString::fromLatin1("Missing initial state in compound state 'brokenState'"));
- QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
- QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'"));
-}
-
-void tst_QStateMachine::customLocalErrorStateInBrokenState()
-{
- QStateMachine machine;
- CustomErrorState *customErrorState = new CustomErrorState(&machine);
- machine.addState(customErrorState);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- brokenState->setObjectName("brokenState");
- machine.addState(brokenState);
- brokenState->setErrorState(customErrorState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(customErrorState));
- QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError);
-}
-
-void tst_QStateMachine::customLocalErrorStateInOtherState()
-{
- QStateMachine machine;
- CustomErrorState *customErrorState = new CustomErrorState(&machine);
- machine.addState(customErrorState);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine");
- initialState->setErrorState(customErrorState);
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- brokenState->setObjectName("brokenState");
-
- machine.addState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'");
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), false);
-}
-
-void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState()
-{
- QStateMachine machine;
- CustomErrorState *customErrorState = new CustomErrorState(&machine);
- machine.addState(customErrorState);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *parentOfBrokenState = new QState();
- machine.addState(parentOfBrokenState);
- parentOfBrokenState->setObjectName("parentOfBrokenState");
- parentOfBrokenState->setErrorState(customErrorState);
-
- QState *brokenState = new QState(parentOfBrokenState);
- brokenState->setObjectName("brokenState");
- parentOfBrokenState->setInitialState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(customErrorState));
-}
-
-void tst_QStateMachine::customLocalErrorStateOverridesParent()
-{
- QStateMachine machine;
- CustomErrorState *customErrorStateForParent = new CustomErrorState(&machine);
- machine.addState(customErrorStateForParent);
-
- CustomErrorState *customErrorStateForBrokenState = new CustomErrorState(&machine);
- machine.addState(customErrorStateForBrokenState);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *parentOfBrokenState = new QState();
- machine.addState(parentOfBrokenState);
- parentOfBrokenState->setObjectName("parentOfBrokenState");
- parentOfBrokenState->setErrorState(customErrorStateForParent);
-
- QState *brokenState = new QState(parentOfBrokenState);
- brokenState->setObjectName("brokenState");
- brokenState->setErrorState(customErrorStateForBrokenState);
- parentOfBrokenState->setInitialState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(customErrorStateForBrokenState));
- QCOMPARE(customErrorStateForBrokenState->error, QStateMachine::NoInitialStateError);
- QCOMPARE(customErrorStateForParent->error, QStateMachine::NoError);
-}
-
-void tst_QStateMachine::errorStateHasChildren()
-{
- QStateMachine machine;
- CustomErrorState *customErrorState = new CustomErrorState(&machine);
- customErrorState->setObjectName("customErrorState");
- machine.addState(customErrorState);
-
- machine.setErrorState(customErrorState);
-
- QState *childOfErrorState = new QState(customErrorState);
- childOfErrorState->setObjectName("childOfErrorState");
- customErrorState->setInitialState(childOfErrorState);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- brokenState->setObjectName("brokenState");
- machine.addState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), true);
- QCOMPARE(machine.configuration().count(), 2);
- QVERIFY(machine.configuration().contains(customErrorState));
- QVERIFY(machine.configuration().contains(childOfErrorState));
-}
-
-
-void tst_QStateMachine::errorStateHasErrors()
-{
- QStateMachine machine;
- CustomErrorState *customErrorState = new CustomErrorState(&machine);
- customErrorState->setObjectName("customErrorState");
- machine.addState(customErrorState);
-
- machine.setErrorState(customErrorState);
-
- QState *childOfErrorState = new QState(customErrorState);
- childOfErrorState->setObjectName("childOfErrorState");
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- brokenState->setObjectName("brokenState");
- machine.addState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'customErrorState'");
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), false);
- QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
- QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'customErrorState'"));
-}
-
-void tst_QStateMachine::errorStateIsRootState()
-{
- QStateMachine machine;
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::setErrorState: root state cannot be error state");
- machine.setErrorState(&machine);
-
- QState *initialState = new QState();
- initialState->setObjectName("initialState");
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- brokenState->setObjectName("brokenState");
- machine.addState(brokenState);
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)));
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'");
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), false);
-}
-
-void tst_QStateMachine::errorStateEntersParentFirst()
-{
- QStateMachine machine;
-
- QObject *entryController = new QObject(&machine);
- entryController->setObjectName("entryController");
- entryController->setProperty("greatGrandParentEntered", false);
- entryController->setProperty("grandParentEntered", false);
- entryController->setProperty("parentEntered", false);
- entryController->setProperty("errorStateEntered", false);
-
- QState *greatGrandParent = new QState();
- greatGrandParent->setObjectName("greatGrandParent");
- greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true);
- machine.addState(greatGrandParent);
- machine.setInitialState(greatGrandParent);
-
- QState *grandParent = new QState(greatGrandParent);
- grandParent->setObjectName("grandParent");
- grandParent->assignProperty(entryController, "grandParentEntered", true);
-
- QState *parent = new QState(grandParent);
- parent->setObjectName("parent");
- parent->assignProperty(entryController, "parentEntered", true);
-
- QState *errorState = new QState(parent);
- errorState->setObjectName("errorState");
- errorState->assignProperty(entryController, "errorStateEntered", true);
- machine.setErrorState(errorState);
-
- QState *initialStateOfGreatGrandParent = new QState(greatGrandParent);
- initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent");
- greatGrandParent->setInitialState(initialStateOfGreatGrandParent);
-
- QState *brokenState = new QState(greatGrandParent);
- brokenState->setObjectName("brokenState");
-
- QState *childState = new QState(brokenState);
- childState->setObjectName("childState");
-
- initialStateOfGreatGrandParent->addTransition(new EventTransition(QEvent::User, brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), true);
- QCOMPARE(entryController->property("grandParentEntered").toBool(), false);
- QCOMPARE(entryController->property("parentEntered").toBool(), false);
- QCOMPARE(entryController->property("errorStateEntered").toBool(), false);
- QCOMPARE(machine.configuration().count(), 2);
- QVERIFY(machine.configuration().contains(greatGrandParent));
- QVERIFY(machine.configuration().contains(initialStateOfGreatGrandParent));
-
- entryController->setProperty("greatGrandParentEntered", false);
- entryController->setProperty("grandParentEntered", false);
- entryController->setProperty("parentEntered", false);
- entryController->setProperty("errorStateEntered", false);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), false);
- QCOMPARE(entryController->property("grandParentEntered").toBool(), true);
- QCOMPARE(entryController->property("parentEntered").toBool(), true);
- QCOMPARE(entryController->property("errorStateEntered").toBool(), true);
- QCOMPARE(machine.configuration().count(), 4);
- QVERIFY(machine.configuration().contains(greatGrandParent));
- QVERIFY(machine.configuration().contains(grandParent));
- QVERIFY(machine.configuration().contains(parent));
- QVERIFY(machine.configuration().contains(errorState));
-}
-
-void tst_QStateMachine::customErrorStateIsNull()
-{
- QStateMachine machine;
- machine.setErrorState(0);
-
- QState *initialState = new QState();
- machine.addState(initialState);
- machine.setInitialState(initialState);
-
- QState *brokenState = new QState();
- machine.addState(brokenState);
-
- new QState(brokenState);
- initialState->addTransition(new EventTransition(QEvent::User, brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::User));
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state ''");
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.errorState(), reinterpret_cast<QAbstractState *>(0));
- QCOMPARE(machine.isRunning(), false);
-}
-
-void tst_QStateMachine::clearError()
-{
- QStateMachine machine;
- machine.setErrorState(new QState(&machine)); // avoid warnings
-
- QState *brokenState = new QState(&machine);
- brokenState->setObjectName("brokenState");
- machine.setInitialState(brokenState);
- new QState(brokenState);
-
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), true);
- QCOMPARE(machine.error(), QStateMachine::NoInitialStateError);
- QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'"));
-
- machine.clearError();
-
- QCOMPARE(machine.error(), QStateMachine::NoError);
- QVERIFY(machine.errorString().isEmpty());
-}
-
-void tst_QStateMachine::historyStateAsInitialState()
-{
- QStateMachine machine;
-
- QHistoryState *hs = new QHistoryState(&machine);
- machine.setInitialState(hs);
-
- QState *s1 = new QState(&machine);
- hs->setDefaultState(s1);
-
- QState *s2 = new QState(&machine);
-
- QHistoryState *s2h = new QHistoryState(s2);
- s2->setInitialState(s2h);
-
- QState *s21 = new QState(s2);
- s2h->setDefaultState(s21);
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s21));
-}
-
-void tst_QStateMachine::historyStateHasNowhereToGo()
-{
- QStateMachine machine;
-
- QState *initialState = new QState(&machine);
- initialState->setObjectName("initialState");
- machine.setInitialState(initialState);
- QState *errorState = new QState(&machine);
- errorState->setObjectName("errorState");
- machine.setErrorState(errorState); // avoid warnings
-
- QState *brokenState = new QState(&machine);
- brokenState->setObjectName("brokenState");
- brokenState->setInitialState(new QState(brokenState));
-
- QHistoryState *historyState = new QHistoryState(brokenState);
- historyState->setObjectName("historyState");
- EventTransition *t = new EventTransition(QEvent::User, historyState);
- t->setObjectName("initialState->historyState");
- initialState->addTransition(t);
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(machine.errorState()));
- QCOMPARE(machine.error(), QStateMachine::NoDefaultStateInHistoryStateError);
- QCOMPARE(machine.errorString(), QString::fromLatin1("Missing default state in history state 'historyState'"));
-}
-
-void tst_QStateMachine::historyStateAfterRestart()
-{
- // QTBUG-8842
- QStateMachine machine;
-
- QState *s1 = new QState(&machine);
- machine.setInitialState(s1);
- QState *s2 = new QState(&machine);
- QState *s21 = new QState(s2);
- QState *s22 = new QState(s2);
- QHistoryState *s2h = new QHistoryState(s2);
- s2h->setDefaultState(s21);
- s1->addTransition(new EventTransition(QEvent::User, s2h));
- s21->addTransition(new EventTransition(QEvent::User, s22));
- s2->addTransition(new EventTransition(QEvent::User, s1));
-
- for (int x = 0; x < 2; ++x) {
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- // s1 -> s2h -> s21 (default state)
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 2);
- QVERIFY(machine.configuration().contains(s2));
- // This used to fail on the 2nd run because the
- // history had not been cleared.
- QVERIFY(machine.configuration().contains(s21));
-
- // s21 -> s22
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s22));
-
- // s2 -> s1 (s22 saved in s2h)
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- // s1 -> s2h -> s22 (saved state)
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().count(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s22));
-
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QVERIFY(stoppedSpy.isValid());
- machine.stop();
- QTRY_COMPARE(stoppedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- }
-}
-
-void tst_QStateMachine::brokenStateIsNeverEntered()
-{
- QStateMachine machine;
-
- QObject *entryController = new QObject(&machine);
- entryController->setProperty("brokenStateEntered", false);
- entryController->setProperty("childStateEntered", false);
- entryController->setProperty("errorStateEntered", false);
-
- QState *initialState = new QState(&machine);
- machine.setInitialState(initialState);
-
- QState *errorState = new QState(&machine);
- errorState->assignProperty(entryController, "errorStateEntered", true);
- machine.setErrorState(errorState);
-
- QState *brokenState = new QState(&machine);
- brokenState->assignProperty(entryController, "brokenStateEntered", true);
- brokenState->setObjectName("brokenState");
-
- QState *childState = new QState(brokenState);
- childState->assignProperty(entryController, "childStateEntered", true);
-
- initialState->addTransition(new EventTransition(QEvent::User, brokenState));
-
- machine.start();
- QCoreApplication::processEvents();
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(entryController->property("errorStateEntered").toBool(), true);
- QCOMPARE(entryController->property("brokenStateEntered").toBool(), false);
- QCOMPARE(entryController->property("childStateEntered").toBool(), false);
-}
-
-void tst_QStateMachine::transitionToStateNotInGraph()
-{
- QStateMachine machine;
-
- QState *initialState = new QState(&machine);
- initialState->setObjectName("initialState");
- machine.setInitialState(initialState);
-
- QState independentState;
- independentState.setObjectName("independentState");
- initialState->addTransition(&independentState);
-
- machine.start();
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initialState'");
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), false);
-}
-
-void tst_QStateMachine::customErrorStateNotInGraph()
-{
- QStateMachine machine;
-
- QState errorState;
- errorState.setObjectName("errorState");
- QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine");
- machine.setErrorState(&errorState);
- QCOMPARE(machine.errorState(), reinterpret_cast<QAbstractState *>(0));
-
- QState *initialBrokenState = new QState(&machine);
- initialBrokenState->setObjectName("initialBrokenState");
- machine.setInitialState(initialBrokenState);
- new QState(initialBrokenState);
-
- machine.start();
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'initialBrokenState'");
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.isRunning(), false);
-}
-
-void tst_QStateMachine::restoreProperties()
-{
- QStateMachine machine;
- QCOMPARE(machine.globalRestorePolicy(), QState::DontRestoreProperties);
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *object = new QObject(&machine);
- object->setProperty("a", 1);
- object->setProperty("b", 2);
-
- QState *S1 = new QState();
- S1->setObjectName("S1");
- S1->assignProperty(object, "a", 3);
- machine.addState(S1);
-
- QState *S2 = new QState();
- S2->setObjectName("S2");
- S2->assignProperty(object, "b", 5);
- machine.addState(S2);
-
- QState *S3 = new QState();
- S3->setObjectName("S3");
- machine.addState(S3);
-
- QFinalState *S4 = new QFinalState();
- machine.addState(S4);
-
- S1->addTransition(new EventTransition(QEvent::User, S2));
- S2->addTransition(new EventTransition(QEvent::User, S3));
- S3->addTransition(S4);
-
- machine.setInitialState(S1);
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(object->property("a").toInt(), 3);
- QCOMPARE(object->property("b").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(object->property("a").toInt(), 1);
- QCOMPARE(object->property("b").toInt(), 5);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- QCOMPARE(object->property("a").toInt(), 1);
- QCOMPARE(object->property("b").toInt(), 2);
-}
-
-void tst_QStateMachine::rootState()
-{
- QStateMachine machine;
- QCOMPARE(qobject_cast<QState*>(machine.parentState()), (QState*)0);
- QCOMPARE(machine.machine(), (QStateMachine*)0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QCOMPARE(s1->parentState(), static_cast<QState*>(&machine));
-
- QState *s2 = new QState();
- DEFINE_ACTIVE_SPY(s2);
- s2->setParent(&machine);
- QCOMPARE(s2->parentState(), static_cast<QState*>(&machine));
- TEST_ACTIVE_CHANGED(s1, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
-}
-
-void tst_QStateMachine::machineWithParent()
-{
- QObject object;
- QStateMachine *machine = new QStateMachine(&object);
- QCOMPARE(machine->parent(), &object);
- QCOMPARE(machine->parentState(), static_cast<QState*>(0));
-}
-
-#ifdef QT_BUILD_INTERNAL
-void tst_QStateMachine::addAndRemoveState()
-{
- QStateMachine machine;
- QStatePrivate *root_d = QStatePrivate::get(&machine);
- QCOMPARE(root_d->childStates().size(), 0);
-
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: cannot add null state");
- machine.addState(0);
-
- QState *s1 = new QState();
- QCOMPARE(s1->parentState(), (QState*)0);
- QCOMPARE(s1->machine(), (QStateMachine*)0);
- machine.addState(s1);
- QCOMPARE(s1->machine(), static_cast<QStateMachine*>(&machine));
- QCOMPARE(s1->parentState(), static_cast<QState*>(&machine));
- QCOMPARE(root_d->childStates().size(), 1);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s1);
-
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine");
- machine.addState(s1);
-
- QState *s2 = new QState();
- QCOMPARE(s2->parentState(), (QState*)0);
- machine.addState(s2);
- QCOMPARE(s2->parentState(), static_cast<QState*>(&machine));
- QCOMPARE(root_d->childStates().size(), 2);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s1);
- QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2);
-
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine");
- machine.addState(s2);
-
- machine.removeState(s1);
- QCOMPARE(s1->parentState(), (QState*)0);
- QCOMPARE(root_d->childStates().size(), 1);
- QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s2);
-
- machine.removeState(s2);
- QCOMPARE(s2->parentState(), (QState*)0);
- QCOMPARE(root_d->childStates().size(), 0);
-
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::removeState: cannot remove null state");
- machine.removeState(0);
-
- {
- QStateMachine machine2;
- {
- const QString warning
- = QString::asprintf("QStateMachine::removeState: state %p's machine (%p) is different from this machine (%p)",
- &machine2, (void*)0, &machine);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- machine.removeState(&machine2);
- }
- // ### check this behavior
- machine.addState(&machine2);
- QCOMPARE(machine2.parent(), (QObject*)&machine);
- }
-
- delete s1;
- delete s2;
- // ### how to deal with this?
- // machine.removeState(machine.errorState());
-}
-#endif
-
-void tst_QStateMachine::stateEntryAndExit()
-{
- // Two top-level states
- {
- QStateMachine machine;
-
- TestState *s1 = new TestState(&machine);
- QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state");
- s1->addTransition((QAbstractState*)0);
- QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add null transition");
- s1->addTransition((QAbstractTransition*)0);
- QTest::ignoreMessage(QtWarningMsg, "QState::removeTransition: cannot remove null transition");
- s1->removeTransition((QAbstractTransition*)0);
-
- TestState *s2 = new TestState(&machine);
- QFinalState *s3 = new QFinalState(&machine);
-
- TestTransition *t = new TestTransition(s2);
- QCOMPARE(t->machine(), (QStateMachine*)0);
- QCOMPARE(t->sourceState(), (QState*)0);
- QCOMPARE(t->targetState(), (QAbstractState*)s2);
- QCOMPARE(t->targetStates().size(), 1);
- QCOMPARE(t->targetStates().at(0), (QAbstractState*)s2);
- t->setTargetState(0);
- QCOMPARE(t->targetState(), (QAbstractState*)0);
- QVERIFY(t->targetStates().isEmpty());
- t->setTargetState(s2);
- QCOMPARE(t->targetState(), (QAbstractState*)s2);
- QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: target state(s) cannot be null");
- t->setTargetStates(QList<QAbstractState*>() << 0);
- QCOMPARE(t->targetState(), (QAbstractState*)s2);
- t->setTargetStates(QList<QAbstractState*>() << s2);
- QCOMPARE(t->targetState(), (QAbstractState*)s2);
- QCOMPARE(t->targetStates().size(), 1);
- QCOMPARE(t->targetStates().at(0), (QAbstractState*)s2);
- s1->addTransition(t);
- QCOMPARE(t->sourceState(), (QState*)s1);
- QCOMPARE(t->machine(), &machine);
-
- {
- QAbstractTransition *trans = s2->addTransition(s3);
- QVERIFY(trans != 0);
- QCOMPARE(trans->sourceState(), (QState*)s2);
- QCOMPARE(trans->targetState(), (QAbstractState*)s3);
- {
- const QString warning
- = QString::asprintf("QState::removeTransition: transition %p's source state (%p) is different from this state (%p)", trans, s2, s1);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- s1->removeTransition(trans);
- }
- s2->removeTransition(trans);
- QCOMPARE(trans->sourceState(), (QState*)0);
- QCOMPARE(trans->targetState(), (QAbstractState*)s3);
- s2->addTransition(trans);
- QCOMPARE(trans->sourceState(), (QState*)s2);
- }
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
-
- QVERIFY(startedSpy.isValid());
- QVERIFY(stoppedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
-
- machine.setInitialState(s1);
- QCOMPARE(machine.initialState(), (QAbstractState*)s1);
- {
- QString warning
- = QString::asprintf("QState::setInitialState: state %p is not a child of this state (%p)", &machine, &machine);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- machine.setInitialState(&machine);
- QCOMPARE(machine.initialState(), (QAbstractState*)s1);
- }
- QVERIFY(machine.configuration().isEmpty());
- globalTick = 0;
- QVERIFY(!machine.isRunning());
- QSignalSpy s1EnteredSpy(s1, &TestState::entered);
- QSignalSpy s1ExitedSpy(s1, &TestState::exited);
- QSignalSpy tTriggeredSpy(t, &TestTransition::triggered);
- QSignalSpy s2EnteredSpy(s2, &TestState::entered);
- QSignalSpy s2ExitedSpy(s2, &TestState::exited);
-
- QVERIFY(s1EnteredSpy.isValid());
- QVERIFY(s1ExitedSpy.isValid());
- QVERIFY(tTriggeredSpy.isValid());
- QVERIFY(s2EnteredSpy.isValid());
- QVERIFY(s2ExitedSpy.isValid());
-
- machine.start();
-
- QTRY_COMPARE(startedSpy.count(), 1);
- QTRY_COMPARE(finishedSpy.count(), 1);
- QTRY_COMPARE(stoppedSpy.count(), 0);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s3));
-
- // s1 is entered
- QCOMPARE(s1->events.count(), 2);
- QCOMPARE(s1->events.at(0).first, 0);
- QCOMPARE(s1->events.at(0).second, TestState::Entry);
- // s1 is exited
- QCOMPARE(s1->events.at(1).first, 1);
- QCOMPARE(s1->events.at(1).second, TestState::Exit);
- // t is triggered
- QCOMPARE(t->triggers.count(), 1);
- QCOMPARE(t->triggers.at(0), 2);
- // s2 is entered
- QCOMPARE(s2->events.count(), 2);
- QCOMPARE(s2->events.at(0).first, 3);
- QCOMPARE(s2->events.at(0).second, TestState::Entry);
- // s2 is exited
- QCOMPARE(s2->events.at(1).first, 4);
- QCOMPARE(s2->events.at(1).second, TestState::Exit);
-
- QCOMPARE(s1EnteredSpy.count(), 1);
- QCOMPARE(s1ExitedSpy.count(), 1);
- QCOMPARE(tTriggeredSpy.count(), 1);
- QCOMPARE(s2EnteredSpy.count(), 1);
- QCOMPARE(s2ExitedSpy.count(), 1);
- }
- // Two top-level states, one has two child states
- {
- QStateMachine machine;
-
- TestState *s1 = new TestState(&machine, "s1");
- TestState *s11 = new TestState(s1, "s11");
- TestState *s12 = new TestState(s1, "s12");
- TestState *s2 = new TestState(&machine, "s2");
- QFinalState *s3 = new QFinalState(&machine);
- s3->setObjectName("s3");
- s1->setInitialState(s11);
- TestTransition *t1 = new TestTransition(s12, "t1");
- s11->addTransition(t1);
- TestTransition *t2 = new TestTransition(s2, "t2");
- s12->addTransition(t2);
- s2->addTransition(s3);
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.setInitialState(s1);
- globalTick = 0;
- machine.start();
-
- QTRY_COMPARE(startedSpy.count(), 1);
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s3));
-
- // s1 is entered
- QCOMPARE(s1->events.count(), 2);
- QCOMPARE(s1->events.at(0).first, 0);
- QCOMPARE(s1->events.at(0).second, TestState::Entry);
- // s11 is entered
- QCOMPARE(s11->events.count(), 2);
- QCOMPARE(s11->events.at(0).first, 1);
- QCOMPARE(s11->events.at(0).second, TestState::Entry);
- // s11 is exited
- QCOMPARE(s11->events.at(1).first, 2);
- QCOMPARE(s11->events.at(1).second, TestState::Exit);
- // t1 is triggered
- QCOMPARE(t1->triggers.count(), 1);
- QCOMPARE(t1->triggers.at(0), 3);
- // s12 is entered
- QCOMPARE(s12->events.count(), 2);
- QCOMPARE(s12->events.at(0).first, 4);
- QCOMPARE(s12->events.at(0).second, TestState::Entry);
- // s12 is exited
- QCOMPARE(s12->events.at(1).first, 5);
- QCOMPARE(s12->events.at(1).second, TestState::Exit);
- // s1 is exited
- QCOMPARE(s1->events.at(1).first, 6);
- QCOMPARE(s1->events.at(1).second, TestState::Exit);
- // t2 is triggered
- QCOMPARE(t2->triggers.count(), 1);
- QCOMPARE(t2->triggers.at(0), 7);
- // s2 is entered
- QCOMPARE(s2->events.count(), 2);
- QCOMPARE(s2->events.at(0).first, 8);
- QCOMPARE(s2->events.at(0).second, TestState::Entry);
- // s2 is exited
- QCOMPARE(s2->events.at(1).first, 9);
- QCOMPARE(s2->events.at(1).second, TestState::Exit);
- }
-}
-
-void tst_QStateMachine::assignProperty()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
-
- QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object");
- s1->assignProperty(0, "foo", QVariant());
-
- s1->assignProperty(s1, "objectName", "s1");
- QFinalState *s2 = new QFinalState(&machine);
- s1->addTransition(s2);
- machine.setInitialState(s1);
- machine.start();
- QTRY_COMPARE(s1->objectName(), QString::fromLatin1("s1"));
- TEST_ACTIVE_CHANGED(s1, 2);
-
- s1->assignProperty(s1, "objectName", "foo");
- machine.start();
- QTRY_COMPARE(s1->objectName(), QString::fromLatin1("foo"));
- TEST_ACTIVE_CHANGED(s1, 4);
-
- s1->assignProperty(s1, "noSuchProperty", 123);
- machine.start();
- QTRY_COMPARE(s1->dynamicPropertyNames().size(), 1);
- QCOMPARE(s1->dynamicPropertyNames().at(0), QByteArray("noSuchProperty"));
- QCOMPARE(s1->objectName(), QString::fromLatin1("foo"));
- TEST_ACTIVE_CHANGED(s1, 6);
-
- {
- QSignalSpy propertiesAssignedSpy(s1, &QState::propertiesAssigned);
- QVERIFY(propertiesAssignedSpy.isValid());
- machine.start();
- QTRY_COMPARE(propertiesAssignedSpy.count(), 1);
- TEST_ACTIVE_CHANGED(s1, 8);
- }
-
- // nested states
- {
- QState *s11 = new QState(s1);
- DEFINE_ACTIVE_SPY(s11);
- QString str = QString::fromLatin1("set by nested state");
- s11->assignProperty(s11, "objectName", str);
- s1->setInitialState(s11);
- machine.start();
- QTRY_COMPARE(s11->objectName(), str);
- TEST_ACTIVE_CHANGED(s1, 10);
- TEST_ACTIVE_CHANGED(s11, 2);
- }
-}
-
-void tst_QStateMachine::assignPropertyWithAnimation()
-{
- // Single animation
- {
- QStateMachine machine;
- QVERIFY(machine.isAnimated());
- machine.setAnimated(false);
- QVERIFY(!machine.isAnimated());
- machine.setAnimated(true);
- QVERIFY(machine.isAnimated());
- QObject obj;
- obj.setProperty("foo", 321);
- obj.setProperty("bar", 654);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(&obj, "foo", 123);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(&obj, "foo", 456);
- s2->assignProperty(&obj, "bar", 789);
- QAbstractTransition *trans = s1->addTransition(s2);
- QVERIFY(trans->animations().isEmpty());
- QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::addAnimation: cannot add null animation");
- trans->addAnimation(0);
- QPropertyAnimation anim(&obj, "foo");
- anim.setDuration(250);
- trans->addAnimation(&anim);
- QCOMPARE(trans->animations().size(), 1);
- QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim);
- QCOMPARE(anim.parent(), (QObject*)0);
- QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::removeAnimation: cannot remove null animation");
- trans->removeAnimation(0);
- trans->removeAnimation(&anim);
- QVERIFY(trans->animations().isEmpty());
- trans->addAnimation(&anim);
- QCOMPARE(trans->animations().size(), 1);
- QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim);
- QFinalState *s3 = new QFinalState(&machine);
- s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
-
- machine.setInitialState(s1);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(obj.property("foo").toInt(), 456);
- QCOMPARE(obj.property("bar").toInt(), 789);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- }
- // Two animations
- {
- QStateMachine machine;
- QObject obj;
- obj.setProperty("foo", 321);
- obj.setProperty("bar", 654);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(&obj, "foo", 123);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(&obj, "foo", 456);
- s2->assignProperty(&obj, "bar", 789);
- QAbstractTransition *trans = s1->addTransition(s2);
- QPropertyAnimation anim(&obj, "foo");
- anim.setDuration(150);
- trans->addAnimation(&anim);
- QPropertyAnimation anim2(&obj, "bar");
- anim2.setDuration(150);
- trans->addAnimation(&anim2);
- QFinalState *s3 = new QFinalState(&machine);
- s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
-
- machine.setInitialState(s1);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(obj.property("foo").toInt(), 456);
- QCOMPARE(obj.property("bar").toInt(), 789);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- }
- // Animation group
- {
- QStateMachine machine;
- QObject obj;
- obj.setProperty("foo", 321);
- obj.setProperty("bar", 654);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(&obj, "foo", 123);
- s1->assignProperty(&obj, "bar", 321);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(&obj, "foo", 456);
- s2->assignProperty(&obj, "bar", 654);
- s2->assignProperty(&obj, "baz", 789);
- QAbstractTransition *trans = s1->addTransition(s2);
- QSequentialAnimationGroup group;
- group.addAnimation(new QPropertyAnimation(&obj, "foo"));
- group.addAnimation(new QPropertyAnimation(&obj, "bar"));
- trans->addAnimation(&group);
- QFinalState *s3 = new QFinalState(&machine);
- s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
-
- machine.setInitialState(s1);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(obj.property("foo").toInt(), 456);
- QCOMPARE(obj.property("bar").toInt(), 654);
- QCOMPARE(obj.property("baz").toInt(), 789);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- }
- // Nested states
- {
- QStateMachine machine;
- QObject obj;
- obj.setProperty("foo", 321);
- obj.setProperty("bar", 654);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QCOMPARE(s1->childMode(), QState::ExclusiveStates);
- s1->setChildMode(QState::ParallelStates);
- QCOMPARE(s1->childMode(), QState::ParallelStates);
- s1->setChildMode(QState::ExclusiveStates);
- QCOMPARE(s1->childMode(), QState::ExclusiveStates);
- QCOMPARE(s1->initialState(), (QAbstractState*)0);
- s1->setObjectName("s1");
- s1->assignProperty(&obj, "foo", 123);
- s1->assignProperty(&obj, "bar", 456);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->setObjectName("s2");
- s2->assignProperty(&obj, "foo", 321);
- QState *s21 = new QState(s2);
- DEFINE_ACTIVE_SPY(s21);
- s21->setObjectName("s21");
- s21->assignProperty(&obj, "bar", 654);
- QState *s22 = new QState(s2);
- DEFINE_ACTIVE_SPY(s22);
- s22->setObjectName("s22");
- s22->assignProperty(&obj, "bar", 789);
- s2->setInitialState(s21);
- QCOMPARE(s2->initialState(), (QAbstractState*)s21);
-
- QAbstractTransition *trans = s1->addTransition(s2);
- QPropertyAnimation anim(&obj, "foo");
- anim.setDuration(500);
- trans->addAnimation(&anim);
- QPropertyAnimation anim2(&obj, "bar");
- anim2.setDuration(250);
- trans->addAnimation(&anim2);
-
- s21->addTransition(s21, SIGNAL(propertiesAssigned()), s22);
-
- QFinalState *s3 = new QFinalState(&machine);
- s22->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
-
- machine.setInitialState(s1);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(obj.property("foo").toInt(), 321);
- QCOMPARE(obj.property("bar").toInt(), 789);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s21, 2);
- TEST_ACTIVE_CHANGED(s22, 2);
- }
- // Aborted animation
- {
- QStateMachine machine;
- SignalEmitter emitter;
- QObject obj;
- obj.setProperty("foo", 321);
- obj.setProperty("bar", 654);
- QState *group = new QState(&machine);
- QState *s1 = new QState(group);
- DEFINE_ACTIVE_SPY(s1);
- group->setInitialState(s1);
- s1->assignProperty(&obj, "foo", 123);
- QState *s2 = new QState(group);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(&obj, "foo", 456);
- s2->assignProperty(&obj, "bar", 789);
- QAbstractTransition *trans = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
- QPropertyAnimation anim(&obj, "foo");
- anim.setDuration(8000);
- trans->addAnimation(&anim);
- QPropertyAnimation anim2(&obj, "bar");
- anim2.setDuration(8000);
- trans->addAnimation(&anim2);
- QState *s3 = new QState(group);
- DEFINE_ACTIVE_SPY(s3);
- s3->assignProperty(&obj, "foo", 911);
- s2->addTransition(&emitter, SIGNAL(signalWithNoArg()), s3);
-
- machine.setInitialState(group);
- machine.start();
- QTRY_COMPARE(machine.configuration().contains(s1), true);
- QSignalSpy propertiesAssignedSpy(s2, &QState::propertiesAssigned);
- QVERIFY(propertiesAssignedSpy.isValid());
- emitter.emitSignalWithNoArg();
- QTRY_COMPARE(machine.configuration().contains(s2), true);
- QVERIFY(propertiesAssignedSpy.isEmpty());
- emitter.emitSignalWithNoArg(); // will cause animations from s1-->s2 to abort
- QTRY_COMPARE(machine.configuration().contains(s3), true);
- QVERIFY(propertiesAssignedSpy.isEmpty());
- QCOMPARE(obj.property("foo").toInt(), 911);
- QCOMPARE(obj.property("bar").toInt(), 789);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- }
-}
-
-struct StringEvent : public QEvent
-{
-public:
- StringEvent(const QString &val)
- : QEvent(QEvent::Type(QEvent::User+2)),
- value(val) {}
-
- QString value;
-};
-
-class StringTransition : public QAbstractTransition
-{
-public:
- StringTransition(const QString &value, QAbstractState *target)
- : QAbstractTransition(), m_value(value)
- { setTargetState(target); }
-
-protected:
- virtual bool eventTest(QEvent *e)
- {
- if (e->type() != QEvent::Type(QEvent::User+2))
- return false;
- StringEvent *se = static_cast<StringEvent*>(e);
- return (m_value == se->value) && (!m_cond.isValid() || (m_cond.indexIn(m_value) != -1));
- }
- virtual void onTransition(QEvent *) {}
-
-private:
- QString m_value;
- QRegExp m_cond;
-};
-
-class StringEventPoster : public QState
-{
-public:
- StringEventPoster(const QString &value, QState *parent = 0)
- : QState(parent), m_value(value), m_delay(-1) {}
-
- void setString(const QString &value)
- { m_value = value; }
- void setDelay(int delay)
- { m_delay = delay; }
-
-protected:
- virtual void onEntry(QEvent *)
- {
- if (m_delay == -1)
- machine()->postEvent(new StringEvent(m_value));
- else
- machine()->postDelayedEvent(new StringEvent(m_value), m_delay);
- }
- virtual void onExit(QEvent *) {}
-
-private:
- QString m_value;
- int m_delay;
-};
-
-void tst_QStateMachine::postEvent()
-{
- for (int x = 0; x < 2; ++x) {
- QStateMachine machine;
- {
- QEvent e(QEvent::None);
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::postEvent: cannot post event when the state machine is not running");
- machine.postEvent(&e);
- }
- StringEventPoster *s1 = new StringEventPoster("a");
- DEFINE_ACTIVE_SPY(s1);
- if (x == 1)
- s1->setDelay(100);
- QFinalState *s2 = new QFinalState;
- s1->addTransition(new StringTransition("a", s2));
- machine.addState(s1);
- machine.addState(s2);
- machine.setInitialState(s1);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
- TEST_ACTIVE_CHANGED(s1, 2);
-
- s1->setString("b");
- QFinalState *s3 = new QFinalState();
- machine.addState(s3);
- s1->addTransition(new StringTransition("b", s3));
- finishedSpy.clear();
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s3));
- TEST_ACTIVE_CHANGED(s1, 4);
- }
-}
-
-void tst_QStateMachine::cancelDelayedEvent()
-{
- QStateMachine machine;
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::cancelDelayedEvent: the machine is not running");
- QVERIFY(!machine.cancelDelayedEvent(-1));
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QFinalState *s2 = new QFinalState(&machine);
- s1->addTransition(new StringTransition("a", s2));
- machine.setInitialState(s1);
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- int id1 = machine.postDelayedEvent(new StringEvent("c"), 50000);
- QVERIFY(id1 != -1);
- int id2 = machine.postDelayedEvent(new StringEvent("b"), 25000);
- QVERIFY(id2 != -1);
- QVERIFY(id2 != id1);
- int id3 = machine.postDelayedEvent(new StringEvent("a"), 100);
- QVERIFY(id3 != -1);
- QVERIFY(id3 != id2);
- QVERIFY(machine.cancelDelayedEvent(id1));
- QVERIFY(!machine.cancelDelayedEvent(id1));
- QVERIFY(machine.cancelDelayedEvent(id2));
- QVERIFY(!machine.cancelDelayedEvent(id2));
-
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- TEST_ACTIVE_CHANGED(s1, 2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-}
-
-void tst_QStateMachine::postDelayedEventAndStop()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QFinalState *s2 = new QFinalState(&machine);
- s1->addTransition(new StringTransition("a", s2));
- machine.setInitialState(s1);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- int id1 = machine.postDelayedEvent(new StringEvent("a"), 0);
- QVERIFY(id1 != -1);
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QVERIFY(stoppedSpy.isValid());
- machine.stop();
- QTRY_COMPARE(stoppedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 2);
- TEST_RUNNING_CHANGED(true);
- TEST_ACTIVE_CHANGED(s1, 3);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- int id2 = machine.postDelayedEvent(new StringEvent("a"), 1000);
- QVERIFY(id2 != -1);
- machine.stop();
- QTRY_COMPARE(stoppedSpy.count(), 2);
- TEST_RUNNING_CHANGED(false);
- TEST_ACTIVE_CHANGED(s1, 3);
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 3);
- TEST_RUNNING_CHANGED(true);
- QTestEventLoop::instance().enterLoop(2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- TEST_ACTIVE_CHANGED(s1, 5);
- QVERIFY(machine.isRunning());
-}
-
-class DelayedEventPosterThread : public QThread
-{
- Q_OBJECT
-public:
- DelayedEventPosterThread(QStateMachine *machine, QObject *parent = 0)
- : QThread(parent), firstEventWasCancelled(false),
- m_machine(machine)
- {
- moveToThread(this);
- QObject::connect(m_machine, SIGNAL(started()),
- this, SLOT(postEvent()));
- }
-
- mutable bool firstEventWasCancelled;
-
-private Q_SLOTS:
- void postEvent()
- {
- int id = m_machine->postDelayedEvent(new QEvent(QEvent::User), 1000);
- firstEventWasCancelled = m_machine->cancelDelayedEvent(id);
-
- m_machine->postDelayedEvent(new QEvent(QEvent::User), 1);
-
- quit();
- }
-private:
- QStateMachine *m_machine;
-};
-
-void tst_QStateMachine::postDelayedEventFromThread()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QFinalState *f = new QFinalState(&machine);
- s1->addTransition(new EventTransition(QEvent::User, f));
- machine.setInitialState(s1);
-
- DelayedEventPosterThread poster(&machine);
- poster.start();
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s1, 2);
- QVERIFY(poster.firstEventWasCancelled);
-}
-
-void tst_QStateMachine::stopAndPostEvent()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- TEST_ACTIVE_CHANGED(s1, 1);
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QVERIFY(stoppedSpy.isValid());
- machine.stop();
- QCOMPARE(stoppedSpy.count(), 0);
- machine.postEvent(new QEvent(QEvent::User));
- QTRY_COMPARE(stoppedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCoreApplication::processEvents();
-}
-
-void tst_QStateMachine::stateFinished()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QState *s1_1 = new QState(s1);
- DEFINE_ACTIVE_SPY(s1_1);
- QFinalState *s1_2 = new QFinalState(s1);
- s1_1->addTransition(s1_2);
- s1->setInitialState(s1_1);
- QFinalState *s2 = new QFinalState(&machine);
- s1->addTransition(s1, SIGNAL(finished()), s2);
- machine.setInitialState(s1);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s1_1, 2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-}
-
-void tst_QStateMachine::parallelStates()
-{
- QStateMachine machine;
-
- TestState *s1 = new TestState(QState::ParallelStates);
- QCOMPARE(s1->childMode(), QState::ParallelStates);
- TestState *s1_1 = new TestState(s1);
- QState *s1_1_1 = new QState(s1_1);
- QFinalState *s1_1_f = new QFinalState(s1_1);
- s1_1_1->addTransition(s1_1_f);
- s1_1->setInitialState(s1_1_1);
- TestState *s1_2 = new TestState(s1);
- QState *s1_2_1 = new QState(s1_2);
- QFinalState *s1_2_f = new QFinalState(s1_2);
- s1_2_1->addTransition(s1_2_f);
- s1_2->setInitialState(s1_2_1);
- {
- const QString warning
- = QString::asprintf("QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", s1);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- s1->setInitialState(0);
- }
- machine.addState(s1);
-
- QFinalState *s2 = new QFinalState();
- machine.addState(s2);
-
- s1->addTransition(s1, SIGNAL(finished()), s2);
-
- machine.setInitialState(s1);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- globalTick = 0;
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-
- QCOMPARE(s1->events.count(), 2);
- // s1 is entered
- QCOMPARE(s1->events.at(0).first, 0);
- QCOMPARE(s1->events.at(0).second, TestState::Entry);
- // s1_1 is entered
- QCOMPARE(s1_1->events.count(), 2);
- QCOMPARE(s1_1->events.at(0).first, 1);
- QCOMPARE(s1_1->events.at(0).second, TestState::Entry);
- // s1_2 is entered
- QCOMPARE(s1_2->events.at(0).first, 2);
- QCOMPARE(s1_2->events.at(0).second, TestState::Entry);
- // s1_2 is exited
- QCOMPARE(s1_2->events.at(1).first, 3);
- QCOMPARE(s1_2->events.at(1).second, TestState::Exit);
- // s1_1 is exited
- QCOMPARE(s1_1->events.at(1).first, 4);
- QCOMPARE(s1_1->events.at(1).second, TestState::Exit);
- // s1 is exited
- QCOMPARE(s1->events.at(1).first, 5);
- QCOMPARE(s1->events.at(1).second, TestState::Exit);
-}
-
-void tst_QStateMachine::parallelRootState()
-{
- QStateMachine machine;
- QState *root = &machine;
- QCOMPARE(root->childMode(), QState::ExclusiveStates);
- root->setChildMode(QState::ParallelStates);
- QCOMPARE(root->childMode(), QState::ParallelStates);
-
- QState *s1 = new QState(root);
- DEFINE_ACTIVE_SPY(s1);
- QFinalState *s1_f = new QFinalState(s1);
- s1->setInitialState(s1_f);
- QState *s2 = new QState(root);
- DEFINE_ACTIVE_SPY(s2);
- QFinalState *s2_f = new QFinalState(s2);
- s2->setInitialState(s2_f);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(machine.configuration().size(), 4);
- QVERIFY(machine.configuration().contains(s1));
- QVERIFY(machine.configuration().contains(s1_f));
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s2_f));
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 1);
- QVERIFY(!machine.isRunning());
-}
-
-void tst_QStateMachine::allSourceToTargetConfigurations()
-{
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- s0->setObjectName("s0");
- QState *s1 = new QState(s0);
- DEFINE_ACTIVE_SPY(s1);
- s1->setObjectName("s1");
- QState *s11 = new QState(s1);
- DEFINE_ACTIVE_SPY(s11);
- s11->setObjectName("s11");
- QState *s2 = new QState(s0);
- DEFINE_ACTIVE_SPY(s2);
- s2->setObjectName("s2");
- QState *s21 = new QState(s2);
- DEFINE_ACTIVE_SPY(s21);
- s21->setObjectName("s21");
- QState *s211 = new QState(s21);
- DEFINE_ACTIVE_SPY(s211);
- s211->setObjectName("s211");
- QFinalState *f = new QFinalState(&machine);
- f->setObjectName("f");
-
- s0->setInitialState(s1);
- s1->setInitialState(s11);
- s2->setInitialState(s21);
- s21->setInitialState(s211);
-
- s11->addTransition(new StringTransition("g", s211));
- s1->addTransition(new StringTransition("a", s1));
- s1->addTransition(new StringTransition("b", s11));
- s1->addTransition(new StringTransition("c", s2));
- s1->addTransition(new StringTransition("d", s0));
- s1->addTransition(new StringTransition("f", s211));
- s211->addTransition(new StringTransition("d", s21));
- s211->addTransition(new StringTransition("g", s0));
- s211->addTransition(new StringTransition("h", f));
- s21->addTransition(new StringTransition("b", s211));
- s2->addTransition(new StringTransition("c", s1));
- s2->addTransition(new StringTransition("f", s11));
- s0->addTransition(new StringTransition("e", s211));
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s21, 0);
- TEST_ACTIVE_CHANGED(s211, 0);
-
- machine.postEvent(new StringEvent("a"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 3);
- TEST_ACTIVE_CHANGED(s11, 3);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s21, 0);
- TEST_ACTIVE_CHANGED(s211, 0);
-
- machine.postEvent(new StringEvent("b"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 5);
- TEST_ACTIVE_CHANGED(s11, 5);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s21, 0);
- TEST_ACTIVE_CHANGED(s211, 0);
-
- machine.postEvent(new StringEvent("c"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 6);
- TEST_ACTIVE_CHANGED(s11, 6);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 1);
- TEST_ACTIVE_CHANGED(s211, 1);
-
- machine.postEvent(new StringEvent("d"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 6);
- TEST_ACTIVE_CHANGED(s11, 6);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 3);
- TEST_ACTIVE_CHANGED(s211, 3);
-
- machine.postEvent(new StringEvent("e"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s1, 6);
- TEST_ACTIVE_CHANGED(s11, 6);
- TEST_ACTIVE_CHANGED(s2, 3);
- TEST_ACTIVE_CHANGED(s21, 5);
- TEST_ACTIVE_CHANGED(s211, 5);
-
- machine.postEvent(new StringEvent("f"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s1, 7);
- TEST_ACTIVE_CHANGED(s11, 7);
- TEST_ACTIVE_CHANGED(s2, 4);
- TEST_ACTIVE_CHANGED(s21, 6);
- TEST_ACTIVE_CHANGED(s211, 6);
-
- machine.postEvent(new StringEvent("g"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s1, 8);
- TEST_ACTIVE_CHANGED(s11, 8);
- TEST_ACTIVE_CHANGED(s2, 5);
- TEST_ACTIVE_CHANGED(s21, 7);
- TEST_ACTIVE_CHANGED(s211, 7);
-
- machine.postEvent(new StringEvent("h"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 4);
- TEST_ACTIVE_CHANGED(s1, 8);
- TEST_ACTIVE_CHANGED(s11, 8);
- TEST_ACTIVE_CHANGED(s2, 6);
- TEST_ACTIVE_CHANGED(s21, 8);
- TEST_ACTIVE_CHANGED(s211, 8);
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-}
-
-class TestSignalTransition : public QSignalTransition
-{
-public:
- TestSignalTransition(QState *sourceState = 0)
- : QSignalTransition(sourceState),
- m_eventTestSender(0), m_eventTestSignalIndex(-1),
- m_transitionSender(0), m_transitionSignalIndex(-1)
- {}
- TestSignalTransition(QObject *sender, const char *signal,
- QAbstractState *target)
- : QSignalTransition(sender, signal),
- m_eventTestSender(0), m_eventTestSignalIndex(-1),
- m_transitionSender(0), m_transitionSignalIndex(-1)
- { setTargetState(target); }
- QObject *eventTestSenderReceived() const {
- return m_eventTestSender;
- }
- int eventTestSignalIndexReceived() const {
- return m_eventTestSignalIndex;
- }
- QVariantList eventTestArgumentsReceived() const {
- return m_eventTestArgs;
- }
- QObject *transitionSenderReceived() const {
- return m_transitionSender;
- }
- int transitionSignalIndexReceived() const {
- return m_transitionSignalIndex;
- }
- QVariantList transitionArgumentsReceived() const {
- return m_transitionArgs;
- }
-protected:
- bool eventTest(QEvent *e) {
- if (!QSignalTransition::eventTest(e))
- return false;
- QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e);
- m_eventTestSender = se->sender();
- m_eventTestSignalIndex = se->signalIndex();
- m_eventTestArgs = se->arguments();
- return true;
- }
- void onTransition(QEvent *e) {
- QSignalTransition::onTransition(e);
- QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e);
- m_transitionSender = se->sender();
- m_transitionSignalIndex = se->signalIndex();
- m_transitionArgs = se->arguments();
- }
-private:
- QObject *m_eventTestSender;
- int m_eventTestSignalIndex;
- QVariantList m_eventTestArgs;
- QObject *m_transitionSender;
- int m_transitionSignalIndex;
- QVariantList m_transitionArgs;
-};
-
-void tst_QStateMachine::signalTransitions()
-{
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null");
- QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QSignalTransition*)0);
-
- SignalEmitter emitter;
- QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: signal cannot be null");
- QCOMPARE(s0->addTransition(&emitter, 0, 0), (QSignalTransition*)0);
-
- QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state");
- QCOMPARE(s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), 0), (QSignalTransition*)0);
-
- QFinalState *s1 = new QFinalState(&machine);
- QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: no such signal SignalEmitter::noSuchSignal()");
- QCOMPARE(s0->addTransition(&emitter, SIGNAL(noSuchSignal()), s1), (QSignalTransition*)0);
-
- QSignalTransition *trans = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
- QVERIFY(trans != 0);
- QCOMPARE(trans->sourceState(), s0);
- QCOMPARE(trans->targetState(), (QAbstractState*)s1);
- QCOMPARE(trans->senderObject(), (QObject*)&emitter);
- QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg())));
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
-
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 2);
- emitter.emitSignalWithNoArg();
-
- trans->setSignal(SIGNAL(signalWithIntArg(int)));
- QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithIntArg(int))));
- machine.start();
- QCoreApplication::processEvents();
- emitter.emitSignalWithIntArg(123);
- QTRY_COMPARE(finishedSpy.count(), 2);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 4);
-
- machine.start();
- QCoreApplication::processEvents();
- trans->setSignal(SIGNAL(signalWithNoArg()));
- QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg())));
- emitter.emitSignalWithNoArg();
- QTRY_COMPARE(finishedSpy.count(), 3);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 6);
-
- SignalEmitter emitter2;
- machine.start();
- QCoreApplication::processEvents();
- trans->setSenderObject(&emitter2);
- emitter2.emitSignalWithNoArg();
- QTRY_COMPARE(finishedSpy.count(), 4);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 8);
-
- machine.start();
- QCoreApplication::processEvents();
- QTest::ignoreMessage(QtWarningMsg, "QSignalTransition: no such signal: SignalEmitter::noSuchSignal()");
- trans->setSignal(SIGNAL(noSuchSignal()));
- QCOMPARE(trans->signal(), QByteArray(SIGNAL(noSuchSignal())));
- TEST_RUNNING_CHANGED(true);
- TEST_ACTIVE_CHANGED(s0, 9);
- QVERIFY(machine.isRunning());
- }
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QFinalState *s1 = new QFinalState(&machine);
- SignalEmitter emitter;
- QSignalTransition *trans = s0->addTransition(&emitter, "signalWithNoArg()", s1);
- QVERIFY(trans != 0);
- QCOMPARE(trans->sourceState(), s0);
- QCOMPARE(trans->targetState(), (QAbstractState*)s1);
- QCOMPARE(trans->senderObject(), (QObject*)&emitter);
- QCOMPARE(trans->signal(), QByteArray("signalWithNoArg()"));
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 2);
-
- trans->setSignal("signalWithIntArg(int)");
- QCOMPARE(trans->signal(), QByteArray("signalWithIntArg(int)"));
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- emitter.emitSignalWithIntArg(123);
- QTRY_COMPARE(finishedSpy.count(), 2);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 4);
- }
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QFinalState *s1 = new QFinalState(&machine);
- SignalEmitter emitter;
- TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- emitter.emitSignalWithIntArg(123);
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 2);
- QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter);
- QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithIntArg(int)"));
- QCOMPARE(trans->eventTestArgumentsReceived().size(), 1);
- QCOMPARE(trans->eventTestArgumentsReceived().at(0).toInt(), 123);
- QCOMPARE(trans->transitionSenderReceived(), (QObject*)&emitter);
- QCOMPARE(trans->transitionSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithIntArg(int)"));
- QCOMPARE(trans->transitionArgumentsReceived().size(), 1);
- QCOMPARE(trans->transitionArgumentsReceived().at(0).toInt(), 123);
- }
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QFinalState *s1 = new QFinalState(&machine);
- SignalEmitter emitter;
- TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
-
- QString testString = QString::fromLatin1("hello");
- emitter.emitSignalWithStringArg(testString);
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 2);
- QCOMPARE(trans->eventTestSenderReceived(), (QObject*)&emitter);
- QCOMPARE(trans->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithStringArg(QString)"));
- QCOMPARE(trans->eventTestArgumentsReceived().size(), 1);
- QCOMPARE(trans->eventTestArgumentsReceived().at(0).toString(), testString);
- QCOMPARE(trans->transitionSenderReceived(), (QObject*)&emitter);
- QCOMPARE(trans->transitionSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithStringArg(QString)"));
- QCOMPARE(trans->transitionArgumentsReceived().size(), 1);
- QCOMPARE(trans->transitionArgumentsReceived().at(0).toString(), testString);
- }
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QFinalState *s1 = new QFinalState(&machine);
-
- TestSignalTransition *trans = new TestSignalTransition();
- QCOMPARE(trans->senderObject(), (QObject*)0);
- QCOMPARE(trans->signal(), QByteArray());
-
- SignalEmitter emitter;
- trans->setSenderObject(&emitter);
- QCOMPARE(trans->senderObject(), (QObject*)&emitter);
- trans->setSignal(SIGNAL(signalWithNoArg()));
- QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg())));
- trans->setTargetState(s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
-
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s0, 2);
- }
- // Multiple transitions for same (object,signal)
- {
- QStateMachine machine;
- SignalEmitter emitter;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
- QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0);
-
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 0);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- emitter.emitSignalWithNoArg();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- s0->removeTransition(t0);
- emitter.emitSignalWithNoArg();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s1, 2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- emitter.emitSignalWithNoArg();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s1, 2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- s1->removeTransition(t1);
- emitter.emitSignalWithNoArg();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s1, 2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- s0->addTransition(t0);
- s1->addTransition(t1);
- emitter.emitSignalWithNoArg();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 4);
- TEST_ACTIVE_CHANGED(s1, 3);
- QVERIFY(machine.isRunning());
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- }
- // multiple signal transitions from same source
- {
- QStateMachine machine;
- SignalEmitter emitter;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QFinalState *s1 = new QFinalState(&machine);
- s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
- QFinalState *s2 = new QFinalState(&machine);
- s0->addTransition(&emitter, SIGNAL(signalWithIntArg(int)), s2);
- QFinalState *s3 = new QFinalState(&machine);
- s0->addTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s3);
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.setInitialState(s0);
-
- machine.start();
- TEST_ACTIVE_CHANGED(s0, 1);
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- emitter.emitSignalWithNoArg();
- TEST_ACTIVE_CHANGED(s0, 2);
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s0, 3);
- QTRY_COMPARE(startedSpy.count(), 2);
- TEST_RUNNING_CHANGED(true);
- emitter.emitSignalWithIntArg(123);
- TEST_ACTIVE_CHANGED(s0, 4);
- QTRY_COMPARE(finishedSpy.count(), 2);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 5);
- QTRY_COMPARE(startedSpy.count(), 3);
- TEST_RUNNING_CHANGED(true);
- emitter.emitSignalWithStringArg("hello");
- TEST_ACTIVE_CHANGED(s0, 6);
- QTRY_COMPARE(finishedSpy.count(), 3);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s3));
- }
- // signature normalization
- {
- QStateMachine machine;
- SignalEmitter emitter;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- QFinalState *s1 = new QFinalState(&machine);
- QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
- QVERIFY(t0 != 0);
- QCOMPARE(t0->signal(), QByteArray(SIGNAL(signalWithNoArg())));
-
- QSignalTransition *t1 = s0->addTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1);
- QVERIFY(t1 != 0);
- QCOMPARE(t1->signal(), QByteArray(SIGNAL(signalWithStringArg(QString))));
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(true);
-
- emitter.emitSignalWithNoArg();
-
- TEST_ACTIVE_CHANGED(s0, 2);
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- }
-}
-
-class TestEventTransition : public QEventTransition
-{
-public:
- TestEventTransition(QState *sourceState = 0)
- : QEventTransition(sourceState),
- m_eventSource(0), m_eventType(QEvent::None)
- {}
- TestEventTransition(QObject *object, QEvent::Type type,
- QAbstractState *target)
- : QEventTransition(object, type),
- m_eventSource(0), m_eventType(QEvent::None)
- { setTargetState(target); }
- QObject *eventSourceReceived() const {
- return m_eventSource;
- }
- QEvent::Type eventTypeReceived() const {
- return m_eventType;
- }
-protected:
- bool eventTest(QEvent *e) {
- if (!QEventTransition::eventTest(e))
- return false;
- QStateMachine::WrappedEvent *we = static_cast<QStateMachine::WrappedEvent*>(e);
- m_eventSource = we->object();
- m_eventType = we->event()->type();
- return true;
- }
-private:
- QObject *m_eventSource;
- QEvent::Type m_eventType;
-};
-
-#ifndef QT_NO_WIDGETS
-void tst_QStateMachine::eventTransitions()
-{
- QPushButton button;
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- QMouseEventTransition *trans;
- trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton);
- QCOMPARE(trans->targetState(), (QAbstractState*)0);
- trans->setTargetState(s1);
- QCOMPARE(trans->eventType(), QEvent::MouseButtonPress);
- QCOMPARE(trans->button(), Qt::LeftButton);
- QCOMPARE(trans->targetState(), (QAbstractState*)s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
-
- QTest::mousePress(&button, Qt::LeftButton);
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-
- QTest::mousePress(&button, Qt::LeftButton);
-
- trans->setEventType(QEvent::MouseButtonRelease);
- QCOMPARE(trans->eventType(), QEvent::MouseButtonRelease);
- machine.start();
- QCoreApplication::processEvents();
- QTest::mouseRelease(&button, Qt::LeftButton);
- QTRY_COMPARE(finishedSpy.count(), 2);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-
- machine.start();
- QCoreApplication::processEvents();
- trans->setEventType(QEvent::MouseButtonPress);
- QTest::mousePress(&button, Qt::LeftButton);
- QTRY_COMPARE(finishedSpy.count(), 3);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-
- QPushButton button2;
- machine.start();
- QCoreApplication::processEvents();
- trans->setEventSource(&button2);
- QTest::mousePress(&button2, Qt::LeftButton);
- QTRY_COMPARE(finishedSpy.count(), 4);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- }
- for (int x = 0; x < 2; ++x) {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- QEventTransition *trans = 0;
- if (x == 0) {
- trans = new QEventTransition();
- QCOMPARE(trans->eventSource(), (QObject*)0);
- QCOMPARE(trans->eventType(), QEvent::None);
- trans->setEventSource(&button);
- trans->setEventType(QEvent::MouseButtonPress);
- trans->setTargetState(s1);
- } else if (x == 1) {
- trans = new QEventTransition(&button, QEvent::MouseButtonPress);
- trans->setTargetState(s1);
- }
- QCOMPARE(trans->eventSource(), (QObject*)&button);
- QCOMPARE(trans->eventType(), QEvent::MouseButtonPress);
- QCOMPARE(trans->targetState(), (QAbstractState*)s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
-
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- }
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- QMouseEventTransition *trans = new QMouseEventTransition();
- QCOMPARE(trans->eventSource(), (QObject*)0);
- QCOMPARE(trans->eventType(), QEvent::None);
- QCOMPARE(trans->button(), Qt::NoButton);
- trans->setEventSource(&button);
- trans->setEventType(QEvent::MouseButtonPress);
- trans->setButton(Qt::LeftButton);
- trans->setTargetState(s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_RUNNING_CHANGED(true);
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- }
-
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- QKeyEventTransition *trans = new QKeyEventTransition(&button, QEvent::KeyPress, Qt::Key_A);
- QCOMPARE(trans->eventType(), QEvent::KeyPress);
- QCOMPARE(trans->key(), (int)Qt::Key_A);
- trans->setTargetState(s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_RUNNING_CHANGED(true);
-
- QTest::keyPress(&button, Qt::Key_A);
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- }
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- QKeyEventTransition *trans = new QKeyEventTransition();
- QCOMPARE(trans->eventSource(), (QObject*)0);
- QCOMPARE(trans->eventType(), QEvent::None);
- QCOMPARE(trans->key(), 0);
- trans->setEventSource(&button);
- trans->setEventType(QEvent::KeyPress);
- trans->setKey(Qt::Key_A);
- trans->setTargetState(s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_RUNNING_CHANGED(true);
-
- QTest::keyPress(&button, Qt::Key_A);
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- }
- // Multiple transitions for same (object,event)
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QState *s1 = new QState(&machine);
- QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress);
- t0->setTargetState(s1);
- s0->addTransition(t0);
- QEventTransition *t1 = new QEventTransition(&button, QEvent::MouseButtonPress);
- t1->setTargetState(s0);
- s1->addTransition(t1);
-
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- s0->removeTransition(t0);
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- s1->removeTransition(t1);
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s0));
-
- s0->addTransition(t0);
- s1->addTransition(t1);
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- }
- // multiple event transitions from same source
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
- QFinalState *s2 = new QFinalState(&machine);
- QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress);
- t0->setTargetState(s1);
- s0->addTransition(t0);
- QEventTransition *t1 = new QEventTransition(&button, QEvent::MouseButtonRelease);
- t1->setTargetState(s2);
- s0->addTransition(t1);
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.setInitialState(s0);
-
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- QTest::mousePress(&button, Qt::LeftButton);
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 2);
- TEST_RUNNING_CHANGED(true);
- QTest::mouseRelease(&button, Qt::LeftButton);
- QTRY_COMPARE(finishedSpy.count(), 2);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
- }
- // custom event
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- QEventTransition *trans = new QEventTransition(&button, QEvent::Type(QEvent::User+1));
- trans->setTargetState(s1);
- s0->addTransition(trans);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QTest::ignoreMessage(QtWarningMsg, "QObject event transitions are not supported for custom types");
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- }
- // custom transition
- {
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- QFinalState *s1 = new QFinalState(&machine);
-
- TestEventTransition *trans = new TestEventTransition(&button, QEvent::MouseButtonPress, s1);
- s0->addTransition(trans);
- QCOMPARE(trans->eventSourceReceived(), (QObject*)0);
- QCOMPARE(trans->eventTypeReceived(), QEvent::None);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.setInitialState(s0);
- machine.start();
- QCoreApplication::processEvents();
- TEST_RUNNING_CHANGED(true);
-
- QTest::mousePress(&button, Qt::LeftButton);
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
-
- QCOMPARE(trans->eventSourceReceived(), (QObject*)&button);
- QCOMPARE(trans->eventTypeReceived(), QEvent::MouseButtonPress);
- }
-}
-
-void tst_QStateMachine::graphicsSceneEventTransitions()
-{
- QGraphicsScene scene;
- QGraphicsTextItem *textItem = scene.addText("foo");
-
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- QFinalState *s2 = new QFinalState(&machine);
- QEventTransition *t = new QEventTransition(textItem, QEvent::GraphicsSceneMouseMove);
- t->setTargetState(s2);
- s1->addTransition(t);
- machine.setInitialState(s1);
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(true);
- QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
- scene.sendEvent(textItem, &mouseEvent);
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
-}
-#endif
-
-void tst_QStateMachine::historyStates()
-{
- for (int x = 0; x < 2; ++x) {
- QStateMachine machine;
- QState *root = &machine;
- QState *s0 = new QState(root);
- DEFINE_ACTIVE_SPY(s0);
- QState *s00 = new QState(s0);
- DEFINE_ACTIVE_SPY(s00);
- QState *s01 = new QState(s0);
- DEFINE_ACTIVE_SPY(s01);
- QHistoryState *s0h;
- if (x == 0) {
- s0h = new QHistoryState(s0);
- QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory);
- s0h->setHistoryType(QHistoryState::DeepHistory);
- } else {
- s0h = new QHistoryState(QHistoryState::DeepHistory, s0);
- }
- QCOMPARE(s0h->historyType(), QHistoryState::DeepHistory);
- s0h->setHistoryType(QHistoryState::ShallowHistory);
- QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory);
- QCOMPARE(s0h->defaultState(), (QAbstractState*)0);
- s0h->setDefaultState(s00);
- QCOMPARE(s0h->defaultState(), (QAbstractState*)s00);
- const QString warning
- = QString::asprintf("QHistoryState::setDefaultState: state %p does not belong to this history state's group (%p)", s0, s0);
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- s0h->setDefaultState(s0);
- QState *s1 = new QState(root);
- DEFINE_ACTIVE_SPY(s1);
- QFinalState *s2 = new QFinalState(root);
-
- s00->addTransition(new StringTransition("a", s01));
- s0->addTransition(new StringTransition("b", s1));
- s1->addTransition(new StringTransition("c", s0h));
- s0->addTransition(new StringTransition("d", s2));
-
- root->setInitialState(s0);
- s0->setInitialState(s00);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s00, 1);
- TEST_ACTIVE_CHANGED(s01, 0);
- TEST_ACTIVE_CHANGED(s1, 0);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s0));
- QVERIFY(machine.configuration().contains(s00));
-
- machine.postEvent(new StringEvent("a"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s00, 2);
- TEST_ACTIVE_CHANGED(s01, 1);
- TEST_ACTIVE_CHANGED(s1, 0);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s0));
- QVERIFY(machine.configuration().contains(s01));
-
- machine.postEvent(new StringEvent("b"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s00, 2);
- TEST_ACTIVE_CHANGED(s01, 2);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.postEvent(new StringEvent("c"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 3);
- TEST_ACTIVE_CHANGED(s00, 2);
- TEST_ACTIVE_CHANGED(s01, 3);
- TEST_ACTIVE_CHANGED(s1, 2);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s0));
- QVERIFY(machine.configuration().contains(s01));
-
- machine.postEvent(new StringEvent("d"));
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s0, 4);
- TEST_ACTIVE_CHANGED(s00, 2);
- TEST_ACTIVE_CHANGED(s01, 4);
- TEST_ACTIVE_CHANGED(s1, 2);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- }
-}
-
-void tst_QStateMachine::startAndStop()
-{
- QStateMachine machine;
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
-
- QVERIFY(startedSpy.isValid());
- QVERIFY(stoppedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
-
- QVERIFY(!machine.isRunning());
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start.");
- machine.start();
- QCOMPARE(startedSpy.count(), 0);
- QCOMPARE(stoppedSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(runningSpy.count(), 0);
- QVERIFY(!machine.isRunning());
- machine.stop();
- QCOMPARE(startedSpy.count(), 0);
- QCOMPARE(stoppedSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(runningSpy.count(), 0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_COMPARE(machine.isRunning(), true);
- QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(stoppedSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running");
- machine.start();
- QCOMPARE(runningSpy.count(), 0);
-
- machine.stop();
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_COMPARE(machine.isRunning(), false);
- QTRY_COMPARE(stoppedSpy.count(), 1);
- QCOMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(false);
-
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 3);
- machine.stop();
- TEST_ACTIVE_CHANGED(s1, 3);
- QTRY_COMPARE(startedSpy.count(), 2);
- QTRY_COMPARE(stoppedSpy.count(), 2);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-}
-
-void tst_QStateMachine::setRunning()
-{
- QStateMachine machine;
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
-
- QVERIFY(startedSpy.isValid());
- QVERIFY(stoppedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
-
- QVERIFY(!machine.isRunning());
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start.");
- machine.setRunning(true);
- QCOMPARE(startedSpy.count(), 0);
- QCOMPARE(stoppedSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(runningSpy.count(), 0);
- QVERIFY(!machine.isRunning());
- machine.setRunning(false);
- QCOMPARE(startedSpy.count(), 0);
- QCOMPARE(stoppedSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(runningSpy.count(), 0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- machine.setRunning(true);
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_COMPARE(machine.isRunning(), true);
- QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(stoppedSpy.count(), 0);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(true);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running");
- machine.setRunning(true);
- TEST_ACTIVE_CHANGED(s1, 1);
- QCOMPARE(runningSpy.count(), 0);
-
- machine.setRunning(false);
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_COMPARE(machine.isRunning(), false);
- QTRY_COMPARE(stoppedSpy.count(), 1);
- QCOMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- machine.setRunning(false);
- QCOMPARE(runningSpy.count(), 0);
- TEST_ACTIVE_CHANGED(s1, 1);
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 3);
- machine.setRunning(false);
- TEST_ACTIVE_CHANGED(s1, 3);
- QTRY_COMPARE(startedSpy.count(), 2);
- QTRY_COMPARE(stoppedSpy.count(), 2);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QState *s1_1 = new QState(s1);
- QFinalState *s1_2 = new QFinalState(s1);
- s1_1->addTransition(s1_2);
- s1->setInitialState(s1_1);
- QFinalState *s2 = new QFinalState(&machine);
- s1->addTransition(s1, SIGNAL(finished()), s2);
- machine.setRunning(false);
- QCOMPARE(runningSpy.count(), 0);
- machine.setRunning(true);
- TEST_ACTIVE_CHANGED(s1, 6);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QTRY_COMPARE(startedSpy.count(), 3);
- QCOMPARE(stoppedSpy.count(), 2);
- QCOMPARE(finishedSpy.count(), 1);
-}
-
-void tst_QStateMachine::targetStateWithNoParent()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->setObjectName("s1");
- QState s2;
- s1->addTransition(&s2);
- machine.setInitialState(s1);
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
-
- QVERIFY(startedSpy.isValid());
- QVERIFY(stoppedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
-
- machine.start();
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'");
- TEST_ACTIVE_CHANGED(s1, 2);
- QTRY_COMPARE(startedSpy.count(), 1);
- QCOMPARE(machine.isRunning(), false);
- QCOMPARE(stoppedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError);
-}
-
-void tst_QStateMachine::targetStateDeleted()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- s1->setObjectName("s1");
- QState *s2 = new QState(&machine);
- QAbstractTransition *trans = s1->addTransition(s2);
- delete s2;
- QCOMPARE(trans->targetState(), (QAbstractState*)0);
- QVERIFY(trans->targetStates().isEmpty());
-}
-
-void tst_QStateMachine::defaultGlobalRestorePolicy()
-{
- QStateMachine machine;
-
- QObject *propertyHolder = new QObject(&machine);
- propertyHolder->setProperty("a", 1);
- propertyHolder->setProperty("b", 2);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(propertyHolder, "a", 3);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(propertyHolder, "b", 4);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
- s2->addTransition(new EventTransition(QEvent::User, s3));
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 4);
-}
-
-void tst_QStateMachine::noInitialStateForInitialState()
-{
- QStateMachine machine;
-
- QState *initialState = new QState(&machine);
- DEFINE_ACTIVE_SPY(initialState);
- initialState->setObjectName("initialState");
- machine.setInitialState(initialState);
-
- QState *childState = new QState(initialState);
- DEFINE_ACTIVE_SPY(childState);
- (void)childState;
-
- QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: "
- "Missing initial state in compound state 'initialState'");
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(initialState, 1);
- TEST_ACTIVE_CHANGED(childState, 0);
- QCOMPARE(machine.isRunning(), false);
- QCOMPARE(int(machine.error()), int(QStateMachine::NoInitialStateError));
-}
-
-void tst_QStateMachine::globalRestorePolicySetToDontRestore()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::DontRestoreProperties);
-
- QObject *propertyHolder = new QObject(&machine);
- propertyHolder->setProperty("a", 1);
- propertyHolder->setProperty("b", 2);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(propertyHolder, "a", 3);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(propertyHolder, "b", 4);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
- s2->addTransition(new EventTransition(QEvent::User, s3));
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 4);
-}
-
-void tst_QStateMachine::globalRestorePolicySetToRestore()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *propertyHolder = new QObject(&machine);
- propertyHolder->setProperty("a", 1);
- propertyHolder->setProperty("b", 2);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(propertyHolder, "a", 3);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(propertyHolder, "b", 4);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
- s2->addTransition(new EventTransition(QEvent::User, s3));
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QCOMPARE(propertyHolder->property("a").toInt(), 3);
- QCOMPARE(propertyHolder->property("b").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- QCOMPARE(propertyHolder->property("a").toInt(), 1);
- QCOMPARE(propertyHolder->property("b").toInt(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QCOMPARE(propertyHolder->property("a").toInt(), 1);
- QCOMPARE(propertyHolder->property("b").toInt(), 2);
-}
-
-void tst_QStateMachine::transitionWithParent()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- QState *s2 = new QState(&machine);
- EventTransition *trans = new EventTransition(QEvent::User, s2, s1);
- QCOMPARE(trans->sourceState(), s1);
- QCOMPARE(trans->targetState(), (QAbstractState*)s2);
- QCOMPARE(trans->targetStates().size(), 1);
- QCOMPARE(trans->targetStates().at(0), (QAbstractState*)s2);
-}
-
-void tst_QStateMachine::simpleAnimation()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("fooBar", 1.0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "fooBar", 2.0);
-
- EventTransition *et = new EventTransition(QEvent::User, s2);
- QPropertyAnimation *animation = new QPropertyAnimation(object, "fooBar", s2);
- et->addAnimation(animation);
- s1->addTransition(et);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- s2->addTransition(animation, SIGNAL(finished()), s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("fooBar").toDouble(), 2.0);
-}
-
-class SlotCalledCounter: public QObject
-{
- Q_OBJECT
-public:
- SlotCalledCounter() : counter(0) {}
-
- int counter;
-
-public slots:
- void slot() { counter++; }
-};
-
-void tst_QStateMachine::twoAnimations()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
- object->setProperty("bar", 3.0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 2.0);
- s2->assignProperty(object, "bar", 10.0);
-
- QPropertyAnimation *animationFoo = new QPropertyAnimation(object, "foo", s2);
- QPropertyAnimation *animationBar = new QPropertyAnimation(object, "bar", s2);
- animationBar->setDuration(900);
-
- SlotCalledCounter counter;
- connect(animationFoo, SIGNAL(finished()), &counter, SLOT(slot()));
- connect(animationBar, SIGNAL(finished()), &counter, SLOT(slot()));
-
- EventTransition *et = new EventTransition(QEvent::User, s2);
- et->addAnimation(animationFoo);
- et->addAnimation(animationBar);
- s1->addTransition(et);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
- s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCOREAPPLICATION_EXEC(5000);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
-
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
- QCOMPARE(object->property("bar").toDouble(), 10.0);
-
- QCOMPARE(counter.counter, 2);
-}
-
-void tst_QStateMachine::twoAnimatedTransitions()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 5.0);
- QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2);
- EventTransition *trans = new EventTransition(QEvent::User, s2);
- s1->addTransition(trans);
- trans->addAnimation(fooAnimation);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
- s2->addTransition(fooAnimation, SIGNAL(finished()), s3);
-
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- s4->assignProperty(object, "foo", 2.0);
- QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4);
- trans = new EventTransition(QEvent::User, s4);
- s3->addTransition(trans);
- trans->addAnimation(fooAnimation2);
-
- QState *s5 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s5);
- QObject::connect(s5, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
- s4->addTransition(fooAnimation2, SIGNAL(finished()), s5);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 5.0);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 2);
- TEST_ACTIVE_CHANGED(s5, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s5));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
-}
-
-void tst_QStateMachine::playAnimationTwice()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 5.0);
- QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2);
- EventTransition *trans = new EventTransition(QEvent::User, s2);
- s1->addTransition(trans);
- trans->addAnimation(fooAnimation);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
- s2->addTransition(fooAnimation, SIGNAL(finished()), s3);
-
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- s4->assignProperty(object, "foo", 2.0);
- trans = new EventTransition(QEvent::User, s4);
- s3->addTransition(trans);
- trans->addAnimation(fooAnimation);
-
- QState *s5 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s5);
- QObject::connect(s5, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
- s4->addTransition(fooAnimation, SIGNAL(finished()), s5);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
- machine.postEvent(new QEvent(QEvent::User));
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 5.0);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 2);
- TEST_ACTIVE_CHANGED(s5, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s5));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
-}
-
-void tst_QStateMachine::nestedTargetStateForAnimation()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
- object->setProperty("bar", 3.0);
-
- SlotCalledCounter counter;
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
-
- s2->assignProperty(object, "foo", 2.0);
-
- QState *s2Child = new QState(s2);
- DEFINE_ACTIVE_SPY(s2Child);
- s2Child->assignProperty(object, "bar", 10.0);
- s2->setInitialState(s2Child);
-
- QState *s2Child2 = new QState(s2);
- DEFINE_ACTIVE_SPY(s2Child2);
- s2Child2->assignProperty(object, "bar", 11.0);
- QAbstractTransition *at = new EventTransition(QEvent::User, s2Child2);
- s2Child->addTransition(at);
-
- QPropertyAnimation *animation = new QPropertyAnimation(object, "bar", s2);
- animation->setDuration(2000);
- connect(animation, SIGNAL(finished()), &counter, SLOT(slot()));
- at->addAnimation(animation);
-
- at = new EventTransition(QEvent::User, s2);
- s1->addTransition(at);
-
- animation = new QPropertyAnimation(object, "foo", s2);
- connect(animation, SIGNAL(finished()), &counter, SLOT(slot()));
- at->addAnimation(animation);
-
- animation = new QPropertyAnimation(object, "bar", s2);
- connect(animation, SIGNAL(finished()), &counter, SLOT(slot()));
- at->addAnimation(animation);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- s2->addTransition(s2Child, SIGNAL(propertiesAssigned()), s3);
-
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s2Child, 0);
- TEST_ACTIVE_CHANGED(s2Child2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- machine.postEvent(new QEvent(QEvent::User));
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s2Child, 1);
- TEST_ACTIVE_CHANGED(s2Child2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s2Child, 2);
- TEST_ACTIVE_CHANGED(s2Child2, 0);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
- QCOMPARE(object->property("bar").toDouble(), 10.0);
- QCOMPARE(counter.counter, 2);
-}
-
-void tst_QStateMachine::propertiesAssignedSignalTransitionsReuseAnimationGroup()
-{
- QStateMachine machine;
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(object, "foo", 123);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 456);
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- s3->assignProperty(object, "foo", 789);
- QFinalState *s4 = new QFinalState(&machine);
-
- QParallelAnimationGroup animationGroup;
- animationGroup.addAnimation(new QPropertyAnimation(object, "foo"));
- QSignalSpy animationFinishedSpy(&animationGroup, &QParallelAnimationGroup::finished);
- QVERIFY(animationFinishedSpy.isValid());
- s1->addTransition(s1, SIGNAL(propertiesAssigned()), s2)->addAnimation(&animationGroup);
- s2->addTransition(s2, SIGNAL(propertiesAssigned()), s3)->addAnimation(&animationGroup);
- s3->addTransition(s3, SIGNAL(propertiesAssigned()), s4);
-
- machine.setInitialState(s1);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy machineFinishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(machineFinishedSpy.isValid());
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- QTRY_COMPARE(machineFinishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QVERIFY(!machine.isRunning());
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s4));
- QCOMPARE(object->property("foo").toInt(), 789);
- QCOMPARE(animationFinishedSpy.count(), 2);
-
-}
-
-void tst_QStateMachine::animatedGlobalRestoreProperty()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
-
- SlotCalledCounter counter;
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 2.0);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
-
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-
- QAbstractTransition *at = new EventTransition(QEvent::User, s2);
- s1->addTransition(at);
- QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", s2);
- connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
- at->addAnimation(pa);
-
- at = s2->addTransition(pa, SIGNAL(finished()), s3);
- pa = new QPropertyAnimation(object, "foo", s3);
- connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
- at->addAnimation(pa);
-
- at = s3->addTransition(pa, SIGNAL(finished()), s4);
- pa = new QPropertyAnimation(object, "foo", s4);
- connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
- at->addAnimation(pa);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
-
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s4));
- QCOMPARE(object->property("foo").toDouble(), 1.0);
- QCOMPARE(counter.counter, 2);
-}
-
-void tst_QStateMachine::specificTargetValueOfAnimation()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 2.0);
-
- QPropertyAnimation *anim = new QPropertyAnimation(object, "foo");
- anim->setEndValue(10.0);
- EventTransition *trans = new EventTransition(QEvent::User, s2);
- s1->addTransition(trans);
- trans->addAnimation(anim);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
- s2->addTransition(anim, SIGNAL(finished()), s3);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
- QCOMPARE(anim->endValue().toDouble(), 10.0);
-
- delete anim;
-}
-
-void tst_QStateMachine::addDefaultAnimation()
-{
- QStateMachine machine;
-
- QObject *object = new QObject();
- object->setProperty("foo", 1.0);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 2.0);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine);
- machine.addDefaultAnimation(pa);
- s2->addTransition(pa, SIGNAL(finished()), s3);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
-
- delete object;
-}
-
-void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
- object->setProperty("bar", 2.0);
-
- SlotCalledCounter counter;
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 2.0);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine);
- connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
- machine.addDefaultAnimation(pa);
- s2->addTransition(pa, SIGNAL(finished()), s3);
-
- pa = new QPropertyAnimation(object, "bar", &machine);
- connect(pa, SIGNAL(finished()), &counter, SLOT(slot()));
- machine.addDefaultAnimation(pa);
-
- machine.setInitialState(s1);
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("foo").toDouble(), 2.0);
- QCOMPARE(counter.counter, 1);
-}
-
-void tst_QStateMachine::removeDefaultAnimation()
-{
- QStateMachine machine;
-
- QObject propertyHolder;
- propertyHolder.setProperty("foo", 0);
-
- QCOMPARE(machine.defaultAnimations().size(), 0);
-
- QPropertyAnimation *anim = new QPropertyAnimation(&propertyHolder, "foo");
-
- machine.addDefaultAnimation(anim);
-
- QCOMPARE(machine.defaultAnimations().size(), 1);
- QVERIFY(machine.defaultAnimations().contains(anim));
-
- machine.removeDefaultAnimation(anim);
-
- QCOMPARE(machine.defaultAnimations().size(), 0);
-
- machine.addDefaultAnimation(anim);
-
- QPropertyAnimation *anim2 = new QPropertyAnimation(&propertyHolder, "foo");
- machine.addDefaultAnimation(anim2);
-
- QCOMPARE(machine.defaultAnimations().size(), 2);
- QVERIFY(machine.defaultAnimations().contains(anim));
- QVERIFY(machine.defaultAnimations().contains(anim2));
-
- machine.removeDefaultAnimation(anim);
-
- QCOMPARE(machine.defaultAnimations().size(), 1);
- QVERIFY(machine.defaultAnimations().contains(anim2));
-
- machine.removeDefaultAnimation(anim2);
- QCOMPARE(machine.defaultAnimations().size(), 0);
-
- delete anim;
- delete anim2;
-}
-
-void tst_QStateMachine::overrideDefaultAnimationWithSpecific()
-{
- QStateMachine machine;
-
- QObject *object = new QObject(&machine);
- object->setProperty("foo", 1.0);
-
- SlotCalledCounter counter;
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(object, "foo", 2.0);
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit()));
-
- QAbstractTransition *at = new EventTransition(QEvent::User, s2);
- s1->addTransition(at);
-
- QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo");
- connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), &counter, SLOT(slot()));
-
- QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo");
- s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3);
- connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)), &counter, SLOT(slot()));
-
- machine.addDefaultAnimation(defaultAnimation);
- at->addAnimation(moreSpecificAnimation);
-
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- QCOREAPPLICATION_EXEC(5000);
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QVERIFY(machine.configuration().contains(s3));
- QCOMPARE(counter.counter, 2); // specific animation started and stopped
-
- delete defaultAnimation;
- delete moreSpecificAnimation;
-}
-
-void tst_QStateMachine::parallelStateAssignmentsDone()
-{
- QStateMachine machine;
-
- QObject *propertyHolder = new QObject(&machine);
- propertyHolder->setProperty("foo", 123);
- propertyHolder->setProperty("bar", 456);
- propertyHolder->setProperty("zoot", 789);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QState *parallelState = new QState(QState::ParallelStates, &machine);
- parallelState->assignProperty(propertyHolder, "foo", 321);
-
- QState *s2 = new QState(parallelState);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(propertyHolder, "bar", 654);
-
- QState *s3 = new QState(parallelState);
- DEFINE_ACTIVE_SPY(s3);
- s3->assignProperty(propertyHolder, "zoot", 987);
-
- s1->addTransition(new EventTransition(QEvent::User, parallelState));
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
-
- QCOMPARE(propertyHolder->property("foo").toInt(), 123);
- QCOMPARE(propertyHolder->property("bar").toInt(), 456);
- QCOMPARE(propertyHolder->property("zoot").toInt(), 789);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QCOMPARE(propertyHolder->property("foo").toInt(), 321);
- QCOMPARE(propertyHolder->property("bar").toInt(), 654);
- QCOMPARE(propertyHolder->property("zoot").toInt(), 987);
-}
-
-void tst_QStateMachine::transitionsFromParallelStateWithNoChildren()
-{
- QStateMachine machine;
-
- QState *parallelState = new QState(QState::ParallelStates, &machine);
- DEFINE_ACTIVE_SPY(parallelState);
- machine.setInitialState(parallelState);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- parallelState->addTransition(new EventTransition(QEvent::User, s1));
-
- machine.start();
- QCoreApplication::processEvents();
- TEST_ACTIVE_CHANGED(parallelState, 1);
- TEST_ACTIVE_CHANGED(s1, 0);
-
- QCOMPARE(1, machine.configuration().size());
- QVERIFY(machine.configuration().contains(parallelState));
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(parallelState, 2);
- TEST_ACTIVE_CHANGED(s1, 1);
- QVERIFY(machine.isRunning());
- QCOMPARE(1, machine.configuration().size());
- QVERIFY(machine.configuration().contains(s1));
-}
-
-void tst_QStateMachine::parallelStateTransition()
-{
- // This test checks if the parallel state is exited and re-entered if one compound state
- // is exited and subsequently re-entered. When the parallel state is exited, the other compound
- // state in the parallel state has to be exited too. When the parallel state is re-entered, the
- // other state also needs to be re-entered.
-
- QStateMachine machine;
-
- QState *parallelState = new QState(QState::ParallelStates, &machine);
- parallelState->setObjectName("parallelState");
- DEFINE_ACTIVE_SPY(parallelState);
- machine.setInitialState(parallelState);
-
- QState *s1 = new QState(parallelState);
- s1->setObjectName("s1");
- DEFINE_ACTIVE_SPY(s1);
- QState *s2 = new QState(parallelState);
- s2->setObjectName("s2");
- DEFINE_ACTIVE_SPY(s2);
-
- QState *s1InitialChild = new QState(s1);
- s1InitialChild->setObjectName("s1InitialChild");
- DEFINE_ACTIVE_SPY(s1InitialChild);
- s1->setInitialState(s1InitialChild);
-
- QState *s2InitialChild = new QState(s2);
- s2InitialChild->setObjectName("s2InitialChild");
- DEFINE_ACTIVE_SPY(s2InitialChild);
- s2->setInitialState(s2InitialChild);
-
- QState *s1OtherChild = new QState(s1);
- s1OtherChild->setObjectName("s1OtherChild");
- DEFINE_ACTIVE_SPY(s1OtherChild);
-
- // The following transition will exit s1 (which means that parallelState is also exited), and
- // subsequently re-entered (which means that parallelState is also re-entered).
- EventTransition *et = new EventTransition(QEvent::User, s1OtherChild);
- et->setObjectName("s1->s1OtherChild");
- s1->addTransition(et);
-
- machine.start();
- QCoreApplication::processEvents();
-
- // Initial entrance of the parallel state and its sub-states:
- TEST_ACTIVE_CHANGED(parallelState, 1);
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s1InitialChild, 1);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s2InitialChild, 1);
- TEST_ACTIVE_CHANGED(s1OtherChild, 0);
-
- QVERIFY(machine.configuration().contains(parallelState));
- QVERIFY(machine.configuration().contains(s1));
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s1InitialChild));
- QVERIFY(machine.configuration().contains(s2InitialChild));
- QCOMPARE(machine.configuration().size(), 5);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(parallelState, 3); // initial + exit + entry
- TEST_ACTIVE_CHANGED(s1, 3); // initial + exit + entry
- TEST_ACTIVE_CHANGED(s1InitialChild, 2); // initial + exit
- TEST_ACTIVE_CHANGED(s2, 3); // initial + exit due to parent exit + entry due to parent re-entry
- TEST_ACTIVE_CHANGED(s2InitialChild, 3); // initial + exit due to parent exit + re-entry due to parent re-entry
- TEST_ACTIVE_CHANGED(s1OtherChild, 1); // entry due to transition
- QVERIFY(machine.isRunning());
-
- // Check that s1InitialChild is not in the configuration, because although s1 is re-entered,
- // another child state (s1OtherChild) is active, so the initial child should not be activated.
- QVERIFY(machine.configuration().contains(parallelState));
- QVERIFY(machine.configuration().contains(s1));
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s1OtherChild));
- QVERIFY(machine.configuration().contains(s2InitialChild));
- QCOMPARE(machine.configuration().size(), 5);
-}
-
-void tst_QStateMachine::nestedRestoreProperties()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *propertyHolder = new QObject(&machine);
- propertyHolder->setProperty("foo", 1);
- propertyHolder->setProperty("bar", 2);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(propertyHolder, "foo", 3);
-
- QState *s21 = new QState(s2);
- DEFINE_ACTIVE_SPY(s21);
- s21->assignProperty(propertyHolder, "bar", 4);
- s2->setInitialState(s21);
-
- QState *s22 = new QState(s2);
- DEFINE_ACTIVE_SPY(s22);
- s22->assignProperty(propertyHolder, "bar", 5);
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
- s21->addTransition(new EventTransition(QEvent::User, s22));
-
- machine.start();
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s21, 0);
- TEST_ACTIVE_CHANGED(s22, 0);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- QCOMPARE(propertyHolder->property("foo").toInt(), 1);
- QCOMPARE(propertyHolder->property("bar").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 1);
- TEST_ACTIVE_CHANGED(s22, 0);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s21));
- QCOMPARE(propertyHolder->property("foo").toInt(), 3);
- QCOMPARE(propertyHolder->property("bar").toInt(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 2);
- TEST_ACTIVE_CHANGED(s22, 1);
- QVERIFY(machine.isRunning());
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s22));
- QCOMPARE(propertyHolder->property("foo").toInt(), 3);
- QCOMPARE(propertyHolder->property("bar").toInt(), 5);
-}
-
-void tst_QStateMachine::nestedRestoreProperties2()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *propertyHolder = new QObject(&machine);
- propertyHolder->setProperty("foo", 1);
- propertyHolder->setProperty("bar", 2);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(propertyHolder, "foo", 3);
-
- QState *s21 = new QState(s2);
- DEFINE_ACTIVE_SPY(s21);
- s21->assignProperty(propertyHolder, "bar", 4);
- s2->setInitialState(s21);
-
- QState *s22 = new QState(s2);
- DEFINE_ACTIVE_SPY(s22);
- s22->assignProperty(propertyHolder, "foo", 6);
- s22->assignProperty(propertyHolder, "bar", 5);
-
- s1->addTransition(new EventTransition(QEvent::User, s2));
- s21->addTransition(new EventTransition(QEvent::User, s22));
- s22->addTransition(new EventTransition(QEvent::User, s21));
-
- machine.start();
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s21, 0);
- TEST_ACTIVE_CHANGED(s22, 0);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- QCOMPARE(propertyHolder->property("foo").toInt(), 1);
- QCOMPARE(propertyHolder->property("bar").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 1);
- TEST_ACTIVE_CHANGED(s22, 0);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s21));
- QCOMPARE(propertyHolder->property("foo").toInt(), 3);
- QCOMPARE(propertyHolder->property("bar").toInt(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 2);
- TEST_ACTIVE_CHANGED(s22, 1);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s22));
- QCOMPARE(propertyHolder->property("foo").toInt(), 6);
- QCOMPARE(propertyHolder->property("bar").toInt(), 5);
-
- machine.postEvent(new QEvent(QEvent::User));
- QCoreApplication::processEvents();
-
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 3);
- TEST_ACTIVE_CHANGED(s22, 2);
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s21));
- QCOMPARE(propertyHolder->property("foo").toInt(), 3);
- QCOMPARE(propertyHolder->property("bar").toInt(), 4);
-
-}
-
-void tst_QStateMachine::nestedStateMachines()
-{
- QStateMachine machine;
- QState *group = new QState(&machine);
- DEFINE_ACTIVE_SPY(group);
- group->setChildMode(QState::ParallelStates);
- QStateMachine *subMachines[3];
- for (int i = 0; i < 3; ++i) {
- QState *subGroup = new QState(group);
- QStateMachine *subMachine = new QStateMachine(subGroup);
- {
- QState *initial = new QState(subMachine);
- QFinalState *done = new QFinalState(subMachine);
- initial->addTransition(new EventTransition(QEvent::User, done));
- subMachine->setInitialState(initial);
- }
- QFinalState *subMachineDone = new QFinalState(subGroup);
- subMachine->addTransition(subMachine, SIGNAL(finished()), subMachineDone);
- subGroup->setInitialState(subMachine);
- subMachines[i] = subMachine;
- }
- QFinalState *final = new QFinalState(&machine);
- group->addTransition(group, SIGNAL(finished()), final);
- machine.setInitialState(group);
-
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
- QTRY_COMPARE(machine.configuration().count(), 1+2*3);
- QVERIFY(machine.configuration().contains(group));
- for (int i = 0; i < 3; ++i)
- QVERIFY(machine.configuration().contains(subMachines[i]));
-
- QCoreApplication::processEvents(); // starts the submachines
- TEST_ACTIVE_CHANGED(group, 1);
-
- for (int i = 0; i < 3; ++i)
- subMachines[i]->postEvent(new QEvent(QEvent::User));
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- TEST_ACTIVE_CHANGED(group, 2);
-}
-
-void tst_QStateMachine::goToState()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- QState *s2 = new QState(&machine);
- machine.setInitialState(s1);
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
-
- QStateMachinePrivate::get(&machine)->goToState(s2);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-
- QStateMachinePrivate::get(&machine)->goToState(s2);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-
- QStateMachinePrivate::get(&machine)->goToState(s1);
- QStateMachinePrivate::get(&machine)->goToState(s2);
- QStateMachinePrivate::get(&machine)->goToState(s1);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- // go to state in group
- QState *s2_1 = new QState(s2);
- s2->setInitialState(s2_1);
- QStateMachinePrivate::get(&machine)->goToState(s2_1);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 2);
- QVERIFY(machine.configuration().contains(s2));
- QVERIFY(machine.configuration().contains(s2_1));
-}
-
-void tst_QStateMachine::goToStateFromSourceWithTransition()
-{
- // QTBUG-21813
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- s1->addTransition(new QSignalTransition);
- QState *s2 = new QState(&machine);
- machine.setInitialState(s1);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
-
- QStateMachinePrivate::get(&machine)->goToState(s2);
- QCoreApplication::processEvents();
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-}
-
-class CloneSignalTransition : public QSignalTransition
-{
-public:
- CloneSignalTransition(QObject *sender, const char *signal, QAbstractState *target)
- : QSignalTransition(sender, signal)
- {
- setTargetState(target);
- }
-
- void onTransition(QEvent *e)
- {
- QSignalTransition::onTransition(e);
- QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(e);
- eventSignalIndex = se->signalIndex();
- }
-
- int eventSignalIndex;
-};
-
-void tst_QStateMachine::clonedSignals()
-{
- SignalEmitter emitter;
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- CloneSignalTransition *t1 = new CloneSignalTransition(&emitter, SIGNAL(signalWithDefaultArg()), s2);
- s1->addTransition(t1);
-
- machine.setInitialState(s1);
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- machine.start();
- QVERIFY(startedSpy.wait());
-
- QSignalSpy transitionSpy(t1, &CloneSignalTransition::triggered);
- emitter.emitSignalWithDefaultArg();
- QTRY_COMPARE(transitionSpy.count(), 1);
-
- QCOMPARE(t1->eventSignalIndex, emitter.metaObject()->indexOfSignal("signalWithDefaultArg()"));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QVERIFY(machine.isRunning());
-}
-
-class EventPosterThread : public QThread
-{
- Q_OBJECT
-public:
- EventPosterThread(QStateMachine *machine, QObject *parent = 0)
- : QThread(parent), m_machine(machine), m_count(0)
- {
- moveToThread(this);
- QObject::connect(m_machine, SIGNAL(started()),
- this, SLOT(postEvent()));
- }
-protected:
- virtual void run()
- {
- exec();
- }
-private Q_SLOTS:
- void postEvent()
- {
- m_machine->postEvent(new QEvent(QEvent::User));
- if (++m_count < 1000)
- QTimer::singleShot(0, this, SLOT(postEvent()));
- else
- quit();
- }
-private:
- QStateMachine *m_machine;
- int m_count;
-};
-
-void tst_QStateMachine::postEventFromOtherThread()
-{
- QStateMachine machine;
- EventPosterThread poster(&machine);
- StringEventPoster *s1 = new StringEventPoster("foo", &machine);
- s1->addTransition(new EventTransition(QEvent::User, s1));
- QFinalState *f = new QFinalState(&machine);
- s1->addTransition(&poster, SIGNAL(finished()), f);
- machine.setInitialState(s1);
-
- poster.start();
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(finishedSpy.isValid());
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-}
-
-#ifndef QT_NO_WIDGETS
-void tst_QStateMachine::eventFilterForApplication()
-{
- QStateMachine machine;
-
- QState *s1 = new QState(&machine);
- {
- machine.setInitialState(s1);
- }
-
- QState *s2 = new QState(&machine);
-
- QEventTransition *transition = new QEventTransition(QCoreApplication::instance(),
- QEvent::ApplicationActivate);
- transition->setTargetState(s2);
- s1->addTransition(transition);
-
- machine.start();
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
-
- QCoreApplication::postEvent(QCoreApplication::instance(),
- new QEvent(QEvent::ApplicationActivate));
- QCoreApplication::processEvents();
-
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
-}
-#endif
-
-void tst_QStateMachine::eventClassesExported()
-{
- // make sure this links
- QStateMachine::WrappedEvent *wrappedEvent = new QStateMachine::WrappedEvent(0, 0);
- Q_UNUSED(wrappedEvent);
- QStateMachine::SignalEvent *signalEvent = new QStateMachine::SignalEvent(0, 0, QList<QVariant>());
- Q_UNUSED(signalEvent);
-}
-
-void tst_QStateMachine::stopInTransitionToFinalState()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- QFinalState *s2 = new QFinalState(&machine);
- QAbstractTransition *t1 = s1->addTransition(s2);
- machine.setInitialState(s1);
-
- QObject::connect(t1, SIGNAL(triggered()), &machine, SLOT(stop()));
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QSignalSpy s2EnteredSpy(s2, &QFinalState::entered);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(stoppedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- QVERIFY(s2EnteredSpy.isValid());
- QVERIFY(runningSpy.isValid());
- machine.start();
- // Stopping should take precedence over finished.
- QTRY_COMPARE(stoppedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- QCOMPARE(s2EnteredSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s2));
- TEST_ACTIVE_CHANGED(s1, 2);
-}
-
-class StopInEventTestTransition : public QAbstractTransition
-{
-public:
- bool eventTest(QEvent *e)
- {
- if (e->type() == QEvent::User)
- machine()->stop();
- return false;
- }
- void onTransition(QEvent *)
- { }
-};
-
-void tst_QStateMachine::stopInEventTest_data()
-{
- QTest::addColumn<int>("eventPriority");
- QTest::newRow("NormalPriority") << int(QStateMachine::NormalPriority);
- QTest::newRow("HighPriority") << int(QStateMachine::HighPriority);
-}
-
-void tst_QStateMachine::stopInEventTest()
-{
- QFETCH(int, eventPriority);
-
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->addTransition(new StopInEventTestTransition());
- machine.setInitialState(s1);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QVERIFY(startedSpy.isValid());
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
-
- QSignalSpy stoppedSpy(&machine, &QStateMachine::stopped);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QVERIFY(stoppedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
- machine.postEvent(new QEvent(QEvent::User), QStateMachine::EventPriority(eventPriority));
-
- QTRY_COMPARE(stoppedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(machine.configuration().size(), 1);
- QVERIFY(machine.configuration().contains(s1));
- TEST_ACTIVE_CHANGED(s1, 1);
-}
-
-class IncrementReceiversTest : public QObject
-{
- Q_OBJECT
-signals:
- void mySignal();
-public:
- virtual void connectNotify(const QMetaMethod &signal)
- {
- signalList.append(signal);
- }
-
- QVector<QMetaMethod> signalList;
-};
-
-void tst_QStateMachine::testIncrementReceivers()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- QFinalState *s2 = new QFinalState(&machine);
-
- IncrementReceiversTest testObject;
- s1->addTransition(&testObject, SIGNAL(mySignal()), s2);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- machine.start();
- TEST_RUNNING_CHANGED(true);
-
- QMetaObject::invokeMethod(&testObject, "mySignal", Qt::QueuedConnection);
-
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
- QCOMPARE(testObject.signalList.size(), 1);
- QCOMPARE(testObject.signalList.at(0), QMetaMethod::fromSignal(&IncrementReceiversTest::mySignal));
- TEST_ACTIVE_CHANGED(s1, 2);
-}
-
-void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- QFinalState *s2 = new QFinalState(&machine);
-
- // When started() is emitted, s1 should be the active state, and this
- // transition should trigger.
- s1->addTransition(&machine, SIGNAL(started()), s2);
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- machine.start();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
- TEST_ACTIVE_CHANGED(s1, 2);
-}
-
-void tst_QStateMachine::deletePropertyAssignmentObjectBeforeEntry()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QObject *o1 = new QObject;
- s1->assignProperty(o1, "objectName", "foo");
- delete o1;
- QObject *o2 = new QObject;
- s1->assignProperty(o2, "objectName", "bar");
-
- machine.start();
- // Shouldn't crash
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- QCOMPARE(o2->objectName(), QString::fromLatin1("bar"));
- delete o2;
- TEST_ACTIVE_CHANGED(s1, 1);
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::deletePropertyAssignmentObjectBeforeRestore()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- QObject *o1 = new QObject;
- s1->assignProperty(o1, "objectName", "foo");
- QObject *o2 = new QObject;
- s1->assignProperty(o2, "objectName", "bar");
-
- QVERIFY(o1->objectName().isEmpty());
- QVERIFY(o2->objectName().isEmpty());
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOMPARE(o1->objectName(), QString::fromLatin1("foo"));
- QCOMPARE(o2->objectName(), QString::fromLatin1("bar"));
-
- delete o1;
- machine.postEvent(new QEvent(QEvent::User));
- // Shouldn't crash
- QTRY_VERIFY(machine.configuration().contains(s2));
-
- QVERIFY(o2->objectName().isEmpty());
- delete o2;
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::deleteInitialState()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- machine.setInitialState(s1);
- delete s1;
- QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start.");
- machine.start();
- // Shouldn't crash
- QCoreApplication::processEvents();
-}
-
-void tst_QStateMachine::setPropertyAfterRestore()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *object = new QObject(&machine);
- object->setProperty("a", 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- s1->assignProperty(object, "a", 2);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- s3->assignProperty(object, "a", 4);
- s2->addTransition(new EventTransition(QEvent::User, s3));
-
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- s3->addTransition(new EventTransition(QEvent::User, s4));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOMPARE(object->property("a").toInt(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(object->property("a").toInt(), 1); // restored
-
- // Set property outside of state machine; this is the value
- // that should be remembered in the next transition
- object->setProperty("a", 3);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- TEST_ACTIVE_CHANGED(s4, 0);
- QTRY_VERIFY(machine.configuration().contains(s3));
- QCOMPARE(object->property("a").toInt(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 1);
- QVERIFY(machine.isRunning());
- QTRY_VERIFY(machine.configuration().contains(s4));
- QCOMPARE(object->property("a").toInt(), 3); // restored
-
- delete object;
-}
-
-void tst_QStateMachine::transitionWithNoTarget_data()
-{
- QTest::addColumn<int>("restorePolicy");
- QTest::newRow("DontRestoreProperties") << int(QState::DontRestoreProperties);
- QTest::newRow("RestoreProperties") << int(QState::RestoreProperties);
-}
-
-void tst_QStateMachine::transitionWithNoTarget()
-{
- QFETCH(int, restorePolicy);
-
- QStateMachine machine;
- machine.setGlobalRestorePolicy(static_cast<QState::RestorePolicy>(restorePolicy));
-
- QObject *object = new QObject;
- object->setProperty("a", 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- s1->assignProperty(object, "a", 2);
- EventTransition *t1 = new EventTransition(QEvent::User, /*target=*/0);
- s1->addTransition(t1);
-
- QSignalSpy s1EnteredSpy(s1, &QState::entered);
- QSignalSpy s1ExitedSpy(s1, &QState::exited);
- QSignalSpy t1TriggeredSpy(t1, &EventTransition::triggered);
-
- machine.start();
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOMPARE(s1EnteredSpy.count(), 1);
- QCOMPARE(s1ExitedSpy.count(), 0);
- QCOMPARE(t1TriggeredSpy.count(), 0);
- QCOMPARE(object->property("a").toInt(), 2);
-
- object->setProperty("a", 3);
-
- machine.postEvent(new QEvent(QEvent::User));
- QTRY_COMPARE(t1TriggeredSpy.count(), 1);
- QCOMPARE(s1EnteredSpy.count(), 1);
- QCOMPARE(s1ExitedSpy.count(), 0);
- // the assignProperty should not be re-executed, nor should the old value
- // be restored
- QCOMPARE(object->property("a").toInt(), 3);
-
- machine.postEvent(new QEvent(QEvent::User));
- QTRY_COMPARE(t1TriggeredSpy.count(), 2);
- QCOMPARE(s1EnteredSpy.count(), 1);
- QCOMPARE(s1ExitedSpy.count(), 0);
- QCOMPARE(object->property("a").toInt(), 3);
-
- delete object;
- TEST_ACTIVE_CHANGED(s1, 1);
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::initialStateIsFinal()
-{
- QStateMachine machine;
- QFinalState *f = new QFinalState(&machine);
- machine.setInitialState(f);
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- machine.start();
- QTRY_VERIFY(machine.configuration().contains(f));
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED_STARTED_STOPPED;
-}
-
-class PropertyObject : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int prop READ prop WRITE setProp)
-public:
- PropertyObject(QObject *parent = 0)
- : QObject(parent), m_propValue(0), m_propWriteCount(0)
- {}
- int prop() const { return m_propValue; }
- void setProp(int value) { m_propValue = value; ++m_propWriteCount; }
- int propWriteCount() const { return m_propWriteCount; }
-private:
- int m_propValue;
- int m_propWriteCount;
-};
-
-void tst_QStateMachine::restorePropertiesSimple()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- PropertyObject *po = new PropertyObject;
- po->setProp(2);
- QCOMPARE(po->propWriteCount(), 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(po, "prop", 4);
- machine.setInitialState(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- s3->assignProperty(po, "prop", 6);
- s2->addTransition(new EventTransition(QEvent::User, s3));
-
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- s4->assignProperty(po, "prop", 8);
- s3->addTransition(new EventTransition(QEvent::User, s4));
-
- QState *s5 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s5);
- s4->addTransition(new EventTransition(QEvent::User, s5));
-
- QState *s6 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s6);
- s5->addTransition(new EventTransition(QEvent::User, s6));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
- TEST_ACTIVE_CHANGED(s6, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOMPARE(po->propWriteCount(), 2);
- QCOMPARE(po->prop(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
- TEST_ACTIVE_CHANGED(s6, 0);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(po->propWriteCount(), 3);
- QCOMPARE(po->prop(), 2); // restored
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- TEST_ACTIVE_CHANGED(s4, 0);
- TEST_ACTIVE_CHANGED(s5, 0);
- TEST_ACTIVE_CHANGED(s6, 0);
- QTRY_VERIFY(machine.configuration().contains(s3));
- QCOMPARE(po->propWriteCount(), 4);
- QCOMPARE(po->prop(), 6);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 1);
- TEST_ACTIVE_CHANGED(s5, 0);
- TEST_ACTIVE_CHANGED(s6, 0);
- QTRY_VERIFY(machine.configuration().contains(s4));
- QCOMPARE(po->propWriteCount(), 5);
- QCOMPARE(po->prop(), 8);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 2);
- TEST_ACTIVE_CHANGED(s5, 1);
- TEST_ACTIVE_CHANGED(s6, 0);
- QTRY_VERIFY(machine.configuration().contains(s5));
- QCOMPARE(po->propWriteCount(), 6);
- QCOMPARE(po->prop(), 2); // restored
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 2);
- TEST_ACTIVE_CHANGED(s5, 2);
- TEST_ACTIVE_CHANGED(s6, 1);
- QVERIFY(machine.isRunning());
- QTRY_VERIFY(machine.configuration().contains(s6));
- QCOMPARE(po->propWriteCount(), 6);
-
- delete po;
-}
-
-void tst_QStateMachine::restoreProperties2()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- PropertyObject *po = new PropertyObject;
- po->setProp(2);
- QCOMPARE(po->propWriteCount(), 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(po, "prop", 4);
- machine.setInitialState(s1);
-
- QState *s11 = new QState(s1);
- DEFINE_ACTIVE_SPY(s11);
- s1->setInitialState(s11);
-
- QState *s12 = new QState(s1);
- DEFINE_ACTIVE_SPY(s12);
- s11->addTransition(new EventTransition(QEvent::User, s12));
-
- QState *s13 = new QState(s1);
- DEFINE_ACTIVE_SPY(s13);
- s13->assignProperty(po, "prop", 6);
- s12->addTransition(new EventTransition(QEvent::User, s13));
-
- QState *s14 = new QState(s1);
- DEFINE_ACTIVE_SPY(s14);
- s14->assignProperty(po, "prop", 8);
- s13->addTransition(new EventTransition(QEvent::User, s14));
-
- QState *s15 = new QState(s1);
- DEFINE_ACTIVE_SPY(s15);
- s14->addTransition(new EventTransition(QEvent::User, s15));
-
- QState *s16 = new QState(s1);
- DEFINE_ACTIVE_SPY(s16);
- s15->addTransition(new EventTransition(QEvent::User, s16));
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(po, "prop", 10);
- s16->addTransition(new EventTransition(QEvent::User, s2));
-
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- s2->addTransition(new EventTransition(QEvent::User, s3));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
- TEST_ACTIVE_CHANGED(s12, 0);
- TEST_ACTIVE_CHANGED(s13, 0);
- TEST_ACTIVE_CHANGED(s14, 0);
- TEST_ACTIVE_CHANGED(s15, 0);
- TEST_ACTIVE_CHANGED(s16, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s11));
- QCOMPARE(po->propWriteCount(), 2);
- QCOMPARE(po->prop(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 1);
- TEST_ACTIVE_CHANGED(s13, 0);
- TEST_ACTIVE_CHANGED(s14, 0);
- TEST_ACTIVE_CHANGED(s15, 0);
- TEST_ACTIVE_CHANGED(s16, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s12));
- QCOMPARE(po->propWriteCount(), 2);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 1);
- TEST_ACTIVE_CHANGED(s14, 0);
- TEST_ACTIVE_CHANGED(s15, 0);
- TEST_ACTIVE_CHANGED(s16, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s13));
- QCOMPARE(po->propWriteCount(), 3);
- QCOMPARE(po->prop(), 6);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 2);
- TEST_ACTIVE_CHANGED(s14, 1);
- TEST_ACTIVE_CHANGED(s15, 0);
- TEST_ACTIVE_CHANGED(s16, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s14));
- QCOMPARE(po->propWriteCount(), 4);
- QCOMPARE(po->prop(), 8);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 2);
- TEST_ACTIVE_CHANGED(s14, 2);
- TEST_ACTIVE_CHANGED(s15, 1);
- TEST_ACTIVE_CHANGED(s16, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s15));
- QCOMPARE(po->propWriteCount(), 5);
- QCOMPARE(po->prop(), 4); // restored s1
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 2);
- TEST_ACTIVE_CHANGED(s14, 2);
- TEST_ACTIVE_CHANGED(s15, 2);
- TEST_ACTIVE_CHANGED(s16, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s16));
- QCOMPARE(po->propWriteCount(), 5);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 2);
- TEST_ACTIVE_CHANGED(s14, 2);
- TEST_ACTIVE_CHANGED(s15, 2);
- TEST_ACTIVE_CHANGED(s16, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s3, 0);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(po->propWriteCount(), 6);
- QCOMPARE(po->prop(), 10);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 2);
- TEST_ACTIVE_CHANGED(s14, 2);
- TEST_ACTIVE_CHANGED(s15, 2);
- TEST_ACTIVE_CHANGED(s16, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QVERIFY(machine.isRunning());
- QTRY_VERIFY(machine.configuration().contains(s3));
- QCOMPARE(po->propWriteCount(), 7);
- QCOMPARE(po->prop(), 2); // restored original
-
- delete po;
-
-}
-
-void tst_QStateMachine::restoreProperties3()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- PropertyObject *po = new PropertyObject;
- po->setProp(2);
- QCOMPARE(po->propWriteCount(), 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(po, "prop", 4);
- machine.setInitialState(s1);
-
- QState *s11 = new QState(s1);
- DEFINE_ACTIVE_SPY(s11);
- s11->assignProperty(po, "prop", 6);
- s1->setInitialState(s11);
-
- QState *s12 = new QState(s1);
- DEFINE_ACTIVE_SPY(s12);
- s11->addTransition(new EventTransition(QEvent::User, s12));
-
- QState *s13 = new QState(s1);
- DEFINE_ACTIVE_SPY(s13);
- s13->assignProperty(po, "prop", 8);
- s12->addTransition(new EventTransition(QEvent::User, s13));
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s13->addTransition(new EventTransition(QEvent::User, s2));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
- TEST_ACTIVE_CHANGED(s12, 0);
- TEST_ACTIVE_CHANGED(s13, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
-
- QTRY_VERIFY(machine.configuration().contains(s11));
- QCOMPARE(po->propWriteCount(), 3);
- QCOMPARE(po->prop(), 6); // s11
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 1);
- TEST_ACTIVE_CHANGED(s13, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s12));
- QCOMPARE(po->propWriteCount(), 4);
- QCOMPARE(po->prop(), 4); // restored s1
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s13));
- QCOMPARE(po->propWriteCount(), 5);
- QCOMPARE(po->prop(), 8);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s13, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QVERIFY(machine.isRunning());
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(po->propWriteCount(), 6);
- QCOMPARE(po->prop(), 2); // restored original
-
- delete po;
-}
-
-// QTBUG-20362
-void tst_QStateMachine::restoreProperties4()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- PropertyObject *po1 = new PropertyObject;
- po1->setProp(2);
- QCOMPARE(po1->propWriteCount(), 1);
- PropertyObject *po2 = new PropertyObject;
- po2->setProp(4);
- QCOMPARE(po2->propWriteCount(), 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->setChildMode(QState::ParallelStates);
- machine.setInitialState(s1);
-
- QState *s11 = new QState(s1);
- DEFINE_ACTIVE_SPY(s11);
- QState *s111 = new QState(s11);
- DEFINE_ACTIVE_SPY(s111);
- s111->assignProperty(po1, "prop", 6);
- s11->setInitialState(s111);
-
- QState *s112 = new QState(s11);
- DEFINE_ACTIVE_SPY(s112);
- s112->assignProperty(po1, "prop", 8);
- s111->addTransition(new EventTransition(QEvent::User, s112));
-
- QState *s12 = new QState(s1);
- DEFINE_ACTIVE_SPY(s12);
- QState *s121 = new QState(s12);
- DEFINE_ACTIVE_SPY(s121);
- s121->assignProperty(po2, "prop", 10);
- s12->setInitialState(s121);
-
- QState *s122 = new QState(s12);
- DEFINE_ACTIVE_SPY(s122);
- s122->assignProperty(po2, "prop", 12);
- s121->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s122));
-
- QState *s2 = new QState(&machine);
- s112->addTransition(new EventTransition(QEvent::User, s2));
- DEFINE_ACTIVE_SPY(s2);
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
- TEST_ACTIVE_CHANGED(s111, 1);
- TEST_ACTIVE_CHANGED(s112, 0);
- TEST_ACTIVE_CHANGED(s12, 1);
- TEST_ACTIVE_CHANGED(s121, 1);
- TEST_ACTIVE_CHANGED(s122, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
-
- QTRY_VERIFY(machine.configuration().contains(s1));
- QVERIFY(machine.configuration().contains(s11));
- QVERIFY(machine.configuration().contains(s111));
- QVERIFY(machine.configuration().contains(s12));
- QVERIFY(machine.configuration().contains(s121));
- QCOMPARE(po1->propWriteCount(), 2);
- QCOMPARE(po1->prop(), 6);
- QCOMPARE(po2->propWriteCount(), 2);
- QCOMPARE(po2->prop(), 10);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
- TEST_ACTIVE_CHANGED(s111, 2);
- TEST_ACTIVE_CHANGED(s112, 1);
- TEST_ACTIVE_CHANGED(s12, 1);
- TEST_ACTIVE_CHANGED(s121, 1);
- TEST_ACTIVE_CHANGED(s122, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s112));
- QCOMPARE(po1->propWriteCount(), 3);
- QCOMPARE(po1->prop(), 8);
- QCOMPARE(po2->propWriteCount(), 2);
-
- machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
- TEST_ACTIVE_CHANGED(s111, 2);
- TEST_ACTIVE_CHANGED(s112, 1);
- TEST_ACTIVE_CHANGED(s12, 1);
- TEST_ACTIVE_CHANGED(s121, 2);
- TEST_ACTIVE_CHANGED(s122, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s122));
- QCOMPARE(po1->propWriteCount(), 3);
- QCOMPARE(po2->propWriteCount(), 3);
- QCOMPARE(po2->prop(), 12);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s11, 2);
- TEST_ACTIVE_CHANGED(s111, 2);
- TEST_ACTIVE_CHANGED(s112, 2);
- TEST_ACTIVE_CHANGED(s12, 2);
- TEST_ACTIVE_CHANGED(s121, 2);
- TEST_ACTIVE_CHANGED(s122, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(po1->propWriteCount(), 4);
- QCOMPARE(po1->prop(), 2); // restored original
- QCOMPARE(po2->propWriteCount(), 4);
- QCOMPARE(po2->prop(), 4); // restored original
-
- delete po1;
- delete po2;
-}
-
-void tst_QStateMachine::restorePropertiesSelfTransition()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- PropertyObject *po = new PropertyObject;
- po->setProp(2);
- QCOMPARE(po->propWriteCount(), 1);
-
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(po, "prop", 4);
- s1->addTransition(new EventTransition(QEvent::User, s1));
- machine.setInitialState(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s1->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s2));
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOMPARE(po->propWriteCount(), 2);
- QCOMPARE(po->prop(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 3);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_COMPARE(po->propWriteCount(), 3);
- QCOMPARE(po->prop(), 4);
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 5);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_COMPARE(po->propWriteCount(), 4);
- QCOMPARE(po->prop(), 4);
-
- machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
- TEST_ACTIVE_CHANGED(s1, 6);
- TEST_ACTIVE_CHANGED(s2, 1);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(po->propWriteCount(), 5);
- QCOMPARE(po->prop(), 2); // restored
-
- delete po;
-}
-
-void tst_QStateMachine::changeStateWhileAnimatingProperty()
-{
- QStateMachine machine;
- machine.setGlobalRestorePolicy(QState::RestoreProperties);
-
- QObject *o1 = new QObject;
- o1->setProperty("x", 10.);
- QObject *o2 = new QObject;
- o2->setProperty("y", 20.);
-
- QState *group = new QState(&machine);
- DEFINE_ACTIVE_SPY(group);
- machine.setInitialState(group);
-
- QState *s0 = new QState(group);
- DEFINE_ACTIVE_SPY(s0);
- group->setInitialState(s0);
-
- QState *s1 = new QState(group);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(o1, "x", 15.);
- QPropertyAnimation *a1 = new QPropertyAnimation(o1, "x", s1);
- a1->setDuration(800);
- machine.addDefaultAnimation(a1);
- group->addTransition(new EventTransition(QEvent::User, s1));
-
- QState *s2 = new QState(group);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(o2, "y", 25.);
- QPropertyAnimation *a2 = new QPropertyAnimation(o2, "y", s2);
- a2->setDuration(800);
- machine.addDefaultAnimation(a2);
- group->addTransition(new EventTransition(static_cast<QEvent::Type>(QEvent::User+1), s2));
-
- machine.start();
- TEST_ACTIVE_CHANGED(group, 1);
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 0);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s0));
-
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(group, 3);
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOREAPPLICATION_EXEC(400);
- machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
- TEST_ACTIVE_CHANGED(group, 5);
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOREAPPLICATION_EXEC(300);
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(group, 7);
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 3);
- TEST_ACTIVE_CHANGED(s2, 2);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QCOREAPPLICATION_EXEC(200);
- machine.postEvent(new QEvent(static_cast<QEvent::Type>(QEvent::User+1)));
- TEST_ACTIVE_CHANGED(group, 9);
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 4);
- TEST_ACTIVE_CHANGED(s2, 3);
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOREAPPLICATION_EXEC(100);
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(group, 11);
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 5);
- TEST_ACTIVE_CHANGED(s2, 4);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QTRY_COMPARE(o1->property("x").toDouble(), 15.);
- QTRY_COMPARE(o2->property("y").toDouble(), 20.);
-
- delete o1;
- delete o2;
-}
-
-class AssignPropertyTestState : public QState
-{
- Q_OBJECT
-public:
- AssignPropertyTestState(QState *parent = 0)
- : QState(parent), onEntryPassed(false), enteredPassed(false)
- { QObject::connect(this, SIGNAL(entered()), this, SLOT(onEntered())); }
-
- virtual void onEntry(QEvent *)
- { onEntryPassed = property("wasAssigned").toBool(); }
-
- bool onEntryPassed;
- bool enteredPassed;
-
-private Q_SLOTS:
- void onEntered()
- { enteredPassed = property("wasAssigned").toBool(); }
-};
-
-void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks_data()
-{
- QTest::addColumn<int>("restorePolicy");
- QTest::newRow("DontRestoreProperties") << int(QState::DontRestoreProperties);
- QTest::newRow("RestoreProperties") << int(QState::RestoreProperties);
-}
-
-void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks()
-{
- QFETCH(int, restorePolicy);
-
- QStateMachine machine;
- machine.setGlobalRestorePolicy(static_cast<QState::RestorePolicy>(restorePolicy));
-
- AssignPropertyTestState *s1 = new AssignPropertyTestState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- s1->assignProperty(s1, "wasAssigned", true);
- machine.setInitialState(s1);
-
- AssignPropertyTestState *s2 = new AssignPropertyTestState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s2->assignProperty(s2, "wasAssigned", true);
- s1->addTransition(new EventTransition(QEvent::User, s2));
-
- QVERIFY(!s1->property("wasAssigned").toBool());
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- QVERIFY(s1->onEntryPassed);
- QVERIFY(s1->enteredPassed);
-
- QVERIFY(!s2->property("wasAssigned").toBool());
- machine.postEvent(new QEvent(QEvent::User));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QTRY_VERIFY(machine.configuration().contains(s2));
-
- QVERIFY(s2->onEntryPassed);
- QVERIFY(s2->enteredPassed);
-}
-
-// QTBUG-25958
-void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup()
-{
- // TODO QTBUG-25958 was reopened, see https://codereview.qt-project.org/89775
- return;
-
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QState *s2 = new QState(QState::ParallelStates, &machine);
- DEFINE_ACTIVE_SPY(s2);
-
- QState *s21 = new QState(s2);
- DEFINE_ACTIVE_SPY(s21);
- QState *s211 = new QState(s21);
- DEFINE_ACTIVE_SPY(s211);
- QState *s212 = new QState(s21);
- DEFINE_ACTIVE_SPY(s212);
- s21->setInitialState(s212);
-
- QState *s22 = new QState(s2);
- DEFINE_ACTIVE_SPY(s22);
- QState *s221 = new QState(s22);
- DEFINE_ACTIVE_SPY(s221);
- QState *s222 = new QState(s22);
- DEFINE_ACTIVE_SPY(s222);
- s22->setInitialState(s222);
-
- QAbstractTransition *t1 = new EventTransition(QEvent::User, QList<QAbstractState *>() << s211 << s221);
- s1->addTransition(t1);
-
- machine.start();
- QTRY_VERIFY(machine.configuration().contains(s1));
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- TEST_ACTIVE_CHANGED(s21, 0);
- TEST_ACTIVE_CHANGED(s211, 0);
- TEST_ACTIVE_CHANGED(s212, 0);
- TEST_ACTIVE_CHANGED(s22, 0);
- TEST_ACTIVE_CHANGED(s221, 0);
- TEST_ACTIVE_CHANGED(s222, 0);
- machine.postEvent(new QEvent(QEvent::User));
- QTRY_VERIFY(machine.configuration().contains(s2));
- QCOMPARE(machine.configuration().size(), 5);
- QVERIFY(machine.configuration().contains(s21));
- QVERIFY(machine.configuration().contains(s211));
- QVERIFY(machine.configuration().contains(s22));
- QVERIFY(machine.configuration().contains(s221));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- TEST_ACTIVE_CHANGED(s21, 1);
- TEST_ACTIVE_CHANGED(s211, 1);
- TEST_ACTIVE_CHANGED(s212, 0);
- TEST_ACTIVE_CHANGED(s22, 1);
- TEST_ACTIVE_CHANGED(s221, 1);
- TEST_ACTIVE_CHANGED(s222, 0);
-}
-
-void tst_QStateMachine::signalTransitionNormalizeSignature()
-{
- QStateMachine machine;
- QState *s0 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s0);
- machine.setInitialState(s0);
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- SignalEmitter emitter;
- TestSignalTransition *t0 = new TestSignalTransition(&emitter, SIGNAL(signalWithNoArg()), s1);
- s0->addTransition(t0);
-
- machine.start();
- TEST_ACTIVE_CHANGED(s0, 1);
- TEST_ACTIVE_CHANGED(s1, 0);
- QTRY_VERIFY(machine.configuration().contains(s0));
- emitter.emitSignalWithNoArg();
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- QCOMPARE(t0->eventTestSenderReceived(), (QObject*)&emitter);
- QCOMPARE(t0->eventTestSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithNoArg()"));
- QCOMPARE(t0->eventTestArgumentsReceived().size(), 0);
- QCOMPARE(t0->transitionSenderReceived(), (QObject*)&emitter);
- QCOMPARE(t0->transitionSignalIndexReceived(), emitter.metaObject()->indexOfSignal("signalWithNoArg()"));
- QCOMPARE(t0->transitionArgumentsReceived().size(), 0);
- TEST_ACTIVE_CHANGED(s0, 2);
- TEST_ACTIVE_CHANGED(s1, 1);
-}
-
-#ifdef Q_COMPILER_DELEGATING_CONSTRUCTORS
-void tst_QStateMachine::createPointerToMemberSignalTransition()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- SignalEmitter emitter;
- QSignalTransition *t1 = new QSignalTransition(&emitter, &SignalEmitter::signalWithNoArg, s1);
- QCOMPARE(t1->sourceState(), s1);
- t1->setTargetState(s2);
- s1->addTransition(t1);
- emitter.emitSignalWithNoArg();
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QTRY_VERIFY(machine.configuration().contains(s2));
-}
-#endif
-
-void tst_QStateMachine::createSignalTransitionWhenRunning()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_VERIFY(machine.configuration().contains(s1));
- // Create by addTransition()
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- SignalEmitter emitter;
- QAbstractTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
- QCOMPARE(t1->sourceState(), s1);
- emitter.emitSignalWithNoArg();
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 1);
- QTRY_VERIFY(machine.configuration().contains(s2));
-
- // Create by constructor that takes sender, signal, source (parent) state
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QSignalTransition *t2 = new QSignalTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
- QCOMPARE(t2->sourceState(), s2);
- t2->setTargetState(s3);
- emitter.emitSignalWithNoArg();
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 1);
- QTRY_VERIFY(machine.configuration().contains(s3));
-
- // Create by constructor that takes source (parent) state
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- QSignalTransition *t3 = new QSignalTransition(s3);
- QCOMPARE(t3->sourceState(), s3);
- t3->setSenderObject(&emitter);
- t3->setSignal(SIGNAL(signalWithNoArg()));
- t3->setTargetState(s4);
- emitter.emitSignalWithNoArg();
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 1);
- QTRY_VERIFY(machine.configuration().contains(s4));
-
- // Create by constructor without parent, then set the parent
- QState *s5 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s5);
- QSignalTransition *t4 = new QSignalTransition();
- t4->setSenderObject(&emitter);
- t4->setParent(s4);
- QCOMPARE(t4->sourceState(), s4);
- t4->setSignal(SIGNAL(signalWithNoArg()));
- t4->setTargetState(s5);
- emitter.emitSignalWithNoArg();
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 2);
- TEST_ACTIVE_CHANGED(s5, 1);
- QTRY_VERIFY(machine.configuration().contains(s5));
-}
-
-void tst_QStateMachine::createEventTransitionWhenRunning()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- // Create by constructor that takes event source, type, source (parent) state
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- QObject object;
- QEventTransition *t1 = new QEventTransition(&object, QEvent::Timer, s1);
- QCOMPARE(t1->sourceState(), s1);
- t1->setTargetState(s2);
-
- object.startTimer(10); // Will cause QEvent::Timer to fire every 10ms
- QTRY_VERIFY(machine.configuration().contains(s2));
-
- // Create by constructor that takes source (parent) state
- QState *s3 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s3);
- QEventTransition *t2 = new QEventTransition(s2);
- QCOMPARE(t2->sourceState(), s2);
- t2->setEventSource(&object);
- t2->setEventType(QEvent::Timer);
- t2->setTargetState(s3);
- QTRY_VERIFY(machine.configuration().contains(s3));
-
- // Create by constructor without parent, then set the parent
- QState *s4 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s4);
- QEventTransition *t3 = new QEventTransition();
- t3->setEventSource(&object);
- t3->setParent(s3);
- QCOMPARE(t3->sourceState(), s3);
- t3->setEventType(QEvent::Timer);
- t3->setTargetState(s4);
- QTRY_VERIFY(machine.configuration().contains(s4));
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- TEST_ACTIVE_CHANGED(s3, 2);
- TEST_ACTIVE_CHANGED(s4, 1);
-}
-
-class SignalEmitterThread : public QThread
-{
- Q_OBJECT
-public:
- SignalEmitterThread(QObject *parent = 0)
- : QThread(parent)
- {
- moveToThread(this);
- }
-
-Q_SIGNALS:
- void signal1();
- void signal2();
-
-public Q_SLOTS:
- void emitSignals()
- {
- emit signal1();
- emit signal2();
- }
-};
-
-// QTBUG-19789
-void tst_QStateMachine::signalTransitionSenderInDifferentThread()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- SignalEmitterThread thread;
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- s1->addTransition(&thread, SIGNAL(signal1()), s2);
-
- QFinalState *s3 = new QFinalState(&machine);
- s2->addTransition(&thread, SIGNAL(signal2()), s3);
-
- thread.start();
- QTRY_VERIFY(thread.isRunning());
-
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s2, 0);
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- QMetaObject::invokeMethod(&thread, "emitSignals");
- // thread emits both signal1() and signal2(), so we should end in s3
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
- QTRY_VERIFY(!machine.isRunning());
- QTRY_VERIFY(machine.configuration().contains(s3));
-
- // Run the machine again; transitions should still be registered
- machine.start();
- TEST_ACTIVE_CHANGED(s1, 3);
- TEST_ACTIVE_CHANGED(s2, 2);
- QTRY_VERIFY(machine.configuration().contains(s1));
- QMetaObject::invokeMethod(&thread, "emitSignals");
- QTRY_VERIFY(machine.configuration().contains(s3));
-
- thread.quit();
- QTRY_VERIFY(thread.wait());
- TEST_ACTIVE_CHANGED(s1, 4);
- TEST_ACTIVE_CHANGED(s2, 4);
- QVERIFY(!machine.isRunning());
-}
-
-void tst_QStateMachine::signalTransitionSenderInDifferentThread2()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
-
- QState *s2 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s2);
- SignalEmitter emitter;
- // At the time of the transition creation, the machine and the emitter
- // are both in the same thread.
- s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2);
-
- QFinalState *s3 = new QFinalState(&machine);
- s2->addTransition(&emitter, SIGNAL(signalWithDefaultArg()), s3);
-
- QThread thread;
- // Move the machine and its states to a secondary thread, but let the
- // SignalEmitter stay in the main thread.
- machine.moveToThread(&thread);
-
- thread.start();
- QTRY_VERIFY(thread.isRunning());
-
- QSignalSpy runningSpy(&machine, &QStateMachine::runningChanged);
- QVERIFY(runningSpy.isValid());
- QSignalSpy startedSpy(&machine, &QStateMachine::started);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- machine.start();
- QTRY_COMPARE(startedSpy.count(), 1);
- TEST_RUNNING_CHANGED(true);
-
- emitter.emitSignalWithNoArg();
- // The second emission should not get "lost".
- emitter.emitSignalWithDefaultArg();
- QTRY_COMPARE(finishedSpy.count(), 1);
- TEST_RUNNING_CHANGED(false);
-
- thread.quit();
- QTRY_VERIFY(thread.wait());
- TEST_ACTIVE_CHANGED(s1, 2);
- TEST_ACTIVE_CHANGED(s2, 2);
-}
-
-class SignalTransitionMutatorThread : public QThread
-{
-public:
- SignalTransitionMutatorThread(QSignalTransition *transition)
- : m_transition(transition)
- {}
- void run()
- {
- // Cause repeated registration and unregistration
- for (int i = 0; i < 50000; ++i) {
- m_transition->setSenderObject(this);
- m_transition->setSenderObject(0);
- }
- }
-private:
- QSignalTransition *m_transition;
-};
-
-// Should not crash:
-void tst_QStateMachine::signalTransitionRegistrationThreadSafety()
-{
- QStateMachine machine;
- QState *s1 = new QState(&machine);
- DEFINE_ACTIVE_SPY(s1);
- machine.setInitialState(s1);
- machine.start();
- QTRY_VERIFY(machine.configuration().contains(s1));
-
- QSignalTransition *t1 = new QSignalTransition();
- t1->setSignal(SIGNAL(objectNameChanged(QString)));
- s1->addTransition(t1);
-
- QSignalTransition *t2 = new QSignalTransition();
- t2->setSignal(SIGNAL(objectNameChanged(QString)));
- s1->addTransition(t2);
-
- SignalTransitionMutatorThread thread(t1);
- thread.start();
- QTRY_VERIFY(thread.isRunning());
-
- // Cause repeated registration and unregistration
- for (int i = 0; i < 50000; ++i) {
- t2->setSenderObject(this);
- t2->setSenderObject(0);
- }
-
- thread.quit();
- QTRY_VERIFY(thread.wait());
- TEST_ACTIVE_CHANGED(s1, 1);
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::childModeConstructor()
-{
- {
- QStateMachine machine(QState::ExclusiveStates);
- QCOMPARE(machine.childMode(), QState::ExclusiveStates);
- QVERIFY(!machine.parent());
- QVERIFY(!machine.parentState());
- }
- {
- QStateMachine machine(QState::ParallelStates);
- QCOMPARE(machine.childMode(), QState::ParallelStates);
- QVERIFY(!machine.parent());
- QVERIFY(!machine.parentState());
- }
- {
- QStateMachine machine(QState::ExclusiveStates, this);
- QCOMPARE(machine.childMode(), QState::ExclusiveStates);
- QCOMPARE(machine.parent(), static_cast<QObject *>(this));
- QVERIFY(!machine.parentState());
- }
- {
- QStateMachine machine(QState::ParallelStates, this);
- QCOMPARE(machine.childMode(), QState::ParallelStates);
- QCOMPARE(machine.parent(), static_cast<QObject *>(this));
- QVERIFY(!machine.parentState());
- }
- QState state;
- {
- QStateMachine machine(QState::ExclusiveStates, &state);
- QCOMPARE(machine.childMode(), QState::ExclusiveStates);
- QCOMPARE(machine.parent(), static_cast<QObject *>(&state));
- QCOMPARE(machine.parentState(), &state);
- }
- {
- QStateMachine machine(QState::ParallelStates, &state);
- QCOMPARE(machine.childMode(), QState::ParallelStates);
- QCOMPARE(machine.parent(), static_cast<QObject *>(&state));
- QCOMPARE(machine.parentState(), &state);
- }
-}
-
-void tst_QStateMachine::qtbug_44963()
-{
- SignalEmitter emitter;
-
- QStateMachine machine;
- QState a(QState::ParallelStates, &machine);
- QHistoryState ha(QHistoryState::DeepHistory, &a);
- QState b(QState::ParallelStates, &a);
- QState c(QState::ParallelStates, &b);
- QState d(QState::ParallelStates, &c);
- QState e(QState::ParallelStates, &d);
- QState i(&e);
- QState i1(&i);
- QState i2(&i);
- QState j(&e);
- QState h(&d);
- QState g(&c);
- QState k(&a);
- QState l(&machine);
-
- machine.setInitialState(&a);
- ha.setDefaultState(&b);
- i.setInitialState(&i1);
- i1.addTransition(&emitter, SIGNAL(signalWithIntArg(int)), &i2)->setObjectName("i1->i2");
- i2.addTransition(&emitter, SIGNAL(signalWithDefaultArg(int)), &l)->setObjectName("i2->l");
- l.addTransition(&emitter, SIGNAL(signalWithNoArg()), &ha)->setObjectName("l->ha");
-
- a.setObjectName("a");
- ha.setObjectName("ha");
- b.setObjectName("b");
- c.setObjectName("c");
- d.setObjectName("d");
- e.setObjectName("e");
- i.setObjectName("i");
- i1.setObjectName("i1");
- i2.setObjectName("i2");
- j.setObjectName("j");
- h.setObjectName("h");
- g.setObjectName("g");
- k.setObjectName("k");
- l.setObjectName("l");
-
- machine.start();
-
- QTRY_COMPARE(machine.configuration().contains(&i1), true);
- QTRY_COMPARE(machine.configuration().contains(&i2), false);
- QTRY_COMPARE(machine.configuration().contains(&j), true);
- QTRY_COMPARE(machine.configuration().contains(&h), true);
- QTRY_COMPARE(machine.configuration().contains(&g), true);
- QTRY_COMPARE(machine.configuration().contains(&k), true);
- QTRY_COMPARE(machine.configuration().contains(&l), false);
-
- emitter.emitSignalWithIntArg(0);
-
- QTRY_COMPARE(machine.configuration().contains(&i1), false);
- QTRY_COMPARE(machine.configuration().contains(&i2), true);
- QTRY_COMPARE(machine.configuration().contains(&j), true);
- QTRY_COMPARE(machine.configuration().contains(&h), true);
- QTRY_COMPARE(machine.configuration().contains(&g), true);
- QTRY_COMPARE(machine.configuration().contains(&k), true);
- QTRY_COMPARE(machine.configuration().contains(&l), false);
-
- emitter.emitSignalWithDefaultArg();
-
- QTRY_COMPARE(machine.configuration().contains(&i1), false);
- QTRY_COMPARE(machine.configuration().contains(&i2), false);
- QTRY_COMPARE(machine.configuration().contains(&j), false);
- QTRY_COMPARE(machine.configuration().contains(&h), false);
- QTRY_COMPARE(machine.configuration().contains(&g), false);
- QTRY_COMPARE(machine.configuration().contains(&k), false);
- QTRY_COMPARE(machine.configuration().contains(&l), true);
-
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(machine.configuration().contains(&i1), false);
- QTRY_COMPARE(machine.configuration().contains(&i2), true);
- QTRY_COMPARE(machine.configuration().contains(&j), true);
- QTRY_COMPARE(machine.configuration().contains(&h), true);
- QTRY_COMPARE(machine.configuration().contains(&g), true);
- QTRY_COMPARE(machine.configuration().contains(&k), true);
- QTRY_COMPARE(machine.configuration().contains(&l), false);
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::qtbug_44783()
-{
- SignalEmitter emitter;
-
- QStateMachine machine;
- QState s(&machine);
- QState p(QState::ParallelStates, &s);
- QState p1(&p);
- QState p1_1(&p1);
- QState p1_2(&p1);
- QState p2(&p);
- QState s1(&machine);
-
- machine.setInitialState(&s);
- s.setInitialState(&p);
- p1.setInitialState(&p1_1);
- p1_1.addTransition(&emitter, SIGNAL(signalWithNoArg()), &p1_2)->setObjectName("p1_1->p1_2");
- p2.addTransition(&emitter, SIGNAL(signalWithNoArg()), &s1)->setObjectName("p2->s1");
-
- s.setObjectName("s");
- p.setObjectName("p");
- p1.setObjectName("p1");
- p1_1.setObjectName("p1_1");
- p1_2.setObjectName("p1_2");
- p2.setObjectName("p2");
- s1.setObjectName("s1");
-
- machine.start();
-
- QTRY_COMPARE(machine.configuration().contains(&s), true);
- QTRY_COMPARE(machine.configuration().contains(&p), true);
- QTRY_COMPARE(machine.configuration().contains(&p1), true);
- QTRY_COMPARE(machine.configuration().contains(&p1_1), true);
- QTRY_COMPARE(machine.configuration().contains(&p1_2), false);
- QTRY_COMPARE(machine.configuration().contains(&p2), true);
- QTRY_COMPARE(machine.configuration().contains(&s1), false);
-
- emitter.emitSignalWithNoArg();
-
- // Only one of the following two can be true, because the two possible transitions conflict.
- if (machine.configuration().contains(&s1)) {
- // the transition p2 -> s1 was taken, not p1_1 -> p1_2, so:
- // the parallel state exited, so none of the states inside it are active
- QTRY_COMPARE(machine.configuration().contains(&s), false);
- QTRY_COMPARE(machine.configuration().contains(&p), false);
- QTRY_COMPARE(machine.configuration().contains(&p1), false);
- QTRY_COMPARE(machine.configuration().contains(&p1_1), false);
- QTRY_COMPARE(machine.configuration().contains(&p1_2), false);
- QTRY_COMPARE(machine.configuration().contains(&p2), false);
- } else {
- // the transition p1_1 -> p1_2 was taken, not p2 -> s1, so:
- // the parallel state was not exited and the state is the same as the start state with one
- // difference: p1_1 inactive and p1_2 active:
- QTRY_COMPARE(machine.configuration().contains(&s), true);
- QTRY_COMPARE(machine.configuration().contains(&p), true);
- QTRY_COMPARE(machine.configuration().contains(&p1), true);
- QTRY_COMPARE(machine.configuration().contains(&p1_1), false);
- QTRY_COMPARE(machine.configuration().contains(&p1_2), true);
- QTRY_COMPARE(machine.configuration().contains(&p2), true);
- }
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::internalTransition()
-{
- SignalEmitter emitter;
-
- QStateMachine machine;
- QState *s = new QState(&machine);
- QState *s1 = new QState(s);
- QState *s11 = new QState(s1);
-
- DEFINE_ACTIVE_SPY(s);
- DEFINE_ACTIVE_SPY(s1);
- DEFINE_ACTIVE_SPY(s11);
-
- machine.setInitialState(s);
- s->setInitialState(s1);
- s1->setInitialState(s11);
- QSignalTransition *t = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s11);
- t->setObjectName("s1->s11");
- t->setTransitionType(QAbstractTransition::InternalTransition);
-
- s->setObjectName("s");
- s1->setObjectName("s1");
- s11->setObjectName("s11");
-
- machine.start();
-
- QTRY_COMPARE(machine.configuration().contains(s), true);
- QTRY_COMPARE(machine.configuration().contains(s1), true);
- QTRY_COMPARE(machine.configuration().contains(s11), true);
- TEST_ACTIVE_CHANGED(s, 1);
- TEST_ACTIVE_CHANGED(s1, 1);
- TEST_ACTIVE_CHANGED(s11, 1);
-
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(machine.configuration().contains(s), true);
- QTRY_COMPARE(machine.configuration().contains(s1), true);
- QTRY_COMPARE(machine.configuration().contains(s11), true);
- TEST_ACTIVE_CHANGED(s11, 3);
- TEST_ACTIVE_CHANGED(s1, 1); // external transitions will return 3, internal transitions should return 1.
- TEST_ACTIVE_CHANGED(s, 1);
-}
-
-void tst_QStateMachine::conflictingTransition()
-{
- SignalEmitter emitter;
-
- QStateMachine machine;
- QState b(QState::ParallelStates, &machine);
- QState c(&b);
- QState d(QState::ParallelStates, &b);
- QState e(&d);
- QState e1(&e);
- QState e2(&e);
- QState f(&d);
- QState f1(&f);
- QState f2(&f);
- QState a1(&machine);
-
- machine.setInitialState(&b);
- e.setInitialState(&e1);
- f.setInitialState(&f1);
- c.addTransition(&emitter, SIGNAL(signalWithNoArg()), &a1)->setObjectName("c->a1");
- e1.addTransition(&emitter, SIGNAL(signalWithNoArg()), &e2)->setObjectName("e1->e2");
- f1.addTransition(&emitter, SIGNAL(signalWithNoArg()), &f2)->setObjectName("f1->f2");
-
- b.setObjectName("b");
- c.setObjectName("c");
- d.setObjectName("d");
- e.setObjectName("e");
- e1.setObjectName("e1");
- e2.setObjectName("e2");
- f.setObjectName("f");
- f1.setObjectName("f1");
- f2.setObjectName("f2");
- a1.setObjectName("a1");
-
- machine.start();
-
- QTRY_COMPARE(machine.configuration().contains(&b), true);
- QTRY_COMPARE(machine.configuration().contains(&c), true);
- QTRY_COMPARE(machine.configuration().contains(&d), true);
- QTRY_COMPARE(machine.configuration().contains(&e), true);
- QTRY_COMPARE(machine.configuration().contains(&e1), true);
- QTRY_COMPARE(machine.configuration().contains(&e2), false);
- QTRY_COMPARE(machine.configuration().contains(&f), true);
- QTRY_COMPARE(machine.configuration().contains(&f1), true);
- QTRY_COMPARE(machine.configuration().contains(&f2), false);
- QTRY_COMPARE(machine.configuration().contains(&a1), false);
-
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(machine.configuration().contains(&b), true);
- QTRY_COMPARE(machine.configuration().contains(&c), true);
- QTRY_COMPARE(machine.configuration().contains(&d), true);
- QTRY_COMPARE(machine.configuration().contains(&e), true);
- QTRY_COMPARE(machine.configuration().contains(&e1), false);
- QTRY_COMPARE(machine.configuration().contains(&e2), true);
- QTRY_COMPARE(machine.configuration().contains(&f), true);
- QTRY_COMPARE(machine.configuration().contains(&f1), false);
- QTRY_COMPARE(machine.configuration().contains(&f2), true);
- QTRY_COMPARE(machine.configuration().contains(&a1), false);
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::conflictingTransition2()
-{
- SignalEmitter emitter;
-
- QStateMachine machine;
- QState s0(&machine);
- QState p0(QState::ParallelStates, &s0);
- QState p0s1(&p0);
- QState p0s2(&p0);
- QState p0s3(&p0);
- QState s1(&machine);
-
- machine.setInitialState(&s0);
- s0.setInitialState(&p0);
-
- QSignalTransition *t1 = new QSignalTransition(&emitter, SIGNAL(signalWithNoArg()));
- p0s1.addTransition(t1);
- QSignalTransition *t2 = p0s2.addTransition(&emitter, SIGNAL(signalWithNoArg()), &p0s1);
- QSignalTransition *t3 = p0s3.addTransition(&emitter, SIGNAL(signalWithNoArg()), &s1);
- QSignalSpy t1Spy(t1, &QAbstractTransition::triggered);
- QSignalSpy t2Spy(t2, &QAbstractTransition::triggered);
- QSignalSpy t3Spy(t3, &QAbstractTransition::triggered);
- QVERIFY(t1Spy.isValid());
- QVERIFY(t2Spy.isValid());
- QVERIFY(t3Spy.isValid());
-
- s0.setObjectName("s0");
- p0.setObjectName("p0");
- p0s1.setObjectName("p0s1");
- p0s2.setObjectName("p0s2");
- p0s3.setObjectName("p0s3");
- s1.setObjectName("s1");
- t1->setObjectName("p0s1->p0s1");
- t2->setObjectName("p0s2->p0s1");
- t3->setObjectName("p0s3->s1");
-
- machine.start();
-
- QTRY_COMPARE(machine.configuration().contains(&s0), true);
- QTRY_COMPARE(machine.configuration().contains(&p0), true);
- QTRY_COMPARE(machine.configuration().contains(&p0s1), true);
- QTRY_COMPARE(machine.configuration().contains(&p0s2), true);
- QTRY_COMPARE(machine.configuration().contains(&p0s3), true);
- QTRY_COMPARE(machine.configuration().contains(&s1), false);
-
- QCOMPARE(t1Spy.count(), 0);
- QCOMPARE(t2Spy.count(), 0);
- QCOMPARE(t3Spy.count(), 0);
-
- emitter.emitSignalWithNoArg();
-
- QTRY_COMPARE(machine.configuration().contains(&s0), true);
- QTRY_COMPARE(machine.configuration().contains(&p0), true);
- QTRY_COMPARE(machine.configuration().contains(&p0s1), true);
- QTRY_COMPARE(machine.configuration().contains(&p0s2), true);
- QTRY_COMPARE(machine.configuration().contains(&p0s3), true);
- QTRY_COMPARE(machine.configuration().contains(&s1), false);
-
- QCOMPARE(t1Spy.count(), 1);
- QCOMPARE(t2Spy.count(), 1);
- QCOMPARE(t3Spy.count(), 0); // t3 got preempted by t2
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::qtbug_46059()
-{
- QStateMachine machine;
- QState a(&machine);
- QState b(&a);
- QState c(&a);
- QState success(&a);
- QState failure(&machine);
-
- machine.setInitialState(&a);
- a.setInitialState(&b);
- b.addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), &c));
- c.addTransition(new EventTransition(QEvent::Type(QEvent::User + 2), &success));
- b.addTransition(new EventTransition(QEvent::Type(QEvent::User + 2), &failure));
-
- machine.start();
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(machine.configuration().contains(&a), true);
- QTRY_COMPARE(machine.configuration().contains(&b), true);
- QTRY_COMPARE(machine.configuration().contains(&c), false);
- QTRY_COMPARE(machine.configuration().contains(&failure), false);
- QTRY_COMPARE(machine.configuration().contains(&success), false);
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 0)), QStateMachine::HighPriority);
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)), QStateMachine::HighPriority);
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 2)), QStateMachine::NormalPriority);
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(machine.configuration().contains(&a), true);
- QTRY_COMPARE(machine.configuration().contains(&b), false);
- QTRY_COMPARE(machine.configuration().contains(&c), false);
- QTRY_COMPARE(machine.configuration().contains(&failure), false);
- QTRY_COMPARE(machine.configuration().contains(&success), true);
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::qtbug_46703()
-{
- QStateMachine machine;
- QState root(&machine);
- QHistoryState h(&root);
- QState p(QState::ParallelStates, &root);
- QState a(&p);
- QState a1(&a);
- QState a2(&a);
- QState a3(&a);
- QState b(&p);
- QState b1(&b);
- QState b2(&b);
-
- machine.setObjectName("machine");
- root.setObjectName("root");
- h.setObjectName("h");
- p.setObjectName("p");
- a.setObjectName("a");
- a1.setObjectName("a1");
- a2.setObjectName("a2");
- a3.setObjectName("a3");
- b.setObjectName("b");
- b1.setObjectName("b1");
- b2.setObjectName("b2");
-
- machine.setInitialState(&root);
- root.setInitialState(&h);
- a.setInitialState(&a3);
- b.setInitialState(&b1);
- struct : public QAbstractTransition {
- virtual bool eventTest(QEvent *) { return false; }
- virtual void onTransition(QEvent *) {}
- } defaultTransition;
- defaultTransition.setTargetStates(QList<QAbstractState*>() << &a2 << &b2);
- h.setDefaultTransition(&defaultTransition);
-
- machine.start();
- QCoreApplication::processEvents();
-
- QTRY_COMPARE(machine.configuration().contains(&root), true);
- QTRY_COMPARE(machine.configuration().contains(&h), false);
- QTRY_COMPARE(machine.configuration().contains(&p), true);
- QTRY_COMPARE(machine.configuration().contains(&a), true);
- QTRY_COMPARE(machine.configuration().contains(&a1), false);
- QTRY_COMPARE(machine.configuration().contains(&a2), true);
- QTRY_COMPARE(machine.configuration().contains(&a3), false);
- QTRY_COMPARE(machine.configuration().contains(&b), true);
- QTRY_COMPARE(machine.configuration().contains(&b1), false);
- QTRY_COMPARE(machine.configuration().contains(&b2), true);
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::postEventFromBeginSelectTransitions()
-{
- class StateMachine : public QStateMachine {
- protected:
- void beginSelectTransitions(QEvent* e) override {
- if (e->type() == QEvent::Type(QEvent::User + 2))
- postEvent(new QEvent(QEvent::Type(QEvent::User + 1)), QStateMachine::HighPriority);
- }
- } machine;
- QState a(&machine);
- QState success(&machine);
-
- machine.setInitialState(&a);
- a.addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), &success));
-
- machine.start();
-
- QTRY_COMPARE(machine.configuration().contains(&a), true);
- QTRY_COMPARE(machine.configuration().contains(&success), false);
-
- machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 2)), QStateMachine::NormalPriority);
-
- QTRY_COMPARE(machine.configuration().contains(&a), false);
- QTRY_COMPARE(machine.configuration().contains(&success), true);
-
- QVERIFY(machine.isRunning());
-}
-
-void tst_QStateMachine::dontProcessSlotsWhenMachineIsNotRunning()
-{
- QStateMachine machine;
- QState initialState;
- QFinalState finalState;
-
- struct Emitter : SignalEmitter
- {
- QThread thread;
- Emitter(QObject *parent = nullptr) : SignalEmitter(parent)
- {
- moveToThread(&thread);
- thread.start();
- }
- } emitter;
-
- initialState.addTransition(&emitter, &Emitter::signalWithNoArg, &finalState);
- QTimer::singleShot(0, [&]() {
- metaObject()->invokeMethod(&emitter, "emitSignalWithNoArg");
- metaObject()->invokeMethod(&emitter, "emitSignalWithNoArg");
- });
- machine.addState(&initialState);
- machine.addState(&finalState);
- machine.setInitialState(&initialState);
- connect(&machine, &QStateMachine::finished, &emitter.thread, &QThread::quit);
- machine.start();
- QSignalSpy emittedSpy(&emitter, &SignalEmitter::signalWithNoArg);
- QSignalSpy finishedSpy(&machine, &QStateMachine::finished);
- QTRY_COMPARE_WITH_TIMEOUT(emittedSpy.count(), 2, 100);
- QTRY_COMPARE(finishedSpy.count(), 1);
- QTRY_VERIFY(emitter.thread.isFinished());
-}
-
-QTEST_MAIN(tst_QStateMachine)
-#include "tst_qstatemachine.moc"
diff --git a/tests/auto/corelib/statemachine/statemachine.pro b/tests/auto/corelib/statemachine/statemachine.pro
deleted file mode 100644
index aa645ac9f4..0000000000
--- a/tests/auto/corelib/statemachine/statemachine.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- qstate \
- qstatemachine
diff --git a/tests/auto/corelib/text/CMakeLists.txt b/tests/auto/corelib/text/CMakeLists.txt
new file mode 100644
index 0000000000..099f0e7eef
--- /dev/null
+++ b/tests/auto/corelib/text/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qanystringview)
+add_subdirectory(qbytearray)
+add_subdirectory(qbytearray_large)
+add_subdirectory(qbytearrayapisymmetry)
+add_subdirectory(qbytearraylist)
+add_subdirectory(qbytearraymatcher)
+add_subdirectory(qbytearrayview)
+add_subdirectory(qbytedatabuffer)
+add_subdirectory(qchar)
+add_subdirectory(qcollator)
+add_subdirectory(qlatin1stringmatcher)
+add_subdirectory(qlatin1stringview)
+add_subdirectory(qregularexpression)
+add_subdirectory(qstring)
+add_subdirectory(qstring_no_cast_from_bytearray)
+add_subdirectory(qstringapisymmetry)
+add_subdirectory(qstringbuilder)
+add_subdirectory(qstringconverter)
+add_subdirectory(qstringiterator)
+add_subdirectory(qstringlist)
+add_subdirectory(qstringmatcher)
+add_subdirectory(qstringtokenizer)
+add_subdirectory(qstringview)
+add_subdirectory(qtextboundaryfinder)
+add_subdirectory(qunicodetools)
+add_subdirectory(qlocale)
diff --git a/tests/auto/corelib/text/qanystringview/.gitignore b/tests/auto/corelib/text/qanystringview/.gitignore
new file mode 100644
index 0000000000..f127febb38
--- /dev/null
+++ b/tests/auto/corelib/text/qanystringview/.gitignore
@@ -0,0 +1 @@
+tst_qanystringview
diff --git a/tests/auto/corelib/text/qanystringview/CMakeLists.txt b/tests/auto/corelib/text/qanystringview/CMakeLists.txt
new file mode 100644
index 0000000000..96837dadf6
--- /dev/null
+++ b/tests/auto/corelib/text/qanystringview/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringview Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qanystringview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qanystringview
+ SOURCES
+ tst_qanystringview.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp
new file mode 100644
index 0000000000..0eaadb870c
--- /dev/null
+++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp
@@ -0,0 +1,918 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QAnyStringView>
+#include <QChar>
+#include <QDebug>
+#include <QList>
+#include <QString>
+#include <QStringBuilder>
+#include <QVarLengthArray>
+#if QT_CONFIG(cpp_winrt)
+# include <private/qt_winrtbase_p.h>
+#endif
+#include <private/qxmlstream_p.h>
+#include <private/qcomparisontesthelper_p.h>
+
+#include <QTest>
+
+#include <string>
+#include <string_view>
+#include <array>
+#include <vector>
+#include <algorithm>
+#include <memory>
+#include <q20iterator.h>
+
+// for negative testing (can't convert from)
+#include <deque>
+#include <list>
+
+#ifdef __cpp_char8_t
+# define ONLY_IF_CHAR_8_T(expr) expr
+#else
+# define ONLY_IF_CHAR_8_T(expr) \
+ QSKIP("This test requires C++20 char8_t support enabled in the compiler.")
+#endif
+
+#ifdef __cpp_lib_char8_t
+# define ONLY_IF_LIB_CHAR_8_T(expr) expr
+#else
+# define ONLY_IF_LIB_CHAR_8_T(expr) \
+ QSKIP("This test requires C++20 char8_t support enabled in the standard library.")
+#endif
+
+#ifdef Q_OS_WIN
+# define ONLY_WIN(expr) expr
+#else
+# define ONLY_WIN(expr) QSKIP("This is a Windows-only test")
+#endif
+
+#ifdef __cpp_impl_three_way_comparison
+# define ONLY_3WAY(expr) expr
+#else
+# define ONLY_3WAY(expr) \
+ QSKIP("This test requires C++20 spaceship operator (<=>) " \
+ "support enabled in the standard library.")
+#endif
+
+using namespace Qt::StringLiterals;
+
+template <typename T>
+constexpr inline bool CanConvert = std::is_convertible_v<T, QAnyStringView>;
+
+static_assert(CanConvert<QLatin1String>);
+static_assert(CanConvert<const char*>);
+static_assert(CanConvert<QByteArray>);
+
+template <typename T>
+struct ImplicitlyConvertibleTo
+{
+ operator T() const;
+};
+
+static_assert(CanConvert<ImplicitlyConvertibleTo<QString>>);
+static_assert(CanConvert<ImplicitlyConvertibleTo<QByteArray>>);
+static_assert(!CanConvert<ImplicitlyConvertibleTo<QLatin1StringView>>);
+
+// QAnyStringView qchar_does_not_compile() { return QAnyStringView(QChar('a')); }
+// QAnyStringView qlatin1string_does_not_compile() { return QAnyStringView(QLatin1String("a")); }
+// QAnyStringView const_char_star_does_not_compile() { return QAnyStringView("a"); }
+// QAnyStringView qbytearray_does_not_compile() { return QAnyStringView(QByteArray("a")); }
+
+//
+// QChar
+//
+
+static_assert(CanConvert<QChar>);
+
+static_assert(CanConvert<QChar[123]>);
+
+static_assert(CanConvert< QString >);
+static_assert(CanConvert<const QString >);
+static_assert(CanConvert< QString&>);
+static_assert(CanConvert<const QString&>);
+
+//
+// ushort
+//
+
+static_assert(CanConvert<ushort>);
+
+static_assert(CanConvert<ushort[123]>);
+
+static_assert(CanConvert< ushort*>);
+static_assert(CanConvert<const ushort*>);
+
+static_assert(CanConvert<QList<ushort>>);
+static_assert(CanConvert<QVarLengthArray<ushort>>);
+static_assert(CanConvert<std::vector<ushort>>);
+static_assert(CanConvert<std::array<ushort, 123>>);
+static_assert(!CanConvert<std::deque<ushort>>);
+static_assert(!CanConvert<std::list<ushort>>);
+
+#ifdef __cpp_char8_t
+
+//
+// char8_t
+//
+
+static_assert(CanConvert<char8_t>);
+
+static_assert(CanConvert< char8_t*>);
+static_assert(CanConvert<const char8_t*>);
+
+#ifdef __cpp_lib_char8_t
+
+static_assert(CanConvert< std::u8string >);
+static_assert(CanConvert<const std::u8string >);
+static_assert(CanConvert< std::u8string&>);
+static_assert(CanConvert<const std::u8string&>);
+
+static_assert(CanConvert< std::u8string_view >);
+static_assert(CanConvert<const std::u8string_view >);
+static_assert(CanConvert< std::u8string_view&>);
+static_assert(CanConvert<const std::u8string_view&>);
+
+#endif // __cpp_lib_char8_t
+
+static_assert(CanConvert<QList<char8_t>>);
+static_assert(CanConvert<QVarLengthArray<char8_t>>);
+static_assert(CanConvert<std::vector<char8_t>>);
+static_assert(CanConvert<std::array<char8_t, 123>>);
+static_assert(!CanConvert<std::deque<char8_t>>);
+static_assert(!CanConvert<std::list<char8_t>>);
+
+#endif // __cpp_char8_t
+
+//
+// char16_t
+//
+
+static_assert(CanConvert<char16_t>);
+
+static_assert(CanConvert< char16_t*>);
+static_assert(CanConvert<const char16_t*>);
+
+static_assert(CanConvert< std::u16string >);
+static_assert(CanConvert<const std::u16string >);
+static_assert(CanConvert< std::u16string&>);
+static_assert(CanConvert<const std::u16string&>);
+
+static_assert(CanConvert< std::u16string_view >);
+static_assert(CanConvert<const std::u16string_view >);
+static_assert(CanConvert< std::u16string_view&>);
+static_assert(CanConvert<const std::u16string_view&>);
+
+static_assert(CanConvert<QList<char16_t>>);
+static_assert(CanConvert<QVarLengthArray<char16_t>>);
+static_assert(CanConvert<std::vector<char16_t>>);
+static_assert(CanConvert<std::array<char16_t, 123>>);
+static_assert(!CanConvert<std::deque<char16_t>>);
+static_assert(!CanConvert<std::list<char16_t>>);
+
+static_assert(CanConvert<QtPrivate::XmlStringRef>);
+
+//
+// char32_t
+//
+
+// Qt Policy: char32_t isn't supported
+
+static_assert(CanConvert<char32_t>); // ... except here
+
+static_assert(!CanConvert< char32_t*>);
+static_assert(!CanConvert<const char32_t*>);
+
+static_assert(!CanConvert< std::u32string >);
+static_assert(!CanConvert<const std::u32string >);
+static_assert(!CanConvert< std::u32string&>);
+static_assert(!CanConvert<const std::u32string&>);
+
+static_assert(!CanConvert< std::u32string_view >);
+static_assert(!CanConvert<const std::u32string_view >);
+static_assert(!CanConvert< std::u32string_view&>);
+static_assert(!CanConvert<const std::u32string_view&>);
+
+static_assert(!CanConvert<QList<char32_t>>);
+static_assert(!CanConvert<QVarLengthArray<char32_t>>);
+static_assert(!CanConvert<std::vector<char32_t>>);
+static_assert(!CanConvert<std::array<char32_t, 123>>);
+static_assert(!CanConvert<std::deque<char32_t>>);
+static_assert(!CanConvert<std::list<char32_t>>);
+
+//
+// wchar_t
+//
+
+constexpr bool CanConvertFromWCharT =
+#ifdef Q_OS_WIN
+ true
+#else
+ false
+#endif
+ ;
+
+static_assert(CanConvert<wchar_t> == CanConvertFromWCharT); // ### FIXME: should work everywhere
+
+static_assert(CanConvert< wchar_t*> == CanConvertFromWCharT);
+static_assert(CanConvert<const wchar_t*> == CanConvertFromWCharT);
+
+static_assert(CanConvert< std::wstring > == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring > == CanConvertFromWCharT);
+static_assert(CanConvert< std::wstring&> == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring&> == CanConvertFromWCharT);
+
+static_assert(CanConvert< std::wstring_view > == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring_view > == CanConvertFromWCharT);
+static_assert(CanConvert< std::wstring_view&> == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring_view&> == CanConvertFromWCharT);
+
+static_assert(CanConvert<QList<wchar_t>> == CanConvertFromWCharT);
+static_assert(CanConvert<QVarLengthArray<wchar_t>> == CanConvertFromWCharT);
+static_assert(CanConvert<std::vector<wchar_t>> == CanConvertFromWCharT);
+static_assert(CanConvert<std::array<wchar_t, 123>> == CanConvertFromWCharT);
+static_assert(!CanConvert<std::deque<wchar_t>>);
+static_assert(!CanConvert<std::list<wchar_t>>);
+
+//
+// QStringBuilder
+//
+
+static_assert(CanConvert<QStringBuilder<QString, QString>>);
+
+#if QT_CONFIG(cpp_winrt)
+
+//
+// winrt::hstring (QTBUG-111886)
+//
+
+static_assert(CanConvert< winrt::hstring >);
+static_assert(CanConvert<const winrt::hstring >);
+static_assert(CanConvert< winrt::hstring&>);
+static_assert(CanConvert<const winrt::hstring&>);
+
+#endif // QT_CONFIG(cpp_winrt)
+
+// In bootstrapped build and in Qt 7+, two lower bits of size() are used as a
+// mask, so check that it is handled correctly, and the mask does not break the
+// actual size
+template <typename Char> struct SampleStrings
+{
+ static constexpr char emptyString[] = "";
+ static constexpr char oneChar[] = "a";
+ static constexpr char twoChars[] = "ab";
+ static constexpr char threeChars[] = "abc";
+ static constexpr char regularString[] = "Hello World!";
+ static constexpr char regularLongString[] = R"(Lorem ipsum dolor sit amet, consectetur
+adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
+ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
+voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
+id est laborum.)";
+ static constexpr char stringWithNulls[] = "Hello\0World\0!";
+ static constexpr qsizetype stringWithNullsLength = std::size(stringWithNulls) -1;
+};
+
+template <> struct SampleStrings<char16_t>
+{
+ static constexpr char16_t emptyString[] = u"";
+ static constexpr char16_t oneChar[] = u"a";
+ static constexpr char16_t twoChars[] = u"ab";
+ static constexpr char16_t threeChars[] = u"abc";
+ static constexpr char16_t regularString[] = u"Hello World!";
+ static constexpr char16_t regularLongString[] = uR"(Lorem ipsum dolor sit amet, consectetur
+adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
+ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
+voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
+id est laborum.)";
+ static constexpr char16_t stringWithNulls[] = u"Hello\0World\0!";
+ static constexpr qsizetype stringWithNullsLength = std::size(stringWithNulls) -1;
+};
+
+template <> struct SampleStrings<QChar>
+{
+ static constexpr QChar emptyString[] = { {} }; // this one is easy
+ static const QChar *const oneChar;
+ static const QChar *const twoChars;
+ static const QChar *const threeChars;
+ static const QChar *const regularString;
+ static const QChar *const regularLongString;
+ static const QChar *const stringWithNulls;
+ static constexpr qsizetype stringWithNullsLength = SampleStrings<char16_t>::stringWithNullsLength;
+};
+const QChar *const SampleStrings<QChar>::oneChar =
+ reinterpret_cast<const QChar *>(SampleStrings<char16_t>::oneChar);
+const QChar *const SampleStrings<QChar>::twoChars =
+ reinterpret_cast<const QChar *>(SampleStrings<char16_t>::twoChars);
+const QChar *const SampleStrings<QChar>::threeChars =
+ reinterpret_cast<const QChar *>(SampleStrings<char16_t>::threeChars);
+const QChar *const SampleStrings<QChar>::regularString =
+ reinterpret_cast<const QChar *>(SampleStrings<char16_t>::regularString);
+const QChar *const SampleStrings<QChar>::regularLongString =
+ reinterpret_cast<const QChar *>(SampleStrings<char16_t>::regularLongString);
+const QChar *const SampleStrings<QChar>::stringWithNulls =
+ reinterpret_cast<const QChar *>(SampleStrings<char16_t>::stringWithNulls);
+
+class tst_QAnyStringView : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void constExpr() const;
+ void basics() const;
+ void debug() const;
+ void asciiLiteralIsLatin1() const;
+
+ void fromQString() const { fromQStringOrByteArray<QString>(); }
+ void fromQByteArray() const { fromQStringOrByteArray<QByteArray>(); }
+ void fromQStringView() const { fromQStringOrByteArray<QStringView>(); }
+ void fromQUtf8StringView() const { fromQStringOrByteArray<QUtf8StringView>(); }
+ void fromQLatin1StringView() const { fromQStringOrByteArray<QLatin1StringView>(); }
+
+ void fromCharArray() const { fromArray<char>(); }
+ void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray<char8_t>()); }
+ void fromChar16Array() const { fromArray<char16_t>(); }
+ void fromQCharArray() const { fromArray<QChar>(); }
+ void fromWCharTArray() const { ONLY_WIN(fromArray<wchar_t>()); }
+
+ void fromQCharStar() const
+ {
+ const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
+ fromLiteral(str);
+ }
+
+ void fromUShortStar() const
+ {
+ const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
+ fromLiteral(str);
+ }
+
+ void fromChar8TStar() const
+ {
+ fromLiteral(u8"Hello, World!"); // char[] in <= C++17, char8_t[] in >= C++20
+ }
+
+ void fromChar16TStar() const { fromLiteral(u"Hello, World!"); }
+ void fromWCharTStar() const { ONLY_WIN(fromLiteral(L"Hello, World!")); }
+
+ void fromCharRange() const { fromRange<char>(); }
+ void fromChar8TRange() const { ONLY_IF_CHAR_8_T(fromRange<char8_t>()); }
+ void fromQCharRange() const { fromRange<QChar>(); }
+ void fromUShortRange() const { fromRange<ushort>(); }
+ void fromChar16TRange() const { fromRange<char16_t>(); }
+ void fromWCharTRange() const { ONLY_WIN(fromRange<wchar_t>()); }
+
+ // std::basic_string
+ void fromStdStringChar() const { fromStdString<char>(); }
+ void fromStdStringChar8T() const { ONLY_IF_LIB_CHAR_8_T(fromStdString<char8_t>()); }
+ void fromStdStringWCharT() const { ONLY_WIN(fromStdString<wchar_t>()); }
+ void fromStdStringChar16T() const { fromStdString<char16_t>(); }
+
+ void fromUShortContainers() const { fromContainers<ushort>(); }
+ void fromQCharContainers() const { fromContainers<QChar>(); }
+ void fromChar16TContainers() const { fromContainers<char16_t>(); }
+ void fromWCharTContainers() const { ONLY_WIN(fromContainers<wchar_t>()); }
+
+ void fromQStringBuilder_QString_QString() const { fromQStringBuilder(u"1"_s % u"2"_s, u"12"); }
+
+ void comparisonCompiles();
+ void comparison_data();
+ void comparison();
+
+private:
+ template <typename StringBuilder>
+ void fromQStringBuilder(StringBuilder &&sb, QStringView expected) const;
+ template <typename Char>
+ void fromArray() const;
+ template <typename String>
+ void conversion_tests(String arg) const;
+ template <typename Char>
+ void fromLiteral(const Char *arg) const;
+ template <typename Char>
+ void fromRange() const;
+ template <typename Char, typename Container>
+ void fromContainer() const;
+ template <typename Char>
+ void fromContainers() const;
+ template <typename Char>
+ void fromStdString() const { fromContainer<Char, std::basic_string<Char> >(); }
+ template <typename QStringOrByteArray>
+ void fromQStringOrByteArray() const;
+};
+
+void tst_QAnyStringView::constExpr() const
+{
+#define IS_NULL(sv) \
+ do { \
+ static_assert(sv.size() == 0); \
+ static_assert(sv.isNull()); \
+ static_assert(sv.empty()); \
+ static_assert(sv.isEmpty()); \
+ static_assert(sv.data() == nullptr); \
+ } while (false) \
+ /*end*/
+#define IS_EMPTY(sv) \
+ do { \
+ static_assert(sv.size() == 0); \
+ static_assert(!sv.isNull()); \
+ static_assert(sv.empty()); \
+ static_assert(sv.isEmpty()); \
+ static_assert(sv.data() != nullptr); \
+ } while (false) \
+ /*end*/
+#define IS_OF_SIZE(sv, sz) \
+ do { \
+ static_assert(sv.size() == sz); \
+ static_assert(!sv.isNull()); \
+ static_assert(!sv.empty()); \
+ static_assert(!sv.isEmpty()); \
+ static_assert(sv.data() != nullptr); \
+ } while (false) \
+ /*end*/
+
+ // compile-time checks
+ {
+ constexpr QAnyStringView sv;
+ IS_NULL(sv);
+ }
+ {
+ constexpr const char *nul = nullptr;
+ constexpr QAnyStringView sv(nul, 0);
+ IS_NULL(sv);
+ }
+ {
+ constexpr const char16_t *nul = nullptr;
+ constexpr QAnyStringView sv(nul, 0);
+ IS_NULL(sv);
+ }
+#ifdef __cpp_char8_t
+ {
+ constexpr const char8_t *nul = nullptr;
+ constexpr QAnyStringView sv(nul, 0);
+ IS_NULL(sv);
+ }
+#endif // __cpp_char8_t
+ {
+ constexpr QAnyStringView sv = nullptr;
+ IS_NULL(sv);
+ }
+ {
+ constexpr QAnyStringView sv = "";
+ IS_EMPTY(sv);
+ }
+ {
+ constexpr QAnyStringView sv = u8"";
+ IS_EMPTY(sv);
+ }
+ {
+ constexpr QAnyStringView sv = u"";
+ IS_EMPTY(sv);
+ }
+ {
+ constexpr QAnyStringView sv = u"Hello";
+ IS_OF_SIZE(sv, 5);
+
+ constexpr QAnyStringView sv2 = sv;
+ IS_OF_SIZE(sv2, 5);
+ }
+#undef IS_OF_SIZE
+#undef IS_EMPTY
+#undef IS_NULL
+}
+
+void tst_QAnyStringView::basics() const
+{
+ QAnyStringView sv1;
+
+ // a default-constructed QAnyStringView is null:
+ QVERIFY(sv1.isNull());
+ // which implies it's empty();
+ QVERIFY(sv1.isEmpty());
+
+ QAnyStringView sv2;
+
+ QVERIFY(sv2 == sv1);
+ QVERIFY(!(sv2 != sv1));
+}
+
+void tst_QAnyStringView::debug() const
+{
+ #ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
+ # define MAYBE_L1(str) str "_L1"
+ # define VERIFY_L1(s) QVERIFY(s.isLatin1())
+ #else
+ # define MAYBE_L1(str) "u8" str
+ # define VERIFY_L1(s) QVERIFY(s.isUtf8())
+ #endif
+ #define CHECK1(s, mod, expected) do { \
+ QString result; \
+ QDebug(&result) mod << "X"_L1 << s << "Y"_L1; \
+ /* QDebug appends an eager ' ', so trim before comparison */ \
+ /* We use X and Y affixes so we can still check spacing */ \
+ /* around the QAnyStringView itself. */ \
+ QCOMPARE(result.trimmed(), expected); \
+ } while (false)
+ #define CHECK(init, esq, eq, es, e) do { \
+ QAnyStringView s = init; \
+ CHECK1(s, , esq); \
+ CHECK1(s, .nospace(), eq); \
+ CHECK1(s, .noquote(), es); \
+ CHECK1(s, .nospace().noquote(), e); \
+ } while (false)
+
+ CHECK(nullptr,
+ R"("X" u8"" "Y")",
+ R"("X"u8"""Y")",
+ R"(X Y)",
+ R"(XY)");
+ CHECK(QLatin1StringView(nullptr),
+ R"("X" ""_L1 "Y")",
+ R"("X"""_L1"Y")",
+ R"(X Y)",
+ R"(XY)");
+ CHECK(QUtf8StringView(nullptr),
+ R"("X" u8"" "Y")",
+ R"("X"u8"""Y")",
+ R"(X Y)",
+ R"(XY)");
+ CHECK(QStringView(nullptr),
+ R"("X" u"" "Y")",
+ R"("X"u"""Y")",
+ R"(X Y)",
+ R"(XY)");
+ {
+ constexpr QAnyStringView asv = "hello";
+ VERIFY_L1(asv); // ### fails when asv isn't constexpr
+ CHECK(asv,
+ R"("X" )" MAYBE_L1(R"("hello")") R"( "Y")",
+ R"("X")" MAYBE_L1(R"("hello")") R"("Y")",
+ R"(X hello Y)",
+ R"(XhelloY)");
+ }
+ CHECK(u8"hällo",
+ R"("X" u8"h\xC3\xA4llo" "Y")",
+ R"("X"u8"h\xC3\xA4llo""Y")",
+ R"(X hällo Y)",
+ R"(XhälloY)");
+ CHECK(u"hällo",
+ R"("X" u"hällo" "Y")",
+ R"("X"u"hällo""Y")",
+ R"(X hällo Y)",
+ R"(XhälloY)");
+
+ #undef CHECK
+ #undef CHECK1
+ #undef VERIFY_L1
+ #undef MAYBE_L1
+}
+
+void tst_QAnyStringView::asciiLiteralIsLatin1() const
+{
+ if constexpr (QAnyStringView::detects_US_ASCII_at_compile_time) {
+ constexpr bool asciiCstringIsLatin1 = QAnyStringView("Hello, World").isLatin1();
+ QVERIFY(asciiCstringIsLatin1);
+ constexpr bool asciiUtf8stringIsLatin1 = QAnyStringView(u8"Hello, World").isLatin1();
+ QVERIFY(asciiUtf8stringIsLatin1);
+ constexpr bool utf8StringIsNotLatin1 = !QAnyStringView(u8"Tørrfisk").isLatin1();
+ QVERIFY(utf8StringIsNotLatin1);
+ constexpr bool asciiCstringArrayIsLatin1 =
+ QAnyStringView::fromArray("Hello, World").isLatin1();
+ QVERIFY(asciiCstringArrayIsLatin1);
+ constexpr bool asciiUtfstringArrayIsLatin1 =
+ QAnyStringView::fromArray(u8"Hello, World").isLatin1();
+ QVERIFY(asciiUtfstringArrayIsLatin1);
+ constexpr bool utf8StringArrayIsNotLatin1 =
+ !QAnyStringView::fromArray(u8"Tørrfisk").isLatin1();
+ QVERIFY(utf8StringArrayIsNotLatin1);
+ } else {
+ QSKIP("Compile-detection of US-ASCII strings not possible with this compiler");
+ }
+}
+
+template <typename StringBuilder>
+void tst_QAnyStringView::fromQStringBuilder(StringBuilder &&sb, QStringView expected) const
+{
+ auto toAnyStringView = [](QAnyStringView sv) { return sv; };
+ QCOMPARE(toAnyStringView(std::forward<StringBuilder>(sb)), expected);
+}
+
+template <typename Char>
+void tst_QAnyStringView::fromArray() const
+{
+ constexpr Char hello[] = {'H', 'e', 'l', 'l', 'o', '\0', 'a', 'b', 'c', '\0', '\0', '.', '\0'};
+
+ QAnyStringView sv = QAnyStringView::fromArray(hello);
+ QCOMPARE(sv.size(), 13);
+ QVERIFY(!sv.empty());
+ QVERIFY(!sv.isEmpty());
+ QVERIFY(!sv.isNull());
+ QCOMPARE(sv.front(), 'H');
+ QCOMPARE(sv.back(), '\0');
+
+ const Char bytes[] = {'a', 'b', 'c'};
+ QAnyStringView sv2 = QAnyStringView::fromArray(bytes);
+ QCOMPARE(sv2.data(), static_cast<const void *>(bytes + 0));
+ QCOMPARE(sv2.size(), 3);
+ QCOMPARE(sv2.back(), u'c');
+}
+
+
+template <typename QStringOrByteArray>
+void tst_QAnyStringView::fromQStringOrByteArray() const
+{
+ using Char = std::remove_cv_t<typename QStringOrByteArray::value_type>;
+ using Strings = SampleStrings<Char>;
+
+ QStringOrByteArray null;
+ QStringOrByteArray empty(Strings::emptyString);
+
+ QVERIFY( QAnyStringView(null).isNull());
+ QVERIFY( QAnyStringView(null).isEmpty());
+ QVERIFY( QAnyStringView(empty).isEmpty());
+ QVERIFY(!QAnyStringView(empty).isNull());
+
+ conversion_tests(QStringOrByteArray(Strings::oneChar));
+ if (QTest::currentTestFailed())
+ return;
+ conversion_tests(QStringOrByteArray(Strings::twoChars));
+ if (QTest::currentTestFailed())
+ return;
+ conversion_tests(QStringOrByteArray(Strings::threeChars));
+ if (QTest::currentTestFailed())
+ return;
+ conversion_tests(QStringOrByteArray(Strings::regularString));
+ if (QTest::currentTestFailed())
+ return;
+ conversion_tests(QStringOrByteArray(Strings::regularLongString));
+ if (QTest::currentTestFailed())
+ return;
+ conversion_tests(QStringOrByteArray(Strings::stringWithNulls, Strings::stringWithNullsLength));
+}
+
+template <typename Char>
+void tst_QAnyStringView::fromLiteral(const Char *arg) const
+{
+ const Char *null = nullptr;
+ const Char empty[] = { Char{} };
+
+ QCOMPARE(QAnyStringView(null).size(), qsizetype(0));
+ QCOMPARE(QAnyStringView(null).data(), nullptr);
+ QCOMPARE(QAnyStringView(empty).size(), qsizetype(0));
+ QCOMPARE(static_cast<const void*>(QAnyStringView(empty).data()),
+ static_cast<const void*>(empty));
+
+ QVERIFY( QAnyStringView(null).isNull());
+ QVERIFY( QAnyStringView(null).isEmpty());
+ QVERIFY( QAnyStringView(empty).isEmpty());
+ QVERIFY(!QAnyStringView(empty).isNull());
+
+ conversion_tests(arg);
+}
+
+template <typename Char>
+void tst_QAnyStringView::fromRange() const
+{
+ auto doTest = [](const Char *first, const Char *last) {
+ QCOMPARE(QAnyStringView(first, first).size(), 0);
+ QCOMPARE(static_cast<const void*>(QAnyStringView(first, first).data()),
+ static_cast<const void*>(first));
+
+ const auto sv = QAnyStringView(first, last);
+ QCOMPARE(sv.size(), last - first);
+ QCOMPARE(static_cast<const void*>(sv.data()),
+ static_cast<const void*>(first));
+
+ // can't call conversion_tests() here, as it requires a single object
+ };
+ const Char *null = nullptr;
+ using RealChar = std::conditional_t<sizeof(Char) == 1, char, char16_t>;
+ using Strings = SampleStrings<RealChar>;
+
+ QCOMPARE(QAnyStringView(null, null).size(), 0);
+ QCOMPARE(QAnyStringView(null, null).data(), nullptr);
+
+ doTest(reinterpret_cast<const Char *>(std::begin(Strings::regularString)),
+ reinterpret_cast<const Char *>(std::end(Strings::regularString)));
+ if (QTest::currentTestFailed())
+ return;
+
+ doTest(reinterpret_cast<const Char *>(std::begin(Strings::regularLongString)),
+ reinterpret_cast<const Char *>(std::end(Strings::regularLongString)));
+ if (QTest::currentTestFailed())
+ return;
+
+ doTest(reinterpret_cast<const Char *>(std::begin(Strings::stringWithNulls)),
+ reinterpret_cast<const Char *>(std::end(Strings::stringWithNulls)));
+ if (QTest::currentTestFailed())
+ return;
+}
+
+template <typename Char, typename Container>
+void tst_QAnyStringView::fromContainer() const
+{
+ const std::string s = "Hello World!";
+ const std::string n(SampleStrings<char>::stringWithNulls, SampleStrings<char>::stringWithNullsLength);
+
+ Container c;
+ // unspecified whether empty containers make null QAnyStringViews
+ QVERIFY(QAnyStringView(c).isEmpty());
+
+ std::copy(s.begin(), s.end(), std::back_inserter(c));
+ conversion_tests(std::move(c));
+ if (QTest::currentTestFailed())
+ return;
+
+ // repeat with nulls
+ c = {};
+ std::copy(n.begin(), n.end(), std::back_inserter(c));
+ conversion_tests(std::move(c));
+}
+
+template <typename Char>
+void tst_QAnyStringView::fromContainers() const
+{
+ fromContainer<Char, QList<Char>>();
+ fromContainer<Char, QVarLengthArray<Char>>();
+ fromContainer<Char, std::vector<Char>>();
+}
+
+namespace help {
+ template <typename T>
+ auto ssize(T &t) { return q20::ssize(t); }
+
+ template <typename T>
+ qsizetype ssize(const T *t)
+ {
+ qsizetype result = 0;
+ if (t) {
+ while (*t++)
+ ++result;
+ }
+ return result;
+ }
+
+ qsizetype ssize(const QChar *t)
+ {
+ qsizetype result = 0;
+ if (t) {
+ while (!t++->isNull())
+ ++result;
+ }
+ return result;
+ }
+}
+
+template <typename String>
+void tst_QAnyStringView::conversion_tests(String string) const
+{
+ // copy-construct:
+ {
+ QAnyStringView sv = string;
+
+ QCOMPARE(help::ssize(sv), help::ssize(string));
+
+ QCOMPARE(sv, string);
+ }
+
+ QAnyStringView sv;
+
+ // copy-assign:
+ {
+ sv = string;
+
+ QCOMPARE(help::ssize(sv), help::ssize(string));
+
+ // check relational operators:
+
+ QCOMPARE(sv, string);
+ QCOMPARE(string, sv);
+
+ QVERIFY(!(sv != string));
+ QVERIFY(!(string != sv));
+
+ QVERIFY(!(sv < string));
+ QVERIFY(sv <= string);
+ QVERIFY(!(sv > string));
+ QVERIFY(sv >= string);
+
+ QVERIFY(!(string < sv));
+ QVERIFY(string <= sv);
+ QVERIFY(!(string > sv));
+ QVERIFY(string >= sv);
+ }
+
+ // copy-construct from rvalue (QAnyStringView never assumes ownership):
+ {
+ QAnyStringView sv2 = std::move(string);
+ QCOMPARE(sv2, sv);
+ QCOMPARE(sv2, string);
+ }
+
+ // copy-assign from rvalue (QAnyStringView never assumes ownership):
+ {
+ QAnyStringView sv2;
+ sv2 = std::move(string);
+ QCOMPARE(sv2, sv);
+ QCOMPARE(sv2, string);
+ }
+}
+
+void tst_QAnyStringView::comparisonCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, char16_t>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QChar>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, const char16_t *>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, const char *>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QByteArray>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QByteArrayView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QString>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QStringView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QUtf8StringView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QAnyStringView, QLatin1StringView>();
+}
+
+void tst_QAnyStringView::comparison_data()
+{
+ QTest::addColumn<QAnyStringView>("lhs");
+ QTest::addColumn<QAnyStringView>("rhs");
+ QTest::addColumn<int>("csr"); // case sensitive result
+ QTest::addColumn<int>("cir"); // case insensitive result
+
+ auto row = [&](QAnyStringView l, QAnyStringView r, int csr, int cir) {
+ QTest::addRow("%s_vs_%s", qPrintable(l.toString()), qPrintable(r.toString()))
+ << l << r << csr << cir;
+ };
+ row(u"aa", u"aa", 0, 0);
+ row(u"aa", u"AA", 1, 0);
+ row(u"ab", u"b", -1, -1);
+ row(u"ab", u"aBb", 1, -1);
+ row(u"ab", u"B", 1, -1);
+}
+
+static int sign(int x)
+{
+ return x == 0 ? 0 : (x < 0 ? -1 : 1);
+}
+
+void tst_QAnyStringView::comparison()
+{
+ QFETCH(const QAnyStringView, lhs);
+ QFETCH(const QAnyStringView, rhs);
+ QFETCH(const int, csr);
+ QFETCH(const int, cir);
+
+ QCOMPARE(sign(QAnyStringView::compare(lhs, rhs)), csr);
+ QCOMPARE(sign(QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive)), cir);
+
+ const Qt::strong_ordering ordering = [&csr] {
+ if (csr == 0)
+ return Qt::strong_ordering::equal;
+ else if (csr < 0)
+ return Qt::strong_ordering::less;
+ else
+ return Qt::strong_ordering::greater;
+ }();
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, ordering);
+
+ const QString rhs_str = rhs.toString();
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_str, ordering);
+
+ const QStringView rhs_sv(rhs_str);
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_sv, ordering);
+
+ if (!rhs_str.contains(QChar(u'\0'))) {
+ const char16_t *utfData = reinterpret_cast<const char16_t*>(rhs_str.constData());
+ QT_TEST_ALL_COMPARISON_OPS(lhs, utfData, ordering);
+ }
+
+ if (rhs_str.size() == 1) {
+ const QChar ch = rhs_str.front();
+ QT_TEST_ALL_COMPARISON_OPS(lhs, ch, ordering);
+ }
+
+ if (rhs.isLatin1()) {
+ const QLatin1StringView rhs_l1 = rhs.asLatin1StringView();
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_l1, ordering);
+ }
+
+ const QByteArray rhs_u8 = rhs_str.toUtf8();
+
+ const QUtf8StringView rhs_u8sv(rhs_u8.data(), rhs_u8.size());
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_u8sv, ordering);
+
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_u8, ordering);
+ const QByteArrayView rhs_u8view{rhs_u8.begin(), rhs_u8.size()};
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_u8view, ordering);
+ if (!rhs_str.contains(QChar(u'\0'))) {
+ const char *rhs_u8data = rhs_u8.constData();
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs_u8data, ordering);
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QAnyStringView)
+#include "tst_qanystringview.moc"
diff --git a/tests/auto/corelib/tools/qbytearray/.gitignore b/tests/auto/corelib/text/qbytearray/.gitignore
index 3de7c3fab5..3de7c3fab5 100644
--- a/tests/auto/corelib/tools/qbytearray/.gitignore
+++ b/tests/auto/corelib/text/qbytearray/.gitignore
diff --git a/tests/auto/corelib/text/qbytearray/CMakeLists.txt b/tests/auto/corelib/text/qbytearray/CMakeLists.txt
new file mode 100644
index 0000000000..34307d9d44
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearray/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbytearray Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytearray LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbytearray
+ SOURCES
+ tst_qbytearray.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qbytearray CONDITION APPLE
+ SOURCES
+ tst_qbytearray_mac.mm
+ LIBRARIES
+ ${FWFoundation}
+)
diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp
new file mode 100644
index 0000000000..81d79da38b
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp
@@ -0,0 +1,2921 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <qbytearray.h>
+#include <qfile.h>
+#include <qhash.h>
+#include <limits.h>
+#include <private/qtools_p.h>
+
+#include "../shared/test_number_shared.h"
+
+#include <QtCore/q20iterator.h>
+#include <sstream>
+
+using namespace Qt::StringLiterals;
+
+class tst_QByteArray : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QByteArray();
+private slots:
+ // Note: much of the shared API is tested in ../qbytearrayapisymmetry/
+ void swap();
+ void qChecksum_data();
+ void qChecksum();
+ void constByteArray();
+ void leftJustified();
+ void rightJustified();
+ void setNum();
+ void iterators();
+ void reverseIterators();
+ void split_data();
+ void split();
+ void base64_data();
+ void base64();
+ void fromBase64_data();
+ void fromBase64();
+ void qvsnprintf();
+ void qstrlen();
+ void qstrnlen();
+ void qstrcpy();
+ void qstrncpy();
+ void chop_data();
+ void chop();
+ void prepend();
+ void prependExtended_data();
+ void prependExtended();
+ void append();
+ void appendFromRawData();
+ void appendExtended_data();
+ void appendExtended();
+ void appendEmptyNull();
+ void assign();
+ void assignShared();
+ void assignUsesPrependBuffer();
+ void insert();
+ void insertExtended_data();
+ void insertExtended();
+ void remove_data();
+ void remove();
+ void remove_extra();
+ void removeIf();
+ void erase();
+ void erase_single_arg();
+ void replace_data();
+ void replace();
+ void replaceWithSpecifiedLength();
+
+ void number();
+ void number_double_data();
+ void number_double();
+ void number_base_data();
+ void number_base();
+ void nullness();
+ void blockSizeCalculations();
+
+ void resizeAfterFromRawData();
+ void toFromHex_data();
+ void toFromHex();
+ void toFromPercentEncoding();
+ void fromPercentEncoding_data();
+ void fromPercentEncoding();
+ void toPercentEncoding_data();
+ void toPercentEncoding();
+ void pecentEncodingRoundTrip_data();
+ void pecentEncodingRoundTrip();
+
+ void qstrcmp_data();
+ void qstrcmp();
+ void compare_singular();
+ void compareCharStar_data();
+ void compareCharStar();
+
+ void repeatedSignature() const;
+ void repeated() const;
+ void repeated_data() const;
+
+ void byteRefDetaching() const;
+
+ void reserve();
+ void reserveExtended_data();
+ void reserveExtended();
+ void resize();
+ void movability_data();
+ void movability();
+ void literals();
+ void userDefinedLiterals();
+ void toUpperLower_data();
+ void toUpperLower();
+ void isUpper();
+ void isLower();
+
+ void macTypes();
+
+ void stdString();
+
+ void emptyAndClear();
+ void fill();
+ void dataPointers();
+ void truncate();
+ void trimmed_data();
+ void trimmed();
+ void simplified();
+ void simplified_data();
+ void left();
+ void right();
+ void mid();
+ void length();
+ void length_data();
+ void slice() const;
+};
+
+static const QByteArray::DataPointer staticStandard = {
+ nullptr,
+ const_cast<char *>("data"),
+ 4
+};
+static const QByteArray::DataPointer staticNotNullTerminated = {
+ nullptr,
+ const_cast<char *>("dataBAD"),
+ 4
+};
+
+template <typename String> String detached(String s)
+{
+ if (!s.isNull()) { // detaching loses nullness, but we need to preserve it
+ auto d = s.data();
+ Q_UNUSED(d);
+ }
+ return s;
+}
+
+template <class T> const T &verifyZeroTermination(const T &t) { return t; }
+
+QByteArray verifyZeroTermination(const QByteArray &ba)
+{
+ // This test does some evil stuff, it's all supposed to work.
+
+ QByteArray::DataPointer baDataPtr = const_cast<QByteArray &>(ba).data_ptr();
+
+ // Skip if !isMutable() as those offer no guarantees
+ if (!baDataPtr->isMutable())
+ return ba;
+
+ qsizetype baSize = ba.size();
+ char baTerminator = ba.constData()[baSize];
+ if ('\0' != baTerminator)
+ return QString::fromUtf8(
+ "*** Result ('%1') not null-terminated: 0x%2 ***").arg(QString::fromUtf8(ba))
+ .arg(baTerminator, 2, 16, QChar('0')).toUtf8();
+
+ // Skip mutating checks on shared strings
+ if (baDataPtr->isShared())
+ return ba;
+
+ const char *baData = ba.constData();
+ const QByteArray baCopy(baData, baSize); // Deep copy
+
+ const_cast<char *>(baData)[baSize] = 'x';
+ if ('x' != ba.constData()[baSize]) {
+ return "*** Failed to replace null-terminator in "
+ "result ('" + ba + "') ***";
+ }
+ if (ba != baCopy) {
+ return "*** Result ('" + ba + "') differs from its copy "
+ "after null-terminator was replaced ***";
+ }
+ const_cast<char *>(baData)[baSize] = '\0'; // Restore sanity
+
+ return ba;
+}
+
+// Overriding QTest's QCOMPARE, to check QByteArray for null termination
+#undef QCOMPARE
+#define QCOMPARE(actual, expected) \
+ do { \
+ if (!QTest::qCompare(verifyZeroTermination(actual), expected, \
+ #actual, #expected, __FILE__, __LINE__)) \
+ return; \
+ } while (0) \
+ /**/
+#undef QTEST
+#define QTEST(actual, testElement) \
+ do { \
+ if (!QTest::qTest(verifyZeroTermination(actual), testElement, \
+ #actual, #testElement, __FILE__, __LINE__)) \
+ return; \
+ } while (0) \
+ /**/
+
+Q_DECLARE_METATYPE(QByteArray::Base64DecodingStatus);
+
+tst_QByteArray::tst_QByteArray()
+{
+}
+
+void tst_QByteArray::qChecksum_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<uint>("len");
+ QTest::addColumn<Qt::ChecksumType>("standard");
+ QTest::addColumn<uint>("checksum");
+
+ // Examples from ISO 14443-3
+ QTest::newRow("1") << QByteArray("\x00\x00", 2) << 2U << Qt::ChecksumItuV41 << 0x1EA0U;
+ QTest::newRow("2") << QByteArray("\x12\x34", 2) << 2U << Qt::ChecksumItuV41 << 0xCF26U;
+ QTest::newRow("3") << QByteArray("\x00\x00\x00", 3) << 3U << Qt::ChecksumIso3309 << 0xC6CCU;
+ QTest::newRow("4") << QByteArray("\x0F\xAA\xFF", 3) << 3U << Qt::ChecksumIso3309 << 0xD1FCU;
+ QTest::newRow("5") << QByteArray("\x0A\x12\x34\x56", 4) << 4U << Qt::ChecksumIso3309 << 0xF62CU;
+}
+
+void tst_QByteArray::qChecksum()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(uint, len);
+ QFETCH(Qt::ChecksumType, standard);
+ QFETCH(uint, checksum);
+
+ QCOMPARE(data.size(), int(len));
+ if (standard == Qt::ChecksumIso3309) {
+ QCOMPARE(::qChecksum(QByteArrayView(data.constData(), len)), static_cast<quint16>(checksum));
+ }
+ QCOMPARE(::qChecksum(QByteArrayView(data.constData(), len), standard), static_cast<quint16>(checksum));
+}
+
+
+void tst_QByteArray::constByteArray()
+{
+ const char *ptr = "abc";
+ QByteArray cba = QByteArray::fromRawData(ptr, 3);
+ QVERIFY(cba.constData() == ptr);
+ cba.squeeze();
+ QVERIFY(cba.constData() == ptr);
+ cba.detach();
+ QVERIFY(cba.size() == 3);
+ QVERIFY(cba.capacity() == 3);
+ QVERIFY(cba.constData() != ptr);
+ QVERIFY(cba.constData()[0] == 'a');
+ QVERIFY(cba.constData()[1] == 'b');
+ QVERIFY(cba.constData()[2] == 'c');
+ QVERIFY(cba.constData()[3] == '\0');
+}
+
+void tst_QByteArray::leftJustified()
+{
+ QByteArray a;
+
+ QCOMPARE(a.leftJustified(3, '-'), QByteArray("---"));
+ QCOMPARE(a.leftJustified(2, ' '), QByteArray(" "));
+ QVERIFY(!a.isDetached());
+
+ a = "ABC";
+ QCOMPARE(a.leftJustified(5,'-'), QByteArray("ABC--"));
+ QCOMPARE(a.leftJustified(4,'-'), QByteArray("ABC-"));
+ QCOMPARE(a.leftJustified(4), QByteArray("ABC "));
+ QCOMPARE(a.leftJustified(3), QByteArray("ABC"));
+ QCOMPARE(a.leftJustified(2), QByteArray("ABC"));
+ QCOMPARE(a.leftJustified(1), QByteArray("ABC"));
+ QCOMPARE(a.leftJustified(0), QByteArray("ABC"));
+
+ QCOMPARE(a.leftJustified(4,' ',true), QByteArray("ABC "));
+ QCOMPARE(a.leftJustified(3,' ',true), QByteArray("ABC"));
+ QCOMPARE(a.leftJustified(2,' ',true), QByteArray("AB"));
+ QCOMPARE(a.leftJustified(1,' ',true), QByteArray("A"));
+ QCOMPARE(a.leftJustified(0,' ',true), QByteArray(""));
+}
+
+void tst_QByteArray::rightJustified()
+{
+ QByteArray a;
+
+ QCOMPARE(a.rightJustified(3, '-'), QByteArray("---"));
+ QCOMPARE(a.rightJustified(2, ' '), QByteArray(" "));
+ QVERIFY(!a.isDetached());
+
+ a="ABC";
+ QCOMPARE(a.rightJustified(5,'-'),QByteArray("--ABC"));
+ QCOMPARE(a.rightJustified(4,'-'),QByteArray("-ABC"));
+ QCOMPARE(a.rightJustified(4),QByteArray(" ABC"));
+ QCOMPARE(a.rightJustified(3),QByteArray("ABC"));
+ QCOMPARE(a.rightJustified(2),QByteArray("ABC"));
+ QCOMPARE(a.rightJustified(1),QByteArray("ABC"));
+ QCOMPARE(a.rightJustified(0),QByteArray("ABC"));
+
+ QCOMPARE(a.rightJustified(4,'-',true),QByteArray("-ABC"));
+ QCOMPARE(a.rightJustified(4,' ',true),QByteArray(" ABC"));
+ QCOMPARE(a.rightJustified(3,' ',true),QByteArray("ABC"));
+ QCOMPARE(a.rightJustified(2,' ',true),QByteArray("AB"));
+ QCOMPARE(a.rightJustified(1,' ',true),QByteArray("A"));
+ QCOMPARE(a.rightJustified(0,' ',true),QByteArray(""));
+ QCOMPARE(a,QByteArray("ABC"));
+}
+
+void tst_QByteArray::setNum()
+{
+ QByteArray a;
+ QCOMPARE(a.setNum(-1), QByteArray("-1"));
+ QCOMPARE(a.setNum(0), QByteArray("0"));
+ QCOMPARE(a.setNum(0, 2), QByteArray("0"));
+ QCOMPARE(a.setNum(0, 36), QByteArray("0"));
+ QCOMPARE(a.setNum(1), QByteArray("1"));
+ QCOMPARE(a.setNum(35, 36), QByteArray("z"));
+ QCOMPARE(a.setNum(37, 2), QByteArray("100101"));
+ QCOMPARE(a.setNum(37, 36), QByteArray("11"));
+
+ QCOMPARE(a.setNum(short(-1), 16), QByteArray("-1"));
+ QCOMPARE(a.setNum(int(-1), 16), QByteArray("-1"));
+ QCOMPARE(a.setNum(qlonglong(-1), 16), QByteArray("-1"));
+
+ QCOMPARE(a.setNum(short(-1), 10), QByteArray("-1"));
+ QCOMPARE(a.setNum(int(-1), 10), QByteArray("-1"));
+ QCOMPARE(a.setNum(qlonglong(-1), 10), QByteArray("-1"));
+
+ QCOMPARE(a.setNum(-123), QByteArray("-123"));
+ QCOMPARE(a.setNum(0x123, 16), QByteArray("123"));
+ QCOMPARE(a.setNum(short(123)), QByteArray("123"));
+
+ QCOMPARE(a.setNum(1.23), QByteArray("1.23"));
+ QCOMPARE(a.setNum(1.234567), QByteArray("1.23457"));
+
+ // Note that there are no 'long' overloads, so not all of the
+ // QString::setNum() tests can be re-used.
+ QCOMPARE(a.setNum(Q_INT64_C(123)), QByteArray("123"));
+ // 2^40 == 1099511627776
+ QCOMPARE(a.setNum(Q_INT64_C(-1099511627776)), QByteArray("-1099511627776"));
+ QCOMPARE(a.setNum(Q_UINT64_C(1099511627776)), QByteArray("1099511627776"));
+ QCOMPARE(a.setNum(Q_INT64_C(9223372036854775807)), // LLONG_MAX
+ QByteArray("9223372036854775807"));
+ QCOMPARE(a.setNum(-Q_INT64_C(9223372036854775807) - Q_INT64_C(1)),
+ QByteArray("-9223372036854775808"));
+ QCOMPARE(a.setNum(Q_UINT64_C(18446744073709551615)), // ULLONG_MAX
+ QByteArray("18446744073709551615"));
+ QCOMPARE(a.setNum(0.000000000931322574615478515625), QByteArray("9.31323e-10"));
+}
+
+void tst_QByteArray::iterators()
+{
+ QByteArray emptyArr;
+ QCOMPARE(emptyArr.constBegin(), emptyArr.constEnd());
+ QCOMPARE(emptyArr.cbegin(), emptyArr.cend());
+ QVERIFY(!emptyArr.isDetached());
+ QCOMPARE(emptyArr.begin(), emptyArr.end());
+
+ QByteArray a("0123456789");
+
+ auto it = a.begin();
+ auto constIt = a.cbegin();
+ qsizetype idx = 0;
+
+ QCOMPARE(*it, a[idx]);
+ QCOMPARE(*constIt, a[idx]);
+
+ it++;
+ constIt++;
+ idx++;
+ QCOMPARE(*it, a[idx]);
+ QCOMPARE(*constIt, a[idx]);
+
+ it += 5;
+ constIt += 5;
+ idx += 5;
+ QCOMPARE(*it, a[idx]);
+ QCOMPARE(*constIt, a[idx]);
+
+ it -= 3;
+ constIt -= 3;
+ idx -= 3;
+ QCOMPARE(*it, a[idx]);
+ QCOMPARE(*constIt, a[idx]);
+
+ it--;
+ constIt--;
+ idx--;
+ QCOMPARE(*it, a[idx]);
+ QCOMPARE(*constIt, a[idx]);
+}
+
+void tst_QByteArray::reverseIterators()
+{
+ QByteArray emptyArr;
+ QCOMPARE(emptyArr.crbegin(), emptyArr.crend());
+ QVERIFY(!emptyArr.isDetached());
+ QCOMPARE(emptyArr.rbegin(), emptyArr.rend());
+
+ QByteArray s = "1234";
+ QByteArray sr = s;
+ std::reverse(sr.begin(), sr.end());
+ const QByteArray &csr = sr;
+ QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin()));
+ QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin()));
+ QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin()));
+ QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin()));
+ QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin()));
+ QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin()));
+}
+
+void tst_QByteArray::split_data()
+{
+ QTest::addColumn<QByteArray>("sample");
+ QTest::addColumn<int>("size");
+
+ QTest::newRow("1") << QByteArray("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile") << 14;
+ QTest::newRow("2") << QByteArray("abcde") << 1;
+ QTest::newRow("one empty") << QByteArray("") << 1;
+ QTest::newRow("two empty") << QByteArray(" ") << 2;
+ QTest::newRow("three empty") << QByteArray(" ") << 3;
+ QTest::newRow("null") << QByteArray() << 1;
+}
+
+void tst_QByteArray::split()
+{
+ QFETCH(QByteArray, sample);
+ QFETCH(int, size);
+
+ QList<QByteArray> list = sample.split(' ');
+ QCOMPARE(list.size(), size);
+}
+
+void tst_QByteArray::swap()
+{
+ QByteArray b1 = "b1", b2 = "b2";
+ b1.swap(b2);
+ QCOMPARE(b1, QByteArray("b2"));
+ QCOMPARE(b2, QByteArray("b1"));
+}
+
+void tst_QByteArray::base64_data()
+{
+ QTest::addColumn<QByteArray>("rawdata");
+ QTest::addColumn<QByteArray>("base64");
+
+ QTest::newRow("null") << QByteArray() << QByteArray();
+ QTest::newRow("1") << QByteArray("") << QByteArray("");
+ QTest::newRow("2") << QByteArray("1") << QByteArray("MQ==");
+ QTest::newRow("3") << QByteArray("12") << QByteArray("MTI=");
+ QTest::newRow("4") << QByteArray("123") << QByteArray("MTIz");
+ QTest::newRow("5") << QByteArray("1234") << QByteArray("MTIzNA==");
+ QTest::newRow("6") << QByteArray("\n") << QByteArray("Cg==");
+ QTest::newRow("7") << QByteArray("a\n") << QByteArray("YQo=");
+ QTest::newRow("8") << QByteArray("ab\n") << QByteArray("YWIK");
+ QTest::newRow("9") << QByteArray("abc\n") << QByteArray("YWJjCg==");
+ QTest::newRow("a") << QByteArray("abcd\n") << QByteArray("YWJjZAo=");
+ QTest::newRow("b") << QByteArray("abcde\n") << QByteArray("YWJjZGUK");
+ QTest::newRow("c") << QByteArray("abcdef\n") << QByteArray("YWJjZGVmCg==");
+ QTest::newRow("d") << QByteArray("abcdefg\n") << QByteArray("YWJjZGVmZwo=");
+ QTest::newRow("e") << QByteArray("abcdefgh\n") << QByteArray("YWJjZGVmZ2gK");
+
+ QByteArray ba;
+ ba.resize(256);
+ for (int i = 0; i < 256; ++i)
+ ba[i] = i;
+ QTest::newRow("f") << ba << QByteArray("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==");
+
+ QTest::newRow("g") << QByteArray("foo\0bar", 7) << QByteArray("Zm9vAGJhcg==");
+ QTest::newRow("h") << QByteArray("f\xd1oo\x9ctar") << QByteArray("ZtFvb5x0YXI=");
+ QTest::newRow("i") << QByteArray("\"\0\0\0\0\0\0\"", 8) << QByteArray("IgAAAAAAACI=");
+}
+
+
+void tst_QByteArray::base64()
+{
+ QFETCH(QByteArray, rawdata);
+ QFETCH(QByteArray, base64);
+ QByteArray::FromBase64Result result;
+
+ result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(result);
+ QCOMPARE(result.decoded, rawdata);
+
+ QByteArray arr = base64;
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(result);
+ QCOMPARE(result.decoded, rawdata);
+
+ QByteArray arr64 = rawdata.toBase64();
+ QCOMPARE(arr64, base64);
+
+ arr64 = rawdata.toBase64(QByteArray::Base64Encoding);
+ QCOMPARE(arr64, base64);
+
+ QByteArray base64noequals = base64;
+ base64noequals.replace('=', "");
+ arr64 = rawdata.toBase64(QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals);
+ QCOMPARE(arr64, base64noequals);
+
+ QByteArray base64url = base64;
+ base64url.replace('/', '_').replace('+', '-');
+ arr64 = rawdata.toBase64(QByteArray::Base64UrlEncoding);
+ QCOMPARE(arr64, base64url);
+
+ QByteArray base64urlnoequals = base64url;
+ base64urlnoequals.replace('=', "");
+ arr64 = rawdata.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
+ QCOMPARE(arr64, base64urlnoequals);
+}
+
+//different from the previous test as the input are invalid
+void tst_QByteArray::fromBase64_data()
+{
+ QTest::addColumn<QByteArray>("rawdata");
+ QTest::addColumn<QByteArray>("base64");
+ QTest::addColumn<QByteArray::Base64DecodingStatus>("status");
+
+ QTest::newRow("1") << QByteArray("") << QByteArray(" ") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("2") << QByteArray("1") << QByteArray("MQ=") << QByteArray::Base64DecodingStatus::IllegalInputLength;
+ QTest::newRow("3") << QByteArray("12") << QByteArray("MTI ") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("4") << QByteArray("123") << QByteArray("M=TIz") << QByteArray::Base64DecodingStatus::IllegalInputLength;
+ QTest::newRow("5") << QByteArray("1234") << QByteArray("MTI zN A ") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("6") << QByteArray("\n") << QByteArray("Cg@") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("7") << QByteArray("a\n") << QByteArray("======YQo=") << QByteArray::Base64DecodingStatus::IllegalInputLength;
+ QTest::newRow("8") << QByteArray("ab\n") << QByteArray("Y\nWIK ") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("9") << QByteArray("abc\n") << QByteArray("YWJjCg=") << QByteArray::Base64DecodingStatus::IllegalInputLength;
+ QTest::newRow("a") << QByteArray("abcd\n") << QByteArray("YWJ\1j\x9cZAo=") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("b") << QByteArray("abcde\n") << QByteArray("YW JjZ\n G\tUK") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("c") << QByteArray("abcdef\n") << QByteArray("YWJjZGVmCg=") << QByteArray::Base64DecodingStatus::IllegalInputLength;
+ QTest::newRow("d") << QByteArray("abcdefg\n") << QByteArray("YWJ\rjZGVmZwo") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("e") << QByteArray("abcdefgh\n") << QByteArray("YWJjZGVmZ2gK====") << QByteArray::Base64DecodingStatus::IllegalPadding;
+
+ QByteArray ba;
+ ba.resize(256);
+ for (int i = 0; i < 256; ++i)
+ ba[i] = i;
+ QTest::newRow("f") << ba << QByteArray("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Nj\n"
+ "c4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1u\n"
+ "b3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpa\n"
+ "anqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd\n"
+ "3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w== ") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+
+
+ QTest::newRow("g") << QByteArray("foo\0bar", 7) << QByteArray("Zm9vAGJhcg=") << QByteArray::Base64DecodingStatus::IllegalInputLength;
+ QTest::newRow("h") << QByteArray("f\xd1oo\x9ctar") << QByteArray("ZtFvb5x 0YXI") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+ QTest::newRow("i") << QByteArray("\"\0\0\0\0\0\0\"", 8) << QByteArray("IgAAAAAAACI ") << QByteArray::Base64DecodingStatus::IllegalCharacter;
+}
+
+
+void tst_QByteArray::fromBase64()
+{
+ QFETCH(QByteArray, rawdata);
+ QFETCH(QByteArray, base64);
+ QFETCH(QByteArray::Base64DecodingStatus, status);
+
+ QByteArray::FromBase64Result result;
+
+ result = QByteArray::fromBase64Encoding(base64);
+ QVERIFY(result);
+ QCOMPARE(result.decoded, rawdata);
+
+ result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64Encoding);
+ QVERIFY(result);
+ QCOMPARE(result.decoded, rawdata);
+
+ result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(!result);
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+
+ QByteArray arr = base64;
+ QVERIFY(!arr.isDetached());
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(!arr.isEmpty());
+ QVERIFY(!result);
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+
+ arr.detach();
+ QVERIFY(arr.isDetached());
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(arr.isEmpty());
+ QVERIFY(!result);
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+
+ // try "base64url" encoding
+ QByteArray base64url = base64;
+ base64url.replace('/', '_').replace('+', '-');
+ result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding);
+ QVERIFY(result);
+ QCOMPARE(result.decoded, rawdata);
+
+ result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(!result);
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+
+ arr = base64url;
+ arr.detach();
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(arr.isEmpty());
+ QVERIFY(!result);
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+
+ if (base64 != base64url) {
+ // check that the invalid decodings fail
+ result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64UrlEncoding);
+ QVERIFY(result);
+ QVERIFY(result.decoded != rawdata);
+ result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64Encoding);
+ QVERIFY(result);
+ QVERIFY(result.decoded != rawdata);
+
+ result = QByteArray::fromBase64Encoding(base64, QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(!result);
+ QVERIFY(result.decoded.isEmpty());
+
+ arr = base64;
+ arr.detach();
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(arr.isEmpty());
+ QVERIFY(!result);
+ QVERIFY(result.decoded.isEmpty());
+
+ result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(!result);
+ QVERIFY(result.decoded.isEmpty());
+
+ arr = base64url;
+ arr.detach();
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64Encoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(arr.isEmpty());
+ QVERIFY(!result);
+ QVERIFY(result.decoded.isEmpty());
+ }
+
+ // also remove padding, if any, and test again. note that by doing
+ // that we might be sanitizing the illegal input, so we can't assume now
+ // that result will be invalid in all cases
+ {
+ auto rightmostNotEqualSign = std::find_if_not(base64url.rbegin(), base64url.rend(), [](char c) { return c == '='; });
+ base64url.chop(std::distance(base64url.rbegin(), rightmostNotEqualSign)); // no QByteArray::erase...
+ }
+
+ result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding);
+ QVERIFY(result);
+ QCOMPARE(result.decoded, rawdata);
+
+ result = QByteArray::fromBase64Encoding(base64url, QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors);
+ if (result) {
+ QCOMPARE(result.decoded, rawdata);
+ } else {
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+ }
+
+ arr = base64url;
+ arr.detach();
+ result = QByteArray::fromBase64Encoding(std::move(arr), QByteArray::Base64UrlEncoding | QByteArray::AbortOnBase64DecodingErrors);
+ QVERIFY(arr.isEmpty());
+ if (result) {
+ QCOMPARE(result.decoded, rawdata);
+ } else {
+ QCOMPARE(result.decodingStatus, status);
+ QVERIFY(result.decoded.isEmpty());
+ }
+}
+
+void tst_QByteArray::qvsnprintf()
+{
+ char buf[20];
+ memset(buf, 42, sizeof(buf));
+
+ QCOMPARE(::qsnprintf(buf, 10, "%s", "bubu"), 4);
+ QCOMPARE(static_cast<const char *>(buf), "bubu");
+#ifndef Q_CC_MSVC
+ // MSVC implementation of vsnprintf overwrites bytes after null terminator so this would fail.
+ QCOMPARE(buf[5], char(42));
+#endif
+
+ memset(buf, 42, sizeof(buf));
+ QCOMPARE(::qsnprintf(buf, 5, "%s", "bubu"), 4);
+ QCOMPARE(static_cast<const char *>(buf), "bubu");
+ QCOMPARE(buf[5], char(42));
+
+ memset(buf, 42, sizeof(buf));
+#ifdef Q_OS_WIN
+ // VS 2005 uses the Qt implementation of vsnprintf.
+# if defined(_MSC_VER)
+ QCOMPARE(::qsnprintf(buf, 3, "%s", "bubu"), -1);
+ QCOMPARE(static_cast<const char*>(buf), "bu");
+# else
+ // windows has to do everything different, of course.
+ QCOMPARE(::qsnprintf(buf, 3, "%s", "bubu"), -1);
+ buf[19] = '\0';
+ QCOMPARE(static_cast<const char *>(buf), "bub****************");
+# endif
+#else
+ QCOMPARE(::qsnprintf(buf, 3, "%s", "bubu"), 4);
+ QCOMPARE(static_cast<const char*>(buf), "bu");
+#endif
+ QCOMPARE(buf[4], char(42));
+
+#ifndef Q_OS_WIN
+ memset(buf, 42, sizeof(buf));
+ QCOMPARE(::qsnprintf(buf, 10, ""), 0);
+#endif
+}
+
+
+void tst_QByteArray::qstrlen()
+{
+ const char *src = "Something about ... \0 a string.";
+ QCOMPARE(::qstrlen(nullptr), size_t(0));
+ QCOMPARE(::qstrlen(src), size_t(20));
+}
+
+void tst_QByteArray::qstrnlen()
+{
+ const char *src = "Something about ... \0 a string.";
+ QCOMPARE(::qstrnlen(nullptr, 1), size_t(0));
+ QCOMPARE(::qstrnlen(src, 31), size_t(20));
+ QCOMPARE(::qstrnlen(src, 19), size_t(19));
+ QCOMPARE(::qstrnlen(src, 21), size_t(20));
+ QCOMPARE(::qstrnlen(src, 20), size_t(20));
+}
+
+void tst_QByteArray::qstrcpy()
+{
+ const char *src = "Something about ... \0 a string.";
+ const char *expected = "Something about ... ";
+ char dst[128];
+
+ QCOMPARE(::qstrcpy(0, 0), (char*)0);
+ QCOMPARE(::qstrcpy(dst, 0), (char*)0);
+
+ QCOMPARE(::qstrcpy(dst ,src), (char *)dst);
+ QCOMPARE((char *)dst, const_cast<char *>(expected));
+}
+
+void tst_QByteArray::qstrncpy()
+{
+ QByteArray src(1024, 'a'), dst(1024, 'b');
+
+ // dst == nullptr
+ QCOMPARE(::qstrncpy(0, src.data(), 0), (char*)0);
+ QCOMPARE(::qstrncpy(0, src.data(), 10), (char*)0);
+
+ // src == nullptr
+ QCOMPARE(::qstrncpy(dst.data(), 0, 0), (char*)0);
+ QCOMPARE(*dst.data(), 'b'); // must not have written to dst
+ QCOMPARE(::qstrncpy(dst.data(), 0, 10), (char*)0);
+ QCOMPARE(*dst.data(), '\0'); // must have written to dst
+ *dst.data() = 'b'; // restore
+
+ // valid pointers, but len == 0
+ QCOMPARE(::qstrncpy(dst.data(), src.data(), 0), dst.data());
+ QCOMPARE(*dst.data(), 'b'); // must not have written to dst
+
+ // normal copy
+ QCOMPARE(::qstrncpy(dst.data(), src.data(), src.size()), dst.data());
+
+ src = QByteArray( "Tumdelidum" );
+ QCOMPARE(QByteArray(::qstrncpy(dst.data(), src.data(), src.size())),
+ QByteArray("Tumdelidu"));
+
+ // normal copy with length is longer than necessary
+ src = QByteArray( "Tumdelidum\0foo" );
+ dst.resize(128*1024);
+ QCOMPARE(QByteArray(::qstrncpy(dst.data(), src.data(), dst.size())),
+ QByteArray("Tumdelidum"));
+}
+
+void tst_QByteArray::chop_data()
+{
+ QTest::addColumn<QByteArray>("src");
+ QTest::addColumn<int>("choplength");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("1") << QByteArray("short1") << 128 << QByteArray();
+ QTest::newRow("2") << QByteArray("short2") << int(strlen("short2"))
+ << QByteArray();
+ QTest::newRow("3") << QByteArray("abcdef\0foo", 10) << 2
+ << QByteArray("abcdef\0f", 8);
+ QTest::newRow("4") << QByteArray("STARTTLS\r\n") << 2
+ << QByteArray("STARTTLS");
+ QTest::newRow("5") << QByteArray("") << 1 << QByteArray();
+ QTest::newRow("6") << QByteArray("foo") << 0 << QByteArray("foo");
+ QTest::newRow("7") << QByteArray(0) << 28 << QByteArray();
+ QTest::newRow("null 0") << QByteArray() << 0 << QByteArray();
+ QTest::newRow("null 10") << QByteArray() << 10 << QByteArray();
+}
+
+void tst_QByteArray::chop()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(int, choplength);
+ QFETCH(QByteArray, expected);
+
+ src.chop(choplength);
+ QCOMPARE(src, expected);
+}
+
+void tst_QByteArray::prepend()
+{
+ const char data[] = "data";
+
+ QCOMPARE(QByteArray().prepend(QByteArray()), QByteArray());
+ QCOMPARE(QByteArray().prepend('a'), QByteArray("a"));
+ QCOMPARE(QByteArray().prepend(2, 'a'), QByteArray("aa"));
+ QCOMPARE(QByteArray().prepend(QByteArray("data")), QByteArray("data"));
+ QCOMPARE(QByteArray().prepend(data), QByteArray("data"));
+ QCOMPARE(QByteArray().prepend(data, 2), QByteArray("da"));
+ QCOMPARE(QByteArray().prepend(QByteArrayView(data)), QByteArray("data"));
+
+ QByteArray ba("foo");
+ QCOMPARE(ba.prepend((char*)0), QByteArray("foo"));
+ QCOMPARE(ba.prepend(QByteArray()), QByteArray("foo"));
+ QCOMPARE(ba.prepend("1"), QByteArray("1foo"));
+ QCOMPARE(ba.prepend(QByteArray("2")), QByteArray("21foo"));
+ QCOMPARE(ba.prepend('3'), QByteArray("321foo"));
+ QCOMPARE(ba.prepend(-1, 'x'), QByteArray("321foo"));
+ QCOMPARE(ba.prepend(3, 'x'), QByteArray("xxx321foo"));
+ QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 xxx321foo", 11));
+
+ QByteArray tenChars;
+ tenChars.reserve(10);
+ QByteArray twoChars("ab");
+ tenChars.prepend(twoChars);
+ QCOMPARE(tenChars.capacity(), 10);
+}
+
+void tst_QByteArray::prependExtended_data()
+{
+ QTest::addColumn<QByteArray>("array");
+ QTest::newRow("literal") << QByteArray(QByteArrayLiteral("data"));
+ QTest::newRow("standard") << QByteArray(staticStandard);
+ QTest::newRow("notNullTerminated") << QByteArray(staticNotNullTerminated);
+ QTest::newRow("non static data") << QByteArray("data");
+ QTest::newRow("from raw data") << QByteArray::fromRawData("data", 4);
+ QTest::newRow("from raw data not terminated") << QByteArray::fromRawData("dataBAD", 4);
+}
+
+void tst_QByteArray::prependExtended()
+{
+ QFETCH(QByteArray, array);
+
+ QCOMPARE(QByteArray().prepend(array), QByteArray("data"));
+ QCOMPARE(QByteArray("").prepend(array), QByteArray("data"));
+
+ QCOMPARE(array.prepend((char*)0), QByteArray("data"));
+ QCOMPARE(array.prepend(QByteArray()), QByteArray("data"));
+ QCOMPARE(array.prepend("1"), QByteArray("1data"));
+ QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data"));
+ QCOMPARE(array.prepend('3'), QByteArray("321data"));
+ QCOMPARE(array.prepend(-1, 'x'), QByteArray("321data"));
+ QCOMPARE(array.prepend(3, 'x'), QByteArray("xxx321data"));
+ QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 xxx321data", 12));
+ QCOMPARE(array.size(), 12);
+}
+
+void tst_QByteArray::append()
+{
+ const char data[] = "data";
+
+ QCOMPARE(QByteArray().append(QByteArray()), QByteArray());
+ QCOMPARE(QByteArray().append('a'), QByteArray("a"));
+ QCOMPARE(QByteArray().append(2, 'a'), QByteArray("aa"));
+ QCOMPARE(QByteArray().append(QByteArray("data")), QByteArray("data"));
+ QCOMPARE(QByteArray().append(data), QByteArray("data"));
+ QCOMPARE(QByteArray().append(data, -1), QByteArray("data"));
+ QCOMPARE(QByteArray().append(data, 2), QByteArray("da"));
+ QCOMPARE(QByteArray().append(QByteArrayView(data)), QByteArray("data"));
+
+ QByteArray ba("foo");
+ QCOMPARE(ba.append((char*)0), QByteArray("foo"));
+ QCOMPARE(ba.append(QByteArray()), QByteArray("foo"));
+ QCOMPARE(ba.append("1"), QByteArray("foo1"));
+ QCOMPARE(ba.append(QByteArray("2")), QByteArray("foo12"));
+ QCOMPARE(ba.append('3'), QByteArray("foo123"));
+ QCOMPARE(ba.append(-1, 'x'), QByteArray("foo123"));
+ QCOMPARE(ba.append(3, 'x'), QByteArray("foo123xxx"));
+ QCOMPARE(ba.append("\0"), QByteArray("foo123xxx"));
+ QCOMPARE(ba.append("\0", 1), QByteArray::fromRawData("foo123xxx\0", 10));
+ QCOMPARE(ba.size(), 10);
+
+ QByteArray tenChars;
+ tenChars.reserve(10);
+ QByteArray twoChars("ab");
+ tenChars.append(twoChars);
+ QCOMPARE(tenChars.capacity(), 10);
+
+ {
+ QByteArray prepended("abcd");
+ prepended.prepend('a');
+ const qsizetype freeAtEnd = prepended.data_ptr()->freeSpaceAtEnd();
+ QVERIFY(prepended.size() + freeAtEnd < prepended.capacity());
+ prepended += QByteArray(freeAtEnd, 'b');
+ prepended.append('c');
+ QCOMPARE(prepended, QByteArray("aabcd") + QByteArray(freeAtEnd, 'b') + QByteArray("c"));
+ }
+
+ {
+ QByteArray prepended2("aaaaaaaaaa");
+ while (prepended2.size())
+ prepended2.remove(0, 1);
+ QVERIFY(prepended2.data_ptr()->freeSpaceAtBegin() > 0);
+ QByteArray array(prepended2.data_ptr()->freeSpaceAtEnd(), 'a');
+ prepended2 += array;
+ prepended2.append('b');
+ QCOMPARE(prepended2, array + QByteArray("b"));
+ }
+}
+
+void tst_QByteArray::appendFromRawData()
+{
+ char rawData[] = "Hello World!";
+ QByteArray ba = QByteArray::fromRawData(rawData, std::size(rawData) - 1);
+
+ QByteArray copy;
+ copy.append(ba);
+ QCOMPARE(copy, ba);
+ // We make an _actual_ copy, because appending a byte array
+ // created with fromRawData() might be optimized to copy the DataPointer,
+ // which means we may point to temporary stack data.
+ QCOMPARE_NE((void *)copy.constData(), (void *)ba.constData());
+}
+
+void tst_QByteArray::appendExtended_data()
+{
+ prependExtended_data();
+}
+
+void tst_QByteArray::appendExtended()
+{
+ QFETCH(QByteArray, array);
+
+ QCOMPARE(QByteArray().append(array), QByteArray("data"));
+ QCOMPARE(QByteArray("").append(array), QByteArray("data"));
+
+ QCOMPARE(array.append((char*)0), QByteArray("data"));
+ QCOMPARE(array.append(QByteArray()), QByteArray("data"));
+ QCOMPARE(array.append("1"), QByteArray("data1"));
+ QCOMPARE(array.append(QByteArray("2")), QByteArray("data12"));
+ QCOMPARE(array.append('3'), QByteArray("data123"));
+ QCOMPARE(array.append(-1, 'x'), QByteArray("data123"));
+ QCOMPARE(array.append(3, 'x'), QByteArray("data123xxx"));
+ QCOMPARE(array.append("\0"), QByteArray("data123xxx"));
+ QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123xxx\0", 11));
+ QCOMPARE(array.size(), 11);
+}
+
+void tst_QByteArray::appendEmptyNull()
+{
+ QByteArray a;
+ QVERIFY(a.isEmpty());
+ QVERIFY(a.isNull());
+
+ QByteArray b("");
+ QVERIFY(b.isEmpty());
+ QVERIFY(!b.isNull());
+
+ // Concatenating a null and an empty-but-not-null byte arrays results in
+ // an empty but not null byte array
+ QByteArray r = a + b;
+ QVERIFY(r.isEmpty());
+ QVERIFY(!r.isNull());
+}
+
+void tst_QByteArray::assign()
+{
+ // QByteArray &assign(QByteArrayView)
+ {
+ QByteArray ba;
+ QByteArray test("data");
+ QCOMPARE(ba.assign(test), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "data\0data";
+ QCOMPARE(ba.assign(test), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "data\0data"_ba;
+ QCOMPARE(ba.assign(test), test);
+ QCOMPARE(ba.size(), test.size());
+ }
+ // QByteArray &assign(qsizetype, char);
+ {
+ QByteArray ba;
+ QByteArray test("ddd");
+ QCOMPARE(ba.assign(3, 'd'), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "xx";
+ QCOMPARE(ba.assign(20, 'd').assign(2, 'x'), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "ddddd";
+ QCOMPARE(ba.assign(0, 'x').assign(5, 'd'), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "\0\0\0"_ba;
+ QCOMPARE(ba.assign(0, 'x').assign(3, '\0'), test);
+ QCOMPARE(ba.size(), test.size());
+ }
+ // QByteArray &assign(InputIterator, InputIterator)
+ {
+ QByteArray ba;
+ QByteArrayView test;
+
+ QList<char> l = {'\0', 'T', 'E', 'S', 'T'};
+ ba.assign(l.begin(), l.end());
+ test = "\0TEST"_ba;
+ QCOMPARE(ba, test);
+ QCOMPARE(ba.size(), test.size());
+
+ const std::byte bytes[] = {std::byte('T'), std::byte(0), std::byte('S'), std::byte('T')};
+ test = QByteArrayView::fromArray(bytes);
+ QCOMPARE(ba.assign(test.begin(), test.end()), test);
+ QCOMPARE(ba.size(), test.size());
+
+ std::stringstream ss;
+ ss << "T " << '\0' << ' ' << "S " << "T ";
+ ba.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ test = "T\0ST"_ba;
+ QCOMPARE(ba, test);
+ QCOMPARE(ba.size(), test.size());
+ }
+ // Test chaining
+ {
+ QByteArray ba;
+ QByteArray test("TTTTT");
+ char arr[] = {'T', 'E', 'S', 'T'};
+ ba.assign(std::begin(arr), std::end(arr)).assign({"Hello World!"}).assign(5, 'T');
+ QCOMPARE(ba, test);
+ QCOMPARE(ba.size(), test.size());
+ test = "DATA";
+ QCOMPARE(ba.assign(300, 'T').assign({"DATA"}), test);
+ QCOMPARE(ba.size(), test.size());
+ test = QByteArray(arr, q20::ssize(arr));
+ QCOMPARE(ba.assign(10, 'c').assign(std::begin(arr), std::end(arr)), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "TTT";
+ QCOMPARE(ba.assign("data").assign(QByteArrayView::fromArray(
+ {std::byte('T'), std::byte('T'), std::byte('T')})), test);
+ QCOMPARE(ba.size(), test.size());
+ test = "\0data";
+ QCOMPARE(ba.assign("data").assign("\0data"), test);
+ QCOMPARE(ba.size(), test.size());
+ }
+}
+
+void tst_QByteArray::assignShared()
+{
+ {
+ QByteArray ba;
+ ba.assign({"DATA"});
+ QVERIFY(ba.isDetached());
+ QCOMPARE(ba, QByteArray("DATA"));
+
+ auto baCopy = ba;
+ QVERIFY(!ba.isDetached());
+ QVERIFY(!baCopy.isDetached());
+ QVERIFY(ba.isSharedWith(baCopy));
+ QVERIFY(baCopy.isSharedWith(ba));
+
+ ba.assign(10, 'D');
+ QVERIFY(ba.isDetached());
+ QVERIFY(baCopy.isDetached());
+ QVERIFY(!ba.isSharedWith(baCopy));
+ QVERIFY(!baCopy.isSharedWith(ba));
+ QCOMPARE(ba, QByteArray("DDDDDDDDDD"));
+ QCOMPARE(baCopy, QByteArray("DATA"));
+ }
+ {
+ QByteArray ba("START");
+ QByteArrayView bav("DATA");
+ QVERIFY(ba.isDetached());
+ QCOMPARE(ba, QByteArray("START"));
+
+ auto copyForwardIt = ba;
+ QVERIFY(!ba.isDetached());
+ QVERIFY(!copyForwardIt.isDetached());
+ QVERIFY(ba.isSharedWith(copyForwardIt));
+ QVERIFY(copyForwardIt.isSharedWith(ba));
+
+ ba.assign(bav.begin(), bav.end());
+ QVERIFY(ba.isDetached());
+ QVERIFY(copyForwardIt.isDetached());
+ QVERIFY(!ba.isSharedWith(copyForwardIt));
+ QVERIFY(!copyForwardIt.isSharedWith(ba));
+ QCOMPARE(ba, QByteArray("DATA"));
+ QCOMPARE(copyForwardIt, QByteArray("START"));
+
+ auto copyInputIt = ba;
+ QVERIFY(!ba.isDetached());
+ QVERIFY(!copyInputIt.isDetached());
+ QVERIFY(ba.isSharedWith(copyInputIt));
+ QVERIFY(copyInputIt.isSharedWith(ba));
+
+ std::stringstream ss("1 2 3 4 5 6 ");
+ ba.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ QVERIFY(ba.isDetached());
+ QVERIFY(copyInputIt.isDetached());
+ QVERIFY(!ba.isSharedWith(copyInputIt));
+ QVERIFY(!copyInputIt.isSharedWith(ba));
+ QCOMPARE(ba, QByteArray("123456"));
+ QCOMPARE(copyInputIt, QByteArray("DATA"));
+ }
+}
+
+void tst_QByteArray::assignUsesPrependBuffer()
+{
+ const auto capBegin = [](const QByteArray &ba) {
+ return ba.begin() - ba.d.freeSpaceAtBegin();
+ };
+ const auto capEnd = [](const QByteArray &ba) {
+ return ba.end() + ba.d.freeSpaceAtEnd();
+ };
+ // QByteArray &assign(QByteArrayView)
+ {
+ QByteArray withFreeSpaceAtBegin;
+ for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i)
+ withFreeSpaceAtBegin.prepend("data");
+ QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1);
+
+ const auto oldCapBegin = capBegin(withFreeSpaceAtBegin);
+ const auto oldCapEnd = capEnd(withFreeSpaceAtBegin);
+
+ std::string test(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 'd');
+ withFreeSpaceAtBegin.assign(test);
+
+ QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer
+ QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin);
+ QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd);
+ QCOMPARE(withFreeSpaceAtBegin, test.data());
+ }
+ // QByteArray &assign(InputIterator, InputIterator)
+ {
+ QByteArray withFreeSpaceAtBegin;
+ for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i)
+ withFreeSpaceAtBegin.prepend("data");
+ QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1);
+
+ const auto oldCapBegin = capBegin(withFreeSpaceAtBegin);
+ const auto oldCapEnd = capEnd(withFreeSpaceAtBegin);
+
+ std::stringstream ss;
+ for (qsizetype i = 0; i < withFreeSpaceAtBegin.d.freeSpaceAtBegin(); ++i)
+ ss << "d ";
+
+ withFreeSpaceAtBegin.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer
+ QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin);
+ QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd);
+ }
+}
+
+void tst_QByteArray::insert()
+{
+ const char data[] = "data";
+
+ QCOMPARE(QByteArray().insert(0, QByteArray()), QByteArray());
+ QCOMPARE(QByteArray().insert(0, 'a'), QByteArray("a"));
+ QCOMPARE(QByteArray().insert(0, 2, 'a'), QByteArray("aa"));
+ QCOMPARE(QByteArray().insert(0, QByteArray("data")), QByteArray("data"));
+ QCOMPARE(QByteArray().insert(0, data), QByteArray("data"));
+ QCOMPARE(QByteArray().insert(0, data, 2), QByteArray("da"));
+ QCOMPARE(QByteArray().insert(0, QByteArrayView(data)), QByteArray("data"));
+
+ // insert into empty with offset
+ QCOMPARE(QByteArray().insert(2, QByteArray()), QByteArray());
+ QCOMPARE(QByteArray().insert(2, 'a'), QByteArray(" a"));
+ QCOMPARE(QByteArray().insert(2, 2, 'a'), QByteArray(" aa"));
+ QCOMPARE(QByteArray().insert(2, QByteArray("data")), QByteArray(" data"));
+ QCOMPARE(QByteArray().insert(2, data), QByteArray(" data"));
+ QCOMPARE(QByteArray().insert(2, data, 2), QByteArray(" da"));
+ QCOMPARE(QByteArray().insert(2, QByteArrayView(data)), QByteArray(" data"));
+
+ QByteArray ba("Meal");
+ QCOMPARE(ba.insert(1, QByteArray("ontr")), QByteArray("Montreal"));
+ QCOMPARE(ba.insert(ba.size(), "foo"), QByteArray("Montrealfoo"));
+
+ ba = QByteArray("13");
+ QCOMPARE(ba.insert(1, QByteArray("2")), QByteArray("123"));
+
+ ba = "ac";
+ QCOMPARE(ba.insert(1, 'b'), QByteArray("abc"));
+ QCOMPARE(ba.size(), 3);
+
+ ba = "ac";
+ QCOMPARE(ba.insert(-1, 3, 'x'), QByteArray("ac"));
+ QCOMPARE(ba.insert(1, 3, 'x'), QByteArray("axxxc"));
+ QCOMPARE(ba.insert(6, 3, 'x'), QByteArray("axxxc xxx"));
+ QCOMPARE(ba.size(), 9);
+
+ ba = "ikl";
+ QCOMPARE(ba.insert(1, "j"), QByteArray("ijkl"));
+ QCOMPARE(ba.size(), 4);
+
+ ba = "ab";
+ QCOMPARE(ba.insert(1, "\0X\0", 3), QByteArray::fromRawData("a\0X\0b", 5));
+ QCOMPARE(ba.size(), 5);
+
+ ba = "Hello World";
+ QCOMPARE(ba.insert(5, QByteArrayView(",")), QByteArray("Hello, World"));
+ QCOMPARE(ba.size(), 12);
+
+ ba = "one";
+ QCOMPARE(ba.insert(1, ba), QByteArray("oonene"));
+ QCOMPARE(ba.size(), 6);
+
+ ba = "one";
+ QCOMPARE(ba.insert(1, QByteArrayView(ba)), QByteArray("oonene"));
+ QCOMPARE(ba.size(), 6);
+
+ {
+ ba = "one";
+ ba.prepend('a');
+ QByteArray b(ba.data_ptr()->freeSpaceAtEnd(), 'b');
+ QCOMPARE(ba.insert(ba.size() + 1, QByteArrayView(b)), QByteArray("aone ") + b);
+ }
+
+ {
+ ba = "onetwothree";
+ while (ba.size() - 1)
+ ba.remove(0, 1);
+ QByteArray b(ba.data_ptr()->freeSpaceAtEnd() + 1, 'b');
+ QCOMPARE(ba.insert(ba.size() + 1, QByteArrayView(b)), QByteArray("e ") + b);
+ }
+
+ {
+ ba = "one";
+ ba.prepend('a');
+ const qsizetype freeAtEnd = ba.data_ptr()->freeSpaceAtEnd();
+ QCOMPARE(ba.insert(ba.size() + 1, freeAtEnd + 1, 'b'),
+ QByteArray("aone ") + QByteArray(freeAtEnd + 1, 'b'));
+ }
+
+ {
+ ba = "onetwothree";
+ while (ba.size() - 1)
+ ba.remove(0, 1);
+ const qsizetype freeAtEnd = ba.data_ptr()->freeSpaceAtEnd();
+ QCOMPARE(ba.insert(ba.size() + 1, freeAtEnd + 1, 'b'),
+ QByteArray("e ") + QByteArray(freeAtEnd + 1, 'b'));
+ }
+}
+
+void tst_QByteArray::insertExtended_data()
+{
+ prependExtended_data();
+}
+
+void tst_QByteArray::insertExtended()
+{
+ QFETCH(QByteArray, array);
+ QCOMPARE(array.insert(1, "i"), QByteArray("diata"));
+ QCOMPARE(array.insert(1, 3, 'x'), QByteArray("dxxxiata"));
+ QCOMPARE(array.size(), 8);
+}
+
+void tst_QByteArray::remove_data()
+{
+ QTest::addColumn<QByteArray>("src");
+ QTest::addColumn<int>("position");
+ QTest::addColumn<int>("length");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("null 0 0") << QByteArray() << 0 << 0 << QByteArray();
+ QTest::newRow("null 0 5") << QByteArray() << 0 << 5 << QByteArray();
+ QTest::newRow("null 3 5") << QByteArray() << 3 << 5 << QByteArray();
+ QTest::newRow("null -1 5") << QByteArray() << -1 << 5 << QByteArray();
+
+ QTest::newRow("1") << QByteArray("Montreal") << 1 << 4
+ << QByteArray("Meal");
+ QTest::newRow("2") << QByteArray() << 10 << 10 << QByteArray();
+ QTest::newRow("3") << QByteArray("hi") << 0 << 10 << QByteArray();
+ QTest::newRow("4") << QByteArray("Montreal") << 4 << 100
+ << QByteArray("Mont");
+
+ // index out of range
+ QTest::newRow("5") << QByteArray("Montreal") << 8 << 1
+ << QByteArray("Montreal");
+ QTest::newRow("6") << QByteArray("Montreal") << 18 << 4
+ << QByteArray("Montreal");
+}
+
+void tst_QByteArray::remove()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(int, position);
+ QFETCH(int, length);
+ QFETCH(QByteArray, expected);
+ // Test when it's shared
+ QByteArray ba1 = src;
+ QCOMPARE(ba1.remove(position, length), expected);
+
+ // Test when it's not shared
+ QByteArray ba2 = src;
+ ba2.detach();
+ QCOMPARE(ba2.remove(position, length), expected);
+}
+
+void tst_QByteArray::remove_extra()
+{
+ QByteArray ba = "Clock";
+ ba.removeFirst();
+ QCOMPARE(ba, "lock");
+ ba.removeLast();
+ QCOMPARE(ba, "loc");
+ ba.removeAt(ba.indexOf('o'));
+ QCOMPARE(ba, "lc");
+ ba.clear();
+ // No crash on empty byte arrays
+ ba.removeFirst();
+ ba.removeLast();
+ ba.removeAt(2);
+}
+
+void tst_QByteArray::removeIf()
+{
+ auto removeA = [](const char c) { return c == 'a' || c == 'A'; };
+
+ QByteArray a;
+ QCOMPARE(a.removeIf(removeA), QByteArray());
+ QVERIFY(!a.isDetached());
+
+ a = QByteArray("aBcAbC");
+ // Test when it's not shared
+ QVERIFY(a.isDetached());
+ QCOMPARE(a.removeIf(removeA), QByteArray("BcbC"));
+
+ a = QByteArray("aBcAbC");
+ QByteArray b = a;
+ // Test when it's shared
+ QVERIFY(!b.isDetached());
+ QCOMPARE(b.removeIf(removeA), QByteArray("BcbC"));
+}
+
+void tst_QByteArray::erase()
+{
+ {
+ QByteArray ba = "kittens";
+ auto it = ba.erase(ba.cbegin(), ba.cbegin() + 2);
+ QCOMPARE(ba, "ttens");
+ QCOMPARE(it, ba.cbegin());
+ }
+
+ {
+ QByteArray ba = "kittens";
+ auto it = ba.erase(ba.cbegin(), ba.cend());
+ QCOMPARE(ba, "");
+ QCOMPARE(it, ba.cbegin());
+ QCOMPARE(ba.cbegin(), ba.cend());
+ }
+
+ {
+ QByteArray ba = "kite";
+ auto it = ba.erase(ba.cbegin(), ba.cbegin());
+ // erase() should return an iterator (not const_iterator)
+ *it = 'Z';
+ QCOMPARE(ba, "Zite");
+ QCOMPARE(it, ba.cbegin());
+ }
+}
+
+void tst_QByteArray::erase_single_arg()
+{
+ QByteArray ba = "abcdefg";
+ ba.erase(ba.cend());
+ auto it = ba.erase(ba.cbegin());
+ QCOMPARE_EQ(ba, "bcdefg");
+ QCOMPARE(it, ba.cbegin());
+
+ it = ba.erase(std::prev(ba.end()));
+ QCOMPARE_EQ(ba, "bcdef");
+ QCOMPARE(it, ba.cend());
+
+ it = ba.erase(std::find(ba.begin(), ba.end(), QChar('d')));
+ QCOMPARE(it, ba.begin() + 2);
+}
+
+void tst_QByteArray::replace_data()
+{
+ // Try to cover both the index and specific char cases.
+ // If "before" is empty, use "pos" as an index
+ QTest::addColumn<QByteArray>("src");
+ QTest::addColumn<int>("pos");
+ QTest::addColumn<int>("len");
+ QTest::addColumn<QByteArray>("before");
+ QTest::addColumn<QByteArray>("after");
+ QTest::addColumn<QByteArray>("expected");
+
+ // Using pos
+
+ QTest::newRow("1") << QByteArray("Say yes!") << 4 << 3 << QByteArray() << QByteArray("no")
+ << QByteArray("Say no!");
+ QTest::newRow("2") << QByteArray("rock and roll") << 5 << 3 << QByteArray() << QByteArray("&")
+ << QByteArray("rock & roll");
+ QTest::newRow("3") << QByteArray("foo") << 3 << 0 << QByteArray() << QByteArray("bar")
+ << QByteArray("foobar");
+ QTest::newRow("4") << QByteArray() << 0 << 0 << QByteArray() << QByteArray() << QByteArray();
+ // index out of range
+ QTest::newRow("5") << QByteArray() << 3 << 0 << QByteArray() << QByteArray("hi")
+ << QByteArray(" hi");
+ // Optimized path
+ QTest::newRow("6") << QByteArray("abcdef") << 3 << 12 << QByteArray()
+ << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijkl");
+ QTest::newRow("7") << QByteArray("abcdef") << 3 << 4 << QByteArray()
+ << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijkl");
+ QTest::newRow("8") << QByteArray("abcdef") << 3 << 3 << QByteArray()
+ << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijkl");
+ QTest::newRow("9") << QByteArray("abcdef") << 3 << 2 << QByteArray()
+ << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijklf");
+ QTest::newRow("10") << QByteArray("abcdef") << 2 << 2 << QByteArray() << QByteArray("xx")
+ << QByteArray("abxxef");
+
+ // Using before
+
+ QTest::newRow("null") << QByteArray() << 0 << 0 << QByteArray("abc") << QByteArray()
+ << QByteArray();
+ QTest::newRow("text to text") << QByteArray("abcdefghbcd") << 0 << 0 << QByteArray("bcd")
+ << QByteArray("1234") << QByteArray("a1234efgh1234");
+ QTest::newRow("char to text") << QByteArray("abcdefgch") << 0 << 0 << QByteArray("c")
+ << QByteArray("1234") << QByteArray("ab1234defg1234h");
+ QTest::newRow("char to char") << QByteArray("abcdefgch") << 0 << 0 << QByteArray("c")
+ << QByteArray("1") << QByteArray("ab1defg1h");
+}
+
+void tst_QByteArray::replace()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(int, pos);
+ QFETCH(int, len);
+ QFETCH(QByteArray, before);
+ QFETCH(QByteArray, after);
+ QFETCH(QByteArray, expected);
+
+ if (before.isEmpty()) {
+ QByteArray copy = src;
+ QCOMPARE(copy.replace(pos, len, after), expected);
+ copy = src;
+ QCOMPARE(copy.replace(pos, len, after.data(), after.size()), expected);
+ } else {
+ QByteArray copy = src;
+ if (before.size() == 1) {
+ if (after.size() == 1)
+ QCOMPARE(copy.replace(before.front(), after.front()), expected);
+ QCOMPARE(copy.replace(before.front(), after), expected);
+ }
+ copy = src;
+ QCOMPARE(copy.replace(before, after), expected);
+ copy = src;
+ QCOMPARE(copy.replace(before.constData(), before.size(), after.constData(), after.size()), expected);
+ }
+}
+
+void tst_QByteArray::replaceWithSpecifiedLength()
+{
+ const char after[] = "zxc\0vbnmqwert";
+ qsizetype lenAfter = 6;
+ QByteArray ba("abcdefghjk");
+ ba.replace(qsizetype(0), 2, after, lenAfter);
+
+ const char _expected[] = "zxc\0vbcdefghjk";
+ QByteArray expected(_expected,sizeof(_expected)-1);
+ QCOMPARE(ba,expected);
+}
+
+void tst_QByteArray::number()
+{
+ QCOMPARE(QByteArray::number(quint64(0)), QByteArray("0"));
+ QCOMPARE(QByteArray::number(Q_UINT64_C(0xFFFFFFFFFFFFFFFF)),
+ QByteArray("18446744073709551615"));
+ QCOMPARE(QByteArray::number(Q_INT64_C(0xFFFFFFFFFFFFFFFF)), QByteArray("-1"));
+ QCOMPARE(QByteArray::number(qint64(0)), QByteArray("0"));
+ QCOMPARE(QByteArray::number(Q_INT64_C(0x7FFFFFFFFFFFFFFF)),
+ QByteArray("9223372036854775807"));
+ QCOMPARE(QByteArray::number(Q_INT64_C(0x8000000000000000)),
+ QByteArray("-9223372036854775808"));
+}
+
+void tst_QByteArray::number_double_data()
+{
+ QTest::addColumn<double>("value");
+ QTest::addColumn<char>("format");
+ QTest::addColumn<int>("precision");
+ QTest::addColumn<QByteArray>("expected");
+
+ // This function is implemented in ../shared/test_number_shared.h
+ add_number_double_shared_data([](NumberDoubleTestData datum) {
+ QByteArray ba(datum.expected.data(), datum.expected.size());
+ const char *title = !datum.optTitle.isEmpty() ? datum.optTitle.data() : ba.data();
+ QTest::addRow("%s, format '%c', precision %d", title, datum.f, datum.p)
+ << datum.d << datum.f << datum.p << ba;
+ if (datum.f != 'f') { // Also test uppercase format
+ datum.f = QtMiscUtils::toAsciiUpper(datum.f);
+ QByteArray upper = ba.toUpper();
+ QByteArray upperTitle = QByteArray(title);
+ if (!datum.optTitle.isEmpty())
+ upperTitle += ", uppercase";
+ else
+ upperTitle = upperTitle.toUpper();
+ QTest::addRow("%s, format '%c', precision %d", upperTitle.data(), datum.f, datum.p)
+ << datum.d << datum.f << datum.p << upper;
+ }
+ });
+}
+
+void tst_QByteArray::number_double()
+{
+ QFETCH(double, value);
+ QFETCH(char, format);
+ QFETCH(int, precision);
+
+ if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) {
+ if (::qstrcmp(QTest::currentDataTag(), "Very small number, very high precision, format 'f', precision 350") == 0) {
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+ }
+ QTEST(QByteArray::number(value, format, precision), "expected");
+}
+
+void tst_QByteArray::number_base_data()
+{
+ QTest::addColumn<qlonglong>("n");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("base 10") << 12346LL << 10 << QByteArray("12346");
+ QTest::newRow("base 2") << 12346LL << 2 << QByteArray("11000000111010");
+ QTest::newRow("base 8") << 12346LL << 8 << QByteArray("30072");
+ QTest::newRow("base 16") << 12346LL << 16 << QByteArray("303a");
+ QTest::newRow("base 17") << 12346LL << 17 << QByteArray("28c4");
+ QTest::newRow("base 36") << 2181789482LL << 36 << QByteArray("102zbje");
+
+ QTest::newRow("largeint, base 10")
+ << 123456789012LL << 10 << QByteArray("123456789012");
+ QTest::newRow("largeint, base 2")
+ << 123456789012LL << 2 << QByteArray("1110010111110100110010001101000010100");
+ QTest::newRow("largeint, base 8")
+ << 123456789012LL << 8 << QByteArray("1627646215024");
+ QTest::newRow("largeint, base 16")
+ << 123456789012LL << 16 << QByteArray("1cbe991a14");
+ QTest::newRow("largeint, base 17")
+ << 123456789012LL << 17 << QByteArray("10bec2b629");
+}
+
+void tst_QByteArray::number_base()
+{
+ QFETCH( qlonglong, n );
+ QFETCH( int, base );
+ QFETCH( QByteArray, expected );
+ QCOMPARE(QByteArray::number(n, base), expected);
+ QCOMPARE(QByteArray::number(-n, base), '-' + expected);
+
+ // check qlonglong->QByteArray->qlonglong round trip
+ for (int ibase = 2; ibase <= 36; ++ibase) {
+ auto stringrep = QByteArray::number(n, ibase);
+ QCOMPARE(QByteArray::number(-n, ibase), '-' + stringrep);
+ bool ok(false);
+ auto result = stringrep.toLongLong(&ok, ibase);
+ QVERIFY(ok);
+ QCOMPARE(n, result);
+ }
+ if (n <= std::numeric_limits<int>::max()) {
+ QCOMPARE(QByteArray::number(int(n), base), expected);
+ QCOMPARE(QByteArray::number(int(-n), base), '-' + expected);
+ } else if (n <= std::numeric_limits<long>::max()) {
+ QCOMPARE(QByteArray::number(long(n), base), expected);
+ QCOMPARE(QByteArray::number(long(-n), base), '-' + expected);
+ }
+}
+
+void tst_QByteArray::nullness()
+{
+ {
+ QByteArray ba;
+ QVERIFY(ba.isNull());
+ }
+ {
+ QByteArray ba = nullptr;
+ QVERIFY(ba.isNull());
+ }
+ {
+ const char *ptr = nullptr;
+ QByteArray ba = ptr;
+ QVERIFY(ba.isNull());
+ }
+ {
+ QByteArray ba(nullptr, 0);
+ QVERIFY(ba.isNull());
+ }
+ {
+ const char *ptr = nullptr;
+ QByteArray ba(ptr, 0);
+ QVERIFY(ba.isNull());
+ }
+ {
+ QByteArrayView bav;
+ QVERIFY(bav.isNull());
+ QByteArray ba = bav.toByteArray();
+ QVERIFY(ba.isNull());
+ }
+}
+
+static bool checkSize(qsizetype value, qsizetype min)
+{
+ return value >= min && value <= std::numeric_limits<qsizetype>::max();
+}
+
+// global functions defined in qbytearray.cpp
+void tst_QByteArray::blockSizeCalculations()
+{
+ qsizetype MaxAllocSize = std::numeric_limits<qsizetype>::max();
+
+ // Not very important, but please behave :-)
+ QCOMPARE(qCalculateBlockSize(0, 1), qsizetype(0));
+ QVERIFY(qCalculateGrowingBlockSize(0, 1).size <= MaxAllocSize);
+ QVERIFY(qCalculateGrowingBlockSize(0, 1).elementCount <= MaxAllocSize);
+
+ // boundary condition
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize, 1), qsizetype(MaxAllocSize));
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize/2, 2), qsizetype(MaxAllocSize) - 1);
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize/2, 2, 1), qsizetype(MaxAllocSize));
+ QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize, 1).size, qsizetype(MaxAllocSize));
+ QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize, 1).elementCount, qsizetype(MaxAllocSize));
+ QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2, 2, 1).size, qsizetype(MaxAllocSize));
+ QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2, 2, 1).elementCount, qsizetype(MaxAllocSize)/2);
+
+ // error conditions
+ QCOMPARE(qCalculateBlockSize(quint64(MaxAllocSize) + 1, 1), qsizetype(-1));
+ QCOMPARE(qCalculateBlockSize(qsizetype(-1), 1), qsizetype(-1));
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize, 1, 1), qsizetype(-1));
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize/2 + 1, 2), qsizetype(-1));
+ QCOMPARE(qCalculateGrowingBlockSize(quint64(MaxAllocSize) + 1, 1).size, qsizetype(-1));
+ QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2 + 1, 2).size, qsizetype(-1));
+
+ // overflow conditions
+#if QT_POINTER_SIZE == 4
+ // on 32-bit platforms, (1 << 16) * (1 << 16) = (1 << 32) which is zero
+ QCOMPARE(qCalculateBlockSize(1 << 16, 1 << 16), qsizetype(-1));
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize/4, 16), qsizetype(-1));
+ // on 32-bit platforms, (1 << 30) * 3 + (1 << 30) would overflow to zero
+ QCOMPARE(qCalculateBlockSize(1U << 30, 3, 1U << 30), qsizetype(-1));
+#else
+ // on 64-bit platforms, (1 << 32) * (1 << 32) = (1 << 64) which is zero
+ QCOMPARE(qCalculateBlockSize(1LL << 32, 1LL << 32), qsizetype(-1));
+ QCOMPARE(qCalculateBlockSize(MaxAllocSize/4, 16), qsizetype(-1));
+ // on 64-bit platforms, (1 << 30) * 3 + (1 << 30) would overflow to zero
+ QCOMPARE(qCalculateBlockSize(1ULL << 62, 3, 1ULL << 62), qsizetype(-1));
+#endif
+ // exact block sizes
+ for (int i = 1; i < 1 << 31; i <<= 1) {
+ QCOMPARE(qCalculateBlockSize(0, 1, i), qsizetype(i));
+ QCOMPARE(qCalculateBlockSize(i, 1), qsizetype(i));
+ QCOMPARE(qCalculateBlockSize(i + i/2, 1), qsizetype(i + i/2));
+ }
+ for (int i = 1; i < 1 << 30; i <<= 1) {
+ QCOMPARE(qCalculateBlockSize(i, 2), 2 * qsizetype(i));
+ QCOMPARE(qCalculateBlockSize(i, 2, 1), 2 * qsizetype(i) + 1);
+ QCOMPARE(qCalculateBlockSize(i, 2, 16), 2 * qsizetype(i) + 16);
+ }
+
+ // growing sizes
+ for (int i = 1; i < 1 << 31; i <<= 1) {
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1).size, i));
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1).elementCount, i));
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 16).size, i));
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 16).elementCount, i));
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 24).size, i));
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 16).elementCount, i));
+ }
+
+ // growth should be limited
+ for (int elementSize = 1; elementSize < (1<<8); elementSize <<= 1) {
+ qsizetype alloc = 1;
+ forever {
+ QVERIFY(checkSize(qCalculateGrowingBlockSize(alloc, elementSize).size, alloc * elementSize));
+ qsizetype newAlloc = qCalculateGrowingBlockSize(alloc, elementSize).elementCount;
+ QVERIFY(checkSize(newAlloc, alloc));
+ if (newAlloc == alloc)
+ break; // no growth, we're at limit
+ alloc = newAlloc;
+ }
+ QVERIFY(checkSize(alloc, qsizetype(MaxAllocSize) / elementSize));
+
+ // the next allocation should be invalid
+ if (alloc < MaxAllocSize) // lest alloc + 1 overflows (= UB)
+ QCOMPARE(qCalculateGrowingBlockSize(alloc + 1, elementSize).size, qsizetype(-1));
+ }
+}
+
+void tst_QByteArray::resizeAfterFromRawData()
+{
+ QByteArray buffer("hello world");
+
+ QByteArray array = QByteArray::fromRawData(buffer.constData(), buffer.size());
+ QVERIFY(array.constData() == buffer.constData());
+ array.resize(5);
+ QVERIFY(array.constData() != buffer.constData());
+ // check null termination
+ QVERIFY(array.constData()[5] == 0);
+}
+
+void tst_QByteArray::toFromHex_data()
+{
+ QTest::addColumn<QByteArray>("str");
+ QTest::addColumn<char>("sep");
+ QTest::addColumn<QByteArray>("hex");
+ QTest::addColumn<QByteArray>("hex_alt1");
+
+ QTest::newRow("Qt is great! (default)")
+ << QByteArray("Qt is great!")
+ << '\0'
+ << QByteArray("517420697320677265617421")
+ << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21");
+
+ QTest::newRow("Qt is great! (with space)")
+ << QByteArray("Qt is great!")
+ << ' '
+ << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21")
+ << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21");
+
+ QTest::newRow("Qt is great! (with minus)")
+ << QByteArray("Qt is great!")
+ << '-'
+ << QByteArray("51-74-20-69-73-20-67-72-65-61-74-21")
+ << QByteArray("51-74-20-69-73-20-67-72-65-61-74-21");
+
+ QTest::newRow("Qt is so great!")
+ << QByteArray("Qt is so great!")
+ << '\0'
+ << QByteArray("517420697320736f20677265617421")
+ << QByteArray("51 74 20 69 73 20 73 6f 20 67 72 65 61 74 21");
+
+ QTest::newRow("default-constructed")
+ << QByteArray()
+ << '\0'
+ << QByteArray()
+ << QByteArray();
+
+ QTest::newRow("default-constructed (with space)")
+ << QByteArray()
+ << ' '
+ << QByteArray()
+ << QByteArray();
+
+ QTest::newRow("empty")
+ << QByteArray("")
+ << '\0'
+ << QByteArray("")
+ << QByteArray("");
+
+ QTest::newRow("null")
+ << QByteArray()
+ << '\0'
+ << QByteArray()
+ << QByteArray();
+
+ QTest::newRow("empty (with space)")
+ << QByteArray("")
+ << ' '
+ << QByteArray("")
+ << QByteArray("");
+
+ QTest::newRow("array-of-null")
+ << QByteArray("\0", 1)
+ << '\0'
+ << QByteArray("00")
+ << QByteArray("0");
+
+ QTest::newRow("no-leading-zero")
+ << QByteArray("\xf")
+ << '\0'
+ << QByteArray("0f")
+ << QByteArray("f");
+
+ QTest::newRow("single-byte")
+ << QByteArray("\xaf")
+ << '\0'
+ << QByteArray("af")
+ << QByteArray("xaf");
+
+ QTest::newRow("no-leading-zero-long")
+ << QByteArray("\xd\xde\xad\xc0\xde")
+ << '\0'
+ << QByteArray("0ddeadc0de")
+ << QByteArray("ddeadc0de");
+
+ QTest::newRow("garbage")
+ << QByteArray("\xC\xde\xeC\xea\xee\xDe\xee\xee")
+ << '\0'
+ << QByteArray("0cdeeceaeedeeeee")
+ << QByteArray("Code less. Create more. Deploy everywhere.");
+
+ QTest::newRow("under-defined-1")
+ << QByteArray("\x1\x23")
+ << '\0'
+ << QByteArray("0123")
+ << QByteArray("x123");
+
+ QTest::newRow("under-defined-2")
+ << QByteArray("\x12\x34")
+ << '\0'
+ << QByteArray("1234")
+ << QByteArray("x1234");
+}
+
+void tst_QByteArray::toFromHex()
+{
+ QFETCH(QByteArray, str);
+ QFETCH(char, sep);
+ QFETCH(QByteArray, hex);
+ QFETCH(QByteArray, hex_alt1);
+
+ if (sep == 0) {
+ const QByteArray th = str.toHex();
+ QCOMPARE(th.size(), hex.size());
+ QCOMPARE(th, hex);
+ }
+
+ {
+ const QByteArray th = str.toHex(sep);
+ QCOMPARE(th.size(), hex.size());
+ QCOMPARE(th, hex);
+ }
+
+ {
+ const QByteArray fh = QByteArray::fromHex(hex);
+ QCOMPARE(fh.size(), str.size());
+ QCOMPARE(fh, str);
+ }
+
+ QCOMPARE(QByteArray::fromHex(hex_alt1), str);
+}
+
+void tst_QByteArray::toFromPercentEncoding()
+{
+ QByteArray arr("Qt is great!");
+
+ QCOMPARE(QByteArray().toPercentEncoding(), QByteArray());
+ QCOMPARE(QByteArray("").toPercentEncoding(), QByteArray(""));
+
+ QByteArray data = arr.toPercentEncoding();
+ QCOMPARE(data, QByteArray("Qt%20is%20great%21"));
+ QCOMPARE(data.percentDecoded(), arr);
+
+ data = arr.toPercentEncoding("! ", "Qt");
+ QCOMPARE(data, QByteArray("%51%74 is grea%74!"));
+ QCOMPARE(data.percentDecoded(), arr);
+
+ data = arr.toPercentEncoding(QByteArray(), "abcdefghijklmnopqrstuvwxyz", 'Q');
+ QCOMPARE(data, QByteArray("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21"));
+ QCOMPARE(data.percentDecoded('Q'), arr);
+
+ // verify that to/from percent encoding preserves nullity
+ arr = "";
+ QVERIFY(arr.isEmpty());
+ QVERIFY(!arr.isNull());
+ QVERIFY(arr.toPercentEncoding().isEmpty());
+ QVERIFY(!arr.toPercentEncoding().isNull());
+ QVERIFY(QByteArray::fromPercentEncoding("").isEmpty());
+ QVERIFY(!QByteArray::fromPercentEncoding("").isNull());
+
+ arr = QByteArray();
+ QVERIFY(arr.isEmpty());
+ QVERIFY(arr.isNull());
+ QVERIFY(arr.toPercentEncoding().isEmpty());
+ QVERIFY(arr.toPercentEncoding().isNull());
+ QVERIFY(QByteArray().percentDecoded().isEmpty());
+ QVERIFY(QByteArray().percentDecoded().isNull());
+
+ // Verify that literal % in the string to be encoded does round-trip:
+ arr = "Qt%20is%20great%21";
+ data = arr.toPercentEncoding();
+ QCOMPARE(data.percentDecoded(), arr);
+ arr = "87% of all statistics are made up!";
+ data = arr.toPercentEncoding();
+ QCOMPARE(data.percentDecoded(), arr);
+}
+
+void tst_QByteArray::fromPercentEncoding_data()
+{
+ QTest::addColumn<QByteArray>("encodedString");
+ QTest::addColumn<QByteArray>("decodedString");
+
+ QTest::newRow("NormalString") << QByteArray("filename") << QByteArray("filename");
+ QTest::newRow("NormalStringEncoded") << QByteArray("file%20name") << QByteArray("file name");
+ QTest::newRow("JustEncoded") << QByteArray("%20") << QByteArray(" ");
+ QTest::newRow("HTTPUrl") << QByteArray("http://qt-project.org") << QByteArray("http://qt-project.org");
+ QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt-project%20org") << QByteArray("http://qt-project org");
+ QTest::newRow("EmptyString") << QByteArray("") << QByteArray("");
+ QTest::newRow("Task27166") << QByteArray("Fran%C3%A7aise") << QByteArray("Française");
+}
+
+void tst_QByteArray::fromPercentEncoding()
+{
+ QFETCH(QByteArray, encodedString);
+ QFETCH(QByteArray, decodedString);
+
+ QCOMPARE(encodedString.percentDecoded(), decodedString);
+}
+
+void tst_QByteArray::toPercentEncoding_data()
+{
+ QTest::addColumn<QByteArray>("decodedString");
+ QTest::addColumn<QByteArray>("encodedString");
+
+ QTest::newRow("NormalString") << QByteArray("filename") << QByteArray("filename");
+ QTest::newRow("NormalStringEncoded") << QByteArray("file name") << QByteArray("file%20name");
+ QTest::newRow("JustEncoded") << QByteArray(" ") << QByteArray("%20");
+ QTest::newRow("HTTPUrl") << QByteArray("http://qt-project.org") << QByteArray("http%3A//qt-project.org");
+ QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt-project org") << QByteArray("http%3A//qt-project%20org");
+ QTest::newRow("EmptyString") << QByteArray("") << QByteArray("");
+ QTest::newRow("Task27166") << QByteArray("Française") << QByteArray("Fran%C3%A7aise");
+}
+
+void tst_QByteArray::toPercentEncoding()
+{
+ QFETCH(QByteArray, decodedString);
+ QFETCH(QByteArray, encodedString);
+
+ QCOMPARE(decodedString.toPercentEncoding("/.").constData(), encodedString.constData());
+}
+
+void tst_QByteArray::pecentEncodingRoundTrip_data()
+{
+ QTest::addColumn<QByteArray>("original");
+ QTest::addColumn<QByteArray>("encoded");
+ QTest::addColumn<QByteArray>("excludeInEncoding");
+ QTest::addColumn<QByteArray>("includeInEncoding");
+
+ QTest::newRow("unchanged")
+ << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
+ << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
+ << QByteArray("") << QByteArray("");
+ QTest::newRow("enclosed-space-quote")
+ << QByteArray("{\t\n\r^\"abc}")
+ << QByteArray("%7B%09%0A%0D%5E%22abc%7D")
+ << QByteArray("") << QByteArray("");
+ QTest::newRow("punctuate")
+ << QByteArray("://?#[]@!$&'()*+,;=")
+ << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D")
+ << QByteArray("") << QByteArray("");
+ QTest::newRow("punctuate-exclude")
+ << QByteArray("://?#[]@!$&'()*+,;=")
+ << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=")
+ << QByteArray("!$&'()*+,;=") << QByteArray("");
+ QTest::newRow("text-include")
+ << QByteArray("abcd") << QByteArray("a%62%63d") << QByteArray("") << QByteArray("bc");
+}
+
+void tst_QByteArray::pecentEncodingRoundTrip()
+{
+ QFETCH(QByteArray, original);
+ QFETCH(QByteArray, encoded);
+ QFETCH(QByteArray, excludeInEncoding);
+ QFETCH(QByteArray, includeInEncoding);
+
+ QByteArray encodedData = original.toPercentEncoding(excludeInEncoding, includeInEncoding);
+ QCOMPARE(encodedData, encoded);
+ QCOMPARE(encodedData.percentDecoded(), original);
+}
+
+struct StringComparisonData
+{
+ const char *const left;
+ const char *const right;
+ const unsigned int clip;
+ const int cmp, icmp, ncmp, nicmp;
+ static int sign(int val) { return val < 0 ? -1 : val > 0 ? +1 : 0; }
+};
+Q_DECLARE_METATYPE(StringComparisonData);
+
+void tst_QByteArray::qstrcmp_data()
+{
+ QTest::addColumn<StringComparisonData>("data");
+
+ QTest::newRow("equal")
+ << StringComparisonData{"abcEdb", "abcEdb", 3, 0, 0, 0, 0};
+ QTest::newRow("upper")
+ << StringComparisonData{"ABCedb", "ABCEDB", 3, 1, 0, 0, 0};
+ QTest::newRow("lower")
+ << StringComparisonData{"ABCEDB", "abcedb", 3, -1, 0, -1, 0};
+ QTest::newRow("upper-late")
+ << StringComparisonData{"abcEdb", "abcEDB", 3, 1, 0, 0, 0};
+ QTest::newRow("lower-late")
+ << StringComparisonData{"ABCEDB", "ABCedb", 3, -1, 0, 0, 0};
+ QTest::newRow("longer")
+ << StringComparisonData{"abcdef", "abcdefg", 6, -1, -1, 0, 0};
+ QTest::newRow("long-up")
+ << StringComparisonData{"abcdef", "abcdeFg", 6, 1, -1, 1, 0};
+ QTest::newRow("long-down")
+ << StringComparisonData{"abcdeF", "abcdefg", 6, -1, -1, -1, 0};
+ QTest::newRow("shorter")
+ << StringComparisonData{"abcdefg", "abcdef", 6, 1, 1, 0, 0};
+ QTest::newRow("short-up")
+ << StringComparisonData{"abcdefg", "abcdeF", 6, 1, 1, 1, 0};
+ QTest::newRow("short-down")
+ << StringComparisonData{"abcdeFg", "abcdef", 6, -1, 1, -1, 0};
+ QTest::newRow("zero-length")
+ << StringComparisonData{"abcdefg", "T", 0, 1, -1, 0, 0};
+ QTest::newRow("null-null")
+ << StringComparisonData{nullptr, nullptr, 6, 0, 0, 0, 0};
+ QTest::newRow("null-empty")
+ << StringComparisonData{nullptr, "", 0, -1, -1, -1, -1};
+ QTest::newRow("empty-null")
+ << StringComparisonData{"", nullptr, 0, 1, 1, 1, 1};
+ QTest::newRow("empty-empty")
+ << StringComparisonData{"", "", 0, 0, 0, 0, 0};
+ QTest::newRow("null-some")
+ << StringComparisonData{nullptr, "some", 0, -1, -1, -1, -1};
+ QTest::newRow("some-null")
+ << StringComparisonData{"some", nullptr, 0, 1, 1, 1, 1};
+ QTest::newRow("empty-some")
+ << StringComparisonData{"", "some", 0, -1, -1, 0, 0};
+ QTest::newRow("some-empty")
+ << StringComparisonData{"some", "", 0, 1, 1, 0, 0};
+}
+
+void tst_QByteArray::qstrcmp()
+{
+ QFETCH(StringComparisonData, data);
+ QCOMPARE(data.sign(::qstrcmp(data.left, data.right)), data.cmp);
+ QCOMPARE(data.sign(::qstricmp(data.left, data.right)), data.icmp);
+ QCOMPARE(data.sign(::qstrncmp(data.left, data.right, data.clip)), data.ncmp);
+ QCOMPARE(data.sign(::qstrnicmp(data.left, data.right, data.clip)), data.nicmp);
+}
+
+void tst_QByteArray::compare_singular()
+{
+ QCOMPARE(QByteArray().compare(nullptr, Qt::CaseInsensitive), 0);
+ QCOMPARE(QByteArray().compare("", Qt::CaseInsensitive), 0);
+ QVERIFY(QByteArray("a").compare(nullptr, Qt::CaseInsensitive) > 0);
+ QVERIFY(QByteArray("a").compare("", Qt::CaseInsensitive) > 0);
+ QVERIFY(QByteArray().compare("a", Qt::CaseInsensitive) < 0);
+ QCOMPARE(QByteArray().compare(QByteArray(), Qt::CaseInsensitive), 0);
+ QVERIFY(QByteArray().compare(QByteArray("a"), Qt::CaseInsensitive) < 0);
+ QVERIFY(QByteArray("a").compare(QByteArray(), Qt::CaseInsensitive) > 0);
+}
+
+void tst_QByteArray::compareCharStar_data()
+{
+ QTest::addColumn<QByteArray>("str1");
+ QTest::addColumn<QByteArray>("string2");
+ QTest::addColumn<int>("result");
+
+ QTest::newRow("null-null") << QByteArray() << QByteArray() << 0;
+ QTest::newRow("null-empty") << QByteArray() << QByteArray("") << 0;
+ QTest::newRow("null-full") << QByteArray() << QByteArray("abc") << -1;
+ QTest::newRow("empty-null") << QByteArray("") << QByteArray() << 0;
+ QTest::newRow("empty-empty") << QByteArray("") << QByteArray("") << 0;
+ QTest::newRow("empty-full") << QByteArray("") << QByteArray("abc") << -1;
+ QTest::newRow("raw-null") << QByteArray::fromRawData("abc", 0) << QByteArray() << 0;
+ QTest::newRow("raw-empty") << QByteArray::fromRawData("abc", 0) << QByteArray("") << 0;
+ QTest::newRow("raw-full") << QByteArray::fromRawData("abc", 0) << QByteArray("abc") << -1;
+
+ QTest::newRow("full-null") << QByteArray("abc") << QByteArray() << +1;
+ QTest::newRow("full-empty") << QByteArray("abc") << QByteArray("") << +1;
+
+ QTest::newRow("equal1") << QByteArray("abc") << QByteArray("abc") << 0;
+ QTest::newRow("equal2") << QByteArray("abcd", 3) << QByteArray("abc") << 0;
+ QTest::newRow("equal3") << QByteArray::fromRawData("abcd", 3) << QByteArray("abc") << 0;
+
+ QTest::newRow("less1") << QByteArray("ab") << QByteArray("abc") << -1;
+ QTest::newRow("less2") << QByteArray("abb") << QByteArray("abc") << -1;
+ QTest::newRow("less3") << QByteArray::fromRawData("abc", 2) << QByteArray("abc") << -1;
+ QTest::newRow("less4") << QByteArray("", 1) << QByteArray("abc") << -1;
+ QTest::newRow("less5") << QByteArray::fromRawData("", 1) << QByteArray("abc") << -1;
+ QTest::newRow("less6") << QByteArray("a\0bc", 4) << QByteArray("a.bc") << -1;
+
+ QTest::newRow("greater1") << QByteArray("ac") << QByteArray("abc") << +1;
+ QTest::newRow("greater2") << QByteArray("abd") << QByteArray("abc") << +1;
+ QTest::newRow("greater3") << QByteArray("abcd") << QByteArray("abc") << +1;
+ QTest::newRow("greater4") << QByteArray::fromRawData("abcd", 4) << QByteArray("abc") << +1;
+}
+
+void tst_QByteArray::compareCharStar()
+{
+ QFETCH(QByteArray, str1);
+ QFETCH(QByteArray, string2);
+ QFETCH(int, result);
+
+ const bool isEqual = result == 0;
+ const bool isLess = result < 0;
+ const bool isGreater = result > 0;
+ const char *str2 = string2.isNull() ? nullptr : string2.constData();
+
+ // basic tests:
+ QCOMPARE(str1 == str2, isEqual);
+ QCOMPARE(str1 < str2, isLess);
+ QCOMPARE(str1 > str2, isGreater);
+
+ // composed tests:
+ QCOMPARE(str1 <= str2, isLess || isEqual);
+ QCOMPARE(str1 >= str2, isGreater || isEqual);
+ QCOMPARE(str1 != str2, !isEqual);
+
+ // inverted tests:
+ QCOMPARE(str2 == str1, isEqual);
+ QCOMPARE(str2 < str1, isGreater);
+ QCOMPARE(str2 > str1, isLess);
+
+ // composed, inverted tests:
+ QCOMPARE(str2 <= str1, isGreater || isEqual);
+ QCOMPARE(str2 >= str1, isLess || isEqual);
+ QCOMPARE(str2 != str1, !isEqual);
+}
+
+void tst_QByteArray::repeatedSignature() const
+{
+ /* repated() should be a const member. */
+ const QByteArray string;
+ (void)string.repeated(3);
+}
+
+void tst_QByteArray::repeated() const
+{
+ QFETCH(QByteArray, string);
+ QFETCH(QByteArray, expected);
+ QFETCH(int, count);
+
+ QCOMPARE(string.repeated(count), expected);
+}
+
+void tst_QByteArray::repeated_data() const
+{
+ QTest::addColumn<QByteArray>("string" );
+ QTest::addColumn<QByteArray>("expected" );
+ QTest::addColumn<int>("count" );
+
+ /* Empty strings. */
+ QTest::newRow("data1")
+ << QByteArray()
+ << QByteArray()
+ << 0;
+
+ QTest::newRow("data2")
+ << QByteArray()
+ << QByteArray()
+ << -1004;
+
+ QTest::newRow("data3")
+ << QByteArray()
+ << QByteArray()
+ << 1;
+
+ QTest::newRow("data4")
+ << QByteArray()
+ << QByteArray()
+ << 5;
+
+ /* On simple string. */
+ QTest::newRow("data5")
+ << QByteArray("abc")
+ << QByteArray()
+ << -1004;
+
+ QTest::newRow("data6")
+ << QByteArray("abc")
+ << QByteArray()
+ << -1;
+
+ QTest::newRow("data7")
+ << QByteArray("abc")
+ << QByteArray()
+ << 0;
+
+ QTest::newRow("data8")
+ << QByteArray("abc")
+ << QByteArray("abc")
+ << 1;
+
+ QTest::newRow("data9")
+ << QByteArray(("abc"))
+ << QByteArray(("abcabc"))
+ << 2;
+
+ QTest::newRow("data10")
+ << QByteArray(("abc"))
+ << QByteArray(("abcabcabc"))
+ << 3;
+
+ QTest::newRow("data11")
+ << QByteArray(("abc"))
+ << QByteArray(("abcabcabcabc"))
+ << 4;
+
+ QTest::newRow("static not null terminated")
+ << QByteArray(staticNotNullTerminated)
+ << QByteArray("datadatadatadata")
+ << 4;
+ QTest::newRow("static standard")
+ << QByteArray(staticStandard)
+ << QByteArray("datadatadatadata")
+ << 4;
+}
+
+void tst_QByteArray::byteRefDetaching() const
+{
+ {
+ QByteArray str = "str";
+ QByteArray copy = str;
+ copy[0] = 'S';
+
+ QCOMPARE(str, QByteArray("str"));
+ }
+
+ {
+ char buf[] = { 's', 't', 'r' };
+ QByteArray str = QByteArray::fromRawData(buf, 3);
+ str[0] = 'S';
+
+ QCOMPARE(buf[0], char('s'));
+ }
+
+ {
+ static const char buf[] = { 's', 't', 'r' };
+ QByteArray str = QByteArray::fromRawData(buf, 3);
+
+ // this causes a crash in most systems if the detaching doesn't work
+ str[0] = 'S';
+
+ QCOMPARE(buf[0], char('s'));
+ }
+}
+
+void tst_QByteArray::reserve()
+{
+ int capacity = 100;
+ QByteArray qba;
+ qba.reserve(capacity);
+ QVERIFY(qba.capacity() == capacity);
+ char *data = qba.data();
+
+ for (int i = 0; i < capacity; i++) {
+ qba.resize(i);
+ QVERIFY(capacity == qba.capacity());
+ QVERIFY(data == qba.data());
+ }
+
+ qba.resize(capacity);
+
+ QByteArray copy = qba;
+ qba.reserve(capacity / 2);
+ QCOMPARE(qba.size(), capacity); // we didn't shrink the size!
+ QCOMPARE(qba.capacity(), capacity);
+ QCOMPARE(copy.capacity(), capacity);
+
+ qba = copy;
+ qba.reserve(capacity * 2);
+ QCOMPARE(qba.size(), capacity);
+ QCOMPARE(qba.capacity(), capacity * 2);
+ QCOMPARE(copy.capacity(), capacity);
+ QVERIFY(qba.constData() != data);
+
+ QByteArray nil1, nil2;
+ nil1.reserve(0);
+ nil2.squeeze();
+ nil1.squeeze();
+ nil2.reserve(0);
+ QCOMPARE(nil1.capacity(), 0);
+ QCOMPARE(nil2.capacity(), 0);
+
+ nil1.resize(5);
+ QVERIFY(nil1.capacity() >= 5);
+}
+
+void tst_QByteArray::reserveExtended_data()
+{
+ prependExtended_data();
+}
+
+void tst_QByteArray::reserveExtended()
+{
+ QFETCH(QByteArray, array);
+ array.reserve(1024);
+ QVERIFY(array.capacity() == 1024);
+ QCOMPARE(array, QByteArray("data"));
+ array.squeeze();
+ QCOMPARE(array, QByteArray("data"));
+ QCOMPARE(array.capacity(), array.size());
+}
+
+void tst_QByteArray::resize()
+{
+ QByteArray ba;
+ ba.resize(15);
+ QCOMPARE(ba.size(), qsizetype(15));
+ ba.resize(10);
+ QCOMPARE(ba.size(), 10);
+ ba.resize(0);
+ QCOMPARE(ba.size(), 0);
+ ba.resize(5, 'a');
+ QCOMPARE(ba.size(), 5);
+ QCOMPARE(ba, "aaaaa");
+ ba.resize(10, 'b');
+ QCOMPARE(ba.size(), 10);
+ QCOMPARE(ba, "aaaaabbbbb");
+}
+
+void tst_QByteArray::movability_data()
+{
+ prependExtended_data();
+
+ QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4);
+ QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4);
+ QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4);
+ QTest::newRow("empty") << QByteArray("");
+ QTest::newRow("null") << QByteArray();
+ QTest::newRow("sss") << QByteArray(3, 's');
+}
+
+void tst_QByteArray::movability()
+{
+ QFETCH(QByteArray, array);
+
+ static_assert(QTypeInfo<QByteArray>::isRelocatable);
+
+ const int size = array.size();
+ const bool isEmpty = array.isEmpty();
+ const bool isNull = array.isNull();
+ const int capacity = array.capacity();
+
+ QByteArray memSpace;
+
+ // we need only memory space not the instance
+ memSpace.~QByteArray();
+ // move array -> memSpace
+ memcpy((void *)&memSpace, (const void *)&array, sizeof(QByteArray));
+ // reconstruct empty QByteArray
+ new (&array) QByteArray;
+
+ QCOMPARE(memSpace.size(), size);
+ QCOMPARE(memSpace.isEmpty(), isEmpty);
+ QCOMPARE(memSpace.isNull(), isNull);
+ QCOMPARE(memSpace.capacity(), capacity);
+
+ // try to not crash
+ (void)memSpace.toLower();
+ (void)memSpace.toUpper();
+ memSpace.prepend('a');
+ memSpace.append("b", 1);
+ memSpace.squeeze();
+ memSpace.reserve(array.size() + 16);
+
+ QByteArray copy(memSpace);
+
+ // reinitialize base values
+ const int newSize = size + 2;
+ const bool newIsEmpty = false;
+ const bool newIsNull = false;
+ const int newCapacity = memSpace.capacity();
+
+ // move back memSpace -> array
+ array.~QByteArray();
+ memcpy((void *)&array, (const void *)&memSpace, sizeof(QByteArray));
+ // reconstruct empty QByteArray
+ new (&memSpace) QByteArray;
+
+ QCOMPARE(array.size(), newSize);
+ QCOMPARE(array.isEmpty(), newIsEmpty);
+ QCOMPARE(array.isNull(), newIsNull);
+ QCOMPARE(array.capacity(), newCapacity);
+ QVERIFY(array.startsWith('a'));
+ QVERIFY(array.endsWith('b'));
+
+ QCOMPARE(copy.size(), newSize);
+ QCOMPARE(copy.isEmpty(), newIsEmpty);
+ QCOMPARE(copy.isNull(), newIsNull);
+ QCOMPARE(copy.capacity(), newCapacity);
+ QVERIFY(copy.startsWith('a'));
+ QVERIFY(copy.endsWith('b'));
+
+ // try to not crash
+ array.squeeze();
+ array.reserve(array.size() + 3);
+ QVERIFY(true);
+}
+
+void tst_QByteArray::literals()
+{
+ QByteArray str(QByteArrayLiteral("abcd"));
+
+ QVERIFY(str.size() == 4);
+ QCOMPARE(str.capacity(), 0);
+ QVERIFY(str == "abcd");
+ QVERIFY(!str.data_ptr()->isMutable());
+
+ const char *s = str.constData();
+ QByteArray str2 = str;
+ QVERIFY(str2.constData() == s);
+ QCOMPARE(str2.capacity(), 0);
+
+ // detach on non const access
+ QVERIFY(str.data() != s);
+ QVERIFY(str.capacity() >= str.size());
+
+ QVERIFY(str2.constData() == s);
+ QVERIFY(str2.data() != s);
+ QVERIFY(str2.capacity() >= str2.size());
+}
+
+void tst_QByteArray::userDefinedLiterals()
+{
+ {
+ QByteArray str = "abcd"_ba;
+
+ QVERIFY(str.size() == 4);
+ QCOMPARE(str.capacity(), 0);
+ QVERIFY(str == "abcd");
+ QVERIFY(!str.data_ptr()->isMutable());
+
+ const char *s = str.constData();
+ QByteArray str2 = str;
+ QVERIFY(str2.constData() == s);
+ QCOMPARE(str2.capacity(), 0);
+
+ // detach on non const access
+ QVERIFY(str.data() != s);
+ QVERIFY(str.capacity() >= str.size());
+
+ QVERIFY(str2.constData() == s);
+ QVERIFY(str2.data() != s);
+ QVERIFY(str2.capacity() >= str2.size());
+ }
+
+#if QT_DEPRECATED_SINCE(6, 8)
+ {
+ QT_IGNORE_DEPRECATIONS(QByteArray str = "abcd"_qba;)
+
+ QVERIFY(str.size() == 4);
+ QCOMPARE(str.capacity(), 0);
+ QVERIFY(str == "abcd");
+ QVERIFY(!str.data_ptr()->isMutable());
+
+ const char *s = str.constData();
+ QByteArray str2 = str;
+ QVERIFY(str2.constData() == s);
+ QCOMPARE(str2.capacity(), 0);
+
+ // detach on non const access
+ QVERIFY(str.data() != s);
+ QVERIFY(str.capacity() >= str.size());
+
+ QVERIFY(str2.constData() == s);
+ QVERIFY(str2.data() != s);
+ QVERIFY(str2.capacity() >= str2.size());
+ }
+#endif // QT_DEPRECATED_SINCE(6, 8)
+}
+
+void tst_QByteArray::toUpperLower_data()
+{
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<QByteArray>("upper");
+ QTest::addColumn<QByteArray>("lower");
+
+ {
+ QByteArray nonAscii(128, Qt::Uninitialized);
+ char *data = nonAscii.data();
+ for (unsigned char i = 0; i < 128; ++i)
+ data[i] = i + 128;
+ QTest::newRow("non-ASCII") << nonAscii << nonAscii << nonAscii;
+ }
+
+ QTest::newRow("null") << QByteArray() << QByteArray() << QByteArray();
+ QTest::newRow("empty") << QByteArray("") << QByteArray("") << QByteArray("");
+ QTest::newRow("literal") << QByteArrayLiteral("Hello World")
+ << QByteArrayLiteral("HELLO WORLD")
+ << QByteArrayLiteral("hello world");
+ QTest::newRow("ascii") << QByteArray("Hello World, this is a STRING")
+ << QByteArray("HELLO WORLD, THIS IS A STRING")
+ << QByteArray("hello world, this is a string");
+ QTest::newRow("nul") << QByteArray("a\0B", 3) << QByteArray("A\0B", 3) << QByteArray("a\0b", 3);
+}
+
+void tst_QByteArray::toUpperLower()
+{
+ QFETCH(QByteArray, input);
+ QFETCH(QByteArray, upper);
+ QFETCH(QByteArray, lower);
+ QVERIFY(upper.isUpper());
+ QVERIFY(lower.isLower());
+ QCOMPARE(lower.toLower(), lower);
+ QVERIFY(lower.toLower().isLower());
+ QCOMPARE(upper.toUpper(), upper);
+ QVERIFY(upper.toUpper().isUpper());
+ QCOMPARE(input.toUpper(), upper);
+ QVERIFY(input.toUpper().isUpper());
+ QCOMPARE(input.toLower(), lower);
+ QVERIFY(input.toLower().isLower());
+
+ QByteArray copy = input;
+ QCOMPARE(std::move(copy).toUpper(), upper);
+ copy = input;
+ copy.detach();
+ QCOMPARE(std::move(copy).toUpper(), upper);
+
+ copy = input;
+ QCOMPARE(std::move(copy).toLower(), lower);
+ copy = input;
+ copy.detach();
+ QCOMPARE(std::move(copy).toLower(), lower);
+
+ copy = lower;
+ QCOMPARE(std::move(copy).toLower(), lower);
+ copy = lower;
+ copy.detach();
+ QCOMPARE(std::move(copy).toLower(), lower);
+
+ copy = upper;
+ QCOMPARE(std::move(copy).toUpper(), upper);
+ copy = upper;
+ copy.detach();
+ QCOMPARE(std::move(copy).toUpper(), upper);
+}
+
+void tst_QByteArray::isUpper()
+{
+ QVERIFY(QByteArray().isUpper());
+ QVERIFY(QByteArray("").isUpper());
+ QVERIFY(QByteArray("TEXT").isUpper());
+ QVERIFY(QByteArray("\xD0\xDE").isUpper());
+ QVERIFY(QByteArray("\xD7").isUpper());
+ QVERIFY(QByteArray("\xDF").isUpper());
+ QVERIFY(!QByteArray("text").isUpper());
+ QVERIFY(!QByteArray("Text").isUpper());
+ QVERIFY(!QByteArray("tExt").isUpper());
+ QVERIFY(!QByteArray("teXt").isUpper());
+ QVERIFY(!QByteArray("texT").isUpper());
+ QVERIFY(!QByteArray("TExt").isUpper());
+ QVERIFY(!QByteArray("teXT").isUpper());
+ QVERIFY(!QByteArray("tEXt").isUpper());
+ QVERIFY(!QByteArray("tExT").isUpper());
+ QVERIFY(QByteArray("@ABYZ[").isUpper());
+ QVERIFY(!QByteArray("@abyz[").isUpper());
+ QVERIFY(QByteArray("`ABYZ{").isUpper());
+ QVERIFY(!QByteArray("`abyz{").isUpper());
+}
+
+void tst_QByteArray::isLower()
+{
+ QVERIFY(QByteArray().isLower());
+ QVERIFY(QByteArray("").isLower());
+ QVERIFY(QByteArray("text").isLower());
+ QVERIFY(QByteArray("\xE0\xFF").isLower());
+ QVERIFY(QByteArray("\xF7").isLower());
+ QVERIFY(!QByteArray("Text").isLower());
+ QVERIFY(!QByteArray("tExt").isLower());
+ QVERIFY(!QByteArray("teXt").isLower());
+ QVERIFY(!QByteArray("texT").isLower());
+ QVERIFY(!QByteArray("TExt").isLower());
+ QVERIFY(!QByteArray("teXT").isLower());
+ QVERIFY(!QByteArray("tEXt").isLower());
+ QVERIFY(!QByteArray("tExT").isLower());
+ QVERIFY(!QByteArray("TEXT").isLower());
+ QVERIFY(!QByteArray("@ABYZ[").isLower());
+ QVERIFY(QByteArray("@abyz[").isLower());
+ QVERIFY(!QByteArray("`ABYZ{").isLower());
+ QVERIFY(QByteArray("`abyz{").isLower());
+}
+
+void tst_QByteArray::macTypes()
+{
+#ifndef Q_OS_DARWIN
+ QSKIP("This is a Apple-only test");
+#else
+ extern void tst_QByteArray_macTypes(); // in qbytearray_mac.mm
+ tst_QByteArray_macTypes();
+#endif
+}
+
+void tst_QByteArray::stdString()
+{
+ std::string stdstr( "QByteArray" );
+
+ const QByteArray stlqt = QByteArray::fromStdString(stdstr);
+ QCOMPARE(stlqt.size(), int(stdstr.length()));
+ QCOMPARE(stlqt.data(), stdstr.c_str());
+ QCOMPARE(stlqt.toStdString(), stdstr);
+
+ std::string utf8str( "Nøt æscii" );
+ const QByteArray u8 = QByteArray::fromStdString(utf8str);
+ const QByteArray l1 = QString::fromUtf8(u8).toLatin1();
+ std::string l1str = l1.toStdString();
+ QVERIFY(l1str.length() < utf8str.length());
+}
+
+void tst_QByteArray::emptyAndClear()
+{
+ QByteArray a;
+ QVERIFY(a.isEmpty());
+ a.clear();
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a.append("data");
+ QVERIFY(!a.isEmpty());
+
+ a.clear();
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QByteArray::fill()
+{
+ QByteArray a;
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ // filling an empty QByteArray does nothing
+ a.fill('a');
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ // filling empty QByteArray to 0 length does nothing
+ a.fill('a', 0);
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a.fill('b', 5);
+ QCOMPARE(a, QByteArray("bbbbb"));
+
+ a.fill('c');
+ QCOMPARE(a, QByteArray("ccccc"));
+
+ a.fill('d', 2);
+ QCOMPARE(a, QByteArray("dd"));
+
+ // filling to 0 length empties the QByteArray
+ a.fill('a', 0);
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QByteArray::dataPointers()
+{
+ QByteArray a;
+ const char *constPtr = a.constData();
+ QCOMPARE(a.data(), constPtr); // does not detach on empty QBA.
+
+ a = "abc"; // detaches
+ const char *dataConstPtr = a.constData();
+ QVERIFY(dataConstPtr != constPtr);
+
+ QByteArray copy = a;
+ QCOMPARE(copy.constData(), dataConstPtr);
+
+ char *dataPtr = copy.data(); // detaches, as the QBA is not empty
+ QVERIFY(dataPtr != dataConstPtr);
+
+ *dataPtr = 'd';
+ QCOMPARE(copy, QByteArray("dbc"));
+ QCOMPARE(a, QByteArray("abc"));
+}
+
+void tst_QByteArray::truncate()
+{
+ QByteArray a;
+ a.truncate(0);
+ a.truncate(10);
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a = QByteArray("abcdef");
+ a.truncate(4);
+ QCOMPARE(a, QByteArray("abcd"));
+ a.truncate(5);
+ QCOMPARE(a, QByteArray("abcd"));
+
+ a.truncate(-5);
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QByteArray::trimmed_data()
+{
+ QTest::addColumn<QByteArray>("full" );
+ QTest::addColumn<QByteArray>("trimmed" );
+
+ QTest::addRow("null") << QByteArray() << QByteArray();
+ QTest::addRow("simple") << "Text"_ba << "Text"_ba;
+ QTest::addRow("single-space") << " "_ba << ""_ba;
+ QTest::addRow("single-char") << " a "_ba << "a"_ba;
+ QTest::addRow("mixed") << " a \n\t\v b "_ba << "a \n\t\v b"_ba;
+}
+
+void tst_QByteArray::trimmed()
+{
+ QFETCH(QByteArray, full);
+ QFETCH(QByteArray, trimmed);
+
+ // Shared
+ if (!full.isNull())
+ QVERIFY(!full.isDetached());
+ QCOMPARE(full.trimmed(), trimmed); // lvalue
+ QCOMPARE(QByteArray(full).trimmed(), trimmed); // rvalue
+ QCOMPARE(full.isNull(), trimmed.isNull());
+
+ // Not shared
+ full = QByteArrayView(full).toByteArray();
+ if (!full.isNull())
+ QVERIFY(full.isDetached());
+ QCOMPARE(full.trimmed(), trimmed); // lvalue
+ QCOMPARE(QByteArray(full).trimmed(), trimmed); // rvalue
+ QCOMPARE(full.isNull(), trimmed.isNull());
+}
+
+void tst_QByteArray::simplified()
+{
+ QFETCH(QByteArray, source);
+ QFETCH(QByteArray, expected);
+
+ QCOMPARE(source.simplified(), expected);
+ QByteArray copy = source;
+ QCOMPARE(std::move(copy).simplified(), expected);
+
+ if (source.isEmpty())
+ QVERIFY(!source.isDetached());
+}
+
+void tst_QByteArray::simplified_data()
+{
+ QTest::addColumn<QByteArray>("source");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("null") << QByteArray() << QByteArray();
+ QTest::newRow("empty") << QByteArray("") << QByteArray("");
+ QTest::newRow("no extra spaces") << QByteArray("a bc d") << QByteArray("a bc d");
+ QTest::newRow("with spaces") << QByteArray("\t \v a b\r\nc\td \r\n\f")
+ << QByteArray("a b c d");
+ QTest::newRow("all spaces") << QByteArray("\t \r \n \v \f") << QByteArray("");
+}
+
+void tst_QByteArray::left()
+{
+ QByteArray a;
+ QCOMPARE(QByteArray().left(0), QByteArray());
+ QCOMPARE(QByteArray().left(10), QByteArray());
+ QCOMPARE(a.left(0), QByteArray());
+ QCOMPARE(a.left(10), QByteArray());
+ QVERIFY(!a.isDetached());
+ QCOMPARE(QByteArray(a).left(0), QByteArray());
+ QCOMPARE(QByteArray(a).left(10), QByteArray());
+ QCOMPARE(detached(a).left(0), QByteArray());
+ QCOMPARE(detached(a).left(10), QByteArray());
+
+ a = QByteArray("abcdefgh");
+ const char *ptr = a.constData();
+
+ // lvalue
+ QCOMPARE(a.left(5), QByteArray("abcde"));
+ QCOMPARE(a.left(20), a);
+ QCOMPARE(a.left(-5), QByteArray());
+ // calling left() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+
+ // rvalue, not detached
+ QCOMPARE(QByteArray(a).left(5), QByteArray("abcde"));
+ QCOMPARE(QByteArray(a).left(20), a);
+ QCOMPARE(QByteArray(a).left(-5), QByteArray());
+ // calling left() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+
+ // rvalue, detached
+ QCOMPARE(detached(a).left(5), QByteArray("abcde"));
+ QCOMPARE(detached(a).left(20), a);
+ QCOMPARE(detached(a).left(-5), QByteArray());
+ // calling left() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+}
+
+void tst_QByteArray::right()
+{
+ QByteArray a;
+ QCOMPARE(QByteArray().right(0), QByteArray());
+ QCOMPARE(QByteArray().right(10), QByteArray());
+ QCOMPARE(a.right(0), QByteArray());
+ QCOMPARE(a.right(10), QByteArray());
+ QVERIFY(!a.isDetached());
+ QCOMPARE(QByteArray(a).right(0), QByteArray());
+ QCOMPARE(QByteArray(a).right(10), QByteArray());
+ QCOMPARE(detached(a).right(0), QByteArray());
+ QCOMPARE(detached(a).right(10), QByteArray());
+
+ a = QByteArray("abcdefgh");
+ const char *ptr = a.constData();
+
+ // lvalue
+ QCOMPARE(a.right(5), QByteArray("defgh"));
+ QCOMPARE(a.right(20), a);
+ QCOMPARE(a.right(-5), QByteArray());
+ // calling right() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+
+ // rvalue, not detached
+ QCOMPARE(QByteArray(a).right(5), QByteArray("defgh"));
+ QCOMPARE(QByteArray(a).right(20), a);
+ QCOMPARE(QByteArray(a).right(-5), QByteArray());
+ // calling right() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+
+ // rvalue, detached
+ QCOMPARE(detached(a).right(5), QByteArray("defgh"));
+ QCOMPARE(detached(a).right(20), a);
+ QCOMPARE(detached(a).right(-5), QByteArray());
+ // calling right() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+}
+
+void tst_QByteArray::mid()
+{
+ QByteArray a;
+ QCOMPARE(QByteArray().mid(0), QByteArray());
+ QCOMPARE(a.mid(0, 10), QByteArray());
+ QCOMPARE(a.mid(0), QByteArray());
+ QCOMPARE(a.mid(0, 10), QByteArray());
+ QCOMPARE(a.mid(10), QByteArray());
+ QVERIFY(!a.isDetached());
+ QCOMPARE(QByteArray(a).mid(0), QByteArray());
+ QCOMPARE(QByteArray(a).mid(0, 10), QByteArray());
+ QCOMPARE(QByteArray(a).mid(10), QByteArray());
+ QCOMPARE(detached(a).mid(0), QByteArray());
+ QCOMPARE(detached(a).mid(0, 10), QByteArray());
+ QCOMPARE(detached(a).mid(10), QByteArray());
+
+ a = QByteArray("abcdefgh");
+ const char *ptr = a.constData();
+
+ // lvalue
+ QCOMPARE(a.mid(2), QByteArray("cdefgh"));
+ QCOMPARE(a.mid(2, 3), QByteArray("cde"));
+ QCOMPARE(a.mid(20), QByteArray());
+ QCOMPARE(a.mid(-5), QByteArray("abcdefgh"));
+ QCOMPARE(a.mid(-5, 8), QByteArray("abc"));
+ // calling mid() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+
+ // rvalue, not detached
+ QCOMPARE(QByteArray(a).mid(2), QByteArray("cdefgh"));
+ QCOMPARE(QByteArray(a).mid(2, 3), QByteArray("cde"));
+ QCOMPARE(QByteArray(a).mid(20), QByteArray());
+ QCOMPARE(QByteArray(a).mid(-5), QByteArray("abcdefgh"));
+ QCOMPARE(QByteArray(a).mid(-5, 8), QByteArray("abc"));
+ // calling mid() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+
+ // rvalue, detached
+ QCOMPARE(detached(a).mid(2), QByteArray("cdefgh"));
+ QCOMPARE(detached(a).mid(2, 3), QByteArray("cde"));
+ QCOMPARE(detached(a).mid(20), QByteArray());
+ QCOMPARE(detached(a).mid(-5), QByteArray("abcdefgh"));
+ QCOMPARE(detached(a).mid(-5, 8), QByteArray("abc"));
+ // calling mid() does not modify the source array
+ QCOMPARE(a.constData(), ptr);
+}
+
+void tst_QByteArray::length()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(qsizetype, res);
+
+ QCOMPARE(src.size(), res);
+ QCOMPARE(src.size(), res);
+#if QT_DEPRECATED_SINCE(6, 4)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ QCOMPARE(src.size(), res);
+QT_WARNING_POP
+#endif
+}
+
+void tst_QByteArray::length_data()
+{
+ QTest::addColumn<QByteArray>("src");
+ QTest::addColumn<qsizetype>("res");
+
+ QTest::newRow("null") << QByteArray() << qsizetype(0);
+ QTest::newRow("empty") << QByteArray("") << qsizetype(0);
+ QTest::newRow("letters and digits") << QByteArray("abc123") << qsizetype(6);
+ QTest::newRow("with space chars") << QByteArray(" abc\r\n123\t\v") << qsizetype(11);
+ QTest::newRow("with '\\0'") << QByteArray("abc\0def", 7) << qsizetype(7);
+ QTest::newRow("with '\\0' no size") << QByteArray("abc\0def") << qsizetype(3);
+}
+
+void tst_QByteArray::slice() const
+{
+ QByteArray a;
+
+ a.slice(0);
+ QVERIFY(a.isEmpty());
+ QVERIFY(a.isNull());
+ a.slice(0, 0);
+ QVERIFY(a.isEmpty());
+ QVERIFY(a.isNull());
+
+ a = "Five pineapples";
+
+ a.slice(5);
+ QCOMPARE_EQ(a, "pineapples");
+
+ a.slice(4, 3);
+ QCOMPARE_EQ(a, "app");
+
+ a.slice(a.size());
+ QVERIFY(a.isEmpty());
+
+ a.slice(0, 0);
+ QVERIFY(a.isEmpty());
+}
+
+QTEST_MAIN(tst_QByteArray)
+#include "tst_qbytearray.moc"
diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm b/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm
new file mode 100644
index 0000000000..a457d84b44
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm
@@ -0,0 +1,74 @@
+// Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QByteArray>
+#include <QTest>
+
+#include <QtCore/private/qcore_mac_p.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Foundation/Foundation.h>
+
+void tst_QByteArray_macTypes()
+{
+ // QByteArray <-> CFData
+ {
+ QByteArray qtByteArray("test bytearray");
+ const CFDataRef cfData = qtByteArray.toCFData();
+ QCOMPARE(QByteArray::fromCFData(cfData), qtByteArray);
+ CFRelease(cfData);
+ }
+ {
+ QByteArray qtByteArray("test bytearray");
+ const CFDataRef cfData = qtByteArray.toCFData();
+ QByteArray qtByteArrayCopy(qtByteArray);
+ qtByteArray = qtByteArray.toUpper(); // modify
+ QCOMPARE(QByteArray::fromCFData(cfData), qtByteArrayCopy);
+ }
+ // QByteArray <-> CFData Raw
+ {
+ QByteArray qtByteArray("test bytearray");
+ const CFDataRef cfData = qtByteArray.toRawCFData();
+ const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
+ QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
+ CFRelease(cfData);
+ }
+ {
+ const UInt8 data[] = "cfdata test";
+ const CFDataRef cfData = CFDataCreate(kCFAllocatorDefault, data, sizeof(data));
+ const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
+ QByteArray qtByteArray = QByteArray::fromRawCFData(cfData);
+ QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
+ CFRelease(cfData);
+ }
+ // QByteArray <-> NSData
+ {
+ QMacAutoReleasePool pool;
+ QByteArray qtByteArray("test bytearray");
+ const NSData *nsData = qtByteArray.toNSData();
+ QCOMPARE(QByteArray::fromNSData(nsData), qtByteArray);
+ }
+ {
+ QMacAutoReleasePool pool;
+ QByteArray qtByteArray("test bytearray");
+ const NSData *nsData = qtByteArray.toNSData();
+ QByteArray qtByteArrayCopy(qtByteArray);
+ qtByteArray = qtByteArray.toUpper(); // modify
+ QCOMPARE(QByteArray::fromNSData(nsData), qtByteArrayCopy);
+ }
+ // QByteArray <-> NSData Raw
+ {
+ QMacAutoReleasePool pool;
+ QByteArray qtByteArray("test bytearray");
+ const NSData *nsData = qtByteArray.toRawNSData();
+ QCOMPARE([nsData bytes], qtByteArray.constData());
+ }
+ {
+ QMacAutoReleasePool pool;
+ const char data[] = "nsdata test";
+ const NSData *nsData = [NSData dataWithBytes:data length:sizeof(data)];
+ QByteArray qtByteArray = QByteArray::fromRawNSData(nsData);
+ QCOMPARE(qtByteArray.constData(), [nsData bytes]);
+ }
+}
diff --git a/tests/auto/corelib/tools/qbytearray/.gitattributes b/tests/auto/corelib/text/qbytearray_large/.gitattributes
index e04709aa2e..e04709aa2e 100644
--- a/tests/auto/corelib/tools/qbytearray/.gitattributes
+++ b/tests/auto/corelib/text/qbytearray_large/.gitattributes
diff --git a/tests/auto/corelib/text/qbytearray_large/CMakeLists.txt b/tests/auto/corelib/text/qbytearray_large/CMakeLists.txt
new file mode 100644
index 0000000000..3a2c6b7216
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearray_large/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytearray_large LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+set(compile_and_link_options "")
+if(WASM)
+ list(APPEND compile_and_link_options "-fexceptions")
+endif()
+
+qt_internal_add_test(tst_qbytearray_large
+ SOURCES
+ tst_qbytearray_large.cpp
+ LIBRARIES
+ Qt::Core
+ TESTDATA "rfc3252.txt"
+ COMPILE_OPTIONS ${compile_and_link_options}
+ LINK_OPTIONS ${compile_and_link_options}
+)
+
diff --git a/tests/auto/corelib/tools/qbytearray/rfc3252.txt b/tests/auto/corelib/text/qbytearray_large/rfc3252.txt
index b80c61bf0a..b80c61bf0a 100644
--- a/tests/auto/corelib/tools/qbytearray/rfc3252.txt
+++ b/tests/auto/corelib/text/qbytearray_large/rfc3252.txt
diff --git a/tests/auto/corelib/text/qbytearray_large/tst_qbytearray_large.cpp b/tests/auto/corelib/text/qbytearray_large/tst_qbytearray_large.cpp
new file mode 100644
index 0000000000..9cf7368907
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearray_large/tst_qbytearray_large.cpp
@@ -0,0 +1,224 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <qbytearray.h>
+
+#include <q20iterator.h>
+#include <stdexcept>
+#include <string_view>
+
+class tst_QByteArrayLarge : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+#ifndef QT_NO_COMPRESS
+ void qCompress_data();
+ void qCompress();
+ void qUncompressCorruptedData_data();
+ void qUncompressCorruptedData();
+ void qUncompress4GiBPlus();
+ void qCompressionZeroTermination();
+#endif
+ void base64_2GiB();
+};
+
+void tst_QByteArrayLarge::initTestCase()
+{
+#if defined(QT_ASAN_ENABLED)
+ QSKIP("Skipping QByteArray tests under ASAN as they are too slow");
+#endif
+}
+
+#ifndef QT_NO_COMPRESS
+void tst_QByteArrayLarge::qCompress_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+
+ const int size1 = 1024*1024;
+ QByteArray ba1( size1, 0 );
+
+ QTest::newRow( "00" ) << QByteArray();
+
+ int i;
+ for ( i=0; i<size1; i++ )
+ ba1[i] = (char)( i / 1024 );
+ QTest::newRow( "01" ) << ba1;
+
+ for ( i=0; i<size1; i++ )
+ ba1[i] = (char)( i % 256 );
+ QTest::newRow( "02" ) << ba1;
+
+ ba1.fill( 'A' );
+ QTest::newRow( "03" ) << ba1;
+
+ QFile file( QFINDTESTDATA("rfc3252.txt") );
+ QVERIFY( file.open(QIODevice::ReadOnly) );
+ QTest::newRow( "04" ) << file.readAll();
+}
+
+void tst_QByteArrayLarge::qCompress()
+{
+ QFETCH( QByteArray, ba );
+ QByteArray compressed = ::qCompress( ba );
+ QTEST( ::qUncompress( compressed ), "ba" );
+}
+
+void tst_QByteArrayLarge::qUncompressCorruptedData_data()
+{
+ QTest::addColumn<QByteArray>("in");
+
+ QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4);
+ QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4);
+ QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00", 4);
+ QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff", 4);
+ QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00", 4);
+ QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff", 4);
+ QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00", 4);
+ QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff", 4);
+ QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00", 4);
+ QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff", 4);
+ QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00", 4);
+ QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4);
+}
+
+// This test is expected to produce some warning messages in the test output.
+void tst_QByteArrayLarge::qUncompressCorruptedData()
+{
+ QFETCH(QByteArray, in);
+
+ QByteArray res;
+ res = ::qUncompress(in);
+ QCOMPARE(res, QByteArray());
+
+ res = ::qUncompress(in + "blah");
+ QCOMPARE(res, QByteArray());
+}
+
+void tst_QByteArrayLarge::qUncompress4GiBPlus()
+{
+ // after three rounds, this decompresses to 4GiB + 1 'X' bytes:
+ constexpr uchar compressed_3x[] = {
+ 0x00, 0x00, 0x1a, 0x76, 0x78, 0x9c, 0x63, 0xb0, 0xdf, 0xb4, 0xad, 0x62,
+ 0xce, 0xdb, 0x3b, 0x0b, 0xf3, 0x26, 0x27, 0x4a, 0xb4, 0x3d, 0x34, 0x5b,
+ 0xed, 0xb4, 0x41, 0xf1, 0xc0, 0x99, 0x2f, 0x02, 0x05, 0x67, 0x26, 0x88,
+ 0x6c, 0x66, 0x71, 0x34, 0x62, 0x9c, 0x75, 0x26, 0xb1, 0xa0, 0xe5, 0xcc,
+ 0xda, 0x94, 0x83, 0xc9, 0x05, 0x73, 0x0e, 0x3c, 0x39, 0xc2, 0xc7, 0xd0,
+ 0xae, 0x38, 0x53, 0x7b, 0x87, 0xdc, 0x01, 0x91, 0x45, 0x59, 0x4f, 0xda,
+ 0xbf, 0xca, 0xcc, 0x52, 0xdb, 0xbb, 0xde, 0xbb, 0xf6, 0xd3, 0x55, 0xff,
+ 0x7d, 0x77, 0x0e, 0x1b, 0xf0, 0xa4, 0xdf, 0xcf, 0xdb, 0x5f, 0x2f, 0xf5,
+ 0xd7, 0x7c, 0xfe, 0xbf, 0x3f, 0xbf, 0x3f, 0x9d, 0x7c, 0xda, 0x2c, 0xc8,
+ 0xc0, 0xc0, 0xb0, 0xe1, 0xf1, 0xb3, 0xfd, 0xfa, 0xdf, 0x8e, 0x7d, 0xef,
+ 0x7f, 0xb9, 0xc1, 0xc2, 0xae, 0x92, 0x19, 0x28, 0xf2, 0x66, 0xd7, 0xe5,
+ 0xbf, 0xed, 0x93, 0xbf, 0x6a, 0x14, 0x7c, 0xff, 0xf6, 0xe1, 0xe8, 0xb6,
+ 0x7e, 0x46, 0xa0, 0x90, 0xd9, 0xbb, 0xcf, 0x9f, 0x17, 0x37, 0x7f, 0xe5,
+ 0x6f, 0xb4, 0x7f, 0xfe, 0x5e, 0xfd, 0xb6, 0x1d, 0x1b, 0x50, 0xe8, 0xc6,
+ 0x8e, 0xe3, 0xab, 0x9f, 0xe6, 0xec, 0x65, 0xfd, 0x23, 0xb1, 0x4e, 0x7e,
+ 0xef, 0xbd, 0x6f, 0xa6, 0x40, 0xa1, 0x03, 0xc7, 0xfe, 0x0a, 0xf1, 0x00,
+ 0xe9, 0x06, 0x91, 0x83, 0x40, 0x92, 0x21, 0x43, 0x10, 0xcc, 0x11, 0x03,
+ 0x73, 0x3a, 0x90, 0x39, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
+ 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
+ 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
+ 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32,
+ 0xa3, 0x32, 0xa3, 0x32, 0xa3, 0x32, 0x34, 0x90, 0x99, 0xb6, 0x7e, 0xf5,
+ 0xd3, 0xe9, 0xbf, 0x35, 0x13, 0xca, 0x8c, 0x75, 0xec, 0xec, 0xa4, 0x2f,
+ 0x7e, 0x2d, 0xf9, 0xf3, 0xf0, 0xee, 0xea, 0xd5, 0xf5, 0xd3, 0x14, 0x57,
+ 0x06, 0x00, 0x00, 0xb9, 0x1e, 0x35, 0xce
+ };
+
+ constexpr qint64 GiB = 1024LL * 1024 * 1024;
+
+ if constexpr (sizeof(qsizetype) == sizeof(int)) {
+ QSKIP("This is a 64-bit-only test.");
+ } else {
+
+ // 1st
+ auto c = ::qUncompress(std::data(compressed_3x), q20::ssize(compressed_3x));
+ QVERIFY(!c.isNull()); // check for decompression error
+
+ // 2nd
+ c = ::qUncompress(c);
+ QVERIFY(!c.isNull());
+
+ // 3rd
+ try {
+ c = ::qUncompress(c);
+ if (c.isNull()) // this step (~18MiB -> 4GiB) might have run out of memory
+ QSKIP("Failed to allocate enough memory.");
+ } catch (const std::bad_alloc &) {
+ QSKIP("Failed to allocate enough memory.");
+ }
+
+ QCOMPARE(c.size(), 4 * GiB + 1);
+ QCOMPARE(std::string_view{c}.find_first_not_of('X'),
+ std::string_view::npos);
+
+ // re-compress once
+ // (produces 18MiB, we shouldn't use much more than that in allocated capacity)
+ c = ::qCompress(c);
+ QVERIFY(!c.isNull());
+
+ // and un-compress again, to make sure compression worked (we
+ // can't compare with compressed_3x, because zlib may change):
+ c = ::qUncompress(c);
+
+ QCOMPARE(c.size(), 4 * GiB + 1);
+ QCOMPARE(std::string_view{c}.find_first_not_of('X'),
+ std::string_view::npos);
+ }
+}
+
+void tst_QByteArrayLarge::qCompressionZeroTermination()
+{
+ QByteArray s = "Hello, I'm a string.";
+ QByteArray ba = ::qUncompress(::qCompress(s));
+ QCOMPARE(ba.data()[ba.size()], '\0');
+ QCOMPARE(ba, s);
+}
+#endif
+
+void tst_QByteArrayLarge::base64_2GiB()
+{
+#ifdef Q_OS_ANDROID
+ QSKIP("Android kills the test when using too much memory");
+#endif
+ if constexpr (sizeof(qsizetype) > sizeof(int)) {
+ try {
+ constexpr qint64 GiB = 1024 * 1024 * 1024;
+ static_assert((2 * GiB + 1) % 3 == 0);
+ const char inputChar = '\0'; // all-NULs encode as
+ const char outputChar = 'A'; // all-'A's
+ const qint64 inputSize = 2 * GiB + 1;
+ const qint64 outputSize = inputSize / 3 * 4;
+ const auto sv = [](const QByteArray &ba) {
+ return std::string_view{ba.data(), size_t(ba.size())};
+ };
+ QByteArray output;
+ {
+ const QByteArray input(inputSize, inputChar);
+ output = input.toBase64();
+ QCOMPARE(output.size(), outputSize);
+ QCOMPARE(sv(output).find_first_not_of(outputChar),
+ std::string_view::npos);
+ }
+ {
+ auto r = QByteArray::fromBase64Encoding(output);
+ QCOMPARE_EQ(r.decodingStatus, QByteArray::Base64DecodingStatus::Ok);
+ QCOMPARE(r.decoded.size(), inputSize);
+ QCOMPARE(sv(r.decoded).find_first_not_of(inputChar),
+ std::string_view::npos);
+ }
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate enough RAM.");
+ }
+ } else {
+ QSKIP("This is a 64-bit only test");
+ }
+}
+
+QTEST_MAIN(tst_QByteArrayLarge)
+#include "tst_qbytearray_large.moc"
diff --git a/tests/auto/corelib/text/qbytearrayapisymmetry/CMakeLists.txt b/tests/auto/corelib/text/qbytearrayapisymmetry/CMakeLists.txt
new file mode 100644
index 0000000000..865c9b7015
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearrayapisymmetry/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbytearrayapisymmetry Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytearrayapisymmetry LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbytearrayapisymmetry
+ SOURCES
+ tst_qbytearrayapisymmetry.cpp
+)
diff --git a/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp b/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp
new file mode 100644
index 0000000000..f03086342c
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearrayapisymmetry/tst_qbytearrayapisymmetry.cpp
@@ -0,0 +1,1561 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <QByteArrayView>
+
+#include <limits>
+
+class tst_QByteArrayApiSymmetry : public QObject
+{
+ Q_OBJECT
+private slots:
+ void startsWith_QByteArray_QByteArray_data() { startsWith_data(); }
+ void startsWith_QByteArray_QByteArray() { startsWith_impl<QByteArray, QByteArray>(); }
+ void startsWith_QByteArray_QByteArrayView_data() { startsWith_data(); }
+ void startsWith_QByteArray_QByteArrayView() { startsWith_impl<QByteArray, QByteArrayView>(); }
+ void startsWith_QByteArrayView_QByteArrayView_data() { startsWith_data(); }
+ void startsWith_QByteArrayView_QByteArrayView() { startsWith_impl<QByteArrayView, QByteArrayView>(); }
+ void startsWith_QByteArrayView_QByteArray_data() { startsWith_data(); }
+ void startsWith_QByteArrayView_QByteArray() { startsWith_impl<QByteArrayView, QByteArray>(); }
+ void startsWithChar_QByteArray() { startsWithChar_impl<QByteArray>(); }
+ void startsWithChar_QByteArrayView() { startsWithChar_impl<QByteArrayView>(); }
+
+ void endsWith_QByteArray_QByteArray_data() { endsWith_data(); }
+ void endsWith_QByteArray_QByteArray() { endsWith_impl<QByteArray, QByteArray>(); }
+ void endsWith_QByteArray_QByteArrayView_data() { endsWith_data(); }
+ void endsWith_QByteArray_QByteArrayView() { endsWith_impl<QByteArray, QByteArrayView>(); }
+ void endsWith_QByteArrayView_QByteArrayView_data() { endsWith_data(); }
+ void endsWith_QByteArrayView_QByteArrayView() { endsWith_impl<QByteArrayView, QByteArrayView>(); }
+ void endsWith_QByteArrayView_QByteArray_data() { endsWith_data(); }
+ void endsWith_QByteArrayView_QByteArray() { endsWith_impl<QByteArrayView, QByteArray>(); }
+ void endsWithChar_QByteArray() { endsWithChar_impl<QByteArray>(); }
+ void endsWithChar_QByteArrayView() { endsWithChar_impl<QByteArrayView>(); }
+
+ void indexOf_QByteArray_QByteArray_data() { indexOf_data(); }
+ void indexOf_QByteArray_QByteArray() { indexOf_impl<QByteArray, QByteArray>(); }
+ void indexOf_QByteArray_QByteArrayView_data() { indexOf_data(); }
+ void indexOf_QByteArray_QByteArrayView() { indexOf_impl<QByteArray, QByteArrayView>(); }
+ void indexOf_QByteArrayView_QByteArrayView_data() { indexOf_data(); }
+ void indexOf_QByteArrayView_QByteArrayView() { indexOf_impl<QByteArrayView, QByteArrayView>(); }
+ void indexOf_QByteArrayView_QByteArray_data() { indexOf_data(); }
+ void indexOf_QByteArrayView_QByteArray() { indexOf_impl<QByteArrayView, QByteArray>(); }
+
+ void lastIndexOf_QByteArray_QByteArray_data() { lastIndexOf_data(); }
+ void lastIndexOf_QByteArray_QByteArray() { lastIndexOf_impl<QByteArray, QByteArray>(); }
+ void lastIndexOf_QByteArray_QByteArrayView_data() { lastIndexOf_data(); }
+ void lastIndexOf_QByteArray_QByteArrayView() { lastIndexOf_impl<QByteArray, QByteArrayView>(); }
+ void lastIndexOf_QByteArrayView_QByteArrayView_data() { lastIndexOf_data(); }
+ void lastIndexOf_QByteArrayView_QByteArrayView() { lastIndexOf_impl<QByteArrayView, QByteArrayView>(); }
+ void lastIndexOf_QByteArrayView_QByteArray_data() { lastIndexOf_data(); }
+ void lastIndexOf_QByteArrayView_QByteArray() { lastIndexOf_impl<QByteArrayView, QByteArray>(); }
+
+ void contains_QByteArray_QByteArray_data() { contains_data(); }
+ void contains_QByteArray_QByteArray() { contains_impl<QByteArray, QByteArray>(); }
+ void contains_QByteArray_QByteArrayView_data() { contains_data(); }
+ void contains_QByteArray_QByteArrayView() { contains_impl<QByteArray, QByteArrayView>(); }
+ void contains_QByteArrayView_QByteArrayView_data() { contains_data(); }
+ void contains_QByteArrayView_QByteArrayView() { contains_impl<QByteArrayView, QByteArrayView>(); }
+ void contains_QByteArrayView_QByteArray_data() { contains_data(); }
+ void contains_QByteArrayView_QByteArray() { contains_impl<QByteArrayView, QByteArray>(); }
+
+ void count_QByteArray_QByteArray_data() { count_data(); }
+ void count_QByteArray_QByteArray() { count_impl<QByteArray, QByteArray>(); }
+ void count_QByteArray_QByteArrayView_data() { count_data(); }
+ void count_QByteArray_QByteArrayView() { count_impl<QByteArray, QByteArrayView>(); }
+ void count_QByteArrayView_QByteArrayView_data() { count_data(); }
+ void count_QByteArrayView_QByteArrayView() { count_impl<QByteArrayView, QByteArrayView>(); }
+ void count_QByteArrayView_QByteArray_data() { count_data(); }
+ void count_QByteArrayView_QByteArray() { count_impl<QByteArrayView, QByteArray>(); }
+
+ void compare_QByteArray_QByteArray_data() { compare_data(); }
+ void compare_QByteArray_QByteArray() { compare_impl<QByteArray, QByteArray>(); }
+ void compare_QByteArray_QByteArrayView_data() { compare_data(); }
+ void compare_QByteArray_QByteArrayView() { compare_impl<QByteArray, QByteArrayView>(); }
+ void compare_QByteArrayView_QByteArray_data() { compare_data(); }
+ void compare_QByteArrayView_QByteArray() { compare_impl<QByteArrayView, QByteArray>(); }
+ void compare_QByteArrayView_QByteArrayView_data() { compare_data(); }
+ void compare_QByteArrayView_QByteArrayView() { compare_impl<QByteArrayView, QByteArrayView>(); }
+
+ void sliced_QByteArray_data() { sliced_data(); }
+ void sliced_QByteArray() { sliced_impl<QByteArray>(); }
+ void sliced_QByteArrayView_data() { sliced_data(); }
+ void sliced_QByteArrayView() { sliced_impl<QByteArrayView>(); }
+
+ void first_QByteArray_data() { first_data(); }
+ void first_QByteArray() { first_impl<QByteArray>(); }
+ void first_QByteArrayView_data() { first_data(); }
+ void first_QByteArrayView() { first_impl<QByteArrayView>(); }
+
+ void last_QByteArray_data() { last_data(); }
+ void last_QByteArray() { last_impl<QByteArray>(); }
+ void last_QByteArrayView_data() { last_data(); }
+ void last_QByteArrayView() { last_impl<QByteArrayView>(); }
+
+ void chop_QByteArray_data() { chop_data(); }
+ void chop_QByteArray() { chop_impl<QByteArray>(); }
+ void chop_QByteArrayView_data() { chop_data(); }
+ void chop_QByteArrayView() { chop_impl<QByteArrayView>(); }
+
+ void trimmed_QByteArray_data() { trimmed_data(); }
+ void trimmed_QByteArray() { trimmed_impl<QByteArray>(); }
+ void trimmed_QByteArrayView_data() { trimmed_data(); }
+ void trimmed_QByteArrayView() { trimmed_impl<QByteArrayView>(); }
+
+ void toShort_QByteArray() const { toShort<QByteArray>(); }
+ void toShort_QByteArrayView() const { toShort<QByteArrayView>(); }
+ void toUShort_QByteArray() const { toUShort<QByteArray>(); }
+ void toUShort_QByteArrayView() const { toUShort<QByteArrayView>(); }
+ void toInt_QByteArray_data() const { toInt_data(); }
+ void toInt_QByteArrayView_data() const { toInt_data(); }
+ void toInt_QByteArray() const { toInt<QByteArray>(); }
+ void toInt_QByteArrayView() const { toInt<QByteArrayView>(); }
+ void toUInt_QByteArray_data() const { toUInt_data(); }
+ void toUInt_QByteArrayView_data() const { toUInt_data(); }
+ void toUInt_QByteArray() const { toUInt<QByteArray>(); }
+ void toUInt_QByteArrayView() const { toUInt<QByteArrayView>(); }
+ void toLong_QByteArray_data() const { toLong_data(); }
+ void toLong_QByteArrayView_data() const { toLong_data(); }
+ void toLong_QByteArray() const { toLong<QByteArray>(); }
+ void toLong_QByteArrayView() const { toLong<QByteArrayView>(); }
+ void toULong_QByteArray_data() const { toULong_data(); }
+ void toULong_QByteArrayView_data() const { toULong_data(); }
+ void toULong_QByteArray() const { toULong<QByteArray>(); }
+ void toULong_QByteArrayView() const { toULong<QByteArrayView>(); }
+ void toLongLong_QByteArray_data() const { toLongLong_data(); }
+ void toLongLong_QByteArrayView_data() const { toLongLong_data(); }
+ void toLongLong_QByteArray() const { toLongLong<QByteArray>(); }
+ void toLongLong_QByteArrayView() const { toLongLong<QByteArrayView>(); }
+ void toULongLong_QByteArray_data() const { toULongLong_data(); }
+ void toULongLong_QByteArrayView_data() const { toULongLong_data(); }
+ void toULongLong_QByteArray() const { toULongLong<QByteArray>(); }
+ void toULongLong_QByteArrayView() const { toULongLong<QByteArrayView>(); }
+ void toFloat_QByteArray() const { toFloat<QByteArray>(); }
+ void toFloat_QByteArrayView() const { toFloat<QByteArrayView>(); }
+ void toDouble_QByteArray_data() const { toDouble_data(); }
+ void toDouble_QByteArrayView_data() const { toDouble_data(); }
+ void toDouble_QByteArray() const { toDouble<QByteArray>(); }
+ void toDouble_QByteArrayView() const { toDouble<QByteArrayView>(); }
+
+private:
+ void startsWith_data();
+ template<typename Haystack, typename Needle> void startsWith_impl();
+ template<typename Haystack> void startsWithChar_impl();
+
+ void endsWith_data();
+ template<typename Haystack, typename Needle> void endsWith_impl();
+ template<typename Haystack> void endsWithChar_impl();
+
+ void indexOf_data();
+ template<typename Haystack, typename Needle> void indexOf_impl();
+
+ void lastIndexOf_data();
+ template<typename Haystack, typename Needle> void lastIndexOf_impl();
+
+ void contains_data();
+ template<typename Haystack, typename Needle> void contains_impl();
+
+ void count_data();
+ template <typename Haystack, typename Needle> void count_impl();
+
+ void compare_data();
+ template <typename LHS, typename RHS> void compare_impl();
+
+ void sliced_data();
+ template <typename ByteArray> void sliced_impl();
+
+ void first_data();
+ template <typename ByteArray> void first_impl();
+
+ void last_data();
+ template <typename ByteArray> void last_impl();
+
+ void chop_data();
+ template <typename ByteArray> void chop_impl();
+
+ void trimmed_data();
+ template <typename ByteArray> void trimmed_impl();
+
+ template <typename ByteArray> void toShort() const;
+ template <typename ByteArray> void toUShort() const;
+ void toInt_data() const;
+ template <typename ByteArray> void toInt() const;
+ void toUInt_data() const;
+ template <typename ByteArray> void toUInt() const;
+ void toLong_data() const;
+ template <typename ByteArray> void toLong() const;
+ void toULong_data() const;
+ template <typename ByteArray> void toULong() const;
+ void toLongLong_data() const;
+ template <typename ByteArray> void toLongLong() const;
+ void toULongLong_data() const;
+ template <typename ByteArray> void toULongLong() const;
+ template <typename ByteArray> void toFloat() const;
+ void toDouble_data() const;
+ template <typename ByteArray> void toDouble() const;
+};
+
+static const auto empty = QByteArray("");
+static const QByteArray null;
+// the tests below rely on the fact that these objects' names match their contents:
+static const auto a = QByteArrayLiteral("a");
+static const auto A = QByteArrayLiteral("A");
+static const auto b = QByteArrayLiteral("b");
+static const auto B = QByteArrayLiteral("B");
+static const auto c = QByteArrayLiteral("c");
+static const auto C = QByteArrayLiteral("C");
+static const auto ab = QByteArrayLiteral("ab");
+static const auto aB = QByteArrayLiteral("aB");
+static const auto bc = QByteArrayLiteral("bc");
+static const auto bC = QByteArrayLiteral("bC");
+static const auto Bc = QByteArrayLiteral("Bc");
+static const auto BC = QByteArrayLiteral("BC");
+static const auto abc = QByteArrayLiteral("abc");
+static const auto aBc = QByteArrayLiteral("aBc");
+
+void tst_QByteArrayApiSymmetry::startsWith_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<QByteArray>("sw");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("01") << QByteArray() << QByteArray() << true;
+ QTest::newRow("02") << QByteArray() << QByteArray("") << true;
+ QTest::newRow("03") << QByteArray() << QByteArray("hallo") << false;
+
+ QTest::newRow("04") << QByteArray("") << QByteArray() << true;
+ QTest::newRow("05") << QByteArray("") << QByteArray("") << true;
+ QTest::newRow("06") << QByteArray("") << QByteArray("h") << false;
+
+ QTest::newRow("07") << QByteArray("hallo") << QByteArray("h") << true;
+ QTest::newRow("08") << QByteArray("hallo") << QByteArray("hallo") << true;
+ QTest::newRow("09") << QByteArray("hallo") << QByteArray("") << true;
+ QTest::newRow("10") << QByteArray("hallo") << QByteArray("hallohallo") << false;
+ QTest::newRow("11") << QByteArray("hallo") << QByteArray() << true;
+}
+
+template<typename Haystack, typename Needle>
+void tst_QByteArrayApiSymmetry::startsWith_impl()
+{
+ QFETCH(QByteArray, ba);
+ QFETCH(QByteArray, sw);
+ QFETCH(bool, result);
+
+ const Haystack haystack(ba.data(), ba.size());
+ const Needle needle(sw.data(), sw.size());
+
+ QVERIFY(haystack.startsWith(needle) == result);
+ if (needle.isNull()) {
+ QVERIFY(haystack.startsWith((char *)0) == result);
+ } else {
+ QVERIFY(haystack.startsWith(needle.data()) == result);
+ if (needle.size() == 1)
+ QVERIFY(haystack.startsWith(needle.at(0)) == result);
+ }
+}
+
+template<typename Haystack>
+void tst_QByteArrayApiSymmetry::startsWithChar_impl()
+{
+ QVERIFY(Haystack("hallo").startsWith('h'));
+ QVERIFY(!Haystack("hallo").startsWith('\0'));
+ QVERIFY(!Haystack("hallo").startsWith('o'));
+ QVERIFY(Haystack("h").startsWith('h'));
+ QVERIFY(!Haystack("h").startsWith('\0'));
+ QVERIFY(!Haystack("h").startsWith('o'));
+ QVERIFY(!Haystack("hallo").startsWith('l'));
+ QVERIFY(!Haystack("").startsWith('\0'));
+ QVERIFY(!Haystack("").startsWith('a'));
+ QVERIFY(!Haystack().startsWith('a'));
+ QVERIFY(!Haystack().startsWith('\0'));
+}
+
+void tst_QByteArrayApiSymmetry::endsWith_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<QByteArray>("sw");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("01") << QByteArray() << QByteArray() << true;
+ QTest::newRow("02") << QByteArray() << QByteArray("") << true;
+ QTest::newRow("03") << QByteArray() << QByteArray("hallo") << false;
+
+ QTest::newRow("04") << QByteArray("") << QByteArray() << true;
+ QTest::newRow("05") << QByteArray("") << QByteArray("") << true;
+ QTest::newRow("06") << QByteArray("") << QByteArray("h") << false;
+
+ QTest::newRow("07") << QByteArray("hallo") << QByteArray("o") << true;
+ QTest::newRow("08") << QByteArray("hallo") << QByteArray("hallo") << true;
+ QTest::newRow("09") << QByteArray("hallo") << QByteArray("") << true;
+ QTest::newRow("10") << QByteArray("hallo") << QByteArray("hallohallo") << false;
+ QTest::newRow("11") << QByteArray("hallo") << QByteArray() << true;
+}
+
+template<typename Haystack, typename Needle>
+void tst_QByteArrayApiSymmetry::endsWith_impl()
+{
+ QFETCH(QByteArray, ba);
+ QFETCH(QByteArray, sw);
+ QFETCH(bool, result);
+
+ const Haystack haystack(ba.data(), ba.size());
+ const Needle needle(sw.data(), sw.size());
+
+ QVERIFY(haystack.endsWith(needle) == result);
+ if (needle.isNull()) {
+ QVERIFY(haystack.endsWith((char *)0) == result);
+ } else {
+ QVERIFY(haystack.endsWith(needle.data()) == result);
+ if (needle.size() == 1)
+ QVERIFY(haystack.endsWith(needle.at(0)) == result);
+ }
+}
+
+template<typename Haystack>
+void tst_QByteArrayApiSymmetry::endsWithChar_impl()
+{
+ QVERIFY(Haystack("hallo").endsWith('o'));
+ QVERIFY(!Haystack("hallo").endsWith('\0'));
+ QVERIFY(!Haystack("hallo").endsWith('h'));
+ QVERIFY(Haystack("h").endsWith('h'));
+ QVERIFY(!Haystack("h").endsWith('\0'));
+ QVERIFY(!Haystack("h").endsWith('o'));
+ QVERIFY(!Haystack("hallo").endsWith('l'));
+ QVERIFY(!Haystack("").endsWith('\0'));
+ QVERIFY(!Haystack("").endsWith('a'));
+ QVERIFY(!Haystack().endsWith('a'));
+ QVERIFY(!Haystack().endsWith('\0'));
+}
+
+void tst_QByteArrayApiSymmetry::indexOf_data()
+{
+ QTest::addColumn<QByteArray>("ba1");
+ QTest::addColumn<QByteArray>("ba2");
+ QTest::addColumn<int>("startpos");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("1") << abc << a << 0 << 0;
+ QTest::newRow("2") << abc << A << 0 << -1;
+ QTest::newRow("3") << abc << a << 1 << -1;
+ QTest::newRow("4") << abc << A << 1 << -1;
+ QTest::newRow("5") << abc << b << 0 << 1;
+ QTest::newRow("6") << abc << B << 0 << -1;
+ QTest::newRow("7") << abc << b << 1 << 1;
+ QTest::newRow("8") << abc << B << 1 << -1;
+ QTest::newRow("9") << abc << b << 2 << -1;
+ QTest::newRow("10") << abc << c << 0 << 2;
+ QTest::newRow("11") << abc << C << 0 << -1;
+ QTest::newRow("12") << abc << c << 1 << 2;
+ QTest::newRow("13") << abc << C << 1 << -1;
+ QTest::newRow("14") << abc << c << 2 << 2;
+ QTest::newRow("15") << aBc << bc << 0 << -1;
+ QTest::newRow("16") << aBc << Bc << 0 << 1;
+ QTest::newRow("17") << aBc << bC << 0 << -1;
+ QTest::newRow("18") << aBc << BC << 0 << -1;
+
+ static const char h19[] = { 'x', 0x00, (char)0xe7, 0x25, 0x1c, 0x0a };
+ static const char n19[] = { 0x00, 0x00, 0x01, 0x00 };
+ QTest::newRow("19") << QByteArray(h19, sizeof(h19)) << QByteArray(n19, sizeof(n19)) << 0 << -1;
+
+ QTest::newRow("empty from 0") << QByteArray("") << QByteArray("x") << 0 << -1;
+ QTest::newRow("empty from -1") << QByteArray("") << QByteArray("x") << -1 << -1;
+ QTest::newRow("empty from 1") << QByteArray("") << QByteArray("x") << 1 << -1;
+ QTest::newRow("null from 0") << QByteArray() << QByteArray("x") << 0 << -1;
+ QTest::newRow("null from -1") << QByteArray() << QByteArray("x") << -1 << -1;
+ QTest::newRow("null from 1") << QByteArray() << QByteArray("x") << 1 << -1;
+ QTest::newRow("null-in-null") << QByteArray() << QByteArray() << 0 << 0;
+ QTest::newRow("empty-in-null") << QByteArray() << QByteArray("") << 0 << 0;
+ QTest::newRow("null-in-empty") << QByteArray("") << QByteArray() << 0 << 0;
+ QTest::newRow("empty-in-empty") << QByteArray("") << QByteArray("") << 0 << 0;
+ QTest::newRow("empty in abc from 0") << abc << QByteArray() << 0 << 0;
+ QTest::newRow("empty in abc from 2") << abc << QByteArray() << 2 << 2;
+ QTest::newRow("empty in abc from 5") << abc << QByteArray() << 5 << -1;
+ QTest::newRow("empty in abc from -1") << abc << QByteArray() << -1 << 2;
+
+ QByteArray veryBigHaystack(500, 'a');
+ veryBigHaystack += 'B';
+ QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << 0;
+ QTest::newRow("BoyerMooreStressTest2")
+ << QByteArray(veryBigHaystack + 'c') << QByteArray(veryBigHaystack) << 0 << 0;
+ QTest::newRow("BoyerMooreStressTest3")
+ << QByteArray('c' + veryBigHaystack) << QByteArray(veryBigHaystack) << 0 << 1;
+ QTest::newRow("BoyerMooreStressTest4")
+ << QByteArray(veryBigHaystack) << QByteArray(veryBigHaystack + 'c') << 0 << -1;
+ QTest::newRow("BoyerMooreStressTest5")
+ << QByteArray(veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1;
+ QTest::newRow("BoyerMooreStressTest6")
+ << QByteArray('d' + veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1;
+ QTest::newRow("BoyerMooreStressTest7")
+ << QByteArray(veryBigHaystack + 'c') << QByteArray('c' + veryBigHaystack) << 0 << -1;
+}
+
+template<typename Haystack, typename Needle>
+void tst_QByteArrayApiSymmetry::indexOf_impl()
+{
+ QFETCH(QByteArray, ba1);
+ QFETCH(QByteArray, ba2);
+ QFETCH(int, startpos);
+ QFETCH(int, expected);
+
+ const Haystack haystack(ba1.data(), ba1.size());
+ const Needle needle(ba2.data(), ba2.size());
+
+ bool hasNull = needle.contains('\0');
+
+ QCOMPARE(haystack.indexOf(needle, startpos), expected);
+ if (!hasNull)
+ QCOMPARE(haystack.indexOf(needle.data(), startpos), expected);
+ if (needle.size() == 1)
+ QCOMPARE(haystack.indexOf(needle.at(0), startpos), expected);
+
+ if (startpos == 0) {
+ QCOMPARE(haystack.indexOf(needle), expected);
+ if (!hasNull)
+ QCOMPARE(haystack.indexOf(needle.data()), expected);
+ if (needle.size() == 1)
+ QCOMPARE(haystack.indexOf(needle.at(0)), expected);
+ }
+}
+
+void tst_QByteArrayApiSymmetry::lastIndexOf_data()
+{
+ QTest::addColumn<QByteArray>("ba1");
+ QTest::addColumn<QByteArray>("ba2");
+ QTest::addColumn<int>("startpos");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("1") << abc << a << 0 << 0;
+ QTest::newRow("2") << abc << A << 0 << -1;
+ QTest::newRow("3") << abc << a << 1 << 0;
+ QTest::newRow("4") << abc << A << 1 << -1;
+ QTest::newRow("5") << abc << a << -1 << 0;
+ QTest::newRow("6") << abc << b << 0 << -1;
+ QTest::newRow("7") << abc << B << 0 << -1;
+ QTest::newRow("8") << abc << b << 1 << 1;
+ QTest::newRow("9") << abc << B << 1 << -1;
+ QTest::newRow("10") << abc << b << 2 << 1;
+ QTest::newRow("11") << abc << b << -1 << 1;
+ QTest::newRow("12") << abc << c << 0 << -1;
+ QTest::newRow("13") << abc << C << 0 << -1;
+ QTest::newRow("14") << abc << c << 1 << -1;
+ QTest::newRow("15") << abc << C << 1 << -1;
+ QTest::newRow("16") << abc << c << 2 << 2;
+ QTest::newRow("17") << abc << c << -1 << 2;
+ QTest::newRow("18") << aBc << bc << 0 << -1;
+ QTest::newRow("19") << aBc << Bc << 0 << -1;
+ QTest::newRow("20") << aBc << Bc << 2 << 1;
+ QTest::newRow("21") << aBc << Bc << 1 << 1;
+ QTest::newRow("22") << aBc << Bc << -1 << 1;
+ QTest::newRow("23") << aBc << bC << 0 << -1;
+ QTest::newRow("24") << aBc << BC << 0 << -1;
+
+ static const char h25[] = { 0x00, (char)0xbc, 0x03, 0x10, 0x0a };
+ static const char n25[] = { 0x00, 0x00, 0x01, 0x00 };
+ QTest::newRow("25") << QByteArray(h25, sizeof(h25)) << QByteArray(n25, sizeof(n25)) << 0 << -1;
+
+ QTest::newRow("empty from 0") << QByteArray("") << QByteArray("x") << 0 << -1;
+ QTest::newRow("empty from -1") << QByteArray("") << QByteArray("x") << -1 << -1;
+ QTest::newRow("empty from 1") << QByteArray("") << QByteArray("x") << 1 << -1;
+ QTest::newRow("null from 0") << QByteArray() << QByteArray("x") << 0 << -1;
+ QTest::newRow("null from -1") << QByteArray() << QByteArray("x") << -1 << -1;
+ QTest::newRow("null from 1") << QByteArray() << QByteArray("x") << 1 << -1;
+ QTest::newRow("null-in-null-off--1") << QByteArray() << QByteArray() << -1 << -1;
+ QTest::newRow("null-in-null-off-0") << QByteArray() << QByteArray() << 0 << 0;
+ QTest::newRow("empty-in-null-off--1") << QByteArray() << QByteArray("") << -1 << -1;
+ QTest::newRow("empty-in-null-off-0") << QByteArray() << QByteArray("") << 0 << 0;
+ QTest::newRow("null-in-empty-off--1") << QByteArray("") << QByteArray() << -1 << -1;
+ QTest::newRow("null-in-empty-off-0") << QByteArray("") << QByteArray() << 0 << 0;
+ QTest::newRow("empty-in-empty-off--1") << QByteArray("") << QByteArray("") << -1 << -1;
+ QTest::newRow("empty-in-empty-off-0") << QByteArray("") << QByteArray("") << 0 << 0;
+ QTest::newRow("empty in abc from 0") << abc << QByteArray() << 0 << 0;
+ QTest::newRow("empty in abc from 2") << abc << QByteArray() << 2 << 2;
+ QTest::newRow("empty in abc from 5")
+ << abc << QByteArray() << 5 << -1; // perversely enough, should be 3?
+ QTest::newRow("empty in abc from -1") << abc << QByteArray() << -1 << 3;
+ QTest::newRow("empty in abc from -5")
+ << abc << QByteArray() << -5 << 3; // perversely enough, should be -1?
+}
+
+template<typename Haystack, typename Needle>
+void tst_QByteArrayApiSymmetry::lastIndexOf_impl()
+{
+ QFETCH(QByteArray, ba1);
+ QFETCH(QByteArray, ba2);
+ QFETCH(int, startpos);
+ QFETCH(int, expected);
+
+ const Haystack haystack(ba1.data(), ba1.size());
+ const Needle needle(ba2.data(), ba2.size());
+
+ bool hasNull = needle.contains('\0');
+
+ QCOMPARE(haystack.lastIndexOf(needle, startpos), expected);
+ if (!hasNull)
+ QCOMPARE(haystack.lastIndexOf(needle.data(), startpos), expected);
+ if (needle.size() == 1)
+ QCOMPARE(haystack.lastIndexOf(needle.at(0), startpos), expected);
+
+ if (startpos == haystack.size()) {
+ QCOMPARE(haystack.lastIndexOf(needle), expected);
+ if (!hasNull)
+ QCOMPARE(haystack.lastIndexOf(needle.data()), expected);
+ if (needle.size() == 1)
+ QCOMPARE(haystack.lastIndexOf(needle.at(0)), expected);
+ }
+}
+
+void tst_QByteArrayApiSymmetry::contains_data()
+{
+ QTest::addColumn<QByteArray>("ba1");
+ QTest::addColumn<QByteArray>("ba2");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("1") << abc << a << true;
+ QTest::newRow("2") << abc << A << false;
+ QTest::newRow("3") << abc << b << true;
+ QTest::newRow("4") << abc << B << false;
+ QTest::newRow("5") << abc << c << true;
+ QTest::newRow("6") << abc << C << false;
+ QTest::newRow("7") << aBc << Bc << true;
+ QTest::newRow("8") << aBc << bc << false;
+
+ const char withnull[] = "a\0bc";
+ QTest::newRow("withnull") << QByteArray(withnull, 4) << QByteArray("bc") << true;
+
+ QTest::newRow("empty") << QByteArray("") << QByteArray("x") << false;
+ QTest::newRow("null") << QByteArray() << QByteArray("x") << false;
+ QTest::newRow("null-in-null") << QByteArray() << QByteArray() << true;
+ QTest::newRow("empty-in-null") << QByteArray() << QByteArray("") << true;
+ QTest::newRow("null-in-empty") << QByteArray("") << QByteArray() << true;
+ QTest::newRow("empty-in-empty") << QByteArray("") << QByteArray("") << true;
+}
+
+template<typename Haystack, typename Needle>
+void tst_QByteArrayApiSymmetry::contains_impl()
+{
+ QFETCH(QByteArray, ba1);
+ QFETCH(QByteArray, ba2);
+ QFETCH(bool, result);
+
+ const Haystack haystack(ba1.data(), ba1.size());
+ const Needle needle(ba2.data(), ba2.size());
+
+ QCOMPARE(haystack.contains(needle), result);
+ if (needle.size() == 1)
+ QCOMPARE(haystack.contains(needle.at(0)), result);
+}
+
+
+void tst_QByteArrayApiSymmetry::count_data()
+{
+ QTest::addColumn<QByteArray>("ba1");
+ QTest::addColumn<QByteArray>("ba2");
+ QTest::addColumn<int>("result");
+
+ QTest::addRow("aaa") << QByteArray("aaa") << QByteArray("a") << 3;
+ QTest::addRow("xyzaaaxyz") << QByteArray("xyzaaxyaxyz") << QByteArray("xyz") << 2;
+ QTest::addRow("a in null") << QByteArray() << QByteArray("a") << 0;
+ QTest::addRow("a in empty") << QByteArray("") << QByteArray("a") << 0;
+ QTest::addRow("xyz in null") << QByteArray() << QByteArray("xyz") << 0;
+ QTest::addRow("xyz in empty") << QByteArray("") << QByteArray("xyz") << 0;
+ QTest::addRow("null in null") << QByteArray() << QByteArray() << 1;
+ QTest::addRow("empty in empty") << QByteArray("") << QByteArray("") << 1;
+ QTest::addRow("empty in null") << QByteArray() << QByteArray("") << 1;
+ QTest::addRow("null in empty") << QByteArray("") << QByteArray() << 1;
+
+ const int len = 500;
+ QByteArray longData(len, 'a');
+ const QByteArray needle("abcdef");
+ longData.insert(0, needle);
+ longData.insert(len / 2, needle);
+ QTest::addRow("longInput") << longData << needle << 2;
+}
+
+template <typename Haystack, typename Needle>
+void tst_QByteArrayApiSymmetry::count_impl()
+{
+ QFETCH(const QByteArray, ba1);
+ QFETCH(const QByteArray, ba2);
+ QFETCH(int, result);
+
+ const Haystack haystack(ba1.data(), ba1.size());
+ const Needle needle(ba2.data(), ba2.size());
+
+ QCOMPARE(haystack.count(needle), result);
+ if (needle.size() == 1)
+ QCOMPARE(haystack.count(needle.at(0)), result);
+}
+
+void tst_QByteArrayApiSymmetry::compare_data()
+{
+ QTest::addColumn<QByteArray>("ba1");
+ QTest::addColumn<QByteArray>("ba2");
+ QTest::addColumn<int>("result");
+
+ QTest::newRow("null") << QByteArray() << QByteArray() << 0;
+ QTest::newRow("null-empty")<< QByteArray() << QByteArray("") << 0;
+ QTest::newRow("empty-null")<< QByteArray("") << QByteArray() << 0;
+ QTest::newRow("null-full") << QByteArray() << QByteArray("abc") << -1;
+ QTest::newRow("full-null") << QByteArray("abc") << QByteArray() << +1;
+ QTest::newRow("empty-full")<< QByteArray("") << QByteArray("abc") << -1;
+ QTest::newRow("full-empty")<< QByteArray("abc") << QByteArray("") << +1;
+ QTest::newRow("rawempty-full") << QByteArray::fromRawData("abc", 0) << QByteArray("abc") << -1;
+ QTest::newRow("full-rawempty") << QByteArray("abc") << QByteArray::fromRawData("abc", 0) << +1;
+
+ QTest::newRow("equal 1") << QByteArray("abc") << QByteArray("abc") << 0;
+ QTest::newRow("equal 2") << QByteArray::fromRawData("abc", 3) << QByteArray("abc") << 0;
+ QTest::newRow("equal 3") << QByteArray::fromRawData("abcdef", 3) << QByteArray("abc") << 0;
+ QTest::newRow("equal 4") << QByteArray("abc") << QByteArray::fromRawData("abc", 3) << 0;
+ QTest::newRow("equal 5") << QByteArray("abc") << QByteArray::fromRawData("abcdef", 3) << 0;
+ QTest::newRow("equal 6") << QByteArray("a\0bc", 4) << QByteArray("a\0bc", 4) << 0;
+ QTest::newRow("equal 7") << QByteArray::fromRawData("a\0bcdef", 4) << QByteArray("a\0bc", 4) << 0;
+ QTest::newRow("equal 8") << QByteArray("a\0bc", 4) << QByteArray::fromRawData("a\0bcdef", 4) << 0;
+
+ QTest::newRow("less 1") << QByteArray("000") << QByteArray("abc") << -1;
+ QTest::newRow("less 2") << QByteArray::fromRawData("00", 3) << QByteArray("abc") << -1;
+ QTest::newRow("less 3") << QByteArray("000") << QByteArray::fromRawData("abc", 3) << -1;
+ QTest::newRow("less 4") << QByteArray("abc", 3) << QByteArray("abc", 4) << -1;
+ QTest::newRow("less 5") << QByteArray::fromRawData("abc\0", 3) << QByteArray("abc\0", 4) << -1;
+ QTest::newRow("less 6") << QByteArray("a\0bc", 4) << QByteArray("a\0bd", 4) << -1;
+
+ QTest::newRow("greater 1") << QByteArray("abc") << QByteArray("000") << +1;
+ QTest::newRow("greater 2") << QByteArray("abc") << QByteArray::fromRawData("00", 3) << +1;
+ QTest::newRow("greater 3") << QByteArray("abcd") << QByteArray::fromRawData("abcd", 3) << +1;
+ QTest::newRow("greater 4") << QByteArray("a\0bc", 4) << QByteArray("a\0bb", 4) << +1;
+}
+
+template <typename LHS, typename RHS>
+void tst_QByteArrayApiSymmetry::compare_impl()
+{
+ QFETCH(QByteArray, ba1);
+ QFETCH(QByteArray, ba2);
+ QFETCH(int, result);
+
+ const bool isEqual = result == 0;
+ const bool isLess = result < 0;
+ const bool isGreater = result > 0;
+
+ const LHS lhs(ba1);
+ const RHS rhs(ba2);
+
+ if constexpr (std::is_same_v<QByteArray, LHS>) {
+ int cmp = lhs.compare(rhs);
+ if (cmp)
+ cmp = (cmp < 0 ? -1 : 1);
+ QCOMPARE(cmp, result);
+ }
+
+ // basic tests:
+ QCOMPARE(lhs == rhs, isEqual);
+ QCOMPARE(lhs < rhs, isLess);
+ QCOMPARE(lhs > rhs, isGreater);
+
+ // composed tests:
+ QCOMPARE(lhs <= rhs, isLess || isEqual);
+ QCOMPARE(lhs >= rhs, isGreater || isEqual);
+ QCOMPARE(lhs != rhs, !isEqual);
+
+ // inverted tests:
+ QCOMPARE(rhs == lhs, isEqual);
+ QCOMPARE(rhs < lhs, isGreater);
+ QCOMPARE(rhs > lhs, isLess);
+
+ // composed, inverted tests:
+ QCOMPARE(rhs <= lhs, isGreater || isEqual);
+ QCOMPARE(rhs >= lhs, isLess || isEqual);
+ QCOMPARE(rhs != lhs, !isEqual);
+
+ if (isEqual)
+ QVERIFY(qHash(lhs) == qHash(rhs));
+}
+
+template <typename ByteArray> ByteArray detached(ByteArray b)
+{
+ if (!b.isNull()) { // detaching loses nullness, but we need to preserve it
+ auto d = b.data();
+ Q_UNUSED(d);
+ }
+ return b;
+}
+
+void tst_QByteArrayApiSymmetry::sliced_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<int>("pos");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QByteArray>("result1");
+ QTest::addColumn<QByteArray>("result2");
+
+ QTest::addRow("empty") << empty << 0 << 0 << empty << empty;
+#define ROW(base, p, n, r1, r2) \
+ QTest::addRow("%s%d%d", #base, p, n) << base << p << n << r1 << r2
+
+ ROW(a, 0, 0, a, empty);
+ ROW(a, 0, 1, a, a);
+ ROW(a, 1, 0, empty, empty);
+
+ ROW(ab, 0, 0, ab, empty);
+ ROW(ab, 0, 1, ab, a);
+ ROW(ab, 0, 2, ab, ab);
+ ROW(ab, 1, 0, b, empty);
+ ROW(ab, 1, 1, b, b);
+ ROW(ab, 2, 0, empty, empty);
+
+ ROW(abc, 0, 0, abc, empty);
+ ROW(abc, 0, 1, abc, a);
+ ROW(abc, 0, 2, abc, ab);
+ ROW(abc, 0, 3, abc, abc);
+ ROW(abc, 1, 0, bc, empty);
+ ROW(abc, 1, 1, bc, b);
+ ROW(abc, 1, 2, bc, bc);
+ ROW(abc, 2, 0, c, empty);
+ ROW(abc, 2, 1, c, c);
+ ROW(abc, 3, 0, empty, empty);
+#undef ROW
+}
+
+template <typename ByteArray>
+void tst_QByteArrayApiSymmetry::sliced_impl()
+{
+ QFETCH(const QByteArray, ba);
+ QFETCH(const int, pos);
+ QFETCH(const int, n);
+ QFETCH(const QByteArray, result1);
+ QFETCH(const QByteArray, result2);
+
+ const ByteArray b(ba);
+ {
+ const auto sliced1 = b.sliced(pos);
+ const auto sliced2 = b.sliced(pos, n);
+
+ QCOMPARE(sliced1, result1);
+ QCOMPARE(sliced1.isNull(), result1.isNull());
+ QCOMPARE(sliced1.isEmpty(), result1.isEmpty());
+
+ QCOMPARE(sliced2, result2);
+ QCOMPARE(sliced2.isNull(), result2.isNull());
+ QCOMPARE(sliced2.isEmpty(), result2.isEmpty());
+ }
+
+ {
+ const auto sliced1 = detached(b).sliced(pos);
+ const auto sliced2 = detached(b).sliced(pos, n);
+
+ QCOMPARE(sliced1, result1);
+ QCOMPARE(sliced1.isNull(), result1.isNull());
+ QCOMPARE(sliced1.isEmpty(), result1.isEmpty());
+
+ QCOMPARE(sliced2, result2);
+ QCOMPARE(sliced2.isNull(), result2.isNull());
+ QCOMPARE(sliced2.isEmpty(), result2.isEmpty());
+ }
+}
+
+void tst_QByteArrayApiSymmetry::first_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::addRow("empty") << empty << 0 << empty;
+
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << base << n << res
+
+ ROW(a, 0, empty);
+ ROW(a, 1, a);
+
+ ROW(ab, 0, empty);
+ ROW(ab, 1, a);
+ ROW(ab, 2, ab);
+
+ ROW(abc, 0, empty);
+ ROW(abc, 1, a);
+ ROW(abc, 2, ab);
+ ROW(abc, 3, abc);
+#undef ROW
+}
+
+template <typename ByteArray>
+void tst_QByteArrayApiSymmetry::first_impl()
+{
+ QFETCH(const QByteArray, ba);
+ QFETCH(const int, n);
+ QFETCH(const QByteArray, result);
+
+ const ByteArray b(ba);
+ {
+ const auto first = b.first(n);
+
+ QCOMPARE(first, result);
+ QCOMPARE(first.isNull(), result.isNull());
+ QCOMPARE(first.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto first = detached(b).first(n);
+
+ QCOMPARE(first, result);
+ QCOMPARE(first.isNull(), result.isNull());
+ QCOMPARE(first.isEmpty(), result.isEmpty());
+ }
+ {
+ auto first = b;
+ first.truncate(n);
+
+ QCOMPARE(first, result);
+ QCOMPARE(first.isNull(), result.isNull());
+ QCOMPARE(first.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QByteArrayApiSymmetry::last_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::addRow("empty") << empty << 0 << empty;
+
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << base << n << res
+
+ ROW(a, 0, empty);
+ ROW(a, 1, a);
+
+ ROW(ab, 0, empty);
+ ROW(ab, 1, b);
+ ROW(ab, 2, ab);
+
+ ROW(abc, 0, empty);
+ ROW(abc, 1, c);
+ ROW(abc, 2, bc);
+ ROW(abc, 3, abc);
+#undef ROW
+}
+
+template <typename ByteArray>
+void tst_QByteArrayApiSymmetry::last_impl()
+{
+ QFETCH(const QByteArray, ba);
+ QFETCH(const int, n);
+ QFETCH(const QByteArray, result);
+
+ const ByteArray b(ba);
+
+ {
+ const auto last = b.last(n);
+
+ QCOMPARE(last, result);
+ QCOMPARE(last.isNull(), result.isNull());
+ QCOMPARE(last.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto last = detached(b).last(n);
+
+ QCOMPARE(last, result);
+ QCOMPARE(last.isNull(), result.isNull());
+ QCOMPARE(last.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QByteArrayApiSymmetry::chop_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::addRow("empty") << empty << 0 << empty;
+
+ // Some classes' truncate() implementations have a wide contract, others a narrow one
+ // so only test valid arguents here:
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << base << n << res
+
+ ROW(a, 0, a);
+ ROW(a, 1, empty);
+
+ ROW(ab, 0, ab);
+ ROW(ab, 1, a);
+ ROW(ab, 2, empty);
+
+ ROW(abc, 0, abc);
+ ROW(abc, 1, ab);
+ ROW(abc, 2, a);
+ ROW(abc, 3, empty);
+#undef ROW
+}
+
+template <typename ByteArray>
+void tst_QByteArrayApiSymmetry::chop_impl()
+{
+ QFETCH(const QByteArray, ba);
+ QFETCH(const int, n);
+ QFETCH(const QByteArray, result);
+
+ const ByteArray b(ba);
+
+ {
+ const auto chopped = b.chopped(n);
+
+ QCOMPARE(chopped, result);
+ QCOMPARE(chopped.isNull(), result.isNull());
+ QCOMPARE(chopped.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto chopped = detached(b).chopped(n);
+
+ QCOMPARE(chopped, result);
+ QCOMPARE(chopped.isNull(), result.isNull());
+ QCOMPARE(chopped.isEmpty(), result.isEmpty());
+ }
+ {
+ auto chopped = b;
+ chopped.chop(n);
+
+ QCOMPARE(chopped, result);
+ QCOMPARE(chopped.isNull(), result.isNull());
+ QCOMPARE(chopped.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QByteArrayApiSymmetry::trimmed_data()
+{
+ QTest::addColumn<QByteArray>("source");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("null") << QByteArray() << QByteArray();
+ QTest::newRow("empty") << QByteArray("") << QByteArray("");
+ QTest::newRow("no end-spaces") << QByteArray("a b\nc\td") << QByteArray("a b\nc\td");
+ QTest::newRow("with end-spaces")
+ << QByteArray("\t \v a b\r\nc \td\ve f \r\n\f") << QByteArray("a b\r\nc \td\ve f");
+ QTest::newRow("all spaces") << QByteArray("\t \r \n \v \f") << QByteArray("");
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::trimmed_impl()
+{
+ QFETCH(QByteArray, source);
+ QFETCH(QByteArray, expected);
+
+ QCOMPARE(ByteArray(source).trimmed(), ByteArray(expected));
+ ByteArray copy{source};
+ QCOMPARE(std::move(copy).trimmed(), ByteArray(expected));
+
+ if constexpr (std::is_same_v<QByteArray, ByteArray>) {
+ if (source.isEmpty())
+ QVERIFY(!source.isDetached());
+ }
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toShort() const
+{
+ bool ok = true; // opposite to the first expected result
+
+ QCOMPARE(ByteArray().toShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("").toShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("12345").toShort(&ok), 12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-12345").toShort(&ok), -12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-12345 and a bit", 5).toShort(&ok), -1234);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-12345 and a bit").sliced(1, 4).toShort(&ok), 1234);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-012345 and a bit", 2).toShort(&ok), 0);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-12345 and a bit", 6).toShort(&ok), -12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-12345 and a bit", 7).toShort(&ok), -12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("12345 and a bit", 10).toShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("32767").toShort(&ok), 32767);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("-32768").toShort(&ok), -32768);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("32768").toShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("-32769").toShort(&ok), 0);
+ QVERIFY(!ok);
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toUShort() const
+{
+ bool ok = true; // opposite to the first expected result
+
+ QCOMPARE(ByteArray().toUShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("").toUShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("12345").toUShort(&ok), 12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("12345 and a bit", 4).toUShort(&ok), 1234);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("012345 and a bit").sliced(1, 4).toUShort(&ok), 1234);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("012345 and a bit", 1).toUShort(&ok), 0);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("12345 and a bit", 5).toUShort(&ok), 12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("12345 and a bit", 6).toUShort(&ok), 12345);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("12345 and a bit", 10).toUShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("-12345").toUShort(&ok), 0);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("32767").toUShort(&ok), 32767);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("32768").toUShort(&ok), 32768);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("65535").toUShort(&ok), 65535);
+ QVERIFY(ok);
+
+ QCOMPARE(ByteArray("65536").toUShort(&ok), 0);
+ QVERIFY(!ok);
+}
+
+// defined later
+extern const char globalChar;
+
+void tst_QByteArrayApiSymmetry::toInt_data() const
+{
+ QTest::addColumn<QByteArray>("string");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<int>("expectednumber");
+ QTest::addColumn<bool>("expectedok");
+
+ QTest::newRow("null") << QByteArray() << 10 << 0 << false;
+ QTest::newRow("empty") << QByteArray("") << 10 << 0 << false;
+
+ QTest::newRow("base 10") << QByteArray("100") << 10 << 100 << true;
+ QTest::newRow("base 16-1") << QByteArray("100") << 16 << 256 << true;
+ QTest::newRow("base 16-2") << QByteArray("0400") << 16 << 1024 << true;
+ QTest::newRow("base 2") << QByteArray("1111") << 2 << 15 << true;
+ QTest::newRow("base 8") << QByteArray("100") << 8 << 64 << true;
+ QTest::newRow("base 0-1") << QByteArray("0x10") << 0 << 16 << true;
+ QTest::newRow("base 0-2") << QByteArray("10") << 0 << 10 << true;
+ QTest::newRow("base 0-3") << QByteArray("010") << 0 << 8 << true;
+ QTest::newRow("base 0 empty") << QByteArray() << 0 << 0 << false;
+
+ QTest::newRow("leading space") << QByteArray(" 100") << 10 << 100 << true;
+ QTest::newRow("trailing space") << QByteArray("100 ") << 10 << 100 << true;
+ QTest::newRow("leading junk") << QByteArray("x100") << 10 << 0 << false;
+ QTest::newRow("trailing junk") << QByteArray("100x") << 10 << 0 << false;
+
+ // using fromRawData
+ QTest::newRow("raw1") << QByteArray::fromRawData("1", 1) << 10 << 1 << true;
+ QTest::newRow("raw2") << QByteArray::fromRawData("1foo", 1) << 10 << 1 << true;
+ QTest::newRow("raw3") << QByteArray::fromRawData("12", 1) << 10 << 1 << true;
+ QTest::newRow("raw4") << QByteArray::fromRawData("123456789", 1) << 10 << 1 << true;
+ QTest::newRow("raw5") << QByteArray::fromRawData("123456789", 2) << 10 << 12 << true;
+
+ QTest::newRow("raw-static") << QByteArray::fromRawData(&globalChar, 1) << 10 << 1 << true;
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toInt() const
+{
+ QFETCH(QByteArray, string);
+ QFETCH(int, base);
+ QFETCH(int, expectednumber);
+ QFETCH(bool, expectedok);
+
+ bool ok;
+ int number = ByteArray(string).toInt(&ok, base);
+
+ QCOMPARE(ok, expectedok);
+ QCOMPARE(number, expectednumber);
+}
+
+void tst_QByteArrayApiSymmetry::toUInt_data() const
+{
+ QTest::addColumn<QByteArray>("string");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<uint>("expectednumber");
+ QTest::addColumn<bool>("expectedok");
+
+ QTest::newRow("null") << QByteArray() << 10 << 0u << false;
+ QTest::newRow("empty") << QByteArray("") << 10 << 0u << false;
+
+ QTest::newRow("negative value") << QByteArray("-50") << 10 << 0u << false;
+ QTest::newRow("more than MAX_INT") << QByteArray("3234567890") << 10 << 3234567890u << true;
+ QTest::newRow("2^32 - 1") << QByteArray("4294967295") << 10 << 4294967295u << true;
+ if constexpr (sizeof(int) > 4)
+ QTest::newRow("2^32") << QByteArray("4294967296") << 10 << (1u << 32) << true;
+ else
+ QTest::newRow("2^32") << QByteArray("4294967296") << 10 << 0u << false;
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toUInt() const
+{
+ QFETCH(QByteArray, string);
+ QFETCH(int, base);
+ QFETCH(uint, expectednumber);
+ QFETCH(bool, expectedok);
+
+ bool ok;
+ const uint number = ByteArray(string).toUInt(&ok, base);
+
+ QCOMPARE(ok, expectedok);
+ QCOMPARE(number, expectednumber);
+}
+
+void tst_QByteArrayApiSymmetry::toLong_data() const
+{
+ QTest::addColumn<QByteArray>("str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<long>("result");
+ QTest::addColumn<bool>("ok");
+
+ QTest::newRow("null") << QByteArray() << 10 << 0L << false;
+ QTest::newRow("empty") << QByteArray("") << 16 << 0L << false;
+ QTest::newRow("in range dec") << QByteArray("1608507359") << 10 << 1608507359L << true;
+ QTest::newRow("in range dec neg") << QByteArray("-1608507359") << 10 << -1608507359L << true;
+ QTest::newRow("in range hex") << QByteArray("12ABCDEF") << 16 << 0x12ABCDEFL << true;
+ QTest::newRow("in range hex neg") << QByteArray("-12ABCDEF") << 16 << -0x12ABCDEFL << true;
+ QTest::newRow("Fibonacci's last int32")
+ << QByteArray("1836311903") << 10 << 1836311903L << true;
+
+ QTest::newRow("leading spaces") << QByteArray(" \r\n\tABC123") << 16 << 0xABC123L << true;
+ QTest::newRow("trailing spaces") << QByteArray("1234567\t\r \n") << 10 << 1234567L << true;
+ QTest::newRow("leading junk") << QByteArray("q12345") << 10 << 0L << false;
+ QTest::newRow("trailing junk") << QByteArray("abc12345t") << 16 << 0L << false;
+
+ QTest::newRow("dec with base 0") << QByteArray("123") << 0 << 123L << true;
+ QTest::newRow("neg dec with base 0") << QByteArray("-123") << 0 << -123L << true;
+ QTest::newRow("hex with base 0") << QByteArray("0x123") << 0 << 0x123L << true;
+ QTest::newRow("neg hex with base 0") << QByteArray("-0x123") << 0 << -0x123L << true;
+ QTest::newRow("oct with base 0") << QByteArray("0123") << 0 << 0123L << true;
+ QTest::newRow("neg oct with base 0") << QByteArray("-0123") << 0 << -0123L << true;
+
+ QTest::newRow("base 3") << QByteArray("12012") << 3 << 140L << true;
+ QTest::newRow("neg base 3") << QByteArray("-201") << 3 << -19L << true;
+
+ using Bounds = std::numeric_limits<long>;
+ QTest::newRow("long max") << QByteArray::number(Bounds::max()) << 10 << Bounds::max() << true;
+ QTest::newRow("long min") << QByteArray::number(Bounds::min()) << 10 << Bounds::min() << true;
+
+ using B32 = std::numeric_limits<qint32>;
+ QTest::newRow("int32 min bin")
+ << (QByteArray("-1") + QByteArray(31, '0')) << 2 << long(B32::min()) << true;
+ QTest::newRow("int32 max bin") << QByteArray(31, '1') << 2 << long(B32::max()) << true;
+ QTest::newRow("int32 min hex") << QByteArray("-80000000") << 16 << long(B32::min()) << true;
+ QTest::newRow("int32 max hex") << QByteArray("7fffffff") << 16 << long(B32::max()) << true;
+ QTest::newRow("int32 min dec") << QByteArray("-2147483648") << 10 << long(B32::min()) << true;
+ QTest::newRow("int32 max dec") << QByteArray("2147483647") << 10 << long(B32::max()) << true;
+
+ if constexpr (sizeof(long) < sizeof(qlonglong)) {
+ QT_WARNING_PUSH
+ // See: https://github.com/llvm/llvm-project/issues/59448
+ QT_WARNING_DISABLE_CLANG("-Winteger-overflow")
+ const qlonglong longMaxPlusOne = static_cast<qlonglong>(Bounds::max()) + 1;
+ const qlonglong longMinMinusOne = static_cast<qlonglong>(Bounds::min()) - 1;
+ QT_WARNING_POP
+
+ QTest::newRow("long max + 1") << QByteArray::number(longMaxPlusOne) << 10 << 0L << false;
+ QTest::newRow("long min - 1") << QByteArray::number(longMinMinusOne) << 10 << 0L << false;
+ }
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toLong() const
+{
+ QFETCH(QByteArray, str);
+ QFETCH(int, base);
+ QFETCH(long, result);
+ QFETCH(bool, ok);
+
+ bool good;
+ QCOMPARE(ByteArray(str).toLong(nullptr, base), result);
+ QCOMPARE(ByteArray(str).toLong(&good, base), result);
+ QCOMPARE(good, ok);
+ if (base == 10) {
+ // check that by default base is assumed to be 10
+ QCOMPARE(ByteArray(str).toLong(&good), result);
+ QCOMPARE(good, ok);
+ }
+}
+
+void tst_QByteArrayApiSymmetry::toULong_data() const
+{
+ QTest::addColumn<QByteArray>("str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<ulong>("result");
+ QTest::addColumn<bool>("ok");
+
+ ulong LongMaxPlusOne = (ulong)LONG_MAX + 1;
+ QTest::newRow("LONG_MAX+1")
+ << QString::number(LongMaxPlusOne).toUtf8() << 10 << LongMaxPlusOne << true;
+ QTest::newRow("null") << QByteArray() << 10 << 0UL << false;
+ QTest::newRow("empty") << QByteArray("") << 10 << 0UL << false;
+ QTest::newRow("ulong1") << QByteArray("3234567890") << 10 << 3234567890UL << true;
+ QTest::newRow("ulong2") << QByteArray("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true;
+
+ QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << 100UL << true;
+ QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << 100UL << true;
+ QTest::newRow("leading junk") << QByteArray("x100") << 10 << 0UL << false;
+ QTest::newRow("trailing junk") << QByteArray("100x") << 10 << 0UL << false;
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toULong() const
+{
+ QFETCH(QByteArray, str);
+ QFETCH(int, base);
+ QFETCH(ulong, result);
+ QFETCH(bool, ok);
+
+ bool good;
+ QCOMPARE(ByteArray(str).toULong(0, base), result);
+ QCOMPARE(ByteArray(str).toULong(&good, base), result);
+ QCOMPARE(good, ok);
+}
+
+static QByteArray decNext(QByteArray &&big)
+{
+ // Increments a decimal digit-string (ignoring sign, so decrements if
+ // negative); only intended for taking a boundary value just out of range,
+ // so big is never a string of only 9s (that'd be one less than a power of
+ // ten, which cannot be a power of two, as odd, or one less than one, as the
+ // power of ten isn't a power of two).
+ int i = big.size() - 1;
+ while (big.at(i) == '9')
+ big[i--] = '0';
+ big[i] += 1;
+ return std::move(big);
+}
+
+void tst_QByteArrayApiSymmetry::toLongLong_data() const
+{
+ QTest::addColumn<QByteArray>("str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<qlonglong>("result");
+ QTest::addColumn<bool>("ok");
+
+ QTest::newRow("null") << QByteArray() << 10 << 0LL << false;
+ QTest::newRow("empty") << QByteArray("") << 10 << 0LL << false;
+ QTest::newRow("out of base bound") << QByteArray("c") << 10 << 0LL << false;
+
+ QTest::newRow("in range dec")
+ << QByteArray("7679359922672374856") << 10 << 7679359922672374856LL << true;
+ QTest::newRow("in range dec neg")
+ << QByteArray("-7679359922672374856") << 10 << -7679359922672374856LL << true;
+ QTest::newRow("in range hex")
+ << QByteArray("6A929129A5421448") << 16 << 0x6A929129A5421448LL << true;
+ QTest::newRow("in range hex prefix")
+ << QByteArray("0x6A929129A5421448") << 16 << 0x6A929129A5421448LL << true;
+ QTest::newRow("in range hex neg")
+ << QByteArray("-6A929129A5421448") << 16 << -0x6A929129A5421448LL << true;
+ QTest::newRow("in range hex prefix neg")
+ << QByteArray("-0x6A929129A5421448") << 16 << -0x6A929129A5421448LL << true;
+ QTest::newRow("Fibonacci's last int64")
+ << QByteArray("7540113804746346429") << 10 << 7540113804746346429LL << true;
+
+ QTest::newRow("leading spaces")
+ << QByteArray(" \r\n\tABCFFFFFFF123") << 16 << 0xABCFFFFFFF123LL << true;
+ QTest::newRow("trailing spaces")
+ << QByteArray("9876543210\t\r \n") << 10 << 9876543210LL << true;
+ QTest::newRow("space after plus") << QByteArray("+ 12") << 10 << 0LL << false;
+ QTest::newRow("space after minus") << QByteArray("- 12") << 10 << 0LL << false;
+ QTest::newRow("leading junk") << QByteArray("q12345") << 10 << 0LL << false;
+ QTest::newRow("trailing junk") << QByteArray("abc12345t") << 16 << 0LL << false;
+
+ QTest::newRow("dec with base 0") << QByteArray("9876543210") << 0 << 9876543210LL << true;
+ QTest::newRow("neg dec with base 0") << QByteArray("-9876543210") << 0 << -9876543210LL << true;
+ QTest::newRow("hex with base 0") << QByteArray("0x9876543210") << 0 << 0x9876543210LL << true;
+ QTest::newRow("neg hex with base 0")
+ << QByteArray("-0x9876543210") << 0 << -0x9876543210LL << true;
+ QTest::newRow("oct with base 0")
+ << QByteArray("07654321234567") << 0 << 07654321234567LL << true;
+ QTest::newRow("neg oct with base 0")
+ << QByteArray("-07654321234567") << 0 << -07654321234567LL << true;
+
+ QTest::newRow("base 3") << QByteArray("12012") << 3 << 140LL << true;
+ QTest::newRow("neg base 3") << QByteArray("-201") << 3 << -19LL << true;
+
+ // Boundary values, first in every base:
+ using LL = std::numeric_limits<qlonglong>;
+ for (int b = 0; b <= 36; ++b) {
+ if (b == 1) // bases 0 and 2 through 36 are allowed
+ ++b;
+ QTest::addRow("max base %d", b)
+ << QByteArray::number(LL::max(), b ? b : 10) << b << LL::max() << true;
+ QTest::addRow("min base %d", b)
+ << QByteArray::number(LL::min(), b ? b : 10) << b << LL::min() << true;
+ }
+ // Check leading zeros don't hit any buffer-too-big problems:
+ QTest::newRow("many-0 max dec")
+ << (QByteArray(512, '0') + QByteArray::number(LL::max())) << 10 << LL::max() << true;
+
+ // Special bases (and let's include some leading space, too !), first decimal:
+ QTest::newRow("max space dec")
+ << ("\t\r\n\f\v " + QByteArray::number(LL::max())) << 10 << LL::max() << true;
+ QTest::newRow("max space dec, base 0")
+ << ("\t\r\n\f\v " + QByteArray::number(LL::max())) << 0 << LL::max() << true;
+ QTest::newRow("min space dec")
+ << ("\t\r\n\f\v " + QByteArray::number(LL::min())) << 10 << LL::min() << true;
+ QTest::newRow("min space dec, base 0")
+ << ("\t\r\n\f\v " + QByteArray::number(LL::min())) << 0 << LL::min() << true;
+
+ // Hex with prefix:
+ QTest::newRow("max 0x base 0")
+ << ("0x" + QByteArray::number(LL::max(), 16)) << 0 << LL::max() << true;
+ QTest::newRow("max +0x base 0")
+ << ("+0x" + QByteArray::number(LL::max(), 16)) << 0 << LL::max() << true;
+ QTest::newRow("max space 0x base 0")
+ << ("\t\r\n\f\v 0x" + QByteArray::number(LL::max(), 16)) << 0 << LL::max() << true;
+ QTest::newRow("max space +0x base 0")
+ << ("\t\r\n\f\v +0x" + QByteArray::number(LL::max(), 16)) << 0 << LL::max() << true;
+ QByteArray big = QByteArray::number(LL::min(), 16);
+ big.insert(1, "0x"); // after sign
+ QTest::newRow("min hex prefix") << big << 16 << LL::min() << true;
+ QTest::newRow("min 0x base 0") << big << 0 << LL::min() << true;
+ big.prepend("\t\r\n\f\v ");
+ QTest::newRow("min space hex prefix") << big << 16 << LL::min() << true;
+ QTest::newRow("min space 0x base 0") << big << 0 << LL::min() << true;
+
+ // Octal with prefix:
+ QTest::newRow("max octal base 0")
+ << ('0' + QByteArray::number(LL::max(), 8)) << 0 << LL::max() << true;
+ QTest::newRow("max +octal base 0")
+ << ("+0" + QByteArray::number(LL::max(), 8)) << 0 << LL::max() << true;
+ QTest::newRow("max space octal base 0")
+ << ("\t\r\n\f\v 0" + QByteArray::number(LL::max(), 8)) << 0 << LL::max() << true;
+ QTest::newRow("max space +octal base 0")
+ << ("\t\r\n\f\v +0" + QByteArray::number(LL::max(), 8)) << 0 << LL::max() << true;
+ big = QByteArray::number(LL::min(), 8);
+ big.insert(1, '0'); // after sign
+ QTest::newRow("min octal prefix") << big << 8 << LL::min() << true;
+ QTest::newRow("min octal base 0") << big << 0 << LL::min() << true;
+ big.prepend("\t\r\n\f\v ");
+ QTest::newRow("min space octal prefix") << big << 8 << LL::min() << true;
+ QTest::newRow("min space octal base 0") << big << 0 << LL::min() << true;
+
+ // Values *just* out of range:
+ QTest::newRow("max + 1 dec") << decNext(QByteArray::number(LL::max())) << 10 << 0LL << false;
+ QTest::newRow("max + 1 dec base 0")
+ << decNext(QByteArray::number(LL::max())) << 0 << 0LL << false;
+ QTest::newRow("min - 1 dec") << decNext(QByteArray::number(LL::min())) << 10 << 0LL << false;
+ QTest::newRow("min - 1 dec base 0")
+ << decNext(QByteArray::number(LL::min())) << 0 << 0LL << false;
+ // For hex and octal, we know the last digit of min is 0 and skipping its sign gets max+1:
+ big = QByteArray::number(LL::min(), 8);
+ QTest::newRow("max + 1 oct") << big.sliced(1) << 8 << 0LL << false;
+ big[big.size() - 1] = '1';
+ QTest::newRow("min - 1 oct") << big << 8 << 0LL << false;
+ big.insert(1, '0'); // after minus sign
+ QTest::newRow("min - 1 octal base 0") << big << 0 << 0LL << false;
+ big = QByteArray::number(LL::min(), 16);
+ QTest::newRow("max + 1 hex") << big.sliced(1) << 16 << 0LL << false;
+ big[big.size() - 1] = '1';
+ QTest::newRow("min - 1 hex") << big << 16 << 0LL << false;
+ big.insert(1, "0x"); // after minus sign
+ QTest::newRow("min - 1, 0x base 0") << big << 0 << 0LL << false;
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toLongLong() const
+{
+ QFETCH(QByteArray, str);
+ QFETCH(int, base);
+ QFETCH(qlonglong, result);
+ QFETCH(bool, ok);
+
+ bool good;
+ QCOMPARE(ByteArray(str).toLongLong(nullptr, base), result);
+ QCOMPARE(ByteArray(str).toLongLong(&good, base), result);
+ QCOMPARE(good, ok);
+ if (base == 10) {
+ QCOMPARE(ByteArray(str).toLongLong(&good), result);
+ QCOMPARE(good, ok);
+ }
+}
+
+void tst_QByteArrayApiSymmetry::toULongLong_data() const
+{
+ QTest::addColumn<QByteArray>("str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<qulonglong>("result");
+ QTest::addColumn<bool>("ok");
+
+ QTest::newRow("null") << QByteArray() << 10 << 0ULL << false;
+ QTest::newRow("empty") << QByteArray("") << 10 << 0ULL << false;
+ QTest::newRow("out of base bound") << QByteArray("c") << 10 << 0ULL << false;
+
+ QTest::newRow("in range dec")
+ << QByteArray("7679359922672374856") << 10 << 7679359922672374856ULL << true;
+ QTest::newRow("in range hex")
+ << QByteArray("6A929129A5421448") << 16 << 0x6A929129A5421448ULL << true;
+ QTest::newRow("in range hex prefix")
+ << QByteArray("0x6A929129A5421448") << 16 << 0x6A929129A5421448ULL << true;
+
+ QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << 100ULL << true;
+ QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << 100ULL << true;
+ QTest::newRow("leading plus") << QByteArray("+100") << 10 << 100ULL << true;
+ QTest::newRow("space after plus") << QByteArray("+ 12") << 10 << 0ULL << false;
+ QTest::newRow("leading minus") << QByteArray("-100") << 10 << 0ULL << false;
+ QTest::newRow("leading junk") << QByteArray("x100") << 10 << 0ULL << false;
+ QTest::newRow("trailing junk") << QByteArray("100x") << 10 << 0ULL << false;
+
+ QTest::newRow("dec, base 0") << QByteArray("9876543210") << 0 << 9876543210ULL << true;
+ QTest::newRow("hex, base 0") << QByteArray("0x9876543210") << 0 << 0x9876543210ULL << true;
+ QTest::newRow("oct, base 0") << QByteArray("07654321234567") << 0 << 07654321234567ULL << true;
+ QTest::newRow("base 3") << QByteArray("12012") << 3 << 140ULL << true;
+
+ // Boundary values, first in every base:
+ using ULL = std::numeric_limits<qulonglong>;
+ for (int b = 0; b <= 36; ++b) {
+ if (b == 1) // bases 0 and 2 through 36 are allowed
+ ++b;
+ QTest::addRow("max base %d", b)
+ << QByteArray::number(ULL::max(), b ? b : 10) << b << ULL::max() << true;
+ }
+ // Check leading zeros don't hit any buffer-too-big problems:
+ QTest::newRow("many-0 max dec")
+ << (QByteArray(512, '0') + QByteArray::number(ULL::max())) << 10 << ULL::max() << true;
+
+ // Special bases (and let's include some leading space, too !), first decimal:
+ QTest::newRow("max space dec")
+ << ("\t\r\n\f\v " + QByteArray::number(ULL::max())) << 10 << ULL::max() << true;
+ QTest::newRow("max space dec, base 0")
+ << ("\t\r\n\f\v " + QByteArray::number(ULL::max())) << 0 << ULL::max() << true;
+
+ // Hex with prefix:
+ QTest::newRow("max 0x base 0")
+ << ("0x" + QByteArray::number(ULL::max(), 16)) << 0 << ULL::max() << true;
+ QTest::newRow("max +0x base 0")
+ << ("+0x" + QByteArray::number(ULL::max(), 16)) << 0 << ULL::max() << true;
+ QTest::newRow("max space 0x base 0")
+ << ("\t\r\n\f\v 0x" + QByteArray::number(ULL::max(), 16)) << 0 << ULL::max() << true;
+ QTest::newRow("max space +0x base 0")
+ << ("\t\r\n\f\v +0x" + QByteArray::number(ULL::max(), 16)) << 0 << ULL::max() << true;
+
+ // Octal with prefix:
+ QTest::newRow("max octal base 0")
+ << ('0' + QByteArray::number(ULL::max(), 8)) << 0 << ULL::max() << true;
+ QTest::newRow("max +octal base 0")
+ << ("+0" + QByteArray::number(ULL::max(), 8)) << 0 << ULL::max() << true;
+ QTest::newRow("max space octal base 0")
+ << ("\t\r\n\f\v 0" + QByteArray::number(ULL::max(), 8)) << 0 << ULL::max() << true;
+ QTest::newRow("max space +octal base 0")
+ << ("\t\r\n\f\v +0" + QByteArray::number(ULL::max(), 8)) << 0 << ULL::max() << true;
+
+ // Values *just* out of range:
+ QTest::newRow("max + 1 dec") << decNext(QByteArray::number(ULL::max())) << 10 << 0ULL << false;
+ QTest::newRow("max + 1 dec base 0")
+ << decNext(QByteArray::number(ULL::max())) << 0 << 0ULL << false;
+ auto big = QByteArray::number(ULL::max(), 8).replace('7', '0');
+ // Number of bits is a power of two, so not a multiple of three; so (only)
+ // first digit of max wasn't 7:
+ big[0] += 1;
+ QTest::newRow("max + 1 oct") << big << 8 << 0ULL << false;
+ // Number of bits is a multiple of four, so every digit of max is 'f'.
+ big = '1' + QByteArray::number(ULL::max(), 16).replace('f', '0');
+ QTest::newRow("max + 1 hex") << big << 16 << 0ULL << false;
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toULongLong() const
+{
+ QFETCH(QByteArray, str);
+ QFETCH(int, base);
+ QFETCH(qulonglong, result);
+ QFETCH(bool, ok);
+
+ bool good;
+ QCOMPARE(ByteArray(str).toULongLong(0, base), result);
+ QCOMPARE(ByteArray(str).toULongLong(&good, base), result);
+ QCOMPARE(good, ok);
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toFloat() const
+{
+ bool ok = true; // opposite to the next expected result
+
+ QCOMPARE(ByteArray().toFloat(&ok), 0.0f);
+ QVERIFY(!ok);
+
+ QCOMPARE(ByteArray("").toFloat(&ok), 0.0f);
+ QVERIFY(!ok);
+
+ // NB: floats < 1e-6 are zero as far as QCOMPARE() is concerned !
+ const char data[] = "0.0000931322574615478515625";
+ const float expectedValue = 9.31322574615478515625e-5f;
+ QCOMPARE(ByteArray(data).toFloat(&ok), expectedValue);
+ QVERIFY(ok);
+ QCOMPARE(ByteArray(data, 6).toFloat(&ok), 0.0f);
+ QVERIFY(ok);
+
+ const char crufty[] = "3.14 and a bit";
+ QCOMPARE(ByteArray(crufty).toFloat(&ok), 0.0f);
+ QVERIFY(!ok);
+ QCOMPARE(ByteArray(crufty, 4).toFloat(&ok), 3.14f);
+ QVERIFY(ok);
+}
+
+void tst_QByteArrayApiSymmetry::toDouble_data() const
+{
+ QTest::addColumn<QByteArray>("string");
+ QTest::addColumn<double>("expectedNumber");
+ QTest::addColumn<bool>("expectedOk");
+
+ QTest::newRow("null") << QByteArray() << 0.0 << false;
+ QTest::newRow("empty") << QByteArray("") << 0.0 << false;
+
+ QTest::newRow("decimal") << QByteArray("1.2345") << 1.2345 << true;
+ QTest::newRow("exponent lowercase") << QByteArray("1.2345e+01") << 12.345 << true;
+ QTest::newRow("exponent uppercase") << QByteArray("1.2345E+02") << 123.45 << true;
+ QTest::newRow("leading spaces") << QByteArray(" \n\r\t1.2345") << 1.2345 << true;
+ QTest::newRow("trailing spaces") << QByteArray("1.2345 \n\r\t") << 1.2345 << true;
+ QTest::newRow("leading junk") << QByteArray("x1.2345") << 0.0 << false;
+ QTest::newRow("trailing junk") << QByteArray("1.2345x") << 0.0 << false;
+ QTest::newRow("high precision")
+ << QByteArray("0.000000000931322574615478515625") << 9.31322574615478515625e-10 << true;
+ QTest::newRow("exponential")
+ << QByteArray("9.31322574615478515625e-10") << 9.31322574615478515625e-10 << true;
+
+ QTest::newRow("raw, null plus junk")
+ << QByteArray::fromRawData("1.2\0 junk", 9) << 0.0 << false;
+ QTest::newRow("raw, null-terminator excluded")
+ << QByteArray::fromRawData("2.3", 3) << 2.3 << true;
+}
+
+template <typename ByteArray> void tst_QByteArrayApiSymmetry::toDouble() const
+{
+ QFETCH(QByteArray, string);
+ QFETCH(double, expectedNumber);
+ QFETCH(bool, expectedOk);
+
+ bool ok;
+ const double number = ByteArray(string).toDouble(&ok);
+
+ QCOMPARE(ok, expectedOk);
+ QCOMPARE(number, expectedNumber);
+}
+
+const char globalChar = '1'; // Used as staic data for a raw byte array
+
+QTEST_APPLESS_MAIN(tst_QByteArrayApiSymmetry)
+#include "tst_qbytearrayapisymmetry.moc"
diff --git a/tests/auto/corelib/text/qbytearraylist/CMakeLists.txt b/tests/auto/corelib/text/qbytearraylist/CMakeLists.txt
new file mode 100644
index 0000000000..ffd8f4f280
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearraylist/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbytearraylist Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytearraylist LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbytearraylist
+ SOURCES
+ tst_qbytearraylist.cpp
+)
diff --git a/tests/auto/corelib/text/qbytearraylist/tst_qbytearraylist.cpp b/tests/auto/corelib/text/qbytearraylist/tst_qbytearraylist.cpp
new file mode 100644
index 0000000000..f82f07df88
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearraylist/tst_qbytearraylist.cpp
@@ -0,0 +1,304 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2014 by Southwest Research Institute (R)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#define QT_USE_QSTRINGBUILDER
+
+#include <QTest>
+#include <qbytearraylist.h>
+
+#include <qmetatype.h>
+#include <qproperty.h>
+
+Q_DECLARE_METATYPE(QByteArrayList)
+
+class tst_QByteArrayList : public QObject
+{
+ Q_OBJECT
+private slots:
+ void join_overloads() const;
+ void join() const;
+ void join_data() const;
+ void joinByteArray() const;
+ void joinByteArray_data() const;
+ void joinChar() const;
+ void joinChar_data() const;
+ void joinEmptiness() const;
+
+ void operator_plus() const;
+ void operator_plus_data() const;
+
+ void indexOf_data() const;
+ void indexOf() const;
+
+ void initializerList() const;
+};
+
+void tst_QByteArrayList::join_overloads() const
+{
+ // Checks that there are no ambiguities between the different join() overloads:
+
+ const QByteArrayList list = {"a", "b", "c"};
+ const QByteArray expected = "aXbXc";
+
+ QCOMPARE(list.join('X'), expected);
+ QCOMPARE(list.join("X"), expected);
+ QCOMPARE(list.join(QByteArrayLiteral("X")), expected);
+ QCOMPARE(list.join(QByteArray("X")), expected);
+ QCOMPARE(list.join(QByteArrayView("X")), expected);
+ const char *sep = "X";
+ QCOMPARE(list.join(sep), expected);
+ QCOMPARE(list.join(QByteArray() % "X"), expected); // QStringBuilder expression
+ QProperty<QByteArray> prop("X"); // implicitly convertible to QByteArray
+ QCOMPARE(list.join(prop), expected);
+ QCOMPARE(list.join(std::as_const(prop)), expected);
+}
+
+void tst_QByteArrayList::join() const
+{
+ QFETCH(QByteArrayList, input);
+ QFETCH(QByteArray, expectedResult);
+
+ QCOMPARE(input.join(), expectedResult);
+ QCOMPARE(input.join(QByteArrayView{}), expectedResult);
+ QCOMPARE(input.join(QByteArray{}), expectedResult);
+}
+
+void tst_QByteArrayList::join_data() const
+{
+ QTest::addColumn<QByteArrayList>("input");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+ QTest::newRow("data1") << QByteArrayList()
+ << QByteArray();
+
+ QTest::newRow("data2") << (QByteArrayList() << "one")
+ << QByteArray("one");
+
+ QTest::newRow("data3") << (QByteArrayList() << "a" << "b")
+ << QByteArray("ab");
+
+ QTest::newRow("data4") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray("abc");
+}
+
+void tst_QByteArrayList::joinByteArray() const
+{
+ QFETCH(QByteArrayList, input);
+ QFETCH(QByteArray, separator);
+ QFETCH(QByteArray, expectedResult);
+
+ QCOMPARE(input.join(separator), expectedResult);
+ QCOMPARE(input.join(QByteArrayView{separator}), expectedResult);
+}
+
+void tst_QByteArrayList::joinByteArray_data() const
+{
+ QTest::addColumn<QByteArrayList>("input");
+ QTest::addColumn<QByteArray>("separator");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+ QTest::newRow("data1") << QByteArrayList()
+ << QByteArray()
+ << QByteArray();
+
+ QTest::newRow("data2") << QByteArrayList()
+ << QByteArray("separator")
+ << QByteArray();
+
+ QTest::newRow("data3") << (QByteArrayList() << "one")
+ << QByteArray("separator")
+ << QByteArray("one");
+
+ QTest::newRow("data4") << (QByteArrayList() << "a" << "b")
+ << QByteArray(" ")
+ << QByteArray("a b");
+
+ QTest::newRow("data5") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray(" ")
+ << QByteArray("a b c");
+
+ QTest::newRow("data6") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray()
+ << QByteArray("abc");
+
+ QTest::newRow("data7") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray("") //empty
+ << QByteArray("abc");
+}
+
+void tst_QByteArrayList::joinChar() const
+{
+ QFETCH(QByteArrayList, input);
+ QFETCH(char, separator);
+ QFETCH(QByteArray, expectedResult);
+
+ QCOMPARE(input.join(separator), expectedResult);
+ QCOMPARE(input.join(QByteArrayView{&separator, 1}), expectedResult);
+}
+
+void tst_QByteArrayList::joinChar_data() const
+{
+ QTest::addColumn<QByteArrayList>("input");
+ QTest::addColumn<char>("separator");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+ QTest::newRow("data1") << QByteArrayList()
+ << ' '
+ << QByteArray();
+
+ QTest::newRow("data2") << (QByteArrayList() << "a a" << "b")
+ << ' '
+ << QByteArray("a a b");
+
+ QTest::newRow("data3") << (QByteArrayList() << "a" << "b" << "c c")
+ << ' '
+ << QByteArray("a b c c");
+}
+
+void tst_QByteArrayList::joinEmptiness() const
+{
+ QByteArrayList list;
+ QByteArray string = list.join(QByteArray());
+
+ QVERIFY(string.isEmpty());
+ QVERIFY(string.isNull());
+}
+
+void tst_QByteArrayList::operator_plus() const
+{
+ QFETCH(QByteArrayList, lhs);
+ QFETCH(QByteArrayList, rhs);
+ QFETCH(QByteArrayList, expectedResult);
+
+ // operator+ for const lvalues
+ {
+ const QByteArrayList bal1 = lhs;
+ const QByteArrayList bal2 = rhs;
+ QCOMPARE(bal1 + bal2, expectedResult);
+ }
+ {
+ const QList<QByteArray> lba1 = lhs;
+ const QByteArrayList bal2 = rhs;
+ QCOMPARE(lba1 + bal2, expectedResult);
+ }
+ {
+ const QByteArrayList bal1 = lhs;
+ const QList<QByteArray> lba2 = rhs;
+ QCOMPARE(bal1 + lba2, expectedResult);
+ }
+ {
+ const QList<QByteArray> lba1 = lhs;
+ const QList<QByteArray> lba2 = rhs;
+ QCOMPARE(lba1 + lba2, QList<QByteArray>(expectedResult)); // check we don't mess with old code
+ }
+
+ // operator+ for rvalues (only lhs)
+ {
+ QByteArrayList bal1 = lhs;
+ const QByteArrayList bal2 = rhs;
+ QCOMPARE(std::move(bal1) + bal2, expectedResult);
+ }
+ {
+ QList<QByteArray> lba1 = lhs;
+ const QByteArrayList bal2 = rhs;
+ QCOMPARE(std::move(lba1) + bal2, expectedResult);
+ }
+ {
+ QByteArrayList bal1 = lhs;
+ const QList<QByteArray> lba2 = rhs;
+ QCOMPARE(std::move(bal1) + lba2, expectedResult);
+ }
+ {
+ QList<QByteArray> lba1 = lhs;
+ const QList<QByteArray> lba2 = rhs;
+ QCOMPARE(std::move(lba1) + lba2, QList<QByteArray>(expectedResult)); // check we don't mess with old code
+ }
+
+ // operator += for const lvalues
+ {
+ QByteArrayList bal1 = lhs;
+ const QByteArrayList bal2 = rhs;
+ QCOMPARE(bal1 += bal2, expectedResult);
+ }
+ {
+ QByteArrayList bal1 = lhs;
+ const QList<QByteArray> lba2 = rhs;
+ QCOMPARE(bal1 += lba2, expectedResult);
+ }
+ {
+ QList<QByteArray> lba1 = lhs;
+ const QByteArrayList bal2 = rhs;
+ QCOMPARE(lba1 += bal2, QList<QByteArray>(expectedResult));
+ }
+
+ QByteArrayList t1 = lhs;
+ QByteArrayList t2 = rhs;
+
+ QCOMPARE(std::move(t1) + t2, expectedResult);
+}
+
+void tst_QByteArrayList::operator_plus_data() const
+{
+ QTest::addColumn<QByteArrayList>("lhs");
+ QTest::addColumn<QByteArrayList>("rhs");
+ QTest::addColumn<QByteArrayList>("expectedResult");
+
+ QTest::newRow("simpl") << ( QByteArrayList() << "a" )
+ << ( QByteArrayList() << "b" << "c" )
+ << ( QByteArrayList() << "a" << "b" << "c" );
+
+ QTest::newRow("blank1") << QByteArrayList()
+ << QByteArrayList()
+ << QByteArrayList();
+
+ QTest::newRow("blank2") << ( QByteArrayList() )
+ << ( QByteArrayList() << "b" << "c" )
+ << ( QByteArrayList() << "b" << "c" );
+
+ QTest::newRow("empty1") << ( QByteArrayList() << "" )
+ << ( QByteArrayList() << "b" << "c" )
+ << ( QByteArrayList() << "" << "b" << "c" );
+
+ QTest::newRow("empty2") << ( QByteArrayList() << "a" )
+ << ( QByteArrayList() << "" << "c" )
+ << ( QByteArrayList() << "a" << "" << "c" );
+}
+
+void tst_QByteArrayList::indexOf_data() const
+{
+ QTest::addColumn<QByteArrayList>("list");
+ QTest::addColumn<QByteArray>("item");
+ QTest::addColumn<int>("expectedResult");
+
+ QTest::newRow("empty") << QByteArrayList() << QByteArray("a") << -1;
+ QTest::newRow("found_1") << ( QByteArrayList() << "a" ) << QByteArray("a") << 0;
+ QTest::newRow("not_found_1") << ( QByteArrayList() << "a" ) << QByteArray("b") << -1;
+ QTest::newRow("found_2") << ( QByteArrayList() << "hello" << "world" ) << QByteArray("world") << 1;
+ QTest::newRow("returns_first") << ( QByteArrayList() << "hello" << "world" << "hello" << "again" ) << QByteArray("hello") << 0;
+}
+
+void tst_QByteArrayList::indexOf() const
+{
+ QFETCH(QByteArrayList, list);
+ QFETCH(QByteArray, item);
+ QFETCH(int, expectedResult);
+
+ QCOMPARE(list.indexOf(item), expectedResult);
+ QCOMPARE(list.indexOf(item.constData()), expectedResult);
+}
+
+void tst_QByteArrayList::initializerList() const
+{
+ // constructor
+ QByteArrayList v1 = {QByteArray("hello"),"world",QByteArray("plop")};
+ QCOMPARE(v1, (QByteArrayList() << "hello" << "world" << "plop"));
+ QCOMPARE(v1, (QByteArrayList{"hello","world","plop"}));
+ // assignment operator (through implicit temporary)
+ QByteArrayList v2;
+ v2 = {QByteArray("hello"),"world",QByteArray("plop")};
+ QCOMPARE(v2, v1);
+}
+
+QTEST_APPLESS_MAIN(tst_QByteArrayList)
+#include "tst_qbytearraylist.moc"
diff --git a/tests/auto/corelib/text/qbytearraymatcher/CMakeLists.txt b/tests/auto/corelib/text/qbytearraymatcher/CMakeLists.txt
new file mode 100644
index 0000000000..f500210f0f
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearraymatcher/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbytearraymatcher Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytearraymatcher LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbytearraymatcher
+ SOURCES
+ tst_qbytearraymatcher.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qbytearraymatcher/tst_qbytearraymatcher.cpp b/tests/auto/corelib/text/qbytearraymatcher/tst_qbytearraymatcher.cpp
new file mode 100644
index 0000000000..cb2ede7db6
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearraymatcher/tst_qbytearraymatcher.cpp
@@ -0,0 +1,291 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
+
+#include <qbytearraymatcher.h>
+
+#include <numeric>
+#include <string>
+
+#include <thread>
+
+// COM interface
+#if defined(Q_OS_WIN) && defined(interface)
+# undef interface
+#endif
+
+class tst_QByteArrayMatcher : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void overloads();
+ void interface();
+ void indexIn();
+ void staticByteArrayMatcher();
+ void haystacksWithMoreThan4GiBWork();
+};
+
+void tst_QByteArrayMatcher::overloads()
+{
+ QByteArray hello = QByteArrayLiteral("hello");
+ QByteArray hello2 = hello.repeated(2);
+ {
+ QByteArrayMatcher m("hello");
+ QCOMPARE(m.pattern(), "hello");
+ QCOMPARE(m.indexIn("hello"), 0);
+ }
+ {
+ QByteArrayMatcher m("hello", qsizetype(3));
+ QCOMPARE(m.pattern(), "hel");
+ QCOMPARE(m.indexIn("hellohello", qsizetype(2)), -1); // haystack is "he", not: from is 2
+ QCOMPARE(m.indexIn("hellohello", qsizetype(3)), 0); // haystack is "hel", not: from is 3
+ }
+ {
+ QByteArrayMatcher m(hello);
+ QCOMPARE(m.pattern(), "hello");
+ QCOMPARE(m.indexIn(hello), 0);
+ QCOMPARE(m.indexIn(hello2, qsizetype(1)), hello.size());
+ }
+ {
+ QStaticByteArrayMatcher m("hel");
+ QCOMPARE(m.pattern(), "hel");
+ QCOMPARE(m.indexIn("hello"), qsizetype(0));
+ QCOMPARE(m.indexIn("hellohello", qsizetype(2)), -1); // haystack is "he", not: from is 2
+ QCOMPARE(m.indexIn("hellohello", qsizetype(3)), 0); // haystack is "hel", not: from is 3
+ QCOMPARE(m.indexIn(hello), 0);
+ QCOMPARE(m.indexIn(hello2, qsizetype(2)), hello.size()); // from is 2
+ QCOMPARE(m.indexIn(hello2, qsizetype(3)), hello.size()); // from is 3
+ }
+}
+
+void tst_QByteArrayMatcher::interface()
+{
+ const char needle[] = "abc123";
+ QByteArray haystack(500, 'a');
+ haystack.insert(6, "123");
+ haystack.insert(31, "abc");
+ haystack.insert(42, "abc123");
+ haystack.insert(84, "abc123");
+
+ QByteArrayMatcher matcher1;
+
+ matcher1 = QByteArrayMatcher(QByteArray(needle));
+ QByteArrayMatcher matcher2;
+ matcher2.setPattern(QByteArray(needle));
+
+ QByteArrayMatcher matcher3 = QByteArrayMatcher(QByteArray(needle));
+ QByteArrayMatcher matcher4(needle, sizeof(needle) - 1);
+ QByteArrayMatcher matcher5(matcher2);
+ QByteArrayMatcher matcher6;
+ matcher6 = matcher3;
+
+ QCOMPARE(matcher1.indexIn(haystack), 42);
+ QCOMPARE(matcher2.indexIn(haystack), 42);
+ QCOMPARE(matcher3.indexIn(haystack), 42);
+ QCOMPARE(matcher4.indexIn(haystack), 42);
+ QCOMPARE(matcher5.indexIn(haystack), 42);
+ QCOMPARE(matcher6.indexIn(haystack), 42);
+
+ QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.size()), 42);
+
+ QCOMPARE(matcher1.indexIn(haystack, 43), 84);
+ QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.size(), 43), 84);
+ QCOMPARE(matcher1.indexIn(haystack, 85), -1);
+ QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.size(), 85), -1);
+
+ QByteArrayMatcher matcher7(QByteArray("123"));
+ QCOMPARE(matcher7.indexIn(haystack), 6);
+
+ matcher7 = QByteArrayMatcher(QByteArray("abc"));
+ QCOMPARE(matcher7.indexIn(haystack), 31);
+
+ matcher7.setPattern(matcher4.pattern());
+ QCOMPARE(matcher7.indexIn(haystack), 42);
+}
+
+#define LONG_STRING__32 "abcdefghijklmnopqrstuvwxyz012345"
+#define LONG_STRING__64 LONG_STRING__32 LONG_STRING__32
+#define LONG_STRING_128 LONG_STRING__64 LONG_STRING__64
+#define LONG_STRING_256 LONG_STRING_128 LONG_STRING_128
+
+void tst_QByteArrayMatcher::indexIn()
+{
+ const char p_data[] = { 0x0, 0x0, 0x1 };
+ QByteArray pattern(p_data, sizeof(p_data));
+
+ QByteArray haystack(8, '\0');
+ haystack[7] = 0x1;
+
+ QByteArrayMatcher matcher;
+
+ matcher = QByteArrayMatcher(pattern);
+ QCOMPARE(matcher.indexIn(haystack, 0), 5);
+ QCOMPARE(matcher.indexIn(haystack, 1), 5);
+ QCOMPARE(matcher.indexIn(haystack, 2), 5);
+
+ matcher.setPattern(pattern);
+ QCOMPARE(matcher.indexIn(haystack, 0), 5);
+ QCOMPARE(matcher.indexIn(haystack, 1), 5);
+ QCOMPARE(matcher.indexIn(haystack, 2), 5);
+
+ QByteArray allChars(256, Qt::Uninitialized);
+ for (int i = 0; i < 256; ++i)
+ allChars[i] = char(i);
+
+ matcher = QByteArrayMatcher(allChars);
+ haystack = LONG_STRING__32 "x" + matcher.pattern();
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+
+ matcher = QByteArrayMatcher(LONG_STRING_256);
+ haystack = LONG_STRING__32 "x" + matcher.pattern();
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+}
+
+void tst_QByteArrayMatcher::staticByteArrayMatcher()
+{
+ {
+ static constexpr auto smatcher = qMakeStaticByteArrayMatcher("Hello");
+ QCOMPARE(smatcher.pattern(), QByteArrayLiteral("Hello"));
+
+ QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!")), 0);
+ QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 0), 0);
+ QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 1), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aHello, World!")), 1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaHello, World!")), 2);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaHello, World!")), 3);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello, World!")), 4);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello, World!")), 5);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello, World!")), 6);
+ QCOMPARE(smatcher.indexIn(QByteArray("HHello, World!")), 1);
+ QCOMPARE(smatcher.indexIn(QByteArray("HeHello, World!")), 2);
+ QCOMPARE(smatcher.indexIn(QByteArray("HelHello, World!")), 3);
+ QCOMPARE(smatcher.indexIn(QByteArray("HellHello, World!")), 4);
+ QCOMPARE(smatcher.indexIn(QByteArray("HellaHello, World!")), 5);
+ QCOMPARE(smatcher.indexIn(QByteArray("HellauHello, World!")), 6);
+ QCOMPARE(smatcher.indexIn(QByteArray("aHella, World!")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaHella, World!")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaHella, World!")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella, World!")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella, World!")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella, World!")), -1);
+
+ QCOMPARE(smatcher.indexIn(QByteArray("aHello")), 1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaHello")), 2);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaHello")), 3);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello")), 4);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello")), 5);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello")), 6);
+ QCOMPARE(smatcher.indexIn(QByteArray("HHello")), 1);
+ QCOMPARE(smatcher.indexIn(QByteArray("HeHello")), 2);
+ QCOMPARE(smatcher.indexIn(QByteArray("HelHello")), 3);
+ QCOMPARE(smatcher.indexIn(QByteArray("HellHello")), 4);
+ QCOMPARE(smatcher.indexIn(QByteArray("HellaHello")), 5);
+ QCOMPARE(smatcher.indexIn(QByteArray("HellauHello")), 6);
+ QCOMPARE(smatcher.indexIn(QByteArray("aHella")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaHella")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaHella")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella")), -1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella")), -1);
+ }
+
+ {
+ static constexpr auto smatcher = qMakeStaticByteArrayMatcher(LONG_STRING_256);
+ QCOMPARE(smatcher.pattern(), QByteArrayLiteral(LONG_STRING_256));
+
+ QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256)), 1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256)), 2);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256)), 3);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256)), 4);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256)), 5);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256)), 6);
+ QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256 "a")), 1);
+ QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256 "a")), 2);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256 "a")), 3);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256 "a")), 4);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256 "a")), 5);
+ QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256 "a")), 6);
+ QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__32 "x" LONG_STRING_256)), 33);
+ QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__64 "x" LONG_STRING_256)), 65);
+ QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING_128 "x" LONG_STRING_256)), 129);
+ }
+
+}
+
+void tst_QByteArrayMatcher::haystacksWithMoreThan4GiBWork()
+{
+#if QT_POINTER_SIZE > 4
+ // use a large needle to trigger long skips in the Boyer-Moore algorithm
+ // (to speed up the test)
+ constexpr std::string_view needle = LONG_STRING_256;
+
+ //
+ // GIVEN: a haystack with more than 4 GiB of data
+ //
+
+ // don't use QByteArray because freeSpaceAtEnd() may break reserve()
+ // semantics and a realloc is the last thing we need here
+ std::string large;
+ QElapsedTimer timer;
+ timer.start();
+ constexpr size_t GiB = 1024 * 1024 * 1024;
+ constexpr size_t BaseSize = 4 * GiB + 1;
+ try {
+ large.reserve(BaseSize + needle.size());
+ large.resize(BaseSize, '\0');
+ large.append(needle);
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4GiB plus a couple hundred bytes of RAM.");
+ }
+ QCOMPARE(large.size(), BaseSize + needle.size());
+ qDebug("created dataset in %lld ms", timer.elapsed());
+
+ using MaybeThread = std::thread;
+
+ //
+ // WHEN: trying to match an occurrence past the 4GiB mark
+ //
+
+ qsizetype dynamicResult, staticResult;
+
+ auto t = MaybeThread{[&]{
+ QByteArrayMatcher m(needle);
+ dynamicResult = m.indexIn(large);
+ }};
+ {
+ static_assert(needle == LONG_STRING_256); // need a string literal in the following line:
+ QStaticByteArrayMatcher m(LONG_STRING_256);
+ staticResult = m.indexIn(large.data(), large.size());
+ }
+ t.join();
+
+ //
+ // THEN: the result index is not trucated
+ //
+
+ QCOMPARE(staticResult, qsizetype(BaseSize));
+ QCOMPARE(dynamicResult, qsizetype(BaseSize));
+#else
+ QSKIP("This test is 64-bit only.");
+#endif
+
+}
+
+#undef LONG_STRING_256
+#undef LONG_STRING_128
+#undef LONG_STRING__64
+#undef LONG_STRING__32
+
+QTEST_APPLESS_MAIN(tst_QByteArrayMatcher)
+#include "tst_qbytearraymatcher.moc"
diff --git a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt
new file mode 100644
index 0000000000..c78a81c7bd
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbytearrayview Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytearrayview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbytearrayview
+ SOURCES
+ tst_qbytearrayview.cpp
+)
diff --git a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp
new file mode 100644
index 0000000000..894f0430dd
--- /dev/null
+++ b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp
@@ -0,0 +1,728 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QByteArrayView>
+
+#include <QTest>
+
+// for negative testing (can't convert from)
+#include <deque>
+#include <list>
+#include <QVarLengthArray>
+
+template <typename T>
+constexpr bool CanConvert = std::is_convertible_v<T, QByteArrayView>;
+
+static_assert(!CanConvert<QString>);
+static_assert(!CanConvert<QStringView>);
+static_assert(!CanConvert<const char16_t*>);
+
+static_assert(!CanConvert<char>);
+static_assert(CanConvert<char[1]>);
+static_assert(CanConvert<const char[1]>);
+static_assert(CanConvert<char*>);
+static_assert(CanConvert<const char*>);
+
+static_assert(!CanConvert<uchar>);
+static_assert(!CanConvert<uchar[1]>);
+static_assert(!CanConvert<const uchar[1]>);
+static_assert(CanConvert<uchar*>);
+static_assert(CanConvert<const uchar*>);
+
+static_assert(!CanConvert<signed char>);
+static_assert(!CanConvert<signed char[1]>);
+static_assert(!CanConvert<const signed char[1]>);
+static_assert(CanConvert<signed char*>);
+static_assert(CanConvert<const signed char*>);
+
+static_assert(!CanConvert<std::byte>);
+static_assert(!CanConvert<std::byte[1]>);
+static_assert(!CanConvert<const std::byte[1]>);
+static_assert(CanConvert<std::byte*>);
+static_assert(CanConvert<const std::byte*>);
+
+static_assert(CanConvert< QByteArray >);
+static_assert(CanConvert<const QByteArray >);
+static_assert(CanConvert< QByteArray&>);
+static_assert(CanConvert<const QByteArray&>);
+
+static_assert(CanConvert< std::string >);
+static_assert(CanConvert<const std::string >);
+static_assert(CanConvert< std::string&>);
+static_assert(CanConvert<const std::string&>);
+
+static_assert(CanConvert< std::string_view >);
+static_assert(CanConvert<const std::string_view >);
+static_assert(CanConvert< std::string_view&>);
+static_assert(CanConvert<const std::string_view&>);
+
+static_assert(CanConvert< QVector<char> >);
+static_assert(CanConvert<const QVector<char> >);
+static_assert(CanConvert< QVector<char>&>);
+static_assert(CanConvert<const QVector<char>&>);
+
+static_assert(CanConvert< QVarLengthArray<char> >);
+static_assert(CanConvert<const QVarLengthArray<char> >);
+static_assert(CanConvert< QVarLengthArray<char>&>);
+static_assert(CanConvert<const QVarLengthArray<char>&>);
+
+static_assert(CanConvert< std::vector<char> >);
+static_assert(CanConvert<const std::vector<char> >);
+static_assert(CanConvert< std::vector<char>&>);
+static_assert(CanConvert<const std::vector<char>&>);
+
+static_assert(CanConvert< std::array<char, 1> >);
+static_assert(CanConvert<const std::array<char, 1> >);
+static_assert(CanConvert< std::array<char, 1>&>);
+static_assert(CanConvert<const std::array<char, 1>&>);
+
+static_assert(!CanConvert<std::deque<char>>);
+static_assert(!CanConvert<std::list<char>>);
+
+class tst_QByteArrayView : public QObject
+{
+ Q_OBJECT
+private slots:
+ // Note: much of the shared API is tested in ../qbytearrayapisymmetry/
+ void constExpr() const;
+ void basics() const;
+ void literals() const;
+ void fromArray() const;
+ void literalsWithInternalNulls() const;
+ void at() const;
+
+ void fromQByteArray() const;
+
+ void fromCharStar() const
+ {
+ fromEmptyLiteral<char>();
+ conversionTests("Hello, World!");
+ }
+
+ void fromUCharStar() const
+ {
+ fromEmptyLiteral<uchar>();
+
+ const uchar data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
+ conversionTests(data);
+ }
+
+ void fromSignedCharStar() const
+ {
+ fromEmptyLiteral<signed char>();
+
+ const signed char data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
+ conversionTests(data);
+ }
+
+ void fromStdByteArray() const
+ {
+ fromEmptyLiteral<std::byte>();
+
+ const std::byte data[] = {std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'},
+ std::byte{'o'}, std::byte{0}};
+ conversionTests(data);
+ }
+
+ void fromCharRange() const
+ {
+ const char data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
+ fromRange(std::begin(data), std::end(data));
+ }
+
+ void fromUCharRange() const
+ {
+ const uchar data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
+ fromRange(std::begin(data), std::end(data));
+ }
+
+ void fromSignedCharRange() const
+ {
+ const signed char data[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
+ fromRange(std::begin(data), std::end(data));
+ }
+
+ void fromStdByteRange() const
+ {
+ const std::byte data[] = {std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'},
+ std::byte{'o'}, std::byte{0}};
+ fromRange(std::begin(data), std::end(data));
+ }
+
+ void fromCharContainers() const
+ {
+ fromContainers<char>();
+ }
+
+ void fromUCharContainers() const
+ {
+ fromContainers<uchar>();
+ }
+
+ void fromSignedCharContainers() const
+ {
+ fromContainers<signed char>();
+ }
+
+ void fromStdByteContainers() const
+ {
+ fromContainers<std::byte>();
+ }
+
+ void comparison() const;
+ void compare() const;
+ void std_stringview_conversion();
+
+private:
+ template <typename Data>
+ void conversionTests(Data arg) const;
+ template <typename Char>
+ void fromEmptyLiteral() const;
+ template <typename Char>
+ void fromRange(const Char *first, const Char *last) const;
+ template <typename Char, typename Container>
+ void fromContainer() const;
+ template <typename Char>
+ void fromContainers() const;
+};
+
+void tst_QByteArrayView::constExpr() const
+{
+ // compile-time checks
+ {
+ constexpr QByteArrayView bv;
+ static_assert(bv.size() == 0);
+ static_assert(bv.isNull());
+ static_assert(bv.empty());
+ static_assert(bv.isEmpty());
+ static_assert(bv.data() == nullptr);
+
+ constexpr std::string_view sv = bv;
+ static_assert(sv.size() == 0);
+ static_assert(sv.data() == nullptr);
+
+ constexpr QByteArrayView bv2(bv.data(), bv.data() + bv.size());
+ static_assert(bv2.isNull());
+ static_assert(bv2.empty());
+ }
+ {
+ constexpr QByteArrayView bv = "";
+ static_assert(bv.size() == 0);
+ static_assert(!bv.isNull());
+ static_assert(bv.empty());
+ static_assert(bv.isEmpty());
+ static_assert(bv.data() != nullptr);
+
+ constexpr std::string_view sv = bv;
+ static_assert(sv.size() == bv.size());
+ static_assert(sv.data() == bv.data());
+
+ constexpr QByteArrayView bv2(bv.data(), bv.data() + bv.size());
+ static_assert(!bv2.isNull());
+ static_assert(bv2.empty());
+ }
+ {
+ static_assert(QByteArrayView("Hello").size() == 5);
+ constexpr QByteArrayView bv = "Hello";
+ static_assert(bv.size() == 5);
+ static_assert(!bv.empty());
+ static_assert(!bv.isEmpty());
+ static_assert(!bv.isNull());
+ static_assert(*bv.data() == 'H');
+ static_assert(bv[0] == 'H');
+ static_assert(bv.at(0) == 'H');
+ static_assert(bv.front() == 'H');
+ static_assert(bv.first() == 'H');
+ static_assert(bv[4] == 'o');
+ static_assert(bv.at(4) == 'o');
+ static_assert(bv.back() == 'o');
+ static_assert(bv.last() == 'o');
+
+ static_assert(*bv.begin() == 'H' );
+ static_assert(*(bv.end() - 1) == 'o' );
+ static_assert(*bv.cbegin() == 'H' );
+ static_assert(*(bv.cend() - 1) == 'o' );
+ static_assert(*bv.rbegin() == 'o' );
+ static_assert(*bv.crbegin() == 'o' );
+
+ // This is just to test that rend()/crend() are constexpr.
+ static_assert(bv.rbegin() != bv.rend());
+ static_assert(bv.crbegin() != bv.crend());
+
+ constexpr std::string_view sv = bv;
+ static_assert(sv.size() == bv.size());
+ static_assert(sv.data() == bv.data());
+#ifdef AMBIGUOUS_CALL // QTBUG-108805
+ static_assert(sv == bv);
+ static_assert(bv == sv);
+#endif
+
+ constexpr QByteArrayView bv2(bv.data(), bv.data() + bv.size());
+ static_assert(!bv2.isNull());
+ static_assert(!bv2.empty());
+ static_assert(bv2.size() == 5);
+ }
+#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
+ // Below checks are disabled because of a compilation issue with GCC and
+ // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962.
+ // Note: Q_CC_GNU is also defined for Clang, so we need to check that too.
+ {
+ static constexpr char hello[] = "Hello";
+ constexpr QByteArrayView bv(hello);
+ static_assert(bv.size() == 5);
+ static_assert(!bv.empty());
+ static_assert(!bv.isEmpty());
+ static_assert(!bv.isNull());
+ static_assert(*bv.data() == 'H');
+ static_assert(bv[0] == 'H');
+ static_assert(bv.at(0) == 'H');
+ static_assert(bv.front() == 'H');
+ static_assert(bv.first() == 'H');
+ static_assert(bv[4] == 'o');
+ static_assert(bv.at(4) == 'o');
+ static_assert(bv.back() == 'o');
+ static_assert(bv.last() == 'o');
+
+ constexpr std::string_view sv = bv;
+ static_assert(bv.size() == sv.size());
+#ifdef AMBIGUOUS_CALL // QTBUG-108805
+ static_assert(bv == sv);
+ static_assert(sv == bv);
+#endif
+ }
+ {
+ static constexpr char hello[] = { 'H', 'e', 'l', 'l', 'o' };
+ constexpr QByteArrayView bv(hello, std::size(hello));
+ static_assert(bv.size() == 5);
+ static_assert(!bv.empty());
+ static_assert(!bv.isEmpty());
+ static_assert(!bv.isNull());
+ static_assert(*bv.data() == 'H');
+ static_assert(bv[0] == 'H');
+ static_assert(bv.at(0) == 'H');
+ static_assert(bv.front() == 'H');
+ static_assert(bv.first() == 'H');
+ static_assert(bv[4] == 'o');
+ static_assert(bv.at(4) == 'o');
+ static_assert(bv.back() == 'o');
+ static_assert(bv.last() == 'o');
+
+ constexpr std::string_view sv = bv;
+ static_assert(bv.size() == sv.size());
+#ifdef AMBIGUOUS_CALL // QTBUG-108805
+ static_assert(bv == sv);
+ static_assert(sv == bv);
+#endif
+ }
+#endif
+ {
+ constexpr char *null = nullptr;
+ constexpr QByteArrayView bv(null);
+ static_assert(bv.isNull());
+ static_assert(bv.isEmpty());
+ static_assert(bv.size() == 0);
+
+ constexpr std::string_view sv = bv;
+ static_assert(sv.size() == 0);
+ static_assert(sv.data() == nullptr);
+ }
+ {
+ constexpr QByteArrayView bv(QLatin1StringView("Hello"));
+ static_assert(bv.size() == 5);
+ static_assert(!bv.empty());
+ static_assert(!bv.isEmpty());
+ static_assert(!bv.isNull());
+ static_assert(*bv.data() == 'H');
+ static_assert(bv[0] == 'H');
+ static_assert(bv.at(0) == 'H');
+ static_assert(bv.front() == 'H');
+ static_assert(bv.first() == 'H');
+ static_assert(bv[4] == 'o');
+ static_assert(bv.at(4) == 'o');
+ static_assert(bv.back() == 'o');
+ static_assert(bv.last() == 'o');
+ }
+ {
+ constexpr QByteArrayView bv(QUtf8StringView("Hello"));
+ static_assert(bv.size() == 5);
+ static_assert(!bv.empty());
+ static_assert(!bv.isEmpty());
+ static_assert(!bv.isNull());
+ static_assert(*bv.data() == 'H');
+ static_assert(bv[0] == 'H');
+ static_assert(bv.at(0) == 'H');
+ static_assert(bv.front() == 'H');
+ static_assert(bv.first() == 'H');
+ static_assert(bv[4] == 'o');
+ static_assert(bv.at(4) == 'o');
+ static_assert(bv.back() == 'o');
+ static_assert(bv.last() == 'o');
+ }
+}
+
+void tst_QByteArrayView::basics() const
+{
+ QByteArrayView bv1;
+
+ // a default-constructed QByteArrayView is null:
+ QVERIFY(bv1.isNull());
+ // which implies it's empty();
+ QVERIFY(bv1.isEmpty());
+
+ QByteArrayView bv2;
+
+ QVERIFY(bv2 == bv1);
+ QVERIFY(!(bv2 != bv1));
+}
+
+// Note: initially the size would be deduced from the array literal,
+// but it caused source compatibility issues so this is currently not the case.
+void tst_QByteArrayView::literals() const
+{
+ const char hello[] = "Hello\0This shouldn't be found";
+
+ QCOMPARE(QByteArrayView(hello).size(), 5);
+ QCOMPARE(QByteArrayView(hello + 0).size(), 5); // forces decay to pointer
+ QByteArrayView bv = hello;
+ QCOMPARE(bv.size(), 5);
+ QVERIFY(!bv.empty());
+ QVERIFY(!bv.isEmpty());
+ QVERIFY(!bv.isNull());
+ QCOMPARE(*bv.data(), 'H');
+ QCOMPARE(bv[0], 'H');
+ QCOMPARE(bv.at(0), 'H');
+ QCOMPARE(bv.front(), 'H');
+ QCOMPARE(bv.first(), 'H');
+ QCOMPARE(bv[4], 'o');
+ QCOMPARE(bv.at(4), 'o');
+ QCOMPARE(bv.back(), 'o');
+ QCOMPARE(bv.last(), 'o');
+
+ QByteArrayView bv2(bv.data(), bv.data() + bv.size());
+ QVERIFY(!bv2.isNull());
+ QVERIFY(!bv2.empty());
+ QCOMPARE(bv2.size(), 5);
+
+ const char abc[] = "abc";
+ bv = abc;
+ QCOMPARE(bv.size(), 3);
+
+ const char def[3] = {'d', 'e', 'f'};
+ bv = def;
+ QCOMPARE(bv.size(), 3);
+}
+
+void tst_QByteArrayView::fromArray() const
+{
+ static constexpr char hello[] = "Hello\0abc\0\0.";
+
+ constexpr QByteArrayView bv = QByteArrayView::fromArray(hello);
+ QCOMPARE(bv.size(), 13);
+ QVERIFY(!bv.empty());
+ QVERIFY(!bv.isEmpty());
+ QVERIFY(!bv.isNull());
+ QCOMPARE(*bv.data(), 'H');
+ QCOMPARE(bv[0], 'H');
+ QCOMPARE(bv.at(0), 'H');
+ QCOMPARE(bv.front(), 'H');
+ QCOMPARE(bv.first(), 'H');
+ QCOMPARE(bv[4], 'o');
+ QCOMPARE(bv.at(4), 'o');
+ QCOMPARE(bv[5], '\0');
+ QCOMPARE(bv.at(5), '\0');
+ QCOMPARE(*(bv.data() + bv.size() - 2), '.');
+ QCOMPARE(bv.back(), '\0');
+ QCOMPARE(bv.last(), '\0');
+
+ const std::byte bytes[] = {std::byte(0x0), std::byte(0x1), std::byte(0x2)};
+ QByteArrayView bbv = QByteArrayView::fromArray(bytes);
+ QCOMPARE(bbv.data(), reinterpret_cast<const char *>(bytes + 0));
+ QCOMPARE(bbv.size(), 3);
+ QCOMPARE(bbv.first(), 0x0);
+ QCOMPARE(bbv.last(), 0x2);
+}
+
+void tst_QByteArrayView::literalsWithInternalNulls() const
+{
+ const char withnull[] = "a\0zzz";
+
+ // these are different results
+ QCOMPARE(size_t(QByteArrayView::fromArray(withnull).size()), std::size(withnull));
+ QCOMPARE(QByteArrayView(withnull + 0).size(), 1);
+
+ QByteArrayView nulled = QByteArrayView::fromArray(withnull);
+ QCOMPARE(nulled.last(), '\0');
+ nulled.chop(1); // cut off trailing \0
+ QCOMPARE(nulled[1], '\0');
+ QCOMPARE(nulled.indexOf('\0'), 1);
+ QCOMPARE(nulled.indexOf('z'), 2);
+ QCOMPARE(nulled.lastIndexOf('z'), 4);
+ QCOMPARE(nulled.lastIndexOf('a'), 0);
+ QVERIFY(nulled.startsWith("a\0z"));
+ QVERIFY(nulled.startsWith("a\0y"));
+ QVERIFY(!nulled.startsWith(QByteArrayView("a\0y", 3)));
+ QVERIFY(nulled.endsWith("zz"));
+ QVERIFY(nulled.contains("z"));
+ QVERIFY(nulled.contains(QByteArrayView("\0z", 2)));
+ QVERIFY(!nulled.contains(QByteArrayView("\0y", 2)));
+ QCOMPARE(nulled.first(5), QByteArrayView(withnull, 5));
+ QCOMPARE(nulled.last(5), QByteArrayView(withnull, 5));
+ QCOMPARE(nulled.sliced(0), QByteArrayView(withnull, 5));
+ QCOMPARE(nulled.sliced(2, 2), "zz");
+ QCOMPARE(nulled.chopped(2), QByteArrayView("a\0z", 3));
+ QVERIFY(nulled.chopped(2) != QByteArrayView("a\0y", 3));
+ QCOMPARE(nulled.count('z'), 3);
+
+ const char nullfirst[] = "\0buzz";
+ QByteArrayView fromnull = QByteArrayView::fromArray(nullfirst);
+ QVERIFY(!fromnull.isEmpty());
+
+ const char nullNotEnd[] = { 'b', 'o', 'w', '\0', 'a', 'f', 't', 'z' };
+ QByteArrayView midNull = QByteArrayView::fromArray(nullNotEnd);
+ QCOMPARE(midNull.back(), 'z');
+}
+
+void tst_QByteArrayView::at() const
+{
+ QByteArray hello("Hello");
+ QByteArrayView bv(hello);
+ QCOMPARE(bv.at(0), 'H'); QCOMPARE(bv[0], 'H');
+ QCOMPARE(bv.at(1), 'e'); QCOMPARE(bv[1], 'e');
+ QCOMPARE(bv.at(2), 'l'); QCOMPARE(bv[2], 'l');
+ QCOMPARE(bv.at(3), 'l'); QCOMPARE(bv[3], 'l');
+ QCOMPARE(bv.at(4), 'o'); QCOMPARE(bv[4], 'o');
+}
+
+void tst_QByteArrayView::fromQByteArray() const
+{
+ QByteArray null;
+ QByteArray empty = "";
+
+ QVERIFY(QByteArrayView(null).isNull());
+ QVERIFY(qToByteArrayViewIgnoringNull(null).isNull());
+
+ QVERIFY(QByteArrayView(null).isEmpty());
+ QVERIFY(qToByteArrayViewIgnoringNull(null).isEmpty());
+
+ QVERIFY(QByteArrayView(empty).isEmpty());
+ QVERIFY(qToByteArrayViewIgnoringNull(empty).isEmpty());
+
+ QVERIFY(!QByteArrayView(empty).isNull());
+ QVERIFY(!qToByteArrayViewIgnoringNull(empty).isNull());
+
+ conversionTests(QByteArray("Hello World!"));
+}
+
+namespace help {
+template <typename T>
+size_t size(const T &t) { return size_t(t.size()); }
+template <typename T>
+size_t size(const T *t) { return std::char_traits<T>::length(t); }
+
+template <typename T>
+decltype(auto) cbegin(const T &t) { return t.begin(); }
+template <typename T>
+const T * cbegin(const T *t) { return t; }
+
+template <typename T>
+decltype(auto) cend(const T &t) { return t.end(); }
+template <typename T>
+const T * cend(const T *t) { return t + size(t); }
+
+template <typename T>
+decltype(auto) crbegin(const T &t) { return t.rbegin(); }
+template <typename T>
+std::reverse_iterator<const T*> crbegin(const T *t) { return std::reverse_iterator<const T*>(cend(t)); }
+
+template <typename T>
+decltype(auto) crend(const T &t) { return t.rend(); }
+template <typename T>
+std::reverse_iterator<const T*> crend(const T *t) { return std::reverse_iterator<const T*>(cbegin(t)); }
+
+} // namespace help
+
+template <typename Data>
+void tst_QByteArrayView::conversionTests(Data data) const
+{
+ // copy-construct:
+ {
+ QByteArrayView bv = data;
+
+ QCOMPARE(help::size(bv), help::size(data));
+
+ const auto compare = [](auto v1, auto v2) {
+ if constexpr (std::is_same_v<decltype(v1), std::byte>)
+ return std::to_integer<char>(v1) == v2;
+ else
+ return v1 == v2;
+ };
+ QVERIFY(std::equal(help::cbegin(data), help::cend(data),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(bv.cbegin(), bv.size()), compare));
+ QVERIFY(std::equal(help::cbegin(data), help::cend(data),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(bv.begin(), bv.size()), compare));
+ QVERIFY(std::equal(help::crbegin(data), help::crend(data), bv.crbegin(), compare));
+ QVERIFY(std::equal(help::crbegin(data), help::crend(data), bv.rbegin(), compare));
+ QCOMPARE(bv, data);
+ }
+
+ QByteArrayView bv;
+
+ // copy-assign:
+ {
+ bv = data;
+
+ QCOMPARE(help::size(bv), help::size(data));
+
+ // check relational operators:
+
+ QCOMPARE(bv, data);
+ QCOMPARE(data, bv);
+
+ QVERIFY(!(bv != data));
+ QVERIFY(!(data != bv));
+
+ QVERIFY(!(bv < data));
+ QVERIFY(bv <= data);
+ QVERIFY(!(bv > data));
+ QVERIFY(bv >= data);
+
+ QVERIFY(!(data < bv));
+ QVERIFY(data <= bv);
+ QVERIFY(!(data > bv));
+ QVERIFY(data >= bv);
+ }
+
+ // copy-construct from rvalue (QByteArrayView never assumes ownership):
+ {
+ QByteArrayView bv2 = std::move(data);
+ QCOMPARE(bv2, bv);
+ QCOMPARE(bv2, data);
+ }
+
+ // copy-assign from rvalue (QByteArrayView never assumes ownership):
+ {
+ QByteArrayView bv2;
+ bv2 = std::move(data);
+ QCOMPARE(bv2, bv);
+ QCOMPARE(bv2, data);
+ }
+}
+
+template <typename Char>
+void tst_QByteArrayView::fromEmptyLiteral() const
+{
+ const Char *null = nullptr;
+ const Char empty[] = { Char{0} };
+
+ QCOMPARE(QByteArrayView(null).size(), 0);
+ QCOMPARE(QByteArrayView(null).data(), nullptr);
+ QCOMPARE(QByteArrayView::fromArray(empty).size(), 1);
+ QCOMPARE(static_cast<const void*>(QByteArrayView::fromArray(empty).data()),
+ static_cast<const void*>(empty));
+
+ QVERIFY(QByteArrayView(null).isNull());
+ QVERIFY(QByteArrayView(null).isEmpty());
+ QVERIFY(!QByteArrayView::fromArray(empty).isEmpty());
+ QVERIFY(!QByteArrayView::fromArray(empty).isNull());
+}
+
+template <typename Char>
+void tst_QByteArrayView::fromRange(const Char *first, const Char *last) const
+{
+ const Char *null = nullptr;
+ QCOMPARE(QByteArrayView(null, null).size(), 0);
+ QCOMPARE(QByteArrayView(null, null).data(), nullptr);
+ QCOMPARE(QByteArrayView(first, first).size(), 0);
+ QCOMPARE(static_cast<const void*>(QByteArrayView(first, first).data()),
+ static_cast<const void*>(first));
+
+ const auto bv = QByteArrayView(first, last);
+ QCOMPARE(bv.size(), last - first);
+ QCOMPARE(static_cast<const void*>(bv.data()),
+ static_cast<const void*>(first));
+
+ QCOMPARE(static_cast<const void*>(bv.last(0).data()),
+ static_cast<const void*>(last));
+ QCOMPARE(static_cast<const void*>(bv.sliced(bv.size()).data()),
+ static_cast<const void*>(last));
+
+ // can't call conversionTests() here, as it requires a single object
+}
+
+template <typename Char, typename Container>
+void tst_QByteArrayView::fromContainer() const
+{
+ const QByteArray s = "Hello World!";
+
+ Container c;
+ // unspecified whether empty containers make null QByteArrayView
+ QVERIFY(QByteArrayView(c).isEmpty());
+
+ QCOMPARE(sizeof(Char), sizeof(char));
+
+ const auto *data = reinterpret_cast<const Char *>(s.data());
+ std::copy(data, data + s.size(), std::back_inserter(c));
+ conversionTests(std::move(c));
+}
+
+template <typename Char>
+void tst_QByteArrayView::fromContainers() const
+{
+ fromContainer<Char, QVector<Char>>();
+ fromContainer<Char, QVarLengthArray<Char>>();
+ fromContainer<Char, std::vector<Char>>();
+ fromContainer<Char, std::basic_string<Char>>();
+}
+
+void tst_QByteArrayView::comparison() const
+{
+ const QByteArrayView aa = "aa";
+ const QByteArrayView bb = "bb";
+
+ QVERIFY(aa == aa);
+ QVERIFY(aa != bb);
+ QVERIFY(aa < bb);
+ QVERIFY(bb > aa);
+}
+
+void tst_QByteArrayView::compare() const
+{
+ QByteArrayView alpha = "original";
+
+ QVERIFY(alpha.compare("original", Qt::CaseSensitive) == 0);
+ QVERIFY(alpha.compare("Original", Qt::CaseSensitive) > 0);
+ QVERIFY(alpha.compare("Original", Qt::CaseInsensitive) == 0);
+ QByteArrayView beta = "unoriginal";
+ QVERIFY(alpha.compare(beta, Qt::CaseInsensitive) < 0);
+ beta = "Unoriginal";
+ QVERIFY(alpha.compare(beta, Qt::CaseInsensitive) < 0);
+ QVERIFY(alpha.compare(beta, Qt::CaseSensitive) > 0);
+}
+
+void tst_QByteArrayView::std_stringview_conversion()
+{
+ static_assert(std::is_convertible_v<QByteArrayView, std::string_view>);
+
+ QByteArrayView bav;
+ std::string_view sv(bav);
+ QCOMPARE(sv, std::string_view());
+
+ bav = "";
+ sv = bav;
+ QCOMPARE(bav.size(), 0);
+ QCOMPARE(sv.size(), size_t(0));
+ QCOMPARE(sv, std::string_view());
+
+ bav = "Hello";
+ sv = bav;
+ QCOMPARE(sv, std::string_view("Hello"));
+
+ bav = QByteArrayView::fromArray("Hello\0world");
+ sv = bav;
+ QCOMPARE(bav.size(), 12);
+ QCOMPARE(sv.size(), size_t(12));
+ QCOMPARE(sv, std::string_view("Hello\0world", 12));
+}
+
+QTEST_APPLESS_MAIN(tst_QByteArrayView)
+#include "tst_qbytearrayview.moc"
diff --git a/tests/auto/corelib/tools/qbytedatabuffer/.gitignore b/tests/auto/corelib/text/qbytedatabuffer/.gitignore
index 3024a4dba2..3024a4dba2 100644
--- a/tests/auto/corelib/tools/qbytedatabuffer/.gitignore
+++ b/tests/auto/corelib/text/qbytedatabuffer/.gitignore
diff --git a/tests/auto/corelib/text/qbytedatabuffer/CMakeLists.txt b/tests/auto/corelib/text/qbytedatabuffer/CMakeLists.txt
new file mode 100644
index 0000000000..bfcfb6bc98
--- /dev/null
+++ b/tests/auto/corelib/text/qbytedatabuffer/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbytedatabuffer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbytedatabuffer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbytedatabuffer
+ SOURCES
+ tst_qbytedatabuffer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp b/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp
new file mode 100644
index 0000000000..27482f6486
--- /dev/null
+++ b/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp
@@ -0,0 +1,204 @@
+// Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <private/qbytedata_p.h>
+// for QIODEVICE_BUFFERSIZE macro (== 16384):
+#include <private/qiodevice_p.h>
+
+class tst_QByteDataBuffer : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void canReadLine();
+ void positionHandling();
+ void appendBuffer();
+ void moveAppendBuffer();
+ void readCompleteBuffer_data();
+ void readCompleteBuffer();
+ void readPartialBuffer_data();
+ void readPartialBuffer();
+ void readPointer();
+private:
+ void readBuffer(int size, int readSize);
+};
+
+void tst_QByteDataBuffer::canReadLine()
+{
+ QByteDataBuffer buf;
+ buf.append(QByteArray("a"));
+ buf.append(QByteArray("\nb"));
+ QVERIFY(buf.canReadLine());
+ QVERIFY(buf.getChar() == 'a');
+ QVERIFY(buf.canReadLine());
+ QVERIFY(buf.getChar() == '\n');
+ QVERIFY(!buf.canReadLine());
+}
+
+void tst_QByteDataBuffer::positionHandling()
+{
+ QByteDataBuffer buf;
+ buf.append(QByteArray("abc"));
+ buf.append(QByteArray("def"));
+
+ QCOMPARE(buf.byteAmount(), (qlonglong)6);
+ QCOMPARE(buf.sizeNextBlock(), (qlonglong)3);
+
+ QCOMPARE(buf.getChar(), 'a');
+ QCOMPARE(buf.byteAmount(), (qlonglong)5);
+ QCOMPARE(buf.sizeNextBlock(), (qlonglong)2);
+
+ QVERIFY(!strcmp(buf[0].constData(), "bc"));
+ QCOMPARE(buf.getChar(), 'b');
+ QCOMPARE(buf.byteAmount(), (qlonglong)4);
+ QCOMPARE(buf.sizeNextBlock(), (qlonglong)1);
+
+ QByteArray tmp("ab");
+ buf.prepend(tmp);
+ QCOMPARE(buf.byteAmount(), (qlonglong)6);
+ QVERIFY(!strcmp(buf.readAll().constData(), "abcdef"));
+ QCOMPARE(buf.byteAmount(), (qlonglong)0);
+
+ QByteDataBuffer buf2;
+ buf2.append(QByteArray("abc"));
+ buf2.getChar();
+ QCOMPARE(buf2.read(), QByteArray("bc"));
+}
+
+void tst_QByteDataBuffer::appendBuffer()
+{
+ QByteDataBuffer buf;
+ QByteArray local("\1\2\3");
+ buf.append(local);
+ buf.getChar();
+
+ QByteDataBuffer tmp;
+ tmp.append(buf);
+ QCOMPARE(tmp.readAll(), buf.readAll());
+}
+
+void tst_QByteDataBuffer::moveAppendBuffer()
+{
+ QByteDataBuffer buf;
+ buf.append(QByteArray("hello world"));
+ QCOMPARE(buf.getChar(), 'h');
+
+ QByteDataBuffer tmp;
+ tmp.append(std::move(buf));
+ QCOMPARE(tmp.readAll(), "ello world");
+}
+
+static QByteArray makeByteArray(int size)
+{
+ QByteArray array;
+ array.resize(size);
+ char *data = array.data();
+ for (int i = 0; i < size; ++i)
+ data[i] = i % 256;
+ return array;
+}
+
+
+void tst_QByteDataBuffer::readBuffer(int size, int readSize)
+{
+ QByteArray data = makeByteArray(size);
+
+ QByteDataBuffer buf;
+ buf.append(data);
+
+ QByteArray tmp;
+ tmp.resize(size);
+
+ QBENCHMARK_ONCE {
+ for (int i = 0; i < (size - 1) / readSize + 1; ++i)
+ buf.read(tmp.data() + i * readSize, readSize);
+ }
+
+ QCOMPARE(data.size(), tmp.size());
+ QCOMPARE(data, tmp);
+}
+
+void tst_QByteDataBuffer::readCompleteBuffer_data()
+{
+ QTest::addColumn<int>("size");
+ QTest::newRow("10B") << (int)10;
+ QTest::newRow("1MB") << (int)1e6;
+ QTest::newRow("5MB") << (int)5e6;
+ QTest::newRow("10MB") << (int)10e6;
+}
+
+void tst_QByteDataBuffer::readCompleteBuffer()
+{
+ QFETCH(int, size);
+ readBuffer(size, size);
+}
+
+void tst_QByteDataBuffer::readPartialBuffer_data()
+{
+ readCompleteBuffer_data();
+}
+
+void tst_QByteDataBuffer::readPartialBuffer()
+{
+ QFETCH(int, size);
+ // QIODevice::readAll() reads in QIODEVICE_BUFFERSIZE size
+ // increments.
+ readBuffer(size, QIODEVICE_BUFFERSIZE);
+}
+
+void tst_QByteDataBuffer::readPointer()
+{
+ QByteDataBuffer buffer;
+
+ auto view = buffer.readPointer();
+ QCOMPARE(view.size(), 0);
+ QCOMPARE(view, "");
+
+ buffer.append("Hello");
+ buffer.append("World");
+
+ qint64 initialSize = buffer.byteAmount();
+ view = buffer.readPointer();
+
+ QCOMPARE(initialSize, buffer.byteAmount());
+ QCOMPARE(view.size(), 5);
+ QCOMPARE(view, "Hello");
+
+ buffer.advanceReadPointer(2);
+ view = buffer.readPointer();
+
+ QCOMPARE(initialSize - 2, buffer.byteAmount());
+ QCOMPARE(view.size(), 3);
+ QCOMPARE(view, "llo");
+
+ buffer.advanceReadPointer(3);
+ view = buffer.readPointer();
+
+ QCOMPARE(initialSize - 5, buffer.byteAmount());
+ QCOMPARE(view.size(), 5);
+ QCOMPARE(view, "World");
+
+ buffer.advanceReadPointer(5);
+ view = buffer.readPointer();
+
+ QVERIFY(buffer.isEmpty());
+ QCOMPARE(view.size(), 0);
+ QCOMPARE(view, "");
+
+ // Advance past the current view's size
+ buffer.append("Hello");
+ buffer.append("World");
+
+ buffer.advanceReadPointer(6);
+ view = buffer.readPointer();
+ QCOMPARE(view, "orld");
+ QCOMPARE(buffer.byteAmount(), 4);
+
+ // Advance past the end of all contained data
+ buffer.advanceReadPointer(6);
+ view = buffer.readPointer();
+ QCOMPARE(view, "");
+}
+
+QTEST_MAIN(tst_QByteDataBuffer)
+#include "tst_qbytedatabuffer.moc"
diff --git a/tests/auto/corelib/tools/qchar/.gitignore b/tests/auto/corelib/text/qchar/.gitignore
index 341b3e6c3f..341b3e6c3f 100644
--- a/tests/auto/corelib/tools/qchar/.gitignore
+++ b/tests/auto/corelib/text/qchar/.gitignore
diff --git a/tests/auto/corelib/text/qchar/CMakeLists.txt b/tests/auto/corelib/text/qchar/CMakeLists.txt
new file mode 100644
index 0000000000..03b99356ea
--- /dev/null
+++ b/tests/auto/corelib/text/qchar/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qchar Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qchar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+list(APPEND test_data "data/NormalizationTest.txt")
+
+qt_internal_add_test(tst_qchar
+ SOURCES
+ tst_qchar.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt b/tests/auto/corelib/text/qchar/data/NormalizationTest.txt
index 0290080998..0290080998 100644
--- a/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt
+++ b/tests/auto/corelib/text/qchar/data/NormalizationTest.txt
diff --git a/tests/auto/corelib/text/qchar/tst_qchar.cpp b/tests/auto/corelib/text/qchar/tst_qchar.cpp
new file mode 100644
index 0000000000..fae507f4c6
--- /dev/null
+++ b/tests/auto/corelib/text/qchar/tst_qchar.cpp
@@ -0,0 +1,1047 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qchar.h>
+#include <qfile.h>
+#include <qstringlist.h>
+
+class tst_QChar : public QObject
+{
+ Q_OBJECT
+private slots:
+ void fromChar16_t();
+ void fromUcs4_data();
+ void fromUcs4();
+ void fromWchar_t();
+ void operator_eqeq_null();
+ void operators_data();
+ void operators();
+ void qchar_qlatin1char_operators_symmetry_data();
+ void qchar_qlatin1char_operators_symmetry();
+ void toUpper();
+ void toLower();
+ void toTitle();
+ void toCaseFolded();
+ void isDigit_data();
+ void isDigit();
+ void isLetter_data();
+ void isLetter();
+ void isLetterOrNumber_data();
+ void isLetterOrNumber();
+ void isPrint();
+ void isUpper();
+ void isLower();
+ void isTitleCase();
+ void isSpace_data();
+ void isSpace();
+ void isSpaceSpecial();
+ void category();
+ void direction();
+ void joiningType();
+ void combiningClass();
+ void digitValue();
+ void mirroredChar();
+ void decomposition();
+ void script();
+#if !defined(Q_OS_WASM)
+ void normalization_data();
+ void normalization();
+#endif // !defined(Q_OS_WASM)
+ void normalization_manual();
+ void normalizationCorrections();
+ void unicodeVersion();
+};
+
+void tst_QChar::fromChar16_t()
+{
+ QChar aUmlaut = u'\u00E4'; // German small letter a-umlaut
+ QCOMPARE(aUmlaut, QChar(0xE4));
+ QChar replacementCharacter = u'\uFFFD';
+ QCOMPARE(replacementCharacter, QChar(QChar::ReplacementCharacter));
+}
+
+void tst_QChar::fromUcs4_data()
+{
+ QTest::addColumn<uint>("ucs4");
+ auto row = [](uint ucs4) {
+ QTest::addRow("0x%08X", ucs4) << ucs4;
+ };
+
+ row(0x2f868); // a CJK Compatibility Ideograph
+ row(0x11139); // Chakma digit 3
+ row(0x1D157); // Musical Symbol Void Notehead
+}
+
+void tst_QChar::fromUcs4()
+{
+ QFETCH(const uint, ucs4);
+
+ const auto result = QChar::fromUcs4(ucs4);
+ if (QChar::requiresSurrogates(ucs4)) {
+ QCOMPARE(result.chars[0], QChar::highSurrogate(ucs4));
+ QCOMPARE(result.chars[1], QChar::lowSurrogate(ucs4));
+ QCOMPARE(QStringView{result}.size(), 2);
+ } else {
+ QCOMPARE(result.chars[0], ucs4);
+ QCOMPARE(result.chars[1], 0u);
+ QCOMPARE(QStringView{result}.size(), 1);
+ }
+}
+
+void tst_QChar::fromWchar_t()
+{
+#if defined(Q_OS_WIN)
+ QChar aUmlaut(L'\u00E4'); // German small letter a-umlaut
+ QCOMPARE(aUmlaut, QChar(0xE4));
+ QChar replacementCharacter(L'\uFFFD');
+ QCOMPARE(replacementCharacter, QChar(QChar::ReplacementCharacter));
+#else
+ QSKIP("This is a Windows-only test.");
+#endif
+}
+
+void tst_QChar::operator_eqeq_null()
+{
+ {
+ const QChar ch = QLatin1Char(' ');
+#define CHECK(NUL) \
+ do { \
+ QVERIFY(!(ch == NUL)); \
+ QVERIFY( ch != NUL ); \
+ QVERIFY(!(ch < NUL)); \
+ QVERIFY( ch > NUL ); \
+ QVERIFY(!(ch <= NUL)); \
+ QVERIFY( ch >= NUL ); \
+ QVERIFY(!(NUL == ch )); \
+ QVERIFY( NUL != ch ); \
+ QVERIFY( NUL < ch ); \
+ QVERIFY(!(NUL > ch )); \
+ QVERIFY( NUL <= ch ); \
+ QVERIFY(!(NUL >= ch )); \
+ } while (0)
+
+ CHECK(0);
+ CHECK('\0');
+#undef CHECK
+ }
+ {
+ const QChar ch = QLatin1Char('\0');
+#define CHECK(NUL) \
+ do { \
+ QVERIFY( ch == NUL ); \
+ QVERIFY(!(ch != NUL)); \
+ QVERIFY(!(ch < NUL)); \
+ QVERIFY(!(ch > NUL)); \
+ QVERIFY( ch <= NUL ); \
+ QVERIFY( ch >= NUL ); \
+ QVERIFY( NUL == ch ); \
+ QVERIFY(!(NUL != ch )); \
+ QVERIFY(!(NUL < ch )); \
+ QVERIFY(!(NUL > ch )); \
+ QVERIFY( NUL <= ch ); \
+ QVERIFY( NUL >= ch ); \
+ } while (0)
+
+ CHECK(0);
+ CHECK('\0');
+#undef CHECK
+ }
+}
+
+void tst_QChar::operators_data()
+{
+ QTest::addColumn<QChar>("lhs");
+ QTest::addColumn<QChar>("rhs");
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j)
+ QTest::addRow("'\\%d' (op) '\\%d'", i, j)
+ << QChar(ushort(i)) << QChar(ushort(j));
+ }
+}
+
+void tst_QChar::operators()
+{
+ QFETCH(QChar, lhs);
+ QFETCH(QChar, rhs);
+
+#define CHECK(op) QCOMPARE((lhs op rhs), (lhs.unicode() op rhs.unicode()))
+ CHECK(==);
+ CHECK(!=);
+ CHECK(< );
+ CHECK(> );
+ CHECK(<=);
+ CHECK(>=);
+#undef CHECK
+}
+
+void tst_QChar::qchar_qlatin1char_operators_symmetry_data()
+{
+ QTest::addColumn<char>("lhs");
+ QTest::addColumn<char>("rhs");
+
+ const uchar values[] = {0x00, 0x3a, 0x7f, 0x80, 0xab, 0xff};
+
+ for (uchar i : values) {
+ for (uchar j : values)
+ QTest::addRow("'\\x%02x'_op_'\\x%02x'", i, j) << char(i) << char(j);
+ }
+}
+
+void tst_QChar::qchar_qlatin1char_operators_symmetry()
+{
+ QFETCH(char, lhs);
+ QFETCH(char, rhs);
+
+ const QLatin1Char l1lhs(lhs);
+ const QLatin1Char l1rhs(rhs);
+#define CHECK(op) QCOMPARE((l1lhs op l1rhs), (QChar(l1lhs) op QChar(l1rhs)))
+ CHECK(==);
+ CHECK(!=);
+ CHECK(< );
+ CHECK(> );
+ CHECK(<=);
+ CHECK(>=);
+#undef CHECK
+}
+
+void tst_QChar::toUpper()
+{
+ QVERIFY(QChar('a').toUpper() == 'A');
+ QVERIFY(QChar('A').toUpper() == 'A');
+ QVERIFY(QChar(0x1c7).toUpper().unicode() == 0x1c7);
+ QVERIFY(QChar(0x1c8).toUpper().unicode() == 0x1c7);
+ QVERIFY(QChar(0x1c9).toUpper().unicode() == 0x1c7);
+ QVERIFY(QChar(0x25c).toUpper().unicode() == 0xa7ab);
+ QVERIFY(QChar(0x29e).toUpper().unicode() == 0xa7b0);
+ QVERIFY(QChar(0x1d79).toUpper().unicode() == 0xa77d);
+ QVERIFY(QChar(0x0265).toUpper().unicode() == 0xa78d);
+
+ QVERIFY(QChar::toUpper('a') == 'A');
+ QVERIFY(QChar::toUpper('A') == 'A');
+ QVERIFY(QChar::toUpper(0xdf) == 0xdf); // german sharp s
+ QVERIFY(QChar::toUpper(0x1c7) == 0x1c7);
+ QVERIFY(QChar::toUpper(0x1c8) == 0x1c7);
+ QVERIFY(QChar::toUpper(0x1c9) == 0x1c7);
+ QVERIFY(QChar::toUpper(0x25c) == 0xa7ab);
+ QVERIFY(QChar::toUpper(0x29e) == 0xa7b0);
+ QVERIFY(QChar::toUpper(0x1d79) == 0xa77d);
+ QVERIFY(QChar::toUpper(0x0265) == 0xa78d);
+
+ QVERIFY(QChar::toUpper(0x10400) == 0x10400);
+ QVERIFY(QChar::toUpper(0x10428) == 0x10400);
+}
+
+void tst_QChar::toLower()
+{
+ QVERIFY(QChar('A').toLower() == 'a');
+ QVERIFY(QChar('a').toLower() == 'a');
+ QVERIFY(QChar(0x1c7).toLower().unicode() == 0x1c9);
+ QVERIFY(QChar(0x1c8).toLower().unicode() == 0x1c9);
+ QVERIFY(QChar(0x1c9).toLower().unicode() == 0x1c9);
+ QVERIFY(QChar(0xa77d).toLower().unicode() == 0x1d79);
+ QVERIFY(QChar(0xa78d).toLower().unicode() == 0x0265);
+ QVERIFY(QChar(0xa7ab).toLower().unicode() == 0x25c);
+ QVERIFY(QChar(0xa7b1).toLower().unicode() == 0x287);
+
+ QVERIFY(QChar::toLower('a') == 'a');
+ QVERIFY(QChar::toLower('A') == 'a');
+ QVERIFY(QChar::toLower(0x1c7) == 0x1c9);
+ QVERIFY(QChar::toLower(0x1c8) == 0x1c9);
+ QVERIFY(QChar::toLower(0x1c9) == 0x1c9);
+ QVERIFY(QChar::toLower(0xa77d) == 0x1d79);
+ QVERIFY(QChar::toLower(0xa78d) == 0x0265);
+ QVERIFY(QChar::toLower(0xa7ab) == 0x25c);
+ QVERIFY(QChar::toLower(0xa7b1) == 0x287);
+
+ QVERIFY(QChar::toLower(0x10400) == 0x10428);
+ QVERIFY(QChar::toLower(0x10428) == 0x10428);
+}
+
+void tst_QChar::toTitle()
+{
+ QVERIFY(QChar('a').toTitleCase() == 'A');
+ QVERIFY(QChar('A').toTitleCase() == 'A');
+ QVERIFY(QChar(0x1c7).toTitleCase().unicode() == 0x1c8);
+ QVERIFY(QChar(0x1c8).toTitleCase().unicode() == 0x1c8);
+ QVERIFY(QChar(0x1c9).toTitleCase().unicode() == 0x1c8);
+ QVERIFY(QChar(0x1d79).toTitleCase().unicode() == 0xa77d);
+ QVERIFY(QChar(0x0265).toTitleCase().unicode() == 0xa78d);
+
+ QVERIFY(QChar::toTitleCase('a') == 'A');
+ QVERIFY(QChar::toTitleCase('A') == 'A');
+ QVERIFY(QChar::toTitleCase(0xdf) == 0xdf); // german sharp s
+ QVERIFY(QChar::toTitleCase(0x1c7) == 0x1c8);
+ QVERIFY(QChar::toTitleCase(0x1c8) == 0x1c8);
+ QVERIFY(QChar::toTitleCase(0x1c9) == 0x1c8);
+ QVERIFY(QChar::toTitleCase(0x1d79) == 0xa77d);
+ QVERIFY(QChar::toTitleCase(0x0265) == 0xa78d);
+
+ QVERIFY(QChar::toTitleCase(0x10400) == 0x10400);
+ QVERIFY(QChar::toTitleCase(0x10428) == 0x10400);
+}
+
+void tst_QChar::toCaseFolded()
+{
+ QVERIFY(QChar('a').toCaseFolded() == 'a');
+ QVERIFY(QChar('A').toCaseFolded() == 'a');
+ QVERIFY(QChar(0x1c7).toCaseFolded().unicode() == 0x1c9);
+ QVERIFY(QChar(0x1c8).toCaseFolded().unicode() == 0x1c9);
+ QVERIFY(QChar(0x1c9).toCaseFolded().unicode() == 0x1c9);
+ QVERIFY(QChar(0xa77d).toCaseFolded().unicode() == 0x1d79);
+ QVERIFY(QChar(0xa78d).toCaseFolded().unicode() == 0x0265);
+ QVERIFY(QChar(0xa7ab).toCaseFolded().unicode() == 0x25c);
+ QVERIFY(QChar(0xa7b1).toCaseFolded().unicode() == 0x287);
+
+ QVERIFY(QChar::toCaseFolded('a') == 'a');
+ QVERIFY(QChar::toCaseFolded('A') == 'a');
+ QVERIFY(QChar::toCaseFolded(0x1c7) == 0x1c9);
+ QVERIFY(QChar::toCaseFolded(0x1c8) == 0x1c9);
+ QVERIFY(QChar::toCaseFolded(0x1c9) == 0x1c9);
+ QVERIFY(QChar::toCaseFolded(0xa77d) == 0x1d79);
+ QVERIFY(QChar::toCaseFolded(0xa78d) == 0x0265);
+ QVERIFY(QChar::toCaseFolded(0xa7ab) == 0x25c);
+ QVERIFY(QChar::toCaseFolded(0xa7b1) == 0x287);
+
+ QVERIFY(QChar::toCaseFolded(0x10400) == 0x10428);
+ QVERIFY(QChar::toCaseFolded(0x10428) == 0x10428);
+
+ QVERIFY(QChar::toCaseFolded(0xb5) == 0x3bc);
+}
+
+void tst_QChar::isDigit_data()
+{
+ QTest::addColumn<ushort>("ucs");
+ QTest::addColumn<bool>("expected");
+
+ for (ushort ucs = 0; ucs < 256; ++ucs) {
+ bool isDigit = (ucs <= '9' && ucs >= '0');
+ const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
+ QTest::newRow(tag.constData()) << ucs << isDigit;
+ }
+}
+
+void tst_QChar::isDigit()
+{
+ QFETCH(ushort, ucs);
+ QFETCH(bool, expected);
+ QCOMPARE(QChar(ucs).isDigit(), expected);
+}
+
+static bool isExpectedLetter(ushort ucs)
+{
+ return (ucs >= 'a' && ucs <= 'z') || (ucs >= 'A' && ucs <= 'Z')
+ || ucs == 0xAA || ucs == 0xB5 || ucs == 0xBA
+ || (ucs >= 0xC0 && ucs <= 0xD6)
+ || (ucs >= 0xD8 && ucs <= 0xF6)
+ || (ucs >= 0xF8 && ucs <= 0xFF);
+}
+
+void tst_QChar::isLetter_data()
+{
+ QTest::addColumn<ushort>("ucs");
+ QTest::addColumn<bool>("expected");
+
+ for (ushort ucs = 0; ucs < 256; ++ucs) {
+ const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
+ QTest::newRow(tag.constData()) << ucs << isExpectedLetter(ucs);
+ }
+}
+
+void tst_QChar::isLetter()
+{
+ QFETCH(ushort, ucs);
+ QFETCH(bool, expected);
+ QCOMPARE(QChar(ucs).isLetter(), expected);
+}
+
+void tst_QChar::isLetterOrNumber_data()
+{
+ QTest::addColumn<ushort>("ucs");
+ QTest::addColumn<bool>("expected");
+
+ for (ushort ucs = 0; ucs < 256; ++ucs) {
+ bool isLetterOrNumber = isExpectedLetter(ucs)
+ || (ucs >= '0' && ucs <= '9')
+ || ucs == 0xB2 || ucs == 0xB3 || ucs == 0xB9
+ || (ucs >= 0xBC && ucs <= 0xBE);
+ const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
+ QTest::newRow(tag.constData()) << ucs << isLetterOrNumber;
+ }
+}
+
+void tst_QChar::isLetterOrNumber()
+{
+ QFETCH(ushort, ucs);
+ QFETCH(bool, expected);
+ QCOMPARE(QChar(ucs).isLetterOrNumber(), expected);
+}
+
+void tst_QChar::isPrint()
+{
+ // noncharacters, reserved (General_Gategory =Cn)
+ QVERIFY(!QChar(0x2064).isPrint());
+ QVERIFY(!QChar(0x2069).isPrint());
+ QVERIFY(!QChar(0xfdd0).isPrint());
+ QVERIFY(!QChar(0xfdef).isPrint());
+ QVERIFY(!QChar(0xfff0).isPrint());
+ QVERIFY(!QChar(0xfff8).isPrint());
+ QVERIFY(!QChar(0xfffe).isPrint());
+ QVERIFY(!QChar(0xffff).isPrint());
+ QVERIFY(!QChar::isPrint(0xe0000));
+ QVERIFY(!QChar::isPrint(0xe0002));
+ QVERIFY(!QChar::isPrint(0xe001f));
+ QVERIFY(!QChar::isPrint(0xe0080));
+ QVERIFY(!QChar::isPrint(0xe00ff));
+
+ // Other_Default_Ignorable_Code_Point, Variation_Selector
+ QVERIFY(QChar(0x034f).isPrint());
+ QVERIFY(QChar(0x115f).isPrint());
+ QVERIFY(QChar(0x180b).isPrint());
+ QVERIFY(QChar(0x180d).isPrint());
+ QVERIFY(QChar(0x3164).isPrint());
+ QVERIFY(QChar(0xfe00).isPrint());
+ QVERIFY(QChar(0xfe0f).isPrint());
+ QVERIFY(QChar(0xffa0).isPrint());
+ QVERIFY(QChar::isPrint(0xe0100));
+ QVERIFY(QChar::isPrint(0xe01ef));
+
+ // Cf, Cs, Cc, White_Space, Annotation Characters
+ QVERIFY(!QChar(0x0008).isPrint());
+ QVERIFY(!QChar(0x000a).isPrint());
+ QVERIFY(QChar(0x0020).isPrint());
+ QVERIFY(QChar(0x00a0).isPrint());
+ QVERIFY(!QChar(0x00ad).isPrint());
+ QVERIFY(!QChar(0x0085).isPrint());
+ QVERIFY(!QChar(0xd800).isPrint());
+ QVERIFY(!QChar(0xdc00).isPrint());
+ QVERIFY(!QChar(0xfeff).isPrint());
+ QVERIFY(!QChar::isPrint(0x1d173));
+
+ QVERIFY(QChar('0').isPrint());
+ QVERIFY(QChar('A').isPrint());
+ QVERIFY(QChar('a').isPrint());
+
+ QVERIFY(QChar(0x0370).isPrint()); // assigned in 5.1
+ QVERIFY(QChar(0x0524).isPrint()); // assigned in 5.2
+ QVERIFY(QChar(0x0526).isPrint()); // assigned in 6.0
+ QVERIFY(QChar(0x08a0).isPrint()); // assigned in 6.1
+ QVERIFY(!QChar(0x1aff).isPrint()); // not assigned
+ QVERIFY(QChar(0x1e9e).isPrint()); // assigned in 5.1
+ QVERIFY(QChar::isPrint(0x1b000)); // assigned in 6.0
+ QVERIFY(QChar::isPrint(0x110d0)); // assigned in 5.1
+ QVERIFY(!QChar::isPrint(0x1bca0)); // assigned in 7.0
+}
+
+void tst_QChar::isUpper()
+{
+ QVERIFY(QChar('A').isUpper());
+ QVERIFY(QChar('Z').isUpper());
+ QVERIFY(!QChar('a').isUpper());
+ QVERIFY(!QChar('z').isUpper());
+ QVERIFY(!QChar('?').isUpper());
+ QVERIFY(QChar(0xC2).isUpper()); // A with ^
+ QVERIFY(!QChar(0xE2).isUpper()); // a with ^
+
+ for (uint codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
+ if (QChar::isUpper(codepoint))
+ QVERIFY(codepoint == QChar::toUpper(codepoint));
+ }
+}
+
+void tst_QChar::isLower()
+{
+ QVERIFY(!QChar('A').isLower());
+ QVERIFY(!QChar('Z').isLower());
+ QVERIFY(QChar('a').isLower());
+ QVERIFY(QChar('z').isLower());
+ QVERIFY(!QChar('?').isLower());
+ QVERIFY(!QChar(0xC2).isLower()); // A with ^
+ QVERIFY(QChar(0xE2).isLower()); // a with ^
+
+ for (uint codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
+ if (QChar::isLower(codepoint))
+ QVERIFY(codepoint == QChar::toLower(codepoint));
+ }
+}
+
+void tst_QChar::isTitleCase()
+{
+ for (uint codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
+ if (QChar::isTitleCase(codepoint))
+ QVERIFY(codepoint == QChar::toTitleCase(codepoint));
+ }
+}
+
+void tst_QChar::isSpace_data()
+{
+ QTest::addColumn<ushort>("ucs");
+ QTest::addColumn<bool>("expected");
+
+ for (ushort ucs = 0; ucs < 256; ++ucs) {
+ bool isSpace = (ucs <= 0x0D && ucs >= 0x09) || ucs == 0x20 || ucs == 0xA0 || ucs == 0x85;
+ const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
+ QTest::newRow(tag.constData()) << ucs << isSpace;
+ }
+}
+
+void tst_QChar::isSpace()
+{
+ QFETCH(ushort, ucs);
+ QFETCH(bool, expected);
+ QCOMPARE(QChar(ucs).isSpace(), expected);
+}
+
+void tst_QChar::isSpaceSpecial()
+{
+ QVERIFY(!QChar(QChar::Null).isSpace());
+ QVERIFY(QChar(QChar::Nbsp).isSpace());
+ QVERIFY(QChar(QChar::ParagraphSeparator).isSpace());
+ QVERIFY(QChar(QChar::LineSeparator).isSpace());
+ QVERIFY(QChar(0x1680).isSpace());
+}
+
+void tst_QChar::category()
+{
+ QVERIFY(QChar('a').category() == QChar::Letter_Lowercase);
+ QVERIFY(QChar('A').category() == QChar::Letter_Uppercase);
+
+ QVERIFY(QChar::category('a') == QChar::Letter_Lowercase);
+ QVERIFY(QChar::category('A') == QChar::Letter_Uppercase);
+
+ QVERIFY(QChar::category(0xe0100) == QChar::Mark_NonSpacing);
+ QVERIFY(QChar::category(0xeffff) != QChar::Other_PrivateUse);
+ QVERIFY(QChar::category(0xf0000) == QChar::Other_PrivateUse);
+ QVERIFY(QChar::category(0xf0001) == QChar::Other_PrivateUse);
+
+ QVERIFY(QChar::category(0xd900) == QChar::Other_Surrogate);
+ QVERIFY(QChar::category(0xdc00) == QChar::Other_Surrogate);
+ QVERIFY(QChar::category(0xdc01) == QChar::Other_Surrogate);
+
+ QVERIFY(QChar::category(0x1aff) == QChar::Other_NotAssigned);
+ QVERIFY(QChar::category(0x10fffd) == QChar::Other_PrivateUse);
+ QVERIFY(QChar::category(0x10ffff) == QChar::Other_NotAssigned);
+ QVERIFY(QChar::category(0x110000) == QChar::Other_NotAssigned);
+}
+
+void tst_QChar::direction()
+{
+ QVERIFY(QChar::direction(0x200E) == QChar::DirL);
+ QVERIFY(QChar::direction(0x200F) == QChar::DirR);
+ QVERIFY(QChar::direction(0x202A) == QChar::DirLRE);
+ QVERIFY(QChar::direction(0x202B) == QChar::DirRLE);
+ QVERIFY(QChar::direction(0x202C) == QChar::DirPDF);
+ QVERIFY(QChar::direction(0x202D) == QChar::DirLRO);
+ QVERIFY(QChar::direction(0x202E) == QChar::DirRLO);
+ QVERIFY(QChar::direction(0x2066) == QChar::DirLRI);
+ QVERIFY(QChar::direction(0x2067) == QChar::DirRLI);
+ QVERIFY(QChar::direction(0x2068) == QChar::DirFSI);
+ QVERIFY(QChar::direction(0x2069) == QChar::DirPDI);
+
+ QVERIFY(QChar('a').direction() == QChar::DirL);
+ QVERIFY(QChar('0').direction() == QChar::DirEN);
+ QVERIFY(QChar(0x627).direction() == QChar::DirAL);
+ QVERIFY(QChar(0x5d0).direction() == QChar::DirR);
+
+ QVERIFY(QChar::direction('a') == QChar::DirL);
+ QVERIFY(QChar::direction('0') == QChar::DirEN);
+ QVERIFY(QChar::direction(0x627) == QChar::DirAL);
+ QVERIFY(QChar::direction(0x5d0) == QChar::DirR);
+
+ QVERIFY(QChar::direction(0xE01DA) == QChar::DirNSM);
+ QVERIFY(QChar::direction(0xf0000) == QChar::DirL);
+ QVERIFY(QChar::direction(0xE0030) == QChar::DirBN);
+ QVERIFY(QChar::direction(0x2FA17) == QChar::DirL);
+}
+
+void tst_QChar::joiningType()
+{
+ QVERIFY(QChar('a').joiningType() == QChar::Joining_None);
+ QVERIFY(QChar('0').joiningType() == QChar::Joining_None);
+ QVERIFY(QChar(0x0627).joiningType() == QChar::Joining_Right);
+ QVERIFY(QChar(0x05d0).joiningType() == QChar::Joining_None);
+ QVERIFY(QChar(0x00ad).joiningType() == QChar::Joining_Transparent);
+ QVERIFY(QChar(0xA872).joiningType() == QChar::Joining_Left);
+
+ QVERIFY(QChar::joiningType('a') == QChar::Joining_None);
+ QVERIFY(QChar::joiningType('0') == QChar::Joining_None);
+ QVERIFY(QChar::joiningType(0x0627) == QChar::Joining_Right);
+ QVERIFY(QChar::joiningType(0x05d0) == QChar::Joining_None);
+ QVERIFY(QChar::joiningType(0x00ad) == QChar::Joining_Transparent);
+
+ QVERIFY(QChar::joiningType(0xE01DA) == QChar::Joining_Transparent);
+ QVERIFY(QChar::joiningType(0xf0000) == QChar::Joining_None);
+ QVERIFY(QChar::joiningType(0xE0030) == QChar::Joining_Transparent);
+ QVERIFY(QChar::joiningType(0x2FA17) == QChar::Joining_None);
+
+ QVERIFY(QChar::joiningType(0xA872) == QChar::Joining_Left);
+ QVERIFY(QChar::joiningType(0x10ACD) == QChar::Joining_Left);
+ QVERIFY(QChar::joiningType(0x10AD7) == QChar::Joining_Left);
+}
+
+void tst_QChar::combiningClass()
+{
+ QVERIFY(QChar('a').combiningClass() == 0);
+ QVERIFY(QChar('0').combiningClass() == 0);
+ QVERIFY(QChar(0x627).combiningClass() == 0);
+ QVERIFY(QChar(0x5d0).combiningClass() == 0);
+
+ QVERIFY(QChar::combiningClass('a') == 0);
+ QVERIFY(QChar::combiningClass('0') == 0);
+ QVERIFY(QChar::combiningClass(0x627) == 0);
+ QVERIFY(QChar::combiningClass(0x5d0) == 0);
+
+ QVERIFY(QChar::combiningClass(0xE01DA) == 0);
+ QVERIFY(QChar::combiningClass(0xf0000) == 0);
+ QVERIFY(QChar::combiningClass(0xE0030) == 0);
+ QVERIFY(QChar::combiningClass(0x2FA17) == 0);
+
+ QVERIFY(QChar::combiningClass(0x300) == 230);
+
+ QVERIFY(QChar::combiningClass(0x1d244) == 230);
+
+}
+
+void tst_QChar::unicodeVersion()
+{
+ QVERIFY(QChar('a').unicodeVersion() == QChar::Unicode_1_1);
+ QVERIFY(QChar('0').unicodeVersion() == QChar::Unicode_1_1);
+ QVERIFY(QChar(0x627).unicodeVersion() == QChar::Unicode_1_1);
+ QVERIFY(QChar(0x5d0).unicodeVersion() == QChar::Unicode_1_1);
+
+ QVERIFY(QChar::unicodeVersion('a') == QChar::Unicode_1_1);
+ QVERIFY(QChar::unicodeVersion('0') == QChar::Unicode_1_1);
+ QVERIFY(QChar::unicodeVersion(0x627) == QChar::Unicode_1_1);
+ QVERIFY(QChar::unicodeVersion(0x5d0) == QChar::Unicode_1_1);
+
+ QVERIFY(QChar(0x0591).unicodeVersion() == QChar::Unicode_2_0);
+ QVERIFY(QChar::unicodeVersion(0x0591) == QChar::Unicode_2_0);
+
+ QVERIFY(QChar(0x20AC).unicodeVersion() == QChar::Unicode_2_1_2);
+ QVERIFY(QChar::unicodeVersion(0x20AC) == QChar::Unicode_2_1_2);
+ QVERIFY(QChar(0xfffc).unicodeVersion() == QChar::Unicode_2_1_2);
+ QVERIFY(QChar::unicodeVersion(0xfffc) == QChar::Unicode_2_1_2);
+
+ QVERIFY(QChar(0x01f6).unicodeVersion() == QChar::Unicode_3_0);
+ QVERIFY(QChar::unicodeVersion(0x01f6) == QChar::Unicode_3_0);
+
+ QVERIFY(QChar(0x03F4).unicodeVersion() == QChar::Unicode_3_1);
+ QVERIFY(QChar::unicodeVersion(0x03F4) == QChar::Unicode_3_1);
+ QVERIFY(QChar::unicodeVersion(0x10300) == QChar::Unicode_3_1);
+
+ QVERIFY(QChar(0x0220).unicodeVersion() == QChar::Unicode_3_2);
+ QVERIFY(QChar::unicodeVersion(0x0220) == QChar::Unicode_3_2);
+ QVERIFY(QChar::unicodeVersion(0xFF5F) == QChar::Unicode_3_2);
+
+ QVERIFY(QChar(0x0221).unicodeVersion() == QChar::Unicode_4_0);
+ QVERIFY(QChar::unicodeVersion(0x0221) == QChar::Unicode_4_0);
+ QVERIFY(QChar::unicodeVersion(0x10000) == QChar::Unicode_4_0);
+
+ QVERIFY(QChar(0x0237).unicodeVersion() == QChar::Unicode_4_1);
+ QVERIFY(QChar::unicodeVersion(0x0237) == QChar::Unicode_4_1);
+ QVERIFY(QChar::unicodeVersion(0x10140) == QChar::Unicode_4_1);
+
+ QVERIFY(QChar(0x0242).unicodeVersion() == QChar::Unicode_5_0);
+ QVERIFY(QChar::unicodeVersion(0x0242) == QChar::Unicode_5_0);
+ QVERIFY(QChar::unicodeVersion(0x12000) == QChar::Unicode_5_0);
+
+ QVERIFY(QChar(0x0370).unicodeVersion() == QChar::Unicode_5_1);
+ QVERIFY(QChar::unicodeVersion(0x0370) == QChar::Unicode_5_1);
+ QVERIFY(QChar::unicodeVersion(0x1f093) == QChar::Unicode_5_1);
+
+ QVERIFY(QChar(0x0524).unicodeVersion() == QChar::Unicode_5_2);
+ QVERIFY(QChar::unicodeVersion(0x0524) == QChar::Unicode_5_2);
+ QVERIFY(QChar::unicodeVersion(0x2b734) == QChar::Unicode_5_2);
+
+ QVERIFY(QChar(0x26ce).unicodeVersion() == QChar::Unicode_6_0);
+ QVERIFY(QChar::unicodeVersion(0x26ce) == QChar::Unicode_6_0);
+ QVERIFY(QChar::unicodeVersion(0x1f618) == QChar::Unicode_6_0);
+
+ QVERIFY(QChar(0xa69f).unicodeVersion() == QChar::Unicode_6_1);
+ QVERIFY(QChar::unicodeVersion(0xa69f) == QChar::Unicode_6_1);
+ QVERIFY(QChar::unicodeVersion(0x1f600) == QChar::Unicode_6_1);
+
+ QVERIFY(QChar(0x20ba).unicodeVersion() == QChar::Unicode_6_2);
+ QVERIFY(QChar::unicodeVersion(0x20ba) == QChar::Unicode_6_2);
+
+ QVERIFY(QChar(0x061c).unicodeVersion() == QChar::Unicode_6_3);
+ QVERIFY(QChar::unicodeVersion(0x061c) == QChar::Unicode_6_3);
+
+ QVERIFY(QChar(0x20bd).unicodeVersion() == QChar::Unicode_7_0);
+ QVERIFY(QChar::unicodeVersion(0x20bd) == QChar::Unicode_7_0);
+ QVERIFY(QChar::unicodeVersion(0x16b00) == QChar::Unicode_7_0);
+
+ QVERIFY(QChar(0x08b3).unicodeVersion() == QChar::Unicode_8_0);
+ QVERIFY(QChar::unicodeVersion(0x08b3) == QChar::Unicode_8_0);
+ QVERIFY(QChar::unicodeVersion(0x108e0) == QChar::Unicode_8_0);
+
+ QVERIFY(QChar(0x09ff).unicodeVersion() == QChar::Unicode_Unassigned);
+ QVERIFY(QChar::unicodeVersion(0x09ff) == QChar::Unicode_Unassigned);
+ QVERIFY(QChar::unicodeVersion(0x110000) == QChar::Unicode_Unassigned);
+}
+
+void tst_QChar::digitValue()
+{
+ QVERIFY(QChar('9').digitValue() == 9);
+ QVERIFY(QChar('0').digitValue() == 0);
+ QVERIFY(QChar('a').digitValue() == -1);
+
+ QVERIFY(QChar::digitValue('9') == 9);
+ QVERIFY(QChar::digitValue('0') == 0);
+
+ QVERIFY(QChar::digitValue(0x1049) == 9);
+ QVERIFY(QChar::digitValue(0x1040) == 0);
+
+ QVERIFY(QChar::digitValue(0xd800) == -1);
+ QVERIFY(QChar::digitValue(0x110000) == -1);
+}
+
+void tst_QChar::mirroredChar()
+{
+ QVERIFY(QChar(0x169B).hasMirrored());
+ QVERIFY(QChar(0x169B).mirroredChar() == QChar(0x169C));
+ QVERIFY(QChar(0x169C).hasMirrored());
+ QVERIFY(QChar(0x169C).mirroredChar() == QChar(0x169B));
+
+ QVERIFY(QChar(0x301A).hasMirrored());
+ QVERIFY(QChar(0x301A).mirroredChar() == QChar(0x301B));
+ QVERIFY(QChar(0x301B).hasMirrored());
+ QVERIFY(QChar(0x301B).mirroredChar() == QChar(0x301A));
+}
+
+void tst_QChar::decomposition()
+{
+ // Hangul syllables
+ for (uint ucs = 0xac00; ucs <= 0xd7af; ++ucs) {
+ QChar::Decomposition expected = QChar::unicodeVersion(ucs) > QChar::Unicode_Unassigned ? QChar::Canonical : QChar::NoDecomposition;
+ QString desc = QString::fromLatin1("ucs = 0x%1, tag = %2, expected = %3")
+ .arg(QString::number(ucs, 16)).arg(QChar::decompositionTag(ucs)).arg(expected);
+ QVERIFY2(QChar::decompositionTag(ucs) == expected, desc.toLatin1());
+ }
+
+ QVERIFY(QChar(0xa0).decompositionTag() == QChar::NoBreak);
+ QVERIFY(QChar(0xa8).decompositionTag() == QChar::Compat);
+ QVERIFY(QChar(0x41).decompositionTag() == QChar::NoDecomposition);
+
+ QVERIFY(QChar::decompositionTag(0xa0) == QChar::NoBreak);
+ QVERIFY(QChar::decompositionTag(0xa8) == QChar::Compat);
+ QVERIFY(QChar::decompositionTag(0x41) == QChar::NoDecomposition);
+
+ QVERIFY(QChar::decomposition(0xa0) == QString(QChar(0x20)));
+ QVERIFY(QChar::decomposition(0xc0) == (QString(QChar(0x41)) + QString(QChar(0x300))));
+
+ {
+ QString str;
+ str += QChar(QChar::highSurrogate(0x1D157));
+ str += QChar(QChar::lowSurrogate(0x1D157));
+ str += QChar(QChar::highSurrogate(0x1D165));
+ str += QChar(QChar::lowSurrogate(0x1D165));
+ QVERIFY(QChar::decomposition(0x1D15e) == str);
+ }
+
+ {
+ QString str;
+ str += QChar(0x1100);
+ str += QChar(0x1161);
+ QVERIFY(QChar::decomposition(0xac00) == str);
+ }
+ {
+ QString str;
+ str += QChar(0x110c);
+ str += QChar(0x1165);
+ str += QChar(0x11b7);
+ QVERIFY(QChar::decomposition(0xc810) == str);
+ }
+}
+
+void tst_QChar::script()
+{
+ QVERIFY(QChar::script(0x0020) == QChar::Script_Common);
+ QVERIFY(QChar::script(0x0041) == QChar::Script_Latin);
+ QVERIFY(QChar::script(0x0375) == QChar::Script_Greek);
+ QVERIFY(QChar::script(0x0400) == QChar::Script_Cyrillic);
+ QVERIFY(QChar::script(0x0531) == QChar::Script_Armenian);
+ QVERIFY(QChar::script(0x0591) == QChar::Script_Hebrew);
+ QVERIFY(QChar::script(0x0600) == QChar::Script_Arabic);
+ QVERIFY(QChar::script(0x0700) == QChar::Script_Syriac);
+ QVERIFY(QChar::script(0x0780) == QChar::Script_Thaana);
+ QVERIFY(QChar::script(0x07c0) == QChar::Script_Nko);
+ QVERIFY(QChar::script(0x0900) == QChar::Script_Devanagari);
+ QVERIFY(QChar::script(0x0981) == QChar::Script_Bengali);
+ QVERIFY(QChar::script(0x0a01) == QChar::Script_Gurmukhi);
+ QVERIFY(QChar::script(0x0a81) == QChar::Script_Gujarati);
+ QVERIFY(QChar::script(0x0b01) == QChar::Script_Oriya);
+ QVERIFY(QChar::script(0x0b82) == QChar::Script_Tamil);
+ QVERIFY(QChar::script(0x0c01) == QChar::Script_Telugu);
+ QVERIFY(QChar::script(0x0c82) == QChar::Script_Kannada);
+ QVERIFY(QChar::script(0x0d02) == QChar::Script_Malayalam);
+ QVERIFY(QChar::script(0x0d82) == QChar::Script_Sinhala);
+ QVERIFY(QChar::script(0x0e01) == QChar::Script_Thai);
+ QVERIFY(QChar::script(0x0e81) == QChar::Script_Lao);
+ QVERIFY(QChar::script(0x0f00) == QChar::Script_Tibetan);
+ QVERIFY(QChar::script(0x1000) == QChar::Script_Myanmar);
+ QVERIFY(QChar::script(0x10a0) == QChar::Script_Georgian);
+ QVERIFY(QChar::script(0x1100) == QChar::Script_Hangul);
+ QVERIFY(QChar::script(0x1680) == QChar::Script_Ogham);
+ QVERIFY(QChar::script(0x16a0) == QChar::Script_Runic);
+ QVERIFY(QChar::script(0x1780) == QChar::Script_Khmer);
+ QVERIFY(QChar::script(0x200c) == QChar::Script_Inherited);
+ QVERIFY(QChar::script(0x200d) == QChar::Script_Inherited);
+ QVERIFY(QChar::script(0x1018a) == QChar::Script_Greek);
+ QVERIFY(QChar::script(0x1f130) == QChar::Script_Common);
+ QVERIFY(QChar::script(0xe0100) == QChar::Script_Inherited);
+}
+
+// wasm is limited in reading filesystems, so omit this test for now
+#if !defined(Q_OS_WASM)
+void tst_QChar::normalization_data()
+{
+ QTest::addColumn<QStringList>("columns");
+ QTest::addColumn<int>("part");
+
+ int linenum = 0;
+ int part = 0;
+
+ QString testFile = QFINDTESTDATA("data/NormalizationTest.txt");
+ QVERIFY2(!testFile.isEmpty(), "data/NormalizationTest.txt not found!");
+ QFile f(testFile);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+
+ while (!f.atEnd()) {
+ linenum++;
+
+ QByteArray line;
+ line.resize(1024);
+ int len = f.readLine(line.data(), 1024);
+ line.resize(len-1);
+
+ int comment = line.indexOf('#');
+ if (comment >= 0)
+ line = line.left(comment);
+
+ if (line.startsWith('@')) {
+ if (line.startsWith("@Part") && line.size() > 5 && QChar(line.at(5)).isDigit())
+ part = QChar(line.at(5)).digitValue();
+ continue;
+ }
+
+ if (line.isEmpty())
+ continue;
+
+ line = line.trimmed();
+ if (line.endsWith(';'))
+ line.truncate(line.size()-1);
+
+ QList<QByteArray> l = line.split(';');
+
+ QCOMPARE(l.size(), 5);
+
+ QStringList columns;
+ for (int i = 0; i < 5; ++i) {
+ columns.append(QString());
+
+ QList<QByteArray> c = l.at(i).split(' ');
+ QVERIFY(!c.isEmpty());
+
+ for (int j = 0; j < c.size(); ++j) {
+ bool ok;
+ uint uc = c.at(j).toInt(&ok, 16);
+ columns[i].append(QChar::fromUcs4(uc));
+ }
+ }
+
+
+ const QByteArray nm = "line #" + QByteArray::number(linenum) + " (part "
+ + QByteArray::number(part);
+ QTest::newRow(nm.constData()) << columns << part;
+ }
+}
+
+void tst_QChar::normalization()
+{
+ QFETCH(QStringList, columns);
+ QFETCH(int, part);
+
+ Q_UNUSED(part);
+
+ // CONFORMANCE:
+ // 1. The following invariants must be true for all conformant implementations
+ //
+ // NFC
+ // c2 == NFC(c1) == NFC(c2) == NFC(c3)
+ // c4 == NFC(c4) == NFC(c5)
+
+ QVERIFY(columns[1] == columns[0].normalized(QString::NormalizationForm_C));
+ QVERIFY(columns[1] == columns[1].normalized(QString::NormalizationForm_C));
+ QVERIFY(columns[1] == columns[2].normalized(QString::NormalizationForm_C));
+ QVERIFY(columns[3] == columns[3].normalized(QString::NormalizationForm_C));
+ QVERIFY(columns[3] == columns[4].normalized(QString::NormalizationForm_C));
+
+ // NFD
+ // c3 == NFD(c1) == NFD(c2) == NFD(c3)
+ // c5 == NFD(c4) == NFD(c5)
+
+ QVERIFY(columns[2] == columns[0].normalized(QString::NormalizationForm_D));
+ QVERIFY(columns[2] == columns[1].normalized(QString::NormalizationForm_D));
+ QVERIFY(columns[2] == columns[2].normalized(QString::NormalizationForm_D));
+ QVERIFY(columns[4] == columns[3].normalized(QString::NormalizationForm_D));
+ QVERIFY(columns[4] == columns[4].normalized(QString::NormalizationForm_D));
+
+ // NFKC
+ // c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5)
+
+ QVERIFY(columns[3] == columns[0].normalized(QString::NormalizationForm_KC));
+ QVERIFY(columns[3] == columns[1].normalized(QString::NormalizationForm_KC));
+ QVERIFY(columns[3] == columns[2].normalized(QString::NormalizationForm_KC));
+ QVERIFY(columns[3] == columns[3].normalized(QString::NormalizationForm_KC));
+ QVERIFY(columns[3] == columns[4].normalized(QString::NormalizationForm_KC));
+
+ // NFKD
+ // c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5)
+
+ QVERIFY(columns[4] == columns[0].normalized(QString::NormalizationForm_KD));
+ QVERIFY(columns[4] == columns[1].normalized(QString::NormalizationForm_KD));
+ QVERIFY(columns[4] == columns[2].normalized(QString::NormalizationForm_KD));
+ QVERIFY(columns[4] == columns[3].normalized(QString::NormalizationForm_KD));
+ QVERIFY(columns[4] == columns[4].normalized(QString::NormalizationForm_KD));
+
+ // 2. For every code point X assigned in this version of Unicode that is not specifically
+ // listed in Part 1, the following invariants must be true for all conformant
+ // implementations:
+ //
+ // X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X)
+
+ // #################
+
+}
+#endif // !defined(Q_OS_WASM)
+
+void tst_QChar::normalization_manual()
+{
+ {
+ QString decomposed;
+ decomposed += QChar(0x41);
+ decomposed += QChar(0x0221); // assigned in 4.0
+ decomposed += QChar(0x300);
+
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_C, QChar::Unicode_3_2) == decomposed);
+
+ decomposed[1] = QChar(0x037f); // unassigned in 6.1
+
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_C) == decomposed);
+ }
+ {
+ QString composed;
+ composed += QChar(0xc0);
+ QString decomposed;
+ decomposed += QChar(0x41);
+ decomposed += QChar(0x300);
+
+ QVERIFY(composed.normalized(QString::NormalizationForm_D) == decomposed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_KC) == composed);
+ }
+ {
+ QString composed;
+ composed += QChar(0xa0);
+ QString decomposed;
+ decomposed += QChar(0x20);
+
+ QVERIFY(composed.normalized(QString::NormalizationForm_D) == composed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_KC) == decomposed);
+ }
+ {
+ QString composed;
+ composed += QChar(0x0061);
+ composed += QChar(0x00f2);
+ QString decomposed;
+ decomposed += QChar(0x0061);
+ decomposed += QChar(0x006f);
+ decomposed += QChar(0x0300);
+
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_D) == decomposed);
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_C) == composed);
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_KD) == decomposed);
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_KC) == composed);
+ }
+ { // hangul
+ QString composed;
+ composed += QChar(0xc154);
+ composed += QChar(0x11f0);
+ QString decomposed;
+ decomposed += QChar(0x1109);
+ decomposed += QChar(0x1167);
+ decomposed += QChar(0x11f0);
+
+ QVERIFY(composed.normalized(QString::NormalizationForm_D) == decomposed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed);
+ QVERIFY(composed.normalized(QString::NormalizationForm_KC) == composed);
+
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_D) == decomposed);
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_C) == composed);
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_KD) == decomposed);
+ QVERIFY(decomposed.normalized(QString::NormalizationForm_KC) == composed);
+ }
+ // QTBUG-71894 - erratum fixed in Unicode 4.1.0; SCount bounds are < not <=
+ {
+ // Hangul compose, test 0x11a7:
+ const QChar c[] = { QChar(0xae30), QChar(0x11a7), {} };
+ const QChar d[] = { QChar(0x1100), QChar(0x1175), QChar(0x11a7), {} };
+ const QString composed(c, 2);
+ const QString decomposed(d, 3);
+
+ QCOMPARE(decomposed.normalized(QString::NormalizationForm_C), composed);
+ }
+ {
+ // Hangul compose, test 0x11c3:
+ const QChar c[] = { QChar(0xae30), QChar(0x11c3), {} };
+ const QChar d[] = { QChar(0x1100), QChar(0x1175), QChar(0x11c3), {} };
+ const QString composed(c, 2);
+ const QString decomposed(d, 3);
+
+ QCOMPARE(decomposed.normalized(QString::NormalizationForm_C), composed);
+ }
+}
+
+void tst_QChar::normalizationCorrections()
+{
+ QString s;
+ s.append(QChar(0xf951));
+
+ QString n = s.normalized(QString::NormalizationForm_D);
+ QString res;
+ res.append(QChar(0x964b));
+ QCOMPARE(n, res);
+
+ n = s.normalized(QString::NormalizationForm_D, QChar::Unicode_3_1);
+ res.clear();
+ res.append(QChar(0x96fb));
+ QCOMPARE(n, res);
+
+ s.clear();
+ s += QChar(QChar::highSurrogate(0x2f868));
+ s += QChar(QChar::lowSurrogate(0x2f868));
+
+ n = s.normalized(QString::NormalizationForm_C);
+ res.clear();
+ res += QChar(0x36fc);
+ QCOMPARE(n, res);
+
+ n = s.normalized(QString::NormalizationForm_C, QChar::Unicode_3_1);
+ res.clear();
+ res += QChar(0xd844);
+ res += QChar(0xdf6a);
+ QCOMPARE(n, res);
+
+ n = s.normalized(QString::NormalizationForm_C, QChar::Unicode_3_2);
+ QCOMPARE(n, res);
+}
+
+
+QTEST_APPLESS_MAIN(tst_QChar)
+#include "tst_qchar.moc"
diff --git a/tests/auto/corelib/text/qcollator/CMakeLists.txt b/tests/auto/corelib/text/qcollator/CMakeLists.txt
new file mode 100644
index 0000000000..c9f5f0e9ca
--- /dev/null
+++ b/tests/auto/corelib/text/qcollator/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcollator Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcollator LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcollator
+ SOURCES
+ tst_qcollator.cpp
+ DEFINES
+ QT_NO_CAST_TO_ASCII
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/text/qcollator/tst_qcollator.cpp b/tests/auto/corelib/text/qcollator/tst_qcollator.cpp
new file mode 100644
index 0000000000..b6da8a3899
--- /dev/null
+++ b/tests/auto/corelib/text/qcollator/tst_qcollator.cpp
@@ -0,0 +1,354 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <qlocale.h>
+#include <qcollator.h>
+#include <private/qglobal_p.h>
+#include <QScopeGuard>
+
+#include <cstring>
+#include <iostream>
+
+class tst_QCollator : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void basics();
+ void moveSemantics();
+
+ void compare_data();
+ void compare();
+
+ void state();
+};
+
+static bool dpointer_is_null(QCollator &c)
+{
+ char mem[sizeof c];
+ using namespace std;
+ memcpy(mem, &c, sizeof c);
+ for (size_t i = 0; i < sizeof c; ++i)
+ if (mem[i])
+ return false;
+ return true;
+}
+
+void tst_QCollator::basics()
+{
+ const QLocale de_AT(QLocale::German, QLocale::Austria);
+
+ QCollator c1(de_AT);
+ QCOMPARE(c1.locale(), de_AT);
+
+ QCollator c2(c1);
+ QCOMPARE(c2.locale(), de_AT);
+
+ QCollator c3;
+ // Test copy assignment
+ c3 = c2;
+ QCOMPARE(c3.locale(), de_AT);
+
+ // posix implementation supports only C and default locale,
+ // so update it for Android and INTEGRITY builds
+#if !QT_CONFIG(icu) && !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
+ c3.setLocale(QLocale());
+#endif
+ QCollatorSortKey key1 = c3.sortKey("test");
+
+ QCollatorSortKey key2(key1);
+ QCOMPARE(key1.compare(key2), 0);
+
+ QCollatorSortKey key3 = c3.sortKey("abc");
+ // Test copy assignment
+ key3 = key2;
+ QCOMPARE(key1.compare(key3), 0);
+}
+
+void tst_QCollator::moveSemantics()
+{
+ const QLocale de_AT(QLocale::German, QLocale::Austria);
+
+ QCollator c1(de_AT);
+ QCOMPARE(c1.locale(), de_AT);
+
+ QCollator c2(std::move(c1));
+ QCOMPARE(c2.locale(), de_AT);
+ QVERIFY(dpointer_is_null(c1));
+
+ QCollator c3(c1);
+ QVERIFY(dpointer_is_null(c3));
+
+ c1 = std::move(c2);
+ QCOMPARE(c1.locale(), de_AT);
+ QVERIFY(dpointer_is_null(c2));
+
+ // test QCollatorSortKey move assignment
+ // posix implementation supports only C and default locale,
+ // so update it for Android and INTEGRITY builds
+#if !QT_CONFIG(icu) && !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
+ c1.setLocale(QLocale());
+#endif
+ QCollatorSortKey key1 = c1.sortKey("1");
+ QCollatorSortKey key2 = c1.sortKey("2");
+ QVERIFY(key1.compare(key2) < 0);
+
+ QCollatorSortKey key3 = c1.sortKey("a");
+ // test move assignment
+ key3 = std::move(key2);
+ QVERIFY(key1.compare(key3) < 0);
+}
+
+
+void tst_QCollator::compare_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<QString>("s2");
+ QTest::addColumn<int>("result");
+ QTest::addColumn<int>("caseInsensitiveResult");
+ QTest::addColumn<bool>("numericMode");
+ QTest::addColumn<bool>("ignorePunctuation");
+ QTest::addColumn<int>("punctuationResult"); // Test ignores punctuation *and case*
+
+ /*
+ It's hard to test English, because it's treated differently
+ on different platforms. For example, on Linux, it uses the
+ iso14651_t1 template file, which happens to provide good
+ defaults for Swedish. OS X seems to do a pure bytewise
+ comparison of Latin-1 values, although I'm not sure. So I
+ just test digits to make sure that it's not totally broken.
+ */
+ QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1 << 1 << false << false << 1;
+ QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1 << -1 << false << false << -1;
+ QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1 << -1 << false << false << -1;
+ QTest::newRow("english4") << QString("en_US") << QString("a") << QString("b") << -1 << -1 << false << false << -1;
+ QTest::newRow("english5") << QString("en_US") << QString("test 9") << QString("test 19") << -1 << -1 << true << false << -1;
+ QTest::newRow("english6") << QString("en_US") << QString("test 9") << QString("test_19") << -1 << -1 << true << true << -1;
+ QTest::newRow("english7") << QString("en_US") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
+ QTest::newRow("english8") << QString("en_US") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
+ QTest::newRow("en-empty-word") << QString("en_US") << QString() << QString("non-empty") << -1 << -1 << false << true << -1;
+ QTest::newRow("en-empty-number") << QString("en_US") << QString() << QString("42") << -1 << -1 << true << true << -1;
+ QTest::newRow("en-word-empty") << QString("en_US") << QString("non-empty") << QString() << 1
+ << 1 << false << true << 1;
+ QTest::newRow("en-number-empty")
+ << QString("en_US") << QString("42") << QString() << 1 << 1 << true << true << 1;
+ QTest::newRow("en-empty-empty")
+ << QString("en_US") << QString() << QString() << 0 << 0 << false << true << 0;
+
+ /*
+ In Swedish, a with ring above (E5) comes before a with
+ diaresis (E4), which comes before o diaresis (F6), which
+ all come after z.
+ */
+ QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1 << -1 << false << false << -1;
+ QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
+ QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
+ QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
+ QTest::newRow("swedish5") << QString("sv_SE") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
+ QTest::newRow("swedish6") << QString("sv_SE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
+ QTest::newRow("swedish7") << QString("sv_SE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
+ QTest::newRow("swedish8") << QString("sv_SE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
+ QTest::newRow("sv-empty-word") << QString("sv_SE") << QString() << QString("mett") << -1 << -1 << false << true << -1;
+ QTest::newRow("sv-empty-number") << QString("sv_SE") << QString() << QString("42") << -1 << -1 << true << true << -1;
+ QTest::newRow("sv-word-empty")
+ << QString("sv_SE") << QString("mett") << QString() << 1 << 1 << false << true << 1;
+ QTest::newRow("sv-number-empty")
+ << QString("sv_SE") << QString("42") << QString() << 1 << 1 << true << true << 1;
+ QTest::newRow("sv-empty-empty")
+ << QString("sv_SE") << QString() << QString() << 0 << 0 << false << true << 0;
+
+ /*
+ In Norwegian, ae (E6) comes before o with stroke (D8), which
+ comes before a with ring above (E5).
+ */
+ QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1 << -1 << false << false << -1;
+ QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
+ QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
+ QTest::newRow("norwegian4") << QString("no_NO") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
+ QTest::newRow("norwegian5") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
+ QTest::newRow("norwegian6") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
+ QTest::newRow("norwegian7") << QString("no_NO") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
+ QTest::newRow("norwegian8") << QString("no_NO") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
+ QTest::newRow("nb-empty-word") << QString("nb_NO") << QString() << QString("mett") << -1 << -1 << false << true << -1;
+ QTest::newRow("nb-empty-number") << QString("nb_NO") << QString() << QString("42") << -1 << -1 << true << true << -1;
+ QTest::newRow("nb-word-empty")
+ << QString("nb_NO") << QString("mett") << QString() << 1 << 1 << false << true << 1;
+ QTest::newRow("nb-number-empty")
+ << QString("nb_NO") << QString("42") << QString() << 1 << 1 << true << true << 1;
+ QTest::newRow("nb-empty-empty")
+ << QString("nb_NO") << QString() << QString() << 0 << 0 << false << true << 0;
+
+ /*
+ In German, z comes *after* a with diaresis (E4),
+ which comes before o diaresis (F6).
+ */
+ QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("a") << QString::fromLatin1("\xe4") << -1 << -1 << false << false << -1;
+ QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("b") << QString::fromLatin1("\xe4") << 1 << 1 << false << false << 1;
+ QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1 << 1 << false << false << 1;
+ QTest::newRow("german4") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
+ QTest::newRow("german5") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1 << 1 << false << false << 1;
+ QTest::newRow("german6") << QString("de_DE") << QString::fromLatin1("\xc0") << QString::fromLatin1("\xe0") << 1 << 0 << false << false << 0;
+ QTest::newRow("german7") << QString("de_DE") << QString::fromLatin1("\xd6") << QString::fromLatin1("\xf6") << 1 << 0 << false << false << 0;
+ QTest::newRow("german8") << QString("de_DE") << QString::fromLatin1("oe") << QString::fromLatin1("\xf6") << 1 << 1 << false << false << 1;
+ QTest::newRow("german9") << QString("de_DE") << QString("A") << QString("a") << 1 << 0 << false << false << 0;
+ QTest::newRow("german10") << QString("de_DE") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
+ QTest::newRow("german11") << QString("de_DE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
+ QTest::newRow("german12") << QString("de_DE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
+ QTest::newRow("german13") << QString("de_DE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
+ QTest::newRow("de-empty-word") << QString("de_DE") << QString() << QString("satt") << -1 << -1 << false << true << -1;
+ QTest::newRow("de-empty-number") << QString("de_DE") << QString() << QString("42") << -1 << -1 << true << true << -1;
+ QTest::newRow("de-word-empty")
+ << QString("de_DE") << QString("satt") << QString() << 1 << 1 << false << true << 1;
+ QTest::newRow("de-number-empty")
+ << QString("de_DE") << QString("42") << QString() << 1 << 1 << true << true << 1;
+ QTest::newRow("de-empty-empty")
+ << QString("de_DE") << QString() << QString() << 0 << 0 << false << true << 0;
+
+ /*
+ French sorting of e and e with acute accent
+ */
+ QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1 << false << false << 1;
+ QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1 << false << false << 1;
+ QTest::newRow("french3") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("d") << 1 << 1 << false << false << 1;
+ QTest::newRow("french4") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("f") << -1 << -1 << false << false << -1;
+ QTest::newRow("french5") << QString("fr_FR") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
+ QTest::newRow("french6") << QString("fr_FR") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
+ QTest::newRow("french7") << QString("fr_FR") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
+ QTest::newRow("french8") << QString("fr_FR") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
+ QTest::newRow("fr-empty-word") << QString("fr_FR") << QString() << QString("plein") << -1 << -1 << false << true << -1;
+ QTest::newRow("fr-empty-number") << QString("fr_FR") << QString() << QString("42") << -1 << -1 << true << true << -1;
+ QTest::newRow("fr-word-empty")
+ << QString("fr_FR") << QString("plein") << QString() << 1 << 1 << false << true << 1;
+ QTest::newRow("fr-number-empty")
+ << QString("fr_FR") << QString("42") << QString() << 1 << 1 << true << true << 1;
+ QTest::newRow("fr-empty-empty")
+ << QString("fr_FR") << QString() << QString() << 0 << 0 << false << true << 0;
+
+ // C locale: case sensitive [A-Z] < [a-z] but case insensitive [Aa] < [Bb] <...< [Zz]
+ const QString C = QStringLiteral("C");
+ QTest::newRow("C:ABBA:AaaA") << C << QStringLiteral("ABBA") << QStringLiteral("AaaA") << -1 << 1 << false << false << 1;
+ QTest::newRow("C:AZa:aAZ") << C << QStringLiteral("AZa") << QStringLiteral("aAZ") << -1 << 1 << false << false << 1;
+ QTest::newRow("C-empty-word") << QString(C) << QString() << QString("non-empty") << -1 << -1 << false << true << -1;
+ QTest::newRow("C-empty-number") << QString(C) << QString() << QString("42") << -1 << -1 << true << true << -1;
+ QTest::newRow("C-word-empty") << QString(C) << QString("non-empty") << QString() << 1 << 1
+ << false << true << 1;
+ QTest::newRow("C-number-empty")
+ << QString(C) << QString("42") << QString() << 1 << 1 << true << true << 1;
+ QTest::newRow("C-empty-empty")
+ << QString(C) << QString() << QString() << 0 << 0 << false << true << 0;
+}
+
+void tst_QCollator::compare()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, s1);
+ QFETCH(QString, s2);
+ QFETCH(int, result);
+ QFETCH(int, caseInsensitiveResult);
+ QFETCH(bool, numericMode);
+ QFETCH(bool, ignorePunctuation);
+ QFETCH(int, punctuationResult);
+
+ QCollator collator((QLocale(locale)));
+
+ // AFTER the QCollator initialization
+ auto localechanger = qScopeGuard([original = QLocale()] {
+ QLocale::setDefault(original); // reset back to what it was
+ });
+ QLocale::setDefault(QLocale(locale));
+
+ // Need to canonicalize sign to -1, 0 or 1, as .compare() can produce any -ve for <, any +ve for >.
+ auto asSign = [](int compared) {
+ return compared < 0 ? -1 : compared > 0 ? 1 : 0;
+ };
+#if defined(Q_OS_WASM)
+ if (strcmp(QTest::currentDataTag(), "english5") == 0
+ || strcmp(QTest::currentDataTag(), "english8") == 0)
+ QSKIP("Some en-us locale tests have issues on WASM");
+#endif // Q_OS_WASM
+#if !QT_CONFIG(icu) && !defined(Q_OS_WIN) && !defined(Q_OS_MACOS)
+ if (collator.locale() != QLocale::c() && collator.locale() != QLocale::system().collation())
+ QSKIP("POSIX implementation of collation only supports C and system collation locales");
+#endif
+
+ if (numericMode)
+ collator.setNumericMode(true);
+
+ [[maybe_unused]] int keyCompareResult = result;
+ [[maybe_unused]] int keyCompareCaseInsensitiveResult = caseInsensitiveResult;
+ [[maybe_unused]] int keyComparePunctuationResultResult = punctuationResult;
+
+ // trying to deal with special behavior of different OS-dependent collators
+ if (collator.locale() == QLocale("C")) {
+#if !QT_CONFIG(icu) && defined(Q_OS_MACOS)
+ // for MACOS C-locale is not supported, always providing empty string for sortKey()
+ keyCompareResult = 0;
+ keyCompareCaseInsensitiveResult = 0;
+ keyComparePunctuationResultResult = 0;
+#else
+ // for other platforms C-locale strings are not modified by sortKey() anyhow
+ keyCompareCaseInsensitiveResult = keyCompareResult;
+ keyComparePunctuationResultResult = keyCompareResult;
+#endif
+ }
+
+ // NOTE: currently QCollatorSortKey::compare is not working
+ // properly without icu: see QTBUG-88704 for details
+ QCOMPARE(asSign(collator.compare(s1, s2)), result);
+ if (!numericMode)
+ QCOMPARE(asSign(QCollator::defaultCompare(s1, s2)), result);
+#if QT_CONFIG(icu)
+ auto key1 = collator.sortKey(s1);
+ auto key2 = collator.sortKey(s2);
+ QCOMPARE(asSign(key1.compare(key2)), keyCompareResult);
+
+ key1 = QCollator::defaultSortKey(s1);
+ key2 = QCollator::defaultSortKey(s2);
+ if (!numericMode)
+ QCOMPARE(asSign(key1.compare(key2)), keyCompareResult);
+#endif
+ collator.setCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(asSign(collator.compare(s1, s2)), caseInsensitiveResult);
+#if QT_CONFIG(icu)
+ key1 = collator.sortKey(s1);
+ key2 = collator.sortKey(s2);
+ QCOMPARE(asSign(key1.compare(key2)), keyCompareCaseInsensitiveResult);
+#endif
+ collator.setIgnorePunctuation(ignorePunctuation);
+ QCOMPARE(asSign(collator.compare(s1, s2)), punctuationResult);
+#if QT_CONFIG(icu)
+ key1 = collator.sortKey(s1);
+ key2 = collator.sortKey(s2);
+ QCOMPARE(asSign(key1.compare(key2)), keyComparePunctuationResultResult);
+#endif
+}
+
+
+void tst_QCollator::state()
+{
+ QCollator c;
+ c.setCaseSensitivity(Qt::CaseInsensitive);
+ c.setLocale(QLocale::German);
+
+ c.compare(QString("a"), QString("b"));
+
+ QCOMPARE(c.caseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(c.locale(), QLocale(QLocale::German));
+
+ c.setLocale(QLocale::French);
+ c.setNumericMode(true);
+ c.setIgnorePunctuation(true);
+ c.setLocale(QLocale::NorwegianBokmal);
+
+ QCOMPARE(c.caseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(c.numericMode(), true);
+ QCOMPARE(c.ignorePunctuation(), true);
+ QCOMPARE(c.locale(), QLocale(QLocale::NorwegianBokmal));
+}
+
+QTEST_APPLESS_MAIN(tst_QCollator)
+
+#include "tst_qcollator.moc"
diff --git a/tests/auto/corelib/text/qlatin1stringmatcher/CMakeLists.txt b/tests/auto/corelib/text/qlatin1stringmatcher/CMakeLists.txt
new file mode 100644
index 0000000000..19db9fc07a
--- /dev/null
+++ b/tests/auto/corelib/text/qlatin1stringmatcher/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qlatin1sgtringmatcher Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlatin1stringmatcher LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qlatin1stringmatcher
+ SOURCES
+ tst_qlatin1stringmatcher.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp
new file mode 100644
index 0000000000..82e12bdfca
--- /dev/null
+++ b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp
@@ -0,0 +1,567 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <QtCore/QLatin1StringMatcher>
+#include <QtCore/QStaticLatin1StringMatcher>
+
+#include <numeric>
+#include <string>
+
+#include <thread>
+
+// COM interface
+#if defined(interface)
+# undef interface
+#endif
+
+using namespace Qt::Literals::StringLiterals;
+
+class tst_QLatin1StringMatcher : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void overloads();
+ void staticOverloads();
+ void interface();
+ void indexIn();
+ void haystacksWithMoreThan4GiBWork();
+ void staticLatin1StringMatcher();
+};
+
+void tst_QLatin1StringMatcher::overloads()
+{
+ QLatin1StringView hello = "hello"_L1;
+ QByteArray hello2B = QByteArrayView(hello).toByteArray().repeated(2);
+ QLatin1StringView hello2(hello2B);
+ {
+ QLatin1StringMatcher m("hello"_L1, Qt::CaseSensitive);
+ QCOMPARE(m.pattern(), "hello"_L1);
+ QCOMPARE(m.indexIn("hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hello"_L1), -1);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 5);
+ QCOMPARE(m.indexIn("helloHello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1, 1), -1);
+ }
+ {
+ QLatin1StringMatcher m("Hello"_L1, Qt::CaseSensitive);
+ QCOMPARE(m.pattern(), "Hello"_L1);
+ QCOMPARE(m.indexIn("hello"_L1), -1);
+ QCOMPARE(m.indexIn("Hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1), 5);
+ QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
+ }
+ {
+ QLatin1StringMatcher m("hello"_L1, Qt::CaseInsensitive);
+ QCOMPARE(m.pattern(), "hello"_L1);
+ QCOMPARE(m.indexIn("hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
+ QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
+ }
+ {
+ QLatin1StringMatcher m("Hello"_L1, Qt::CaseInsensitive);
+ QCOMPARE(m.pattern(), "Hello"_L1);
+ QCOMPARE(m.indexIn("hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
+ QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
+ }
+ {
+ QLatin1StringMatcher m(hello, Qt::CaseSensitive);
+ QCOMPARE(m.pattern(), "hello"_L1);
+ QCOMPARE(m.indexIn(hello), 0);
+ QCOMPARE(m.indexIn(hello, 1), -1);
+ QCOMPARE(m.indexIn(hello2, 1), hello.size());
+ QCOMPARE(m.indexIn(hello2, 6), -1);
+ }
+}
+
+void tst_QLatin1StringMatcher::staticOverloads()
+{
+#ifdef QT_STATIC_BOYER_MOORE_NOT_SUPPORTED
+ QSKIP("Test is only valid on an OS that supports static latin1 string matcher");
+#else
+ constexpr QLatin1StringView hello = "hello"_L1;
+ QByteArray hello2B = QByteArrayView(hello).toByteArray().repeated(2);
+ QLatin1StringView hello2(hello2B);
+ {
+ static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("hel");
+ QCOMPARE(m.indexIn("hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hello"_L1), -1);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 5);
+ QCOMPARE(m.indexIn("helloHello"_L1), 0);
+ QCOMPARE(m.indexIn("he"_L1), -1);
+ QCOMPARE(m.indexIn("hel"_L1), 0);
+ QCOMPARE(m.indexIn(hello), 0);
+ QCOMPARE(m.indexIn(hello, 1), -1); // from is 1
+ QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2
+ QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3
+ QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
+ static_assert(m.indexIn("hello"_L1) == 0);
+ static_assert(m.indexIn("Hello"_L1) == -1);
+ static_assert(m.indexIn("Hellohello"_L1) == 5);
+ static_assert(m.indexIn("helloHello"_L1) == 0);
+ static_assert(m.indexIn("he"_L1) == -1);
+ static_assert(m.indexIn("hel"_L1) == 0);
+ static_assert(m.indexIn("hellohello"_L1, 2) == 5); // from is 2
+ static_assert(m.indexIn("hellohello"_L1, 3) == 5); // from is 3
+ static_assert(m.indexIn("hellohello"_L1, 6) == -1); // from is 6
+ }
+ {
+ static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("Hel");
+ QCOMPARE(m.indexIn("hello"_L1), -1);
+ QCOMPARE(m.indexIn("Hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1), 5);
+ QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
+ QCOMPARE(m.indexIn("He"_L1), -1);
+ QCOMPARE(m.indexIn("Hel"_L1), 0);
+ QCOMPARE(m.indexIn(hello), -1);
+ QCOMPARE(m.indexIn(hello2, 2), -1); // from is 2
+ QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
+ static_assert(m.indexIn("hello"_L1) == -1);
+ static_assert(m.indexIn("Hello"_L1) == 0);
+ static_assert(m.indexIn("Hellohello"_L1) == 0);
+ static_assert(m.indexIn("helloHello"_L1) == 5);
+ static_assert(m.indexIn("helloHello"_L1, 6) == -1);
+ static_assert(m.indexIn("He"_L1) == -1);
+ static_assert(m.indexIn("Hel"_L1) == 0);
+ static_assert(m.indexIn("hellohello"_L1, 2) == -1); // from is 2
+ static_assert(m.indexIn("hellohello"_L1, 6) == -1); // from is 6
+ }
+ {
+ static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("hel");
+ QCOMPARE(m.indexIn("hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1), 0);
+ QCOMPARE(m.indexIn("he"_L1), -1);
+ QCOMPARE(m.indexIn("hel"_L1), 0);
+ QCOMPARE(m.indexIn(hello), 0);
+ QCOMPARE(m.indexIn(hello, 1), -1);
+ QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2
+ QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3
+ QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
+ static_assert(m.indexIn("hello"_L1) == 0);
+ static_assert(m.indexIn("Hello"_L1) == 0);
+ static_assert(m.indexIn("Hellohello"_L1) == 0);
+ static_assert(m.indexIn("helloHello"_L1) == 0);
+ static_assert(m.indexIn("he"_L1) == -1);
+ static_assert(m.indexIn("hel"_L1) == 0);
+ static_assert(m.indexIn("hellohello"_L1, 2) == 5); // from is 2
+ static_assert(m.indexIn("hellohello"_L1, 3) == 5); // from is 3
+ static_assert(m.indexIn("hellohello"_L1, 6) == -1); // from is 6
+ }
+ {
+ static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("Hel");
+ QCOMPARE(m.indexIn("hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hello"_L1), 0);
+ QCOMPARE(m.indexIn("Hellohello"_L1), 0);
+ QCOMPARE(m.indexIn("helloHello"_L1), 0);
+ QCOMPARE(m.indexIn("he"_L1), -1);
+ QCOMPARE(m.indexIn("hel"_L1), 0);
+ QCOMPARE(m.indexIn(hello), 0);
+ QCOMPARE(m.indexIn(hello, 1), -1);
+ QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2
+ QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3
+ QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
+ static_assert(m.indexIn("hello"_L1) == 0);
+ static_assert(m.indexIn("Hello"_L1) == 0);
+ static_assert(m.indexIn("Hellohello"_L1) == 0);
+ static_assert(m.indexIn("helloHello"_L1) == 0);
+ static_assert(m.indexIn("he"_L1) == -1);
+ static_assert(m.indexIn("hel"_L1) == 0);
+ static_assert(m.indexIn("hellohello"_L1, 2) == 5); // from is 2
+ static_assert(m.indexIn("hellohello"_L1, 3) == 5); // from is 3
+ static_assert(m.indexIn("hellohello"_L1, 6) == -1); // from is 6
+ }
+ {
+ static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("b\xF8");
+ QCOMPARE(m.indexIn("B\xD8"_L1), 0);
+ QCOMPARE(m.indexIn("B\xF8"_L1), 0);
+ QCOMPARE(m.indexIn("b\xD8"_L1), 0);
+ QCOMPARE(m.indexIn("b\xF8"_L1), 0);
+ QCOMPARE(m.indexIn("b\xF8lle"_L1), 0);
+ QCOMPARE(m.indexIn("m\xF8lle"_L1), -1);
+ QCOMPARE(m.indexIn("Si b\xF8"_L1), 3);
+ }
+ {
+ static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("b\xF8");
+ QCOMPARE(m.indexIn("B\xD8"_L1), -1);
+ QCOMPARE(m.indexIn("B\xF8"_L1), -1);
+ QCOMPARE(m.indexIn("b\xD8"_L1), -1);
+ QCOMPARE(m.indexIn("b\xF8"_L1), 0);
+ QCOMPARE(m.indexIn("b\xF8lle"_L1), 0);
+ QCOMPARE(m.indexIn("m\xF8lle"_L1), -1);
+ QCOMPARE(m.indexIn("Si b\xF8"_L1), 3);
+ }
+#endif
+}
+
+void tst_QLatin1StringMatcher::interface()
+{
+ QLatin1StringView needle = "abc123"_L1;
+ QByteArray haystackT(500, 'a');
+ haystackT.insert(6, "123");
+ haystackT.insert(31, "abc");
+ haystackT.insert(42, "abc123");
+ haystackT.insert(84, "abc123");
+ QLatin1StringView haystack(haystackT);
+
+ QLatin1StringMatcher matcher1;
+
+ matcher1 = QLatin1StringMatcher(needle, Qt::CaseSensitive);
+ QLatin1StringMatcher matcher2;
+ matcher2.setPattern(needle);
+
+ QLatin1StringMatcher matcher3 = QLatin1StringMatcher(needle, Qt::CaseSensitive);
+ QLatin1StringMatcher matcher4;
+ matcher4 = matcher3;
+
+ QCOMPARE(matcher1.indexIn(haystack), 42);
+ QCOMPARE(matcher2.indexIn(haystack), 42);
+ QCOMPARE(matcher3.indexIn(haystack), 42);
+ QCOMPARE(matcher4.indexIn(haystack), 42);
+
+ QCOMPARE(matcher1.indexIn(haystack, 43), 84);
+ QCOMPARE(matcher1.indexIn(haystack, 85), -1);
+
+ QLatin1StringMatcher matcher5("123"_L1, Qt::CaseSensitive);
+ QCOMPARE(matcher5.indexIn(haystack), 6);
+
+ matcher5 = QLatin1StringMatcher("abc"_L1, Qt::CaseSensitive);
+ QCOMPARE(matcher5.indexIn(haystack), 31);
+
+ matcher5.setPattern(matcher4.pattern());
+ QCOMPARE(matcher5.indexIn(haystack), 42);
+
+ QLatin1StringMatcher matcher6 = matcher5;
+ QCOMPARE(matcher6.indexIn(haystack), 42);
+
+ QLatin1StringMatcher matcher7 = std::move(matcher5);
+ QCOMPARE(matcher7.indexIn(haystack), 42);
+
+ matcher1.setPattern("123"_L1);
+ matcher7 = std::move(matcher1);
+ QCOMPARE(matcher7.indexIn(haystack), 6);
+}
+
+#define LONG_STRING__32 "abcdefghijklmnopqrstuvwxyz012345"
+#define LONG_STRING__64 LONG_STRING__32 LONG_STRING__32
+#define LONG_STRING_128 LONG_STRING__64 LONG_STRING__64
+#define LONG_STRING_256 LONG_STRING_128 LONG_STRING_128
+#define LONG_STRING_512 LONG_STRING_256 LONG_STRING_256
+
+void tst_QLatin1StringMatcher::indexIn()
+{
+ const char p_data[] = { 0x0, 0x0, 0x1 };
+ QLatin1StringView pattern(p_data, sizeof(p_data));
+
+ QByteArray haystackT(8, '\0');
+ haystackT[7] = 0x1;
+ QLatin1StringView haystack(haystackT);
+
+ QLatin1StringMatcher matcher;
+
+ matcher = QLatin1StringMatcher(pattern, Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack, 0), 5);
+ QCOMPARE(matcher.indexIn(haystack, 1), 5);
+ QCOMPARE(matcher.indexIn(haystack, 2), 5);
+
+ matcher.setPattern(pattern);
+ QCOMPARE(matcher.indexIn(haystack, 0), 5);
+ QCOMPARE(matcher.indexIn(haystack, 1), 5);
+ QCOMPARE(matcher.indexIn(haystack, 2), 5);
+
+ std::array<char, 256> allChars;
+ for (int i = 0; i < 256; ++i)
+ allChars[i] = char(i);
+
+ matcher = QLatin1StringMatcher(QLatin1StringView(allChars), Qt::CaseSensitive);
+ haystackT = LONG_STRING__32 "x";
+ haystackT += matcher.pattern();
+ haystack = QLatin1StringView(haystackT);
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+
+ matcher = QLatin1StringMatcher(QLatin1StringView(LONG_STRING_256), Qt::CaseSensitive);
+ haystackT = QByteArray(LONG_STRING__32 "x");
+ haystackT += matcher.pattern();
+ haystackT += QByteArrayView("Just junk at the end");
+ haystack = QLatin1StringView(haystackT);
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+ matcher.setCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+
+ matcher = QLatin1StringMatcher(QLatin1StringView(LONG_STRING_512), Qt::CaseInsensitive);
+ haystackT = QByteArray(LONG_STRING__32 "x");
+ haystackT += matcher.pattern();
+ haystackT += QByteArrayView("Just junk at the end");
+ haystack = QLatin1StringView(haystackT);
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+ matcher.setCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack, 0), 33);
+ QCOMPARE(matcher.indexIn(haystack, 1), 33);
+ QCOMPARE(matcher.indexIn(haystack, 2), 33);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+ QCOMPARE(matcher.indexIn(haystack, 34), -1);
+
+ matcher = QLatin1StringMatcher(QLatin1StringView(""), Qt::CaseSensitive);
+ haystackT = QByteArray(LONG_STRING__32 "x");
+ haystack = QLatin1StringView(haystackT);
+ QCOMPARE(matcher.indexIn(haystack, 0), 0);
+ QCOMPARE(matcher.indexIn(haystack, 1), 1);
+ QCOMPARE(matcher.indexIn(haystack, 2), 2);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+
+ matcher = QLatin1StringMatcher(QLatin1StringView(""), Qt::CaseInsensitive);
+ haystackT = QByteArray(LONG_STRING__32 "x");
+ haystack = QLatin1StringView(haystackT);
+ QCOMPARE(matcher.indexIn(haystack, 0), 0);
+ QCOMPARE(matcher.indexIn(haystack, 1), 1);
+ QCOMPARE(matcher.indexIn(haystack, 2), 2);
+ QCOMPARE(matcher.indexIn(haystack, 33), 33);
+
+ matcher = QLatin1StringMatcher(QLatin1StringView("m\xF8"), Qt::CaseInsensitive);
+ haystackT = QByteArray("M\xF8m\xF8");
+ haystack = QLatin1StringView(haystackT);
+ QCOMPARE(matcher.indexIn(haystack, 0), 0);
+ QCOMPARE(matcher.indexIn(haystack, 1), 2);
+ QCOMPARE(matcher.indexIn(haystack, 2), 2);
+ QCOMPARE(matcher.indexIn(haystack, 3), -1);
+ matcher.setCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack, 0), 2);
+ QCOMPARE(matcher.indexIn(haystack, 1), 2);
+ QCOMPARE(matcher.indexIn(haystack, 2), 2);
+ QCOMPARE(matcher.indexIn(haystack, 3), -1);
+}
+
+void tst_QLatin1StringMatcher::haystacksWithMoreThan4GiBWork()
+{
+#if QT_POINTER_SIZE > 4
+ // use a large needle to trigger long skips in the Boyer-Moore algorithm
+ // (to speed up the test)
+ constexpr std::string_view needle = LONG_STRING_256;
+
+ //
+ // GIVEN: a haystack with more than 4 GiB of data
+ //
+
+ // don't use QByteArray because freeSpaceAtEnd() may break reserve()
+ // semantics and a realloc is the last thing we need here
+ std::string large;
+ QElapsedTimer timer;
+ timer.start();
+ constexpr size_t GiB = 1024 * 1024 * 1024;
+ constexpr size_t BaseSize = 4 * GiB + 1;
+ try {
+ large.reserve(BaseSize + needle.size());
+ large.resize(BaseSize, '\0');
+ large.append(needle);
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4GiB plus a couple hundred bytes of RAM.");
+ }
+ QCOMPARE(large.size(), BaseSize + needle.size());
+ qDebug("created dataset in %lld ms", timer.elapsed());
+
+ using MaybeThread = std::thread;
+
+ //
+ // WHEN: trying to match an occurrence past the 4GiB mark
+ //
+
+ qsizetype dynamicResult;
+
+ auto t = MaybeThread{ [&] {
+ QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive);
+ dynamicResult = m.indexIn(QLatin1StringView(large));
+ } };
+ t.join();
+
+ //
+ // THEN: the result index is not trucated
+ //
+
+ QCOMPARE(dynamicResult, qsizetype(BaseSize));
+#else
+ QSKIP("This test is 64-bit only.");
+#endif
+}
+
+void tst_QLatin1StringMatcher::staticLatin1StringMatcher()
+{
+#ifdef QT_STATIC_BOYER_MOORE_NOT_SUPPORTED
+ QSKIP("Test is only valid on an OS that supports static latin1 string matcher");
+#else
+ {
+ static constexpr auto smatcher = qMakeStaticCaseSensitiveLatin1StringMatcher("Hello");
+ QCOMPARE(smatcher.indexIn("Hello"_L1), 0);
+ QCOMPARE(smatcher.indexIn("Hello, World!"_L1), 0);
+ QCOMPARE(smatcher.indexIn("Hello, World!"_L1, 0), 0);
+ QCOMPARE(smatcher.indexIn("Hello, World!"_L1, 1), -1);
+ QCOMPARE(smatcher.indexIn("aHello, World!"_L1), 1);
+ QCOMPARE(smatcher.indexIn("aaHello, World!"_L1), 2);
+ QCOMPARE(smatcher.indexIn("aaaHello, World!"_L1), 3);
+ QCOMPARE(smatcher.indexIn("aaaaHello, World!"_L1), 4);
+ QCOMPARE(smatcher.indexIn("aaaaaHello, World!"_L1), 5);
+ QCOMPARE(smatcher.indexIn("aaaaaaHello, World!"_L1), 6);
+ QCOMPARE(smatcher.indexIn("HHello, World!"_L1), 1);
+ QCOMPARE(smatcher.indexIn("HeHello, World!"_L1), 2);
+ QCOMPARE(smatcher.indexIn("HelHello, World!"_L1), 3);
+ QCOMPARE(smatcher.indexIn("HellHello, World!"_L1), 4);
+ QCOMPARE(smatcher.indexIn("HellaHello, World!"_L1), 5);
+ QCOMPARE(smatcher.indexIn("HellauHello, World!"_L1), 6);
+ QCOMPARE(smatcher.indexIn("aHella, World!"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaHella, World!"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaHella, World!"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaaHella, World!"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaaaHella, World!"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaaaaHella, World!"_L1), -1);
+
+ QCOMPARE(smatcher.indexIn("aHello"_L1), 1);
+ QCOMPARE(smatcher.indexIn("aaHello"_L1), 2);
+ QCOMPARE(smatcher.indexIn("aaaHello"_L1), 3);
+ QCOMPARE(smatcher.indexIn("aaaaHello"_L1), 4);
+ QCOMPARE(smatcher.indexIn("aaaaaHello"_L1), 5);
+ QCOMPARE(smatcher.indexIn("aaaaaaHello"_L1), 6);
+ QCOMPARE(smatcher.indexIn("HHello"_L1), 1);
+ QCOMPARE(smatcher.indexIn("HeHello"_L1), 2);
+ QCOMPARE(smatcher.indexIn("HelHello"_L1), 3);
+ QCOMPARE(smatcher.indexIn("HellHello"_L1), 4);
+ QCOMPARE(smatcher.indexIn("HellaHello"_L1), 5);
+ QCOMPARE(smatcher.indexIn("HellauHello"_L1), 6);
+ QCOMPARE(smatcher.indexIn("aHella"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaHella"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaHella"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaaHella"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaaaHella"_L1), -1);
+ QCOMPARE(smatcher.indexIn("aaaaaaHella"_L1), -1);
+
+ constexpr qsizetype found = smatcher.indexIn("Oh Hello"_L1);
+ static_assert(found == 3);
+
+ static_assert(smatcher.indexIn("Hello"_L1) == 0);
+ static_assert(smatcher.indexIn("Hello, World!"_L1) == 0);
+ static_assert(smatcher.indexIn("Hello, World!"_L1, 0) == 0);
+ static_assert(smatcher.indexIn("Hello, World!"_L1, 1) == -1);
+ static_assert(smatcher.indexIn("aHello, World!"_L1) == 1);
+ static_assert(smatcher.indexIn("aaHello, World!"_L1) == 2);
+ static_assert(smatcher.indexIn("aaaHello, World!"_L1) == 3);
+ static_assert(smatcher.indexIn("aaaaHello, World!"_L1) == 4);
+ static_assert(smatcher.indexIn("aaaaaHello, World!"_L1) == 5);
+ static_assert(smatcher.indexIn("aaaaaaHello, World!"_L1) == 6);
+ static_assert(smatcher.indexIn("HHello, World!"_L1) == 1);
+ static_assert(smatcher.indexIn("HeHello, World!"_L1) == 2);
+ static_assert(smatcher.indexIn("HelHello, World!"_L1) == 3);
+ static_assert(smatcher.indexIn("HellHello, World!"_L1) == 4);
+ static_assert(smatcher.indexIn("HellaHello, World!"_L1) == 5);
+ static_assert(smatcher.indexIn("HellauHello, World!"_L1) == 6);
+ static_assert(smatcher.indexIn("aHella, World!"_L1) == -1);
+ static_assert(smatcher.indexIn("aaHella, World!"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaHella, World!"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaaHella, World!"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaaaHella, World!"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaaaaHella, World!"_L1) == -1);
+
+ static_assert(smatcher.indexIn("aHello"_L1) == 1);
+ static_assert(smatcher.indexIn("aaHello"_L1) == 2);
+ static_assert(smatcher.indexIn("aaaHello"_L1) == 3);
+ static_assert(smatcher.indexIn("aaaaHello"_L1) == 4);
+ static_assert(smatcher.indexIn("aaaaaHello"_L1) == 5);
+ static_assert(smatcher.indexIn("aaaaaaHello"_L1) == 6);
+ static_assert(smatcher.indexIn("HHello"_L1) == 1);
+ static_assert(smatcher.indexIn("HeHello"_L1) == 2);
+ static_assert(smatcher.indexIn("HelHello"_L1) == 3);
+ static_assert(smatcher.indexIn("HellHello"_L1) == 4);
+ static_assert(smatcher.indexIn("HellaHello"_L1) == 5);
+ static_assert(smatcher.indexIn("HellauHello"_L1) == 6);
+ static_assert(smatcher.indexIn("aHella"_L1) == -1);
+ static_assert(smatcher.indexIn("aaHella"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaHella"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaaHella"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaaaHella"_L1) == -1);
+ static_assert(smatcher.indexIn("aaaaaaHella"_L1) == -1);
+
+ static_assert(smatcher.indexIn("aHello"_L1) == 1);
+ static_assert(smatcher.indexIn("no"_L1) == -1);
+ static_assert(smatcher.indexIn("miss"_L1) == -1);
+ static_assert(smatcher.indexIn("amiss"_L1) == -1);
+ static_assert(smatcher.indexIn("olleH"_L1) == -1);
+ static_assert(smatcher.indexIn("HellNo"_L1) == -1);
+ static_assert(smatcher.indexIn("lloHello"_L1) == 3);
+ static_assert(smatcher.indexIn("lHello"_L1) == 1);
+ static_assert(smatcher.indexIn("oHello"_L1) == 1);
+ }
+ {
+ static constexpr auto smatcher =
+ qMakeStaticCaseSensitiveLatin1StringMatcher(LONG_STRING_256);
+
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("a" LONG_STRING_256)), 1);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aa" LONG_STRING_256)), 2);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaa" LONG_STRING_256)), 3);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaaa" LONG_STRING_256)), 4);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaaaa" LONG_STRING_256)), 5);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaaaaa" LONG_STRING_256)), 6);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("a" LONG_STRING_256 "a")), 1);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aa" LONG_STRING_256 "a")), 2);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaa" LONG_STRING_256 "a")), 3);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaaa" LONG_STRING_256 "a")), 4);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaaaa" LONG_STRING_256 "a")), 5);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView("aaaaaa" LONG_STRING_256 "a")), 6);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView(LONG_STRING__32 "x" LONG_STRING_256)), 33);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView(LONG_STRING__64 "x" LONG_STRING_256)), 65);
+ QCOMPARE(smatcher.indexIn(QLatin1StringView(LONG_STRING_128 "x" LONG_STRING_256)), 129);
+
+ static_assert(smatcher.indexIn(QLatin1StringView("a" LONG_STRING_256)) == 1);
+ static_assert(smatcher.indexIn(QLatin1StringView("aa" LONG_STRING_256)) == 2);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaa" LONG_STRING_256)) == 3);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaaa" LONG_STRING_256)) == 4);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaaaa" LONG_STRING_256)) == 5);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaaaaa" LONG_STRING_256)) == 6);
+ static_assert(smatcher.indexIn(QLatin1StringView("a" LONG_STRING_256 "a")) == 1);
+ static_assert(smatcher.indexIn(QLatin1StringView("aa" LONG_STRING_256 "a")) == 2);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaa" LONG_STRING_256 "a")) == 3);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaaa" LONG_STRING_256 "a")) == 4);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaaaa" LONG_STRING_256 "a")) == 5);
+ static_assert(smatcher.indexIn(QLatin1StringView("aaaaaa" LONG_STRING_256 "a")) == 6);
+ static_assert(smatcher.indexIn(QLatin1StringView(LONG_STRING__32 "x" LONG_STRING_256))
+ == 33);
+ static_assert(smatcher.indexIn(QLatin1StringView(LONG_STRING__64 "x" LONG_STRING_256))
+ == 65);
+ static_assert(smatcher.indexIn(QLatin1StringView(LONG_STRING_128 "x" LONG_STRING_256))
+ == 129);
+ }
+#endif
+}
+
+#undef LONG_STRING_512
+#undef LONG_STRING_256
+#undef LONG_STRING_128
+#undef LONG_STRING__64
+#undef LONG_STRING__32
+
+QTEST_APPLESS_MAIN(tst_QLatin1StringMatcher)
+#include "tst_qlatin1stringmatcher.moc"
diff --git a/tests/auto/corelib/text/qlatin1stringview/.gitignore b/tests/auto/corelib/text/qlatin1stringview/.gitignore
new file mode 100644
index 0000000000..8156eca574
--- /dev/null
+++ b/tests/auto/corelib/text/qlatin1stringview/.gitignore
@@ -0,0 +1 @@
+tst_qlatin1stringview
diff --git a/tests/auto/corelib/text/qlatin1stringview/CMakeLists.txt b/tests/auto/corelib/text/qlatin1stringview/CMakeLists.txt
new file mode 100644
index 0000000000..7a3b493789
--- /dev/null
+++ b/tests/auto/corelib/text/qlatin1stringview/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qlatin1stringview Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlatin1stringview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qlatin1stringview
+ SOURCES
+ tst_qlatin1stringview.cpp
+ DEFINES
+ QT_NO_CAST_TO_ASCII
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qlatin1stringview/tst_qlatin1stringview.cpp b/tests/auto/corelib/text/qlatin1stringview/tst_qlatin1stringview.cpp
new file mode 100644
index 0000000000..e719c81731
--- /dev/null
+++ b/tests/auto/corelib/text/qlatin1stringview/tst_qlatin1stringview.cpp
@@ -0,0 +1,519 @@
+// Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <QString>
+
+// Preserve QLatin1StringView-ness (QVariant(QLatin1StringView) creates a QVariant::String):
+struct QLatin1StringViewContainer {
+ QLatin1StringView l1;
+};
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(QLatin1StringViewContainer, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QLatin1StringViewContainer)
+
+class tst_QLatin1StringView : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void constExpr();
+ void construction();
+ void userDefinedLiterals();
+ void at();
+ void arg() const;
+ void midLeftRight();
+ void nullString();
+ void emptyString();
+ void iterators();
+ void relationalOperators_data();
+ void relationalOperators();
+ void count();
+ void indexOf_data();
+ void indexOf();
+};
+
+void tst_QLatin1StringView::constExpr()
+{
+ // compile-time checks
+ {
+ constexpr QLatin1StringView l1s;
+ static_assert(l1s.size() == 0);
+ static_assert(l1s.isNull());
+ static_assert(l1s.empty());
+ static_assert(l1s.isEmpty());
+ static_assert(l1s.latin1() == nullptr);
+
+ constexpr QLatin1StringView l1s2(l1s.latin1(), l1s.latin1() + l1s.size());
+ static_assert(l1s2.isNull());
+ static_assert(l1s2.empty());
+ }
+ {
+ constexpr QLatin1StringView l1s = nullptr;
+ static_assert(l1s.size() == 0);
+ static_assert(l1s.isNull());
+ static_assert(l1s.empty());
+ static_assert(l1s.isEmpty());
+ static_assert(l1s.latin1() == nullptr);
+ }
+ {
+ constexpr QLatin1StringView l1s("");
+ static_assert(l1s.size() == 0);
+ static_assert(!l1s.isNull());
+ static_assert(l1s.empty());
+ static_assert(l1s.isEmpty());
+ static_assert(l1s.latin1() != nullptr);
+
+ constexpr QLatin1StringView l1s2(l1s.latin1(), l1s.latin1() + l1s.size());
+ static_assert(!l1s2.isNull());
+ static_assert(l1s2.empty());
+ }
+ {
+ static_assert(QLatin1StringView("Hello").size() == 5);
+ constexpr QLatin1StringView l1s("Hello");
+ static_assert(l1s.size() == 5);
+ static_assert(!l1s.empty());
+ static_assert(!l1s.isEmpty());
+ static_assert(!l1s.isNull());
+ static_assert(*l1s.latin1() == 'H');
+ static_assert(l1s[0] == QLatin1Char('H'));
+ static_assert(l1s.at(0) == QLatin1Char('H'));
+ static_assert(l1s.front() == QLatin1Char('H'));
+ static_assert(l1s.first() == QLatin1Char('H'));
+ static_assert(l1s[4] == QLatin1Char('o'));
+ static_assert(l1s.at(4) == QLatin1Char('o'));
+ static_assert(l1s.back() == QLatin1Char('o'));
+ static_assert(l1s.last() == QLatin1Char('o'));
+
+ constexpr QLatin1StringView l1s2(l1s.latin1(), l1s.latin1() + l1s.size());
+ static_assert(!l1s2.isNull());
+ static_assert(!l1s2.empty());
+ static_assert(l1s2.size() == 5);
+ }
+}
+
+void tst_QLatin1StringView::construction()
+{
+ {
+ const char str[6] = "hello";
+ QLatin1StringView l1s(str);
+ QCOMPARE(l1s.size(), 5);
+ QCOMPARE(l1s.latin1(), reinterpret_cast<const void *>(&str[0]));
+ QCOMPARE(l1s.latin1(), "hello");
+
+ QLatin1StringView s1 = {str, 5};
+ QCOMPARE(s1, l1s);
+ QLatin1StringView s2 = {str, str + 5};
+ QCOMPARE(s2, l1s);
+
+ QByteArrayView helloView(str);
+ helloView = helloView.first(4);
+ l1s = QLatin1StringView(helloView);
+ QCOMPARE(l1s.latin1(), helloView.data());
+ QCOMPARE(l1s.latin1(), reinterpret_cast<const void *>(helloView.data()));
+ QCOMPARE(l1s.size(), helloView.size());
+ }
+
+ {
+ const QByteArray helloArray("hello");
+ QLatin1StringView l1s(helloArray);
+ QCOMPARE(l1s.latin1(), helloArray.data());
+ QCOMPARE(l1s.size(), helloArray.size());
+
+ QByteArrayView helloView(helloArray);
+ helloView = helloView.first(4);
+ l1s = QLatin1StringView(helloView);
+ QCOMPARE(l1s.latin1(), helloView.data());
+ QCOMPARE(l1s.size(), helloView.size());
+ }
+}
+
+void tst_QLatin1StringView::userDefinedLiterals()
+{
+ {
+ using namespace Qt::Literals::StringLiterals;
+
+ auto str = "abcd"_L1;
+ static_assert(std::is_same_v<decltype(str), QLatin1StringView>);
+ QCOMPARE(str.size(), 4);
+ QCOMPARE(str, QLatin1StringView("abcd"));
+ QCOMPARE(str.latin1(), "abcd");
+ QCOMPARE("abcd"_L1, str.latin1());
+ QCOMPARE("M\xE5rten"_L1, QLatin1StringView("M\xE5rten"));
+
+ auto ch = 'a'_L1;
+ static_assert(std::is_same_v<decltype(ch), QLatin1Char>);
+ QCOMPARE(ch, QLatin1Char('a'));
+ QCOMPARE(ch.toLatin1(), 'a');
+ QCOMPARE('a'_L1, ch.toLatin1());
+ QCOMPARE('\xE5'_L1, QLatin1Char('\xE5'));
+ }
+ {
+ using namespace Qt::Literals;
+
+ auto str = "abcd"_L1;
+ static_assert(std::is_same_v<decltype(str), QLatin1StringView>);
+ QCOMPARE(str, QLatin1StringView("abcd"));
+
+ auto ch = 'a'_L1;
+ static_assert(std::is_same_v<decltype(ch), QLatin1Char>);
+ QCOMPARE(ch, QLatin1Char('a'));
+ }
+ {
+ using namespace Qt;
+
+ auto str = "abcd"_L1;
+ static_assert(std::is_same_v<decltype(str), QLatin1StringView>);
+ QCOMPARE(str, QLatin1StringView("abcd"));
+
+ auto ch = 'a'_L1;
+ static_assert(std::is_same_v<decltype(ch), QLatin1Char>);
+ QCOMPARE(ch, QLatin1Char('a'));
+ }
+}
+
+void tst_QLatin1StringView::at()
+{
+ const QLatin1StringView l1("Hello World");
+ QCOMPARE(l1.at(0), QLatin1Char('H'));
+ QCOMPARE(l1.at(l1.size() - 1), QLatin1Char('d'));
+ QCOMPARE(l1[0], QLatin1Char('H'));
+ QCOMPARE(l1[l1.size() - 1], QLatin1Char('d'));
+}
+
+void tst_QLatin1StringView::arg() const
+{
+#define CHECK1(pattern, arg1, expected) \
+ do { \
+ auto p = QLatin1StringView(pattern); \
+ QCOMPARE(p.arg(QLatin1StringView(arg1)), expected); \
+ QCOMPARE(p.arg(u"" arg1), expected); \
+ QCOMPARE(p.arg(QStringLiteral(arg1)), expected); \
+ QCOMPARE(p.arg(QString(QLatin1StringView(arg1))), expected); \
+ } while (false) \
+ /*end*/
+#define CHECK2(pattern, arg1, arg2, expected) \
+ do { \
+ auto p = QLatin1StringView(pattern); \
+ QCOMPARE(p.arg(QLatin1StringView(arg1), QLatin1StringView(arg2)), expected); \
+ QCOMPARE(p.arg(u"" arg1, QLatin1StringView(arg2)), expected); \
+ QCOMPARE(p.arg(QLatin1StringView(arg1), u"" arg2), expected); \
+ QCOMPARE(p.arg(u"" arg1, u"" arg2), expected); \
+ } while (false) \
+ /*end*/
+
+ CHECK1("", "World", "");
+ CHECK1("%1", "World", "World");
+ CHECK1("!%1?", "World", "!World?");
+ CHECK1("%1%1", "World", "WorldWorld");
+ CHECK1("%1%2", "World", "World%2");
+ CHECK1("%2%1", "World", "%2World");
+
+ CHECK2("", "Hello", "World", "");
+ CHECK2("%1", "Hello", "World", "Hello");
+ CHECK2("!%1, %2?", "Hello", "World", "!Hello, World?");
+ CHECK2("%1%1", "Hello", "World", "HelloHello");
+ CHECK2("%1%2", "Hello", "World", "HelloWorld");
+ CHECK2("%2%1", "Hello", "World", "WorldHello");
+
+#undef CHECK2
+#undef CHECK1
+
+ QCOMPARE(QLatin1StringView(" %2 %2 %1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'),
+ " \r \r c C ");
+}
+
+void tst_QLatin1StringView::midLeftRight()
+{
+ const QLatin1StringView l1("Hello World");
+ QCOMPARE(l1.mid(0), l1);
+ QCOMPARE(l1.mid(0, l1.size()), l1);
+ QCOMPARE(l1.left(l1.size()), l1);
+ QCOMPARE(l1.right(l1.size()), l1);
+
+ QCOMPARE(l1.mid(6), QLatin1StringView("World"));
+ QCOMPARE(l1.mid(6, 5), QLatin1StringView("World"));
+ QCOMPARE(l1.right(5), QLatin1StringView("World"));
+
+ QCOMPARE(l1.mid(6, 1), QLatin1StringView("W"));
+ QCOMPARE(l1.right(5).left(1), QLatin1StringView("W"));
+
+ QCOMPARE(l1.left(5), QLatin1StringView("Hello"));
+}
+
+void tst_QLatin1StringView::nullString()
+{
+ // default ctor
+ {
+ QLatin1StringView l1;
+ QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
+ QCOMPARE(l1.size(), 0);
+
+ QString s = l1;
+ QVERIFY(s.isNull());
+ }
+
+ // from nullptr
+ {
+ const char *null = nullptr;
+ QLatin1StringView l1(null);
+ QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
+ QCOMPARE(l1.size(), 0);
+
+ QString s = l1;
+ QVERIFY(s.isNull());
+ }
+
+ // from null QByteArray
+ {
+ const QByteArray null;
+ QVERIFY(null.isNull());
+
+ QLatin1StringView l1(null);
+ QEXPECT_FAIL("", "null QByteArrays become non-null QLatin1Strings...", Continue);
+ QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
+ QCOMPARE(l1.size(), 0);
+
+ QString s = l1;
+ QEXPECT_FAIL("", "null QByteArrays become non-null QLatin1Strings become non-null QStrings...", Continue);
+ QVERIFY(s.isNull());
+ }
+}
+
+void tst_QLatin1StringView::emptyString()
+{
+ {
+ const char *empty = "";
+ QLatin1StringView l1(empty);
+ QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty));
+ QCOMPARE(l1.size(), 0);
+
+ QString s = l1;
+ QVERIFY(s.isEmpty());
+ QVERIFY(!s.isNull());
+ }
+
+ {
+ const char *notEmpty = "foo";
+ QLatin1StringView l1(notEmpty, qsizetype(0));
+ QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(notEmpty));
+ QCOMPARE(l1.size(), 0);
+
+ QString s = l1;
+ QVERIFY(s.isEmpty());
+ QVERIFY(!s.isNull());
+ }
+
+ {
+ const QByteArray empty = "";
+ QLatin1StringView l1(empty);
+ QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty.constData()));
+ QCOMPARE(l1.size(), 0);
+
+ QString s = l1;
+ QVERIFY(s.isEmpty());
+ QVERIFY(!s.isNull());
+ }
+}
+
+void tst_QLatin1StringView::iterators()
+{
+ QLatin1StringView hello("hello");
+ QLatin1StringView olleh("olleh");
+
+ QVERIFY(std::equal(hello.begin(), hello.end(),
+ olleh.rbegin()));
+ QVERIFY(std::equal(hello.rbegin(), hello.rend(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size())));
+
+ QVERIFY(std::equal(hello.cbegin(), hello.cend(),
+ olleh.rbegin()));
+ QVERIFY(std::equal(hello.crbegin(), hello.crend(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size())));
+}
+
+void tst_QLatin1StringView::relationalOperators_data()
+{
+ QTest::addColumn<QLatin1StringViewContainer>("lhs");
+ QTest::addColumn<int>("lhsOrderNumber");
+ QTest::addColumn<QLatin1StringViewContainer>("rhs");
+ QTest::addColumn<int>("rhsOrderNumber");
+
+ struct Data {
+ QLatin1StringView l1;
+ int order;
+ } data[] = {
+ { QLatin1StringView(), 0 },
+ { QLatin1StringView(""), 0 },
+ { QLatin1StringView("a"), 1 },
+ { QLatin1StringView("aa"), 2 },
+ { QLatin1StringView("b"), 3 },
+ };
+
+ for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) {
+ for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) {
+ QLatin1StringViewContainer l = { lhs->l1 }, r = { rhs->l1 };
+ QTest::addRow("\"%s\" <> \"%s\"",
+ lhs->l1.data() ? lhs->l1.data() : "nullptr",
+ rhs->l1.data() ? rhs->l1.data() : "nullptr")
+ << l << lhs->order << r << rhs->order;
+ }
+ }
+}
+
+void tst_QLatin1StringView::relationalOperators()
+{
+ QFETCH(QLatin1StringViewContainer, lhs);
+ QFETCH(int, lhsOrderNumber);
+ QFETCH(QLatin1StringViewContainer, rhs);
+ QFETCH(int, rhsOrderNumber);
+
+#define CHECK(op) \
+ QCOMPARE(lhs.l1 op rhs.l1, lhsOrderNumber op rhsOrderNumber) \
+ /*end*/
+ CHECK(==);
+ CHECK(!=);
+ CHECK(< );
+ CHECK(> );
+ CHECK(<=);
+ CHECK(>=);
+#undef CHECK
+}
+
+void tst_QLatin1StringView::count()
+{
+ QLatin1StringView a("ABCDEFGHIEfGEFG");
+ QCOMPARE(a.size(), 15);
+ QCOMPARE(a.count('A'), 1);
+ QCOMPARE(a.count('Z'), 0);
+ QCOMPARE(a.count('E'), 3);
+ QCOMPARE(a.count('F'), 2);
+ QCOMPARE(a.count('F', Qt::CaseInsensitive), 3);
+ QCOMPARE(a.count(QLatin1StringView("FG")), 2);
+ QCOMPARE(a.count(QLatin1StringView("FG"), Qt::CaseInsensitive), 3);
+ QCOMPARE(a.count(QLatin1StringView(), Qt::CaseInsensitive), 16);
+ QCOMPARE(a.count(QLatin1StringView(""), Qt::CaseInsensitive), 16);
+
+ QLatin1StringView nullStr;
+ QCOMPARE(nullStr.count('A'), 0);
+ QCOMPARE(nullStr.count(QLatin1StringView("AB")), 0);
+ QCOMPARE(nullStr.count(QLatin1StringView()), 1);
+ QCOMPARE(nullStr.count(QLatin1StringView("")), 1);
+
+ QLatin1StringView emptyStr("");
+ QCOMPARE(emptyStr.count('A'), 0);
+ QCOMPARE(emptyStr.count(QLatin1StringView("AB")), 0);
+ QCOMPARE(emptyStr.count(QLatin1StringView()), 1);
+ QCOMPARE(emptyStr.count(QLatin1StringView("")), 1);
+
+ using namespace Qt::Literals::StringLiterals;
+ QCOMPARE("a\0b"_L1.count(QChar::SpecialCharacter::LineSeparator), 0);
+}
+
+void tst_QLatin1StringView::indexOf_data()
+{
+ using namespace Qt::Literals::StringLiterals;
+
+ QTest::addColumn<QLatin1StringView>("needle");
+ QTest::addColumn<QLatin1StringView>("haystack");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("indexCaseSensitive");
+ QTest::addColumn<int>("indexCaseInsensitive");
+
+ // Should never trigger Boyer Moore algorithm
+ QTest::newRow("Single letter match start")
+ << QLatin1StringView("A") << QLatin1StringView("ABCDEF") << 0 << 0 << 0;
+ QTest::newRow("Single letter match second letter")
+ << QLatin1StringView("B") << QLatin1StringView("ABCDEF") << 0 << 1 << 1;
+ QTest::newRow("Single letter mismatch")
+ << QLatin1StringView("G") << QLatin1StringView("ABCDEF") << 0 << -1 << -1;
+ QTest::newRow("Single letter case sensitive start")
+ << QLatin1StringView("a") << QLatin1StringView("ABCDEF") << 0 << -1 << 0;
+ QTest::newRow("Single letter case sensitive end")
+ << QLatin1StringView("f") << QLatin1StringView("ABCDEF") << 0 << -1 << 5;
+ QTest::newRow("Single letter different match depending on case")
+ << QLatin1StringView("a") << QLatin1StringView("ABCabc") << 0 << 3 << 0;
+ QTest::newRow("Single letter different match depending on case from 2")
+ << QLatin1StringView("a") << QLatin1StringView("ABCABCabc") << 2 << 6 << 3;
+ QTest::newRow("Single letter negative from")
+ << QLatin1StringView("a") << QLatin1StringView("abcabc") << -3 << 3 << 3;
+ QTest::newRow("Single letter non-ASCII") // searching for "ø" in "Øø"
+ << "\xf8"_L1
+ << "\xd8\xf8"_L1 << 0 << 1 << 0;
+ QTest::newRow("Single uppercase letter")
+ << QLatin1StringView("A") << QLatin1StringView("aA") << 0 << 1 << 0;
+
+ // Might trigger Boyer Moore algorithm
+ QTest::newRow("Small match start")
+ << QLatin1StringView("ABC") << QLatin1StringView("ABCDEF") << 0 << 0 << 0;
+ QTest::newRow("Small match second letter")
+ << QLatin1StringView("BCD") << QLatin1StringView("ABCDEF") << 0 << 1 << 1;
+ QTest::newRow("Small mismatch")
+ << QLatin1StringView("EFG") << QLatin1StringView("ABCDEF") << 0 << -1 << -1;
+ QTest::newRow("Small case sensitive start")
+ << QLatin1StringView("abc") << QLatin1StringView("ABCDEF") << 0 << -1 << 0;
+ QTest::newRow("Small case sensitive end")
+ << QLatin1StringView("DEF") << QLatin1StringView("abcdef") << 0 << -1 << 3;
+ QTest::newRow("Small different match depending on case")
+ << QLatin1StringView("abcabc") << QLatin1StringView("!!ABCabcabcABC") << 0 << 5 << 2;
+ QTest::newRow("Small different match depending on case from 2")
+ << QLatin1StringView("abcabc") << QLatin1StringView("ABCABCabcabcABC") << 2 << 6 << 3;
+ QTest::newRow("Small negative from") << QLatin1StringView("negative")
+ << QLatin1StringView("negativenegative") << -8 << 8 << 8;
+ QTest::newRow("Small non-ASCII") // searching for "løve" in "LØVEløve"
+ << "l\xf8ve"_L1
+ << "L\xd8VEl\xf8ve"_L1 << 0 << 4 << 0;
+ QTest::newRow("Small skip test")
+ << QLatin1StringView("ABBB") << QLatin1StringView("ABABBB") << 0 << 2 << 2;
+ QTest::newRow("Small uppercase needle")
+ << QLatin1StringView("ABCDEF") << QLatin1StringView("abcdefABCDEF") << 0 << 6 << 0;
+
+ // Should trigger Boyer Moore algorithm
+ QTest::newRow("Medium match start")
+ << QLatin1StringView("ABCDEFGHIJKLMNOP")
+ << QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << 0 << 0;
+ QTest::newRow("Medium match second letter")
+ << QLatin1StringView("BCDEFGHIJKLMNOPQ")
+ << QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << 1 << 1;
+ QTest::newRow("Medium mismatch")
+ << QLatin1StringView("PONMLKJIHGFEDCBA")
+ << QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << -1 << -1;
+ QTest::newRow("Medium case sensitive start")
+ << QLatin1StringView("abcdefghijklmnopq")
+ << QLatin1StringView("ABCDEFGHIJKLMNOPQRSTUVWXYZ") << 0 << -1 << 0;
+ QTest::newRow("Medium case sensitive second letter")
+ << QLatin1StringView("BCDEFGHIJKLMNOPQR")
+ << QLatin1StringView("abcdefghijklmnopqrstuvxyz") << 0 << -1 << 1;
+ QTest::newRow("Medium different match depending on case")
+ << QLatin1StringView("testingtesting")
+ << QLatin1StringView("TESTINGtestingtestingTESTING") << 0 << 7 << 0;
+ QTest::newRow("Medium different match depending on case from 2")
+ << QLatin1StringView("testingtesting")
+ << QLatin1StringView("TESTINGTESTINGtestingtestingTESTING") << 2 << 14 << 7;
+ QTest::newRow("Medium negative from")
+ << QLatin1StringView("abcdefghijklmnop")
+ << QLatin1StringView("abcdefghijklmnopabcdefghijklmnop") << -16 << 16 << 16;
+ QTest::newRow("Medium non-ASCII") // searching for "dampfschiffahrtsgesellschaftskapitän"
+ << "dampfschiffahrtsgesellschaftskapit\xe4n"_L1
+ << "DAMPFSCHIFFAHRTSGESELLSCHAFTSKAPIT\xc4Ndampfschiffahrtsgesellschaftskapit\xe4n"_L1
+ << 0 << 36 << 0;
+ QTest::newRow("Medium skip test") << QLatin1StringView("ABBBBBBBBBBBBBBB")
+ << QLatin1StringView("ABABBBBBBBBBBBBBBB") << 0 << 2 << 2;
+}
+
+void tst_QLatin1StringView::indexOf()
+{
+ QFETCH(QLatin1StringView, needle);
+ QFETCH(QLatin1StringView, haystack);
+ QFETCH(int, from);
+ QFETCH(int, indexCaseSensitive);
+ QFETCH(int, indexCaseInsensitive);
+ QCOMPARE(haystack.indexOf(needle, from, Qt::CaseSensitive), (qsizetype)indexCaseSensitive);
+ QCOMPARE(haystack.indexOf(needle, from, Qt::CaseInsensitive), (qsizetype)indexCaseInsensitive);
+}
+
+QTEST_APPLESS_MAIN(tst_QLatin1StringView)
+
+#include "tst_qlatin1stringview.moc"
diff --git a/tests/auto/corelib/tools/qlocale/.gitignore b/tests/auto/corelib/text/qlocale/.gitignore
index 21ab80a2af..21ab80a2af 100644
--- a/tests/auto/corelib/tools/qlocale/.gitignore
+++ b/tests/auto/corelib/text/qlocale/.gitignore
diff --git a/tests/auto/corelib/text/qlocale/CMakeLists.txt b/tests/auto/corelib/text/qlocale/CMakeLists.txt
new file mode 100644
index 0000000000..3e6693d12b
--- /dev/null
+++ b/tests/auto/corelib/text/qlocale/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlocale LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(test)
+add_subdirectory(syslocaleapp)
diff --git a/tests/auto/corelib/text/qlocale/syslocaleapp/CMakeLists.txt b/tests/auto/corelib/text/qlocale/syslocaleapp/CMakeLists.txt
new file mode 100644
index 0000000000..0a5bce6183
--- /dev/null
+++ b/tests/auto/corelib/text/qlocale/syslocaleapp/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## syslocaleapp Binary:
+#####################################################################
+
+qt_internal_add_executable(syslocaleapp
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ syslocaleapp.cpp
+)
diff --git a/tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.cpp b/tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.cpp
new file mode 100644
index 0000000000..44c6ce3aa6
--- /dev/null
+++ b/tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.cpp
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QLocale>
+#include <QCalendar>
+#include <QCoreApplication>
+#include <QTextStream>
+
+int main(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+ // Setting a default locale should not mess up the system one.
+ QLocale::setDefault(QLocale::Persian);
+ QLocale l = QLocale::system();
+ // A non-Roman calendar will use CLDR data instead of system data, so needs
+ // to have got the right locale index to look that up.
+ QCalendar cal = QCalendar(QCalendar::System::Jalali);
+ QTextStream str(stdout);
+ str << l.name() << ' ' << cal.standaloneMonthName(l, 2);
+
+ return 0;
+}
diff --git a/tests/auto/corelib/text/qlocale/test/CMakeLists.txt b/tests/auto/corelib/text/qlocale/test/CMakeLists.txt
new file mode 100644
index 0000000000..fc3e1488cd
--- /dev/null
+++ b/tests/auto/corelib/text/qlocale/test/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qlocale Test:
+#####################################################################
+
+qt_internal_add_test(tst_qlocale
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../tst_qlocale.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qlocale CONDITION embedded
+ LIBRARIES
+ Qt::Gui
+)
+
+qt_internal_extend_target(tst_qlocale CONDITION NOT QT_FEATURE_doubleconversion AND NOT QT_FEATURE_system_doubleconversion
+ DEFINES
+ QT_NO_DOUBLECONVERSION
+)
+
+## Depends on ../syslocaleapp
+if(QT_FEATURE_process)
+ add_dependencies(tst_qlocale syslocaleapp)
+endif()
diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
new file mode 100644
index 0000000000..c9668cd4d4
--- /dev/null
+++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
@@ -0,0 +1,4628 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QLocale>
+
+#include <QDateTime>
+#include <QDebug>
+#include <QDir>
+#include <QFileInfo>
+#include <qnumeric.h>
+#if QT_CONFIG(process)
+# include <QProcess>
+#endif
+#include <QScopedArrayPointer>
+#include <QTimeZone>
+
+#include <private/qlocale_p.h>
+#include <private/qlocale_tools_p.h>
+#include "../../../../shared/localechange.h"
+
+#include <float.h>
+#include <math.h>
+#include <fenv.h>
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
+# include <stdlib.h>
+#endif
+
+using namespace Qt::StringLiterals;
+
+Q_DECLARE_METATYPE(QLocale::FormatType)
+
+class tst_QLocale : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QLocale();
+
+private slots:
+ void initTestCase();
+ void compareCompiles();
+#if defined(Q_OS_WIN)
+ void windowsDefaultLocale();
+#endif
+#ifdef Q_OS_DARWIN
+ void macDefaultLocale();
+#endif
+
+ void ctor_data();
+ void ctor();
+ void ctor_match_land();
+ void systemLocale_data();
+ void systemLocale();
+ void consistentC();
+ void matchingLocales();
+
+ void stringToDouble_data();
+ void stringToDouble();
+ void stringToFloat_data();
+ void stringToFloat();
+ void doubleToString_data();
+ void doubleToString();
+ void strtod_data();
+ void strtod();
+ void long_long_conversion_data();
+ void long_long_conversion();
+ void long_long_conversion_extra();
+ void infNaN();
+ void fpExceptions();
+ void negativeZero_data();
+ void negativeZero();
+
+ void dayOfWeek();
+ void dayOfWeek_data();
+ void formatDate();
+ void formatDate_data();
+ void formatTime();
+ void formatTime_data();
+ void formatDateTime();
+ void formatDateTime_data();
+ void formatTimeZone();
+ void toDateTime_data();
+ void toDateTime();
+ void toDate_data();
+ void toDate();
+ void toTime_data();
+ void toTime();
+
+ void doubleRoundTrip_data();
+ void doubleRoundTrip();
+ void integerRoundTrip_data();
+ void integerRoundTrip();
+ void negativeNumbers();
+ void numberOptions();
+ void dayName_data();
+ void dayName();
+ void standaloneDayName_data();
+ void standaloneDayName();
+ void underflowOverflow();
+
+ void dateFormat();
+ void timeFormat();
+ void dateTimeFormat();
+ void monthName();
+ void standaloneMonthName();
+
+ void languageToString_data();
+ void languageToString();
+ void scriptToString_data();
+ void scriptToString();
+ void territoryToString_data();
+ void territoryToString();
+ void endonym_data();
+ void endonym();
+
+ void defaultNumberingSystem_data();
+ void defaultNumberingSystem();
+
+ void ampm_data();
+ void ampm();
+ void currency();
+ void quoteString();
+ void uiLanguages_data();
+ void uiLanguages();
+ void weekendDays();
+ void listPatterns();
+
+ void measurementSystems_data();
+ void measurementSystems();
+ void QTBUG_26035_positivesign();
+
+ void textDirection_data();
+ void textDirection();
+
+ void formattedDataSize_data();
+ void formattedDataSize();
+ void bcp47Name_data();
+ void bcp47Name();
+
+#ifndef QT_NO_SYSTEMLOCALE
+# ifdef QT_BUILD_INTERNAL
+ void mySystemLocale_data();
+ void mySystemLocale();
+# endif
+
+ void systemLocaleDayAndMonthNames_data();
+ void systemLocaleDayAndMonthNames();
+#endif
+
+ void numberGrouping_data();
+ void numberGrouping();
+ void numberGroupingIndia();
+ void numberFormatChakma();
+
+ void lcsToCode();
+ void codeToLcs();
+
+ // *** ORDER-DEPENDENCY *** (This Is Bad.)
+ // Test order is determined by order of declaration here: *all* tests that
+ // QLocale::setDefault() *must* appear *after* all other tests !
+ void defaulted_ctor(); // This one must be the first of these.
+ void legacyNames();
+ void unixLocaleName_data();
+ void unixLocaleName();
+ void testNames_data();
+ void testNames();
+ // DO NOT add tests here unless they QLocale::setDefault(); see above.
+private:
+ QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
+ QString m_sysapp;
+ QStringList cleanEnv;
+ const bool europeanTimeZone;
+ void toReal_data();
+
+ using TransientLocale = QTestLocaleChange::TransientLocale;
+};
+
+tst_QLocale::tst_QLocale()
+ // Some tests are specific to CET, test if it applies:
+ : europeanTimeZone(
+ QDate(2013, 1, 1).startOfDay().offsetFromUtc() == 3600
+ && QDate(2013, 6, 1).startOfDay().offsetFromUtc() == 7200
+ // ICU in a zone not currently doing DST may ignore any historical DST
+ // excursions in its display-names (Africa/Tripoli).
+ && QDate(QDate::currentDate().year(), 1, 1).startOfDay().offsetFromUtc() == 3600
+ && QDate(QDate::currentDate().year(), 7, 1).startOfDay().offsetFromUtc() == 7200)
+{
+ qRegisterMetaType<QLocale::FormatType>("QLocale::FormatType");
+}
+
+void tst_QLocale::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QLocale>();
+}
+
+void tst_QLocale::initTestCase()
+{
+#ifdef Q_OS_ANDROID
+ // We can't start a QProcess on Android, and we anyway skip the test
+ // that uses m_sysapp. So no need to initialize it properly.
+ return;
+#elif QT_CONFIG(process)
+ const QString syslocaleapp_dir = QFINDTESTDATA("syslocaleapp");
+ QVERIFY2(!syslocaleapp_dir.isEmpty(),
+ qPrintable(QStringLiteral("Cannot find 'syslocaleapp' starting from ")
+ + QDir::toNativeSeparators(QDir::currentPath())));
+ m_sysapp = syslocaleapp_dir + QStringLiteral("/syslocaleapp");
+#ifdef Q_OS_WIN
+ m_sysapp += QStringLiteral(".exe");
+#endif
+ const QFileInfo fi(m_sysapp);
+ QVERIFY2(fi.exists() && fi.isExecutable(),
+ qPrintable(QDir::toNativeSeparators(m_sysapp)
+ + QStringLiteral(" does not exist or is not executable.")));
+
+ // Get an environment free of any locale-related variables
+ cleanEnv.clear();
+ const QStringList sysenv = QProcess::systemEnvironment();
+ for (const QString &entry : sysenv) {
+ if (entry.startsWith("LANG=") || entry.startsWith("LC_") || entry.startsWith("LANGUAGE="))
+ continue;
+ cleanEnv << entry;
+ }
+#endif // QT_CONFIG(process)
+}
+
+void tst_QLocale::ctor_data()
+{
+ QTest::addColumn<QLocale::Language>("reqLang");
+ QTest::addColumn<QLocale::Script>("reqText");
+ QTest::addColumn<QLocale::Territory>("reqLand");
+ QTest::addColumn<QLocale::Language>("expLang");
+ QTest::addColumn<QLocale::Script>("expText");
+ QTest::addColumn<QLocale::Territory>("expLand");
+
+ // Exact match
+#define ECHO(name, lang, text, land) \
+ QTest::newRow(name) \
+ << QLocale::lang << QLocale::text << QLocale::land \
+ << QLocale::lang << QLocale::text << QLocale::land
+
+ ECHO("zh_Hans_CN", Chinese, SimplifiedHanScript, China);
+ ECHO("zh_Hant_TW", Chinese, TraditionalHanScript, Taiwan);
+ ECHO("zh_Hant_HK", Chinese, TraditionalHanScript, HongKong);
+#undef ECHO
+
+ // Determine territory from language and script:
+#define WHATLAND(name, lang, text, land) \
+ QTest::newRow(name) \
+ << QLocale::lang << QLocale::text << QLocale::AnyTerritory \
+ << QLocale::lang << QLocale::text << QLocale::land
+
+ WHATLAND("zh_Hans", Chinese, SimplifiedHanScript, China);
+ WHATLAND("zh_Hant", Chinese, TraditionalHanScript, Taiwan);
+#undef WHATLAND
+
+ // Determine script from language and territory:
+#define WHATTEXT(name, lang, text, land) \
+ QTest::newRow(name) \
+ << QLocale::lang << QLocale::AnyScript << QLocale::land \
+ << QLocale::lang << QLocale::text << QLocale::land
+
+ WHATTEXT("zh_CN", Chinese, SimplifiedHanScript, China);
+ WHATTEXT("zh_TW", Chinese, TraditionalHanScript, Taiwan);
+ WHATTEXT("zh_HK", Chinese, TraditionalHanScript, HongKong);
+#undef WHATTEXT
+
+ // No exact match, fix by change of territory:
+#define FIXLAND(name, lang, text, land, fixed) \
+ QTest::newRow(name) \
+ << QLocale::lang << QLocale::text << QLocale::land \
+ << QLocale::lang << QLocale::text << QLocale::fixed
+
+ FIXLAND("zh_Hans_TW", Chinese, SimplifiedHanScript, Taiwan, China);
+ FIXLAND("zh_Hans_US", Chinese, SimplifiedHanScript, UnitedStates, China);
+ FIXLAND("zh_Hant_CN", Chinese, TraditionalHanScript, China, Taiwan);
+ FIXLAND("zh_Hant_US", Chinese, TraditionalHanScript, UnitedStates, Taiwan);
+#undef FIXLAND
+
+ // No exact match, fix by change of script:
+#define FIXTEXT(name, lang, text, land, fixed) \
+ QTest::newRow(name) \
+ << QLocale::lang << QLocale::text << QLocale::land \
+ << QLocale::lang << QLocale::fixed << QLocale::land
+
+ FIXTEXT("zh_Latn_CN", Chinese, LatinScript, China, SimplifiedHanScript);
+ FIXTEXT("zh_Latn_TW", Chinese, LatinScript, Taiwan, TraditionalHanScript);
+#undef FIXTEXT
+
+ // No exact match, preserve language:
+#define KEEPLANG(name, lang, text, land, fixtext, fixland) \
+ QTest::newRow(name) \
+ << QLocale::lang << QLocale::text << QLocale::land \
+ << QLocale::lang << QLocale::fixtext << QLocale::fixland
+
+ KEEPLANG("zh_US", Chinese, AnyScript, UnitedStates, SimplifiedHanScript, China);
+ KEEPLANG("zh_Latn_US", Chinese, LatinScript, UnitedStates, SimplifiedHanScript, China);
+#undef KEEPLANG
+
+ // Only territory - likely subtags imply language and script:
+#define LANDFILL(name, lang, text, land) \
+ QTest::newRow(name) \
+ << QLocale::AnyLanguage << QLocale::AnyScript << QLocale::land \
+ << QLocale::lang << QLocale::text << QLocale::land
+
+ LANDFILL("und_CN", Chinese, SimplifiedHanScript, China);
+ LANDFILL("und_TW", Chinese, TraditionalHanScript, Taiwan);
+ LANDFILL("und_CA", English, LatinScript, Canada);
+ LANDFILL("und_US", English, LatinScript, UnitedStates);
+ LANDFILL("und_GB", English, LatinScript, UnitedKingdom);
+#undef LANDFILL
+}
+
+void tst_QLocale::ctor()
+{
+ QFETCH(const QLocale::Language, reqLang);
+ QFETCH(const QLocale::Script, reqText);
+ QFETCH(const QLocale::Territory, reqLand);
+
+ {
+ const QLocale l(reqLang, reqText, reqLand);
+ QTEST(l.language(), "expLang");
+ QTEST(l.script(), "expText");
+ QTEST(l.territory(), "expLand");
+ }
+ const QLatin1String request(QTest::currentDataTag());
+ if (!request.startsWith(u"und_")) {
+ const QLocale l(request);
+ QTEST(l.language(), "expLang");
+ QTEST(l.script(), "expText");
+ QTEST(l.territory(), "expLand");
+ }
+}
+
+void tst_QLocale::ctor_match_land()
+{
+ // QTBUG-64940: QLocale(Any, Any, land).territory() should normally be land:
+ constexpr QLocale::Territory exceptions[] = {
+ // There are, however, some exceptions:
+ QLocale::AmericanSamoa,
+ QLocale::Antarctica,
+ QLocale::AscensionIsland,
+ QLocale::BouvetIsland,
+ QLocale::CaribbeanNetherlands,
+ QLocale::ClippertonIsland,
+ QLocale::Curacao,
+ QLocale::Europe,
+ QLocale::EuropeanUnion,
+ QLocale::FrenchSouthernTerritories,
+ QLocale::Haiti,
+ QLocale::HeardAndMcDonaldIslands,
+ QLocale::OutlyingOceania,
+ QLocale::Palau,
+ QLocale::Samoa,
+ QLocale::SouthGeorgiaAndSouthSandwichIslands,
+ QLocale::TokelauTerritory,
+ QLocale::TristanDaCunha,
+ QLocale::TuvaluTerritory,
+ QLocale::Vanuatu
+ };
+ for (int i = int(QLocale::AnyTerritory) + 1; i <= int(QLocale::LastTerritory); ++i) {
+ const auto land = QLocale::Territory(i);
+ if (std::find(std::begin(exceptions), std::end(exceptions), land) != std::end(exceptions))
+ continue;
+ QCOMPARE(QLocale(QLocale::AnyLanguage, QLocale::AnyScript, land).territory(), land);
+ }
+}
+
+void tst_QLocale::defaulted_ctor()
+{
+ QLocale default_locale = QLocale::system();
+ QLocale::Language default_lang = default_locale.language();
+ QLocale::Territory default_country = default_locale.territory();
+
+ qDebug("Default: %s/%s", QLocale::languageToString(default_lang).toUtf8().constData(),
+ QLocale::territoryToString(default_country).toUtf8().constData());
+
+ {
+ QLocale l;
+ QCOMPARE(l.language(), default_lang);
+ QCOMPARE(l.territory(), default_country);
+ }
+
+ {
+ QLocale l(QLocale::C, QLocale::AnyTerritory);
+ QCOMPARE(l.language(), QLocale::C);
+ QCOMPARE(l.territory(), QLocale::AnyTerritory);
+ }
+
+#define CHECK_DEFAULT(lang, terr) \
+ do { \
+ const QLocale l; \
+ QCOMPARE(l.language(), lang); \
+ QCOMPARE(l.territory(), terr); \
+ } while (false)
+
+#define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \
+ do { \
+ const QLocale l(QLocale::req_lang, QLocale::req_country); \
+ QCOMPARE(l.language(), exp_lang); \
+ QCOMPARE(l.territory(), exp_country); \
+ } while (false)
+
+ TEST_CTOR(AnyLanguage, AnyTerritory, default_lang, default_country);
+ TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(Aymara, AnyTerritory, default_lang, default_country);
+ TEST_CTOR(Aymara, France, default_lang, default_country);
+
+ TEST_CTOR(English, AnyTerritory, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(French, France, QLocale::French, QLocale::France);
+ TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(Spanish, LatinAmerica, QLocale::Spanish,
+ QLocale::LatinAmerica);
+
+ QLocale::setDefault(QLocale(QLocale::English, QLocale::France));
+ CHECK_DEFAULT(QLocale::English, QLocale::UnitedStates);
+
+ TEST_CTOR(French, France, QLocale::French, QLocale::France);
+ TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(French, France, QLocale::French, QLocale::France);
+ TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(Aymara, AnyTerritory, QLocale::English, QLocale::UnitedStates);
+
+ QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom));
+ CHECK_DEFAULT(QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(French, France, QLocale::French, QLocale::France);
+ TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory);
+
+ QLocale::setDefault(QLocale(QLocale::Aymara, QLocale::France));
+ CHECK_DEFAULT(QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(Aymara, AnyTerritory, QLocale::English, QLocale::UnitedKingdom);
+ TEST_CTOR(Aymara, France, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(English, AnyTerritory, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(French, France, QLocale::French, QLocale::France);
+ TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory);
+
+ QLocale::setDefault(QLocale(QLocale::Aymara, QLocale::AnyTerritory));
+ CHECK_DEFAULT(QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(Aymara, AnyTerritory, QLocale::English, QLocale::UnitedKingdom);
+ TEST_CTOR(Aymara, France, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(English, AnyTerritory, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates);
+ TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom);
+
+ TEST_CTOR(French, France, QLocale::French, QLocale::France);
+ TEST_CTOR(C, AnyTerritory, QLocale::C, QLocale::AnyTerritory);
+ TEST_CTOR(C, France, QLocale::C, QLocale::AnyTerritory);
+
+ TEST_CTOR(Arabic, AnyTerritory, QLocale::Arabic, QLocale::Egypt);
+ TEST_CTOR(Dutch, AnyTerritory, QLocale::Dutch, QLocale::Netherlands);
+ TEST_CTOR(German, AnyTerritory, QLocale::German, QLocale::Germany);
+ TEST_CTOR(Greek, AnyTerritory, QLocale::Greek, QLocale::Greece);
+ TEST_CTOR(Malay, AnyTerritory, QLocale::Malay, QLocale::Malaysia);
+ TEST_CTOR(Persian, AnyTerritory, QLocale::Persian, QLocale::Iran);
+ TEST_CTOR(Portuguese, AnyTerritory, QLocale::Portuguese, QLocale::Brazil);
+ TEST_CTOR(Serbian, AnyTerritory, QLocale::Serbian, QLocale::Serbia);
+ TEST_CTOR(Somali, AnyTerritory, QLocale::Somali, QLocale::Somalia);
+ TEST_CTOR(Spanish, AnyTerritory, QLocale::Spanish, QLocale::Spain);
+ TEST_CTOR(Swedish, AnyTerritory, QLocale::Swedish, QLocale::Sweden);
+ TEST_CTOR(Uzbek, AnyTerritory, QLocale::Uzbek, QLocale::Uzbekistan);
+
+#undef TEST_CTOR
+#define TEST_CTOR(req_lc, exp_lang, exp_country) \
+ do { \
+ const QLocale l(req_lc); \
+ QCOMPARE(l.language(), QLocale::exp_lang); \
+ QCOMPARE(l.territory(), QLocale::exp_country); \
+ const QLocale m(QLocale::exp_lang, QLocale::exp_country); \
+ QCOMPARE(l, m); \
+ QCOMPARE(qHash(l), qHash(m)); \
+ } while (false)
+
+ QLocale::setDefault(QLocale(QLocale::C));
+ const QString empty;
+
+ TEST_CTOR("C", C, AnyTerritory);
+ TEST_CTOR("bla", C, AnyTerritory);
+ TEST_CTOR("zz", C, AnyTerritory);
+ TEST_CTOR("zz_zz", C, AnyTerritory);
+ TEST_CTOR("zz...", C, AnyTerritory);
+ TEST_CTOR("", C, AnyTerritory);
+ TEST_CTOR("en/", C, AnyTerritory);
+ TEST_CTOR(empty, C, AnyTerritory);
+ TEST_CTOR("en", English, UnitedStates);
+ TEST_CTOR("en", English, UnitedStates);
+ TEST_CTOR("en.", English, UnitedStates);
+ TEST_CTOR("en@", English, UnitedStates);
+ TEST_CTOR("en.@", English, UnitedStates);
+ TEST_CTOR("en_", English, UnitedStates);
+ TEST_CTOR("en_U", English, UnitedStates);
+ TEST_CTOR("en_.", English, UnitedStates);
+ TEST_CTOR("en_.@", English, UnitedStates);
+ TEST_CTOR("en.bla", English, UnitedStates);
+ TEST_CTOR("en@bla", English, UnitedStates);
+ TEST_CTOR("en_blaaa", English, UnitedStates);
+ TEST_CTOR("en_zz", English, UnitedStates);
+ TEST_CTOR("en_GB", English, UnitedKingdom);
+ TEST_CTOR("en_GB.bla", English, UnitedKingdom);
+ TEST_CTOR("en_GB@.bla", English, UnitedKingdom);
+ TEST_CTOR("en_GB@bla", English, UnitedKingdom);
+ TEST_CTOR("en-GB", English, UnitedKingdom);
+ TEST_CTOR("en-GB@bla", English, UnitedKingdom);
+ TEST_CTOR("eo", Esperanto, World);
+ TEST_CTOR("yi", Yiddish, Ukraine);
+
+ TEST_CTOR("no", NorwegianBokmal, Norway);
+ TEST_CTOR("nb", NorwegianBokmal, Norway);
+ TEST_CTOR("nn", NorwegianNynorsk, Norway);
+ TEST_CTOR("no_NO", NorwegianBokmal, Norway);
+ TEST_CTOR("nb_NO", NorwegianBokmal, Norway);
+ TEST_CTOR("nn_NO", NorwegianNynorsk, Norway);
+ TEST_CTOR("es_ES", Spanish, Spain);
+ TEST_CTOR("es_419", Spanish, LatinAmerica);
+ TEST_CTOR("es-419", Spanish, LatinAmerica);
+ TEST_CTOR("fr_MA", French, Morocco);
+
+ // test default countries for languages
+ TEST_CTOR("zh", Chinese, China);
+ TEST_CTOR("zh-Hans", Chinese, China);
+ TEST_CTOR("ne", Nepali, Nepal);
+
+#undef TEST_CTOR
+#define TEST_CTOR(req_lc, exp_lang, exp_script, exp_country) \
+ do { \
+ const QLocale l(req_lc); \
+ QCOMPARE(l.language(), QLocale::exp_lang); \
+ QCOMPARE(l.script(), QLocale::exp_script); \
+ QCOMPARE(l.territory(), QLocale::exp_country); \
+ } while (false)
+
+ TEST_CTOR("zh_CN", Chinese, SimplifiedHanScript, China);
+ TEST_CTOR("zh_Hans_CN", Chinese, SimplifiedHanScript, China);
+ TEST_CTOR("zh_Hans", Chinese, SimplifiedHanScript, China);
+ TEST_CTOR("zh_Hant", Chinese, TraditionalHanScript, Taiwan);
+ TEST_CTOR("zh_Hans_MO", Chinese, SimplifiedHanScript, Macau);
+ TEST_CTOR("zh_Hant_MO", Chinese, TraditionalHanScript, Macau);
+ TEST_CTOR("az_Latn_AZ", Azerbaijani, LatinScript, Azerbaijan);
+ TEST_CTOR("ha_NG", Hausa, LatinScript, Nigeria);
+
+ TEST_CTOR("ru", Russian, CyrillicScript, RussianFederation);
+ TEST_CTOR("ru_Cyrl", Russian, CyrillicScript, RussianFederation);
+
+#undef TEST_CTOR
+#undef CHECK_DEFAULT
+}
+
+#if QT_CONFIG(process)
+static inline bool runSysApp(const QString &binary,
+ const QStringList &args,
+ const QStringList &env,
+ QString *output,
+ QString *errorMessage)
+{
+ output->clear();
+ errorMessage->clear();
+ QProcess process;
+ process.setEnvironment(env);
+ process.start(binary, args);
+ process.closeWriteChannel();
+ if (!process.waitForStarted()) {
+ *errorMessage = QLatin1String("Cannot start '") + binary
+ + QLatin1String("': ") + process.errorString();
+ return false;
+ }
+ if (!process.waitForFinished()) {
+ process.kill();
+ *errorMessage = QStringLiteral("Timeout waiting for ") + binary;
+ return false;
+ }
+ *output = QString::fromLocal8Bit(process.readAllStandardOutput());
+ return true;
+}
+
+static inline bool runSysAppTest(const QString &binary,
+ QStringList baseEnv,
+ const QString &requestedLocale,
+ const QString &expectedOutput,
+ QString *errorMessage)
+{
+ QString output;
+ QStringList args;
+#ifdef Q_OS_MACOS
+ args << "-AppleLocale" << requestedLocale;
+#endif
+ baseEnv.append(QStringLiteral("LANG=") + requestedLocale);
+ if (!runSysApp(binary, args, baseEnv, &output, errorMessage))
+ return false;
+
+ if (output.isEmpty()) {
+ *errorMessage = QLatin1String("Empty output received for requested '") + requestedLocale
+ + QLatin1String("' (expected '") + expectedOutput + QLatin1String("')");
+ return false;
+ }
+ if (output != expectedOutput) {
+ *errorMessage = QLatin1String("Output mismatch for requested '") + requestedLocale
+ + QLatin1String("': Expected '") + expectedOutput + QLatin1String("', got '")
+ + output + QLatin1String("'");
+ return false;
+ }
+ return true;
+}
+#endif
+
+void tst_QLocale::systemLocale_data()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support");
+#endif
+#ifdef Q_OS_ANDROID
+ QSKIP("Can't start QProcess to run a custom user binary on Android");
+#endif
+
+ QTest::addColumn<QString>("expected");
+
+#define ADD_CTOR_TEST(give, expect) QTest::newRow(give) << QStringLiteral(expect);
+
+ // For format and meaning, see:
+ // http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
+ // Note that the accepted values for fields are implementation-dependent;
+ // the template is language[_territory][.codeset][@modifier]
+
+ // "Ordibehesht" is the name (as adapted to English, German or Norsk) of the
+ // second month of the Jalali calendar. If you see anything in Arabic,
+ // setDefault(Persian) has interfered with the system locale setup.
+
+ // Vanilla:
+ ADD_CTOR_TEST("C", "C Ordibehesht");
+
+ // Standard forms:
+ ADD_CTOR_TEST("en", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_GB", "en_GB Ordibehesht");
+ ADD_CTOR_TEST("de", "de_DE Ordibehescht");
+ // Norsk has some quirks:
+ ADD_CTOR_TEST("no", "nb_NO ordibehesht");
+ ADD_CTOR_TEST("nb", "nb_NO ordibehesht");
+ ADD_CTOR_TEST("nn", "nn_NO ordibehesht");
+ ADD_CTOR_TEST("no_NO", "nb_NO ordibehesht");
+ ADD_CTOR_TEST("nb_NO", "nb_NO ordibehesht");
+ ADD_CTOR_TEST("nn_NO", "nn_NO ordibehesht");
+
+ // Not too fussy about case:
+ ADD_CTOR_TEST("DE", "de_DE Ordibehescht");
+ ADD_CTOR_TEST("EN", "en_US Ordibehesht");
+
+ // Invalid fields
+ ADD_CTOR_TEST("bla", "C Ordibehesht");
+ ADD_CTOR_TEST("zz", "C Ordibehesht");
+ ADD_CTOR_TEST("zz_zz", "C Ordibehesht");
+ ADD_CTOR_TEST("zz...", "C Ordibehesht");
+ ADD_CTOR_TEST("en.bla", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en@bla", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_blaaa", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_zz", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_GB.bla", "en_GB Ordibehesht");
+ ADD_CTOR_TEST("en_GB@.bla", "en_GB Ordibehesht");
+ ADD_CTOR_TEST("en_GB@bla", "en_GB Ordibehesht");
+
+ // Empty optional fields, but with punctuators supplied
+ ADD_CTOR_TEST("en.", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en@", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en.@", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_.", "en_US Ordibehesht");
+ ADD_CTOR_TEST("en_.@", "en_US Ordibehesht");
+#undef ADD_CTOR_TEST
+
+#if QT_CONFIG(process) // for runSysApp
+ // Get default locale.
+ QString defaultLoc;
+ QString errorMessage;
+ if (runSysApp(m_sysapp, QStringList(), cleanEnv, &defaultLoc, &errorMessage)) {
+#if defined(Q_OS_MACOS)
+ QString localeForInvalidLocale = "C Ordibehesht";
+#else
+ QString localeForInvalidLocale = defaultLoc;
+#endif
+#define ADD_CTOR_TEST(give) QTest::newRow(give) << localeForInvalidLocale;
+ ADD_CTOR_TEST("en/");
+ ADD_CTOR_TEST("asdfghj");
+ ADD_CTOR_TEST("123456");
+#undef ADD_CTOR_TEST
+ } else {
+ qDebug() << "Skipping tests based on default locale" << qPrintable(errorMessage);
+ }
+#endif // process
+}
+
+void tst_QLocale::systemLocale()
+{
+#if QT_CONFIG(process) // for runSysAppTest
+ QLatin1String request(QTest::currentDataTag());
+ QFETCH(QString, expected);
+
+ // Test constructor without arguments (see syslocaleapp/syslocaleapp.cpp)
+ // Needs separate process because of caching of the system locale.
+ QString errorMessage;
+ QVERIFY2(runSysAppTest(m_sysapp, cleanEnv, request, expected, &errorMessage),
+ qPrintable(errorMessage));
+
+#else
+ // This won't be called, as _data() skipped out early.
+#endif // process
+}
+
+void tst_QLocale::legacyNames()
+{
+ QLocale::setDefault(QLocale(QLocale::C));
+
+#define TEST_CTOR(req_lc, exp_lang, exp_country) \
+ do { \
+ const QLocale l(req_lc); \
+ QCOMPARE(l.language(), QLocale::exp_lang); \
+ QCOMPARE(l.territory(), QLocale::exp_country); \
+ } while (false)
+
+ TEST_CTOR("mo_MD", Romanian, Moldova);
+ TEST_CTOR("no", NorwegianBokmal, Norway);
+ TEST_CTOR("sh_ME", Serbian, Montenegro);
+ TEST_CTOR("tl", Filipino, Philippines);
+ TEST_CTOR("iw", Hebrew, Israel);
+ TEST_CTOR("in", Indonesian, Indonesia);
+#undef TEST_CTOR
+}
+
+void tst_QLocale::consistentC()
+{
+ const QLocale c(QLocale::C);
+ QT_TEST_EQUALITY_OPS(c, QLocale::c(), true);
+ QT_TEST_EQUALITY_OPS(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory), true);
+ QVERIFY(QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
+ QLocale::AnyTerritory).contains(c));
+}
+
+void tst_QLocale::matchingLocales()
+{
+ const QLocale c(QLocale::C);
+ const QLocale ru_RU(QLocale::Russian, QLocale::Russia);
+ QT_TEST_EQUALITY_OPS(c, ru_RU, false);
+
+ QList<QLocale> locales = QLocale::matchingLocales(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory);
+ QCOMPARE(locales.size(), 1);
+ QVERIFY(locales.contains(c));
+
+ locales = QLocale::matchingLocales(QLocale::Russian, QLocale::CyrillicScript, QLocale::Russia);
+ QCOMPARE(locales.size(), 1);
+ QVERIFY(locales.contains(ru_RU));
+
+ locales = QLocale::matchingLocales(QLocale::Russian, QLocale::AnyScript, QLocale::AnyTerritory);
+ QVERIFY(!locales.isEmpty());
+ QVERIFY(!locales.contains(c));
+ QVERIFY(locales.contains(ru_RU));
+
+ locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::CyrillicScript, QLocale::AnyTerritory);
+ QVERIFY(!locales.isEmpty());
+ QVERIFY(!locales.contains(c));
+ QVERIFY(locales.contains(ru_RU));
+
+ locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::Russia);
+ QVERIFY(!locales.isEmpty());
+ QVERIFY(!locales.contains(c));
+ QVERIFY(locales.contains(ru_RU));
+
+ // Regression check for assertion failure when no locales match:
+ locales = QLocale::matchingLocales(QLocale::Abkhazian, QLocale::AnyScript, QLocale::AnyTerritory);
+ // Empty in CLDR v39, but don't require that.
+ QVERIFY(!locales.contains(c));
+ QVERIFY(!locales.contains(ru_RU));
+}
+
+void tst_QLocale::unixLocaleName_data()
+{
+ QTest::addColumn<QLocale::Language>("lang");
+ QTest::addColumn<QLocale::Territory>("land");
+ QTest::addColumn<QString>("expect");
+
+#define ADDROW(nom, lang, land, name) \
+ QTest::newRow(nom) << QLocale::lang << QLocale::land << QStringLiteral(name)
+
+ ADDROW("C_any", C, AnyTerritory, "C");
+ ADDROW("en_any", English, AnyTerritory, "en_US");
+ ADDROW("en_GB", English, UnitedKingdom, "en_GB");
+ ADDROW("ay_GB", Aymara, UnitedKingdom, "C");
+#undef ADDROW
+}
+
+void tst_QLocale::unixLocaleName()
+{
+ QFETCH(const QLocale::Language, lang);
+ QFETCH(const QLocale::Territory, land);
+ QFETCH(const QString, expect);
+ const auto expected = [expect](QChar ch) {
+ // Kludge around QString::replace() not being const.
+ QString copy = expect;
+ return copy.replace(u'_', ch);
+ };
+
+ QLocale::setDefault(QLocale(QLocale::C));
+
+ const QLocale locale(lang, land);
+ QCOMPARE(locale.name(), expect);
+ QCOMPARE(locale.name(QLocale::TagSeparator::Dash), expected(u'-'));
+ QCOMPARE(locale.name(QLocale::TagSeparator{'|'}), expected(u'|'));
+ QTest::ignoreMessage(QtWarningMsg, "QLocale::name(): "
+ "Using non-ASCII separator '\u00ff' (ff) is unsupported");
+ QCOMPARE(locale.name(QLocale::TagSeparator{'\xff'}), QString());
+}
+
+void tst_QLocale::toReal_data()
+{
+ QTest::addColumn<QString>("locale_name");
+ QTest::addColumn<QString>("num_str");
+ QTest::addColumn<bool>("good");
+ QTest::addColumn<double>("num");
+
+ QTest::newRow("C 1") << QString("C") << QString("1") << true << 1.0;
+ QTest::newRow("C 1.0") << QString("C") << QString("1.0") << true << 1.0;
+ QTest::newRow("C 1.234") << QString("C") << QString("1.234") << true << 1.234;
+ QTest::newRow("C 1.234e-10") << QString("C") << QString("1.234e-10") << true << 1.234e-10;
+ QTest::newRow("C 1.234E10") << QString("C") << QString("1.234E10") << true << 1.234e10;
+ QTest::newRow("C 1e10") << QString("C") << QString("1e10") << true << 1.0e10;
+ QTest::newRow("C 1e310") << QString("C") << QString("1e310") << false << std::numeric_limits<double>::infinity();
+ QTest::newRow("C 1E310") << QString("C") << QString("1E310") << false << std::numeric_limits<double>::infinity();
+ QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0;
+ QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0;
+ QTest::newRow("C 1 ") << QString("C") << QString("1 ") << true << 1.0;
+ QTest::newRow("C 1 ") << QString("C") << QString("1 ") << true << 1.0;
+
+ QTest::newRow("C 1,") << QString("C") << QString("1,") << false << 0.0;
+ QTest::newRow("C 1,2") << QString("C") << QString("1,2") << false << 0.0;
+ QTest::newRow("C 1,23") << QString("C") << QString("1,23") << false << 0.0;
+ QTest::newRow("C 1,234") << QString("C") << QString("1,234") << true << 1234.0;
+ QTest::newRow("C 1,234,") << QString("C") << QString("1,234,") << false << 0.0;
+ QTest::newRow("C 1,234,5") << QString("C") << QString("1,234,5") << false << 0.0;
+ QTest::newRow("C 1,234,56") << QString("C") << QString("1,234,56") << false << 0.0;
+ QTest::newRow("C 1,234,567") << QString("C") << QString("1,234,567") << true << 1234567.0;
+ QTest::newRow("C 1,234,567.") << QString("C") << QString("1,234,567.") << true << 1234567.0;
+ QTest::newRow("C 1,234,567.8") << QString("C") << QString("1,234,567.8") << true << 1234567.8;
+ QTest::newRow("C 1,234567.8") << QString("C") << QString("1,234567.8") << false << 0.0;
+ QTest::newRow("C 12,34567.8") << QString("C") << QString("12,34567.8") << false << 0.0;
+ QTest::newRow("C 1234,567.8") << QString("C") << QString("1234,567.8") << false << 0.0;
+ QTest::newRow("C 1234567.8") << QString("C") << QString("1234567.8") << true << 1234567.8;
+ QTest::newRow("C ,") << QString("C") << QString(",") << false << 0.0;
+ QTest::newRow("C ,123") << QString("C") << QString(",123") << false << 0.0;
+ QTest::newRow("C ,3") << QString("C") << QString(",3") << false << 0.0;
+ QTest::newRow("C , 3") << QString("C") << QString(", 3") << false << 0.0;
+ QTest::newRow("C , 3") << QString("C") << QString(", 3") << false << 0.0;
+ QTest::newRow("C , 3.2") << QString("C") << QString(", 3.2") << false << 0.0;
+ QTest::newRow("C , 3.2e2") << QString("C") << QString(", 3.2e2") << false << 0.0;
+ QTest::newRow("C , e2") << QString("C") << QString(", e2") << false << 0.0;
+ QTest::newRow("C 1,,234") << QString("C") << QString("1,,234") << false << 0.0;
+
+ QTest::newRow("C empty") << QString("C") << QString("") << false << 0.0;
+ QTest::newRow("C null") << QString("C") << QString() << false << 0.0;
+ QTest::newRow("C .") << QString("C") << QString(".") << false << 0.0;
+ QTest::newRow("C 1e") << QString("C") << QString("1e") << false << 0.0;
+ QTest::newRow("C 1,0") << QString("C") << QString("1,0") << false << 0.0;
+ QTest::newRow("C 1,000") << QString("C") << QString("1,000") << true << 1000.0;
+ QTest::newRow("C 1,000e-6") << QString("C") << QString("1,000e-6") << true << 1000.0e-6;
+ QTest::newRow("C 1e1.0") << QString("C") << QString("1e1.0") << false << 0.0;
+ QTest::newRow("C 1e+") << QString("C") << QString("1e+") << false << 0.0;
+ QTest::newRow("C 1e-") << QString("C") << QString("1e-") << false << 0.0;
+
+ QTest::newRow("C .1") << QString("C") << QString(".1") << true << 0.1;
+ QTest::newRow("C -.1") << QString("C") << QString("-.1") << true << -0.1;
+ QTest::newRow("C 1.") << QString("C") << QString("1.") << true << 1.0;
+ QTest::newRow("C 1.E10") << QString("C") << QString("1.E10") << true << 1.0e10;
+ QTest::newRow("C 1e+10") << QString("C") << QString("1e+10") << true << 1.0e+10;
+
+ QTest::newRow("de_DE 1.") << QString("de_DE") << QString("1.") << false << 0.0;
+ QTest::newRow("de_DE 1.2") << QString("de_DE") << QString("1.2") << false << 0.0;
+ QTest::newRow("de_DE 1.23") << QString("de_DE") << QString("1.23") << false << 0.0;
+ QTest::newRow("de_DE 1.234") << QString("de_DE") << QString("1.234") << true << 1234.0;
+ QTest::newRow("de_DE 1.234,") << QString("de_DE") << QString("1.234.") << false << 0.0;
+ QTest::newRow("de_DE 1.234.5") << QString("de_DE") << QString("1.234.5") << false << 0.0;
+ QTest::newRow("de_DE 1.234.56") << QString("de_DE") << QString("1.234.56") << false << 0.0;
+ QTest::newRow("de_DE 1.234.567") << QString("de_DE") << QString("1.234.567") << true << 1234567.0;
+ QTest::newRow("de_DE 1.234.567,") << QString("de_DE") << QString("1.234.567,") << true << 1234567.0;
+ QTest::newRow("de_DE 1.234.567,8") << QString("de_DE") << QString("1.234.567,8") << true << 1234567.8;
+ QTest::newRow("de_DE 1.234567,8") << QString("de_DE") << QString("1.234567,8") << false << 0.0;
+ QTest::newRow("de_DE 12.34567,8") << QString("de_DE") << QString("12.34567,8") << false << 0.0;
+ QTest::newRow("de_DE 1234.567,8") << QString("de_DE") << QString("1234.567,8") << false << 0.0;
+ QTest::newRow("de_DE 1234567,8") << QString("de_DE") << QString("1234567,8") << true << 1234567.8;
+ QTest::newRow("de_DE .123") << QString("de_DE") << QString(".123") << false << 0.0;
+ QTest::newRow("de_DE .3") << QString("de_DE") << QString(".3") << false << 0.0;
+ QTest::newRow("de_DE . 3") << QString("de_DE") << QString(". 3") << false << 0.0;
+ QTest::newRow("de_DE . 3") << QString("de_DE") << QString(". 3") << false << 0.0;
+ QTest::newRow("de_DE . 3,2") << QString("de_DE") << QString(". 3,2") << false << 0.0;
+ QTest::newRow("de_DE . 3,2e2") << QString("de_DE") << QString(". 3,2e2") << false << 0.0;
+ QTest::newRow("de_DE . e2") << QString("de_DE") << QString(". e2") << false << 0.0;
+ QTest::newRow("de_DE 1..234") << QString("de_DE") << QString("1..234") << false << 0.0;
+
+ QTest::newRow("de_DE 1") << QString("de_DE") << QString("1") << true << 1.0;
+ QTest::newRow("de_DE 1.0") << QString("de_DE") << QString("1.0") << false << 0.0;
+ QTest::newRow("de_DE 1.234e-10") << QString("de_DE") << QString("1.234e-10") << true << 1234.0e-10;
+ QTest::newRow("de_DE 1.234E10") << QString("de_DE") << QString("1.234E10") << true << 1234.0e10;
+ QTest::newRow("de_DE 1e10") << QString("de_DE") << QString("1e10") << true << 1.0e10;
+ QTest::newRow("de_DE .1") << QString("de_DE") << QString(".1") << false << 0.0;
+ QTest::newRow("de_DE -.1") << QString("de_DE") << QString("-.1") << false << 0.0;
+ QTest::newRow("de_DE 1.E10") << QString("de_DE") << QString("1.E10") << false << 0.0;
+ QTest::newRow("de_DE 1e+10") << QString("de_DE") << QString("1e+10") << true << 1.0e+10;
+
+ QTest::newRow("de_DE 1,0") << QString("de_DE") << QString("1,0") << true << 1.0;
+ QTest::newRow("de_DE 1,234") << QString("de_DE") << QString("1,234") << true << 1.234;
+ QTest::newRow("de_DE 1,234e-10") << QString("de_DE") << QString("1,234e-10") << true << 1.234e-10;
+ QTest::newRow("de_DE 1,234E10") << QString("de_DE") << QString("1,234E10") << true << 1.234e10;
+ QTest::newRow("de_DE ,1") << QString("de_DE") << QString(",1") << true << 0.1;
+ QTest::newRow("de_DE -,1") << QString("de_DE") << QString("-,1") << true << -0.1;
+ QTest::newRow("de_DE 1,") << QString("de_DE") << QString("1,") << true << 1.0;
+ QTest::newRow("de_DE 1,E10") << QString("de_DE") << QString("1,E10") << true << 1.0e10;
+
+ QTest::newRow("de_DE empty") << QString("de_DE") << QString("") << false << 0.0;
+ QTest::newRow("de_DE null") << QString("de_DE") << QString() << false << 0.0;
+ QTest::newRow("de_DE .") << QString("de_DE") << QString(".") << false << 0.0;
+ QTest::newRow("de_DE 1e") << QString("de_DE") << QString("1e") << false << 0.0;
+ QTest::newRow("de_DE 1e1.0") << QString("de_DE") << QString("1e1.0") << false << 0.0;
+ QTest::newRow("de_DE 1e+") << QString("de_DE") << QString("1e+") << false << 0.0;
+ QTest::newRow("de_DE 1e-") << QString("de_DE") << QString("1e-") << false << 0.0;
+
+ QTest::newRow("C 9,876543") << QString("C") << QString("9,876543") << false << 0.0;
+ QTest::newRow("C 9,876543.2") << QString("C") << QString("9,876543.2") << false << 0.0;
+ QTest::newRow("C 9,876543e-2") << QString("C") << QString("9,876543e-2") << false << 0.0;
+ QTest::newRow("C 9,876543.0e-2") << QString("C") << QString("9,876543.0e-2") << false << 0.0;
+
+ QTest::newRow("de_DE 9.876543") << QString("de_DE") << QString("9876.543") << false << 0.0;
+ QTest::newRow("de_DE 9.876543,2") << QString("de_DE") << QString("9.876543,2") << false << 0.0;
+ QTest::newRow("de_DE 9.876543e-2") << QString("de_DE") << QString("9.876543e-2") << false << 0.0;
+ QTest::newRow("de_DE 9.876543,0e-2") << QString("de_DE") << QString("9.876543,0e-2") << false << 0.0;
+ QTest::newRow("de_DE 9.876543e--2") << QString("de_DE") << QString("9.876543e")+QChar(8722)+QString("2") << false << 0.0;
+ QTest::newRow("de_DE 9.876543,0e--2") << QString("de_DE") << QString("9.876543,0e")+QChar(8722)+QString("2") << false << 0.0;
+
+ // Signs and exponent separator aren't single characters:
+ QTest::newRow("sv_SE 4e-3") // Swedish, Sweden
+ << u"sv_SE"_s << u"4\u00d7" "10^\u2212" "03"_s << true << 4e-3;
+ QTest::newRow("sv_SE 4x-3") // Only first character of exponent
+ << u"sv_SE"_s << u"4\u00d7\u2212" "03"_s << false << 0.0;
+ QTest::newRow("se_NO 4e-3") // Northern Sami, Norway
+ << u"se_NO"_s << u"4\u00b7" "10^\u2212" "03"_s << true << 4e-3;
+ QTest::newRow("se_NO 4x-3") // Only first character of exponent
+ << u"se_NO"_s << u"4\u00b7\u2212" "03"_s << false << 0.0;
+ QTest::newRow("ar_EG 4e-3") // Arabic, Egypt
+ << u"ar_EG"_s << u"\u0664\u0623\u0633\u061c-\u0660\u0663"_s << true << 4e-3;
+ QTest::newRow("ar_EG 4e!3") // Only first character of sign:
+ << u"ar_EG"_s << u"\u0664\u0623\u0633\u061c\u0660\u0663"_s << false << 0.0;
+ QTest::newRow("ar_EG 4x-3") // Only first character of exponent
+ << u"ar_EG"_s << u"\u0664\u0623\u061c-\u0660\u0663"_s << false << 0.0;
+ QTest::newRow("ar_EG 4x!3") // Only first character of exponent and sign
+ << u"ar_EG"_s << u"\u0664\u0623\u061c\u0660\u0663"_s << false << 0.0;
+ QTest::newRow("fa_IR 4e-3") // Farsi, Iran
+ << u"fa_IR"_s << u"\u06f4\u00d7\u06f1\u06f0^\u200e\u2212\u06f0\u06f3"_s << true << 4e-3;
+ QTest::newRow("fa_IR 4e!3") // Only first character of sign:
+ << u"fa_IR"_s << u"\u06f4\u00d7\u06f1\u06f0^\u200e\u06f0\u06f3"_s << false << 0.0;
+ QTest::newRow("fa_IR 4x-3") // Only first character of exponent
+ << u"fa_IR"_s << u"\u06f4\u00d7\u200e\u2212\u06f0\u06f3"_s << false << 0.0;
+ QTest::newRow("fa_IR 4x!3") // Only first character of exponent and sign
+ << u"fa_IR"_s << u"\u06f4\u00d7\u200e\u06f0\u06f3"_s << false << 0.0;
+
+ // Cyrillic has its own E; only officially used by Ukrainian as exponent,
+ // with other Cyrillic locales using the Latin E. QLocale allows that there
+ // may be some cross-over between these.
+ QTest::newRow("uk_UA Cyrillic E") << u"uk_UA"_s << u"4\u0415-3"_s << true << 4e-3; // Official
+ QTest::newRow("uk_UA Latin E") << u"uk_UA"_s << u"4E-3"_s << true << 4e-3;
+ QTest::newRow("uk_UA Cyrilic e") << u"uk_UA"_s << u"4\u0435-3"_s << true << 4e-3;
+ QTest::newRow("uk_UA Latin e") << u"uk_UA"_s << u"4e-3"_s << true << 4e-3;
+ QTest::newRow("ru_RU Latin E") << u"ru_RU"_s << u"4E-3"_s << true << 4e-3; // Official
+ QTest::newRow("ru_RU Cyrillic E") << u"ru_RU"_s << u"4\u0415-3"_s << true << 4e-3;
+ QTest::newRow("ru_RU Latin e") << u"ru_RU"_s << u"4e-3"_s << true << 4e-3;
+ QTest::newRow("ru_RU Cyrilic e") << u"ru_RU"_s << u"4\u0435-3"_s << true << 4e-3;
+}
+
+void tst_QLocale::stringToDouble_data()
+{
+ toReal_data();
+ if (std::numeric_limits<double>::has_infinity) {
+ double huge = std::numeric_limits<double>::infinity();
+ QTest::newRow("C inf") << QString("C") << QString("inf") << true << huge;
+ QTest::newRow("C +inf") << QString("C") << QString("+inf") << true << +huge;
+ QTest::newRow("C -inf") << QString("C") << QString("-inf") << true << -huge;
+ // Overflow:
+ QTest::newRow("C huge") << QString("C") << QString("2e308") << false << huge;
+ QTest::newRow("C -huge") << QString("C") << QString("-2e308") << false << -huge;
+ }
+ if (std::numeric_limits<double>::has_quiet_NaN)
+ QTest::newRow("C qnan") << QString("C") << QString("NaN") << true << std::numeric_limits<double>::quiet_NaN();
+
+ // In range (but outside float's range):
+ QTest::newRow("C big") << QString("C") << QString("3.5e38") << true << 3.5e38;
+ QTest::newRow("C -big") << QString("C") << QString("-3.5e38") << true << -3.5e38;
+ QTest::newRow("C small") << QString("C") << QString("1e-45") << true << 1e-45;
+ QTest::newRow("C -small") << QString("C") << QString("-1e-45") << true << -1e-45;
+
+ // Underflow:
+ QTest::newRow("C tiny") << QString("C") << QString("2e-324") << false << 0.;
+ QTest::newRow("C -tiny") << QString("C") << QString("-2e-324") << false << 0.;
+
+ // Test a tiny fraction (well beyond denomal) with a huge exponent:
+ const QString zeros(500, '0');
+ QTest::newRow("C tiny fraction, huge exponent")
+ << u"C"_s << u"0."_s + zeros + u"123e501"_s << true << 1.23;
+ QTest::newRow("uk_UA tiny fraction, huge exponent")
+ << u"uk_UA"_s << u"0,"_s + zeros + u"123\u0415" "501"_s << true << 1.23;
+}
+
+void tst_QLocale::stringToDouble()
+{
+#define MY_DOUBLE_EPSILON (2.22045e-16) // 1/2^{52}; double has a 53-bit mantissa
+
+ QFETCH(QString, locale_name);
+ QFETCH(QString, num_str);
+ QFETCH(bool, good);
+ QFETCH(double, num);
+ QStringView num_strRef{ num_str };
+
+ QLocale locale(locale_name);
+ QCOMPARE(locale.name(), locale_name);
+
+ bool ok;
+ double d = locale.toDouble(num_str, &ok);
+ QCOMPARE(ok, good);
+
+ {
+ // Make sure result is independent of locale:
+ TransientLocale ignoreme(LC_ALL, "ar_SA.UTF-8");
+ QCOMPARE(locale.toDouble(num_str, &ok), d);
+ QCOMPARE(ok, good);
+ }
+
+ if (ok || std::isinf(num)) {
+ // First use fuzzy-compare, then a more precise check:
+ QCOMPARE(d, num);
+ if (std::isfinite(num)) {
+ double diff = d > num ? d - num : num - d;
+ QCOMPARE_LE(diff, MY_DOUBLE_EPSILON);
+ }
+ }
+
+ d = locale.toDouble(num_strRef, &ok);
+ QCOMPARE(ok, good);
+
+ if (ok || std::isinf(num)) {
+ QCOMPARE(d, num);
+ if (std::isfinite(num)) {
+ double diff = d > num ? d - num : num - d;
+ QCOMPARE_LE(diff, MY_DOUBLE_EPSILON);
+ }
+ }
+#undef MY_DOUBLE_EPSILON
+}
+
+void tst_QLocale::stringToFloat_data()
+{
+ using Bounds = std::numeric_limits<float>;
+ toReal_data();
+ const QString C(QStringLiteral("C"));
+ if (Bounds::has_infinity) {
+ double huge = Bounds::infinity();
+ QTest::newRow("C inf") << C << QString("inf") << true << huge;
+ QTest::newRow("C +inf") << C << QString("+inf") << true << +huge;
+ QTest::newRow("C -inf") << C << QString("-inf") << true << -huge;
+ // Overflow float, but not double:
+ QTest::newRow("C big") << C << QString("3.5e38") << false << huge;
+ QTest::newRow("C -big") << C << QString("-3.5e38") << false << -huge;
+ // Overflow double, too:
+ QTest::newRow("C huge") << C << QString("2e308") << false << huge;
+ QTest::newRow("C -huge") << C << QString("-2e308") << false << -huge;
+ }
+ if (Bounds::has_quiet_NaN)
+ QTest::newRow("C qnan") << C << QString("NaN") << true << double(Bounds::quiet_NaN());
+
+ // Minimal float: shouldn't underflow
+ QTest::newRow("C float min")
+ << C << QLocale::c().toString(Bounds::denorm_min()) << true << double(Bounds::denorm_min());
+ QTest::newRow("C float -min")
+ << C << QLocale::c().toString(-Bounds::denorm_min()) << true << -double(Bounds::denorm_min());
+
+ // Underflow float, but not double:
+ QTest::newRow("C small") << C << QString("7e-46") << false << 0.;
+ QTest::newRow("C -small") << C << QString("-7e-46") << false << 0.;
+ using Double = std::numeric_limits<double>;
+ QTest::newRow("C double min")
+ << C << QLocale::c().toString(Double::denorm_min()) << false << 0.0;
+ QTest::newRow("C double -min")
+ << C << QLocale::c().toString(-Double::denorm_min()) << false << 0.0;
+
+ // Underflow double, too:
+ QTest::newRow("C tiny") << C << QString("2e-324") << false << 0.;
+ QTest::newRow("C -tiny") << C << QString("-2e-324") << false << 0.;
+
+ // Test a small fraction (well beyond denomal) with a big exponent:
+ const QString zeros(80, '0');
+ QTest::newRow("C small fraction, big exponent")
+ << u"C"_s << u"0."_s + zeros + u"123e81"_s << true << 1.23;
+ QTest::newRow("uk_UA small fraction, big exponent")
+ << u"uk_UA"_s << u"0,"_s + zeros + u"123\u0415" "81"_s << true << 1.23;
+}
+
+void tst_QLocale::stringToFloat()
+{
+#define MY_FLOAT_EPSILON (2.384e-7) // 1/2^{22}; float has a 23-bit mantissa
+
+ QFETCH(QString, locale_name);
+ QFETCH(QString, num_str);
+ QFETCH(bool, good);
+ QFETCH(double, num);
+ QStringView num_strRef{ num_str };
+ float fnum = num;
+
+ QLocale locale(locale_name);
+ QCOMPARE(locale.name(), locale_name);
+
+ if constexpr (std::numeric_limits<float>::has_denorm != std::denorm_present) {
+ if (qstrcmp(QTest::currentDataTag(), "C float -min") == 0
+ || qstrcmp(QTest::currentDataTag(), "C float min") == 0)
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+ bool ok;
+ float f = locale.toFloat(num_str, &ok);
+ QCOMPARE(ok, good);
+
+ if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) {
+ if (qstrcmp(QTest::currentDataTag(), "C double min") == 0
+ || qstrcmp(QTest::currentDataTag(), "C double -min") == 0
+ || qstrcmp(QTest::currentDataTag(), "C tiny") == 0
+ || qstrcmp(QTest::currentDataTag(), "C -tiny") == 0) {
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+ }
+
+ {
+ // Make sure result is independent of locale:
+ TransientLocale ignoreme(LC_ALL, "ar_SA.UTF-8");
+ QCOMPARE(locale.toFloat(num_str, &ok), f);
+ QCOMPARE(ok, good);
+ }
+
+ if (ok || std::isinf(fnum)) {
+ // First use fuzzy-compare, then a more precise check:
+ QCOMPARE(f, fnum);
+ if (std::isfinite(fnum)) {
+ float diff = f > fnum ? f - fnum : fnum - f;
+ QCOMPARE_LE(diff, MY_FLOAT_EPSILON);
+ }
+ }
+
+ f = locale.toFloat(num_strRef, &ok);
+ QCOMPARE(ok, good);
+
+ if (ok || std::isinf(fnum)) {
+ QCOMPARE(f, fnum);
+ if (std::isfinite(fnum)) {
+ float diff = f > fnum ? f - fnum : fnum - f;
+ QCOMPARE_LE(diff, MY_FLOAT_EPSILON);
+ }
+ }
+#undef MY_FLOAT_EPSILON
+}
+
+void tst_QLocale::doubleToString_data()
+{
+ QTest::addColumn<QString>("localeName");
+ QTest::addColumn<QString>("numStr");
+ QTest::addColumn<double>("num");
+ QTest::addColumn<char>("mode");
+ QTest::addColumn<int>("precision");
+
+ int shortest = QLocale::FloatingPointShortest;
+
+ QTest::newRow("C 0 f 0") << QString("C") << QString("0") << 0.0 << 'f' << 0;
+ QTest::newRow("C 0 f 5") << QString("C") << QString("0.00000") << 0.0 << 'f' << 5;
+ QTest::newRow("C 0 f -") << QString("C") << QString("0") << 0.0 << 'f' << shortest;
+ QTest::newRow("C 0 e 0") << QString("C") << QString("0e+00") << 0.0 << 'e' << 0;
+ QTest::newRow("C 0 e 5") << QString("C") << QString("0.00000e+00") << 0.0 << 'e' << 5;
+ QTest::newRow("C 0 e -") << QString("C") << QString("0e+00") << 0.0 << 'e' << shortest;
+ QTest::newRow("C 0 g 0") << QString("C") << QString("0") << 0.0 << 'g' << 0;
+ QTest::newRow("C 0 g 5") << QString("C") << QString("0") << 0.0 << 'g' << 5;
+ QTest::newRow("C 0 g -") << QString("C") << QString("0") << 0.0 << 'g' << shortest;
+
+ double d = std::numeric_limits<double>::max();
+ static const char doublemaxfixed[] =
+ "1797693134862315708145274237317043567980705675258449965989174768031572607800285387605"
+ "8955863276687817154045895351438246423432132688946418276846754670353751698604991057655"
+ "1282076245490090389328944075868508455133942304583236903222948165808559332123348274797"
+ "826204144723168738177180919299881250404026184124858368";
+
+ QTest::newRow("C max f 0") << QString("C") << QString(doublemaxfixed) << d << 'f' << 0;
+ QTest::newRow("C max f 5") << QString("C") << doublemaxfixed + QString(".00000") << d << 'f' << 5;
+ QTest::newRow("C max e 0") << QString("C") << QString("2e+308") << d << 'e' << 0;
+ QTest::newRow("C max g 0") << QString("C") << QString("2e+308") << d << 'g' << 0;
+ QTest::newRow("C max e 5") << QString("C") << QString("1.79769e+308") << d << 'e' << 5;
+ QTest::newRow("C max g 5") << QString("C") << QString("1.7977e+308") << d << 'g' << 5;
+#if QT_CONFIG(doubleconversion)
+ QTest::newRow("C max e -") << QString("C") << QString("1.7976931348623157e+308") << d << 'e' << shortest;
+ QTest::newRow("C max g -") << QString("C") << QString("1.7976931348623157e+308") << d << 'g' << shortest;
+ QTest::newRow("C max f -") << QString("C")
+ << QString("%1").arg("17976931348623157", -int(strlen(doublemaxfixed)), u'0')
+ << d << 'f' << shortest;
+#endif
+
+ d = std::numeric_limits<double>::min();
+ QTest::newRow("C min f 0") << QString("C") << QString("0") << d << 'f' << 0;
+ QTest::newRow("C min f 5") << QString("C") << QString("0.00000") << d << 'f' << 5;
+ QTest::newRow("C min e 0") << QString("C") << QString("2e-308") << d << 'e' << 0;
+ QTest::newRow("C min g 0") << QString("C") << QString("2e-308") << d << 'g' << 0;
+ QTest::newRow("C min e 5") << QString("C") << QString("2.22507e-308") << d << 'e' << 5;
+ QTest::newRow("C min g 5") << QString("C") << QString("2.2251e-308") << d << 'g' << 5;
+#if QT_CONFIG(doubleconversion)
+ QTest::newRow("C min e -") << QString("C") << QString("2.2250738585072014e-308") << d << 'e' << shortest;
+ QTest::newRow("C min f -") << QString("C")
+ << QString("0.%1").arg("22250738585072014", 308 - 1 + std::numeric_limits<double>::max_digits10, u'0')
+ << d << 'f' << shortest;
+ QTest::newRow("C min g -") << QString("C") << QString("2.2250738585072014e-308") << d << 'g' << shortest;
+#endif
+
+ QTest::newRow("C 3.4 f 5") << QString("C") << QString("3.40000") << 3.4 << 'f' << 5;
+ QTest::newRow("C 3.4 f 0") << QString("C") << QString("3") << 3.4 << 'f' << 0;
+ QTest::newRow("C 3.4 e 5") << QString("C") << QString("3.40000e+00") << 3.4 << 'e' << 5;
+ QTest::newRow("C 3.4 e 0") << QString("C") << QString("3e+00") << 3.4 << 'e' << 0;
+ QTest::newRow("C 3.4 g 5") << QString("C") << QString("3.4") << 3.4 << 'g' << 5;
+ QTest::newRow("C 3.4 g 1") << QString("C") << QString("3") << 3.4 << 'g' << 1;
+
+ QTest::newRow("C 3.4 f 1") << QString("C") << QString("3.4") << 3.4 << 'f' << 1;
+ QTest::newRow("C 3.4 f -") << QString("C") << QString("3.4") << 3.4 << 'f' << shortest;
+ QTest::newRow("C 3.4 e 1") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << 1;
+ QTest::newRow("C 3.4 e -") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << shortest;
+ QTest::newRow("C 3.4 g 2") << QString("C") << QString("3.4") << 3.4 << 'g' << 2;
+ QTest::newRow("C 3.4 g -") << QString("C") << QString("3.4") << 3.4 << 'g' << shortest;
+
+ QTest::newRow("de_DE 3,4 f 1") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << 1;
+ QTest::newRow("de_DE 3,4 f -") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << shortest;
+ QTest::newRow("de_DE 3,4 e 1") << QString("de_DE") << QString("3,4E+00") << 3.4 << 'e' << 1;
+ QTest::newRow("de_DE 3,4 e -") << QString("de_DE") << QString("3,4E+00") << 3.4 << 'e' << shortest;
+ QTest::newRow("de_DE 3,4 g 2") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << 2;
+ QTest::newRow("de_DE 3,4 g -") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << shortest;
+
+ QTest::newRow("C 0.035003945 f 12") << QString("C") << QString("0.035003945000") << 0.035003945 << 'f' << 12;
+ QTest::newRow("C 0.035003945 f 6") << QString("C") << QString("0.035004") << 0.035003945 << 'f' << 6;
+ QTest::newRow("C 0.035003945 e 10") << QString("C") << QString("3.5003945000e-02") << 0.035003945 << 'e' << 10;
+ QTest::newRow("C 0.035003945 e 4") << QString("C") << QString("3.5004e-02") << 0.035003945 << 'e' << 4;
+ QTest::newRow("C 0.035003945 g 11") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 11;
+ QTest::newRow("C 0.035003945 g 5") << QString("C") << QString("0.035004") << 0.035003945 << 'g' << 5;
+
+ QTest::newRow("C 0.035003945 f 9") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << 9;
+ QTest::newRow("C 0.035003945 f -") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << shortest;
+ QTest::newRow("C 0.035003945 e 7") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << 7;
+ QTest::newRow("C 0.035003945 e -") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << shortest;
+ QTest::newRow("C 0.035003945 g 8") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 8;
+ QTest::newRow("C 0.035003945 g -") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << shortest;
+
+ QTest::newRow("de_DE 0,035003945 f 9") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << 9;
+ QTest::newRow("de_DE 0,035003945 f -") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << shortest;
+ QTest::newRow("de_DE 0,035003945 e 7") << QString("de_DE") << QString("3,5003945E-02") << 0.035003945 << 'e' << 7;
+ QTest::newRow("de_DE 0,035003945 e -") << QString("de_DE") << QString("3,5003945E-02") << 0.035003945 << 'e' << shortest;
+ QTest::newRow("de_DE 0,035003945 g 8") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << 8;
+ QTest::newRow("de_DE 0,035003945 g -") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << shortest;
+ // Check 'f/F' iff (adjusted) precision > exponent >= -4:
+ QTest::newRow("de_DE 12345 g 4") << QString("de_DE") << QString("1,235E+04") << 12345. << 'g' << 4;
+ QTest::newRow("de_DE 1e7 g 8") << QString("de_DE") << QString("10.000.000") << 1e7 << 'g' << 8;
+ QTest::newRow("de_DE 1e8 g 8") << QString("de_DE") << QString("1E+08") << 1e8 << 'g' << 8;
+ QTest::newRow("de_DE 10.0 g 1") << QString("de_DE") << QString("1E+01") << 10.0 << 'g' << 1;
+ QTest::newRow("de_DE 10.0 g 0") << QString("de_DE") << QString("1E+01") << 10.0 << 'g' << 0;
+ QTest::newRow("de_DE 1.0 g 0") << QString("de_DE") << QString("1") << 1.0 << 'g' << 0;
+ QTest::newRow("de_DE 0.0001 g 0") << QString("de_DE") << QString("0,0001") << 0.0001 << 'g' << 0;
+ QTest::newRow("de_DE 0.00001 g 0") << QString("de_DE") << QString("1E-05") << 0.00001 << 'g' << 0;
+ // Check transition to exponent form:
+ QTest::newRow("de_DE 1245678900 g -") << QString("de_DE") << QString("1.245.678.900") << 12456789e2 << 'g' << shortest;
+ QTest::newRow("de_DE 12456789100 g -") << QString("de_DE") << QString("12.456.789.100") << 124567891e2 << 'g' << shortest;
+ QTest::newRow("de_DE 12456789000 g -") << QString("de_DE") << QString("1,2456789E+10") << 12456789e3 << 'g' << shortest;
+ QTest::newRow("de_DE 12000 g -")
+ << QString("de_DE") << QString("12.000") << 12e3 << 'g' << shortest;
+ // 12e4 has "120.000" and "1.2E+05" of equal length; which shortest picks is unspecified.
+ QTest::newRow("de_DE 1200000 g -") << QString("de_DE") << QString("1,2E+06") << 12e5 << 'g' << shortest;
+ QTest::newRow("de_DE 1000 g -") << QString("de_DE") << QString("1.000") << 1e3 << 'g' << shortest;
+ QTest::newRow("de_DE 10000 g -") << QString("de_DE") << QString("1E+04") << 1e4 << 'g' << shortest;
+
+ QTest::newRow("C 0.000003945 f 12") << QString("C") << QString("0.000003945000") << 0.000003945 << 'f' << 12;
+ QTest::newRow("C 0.000003945 f 6") << QString("C") << QString("0.000004") << 0.000003945 << 'f' << 6;
+ QTest::newRow("C 0.000003945 e 6") << QString("C") << QString("3.945000e-06") << 0.000003945 << 'e' << 6;
+ QTest::newRow("C 0.000003945 e 0") << QString("C") << QString("4e-06") << 0.000003945 << 'e' << 0;
+ QTest::newRow("C 0.000003945 g 7") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 7;
+ QTest::newRow("C 0.000003945 g 1") << QString("C") << QString("4e-06") << 0.000003945 << 'g' << 1;
+ QTest::newRow("sv_SE 0.000003945 g 1") // Swedish, Sweden (among others)
+ << u"sv_SE"_s << u"4\u00d7" "10^\u2212" "06"_s << 0.000003945 << 'g' << 1;
+ QTest::newRow("sv_SE 3945e3 g 1")
+ << u"sv_SE"_s << u"4\u00d7" "10^+06"_s << 3945e3 << 'g' << 1;
+ QTest::newRow("se 0.000003945 g 1") // Northern Sami
+ << u"se"_s << u"4\u00b7" "10^\u2212" "06"_s << 0.000003945 << 'g' << 1;
+ QTest::newRow("ar_EG 0.000003945 g 1") // Arabic, Egypt (among others)
+ << u"ar_EG"_s << u"\u0664\u0623\u0633\u061c-\u0660\u0666"_s << 0.000003945 << 'g' << 1;
+ QTest::newRow("ar_EG 3945e3 g 1")
+ << u"ar_EG"_s << u"\u0664\u0623\u0633\u061c+\u0660\u0666"_s << 3945e3 << 'g' << 1;
+ QTest::newRow("fa_IR 0.000003945 g 1") // Farsi, Iran (same for Afghanistan)
+ << u"fa_IR"_s << u"\u06f4\u00d7\u06f1\u06f0^\u200e\u2212\u06f0\u06f6"_s
+ << 0.000003945 << 'g' << 1;
+
+ QTest::newRow("C 0.000003945 f 9") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << 9;
+ QTest::newRow("C 0.000003945 f -") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << shortest;
+ QTest::newRow("C 0.000003945 e 3") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << 3;
+ QTest::newRow("C 0.000003945 e -") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << shortest;
+ QTest::newRow("C 0.000003945 g 4") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 4;
+ QTest::newRow("C 0.000003945 g -") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << shortest;
+
+ QTest::newRow("de_DE 0,000003945 f 9") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << 9;
+ QTest::newRow("de_DE 0,000003945 f -") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << shortest;
+ QTest::newRow("de_DE 0,000003945 e 3") << QString("de_DE") << QString("3,945E-06") << 0.000003945 << 'e' << 3;
+ QTest::newRow("de_DE 0,000003945 e -") << QString("de_DE") << QString("3,945E-06") << 0.000003945 << 'e' << shortest;
+ QTest::newRow("de_DE 0,000003945 g 4") << QString("de_DE") << QString("3,945E-06") << 0.000003945 << 'g' << 4;
+ QTest::newRow("de_DE 0,000003945 g -") << QString("de_DE") << QString("3,945E-06") << 0.000003945 << 'g' << shortest;
+
+ QTest::newRow("C 12456789012 f 3") << QString("C") << QString("12456789012.000") << 12456789012.0 << 'f' << 3;
+ QTest::newRow("C 12456789012 e 13") << QString("C") << QString("1.2456789012000e+10") << 12456789012.0 << 'e' << 13;
+ QTest::newRow("C 12456789012 e 7") << QString("C") << QString("1.2456789e+10") << 12456789012.0 << 'e' << 7;
+ QTest::newRow("C 12456789012 g 14") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << 14;
+ QTest::newRow("C 12456789012 g 8") << QString("C") << QString("1.2456789e+10") << 12456789012.0 << 'g' << 8;
+ // Check 'f/F' iff (adjusted) precision > exponent >= -4:
+ QTest::newRow("C 12345 g 4") << QString("C") << QString("1.235e+04") << 12345. << 'g' << 4;
+ QTest::newRow("C 1e7 g 8") << QString("C") << QString("10000000") << 1e7 << 'g' << 8;
+ QTest::newRow("C 1e8 g 8") << QString("C") << QString("1e+08") << 1e8 << 'g' << 8;
+ QTest::newRow("C 10.0 g 1") << QString("C") << QString("1e+01") << 10.0 << 'g' << 1;
+ QTest::newRow("C 10.0 g 0") << QString("C") << QString("1e+01") << 10.0 << 'g' << 0;
+ QTest::newRow("C 1.0 g 0") << QString("C") << QString("1") << 1.0 << 'g' << 0;
+ QTest::newRow("C 0.0001 g 0") << QString("C") << QString("0.0001") << 0.0001 << 'g' << 0;
+ QTest::newRow("C 0.00001 g 0") << QString("C") << QString("1e-05") << 0.00001 << 'g' << 0;
+ // Check transition to exponent form:
+ QTest::newRow("C 1245678900000 g -") << QString("C") << QString("1245678900000") << 1245678900000.0 << 'g' << shortest;
+ QTest::newRow("C 12456789100000 g -") << QString("C") << QString("12456789100000") << 12456789100000.0 << 'g' << shortest;
+ QTest::newRow("C 12456789000000 g -") << QString("C") << QString("1.2456789e+13") << 12456789000000.0 << 'g' << shortest;
+ QTest::newRow("C 1200000 g -") << QString("C") << QString("1200000") << 12e5 << 'g' << shortest;
+ QTest::newRow("C 12000000 g -") << QString("C") << QString("1.2e+07") << 12e6 << 'g' << shortest;
+ QTest::newRow("C 10000 g -") << QString("C") << QString("10000") << 1e4 << 'g' << shortest;
+ QTest::newRow("C 100000 g -") << QString("C") << QString("1e+05") << 1e5 << 'g' << shortest;
+
+ QTest::newRow("C 12456789012 f 0") << QString("C") << QString("12456789012") << 12456789012.0 << 'f' << 0;
+ QTest::newRow("C 12456789012 f -") << QString("C") << QString("12456789012") << 12456789012.0 << 'f' << shortest;
+ QTest::newRow("C 12456789012 e 10") << QString("C") << QString("1.2456789012e+10") << 12456789012.0 << 'e' << 10;
+ QTest::newRow("C 12456789012 e -") << QString("C") << QString("1.2456789012e+10") << 12456789012.0 << 'e' << shortest;
+ QTest::newRow("C 12456789012 g 11") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << 11;
+ QTest::newRow("C 12456789012 g -") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << shortest;
+
+ QTest::newRow("de_DE 12456789012 f 0") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'f' << 0;
+ QTest::newRow("de_DE 12456789012 f -") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'f' << shortest;
+ QTest::newRow("de_DE 12456789012 e 10") << QString("de_DE") << QString("1,2456789012E+10") << 12456789012.0 << 'e' << 10;
+ QTest::newRow("de_DE 12456789012 e -") << QString("de_DE") << QString("1,2456789012E+10") << 12456789012.0 << 'e' << shortest;
+ QTest::newRow("de_DE 12456789012 g 11") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'g' << 11;
+ QTest::newRow("de_DE 12456789012 g -") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'g' << shortest;
+}
+
+void tst_QLocale::doubleToString()
+{
+ QFETCH(QString, localeName);
+ QFETCH(QString, numStr);
+ QFETCH(double, num);
+ QFETCH(char, mode);
+ QFETCH(int, precision);
+
+#ifdef QT_NO_DOUBLECONVERSION
+ if (precision == QLocale::FloatingPointShortest)
+ QSKIP("'Shortest' double conversion is not that short without libdouble-conversion");
+#endif
+
+ const QLocale locale(localeName);
+ QCOMPARE(locale.toString(num, mode, precision), numStr);
+
+ // System locale is irrelevant here:
+ TransientLocale ignoreme(LC_ALL, "de_DE.UTF-8");
+ QCOMPARE(locale.toString(num, mode, precision), numStr);
+}
+
+void tst_QLocale::strtod_data()
+{
+ QTest::addColumn<QString>("num_str");
+ QTest::addColumn<double>("num");
+ QTest::addColumn<int>("processed");
+ QTest::addColumn<bool>("ok");
+
+ // plain numbers, success
+ QTest::newRow("0") << QString("0") << 0.0 << 1 << true;
+ QTest::newRow("0.") << QString("0.") << 0.0 << 2 << true;
+ QTest::newRow("0.0") << QString("0.0") << 0.0 << 3 << true;
+ QTest::newRow("0e+0") << QString("0e+0") << 0.0 << 4 << true;
+ QTest::newRow("0e-0") << QString("0e-0") << 0.0 << 4 << true;
+ QTest::newRow("0e+1") << QString("0e+1") << 0.0 << 4 << true;
+ QTest::newRow("0e-1") << QString("0e-1") << 0.0 << 4 << true;
+ QTest::newRow("0E+0") << QString("0E+0") << 0.0 << 4 << true;
+ QTest::newRow("0E-0") << QString("0E-0") << 0.0 << 4 << true;
+ QTest::newRow("0E+1") << QString("0E+1") << 0.0 << 4 << true;
+ QTest::newRow("0E-1") << QString("0E-1") << 0.0 << 4 << true;
+ QTest::newRow("3.4") << QString("3.4") << 3.4 << 3 << true;
+ QTest::newRow("0.035003945") << QString("0.035003945") << 0.035003945 << 11 << true;
+ QTest::newRow("3.5003945e-2") << QString("3.5003945e-2") << 0.035003945 << 12 << true;
+ QTest::newRow("0.000003945") << QString("0.000003945") << 0.000003945 << 11 << true;
+ QTest::newRow("3.945e-6") << QString("3.945e-6") << 0.000003945 << 8 << true;
+ QTest::newRow("12456789012") << QString("12456789012") << 12456789012.0 << 11 << true;
+ QTest::newRow("1.2456789012e10") << QString("1.2456789012e10") << 12456789012.0 << 15 << true;
+
+ // Overflow - fails but reports right length:
+ QTest::newRow("1e2000") << QString("1e2000") << qInf() << 6 << false;
+ QTest::newRow("-1e2000") << QString("-1e2000") << -qInf() << 7 << false;
+
+ // Underflow - fails but reports right length:
+ QTest::newRow("1e-2000") << QString("1e-2000") << 0.0 << 7 << false;
+ QTest::newRow("-1e-2000") << QString("-1e-2000") << 0.0 << 8 << false;
+
+ // starts with junk, fails
+ QTest::newRow("a0") << QString("a0") << 0.0 << 0 << false;
+ QTest::newRow("a0.") << QString("a0.") << 0.0 << 0 << false;
+ QTest::newRow("a0.0") << QString("a0.0") << 0.0 << 0 << false;
+ QTest::newRow("a3.4") << QString("a3.4") << 0.0 << 0 << false;
+ QTest::newRow("b0.035003945") << QString("b0.035003945") << 0.0 << 0 << false;
+ QTest::newRow("c3.5003945e-2") << QString("c3.5003945e-2") << 0.0 << 0 << false;
+ QTest::newRow("d0.000003945") << QString("d0.000003945") << 0.0 << 0 << false;
+ QTest::newRow("e3.945e-6") << QString("e3.945e-6") << 0.0 << 0 << false;
+ QTest::newRow("f12456789012") << QString("f12456789012") << 0.0 << 0 << false;
+ QTest::newRow("g1.2456789012e10") << QString("g1.2456789012e10") << 0.0 << 0 << false;
+
+ // ends with junk, success
+ QTest::newRow("0a") << QString("0a") << 0.0 << 1 << true;
+ QTest::newRow("0.a") << QString("0.a") << 0.0 << 2 << true;
+ QTest::newRow("0.0a") << QString("0.0a") << 0.0 << 3 << true;
+ QTest::newRow("0e+0a") << QString("0e+0a") << 0.0 << 4 << true;
+ QTest::newRow("0e-0a") << QString("0e-0a") << 0.0 << 4 << true;
+ QTest::newRow("0e+1a") << QString("0e+1a") << 0.0 << 4 << true;
+ QTest::newRow("0e-1a") << QString("0e-1a") << 0.0 << 4 << true;
+ QTest::newRow("0E+0a") << QString("0E+0a") << 0.0 << 4 << true;
+ QTest::newRow("0E-0a") << QString("0E-0a") << 0.0 << 4 << true;
+ QTest::newRow("0E+1a") << QString("0E+1a") << 0.0 << 4 << true;
+ QTest::newRow("0E-1a") << QString("0E-1a") << 0.0 << 4 << true;
+ QTest::newRow("0.035003945b") << QString("0.035003945b") << 0.035003945 << 11 << true;
+ QTest::newRow("3.5003945e-2c") << QString("3.5003945e-2c") << 0.035003945 << 12 << true;
+ QTest::newRow("0.000003945d") << QString("0.000003945d") << 0.000003945 << 11 << true;
+ QTest::newRow("3.945e-6e") << QString("3.945e-6e") << 0.000003945 << 8 << true;
+ QTest::newRow("12456789012f") << QString("12456789012f") << 12456789012.0 << 11 << true;
+ QTest::newRow("1.2456789012e10g") << QString("1.2456789012e10g") << 12456789012.0 << 15 << true;
+
+ // Overflow, ends with cruft - fails but reports right length:
+ QTest::newRow("1e2000 cruft") << QString("1e2000 cruft") << qInf() << 6 << false;
+ QTest::newRow("-1e2000 cruft") << QString("-1e2000 cruft") << -qInf() << 7 << false;
+
+ // NaN and nan
+ QTest::newRow("NaN") << QString("NaN") << qQNaN() << 3 << true;
+ QTest::newRow("nan") << QString("nan") << qQNaN() << 3 << true;
+
+ // Underflow, ends with cruft - fails but reports right length:
+ QTest::newRow("1e-2000 cruft") << QString("1e-2000 cruft") << 0.0 << 7 << false;
+ QTest::newRow("-1e-2000 cruft") << QString("-1e-2000 cruft") << 0.0 << 8 << false;
+
+ // "0x" prefix, success but only for the "0" before "x"
+ QTest::newRow("0x0") << QString("0x0") << 0.0 << 1 << true;
+ QTest::newRow("0x0.") << QString("0x0.") << 0.0 << 1 << true;
+ QTest::newRow("0x0.0") << QString("0x0.0") << 0.0 << 1 << true;
+ QTest::newRow("0x3.4") << QString("0x3.4") << 0.0 << 1 << true;
+ QTest::newRow("0x0.035003945") << QString("0x0.035003945") << 0.0 << 1 << true;
+ QTest::newRow("0x3.5003945e-2") << QString("0x3.5003945e-2") << 0.0 << 1 << true;
+ QTest::newRow("0x0.000003945") << QString("0x0.000003945") << 0.0 << 1 << true;
+ QTest::newRow("0x3.945e-6") << QString("0x3.945e-6") << 0.0 << 1 << true;
+ QTest::newRow("0x12456789012") << QString("0x12456789012") << 0.0 << 1 << true;
+ QTest::newRow("0x1.2456789012e10") << QString("0x1.2456789012e10") << 0.0 << 1 << true;
+
+ // hexfloat is not supported (yet)
+ QTest::newRow("0x1.921fb5p+1") << QString("0x1.921fb5p+1") << 0.0 << 1 << true;
+}
+
+void tst_QLocale::strtod()
+{
+ QFETCH(QString, num_str);
+ QFETCH(double, num);
+ QFETCH(int, processed);
+ QFETCH(bool, ok);
+
+ QByteArray numData = num_str.toUtf8();
+ const char *end = nullptr;
+ bool actualOk = false;
+ double result = qstrtod(numData.constData(), &end, &actualOk);
+
+ QCOMPARE(result, num);
+ QCOMPARE(actualOk, ok);
+ QCOMPARE(static_cast<int>(end - numData.constData()), processed);
+
+ // Make sure QByteArray, QString and QLocale also work.
+ // (They don't support incomplete parsing, and give 0 for overflow.)
+ if (ok && (processed == num_str.size() || processed == 0)) {
+ actualOk = false;
+ QCOMPARE(num_str.toDouble(&actualOk), num);
+ QCOMPARE(actualOk, ok);
+
+ actualOk = false;
+ QCOMPARE(numData.toDouble(&actualOk), num);
+ QCOMPARE(actualOk, ok);
+
+ actualOk = false;
+ QCOMPARE(QLocale::c().toDouble(num_str, &actualOk), num);
+ QCOMPARE(actualOk, ok);
+ }
+
+ // and QStringView, but we can limit the length without allocating memory
+ QStringView num_strref = QStringView{ num_str }.mid(0, processed);
+ actualOk = false;
+ QCOMPARE(QLocale::c().toDouble(num_strref, &actualOk), num);
+ QCOMPARE(actualOk, ok);
+}
+
+void tst_QLocale::long_long_conversion_data()
+{
+ QTest::addColumn<QString>("locale_name");
+ QTest::addColumn<QString>("num_str");
+ QTest::addColumn<bool>("good");
+ QTest::addColumn<qlonglong>("num");
+
+ QTest::newRow("C null") << QString("C") << QString() << false << (qlonglong) 0;
+ QTest::newRow("C empty") << QString("C") << QString("") << false << (qlonglong) 0;
+ QTest::newRow("C 1") << QString("C") << "1" << true << (qlonglong) 1;
+ QTest::newRow("C 1,") << QString("C") << "1," << false << (qlonglong) 0;
+ QTest::newRow("C 1,2") << QString("C") << "1,2" << false << (qlonglong) 0;
+ QTest::newRow("C 1,23") << QString("C") << "1,23" << false << (qlonglong) 0;
+ QTest::newRow("C 1,234") << QString("C") << "1,234" << true << (qlonglong) 1234;
+ QTest::newRow("C 1234567") << QString("C") << "1234567" << true << (qlonglong) 1234567;
+ QTest::newRow("C 1,234567") << QString("C") << "1,234567" << false << (qlonglong) 0;
+ QTest::newRow("C 12,34567") << QString("C") << "12,34567" << false << (qlonglong) 0;
+ QTest::newRow("C 123,4567") << QString("C") << "123,4567" << false << (qlonglong) 0;
+ QTest::newRow("C 1234,567") << QString("C") << "1234,567" << false << (qlonglong) 0;
+ QTest::newRow("C 12345,67") << QString("C") << "12345,67" << false << (qlonglong) 0;
+ QTest::newRow("C 123456,7") << QString("C") << "123456,7" << false << (qlonglong) 0;
+ QTest::newRow("C 1,234,567") << QString("C") << "1,234,567" << true << (qlonglong) 1234567;
+ using LL = std::numeric_limits<qlonglong>;
+ QTest::newRow("C LLONG_MIN") << QString("C") << QString::number(LL::min()) << true << LL::min();
+ QTest::newRow("C LLONG_MAX") << QString("C") << QString::number(LL::max()) << true << LL::max();
+
+ QTest::newRow("de_DE 1") << QString("de_DE") << "1" << true << (qlonglong) 1;
+ QTest::newRow("de_DE 1.") << QString("de_DE") << "1." << false << (qlonglong) 0;
+ QTest::newRow("de_DE 1.2") << QString("de_DE") << "1.2" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 1.23") << QString("de_DE") << "1.23" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 1.234") << QString("de_DE") << "1.234" << true << (qlonglong) 1234;
+ QTest::newRow("de_DE 1234567") << QString("de_DE") << "1234567" << true << (qlonglong) 1234567;
+ QTest::newRow("de_DE 1.234567") << QString("de_DE") << "1.234567" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 12.34567") << QString("de_DE") << "12.34567" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 123.4567") << QString("de_DE") << "123.4567" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 1234.567") << QString("de_DE") << "1234.567" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 12345.67") << QString("de_DE") << "12345.67" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 123456.7") << QString("de_DE") << "123456.7" << false << (qlonglong) 0;
+ QTest::newRow("de_DE 1.234.567") << QString("de_DE") << "1.234.567" << true << (qlonglong) 1234567;
+ QTest::newRow("de_DE 1.234.567 ldspcs") << QString("de_DE") << " 1.234.567" << true << (qlonglong) 1234567;
+ QTest::newRow("de_DE 1.234.567 trspcs") << QString("de_DE") << "1.234.567 " << true << (qlonglong) 1234567;
+ QTest::newRow("de_DE 1.234.567 ldtrspcs") << QString("de_DE") << " 1.234.567 " << true << (qlonglong) 1234567;
+
+ // test that space is also accepted whenever QLocale::groupSeparator() == 0xa0 (which looks like space).
+ QTest::newRow("nb_NO 123 groupsep") << QString("nb_NO") << QString("1")+QChar(0xa0)+QString("234") << true << (qlonglong) 1234;
+ QTest::newRow("nb_NO 123 groupsep_space") << QString("nb_NO") << QString("1")+QChar(0x20)+QString("234") << true << (qlonglong) 1234;
+
+ QTest::newRow("nb_NO 123 ldspcs") << QString("nb_NO") << " 123" << true << (qlonglong) 123;
+ QTest::newRow("nb_NO 123 trspcs") << QString("nb_NO") << "123 " << true << (qlonglong) 123;
+ QTest::newRow("nb_NO 123 ldtrspcs") << QString("nb_NO") << " 123 " << true << (qlonglong) 123;
+
+ QTest::newRow("C 1234") << QString("C") << " 1234" << true << (qlonglong) 1234;
+ QTest::newRow("C 1234 ") << QString("C") << "1234 " << true << (qlonglong) 1234;
+ QTest::newRow("C 1234 ") << QString("C") << " 1234 " << true << (qlonglong) 1234;
+}
+
+void tst_QLocale::long_long_conversion()
+{
+ QFETCH(QString, locale_name);
+ QFETCH(QString, num_str);
+ QFETCH(bool, good);
+ QFETCH(qlonglong, num);
+ QStringView num_strRef{ num_str };
+
+ QLocale locale(locale_name);
+ QCOMPARE(locale.name(), locale_name);
+
+ bool ok;
+ qlonglong l = locale.toLongLong(num_str, &ok);
+ QCOMPARE(ok, good);
+
+ if (ok)
+ QCOMPARE(l, num);
+
+ l = locale.toLongLong(num_strRef, &ok);
+ QCOMPARE(ok, good);
+
+ if (ok)
+ QCOMPARE(l, num);
+}
+
+void tst_QLocale::long_long_conversion_extra()
+{
+ QLocale l(QLocale::C);
+ l.setNumberOptions({ });
+ QCOMPARE(l.toString((qlonglong)1), QString("1"));
+ QCOMPARE(l.toString((qlonglong)12), QString("12"));
+ QCOMPARE(l.toString((qlonglong)123), QString("123"));
+ QCOMPARE(l.toString((qlonglong)1234), QString("1,234"));
+ QCOMPARE(l.toString((qlonglong)12345), QString("12,345"));
+ QCOMPARE(l.toString((qlonglong)-1), QString("-1"));
+ QCOMPARE(l.toString((qlonglong)-12), QString("-12"));
+ QCOMPARE(l.toString((qlonglong)-123), QString("-123"));
+ QCOMPARE(l.toString((qlonglong)-1234), QString("-1,234"));
+ QCOMPARE(l.toString((qlonglong)-12345), QString("-12,345"));
+ QCOMPARE(l.toString((qulonglong)1), QString("1"));
+ QCOMPARE(l.toString((qulonglong)12), QString("12"));
+ QCOMPARE(l.toString((qulonglong)123), QString("123"));
+ QCOMPARE(l.toString((qulonglong)1234), QString("1,234"));
+ QCOMPARE(l.toString((qulonglong)12345), QString("12,345"));
+}
+
+void tst_QLocale::infNaN()
+{
+ // TODO: QTBUG-95460 -- could support localized forms of inf/NaN
+ const QLocale c(QLocale::C);
+
+ QT_TEST_EQUALITY_OPS(QLocale(), QLocale(QLocale::C), false);
+ QT_TEST_EQUALITY_OPS(QLocale(), QLocale(), true);
+ QT_TEST_EQUALITY_OPS(QLocale(QLocale::C), c, true);
+
+ QCOMPARE(c.toString(qQNaN()), u"nan");
+ QCOMPARE(c.toString(qQNaN(), 'e'), u"nan");
+ QCOMPARE(c.toString(qQNaN(), 'f'), u"nan");
+ QCOMPARE(c.toString(qQNaN(), 'g'), u"nan");
+ QCOMPARE(c.toString(qQNaN(), 'E'), u"NAN");
+ QCOMPARE(c.toString(qQNaN(), 'F'), u"NAN");
+ QCOMPARE(c.toString(qQNaN(), 'G'), u"NAN");
+
+ QCOMPARE(c.toString(qInf()), u"inf");
+ QCOMPARE(c.toString(qInf(), 'e'), u"inf");
+ QCOMPARE(c.toString(qInf(), 'f'), u"inf");
+ QCOMPARE(c.toString(qInf(), 'g'), u"inf");
+ QCOMPARE(c.toString(qInf(), 'E'), u"INF");
+ QCOMPARE(c.toString(qInf(), 'F'), u"INF");
+ QCOMPARE(c.toString(qInf(), 'G'), u"INF");
+
+ // Precision is ignored for inf and NaN:
+ QCOMPARE(c.toString(qQNaN(), 'g', 42), u"nan");
+ QCOMPARE(c.toString(qQNaN(), 'G', 42), u"NAN");
+ QCOMPARE(c.toString(qInf(), 'g', 42), u"inf");
+ QCOMPARE(c.toString(qInf(), 'G', 42), u"INF");
+
+ // Case is ignored when parsing inf and NaN:
+ bool ok = false;
+ QCOMPARE(c.toDouble("inf", &ok), qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("INF", &ok), qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("Inf", &ok), qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("+inf", &ok), qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("+INF", &ok), qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("+inF", &ok), qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("-inf", &ok), -qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("-INF", &ok), -qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("-iNf", &ok), -qInf());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("nan", &ok), qQNaN());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("NaN", &ok), qQNaN());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("NAN", &ok), qQNaN());
+ QVERIFY(ok);
+ QCOMPARE(c.toDouble("nAn", &ok), qQNaN());
+ QVERIFY(ok);
+ // Sign is invalid for NaN:
+ QCOMPARE(c.toDouble("-nan", &ok), 0.0);
+ QVERIFY(!ok);
+ QCOMPARE(c.toDouble("+nan", &ok), 0.0);
+ QVERIFY(!ok);
+
+
+ // Case is ignored when parsing inf and NaN:
+ QCOMPARE(c.toFloat("inf", &ok), float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("INF", &ok), float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("Inf", &ok), float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("+inf", &ok), float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("+INF", &ok), float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("+inF", &ok), float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("-inf", &ok), -float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("-INF", &ok), -float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("-iNf", &ok), -float(qInf()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("nan", &ok), float(qQNaN()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("NaN", &ok), float(qQNaN()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("NAN", &ok), float(qQNaN()));
+ QVERIFY(ok);
+ QCOMPARE(c.toFloat("nAn", &ok), float(qQNaN()));
+ QVERIFY(ok);
+ // Sign is invalid for NaN:
+ QCOMPARE(c.toFloat("-nan", &ok), 0.0f);
+ QVERIFY(!ok);
+ QCOMPARE(c.toFloat("+nan", &ok), 0.0f);
+ QVERIFY(!ok);
+}
+
+void tst_QLocale::fpExceptions()
+{
+#if defined(FE_ALL_EXCEPT) && FE_ALL_EXCEPT != 0
+ // Check that double-to-string conversion doesn't throw floating point
+ // exceptions when they are enabled.
+ fenv_t envp;
+ fegetenv(&envp);
+ feclearexcept(FE_ALL_EXCEPT);
+
+ QString::number(1000.1245);
+ QString::number(1.1);
+ QString::number(0.0);
+
+ QVERIFY(true);
+
+ QCOMPARE(fetestexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID), 0);
+ fesetenv(&envp);
+#endif
+}
+
+void tst_QLocale::negativeZero_data()
+{
+ QTest::addColumn<QLocale::Language>("language");
+ QTest::addColumn<QLocale::Script>("script");
+ QTest::addColumn<QLocale::Territory>("territory");
+ QTest::addColumn<QStringView>("expect");
+
+ QTest::newRow("C")
+ << QLocale::C << QLocale::AnyScript << QLocale::AnyTerritory
+ << QStringView(u"0");
+ QTest::newRow("Arabic")
+ << QLocale::Arabic << QLocale::ArabicScript << QLocale::AnyTerritory
+ << QStringView(u"\u0660");
+ QTest::newRow("Chakma")
+ << QLocale::Chakma << QLocale::ChakmaScript << QLocale::AnyTerritory
+ << QStringView(u"\xD804\xDD36"); // A surrogate pair.
+}
+
+void tst_QLocale::negativeZero()
+{
+ QFETCH(QLocale::Language, language);
+ QFETCH(QLocale::Script, script);
+ QFETCH(QLocale::Territory, territory);
+ QFETCH(QStringView, expect);
+ QLocale locale(language, script, territory);
+ QCOMPARE(locale.toString(std::copysign(0.0, -1.0)), expect);
+}
+
+void tst_QLocale::dayOfWeek_data()
+{
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<QString>("shortName");
+ QTest::addColumn<QString>("longName");
+
+ QTest::newRow("Sun") << QDate(2006, 1, 1) << "Sun" << "Sunday";
+ QTest::newRow("Mon") << QDate(2006, 1, 2) << "Mon" << "Monday";
+ QTest::newRow("Tue") << QDate(2006, 1, 3) << "Tue" << "Tuesday";
+ QTest::newRow("Wed") << QDate(2006, 1, 4) << "Wed" << "Wednesday";
+ QTest::newRow("Thu") << QDate(2006, 1, 5) << "Thu" << "Thursday";
+ QTest::newRow("Fri") << QDate(2006, 1, 6) << "Fri" << "Friday";
+ QTest::newRow("Sat") << QDate(2006, 1, 7) << "Sat" << "Saturday";
+}
+
+void tst_QLocale::dayOfWeek()
+{
+ QFETCH(QDate, date);
+ QFETCH(QString, shortName);
+ QFETCH(QString, longName);
+
+ QCOMPARE(QLocale::c().toString(date, "ddd"), shortName);
+ QCOMPARE(QLocale::c().toString(date, "dddd"), longName);
+
+ QCOMPARE(QLocale::c().toString(date, u"ddd"), shortName);
+ QCOMPARE(QLocale::c().toString(date, u"dddd"), longName);
+}
+
+void tst_QLocale::formatDate_data()
+{
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("1") << QDate(1974, 12, 1) << "d/M/yyyy" << "1/12/1974";
+ QTest::newRow("2") << QDate(1974, 12, 1) << "d/M/yyyyy" << "1/12/1974y";
+ QTest::newRow("4") << QDate(1974, 1, 1) << "d/M/yyyy" << "1/1/1974";
+ QTest::newRow("5") << QDate(1974, 1, 1) << "dd/MM/yyy" << "01/01/74y";
+ QTest::newRow("6") << QDate(1974, 12, 1) << "ddd/MMM/yy" << "Sun/Dec/74";
+ QTest::newRow("7") << QDate(1974, 12, 1) << "dddd/MMMM/y" << "Sunday/December/y";
+ QTest::newRow("8") << QDate(1974, 12, 1) << "ddddd/MMMMM/yy" << "Sunday1/December12/74";
+ QTest::newRow("9") << QDate(1974, 12, 1) << "'dddd'/MMMM/yy" << "dddd/December/74";
+ QTest::newRow("10") << QDate(1974, 12, 1) << "d'dd'd/MMMM/yyy" << "1dd1/December/74y";
+ QTest::newRow("11") << QDate(1974, 12, 1) << "d'dd'd/MMM'M'/yy" << "1dd1/DecM/74";
+ QTest::newRow("12") << QDate(1974, 12, 1) << "d'd'dd/M/yy" << "1d01/12/74";
+
+ QTest::newRow("20") << QDate(1974, 12, 1) << "foo" << "foo";
+ QTest::newRow("21") << QDate(1974, 12, 1) << "'" << "";
+ QTest::newRow("22") << QDate(1974, 12, 1) << "''" << "'";
+ QTest::newRow("23") << QDate(1974, 12, 1) << "'''" << "'";
+ QTest::newRow("24") << QDate(1974, 12, 1) << "\"" << "\"";
+ QTest::newRow("25") << QDate(1974, 12, 1) << "\"\"" << "\"\"";
+ QTest::newRow("26") << QDate(1974, 12, 1) << "\"yy\"" << "\"74\"";
+ QTest::newRow("27") << QDate(1974, 12, 1) << "'\"yy\"'" << "\"yy\"";
+ QTest::newRow("28") << QDate() << "'\"yy\"'" << "";
+ QTest::newRow("29")
+ << QDate(1974, 12, 1) << "hh:mm:ss.zzz ap d'd'dd/M/yy" << "hh:mm:ss.zzz ap 1d01/12/74";
+
+ QTest::newRow("dd MMMM yyyy") << QDate(1, 1, 1) << "dd MMMM yyyy" << "01 January 0001";
+
+ // Test unicode handling.
+ QTest::newRow("unicode in format string") << QDate(1, 1, 1)
+ << u8"🔴😤🌼😫dd☀😥🤤👉💃MM💛🙂💓🤩yyyy😴"
+ << u8"🔴😤🌼😫01☀😥🤤👉💃01💛🙂💓🤩0001😴";
+}
+
+void tst_QLocale::formatDate()
+{
+ QFETCH(QDate, date);
+ QFETCH(QString, format);
+ QFETCH(QString, result);
+
+ QLocale l(QLocale::C);
+ QCOMPARE(l.toString(date, format), result);
+ QCOMPARE(l.toString(date, QStringView(format)), result);
+}
+
+void tst_QLocale::formatTime_data()
+{
+ QTest::addColumn<QTime>("time");
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("C-h:m:s-am") << QTime(1, 2, 3) << "C" << "h:m:s" << "1:2:3";
+ QTest::newRow("C-H:m:s-am") << QTime(1, 2, 3) << "C" << "H:m:s" << "1:2:3";
+ QTest::newRow("C-hh:mm:ss-am") << QTime(1, 2, 3) << "C" << "hh:mm:ss" << "01:02:03";
+ QTest::newRow("C-HH:mm:ss-am") << QTime(1, 2, 3) << "C" << "HH:mm:ss" << "01:02:03";
+ QTest::newRow("C-hhh:mmm:sss-am") << QTime(1, 2, 3) << "C" << "hhh:mmm:sss" << "011:022:033";
+
+ QTest::newRow("C-h:m:s-pm") << QTime(14, 2, 3) << "C" << "h:m:s" << "14:2:3";
+ QTest::newRow("C-H:m:s-pm") << QTime(14, 2, 3) << "C" << "H:m:s" << "14:2:3";
+ QTest::newRow("C-hh:mm:ss-pm") << QTime(14, 2, 3) << "C" << "hh:mm:ss" << "14:02:03";
+ QTest::newRow("C-HH:mm:ss-pm") << QTime(14, 2, 3) << "C" << "HH:mm:ss" << "14:02:03";
+ QTest::newRow("C-hhh:mmm:sss-pm") << QTime(14, 2, 3) << "C" << "hhh:mmm:sss" << "1414:022:033";
+
+ QTest::newRow("C-h:m:s+ap-pm") << QTime(14, 2, 3) << "C" << "h:m:s ap" << "2:2:3 pm";
+ QTest::newRow("C-H:m:s+AP-pm") << QTime(14, 2, 3) << "C" << "H:m:s AP" << "14:2:3 PM";
+ QTest::newRow("C-hh:mm:ss+aap-pm")
+ << QTime(14, 2, 3) << "C" << "hh:mm:ss aap" << "02:02:03 pmpm";
+ QTest::newRow("C-HH:mm:ss+AP+aa-pm")
+ << QTime(14, 2, 3) << "C" << "HH:mm:ss AP aa" << "14:02:03 PM pmpm";
+
+ QTest::newRow("C-h:m:s+ap-am") << QTime(1, 2, 3) << "C" << "h:m:s ap" << "1:2:3 am";
+ QTest::newRow("C-H:m:s+AP-am") << QTime(1, 2, 3) << "C" << "H:m:s AP" << "1:2:3 AM";
+
+ QTest::newRow("C-foo") << QTime(1, 2, 3) << "C" << "foo" << "foo";
+ QTest::newRow("C-quote") << QTime(1, 2, 3) << "C" << "'" << "";
+ QTest::newRow("C-quote*2") << QTime(1, 2, 3) << "C" << "''" << "'";
+ QTest::newRow("C-quote*3") << QTime(1, 2, 3) << "C" << "'''" << "'";
+ QTest::newRow("C-dquote") << QTime(1, 2, 3) << "C" << "\"" << "\"";
+ QTest::newRow("C-dquote*2") << QTime(1, 2, 3) << "C" << "\"\"" << "\"\"";
+ QTest::newRow("C-dquote-H") << QTime(1, 2, 3) << "C" << "\"H\"" << "\"1\"";
+ QTest::newRow("C-quote-dquote-H") << QTime(1, 2, 3) << "C" << "'\"H\"'" << "\"H\"";
+
+ QTest::newRow("C-H:m:s.z") << QTime(1, 2, 3, 456) << "C" << "H:m:s.z" << "1:2:3.456";
+ QTest::newRow("C-H:m:s.zz") << QTime(1, 2, 3, 456) << "C" << "H:m:s.zz" << "1:2:3.456";
+ QTest::newRow("C-H:m:s.zzz") << QTime(1, 2, 3, 456) << "C" << "H:m:s.zzz" << "1:2:3.456";
+ QTest::newRow("C-H:m:s.z=400") << QTime(1, 2, 3, 400) << "C" << "H:m:s.z" << "1:2:3.4";
+ QTest::newRow("C-H:m:s.zzz=400") << QTime(1, 2, 3, 400) << "C" << "H:m:s.zzz" << "1:2:3.400";
+ QTest::newRow("C-H:m:s.z=004") << QTime(1, 2, 3, 4) << "C" << "H:m:s.z" << "1:2:3.004";
+ QTest::newRow("C-H:m:s.zzz=004") << QTime(1, 2, 3, 4) << "C" << "H:m:s.zzz" << "1:2:3.004";
+
+ QTest::newRow("C-invalid") << QTime() << "C" << "H:m:s.zzz" << "";
+ QTest::newRow("C-date-time")
+ << QTime(1, 2, 3, 4) << "C" << "dd MM yyyy H:m:s.zzz" << "dd MM yyyy 1:2:3.004";
+
+ // Test unicode handling.
+ QTest::newRow("C-emoji")
+ << QTime(17, 22, 05, 18) << "C" << u8"m📌ss📢H.zzz" << u8"22📌05📢17.018";
+
+ // Test-cases related to QTBUG-95790 (case of localized am/pm indicators):
+ QTest::newRow("en_US-h:m:s+ap-pm")
+ << QTime(14, 2, 3) << "en_US" << "h:m:s ap" << "2:2:3 pm";
+ QTest::newRow("en_US-H:m:s+AP-pm")
+ << QTime(14, 2, 3) << "en_US" << "H:m:s AP" << "14:2:3 PM";
+ QTest::newRow("en_US-H:m:s+Ap-pm")
+ << QTime(14, 2, 3) << "en_US" << "H:m:s Ap" << "14:2:3 PM";
+ QTest::newRow("en_US-h:m:s+ap-am")
+ << QTime(1, 2, 3) << "en_US" << "h:m:s ap" << "1:2:3 am";
+ QTest::newRow("en_US-H:m:s+AP-am")
+ << QTime(1, 2, 3) << "en_US" << "H:m:s AP" << "1:2:3 AM";
+ QTest::newRow("en_US-H:m:s+aP-am")
+ << QTime(1, 2, 3) << "en_US" << "H:m:s aP" << "1:2:3 AM";
+
+ QTest::newRow("cs_CZ-h:m:s+ap-pm")
+ << QTime(14, 2, 3) << "cs_CZ" << "h:m:s ap" << "2:2:3 odp.";
+ QTest::newRow("cs_CZ-h:m:s+AP-pm")
+ << QTime(14, 2, 3) << "cs_CZ" << "h:m:s AP" << "2:2:3 ODP.";
+ QTest::newRow("cs_CZ-h:m:s+Ap-pm")
+ << QTime(14, 2, 3) << "cs_CZ" << "h:m:s Ap" << "2:2:3 odp.";
+ QTest::newRow("cs_CZ-h:m:s+ap-am")
+ << QTime(1, 2, 3) << "cs_CZ" << "h:m:s ap" << "1:2:3 dop.";
+ QTest::newRow("cs_CZ-h:m:s+AP-am")
+ << QTime(1, 2, 3) << "cs_CZ" << "h:m:s AP" << "1:2:3 DOP.";
+ QTest::newRow("cs_CZ-h:m:s+aP-am")
+ << QTime(1, 2, 3) << "cs_CZ" << "h:m:s aP" << "1:2:3 dop.";
+}
+
+void tst_QLocale::formatTime()
+{
+ QFETCH(const QTime, time);
+ QFETCH(const QString, locale);
+ QFETCH(const QString, format);
+ QFETCH(const QString, result);
+
+ QLocale l(locale);
+ QCOMPARE(l.toString(time, format), result);
+ QCOMPARE(l.toString(time, QStringView(format)), result);
+}
+
+
+void tst_QLocale::formatDateTime_data()
+{
+ QTest::addColumn<QString>("localeName");
+ QTest::addColumn<QDateTime>("dateTime");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("1C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13))
+ << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14";
+ QTest::newRow("2C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "d/M/yyyyy h" << "1/12/1974y 15";
+ QTest::newRow("4C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
+ << "d/M/yyyy zzz" << "1/1/1974 000";
+ QTest::newRow("5C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
+ << "dd/MM/yyy z" << "01/01/74y 0";
+ QTest::newRow("6C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
+ << "ddd/MMM/yy AP" << "Mon/Dec/74 PM";
+ QTest::newRow("7C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
+ << "dddd/MMMM/y apa" << "Monday/December/y pmpm";
+ QTest::newRow("8C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
+ << "ddddd/MMMMM/yy ss" << "Monday2/December12/74 13";
+ QTest::newRow("9C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'dddd'/MMMM/yy s" << "dddd/December/74 13";
+ QTest::newRow("10C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 4, 13))
+ << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/December/74y 4m04";
+ QTest::newRow("11C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 3))
+ << "d'dd'd/MMM'M'/yysss" << "1dd1/DecM/74033";
+ QTest::newRow("12C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "d'd'dd/M/yyh" << "1d01/12/7415";
+
+ QTest::newRow("dd MMMM yyyy, hh:mm:ss") << "C" << QDateTime(QDate(1, 1, 1), QTime(12, 00, 00))
+ << "dd MMMM yyyy, hh:mm:ss" << "01 January 0001, 12:00:00";
+
+ QTest::newRow("20C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "foo" << "foo";
+ QTest::newRow("21C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'" << "";
+ QTest::newRow("22C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "''" << "'";
+ QTest::newRow("23C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'''" << "'";
+ QTest::newRow("24C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "\"" << "\"";
+ QTest::newRow("25C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "\"\"" << "\"\"";
+ QTest::newRow("26C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "\"yymm\"" << "\"7414\"";
+ QTest::newRow("27C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'\"yymm\"'" << "\"yymm\"";
+ QTest::newRow("28C") << "C" << QDateTime()
+ << "'\"yymm\"'" << "";
+
+ QTest::newRow("1no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13))
+ << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14";
+ QTest::newRow("2no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "d/M/yyyyy h" << "1/12/1974y 15";
+ QTest::newRow("4no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
+ << "d/M/yyyy zzz" << "1/1/1974 000";
+ QTest::newRow("5no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
+ << "dd/MM/yyy z" << "01/01/74y 0";
+ QTest::newRow("6no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
+ << "ddd/MMM/yy AP" << "man./des./74 P.M.";
+ QTest::newRow("7no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
+ << "dddd/MMMM/y apa" << "mandag/desember/y p.m.p.m.";
+ QTest::newRow("8no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
+ << "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13";
+ QTest::newRow("9no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'dddd'/MMMM/yy s" << "dddd/desember/74 13";
+ QTest::newRow("10no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 4, 13))
+ << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/desember/74y 4m04";
+ QTest::newRow("11no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 3))
+ << "d'dd'd/MMM'M'/yysss" << "1dd1/des.M/74033";
+ QTest::newRow("12no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "d'd'dd/M/yyh" << "1d01/12/7415";
+
+ QTest::newRow("20no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "foo" << "foo";
+ QTest::newRow("21no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'" << "";
+ QTest::newRow("22no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "''" << "'";
+ QTest::newRow("23no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'''" << "'";
+ QTest::newRow("24no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "\"" << "\"";
+ QTest::newRow("25no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "\"\"" << "\"\"";
+ QTest::newRow("26no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "\"yymm\"" << "\"7414\"";
+ QTest::newRow("27no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
+ << "'\"yymm\"'" << "\"yymm\"";
+ QTest::newRow("28no_NO") << "no_NO" << QDateTime()
+ << "'\"yymm\"'" << "";
+
+ QDateTime testLongHour(QDate(1999, 12, 31), QTime(23, 59, 59, 999));
+ QDateTime testShortHour(QDate(1999, 12, 31), QTime(3, 59, 59, 999));
+ QDateTime testZeroHour(QDate(1999, 12, 31), QTime(0, 59, 59, 999));
+
+ QTest::newRow("datetime0") << "en_US" << QDateTime()
+ << QString("dd-MM-yyyy hh:mm:ss") << QString();
+ QTest::newRow("datetime1") << "en_US" << testLongHour
+ << QString("dd-'mmddyy'MM-yyyy hh:mm:ss.zzz")
+ << QString("31-mmddyy12-1999 23:59:59.999");
+ QTest::newRow("datetime2") << "en_US" << testLongHour
+ << QString("dd-'apAP'MM-yyyy hh:mm:ss.zzz")
+ << QString("31-apAP12-1999 23:59:59.999");
+ QTest::newRow("datetime3") << "en_US" << testLongHour
+ << QString("Apdd-MM-yyyy hh:mm:ss.zzz")
+ << QString("PM31-12-1999 11:59:59.999");
+ QTest::newRow("datetime4") << "en_US" << testLongHour
+ << QString("'ap'apdd-MM-yyyy 'AP'hh:mm:ss.zzz")
+ << QString("appm31-12-1999 AP11:59:59.999");
+ QTest::newRow("datetime5") << "en_US" << testLongHour
+ << QString("'''") << QString("'");
+ QTest::newRow("datetime6") << "en_US" << testLongHour
+ << QString("'ap") << QString("ap");
+ QTest::newRow("datetime7") << "en_US" << testLongHour
+ << QString("' ' 'hh' hh") << QString(" hh 23");
+ QTest::newRow("datetime8") << "en_US" << testLongHour
+ << QString("d'foobar'") << QString("31foobar");
+ QTest::newRow("datetime9") << "en_US" << testShortHour
+ << QString("hhhhh") << QString("03033");
+ QTest::newRow("datetime11") << "en_US" << testLongHour
+ << QString("HHHhhhAaAPap") << QString("23231111PMpmPMpm");
+ QTest::newRow("datetime12") << "en_US" << testShortHour
+ << QString("HHHhhhAaAPap") << QString("033033AMamAMam");
+ QTest::newRow("datetime13") << "en_US" << QDateTime(QDate(1974, 12, 1), QTime(14, 14, 20))
+ << QString("hh''mm''ss dd''MM''yyyy")
+ << QString("14'14'20 01'12'1974");
+ QTest::newRow("AM no p") << "en_US" << testZeroHour
+ << QString("hhAX") << QString("12AMX");
+ QTest::newRow("AM no p, x 2") << "en_US" << testShortHour
+ << QString("hhhhhaA") << QString("03033amAM");
+ QTest::newRow("am 0 hour") << "en_US" << testZeroHour
+ << QString("hAP") << QString("12AM");
+ QTest::newRow("AM zero hour") << "en_US" << testZeroHour
+ << QString("hhAP") << QString("12AM");
+ QTest::newRow("dddd") << "en_US" << testZeroHour
+ << QString("dddd") << QString("Friday");
+ QTest::newRow("ddd") << "en_US" << testZeroHour
+ << QString("ddd") << QString("Fri");
+ QTest::newRow("MMMM") << "en_US" << testZeroHour
+ << QString("MMMM") << QString("December");
+ QTest::newRow("MMM") << "en_US" << testZeroHour
+ << QString("MMM") << QString("Dec");
+ QTest::newRow("empty") << "en_US" << testZeroHour
+ << QString("") << QString("");
+
+ // Test unicode handling.
+ QTest::newRow("emoji in format string")
+ << "en_US" << QDateTime(QDate(1980, 2, 1), QTime(17, 12))
+ << QString(u8"💖yyyy💖MM💖dd hh💖mm") << u8"💖1980💖02💖01 17💖12";
+}
+
+void tst_QLocale::formatDateTime()
+{
+ QFETCH(QString, localeName);
+ QFETCH(QDateTime, dateTime);
+ QFETCH(QString, format);
+ QFETCH(QString, result);
+
+ QLocale l(localeName);
+ QCOMPARE(l.toString(dateTime, format), result);
+ QCOMPARE(l.toString(dateTime, QStringView(format)), result);
+}
+
+void tst_QLocale::formatTimeZone()
+{
+ QLocale enUS("en_US");
+
+ QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QCOMPARE(enUS.toString(dt1, "t"), QLatin1String("UTC+01:00"));
+
+ QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(-60 * 60));
+ QCOMPARE(enUS.toString(dt2, "t"), QLatin1String("UTC-01:00"));
+
+ QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0), QTimeZone::UTC);
+ QCOMPARE(enUS.toString(dt3, "t"), QLatin1String("UTC"));
+
+ // LocalTime should vary
+ if (europeanTimeZone) {
+ // Time definitely in Standard Time
+ const QStringList knownCETus = {
+ u"GMT+1"_s, // ICU
+ u"Central Europe Standard Time"_s, // MS (lacks abbreviations)
+ u"Central European Standard Time"_s,
+ u"CET"_s // Standard abbreviation
+ };
+ const QString cet = enUS.toString(QDate(2013, 1, 1).startOfDay(), u"t");
+ QVERIFY2(knownCETus.contains(cet), qPrintable(cet));
+
+ // Time definitely in Daylight Time
+ const QStringList knownCESTus = {
+ u"GMT+2"_s, // ICU
+ u"Central Europe Summer Time"_s, // MS (lacks abbreviations)
+ u"Central European Summer Time"_s,
+ u"CEST"_s // Standard abbreviation
+ };
+ const QString cest = enUS.toString(QDate(2013, 6, 1).startOfDay(), u"t");
+ QVERIFY2(knownCESTus.contains(cest), qPrintable(cest));
+ } else {
+ qDebug("(Skipped some CET-only tests)");
+ }
+
+#if QT_CONFIG(timezone)
+ const QTimeZone berlin("Europe/Berlin");
+ const QDateTime jan(QDate(2010, 1, 1).startOfDay(berlin));
+ const QDateTime jul(QDate(2010, 7, 1).startOfDay(berlin));
+
+ QCOMPARE(enUS.toString(jan, "t"), berlin.displayName(jan, QTimeZone::ShortName, enUS));
+ QCOMPARE(enUS.toString(jul, "t"), berlin.displayName(jul, QTimeZone::ShortName, enUS));
+#endif
+
+ // Current datetime should use current zone's abbreviation:
+ const auto now = QDateTime::currentDateTime();
+ QString zone;
+#if QT_CONFIG(timezone) // Match logic in QDTP's startsWithLocalTimeZone() helper.
+ zone = now.timeRepresentation().displayName(now, QTimeZone::ShortName, enUS);
+ if (zone.isEmpty()) // Fall back to unlocalized from when no timezone backend:
+#endif
+ zone = now.timeZoneAbbreviation();
+ QCOMPARE(enUS.toString(now, "t"), zone);
+
+ // Time on its own will always use the current local time zone:
+ QCOMPARE(enUS.toString(now.time(), "t"), zone);
+}
+
+void tst_QLocale::toDateTime_data()
+{
+ QTest::addColumn<QString>("localeName");
+ QTest::addColumn<QDateTime>("result");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("string");
+ // No non-format letters in format string, no time-zone (t format):
+ QTest::addColumn<bool>("clean");
+
+ QTest::newRow("1C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 0))
+ << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14" << true;
+ QTest::newRow("2C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
+ << "d/M/yyyyy h" << "1/12/1974y 15" << false;
+ QTest::newRow("4C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 1))
+ << "d/M/yyyy zzz" << "1/1/1974 001" << true;
+ QTest::newRow("5C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 1))
+ << "dd/MM/yyy z" << "01/01/74y 001" << false;
+ QTest::newRow("6C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 100))
+ << "dd/MM/yyy z" << "01/01/74y 1" << false;
+ QTest::newRow("8C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(0, 0, 13))
+ << "ddddd/MMMMM/yy ss" << "Monday2/December12/74 13" << true;
+ QTest::newRow("9C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 13))
+ << "'dddd'/MMMM/yy s" << "dddd/December/74 13" << false;
+ QTest::newRow("10C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 4, 0))
+ << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/December/74y 4m04" << false;
+ QTest::newRow("11C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 3))
+ << "d'dd'd/MMM'M'/yysss" << "1dd1/DecM/74033" << false;
+ QTest::newRow("12C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
+ << "d'd'dd/M/yyh" << "1d01/12/7415" << false;
+ // Unpadded value for fixed-width field is wrong:
+ QTest::newRow("bad-day-C") << "C" << QDateTime() << "dd-MMM-yy" << "4-Jun-11" << true;
+ QTest::newRow("bad-month-C") << "C" << QDateTime() << "d-MM-yy" << "4-6-11" << true;
+ QTest::newRow("bad-year-C") << "C" << QDateTime() << "d-MMM-yyyy" << "4-Jun-11" << true;
+ QTest::newRow("bad-hour-C") << "C" << QDateTime() << "d-MMM-yy hh:m" << "4-Jun-11 1:2" << true;
+ QTest::newRow("bad-min-C") << "C" << QDateTime() << "d-MMM-yy h:mm" << "4-Jun-11 1:2" << true;
+ QTest::newRow("bad-sec-C")
+ << "C" << QDateTime() << "d-MMM-yy h:m:ss" << "4-Jun-11 1:2:3" << true;
+ QTest::newRow("bad-milli-C")
+ << "C" << QDateTime() << "d-MMM-yy h:m:s.zzz" << "4-Jun-11 1:2:3.4" << true;
+ QTest::newRow("ok-C") << "C" << QDateTime(QDate(1911, 6, 4), QTime(1, 2, 3, 400))
+ << "d-MMM-yy h:m:s.z" << "4-Jun-11 1:2:3.4" << true;
+
+ QTest::newRow("1no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 0))
+ << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14" << true;
+ QTest::newRow("2no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
+ << "d/M/yyyyy h" << "1/12/1974y 15" << false;
+ QTest::newRow("4no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0))
+ << "d/M/yyyy zzz" << "1/1/1974 000" << true;
+ QTest::newRow("5no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0))
+ << "dd/MM/yyy z" << "01/01/74y 0" << false;
+ QTest::newRow("8no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(0, 0, 13))
+ << "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13" << true;
+ QTest::newRow("9no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 13))
+ << "'dddd'/MMMM/yy s" << "dddd/desember/74 13" << false;
+ QTest::newRow("10no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 4, 0))
+ << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/desember/74y 4m04" << false;
+ QTest::newRow("11no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 3))
+ << "d'dd'd/MMM'M'/yysss" << "1dd1/des.M/74033" << false;
+ QTest::newRow("12no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
+ << "d'd'dd/M/yyh" << "1d01/12/7415" << false;
+
+ QTest::newRow("short-ss") // QTBUG-102199: trips over an assert in CET
+ << "C" << QDateTime() // Single-digit seconds does not match ss format.
+ << u"ddd, d MMM yyyy HH:mm:ss"_s << u"Sun, 29 Mar 2020 02:26:3"_s << true;
+
+ QTest::newRow("short-ss-Z") // Same, but with a valid date-time:
+ << "C" << QDateTime()
+ << u"ddd, d MMM yyyy HH:mm:ss t"_s << u"Sun, 29 Mar 2020 02:26:3 Z"_s << false;
+
+ QTest::newRow("s-Z") // Same, but with a format that accepts the single digit:
+ << "C" << QDateTime(QDate(2020, 3, 29), QTime(2, 26, 3), QTimeZone::UTC)
+ << u"ddd, d MMM yyyy HH:mm:s t"_s << u"Sun, 29 Mar 2020 02:26:3 Z"_s << false;
+
+ QTest::newRow("RFC-1123")
+ << "C" << QDateTime(QDate(2007, 11, 1), QTime(18, 8, 30))
+ << "ddd, dd MMM yyyy hh:mm:ss 'GMT'" << "Thu, 01 Nov 2007 18:08:30 GMT" << false;
+
+ QTest::newRow("longFormat")
+ << "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32))
+ << "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM " << true;
+
+ // Parsing am/pm indicators case-insensitively:
+ QTest::newRow("am-cs_CZ")
+ << "cs_CZ" << QDateTime(QDate(1945, 8, 6), QTime(8, 15, 44, 400))
+ << "yyyy-MM-dd hh:mm:ss.z aP" << "1945-08-06 08:15:44.4 dOp." << true;
+ QTest::newRow("pm-cs_CZ")
+ << "cs_CZ" << QDateTime(QDate(1945, 8, 15), QTime(12, 0))
+ << "yyyy-MM-dd hh:mm aP" << "1945-08-15 12:00 OdP." << true;
+
+ const QDateTime dt(QDate(2017, 02, 25), QTime(17, 21, 25));
+ // These formats correspond to the locale formats, with the timezone removed.
+ // We hardcode them in case an update to the locale DB changes them.
+
+ QTest::newRow("C:long") << "C" << dt << "dddd, d MMMM yyyy HH:mm:ss"
+ << "Saturday, 25 February 2017 17:21:25" << true;
+ QTest::newRow("C:short")
+ << "C" << dt << "d MMM yyyy HH:mm:ss" << "25 Feb 2017 17:21:25" << true;
+ QTest::newRow("C:narrow")
+ << "C" << dt << "d MMM yyyy HH:mm:ss" << "25 Feb 2017 17:21:25" << true;
+
+ // Test the same again with unicode and emoji.
+ QTest::newRow("C:long with emoji") << "C" << dt << u8"dddd, d💪MMMM yyyy HH:mm:ss"
+ << u8"Saturday, 25💪February 2017 17:21:25" << true;
+ QTest::newRow("C:short with emoji")
+ << "C" << dt << u8"d MMM yyyy HH📞mm📞ss" << u8"25 Feb 2017 17📞21📞25" << true;
+ QTest::newRow("C:narrow with emoji")
+ << "C" << dt << u8"🇬🇧d MMM yyyy HH:mm:ss🇬🇧" << u8"🇬🇧25 Feb 2017 17:21:25🇬🇧" << true;
+
+ QTest::newRow("fr:long") << "fr" << dt << "dddd d MMMM yyyy HH:mm:ss"
+ << "Samedi 25 février 2017 17:21:25" << true;
+ QTest::newRow("fr:short")
+ << "fr" << dt.addSecs(-25) << "dd/MM/yyyy HH:mm" << "25/02/2017 17:21" << true;
+
+ // In Turkish, the word for Friday ("Cuma") is a prefix for the word for
+ // Saturday ("Cumartesi")
+ QTest::newRow("tr:long")
+ << "tr" << dt << "d MMMM yyyy dddd HH:mm:ss" << "25 Şubat 2017 Cumartesi 17:21:25" << true;
+ QTest::newRow("tr:long2") << "tr" << dt.addDays(-1) << "d MMMM yyyy dddd HH:mm:ss"
+ << "24 Şubat 2017 Cuma 17:21:25" << true;
+ QTest::newRow("tr:mashed")
+ << "tr" << dt << "d MMMMyyyy ddddHH:mm:ss" << "25 Şubat2017 Cumartesi17:21:25" << true;
+ QTest::newRow("tr:mashed2") << "tr" << dt.addDays(-1) << "d MMMMyyyy ddddHH:mm:ss"
+ << "24 Şubat2017 Cuma17:21:25" << true;
+ QTest::newRow("tr:short")
+ << "tr" << dt.addSecs(-25) << "d.MM.yyyy HH:mm" << "25.02.2017 17:21" << true;
+
+ QTest::newRow("ccp:short")
+ << "ccp" << dt << "dd/M/yy h:mm AP"
+ // "𑄸𑄻/𑄸/𑄷𑄽 𑄻:𑄸𑄷 PM"
+ << QString::fromUcs4(U"\U00011138\U0001113b/\U00011138/\U00011137\U0001113d \U0001113b:"
+ U"\U00011138\U00011137 PM") << true;
+ QTest::newRow("ccp:long")
+ << "ccp" << dt << "dddd, d MMMM, yyyy h:mm:ss AP"
+ // "𑄥𑄧𑄚𑄨𑄝𑄢𑄴, 𑄸𑄻 𑄜𑄬𑄛𑄴𑄝𑄳𑄢𑄪𑄠𑄢𑄨, 𑄸𑄶𑄷𑄽 𑄻:𑄸𑄷:𑄸𑄻 PM"
+ << QString::fromUcs4(U"\U00011125\U00011127\U0001111a\U00011128\U0001111d\U00011122"
+ U"\U00011134, \U00011138\U0001113b \U0001111c\U0001112c\U0001111b"
+ U"\U00011134\U0001111d\U00011133\U00011122\U0001112a\U00011120"
+ U"\U00011122\U00011128, \U00011138\U00011136\U00011137\U0001113d "
+ U"\U0001113b:\U00011138\U00011137:\U00011138\U0001113b PM") << true;
+}
+
+void tst_QLocale::toDateTime()
+{
+ QFETCH(QString, localeName);
+ QFETCH(QDateTime, result);
+ QFETCH(QString, format);
+ QFETCH(QString, string);
+ QFETCH(bool, clean);
+
+ QLocale l(localeName);
+ QEXPECT_FAIL("ccp:short", "QTBUG-87111: Handling of code points outside BMP is broken", Abort);
+ QEXPECT_FAIL("ccp:long", "QTBUG-87111: Handling of code points outside BMP is broken", Abort);
+ QCOMPARE(l.toDateTime(string, format), result);
+ if (clean) {
+ QCOMPARE(l.toDateTime(string.toLower(), format), result);
+ QCOMPARE(l.toDateTime(string.toUpper(), format), result);
+ }
+
+ if (l.dateTimeFormat(QLocale::LongFormat) == format)
+ QCOMPARE(l.toDateTime(string, QLocale::LongFormat), result);
+ if (l.dateTimeFormat(QLocale::ShortFormat) == format)
+ QCOMPARE(l.toDateTime(string, QLocale::ShortFormat), result);
+}
+
+void tst_QLocale::toDate_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QDate>("result");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("string");
+ // No non-format letters in format string:
+ QTest::addColumn<bool>("clean");
+
+ const auto C = QLocale::c();
+ QTest::newRow("C-d/M/yyyy")
+ << C << QDate(1974, 12, 1) << u"d/M/yyyy"_s << u"1/12/1974"_s << true;
+ QTest::newRow("C-d/M/yyyyy")
+ << C << QDate(1974, 12, 1) << u"d/M/yyyyy"_s << u"1/12/1974y"_s << false;
+ QTest::newRow("C-dd/MM/yyy")
+ << C << QDate(1974, 1, 1) << u"dd/MM/yyy"_s << u"01/01/74y"_s << false;
+ QTest::newRow("C-ddddd/MMMMM/yy")
+ << C << QDate(1974, 12, 2) << u"ddddd/MMMMM/yy"_s << u"Monday2/December12/74"_s
+ << true;
+ QTest::newRow("C-'dddd'/MMMM/yy")
+ << C << QDate(1974, 12, 1) << u"'dddd'/MMMM/yy"_s << u"dddd/December/74"_s << false;
+ QTest::newRow("C-d'dd'd/MMMM/yyy")
+ << C << QDate(1974, 12, 1) << u"d'dd'd/MMMM/yyy"_s << u"1dd1/December/74y"_s << false;
+ QTest::newRow("C-d'dd'd/MMM'M'/yy")
+ << C << QDate(1974, 12, 1) << u"d'dd'd/MMM'M'/yy"_s << u"1dd1/DecM/74"_s << false;
+ QTest::newRow("C-d'd'dd/M/yy")
+ << C << QDate(1974, 12, 1) << u"d'd'dd/M/yy"_s << u"1d01/12/74"_s << false;
+ // Unpadded value for fixed-width field is wrong:
+ QTest::newRow("bad-day-C")
+ << C << QDate() << u"dd-MMM-yy"_s << u"4-Jun-11"_s << true;
+ QTest::newRow("bad-month-C")
+ << C << QDate() << u"d-MM-yy"_s << u"4-6-11"_s << true;
+ QTest::newRow("bad-year-C")
+ << C << QDate() << u"d-MMM-yyyy"_s << u"4-Jun-11"_s << true;
+ QTest::newRow("ok-C")
+ << C << QDate(1911, 6, 4) << u"d-MMM-yy"_s << u"4-Jun-11"_s << true;
+
+ // Locale-specific details frozen to avoid CLDR update breakage.
+ // However, updating to match CLDR from time to time would be constructive.
+ const QLocale norsk{QLocale::NorwegianBokmal, QLocale::Norway};
+ QTest::newRow("no_NO-d/M/yyyy")
+ << norsk << QDate(1974, 12, 1) << u"d/M/yyyy"_s << u"1/12/1974"_s << true;
+ QTest::newRow("no_NO-d/M/yyyyy")
+ << norsk << QDate(1974, 12, 1) << u"d/M/yyyyy"_s << u"1/12/1974y"_s << false;
+ QTest::newRow("no_NO-dd/MM/yyy")
+ << norsk << QDate(1974, 1, 1) << u"dd/MM/yyy"_s << u"01/01/74y"_s << false;
+ QTest::newRow("no_NO-ddddd/MMMMM/yy")
+ << norsk << QDate(1974, 12, 2) << u"ddddd/MMMMM/yy"_s << u"mandag2/desember12/74"_s
+ << true;
+ QTest::newRow("no_NO-'dddd'/MMMM/yy")
+ << norsk << QDate(1974, 12, 1) << u"'dddd'/MMMM/yy"_s << u"dddd/desember/74"_s
+ << false;
+ QTest::newRow("no_NO-d'dd'd/MMMM/yyy")
+ << norsk << QDate(1974, 12, 1) << u"d'dd'd/MMMM/yyy"_s << u"1dd1/desember/74y"_s
+ << false;
+ QTest::newRow("no_NO-d'dd'd/MMM'M'/yy")
+ << norsk << QDate(1974, 12, 1) << u"d'dd'd/MMM'M'/yy"_s << u"1dd1/des.M/74"_s
+ << false;
+ QTest::newRow("no_NO-d'd'dd/M/yy")
+ << norsk << QDate(1974, 12, 1) << u"d'd'dd/M/yy"_s << u"1d01/12/74"_s << false;
+
+ QTest::newRow("RFC-1123")
+ << C << QDate(2007, 11, 1) << u"ddd, dd MMM yyyy 'GMT'"_s << u"Thu, 01 Nov 2007 GMT"_s
+ << false;
+
+ const QLocale usa{QLocale::English, QLocale::UnitedStates};
+ QTest::newRow("longFormat")
+ << usa << QDate(2009, 1, 5) << u"dddd, MMMM d, yyyy"_s
+ << u"Monday, January 5, 2009"_s << true;
+ QTest::newRow("shortFormat") // Use of two-digit year considered harmful.
+ << usa << QDate(1909, 1, 5) << u"M/d/yy"_s << u"1/5/09"_s << true;
+
+ const QDate date(2017, 02, 25);
+ QTest::newRow("C:long")
+ << C << date << "dddd, d MMMM yyyy" << u"Saturday, 25 February 2017"_s << true;
+ QTest::newRow("C:short")
+ << C << date << u"d MMM yyyy"_s << u"25 Feb 2017"_s << true;
+ QTest::newRow("C:narrow")
+ << C << date << u"d MMM yyyy"_s << u"25 Feb 2017"_s << true;
+
+ // Test the same again with unicode and emoji.
+ QTest::newRow("C:long with emoji")
+ << C << date << u8"dddd, d💪MMMM yyyy" << u8"Saturday, 25💪February 2017" << true;
+ QTest::newRow("C:short with emoji")
+ << C << date << u8"d📞MMM📞yyyy" << u8"25📞Feb📞2017" << true;
+ QTest::newRow("C:narrow with emoji")
+ << C << date << u8"🇬🇧d MMM yyyy🇬🇧"
+ << u8"🇬🇧25 Feb 2017🇬🇧" << true;
+
+ const QLocale fr{QLocale::French};
+ QTest::newRow("fr:long")
+ << fr << date << "dddd d MMMM yyyy" << u"Samedi 25 février 2017"_s << true;
+ QTest::newRow("fr:short")
+ << fr << date << u"dd/MM/yyyy"_s << u"25/02/2017"_s << true;
+
+ // In Turkish, the word for Friday ("Cuma") is a prefix for the word for
+ // Saturday ("Cumartesi")
+ const QLocale turk(QLocale::Turkish);
+ QTest::newRow("tr:long-Cumartesi")
+ << turk << date << u"d MMMM yyyy dddd"_s << u"25 Şubat 2017 Cumartesi"_s << true;
+ QTest::newRow("tr:long-Cuma")
+ << turk << date.addDays(-1) << "d MMMM yyyy dddd" << u"24 Şubat 2017 Cuma"_s << true;
+ QTest::newRow("tr:mashed-Cumartesi")
+ << turk << date << u"d MMMMyyyydddd"_s << u"25 Şubat2017Cumartesi"_s << true;
+ QTest::newRow("tr:mashed-Cuma")
+ << turk << date.addDays(-1) << "ddddd MMMMyyyy" << u"Cuma24 Şubat2017"_s << true;
+ QTest::newRow("tr:short")
+ << turk << date << u"d.MM.yyyy"_s << u"25.02.2017"_s << true;
+
+ const QLocale chakma{QLocale::Chakma};
+ QTest::newRow("ccp:short")
+ << chakma << date << "dd/M/yy"
+ // "𑄸𑄻/𑄸/𑄷𑄽"
+ << QString::fromUcs4(U"\U00011138\U0001113b/\U00011138/\U00011137\U0001113d") << true;
+ QTest::newRow("ccp:long")
+ << chakma << date << "dddd, d MMMM, yyyy"
+ // "𑄥𑄧𑄚𑄨𑄝𑄢𑄴, 𑄸𑄻 𑄜𑄬𑄛𑄴𑄝𑄳𑄢𑄪𑄠𑄢𑄨, 𑄸𑄶𑄷𑄽"
+ << QString::fromUcs4(U"\U00011125\U00011127\U0001111a\U00011128\U0001111d\U00011122"
+ U"\U00011134, \U00011138\U0001113b \U0001111c\U0001112c\U0001111b"
+ U"\U00011134\U0001111d\U00011133\U00011122\U0001112a\U00011120"
+ U"\U00011122\U00011128, \U00011138\U00011136\U00011137\U0001113d")
+ << true;
+}
+
+void tst_QLocale::toDate()
+{
+ QFETCH(const QLocale, locale);
+ QFETCH(const QDate, result);
+ QFETCH(const QString, format);
+ QFETCH(const QString, string);
+ QFETCH(const bool, clean);
+
+ QEXPECT_FAIL("ccp:short", "QTBUG-87111: Handling of code points outside BMP is broken", Abort);
+ QEXPECT_FAIL("ccp:long", "QTBUG-87111: Handling of code points outside BMP is broken", Abort);
+ QCOMPARE(locale.toDate(string, format), result);
+ if (clean) {
+ QCOMPARE(locale.toDate(string.toLower(), format), result);
+ QCOMPARE(locale.toDate(string.toUpper(), format), result);
+ }
+
+ if (locale.dateFormat(QLocale::LongFormat) == format)
+ QCOMPARE(locale.toDate(string, QLocale::LongFormat), result);
+ if (locale.dateFormat(QLocale::ShortFormat) == format)
+ QCOMPARE(locale.toDate(string, QLocale::ShortFormat), result);
+}
+
+void tst_QLocale::toTime_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QTime>("result");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("string");
+ // No non-format letters in format string:
+ QTest::addColumn<bool>("clean");
+
+ const auto C = QLocale::c();
+ QTest::newRow("C-hh:h:mm")
+ << C << QTime(5, 14) << u"hh:h:mm"_s << u"05:5:14"_s << true;
+ QTest::newRow("C-h")
+ << C << QTime(15, 0) << u"h"_s << u"15"_s << true;
+ QTest::newRow("C-zzz")
+ << C << QTime(0, 0, 0, 1) << u"zzz"_s << u"001"_s << true;
+ QTest::newRow("C-z/001")
+ << C << QTime(0, 0, 0, 1) << u"z"_s << u"001"_s << true;
+ QTest::newRow("C-z/1")
+ << C << QTime(0, 0, 0, 100) << u"z"_s << u"1"_s << true;
+ QTest::newRow("C-ss")
+ << C << QTime(0, 0, 13) << u"ss"_s << u"13"_s << true;
+ QTest::newRow("C-s")
+ << C << QTime(0, 0, 13) << u"s"_s << u"13"_s << true;
+ QTest::newRow("C-m'm'mm")
+ << C << QTime(0, 4) << u"m'm'mm"_s << u"4m04"_s << false;
+ QTest::newRow("C-hhmmsss")
+ << C << QTime(0, 0, 3) << u"hhmmsss"_s << u"0000033"_s << true;
+ // Unpadded value for fixed-width field is wrong:
+ QTest::newRow("bad-hour-C")
+ << C << QTime() << u"hh:m"_s << u"1:2"_s << true;
+ QTest::newRow("bad-min-C")
+ << C << QTime() << u"h:mm"_s << u"1:2"_s << true;
+ QTest::newRow("bad-sec-C")
+ << C << QTime() << u"d-MMM-yy h:m:ss"_s << u"4-Jun-11 1:2:3"_s << true;
+ QTest::newRow("bad-milli-C")
+ << C << QTime() << u"h:m:s.zzz"_s << u"1:2:3.4"_s << true;
+ QTest::newRow("ok-C")
+ << C << QTime(1, 2, 3, 400) << u"h:m:s.z"_s << u"1:2:3.4"_s << true;
+
+ // Locale-specific details frozen to avoid CLDR update breakage.
+ // However, updating to match CLDR from time to time would be constructive.
+ const QLocale norsk{QLocale::NorwegianBokmal, QLocale::Norway};
+ QTest::newRow("nb_NO-hh:h:mm")
+ << norsk << QTime(5, 14) << u"hh:h:mm"_s << u"05:5:14"_s << true;
+ QTest::newRow("nb_NO-h")
+ <<norsk << QTime(15, 0) << u"h"_s << u"15"_s << true;
+ QTest::newRow("nb_NO-zzz")
+ <<norsk << QTime(0, 0) << u"zzz"_s << u"000"_s << true;
+ QTest::newRow("nb_NO-z")
+ <<norsk << QTime(0, 0) << u"z"_s << u"0"_s << true;
+ QTest::newRow("nb_NO-ss")
+ <<norsk << QTime(0, 0, 13) << u"ss"_s << u"13"_s << true;
+ QTest::newRow("nb_NO-s")
+ <<norsk << QTime(0, 0, 13) << u"s"_s << u"13"_s << true;
+ QTest::newRow("nb_NO-m'm'mm")
+ <<norsk << QTime(0, 4) << u"m'm'mm"_s << u"4m04"_s << false;
+ QTest::newRow("nb_NO-hhmmsss")
+ <<norsk << QTime(0, 0, 3) << u"hhmmsss"_s << u"0000033"_s << true;
+
+ QTest::newRow("short-ss") // Single-digit seconds does not match ss format.
+ << C << QTime() << u"HH:mm:ss"_s << u"02:26:3"_s << true;
+ QTest::newRow("RFC-1123")
+ << C << QTime(18, 8, 30) << u"hh:mm:ss 'GMT'"_s << u"18:08:30 GMT"_s << false;
+
+ const QLocale usa{QLocale::English, QLocale::UnitedStates};
+ QTest::newRow("longFormat-AM")
+ << usa << QTime(4, 43, 32) << u"h:mm:ss AP "_s << u"4:43:32 AM "_s << true;
+ QTest::newRow("shortFormat-AM")
+ << usa << QTime(4, 43) << u"h:mm AP "_s << u"4:43 AM "_s << true;
+ QTest::newRow("longFormat-PM")
+ << usa << QTime(16, 43, 32) << u"h:mm:ss AP "_s << u"4:43:32 PM "_s << true;
+ QTest::newRow("shortFormat-PM")
+ << usa << QTime(16, 43) << u"h:mm AP "_s << u"4:43 PM "_s << true;
+ // Some locales use a narrow non-breaking space as separator, but
+ // the user can't see the difference from a space (QTBUG-114909):
+ QTest::newRow("shortFormat-AM-mixspace")
+ << usa << QTime(4, 43) << u"h:mm\u202F" "AP "_s << u"4:43 AM "_s << true;
+
+ // Parsing am/pm indicators case-insensitively:
+ const QLocale czech{QLocale::Czech, QLocale::Czechia};
+ QTest::newRow("am-cs_CZ")
+ << czech << QTime(8, 15, 44, 400) << u"hh:mm:ss.z aP"_s << u"08:15:44.4 dOp."_s
+ << true;
+ QTest::newRow("pm-cs_CZ")
+ << czech << QTime(12, 0) << u"hh:mm aP"_s << u"12:00 OdP."_s << true;
+
+ const QTime time(17, 21, 25);
+ QTest::newRow("C:long")
+ << C << time << "HH:mm:ss" << u"17:21:25"_s << true;
+ QTest::newRow("C:short")
+ << C << time << u"HH:mm:ss"_s << u"17:21:25"_s << true;
+ QTest::newRow("C:narrow")
+ << C << time << u"HH:mm:ss"_s << u"17:21:25"_s << true;
+
+ // Test the same again with unicode and emoji.
+ QTest::newRow("C:long with emoji")
+ << C << time << u8"HH💪mm💪ss" << u8"17💪21💪25" << true;
+ QTest::newRow("C:short with emoji")
+ << C << time << u8"HH📞mm📞ss" << u8"17📞21📞25" << true;
+ QTest::newRow("C:narrow with emoji")
+ << C << time << u8"🇬🇧HH:mm:ss🇬🇧"
+ << u8"🇬🇧17:21:25🇬🇧" << true;
+
+ const QLocale fr{QLocale::French};
+ QTest::newRow("fr:long")
+ << fr << time << "HH:mm:ss" << u"17:21:25"_s << true;
+ QTest::newRow("fr:short")
+ << fr << time.addSecs(-25) << u"HH:mm"_s << u"17:21"_s << true;
+ QTest::newRow("tr:short")
+ << QLocale(QLocale::Turkish) << time.addSecs(-25) << u"HH:mm"_s << u"17:21"_s << true;
+
+ const QLocale chakma{QLocale::Chakma};
+ QTest::newRow("ccp:short")
+ << chakma << time << "h:mm AP"
+ // "𑄸𑄻/𑄸/𑄷𑄽 𑄻:𑄸𑄷 PM"
+ << QString::fromUcs4(U"\U0001113b:\U00011138\U00011137 PM") << true;
+ QTest::newRow("ccp:long")
+ << chakma << time << "h:mm:ss AP"
+ // "𑄻:𑄸𑄷:𑄸𑄻 PM"
+ << QString::fromUcs4(U"\U0001113b:\U00011138\U00011137:\U00011138\U0001113b PM") << true;
+}
+
+void tst_QLocale::toTime()
+{
+ QFETCH(const QLocale, locale);
+ QFETCH(const QTime, result);
+ QFETCH(const QString, format);
+ QFETCH(const QString, string);
+ QFETCH(const bool, clean);
+
+ QEXPECT_FAIL("ccp:short", "QTBUG-87111: Handling of code points outside BMP is broken", Abort);
+ QEXPECT_FAIL("ccp:long", "QTBUG-87111: Handling of code points outside BMP is broken", Abort);
+ QCOMPARE(locale.toTime(string, format), result);
+ if (clean) {
+ QCOMPARE(locale.toTime(string.toLower(), format), result);
+ QCOMPARE(locale.toTime(string.toUpper(), format), result);
+ }
+
+ if (locale.timeFormat(QLocale::LongFormat) == format)
+ QCOMPARE(locale.toTime(string, QLocale::LongFormat), result);
+ if (locale.timeFormat(QLocale::ShortFormat) == format)
+ QCOMPARE(locale.toTime(string, QLocale::ShortFormat), result);
+}
+
+void tst_QLocale::doubleRoundTrip_data()
+{
+ QTest::addColumn<QString>("localeName");
+ QTest::addColumn<QString>("numberText");
+ QTest::addColumn<char>("numberFormat");
+
+ // Signs and exponent separator aren't single characters:
+ QTest::newRow("sv_SE 4e-06 g") // Swedish, Sweden
+ << u"sv_SE"_s << u"4\u00d7" "10^\u2212" "06"_s << 'g';
+ QTest::newRow("se_NO 4e-06 g") // Northern Sami, Norway
+ << u"se_NO"_s << u"4\u00b7" "10^\u2212" "06"_s << 'g';
+ QTest::newRow("ar_EG 4e-06 g") // Arabic, Egypt
+ << u"ar_EG"_s << u"\u0664\u0623\u0633\u061c-\u0660\u0666"_s << 'g';
+ QTest::newRow("fa_IR 4e-06 g") // Farsi, Iran
+ << u"fa_IR"_s << u"\u06f4\u00d7\u06f1\u06f0^\u200e\u2212\u06f0\u06f6"_s << 'g';
+}
+
+void tst_QLocale::doubleRoundTrip()
+{
+ QFETCH(QString, localeName);
+ QFETCH(QString, numberText);
+ QFETCH(char, numberFormat);
+
+ QLocale locale(localeName);
+ bool ok;
+
+ double number = locale.toDouble(numberText, &ok);
+ QVERIFY(ok);
+ QCOMPARE(locale.toString(number, numberFormat), numberText);
+}
+
+void tst_QLocale::integerRoundTrip_data()
+{
+ QTest::addColumn<QString>("localeName");
+ QTest::addColumn<QString>("numberText");
+
+ // Two-character signs:
+ // Arabic, Egypt
+ QTest::newRow("ar_EG -406") << u"ar_EG"_s << u"\u061c-\u0664\u0660\u0666"_s;
+ // Farsi, Iran
+ QTest::newRow("fa_IR -406") << u"fa_IR"_s << u"\u200e\u2212\u06f4\u06f0\u06f6"_s;
+}
+
+void tst_QLocale::integerRoundTrip()
+{
+ QFETCH(QString, localeName);
+ QFETCH(QString, numberText);
+
+ QLocale locale(localeName);
+ bool ok;
+
+ qlonglong number = locale.toLongLong(numberText, &ok);
+ QVERIFY(ok);
+ QCOMPARE(locale.toString(number), numberText);
+}
+
+#ifdef Q_OS_DARWIN
+
+// Format number string according to system locale settings.
+// Expected in format is US "1,234.56".
+QString systemLocaleFormatNumber(QString &&numberString)
+{
+ QLocale locale = QLocale::system();
+ QString numberStringMunged =
+ numberString.replace(QChar(','), QChar('G')).replace(QChar('.'), QChar('D'));
+ if (locale.numberOptions() & QLocale::OmitGroupSeparator)
+ numberStringMunged.remove(QLatin1Char('G'));
+ else
+ numberStringMunged.replace(QChar('G'), locale.groupSeparator());
+ return numberStringMunged.replace(QChar('D'), locale.decimalPoint());
+}
+
+void tst_QLocale::macDefaultLocale()
+{
+ QLocale locale = QLocale::system();
+
+ if (locale.name() != QLatin1String("en_US"))
+ QSKIP("This test only tests for en_US");
+
+ QTime invalidTime;
+ QDate invalidDate;
+ QCOMPARE(locale.toString(invalidTime, QLocale::ShortFormat), QString());
+ QCOMPARE(locale.toString(invalidDate, QLocale::ShortFormat), QString());
+ QCOMPARE(locale.toString(invalidTime, QLocale::NarrowFormat), QString());
+ QCOMPARE(locale.toString(invalidDate, QLocale::NarrowFormat), QString());
+ QCOMPARE(locale.toString(invalidTime, QLocale::LongFormat), QString());
+ QCOMPARE(locale.toString(invalidDate, QLocale::LongFormat), QString());
+
+ // On OS X the decimal point and group separator are configurable
+ // independently of the locale. Verify that they have one of the
+ // allowed values and are not the same.
+ QVERIFY(locale.decimalPoint() == QStringView(u".")
+ || locale.decimalPoint() == QStringView(u","));
+ QVERIFY(locale.groupSeparator() == QStringView(u",")
+ || locale.groupSeparator() == QStringView(u".")
+ || locale.groupSeparator() == QStringView(u"\xA0") // no-breaking space
+ || locale.groupSeparator() == QStringView(u"'")
+ || locale.groupSeparator().isEmpty());
+ QCOMPARE_NE(locale.decimalPoint(), locale.groupSeparator());
+
+ // make sure we are using the system to parse them
+ QCOMPARE(locale.toString(1234.56), systemLocaleFormatNumber(QString("1,234.56")));
+
+ QTime testTime = QTime(1, 2, 3);
+ QTime utcTime = QDateTime(QDate::currentDate(), testTime).toUTC().time();
+ int diff = testTime.hour() - utcTime.hour();
+
+ // Check if local time and utc time are on opposite sides of the 24-hour wrap-around.
+ if (diff < -12)
+ diff += 24;
+ if (diff > 12)
+ diff -= 24;
+
+ const QString timeString = locale.toString(testTime, QLocale::LongFormat);
+ QVERIFY(timeString.contains(QString("1:02:03")));
+
+ // To run this test make sure "Curreny" is US Dollar in System Preferences->Language & Region->Advanced.
+ if (locale.currencySymbol() == QString("$")) {
+ QCOMPARE(locale.toCurrencyString(qulonglong(1234)),
+ systemLocaleFormatNumber(QString("$1,234.00")));
+ QCOMPARE(locale.toCurrencyString(double(1234.56)),
+ systemLocaleFormatNumber(QString("$1,234.56")));
+ }
+
+ // Depending on the configured time zone, the time string might not
+ // contain a GMT specifier. (Sometimes it just names the zone, like "CEST")
+ QLatin1String gmt("GMT");
+ if (timeString.contains(gmt) && diff) {
+ QLatin1Char sign(diff < 0 ? '-' : '+');
+ QString number(QString::number(qAbs(diff)));
+ const QString expect = gmt + sign + number;
+
+ if (diff < 10) {
+ const QString zeroed = gmt + sign + QLatin1Char('0') + number;
+
+ QVERIFY2(timeString.contains(expect) || timeString.contains(zeroed),
+ qPrintable(QString("timeString `%1', expected GMT specifier `%2' or `%3'")
+ .arg(timeString).arg(expect).arg(zeroed)));
+ } else {
+ QVERIFY2(timeString.contains(expect),
+ qPrintable(QString("timeString `%1', expected GMT specifier `%2'")
+ .arg(timeString).arg(expect)));
+ }
+ }
+ QCOMPARE(locale.dayName(1), QString("Monday"));
+ QCOMPARE(locale.dayName(7), QString("Sunday"));
+ QCOMPARE(locale.monthName(1), QString("January"));
+ QCOMPARE(locale.monthName(12), QString("December"));
+ QCOMPARE(locale.quoteString("string"),
+ QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d"));
+ QCOMPARE(locale.quoteString("string", QLocale::AlternateQuotation),
+ QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99"));
+
+ QList<Qt::DayOfWeek> days;
+ days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday;
+ QCOMPARE(locale.weekdays(), days);
+
+}
+#endif // Q_OS_DARWIN
+
+#if defined(Q_OS_WIN)
+#include <qt_windows.h>
+
+static QString getWinLocaleInfo(LCTYPE type)
+{
+ LCID id = GetThreadLocale();
+ int cnt = GetLocaleInfo(id, type, 0, 0) * 2;
+
+ if (cnt == 0) {
+ qWarning().nospace() << "QLocale: empty windows locale info (" << type << ')';
+ return QString();
+ }
+ cnt /= sizeof(wchar_t);
+ QScopedArrayPointer<wchar_t> buf(new wchar_t[cnt]);
+ cnt = GetLocaleInfo(id, type, buf.data(), cnt);
+
+ if (cnt == 0) {
+ qWarning().nospace() << "QLocale: empty windows locale info (" << type << ')';
+ return QString();
+ }
+ return QString::fromWCharArray(buf.data());
+}
+
+static void setWinLocaleInfo(LCTYPE type, QStringView value)
+{
+ LCID id = GetThreadLocale();
+ SetLocaleInfo(id, type, reinterpret_cast<const wchar_t*>(value.utf16()));
+}
+
+#ifndef LOCALE_SSHORTTIME
+# define LOCALE_SSHORTTIME 0x00000079
+#endif
+
+class RestoreLocaleHelper
+{
+public:
+ RestoreLocaleHelper()
+ {
+ m_decimal = getWinLocaleInfo(LOCALE_SDECIMAL);
+ m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND);
+ m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE);
+ m_ldate = getWinLocaleInfo(LOCALE_SLONGDATE);
+ m_stime = getWinLocaleInfo(LOCALE_SSHORTTIME);
+ m_ltime = getWinLocaleInfo(LOCALE_STIMEFORMAT);
+ m_digits = getWinLocaleInfo(LOCALE_SNATIVEDIGITS);
+ m_subst = getWinLocaleInfo(LOCALE_IDIGITSUBSTITUTION);
+ }
+
+ ~RestoreLocaleHelper()
+ {
+ // restore these, or the user will get a surprise
+ setWinLocaleInfo(LOCALE_SDECIMAL, m_decimal);
+ setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand);
+ setWinLocaleInfo(LOCALE_SSHORTDATE, m_sdate);
+ setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate);
+ setWinLocaleInfo(LOCALE_SSHORTTIME, m_stime);
+ setWinLocaleInfo(LOCALE_STIMEFORMAT, m_ltime);
+ setWinLocaleInfo(LOCALE_SNATIVEDIGITS, m_digits);
+ setWinLocaleInfo(LOCALE_IDIGITSUBSTITUTION, m_subst);
+
+ QTestLocaleChange::resetSystemLocale();
+ }
+
+ QString m_decimal, m_thousand, m_sdate, m_ldate, m_stime, m_ltime, m_digits, m_subst;
+};
+
+void tst_QLocale::windowsDefaultLocale()
+{
+ RestoreLocaleHelper systemLocale;
+ // set weird system defaults and make sure we're using them
+ setWinLocaleInfo(LOCALE_SDECIMAL, u"@");
+ setWinLocaleInfo(LOCALE_STHOUSAND, u"?");
+ const QString shortDateFormat = QStringLiteral("d*M*yyyy");
+ setWinLocaleInfo(LOCALE_SSHORTDATE, shortDateFormat);
+ const QString longDateFormat = QStringLiteral("d@M@yyyy");
+ setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat);
+ const QString shortTimeFormat = QStringLiteral("h^m^s");
+ setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat);
+ const QString longTimeFormat = QStringLiteral("HH%mm%ss");
+ setWinLocaleInfo(LOCALE_STIMEFORMAT, longTimeFormat);
+ // Suzhou numerals (QTBUG-85409):
+ const QStringView digits = u"\u3007\u3021\u3022\u3023\u3024\u3025\u3026\u3027\u3028\u3029";
+ setWinLocaleInfo(LOCALE_SNATIVEDIGITS, digits);
+ setWinLocaleInfo(LOCALE_IDIGITSUBSTITUTION, u"2");
+ // NB: when adding to the system things being set, be sure to update RestoreLocaleHelper, too.
+
+ QLocale locale = QTestLocaleChange::resetSystemLocale();
+
+ // Make sure we are seeing the system's format strings
+ QCOMPARE(locale.zeroDigit(), QStringView(u"\u3007"));
+ QCOMPARE(locale.decimalPoint(), QStringView(u"@"));
+ QCOMPARE(locale.groupSeparator(), QStringView(u"?"));
+ QCOMPARE(locale.dateFormat(QLocale::ShortFormat), shortDateFormat);
+ QCOMPARE(locale.dateFormat(QLocale::LongFormat), longDateFormat);
+ QCOMPARE(locale.timeFormat(QLocale::ShortFormat), shortTimeFormat);
+ QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat),
+ shortDateFormat + QLatin1Char(' ') + shortTimeFormat);
+ const QString expectedLongDateTimeFormat
+ = longDateFormat + QLatin1Char(' ') + longTimeFormat;
+ QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat);
+
+ // make sure we are using the system to parse them
+ QCOMPARE(locale.toString(1234.56), QStringView(u"\u3021?\u3022\u3023\u3024@\u3025\u3026"));
+ QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat),
+ QStringView(u"\u3021*\u3021\u3022*\u3021\u3029\u3027\u3024"));
+ QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::NarrowFormat),
+ locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat));
+ QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::LongFormat),
+ QStringView(u"\u3021@\u3021\u3022@\u3021\u3029\u3027\u3024"));
+ const QString expectedFormattedShortTime = QStringView(u"\u3021^\u3022^\u3023").toString();
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime);
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat),
+ locale.toString(QTime(1,2,3), QLocale::ShortFormat));
+ const QString expectedFormattedLongTime
+ = QStringView(u"\u3007\u3021%\u3007\u3022%\u3007\u3023").toString();
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
+ QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat),
+ QStringView(u"\u3021*\u3021\u3022*\u3021\u3029\u3027\u3024 ").toString()
+ + expectedFormattedShortTime);
+ QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::NarrowFormat),
+ locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat));
+ QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::LongFormat),
+ QStringView(u"\u3021@\u3021\u3022@\u3021\u3029\u3027\u3024 ").toString()
+ + expectedFormattedLongTime);
+}
+#endif // Q_OS_WIN
+
+void tst_QLocale::numberOptions()
+{
+ bool ok;
+
+ QLocale locale(QLocale::C);
+ QCOMPARE(locale.numberOptions(), QLocale::OmitGroupSeparator);
+ QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
+ QVERIFY(ok);
+ QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
+ QVERIFY(ok);
+ QCOMPARE(locale.toString(12345), QString("12345"));
+
+ locale.setNumberOptions({ });
+ QCOMPARE(locale.numberOptions(), 0);
+ QCOMPARE(locale.toInt(QString("12,345"), &ok), 12345);
+ QVERIFY(ok);
+ QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
+ QVERIFY(ok);
+ QCOMPARE(locale.toString(12345), QString("12,345"));
+
+ locale.setNumberOptions(QLocale::RejectGroupSeparator);
+ QCOMPARE(locale.numberOptions(), QLocale::RejectGroupSeparator);
+ locale.toInt(QString("12,345"), &ok);
+ QVERIFY(!ok);
+ QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
+ QVERIFY(ok);
+ QCOMPARE(locale.toString(12345), QString("12,345"));
+
+ QLocale locale2 = locale;
+ QCOMPARE(locale2.numberOptions(), QLocale::RejectGroupSeparator);
+
+ QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+01"));
+ locale.setNumberOptions(QLocale::OmitLeadingZeroInExponent);
+ QCOMPARE(locale.numberOptions(), QLocale::OmitLeadingZeroInExponent);
+ QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+1"));
+
+ locale.toDouble(QString("1.24e+01"), &ok);
+ QVERIFY(ok);
+ locale.setNumberOptions(QLocale::RejectLeadingZeroInExponent);
+ QCOMPARE(locale.numberOptions(), QLocale::RejectLeadingZeroInExponent);
+ locale.toDouble(QString("1.24e+1"), &ok);
+ QVERIFY(ok);
+ locale.toDouble(QString("1.24e+01"), &ok);
+ QVERIFY(!ok);
+
+ QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.4"));
+ locale.setNumberOptions(QLocale::IncludeTrailingZeroesAfterDot);
+ QCOMPARE(locale.numberOptions(), QLocale::IncludeTrailingZeroesAfterDot);
+ QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.400"));
+
+ locale.toDouble(QString("1.24e+01"), &ok);
+ QVERIFY(ok);
+ locale.toDouble(QString("1.2400e+01"), &ok);
+ QVERIFY(ok);
+ locale.toDouble(QString("12.4"), &ok);
+ QVERIFY(ok);
+ locale.toDouble(QString("12.400"), &ok);
+ QVERIFY(ok);
+ locale.setNumberOptions(QLocale::RejectTrailingZeroesAfterDot);
+ QCOMPARE(locale.numberOptions(), QLocale::RejectTrailingZeroesAfterDot);
+ locale.toDouble(QString("1.24e+01"), &ok);
+ QVERIFY(ok);
+ locale.toDouble(QString("1.2400e+01"), &ok);
+ QVERIFY(!ok);
+ locale.toDouble(QString("12.4"), &ok);
+ QVERIFY(ok);
+ locale.toDouble(QString("12.400"), &ok);
+ QVERIFY(!ok);
+ QT_TEST_EQUALITY_OPS(locale, locale2, false);
+}
+
+void tst_QLocale::negativeNumbers()
+{
+ QLocale locale(QLocale::C);
+
+ bool ok;
+ int i;
+
+ i = locale.toInt(QLatin1String("-100"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -100);
+
+ i = locale.toInt(QLatin1String("-1,000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -1000);
+
+ i = locale.toInt(QLatin1String("-1000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -1000);
+
+ i = locale.toInt(QLatin1String("-10,000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -10000);
+
+ i = locale.toInt(QLatin1String("-10000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -10000);
+
+ i = locale.toInt(QLatin1String("-100,000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -100000);
+
+ i = locale.toInt(QLatin1String("-100000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -100000);
+
+ i = locale.toInt(QLatin1String("-1,000,000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -1000000);
+
+ i = locale.toInt(QLatin1String("-1000000"), &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -1000000);
+
+ // Several Arabic locales have an invisible script-marker before their signs:
+ const QLocale egypt(QLocale::Arabic, QLocale::Egypt);
+ QCOMPARE(egypt.toString(-403), u"\u061c-\u0664\u0660\u0663"_s);
+ i = egypt.toInt(u"\u061c-\u0664\u0660\u0663"_s, &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -403);
+ i = egypt.toInt(u"\u061c+\u0664\u0660\u0663"_s, &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, 403);
+
+ // Likewise Farsi:
+ const QLocale farsi(QLocale::Persian, QLocale::Iran);
+ QCOMPARE(farsi.toString(-403), u"\u200e\u2212\u06f4\u06f0\u06f3"_s);
+ i = farsi.toInt(u"\u200e\u2212\u06f4\u06f0\u06f3"_s, &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, -403);
+ i = farsi.toInt(u"\u200e+\u06f4\u06f0\u06f3"_s, &ok);
+ QVERIFY(ok);
+ QCOMPARE(i, 403);
+ QT_TEST_EQUALITY_OPS(egypt, farsi, false);
+}
+
+#include <private/qlocale_p.h>
+#include <private/qlocale_data_p.h>
+
+static const int locale_data_count = sizeof(locale_data)/sizeof(locale_data[0]);
+
+void tst_QLocale::testNames_data()
+{
+ QTest::addColumn<QLocale::Language>("language");
+ QTest::addColumn<QLocale::Territory>("country");
+
+ QLocale::setDefault(QLocale(QLocale::C)); // Ensures predictable fall-backs
+
+ for (int i = 0; i < locale_data_count; ++i) {
+ const QLocaleData &item = locale_data[i];
+ const QByteArray lang =
+ QLocale::languageToString(QLocale::Language(item.m_language_id)).toUtf8();
+ const QByteArray land =
+ QLocale::territoryToString(QLocale::Territory(item.m_territory_id)).toUtf8();
+
+ QTest::addRow("data_%d (%s/%s)", i, lang.constData(), land.constData())
+ << QLocale::Language(item.m_language_id) << QLocale::Territory(item.m_territory_id);
+ }
+}
+
+void tst_QLocale::testNames()
+{
+ QFETCH(QLocale::Language, language);
+ QFETCH(const QLocale::Territory, country);
+
+ const QLocale l1(language, country);
+ if (language == QLocale::AnyLanguage && country == QLocale::AnyTerritory)
+ language = QLocale::C;
+ QCOMPARE(l1.language(), language);
+ QCOMPARE(l1.territory(), country);
+
+ const QString name = l1.name();
+
+ const QLocale l2(name);
+ QCOMPARE(l2.language(), language);
+ QCOMPARE(l2.territory(), country);
+ QCOMPARE(l2.name(), name);
+
+ const QLocale l3(name + QLatin1String("@foo"));
+ QCOMPARE(l3.language(), language);
+ QCOMPARE(l3.territory(), country);
+ QCOMPARE(l3.name(), name);
+
+ const QLocale l4(name + QLatin1String(".foo"));
+ QCOMPARE(l4.language(), language);
+ QCOMPARE(l4.territory(), country);
+ QCOMPARE(l4.name(), name);
+
+ if (language != QLocale::C) {
+ const int idx = name.indexOf(QLatin1Char('_'));
+ QCOMPARE_NE(idx, -1);
+ const QString lang = name.left(idx);
+
+ QCOMPARE(QLocale(lang).language(), language);
+ QCOMPARE(QLocale(lang + QLatin1String("@foo")).language(), language);
+ QCOMPARE(QLocale(lang + QLatin1String(".foo")).language(), language);
+ }
+}
+
+void tst_QLocale::dayName_data()
+{
+ QTest::addColumn<QString>("locale_name");
+ QTest::addColumn<QString>("dayName");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<QLocale::FormatType>("format");
+
+ QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
+
+ QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
+ QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
+ QTest::newRow("C narrow") << QString("C") << QString("7") << 7 << QLocale::NarrowFormat;
+
+ QTest::newRow("ru_RU long")
+ << QString("ru_RU")
+ << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320"
+ "\265\321\201\320\265\320\275\321\214\320\265")
+ << 7 << QLocale::LongFormat;
+ QTest::newRow("ru_RU short")
+ << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
+ QTest::newRow("ru_RU narrow")
+ << QString("ru_RU") << u"\u0412"_s << 7 << QLocale::NarrowFormat;
+
+ QTest::newRow("ga_IE/Mon") << QString("ga_IE") << QString("Luan") << 1 << QLocale::ShortFormat;
+ QTest::newRow("ga_IE/Sun") << QString("ga_IE") << QString("Domh") << 7 << QLocale::ShortFormat;
+ QTest::newRow("el_GR/Tue")
+ << QString("el_GR") << QString::fromUtf8("\316\244\317\201\316\257")
+ << 2 << QLocale::ShortFormat;
+ QTest::newRow("el_GR/Thu")
+ << QString("el_GR") << QString::fromUtf8("\316\240\316\255\316\274")
+ << 4 << QLocale::ShortFormat;
+ QTest::newRow("el_GR/Sat")
+ << QString("el_GR") << QString::fromUtf8("\316\243\316\254\316\262")
+ << 6 << QLocale::ShortFormat;
+}
+
+void tst_QLocale::dayName()
+{
+ QFETCH(QString, locale_name);
+ QFETCH(int, day);
+ QFETCH(QLocale::FormatType, format);
+
+ QLocale l(locale_name);
+ QTEST(l.dayName(day, format), "dayName");
+}
+
+void tst_QLocale::standaloneDayName_data()
+{
+ QTest::addColumn<QString>("locale_name");
+ QTest::addColumn<QString>("dayName");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<QLocale::FormatType>("format");
+
+ QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
+
+ QTest::newRow("C invalid: 0 long") << QString("C") << QString() << 0 << QLocale::LongFormat;
+ QTest::newRow("C invalid: 0 short") << QString("C") << QString() << 0 << QLocale::ShortFormat;
+ QTest::newRow("C invalid: 0 narrow") << QString("C") << QString() << 0 << QLocale::NarrowFormat;
+ QTest::newRow("C invalid: 8 long") << QString("C") << QString() << 8 << QLocale::LongFormat;
+ QTest::newRow("C invalid: 8 short") << QString("C") << QString() << 8 << QLocale::ShortFormat;
+ QTest::newRow("C invalid: 8 narrow") << QString("C") << QString() << 8 << QLocale::NarrowFormat;
+
+ QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
+ QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
+ QTest::newRow("C narrow") << QString("C") << QString("S") << 7 << QLocale::NarrowFormat;
+
+ QTest::newRow("ru_RU long")
+ << QString("ru_RU")
+ << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320"
+ "\265\321\201\320\265\320\275\321\214\320\265")
+ << 7 << QLocale::LongFormat;
+ QTest::newRow("ru_RU short")
+ << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
+ QTest::newRow("ru_RU narrow")
+ << QString("ru_RU") << QString::fromUtf8("\320\222") << 7 << QLocale::NarrowFormat;
+}
+
+void tst_QLocale::standaloneDayName()
+{
+ QFETCH(QString, locale_name);
+ QFETCH(int, day);
+ QFETCH(QLocale::FormatType, format);
+
+ QLocale l(locale_name);
+ QTEST(l.standaloneDayName(day, format), "dayName");
+}
+
+void tst_QLocale::underflowOverflow()
+{
+ QString a(QLatin1String("0.") + QString(546, QLatin1Char('0')) + QLatin1String("1e10"));
+ bool ok = false;
+ double d = a.toDouble(&ok);
+ QVERIFY(!ok);
+ QCOMPARE(d, 0.0);
+
+ a = QLatin1String("1e600");
+ ok = false;
+ d = a.toDouble(&ok);
+ QVERIFY(!ok); // detectable overflow
+ QVERIFY(qIsInf(d));
+
+ a = QLatin1String("-1e600");
+ ok = false;
+ d = a.toDouble(&ok);
+ QVERIFY(!ok); // detectable underflow
+ QVERIFY(qIsInf(-d));
+
+ a = QLatin1String("1e-600");
+ ok = false;
+ d = a.toDouble(&ok);
+ QVERIFY(!ok);
+ QCOMPARE(d, 0.0);
+
+ a = QLatin1String("-9223372036854775809");
+ a.toLongLong(&ok);
+ QVERIFY(!ok);
+}
+
+void tst_QLocale::defaultNumberingSystem_data()
+{
+ QTest::addColumn<QString>("expect");
+
+ QTest::newRow("sk_SK") << QStringLiteral("123");
+ QTest::newRow("ta_IN") << QStringLiteral("123");
+ QTest::newRow("te_IN") << QStringLiteral("123");
+ QTest::newRow("hi_IN") << QStringLiteral("123");
+ QTest::newRow("gu_IN") << QStringLiteral("123");
+ QTest::newRow("kn_IN") << QStringLiteral("123");
+ QTest::newRow("pa_IN") << QStringLiteral("123");
+ QTest::newRow("ne_IN") << QString::fromUtf8("१२३");
+ QTest::newRow("mr_IN") << QString::fromUtf8("१२३");
+ QTest::newRow("ml_IN") << QStringLiteral("123");
+ QTest::newRow("kok_IN") << QStringLiteral("123");
+}
+
+void tst_QLocale::defaultNumberingSystem()
+{
+ QLatin1String name(QTest::currentDataTag());
+ QLocale locale(name);
+ QTEST(locale.toString(123), "expect");
+}
+
+void tst_QLocale::ampm_data()
+{
+ QTest::addColumn<QString>("morn");
+ QTest::addColumn<QString>("even");
+
+ QTest::newRow("C") << QStringLiteral("AM") << QStringLiteral("PM");
+ QTest::newRow("de_DE") << QStringLiteral("AM") << QStringLiteral("PM");
+ QTest::newRow("sv_SE") << QStringLiteral("fm") << QStringLiteral("em");
+ QTest::newRow("nl_NL") << QStringLiteral("a.m.") << QStringLiteral("p.m.");
+ QTest::newRow("uk_UA") << QString::fromUtf8("\320\264\320\277")
+ << QString::fromUtf8("\320\277\320\277");
+ QTest::newRow("tr_TR") << QString::fromUtf8("\303\226\303\226")
+ << QString::fromUtf8("\303\226\123");
+ QTest::newRow("id_ID") << QStringLiteral("AM") << QStringLiteral("PM");
+ // CLDR v44 made Tamil's AM/PM inconsistent; AM was "முற்பகல்" before.
+ QTest::newRow("ta_LK") << QString::fromUtf8("AM") << QString::fromUtf8("பிற்பகல்");
+}
+
+void tst_QLocale::ampm()
+{
+ QLatin1String name(QTest::currentDataTag());
+ QLocale locale(name == QLatin1String("C") ? QLocale(QLocale::C) : QLocale(name));
+ QTEST(locale.amText(), "morn");
+ QTEST(locale.pmText(), "even");
+}
+
+void tst_QLocale::dateFormat()
+{
+ const QLocale c(QLocale::C);
+ // check that the NarrowFormat is the same as ShortFormat.
+ QCOMPARE(c.dateFormat(QLocale::NarrowFormat), c.dateFormat(QLocale::ShortFormat));
+
+ const QLocale no("no_NO");
+ QCOMPARE(no.dateFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy"));
+ QCOMPARE(no.dateFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy"));
+ QCOMPARE(no.dateFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy"));
+
+ const QLocale ca("en_CA");
+ QCOMPARE(ca.dateFormat(QLocale::ShortFormat), QLatin1String("yyyy-MM-dd"));
+ QCOMPARE(ca.dateFormat(QLocale::LongFormat), QLatin1String("dddd, MMMM d, yyyy"));
+
+ const QLocale ja("ja_JP");
+ QCOMPARE(ja.dateFormat(QLocale::ShortFormat), QLatin1String("yyyy/MM/dd"));
+
+ const QLocale ir("ga_IE");
+ QCOMPARE(ir.dateFormat(QLocale::ShortFormat), QLatin1String("dd/MM/yyyy"));
+
+ QT_TEST_EQUALITY_OPS(c, no, false);
+ QT_TEST_EQUALITY_OPS(ca, ja, false);
+ QT_TEST_EQUALITY_OPS(ca, ir, false);
+ QT_TEST_EQUALITY_OPS(ir, ja, false);
+
+ const auto sys = QLocale::system(); // QTBUG-92018, ru_RU on MS
+ const QDate date(2021, 3, 17);
+ QCOMPARE(sys.toString(date, sys.dateFormat(QLocale::LongFormat)), sys.toString(date));
+
+ // Check that system locale can format a date with year < 1601 (MS cut-off):
+ QString old = sys.toString(QDate(1564, 2, 15), QLocale::LongFormat);
+ QVERIFY(!old.isEmpty());
+ QVERIFY2(old.contains(u"1564"), qPrintable(old + QLatin1String(" for locale ") + sys.name()));
+ old = sys.toString(QDate(1564, 2, 15), QLocale::ShortFormat);
+ QVERIFY(!old.isEmpty());
+ QVERIFY2(old.contains(u"64"), qPrintable(old + QLatin1String(" for locale ") + sys.name()));
+
+ // Including one with year % 100 < 12 (lest we substitute year for month or day)
+ old = sys.toString(QDate(1511, 11, 11), QLocale::LongFormat);
+ QVERIFY(!old.isEmpty());
+ QVERIFY2(old.contains(u"1511"), qPrintable(old + QLatin1String(" for locale ") + sys.name()));
+ old = sys.toString(QDate(1511, 11, 11), QLocale::ShortFormat);
+ QVERIFY(!old.isEmpty());
+ QVERIFY2(old.contains(u"11"), qPrintable(old + QLatin1String(" for locale ") + sys.name()));
+
+ // And, indeed, one for a negative year:
+ old = sys.toString(QDate(-1173, 5, 1), QLocale::LongFormat);
+ QVERIFY(!old.isEmpty());
+ qsizetype yearDigitStart = old.indexOf(u"1173");
+ QVERIFY2(yearDigitStart != -1, qPrintable(old + QLatin1String(" for locale ") + sys.name()));
+ QStringView before = QStringView(old).first(yearDigitStart);
+ QVERIFY2(before.endsWith(QChar('-')) || before.endsWith(QChar(0x2212)),
+ qPrintable(old + QLatin1String(" has no minus sign for locale ") + sys.name()));
+}
+
+void tst_QLocale::timeFormat()
+{
+ const QLocale c(QLocale::C);
+ // check that the NarrowFormat is the same as ShortFormat.
+ QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat));
+
+ const QLocale no("no_NO");
+ QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH:mm"));
+ QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm"));
+ QCOMPARE(no.timeFormat(QLocale::LongFormat), "HH:mm:ss tttt"_L1);
+
+ const QLocale id("id_ID");
+ QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
+ QCOMPARE(id.timeFormat(QLocale::LongFormat), "HH.mm.ss tttt"_L1);
+
+ const QLocale cat("ca_ES");
+ QCOMPARE(cat.timeFormat(QLocale::ShortFormat), QLatin1String("H:mm"));
+ QCOMPARE(cat.timeFormat(QLocale::LongFormat), "H:mm:ss (tttt)"_L1);
+
+ const QLocale bra("pt_BR");
+ QCOMPARE(bra.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm"));
+ QCOMPARE(bra.timeFormat(QLocale::LongFormat), "HH:mm:ss tttt"_L1);
+
+ // QTBUG-123872 - we kludge CLDR's B to Ap:
+ const QLocale tw("zh_TW");
+ QCOMPARE(tw.timeFormat(QLocale::ShortFormat), "Aph:mm"_L1);
+ QCOMPARE(tw.timeFormat(QLocale::LongFormat), "Aph:mm:ss [tttt]"_L1);
+
+ QT_TEST_EQUALITY_OPS(c, no, false);
+ QT_TEST_EQUALITY_OPS(id, no, false);
+ QT_TEST_EQUALITY_OPS(c, cat, false);
+ QT_TEST_EQUALITY_OPS(bra, no, false);
+}
+
+void tst_QLocale::dateTimeFormat()
+{
+ const QLocale c(QLocale::C);
+ // check that the NarrowFormat is the same as ShortFormat.
+ QCOMPARE(c.dateTimeFormat(QLocale::NarrowFormat), c.dateTimeFormat(QLocale::ShortFormat));
+
+ const QLocale no("no_NO");
+ QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH:mm"));
+ QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH:mm"));
+ QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), "dddd d. MMMM yyyy HH:mm:ss tttt"_L1);
+
+ QT_TEST_EQUALITY_OPS(c, no, false);
+}
+
+void tst_QLocale::monthName()
+{
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.monthName(0, QLocale::ShortFormat), QString());
+ QCOMPARE(c.monthName(0, QLocale::LongFormat), QString());
+ QCOMPARE(c.monthName(0, QLocale::NarrowFormat), QString());
+ QCOMPARE(c.monthName(13, QLocale::ShortFormat), QString());
+ QCOMPARE(c.monthName(13, QLocale::LongFormat), QString());
+ QCOMPARE(c.monthName(13, QLocale::NarrowFormat), QString());
+
+ QCOMPARE(c.monthName(1, QLocale::LongFormat), QLatin1String("January"));
+ QCOMPARE(c.monthName(1, QLocale::ShortFormat), QLatin1String("Jan"));
+ QCOMPARE(c.monthName(1, QLocale::NarrowFormat), QLatin1String("1"));
+
+ const QLocale de("de_DE");
+ QCOMPARE(de.monthName(12, QLocale::LongFormat), QLatin1String("Dezember"));
+ QCOMPARE(de.monthName(12, QLocale::ShortFormat), QLatin1String("Dez."));
+ // 'de' locale doesn't have narrow month name
+ QCOMPARE(de.monthName(12, QLocale::NarrowFormat), QLatin1String("D"));
+
+ const QLocale ru("ru_RU");
+ QCOMPARE(ru.monthName(1, QLocale::LongFormat),
+ QString::fromUtf8("\321\217\320\275\320\262\320\260\321\200\321\217"));
+ QCOMPARE(ru.monthName(1, QLocale::ShortFormat),
+ QString::fromUtf8("\321\217\320\275\320\262\56"));
+ QCOMPARE(ru.monthName(1, QLocale::NarrowFormat), QString::fromUtf8("\320\257"));
+ const auto sys = QLocale::system();
+ if (sys.language() == QLocale::Russian) // QTBUG-92018
+ QCOMPARE_NE(sys.monthName(3), sys.standaloneMonthName(3));
+
+ const QLocale ir("ga_IE");
+ QCOMPARE(ir.monthName(1, QLocale::ShortFormat), QLatin1String("Ean"));
+ QCOMPARE(ir.monthName(12, QLocale::ShortFormat), QLatin1String("Noll"));
+
+ const QLocale cz("cs_CZ");
+ QCOMPARE(cz.monthName(1, QLocale::ShortFormat), QLatin1String("led"));
+ QCOMPARE(cz.monthName(12, QLocale::ShortFormat), QLatin1String("pro"));
+}
+
+void tst_QLocale::standaloneMonthName()
+{
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.monthName(0, QLocale::ShortFormat), QString());
+ QCOMPARE(c.monthName(0, QLocale::LongFormat), QString());
+ QCOMPARE(c.monthName(0, QLocale::NarrowFormat), QString());
+ QCOMPARE(c.monthName(13, QLocale::ShortFormat), QString());
+ QCOMPARE(c.monthName(13, QLocale::LongFormat), QString());
+ QCOMPARE(c.monthName(13, QLocale::NarrowFormat), QString());
+
+ QCOMPARE(c.standaloneMonthName(1, QLocale::LongFormat), QLatin1String("January"));
+ QCOMPARE(c.standaloneMonthName(1, QLocale::ShortFormat), QLatin1String("Jan"));
+
+ const QLocale de("de_DE");
+ // For de_DE locale Unicode CLDR database doesn't contain standalone long months
+ // so just checking if the return value is the same as in monthName().
+ QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat), QLatin1String("Dezember"));
+ QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat),
+ de.monthName(12, QLocale::LongFormat));
+ QCOMPARE(de.standaloneMonthName(12, QLocale::ShortFormat), QLatin1String("Dez"));
+ QCOMPARE(de.standaloneMonthName(12, QLocale::NarrowFormat), QLatin1String("D"));
+
+ QLocale ru("ru_RU");
+ QCOMPARE(ru.standaloneMonthName(1, QLocale::LongFormat),
+ QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c"));
+ QCOMPARE(ru.standaloneMonthName(1, QLocale::ShortFormat),
+ QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2."));
+ QCOMPARE(ru.standaloneMonthName(1, QLocale::NarrowFormat), QString::fromUtf8("\xd0\xaf"));
+}
+
+void tst_QLocale::languageToString_data()
+{
+ QTest::addColumn<QLocale::Language>("language");
+ QTest::addColumn<QString>("name");
+
+ // Prone to change at CLDR updates.
+ QTest::newRow("cu") << QLocale::Church << u"Church Slavic"_s;
+ QTest::newRow("dyo") << QLocale::JolaFonyi << u"Jola-Fonyi"_s;
+ QTest::newRow("ff") << QLocale::Fulah << u"Fula"_s;
+ QTest::newRow("gd") << QLocale::Gaelic << u"Scottish Gaelic"_s;
+ QTest::newRow("ht") << QLocale::Haitian << u"Haitian Creole"_s;
+ QTest::newRow("lu") << QLocale::LubaKatanga << u"Luba-Katanga"_s;
+ QTest::newRow("mgh") << QLocale::MakhuwaMeetto << u"Makhuwa-Meetto"_s;
+ QTest::newRow("mgo") << QLocale::Meta << u"Meta\u02bc"_s;
+ QTest::newRow("mi") << QLocale::Maori << u"M\u0101" "ori"_s;
+ QTest::newRow("nb") << QLocale::NorwegianBokmal << u"Norwegian Bokm\u00e5" "l"_s;
+ QTest::newRow("nqo") << QLocale::Nko << u"N\u2019" "Ko"_s;
+ QTest::newRow("quc") << QLocale::Kiche << u"K\u02bc" "iche\u02bc"_s;
+ QTest::newRow("sah") << QLocale::Sakha << u"Yakut"_s;
+ QTest::newRow("vo") << QLocale::Volapuk << u"Volap\u00fc" "k"_s;
+}
+
+void tst_QLocale::languageToString()
+{
+ QFETCH(const QLocale::Language, language);
+ QTEST(QLocale::languageToString(language), "name");
+}
+
+void tst_QLocale::scriptToString_data()
+{
+ QTest::addColumn<QLocale::Script>("script");
+ QTest::addColumn<QString>("name");
+
+ // Prone to change at CLDR updates.
+ QTest::newRow("Cans")
+ << QLocale::CanadianAboriginalScript << u"Unified Canadian Aboriginal Syllabics"_s;
+ QTest::newRow("Dupl") << QLocale::DuployanScript << u"Duployan shorthand"_s;
+ QTest::newRow("Egyp") << QLocale::EgyptianHieroglyphsScript << u"Egyptian hieroglyphs"_s;
+ QTest::newRow("Nkoo") << QLocale::NkoScript << u"N\u2019" "Ko"_s;
+ QTest::newRow("Phag") << QLocale::PhagsPaScript << u"Phags-pa"_s;
+ QTest::newRow("Rohg") << QLocale::HanifiScript << u"Hanifi Rohingya"_s;
+ QTest::newRow("Sgnw") << QLocale::SignWritingScript << u"SignWriting"_s;
+ QTest::newRow("Xsux") << QLocale::CuneiformScript << u"Sumero-Akkadian Cuneiform"_s;
+}
+
+void tst_QLocale::scriptToString()
+{
+ QFETCH(const QLocale::Script, script);
+ QTEST(QLocale::scriptToString(script), "name");
+}
+
+void tst_QLocale::territoryToString_data()
+{
+ QTest::addColumn<QLocale::Territory>("territory");
+ QTest::addColumn<QString>("name");
+ // Prone to change at CLDR updates.
+
+ QTest::newRow("AX") << QLocale::AlandIslands << u"\u00c5" "land Islands"_s;
+ QTest::newRow("AG") << QLocale::AntiguaAndBarbuda << u"Antigua & Barbuda"_s;
+ QTest::newRow("BA") << QLocale::BosniaAndHerzegovina << u"Bosnia & Herzegovina"_s;
+ QTest::newRow("BL") << QLocale::SaintBarthelemy << u"St. Barth\u00e9" "lemy"_s;
+ QTest::newRow("CC") << QLocale::CocosIslands << u"Cocos (Keeling) Islands"_s;
+ QTest::newRow("CD") << QLocale::CongoKinshasa << u"Congo - Kinshasa"_s;
+ QTest::newRow("CG") << QLocale::CongoBrazzaville << u"Congo - Brazzaville"_s;
+ QTest::newRow("CI") << QLocale::IvoryCoast << u"C\u00f4" "te d\u2019" "Ivoire"_s;
+ QTest::newRow("CW") << QLocale::Curacao << u"Cura\u00e7" "ao"_s;
+ QTest::newRow("EA") << QLocale::CeutaAndMelilla << u"Ceuta & Melilla"_s;
+ QTest::newRow("GS")
+ << QLocale::SouthGeorgiaAndSouthSandwichIslands
+ << u"South Georgia & South Sandwich Islands"_s;
+ QTest::newRow("GW") << QLocale::GuineaBissau << u"Guinea-Bissau"_s;
+ QTest::newRow("HM") << QLocale::HeardAndMcDonaldIslands << u"Heard & McDonald Islands"_s;
+ QTest::newRow("IM") << QLocale::IsleOfMan << u"Isle of Man"_s;
+ QTest::newRow("KN") << QLocale::SaintKittsAndNevis << u"St. Kitts & Nevis"_s;
+ QTest::newRow("LC") << QLocale::SaintLucia << u"St. Lucia"_s;
+ QTest::newRow("MF") << QLocale::SaintMartin << u"St. Martin"_s;
+ QTest::newRow("MK") << QLocale::Macedonia << u"North Macedonia"_s;
+ QTest::newRow("MM") << QLocale::Myanmar << u"Myanmar (Burma)"_s;
+ QTest::newRow("MO") << QLocale::Macao << u"Macao SAR China"_s;
+ QTest::newRow("PM") << QLocale::SaintPierreAndMiquelon << u"St. Pierre & Miquelon"_s;
+ QTest::newRow("PN") << QLocale::Pitcairn << u"Pitcairn Islands"_s;
+ QTest::newRow("RE") << QLocale::Reunion << u"R\u00e9" "union"_s;
+ QTest::newRow("SH") << QLocale::SaintHelena << u"St. Helena"_s;
+ QTest::newRow("SJ") << QLocale::SvalbardAndJanMayen << u"Svalbard & Jan Mayen"_s;
+ QTest::newRow("ST")
+ << QLocale::SaoTomeAndPrincipe << u"S\u00e3" "o Tom\u00e9" " & Pr\u00ed" "ncipe"_s;
+ QTest::newRow("TA") << QLocale::TristanDaCunha << u"Tristan da Cunha"_s;
+ QTest::newRow("TC") << QLocale::TurksAndCaicosIslands << u"Turks & Caicos Islands"_s;
+ QTest::newRow("TR") << QLocale::Turkey << u"T\u00fc" "rkiye"_s;
+ QTest::newRow("TT") << QLocale::TrinidadAndTobago << u"Trinidad & Tobago"_s;
+ QTest::newRow("UM") << QLocale::UnitedStatesOutlyingIslands << u"U.S. Outlying Islands"_s;
+ QTest::newRow("VC") << QLocale::SaintVincentAndGrenadines << u"St. Vincent & Grenadines"_s;
+ QTest::newRow("VI") << QLocale::UnitedStatesVirginIslands << u"U.S. Virgin Islands"_s;
+ QTest::newRow("WF") << QLocale::WallisAndFutuna << u"Wallis & Futuna"_s;
+ QTest::newRow("001") << QLocale::World << u"world"_s;
+}
+
+void tst_QLocale::territoryToString()
+{
+ QFETCH(const QLocale::Territory, territory);
+ QTEST(QLocale::territoryToString(territory), "name");
+}
+
+void tst_QLocale::endonym_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QString>("language");
+ QTest::addColumn<QString>("territory");
+
+ QTest::newRow("en")
+ << QLocale(QLocale::English, QLocale::UnitedStates)
+ << u"American English"_s << u"United States"_s;
+ QTest::newRow("en_GB")
+ << QLocale(QLocale::English, QLocale::UnitedKingdom)
+ << u"British English"_s << u"United Kingdom"_s; // So inaccurate
+}
+
+void tst_QLocale::endonym()
+{
+ QFETCH(const QLocale, locale);
+
+ auto report = qScopeGuard([locale]() {
+ qDebug()
+ << "Failed for" << locale.name()
+ << "with language" << QLocale::languageToString(locale.language())
+ << "for territory" << QLocale::territoryToString(locale.territory())
+ << "in script" << QLocale::scriptToString(locale.script());
+ });
+
+ QTEST(locale.nativeLanguageName(), "language");
+ QTEST(locale.nativeTerritoryName(), "territory");
+ report.dismiss();
+}
+
+void tst_QLocale::currency()
+{
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.toCurrencyString(qulonglong(1234)), QString("1234"));
+ QCOMPARE(c.toCurrencyString(qlonglong(-1234)), QString("-1234"));
+ QCOMPARE(c.toCurrencyString(double(1234.56)), QString("1234.56"));
+ QCOMPARE(c.toCurrencyString(double(-1234.56)), QString("-1234.56"));
+ QCOMPARE(c.toCurrencyString(double(-1234.5678)), QString("-1234.57"));
+ QCOMPARE(c.toCurrencyString(double(-1234.5678), NULL, 4), QString("-1234.5678"));
+ QCOMPARE(c.toCurrencyString(double(-1234.56), NULL, 4), QString("-1234.5600"));
+
+ const QLocale en_US("en_US");
+ QCOMPARE(en_US.toCurrencyString(qulonglong(1234)), QString("$1,234"));
+ QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("($1,234)"));
+ QCOMPARE(en_US.toCurrencyString(double(1234.56)), QString("$1,234.56"));
+ QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("($1,234.56)"));
+ QCOMPARE(en_US.toCurrencyString(double(-1234.5678)), QString("($1,234.57)"));
+ QCOMPARE(en_US.toCurrencyString(double(-1234.5678), NULL, 4), QString("($1,234.5678)"));
+ QCOMPARE(en_US.toCurrencyString(double(-1234.56), NULL, 4), QString("($1,234.5600)"));
+
+ const QLocale ru_RU("ru_RU");
+ QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)),
+ QString::fromUtf8("1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(qlonglong(-1234)),
+ QString::fromUtf8("-1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(double(1234.56)),
+ QString::fromUtf8("1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(double(-1234.56)),
+ QString::fromUtf8("-1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
+
+ const QLocale de_DE("de_DE");
+ QCOMPARE(de_DE.toCurrencyString(qulonglong(1234)),
+ QString::fromUtf8("1.234\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(qulonglong(1234), QLatin1String("BAZ")),
+ QString::fromUtf8("1.234\xc2\xa0" "BAZ"));
+ QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234)),
+ QString::fromUtf8("-1.234\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234), QLatin1String("BAZ")),
+ QString::fromUtf8("-1.234\xc2\xa0" "BAZ"));
+ QCOMPARE(de_DE.toCurrencyString(double(1234.56)),
+ QString::fromUtf8("1.234,56\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(double(-1234.56)),
+ QString::fromUtf8("-1.234,56\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")),
+ QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ"));
+
+ const QLocale es_CR(QLocale::Spanish, QLocale::CostaRica);
+ QCOMPARE(es_CR.toCurrencyString(double(1565.25)),
+ QString::fromUtf8("\xE2\x82\xA1" "1\xC2\xA0" "565,25"));
+ QCOMPARE(es_CR.toCurrencyString(double(12565.25)),
+ QString::fromUtf8("\xE2\x82\xA1" "12\xC2\xA0" "565,25"));
+
+ const QLocale system = QLocale::system();
+ QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO")));
+ QT_TEST_EQUALITY_OPS(system, es_CR, false);
+}
+
+void tst_QLocale::quoteString()
+{
+ const QString someText("text");
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.quoteString(someText), QString::fromUtf8("\x22" "text" "\x22"));
+ QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation),
+ QString::fromUtf8("\x27" "text" "\x27"));
+
+ const QLocale de_CH("de_CH");
+ QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xe2\x80\x9e" "text" "\xe2\x80\x9c"));
+ QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation),
+ QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98"));
+ QT_TEST_EQUALITY_OPS(de_CH, c, false);
+}
+
+void tst_QLocale::uiLanguages_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QStringList>("all");
+
+ QTest::newRow("C") << QLocale::c() << QStringList{QString("C")};
+
+ QTest::newRow("en_US")
+ << QLocale("en_US")
+ << QStringList{QString("en-Latn-US"), QString("en-US"), QString("en")};
+
+ QTest::newRow("en_Latn_US")
+ << QLocale("en_Latn_US") // Specifying the default script makes no difference
+ << QStringList{QString("en-Latn-US"), QString("en-US"), QString("en")};
+
+ QTest::newRow("en_GB")
+ << QLocale("en_GB")
+ << QStringList{QString("en-Latn-GB"), QString("en-GB")};
+
+ QTest::newRow("en_Dsrt_US")
+ << QLocale("en_Dsrt_US")
+ << QStringList{QString("en-Dsrt-US"), QString("en-Dsrt")};
+
+ QTest::newRow("ru_RU")
+ << QLocale("ru_RU")
+ << QStringList{QString("ru-Cyrl-RU"), QString("ru-RU"), QString("ru")};
+
+ QTest::newRow("zh_Hant")
+ << QLocale("zh_Hant")
+ << QStringList{QString("zh-Hant-TW"), QString("zh-TW")};
+
+ QTest::newRow("zh_Hans_CN")
+ << QLocale(QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China)
+ << QStringList{QString("zh-Hans-CN"), QString("zh-CN"), QString("zh")};
+
+ // We presently map und (or any other unrecognized language) to C, ignoring
+ // what a sub-tag lookup would surely find us.
+ QTest::newRow("und_US") << QLocale("und_US") << QStringList{QString("C")};
+ QTest::newRow("und_Latn") << QLocale("und_Latn") << QStringList{QString("C")};
+}
+
+void tst_QLocale::uiLanguages()
+{
+ // Compare mySystemLocale(), which tests the same for a custom system locale.
+ QFETCH(const QLocale, locale);
+ QFETCH(const QStringList, all);
+ const auto expected = [all](QChar sep) {
+ QStringList adjusted;
+ for (QString name : all)
+ adjusted << name.replace(u'-', sep);
+ return adjusted;
+ };
+
+ {
+ // By default tags are joined with a dash:
+ const QStringList actual = locale.uiLanguages();
+ auto reporter = qScopeGuard([&actual]() {
+ qDebug("\n\t%ls", qUtf16Printable(actual.join("\n\t"_L1)));
+ });
+ QCOMPARE(actual, all);
+ reporter.dismiss();
+ }
+ {
+ // We also support joining with an underscore:
+ const QStringList actual = locale.uiLanguages(QLocale::TagSeparator::Underscore);
+ auto reporter = qScopeGuard([&actual]() {
+ qDebug("\n\t%ls", qUtf16Printable(actual.join("\n\t"_L1)));
+ });
+ QCOMPARE(actual, expected(u'_'));
+ reporter.dismiss();
+ }
+ {
+ // Or, in fact, any ASCII character:
+ const QStringList actual = locale.uiLanguages(QLocale::TagSeparator{'|'});
+ auto reporter = qScopeGuard([&actual]() {
+ qDebug("\n\t%ls", qUtf16Printable(actual.join("\n\t"_L1)));
+ });
+ QCOMPARE(actual, expected(u'|'));
+ reporter.dismiss();
+ }
+ {
+ // Non-ASCII separator (here, y-umlaut) is unsupported.
+ QTest::ignoreMessage(QtWarningMsg, "QLocale::uiLanguages(): "
+ "Using non-ASCII separator '\u00ff' (ff) is unsupported");
+ const QStringList actual = locale.uiLanguages(QLocale::TagSeparator{'\xff'});
+ auto reporter = qScopeGuard([&actual]() {
+ qDebug("\n\t%ls", qUtf16Printable(actual.join("\n\t"_L1)));
+ });
+ QCOMPARE(actual, QStringList{});
+ reporter.dismiss();
+ }
+}
+
+void tst_QLocale::weekendDays()
+{
+ const QLocale c(QLocale::C);
+ QList<Qt::DayOfWeek> days;
+ days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday;
+ QCOMPARE(c.weekdays(), days);
+}
+
+void tst_QLocale::listPatterns()
+{
+ QStringList sl1;
+ QStringList sl2;
+ sl2 << "aaa";
+ QStringList sl3;
+ sl3 << "aaa" << "bbb";
+ QStringList sl4;
+ sl4 << "aaa" << "bbb" << "ccc";
+ QStringList sl5;
+ sl5 << "aaa" << "bbb" << "ccc" << "ddd";
+
+ const QLocale c(QLocale::C);
+ QCOMPARE(c.createSeparatedList(sl1), QString(""));
+ QCOMPARE(c.createSeparatedList(sl2), QString("aaa"));
+ QCOMPARE(c.createSeparatedList(sl3), QString("aaa, bbb"));
+ QCOMPARE(c.createSeparatedList(sl4), QString("aaa, bbb, ccc"));
+ QCOMPARE(c.createSeparatedList(sl5), QString("aaa, bbb, ccc, ddd"));
+
+ const QLocale en_US("en_US");
+ QCOMPARE(en_US.createSeparatedList(sl1), QString(""));
+ QCOMPARE(en_US.createSeparatedList(sl2), QString("aaa"));
+ QCOMPARE(en_US.createSeparatedList(sl3), QString("aaa and bbb"));
+ QCOMPARE(en_US.createSeparatedList(sl4), QString("aaa, bbb, and ccc"));
+ QCOMPARE(en_US.createSeparatedList(sl5), QString("aaa, bbb, ccc, and ddd"));
+
+ const QLocale zh_CN("zh_CN");
+ QCOMPARE(zh_CN.createSeparatedList(sl1), QString(""));
+ QCOMPARE(zh_CN.createSeparatedList(sl2), QString("aaa"));
+ QCOMPARE(zh_CN.createSeparatedList(sl3), QString::fromUtf8("aaa" "\xe5\x92\x8c" "bbb"));
+ QCOMPARE(zh_CN.createSeparatedList(sl4),
+ QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe5\x92\x8c" "ccc"));
+ QCOMPARE(zh_CN.createSeparatedList(sl5),
+ QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81"
+ "ccc" "\xe5\x92\x8c" "ddd"));
+}
+
+void tst_QLocale::measurementSystems_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QLocale::MeasurementSystem>("system");
+ QTest::newRow("en_US") << QLocale(QLocale::English, QLocale::UnitedStates) << QLocale::ImperialUSSystem;
+ QTest::newRow("en_GB") << QLocale(QLocale::English, QLocale::UnitedKingdom) << QLocale::ImperialUKSystem;
+ QTest::newRow("en_AU") << QLocale(QLocale::English, QLocale::Australia) << QLocale::MetricSystem;
+ QTest::newRow("de") << QLocale(QLocale::German) << QLocale::MetricSystem;
+}
+
+void tst_QLocale::measurementSystems()
+{
+ QFETCH(QLocale, locale);
+ QTEST(locale.measurementSystem(), "system");
+}
+
+void tst_QLocale::QTBUG_26035_positivesign()
+{
+ QLocale locale(QLocale::C);
+ bool ok (false);
+ QCOMPARE(locale.toInt(QString("+100,000"), &ok), 100000);
+ QVERIFY(ok);
+ ok = false;
+ QCOMPARE(locale.toInt(QString("+100,000,000"), &ok), 100000000);
+ QVERIFY(ok);
+ ok = false;
+ QCOMPARE(locale.toLongLong(QString("+100,000"), &ok), (qlonglong)100000);
+ QVERIFY(ok);
+ ok = false;
+ QCOMPARE(locale.toLongLong(QString("+100,000,000"), &ok), (qlonglong)100000000);
+ QVERIFY(ok);
+}
+
+void tst_QLocale::textDirection_data()
+{
+ QTest::addColumn<int>("language");
+ QTest::addColumn<int>("script");
+ QTest::addColumn<bool>("rightToLeft");
+
+ for (int language = QLocale::C; language <= QLocale::LastLanguage; ++language) {
+ bool rightToLeft = false;
+ switch (language) {
+ // based on likelySubtags for RTL scripts
+ case QLocale::AncientGreek:
+ case QLocale::Arabic:
+ case QLocale::Aramaic:
+ case QLocale::Avestan:
+ case QLocale::Baluchi:
+ case QLocale::CentralKurdish:
+ case QLocale::Divehi:
+// case QLocale::Fulah:
+// case QLocale::Hausa:
+ case QLocale::Hebrew:
+// case QLocale::Hungarian:
+ case QLocale::Kashmiri:
+// case QLocale::Kurdish:
+ case QLocale::Mandingo:
+ case QLocale::Mazanderani:
+ case QLocale::Mende:
+ case QLocale::Nko:
+ case QLocale::NorthernLuri:
+ case QLocale::Pahlavi:
+ case QLocale::Pashto:
+ case QLocale::Persian:
+ case QLocale::Phoenician:
+ case QLocale::Sindhi:
+ case QLocale::SouthernKurdish:
+ case QLocale::Syriac:
+ case QLocale::Torwali:
+ case QLocale::Uighur:
+ case QLocale::Urdu:
+ case QLocale::WesternBalochi:
+ case QLocale::Yiddish:
+ // false if there is no locale data for language:
+ rightToLeft = (QLocale(QLocale::Language(language)).language()
+ == QLocale::Language(language));
+ break;
+ default:
+ break;
+ }
+ const QString testName = QLocale::languageToCode(QLocale::Language(language));
+ QTest::newRow(qPrintable(testName)) << language << int(QLocale::AnyScript) << rightToLeft;
+ }
+ QTest::newRow("pa_Arab") << int(QLocale::Punjabi) << int(QLocale::ArabicScript) << true;
+ QTest::newRow("uz_Arab") << int(QLocale::Uzbek) << int(QLocale::ArabicScript) << true;
+}
+
+void tst_QLocale::textDirection()
+{
+ QFETCH(int, language);
+ QFETCH(int, script);
+
+ QLocale locale(QLocale::Language(language), QLocale::Script(script), QLocale::AnyTerritory);
+ QTEST(locale.textDirection() == Qt::RightToLeft, "rightToLeft");
+}
+
+void tst_QLocale::formattedDataSize_data()
+{
+ QTest::addColumn<QLocale::Language>("language");
+ QTest::addColumn<int>("decimalPlaces");
+ QTest::addColumn<QLocale::DataSizeFormats>("units");
+ QTest::addColumn<int>("bytes");
+ QTest::addColumn<QString>("output");
+
+ struct {
+ const char *name;
+ QLocale::Language lang;
+ const char *bytes;
+ const char abbrev;
+ const char sep; // decimal separator
+ } data[] = {
+ { "English", QLocale::English, "bytes", 'B', '.' },
+ { "French", QLocale::French, "octets", 'o', ',' },
+ { "C", QLocale::C, "bytes", 'B', '.' }
+ };
+
+ for (const auto row : data) {
+#define ROWB(id, deci, num, text) \
+ QTest::addRow("%s-%s", row.name, id) \
+ << row.lang << deci << format \
+ << num << (QString(text) + QChar(' ') + QString(row.bytes))
+#define ROWQ(id, deci, num, head, tail) \
+ QTest::addRow("%s-%s", row.name, id) \
+ << row.lang << deci << format \
+ << num << (QString(head) + QChar(row.sep) + QString(tail) + QChar(row.abbrev))
+
+ // Metatype system fails to handle raw enum members as format; needs variable
+ {
+ const QLocale::DataSizeFormats format = QLocale::DataSizeIecFormat;
+ ROWB("IEC-0", 2, 0, "0");
+ ROWB("IEC-10", 2, 10, "10");
+ ROWQ("IEC-12Ki", 2, 12345, "12", "06 Ki");
+ ROWQ("IEC-16Ki", 2, 16384, "16", "00 Ki");
+ ROWQ("IEC-1235k", 2, 1234567, "1", "18 Mi");
+ ROWQ("IEC-1374k", 2, 1374744, "1", "31 Mi");
+ ROWQ("IEC-1234M", 2, 1234567890, "1", "15 Gi");
+ }
+ {
+ const QLocale::DataSizeFormats format = QLocale::DataSizeTraditionalFormat;
+ ROWB("Trad-0", 2, 0, "0");
+ ROWB("Trad-10", 2, 10, "10");
+ ROWQ("Trad-12Ki", 2, 12345, "12", "06 k");
+ ROWQ("Trad-16Ki", 2, 16384, "16", "00 k");
+ ROWQ("Trad-1235k", 2, 1234567, "1", "18 M");
+ ROWQ("Trad-1374k", 2, 1374744, "1", "31 M");
+ ROWQ("Trad-1234M", 2, 1234567890, "1", "15 G");
+ }
+ {
+ const QLocale::DataSizeFormats format = QLocale::DataSizeSIFormat;
+ ROWB("Decimal-0", 2, 0, "0");
+ ROWB("Decimal-10", 2, 10, "10");
+ ROWQ("Decimal-16Ki", 2, 16384, "16", "38 k");
+ ROWQ("Decimal-1234k", 2, 1234567, "1", "23 M");
+ ROWQ("Decimal-1374k", 2, 1374744, "1", "37 M");
+ ROWQ("Decimal-1234M", 2, 1234567890, "1", "23 G");
+ }
+#undef ROWQ
+#undef ROWB
+ }
+
+ // Languages which don't use a Latin alphabet
+
+ const QLocale::DataSizeFormats iecFormat = QLocale::DataSizeIecFormat;
+ const QLocale::DataSizeFormats traditionalFormat = QLocale::DataSizeTraditionalFormat;
+ const QLocale::DataSizeFormats siFormat = QLocale::DataSizeSIFormat;
+ const QLocale::Language lang = QLocale::Russian;
+
+ QTest::newRow("Russian-IEC-0") << lang << 2 << iecFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-IEC-10") << lang << 2 << iecFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
+ // CLDR doesn't provide IEC prefixes (yet?) so they aren't getting translated
+ QTest::newRow("Russian-IEC-12Ki") << lang << 2 << iecFormat << 12345 << QString("12,06 KiB");
+ QTest::newRow("Russian-IEC-16Ki") << lang << 2 << iecFormat << 16384 << QString("16,00 KiB");
+ QTest::newRow("Russian-IEC-1235k") << lang << 2 << iecFormat << 1234567 << QString("1,18 MiB");
+ QTest::newRow("Russian-IEC-1374k") << lang << 2 << iecFormat << 1374744 << QString("1,31 MiB");
+ QTest::newRow("Russian-IEC-1234M") << lang << 2 << iecFormat << 1234567890 << QString("1,15 GiB");
+
+ QTest::newRow("Russian-Trad-0") << lang << 2 << traditionalFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Trad-10") << lang << 2 << traditionalFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Trad-12Ki") << lang << 2 << traditionalFormat << 12345 << QString("12,06 \u043A\u0411");
+ QTest::newRow("Russian-Trad-16Ki") << lang << 2 << traditionalFormat << 16384 << QString("16,00 \u043A\u0411");
+ QTest::newRow("Russian-Trad-1235k") << lang << 2 << traditionalFormat << 1234567 << QString("1,18 \u041C\u0411");
+ QTest::newRow("Russian-Trad-1374k") << lang << 2 << traditionalFormat << 1374744 << QString("1,31 \u041C\u0411");
+ QTest::newRow("Russian-Trad-1234M") << lang << 2 << traditionalFormat << 1234567890 << QString("1,15 \u0413\u0411");
+
+ QTest::newRow("Russian-Decimal-0") << lang << 2 << siFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Decimal-10") << lang << 2 << siFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Decimal-16Ki") << lang << 2 << siFormat << 16384 << QString("16,38 \u043A\u0411");
+ QTest::newRow("Russian-Decimal-1234k") << lang << 2 << siFormat << 1234567 << QString("1,23 \u041C\u0411");
+ QTest::newRow("Russian-Decimal-1374k") << lang << 2 << siFormat << 1374744 << QString("1,37 \u041C\u0411");
+ QTest::newRow("Russian-Decimal-1234M") << lang << 2 << siFormat << 1234567890 << QString("1,23 \u0413\u0411");
+}
+
+void tst_QLocale::formattedDataSize()
+{
+ QFETCH(QLocale::Language, language);
+ QFETCH(int, decimalPlaces);
+ QFETCH(QLocale::DataSizeFormats, units);
+ QFETCH(int, bytes);
+
+ QTEST(QLocale(language).formattedDataSize(bytes, decimalPlaces, units), "output");
+}
+
+void tst_QLocale::bcp47Name_data()
+{
+ QTest::addColumn<QString>("expect");
+
+ QTest::newRow("C") << QStringLiteral("en");
+ QTest::newRow("en") << QStringLiteral("en");
+ QTest::newRow("en_US") << QStringLiteral("en");
+ QTest::newRow("en_GB") << QStringLiteral("en-GB");
+ QTest::newRow("en_DE") << QStringLiteral("en-DE");
+ QTest::newRow("de_DE") << QStringLiteral("de");
+ QTest::newRow("sr_RS") << QStringLiteral("sr");
+ QTest::newRow("sr_Cyrl_RS") << QStringLiteral("sr");
+ QTest::newRow("sr_Latn_RS") << QStringLiteral("sr-Latn");
+ QTest::newRow("sr_ME") << QStringLiteral("sr-ME");
+ QTest::newRow("sr_Cyrl_ME") << QStringLiteral("sr-Cyrl-ME");
+ QTest::newRow("sr_Latn_ME") << QStringLiteral("sr-ME");
+
+ // Fall back to defaults when country isn't in CLDR for this language:
+ QTest::newRow("sr_HR") << QStringLiteral("sr");
+ QTest::newRow("sr_Cyrl_HR") << QStringLiteral("sr");
+ QTest::newRow("sr_Latn_HR") << QStringLiteral("sr-Latn");
+}
+
+void tst_QLocale::bcp47Name()
+{
+ QFETCH(const QString, expect);
+ const auto expected = [expect](QChar ch) {
+ // Kludge around QString::replace() not being const.
+ QString copy = expect;
+ return copy.replace(u'-', ch);
+ };
+
+ const auto locale = QLocale(QLatin1String(QTest::currentDataTag()));
+ QCOMPARE(locale.bcp47Name(), expect);
+ QCOMPARE(locale.bcp47Name(QLocale::TagSeparator::Underscore), expected(u'_'));
+ QCOMPARE(locale.bcp47Name(QLocale::TagSeparator{'|'}), expected(u'|'));
+ QTest::ignoreMessage(QtWarningMsg, "QLocale::bcp47Name(): "
+ "Using non-ASCII separator '\u00ff' (ff) is unsupported");
+ QCOMPARE(locale.bcp47Name(QLocale::TagSeparator{'\xff'}), QString());
+ QT_TEST_EQUALITY_OPS(locale, QLocale(QLatin1String(QTest::currentDataTag())), true);
+}
+
+#ifndef QT_NO_SYSTEMLOCALE
+# ifdef QT_BUILD_INTERNAL
+class MySystemLocale : public QSystemLocale
+{
+ Q_DISABLE_COPY_MOVE(MySystemLocale)
+public:
+ MySystemLocale(const QString &locale)
+ : m_name(locale), m_id(QLocaleId::fromName(locale)), m_locale(locale)
+ {
+ }
+
+ QVariant query(QueryType type, QVariant &&/*in*/) const override
+ {
+ switch (type) {
+ case UILanguages:
+ if (m_name == u"en-DE") // QTBUG-104930: simulate macOS's list not including m_name.
+ return QVariant(QStringList{QStringLiteral("en-GB"), QStringLiteral("de-DE")});
+ return QVariant(QStringList{m_name});
+ case LanguageId:
+ return m_id.language_id;
+ case TerritoryId:
+ return m_id.territory_id;
+ case ScriptId:
+ return m_id.script_id;
+
+ default:
+ break;
+ }
+ return QVariant();
+ }
+
+ QLocale fallbackLocale() const override
+ {
+ return m_locale;
+ }
+
+private:
+ const QString m_name;
+ const QLocaleId m_id;
+ const QLocale m_locale;
+};
+
+void tst_QLocale::mySystemLocale_data()
+{
+ // Test uses MySystemLocale, so is platform-independent.
+ QTest::addColumn<QString>("name");
+ QTest::addColumn<QLocale::Language>("language");
+ QTest::addColumn<QStringList>("uiLanguages");
+
+ QTest::addRow("catalan")
+ << QString("ca") << QLocale::Catalan
+ << QStringList{QStringLiteral("ca"), QStringLiteral("ca-Latn-ES"), QStringLiteral("ca-ES")};
+ QTest::addRow("catalan-spain")
+ << QString("ca-ES") << QLocale::Catalan
+ << QStringList{QStringLiteral("ca-ES"), QStringLiteral("ca-Latn-ES"), QStringLiteral("ca")};
+ QTest::addRow("catalan-latin")
+ << QString("ca-Latn") << QLocale::Catalan
+ << QStringList{QStringLiteral("ca-Latn"), QStringLiteral("ca-Latn-ES"),
+ QStringLiteral("ca-ES"), QStringLiteral("ca")};
+ QTest::addRow("ukrainian")
+ << QString("uk") << QLocale::Ukrainian
+ << QStringList{QStringLiteral("uk"), QStringLiteral("uk-Cyrl-UA"), QStringLiteral("uk-UA")};
+ QTest::addRow("english-germany")
+ << QString("en-DE") << QLocale::English
+ // First two were missed out before fix to QTBUG-104930:
+ << QStringList{QStringLiteral("en-DE"), QStringLiteral("en-Latn-DE"),
+ QStringLiteral("en-GB"), QStringLiteral("en-Latn-GB"),
+ QStringLiteral("de-DE"), QStringLiteral("de-Latn-DE"), QStringLiteral("de")};
+ QTest::addRow("german")
+ << QString("de") << QLocale::German
+ << QStringList{QStringLiteral("de"), QStringLiteral("de-Latn-DE"), QStringLiteral("de-DE")};
+ QTest::addRow("german-britain")
+ << QString("de-GB") << QLocale::German
+ << QStringList{QStringLiteral("de-GB"), QStringLiteral("de-Latn-GB")};
+ QTest::addRow("chinese-min")
+ << QString("zh") << QLocale::Chinese
+ << QStringList{QStringLiteral("zh"), QStringLiteral("zh-Hans-CN"), QStringLiteral("zh-CN")};
+ QTest::addRow("chinese-full")
+ << QString("zh-Hans-CN") << QLocale::Chinese
+ << QStringList{QStringLiteral("zh-Hans-CN"), QStringLiteral("zh-CN"), QStringLiteral("zh")};
+
+ // For C, it should preserve what the system gave us but only add "C", never anything more:
+ QTest::addRow("C") << QString("C") << QLocale::C << QStringList{QStringLiteral("C")};
+ QTest::addRow("C-Latn")
+ << QString("C-Latn") << QLocale::C
+ << QStringList{QStringLiteral("C-Latn"), QStringLiteral("C")};
+ QTest::addRow("C-US")
+ << QString("C-US") << QLocale::C
+ << QStringList{QStringLiteral("C-US"), QStringLiteral("C")};
+ QTest::addRow("C-Latn-US")
+ << QString("C-Latn-US") << QLocale::C
+ << QStringList{QStringLiteral("C-Latn-US"), QStringLiteral("C")};
+ QTest::addRow("C-Hans")
+ << QString("C-Hans") << QLocale::C
+ << QStringList{QStringLiteral("C-Hans"), QStringLiteral("C")};
+ QTest::addRow("C-CN")
+ << QString("C-CN") << QLocale::C
+ << QStringList{QStringLiteral("C-CN"), QStringLiteral("C")};
+ QTest::addRow("C-Hans-CN")
+ << QString("C-Hans-CN") << QLocale::C
+ << QStringList{QStringLiteral("C-Hans-CN"), QStringLiteral("C")};
+
+ QTest::newRow("und-US")
+ << QString("und-US") << QLocale::C
+ << QStringList{QStringLiteral("und-US"), QStringLiteral("C")};
+
+ QTest::newRow("und-Latn")
+ << QString("und-Latn") << QLocale::C
+ << QStringList{QStringLiteral("und-Latn"), QStringLiteral("C")};
+
+ // TODO: test actual system backends correctly handle locales with
+ // script-specificity (script listed first is the default, in CLDR v40):
+ // az_{Latn,Cyrl}_AZ, bs_{Latn,Cyrl}_BA, sr_{Cyrl,Latn}_{BA,RS,XK,UZ},
+ // sr_{Latn,Cyrl}_ME, ff_{Latn,Adlm}_{BF,CM,GH,GM,GN,GW,LR,MR,NE,NG,SL,SN},
+ // shi_{Tfng,Latn}_MA, vai_{Vaii,Latn}_LR, zh_{Hant,Hans}_{MO,HK}
+}
+
+void tst_QLocale::mySystemLocale()
+{
+ // Compare uiLanguages(), which tests this for CLDR-derived locales.
+ QLocale originalLocale;
+ QLocale originalSystemLocale = QLocale::system();
+
+ QFETCH(QString, name);
+ QFETCH(QLocale::Language, language);
+ QFETCH(QStringList, uiLanguages);
+
+ {
+ MySystemLocale sLocale(name);
+ QCOMPARE(QLocale().language(), language);
+ QCOMPARE(QLocale::system().language(), language);
+ auto reporter = qScopeGuard([]() {
+ qDebug("\n\t%s", qPrintable(QLocale::system().uiLanguages().join(u"\n\t")));
+ });
+ QCOMPARE(QLocale::system().uiLanguages(), uiLanguages);
+ reporter.dismiss();
+ }
+
+ // Verify MySystemLocale tidy-up restored prior state:
+ QT_TEST_EQUALITY_OPS(QLocale(), originalLocale, true);
+ QT_TEST_EQUALITY_OPS(QLocale::system(), originalSystemLocale, true);
+}
+# endif // QT_BUILD_INTERNAL
+
+void tst_QLocale::systemLocaleDayAndMonthNames_data()
+{
+ QTest::addColumn<QByteArray>("locale");
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<QLocale::FormatType>("format");
+ QTest::addColumn<QString>("month");
+ QTest::addColumn<QString>("standaloneMonth");
+ QTest::addColumn<QString>("day");
+ QTest::addColumn<QString>("standaloneDay");
+
+ // en_US and de_DE locale outputs for ICU and macOS are similar.
+ // ru_RU are different.
+ // Windows has its own representation for all of the locales
+
+#if QT_CONFIG(icu)
+ // августа, август, понедельник, понедельник
+ QTest::newRow("ru_RU 30.08.2021 long")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442\u0430")
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a");
+ // авг., авг., пн, пн
+ QTest::newRow("ru_RU 30.08.2021 short")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << QString("\u0430\u0432\u0433.") << QString("\u0430\u0432\u0433.")
+ << QString("\u043f\u043d") << QString("\u043f\u043d");
+ // А, А, П, П
+ QTest::newRow("ru_RU 30.08.2021 narrow")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << QString("\u0410") << QString("\u0410") << QString("\u041f")
+ << QString("\u041f");
+#elif defined(Q_OS_DARWIN)
+ // августа, август, понедельник, понедельник
+ QTest::newRow("ru_RU 30.08.2021 long")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442\u0430")
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a");
+ // авг., авг., Пн, Пн
+ QTest::newRow("ru_RU 30.08.2021 short")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << QString("\u0430\u0432\u0433.") << QString("\u0430\u0432\u0433.")
+ << QString("\u041f\u043d") << QString("\u041f\u043d");
+ // А, А, Пн, П
+ QTest::newRow("ru_RU 30.08.2021 narrow")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << QString("\u0410") << QString("\u0410") << QString("\u041f\u043d")
+ << QString("\u041f");
+#endif
+
+#if QT_CONFIG(icu) || defined(Q_OS_DARWIN)
+ QTest::newRow("en_US 30.08.2021 long")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Monday" << "Monday";
+ QTest::newRow("en_US 30.08.2021 short")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug" << "Aug" << "Mon" << "Mon";
+ QTest::newRow("en_US 30.08.2021 narrow")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << "A" << "A" << "M" << "M";
+
+ QTest::newRow("de_DE 30.08.2021 long")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Montag" << "Montag";
+ QTest::newRow("de_DE 30.08.2021 short")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug." << "Aug" << "Mo." << "Mo";
+ QTest::newRow("de_DE 30.08.2021 narrow")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << "A" << "A" << "M" << "M";
+#elif defined(Q_OS_WIN)
+ // августа, Август, понедельник, понедельник
+ QTest::newRow("ru_RU 30.08.2021 long")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442\u0430")
+ << QString("\u0410\u0432\u0433\u0443\u0441\u0442")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a");
+ // авг, авг, Пн, пн
+ QTest::newRow("ru_RU 30.08.2021 short")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << QString("\u0430\u0432\u0433") << QString("\u0430\u0432\u0433")
+ << QString("\u041f\u043d") << QString("\u043f\u043d");
+ // А, А, Пн, П
+ QTest::newRow("ru_RU 30.08.2021 narrow")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << QString("\u0410") << QString("\u0410") << QString("\u041f\u043d")
+ << QString("\u041f");
+
+ QTest::newRow("en_US 30.08.2021 long")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Monday" << "Monday";
+ QTest::newRow("en_US 30.08.2021 short")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug" << "Aug" << "Mon" << "Mon";
+ QTest::newRow("en_US 30.08.2021 narrow")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << "A" << "A" << "Mo" << "M";
+
+ QTest::newRow("de_DE 30.08.2021 long")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Montag" << "Montag";
+ QTest::newRow("de_DE 30.08.2021 short")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug" << "Aug" << "Mo" << "Mo";
+ QTest::newRow("de_DE 30.08.2021 narrow")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::NarrowFormat
+ << "A" << "A" << "Mo" << "M";
+#else
+ QSKIP("This test can't run on this OS");
+#endif
+}
+
+void tst_QLocale::systemLocaleDayAndMonthNames()
+{
+ QFETCH(QByteArray, locale);
+ QFETCH(QDate, date);
+ QFETCH(QLocale::FormatType, format);
+ locale += ".UTF-8"; // So we don't have to repeat it on every data row !
+
+ const TransientLocale tested(LC_ALL, locale.constData());
+
+ QLocale sys = QLocale::system();
+#if !QT_CONFIG(icu)
+ // setlocale() does not really change locale on Windows and macOS, we
+ // need to actually set the locale manually to run the test
+ if (!locale.startsWith(sys.name().toUtf8()))
+ QSKIP(("Set locale to " + locale + " manually to run this test.").constData());
+#endif
+
+ const int m = date.month();
+ QTEST(sys.monthName(m, format), "month");
+ QTEST(sys.standaloneMonthName(m, format), "standaloneMonth");
+
+ const int d = date.dayOfWeek();
+ QTEST(sys.dayName(d, format), "day");
+ QTEST(sys.standaloneDayName(d, format), "standaloneDay");
+}
+
+#endif // QT_NO_SYSTEMLOCALE
+
+void tst_QLocale::numberGrouping_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<int>("number");
+ QTest::addColumn<QString>("string");
+ // Number options set here are expected to be default, but set for the
+ // avoidance of uncertainty or susceptibility to changed defaults.
+
+ QLocale c(QLocale::C); // English-style, without separators.
+ c.setNumberOptions(c.numberOptions() | QLocale::OmitGroupSeparator);
+ QTest::newRow("c:1") << c << 1 << u"1"_s;
+ QTest::newRow("c:12") << c << 12 << u"12"_s;
+ QTest::newRow("c:123") << c << 123 << u"123"_s;
+ QTest::newRow("c:1234") << c << 1234 << u"1234"_s;
+ QTest::newRow("c:12345") << c << 12345 << u"12345"_s;
+ QTest::newRow("c:123456") << c << 123456 << u"123456"_s;
+ QTest::newRow("c:1234567") << c << 1234567 << u"1234567"_s;
+ QTest::newRow("c:12345678") << c << 12345678 << u"12345678"_s;
+ QTest::newRow("c:123456789") << c << 123456789 << u"123456789"_s;
+ QTest::newRow("c:1234567890") << c << 1234567890 << u"1234567890"_s;
+
+ QLocale en(QLocale::English); // English-style, with separators:
+ en.setNumberOptions(en.numberOptions() & ~QLocale::OmitGroupSeparator);
+ QTest::newRow("en:1") << en << 1 << u"1"_s;
+ QTest::newRow("en:12") << en << 12 << u"12"_s;
+ QTest::newRow("en:123") << en << 123 << u"123"_s;
+ QTest::newRow("en:1,234") << en << 1234 << u"1,234"_s;
+ QTest::newRow("en:12,345") << en << 12345 << u"12,345"_s;
+ QTest::newRow("en:123,456") << en << 123456 << u"123,456"_s;
+ QTest::newRow("en:1,234,567") << en << 1234567 << u"1,234,567"_s;
+ QTest::newRow("en:12,345,678") << en << 12345678 << u"12,345,678"_s;
+ QTest::newRow("en:123,456,789") << en << 123456789 << u"123,456,789"_s;
+ QTest::newRow("en:1,234,567,890") << en << 1234567890 << u"1,234,567,890"_s;
+
+ QLocale es(QLocale::Spanish); // Spanish-style, with separators
+ es.setNumberOptions(es.numberOptions() & ~QLocale::OmitGroupSeparator);
+ QTest::newRow("es:1") << es << 1 << u"1"_s;
+ QTest::newRow("es:12") << es << 12 << u"12"_s;
+ QTest::newRow("es:123") << es << 123 << u"123"_s;
+ // First split doesn't happen unless first group has at least two digits:
+ QTest::newRow("es:1234") << es << 1234 << u"1234"_s;
+ QTest::newRow("es:12.345") << es << 12345 << u"12.345"_s;
+ QTest::newRow("es:123.456") << es << 123456 << u"123.456"_s;
+ // Later splits aren't limited to two digits (QTBUG-115740):
+ QTest::newRow("es:1.234.567") << es << 1234567 << u"1.234.567"_s;
+ QTest::newRow("es:12.345.678") << es << 12345678 << u"12.345.678"_s;
+ QTest::newRow("es:123.456.789") << es << 123456789 << u"123.456.789"_s;
+ QTest::newRow("es:1.234.567.890") << es << 1234567890 << u"1.234.567.890"_s;
+
+ QLocale hi(QLocale::Hindi, QLocale::India);
+ hi.setNumberOptions(hi.numberOptions() & ~QLocale::OmitGroupSeparator);
+ QTest::newRow("hi:1") << hi << 1 << u"1"_s;
+ QTest::newRow("hi:12") << hi << 12 << u"12"_s;
+ QTest::newRow("hi:123") << hi << 123 << u"123"_s;
+ QTest::newRow("hi:1,234") << hi << 1234 << u"1,234"_s;
+ QTest::newRow("hi:12,345") << hi << 12345 << u"12,345"_s;
+ QTest::newRow("hi:1,23,456") << hi << 123456 << u"1,23,456"_s;
+ QTest::newRow("hi:12,34,567") << hi << 1234567 << u"12,34,567"_s;
+ QTest::newRow("hi:1,23,45,678") << hi << 12345678 << u"1,23,45,678"_s;
+ QTest::newRow("hi:12,34,56,789") << hi << 123456789 << u"12,34,56,789"_s;
+ QTest::newRow("hi:1,23,45,67,890") << hi << 1234567890 << u"1,23,45,67,890"_s;
+}
+
+void tst_QLocale::numberGrouping()
+{
+ QFETCH(const QLocale, locale);
+ QFETCH(const int, number);
+ QFETCH(const QString, string);
+
+ QCOMPARE(locale.toString(number), string);
+ QLocale sys = QLocale::system();
+ if (sys.language() == locale.language()
+ && sys.script() == locale.script()
+ && sys.territory() == locale.territory()) {
+ sys.setNumberOptions(locale.numberOptions());
+
+ QCOMPARE(sys.toString(number), string);
+ if (QLocale() == sys) { // This normally should be the case.
+ QCOMPARE(u"%L1"_s.arg(number), string);
+ QCOMPARE(u"%L1"_s.arg(double(number), 0, 'f', 0), string);
+ }
+ }
+}
+
+void tst_QLocale::numberGroupingIndia()
+{
+ const QLocale indian(QLocale::Hindi, QLocale::India);
+
+ // A 7-bit value (fits in signed 8-bit):
+ const QString strResult8("120");
+ const qint8 int8 = 120;
+ QCOMPARE(indian.toString(int8), strResult8);
+ QCOMPARE(indian.toShort(strResult8), short(int8));
+
+ const quint8 uint8 = 120u;
+ QCOMPARE(indian.toString(uint8), strResult8);
+ QCOMPARE(indian.toShort(strResult8), short(uint8));
+
+ // Boundary case for needing a first separator:
+ const QString strResultSep("3,210");
+ const short shortSep = 3210;
+ QCOMPARE(indian.toString(shortSep), strResultSep);
+ QCOMPARE(indian.toShort(strResultSep), shortSep);
+
+ const ushort uShortSep = 3210u;
+ QCOMPARE(indian.toString(uShortSep), strResultSep);
+ QCOMPARE(indian.toUShort(strResultSep), uShortSep);
+
+ // 15-bit:
+ const QString strResult16("24,310");
+ const short short16 = 24310;
+ QCOMPARE(indian.toString(short16), strResult16);
+ QCOMPARE(indian.toShort(strResult16), short16);
+
+ const ushort uShort16 = 24310u;
+ QCOMPARE(indian.toString(uShort16), strResult16);
+ QCOMPARE(indian.toUShort(strResult16), uShort16);
+
+ // 31-bit
+ const QString strResult32("2,03,04,05,010");
+ const int integer32 = 2030405010;
+ QCOMPARE(indian.toString(integer32), strResult32);
+ QCOMPARE(indian.toInt(strResult32), integer32);
+
+ const uint uInteger32 = 2030405010u;
+ QCOMPARE(indian.toString(uInteger32), strResult32);
+ QCOMPARE(indian.toUInt(strResult32), uInteger32);
+
+ // 63-bit:
+ const QString strResult64("60,05,00,40,03,00,20,01,000");
+ const qint64 int64 = Q_INT64_C(6005004003002001000);
+ QCOMPARE(indian.toString(int64), strResult64);
+ QCOMPARE(indian.toLongLong(strResult64), int64);
+
+ const quint64 uint64 = Q_UINT64_C(6005004003002001000);
+ QCOMPARE(indian.toString(uint64), strResult64);
+ QCOMPARE(indian.toULongLong(strResult64), uint64);
+}
+
+void tst_QLocale::numberFormatChakma()
+{
+ const QLocale chakma(QLocale::Chakma, QLocale::ChakmaScript, QLocale::Bangladesh);
+ const uint zeroVal = 0x11136; // Unicode's representation of Chakma zero
+ const QChar data[] = {
+ QChar::highSurrogate(zeroVal), QChar::lowSurrogate(zeroVal),
+ QChar::highSurrogate(zeroVal + 1), QChar::lowSurrogate(zeroVal + 1),
+ QChar::highSurrogate(zeroVal + 2), QChar::lowSurrogate(zeroVal + 2),
+ QChar::highSurrogate(zeroVal + 3), QChar::lowSurrogate(zeroVal + 3),
+ QChar::highSurrogate(zeroVal + 4), QChar::lowSurrogate(zeroVal + 4),
+ QChar::highSurrogate(zeroVal + 5), QChar::lowSurrogate(zeroVal + 5),
+ QChar::highSurrogate(zeroVal + 6), QChar::lowSurrogate(zeroVal + 6),
+ };
+ const QChar separator(QLatin1Char(','));
+ const QString
+ zero = QString::fromRawData(data, 2),
+ one = QString::fromRawData(data + 2, 2),
+ two = QString::fromRawData(data + 4, 2),
+ three = QString::fromRawData(data + 6, 2),
+ four = QString::fromRawData(data + 8, 2),
+ five = QString::fromRawData(data + 10, 2),
+ six = QString::fromRawData(data + 12, 2);
+
+ // A 7-bit value (fits in signed 8-bit):
+ const QString strResult8 = one + two + zero;
+ const qint8 int8 = 120;
+ QCOMPARE(chakma.toString(int8), strResult8);
+ QCOMPARE(chakma.toShort(strResult8), short(int8));
+
+ const quint8 uint8 = 120;
+ QCOMPARE(chakma.toString(uint8), strResult8);
+ QCOMPARE(chakma.toShort(strResult8), short(uint8));
+
+ // Boundary case for needing a first separator:
+ const QString strResultSep = three + separator + two + one + zero;
+ const short shortSep = 3210;
+ QCOMPARE(chakma.toString(shortSep), strResultSep);
+ QCOMPARE(chakma.toShort(strResultSep), shortSep);
+
+ const ushort uShortSep = 3210u;
+ QCOMPARE(chakma.toString(uShortSep), strResultSep);
+ QCOMPARE(chakma.toUShort(strResultSep), uShortSep);
+
+ // Fifteen-bit value:
+ const QString strResult16 = two + four + separator + three + one + zero;
+ const short short16 = 24310;
+ QCOMPARE(chakma.toString(short16), strResult16);
+ QCOMPARE(chakma.toShort(strResult16), short16);
+
+ const ushort uShort16 = 24310u;
+ QCOMPARE(chakma.toString(uShort16), strResult16);
+ QCOMPARE(chakma.toUShort(strResult16), uShort16);
+
+ // 31-bit
+ const QString strResult32 =
+ two + separator + zero + three + separator + zero + four
+ + separator + zero + five + separator + zero + one + zero;
+ const int integer32 = 2030405010;
+ QCOMPARE(chakma.toString(integer32), strResult32);
+ QCOMPARE(chakma.toInt(strResult32), integer32);
+
+ const uint uInteger32 = 2030405010u;
+ QCOMPARE(chakma.toString(uInteger32), strResult32);
+ QCOMPARE(chakma.toUInt(strResult32), uInteger32);
+
+ // 63-bit:
+ const QString strResult64 =
+ six + zero + separator + zero + five + separator + zero + zero + separator
+ + four + zero + separator + zero + three + separator + zero + zero + separator
+ + two + zero + separator + zero + one + separator + zero + zero + zero;
+ const qint64 int64 = Q_INT64_C(6005004003002001000);
+ QCOMPARE(chakma.toString(int64), strResult64);
+ QCOMPARE(chakma.toLongLong(strResult64), int64);
+
+ const quint64 uint64 = Q_UINT64_C(6005004003002001000);
+ QCOMPARE(chakma.toString(uint64), strResult64);
+ QCOMPARE(chakma.toULongLong(strResult64), uint64);
+}
+
+void tst_QLocale::lcsToCode()
+{
+ QCOMPARE(QLocale::languageToCode(QLocale::AnyLanguage), QString());
+ QCOMPARE(QLocale::languageToCode(QLocale::C), QString("C"));
+ QCOMPARE(QLocale::languageToCode(QLocale::English), QString("en"));
+ QCOMPARE(QLocale::languageToCode(QLocale::Albanian), u"sq"_s);
+ QCOMPARE(QLocale::languageToCode(QLocale::Albanian, QLocale::ISO639Part1), u"sq"_s);
+ QCOMPARE(QLocale::languageToCode(QLocale::Albanian, QLocale::ISO639Part2B), u"alb"_s);
+ QCOMPARE(QLocale::languageToCode(QLocale::Albanian, QLocale::ISO639Part2T), u"sqi"_s);
+ QCOMPARE(QLocale::languageToCode(QLocale::Albanian, QLocale::ISO639Part3), u"sqi"_s);
+
+ QCOMPARE(QLocale::languageToCode(QLocale::Taita), u"dav"_s);
+ QCOMPARE(QLocale::languageToCode(QLocale::Taita,
+ QLocale::ISO639Part1 | QLocale::ISO639Part2B
+ | QLocale::ISO639Part2T),
+ QString());
+ QCOMPARE(QLocale::languageToCode(QLocale::Taita, QLocale::ISO639Part3), u"dav"_s);
+ QCOMPARE(QLocale::languageToCode(QLocale::English, QLocale::LanguageCodeTypes {}), QString());
+
+ // Legacy codes can only be used to convert them to Language values, not other way around.
+ QCOMPARE(QLocale::languageToCode(QLocale::NorwegianBokmal, QLocale::LegacyLanguageCode),
+ QString());
+
+ QCOMPARE(QLocale::territoryToCode(QLocale::AnyTerritory), QString());
+ QCOMPARE(QLocale::territoryToCode(QLocale::UnitedStates), QString("US"));
+ QCOMPARE(QLocale::territoryToCode(QLocale::EuropeanUnion), QString("EU"));
+
+ QCOMPARE(QLocale::scriptToCode(QLocale::AnyScript), QString());
+ QCOMPARE(QLocale::scriptToCode(QLocale::SimplifiedHanScript), QString("Hans"));
+}
+
+void tst_QLocale::codeToLcs()
+{
+ QCOMPARE(QLocale::codeToLanguage(QString()), QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(QString(" ")), QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(QString("und")), QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(QString("e")), QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(QString("en")), QLocale::English);
+ QCOMPARE(QLocale::codeToLanguage(QString("EN")), QLocale::English);
+ QCOMPARE(QLocale::codeToLanguage(QString("eng")), QLocale::English);
+ QCOMPARE(QLocale::codeToLanguage(QString("ha")), QLocale::Hausa);
+ QCOMPARE(QLocale::codeToLanguage(QString("ha"), QLocale::ISO639Alpha3), QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(QString("haw")), QLocale::Hawaiian);
+ QCOMPARE(QLocale::codeToLanguage(QString("haw"), QLocale::ISO639Alpha2), QLocale::AnyLanguage);
+
+ QCOMPARE(QLocale::codeToLanguage(u"sq"), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"alb"), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"sqi"), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"sq", QLocale::ISO639Part1), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"sq", QLocale::ISO639Part3), QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(u"alb", QLocale::ISO639Part2B), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"alb", QLocale::ISO639Part2T | QLocale::ISO639Part3),
+ QLocale::AnyLanguage);
+ QCOMPARE(QLocale::codeToLanguage(u"sqi", QLocale::ISO639Part2T), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"sqi", QLocale::ISO639Part3), QLocale::Albanian);
+ QCOMPARE(QLocale::codeToLanguage(u"sqi", QLocale::ISO639Part1 | QLocale::ISO639Part2B),
+ QLocale::AnyLanguage);
+
+ // Legacy code
+ QCOMPARE(QLocale::codeToLanguage(u"no"), QLocale::NorwegianBokmal);
+ QCOMPARE(QLocale::codeToLanguage(u"no", QLocale::ISO639Part1), QLocale::AnyLanguage);
+
+ QCOMPARE(QLocale::codeToTerritory(QString()), QLocale::AnyTerritory);
+ QCOMPARE(QLocale::codeToTerritory(QString("ZZ")), QLocale::AnyTerritory);
+ QCOMPARE(QLocale::codeToTerritory(QString("US")), QLocale::UnitedStates);
+ QCOMPARE(QLocale::codeToTerritory(QString("us")), QLocale::UnitedStates);
+ QCOMPARE(QLocale::codeToTerritory(QString("USA")), QLocale::AnyTerritory);
+ QCOMPARE(QLocale::codeToTerritory(QString("EU")), QLocale::EuropeanUnion);
+ QCOMPARE(QLocale::codeToTerritory(QString("001")), QLocale::World);
+ QCOMPARE(QLocale::codeToTerritory(QString("150")), QLocale::Europe);
+
+ QCOMPARE(QLocale::codeToScript(QString()), QLocale::AnyScript);
+ QCOMPARE(QLocale::codeToScript(QString("Zzzz")), QLocale::AnyScript);
+ QCOMPARE(QLocale::codeToScript(QString("Hans")), QLocale::SimplifiedHanScript);
+}
+
+QTEST_MAIN(tst_QLocale)
+#include "tst_qlocale.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/.gitignore b/tests/auto/corelib/text/qregularexpression/.gitignore
index 4650b4454e..4650b4454e 100644
--- a/tests/auto/corelib/tools/qregularexpression/.gitignore
+++ b/tests/auto/corelib/text/qregularexpression/.gitignore
diff --git a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt
new file mode 100644
index 0000000000..b1d3ed0a8d
--- /dev/null
+++ b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qregularexpression Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qregularexpression LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qregularexpression
+ SOURCES
+ tst_qregularexpression.cpp
+)
diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
new file mode 100644
index 0000000000..72c49d2a9c
--- /dev/null
+++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
@@ -0,0 +1,2579 @@
+// Copyright (C) 2015 Giuseppe D'Angelo <dangelog@gmail.com>.
+// Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qstring.h>
+#include <qlist.h>
+#include <qstringlist.h>
+#include <qhash.h>
+
+#include <qobject.h>
+#include <qregularexpression.h>
+#include <qthread.h>
+
+#include <iostream>
+#include <optional>
+
+Q_DECLARE_METATYPE(QRegularExpression::PatternOptions)
+Q_DECLARE_METATYPE(QRegularExpression::MatchType)
+Q_DECLARE_METATYPE(QRegularExpression::MatchOptions)
+
+class tst_QRegularExpression : public QObject
+{
+ Q_OBJECT
+
+public:
+ static void initMain();
+
+private slots:
+ void defaultConstructors();
+ void moveSemantics();
+ void moveSemanticsMatch();
+ void moveSemanticsMatchIterator();
+ void gettersSetters_data();
+ void gettersSetters();
+ void escape_data();
+ void escape();
+ void validity_data();
+ void validity();
+ void patternOptions_data();
+ void patternOptions();
+ void normalMatch_data();
+ void normalMatch();
+ void partialMatch_data();
+ void partialMatch();
+ void globalMatch_data();
+ void globalMatch();
+ void serialize_data();
+ void serialize();
+ void operatoreq_data();
+ void operatoreq();
+ void captureCount_data();
+ void captureCount();
+ void captureNames_data();
+ void captureNames();
+ void captureNamesNul();
+ void pcreJitStackUsage_data();
+ void pcreJitStackUsage();
+ void regularExpressionMatch_data();
+ void regularExpressionMatch();
+ void JOptionUsage_data();
+ void JOptionUsage();
+ void QStringAndQStringViewEquivalence();
+ void threadSafety_data();
+ void threadSafety();
+
+ void returnsViewsIntoOriginalString();
+ void wildcard_data();
+ void wildcard();
+ void testInvalidWildcard_data();
+ void testInvalidWildcard();
+
+private:
+ void provideRegularExpressions();
+};
+
+using CapturedList = QVector<std::optional<QString>>;
+
+struct Match
+{
+ Match()
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ isValid = false;
+ hasMatch = false;
+ hasPartialMatch = false;
+ captured.clear();
+ namedCaptured.clear();
+ }
+
+ bool isValid;
+ bool hasMatch;
+ bool hasPartialMatch;
+ CapturedList captured;
+ QHash<QString, std::optional<QString>> namedCaptured;
+};
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(Match, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Match)
+
+bool operator==(const QRegularExpressionMatch &rem, const Match &m)
+{
+ if (rem.isValid() != m.isValid)
+ return false;
+ if (!rem.isValid())
+ return true;
+ if ((rem.hasMatch() != m.hasMatch) || (rem.hasPartialMatch() != m.hasPartialMatch))
+ return false;
+ if (rem.hasMatch() || rem.hasPartialMatch()) {
+ if (!rem.hasCaptured(0))
+ return false;
+ if (rem.lastCapturedIndex() != (m.captured.size() - 1))
+ return false;
+ for (int i = 0; i <= rem.lastCapturedIndex(); ++i) {
+ auto mMaybeCaptured = m.captured.at(i);
+ QString remCaptured = rem.captured(i);
+ if (!mMaybeCaptured) {
+ if (rem.hasCaptured(i))
+ return false;
+ if (!remCaptured.isNull())
+ return false;
+ } else {
+ if (!rem.hasCaptured(i))
+ return false;
+ QString mCaptured = *mMaybeCaptured;
+ if (remCaptured != mCaptured
+ || remCaptured.isNull() != mCaptured.isNull()
+ || remCaptured.isEmpty() != mCaptured.isEmpty()) {
+ return false;
+ }
+ }
+ }
+
+ for (auto it = m.namedCaptured.begin(), end = m.namedCaptured.end(); it != end; ++it) {
+ const QString capturedGroupName = it.key();
+ const QString remCaptured = rem.captured(capturedGroupName);
+ const auto mMaybeCaptured = it.value();
+ if (!mMaybeCaptured) {
+ if (rem.hasCaptured(capturedGroupName))
+ return false;
+ if (!remCaptured.isNull())
+ return false;
+ } else {
+ if (!rem.hasCaptured(capturedGroupName))
+ return false;
+ const auto mCaptured = *mMaybeCaptured;
+ if (remCaptured != mCaptured
+ || remCaptured.isNull() != mCaptured.isNull()
+ || remCaptured.isEmpty() != mCaptured.isEmpty()) {
+ return false;
+ }
+ }
+ }
+ } else {
+ if (rem.hasCaptured(0))
+ return false;
+ }
+
+ return true;
+}
+
+bool operator==(const Match &m, const QRegularExpressionMatch &rem)
+{
+ return operator==(rem, m);
+}
+
+bool operator!=(const QRegularExpressionMatch &rem, const Match &m)
+{
+ return !operator==(rem, m);
+}
+
+bool operator!=(const Match &m, const QRegularExpressionMatch &rem)
+{
+ return !operator==(m, rem);
+}
+
+
+bool operator==(const QRegularExpressionMatchIterator &iterator, const QList<Match> &expectedMatchList)
+{
+ QRegularExpressionMatchIterator i = iterator;
+
+ for (const Match &expectedMatch : expectedMatchList) {
+ if (!i.hasNext())
+ return false;
+
+ QRegularExpressionMatch match = i.next();
+ if (match != expectedMatch)
+ return false;
+ }
+
+ if (i.hasNext())
+ return false;
+
+ i = iterator;
+
+ int index = 0;
+ for (const QRegularExpressionMatch &match : i) {
+ if (match != expectedMatchList[index++])
+ return false;
+ }
+
+ if (index != expectedMatchList.size())
+ return false;
+
+ // do it again
+ index = 0;
+ for (const QRegularExpressionMatch &match : i) {
+ if (match != expectedMatchList[index++])
+ return false;
+ }
+
+ if (index != expectedMatchList.size())
+ return false;
+
+ return true;
+}
+
+bool operator==(const QList<Match> &expectedMatchList, const QRegularExpressionMatchIterator &iterator)
+{
+ return operator==(iterator, expectedMatchList);
+}
+
+bool operator!=(const QRegularExpressionMatchIterator &iterator, const QList<Match> &expectedMatchList)
+{
+ return !operator==(iterator, expectedMatchList);
+}
+
+bool operator!=(const QList<Match> &expectedMatchList, const QRegularExpressionMatchIterator &iterator)
+{
+ return !operator==(expectedMatchList, iterator);
+}
+
+void consistencyCheck(const QRegularExpressionMatch &match)
+{
+ if (match.isValid()) {
+ QVERIFY(match.regularExpression().isValid());
+ QVERIFY(!(match.hasMatch() && match.hasPartialMatch()));
+
+ if (match.hasMatch() || match.hasPartialMatch()) {
+ QVERIFY(match.lastCapturedIndex() >= 0);
+ if (match.hasPartialMatch())
+ QVERIFY(match.lastCapturedIndex() == 0);
+
+ for (int i = 0; i <= match.lastCapturedIndex(); ++i) {
+ qsizetype startPos = match.capturedStart(i);
+ qsizetype endPos = match.capturedEnd(i);
+ qsizetype length = match.capturedLength(i);
+ QString captured = match.captured(i);
+ QStringView capturedView = match.capturedView(i);
+
+ if (!captured.isNull()) {
+ QVERIFY(startPos >= 0);
+ QVERIFY(endPos >= 0);
+ QVERIFY(length >= 0);
+ QVERIFY(endPos >= startPos);
+ QVERIFY((endPos - startPos) == length);
+ QVERIFY(captured == capturedView);
+ } else {
+ // A null capture can either mean no capture at all,
+ // or capture of length 0 over a null subject.
+ QVERIFY(startPos == endPos);
+ QVERIFY(((startPos == -1) && (endPos == -1)) // no capture
+ || ((startPos == 0) && (endPos == 0))); // null subject
+ QVERIFY((endPos - startPos) == length);
+ QVERIFY(capturedView.isNull());
+ }
+ }
+ }
+ } else {
+ QVERIFY(!match.hasMatch());
+ QVERIFY(!match.hasPartialMatch());
+ QVERIFY(match.captured(0).isNull());
+ QVERIFY(match.capturedStart(0) == -1);
+ QVERIFY(match.capturedEnd(0) == -1);
+ QVERIFY(match.capturedLength(0) == 0);
+ }
+}
+
+void consistencyCheck(const QRegularExpressionMatchIterator &iterator)
+{
+ QRegularExpressionMatchIterator i(iterator); // make a copy, we modify it
+ if (i.isValid()) {
+ while (i.hasNext()) {
+ QRegularExpressionMatch peeked = i.peekNext();
+ QRegularExpressionMatch match = i.next();
+ consistencyCheck(peeked);
+ if (QTest::currentTestFailed())
+ return;
+ consistencyCheck(match);
+ if (QTest::currentTestFailed())
+ return;
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch() || match.hasPartialMatch());
+ QCOMPARE(i.regularExpression(), match.regularExpression());
+ QCOMPARE(i.matchOptions(), match.matchOptions());
+ QCOMPARE(i.matchType(), match.matchType());
+
+ QVERIFY(peeked.isValid() == match.isValid());
+ QVERIFY(peeked.hasMatch() == match.hasMatch());
+ QVERIFY(peeked.hasPartialMatch() == match.hasPartialMatch());
+ QVERIFY(peeked.lastCapturedIndex() == match.lastCapturedIndex());
+ for (int i = 0; i <= peeked.lastCapturedIndex(); ++i) {
+ QVERIFY(peeked.captured(i) == match.captured(i));
+ QVERIFY(peeked.capturedStart(i) == match.capturedStart(i));
+ QVERIFY(peeked.capturedEnd(i) == match.capturedEnd(i));
+ }
+ }
+ } else {
+ QVERIFY(!i.hasNext());
+ QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatchIterator::peekNext() called on an iterator already at end");
+ QRegularExpressionMatch peeked = i.peekNext();
+ QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatchIterator::next() called on an iterator already at end");
+ QRegularExpressionMatch match = i.next();
+ consistencyCheck(peeked);
+ consistencyCheck(match);
+ QVERIFY(!match.isValid());
+ QVERIFY(!peeked.isValid());
+ }
+
+}
+
+template<typename Result>
+static void prepareResultForNoMatchType(Result *r, const Result &orig)
+{
+ Q_UNUSED(r);
+ Q_UNUSED(orig);
+}
+
+static void prepareResultForNoMatchType(Match *m, const Match &orig)
+{
+ m->isValid = orig.isValid;
+}
+
+template<typename QREMatch, typename QREMatchFunc, typename Subject, typename Result>
+static void testMatchImpl(const QRegularExpression &regexp,
+ QREMatchFunc matchingMethod,
+ const Subject &subject,
+ qsizetype offset,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ const Result &result)
+{
+ {
+ const QREMatch m = (regexp.*matchingMethod)(subject, offset, matchType, matchOptions);
+ consistencyCheck(m);
+ QVERIFY(m == result);
+ QCOMPARE(m.regularExpression(), regexp);
+ QCOMPARE(m.matchType(), matchType);
+ QCOMPARE(m.matchOptions(), matchOptions);
+ }
+ {
+ // ignore the expected results provided by the match object --
+ // we'll never get any result when testing the NoMatch type.
+ // Just check the validity of the match here.
+ Result realMatch;
+ prepareResultForNoMatchType(&realMatch, result);
+
+ const QREMatch m = (regexp.*matchingMethod)(subject, offset, QRegularExpression::NoMatch, matchOptions);
+ consistencyCheck(m);
+ QVERIFY(m == realMatch);
+ QCOMPARE(m.regularExpression(), regexp);
+ QCOMPARE(m.matchType(), QRegularExpression::NoMatch);
+ QCOMPARE(m.matchOptions(), matchOptions);
+ }
+}
+
+template<typename QREMatch, typename QREMatchFuncForString, typename QREMatchFuncForStringRef, typename Result>
+static void testMatch(const QRegularExpression &regexp,
+ QREMatchFuncForString matchingMethodForString,
+ QREMatchFuncForStringRef matchingMethodForStringRef,
+ const QString &subject,
+ qsizetype offset,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ const Result &result)
+{
+ // test with QString as subject type
+ testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result);
+
+ // test with QStringView as subject type
+ testMatchImpl<QREMatch>(regexp,
+ matchingMethodForStringRef,
+ QStringView(subject),
+ offset,
+ matchType,
+ matchOptions,
+ result);
+}
+
+// ### Qt 7: there should no longer be the need for these
+typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringPMF)(const QString &, qsizetype, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
+typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringViewPMF)(QStringView, qsizetype, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
+typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringPMF)(const QString &, qsizetype, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
+typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringViewPMF)(QStringView, qsizetype, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
+
+void tst_QRegularExpression::provideRegularExpressions()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QRegularExpression::PatternOptions>("patternOptions");
+
+ QTest::newRow("emptynull01") << QString()
+ << QRegularExpression::PatternOptions{};
+ QTest::newRow("emptynull02") << QString()
+ << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
+ | QRegularExpression::DotMatchesEverythingOption
+ | QRegularExpression::MultilineOption);
+ QTest::newRow("emptynull03") << ""
+ << QRegularExpression::PatternOptions{};
+ QTest::newRow("emptynull04") << ""
+ << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
+ | QRegularExpression::DotMatchesEverythingOption
+ | QRegularExpression::MultilineOption);
+
+ QTest::newRow("regexp01") << "a pattern"
+ << QRegularExpression::PatternOptions{};
+ QTest::newRow("regexp02") << "^a (.*) more complicated(?<P>pattern)$"
+ << QRegularExpression::PatternOptions{};
+ QTest::newRow("regexp03") << "(?:a) pAttErN"
+ << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption);
+ QTest::newRow("regexp04") << "a\nmultiline\npattern"
+ << QRegularExpression::PatternOptions(QRegularExpression::MultilineOption);
+ QTest::newRow("regexp05") << "an extended # IGNOREME\npattern"
+ << QRegularExpression::PatternOptions(QRegularExpression::ExtendedPatternSyntaxOption);
+ QTest::newRow("regexp06") << "a [sS]ingleline .* match"
+ << QRegularExpression::PatternOptions(QRegularExpression::DotMatchesEverythingOption);
+ QTest::newRow("regexp07") << "multiple.*options"
+ << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
+ | QRegularExpression::DotMatchesEverythingOption
+ | QRegularExpression::MultilineOption
+ | QRegularExpression::DontCaptureOption
+ | QRegularExpression::InvertedGreedinessOption);
+
+ QTest::newRow("unicode01") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$")
+ << QRegularExpression::PatternOptions{};
+ QTest::newRow("unicode02") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$")
+ << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
+ | QRegularExpression::DotMatchesEverythingOption
+ | QRegularExpression::InvertedGreedinessOption);
+ QTest::newRow("unicode03") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f")
+ << QRegularExpression::PatternOptions{};
+ QTest::newRow("unicode04") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f")
+ << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
+ | QRegularExpression::DotMatchesEverythingOption
+ | QRegularExpression::InvertedGreedinessOption);
+}
+
+static const char enableJitEnvironmentVariable[] = "QT_ENABLE_REGEXP_JIT";
+
+void tst_QRegularExpression::initMain()
+{
+ if (!qEnvironmentVariableIsSet(enableJitEnvironmentVariable)) {
+ std::cerr << "Enabling QRegularExpression JIT for testing; set QT_ENABLE_REGEXP_JIT to 0 to disable it.\n";
+ qputenv(enableJitEnvironmentVariable, "1");
+ }
+}
+
+void tst_QRegularExpression::defaultConstructors()
+{
+ QRegularExpression re;
+ QCOMPARE(re.pattern(), QString());
+ QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
+ QCOMPARE(re.isValid(), true);
+ QCOMPARE(re.patternErrorOffset(), -1);
+ QCOMPARE(re.captureCount(), 0);
+ QCOMPARE(re.namedCaptureGroups(), QStringList { QString() });
+
+ QRegularExpressionMatch match;
+ QCOMPARE(match.regularExpression(), QRegularExpression());
+ QCOMPARE(match.regularExpression(), re);
+ QCOMPARE(match.matchType(), QRegularExpression::NoMatch);
+ QCOMPARE(match.matchOptions(), QRegularExpression::NoMatchOption);
+ QCOMPARE(match.hasMatch(), false);
+ QCOMPARE(match.hasPartialMatch(), false);
+ QCOMPARE(match.isValid(), true);
+ QCOMPARE(match.lastCapturedIndex(), -1);
+ QCOMPARE(match.captured(), QString());
+ QCOMPARE(match.captured("test"), QString());
+ QCOMPARE(match.capturedTexts(), QStringList());
+ QCOMPARE(match.capturedStart(), -1);
+ QCOMPARE(match.capturedEnd(), -1);
+ QCOMPARE(match.capturedLength(), 0);
+ QCOMPARE(match.capturedStart("test"), -1);
+ QCOMPARE(match.capturedEnd("test"), -1);
+ QCOMPARE(match.capturedLength("test"), 0);
+
+ QRegularExpressionMatchIterator iterator;
+ QCOMPARE(iterator.regularExpression(), QRegularExpression());
+ QCOMPARE(iterator.regularExpression(), re);
+ QCOMPARE(iterator.matchType(), QRegularExpression::NoMatch);
+ QCOMPARE(iterator.matchOptions(), QRegularExpression::NoMatchOption);
+ QCOMPARE(iterator.isValid(), true);
+ QCOMPARE(iterator.hasNext(), false);
+}
+
+void tst_QRegularExpression::moveSemantics()
+{
+ const QString pattern = "pattern";
+ const QRegularExpression::PatternOptions options = QRegularExpression::CaseInsensitiveOption;
+ QRegularExpression expr1(pattern, options);
+ QCOMPARE(expr1.pattern(), pattern);
+ QCOMPARE(expr1.patternOptions(), options);
+
+ QRegularExpression expr2(std::move(expr1));
+ QCOMPARE(expr2.pattern(), pattern);
+ QCOMPARE(expr2.patternOptions(), options);
+
+ const QString pattern2 = "pattern2";
+ QRegularExpression expr3(pattern2);
+ QCOMPARE(expr3.pattern(), pattern2);
+ QCOMPARE(expr3.patternOptions(), QRegularExpression::NoPatternOption);
+
+ // check that (move)assigning to the moved-from object is ok
+ expr1 = std::move(expr3);
+ QCOMPARE(expr1.pattern(), pattern2);
+ QCOMPARE(expr1.patternOptions(), QRegularExpression::NoPatternOption);
+
+ // here expr3 is in the moved-from state, so destructor call for moved-from
+ // object is also checked
+}
+
+void tst_QRegularExpression::moveSemanticsMatch()
+{
+ QRegularExpression re("test");
+ QRegularExpressionMatch match1 = re.match("abctestdef");
+ QCOMPARE(match1.hasMatch(), true);
+ QCOMPARE(match1.capturedStart(), 3);
+ QCOMPARE(match1.capturedEnd(), 7);
+
+ QRegularExpressionMatch match2(std::move(match1));
+ QCOMPARE(match2.hasMatch(), true);
+ QCOMPARE(match2.capturedStart(), 3);
+ QCOMPARE(match2.capturedEnd(), 7);
+ consistencyCheck(match2);
+ if (QTest::currentTestFailed())
+ return;
+
+ QRegularExpressionMatch match3 = re.match("test1");
+ QCOMPARE(match3.hasMatch(), true);
+ QCOMPARE(match3.capturedStart(), 0);
+ QCOMPARE(match3.capturedEnd(), 4);
+
+ // check that (move)assigning to the moved-from object is ok
+ match1 = std::move(match3);
+ QCOMPARE(match1.hasMatch(), true);
+ QCOMPARE(match1.capturedStart(), 0);
+ QCOMPARE(match1.capturedEnd(), 4);
+ consistencyCheck(match1);
+ if (QTest::currentTestFailed())
+ return;
+
+ // here match3 is in the moved-from state, so destructor call for moved-from
+ // object is also checked
+}
+
+void tst_QRegularExpression::moveSemanticsMatchIterator()
+{
+ QRegularExpression re("(\\w+)");
+ QRegularExpressionMatchIterator it1 = re.globalMatch("some test");
+ QVERIFY(it1.isValid());
+ QVERIFY(it1.hasNext());
+ QCOMPARE(it1.regularExpression(), re);
+
+ QRegularExpressionMatchIterator it2(std::move(it1));
+ QVERIFY(it2.isValid());
+ QVERIFY(it2.hasNext());
+ QCOMPARE(it2.regularExpression(), re);
+ consistencyCheck(it2);
+ if (QTest::currentTestFailed())
+ return;
+
+ QRegularExpression re2("test");
+ QRegularExpressionMatchIterator it3 = re2.globalMatch("123test456");
+ QVERIFY(it3.isValid());
+ QVERIFY(it3.hasNext());
+ QCOMPARE(it3.regularExpression(), re2);
+
+ // check that (move)assigning to the moved-from object is ok
+ it1 = std::move(it3);
+ QVERIFY(it1.isValid());
+ QVERIFY(it1.hasNext());
+ QCOMPARE(it1.regularExpression(), re2);
+ consistencyCheck(it1);
+ if (QTest::currentTestFailed())
+ return;
+
+ // here it3 is in the moved-from state, so destructor call for moved-from
+ // object is also checked
+}
+
+void tst_QRegularExpression::gettersSetters_data()
+{
+ provideRegularExpressions();
+}
+
+void tst_QRegularExpression::gettersSetters()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QRegularExpression::PatternOptions, patternOptions);
+ {
+ QRegularExpression re;
+ re.setPattern(pattern);
+ QCOMPARE(re.pattern(), pattern);
+ QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
+ }
+ {
+ QRegularExpression re;
+ re.setPatternOptions(patternOptions);
+ QCOMPARE(re.pattern(), QString());
+ QCOMPARE(re.patternOptions(), patternOptions);
+ }
+ {
+ QRegularExpression re(pattern);
+ QCOMPARE(re.pattern(), pattern);
+ QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
+ }
+ {
+ QRegularExpression re(pattern, patternOptions);
+ QCOMPARE(re.pattern(), pattern);
+ QCOMPARE(re.patternOptions(), patternOptions);
+ }
+}
+
+void tst_QRegularExpression::escape_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("escaped");
+ QTest::newRow("escape01") << "a normal pattern"
+ << "a\\ normal\\ pattern";
+
+ QTest::newRow("escape02") << "abcdefghijklmnopqrstuvzABCDEFGHIJKLMNOPQRSTUVZ1234567890_"
+ << "abcdefghijklmnopqrstuvzABCDEFGHIJKLMNOPQRSTUVZ1234567890_";
+
+ QTest::newRow("escape03") << "^\\ba\\b.*(?<NAME>reg|exp)$"
+ << "\\^\\\\ba\\\\b\\.\\*\\(\\?\\<NAME\\>reg\\|exp\\)\\$";
+
+ QString nulString("abcXabcXXabc");
+ nulString[3] = nulString[7] = nulString[8] = QChar(0, 0);
+ QTest::newRow("NUL") << nulString
+ << "abc\\0abc\\0\\0abc";
+
+ QTest::newRow("unicode01") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$")
+ << QString::fromUtf8("\\^s\\[ome\\]\\ latin\\-1\\ \\\xc3\x80\\\xc3\x88\\\xc3\x8c\\\xc3\x92\\\xc3\x99\\ chars\\$");
+ QTest::newRow("unicode02") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f")
+ << QString::fromUtf8("Unicode\\ \\\xf0\x9d\x85\x9d\\ \\\xf0\x9d\x85\x9e\\\xf0\x9d\x85\x9f");
+
+ QString unicodeAndNulString = QString::fromUtf8("^\xc3\x80\xc3\x88\xc3\x8cN\xc3\x92NN\xc3\x99 chars$");
+ unicodeAndNulString[4] = unicodeAndNulString[6] = unicodeAndNulString[7] = QChar(0, 0);
+ QTest::newRow("unicode03") << unicodeAndNulString
+ << QString::fromUtf8("\\^\\\xc3\x80\\\xc3\x88\\\xc3\x8c\\0\\\xc3\x92\\0\\0\\\xc3\x99\\ chars\\$");
+}
+
+void tst_QRegularExpression::escape()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, escaped);
+ QCOMPARE(QRegularExpression::escape(string), escaped);
+ QRegularExpression re(escaped);
+ QCOMPARE(re.isValid(), true);
+}
+
+void tst_QRegularExpression::validity_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<bool>("validity");
+
+ QTest::newRow("valid01") << "a pattern" << true;
+ QTest::newRow("valid02") << "(a|pattern)" << true;
+ QTest::newRow("valid03") << "a [pP]attern" << true;
+ QTest::newRow("valid04") << "^(?<article>a).*(?<noun>pattern)$" << true;
+ QTest::newRow("valid05") << "a \\P{Ll}attern" << true;
+
+ QTest::newRow("invalid01") << "a pattern\\" << false;
+ QTest::newRow("invalid02") << "(a|pattern" << false;
+ QTest::newRow("invalid03") << "a \\P{BLAH}attern" << false;
+
+ QString pattern;
+ // 0xD800 (high surrogate) not followed by a low surrogate
+ pattern = "abcdef";
+ pattern[3] = QChar(0x00, 0xD8);
+ QTest::newRow("invalidUnicode01") << pattern << false;
+}
+
+void tst_QRegularExpression::validity()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ "^" + QRegularExpression::escape("QRegularExpressionPrivate::doMatch(): "
+ "called on an invalid QRegularExpression object")
+ );
+
+ QFETCH(QString, pattern);
+ QFETCH(bool, validity);
+ QRegularExpression re(pattern);
+ QCOMPARE(re.isValid(), validity);
+ if (!validity)
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QRegularExpressionMatch match = re.match("a pattern");
+ QCOMPARE(match.isValid(), validity);
+ consistencyCheck(match);
+
+ if (!validity)
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QRegularExpressionMatchIterator iterator = re.globalMatch("a pattern");
+ QCOMPARE(iterator.isValid(), validity);
+}
+
+void tst_QRegularExpression::patternOptions_data()
+{
+ QTest::addColumn<QRegularExpression>("regexp");
+ QTest::addColumn<QString>("subject");
+ QTest::addColumn<Match>("match");
+
+ // none of these would successfully match if the respective
+ // pattern option is not set
+
+ Match m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString::fromUtf8("AbC\xc3\xa0");
+ QTest::newRow("/i") << QRegularExpression(QString::fromUtf8("abc\xc3\x80"), QRegularExpression::CaseInsensitiveOption)
+ << QString::fromUtf8("AbC\xc3\xa0")
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "abc123\n678def";
+ QTest::newRow("/s") << QRegularExpression("\\Aabc.*def\\z", QRegularExpression::DotMatchesEverythingOption)
+ << "abc123\n678def"
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "jumped over";
+ QTest::newRow("/m") << QRegularExpression("^\\w+ \\w+$", QRegularExpression::MultilineOption)
+ << "the quick fox\njumped over\nthe lazy\ndog"
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "abc 123456";
+ QTest::newRow("/x") << QRegularExpression("\\w+ # a word\n"
+ "\\ # a space\n"
+ "\\w+ # another word",
+ QRegularExpression::ExtendedPatternSyntaxOption)
+ << "abc 123456 def"
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "the quick fox" << "the" << "quick fox";
+ QTest::newRow("/U") << QRegularExpression("(.+) (.+?)", QRegularExpression::InvertedGreedinessOption)
+ << "the quick fox"
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "the quick fox" << "quick";
+ m.namedCaptured["named"] = "quick";
+ QTest::newRow("no cap") << QRegularExpression("(\\w+) (?<named>\\w+) (\\w+)", QRegularExpression::DontCaptureOption)
+ << "the quick fox"
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString::fromUtf8("abc\xc3\x80\xc3\xa0 12\xdb\xb1\xdb\xb2\xf0\x9d\x9f\x98")
+ << QString::fromUtf8("abc\xc3\x80\xc3\xa0")
+ << QString::fromUtf8("12\xdb\xb1\xdb\xb2\xf0\x9d\x9f\x98");
+ QTest::newRow("unicode properties") << QRegularExpression("(\\w+) (\\d+)", QRegularExpression::UseUnicodePropertiesOption)
+ << QString::fromUtf8("abc\xc3\x80\xc3\xa0 12\xdb\xb1\xdb\xb2\xf0\x9d\x9f\x98")
+ << m;
+}
+
+void tst_QRegularExpression::patternOptions()
+{
+ QFETCH(QRegularExpression, regexp);
+ QFETCH(QString, subject);
+ QFETCH(Match, match);
+
+ QRegularExpressionMatch m = regexp.match(subject);
+ consistencyCheck(m);
+ QVERIFY(m == match);
+}
+
+void tst_QRegularExpression::normalMatch_data()
+{
+ QTest::addColumn<QRegularExpression>("regexp");
+ QTest::addColumn<QString>("subject");
+ QTest::addColumn<qsizetype>("offset");
+ QTest::addColumn<QRegularExpression::MatchOptions>("matchOptions");
+ QTest::addColumn<Match>("match");
+
+ Match m;
+ qsizetype offset = 0;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "string" << "string";
+ QTest::newRow("match01") << QRegularExpression("(\\bstring\\b)")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "a string" << "a" << "string";
+ QTest::newRow("match02") << QRegularExpression("(\\w+) (\\w+)")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "a string" << "a" << "string";
+ m.namedCaptured["article"] = "a";
+ m.namedCaptured["noun"] = "string";
+ QTest::newRow("match03") << QRegularExpression("(?<article>\\w+) (?<noun>\\w+)")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << " string" << std::nullopt << "string";
+ QTest::newRow("match04") << QRegularExpression("(\\w+)? (\\w+)")
+ << " string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << " string" << QString("") << "string";
+ QTest::newRow("match05") << QRegularExpression("(\\w*) (\\w+)")
+ << " string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "c123def" << "c12" << "3" << "def";
+ offset = 2;
+ for (qsizetype i = 0; i <= offset; ++i) {
+ QTest::newRow(("match06-offset" + QByteArray::number(i)).constData())
+ << QRegularExpression("(\\w*)(\\d+)(\\w*)")
+ << QStringLiteral("abc123def").mid(offset - i)
+ << i
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+ }
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString("");
+ offset = 9;
+ for (qsizetype i = 0; i <= offset; ++i) {
+ QTest::newRow(("match07-offset" + QByteArray::number(i)).constData())
+ << QRegularExpression("\\w*")
+ << QStringLiteral("abc123def").mid(offset - i)
+ << i
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+ }
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString("a string") << QString("a string") << QString("");
+ QTest::newRow("match08") << QRegularExpression("(.*)(.*)")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString("a string") << QString("") << QString("a string");
+ QTest::newRow("match09") << QRegularExpression("(.*?)(.*)")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString();
+ QTest::newRow("empty-in-null-string") << QRegularExpression("")
+ << QString()
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString("");
+ QTest::newRow("empty-in-empty-string") << QRegularExpression("")
+ << QString("")
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ // non existing names for capturing groups
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "a string" << "a" << "string";
+ m.namedCaptured["article"] = "a";
+ m.namedCaptured["noun"] = "string";
+ m.namedCaptured["nonexisting1"] = std::nullopt;
+ m.namedCaptured["nonexisting2"] = std::nullopt;
+ m.namedCaptured["nonexisting3"] = std::nullopt;
+ QTest::newRow("match10") << QRegularExpression("(?<article>\\w+) (?<noun>\\w+)")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "" << "";
+ m.namedCaptured["digits"] = ""; // empty VS null
+ m.namedCaptured["nonexisting"] = std::nullopt;
+ QTest::newRow("match11") << QRegularExpression("(?<digits>\\d*)")
+ << "abcde"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ // ***
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "bcd";
+ QTest::newRow("match12")
+ << QRegularExpression("\\Bbcd\\B")
+ << "abcde"
+ << qsizetype(1)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ // ***
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString() << QString();
+ QTest::newRow("capture-in-null-string")
+ << QRegularExpression("(a*)")
+ << QString()
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString() << QString() << QString();
+ QTest::newRow("capture-in-null-string-2")
+ << QRegularExpression("(a*)(b*)")
+ << QString()
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << QString();
+ QTest::newRow("no-capture-in-null-string")
+ << QRegularExpression("(a+)?")
+ << QString()
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "bb" << QString("") << "bb";
+ QTest::newRow("empty-capture-in-non-null-string")
+ << QRegularExpression("(a*)(b*)")
+ << QString("bbc")
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "bb" << std::nullopt << "bb";
+ QTest::newRow("no-capture-in-non-null-string")
+ << QRegularExpression("(a+)?(b+)?")
+ << QString("bbc")
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("nomatch01") << QRegularExpression("\\d+")
+ << "a string"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true;
+ offset = 1;
+ for (qsizetype i = 0; i <= offset; ++i) {
+ QTest::newRow(("nomatch02-offset" + QByteArray::number(i)).constData())
+ << QRegularExpression("(\\w+) (\\w+)")
+ << QStringLiteral("a string").mid(offset - i)
+ << i
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+ }
+
+ m.clear();
+ m.isValid = true;
+ offset = 9;
+ for (qsizetype i = 0; i <= offset; ++i) {
+ QTest::newRow(("nomatch03-offset" + QByteArray::number(i)).constData())
+ << QRegularExpression("\\w+")
+ << QStringLiteral("abc123def").mid(offset - i)
+ << i
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+ }
+
+ // ***
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("anchoredmatch01") << QRegularExpression("\\d+")
+ << "abc123def"
+ << qsizetype(0)
+ << QRegularExpression::MatchOptions(QRegularExpression::AnchorAtOffsetMatchOption)
+ << m;
+
+ // ***
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "678";
+ QTest::newRow("negativeoffset01") << QRegularExpression("\\d+")
+ << "abc123def678ghi"
+ << qsizetype(-6)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "678";
+ QTest::newRow("negativeoffset02") << QRegularExpression("\\d+")
+ << "abc123def678ghi"
+ << qsizetype(-8)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "678ghi" << "678" << "ghi";
+ QTest::newRow("negativeoffset03") << QRegularExpression("(\\d+)(\\w+)")
+ << "abc123def678ghi"
+ << qsizetype(-8)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("negativeoffset04") << QRegularExpression("\\d+")
+ << "abc123def678ghi"
+ << qsizetype(-3)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "678";
+ QTest::newRow("negativeoffset05") << QRegularExpression("^\\d+", QRegularExpression::MultilineOption)
+ << "a\nbc123\ndef\n678gh\ni"
+ << qsizetype(-10)
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+}
+
+
+void tst_QRegularExpression::normalMatch()
+{
+ QFETCH(QRegularExpression, regexp);
+ QFETCH(QString, subject);
+ QFETCH(qsizetype, offset);
+ QFETCH(QRegularExpression::MatchOptions, matchOptions);
+ QFETCH(Match, match);
+
+ testMatch<QRegularExpressionMatch>(regexp,
+ static_cast<QREMatchStringPMF>(&QRegularExpression::match),
+ static_cast<QREMatchStringViewPMF>(&QRegularExpression::matchView),
+ subject,
+ offset,
+ QRegularExpression::NormalMatch,
+ matchOptions,
+ match);
+}
+
+void tst_QRegularExpression::partialMatch_data()
+{
+ QTest::addColumn<QRegularExpression>("regexp");
+ QTest::addColumn<QString>("subject");
+ QTest::addColumn<qsizetype>("offset");
+ QTest::addColumn<QRegularExpression::MatchType>("matchType");
+ QTest::addColumn<QRegularExpression::MatchOptions>("matchOptions");
+ QTest::addColumn<Match>("match");
+
+ Match m;
+ qsizetype offset = 0;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "str";
+ QTest::newRow("softmatch01") << QRegularExpression("string")
+ << "a str"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << " str";
+ QTest::newRow("softmatch02") << QRegularExpression("\\bstring\\b")
+ << "a str"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << " str";
+ QTest::newRow("softmatch03") << QRegularExpression("(\\bstring\\b)")
+ << "a str"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "8 Dec 19";
+ QTest::newRow("softmatch04") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
+ << "8 Dec 19"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "8 Dec 1985" << "8" << "Dec" << "1985";
+ QTest::newRow("softmatch05") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
+ << "8 Dec 1985"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured << "def";
+ QTest::newRow("softmatch06") << QRegularExpression("abc\\w+X|def")
+ << "abcdef"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "abcdef";
+ QTest::newRow("softmatch07") << QRegularExpression("abc\\w+X|defY")
+ << "abcdef"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "def";
+ offset = 1;
+ for (qsizetype i = 0; i <= offset; ++i) {
+ QTest::newRow(("softmatch08-offset" + QByteArray::number(i)).constData())
+ << QRegularExpression("abc\\w+X|defY")
+ << QStringLiteral("abcdef").mid(offset - i)
+ << i
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+ }
+
+ // ***
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "str";
+ QTest::newRow("hardmatch01") << QRegularExpression("string")
+ << "a str"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << " str";
+ QTest::newRow("hardmatch02") << QRegularExpression("\\bstring\\b")
+ << "a str"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << " str";
+ QTest::newRow("hardmatch03") << QRegularExpression("(\\bstring\\b)")
+ << "a str"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "8 Dec 19";
+ QTest::newRow("hardmatch04") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
+ << "8 Dec 19"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "8 Dec 1985";
+ QTest::newRow("hardmatch05") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
+ << "8 Dec 1985"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "abcdef";
+ QTest::newRow("hardmatch06") << QRegularExpression("abc\\w+X|def")
+ << "abcdef"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "abcdef";
+ QTest::newRow("hardmatch07") << QRegularExpression("abc\\w+X|defY")
+ << "abcdef"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "def";
+ offset = 1;
+ for (qsizetype i = 0; i <= offset; ++i) {
+ QTest::newRow(("hardmatch08-offset" + QByteArray::number(i)).constData())
+ << QRegularExpression("abc\\w+X|defY")
+ << QStringLiteral("abcdef").mid(offset - i)
+ << i
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+ }
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "ab";
+ QTest::newRow("hardmatch09") << QRegularExpression("abc|ab")
+ << "ab"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "abc";
+ QTest::newRow("hardmatch10") << QRegularExpression("abc(def)?")
+ << "abc"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true; m.hasPartialMatch = true;
+ m.captured << "abc";
+ QTest::newRow("hardmatch11") << QRegularExpression("(abc)*")
+ << "abc"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+
+ // ***
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("nomatch01") << QRegularExpression("abc\\w+X|defY")
+ << "123456"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("nomatch02") << QRegularExpression("abc\\w+X|defY")
+ << "123456"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("nomatch03") << QRegularExpression("abc\\w+X|defY")
+ << "ab123"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferCompleteMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+ m.clear();
+ m.isValid = true;
+ QTest::newRow("nomatch04") << QRegularExpression("abc\\w+X|defY")
+ << "ab123"
+ << qsizetype(0)
+ << QRegularExpression::PartialPreferFirstMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << m;
+
+}
+
+void tst_QRegularExpression::partialMatch()
+{
+ QFETCH(QRegularExpression, regexp);
+ QFETCH(QString, subject);
+ QFETCH(qsizetype, offset);
+ QFETCH(QRegularExpression::MatchType, matchType);
+ QFETCH(QRegularExpression::MatchOptions, matchOptions);
+ QFETCH(Match, match);
+
+ testMatch<QRegularExpressionMatch>(regexp,
+ static_cast<QREMatchStringPMF>(&QRegularExpression::match),
+ static_cast<QREMatchStringViewPMF>(&QRegularExpression::matchView),
+ subject,
+ offset,
+ matchType,
+ matchOptions,
+ match);
+}
+
+void tst_QRegularExpression::globalMatch_data()
+{
+ QTest::addColumn<QRegularExpression>("regexp");
+ QTest::addColumn<QString>("subject");
+ QTest::addColumn<qsizetype>("offset");
+ QTest::addColumn<QRegularExpression::MatchType>("matchType");
+ QTest::addColumn<QRegularExpression::MatchOptions>("matchOptions");
+ QTest::addColumn<QList<Match> >("matchList");
+
+ QList<Match> matchList;
+ Match m;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the";
+ matchList << m;
+ m.captured = CapturedList() << "quick";
+ matchList << m;
+ m.captured = CapturedList() << "fox";
+ matchList << m;
+ QTest::newRow("globalmatch01") << QRegularExpression("\\w+")
+ << "the quick fox"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the" << "t" << "he";
+ matchList << m;
+ m.captured = CapturedList() << "quick" << "q" << "uick";
+ matchList << m;
+ m.captured = CapturedList() << "fox" << "f" << "ox";
+ matchList << m;
+ QTest::newRow("globalmatch02") << QRegularExpression("(\\w+?)(\\w+)")
+ << "the quick fox"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "ACA""GTG""CGA""AAA";
+ matchList << m;
+ m.captured = CapturedList() << "AAA";
+ matchList << m;
+ m.captured = CapturedList() << "AAG""GAA""AAG""AAA";
+ matchList << m;
+ m.captured = CapturedList() << "AAA";
+ matchList << m;
+ QTest::newRow("globalmatch03") << QRegularExpression("\\G(?:\\w\\w\\w)*?AAA")
+ << "ACA""GTG""CGA""AAA""AAA""AAG""GAA""AAG""AAA""AAA"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ QTest::newRow("globalmatch04") << QRegularExpression("(?:\\w\\w\\w)*?AAA")
+ << "ACA""GTG""CGA""AAA""AAA""AAG""GAA""AAG""AAA""AAA"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::AnchorAtOffsetMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "c";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "c";
+ matchList << m;
+ m.captured = CapturedList() << "aabb";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+
+ QTest::newRow("globalmatch_emptycaptures01") << QRegularExpression("a*b*|c")
+ << "ccaabbd"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "quick";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "fox";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+
+ QTest::newRow("globalmatch_emptycaptures02") << QRegularExpression(".*")
+ << "the\nquick\nfox"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "quick";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "fox";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+
+ QTest::newRow("globalmatch_emptycaptures03") << QRegularExpression(".*")
+ << "the\nquick\nfox\n"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "quick";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "fox";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+
+ QTest::newRow("globalmatch_emptycaptures04") << QRegularExpression("(*CRLF).*")
+ << "the\r\nquick\r\nfox"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "quick";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "fox";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+
+ QTest::newRow("globalmatch_emptycaptures05") << QRegularExpression("(*CRLF).*")
+ << "the\r\nquick\r\nfox\r\n"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "the";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "quick";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "fox";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "jumped";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+
+ QTest::newRow("globalmatch_emptycaptures06") << QRegularExpression("(*ANYCRLF).*")
+ << "the\r\nquick\nfox\rjumped"
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << "ABC";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "DEF";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << "GHI";
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ QTest::newRow("globalmatch_emptycaptures07") << QRegularExpression("[\\x{0000}-\\x{FFFF}]*")
+ << QString::fromUtf8("ABC""\xf0\x9d\x85\x9d""DEF""\xf0\x9d\x85\x9e""GHI")
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+
+ matchList.clear();
+ m.clear();
+ m.isValid = true; m.hasMatch = true;
+ m.captured = CapturedList() << QString::fromUtf8("ABC""\xc3\x80");
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ m.captured = CapturedList() << QString::fromUtf8("\xc3\x80""DEF""\xc3\x80");
+ matchList << m;
+ m.captured = CapturedList() << "";
+ matchList << m;
+ QTest::newRow("globalmatch_emptycaptures08") << QRegularExpression("[\\x{0000}-\\x{FFFF}]*")
+ << QString::fromUtf8("ABC""\xc3\x80""\xf0\x9d\x85\x9d""\xc3\x80""DEF""\xc3\x80")
+ << qsizetype(0)
+ << QRegularExpression::NormalMatch
+ << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
+ << matchList;
+}
+
+void tst_QRegularExpression::globalMatch()
+{
+ QFETCH(QRegularExpression, regexp);
+ QFETCH(QString, subject);
+ QFETCH(qsizetype, offset);
+ QFETCH(QRegularExpression::MatchType, matchType);
+ QFETCH(QRegularExpression::MatchOptions, matchOptions);
+ QFETCH(QList<Match>, matchList);
+
+ testMatch<QRegularExpressionMatchIterator>(regexp,
+ static_cast<QREGlobalMatchStringPMF>(&QRegularExpression::globalMatch),
+ static_cast<QREGlobalMatchStringViewPMF>(&QRegularExpression::globalMatchView),
+ subject,
+ offset,
+ matchType,
+ matchOptions,
+ matchList);
+}
+
+void tst_QRegularExpression::serialize_data()
+{
+ provideRegularExpressions();
+}
+
+void tst_QRegularExpression::serialize()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QRegularExpression::PatternOptions, patternOptions);
+ QRegularExpression outRe(pattern, patternOptions);
+
+ QByteArray buffer;
+ {
+ QDataStream out(&buffer, QIODevice::WriteOnly);
+ out << outRe;
+ }
+ QRegularExpression inRe;
+ {
+ QDataStream in(&buffer, QIODevice::ReadOnly);
+ in >> inRe;
+ }
+ QCOMPARE(inRe, outRe);
+}
+
+static void verifyEquality(const QRegularExpression &re1, const QRegularExpression &re2)
+{
+ QVERIFY(re1 == re2);
+ QVERIFY(re2 == re1);
+ QCOMPARE(qHash(re1), qHash(re2));
+ QVERIFY(!(re1 != re2));
+ QVERIFY(!(re2 != re1));
+
+ QRegularExpression re3(re1);
+
+ QVERIFY(re1 == re3);
+ QVERIFY(re3 == re1);
+ QCOMPARE(qHash(re1), qHash(re3));
+ QVERIFY(!(re1 != re3));
+ QVERIFY(!(re3 != re1));
+
+ QVERIFY(re2 == re3);
+ QVERIFY(re3 == re2);
+ QCOMPARE(qHash(re2), qHash(re3));
+ QVERIFY(!(re2 != re3));
+ QVERIFY(!(re3 != re2));
+
+ re3 = re2;
+ QVERIFY(re1 == re3);
+ QVERIFY(re3 == re1);
+ QCOMPARE(qHash(re1), qHash(re3));
+ QVERIFY(!(re1 != re3));
+ QVERIFY(!(re3 != re1));
+
+ QVERIFY(re2 == re3);
+ QVERIFY(re3 == re2);
+ QCOMPARE(qHash(re2), qHash(re3));
+ QVERIFY(!(re2 != re3));
+ QVERIFY(!(re3 != re2));
+}
+
+void tst_QRegularExpression::operatoreq_data()
+{
+ provideRegularExpressions();
+}
+
+void tst_QRegularExpression::operatoreq()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QRegularExpression::PatternOptions, patternOptions);
+ {
+ QRegularExpression re1(pattern);
+ QRegularExpression re2(pattern);
+
+ verifyEquality(re1, re2);
+ }
+ {
+ QRegularExpression re1(QString(), patternOptions);
+ QRegularExpression re2(QString(), patternOptions);
+
+ verifyEquality(re1, re2);
+ }
+ {
+ QRegularExpression re1(pattern, patternOptions);
+ QRegularExpression re2(pattern, patternOptions);
+
+ verifyEquality(re1, re2);
+ }
+}
+
+void tst_QRegularExpression::captureCount_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<int>("captureCount");
+ QTest::newRow("captureCount01") << "a pattern" << 0;
+ QTest::newRow("captureCount02") << "a.*pattern" << 0;
+ QTest::newRow("captureCount03") << "(a) pattern" << 1;
+ QTest::newRow("captureCount04") << "(a).*(pattern)" << 2;
+ QTest::newRow("captureCount05") << "^(?<article>\\w+) (?<noun>\\w+)$" << 2;
+ QTest::newRow("captureCount06") << "^(\\w+) (?<word>\\w+) (.)$" << 3;
+ QTest::newRow("captureCount07") << "(?:non capturing) (capturing) (?<n>named) (?:non (capturing))" << 3;
+ QTest::newRow("captureCount08") << "(?|(a)(b)|(c)(d))" << 2;
+ QTest::newRow("captureCount09") << "(?|(a)(b)|(c)(d)(?:e))" << 2;
+ QTest::newRow("captureCount10") << "(?|(a)(b)|(c)(d)(e)) (f)(g)" << 5;
+ QTest::newRow("captureCount11") << "(?|(a)(b)|(c)(d)(e)) (f)(?:g)" << 4;
+ QTest::newRow("captureCount_invalid01") << "(.*" << -1;
+ QTest::newRow("captureCount_invalid02") << "\\" << -1;
+ QTest::newRow("captureCount_invalid03") << "(?<noun)" << -1;
+}
+
+void tst_QRegularExpression::captureCount()
+{
+ QFETCH(QString, pattern);
+ QRegularExpression re(pattern);
+
+ QTEST(re.captureCount(), "captureCount");
+ if (!re.isValid())
+ QCOMPARE(re.captureCount(), -1);
+}
+
+// the comma in the template breaks QFETCH...
+typedef QMultiHash<QString, int> StringToIntMap;
+Q_DECLARE_METATYPE(StringToIntMap)
+
+void tst_QRegularExpression::captureNames_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<StringToIntMap>("namedCapturesIndexMap");
+ StringToIntMap map;
+
+ QTest::newRow("captureNames01") << "a pattern" << map;
+ QTest::newRow("captureNames02") << "a.*pattern" << map;
+ QTest::newRow("captureNames03") << "(a) pattern" << map;
+ QTest::newRow("captureNames04") << "(a).*(pattern)" << map;
+
+ map.clear();
+ map.replace("named", 1);
+ QTest::newRow("captureNames05") << "a.*(?<named>pattern)" << map;
+
+ map.clear();
+ map.replace("named", 2);
+ QTest::newRow("captureNames06") << "(a).*(?<named>pattern)" << map;
+
+ map.clear();
+ map.replace("name1", 1);
+ map.replace("name2", 2);
+ QTest::newRow("captureNames07") << "(?<name1>a).*(?<name2>pattern)" << map;
+
+ map.clear();
+ map.replace("name1", 2);
+ map.replace("name2", 1);
+ QTest::newRow("captureNames08") << "(?<name2>a).*(?<name1>pattern)" << map;
+
+ map.clear();
+ map.replace("date", 1);
+ map.replace("month", 2);
+ map.replace("year", 3);
+ QTest::newRow("captureNames09") << "^(?<date>\\d\\d)/(?<month>\\d\\d)/(?<year>\\d\\d\\d\\d)$" << map;
+
+ map.clear();
+ map.replace("date", 2);
+ map.replace("month", 1);
+ map.replace("year", 3);
+ QTest::newRow("captureNames10") << "^(?<month>\\d\\d)/(?<date>\\d\\d)/(?<year>\\d\\d\\d\\d)$" << map;
+
+ map.clear();
+ map.replace("noun", 2);
+ QTest::newRow("captureNames11") << "(a)(?|(?<noun>b)|(?<noun>c))(d)" << map;
+
+ map.clear();
+ QTest::newRow("captureNames_invalid01") << "(.*" << map;
+ QTest::newRow("captureNames_invalid02") << "\\" << map;
+ QTest::newRow("captureNames_invalid03") << "(?<noun)" << map;
+ QTest::newRow("captureNames_invalid04") << "(?|(?<noun1>a)|(?<noun2>b))" << map;
+}
+
+void tst_QRegularExpression::captureNames()
+{
+ QFETCH(QString, pattern);
+ QFETCH(StringToIntMap, namedCapturesIndexMap);
+
+ QRegularExpression re(pattern);
+
+ QStringList namedCaptureGroups = re.namedCaptureGroups();
+ int namedCaptureGroupsCount = namedCaptureGroups.size();
+
+ QCOMPARE(namedCaptureGroupsCount, re.captureCount() + 1);
+
+ for (int i = 0; i < namedCaptureGroupsCount; ++i) {
+ const QString &name = namedCaptureGroups.at(i);
+
+ if (name.isEmpty()) {
+ QVERIFY(!namedCapturesIndexMap.contains(name));
+ } else {
+ QVERIFY(namedCapturesIndexMap.contains(name));
+ QCOMPARE(i, namedCapturesIndexMap.value(name));
+ }
+ }
+
+}
+
+void tst_QRegularExpression::captureNamesNul()
+{
+ QRegularExpression re("a(\\d+)b(?<name>\\d+)c(?<anotherName>\\d+)d(\\d+)e$");
+ QVERIFY(re.isValid());
+
+ QCOMPARE(re.captureCount(), 4);
+
+ QStringList namedCaptureGroups = re.namedCaptureGroups();
+ QCOMPARE(namedCaptureGroups[0], QString());
+ QCOMPARE(namedCaptureGroups[1], QString());
+ QCOMPARE(namedCaptureGroups[2], "name");
+ QCOMPARE(namedCaptureGroups[3], "anotherName");
+ QCOMPARE(namedCaptureGroups[4], QString());
+
+ QRegularExpressionMatch m = re.match("a12b456c789d0e");
+ QVERIFY(m.hasMatch());
+
+ QString captureName("name");
+ QCOMPARE(m.captured(captureName), "456");
+ QCOMPARE(m.captured(QStringView(captureName)), "456");
+ QCOMPARE(m.captured(QAnyStringView(captureName)), "456");
+ QCOMPARE(m.captured(qToStringViewIgnoringNull(captureName)), "456");
+ QCOMPARE(m.captured(u"name"), "456");
+
+ captureName = "anotherName";
+ QCOMPARE(m.captured(captureName), "789");
+ QCOMPARE(m.captured(QStringView(captureName)), "789");
+ QCOMPARE(m.captured(QAnyStringView(captureName)), "789");
+ QCOMPARE(m.captured(qToStringViewIgnoringNull(captureName)), "789");
+ QCOMPARE(m.captured(u"anotherName"), "789");
+}
+
+void tst_QRegularExpression::pcreJitStackUsage_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("subject");
+ // these patterns cause enough backtrack (or even infinite recursion)
+ // in the regexp engine, so that JIT requests more memory.
+ QTest::newRow("jitstack01") << "(?(R)a*(?1)|((?R))b)" << "aaaabcde";
+ QTest::newRow("jitstack02") << "(?(R)a*(?1)|((?R))b)" << "aaaaaaabcde";
+}
+
+void tst_QRegularExpression::pcreJitStackUsage()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, subject);
+
+ QRegularExpression re(pattern);
+
+ QVERIFY(re.isValid());
+ QRegularExpressionMatch match = re.match(subject);
+ consistencyCheck(match);
+ QRegularExpressionMatchIterator iterator = re.globalMatch(subject);
+ consistencyCheck(iterator);
+ while (iterator.hasNext()) {
+ match = iterator.next();
+ consistencyCheck(match);
+ }
+}
+
+void tst_QRegularExpression::regularExpressionMatch_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("subject");
+
+ QTest::newRow("validity01") << "(?<digits>\\d+)" << "1234 abcd";
+ QTest::newRow("validity02") << "(?<digits>\\d+) (?<alpha>\\w+)" << "1234 abcd";
+}
+
+void tst_QRegularExpression::regularExpressionMatch()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, subject);
+
+ QRegularExpression re(pattern);
+
+ QVERIFY(re.isValid());
+ QRegularExpressionMatch match = re.match(subject);
+ consistencyCheck(match);
+ QCOMPARE(match.captured("non-existing").isNull(), true);
+ QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatch::captured: empty capturing group name passed");
+ QCOMPARE(match.captured("").isNull(), true);
+ QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatch::captured: empty capturing group name passed");
+ QCOMPARE(match.captured(QString()).isNull(), true);
+}
+
+void tst_QRegularExpression::JOptionUsage_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<bool>("isValid");
+ QTest::addColumn<bool>("JOptionUsed");
+
+ QTest::newRow("joption-notused-01") << "a.*b" << true << false;
+ QTest::newRow("joption-notused-02") << "^a(b)(c)$" << true << false;
+ QTest::newRow("joption-notused-03") << "a(b)(?<c>d)|e" << true << false;
+ QTest::newRow("joption-notused-04") << "(?<a>.)(?<a>.)" << false << false;
+
+ QTest::newRow("joption-used-01") << "(?J)a.*b" << true << true;
+ QTest::newRow("joption-used-02") << "(?-J)a.*b" << true << true;
+ QTest::newRow("joption-used-03") << "(?J)(?<a>.)(?<a>.)" << true << true;
+ QTest::newRow("joption-used-04") << "(?-J)(?<a>.)(?<a>.)" << false << true;
+
+}
+
+void tst_QRegularExpression::JOptionUsage()
+{
+ QFETCH(QString, pattern);
+ QFETCH(bool, isValid);
+ QFETCH(bool, JOptionUsed);
+
+ const QString warningMessage = QStringLiteral("QRegularExpressionPrivate::getPatternInfo(): the pattern '%1'\n is using the (?J) option; duplicate capturing group names are not supported by Qt");
+
+ QRegularExpression re(pattern);
+ if (isValid && JOptionUsed)
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(warningMessage.arg(pattern)));
+ QCOMPARE(re.isValid(), isValid);
+}
+
+void tst_QRegularExpression::QStringAndQStringViewEquivalence()
+{
+ const QString subject = QStringLiteral("Mississippi");
+ {
+ const QRegularExpression re("\\Biss\\B");
+ QVERIFY(re.isValid());
+ {
+ const QRegularExpressionMatch match = re.match(subject);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 1);
+ QCOMPARE(match.capturedEnd(), 4);
+ }
+ {
+ const QRegularExpressionMatch match = re.matchView(QStringView(subject));
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 1);
+ QCOMPARE(match.capturedEnd(), 4);
+ }
+ {
+ const QRegularExpressionMatch match = re.match(subject, 1);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 1);
+ QCOMPARE(match.capturedEnd(), 4);
+ }
+ {
+ const QRegularExpressionMatch match = re.matchView(QStringView(subject), 1);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 1);
+ QCOMPARE(match.capturedEnd(), 4);
+ }
+ {
+ const QRegularExpressionMatch match = re.match(subject.mid(1));
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+ }
+ {
+ const QRegularExpressionMatch match = re.matchView(QStringView(subject).mid(1));
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+ }
+ {
+ const QRegularExpressionMatch match = re.match(subject.mid(1), 1);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+ }
+ {
+ const QRegularExpressionMatch match = re.matchView(QStringView(subject).mid(1), 1);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+ }
+ {
+ const QRegularExpressionMatch match = re.match(subject, 4);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 4);
+ QCOMPARE(match.capturedEnd(), 7);
+ }
+ {
+ const QRegularExpressionMatch match = re.matchView(QStringView(subject), 4);
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 4);
+ QCOMPARE(match.capturedEnd(), 7);
+ }
+ {
+ const QRegularExpressionMatch match = re.match(subject.mid(4));
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(!match.hasMatch());
+ }
+ {
+ const QRegularExpressionMatch match = re.matchView(QStringView(subject).mid(4));
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(!match.hasMatch());
+ }
+
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match1 = i.next();
+ consistencyCheck(match1);
+ QVERIFY(match1.isValid());
+ QVERIFY(match1.hasMatch());
+ QCOMPARE(match1.captured(), QStringLiteral("iss"));
+ QCOMPARE(match1.capturedStart(), 1);
+ QCOMPARE(match1.capturedEnd(), 4);
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match2 = i.next();
+ consistencyCheck(match2);
+ QVERIFY(match2.isValid());
+ QVERIFY(match2.hasMatch());
+ QCOMPARE(match2.captured(), QStringLiteral("iss"));
+ QCOMPARE(match2.capturedStart(), 4);
+ QCOMPARE(match2.capturedEnd(), 7);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject));
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match1 = i.next();
+ consistencyCheck(match1);
+ QVERIFY(match1.isValid());
+ QVERIFY(match1.hasMatch());
+ QCOMPARE(match1.captured(), QStringLiteral("iss"));
+ QCOMPARE(match1.capturedStart(), 1);
+ QCOMPARE(match1.capturedEnd(), 4);
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match2 = i.next();
+ consistencyCheck(match2);
+ QVERIFY(match2.isValid());
+ QVERIFY(match2.hasMatch());
+ QCOMPARE(match2.captured(), QStringLiteral("iss"));
+ QCOMPARE(match2.capturedStart(), 4);
+ QCOMPARE(match2.capturedEnd(), 7);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject, 1);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match1 = i.next();
+ consistencyCheck(match1);
+ QVERIFY(match1.isValid());
+ QVERIFY(match1.hasMatch());
+ QCOMPARE(match1.captured(), QStringLiteral("iss"));
+ QCOMPARE(match1.capturedStart(), 1);
+ QCOMPARE(match1.capturedEnd(), 4);
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match2 = i.next();
+ consistencyCheck(match2);
+ QVERIFY(match2.isValid());
+ QVERIFY(match2.hasMatch());
+ QCOMPARE(match2.captured(), QStringLiteral("iss"));
+ QCOMPARE(match2.capturedStart(), 4);
+ QCOMPARE(match2.capturedEnd(), 7);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject), 1);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match1 = i.next();
+ consistencyCheck(match1);
+ QVERIFY(match1.isValid());
+ QVERIFY(match1.hasMatch());
+ QCOMPARE(match1.captured(), QStringLiteral("iss"));
+ QCOMPARE(match1.capturedStart(), 1);
+ QCOMPARE(match1.capturedEnd(), 4);
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match2 = i.next();
+ consistencyCheck(match2);
+ QVERIFY(match2.isValid());
+ QVERIFY(match2.hasMatch());
+ QCOMPARE(match2.captured(), QStringLiteral("iss"));
+ QCOMPARE(match2.capturedStart(), 4);
+ QCOMPARE(match2.capturedEnd(), 7);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(1));
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject).mid(1));
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(1), 1);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject).mid(1), 1);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(1), 1);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject).mid(1), 1);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 3);
+ QCOMPARE(match.capturedEnd(), 6);
+
+ QVERIFY(!i.hasNext());
+ }
+
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject, 4);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 4);
+ QCOMPARE(match.capturedEnd(), 7);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject), 4);
+ QVERIFY(i.isValid());
+
+ consistencyCheck(i);
+ QVERIFY(i.hasNext());
+ const QRegularExpressionMatch match = i.next();
+ consistencyCheck(match);
+ QVERIFY(match.isValid());
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.captured(), QStringLiteral("iss"));
+ QCOMPARE(match.capturedStart(), 4);
+ QCOMPARE(match.capturedEnd(), 7);
+
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(4));
+ consistencyCheck(i);
+ QVERIFY(i.isValid());
+ QVERIFY(!i.hasNext());
+ }
+ {
+ QRegularExpressionMatchIterator i = re.globalMatchView(QStringView(subject).mid(4));
+ consistencyCheck(i);
+ QVERIFY(i.isValid());
+ QVERIFY(!i.hasNext());
+ }
+ }
+}
+
+class MatcherThread : public QThread
+{
+public:
+ explicit MatcherThread(const QRegularExpression &re, const QString &subject, QObject *parent = nullptr)
+ : QThread(parent),
+ m_re(re),
+ m_subject(subject)
+ {
+ }
+
+private:
+ static const int MATCH_ITERATIONS = 50;
+
+ void run() override
+ {
+ yieldCurrentThread();
+ for (int i = 0; i < MATCH_ITERATIONS; ++i)
+ (void)m_re.match(m_subject);
+ }
+
+ const QRegularExpression &m_re;
+ const QString &m_subject;
+};
+
+void tst_QRegularExpression::threadSafety_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("subject");
+
+ int i = 0;
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abbbbcccd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abababcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcabcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abccccccababd";
+
+ {
+ QString subject(512*1024, QLatin1Char('x'));
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ {
+ QString subject = "ab";
+ subject.append(QString(512*1024, QLatin1Char('x')));
+ subject.append("c");
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ {
+ QString subject = "ab";
+ subject.append(QString(512*1024, QLatin1Char('x')));
+ subject.append("cd");
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaabcde";
+ QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaaaaabcde";
+}
+
+void tst_QRegularExpression::threadSafety()
+{
+#if defined(Q_OS_WASM)
+ QSKIP("This test misbehaves on WASM. Investigation needed (QTBUG-110067)");
+#endif
+
+ QFETCH(QString, pattern);
+ QFETCH(QString, subject);
+
+ QElapsedTimer time;
+ time.start();
+ static const int THREAD_SAFETY_ITERATIONS = 50;
+ const int threadCount = qMax(QThread::idealThreadCount(), 4);
+
+ for (int threadSafetyIteration = 0; threadSafetyIteration < THREAD_SAFETY_ITERATIONS && time.elapsed() < 2000; ++threadSafetyIteration) {
+ QRegularExpression re(pattern);
+
+ QList<MatcherThread *> threads;
+ for (int i = 0; i < threadCount; ++i) {
+ MatcherThread *thread = new MatcherThread(re, subject);
+ thread->start();
+ threads.push_back(thread);
+ }
+
+ for (int i = 0; i < threadCount; ++i)
+ threads[i]->wait();
+
+ qDeleteAll(threads);
+ }
+}
+
+void tst_QRegularExpression::returnsViewsIntoOriginalString()
+{
+ // https://bugreports.qt.io/browse/QTBUG-98653
+
+ auto to_void = [](const auto *p) -> const void* { return p; };
+
+ // GIVEN
+ // a QString with dynamically-allocated data:
+ const QString string = QLatin1String("A\nA\nB\nB\n\nC\nC"); // NOT QStringLiteral!
+ const auto stringDataAddress = to_void(string.data());
+
+ // and a view over said QString:
+ QStringView view(string);
+ const auto viewDataAddress = to_void(view.data());
+ QCOMPARE(stringDataAddress, viewDataAddress);
+
+ // WHEN
+ // we call view.split() with a temporary QRegularExpression object
+ const auto split = view.split(QRegularExpression( "(\r\n|\n|\r)" ), Qt::KeepEmptyParts);
+
+ // THEN
+ // the returned views should point into the underlying string:
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QEXPECT_FAIL("", "QTBUG-98653", Continue);
+#endif
+ QCOMPARE(to_void(split.front().data()), stringDataAddress);
+}
+
+void tst_QRegularExpression::wildcard_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<bool>("matchesPathGlob");
+ QTest::addColumn<bool>("matchesNonPathGlob");
+ QTest::addColumn<bool>("anchored");
+
+ auto addRow = [](const char *pattern, const char *string, bool matchesPathGlob, bool matchesNonPathGlob, bool anchored = true) {
+ QTest::addRow("%s@%s", pattern, string) << pattern << string << matchesPathGlob << matchesNonPathGlob << anchored;
+ };
+
+ addRow("*.html", "test.html", true, true);
+ addRow("*.html", "test.htm", false, false);
+ addRow("*bar*", "foobarbaz", true, true);
+ addRow("*", "Qt Rocks!", true, true);
+ addRow("*.h", "test.cpp", false, false);
+ addRow("*.???l", "test.html", true, true);
+ addRow("*?", "test.html", true, true);
+ addRow("*?ml", "test.html", true, true);
+ addRow("*[*]", "test.html", false, false);
+ addRow("*[?]","test.html", false, false);
+ addRow("*[?]ml","test.h?ml", true, true);
+ addRow("*[[]ml","test.h[ml", true, true);
+ addRow("*[]]ml","test.h]ml", true, true);
+ addRow("*.h[a-z]ml", "test.html", true, true);
+ addRow("*.h[A-Z]ml", "test.html", false, false);
+ addRow("*.h[A-Z]ml", "test.hTml", true, true);
+ addRow("*.h[!A-Z]ml", "test.hTml", false, false);
+ addRow("*.h[!A-Z]ml", "test.html", true, true);
+ addRow("*.h[!T]ml", "test.hTml", false, false);
+ addRow("*.h[!T]ml", "test.html", true, true);
+ addRow("*.h[!T]m[!L]", "test.htmL", false, false);
+ addRow("*.h[!T]m[!L]", "test.html", true, true);
+ addRow("*.h[][!]ml", "test.h]ml", true, true);
+ addRow("*.h[][!]ml", "test.h[ml", true, true);
+ addRow("*.h[][!]ml", "test.h!ml", true, true);
+
+ addRow("foo/*/bar", "foo/baz/bar", true, true);
+ addRow("foo/*/bar", "foo/fie/baz/bar", false, true);
+ addRow("foo?bar", "foo/bar", false, true);
+ addRow("foo/(*)/bar", "foo/baz/bar", false, false);
+ addRow("foo/(*)/bar", "foo/(baz)/bar", true, true);
+ addRow("foo/?/bar", "foo/Q/bar", true, true);
+ addRow("foo/?/bar", "foo/Qt/bar", false, false);
+ addRow("foo/(?)/bar", "foo/Q/bar", false, false);
+ addRow("foo/(?)/bar", "foo/(Q)/bar", true, true);
+
+ addRow("foo*bar", "foo/fie/baz/bar", false, true);
+ addRow("foo*bar", "foo bar", true, true);
+ addRow("foo*bar", "foo\tbar", true, true);
+ addRow("foo*bar", "foo\nbar", true, true);
+ addRow("foo*bar", "foo\r\nbar", true, true);
+
+ // different anchor modes
+ addRow("foo", "afoob", false, false, true);
+ addRow("foo", "afoob", true, true, false);
+
+ addRow("fie*bar", "foo/fie/baz/bar", false, false, true);
+ addRow("fie*bar", "foo/fie/baz/bar", false, true, false);
+
+#ifdef Q_OS_WIN
+ addRow("foo\\*\\bar", "foo\\baz\\bar", true, true);
+ addRow("foo\\*\\bar", "foo/baz/bar", true, false);
+ addRow("foo\\*\\bar", "foo/baz\\bar", true, false);
+ addRow("foo\\*\\bar", "foo\\fie\\baz\\bar", false, true);
+ addRow("foo\\*\\bar", "foo/fie/baz/bar", false, false);
+ addRow("foo/*/bar", "foo\\baz\\bar", true, false);
+ addRow("foo/*/bar", "foo/baz/bar", true, true);
+ addRow("foo/*/bar", "foo\\fie\\baz\\bar", false, false);
+ addRow("foo/*/bar", "foo/fie/baz/bar", false, true);
+ addRow("foo\\(*)\\bar", "foo\\baz\\bar", false, false);
+ addRow("foo\\(*)\\bar", "foo\\(baz)\\bar", true, true);
+ addRow("foo\\?\\bar", "foo\\Q\\bar", true, true);
+ addRow("foo\\?\\bar", "foo\\Qt\\bar", false, false);
+ addRow("foo\\(?)\\bar", "foo\\Q\\bar", false, false);
+ addRow("foo\\(?)\\bar", "foo\\(Q)\\bar", true, true);
+#endif
+}
+
+void tst_QRegularExpression::wildcard()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, string);
+ QFETCH(bool, matchesPathGlob);
+ QFETCH(bool, matchesNonPathGlob);
+ QFETCH(bool, anchored);
+
+ QRegularExpression::WildcardConversionOptions options = {};
+ if (!anchored)
+ options |= QRegularExpression::UnanchoredWildcardConversion;
+
+ {
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern, options));
+ QCOMPARE(string.contains(re), matchesPathGlob);
+ }
+ {
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern, options | QRegularExpression::NonPathWildcardConversion));
+ QCOMPARE(string.contains(re), matchesNonPathGlob);
+ }
+}
+
+void tst_QRegularExpression::testInvalidWildcard_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<bool>("isValid");
+
+ QTest::newRow("valid []") << "[abc]" << true;
+ QTest::newRow("valid ending ]") << "abc]" << true;
+ QTest::newRow("invalid [") << "[abc" << false;
+ QTest::newRow("ending [") << "abc[" << false;
+ QTest::newRow("ending [^") << "abc[^" << false;
+ QTest::newRow("ending [\\") << "abc[\\" << false;
+ QTest::newRow("ending []") << "abc[]" << false;
+ QTest::newRow("ending [[") << "abc[[" << false;
+}
+
+void tst_QRegularExpression::testInvalidWildcard()
+{
+ QFETCH(QString, pattern);
+ QFETCH(bool, isValid);
+
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
+ QCOMPARE(re.isValid(), isValid);
+}
+
+QTEST_APPLESS_MAIN(tst_QRegularExpression)
+
+#include "tst_qregularexpression.moc"
diff --git a/tests/auto/corelib/tools/qstring/.gitignore b/tests/auto/corelib/text/qstring/.gitignore
index c2ea8d0336..c2ea8d0336 100644
--- a/tests/auto/corelib/tools/qstring/.gitignore
+++ b/tests/auto/corelib/text/qstring/.gitignore
diff --git a/tests/auto/corelib/text/qstring/CMakeLists.txt b/tests/auto/corelib/text/qstring/CMakeLists.txt
new file mode 100644
index 0000000000..80917554d2
--- /dev/null
+++ b/tests/auto/corelib/text/qstring/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstring LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+if(NOT QT_FEATURE_doubleconversion AND NOT QT_FEATURE_system_doubleconversion)
+ list(APPEND tst_qstring_extra_defines QT_NO_DOUBLECONVERSION)
+endif()
+
+if(APPLE)
+ list(APPEND tst_qstring_extra_libraries ${FWFoundation})
+ list(APPEND tst_qstring_extra_sources tst_qstring_mac.mm)
+endif()
+if(WASM)
+ list(APPEND tst_qstring_extra_sources tst_qstring_wasm.cpp)
+endif()
+
+foreach(test tst_qstring tst_qstring_restricted_ascii tst_qstring_no_cast_from_ascii)
+ qt_internal_add_test(${test}
+ NO_BATCH
+ SOURCES
+ tst_qstring.cpp
+ ${tst_qstring_extra_sources}
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+ ${tst_qstring_extra_libraries}
+ DEFINES
+ ${tst_qstring_extra_defines}
+ )
+endforeach()
+
+qt_internal_extend_target(tst_qstring_restricted_ascii
+ DEFINES
+ QT_RESTRICTED_CAST_FROM_ASCII
+ tst_QString=tst_QString_restricted_ascii
+)
+
+qt_internal_extend_target(tst_qstring_no_cast_from_ascii
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ tst_QString=tst_QString_no_cast_from_ascii
+)
diff --git a/tests/auto/corelib/text/qstring/double_data.h b/tests/auto/corelib/text/qstring/double_data.h
new file mode 100644
index 0000000000..712ed11563
--- /dev/null
+++ b/tests/auto/corelib/text/qstring/double_data.h
@@ -0,0 +1,9998 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+struct SprintfDoubleData
+{
+ const char *fmt;
+ const char *expected;
+ int bytes[8];
+};
+
+static const SprintfDoubleData g_sprintf_double_data[] = {
+ { "%'1g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'3g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'50g", "00000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'.0g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'3.0g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'50.0g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'.1g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'1.1g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'50.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'.3g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'1.3g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'3.3g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'.50g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'1.50g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'3.50g", "000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'50.50g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'1G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'3G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'50G", "00000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'.0G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'3.0G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'50.0G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'.1G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'1.1G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'50.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'.3G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'1.3G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'3.3G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'.50G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-'1.50G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0'3.50G", "000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-'50.50G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'.0g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'3.0g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'50.0g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'1.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'50.1g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'1.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'3.3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'1.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'3.50g", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'50.50g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'.0G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'3.0G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'50.0G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'1.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'50.1G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'1.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'3.3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%+'.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%-+'1.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0+'3.50G", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0-+'50.50G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '3g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '.0g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '3.0g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '50.0g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '1.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '50.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '.3g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '1.3g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '3.3g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '.50g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '1.50g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '3.50g", " 00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '50.50g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '3G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '.0G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '3.0G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '50.0G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '1.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '50.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '.3G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '1.3G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '3.3G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% '.50G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- '1.50G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 '3.50G", " 00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- '50.50G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'.0g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'3.0g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'50.0g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'1.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'50.1g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'1.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'3.3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'1.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'3.50g", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'50.50g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'.0G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'3.0G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'50.0G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'1.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'50.1G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'1.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'3.3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "% +'.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%- +'1.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0 +'3.50G", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%0- +'50.50G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'1g", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'3g", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'.0g", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'3.0g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'50.0g", "0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'.1g", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'1.1g", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'50.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'.3g", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'1.3g", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'3.3g", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'1.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'3.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'50.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'1G", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'3G", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'.0G", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'3.0G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'50.0G", "0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'.1G", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'1.1G", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'50.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'.3G", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'1.3G", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'3.3G", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#'.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-'1.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0'3.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-'50.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'1g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'3g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'3.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'50.0g", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'1.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'50.1g", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'1.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'3.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'1.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'3.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'50.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'1G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'3G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'3.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'50.0G", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'1.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'50.1G", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'1.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'3.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#+'.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#-+'1.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0+'3.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0-+'50.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '1g", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '3g", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '.0g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '3.0g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '50.0g", " 0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '1.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '50.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '.3g", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '1.3g", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '3.3g", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '1.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '3.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '50.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '1G", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '3G", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '.0G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '3.0G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '50.0G", " 0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '1.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '50.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '.3G", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '1.3G", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '3.3G", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# '.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- '1.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 '3.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- '50.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'1g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'3g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'3.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'50.0g", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'1.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'50.1g", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'1.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'3.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'1.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'3.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'50.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'1G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'3G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'3.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'50.0G", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'1.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'50.1G", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'1.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'3.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%# +'.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#- +'1.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0 +'3.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%#0- +'50.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { "%'1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'3.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'50.0g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'1.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'1.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'3.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'1.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'3.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'50.50g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'3.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'50.0G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'1.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'1.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'3.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-'1.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0'3.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-'50.50G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%+'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%-+'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0+'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0-+'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '3.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '50.0g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '1.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '1.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '3.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '1.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '3.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '50.50g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '3.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '50.0G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '1.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '1.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '3.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% '.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- '1.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 '3.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- '50.50G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "% +'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%- +'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0 +'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%0- +'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'3.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'50.0g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'1.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'1.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'3.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'1.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'3.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'50.50g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'3.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'50.0G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'1.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'1.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'3.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#'.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-'1.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0'3.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-'50.50G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#+'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#-+'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0+'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0-+'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '3.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '50.0g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '1.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '1.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '3.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '1.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '3.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '50.50g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '3.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '50.0G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '1.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '1.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '3.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# '.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- '1.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 '3.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- '50.50G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%# +'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#- +'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0 +'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%#0- +'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
+ { "%'1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'3.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'50.0g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'1.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'1.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'3.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'1.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'3.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'50.50g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'3.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'50.0G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'1.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'1.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'3.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-'1.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0'3.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-'50.50G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%+'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%-+'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0+'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0-+'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '3.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '50.0g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '1.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '1.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '3.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '1.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '3.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '50.50g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '3.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '50.0G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '1.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '1.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '3.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% '.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- '1.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 '3.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- '50.50G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "% +'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%- +'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0 +'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%0- +'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'3.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'50.0g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'1.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'1.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'3.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'1.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'3.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'50.50g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'3.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'50.0G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'1.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'1.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'3.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#'.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-'1.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0'3.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-'50.50G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#+'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#-+'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0+'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0-+'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '3.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '50.0g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '1.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '1.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '3.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '1.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '3.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '50.50g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '3.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '50.0G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '1.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '1.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '3.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# '.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- '1.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 '3.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- '50.50G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%# +'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#- +'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0 +'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%#0- +'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
+ { "%'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%+'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%-+'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0+'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0-+'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% '.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- '1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 '3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- '50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "% +'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%- +'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0 +'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%0- +'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#+'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#-+'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0+'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0-+'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# '.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- '1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 '3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- '50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%# +'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#- +'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0 +'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%#0- +'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
+ { "%'1g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'3g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'50g", "00000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'.0g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'3.0g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'50.0g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'.1g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'1.1g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'50.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'.3g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'1.3g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'3.3g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'.50g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'1.50g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'3.50g", "001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'50.50g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'1G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'3G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'50G", "00000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'.0G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'3.0G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'50.0G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'.1G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'1.1G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'50.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'.3G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'1.3G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'3.3G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'.50G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-'1.50G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0'3.50G", "001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-'50.50G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'.0g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'3.0g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'50.0g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'1.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'50.1g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'1.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'3.3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'1.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'3.50g", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'50.50g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'.0G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'3.0G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'50.0G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'1.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'50.1G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'1.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'3.3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%+'.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%-+'1.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0+'3.50G", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0-+'50.50G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '3g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '.0g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '3.0g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '50.0g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '1.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '50.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '.3g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '1.3g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '3.3g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '.50g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '1.50g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '3.50g", " 01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '50.50g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '3G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '.0G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '3.0G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '50.0G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '1.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '50.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '.3G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '1.3G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '3.3G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% '.50G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- '1.50G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 '3.50G", " 01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- '50.50G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'.0g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'3.0g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'50.0g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'1.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'50.1g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'1.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'3.3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'1.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'3.50g", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'50.50g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'.0G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'3.0G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'50.0G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'1.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'50.1G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'1.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'3.3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "% +'.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%- +'1.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0 +'3.50G", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%0- +'50.50G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'1g", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'3g", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'.0g", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'3.0g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'50.0g", "1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'.1g", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'1.1g", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'50.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'.3g", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'1.3g", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'3.3g", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'1.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'3.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'50.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'1G", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'3G", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'.0G", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'3.0G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'50.0G", "1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'.1G", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'1.1G", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'50.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'.3G", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'1.3G", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'3.3G", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#'.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-'1.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0'3.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-'50.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'1g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'3g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'3.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'50.0g", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'1.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'50.1g", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'1.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'3.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'1.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'3.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'50.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'1G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'3G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'3.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'50.0G", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'1.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'50.1G", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'1.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'3.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#+'.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#-+'1.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0+'3.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0-+'50.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '1g", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '3g", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '.0g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '3.0g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '50.0g", " 1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '1.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '50.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '.3g", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '1.3g", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '3.3g", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '1.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '3.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '50.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '1G", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '3G", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '.0G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '3.0G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '50.0G", " 1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '1.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '50.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '.3G", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '1.3G", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '3.3G", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# '.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- '1.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 '3.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- '50.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'1g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'3g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'3.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'50.0g", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'1.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'50.1g", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'1.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'3.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'1.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'3.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'50.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'1G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'3G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'3.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'50.0G", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'1.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'50.1G", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'1.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'3.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%# +'.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#- +'1.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0 +'3.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%#0- +'50.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
+ { "%'1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-'1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0'3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-'50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%+'.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%-+'1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0+'3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0-+'50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% '.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- '1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 '3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- '50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "% +'.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%- +'1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0 +'3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%0- +'50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#'.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-'1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0'3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-'50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#+'.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#-+'1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0+'3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0-+'50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# '.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- '1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 '3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- '50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%# +'.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#- +'1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0 +'3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%#0- +'50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
+ { "%'1g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'3g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'50g", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'.0g", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'3.0g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'50.0g", "2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'.1g", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'1.1g", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'50.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'1.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'3.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'1.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'3.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'50.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'1G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'3G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'50G", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'.0G", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'3.0G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'50.0G", "2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'.1G", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'1.1G", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'50.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'1.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'3.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-'1.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0'3.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-'50.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'.0g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'3.0g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'50.0g", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'1.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'50.1g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'.0G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'3.0G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'50.0G", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'1.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'50.1G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%+'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%-+'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0+'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0-+'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '1g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '3g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '.0g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '3.0g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '50.0g", " 2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '1.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '50.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '1.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '3.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '1.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '3.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '50.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '1G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '3G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '.0G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '3.0G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '50.0G", " 2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '1.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '50.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '1.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '3.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% '.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- '1.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 '3.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- '50.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'.0g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'3.0g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'50.0g", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'1.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'50.1g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'.0G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'3.0G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'50.0G", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'1.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'50.1G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "% +'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%- +'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0 +'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%0- +'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'1g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'3g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'.0g", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'3.0g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'50.0g", "2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'.1g", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'1.1g", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'50.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'1.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'3.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'1.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'3.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'50.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'1G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'3G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'.0G", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'3.0G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'50.0G", "2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'.1G", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'1.1G", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'50.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'1.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'3.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#'.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-'1.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0'3.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-'50.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'3.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'50.0g", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'1.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'50.1g", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'3.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'50.0G", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'1.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'50.1G", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#+'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#-+'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0+'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0-+'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '1g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '3g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '.0g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '3.0g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '50.0g", " 2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '1.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '50.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '1.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '3.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '1.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '3.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '50.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '1G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '3G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '.0G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '3.0G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '50.0G", " 2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '1.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '50.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '1.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '3.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# '.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- '1.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 '3.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- '50.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'3.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'50.0g", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'1.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'50.1g", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'3.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'50.0G", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'1.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'50.1G", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%# +'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#- +'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0 +'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%#0- +'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
+ { "%'1g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'3g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'3.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'50.0g", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'1.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'1.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'3.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'1.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'3.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'50.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'1G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'3G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'3.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'50.0G", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'1.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'1.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'3.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-'1.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0'3.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-'50.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%+'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%-+'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0+'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0-+'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '1g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '3g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '3.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '50.0g", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '1.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '1.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '3.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '1.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '3.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '50.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '1G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '3G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '3.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '50.0G", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '1.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '1.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '3.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% '.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- '1.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 '3.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- '50.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "% +'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%- +'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0 +'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%0- +'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'1g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'3g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'50g", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'3.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'50.0g", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'1.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'1.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'3.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'1.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'3.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'50.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'1G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'3G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'50G", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'3.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'50.0G", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'1.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'1.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'3.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#'.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-'1.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0'3.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-'50.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#+'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#-+'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0+'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0-+'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '1g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '3g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '3.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '50.0g", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '1.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '1.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '3.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '1.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '3.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '50.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '1G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '3G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '3.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '50.0G", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '1.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '1.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '3.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# '.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- '1.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 '3.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- '50.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%# +'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#- +'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0 +'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%#0- +'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
+ { "%'1g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'3g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'50g", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'.0g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'3.0g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'50.0g", "2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'.1g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'1.1g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'50.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'1.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'3.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'.50g", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'1.50g", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'3.50g", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'50.50g", "1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'1G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'3G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'50G", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'.0G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'3.0G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'50.0G", "2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'.1G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'1.1G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'50.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'1.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'3.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'.50G", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-'1.50G", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0'3.50G", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-'50.50G", "1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'3.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'50.0g", "+2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'1.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'50.1g", " +2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'1.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'3.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'50.50g", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'3.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'50.0G", "+2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'1.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'50.1G", " +2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%+'.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%-+'1.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0+'3.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0-+'50.50G", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '1g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '3g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '.0g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '3.0g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '50.0g", " 2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '1.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '50.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '1.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '3.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '.50g", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '1.50g", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '3.50g", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '50.50g", " 1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '1G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '3G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '.0G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '3.0G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '50.0G", " 2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '1.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '50.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '1.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '3.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% '.50G", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- '1.50G", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 '3.50G", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- '50.50G", " 1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'3.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'50.0g", "+2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'1.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'50.1g", " +2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'1.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'3.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'50.50g", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'3.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'50.0G", "+2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'1.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'50.1G", " +2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "% +'.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%- +'1.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0 +'3.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%0- +'50.50G", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'1g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'3g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'50g", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'.0g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'3.0g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'50.0g", "2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'.1g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'1.1g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'50.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'1.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'3.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'1.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'3.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'50.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'1G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'3G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'50G", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'.0G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'3.0G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'50.0G", "2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'.1G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'1.1G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'50.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'1.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'3.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#'.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-'1.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0'3.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-'50.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'3.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'50.0g", "+2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'1.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'50.1g", " +2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'1.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'3.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'50.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'3.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'50.0G", "+2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'1.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'50.1G", " +2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#+'.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#-+'1.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0+'3.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0-+'50.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '1g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '3g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '.0g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '3.0g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '50.0g", " 2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '1.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '50.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '1.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '3.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '1.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '3.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '50.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '1G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '3G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '.0G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '3.0G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '50.0G", " 2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '1.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '50.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '1.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '3.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# '.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- '1.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 '3.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- '50.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'3.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'50.0g", "+2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'1.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'50.1g", " +2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'1.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'3.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'50.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'3.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'50.0G", "+2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'1.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'50.1G", " +2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%# +'.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#- +'1.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0 +'3.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%#0- +'50.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
+ { "%'1g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'3g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'50g", "0000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'.0g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'3.0g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'50.0g", "2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'.1g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'1.1g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'50.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'1.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'3.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'.50g", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'1.50g", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'3.50g", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'50.50g", "1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'1G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'3G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'50G", "0000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'.0G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'3.0G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'50.0G", "2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'.1G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'1.1G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'50.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'1.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'3.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'.50G", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-'1.50G", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0'3.50G", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-'50.50G", "1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'3.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'50.0g", "+2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'1.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'50.1g", " +2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'1.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'3.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'50.50g", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'3.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'50.0G", "+2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'1.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'50.1G", " +2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%+'.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%-+'1.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0+'3.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0-+'50.50G", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '1g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '3g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '50g", " 000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '.0g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '3.0g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '50.0g", " 2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '1.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '50.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '1.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '3.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '.50g", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '1.50g", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '3.50g", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '50.50g", " 1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '1G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '3G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '50G", " 000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '.0G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '3.0G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '50.0G", " 2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '1.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '50.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '1.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '3.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% '.50G", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- '1.50G", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 '3.50G", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- '50.50G", " 1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'3.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'50.0g", "+2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'1.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'50.1g", " +2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'1.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'3.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'50.50g", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'3.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'50.0G", "+2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'1.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'50.1G", " +2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "% +'.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%- +'1.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0 +'3.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%0- +'50.50G", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'1g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'3g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'.0g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'3.0g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'50.0g", "2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'.1g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'1.1g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'50.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'1.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'3.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'1.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'3.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'50.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'1G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'3G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'.0G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'3.0G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'50.0G", "2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'.1G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'1.1G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'50.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'1.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'3.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#'.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-'1.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0'3.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-'50.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'3.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'50.0g", "+2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'1.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'50.1g", " +2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'1.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'3.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'50.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'3.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'50.0G", "+2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'1.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'50.1G", " +2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#+'.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#-+'1.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0+'3.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0-+'50.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '1g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '3g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '.0g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '3.0g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '50.0g", " 2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '1.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '50.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '1.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '3.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '1.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '3.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '50.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '1G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '3G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '.0G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '3.0G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '50.0G", " 2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '1.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '50.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '1.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '3.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# '.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- '1.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 '3.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- '50.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'3.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'50.0g", "+2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'1.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'50.1g", " +2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'1.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'3.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'50.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'3.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'50.0G", "+2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'1.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'50.1G", " +2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%# +'.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#- +'1.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0 +'3.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%#0- +'50.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
+ { "%'1g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'3g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'50g", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'3.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'50.0g", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'1.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'1.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'3.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'1.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'3.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'50.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'1G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'3G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'50G", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'3.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'50.0G", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'1.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'1.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'3.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-'1.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0'3.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-'50.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%+'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%-+'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0+'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0-+'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '1g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '3g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '3.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '50.0g", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '1.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '1.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '3.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '1.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '3.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '50.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '1G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '3G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '3.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '50.0G", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '1.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '1.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '3.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% '.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- '1.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 '3.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- '50.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "% +'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%- +'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0 +'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%0- +'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'1g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'3g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'3.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'50.0g", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'1.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'1.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'3.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'1.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'3.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'50.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'1G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'3G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'3.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'50.0G", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'1.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'1.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'3.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#'.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-'1.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0'3.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-'50.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#+'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#-+'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0+'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0-+'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '1g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '3g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '3.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '50.0g", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '1.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '1.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '3.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '1.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '3.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '50.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '1G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '3G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '3.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '50.0G", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '1.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '1.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '3.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# '.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- '1.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 '3.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- '50.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%# +'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#- +'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0 +'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%#0- +'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
+ { "%'1g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'3g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'50g", "0000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'.0g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'3.0g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'50.0g", "2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'.1g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'1.1g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'50.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'1.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'3.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'1.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'3.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'50.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'1G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'3G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'50G", "0000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'.0G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'3.0G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'50.0G", "2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'.1G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'1.1G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'50.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'1.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'3.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-'1.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0'3.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-'50.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'3.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'50.0g", "+2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'1.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'50.1g", " +2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'3.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'50.0G", "+2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'1.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'50.1G", " +2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%+'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%-+'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0+'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0-+'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '1g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '3g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '50g", " 000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '.0g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '3.0g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '50.0g", " 2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '1.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '50.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '1.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '3.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '1.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '3.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '50.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '1G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '3G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '50G", " 000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '.0G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '3.0G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '50.0G", " 2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '1.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '50.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '1.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '3.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% '.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- '1.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 '3.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- '50.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'3.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'50.0g", "+2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'1.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'50.1g", " +2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'3.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'50.0G", "+2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'1.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'50.1G", " +2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "% +'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%- +'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0 +'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%0- +'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'1g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'3g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'.0g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'3.0g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'50.0g", "2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'.1g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'1.1g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'50.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'1.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'3.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'1.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'3.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'50.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'1G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'3G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'.0G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'3.0G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'50.0G", "2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'.1G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'1.1G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'50.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'1.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'3.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#'.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-'1.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0'3.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-'50.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'3.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'50.0g", "+2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'1.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'50.1g", " +2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'3.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'50.0G", "+2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'1.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'50.1G", " +2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#+'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#-+'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0+'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0-+'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '1g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '3g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '.0g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '3.0g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '50.0g", " 2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '1.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '50.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '1.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '3.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '1.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '3.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '50.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '1G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '3G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '.0G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '3.0G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '50.0G", " 2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '1.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '50.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '1.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '3.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# '.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- '1.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 '3.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- '50.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'3.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'50.0g", "+2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'1.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'50.1g", " +2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'3.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'50.0G", "+2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'1.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'50.1G", " +2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%# +'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#- +'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0 +'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%#0- +'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
+ { "%'1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'50g", "000000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'3.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'50.0g", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'1.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'.3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'1.3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'3.3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'1.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'3.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'50.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'50G", "000000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'3.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'50.0G", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'1.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'.3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'1.3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'3.3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-'1.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0'3.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-'50.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'50g", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'1.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'3.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'1.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'3.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'50.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'50G", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'1.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'3.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%+'.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%-+'1.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0+'3.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0-+'50.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '50g", " 00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '3.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '50.0g", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '1.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '.3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '1.3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '3.3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '1.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '3.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '50.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '50G", " 00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '3.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '50.0G", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '1.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '.3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '1.3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '3.3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% '.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- '1.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 '3.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- '50.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'1.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'3.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'1.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'3.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'50.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'1.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'3.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "% +'.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%- +'1.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0 +'3.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%0- +'50.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'1g", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'3g", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'50g", "0000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'3.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'50.0g", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'1.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'.3g", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'1.3g", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'3.3g", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'1.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'3.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'50.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'1G", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'3G", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'50G", "0000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'3.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'50.0G", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'1.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'.3G", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'1.3G", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'3.3G", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#'.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-'1.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0'3.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-'50.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'1g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'3g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'1.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'3.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'1.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'3.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'50.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'1G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'3G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'1.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'3.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#+'.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#-+'1.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0+'3.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0-+'50.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '1g", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '3g", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '3.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '50.0g", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '1.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '.3g", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '1.3g", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '3.3g", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '1.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '3.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '50.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '1G", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '3G", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '3.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '50.0G", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '1.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '.3G", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '1.3G", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '3.3G", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# '.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- '1.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 '3.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- '50.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'1g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'3g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'1.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'3.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'1.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'3.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'50.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'1G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'3G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'1.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'3.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%# +'.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#- +'1.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0 +'3.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%#0- +'50.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
+ { "%'1g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'.0g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'3.0g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'50.0g", "1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'.1g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'1.1g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'50.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'.3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'1.3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'3.3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'1.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'3.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'50.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'1G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'.0G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'3.0G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'50.0G", "1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'.1G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'1.1G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'50.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'.3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'1.3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'3.3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-'1.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0'3.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-'50.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'3.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'50.0g", "+1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'1.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'50.1g", " +1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'1.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'3.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'3.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'50.0G", "+1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'1.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'50.1G", " +1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'1.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'3.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%+'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%-+'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0+'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0-+'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '.0g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '3.0g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '50.0g", " 1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '1.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '50.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '.3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '1.3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '3.3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '1.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '3.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '50.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '.0G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '3.0G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '50.0G", " 1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '1.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '50.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '.3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '1.3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '3.3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% '.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- '1.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 '3.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- '50.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'3.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'50.0g", "+1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'1.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'50.1g", " +1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'1.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'3.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'3.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'50.0G", "+1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'1.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'50.1G", " +1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'1.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'3.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "% +'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%- +'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0 +'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%0- +'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'1g", "1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'3g", "1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'.0g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'3.0g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'50.0g", "1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'.1g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'1.1g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'50.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'.3g", "1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'1.3g", "1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'3.3g", "1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'1.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'3.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'50.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'1G", "1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'3G", "1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'.0G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'3.0G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'50.0G", "1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'.1G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'1.1G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'50.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'.3G", "1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'1.3G", "1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'3.3G", "1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#'.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-'1.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0'3.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-'50.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'1g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'3g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'3.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'50.0g", "+1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'1.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'50.1g", " +1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'1.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'3.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'1G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'3G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'3.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'50.0G", "+1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'1.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'50.1G", " +1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'1.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'3.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#+'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#-+'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0+'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0-+'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '1g", " 1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '3g", " 1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '.0g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '3.0g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '50.0g", " 1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '1.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '50.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '.3g", " 1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '1.3g", " 1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '3.3g", " 1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '1.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '3.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '50.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '1G", " 1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '3G", " 1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '.0G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '3.0G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '50.0G", " 1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '1.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '50.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '.3G", " 1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '1.3G", " 1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '3.3G", " 1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# '.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- '1.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 '3.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- '50.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'1g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'3g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'3.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'50.0g", "+1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'1.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'50.1g", " +1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'1.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'3.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'1G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'3G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'3.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'50.0G", "+1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'1.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'50.1G", " +1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'1.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'3.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%# +'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#- +'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0 +'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%#0- +'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
+ { "%'1g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'3g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'.0g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'3.0g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'50.0g", "1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'.1g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'1.1g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'50.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'.3g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'1.3g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'3.3g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'.50g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'1.50g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'3.50g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'50.50g", "100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'1G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'3G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'.0G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'3.0G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'50.0G", "1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'.1G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'1.1G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'50.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'.3G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'1.3G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'3.3G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'.50G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-'1.50G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0'3.50G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-'50.50G", "100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'1g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'3g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'3.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'50.0g", "+1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'1.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'50.1g", " +1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'1.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'3.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'1.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'3.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'50.50g", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'1G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'3G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'3.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'50.0G", "+1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'1.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'50.1G", " +1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'1.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'3.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%+'.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%-+'1.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0+'3.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0-+'50.50G", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '1g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '3g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '.0g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '3.0g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '50.0g", " 1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '1.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '50.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '.3g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '1.3g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '3.3g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '.50g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '1.50g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '3.50g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '50.50g", " 100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '1G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '3G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '.0G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '3.0G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '50.0G", " 1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '1.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '50.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '.3G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '1.3G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '3.3G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% '.50G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- '1.50G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 '3.50G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- '50.50G", " 100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'1g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'3g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'3.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'50.0g", "+1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'1.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'50.1g", " +1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'1.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'3.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'1.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'3.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'50.50g", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'1G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'3G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'3.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'50.0G", "+1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'1.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'50.1G", " +1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'1.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'3.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "% +'.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%- +'1.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0 +'3.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%0- +'50.50G", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'1g", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'3g", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'50g", "000000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'.0g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'3.0g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'50.0g", "1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'.1g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'1.1g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'50.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'.3g", "1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'1.3g", "1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'3.3g", "1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'1.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'3.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'50.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'1G", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'3G", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'50G", "000000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'.0G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'3.0G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'50.0G", "1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'.1G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'1.1G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'50.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'.3G", "1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'1.3G", "1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'3.3G", "1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#'.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-'1.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0'3.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-'50.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'1g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'3g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'3.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'50.0g", "+1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'1.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'50.1g", " +1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'1.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'3.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'1.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'3.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'50.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'1G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'3G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'3.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'50.0G", "+1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'1.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'50.1G", " +1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'1.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'3.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#+'.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#-+'1.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0+'3.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0-+'50.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '1g", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '3g", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '.0g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '3.0g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '50.0g", " 1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '1.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '50.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '.3g", " 1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '1.3g", " 1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '3.3g", " 1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '1.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '3.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '50.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '1G", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '3G", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '.0G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '3.0G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '50.0G", " 1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '1.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '50.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '.3G", " 1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '1.3G", " 1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '3.3G", " 1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# '.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- '1.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 '3.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- '50.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'1g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'3g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'3.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'50.0g", "+1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'1.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'50.1g", " +1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'1.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'3.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'1.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'3.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'50.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'1G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'3G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'3.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'50.0G", "+1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'1.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'50.1G", " +1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'1.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'3.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%# +'.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#- +'1.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0 +'3.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%#0- +'50.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
+ { "%'1g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'3g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'50g", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'.0g", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'3.0g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'50.0g", "3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'.1g", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'1.1g", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'50.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'1.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'3.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'1.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'3.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'50.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'1G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'3G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'50G", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'.0G", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'3.0G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'50.0G", "3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'.1G", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'1.1G", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'50.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'1.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'3.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-'1.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0'3.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-'50.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'.0g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'3.0g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'50.0g", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'1.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'50.1g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'1.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'3.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'50.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'.0G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'3.0G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'50.0G", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'1.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'50.1G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%+'.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%-+'1.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0+'3.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0-+'50.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '1g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '3g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '.0g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '3.0g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '50.0g", " 3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '1.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '50.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '1.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '3.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '1.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '3.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '50.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '1G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '3G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '.0G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '3.0G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '50.0G", " 3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '1.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '50.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '1.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '3.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% '.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- '1.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 '3.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- '50.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'.0g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'3.0g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'50.0g", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'1.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'50.1g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'1.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'3.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'50.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'.0G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'3.0G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'50.0G", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'1.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'50.1G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "% +'.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%- +'1.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0 +'3.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%0- +'50.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'1g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'3g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'.0g", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'3.0g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'50.0g", "3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'.1g", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'1.1g", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'50.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'1.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'3.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'1.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'3.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'50.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'1G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'3G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'.0G", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'3.0G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'50.0G", "3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'.1G", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'1.1G", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'50.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'1.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'3.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#'.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-'1.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0'3.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-'50.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'3.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'50.0g", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'1.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'50.1g", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'1.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'3.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'50.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'3.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'50.0G", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'1.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'50.1G", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#+'.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#-+'1.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0+'3.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0-+'50.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '1g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '3g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '.0g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '3.0g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '50.0g", " 3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '1.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '50.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '1.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '3.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '1.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '3.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '50.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '1G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '3G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '.0G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '3.0G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '50.0G", " 3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '1.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '50.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '1.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '3.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# '.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- '1.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 '3.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- '50.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'3.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'50.0g", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'1.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'50.1g", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'1.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'3.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'50.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'3.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'50.0G", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'1.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'50.1G", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%# +'.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#- +'1.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0 +'3.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%#0- +'50.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
+ { "%'1g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'3g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'50g", "0000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'.0g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'3.0g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'50.0g", "3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'.1g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'1.1g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'50.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'1.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'3.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'1.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'3.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'50.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'1G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'3G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'50G", "0000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'.0G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'3.0G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'50.0G", "3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'.1G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'1.1G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'50.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'1.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'3.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-'1.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0'3.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-'50.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'3.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'50.0g", "+3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'1.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'50.1g", " +3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'3.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'50.0G", "+3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'1.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'50.1G", " +3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%+'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%-+'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0+'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0-+'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '1g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '3g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '50g", " 000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '.0g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '3.0g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '50.0g", " 3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '1.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '50.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '1.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '3.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '1.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '3.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '50.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '1G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '3G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '50G", " 000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '.0G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '3.0G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '50.0G", " 3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '1.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '50.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '1.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '3.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% '.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- '1.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 '3.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- '50.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'3.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'50.0g", "+3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'1.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'50.1g", " +3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'3.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'50.0G", "+3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'1.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'50.1G", " +3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "% +'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%- +'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0 +'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%0- +'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'1g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'3g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'50g", "0000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'.0g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'3.0g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'50.0g", "3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'.1g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'1.1g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'50.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'1.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'3.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'1.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'3.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'50.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'1G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'3G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'50G", "0000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'.0G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'3.0G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'50.0G", "3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'.1G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'1.1G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'50.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'1.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'3.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#'.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-'1.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0'3.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-'50.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'3.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'50.0g", "+3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'1.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'50.1g", " +3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'3.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'50.0G", "+3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'1.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'50.1G", " +3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#+'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#-+'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0+'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0-+'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '1g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '3g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '.0g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '3.0g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '50.0g", " 3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '1.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '50.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '1.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '3.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '1.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '3.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '50.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '1G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '3G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '.0G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '3.0G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '50.0G", " 3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '1.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '50.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '1.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '3.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# '.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- '1.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 '3.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- '50.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'3.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'50.0g", "+3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'1.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'50.1g", " +3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'3.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'50.0G", "+3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'1.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'50.1G", " +3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%# +'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#- +'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0 +'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%#0- +'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
+ { "%'1g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'3g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'50g", "0000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'.0g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'3.0g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'50.0g", "3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'.1g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'1.1g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'50.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'1.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'3.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'1.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'3.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'50.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'1G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'3G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'50G", "0000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'.0G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'3.0G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'50.0G", "3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'.1G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'1.1G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'50.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'1.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'3.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-'1.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0'3.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-'50.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'3.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'50.0g", "+3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'1.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'50.1g", " +3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'1.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'3.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'50.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'3.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'50.0G", "+3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'1.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'50.1G", " +3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%+'.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%-+'1.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0+'3.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0-+'50.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '1g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '3g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '50g", " 000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '.0g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '3.0g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '50.0g", " 3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '1.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '50.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '1.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '3.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '1.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '3.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '50.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '1G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '3G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '50G", " 000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '.0G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '3.0G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '50.0G", " 3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '1.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '50.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '1.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '3.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% '.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- '1.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 '3.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- '50.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'3.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'50.0g", "+3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'1.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'50.1g", " +3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'1.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'3.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'50.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'3.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'50.0G", "+3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'1.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'50.1G", " +3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "% +'.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%- +'1.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0 +'3.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%0- +'50.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'1g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'3g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'50g", "0000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'.0g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'3.0g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'50.0g", "3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'.1g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'1.1g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'50.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'1.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'3.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'1.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'3.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'50.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'1G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'3G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'50G", "0000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'.0G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'3.0G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'50.0G", "3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'.1G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'1.1G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'50.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'1.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'3.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#'.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-'1.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0'3.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-'50.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'3.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'50.0g", "+3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'1.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'50.1g", " +3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'1.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'3.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'50.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'3.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'50.0G", "+3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'1.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'50.1G", " +3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#+'.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#-+'1.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0+'3.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0-+'50.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '1g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '3g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '.0g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '3.0g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '50.0g", " 3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '1.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '50.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '1.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '3.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '1.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '3.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '50.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '1G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '3G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '.0G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '3.0G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '50.0G", " 3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '1.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '50.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '1.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '3.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# '.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- '1.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 '3.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- '50.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'3.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'50.0g", "+3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'1.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'50.1g", " +3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'1.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'3.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'50.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'3.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'50.0G", "+3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'1.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'50.1G", " +3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%# +'.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#- +'1.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0 +'3.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%#0- +'50.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
+ { "%'1g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'3g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'50g", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'.0g", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'3.0g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'50.0g", "3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'.1g", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'1.1g", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'50.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'1.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'3.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'1.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'3.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'50.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'1G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'3G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'50G", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'.0G", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'3.0G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'50.0G", "3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'.1G", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'1.1G", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'50.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'1.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'3.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-'1.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0'3.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-'50.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'.0g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'3.0g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'50.0g", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'1.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'50.1g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'.0G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'3.0G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'50.0G", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'1.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'50.1G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%+'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%-+'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0+'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0-+'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '1g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '3g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '.0g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '3.0g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '50.0g", " 3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '1.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '50.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '1.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '3.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '1.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '3.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '50.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '1G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '3G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '.0G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '3.0G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '50.0G", " 3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '1.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '50.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '1.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '3.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% '.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- '1.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 '3.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- '50.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'.0g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'3.0g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'50.0g", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'1.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'50.1g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'.0G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'3.0G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'50.0G", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'1.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'50.1G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "% +'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%- +'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0 +'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%0- +'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'1g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'3g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'.0g", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'3.0g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'50.0g", "3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'.1g", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'1.1g", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'50.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'1.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'3.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'1.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'3.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'50.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'1G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'3G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'.0G", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'3.0G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'50.0G", "3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'.1G", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'1.1G", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'50.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'1.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'3.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#'.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-'1.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0'3.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-'50.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'3.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'50.0g", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'1.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'50.1g", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'3.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'50.0G", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'1.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'50.1G", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#+'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#-+'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0+'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0-+'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '1g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '3g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '.0g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '3.0g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '50.0g", " 3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '1.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '50.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '1.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '3.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '1.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '3.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '50.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '1G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '3G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '.0G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '3.0G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '50.0G", " 3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '1.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '50.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '1.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '3.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# '.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- '1.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 '3.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- '50.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'3.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'50.0g", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'1.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'50.1g", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'3.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'50.0G", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'1.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'50.1G", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%# +'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#- +'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0 +'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%#0- +'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
+ { "%'1g", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'3g", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'50g", "000000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'.0g", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'3.0g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'50.0g", "1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'.1g", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'1.1g", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'50.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'1.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'3.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'1.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'3.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'50.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'1G", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'3G", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'50G", "000000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'.0G", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'3.0G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'50.0G", "1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'.1G", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'1.1G", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'50.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'1.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'3.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-'1.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0'3.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-'50.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'1g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'3g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'50g", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'.0g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'3.0g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'50.0g", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'1.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'50.1g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'1G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'3G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'50G", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'.0G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'3.0G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'50.0G", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'1.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'50.1G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%+'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%-+'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0+'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0-+'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '1g", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '3g", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '50g", " 00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '.0g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '3.0g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '50.0g", " 1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '1.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '50.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '1.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '3.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '1.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '3.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '50.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '1G", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '3G", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '50G", " 00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '.0G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '3.0G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '50.0G", " 1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '1.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '50.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '1.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '3.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% '.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- '1.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 '3.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- '50.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'1g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'3g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'.0g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'3.0g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'50.0g", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'1.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'50.1g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'1G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'3G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'.0G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'3.0G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'50.0G", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'1.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'50.1G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "% +'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%- +'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0 +'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%0- +'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'1g", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'3g", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'.0g", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'3.0g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'50.0g", "1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'.1g", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'1.1g", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'50.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'1.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'3.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'1.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'3.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'50.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'1G", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'3G", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'.0G", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'3.0G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'50.0G", "1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'.1G", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'1.1G", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'50.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'1.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'3.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#'.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-'1.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0'3.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-'50.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'1g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'3g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'3.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'50.0g", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'1.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'50.1g", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'1G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'3G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'3.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'50.0G", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'1.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'50.1G", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#+'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#-+'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0+'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0-+'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '1g", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '3g", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '.0g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '3.0g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '50.0g", " 1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '1.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '50.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '1.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '3.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '1.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '3.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '50.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '1G", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '3G", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '.0G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '3.0G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '50.0G", " 1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '1.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '50.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '1.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '3.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# '.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- '1.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 '3.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- '50.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'1g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'3g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'3.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'50.0g", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'1.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'50.1g", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'1G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'3G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'3.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'50.0G", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'1.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'50.1G", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%# +'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#- +'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0 +'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%#0- +'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
+ { "%'1g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'3g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'3.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'50.0g", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'1.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'1.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'3.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'1.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'3.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'50.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'1G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'3G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'3.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'50.0G", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'1.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'1.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'3.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-'1.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0'3.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-'50.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%+'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%-+'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0+'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0-+'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '1g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '3g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '3.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '50.0g", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '1.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '1.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '3.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '1.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '3.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '50.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '1G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '3G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '3.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '50.0G", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '1.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '1.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '3.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% '.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- '1.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 '3.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- '50.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "% +'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%- +'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0 +'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%0- +'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'1g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'3g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'50g", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'3.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'50.0g", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'1.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'1.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'3.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'1.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'3.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'50.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'1G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'3G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'50G", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'3.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'50.0G", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'1.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'1.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'3.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#'.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-'1.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0'3.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-'50.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#+'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#-+'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0+'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0-+'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '1g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '3g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '3.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '50.0g", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '1.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '1.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '3.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '1.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '3.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '50.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '1G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '3G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '3.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '50.0G", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '1.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '1.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '3.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# '.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- '1.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 '3.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- '50.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%# +'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#- +'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0 +'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%#0- +'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
+ { "%'1g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'3g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'3.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'50.0g", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'1.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'1.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'3.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'1.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'3.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'50.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'1G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'3G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'3.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'50.0G", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'1.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'1.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'3.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-'1.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0'3.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-'50.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%+'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%-+'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0+'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0-+'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '1g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '3g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '3.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '50.0g", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '1.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '1.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '3.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '1.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '3.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '50.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '1G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '3G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '3.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '50.0G", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '1.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '1.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '3.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% '.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- '1.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 '3.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- '50.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "% +'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%- +'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0 +'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%0- +'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'1g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'3g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'50g", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'3.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'50.0g", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'1.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'1.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'3.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'1.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'3.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'50.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'1G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'3G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'50G", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'3.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'50.0G", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'1.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'1.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'3.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#'.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-'1.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0'3.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-'50.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#+'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#-+'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0+'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0-+'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '1g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '3g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '3.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '50.0g", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '1.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '1.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '3.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '1.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '3.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '50.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '1G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '3G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '3.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '50.0G", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '1.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '1.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '3.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# '.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- '1.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 '3.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- '50.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%# +'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#- +'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0 +'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%#0- +'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
+ { "%'1g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'3g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'50g", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'.0g", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'3.0g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'50.0g", "2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'.1g", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'1.1g", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'50.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'.3g", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'1.3g", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'3.3g", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'1.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'3.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'50.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'1G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'3G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'50G", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'.0G", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'3.0G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'50.0G", "2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'.1G", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'1.1G", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'50.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'.3G", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'1.3G", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'3.3G", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-'1.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0'3.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-'50.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'.0g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'3.0g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'50.0g", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'1.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'50.1g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'1.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'3.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'.0G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'3.0G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'50.0G", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'1.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'50.1G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'1.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'3.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%+'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%-+'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0+'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0-+'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '1g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '3g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '.0g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '3.0g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '50.0g", " 2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '1.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '50.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '.3g", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '1.3g", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '3.3g", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '1.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '3.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '50.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '1G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '3G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '.0G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '3.0G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '50.0G", " 2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '1.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '50.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '.3G", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '1.3G", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '3.3G", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% '.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- '1.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 '3.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- '50.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'.0g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'3.0g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'50.0g", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'1.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'50.1g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'1.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'3.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'.0G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'3.0G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'50.0G", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'1.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'50.1G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'1.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'3.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "% +'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%- +'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0 +'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%0- +'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'1g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'3g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'.0g", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'3.0g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'50.0g", "2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'.1g", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'1.1g", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'50.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'.3g", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'1.3g", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'3.3g", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'1.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'3.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'50.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'1G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'3G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'.0G", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'3.0G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'50.0G", "2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'.1G", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'1.1G", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'50.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'.3G", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'1.3G", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'3.3G", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#'.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-'1.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0'3.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-'50.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'3.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'50.0g", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'1.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'50.1g", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'1.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'3.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'3.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'50.0G", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'1.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'50.1G", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'1.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'3.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#+'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#-+'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0+'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0-+'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '1g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '3g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '.0g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '3.0g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '50.0g", " 2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '1.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '50.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '.3g", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '1.3g", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '3.3g", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '1.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '3.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '50.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '1G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '3G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '.0G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '3.0G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '50.0G", " 2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '1.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '50.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '.3G", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '1.3G", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '3.3G", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# '.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- '1.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 '3.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- '50.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'3.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'50.0g", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'1.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'50.1g", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'1.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'3.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'3.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'50.0G", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'1.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'50.1G", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'1.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'3.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%# +'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#- +'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0 +'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%#0- +'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
+ { "%'1g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'3g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'50g", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'.0g", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'3.0g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'50.0g", "1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'.1g", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'1.1g", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'50.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'1.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'3.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'1.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'3.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'50.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'1G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'3G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'50G", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'.0G", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'3.0G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'50.0G", "1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'.1G", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'1.1G", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'50.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'1.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'3.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-'1.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0'3.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-'50.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'.0g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'3.0g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'50.0g", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'1.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'50.1g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'.0G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'3.0G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'50.0G", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'1.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'50.1G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%+'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%-+'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0+'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0-+'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '1g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '3g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '.0g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '3.0g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '50.0g", " 1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '1.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '50.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '1.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '3.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '1.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '3.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '50.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '1G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '3G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '.0G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '3.0G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '50.0G", " 1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '1.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '50.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '1.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '3.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% '.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- '1.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 '3.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- '50.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'.0g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'3.0g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'50.0g", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'1.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'50.1g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'.0G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'3.0G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'50.0G", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'1.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'50.1G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "% +'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%- +'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0 +'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%0- +'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'1g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'3g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'.0g", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'3.0g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'50.0g", "1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'.1g", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'1.1g", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'50.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'1.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'3.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'1.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'3.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'50.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'1G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'3G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'.0G", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'3.0G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'50.0G", "1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'.1G", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'1.1G", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'50.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'1.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'3.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#'.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-'1.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0'3.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-'50.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'3.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'50.0g", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'1.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'50.1g", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'3.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'50.0G", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'1.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'50.1G", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#+'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#-+'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0+'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0-+'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '1g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '3g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '.0g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '3.0g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '50.0g", " 1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '1.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '50.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '1.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '3.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '1.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '3.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '50.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '1G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '3G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '.0G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '3.0G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '50.0G", " 1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '1.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '50.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '1.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '3.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# '.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- '1.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 '3.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- '50.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'3.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'50.0g", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'1.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'50.1g", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'3.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'50.0G", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'1.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'50.1G", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%# +'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#- +'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0 +'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%#0- +'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
+ { "%'1g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'3g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'50g", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'.0g", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'3.0g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'50.0g", "1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'.1g", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'1.1g", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'50.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'1.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'3.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'1.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'3.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'50.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'1G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'3G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'50G", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'.0G", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'3.0G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'50.0G", "1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'.1G", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'1.1G", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'50.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'1.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'3.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-'1.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0'3.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-'50.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'.0g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'3.0g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'50.0g", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'1.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'50.1g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'.0G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'3.0G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'50.0G", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'1.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'50.1G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%+'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%-+'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0+'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0-+'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '1g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '3g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '.0g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '3.0g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '50.0g", " 1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '1.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '50.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '1.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '3.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '1.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '3.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '50.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '1G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '3G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '.0G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '3.0G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '50.0G", " 1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '1.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '50.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '1.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '3.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% '.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- '1.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 '3.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- '50.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'.0g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'3.0g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'50.0g", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'1.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'50.1g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'.0G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'3.0G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'50.0G", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'1.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'50.1G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "% +'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%- +'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0 +'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%0- +'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'1g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'3g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'.0g", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'3.0g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'50.0g", "1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'.1g", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'1.1g", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'50.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'1.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'3.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'1.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'3.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'50.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'1G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'3G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'.0G", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'3.0G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'50.0G", "1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'.1G", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'1.1G", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'50.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'1.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'3.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#'.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-'1.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0'3.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-'50.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'3.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'50.0g", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'1.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'50.1g", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'3.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'50.0G", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'1.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'50.1G", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#+'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#-+'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0+'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0-+'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '1g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '3g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '.0g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '3.0g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '50.0g", " 1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '1.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '50.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '1.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '3.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '1.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '3.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '50.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '1G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '3G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '.0G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '3.0G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '50.0G", " 1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '1.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '50.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '1.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '3.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# '.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- '1.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 '3.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- '50.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'3.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'50.0g", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'1.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'50.1g", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'3.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'50.0G", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'1.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'50.1G", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%# +'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#- +'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0 +'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%#0- +'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
+ { "%'1g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'3g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'3.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'50.0g", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'1.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'1.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'3.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'1.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'3.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'50.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'1G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'3G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'3.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'50.0G", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'1.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'1.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'3.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-'1.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0'3.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-'50.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%+'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%-+'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0+'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0-+'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '1g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '3g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '3.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '50.0g", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '1.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '1.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '3.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '1.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '3.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '50.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '1G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '3G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '3.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '50.0G", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '1.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '1.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '3.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% '.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- '1.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 '3.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- '50.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "% +'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%- +'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0 +'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%0- +'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'1g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'3g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'50g", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'3.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'50.0g", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'1.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'1.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'3.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'1.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'3.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'50.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'1G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'3G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'50G", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'3.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'50.0G", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'1.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'1.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'3.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#'.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-'1.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0'3.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-'50.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#+'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#-+'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0+'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0-+'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '1g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '3g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '3.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '50.0g", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '1.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '1.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '3.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '1.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '3.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '50.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '1G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '3G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '3.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '50.0G", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '1.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '1.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '3.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# '.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- '1.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 '3.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- '50.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%# +'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#- +'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0 +'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%#0- +'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
+ { "%'1g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'.0g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'3.0g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'50.0g", "1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'.1g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'1.1g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'50.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'.3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'1.3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'3.3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'1.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'3.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'50.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'1G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'.0G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'3.0G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'50.0G", "1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'.1G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'1.1G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'50.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'.3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'1.3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'3.3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-'1.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0'3.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-'50.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'3.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'50.0g", "+1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'1.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'50.1g", " +1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'1.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'3.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'3.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'50.0G", "+1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'1.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'50.1G", " +1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'1.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'3.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%+'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%-+'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0+'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0-+'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '.0g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '3.0g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '50.0g", " 1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '1.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '50.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '.3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '1.3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '3.3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '1.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '3.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '50.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '.0G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '3.0G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '50.0G", " 1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '1.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '50.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '.3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '1.3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '3.3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% '.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- '1.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 '3.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- '50.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'3.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'50.0g", "+1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'1.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'50.1g", " +1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'1.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'3.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'3.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'50.0G", "+1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'1.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'50.1G", " +1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'1.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'3.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "% +'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%- +'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0 +'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%0- +'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'1g", "1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'3g", "1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'.0g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'3.0g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'50.0g", "1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'.1g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'1.1g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'50.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'.3g", "1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'1.3g", "1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'3.3g", "1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'1.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'3.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'50.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'1G", "1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'3G", "1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'.0G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'3.0G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'50.0G", "1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'.1G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'1.1G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'50.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'.3G", "1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'1.3G", "1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'3.3G", "1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#'.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-'1.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0'3.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-'50.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'1g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'3g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'3.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'50.0g", "+1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'1.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'50.1g", " +1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'1.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'3.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'1G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'3G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'3.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'50.0G", "+1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'1.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'50.1G", " +1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'1.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'3.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#+'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#-+'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0+'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0-+'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '1g", " 1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '3g", " 1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '.0g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '3.0g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '50.0g", " 1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '1.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '50.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '.3g", " 1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '1.3g", " 1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '3.3g", " 1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '1.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '3.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '50.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '1G", " 1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '3G", " 1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '.0G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '3.0G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '50.0G", " 1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '1.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '50.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '.3G", " 1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '1.3G", " 1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '3.3G", " 1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# '.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- '1.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 '3.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- '50.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'1g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'3g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'3.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'50.0g", "+1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'1.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'50.1g", " +1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'1.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'3.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'1G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'3G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'3.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'50.0G", "+1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'1.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'50.1G", " +1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'1.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'3.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%# +'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#- +'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0 +'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%#0- +'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
+ { "%'1g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'3g", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'50g", "00000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'.0g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'3.0g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'50.0g", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'.1g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'1.1g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'50.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'.3g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'1.3g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'3.3g", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'1.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'3.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'50.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'1G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'3G", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'50G", "00000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'.0G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'3.0G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'50.0G", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'.1G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'1.1G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'50.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'.3G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'1.3G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'3.3G", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-'1.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0'3.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-'50.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'50g", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'.0g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'3.0g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'50.0g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'1.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'50.1g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'1.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'3.3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'50G", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'.0G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'3.0G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'50.0G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'1.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'50.1G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'1.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'3.3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%+'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%-+'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0+'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0-+'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '3g", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '50g", " 0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '.0g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '3.0g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '50.0g", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '1.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '50.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '.3g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '1.3g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '3.3g", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '1.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '3.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '50.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '3G", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '50G", " 0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '.0G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '3.0G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '50.0G", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '1.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '50.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '.3G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '1.3G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '3.3G", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% '.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- '1.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 '3.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- '50.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'50g", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'.0g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'3.0g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'50.0g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'1.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'50.1g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'1.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'3.3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'50G", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'.0G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'3.0G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'50.0G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'1.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'50.1G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'1.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'3.3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "% +'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%- +'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0 +'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%0- +'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'1g", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'3g", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'50g", "00000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'.0g", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'3.0g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'50.0g", "1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'.1g", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'1.1g", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'50.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'.3g", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'1.3g", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'3.3g", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'1.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'3.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'50.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'1G", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'3G", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'50G", "00000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'.0G", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'3.0G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'50.0G", "1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'.1G", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'1.1G", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'50.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'.3G", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'1.3G", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'3.3G", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#'.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-'1.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0'3.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-'50.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'1g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'3g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'50g", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'3.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'50.0g", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'1.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'50.1g", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'1.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'3.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'1G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'3G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'50G", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'3.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'50.0G", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'1.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'50.1G", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'1.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'3.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#+'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#-+'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0+'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0-+'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '1g", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '3g", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '50g", " 0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '.0g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '3.0g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '50.0g", " 1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '1.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '50.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '.3g", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '1.3g", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '3.3g", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '1.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '3.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '50.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '1G", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '3G", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '50G", " 0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '.0G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '3.0G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '50.0G", " 1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '1.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '50.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '.3G", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '1.3G", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '3.3G", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# '.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- '1.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 '3.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- '50.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'1g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'3g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'50g", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'3.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'50.0g", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'1.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'50.1g", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'1.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'3.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'1G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'3G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'50G", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'3.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'50.0G", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'1.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'50.1G", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'1.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'3.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%# +'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#- +'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0 +'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%#0- +'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
+ { "%'1g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'.0g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'3.0g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'50.0g", "1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'.1g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'1.1g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'50.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'.3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'1.3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'3.3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'1.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'3.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'50.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'1G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'.0G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'3.0G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'50.0G", "1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'.1G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'1.1G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'50.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'.3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'1.3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'3.3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-'1.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0'3.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-'50.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'3.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'50.0g", "+1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'1.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'50.1g", " +1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'1.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'3.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'3.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'50.0G", "+1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'1.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'50.1G", " +1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'1.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'3.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%+'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%-+'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0+'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0-+'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '.0g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '3.0g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '50.0g", " 1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '1.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '50.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '.3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '1.3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '3.3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '1.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '3.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '50.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '.0G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '3.0G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '50.0G", " 1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '1.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '50.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '.3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '1.3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '3.3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% '.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- '1.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 '3.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- '50.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'3.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'50.0g", "+1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'1.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'50.1g", " +1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'1.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'3.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'3.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'50.0G", "+1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'1.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'50.1G", " +1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'1.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'3.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "% +'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%- +'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0 +'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%0- +'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'1g", "1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'3g", "1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'.0g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'3.0g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'50.0g", "1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'.1g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'1.1g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'50.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'.3g", "1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'1.3g", "1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'3.3g", "1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'1.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'3.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'50.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'1G", "1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'3G", "1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'.0G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'3.0G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'50.0G", "1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'.1G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'1.1G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'50.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'.3G", "1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'1.3G", "1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'3.3G", "1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#'.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-'1.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0'3.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-'50.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'1g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'3g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'3.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'50.0g", "+1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'1.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'50.1g", " +1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'1.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'3.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'1G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'3G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'3.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'50.0G", "+1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'1.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'50.1G", " +1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'1.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'3.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#+'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#-+'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0+'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0-+'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '1g", " 1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '3g", " 1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '.0g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '3.0g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '50.0g", " 1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '1.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '50.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '.3g", " 1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '1.3g", " 1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '3.3g", " 1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '1.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '3.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '50.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '1G", " 1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '3G", " 1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '.0G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '3.0G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '50.0G", " 1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '1.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '50.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '.3G", " 1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '1.3G", " 1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '3.3G", " 1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# '.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- '1.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 '3.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- '50.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'1g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'3g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'3.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'50.0g", "+1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'1.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'50.1g", " +1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'1.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'3.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'1G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'3G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'3.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'50.0G", "+1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'1.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'50.1G", " +1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'1.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'3.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%# +'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#- +'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0 +'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%#0- +'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
+ { "%'1g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'50g", "0000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'.0g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'3.0g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'50.0g", "1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'.1g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'1.1g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'50.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'.3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'1.3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'3.3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'1.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'3.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'50.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'1G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'50G", "0000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'.0G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'3.0G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'50.0G", "1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'.1G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'1.1G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'50.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'.3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'1.3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'3.3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-'1.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0'3.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-'50.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'50g", "+000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'3.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'50.0g", "+1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'1.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'50.1g", " +1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'1.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'3.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'1.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'3.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'50.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'50G", "+000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'3.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'50.0G", "+1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'1.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'50.1G", " +1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'1.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'3.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%+'.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%-+'1.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0+'3.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0-+'50.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '50g", " 000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '.0g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '3.0g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '50.0g", " 1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '1.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '50.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '.3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '1.3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '3.3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '1.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '3.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '50.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '50G", " 000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '.0G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '3.0G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '50.0G", " 1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '1.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '50.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '.3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '1.3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '3.3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% '.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- '1.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 '3.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- '50.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'3.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'50.0g", "+1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'1.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'50.1g", " +1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'1.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'3.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'1.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'3.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'50.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'3.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'50.0G", "+1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'1.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'50.1G", " +1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'1.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'3.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "% +'.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%- +'1.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0 +'3.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%0- +'50.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'1g", "1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'3g", "1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'.0g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'3.0g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'50.0g", "1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'.1g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'1.1g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'50.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'.3g", "1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'1.3g", "1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'3.3g", "1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'1.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'3.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'50.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'1G", "1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'3G", "1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'.0G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'3.0G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'50.0G", "1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'.1G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'1.1G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'50.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'.3G", "1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'1.3G", "1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'3.3G", "1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#'.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-'1.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0'3.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-'50.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'1g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'3g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'3.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'50.0g", "+1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'1.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'50.1g", " +1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'1.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'3.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'1.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'3.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'50.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'1G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'3G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'3.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'50.0G", "+1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'1.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'50.1G", " +1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'1.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'3.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#+'.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#-+'1.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0+'3.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0-+'50.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '1g", " 1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '3g", " 1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '.0g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '3.0g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '50.0g", " 1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '1.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '50.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '.3g", " 1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '1.3g", " 1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '3.3g", " 1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '1.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '3.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '50.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '1G", " 1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '3G", " 1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '.0G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '3.0G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '50.0G", " 1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '1.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '50.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '.3G", " 1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '1.3G", " 1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '3.3G", " 1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# '.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- '1.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 '3.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- '50.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'1g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'3g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'3.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'50.0g", "+1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'1.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'50.1g", " +1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'1.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'3.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'1.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'3.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'50.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'1G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'3G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'3.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'50.0G", "+1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'1.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'50.1G", " +1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'1.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'3.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%# +'.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#- +'1.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0 +'3.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%#0- +'50.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
+ { "%'1g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'50g", "000000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'.0g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'3.0g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'50.0g", "1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'.1g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'1.1g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'50.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'.3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'1.3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'3.3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'1.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'3.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'50.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'1G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'50G", "000000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'.0G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'3.0G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'50.0G", "1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'.1G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'1.1G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'50.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'.3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'1.3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'3.3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-'1.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0'3.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-'50.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'50g", "+00000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'3.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'50.0g", "+1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'1.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'50.1g", " +1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'1.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'3.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'50G", "+00000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'3.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'50.0G", "+1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'1.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'50.1G", " +1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'1.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'3.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%+'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%-+'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0+'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0-+'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '50g", " 00000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '.0g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '3.0g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '50.0g", " 1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '1.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '50.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '.3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '1.3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '3.3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '1.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '3.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '50.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '50G", " 00000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '.0G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '3.0G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '50.0G", " 1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '1.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '50.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '.3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '1.3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '3.3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% '.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- '1.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 '3.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- '50.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'3.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'50.0g", "+1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'1.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'50.1g", " +1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'1.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'3.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'3.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'50.0G", "+1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'1.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'50.1G", " +1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'1.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'3.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "% +'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%- +'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0 +'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%0- +'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'1g", "1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'3g", "1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'50g", "000000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'.0g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'3.0g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'50.0g", "1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'.1g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'1.1g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'50.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'.3g", "1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'1.3g", "1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'3.3g", "1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'1.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'3.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'50.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'1G", "1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'3G", "1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'50G", "000000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'.0G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'3.0G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'50.0G", "1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'.1G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'1.1G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'50.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'.3G", "1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'1.3G", "1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'3.3G", "1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#'.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-'1.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0'3.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-'50.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'1g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'3g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'3.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'50.0g", "+1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'1.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'50.1g", " +1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'1.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'3.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'1G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'3G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'3.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'50.0G", "+1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'1.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'50.1G", " +1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'1.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'3.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#+'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#-+'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0+'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0-+'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '1g", " 1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '3g", " 1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '.0g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '3.0g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '50.0g", " 1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '1.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '50.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '.3g", " 1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '1.3g", " 1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '3.3g", " 1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '1.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '3.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '50.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '1G", " 1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '3G", " 1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '.0G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '3.0G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '50.0G", " 1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '1.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '50.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '.3G", " 1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '1.3G", " 1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '3.3G", " 1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# '.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- '1.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 '3.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- '50.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'1g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'3g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'3.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'50.0g", "+1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'1.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'50.1g", " +1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'1.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'3.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'1G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'3G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'3.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'50.0G", "+1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'1.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'50.1G", " +1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'1.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'3.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%# +'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#- +'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0 +'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%#0- +'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
+ { "%'1g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'50g", "000000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'.0g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'3.0g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'50.0g", "1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'.1g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'1.1g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'50.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'.3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'1.3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'3.3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'1.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'3.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'50.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'1G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'50G", "000000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'.0G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'3.0G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'50.0G", "1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'.1G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'1.1G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'50.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'.3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'1.3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'3.3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-'1.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0'3.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-'50.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'50g", "+00000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'3.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'50.0g", "+1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'1.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'50.1g", " +1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'1.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'3.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'50G", "+00000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'3.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'50.0G", "+1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'1.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'50.1G", " +1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'1.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'3.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%+'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%-+'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0+'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0-+'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '50g", " 00000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '.0g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '3.0g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '50.0g", " 1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '1.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '50.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '.3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '1.3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '3.3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '1.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '3.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '50.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '50G", " 00000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '.0G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '3.0G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '50.0G", " 1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '1.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '50.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '.3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '1.3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '3.3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% '.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- '1.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 '3.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- '50.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'3.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'50.0g", "+1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'1.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'50.1g", " +1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'1.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'3.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'3.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'50.0G", "+1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'1.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'50.1G", " +1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'1.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'3.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "% +'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%- +'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0 +'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%0- +'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'1g", "1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'3g", "1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'50g", "000000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'.0g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'3.0g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'50.0g", "1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'.1g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'1.1g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'50.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'.3g", "1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'1.3g", "1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'3.3g", "1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'1.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'3.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'50.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'1G", "1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'3G", "1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'50G", "000000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'.0G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'3.0G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'50.0G", "1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'.1G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'1.1G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'50.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'.3G", "1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'1.3G", "1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'3.3G", "1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#'.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-'1.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0'3.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-'50.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'1g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'3g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'3.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'50.0g", "+1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'1.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'50.1g", " +1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'1.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'3.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'1G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'3G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'3.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'50.0G", "+1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'1.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'50.1G", " +1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'1.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'3.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#+'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#-+'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0+'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0-+'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '1g", " 1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '3g", " 1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '.0g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '3.0g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '50.0g", " 1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '1.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '50.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '.3g", " 1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '1.3g", " 1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '3.3g", " 1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '1.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '3.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '50.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '1G", " 1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '3G", " 1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '.0G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '3.0G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '50.0G", " 1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '1.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '50.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '.3G", " 1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '1.3G", " 1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '3.3G", " 1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# '.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- '1.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 '3.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- '50.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'1g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'3g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'3.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'50.0g", "+1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'1.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'50.1g", " +1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'1.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'3.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'1G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'3G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'3.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'50.0G", "+1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'1.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'50.1G", " +1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'1.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'3.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%# +'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#- +'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0 +'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%#0- +'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
+ { "%'1g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'50g", "000000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'.0g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'3.0g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'50.0g", "1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'.1g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'1.1g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'50.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'.3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'1.3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'3.3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'1.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'3.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'50.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'1G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'50G", "000000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'.0G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'3.0G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'50.0G", "1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'.1G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'1.1G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'50.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'.3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'1.3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'3.3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-'1.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0'3.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-'50.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'50g", "+00000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'3.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'50.0g", "+1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'1.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'50.1g", " +1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'1.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'3.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'50G", "+00000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'3.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'50.0G", "+1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'1.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'50.1G", " +1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'1.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'3.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%+'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%-+'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0+'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0-+'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '50g", " 00000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '.0g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '3.0g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '50.0g", " 1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '1.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '50.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '.3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '1.3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '3.3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '1.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '3.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '50.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '50G", " 00000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '.0G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '3.0G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '50.0G", " 1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '1.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '50.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '.3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '1.3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '3.3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% '.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- '1.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 '3.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- '50.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'3.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'50.0g", "+1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'1.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'50.1g", " +1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'1.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'3.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'3.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'50.0G", "+1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'1.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'50.1G", " +1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'1.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'3.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "% +'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%- +'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0 +'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%0- +'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'1g", "1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'3g", "1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'50g", "000000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'.0g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'3.0g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'50.0g", "1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'.1g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'1.1g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'50.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'.3g", "1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'1.3g", "1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'3.3g", "1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'1.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'3.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'50.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'1G", "1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'3G", "1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'50G", "000000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'.0G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'3.0G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'50.0G", "1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'.1G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'1.1G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'50.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'.3G", "1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'1.3G", "1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'3.3G", "1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#'.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-'1.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0'3.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-'50.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'1g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'3g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'3.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'50.0g", "+1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'1.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'50.1g", " +1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'1.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'3.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'1G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'3G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'3.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'50.0G", "+1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'1.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'50.1G", " +1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'1.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'3.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#+'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#-+'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0+'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0-+'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '1g", " 1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '3g", " 1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '.0g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '3.0g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '50.0g", " 1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '1.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '50.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '.3g", " 1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '1.3g", " 1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '3.3g", " 1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '1.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '3.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '50.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '1G", " 1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '3G", " 1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '.0G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '3.0G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '50.0G", " 1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '1.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '50.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '.3G", " 1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '1.3G", " 1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '3.3G", " 1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# '.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- '1.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 '3.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- '50.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'1g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'3g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'3.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'50.0g", "+1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'1.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'50.1g", " +1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'1.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'3.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'1G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'3G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'3.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'50.0G", "+1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'1.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'50.1G", " +1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'1.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'3.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%# +'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#- +'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0 +'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%#0- +'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
+ { "%'1g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'50g", "000000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'.0g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'3.0g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'50.0g", "1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'.1g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'1.1g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'50.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'.3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'1.3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'3.3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'1.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'3.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'50.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'1G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'50G", "000000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'.0G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'3.0G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'50.0G", "1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'.1G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'1.1G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'50.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'.3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'1.3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'3.3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-'1.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0'3.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-'50.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'50g", "+00000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'3.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'50.0g", "+1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'1.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'50.1g", " +1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'1.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'3.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'50G", "+00000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'3.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'50.0G", "+1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'1.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'50.1G", " +1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'1.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'3.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%+'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%-+'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0+'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0-+'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '50g", " 00000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '.0g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '3.0g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '50.0g", " 1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '1.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '50.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '.3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '1.3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '3.3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '1.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '3.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '50.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '50G", " 00000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '.0G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '3.0G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '50.0G", " 1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '1.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '50.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '.3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '1.3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '3.3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% '.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- '1.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 '3.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- '50.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'3.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'50.0g", "+1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'1.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'50.1g", " +1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'1.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'3.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'3.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'50.0G", "+1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'1.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'50.1G", " +1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'1.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'3.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "% +'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%- +'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0 +'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%0- +'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'1g", "1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'3g", "1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'50g", "000000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'.0g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'3.0g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'50.0g", "1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'.1g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'1.1g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'50.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'.3g", "1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'1.3g", "1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'3.3g", "1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'1.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'3.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'50.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'1G", "1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'3G", "1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'50G", "000000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'.0G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'3.0G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'50.0G", "1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'.1G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'1.1G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'50.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'.3G", "1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'1.3G", "1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'3.3G", "1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#'.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-'1.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0'3.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-'50.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'1g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'3g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'3.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'50.0g", "+1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'1.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'50.1g", " +1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'1.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'3.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'1G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'3G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'3.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'50.0G", "+1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'1.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'50.1G", " +1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'1.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'3.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#+'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#-+'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0+'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0-+'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '1g", " 1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '3g", " 1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '.0g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '3.0g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '50.0g", " 1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '1.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '50.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '.3g", " 1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '1.3g", " 1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '3.3g", " 1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '1.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '3.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '50.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '1G", " 1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '3G", " 1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '.0G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '3.0G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '50.0G", " 1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '1.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '50.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '.3G", " 1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '1.3G", " 1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '3.3G", " 1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# '.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- '1.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 '3.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- '50.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'1g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'3g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'3.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'50.0g", "+1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'1.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'50.1g", " +1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'1.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'3.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'1G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'3G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'3.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'50.0G", "+1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'1.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'50.1G", " +1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'1.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'3.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%# +'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#- +'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0 +'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%#0- +'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
+ { "%'1g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'3g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'50g", "000000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'.0g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'3.0g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'50.0g", "2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'.1g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'1.1g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'50.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'.3g", "1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'1.3g", "1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'3.3g", "1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'1.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'3.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'50.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'1G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'3G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'50G", "000000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'.0G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'3.0G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'50.0G", "2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'.1G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'1.1G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'50.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'.3G", "1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'1.3G", "1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'3.3G", "1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-'1.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0'3.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-'50.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'3.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'50.0g", "+2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'1.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'50.1g", " +2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'1.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'3.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'3.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'50.0G", "+2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'1.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'50.1G", " +2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'1.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'3.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%+'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%-+'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0+'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0-+'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '1g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '3g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '50g", " 00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '.0g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '3.0g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '50.0g", " 2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '1.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '50.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '.3g", " 1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '1.3g", " 1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '3.3g", " 1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '1.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '3.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '50.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '1G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '3G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '50G", " 00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '.0G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '3.0G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '50.0G", " 2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '1.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '50.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '.3G", " 1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '1.3G", " 1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '3.3G", " 1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% '.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- '1.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 '3.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- '50.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'3.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'50.0g", "+2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'1.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'50.1g", " +2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'1.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'3.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'3.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'50.0G", "+2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'1.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'50.1G", " +2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'1.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'3.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "% +'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%- +'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0 +'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%0- +'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'1g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'3g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'50g", "000000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'.0g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'3.0g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'50.0g", "2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'.1g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'1.1g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'50.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'.3g", "1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'1.3g", "1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'3.3g", "1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'1.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'3.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'50.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'1G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'3G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'50G", "000000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'.0G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'3.0G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'50.0G", "2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'.1G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'1.1G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'50.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'.3G", "1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'1.3G", "1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'3.3G", "1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#'.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-'1.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0'3.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-'50.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'3.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'50.0g", "+2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'1.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'50.1g", " +2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'1.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'3.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'3.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'50.0G", "+2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'1.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'50.1G", " +2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'1.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'3.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#+'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#-+'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0+'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0-+'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '1g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '3g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '.0g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '3.0g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '50.0g", " 2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '1.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '50.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '.3g", " 1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '1.3g", " 1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '3.3g", " 1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '1.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '3.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '50.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '1G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '3G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '.0G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '3.0G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '50.0G", " 2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '1.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '50.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '.3G", " 1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '1.3G", " 1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '3.3G", " 1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# '.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- '1.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 '3.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- '50.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'3.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'50.0g", "+2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'1.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'50.1g", " +2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'1.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'3.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'3.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'50.0G", "+2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'1.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'50.1G", " +2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'1.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'3.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%# +'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#- +'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0 +'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%#0- +'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
+ { "%'1g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'3g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'50g", "0000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'.0g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'3.0g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'50.0g", "3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'.1g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'1.1g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'50.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'.3g", "3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'1.3g", "3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'3.3g", "3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'1.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'3.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'50.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'1G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'3G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'50G", "0000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'.0G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'3.0G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'50.0G", "3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'.1G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'1.1G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'50.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'.3G", "3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'1.3G", "3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'3.3G", "3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-'1.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0'3.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-'50.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'3.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'50.0g", "+3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'1.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'50.1g", " +3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'1.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'3.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'3.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'50.0G", "+3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'1.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'50.1G", " +3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'1.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'3.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%+'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%-+'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0+'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0-+'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '1g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '3g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '50g", " 000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '.0g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '3.0g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '50.0g", " 3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '1.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '50.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '.3g", " 3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '1.3g", " 3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '3.3g", " 3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '1.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '3.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '50.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '1G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '3G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '50G", " 000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '.0G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '3.0G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '50.0G", " 3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '1.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '50.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '.3G", " 3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '1.3G", " 3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '3.3G", " 3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% '.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- '1.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 '3.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- '50.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'3.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'50.0g", "+3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'1.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'50.1g", " +3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'1.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'3.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'3.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'50.0G", "+3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'1.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'50.1G", " +3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'1.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'3.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "% +'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%- +'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0 +'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%0- +'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'1g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'3g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'50g", "0000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'.0g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'3.0g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'50.0g", "3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'.1g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'1.1g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'50.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'.3g", "3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'1.3g", "3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'3.3g", "3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'1.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'3.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'50.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'1G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'3G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'50G", "0000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'.0G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'3.0G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'50.0G", "3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'.1G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'1.1G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'50.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'.3G", "3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'1.3G", "3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'3.3G", "3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#'.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-'1.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0'3.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-'50.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'3.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'50.0g", "+3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'1.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'50.1g", " +3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'1.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'3.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'3.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'50.0G", "+3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'1.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'50.1G", " +3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'1.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'3.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#+'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#-+'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0+'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0-+'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '1g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '3g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '.0g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '3.0g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '50.0g", " 3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '1.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '50.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '.3g", " 3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '1.3g", " 3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '3.3g", " 3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '1.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '3.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '50.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '1G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '3G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '.0G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '3.0G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '50.0G", " 3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '1.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '50.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '.3G", " 3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '1.3G", " 3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '3.3G", " 3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# '.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- '1.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 '3.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- '50.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'3.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'50.0g", "+3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'1.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'50.1g", " +3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'1.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'3.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'3.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'50.0G", "+3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'1.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'50.1G", " +3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'1.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'3.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%# +'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#- +'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0 +'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%#0- +'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
+ { "%'1g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'3g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'50g", "0000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'.0g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'3.0g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'50.0g", "2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'.1g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'1.1g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'50.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'1.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'3.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'.50g", "2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'1.50g", "2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'3.50g", "2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'50.50g", "2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'1G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'3G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'50G", "0000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'.0G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'3.0G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'50.0G", "2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'.1G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'1.1G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'50.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'1.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'3.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'.50G", "2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-'1.50G", "2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0'3.50G", "2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-'50.50G", "2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'3.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'50.0g", "+2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'1.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'50.1g", " +2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'1.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'3.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'50.50g", "+2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'3.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'50.0G", "+2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'1.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'50.1G", " +2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%+'.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%-+'1.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0+'3.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0-+'50.50G", "+2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '1g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '3g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '50g", " 000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '.0g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '3.0g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '50.0g", " 2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '1.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '50.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '1.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '3.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '.50g", " 2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '1.50g", " 2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '3.50g", " 2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '50.50g", " 2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '1G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '3G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '50G", " 000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '.0G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '3.0G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '50.0G", " 2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '1.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '50.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '1.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '3.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% '.50G", " 2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- '1.50G", " 2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 '3.50G", " 2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- '50.50G", " 2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'3.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'50.0g", "+2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'1.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'50.1g", " +2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'1.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'3.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'50.50g", "+2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'3.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'50.0G", "+2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'1.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'50.1G", " +2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "% +'.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%- +'1.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0 +'3.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%0- +'50.50G", "+2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'1g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'3g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'50g", "0000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'.0g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'3.0g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'50.0g", "2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'.1g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'1.1g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'50.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'1.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'3.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'1.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'3.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'50.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'1G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'3G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'50G", "0000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'.0G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'3.0G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'50.0G", "2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'.1G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'1.1G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'50.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'1.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'3.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#'.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-'1.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0'3.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-'50.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'3.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'50.0g", "+2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'1.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'50.1g", " +2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'1.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'3.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'50.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'3.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'50.0G", "+2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'1.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'50.1G", " +2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#+'.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#-+'1.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0+'3.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0-+'50.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '1g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '3g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '.0g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '3.0g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '50.0g", " 2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '1.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '50.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '1.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '3.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '1.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '3.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '50.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '1G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '3G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '.0G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '3.0G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '50.0G", " 2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '1.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '50.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '1.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '3.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# '.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- '1.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 '3.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- '50.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'3.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'50.0g", "+2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'1.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'50.1g", " +2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'1.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'3.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'50.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'3.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'50.0G", "+2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'1.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'50.1G", " +2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%# +'.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#- +'1.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0 +'3.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%#0- +'50.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
+ { "%'1g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'3g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'50g", "000000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'.0g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'3.0g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'50.0g", "2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'.1g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'1.1g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'50.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'1.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'3.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'1.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'3.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'50.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'1G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'3G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'50G", "000000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'.0G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'3.0G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'50.0G", "2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'.1G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'1.1G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'50.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'1.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'3.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-'1.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0'3.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-'50.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'3.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'50.0g", "+2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'1.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'50.1g", " +2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'3.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'50.0G", "+2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'1.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'50.1G", " +2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%+'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%-+'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0+'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0-+'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '1g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '3g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '50g", " 00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '.0g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '3.0g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '50.0g", " 2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '1.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '50.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '1.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '3.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '1.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '3.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '50.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '1G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '3G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '50G", " 00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '.0G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '3.0G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '50.0G", " 2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '1.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '50.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '1.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '3.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% '.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- '1.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 '3.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- '50.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'3.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'50.0g", "+2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'1.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'50.1g", " +2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'3.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'50.0G", "+2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'1.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'50.1G", " +2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "% +'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%- +'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0 +'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%0- +'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'1g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'3g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'50g", "000000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'.0g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'3.0g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'50.0g", "2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'.1g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'1.1g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'50.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'1.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'3.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'1.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'3.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'50.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'1G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'3G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'50G", "000000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'.0G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'3.0G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'50.0G", "2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'.1G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'1.1G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'50.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'1.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'3.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#'.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-'1.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0'3.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-'50.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'3.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'50.0g", "+2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'1.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'50.1g", " +2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'3.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'50.0G", "+2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'1.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'50.1G", " +2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#+'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#-+'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0+'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0-+'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '1g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '3g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '50g", " 00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '.0g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '3.0g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '50.0g", " 2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '1.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '50.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '1.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '3.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '1.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '3.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '50.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '1G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '3G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '50G", " 00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '.0G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '3.0G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '50.0G", " 2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '1.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '50.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '1.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '3.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# '.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- '1.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 '3.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- '50.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'3.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'50.0g", "+2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'1.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'50.1g", " +2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'3.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'50.0G", "+2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'1.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'50.1G", " +2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%# +'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#- +'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0 +'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%#0- +'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
+ { "%'1g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'3g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'50g", "0000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'.0g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'3.0g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'50.0g", "1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'.1g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'1.1g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'50.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'1.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'3.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'1.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'3.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'50.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'1G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'3G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'50G", "0000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'.0G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'3.0G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'50.0G", "1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'.1G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'1.1G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'50.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'1.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'3.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%'.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-'1.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0'3.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-'50.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'3.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'50.0g", "+1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'1.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'50.1g", " +1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'3.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'50.0G", "+1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'1.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'50.1G", " +1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%+'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%-+'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0+'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0-+'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '1g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '3g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '50g", " 000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '.0g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '3.0g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '50.0g", " 1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '1.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '50.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '1.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '3.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '1.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '3.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '50.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '1G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '3G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '50G", " 000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '.0G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '3.0G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '50.0G", " 1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '1.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '50.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '1.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '3.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% '.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- '1.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 '3.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- '50.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'3.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'50.0g", "+1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'1.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'50.1g", " +1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'3.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'50.0G", "+1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'1.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'50.1G", " +1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "% +'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%- +'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0 +'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%0- +'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'1g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'3g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'50g", "0000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'.0g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'3.0g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'50.0g", "1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'.1g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'1.1g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'50.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'1.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'3.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'1.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'3.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'50.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'1G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'3G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'50G", "0000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'.0G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'3.0G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'50.0G", "1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'.1G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'1.1G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'50.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'1.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'3.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#'.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-'1.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0'3.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-'50.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'3.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'50.0g", "+1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'1.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'50.1g", " +1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'3.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'50.0G", "+1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'1.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'50.1G", " +1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#+'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#-+'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0+'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0-+'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '1g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '3g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '50g", " 000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '.0g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '3.0g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '50.0g", " 1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '1.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '50.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '1.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '3.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '1.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '3.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '50.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '1G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '3G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '50G", " 000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '.0G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '3.0G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '50.0G", " 1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '1.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '50.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '1.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '3.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# '.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- '1.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 '3.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- '50.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'3.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'50.0g", "+1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'1.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'50.1g", " +1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'3.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'50.0G", "+1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'1.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'50.1G", " +1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%# +'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#- +'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0 +'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { "%#0- +'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
+ { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }
+};
+
diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp
new file mode 100644
index 0000000000..d56a9ebd20
--- /dev/null
+++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp
@@ -0,0 +1,9345 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifdef QT_NO_CAST_TO_ASCII
+# undef QT_NO_CAST_TO_ASCII
+#endif
+#ifdef QT_ASCII_CAST_WARNINGS
+# undef QT_ASCII_CAST_WARNINGS
+#endif
+
+#include <private/qglobal_p.h> // for the icu feature test
+#include <QtTest/private/qcomparisontesthelper_p.h>
+#include <QTest>
+#include <QString>
+#include <QStringBuilder>
+#if QT_CONFIG(regularexpression)
+#include <qregularexpression.h>
+#endif
+#include <qtextstream.h>
+#include <qstringlist.h>
+#include <qstringmatcher.h>
+#include <qbytearraymatcher.h>
+#include <qvariant.h>
+
+#include <qlocale.h>
+#include <locale.h>
+#include <qhash.h>
+#include <private/qtools_p.h>
+
+#include <forward_list>
+#include <string>
+#include <algorithm>
+#include <limits>
+#include <sstream>
+
+#include "../shared/test_number_shared.h"
+#include "../../../../shared/localechange.h"
+
+using namespace Qt::StringLiterals;
+
+#define CREATE_VIEW(string) \
+ const QString padded = QLatin1Char(' ') + string + QLatin1Char(' '); \
+ const QStringView view = QStringView{ padded }.mid(1, padded.size() - 2);
+
+namespace {
+
+template <typename String> String detached(String s)
+{
+ if (!s.isNull()) { // detaching loses nullness, but we need to preserve it
+ auto d = s.data();
+ Q_UNUSED(d);
+ }
+ return s;
+}
+
+// this wraps an argument to a QString function, as well as how to apply
+// the argument to a given QString member function.
+template <typename T>
+class Arg;
+
+template <typename T>
+class Reversed {}; // marker for Arg<QChar> to apply the operation in reverse order (for prepend())
+
+class ArgBase
+{
+protected:
+ QString pinned;
+ explicit ArgBase(const char *str)
+ : pinned(QString::fromUtf8(str)) {}
+};
+
+template <>
+class Arg<QChar> : protected ArgBase
+{
+public:
+ explicit Arg(const char *str) : ArgBase(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { for (QChar ch : std::as_const(this->pinned)) (s.*mf)(ch); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { for (QChar ch : std::as_const(this->pinned)) (s.*mf)(a1, ch); }
+};
+
+template <>
+class Arg<Reversed<QChar> > : private Arg<QChar>
+{
+public:
+ explicit Arg(const char *str) : Arg<QChar>(str)
+ {
+ std::reverse(this->pinned.begin(), this->pinned.end());
+ }
+
+ using Arg<QChar>::apply0;
+ using Arg<QChar>::apply1;
+};
+
+template <>
+class Arg<QString> : ArgBase
+{
+public:
+ explicit Arg(const char *str) : ArgBase(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { (s.*mf)(this->pinned); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { (s.*mf)(a1, this->pinned); }
+};
+
+template <>
+class Arg<QStringView> : ArgBase
+{
+ QStringView view() const
+ { return this->pinned.isNull() ? QStringView() : QStringView(this->pinned) ; }
+public:
+ explicit Arg(const char *str) : ArgBase(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { (s.*mf)(view()); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { (s.*mf)(a1, view()); }
+};
+
+template <>
+class Arg<QPair<const QChar *, int> > : ArgBase
+{
+public:
+ explicit Arg(const char *str) : ArgBase(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { (s.*mf)(this->pinned.constData(), this->pinned.size()); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { (s.*mf)(a1, this->pinned.constData(), this->pinned.size()); }
+};
+
+template <>
+class Arg<QLatin1String>
+{
+ QLatin1String l1;
+public:
+ explicit Arg(const char *str) : l1(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { (s.*mf)(l1); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { (s.*mf)(a1, l1); }
+};
+
+template <bool b>
+class Arg<QBasicUtf8StringView<b>>
+{
+ QUtf8StringView u8;
+public:
+ explicit Arg(const char *str) : u8(str) {}
+
+ template <typename MemFunc>
+ void apply0(QString &s, MemFunc mf) const
+ { (s.*mf)(u8); }
+
+ template <typename MemFunc, typename A1>
+ void apply1(QString &s, MemFunc mf, A1 a1) const
+ { (s.*mf)(a1, u8); }
+};
+
+template <>
+class Arg<char>
+{
+protected:
+ const char *str;
+public:
+ explicit Arg(const char *str) : str(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ {
+ if (str) {
+ for (const char *it = str; *it; ++it)
+ (s.*mf)(*it);
+ }
+ }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ {
+ if (str) {
+ for (const char *it = str; *it; ++it)
+ (s.*mf)(a1, *it);
+ }
+ }
+};
+
+template <>
+class Arg<Reversed<char> > : private Arg<char>
+{
+ static const char *dupAndReverse(const char *s)
+ {
+ char *s2 = qstrdup(s);
+ std::reverse(s2, s2 + qstrlen(s2));
+ return s2;
+ }
+public:
+ explicit Arg(const char *str) : Arg<char>(dupAndReverse(str)) {}
+ ~Arg() { delete[] str; }
+
+ using Arg<char>::apply0;
+ using Arg<char>::apply1;
+};
+
+template <>
+class Arg<const char*>
+{
+ const char *str;
+public:
+ explicit Arg(const char *str) : str(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { (s.*mf)(str); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { (s.*mf)(a1, str); }
+};
+
+template <>
+class Arg<QByteArray>
+{
+ QByteArray ba;
+public:
+ explicit Arg(const char *str) : ba(str) {}
+
+ template <typename MemFun>
+ void apply0(QString &s, MemFun mf) const
+ { (s.*mf)(ba); }
+
+ template <typename MemFun, typename A1>
+ void apply1(QString &s, MemFun mf, A1 a1) const
+ { (s.*mf)(a1, ba); }
+};
+
+// const char* is not allowed as columns in data-driven tests (causes static_assert failure),
+// so wrap it in a container (default ctor is a QMetaType/QVariant requirement):
+class CharStarContainer
+{
+ const char *str;
+public:
+ explicit constexpr CharStarContainer(const char *s = nullptr) : str(s) {}
+ constexpr operator const char *() const { return str; }
+};
+
+} // unnamed namespace
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(CharStarContainer, Q_PRIMITIVE_TYPE);
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(CharStarContainer)
+
+// implementation helpers for append_impl/prepend_impl etc
+template <typename ArgType, typename MemFun>
+static void do_apply0(MemFun mf)
+{
+ QFETCH(QString, s);
+ QFETCH(CharStarContainer, arg);
+ QFETCH(QString, expected);
+
+ Arg<ArgType>(arg).apply0(s, mf);
+
+ QCOMPARE(s, expected);
+ QCOMPARE(s.isEmpty(), expected.isEmpty());
+ QCOMPARE(s.isNull(), expected.isNull());
+}
+
+template <typename ArgType, typename A1, typename MemFun>
+static void do_apply1(MemFun mf)
+{
+ QFETCH(QString, s);
+ QFETCH(CharStarContainer, arg);
+ QFETCH(A1, a1);
+ QFETCH(QString, expected);
+
+ // Test when the string is shared
+ QString str = s;
+ Arg<ArgType>(arg).apply1(str, mf, a1);
+
+ QCOMPARE(str, expected);
+ QCOMPARE(str.isEmpty(), expected.isEmpty());
+ QCOMPARE(str.isNull(), expected.isNull());
+
+ // Test when the string is not shared
+ str = s;
+ str.detach();
+ Arg<ArgType>(arg).apply1(str, mf, a1);
+ QCOMPARE(str, expected);
+ QCOMPARE(str.isEmpty(), expected.isEmpty());
+ // A detached string is not null
+ // QCOMPARE(str.isNull(), expected.isNull());
+}
+
+class tst_QString : public QObject
+{
+ Q_OBJECT
+public:
+ enum DataOption {
+ EmptyIsNoop = 0x1,
+ Latin1Encoded = 0x2
+ };
+ Q_DECLARE_FLAGS(DataOptions, DataOption)
+private:
+
+#if QT_CONFIG(regularexpression)
+ template<typename List, class RegExp>
+ void split_regexp(const QString &string, const QString &pattern, QStringList result);
+#endif
+ template<typename List>
+ void split(const QString &string, const QString &separator, QStringList result);
+
+ template <typename ArgType, typename MemFun>
+ void append_impl() const { do_apply0<ArgType>(MemFun(&QString::append)); }
+ template <typename ArgType>
+ void append_impl() const { append_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
+ void append_data(DataOptions options = {});
+ template <typename ArgType, typename MemFun>
+ void operator_pluseq_impl() const { do_apply0<ArgType>(MemFun(&QString::operator+=)); }
+ template <typename ArgType>
+ void operator_pluseq_impl() const { operator_pluseq_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
+ void operator_pluseq_data(DataOptions options = {});
+ template <typename ArgType, typename MemFun>
+ void prepend_impl() const { do_apply0<ArgType>(MemFun(&QString::prepend)); }
+ template <typename ArgType>
+ void prepend_impl() const { prepend_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
+ void prepend_data(DataOptions options = {});
+ template <typename ArgType, typename MemFun>
+ void insert_impl() const { do_apply1<ArgType, int>(MemFun(&QString::insert)); }
+ template <typename ArgType>
+ void insert_impl() const { insert_impl<ArgType, QString &(QString::*)(qsizetype, const ArgType&)>(); }
+ void insert_data(DataOptions options = {});
+
+ class TransientDefaultLocale
+ {
+ // This default-constructed QLocale records what *was* the default before we changed it:
+ const QLocale prior = {};
+ public:
+ TransientDefaultLocale(const QLocale &transient) { revise(transient); }
+ void revise(const QLocale &transient) { QLocale::setDefault(transient); }
+ ~TransientDefaultLocale() { QLocale::setDefault(prior); }
+ };
+
+public:
+ tst_QString();
+private slots:
+ void fromStdString();
+ void toStdString();
+ void check_QTextIOStream();
+ void check_QTextStream();
+ void check_QDataStream();
+ void fromRawData();
+ void setRawData();
+ void setUnicode();
+ void endsWith();
+ void startsWith();
+ void setNum();
+ void toDouble_data();
+ void toDouble();
+ void toFloat();
+ void toLong_data();
+ void toLong();
+ void toULong_data();
+ void toULong();
+ void toLongLong();
+ void toULongLong();
+ void toUInt();
+ void toInt();
+ void toShort();
+ void toUShort();
+ void replace_qchar_qchar_data();
+ void replace_qchar_qchar();
+ void replace_qchar_qstring_data();
+ void replace_qchar_qstring();
+ void replace_uint_uint_data();
+ void replace_uint_uint();
+ void replace_uint_uint_extra();
+ void replace_extra();
+ void replace_string_data();
+ void replace_string();
+ void replace_string_extra();
+#if QT_CONFIG(regularexpression)
+ void replace_regexp_data();
+ void replace_regexp();
+ void replace_regexp_extra();
+#endif
+ void remove_uint_uint_data();
+ void remove_uint_uint();
+ void remove_string_data();
+ void remove_string();
+#if QT_CONFIG(regularexpression)
+ void remove_regexp_data();
+ void remove_regexp();
+#endif
+ void remove_extra();
+ void erase_single_arg();
+ void erase();
+ void swap();
+
+ void prepend_qstring() { prepend_impl<QString>(); }
+ void prepend_qstring_data() { prepend_data(EmptyIsNoop); }
+ void prepend_qstringview() { prepend_impl<QStringView, QString &(QString::*)(QStringView)>(); }
+ void prepend_qstringview_data() { prepend_data(EmptyIsNoop); }
+ void prepend_qlatin1string() { prepend_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
+ void prepend_qlatin1string_data() { prepend_data({EmptyIsNoop, Latin1Encoded}); }
+ void prepend_qutf8stringview() { prepend_impl<QUtf8StringView, QString &(QString::*)(QUtf8StringView)>(); }
+ void prepend_qutf8stringview_data() { prepend_data(EmptyIsNoop); }
+ void prepend_qcharstar_int() { prepend_impl<QPair<const QChar *, int>, QString &(QString::*)(const QChar *, qsizetype)>(); }
+ void prepend_qcharstar_int_data() { prepend_data(EmptyIsNoop); }
+ void prepend_qchar() { prepend_impl<Reversed<QChar>, QString &(QString::*)(QChar)>(); }
+ void prepend_qchar_data() { prepend_data(EmptyIsNoop); }
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void prepend_qbytearray() { prepend_impl<QByteArray>(); }
+ void prepend_qbytearray_data() { prepend_data(EmptyIsNoop); }
+ void prepend_charstar() { prepend_impl<const char *, QString &(QString::*)(const char *)>(); }
+ void prepend_charstar_data() { prepend_data(EmptyIsNoop); }
+ void prepend_bytearray_special_cases_data();
+ void prepend_bytearray_special_cases();
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+#if !defined(QT_NO_CAST_FROM_ASCII)
+ void prepend_char() { prepend_impl<Reversed<char>, QString &(QString::*)(QChar)>(); }
+ void prepend_char_data() { prepend_data({EmptyIsNoop, Latin1Encoded}); }
+#endif
+
+ void prependEventuallyProducesFreeSpaceAtBegin();
+
+ void append_qstring() { append_impl<QString>(); }
+ void append_qstring_data() { append_data(); }
+ void append_qstringview() { append_impl<QStringView, QString &(QString::*)(QStringView)>(); }
+ void append_qstringview_data() { append_data(EmptyIsNoop); }
+ void append_qlatin1string() { append_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
+ void append_qlatin1string_data() { append_data(Latin1Encoded); }
+ void append_qutf8stringview() { append_impl<QUtf8StringView, QString &(QString::*)(QUtf8StringView)>(); }
+ void append_qutf8stringview_data() { append_data(); }
+ void append_qcharstar_int() { append_impl<QPair<const QChar *, int>, QString&(QString::*)(const QChar *, qsizetype)>(); }
+ void append_qcharstar_int_data() { append_data(EmptyIsNoop); }
+ void append_qchar() { append_impl<QChar, QString &(QString::*)(QChar)>(); }
+ void append_qchar_data() { append_data(EmptyIsNoop); }
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void append_qbytearray() { append_impl<QByteArray>(); }
+ void append_qbytearray_data() { append_data(); }
+#endif
+
+#if !defined(QT_NO_CAST_FROM_ASCII)
+ void append_char() { append_impl<char, QString &(QString::*)(QChar)>(); }
+ void append_char_data() { append_data({EmptyIsNoop, Latin1Encoded}); }
+#endif
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void append_charstar() { append_impl<const char *, QString &(QString::*)(const char *)>(); }
+ void append_charstar_data() { append_data(); }
+#endif
+
+ void append_special_cases();
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void append_bytearray_special_cases_data();
+ void append_bytearray_special_cases();
+#endif
+
+ void appendFromRawData();
+
+ void operator_pluseq_qstring() { operator_pluseq_impl<QString>(); }
+ void operator_pluseq_qstring_data() { operator_pluseq_data(); }
+ void operator_pluseq_qstringview() { operator_pluseq_impl<QStringView, QString &(QString::*)(QStringView)>(); }
+ void operator_pluseq_qstringview_data() { operator_pluseq_data(EmptyIsNoop); }
+ void operator_pluseq_qlatin1string() { operator_pluseq_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
+ void operator_pluseq_qlatin1string_data() { operator_pluseq_data(Latin1Encoded); }
+ void operator_pluseq_qutf8stringview() { operator_pluseq_impl<QUtf8StringView, QString &(QString::*)(QUtf8StringView)>(); }
+ void operator_pluseq_qutf8stringview_data() { operator_pluseq_data(); }
+ void operator_pluseq_qchar() { operator_pluseq_impl<QChar, QString &(QString::*)(QChar)>(); }
+ void operator_pluseq_qchar_data() { operator_pluseq_data(EmptyIsNoop); }
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void operator_pluseq_qbytearray() { operator_pluseq_impl<QByteArray>(); }
+ void operator_pluseq_qbytearray_data() { operator_pluseq_data(); }
+ void operator_pluseq_charstar() { operator_pluseq_impl<const char *, QString &(QString::*)(const char *)>(); }
+ void operator_pluseq_charstar_data() { operator_pluseq_data(); }
+ void operator_assign_symmetry();
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+ void operator_pluseq_special_cases();
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void operator_pluseq_bytearray_special_cases_data();
+ void operator_pluseq_bytearray_special_cases();
+#endif
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void operator_eqeq_bytearray_data();
+ void operator_eqeq_bytearray();
+#endif
+ void operator_eqeq_nullstring();
+ void operator_smaller();
+
+ void insert_qstring() { insert_impl<QString>(); }
+ void insert_qstring_data() { insert_data(EmptyIsNoop); }
+ void insert_qstringview() { insert_impl<QStringView, QString &(QString::*)(qsizetype, QStringView)>(); }
+ void insert_qstringview_data() { insert_data(EmptyIsNoop); }
+ void insert_qlatin1string() { insert_impl<QLatin1String, QString &(QString::*)(qsizetype, QLatin1String)>(); }
+ void insert_qlatin1string_data() { insert_data({EmptyIsNoop, Latin1Encoded}); }
+ void insert_qutf8stringview() { insert_impl<QUtf8StringView, QString &(QString::*)(qsizetype, QUtf8StringView)>(); }
+ void insert_qutf8stringview_data() { insert_data(EmptyIsNoop); }
+ void insert_qcharstar_int() { insert_impl<QPair<const QChar *, int>, QString &(QString::*)(qsizetype, const QChar*, qsizetype) >(); }
+ void insert_qcharstar_int_data() { insert_data(EmptyIsNoop); }
+ void insert_qchar() { insert_impl<Reversed<QChar>, QString &(QString::*)(qsizetype, QChar)>(); }
+ void insert_qchar_data() { insert_data(EmptyIsNoop); }
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void insert_qbytearray() { insert_impl<QByteArray>(); }
+ void insert_qbytearray_data() { insert_data(EmptyIsNoop); }
+#endif
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ void insert_char() { insert_impl<Reversed<char>, QString &(QString::*)(qsizetype, QChar)>(); }
+ void insert_char_data() { insert_data({EmptyIsNoop, Latin1Encoded}); }
+#endif
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void insert_charstar() { insert_impl<const char *, QString &(QString::*)(qsizetype, const char*) >(); }
+ void insert_charstar_data() { insert_data(EmptyIsNoop); }
+#endif
+
+ void insert_special_cases();
+
+ void assign();
+ void assign_shared();
+ void assign_uses_prepend_buffer();
+
+ void simplified_data();
+ void simplified();
+ void trimmed_data();
+ void trimmed();
+ void unicodeTableAccess_data();
+ void unicodeTableAccess();
+ void toUpper();
+ void toLower();
+ void isLower_isUpper_data();
+ void isLower_isUpper();
+ void toCaseFolded();
+ void rightJustified();
+ void leftJustified();
+ void mid();
+ void right();
+ void left();
+ void contains();
+ void count();
+ void lastIndexOf_data();
+ void lastIndexOf();
+ void indexOf_data();
+ void indexOf();
+#if QT_CONFIG(regularexpression)
+ void indexOfInvalidRegex();
+ void lastIndexOfInvalidRegex();
+#endif
+ void indexOf2_data();
+ void indexOf2();
+ void indexOf3_data();
+// void indexOf3();
+ void asprintf();
+ void asprintfS();
+ void fill();
+ void truncate();
+ void chop_data();
+ void chop();
+
+ void constructor();
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void constructorQByteArray_data();
+ void constructorQByteArray();
+#endif
+
+ void STL();
+ void macTypes();
+ void wasmTypes();
+ void isEmpty();
+ void isNull();
+ void nullness();
+#ifndef QT_NO_CAST_FROM_ASCII
+ void acc_01();
+#endif
+ void length_data();
+ void length();
+ void utf8_data();
+ void utf8();
+ void fromUtf8_data();
+ void fromUtf8();
+ void nullFromUtf8();
+ void fromLocal8Bit_data();
+ void fromLocal8Bit();
+ void local8Bit_data();
+ void local8Bit();
+ void invalidToLocal8Bit_data();
+ void invalidToLocal8Bit();
+ void nullFromLocal8Bit();
+ void fromLatin1Roundtrip_data();
+ void fromLatin1Roundtrip();
+ void toLatin1Roundtrip_data();
+ void toLatin1Roundtrip();
+ void fromLatin1();
+ void fromUcs4();
+ void toUcs4();
+ void arg();
+ void number();
+ void number_double_data();
+ void number_double();
+ void number_base_data();
+ void number_base();
+ void doubleOut();
+ void arg_fillChar_data();
+ void arg_fillChar();
+ void capacity_data();
+ void capacity();
+ void section_data();
+ void section();
+ void double_conversion_data();
+ void double_conversion();
+ void integer_conversion_data();
+ void integer_conversion();
+ void tortureSprintfDouble();
+ void toNum_base_data();
+ void toNum_base();
+ void toNum_base_neg_data();
+ void toNum_base_neg();
+ void toNum_Bad();
+ void toNum_BadAll_data();
+ void toNum_BadAll();
+ void toNum();
+ void iterators();
+ void reverseIterators();
+ void split_data();
+ void split();
+#if QT_CONFIG(regularexpression)
+ void split_regularexpression_data();
+ void split_regularexpression();
+ void regularexpression_lifetime();
+#endif
+ void fromUtf16_data();
+#if QT_DEPRECATED_SINCE(6, 0)
+ void fromUtf16();
+#endif
+ void fromUtf16_char16_data() { fromUtf16_data(); }
+
+ void fromUtf16_char16();
+ void latin1String();
+ void isInf_data();
+ void isInf();
+ void isNan_data();
+ void isNan();
+ void nanAndInf();
+ void comparisonCompiles();
+ void compare_data();
+ void compare();
+ void comparisonMacros_data();
+ void comparisonMacros();
+ void resize();
+ void resizeAfterFromRawData();
+ void resizeAfterReserve();
+ void resizeWithNegative() const;
+ void truncateWithNegative() const;
+ void QCharRefMutableUnicode() const;
+ void QCharRefDetaching() const;
+ void repeatedSignature() const;
+ void repeated() const;
+ void repeated_data() const;
+ void arg_locale();
+#if QT_CONFIG(icu)
+ void toUpperLower_icu();
+#endif
+ void literals();
+ void userDefinedLiterals();
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ void eightBitLiterals_data();
+ void eightBitLiterals();
+#endif
+ void reserve();
+ void toHtmlEscaped_data();
+ void toHtmlEscaped();
+ void operatorGreaterWithQLatin1String();
+ void compareQLatin1Strings();
+ void fromQLatin1StringWithLength();
+ void assignQLatin1String();
+ void assignQChar();
+ void isRightToLeft_data();
+ void isRightToLeft();
+ void isValidUtf16_data();
+ void isValidUtf16();
+ void unicodeStrings();
+ void vasprintfWithPrecision();
+
+ void rawData();
+ void clear();
+ void first();
+ void last();
+ void sliced();
+ void slice();
+ void chopped();
+ void removeIf();
+
+ void std_stringview_conversion();
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(tst_QString::DataOptions)
+
+
+template <class T> const T &verifyZeroTermination(const T &t) { return t; }
+
+QString verifyZeroTermination(const QString &str)
+{
+ // This test does some evil stuff, it's all supposed to work.
+
+ QString::DataPointer strDataPtr = const_cast<QString &>(str).data_ptr();
+
+ // Skip if isStatic() or fromRawData(), as those offer no guarantees
+ if (!strDataPtr->isMutable())
+ return str;
+
+ qsizetype strSize = str.size();
+ QChar strTerminator = str.constData()[strSize];
+ if (QChar(u'\0') != strTerminator)
+ return QString::fromLatin1(
+ "*** Result ('%1') not null-terminated: 0x%2 ***").arg(str)
+ .arg(strTerminator.unicode(), 4, 16, QChar(u'0'));
+
+ // Skip mutating checks on shared strings
+ if (strDataPtr->isShared())
+ return str;
+
+ const QChar *strData = str.constData();
+ const QString strCopy(strData, strSize); // Deep copy
+
+ const_cast<QChar *>(strData)[strSize] = QChar(u'x');
+ if (QChar(u'x') != str.constData()[strSize]) {
+ return QString::fromLatin1("*** Failed to replace null-terminator in "
+ "result ('%1') ***").arg(str);
+ }
+ if (str != strCopy) {
+ return QString::fromLatin1( "*** Result ('%1') differs from its copy "
+ "after null-terminator was replaced ***").arg(str);
+ }
+ const_cast<QChar *>(strData)[strSize] = QChar(u'\0'); // Restore sanity
+
+ return str;
+}
+
+// Overriding QTest's QCOMPARE, to check QString for null termination
+#undef QCOMPARE
+#define QCOMPARE(actual, expected) \
+ do { \
+ if (!QTest::qCompare(verifyZeroTermination(actual), expected, \
+ #actual, #expected, __FILE__, __LINE__)) \
+ return; \
+ } while (0) \
+ /**/
+#undef QTEST
+#define QTEST(actual, testElement) \
+ do { \
+ if (!QTest::qTest(verifyZeroTermination(actual), testElement, \
+ #actual, #testElement, __FILE__, __LINE__)) \
+ return; \
+ } while (0) \
+ /**/
+
+typedef QList<int> IntList;
+
+tst_QString::tst_QString()
+{
+ setlocale(LC_ALL, "");
+}
+
+void tst_QString::remove_uint_uint_data()
+{
+ replace_uint_uint_data();
+}
+
+void tst_QString::remove_string_data()
+{
+ replace_string_data();
+}
+
+void tst_QString::indexOf3_data()
+{
+ indexOf2_data();
+}
+
+void tst_QString::replace_qchar_qchar_data()
+{
+ QTest::addColumn<QString>("src" );
+ QTest::addColumn<QChar>("before" );
+ QTest::addColumn<QChar>("after" );
+ QTest::addColumn<Qt::CaseSensitivity>("cs");
+ QTest::addColumn<QString>("expected" );
+
+ QTest::newRow("1") << u"foo"_s << QChar(u'o') << QChar(u'a') << Qt::CaseSensitive << u"faa"_s;
+ QTest::newRow("2") << u"foo"_s << QChar(u'o') << QChar(u'a') << Qt::CaseInsensitive << u"faa"_s;
+ QTest::newRow("3") << u"foo"_s << QChar(u'O') << QChar(u'a') << Qt::CaseSensitive << u"foo"_s;
+ QTest::newRow("4") << u"foo"_s << QChar(u'O') << QChar(u'a') << Qt::CaseInsensitive << u"faa"_s;
+ QTest::newRow("5") << u"ababABAB"_s << QChar(u'a') << QChar(u' ') << Qt::CaseSensitive
+ << u" b bABAB"_s;
+ QTest::newRow("6") << u"ababABAB"_s << QChar(u'a') << QChar(u' ') << Qt::CaseInsensitive
+ << u" b b B B"_s;
+ QTest::newRow("7") << u"ababABAB"_s << QChar() << QChar(u' ') << Qt::CaseInsensitive
+ << u"ababABAB"_s;
+ QTest::newRow("8") << QString() << QChar() << QChar(u'x') << Qt::CaseInsensitive << QString();
+ QTest::newRow("9") << QString() << QChar(u'a') << QChar(u'x') << Qt::CaseInsensitive
+ << QString();
+}
+
+void tst_QString::replace_qchar_qchar()
+{
+ QFETCH(QString, src);
+ QFETCH(QChar, before);
+ QFETCH(QChar, after);
+ QFETCH(Qt::CaseSensitivity, cs);
+ QFETCH(QString, expected);
+
+ QString str = src;
+ // Test when string is shared
+ QCOMPARE(str.replace(before, after, cs), expected);
+
+ str = src;
+ // Test when it's not shared
+ str.detach();
+ QCOMPARE(str.replace(before, after, cs), expected);
+}
+
+void tst_QString::replace_qchar_qstring_data()
+{
+ QTest::addColumn<QString>("src" );
+ QTest::addColumn<QChar>("before" );
+ QTest::addColumn<QString>("after" );
+ QTest::addColumn<Qt::CaseSensitivity>("cs");
+ QTest::addColumn<QString>("expected" );
+
+ QTest::newRow("1") << u"foo"_s << QChar(u'o') << u"aA"_s << Qt::CaseSensitive
+ << u"faAaA"_s;
+ QTest::newRow("2") << u"foo"_s << QChar(u'o') << u"aA"_s << Qt::CaseInsensitive
+ << u"faAaA"_s;
+ QTest::newRow("3") << u"foo"_s << QChar(u'O') << u"aA"_s << Qt::CaseSensitive
+ << u"foo"_s;
+ QTest::newRow("4") << u"foo"_s << QChar(u'O') << u"aA"_s << Qt::CaseInsensitive
+ << u"faAaA"_s;
+ QTest::newRow("5") << u"ababABAB"_s << QChar(u'a') << u" "_s << Qt::CaseSensitive
+ << u" b bABAB"_s;
+ QTest::newRow("6") << u"ababABAB"_s << QChar(u'a') << u" "_s << Qt::CaseInsensitive
+ << u" b b B B"_s;
+ QTest::newRow("7") << u"ababABAB"_s << QChar() << u" "_s << Qt::CaseInsensitive
+ << u"ababABAB"_s;
+ QTest::newRow("8") << u"ababABAB"_s << QChar() << QString() << Qt::CaseInsensitive
+ << u"ababABAB"_s;
+ QTest::newRow("null-in-null-with-X") << QString() << QChar() << u"X"_s
+ << Qt::CaseSensitive << QString();
+ QTest::newRow("x-in-null-with-abc") << QString() << QChar(u'x') << u"abc"_s
+ << Qt::CaseSensitive << QString();
+ QTest::newRow("null-in-empty-with-X") << u""_s << QChar() << u"X"_s
+ << Qt::CaseInsensitive << QString();
+ QTest::newRow("x-in-empty-with-abc") << u""_s << QChar(u'x') << u"abc"_s
+ << Qt::CaseInsensitive << QString();
+}
+
+void tst_QString::replace_qchar_qstring()
+{
+ QFETCH(QString, src);
+ QFETCH(QChar, before);
+ QFETCH(QString, after);
+ QFETCH(Qt::CaseSensitivity, cs);
+ QFETCH(QString, expected);
+
+ // Test when string needs detach
+ QString s = src;
+ QCOMPARE(s.replace(before, after, cs), expected);
+
+ // Test when it's not shared
+ s = src;
+ s.detach();
+ QCOMPARE(s.replace(before, after, cs), expected);
+}
+
+void tst_QString::replace_uint_uint_data()
+{
+ QTest::addColumn<QString>("string" );
+ QTest::addColumn<int>("index" );
+ QTest::addColumn<int>("len" );
+ QTest::addColumn<QString>("after" );
+ QTest::addColumn<QString>("result" );
+
+ QTest::newRow("empty_rem00") << QString() << 0 << 0 << u""_s << QString();
+ QTest::newRow("empty_rem01") << QString() << 0 << 3 << u""_s << QString();
+ QTest::newRow("empty_rem02") << QString() << 5 << 3 << u""_s << QString();
+
+ QTest::newRow( "rem00" ) << u"-<>ABCABCABCABC>"_s << 0 << 3 << u""_s << u"ABCABCABCABC>"_s;
+ QTest::newRow( "rem01" ) << u"ABCABCABCABC>"_s << 1 << 4 << u""_s << u"ACABCABC>"_s;
+ QTest::newRow( "rem04" ) << u"ACABCABC>"_s << 8 << 4 << u""_s << u"ACABCABC"_s;
+ QTest::newRow( "rem05" ) << u"ACABCABC"_s << 7 << 1 << u""_s << u"ACABCAB"_s;
+ QTest::newRow( "rem06" ) << u"ACABCAB"_s << 4 << 0 << u""_s << u"ACABCAB"_s;
+
+ QTest::newRow("empty_rep00") << QString() << 0 << 0 << u"X"_s << u"X"_s;
+ QTest::newRow("empty_rep01") << QString() << 0 << 3 << u"X"_s << u"X"_s;
+ QTest::newRow("empty_rep02") << QString() << 5 << 3 << u"X"_s << QString();
+
+ QTest::newRow( "rep00" ) << u"ACABCAB"_s << 4 << 0 << u"X"_s << u"ACABXCAB"_s;
+ QTest::newRow( "rep01" ) << u"ACABXCAB"_s << 4 << 1 << u"Y"_s << u"ACABYCAB"_s;
+ QTest::newRow( "rep02" ) << u"ACABYCAB"_s << 4 << 1 << u""_s << u"ACABCAB"_s;
+ QTest::newRow( "rep03" ) << u"ACABCAB"_s << 0 << 9999 << u"XX"_s << u"XX"_s;
+ QTest::newRow( "rep04" ) << u"XX"_s << 0 << 9999 << u""_s << u""_s;
+ QTest::newRow( "rep05" ) << u"ACABCAB"_s << 0 << 2 << u"XX"_s << u"XXABCAB"_s;
+ QTest::newRow( "rep06" ) << u"ACABCAB"_s << 1 << 2 << u"XX"_s << u"AXXBCAB"_s;
+ QTest::newRow( "rep07" ) << u"ACABCAB"_s << 2 << 2 << u"XX"_s << u"ACXXCAB"_s;
+ QTest::newRow( "rep08" ) << u"ACABCAB"_s << 3 << 2 << u"XX"_s << u"ACAXXAB"_s;
+ QTest::newRow( "rep09" ) << u"ACABCAB"_s << 4 << 2 << u"XX"_s << u"ACABXXB"_s;
+ QTest::newRow( "rep10" ) << u"ACABCAB"_s << 5 << 2 << u"XX"_s << u"ACABCXX"_s;
+ QTest::newRow( "rep11" ) << u"ACABCAB"_s << 6 << 2 << u"XX"_s << u"ACABCAXX"_s;
+ QTest::newRow( "rep12" ) << QString() << 0 << 10 << u"X"_s << u"X"_s;
+ QTest::newRow( "rep13" ) << u"short"_s << 0 << 10 << u"X"_s << u"X"_s;
+ QTest::newRow( "rep14" ) << QString() << 0 << 10 << u"XX"_s << u"XX"_s;
+ QTest::newRow( "rep15" ) << u"short"_s << 0 << 10 << u"XX"_s << u"XX"_s;
+
+ // This is a regression test for an old bug where QString would add index and len parameters,
+ // potentially causing integer overflow.
+ QTest::newRow( "no overflow" ) << u"ACABCAB"_s << 1 << INT_MAX - 1 << u""_s << u"A"_s;
+ QTest::newRow( "overflow" ) << u"ACABCAB"_s << 1 << INT_MAX << u""_s << u"A"_s;
+}
+
+void tst_QString::replace_string_data()
+{
+ QTest::addColumn<QString>("string" );
+ QTest::addColumn<QString>("before" );
+ QTest::addColumn<QString>("after" );
+ QTest::addColumn<QString>("result" );
+ QTest::addColumn<bool>("bcs" );
+
+ QTest::newRow( "rem00" ) << u""_s << u""_s << u""_s << u""_s << true;
+ QTest::newRow( "rem01" ) << u"A"_s << u""_s << u""_s << u"A"_s << true;
+ QTest::newRow( "rem02" ) << u"A"_s << u"A"_s << u""_s << u""_s << true;
+ QTest::newRow( "rem03" ) << u"A"_s << u"B"_s << u""_s << u"A"_s << true;
+ QTest::newRow( "rem04" ) << u"AA"_s << u"A"_s << u""_s << u""_s << true;
+ QTest::newRow( "rem05" ) << u"AB"_s << u"A"_s << u""_s << u"B"_s << true;
+ QTest::newRow( "rem06" ) << u"AB"_s << u"B"_s << u""_s << u"A"_s << true;
+ QTest::newRow( "rem07" ) << u"AB"_s << u"C"_s << u""_s << u"AB"_s << true;
+ QTest::newRow( "rem08" ) << u"ABA"_s << u"A"_s << u""_s << u"B"_s << true;
+ QTest::newRow( "rem09" ) << u"ABA"_s << u"B"_s << u""_s << u"AA"_s << true;
+ QTest::newRow( "rem10" ) << u"ABA"_s << u"C"_s << u""_s << u"ABA"_s << true;
+ QTest::newRow( "rem11" ) << u"banana"_s << u"an"_s << u""_s << u"ba"_s << true;
+ QTest::newRow( "rem12" ) << u""_s << u"A"_s << u""_s << u""_s << true;
+ QTest::newRow( "rem13" ) << u""_s << u"A"_s << QString() << u""_s << true;
+ QTest::newRow( "rem14" ) << QString() << u"A"_s << u""_s << QString() << true;
+ QTest::newRow( "rem15" ) << QString() << u"A"_s << QString() << QString() << true;
+ QTest::newRow( "rem16" ) << QString() << u""_s << u""_s << u""_s << true;
+ QTest::newRow( "rem17" ) << u""_s << QString() << u""_s << u""_s << true;
+ QTest::newRow( "rem18" ) << u"a"_s << u"a"_s << u""_s << u""_s << false;
+ QTest::newRow( "rem19" ) << u"A"_s << u"A"_s << u""_s << u""_s << false;
+ QTest::newRow( "rem20" ) << u"a"_s << u"A"_s << u""_s << u""_s << false;
+ QTest::newRow( "rem21" ) << u"A"_s << u"a"_s << u""_s << u""_s << false;
+ QTest::newRow( "rem22" ) << u"Alpha beta"_s << u"a"_s << u""_s << u"lph bet"_s << false;
+ QTest::newRow( "rem23" ) << u"+00:00"_s << u":"_s << u""_s << u"+0000"_s << false;
+
+ QTest::newRow( "rep00" ) << u"ABC"_s << u"B"_s << u"-"_s << u"A-C"_s << true;
+ QTest::newRow( "rep01" ) << u"$()*+.?[\\]^{|}"_s << u"$()*+.?[\\]^{|}"_s << u"X"_s << u"X"_s << true;
+ QTest::newRow( "rep02" ) << u"ABCDEF"_s << u""_s << u"X"_s << u"XAXBXCXDXEXFX"_s << true;
+ QTest::newRow( "rep03" ) << u""_s << u""_s << u"X"_s << u"X"_s << true;
+ QTest::newRow( "rep04" ) << u"a"_s << u"a"_s << u"b"_s << u"b"_s << false;
+ QTest::newRow( "rep05" ) << u"A"_s << u"A"_s << u"b"_s << u"b"_s << false;
+ QTest::newRow( "rep06" ) << u"a"_s << u"A"_s << u"b"_s << u"b"_s << false;
+ QTest::newRow( "rep07" ) << u"A"_s << u"a"_s << u"b"_s << u"b"_s << false;
+ QTest::newRow( "rep08" ) << u"a"_s << u"a"_s << u"a"_s << u"a"_s << false;
+ QTest::newRow( "rep09" ) << u"A"_s << u"A"_s << u"a"_s << u"a"_s << false;
+ QTest::newRow( "rep10" ) << u"a"_s << u"A"_s << u"a"_s << u"a"_s << false;
+ QTest::newRow( "rep11" ) << u"A"_s << u"a"_s << u"a"_s << u"a"_s << false;
+ QTest::newRow( "rep12" ) << u"Alpha beta"_s << u"a"_s << u"o"_s << u"olpho beto"_s << false;
+ QTest::newRow( "rep13" ) << QString() << u""_s << u"A"_s << u"A"_s << true;
+ QTest::newRow( "rep14" ) << u""_s << QString() << u"A"_s << u"A"_s << true;
+ QTest::newRow( "rep15" ) << u"fooxbarxbazxblub"_s << u"x"_s << u"yz"_s << u"fooyzbaryzbazyzblub"_s << true;
+ QTest::newRow( "rep16" ) << u"fooxbarxbazxblub"_s << u"x"_s << u"z"_s << u"foozbarzbazzblub"_s << true;
+ QTest::newRow( "rep17" ) << u"fooxybarxybazxyblub"_s << u"xy"_s << u"z"_s << u"foozbarzbazzblub"_s << true;
+ QTest::newRow("rep18") << QString() << QString() << u"X"_s << u"X"_s << false;
+ QTest::newRow("rep19") << QString() << u"A"_s << u"X"_s << u""_s << false;
+}
+
+#if QT_CONFIG(regularexpression)
+void tst_QString::replace_regexp_data()
+{
+ remove_regexp_data(); // Sets up the columns, adds rows with empty replacement text.
+ // Columns (all QString): string, regexp, after, result; string.replace(regexp, after) == result
+ // Test-cases with empty after (replacement text, third column) go in remove_regexp_data()
+
+ QTest::newRow("empty-in-null") << QString() << "" << "after" << "after";
+ QTest::newRow("empty-in-empty") << "" << "" << "after" << "after";
+
+ QTest::newRow( "rep00" ) << u"A <i>bon mot</i>."_s << u"<i>([^<]*)</i>"_s << u"\\emph{\\1}"_s << u"A \\emph{bon mot}."_s;
+ QTest::newRow( "rep01" ) << u"banana"_s << u"^.a()"_s << u"\\1"_s << u"nana"_s;
+ QTest::newRow( "rep02" ) << u"banana"_s << u"(ba)"_s << u"\\1X\\1"_s << u"baXbanana"_s;
+ QTest::newRow( "rep03" ) << u"banana"_s << u"(ba)(na)na"_s << u"\\2X\\1"_s << u"naXba"_s;
+ QTest::newRow("rep04") << QString() << u"(ba)"_s << u"\\1X\\1"_s << QString();
+
+ QTest::newRow("backref00") << u"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\A\\10\\11"_s << u"\\\\[34]"_s
+ << u"X"_s << u"\\1\\2XX\\5\\6\\7\\8\\9\\A\\10\\11"_s;
+ QTest::newRow("backref01") << u"foo"_s << u"[fo]"_s << u"\\1"_s << u"\\1\\1\\1"_s;
+ QTest::newRow("backref02") << u"foo"_s << u"([fo])"_s << u"(\\1)"_s << u"(f)(o)(o)"_s;
+ QTest::newRow("backref03") << u"foo"_s << u"([fo])"_s << u"\\2"_s << u"\\2\\2\\2"_s;
+ QTest::newRow("backref04") << u"foo"_s << u"([fo])"_s << u"\\10"_s << u"f0o0o0"_s;
+ QTest::newRow("backref05") << u"foo"_s << u"([fo])"_s << u"\\11"_s << u"f1o1o1"_s;
+ QTest::newRow("backref06") << u"foo"_s << u"([fo])"_s << u"\\19"_s << u"f9o9o9"_s;
+ QTest::newRow("backref07") << u"foo"_s << u"(f)(o+)"_s
+ << u"\\2\\1\\10\\20\\11\\22\\19\\29\\3"_s
+ << u"ooff0oo0f1oo2f9oo9\\3"_s;
+ QTest::newRow("backref08") << u"abc"_s << u"(((((((((((((([abc]))))))))))))))"_s
+ << u"{\\14}"_s << u"{a}{b}{c}"_s;
+ QTest::newRow("backref09") << u"abcdefghijklmn"_s
+ << u"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)"_s
+ << u"\\19\\18\\17\\16\\15\\14\\13\\12\\11\\10"
+ "\\9\\90\\8\\80\\7\\70\\6\\60\\5\\50\\4\\40\\3\\30\\2\\20\\1"_s
+ << u"a9a8a7a6a5nmlkjii0hh0gg0ff0ee0dd0cc0bb0a"_s;
+ QTest::newRow("backref10") << u"abc"_s << u"((((((((((((((abc))))))))))))))"_s
+ << u"\\0\\01\\011"_s << u"\\0\\01\\011"_s;
+}
+#endif
+
+void tst_QString::utf8_data()
+{
+ QString str;
+ QTest::addColumn<QByteArray>("utf8" );
+ QTest::addColumn<QString>("res" );
+
+ QTest::newRow("null") << QByteArray() << QString();
+ QTest::newRow("empty") << QByteArray("") << u""_s;
+
+ QTest::newRow("str0") << QByteArray("abcdefgh") << u"abcdefgh"_s;
+
+ QTest::newRow( "str1" ) << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
+ << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") ;
+ str += QChar( 0x05e9 );
+ str += QChar( 0x05d3 );
+ str += QChar( 0x05d2 );
+ QTest::newRow( "str2" ) << QByteArray("\327\251\327\223\327\222")
+ << str;
+
+ str = QChar( 0x20ac );
+ str += u" some text"_s;
+ QTest::newRow( "str3" ) << QByteArray("\342\202\254 some text")
+ << str;
+
+ str = u"Old Italic: "_s;
+ str += QChar(0xd800);
+ str += QChar(0xdf00);
+ str += QChar(0xd800);
+ str += QChar(0xdf01);
+ str += QChar(0xd800);
+ str += QChar(0xdf02);
+ str += QChar(0xd800);
+ str += QChar(0xdf03);
+ str += QChar(0xd800);
+ str += QChar(0xdf04);
+ QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str;
+}
+
+void tst_QString::length_data()
+{
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<qsizetype>("res");
+
+ QTest::newRow("null") << QString() << qsizetype(0);
+ QTest::newRow("empty") << u""_s << qsizetype(0);
+ QTest::newRow("data0") << u"Test"_s << qsizetype(4);
+ QTest::newRow("data1") << u"The quick brown fox jumps over the lazy dog"_s << qsizetype(43);
+ QTest::newRow("data2") << u"Sphinx of black quartz, judge my vow!"_s << qsizetype(37);
+ QTest::newRow("data3") << u"A"_s << qsizetype(1);
+ QTest::newRow("data4") << u"AB"_s << qsizetype(2);
+ QTest::newRow("data5") << u"AB\n"_s << qsizetype(3);
+ QTest::newRow("data6") << u"AB\nC"_s << qsizetype(4);
+ QTest::newRow("data7") << u"\n"_s << qsizetype(1);
+ QTest::newRow("data8") << u"\nA"_s << qsizetype(2);
+ QTest::newRow("data9") << u"\nAB"_s << qsizetype(3);
+ QTest::newRow("data10") << u"\nAB\nCDE"_s << qsizetype(7);
+ QTest::newRow("data11") << u"shdnftrheid fhgnt gjvnfmd chfugkh bnfhg thgjf vnghturkf "
+ "chfnguh bjgnfhvygh hnbhgutjfv dhdnjds dcjs d"_s
+ << qsizetype(100);
+}
+
+void tst_QString::length()
+{
+ // size(), length() and count() do the same
+ QFETCH(QString, s1);
+ QTEST(s1.size(), "res");
+ QTEST(s1.size(), "res");
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_IGNORE_DEPRECATIONS(QTEST(s1.size(), "res");)
+#endif
+}
+
+#include <qfile.h>
+
+#ifndef QT_NO_CAST_FROM_ASCII
+void tst_QString::acc_01()
+{
+ QString a;
+ QString b; //b(10);
+ QString bb; //bb((int)0);
+ QString c("String C");
+ QChar tmp[10];
+ tmp[0] = 'S';
+ tmp[1] = 't';
+ tmp[2] = 'r';
+ tmp[3] = 'i';
+ tmp[4] = 'n';
+ tmp[5] = 'g';
+ tmp[6] = ' ';
+ tmp[7] = 'D';
+ tmp[8] = 'X';
+ tmp[9] = '\0';
+ QString d(tmp,8);
+ QString ca(a);
+ QString cb(b);
+ QString cc(c);
+ QString n;
+ QString e("String E");
+ QString f;
+ f = e;
+ f[7]='F';
+ QCOMPARE(e, QLatin1String("String E"));
+
+#ifndef QT_RESTRICTED_CAST_FROM_ASCII
+ char text[]="String f";
+ f = text;
+ text[7]='!';
+ QCOMPARE(f, QLatin1String("String f"));
+ f[7]='F';
+ QCOMPARE(text[7],'!');
+#endif
+
+ a="123";
+ b="456";
+ a[0]=a[1];
+ QCOMPARE(a, QLatin1String("223"));
+ a[1]=b[1];
+ QCOMPARE(b, QLatin1String("456"));
+ QCOMPARE(a, QLatin1String("253"));
+
+#ifndef QT_RESTRICTED_CAST_FROM_ASCII
+ char t[]="TEXT";
+ a="A";
+ a=t;
+ QCOMPARE(a, QLatin1String("TEXT"));
+ QCOMPARE(a,(QString)t);
+ a[0]='X';
+ QCOMPARE(a, QLatin1String("XEXT"));
+ QCOMPARE(t[0],'T');
+ t[0]='Z';
+ QCOMPARE(a, QLatin1String("XEXT"));
+#endif
+
+ a="ABC";
+ QCOMPARE(char(a.toLatin1()[1]),'B');
+ QCOMPARE(strcmp(a.toLatin1(), QByteArrayLiteral("ABC")), 0);
+ QCOMPARE(a+="DEF", QLatin1String("ABCDEF"));
+ QCOMPARE(a+='G', QLatin1String("ABCDEFG"));
+ QCOMPARE(a+=((const char*)(0)), QLatin1String("ABCDEFG"));
+
+ // non-member operators
+
+ a="ABC";
+ b="ABC";
+ c="ACB";
+ d="ABCD";
+ QVERIFY(a==b);
+ QVERIFY(!(a==d));
+ QVERIFY(!(a!=b));
+ QVERIFY(a!=d);
+ QVERIFY(!(a<b));
+ QVERIFY(a<c);
+ QVERIFY(a<d);
+ QVERIFY(!(d<a));
+ QVERIFY(!(c<a));
+ QVERIFY(a<=b);
+ QVERIFY(a<=d);
+ QVERIFY(a<=c);
+ QVERIFY(!(c<=a));
+ QVERIFY(!(d<=a));
+ QCOMPARE(QString(a+b), QLatin1String("ABCABC"));
+ QCOMPARE(QString(a+"XXXX"), QLatin1String("ABCXXXX"));
+ QCOMPARE(QString(a+'X'), QLatin1String("ABCX"));
+ QCOMPARE(QString("XXXX"+a), QLatin1String("XXXXABC"));
+ QCOMPARE(QString('X'+a), QLatin1String("XABC"));
+#ifndef QT_RESTRICTED_CAST_FROM_ASCII
+ a = (const char*)0;
+ QVERIFY(a.isNull());
+ QVERIFY(*a.toLatin1().constData() == '\0');
+#endif
+}
+#endif // QT_NO_CAST_FROM_ASCII
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wformat-security")
+QT_WARNING_DISABLE_CLANG("-Wformat-security")
+
+void tst_QString::isNull()
+{
+ QString a;
+ QVERIFY(a.isNull());
+ QVERIFY(!a.isDetached());
+
+ const char *zero = nullptr;
+ QVERIFY(!QString::asprintf(zero).isNull());
+}
+
+QT_WARNING_POP
+
+void tst_QString::nullness()
+{
+ {
+ QString s;
+ QVERIFY(s.isNull());
+ }
+#if defined(__cpp_char8_t) || !defined(QT_RESTRICTED_CAST_FROM_ASCII)
+#if !defined(QT_NO_CAST_FROM_ASCII)
+ // we don't have QString(std::nullptr_t), so this uses QString(const char8_t*) in C++20:
+ {
+ QString s = nullptr;
+ QVERIFY(s.isNull());
+ }
+#endif
+#endif
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ {
+ const char *ptr = nullptr;
+ QString s = ptr;
+ QVERIFY(s.isNull());
+ }
+#endif
+#ifdef __cpp_char8_t
+ {
+ const char8_t *ptr = nullptr;
+ QString s = ptr;
+ QVERIFY(s.isNull());
+ }
+#endif
+ {
+ QString s(nullptr, 0);
+ QVERIFY(s.isNull());
+ }
+ {
+ const QChar *ptr = nullptr;
+ QString s(ptr, 0);
+ QVERIFY(s.isNull());
+ }
+ {
+ QLatin1String l1;
+ QVERIFY(l1.isNull());
+ QString s = l1;
+ QVERIFY(s.isNull());
+ }
+ {
+ QStringView sv;
+ QVERIFY(sv.isNull());
+ QString s = sv.toString();
+ QVERIFY(s.isNull());
+ }
+}
+
+void tst_QString::isEmpty()
+{
+ QString a;
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ QString b = QString::fromLatin1("Not empty");
+ QVERIFY(!b.isEmpty());
+
+ QString c = u"Not empty"_s;
+ QVERIFY(!c.isEmpty());
+}
+
+void tst_QString::constructor()
+{
+ // String literal with explicit \0 character
+ static constexpr char16_t utf16[] = u"String DX\u0000";
+ const size_t size_minus_null_terminator = std::size(utf16) - 1;
+ const auto *qchar = reinterpret_cast<const QChar *>(utf16);
+
+ // Up to but not including the explicit \0 in utf16[]
+ QString b1(qchar);
+ QCOMPARE(b1, u"String DX");
+ // Up to and including the explicit \0 in utf16[]
+ QString b2(qchar, size_minus_null_terminator);
+ QCOMPARE(b2, QStringView(utf16, size_minus_null_terminator));
+
+ QString a;
+ QString a_copy(a);
+ QCOMPARE(a, a_copy);
+ QVERIFY(a.isNull());
+ QCOMPARE(a, u""_s);
+
+ QString c(u"String C"_s);
+ QString c_copy(c);
+ QCOMPARE(c, c_copy);
+
+ QString e(QLatin1StringView("String E"));
+ QString e_copy(e);
+ QCOMPARE(e, e_copy);
+ QCOMPARE(e, "String E"_L1);
+
+ QString d(qchar, 8);
+ QCOMPARE(d, "String D"_L1);
+
+ QString nullStr;
+ QVERIFY( nullStr.isNull() );
+ QVERIFY( nullStr.isEmpty() );
+
+ QString empty(u""_s);
+ QVERIFY( !empty.isNull() );
+ QVERIFY( empty.isEmpty() );
+
+ empty = QString::fromLatin1("");
+ QVERIFY(!empty.isNull());
+ QVERIFY(empty.isEmpty());
+
+ empty = QString::fromUtf8("");
+ QVERIFY(!empty.isNull());
+ QVERIFY(empty.isEmpty());
+}
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+void tst_QString::constructorQByteArray_data()
+{
+ QTest::addColumn<QByteArray>("src" );
+ QTest::addColumn<QString>("expected" );
+
+ QByteArray ba( 4, 0 );
+ ba[0] = 'C';
+ ba[1] = 'O';
+ ba[2] = 'M';
+ ba[3] = 'P';
+
+ QTest::newRow( "1" ) << ba << u"COMP"_s;
+
+ QByteArray ba1( 7, 0 );
+ ba1[0] = 'a';
+ ba1[1] = 'b';
+ ba1[2] = 'c';
+ ba1[3] = '\0';
+ ba1[4] = 'd';
+ ba1[5] = 'e';
+ ba1[6] = 'f';
+
+ QTest::newRow( "2" ) << ba1 << QString::fromUtf16(u"abc\0def", 7);
+
+ QTest::newRow( "3" ) << QByteArray::fromRawData("abcd", 3) << u"abc"_s;
+ QTest::newRow( "4" ) << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
+ QTest::newRow( "4-bis" ) << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
+ QTest::newRow( "4-tre" ) << QByteArray("\xc3\xa9") << QString::fromLatin1("\xe9");
+}
+
+void tst_QString::constructorQByteArray()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(QString, expected);
+
+ QString strBA(src);
+ QCOMPARE( strBA, expected );
+
+ // test operator= too
+ strBA.clear();
+ strBA = src;
+ QCOMPARE( strBA, expected );
+
+ // test constructor/operator=(const char *)
+ if (src.constData()[src.size()] == '\0') {
+ qsizetype zero = expected.indexOf(QLatin1Char('\0'));
+ if (zero < 0)
+ zero = expected.size();
+
+ QString str1(src.constData());
+ QCOMPARE(str1.size(), zero);
+ QCOMPARE(str1, expected.left(zero));
+
+ str1.clear();
+ str1 = src.constData();
+ QCOMPARE(str1, expected.left(zero));
+ }
+}
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+void tst_QString::STL()
+{
+ QString nullStr;
+ QVERIFY(nullStr.toStdWString().empty());
+ QVERIFY(!nullStr.isDetached());
+
+ wchar_t dataArray[] = { 'w', 'o', 'r', 'l', 'd', 0 };
+
+ QCOMPARE(nullStr.toWCharArray(dataArray), 0);
+ QVERIFY(dataArray[0] == 'w'); // array was not modified
+ QVERIFY(!nullStr.isDetached());
+
+ QString emptyStr(u""_s);
+
+ QVERIFY(emptyStr.toStdWString().empty());
+ QVERIFY(!emptyStr.isDetached());
+
+ QCOMPARE(emptyStr.toWCharArray(dataArray), 0);
+ QVERIFY(dataArray[0] == 'w'); // array was not modified
+ QVERIFY(!emptyStr.isDetached());
+
+ std::string stdstr( "QString" );
+
+ QString stlqt = QString::fromStdString(stdstr);
+ QCOMPARE(stlqt, QString::fromLatin1(stdstr.c_str()));
+ QCOMPARE(stlqt.toStdString(), stdstr);
+
+ const wchar_t arr[] = {'h', 'e', 'l', 'l', 'o', 0};
+ std::wstring stlStr = arr;
+
+ QString s = QString::fromStdWString(stlStr);
+
+ QCOMPARE(s, QString::fromLatin1("hello"));
+ QCOMPARE(stlStr, s.toStdWString());
+
+ // replacing the content of dataArray by calling toWCharArray()
+ QCOMPARE(s.toWCharArray(dataArray), 5);
+ const std::wstring stlStrFromUpdatedArray = dataArray;
+ QCOMPARE(stlStrFromUpdatedArray, stlStr);
+}
+
+void tst_QString::macTypes()
+{
+#ifndef Q_OS_DARWIN
+ QSKIP("This is a Mac-only test");
+#else
+ extern void tst_QString_macTypes(); // in qcore_foundation.mm
+ tst_QString_macTypes();
+#endif
+}
+
+void tst_QString::wasmTypes()
+{
+#ifndef Q_OS_WASM
+ QSKIP("This is a WASM-only test");
+#else
+ extern void tst_QString_wasmTypes(); // in qcore_wasm.cpp
+ tst_QString_wasmTypes();
+#endif
+}
+
+void tst_QString::truncate()
+{
+ QString nullStr;
+ nullStr.truncate(5);
+ QVERIFY(nullStr.isEmpty());
+ nullStr.truncate(0);
+ QVERIFY(nullStr.isEmpty());
+ nullStr.truncate(-3);
+ QVERIFY(nullStr.isEmpty());
+ QVERIFY(!nullStr.isDetached());
+
+ QString emptyStr(u""_s);
+ emptyStr.truncate(5);
+ QVERIFY(emptyStr.isEmpty());
+ emptyStr.truncate(0);
+ QVERIFY(emptyStr.isEmpty());
+ emptyStr.truncate(-3);
+ QVERIFY(emptyStr.isEmpty());
+ QVERIFY(!emptyStr.isDetached());
+
+ QString e(u"String E"_s);
+ e.truncate(4);
+ QCOMPARE(e, QLatin1String("Stri"));
+
+ e = u"String E"_s;
+ e.truncate(0);
+ QCOMPARE(e, QLatin1String(""));
+ QVERIFY(e.isEmpty());
+ QVERIFY(!e.isNull());
+
+}
+
+void tst_QString::chop_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<int>("count" );
+ QTest::addColumn<QString>("result");
+
+ const QString original(u"abcd"_s);
+
+ QTest::newRow("null chop 1") << QString() << 1 << QString();
+ QTest::newRow("null chop -1") << QString() << -1 << QString();
+ QTest::newRow("empty chop 1") << u""_s << 1 << u""_s;
+ QTest::newRow("empty chop -1") << u""_s << -1 << u""_s;
+ QTest::newRow("data0") << original << 1 << u"abc"_s;
+ QTest::newRow("data1") << original << 0 << original;
+ QTest::newRow("data2") << original << -1 << original;
+ QTest::newRow("data3") << original << int(original.size()) << QString();
+ QTest::newRow("data4") << original << 1000 << QString();
+}
+
+void tst_QString::chop()
+{
+ QFETCH(QString, input);
+ QFETCH(int, count);
+ QFETCH(QString, result);
+
+ input.chop(count);
+ QCOMPARE(input, result);
+}
+
+void tst_QString::fill()
+{
+ QString e;
+ e.fill(u'e', 1);
+ QCOMPARE(e, QLatin1String("e"));
+ QString f;
+ f.fill(u'f', 3);
+ QCOMPARE(f, QLatin1String("fff"));
+ f.fill(u'F');
+ QCOMPARE(f, QLatin1String("FFF"));
+ f.fill(u'a', 2);
+ QCOMPARE(f, QLatin1String("aa"));
+}
+
+static inline const void *ptrValue(quintptr v)
+{
+ return reinterpret_cast<const void *>(v);
+}
+
+void tst_QString::asprintf()
+{
+ QString a;
+ QCOMPARE(QString::asprintf("COMPARE"), QLatin1String("COMPARE"));
+ QCOMPARE(QString::asprintf("%%%d", 1), QLatin1String("%1"));
+ QCOMPARE(QString::asprintf("X%dY",2), QLatin1String("X2Y"));
+ QCOMPARE(QString::asprintf("X%9iY", 50000 ), QLatin1String("X 50000Y"));
+ QCOMPARE(QString::asprintf("X%-9sY","hello"), QLatin1String("Xhello Y"));
+ QCOMPARE(QString::asprintf("X%-9iY", 50000 ), QLatin1String("X50000 Y"));
+ QCOMPARE(QString::asprintf("%lf", 1.23), QLatin1String("1.230000"));
+ QCOMPARE(QString::asprintf("%lf", 1.23456789), QLatin1String("1.234568"));
+ QCOMPARE(QString::asprintf("%p", ptrValue(0xbfffd350)), QLatin1String("0xbfffd350"));
+ QCOMPARE(QString::asprintf("%p", ptrValue(0)), QLatin1String("0x0"));
+ QCOMPARE(QString::asprintf("%td", ptrdiff_t(6)), QString::fromLatin1("6"));
+ QCOMPARE(QString::asprintf("%td", ptrdiff_t(-6)), QString::fromLatin1("-6"));
+ QCOMPARE(QString::asprintf("%zu", size_t(6)), QString::fromLatin1("6"));
+ QCOMPARE(QString::asprintf("%zu", size_t(1) << 31), QString::fromLatin1("2147483648"));
+
+ // cross z and t
+ using ssize_t = std::make_signed<size_t>::type; // should be ptrdiff_t
+ using uptrdiff_t = std::make_unsigned<ptrdiff_t>::type; // should be size_t
+ QCOMPARE(QString::asprintf("%tu", uptrdiff_t(6)), QString::fromLatin1("6"));
+ QCOMPARE(QString::asprintf("%tu", uptrdiff_t(1) << 31), QString::fromLatin1("2147483648"));
+ QCOMPARE(QString::asprintf("%zd", ssize_t(-6)), QString::fromLatin1("-6"));
+
+ if (sizeof(qsizetype) > sizeof(int)) {
+ // 64-bit test
+ QCOMPARE(QString::asprintf("%zu", SIZE_MAX), QString::fromLatin1("18446744073709551615"));
+ QCOMPARE(QString::asprintf("%td", PTRDIFF_MAX), QString::fromLatin1("9223372036854775807"));
+ QCOMPARE(QString::asprintf("%td", PTRDIFF_MIN), QString::fromLatin1("-9223372036854775808"));
+
+ // sign extension is easy, make sure we can get something middle-ground
+ // (24 + 8 = 32; addition used to avoid warning about shifting more
+ // than size type on 32-bit systems)
+ size_t ubig = size_t(1) << (24 + sizeof(size_t));
+ ptrdiff_t sbig = ptrdiff_t(1) << (24 + sizeof(ptrdiff_t));
+ QCOMPARE(QString::asprintf("%zu", ubig), QString::fromLatin1("4294967296"));
+ QCOMPARE(QString::asprintf("%td", sbig), QString::fromLatin1("4294967296"));
+ QCOMPARE(QString::asprintf("%td", -sbig), QString::fromLatin1("-4294967296"));
+ }
+
+ int i = 6;
+ long l = -2;
+ float f = 4.023f;
+ QCOMPARE(QString::asprintf("%d %ld %f", i, l, f), QLatin1String("6 -2 4.023000"));
+
+ double d = -514.25683;
+ QCOMPARE(QString::asprintf("%f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%.f", d), QLatin1String("-514"));
+ QCOMPARE(QString::asprintf("%.0f", d), QLatin1String("-514"));
+ QCOMPARE(QString::asprintf("%1f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%1.f", d), QLatin1String("-514"));
+ QCOMPARE(QString::asprintf("%1.0f", d), QLatin1String("-514"));
+ QCOMPARE(QString::asprintf("%1.6f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%1.10f", d), QLatin1String("-514.2568300000"));
+ QCOMPARE(QString::asprintf("%-1f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%-1.f", d), QLatin1String("-514"));
+ QCOMPARE(QString::asprintf("%-1.0f", d), QLatin1String("-514"));
+ QCOMPARE(QString::asprintf("%-1.6f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%-1.10f", d), QLatin1String("-514.2568300000"));
+ QCOMPARE(QString::asprintf("%10f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%10.f", d), QLatin1String(" -514"));
+ QCOMPARE(QString::asprintf("%10.0f", d), QLatin1String(" -514"));
+ QCOMPARE(QString::asprintf("%-10f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%-10.f", d), QLatin1String("-514 "));
+ QCOMPARE(QString::asprintf("%-10.0f", d), QLatin1String("-514 "));
+ QCOMPARE(QString::asprintf("%010f", d), QLatin1String("-514.256830"));
+ QCOMPARE(QString::asprintf("%010.f", d), QLatin1String("-000000514"));
+ QCOMPARE(QString::asprintf("%010.0f", d), QLatin1String("-000000514"));
+ QCOMPARE(QString::asprintf("%15f", d), QLatin1String(" -514.256830"));
+ QCOMPARE(QString::asprintf("%15.6f", d), QLatin1String(" -514.256830"));
+ QCOMPARE(QString::asprintf("%15.10f", d), QLatin1String("-514.2568300000"));
+ QCOMPARE(QString::asprintf("%-15f", d), QLatin1String("-514.256830 "));
+ QCOMPARE(QString::asprintf("%-15.6f", d), QLatin1String("-514.256830 "));
+ QCOMPARE(QString::asprintf("%-15.10f", d), QLatin1String("-514.2568300000"));
+ QCOMPARE(QString::asprintf("%015f", d), QLatin1String("-0000514.256830"));
+ QCOMPARE(QString::asprintf("%015.6f", d), QLatin1String("-0000514.256830"));
+ QCOMPARE(QString::asprintf("%015.10f", d), QLatin1String("-514.2568300000"));
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wformat")
+QT_WARNING_DISABLE_CLANG("-Wformat") // Flag '0' ignored when flag '-' is present
+ QCOMPARE(QString::asprintf("%-015f", d), QLatin1String("-514.256830 "));
+ QCOMPARE(QString::asprintf("%-015.6f", d), QLatin1String("-514.256830 "));
+ QCOMPARE(QString::asprintf("%-015.10f", d), QLatin1String("-514.2568300000"));
+QT_WARNING_POP
+
+ {
+ /* This code crashed. I don't know how to reduce it further. In other words,
+ * both %zu and %s needs to be present. */
+ size_t s = 6;
+ QCOMPARE(QString::asprintf("%zu%s", s, "foo"), QString::fromLatin1("6foo"));
+ QCOMPARE(QString::asprintf("%zu %s\n", s, "foo"), QString::fromLatin1("6 foo\n"));
+ }
+}
+
+void tst_QString::asprintfS()
+{
+ QCOMPARE(QString::asprintf("%.3s", "Hello" ), QLatin1String("Hel"));
+ QCOMPARE(QString::asprintf("%10.3s", "Hello" ), QLatin1String(" Hel"));
+ QCOMPARE(QString::asprintf("%.10s", "Hello" ), QLatin1String("Hello"));
+ QCOMPARE(QString::asprintf("%10.10s", "Hello" ), QLatin1String(" Hello"));
+ QCOMPARE(QString::asprintf("%-10.10s", "Hello" ), QLatin1String("Hello "));
+ QCOMPARE(QString::asprintf("%-10.3s", "Hello" ), QLatin1String("Hel "));
+ QCOMPARE(QString::asprintf("%-5.5s", "Hello" ), QLatin1String("Hello"));
+ QCOMPARE(QString::asprintf("%*s", 4, "Hello"), QLatin1String("Hello"));
+ QCOMPARE(QString::asprintf("%*s", 10, "Hello"), QLatin1String(" Hello"));
+ QCOMPARE(QString::asprintf("%-*s", 10, "Hello"), QLatin1String("Hello "));
+
+ // Check utf8 conversion for %s
+ QCOMPARE(QString::asprintf("%s", "\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205"), QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305"));
+
+ int n1;
+ QCOMPARE(QString::asprintf("%s%n%s", "hello", &n1, "goodbye"), u"hellogoodbye");
+ QCOMPARE(n1, 5);
+ qlonglong n2;
+ QCOMPARE(QString::asprintf("%s%s%lln%s", "foo", "bar", &n2, "whiz"), u"foobarwhiz");
+ QCOMPARE((int)n2, 6);
+
+ { // %ls
+
+ QString str(u"Hello"_s);
+ QCOMPARE(QString::asprintf("%.3ls", qUtf16Printable(str)), "Hel"_L1);
+ QCOMPARE(QString::asprintf("%10.3ls", qUtf16Printable(str)), " Hel"_L1);
+ QCOMPARE(QString::asprintf("%.10ls", qUtf16Printable(str)), "Hello"_L1);
+ QCOMPARE(QString::asprintf("%10.10ls", qUtf16Printable(str)), " Hello"_L1);
+ QCOMPARE(QString::asprintf("%-10.10ls", qUtf16Printable(str)), "Hello "_L1);
+ QCOMPARE(QString::asprintf("%-10.3ls", qUtf16Printable(str)), "Hel "_L1);
+ QCOMPARE(QString::asprintf("%-5.5ls", qUtf16Printable(str)), "Hello"_L1);
+ QCOMPARE(QString::asprintf("%*ls", 4, qUtf16Printable(str)), "Hello"_L1);
+ QCOMPARE(QString::asprintf("%*ls", 10, qUtf16Printable(str)), " Hello"_L1);
+ QCOMPARE(QString::asprintf("%-*ls", 10, qUtf16Printable(str)), "Hello "_L1);
+
+ // Check utf16 is preserved for %ls
+ QCOMPARE(QString::asprintf("%ls",
+ qUtf16Printable(QString::fromUtf8(
+ "\303\266\303\244\303\274\303\226\303\204\303\234\303"
+ "\270\303\246\303\245\303\230\303\206\303\205"))),
+ QLatin1String("\366\344\374\326\304\334\370\346\345\330\306\305"));
+
+ int n;
+ QCOMPARE(QString::asprintf("%ls%n%s", qUtf16Printable(u"hello"_s), &n, "goodbye"), "hellogoodbye"_L1);
+ QCOMPARE(n, 5);
+ }
+}
+
+/*
+ indexOf() and indexOf02() test QString::indexOf(),
+ QString::lastIndexOf(), and their QByteArray equivalents.
+
+ lastIndexOf() tests QString::lastIndexOf() more in depth, but it
+ should probably be rewritten to use a data table.
+*/
+
+void tst_QString::indexOf_data()
+{
+ QTest::addColumn<QString>("haystack" );
+ QTest::addColumn<QString>("needle" );
+ QTest::addColumn<int>("startpos" );
+ QTest::addColumn<bool>("bcs" );
+ QTest::addColumn<int>("resultpos" );
+
+ QTest::newRow( "data0" ) << u"abc"_s << u"a"_s << 0 << true << 0;
+ QTest::newRow( "data1" ) << u"abc"_s << u"a"_s << 0 << false << 0;
+ QTest::newRow( "data2" ) << u"abc"_s << u"A"_s << 0 << true << -1;
+ QTest::newRow( "data3" ) << u"abc"_s << u"A"_s << 0 << false << 0;
+ QTest::newRow( "data4" ) << u"abc"_s << u"a"_s << 1 << true << -1;
+ QTest::newRow( "data5" ) << u"abc"_s << u"a"_s << 1 << false << -1;
+ QTest::newRow( "data6" ) << u"abc"_s << u"A"_s << 1 << true << -1;
+ QTest::newRow( "data7" ) << u"abc"_s << u"A"_s << 1 << false << -1;
+ QTest::newRow( "data8" ) << u"abc"_s << u"b"_s << 0 << true << 1;
+ QTest::newRow( "data9" ) << u"abc"_s << u"b"_s << 0 << false << 1;
+ QTest::newRow( "data10" ) << u"abc"_s << u"B"_s << 0 << true << -1;
+ QTest::newRow( "data11" ) << u"abc"_s << u"B"_s << 0 << false << 1;
+ QTest::newRow( "data12" ) << u"abc"_s << u"b"_s << 1 << true << 1;
+ QTest::newRow( "data13" ) << u"abc"_s << u"b"_s << 1 << false << 1;
+ QTest::newRow( "data14" ) << u"abc"_s << u"B"_s << 1 << true << -1;
+ QTest::newRow( "data15" ) << u"abc"_s << u"B"_s << 1 << false << 1;
+ QTest::newRow( "data16" ) << u"abc"_s << u"b"_s << 2 << true << -1;
+ QTest::newRow( "data17" ) << u"abc"_s << u"b"_s << 2 << false << -1;
+
+ QTest::newRow( "data20" ) << u"ABC"_s << u"A"_s << 0 << true << 0;
+ QTest::newRow( "data21" ) << u"ABC"_s << u"A"_s << 0 << false << 0;
+ QTest::newRow( "data22" ) << u"ABC"_s << u"a"_s << 0 << true << -1;
+ QTest::newRow( "data23" ) << u"ABC"_s << u"a"_s << 0 << false << 0;
+ QTest::newRow( "data24" ) << u"ABC"_s << u"A"_s << 1 << true << -1;
+ QTest::newRow( "data25" ) << u"ABC"_s << u"A"_s << 1 << false << -1;
+ QTest::newRow( "data26" ) << u"ABC"_s << u"a"_s << 1 << true << -1;
+ QTest::newRow( "data27" ) << u"ABC"_s << u"a"_s << 1 << false << -1;
+ QTest::newRow( "data28" ) << u"ABC"_s << u"B"_s << 0 << true << 1;
+ QTest::newRow( "data29" ) << u"ABC"_s << u"B"_s << 0 << false << 1;
+ QTest::newRow( "data30" ) << u"ABC"_s << u"b"_s << 0 << true << -1;
+ QTest::newRow( "data31" ) << u"ABC"_s << u"b"_s << 0 << false << 1;
+ QTest::newRow( "data32" ) << u"ABC"_s << u"B"_s << 1 << true << 1;
+ QTest::newRow( "data33" ) << u"ABC"_s << u"B"_s << 1 << false << 1;
+ QTest::newRow( "data34" ) << u"ABC"_s << u"b"_s << 1 << true << -1;
+ QTest::newRow( "data35" ) << u"ABC"_s << u"b"_s << 1 << false << 1;
+ QTest::newRow( "data36" ) << u"ABC"_s << u"B"_s << 2 << true << -1;
+ QTest::newRow( "data37" ) << u"ABC"_s << u"B"_s << 2 << false << -1;
+
+ QTest::newRow( "data40" ) << u"aBc"_s << u"bc"_s << 0 << true << -1;
+ QTest::newRow( "data41" ) << u"aBc"_s << u"Bc"_s << 0 << true << 1;
+ QTest::newRow( "data42" ) << u"aBc"_s << u"bC"_s << 0 << true << -1;
+ QTest::newRow( "data43" ) << u"aBc"_s << u"BC"_s << 0 << true << -1;
+ QTest::newRow( "data44" ) << u"aBc"_s << u"bc"_s << 0 << false << 1;
+ QTest::newRow( "data45" ) << u"aBc"_s << u"Bc"_s << 0 << false << 1;
+ QTest::newRow( "data46" ) << u"aBc"_s << u"bC"_s << 0 << false << 1;
+ QTest::newRow( "data47" ) << u"aBc"_s << u"BC"_s << 0 << false << 1;
+ QTest::newRow( "data48" ) << u"AbC"_s << u"bc"_s << 0 << true << -1;
+ QTest::newRow( "data49" ) << u"AbC"_s << u"Bc"_s << 0 << true << -1;
+ QTest::newRow( "data50" ) << u"AbC"_s << u"bC"_s << 0 << true << 1;
+ QTest::newRow( "data51" ) << u"AbC"_s << u"BC"_s << 0 << true << -1;
+ QTest::newRow( "data52" ) << u"AbC"_s << u"bc"_s << 0 << false << 1;
+ QTest::newRow( "data53" ) << u"AbC"_s << u"Bc"_s << 0 << false << 1;
+
+ QTest::newRow( "data54" ) << u"AbC"_s << u"bC"_s << 0 << false << 1;
+ QTest::newRow( "data55" ) << u"AbC"_s << u"BC"_s << 0 << false << 1;
+ QTest::newRow( "data56" ) << u"AbC"_s << u"BC"_s << 1 << false << 1;
+ QTest::newRow( "data57" ) << u"AbC"_s << u"BC"_s << 2 << false << -1;
+
+ QTest::newRow( "null-in-null") << QString() << QString() << 0 << false << 0;
+ QTest::newRow( "empty-in-null") << QString() << u""_s << 0 << false << 0;
+ QTest::newRow( "null-in-empty") << u""_s << QString() << 0 << false << 0;
+ QTest::newRow( "empty-in-empty") << u""_s << u""_s << 0 << false << 0;
+ QTest::newRow( "data-in-null") << QString() << u"a"_s << 0 << false << -1;
+ QTest::newRow( "data-in-empty") << u""_s << u"a"_s << 0 << false << -1;
+
+
+ QString s1 = u"abc"_s;
+ s1 += QChar(0xb5);
+ QString s2;
+ s2 += QChar(0x3bc);
+ QTest::newRow( "data58" ) << s1 << s2 << 0 << false << 3;
+ s2.prepend(QLatin1Char('C'));
+ QTest::newRow( "data59" ) << s1 << s2 << 0 << false << 2;
+
+ QString veryBigHaystack(500, u'a');
+ veryBigHaystack += u'B';
+ QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0;
+ QTest::newRow("BoyerMooreStressTest2") << QString(veryBigHaystack + u'c') << veryBigHaystack << 0 << true << 0;
+ QTest::newRow("BoyerMooreStressTest3") << QString(u'c' + veryBigHaystack) << veryBigHaystack << 0 << true << 1;
+ QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << QString(veryBigHaystack + u'c') << 0 << true << -1;
+ QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << QString(u'c' + veryBigHaystack) << 0 << true << -1;
+ QTest::newRow("BoyerMooreStressTest6") << QString(u'd' + veryBigHaystack) << QString(u'c' + veryBigHaystack) << 0 << true << -1;
+ QTest::newRow("BoyerMooreStressTest7") << QString(veryBigHaystack + u'c') << QString(u'c' + veryBigHaystack) << 0 << true << -1;
+
+ QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0;
+
+}
+
+void tst_QString::indexOf()
+{
+ QFETCH( QString, haystack );
+ QFETCH( QString, needle );
+ QFETCH( int, startpos );
+ QFETCH( bool, bcs );
+ QFETCH( int, resultpos );
+ CREATE_VIEW(needle);
+
+ Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ bool needleIsLatin = (QString::fromLatin1(needle.toLatin1()) == needle);
+
+ QCOMPARE( haystack.indexOf(needle, startpos, cs), resultpos );
+ QCOMPARE( haystack.indexOf(view, startpos, cs), resultpos );
+ if (needleIsLatin) {
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && ! defined(QT_NO_CAST_FROM_ASCII)
+ QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos, cs), resultpos );
+ QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos, cs), resultpos );
+#endif
+ }
+
+#if QT_CONFIG(regularexpression)
+ {
+ QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
+ if (!bcs)
+ options |= QRegularExpression::CaseInsensitiveOption;
+
+ QRegularExpression re(QRegularExpression::escape(needle), options);
+ QCOMPARE( haystack.indexOf(re, startpos), resultpos );
+ QCOMPARE(haystack.indexOf(re, startpos, nullptr), resultpos);
+
+ QRegularExpressionMatch match;
+ QVERIFY(!match.hasMatch());
+ QCOMPARE(haystack.indexOf(re, startpos, &match), resultpos);
+ QCOMPARE(match.hasMatch(), resultpos != -1);
+ if (resultpos > -1 && needleIsLatin) {
+ if (bcs)
+ QVERIFY(match.captured() == needle);
+ else
+ QVERIFY(match.captured().toLower() == needle.toLower());
+ }
+ }
+#endif
+
+ if (cs == Qt::CaseSensitive) {
+ QCOMPARE( haystack.indexOf(needle, startpos), resultpos );
+ QCOMPARE( haystack.indexOf(view, startpos), resultpos );
+ if (needleIsLatin) {
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos), resultpos );
+ QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos), resultpos );
+#endif
+ }
+ if (startpos == 0) {
+ QCOMPARE( haystack.indexOf(needle), resultpos );
+ QCOMPARE( haystack.indexOf(view), resultpos );
+ if (needleIsLatin) {
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QCOMPARE( haystack.indexOf(needle.toLatin1()), resultpos );
+ QCOMPARE( haystack.indexOf(needle.toLatin1().data()), resultpos );
+#endif
+ }
+ }
+ }
+ if (needle.size() == 1) {
+ QCOMPARE(haystack.indexOf(needle.at(0), startpos, cs), resultpos);
+ QCOMPARE(haystack.indexOf(view.at(0), startpos, cs), resultpos);
+ }
+
+}
+
+void tst_QString::indexOf2_data()
+{
+ QTest::addColumn<QString>("haystack" );
+ QTest::addColumn<QString>("needle" );
+ QTest::addColumn<int>("resultpos" );
+
+ QTest::newRow( "data0" ) << QString() << QString() << 0;
+ QTest::newRow( "data1" ) << QString() << u""_s << 0;
+ QTest::newRow( "data2" ) << u""_s << QString() << 0;
+ QTest::newRow( "data3" ) << u""_s << u""_s << 0;
+ QTest::newRow( "data4" ) << QString() << u"a"_s << -1;
+ QTest::newRow( "data5" ) << QString() << u"abcdefg"_s << -1;
+ QTest::newRow( "data6" ) << u""_s << u"a"_s << -1;
+ QTest::newRow( "data7" ) << u""_s << u"abcdefg"_s << -1;
+
+ QTest::newRow( "data8" ) << u"a"_s << QString() << 0;
+ QTest::newRow( "data9" ) << u"a"_s << u""_s << 0;
+ QTest::newRow( "data10" ) << u"a"_s << u"a"_s << 0;
+ QTest::newRow( "data11" ) << u"a"_s << u"b"_s << -1;
+ QTest::newRow( "data12" ) << u"a"_s << u"abcdefg"_s << -1;
+ QTest::newRow( "data13" ) << u"ab"_s << QString() << 0;
+ QTest::newRow( "data14" ) << u"ab"_s << u""_s << 0;
+ QTest::newRow( "data15" ) << u"ab"_s << u"a"_s << 0;
+ QTest::newRow( "data16" ) << u"ab"_s << u"b"_s << 1;
+ QTest::newRow( "data17" ) << u"ab"_s << u"ab"_s << 0;
+ QTest::newRow( "data18" ) << u"ab"_s << u"bc"_s << -1;
+ QTest::newRow( "data19" ) << u"ab"_s << u"abcdefg"_s << -1;
+
+ QTest::newRow( "data30" ) << u"abc"_s << u"a"_s << 0;
+ QTest::newRow( "data31" ) << u"abc"_s << u"b"_s << 1;
+ QTest::newRow( "data32" ) << u"abc"_s << u"c"_s << 2;
+ QTest::newRow( "data33" ) << u"abc"_s << u"d"_s << -1;
+ QTest::newRow( "data34" ) << u"abc"_s << u"ab"_s << 0;
+ QTest::newRow( "data35" ) << u"abc"_s << u"bc"_s << 1;
+ QTest::newRow( "data36" ) << u"abc"_s << u"cd"_s << -1;
+ QTest::newRow( "data37" ) << u"abc"_s << u"ac"_s << -1;
+
+ // sizeof(whale) > 32
+ QString whale = u"a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn"_s;
+ QString minnow = u"zby"_s;
+
+ QTest::newRow( "data40" ) << whale << minnow << 2;
+ QTest::newRow( "data41" ) << QString(whale + whale) << minnow << 2;
+ QTest::newRow( "data42" ) << QString(minnow + whale) << minnow << 0;
+ QTest::newRow( "data43" ) << whale << whale << 0;
+ QTest::newRow( "data44" ) << QString(whale + whale) << whale << 0;
+ QTest::newRow( "data45" ) << whale << QString(whale + whale) << -1;
+ QTest::newRow( "data46" ) << QString(whale + whale) << QString(whale + whale) << 0;
+ QTest::newRow( "data47" ) << QString(whale + whale) << QString(whale + minnow) << -1;
+ QTest::newRow( "data48" ) << QString(minnow + whale) << whale << (int)minnow.size();
+}
+
+void tst_QString::indexOf2()
+{
+ QFETCH( QString, haystack );
+ QFETCH( QString, needle );
+ QFETCH( int, resultpos );
+ CREATE_VIEW(needle);
+
+ QByteArray chaystack = haystack.toLatin1();
+ QByteArray cneedle = needle.toLatin1();
+ int got;
+
+ QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseSensitive), resultpos );
+ QCOMPARE( haystack.indexOf(view, 0, Qt::CaseSensitive), resultpos );
+ QCOMPARE( QStringMatcher(needle, Qt::CaseSensitive).indexIn(haystack, 0), resultpos );
+ QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseInsensitive), resultpos );
+ QCOMPARE( haystack.indexOf(view, 0, Qt::CaseInsensitive), resultpos );
+ QCOMPARE( QStringMatcher(needle, Qt::CaseInsensitive).indexIn(haystack, 0), resultpos );
+ if ( needle.size() > 0 ) {
+ got = haystack.lastIndexOf( needle, -1, Qt::CaseSensitive );
+ QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
+ got = haystack.lastIndexOf( needle, -1, Qt::CaseInsensitive );
+ QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
+ }
+
+ QCOMPARE( chaystack.indexOf(cneedle, 0), resultpos );
+ QCOMPARE( QByteArrayMatcher(cneedle).indexIn(chaystack, 0), resultpos );
+ if ( cneedle.size() > 0 ) {
+ got = chaystack.lastIndexOf(cneedle, -1);
+ QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
+ }
+}
+
+#if QT_CONFIG(regularexpression)
+void tst_QString::indexOfInvalidRegex()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ u"^QString\\(View\\)::indexOf\\(\\): called on an invalid QRegularExpression object"_s
+ );
+
+ QString str = u"invalid regex\\"_s;
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(str.indexOf(QRegularExpression(str)), -1);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(str.indexOf(QRegularExpression(str), -1, nullptr), -1);
+
+ QRegularExpressionMatch match;
+ QVERIFY(!match.hasMatch());
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(str.indexOf(QRegularExpression(str), -1, &match), -1);
+ QVERIFY(!match.hasMatch());
+}
+#endif
+
+void tst_QString::lastIndexOf_data()
+{
+ QTest::addColumn<QString>("haystack" );
+ QTest::addColumn<QString>("needle" );
+ QTest::addColumn<int>("from" );
+ QTest::addColumn<int>("expected" );
+ QTest::addColumn<bool>("caseSensitive" );
+
+ QString a = u"ABCDEFGHIEfGEFG"_s;
+
+ QTest::newRow("-1") << a << "G" << int(a.size()) - 1 << 14 << true;
+ QTest::newRow("1") << a << "G" << - 1 << 14 << true;
+ QTest::newRow("2") << a << "G" << -3 << 11 << true;
+ QTest::newRow("3") << a << "G" << -5 << 6 << true;
+ QTest::newRow("4") << a << "G" << 14 << 14 << true;
+ QTest::newRow("5") << a << "G" << 13 << 11 << true;
+ QTest::newRow("6") << a << "B" << int(a.size()) - 1 << 1 << true;
+ QTest::newRow("7") << a << "B" << - 1 << 1 << true;
+ QTest::newRow("8") << a << "B" << 1 << 1 << true;
+ QTest::newRow("9") << a << "B" << 0 << -1 << true;
+
+ QTest::newRow("10") << a << "G" << -1 << int(a.size())-1 << true;
+ QTest::newRow("11") << a << "G" << int(a.size())-1 << int(a.size())-1 << true;
+ QTest::newRow("12") << a << "G" << int(a.size()) << int(a.size())-1 << true;
+ QTest::newRow("13") << a << "A" << 0 << 0 << true;
+ QTest::newRow("14") << a << "A" << -1*int(a.size()) << 0 << true;
+
+ QTest::newRow("15") << a << "efg" << 0 << -1 << false;
+ QTest::newRow("16") << a << "efg" << int(a.size()) << 12 << false;
+ QTest::newRow("17") << a << "efg" << -1 * int(a.size()) << -1 << false;
+ QTest::newRow("19") << a << "efg" << int(a.size()) - 1 << 12 << false;
+ QTest::newRow("20") << a << "efg" << 12 << 12 << false;
+ QTest::newRow("21") << a << "efg" << -12 << -1 << false;
+ QTest::newRow("22") << a << "efg" << 11 << 9 << false;
+
+ QTest::newRow("24") << "" << "asdf" << -1 << -1 << false;
+ QTest::newRow("25") << "asd" << "asdf" << -1 << -1 << false;
+ QTest::newRow("26") << "" << QString() << -1 << -1 << false;
+
+ QTest::newRow("27") << a << "" << int(a.size()) << int(a.size()) << false;
+ QTest::newRow("28") << a << "" << int(a.size()) + 10 << -1 << false;
+
+ QTest::newRow("null-in-null") << QString() << QString() << 0 << 0 << false;
+ QTest::newRow("empty-in-null") << QString() << u""_s << 0 << 0 << false;
+ QTest::newRow("null-in-empty") << u""_s << QString() << 0 << 0 << false;
+ QTest::newRow("empty-in-empty") << u""_s << u""_s << 0 << 0 << false;
+ QTest::newRow("data-in-null") << QString() << u"a"_s << 0 << -1 << false;
+ QTest::newRow("data-in-empty") << u""_s << u"a"_s << 0 << -1 << false;
+}
+
+void tst_QString::lastIndexOf()
+{
+ QFETCH(QString, haystack);
+ QFETCH(QString, needle);
+ QFETCH(int, from);
+ QFETCH(int, expected);
+ QFETCH(bool, caseSensitive);
+ CREATE_VIEW(needle);
+
+ Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
+
+ QCOMPARE(haystack.lastIndexOf(needle, from, cs), expected);
+ QCOMPARE(haystack.lastIndexOf(view, from, cs), expected);
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from, cs), expected);
+ QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from, cs), expected);
+#endif
+
+#if QT_CONFIG(regularexpression)
+ if (from >= -1 && from < haystack.size() && needle.size() > 0) {
+ // unfortunately, QString and QRegularExpression don't have the same out of bound semantics
+ // I think QString is wrong -- See file log for contact information.
+ {
+ QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
+ if (!caseSensitive)
+ options |= QRegularExpression::CaseInsensitiveOption;
+
+ QRegularExpression re(QRegularExpression::escape(needle), options);
+ QCOMPARE(haystack.lastIndexOf(re, from), expected);
+ QCOMPARE(haystack.lastIndexOf(re, from, nullptr), expected);
+ QRegularExpressionMatch match;
+ QVERIFY(!match.hasMatch());
+ QCOMPARE(haystack.lastIndexOf(re, from, &match), expected);
+ QCOMPARE(match.hasMatch(), expected > -1);
+ if (expected > -1) {
+ if (caseSensitive)
+ QCOMPARE(match.captured(), needle);
+ else
+ QCOMPARE(match.captured().toLower(), needle.toLower());
+ }
+ }
+ }
+#endif
+
+ if (cs == Qt::CaseSensitive) {
+ QCOMPARE(haystack.lastIndexOf(needle, from), expected);
+ QCOMPARE(haystack.lastIndexOf(view, from), expected);
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from), expected);
+ QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from), expected);
+#endif
+ if (from == haystack.size()) {
+ QCOMPARE(haystack.lastIndexOf(needle), expected);
+ QCOMPARE(haystack.lastIndexOf(view), expected);
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QCOMPARE(haystack.lastIndexOf(needle.toLatin1()), expected);
+ QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data()), expected);
+#endif
+ }
+ }
+ if (needle.size() == 1) {
+ QCOMPARE(haystack.lastIndexOf(needle.at(0), from), expected);
+ QCOMPARE(haystack.lastIndexOf(view.at(0), from), expected);
+ }
+}
+
+#if QT_CONFIG(regularexpression)
+void tst_QString::lastIndexOfInvalidRegex()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ u"^QString\\(View\\)::lastIndexOf\\(\\): called on an invalid QRegularExpression object"_s
+ );
+
+ const QString str(u"invalid regex\\"_s);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(str.lastIndexOf(QRegularExpression(str), 0), -1);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(str.lastIndexOf(QRegularExpression(str), -1, nullptr), -1);
+
+ QRegularExpressionMatch match;
+ QVERIFY(!match.hasMatch());
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(str.lastIndexOf(QRegularExpression(str), -1, &match), -1);
+ QVERIFY(!match.hasMatch());
+}
+#endif
+
+void tst_QString::count()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ u"^QString\\(View\\)::count\\(\\): called on an invalid QRegularExpression object"_s
+ );
+
+ QString a(u"ABCDEFGHIEfGEFG"_s);
+ QCOMPARE(a.size(), 15);
+
+ QCOMPARE(a.count(QChar(u'A')), 1);
+ QCOMPARE(a.count(QChar(u'Z')), 0);
+ QCOMPARE(a.count(QChar(u'E')), 3);
+ QCOMPARE(a.count(QChar(u'F')), 2);
+ QCOMPARE(a.count(QChar(u'F'), Qt::CaseInsensitive), 3);
+
+ QCOMPARE(a.count(QString(u"FG"_s)), 2);
+ QCOMPARE(a.count(QString(u"FG"_s), Qt::CaseInsensitive), 3);
+
+ QCOMPARE(a.count(QStringView(u"FG")), 2);
+ QCOMPARE(a.count(QStringView(u"FG"), Qt::CaseInsensitive), 3);
+
+ QCOMPARE(a.count(QLatin1StringView("FG")), 2);
+ QCOMPARE(a.count(QLatin1StringView("FG"), Qt::CaseInsensitive), 3);
+
+ QCOMPARE(a.count( QString(), Qt::CaseInsensitive), 16);
+ QCOMPARE(a.count(QString(u""_s), Qt::CaseInsensitive), 16);
+ QCOMPARE(a.count(QStringView(u""), Qt::CaseInsensitive), 16);
+ QCOMPARE(a.count(QLatin1StringView(""), Qt::CaseInsensitive), 16);
+
+#if QT_CONFIG(regularexpression)
+ QCOMPARE(a.count(QRegularExpression(u""_s)), 16);
+ QCOMPARE(a.count(QRegularExpression(u"[FG][HI]"_s)), 1);
+ QCOMPARE(a.count(QRegularExpression(u"[G][HE]"_s)), 2);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(a.count(QRegularExpression(u"invalid regex\\"_s)), 0);
+#endif
+
+ CREATE_VIEW(QLatin1String("FG"));
+ QCOMPARE(a.count(view),2);
+ QCOMPARE(a.count(view,Qt::CaseInsensitive),3);
+ QCOMPARE(a.count( QStringView(), Qt::CaseInsensitive), 16);
+
+ QString nullStr;
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(nullStr.size(), 0);)
+#endif
+ QCOMPARE(nullStr.count(QChar(u'A')), 0);
+ QCOMPARE(nullStr.count(QString(u"AB"_s)), 0);
+ QCOMPARE(nullStr.count(view), 0);
+ QCOMPARE(nullStr.count(QLatin1StringView("AB")), 0);
+
+ QCOMPARE(nullStr.count(QString()), 1);
+ QCOMPARE(nullStr.count(QString(u""_s)), 1);
+ QCOMPARE(nullStr.count(QStringView(u"")), 1);
+ QCOMPARE(nullStr.count(QLatin1StringView("")), 1);
+
+#if QT_CONFIG(regularexpression)
+ QCOMPARE(nullStr.count(QRegularExpression(u""_s)), 1);
+ QCOMPARE(nullStr.count(QRegularExpression(u"[FG][HI]"_s)), 0);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(nullStr.count(QRegularExpression(u"invalid regex\\"_s)), 0);
+#endif
+
+ QString emptyStr(u""_s);
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(emptyStr.size(), 0);)
+#endif
+ QCOMPARE(emptyStr.count(u'A'), 0);
+ QCOMPARE(emptyStr.count(QString(u"AB"_s)), 0);
+ QCOMPARE(emptyStr.count(view), 0);
+ QCOMPARE(emptyStr.count(QString()), 1);
+ QCOMPARE(emptyStr.count(QStringView()), 1);
+ QCOMPARE(emptyStr.count(QLatin1StringView()), 1);
+ QCOMPARE(emptyStr.count(QString(u""_s)), 1);
+ QCOMPARE(emptyStr.count(QStringView(u"")), 1);
+ QCOMPARE(emptyStr.count(QLatin1StringView("")), 1);
+
+#if QT_CONFIG(regularexpression)
+ QCOMPARE(emptyStr.count(QRegularExpression(u""_s)), 1);
+ QCOMPARE(emptyStr.count(QRegularExpression(u"[FG][HI]"_s)), 0);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(emptyStr.count(QRegularExpression(u"invalid regex\\"_s)), 0);
+#endif
+
+ QString nonBmpString = u"\U00010000\U00010000abc\U00010000"_s;
+ QCOMPARE(nonBmpString.count(u"\U00010000"), 3);
+#if QT_CONFIG(regularexpression)
+ QCOMPARE(nonBmpString.count(QRegularExpression(u"\U00010000"_s)), 3);
+ QCOMPARE(nonBmpString.count(QRegularExpression(u"\U00010000a?"_s)), 3);
+ QCOMPARE(nonBmpString.count(QRegularExpression(u"\U00010000a"_s)), 1);
+ QCOMPARE(nonBmpString.count(QRegularExpression(u"."_s)), 6);
+
+ // can't search for unpaired surrogates
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(nonBmpString.count(QRegularExpression(QChar(0xd800))), 0);
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QCOMPARE(nonBmpString.count(QRegularExpression(QChar(0xdc00))), 0);
+#endif // QT_CONFIG(regularexpression)
+}
+
+void tst_QString::contains()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ u"^QString\\(View\\)::contains\\(\\): called on an invalid QRegularExpression object"_s
+ );
+
+ QString a(u"ABCDEFGHIEfGEFG"_s);
+ QCOMPARE(a.size(), 15);
+
+ QVERIFY(a.contains(QChar(u'A')));
+ QVERIFY(!a.contains(QChar(u'Z')));
+ QVERIFY(a.contains(QChar(u'E')));
+ QVERIFY(a.contains(QChar(u'F')));
+ QVERIFY(a.contains(QChar(u'f'), Qt::CaseInsensitive));
+
+ QVERIFY(a.contains(QString(u"FG"_s)));
+ QVERIFY(a.contains(QString(u"FG"_s), Qt::CaseInsensitive));
+ QVERIFY(a.contains(QStringView(u"FG")));
+ QVERIFY(a.contains(QStringView(u"fg"), Qt::CaseInsensitive));
+
+ QVERIFY(a.contains(QLatin1String("FG")));
+ QVERIFY(a.contains(QLatin1String("fg"),Qt::CaseInsensitive));
+
+ QVERIFY(a.contains(QString(), Qt::CaseInsensitive));
+ QVERIFY(a.contains(QString(u""_s), Qt::CaseInsensitive));
+ QVERIFY(a.contains(QStringView(), Qt::CaseInsensitive));
+ QVERIFY(a.contains(QStringView(u""), Qt::CaseInsensitive));
+ QVERIFY(a.contains(QLatin1StringView(), Qt::CaseInsensitive));
+ QVERIFY(a.contains(QLatin1StringView(""), Qt::CaseInsensitive));
+
+#if QT_CONFIG(regularexpression)
+ QVERIFY(a.contains(QRegularExpression(u"[FG][HI]"_s)));
+ QVERIFY(a.contains(QRegularExpression(u"[G][HE]"_s)));
+
+ {
+ QRegularExpressionMatch match;
+ QVERIFY(!match.hasMatch());
+
+ QVERIFY(a.contains(QRegularExpression(u"[FG][HI]"_s), &match));
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.capturedStart(), 6);
+ QCOMPARE(match.capturedEnd(), 8);
+ QCOMPARE(match.captured(), QStringLiteral("GH"));
+
+ QVERIFY(a.contains(QRegularExpression(u"[G][HE]"_s), &match));
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.capturedStart(), 6);
+ QCOMPARE(match.capturedEnd(), 8);
+ QCOMPARE(match.captured(), QStringLiteral("GH"));
+
+ QVERIFY(a.contains(QRegularExpression(u"[f](.*)[FG]"_s), &match));
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.capturedStart(), 10);
+ QCOMPARE(match.capturedEnd(), 15);
+ QCOMPARE(match.captured(), u"fGEFG");
+ QCOMPARE(match.capturedStart(1), 11);
+ QCOMPARE(match.capturedEnd(1), 14);
+ QCOMPARE(match.captured(1), QStringLiteral("GEF"));
+
+ QVERIFY(a.contains(QRegularExpression(u"[f](.*)[F]"_s), &match));
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.capturedStart(), 10);
+ QCOMPARE(match.capturedEnd(), 14);
+ QCOMPARE(match.captured(), u"fGEF");
+ QCOMPARE(match.capturedStart(1), 11);
+ QCOMPARE(match.capturedEnd(1), 13);
+ QCOMPARE(match.captured(1), QStringLiteral("GE"));
+
+ QVERIFY(!a.contains(QRegularExpression(u"ZZZ"_s), &match));
+ // doesn't match, but ensure match didn't change
+ QVERIFY(match.hasMatch());
+ QCOMPARE(match.capturedStart(), 10);
+ QCOMPARE(match.capturedEnd(), 14);
+ QCOMPARE(match.captured(), QStringLiteral("fGEF"));
+ QCOMPARE(match.capturedStart(1), 11);
+ QCOMPARE(match.capturedEnd(1), 13);
+ QCOMPARE(match.captured(1), QStringLiteral("GE"));
+
+ // don't crash with a null pointer
+ QVERIFY(a.contains(QRegularExpression(u"[FG][HI]"_s), 0));
+ QVERIFY(!a.contains(QRegularExpression(u"ZZZ"_s), 0));
+ }
+
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ QVERIFY(!a.contains(QRegularExpression(u"invalid regex\\"_s)));
+#endif
+
+ CREATE_VIEW(QLatin1String("FG"));
+ QVERIFY(a.contains(view));
+ QVERIFY(a.contains(view, Qt::CaseInsensitive));
+ QVERIFY(a.contains( QStringView(), Qt::CaseInsensitive));
+
+ QString nullStr;
+ QVERIFY(!nullStr.contains(u'A'));
+ QVERIFY(!nullStr.contains(QString(u"AB"_s)));
+ QVERIFY(!nullStr.contains(QLatin1StringView("AB")));
+ QVERIFY(!nullStr.contains(view));
+#if QT_CONFIG(regularexpression)
+ QVERIFY(!nullStr.contains(QRegularExpression(u"[FG][HI]"_s)));
+ QRegularExpressionMatch nullMatch;
+ QVERIFY(nullStr.contains(QRegularExpression(u""_s), &nullMatch));
+ QVERIFY(nullMatch.hasMatch());
+ QCOMPARE(nullMatch.captured(), u"");
+ QCOMPARE(nullMatch.capturedStart(), 0);
+ QCOMPARE(nullMatch.capturedEnd(), 0);
+#endif
+ QVERIFY(!nullStr.isDetached());
+
+ QString emptyStr(u""_s);
+ QVERIFY(!emptyStr.contains(u'A'));
+ QVERIFY(!emptyStr.contains(QString(u"AB"_s)));
+ QVERIFY(!emptyStr.contains(QLatin1StringView("AB")));
+ QVERIFY(!emptyStr.contains(view));
+#if QT_CONFIG(regularexpression)
+ QVERIFY(!emptyStr.contains(QRegularExpression(u"[FG][HI]"_s)));
+ QRegularExpressionMatch emptyMatch;
+ QVERIFY(emptyStr.contains(QRegularExpression(u""_s), &emptyMatch));
+ QVERIFY(emptyMatch.hasMatch());
+ QCOMPARE(emptyMatch.captured(), u"");
+ QCOMPARE(emptyMatch.capturedStart(), 0);
+ QCOMPARE(emptyMatch.capturedEnd(), 0);
+#endif
+ QVERIFY(!emptyStr.isDetached());
+}
+
+
+void tst_QString::left()
+{
+ QString a;
+
+ // lvalue
+ QVERIFY(a.left(0).isNull());
+ QVERIFY(a.left(5).isNull());
+ QVERIFY(a.left(-4).isNull());
+ QVERIFY(!a.isDetached());
+
+ // rvalue, not detached
+ QVERIFY(QString(a).left(0).isNull());
+ QVERIFY(QString(a).left(5).isNull());
+ QVERIFY(QString(a).left(-4).isNull());
+ QVERIFY(!QString(a).isDetached());
+
+ // rvalue, detached is not applicable
+
+ a = u"ABCDEFGHIEfGEFG"_s;
+ QCOMPARE(a.size(), 15);
+
+ // lvalue
+ QCOMPARE(a.left(3), QLatin1String("ABC"));
+ QVERIFY(!a.left(0).isNull());
+ QCOMPARE(a.left(0), QLatin1String(""));
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).left(3), QLatin1String("ABC"));
+ QVERIFY(!QString(a).left(0).isNull());
+ QCOMPARE(QString(a).left(0), QLatin1String(""));
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, detached
+ QCOMPARE(detached(a).left(3), QLatin1String("ABC"));
+ QVERIFY(!detached(a).left(0).isNull());
+ QCOMPARE(detached(a).left(0), QLatin1String(""));
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ QString n;
+ QVERIFY(QString().left(3).isNull());
+ QVERIFY(QString().left(0).isNull());
+ QVERIFY(QString().left(0).isNull());
+ QVERIFY(n.left(3).isNull());
+ QVERIFY(n.left(0).isNull());
+ QVERIFY(n.left(0).isNull());
+
+ QString l = u"Left"_s;
+
+ // lvalue
+ QCOMPARE(l.left(-1), l);
+ QCOMPARE(l.left(100), l);
+ QCOMPARE(l, u"Left");
+
+ // rvalue, not detached
+ QCOMPARE(QString(l).left(-1), l);
+ QCOMPARE(QString(l).left(100), l);
+ QCOMPARE(l, u"Left");
+
+ // rvalue, detached
+ QCOMPARE(detached(l).left(-1), l);
+ QCOMPARE(detached(l).left(100), l);
+ QCOMPARE(l, u"Left");
+}
+
+void tst_QString::right()
+{
+ QString a;
+
+ // lvalue
+ QVERIFY(a.right(0).isNull());
+ QVERIFY(a.right(5).isNull());
+ QVERIFY(a.right(-4).isNull());
+ QVERIFY(!a.isDetached());
+
+ // rvalue, not detached
+ QVERIFY(QString(a).right(0).isNull());
+ QVERIFY(QString(a).right(5).isNull());
+ QVERIFY(QString(a).right(-4).isNull());
+ QVERIFY(!QString(a).isDetached());
+
+ // rvalue, detached is not applicable
+
+ a = u"ABCDEFGHIEfGEFG"_s;
+ QCOMPARE(a.size(), 15);
+
+ // lvalue
+ QCOMPARE(a.right(3), QLatin1String("EFG"));
+ QCOMPARE(a.right(0), QLatin1String(""));
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).right(3), QLatin1String("EFG"));
+ QCOMPARE(QString(a).right(0), QLatin1String(""));
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, detached
+ QCOMPARE(detached(a).right(3), QLatin1String("EFG"));
+ QCOMPARE(detached(a).right(0), QLatin1String(""));
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ QString n;
+ QVERIFY(QString().right(3).isNull());
+ QVERIFY(QString().right(0).isNull());
+ QVERIFY(n.right(3).isNull());
+ QVERIFY(n.right(0).isNull());
+
+ QString r = u"Right"_s;
+
+ // lvalue
+ QCOMPARE(r.right(-1), r);
+ QCOMPARE(r.right(100), r);
+ QCOMPARE(r, u"Right");
+
+ // rvalue, not detached
+ QCOMPARE(QString(r).right(-1), r);
+ QCOMPARE(QString(r).right(100), r);
+ QCOMPARE(r, u"Right");
+
+ // rvalue, detached
+ QCOMPARE(detached(r).right(-1), r);
+ QCOMPARE(detached(r).right(100), r);
+ QCOMPARE(r, u"Right");
+}
+
+void tst_QString::mid()
+{
+ QString a;
+
+ QVERIFY(a.mid(0).isNull());
+ QVERIFY(a.mid(5, 6).isNull());
+ QVERIFY(a.mid(-4, 3).isNull());
+ QVERIFY(a.mid(4, -3).isNull());
+ QVERIFY(!a.isDetached());
+
+ a = u"ABCDEFGHIEfGEFG"_s;
+ QCOMPARE(a.size(), 15);
+
+ // lvalue
+ QCOMPARE(a.mid(3,3), QLatin1String("DEF"));
+ QCOMPARE(a.mid(0,0), QLatin1String(""));
+ QVERIFY(!a.mid(15,0).isNull());
+ QVERIFY(a.mid(15,0).isEmpty());
+ QVERIFY(!a.mid(15,1).isNull());
+ QVERIFY(a.mid(15,1).isEmpty());
+ QVERIFY(a.mid(9999).isNull());
+ QVERIFY(a.mid(9999,1).isNull());
+ QCOMPARE(a.mid(-1, 6), a.mid(0, 5));
+ QVERIFY(a.mid(-100, 6).isEmpty());
+ QVERIFY(a.mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(a.mid(INT_MIN, -1), a);
+ QVERIFY(a.mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1));
+ QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a);
+ QVERIFY(a.mid(INT_MAX).isNull());
+ QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(a.mid(-5, INT_MAX), a);
+ QCOMPARE(a.mid(-1, INT_MAX), a);
+ QCOMPARE(a.mid(0, INT_MAX), a);
+ QCOMPARE(a.mid(1, INT_MAX), u"BCDEFGHIEfGEFG");
+ QCOMPARE(a.mid(5, INT_MAX), u"FGHIEfGEFG");
+ QVERIFY(a.mid(20, INT_MAX).isNull());
+ QCOMPARE(a.mid(-1, -1), a);
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).mid(3,3), QLatin1String("DEF"));
+ QCOMPARE(QString(a).mid(0,0), QLatin1String(""));
+ QVERIFY(!QString(a).mid(15,0).isNull());
+ QVERIFY(QString(a).mid(15,0).isEmpty());
+ QVERIFY(!QString(a).mid(15,1).isNull());
+ QVERIFY(QString(a).mid(15,1).isEmpty());
+ QVERIFY(QString(a).mid(9999).isNull());
+ QVERIFY(QString(a).mid(9999,1).isNull());
+ QCOMPARE(QString(a).mid(-1, 6), QString(a).mid(0, 5));
+ QVERIFY(QString(a).mid(-100, 6).isEmpty());
+ QVERIFY(QString(a).mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(QString(a).mid(INT_MIN, -1), a);
+ QVERIFY(QString(a).mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(QString(a).mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(QString(a).mid(INT_MIN + 2, INT_MAX), a.left(1));
+ QCOMPARE(QString(a).mid(INT_MIN + a.size() + 1, INT_MAX), a);
+ QVERIFY(QString(a).mid(INT_MAX).isNull());
+ QVERIFY(QString(a).mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(QString(a).mid(-5, INT_MAX), a);
+ QCOMPARE(QString(a).mid(-1, INT_MAX), a);
+ QCOMPARE(QString(a).mid(0, INT_MAX), a);
+ QCOMPARE(QString(a).mid(1, INT_MAX), u"BCDEFGHIEfGEFG");
+ QCOMPARE(QString(a).mid(5, INT_MAX), u"FGHIEfGEFG");
+ QVERIFY(QString(a).mid(20, INT_MAX).isNull());
+ QCOMPARE(QString(a).mid(-1, -1), a);
+
+ // rvalue, detached
+ QCOMPARE(detached(a).mid(3,3), QLatin1String("DEF"));
+ QCOMPARE(detached(a).mid(0,0), QLatin1String(""));
+ QVERIFY(!detached(a).mid(15,0).isNull());
+ QVERIFY(detached(a).mid(15,0).isEmpty());
+ QVERIFY(!detached(a).mid(15,1).isNull());
+ QVERIFY(detached(a).mid(15,1).isEmpty());
+ QVERIFY(detached(a).mid(9999).isNull());
+ QVERIFY(detached(a).mid(9999,1).isNull());
+ QCOMPARE(detached(a).mid(-1, 6), detached(a).mid(0, 5));
+ QVERIFY(detached(a).mid(-100, 6).isEmpty());
+ QVERIFY(detached(a).mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(detached(a).mid(INT_MIN, -1), a);
+ QVERIFY(detached(a).mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(detached(a).mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(detached(a).mid(INT_MIN + 2, INT_MAX), a.left(1));
+ QCOMPARE(detached(a).mid(INT_MIN + a.size() + 1, INT_MAX), a);
+ QVERIFY(detached(a).mid(INT_MAX).isNull());
+ QVERIFY(detached(a).mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(detached(a).mid(-5, INT_MAX), a);
+ QCOMPARE(detached(a).mid(-1, INT_MAX), a);
+ QCOMPARE(detached(a).mid(0, INT_MAX), a);
+ QCOMPARE(detached(a).mid(1, INT_MAX), u"BCDEFGHIEfGEFG");
+ QCOMPARE(detached(a).mid(5, INT_MAX), u"FGHIEfGEFG");
+ QVERIFY(detached(a).mid(20, INT_MAX).isNull());
+ QCOMPARE(detached(a).mid(-1, -1), a);
+
+ QString n;
+ QVERIFY(n.mid(3,3).isNull());
+ QVERIFY(n.mid(0,0).isNull());
+ QVERIFY(n.mid(9999,0).isNull());
+ QVERIFY(n.mid(9999,1).isNull());
+ QVERIFY(n.mid(-1, 6).isNull());
+ QVERIFY(n.mid(-100, 6).isNull());
+ QVERIFY(n.mid(INT_MIN, 0).isNull());
+ QVERIFY(n.mid(INT_MIN, -1).isNull());
+ QVERIFY(n.mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MIN + 1, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MIN + 2, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MIN + n.size() + 1, INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MAX).isNull());
+ QVERIFY(n.mid(INT_MAX, INT_MAX).isNull());
+ QVERIFY(n.mid(-5, INT_MAX).isNull());
+ QVERIFY(n.mid(-1, INT_MAX).isNull());
+ QVERIFY(n.mid(0, INT_MAX).isNull());
+ QVERIFY(n.mid(1, INT_MAX).isNull());
+ QVERIFY(n.mid(5, INT_MAX).isNull());
+ QVERIFY(n.mid(20, INT_MAX).isNull());
+ QVERIFY(n.mid(-1, -1).isNull());
+
+ QVERIFY(QString().mid(3,3).isNull());
+ QVERIFY(QString().mid(0,0).isNull());
+ QVERIFY(QString().mid(9999,0).isNull());
+ QVERIFY(QString().mid(9999,1).isNull());
+ QVERIFY(QString().mid(-1, 6).isNull());
+ QVERIFY(QString().mid(-100, 6).isNull());
+ QVERIFY(QString().mid(INT_MIN, 0).isNull());
+ QVERIFY(QString().mid(INT_MIN, -1).isNull());
+ QVERIFY(QString().mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(QString().mid(INT_MIN + 1, INT_MAX).isNull());
+ QVERIFY(QString().mid(INT_MIN + 2, INT_MAX).isNull());
+ QVERIFY(QString().mid(INT_MIN + QString().size() + 1, INT_MAX).isNull());
+ QVERIFY(QString().mid(INT_MAX).isNull());
+ QVERIFY(QString().mid(INT_MAX, INT_MAX).isNull());
+ QVERIFY(QString().mid(-5, INT_MAX).isNull());
+ QVERIFY(QString().mid(-1, INT_MAX).isNull());
+ QVERIFY(QString().mid(0, INT_MAX).isNull());
+ QVERIFY(QString().mid(1, INT_MAX).isNull());
+ QVERIFY(QString().mid(5, INT_MAX).isNull());
+ QVERIFY(QString().mid(20, INT_MAX).isNull());
+ QVERIFY(QString().mid(-1, -1).isNull());
+
+ QString x = u"Nine pineapples"_s;
+ QCOMPARE(x.mid(5, 4), u"pine");
+ QCOMPARE(x.mid(5), u"pineapples");
+ QCOMPARE(x.mid(-1, 6), x.mid(0, 5));
+ QVERIFY(x.mid(-100, 6).isEmpty());
+ QVERIFY(x.mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(x.mid(INT_MIN, -1), x);
+ QVERIFY(x.mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1));
+ QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX), x);
+ QVERIFY(x.mid(INT_MAX).isNull());
+ QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(x.mid(-5, INT_MAX), x);
+ QCOMPARE(x.mid(-1, INT_MAX), x);
+ QCOMPARE(x.mid(0, INT_MAX), x);
+ QCOMPARE(x.mid(1, INT_MAX), u"ine pineapples");
+ QCOMPARE(x.mid(5, INT_MAX), u"pineapples");
+ QVERIFY(x.mid(20, INT_MAX).isNull());
+ QCOMPARE(x.mid(-1, -1), x);
+ QCOMPARE(x, u"Nine pineapples");
+
+ // rvalue, not detached
+ QCOMPARE(QString(x).mid(5, 4), u"pine");
+ QCOMPARE(QString(x).mid(5), u"pineapples");
+ QCOMPARE(QString(x).mid(-1, 6), QString(x).mid(0, 5));
+ QVERIFY(QString(x).mid(-100, 6).isEmpty());
+ QVERIFY(QString(x).mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(QString(x).mid(INT_MIN, -1), x);
+ QVERIFY(QString(x).mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(QString(x).mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(QString(x).mid(INT_MIN + 2, INT_MAX), x.left(1));
+ QCOMPARE(QString(x).mid(INT_MIN + x.size() + 1, INT_MAX), x);
+ QVERIFY(QString(x).mid(INT_MAX).isNull());
+ QVERIFY(QString(x).mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(QString(x).mid(-5, INT_MAX), x);
+ QCOMPARE(QString(x).mid(-1, INT_MAX), x);
+ QCOMPARE(QString(x).mid(0, INT_MAX), x);
+ QCOMPARE(QString(x).mid(1, INT_MAX), u"ine pineapples");
+ QCOMPARE(QString(x).mid(5, INT_MAX), u"pineapples");
+ QVERIFY(QString(x).mid(20, INT_MAX).isNull());
+ QCOMPARE(QString(x).mid(-1, -1), x);
+ QCOMPARE(x, u"Nine pineapples");
+
+ // rvalue, detached
+ QCOMPARE(detached(x).mid(5, 4), u"pine");
+ QCOMPARE(detached(x).mid(5), u"pineapples");
+ QCOMPARE(detached(x).mid(-1, 6), detached(x).mid(0, 5));
+ QVERIFY(detached(x).mid(-100, 6).isEmpty());
+ QVERIFY(detached(x).mid(INT_MIN, 0).isEmpty());
+ QCOMPARE(detached(x).mid(INT_MIN, -1), x);
+ QVERIFY(detached(x).mid(INT_MIN, INT_MAX).isNull());
+ QVERIFY(detached(x).mid(INT_MIN + 1, INT_MAX).isEmpty());
+ QCOMPARE(detached(x).mid(INT_MIN + 2, INT_MAX), x.left(1));
+ QCOMPARE(detached(x).mid(INT_MIN + x.size() + 1, INT_MAX), x);
+ QVERIFY(detached(x).mid(INT_MAX).isNull());
+ QVERIFY(detached(x).mid(INT_MAX, INT_MAX).isNull());
+ QCOMPARE(detached(x).mid(-5, INT_MAX), x);
+ QCOMPARE(detached(x).mid(-1, INT_MAX), x);
+ QCOMPARE(detached(x).mid(0, INT_MAX), x);
+ QCOMPARE(detached(x).mid(1, INT_MAX), u"ine pineapples");
+ QCOMPARE(detached(x).mid(5, INT_MAX), u"pineapples");
+ QVERIFY(detached(x).mid(20, INT_MAX).isNull());
+ QCOMPARE(detached(x).mid(-1, -1), x);
+ QCOMPARE(x, u"Nine pineapples");
+}
+
+void tst_QString::leftJustified()
+{
+ QString a;
+
+ QCOMPARE(a.leftJustified(3, u'-'), "---"_L1);
+ QCOMPARE(a.leftJustified(2), QLatin1String(" "));
+ QVERIFY(!a.isDetached());
+
+ a= u"ABC"_s;
+ QCOMPARE(a.leftJustified(5, u'-'), "ABC--"_L1);
+ QCOMPARE(a.leftJustified(4, u'-'), "ABC-"_L1);
+ QCOMPARE(a.leftJustified(4), QLatin1String("ABC "));
+ QCOMPARE(a.leftJustified(3), QLatin1String("ABC"));
+ QCOMPARE(a.leftJustified(2), QLatin1String("ABC"));
+ QCOMPARE(a.leftJustified(1), QLatin1String("ABC"));
+ QCOMPARE(a.leftJustified(0), QLatin1String("ABC"));
+
+ QCOMPARE(a.leftJustified(4, u' ', true), "ABC "_L1);
+ QCOMPARE(a.leftJustified(3, u' ', true), "ABC"_L1);
+ QCOMPARE(a.leftJustified(2, u' ', true), "AB"_L1);
+ QCOMPARE(a.leftJustified(1, u' ', true), "A"_L1);
+ QCOMPARE(a.leftJustified(0, u' ', true), ""_L1);
+}
+
+void tst_QString::rightJustified()
+{
+ QString a;
+
+ QCOMPARE(a.rightJustified(3, u'-'), "---"_L1);
+ QCOMPARE(a.rightJustified(2), QLatin1String(" "));
+ QVERIFY(!a.isDetached());
+
+ a = u"ABC"_s;
+ QCOMPARE(a.rightJustified(5, u'-'), "--ABC"_L1);
+ QCOMPARE(a.rightJustified(4, u'-'), "-ABC"_L1);
+ QCOMPARE(a.rightJustified(4), QLatin1String(" ABC"));
+ QCOMPARE(a.rightJustified(3), QLatin1String("ABC"));
+ QCOMPARE(a.rightJustified(2), QLatin1String("ABC"));
+ QCOMPARE(a.rightJustified(1), QLatin1String("ABC"));
+ QCOMPARE(a.rightJustified(0), QLatin1String("ABC"));
+
+ QCOMPARE(a.rightJustified(4, u'-', true), "-ABC"_L1);
+ QCOMPARE(a.rightJustified(4, u' ', true), " ABC"_L1);
+ QCOMPARE(a.rightJustified(3, u' ', true), "ABC"_L1);
+ QCOMPARE(a.rightJustified(2, u' ', true), "AB"_L1);
+ QCOMPARE(a.rightJustified(1, u' ', true), "A"_L1);
+ QCOMPARE(a.rightJustified(0, u' ', true), ""_L1);
+ QCOMPARE(a, QLatin1String("ABC"));
+}
+
+void tst_QString::unicodeTableAccess_data()
+{
+ QTest::addColumn<QString>("invalid");
+
+ const auto join = [](char16_t high, char16_t low) {
+ const QChar pair[2] = { high, low };
+ return QString(pair, 2);
+ };
+ // Least high surrogate for which an invalid successor produces an error:
+ QTest::newRow("least-high") << join(0xdbf8, 0xfc00);
+ // Least successor that, after a high surrogate, produces invalid:
+ QTest::newRow("least-follow") << join(0xdbff, 0xe000);
+}
+
+void tst_QString::unicodeTableAccess()
+{
+ // QString processing must not access unicode tables out of bounds.
+ QFETCH(QString, invalid);
+ // Exercise methods, to see if any assertions trigger:
+ const auto upper = invalid.toUpper();
+ const auto lower = invalid.toLower();
+ const auto folded = invalid.toCaseFolded();
+ // Fatuous test, just to use those.
+ QVERIFY(upper == invalid || lower == invalid || folded == invalid || lower != upper);
+}
+
+void tst_QString::toUpper()
+{
+ const QString s;
+ QCOMPARE( s.toUpper(), QString() ); // lvalue
+ QCOMPARE( QString().toUpper(), QString() ); // rvalue
+ QCOMPARE(QString(u""_s).toUpper(), QString(u""_s));
+
+ const QString TEXT(u"TEXT"_s);
+ QCOMPARE(QStringLiteral("text").toUpper(), TEXT);
+ QCOMPARE(QString(u"text"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"Text"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"tExt"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"teXt"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"texT"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"TExt"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"teXT"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"tEXt"_s).toUpper(), TEXT);
+ QCOMPARE(QString(u"tExT"_s).toUpper(), TEXT);
+ QCOMPARE(TEXT.toUpper(), TEXT);
+ QCOMPARE(QString(u"@ABYZ["_s).toUpper(), u"@ABYZ[");
+ QCOMPARE(QString(u"@abyz["_s).toUpper(), u"@ABYZ[");
+ QCOMPARE(QString(u"`ABYZ{"_s).toUpper(), u"`ABYZ{");
+ QCOMPARE(QString(u"`abyz{"_s).toUpper(), u"`ABYZ{");
+
+ QCOMPARE(QString(1, QChar(0xdf)).toUpper(), u"SS");
+ {
+ QString s = QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e");
+
+ // call lvalue-ref version, mustn't change the original
+ QCOMPARE(s.toUpper(), u"GROSSSTRASSE");
+ QCOMPARE(s, QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e"));
+
+ // call rvalue-ref while shared (the original mustn't change)
+ QString copy = s;
+ QCOMPARE(std::move(copy).toUpper(), u"GROSSSTRASSE");
+ QCOMPARE(s, QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e"));
+
+ // call rvalue-ref version on detached case
+ copy.clear();
+ QCOMPARE(std::move(s).toUpper(), u"GROSSSTRASSE");
+ }
+
+ QString lower, upper;
+ lower += QChar(QChar::highSurrogate(0x10428));
+ lower += QChar(QChar::lowSurrogate(0x10428));
+ upper += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::lowSurrogate(0x10400));
+ QCOMPARE( lower.toUpper(), upper);
+ lower += lower;
+ upper += upper;
+ QCOMPARE( lower.toUpper(), upper);
+
+ // test for broken surrogate pair handling (low low hi low hi low)
+ lower.prepend(QChar(QChar::lowSurrogate(0x10428)));
+ lower.prepend(QChar(QChar::lowSurrogate(0x10428)));
+ upper.prepend(QChar(QChar::lowSurrogate(0x10428)));
+ upper.prepend(QChar(QChar::lowSurrogate(0x10428)));
+ QCOMPARE(lower.toUpper(), upper);
+ // test for broken surrogate pair handling (low low hi low hi low hi hi)
+ lower += QChar(QChar::highSurrogate(0x10428));
+ lower += QChar(QChar::highSurrogate(0x10428));
+ upper += QChar(QChar::highSurrogate(0x10428));
+ upper += QChar(QChar::highSurrogate(0x10428));
+ QCOMPARE(lower.toUpper(), upper);
+
+ for (int i = 0; i < 65536; ++i) {
+ QString str(1, QChar(i));
+ QString upper = str.toUpper();
+ QVERIFY(upper.size() >= 1);
+ if (upper.size() == 1)
+ QVERIFY(upper == QString(1, QChar(i).toUpper()));
+ }
+}
+
+void tst_QString::toLower()
+{
+ const QString s;
+ QCOMPARE(s.toLower(), QString()); // lvalue
+ QCOMPARE( QString().toLower(), QString() ); // rvalue
+ QCOMPARE(QString(u""_s).toLower(), u"");
+
+ const QString lowerText(u"text"_s);
+ QCOMPARE(lowerText.toLower(), lowerText);
+ QCOMPARE(QStringLiteral("Text").toLower(), lowerText);
+ QCOMPARE(QString(u"Text"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"tExt"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"teXt"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"texT"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"TExt"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"teXT"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"tEXt"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"tExT"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"TEXT"_s).toLower(), lowerText);
+ QCOMPARE(QString(u"@ABYZ["_s).toLower(), u"@abyz[");
+ QCOMPARE(QString(u"@abyz["_s).toLower(), u"@abyz[");
+ QCOMPARE(QString(u"`ABYZ{"_s).toLower(), u"`abyz{");
+ QCOMPARE(QString(u"`abyz{"_s).toLower(), u"`abyz{");
+
+ QCOMPARE( QString(1, QChar(0x130)).toLower(), QString(QString(1, QChar(0x69)) + QChar(0x307)));
+
+ QString lower, upper;
+ lower += QChar(QChar::highSurrogate(0x10428));
+ lower += QChar(QChar::lowSurrogate(0x10428));
+ upper += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::lowSurrogate(0x10400));
+ QCOMPARE( upper.toLower(), lower);
+ lower += lower;
+ upper += upper;
+ QCOMPARE( upper.toLower(), lower);
+
+ // test for broken surrogate pair handling (low low hi low hi low)
+ lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ QCOMPARE( upper.toLower(), lower);
+ // test for broken surrogate pair handling (low low hi low hi low hi hi)
+ lower += QChar(QChar::highSurrogate(0x10400));
+ lower += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::highSurrogate(0x10400));
+ QCOMPARE( upper.toLower(), lower);
+
+ for (int i = 0; i < 65536; ++i) {
+ QString str(1, QChar(i));
+ QString lower = str.toLower();
+ QVERIFY(lower.size() >= 1);
+ if (lower.size() == 1)
+ QVERIFY(str.toLower() == QString(1, QChar(i).toLower()));
+ }
+}
+
+void tst_QString::isLower_isUpper_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<bool>("isLower");
+ QTest::addColumn<bool>("isUpper");
+
+ int row = 0;
+ QTest::addRow("lower-and-upper-%02d", row++) << QString() << true << true;
+ QTest::addRow("lower-and-upper-%02d", row++) << u""_s << true << true;
+ QTest::addRow("lower-and-upper-%02d", row++) << u" "_s << true << true;
+ QTest::addRow("lower-and-upper-%02d", row++) << u"123"_s << true << true;
+ QTest::addRow("lower-and-upper-%02d", row++) << u"@123$#"_s << true << true;
+ QTest::addRow("lower-and-upper-%02d", row++) << QString::fromUtf8("𝄞𝄴𝆏♫") << true << true; // Unicode Block 'Musical Symbols'
+ // not foldable
+ QTest::addRow("lower-and-upper-%02d", row++) << u"𝚊𝚋𝚌𝚍𝚎"_s << true << true; // MATHEMATICAL MONOSPACE SMALL A, ... E
+ QTest::addRow("lower-and-upper-%02d", row++) << u"𝙖,𝙗,𝙘,𝙙,𝙚"_s << true << true; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E
+ QTest::addRow("lower-and-upper-%02d", row++) << u"𝗔𝗕𝗖𝗗𝗘"_s << true << true; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A, ... E
+ QTest::addRow("lower-and-upper-%02d", row++) << u"𝐀,𝐁,𝐂,𝐃,𝐄"_s << true << true; // MATHEMATICAL BOLD CAPITAL A, ... E
+
+ row = 0;
+ QTest::addRow("only-lower-%02d", row++) << u"text"_s << true << false;
+ QTest::addRow("only-lower-%02d", row++) << QString::fromUtf8("àaa") << true << false;
+ QTest::addRow("only-lower-%02d", row++) << QString::fromUtf8("øæß") << true << false;
+ QTest::addRow("only-lower-%02d", row++) << u"text "_s << true << false;
+ QTest::addRow("only-lower-%02d", row++) << u" text"_s << true << false;
+ QTest::addRow("only-lower-%02d", row++) << u"hello, world!"_s << true << false;
+ QTest::addRow("only-lower-%02d", row++) << u"123@abyz["_s << true << false;
+ QTest::addRow("only-lower-%02d", row++) << u"`abyz{"_s << true << false;
+ // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E
+ QTest::addRow("only-lower-%02d", row++) << u"a𝙖a|b𝙗b|c𝙘c|d𝙙d|e𝙚e"_s << true << false;
+ // DESERET SMALL LETTER LONG I
+ QTest::addRow("only-lower-%02d", row++) << u"𐐨"_s << true << false;
+ // uppercase letters, not foldable
+ // MATHEMATICAL SANS-SERIF BOLD CAPITAL A
+ QTest::addRow("only-lower-%02d", row++) << u"text𝗔text"_s << true << false;
+
+ row = 0;
+ QTest::addRow("only-upper-%02d", row++) << u"TEXT"_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u"ÀAA"_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u"ØÆẞ"_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u"TEXT "_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u" TEXT"_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u"HELLO, WORLD!"_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u"123@ABYZ["_s << false << true;
+ QTest::addRow("only-upper-%02d", row++) << u"`ABYZ{"_s << false << true;
+ // MATHEMATICAL BOLD CAPITAL A, ... E
+ QTest::addRow("only-upper-%02d", row++) << u"A𝐀A|B𝐁B|C𝐂C|D𝐃D|E𝐄E"_s << false << true;
+ // DESERET CAPITAL LETTER LONG I
+ QTest::addRow("only-upper-%02d", row++) << u"𐐀"_s << false << true;
+ // lowercase letters, not foldable
+ // MATHEMATICAL MONOSPACE SMALL A
+ QTest::addRow("only-upper-%02d", row++) << u"TEXT𝚊TEXT"_s << false << true;
+
+ row = 0;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"Text"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"tExt"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"teXt"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"texT"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"TExt"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"teXT"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"tEXt"_s << false << false;
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"tExT"_s << false << false;
+ // not foldable
+ // MATHEMATICAL MONOSPACE SMALL A
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"TEXT𝚊text"_s << false << false;
+ // MATHEMATICAL SANS-SERIF BOLD CAPITAL A
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"text𝗔TEXT"_s << false << false;
+ // titlecase, foldable
+ // LATIN CAPITAL LETTER L WITH SMALL LETTER J
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"abcLjdef"_s << false << false;
+ // LATIN CAPITAL LETTER L WITH SMALL LETTER J
+ QTest::addRow("not-lower-nor-upper-%02d", row++) << u"ABCLjDEF"_s << false << false;
+}
+
+void tst_QString::isLower_isUpper()
+{
+ QFETCH(QString, string);
+ QFETCH(bool, isLower);
+ QFETCH(bool, isUpper);
+
+ QCOMPARE(string.isLower(), isLower);
+ QCOMPARE(QStringView(string).isLower(), isLower);
+ QCOMPARE(string.toLower() == string, isLower);
+ QVERIFY(string.toLower().isLower());
+
+ QCOMPARE(string.isUpper(), isUpper);
+ QCOMPARE(QStringView(string).isUpper(), isUpper);
+ QCOMPARE(string.toUpper() == string, isUpper);
+ QVERIFY(string.toUpper().isUpper());
+}
+
+void tst_QString::toCaseFolded()
+{
+ const QString s;
+ QCOMPARE( s.toCaseFolded(), QString() ); // lvalue
+ QCOMPARE( QString().toCaseFolded(), QString() ); // rvalue
+ QCOMPARE(QString(u""_s).toCaseFolded(), u"");
+
+ const QString lowerText(u"text"_s);
+ QCOMPARE(lowerText.toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"Text"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"tExt"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"teXt"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"texT"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"TExt"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"teXT"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"tEXt"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"tExT"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"TEXT"_s).toCaseFolded(), lowerText);
+ QCOMPARE(QString(u"@ABYZ["_s).toCaseFolded(), u"@abyz[");
+ QCOMPARE(QString(u"@abyz["_s).toCaseFolded(), u"@abyz[");
+ QCOMPARE(QString(u"`ABYZ{"_s).toCaseFolded(), u"`abyz{");
+ QCOMPARE(QString(u"`abyz{"_s).toCaseFolded(), u"`abyz{");
+
+ QCOMPARE( QString(1, QChar(0xa77d)).toCaseFolded(), QString(1, QChar(0x1d79)));
+ QCOMPARE( QString(1, QChar(0xa78d)).toCaseFolded(), QString(1, QChar(0x0265)));
+
+ QString lower, upper;
+ upper += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::lowSurrogate(0x10400));
+ lower += QChar(QChar::highSurrogate(0x10428));
+ lower += QChar(QChar::lowSurrogate(0x10428));
+ QCOMPARE( upper.toCaseFolded(), lower);
+ lower += lower;
+ upper += upper;
+ QCOMPARE( upper.toCaseFolded(), lower);
+
+ // test for broken surrogate pair handling (low low hi low hi low)
+ lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
+ QCOMPARE(upper.toCaseFolded(), lower);
+ // test for broken surrogate pair handling (low low hi low hi low hi hi)
+ lower += QChar(QChar::highSurrogate(0x10400));
+ lower += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::highSurrogate(0x10400));
+ QCOMPARE(upper.toCaseFolded(), lower);
+
+ //### we currently don't support full case foldings
+ for (int i = 0; i < 65536; ++i) {
+ QString str(1, QChar(i));
+ QString lower = str.toCaseFolded();
+ QVERIFY(lower.size() >= 1);
+ if (lower.size() == 1)
+ QVERIFY(str.toCaseFolded() == QString(1, QChar(i).toCaseFolded()));
+ }
+}
+
+void tst_QString::trimmed_data()
+{
+ QTest::addColumn<QString>("full" );
+ QTest::addColumn<QString>("trimmed" );
+
+ QTest::addRow("null") << QString() << QString();
+ QTest::addRow("simple") << u"Text"_s << u"Text"_s;
+ QTest::addRow("single-space") << u" "_s << u""_s;
+ QTest::addRow("single-char") << u" a "_s << u"a"_s;
+ QTest::addRow("mixed") << u" a \t\n\v b "_s << u"a \t\n\v b"_s;
+}
+
+void tst_QString::trimmed()
+{
+ QFETCH(QString, full);
+ QFETCH(QString, trimmed);
+
+ // Shared
+ if (!full.isNull())
+ QVERIFY(!full.isDetached());
+ QCOMPARE(full.trimmed(), trimmed); // lvalue
+ QCOMPARE(QString(full).trimmed(), trimmed); // rvalue
+ QCOMPARE(full.isNull(), trimmed.isNull());
+
+ // Not shared
+ full = QStringView(full).toString();
+ if (!full.isNull())
+ QVERIFY(full.isDetached());
+ QCOMPARE(full.trimmed(), trimmed); // lvalue
+ QCOMPARE(QString(full).trimmed(), trimmed); // rvalue
+ QCOMPARE(full.isNull(), trimmed.isNull());
+}
+
+void tst_QString::simplified_data()
+{
+ QTest::addColumn<QString>("full" );
+ QTest::addColumn<QString>("simple" );
+
+ QTest::newRow("null") << QString() << QString();
+ QTest::newRow("empty") << "" << "";
+ QTest::newRow("one char") << "a" << "a";
+ QTest::newRow("one word") << "foo" << "foo";
+ QTest::newRow("chars trivial") << "a b" << "a b";
+ QTest::newRow("words trivial") << "foo bar" << "foo bar";
+ QTest::newRow("allspace") << " \t\v " << "";
+ QTest::newRow("char trailing") << "a " << "a";
+ QTest::newRow("char trailing tab") << "a\t" << "a";
+ QTest::newRow("char multitrailing") << "a " << "a";
+ QTest::newRow("char multitrailing tab") << "a \t" << "a";
+ QTest::newRow("char leading") << " a" << "a";
+ QTest::newRow("char leading tab") << "\ta" << "a";
+ QTest::newRow("char multileading") << " a" << "a";
+ QTest::newRow("char multileading tab") << "\t a" << "a";
+ QTest::newRow("chars apart") << "a b" << "a b";
+ QTest::newRow("words apart") << "foo bar" << "foo bar";
+ QTest::newRow("enclosed word") << " foo \t " << "foo";
+ QTest::newRow("enclosed chars apart") << " a b " << "a b";
+ QTest::newRow("enclosed words apart") << " foo bar " << "foo bar";
+ QTest::newRow("chars apart posttab") << "a \tb" << "a b";
+ QTest::newRow("chars apart pretab") << "a\t b" << "a b";
+ QTest::newRow("many words") << " just some random\ttext here" << "just some random text here";
+ QTest::newRow("newlines") << "a\nb\nc" << "a b c";
+ QTest::newRow("newlines-trailing") << "a\nb\nc\n" << "a b c";
+}
+
+void tst_QString::simplified()
+{
+ QFETCH(QString, full);
+ QFETCH(QString, simple);
+
+ QString orig_full = full;
+ orig_full.data(); // forces a detach
+
+ QString result = full.simplified();
+ if (simple.isNull()) {
+ QVERIFY2(result.isNull(), qPrintable("'"_L1 + full + "' did not yield null: "_L1 + result));
+ } else if (simple.isEmpty()) {
+ QVERIFY2(result.isEmpty() && !result.isNull(), qPrintable("'"_L1 + full + "' did not yield empty: "_L1 + result));
+ } else {
+ QCOMPARE(result, simple);
+ }
+ QCOMPARE(full, orig_full);
+
+ // without detaching:
+ QString copy1 = full;
+ QCOMPARE(std::move(full).simplified(), simple);
+ QCOMPARE(full, orig_full);
+
+ // force a detach
+ if (!full.isEmpty())
+ full[0] = full[0];
+ QCOMPARE(std::move(full).simplified(), simple);
+}
+
+void tst_QString::insert_data(DataOptions options)
+{
+ QTest::addColumn<QString>("s");
+ QTest::addColumn<CharStarContainer>("arg");
+ QTest::addColumn<int>("a1");
+ QTest::addColumn<QString>("expected");
+
+ const bool emptyIsNoop = options.testFlag(EmptyIsNoop);
+
+ const CharStarContainer nullC;
+ const CharStarContainer emptyC("");
+ const CharStarContainer aC("a");
+ const CharStarContainer bC("b");
+ //const CharStarContainer abC("ab");
+ const CharStarContainer baC("ba");
+ const CharStarContainer yumlautC(options.testFlag(Latin1Encoded) ? "\xff" : "\xc3\xbf");
+
+ const QString null;
+ const QString empty(u""_s);
+ const QString a(u'a');
+ const QString b(u'b');
+ const QString ab(u"ab"_s);
+ const QString ba(u"ba"_s);
+
+ const QString yumlaut = QStringLiteral("\u00ff"); // LATIN LETTER SMALL Y WITH UMLAUT
+ const QString yumlautA = QStringLiteral("\u00ffa");
+ const QString aYumlaut = QStringLiteral("a\u00ff");
+
+ QTest::newRow("null.insert(0, null)") << null << nullC << 0 << null;
+ QTest::newRow("null.insert(0, empty)") << null << emptyC << 0 << (emptyIsNoop ? null : empty);
+ QTest::newRow("null.insert(0, a)") << null << aC << 0 << a;
+ QTest::newRow("empty.insert(0, null)") << empty << nullC << 0 << empty;
+ QTest::newRow("empty.insert(0, empty)") << empty << emptyC << 0 << empty;
+ QTest::newRow("empty.insert(0, a)") << empty << aC << 0 << a;
+ QTest::newRow("a.insert(0, null)") << a << nullC << 0 << a;
+ QTest::newRow("a.insert(0, empty)") << a << emptyC << 0 << a;
+ QTest::newRow("a.insert(0, b)") << a << bC << 0 << ba;
+ QTest::newRow("a.insert(0, ba)") << a << baC << 0 << (ba + a);
+ QTest::newRow("a.insert(1, null)") << a << nullC << 1 << a;
+ QTest::newRow("a.insert(1, empty)") << a << emptyC << 1 << a;
+ QTest::newRow("a.insert(1, b)") << a << bC << 1 << ab;
+ QTest::newRow("a.insert(1, ba)") << a << baC << 1 << (a + ba);
+ QTest::newRow("ba.insert(1, a)") << ba << aC << 1 << (ba + a);
+ QTest::newRow("ba.insert(2, b)") << ba << bC << 2 << (ba + b);
+ QTest::newRow("ba.insert(10, b)") << ba << bC << 10 << (ba + QString(10 - ba.size(), u' ') + b);
+
+ QTest::newRow("null-insert-0-yumlaut") << null << yumlautC << 0 << yumlaut;
+ QTest::newRow("empty-insert-0-yumlaut") << empty << yumlautC << 0 << yumlaut;
+ QTest::newRow("yumlaut-insert-0-null") << yumlaut << nullC << 0 << yumlaut;
+ QTest::newRow("yumlaut-insert-0-empty") << yumlaut << emptyC << 0 << yumlaut;
+ QTest::newRow("a-insert-0-yumlaut") << a << yumlautC << 0 << yumlautA;
+ QTest::newRow("a-insert-1-yumlaut") << a << yumlautC << 1 << aYumlaut;
+
+ if (!options.testFlag(Latin1Encoded)) {
+ const auto smallTheta = QStringLiteral("\u03b8"); // GREEK LETTER SMALL THETA
+ const auto ssa = QStringLiteral("\u0937"); // DEVANAGARI LETTER SSA
+ const auto chakmaZero = QStringLiteral("\U00011136"); // CHAKMA DIGIT ZERO
+
+ const auto aSmallTheta = QStringLiteral("a\u03b8");
+ const auto aSsa = QStringLiteral("a\u0937");
+ const auto aChakmaZero = QStringLiteral("a\U00011136");
+
+ const auto smallThetaA = QStringLiteral("\u03b8a");
+ const auto ssaA = QStringLiteral("\u0937a");
+ const auto chakmaZeroA = QStringLiteral("\U00011136a");
+
+ const auto umlautTheta = QStringLiteral("\u00ff\u03b8");
+ const auto thetaUmlaut = QStringLiteral("\u03b8\u00ff");
+ const auto ssaChakma = QStringLiteral("\u0937\U00011136");
+ const auto chakmaSsa = QStringLiteral("\U00011136\u0937");
+
+ const CharStarContainer smallThetaC("\xce\xb8"); // non-Latin1
+ const CharStarContainer ssaC("\xe0\xa4\xb7"); // Higher BMP
+ const CharStarContainer chakmaZeroC("\xf0\x91\x84\xb6"); // Non-BMP
+
+ QTest::newRow("null-insert-0-theta") << null << smallThetaC << 0 << smallTheta;
+ QTest::newRow("null-insert-0-ssa") << null << ssaC << 0 << ssa;
+ QTest::newRow("null-insert-0-chakma") << null << chakmaZeroC << 0 << chakmaZero;
+
+ QTest::newRow("empty-insert-0-theta") << empty << smallThetaC << 0 << smallTheta;
+ QTest::newRow("empty-insert-0-ssa") << empty << ssaC << 0 << ssa;
+ QTest::newRow("empty-insert-0-chakma") << empty << chakmaZeroC << 0 << chakmaZero;
+
+ QTest::newRow("theta-insert-0-null") << smallTheta << nullC << 0 << smallTheta;
+ QTest::newRow("ssa-insert-0-null") << ssa << nullC << 0 << ssa;
+ QTest::newRow("chakma-insert-0-null") << chakmaZero << nullC << 0 << chakmaZero;
+
+ QTest::newRow("theta-insert-0-empty") << smallTheta << emptyC << 0 << smallTheta;
+ QTest::newRow("ssa-insert-0-empty") << ssa << emptyC << 0 << ssa;
+ QTest::newRow("chakma-insert-0-empty") << chakmaZero << emptyC << 0 << chakmaZero;
+
+ QTest::newRow("a-insert-0-theta") << a << smallThetaC << 0 << smallThetaA;
+ QTest::newRow("a-insert-0-ssa") << a << ssaC << 0 << ssaA;
+ QTest::newRow("a-insert-0-chakma") << a << chakmaZeroC << 0 << chakmaZeroA;
+ QTest::newRow("yumlaut-insert-0-theta") << yumlaut << smallThetaC << 0 << thetaUmlaut;
+ QTest::newRow("theta-insert-0-yumlaut") << smallTheta << yumlautC << 0 << umlautTheta;
+ QTest::newRow("ssa-insert-0-chakma") << ssa << chakmaZeroC << 0 << chakmaSsa;
+ QTest::newRow("chakma-insert-0-ssa") << chakmaZero << ssaC << 0 << ssaChakma;
+
+ QTest::newRow("theta-insert-1-null") << smallTheta << nullC << 1 << smallTheta;
+ QTest::newRow("ssa-insert-1-null") << ssa << nullC << 1 << ssa;
+ QTest::newRow("chakma-insert-1-null") << chakmaZero << nullC << 1 << chakmaZero;
+
+ QTest::newRow("theta-insert-1-empty") << smallTheta << emptyC << 1 << smallTheta;
+ QTest::newRow("ssa-insert-1-empty") << ssa << emptyC << 1 << ssa;
+ QTest::newRow("chakma-insert-1-empty") << chakmaZero << emptyC << 1 << chakmaZero;
+
+ QTest::newRow("a-insert-1-theta") << a << smallThetaC << 1 << aSmallTheta;
+ QTest::newRow("a-insert-1-ssa") << a << ssaC << 1 << aSsa;
+ QTest::newRow("a-insert-1-chakma") << a << chakmaZeroC << 1 << aChakmaZero;
+ QTest::newRow("yumlaut-insert-1-theta") << yumlaut << smallThetaC << 1 << umlautTheta;
+ QTest::newRow("theta-insert-1-yumlaut") << smallTheta << yumlautC << 1 << thetaUmlaut;
+ QTest::newRow("ssa-insert-1-chakma") << ssa << chakmaZeroC << 1 << ssaChakma;
+ // Beware, this will insert ssa right into the middle of the chakma:
+ // Actual (s) : "\uD804\u0937\uDD36"
+ // Expected (expected): "\uD804\uDD36\u0937"
+ // QTest::newRow("chakma.insert(1, ssa)") << chakmaZero << ssaC << 1 << chakmaSsa;
+ }
+}
+
+void tst_QString::insert_special_cases()
+{
+ QString a;
+ QString dummy_share;
+
+ {
+ // Test when string is not shared
+ a = u"Ys"_s;
+ QCOMPARE(a.insert(1, u'e'), u"Yes");
+ QCOMPARE(a.insert(3, u'!'), u"Yes!");
+ QCOMPARE(a.insert(5, u'?'), u"Yes! ?");
+ QCOMPARE(a.insert(-1, u'a'), u"Yes! a?");
+ }
+ {
+ // Test when string is shared
+ a = u"Ys"_s;
+ dummy_share = a;
+ QCOMPARE(a.insert(1, u'e'), u"Yes");
+ dummy_share = a;
+ QCOMPARE(a.insert(3, u'!'), u"Yes!");
+ dummy_share = a;
+ QCOMPARE(a.insert(5, u'?'), u"Yes! ?");
+ dummy_share = a;
+ QCOMPARE(a.insert(-1, u'a'), u"Yes! a?");
+ }
+
+ a = u"ABC"_s;
+ dummy_share = a;
+ QCOMPARE(dummy_share.insert(5, u"DEF"_s), u"ABC DEF"_s); // Shared
+ QCOMPARE(a.insert(5, u"DEF"_s), u"ABC DEF"_s); // Not shared after dummy_shared.insert()
+
+ {
+ // Test when string is not shared
+ a = u"ABC"_s;
+ QCOMPARE(a.insert(2, QString()), u"ABC");
+ QCOMPARE(a.insert(0, u"ABC"_s), u"ABCABC");
+ QCOMPARE(a, u"ABCABC");
+ QCOMPARE(a.insert(0, a), u"ABCABCABCABC");
+
+ QCOMPARE(a, u"ABCABCABCABC");
+ QCOMPARE(a.insert(0, u'<'), u"<ABCABCABCABC");
+ QCOMPARE(a.insert(1, u'>'), u"<>ABCABCABCABC");
+ }
+ {
+ // Test when string is shared
+ a = u"ABC"_s;
+ dummy_share = a;
+ QCOMPARE(a.insert(2, QString()), u"ABC");
+ dummy_share = a;
+ QCOMPARE(a.insert(0, u"ABC"_s), u"ABCABC");
+ dummy_share = a;
+ QCOMPARE(a, u"ABCABC");
+ dummy_share = a;
+ QCOMPARE(a.insert(0, a), u"ABCABCABCABC");
+
+ QCOMPARE(a, u"ABCABCABCABC");
+ dummy_share = a;
+ QCOMPARE(a.insert(0, u'<'), u"<ABCABCABCABC");
+ dummy_share = a;
+ QCOMPARE(a.insert(1, u'>'), u"<>ABCABCABCABC");
+ }
+
+ const QString montreal = QStringLiteral("Montreal");
+ {
+ // Test when string is not shared
+ a = u"Meal"_s;
+ QCOMPARE(a.insert(1, "ontr"_L1), montreal);
+ QCOMPARE(a.insert(4, ""_L1), montreal);
+ QCOMPARE(a.insert(3, ""_L1), montreal);
+ QCOMPARE(a.insert(3, QLatin1String(nullptr)), montreal);
+#ifndef QT_NO_CAST_FROM_ASCII
+ QCOMPARE(a.insert(3, static_cast<const char *>(0)), montreal);
+#endif
+ QCOMPARE(a.insert(0, u"a"_s), "aMontreal"_L1);
+ }
+ {
+ // Test when string is shared
+ a = u"Meal"_s;
+ dummy_share = a;
+ QCOMPARE(a.insert(1, "ontr"_L1), montreal);
+ dummy_share = a;
+ QCOMPARE(a.insert(4, ""_L1), montreal);
+ dummy_share = a;
+ QCOMPARE(a.insert(3, ""_L1), montreal);
+ dummy_share = a;
+ QCOMPARE(a.insert(3, QLatin1String(nullptr)), montreal);
+ dummy_share = a;
+ QCOMPARE(a.insert(3, QLatin1String(static_cast<const char *>(0))), montreal);
+ dummy_share = a;
+ QCOMPARE(a.insert(0, u"a"_s), "aMontreal"_L1);
+ }
+
+ {
+ // Test when string is not shared
+ a = u"Mont"_s;
+ QCOMPARE(a.insert(a.size(), "real"_L1), montreal);
+ QCOMPARE(a.insert(a.size() + 1, "ABC"_L1), u"Montreal ABC");
+ }
+ {
+ // Test when string is shared
+ a = u"Mont"_s;
+ dummy_share = a;
+ QCOMPARE(a.insert(a.size(), "real"_L1), montreal);
+ dummy_share = a;
+ QCOMPARE(a.insert(a.size() + 1, "ABC"_L1), u"Montreal ABC");
+ }
+
+ {
+ // Test when string is not shared
+ a = u"AEF"_s;
+ QCOMPARE(a.insert(1, "BCD"_L1), u"ABCDEF");
+ QCOMPARE(a.insert(3, "-"_L1), u"ABC-DEF");
+ QCOMPARE(a.insert(a.size() + 1, "XYZ"_L1), u"ABC-DEF XYZ");
+ }
+
+ {
+ // Test when string is shared
+ a = u"AEF"_s;
+ dummy_share = a ;
+ QCOMPARE(a.insert(1, "BCD"_L1), u"ABCDEF");
+ dummy_share = a ;
+ QCOMPARE(a.insert(3, "-"_L1), u"ABC-DEF");
+ dummy_share = a ;
+ QCOMPARE(a.insert(a.size() + 1, "XYZ"_L1), u"ABC-DEF XYZ");
+ }
+
+
+ {
+ a = u"one"_s;
+ a.prepend(u'a');
+ QString b(a.data_ptr()->freeSpaceAtEnd(), u'b');
+ QCOMPARE(a.insert(a.size() + 1, QLatin1String(b.toLatin1())), u"aone "_s + b);
+ }
+ {
+ a = u"one"_s;
+ a.prepend(u'a');
+ QString b(a.data_ptr()->freeSpaceAtEnd(), u'b');
+ QCOMPARE(a.insert(a.size() + 1, b), u"aone "_s + b);
+ }
+
+ {
+ a = u"onetwothree"_s;
+ while (a.size() - 1)
+ a.remove(0, 1);
+ QString b(a.data_ptr()->freeSpaceAtEnd() + 1, u'b');
+ QCOMPARE(a.insert(a.size() + 1, QLatin1String(b.toLatin1())), u"e "_s + b);
+ }
+ {
+ a = u"onetwothree"_s;
+ while (a.size() - 1)
+ a.remove(0, 1);
+ QString b(a.data_ptr()->freeSpaceAtEnd() + 1, u'b');
+ QCOMPARE(a.insert(a.size() + 1, b), u"e "_s + b);
+ }
+}
+
+void tst_QString::append_data(DataOptions options)
+{
+ QTest::addColumn<QString>("s");
+ QTest::addColumn<CharStarContainer>("arg");
+ QTest::addColumn<QString>("expected");
+
+ const bool emptyIsNoop = options.testFlag(EmptyIsNoop);
+
+ const CharStarContainer nullC;
+ const CharStarContainer emptyC("");
+ const CharStarContainer aC("a");
+ const CharStarContainer bC("b");
+ //const CharStarContainer abC("ab");
+ const CharStarContainer yumlautC(options.testFlag(Latin1Encoded) ? "\xff" : "\xc3\xbf");
+
+ const QString null;
+ const QString empty(u""_s);
+ const QString a(u"a"_s);
+ //const QString b("b");
+ const QString ab(u"ab"_s);
+
+ const QString yumlaut = QStringLiteral("\u00ff"); // LATIN LETTER SMALL Y WITH UMLAUT
+ const QString aYumlaut = QStringLiteral("a\u00ff");
+
+ QTest::newRow("null + null") << null << nullC << null;
+ QTest::newRow("null + empty") << null << emptyC << (emptyIsNoop ? null : empty);
+ QTest::newRow("null + a") << null << aC << a;
+ QTest::newRow("empty + null") << empty << nullC << empty;
+ QTest::newRow("empty + empty") << empty << emptyC << empty;
+ QTest::newRow("empty + a") << empty << aC << a;
+ QTest::newRow("a + null") << a << nullC << a;
+ QTest::newRow("a + empty") << a << emptyC << a;
+ QTest::newRow("a + b") << a << bC << ab;
+
+ QTest::newRow("null+yumlaut") << null << yumlautC << yumlaut;
+ QTest::newRow("empty+yumlaut") << empty << yumlautC << yumlaut;
+ QTest::newRow("a+yumlaut") << a << yumlautC << aYumlaut;
+
+ if (!options.testFlag(Latin1Encoded)) {
+ const auto smallTheta = QStringLiteral("\u03b8"); // GREEK LETTER SMALL THETA
+ const auto ssa = QStringLiteral("\u0937"); // DEVANAGARI LETTER SSA
+ const auto chakmaZero = QStringLiteral("\U00011136"); // CHAKMA DIGIT ZERO
+
+ const auto aSmallTheta = QStringLiteral("a\u03b8");
+ const auto aSsa = QStringLiteral("a\u0937");
+ const auto aChakmaZero = QStringLiteral("a\U00011136");
+
+ const auto thetaChakma = QStringLiteral("\u03b8\U00011136");
+ const auto chakmaTheta = QStringLiteral("\U00011136\u03b8");
+ const auto ssaTheta = QStringLiteral("\u0937\u03b8");
+ const auto thetaSsa = QStringLiteral("\u03b8\u0937");
+ const auto ssaChakma = QStringLiteral("\u0937\U00011136");
+ const auto chakmaSsa = QStringLiteral("\U00011136\u0937");
+ const auto thetaUmlaut = QStringLiteral("\u03b8\u00ff");
+ const auto umlautTheta = QStringLiteral("\u00ff\u03b8");
+ const auto ssaUmlaut = QStringLiteral("\u0937\u00ff");
+ const auto umlautSsa = QStringLiteral("\u00ff\u0937");
+ const auto chakmaUmlaut = QStringLiteral("\U00011136\u00ff");
+ const auto umlautChakma = QStringLiteral("\u00ff\U00011136");
+
+ const CharStarContainer smallThetaC("\xce\xb8"); // non-Latin1
+ const CharStarContainer ssaC("\xe0\xa4\xb7"); // Higher BMP
+ const CharStarContainer chakmaZeroC("\xf0\x91\x84\xb6"); // Non-BMP
+
+ QTest::newRow("null+smallTheta") << null << smallThetaC << smallTheta;
+ QTest::newRow("empty+smallTheta") << empty << smallThetaC << smallTheta;
+ QTest::newRow("a+smallTheta") << a << smallThetaC << aSmallTheta;
+
+ QTest::newRow("null+ssa") << null << ssaC << ssa;
+ QTest::newRow("empty+ssa") << empty << ssaC << ssa;
+ QTest::newRow("a+ssa") << a << ssaC << aSsa;
+
+ QTest::newRow("null+chakma") << null << chakmaZeroC << chakmaZero;
+ QTest::newRow("empty+chakma") << empty << chakmaZeroC << chakmaZero;
+ QTest::newRow("a+chakma") << a << chakmaZeroC << aChakmaZero;
+
+ QTest::newRow("smallTheta+chakma") << smallTheta << chakmaZeroC << thetaChakma;
+ QTest::newRow("chakma+smallTheta") << chakmaZero << smallThetaC << chakmaTheta;
+ QTest::newRow("smallTheta+ssa") << smallTheta << ssaC << thetaSsa;
+
+ QTest::newRow("ssa+smallTheta") << ssa << smallThetaC << ssaTheta;
+ QTest::newRow("ssa+chakma") << ssa << chakmaZeroC << ssaChakma;
+ QTest::newRow("chakma+ssa") << chakmaZero << ssaC << chakmaSsa;
+
+ QTest::newRow("smallTheta+yumlaut") << smallTheta << yumlautC << thetaUmlaut;
+ QTest::newRow("yumlaut+smallTheta") << yumlaut << smallThetaC << umlautTheta;
+ QTest::newRow("ssa+yumlaut") << ssa << yumlautC << ssaUmlaut;
+ QTest::newRow("yumlaut+ssa") << yumlaut << ssaC << umlautSsa;
+ QTest::newRow("chakma+yumlaut") << chakmaZero << yumlautC << chakmaUmlaut;
+ QTest::newRow("yumlaut+chakma") << yumlaut << chakmaZeroC << umlautChakma;
+ }
+}
+
+void tst_QString::append_special_cases()
+{
+ {
+ static constexpr char16_t utf16[] = u"Hello, World!";
+ constexpr size_t len = std::char_traits<char16_t>::length(utf16);
+ const auto *unicode = reinterpret_cast<const QChar *>(utf16);
+ QString a;
+ a.append(unicode, len);
+ QCOMPARE(a, QLatin1String("Hello, World!"));
+ static const QChar nl(u'\n');
+ a.append(&nl, 1);
+ QCOMPARE(a, QLatin1String("Hello, World!\n"));
+ a.append(unicode, len);
+ QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
+ a.append(unicode, 0); // no-op
+ QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
+ a.append(unicode, -1); // no-op
+ QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
+ a.append(0, 1); // no-op
+ QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
+ }
+
+ {
+ QString a;
+ a.insert(0, QChar(u'A'));
+ QCOMPARE(a.size(), 1);
+ QVERIFY(a.capacity() > 0);
+ a.append(QLatin1String("BC"));
+ QCOMPARE(a, QLatin1String("ABC"));
+ }
+
+ {
+ QString a = u"one"_s;
+ a.prepend(u'a');
+ QString b(a.data_ptr()->freeSpaceAtEnd(), u'b');
+ QCOMPARE(a.append(QLatin1String(b.toLatin1())), u"aone"_s + b);
+ }
+
+ {
+ QString a = u"onetwothree"_s;
+ while (a.size() - 1)
+ a.remove(0, 1);
+ QString b(a.data_ptr()->freeSpaceAtEnd(), u'b');
+ QCOMPARE(a.append(QLatin1String(b.toLatin1())), u'e' + b);
+ }
+
+ {
+ QString a = u"one"_s;
+ a.prepend(u'a');
+ QString b(a.data_ptr()->freeSpaceAtEnd(), u'b');
+ QCOMPARE(a.append(b), u"aone"_s + b);
+ }
+
+ {
+ QString a = u"onetwothree"_s;
+ while (a.size() - 1)
+ a.remove(0, 1);
+ QString b(a.data_ptr()->freeSpaceAtEnd() + 1, u'b');
+ QCOMPARE(a.append(b), u'e' + b);
+ }
+
+ {
+ QString a = u"one"_s;
+ a.prepend(u'a');
+ QCOMPARE(a.append(u'b'), u"aoneb");
+ }
+
+ {
+ QString a = u"onetwothree"_s;
+ a.erase(a.cbegin(), std::prev(a.cend()));
+ QCOMPARE(a.append(u'b'), u"eb");
+ }
+}
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+void tst_QString::append_bytearray_special_cases_data()
+{
+ QTest::addColumn<QString>("str" );
+ QTest::addColumn<QByteArray>("ba" );
+ QTest::addColumn<QString>("res" );
+
+ QByteArray ba( 5, 0 );
+ ba[0] = 'a';
+ ba[1] = 'b';
+ ba[2] = 'c';
+ ba[3] = 'd';
+
+ // no 0 termination
+ ba.resize( 4 );
+ QTest::newRow( "notTerminated_0" ) << QString() << ba << u"abcd"_s;
+ QTest::newRow( "notTerminated_1" ) << u""_s << ba << u"abcd"_s;
+ QTest::newRow( "notTerminated_2" ) << u"foobar "_s << ba << u"foobar abcd"_s;
+
+ // byte array with only a 0
+ ba.resize( 1 );
+ ba[0] = 0;
+ QByteArray ba2("foobar ");
+ ba2.append('\0');
+ QTest::newRow( "emptyString" ) << u"foobar "_s << ba << QString(ba2);
+
+ // empty byte array
+ ba.resize( 0 );
+ QTest::newRow( "emptyByteArray" ) << u"foobar "_s << ba << u"foobar "_s;
+
+ // non-ascii byte array
+ QTest::newRow( "nonAsciiByteArray") << QString() << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
+ QTest::newRow( "nonAsciiByteArray2") << QString() << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
+}
+
+void tst_QString::append_bytearray_special_cases()
+{
+ {
+ QFETCH( QString, str );
+ QFETCH( QByteArray, ba );
+
+ str.append( ba );
+
+ QTEST( str, "res" );
+ }
+ {
+ QFETCH( QString, str );
+ QFETCH( QByteArray, ba );
+
+ str.append( ba );
+
+ QTEST( str, "res" );
+ }
+
+ QFETCH( QByteArray, ba );
+ if (!ba.contains('\0') && ba.constData()[ba.size()] == '\0') {
+ QFETCH( QString, str );
+
+ str.append(ba.constData());
+ QTEST( str, "res" );
+ }
+}
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+void tst_QString::appendFromRawData()
+{
+ const char16_t utf[] = u"Hello World!";
+ auto *rawData = reinterpret_cast<const QChar *>(utf);
+ QString str = QString::fromRawData(rawData, std::size(utf) - 1);
+
+ QString copy;
+ copy.append(str);
+ QCOMPARE(copy, str);
+ // We make an _actual_ copy, because appending a byte array
+ // created with fromRawData() might be optimized to copy the DataPointer,
+ // which means we may point to temporary stack data.
+ QCOMPARE_NE((void *)copy.constData(), (void *)str.constData());
+}
+
+void tst_QString::assign()
+{
+ // QString &assign(QAnyStringView)
+ {
+ QString str;
+ QCOMPARE(str.assign("data"), u"data");
+ QCOMPARE(str.size(), 4);
+ QCOMPARE(str.assign(u8"data\0data"), u"data\0data");
+ QCOMPARE(str.size(), 4);
+ QCOMPARE(str.assign(u"\0data\0data"), u"\0data\0data");
+ QCOMPARE(str.size(), 0);
+ QCOMPARE(str.assign(QAnyStringView("data\0")), u"data\0");
+ QCOMPARE(str.size(), 4);
+ QCOMPARE(str.assign(QStringView(u"(ノಠ益ಠ)ノ彡┻━┻\0")), u"(ノಠ益ಠ)ノ彡┻━┻\0");
+ QCOMPARE(str.size(), 11);
+ QCOMPARE(str.assign(QUtf8StringView(u8"٩(⁎❛ᴗ❛⁎)۶")), u"٩(⁎❛ᴗ❛⁎)۶");
+ QCOMPARE(str.size(), 9);
+ QCOMPARE(str.assign(QLatin1String("datadata")), u"datadata");
+ QCOMPARE(str.size(), 8);
+ }
+ // QString &assign(qsizetype, char);
+ {
+ QString str;
+ QCOMPARE(str.assign(3, u'è'), u"èèè");
+ QCOMPARE(str.size(), 3);
+ QCOMPARE(str.assign(20, u'd').assign(2, u'ᴗ'), u"ᴗᴗ");
+ QCOMPARE(str.size(), 2);
+ QCOMPARE(str.assign(0, u'x').assign(5, QLatin1Char('d')), u"ddddd");
+ QCOMPARE(str.size(), 5);
+ QCOMPARE(str.assign(3, u'x'), u"xxx");
+ QCOMPARE(str.size(), 3);
+ }
+ // QString &assign(InputIterator, InputIterator)
+ {
+ // Forward iterator versions
+ QString str;
+ const QString tstr = QString::fromUtf8(u8"(ノಠ益ಠ)\0ノ彡┻━┻");
+ QCOMPARE(str.assign(tstr.begin(), tstr.end()), u"(ノಠ益ಠ)\0ノ彡┻━┻");
+ QCOMPARE(str.size(), 6);
+
+ auto oldCap = str.capacity();
+ str.assign(tstr.begin(), tstr.begin()); // empty range
+ QCOMPARE_EQ(str.capacity(), oldCap);
+ QCOMPARE_EQ(str.size(), 0);
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ const char c8[] = "a©☻🂤"; // [1, 2, 3, 4] bytes in utf-8 code points
+ str.assign(std::begin(c8), std::end(c8) - 1);
+ QCOMPARE(str, c8);
+
+ std::string c8str(c8);
+ str.assign(c8str.begin(), c8str.end());
+ QCOMPARE(str, c8);
+ QCOMPARE(str.capacity(), qsizetype(std::size(c8) - 1));
+
+ oldCap = str.capacity();
+ str.assign(c8str.begin(), c8str.begin()); // empty range
+ QCOMPARE_EQ(str.capacity(), oldCap);
+ QCOMPARE_EQ(str.size(), 0);
+
+ std::forward_list<char> fwd(std::begin(c8), std::end(c8) - 1);
+ str.assign(fwd.begin(), fwd.end());
+ QCOMPARE(str, c8);
+#endif
+#ifdef __cpp_char8_t
+ const char8_t c8t[] = u8"🂤🂤🂤🂤🂤🂤🂤🂤🂤🂤"; // 10 x 4 bytes in utf-8 code points
+ str.assign(std::begin(c8t), std::end(c8t) - 1);
+ QCOMPARE(str, c8t);
+ QCOMPARE(str.size(), 20);
+#endif
+#ifdef __cpp_lib_char8_t
+ std::u8string c8tstr(c8t);
+ str.assign(c8tstr.begin(), c8tstr.end());
+ QCOMPARE(str, c8t);
+#endif
+
+ const char16_t c16[] = u"٩(⁎❛ᴗ❛⁎)۶ 🤷";
+ str.assign(std::begin(c16), std::end(c16) - 1);
+ QCOMPARE(str, c16);
+
+ std::u16string c16str(c16);
+ str.assign(c16str.begin(), c16str.end());
+ QCOMPARE(str, c16);
+
+ oldCap = str.capacity();
+ str.assign(c16str.begin(), c16str.begin()); // empty range
+ QCOMPARE_EQ(str.capacity(), oldCap);
+ QCOMPARE_EQ(str.size(), 0);
+
+ const char32_t c32[] = U"٩(⁎❛ᴗ❛⁎)۶ 🤷";
+ str.assign(std::begin(c32), std::end(c32) - 1);
+ QCOMPARE(str, c16);
+
+ std::u32string c32str(c32);
+ str.assign(c32str.begin(), c32str.end());
+ QCOMPARE(str, c16);
+
+ oldCap = str.capacity();
+ str.assign(c32str.begin(), c32str.begin()); // empty range
+ QCOMPARE_EQ(str.capacity(), oldCap);
+ QCOMPARE_EQ(str.size(), 0);
+
+ QVarLengthArray<QLatin1Char, 5> l1ch = {'F'_L1, 'G'_L1, 'H'_L1, 'I'_L1, 'J'_L1};
+ str.assign(l1ch.begin(), l1ch.end());
+ QCOMPARE(str, u"FGHIJ");
+ std::forward_list<QChar> qch = {u'G', u'H', u'I', u'J', u'K'};
+ str.assign(qch.begin(), qch.end());
+ QCOMPARE(str, u"GHIJK");
+ const QList<char16_t> qch16 = {u'X', u'H', u'I', u'J', u'K'}; // QList<T>::iterator need not be T*
+ str.assign(qch16.begin(), qch16.end());
+ QCOMPARE(str, u"XHIJK");
+#if defined(Q_OS_WIN)
+ QVarLengthArray<wchar_t> wch = {L'A', L'B', L'C', L'D', L'E'};
+ str.assign(wch.begin(), wch.end());
+ QCOMPARE(str, u"ABCDE");
+#endif
+ // Input iterator versions
+ std::stringstream ss("50 51 52 53 54");
+ str.assign(std::istream_iterator<ushort>{ss}, std::istream_iterator<ushort>{});
+ QCOMPARE(str, u"23456");
+
+ oldCap = str.capacity();
+ str.assign(std::istream_iterator<ushort>{}, std::istream_iterator<ushort>{}); // empty range
+ QCOMPARE_EQ(str.capacity(), oldCap);
+ QCOMPARE_EQ(str.size(), 0);
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ str.resize(0);
+ str.squeeze();
+ str.reserve(5);
+ const char c8cmp[] = "🂤🂤a"; // 2 + 2 + 1 byte
+ ss.clear();
+ ss.str(c8cmp);
+ str.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ QCOMPARE(str, c8cmp);
+ QCOMPARE(str.size(), 5);
+ QCOMPARE(str.capacity(), 5);
+
+ // 1 code-point + ill-formed sequence + 1 code-point.
+ const char c8IllFormed[] = "a\xe0\x9f\x80""a";
+ ss.clear();
+ ss.str(c8IllFormed);
+ str.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ QEXPECT_FAIL("", "Iconsistent handling of ill-formed sequences, QTBUG-117051", Continue);
+ QCOMPARE_EQ(str, QString(c8IllFormed));
+
+ const char c82[] = "ÌşṫһíᶊśꞧɨℼṩuDF49ïľι?";
+ ss.clear();
+ ss.str(c82);
+ str.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ QCOMPARE(str, c82);
+
+ const char uc8[] = "ẵƽ𝔰ȉ𝚐ꞑ𝒾𝝿𝕘";
+ ss.clear();
+ ss.str(uc8);
+ str.assign(std::istream_iterator<uchar>{ss}, std::istream_iterator<uchar>{});
+ QCOMPARE(str, uc8);
+
+ ss.clear();
+ const char sc8[] = "𓁇ख़ॵ௵";
+ ss.str(sc8);
+ str.assign(std::istream_iterator<signed char>{ss}, std::istream_iterator<signed char>{});
+ QCOMPARE(str, sc8);
+
+ oldCap = str.capacity();
+ str.assign(std::istream_iterator<signed char>{}, // empty range
+ std::istream_iterator<signed char>{});
+ QCOMPARE_EQ(str.capacity(), oldCap);
+ QCOMPARE_EQ(str.size(), 0);
+#endif
+ }
+ // Test chaining
+ {
+ QString str;
+ QString tstr = u"TEST DATA"_s;
+ str.assign(tstr.begin(), tstr.end()).assign({"Hello World!"}).assign(5, u'T');
+ QCOMPARE(str, u"TTTTT");
+ QCOMPARE(str.size(), 5);
+ QCOMPARE(str.assign(300, u'T').assign({"[̲̅$̲̅(̲̅5̲̅)̲̅$̲̅]"}), u"[̲̅$̲̅(̲̅5̲̅)̲̅$̲̅]");
+ QCOMPARE(str.size(), 19);
+ QCOMPARE(str.assign(10, u'c').assign(str.begin(), str.end()), str);
+ QCOMPARE(str.size(), 10);
+ QCOMPARE(str.assign("data").assign(QByteArrayView::fromArray(
+ {std::byte('T'), std::byte('T'), std::byte('T')})), u"TTT");
+ QCOMPARE(str.size(), 3);
+ QCOMPARE(str.assign("data").assign("\0data"), u"\0data");
+ QCOMPARE(str.size(), 0);
+ }
+}
+
+void tst_QString::assign_shared()
+{
+ {
+ QString str = "DATA"_L1;
+ QVERIFY(str.isDetached());
+ auto strCopy = str;
+ QVERIFY(!str.isDetached());
+ QVERIFY(!strCopy.isDetached());
+ QVERIFY(str.isSharedWith(strCopy));
+ QVERIFY(strCopy.isSharedWith(str));
+
+ str.assign(4, u'D');
+ QVERIFY(str.isDetached());
+ QVERIFY(strCopy.isDetached());
+ QVERIFY(!str.isSharedWith(strCopy));
+ QVERIFY(!strCopy.isSharedWith(str));
+ QCOMPARE(str, u"DDDD");
+ QCOMPARE(strCopy, u"DATA");
+ }
+ {
+ QString str = "DATA"_L1;
+ QVERIFY(str.isDetached());
+ auto copyForwardIt = str;
+ QVERIFY(!str.isDetached());
+ QVERIFY(!copyForwardIt.isDetached());
+ QVERIFY(str.isSharedWith(copyForwardIt));
+ QVERIFY(copyForwardIt.isSharedWith(str));
+
+ QString tstr = u"DDDD"_s;
+ str.assign(tstr.begin(), tstr.end());
+ QVERIFY(str.isDetached());
+ QVERIFY(copyForwardIt.isDetached());
+ QVERIFY(!str.isSharedWith(copyForwardIt));
+ QVERIFY(!copyForwardIt.isSharedWith(str));
+ QCOMPARE(str, u"DDDD");
+ QCOMPARE(copyForwardIt, u"DATA");
+ }
+ {
+ QString str = "DATA"_L1;
+ QVERIFY(str.isDetached());
+ auto copyInputIt = str;
+ QVERIFY(!str.isDetached());
+ QVERIFY(!copyInputIt.isDetached());
+ QVERIFY(str.isSharedWith(copyInputIt));
+ QVERIFY(copyInputIt.isSharedWith(str));
+
+ std::stringstream ss("49 50 51 52 53 54 ");
+ str.assign(std::istream_iterator<ushort>{ss}, std::istream_iterator<ushort>{});
+ QVERIFY(str.isDetached());
+ QVERIFY(copyInputIt.isDetached());
+ QVERIFY(!str.isSharedWith(copyInputIt));
+ QVERIFY(!copyInputIt.isSharedWith(str));
+
+ QCOMPARE(str, u"123456");
+ QCOMPARE(copyInputIt, u"DATA");
+ }
+}
+
+void tst_QString::assign_uses_prepend_buffer()
+{
+ const auto capBegin = [](const QString &s) {
+ return s.begin() - s.d.freeSpaceAtBegin();
+ };
+ const auto capEnd = [](const QString &s) {
+ return s.end() + s.d.freeSpaceAtEnd();
+ };
+ // QString &assign(QAnyStringView)
+ {
+ QString withFreeSpaceAtBegin;
+ for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i)
+ withFreeSpaceAtBegin.prepend(u'd');
+ QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1);
+
+ const auto oldCapBegin = capBegin(withFreeSpaceAtBegin);
+ const auto oldCapEnd = capEnd(withFreeSpaceAtBegin);
+
+ QString test(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), u'ȍ');
+ withFreeSpaceAtBegin.assign(test);
+
+ QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer
+ QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin);
+ QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd);
+ QCOMPARE(withFreeSpaceAtBegin, test);
+ }
+ // QString &assign(InputIterator, InputIterator)
+ {
+ QString withFreeSpaceAtBegin;
+ for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i)
+ withFreeSpaceAtBegin.prepend(u'd');
+ QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1);
+
+ const auto oldCapBegin = capBegin(withFreeSpaceAtBegin);
+ const auto oldCapEnd = capEnd(withFreeSpaceAtBegin);
+
+ std::stringstream ss;
+ for (qsizetype i = 0; i < withFreeSpaceAtBegin.d.freeSpaceAtBegin(); ++i)
+ ss << "d ";
+
+ withFreeSpaceAtBegin.assign(std::istream_iterator<char>{ss}, std::istream_iterator<char>{});
+ QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer
+ QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin);
+ QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd);
+ }
+}
+
+void tst_QString::operator_pluseq_special_cases()
+{
+ QString a;
+ a += QChar::CarriageReturn;
+ a += u'\r';
+ a += u'\x1111';
+ QCOMPARE(a, u"\r\r\x1111");
+}
+
+void tst_QString::operator_pluseq_data(DataOptions options)
+{
+ append_data(options);
+}
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+void tst_QString::operator_pluseq_bytearray_special_cases_data()
+{
+ append_bytearray_special_cases_data();
+}
+
+void tst_QString::operator_pluseq_bytearray_special_cases()
+{
+ {
+ QFETCH( QString, str );
+ QFETCH( QByteArray, ba );
+
+ str += ba;
+
+ QTEST( str, "res" );
+ }
+ {
+ QFETCH( QString, str );
+ QFETCH( QByteArray, ba );
+
+ str += ba;
+
+ QTEST( str, "res" );
+ }
+
+ QFETCH( QByteArray, ba );
+ if (!ba.contains('\0') && ba.constData()[ba.size()] == '\0') {
+ QFETCH( QString, str );
+
+ str += ba.constData();
+ QTEST( str, "res" );
+ }
+}
+
+void tst_QString::operator_eqeq_bytearray_data()
+{
+ constructorQByteArray_data();
+}
+
+void tst_QString::operator_eqeq_bytearray()
+{
+ QFETCH(QByteArray, src);
+ QFETCH(QString, expected);
+
+ QVERIFY(expected == src);
+ QVERIFY(!(expected != src));
+
+ if (!src.contains('\0') && src.constData()[src.size()] == '\0') {
+ QVERIFY(expected == src.constData());
+ QVERIFY(!(expected != src.constData()));
+ }
+}
+
+void tst_QString::operator_assign_symmetry()
+{
+ {
+ QString str("DATA");
+ str.operator=(QString());
+ QCOMPARE_EQ(str.capacity(), 0);
+ QVERIFY(str.isNull());
+ }
+ {
+ QString str("DATA");
+ str.operator=(QByteArray());
+ QCOMPARE_EQ(str.capacity(), 0);
+ QVERIFY(str.isNull());
+ }
+ {
+ QString str("DATA");
+ const char *data = nullptr;
+ str.operator=(data);
+ QCOMPARE_EQ(str.capacity(), 0);
+ QVERIFY(str.isNull());
+ }
+}
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+void tst_QString::swap()
+{
+ QString s1 = QString::fromUtf8("s1");
+ QString s2 = QString::fromUtf8("s2");
+ s1.swap(s2);
+ QCOMPARE(s1,QLatin1String("s2"));
+ QCOMPARE(s2,QLatin1String("s1"));
+}
+
+void tst_QString::prepend_data(DataOptions options)
+{
+ QTest::addColumn<QString>("s");
+ QTest::addColumn<CharStarContainer>("arg");
+ QTest::addColumn<QString>("expected");
+
+ const bool emptyIsNoop = options.testFlag(EmptyIsNoop);
+
+ const CharStarContainer nullC;
+ const CharStarContainer emptyC("");
+ const CharStarContainer aC("a");
+ const CharStarContainer bC("b");
+ const CharStarContainer baC("ba");
+ const CharStarContainer yumlautC(options.testFlag(Latin1Encoded) ? "\xff" : "\xc3\xbf");
+
+ const QString null;
+ const QString empty(u""_s);
+ const QString a(u'a');
+ //const QString b("b");
+ const QString ba(u"ba"_s);
+
+ const QString yumlaut = QStringLiteral("\u00ff"); // LATIN LETTER SMALL Y WITH UMLAUT
+ const QString yumlautA = QStringLiteral("\u00ffa");
+
+ QTest::newRow("null.prepend(null)") << null << nullC << null;
+ QTest::newRow("null.prepend(empty)") << null << emptyC << (emptyIsNoop ? null : empty);
+ QTest::newRow("null.prepend(a)") << null << aC << a;
+ QTest::newRow("empty.prepend(null)") << empty << nullC << empty;
+ QTest::newRow("empty.prepend(empty)") << empty << emptyC << empty;
+ QTest::newRow("empty.prepend(a)") << empty << aC << a;
+ QTest::newRow("a.prepend(null)") << a << nullC << a;
+ QTest::newRow("a.prepend(empty)") << a << emptyC << a;
+ QTest::newRow("a.prepend(b)") << a << bC << ba;
+ QTest::newRow("a.prepend(ba)") << a << baC << (ba + a);
+
+ QTest::newRow("null-prepend-yumlaut") << null << yumlautC << yumlaut;
+ QTest::newRow("empty-prepend-yumlaut") << empty << yumlautC << yumlaut;
+ QTest::newRow("a-prepend-yumlaut") << a << yumlautC << yumlautA;
+
+ if (!options.testFlag(Latin1Encoded)) {
+ const auto smallTheta = QStringLiteral("\u03b8"); // GREEK LETTER SMALL THETA
+ const auto ssa = QStringLiteral("\u0937"); // DEVANAGARI LETTER SSA
+ const auto chakmaZero = QStringLiteral("\U00011136"); // CHAKMA DIGIT ZERO
+
+ const auto smallThetaA = QStringLiteral("\u03b8a");
+ const auto ssaA = QStringLiteral("\u0937a");
+ const auto chakmaZeroA = QStringLiteral("\U00011136a");
+
+ const auto thetaChakma = QStringLiteral("\u03b8\U00011136");
+ const auto chakmaTheta = QStringLiteral("\U00011136\u03b8");
+ const auto ssaTheta = QStringLiteral("\u0937\u03b8");
+ const auto thetaSsa = QStringLiteral("\u03b8\u0937");
+ const auto ssaChakma = QStringLiteral("\u0937\U00011136");
+ const auto chakmaSsa = QStringLiteral("\U00011136\u0937");
+ const auto thetaUmlaut = QStringLiteral("\u03b8\u00ff");
+ const auto umlautTheta = QStringLiteral("\u00ff\u03b8");
+ const auto ssaUmlaut = QStringLiteral("\u0937\u00ff");
+ const auto umlautSsa = QStringLiteral("\u00ff\u0937");
+ const auto chakmaUmlaut = QStringLiteral("\U00011136\u00ff");
+ const auto umlautChakma = QStringLiteral("\u00ff\U00011136");
+
+ const CharStarContainer smallThetaC("\xce\xb8"); // non-Latin1
+ const CharStarContainer ssaC("\xe0\xa4\xb7"); // Higher BMP
+ const CharStarContainer chakmaZeroC("\xf0\x91\x84\xb6"); // Non-BMP
+
+ QTest::newRow("null-prepend-smallTheta") << null << smallThetaC << smallTheta;
+ QTest::newRow("empty-prepend-smallTheta") << empty << smallThetaC << smallTheta;
+ QTest::newRow("a-prepend-smallTheta") << a << smallThetaC << smallThetaA;
+
+ QTest::newRow("null-prepend-ssa") << null << ssaC << ssa;
+ QTest::newRow("empty-prepend-ssa") << empty << ssaC << ssa;
+ QTest::newRow("a-prepend-ssa") << a << ssaC << ssaA;
+
+ QTest::newRow("null-prepend-chakma") << null << chakmaZeroC << chakmaZero;
+ QTest::newRow("empty-prepend-chakma") << empty << chakmaZeroC << chakmaZero;
+ QTest::newRow("a-prepend-chakma") << a << chakmaZeroC << chakmaZeroA;
+
+ QTest::newRow("smallTheta-prepend-chakma") << smallTheta << chakmaZeroC << chakmaTheta;
+ QTest::newRow("chakma-prepend-smallTheta") << chakmaZero << smallThetaC << thetaChakma;
+ QTest::newRow("smallTheta-prepend-ssa") << smallTheta << ssaC << ssaTheta;
+ QTest::newRow("ssa-prepend-smallTheta") << ssa << smallThetaC << thetaSsa;
+ QTest::newRow("ssa-prepend-chakma") << ssa << chakmaZeroC << chakmaSsa;
+ QTest::newRow("chakma-prepend-ssa") << chakmaZero << ssaC << ssaChakma;
+ QTest::newRow("smallTheta-prepend-yumlaut") << smallTheta << yumlautC << umlautTheta;
+ QTest::newRow("yumlaut-prepend-smallTheta") << yumlaut << smallThetaC << thetaUmlaut;
+ QTest::newRow("ssa-prepend-yumlaut") << ssa << yumlautC << umlautSsa;
+ QTest::newRow("yumlaut-prepend-ssa") << yumlaut << ssaC << ssaUmlaut;
+ QTest::newRow("chakma-prepend-yumlaut") << chakmaZero << yumlautC << umlautChakma;
+ QTest::newRow("yumlaut-prepend-chakma") << yumlaut << chakmaZeroC << chakmaUmlaut;
+ }
+}
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+void tst_QString::prepend_bytearray_special_cases_data()
+{
+ QTest::addColumn<QString>("str" );
+ QTest::addColumn<QByteArray>("ba" );
+ QTest::addColumn<QString>("res" );
+
+ QByteArray ba( 5, 0 );
+ ba[0] = 'a';
+ ba[1] = 'b';
+ ba[2] = 'c';
+ ba[3] = 'd';
+
+ // byte array with only a 0
+ ba.resize( 1 );
+ ba[0] = 0;
+ QTest::newRow( "emptyString" ) << u"foobar "_s << ba << QStringView::fromArray(u"\0foobar ").chopped(1).toString();
+
+ // empty byte array
+ ba.resize( 0 );
+ QTest::newRow( "emptyByteArray" ) << u" foobar"_s << ba << u" foobar"_s;
+
+ // non-ascii byte array
+ QTest::newRow( "nonAsciiByteArray") << QString() << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
+ QTest::newRow( "nonAsciiByteArray2") << QString() << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
+}
+
+void tst_QString::prepend_bytearray_special_cases()
+{
+ {
+ QFETCH( QString, str );
+ QFETCH( QByteArray, ba );
+
+ str.prepend( ba );
+
+ QFETCH( QString, res );
+ QCOMPARE( str, res );
+ }
+ {
+ QFETCH( QString, str );
+ QFETCH( QByteArray, ba );
+
+ str.prepend( ba );
+
+ QTEST( str, "res" );
+ }
+
+ QFETCH( QByteArray, ba );
+ if (!ba.contains('\0') && ba.constData()[ba.size()] == '\0') {
+ QFETCH( QString, str );
+
+ str.prepend(ba.constData());
+ QTEST( str, "res" );
+ }
+}
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+void tst_QString::prependEventuallyProducesFreeSpaceAtBegin()
+{
+ QString s;
+ for (int i = 0; i < 100 && !s.data_ptr().freeSpaceAtBegin(); ++i)
+ s.prepend(u'd');
+ QCOMPARE_GT(s.data_ptr().freeSpaceAtBegin(), 1);
+}
+
+void tst_QString::replace_uint_uint()
+{
+ QFETCH( QString, string );
+ QFETCH( int, index );
+ QFETCH( int, len );
+ QFETCH( QString, after );
+
+ // Test when the string is shared
+ QString s1 = string;
+ s1.replace( (uint) index, (int) len, after );
+ QTEST( s1, "result" );
+ // Test when it's not shared
+ s1 = string;
+ s1.detach();
+ s1.replace((uint)index, (int)len, after);
+ QTEST(s1, "result");
+
+ // Test when the string is shared
+ QString s2 = string;
+ s2.replace((uint)index, (uint)len, after.unicode(), after.size());
+ QTEST(s2, "result");
+ // Test when it's not shared
+ s2 = string;
+ s2.detach();
+ s2.replace((uint)index, (uint)len, after.unicode(), after.size());
+ QTEST(s2, "result");
+
+ if (after.size() == 1) {
+ // Test when the string is shared
+ QString s3 = string;
+ s3.replace((uint)index, (uint)len, QChar(after[0]));
+ QTEST(s3, "result");
+ // Test when it's not shared
+ s3 = string;
+ s3.detach();
+ s3.replace((uint)index, (uint)len, QChar(after[0]));
+ QTEST(s3, "result");
+
+#if !defined(QT_NO_CAST_FROM_ASCII)
+ // Testing replace(qsizetype, qsizetype, QLatin1Char) calls aren't ambiguous
+
+ // Test when the string is shared
+ QString s4 = string;
+ s4.replace((uint)index, (uint)len, QChar(after[0]).toLatin1());
+ QTEST(s4, "result");
+ // Test when it's not shared
+ s4 = string;
+ s4.detach();
+ s4.replace((uint)index, (uint)len, QChar(after[0]).toLatin1());
+ QTEST(s4, "result");
+#endif
+ }
+}
+
+void tst_QString::replace_uint_uint_extra()
+{
+ {
+ QString s;
+ s.insert(0, QChar(u'A'));
+
+ auto bigReplacement = QString(u'B').repeated(s.capacity() * 3);
+
+ s.replace( 0, 1, bigReplacement );
+ QCOMPARE( s, bigReplacement );
+ }
+
+ {
+ QString s;
+ s.insert(0, QLatin1String("BBB"));
+
+ auto smallReplacement = QString(u'C');
+
+ s.replace( 0, 3, smallReplacement );
+ QCOMPARE( s, smallReplacement );
+ }
+
+ {
+ QString s;
+ s.insert(0, QLatin1String("BBB"));
+
+ auto smallReplacement = QString(u'C');
+
+ s.replace( 5, 3, smallReplacement );
+ QCOMPARE( s, QLatin1String("BBB") );
+ }
+}
+
+void tst_QString::replace_extra()
+{
+ /*
+ This test is designed to be extremely slow if QString::replace() doesn't optimize the case
+ len == after.size().
+ */
+ QString str(u"dsfkljfdsjklsdjsfjklfsdjkldfjslkjsdfkllkjdsfjklsfdkjsdflkjlsdfjklsdfkjldsflkjsddlkj"_s);
+ for (int j = 1; j < 12; ++j)
+ str += str;
+
+ QString str2(u"aaaaaaaaaaaaaaaaaaaa"_s);
+ for (int i = 0; i < 2000000; ++i) {
+ str.replace(10, 20, str2);
+ }
+
+ /*
+ Make sure that replacing with itself works.
+ */
+ QString copy(str);
+ copy.detach();
+ str.replace(0, str.size(), str);
+ QVERIFY(copy == str);
+
+ /*
+ Make sure that replacing a part of oneself with itself works.
+ */
+ QString str3(u"abcdefghij"_s);
+ str3.replace(0, 1, str3);
+ QCOMPARE(str3, u"abcdefghijbcdefghij");
+
+ QString str4(u"abcdefghij"_s);
+ str4.replace(1, 3, str4);
+ QCOMPARE(str4, u"aabcdefghijefghij");
+
+ QString str5(u"abcdefghij"_s);
+ str5.replace(8, 10, str5);
+ QCOMPARE(str5, u"abcdefghabcdefghij");
+
+ // Replacements using only part of the string modified:
+ QString str6(u"abcdefghij"_s);
+ str6.replace(1, 8, str6.constData() + 3, 3);
+ QCOMPARE(str6, u"adefj");
+
+ QString str7(u"abcdefghibcdefghij"_s);
+ str7.replace(str7.constData() + 1, 6, str7.constData() + 2, 3);
+ QCOMPARE(str7, u"acdehicdehij");
+
+ const int many = 1024;
+ /*
+ QS::replace(const QChar *, int, const QChar *, int, Qt::CaseSensitivity)
+ does its replacements in batches of many (please keep in sync with any
+ changes to batch size), which lead to misbehaviour if ether QChar * array
+ was part of the data being modified.
+ */
+ QString str8(u"abcdefg"_s);
+ QString ans8(u"acdeg"_s);
+ {
+ // Make str8 and ans8 repeat themselves many + 1 times:
+ int i = many;
+ QString big(str8), small(ans8);
+ while (i && !(i & 1)) { // Exploit many being a power of 2:
+ big += big;
+ small += small;
+ i >>= 1;
+ }
+ while (i-- > 0) {
+ str8 += big;
+ ans8 += small;
+ }
+ }
+ str8.replace(str8.constData() + 1, 5, str8.constData() + 2, 3);
+ // Pre-test the bit where the diff happens, so it gets displayed:
+ QCOMPARE(str8.mid((many - 3) * 5), ans8.mid((many - 3) * 5));
+ // Also check the full values match, of course:
+ QCOMPARE(str8.size(), ans8.size());
+ QCOMPARE(str8, ans8);
+}
+
+void tst_QString::replace_string()
+{
+ QFETCH( QString, string );
+ QFETCH( QString, before );
+ QFETCH( QString, after );
+ QFETCH( bool, bcs );
+ QFETCH(QString, result);
+
+ Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ if ( before.size() == 1 ) {
+ QChar ch = before.at( 0 );
+
+ // Test when isShared() is true
+ QString s1 = string;
+ s1.replace( ch, after, cs );
+ QCOMPARE(s1, result);
+
+ QString s4 = string;
+ s4.begin(); // Test when isShared() is false
+ s4.replace(ch, after, cs);
+ QCOMPARE(s4, result);
+ }
+
+ QString s3 = string;
+ s3.replace( before, after, cs );
+ QCOMPARE(s3, result);
+}
+
+void tst_QString::replace_string_extra()
+{
+ {
+ QString s;
+ s.insert(0, u'A');
+
+ auto bigReplacement = QString(u'B').repeated(s.capacity() * 3);
+
+ s.replace( u"A"_s, bigReplacement );
+ QCOMPARE( s, bigReplacement );
+ }
+
+ {
+ QString s;
+ s.insert(0, QLatin1String("BBB"));
+
+ auto smallReplacement = QString(u'C');
+
+ s.replace( u"BBB"_s, smallReplacement );
+ QCOMPARE( s, smallReplacement );
+ }
+
+ {
+ QString s(QLatin1String("BBB"));
+ QString expected(QLatin1String("BBB"));
+ for (int i = 0; i < 1028; ++i) {
+ s.append(u'X');
+ expected.append(u"GXU"_s);
+ }
+ s.replace(QChar(u'X'), u"GXU"_s);
+ QCOMPARE(s, expected);
+ }
+}
+
+#if QT_CONFIG(regularexpression)
+void tst_QString::replace_regexp()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ u"^QString::replace\\(\\): called on an invalid QRegularExpression object"_s
+ );
+
+ QFETCH( QString, string );
+ QFETCH( QString, regexp );
+ QFETCH( QString, after );
+
+ QRegularExpression regularExpression(regexp);
+ if (!regularExpression.isValid())
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ string.replace(regularExpression, after);
+ QTEST(string, "result");
+}
+
+void tst_QString::replace_regexp_extra()
+{
+ {
+ QString s;
+ s.insert(0, QChar(u'A'));
+
+ auto bigReplacement = QString(u'B').repeated(s.capacity() * 3);
+
+ QRegularExpression regularExpression(u"A"_s);
+ QVERIFY(regularExpression.isValid());
+
+ s.replace( regularExpression, bigReplacement );
+ QCOMPARE( s, bigReplacement );
+ }
+
+ {
+ QString s;
+ s.insert(0, QLatin1String("BBB"));
+
+ auto smallReplacement = QString(u'C');
+
+ QRegularExpression regularExpression(u"BBB"_s);
+ QVERIFY(regularExpression.isValid());
+
+ s.replace( regularExpression, smallReplacement );
+ QCOMPARE( s, smallReplacement );
+ }
+}
+#endif
+
+void tst_QString::remove_uint_uint()
+{
+ QFETCH( QString, string );
+ QFETCH( int, index );
+ QFETCH( int, len );
+ QFETCH( QString, after );
+ QFETCH(QString, result);
+
+ // For the replace() unitests?
+ if ( after.size() != 0 ) {
+ return;
+ }
+
+ // Test when isShared() is true
+ QString s1 = string;
+ s1.remove((qsizetype)index, (qsizetype)len);
+ QCOMPARE(s1, result);
+
+ QString s2 = string;
+ // Test when isShared() is false
+ s2.detach();
+ s2.remove((qsizetype)index, (qsizetype)len);
+ QCOMPARE(s2, result);
+}
+
+void tst_QString::remove_string()
+{
+ QFETCH( QString, string );
+ QFETCH( QString, before );
+ QFETCH( QString, after );
+ QFETCH( bool, bcs );
+ QFETCH(QString, result);
+
+ Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ if ( after.size() == 0 ) {
+ if ( before.size() == 1 && cs ) {
+ QChar ch = before.at( 0 );
+
+ // Test when isShared() is true
+ QString s1 = string;
+ s1.remove( ch );
+ QCOMPARE(s1, result);
+
+ // Test again with isShared() is false
+ QString s4 = string;
+ s4.begin(); // Detach
+ s4.remove( ch );
+ QCOMPARE(s4, result);
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ // Testing remove(QLatin1Char) isn't ambiguous
+ if ( QChar(ch.toLatin1()) == ch ) {
+ QString s2 = string;
+ s2.remove(ch.toLatin1());
+ QCOMPARE(s2, result);
+ }
+#endif
+ }
+
+ // Test when needsDetach() is true
+ QString s3 = string;
+ s3.remove( before, cs );
+ QCOMPARE(s3, result);
+
+ QString s5 = string;
+ s5.begin(); // Detach so needsDetach() is false
+ s5.remove( before, cs );
+ QCOMPARE(s5, result);
+
+ if (QtPrivate::isLatin1(before)) {
+ QString s6 = string;
+ s6.remove( QLatin1String(before.toLatin1()), cs );
+ QCOMPARE(s6, result);
+ }
+ }
+}
+
+#if QT_CONFIG(regularexpression)
+void tst_QString::remove_regexp_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("regexp");
+ QTest::addColumn<QString>("after"); // For the benefit of replace_regexp; empty = remove.
+ QTest::addColumn<QString>("result");
+ // string.remove(regexp) == result
+
+ QTest::newRow("alpha:s/a+//")
+ << u"alpha"_s << u"a+"_s << u""_s << u"lph"_s;
+ QTest::newRow("banana:s/^.a//")
+ << u"banana"_s << u"^.a"_s << u""_s << u"nana"_s;
+ QTest::newRow("<empty>:s/^.a//")
+ << u""_s << u"^.a"_s << u""_s << u""_s;
+ // The null-vs-empty distinction in after is only relevant to repplace_regexp(), but
+ // include both cases here to keep after's "empty here, non-empty there" rule simple.
+ QTest::newRow("<empty>:s/^.a/<null>/")
+ << u""_s << u"^.a"_s << QString() << u""_s;
+ QTest::newRow("<null>:s/^.a//") << QString() << u"^.a"_s << u""_s << QString();
+ QTest::newRow("<null>s/.a/<null>/") << QString() << u"^.a"_s << QString() << QString();
+ QTest::newRow("invalid")
+ << u""_s << u"invalid regex\\"_s << u""_s << u""_s;
+}
+
+void tst_QString::remove_regexp()
+{
+ static const QRegularExpression ignoreMessagePattern(
+ u"^QString::replace\\(\\): called on an invalid QRegularExpression object"_s
+ );
+
+ QFETCH( QString, string );
+ QFETCH( QString, regexp );
+ QTEST(QString(), "after"); // non-empty replacement text tests should go in replace_regexp_data()
+
+ QRegularExpression regularExpression(regexp);
+ // remove() delegates to replace(), which produces this warning:
+ if (!regularExpression.isValid())
+ QTest::ignoreMessage(QtWarningMsg, ignoreMessagePattern);
+ string.remove(regularExpression);
+ QTEST(string, "result");
+}
+#endif
+
+void tst_QString::remove_extra()
+{
+ {
+ QString quickFox = "The quick brown fox jumps over the lazy dog. "
+ "The lazy dog jumps over the quick brown fox."_L1;
+ QString s1 = quickFox;
+ QVERIFY(s1.data_ptr().needsDetach());
+ s1.remove(s1);
+ QVERIFY(s1.isEmpty());
+ QVERIFY(!quickFox.isEmpty());
+
+ QVERIFY(!quickFox.data_ptr().needsDetach());
+ quickFox.remove(quickFox);
+ QVERIFY(quickFox.isEmpty());
+ }
+
+ {
+ QString s = u"BCDEFGHJK"_s;
+ QString s1 = s;
+ s1.insert(0, u'A'); // detaches
+ s1.erase(s1.cbegin());
+ QCOMPARE(s1, s);
+ }
+
+ {
+ QString s = u"Clock"_s;
+ s.removeFirst();
+ QCOMPARE(s, u"lock");
+ s.removeLast();
+ QCOMPARE(s, u"loc");
+ s.removeAt(s.indexOf(u'o'));
+ QCOMPARE(s, u"lc");
+ s.clear();
+ // No crash on empty strings
+ s.removeFirst();
+ s.removeLast();
+ s.removeAt(2);
+ }
+}
+
+void tst_QString::erase_single_arg()
+{
+ QString s = u"abcdefg"_s;
+ auto it = s.erase(s.cbegin());
+ QCOMPARE_EQ(s, u"bcdefg");
+ QCOMPARE(it, s.cbegin());
+
+ it = s.erase(std::prev(s.end()));
+ QCOMPARE_EQ(s, u"bcdef");
+ QCOMPARE(it, s.cend());
+
+ it = s.erase(std::find(s.begin(), s.end(), QChar(u'd')));
+ QCOMPARE(it, s.begin() + 2);
+}
+
+void tst_QString::erase()
+{
+ QString str = u"abcdefg"_s;
+
+ QString s = str;
+ auto it = s.erase(s.begin(), s.end());
+ QCOMPARE_EQ(s, u"");
+ QCOMPARE(it, s.end());
+
+ s = str;
+ it = s.erase(std::prev(s.end()));
+ QCOMPARE_EQ(s, u"abcdef");
+ QCOMPARE(it, s.end());
+
+ it = s.erase(s.begin() + 2, s.end());
+ QCOMPARE_EQ(s, u"ab");
+ QCOMPARE(it, s.end());
+
+ it = s.erase(s.begin(), s.begin() + 1);
+ QCOMPARE_EQ(s, u"b");
+ QCOMPARE(it, s.begin());
+
+ {
+ QString s1 = QLatin1String("house");
+ QString copy = s1;
+ // erase() should return an iterator, not const_iterator
+ auto it = s1.erase(s1.cbegin(), s1.cbegin());
+ *it = QLatin1Char('m');
+ QCOMPARE(s1, u"mouse");
+ QCOMPARE(copy, u"house");
+ }
+}
+
+void tst_QString::toNum_base_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("FF") << u"FF"_s << 16 << 255;
+ QTest::newRow("0xFF") << u"0xFF"_s << 16 << 255;
+ QTest::newRow("77") << u"77"_s << 8 << 63;
+ QTest::newRow("077") << u"077"_s << 8 << 63;
+
+ QTest::newRow("0xFF - deduced base") << u"0xFF"_s << 0 << 255;
+ QTest::newRow("077 - deduced base") << u"077"_s << 0 << 63;
+ QTest::newRow("255 - deduced base") << u"255"_s << 0 << 255;
+
+ QTest::newRow(" FF") << u" FF"_s << 16 << 255;
+ QTest::newRow(" 0xFF") << u" 0xFF"_s << 16 << 255;
+ QTest::newRow(" 77") << u" 77"_s << 8 << 63;
+ QTest::newRow(" 077") << u" 077"_s << 8 << 63;
+
+ QTest::newRow(" 0xFF - deduced base") << u" 0xFF"_s << 0 << 255;
+ QTest::newRow(" 077 - deduced base") << u" 077"_s << 0 << 63;
+ QTest::newRow(" 255 - deduced base") << u" 255"_s << 0 << 255;
+
+ QTest::newRow("\tFF\t") << u"\tFF\t"_s << 16 << 255;
+ QTest::newRow("\t0xFF ") << u"\t0xFF "_s << 16 << 255;
+ QTest::newRow(" 77 ") << u" 77 "_s << 8 << 63;
+ QTest::newRow("77 ") << u"77 "_s << 8 << 63;
+}
+
+void tst_QString::toNum_base()
+{
+ QFETCH(QString, str);
+ QFETCH(int, base);
+ QFETCH(int, expected);
+
+ bool ok = false;
+ QCOMPARE(str.toInt(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toUInt(&ok, base), uint(expected));
+ QVERIFY(ok);
+
+ QCOMPARE(str.toShort(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toUShort(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toLong(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toULong(&ok, base), ulong(expected));
+ QVERIFY(ok);
+
+ QCOMPARE(str.toLongLong(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toULongLong(&ok, base), qulonglong(expected));
+ QVERIFY(ok);
+}
+
+void tst_QString::toNum_base_neg_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("-FE") << u"-FE"_s << 16 << -254;
+ QTest::newRow("-0xFE") << u"-0xFE"_s << 16 << -254;
+ QTest::newRow("-77") << u"-77"_s << 8 << -63;
+ QTest::newRow("-077") << u"-077"_s << 8 << -63;
+
+ QTest::newRow("-0xFE - deduced base") << u"-0xFE"_s << 0 << -254;
+ QTest::newRow("-077 - deduced base") << u"-077"_s << 0 << -63;
+ QTest::newRow("-254 - deduced base") << u"-254"_s << 0 << -254;
+}
+
+void tst_QString::toNum_base_neg()
+{
+ QFETCH(QString, str);
+ QFETCH(int, base);
+ QFETCH(int, expected);
+
+ bool ok = false;
+ QCOMPARE(str.toInt(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toShort(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toLong(&ok, base), expected);
+ QVERIFY(ok);
+
+ QCOMPARE(str.toLongLong(&ok, base), expected);
+ QVERIFY(ok);
+}
+
+void tst_QString::toNum_Bad()
+{
+ QString a;
+ bool ok = false;
+
+ QString(u"32768"_s).toShort(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-32769"_s).toShort(&ok);
+ QVERIFY(!ok);
+
+ QString(u"65536"_s).toUShort(&ok);
+ QVERIFY(!ok);
+
+ QString(u"2147483648"_s).toInt(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-2147483649"_s).toInt(&ok);
+ QVERIFY(!ok);
+
+ QString(u"4294967296"_s).toUInt(&ok);
+ QVERIFY(!ok);
+
+ if (sizeof(long) == 4) {
+ QString(u"2147483648"_s).toLong(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-2147483649"_s).toLong(&ok);
+ QVERIFY(!ok);
+
+ QString(u"4294967296"_s).toULong(&ok);
+ QVERIFY(!ok);
+ }
+
+ QString(u"9223372036854775808"_s).toLongLong(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-9223372036854775809"_s).toLongLong(&ok);
+ QVERIFY(!ok);
+
+ QString(u"18446744073709551616"_s).toULongLong(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-1"_s).toUShort(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-1"_s).toUInt(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-1"_s).toULong(&ok);
+ QVERIFY(!ok);
+
+ QString(u"-1"_s).toULongLong(&ok);
+ QVERIFY(!ok);
+}
+
+void tst_QString::toNum_BadAll_data()
+{
+ QTest::addColumn<QString>("str");
+
+ QTest::newRow("empty") << u""_s;
+ QTest::newRow("space") << u" "_s;
+ QTest::newRow("dot") << u"."_s;
+ QTest::newRow("dash") << u"-"_s;
+ QTest::newRow("hello") << u"hello"_s;
+ QTest::newRow("1.2.3") << u"1.2.3"_s;
+ QTest::newRow("0x0x0x") << u"0x0x0x"_s;
+ QTest::newRow("123-^~<") << u"123-^~<"_s;
+ QTest::newRow("123ThisIsNotANumber") << u"123ThisIsNotANumber"_s;
+}
+
+void tst_QString::toNum_BadAll()
+{
+ QFETCH(QString, str);
+ bool ok = false;
+
+ str.toShort(&ok);
+ QVERIFY(!ok);
+
+ str.toUShort(&ok);
+ QVERIFY(!ok);
+
+ str.toInt(&ok);
+ QVERIFY(!ok);
+
+ str.toUInt(&ok);
+ QVERIFY(!ok);
+
+ str.toLong(&ok);
+ QVERIFY(!ok);
+
+ str.toULong(&ok);
+ QVERIFY(!ok);
+
+ str.toLongLong(&ok);
+ QVERIFY(!ok);
+
+ str.toULongLong(&ok);
+ QVERIFY(!ok);
+
+ str.toFloat(&ok);
+ QVERIFY(!ok);
+
+ str.toDouble(&ok);
+ QVERIFY(!ok);
+}
+
+void tst_QString::toNum()
+{
+#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
+#define TEST_TO_INT(num, func) \
+ a = QLatin1StringView(#num); \
+ QVERIFY2(a.func(&ok) == num ## i64 && ok, "Failed: num=" #num ", func=" #func);
+#else
+#define TEST_TO_INT(num, func) \
+ a = QLatin1StringView(#num); \
+ QVERIFY2(a.func(&ok) == num ## LL && ok, "Failed: num=" #num ", func=" #func);
+#endif
+
+ QString a;
+ bool ok = false;
+
+ TEST_TO_INT(0, toInt)
+ TEST_TO_INT(-1, toInt)
+ TEST_TO_INT(1, toInt)
+ TEST_TO_INT(2147483647, toInt)
+ TEST_TO_INT(-2147483648, toInt)
+
+ TEST_TO_INT(0, toShort)
+ TEST_TO_INT(-1, toShort)
+ TEST_TO_INT(1, toShort)
+ TEST_TO_INT(32767, toShort)
+ TEST_TO_INT(-32768, toShort)
+
+ TEST_TO_INT(0, toLong)
+ TEST_TO_INT(-1, toLong)
+ TEST_TO_INT(1, toLong)
+ TEST_TO_INT(2147483647, toLong)
+ TEST_TO_INT(-2147483648, toLong)
+ TEST_TO_INT(0, toLongLong)
+ TEST_TO_INT(-1, toLongLong)
+ TEST_TO_INT(1, toLongLong)
+ TEST_TO_INT(9223372036854775807, toLongLong)
+ TEST_TO_INT(-9223372036854775807, toLongLong)
+
+#undef TEST_TO_INT
+
+#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
+#define TEST_TO_UINT(num, func) \
+ a = QLatin1StringView(#num); \
+ QVERIFY2(a.func(&ok) == num ## i64 && ok, "Failed: num=" #num ", func=" #func);
+#else
+#define TEST_TO_UINT(num, func) \
+ a = QLatin1StringView(#num); \
+ QVERIFY2(a.func(&ok) == num ## ULL && ok, "Failed: num=" #num ", func=" #func);
+#endif
+
+ TEST_TO_UINT(0, toUInt)
+ TEST_TO_UINT(1, toUInt)
+ TEST_TO_UINT(4294967295, toUInt)
+
+ TEST_TO_UINT(0, toUShort)
+ TEST_TO_UINT(1, toUShort)
+ TEST_TO_UINT(65535, toUShort)
+
+ TEST_TO_UINT(0, toULong)
+ TEST_TO_UINT(1, toULong)
+ TEST_TO_UINT(4294967295, toULong)
+
+ TEST_TO_UINT(0, toULongLong)
+ TEST_TO_UINT(1, toULongLong)
+ TEST_TO_UINT(18446744073709551615, toULongLong)
+#undef TEST_TO_UINT
+
+ a = u"FF"_s;
+ a.toULongLong(&ok, 10);
+ QVERIFY(!ok);
+
+ a = u"FF"_s;
+ a.toULongLong(&ok, 0);
+ QVERIFY(!ok);
+
+#ifdef QT_NO_FPU
+ double d = 3.40282346638528e+38; // slightly off FLT_MAX when using hardfloats
+#else
+ double d = 3.4028234663852886e+38; // FLT_MAX
+#endif
+ QString::number(d, 'e', 17).toFloat(&ok);
+ QVERIFY(ok);
+ QString::number(d + 1e32, 'e', 17).toFloat(&ok);
+ QVERIFY(!ok);
+ QString::number(-d, 'e', 17).toFloat(&ok);
+ QVERIFY(ok);
+ QString::number(-d - 1e32, 'e', 17).toFloat(&ok);
+ QVERIFY(!ok);
+ QString::number(d + 1e32, 'e', 17).toDouble(&ok);
+ QVERIFY(ok);
+ QString::number(-d - 1e32, 'e', 17).toDouble(&ok);
+ QVERIFY(ok);
+}
+
+void tst_QString::toUShort()
+{
+ QString a;
+ bool ok;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u""_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"COMPARE"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"123"_s;
+ QCOMPARE(a.toUShort(),(ushort)123);
+ QCOMPARE(a.toUShort(&ok),(ushort)123);
+ QVERIFY(ok);
+
+ a = u"123A"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"1234567"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"aaa123aaa"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"aaa123"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"123aaa"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"32767"_s;
+ QCOMPARE(a.toUShort(),(ushort)32767);
+ QCOMPARE(a.toUShort(&ok),(ushort)32767);
+ QVERIFY(ok);
+
+ a = u"-32767"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"65535"_s;
+ QCOMPARE(a.toUShort(),(ushort)65535);
+ QCOMPARE(a.toUShort(&ok),(ushort)65535);
+ QVERIFY(ok);
+
+ if (sizeof(short) == 2) {
+ a = u"65536"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+
+ a = u"123456"_s;
+ QCOMPARE(a.toUShort(),(ushort)0);
+ QCOMPARE(a.toUShort(&ok),(ushort)0);
+ QVERIFY(!ok);
+ }
+}
+
+void tst_QString::toShort()
+{
+ QString a;
+ bool ok;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u""_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"COMPARE"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"123"_s;
+ QCOMPARE(a.toShort(),(short)123);
+ QCOMPARE(a.toShort(&ok),(short)123);
+ QVERIFY(ok);
+
+ a = u"123A"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"1234567"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"aaa123aaa"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"aaa123"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"123aaa"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"32767"_s;
+ QCOMPARE(a.toShort(),(short)32767);
+ QCOMPARE(a.toShort(&ok),(short)32767);
+ QVERIFY(ok);
+
+ a = u"-32767"_s;
+ QCOMPARE(a.toShort(),(short)-32767);
+ QCOMPARE(a.toShort(&ok),(short)-32767);
+ QVERIFY(ok);
+
+ a = u"-32768"_s;
+ QCOMPARE(a.toShort(),(short)-32768);
+ QCOMPARE(a.toShort(&ok),(short)-32768);
+ QVERIFY(ok);
+
+ if (sizeof(short) == 2) {
+ a = u"32768"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+
+ a = u"-32769"_s;
+ QCOMPARE(a.toShort(),(short)0);
+ QCOMPARE(a.toShort(&ok),(short)0);
+ QVERIFY(!ok);
+ }
+}
+
+void tst_QString::toInt()
+{
+ QString a;
+ bool ok;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u""_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"COMPARE"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"123"_s;
+ QCOMPARE(a.toInt(),123);
+ QCOMPARE(a.toInt(&ok),123);
+ QVERIFY(ok);
+
+ a = u"123A"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"1234567"_s;
+ QCOMPARE(a.toInt(),1234567);
+ QCOMPARE(a.toInt(&ok),1234567);
+ QVERIFY(ok);
+
+ a = u"12345678901234"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"3234567890"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"aaa12345aaa"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"aaa12345"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"12345aaa"_s;
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"2147483647"_s; // 2**31 - 1
+ QCOMPARE(a.toInt(),2147483647);
+ QCOMPARE(a.toInt(&ok),2147483647);
+ QVERIFY(ok);
+
+ if (sizeof(int) == 4) {
+ a = u"-2147483647"_s; // -(2**31 - 1)
+ QCOMPARE(a.toInt(),-2147483647);
+ QCOMPARE(a.toInt(&ok),-2147483647);
+ QVERIFY(ok);
+
+ a = u"2147483648"_s; // 2**31
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+
+ a = u"-2147483648"_s; // -2**31
+ QCOMPARE(a.toInt(),-2147483647 - 1);
+ QCOMPARE(a.toInt(&ok),-2147483647 - 1);
+ QVERIFY(ok);
+
+ a = u"2147483649"_s; // 2**31 + 1
+ QCOMPARE(a.toInt(),0);
+ QCOMPARE(a.toInt(&ok),0);
+ QVERIFY(!ok);
+ }
+}
+
+void tst_QString::toUInt()
+{
+ bool ok;
+ QString a;
+
+ QCOMPARE(a.toUInt(), 0u);
+ QCOMPARE(a.toUInt(&ok), 0u);
+ QVERIFY(!ok);
+
+ a = u"3234567890"_s;
+ QCOMPARE(a.toUInt(&ok),3234567890u);
+ QVERIFY(ok);
+
+ a = u"-50"_s;
+ QCOMPARE(a.toUInt(),0u);
+ QCOMPARE(a.toUInt(&ok),0u);
+ QVERIFY(!ok);
+
+ a = u"4294967295"_s; // 2**32 - 1
+ QCOMPARE(a.toUInt(),4294967295u);
+ QCOMPARE(a.toUInt(&ok),4294967295u);
+ QVERIFY(ok);
+
+ if (sizeof(int) == 4) {
+ a = u"4294967296"_s; // 2**32
+ QCOMPARE(a.toUInt(),0u);
+ QCOMPARE(a.toUInt(&ok),0u);
+ QVERIFY(!ok);
+ }
+}
+
+///////////////////////////// to*Long //////////////////////////////////////
+
+void tst_QString::toULong_data()
+{
+ QTest::addColumn<QString>("str" );
+ QTest::addColumn<int>("base" );
+ QTest::addColumn<ulong>("result" );
+ QTest::addColumn<bool>("ok" );
+
+ QTest::newRow( "default" ) << QString() << 10 << 0UL << false;
+ QTest::newRow( "empty" ) << u""_s << 10 << 0UL << false;
+ QTest::newRow( "ulong1" ) << u"3234567890"_s << 10 << 3234567890UL << true;
+ QTest::newRow( "ulong2" ) << u"fFFfFfFf"_s << 16 << 0xFFFFFFFFUL << true;
+}
+
+void tst_QString::toULong()
+{
+ QFETCH( QString, str );
+ QFETCH( int, base );
+ QFETCH( ulong, result );
+ QFETCH( bool, ok );
+
+ bool b;
+ QCOMPARE( str.toULong( 0, base ), result );
+ QCOMPARE( str.toULong( &b, base ), result );
+ QCOMPARE( b, ok );
+}
+
+void tst_QString::toLong_data()
+{
+ QTest::addColumn<QString>("str" );
+ QTest::addColumn<int>("base" );
+ QTest::addColumn<long>("result" );
+ QTest::addColumn<bool>("ok" );
+
+ QTest::newRow( "default" ) << QString() << 10 << 0L << false;
+ QTest::newRow("empty") << u""_s << 10 << 0L << false;
+ QTest::newRow("normal") << u"7fFFfFFf"_s << 16 << 0x7fFFfFFfL << true;
+ QTest::newRow("long_max") << u"2147483647"_s << 10 << 2147483647L << true;
+ if (sizeof(long) == 4) {
+ QTest::newRow("long_max+1") << u"2147483648"_s << 10 << 0L << false;
+ QTest::newRow("long_min-1") << u"-80000001"_s << 16 << 0L << false;
+ }
+ QTest::newRow("negative") << u"-7fffffff"_s << 16 << -0x7fffffffL << true;
+// QTest::newRow( "long_min" ) << QString("-80000000") << 16 << 0x80000000uL << true;
+}
+
+void tst_QString::toLong()
+{
+ QFETCH( QString, str );
+ QFETCH( int, base );
+ QFETCH( long, result );
+ QFETCH( bool, ok );
+
+ bool b;
+ QCOMPARE( str.toLong( 0, base ), result );
+ QCOMPARE( str.toLong( &b, base ), result );
+ QCOMPARE( b, ok );
+}
+
+
+////////////////////////// to*LongLong //////////////////////////////////////
+
+void tst_QString::toULongLong()
+{
+ QString str;
+ bool ok = true;
+
+ QCOMPARE(str.toULongLong(), Q_UINT64_C(0));
+ QCOMPARE(str.toULongLong(&ok), Q_UINT64_C(0));
+ QVERIFY(!ok);
+
+ str = u"18446744073709551615"_s; // ULLONG_MAX
+ QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(18446744073709551615) );
+ QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(18446744073709551615) );
+ QVERIFY( ok );
+
+ str = u"18446744073709551616"_s; // ULLONG_MAX + 1
+ QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(0) );
+ QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(0) );
+ QVERIFY( !ok );
+
+ str = u"-150"_s;
+ QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(0) );
+ QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(0) );
+ QVERIFY( !ok );
+
+ // Check limits round-trip in every base:
+ using ULL = std::numeric_limits<qulonglong>;
+ for (int b = 0; b <= 36; ++b) {
+ if (b == 1) // 0 and 2 through 36 are valid bases
+ ++b;
+ QCOMPARE(QString::number(ULL::max(), b ? b : 10).toULongLong(&ok, b), ULL::max());
+ QVERIFY(ok);
+ }
+}
+
+void tst_QString::toLongLong()
+{
+ QString str;
+ bool ok;
+
+ QCOMPARE(str.toLongLong(0), Q_INT64_C(0));
+ QCOMPARE(str.toLongLong(&ok), Q_INT64_C(0));
+ QVERIFY(!ok);
+
+ str = u"9223372036854775807"_s; // LLONG_MAX
+ QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(9223372036854775807) );
+ QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(9223372036854775807) );
+ QVERIFY( ok );
+
+ str = u"-9223372036854775808"_s; // LLONG_MIN
+ QCOMPARE( str.toLongLong( 0 ),
+ -Q_INT64_C(9223372036854775807) - Q_INT64_C(1) );
+ QCOMPARE( str.toLongLong( &ok ),
+ -Q_INT64_C(9223372036854775807) - Q_INT64_C(1) );
+ QVERIFY( ok );
+
+ str = u"aaaa9223372036854775807aaaa"_s;
+ QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
+ QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
+ QVERIFY( !ok );
+
+ str = u"9223372036854775807aaaa"_s;
+ QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
+ QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
+ QVERIFY( !ok );
+
+ str = u"aaaa9223372036854775807"_s;
+ QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
+ QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
+ QVERIFY( !ok );
+
+ static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ for (int i = 0; i < 36; ++i) {
+ for (int j = 0; j < 36; ++j) {
+ for (int k = 0; k < 36; ++k) {
+ QString str;
+ str += QLatin1Char(digits[i]);
+ str += QLatin1Char(digits[j]);
+ str += QLatin1Char(digits[k]);
+ qlonglong value = (((i * 36) + j) * 36) + k;
+ QVERIFY(str.toLongLong(0, 36) == value);
+ }
+ }
+ }
+
+ // Check bounds.
+ // First in every base, with no prefix:
+ using LL = std::numeric_limits<qlonglong>;
+ for (int b = 0; b <= 36; ++b) {
+ if (b == 1) // 0 and 2 through 36 are valid bases
+ ++b;
+ QCOMPARE(QString::number(LL::max(), b ? b : 10).toLongLong(&ok, b), LL::max());
+ QVERIFY(ok);
+ QCOMPARE(QString::number(LL::min(), b ? b : 10).toLongLong(&ok, b), LL::min());
+ QVERIFY(ok);
+ }
+
+ // Then in base 16 or 0 with 0x prefix:
+ auto big = QString::number(LL::min(), 16);
+ big.insert(1, u"0x"); // after the minus sign
+ big.prepend(u"\t\r\n\f\v ");
+ QCOMPARE(big.toLongLong(&ok, 16), LL::min());
+ QVERIFY(ok);
+ QCOMPARE(big.toLongLong(&ok, 0), LL::min());
+ QVERIFY(ok);
+ big = QString::number(LL::max(), 16);
+ big.prepend(u"\t\r\n\f\v 0x");
+ QCOMPARE(big.toLongLong(&ok, 16), LL::max());
+ QVERIFY(ok);
+ QCOMPARE(big.toLongLong(&ok, 0), LL::max());
+ QVERIFY(ok);
+ big.insert(6, u'+');
+ QCOMPARE(big.toLongLong(&ok, 16), LL::max());
+ QVERIFY(ok);
+ QCOMPARE(big.toLongLong(&ok, 0), LL::max());
+ QVERIFY(ok);
+
+ // Next octal:
+ big = QString::number(LL::min(), 8);
+ big.insert(1, u'0'); // after the minus sign
+ big.prepend(u"\t\r\n\f\v ");
+ QCOMPARE(big.toLongLong(&ok, 8), LL::min());
+ QVERIFY(ok);
+ QCOMPARE(big.toLongLong(&ok, 0), LL::min());
+ QVERIFY(ok);
+ big = QString::number(LL::max(), 8);
+ big.prepend(u"\t\r\n\f\v 0");
+ QCOMPARE(big.toLongLong(&ok, 8), LL::max());
+ QVERIFY(ok);
+ QCOMPARE(big.toLongLong(&ok, 0), LL::max());
+ QVERIFY(ok);
+ big.insert(6, u'+');
+ QCOMPARE(big.toLongLong(&ok, 8), LL::max());
+ QVERIFY(ok);
+ QCOMPARE(big.toLongLong(&ok, 0), LL::max());
+ QVERIFY(ok);
+
+ // Finally decimal for base 0:
+ big = QString::number(LL::min(), 10);
+ big.prepend(u"\t\r\n\f\v ");
+ QCOMPARE(big.toLongLong(&ok, 0), LL::min());
+ QVERIFY(ok);
+ big = QString::number(LL::max(), 10);
+ big.prepend(u"\t\r\n\f\v ");
+ QCOMPARE(big.toLongLong(&ok, 0), LL::max());
+ QVERIFY(ok);
+ big.insert(6, u'+');
+ QCOMPARE(big.toLongLong(&ok, 0), LL::max());
+ QVERIFY(ok);
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+void tst_QString::toFloat()
+{
+ QString a;
+ bool ok;
+
+ QCOMPARE(a.toFloat(), 0.0f);
+ QCOMPARE(a.toFloat(&ok), 0.0f);
+ QVERIFY(!ok);
+
+ a = u"0.000000000931322574615478515625"_s;
+ QCOMPARE(a.toFloat(&ok),(float)(0.000000000931322574615478515625));
+ QVERIFY(ok);
+}
+
+void tst_QString::toDouble_data()
+{
+ QTest::addColumn<QString>("str" );
+ QTest::addColumn<double>("result" );
+ QTest::addColumn<bool>("result_ok" );
+
+ QTest::newRow("null") << QString() << 0.0 << false;
+ QTest::newRow("empty") << u""_s << 0.0 << false;
+
+ QTest::newRow("ok00") << u"0.000000000931322574615478515625"_s << 0.000000000931322574615478515625 << true;
+ QTest::newRow("ok01") << u" 123.45"_s << 123.45 << true;
+
+ QTest::newRow("ok02") << u"0.1e10"_s << 0.1e10 << true;
+ QTest::newRow("ok03") << u"0.1e-10"_s << 0.1e-10 << true;
+
+ QTest::newRow("ok04") << u"1e10"_s << 1.0e10 << true;
+ QTest::newRow("ok05") << u"1e+10"_s << 1.0e10 << true;
+ QTest::newRow("ok06") << u"1e-10"_s << 1.0e-10 << true;
+
+ QTest::newRow("ok07") << u" 1e10"_s << 1.0e10 << true;
+ QTest::newRow("ok08") << u" 1e+10"_s << 1.0e10 << true;
+ QTest::newRow("ok09") << u" 1e-10"_s << 1.0e-10 << true;
+
+ QTest::newRow("ok10") << u"1."_s << 1.0 << true;
+ QTest::newRow("ok11") << u".1"_s << 0.1 << true;
+ QTest::newRow("ok12") << u"1.2345"_s << 1.2345 << true;
+ QTest::newRow("ok13") << u"12345.6"_s << 12345.6 << true;
+ QTest::newRow("double-e+") << u"1.2345e+01"_s << 12.345 << true;
+ QTest::newRow("double-E+") << u"1.2345E+01"_s << 12.345 << true;
+
+ QTest::newRow("wrong00") << u"123.45 "_s << 123.45 << true;
+ QTest::newRow("wrong01") << u" 123.45 "_s << 123.45 << true;
+
+ QTest::newRow("wrong02") << u"aa123.45aa"_s << 0.0 << false;
+ QTest::newRow("wrong03") << u"123.45aa"_s << 0.0 << false;
+ QTest::newRow("wrong04") << u"123erf"_s << 0.0 << false;
+
+ QTest::newRow("wrong05") << u"abc"_s << 0.0 << false;
+ QTest::newRow( "wrong06" ) << QString() << 0.0 << false;
+ QTest::newRow("wrong07") << u""_s << 0.0 << false;
+}
+
+void tst_QString::toDouble()
+{
+ QFETCH( QString, str );
+ QFETCH( bool, result_ok );
+ bool ok;
+ double d = str.toDouble( &ok );
+ if ( result_ok ) {
+ QTEST( d, "result" );
+ QVERIFY( ok );
+ } else {
+ QVERIFY( !ok );
+ }
+}
+
+void tst_QString::setNum()
+{
+ QString a;
+ QCOMPARE(a.setNum(123), QLatin1String("123"));
+ QCOMPARE(a.setNum(-123), QLatin1String("-123"));
+ QCOMPARE(a.setNum(0x123,16), QLatin1String("123"));
+ QCOMPARE(a.setNum((short)123), QLatin1String("123"));
+ QCOMPARE(a.setNum(123L), QLatin1String("123"));
+ QCOMPARE(a.setNum(123UL), QLatin1String("123"));
+ QCOMPARE(a.setNum(2147483647L), u"2147483647"); // 32 bit LONG_MAX
+ QCOMPARE(a.setNum(-2147483647L), u"-2147483647"); // LONG_MIN + 1
+ QCOMPARE(a.setNum(-2147483647L-1L), u"-2147483648"); // LONG_MIN
+ QCOMPARE(a.setNum(1.23), u"1.23");
+ QCOMPARE(a.setNum(1.234567), u"1.23457");
+#if defined(LONG_MAX) && defined(LLONG_MAX) && LONG_MAX == LLONG_MAX
+ // LONG_MAX and LONG_MIN on 64 bit systems
+ QCOMPARE(a.setNum(9223372036854775807L), u"9223372036854775807");
+ QCOMPARE(a.setNum(-9223372036854775807L-1L), u"-9223372036854775808");
+ QCOMPARE(a.setNum(18446744073709551615UL), u"18446744073709551615");
+#endif
+ QCOMPARE(a.setNum(Q_INT64_C(123)), u"123");
+ // 2^40 == 1099511627776
+ QCOMPARE(a.setNum(Q_INT64_C(-1099511627776)), u"-1099511627776");
+ QCOMPARE(a.setNum(Q_UINT64_C(1099511627776)), u"1099511627776");
+ QCOMPARE(a.setNum(Q_INT64_C(9223372036854775807)), // LLONG_MAX
+ u"9223372036854775807");
+ QCOMPARE(a.setNum(-Q_INT64_C(9223372036854775807) - Q_INT64_C(1)),
+ u"-9223372036854775808");
+ QCOMPARE(a.setNum(Q_UINT64_C(18446744073709551615)), // ULLONG_MAX
+ u"18446744073709551615");
+ QCOMPARE(a.setNum(0.000000000931322574615478515625), u"9.31323e-10");
+
+// QCOMPARE(a.setNum(0.000000000931322574615478515625,'g',30),(QString)"9.31322574615478515625e-010");
+// QCOMPARE(a.setNum(0.000000000931322574615478515625,'f',30),(QString)"0.00000000093132257461547852");
+}
+
+void tst_QString::startsWith()
+{
+ QString a;
+
+ QVERIFY(!a.startsWith(u'A'));
+ QVERIFY(!a.startsWith(u"AB"_s));
+ {
+ CREATE_VIEW(u"AB"_s);
+ QVERIFY(!a.startsWith(view));
+ }
+ QVERIFY(!a.isDetached());
+
+ a = u"AB"_s;
+ QVERIFY(a.startsWith(u"A"));
+ QVERIFY(a.startsWith(u"AB"_s));
+ QVERIFY(!a.startsWith(u"C"));
+ QVERIFY(!a.startsWith(u"ABCDEF"_s));
+ QVERIFY(a.startsWith(u""_s));
+ QVERIFY( a.startsWith(QString()) );
+ QVERIFY(a.startsWith(u'A'));
+ QVERIFY(a.startsWith(QLatin1Char('A')));
+ QVERIFY(a.startsWith(QChar(u'A')));
+ QVERIFY(!a.startsWith(u'C'));
+ QVERIFY( !a.startsWith(QChar()) );
+ QVERIFY( !a.startsWith(QLatin1Char(0)) );
+
+ QVERIFY( a.startsWith(QLatin1String("A")) );
+ QVERIFY( a.startsWith(QLatin1String("AB")) );
+ QVERIFY( !a.startsWith(QLatin1String("C")) );
+ QVERIFY( !a.startsWith(QLatin1String("ABCDEF")) );
+ QVERIFY( a.startsWith(QLatin1String("")) );
+ QVERIFY( a.startsWith(QLatin1String(nullptr)) );
+
+ QVERIFY(a.startsWith(u"A"_s, Qt::CaseSensitive));
+ QVERIFY(a.startsWith(u"A"_s, Qt::CaseInsensitive));
+ QVERIFY(!a.startsWith(u"a"_s, Qt::CaseSensitive));
+ QVERIFY(a.startsWith(u"a"_s, Qt::CaseInsensitive));
+ QVERIFY(!a.startsWith(u"aB"_s, Qt::CaseSensitive));
+ QVERIFY(a.startsWith(u"aB"_s, Qt::CaseInsensitive));
+ QVERIFY(!a.startsWith(u"C"_s, Qt::CaseSensitive));
+ QVERIFY(!a.startsWith(u"C"_s, Qt::CaseInsensitive));
+ QVERIFY(!a.startsWith(u"c"_s, Qt::CaseSensitive));
+ QVERIFY(!a.startsWith(u"c"_s, Qt::CaseInsensitive));
+ QVERIFY(!a.startsWith(u"abcdef"_s, Qt::CaseInsensitive));
+ QVERIFY(a.startsWith(u""_s, Qt::CaseInsensitive));
+ QVERIFY( a.startsWith(QString(), Qt::CaseInsensitive) );
+ QVERIFY(a.startsWith(u'a', Qt::CaseInsensitive));
+ QVERIFY(a.startsWith(u'A', Qt::CaseInsensitive));
+ QVERIFY( a.startsWith(QLatin1Char('a'), Qt::CaseInsensitive) );
+ QVERIFY(a.startsWith(QChar(u'a'), Qt::CaseInsensitive));
+ QVERIFY(!a.startsWith(u'c', Qt::CaseInsensitive));
+ QVERIFY( !a.startsWith(QChar(), Qt::CaseInsensitive) );
+ QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseInsensitive) );
+
+ QVERIFY( a.startsWith(QLatin1String("A"), Qt::CaseSensitive) );
+ QVERIFY( a.startsWith(QLatin1String("A"), Qt::CaseInsensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("a"), Qt::CaseSensitive) );
+ QVERIFY( a.startsWith(QLatin1String("a"), Qt::CaseInsensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("aB"), Qt::CaseSensitive) );
+ QVERIFY( a.startsWith(QLatin1String("aB"), Qt::CaseInsensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("C"), Qt::CaseSensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("C"), Qt::CaseInsensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("c"), Qt::CaseSensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("c"), Qt::CaseInsensitive) );
+ QVERIFY( !a.startsWith(QLatin1String("abcdef"), Qt::CaseInsensitive) );
+ QVERIFY( a.startsWith(QLatin1String(""), Qt::CaseInsensitive) );
+ QVERIFY( a.startsWith(QLatin1String(nullptr), Qt::CaseInsensitive) );
+ QVERIFY(a.startsWith(u'A', Qt::CaseSensitive));
+ QVERIFY(a.startsWith(QLatin1Char('A'), Qt::CaseSensitive));
+ QVERIFY(a.startsWith(QChar(u'A'), Qt::CaseSensitive));
+ QVERIFY(!a.startsWith(u'a', Qt::CaseSensitive));
+ QVERIFY( !a.startsWith(QChar(), Qt::CaseSensitive) );
+ QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseSensitive) );
+
+#define TEST_VIEW_STARTS_WITH(string, yes) { CREATE_VIEW(string); QCOMPARE(a.startsWith(view), yes); }
+ TEST_VIEW_STARTS_WITH(u"A"_s, true);
+ TEST_VIEW_STARTS_WITH(u"AB"_s, true);
+ TEST_VIEW_STARTS_WITH(u"C"_s, false);
+ TEST_VIEW_STARTS_WITH(u"ABCDEF"_s, false);
+#undef TEST_VIEW_STARTS_WITH
+
+ a = u""_s;
+ QVERIFY(a.startsWith(u""_s));
+ QVERIFY( a.startsWith(QString()) );
+ QVERIFY(!a.startsWith(u"ABC"_s));
+
+ QVERIFY( a.startsWith(QLatin1String("")) );
+ QVERIFY( a.startsWith(QLatin1String(nullptr)) );
+ QVERIFY( !a.startsWith(QLatin1String("ABC")) );
+
+ QVERIFY( !a.startsWith(QLatin1Char(0)) );
+ QVERIFY( !a.startsWith(QLatin1Char('x')) );
+ QVERIFY( !a.startsWith(QChar()) );
+
+ a = QString();
+ QVERIFY( !a.startsWith(u""_s) );
+ QVERIFY( a.startsWith(QString()) );
+ QVERIFY(!a.startsWith(u"ABC"_s));
+
+ QVERIFY( !a.startsWith(QLatin1String("")) );
+ QVERIFY( a.startsWith(QLatin1String(nullptr)) );
+ QVERIFY( !a.startsWith(QLatin1String("ABC")) );
+
+ QVERIFY( !a.startsWith(QLatin1Char(0)) );
+ QVERIFY( !a.startsWith(QLatin1Char('x')) );
+ QVERIFY( !a.startsWith(QChar()) );
+
+ // this test is independent of encoding
+ a = u'é';
+ QVERIFY(a.startsWith(u"é"_s));
+ QVERIFY(!a.startsWith(u"á"_s));
+
+ // this one is dependent of encoding
+ QVERIFY(a.startsWith(u"É"_s, Qt::CaseInsensitive));
+}
+
+void tst_QString::endsWith()
+{
+ QString a;
+
+ QVERIFY(!a.endsWith(u'A'));
+ QVERIFY(!a.endsWith(u"AB"_s));
+ {
+ CREATE_VIEW(u"AB"_s);
+ QVERIFY(!a.endsWith(view));
+ }
+ QVERIFY(!a.isDetached());
+
+ a = u"AB"_s;
+ QVERIFY( a.endsWith(u"B"_s) );
+ QVERIFY( a.endsWith(u"AB"_s) );
+ QVERIFY( !a.endsWith(u"C"_s) );
+ QVERIFY( !a.endsWith(u"ABCDEF"_s) );
+ QVERIFY( a.endsWith(u""_s) );
+ QVERIFY( a.endsWith(QString()) );
+ QVERIFY( a.endsWith(u'B') );
+ QVERIFY( a.endsWith(QLatin1Char('B')) );
+ QVERIFY( a.endsWith(QChar(u'B')) );
+ QVERIFY( !a.endsWith(u'C') );
+ QVERIFY( !a.endsWith(QChar()) );
+ QVERIFY( !a.endsWith(QLatin1Char(0)) );
+
+ QVERIFY( a.endsWith(QLatin1String("B")) );
+ QVERIFY( a.endsWith(QLatin1String("AB")) );
+ QVERIFY( !a.endsWith(QLatin1String("C")) );
+ QVERIFY( !a.endsWith(QLatin1String("ABCDEF")) );
+ QVERIFY( a.endsWith(QLatin1String("")) );
+ QVERIFY( a.endsWith(QLatin1String(nullptr)) );
+
+ QVERIFY( a.endsWith(u"B"_s, Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(u"B", Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(u"b", Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(u"b"_s, Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(u"aB"_s, Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(u"aB"_s, Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(u"C"_s, Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(u"C"_s, Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(u"c"_s, Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(u"c"_s, Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(u"abcdef"_s, Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(u""_s, Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(QString(), Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(u'b', Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(u'B', Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(QLatin1Char('b'), Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(QChar(u'b'), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(u'c', Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QChar(), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseInsensitive) );
+
+ QVERIFY( a.endsWith(QLatin1String("B"), Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(QLatin1String("B"), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("b"), Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(QLatin1String("b"), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("aB"), Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(QLatin1String("aB"), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("C"), Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("C"), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("c"), Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("c"), Qt::CaseInsensitive) );
+ QVERIFY( !a.endsWith(QLatin1String("abcdef"), Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(QLatin1String(""), Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(QLatin1String(nullptr), Qt::CaseInsensitive) );
+ QVERIFY( a.endsWith(u'B', Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(QLatin1Char('B'), Qt::CaseSensitive) );
+ QVERIFY( a.endsWith(QChar(u'B'), Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(u'b', Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(QChar(), Qt::CaseSensitive) );
+ QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseSensitive) );
+
+#define TEST_VIEW_ENDS_WITH(string, yes) { CREATE_VIEW(string); QCOMPARE(a.endsWith(view), yes); }
+ TEST_VIEW_ENDS_WITH(QLatin1String("B"), true);
+ TEST_VIEW_ENDS_WITH(QLatin1String("AB"), true);
+ TEST_VIEW_ENDS_WITH(QLatin1String("C"), false);
+ TEST_VIEW_ENDS_WITH(QLatin1String("ABCDEF"), false);
+ TEST_VIEW_ENDS_WITH(QLatin1String(""), true);
+ TEST_VIEW_ENDS_WITH(QLatin1String(nullptr), true);
+#undef TEST_VIEW_ENDS_WITH
+
+ a = u""_s;
+ QVERIFY( a.endsWith(u""_s) );
+ QVERIFY( a.endsWith(QString()) );
+ QVERIFY( !a.endsWith(u"ABC"_s) );
+ QVERIFY( !a.endsWith(QLatin1Char(0)) );
+ QVERIFY( !a.endsWith(QLatin1Char('x')) );
+ QVERIFY( !a.endsWith(QChar()) );
+
+ QVERIFY( a.endsWith(QLatin1String("")) );
+ QVERIFY( a.endsWith(QLatin1String(nullptr)) );
+ QVERIFY( !a.endsWith(QLatin1String("ABC")) );
+
+ a = QString();
+ QVERIFY( !a.endsWith(u""_s) );
+ QVERIFY( a.endsWith(QString()) );
+ QVERIFY( !a.endsWith(u"ABC"_s) );
+
+ QVERIFY( !a.endsWith(QLatin1String("")) );
+ QVERIFY( a.endsWith(QLatin1String(nullptr)) );
+ QVERIFY( !a.endsWith(QLatin1String("ABC")) );
+
+ QVERIFY( !a.endsWith(QLatin1Char(0)) );
+ QVERIFY( !a.endsWith(QLatin1Char('x')) );
+ QVERIFY( !a.endsWith(QChar()) );
+
+ // this test is independent of encoding
+ a = u'é';
+ QVERIFY(a.endsWith(u"é"_s));
+ QVERIFY(!a.endsWith(u"á"_s));
+
+ // this one is dependent of encoding
+ QVERIFY(a.endsWith(u"É"_s, Qt::CaseInsensitive));
+}
+
+void tst_QString::check_QDataStream()
+{
+ QString a;
+ QByteArray ar;
+ {
+ QDataStream out(&ar,QIODevice::WriteOnly);
+ out << u"COMPARE Text"_s;
+ }
+ {
+ QDataStream in(&ar,QIODevice::ReadOnly);
+ in >> a;
+ QCOMPARE(a, QLatin1String("COMPARE Text"));
+ }
+}
+
+void tst_QString::check_QTextStream()
+{
+ QString a;
+ QByteArray ar;
+ {
+ QTextStream out(&ar,QIODevice::WriteOnly);
+ out << u"This is COMPARE Text"_s;
+ }
+ {
+ QTextStream in(&ar,QIODevice::ReadOnly);
+ in >> a;
+ QCOMPARE(a, QLatin1String("This"));
+ }
+}
+
+void tst_QString::check_QTextIOStream()
+{
+ QString a;
+ {
+ a = u""_s;
+ QTextStream ts(&a);
+ // invalid Utf8
+ ts << "pi \261= " << 3.125;
+ QCOMPARE(a, QString::fromUtf16(u"pi \xfffd= 3.125"));
+ }
+ {
+ a = u""_s;
+ QTextStream ts(&a);
+ // valid Utf8
+ ts << "pi ø= " << 3.125;
+ QCOMPARE(a, QString::fromUtf16(u"pi ø= 3.125"));
+ }
+ {
+ a = u"123 456"_s;
+ int x,y;
+ QTextStream(&a) >> x >> y;
+ QCOMPARE(x,123);
+ QCOMPARE(y,456);
+ }
+}
+
+void tst_QString::fromRawData()
+{
+ const QChar ptr[] = { QChar(0x1234), QChar(0x0000) };
+ QString cstr = QString::fromRawData(ptr, 1);
+ QVERIFY(!cstr.isDetached());
+ QVERIFY(cstr.constData() == ptr);
+ QVERIFY(cstr == QString(ptr, 1));
+ cstr.squeeze();
+ QVERIFY(cstr.constData() == ptr);
+ cstr.detach();
+ QVERIFY(cstr.size() == 1);
+ QVERIFY(cstr.capacity() == 1);
+ QVERIFY(cstr.constData() != ptr);
+ QVERIFY(cstr.constData()[0] == QChar(0x1234));
+ QVERIFY(cstr.constData()[1] == QChar(0x0000));
+}
+
+void tst_QString::setRawData()
+{
+ const QChar ptr[] = { QChar(0x1234), QChar(0x0000) };
+ const QChar ptr2[] = { QChar(0x4321), QChar(0x0000) };
+ QString cstr;
+
+ // This just tests the fromRawData() fallback
+ QVERIFY(!cstr.isDetached());
+ cstr.setRawData(ptr, 1);
+ QVERIFY(!cstr.isDetached());
+ QVERIFY(cstr.constData() == ptr);
+ QVERIFY(cstr == QString(ptr, 1));
+
+ // This actually tests the recycling of the shared data object
+ QString::DataPointer csd = cstr.data_ptr();
+ cstr.setRawData(ptr2, 1);
+ QEXPECT_FAIL("", "This is currently not working: QTBUG-94450.", Continue);
+ QVERIFY(cstr.isDetached());
+ QVERIFY(cstr.constData() == ptr2);
+ QVERIFY(cstr == QString(ptr2, 1));
+ QEXPECT_FAIL("", "This is currently not working: QTBUG-94450.", Continue);
+ QVERIFY(cstr.data_ptr() == csd);
+
+ // This tests the discarding of the shared data object
+ cstr = QString::fromUtf8("foo");
+ QVERIFY(cstr.isDetached());
+ QVERIFY(cstr.constData() != ptr2);
+
+ // Another test of the fallback
+ csd = cstr.data_ptr();
+ cstr.setRawData(ptr2, 1);
+ QEXPECT_FAIL("", "This is currently not working: QTBUG-94450.", Continue);
+ QVERIFY(cstr.isDetached());
+ QVERIFY(cstr.constData() == ptr2);
+ QVERIFY(cstr == QString(ptr2, 1));
+ QVERIFY(cstr.data_ptr() != csd);
+}
+
+void tst_QString::setUnicode()
+{
+ const QChar ptr[] = { QChar(0x1234), QChar(0x0000) };
+
+ QString str;
+ QVERIFY(!str.isDetached());
+ str.setUnicode(ptr, 1);
+ // make sure that the data is copied
+ QVERIFY(str.constData() != ptr);
+ QVERIFY(str.isDetached());
+ QCOMPARE(str, QString(ptr, 1));
+
+ // make sure that the string is resized, even if the data is nullptr
+ str = u"test"_s;
+ QCOMPARE(str.size(), 4);
+ str.setUnicode(nullptr, 1);
+ QCOMPARE(str.size(), 1);
+ QCOMPARE(str, u"t");
+}
+
+void tst_QString::fromStdString()
+{
+ QVERIFY(QString::fromStdString(std::string()).isEmpty());
+ std::string stroustrup = "foo";
+ QString eng = QString::fromStdString( stroustrup );
+ QCOMPARE( eng, u"foo"_s );
+ const char cnull[] = "Embedded\0null\0character!";
+ std::string stdnull( cnull, sizeof(cnull)-1 );
+ QString qtnull = QString::fromStdString( stdnull );
+ QCOMPARE(qtnull.size(), qsizetype(stdnull.size()));
+}
+
+void tst_QString::toStdString()
+{
+ QString nullStr;
+ QVERIFY(nullStr.toStdString().empty());
+ QVERIFY(!nullStr.isDetached());
+
+ QString emptyStr(u""_s);
+ QVERIFY(emptyStr.toStdString().empty());
+ QVERIFY(!emptyStr.isDetached());
+
+ QString nord = u"foo"_s;
+ std::string stroustrup1 = nord.toStdString();
+ QVERIFY( qstrcmp(stroustrup1.c_str(), "foo") == 0 );
+
+ // For now, most QString constructors are also broken with respect
+ // to embedded null characters, had to find one that works...
+ const char16_t utf16[] = u"Embedded\0null\0character!";
+ const size_t size = std::size(utf16) - 1; // - 1, null terminator of the string literal
+ QString qtnull(reinterpret_cast<const QChar *>(utf16), size);
+
+ std::string stdnull = qtnull.toStdString();
+ QCOMPARE(int(stdnull.size()), qtnull.size());
+
+ std::u16string stdu16null = qtnull.toStdU16String();
+ QCOMPARE(int(stdu16null.size()), qtnull.size());
+}
+
+void tst_QString::utf8()
+{
+ QFETCH( QByteArray, utf8 );
+ QFETCH( QString, res );
+
+ QCOMPARE(res.toUtf8(), utf8);
+
+ // try rvalue version
+ QCOMPARE(std::move(res).toUtf8(), utf8);
+}
+
+void tst_QString::fromUtf8_data()
+{
+ QTest::addColumn<QByteArray>("utf8");
+ QTest::addColumn<QString>("res");
+ QTest::addColumn<int>("len");
+ QString str;
+
+ QTest::newRow("str0") << QByteArray("abcdefgh") << u"abcdefgh"_s << -1;
+ QTest::newRow("str0-len") << QByteArray("abcdefgh") << u"abc"_s << 3;
+ QTest::newRow("str1") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
+ << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") << -1;
+ QTest::newRow("str1-len") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
+ << QString::fromLatin1("\366\344\374\326\304") << 10;
+
+ str += QChar(0x05e9);
+ str += QChar(0x05d3);
+ str += QChar(0x05d2);
+ QTest::newRow("str2") << QByteArray("\327\251\327\223\327\222") << str << -1;
+
+ str = QChar(0x05e9);
+ QTest::newRow("str2-len") << QByteArray("\327\251\327\223\327\222") << str << 2;
+
+ str = QChar(0x20ac);
+ str += u" some text"_s;
+ QTest::newRow("str3") << QByteArray("\342\202\254 some text") << str << -1;
+
+ str = QChar(0x20ac);
+ str += u" some "_s;
+ QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9;
+
+ // test that QString::fromUtf8 suppresses an initial BOM, but not a ZWNBSP
+ str = u"hello"_s;
+ QByteArray bom("\357\273\277");
+ QTest::newRow("bom0") << bom << QString() << 3;
+ QTest::newRow("bom1") << bom + "hello" << str << -1;
+ QTest::newRow("bom+zwnbsp0") << bom + bom << QString(QChar(0xfeff)) << -1;
+ QTest::newRow("bom+zwnbsp1") << bom + "hello" + bom << str + QChar(0xfeff) << -1;
+
+ str = u"hello"_s;
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x68);
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x61);
+ str += QChar::ReplacementCharacter;
+ QTest::newRow("invalid utf8") << QByteArray("hello\344h\344\344\366\344a\304") << str << -1;
+ QTest::newRow("invalid utf8-len") << QByteArray("hello\344h\344\344\366\344a\304") << u"hello"_s << 5;
+
+ str = u"Prohl"_s;
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += u"e"_s;
+ str += QChar::ReplacementCharacter;
+ str += u" plugin"_s;
+ str += QChar::ReplacementCharacter;
+ str += u" Netscape"_s;
+
+ QTest::newRow("invalid utf8 2") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << str << -1;
+ QTest::newRow("invalid utf8-len 2") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << u""_s << 0;
+
+ QTest::newRow("null-1") << QByteArray() << QString() << -1;
+ QTest::newRow("null0") << QByteArray() << QString() << 0;
+ QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << QString() << -1;
+ QTest::newRow("empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1("\0abcd", 5) << 5;
+ QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab") << -1;
+ QTest::newRow("other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab\0cd", 5) << 5;
+
+ str = u"Old Italic: "_s;
+ str += QChar(0xd800);
+ str += QChar(0xdf00);
+ str += QChar(0xd800);
+ str += QChar(0xdf01);
+ str += QChar(0xd800);
+ str += QChar(0xdf02);
+ str += QChar(0xd800);
+ str += QChar(0xdf03);
+ str += QChar(0xd800);
+ str += QChar(0xdf04);
+ QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str << -1;
+
+ QTest::newRow("surrogate-len") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str.left(16) << 20;
+
+}
+
+void tst_QString::fromUtf8()
+{
+ QFETCH(QByteArray, utf8);
+ QFETCH(QString, res);
+ QFETCH(int, len);
+
+ QCOMPARE(QString::fromUtf8(utf8.isNull() ? 0 : utf8.data(), len), res);
+}
+
+void tst_QString::nullFromUtf8()
+{
+ QString a;
+ a = QString::fromUtf8(0);
+ QVERIFY(a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromUtf8(nullptr);
+ QVERIFY(a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromUtf8("");
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromUtf8(u8""); // char in C++17 / char8_t in C++20
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromUtf8(QByteArray());
+ QVERIFY(a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromUtf8(QByteArray(""));
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QString::fromLocal8Bit_data()
+{
+ QTest::addColumn<QByteArray>("local8Bit");
+ QTest::addColumn<int>("len");
+ QTest::addColumn<QString>("result");
+
+ //QTest::newRow("nullString") << QByteArray() << -1 << QString();
+ //QTest::newRow("emptyString") << QByteArray("") << -1 << QString("");
+ //QTest::newRow("string") << QByteArray("test") << -1 << QString("test");
+ //QTest::newRow("stringlen0") << QByteArray("test") << 0 << QString("");
+ //QTest::newRow("stringlen3") << QByteArray("test") << 3 << QString("tes");
+ QTest::newRow("stringlen99") << QByteArray("test\0foo", 8) << 8 << QString::fromLatin1("test\0foo", 8);
+
+ QByteArray longQByteArray;
+ QString longQString;
+
+ for (int l=0;l<111;l++) {
+ longQByteArray = longQByteArray + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ longQString += u"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"_s;
+ }
+
+ //QTest::newRow("longString") << longQByteArray << -1 << longQString;
+ //QTest::newRow("longStringlen0") << longQByteArray << 0 << QString("");
+ //QTest::newRow("longStringlen3") << longQByteArray << 3 << QString("aaa");
+ //QTest::newRow("someNonAlphaChars") << QByteArray("d:/this/is/a/test.h") << -1 << QString("d:/this/is/a/test.h");
+
+ //QTest::newRow("null-1") << QByteArray() << -1 << QString();
+ //QTest::newRow("null0") << QByteArray() << 0 << QString();
+ //QTest::newRow("null5") << QByteArray() << 5 << QString();
+ //QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << -1 << QString();
+ //QTest::newRow("empty0") << QByteArray() << 0 << QString();
+ //QTest::newRow("empty5") << QByteArray("\0abcd", 5) << 5 << QString::fromLatin1("\0abcd", 5);
+ //QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << -1 << QString::fromLatin1("ab");
+ //QTest::newRow("other5") << QByteArray("ab\0cd", 5) << 5 << QString::fromLatin1("ab\0cd", 5);
+}
+
+void tst_QString::fromLocal8Bit()
+{
+ QFETCH(QByteArray, local8Bit);
+ QFETCH(int, len);
+ QFETCH(QString, result);
+
+ QCOMPARE(QString::fromLocal8Bit(local8Bit.isNull() ? 0 : local8Bit.data(), len).size(),
+ result.size());
+ QCOMPARE(QString::fromLocal8Bit(local8Bit.isNull() ? 0 : local8Bit.data(), len), result);
+}
+
+void tst_QString::local8Bit_data()
+{
+ QTest::addColumn<QString>("local8Bit");
+ QTest::addColumn<QByteArray>("result");
+
+ QTest::newRow("nullString") << QString() << QByteArray();
+ QTest::newRow("emptyString") << u""_s << QByteArray("");
+ QTest::newRow("string") << u"test"_s << QByteArray("test");
+
+ QByteArray longQByteArray;
+ QString longQString;
+
+ for (int l=0;l<111;l++) {
+ longQByteArray = longQByteArray + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ longQString += u"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"_s;
+ }
+
+ QTest::newRow("longString") << longQString << longQByteArray;
+ QTest::newRow("someNonAlphaChars") << u"d:/this/is/a/test.h"_s << QByteArray("d:/this/is/a/test.h");
+}
+
+void tst_QString::local8Bit()
+{
+ QFETCH(QString, local8Bit);
+ QFETCH(QByteArray, result);
+
+ QCOMPARE(local8Bit.toLocal8Bit(), QByteArray(result));
+}
+
+void tst_QString::invalidToLocal8Bit_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<QByteArray>("expect"); // Initial validly-converted prefix
+
+ {
+ const QChar malformed[] = { u'A', QChar(0xd800), u'B', u'\0' };
+ const char expected[] = "A";
+ QTest::newRow("LoneHighSurrogate")
+ << QString(malformed, sizeof(malformed) / sizeof(QChar))
+ // Don't include the terminating '\0' of expected:
+ << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
+ }
+ {
+ const QChar malformed[] = { u'A', QChar(0xdc00), u'B', u'\0' };
+ const char expected[] = "A";
+ QTest::newRow("LoneLowSurrogate")
+ << QString(malformed, sizeof(malformed) / sizeof(QChar))
+ << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
+ }
+ {
+ const QChar malformed[] = { u'A', QChar(0xd800), QChar(0xd801), u'B', u'\0' };
+ const char expected[] = "A";
+ QTest::newRow("DoubleHighSurrogate")
+ << QString(malformed, sizeof(malformed) / sizeof(QChar))
+ << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
+ }
+ {
+ const QChar malformed[] = { u'A', QChar(0xdc00), QChar(0xdc01), u'B', u'\0' };
+ const char expected[] = "A";
+ QTest::newRow("DoubleLowSurrogate")
+ << QString(malformed, sizeof(malformed) / sizeof(QChar))
+ << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
+ }
+ {
+ const QChar malformed[] = { u'A', QChar(0xdc00), QChar(0xd800), u'B', u'\0' };
+ const char expected[] = "A";
+ QTest::newRow("ReversedSurrogates") // low before high
+ << QString(malformed, sizeof(malformed) / sizeof(QChar))
+ << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
+ }
+}
+
+void tst_QString::invalidToLocal8Bit()
+{
+ QFETCH(QString, unicode);
+ QFETCH(QByteArray, expect);
+ QByteArray local = unicode.toLocal8Bit();
+ /*
+ The main concern of this test is to check that any error-reporting that
+ toLocal8Bit() prompts on failure isn't dependent on outputting the data
+ it's converting via toLocal8Bit(), which would be apt to recurse. So the
+ real purpose of this QVERIFY(), for all that we should indeed check we get
+ the borked output that matches what we can reliably expect (despite
+ variation in how codecs respond to errors), is to verify that we got here
+ - i.e. we didn't crash in such a recursive stack over-flow.
+ */
+ QVERIFY(local.startsWith(expect));
+}
+
+void tst_QString::nullFromLocal8Bit()
+{
+ QString a;
+ a = QString::fromLocal8Bit(0);
+ QVERIFY(a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromLocal8Bit("");
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromLocal8Bit(QByteArray());
+ QVERIFY(a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromLocal8Bit(QByteArray(""));
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QString::fromLatin1Roundtrip_data()
+{
+ QTest::addColumn<QByteArray>("latin1");
+ QTest::addColumn<QString>("unicode");
+
+ QTest::newRow("null") << QByteArray() << QString();
+ QTest::newRow("empty") << QByteArray("") << "";
+
+ static const char16_t unicode1[] = { 'H', 'e', 'l', 'l', 'o', 1, '\r', '\n', 0x7f };
+ QTest::newRow("ascii-only") << QByteArray("Hello") << QString::fromUtf16(unicode1, 5);
+ QTest::newRow("ascii+control") << QByteArray("Hello\1\r\n\x7f") << QString::fromUtf16(unicode1, 9);
+
+ static const char16_t unicode3[] = { 'a', 0, 'z' };
+ QTest::newRow("ascii+nul") << QByteArray("a\0z", 3) << QString::fromUtf16(unicode3, 3);
+
+ static const char16_t unicode4[] = { 0x80, 0xc0, 0xff };
+ QTest::newRow("non-ascii") << QByteArray("\x80\xc0\xff") << QString::fromUtf16(unicode4, 3);
+}
+
+void tst_QString::fromLatin1Roundtrip()
+{
+ QFETCH(QByteArray, latin1);
+ QFETCH(QString, unicode);
+
+ // Qt Test safety check:
+ QCOMPARE(latin1.isNull(), unicode.isNull());
+ QCOMPARE(latin1.isEmpty(), unicode.isEmpty());
+ QCOMPARE(latin1.size(), unicode.size());
+
+ auto roundtripTest = [&]() {
+ // fromLatin1
+ QString fromLatin1 = QString::fromLatin1(latin1, latin1.length());
+ QCOMPARE(fromLatin1.length(), unicode.length());
+ QCOMPARE(fromLatin1, unicode);
+
+ // and back:
+ QByteArray toLatin1 = unicode.toLatin1();
+ QCOMPARE(toLatin1.length(), latin1.length());
+ QCOMPARE(toLatin1, latin1);
+ };
+
+ roundtripTest();
+
+ if (latin1.isEmpty())
+ return;
+
+ if (QTest::currentTestFailed()) QFAIL("failed");
+ while (latin1.length() < 16) {
+ latin1 += latin1;
+ unicode += unicode;
+ }
+ roundtripTest();
+
+ // double again (length will be > 32)
+ if (QTest::currentTestFailed()) QFAIL("failed");
+ latin1 += latin1;
+ unicode += unicode;
+ roundtripTest();
+
+ // double again (length will be > 64)
+ if (QTest::currentTestFailed()) QFAIL("failed");
+ latin1 += latin1;
+ unicode += unicode;
+ roundtripTest();
+
+ if (QTest::currentTestFailed()) QFAIL("failed");
+ latin1 += latin1;
+ unicode += unicode;
+ roundtripTest();
+}
+
+void tst_QString::toLatin1Roundtrip_data()
+{
+ QTest::addColumn<QByteArray>("latin1");
+ QTest::addColumn<QString>("unicodesrc");
+ QTest::addColumn<QString>("unicodedst");
+
+ QTest::newRow("null") << QByteArray() << QString() << QString();
+ QTest::newRow("empty") << QByteArray("") << "" << "";
+
+ static const char16_t unicode1[] = { 'H', 'e', 'l', 'l', 'o', 1, '\r', '\n', 0x7f };
+ QTest::newRow("ascii-only") << QByteArray("Hello") << QString::fromUtf16(unicode1, 5) << QString::fromUtf16(unicode1, 5);
+ QTest::newRow("ascii+control") << QByteArray("Hello\1\r\n\x7f") << QString::fromUtf16(unicode1, 9) << QString::fromUtf16(unicode1, 9);
+
+ static const char16_t unicode3[] = { 'a', 0, 'z' };
+ QTest::newRow("ascii+nul") << QByteArray("a\0z", 3) << QString::fromUtf16(unicode3, 3) << QString::fromUtf16(unicode3, 3);
+
+ static const char16_t unicode4[] = { 0x80, 0xc0, 0xff };
+ QTest::newRow("non-ascii") << QByteArray("\x80\xc0\xff") << QString::fromUtf16(unicode4, 3) << QString::fromUtf16(unicode4, 3);
+
+ static const char16_t unicodeq[] = { '?', '?', '?', '?', '?' };
+ const QString questionmarks = QString::fromUtf16(unicodeq, 5);
+
+ static const char16_t unicode5[] = { 0x100, 0x101, 0x17f, 0x7f00, 0x7f7f };
+ QTest::newRow("non-latin1a") << QByteArray("?????") << QString::fromUtf16(unicode5, 5) << questionmarks;
+
+ static const char16_t unicode6[] = { 0x180, 0x1ff, 0x8001, 0x8080, 0xfffc };
+ QTest::newRow("non-latin1b") << QByteArray("?????") << QString::fromUtf16(unicode6, 5) << questionmarks;
+}
+
+void tst_QString::toLatin1Roundtrip()
+{
+ QFETCH(QByteArray, latin1);
+ QFETCH(QString, unicodesrc);
+ QFETCH(QString, unicodedst);
+
+ // Qt Test safety check:
+ QCOMPARE(latin1.isNull(), unicodesrc.isNull());
+ QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty());
+ QCOMPARE(latin1.size(), unicodesrc.size());
+ QCOMPARE(latin1.isNull(), unicodedst.isNull());
+ QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty());
+ QCOMPARE(latin1.size(), unicodedst.size());
+
+ if (!latin1.isEmpty())
+ while (latin1.size() < 128) {
+ latin1 += latin1;
+ unicodesrc += unicodesrc;
+ unicodedst += unicodedst;
+ }
+
+ // toLatin1
+ QCOMPARE(unicodesrc.toLatin1().size(), latin1.size());
+ QCOMPARE(unicodesrc.toLatin1(), latin1);
+
+ // and back:
+ QCOMPARE(QString::fromLatin1(latin1, latin1.size()).size(), unicodedst.size());
+ QCOMPARE(QString::fromLatin1(latin1, latin1.size()), unicodedst);
+
+ // try the rvalue version of toLatin1()
+ QString s = unicodesrc;
+ QCOMPARE(std::move(s).toLatin1(), latin1);
+
+ // and verify that the moved-from object can still be used
+ s = u"foo"_s;
+ s.clear();
+}
+
+void tst_QString::fromLatin1()
+{
+ QString a;
+ a = QString::fromLatin1( 0 );
+ QVERIFY( a.isNull() );
+ QVERIFY( a.isEmpty() );
+ a = QString::fromLatin1( "" );
+ QVERIFY( !a.isNull() );
+ QVERIFY( a.isEmpty() );
+ a = QString::fromLatin1(QByteArray());
+ QVERIFY(a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromLatin1(QByteArray(""));
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+
+ a = QString::fromLatin1(0, 0);
+ QVERIFY(a.isNull());
+ a = QString::fromLatin1("\0abcd", 0);
+ QVERIFY(!a.isNull());
+ QVERIFY(a.isEmpty());
+ a = QString::fromLatin1("\0abcd", 5);
+ QVERIFY(a.size() == 5);
+}
+
+void tst_QString::fromUcs4()
+{
+ const char32_t *null = nullptr;
+ QString s;
+ s = QString::fromUcs4( null );
+ QVERIFY( s.isNull() );
+ QCOMPARE( s.size(), 0 );
+ s = QString::fromUcs4( null, 0 );
+ QVERIFY( s.isNull() );
+ QCOMPARE( s.size(), 0 );
+ s = QString::fromUcs4( null, 5 );
+ QVERIFY( s.isNull() );
+ QCOMPARE( s.size(), 0 );
+
+ char32_t nil = '\0';
+ s = QString::fromUcs4( &nil );
+ QVERIFY( !s.isNull() );
+ QCOMPARE( s.size(), 0 );
+ s = QString::fromUcs4( &nil, 0 );
+ QVERIFY( !s.isNull() );
+ QCOMPARE( s.size(), 0 );
+
+ char32_t bmp = 'a';
+ s = QString::fromUcs4( &bmp, 1 );
+ QVERIFY( !s.isNull() );
+ QCOMPARE( s.size(), 1 );
+
+ char32_t smp = 0x10000;
+ s = QString::fromUcs4( &smp, 1 );
+ QVERIFY( !s.isNull() );
+ QCOMPARE( s.size(), 2 );
+
+ static const char32_t str1[] = U"Hello Unicode World";
+ s = QString::fromUcs4(str1, sizeof(str1) / sizeof(str1[0]) - 1);
+ QCOMPARE(s, u"Hello Unicode World");
+
+ s = QString::fromUcs4(str1);
+ QCOMPARE(s, u"Hello Unicode World");
+
+ s = QString::fromUcs4(str1, 5);
+ QCOMPARE(s, u"Hello");
+
+ s = QString::fromUcs4(U"\u221212\U000020AC\U00010000");
+ QCOMPARE(s, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
+
+ // QTBUG-62011: don't mistake ZWNBS for BOM
+ // Start with one BOM, to ensure we use the right endianness:
+ const char32_t text[] = { 0xfeff, 97, 0xfeff, 98, 0xfeff, 99, 0xfeff, 100 };
+ s = QString::fromUcs4(text, 8);
+ QCOMPARE(s, QStringView(u"a\xfeff" u"b\xfeff" u"c\xfeff" "d"));
+}
+
+void tst_QString::toUcs4()
+{
+ QString s;
+ QList<uint> ucs4;
+ QCOMPARE( s.toUcs4().size(), 0 );
+ QVERIFY(!s.isDetached());
+
+ static const QChar bmp = QLatin1Char('a');
+ s = QString(&bmp, 1);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+
+#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
+
+ static const QChar smp[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
+ s = QSTRING_FROM_QCHARARRAY(smp);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0x10000u );
+
+ static const QChar smp2[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000), QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
+ s = QSTRING_FROM_QCHARARRAY(smp2);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 2 );
+ QCOMPARE( ucs4.at(0), 0x10000u );
+ QCOMPARE( ucs4.at(1), 0x10000u );
+
+ static const QChar invalid_01[] = { QChar(0xd800) };
+ s = QSTRING_FROM_QCHARARRAY(invalid_01);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0xFFFDu );
+
+ static const QChar invalid_02[] = { QChar(0xdc00) };
+ s = QSTRING_FROM_QCHARARRAY(invalid_02);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0xFFFDu );
+
+ static const QChar invalid_03[] = { QLatin1Char('a'), QChar(0xd800), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_03);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 3 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0x0062u );
+
+ static const QChar invalid_04[] = { QLatin1Char('a'), QChar(0xdc00), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_04);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 3 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0x0062u );
+
+ static const QChar invalid_05[] = { QLatin1Char('a'), QChar(0xd800), QChar(0xd800), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_05);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 4 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0xFFFDu );
+ QCOMPARE( ucs4.at(3), 0x0062u );
+
+ static const QChar invalid_06[] = { QLatin1Char('a'), QChar(0xdc00), QChar(0xdc00), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_06);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 4 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0xFFFDu );
+ QCOMPARE( ucs4.at(3), 0x0062u );
+
+#undef QSTRING_FROM_QCHARARRAY
+
+}
+
+void tst_QString::arg()
+{
+/*
+ Warning: If any of these test fails, the warning given by Qt Test
+ is all messed up, because Qt Test itself uses QString::arg().
+*/
+
+ TransientDefaultLocale transient(QLocale(u"de_DE"));
+
+ QString s3;
+ QString s4(u"[%0]"_s);
+ QString s5(u"[%1]"_s);
+ QString s6(u"[%3]"_s);
+ QString s7(u"[%9]"_s);
+ QString s8(u"[%0 %1]"_s);
+ QString s9(u"[%0 %3]"_s);
+ QString s10(u"[%1 %2 %3]"_s);
+ QString s11(u"[%9 %3 %0]"_s);
+ QString s12(u"[%9 %1 %3 %9 %0 %8]"_s);
+ QString s13(u"%1% %x%c%2 %d%2-%"_s);
+ QString s14(u"%1%2%3"_s);
+
+ const QString null;
+ const QString empty(u""_s);
+ const QString foo(u"foo"_s);
+ const QString bar(u"bar"_s);
+
+ Q_ASSERT(null.isNull());
+ Q_ASSERT(!empty.isNull());
+ QCOMPARE(s4.arg(null), "[]"_L1);
+ QCOMPARE(s4.arg(empty), "[]"_L1);
+ QCOMPARE(s4.arg(QStringView()), "[]"_L1);
+ QCOMPARE(s4.arg(QStringView(u"")), "[]"_L1);
+
+ QCOMPARE(s4.arg(foo), "[foo]"_L1);
+ QCOMPARE( s5.arg(QLatin1String("foo")), QLatin1String("[foo]") );
+ QCOMPARE( s6.arg(u"foo"), QLatin1String("[foo]") );
+ QCOMPARE(s7.arg(foo), "[foo]"_L1);
+ QCOMPARE(s8.arg(foo), "[foo %1]"_L1);
+ QCOMPARE(s8.arg(foo).arg(bar), "[foo bar]"_L1);
+ QCOMPARE(s8.arg(foo, bar), "[foo bar]"_L1);
+ QCOMPARE(s9.arg(foo), "[foo %3]"_L1);
+ QCOMPARE(s9.arg(foo).arg(bar), "[foo bar]"_L1);
+ QCOMPARE(s9.arg(foo, bar), "[foo bar]"_L1);
+ QCOMPARE(s10.arg(foo), "[foo %2 %3]"_L1);
+ QCOMPARE(s10.arg(foo).arg(bar), "[foo bar %3]"_L1);
+ QCOMPARE(s10.arg(foo, bar), "[foo bar %3]"_L1);
+ QCOMPARE(s10.arg(foo).arg(bar).arg(u"baz"_s), "[foo bar baz]"_L1);
+ QCOMPARE(s10.arg(foo, bar, u"baz"_s), "[foo bar baz]"_L1);
+ QCOMPARE(s11.arg(foo), "[%9 %3 foo]"_L1);
+ QCOMPARE(s11.arg(foo).arg(bar), "[%9 bar foo]"_L1);
+ QCOMPARE(s11.arg(foo, bar), "[%9 bar foo]"_L1);
+ QCOMPARE(s11.arg(foo).arg(bar).arg(u"baz"_s), "[baz bar foo]"_L1);
+ QCOMPARE(s11.arg(foo, bar, u"baz"_s), "[baz bar foo]"_L1);
+ QCOMPARE( s12.arg(u"a"_s).arg(u"b"_s).arg(u"c"_s).arg(u"d"_s).arg(u"e"_s),
+ QLatin1String("[e b c e a d]") );
+ QCOMPARE(s12.arg(u"a"_s, u"b"_s, u"c"_s, u"d"_s).arg(u"e"_s), "[e b c e a d]"_L1);
+ QCOMPARE(s12.arg(u"a"_s).arg(u"b"_s, u"c"_s, u"d"_s, u"e"_s), "[e b c e a d]"_L1);
+ QCOMPARE( s13.arg(u"alpha"_s).arg(u"beta"_s),
+ QLatin1String("alpha% %x%cbeta %dbeta-%") );
+ QCOMPARE(s13.arg(u"alpha"_s, u"beta"_s), "alpha% %x%cbeta %dbeta-%"_L1);
+ QCOMPARE(s14.arg(u"a"_s, u"b"_s, u"c"_s), "abc"_L1);
+ QCOMPARE(s8.arg(u"%1"_s).arg(foo), "[foo foo]"_L1);
+ QCOMPARE(s8.arg(u"%1"_s, foo), "[%1 foo]"_L1);
+ QCOMPARE(s4.arg(foo, 2), "[foo]"_L1);
+ QCOMPARE(s4.arg(foo, -2), "[foo]"_L1);
+ QCOMPARE(s4.arg(foo, 10), "[ foo]"_L1);
+ QCOMPARE(s4.arg(foo, -10), "[foo ]"_L1);
+
+ QString firstName(u"James"_s);
+ QString lastName(u"Bond"_s);
+ QString fullName = QString(u"My name is %2, %1 %2"_s).arg(firstName).arg(lastName);
+ QCOMPARE(fullName, QLatin1String("My name is Bond, James Bond"));
+
+ // ### Qt 7: clean this up, leave just the #else branch
+#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
+ static const QRegularExpression nonAsciiArgWarning("QString::arg\\(\\): the replacement \".*\" contains non-ASCII digits");
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QCOMPARE( QString("%¹").arg("foo"), QString("foo") );
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QCOMPARE( QString("%¹%1").arg("foo"), QString("foofoo") );
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QCOMPARE( QString("%1²").arg("E=mc"), QString("E=mc") );
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QCOMPARE( QString("%1²%2").arg("a").arg("b"), QString("ba") );
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QCOMPARE( QString("%¹%1²%2").arg("a").arg("b"), QString("a%1²b") );
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QTest::ignoreMessage(QtWarningMsg, nonAsciiArgWarning);
+ QCOMPARE( QString("%2²%1").arg("a").arg("b"), QString("ba") );
+#else
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: %¹, foo");
+ QCOMPARE(u"%¹"_s.arg(foo), u"%¹");
+ QCOMPARE(u"%¹%1"_s.arg(foo), u"%¹foo");
+ QCOMPARE(u"%1²"_s.arg(u"E=mc"_s), u"E=mc²");
+ QCOMPARE(u"%1²%2"_s.arg(u"a"_s).arg(u"b"_s), u"a²b");
+ QCOMPARE(u"%¹%1²%2"_s.arg(u"a"_s).arg(u"b"_s), u"%¹a²b");
+ QCOMPARE(u"%2²%1"_s.arg(u"a"_s).arg(u"b"_s), u"b²a");
+#endif
+
+ // number overloads
+ QCOMPARE( s4.arg(0), QLatin1String("[0]") );
+ QCOMPARE( s4.arg(-1), QLatin1String("[-1]") );
+ QCOMPARE( s4.arg(4294967295UL), QLatin1String("[4294967295]") ); // ULONG_MAX 32
+ QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX
+ QLatin1String("[9223372036854775807]") );
+
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: , foo");
+ QCOMPARE(QString().arg(foo), QString());
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0");
+ QCOMPARE( QString().arg(0), QString() );
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0");
+ QCOMPARE(QString(u""_s).arg(0), u""_s);
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \" \" , 0");
+ QCOMPARE(QString(u" "_s).arg(0), " "_L1);
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%\" , 0");
+ QCOMPARE(QString(u"%"_s).arg(0), "%"_L1);
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%%\" , 0");
+ QCOMPARE(QString(u"%%"_s).arg(0), "%%"_L1);
+ QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%%%\" , 0");
+ QCOMPARE(QString(u"%%%"_s).arg(0), "%%%"_L1);
+ QCOMPARE(QString(u"%%%1%%%2"_s).arg(foo).arg(bar), "%%foo%%bar"_L1);
+
+ QCOMPARE(u"%1"_s.arg(null, 3), " "_L1);
+ QCOMPARE(u"%1"_s.arg(empty, 3), " "_L1);
+ QCOMPARE(u"%1"_s.arg(QStringView(), 3), " "_L1);
+ QCOMPARE(u"%1"_s.arg(QStringView(u""), 3), " "_L1);
+ QCOMPARE(u"%1%1"_s.arg(null), ""_L1);
+ QCOMPARE(u"%2%1"_s.arg(empty), "%2"_L1);
+ QCOMPARE(u"%2%1"_s.arg(QStringView()), "%2"_L1);
+ QCOMPARE(u"%2%1"_s.arg(QStringView(u"")), "%2"_L1);
+ QCOMPARE(u"%1"_s.arg(u"hello"_s, -10), "hello "_L1);
+ QCOMPARE(u"%1"_s.arg("hello"_L1, -5), "hello"_L1);
+ QCOMPARE(u"%1"_s.arg(u"hello", -2), "hello"_L1);
+ QCOMPARE(u"%1"_s.arg(u"hello"_s, 0), "hello"_L1);
+ QCOMPARE(u"%1"_s.arg("hello"_L1, 2), "hello"_L1);
+ QCOMPARE(u"%1"_s.arg(u"hello", 5), "hello"_L1);
+ QCOMPARE(u"%1"_s.arg(u"hello"_s, 10), " hello"_L1);
+ QCOMPARE(u"%1%1"_s.arg(u"hello"_s), "hellohello"_L1);
+ QCOMPARE(u"%2%1"_s.arg(u"hello"_s), "%2hello"_L1);
+
+ QCOMPARE( QString(u"%2 %L1"_s).arg(12345.6789).arg(12345.6789),
+ QLatin1String("12345.7 12.345,7") );
+ QCOMPARE( QString(u"[%2] [%L1]"_s).arg(12345.6789, 9).arg(12345.6789, 9),
+ QLatin1String("[ 12345.7] [ 12.345,7]") );
+ QCOMPARE( QString(u"[%2] [%L1]"_s).arg(12345.6789, 9, 'g', 7).arg(12345.6789, 9, 'g', 7),
+ QLatin1String("[ 12345.68] [12.345,68]") );
+ QCOMPARE( QString(u"[%2] [%L1]"_s).arg(12345.6789, 10, 'g', 7, QLatin1Char('0')).arg(12345.6789, 10, 'g', 7, QLatin1Char('0')),
+ QLatin1String("[0012345.68] [012.345,68]") );
+
+ QCOMPARE( QString(u"%2 %L1"_s).arg(123456789).arg(123456789),
+ QLatin1String("123456789 123.456.789") );
+ QCOMPARE( QString(u"[%2] [%L1]"_s).arg(123456789, 12).arg(123456789, 12),
+ QLatin1String("[ 123456789] [ 123.456.789]") );
+ QCOMPARE( QString(u"[%2] [%L1]"_s).arg(123456789, 13, 10, QLatin1Char('0')).arg(123456789, 12, 10, QLatin1Char('0')),
+ QLatin1String("[000123456789] [00123.456.789]") );
+ QCOMPARE( QString(u"[%2] [%L1]"_s).arg(123456789, 13, 16, QLatin1Char('0')).arg(123456789, 12, 16, QLatin1Char('0')),
+ QLatin1String("[0000075bcd15] [00000075bcd15]") );
+
+ QCOMPARE( QString(u"%L2 %L1 %3"_s).arg(12345.7).arg(123456789).arg('c'),
+ QLatin1String("123.456.789 12.345,7 c") );
+
+ // multi-digit replacement
+ QString input(u"%%%L0 %1 %02 %3 %4 %5 %L6 %7 %8 %%% %090 %10 %11 %L12 %14 %L9888 %9999 %%%%%%%L"_s);
+ input = input.arg(u"A"_s).arg(u"B"_s).arg(u"C"_s)
+ .arg(u"D"_s).arg(u"E"_s).arg(u"f"_s)
+ .arg(u"g"_s).arg(u"h"_s).arg(u"i"_s).arg(u"j"_s)
+ .arg(u"k"_s).arg(u"l"_s).arg(u"m"_s)
+ .arg(u"n"_s).arg(u"o"_s).arg(u"p"_s);
+
+ QCOMPARE(input, QLatin1String("%%A B C D E f g h i %%% j0 k l m n o88 p99 %%%%%%%L"));
+
+ QString str(u"%1 %2 %3 %4 %5 %6 %7 %8 %9 foo %10 %11 bar"_s);
+ str = str.arg(u"one"_s, u"2"_s, u"3"_s, u"4"_s, u"5"_s, u"6"_s, u"7"_s, u"8"_s, u"9"_s);
+ str = str.arg(u"ahoy"_s, u"there"_s);
+ QCOMPARE(str, "one 2 3 4 5 6 7 8 9 foo ahoy there bar"_L1);
+
+ // Make sure the single- and multi-arg expand the same sequences: at most
+ // two digits. The sequence below has four replacements: %01, %10 (twice),
+ // %11, and %12.
+ QString str2 = u"%100 %101 %110 %12 %0100"_s;
+ QLatin1StringView str2expected = "B0 B1 C0 D A00"_L1;
+ QCOMPARE(str2.arg(QChar(u'A')).arg(QChar(u'B')).arg(QChar(u'C')).arg(QChar(u'D')), str2expected);
+ QCOMPARE(str2.arg(QChar(u'A'), QChar(u'B')).arg(QChar(u'C')).arg(QChar(u'D')), str2expected);
+ QCOMPARE(str2.arg(QChar(u'A'), QChar(u'B'), QChar(u'C')).arg(QChar(u'D')), str2expected);
+ QCOMPARE(str2.arg(QChar(u'A'), QChar(u'B'), QChar(u'C'), QChar(u'D')), str2expected);
+
+ QCOMPARE(u"%1"_s.arg(-1, 3, 10, QChar(u'0')), "-01"_L1);
+ QCOMPARE(u"%1"_s.arg(-100, 3, 10, QChar(u'0')), "-100"_L1);
+ QCOMPARE(u"%1"_s.arg(-1, 3, 10, QChar(u' ')), " -1"_L1);
+ QCOMPARE(u"%1"_s.arg(-100, 3, 10, QChar(u' ')), "-100"_L1);
+ QCOMPARE(u"%1"_s.arg(1U, 3, 10, QChar(u' ')), " 1"_L1);
+ QCOMPARE(u"%1"_s.arg(1000U, 3, 10, QChar(u' ')), "1000"_L1);
+ QCOMPARE(u"%1"_s.arg(-1, 3, 10, QChar(u'x')), "x-1"_L1);
+ QCOMPARE(u"%1"_s.arg(-100, 3, 10, QChar(u'x')), "-100"_L1);
+ QCOMPARE(u"%1"_s.arg(1U, 3, 10, QChar(u'x')), "xx1"_L1);
+ QCOMPARE(u"%1"_s.arg(1000U, 3, 10, QChar(u'x')), "1000"_L1);
+
+ QCOMPARE(u"%1"_s.arg(-1., 3, 'g', -1, QChar(u'0')), "-01"_L1);
+ QCOMPARE(u"%1"_s.arg(-100., 3, 'g', -1, QChar(u'0')), "-100"_L1);
+ QCOMPARE(u"%1"_s.arg(-1., 3, 'g', -1, QChar(u' ')), " -1"_L1);
+ QCOMPARE(u"%1"_s.arg(-100., 3, 'g', -1, QChar(u' ')), "-100"_L1);
+ QCOMPARE(u"%1"_s.arg(1., 3, 'g', -1, QChar(u'x')), "xx1"_L1);
+ QCOMPARE(u"%1"_s.arg(1000., 3, 'g', -1, QChar(u'x')), "1000"_L1);
+ QCOMPARE(u"%1"_s.arg(-1., 3, 'g', -1, QChar(u'x')), "x-1"_L1);
+ QCOMPARE(u"%1"_s.arg(-100., 3, 'g', -1, QChar(u'x')), "-100"_L1);
+
+ transient.revise(QLocale(u"ar"_s));
+ QCOMPARE(u"%L1"_s.arg(12345.6789, 10, 'g', 7, QLatin1Char('0')),
+ u"\u0660\u0661\u0662\u066c\u0663\u0664\u0665\u066b\u0666\u0668"); // "٠١٢٬٣٤٥٫٦٨"
+ QCOMPARE(u"%L1"_s.arg(123456789, 13, 10, QLatin1Char('0')),
+ u"\u0660\u0660\u0661\u0662\u0663\u066c\u0664\u0665\u0666\u066c\u0667\u0668\u0669"); // ٠٠١٢٣٬٤٥٦٬٧٨٩
+}
+
+void tst_QString::number()
+{
+ QCOMPARE(QString::number(int(0)), QLatin1String("0"));
+ QCOMPARE(QString::number(std::copysign(0.0, -1.0)), QLatin1String("0"));
+ QCOMPARE(QString::number((unsigned int)(11)), QLatin1String("11"));
+ QCOMPARE(QString::number(-22L), QLatin1String("-22"));
+ QCOMPARE(QString::number(333UL), QLatin1String("333"));
+ QCOMPARE(QString::number(4.4), QLatin1String("4.4"));
+ QCOMPARE(QString::number(Q_INT64_C(-555)), QLatin1String("-555"));
+ QCOMPARE(QString::number(Q_UINT64_C(6666)), QLatin1String("6666"));
+}
+
+void tst_QString::number_double_data()
+{
+ QTest::addColumn<double>("value");
+ QTest::addColumn<char>("format");
+ QTest::addColumn<int>("precision");
+ QTest::addColumn<QString>("expected");
+
+ // This function is implemented in ../shared/test_number_shared.h
+ add_number_double_shared_data([](NumberDoubleTestData datum) {
+ const char *title =
+ !datum.optTitle.isEmpty() ? datum.optTitle.data() : datum.expected.data();
+ QTest::addRow("%s, format '%c', precision %d", title, datum.f, datum.p)
+ << datum.d << datum.f << datum.p << datum.expected.toString();
+ if (datum.f != 'f') { // Also test uppercase format
+ datum.f = QtMiscUtils::toAsciiUpper(datum.f);
+ QString upper = datum.expected.toString().toUpper();
+ QString upperTitle = QString::fromLatin1(title);
+ if (!datum.optTitle.isEmpty())
+ upperTitle += u", uppercase"_s;
+ else
+ upperTitle = upperTitle.toUpper();
+ QTest::addRow("%s, format '%c', precision %d", qPrintable(upper), datum.f, datum.p)
+ << datum.d << datum.f << datum.p << upper;
+ }
+ });
+}
+
+void tst_QString::number_double()
+{
+ QFETCH(double, value);
+ QFETCH(char, format);
+ QFETCH(int, precision);
+ if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) {
+ if (::qstrcmp(QTest::currentDataTag(), "Very small number, very high precision, format 'f', precision 350") == 0) {
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+ }
+ QTEST(QString::number(value, format, precision), "expected");
+}
+
+void tst_QString::number_base_data()
+{
+ QTest::addColumn<qlonglong>("n");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("base 10, positive") << 12346LL << 10 << u"12346"_s;
+ QTest::newRow("base 2, positive") << 12346LL << 2 << u"11000000111010"_s;
+ QTest::newRow("base 8, positive") << 12346LL << 8 << u"30072"_s;
+ QTest::newRow("base 16, positive") << 12346LL << 16 << u"303a"_s;
+ QTest::newRow("base 17, positive") << 12346LL << 17 << u"28c4"_s;
+ QTest::newRow("base 36, positive") << 2181789482LL << 36 << u"102zbje"_s;
+
+ QTest::newRow("base 10, negative") << -12346LL << 10 << u"-12346"_s;
+ QTest::newRow("base 2, negative") << -12346LL << 2 << u"-11000000111010"_s;
+ QTest::newRow("base 8, negative") << -12346LL << 8 << u"-30072"_s;
+ QTest::newRow("base 16, negative") << -12346LL << 16 << u"-303a"_s;
+ QTest::newRow("base 17, negative") << -12346LL << 17 << u"-28c4"_s;
+ QTest::newRow("base 36, negative") << -2181789482LL << 36 << u"-102zbje"_s;
+
+ QTest::newRow("base 2, minus 1") << -1LL << 2 << u"-1"_s;
+
+ QTest::newRow("largeint, base 10, positive")
+ << 123456789012LL << 10 << u"123456789012"_s;
+ QTest::newRow("largeint, base 2, positive")
+ << 123456789012LL << 2 << u"1110010111110100110010001101000010100"_s;
+ QTest::newRow("largeint, base 8, positive")
+ << 123456789012LL << 8 << u"1627646215024"_s;
+ QTest::newRow("largeint, base 16, positive")
+ << 123456789012LL << 16 << u"1cbe991a14"_s;
+ QTest::newRow("largeint, base 17, positive")
+ << 123456789012LL << 17 << u"10bec2b629"_s;
+
+ QTest::newRow("largeint, base 10, negative")
+ << -123456789012LL << 10 << u"-123456789012"_s;
+ QTest::newRow("largeint, base 2, negative")
+ << -123456789012LL << 2 << u"-1110010111110100110010001101000010100"_s;
+ QTest::newRow("largeint, base 8, negative")
+ << -123456789012LL << 8 << u"-1627646215024"_s;
+ QTest::newRow("largeint, base 16, negative")
+ << -123456789012LL << 16 << u"-1cbe991a14"_s;
+ QTest::newRow("largeint, base 17, negative")
+ << -123456789012LL << 17 << u"-10bec2b629"_s;
+}
+
+void tst_QString::number_base()
+{
+ QFETCH( qlonglong, n );
+ QFETCH( int, base );
+ QFETCH( QString, expected );
+ QCOMPARE(QString::number(n, base), expected);
+
+ // check qlonglong->QString->qlonglong round trip
+ for (int ibase = 2; ibase <= 36; ++ibase) {
+ auto stringrep = QString::number(n, ibase);
+ bool ok(false);
+ auto result = stringrep.toLongLong(&ok, ibase);
+ QVERIFY(ok);
+ QCOMPARE(n, result);
+ }
+}
+
+void tst_QString::doubleOut()
+{
+ // Regression test for QTBUG-63620; the first two paths lost the exponent's
+ // leading 0 at 5.7; C's printf() family guarantee a two-digit exponent (in
+ // contrast with ECMAScript, which forbids leading zeros).
+ const QString expect(QStringLiteral("1e-06"));
+ const double micro = 1e-6;
+ QCOMPARE(QString::number(micro), expect);
+ QCOMPARE(u"%1"_s.arg(micro), expect);
+ {
+ QCOMPARE(QString::asprintf("%g", micro), expect);
+ }
+ {
+ QString text;
+ QTextStream stream(&text);
+ stream << micro;
+ QCOMPARE(text, expect);
+ }
+}
+
+void tst_QString::capacity_data()
+{
+ length_data();
+}
+
+void tst_QString::capacity()
+{
+ QFETCH( QString, s1 );
+ QFETCH( qsizetype, res );
+
+ QString s2( s1 );
+ s2.reserve( res );
+ QVERIFY( s2.capacity() >= res );
+ QCOMPARE( s2, s1 );
+
+ s2 = s1; // share again
+ s2.reserve( res * 2 );
+ QVERIFY( s2.capacity() >= res * 2 );
+ if (res != 0) // can both point to QString::_empty when empty
+ QVERIFY(s2.constData() != s1.constData());
+ QCOMPARE( s2, s1 );
+
+ // don't share again -- s2 must be detached for squeeze() to do anything
+ s2.squeeze();
+ QVERIFY( s2.capacity() == res );
+ QCOMPARE( s2, s1 );
+
+ s2 = s1; // share again
+ int oldsize = s1.size();
+ s2.reserve( res / 2 );
+ QVERIFY( s2.capacity() >= res / 2 );
+ QVERIFY( s2.capacity() >= oldsize );
+ QCOMPARE( s2, s1 );
+}
+
+void tst_QString::section_data()
+{
+ QTest::addColumn<QString>("wholeString" );
+ QTest::addColumn<QString>("sep" );
+ QTest::addColumn<int>("start" );
+ QTest::addColumn<int>("end" );
+ QTest::addColumn<int>("flags" );
+ QTest::addColumn<QString>("sectionString" );
+ QTest::addColumn<bool>("regexp" );
+
+ QTest::newRow("null") << QString() << u","_s << 0 << -1 << int(QString::SectionDefault)
+ << QString() << false;
+ QTest::newRow("empty") << u""_s << u","_s << 0 << -1 << int(QString::SectionDefault) << u""_s
+ << false;
+ QTest::newRow("data0") << u"forename,middlename,surname,phone"_s << u","_s << 2 << 2
+ << int(QString::SectionDefault) << u"surname"_s << false;
+ QTest::newRow("data1") << u"/usr/local/bin/myapp"_s << u"/"_s << 3 << 4
+ << int(QString::SectionDefault) << u"bin/myapp"_s << false;
+ QTest::newRow("data2") << u"/usr/local/bin/myapp"_s << u"/"_s << 3 << 3
+ << int(QString::SectionSkipEmpty) << u"myapp"_s << false;
+ QTest::newRow("data3") << u"forename**middlename**surname**phone"_s << u"**"_s << 2 << 2
+ << int(QString::SectionDefault) << u"surname"_s << false;
+ QTest::newRow("data4") << u"forename**middlename**surname**phone"_s << u"**"_s << -3 << -2
+ << int(QString::SectionDefault) << u"middlename**surname"_s << false;
+ QTest::newRow("data5") << u"##Datt######wollen######wir######mal######sehen##"_s << u"#"_s << 0
+ << 0 << int(QString::SectionSkipEmpty) << u"Datt"_s << false;
+ QTest::newRow("data6") << u"##Datt######wollen######wir######mal######sehen##"_s << u"#"_s << 1
+ << 1 << int(QString::SectionSkipEmpty) << u"wollen"_s << false;
+ QTest::newRow("data7") << u"##Datt######wollen######wir######mal######sehen##"_s << u"#"_s << 2
+ << 2 << int(QString::SectionSkipEmpty) << u"wir"_s << false;
+ QTest::newRow("data8") << u"##Datt######wollen######wir######mal######sehen##"_s << u"#"_s << 3
+ << 3 << int(QString::SectionSkipEmpty) << u"mal"_s << false;
+ QTest::newRow("data9") << u"##Datt######wollen######wir######mal######sehen##"_s << u"#"_s << 4
+ << 4 << int(QString::SectionSkipEmpty) << u"sehen"_s << false;
+ // not fixed for 3.1
+ QTest::newRow("data10") << u"a/b/c/d"_s << u"/"_s << 1 << -1
+ << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep)
+ << u"/b/c/d"_s << false;
+ QTest::newRow("data11") << u"aoLoboLocolod"_s << u"olo"_s << -1 << -1
+ << int(QString::SectionCaseInsensitiveSeps) << u"d"_s << false;
+ QTest::newRow("data12") << u"F0"_s << u"F"_s << 0 << 0 << int(QString::SectionSkipEmpty)
+ << u"0"_s << false;
+ QTest::newRow("foo1") << u"foo;foo;"_s << u";"_s << 0 << 0
+ << int(QString::SectionIncludeLeadingSep) << u"foo"_s << false;
+ QTest::newRow("foo2") << u"foo;foo;"_s << u";"_s << 1 << 1
+ << int(QString::SectionIncludeLeadingSep) << u";foo"_s << false;
+ QTest::newRow("foo3") << u"foo;foo;"_s << u";"_s << 2 << 2
+ << int(QString::SectionIncludeLeadingSep) << u";"_s << false;
+ QTest::newRow("foo1rx") << u"foo;foo;"_s << u";"_s << 0 << 0
+ << int(QString::SectionIncludeLeadingSep) << u"foo"_s << true;
+ QTest::newRow("foo2rx") << u"foo;foo;"_s << u";"_s << 1 << 1
+ << int(QString::SectionIncludeLeadingSep) << u";foo"_s << true;
+ QTest::newRow("foo3rx") << u"foo;foo;"_s << u";"_s << 2 << 2
+ << int(QString::SectionIncludeLeadingSep) << u";"_s << true;
+
+ QTest::newRow("qmake_path") << u"/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode/"_s
+ << u"/"_s << 0 << -2 << int(QString::SectionDefault)
+ << u"/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode"_s
+ << false;
+ QTest::newRow("qmake_pathrx") << u"/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode/"_s
+ << u"/"_s << 0 << -2 << int(QString::SectionDefault)
+ << u"/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode"_s
+ << true;
+ QTest::newRow("data13") << u"||2|3|||"_s << u"|"_s << 0 << 1
+ << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep)
+ << u"||"_s << false;
+ QTest::newRow("data14") << u"||2|3|||"_s << u"\\|"_s << 0 << 1
+ << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep)
+ << u"||"_s << true;
+ QTest::newRow("data15") << u"|1|2|"_s << u"|"_s << 0 << 1
+ << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep)
+ << u"|1|"_s << false;
+ QTest::newRow("data16") << u"|1|2|"_s << u"\\|"_s << 0 << 1
+ << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep)
+ << u"|1|"_s << true;
+ QTest::newRow("normal1") << u"o1o2o"_s
+ << u"o"_s << 0 << 0
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o"_s << false;
+ QTest::newRow("normal2") << u"o1o2o"_s
+ << u"o"_s << 1 << 1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o1o"_s << false;
+ QTest::newRow("normal3") << u"o1o2o"_s
+ << u"o"_s << 2 << 2
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o2o"_s << false;
+ QTest::newRow("normal4") << u"o1o2o"_s
+ << u"o"_s << 2 << 3
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o2o"_s << false;
+ QTest::newRow("normal5") << u"o1o2o"_s
+ << u"o"_s << 1 << 2
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o1o2o"_s << false;
+ QTest::newRow("range1") << u"o1o2o"_s
+ << u"o"_s << -5 << -5
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << QString() << false;
+ QTest::newRow("range2") << u"oo1o2o"_s
+ << u"o"_s << -5 << 1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
+ |QString::SectionSkipEmpty)
+ << u"oo1o2o"_s << false;
+ QTest::newRow("range3") << u"o1o2o"_s
+ << u"o"_s << 2 << 1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << QString() << false;
+ QTest::newRow("range4") << u"o1o2o"_s
+ << u"o"_s << 4 << 4
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << QString() << false;
+ QTest::newRow("range5") << u"o1oo2o"_s
+ << u"o"_s << -2 << -1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
+ |QString::SectionSkipEmpty)
+ << u"o1oo2o"_s << false;
+ QTest::newRow("rx1") << u"o1o2o"_s
+ << u"[a-z]"_s << 0 << 0
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o"_s << true;
+ QTest::newRow("rx2") << u"o1o2o"_s
+ << u"[a-z]"_s << 1 << 1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o1o"_s << true;
+ QTest::newRow("rx3") << u"o1o2o"_s
+ << u"[a-z]"_s << 2 << 2
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o2o"_s << true;
+ QTest::newRow("rx4") << u"o1o2o"_s
+ << u"[a-z]"_s << 2 << 3
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o2o"_s << true;
+ QTest::newRow("rx5") << u"o1o2o"_s
+ << u"[a-z]"_s << 1 << 2
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << u"o1o2o"_s << true;
+ QTest::newRow("data17") << u"This is a story, a small story"_s
+ << u"\\b"_s << 3 << 3
+ << int(QString::SectionDefault)
+ << u"is"_s << true;
+ QTest::newRow("data18") << u"99.0 42.3"_s
+ << u"\\s*[AaBb]\\s*"_s << 1 << 1
+ << int(QString::SectionIncludeLeadingSep)
+ << QString() << true;
+}
+
+void tst_QString::section()
+{
+ QFETCH( QString, wholeString );
+ QFETCH( QString, sep );
+ QFETCH( int, start );
+ QFETCH( int, end );
+ QFETCH( int, flags );
+ QFETCH( QString, sectionString );
+ QFETCH( bool, regexp );
+ if (regexp) {
+#if QT_CONFIG(regularexpression)
+ QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString );
+#else
+ QSKIP("QRegularExpression not supported");
+#endif
+ } else {
+ if (sep.size() == 1)
+ QCOMPARE( wholeString.section( sep[0], start, end, QString::SectionFlag(flags) ), sectionString );
+ QCOMPARE( wholeString.section( sep, start, end, QString::SectionFlag(flags) ), sectionString );
+#if QT_CONFIG(regularexpression)
+ QCOMPARE( wholeString.section( QRegularExpression(QRegularExpression::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
+#endif
+ }
+}
+
+
+void tst_QString::operator_eqeq_nullstring()
+{
+ /* Some of these might not be all that logical but it's the behaviour we've had since 3.0.0
+ so we should probably stick with it. */
+
+ QVERIFY( QString() == u""_s );
+ QVERIFY( u""_s == QString() );
+
+ QVERIFY( QString(u""_s) == u""_s );
+ QVERIFY( u""_s == QString(u""_s) );
+
+ QVERIFY(QString() == nullptr);
+ QVERIFY(nullptr == QString());
+
+ QVERIFY(QString(u""_s) == nullptr);
+ QVERIFY(nullptr == QString(u""_s));
+
+ QVERIFY( QString().size() == 0 );
+
+ QVERIFY(u""_s.size() == 0);
+
+ QVERIFY(QString() == u""_s);
+ QVERIFY( QString(u""_s) == QString() );
+}
+
+void tst_QString::operator_smaller()
+{
+ QString null;
+ QString empty(u""_s);
+ QString foo(u"foo"_s);
+ [[maybe_unused]]
+ const char *nullC = nullptr;
+ [[maybe_unused]]
+ const char *emptyC = "";
+
+ QVERIFY( !(null < QString()) );
+ QVERIFY( !(null > QString()) );
+
+ QVERIFY(!(empty < u""_s));
+ QVERIFY(!(empty > u""_s));
+
+ QVERIFY( !(null < empty) );
+ QVERIFY( !(null > empty) );
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QVERIFY( !(nullC < empty) );
+ QVERIFY( !(nullC > empty) );
+
+ QVERIFY( !(null < emptyC) );
+ QVERIFY( !(null > emptyC) );
+#endif
+
+ QVERIFY( null < foo );
+ QVERIFY( !(null > foo) );
+ QVERIFY( foo > null );
+ QVERIFY( !(foo < null) );
+
+ QVERIFY( empty < foo );
+ QVERIFY( !(empty > foo) );
+ QVERIFY( foo > empty );
+ QVERIFY( !(foo < empty) );
+
+ QVERIFY( !(null < QLatin1String(nullptr)) );
+ QVERIFY( !(null > QLatin1String(nullptr)) );
+ QVERIFY( !(null < QLatin1String("")) );
+ QVERIFY( !(null > QLatin1String("")) );
+
+ QVERIFY( !(null < QLatin1String("")) );
+ QVERIFY( !(null > QLatin1String("")) );
+ QVERIFY( !(empty < QLatin1String("")) );
+ QVERIFY( !(empty > QLatin1String("")) );
+
+ QVERIFY( !(QLatin1String(nullptr) < null) );
+ QVERIFY( !(QLatin1String(nullptr) > null) );
+ QVERIFY( !(QLatin1String("") < null) );
+ QVERIFY( !(QLatin1String("") > null) );
+
+ QVERIFY( !(QLatin1String(nullptr) < empty) );
+ QVERIFY( !(QLatin1String(nullptr) > empty) );
+ QVERIFY( !(QLatin1String("") < empty) );
+ QVERIFY( !(QLatin1String("") > empty) );
+
+ QVERIFY( QLatin1String(nullptr) < foo );
+ QVERIFY( !(QLatin1String(nullptr) > foo) );
+ QVERIFY( QLatin1String("") < foo );
+ QVERIFY( !(QLatin1String("") > foo) );
+
+ QVERIFY( foo > QLatin1String(nullptr) );
+ QVERIFY( !(foo < QLatin1String(nullptr)) );
+ QVERIFY( foo > QLatin1String("") );
+ QVERIFY( !(foo < QLatin1String("")) );
+
+ QVERIFY( QLatin1String(nullptr) == empty);
+ QVERIFY( QLatin1String(nullptr) == null);
+ QVERIFY( QLatin1String("") == empty);
+ QVERIFY( QLatin1String("") == null);
+
+ QVERIFY( !(foo < QLatin1String("foo")));
+ QVERIFY( !(foo > QLatin1String("foo")));
+ QVERIFY( !(QLatin1String("foo") < foo));
+ QVERIFY( !(QLatin1String("foo") > foo));
+
+ QVERIFY( !(foo < QLatin1String("a")));
+ QVERIFY( (foo > QLatin1String("a")));
+ QVERIFY( (QLatin1String("a") < foo));
+ QVERIFY( !(QLatin1String("a") > foo));
+
+ QVERIFY( (foo < QLatin1String("z")));
+ QVERIFY( !(foo > QLatin1String("z")));
+ QVERIFY( !(QLatin1String("z") < foo));
+ QVERIFY( (QLatin1String("z") > foo));
+
+ // operator< is not locale-aware (or shouldn't be)
+ QCOMPARE_LT(foo, QString::fromUtf8("\xc3\xa9"));
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ QVERIFY( foo < "\xc3\xa9" );
+#endif
+
+ QCOMPARE_LT(QString(u"a"_s), QString(u"b"_s));
+ QCOMPARE_LE(QString(u"a"_s), QString(u"b"_s));
+ QCOMPARE_LE(QString(u"a"_s), QString(u"a"_s));
+ QCOMPARE_EQ(QString(u"a"_s), QString(u"a"_s));
+ QCOMPARE_GE(QString(u"a"_s), QString(u"a"_s));
+ QCOMPARE_GE(QString(u"b"_s), QString(u"a"_s));
+ QCOMPARE_GT(QString(u"b"_s), QString(u"a"_s));
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ QVERIFY(QString("a") < "b");
+ QVERIFY(QString("a") <= "b");
+ QVERIFY(QString("a") <= "a");
+ QVERIFY(QString("a") == "a");
+ QVERIFY(QString("a") >= "a");
+ QVERIFY(QString("b") >= "a");
+ QVERIFY(QString("b") > "a");
+
+ QCOMPARE_LT("a", QString(u"b"_s));
+ QCOMPARE_LE("a", QString(u"b"_s));
+ QCOMPARE_LE("a", QString(u"a"_s));
+ QCOMPARE_EQ("a", QString(u"a"_s));
+ QCOMPARE_GE("a", QString(u"a"_s));
+ QCOMPARE_GE("b", QString(u"a"_s));
+ QCOMPARE_GT("b", QString(u"a"_s));
+#endif
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QVERIFY(QString("a") < QByteArray("b"));
+ QVERIFY(QString("a") <= QByteArray("b"));
+ QVERIFY(QString("a") <= QByteArray("a"));
+ QVERIFY(QString("a") == QByteArray("a"));
+ QVERIFY(QString("a") >= QByteArray("a"));
+ QVERIFY(QString("b") >= QByteArray("a"));
+ QVERIFY(QString("b") > QByteArray("a"));
+#endif
+
+ QVERIFY(QLatin1String("a") < QString(u"b"_s));
+ QVERIFY(QLatin1String("a") <= QString(u"b"_s));
+ QVERIFY(QLatin1String("a") <= QString(u"a"_s));
+ QVERIFY(QLatin1String("a") == QString(u"a"_s));
+ QVERIFY(QLatin1String("a") >= QString(u"a"_s));
+ QVERIFY(QLatin1String("b") >= QString(u"a"_s));
+ QVERIFY(QLatin1String("b") > QString(u"a"_s));
+
+ QVERIFY(QString(u"a"_s) < QLatin1String("b"));
+ QVERIFY(QString(u"a"_s) <= QLatin1String("b"));
+ QVERIFY(QString(u"a"_s) <= QLatin1String("a"));
+ QVERIFY(QString(u"a"_s) == QLatin1String("a"));
+ QVERIFY(QString(u"a"_s) >= QLatin1String("a"));
+ QVERIFY(QString(u"b"_s) >= QLatin1String("a"));
+ QVERIFY(QString(u"b"_s) > QLatin1String("a"));
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QVERIFY("a" < QLatin1String("b"));
+ QVERIFY("a" <= QLatin1String("b"));
+ QVERIFY("a" <= QLatin1String("a"));
+ QVERIFY("a" == QLatin1String("a"));
+ QVERIFY("a" >= QLatin1String("a"));
+ QVERIFY("b" >= QLatin1String("a"));
+ QVERIFY("b" > QLatin1String("a"));
+
+ QVERIFY(QLatin1String("a") < "b");
+ QVERIFY(QLatin1String("a") <= "b");
+ QVERIFY(QLatin1String("a") <= "a");
+ QVERIFY(QLatin1String("a") == "a");
+ QVERIFY(QLatin1String("a") >= "a");
+ QVERIFY(QLatin1String("b") >= "a");
+ QVERIFY(QLatin1String("b") > "a");
+#endif
+}
+
+void tst_QString::integer_conversion_data()
+{
+ QTest::addColumn<QString>("num_str");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<bool>("good");
+ QTest::addColumn<qlonglong>("num");
+
+ QTest::newRow("C empty 0") << u""_s << 0 << false << qlonglong(0);
+ QTest::newRow("C empty 8") << u""_s << 8 << false << qlonglong(0);
+ QTest::newRow("C empty 10") << u""_s << 10 << false << qlonglong(0);
+ QTest::newRow("C empty 16") << u""_s << 16 << false << qlonglong(0);
+
+ QTest::newRow("C null 0") << QString() << 0 << false << (qlonglong)0;
+ QTest::newRow("C null 8") << QString() << 8 << false << (qlonglong)0;
+ QTest::newRow("C null 10") << QString() << 10 << false << (qlonglong)0;
+ QTest::newRow("C null 16") << QString() << 16 << false << (qlonglong)0;
+
+ QTest::newRow("C -0xf 0") << u" -0xf"_s << 0 << true << qlonglong(-15);
+ QTest::newRow("C -0xf 0") << u"-0xf "_s << 0 << true << qlonglong(-15);
+ QTest::newRow("C \t0xf\t 0") << u"\t0xf\t"_s << 0 << true << qlonglong(15);
+ QTest::newRow("C -010 0") << u" -010"_s << 0 << true << qlonglong(-8);
+ QTest::newRow("C 010 0") << u"010 "_s << 0 << true << qlonglong(8);
+ QTest::newRow("C \t-010\t 0") << u"\t-010\t"_s << 0 << true << qlonglong(-8);
+ QTest::newRow("C 123 10") << u" 123"_s << 10 << true << qlonglong(123);
+ QTest::newRow("C 123 10") << u"123 "_s << 10 << true << qlonglong(123);
+ QTest::newRow("C \t123\t 10") << u"\t123\t"_s << 10 << true << qlonglong(123);
+ QTest::newRow("C -0xf 16") << u" -0xf"_s << 16 << true << qlonglong(-15);
+ QTest::newRow("C -0xf 16") << u"-0xf "_s << 16 << true << qlonglong(-15);
+ QTest::newRow("C \t0xf\t 16") << u"\t0xf\t"_s << 16 << true << qlonglong(15);
+
+ QTest::newRow("C -0 0") << u"-0"_s << 0 << true << qlonglong(0);
+ QTest::newRow("C -0 8") << u"-0"_s << 8 << true << qlonglong(0);
+ QTest::newRow("C -0 10") << u"-0"_s << 10 << true << qlonglong(0);
+ QTest::newRow("C -0 16") << u"-0"_s << 16 << true << qlonglong(0);
+
+ QTest::newRow("C 1.234 10") << u"1.234"_s << 10 << false << qlonglong(0);
+ QTest::newRow("C 1,234 10") << u"1,234"_s << 10 << false << qlonglong(0);
+
+ QTest::newRow("C 0x 0") << u"0x"_s << 0 << false << qlonglong(0);
+ QTest::newRow("C 0x 16") << u"0x"_s << 16 << false << qlonglong(0);
+
+ QTest::newRow("C 10 0") << u"10"_s << 0 << true << qlonglong(10);
+ QTest::newRow("C 010 0") << u"010"_s << 0 << true << qlonglong(8);
+ QTest::newRow("C 0x10 0") << u"0x10"_s << 0 << true << qlonglong(16);
+ QTest::newRow("C 10 8") << u"10"_s << 8 << true << qlonglong(8);
+ QTest::newRow("C 010 8") << u"010"_s << 8 << true << qlonglong(8);
+ QTest::newRow("C 0x10 8") << u"0x10"_s << 8 << false << qlonglong(0);
+ QTest::newRow("C 10 10") << u"10"_s << 10 << true << qlonglong(10);
+ QTest::newRow("C 010 10") << u"010"_s << 10 << true << qlonglong(10);
+ QTest::newRow("C 0x10 10") << u"0x10"_s << 10 << false << qlonglong(0);
+ QTest::newRow("C 10 16") << u"10"_s << 16 << true << qlonglong(16);
+ QTest::newRow("C 010 16") << u"010"_s << 16 << true << qlonglong(16);
+ QTest::newRow("C 0x10 16") << u"0x10"_s << 16 << true << qlonglong(16);
+
+ QTest::newRow("C -10 0") << u"-10"_s << 0 << true << qlonglong(-10);
+ QTest::newRow("C -010 0") << u"-010"_s << 0 << true << qlonglong(-8);
+ QTest::newRow("C -0x10 0") << u"-0x10"_s << 0 << true << qlonglong(-16);
+ QTest::newRow("C -10 8") << u"-10"_s << 8 << true << qlonglong(-8);
+ QTest::newRow("C -010 8") << u"-010"_s << 8 << true << qlonglong(-8);
+ QTest::newRow("C -0x10 8") << u"-0x10"_s << 8 << false << qlonglong(0);
+ QTest::newRow("C -10 10") << u"-10"_s << 10 << true << qlonglong(-10);
+ QTest::newRow("C -010 10") << u"-010"_s << 10 << true << qlonglong(-10);
+ QTest::newRow("C -0x10 10") << u"-0x10"_s << 10 << false << qlonglong(0);
+ QTest::newRow("C -10 16") << u"-10"_s << 16 << true << qlonglong(-16);
+ QTest::newRow("C -010 16") << u"-010"_s << 16 << true << qlonglong(-16);
+ QTest::newRow("C -0x10 16") << u"-0x10"_s << 16 << true << qlonglong(-16);
+
+ // Let's try some Arabic
+ const char16_t arabic_str[] = { 0x0661, 0x0662, 0x0663, 0x0664, 0x0000 }; // "1234"
+ QTest::newRow("ar_SA 1234 0") << QString::fromUtf16(arabic_str) << 0 << false << (qlonglong)0;
+}
+
+void tst_QString::integer_conversion()
+{
+ QFETCH(QString, num_str);
+ QFETCH(int, base);
+ QFETCH(bool, good);
+ QFETCH(qlonglong, num);
+
+ bool ok;
+ qlonglong d = num_str.toLongLong(&ok, base);
+ QCOMPARE(ok, good);
+
+ if (ok) {
+ QCOMPARE(d, num);
+ }
+}
+
+void tst_QString::double_conversion_data()
+{
+ QTest::addColumn<QString>("num_str");
+ QTest::addColumn<bool>("good");
+ QTest::addColumn<double>("num");
+
+ // The good...
+
+ QTest::newRow("C 1") << u"1"_s << true << 1.0;
+ QTest::newRow("C 1.0") << u"1.0"_s << true << 1.0;
+ QTest::newRow("C 1.234") << u"1.234"_s << true << 1.234;
+ QTest::newRow("C 1.234e-10") << u"1.234e-10"_s << true << 1.234e-10;
+ QTest::newRow("C 1.234E10") << u"1.234E10"_s << true << 1.234e10;
+ QTest::newRow("C 1e10") << u"1e10"_s << true << 1.0e10;
+
+ // The bad...
+
+ QTest::newRow("C empty") << u""_s << false << 0.0;
+ QTest::newRow("C null") << QString() << false << 0.0;
+ QTest::newRow("C .") << u"."_s << false << 0.0;
+ QTest::newRow("C 1e") << u"1e"_s << false << 0.0;
+ QTest::newRow("C 1,") << u"1,"_s << false << 0.0;
+ QTest::newRow("C 1,0") << u"1,0"_s << false << 0.0;
+ QTest::newRow("C 1,000") << u"1,000"_s << false << 0.0;
+ QTest::newRow("C 1e1.0") << u"1e1.0"_s << false << 0.0;
+ QTest::newRow("C 1e+") << u"1e+"_s << false << 0.0;
+ QTest::newRow("C 1e-") << u"1e-"_s << false << 0.0;
+ QTest::newRow("de_DE 1,0") << u"1,0"_s << false << 0.0;
+ QTest::newRow("de_DE 1,234") << u"1,234"_s << false << 0.0;
+ QTest::newRow("de_DE 1,234e-10") << u"1,234e-10"_s << false << 0.0;
+ QTest::newRow("de_DE 1,234E10") << u"1,234E10"_s << false << 0.0;
+
+ // And the ugly...
+
+ QTest::newRow("C .1") << u".1"_s << true << 0.1;
+ QTest::newRow("C -.1") << u"-.1"_s << true << -0.1;
+ QTest::newRow("C 1.") << u"1."_s << true << 1.0;
+ QTest::newRow("C 1.E10") << u"1.E10"_s << true << 1.0e10;
+ QTest::newRow("C 1e+10") << u"1e+10"_s << true << 1.0e+10;
+ QTest::newRow("C 1") << u" 1"_s << true << 1.0;
+ QTest::newRow("C 1 ") << u"1 "_s << true << 1.0;
+
+ // Let's try some Arabic
+ const char16_t arabic_str[] = { 0x0660, 0x066B, 0x0661, 0x0662,
+ 0x0663, 0x0664, 0x0065, 0x0662,
+ 0x0000 }; // "0.1234e2"
+ QTest::newRow("ar_SA") << QString::fromUtf16(arabic_str) << false << 0.0;
+}
+
+void tst_QString::double_conversion()
+{
+#define MY_DOUBLE_EPSILON (2.22045e-16)
+
+ QFETCH(QString, num_str);
+ QFETCH(bool, good);
+ QFETCH(double, num);
+
+ bool ok;
+ double d = num_str.toDouble(&ok);
+ QCOMPARE(ok, good);
+
+ if (ok) {
+ double diff = d - num;
+ if (diff < 0)
+ diff = -diff;
+ QVERIFY(diff <= MY_DOUBLE_EPSILON);
+ }
+}
+
+#ifndef Q_MOC_RUN
+#include "double_data.h"
+#endif
+
+void tst_QString::tortureSprintfDouble()
+{
+ const SprintfDoubleData *data = g_sprintf_double_data;
+
+ for (; data->fmt != 0; ++data) {
+ double d;
+ char *buff = (char *)&d;
+# ifndef Q_BYTE_ORDER
+# error "Q_BYTE_ORDER not defined"
+# endif
+
+# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ for (uint i = 0; i < 8; ++i)
+ buff[i] = data->bytes[i];
+# else
+ for (uint i = 0; i < 8; ++i)
+ buff[7 - i] = data->bytes[i];
+# endif
+ const QString s = QString::asprintf(data->fmt, d);
+#ifdef QT_NO_FPU // reduced precision when running with hardfloats in qemu
+ if (d - 0.1 < 1e12)
+ QSKIP("clib sprintf doesn't fill with 0's on this platform");
+ QCOMPARE(s.left(16), QString(data->expected).left(16));
+#else
+ QCOMPARE(s, QLatin1String(data->expected));
+#endif
+ }
+}
+
+void tst_QString::iterators()
+{
+ QString emptyStr;
+ QCOMPARE(emptyStr.constBegin(), emptyStr.constEnd());
+ QCOMPARE(emptyStr.cbegin(), emptyStr.cend());
+ QVERIFY(!emptyStr.isDetached());
+ QCOMPARE(emptyStr.begin(), emptyStr.end());
+
+ QString s = u"0123456789"_s;
+
+ auto it = s.begin();
+ auto constIt = s.cbegin();
+ qsizetype idx = 0;
+
+ QCOMPARE(*it, s[idx]);
+ QCOMPARE(*constIt, s[idx]);
+
+ it++;
+ constIt++;
+ idx++;
+ QCOMPARE(*it, s[idx]);
+ QCOMPARE(*constIt, s[idx]);
+
+ it += 5;
+ constIt += 5;
+ idx += 5;
+ QCOMPARE(*it, s[idx]);
+ QCOMPARE(*constIt, s[idx]);
+
+ it -= 3;
+ constIt -= 3;
+ idx -= 3;
+ QCOMPARE(*it, s[idx]);
+ QCOMPARE(*constIt, s[idx]);
+
+ it--;
+ constIt--;
+ idx--;
+ QCOMPARE(*it, s[idx]);
+ QCOMPARE(*constIt, s[idx]);
+}
+
+void tst_QString::reverseIterators()
+{
+ QString emptyStr;
+ QCOMPARE(emptyStr.crbegin(), emptyStr.crend());
+ QVERIFY(!emptyStr.isDetached());
+ QCOMPARE(emptyStr.rbegin(), emptyStr.rend());
+
+ QString s(u"1234"_s);
+ QString sr = s;
+ std::reverse(sr.begin(), sr.end());
+ const QString &csr = sr;
+ QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin()));
+ QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin()));
+ QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin()));
+ QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin()));
+ QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin()));
+ QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin()));
+}
+
+void tst_QString::split_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<QString>("sep");
+ QTest::addColumn<QStringList>("result");
+
+ QTest::newRow("1") << u"a,b,c"_s << u","_s << QStringList{u"a"_s, u"b"_s, u"c"_s};
+ QTest::newRow("2") << u"-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile"_s << u" "_s
+ << QStringList{ u"-rw-r--r--"_s, u""_s, u"1"_s, u"0"_s, u""_s,
+ u"0"_s, u""_s, u"519240"_s, u"Jul"_s, u""_s,
+ u"9"_s, u""_s, u"2002"_s, u"bigfile"_s };
+ QTest::newRow("one-empty") << u""_s << u" "_s << QStringList{u""_s};
+ QTest::newRow("two-empty") << u" "_s << u" "_s << QStringList{u""_s, u""_s};
+ QTest::newRow("three-empty") << u" "_s << u" "_s << QStringList{u""_s, u""_s, u""_s};
+
+ QTest::newRow("all-empty") << u""_s << u""_s << QStringList{u""_s, u""_s};
+ QTest::newRow("sep-empty") << u"abc"_s << u""_s << QStringList{u""_s, u"a"_s, u"b"_s, u"c"_s, u""_s};
+ QTest::newRow("null-empty") << QString() << u" "_s << QStringList{u""_s};
+}
+
+template<class> struct StringSplitWrapper;
+template<> struct StringSplitWrapper<QString>
+{
+ const QString &string;
+
+ QStringList split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
+ QStringList split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
+#if QT_CONFIG(regularexpression)
+ QStringList split(const QRegularExpression &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const { return string.split(sep, behavior); }
+#endif
+};
+
+template<> struct StringSplitWrapper<QStringView>
+{
+ const QString &string;
+ QList<QStringView> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ { return QStringView{string}.split(sep, behavior, cs); }
+ QList<QStringView> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ { return QStringView{string}.split(sep, behavior, cs); }
+#if QT_CONFIG(regularexpression)
+ QList<QStringView> split(const QRegularExpression &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const
+ { return QStringView{string}.split(sep, behavior); }
+#endif
+};
+
+static bool operator==(const QList<QStringView> &result, const QStringList &expected)
+{
+ if (expected.size() != result.size())
+ return false;
+ for (int i = 0; i < expected.size(); ++i)
+ if (expected.at(i) != result.at(i))
+ return false;
+ return true;
+}
+
+template<class List>
+void tst_QString::split(const QString &string, const QString &sep, QStringList result)
+{
+#if QT_CONFIG(regularexpression)
+ QRegularExpression re(QRegularExpression::escape(sep));
+#endif
+
+ List list;
+ StringSplitWrapper<typename List::value_type> str = {string};
+
+ list = str.split(sep);
+ QVERIFY(list == result);
+#if QT_CONFIG(regularexpression)
+ list = str.split(re);
+ QVERIFY(list == result);
+#endif
+ if (sep.size() == 1) {
+ list = str.split(sep.at(0));
+ QVERIFY(list == result);
+ }
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ list = str.split(sep, Qt::KeepEmptyParts);
+ QVERIFY(list == result);
+#if QT_CONFIG(regularexpression)
+ list = str.split(re, Qt::KeepEmptyParts);
+ QVERIFY(list == result);
+#endif
+ if (sep.size() == 1) {
+ list = str.split(sep.at(0), Qt::KeepEmptyParts);
+ QVERIFY(list == result);
+ }
+
+ result.removeAll(u""_s);
+ list = str.split(sep, Qt::SkipEmptyParts);
+ QVERIFY(list == result);
+#if QT_CONFIG(regularexpression)
+ list = str.split(re, Qt::SkipEmptyParts);
+ QVERIFY(list == result);
+#endif
+ if (sep.size() == 1) {
+ list = str.split(sep.at(0), Qt::SkipEmptyParts);
+ QVERIFY(list == result);
+ }
+QT_WARNING_POP
+}
+
+void tst_QString::split()
+{
+ QFETCH(QString, str);
+ QFETCH(QString, sep);
+ QFETCH(QStringList, result);
+ split<QStringList>(str, sep, result);
+ split<QList<QStringView>>(str, sep, result);
+}
+
+#if QT_CONFIG(regularexpression)
+void tst_QString::split_regularexpression_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("result");
+
+ QTest::newRow("data01") << "Some text\n\twith strange whitespace."
+ << "\\s+"
+ << QStringList{u"Some"_s, u"text"_s, u"with"_s, u"strange"_s, u"whitespace."_s };
+
+ QTest::newRow("data02") << "This time, a normal English sentence."
+ << "\\W+"
+ << QStringList{u"This"_s, u"time"_s, u"a"_s, u"normal"_s, u"English"_s, u"sentence"_s, u""_s};
+
+ QTest::newRow("data03") << "Now: this sentence fragment."
+ << "\\b"
+ << QStringList{u""_s, u"Now"_s, u": "_s, u"this"_s, u" "_s, u"sentence"_s, u" "_s, u"fragment"_s, u"."_s};
+}
+
+template<class List, class RegExp>
+void tst_QString::split_regexp(const QString &_string, const QString &pattern, QStringList result)
+{
+ List list;
+ StringSplitWrapper<typename List::value_type> string = {_string};
+
+ list = string.split(RegExp(pattern));
+ QVERIFY(list == result);
+
+ result.removeAll(QString());
+
+ list = string.split(RegExp(pattern), Qt::SkipEmptyParts);
+ QVERIFY(list == result);
+}
+
+void tst_QString::split_regularexpression()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, result);
+ split_regexp<QStringList, QRegularExpression>(string, pattern, result);
+ split_regexp<QList<QStringView>, QRegularExpression>(string, pattern, result);
+}
+
+// Test that rvalue strings (e.g. temporaries) are kept alive in
+// QRegularExpression-related APIs
+void tst_QString::regularexpression_lifetime()
+{
+ const auto getString = [] {
+ // deliberately heap-allocated
+ return QString(QLatin1String("the quick brown fox jumps over the lazy dog"));
+ };
+
+ QRegularExpression re(u"\\w{5}"_s);
+
+ {
+ QString s = getString();
+ QRegularExpressionMatch match;
+ const bool contains = std::move(s).contains(re, &match);
+ s.fill(u'X'); // NOLINT(bugprone-use-after-move)
+ QVERIFY(contains);
+ QCOMPARE(match.capturedView(), u"quick");
+ }
+
+ {
+ QString s = getString();
+ QRegularExpressionMatch match;
+ const auto index = std::move(s).indexOf(re, 0, &match);
+ s.fill(u'X'); // NOLINT(bugprone-use-after-move)
+ QCOMPARE(index, 4);
+ QCOMPARE(match.capturedView(), u"quick");
+ }
+
+ {
+ QString s = getString();
+ QRegularExpressionMatch match;
+ const auto lastIndex = std::move(s).lastIndexOf(re, &match);
+ s.fill(u'X'); // NOLINT(bugprone-use-after-move)
+ QCOMPARE(lastIndex, 20);
+ QCOMPARE(match.capturedView(), u"jumps");
+ }
+}
+#endif
+
+void tst_QString::fromUtf16_data()
+{
+ QTest::addColumn<QString>("ucs2");
+ QTest::addColumn<QString>("res");
+ QTest::addColumn<int>("len");
+
+ QTest::newRow("str0") << u"abcdefgh"_s << u"abcdefgh"_s << -1;
+ QTest::newRow("str0-len") << u"abcdefgh"_s << u"abc"_s << 3;
+}
+
+#if QT_DEPRECATED_SINCE(6, 0)
+void tst_QString::fromUtf16()
+{
+ QFETCH(QString, ucs2);
+ QFETCH(QString, res);
+ QFETCH(int, len);
+ QT_IGNORE_DEPRECATIONS(QCOMPARE(QString::fromUtf16(ucs2.utf16(), len), res);)
+}
+#endif // QT_DEPRECATED_SINCE(6, 0)
+
+void tst_QString::fromUtf16_char16()
+{
+ QFETCH(QString, ucs2);
+ QFETCH(QString, res);
+ QFETCH(int, len);
+
+ QCOMPARE(QString::fromUtf16(reinterpret_cast<const char16_t *>(ucs2.utf16()), len), res);
+}
+
+void tst_QString::unicodeStrings()
+{
+ QString nullStr;
+ QVERIFY(nullStr.toStdU16String().empty());
+ QVERIFY(nullStr.toStdU32String().empty());
+ QVERIFY(!nullStr.isDetached());
+
+ QString emptyStr(u""_s);
+ QVERIFY(emptyStr.toStdU16String().empty());
+ QVERIFY(emptyStr.toStdU32String().empty());
+ QVERIFY(!emptyStr.isDetached());
+
+ QString s1, s2;
+ static const std::u16string u16str1(u"Hello Unicode World");
+ static const std::u32string u32str1(U"Hello Unicode World");
+ s1 = QString::fromStdU16String(u16str1);
+ s2 = QString::fromStdU32String(u32str1);
+ QCOMPARE(s1, u"Hello Unicode World");
+ QCOMPARE(s1, s2);
+
+ QCOMPARE(s2.toStdU16String(), u16str1);
+ QCOMPARE(s1.toStdU32String(), u32str1);
+
+ s1 = QString::fromStdU32String(std::u32string(U"\u221212\U000020AC\U00010000"));
+ QCOMPARE(s1, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
+}
+
+void tst_QString::latin1String()
+{
+ QString s(u"Hello"_s);
+
+ QVERIFY(s == QLatin1String("Hello"));
+ QVERIFY(s != QLatin1String("Hello World"));
+ QVERIFY(s < QLatin1String("Helloa"));
+ QVERIFY(!(s > QLatin1String("Helloa")));
+ QVERIFY(s > QLatin1String("Helln"));
+ QVERIFY(s > QLatin1String("Hell"));
+ QVERIFY(!(s < QLatin1String("Helln")));
+ QVERIFY(!(s < QLatin1String("Hell")));
+}
+
+void tst_QString::isInf_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<bool>("expected_ok");
+ QTest::addColumn<bool>("expected_is_inf");
+
+ QTest::newRow("inf") << u"inf"_s << true << true;
+ QTest::newRow("INF") << u"INF"_s << true << true;
+ QTest::newRow("inf ") << u"inf "_s << true << true;
+ QTest::newRow("+inf") << u"+inf"_s << true << true;
+ QTest::newRow("\t +INF") << u"\t +INF"_s << true << true;
+ QTest::newRow("\t INF") << u"\t INF"_s << true << true;
+ QTest::newRow("inF ") << u"inF "_s << true << true;
+ QTest::newRow("+iNf") << u"+iNf"_s << true << true;
+ QTest::newRow("INFe-10") << u"INFe-10"_s << false << false;
+ QTest::newRow("0xINF") << u"0xINF"_s << false << false;
+ QTest::newRow("- INF") << u"- INF"_s << false << false;
+ QTest::newRow("+ INF") << u"+ INF"_s << false << false;
+ QTest::newRow("-- INF") << u"-- INF"_s << false << false;
+ QTest::newRow("inf0") << u"inf0"_s << false << false;
+ QTest::newRow("--INF") << u"--INF"_s << false << false;
+ QTest::newRow("++INF") << u"++INF"_s << false << false;
+ QTest::newRow("INF++") << u"INF++"_s << false << false;
+ QTest::newRow("INF--") << u"INF--"_s << false << false;
+ QTest::newRow("INF +") << u"INF +"_s << false << false;
+ QTest::newRow("INF -") << u"INF -"_s << false << false;
+ QTest::newRow("0INF") << u"0INF"_s << false << false;
+}
+
+void tst_QString::isInf()
+{
+ QFETCH(QString, str);
+ QFETCH(bool, expected_ok);
+ QFETCH(bool, expected_is_inf);
+
+ bool ok = false;
+ double dbl = str.toDouble(&ok);
+ QVERIFY(ok == expected_ok);
+ QVERIFY(qIsInf(dbl) == expected_is_inf);
+}
+
+void tst_QString::isNan_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<bool>("expected_ok");
+ QTest::addColumn<bool>("expected_is_nan");
+
+ QTest::newRow("nan") << u"nan"_s << true << true;
+ QTest::newRow("NAN") << u"NAN"_s << true << true;
+ QTest::newRow("nan ") << u"nan "_s << true << true;
+ QTest::newRow("\t NAN") << u"\t NAN"_s << true << true;
+ QTest::newRow("\t NAN ") << u"\t NAN "_s << true << true;
+ QTest::newRow("-nan") << u"-nan"_s << false << false;
+ QTest::newRow("+NAN") << u"+NAN"_s << false << false;
+ QTest::newRow("NaN") << u"NaN"_s << true << true;
+ QTest::newRow("nAn") << u"nAn"_s << true << true;
+ QTest::newRow("NANe-10") << u"NANe-10"_s << false << false;
+ QTest::newRow("0xNAN") << u"0xNAN"_s << false << false;
+ QTest::newRow("0NAN") << u"0NAN"_s << false << false;
+}
+
+void tst_QString::isNan()
+{
+ QFETCH(QString, str);
+ QFETCH(bool, expected_ok);
+ QFETCH(bool, expected_is_nan);
+
+ bool ok = false;
+ double dbl = str.toDouble(&ok);
+ QVERIFY(ok == expected_ok);
+ QVERIFY(qIsNaN(dbl) == expected_is_nan);
+}
+
+void tst_QString::nanAndInf()
+{
+ bool ok;
+ double d;
+
+ d = u"-INF"_s.toDouble(&ok);
+ QVERIFY(ok);
+ QVERIFY(d == -qInf());
+
+ u"INF"_s.toLong(&ok);
+ QVERIFY(!ok);
+
+ u"INF"_s.toLong(&ok, 36);
+ QVERIFY(ok);
+
+ u"INF0"_s.toLong(&ok, 36);
+ QVERIFY(ok);
+
+ u"0INF0"_s.toLong(&ok, 36);
+ QVERIFY(ok);
+
+ // Check that inf (float) => "inf" (QString) => inf (float).
+ float value = qInf();
+ QString valueAsString = QString::number(value);
+ QCOMPARE(valueAsString, QString::fromLatin1("inf"));
+ float valueFromString = valueAsString.toFloat();
+ QVERIFY(qIsInf(valueFromString));
+
+ // Check that -inf (float) => "-inf" (QString) => -inf (float).
+ value = -qInf();
+ valueAsString = QString::number(value);
+ QCOMPARE(valueAsString, QString::fromLatin1("-inf"));
+ valueFromString = valueAsString.toFloat();
+ QVERIFY(value == -qInf());
+ QVERIFY(qIsInf(valueFromString));
+
+ // Check that .arg(inf-or-nan, wide, fmt, 3, '0') padds with zeros
+ QString form = QStringLiteral("%1");
+ QCOMPARE(form.arg(qInf(), 5, 'f', 3, u'0'), u"00inf");
+ QCOMPARE(form.arg(qInf(), -5, 'f', 3, u'0'), u"inf00");
+ QCOMPARE(form.arg(-qInf(), 6, 'f', 3, u'0'), u"00-inf");
+ QCOMPARE(form.arg(-qInf(), -6, 'f', 3, u'0'), u"-inf00");
+ QCOMPARE(form.arg(qQNaN(), -5, 'f', 3, u'0'), u"nan00");
+ QCOMPARE(form.arg(qInf(), 5, 'F', 3, u'0'), u"00INF");
+ QCOMPARE(form.arg(qInf(), -5, 'F', 3, u'0'), u"INF00");
+ QCOMPARE(form.arg(-qInf(), 6, 'F', 3, u'0'), u"00-INF");
+ QCOMPARE(form.arg(-qInf(), -6, 'F', 3, u'0'), u"-INF00");
+ QCOMPARE(form.arg(qQNaN(), -5, 'F', 3, u'0'), u"NAN00");
+ QCOMPARE(form.arg(qInf(), 5, 'e', 3, u'0'), u"00inf");
+ QCOMPARE(form.arg(qInf(), -5, 'e', 3, u'0'), u"inf00");
+ QCOMPARE(form.arg(-qInf(), 6, 'e', 3, u'0'), u"00-inf");
+ QCOMPARE(form.arg(-qInf(), -6, 'e', 3, u'0'), u"-inf00");
+ QCOMPARE(form.arg(qQNaN(), -5, 'e', 3, u'0'), u"nan00");
+ QCOMPARE(form.arg(qInf(), 5, 'E', 3, u'0'), u"00INF");
+ QCOMPARE(form.arg(qInf(), -5, 'E', 3, u'0'), u"INF00");
+ QCOMPARE(form.arg(-qInf(), 6, 'E', 3, u'0'), u"00-INF");
+ QCOMPARE(form.arg(-qInf(), -6, 'E', 3, u'0'), u"-INF00");
+ QCOMPARE(form.arg(qQNaN(), -5, 'E', 3, u'0'), u"NAN00");
+ QCOMPARE(form.arg(qInf(), 5, 'g', 3, u'0'), u"00inf");
+ QCOMPARE(form.arg(qInf(), -5, 'g', 3, u'0'), u"inf00");
+ QCOMPARE(form.arg(-qInf(), 6, 'g', 3, u'0'), u"00-inf");
+ QCOMPARE(form.arg(-qInf(), -6, 'g', 3, u'0'), u"-inf00");
+ QCOMPARE(form.arg(qQNaN(), -5, 'g', 3, u'0'), u"nan00");
+ QCOMPARE(form.arg(qInf(), 5, 'G', 3, u'0'), u"00INF");
+ QCOMPARE(form.arg(qInf(), -5, 'G', 3, u'0'), u"INF00");
+ QCOMPARE(form.arg(-qInf(), 6, 'G', 3, u'0'), u"00-INF");
+ QCOMPARE(form.arg(-qInf(), -6, 'G', 3, u'0'), u"-INF00");
+ QCOMPARE(form.arg(qQNaN(), -5, 'G', 3, u'0'), u"NAN00");
+}
+
+void tst_QString::arg_fillChar_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QList<QVariant> >("replaceValues");
+ QTest::addColumn<IntList>("widths");
+ QTest::addColumn<QString>("fillChars");
+ QTest::addColumn<QString>("expected");
+
+ using DataList = QList<QVariant>;
+
+ QTest::newRow("str0")
+ << QStringLiteral("%1%2%3")
+ << DataList{QVariant(int(5)), QVariant(u"f"_s), QVariant(int(0))}
+ << IntList{3, 2, 5} << u"abc"_s << u"aa5bfcccc0"_s;
+
+ QTest::newRow("str1")
+ << QStringLiteral("%3.%1.%3.%2")
+ << DataList{QVariant(int(5)), QVariant(u"foo"_s), QVariant(qulonglong(INT_MAX))}
+ << IntList{10, 2, 5} << u"0 c"_s << u"2147483647.0000000005.2147483647.foo"_s;
+
+ QTest::newRow("str2")
+ << QStringLiteral("%9 og poteter")
+ << DataList{QVariant(u"fisk"_s)} << IntList{100} << u"f"_s
+ << u"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffisk og poteter"_s;
+
+ // Left-padding with zeros fits them before the minus sign:
+ QTest::newRow("zero-left")
+ << QStringLiteral("%1 %2 %3 %4 %5 %6")
+ << DataList{QVariant(-314.0), QVariant(-3.14e8), QVariant(-3.14e12),
+ QVariant(-.0314), QVariant(-3.14e-7), QVariant(-3.14e-13)}
+ << IntList{6, 11, 11, 9, 11, 11} << QStringLiteral("000000")
+ << QStringLiteral("-00314 -003.14e+08 -003.14e+12 -000.0314 -003.14e-07 -003.14e-13");
+
+ // Right-padding with zeros is not so sensible:
+ QTest::newRow("zero-right")
+ << QStringLiteral("%1 %2 %3 %4 %5 %6")
+ << DataList{QVariant(-314.0), QVariant(-3.14e8), QVariant(-3.14e12),
+ QVariant(-.0314), QVariant(-3.14e-7), QVariant(-3.14e-13)}
+ << IntList{-6, -11, -11, -9, -11, -11} << QStringLiteral("000000")
+ << QStringLiteral("-31400 -3.14e+0800 -3.14e+1200 -0.031400 -3.14e-0700 -3.14e-1300");
+}
+
+void tst_QString::arg_fillChar()
+{
+ static const int base = 10;
+ static const char fmt = 'g';
+ static const int prec = -1;
+
+ QFETCH(QString, pattern);
+ QFETCH(QList<QVariant>, replaceValues);
+ QFETCH(IntList, widths);
+ QFETCH(QString, fillChars);
+ QFETCH(QString, expected);
+ QCOMPARE(replaceValues.size(), fillChars.size());
+ QCOMPARE(replaceValues.size(), widths.size());
+
+ QString actual = pattern;
+ for (int i=0; i<replaceValues.size(); ++i) {
+ const QVariant &var = replaceValues.at(i);
+ const int width = widths.at(i);
+ const QChar fillChar = fillChars.at(i);
+ switch (var.typeId()) {
+ case QMetaType::QString:
+ actual = actual.arg(var.toString(), width, fillChar);
+ break;
+ case QMetaType::Int:
+ actual = actual.arg(var.toInt(), width, base, fillChar);
+ break;
+ case QMetaType::UInt:
+ actual = actual.arg(var.toUInt(), width, base, fillChar);
+ break;
+ case QMetaType::Double:
+ actual = actual.arg(var.toDouble(), width, fmt, prec, fillChar);
+ break;
+ case QMetaType::LongLong:
+ actual = actual.arg(var.toLongLong(), width, base, fillChar);
+ break;
+ case QMetaType::ULongLong:
+ actual = actual.arg(var.toULongLong(), width, base, fillChar);
+ break;
+ default:
+ QVERIFY(0);
+ break;
+ }
+ }
+
+ QCOMPARE(actual, expected);
+}
+
+void tst_QString::comparisonCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QString>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, std::nullptr_t>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, QChar>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, QLatin1StringView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, const char16_t *>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, QStringView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, QUtf8StringView>();
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, QByteArrayView>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, QByteArray>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, const char *>();
+#endif
+#ifdef __cpp_char8_t
+ QTestPrivate::testAllComparisonOperatorsCompile<QString, const char8_t *>();
+#endif
+}
+
+void tst_QString::compare_data()
+{
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<QString>("s2");
+ QTest::addColumn<int>("csr"); // case sensitive result
+ QTest::addColumn<int>("cir"); // case insensitive result
+
+ // null strings
+ QTest::newRow("null-null") << QString() << QString() << 0 << 0;
+ QTest::newRow("text-null") << u"a"_s << QString() << 1 << 1;
+ QTest::newRow("null-text") << QString() << u"a"_s << -1 << -1;
+ QTest::newRow("null-empty") << QString() << u""_s << 0 << 0;
+ QTest::newRow("empty-null") << u""_s << QString() << 0 << 0;
+
+ // empty strings
+ QTest::newRow("data0") << u""_s << u""_s << 0 << 0;
+ QTest::newRow("data1") << u"a"_s << u""_s << 1 << 1;
+ QTest::newRow("data2") << u""_s << u"a"_s << -1 << -1;
+
+ // equal length
+ QTest::newRow("data3") << u"abc"_s << u"abc"_s << 0 << 0;
+ QTest::newRow("data4") << u"abC"_s << u"abc"_s << -1 << 0;
+ QTest::newRow("data5") << u"abc"_s << u"abC"_s << 1 << 0;
+
+ // different length
+ QTest::newRow("data6") << u"abcdef"_s << u"abc"_s << 1 << 1;
+ QTest::newRow("data7") << u"abCdef"_s << u"abc"_s << -1 << 1;
+ QTest::newRow("data8") << u"abc"_s << u"abcdef"_s << -1 << -1;
+
+ QString upper;
+ upper += QChar(QChar::highSurrogate(0x10400));
+ upper += QChar(QChar::lowSurrogate(0x10400));
+ QString lower;
+ lower += QChar(QChar::highSurrogate(0x10428));
+ lower += QChar(QChar::lowSurrogate(0x10428));
+ QTest::newRow("data9") << upper << lower << -1 << 0;
+
+ // embedded nulls
+ QLatin1String onenull("", 1);
+ QTest::newRow("data10") << QString(onenull) << QString(onenull) << 0 << 0;
+ QTest::newRow("data11") << QString(onenull) << u""_s << 1 << 1;
+ QTest::newRow("data12") << u""_s << QString(onenull) << -1 << -1;
+ QTest::newRow("data13") << QString::fromLatin1("ab\0c", 4) << QString(QLatin1String("ab\0c", 4)) << 0 << 0;
+ QTest::newRow("data14") << QString(QLatin1String("ab\0c", 4)) << u"abc"_s << -1 << -1;
+ QTest::newRow("data15") << u"abc"_s << QString(QLatin1String("ab\0c", 4)) << 1 << 1;
+ QTest::newRow("data16") << u"abc"_s << QString(QLatin1String("abc", 4)) << -1 << -1;
+
+ // All tests below (generated by the 3 for-loops) are meant to exercise the vectorized versions
+ // of ucstrncmp.
+
+ QString in1, in2;
+ for (int i = 0; i < 70; ++i) {
+ in1 += QString::number(i % 10);
+ in2 += QString::number((70 - i + 1) % 10);
+ }
+ Q_ASSERT(in1.size() == in2.size());
+ Q_ASSERT(in1 != in2);
+ Q_ASSERT(in1.at(0) < in2.at(0));
+ for (int i = 0; i < in1.size(); ++i) {
+ Q_ASSERT(in1.at(i) != in2.at(i));
+ }
+
+ for (int i = 1; i <= 65; ++i) {
+ QString inp1 = in1.left(i);
+ QString inp2 = in2.left(i);
+ QTest::addRow("all-different-%d", i) << inp1 << inp2 << -1 << -1;
+ }
+
+ for (int i = 1; i <= 65; ++i) {
+ QString start(i - 1, u'a');
+
+ QString in = start + QLatin1Char('a');
+ QTest::addRow("all-same-%d", i) << in << in << 0 << 0;
+
+ QString in2 = start + QLatin1Char('b');
+ QTest::addRow("last-different-%d", i) << in << in2 << -1 << -1;
+ }
+
+ for (int i = 0; i < 16; ++i) {
+ QString in1(16, u'a');
+ QString in2 = in1;
+ in2[i] = u'b';
+ QTest::addRow("all-same-except-char-%d", i) << in1 << in2 << -1 << -1;
+ }
+
+ // some non-US-ASCII comparisons
+ QChar smallA = u'a';
+ QChar smallAWithAcute = u'á';
+ QChar capitalAWithAcute = u'Á';
+ QChar nbsp = u'\u00a0';
+ for (int i = 1; i <= 65; ++i) {
+ QString padding(i - 1, u' ');
+ QTest::addRow("ascii-nonascii-%d", i)
+ << (padding + smallA) << (padding + smallAWithAcute) << -1 << -1;
+ QTest::addRow("nonascii-nonascii-equal-%d", i)
+ << (padding + smallAWithAcute) << (padding + smallAWithAcute) << 0 << 0;
+ QTest::addRow("nonascii-nonascii-caseequal-%d", i)
+ << (padding + capitalAWithAcute) << (padding + smallAWithAcute) << -1 << 0;
+ QTest::addRow("nonascii-nonascii-notequal-%d", i)
+ << (padding + nbsp) << (padding + smallAWithAcute) << -1 << -1;
+ }
+}
+
+static bool isLatin(const QString &s)
+{
+ for (int i = 0; i < s.size(); ++i)
+ if (s.at(i).unicode() > 0xff)
+ return false;
+ return true;
+}
+
+static inline int sign(int x)
+{
+ return x == 0 ? 0 : (x < 0 ? -1 : 1);
+}
+
+void tst_QString::compare()
+{
+ QFETCH(QString, s1);
+ QFETCH(QString, s2);
+ QFETCH(int, csr);
+ QFETCH(int, cir);
+
+ QByteArray s1_8 = s1.toUtf8();
+ QByteArray s2_8 = s2.toUtf8();
+ QByteArray s1_1 = s1.toLatin1();
+ QByteArray s2_1 = s2.toLatin1();
+ QLatin1String l1s1(s1_1);
+ QLatin1String l1s2(s2_1);
+
+ const QStringView v1(s1);
+ const QStringView v2(s2);
+
+ QCOMPARE(sign(QString::compare(s1, s2)), csr);
+ QCOMPARE(sign(s1.compare(s2)), csr);
+ QCOMPARE(sign(s1.compare(v2)), csr);
+
+ QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr);
+ QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir);
+ QCOMPARE(sign(s1.compare(v2, Qt::CaseSensitive)), csr);
+ QCOMPARE(sign(s1.compare(v2, Qt::CaseInsensitive)), cir);
+ QCOMPARE(sign(QtPrivate::compareStrings(QUtf8StringView(s1_8), v2, Qt::CaseSensitive)), csr);
+ QCOMPARE(sign(QtPrivate::compareStrings(QUtf8StringView(s1_8), v2, Qt::CaseInsensitive)), cir);
+ QCOMPARE(sign(QtPrivate::compareStrings(QUtf8StringView(s2_8), v1, Qt::CaseSensitive)), -csr);
+ QCOMPARE(sign(QtPrivate::compareStrings(QUtf8StringView(s2_8), v1, Qt::CaseInsensitive)), -cir);
+
+ QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr);
+ QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir);
+
+ if (csr == 0) {
+ QVERIFY(qHash(s1) == qHash(s2));
+ QVERIFY(s1 == s2);
+ QVERIFY(!(s1 != s2));
+ } else {
+ QVERIFY(s1 != s2);
+ QVERIFY(!(s1 == s2));
+ }
+
+ if (!cir)
+ QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded());
+
+ if (isLatin(s2)) {
+ QVERIFY(QtPrivate::isLatin1(s2));
+ QCOMPARE(sign(QString::compare(s1, l1s2)), csr);
+ QCOMPARE(sign(QString::compare(s1, l1s2, Qt::CaseInsensitive)), cir);
+
+ // ensure it doesn't compare past the explicit size
+ QByteArray l1 = s2.toLatin1();
+ l1 += "x";
+ QLatin1String l1str(l1.constData(), l1.size() - 1);
+ QCOMPARE(sign(QString::compare(s1, l1str)), csr);
+ QCOMPARE(sign(QString::compare(s1, l1str, Qt::CaseInsensitive)), cir);
+ }
+
+ if (isLatin(s1)) {
+ QVERIFY(QtPrivate::isLatin1(s1));
+ QCOMPARE(sign(QString::compare(l1s1, s2)), csr);
+ QCOMPARE(sign(QString::compare(l1s1, s2, Qt::CaseInsensitive)), cir);
+ }
+
+ if (isLatin(s1) && isLatin(s2)) {
+ QCOMPARE(sign(QtPrivate::compareStrings(l1s1, l1s2)), csr);
+ QCOMPARE(sign(QtPrivate::compareStrings(l1s1, l1s2, Qt::CaseInsensitive)), cir);
+ QCOMPARE(l1s1 == l1s2, csr == 0);
+ QCOMPARE(l1s1 < l1s2, csr < 0);
+ QCOMPARE(l1s1 > l1s2, csr > 0);
+ }
+}
+
+void tst_QString::comparisonMacros_data()
+{
+ compare_data();
+}
+
+void tst_QString::comparisonMacros()
+{
+ QFETCH(const QString, s1);
+ QFETCH(const QString, s2);
+ QFETCH(int, csr);
+
+ const Qt::strong_ordering expectedOrdering = [&csr] {
+ if (csr > 0)
+ return Qt::strong_ordering::greater;
+ else if (csr < 0)
+ return Qt::strong_ordering::less;
+ return Qt::strong_ordering::equal;
+ }();
+
+ QT_TEST_ALL_COMPARISON_OPS(s1, s2, expectedOrdering);
+
+ const QStringView s2sv(s2);
+ QT_TEST_ALL_COMPARISON_OPS(s1, s2sv, expectedOrdering);
+
+ if (!s2.contains(QChar(u'\0'))) {
+ const char16_t *utfData = reinterpret_cast<const char16_t*>(s2.constData());
+ QT_TEST_ALL_COMPARISON_OPS(s1, utfData, expectedOrdering);
+ }
+
+ if (s2.size() == 1) {
+ const QChar ch = s2.front();
+ QT_TEST_ALL_COMPARISON_OPS(s1, ch, expectedOrdering);
+ }
+
+ if (isLatin(s2)) {
+ QByteArray ba = s2.toLatin1();
+ const QLatin1StringView l1s2{ba};
+ QT_TEST_ALL_COMPARISON_OPS(s1, l1s2, expectedOrdering);
+ }
+
+ const QByteArray u8s2 = s2.toUtf8();
+
+ const QUtf8StringView u8s2sv(u8s2.data(), u8s2.size());
+ QT_TEST_ALL_COMPARISON_OPS(s1, u8s2sv, expectedOrdering);
+
+#ifdef __cpp_char8_t
+ if (!s2.contains(QChar(u'\0'))) {
+ const char8_t *char8data = reinterpret_cast<const char8_t*>(u8s2.constData());
+ QT_TEST_ALL_COMPARISON_OPS(s1, char8data, expectedOrdering);
+ }
+#endif // __cpp_char8_t
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+ QT_TEST_ALL_COMPARISON_OPS(s1, u8s2, expectedOrdering);
+ const QByteArrayView u8s2view{u8s2.begin(), u8s2.size()};
+ QT_TEST_ALL_COMPARISON_OPS(s1, u8s2view, expectedOrdering);
+ if (!s2.contains(QChar(u'\0'))) {
+ const char *u8data = u8s2.constData();
+ QT_TEST_ALL_COMPARISON_OPS(s1, u8data, expectedOrdering);
+ }
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+}
+
+void tst_QString::resize()
+{
+ QString s;
+ s.resize(11, u' ');
+ QCOMPARE(s.size(), 11);
+ QCOMPARE(s, QLatin1String(" "));
+
+ s = QLatin1String("hello world");
+
+ s.resize(5);
+ QCOMPARE(s, QLatin1String("hello"));
+ s.resize(8);
+ QCOMPARE(s.size(), 8);
+ QVERIFY(s.startsWith(QLatin1String("hello")));
+
+ s.resize(10, QLatin1Char('n'));
+ QCOMPARE(s.size(), 10);
+ QVERIFY(s.startsWith(QLatin1String("hello")));
+ QCOMPARE(s.right(2), QLatin1String("nn"));
+}
+
+void tst_QString::resizeAfterFromRawData()
+{
+ QString buffer(u"hello world"_s);
+
+ QString array = QString::fromRawData(buffer.constData(), buffer.size());
+ QVERIFY(array.constData() == buffer.constData());
+ array.resize(5);
+ QVERIFY(array.constData() != buffer.constData());
+ // check null termination
+ QVERIFY(array.constData()[5] == 0);
+}
+
+void tst_QString::resizeAfterReserve()
+{
+
+ QString s;
+ s.reserve(100);
+
+ s += u"hello world"_s;
+
+ // resize should not affect capacity
+ s.resize(s.size());
+ QVERIFY(s.capacity() == 100);
+
+ // but squeeze does
+ s.squeeze();
+ QVERIFY(s.capacity() == s.size());
+
+ // clear does too
+ s.clear();
+ QVERIFY(s.capacity() == 0);
+
+ // test resize(0) border case
+ s.reserve(100);
+ s += u"hello world"_s;
+ s.resize(0);
+ QVERIFY(s.capacity() == 100);
+
+ // reserve() can't be used to truncate data
+ s.fill(u'x', 100);
+ s.reserve(50);
+ QVERIFY(s.capacity() == 100);
+ QVERIFY(s.size() == 100);
+
+ // even with increased ref count truncation isn't allowed
+ QString t = s;
+ s.reserve(50);
+ QVERIFY(s.capacity() == 100);
+ QVERIFY(s.size() == 100);
+}
+
+void tst_QString::resizeWithNegative() const
+{
+ {
+ QString string(QLatin1String("input"));
+ string.resize(-1);
+ QCOMPARE(string, QString());
+ }
+
+ {
+ QString string(QLatin1String("input"));
+ string.resize(-9099);
+ QCOMPARE(string, QString());
+ }
+
+ {
+ /* Example code from customer. */
+ QString s(QLatin1String("hola"));
+ s.reserve(1);
+ s.resize(-1);
+ QCOMPARE(s, QString());
+ }
+}
+
+void tst_QString::truncateWithNegative() const
+{
+ {
+ QString string(QLatin1String("input"));
+ string.truncate(-1);
+ QCOMPARE(string, QString());
+ }
+
+ {
+ QString string(QLatin1String("input"));
+ string.truncate(-9099);
+ QCOMPARE(string, QString());
+ }
+}
+
+void tst_QString::QCharRefMutableUnicode() const
+{
+ QString str;
+ str.resize(3);
+ str[0].unicode() = 115;
+ str[1].unicode() = 116;
+ str[2].unicode() = 114;
+
+ QCOMPARE(str, QString::fromLatin1("str"));
+}
+
+void tst_QString::QCharRefDetaching() const
+{
+ {
+ QString str = QString::fromLatin1("str");
+ QString copy = str;
+ copy[0] = QLatin1Char('S');
+
+ QCOMPARE(str, QString::fromLatin1("str"));
+ }
+
+ {
+ ushort buf[] = { 's', 't', 'r' };
+ QString str = QString::fromRawData((const QChar *)buf, 3);
+ str[0] = QLatin1Char('S');
+
+ QCOMPARE(buf[0], ushort('s'));
+ }
+
+ {
+ static const ushort buf[] = { 's', 't', 'r' };
+ QString str = QString::fromRawData((const QChar *)buf, 3);
+
+ // this causes a crash in most systems if the detaching doesn't work
+ str[0] = QLatin1Char('S');
+
+ QCOMPARE(buf[0], ushort('s'));
+ }
+}
+
+void tst_QString::repeatedSignature() const
+{
+ /* repated() should be a const member. */
+ const QString string;
+ (void) string.repeated(3);
+}
+
+void tst_QString::repeated() const
+{
+ QFETCH(QString, string);
+ QFETCH(QString, expected);
+ QFETCH(int, count);
+
+ QCOMPARE(string.repeated(count), expected);
+}
+
+void tst_QString::repeated_data() const
+{
+ QTest::addColumn<QString>("string" );
+ QTest::addColumn<QString>("expected" );
+ QTest::addColumn<int>("count" );
+
+ /* Empty strings. */
+ QTest::newRow("data1")
+ << QString()
+ << QString()
+ << 0;
+
+ QTest::newRow("data2")
+ << QString()
+ << QString()
+ << -1004;
+
+ QTest::newRow("data3")
+ << QString()
+ << QString()
+ << 1;
+
+ QTest::newRow("data4")
+ << QString()
+ << QString()
+ << 5;
+
+ /* On simple string. */
+ QTest::newRow("data5")
+ << QString(QLatin1String("abc"))
+ << QString()
+ << -1004;
+
+ QTest::newRow("data6")
+ << QString(QLatin1String("abc"))
+ << QString()
+ << -1;
+
+ QTest::newRow("data7")
+ << QString(QLatin1String("abc"))
+ << QString()
+ << 0;
+
+ QTest::newRow("data8")
+ << QString(QLatin1String("abc"))
+ << QString(QLatin1String("abc"))
+ << 1;
+
+ QTest::newRow("data9")
+ << QString(QLatin1String("abc"))
+ << QString(QLatin1String("abcabc"))
+ << 2;
+
+ QTest::newRow("data10")
+ << QString(QLatin1String("abc"))
+ << QString(QLatin1String("abcabcabc"))
+ << 3;
+
+ QTest::newRow("data11")
+ << QString(QLatin1String("abc"))
+ << QString(QLatin1String("abcabcabcabc"))
+ << 4;
+}
+
+void tst_QString::arg_locale()
+{
+ QLocale l(QLocale::English, QLocale::UnitedKingdom);
+ QString str(u"*%L1*%L2*"_s);
+
+ TransientDefaultLocale transient(l);
+ QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123,456*1,234.56*"));
+
+ l.setNumberOptions(QLocale::OmitGroupSeparator);
+ transient.revise(l);
+ QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*"));
+
+ transient.revise(QLocale::C);
+ QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*"));
+}
+
+
+#if QT_CONFIG(icu)
+// Qt has to be built with ICU support
+void tst_QString::toUpperLower_icu()
+{
+ QString s = QString::fromLatin1("i");
+
+ QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
+ QCOMPARE(s.toLower(), QString::fromLatin1("i"));
+
+ TransientDefaultLocale transient(QLocale(QLocale::Turkish, QLocale::Turkey));
+
+ QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
+ QCOMPARE(s.toLower(), QString::fromLatin1("i"));
+
+ // turkish locale has a capital I with a dot (U+0130, utf8 c4b0)
+ QLocale l;
+
+ QCOMPARE(l.toUpper(s), QString::fromUtf8("\xc4\xb0"));
+ QCOMPARE(l.toLower(QString::fromUtf8("\xc4\xb0")), s);
+
+ // nothing should happen here
+ QCOMPARE(l.toLower(s), s);
+ QCOMPARE(l.toUpper(QString::fromLatin1("I")), QString::fromLatin1("I"));
+
+ // U+0131, utf8 c4b1 is the lower-case i without a dot
+ QString sup = QString::fromUtf8("\xc4\xb1");
+
+ QCOMPARE(l.toUpper(sup), QString::fromLatin1("I"));
+ QCOMPARE(l.toLower(QString::fromLatin1("I")), sup);
+
+ // nothing should happen here
+ QCOMPARE(l.toLower(sup), sup);
+ QCOMPARE(l.toLower(QString::fromLatin1("i")), QString::fromLatin1("i"));
+}
+#endif // icu
+
+void tst_QString::literals()
+{
+ QString str(QStringLiteral("abcd"));
+
+ QVERIFY(str.size() == 4);
+ QCOMPARE(str.capacity(), 0);
+ QVERIFY(str == QLatin1String("abcd"));
+ QVERIFY(!str.data_ptr()->isMutable());
+
+ const QChar *s = str.constData();
+ QString str2 = str;
+ QVERIFY(str2.constData() == s);
+ QCOMPARE(str2.capacity(), 0);
+
+ // detach on non const access
+ QVERIFY(str.data() != s);
+ QVERIFY(str.capacity() >= str.size());
+
+ QVERIFY(str2.constData() == s);
+ QVERIFY(str2.data() != s);
+ QVERIFY(str2.capacity() >= str2.size());
+}
+
+void tst_QString::userDefinedLiterals()
+{
+ {
+ using namespace Qt::StringLiterals;
+ QString str = u"abcd"_s;
+
+ QVERIFY(str.size() == 4);
+ QCOMPARE(str.capacity(), 0);
+ QVERIFY(str == QLatin1String("abcd"));
+ QVERIFY(!str.data_ptr()->isMutable());
+
+ const QChar *s = str.constData();
+ QString str2 = str;
+ QVERIFY(str2.constData() == s);
+ QCOMPARE(str2.capacity(), 0);
+
+ // detach on non const access
+ QVERIFY(str.data() != s);
+ QVERIFY(str.capacity() >= str.size());
+
+ QVERIFY(str2.constData() == s);
+ QVERIFY(str2.data() != s);
+ QVERIFY(str2.capacity() >= str2.size());
+ }
+
+#if QT_DEPRECATED_SINCE(6, 8)
+ {
+ QT_IGNORE_DEPRECATIONS(QString str = u"abcd"_qs;)
+
+ QVERIFY(str.size() == 4);
+ QCOMPARE(str.capacity(), 0);
+ QVERIFY(str == QLatin1String("abcd"));
+ QVERIFY(!str.data_ptr()->isMutable());
+
+ const QChar *s = str.constData();
+ QString str2 = str;
+ QVERIFY(str2.constData() == s);
+ QCOMPARE(str2.capacity(), 0);
+
+ // detach on non const access
+ QVERIFY(str.data() != s);
+ QVERIFY(str.capacity() >= str.size());
+
+ QVERIFY(str2.constData() == s);
+ QVERIFY(str2.data() != s);
+ QVERIFY(str2.capacity() >= str2.size());
+ }
+#endif // QT_DEPRECATED_SINCE(6, 8)
+}
+
+#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+void tst_QString::eightBitLiterals_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("stringData");
+
+ QTest::newRow("null") << QByteArray() << QString();
+ QTest::newRow("empty") << QByteArray("") << QString("");
+ QTest::newRow("regular") << QByteArray("foo") << "foo";
+ QTest::newRow("non-ascii") << QByteArray("\xc3\xa9") << QString::fromLatin1("\xe9");
+}
+
+void tst_QString::eightBitLiterals()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, stringData);
+
+ {
+ QString s(data);
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s(data.constData());
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s = data;
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s = data.constData();
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s.append(data);
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s.append(data.constData());
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s += data;
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s += data.constData();
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s.prepend(data);
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s;
+ s.prepend(data.constData());
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s = QString() + data;
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s = QString() + data.constData();
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s = data + QString();
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s = QString() % data;
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s = QString() % data.constData();
+ QCOMPARE(s, stringData);
+ }
+ {
+ QString s = data % QString();
+ QCOMPARE(s, stringData);
+ }
+
+ {
+ QVERIFY(stringData == data);
+ QVERIFY(stringData == data.constData());
+ QVERIFY(!(stringData != data));
+ QVERIFY(!(stringData != data.constData()));
+ QVERIFY(!(stringData < data));
+ QVERIFY(!(stringData < data.constData()));
+ QVERIFY(!(stringData > data));
+ QVERIFY(!(stringData > data.constData()));
+ QVERIFY(stringData <= data);
+ QVERIFY(stringData <= data.constData());
+ QVERIFY(stringData >= data);
+ QVERIFY(stringData >= data.constData());
+ }
+}
+#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
+
+void tst_QString::reserve()
+{
+ QString nil1, nil2;
+ nil1.reserve(0);
+ nil2.squeeze();
+ nil1.squeeze();
+ nil2.reserve(0);
+ QVERIFY(!nil1.isDetached());
+ QVERIFY(!nil2.isDetached());
+}
+
+void tst_QString::toHtmlEscaped_data()
+{
+ QTest::addColumn<QString>("original");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("null") << QString() << QString();
+ QTest::newRow("empty") << u""_s << u""_s;
+ QTest::newRow("1") << "Hello World\n" << "Hello World\n";
+ QTest::newRow("2") << "#include <QtCore>" << "#include &lt;QtCore&gt;";
+ QTest::newRow("3") << "<p class=\"cool\"><a href=\"http://example.com/?foo=bar&amp;bar=foo\">plop --&gt; </a></p>"
+ << "&lt;p class=&quot;cool&quot;&gt;&lt;a href=&quot;http://example.com/?foo=bar&amp;amp;bar=foo&quot;&gt;plop --&amp;gt; &lt;/a&gt;&lt;/p&gt;";
+ QTest::newRow("4") << QString::fromUtf8("<\320\222\321\201>") << QString::fromUtf8("&lt;\320\222\321\201&gt;");
+}
+
+void tst_QString::toHtmlEscaped()
+{
+ QFETCH(QString, original);
+ QFETCH(QString, expected);
+
+ QCOMPARE(original.toHtmlEscaped(), expected);
+}
+
+void tst_QString::operatorGreaterWithQLatin1String()
+{
+ QLatin1String latin1foo("fooZZ", 3);
+ QString stringfoo = QString::fromLatin1("foo");
+ QVERIFY(stringfoo >= latin1foo);
+ QVERIFY(!(stringfoo > latin1foo));
+ QVERIFY(stringfoo <= latin1foo);
+ QVERIFY(!(stringfoo < latin1foo));
+}
+
+void tst_QString::compareQLatin1Strings()
+{
+ QLatin1String abc("abc");
+ QLatin1String abcd("abcd");
+ QLatin1String cba("cba");
+ QLatin1String de("de");
+
+ QVERIFY(abc == abc);
+ QVERIFY(!(abc == cba));
+ QVERIFY(!(cba == abc));
+ QVERIFY(!(abc == abcd));
+ QVERIFY(!(abcd == abc));
+
+ QVERIFY(abc != cba);
+ QVERIFY(!(abc != abc));
+ QVERIFY(cba != abc);
+ QVERIFY(abc != abcd);
+ QVERIFY(abcd != abc);
+
+ QVERIFY(abc < abcd);
+ QVERIFY(abc < cba);
+ QVERIFY(abc < de);
+ QVERIFY(abcd < cba);
+ QVERIFY(!(abc < abc));
+ QVERIFY(!(abcd < abc));
+ QVERIFY(!(de < cba));
+
+ QVERIFY(abcd > abc);
+ QVERIFY(cba > abc);
+ QVERIFY(de > abc);
+ QVERIFY(!(abc > abc));
+ QVERIFY(!(abc > abcd));
+ QVERIFY(!(abcd > cba));
+
+ QVERIFY(abc <= abc);
+ QVERIFY(abc <= abcd);
+ QVERIFY(abc <= cba);
+ QVERIFY(abc <= de);
+ QVERIFY(!(abcd <= abc));
+ QVERIFY(!(cba <= abc));
+ QVERIFY(!(cba <= abcd));
+ QVERIFY(!(de <= abc));
+
+ QVERIFY(abc >= abc);
+ QVERIFY(abcd >= abc);
+ QVERIFY(!(abc >= abcd));
+ QVERIFY(cba >= abc);
+ QVERIFY(!(abc >= cba));
+ QVERIFY(de >= abc);
+ QVERIFY(!(abc >= de));
+
+ QLatin1String subfoo("fooZZ", 3);
+ QLatin1String foo("foo");
+ QVERIFY(subfoo == foo);
+ QVERIFY(foo == subfoo);
+ QVERIFY(!(subfoo != foo));
+ QVERIFY(!(foo != subfoo));
+ QVERIFY(!(foo < subfoo));
+ QVERIFY(!(subfoo < foo));
+ QVERIFY(foo >= subfoo);
+ QVERIFY(subfoo >= foo);
+ QVERIFY(!(foo > subfoo));
+ QVERIFY(!(subfoo > foo));
+ QVERIFY(foo <= subfoo);
+ QVERIFY(subfoo <= foo);
+
+ QLatin1String subabc("abcZZ", 3);
+ QLatin1String subab("abcZZ", 2);
+ QVERIFY(subabc != subab);
+ QVERIFY(subab != subabc);
+ QVERIFY(!(subabc == subab));
+ QVERIFY(!(subab == subabc));
+ QVERIFY(subab < subabc);
+ QVERIFY(!(subabc < subab));
+ QVERIFY(subabc > subab);
+ QVERIFY(!(subab > subabc));
+ QVERIFY(subab <= subabc);
+ QVERIFY(!(subabc <= subab));
+ QVERIFY(subabc >= subab);
+ QVERIFY(!(subab >= subabc));
+}
+
+void tst_QString::fromQLatin1StringWithLength()
+{
+ QLatin1String latin1foo("foobar", 3);
+ QString foo(latin1foo);
+ QCOMPARE(foo.size(), latin1foo.size());
+ QCOMPARE(foo, QString::fromLatin1("foo"));
+}
+
+void tst_QString::assignQLatin1String()
+{
+ QString empty = QLatin1String("");
+ QVERIFY(empty.isEmpty());
+ QVERIFY(!empty.isNull());
+
+ QString null = QLatin1String(nullptr);
+ QVERIFY(null.isEmpty());
+ QVERIFY(null.isNull());
+
+ QLatin1String latin1foo("foo");
+ QString foo = latin1foo;
+ QCOMPARE(foo.size(), latin1foo.size());
+ QCOMPARE(foo, QString::fromLatin1("foo"));
+
+ QLatin1String latin1subfoo("foobar", 3);
+ foo = latin1subfoo;
+ QCOMPARE(foo.size(), latin1subfoo.size());
+ QCOMPARE(foo, QString::fromLatin1("foo"));
+
+ // check capacity re-use:
+ QString s;
+ QCOMPARE(s.capacity(), 0);
+
+ // assign to null QString:
+ s = latin1foo;
+ QCOMPARE(s, QString::fromLatin1("foo"));
+ QCOMPARE(s.capacity(), 3);
+
+ // assign to non-null QString with enough capacity:
+ s = QString::fromLatin1("foofoo");
+ const int capacity = s.capacity();
+ s = latin1foo;
+ QCOMPARE(s, QString::fromLatin1("foo"));
+ QCOMPARE(s.capacity(), capacity);
+
+ // assign to shared QString (enough capacity, but can't use):
+ s = QString::fromLatin1("foofoo");
+ QString s2 = s;
+ s = latin1foo;
+ QCOMPARE(s, QString::fromLatin1("foo"));
+ QCOMPARE(s.capacity(), 3);
+
+ // assign to QString with too little capacity:
+ s = QString::fromLatin1("fo");
+ QCOMPARE(s.capacity(), 2);
+ s = latin1foo;
+ QCOMPARE(s, QString::fromLatin1("foo"));
+ QCOMPARE(s.capacity(), 3);
+
+}
+
+void tst_QString::assignQChar()
+{
+ const QChar sp = QLatin1Char(' ');
+ QString s;
+ QCOMPARE(s.capacity(), 0);
+
+ // assign to null QString:
+ s = sp;
+ QCOMPARE(s, QString(sp));
+
+ // assign to non-null QString with enough capacity:
+ s.clear();
+ s.squeeze();
+ s.reserve(3);
+ s = QLatin1String("foo");
+ const int capacity = s.capacity();
+ QCOMPARE(s.capacity(), 3);
+ s = sp;
+ QCOMPARE(s, QString(sp));
+ QCOMPARE(s.capacity(), capacity);
+
+ // assign to shared QString (enough capacity, but can't use):
+ s = QLatin1String("foo");
+ QString s2 = s;
+ s = sp;
+ QCOMPARE(s, QString(sp));
+
+ // assign to empty QString:
+ s = QString(u""_s);
+ s.detach();
+ QCOMPARE(s.capacity(), 0);
+ s = sp;
+ QCOMPARE(s, QString(sp));
+}
+
+void tst_QString::isRightToLeft_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<bool>("rtl");
+
+ QTest::newRow("null") << QString() << false;
+ QTest::newRow("empty") << u""_s << false;
+
+ QTest::newRow("numbers-only") << u"12345"_s << false;
+ QTest::newRow("latin1-only") << u"hello"_s << false;
+ QTest::newRow("numbers-latin1") << (u"12345"_s + u"hello"_s) << false;
+
+ static const char16_t unicode1[] = { 0x627, 0x627 };
+ QTest::newRow("arabic-only") << QString::fromUtf16(unicode1, 2) << true;
+ QTest::newRow("numbers-arabic") << (u"12345"_s + QString::fromUtf16(unicode1, 2)) << true;
+ QTest::newRow("numbers-latin1-arabic") << (u"12345"_s + u"hello"_s + QString::fromUtf16(unicode1, 2)) << false;
+ QTest::newRow("numbers-arabic-latin1") << (u"12345"_s + QString::fromUtf16(unicode1, 2) + u"hello"_s) << true;
+
+ static const char16_t unicode2[] = { QChar::highSurrogate(0xE01DAu), QChar::lowSurrogate(0xE01DAu), QChar::highSurrogate(0x2F800u), QChar::lowSurrogate(0x2F800u) };
+ QTest::newRow("surrogates-VS-CJK") << QString::fromUtf16(unicode2, 4) << false;
+
+ static const char16_t unicode3[] = { QChar::highSurrogate(0x10800u), QChar::lowSurrogate(0x10800u), QChar::highSurrogate(0x10805u), QChar::lowSurrogate(0x10805u) };
+ QTest::newRow("surrogates-cypriot") << QString::fromUtf16(unicode3, 4) << true;
+
+ QTest::newRow("lre") << (u"12345"_s + QChar(0x202a) + u"9"_s + QChar(0x202c)) << false;
+ QTest::newRow("rle") << (u"12345"_s + QChar(0x202b) + u"9"_s + QChar(0x202c)) << false;
+ QTest::newRow("r in lre") << (u"12345"_s + QChar(0x202a) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + u"a"_s) << true;
+ QTest::newRow("l in lre") << (u"12345"_s + QChar(0x202a) + u"a"_s + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
+ QTest::newRow("r in rle") << (u"12345"_s + QChar(0x202b) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + u"a"_s) << true;
+ QTest::newRow("l in rle") << (u"12345"_s + QChar(0x202b) + u"a"_s + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
+
+ QTest::newRow("lro") << (u"12345"_s + QChar(0x202d) + u"9"_s + QChar(0x202c)) << false;
+ QTest::newRow("rlo") << (u"12345"_s + QChar(0x202e) + u"9"_s + QChar(0x202c)) << false;
+ QTest::newRow("r in lro") << (u"12345"_s + QChar(0x202d) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + u"a"_s) << true;
+ QTest::newRow("l in lro") << (u"12345"_s + QChar(0x202d) + u"a"_s + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
+ QTest::newRow("r in rlo") << (u"12345"_s + QChar(0x202e) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + u"a"_s) << true;
+ QTest::newRow("l in rlo") << (u"12345"_s + QChar(0x202e) + u"a"_s + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
+
+ QTest::newRow("lri") << (u"12345"_s + QChar(0x2066) + u"a"_s + QChar(0x2069) + QString::fromUtf16(unicode1, 2)) << true;
+ QTest::newRow("rli") << (u"12345"_s + QChar(0x2067) + QString::fromUtf16(unicode1, 2) + QChar(0x2069) + u"a"_s) << false;
+ QTest::newRow("fsi1") << (u"12345"_s + QChar(0x2068) + u"a"_s + QChar(0x2069) + QString::fromUtf16(unicode1, 2)) << true;
+ QTest::newRow("fsi2") << (u"12345"_s + QChar(0x2068) + QString::fromUtf16(unicode1, 2) + QChar(0x2069) + u"a"_s) << false;
+}
+
+void tst_QString::isRightToLeft()
+{
+ QFETCH(QString, unicode);
+ QFETCH(bool, rtl);
+
+ QCOMPARE(unicode.isRightToLeft(), rtl);
+}
+
+void tst_QString::isValidUtf16_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<bool>("valid");
+
+ int row = 0;
+ QTest::addRow("valid-%02d", row++) << QString() << true;
+ QTest::addRow("valid-%02d", row++) << u""_s << true;
+ QTest::addRow("valid-%02d", row++) << u"abc def"_s << true;
+ QTest::addRow("valid-%02d", row++) << u"àbç"_s << true;
+ QTest::addRow("valid-%02d", row++) << u"ßẞ"_s << true;
+ QTest::addRow("valid-%02d", row++) << u"𝐀𝐁𝐂abc𝐃𝐄𝐅def"_s << true;
+ QTest::addRow("valid-%02d", row++) << u"abc𝐀𝐁𝐂def𝐃𝐄𝐅"_s << true;
+ QTest::addRow("valid-%02d", row++) << QString(u"abc"_s + QChar(0x0000) + u"def"_s) << true;
+ QTest::addRow("valid-%02d", row++) << QString(u"abc"_s + QChar(0xFFFF) + u"def"_s) << true;
+ // check that BOM presence doesn't make any difference
+ QTest::addRow("valid-%02d", row++) << (QString() + QChar(0xFEFF) + u"abc𝐀𝐁𝐂def𝐃𝐄𝐅"_s) << true;
+ QTest::addRow("valid-%02d", row++) << (QString() + QChar(0xFFFE) + u"abc𝐀𝐁𝐂def𝐃𝐄𝐅"_s) << true;
+
+ row = 0;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800)) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + u"abc"_s + QChar(0xD800)) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800) + u"def"_s) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + u"abc"_s + QChar(0xD800) + u"def"_s) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800) + QChar(0xD800)) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + u"abc"_s + QChar(0xD800) + QChar(0xD800)) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + QChar(0xD800) + QChar(0xD800) + u"def"_s) << false;
+ QTest::addRow("stray-high-%02d", row++) << (QString() + u"abc"_s + QChar(0xD800) + QChar(0xD800) + u"def"_s) << false;
+
+ row = 0;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00)) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + u"abc"_s + QChar(0xDC00)) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00) + u"def"_s) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + u"abc"_s + QChar(0xDC00) + u"def"_s) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QChar(0xDC00)) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + u"abc"_s + QChar(0xDC00) + QChar(0xDC00)) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + QChar(0xDC00) + QChar(0xDC00) + u"def"_s) << false;
+ QTest::addRow("stray-low-%02d", row++) << (QString() + u"abc"_s + QChar(0xDC00) + QChar(0xDC00) + u"def"_s) << false;
+}
+
+void tst_QString::isValidUtf16()
+{
+ QFETCH(QString, string);
+ QTEST(string.isValidUtf16(), "valid");
+}
+
+static QString doVasprintf(const char *msg, ...) {
+ va_list args;
+ va_start(args, msg);
+ const QString result = QString::vasprintf(msg, args);
+ va_end(args);
+ return result;
+}
+
+void tst_QString::vasprintfWithPrecision()
+{
+ {
+ const char *msg = "Endpoint %.*s with";
+ static const char arg0[3] = { 'a', 'b', 'c' };
+ static const char arg1[4] = { 'a', 'b', 'c', '\0' };
+ QCOMPARE(doVasprintf(msg, 3, arg0), QStringLiteral("Endpoint abc with"));
+ QCOMPARE(doVasprintf(msg, 9, arg1), QStringLiteral("Endpoint abc with"));
+ QCOMPARE(doVasprintf(msg, 0, nullptr), QStringLiteral("Endpoint with"));
+ }
+
+ {
+ const char *msg = "Endpoint %.*ls with";
+ static const ushort arg0[3] = { 'a', 'b', 'c' };
+ static const ushort arg1[4] = { 'a', 'b', 'c', '\0' };
+ QCOMPARE(doVasprintf(msg, 3, arg0), QStringLiteral("Endpoint abc with"));
+ QCOMPARE(doVasprintf(msg, 9, arg1), QStringLiteral("Endpoint abc with"));
+ QCOMPARE(doVasprintf(msg, 0, nullptr), QStringLiteral("Endpoint with"));
+ }
+}
+
+void tst_QString::rawData()
+{
+ QString s;
+ // it can be nullptr or a pointer to static shared data
+ const QChar *constPtr = s.constData();
+ QCOMPARE(s.unicode(), constPtr); // unicode() is the same as constData()
+ QCOMPARE(s.data(), constPtr); // does not detach() on empty string
+ QCOMPARE(s.utf16(), reinterpret_cast<const ushort *>(constPtr));
+ QVERIFY(!s.isDetached());
+
+ s = QString::fromUtf8("abc"); // detached
+ const QChar *dataConstPtr = s.constData();
+ QVERIFY(dataConstPtr != constPtr);
+
+ const char16_t *char16Ptr = reinterpret_cast<const char16_t *>(s.utf16());
+
+ QString s1 = s;
+ QCOMPARE(s1.constData(), dataConstPtr);
+ QCOMPARE(s1.unicode(), s.unicode());
+
+ QChar *s1Ptr = s1.data(); // detaches here, because the string is not empty
+ QVERIFY(s1Ptr != dataConstPtr);
+ QVERIFY(s1.unicode() != s.unicode());
+
+ *s1Ptr = u'd';
+ QCOMPARE(s1, u"dbc");
+
+ // utf pointer is valid while the string is not changed
+ QCOMPARE(QString::fromUtf16(char16Ptr), s);
+}
+
+void tst_QString::clear()
+{
+ QString s;
+ s.clear();
+ QVERIFY(s.isEmpty());
+ QVERIFY(!s.isDetached());
+
+ s = u"some tests string"_s;
+ QVERIFY(!s.isEmpty());
+
+ s.clear();
+ QVERIFY(s.isEmpty());
+}
+
+void tst_QString::first()
+{
+ QString a;
+
+ QVERIFY(a.first(0).isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a = u"ABCDEFGHIEfGEFG"_s; // 15 chars
+
+ // lvalue
+ QCOMPARE(a.first(5), u"ABCDE");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).first(5), u"ABCDE");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, detached
+ QCOMPARE(detached(a).first(5), u"ABCDE");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+}
+
+void tst_QString::last()
+{
+ QString a;
+
+ QVERIFY(a.last(0).isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a = u"ABCDEFGHIEfGEFG"_s; // 15 chars
+
+ // lvalue
+ QCOMPARE(a.last(10), u"FGHIEfGEFG");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).last(10), u"FGHIEfGEFG");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, detached
+ QCOMPARE(detached(a).last(10), u"FGHIEfGEFG");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+}
+
+void tst_QString::sliced()
+{
+ QString a;
+
+ QVERIFY(a.sliced(0).isEmpty());
+ QVERIFY(a.sliced(0, 0).isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a = u"ABCDEFGHIEfGEFG"_s; // 15 chars
+
+ // lvalue
+ QCOMPARE(a.sliced(5), u"FGHIEfGEFG");
+ QCOMPARE(a.sliced(5, 3), u"FGH");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).sliced(5), u"FGHIEfGEFG");
+ QCOMPARE(QString(a).sliced(5, 3), u"FGH");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, detached
+ QCOMPARE(detached(a).sliced(5), u"FGHIEfGEFG");
+ QCOMPARE(detached(a).sliced(5, 3), u"FGH");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+}
+
+void tst_QString::slice()
+{
+ QString a;
+
+ a.slice(0);
+ QVERIFY(a.isEmpty());
+ QVERIFY(a.isNull());
+ a.slice(0, 0);
+ QVERIFY(a.isEmpty());
+ QVERIFY(a.isNull());
+
+ a = u"Five pineapples"_s;
+
+ a.slice(5);
+ QCOMPARE_EQ(a, u"pineapples");
+
+ a.slice(4, 3);
+ QCOMPARE_EQ(a, u"app");
+
+ a.slice(a.size());
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QString::chopped()
+{
+ QString a;
+
+ QVERIFY(a.chopped(0).isEmpty());
+ QVERIFY(!a.isDetached());
+
+ a = u"ABCDEFGHIEfGEFG"_s; // 15 chars
+
+ // lvalue
+ QCOMPARE(a.chopped(10), u"ABCDE");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, not detached
+ QCOMPARE(QString(a).chopped(10), u"ABCDE");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+
+ // rvalue, detached
+ QCOMPARE(detached(a).chopped(10), u"ABCDE");
+ QCOMPARE(a, u"ABCDEFGHIEfGEFG");
+}
+
+void tst_QString::removeIf()
+{
+ QString a;
+
+ auto pred = [](const QChar &c) { return c.isLower(); };
+ a.removeIf(pred);
+ QVERIFY(a.isEmpty());
+ QVERIFY(!a.isDetached());
+
+ // Test when the string is not shared
+ a = "aABbcCDd"_L1;
+ QVERIFY(!a.data_ptr()->needsDetach());
+ a.removeIf(pred);
+ QCOMPARE(a, u"ABCD");
+
+ // Test when the string is shared
+ a = "aABbcCDd"_L1;
+ QString b = a;
+ QVERIFY(a.data_ptr()->needsDetach());
+ a.removeIf(pred);
+ QCOMPARE(a, u"ABCD");
+ QCOMPARE(b, "aABbcCDd"_L1);
+
+ auto removeA = [](const char c) { return c == 'a' || c == 'A'; };
+
+ a = "aBcAbCa"_L1; // Not shared
+ QCOMPARE(a.removeIf(removeA), u"BcbC");
+
+ a = "aBcAbCa"_L1;
+ b = a; // Shared
+ QCOMPARE(a.removeIf(removeA), u"BcbC");
+}
+
+void tst_QString::std_stringview_conversion()
+{
+ static_assert(std::is_convertible_v<QString, std::u16string_view>);
+
+ QString s;
+ std::u16string_view sv(s);
+ QCOMPARE(sv, std::u16string_view());
+
+ s = u""_s;
+ sv = s;
+ QCOMPARE(s.size(), 0);
+ QCOMPARE(sv.size(), size_t(0));
+ QCOMPARE(sv, std::u16string_view());
+
+ s = u"Hello"_s;
+ sv = s;
+ QCOMPARE(sv, std::u16string_view(u"Hello"));
+
+ s = u"Hello\0world"_s;
+ sv = s;
+ QCOMPARE(s.size(), 11);
+ QCOMPARE(sv.size(), size_t(11));
+ QCOMPARE(sv, std::u16string_view(u"Hello\0world", 11));
+}
+
+// QString's collation order is only supported during the lifetime as QCoreApplication
+QTEST_GUILESS_MAIN(tst_QString)
+
+#include "tst_qstring.moc"
diff --git a/tests/auto/corelib/text/qstring/tst_qstring_mac.mm b/tests/auto/corelib/text/qstring/tst_qstring_mac.mm
new file mode 100644
index 0000000000..f9d35d938a
--- /dev/null
+++ b/tests/auto/corelib/text/qstring/tst_qstring_mac.mm
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QString>
+#include <QTest>
+
+#include <QtCore/private/qcore_mac_p.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Foundation/Foundation.h>
+
+using namespace Qt::StringLiterals;
+
+void tst_QString_macTypes()
+{
+ const QLatin1StringView testString("test string");
+ // QString <-> CFString
+ {
+ QString qtString = testString;
+ const CFStringRef cfString = qtString.toCFString();
+ QCOMPARE(QString::fromCFString(cfString), qtString);
+ CFRelease(cfString);
+ }
+ {
+ QString qtString = testString;
+ const CFStringRef cfString = qtString.toCFString();
+ QString qtStringCopy(qtString);
+ qtString = qtString.toUpper(); // modify
+ QCOMPARE(QString::fromCFString(cfString), qtStringCopy);
+ }
+ // QString <-> NSString
+ {
+ QMacAutoReleasePool pool;
+
+ QString qtString = testString;
+ const NSString *nsString = qtString.toNSString();
+ QCOMPARE(QString::fromNSString(nsString), qtString);
+ }
+ {
+ QMacAutoReleasePool pool;
+
+ QString qtString = testString;
+ const NSString *nsString = qtString.toNSString();
+ QString qtStringCopy(qtString);
+ qtString = qtString.toUpper(); // modify
+ QCOMPARE(QString::fromNSString(nsString), qtStringCopy);
+ }
+}
diff --git a/tests/auto/corelib/text/qstring/tst_qstring_wasm.cpp b/tests/auto/corelib/text/qstring/tst_qstring_wasm.cpp
new file mode 100644
index 0000000000..64865211dc
--- /dev/null
+++ b/tests/auto/corelib/text/qstring/tst_qstring_wasm.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QString>
+#include <QTest>
+
+#include <emscripten/val.h>
+
+void tst_QString_wasmTypes()
+{
+ const QLatin1StringView testString("test string");
+ // QString <-> emscripten::val
+ {
+ QString qtString = testString;
+ const emscripten::val jsString = qtString.toEcmaString();
+ QString qtStringCopy(qtString);
+ qtString = qtString.toUpper(); // modify
+ QCOMPARE(QString::fromEcmaString(jsString), qtStringCopy);
+ }
+ {
+ QString longString;
+ for (uint64_t i = 0; i < 1000; ++i)
+ longString += testString;
+ const emscripten::val jsString = longString.toEcmaString();
+ QString qtStringCopy(longString);
+ longString = longString.toUpper(); // modify
+ QCOMPARE(QString::fromEcmaString(jsString), qtStringCopy);
+ }
+}
diff --git a/tests/auto/corelib/text/qstring_no_cast_from_bytearray/CMakeLists.txt b/tests/auto/corelib/text/qstring_no_cast_from_bytearray/CMakeLists.txt
new file mode 100644
index 0000000000..6327b6952c
--- /dev/null
+++ b/tests/auto/corelib/text/qstring_no_cast_from_bytearray/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstring_no_cast_from_bytearray Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstring_no_cast_from_bytearray LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstring_no_cast_from_bytearray
+ SOURCES
+ tst_qstring_no_cast_from_bytearray.cpp
+ DEFINES
+ QT_NO_CAST_FROM_BYTEARRAY
+)
diff --git a/tests/auto/corelib/text/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp b/tests/auto/corelib/text/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp
new file mode 100644
index 0000000000..dd9c4ba21a
--- /dev/null
+++ b/tests/auto/corelib/text/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtCore/QtCore>
+
+class tst_QString_NoCastFromByteArray: public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void initTestCase();
+};
+
+void tst_QString_NoCastFromByteArray::initTestCase()
+{
+ qWarning("This is a compile test only");
+}
+
+QTEST_APPLESS_MAIN(tst_QString_NoCastFromByteArray)
+
+#include "tst_qstring_no_cast_from_bytearray.moc"
diff --git a/tests/auto/corelib/tools/qstringapisymmetry/.gitignore b/tests/auto/corelib/text/qstringapisymmetry/.gitignore
index d28de05438..d28de05438 100644
--- a/tests/auto/corelib/tools/qstringapisymmetry/.gitignore
+++ b/tests/auto/corelib/text/qstringapisymmetry/.gitignore
diff --git a/tests/auto/corelib/text/qstringapisymmetry/CMakeLists.txt b/tests/auto/corelib/text/qstringapisymmetry/CMakeLists.txt
new file mode 100644
index 0000000000..1989c26e9a
--- /dev/null
+++ b/tests/auto/corelib/text/qstringapisymmetry/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringapisymmetry Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringapisymmetry LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringapisymmetry
+ SOURCES
+ tst_qstringapisymmetry.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp
new file mode 100644
index 0000000000..35a734cf02
--- /dev/null
+++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp
@@ -0,0 +1,3655 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// Copyright (C) 2019 Mail.ru Group.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#undef QT_NO_CAST_FROM_ASCII
+#undef QT_NO_CAST_TO_ASCII
+#undef QT_ASCII_CAST_WARNINGS
+#define QT_USE_QSTRINGBUILDER
+
+#include <QChar>
+#include <QLatin1String>
+#include <QList>
+#include <QScopedArrayPointer>
+#include <QString>
+#include <QStringTokenizer>
+#include <QStringView>
+#include <QTest>
+#include <QVarLengthArray>
+
+#include "../../../../shared/localechange.h"
+
+#include <locale.h>
+
+Q_DECLARE_METATYPE(QLatin1String)
+
+namespace {
+
+struct QAnyStringViewUsingL1 : QAnyStringView {}; // QAnyStringView with Latin-1 content
+struct QAnyStringViewUsingU8 : QAnyStringView {}; // QAnyStringView with Utf-8 content
+struct QAnyStringViewUsingU16 : QAnyStringView {}; // QAnyStringView with Utf-16 content
+
+template <typename T>
+QString toQString(const T &t) { return QString(t); }
+QString toQString(QStringView view) { return view.toString(); }
+
+template <typename Iterable>
+QStringList toQStringList(const Iterable &i) {
+ QStringList result;
+ for (auto &e : i)
+ result.push_back(toQString(e));
+ return result;
+}
+
+template <typename LHS, typename RHS>
+constexpr bool is_fake_comparator_v = false;
+
+} // namespace
+
+static constexpr int sign(int i) noexcept
+{
+ return i < 0 ? -1 :
+ i > 0 ? +1 :
+ /*else*/ 0 ;
+}
+
+// Return a plain ASCII row name consisting of maximum 16 chars and the
+// size for data
+static QByteArray rowName(const QByteArray &data)
+{
+ const int size = data.size();
+ QScopedArrayPointer<char> prettyC(QTest::toPrettyCString(data.constData(), qMin(16, size)));
+ QByteArray result = prettyC.data();
+ result += " (";
+ result += QByteArray::number(size);
+ result += ')';
+ return result;
+}
+
+#ifdef __cpp_char8_t
+# define IF_CHAR8T(x) do { x; } while (false)
+#else
+# define IF_CHAR8T(x) QSKIP("This test requires C++20 char8_t support enabled in the compiler.")
+#endif
+
+class tst_QStringApiSymmetry : public QObject
+{
+ Q_OBJECT
+
+ //
+ // Overload set checks
+ //
+
+private:
+ template <typename T>
+ void overload();
+
+private Q_SLOTS:
+ void overload_char() { overload<char>(); }
+ void overload_QChar() { overload<QChar>(); }
+ void overload_char16_t() { overload<char16_t>(); }
+ void overload_QString() { overload<QString>(); }
+ void overload_QStringView() { overload<QStringView>(); }
+ void overload_QUtf8StringView() { overload<QUtf8StringView>(); }
+ void overload_QAnyStringView() { overload<QAnyStringView>(); }
+ void overload_QLatin1String() { overload<QLatin1String>(); }
+ void overload_QByteArray() { overload<QByteArray>(); }
+ void overload_QByteArrayView() { overload<QByteArrayView>(); }
+ void overload_const_char_star() { overload<const char*>(); }
+ void overload_const_char8_t_star() { IF_CHAR8T(overload<const char8_t*>()); }
+ void overload_const_char16_t_star() { overload<const char16_t*>(); }
+ void overload_char_array() { overload<char[10]>(); }
+ void overload_char8_t_array() { IF_CHAR8T(overload<char8_t[10]>()); }
+ void overload_char16_t_array() { overload<char16_t[10]>(); }
+ void overload_QChar_array() { overload<QChar[10]>(); }
+ void overload_std_string() { overload<std::string>(); }
+ void overload_std_u8string() { IF_CHAR8T(overload<std::u8string>()); }
+ void overload_std_u16string() { overload<std::u16string>(); }
+ void overload_QVarLengthArray_char() { overload<QVarLengthArray<char, 123>>(); }
+ void overload_QVarLengthArray_char8_t() { IF_CHAR8T((overload<QVarLengthArray<char, 321>>())); }
+ void overload_QVarLengthArray_char16_t() { overload<QVarLengthArray<char, 456>>(); }
+ void overload_QVarLengthArray_QChar() { overload<QVarLengthArray<QChar, 1023>>(); }
+ void overload_vector_char() { overload<std::vector<char>>(); }
+ void overload_vector_char8_t() { IF_CHAR8T(overload<std::vector<char8_t>>()); }
+ void overload_vector_char16_t() { overload<std::vector<char16_t>>(); }
+ void overload_vector_QChar() { overload<std::vector<QChar>>(); }
+
+ void overload_special();
+private:
+ //
+ // Mixed UTF-16, UTF-8, Latin-1 checks:
+ //
+
+ void compare_data(bool hasConceptOfNullAndEmpty=true);
+ template <typename LHS, typename RHS>
+ void compare_impl() const;
+
+private Q_SLOTS:
+ // test all combinations of {QChar, char16_t, QString, QStringView, QLatin1String, QByteArray/View, const char*}
+ void compare_QChar_QChar_data() { compare_data(false); }
+ void compare_QChar_QChar() { compare_impl<QChar, QChar>(); }
+ void compare_QChar_char16_t_data() { compare_data(false); }
+ void compare_QChar_char16_t() { compare_impl<QChar, char16_t>(); }
+ void compare_QChar_QString_data() { compare_data(false); }
+ void compare_QChar_QString() { compare_impl<QChar, QString>(); }
+ void compare_QChar_QStringView_data() { compare_data(false); }
+ void compare_QChar_QStringView() { compare_impl<QChar, QStringView>(); }
+ void compare_QChar_QUtf8StringView_data() { compare_data(false); }
+ void compare_QChar_QUtf8StringView() { compare_impl<QChar, QUtf8StringView>(); }
+ void compare_QChar_QLatin1String_data() { compare_data(false); }
+ void compare_QChar_QLatin1String() { compare_impl<QChar, QLatin1String>(); }
+ void compare_QChar_QByteArray_data() { compare_data(false); }
+ void compare_QChar_QByteArray() { compare_impl<QChar, QByteArray>(); }
+ void compare_QChar_QByteArrayView_data() { compare_data(false); }
+ void compare_QChar_QByteArrayView() { compare_impl<QChar, QByteArrayView>(); }
+ void compare_QChar_const_char_star_data() { compare_data(false); }
+ void compare_QChar_const_char_star() { compare_impl<QChar, const char *>(); }
+
+ void compare_char16_t_QChar_data() { compare_data(false); }
+ void compare_char16_t_QChar() { compare_impl<char16_t, QChar>(); }
+ //void compare_char16_t_char16_t_data() { compare_data(false); }
+ //void compare_char16_t_char16_t() { compare_impl<char16_t, char16_t>(); }
+ void compare_char16_t_QString_data() { compare_data(false); }
+ void compare_char16_t_QString() { compare_impl<char16_t, QString>(); }
+ void compare_char16_t_QStringView_data() { compare_data(false); }
+ void compare_char16_t_QStringView() { compare_impl<char16_t, QStringView>(); }
+ void compare_char16_t_QUtf8StringView_data() { compare_data(false); }
+ void compare_char16_t_QUtf8StringView() { compare_impl<char16_t, QUtf8StringView>(); }
+ void compare_char16_t_QLatin1String_data() { compare_data(false); }
+ void compare_char16_t_QLatin1String() { compare_impl<char16_t, QLatin1String>(); }
+ void compare_char16_t_QByteArray_data() { compare_data(false); }
+ void compare_char16_t_QByteArray() { compare_impl<char16_t, QByteArray>(); }
+ void compare_char16_t_QByteArrayView_data() { compare_data(false); }
+ void compare_char16_t_QByteArrayView() { compare_impl<char16_t, QByteArrayView>(); }
+ //void compare_char16_t_const_char_star_data() { compare_data(false); }
+ //void compare_char16_t_const_char_star() { compare_impl<char16_t, const char *>(); }
+
+ void compare_QString_QChar_data() { compare_data(false); }
+ void compare_QString_QChar() { compare_impl<QString, QChar>(); }
+ void compare_QString_char16_t_data() { compare_data(false); }
+ void compare_QString_char16_t() { compare_impl<QString, char16_t>(); }
+ void compare_QString_QString_data() { compare_data(); }
+ void compare_QString_QString() { compare_impl<QString, QString>(); }
+ void compare_QString_QStringView_data() { compare_data(); }
+ void compare_QString_QStringView() { compare_impl<QString, QStringView>(); }
+ void compare_QString_QUtf8StringView_data() { compare_data(); }
+ void compare_QString_QUtf8StringView() { compare_impl<QString, QUtf8StringView>(); }
+ void compare_QString_QLatin1String_data() { compare_data(); }
+ void compare_QString_QLatin1String() { compare_impl<QString, QLatin1String>(); }
+ void compare_QString_QByteArray_data() { compare_data(); }
+ void compare_QString_QByteArray() { compare_impl<QString, QByteArray>(); }
+ void compare_QString_QByteArrayView_data() { compare_data(); }
+ void compare_QString_QByteArrayView() { compare_impl<QString, QByteArrayView>(); }
+ void compare_QString_const_char_star_data() { compare_data(); }
+ void compare_QString_const_char_star() { compare_impl<QString, const char *>(); }
+
+ void compare_QStringView_QChar_data() { compare_data(false); }
+ void compare_QStringView_QChar() { compare_impl<QStringView, QChar>(); }
+ void compare_QStringView_char16_t_data() { compare_data(false); }
+ void compare_QStringView_char16_t() { compare_impl<QStringView, char16_t>(); }
+ void compare_QStringView_QString_data() { compare_data(); }
+ void compare_QStringView_QString() { compare_impl<QStringView, QString>(); }
+ void compare_QStringView_QStringView_data() { compare_data(); }
+ void compare_QStringView_QStringView() { compare_impl<QStringView, QStringView>(); }
+ void compare_QStringView_QUtf8StringView_data() { compare_data(); }
+ void compare_QStringView_QUtf8StringView() { compare_impl<QStringView, QUtf8StringView>(); }
+ void compare_QStringView_QLatin1String_data() { compare_data(); }
+ void compare_QStringView_QLatin1String() { compare_impl<QStringView, QLatin1String>(); }
+ void compare_QStringView_QByteArray_data() { compare_data(); }
+ void compare_QStringView_QByteArray() { compare_impl<QStringView, QByteArray>(); }
+ void compare_QStringView_QByteArrayView_data() { compare_data(); }
+ void compare_QStringView_QByteArrayView() { compare_impl<QStringView, QByteArrayView>(); }
+ void compare_QStringView_const_char_star_data() { compare_data(); }
+ void compare_QStringView_const_char_star() { compare_impl<QStringView, const char *>(); }
+
+ void compare_QUtf8StringView_QChar_data() { compare_data(false); }
+ void compare_QUtf8StringView_QChar() { compare_impl<QUtf8StringView, QChar>(); }
+ void compare_QUtf8StringView_char16_t_data() { compare_data(false); }
+ void compare_QUtf8StringView_char16_t() { compare_impl<QUtf8StringView, char16_t>(); }
+ void compare_QUtf8StringView_QString_data() { compare_data(); }
+ void compare_QUtf8StringView_QString() { compare_impl<QUtf8StringView, QString>(); }
+ void compare_QUtf8StringView_QStringView_data() { compare_data(); }
+ void compare_QUtf8StringView_QStringView() { compare_impl<QUtf8StringView, QStringView>(); }
+ void compare_QUtf8StringView_QUtf8StringView_data() { compare_data(); }
+ void compare_QUtf8StringView_QUtf8StringView() { compare_impl<QUtf8StringView, QUtf8StringView>(); }
+ void compare_QUtf8StringView_QLatin1String_data() { compare_data(); }
+ void compare_QUtf8StringView_QLatin1String() { compare_impl<QUtf8StringView, QLatin1String>(); }
+ void compare_QUtf8StringView_QByteArray_data() { compare_data(); }
+ void compare_QUtf8StringView_QByteArray() { compare_impl<QUtf8StringView, QByteArray>(); }
+ void compare_QUtf8StringView_QByteArrayView_data() { compare_data(); }
+ void compare_QUtf8StringView_QByteArrayView() { compare_impl<QUtf8StringView, QByteArrayView>(); }
+ void compare_QUtf8StringView_const_char_star_data() { compare_data(); }
+ void compare_QUtf8StringView_const_char_star() { compare_impl<QUtf8StringView, const char *>(); }
+
+ void compare_QLatin1String_QChar_data() { compare_data(false); }
+ void compare_QLatin1String_QChar() { compare_impl<QLatin1String, QChar>(); }
+ void compare_QLatin1String_char16_t_data() { compare_data(false); }
+ void compare_QLatin1String_char16_t() { compare_impl<QLatin1String, char16_t>(); }
+ void compare_QLatin1String_QString_data() { compare_data(); }
+ void compare_QLatin1String_QString() { compare_impl<QLatin1String, QString>(); }
+ void compare_QLatin1String_QStringView_data() { compare_data(); }
+ void compare_QLatin1String_QStringView() { compare_impl<QLatin1String, QStringView>(); }
+ void compare_QLatin1String_QUtf8StringView_data() { compare_data(); }
+ void compare_QLatin1String_QUtf8StringView() { compare_impl<QLatin1String, QUtf8StringView>(); }
+ void compare_QLatin1String_QLatin1String_data() { compare_data(); }
+ void compare_QLatin1String_QLatin1String() { compare_impl<QLatin1String, QLatin1String>(); }
+ void compare_QLatin1String_QByteArray_data() { compare_data(); }
+ void compare_QLatin1String_QByteArray() { compare_impl<QLatin1String, QByteArray>(); }
+ void compare_QLatin1String_QByteArrayView_data() { compare_data(); }
+ void compare_QLatin1String_QByteArrayView() { compare_impl<QLatin1String, QByteArrayView>(); }
+ void compare_QLatin1String_const_char_star_data() { compare_data(); }
+ void compare_QLatin1String_const_char_star() { compare_impl<QLatin1String, const char *>(); }
+
+ void compare_QByteArray_QChar_data() { compare_data(false); }
+ void compare_QByteArray_QChar() { compare_impl<QByteArray, QChar>(); }
+ void compare_QByteArray_char16_t_data() { compare_data(false); }
+ void compare_QByteArray_char16_t() { compare_impl<QByteArray, char16_t>(); }
+ void compare_QByteArray_QString_data() { compare_data(); }
+ void compare_QByteArray_QString() { compare_impl<QByteArray, QString>(); }
+ void compare_QByteArray_QStringView_data() { compare_data(); }
+ void compare_QByteArray_QStringView() { compare_impl<QByteArray, QStringView>(); }
+ void compare_QByteArray_QUtf8StringView_data() { compare_data(); }
+ void compare_QByteArray_QUtf8StringView() { compare_impl<QByteArray, QUtf8StringView>(); }
+ void compare_QByteArray_QLatin1String_data() { compare_data(); }
+ void compare_QByteArray_QLatin1String() { compare_impl<QByteArray, QLatin1String>(); }
+ void compare_QByteArray_QByteArray_data() { compare_data(); }
+ void compare_QByteArray_QByteArray() { compare_impl<QByteArray, QByteArray>(); }
+ void compare_QByteArray_QByteArrayView_data() { compare_data(); }
+ void compare_QByteArray_QByteArrayView() { compare_impl<QByteArray, QByteArrayView>(); }
+ void compare_QByteArray_const_char_star_data() { compare_data(); }
+ void compare_QByteArray_const_char_star() { compare_impl<QByteArray, const char *>(); }
+
+ void compare_QByteArrayView_QChar_data() { compare_data(false); }
+ void compare_QByteArrayView_QChar() { compare_impl<QByteArrayView, QChar>(); }
+ void compare_QByteArrayView_char16_t_data() { compare_data(false); }
+ void compare_QByteArrayView_char16_t() { compare_impl<QByteArrayView, char16_t>(); }
+ void compare_QByteArrayView_QString_data() { compare_data(); }
+ void compare_QByteArrayView_QString() { compare_impl<QByteArrayView, QString>(); }
+ void compare_QByteArrayView_QStringView_data() { compare_data(); }
+ void compare_QByteArrayView_QStringView() { compare_impl<QByteArrayView, QStringView>(); }
+ void compare_QByteArrayView_QUtf8StringView_data() { compare_data(); }
+ void compare_QByteArrayView_QUtf8StringView() { compare_impl<QByteArrayView, QUtf8StringView>(); }
+ void compare_QByteArrayView_QLatin1String_data() { compare_data(); }
+ void compare_QByteArrayView_QLatin1String() { compare_impl<QByteArrayView, QLatin1String>(); }
+ void compare_QByteArrayView_QByteArray_data() { compare_data(); }
+ void compare_QByteArrayView_QByteArray() { compare_impl<QByteArrayView, QByteArray>(); }
+ void compare_QByteArrayView_QByteArrayView_data() { compare_data(); }
+ void compare_QByteArrayView_QByteArrayView() { compare_impl<QByteArrayView, QByteArrayView>(); }
+ void compare_QByteArrayView_const_char_star_data() { compare_data(); }
+ void compare_QByteArrayView_const_char_star() { compare_impl<QByteArrayView, const char *>(); }
+
+ void compare_const_char_star_QChar_data() { compare_data(false); }
+ void compare_const_char_star_QChar() { compare_impl<const char *, QChar>(); }
+ //void compare_const_char_star_char16_t_data() { compare_data(false); }
+ //void compare_const_char_star_char16_t() { compare_impl<const char *, char16_t>(); }
+ void compare_const_char_star_QString_data() { compare_data(); }
+ void compare_const_char_star_QString() { compare_impl<const char *, QString>(); }
+ void compare_const_char_star_QStringView_data() { compare_data(); }
+ void compare_const_char_star_QStringView() { compare_impl<const char *, QStringView>(); }
+ void compare_const_char_star_QUtf8StringView_data() { compare_data(); }
+ void compare_const_char_star_QUtf8StringView() { compare_impl<const char *, QUtf8StringView>(); }
+ void compare_const_char_star_QLatin1String_data() { compare_data(false); }
+ void compare_const_char_star_QLatin1String() { compare_impl<const char *, QLatin1String>(); }
+ void compare_const_char_star_QByteArray_data() { compare_data(); }
+ void compare_const_char_star_QByteArray() { compare_impl<const char *, QByteArray>(); }
+ void compare_const_char_star_QByteArrayView_data() { compare_data(); }
+ void compare_const_char_star_QByteArrayView() { compare_impl<const char *, QByteArrayView>(); }
+ //void compare_const_char_star_const_char_star_data() { compare_data(); }
+ //void compare_const_char_star_const_char_star() { compare_impl<const char *, const char *>(); }
+
+private:
+ void member_compare_data(bool hasConceptOfNullAndEmpty=true) { compare_data(hasConceptOfNullAndEmpty); }
+ template <typename LHS, typename RHS>
+ void member_compare_impl() const;
+
+private Q_SLOTS:
+ // test all combinations of {QChar, char16_t, QString, QStringView, QLatin1String, QByteArray, const char*}
+#ifdef NOT_YET_IMPLEMENTED // probably never will be - what's the point of QChar::compare(QStringView)?
+ void member_compare_QChar_QChar_data() { member_compare_data(false); }
+ void member_compare_QChar_QChar() { member_compare_impl<QChar, QChar>(); }
+ void member_compare_QChar_char16_t_data() { member_compare_data(false); }
+ void member_compare_QChar_char16_t() { member_compare_impl<QChar, char16_t>(); }
+ void member_compare_QChar_QString_data() { member_compare_data(false); }
+ void member_compare_QChar_QString() { member_compare_impl<QChar, QString>(); }
+ void member_compare_QChar_QStringView_data() { member_compare_data(false); }
+ void member_compare_QChar_QStringView() { member_compare_impl<QChar, QStringView>(); }
+ void member_compare_QChar_QLatin1String_data() { member_compare_data(false); }
+ void member_compare_QChar_QLatin1String() { member_compare_impl<QChar, QLatin1String>(); }
+ void member_compare_QChar_QByteArray_data() { member_compare_data(false); }
+ void member_compare_QChar_QByteArray() { member_compare_impl<QChar, QByteArray>(); }
+ void member_compare_QChar_QByteArrayView_data() { member_compare_data(false); }
+ void member_compare_QChar_QByteArrayView() { member_compare_impl<QChar, QByteArrayView>(); }
+ void member_compare_QChar_const_char_star_data() { member_compare_data(false); }
+ void member_compare_QChar_const_char_star() { member_compare_impl<QChar, const char *>(); }
+#endif
+
+ // void member_compare_char16_t_XXX() - not possible
+
+ void member_compare_QString_QChar_data() { member_compare_data(false); }
+ void member_compare_QString_QChar() { member_compare_impl<QString, QChar>(); }
+ void member_compare_QString_char16_t_data() { member_compare_data(false); }
+ void member_compare_QString_char16_t() { member_compare_impl<QString, char16_t>(); }
+ void member_compare_QString_QString_data() { member_compare_data(); }
+ void member_compare_QString_QString() { member_compare_impl<QString, QString>(); }
+ void member_compare_QString_QStringView_data() { member_compare_data(); }
+ void member_compare_QString_QStringView() { member_compare_impl<QString, QStringView>(); }
+ void member_compare_QString_QLatin1String_data() { member_compare_data(); }
+ void member_compare_QString_QLatin1String() { member_compare_impl<QString, QLatin1String>(); }
+ void member_compare_QString_QByteArray_data() { member_compare_data(); }
+ void member_compare_QString_QByteArray() { member_compare_impl<QString, QByteArray>(); }
+#ifdef NOT_YET_IMPLEMENTED
+ void member_compare_QString_QByteArrayView_data() { member_compare_data(); }
+ void member_compare_QString_QByteArrayView() { member_compare_impl<QString, QByteArrayView>(); }
+#endif
+ void member_compare_QString_const_char_star_data() { member_compare_data(); }
+ void member_compare_QString_const_char_star() { member_compare_impl<QString, const char *>(); }
+
+ void member_compare_QStringView_QChar_data() { member_compare_data(false); }
+ void member_compare_QStringView_QChar() { member_compare_impl<QStringView, QChar>(); }
+ void member_compare_QStringView_char16_t_data() { member_compare_data(false); }
+ void member_compare_QStringView_char16_t() { member_compare_impl<QStringView, char16_t>(); }
+ void member_compare_QStringView_QString_data() { member_compare_data(); }
+ void member_compare_QStringView_QString() { member_compare_impl<QStringView, QString>(); }
+ void member_compare_QStringView_QStringView_data() { member_compare_data(); }
+ void member_compare_QStringView_QStringView() { member_compare_impl<QStringView, QStringView>(); }
+ void member_compare_QStringView_QLatin1String_data() { member_compare_data(); }
+ void member_compare_QStringView_QLatin1String() { member_compare_impl<QStringView, QLatin1String>(); }
+ void member_compare_QStringView_QUtf8StringView_data() { member_compare_data(); }
+ void member_compare_QStringView_QUtf8StringView() { member_compare_impl<QStringView, QUtf8StringView>(); }
+#ifdef NOT_YET_IMPLEMENTED
+ void member_compare_QStringView_QByteArray_data() { member_compare_data(); }
+ void member_compare_QStringView_QByteArray() { member_compare_impl<QStringView, QByteArray>(); }
+ void member_compare_QStringView_QByteArrayView_data() { member_compare_data(); }
+ void member_compare_QStringView_QByteArrayView() { member_compare_impl<QStringView, QByteArrayView>(); }
+ void member_compare_QStringView_const_char_star_data() { member_compare_data(); }
+ void member_compare_QStringView_const_char_star() { member_compare_impl<QStringView, const char *>(); }
+#endif
+
+ void member_compare_QLatin1String_QChar_data() { member_compare_data(false); }
+ void member_compare_QLatin1String_QChar() { member_compare_impl<QLatin1String, QChar>(); }
+ void member_compare_QLatin1String_char16_t_data() { member_compare_data(false); }
+ void member_compare_QLatin1String_char16_t() { member_compare_impl<QLatin1String, char16_t>(); }
+ void member_compare_QLatin1String_QLatin1Char_data() { member_compare_data(false); }
+ void member_compare_QLatin1String_QLatin1Char() { member_compare_impl<QLatin1String, QLatin1Char>(); }
+ void member_compare_QLatin1String_QString_data() { member_compare_data(); }
+ void member_compare_QLatin1String_QString() { member_compare_impl<QLatin1String, QString>(); }
+ void member_compare_QLatin1String_QStringView_data() { member_compare_data(); }
+ void member_compare_QLatin1String_QStringView() { member_compare_impl<QLatin1String, QStringView>(); }
+ void member_compare_QLatin1String_QLatin1String_data() { member_compare_data(); }
+ void member_compare_QLatin1String_QLatin1String() { member_compare_impl<QLatin1String, QLatin1String>(); }
+ void member_compare_QLatin1String_QUtf8StringView_data() { member_compare_data(); }
+ void member_compare_QLatin1String_QUtf8StringView() { member_compare_impl<QLatin1String, QUtf8StringView>(); }
+#ifdef NOT_YET_IMPLEMENTED
+ void member_compare_QLatin1String_QByteArray_data() { member_compare_data(); }
+ void member_compare_QLatin1String_QByteArray() { member_compare_impl<QLatin1String, QByteArray>(); }
+ void member_compare_QLatin1String_QByteArrayView_data() { member_compare_data(); }
+ void member_compare_QLatin1String_QByteArrayView() { member_compare_impl<QLatin1String, QByteArrayView>(); }
+ void member_compare_QLatin1String_const_char_star_data() { member_compare_data(); }
+ void member_compare_QLatin1String_const_char_star() { member_compare_impl<QLatin1String, const char *>(); }
+#endif
+
+#ifdef NOT_YET_IMPLEMENTED
+ void member_compare_QByteArray_QChar_data() { member_compare_data(false); }
+ void member_compare_QByteArray_QChar() { member_compare_impl<QByteArray, QChar>(); }
+ void member_compare_QByteArray_char16_t_data() { member_compare_data(false); }
+ void member_compare_QByteArray_char16_t() { member_compare_impl<QByteArray, char16_t>(); }
+ void member_compare_QByteArray_QString_data() { member_compare_data(); }
+ void member_compare_QByteArray_QString() { member_compare_impl<QByteArray, QString>(); }
+ void member_compare_QByteArray_QLatin1String_data() { member_compare_data(); }
+ void member_compare_QByteArray_QLatin1String() { member_compare_impl<QByteArray, QLatin1String>(); }
+#endif
+ void member_compare_QByteArray_QByteArray_data() { member_compare_data(); }
+ void member_compare_QByteArray_QByteArray() { member_compare_impl<QByteArray, QByteArray>(); }
+ void member_compare_QByteArray_QByteArrayView_data() { member_compare_data(); }
+ void member_compare_QByteArray_QByteArrayView() { member_compare_impl<QByteArray, QByteArrayView>(); }
+ void member_compare_QByteArray_const_char_star_data() { member_compare_data(); }
+ void member_compare_QByteArray_const_char_star() { member_compare_impl<QByteArray, const char *>(); }
+
+#ifdef NOT_YET_IMPLEMENTED
+ void member_compare_QByteArrayView_QChar_data() { member_compare_data(false); }
+ void member_compare_QByteArrayView_QChar() { member_compare_impl<QByteArrayView, QChar>(); }
+ void member_compare_QByteArrayView_char16_t_data() { member_compare_data(false); }
+ void member_compare_QByteArrayView_char16_t() { member_compare_impl<QByteArrayView, char16_t>(); }
+ void member_compare_QByteArrayView_QString_data() { member_compare_data(); }
+ void member_compare_QByteArrayView_QString() { member_compare_impl<QByteArrayView, QString>(); }
+ void member_compare_QByteArrayView_QLatin1String_data() { member_compare_data(); }
+ void member_compare_QByteArrayView_QLatin1String() { member_compare_impl<QByteArrayView, QLatin1String>(); }
+#endif
+ void member_compare_QByteArrayView_QByteArray_data() { member_compare_data(); }
+ void member_compare_QByteArrayView_QByteArray() { member_compare_impl<QByteArrayView, QByteArray>(); }
+ void member_compare_QByteArrayView_QByteArrayView_data() { member_compare_data(); }
+ void member_compare_QByteArrayView_QByteArrayView() { member_compare_impl<QByteArrayView, QByteArrayView>(); }
+ void member_compare_QByteArrayView_const_char_star_data() { member_compare_data(); }
+ void member_compare_QByteArrayView_const_char_star() { member_compare_impl<QByteArrayView, const char *>(); }
+
+#ifdef NOT_YET_IMPLEMENTED
+ void member_compare_QUtf8StringView_QChar_data() { member_compare_data(false); }
+ void member_compare_QUtf8StringView_QChar() { member_compare_impl<QUtf8StringView, QChar>(); }
+ void member_compare_QUtf8StringView_char16_t_data() { member_compare_data(false); }
+ void member_compare_QUtf8StringView_char16_t() { member_compare_impl<QUtf8StringView, char16_t>(); }
+#endif
+ void member_compare_QUtf8StringView_QString_data() { member_compare_data(); }
+ void member_compare_QUtf8StringView_QString() { member_compare_impl<QUtf8StringView, QString>(); }
+ void member_compare_QUtf8StringView_QLatin1String_data() { member_compare_data(); }
+ void member_compare_QUtf8StringView_QLatin1String() { member_compare_impl<QUtf8StringView, QLatin1String>(); }
+ void member_compare_QUtf8StringView_QUtf8StringView_data() { member_compare_data(); }
+ void member_compare_QUtf8StringView_QUtf8StringView() { member_compare_impl<QUtf8StringView, QUtf8StringView>(); }
+
+private:
+ void localeAwareCompare_data();
+ template<typename LHS, typename RHS>
+ void localeAwareCompare_impl();
+
+private Q_SLOTS:
+ void localeAwareCompare_QString_QString_data() { localeAwareCompare_data(); }
+ void localeAwareCompare_QString_QString() { localeAwareCompare_impl<QString, QString>(); }
+ void localeAwareCompare_QString_QStringView_data() { localeAwareCompare_data(); }
+ void localeAwareCompare_QString_QStringView() { localeAwareCompare_impl<QString, QStringView>(); }
+ void localeAwareCompare_QStringView_QString_data() { localeAwareCompare_data(); }
+ void localeAwareCompare_QStringView_QString() { localeAwareCompare_impl<QStringView, QString>(); }
+ void localeAwareCompare_QStringView_QStringView_data() { localeAwareCompare_data(); }
+ void localeAwareCompare_QStringView_QStringView() { localeAwareCompare_impl<QStringView, QStringView>(); }
+
+private:
+ void member_localeAwareCompare_data() { localeAwareCompare_data(); }
+ template<typename LHS, typename RHS>
+ void member_localeAwareCompare_impl();
+
+private Q_SLOTS:
+ void member_localeAwareCompare_QString_QString_data() { member_localeAwareCompare_data(); }
+ void member_localeAwareCompare_QString_QString() { member_localeAwareCompare_impl<QString, QString>(); }
+ void member_localeAwareCompare_QString_QStringView_data() { member_localeAwareCompare_data(); }
+ void member_localeAwareCompare_QString_QStringView() { member_localeAwareCompare_impl<QString, QStringView>(); }
+ void member_localeAwareCompare_QStringView_QString_data() { member_localeAwareCompare_data(); }
+ void member_localeAwareCompare_QStringView_QString() { member_localeAwareCompare_impl<QStringView, QString>(); }
+ void member_localeAwareCompare_QStringView_QStringView_data() { member_localeAwareCompare_data(); }
+ void member_localeAwareCompare_QStringView_QStringView() { member_localeAwareCompare_impl<QStringView, QStringView>(); }
+
+private:
+ void startsWith_data(bool rhsIsQChar = false);
+ template <typename Haystack, typename Needle> void startsWith_impl() const;
+
+ void endsWith_data(bool rhsIsQChar = false);
+ template <typename Haystack, typename Needle> void endsWith_impl() const;
+
+private Q_SLOTS:
+ // test all combinations of {QString, QStringView, QLatin1String} x {QString, QStringView, QLatin1String, QChar, char16_t}:
+ void startsWith_QString_QString_data() { startsWith_data(); }
+ void startsWith_QString_QString() { startsWith_impl<QString, QString>(); }
+ void startsWith_QString_QStringView_data() { startsWith_data(); }
+ void startsWith_QString_QStringView() { startsWith_impl<QString, QStringView>(); }
+ void startsWith_QString_QLatin1String_data() { startsWith_data(); }
+ void startsWith_QString_QLatin1String() { startsWith_impl<QString, QLatin1String>(); }
+ void startsWith_QString_QChar_data() { startsWith_data(false); }
+ void startsWith_QString_QChar() { startsWith_impl<QString, QChar>(); }
+ void startsWith_QString_char16_t_data() { startsWith_data(false); }
+ void startsWith_QString_char16_t() { startsWith_impl<QString, char16_t>(); }
+
+ void startsWith_QStringView_QString_data() { startsWith_data(); }
+ void startsWith_QStringView_QString() { startsWith_impl<QStringView, QString>(); }
+ void startsWith_QStringView_QStringView_data() { startsWith_data(); }
+ void startsWith_QStringView_QStringView() { startsWith_impl<QStringView, QStringView>(); }
+ void startsWith_QStringView_QLatin1String_data() { startsWith_data(); }
+ void startsWith_QStringView_QLatin1String() { startsWith_impl<QStringView, QLatin1String>(); }
+ void startsWith_QStringView_QChar_data() { startsWith_data(false); }
+ void startsWith_QStringView_QChar() { startsWith_impl<QStringView, QChar>(); }
+ void startsWith_QStringView_char16_t_data() { startsWith_data(false); }
+ void startsWith_QStringView_char16_t() { startsWith_impl<QStringView, char16_t>(); }
+
+ void startsWith_QLatin1String_QString_data() { startsWith_data(); }
+ void startsWith_QLatin1String_QString() { startsWith_impl<QLatin1String, QString>(); }
+ void startsWith_QLatin1String_QStringView_data() { startsWith_data(); }
+ void startsWith_QLatin1String_QStringView() { startsWith_impl<QLatin1String, QStringView>(); }
+ void startsWith_QLatin1String_QLatin1String_data() { startsWith_data(); }
+ void startsWith_QLatin1String_QLatin1String() { startsWith_impl<QLatin1String, QLatin1String>(); }
+ void startsWith_QLatin1String_QChar_data() { startsWith_data(false); }
+ void startsWith_QLatin1String_QChar() { startsWith_impl<QLatin1String, QChar>(); }
+ void startsWith_QLatin1String_char16_t_data() { startsWith_data(false); }
+ void startsWith_QLatin1String_char16_t() { startsWith_impl<QLatin1String, char16_t>(); }
+ void startsWith_QLatin1String_QLatin1Char_data() { startsWith_data(false); }
+ void startsWith_QLatin1String_QLatin1Char() { startsWith_impl<QLatin1String, QLatin1Char>(); }
+
+ void endsWith_QString_QString_data() { endsWith_data(); }
+ void endsWith_QString_QString() { endsWith_impl<QString, QString>(); }
+ void endsWith_QString_QStringView_data() { endsWith_data(); }
+ void endsWith_QString_QStringView() { endsWith_impl<QString, QStringView>(); }
+ void endsWith_QString_QLatin1String_data() { endsWith_data(); }
+ void endsWith_QString_QLatin1String() { endsWith_impl<QString, QLatin1String>(); }
+ void endsWith_QString_QChar_data() { endsWith_data(false); }
+ void endsWith_QString_QChar() { endsWith_impl<QString, QChar>(); }
+ void endsWith_QString_char16_t_data() { endsWith_data(false); }
+ void endsWith_QString_char16_t() { endsWith_impl<QString, char16_t>(); }
+
+ void endsWith_QStringView_QString_data() { endsWith_data(); }
+ void endsWith_QStringView_QString() { endsWith_impl<QStringView, QString>(); }
+ void endsWith_QStringView_QStringView_data() { endsWith_data(); }
+ void endsWith_QStringView_QStringView() { endsWith_impl<QStringView, QStringView>(); }
+ void endsWith_QStringView_QLatin1String_data() { endsWith_data(); }
+ void endsWith_QStringView_QLatin1String() { endsWith_impl<QStringView, QLatin1String>(); }
+ void endsWith_QStringView_QChar_data() { endsWith_data(false); }
+ void endsWith_QStringView_QChar() { endsWith_impl<QStringView, QChar>(); }
+ void endsWith_QStringView_char16_t_data() { endsWith_data(false); }
+ void endsWith_QStringView_char16_t() { endsWith_impl<QStringView, char16_t>(); }
+
+ void endsWith_QLatin1String_QString_data() { endsWith_data(); }
+ void endsWith_QLatin1String_QString() { endsWith_impl<QLatin1String, QString>(); }
+ void endsWith_QLatin1String_QStringView_data() { endsWith_data(); }
+ void endsWith_QLatin1String_QStringView() { endsWith_impl<QLatin1String, QStringView>(); }
+ void endsWith_QLatin1String_QLatin1String_data() { endsWith_data(); }
+ void endsWith_QLatin1String_QLatin1String() { endsWith_impl<QLatin1String, QLatin1String>(); }
+ void endsWith_QLatin1String_QChar_data() { endsWith_data(false); }
+ void endsWith_QLatin1String_QChar() { endsWith_impl<QLatin1String, QChar>(); }
+ void endsWith_QLatin1String_char16_t_data() { endsWith_data(false); }
+ void endsWith_QLatin1String_char16_t() { endsWith_impl<QLatin1String, char16_t>(); }
+ void endsWith_QLatin1String_QLatin1Char_data() { endsWith_data(false); }
+ void endsWith_QLatin1String_QLatin1Char() { endsWith_impl<QLatin1String, QLatin1Char>(); }
+
+private:
+ void split_data(bool rhsHasVariableLength = true);
+ template <typename Haystack, typename Needle> void split_impl() const;
+
+private Q_SLOTS:
+ // test all combinations of {QString} x {QString, QLatin1String, QChar, char16_t}:
+ void split_QString_QString_data() { split_data(); }
+ void split_QString_QString() { split_impl<QString, QString>(); }
+ void split_QString_QLatin1String_data() { split_data(); }
+ void split_QString_QLatin1String() { split_impl<QString, QLatin1String>(); }
+ void split_QString_QChar_data() { split_data(false); }
+ void split_QString_QChar() { split_impl<QString, QChar>(); }
+ void split_QString_char16_t_data() { split_data(false); }
+ void split_QString_char16_t() { split_impl<QString, char16_t>(); }
+
+private:
+ void tok_data(bool rhsHasVariableLength = true);
+ template <typename Haystack, typename Needle> void tok_impl() const;
+
+private Q_SLOTS:
+ // let Splittable = {QString, QStringView, QLatin1String, const char16_t*, std::u16string}
+ // let Separators = Splittable ∪ {QChar, char16_t}
+ // test Splittable × Separators:
+ void tok_QString_QString_data() { tok_data(); }
+ void tok_QString_QString() { tok_impl<QString, QString>(); }
+ void tok_QString_QStringView_data() { tok_data(); }
+ void tok_QString_QStringView() { tok_impl<QString, QStringView>(); }
+ void tok_QString_QLatin1String_data() { tok_data(); }
+ void tok_QString_QLatin1String() { tok_impl<QString, QLatin1String>(); }
+ void tok_QString_const_char16_t_star_data() { tok_data(); }
+ void tok_QString_const_char16_t_star() { tok_impl<QString, const char16_t*>(); }
+ void tok_QString_stdu16string_data() { tok_data(); }
+ void tok_QString_stdu16string() { tok_impl<QString, std::u16string>(); }
+ void tok_QString_QChar_data() { tok_data(false); }
+ void tok_QString_QChar() { tok_impl<QString, QChar>(); }
+ void tok_QString_char16_t_data() { tok_data(false); }
+ void tok_QString_char16_t() { tok_impl<QString, char16_t>(); }
+
+ void tok_QStringView_QString_data() { tok_data(); }
+ void tok_QStringView_QString() { tok_impl<QStringView, QString>(); }
+ void tok_QStringView_QStringView_data() { tok_data(); }
+ void tok_QStringView_QStringView() { tok_impl<QStringView, QStringView>(); }
+ void tok_QStringView_QLatin1String_data() { tok_data(); }
+ void tok_QStringView_QLatin1String() { tok_impl<QStringView, QLatin1String>(); }
+ void tok_QStringView_const_char16_t_star_data() { tok_data(); }
+ void tok_QStringView_const_char16_t_star() { tok_impl<QStringView, const char16_t*>(); }
+ void tok_QStringView_stdu16string_data() { tok_data(); }
+ void tok_QStringView_stdu16string() { tok_impl<QStringView, std::u16string>(); }
+ void tok_QStringView_QChar_data() { tok_data(false); }
+ void tok_QStringView_QChar() { tok_impl<QStringView, QChar>(); }
+ void tok_QStringView_char16_t_data() { tok_data(false); }
+ void tok_QStringView_char16_t() { tok_impl<QStringView, char16_t>(); }
+
+ void tok_QLatin1String_QString_data() { tok_data(); }
+ void tok_QLatin1String_QString() { tok_impl<QLatin1String, QString>(); }
+ void tok_QLatin1String_QStringView_data() { tok_data(); }
+ void tok_QLatin1String_QStringView() { tok_impl<QLatin1String, QStringView>(); }
+ void tok_QLatin1String_QLatin1String_data() { tok_data(); }
+ void tok_QLatin1String_QLatin1String() { tok_impl<QLatin1String, QLatin1String>(); }
+ void tok_QLatin1String_const_char16_t_star_data() { tok_data(); }
+ void tok_QLatin1String_const_char16_t_star() { tok_impl<QLatin1String, const char16_t*>(); }
+ void tok_QLatin1String_stdu16string_data() { tok_data(); }
+ void tok_QLatin1String_stdu16string() { tok_impl<QLatin1String, std::u16string>(); }
+ void tok_QLatin1String_QChar_data() { tok_data(false); }
+ void tok_QLatin1String_QChar() { tok_impl<QLatin1String, QChar>(); }
+ void tok_QLatin1String_char16_t_data() { tok_data(false); }
+ void tok_QLatin1String_char16_t() { tok_impl<QLatin1String, char16_t>(); }
+ void tok_QLatin1String_QLatin1Char_data() { tok_data(false); }
+ void tok_QLatin1String_QLatin1Char() { tok_impl<QLatin1String, QLatin1Char>(); }
+
+ void tok_const_char16_t_star_QString_data() { tok_data(); }
+ void tok_const_char16_t_star_QString() { tok_impl<const char16_t*, QString>(); }
+ void tok_const_char16_t_star_QStringView_data() { tok_data(); }
+ void tok_const_char16_t_star_QStringView() { tok_impl<const char16_t*, QStringView>(); }
+ void tok_const_char16_t_star_QLatin1String_data() { tok_data(); }
+ void tok_const_char16_t_star_QLatin1String() { tok_impl<const char16_t*, QLatin1String>(); }
+ void tok_const_char16_t_star_const_char16_t_star_data() { tok_data(); }
+ void tok_const_char16_t_star_const_char16_t_star() { tok_impl<const char16_t*, const char16_t*>(); }
+ void tok_const_char16_t_star_stdu16string_data() { tok_data(); }
+ void tok_const_char16_t_star_stdu16string() { tok_impl<const char16_t*, std::u16string>(); }
+ void tok_const_char16_t_star_QChar_data() { tok_data(false); }
+ void tok_const_char16_t_star_QChar() { tok_impl<const char16_t*, QChar>(); }
+ void tok_const_char16_t_star_char16_t_data() { tok_data(false); }
+ void tok_const_char16_t_star_char16_t() { tok_impl<const char16_t*, char16_t>(); }
+
+ void tok_stdu16string_QString_data() { tok_data(); }
+ void tok_stdu16string_QString() { tok_impl<std::u16string, QString>(); }
+ void tok_stdu16string_QStringView_data() { tok_data(); }
+ void tok_stdu16string_QStringView() { tok_impl<std::u16string, QStringView>(); }
+ void tok_stdu16string_QLatin1String_data() { tok_data(); }
+ void tok_stdu16string_QLatin1String() { tok_impl<std::u16string, QLatin1String>(); }
+ void tok_stdu16string_const_char16_t_star_data() { tok_data(); }
+ void tok_stdu16string_const_char16_t_star() { tok_impl<std::u16string, const char16_t*>(); }
+ void tok_stdu16string_stdu16string_data() { tok_data(); }
+ void tok_stdu16string_stdu16string() { tok_impl<std::u16string, std::u16string>(); }
+ void tok_stdu16string_QChar_data() { tok_data(false); }
+ void tok_stdu16string_QChar() { tok_impl<std::u16string, QChar>(); }
+ void tok_stdu16string_char16_t_data() { tok_data(false); }
+ void tok_stdu16string_char16_t() { tok_impl<std::u16string, char16_t>(); }
+
+private:
+ void mid_data();
+ template <typename String> void mid_impl();
+
+ void left_data();
+ template <typename String> void left_impl();
+
+ void right_data();
+ template <typename String> void right_impl();
+
+ void sliced_data();
+ template <typename String> void sliced_impl();
+ template <typename String> void slice_impl();
+
+ void first_data();
+ template <typename String> void first_impl();
+
+ void last_data();
+ template <typename String> void last_impl();
+
+ void chop_data();
+ template <typename String> void chop_impl();
+
+private Q_SLOTS:
+
+ void mid_QString_data() { mid_data(); }
+ void mid_QString() { mid_impl<QString>(); }
+ void mid_QStringView_data() { mid_data(); }
+ void mid_QStringView() { mid_impl<QStringView>(); }
+ void mid_QUtf8StringView_data() { mid_data(); }
+ void mid_QUtf8StringView() { mid_impl<QUtf8StringView>(); }
+ void mid_QLatin1String_data() { mid_data(); }
+ void mid_QLatin1String() { mid_impl<QLatin1String>(); }
+ void mid_QAnyStringViewUsingL1_data() { mid_data(); }
+ void mid_QAnyStringViewUsingL1() { mid_impl<QAnyStringViewUsingL1>(); }
+ void mid_QAnyStringViewUsingU8_data() { mid_data(); }
+ void mid_QAnyStringViewUsingU8() { mid_impl<QAnyStringViewUsingU8>(); }
+ void mid_QAnyStringViewUsingU16_data() { mid_data(); }
+ void mid_QAnyStringViewUsingU16() { mid_impl<QAnyStringViewUsingU16>(); }
+ void mid_QByteArray_data() { mid_data(); }
+ void mid_QByteArray() { mid_impl<QByteArray>(); }
+ void mid_QByteArrayView_data() { mid_data(); }
+ void mid_QByteArrayView() { mid_impl<QByteArrayView>(); }
+
+ void left_QString_data() { left_data(); }
+ void left_QString() { left_impl<QString>(); }
+ void left_QStringView_data() { left_data(); }
+ void left_QStringView() { left_impl<QStringView>(); }
+ void left_QUtf8StringView_data() { left_data(); }
+ void left_QUtf8StringView() { left_impl<QUtf8StringView>(); }
+ void left_QLatin1String_data() { left_data(); }
+ void left_QLatin1String() { left_impl<QLatin1String>(); }
+ void left_QAnyStringViewUsingL1_data() { left_data(); }
+ void left_QAnyStringViewUsingL1() { left_impl<QAnyStringViewUsingL1>(); }
+ void left_QAnyStringViewUsingU8_data() { left_data(); }
+ void left_QAnyStringViewUsingU8() { left_impl<QAnyStringViewUsingU8>(); }
+ void left_QAnyStringViewUsingU16_data() { left_data(); }
+ void left_QAnyStringViewUsingU16() { left_impl<QAnyStringViewUsingU16>(); }
+ void left_QByteArray_data();
+ void left_QByteArray() { left_impl<QByteArray>(); }
+ void left_QByteArrayView_data() { left_data(); }
+ void left_QByteArrayView() { left_impl<QByteArrayView>(); }
+
+ void right_QString_data() { right_data(); }
+ void right_QString() { right_impl<QString>(); }
+ void right_QStringView_data() { right_data(); }
+ void right_QStringView() { right_impl<QStringView>(); }
+ void right_QUtf8StringView_data() { right_data(); }
+ void right_QUtf8StringView() { right_impl<QUtf8StringView>(); }
+ void right_QLatin1String_data() { right_data(); }
+ void right_QLatin1String() { right_impl<QLatin1String>(); }
+ void right_QAnyStringViewUsingL1_data() { right_data(); }
+ void right_QAnyStringViewUsingL1() { right_impl<QAnyStringViewUsingL1>(); }
+ void right_QAnyStringViewUsingU8_data() { right_data(); }
+ void right_QAnyStringViewUsingU8() { right_impl<QAnyStringViewUsingU8>(); }
+ void right_QAnyStringViewUsingU16_data() { right_data(); }
+ void right_QAnyStringViewUsingU16() { right_impl<QAnyStringViewUsingU16>(); }
+ void right_QByteArray_data();
+ void right_QByteArray() { right_impl<QByteArray>(); }
+ void right_QByteArrayView_data() { right_data(); }
+ void right_QByteArrayView() { right_impl<QByteArrayView>(); }
+
+ void sliced_QString_data() { sliced_data(); }
+ void sliced_QString() { sliced_impl<QString>(); }
+ void sliced_QStringView_data() { sliced_data(); }
+ void sliced_QStringView() { sliced_impl<QStringView>(); }
+ void sliced_QLatin1String_data() { sliced_data(); }
+ void sliced_QLatin1String() { sliced_impl<QLatin1String>(); }
+ void sliced_QUtf8StringView_data() { sliced_data(); }
+ void sliced_QUtf8StringView() { sliced_impl<QUtf8StringView>(); }
+ void sliced_QAnyStringViewUsingL1_data() { sliced_data(); }
+ void sliced_QAnyStringViewUsingL1() { sliced_impl<QAnyStringViewUsingL1>(); }
+ void sliced_QAnyStringViewUsingU8_data() { sliced_data(); }
+ void sliced_QAnyStringViewUsingU8() { sliced_impl<QAnyStringViewUsingU8>(); }
+ void sliced_QAnyStringViewUsingU16_data() { sliced_data(); }
+ void sliced_QAnyStringViewUsingU16() { sliced_impl<QAnyStringViewUsingU16>(); }
+ void sliced_QByteArray_data() { sliced_data(); }
+ void sliced_QByteArray() { sliced_impl<QByteArray>(); }
+ void sliced_QByteArrayView_data() { sliced_data(); }
+ void sliced_QByteArrayView() { sliced_impl<QByteArrayView>(); }
+
+ void slice_QString_data() { sliced_data(); }
+ void slice_QString() { slice_impl<QString>(); }
+ void slice_QByteArray_data() { sliced_data(); }
+ void slice_QByteArray() { slice_impl<QByteArray>(); }
+
+ void first_truncate_QString_data() { first_data(); }
+ void first_truncate_QString() { first_impl<QString>(); }
+ void first_truncate_QStringView_data() { first_data(); }
+ void first_truncate_QStringView() { first_impl<QStringView>(); }
+ void first_truncate_QLatin1String_data() { first_data(); }
+ void first_truncate_QLatin1String() { first_impl<QLatin1String>(); }
+ void first_truncate_QUtf8StringView_data() { first_data(); }
+ void first_truncate_QUtf8StringView() { first_impl<QUtf8StringView>(); }
+ void first_truncate_QAnyStringViewUsingL1_data() { first_data(); }
+ void first_truncate_QAnyStringViewUsingL1() { first_impl<QAnyStringViewUsingL1>(); }
+ void first_truncate_QAnyStringViewUsingU8_data() { first_data(); }
+ void first_truncate_QAnyStringViewUsingU8() { first_impl<QAnyStringViewUsingU8>(); }
+ void first_truncate_QAnyStringViewUsingU16_data() { first_data(); }
+ void first_truncate_QAnyStringViewUsingU16() { first_impl<QAnyStringViewUsingU16>(); }
+ void first_truncate_QByteArray_data() { first_data(); }
+ void first_truncate_QByteArray() { first_impl<QByteArray>(); }
+ void first_truncate_QByteArrayView_data() { first_data(); }
+ void first_truncate_QByteArrayView() { first_impl<QByteArrayView>(); }
+
+ void last_QString_data() { last_data(); }
+ void last_QString() { last_impl<QString>(); }
+ void last_QStringView_data() { last_data(); }
+ void last_QStringView() { last_impl<QStringView>(); }
+ void last_QLatin1String_data() { last_data(); }
+ void last_QLatin1String() { last_impl<QLatin1String>(); }
+ void last_QUtf8StringView_data() { last_data(); }
+ void last_QUtf8StringView() { last_impl<QUtf8StringView>(); }
+ void last_QAnyStringViewUsingL1_data() { last_data(); }
+ void last_QAnyStringViewUsingL1() { last_impl<QAnyStringViewUsingL1>(); }
+ void last_QAnyStringViewUsingU8_data() { last_data(); }
+ void last_QAnyStringViewUsingU8() { last_impl<QAnyStringViewUsingU8>(); }
+ void last_QAnyStringViewUsingU16_data() { last_data(); }
+ void last_QAnyStringViewUsingU16() { last_impl<QAnyStringViewUsingU16>(); }
+ void last_QByteArray_data() { last_data(); }
+ void last_QByteArray() { last_impl<QByteArray>(); }
+ void last_QByteArrayView_data() { last_data(); }
+ void last_QByteArrayView() { last_impl<QByteArrayView>(); }
+
+ void chop_QString_data() { chop_data(); }
+ void chop_QString() { chop_impl<QString>(); }
+ void chop_QStringView_data() { chop_data(); }
+ void chop_QStringView() { chop_impl<QStringView>(); }
+ void chop_QLatin1String_data() { chop_data(); }
+ void chop_QLatin1String() { chop_impl<QLatin1String>(); }
+ void chop_QUtf8StringView_data() { chop_data(); }
+ void chop_QUtf8StringView() { chop_impl<QUtf8StringView>(); }
+ void chop_QAnyStringViewUsingL1_data() { chop_data(); }
+ void chop_QAnyStringViewUsingL1() { chop_impl<QAnyStringViewUsingL1>(); }
+ void chop_QAnyStringViewUsingU8_data() { chop_data(); }
+ void chop_QAnyStringViewUsingU8() { chop_impl<QAnyStringViewUsingU8>(); }
+ void chop_QAnyStringViewUsingU16_data() { chop_data(); }
+ void chop_QAnyStringViewUsingU16() { chop_impl<QAnyStringViewUsingU16>(); }
+ void chop_QByteArray_data() { chop_data(); }
+ void chop_QByteArray() { chop_impl<QByteArray>(); }
+ void chop_QByteArrayView_data() { chop_data(); }
+ void chop_QByteArrayView() { chop_impl<QByteArrayView>(); }
+
+private:
+ void trimmed_data();
+ template <typename String> void trimmed_impl();
+
+private Q_SLOTS:
+ void trim_trimmed_QString_data() { trimmed_data(); }
+ void trim_trimmed_QString() { trimmed_impl<QString>(); }
+ void trim_trimmed_QStringView_data() { trimmed_data(); }
+ void trim_trimmed_QStringView() { trimmed_impl<QStringView>(); }
+ void trim_trimmed_QLatin1String_data() { trimmed_data(); }
+ void trim_trimmed_QLatin1String() { trimmed_impl<QLatin1String>(); }
+ void trim_trimmed_QByteArray_data() { trimmed_data(); }
+ void trim_trimmed_QByteArray() { trimmed_impl<QByteArray>(); }
+ void trim_trimmed_QByteArrayView_data() { trimmed_data(); }
+ void trim_trimmed_QByteArrayView() { trimmed_impl<QByteArrayView>(); }
+
+private:
+ void toNumber_data();
+ template <typename String> void toNumber_impl();
+ void toNumberWithBases_data();
+ template <typename String> void toNumberWithBases_impl();
+
+private Q_SLOTS:
+ void toNumber_QString_data() { toNumber_data(); }
+ void toNumber_QString() { toNumber_impl<QString>(); }
+ void toNumber_QStringView_data() { toNumber_data(); }
+ void toNumber_QStringView() { toNumber_impl<QStringView>(); }
+ void toNumber_QLatin1String_data() { toNumber_data(); }
+ void toNumber_QLatin1String() { toNumber_impl<QLatin1String>(); }
+ void toNumber_QByteArray_data() { toNumber_data(); }
+ void toNumber_QByteArray() { toNumber_impl<QByteArray>(); }
+ void toNumber_QByteArrayView_data() { toNumber_data(); }
+ void toNumber_QByteArrayView() { toNumber_impl<QByteArrayView>(); }
+
+ void toNumberWithBases_QString_data() { toNumberWithBases_data(); }
+ void toNumberWithBases_QString() { toNumberWithBases_impl<QString>(); }
+ void toNumberWithBases_QStringView_data() { toNumberWithBases_data(); }
+ void toNumberWithBases_QStringView() { toNumberWithBases_impl<QStringView>(); }
+ void toNumberWithBases_QLatin1String_data() { toNumberWithBases_data(); }
+ void toNumberWithBases_QLatin1String() { toNumberWithBases_impl<QLatin1String>(); }
+ void toNumberWithBases_QByteArray_data() { toNumberWithBases_data(); }
+ void toNumberWithBases_QByteArray() { toNumberWithBases_impl<QByteArray>(); }
+ void toNumberWithBases_QByteArrayView_data() { toNumberWithBases_data(); }
+ void toNumberWithBases_QByteArrayView() { toNumberWithBases_impl<QByteArrayView>(); }
+
+private:
+ void count_data();
+ template<typename Haystack, typename Needle>
+ void count_impl();
+
+private Q_SLOTS:
+ void count_QString_QString_data() { count_data(); }
+ void count_QString_QString() { count_impl<QString, QString>(); }
+ void count_QString_QLatin1String_data() { count_data(); }
+ void count_QString_QLatin1String() { count_impl<QString, QLatin1String>(); }
+ void count_QString_QStringView_data() { count_data(); }
+ void count_QString_QStringView() { count_impl<QString, QStringView>(); }
+ void count_QString_QChar_data() { count_data(); }
+ void count_QString_QChar() { count_impl<QString, QChar>(); }
+ void count_QString_char16_t_data() { count_data(); }
+ void count_QString_char16_t() { count_impl<QString, char16_t>(); }
+
+ void count_QStringView_QString_data() { count_data(); }
+ void count_QStringView_QString() { count_impl<QStringView, QString>(); }
+ void count_QStringView_QLatin1String_data() { count_data(); }
+ void count_QStringView_QLatin1String() { count_impl<QStringView, QLatin1String>(); }
+ void count_QStringView_QStringView_data() { count_data(); }
+ void count_QStringView_QStringView() { count_impl<QStringView, QStringView>(); }
+ void count_QStringView_QChar_data() { count_data(); }
+ void count_QStringView_QChar() { count_impl<QStringView, QChar>(); }
+ void count_QStringView_char16_t_data() { count_data(); }
+ void count_QStringView_char16_t() { count_impl<QStringView, char16_t>(); }
+
+ void count_QLatin1String_QString_data() { count_data(); }
+ void count_QLatin1String_QString() { count_impl<QLatin1String, QString>(); }
+ void count_QLatin1String_QLatin1String_data() { count_data(); }
+ void count_QLatin1String_QLatin1String() { count_impl<QLatin1String, QLatin1String>(); }
+ void count_QLatin1String_QStringView_data() { count_data(); }
+ void count_QLatin1String_QStringView() { count_impl<QLatin1String, QStringView>(); }
+ void count_QLatin1String_QChar_data() { count_data(); }
+ void count_QLatin1String_QChar() { count_impl<QLatin1String, QChar>(); }
+ void count_QLatin1String_char16_t_data() { count_data(); }
+ void count_QLatin1String_char16_t() { count_impl<QLatin1String, char16_t>(); }
+ void count_QLatin1String_QLatin1Char_data() { count_data(); }
+ void count_QLatin1String_QLatin1Char() { count_impl<QLatin1String, QLatin1Char>(); }
+
+ //
+ // UTF-16-only checks:
+ //
+private:
+
+ void toLocal8Bit_data();
+ template <typename String> void toLocal8Bit_impl();
+
+ void toLatin1_data();
+ template <typename String> void toLatin1_impl();
+
+ void toUtf8_data();
+ template <typename String> void toUtf8_impl();
+
+ void toUcs4_data();
+ template <typename String> void toUcs4_impl();
+
+private Q_SLOTS:
+
+ void toLocal8Bit_QString_data() { toLocal8Bit_data(); }
+ void toLocal8Bit_QString() { toLocal8Bit_impl<QString>(); }
+ void toLocal8Bit_QStringView_data() { toLocal8Bit_data(); }
+ void toLocal8Bit_QStringView() { toLocal8Bit_impl<QStringView>(); }
+
+ void toLatin1_QString_data() { toLatin1_data(); }
+ void toLatin1_QString() { toLatin1_impl<QString>(); }
+ void toLatin1_QStringView_data() { toLatin1_data(); }
+ void toLatin1_QStringView() { toLatin1_impl<QStringView>(); }
+
+ void toUtf8_QString_data() { toUtf8_data(); }
+ void toUtf8_QString() { toUtf8_impl<QString>(); }
+ void toUtf8_QStringView_data() { toUtf8_data(); }
+ void toUtf8_QStringView() { toUtf8_impl<QStringView>(); }
+
+ void toUcs4_QString_data() { toUcs4_data(); }
+ void toUcs4_QString() { toUcs4_impl<QString>(); }
+ void toUcs4_QStringView_data() { toUcs4_data(); }
+ void toUcs4_QStringView() { toUcs4_impl<QStringView>(); }
+
+private:
+ template <typename Haystack, typename Needle> void indexOf_impl() const;
+ void indexOf_data(bool rhsHasVariableLength = true);
+
+private Q_SLOTS:
+ // test all combinations of {QString, QLatin1String, QStringView} x {QString, QLatin1String, QStringView, QChar, char16_t}:
+ void indexOf_QString_QString_data() { indexOf_data(); }
+ void indexOf_QString_QString() { indexOf_impl<QString, QString>(); }
+ void indexOf_QString_QLatin1String_data() { indexOf_data(); }
+ void indexOf_QString_QLatin1String() { indexOf_impl<QString, QLatin1String>(); }
+ void indexOf_QString_QStringView_data() { indexOf_data(); }
+ void indexOf_QString_QStringView() { indexOf_impl<QString, QStringView>(); }
+ void indexOf_QString_QChar_data() { indexOf_data(false); }
+ void indexOf_QString_QChar() { indexOf_impl<QString, QChar>(); }
+ void indexOf_QString_char16_t_data() { indexOf_data(false); }
+ void indexOf_QString_char16_t() { indexOf_impl<QString, char16_t>(); }
+
+ void indexOf_QLatin1String_QString_data() { indexOf_data(); }
+ void indexOf_QLatin1String_QString() { indexOf_impl<QLatin1String, QString>(); }
+ void indexOf_QLatin1String_QLatin1String_data() { indexOf_data(); }
+ void indexOf_QLatin1String_QLatin1String() { indexOf_impl<QLatin1String, QLatin1String>(); }
+ void indexOf_QLatin1String_QStringView_data() { indexOf_data(); }
+ void indexOf_QLatin1String_QStringView() { indexOf_impl<QLatin1String, QStringView>(); }
+ void indexOf_QLatin1String_QChar_data() { indexOf_data(false); }
+ void indexOf_QLatin1String_QChar() { indexOf_impl<QLatin1String, QChar>(); }
+ void indexOf_QLatin1String_char16_t_data() { indexOf_data(false); }
+ void indexOf_QLatin1String_char16_t() { indexOf_impl<QLatin1String, char16_t>(); }
+ void indexOf_QLatin1String_QLatin1Char_data() { indexOf_data(false); }
+ void indexOf_QLatin1String_QLatin1Char() { indexOf_impl<QLatin1String, QLatin1Char>(); }
+
+ void indexOf_QStringView_QString_data() { indexOf_data(); }
+ void indexOf_QStringView_QString() { indexOf_impl<QStringView, QString>(); }
+ void indexOf_QStringView_QLatin1String_data() { indexOf_data(); }
+ void indexOf_QStringView_QLatin1String() { indexOf_impl<QStringView, QLatin1String>(); }
+ void indexOf_QStringView_QStringView_data() { indexOf_data(); }
+ void indexOf_QStringView_QStringView() { indexOf_impl<QStringView, QStringView>(); }
+ void indexOf_QStringView_QChar_data() { indexOf_data(false); }
+ void indexOf_QStringView_QChar() { indexOf_impl<QStringView, QChar>(); }
+ void indexOf_QStringView_char16_t_data() { indexOf_data(false); }
+ void indexOf_QStringView_char16_t() { indexOf_impl<QStringView, char16_t>(); }
+
+private:
+ template <typename Haystack, typename Needle> void contains_impl() const;
+ void contains_data(bool rhsHasVariableLength = true);
+
+private Q_SLOTS:
+ // test all combinations of {QString, QLatin1String, QStringView} x {QString, QLatin1String, QStringView, QChar, char16_t}:
+ void contains_QString_QString_data() { contains_data(); }
+ void contains_QString_QString() { contains_impl<QString, QString>(); }
+ void contains_QString_QLatin1String_data() { contains_data(); }
+ void contains_QString_QLatin1String() { contains_impl<QString, QLatin1String>(); }
+ void contains_QString_QStringView_data() { contains_data(); }
+ void contains_QString_QStringView() { contains_impl<QString, QStringView>(); }
+ void contains_QString_QChar_data() { contains_data(false); }
+ void contains_QString_QChar() { contains_impl<QString, QChar>(); }
+ void contains_QString_char16_t_data() { contains_data(false); }
+ void contains_QString_char16_t() { contains_impl<QString, char16_t>(); }
+
+ void contains_QLatin1String_QString_data() { contains_data(); }
+ void contains_QLatin1String_QString() { contains_impl<QLatin1String, QString>(); }
+ void contains_QLatin1String_QLatin1String_data() { contains_data(); }
+ void contains_QLatin1String_QLatin1String() { contains_impl<QLatin1String, QLatin1String>(); }
+ void contains_QLatin1String_QStringView_data() { contains_data(); }
+ void contains_QLatin1String_QStringView() { contains_impl<QLatin1String, QStringView>(); }
+ void contains_QLatin1String_QChar_data() { contains_data(false); }
+ void contains_QLatin1String_QChar() { contains_impl<QLatin1String, QChar>(); }
+ void contains_QLatin1String_char16_t_data() { contains_data(false); }
+ void contains_QLatin1String_char16_t() { contains_impl<QLatin1String, char16_t>(); }
+ void contains_QLatin1String_QLatin1Char_data() { contains_data(false); }
+ void contains_QLatin1String_QLatin1Char() { contains_impl<QLatin1String, QLatin1Char>(); }
+
+ void contains_QStringView_QString_data() { contains_data(); }
+ void contains_QStringView_QString() { contains_impl<QStringView, QString>(); }
+ void contains_QStringView_QLatin1String_data() { contains_data(); }
+ void contains_QStringView_QLatin1String() { contains_impl<QStringView, QLatin1String>(); }
+ void contains_QStringView_QStringView_data() { contains_data(); }
+ void contains_QStringView_QStringView() { contains_impl<QStringView, QStringView>(); }
+ void contains_QStringView_QChar_data() { contains_data(false); }
+ void contains_QStringView_QChar() { contains_impl<QStringView, QChar>(); }
+ void contains_QStringView_char16_t_data() { contains_data(false); }
+ void contains_QStringView_char16_t() { contains_impl<QStringView, char16_t>(); }
+
+private:
+ template <typename Haystack, typename Needle> void lastIndexOf_impl() const;
+ void lastIndexOf_data(bool rhsHasVariableLength = true);
+
+private Q_SLOTS:
+ // test all combinations of {QString, QLatin1String, QStringView} x {QString, QLatin1String, QStringView, QChar, char16_t}:
+ void lastIndexOf_QString_QString_data() { lastIndexOf_data(); }
+ void lastIndexOf_QString_QString() { lastIndexOf_impl<QString, QString>(); }
+ void lastIndexOf_QString_QLatin1String_data() { lastIndexOf_data(); }
+ void lastIndexOf_QString_QLatin1String() { lastIndexOf_impl<QString, QLatin1String>(); }
+ void lastIndexOf_QString_QStringView_data() { lastIndexOf_data(); }
+ void lastIndexOf_QString_QStringView() { lastIndexOf_impl<QString, QStringView>(); }
+ void lastIndexOf_QString_QChar_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QString_QChar() { lastIndexOf_impl<QString, QChar>(); }
+ void lastIndexOf_QString_char16_t_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QString_char16_t() { lastIndexOf_impl<QString, char16_t>(); }
+
+ void lastIndexOf_QLatin1String_QString_data() { lastIndexOf_data(); }
+ void lastIndexOf_QLatin1String_QString() { lastIndexOf_impl<QLatin1String, QString>(); }
+ void lastIndexOf_QLatin1String_QLatin1String_data() { lastIndexOf_data(); }
+ void lastIndexOf_QLatin1String_QLatin1String() { lastIndexOf_impl<QLatin1String, QLatin1String>(); }
+ void lastIndexOf_QLatin1String_QStringView_data() { lastIndexOf_data(); }
+ void lastIndexOf_QLatin1String_QStringView() { lastIndexOf_impl<QLatin1String, QStringView>(); }
+ void lastIndexOf_QLatin1String_QChar_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QLatin1String_QChar() { lastIndexOf_impl<QLatin1String, QChar>(); }
+ void lastIndexOf_QLatin1String_char16_t_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QLatin1String_char16_t() { lastIndexOf_impl<QLatin1String, char16_t>(); }
+ void lastIndexOf_QLatin1String_QLatin1Char_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QLatin1String_QLatin1Char() { lastIndexOf_impl<QLatin1String, QLatin1Char>(); }
+
+ void lastIndexOf_QStringView_QString_data() { lastIndexOf_data(); }
+ void lastIndexOf_QStringView_QString() { lastIndexOf_impl<QStringView, QString>(); }
+ void lastIndexOf_QStringView_QLatin1String_data() { lastIndexOf_data(); }
+ void lastIndexOf_QStringView_QLatin1String() { lastIndexOf_impl<QStringView, QLatin1String>(); }
+ void lastIndexOf_QStringView_QStringView_data() { lastIndexOf_data(); }
+ void lastIndexOf_QStringView_QStringView() { lastIndexOf_impl<QStringView, QStringView>(); }
+ void lastIndexOf_QStringView_QChar_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QStringView_QChar() { lastIndexOf_impl<QStringView, QChar>(); }
+ void lastIndexOf_QStringView_char16_t_data() { lastIndexOf_data(false); }
+ void lastIndexOf_QStringView_char16_t() { lastIndexOf_impl<QStringView, char16_t>(); }
+
+private:
+ void indexOf_contains_lastIndexOf_count_regexp_data();
+ template <typename String> void indexOf_contains_lastIndexOf_count_regexp_impl() const;
+
+private Q_SLOTS:
+ void indexOf_regexp_QString_data() { indexOf_contains_lastIndexOf_count_regexp_data(); }
+ void indexOf_regexp_QString() { indexOf_contains_lastIndexOf_count_regexp_impl<QString>(); }
+ void indexOf_regexp_QStringView_data() { indexOf_contains_lastIndexOf_count_regexp_data(); }
+ void indexOf_regexp_QStringView() { indexOf_contains_lastIndexOf_count_regexp_impl<QStringView>(); }
+
+private:
+ void isValidUtf8_data();
+ template<typename String>
+ void isValidUtf8_impl() const;
+
+private Q_SLOTS:
+ void isValidUtf8_QByteArray_data() { isValidUtf8_data(); }
+ void isValidUtf8_QByteArray() { isValidUtf8_impl<QByteArray>(); }
+ void isValidUtf8_QByteArrayView_data() { isValidUtf8_data(); }
+ void isValidUtf8_QByteArrayView() { isValidUtf8_impl<QByteArrayView>(); }
+ void isValidUtf8_QUtf8StringView_data() { isValidUtf8_data(); }
+ void isValidUtf8_QUtf8StringView() { isValidUtf8_impl<QUtf8StringView>(); }
+};
+
+namespace help {
+
+template <typename T> constexpr qsizetype size(const T &s) { return qsizetype(s.size()); }
+
+template <> constexpr qsizetype size(const QChar&) { return 1; }
+template <> constexpr qsizetype size(const QLatin1Char&) { return 1; }
+template <> constexpr qsizetype size(const char16_t&) { return 1; }
+} // namespace help
+
+namespace {
+
+auto overload_s_a(const QString &s) { return s; }
+Q_WEAK_OVERLOAD
+auto overload_s_a(QAnyStringView s) { return s; }
+
+auto overload_sr_a(QString &&s) { return std::move(s); }
+Q_WEAK_OVERLOAD
+auto overload_sr_a(QAnyStringView s) { return s; }
+
+Q_WEAK_OVERLOAD
+auto overload_a_s(const QString &s) { return s; }
+auto overload_a_s(QAnyStringView s) { return s; }
+
+Q_WEAK_OVERLOAD
+auto overload_a_sr(QString &&s) { return std::move(s); }
+auto overload_a_sr(QAnyStringView s) { return s; }
+
+auto overload_s_v(const QString &s) { return s; }
+auto overload_s_v(QStringView s) { return s; }
+
+auto overload_sr_v(QString &&s) { return std::move(s); }
+auto overload_sr_v(QStringView s) { return s; }
+
+} // unnamed namespace
+
+template<typename T>
+void tst_QStringApiSymmetry::overload()
+{
+ // compile-only test:
+ //
+ // check the common overload sets defined above to be free of ambiguities
+ // for arguments of type T
+
+ QT_WARNING_PUSH
+ // GCC complains about "t" and "ct"
+ QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
+
+ using CT = const T;
+
+ T t = {};
+ CT ct = {};
+
+ overload_s_a(t);
+ overload_s_a(ct);
+ if constexpr (!std::is_array_v<T>) {
+ overload_s_a(T());
+ overload_s_a(CT());
+ }
+
+ overload_sr_a(t);
+ overload_sr_a(ct);
+ if constexpr (!std::is_array_v<T>) {
+ overload_sr_a(T());
+ overload_sr_a(CT());
+ }
+
+ overload_a_s(t);
+ overload_a_s(ct);
+ if constexpr (!std::is_array_v<T>) {
+ overload_a_s(T());
+ overload_a_s(CT());
+ }
+
+ overload_a_sr(t);
+ overload_a_sr(ct);
+ if constexpr (!std::is_array_v<T>) {
+ overload_a_sr(T());
+ overload_a_sr(CT());
+ }
+
+ if constexpr (std::is_convertible_v<T, QStringView> || std::is_convertible_v<T, QString>) {
+ overload_s_v(t);
+ overload_s_v(ct);
+ if constexpr (!std::is_array_v<T>) {
+ overload_s_v(T());
+ overload_s_v(CT());
+ }
+
+ overload_sr_v(t);
+ overload_sr_v(ct);
+ if constexpr (!std::is_array_v<T>) {
+ overload_sr_v(T());
+ overload_sr_v(CT());
+ }
+ }
+ QT_WARNING_POP
+}
+
+void tst_QStringApiSymmetry::overload_special()
+{
+ auto check = [](auto result, auto expected) {
+ static_assert(std::is_same_v<decltype(result), decltype(expected)>);
+ };
+
+ {
+#define rvalue QStringLiteral("hello")
+ auto lvalue = rvalue;
+ auto builder = [&] { return lvalue % ""; };
+
+ // check that QString/Builder go to the QString overload in a_s(r):
+
+ check(overload_a_s(lvalue), QString());
+ check(overload_a_s(rvalue), QString());
+ check(overload_a_s(builder()), QAnyStringView()); // weak overloads must match exactly
+ check(overload_a_s(QString(builder())), QString());
+
+ check(overload_a_sr(lvalue), QAnyStringView()); // lvalue can't bind to rvalue ref
+ check(overload_a_sr(rvalue), QString());
+ check(overload_a_sr(builder()), QAnyStringView());
+ check(overload_a_sr(QString(builder())), QString());
+
+ // check that everything goes to the QString overload in s(r)_a:
+ // exception: u""
+
+ check(overload_s_a(lvalue), QString());
+ check(overload_s_a(rvalue), QString());
+ check(overload_s_a(builder()), QString());
+ check(overload_s_a(""), QString());
+ check(overload_s_a(u""), QAnyStringView());
+ check(overload_s_a(u8""), QString());
+ check(overload_s_a(QLatin1String("")), QString());
+
+ check(overload_sr_a(lvalue), QAnyStringView()); // lvalues don't bind to rvalue refs
+ check(overload_sr_a(rvalue), QString());
+ check(overload_sr_a(builder()), QString());
+ check(overload_sr_a(""), QString());
+ check(overload_sr_a(u""), QAnyStringView());
+ check(overload_sr_a(u8""), QString());
+ check(overload_sr_a(QLatin1String("")), QString());
+#undef rvalue
+ }
+}
+
+void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty)
+{
+ QTest::addColumn<QStringView>("lhsUnicode");
+ QTest::addColumn<QLatin1String>("lhsLatin1");
+ QTest::addColumn<QStringView>("rhsUnicode");
+ QTest::addColumn<QLatin1String>("rhsLatin1");
+ QTest::addColumn<int>("caseSensitiveCompareResult");
+ QTest::addColumn<int>("caseInsensitiveCompareResult");
+
+ if (hasConceptOfNullAndEmpty) {
+ QTest::newRow("null <> null") << QStringView() << QLatin1String()
+ << QStringView() << QLatin1String()
+ << 0 << 0;
+ static const QString empty("");
+ QTest::newRow("null <> empty") << QStringView() << QLatin1String()
+ << QStringView(empty) << QLatin1String("")
+ << 0 << 0;
+ QTest::newRow("empty <> null") << QStringView(empty) << QLatin1String("")
+ << QStringView() << QLatin1String()
+ << 0 << 0;
+ }
+
+#define ROW(lhs, rhs, caseless) \
+ do { \
+ static const QString pinned[] = { \
+ QString(QLatin1String(lhs)), \
+ QString(QLatin1String(rhs)), \
+ }; \
+ QTest::newRow(qUtf8Printable(QLatin1String("'" lhs "' <> '" rhs "': "))) \
+ << QStringView(pinned[0]) << QLatin1String(lhs) \
+ << QStringView(pinned[1]) << QLatin1String(rhs) \
+ << sign(qstrcmp(lhs, rhs)) << caseless; \
+ } while (false)
+#define ASCIIROW(lhs, rhs) ROW(lhs, rhs, sign(qstricmp(lhs, rhs)))
+ ASCIIROW("", "0");
+ ASCIIROW("0", "");
+ ASCIIROW("0", "1");
+ ASCIIROW("0", "0");
+ ASCIIROW("10", "0");
+ ASCIIROW("01", "1");
+ ASCIIROW("e", "e");
+ ASCIIROW("e", "E");
+ ROW("\xE4", "\xE4", 0); // ä <> ä
+ ROW("\xE4", "\xC4", 0); // ä <> Ä
+#undef ROW
+}
+
+template <typename String> String detached(String s)
+{
+ if (!s.isNull()) { // detaching loses nullness, but we need to preserve it
+ auto d = s.data();
+ Q_UNUSED(d);
+ }
+ return s;
+}
+
+template <class Str> Str make(const QString &s);
+template <> QString make(const QString &s) { return s; }
+template <> QStringView make(const QString &s) { return s; }
+
+template <class Str> Str make(QStringView sf, QLatin1String l1, const QByteArray &u8);
+
+#define MAKE(Which) \
+ template <> Which make([[maybe_unused]] QStringView sv, \
+ [[maybe_unused]] QLatin1String l1, \
+ [[maybe_unused]] const QByteArray &u8) \
+ /*end*/
+MAKE(QChar) { return sv.isEmpty() ? QChar() : sv.at(0); }
+MAKE(char16_t) { return sv.isEmpty() ? char16_t() : char16_t{sv.at(0).unicode()}; }
+MAKE(QLatin1Char) { return l1.isEmpty() ? QLatin1Char('\0') : l1.at(0); }
+MAKE(QString) { return sv.toString(); }
+MAKE(QStringView) { return sv; }
+MAKE(QLatin1String) { return l1; }
+MAKE(QByteArray) { return u8; }
+MAKE(QByteArrayView) { return u8; }
+MAKE(const char *) { return u8.data(); }
+MAKE(const char16_t *) { return sv.utf16(); } // assumes `sv` doesn't represent a substring
+MAKE(std::u16string) { return sv.toString().toStdU16String(); }
+MAKE(QUtf8StringView) { return u8; }
+MAKE(QAnyStringViewUsingL1) { return {QAnyStringView{l1}}; }
+MAKE(QAnyStringViewUsingU8) { return {QAnyStringView{u8}}; }
+MAKE(QAnyStringViewUsingU16) { return {QAnyStringView{sv}}; }
+#undef MAKE
+
+// Some types have ASCII-only case-insensitive compare, but are handled as containing
+// UTF-8 when implicitly converted to QString.
+template <typename> constexpr bool is_bytearray_like_v = false;
+template <> constexpr bool is_bytearray_like_v<const char *> = true;
+template <> constexpr bool is_bytearray_like_v<QByteArray> = true;
+template <> constexpr bool is_bytearray_like_v<QByteArrayView> = true;
+
+template <typename LHS, typename RHS>
+constexpr bool has_nothrow_member_compare_v = is_bytearray_like_v<LHS> == is_bytearray_like_v<RHS>;
+
+template <typename LHS, typename RHS>
+void tst_QStringApiSymmetry::compare_impl() const
+{
+ QFETCH(QStringView, lhsUnicode);
+ QFETCH(QLatin1String, lhsLatin1);
+ QFETCH(QStringView, rhsUnicode);
+ QFETCH(QLatin1String, rhsLatin1);
+ QFETCH(int, caseSensitiveCompareResult);
+ QFETCH(const int, caseInsensitiveCompareResult);
+
+ const auto lhsU8 = lhsUnicode.toUtf8();
+ const auto rhsU8 = rhsUnicode.toUtf8();
+
+ const auto lhs = make<LHS>(lhsUnicode, lhsLatin1, lhsU8);
+ const auto rhs = make<RHS>(rhsUnicode, rhsLatin1, rhsU8);
+
+ auto icResult = sign(
+ QAnyStringView::compare(QAnyStringView(lhs), QAnyStringView(rhs), Qt::CaseInsensitive));
+ QCOMPARE_EQ(icResult, caseInsensitiveCompareResult);
+
+ auto scResult = sign(
+ QAnyStringView::compare(QAnyStringView(lhs), QAnyStringView(rhs), Qt::CaseSensitive));
+ QCOMPARE_EQ(scResult, caseSensitiveCompareResult);
+
+#define CHECK(op) \
+ do { \
+ /* comment out the noexcept check for now, as we first need to sort all the overloads anew */ \
+ if (false) { \
+ if constexpr (!is_fake_comparator_v<LHS, RHS>) \
+ QVERIFY(noexcept(lhs op rhs)); \
+ } \
+ if (caseSensitiveCompareResult op 0) \
+ QVERIFY(lhs op rhs); \
+ else \
+ QVERIFY(!(lhs op rhs)); \
+ } while (false)
+
+ CHECK(==);
+ CHECK(!=);
+ CHECK(<);
+ CHECK(>);
+ CHECK(<=);
+ CHECK(>=);
+#undef CHECK
+ // Test that all string-like types implemente compareThreeWay() as a friend
+ // function.
+ const Qt::strong_ordering expectedOrdering =
+ Qt::compareThreeWay(caseSensitiveCompareResult, 0);
+ QCOMPARE_EQ(qCompareThreeWay(lhs, rhs), expectedOrdering);
+}
+
+template <typename LHS, typename RHS>
+void tst_QStringApiSymmetry::member_compare_impl() const
+{
+ QFETCH(QStringView, lhsUnicode);
+ QFETCH(QLatin1String, lhsLatin1);
+ QFETCH(QStringView, rhsUnicode);
+ QFETCH(QLatin1String, rhsLatin1);
+ QFETCH(const int, caseSensitiveCompareResult);
+ QFETCH(const int, caseInsensitiveCompareResult);
+
+ const auto lhsU8 = lhsUnicode.toUtf8();
+ const auto rhsU8 = rhsUnicode.toUtf8();
+
+ const auto lhs = make<LHS>(lhsUnicode, lhsLatin1, lhsU8);
+ const auto rhs = make<RHS>(rhsUnicode, rhsLatin1, rhsU8);
+
+ if constexpr (has_nothrow_member_compare_v<LHS, RHS>)
+ QVERIFY(noexcept(lhs.compare(rhs, Qt::CaseSensitive)));
+
+ QCOMPARE_EQ(sign(lhs.compare(rhs)), caseSensitiveCompareResult);
+ QCOMPARE_EQ(sign(lhs.compare(rhs, Qt::CaseSensitive)), caseSensitiveCompareResult);
+ if (is_bytearray_like_v<LHS> && is_bytearray_like_v<RHS> &&
+ caseSensitiveCompareResult != caseInsensitiveCompareResult &&
+ (!QtPrivate::isAscii(lhsUnicode) || !QtPrivate::isAscii(rhsUnicode)))
+ {
+ QEXPECT_FAIL("", "The types don't support non-ASCII case-insensitive comparison", Continue);
+ }
+ QCOMPARE_EQ(sign(lhs.compare(rhs, Qt::CaseInsensitive)), caseInsensitiveCompareResult);
+}
+
+void tst_QStringApiSymmetry::localeAwareCompare_data()
+{
+ QTest::addColumn<QByteArray>("locale");
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<QString>("s2");
+ QTest::addColumn<int>("result");
+
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || QT_CONFIG(icu)
+ // Although the test sets LC_ALL (and adds a suffix to wanted) test
+ // LC_COLLATE because setlocale(LC_ALL, nullptr) encodes the whole locale,
+ // it's not simply the value of LC_ALL. We need our own copy of the reported
+ // value, as later setlocale() calls may stomp the value:
+ const QByteArray current(setlocale(LC_COLLATE, nullptr));
+ const auto canTest = [current](const char *wanted) {
+# if QT_CONFIG(icu)
+ // ICU will correctly use en when relevant environment variables are set
+ // to en.UTF-8, but setlocale() reports that as C, whose sort order is
+ // simpler. Only believe we can run C tests if the environment variables
+ // (which, conveniently, QLocale::system()'s Unix backend uses) say it
+ // really is. Conversely, don't reject "en_US" just because setlocale()
+ // misdescribes it.
+ if (current == "C") {
+ const QString sys = QLocale::system().name();
+ if (wanted == current ? sys == u"C" : sys.startsWith(wanted))
+ return true;
+ qDebug("Skipping %s test-cases as we can only test in locale %s (seen as C)",
+ wanted, sys.toUtf8().constData());
+ return false;
+ }
+# endif
+ if (current.startsWith(wanted))
+ return true;
+# ifdef Q_OS_WIN
+ // Unhelpfully, MS doesn't deign to use the usual format of locale tags,
+ // but expands the tag names to full names (in English):
+ const auto want = QLocale(QLatin1String(wanted));
+ if (current.startsWith(
+ QString(QLocale::languageToString(want.language()) + QChar('_')
+ + QLocale::territoryToString(want.territory())).toLocal8Bit())) {
+ return true;
+ }
+# endif
+ qDebug("Skipping %s test-cases as we can only test in locale %s (seen as %s)",
+ wanted, QLocale::system().name().toUtf8().constData(), current.data());
+ return false;
+ };
+#else
+ const auto canTest = [](const char *wanted) {
+ return QLocale(wanted) == QLocale::c() || QLocale(wanted) == QLocale::system().collation();
+ };
+#endif
+ // Update tailpiece's max-value for this if you add a new locale group
+ int countGroups = 0;
+
+ // Compare decomposed and composed form
+ if (canTest("en_US")) {
+ // From ES6 test262 test suite (built-ins/String/prototype/localeCompare/15.5.4.9_CE.js).
+ // The test cases boil down to code like this:
+ // console.log("\u1111\u1171\u11B6".localeCompare("\ud4db")
+
+ // example from Unicode 5.0, section 3.7, definition D70
+ QTest::newRow("normalize1")
+ << QByteArray("en_US")
+ << QString::fromUtf8("o\xCC\x88")
+ << QString::fromUtf8("\xC3\xB6") << 0;
+ // examples from Unicode 5.0, chapter 3.11
+ QTest::newRow("normalize2")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xC3\xA4\xCC\xA3")
+ << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
+ QTest::newRow("normalize3")
+ << QByteArray("en_US")
+ << QString::fromUtf8("a\xCC\x88\xCC\xA3")
+ << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
+ QTest::newRow("normalize4")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88")
+ << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
+ QTest::newRow("normalize5")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xC3\xA4\xCC\x86")
+ << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0;
+ QTest::newRow("normalize6")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xC4\x83\xCC\x88")
+ << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0;
+ // example from Unicode 5.0, chapter 3.12
+ QTest::newRow("normalize7")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6")
+ << QString::fromUtf8("\xED\x93\x9B") << 0;
+ // examples from UTS 10, Unicode Collation Algorithm
+ QTest::newRow("normalize8")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE2\x84\xAB")
+ << QString::fromUtf8("\xC3\x85") << 0;
+ QTest::newRow("normalize9")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE2\x84\xAB")
+ << QString::fromUtf8("A\xCC\x8A") << 0;
+ QTest::newRow("normalize10")
+ << QByteArray("en_US")
+ << QString::fromUtf8("x\xCC\x9B\xCC\xA3")
+ << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0;
+ QTest::newRow("normalize11")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xBB\xB1")
+ << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0;
+ QTest::newRow("normalize12")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xBB\xB1")
+ << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0;
+ QTest::newRow("normalize13")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xBB\xB1")
+ << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0;
+ QTest::newRow("normalize14")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xBB\xB1")
+ << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0;
+ // examples from UAX 15, Unicode Normalization Forms
+ QTest::newRow("normalize15")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xC3\x87")
+ << QString::fromUtf8("C\xCC\xA7") << 0;
+ QTest::newRow("normalize16")
+ << QByteArray("en_US")
+ << QString::fromUtf8("q\xCC\x87\xCC\xA3")
+ << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0;
+ QTest::newRow("normalize17")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xEA\xB0\x80")
+ << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0;
+ QTest::newRow("normalize18")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE2\x84\xAB")
+ << QString::fromUtf8("A\xCC\x8A") << 0;
+ QTest::newRow("normalize19")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE2\x84\xA6")
+ << QString::fromUtf8("\xCE\xA9") << 0;
+ QTest::newRow("normalize20")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xC3\x85")
+ << QString::fromUtf8("A\xCC\x8A") << 0;
+ QTest::newRow("normalize21")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xC3\xB4")
+ << QString::fromUtf8("o\xCC\x82") << 0;
+ QTest::newRow("normalize22")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xB9\xA9")
+ << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0;
+ QTest::newRow("normalize23")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3")
+ << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0;
+ QTest::newRow("normalize24")
+ << QByteArray("en_US")
+ << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3")
+ << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0;
+ QTest::newRow("normalize25")
+ << QByteArray("en_US")
+ << QString::fromUtf8("q\xCC\x87\xCC\xA3")
+ << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0;
+
+ QTest::newRow("en@5.gt.4") << QByteArray("en_US") << QString("5") << QString("4") << 1;
+ QTest::newRow("en@4.lt.6") << QByteArray("en_US") << QString("4") << QString("6") << -1;
+ QTest::newRow("en@5.l6.6") << QByteArray("en_US") << QString("5") << QString("6") << -1;
+
+ QTest::newRow("en@null.eq.null") << QByteArray("en_US") << QString() << QString() << 0;
+ QTest::newRow("en@empty.eq.null") << QByteArray("en_US") << QString("") << QString() << 0;
+ QTest::newRow("en@null.lt.non-empty") << QByteArray("en_US") << QString()
+ << QString("test") << -1;
+ QTest::newRow("en@empty.lt.non-empty") << QByteArray("en_US") << QString("")
+ << QString("test") << -1;
+
+ countGroups++;
+ }
+
+ /*
+ The C locale performs simple code-point number comparison of successive
+ characters until if finds a difference. Contrast with Swedish below,
+ particularly the a-umlaut vs a-ring comparison.
+ */
+ if (canTest("C")) {
+ QTest::newRow("C@auml.lt.aring")
+ << QByteArray("C")
+ << QString::fromLatin1("\xe4") // &auml;
+ << QString::fromLatin1("\xe5") << -1;
+ QTest::newRow("C@auml.lt.ouml")
+ << QByteArray("C")
+ << QString::fromLatin1("\xe4")
+ << QString::fromLatin1("\xf6") << -1; // &ouml;
+ QTest::newRow("C.aring.lt.ouml")
+ << QByteArray("C")
+ << QString::fromLatin1("\xe5") // &aring;
+ << QString::fromLatin1("\xf6") << -1;
+
+ countGroups++;
+ }
+
+ /*
+ In Swedish, a with ring above (E5) comes before a with
+ diaresis (E4), which comes before o diaresis (F6), which
+ all come after z.
+ */
+ if (canTest("sv_SE")) {
+ QTest::newRow("swede@aring.lt.auml")
+ << QByteArray("sv_SE")
+ << QString::fromLatin1("\xe5")
+ << QString::fromLatin1("\xe4") << -1;
+ QTest::newRow("swede@auml.lt.ouml")
+ << QByteArray("sv_SE")
+ << QString::fromLatin1("\xe4")
+ << QString::fromLatin1("\xf6") << -1;
+ QTest::newRow("swede.aring.lt.ouml")
+ << QByteArray("sv_SE")
+ << QString::fromLatin1("\xe5")
+ << QString::fromLatin1("\xf6") << -1;
+ QTest::newRow("swede.z.lt.aring")
+ << QByteArray("sv_SE")
+ << QString::fromLatin1("z")
+ << QString::fromLatin1("\xe5") << -1;
+
+ countGroups++;
+ }
+
+ /*
+ In Norwegian, ae (E6) comes before o with stroke (D8), which
+ comes before a with ring above (E5).
+ */
+ if (canTest("nb_NO")) {
+ QTest::newRow("norsk.ae.lt.oslash")
+ << QByteArray("nb_NO")
+ << QString::fromLatin1("\xe6")
+ << QString::fromLatin1("\xd8") << -1;
+ QTest::newRow("norsk.oslash.lt.aring")
+ << QByteArray("nb_NO")
+ << QString::fromLatin1("\xd8")
+ << QString::fromLatin1("\xe5") << -1;
+ QTest::newRow("norsk.ae.lt.aring")
+ << QByteArray("nb_NO")
+ << QString::fromLatin1("\xe6")
+ << QString::fromLatin1("\xe5") << -1;
+
+ countGroups++;
+ }
+
+ /*
+ In German, z comes *after* a with diaresis (E4),
+ which comes before o diaresis (F6).
+ */
+ if (canTest("de_DE")) {
+ QTest::newRow("german.z.gt.auml")
+ << QByteArray("de_DE")
+ << QString::fromLatin1("z")
+ << QString::fromLatin1("\xe4") << 1;
+ QTest::newRow("german.auml.lt.ouml")
+ << QByteArray("de_DE")
+ << QString::fromLatin1("\xe4")
+ << QString::fromLatin1("\xf6") << -1;
+ QTest::newRow("german.z.gt.ouml")
+ << QByteArray("de_DE")
+ << QString::fromLatin1("z")
+ << QString::fromLatin1("\xf6") << 1;
+
+ countGroups++;
+ }
+ // Tell developers how to get all the results (bot don't spam Coin logs):
+ if (countGroups < 5 && !qgetenv("QTEST_ENVIRONMENT").split(' ').contains("ci")) {
+ qDebug(R"(On platforms where this test cannot control the locale used by
+QString::localeAwareCompare(), it only runs test-cases for the locale in use.
+To test thoroughly, it is necessary to run this test repeatedly with each of
+C.UTF-8, en_US.UTF-8, sv_SE.UTF-8, nb_NO.UTF-8 and de_DE.UTF-8 as the system
+locale.)");
+ }
+ if (!countGroups)
+ QSKIP("No data for available locale");
+}
+
+template<typename LHS, typename RHS>
+void tst_QStringApiSymmetry::localeAwareCompare_impl()
+{
+ QFETCH(QByteArray, locale);
+ QFETCH(const QString, s1);
+ QFETCH(const QString, s2);
+ QFETCH(int, result);
+ locale += ".UTF-8"; // So we don't have to repeat it on every data row !
+
+ const QTestLocaleChange::TransientLocale tested(LC_ALL, locale.constData());
+ if (!tested.isValid())
+ QSKIP(QByteArray("Test needs locale " + locale + " installed on this machine").constData());
+
+ const auto lhs = make<LHS>(s1);
+ const auto rhs = make<RHS>(s2);
+
+ // qDebug() << s1.toUtf8().toHex(' ') << "as" << result << "to" << s2.toUtf8().toHex(' ');
+ QCOMPARE_EQ(sign(QString::localeAwareCompare(lhs, rhs)), result);
+}
+
+template<typename LHS, typename RHS>
+void tst_QStringApiSymmetry::member_localeAwareCompare_impl()
+{
+ QFETCH(QByteArray, locale);
+ QFETCH(const QString, s1);
+ QFETCH(const QString, s2);
+ QFETCH(int, result);
+ locale += ".UTF-8"; // So we don't have to repeat it on every data row !
+
+ const QTestLocaleChange::TransientLocale tested(LC_ALL, locale.constData());
+ if (!tested.isValid())
+ QSKIP(QByteArray("Test needs locale " + locale + " installed on this machine").constData());
+
+ const auto lhs = make<LHS>(s1);
+ const auto rhs = make<RHS>(s2);
+
+ // qDebug() << s1.toUtf8().toHex(' ') << "as" << result << "to" << s2.toUtf8().toHex(' ');
+ QCOMPARE_EQ(sign(lhs.localeAwareCompare(rhs)), result);
+}
+
+static QString empty = QLatin1String("");
+static QString null;
+// the tests below rely on the fact that these objects' names match their contents:
+static QString a = QStringLiteral("a");
+static QString A = QStringLiteral("A");
+static QString b = QStringLiteral("b");
+static QString B = QStringLiteral("B");
+static QString c = QStringLiteral("c");
+static QString C = QStringLiteral("C");
+static QString d = QStringLiteral("d");
+static QString D = QStringLiteral("D");
+static QString e = QStringLiteral("e");
+static QString E = QStringLiteral("E");
+static QString f = QStringLiteral("f");
+static QString F = QStringLiteral("F");
+static QString g = QStringLiteral("g");
+static QString G = QStringLiteral("G");
+static QString ab = QStringLiteral("ab");
+static QString aB = QStringLiteral("aB");
+static QString Ab = QStringLiteral("Ab");
+static QString AB = QStringLiteral("AB");
+static QString bc = QStringLiteral("bc");
+static QString bC = QStringLiteral("bC");
+static QString Bc = QStringLiteral("Bc");
+static QString BC = QStringLiteral("BC");
+static QString abc = QStringLiteral("abc");
+static QString abC = QStringLiteral("abC");
+static QString aBc = QStringLiteral("aBc");
+static QString aBC = QStringLiteral("aBC");
+static QString Abc = QStringLiteral("Abc");
+static QString AbC = QStringLiteral("AbC");
+static QString ABc = QStringLiteral("ABc");
+static QString ABC = QStringLiteral("ABC");
+
+void tst_QStringApiSymmetry::startsWith_data(bool rhsHasVariableLength)
+{
+ QTest::addColumn<QStringView>("haystackU16");
+ QTest::addColumn<QLatin1String>("haystackL1");
+ QTest::addColumn<QStringView>("needleU16");
+ QTest::addColumn<QLatin1String>("needleL1");
+ QTest::addColumn<bool>("resultCS");
+ QTest::addColumn<bool>("resultCIS");
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("null ~= ^null") << QStringView() << QLatin1String()
+ << QStringView() << QLatin1String() << true << true;
+ QTest::addRow("empty ~= ^null") << QStringView(empty) << QLatin1String("")
+ << QStringView() << QLatin1String() << true << true;
+ QTest::addRow("a ~= ^null") << QStringView(a) << QLatin1String("a")
+ << QStringView() << QLatin1String() << true << true;
+ QTest::addRow("null ~= ^empty") << QStringView() << QLatin1String()
+ << QStringView(empty) << QLatin1String("") << false << false;
+ QTest::addRow("a ~= ^empty") << QStringView(a) << QLatin1String("a")
+ << QStringView(empty) << QLatin1String("") << true << true;
+ QTest::addRow("empty ~= ^empty") << QStringView(empty) << QLatin1String("")
+ << QStringView(empty) << QLatin1String("") << true << true;
+ }
+ QTest::addRow("null ~= ^a") << QStringView() << QLatin1String()
+ << QStringView(a) << QLatin1String("a") << false << false;
+ QTest::addRow("empty ~= ^a") << QStringView(empty) << QLatin1String("")
+ << QStringView(a) << QLatin1String("a") << false << false;
+
+#define ROW(h, n, cs, cis) \
+ QTest::addRow("%s ~= ^%s", #h, #n) << QStringView(h) << QLatin1String(#h) \
+ << QStringView(n) << QLatin1String(#n) \
+ << bool(cs) << bool(cis)
+ ROW(a, a, 1, 1);
+ ROW(a, A, 0, 1);
+ ROW(a, b, 0, 0);
+
+ if (rhsHasVariableLength)
+ ROW(a, aB, 0, 0);
+
+ ROW(ab, a, 1, 1);
+ if (rhsHasVariableLength) {
+ ROW(ab, ab, 1, 1);
+ ROW(ab, aB, 0, 1);
+ ROW(ab, Ab, 0, 1);
+ }
+ ROW(ab, c, 0, 0);
+
+ if (rhsHasVariableLength)
+ ROW(ab, abc, 0, 0);
+
+ ROW(Abc, c, 0, 0);
+ if (rhsHasVariableLength) {
+ ROW(Abc, ab, 0, 1);
+ ROW(Abc, aB, 0, 1);
+ ROW(Abc, Ab, 1, 1);
+ ROW(Abc, AB, 0, 1);
+ ROW(aBC, ab, 0, 1);
+ ROW(aBC, aB, 1, 1);
+ ROW(aBC, Ab, 0, 1);
+ ROW(aBC, AB, 0, 1);
+ }
+ ROW(ABC, b, 0, 0);
+ ROW(ABC, a, 0, 1);
+#undef ROW
+}
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::startsWith_impl() const
+{
+ QFETCH(const QStringView, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QStringView, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const bool, resultCS);
+ QFETCH(const bool, resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
+ const auto needle = make<Needle>(needleU16, needleL1, needleU8);
+
+ QCOMPARE_EQ(haystack.startsWith(needle), resultCS);
+ QCOMPARE_EQ(haystack.startsWith(needle, Qt::CaseSensitive), resultCS);
+ QCOMPARE_EQ(haystack.startsWith(needle, Qt::CaseInsensitive), resultCIS);
+}
+
+void tst_QStringApiSymmetry::endsWith_data(bool rhsHasVariableLength)
+{
+ QTest::addColumn<QStringView>("haystackU16");
+ QTest::addColumn<QLatin1String>("haystackL1");
+ QTest::addColumn<QStringView>("needleU16");
+ QTest::addColumn<QLatin1String>("needleL1");
+ QTest::addColumn<bool>("resultCS");
+ QTest::addColumn<bool>("resultCIS");
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("null ~= null$") << QStringView() << QLatin1String()
+ << QStringView() << QLatin1String() << true << true;
+ QTest::addRow("empty ~= null$") << QStringView(empty) << QLatin1String("")
+ << QStringView() << QLatin1String() << true << true;
+ QTest::addRow("a ~= null$") << QStringView(a) << QLatin1String("a")
+ << QStringView() << QLatin1String() << true << true;
+ QTest::addRow("null ~= empty$") << QStringView() << QLatin1String()
+ << QStringView(empty) << QLatin1String("") << false << false;
+ QTest::addRow("a ~= empty$") << QStringView(a) << QLatin1String("a")
+ << QStringView(empty) << QLatin1String("") << true << true;
+ QTest::addRow("empty ~= empty$") << QStringView(empty) << QLatin1String("")
+ << QStringView(empty) << QLatin1String("") << true << true;
+ }
+ QTest::addRow("null ~= a$") << QStringView() << QLatin1String()
+ << QStringView(a) << QLatin1String("a") << false << false;
+ QTest::addRow("empty ~= a$") << QStringView(empty) << QLatin1String("")
+ << QStringView(a) << QLatin1String("a") << false << false;
+
+#define ROW(h, n, cs, cis) \
+ QTest::addRow("%s ~= %s$", #h, #n) << QStringView(h) << QLatin1String(#h) \
+ << QStringView(n) << QLatin1String(#n) \
+ << bool(cs) << bool(cis)
+ ROW(a, a, 1, 1);
+ ROW(a, A, 0, 1);
+ ROW(a, b, 0, 0);
+
+ if (rhsHasVariableLength)
+ ROW(b, ab, 0, 0);
+
+ ROW(ab, b, 1, 1);
+ if (rhsHasVariableLength) {
+ ROW(ab, ab, 1, 1);
+ ROW(ab, aB, 0, 1);
+ ROW(ab, Ab, 0, 1);
+ }
+ ROW(ab, c, 0, 0);
+
+ if (rhsHasVariableLength)
+ ROW(bc, abc, 0, 0);
+
+ ROW(Abc, c, 1, 1);
+ if (rhsHasVariableLength) {
+ ROW(Abc, bc, 1, 1);
+ ROW(Abc, bC, 0, 1);
+ ROW(Abc, Bc, 0, 1);
+ ROW(Abc, BC, 0, 1);
+ ROW(aBC, bc, 0, 1);
+ ROW(aBC, bC, 0, 1);
+ ROW(aBC, Bc, 0, 1);
+ ROW(aBC, BC, 1, 1);
+ }
+ ROW(ABC, b, 0, 0);
+ ROW(ABC, a, 0, 0);
+#undef ROW
+}
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::endsWith_impl() const
+{
+ QFETCH(const QStringView, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QStringView, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const bool, resultCS);
+ QFETCH(const bool, resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
+ const auto needle = make<Needle>(needleU16, needleL1, needleU8);
+
+ QCOMPARE_EQ(haystack.endsWith(needle), resultCS);
+ QCOMPARE_EQ(haystack.endsWith(needle, Qt::CaseSensitive), resultCS);
+ QCOMPARE_EQ(haystack.endsWith(needle, Qt::CaseInsensitive), resultCIS);
+}
+
+void tst_QStringApiSymmetry::split_data(bool rhsHasVariableLength)
+{
+ QTest::addColumn<QStringView>("haystackU16");
+ QTest::addColumn<QLatin1String>("haystackL1");
+ QTest::addColumn<QStringView>("needleU16");
+ QTest::addColumn<QLatin1String>("needleL1");
+ QTest::addColumn<QStringList>("resultCS");
+ QTest::addColumn<QStringList>("resultCIS");
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("null ~= null$") << QStringView{} << QLatin1String{}
+ << QStringView{} << QLatin1String{}
+ << QStringList{{}, {}} << QStringList{{}, {}};
+ QTest::addRow("empty ~= null$") << QStringView{empty} << QLatin1String("")
+ << QStringView{} << QLatin1String{}
+ << QStringList{empty, empty} << QStringList{empty, empty};
+ QTest::addRow("a ~= null$") << QStringView{a} << QLatin1String{"a"}
+ << QStringView{} << QLatin1String{}
+ << QStringList{empty, a, empty} << QStringList{empty, a, empty};
+ QTest::addRow("null ~= empty$") << QStringView{} << QLatin1String{}
+ << QStringView{empty} << QLatin1String{""}
+ << QStringList{{}, {}} << QStringList{{}, {}};
+ QTest::addRow("a ~= empty$") << QStringView{a} << QLatin1String{"a"}
+ << QStringView{empty} << QLatin1String{""}
+ << QStringList{empty, a, empty} << QStringList{empty, a, empty};
+ QTest::addRow("empty ~= empty$") << QStringView{empty} << QLatin1String{""}
+ << QStringView{empty} << QLatin1String{""}
+ << QStringList{empty, empty} << QStringList{empty, empty};
+ }
+ QTest::addRow("null ~= a$") << QStringView{} << QLatin1String{}
+ << QStringView{a} << QLatin1String{"a"}
+ << QStringList{{}} << QStringList{{}};
+ QTest::addRow("empty ~= a$") << QStringView{empty} << QLatin1String{""}
+ << QStringView{a} << QLatin1String{"a"}
+ << QStringList{empty} << QStringList{empty};
+
+#define ROW(h, n, cs, cis) \
+ QTest::addRow("%s ~= %s$", #h, #n) << QStringView(h) << QLatin1String(#h) \
+ << QStringView(n) << QLatin1String(#n) \
+ << QStringList cs << QStringList cis
+ ROW(a, a, ({empty, empty}), ({empty, empty}));
+ ROW(a, A, {a}, ({empty, empty}));
+ ROW(a, b, {a}, {a});
+
+ if (rhsHasVariableLength)
+ ROW(b, ab, {b}, {b});
+
+ ROW(ab, b, ({a, empty}), ({a, empty}));
+ if (rhsHasVariableLength) {
+ ROW(ab, ab, ({empty, empty}), ({empty, empty}));
+ ROW(ab, aB, {ab}, ({empty, empty}));
+ ROW(ab, Ab, {ab}, ({empty, empty}));
+ }
+ ROW(ab, c, {ab}, {ab});
+
+ if (rhsHasVariableLength)
+ ROW(bc, abc, {bc}, {bc});
+
+ ROW(Abc, c, ({Ab, empty}), ({Ab, empty}));
+#if 0
+ if (rhsHasVariableLength) {
+ ROW(Abc, bc, 1, 1);
+ ROW(Abc, bC, 0, 1);
+ ROW(Abc, Bc, 0, 1);
+ ROW(Abc, BC, 0, 1);
+ ROW(aBC, bc, 0, 1);
+ ROW(aBC, bC, 0, 1);
+ ROW(aBC, Bc, 0, 1);
+ ROW(aBC, BC, 1, 1);
+ }
+#endif
+ ROW(ABC, b, {ABC}, ({A, C}));
+ ROW(ABC, a, {ABC}, ({empty, BC}));
+#undef ROW
+}
+
+static QStringList skipped(const QStringList &sl)
+{
+ QStringList result;
+ result.reserve(sl.size());
+ for (const QString &s : sl) {
+ if (!s.isEmpty())
+ result.push_back(s);
+ }
+ return result;
+}
+
+template <typename T> T deepCopied(T s) { return s; }
+template <> QString deepCopied(QString s) { return detached(s); }
+template <> QByteArray deepCopied(QByteArray s) { return detached(s); }
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::split_impl() const
+{
+ QFETCH(const QStringView, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QStringView, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const QStringList, resultCS);
+ QFETCH(const QStringList, resultCIS);
+
+ const QStringList skippedResultCS = skipped(resultCS);
+ const QStringList skippedResultCIS = skipped(resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
+ const auto needle = make<Needle>(needleU16, needleL1, needleU8);
+
+ QCOMPARE_EQ(toQStringList(haystack.split(needle)), resultCS);
+ QCOMPARE_EQ(toQStringList(haystack.split(needle, Qt::KeepEmptyParts, Qt::CaseSensitive)), resultCS);
+ QCOMPARE_EQ(toQStringList(haystack.split(needle, Qt::KeepEmptyParts, Qt::CaseInsensitive)), resultCIS);
+ QCOMPARE_EQ(toQStringList(haystack.split(needle, Qt::SkipEmptyParts, Qt::CaseSensitive)), skippedResultCS);
+ QCOMPARE_EQ(toQStringList(haystack.split(needle, Qt::SkipEmptyParts, Qt::CaseInsensitive)), skippedResultCIS);
+}
+
+void tst_QStringApiSymmetry::tok_data(bool rhsHasVariableLength)
+{
+ split_data(rhsHasVariableLength);
+}
+
+template <typename T> struct has_tokenize_method : std::false_type {};
+template <> struct has_tokenize_method<QString> : std::true_type {};
+template <> struct has_tokenize_method<QStringView> : std::true_type {};
+template <> struct has_tokenize_method<QLatin1String> : std::true_type {};
+
+template <typename T>
+constexpr inline bool has_tokenize_method_v = has_tokenize_method<std::decay_t<T>>::value;
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::tok_impl() const
+{
+ QFETCH(const QStringView, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QStringView, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const QStringList, resultCS);
+ QFETCH(const QStringList, resultCIS);
+
+ const QStringList skippedResultCS = skipped(resultCS);
+ const QStringList skippedResultCIS = skipped(resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
+ const auto needle = make<Needle>(needleU16, needleL1, needleU8);
+
+ QCOMPARE_EQ(toQStringList(qTokenize(haystack, needle)), resultCS);
+ QCOMPARE_EQ(toQStringList(qTokenize(haystack, needle, Qt::KeepEmptyParts, Qt::CaseSensitive)), resultCS);
+ QCOMPARE_EQ(toQStringList(qTokenize(haystack, needle, Qt::CaseInsensitive, Qt::KeepEmptyParts)), resultCIS);
+ QCOMPARE_EQ(toQStringList(qTokenize(haystack, needle, Qt::SkipEmptyParts, Qt::CaseSensitive)), skippedResultCS);
+ QCOMPARE_EQ(toQStringList(qTokenize(haystack, needle, Qt::CaseInsensitive, Qt::SkipEmptyParts)), skippedResultCIS);
+
+ {
+ const auto tok = qTokenize(deepCopied(haystack), deepCopied(needle));
+ // here, the temporaries returned from deepCopied() have already been destroyed,
+ // yet `tok` should have kept a copy alive as needed:
+ QCOMPARE_EQ(toQStringList(tok), resultCS);
+ }
+
+ QCOMPARE_EQ(toQStringList(QStringTokenizer{haystack, needle}), resultCS);
+ QCOMPARE_EQ(toQStringList(QStringTokenizer{haystack, needle, Qt::KeepEmptyParts, Qt::CaseSensitive}), resultCS);
+ QCOMPARE_EQ(toQStringList(QStringTokenizer{haystack, needle, Qt::CaseInsensitive, Qt::KeepEmptyParts}), resultCIS);
+ QCOMPARE_EQ(toQStringList(QStringTokenizer{haystack, needle, Qt::SkipEmptyParts, Qt::CaseSensitive}), skippedResultCS);
+ QCOMPARE_EQ(toQStringList(QStringTokenizer{haystack, needle, Qt::CaseInsensitive, Qt::SkipEmptyParts}), skippedResultCIS);
+
+ {
+ const auto tok = QStringTokenizer{deepCopied(haystack), deepCopied(needle)};
+ // here, the temporaries returned from deepCopied() have already been destroyed,
+ // yet `tok` should have kept a copy alive as needed:
+ QCOMPARE_EQ(toQStringList(tok), resultCS);
+ }
+
+ if constexpr (has_tokenize_method_v<Haystack>) {
+ QCOMPARE_EQ(toQStringList(haystack.tokenize(needle)), resultCS);
+ QCOMPARE_EQ(toQStringList(haystack.tokenize(needle, Qt::KeepEmptyParts, Qt::CaseSensitive)), resultCS);
+ QCOMPARE_EQ(toQStringList(haystack.tokenize(needle, Qt::CaseInsensitive, Qt::KeepEmptyParts)), resultCIS);
+ QCOMPARE_EQ(toQStringList(haystack.tokenize(needle, Qt::SkipEmptyParts, Qt::CaseSensitive)), skippedResultCS);
+ QCOMPARE_EQ(toQStringList(haystack.tokenize(needle, Qt::CaseInsensitive, Qt::SkipEmptyParts)), skippedResultCIS);
+
+ {
+ const auto tok = deepCopied(haystack).tokenize(deepCopied(needle));
+ // here, the temporaries returned from deepCopied() have already been destroyed,
+ // yet `tok` should have kept a copy alive as needed:
+ QCOMPARE_EQ(toQStringList(tok), resultCS);
+ }
+ }
+}
+
+void tst_QStringApiSymmetry::mid_data()
+{
+ sliced_data();
+
+ // mid() has a wider contract compared to sliced(), so test those cases here:
+#define ROW(base, p, n, r1, r2) \
+ QTest::addRow("%s %d %d", #base, p, n) << QStringView(base) << QLatin1String(#base) << p << n << QAnyStringView(r1) << QAnyStringView(r2)
+
+ ROW(a, -1, 0, a, null);
+ ROW(a, -1, 2, a, a);
+ ROW(a, -1, 3, a, a);
+ ROW(a, 0, -1, a, a);
+ ROW(a, 0, 2, a, a);
+ ROW(a, -1, -1, a, a);
+ ROW(a, 1, -1, empty, empty);
+ ROW(a, 1, 1, empty, empty);
+ ROW(a, 2, -1, null, null);
+ ROW(a, 2, 1, null, null);
+
+ ROW(abc, -1, -1, abc, abc);
+ ROW(abc, -1, 0, abc, null);
+ ROW(abc, -1, 2, abc, a);
+ ROW(abc, -1, 3, abc, ab);
+ ROW(abc, -1, 5, abc, abc);
+ ROW(abc, 0, -1, abc, abc);
+ ROW(abc, 0, 5, abc, abc);
+ ROW(abc, -1, 1, abc, null);
+ ROW(abc, -1, 4, abc, abc);
+ ROW(abc, 1, -1, bc, bc);
+ ROW(abc, 1, 1, bc, b);
+ ROW(abc, 3, -1, empty, empty);
+ ROW(abc, 3, 1, empty, empty);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::mid_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, pos);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+ QFETCH(const QAnyStringView, result2);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto mid = s.mid(pos);
+ const auto mid2 = s.mid(pos, n);
+
+ QCOMPARE_EQ(mid, result);
+ QCOMPARE_EQ(mid.isNull(), result.isNull());
+ QCOMPARE_EQ(mid.isEmpty(), result.isEmpty());
+
+ QCOMPARE_EQ(mid2, result2);
+ QCOMPARE_EQ(mid2.isNull(), result2.isNull());
+ QCOMPARE_EQ(mid2.isEmpty(), result2.isEmpty());
+ }
+ {
+ const auto mid = detached(s).mid(pos);
+ const auto mid2 = detached(s).mid(pos, n);
+
+ QCOMPARE_EQ(mid, result);
+ QCOMPARE_EQ(mid.isNull(), result.isNull());
+ QCOMPARE_EQ(mid.isEmpty(), result.isEmpty());
+
+ QCOMPARE_EQ(mid2, result2);
+ QCOMPARE_EQ(mid2.isNull(), result2.isNull());
+ QCOMPARE_EQ(mid2.isEmpty(), result2.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::left_data()
+{
+ first_data();
+
+ // specific data testing out of bounds cases
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, -1, a);
+ ROW(a, 2, a);
+
+ ROW(ab, -100, ab);
+ ROW(ab, 100, ab);
+#undef ROW
+}
+
+// This is different from the rest for historical reasons. As we're replacing
+// left() with first() as the recommended API, there's no point fixing this anymore
+void tst_QStringApiSymmetry::left_QByteArray_data()
+{
+ first_data();
+
+ // specific data testing out of bounds cases
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, -1, empty);
+ ROW(a, 2, a);
+
+ ROW(ab, -100, empty);
+ ROW(ab, 100, ab);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::left_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto left = s.left(n);
+
+ QCOMPARE_EQ(left, result);
+ QCOMPARE_EQ(left.isNull(), result.isNull());
+ QCOMPARE_EQ(left.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto left = detached(s).left(n);
+
+ QCOMPARE_EQ(left, result);
+ QCOMPARE_EQ(left.isNull(), result.isNull());
+ QCOMPARE_EQ(left.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::right_data()
+{
+ last_data();
+
+ // specific data testing out of bounds cases
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, -1, a);
+ ROW(a, 2, a);
+
+ ROW(ab, -100, ab);
+ ROW(ab, 100, ab);
+#undef ROW
+}
+
+// This is different from the rest for historical reasons. As we're replacing
+// left() with first() as the recommended API, there's no point fixing this anymore
+void tst_QStringApiSymmetry::right_QByteArray_data()
+{
+ last_data();
+
+ // specific data testing out of bounds cases
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, -1, empty);
+ ROW(a, 2, a);
+
+ ROW(ab, -100, empty);
+ ROW(ab, 100, ab);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::right_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto right = s.right(n);
+
+ QCOMPARE_EQ(right, result);
+ QCOMPARE_EQ(right.isNull(), result.isNull());
+ QCOMPARE_EQ(right.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto right = detached(s).right(n);
+
+ QCOMPARE_EQ(right, result);
+ QCOMPARE_EQ(right.isNull(), result.isNull());
+ QCOMPARE_EQ(right.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::sliced_data()
+{
+ QTest::addColumn<QStringView>("unicode");
+ QTest::addColumn<QLatin1String>("latin1");
+ QTest::addColumn<int>("pos");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QAnyStringView>("result");
+ QTest::addColumn<QAnyStringView>("result2");
+
+// QTest::addRow("null") << QStringView() << QLatin1String() << 0 << 0 << QStringView() << QStringView();
+ QTest::addRow("empty") << QStringView(empty) << QLatin1String("") << 0 << 0 << QAnyStringView(empty) << QAnyStringView(empty);
+
+#define ROW(base, p, n, r1, r2) \
+ QTest::addRow("%s%d%d", #base, p, n) << QStringView(base) << QLatin1String(#base) << p << n << QAnyStringView(r1) << QAnyStringView(r2)
+
+ ROW(a, 0, 0, a, empty);
+ ROW(a, 0, 1, a, a);
+ ROW(a, 1, 0, empty, empty);
+
+ ROW(ab, 0, 0, ab, empty);
+ ROW(ab, 0, 1, ab, a);
+ ROW(ab, 0, 2, ab, ab);
+ ROW(ab, 1, 0, b, empty);
+ ROW(ab, 1, 1, b, b);
+ ROW(ab, 2, 0, empty, empty);
+
+ ROW(abc, 0, 0, abc, empty);
+ ROW(abc, 0, 1, abc, a);
+ ROW(abc, 0, 2, abc, ab);
+ ROW(abc, 0, 3, abc, abc);
+ ROW(abc, 1, 0, bc, empty);
+ ROW(abc, 1, 1, bc, b);
+ ROW(abc, 1, 2, bc, bc);
+ ROW(abc, 2, 0, c, empty);
+ ROW(abc, 2, 1, c, c);
+ ROW(abc, 3, 0, empty, empty);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::sliced_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, pos);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+ QFETCH(const QAnyStringView, result2);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto sliced = s.sliced(pos);
+
+ QCOMPARE_EQ(sliced, result);
+ QCOMPARE_EQ(sliced.isNull(), result.isNull());
+ QCOMPARE_EQ(sliced.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto sliced = s.sliced(pos, n);
+
+ QCOMPARE_EQ(sliced, result2);
+ QCOMPARE_EQ(sliced.isNull(), result2.isNull());
+ QCOMPARE_EQ(sliced.isEmpty(), result2.isEmpty());
+ }
+ {
+ const auto sliced = detached(s).sliced(pos);
+
+ QCOMPARE_EQ(sliced, result);
+ QCOMPARE_EQ(sliced.isNull(), result.isNull());
+ QCOMPARE_EQ(sliced.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto sliced = detached(s).sliced(pos, n);
+
+ QCOMPARE_EQ(sliced, result2);
+ QCOMPARE_EQ(sliced.isNull(), result2.isNull());
+ QCOMPARE_EQ(sliced.isEmpty(), result2.isEmpty());
+ }
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::slice_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, pos);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+ QFETCH(const QAnyStringView, result2);
+
+ const auto str = make<String>(unicode, latin1, unicode.toUtf8());
+
+ auto s = str;
+ s.slice(pos);
+ QCOMPARE_EQ(s, result);
+
+ s = str;
+ s.slice(pos, n);
+ QCOMPARE_EQ(s, result2);
+}
+
+void tst_QStringApiSymmetry::first_data()
+{
+ QTest::addColumn<QStringView>("unicode");
+ QTest::addColumn<QLatin1String>("latin1");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QAnyStringView>("result");
+
+// QTest::addRow("null") << QStringView() << QLatin1String() << 0 << QStringView();
+ QTest::addRow("empty") << QStringView(empty) << QLatin1String("") << 0 << QAnyStringView(empty);
+
+ // Some classes' left() implementations have a wide contract, others a narrow one
+ // so only test valid arguments here:
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, 0, empty);
+ ROW(a, 1, a);
+
+ ROW(ab, 0, empty);
+ ROW(ab, 1, a);
+ ROW(ab, 2, ab);
+
+ ROW(abc, 0, empty);
+ ROW(abc, 1, a);
+ ROW(abc, 2, ab);
+ ROW(abc, 3, abc);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::first_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto first = s.first(n);
+
+ QCOMPARE_EQ(first, result);
+ QCOMPARE_EQ(first.isNull(), result.isNull());
+ QCOMPARE_EQ(first.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto first = detached(s).first(n);
+
+ QCOMPARE_EQ(first, result);
+ QCOMPARE_EQ(first.isNull(), result.isNull());
+ QCOMPARE_EQ(first.isEmpty(), result.isEmpty());
+ }
+ {
+ auto first = s;
+ first.truncate(n);
+
+ QCOMPARE_EQ(first, result);
+ QCOMPARE_EQ(first.isNull(), result.isNull());
+ QCOMPARE_EQ(first.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::last_data()
+{
+ QTest::addColumn<QStringView>("unicode");
+ QTest::addColumn<QLatin1String>("latin1");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QAnyStringView>("result");
+
+// QTest::addRow("null") << QStringView() << QLatin1String() << 0 << QStringView();
+ QTest::addRow("empty") << QStringView(empty) << QLatin1String("") << 0 << QAnyStringView(empty);
+
+ // Some classes' last() implementations have a wide contract, others a narrow one
+ // so only test valid arguments here:
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, 0, empty);
+ ROW(a, 1, a);
+
+ ROW(ab, 0, empty);
+ ROW(ab, 1, b);
+ ROW(ab, 2, ab);
+
+ ROW(abc, 0, empty);
+ ROW(abc, 1, c);
+ ROW(abc, 2, bc);
+ ROW(abc, 3, abc);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::last_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto last = s.last(n);
+
+ QCOMPARE_EQ(last, result);
+ QCOMPARE_EQ(last.isNull(), result.isNull());
+ QCOMPARE_EQ(last.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto last = detached(s).last(n);
+
+ QCOMPARE_EQ(last, result);
+ QCOMPARE_EQ(last.isNull(), result.isNull());
+ QCOMPARE_EQ(last.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::chop_data()
+{
+ QTest::addColumn<QStringView>("unicode");
+ QTest::addColumn<QLatin1String>("latin1");
+ QTest::addColumn<int>("n");
+ QTest::addColumn<QAnyStringView>("result");
+
+// QTest::addRow("null") << QStringView() << QLatin1String() << 0 << QStringView();
+ QTest::addRow("empty") << QStringView(empty) << QLatin1String("") << 0 << QAnyStringView(empty);
+
+ // Some classes' truncate() implementations have a wide contract, others a narrow one
+ // so only test valid arguents here:
+#define ROW(base, n, res) \
+ QTest::addRow("%s%d", #base, n) << QStringView(base) << QLatin1String(#base) << n << QAnyStringView(res);
+
+ ROW(a, 0, a);
+ ROW(a, 1, empty);
+
+ ROW(ab, 0, ab);
+ ROW(ab, 1, a);
+ ROW(ab, 2, empty);
+
+ ROW(abc, 0, abc);
+ ROW(abc, 1, ab);
+ ROW(abc, 2, a);
+ ROW(abc, 3, empty);
+#undef ROW
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::chop_impl()
+{
+ QFETCH(const QStringView, unicode);
+ QFETCH(const QLatin1String, latin1);
+ QFETCH(const int, n);
+ QFETCH(const QAnyStringView, result);
+
+ const auto utf8 = unicode.toUtf8();
+
+ const auto s = make<String>(unicode, latin1, utf8);
+
+ {
+ const auto chopped = s.chopped(n);
+
+ QCOMPARE_EQ(chopped, result);
+ QCOMPARE_EQ(chopped.isNull(), result.isNull());
+ QCOMPARE_EQ(chopped.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto chopped = detached(s).chopped(n);
+
+ QCOMPARE_EQ(chopped, result);
+ QCOMPARE_EQ(chopped.isNull(), result.isNull());
+ QCOMPARE_EQ(chopped.isEmpty(), result.isEmpty());
+ }
+ {
+ auto chopped = s;
+ chopped.chop(n);
+
+ QCOMPARE_EQ(chopped, result);
+ QCOMPARE_EQ(chopped.isNull(), result.isNull());
+ QCOMPARE_EQ(chopped.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::trimmed_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<QAnyStringView>("result");
+
+ const auto latin1Whitespace = QLatin1StringView(" \r\n\t\f\v");
+
+ QTest::addRow("null") << QString() << QAnyStringView();
+
+ auto add = [latin1Whitespace](const QString &str) {
+ auto row = [&](QLatin1StringView spaces) {
+ const QString unicode = spaces + str + spaces;
+ const QScopedArrayPointer<const char> escaped(QTest::toString(unicode));
+ QTest::addRow("%s", escaped.data()) << unicode << QAnyStringView(str);
+ };
+ row({}); // The len = 0 case of the following.
+ for (qsizetype len = 1; len < latin1Whitespace.size(); ++len) {
+ for (qsizetype pos = 0; pos < latin1Whitespace.size() - len; ++pos)
+ row (latin1Whitespace.mid(pos, len));
+ }
+ };
+
+ add(empty);
+ add(a);
+ add(ab);
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::trimmed_impl()
+{
+ QFETCH(const QString, unicode);
+ QFETCH(const QAnyStringView, result);
+
+ const auto utf8 = unicode.toUtf8();
+ const auto l1s = unicode.toLatin1();
+ const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s);
+
+ const auto ref = unicode.isNull() ? QStringView() : QStringView(unicode);
+ const auto s = make<String>(ref, l1, utf8);
+
+ QCOMPARE_EQ(s.isNull(), unicode.isNull());
+
+ {
+ const auto trimmed = s.trimmed();
+
+ QCOMPARE_EQ(trimmed, result);
+ QCOMPARE_EQ(trimmed.isNull(), result.isNull());
+ QCOMPARE_EQ(trimmed.isEmpty(), result.isEmpty());
+ }
+ {
+ const auto trimmed = detached(s).trimmed();
+
+ QCOMPARE_EQ(trimmed, result);
+ QCOMPARE_EQ(trimmed.isNull(), result.isNull());
+ QCOMPARE_EQ(trimmed.isEmpty(), result.isEmpty());
+ }
+}
+
+void tst_QStringApiSymmetry::toNumber_data()
+{
+ QTest::addColumn<QString>("data");
+ QTest::addColumn<qint64>("result");
+ QTest::addColumn<bool>("ok");
+
+ QTest::addRow("0") << QString::fromUtf8("0") << qint64(0) << true;
+ QTest::addRow("a0") << QString::fromUtf8("a0") << qint64(0) << false;
+ QTest::addRow("10") << QString::fromUtf8("10") << qint64(10) << true;
+ QTest::addRow("-10") << QString::fromUtf8("-10") << qint64(-10) << true;
+ QTest::addRow("32767") << QString::fromUtf8("32767") << qint64(32767) << true;
+ QTest::addRow("32768") << QString::fromUtf8("32768") << qint64(32768) << true;
+ QTest::addRow("-32767") << QString::fromUtf8("-32767") << qint64(-32767) << true;
+ QTest::addRow("-32768") << QString::fromUtf8("-32768") << qint64(-32768) << true;
+ QTest::addRow("100x") << QString::fromUtf8("100x") << qint64(0) << false;
+ QTest::addRow("-100x") << QString::fromUtf8("-100x") << qint64(0) << false;
+ QTest::addRow("-min64") << QString::fromUtf8("--9223372036854775808") << qint64(0) << false;
+}
+
+template<typename T>
+bool inRange(qint64 n)
+{
+ bool checkMax = quint64(std::numeric_limits<T>::max()) <= quint64(std::numeric_limits<qint64>::max());
+ if (checkMax && n > qint64(std::numeric_limits<T>::max()))
+ return false;
+ return qint64(std::numeric_limits<T>::min()) <= n;
+}
+
+template<typename String>
+void tst_QStringApiSymmetry::toNumber_impl()
+{
+ QFETCH(const QString, data);
+ QFETCH(qint64, result);
+ QFETCH(bool, ok);
+
+ const auto utf8 = data.toUtf8();
+ const auto l1s = data.toLatin1();
+ const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s);
+
+ const auto ref = data.isNull() ? QStringView() : QStringView(data);
+ const auto s = make<String>(ref, l1, utf8);
+
+ bool is_ok = false;
+ qint64 n = 0;
+
+ n = s.toShort(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<short>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toUShort(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<ushort>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toInt(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<int>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toUInt(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<uint>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toLong(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<long>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toULong(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<ulong>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toLongLong(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<qlonglong>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toULongLong(&is_ok);
+ QCOMPARE_EQ(is_ok, ok && inRange<qulonglong>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ if (qint64(float(n)) == n) {
+ float f = s.toFloat(&is_ok);
+ QCOMPARE_EQ(is_ok, ok);
+ if (is_ok)
+ QCOMPARE_EQ(qint64(f), result);
+ }
+
+ if (qint64(double(n)) == n) {
+ double d = s.toDouble(&is_ok);
+ QCOMPARE_EQ(is_ok, ok);
+ if (is_ok)
+ QCOMPARE_EQ(qint64(d), result);
+ }
+}
+
+void tst_QStringApiSymmetry::toNumberWithBases_data()
+{
+ QTest::addColumn<QString>("data");
+ QTest::addColumn<int>("base");
+ QTest::addColumn<qint64>("result");
+ QTest::addColumn<bool>("ok");
+
+ constexpr struct {
+ const char prefix[3];
+ int base;
+ } bases[] = {
+ { "0b", 2 },
+ { "0", 8 },
+ { "", 10 },
+ { "0x", 16 },
+ };
+
+ const auto check = [&](const char *input, qint64 n2, qint64 n8, qint64 n10, qint64 n16, bool result) {
+ for (const auto &e : bases) {
+ const QString data = QLatin1StringView(e.prefix) + QString::fromUtf8(input);
+ const auto row = [&](int base) {
+ const auto select = [&](int base) {
+ switch (base) {
+ case 2: return n2;
+ case 8: return n8;
+ case 10: return n10;
+ case 16: return n16;
+ }
+ Q_UNREACHABLE();
+ };
+ QTest::addRow("base%2d: %s%s", base, e.prefix, input)
+ << data << base << select(e.base /* NOT base! */) << result;
+ };
+ row(e.base); // explicit base
+ row(0); // automatically detected base
+ }
+ };
+
+ check("0", 0, 0, 0, 0, true);
+ check("y0", 0, 0, 0, 0, false);
+ check("0y", 0, 0, 0, 0, false);
+ check("10", 2, 8, 10, 16, true);
+ check("11", 3, 9, 11, 17, true);
+ check("100", 4, 64, 100, 256, true);
+}
+
+template<typename String>
+void tst_QStringApiSymmetry::toNumberWithBases_impl()
+{
+ QFETCH(const QString, data);
+ QFETCH(const int, base);
+ QFETCH(const qint64, result);
+ QFETCH(const bool, ok);
+
+ const auto utf8 = data.toUtf8();
+ const auto l1s = data.toLatin1();
+ const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s);
+
+ const auto ref = data.isNull() ? QStringView() : QStringView(data);
+ const auto s = make<String>(ref, l1, utf8);
+
+ bool is_ok = false;
+ qint64 n = 0;
+
+ n = s.toShort(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<short>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toUShort(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<ushort>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toInt(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<int>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toUInt(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<uint>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toLong(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<long>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toULong(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<ulong>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toLongLong(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<qlonglong>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+
+ n = s.toULongLong(&is_ok, base);
+ QCOMPARE_EQ(is_ok, ok && inRange<qulonglong>(result));
+ if (is_ok)
+ QCOMPARE_EQ(n, result);
+}
+
+void tst_QStringApiSymmetry::count_data()
+{
+ QTest::addColumn<QString>("data");
+ QTest::addColumn<QString>("needle");
+ QTest::addColumn<qsizetype>("result");
+
+ QTest::addRow("xxx") << QString::fromUtf8("xxx") << QString::fromUtf8("x") << qsizetype(3);
+ QTest::addRow("xyzaaaxyz") << QString::fromUtf8("xyzaaaxyz") << QString::fromUtf8("xyz") << qsizetype(2);
+}
+
+template<typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::count_impl()
+{
+ QFETCH(const QString, data);
+ QFETCH(const QString, needle);
+ QFETCH(qsizetype, result);
+
+ const auto utf8 = data.toUtf8();
+ const auto l1s = data.toLatin1();
+ const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s);
+
+ const auto ref = data.isNull() ? QStringView() : QStringView(data);
+ const auto s = make<Haystack>(ref, l1, utf8);
+
+ const auto nutf8 = needle.toUtf8();
+ const auto nl1s = needle.toLatin1();
+ const auto nl1 = nl1s.isNull() ? QLatin1String() : QLatin1String(nl1s);
+
+ const auto nref = needle.isNull() ? QStringView() : QStringView(needle);
+ const auto ns = make<Needle>(nref, nl1, nutf8);
+
+ QCOMPARE_EQ(s.count(ns), result);
+}
+
+//
+//
+// UTF-16-only checks:
+//
+//
+
+#define REPEAT_16X(X) X X X X X X X X X X X X X X X X
+#define LONG_STRING_256 REPEAT_16X("0123456789abcdef")
+
+void tst_QStringApiSymmetry::toLocal8Bit_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<QByteArray>("local");
+
+ auto add = [](const char *local) {
+ const QByteArray ba(local);
+ QString s;
+ for (char c : ba)
+ s += QLatin1Char(c);
+ QTest::newRow(rowName(ba).constData()) << s << ba;
+ };
+
+ QTest::addRow("null") << QString() << QByteArray();
+ QTest::addRow("empty") << QString("") << QByteArray("");
+
+ add("Moebius");
+ add(LONG_STRING_256);
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::toLocal8Bit_impl()
+{
+ QFETCH(const QString, unicode);
+ QFETCH(const QByteArray, local);
+
+ const auto str = make<String>(unicode);
+
+ const auto result = str.toLocal8Bit();
+
+ QCOMPARE_EQ(result, local);
+ QCOMPARE_EQ(unicode.isEmpty(), result.isEmpty());
+ QCOMPARE_EQ(unicode.isNull(), result.isNull());
+}
+
+void tst_QStringApiSymmetry::toLatin1_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<QByteArray>("latin1");
+
+ auto add = [](const char *l1) {
+ const QByteArray ba(l1);
+ QString s;
+ for (char c : ba)
+ s += QLatin1Char(c);
+ QTest::newRow(rowName(ba).constData()) << s << ba;
+ };
+
+ QTest::addRow("null") << QString() << QByteArray();
+ QTest::addRow("empty") << QString("") << QByteArray("");
+
+ add("M\xF6" "bius");
+ add(LONG_STRING_256);
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::toLatin1_impl()
+{
+ QFETCH(const QString, unicode);
+ QFETCH(const QByteArray, latin1);
+
+ const auto str = make<String>(unicode);
+
+ const auto result = str.toLatin1();
+
+ QCOMPARE_EQ(result, latin1);
+ QCOMPARE_EQ(unicode.isEmpty(), result.isEmpty());
+ QCOMPARE_EQ(unicode.isNull(), result.isNull());
+}
+
+void tst_QStringApiSymmetry::toUtf8_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<QByteArray>("utf8");
+
+ auto add = [](const char *u8) {
+ QByteArray ba(u8);
+ QString s = ba;
+ QTest::newRow(rowName(ba).constData()) << s << ba;
+ };
+
+ QTest::addRow("null") << QString() << QByteArray();
+ QTest::addRow("empty") << QString("") << QByteArray("");
+
+ add("M\xC3\xB6" "bius");
+ add(LONG_STRING_256);
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::toUtf8_impl()
+{
+ QFETCH(const QString, unicode);
+ QFETCH(const QByteArray, utf8);
+
+ const auto str = make<String>(unicode);
+
+ const auto result = str.toUtf8();
+
+ QCOMPARE_EQ(result, utf8);
+ QCOMPARE_EQ(unicode.isEmpty(), result.isEmpty());
+ QCOMPARE_EQ(unicode.isNull(), result.isNull());
+}
+
+void tst_QStringApiSymmetry::toUcs4_data()
+{
+ QTest::addColumn<QString>("unicode");
+ QTest::addColumn<QList<uint>>("ucs4");
+
+ auto add = [](const char *l1) {
+ const QByteArray ba(l1);
+ QString s;
+ QList<uint> ucs4;
+ for (char c : ba) {
+ s += QLatin1Char(c);
+ ucs4.append(uint(uchar(c)));
+ }
+ QTest::newRow(rowName(ba).constData()) << s << ucs4;
+ };
+
+ QTest::addRow("null") << QString() << QList<uint>();
+ QTest::addRow("empty") << QString("") << QList<uint>();
+
+ add("M\xF6" "bius");
+ add(LONG_STRING_256);
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::toUcs4_impl()
+{
+ QFETCH(const QString, unicode);
+ QFETCH(const QList<uint>, ucs4);
+
+ const auto str = make<String>(unicode);
+
+ const auto result = str.toUcs4();
+
+ QCOMPARE_EQ(result, ucs4);
+ QCOMPARE_EQ(unicode.isEmpty(), ucs4.isEmpty());
+}
+
+void tst_QStringApiSymmetry::indexOf_data(bool rhsHasVariableLength)
+{
+ QTest::addColumn<QString>("haystackU16");
+ QTest::addColumn<QLatin1String>("haystackL1");
+ QTest::addColumn<QString>("needleU16");
+ QTest::addColumn<QLatin1String>("needleL1");
+ QTest::addColumn<qsizetype>("startpos");
+ QTest::addColumn<qsizetype>("resultCS");
+ QTest::addColumn<qsizetype>("resultCIS");
+
+ constexpr qsizetype zeroPos = 0;
+ constexpr qsizetype minus1Pos = -1;
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("haystack: null, needle: null") << null << QLatin1String()
+ << null << QLatin1String() << zeroPos << zeroPos << zeroPos;
+ QTest::addRow("haystack: empty, needle: null") << empty << QLatin1String("")
+ << null << QLatin1String() << zeroPos << zeroPos << zeroPos;
+ QTest::addRow("haystack: a, needle: null") << a << QLatin1String("a")
+ << null << QLatin1String() << zeroPos << zeroPos << zeroPos;
+ QTest::addRow("haystack: null, needle: empty") << null << QLatin1String()
+ << empty << QLatin1String("") << zeroPos << zeroPos << zeroPos;
+ QTest::addRow("haystack: a, needle: empty") << a << QLatin1String("a")
+ << empty << QLatin1String("") << zeroPos << zeroPos << zeroPos;
+ QTest::addRow("haystack: empty, needle: empty") << empty << QLatin1String("")
+ << empty << QLatin1String("") << zeroPos << zeroPos << zeroPos;
+ }
+ QTest::addRow("haystack: empty, needle: a") << empty << QLatin1String("")
+ << a << QLatin1String("a") << zeroPos << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: null, needle: a") << null << QLatin1String()
+ << a << QLatin1String("a") << zeroPos << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: anything, needle: a, large negative offset")
+ << "anything" << QLatin1String("anything") << a << QLatin1String("a") << qsizetype(-500)
+ << minus1Pos << minus1Pos;
+
+#define ROW(h, n, st, cs, cis) \
+ QTest::addRow("haystack: %s, needle: %s, start: %d", #h, #n, st) \
+ << h << QLatin1String(#h) << n << QLatin1String(#n) \
+ << qsizetype(st) << qsizetype(cs) << qsizetype(cis)
+
+ ROW(abc, a, 0, 0, 0);
+ ROW(abc, A, 0, -1, 0);
+ ROW(abc, a, 1, -1, -1);
+ ROW(abc, A, 1, -1, -1);
+ ROW(abc, b, 0, 1, 1);
+ ROW(abc, B, 0, -1, 1);
+ ROW(abc, b, 1, 1, 1);
+ ROW(abc, B, 1, -1, 1);
+ ROW(abc, B, 2, -1, -1);
+
+ ROW(ABC, A, 0, 0, 0);
+ ROW(ABC, a, 0, -1, 0);
+ ROW(ABC, A, 1, -1, -1);
+ ROW(ABC, a, 1, -1, -1);
+ ROW(ABC, B, 0, 1, 1);
+ ROW(ABC, b, 0, -1, 1);
+ ROW(ABC, B, 1, 1, 1);
+ ROW(ABC, b, 1, -1, 1);
+ ROW(ABC, B, 2, -1, -1);
+
+ if (rhsHasVariableLength) {
+ ROW(aBc, bc, 0, -1, 1);
+ ROW(aBc, Bc, 0, 1, 1);
+ ROW(aBc, bC, 0, -1, 1);
+ ROW(aBc, BC, 0, -1, 1);
+
+ ROW(AbC, bc, 0, -1, 1);
+ ROW(AbC, Bc, 0, -1, 1);
+ ROW(AbC, bC, 0, 1, 1);
+ ROW(AbC, BC, 0, -1, 1);
+ ROW(AbC, BC, 1, -1, 1);
+ ROW(AbC, BC, 2, -1, -1);
+ }
+#undef ROW
+
+}
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::indexOf_impl() const
+{
+ QFETCH(const QString, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QString, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const qsizetype, startpos);
+ QFETCH(const qsizetype, resultCS);
+ QFETCH(const qsizetype, resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(QStringView(haystackU16), haystackL1, haystackU8);
+ const auto needle = make<Needle>(QStringView(needleU16), needleL1, needleU8);
+
+ using size_type = typename Haystack::size_type;
+
+ QCOMPARE_EQ(haystack.indexOf(needle, startpos), size_type(resultCS));
+ QCOMPARE_EQ(haystack.indexOf(needle, startpos, Qt::CaseSensitive), size_type(resultCS));
+ QCOMPARE_EQ(haystack.indexOf(needle, startpos, Qt::CaseInsensitive), size_type(resultCIS));
+}
+
+static QString ABCDEFGHIEfGEFG = QStringLiteral("ABCDEFGHIEfGEFG");
+static QString EFG = QStringLiteral("EFG");
+static QString efg = QStringLiteral("efg");
+static QString asd = QStringLiteral("asd");
+static QString asdf = QStringLiteral("asdf");
+static QString Z = QStringLiteral("Z");
+
+void tst_QStringApiSymmetry::contains_data(bool rhsHasVariableLength)
+{
+ QTest::addColumn<QString>("haystackU16");
+ QTest::addColumn<QLatin1String>("haystackL1");
+ QTest::addColumn<QString>("needleU16");
+ QTest::addColumn<QLatin1String>("needleL1");
+ QTest::addColumn<bool>("resultCS");
+ QTest::addColumn<bool>("resultCIS");
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("haystack: null, needle: null") << null << QLatin1String()
+ << null << QLatin1String() << true << true;
+ QTest::addRow("haystack: empty, needle: null") << empty << QLatin1String("")
+ << null << QLatin1String() << true << true;
+ QTest::addRow("haystack: a, needle: null") << a << QLatin1String("a")
+ << null << QLatin1String() << true << true;
+ QTest::addRow("haystack: null, needle: empty") << null << QLatin1String()
+ << empty << QLatin1String("") << true << true;
+ QTest::addRow("haystack: a, needle: empty") << a << QLatin1String("a")
+ << empty << QLatin1String("") << true << true;
+ QTest::addRow("haystack: empty, needle: empty") << empty << QLatin1String("")
+ << empty << QLatin1String("") << true << true;
+ }
+ QTest::addRow("haystack: empty, needle: a") << empty << QLatin1String("")
+ << a << QLatin1String("a") << false << false;
+ QTest::addRow("haystack: null, needle: a") << null << QLatin1String()
+ << a << QLatin1String("a") << false << false;
+
+#define ROW(h, n, cs, cis) \
+ QTest::addRow("haystack: %s, needle: %s", #h, #n) << h << QLatin1String(#h) \
+ << n << QLatin1String(#n) \
+ << cs << cis
+
+ ROW(ABCDEFGHIEfGEFG, A, true, true);
+ ROW(ABCDEFGHIEfGEFG, a, false, true);
+ ROW(ABCDEFGHIEfGEFG, Z, false, false);
+ if (rhsHasVariableLength) {
+ ROW(ABCDEFGHIEfGEFG, EFG, true, true);
+ ROW(ABCDEFGHIEfGEFG, efg, false, true);
+ }
+ ROW(ABCDEFGHIEfGEFG, E, true, true);
+ ROW(ABCDEFGHIEfGEFG, e, false, true);
+#undef ROW
+}
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::contains_impl() const
+{
+ QFETCH(const QString, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QString, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const bool, resultCS);
+ QFETCH(const bool, resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(QStringView(haystackU16), haystackL1, haystackU8);
+ const auto needle = make<Needle>(QStringView(needleU16), needleL1, needleU8);
+
+ QCOMPARE_EQ(haystack.contains(needle), resultCS);
+ QCOMPARE_EQ(haystack.contains(needle, Qt::CaseSensitive), resultCS);
+ QCOMPARE_EQ(haystack.contains(needle, Qt::CaseInsensitive), resultCIS);
+}
+
+void tst_QStringApiSymmetry::lastIndexOf_data(bool rhsHasVariableLength)
+{
+ QTest::addColumn<QString>("haystackU16");
+ QTest::addColumn<QLatin1String>("haystackL1");
+ QTest::addColumn<QString>("needleU16");
+ QTest::addColumn<QLatin1String>("needleL1");
+ QTest::addColumn<qsizetype>("startpos");
+ QTest::addColumn<qsizetype>("resultCS");
+ QTest::addColumn<qsizetype>("resultCIS");
+
+ constexpr qsizetype zeroPos = 0;
+ constexpr qsizetype minus1Pos = -1;
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("haystack: null, needle: null") << null << QLatin1String()
+ << null << QLatin1String() << minus1Pos << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: empty, needle: null") << empty << QLatin1String("")
+ << null << QLatin1String() << minus1Pos << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: a, needle: null") << a << QLatin1String("a")
+ << null << QLatin1String() << minus1Pos << zeroPos << zeroPos;
+ QTest::addRow("haystack: null, needle: empty") << null << QLatin1String()
+ << empty << QLatin1String("") << minus1Pos << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: a, needle: empty") << a << QLatin1String("a")
+ << empty << QLatin1String("") << minus1Pos << zeroPos << zeroPos;
+ QTest::addRow("haystack: empty, needle: empty") << empty << QLatin1String("")
+ << empty << QLatin1String("") << minus1Pos << minus1Pos << minus1Pos;
+ }
+ QTest::addRow("haystack: empty, needle: a") << empty << QLatin1String("")
+ << a << QLatin1String("a") << minus1Pos << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: null, needle: a") << null << QLatin1String()
+ << a << QLatin1String("a") << minus1Pos << minus1Pos << minus1Pos;
+
+ if (rhsHasVariableLength) {
+ QTest::addRow("haystack: a, needle: null, start 1")
+ << a << QLatin1String("a")
+ << null << QLatin1String() << qsizetype(1) << qsizetype(1) << qsizetype(1);
+ QTest::addRow("haystack: a, needle: empty, start 1")
+ << a << QLatin1String("a")
+ << empty << QLatin1String("") << qsizetype(1) << qsizetype(1) << qsizetype(1);
+ QTest::addRow("haystack: a, needle: null, start 2")
+ << a << QLatin1String("a")
+ << null << QLatin1String() << qsizetype(2) << minus1Pos << minus1Pos;
+ QTest::addRow("haystack: a, needle: empty, start 2")
+ << a << QLatin1String("a")
+ << empty << QLatin1String("") << qsizetype(2) << minus1Pos << minus1Pos;
+ }
+
+#define ROW(h, n, st, cs, cis) \
+ QTest::addRow("haystack: %s, needle: %s, start %d", #h, #n, st) << h << QLatin1String(#h) \
+ << n << QLatin1String(#n) \
+ << qsizetype(st) << qsizetype(cs) << qsizetype(cis)
+
+ if (rhsHasVariableLength)
+ ROW(asd, asdf, -1, -1, -1);
+
+ ROW(ABCDEFGHIEfGEFG, G, -1, 14, 14);
+ ROW(ABCDEFGHIEfGEFG, g, -1, -1, 14);
+ ROW(ABCDEFGHIEfGEFG, G, -3, 11, 11);
+ ROW(ABCDEFGHIEfGEFG, g, -3, -1, 11);
+ ROW(ABCDEFGHIEfGEFG, G, -5, 6, 6);
+ ROW(ABCDEFGHIEfGEFG, g, -5, -1, 6);
+ ROW(ABCDEFGHIEfGEFG, G, 14, 14, 14);
+ ROW(ABCDEFGHIEfGEFG, g, 14, -1, 14);
+ ROW(ABCDEFGHIEfGEFG, G, 13, 11, 11);
+ ROW(ABCDEFGHIEfGEFG, g, 13, -1, 11);
+ ROW(ABCDEFGHIEfGEFG, G, 15, 14, 14);
+ ROW(ABCDEFGHIEfGEFG, g, 15, -1, 14);
+ ROW(ABCDEFGHIEfGEFG, B, 14, 1, 1);
+ ROW(ABCDEFGHIEfGEFG, b, 14, -1, 1);
+ ROW(ABCDEFGHIEfGEFG, B, -1, 1, 1);
+ ROW(ABCDEFGHIEfGEFG, b, -1, -1, 1);
+ ROW(ABCDEFGHIEfGEFG, B, 1, 1, 1);
+ ROW(ABCDEFGHIEfGEFG, b, 1, -1, 1);
+ ROW(ABCDEFGHIEfGEFG, B, 0, -1, -1);
+ ROW(ABCDEFGHIEfGEFG, b, 0, -1, -1);
+ ROW(ABCDEFGHIEfGEFG, A, 0, 0, 0);
+ ROW(ABCDEFGHIEfGEFG, a, 0, -1, 0);
+ ROW(ABCDEFGHIEfGEFG, A, -15, 0, 0);
+ ROW(ABCDEFGHIEfGEFG, a, -15, -1, 0);
+
+ if (rhsHasVariableLength) {
+ ROW(ABCDEFGHIEfGEFG, efg, 0, -1, -1);
+ ROW(ABCDEFGHIEfGEFG, efg, 15, -1, 12);
+ ROW(ABCDEFGHIEfGEFG, efg, -15, -1, -1);
+ ROW(ABCDEFGHIEfGEFG, efg, 14, -1, 12);
+ ROW(ABCDEFGHIEfGEFG, efg, 12, -1, 12);
+ ROW(ABCDEFGHIEfGEFG, efg, -12, -1, -1);
+ ROW(ABCDEFGHIEfGEFG, efg, 11, -1, 9);
+ }
+#undef ROW
+}
+
+template <typename Haystack, typename Needle>
+void tst_QStringApiSymmetry::lastIndexOf_impl() const
+{
+ QFETCH(const QString, haystackU16);
+ QFETCH(const QLatin1String, haystackL1);
+ QFETCH(const QString, needleU16);
+ QFETCH(const QLatin1String, needleL1);
+ QFETCH(const qsizetype, startpos);
+ QFETCH(const qsizetype, resultCS);
+ QFETCH(const qsizetype, resultCIS);
+
+ const auto haystackU8 = haystackU16.toUtf8();
+ const auto needleU8 = needleU16.toUtf8();
+
+ const auto haystack = make<Haystack>(QStringView(haystackU16), haystackL1, haystackU8);
+ const auto needle = make<Needle>(QStringView(needleU16), needleL1, needleU8);
+
+ using size_type = typename Haystack::size_type;
+
+ QCOMPARE_EQ(haystack.lastIndexOf(needle, startpos), size_type(resultCS));
+ QCOMPARE_EQ(haystack.lastIndexOf(needle, startpos, Qt::CaseSensitive), size_type(resultCS));
+ QCOMPARE_EQ(haystack.lastIndexOf(needle, startpos, Qt::CaseInsensitive), size_type(resultCIS));
+
+ if (startpos == haystack.size() ||
+ (startpos == -1 && help::size(needle) > 0)) { // -1 skips past-the-end-match w/empty needle
+ // check that calls without an explicit 'from' argument work, too:
+ QCOMPARE_EQ(haystack.lastIndexOf(needle), size_type(resultCS));
+ QCOMPARE_EQ(haystack.lastIndexOf(needle, Qt::CaseSensitive), size_type(resultCS));
+ QCOMPARE_EQ(haystack.lastIndexOf(needle, Qt::CaseInsensitive), size_type(resultCIS));
+ }
+}
+
+void tst_QStringApiSymmetry::indexOf_contains_lastIndexOf_count_regexp_data()
+{
+ QTest::addColumn<QString>("subject");
+ QTest::addColumn<QRegularExpression>("regexp");
+ QTest::addColumn<qsizetype>("leftFrom");
+ QTest::addColumn<qsizetype>("indexOf");
+ QTest::addColumn<qsizetype>("count");
+ QTest::addColumn<qsizetype>("rightFrom");
+ QTest::addColumn<qsizetype>("lastIndexOf");
+
+ const auto ROW = [](const char *subject,
+ const char *pattern,
+ QRegularExpression::PatternOptions options,
+ qsizetype leftFrom, qsizetype indexOf, qsizetype count,
+ qsizetype rightFrom, qsizetype lastIndexOf)
+ {
+ QTest::addRow("subject \"%s\" pattern \"%s\" options %d leftFrom %d rightFrom %d",
+ subject, pattern, (int)options, (int)leftFrom, (int)rightFrom)
+ << subject
+ << QRegularExpression(pattern, options)
+ << leftFrom
+ << indexOf
+ << count
+ << rightFrom
+ << lastIndexOf;
+ };
+
+ ROW("", "", QRegularExpression::NoPatternOption, 0, 0, 1, -1, -1);
+ ROW("", "", QRegularExpression::NoPatternOption, 0, 0, 1, 0, 0);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, -1, 3);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, -2, 2);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, -3, 1);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, -4, 0);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, -5, -1);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, 0, 0);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, 1, 1);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, 2, 2);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, 3, 3);
+ ROW("test", "", QRegularExpression::NoPatternOption, 0, 0, 5, 4, 4);
+ ROW("", "^", QRegularExpression::NoPatternOption, 0, 0, 1, -1, -1);
+ ROW("", "^", QRegularExpression::NoPatternOption, 0, 0, 1, 0, 0);
+ ROW("", "$", QRegularExpression::NoPatternOption, 0, 0, 1, -1, -1);
+ ROW("", "$", QRegularExpression::NoPatternOption, 0, 0, 1, 0, 0);
+ ROW("", "^$", QRegularExpression::NoPatternOption, 0, 0, 1, -1, -1);
+ ROW("", "^$", QRegularExpression::NoPatternOption, 0, 0, 1, 0, 0);
+ ROW("", "x", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("", "x", QRegularExpression::NoPatternOption, 0, -1, 0, 0, -1);
+ ROW("", "^x", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("", "^x", QRegularExpression::NoPatternOption, 0, -1, 0, 0, -1);
+ ROW("", "x$", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("", "x$", QRegularExpression::NoPatternOption, 0, -1, 0, 0, -1);
+ ROW("", "^x$", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("", "^x$", QRegularExpression::NoPatternOption, 0, -1, 0, 0, -1);
+
+ ROW("test", "e", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "es", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "es", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "es?", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "es?", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "es+", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "es+", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "e.", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e.", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "e.*", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e.*", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "e(?=s)", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e(?!x)", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "ex?s", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "(?<=t)e", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "(?<!x)e", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, 0, 0);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, 1, 0);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, 2, 0);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, 3, 3);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, 4, 3);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, -1, 3);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, -2, 0);
+ ROW("test", "t", QRegularExpression::NoPatternOption, 0, 0, 2, -3, 0);
+
+ ROW("test", "^es", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("test", "^es", QRegularExpression::NoPatternOption, 0, -1, 0, -2, -1);
+ ROW("test", "es$", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("test", "ex", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("test", "ex?", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "ex+", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("test", "e(?=x)", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+ ROW("test", "e(?!s)", QRegularExpression::NoPatternOption, 0, -1, 0, -1, -1);
+
+
+ ROW("test", "e.*t", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e.*t", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "e.*t", QRegularExpression::NoPatternOption, 0, 1, 1, -3, 1);
+ ROW("test", "e.*t", QRegularExpression::NoPatternOption, 0, 1, 1, -4, -1);
+ ROW("test", "e.*t", QRegularExpression::NoPatternOption, 0, 1, 1, -5, -1);
+ ROW("test", "e.*t$", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e.*t$", QRegularExpression::NoPatternOption, 0, 1, 1, -2, 1);
+ ROW("test", "e.*st", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "e.*st$", QRegularExpression::NoPatternOption, 0, 1, 1, -1, 1);
+ ROW("test", "t.*t", QRegularExpression::NoPatternOption, 0, 0, 1, -1, 0);
+ ROW("test", "t.*t", QRegularExpression::NoPatternOption, 0, 0, 1, -2, 0);
+ ROW("test", "st", QRegularExpression::NoPatternOption, 0, 2, 1, -1, 2);
+ ROW("test", "st", QRegularExpression::NoPatternOption, 0, 2, 1, -2, 2);
+ ROW("test", "st", QRegularExpression::NoPatternOption, 0, 2, 1, -3, -1);
+ ROW("test", "st", QRegularExpression::NoPatternOption, 0, 2, 1, -4, -1);
+
+ ROW("", "", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, -1, -1);
+ ROW("", "", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, 0, 0);
+ ROW("test", "", QRegularExpression::CaseInsensitiveOption, 0, 0, 5, -1, 3);
+ ROW("test", "", QRegularExpression::CaseInsensitiveOption, 0, 0, 5, 4, 4);
+ ROW("test", "^", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, -1, 0);
+ ROW("test", "^", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, 4, 0);
+ ROW("test", "^t", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, -1, 0);
+ ROW("test", "^t", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, 4, 0);
+ ROW("TEST", "^t", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, -1, 0);
+ ROW("TEST", "^t", QRegularExpression::CaseInsensitiveOption, 0, 0, 1, 4, 0);
+ ROW("test", "e", QRegularExpression::CaseInsensitiveOption, 0, 1, 1, -1, 1);
+ ROW("TEST", "e", QRegularExpression::CaseInsensitiveOption, 0, 1, 1, -1, 1);
+ ROW("TEST", "es", QRegularExpression::CaseInsensitiveOption, 0, 1, 1, -1, 1);
+ ROW("test", "ES", QRegularExpression::CaseInsensitiveOption, 0, 1, 1, -1, 1);
+ ROW("TEST", "ex?s", QRegularExpression::CaseInsensitiveOption, 0, 1, 1, -1, 1);
+
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -1, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -2, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -3, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -4, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -5, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -6, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -7, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 0, 1, 2, -8, -1);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 0, 1, 2, -1, 5);
+ ROW("testtest", "e.*s", QRegularExpression::NoPatternOption, 0, 1, 2, -1, 1);
+
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 1, 1, 2, -1, 5);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 1, 1, 2, -1, 5);
+ ROW("testtest", "e.*s", QRegularExpression::NoPatternOption, 1, 1, 2, -1, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, 2, 5, 1, -1, 5);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 2, 5, 1, -1, 5);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 2, 5, 1, -2, 5);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 2, 5, 1, -3, 5);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 2, 5, 1, -4, 1);
+ ROW("testtest", "es", QRegularExpression::NoPatternOption, 2, 5, 1, -5, 1);
+ ROW("testtest", "e.*s", QRegularExpression::NoPatternOption, 2, 5, 1, -1, 1);
+
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 0, -1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 1, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 2, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 3, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 4, 1);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 5, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 6, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -1, -1, 0, 7, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -2, -1, 0, -1, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -3, 5, 1, -1, 5);
+ ROW("testtest", "e", QRegularExpression::NoPatternOption, -4, 5, 1, -1, 5);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 0, 0);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 1, 0);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 2, 0);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 3, 3);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 4, 4);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 5, 4);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 6, 4);
+ ROW("testtest", "t", QRegularExpression::NoPatternOption, 0, 0, 4, 7, 7);
+ ROW("testtest", "t(?!e)", QRegularExpression::NoPatternOption, 0, 3, 2, 0, -1);
+ ROW("testtest", "t(?!e)", QRegularExpression::NoPatternOption, 0, 3, 2, 1, -1);
+ ROW("testtest", "t(?!e)", QRegularExpression::NoPatternOption, 0, 3, 2, 2, -1);
+ ROW("testtest", "t(?!e)", QRegularExpression::NoPatternOption, 0, 3, 2, 3, 3);
+ ROW("testtest", "t(?!e)", QRegularExpression::NoPatternOption, 0, 3, 2, 4, 3);
+ ROW("testtest", "t(?!e)", QRegularExpression::NoPatternOption, 0, 3, 2, -1, 7);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -1, -1, 0, 0, -1);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -1, -1, 0, 1, -1);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -1, -1, 0, 2, -1);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -1, -1, 0, 3, 3);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -1, -1, 0, 4, 3);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -2, -1, 0, 0, -1);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -3, -1, 0, 0, -1);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -4, -1, 0, 0, -1);
+ ROW("testtest", "tt", QRegularExpression::NoPatternOption, -5, 3, 1, -1, 3);
+
+ ROW("testtest", "(?<=t)e", QRegularExpression::NoPatternOption, 1, 1, 1, -1, 5); // the count is 1 because in the test we _cut_ the string before the lookbehind
+ ROW("testtest", "(?<=t)e", QRegularExpression::NoPatternOption, 2, 5, 1, -1, 5);
+ ROW("testtest", "(?<=t)e", QRegularExpression::NoPatternOption, 3, 5, 1, -1, 5);
+ ROW("testtest", "(?<=t)e", QRegularExpression::NoPatternOption, 4, 5, 1, -1, 5);
+ ROW("testtest", "(?<=t)e", QRegularExpression::NoPatternOption, 5, 5, 0, -1, 5); // the count is 0 because in the test we _cut_ the string before the lookbehind
+ ROW("testtest", "(?<=t)e", QRegularExpression::NoPatternOption, 6, -1, 0, -1, 5);
+
+ ROW("foo bar blubb", "\\s+", QRegularExpression::NoPatternOption, 0, 3, 2, -1, 7);
+ ROW("foo bar blubb", "\\s+", QRegularExpression::NoPatternOption, 0, 3, 2, -7, 3);
+}
+
+template <typename String>
+void tst_QStringApiSymmetry::indexOf_contains_lastIndexOf_count_regexp_impl() const
+{
+ QFETCH(QString, subject);
+ QFETCH(QRegularExpression, regexp);
+ QFETCH(qsizetype, leftFrom);
+ QFETCH(qsizetype, indexOf);
+ QFETCH(qsizetype, count);
+ QFETCH(qsizetype, rightFrom);
+ QFETCH(qsizetype, lastIndexOf);
+
+ // indexOf
+ String s = subject;
+ qsizetype result = s.indexOf(regexp, leftFrom);
+ QCOMPARE_EQ(result, indexOf);
+
+ // contains
+ if (result >= 0)
+ QVERIFY(s.contains(regexp));
+ else if (leftFrom == 0)
+ QVERIFY(!s.contains(regexp));
+
+ // count
+ if (leftFrom >= 0)
+ QCOMPARE_EQ(s.mid(leftFrom).count(regexp), count);
+ else
+ QCOMPARE_EQ(s.mid(leftFrom + s.size()).count(regexp), count);
+
+ // lastIndexOf
+ result = s.lastIndexOf(regexp, rightFrom);
+ QCOMPARE_EQ(result, lastIndexOf);
+ if (rightFrom == s.size()) {
+ result = s.lastIndexOf(regexp);
+ QCOMPARE_EQ(result, lastIndexOf);
+ }
+}
+
+void tst_QStringApiSymmetry::isValidUtf8_data()
+{
+ QTest::addColumn<QByteArray>("ba");
+ QTest::addColumn<bool>("valid");
+
+ int row = 0;
+ QTest::addRow("valid-%02d", row++) << QByteArray() << true;
+ QTest::addRow("valid-%02d", row++) << QByteArray("ascii") << true;
+ QTest::addRow("valid-%02d", row++)
+ << QByteArray("\xc2\xa2\xe0\xa4\xb9\xf0\x90\x8d\x88") << true; // U+00A2 U+0939 U+10348
+ QTest::addRow("valid-%02d", row++) << QByteArray("\xf4\x8f\xbf\xbf") << true; // U+10FFFF
+
+ row = 0;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xc0\x00") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xc1\xff") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xc1\xbf") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xc1\x01") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xe0\x00\x00") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xe0\xa0\x7f") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xf0\x00\x00\x00") << false;
+ QTest::addRow("overlong-%02d", row++) << QByteArray("\xf0\x90\x80\x7f") << false;
+
+ row = 0;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xc2") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xc2") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xc2y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xc2y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xe0\xa4") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xe0\xa4") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xe0\xa4y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xe0\xa4y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xe0") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xe0") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xe0y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xe0y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xf4\x8f\xbf") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xf4\x8f\xbf") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xf4\x8f\xbfy") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xf4\x8f\xbfy") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xf4\x8f") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xf4\x8f") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xf4\x8fy") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xf4\x8fy") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xf4") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xf4") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("x\xf4y") << false;
+ QTest::addRow("short-%02d", row++) << QByteArray("\xf4y") << false;
+
+ row = 0;
+ QTest::addRow("surrogates-%02d", row++) << QByteArray("\xed\x9f\xc0\xee\x80\x7f") << false;
+ QTest::addRow("surrogates-%02d", row++) << QByteArray("\xed\x9f\xc0") << false;
+ QTest::addRow("surrogates-%02d", row++) << QByteArray("\xee\x80\x7f") << false;
+ QTest::addRow("surrogates-%02d", row++) << QByteArray("\xee\x80\x7f\xed\x9f\xc0") << false;
+
+ row = 0;
+ QTest::addRow("other-%02d", row++) << QByteArray("\xf4\x8f\xbf\xc0") << false;
+ QTest::addRow("other-%02d", row++) << QByteArray("\xf7\x80\x80\x80") << false;
+ QTest::addRow("other-%02d", row++) << QByteArray("\xfd\xbf\xbf\xbf\xbf") << false;
+ QTest::addRow("other-%02d", row++) << QByteArray("\xfe\xbf\xbf\xbf\xbf\xbf") << false;
+ QTest::addRow("other-%02d", row++) << QByteArray("\xff\xbf\xbf\xbf\xbf\xbf\xbf") << false;
+ QTest::addRow("other-%02d", row++) << QByteArray("\x80") << false;
+ QTest::addRow("other-%02d", row++) << QByteArray("\xbf") << false;
+}
+
+template<typename String>
+void tst_QStringApiSymmetry::isValidUtf8_impl() const
+{
+ QFETCH(QByteArray, ba);
+ const String string(ba);
+ QTEST(string.isValidUtf8(), "valid");
+}
+
+QTEST_APPLESS_MAIN(tst_QStringApiSymmetry)
+
+#include "tst_qstringapisymmetry.moc"
diff --git a/tests/auto/corelib/text/qstringbuilder/CMakeLists.txt b/tests/auto/corelib/text/qstringbuilder/CMakeLists.txt
new file mode 100644
index 0000000000..2ac5d1a73e
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qstringbuilder1)
+add_subdirectory(qstringbuilder2)
+add_subdirectory(qstringbuilder3)
+add_subdirectory(qstringbuilder4)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/CMakeLists.txt b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/CMakeLists.txt
new file mode 100644
index 0000000000..069b7573ba
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringbuilder1 Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringbuilder1 LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringbuilder1
+ SOURCES
+ tst_qstringbuilder1.cpp
+)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp
new file mode 100644
index 0000000000..59362d010a
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp
@@ -0,0 +1,578 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+// Do not include anything in this file. We are being #included in the unnamed namespace
+// with a bunch of defines that may break other legitimate code.
+
+#define LITERAL "some literal"
+#define LITERAL_LEN (sizeof(LITERAL)-1)
+#define LITERAL_EXTRA "some literal" "EXTRA"
+
+// "some literal", but replacing all vowels by their umlauted UTF-8 string :)
+#define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l"
+#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1)
+#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA"
+
+// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
+#define UNICODE_LITERAL u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l"
+#define UNICODE_LITERAL_LEN ((sizeof(UNICODE_LITERAL) - 1) / 2)
+#define UNICODE_LITERAL_EXTRA u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l" "EXTRA"
+
+#ifndef P
+# error You need to define P
+#endif
+
+//fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS
+#ifndef QT_USE_FAST_CONCATENATION
+#define Q %
+#else
+#define Q P
+#endif
+
+template <typename T> QString toQString(const T &t);
+
+template <> QString toQString(const QString &s) { return s; }
+template <> QString toQString(const QStringView &v) { return v.toString(); }
+template <> QString toQString(const QLatin1String &l) { return l; }
+template <> QString toQString(const QLatin1Char &l) { return QChar(l); }
+template <> QString toQString(const QChar &c) { return c; }
+template <> QString toQString(const QChar::SpecialCharacter &c) { return QChar(c); }
+template <> QString toQString(char16_t * const &p) { return QStringView(p).toString(); }
+template <size_t N> QString toQString(const char16_t (&a)[N]) { return QStringView(a).toString(); }
+template <> QString toQString(const char16_t &c) { return QChar(c); }
+
+template <typename T> QByteArray toQByteArray(const T &t);
+
+template <> QByteArray toQByteArray(const QByteArray &b) { return b; }
+template <> QByteArray toQByteArray(const QByteArrayView &bav) { return bav.toByteArray(); }
+template <> QByteArray toQByteArray(char * const &p) { return p; }
+template <size_t N> QByteArray toQByteArray(const char (&a)[N]) { return a; }
+template <> QByteArray toQByteArray(const char &c) { return QByteArray(&c, 1); }
+
+template <typename String, typename Separator>
+void checkItWorksWithFreeSpaceAtBegin(const String &chunk, const Separator &separator)
+{
+ // GIVEN: a String with freeSpaceAtBegin() and less than chunk.size() freeSpaceAtEnd()
+ String str;
+
+ int prepends = 0;
+ const int max_prepends = 10;
+ while (str.data_ptr().freeSpaceAtBegin() < chunk.size() && prepends++ < max_prepends)
+ str.prepend(chunk);
+ QVERIFY(prepends < max_prepends);
+
+ int appends = 0;
+ const int max_appends = 100;
+ while (str.data_ptr().freeSpaceAtEnd() >= chunk.size() && appends++ < max_appends)
+ str.append(chunk);
+ QVERIFY(appends < max_appends);
+
+ QVERIFY(str.capacity() - str.size() >= chunk.size());
+ QVERIFY(str.data_ptr().freeSpaceAtEnd() < chunk.size());
+
+ // WHEN: adding a QStringBuilder expression which exceeds freeSpaceAtEnd()
+ str += separator P chunk;
+
+ // THEN: it doesn't crash (QTBUG-99330)
+ const String expected = chunk.repeated(prepends + appends) + separator + chunk;
+ QCOMPARE(str, expected);
+}
+
+template <typename String>
+void checkNullVsEmpty(const String &empty)
+{
+ String a;
+ String b;
+ QVERIFY(a.isNull());
+ QVERIFY(b.isNull());
+ String result = a P b;
+ QVERIFY(result.isNull());
+
+ String d = empty;
+ QVERIFY(d.isEmpty());
+ QVERIFY(!d.isNull());
+ result = a P d;
+ QVERIFY(result.isEmpty());
+ QVERIFY(!result.isNull());
+
+ result = a P a P a;
+ QVERIFY(result.isNull());
+}
+
+namespace CheckAuto {
+// T is cvref-qualified, using universal reference deduction rules.
+template <typename T> struct Helper;
+
+// These specializations forward to the non-const ones, and add const on top.
+template <typename T> struct Helper<const T>
+{
+ static const T create() { return Helper<T>::create(); }
+ static const T createNull() { return Helper<T>::createNull(); }
+};
+template <typename T> struct Helper<const T &>
+{
+ static const T &create() { return Helper<T &>::create(); }
+ static const T &createNull() { return Helper<T &>::createNull(); }
+};
+
+template <> struct Helper<QString>
+{
+ static QString create() { return QString::fromUtf8("QString rvalue"); }
+ static QString createNull() { return QString(); }
+};
+
+template <> struct Helper<QString &>
+{
+ static QString &create() { static QString s = QString::fromUtf8("QString lvalue"); return s; }
+ static QString &createNull() { static QString s; return s; }
+};
+
+template <> struct Helper<QStringView>
+{
+ static QStringView create() { return QStringView(u"QStringView rvalue"); }
+ static QStringView createNull() { return QStringView(); }
+};
+
+template <> struct Helper<QStringView &>
+{
+ static QStringView &create() { static QStringView s = u"QStringView lvalue"; return s; }
+ static QStringView &createNull() { static QStringView s; return s; }
+};
+
+template <> struct Helper<QByteArray>
+{
+ static QByteArray create() { return QByteArray("QByteArray rvalue"); }
+ static QByteArray createNull() { return QByteArray(); }
+};
+
+template <> struct Helper<QByteArray &>
+{
+ static QByteArray &create() { static QByteArray ba = QByteArray("QByteArray lvalue"); return ba; }
+ static QByteArray &createNull() { static QByteArray ba; return ba; }
+};
+
+template <> struct Helper<QByteArrayView>
+{
+ static QByteArrayView create() { return QByteArrayView("QByteArrayView rvalue"); }
+ static QByteArrayView createNull() { return QByteArrayView(); }
+};
+
+template <> struct Helper<QByteArrayView &>
+{
+ static QByteArrayView &create() { static QByteArrayView ba = "QByteArrayView lvalue"; return ba; }
+ static QByteArrayView &createNull() { static QByteArrayView ba; return ba; }
+};
+
+template <> struct Helper<const char *>
+{
+ static const char *create() { return "const char * rvalue"; }
+ static const char *createNull() { return ""; }
+};
+
+template <> struct Helper<const char *&>
+{
+ static const char *&create() { static const char *s = "const char * lvalue"; return s; }
+ static const char *&createNull() { static const char *s = ""; return s; }
+};
+
+template <typename String1, typename String2, typename Result>
+void checkAutoImpl3()
+{
+ {
+ auto result = Helper<String1>::create() P Helper<String2>::create();
+ Result expected = result;
+ QCOMPARE(result, expected);
+ }
+ {
+ auto result = Helper<String2>::create() P Helper<String1>::create();
+ Result expected = result;
+ QCOMPARE(result, expected);
+ }
+ {
+ auto result = Helper<String1>::create() P Helper<String2>::create() P Helper<String1>::create();
+ Result expected = result;
+ QCOMPARE(result, expected);
+ }
+ {
+ auto result = Helper<String2>::create() P Helper<String1>::create() P Helper<String2>::create();
+ Result expected = result;
+ QCOMPARE(result, expected);
+ }
+ {
+ auto result = Helper<String1>::createNull() P Helper<String2>::create();
+ Result expected = result;
+ QCOMPARE(result, expected);
+ }
+ {
+ auto result = Helper<String1>::createNull() P Helper<String2>::createNull();
+ Result expected = result;
+ QCOMPARE(result, expected);
+ }
+}
+
+template <typename String1, typename String2, typename Result>
+void checkAutoImpl2()
+{
+ checkAutoImpl3<String1 , String2 , Result>();
+ checkAutoImpl3<String1 &, String2 , Result>();
+ checkAutoImpl3<String1 , String2 &, Result>();
+ checkAutoImpl3<String1 &, String2 &, Result>();
+}
+
+template <typename String1, typename String2, typename Result>
+void checkAutoImpl()
+{
+ checkAutoImpl2< String1, String2, Result>();
+ checkAutoImpl2<const String1, String2, Result>();
+ checkAutoImpl2< String1, const String2, Result>();
+ checkAutoImpl2<const String1, const String2, Result>();
+}
+
+} // namespace CheckAuto
+
+void checkAuto()
+{
+ CheckAuto::checkAutoImpl<QString, QString, QString>();
+ CheckAuto::checkAutoImpl<QString, QStringView, QString>();
+
+ CheckAuto::checkAutoImpl<QByteArray, QByteArray, QByteArray>();
+ CheckAuto::checkAutoImpl<QByteArray, const char *, QByteArray>();
+ CheckAuto::checkAutoImpl<QByteArray, QByteArrayView, QByteArray>();
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ CheckAuto::checkAutoImpl<QString, const char *, QString>();
+ CheckAuto::checkAutoImpl<QString, QByteArray, QString>();
+#endif
+}
+
+void runScenario()
+{
+ // this code is latin1. TODO: replace it with the utf8 block below, once
+ // strings default to utf8.
+ QLatin1String l1string(LITERAL);
+ QString string(l1string);
+ QStringView stringview = QStringView{ string }.mid(2, 10);
+ QLatin1Char lchar('c');
+ QChar qchar(lchar);
+ QChar::SpecialCharacter special(QChar::Nbsp);
+ char16_t u16char = UNICODE_LITERAL[0];
+ char16_t u16chararray[] = { u's', 0xF6, u'm', 0xEB, u' ', u'l', 0xEF, u't', 0xEB, u'r', 0xE4, u'l', 0x00 };
+ QCOMPARE(QStringView(u16chararray), QStringView(UNICODE_LITERAL));
+ char16_t *u16charstar = u16chararray;
+
+#define CHECK(QorP, a1, a2) \
+ do { \
+ QCOMPARE(QString(a1 QorP a2), toQString(a1).append(toQString(a2))); \
+ QCOMPARE(QString(a2 QorP a1), toQString(a2).append(toQString(a1))); \
+ } while (0)
+
+ CHECK(P, l1string, l1string);
+ CHECK(P, l1string, string);
+ CHECK(P, l1string, QString(string));
+ CHECK(Q, l1string, string);
+ CHECK(Q, l1string, QString(string));
+
+ CHECK(Q, l1string, stringview);
+ CHECK(P, l1string, lchar);
+ CHECK(P, l1string, qchar);
+ CHECK(P, l1string, special);
+ CHECK(P, l1string, QStringLiteral(LITERAL));
+ CHECK(Q, l1string, u16char);
+ CHECK(Q, l1string, u16chararray);
+ CHECK(Q, l1string, u16charstar);
+
+ CHECK(P, string, string);
+ CHECK(P, string, QString(string));
+ CHECK(P, QString(string), QString(string));
+ CHECK(Q, string, string);
+ CHECK(Q, string, QString(string));
+ CHECK(Q, QString(string), QString(string));
+
+ CHECK(P, string, stringview);
+ CHECK(P, QString(string), stringview);
+ CHECK(Q, string, stringview);
+ CHECK(Q, QString(string), stringview);
+
+ CHECK(P, string, lchar);
+ CHECK(P, QString(string), lchar);
+ CHECK(Q, string, lchar);
+ CHECK(Q, QString(string), lchar);
+
+ CHECK(P, string, qchar);
+ CHECK(P, QString(string), qchar);
+ CHECK(P, string, special);
+ CHECK(P, QString(string), special);
+ CHECK(P, string, QStringLiteral(LITERAL));
+ CHECK(P, QString(string), QStringLiteral(LITERAL));
+ CHECK(Q, string, qchar);
+ CHECK(Q, QString(string), qchar);
+ CHECK(Q, string, special);
+ CHECK(Q, QString(string), special);
+ CHECK(Q, string, QStringLiteral(LITERAL));
+ CHECK(Q, QString(string), QStringLiteral(LITERAL));
+
+ CHECK(Q, string, u16char);
+ CHECK(Q, QString(string), u16char);
+ CHECK(Q, string, u16chararray);
+ CHECK(Q, QString(string), u16chararray);
+ CHECK(Q, string, u16charstar);
+ CHECK(Q, QString(string), u16charstar);
+
+ CHECK(Q, stringview, stringview);
+ CHECK(Q, stringview, lchar);
+ CHECK(Q, stringview, qchar);
+ CHECK(Q, stringview, special);
+ CHECK(P, stringview, QStringLiteral(LITERAL));
+ CHECK(Q, stringview, QStringLiteral(LITERAL));
+ CHECK(Q, stringview, u16char);
+ CHECK(Q, stringview, u16chararray);
+ CHECK(Q, stringview, u16charstar);
+
+ CHECK(P, lchar, lchar);
+ CHECK(P, lchar, qchar);
+ CHECK(P, lchar, special);
+ CHECK(P, lchar, QStringLiteral(LITERAL));
+ CHECK(Q, lchar, u16char);
+ CHECK(Q, lchar, u16chararray);
+ CHECK(Q, lchar, u16charstar);
+
+ CHECK(P, qchar, qchar);
+ CHECK(P, qchar, special);
+ CHECK(P, qchar, QStringLiteral(LITERAL));
+ CHECK(Q, qchar, u16char);
+ CHECK(Q, qchar, u16chararray);
+ CHECK(Q, qchar, u16charstar);
+
+ CHECK(P, special, special);
+ CHECK(P, special, QStringLiteral(LITERAL));
+ CHECK(Q, special, u16char);
+ CHECK(Q, special, u16chararray);
+ CHECK(Q, special, u16charstar);
+
+ CHECK(P, QStringLiteral(LITERAL), QStringLiteral(LITERAL));
+ CHECK(Q, QStringLiteral(LITERAL), u16char);
+ CHECK(Q, QStringLiteral(LITERAL), u16chararray);
+ CHECK(Q, QStringLiteral(LITERAL), u16charstar);
+
+ // CHECK(Q, u16char, u16char); // BUILTIN <-> BUILTIN cat't be overloaded
+ // CHECK(Q, u16char, u16chararray);
+ // CHECK(Q, u16char, u16charstar);
+
+ // CHECK(Q, u16chararray, u16chararray); // BUILTIN <-> BUILTIN cat't be overloaded
+ // CHECK(Q, u16chararray, u16charstar);
+
+ // CHECK(Q, u16charstar, u16charstar); // BUILTIN <-> BUILTIN cat't be overloaded
+
+#undef CHECK
+
+#define CHECK(QorP, a1, a2) \
+ do { \
+ QCOMPARE(QByteArray(a1 QorP a2), toQByteArray(a1).append(toQByteArray(a2))); \
+ QCOMPARE(QByteArray(a2 QorP a1), toQByteArray(a2).append(toQByteArray(a1))); \
+ } while (0)
+
+ QByteArray bytearray = stringview.toUtf8();
+ QByteArrayView baview = QByteArrayView(bytearray).mid(0, bytearray.size() - 2);
+ char *charstar = bytearray.data();
+ char chararray[3] = { 'H', 'i', '\0' };
+ const char constchararray[3] = { 'H', 'i', '\0' };
+ char achar = 'a';
+
+ CHECK(P, bytearray, bytearray);
+ CHECK(P, QByteArray(bytearray), bytearray);
+ CHECK(P, QByteArray(bytearray), QByteArray(bytearray));
+ CHECK(P, bytearray, baview);
+ CHECK(P, QByteArray(bytearray), baview);
+ CHECK(P, bytearray, charstar);
+ CHECK(Q, bytearray, bytearray);
+ CHECK(Q, QByteArray(bytearray), bytearray);
+ CHECK(Q, QByteArray(bytearray), QByteArray(bytearray));
+ CHECK(Q, bytearray, baview);
+ CHECK(Q, QByteArray(bytearray), baview);
+ CHECK(Q, bytearray, charstar);
+
+#ifndef Q_CC_MSVC // see QTBUG-65359
+ CHECK(P, bytearray, chararray);
+#else
+ Q_UNUSED(chararray);
+#endif
+ CHECK(P, bytearray, constchararray);
+ CHECK(P, bytearray, achar);
+ CHECK(Q, bytearray, constchararray);
+ CHECK(Q, bytearray, achar);
+
+ //CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded
+ //CHECK(Q, charstar, chararray);
+ //CHECK(Q, charstar, achar);
+
+ //CHECK(Q, chararray, chararray); // BUILTIN <-> BUILTIN cat't be overloaded
+ //CHECK(Q, chararray, achar);
+
+ //CHECK(Q, achar, achar); // BUILTIN <-> BUILTIN cat't be overloaded
+
+#undef CHECK
+
+ QString r2(QLatin1String(LITERAL LITERAL));
+ QString r3 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
+ QString r;
+
+ // self-assignment:
+ r = stringview.toString();
+ r = lchar + r;
+ QCOMPARE(r, QString(lchar P stringview));
+
+ r = QStringLiteral(UNICODE_LITERAL);
+ r = r Q QStringLiteral(UNICODE_LITERAL);
+ QCOMPARE(r, r3);
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ r = string P LITERAL;
+ QCOMPARE(r, r2);
+ r = LITERAL P string;
+ QCOMPARE(r, r2);
+
+ QByteArray ba = QByteArray(LITERAL);
+ r = ba P string;
+ QCOMPARE(r, r2);
+ r = string P ba;
+ QCOMPARE(r, r2);
+
+ r = string P QByteArrayLiteral(LITERAL);
+ QCOMPARE(r, r2);
+ r = QByteArrayLiteral(LITERAL) P string;
+ QCOMPARE(r, r2);
+
+ static const char badata[] = LITERAL_EXTRA;
+ ba = QByteArray::fromRawData(badata, LITERAL_LEN);
+ r = ba P string;
+ QCOMPARE(r, r2);
+ r = string P ba;
+ QCOMPARE(r, r2);
+
+ string = QString::fromUtf8(UTF8_LITERAL);
+ ba = UTF8_LITERAL;
+
+ r = string P UTF8_LITERAL;
+ QCOMPARE(r.size(), r3.size());
+ QCOMPARE(r, r3);
+ r = UTF8_LITERAL P string;
+ QCOMPARE(r, r3);
+ r = ba P string;
+ QCOMPARE(r, r3);
+ r = string P ba;
+ QCOMPARE(r, r3);
+
+ ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
+ r = ba P string;
+ QCOMPARE(r, r3);
+ r = string P ba;
+ QCOMPARE(r, r3);
+
+ ba = QByteArray(); // empty
+ r = ba P string;
+ QCOMPARE(r, string);
+ r = string P ba;
+ QCOMPARE(r, string);
+
+ const char *zero = nullptr;
+ r = string P zero;
+ QCOMPARE(r, string);
+ r = zero P string;
+ QCOMPARE(r, string);
+#endif
+
+ string = QString::fromLatin1(LITERAL);
+ QCOMPARE(QByteArray(qPrintable(string P string)), QByteArray(string.toLatin1() + string.toLatin1()));
+
+
+
+ //QByteArray
+ {
+ QByteArray ba = LITERAL;
+ QByteArray superba = ba P ba P LITERAL;
+ QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
+
+ ba = QByteArrayLiteral(LITERAL);
+ QCOMPARE(ba, QByteArray(LITERAL));
+ superba = ba P QByteArrayLiteral(LITERAL) P LITERAL;
+ QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
+
+ QByteArray testWith0 = ba P "test\0with\0zero" P ba;
+ QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL));
+
+ QByteArray ba2 = ba P '\0' + LITERAL;
+ QCOMPARE(ba2, QByteArray(LITERAL "\0" LITERAL, ba.size()*2+1));
+
+ const char *mmh = "test\0foo";
+ QCOMPARE(QByteArray(ba P mmh P ba), testWith0);
+
+ QByteArray raw = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
+ QByteArray r = "hello" P raw;
+ QByteArray r2 = "hello" UTF8_LITERAL;
+ QCOMPARE(r, r2);
+ r2 = QByteArray("hello\0") P UTF8_LITERAL;
+ QCOMPARE(r, r2);
+
+ const char *zero = nullptr;
+ r = ba P zero;
+ QCOMPARE(r, ba);
+ r = zero P ba;
+ QCOMPARE(r, ba);
+
+ QByteArrayView qbav = LITERAL;
+ superba = qbav P qbav P LITERAL;
+ QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
+ }
+
+ //operator QString +=
+ {
+ QString str = QString::fromUtf8(UTF8_LITERAL);
+ str += QLatin1String(LITERAL) P str;
+ QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
+#ifndef QT_NO_CAST_FROM_ASCII
+ str = (QString::fromUtf8(UTF8_LITERAL) += QLatin1String(LITERAL) P UTF8_LITERAL);
+ QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
+#endif
+
+ QString str2 = QString::fromUtf8(UTF8_LITERAL);
+ QString str2_e = QString::fromUtf8(UTF8_LITERAL);
+ const char * nullData = 0;
+ str2 += QLatin1String(nullData) P str2;
+ str2_e += QLatin1String("") P str2_e;
+ QCOMPARE(str2, str2_e);
+ }
+
+ checkItWorksWithFreeSpaceAtBegin(QString::fromUtf8(UTF8_LITERAL),
+ #ifdef QT_NO_CAST_FROM_ASCII
+ QLatin1String("1234")
+ #else
+ "1234"
+ #endif
+ );
+ if (QTest::currentTestFailed())
+ return;
+
+ //operator QByteArray +=
+ {
+ QByteArray ba = UTF8_LITERAL;
+ ba += QByteArray(LITERAL) P UTF8_LITERAL;
+ QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
+ ba += LITERAL P QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
+ QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL LITERAL UTF8_LITERAL));
+ QByteArray withZero = QByteArray(LITERAL "\0" LITERAL, LITERAL_LEN*2+1);
+ QByteArray ba2 = withZero;
+ ba2 += ba2 P withZero;
+ QCOMPARE(ba2, QByteArray(withZero + withZero + withZero));
+ }
+
+ // null vs. empty
+ checkNullVsEmpty(QStringLiteral(""));
+ checkNullVsEmpty(QByteArrayLiteral(""));
+
+ // auto
+ checkAuto();
+
+ checkItWorksWithFreeSpaceAtBegin(QByteArray(UTF8_LITERAL), "1234");
+ if (QTest::currentTestFailed())
+ return;
+}
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp
new file mode 100644
index 0000000000..394372c398
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qglobal.h>
+
+// SCENARIO 1
+// this is the "no harm done" version. Only operator% is active,
+// with NO_CAST * defined
+#undef QT_USE_QSTRINGBUILDER
+#define QT_NO_CAST_FROM_ASCII
+#define QT_NO_CAST_TO_ASCII
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringBuilder>
+#include <QtTest/QTest>
+
+#define LITERAL "some literal"
+
+namespace {
+#define P %
+#include "stringbuilder.cpp"
+#undef P
+} // namespace
+
+class tst_QStringBuilder1 : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void scenario() { runScenario(); }
+};
+
+#include "tst_qstringbuilder1.moc"
+
+QTEST_APPLESS_MAIN(tst_QStringBuilder1)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/CMakeLists.txt b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/CMakeLists.txt
new file mode 100644
index 0000000000..8db076581a
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringbuilder2 Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringbuilder2 LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringbuilder2
+ SOURCES
+ tst_qstringbuilder2.cpp
+)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp
new file mode 100644
index 0000000000..dc590304f5
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qglobal.h>
+
+// SCENARIO 2
+// this is the "full" version. Operator+ is replaced by a QStringBuilder
+// based version
+// with NO_CAST * defined
+#define QT_USE_QSTRINGBUILDER
+#define QT_NO_CAST_FROM_ASCII
+#define QT_NO_CAST_TO_ASCII
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringBuilder>
+#include <QtTest/QTest>
+
+#define LITERAL "some literal"
+
+namespace {
+#define P +
+#include "../qstringbuilder1/stringbuilder.cpp"
+#undef P
+} // namespace
+
+class tst_QStringBuilder2 : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void scenario() { runScenario(); }
+};
+
+#include "tst_qstringbuilder2.moc"
+
+QTEST_APPLESS_MAIN(tst_QStringBuilder2)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/CMakeLists.txt b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/CMakeLists.txt
new file mode 100644
index 0000000000..177b41bf2f
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringbuilder3 Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringbuilder3 LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringbuilder3
+ SOURCES
+ tst_qstringbuilder3.cpp
+)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp
new file mode 100644
index 0000000000..3222b52713
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qglobal.h>
+
+// SCENARIO 3
+// this is the "no harm done" version. Only operator% is active,
+// with NO_CAST * _not_ defined
+#undef QT_USE_QSTRINGBUILDER
+#undef QT_NO_CAST_FROM_ASCII
+#undef QT_NO_CAST_TO_ASCII
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringBuilder>
+#include <QtTest/QTest>
+
+#define LITERAL "some literal"
+
+namespace {
+#define P %
+#include "../qstringbuilder1/stringbuilder.cpp"
+#undef P
+} // namespace
+
+class tst_QStringBuilder3 : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void scenario() { runScenario(); }
+};
+
+#include "tst_qstringbuilder3.moc"
+
+QTEST_APPLESS_MAIN(tst_QStringBuilder3)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/CMakeLists.txt b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/CMakeLists.txt
new file mode 100644
index 0000000000..94883b498a
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringbuilder4 Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringbuilder4 LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringbuilder4
+ SOURCES
+ tst_qstringbuilder4.cpp
+)
diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp
new file mode 100644
index 0000000000..442c5275d2
--- /dev/null
+++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qglobal.h>
+
+// SCENARIO 4
+// this is the "full" version. Operator+ is replaced by a QStringBuilder
+// based version
+// with NO_CAST * _not_ defined
+#define QT_USE_QSTRINGBUILDER
+#undef QT_NO_CAST_FROM_ASCII
+#undef QT_NO_CAST_TO_ASCII
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringBuilder>
+#include <QtTest/QTest>
+
+#define LITERAL "some literal"
+
+namespace {
+#define P +
+#include "../qstringbuilder1/stringbuilder.cpp"
+#undef P
+} // namespace
+
+class tst_QStringBuilder4 : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void scenario() { runScenario(); }
+};
+
+#include "tst_qstringbuilder4.moc"
+
+QTEST_APPLESS_MAIN(tst_QStringBuilder4)
diff --git a/tests/auto/corelib/text/qstringconverter/CMakeLists.txt b/tests/auto/corelib/text/qstringconverter/CMakeLists.txt
new file mode 100644
index 0000000000..22378fe96b
--- /dev/null
+++ b/tests/auto/corelib/text/qstringconverter/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringconverter Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringconverter LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringconverter
+ SOURCES
+ tst_qstringconverter.cpp
+ TESTDATA ${test_data}
+ LIBRARIES
+ Qt::CorePrivate # for access to Qt's feature system
+)
+
+
+qt_internal_add_resource(tst_qstringconverter "compressedtexture_bc1"
+ PREFIX
+ "/"
+ FILES
+ "euc_kr.txt"
+)
diff --git a/tests/auto/corelib/text/qstringconverter/euc_kr.txt b/tests/auto/corelib/text/qstringconverter/euc_kr.txt
new file mode 100644
index 0000000000..a0eb9af691
--- /dev/null
+++ b/tests/auto/corelib/text/qstringconverter/euc_kr.txt
@@ -0,0 +1 @@
+Ы?Ȫʦ??ɪǪEUC Packed Formatȡ2ЫͳEUC Fixed Width Format롣ġ?ݻ?ĪǡEUCȪ򦪹Ǫ˪Ī?롣
diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
new file mode 100644
index 0000000000..ed3f91ac94
--- /dev/null
+++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp
@@ -0,0 +1,2839 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <QtCore/private/qglobal_p.h>
+#include <qstringconverter.h>
+#include <private/qstringconverter_p.h>
+#include <qthreadpool.h>
+
+#include <array>
+#include <numeric>
+
+using namespace Qt::StringLiterals;
+
+QT_BEGIN_NAMESPACE
+namespace QTest {
+template <typename T>
+char *toString(const std::optional<T> &opt)
+{
+ if (opt)
+ return QTest::toString(*opt);
+ else
+ return qstrdup("std::nullopt");
+}
+} // namespace QTest
+QT_END_NAMESPACE
+
+using QTest::toString;
+
+static constexpr bool IsBigEndian = QSysInfo::ByteOrder == QSysInfo::BigEndian;
+enum CodecLimitation {
+ AsciiOnly,
+ Latin1Only,
+ FullUnicode
+};
+
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+static bool localeIsUtf8()
+{
+ return GetACP() == CP_UTF8;
+}
+#else
+static constexpr bool localeIsUtf8()
+{
+ return true;
+}
+#endif
+
+struct Codec
+{
+ const char name[12];
+ QStringConverter::Encoding code;
+ CodecLimitation limitation = FullUnicode;
+};
+static const std::array codes = {
+ Codec{ "UTF-8", QStringConverter::Utf8 },
+ Codec{ "UTF-16", QStringConverter::Utf16 },
+ Codec{ "UTF-16-le", QStringConverter::Utf16LE },
+ Codec{ "UTF-16-be", QStringConverter::Utf16BE },
+ Codec{ "UTF-32", QStringConverter::Utf32 },
+ Codec{ "UTF-32-le", QStringConverter::Utf32LE },
+ Codec{ "UTF-32-be", QStringConverter::Utf32BE },
+ Codec{ "Latin-1", QStringConverter::Latin1, Latin1Only },
+ Codec{ "System", QStringConverter::System, localeIsUtf8() ? FullUnicode : AsciiOnly }
+};
+
+static const std::array encodedBoms = {
+ QByteArrayView("\xef\xbb\xbf"), // Utf8,
+ QByteArrayView(IsBigEndian ? "\xfe\xff" : "\xff\xfe"), // Utf16,
+ QByteArrayView("\xff\xfe"), // Utf16LE,
+ QByteArrayView("\xfe\xff"), // Utf16BE,
+ QByteArrayView(IsBigEndian ? "\0\0\xfe\xff" : "\xff\xfe\0", 4), // Utf32,
+ QByteArrayView("\xff\xfe\0", 4), // Utf32LE,
+ QByteArrayView("\0\0\xfe\xff", 4), // Utf32BE,
+};
+
+struct TestString
+{
+ const char *description;
+ QUtf8StringView utf8;
+ QStringView utf16;
+ CodecLimitation limitation = FullUnicode;
+};
+static const std::array testStrings = {
+ TestString{ "empty", "", u"", AsciiOnly },
+ TestString{ "null-character", QUtf8StringView("", 1), QStringView(u"", 1), AsciiOnly },
+ TestString{ "ascii-text",
+ "This is a standard US-ASCII message",
+ "This is a standard US-ASCII message" u"",
+ AsciiOnly
+ },
+ TestString{ "ascii-with-carriage-return", "a\rb", u"a\rb", AsciiOnly },
+ TestString{ "ascii-with-control",
+ "\1This\2is\3an\4US-ASCII\020 message interspersed with control chars",
+ "\1This\2is\3an\4US-ASCII\020 message interspersed with control chars" u"",
+ AsciiOnly
+ },
+
+ TestString{ "nbsp", "\u00a0", u"\u00a0", Latin1Only },
+ TestString{ "latin1-text",
+ "Hyvää päivää, käyhän että tuon kannettavani saunaan?",
+ "Hyvää päivää, käyhän että tuon kannettavani saunaan?" u"",
+ Latin1Only
+ },
+
+#define ROW(name, string) TestString{ name, u8"" string, u"" string }
+ ROW("euro", "€"),
+ ROW("character+bom", "b\ufeff"),
+ /* Check that the codec does NOT flag EFBFBF.
+ * This is a regression test; see QTBUG-33229
+ */
+ ROW("last-bmp", "\uffff"),
+ ROW("character+last-bmp", "b\uffff"),
+ ROW("replacement", "\ufffd"),
+ ROW("supplementary-plane", "\U00010203"),
+ ROW("mahjong", "\U0001f000\U0001f001\U0001f002\U0001f003\U0001f004\U0001f005"
+ "\U0001f006\U0001f007\U0001f008\U0001f009\U0001f00a\U0001f00b\U0001f00c"
+ "\U0001f00d\U0001f00e\U0001f00f"),
+ ROW("emojis", "😂, 😃, 🧘🏻‍♂️, 🌍, 🌦️, 🍞, 🚗, 📞, 🎉, ❤️, 🏁"), // https://en.wikipedia.org/wiki/Emoji
+ ROW("last-valid", "\U0010fffd"), // U+10FFFF is the strict last, but it's a non-character
+ ROW("mixed-bmp-only", "abc\u00a0\u00e1\u00e9\u01fd \u20acdef"),
+ ROW("mixed-full", "abc\u00a0\u00e1\u00e9\u01fd \U0010FFFD \u20acdef"),
+ ROW("xml", "<doc>\U00010000\U0010FFFD</doc>\r\n")
+#undef ROW
+};
+
+class tst_QStringConverter : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+
+ void threadSafety();
+
+ void constructByName();
+
+ void invalidConverter();
+
+ void convertUtf8_data();
+ void convertUtf8();
+ void convertUtf8CharByChar_data() { convertUtf8_data(); }
+ void convertUtf8CharByChar();
+ void roundtrip_data();
+ void roundtrip();
+
+ void convertL1U8();
+
+ void convertL1U16();
+
+#if QT_CONFIG(icu)
+ void roundtripIcu_data();
+ void roundtripIcu();
+ void icuInvalidCharacter_data();
+ void icuInvalidCharacter();
+ void icuEncodeEdgeCases_data();
+ void icuEncodeEdgeCases();
+ void icuUsableAfterMove();
+ void charByCharConsistency_data();
+ void charByCharConsistency();
+ void byteByByteConsistency_data();
+ void byteByByteConsistency();
+ void statefulPieceWise();
+#endif
+
+ void flagF7808080() const;
+
+ void utf8Codec_data();
+ void utf8Codec();
+
+ void utf8bom_data();
+ void utf8bom();
+ void roundtripBom_data();
+ void roundtripBom();
+
+ void utf8stateful_data();
+ void utf8stateful();
+
+ void utfHeaders_data();
+ void utfHeaders();
+
+ void encodingForName_data();
+ void encodingForName();
+
+ void nameForEncoding_data();
+ void nameForEncoding();
+
+ void encodingForData_data();
+ void encodingForData();
+
+ void encodingForHtml_data();
+ void encodingForHtml();
+
+ void availableCodesAreAvailable();
+
+#ifdef Q_OS_WIN
+ // On all other systems local 8-bit encoding is UTF-8
+ void fromLocal8Bit_data();
+ void fromLocal8Bit();
+ void fromLocal8Bit_special_cases();
+ void fromLocal8Bit_2GiB();
+ void toLocal8Bit_data();
+ void toLocal8Bit();
+ void toLocal8Bit_special_cases();
+ void toLocal8Bit_2GiB();
+#endif
+};
+
+void tst_QStringConverter::constructByName()
+{
+ QStringDecoder decoder("UTF-8");
+ QVERIFY(decoder.isValid());
+ QVERIFY(!strcmp(decoder.name(), "UTF-8"));
+ decoder = QStringDecoder("XXX");
+ QVERIFY(!decoder.isValid());
+ decoder = QStringDecoder("ISO-8859-1");
+ QVERIFY(decoder.isValid());
+ QVERIFY(!strcmp(decoder.name(), "ISO-8859-1"));
+ decoder = QStringDecoder("UTF-16LE");
+ QVERIFY(decoder.isValid());
+ QVERIFY(!strcmp(decoder.name(), "UTF-16LE"));
+
+ decoder = QStringDecoder("utf8");
+ QVERIFY(decoder.isValid());
+ QVERIFY(!strcmp(decoder.name(), "UTF-8"));
+ decoder = QStringDecoder("iso8859-1");
+ QVERIFY(decoder.isValid());
+ QVERIFY(!strcmp(decoder.name(), "ISO-8859-1"));
+ decoder = QStringDecoder("utf-16");
+ QVERIFY(decoder.isValid());
+ QVERIFY(!strcmp(decoder.name(), "UTF-16"));
+}
+
+void tst_QStringConverter::invalidConverter()
+{
+ // QStringEncoder tests
+ {
+ QStringEncoder encoder;
+ QVERIFY(!encoder.isValid());
+ QVERIFY(!encoder.name());
+ QByteArray encoded = encoder(u"Some text");
+ QVERIFY(encoded.isEmpty());
+ QVERIFY(encoder.hasError());
+
+ encoder.resetState();
+ QVERIFY(!encoder.hasError());
+
+ encoded = encoder.encode(u"More text");
+ QVERIFY(encoded.isEmpty());
+ QVERIFY(encoder.hasError());
+ QCOMPARE(encoder.requiredSpace(42), 0);
+
+ encoder.resetState();
+ QVERIFY(!encoder.hasError());
+ char buffer[100];
+ char *position = encoder.appendToBuffer(buffer, u"Even more");
+ QCOMPARE(position, buffer);
+ QVERIFY(encoder.hasError());
+ }
+
+ // QStringDecoder tests
+ {
+ QStringDecoder decoder;
+ QVERIFY(!decoder.name());
+ QVERIFY(!decoder.isValid());
+ QString decoded = decoder("Some text");
+ QVERIFY(decoded.isEmpty());
+ QVERIFY(decoder.hasError());
+
+ decoder.resetState();
+ QVERIFY(!decoder.hasError());
+
+ decoded = decoder.decode("More text");
+ QVERIFY(decoded.isEmpty());
+ QVERIFY(decoder.hasError());
+
+ QCOMPARE(decoder.requiredSpace(42), 0);
+
+ decoder.resetState();
+ QVERIFY(!decoder.hasError());
+ char16_t buffer[100];
+ char16_t *position = decoder.appendToBuffer(buffer, "Even more");
+ QCOMPARE(position, buffer);
+ QVERIFY(decoder.hasError());
+ }
+}
+
+void tst_QStringConverter::convertUtf8_data()
+{
+ QTest::addColumn<QStringConverter::Encoding>("encoding");
+ QTest::addColumn<QUtf8StringView>("utf8");
+ QTest::addColumn<QStringView>("utf16");
+ auto addRow = [](const TestString &s) {
+ QTest::addRow("Utf8:%s", s.description) << QStringDecoder::Utf8 << s.utf8 << s.utf16;
+ if (localeIsUtf8())
+ QTest::addRow("System:%s", s.description) << QStringDecoder::System << s.utf8 << s.utf16;
+ };
+
+ for (const TestString &s : testStrings)
+ addRow(s);
+}
+
+void tst_QStringConverter::convertUtf8()
+{
+ QFETCH(QStringConverter::Encoding, encoding);
+ QFETCH(QUtf8StringView, utf8);
+ QFETCH(QStringView, utf16);
+
+ QByteArray ba = QByteArray::fromRawData(utf8.data(), utf8.size());
+
+ QStringDecoder decoder(encoding);
+ QVERIFY(decoder.isValid());
+ QString uniString = decoder(ba);
+ QCOMPARE(uniString, utf16);
+ QCOMPARE(uniString, QString::fromUtf8(ba));
+ QCOMPARE(ba, uniString.toUtf8());
+
+ // do it again (using .decode())
+ uniString = decoder.decode(ba);
+ QCOMPARE(uniString, utf16);
+ QCOMPARE(uniString, QString::fromUtf8(ba));
+ QCOMPARE(ba, uniString.toUtf8());
+
+ QStringEncoder encoder(encoding);
+ QByteArray reencoded = encoder(utf16);
+ QCOMPARE(reencoded, utf8);
+ QCOMPARE(reencoded, uniString.toUtf8());
+
+ // do it again (using .encode())
+ reencoded = encoder.encode(utf16);
+ QCOMPARE(reencoded, utf8);
+ QCOMPARE(reencoded, uniString.toUtf8());
+
+ if (utf16.isEmpty())
+ return;
+
+ // repeat, with a longer string
+ constexpr qsizetype MinSize = 128;
+ uniString = utf16.toString();
+ while (uniString.size() < MinSize && ba.size() < MinSize) {
+ uniString += uniString;
+ ba += ba;
+ }
+ QCOMPARE(decoder(ba), uniString);
+ QCOMPARE(encoder(uniString), ba);
+}
+
+void tst_QStringConverter::convertUtf8CharByChar()
+{
+ QFETCH(QStringConverter::Encoding, encoding);
+ QFETCH(QUtf8StringView, utf8);
+ QFETCH(QStringView, utf16);
+
+ QByteArray ba = QByteArray::fromRawData(utf8.data(), utf8.size());
+
+ QStringDecoder decoder(encoding);
+ QVERIFY(decoder.isValid());
+ QString uniString;
+ for (int i = 0; i < ba.size(); ++i)
+ uniString += decoder(QByteArrayView(ba).sliced(i, 1));
+ QCOMPARE(uniString, utf16);
+ QCOMPARE(uniString, QString::fromUtf8(ba));
+ uniString.clear();
+
+ // do it again (using .decode())
+ for (int i = 0; i < ba.size(); ++i)
+ uniString += decoder.decode(QByteArrayView(ba).sliced(i, 1));
+ QCOMPARE(uniString, utf16);
+ QCOMPARE(uniString, QString::fromUtf8(ba));
+
+ QStringEncoder encoder(encoding);
+ QByteArray reencoded;
+ for (int i = 0; i < utf16.size(); ++i)
+ reencoded += encoder(utf16.sliced(i, 1));
+ QCOMPARE(reencoded, ba);
+ reencoded.clear();
+
+ // do it again (using .encode())
+ for (int i = 0; i < utf16.size(); ++i)
+ reencoded += encoder.encode(utf16.sliced(i, 1));
+ QCOMPARE(reencoded, ba);
+}
+
+void tst_QStringConverter::convertL1U16()
+{
+ const QLatin1StringView latin1("some plain latin1 text");
+ const QString qstr(latin1);
+
+ QStringDecoder decoder(QStringConverter::Latin1);
+ QVERIFY(decoder.isValid());
+ QString uniString = decoder(latin1);
+ QCOMPARE(uniString, qstr);
+ QCOMPARE(latin1, uniString.toLatin1());
+
+ // do it again (using .decode())
+ uniString = decoder.decode(latin1);
+ QCOMPARE(uniString, qstr);
+ QCOMPARE(latin1, uniString.toLatin1());
+
+ QStringEncoder encoder(QStringConverter::Latin1);
+ QByteArray reencoded = encoder(uniString);
+ QCOMPARE(reencoded, QByteArrayView(latin1));
+ QCOMPARE(reencoded, uniString.toLatin1());
+
+ // do it again (using .encode())
+ reencoded = encoder.encode(uniString);
+ QCOMPARE(reencoded, QByteArrayView(latin1));
+ QCOMPARE(reencoded, uniString.toLatin1());
+}
+
+void tst_QStringConverter::roundtrip_data()
+{
+ QTest::addColumn<QStringView>("utf16");
+ QTest::addColumn<QStringConverter::Encoding>("code");
+
+ for (const auto &code : codes) {
+ for (const TestString &s : testStrings) {
+ // rules:
+ // 1) don't pass the null character to the System codec
+ // 2) only pass operate on a string that will properly convert
+ if (code.code == QStringConverter::System && s.utf16.contains(QChar(0)))
+ continue;
+ if (code.limitation < s.limitation)
+ continue;
+ QTest::addRow("%s:%s", code.name, s.description) << s.utf16 << code.code;
+ }
+
+ if (code.limitation == FullUnicode) {
+ using Digits = std::array<QChar, 2>;
+ using DigitsArray = std::array<Digits, 10>;
+ static constexpr DigitsArray chakmaDigits = []() {
+ const char32_t zeroVal = 0x11136; // Unicode's representation of Chakma zero
+ DigitsArray r;
+ for (int i = 0; i < int(r.size()); ++i)
+ r[i] = { QChar::highSurrogate(zeroVal + i), QChar::lowSurrogate(zeroVal + i) };
+ return r;
+ }();
+ for (int i = 0; i < int(chakmaDigits.size()); ++i)
+ QTest::addRow("%s:Chakma-digit-%d", code.name, i) << QStringView(chakmaDigits[i]) << code.code;
+ }
+ }
+}
+
+void tst_QStringConverter::roundtrip()
+{
+ QFETCH(QStringView, utf16);
+ QFETCH(QStringConverter::Encoding, code);
+ QStringEncoder out(code);
+ QByteArray encoded = out.encode(utf16);
+ QStringDecoder back(code);
+ QString decoded = back.decode(encoded);
+ QCOMPARE(decoded, utf16);
+
+ // test some flags
+ QStringConverter::Flags flag = QStringEncoder::Flag::Stateless;
+ {
+ QStringEncoder out2(code, flag);
+ QStringDecoder back2(code, flag);
+ decoded = back2.decode(out2.encode(utf16));
+ QCOMPARE(decoded, utf16);
+ }
+ flag |= QStringConverter::Flag::ConvertInvalidToNull;
+ {
+ QStringEncoder out2(code, flag);
+ QStringDecoder back2(code, flag);
+ decoded = back2.decode(out2.encode(utf16));
+ QCOMPARE(decoded, utf16);
+ }
+
+ if (utf16.isEmpty())
+ return;
+
+ // repeat, with a longer string
+ constexpr qsizetype MinSize = 128;
+ QString uniString = utf16.toString();
+ while (uniString.size() < MinSize && encoded.size() < MinSize) {
+ uniString += uniString;
+ encoded += encoded;
+ }
+ QCOMPARE(out.encode(uniString), encoded);
+ QCOMPARE(back.decode(encoded), uniString);
+
+ QStringEncoder out2(code, flag);
+ QStringDecoder back2(code, flag);
+ decoded = back2.decode(out2.encode(uniString));
+ QCOMPARE(decoded, uniString);
+}
+
+void tst_QStringConverter::convertL1U8()
+{
+ {
+ std::array<char, 256> latin1;
+ std::iota(latin1.data(), latin1.data() + latin1.size(), uchar(0));
+ std::array<char, 512> utf8;
+ auto out = QUtf8::convertFromLatin1(utf8.data(), QLatin1StringView{latin1.data(), latin1.size()});
+ QCOMPARE(QString::fromLatin1(latin1.data(), latin1.size()),
+ QString::fromUtf8(utf8.data(), out - utf8.data()));
+ }
+}
+
+#if QT_CONFIG(icu)
+
+void tst_QStringConverter::roundtripIcu_data()
+{
+ QTest::addColumn<QString>("original");
+ QTest::addColumn<QByteArray>("codec");
+
+ QTest::addRow("shift_jis") << u"古池や 蛙飛び込む 水の音"_s << QByteArray("shift_jis");
+ QTest::addRow("UTF7") << u"Übermäßig: čçö"_s << QByteArray("UTF-7");
+}
+
+void tst_QStringConverter::roundtripIcu()
+{
+ QFETCH(QString, original);
+ QFETCH(QByteArray, codec);
+ QStringEncoder fromUtf16(codec);
+ if (!fromUtf16.isValid())
+ QSKIP("Unsupported codec");
+ QStringDecoder toUtf16(codec);
+ QByteArray asShiftJIS = fromUtf16(original);
+ QString roundTripped = toUtf16(asShiftJIS);
+ QCOMPARE(roundTripped, original);
+}
+
+void tst_QStringConverter::icuEncodeEdgeCases_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<QByteArray>("expected") ;
+ QTest::addColumn<QByteArray>("codec");
+
+ QTest::addRow("empty") << QString() << QByteArray() << QByteArray("ISO-2022-CN");
+ QTest::addRow("BOMonly") << QString(QChar(QChar::ByteOrderMark)) << QByteArray() << QByteArray("ISO-2022-CN");
+ QTest::addRow("1to6") << u"좋"_s << QByteArray::fromHex("1b2428434141") << QByteArray("ISO-2022-JP-2");
+ QTest::addRow("1to7") << u"漢"_s << QByteArray::fromHex("1b2429470e6947") << QByteArray("ISO-2022-CN");
+ QTest::addRow("1to8") << u"墎"_s << QByteArray::fromHex("1b242a481b4e4949") << QByteArray("ISO-2022-CN");
+ QTest::addRow("utf7") << u"Übergröße"_s << QByteArray("+ANw-bergr+APYA3w-e") << QByteArray("UTF-7");
+}
+
+void tst_QStringConverter::icuEncodeEdgeCases()
+{
+ QFETCH(QString, source);
+ QFETCH(QByteArray, expected);
+ QFETCH(QByteArray, codec);
+ QStringEncoder encoder(codec);
+ if (!encoder.isValid())
+ QSKIP("Unsupported codec");
+ QVERIFY(encoder.isValid());
+ QByteArray encoded = encoder.encode(source);
+ QCOMPARE(encoded, expected);
+}
+
+void tst_QStringConverter::charByCharConsistency_data()
+{
+ QTest::addColumn<QStringView>("source");
+ QTest::addColumn<QByteArray>("codec");
+
+ auto addRow = [](const TestString &s) {
+ QTest::addRow("%s_shift_jis", s.description) << s.utf16 << QByteArray("shift_jis");
+ QTest::addRow("%s_EUC-CN", s.description) << s.utf16 << QByteArray("EUC-CN");
+ };
+
+ for (const TestString &s : testStrings) {
+ if (s.utf16.isEmpty())
+ continue;
+ addRow(s);
+ }
+}
+
+void tst_QStringConverter::charByCharConsistency()
+{
+ QFETCH(const QStringView, source);
+ QFETCH(const QByteArray, codec);
+
+ const auto check = [&](QStringEncoder encoder){
+ if (!encoder.isValid())
+ QSKIP("Unsupported codec");
+
+ QByteArray fullyConverted = encoder.encode(source);
+ encoder.resetState();
+ QByteArray stepByStepConverted;
+ for (const auto& codeUnit: source) {
+ stepByStepConverted += encoder.encode(codeUnit);
+ }
+ QCOMPARE(stepByStepConverted, fullyConverted);
+ };
+
+ check(QStringEncoder(codec));
+ if (QTest::currentTestResolved()) return;
+
+ check(QStringEncoder(codec, QStringConverter::Flag::ConvertInvalidToNull));
+ if (QTest::currentTestResolved()) return;
+
+ // moved codecs also work:
+
+ {
+ QStringEncoder dec(codec);
+ check(std::move(dec));
+ }
+ if (QTest::currentTestResolved()) return;
+
+ {
+ QStringEncoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull);
+ check(std::move(dec));
+ }
+ if (QTest::currentTestResolved()) return;
+
+}
+
+void tst_QStringConverter::byteByByteConsistency_data()
+{
+ QTest::addColumn<QByteArray>("source");
+ QTest::addColumn<QByteArray>("codec");
+
+ QTest::addRow("plain_ascii_utf7") << QByteArray("Hello, world!") << QByteArray("UTF-7");
+ QFile eucKr(":/euc_kr.txt");
+ if (eucKr.open(QFile::ReadOnly))
+ QTest::addRow("euc_kr_storing_jp") << eucKr.readAll() << QByteArray("EUC-KR");
+ QTest::addRow("incomplete_euc_jp") << QByteArrayLiteral("test\x8Ftest") << QByteArray("EUC-JP");
+}
+
+void tst_QStringConverter::byteByByteConsistency()
+{
+ QFETCH(const QByteArray, source);
+ QFETCH(const QByteArray, codec);
+
+ const auto check = [&](QStringDecoder decoder) {
+ if (!decoder.isValid())
+ QSKIP("Unsupported codec");
+
+ QString fullyConverted = decoder.decode(source);
+ decoder.resetState();
+ QString stepByStepConverted;
+ for (const auto& byte: source) {
+ QByteArray singleChar;
+ singleChar.append(byte);
+ stepByStepConverted += decoder.decode(singleChar);
+ }
+ QCOMPARE(stepByStepConverted, fullyConverted);
+ };
+
+ check(QStringDecoder(codec));
+ if (QTest::currentTestResolved()) return;
+
+ check(QStringDecoder(codec, QStringConverter::Flag::ConvertInvalidToNull));
+ if (QTest::currentTestResolved()) return;
+
+ // moved codecs also work:
+
+ {
+ QStringDecoder dec(codec);
+ check(std::move(dec));
+ }
+ if (QTest::currentTestResolved()) return;
+
+ {
+ QStringDecoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull);
+ check(std::move(dec));
+ }
+ if (QTest::currentTestResolved()) return;
+
+}
+
+void tst_QStringConverter::statefulPieceWise()
+{
+ QStringDecoder decoder("HZ");
+ if (!decoder.isValid())
+ QSKIP("Unsupported codec");
+ QString start = decoder.decode("pure ASCII");
+ QCOMPARE(start, u"pure ASCII");
+ QString shifted = decoder.decode("~{");
+ // shift out changes the state, but won't create any output
+ QCOMPARE(shifted, "");
+ QString continuation = decoder.decode("\x42\x43");
+ QCOMPARE(continuation, "旅");
+ decoder.resetState();
+ // after resetting the state we're in N0 again
+ QString afterReset = decoder.decode("\x42\x43");
+ QCOMPARE(afterReset, "BC");
+}
+
+void tst_QStringConverter::icuUsableAfterMove()
+{
+ {
+ QStringDecoder decoder("EUC-JP");
+ QVERIFY(decoder.isValid());
+ QString partial = decoder.decode("Test\x8E");
+ QCOMPARE(partial, u"Test"_s);
+ QStringDecoder moved(std::move(decoder));
+ QString complete = partial + moved.decode("\xA1Test");
+ QCOMPARE(complete, u"Test\uFF61Test"_s);
+ }
+ {
+ QStringEncoder encoder("Big5");
+ QVERIFY(encoder.isValid());
+ QByteArray encoded = encoder.encode("hello"_L1);
+ QCOMPARE(encoded, "hello");
+ QStringEncoder moved(std::move(encoder));
+ encoded = moved.encode("bye");
+ QCOMPARE(encoded, "bye");
+ }
+}
+
+void tst_QStringConverter::icuInvalidCharacter_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QByteArray>("bytearray");
+ QTest::addColumn<QByteArray>("codec");
+ QTest::addColumn<QStringConverter::Flags>("flags");
+ QTest::addColumn<bool>("shouldDecode");
+
+ using Flags = QStringConverter::Flags;
+ using Flag = QStringConverter::Flag;
+ QTest::addRow("encode")
+ << u"Test👪Test"_s
+ << QByteArrayLiteral("\xE3\x85\xA2\xA3\x3F\xE3\x85\xA2\xA3")
+ << QByteArray("IBM-037") << Flags(Flag::Default)
+ << false;
+ QTest::addRow("encode_null")
+ << u"Test👪Test"_s
+ << QByteArrayLiteral("\xE3\x85\xA2\xA3\0\xE3\x85\xA2\xA3")
+ << QByteArray("IBM-037") << Flags(Flag::ConvertInvalidToNull)
+ << false;
+ QTest::addRow("decode_incomplete_EUC-JP")
+ << u"test"_s
+ << QByteArrayLiteral("test\x8F")
+ << QByteArray("EUC-JP") << Flags(Flag::Stateless)
+ << true;
+ QTest::addRow("decode_invalid_EUC-JP_sequence")
+ << u"test\0test"_s
+ << QByteArrayLiteral("test\x8Ftest")
+ << QByteArray("EUC-JP") << Flags(Flag::ConvertInvalidToNull)
+ << true;
+ QTest::addRow("encode_incomplete_surrogate")
+ << u"test"_s + QChar::highSurrogate(0x11136)
+ << QByteArray("test")
+ << QByteArray("EUC-JP") << Flags(Flag::Stateless)
+ << false;
+}
+
+void tst_QStringConverter::icuInvalidCharacter()
+{
+ QFETCH(QString, string);
+ QFETCH(QByteArray, bytearray);
+ QFETCH(QByteArray, codec);
+ QFETCH(QStringConverter::Flags, flags);
+ QFETCH(bool, shouldDecode);
+ if (shouldDecode) {
+ QStringDecoder decoder(codec.data(), flags);
+ QVERIFY(decoder.isValid());
+ QString decoded = decoder.decode(bytearray);
+ QVERIFY(decoder.hasError());
+ QCOMPARE(decoded, string);
+ } else {
+ QStringEncoder encoder(codec.data(), flags);
+ QVERIFY(encoder.isValid());
+ QByteArray encoded = encoder.encode(string);
+ QVERIFY(encoder.hasError());
+ QCOMPARE(encoded, bytearray);
+ }
+}
+
+#endif
+
+void tst_QStringConverter::flagF7808080() const
+{
+ /* This test case stems from test not-wf-sa-170, tests/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml,
+ * whose description reads:
+ *
+ * "Four byte UTF-8 encodings can encode UCS-4 characters
+ * which are beyond the range of legal XML characters
+ * (and can't be expressed in Unicode surrogate pairs).
+ * This document holds such a character."
+ *
+ * In binary, this is:
+ * 11110111100000001000000010000000
+ * * * * *
+ * 11110www10xxxxxx10yyyyyy10zzzzzz
+ *
+ * With multibyte logic removed it is the codepoint 0x1C0000.
+ */
+ QByteArray input;
+ input.resize(4);
+ input[0] = char(0xF7);
+ input[1] = char(0x80);
+ input[2] = char(0x80);
+ input[3] = char(0x80);
+
+ QStringDecoder decoder(QStringEncoder::Utf8, QStringDecoder::Flag::ConvertInvalidToNull);
+ QVERIFY(decoder.isValid());
+
+ QCOMPARE(decoder(input), QString(input.size(), QChar(0)));
+}
+
+static QString fromInvalidUtf8Sequence(const QByteArray &ba)
+{
+ return QString().fill(QChar::ReplacementCharacter, ba.size());
+}
+
+// copied from tst_QString::fromUtf8_data()
+void tst_QStringConverter::utf8Codec_data()
+{
+ QTest::addColumn<QByteArray>("utf8");
+ QTest::addColumn<QString>("res");
+ QTest::addColumn<int>("len");
+ QString str;
+
+ QTest::newRow("str0") << QByteArray("abcdefgh") << QString("abcdefgh") << -1;
+ QTest::newRow("str0-len") << QByteArray("abcdefgh") << QString("abc") << 3;
+ QTest::newRow("str1") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
+ << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") << -1;
+ QTest::newRow("str1-len") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
+ << QString::fromLatin1("\366\344\374\326\304") << 10;
+
+ str += QChar(0x05e9);
+ str += QChar(0x05d3);
+ str += QChar(0x05d2);
+ QTest::newRow("str2") << QByteArray("\327\251\327\223\327\222") << str << -1;
+
+ str = QChar(0x05e9);
+ QTest::newRow("str2-len") << QByteArray("\327\251\327\223\327\222") << str << 2;
+
+ str = QChar(0x20ac);
+ str += " some text";
+ QTest::newRow("str3") << QByteArray("\342\202\254 some text") << str << -1;
+
+ str = QChar(0x20ac);
+ str += " some ";
+ QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9;
+
+ str = "hello";
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x68);
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x61);
+ str += QChar::ReplacementCharacter;
+ QTest::newRow("invalid utf8") << QByteArray("hello\344h\344\344\366\344a\304") << str << -1;
+ QTest::newRow("invalid utf8-len") << QByteArray("hello\344h\344\344\366\344a\304") << QString("hello") << 5;
+
+ str = "Prohl";
+ str += QChar::ReplacementCharacter;
+ str += QChar::ReplacementCharacter;
+ str += QLatin1Char('e');
+ str += QChar::ReplacementCharacter;
+ str += " plugin";
+ str += QChar::ReplacementCharacter;
+ str += " Netscape";
+
+ QTest::newRow("task28417") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << str << -1;
+ QTest::newRow("task28417-len") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << QString("") << 0;
+
+ QTest::newRow("null-1") << QByteArray() << QString() << -1;
+ QTest::newRow("null0") << QByteArray() << QString() << 0;
+ // QTest::newRow("null5") << QByteArray() << QString() << 5;
+ QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << QString() << -1;
+ QTest::newRow("empty0") << QByteArray() << QString() << 0;
+ QTest::newRow("empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1("\0abcd", 5) << 5;
+ QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab") << -1;
+ QTest::newRow("other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab\0cd", 5) << 5;
+
+ str = "Old Italic: ";
+ str += QChar(0xd800);
+ str += QChar(0xdf00);
+ str += QChar(0xd800);
+ str += QChar(0xdf01);
+ str += QChar(0xd800);
+ str += QChar(0xdf02);
+ str += QChar(0xd800);
+ str += QChar(0xdf03);
+ str += QChar(0xd800);
+ str += QChar(0xdf04);
+ QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str << -1;
+
+ QTest::newRow("surrogate-len") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str.left(16) << 20;
+
+ // from http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html
+
+ // 2.1.1 U+00000000
+ QByteArray utf8;
+ utf8 += char(0x00);
+ str = QChar(QChar::Null);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.1") << utf8 << str << 1;
+
+ // 2.1.2 U+00000080
+ utf8.clear();
+ utf8 += char(0xc2);
+ utf8 += char(0x80);
+ str = QChar(0x80);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.2") << utf8 << str << -1;
+
+ // 2.1.3 U+00000800
+ utf8.clear();
+ utf8 += char(0xe0);
+ utf8 += char(0xa0);
+ utf8 += char(0x80);
+ str = QChar(0x800);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.3") << utf8 << str << -1;
+
+ // 2.1.4 U+00010000
+ utf8.clear();
+ utf8 += char(0xf0);
+ utf8 += char(0x90);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str.clear();
+ str += QChar(0xd800);
+ str += QChar(0xdc00);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.4") << utf8 << str << -1;
+
+ // 2.1.5 U+00200000 (not a valid Unicode character)
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x88);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.5") << utf8 << str << -1;
+
+ // 2.1.6 U+04000000 (not a valid Unicode character)
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x84);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.6") << utf8 << str << -1;
+
+ // 2.2.1 U+0000007F
+ utf8.clear();
+ utf8 += char(0x7f);
+ str = QChar(0x7f);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.1") << utf8 << str << -1;
+
+ // 2.2.2 U+000007FF
+ utf8.clear();
+ utf8 += char(0xdf);
+ utf8 += char(0xbf);
+ str = QChar(0x7ff);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.2") << utf8 << str << -1;
+
+ // 2.2.3 U+000FFFF - non-character code
+ utf8.clear();
+ utf8 += char(0xef);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = QString::fromUtf8(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.3") << utf8 << str << -1;
+
+ // 2.2.4 U+001FFFFF
+ utf8.clear();
+ utf8 += char(0xf7);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.4") << utf8 << str << -1;
+
+ // 2.2.5 U+03FFFFFF (not a valid Unicode character)
+ utf8.clear();
+ utf8 += char(0xfb);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.5") << utf8 << str << -1;
+
+ // 2.2.6 U+7FFFFFFF
+ utf8.clear();
+ utf8 += char(0xfd);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.6") << utf8 << str << -1;
+
+ // 2.3.1 U+0000D7FF
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0x9f);
+ utf8 += char(0xbf);
+ str = QChar(0xd7ff);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.1") << utf8 << str << -1;
+
+ // 2.3.2 U+0000E000
+ utf8.clear();
+ utf8 += char(0xee);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = QChar(0xe000);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.2") << utf8 << str << -1;
+
+ // 2.3.3 U+0000FFFD
+ utf8.clear();
+ utf8 += char(0xef);
+ utf8 += char(0xbf);
+ utf8 += char(0xbd);
+ str = QChar(QChar::ReplacementCharacter);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.3") << utf8 << str << -1;
+
+ // 2.3.4 U+0010FFFD
+ utf8.clear();
+ utf8 += char(0xf4);
+ utf8 += char(0x8f);
+ utf8 += char(0xbf);
+ utf8 += char(0xbd);
+ str.clear();
+ str += QChar(0xdbff);
+ str += QChar(0xdffd);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.4") << utf8 << str << -1;
+
+ // 2.3.5 U+00110000
+ utf8.clear();
+ utf8 += char(0xf4);
+ utf8 += char(0x90);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.5") << utf8 << str << -1;
+
+ // 3.1.1
+ utf8.clear();
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.1") << utf8 << str << -1;
+
+ // 3.1.2
+ utf8.clear();
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.2") << utf8 << str << -1;
+
+ // 3.1.3
+ utf8.clear();
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.3") << utf8 << str << -1;
+
+ // 3.1.4
+ utf8.clear();
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.4") << utf8 << str << -1;
+
+ // 3.1.5
+ utf8.clear();
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.5") << utf8 << str << -1;
+
+ // 3.1.6
+ utf8.clear();
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.6") << utf8 << str << -1;
+
+ // 3.1.7
+ utf8.clear();
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.7") << utf8 << str << -1;
+
+ // 3.1.8
+ utf8.clear();
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ utf8 += char(0xbf);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.8") << utf8 << str << -1;
+
+ // 3.1.9
+ utf8.clear();
+ for (uint i = 0x80; i<= 0xbf; ++i)
+ utf8 += i;
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.9") << utf8 << str << -1;
+
+ // 3.2.1
+ utf8.clear();
+ str.clear();
+ for (uint i = 0xc8; i <= 0xdf; ++i) {
+ utf8 += i;
+ utf8 += char(0x20);
+
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x0020);
+ }
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.1") << utf8 << str << -1;
+
+ // 3.2.2
+ utf8.clear();
+ str.clear();
+ for (uint i = 0xe0; i <= 0xef; ++i) {
+ utf8 += i;
+ utf8 += char(0x20);
+
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x0020);
+ }
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.2") << utf8 << str << -1;
+
+ // 3.2.3
+ utf8.clear();
+ str.clear();
+ for (uint i = 0xf0; i <= 0xf7; ++i) {
+ utf8 += i;
+ utf8 += 0x20;
+
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x0020);
+ }
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.3") << utf8 << str << -1;
+
+ // 3.2.4
+ utf8.clear();
+ str.clear();
+ for (uint i = 0xf8; i <= 0xfb; ++i) {
+ utf8 += i;
+ utf8 += 0x20;
+
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x0020);
+ }
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.4") << utf8 << str << -1;
+
+ // 3.2.5
+ utf8.clear();
+ str.clear();
+ for (uint i = 0xfc; i <= 0xfd; ++i) {
+ utf8 += i;
+ utf8 += 0x20;
+
+ str += QChar::ReplacementCharacter;
+ str += QChar(0x0020);
+ }
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.5") << utf8 << str << -1;
+
+ // 3.3.1
+ utf8.clear();
+ utf8 += char(0xc0);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.1") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.1-1") << utf8 << str << -1;
+
+ // 3.3.2
+ utf8.clear();
+ utf8 += char(0xe0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xe0);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-2") << utf8 << str << -1;
+ utf8 += 0x30;
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-3") << utf8 << str << -1;
+
+ // 3.3.3
+ utf8.clear();
+ utf8 += char(0xf0);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf0);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-3") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-5") << utf8 << str << -1;
+
+ // 3.3.4
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-3") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-5") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf8);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-6") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-7") << utf8 << str << -1;
+
+ // 3.3.5
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-3") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-5") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-6") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-7") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfc);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-8") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-9") << utf8 << str << -1;
+
+ // 3.3.6
+ utf8.clear();
+ utf8 += char(0xdf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.6") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.6-1") << utf8 << str << -1;
+
+ // 3.3.7
+ utf8.clear();
+ utf8 += char(0xef);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xef);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-3") << utf8 << str << -1;
+
+ // 3.3.8
+ utf8.clear();
+ utf8 += char(0xf7);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf7);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-3") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xf7);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-5") << utf8 << str << -1;
+
+ // 3.3.9
+ utf8.clear();
+ utf8 += char(0xfb);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfb);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-3") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfb);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-5") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfb);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-6") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-7") << utf8 << str << -1;
+
+ // 3.3.10
+ utf8.clear();
+ utf8 += char(0xfd);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-1") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfd);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-2") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-3") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfd);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-4") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-5") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfd);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-6") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-7") << utf8 << str << -1;
+
+ utf8.clear();
+ utf8 += char(0xfd);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-8") << utf8 << str << -1;
+ utf8 += char(0x30);
+ str += QChar(0x30);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-9") << utf8 << str << -1;
+
+ // 3.4
+ utf8.clear();
+ utf8 += char(0xc0);
+ utf8 += char(0xe0);
+ utf8 += char(0x80);
+ utf8 += char(0xf0);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0xf8);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0xdf);
+ utf8 += char(0xef);
+ utf8 += char(0xbf);
+ utf8 += char(0xf7);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xfb);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xfd);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.4") << utf8 << str << -1;
+
+ // 3.5.1
+ utf8.clear();
+ utf8 += char(0xfe);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.1") << utf8 << str << -1;
+
+ // 3.5.2
+ utf8.clear();
+ utf8 += char(0xff);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2") << utf8 << str << -1;
+
+ // 3.5.2
+ utf8.clear();
+ utf8 += char(0xfe);
+ utf8 += char(0xfe);
+ utf8 += char(0xff);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2-1") << utf8 << str << -1;
+
+ // 4.1.1
+ utf8.clear();
+ utf8 += char(0xc0);
+ utf8 += char(0xaf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.1") << utf8 << str << -1;
+
+ // 4.1.2
+ utf8.clear();
+ utf8 += char(0xe0);
+ utf8 += char(0x80);
+ utf8 += char(0xaf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.2") << utf8 << str << -1;
+
+ // 4.1.3
+ utf8.clear();
+ utf8 += char(0xf0);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0xaf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.3") << utf8 << str << -1;
+
+ // 4.1.4
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0xaf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.4") << utf8 << str << -1;
+
+ // 4.1.5
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0xaf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.5") << utf8 << str << -1;
+
+ // 4.2.1
+ utf8.clear();
+ utf8 += char(0xc1);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.1") << utf8 << str << -1;
+
+ // 4.2.2
+ utf8.clear();
+ utf8 += char(0xe0);
+ utf8 += char(0x9f);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.2") << utf8 << str << -1;
+
+ // 4.2.3
+ utf8.clear();
+ utf8 += char(0xf0);
+ utf8 += char(0x8f);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.3") << utf8 << str << -1;
+
+ // 4.2.4
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x87);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.4") << utf8 << str << -1;
+
+ // 4.2.5
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x83);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.5") << utf8 << str << -1;
+
+ // 4.3.1
+ utf8.clear();
+ utf8 += char(0xc0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.1") << utf8 << str << -1;
+
+ // 4.3.2
+ utf8.clear();
+ utf8 += char(0xe0);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.2") << utf8 << str << -1;
+
+ // 4.3.3
+ utf8.clear();
+ utf8 += char(0xf0);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.3") << utf8 << str << -1;
+
+ // 4.3.4
+ utf8.clear();
+ utf8 += char(0xf8);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.4") << utf8 << str << -1;
+
+ // 4.3.5
+ utf8.clear();
+ utf8 += char(0xfc);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.5") << utf8 << str << -1;
+
+ // 5.1.1
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xa0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.1") << utf8 << str << -1;
+
+ // 5.1.2
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xad);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.2") << utf8 << str << -1;
+
+ // 5.1.3
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xae);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.3") << utf8 << str << -1;
+
+ // 5.1.4
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xaf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.4") << utf8 << str << -1;
+
+ // 5.1.5
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xb0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.5") << utf8 << str << -1;
+
+ // 5.1.6
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xbe);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.6") << utf8 << str << -1;
+
+ // 5.1.7
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.7") << utf8 << str << -1;
+
+ // 5.2.1
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xa0);
+ utf8 += char(0x80);
+ utf8 += char(0xed);
+ utf8 += char(0xb0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.1") << utf8 << str << -1;
+
+ // 5.2.2
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xa0);
+ utf8 += char(0x80);
+ utf8 += char(0xed);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.2") << utf8 << str << -1;
+
+ // 5.2.3
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xad);
+ utf8 += char(0xbf);
+ utf8 += char(0xed);
+ utf8 += char(0xb0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.3") << utf8 << str << -1;
+
+ // 5.2.4
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xad);
+ utf8 += char(0xbf);
+ utf8 += char(0xed);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.4") << utf8 << str << -1;
+
+ // 5.2.5
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xae);
+ utf8 += char(0x80);
+ utf8 += char(0xed);
+ utf8 += char(0xb0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.5") << utf8 << str << -1;
+
+ // 5.2.6
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xae);
+ utf8 += char(0x80);
+ utf8 += char(0xed);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.6") << utf8 << str << -1;
+
+ // 5.2.7
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xaf);
+ utf8 += char(0xbf);
+ utf8 += char(0xed);
+ utf8 += char(0xb0);
+ utf8 += char(0x80);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.7") << utf8 << str << -1;
+
+ // 5.2.8
+ utf8.clear();
+ utf8 += char(0xed);
+ utf8 += char(0xaf);
+ utf8 += char(0xbf);
+ utf8 += char(0xed);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ str = fromInvalidUtf8Sequence(utf8);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.8") << utf8 << str << -1;
+
+ // 5.3.1 - non-character code
+ utf8.clear();
+ utf8 += char(0xef);
+ utf8 += char(0xbf);
+ utf8 += char(0xbe);
+ //str = QChar(QChar::ReplacementCharacter);
+ str = QChar(0xfffe);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.1") << utf8 << str << -1;
+
+ // 5.3.2 - non-character code
+ utf8.clear();
+ utf8 += char(0xef);
+ utf8 += char(0xbf);
+ utf8 += char(0xbf);
+ //str = QChar(QChar::ReplacementCharacter);
+ str = QChar(0xffff);
+ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.2") << utf8 << str << -1;
+}
+
+void tst_QStringConverter::utf8Codec()
+{
+ QFETCH(QByteArray, utf8);
+ QFETCH(QString, res);
+ QFETCH(int, len);
+
+ QStringDecoder decoder(QStringDecoder::Utf8, QStringDecoder::Flag::Stateless);
+ QString str = decoder(QByteArrayView(utf8).first(len < 0 ? qstrlen(utf8.constData()) : len));
+ QCOMPARE(str, res);
+
+ str = QString::fromUtf8(utf8.isNull() ? 0 : utf8.constData(), len);
+ QCOMPARE(str, res);
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QStringConverter::utf8bom_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("nobom")
+ << QByteArray("\302\240", 2)
+ << QString::fromLatin1("\240");
+
+ {
+ static const char16_t data[] = { 0x201d };
+ QTest::newRow("nobom 2")
+ << QByteArray("\342\200\235", 3)
+ << QString::fromUtf16(data, std::size(data));
+ }
+
+ {
+ static const char16_t data[] = { 0xf000 };
+ QTest::newRow("bom1")
+ << QByteArray("\357\200\200", 3)
+ << QString::fromUtf16(data, std::size(data));
+ }
+
+ {
+ static const char16_t data[] = { 0xfec0 };
+ QTest::newRow("bom2")
+ << QByteArray("\357\273\200", 3)
+ << QString::fromUtf16(data, std::size(data));
+ }
+
+ {
+ QTest::newRow("normal-bom")
+ << QByteArray("\357\273\277a", 4)
+ << QString("a");
+ }
+
+ { // test the non-SIMD code-path
+ static const char16_t data[] = { 0x61, 0xfeff, 0x62 };
+ QTest::newRow("middle-bom (non SIMD)")
+ << QByteArray("a\357\273\277b")
+ << QString::fromUtf16(data, std::size(data));
+ }
+
+ { // test the SIMD code-path
+ static const char16_t data[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0xfeff, 0x6d };
+ QTest::newRow("middle-bom (SIMD)")
+ << QByteArray("abcdefghijkl\357\273\277m")
+ << QString::fromUtf16(data, std::size(data));
+ }
+}
+QT_WARNING_POP
+
+void tst_QStringConverter::utf8bom()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, result);
+
+ QStringDecoder decoder(QStringDecoder::Utf8);
+
+ QCOMPARE(decoder(data), result);
+}
+
+// someone set us up the BOM!
+void tst_QStringConverter::roundtripBom_data()
+{
+ QTest::addColumn<QStringView>("utf16");
+ QTest::addColumn<QStringConverter::Encoding>("code");
+
+ for (const auto &code : codes) {
+ if (size_t(code.code) >= encodedBoms.size())
+ break;
+ if (code.limitation != FullUnicode)
+ continue; // can't represent BOM
+
+ for (const TestString &s : testStrings) {
+ if (s.utf16.isEmpty())
+ continue;
+ QTest::addRow("%s:%s", code.name, s.description) << s.utf16 << code.code;
+ }
+ }
+}
+
+void tst_QStringConverter::roundtripBom()
+{
+ QFETCH(QStringView, utf16);
+ QFETCH(QStringConverter::Encoding, code);
+ QByteArray encodedBom = encodedBoms[code].toByteArray();
+ QChar bom = QChar::ByteOrderMark;
+
+ // QStringConverter defaults to producing no BOM, but interpreting it if it
+ // is there
+
+ QStringEncoder encoderWithoutBom(code);
+ QStringEncoder encoderWithBom(code, QStringEncoder::Flag::WriteBom);
+ QByteArray encodedWithoutBom = encoderWithoutBom(utf16);
+ QByteArray encodedWithBom = encoderWithBom(utf16);
+ QCOMPARE(encodedWithBom, encodedBom + encodedWithoutBom);
+
+ QStringDecoder decoderWithoutBom(code, QStringDecoder::Flag::ConvertInitialBom);
+ QStringDecoder decoderWithBom(code);
+ QString decoded = decoderWithBom(encodedWithBom);
+ QCOMPARE(decoded, utf16);
+
+ decoded = decoderWithoutBom(encodedWithBom);
+ QCOMPARE(decoded, bom + utf16.toString());
+}
+
+void tst_QStringConverter::utf8stateful_data()
+{
+ QTest::addColumn<QByteArray>("buffer1");
+ QTest::addColumn<QByteArray>("buffer2");
+ QTest::addColumn<QString>("result"); // null QString indicates decoder error
+
+ // valid buffer continuations
+ QTest::newRow("1of2+valid") << QByteArray("\xc2") << QByteArray("\xa0") << "\xc2\xa0";
+ QTest::newRow("1of3+valid") << QByteArray("\xe0") << QByteArray("\xa0\x80") << "\xe0\xa0\x80";
+ QTest::newRow("2of3+valid") << QByteArray("\xe0\xa0") << QByteArray("\x80") << "\xe0\xa0\x80";
+ QTest::newRow("1of4+valid") << QByteArray("\360") << QByteArray("\220\210\203") << "\360\220\210\203";
+ QTest::newRow("2of4+valid") << QByteArray("\360\220") << QByteArray("\210\203") << "\360\220\210\203";
+ QTest::newRow("3of4+valid") << QByteArray("\360\220\210") << QByteArray("\203") << "\360\220\210\203";
+ QTest::newRow("1ofBom+valid") << QByteArray("\xef") << QByteArray("\xbb\xbf") << "";
+ QTest::newRow("2ofBom+valid") << QByteArray("\xef\xbb") << QByteArray("\xbf") << "";
+
+ // invalid continuation
+ QTest::newRow("1of2+invalid") << QByteArray("\xc2") << QByteArray("a") << QString();
+ QTest::newRow("1of3+invalid") << QByteArray("\xe0") << QByteArray("a") << QString();
+ QTest::newRow("2of3+invalid") << QByteArray("\xe0\xa0") << QByteArray("a") << QString();
+ QTest::newRow("1of4+invalid") << QByteArray("\360") << QByteArray("a") << QString();
+ QTest::newRow("2of4+invalid") << QByteArray("\360\220") << QByteArray("a") << QString();
+ QTest::newRow("3of4+invalid") << QByteArray("\360\220\210") << QByteArray("a") << QString();
+
+ // overlong sequence:
+ QTest::newRow("overlong-1of2") << QByteArray("\xc1") << QByteArray("\x81") << QString();
+ QTest::newRow("overlong-1of3") << QByteArray("\xe0") << QByteArray("\x81\x81") << QString();
+ QTest::newRow("overlong-2of3") << QByteArray("\xe0\x81") << QByteArray("\x81") << QString();
+ QTest::newRow("overlong-1of4") << QByteArray("\xf0") << QByteArray("\x80\x81\x81") << QString();
+ QTest::newRow("overlong-2of4") << QByteArray("\xf0\x80") << QByteArray("\x81\x81") << QString();
+ QTest::newRow("overlong-3of4") << QByteArray("\xf0\x80\x81") << QByteArray("\x81") << QString();
+
+ // out of range:
+ // leading byte 0xF4 can produce codepoints above U+10FFFF, which aren't valid
+ QTest::newRow("outofrange1-1of4") << QByteArray("\xf4") << QByteArray("\x90\x80\x80") << QString();
+ QTest::newRow("outofrange1-2of4") << QByteArray("\xf4\x90") << QByteArray("\x80\x80") << QString();
+ QTest::newRow("outofrange1-3of4") << QByteArray("\xf4\x90\x80") << QByteArray("\x80") << QString();
+ QTest::newRow("outofrange2-1of4") << QByteArray("\xf5") << QByteArray("\x90\x80\x80") << QString();
+ QTest::newRow("outofrange2-2of4") << QByteArray("\xf5\x90") << QByteArray("\x80\x80") << QString();
+ QTest::newRow("outofrange2-3of4") << QByteArray("\xf5\x90\x80") << QByteArray("\x80") << QString();
+ QTest::newRow("outofrange-1of5") << QByteArray("\xf8") << QByteArray("\x88\x80\x80\x80") << QString();
+ QTest::newRow("outofrange-2of5") << QByteArray("\xf8\x88") << QByteArray("\x80\x80\x80") << QString();
+ QTest::newRow("outofrange-3of5") << QByteArray("\xf8\x88\x80") << QByteArray("\x80\x80") << QString();
+ QTest::newRow("outofrange-4of5") << QByteArray("\xf8\x88\x80\x80") << QByteArray("\x80") << QString();
+ QTest::newRow("outofrange-1of6") << QByteArray("\xfc") << QByteArray("\x84\x80\x80\x80\x80") << QString();
+ QTest::newRow("outofrange-2of6") << QByteArray("\xfc\x84") << QByteArray("\x80\x80\x80\x80") << QString();
+ QTest::newRow("outofrange-3of6") << QByteArray("\xfc\x84\x80") << QByteArray("\x80\x80\x80") << QString();
+ QTest::newRow("outofrange-4of6") << QByteArray("\xfc\x84\x80\x80") << QByteArray("\x80\x80") << QString();
+ QTest::newRow("outofrange-5of6") << QByteArray("\xfc\x84\x80\x80\x80") << QByteArray("\x80") << QString();
+}
+
+void tst_QStringConverter::utf8stateful()
+{
+ QFETCH(QByteArray, buffer1);
+ QFETCH(QByteArray, buffer2);
+ QFETCH(QString, result);
+
+ {
+ QStringDecoder decoder(QStringDecoder::Utf8);
+ QVERIFY(decoder.isValid());
+
+ QString decoded = decoder(buffer1);
+ if (result.isNull()) {
+ if (!decoder.hasError()) {
+ // incomplete data
+ decoded += decoder(buffer2);
+ QVERIFY(decoder.hasError());
+ }
+ } else {
+ QVERIFY(!decoder.hasError());
+ decoded += decoder(buffer2);
+ QVERIFY(!decoder.hasError());
+ QCOMPARE(decoded, result);
+ }
+ }
+
+ if (!buffer2.isEmpty()) {
+ QStringDecoder decoder(QStringDecoder::Utf8);
+ QVERIFY(decoder.isValid());
+
+ QString decoded;
+ for (char c : buffer1)
+ decoded += decoder(QByteArrayView(&c, 1));
+ for (char c : buffer2)
+ decoded += decoder(QByteArrayView(&c, 1));
+ if (result.isNull()) {
+ QVERIFY(decoder.hasError());
+ } else {
+ QVERIFY(!decoder.hasError());
+ QCOMPARE(decoded, result);
+ }
+ }
+}
+
+void tst_QStringConverter::utfHeaders_data()
+{
+ QTest::addColumn<QStringConverter::Encoding>("encoding");
+ QTest::addColumn<QStringConverter::Flag>("flags");
+ QTest::addColumn<QByteArray>("encoded");
+ QTest::addColumn<QString>("unicode");
+
+ QTest::newRow("utf8 bom")
+ << QStringConverter::Utf8
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xef\xbb\xbfhello")
+ << QString::fromLatin1("hello");
+ QTest::newRow("utf8 nobom")
+ << QStringConverter::Utf8
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("hello")
+ << QString::fromLatin1("hello");
+ QTest::newRow("utf8 bom ignore header")
+ << QStringConverter::Utf8
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xef\xbb\xbfhello")
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hello"));
+ QTest::newRow("utf8 nobom ignore header")
+ << QStringConverter::Utf8
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("hello")
+ << QString::fromLatin1("hello");
+
+ QTest::newRow("utf16 bom be")
+ << QStringConverter::Utf16
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xfe\xff\0h\0e\0l", 8)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16 bom le")
+ << QStringConverter::Utf16
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xff\xfeh\0e\0l\0", 8)
+ << QString::fromLatin1("hel");
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ QTest::newRow("utf16 nobom")
+ << QStringConverter::Utf16
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\0h\0e\0l", 6)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16 bom be ignore header")
+ << QStringConverter::Utf16
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xfe\xff\0h\0e\0l", 8)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+ } else {
+ QTest::newRow("utf16 nobom")
+ << QStringConverter::Utf16
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("h\0e\0l\0", 6)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16 bom le ignore header")
+ << QStringConverter::Utf16
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xff\xfeh\0e\0l\0", 8)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+ }
+
+ QTest::newRow("utf16-be bom be")
+ << QStringConverter::Utf16BE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xfe\xff\0h\0e\0l", 8)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16-be nobom")
+ << QStringConverter::Utf16BE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\0h\0e\0l", 6)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16-be bom be ignore header")
+ << QStringConverter::Utf16BE
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xfe\xff\0h\0e\0l", 8)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+
+ QTest::newRow("utf16-le bom le")
+ << QStringConverter::Utf16LE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xff\xfeh\0e\0l\0", 8)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16-le nobom")
+ << QStringConverter::Utf16LE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("h\0e\0l\0", 6)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf16-le bom le ignore header")
+ << QStringConverter::Utf16LE
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xff\xfeh\0e\0l\0", 8)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+
+ QTest::newRow("utf32 bom be")
+ << QStringConverter::Utf32
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32 bom le")
+ << QStringConverter::Utf32
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
+ << QString::fromLatin1("hel");
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ QTest::newRow("utf32 nobom")
+ << QStringConverter::Utf32
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32 bom be ignore header")
+ << QStringConverter::Utf32
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+ } else {
+ QTest::newRow("utf32 nobom")
+ << QStringConverter::Utf32
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("h\0\0\0e\0\0\0l\0\0\0", 12)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32 bom le ignore header")
+ << QStringConverter::Utf32
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+ }
+
+ QTest::newRow("utf32-be bom be")
+ << QStringConverter::Utf32BE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32-be nobom")
+ << QStringConverter::Utf32BE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32-be bom be ignore header")
+ << QStringConverter::Utf32BE
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+
+ QTest::newRow("utf32-le bom le")
+ << QStringConverter::Utf32LE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32-le nobom")
+ << QStringConverter::Utf32LE
+ << QStringConverter::Flag::WriteBom
+ << QByteArray("h\0\0\0e\0\0\0l\0\0\0", 12)
+ << QString::fromLatin1("hel");
+ QTest::newRow("utf32-le bom le ignore header")
+ << QStringConverter::Utf32LE
+ << QStringConverter::Flag::ConvertInitialBom
+ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
+ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"));
+}
+
+void tst_QStringConverter::utfHeaders()
+{
+ QFETCH(QStringConverter::Encoding, encoding);
+ QFETCH(QStringConverter::Flag, flags);
+ QFETCH(QByteArray, encoded);
+ QFETCH(QString, unicode);
+
+ QLatin1String ignoreReverseTestOn = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? QLatin1String(" le") : QLatin1String(" be");
+ QString rowName(QTest::currentDataTag());
+
+ {
+ QStringDecoder decode(encoding, flags);
+ QVERIFY(decode.isValid());
+
+ QString result = decode(encoded);
+ QCOMPARE(result.size(), unicode.size());
+ QCOMPARE(result, unicode);
+ }
+
+ {
+ QStringDecoder decode(encoding, flags);
+ QVERIFY(decode.isValid());
+
+ QString result;
+ for (char c : encoded)
+ result += decode(QByteArrayView(&c, 1));
+ QCOMPARE(result.size(), unicode.size());
+ QCOMPARE(result, unicode);
+ }
+
+ if (!rowName.endsWith("nobom") && !rowName.contains(ignoreReverseTestOn)) {
+ {
+ QStringEncoder encode(encoding, flags);
+ QVERIFY(encode.isValid());
+ QByteArray reencoded = encode(unicode);
+ QCOMPARE(reencoded, encoded);
+ }
+
+ {
+ QStringEncoder encode(encoding, flags);
+ QVERIFY(encode.isValid());
+ QByteArray reencoded;
+ for (QChar c : unicode)
+ reencoded += encode(QStringView(&c, 1));
+ QCOMPARE(reencoded, encoded);
+ }
+ }
+}
+
+void tst_QStringConverter::encodingForName_data()
+{
+ QTest::addColumn<QByteArray>("name");
+ QTest::addColumn<std::optional<QStringConverter::Encoding>>("encoding");
+
+ auto row = [](const char *name, std::optional<QStringConverter::Encoding> expected = std::nullopt) {
+ auto protect = [](auto p) { return p ? *p ? p : "<empty>" : "<nullptr>"; };
+ QTest::addRow("%s", protect(name)) << QByteArray(name) << expected;
+ };
+
+ row("UTF-8", QStringConverter::Utf8);
+ row("utf8", QStringConverter::Utf8);
+ row("Utf-8", QStringConverter::Utf8);
+ row("UTF-16", QStringConverter::Utf16);
+ row("UTF-16le", QStringConverter::Utf16LE);
+ row("ISO-8859-1", QStringConverter::Latin1);
+ row("ISO8859-1", QStringConverter::Latin1);
+ row("iso8859-1", QStringConverter::Latin1);
+ row("latin1", QStringConverter::Latin1);
+ row("latin-1_-", QStringConverter::Latin1);
+ row("latin_1-_", QStringConverter::Latin1);
+ row("-_latin-1", QStringConverter::Latin1);
+ row("_-latin_1", QStringConverter::Latin1);
+
+ // failures:
+ row(nullptr);
+ row("");
+ row("latin2");
+ row("latin42");
+ row(" latin1"); // spaces are significant
+ row("\tlatin1"); // HTs are significant
+}
+
+void tst_QStringConverter::encodingForName()
+{
+ QFETCH(const QByteArray, name);
+ QFETCH(const std::optional<QStringConverter::Encoding>, encoding);
+
+ const auto *ptr = name.isNull() ? nullptr : name.data();
+
+ const auto e = QStringConverter::encodingForName(ptr);
+ QCOMPARE(e, encoding);
+}
+
+void tst_QStringConverter::nameForEncoding_data()
+{
+ QTest::addColumn<QByteArray>("name");
+ QTest::addColumn<QStringConverter::Encoding>("encoding");
+
+ QTest::newRow("UTF-8") << QByteArray("UTF-8") << QStringConverter::Utf8;
+ QTest::newRow("UTF-16") << QByteArray("UTF-16") << QStringConverter::Utf16;
+ QTest::newRow("UTF-16LE") << QByteArray("UTF-16LE") << QStringConverter::Utf16LE;
+ QTest::newRow("ISO-8859-1") << QByteArray("ISO-8859-1") << QStringConverter::Latin1;
+}
+
+void tst_QStringConverter::nameForEncoding()
+{
+ QFETCH(QByteArray, name);
+ QFETCH(QStringConverter::Encoding, encoding);
+
+ QByteArray n = QStringConverter::nameForEncoding(encoding);
+ QCOMPARE(n, name);
+}
+
+void tst_QStringConverter::encodingForData_data()
+{
+ QTest::addColumn<QByteArray>("encoded");
+ QTest::addColumn<std::optional<QStringConverter::Encoding>>("encoding");
+
+
+ QTest::newRow("utf8 bom")
+ << QByteArray("\xef\xbb\xbfhello")
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8);
+ QTest::newRow("utf8 nobom")
+ << QByteArray("hello")
+ << std::optional<QStringConverter::Encoding>();
+
+ QTest::newRow("utf16 bom be")
+ << QByteArray("\xfe\xff\0h\0e\0l", 8)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf16BE);
+ QTest::newRow("utf16 bom le")
+ << QByteArray("\xff\xfeh\0e\0l\0", 8)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf16LE);
+ QTest::newRow("utf16 nobom be")
+ << QByteArray("\0<\0e\0l", 6)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf16BE);
+ QTest::newRow("utf16 nobom le")
+ << QByteArray("<\0e\0l\0", 6)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf16LE);
+ QTest::newRow("utf16 nobom no match")
+ << QByteArray("h\0e\0l\0", 6)
+ << std::optional<QStringConverter::Encoding>();
+
+ QTest::newRow("utf32 bom be")
+ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf32BE);
+ QTest::newRow("utf32 bom le")
+ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf32LE);
+ QTest::newRow("utf32 nobom be")
+ << QByteArray("\0\0\0<\0\0\0e\0\0\0l", 12)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf32BE);
+ QTest::newRow("utf32 nobom")
+ << QByteArray("<\0\0\0e\0\0\0l\0\0\0", 12)
+ << std::optional<QStringConverter::Encoding>(QStringConverter::Utf32LE);
+ QTest::newRow("utf32 nobom no match")
+ << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
+ << std::optional<QStringConverter::Encoding>();
+}
+
+void tst_QStringConverter::encodingForData()
+{
+ QFETCH(QByteArray, encoded);
+ QFETCH(std::optional<QStringConverter::Encoding>, encoding);
+
+ auto e = QStringConverter::encodingForData(encoded, char16_t('<'));
+ QCOMPARE(e, encoding);
+}
+
+
+void tst_QStringConverter::encodingForHtml_data()
+{
+ QTest::addColumn<QByteArray>("html");
+ QTest::addColumn<std::optional<QStringConverter::Encoding>>("encoding");
+ QTest::addColumn<QByteArray>("name"); // ICU name if we have ICU support
+
+ QByteArray html = "<html><head></head><body>blah</body></html>";
+ QTest::newRow("no charset") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-15\" /></head></html>";
+ QTest::newRow("latin 15") << html << std::optional<QStringConverter::Encoding>() << QByteArray("ISO-8859-15");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=SJIS\" /></head></html>";
+ QTest::newRow("sjis") << html << std::optional<QStringConverter::Encoding>() << QByteArray("Shift_JIS");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-2022-JP\" /></head></html>";
+ QTest::newRow("ISO-2022-JP") << html << std::optional<QStringConverter::Encoding>() << QByteArray("ISO-2022-JP");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-2022\" /></head></html>";
+ QTest::newRow("ISO-2022") << html << std::optional<QStringConverter::Encoding>() << QByteArray("ISO-2022-JP");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=GB2312\" /></head></html>";
+ QTest::newRow("GB2312") << html << std::optional<QStringConverter::Encoding>() << QByteArray("GB2312");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=Big5\" /></head></html>";
+ QTest::newRow("Big5") << html << std::optional<QStringConverter::Encoding>() << QByteArray("Big5");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=GB18030\" /></head></html>";
+ QTest::newRow("GB18030") << html << std::optional<QStringConverter::Encoding>() << QByteArray("GB18030");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=GB2312-HKSCS\" /></head></html>";
+ QTest::newRow("GB2312-HKSCS") << html << std::optional<QStringConverter::Encoding>() << QByteArray("GB2312-HKSCS");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=Big5-HKSCS\" /></head></html>";
+ QTest::newRow("Big5-HKSCS") << html << std::optional<QStringConverter::Encoding>() << QByteArray("Big5-HKSCS");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=EucJP\" /></head></html>";
+ QTest::newRow("EucJP") << html << std::optional<QStringConverter::Encoding>() << QByteArray("EUC-JP");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=EucKR\" /></head></html>";
+ QTest::newRow("EucKR") << html << std::optional<QStringConverter::Encoding>() << QByteArray("EUC-KR");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=KOI8-R\" /></head></html>";
+ QTest::newRow("KOI8-R") << html << std::optional<QStringConverter::Encoding>() << QByteArray("KOI8-R");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=KOI8-U\" /></head></html>";
+ QTest::newRow("KOI8-U") << html << std::optional<QStringConverter::Encoding>() << QByteArray("KOI8-U");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\" /></head></html>";
+ QTest::newRow("latin 1") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Latin1) << QByteArray("ISO-8859-1");
+
+ html = "<!DOCTYPE html><html><head><meta charset=\"ISO_8859-1:1987\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><title>Test</title></head>";
+ QTest::newRow("latin 1 (#2)") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Latin1) << QByteArray("ISO-8859-1");
+
+ html = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><title>Test</title></head>";
+ QTest::newRow("UTF-8") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"utf-8\"><title>Test</title></head>";
+ QTest::newRow("UTF-8 (#2)") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8/></head></html>";
+ QTest::newRow("UTF-8, no quotes") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset='UTF-8'/></head></html>";
+ QTest::newRow("UTF-8, single quotes") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<!DOCTYPE html><html><head><meta charset=utf-8><title>Test</title></head>";
+ QTest::newRow("UTF-8, > terminator") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<!DOCTYPE html><html><head><meta charset= utf-8 ><title>Test</title></head>";
+ QTest::newRow("UTF-8, > terminator with spaces") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ // Test invalid charsets.
+ html = "<!DOCTYPE html><html><head><meta charset= utf/8 ><title>Test</title></head>";
+ QTest::newRow("utf/8") << html << std::optional<QStringConverter::Encoding>() << QByteArray();
+
+ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=invalid-foo\" /></head></html>";
+ QTest::newRow("invalid charset, no default") << html << std::optional<QStringConverter::Encoding>() << QByteArray("UTF-8");
+
+ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"";
+ html.prepend(QByteArray().fill(' ', 512 - html.size()));
+ QTest::newRow("invalid charset (large header)") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+
+ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"utf-8";
+ QTest::newRow("invalid charset (no closing double quote)") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+
+ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset='utf-8";
+ QTest::newRow("invalid charset (no closing single quote)") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<!DOCTYPE html><html><head><meta charset=utf-8 foo=bar><title>Test</title></head>";
+ QTest::newRow("invalid (space terminator)") << html << std::optional<QStringConverter::Encoding>() << QByteArray();
+
+ html = "<!DOCTYPE html><html><head><meta charset=\" utf' 8 /><title>Test</title></head>";
+ QTest::newRow("invalid charset, early terminator (')") << html << std::optional<QStringConverter::Encoding>() << QByteArray();
+
+ const char src[] = { char(0xff), char(0xfe), char(0x7a), char(0x03), 0, 0 };
+ html = src;
+ QTest::newRow("greek text UTF-16LE") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf16LE) << QByteArray("UTF-16LE");
+
+
+ html = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><span style=\"color: rgb(0, 0, 0); font-family: "
+ "'Galatia SIL'; font-size: 27px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; "
+ "line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: "
+ "auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: "
+ "none;\">&#x37b</span>\000";
+ QTest::newRow("greek text UTF-8") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+
+ html = "<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=unicode\">"
+ "<head/><body><p>bla</p></body></html>"; // QTBUG-41998, ICU will return UTF-16.
+ QTest::newRow("legacy unicode UTF-8") << html << std::optional<QStringConverter::Encoding>(QStringConverter::Utf8) << QByteArray("UTF-8");
+}
+
+void tst_QStringConverter::encodingForHtml()
+{
+ QFETCH(QByteArray, html);
+ QFETCH(std::optional<QStringConverter::Encoding>, encoding);
+ QFETCH(QByteArray, name);
+
+ QCOMPARE(QStringConverter::encodingForHtml(html), encoding);
+
+ QStringDecoder decoder = QStringDecoder::decoderForHtml(html);
+ if (encoding || // we should have a valid decoder independent of ICU support
+ decoder.isValid()) { // we got a valid decoder through ICU
+ QCOMPARE(decoder.name(), name);
+ }
+}
+
+void tst_QStringConverter::availableCodesAreAvailable()
+{
+ auto codecs = QStringConverter::availableCodecs();
+ for (const auto &codecName: codecs)
+ QVERIFY(QStringEncoder(codecName.toLatin1()).isValid());
+}
+
+class LoadAndConvert: public QRunnable
+{
+public:
+ LoadAndConvert(QStringConverter::Encoding encoding, QString *destination)
+ : encode(encoding), decode(encoding), target(destination)
+ {}
+ QStringEncoder encode;
+ QStringDecoder decode;
+ QString *target;
+ void run() override
+ {
+ QString str = QString::fromLatin1("abcdefghijklmonpqrstufvxyz");
+ for (int i = 0; i < 10000; ++i) {
+ QByteArray b = encode(str);
+ *target = decode(b);
+ QCOMPARE(*target, str);
+ }
+ }
+};
+
+void tst_QStringConverter::initTestCase()
+{
+ if (localeIsUtf8())
+ qInfo("System locale is UTF-8");
+ else
+ qInfo("System locale is not UTF-8");
+}
+
+void tst_QStringConverter::threadSafety()
+{
+#if defined(Q_OS_WASM)
+ QSKIP("This test misbehaves on WASM. Investigation needed (QTBUG-110067)");
+#endif
+
+ QThreadPool::globalInstance()->setMaxThreadCount(12);
+
+ QList<QString> res;
+ res.resize(QStringConverter::LastEncoding + 1);
+ for (int i = 0; i < QStringConverter::LastEncoding + 1; ++i) {
+ QThreadPool::globalInstance()->start(new LoadAndConvert(QStringConverter::Encoding(i), &res[i]));
+ }
+
+ // wait for all threads to finish working
+ QThreadPool::globalInstance()->waitForDone();
+
+ for (auto b : res)
+ QCOMPARE(b, QString::fromLatin1("abcdefghijklmonpqrstufvxyz"));
+}
+
+#ifdef Q_OS_WIN
+void tst_QStringConverter::fromLocal8Bit_data()
+{
+ QTest::addColumn<QByteArray>("eightBit");
+ QTest::addColumn<QString>("utf16");
+ QTest::addColumn<quint32>("codePage");
+
+ constexpr uint WINDOWS_1252 = 1252u;
+ QTest::newRow("windows-1252") << "Hello, world!"_ba << u"Hello, world!"_s << WINDOWS_1252;
+ constexpr uint SHIFT_JIS = 932u;
+ // Mostly two byte characters, but the comma is a single byte character (0xa4)
+ QTest::newRow("shiftJIS")
+ << "\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\xa4\x90\xa2\x8a\x45\x81\x49"_ba
+ << u"こんにちは、世界!"_s << SHIFT_JIS;
+
+ constexpr uint GB_18030 = 54936u;
+ QTest::newRow("GB-18030") << "\xc4\xe3\xba\xc3\xca\xc0\xbd\xe7\xa3\xa1"_ba << u"你好世界!"_s
+ << GB_18030;
+}
+
+void tst_QStringConverter::fromLocal8Bit()
+{
+ QFETCH(const QByteArray, eightBit);
+ QFETCH(const QString, utf16);
+ QFETCH(const quint32, codePage);
+
+ QStringConverter::State state;
+
+ QString result = QLocal8Bit::convertToUnicode_sys(eightBit, codePage, &state);
+ QCOMPARE(result, utf16);
+ QCOMPARE(state.remainingChars, 0);
+
+ result.clear();
+ state.clear();
+ for (char c : eightBit)
+ result += QLocal8Bit::convertToUnicode_sys({&c, 1}, codePage, &state);
+ QCOMPARE(result, utf16);
+ QCOMPARE(state.remainingChars, 0);
+
+ result.clear();
+ state.clear();
+ // Decode the full string again, this time without state
+ state.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertToUnicode_sys(eightBit, codePage, &state);
+ QCOMPARE(result, utf16);
+ QCOMPARE(state.remainingChars, 0);
+}
+
+void tst_QStringConverter::fromLocal8Bit_special_cases()
+{
+ QStringConverter::State state;
+ constexpr uint SHIFT_JIS = 932u;
+ // Decode a 2-octet character, but only provide 1 octet at first:
+ QString result = QLocal8Bit::convertToUnicode_sys("\x82", SHIFT_JIS, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ QCOMPARE_GT(state.remainingChars, 0);
+ // Then provide the second octet:
+ result = QLocal8Bit::convertToUnicode_sys("\xb1", SHIFT_JIS, &state);
+ QCOMPARE(result, u"こ");
+ QCOMPARE(state.remainingChars, 0);
+
+ // And without state:
+ result.clear();
+ QStringConverter::State statelessState;
+ statelessState.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertToUnicode_sys("\x82", SHIFT_JIS, &statelessState);
+ result += QLocal8Bit::convertToUnicode_sys("\xb1", SHIFT_JIS, &statelessState);
+ // 0xb1 is a valid single-octet character in Shift-JIS, so the output
+ // isn't really what you would expect:
+ QCOMPARE(result, QString(QChar::ReplacementCharacter) + u'ア');
+ QCOMPARE(statelessState.remainingChars, 0);
+
+ // Now try a 3-octet UTF-8 sequence:
+ result.clear();
+ state.clear();
+ constexpr uint UTF8 = 65001u;
+ // First the first 2 octets:
+ result = QLocal8Bit::convertToUnicode_sys("\xe4\xbd", UTF8, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ QCOMPARE_GT(state.remainingChars, 0);
+ // Then provide the remaining octet:
+ result = QLocal8Bit::convertToUnicode_sys("\xa0", UTF8, &state);
+ QCOMPARE(result, u"你");
+ QCOMPARE(state.remainingChars, 0);
+
+ // Now the same, but there is an incomplete sequence at the start
+ result.clear();
+ state.clear();
+ result = QLocal8Bit::convertToUnicode_sys("\xe4\xe4\xbd", UTF8, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ // Remaining octet (and a '.' to force it to discard something from the
+ // internal state which is currently limited to 4 octets):
+ result += QLocal8Bit::convertToUnicode_sys("\xa0.", UTF8, &state);
+ QCOMPARE(result, QChar::ReplacementCharacter + u"你."_s);
+ QCOMPARE(state.remainingChars, 0);
+
+ // Test QTBUG-118834, which is failing
+ result.clear();
+ state.clear();
+ result = QLocal8Bit::convertToUnicode_sys("\xe4\xe4\xbd", UTF8, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ // Remaining octet:
+ result += QLocal8Bit::convertToUnicode_sys("\xa0", UTF8, &state);
+ QEXPECT_FAIL("", "QTBUG-118834: We don't output anything because it's "
+ "within the size of our internal state, and we cannot "
+ "signal that it needs to be drained.", Continue);
+ QCOMPARE(result, QChar::ReplacementCharacter + u"你"_s);
+ QEXPECT_FAIL("", "QTBUG-118834: As above", Continue);
+ QCOMPARE(state.remainingChars, 0);
+
+ // Now try a 4-octet GB 18030 sequence:
+ result.clear();
+ state.clear();
+ constexpr uint GB_18030 = 54936u;
+ const char sequence[] = "\x95\x32\x90\x31";
+ // Repeat the sequence multiple times to test handling of exhaustion of
+ // internal buffer
+ QByteArray repeated = QByteArray(sequence).repeated(2049);
+ QByteArrayView octets = QByteArrayView(repeated);
+ result = QLocal8Bit::convertToUnicode_sys(octets.first(2), GB_18030, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ QCOMPARE_GT(state.remainingChars, 0);
+ // Then provide one more octet:
+ result = QLocal8Bit::convertToUnicode_sys(octets.sliced(2, 1), GB_18030, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ QCOMPARE_GT(state.remainingChars, 0);
+ // Then provide the last octet + the rest of the string
+ result = QLocal8Bit::convertToUnicode_sys(octets.sliced(3), GB_18030, &state);
+ QCOMPARE(result.first(2), u"𠂇");
+ QCOMPARE(state.remainingChars, 0);
+}
+
+void tst_QStringConverter::fromLocal8Bit_2GiB()
+{
+#if QT_POINTER_SIZE == 4
+ QSKIP("This test is only relevant for 64-bit builds");
+#else
+ qsizetype size = qsizetype(std::numeric_limits<int>::max()) + 3;
+ QByteArray input;
+ QT_TRY {
+ input.reserve(size);
+ } QT_CATCH (const std::bad_alloc &) {
+ QSKIP("Out of memory");
+ }
+ // fill with '、' - a single octet character in Shift-JIS
+ input.fill('\xa4', std::numeric_limits<int>::max() - 1);
+ // then append 'こ' - a two octet character in Shift-JIS
+ // which is now straddling the 2 GiB boundary
+ input += "\x82\xb1";
+ // then append another two '、', so that our output is also crossing the
+ // 2 GiB boundary
+ input += "\xa4\xa4";
+ QCOMPARE(input.size(), input.capacity());
+ constexpr uint SHIFT_JIS = 932u;
+ QStringConverter::State state;
+ QString result;
+ QT_TRY {
+ result = QLocal8Bit::convertToUnicode_sys(input, SHIFT_JIS, &state);
+ } QT_CATCH (const std::bad_alloc &) {
+ QSKIP("Out of memory");
+ }
+ QCOMPARE(result.size(), size - 1); // The 2-octet character is only 1 code unit in UTF-16
+ QCOMPARE(result.last(4), u"、こ、、"); // Check we correctly decoded it
+ QCOMPARE(state.remainingChars, 0); // and there is nothing left in the state
+#endif
+}
+
+void tst_QStringConverter::toLocal8Bit_data()
+{
+ fromLocal8Bit_data();
+}
+
+void tst_QStringConverter::toLocal8Bit()
+{
+ QFETCH(const QByteArray, eightBit);
+ QFETCH(const QString, utf16);
+ QFETCH(const quint32, codePage);
+
+ QStringConverter::State state;
+
+ QByteArray result = QLocal8Bit::convertFromUnicode_sys(utf16, codePage, &state);
+ QCOMPARE(result, eightBit);
+ QCOMPARE(state.remainingChars, 0);
+
+ result.clear();
+ state.clear();
+ for (QChar c : utf16)
+ result += QLocal8Bit::convertFromUnicode_sys(QStringView(&c, 1), codePage, &state);
+ QCOMPARE(result, eightBit);
+ QCOMPARE(state.remainingChars, 0);
+
+ result.clear();
+ state.clear();
+ // Decode the full string again, this time without state
+ state.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertFromUnicode_sys(utf16, codePage, &state);
+ QCOMPARE(result, eightBit);
+ QCOMPARE(state.remainingChars, 0);
+}
+
+void tst_QStringConverter::toLocal8Bit_special_cases()
+{
+ QStringConverter::State state;
+ // Normally utf8 goes through a different code path, but we can force it here
+ constexpr uint UTF8 = 65001u;
+ // Decode a 2-code unit character, but only provide 1 code unit at first:
+ const char16_t a[] = u"𬽦";
+ QStringView codeUnits = a;
+ QByteArray result = QLocal8Bit::convertFromUnicode_sys(codeUnits.first(1), UTF8, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ QCOMPARE_GT(state.remainingChars, 0);
+ // Then provide the second code unit:
+ result = QLocal8Bit::convertFromUnicode_sys(codeUnits.sliced(1), UTF8, &state);
+ QCOMPARE(result, "\xf0\xac\xbd\xa6"_ba);
+ QCOMPARE(state.remainingChars, 0);
+
+ // Retain compat with the behavior for toLocal8Bit:
+ QCOMPARE(codeUnits.first(1).toLocal8Bit(), "?");
+
+ // QString::toLocal8Bit is already stateless, but test stateless handling
+ // explicitly anyway:
+ result.clear();
+ QStringConverter::State statelessState;
+ statelessState.flags |= QStringConverter::Flag::Stateless;
+ result = QLocal8Bit::convertFromUnicode_sys(codeUnits.first(1), UTF8, &statelessState);
+ result += QLocal8Bit::convertFromUnicode_sys(codeUnits.sliced(1), UTF8, &statelessState);
+ // Windows uses the replacement character for invalid characters:
+ QCOMPARE(result, "\ufffd\ufffd");
+
+ // Now do the same, but the second time we feed in a character, we also
+ // provide many more so the internal stack buffer is not large enough.
+ result.clear();
+ state.clear();
+ QString str = QStringView(a).toString().repeated(2048);
+ codeUnits = str;
+ result = QLocal8Bit::convertFromUnicode_sys(codeUnits.first(1), UTF8, &state);
+ QCOMPARE(result, QString());
+ QVERIFY(result.isNull());
+ QCOMPARE_GT(state.remainingChars, 0);
+ // Then we provide the rest of the string:
+ result = QLocal8Bit::convertFromUnicode_sys(codeUnits.sliced(1), UTF8, &state);
+ QCOMPARE(result.first(4), "\xf0\xac\xbd\xa6"_ba);
+ QCOMPARE(state.remainingChars, 0);
+}
+
+void tst_QStringConverter::toLocal8Bit_2GiB()
+{
+#if QT_POINTER_SIZE == 4
+ QSKIP("This test is only relevant for 64-bit builds");
+#else
+ constexpr qsizetype TwoGiB = qsizetype(std::numeric_limits<int>::max());
+ QString input;
+ QT_TRY {
+ input.reserve(TwoGiB + 1);
+ } QT_CATCH (const std::bad_alloc &) {
+ QSKIP("Out of memory");
+ }
+ // Fill with a single code unit character
+ input.fill(u'.', TwoGiB - 1);
+ // Then append a 2 code unit character, so that the input straddles the 2 GiB
+ // boundary
+ input += u"🙂";
+ QCOMPARE(input.size(), input.capacity());
+ constexpr uint UTF8 = 65001u;
+ QStringConverter::State state;
+ QByteArray result;
+ QT_TRY {
+ result = QLocal8Bit::convertFromUnicode_sys(input, UTF8, &state);
+ } QT_CATCH (const std::bad_alloc &) {
+ QSKIP("Out of memory");
+ }
+ QUtf8StringView rView = result;
+ QCOMPARE(rView.size(), TwoGiB + 3); // The 2 code unit smiley is 4 code units in UTF-8
+ QCOMPARE(rView.last(7), u8"...🙂"); // Check we correctly decoded it
+ QCOMPARE(state.remainingChars, 0); // and there is nothing left in the state
+#endif
+}
+#endif // Q_OS_WIN
+
+struct DontCrashAtExit {
+ ~DontCrashAtExit() {
+ QStringDecoder decoder(QStringDecoder::Utf8);
+ QVERIFY(decoder.isValid());
+ (void)decoder("azerty");
+ }
+} dontCrashAtExit;
+
+
+QTEST_MAIN(tst_QStringConverter)
+#include "tst_qstringconverter.moc"
diff --git a/tests/auto/corelib/text/qstringiterator/CMakeLists.txt b/tests/auto/corelib/text/qstringiterator/CMakeLists.txt
new file mode 100644
index 0000000000..7927fd9e8d
--- /dev/null
+++ b/tests/auto/corelib/text/qstringiterator/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringiterator Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringiterator LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringiterator
+ SOURCES
+ tst_qstringiterator.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp b/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp
new file mode 100644
index 0000000000..22bff24eec
--- /dev/null
+++ b/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp
@@ -0,0 +1,637 @@
+// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtCore/QString>
+#include <private/qstringiterator_p.h>
+
+class tst_QStringIterator : public QObject
+{
+ Q_OBJECT
+private slots:
+ void sweep_data();
+ void sweep();
+
+ void position();
+};
+
+void tst_QStringIterator::sweep_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<int>("count");
+
+ QTest::newRow("sweep_00") << QString::fromUtf8("", 0) << true << 0;
+ QTest::newRow("sweep_01") << QString::fromUtf8("a", 1) << true << 1;
+ QTest::newRow("sweep_02") << QString::fromUtf8("a string", 8) << true << 8;
+ QTest::newRow("sweep_03") << QString::fromUtf8("\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb2\xc3\xb9", 10) << true << 5;
+ QTest::newRow("sweep_04") << QString::fromUtf8("\xc3\x9f\xe2\x80\x94\xc2\xa1", 7) << true << 3;
+ QTest::newRow("sweep_05") << QString::fromUtf8("\xe6\xb0\xb4\xe6\xb0\xb5\xe6\xb0\xb6\xe6\xb0\xb7\xe6\xb0\xb8\xe6\xb0\xb9", 18) << true << 6;
+ QTest::newRow("sweep_06") << QString::fromUtf8("\xf0\x9f\x98\x81\xf0\x9f\x98\x82\x61\x62\x63\xf0\x9f\x98\x83\xc4\x91\xc3\xa8\xef\xac\x80\xf0\x9f\x98\x84\xf0\x9f\x98\x85", 30) << true << 11;
+ QTest::newRow("sweep_07") << QString::fromUtf8("\xf0\x9f\x82\xaa\xf0\x9f\x82\xab\xf0\x9f\x82\xad\xf0\x9f\x82\xae\xf0\x9f\x82\xa1\x20\x52\x4f\x59\x41\x4c\x20\x46\x4c\x55\x53\x48\x20\x4f\x46\x20\x53\x50\x41\x44\x45\x53", 42) << true << 27;
+ QTest::newRow("sweep_08") << QString::fromUtf8("abc\0def", 7) << true << 7;
+ QTest::newRow("sweep_09") << QString::fromUtf8("\xc3\xa0\xce\xb2\xc3\xa7\xf0\x9f\x80\xb9\xf0\x9f\x80\xb8\x00\xf0\x9f\x80\xb1\x00\xf0\x9f\x80\xb3\xf0\x9f\x81\x85\xe1\xb8\x8a\xc4\x99\xc6\x92", 35) << true << 13;
+
+ QTest::newRow("sweep_invalid_00") << QString(QChar(0xd800)) << false << 1;
+ QTest::newRow("sweep_invalid_01") << QString(QChar(0xdc00)) << false << 1;
+ QTest::newRow("sweep_invalid_02") << QString(QChar(0xdbff)) << false << 1;
+ QTest::newRow("sweep_invalid_03") << QString(QChar(0xdfff)) << false << 1;
+
+#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
+
+ static const QChar invalid_04[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800)
+ };
+ QTest::newRow("sweep_invalid_04") << QSTRING_FROM_QCHARARRAY(invalid_04) << false << 8;
+
+ static const QChar invalid_05[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_05") << QSTRING_FROM_QCHARARRAY(invalid_05) << false << 9;
+
+ static const QChar invalid_06[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00)
+ };
+ QTest::newRow("sweep_invalid_06") << QSTRING_FROM_QCHARARRAY(invalid_06) << false << 8;
+
+ static const QChar invalid_07[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_07") << QSTRING_FROM_QCHARARRAY(invalid_07) << false << 9;
+
+ static const QChar invalid_08[] = {
+ QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_08") << QSTRING_FROM_QCHARARRAY(invalid_08) << false << 8;
+
+ static const QChar invalid_09[] = {
+ QChar(0xdc00),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_09") << QSTRING_FROM_QCHARARRAY(invalid_09) << false << 8;
+
+ static const QChar invalid_10[] = {
+ QChar(0xd800), QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_10") << QSTRING_FROM_QCHARARRAY(invalid_10) << false << 9;
+
+ static const QChar invalid_11[] = {
+ QChar(0xdc00), QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_11") << QSTRING_FROM_QCHARARRAY(invalid_11) << false << 9;
+
+ static const QChar invalid_12[] = {
+ QChar(0xdc00), QChar(0xdc00),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_12") << QSTRING_FROM_QCHARARRAY(invalid_12) << false << 9;
+
+ static const QChar invalid_13[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800)
+ };
+ QTest::newRow("sweep_invalid_13") << QSTRING_FROM_QCHARARRAY(invalid_13) << false << 9;
+
+ static const QChar invalid_14[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_14") << QSTRING_FROM_QCHARARRAY(invalid_14) << false << 10;
+
+ static const QChar invalid_15[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00)
+ };
+ QTest::newRow("sweep_invalid_15") << QSTRING_FROM_QCHARARRAY(invalid_15) << false << 9;
+
+ static const QChar invalid_16[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_16") << QSTRING_FROM_QCHARARRAY(invalid_16) << false << 10;
+
+ static const QChar invalid_17[] = {
+ QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_17") << QSTRING_FROM_QCHARARRAY(invalid_17) << false << 9;
+
+ static const QChar invalid_18[] = {
+ QChar(0xdc00),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_18") << QSTRING_FROM_QCHARARRAY(invalid_18) << false << 9;
+
+#undef QSTRING_FROM_QCHARARRAY
+}
+
+void tst_QStringIterator::sweep()
+{
+ QFETCH(QString, string);
+ QFETCH(bool, valid);
+
+ QStringIterator i(string);
+ int count = 0;
+ QString rebuiltString;
+
+ while (i.hasNext()) {
+ const char32_t peekedCodePoint = i.peekNext(~0u);
+ const char32_t codePoint = i.next(~0u);
+
+ QVERIFY(peekedCodePoint == codePoint);
+
+ if (codePoint == ~0u)
+ rebuiltString += *(i.position() - 1);
+ else
+ rebuiltString += QChar::fromUcs4(codePoint);
+
+ ++count;
+ }
+
+ QTEST(count, "count");
+ QTEST(rebuiltString, "string");
+ rebuiltString.clear();
+
+ while (i.hasPrevious()) {
+ const char32_t peekedCodePoint = i.peekPrevious(~0u);
+ const char32_t codePoint = i.previous(~0u);
+
+ QVERIFY(peekedCodePoint == codePoint);
+
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+
+ while (i.hasNext()) {
+ i.advance();
+ ++count;
+ }
+
+ QTEST(count, "count");
+
+ while (i.hasPrevious()) {
+ i.recede();
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+
+ if (valid) {
+ while (i.hasNext()) {
+ const char32_t peekedCodePoint = i.peekNextUnchecked();
+ const char32_t codePoint = i.nextUnchecked();
+
+ QVERIFY(peekedCodePoint == codePoint);
+ QVERIFY(codePoint <= 0x10FFFFu);
+ rebuiltString += QChar::fromUcs4(codePoint);
+ ++count;
+ }
+
+ QTEST(count, "count");
+ QTEST(rebuiltString, "string");
+
+ while (i.hasPrevious()) {
+ const char32_t peekedCodePoint = i.peekPreviousUnchecked();
+ const char32_t codePoint = i.previousUnchecked();
+
+ QVERIFY(peekedCodePoint == codePoint);
+
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+
+ while (i.hasNext()) {
+ i.advanceUnchecked();
+ ++count;
+ }
+
+ QTEST(count, "count");
+
+ while (i.hasPrevious()) {
+ i.recedeUnchecked();
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+ }
+}
+
+void tst_QStringIterator::position()
+{
+ static const QChar stringData[] =
+ {
+ // codeunit count: 0
+ QLatin1Char('a'), QLatin1Char('b'), QLatin1Char('c'),
+ // codeunit count: 3
+ QChar(0x00A9), // U+00A9 COPYRIGHT SIGN
+ // codeunit count: 4
+ QChar(0x00AE), // U+00AE REGISTERED SIGN
+ // codeunit count: 5
+ QLatin1Char('d'), QLatin1Char('e'), QLatin1Char('f'),
+ // codeunit count: 8
+ QLatin1Char('\0'),
+ // codeunit count: 9
+ QLatin1Char('g'), QLatin1Char('h'), QLatin1Char('i'),
+ // codeunit count: 12
+ QChar(0xD834), QChar(0xDD1E), // U+1D11E MUSICAL SYMBOL G CLEF
+ // codeunit count: 14
+ QChar(0xD834), QChar(0xDD21), // U+1D121 MUSICAL SYMBOL C CLEF
+ // codeunit count: 16
+ QLatin1Char('j'),
+ // codeunit count: 17
+ QChar(0xD800), // stray high surrogate
+ // codeunit count: 18
+ QLatin1Char('k'),
+ // codeunit count: 19
+ QChar(0xDC00), // stray low surrogate
+ // codeunit count: 20
+ QLatin1Char('l'),
+ // codeunit count: 21
+ QChar(0xD800), QChar(0xD800), // two high surrogates
+ // codeunit count: 23
+ QLatin1Char('m'),
+ // codeunit count: 24
+ QChar(0xDC00), QChar(0xDC00), // two low surrogates
+ // codeunit count: 26
+ QLatin1Char('n'),
+ // codeunit count: 27
+ QChar(0xD800), QChar(0xD800), QChar(0xDC00), // stray high surrogate followed by valid pair
+ // codeunit count: 30
+ QLatin1Char('o'),
+ // codeunit count: 31
+ QChar(0xDC00), QChar(0xD800), QChar(0xDC00), // stray low surrogate followed by valid pair
+ // codeunit count: 34
+ QLatin1Char('p')
+ // codeunit count: 35
+ };
+ static const int stringDataSize = sizeof(stringData) / sizeof(stringData[0]);
+
+ QStringIterator i(QStringView(stringData, stringDataSize));
+
+ QCOMPARE(i.position(), stringData);
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ i.setPosition(stringData + stringDataSize);
+ QCOMPARE(i.position(), stringData + stringDataSize);
+ QVERIFY(!i.hasNext());
+ QVERIFY(i.hasPrevious());
+
+#define QCHAR_UNICODE_VALUE(x) ((uint)(QChar(x).unicode()))
+
+ const QChar *begin = stringData;
+ i.setPosition(begin);
+ QCOMPARE(i.position(), begin);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
+
+ QCOMPARE(i.position(), begin + 1);
+
+ i.setPosition(begin + 2);
+ QCOMPARE(i.position(), begin + 2);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
+
+ QCOMPARE(i.position(), begin + 3);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00A9));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00A9));
+
+ QCOMPARE(i.position(), begin + 4);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00AE));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00AE));
+
+ QCOMPARE(i.position(), begin + 5);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00AE));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00AE));
+
+ QCOMPARE(i.position(), begin + 4);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00A9));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00A9));
+
+ QCOMPARE(i.position(), begin + 3);
+
+ i.setPosition(begin + 8);
+ QCOMPARE(i.position(), begin + 8);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+
+ QCOMPARE(i.position(), begin + 9);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+
+ QCOMPARE(i.position(), begin + 10);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+
+ QCOMPARE(i.position(), begin + 9);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+
+ QCOMPARE(i.position(), begin + 8);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
+
+ QCOMPARE(i.position(), begin + 7);
+
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+
+ QCOMPARE(i.position(), begin + 12);
+ QCOMPARE(i.peekNext(), 0x1D11Eu);
+ QCOMPARE(i.next(), 0x1D11Eu);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekNext(), 0x1D121u);
+ QCOMPARE(i.next(), 0x1D121u);
+
+ QCOMPARE(i.position(), begin + 16);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ QCOMPARE(i.position(), begin + 17);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ QCOMPARE(i.position(), begin + 16);
+ QCOMPARE(i.peekPrevious(), 0x1D121u);
+ QCOMPARE(i.previous(), 0x1D121u);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekPrevious(), 0x1D11Eu);
+ QCOMPARE(i.previous(), 0x1D11Eu);
+
+ QCOMPARE(i.position(), begin + 12);
+
+
+ i.setPosition(begin + 13);
+ QCOMPARE(i.position(), begin + 13);
+
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekNext(), 0x1D121u);
+ QCOMPARE(i.next(), 0x1D121u);
+
+ QCOMPARE(i.position(), begin + 16);
+
+
+ i.setPosition(begin + 15);
+ QCOMPARE(i.position(), begin + 15);
+
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekPrevious(), 0x1D11Eu);
+ QCOMPARE(i.previous(), 0x1D11Eu);
+
+ QCOMPARE(i.position(), begin + 12);
+
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+
+ QCOMPARE(i.position(), begin + 16);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ QCOMPARE(i.position(), begin + 17);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 18);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+
+ QCOMPARE(i.position(), begin + 19);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 20);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+
+ QCOMPARE(i.position(), begin + 21);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 22);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 23);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+
+ QCOMPARE(i.position(), begin + 24);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 25);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 26);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+
+ QCOMPARE(i.position(), begin + 27);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 28);
+ QCOMPARE(i.peekNext(), 0x10000u);
+ QCOMPARE(i.next(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 31);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 32);
+ QCOMPARE(i.peekNext(), 0x10000u);
+ QCOMPARE(i.next(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QVERIFY(!i.hasNext());
+
+ QCOMPARE(i.position(), begin + 35);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 32);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 31);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 28);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 27);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+
+ QCOMPARE(i.position(), begin + 26);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 25);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 24);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+
+ QCOMPARE(i.position(), begin + 23);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 22);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 21);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+
+ QCOMPARE(i.position(), begin + 20);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 19);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+
+ QCOMPARE(i.position(), begin + 18);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 17);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ i.setPosition(begin + 29);
+ QCOMPARE(i.position(), begin + 29);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 31);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 28);
+
+ i.setPosition(begin + 33);
+ QCOMPARE(i.position(), begin + 33);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QCOMPARE(i.position(), begin + 35);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 32);
+
+
+ i.setPosition(begin + 16);
+ QCOMPARE(i.position(), begin + 16);
+
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ QCOMPARE(i.position(), begin + 12);
+
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ QCOMPARE(i.position(), begin + 8);
+
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ QCOMPARE(i.position(), begin + 2);
+
+#undef QCHAR_UNICODE_VALUE
+}
+
+QTEST_APPLESS_MAIN(tst_QStringIterator)
+
+#include "tst_qstringiterator.moc"
diff --git a/tests/auto/corelib/tools/qstringlist/.gitignore b/tests/auto/corelib/text/qstringlist/.gitignore
index 3e0cdc952f..3e0cdc952f 100644
--- a/tests/auto/corelib/tools/qstringlist/.gitignore
+++ b/tests/auto/corelib/text/qstringlist/.gitignore
diff --git a/tests/auto/corelib/text/qstringlist/CMakeLists.txt b/tests/auto/corelib/text/qstringlist/CMakeLists.txt
new file mode 100644
index 0000000000..d8f8a740c3
--- /dev/null
+++ b/tests/auto/corelib/text/qstringlist/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringlist Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringlist LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringlist
+ SOURCES
+ tst_qstringlist.cpp
+)
diff --git a/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp
new file mode 100644
index 0000000000..6ac8236d57
--- /dev/null
+++ b/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp
@@ -0,0 +1,479 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qlist.h>
+#include <qregularexpression.h>
+#include <qstringlist.h>
+#include <QScopeGuard>
+
+#include <locale.h>
+
+#include <algorithm>
+
+using namespace Qt::StringLiterals;
+
+class tst_QStringList : public QObject
+{
+ Q_OBJECT
+private slots:
+ void constructors();
+ void sort();
+ void filter();
+ void replaceInStrings();
+ void removeDuplicates();
+ void removeDuplicates_data();
+ void contains_data();
+ void contains();
+ void indexOf_data();
+ void indexOf();
+ void lastIndexOf_data();
+ void lastIndexOf();
+
+ void streamingOperator();
+ void assignmentOperator();
+ void join() const;
+ void join_data() const;
+ void joinEmptiness() const;
+ void joinChar() const;
+ void joinChar_data() const;
+
+ void initializeList() const;
+};
+
+extern const char email[];
+
+void tst_QStringList::constructors()
+{
+ {
+ QStringList list;
+ QVERIFY(list.isEmpty());
+ QCOMPARE(list.size(), 0);
+ QVERIFY(list == QStringList());
+ }
+ {
+ QString str = "abc";
+ QStringList list(str);
+ QVERIFY(!list.isEmpty());
+ QCOMPARE(list.size(), 1);
+ QCOMPARE(list.at(0), str);
+ }
+ {
+ QStringList list{ "a", "b", "c" };
+ QVERIFY(!list.isEmpty());
+ QCOMPARE(list.size(), 3);
+ QCOMPARE(list.at(0), "a");
+ QCOMPARE(list.at(1), "b");
+ QCOMPARE(list.at(2), "c");
+ }
+ {
+ const QList<QString> reference{ "a", "b", "c" };
+ QCOMPARE(reference.size(), 3);
+
+ QStringList list(reference.cbegin(), reference.cend());
+ QCOMPARE(list.size(), reference.size());
+ QVERIFY(std::equal(list.cbegin(), list.cend(), reference.cbegin()));
+ }
+}
+
+void tst_QStringList::indexOf_data()
+{
+ QTest::addColumn<QStringList>("list");
+ QTest::addColumn<QString>("search");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("expectedResult");
+
+ QStringList searchIn{"harald", "trond", "vohi", "harald"};
+ QTest::newRow("harald") << searchIn << "harald" << 0 << 0;
+ QTest::newRow("trond") << searchIn << "trond" << 0 << 1;
+ QTest::newRow("vohi") << searchIn << "vohi" << 0 << 2;
+ QTest::newRow("harald-1") << searchIn << "harald" << 1 << 3;
+
+ QTest::newRow("hans") << searchIn << "hans" << 0 << -1;
+ QTest::newRow("trond-1") << searchIn << "trond" << 2 << -1;
+ QTest::newRow("harald-2") << searchIn << "harald" << -1 << 3;
+ QTest::newRow("vohi-1") << searchIn << "vohi" << -3 << 2;
+
+ QTest::newRow("from-bigger-than-size") << searchIn << "harald" << 100 << -1;
+
+ searchIn = {"lost+found", "foo.bar"};
+ QTest::newRow("string-with-regex-meta-char1") << searchIn << "lost+found" << 0 << 0;
+ QTest::newRow("string-with-regex-meta-char2") << searchIn << "foo.bar" << 0 << 1;
+ QTest::newRow("string-with-regex-meta-char3") << searchIn << "foo.bar" << 2 << -1;
+}
+
+void tst_QStringList::indexOf()
+{
+ QFETCH(QStringList, list);
+ QFETCH(QString, search);
+ QFETCH(int, from);
+ QFETCH(int, expectedResult);
+
+ QCOMPARE(list.indexOf(search, from), expectedResult);
+ QCOMPARE(list.indexOf(QStringView(search), from), expectedResult);
+ QCOMPARE(list.indexOf(QLatin1String(search.toLatin1()), from), expectedResult);
+ QCOMPARE(list.indexOf(QRegularExpression(QRegularExpression::escape(search)), from), expectedResult);
+
+ QString searchUpper = search.toUpper();
+ QCOMPARE(list.indexOf(searchUpper, from, Qt::CaseInsensitive), expectedResult);
+ QCOMPARE(list.indexOf(QStringView(searchUpper), from, Qt::CaseInsensitive), expectedResult);
+ QCOMPARE(list.indexOf(QLatin1StringView(searchUpper.toLatin1()), from, Qt::CaseInsensitive),
+ expectedResult);
+ const QRegularExpression re(QRegularExpression::escape(searchUpper),
+ QRegularExpression::CaseInsensitiveOption);
+ QCOMPARE(list.indexOf(re, from), expectedResult);
+}
+
+void tst_QStringList::lastIndexOf_data()
+{
+ QTest::addColumn<QStringList>("list");
+ QTest::addColumn<QString>("search");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("expectedResult");
+
+ QStringList list{"harald", "trond", "vohi", "harald"};
+ QTest::newRow("harald") << list << "harald" << -1 << 3;
+ QTest::newRow("trond") << list << "trond" << -1 << 1;
+ QTest::newRow("vohi") << list << "vohi" << -1 << 2;
+ QTest::newRow("harald-1") << list << "harald" << 2 << 0;
+
+ QTest::newRow("hans") << list << "hans" << -1 << -1;
+ QTest::newRow("vohi-1") << list << "vohi" << 1 << -1;
+ QTest::newRow("vohi-2") << list << "vohi" << -1 << 2;
+ QTest::newRow("vohi-3") << list << "vohi" << -3 << -1;
+
+ list = {"lost+found", "foo.bar"};
+ QTest::newRow("string-with-regex-meta-char1") << list << "lost+found" << -1 << 0;
+ QTest::newRow("string-with-regex-meta-char2") << list << "foo.bar" << -1 << 1;
+ QTest::newRow("string-with-regex-meta-char3") << list << "foo.bar" << -2 << -1;
+}
+
+void tst_QStringList::lastIndexOf()
+{
+ QFETCH(QStringList, list);
+ QFETCH(QString, search);
+ QFETCH(int, from);
+ QFETCH(int, expectedResult);
+
+ QCOMPARE(list.lastIndexOf(search, from), expectedResult);
+ QCOMPARE(list.lastIndexOf(QStringView(search), from), expectedResult);
+ QCOMPARE(list.lastIndexOf(QLatin1String(search.toLatin1()), from), expectedResult);
+ QCOMPARE(list.lastIndexOf(QRegularExpression(QRegularExpression::escape(search)), from), expectedResult);
+
+ const QString searchUpper = search.toUpper();
+ QCOMPARE(list.lastIndexOf(searchUpper, from, Qt::CaseInsensitive), expectedResult);
+ QCOMPARE(list.lastIndexOf(QStringView(searchUpper), from, Qt::CaseInsensitive), expectedResult);
+ QCOMPARE(list.lastIndexOf(QLatin1String(searchUpper.toLatin1()), from, Qt::CaseInsensitive),
+ expectedResult);
+ const QRegularExpression re(QRegularExpression::escape(searchUpper),
+ QRegularExpression::CaseInsensitiveOption);
+ QCOMPARE(list.lastIndexOf(re, from), expectedResult);
+}
+
+void tst_QStringList::filter()
+{
+ const QStringList list = {u"Bill Gates"_s, u"Joe Blow"_s, u"Bill Clinton"_s, u"bIll"_s};
+
+ { // CaseSensitive
+ const QStringList expected{u"Bill Gates"_s, u"Bill Clinton"_s};
+ QCOMPARE(list.filter(u"Bill"_s), expected);
+ QCOMPARE(list.filter(u"Bill"), expected);
+ QCOMPARE(list.filter("Bill"_L1), expected);
+ QCOMPARE(list.filter(QRegularExpression(u"[i]ll"_s)), expected);
+ QCOMPARE(list.filter(QStringMatcher(u"Bill")), expected);
+ }
+
+ { // CaseInsensitive
+ const QStringList expected = {u"Bill Gates"_s, u"Bill Clinton"_s, u"bIll"_s};
+ QCOMPARE(list.filter(u"bill"_s, Qt::CaseInsensitive), expected);
+ QCOMPARE(list.filter(u"bill", Qt::CaseInsensitive), expected);
+ QCOMPARE(list.filter("bill"_L1, Qt::CaseInsensitive), expected);
+ QCOMPARE(list.filter(QRegularExpression(u"[i]ll"_s, QRegularExpression::CaseInsensitiveOption)),
+ expected);
+ QCOMPARE(list.filter(QStringMatcher(u"Bill", Qt::CaseInsensitive)), expected);
+ }
+}
+
+void tst_QStringList::sort()
+{
+ QStringList list1, list2;
+ list1 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon";
+ list1.sort();
+ list2 << "BETA" << "Gamma" << "alpha" << "beta" << "epsilon" << "gAmma" << "gamma";
+ QCOMPARE( list1, list2 );
+
+ const char *const currentLocale = setlocale(LC_ALL, "C.UTF-8");
+ if (!currentLocale)
+ QSKIP("Failed to set C locale, needed for testing");
+ const QScopeGuard restore([currentLocale]() { setlocale(LC_ALL, currentLocale); });
+ QStringList list3, list4;
+ list3 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon";
+ list3.sort(Qt::CaseInsensitive);
+ list4 << "alpha" << "beta" << "BETA" << "epsilon" << "Gamma" << "gAmma" << "gamma";
+ // with this list, case insensitive sorting can give more than one permutation for "equivalent"
+ // elements; so we check that the sort gave the formally correct result (list[i] <= list[i+1])
+ for (int i = 0; i < list4.size() - 1; ++i)
+ QVERIFY2(QString::compare(list4.at(i), list4.at(i + 1), Qt::CaseInsensitive) <= 0, qPrintable(QString("index %1 failed").arg(i)));
+ // additional checks
+ QCOMPARE(list4.at(0), QString("alpha"));
+ QVERIFY(list4.indexOf("epsilon") > 0);
+ QVERIFY(list4.indexOf("epsilon") < (list4.size() - 1));
+}
+
+void tst_QStringList::replaceInStrings()
+{
+ QStringList list1, list2;
+ list1 << "alpha" << "beta" << "gamma" << "epsilon";
+ list1.replaceInStrings( "a", "o" );
+ list2 << "olpho" << "beto" << "gommo" << "epsilon";
+ QCOMPARE( list1, list2 );
+
+ QStringList list7, list8;
+ list7 << "alpha" << "beta" << "gamma" << "epsilon";
+ list7.replaceInStrings( QRegularExpression("^a"), "o" );
+ list8 << "olpha" << "beta" << "gamma" << "epsilon";
+ QCOMPARE( list7, list8 );
+
+ QStringList list9, list10;
+ list9 << "Bill Clinton" << "Gates, Bill";
+ list10 << "Bill Clinton" << "Bill Gates";
+ list9.replaceInStrings( QRegularExpression("^(.*), (.*)$"), "\\2 \\1" );
+ QCOMPARE( list9, list10 );
+
+ QStringList list11, list12, list13, list14;
+ list11 << "alpha" << "beta" << "gamma" << "epsilon";
+ list12 << "alpha" << "beta" << "gamma" << "epsilon";
+ list13 << "alpha" << "beta" << "gamma" << "epsilon";
+ list11.replaceInStrings( QStringView(QString("a")), QStringView(QString("o")) );
+ list12.replaceInStrings( QStringView(QString("a")), QString("o") );
+ list13.replaceInStrings( QString("a"), QStringView(QString("o")) );
+ list14 << "olpho" << "beto" << "gommo" << "epsilon";
+ QCOMPARE( list11, list12 );
+
+ QStringList list{"alpha", "beta", "gamma"};
+ QStringList copy = list;
+ QVERIFY(!copy.isDetached());
+
+ // No matches, no detach
+ copy.replaceInStrings("z", "y");
+ QVERIFY(!copy.isDetached());
+ QCOMPARE(copy, list);
+
+ copy.replaceInStrings("a", "y");
+ QVERIFY(copy.isDetached());
+ QCOMPARE(copy, (QStringList{"ylphy", "bety", "gymmy"}));
+}
+
+void tst_QStringList::contains_data()
+{
+ QTest::addColumn<QString>("needle");
+ QTest::addColumn<Qt::CaseSensitivity>("cs");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("arthur") << u"arthur"_s << Qt::CaseSensitive << true;
+ QTest::newRow("ArthuR") << u"ArthuR"_s << Qt::CaseSensitive << false;
+ QTest::newRow("arthur") << u"arthur"_s << Qt::CaseInsensitive << true;
+ QTest::newRow("ArthuR") << u"ArthuR"_s << Qt::CaseInsensitive << true;
+ QTest::newRow("ARTHUR") << u"ARTHUR"_s << Qt::CaseInsensitive << true;
+ QTest::newRow("Hans") << u"Hans"_s << Qt::CaseSensitive << false;
+ QTest::newRow("hans") << u"hans"_s << Qt::CaseInsensitive << false;
+ QTest::newRow("dent") << u"dent"_s << Qt::CaseInsensitive << true;
+}
+
+void tst_QStringList::contains()
+{
+ QFETCH(QString, needle);
+ QFETCH(Qt::CaseSensitivity, cs);
+ QFETCH(bool, expected);
+
+ const QStringList list = {
+ u"arthur"_s, u"Arthur"_s, u"arthuR"_s, u"ARTHUR"_s, u"Dent"_s, u"Hans Dent"_s
+ };
+
+ QCOMPARE(list.contains(needle, cs), expected);
+ QCOMPARE(list.contains(QStringView(needle), cs), expected);
+ QCOMPARE(list.contains(QLatin1StringView(needle.toLatin1()), cs), expected);
+}
+
+void tst_QStringList::removeDuplicates_data()
+{
+ QTest::addColumn<QString>("before");
+ QTest::addColumn<QString>("after");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<bool>("detached");
+
+ QTest::newRow("empty-1") << "Hello,Hello" << "Hello" << 1 << true;
+ QTest::newRow("empty-2") << "Hello,World" << "Hello,World" << 0 << false;
+ QTest::newRow("middle") << "Hello,World,Hello" << "Hello,World" << 1 << true;
+}
+
+void tst_QStringList::removeDuplicates()
+{
+ QFETCH(QString, before);
+ QFETCH(QString, after);
+ QFETCH(int, count);
+ QFETCH(bool, detached);
+
+ QStringList lbefore = before.split(',');
+ const QStringList oldlbefore = lbefore;
+ QStringList lafter = after.split(',');
+ int removed = lbefore.removeDuplicates();
+
+ QCOMPARE(removed, count);
+ QCOMPARE(lbefore, lafter);
+ QCOMPARE(detached, !oldlbefore.isSharedWith(lbefore));
+}
+
+void tst_QStringList::streamingOperator()
+{
+ QStringList list;
+ list << "hei";
+ list << list << "hopp" << list;
+
+ QList<QString> slist = list;
+ list << slist;
+
+ QCOMPARE(list, QStringList()
+ << "hei" << "hei" << "hopp"
+ << "hei" << "hei" << "hopp"
+ << "hei" << "hei" << "hopp"
+ << "hei" << "hei" << "hopp");
+
+ QStringList list2;
+ list2 << "adam";
+
+ QStringList list3;
+ list3 << "eva";
+
+ QCOMPARE(list2 << list3, QStringList() << "adam" << "eva");
+}
+
+void tst_QStringList::assignmentOperator()
+{
+ // compile-only test
+
+ QStringList adam;
+ adam << "adam";
+ QList<QString> eva;
+ eva << "eva";
+ QStringList result;
+ QStringList &ref1 = (result = adam);
+ QStringList &ref2 = (result = eva);
+ Q_UNUSED(ref1);
+ Q_UNUSED(ref2);
+}
+
+void tst_QStringList::join() const
+{
+ QFETCH(QStringList, input);
+ QFETCH(QString, separator);
+ QFETCH(QString, expectedResult);
+
+ QCOMPARE(input.join(separator), expectedResult);
+ QCOMPARE(input.join(QLatin1String(separator.toLatin1())), expectedResult);
+ QCOMPARE(input.join(QStringView(separator)), expectedResult);
+}
+
+void tst_QStringList::join_data() const
+{
+ QTest::addColumn<QStringList>("input");
+ QTest::addColumn<QString>("separator");
+ QTest::addColumn<QString>("expectedResult");
+
+ QTest::newRow("data1")
+ << QStringList()
+ << QString()
+ << QString();
+
+ QTest::newRow("data2")
+ << QStringList()
+ << QString(QLatin1String("separator"))
+ << QString();
+
+ QTest::newRow("data3")
+ << QStringList("one")
+ << QString(QLatin1String("separator"))
+ << QString("one");
+
+ QTest::newRow("data4")
+ << QStringList("one")
+ << QString(QLatin1String("separator"))
+ << QString("one");
+
+
+ QTest::newRow("data5")
+ << (QStringList()
+ << QLatin1String("a")
+ << QLatin1String("b"))
+ << QString(QLatin1String(" "))
+ << QString("a b");
+
+ QTest::newRow("data6")
+ << (QStringList()
+ << QLatin1String("a")
+ << QLatin1String("b")
+ << QLatin1String("c"))
+ << QString(QLatin1String(" "))
+ << QString("a b c");
+}
+
+void tst_QStringList::joinChar() const
+{
+ QFETCH(QStringList, input);
+ QFETCH(QChar, separator);
+ QFETCH(QString, expectedResult);
+
+ QCOMPARE(input.join(separator), expectedResult);
+}
+
+void tst_QStringList::joinChar_data() const
+{
+ QTest::addColumn<QStringList>("input");
+ QTest::addColumn<QChar>("separator");
+ QTest::addColumn<QString>("expectedResult");
+
+ QTest::newRow("data1")
+ << QStringList()
+ << QChar(QLatin1Char(' '))
+ << QString();
+
+ QTest::newRow("data5")
+ << (QStringList()
+ << QLatin1String("a")
+ << QLatin1String("b"))
+ << QChar(QLatin1Char(' '))
+ << QString("a b");
+
+ QTest::newRow("data6")
+ << (QStringList()
+ << QLatin1String("a")
+ << QLatin1String("b")
+ << QLatin1String("c"))
+ << QChar(QLatin1Char(' '))
+ << QString("a b c");
+
+ QTest::newRow("null separator")
+ << QStringList{QStringLiteral("a"), QStringLiteral("b"), QStringLiteral("c")}
+ << QChar(u'\0')
+ << QStringLiteral("a\0b\0c");
+}
+
+void tst_QStringList::joinEmptiness() const
+{
+ QStringList list;
+ QString string = list.join(QString());
+
+ QVERIFY(string.isEmpty());
+ QVERIFY(string.isNull());
+}
+
+void tst_QStringList::initializeList() const
+{
+
+ QStringList v1{QLatin1String("hello"),"world",QString::fromLatin1("plop")};
+ QCOMPARE(v1, (QStringList() << "hello" << "world" << "plop"));
+ QCOMPARE(v1, (QStringList{"hello","world","plop"}));
+}
+
+QTEST_APPLESS_MAIN(tst_QStringList)
+#include "tst_qstringlist.moc"
diff --git a/tests/auto/corelib/tools/qstringmatcher/.gitignore b/tests/auto/corelib/text/qstringmatcher/.gitignore
index 3c7caf8490..3c7caf8490 100644
--- a/tests/auto/corelib/tools/qstringmatcher/.gitignore
+++ b/tests/auto/corelib/text/qstringmatcher/.gitignore
diff --git a/tests/auto/corelib/text/qstringmatcher/CMakeLists.txt b/tests/auto/corelib/text/qstringmatcher/CMakeLists.txt
new file mode 100644
index 0000000000..390aff1c53
--- /dev/null
+++ b/tests/auto/corelib/text/qstringmatcher/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringmatcher Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringmatcher LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringmatcher
+ SOURCES
+ tst_qstringmatcher.cpp
+ DEFINES
+ QT_NO_CAST_TO_ASCII
+)
diff --git a/tests/auto/corelib/text/qstringmatcher/tst_qstringmatcher.cpp b/tests/auto/corelib/text/qstringmatcher/tst_qstringmatcher.cpp
new file mode 100644
index 0000000000..c7f67f8541
--- /dev/null
+++ b/tests/auto/corelib/text/qstringmatcher/tst_qstringmatcher.cpp
@@ -0,0 +1,153 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qstringmatcher.h>
+
+class tst_QStringMatcher : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void qstringmatcher();
+ void caseSensitivity();
+ void indexIn_data();
+ void indexIn();
+ void setCaseSensitivity_data();
+ void setCaseSensitivity();
+ void assignOperator();
+};
+
+void tst_QStringMatcher::qstringmatcher()
+{
+ QStringMatcher matcher;
+ QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn("foo", 1), 1);
+ QCOMPARE(matcher.pattern(), QString());
+ QCOMPARE(matcher.patternView(), QStringView());
+}
+
+// public Qt::CaseSensitivity caseSensitivity() const
+void tst_QStringMatcher::caseSensitivity()
+{
+ const QString haystack = QStringLiteral("foobarFoo");
+ const QStringView needle = QStringView{ haystack }.right(3); // "Foo"
+ QStringMatcher matcher(needle.data(), needle.size());
+
+ QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack), 6);
+
+ matcher.setCaseSensitivity(Qt::CaseInsensitive);
+
+ QCOMPARE(matcher.caseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(matcher.indexIn(haystack), 0);
+
+ matcher.setCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack), 6);
+}
+
+void tst_QStringMatcher::indexIn_data()
+{
+ QTest::addColumn<QString>("needle");
+ QTest::addColumn<QString>("haystack");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("indexIn");
+ QTest::newRow("empty-1") << QString() << QString("foo") << 0 << 0;
+ QTest::newRow("empty-2") << QString() << QString("foo") << 10 << -1;
+ QTest::newRow("empty-3") << QString() << QString("foo") << -10 << 0;
+
+ QTest::newRow("simple-1") << QString("a") << QString("foo") << 0 << -1;
+ QTest::newRow("simple-2") << QString("a") << QString("bar") << 0 << 1;
+ QTest::newRow("harder-1") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 0 << 26;
+ QTest::newRow("harder-2") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 20 << 26;
+ QTest::newRow("harder-3") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 26 << 26;
+ QTest::newRow("harder-4") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 27 << -1;
+}
+
+void tst_QStringMatcher::indexIn()
+{
+ QFETCH(QString, needle);
+ QFETCH(QString, haystack);
+ QFETCH(int, from);
+ QFETCH(int, indexIn);
+
+ QStringMatcher matcher;
+ matcher.setPattern(needle);
+
+ QCOMPARE(matcher.indexIn(haystack, from), indexIn);
+
+ const auto needleSV = QStringView(needle);
+ QStringMatcher matcherSV(needleSV);
+
+ QCOMPARE(matcherSV.indexIn(QStringView(haystack), from), indexIn);
+}
+
+void tst_QStringMatcher::setCaseSensitivity_data()
+{
+ QTest::addColumn<QString>("needle");
+ QTest::addColumn<QString>("haystack");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("indexIn");
+ QTest::addColumn<int>("cs");
+
+ QTest::newRow("overshot") << QString("foo") << QString("baFooz foo bar") << 14 << -1 << (int) Qt::CaseSensitive;
+ QTest::newRow("sensitive") << QString("foo") << QString("baFooz foo bar") << 1 << 7 << (int) Qt::CaseSensitive;
+ QTest::newRow("insensitive-1")
+ << QString("foo") << QString("baFooz foo bar") << 0 << 2 << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-2")
+ << QString("foo") << QString("baFooz foo bar") << 1 << 2 << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-3")
+ << QString("foo") << QString("baFooz foo bar") << 4 << 7 << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-4")
+ << QString("foogabooga") << QString("baFooGaBooga foogabooga bar") << 1 << 2
+ << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-5")
+ << QString("foogabooga") << QString("baFooGaBooga foogabooga bar") << 3 << 13
+ << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-6") << QString("foogabooga") << QString("GaBoogaFoogaBooga bar") << 0
+ << 7 << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-7") << QString("foogabooga") << QString("FoGaBoogaFoogaBooga") << 9
+ << 9 << (int)Qt::CaseInsensitive;
+ QTest::newRow("insensitive-8") << QString("foogaBooga") << QString("zzzzaazzffoogaBooga") << 0
+ << 9 << (int)Qt::CaseInsensitive;
+ QString stringOf32("abcdefghijklmnopqrstuvwxyz123456");
+ Q_ASSERT(stringOf32.size() == 32);
+ QString stringOf128 = stringOf32 + stringOf32 + stringOf32 + stringOf32;
+ QString needle = stringOf128 + stringOf128 + "CAse";
+ QString haystack = stringOf128 + stringOf128 + "caSE";
+ QTest::newRow("insensitive-9") << needle << haystack << 0 << 0 << (int)Qt::CaseInsensitive;
+}
+
+void tst_QStringMatcher::setCaseSensitivity()
+{
+ QFETCH(QString, needle);
+ QFETCH(QString, haystack);
+ QFETCH(int, from);
+ QFETCH(int, indexIn);
+ QFETCH(int, cs);
+
+ QStringMatcher matcher;
+ matcher.setPattern(needle);
+ matcher.setCaseSensitivity(static_cast<Qt::CaseSensitivity> (cs));
+
+ QCOMPARE(matcher.indexIn(haystack, from), indexIn);
+ QCOMPARE(matcher.indexIn(QStringView(haystack), from), indexIn);
+}
+
+void tst_QStringMatcher::assignOperator()
+{
+ QString needle("d");
+ QString hayStack("abcdef");
+ QStringMatcher m1(needle);
+ QCOMPARE(m1.indexIn(hayStack), 3);
+
+ QStringMatcher m2 = m1;
+ QCOMPARE(m2.pattern(), needle);
+ QCOMPARE(m2.patternView(), needle);
+ QCOMPARE(m2.indexIn(hayStack), 3);
+}
+
+QTEST_MAIN(tst_QStringMatcher)
+#include "tst_qstringmatcher.moc"
+
diff --git a/tests/auto/corelib/text/qstringtokenizer/.gitignore b/tests/auto/corelib/text/qstringtokenizer/.gitignore
new file mode 100644
index 0000000000..5925520afd
--- /dev/null
+++ b/tests/auto/corelib/text/qstringtokenizer/.gitignore
@@ -0,0 +1 @@
+tst_qstringtokenizer
diff --git a/tests/auto/corelib/text/qstringtokenizer/CMakeLists.txt b/tests/auto/corelib/text/qstringtokenizer/CMakeLists.txt
new file mode 100644
index 0000000000..35fa2a31fd
--- /dev/null
+++ b/tests/auto/corelib/text/qstringtokenizer/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringtokenizer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringtokenizer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringtokenizer
+ SOURCES
+ tst_qstringtokenizer.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp b/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp
new file mode 100644
index 0000000000..0101c74a7b
--- /dev/null
+++ b/tests/auto/corelib/text/qstringtokenizer/tst_qstringtokenizer.cpp
@@ -0,0 +1,140 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QStringTokenizer>
+#include <QStringBuilder>
+
+#include <QTest>
+
+#include <string>
+
+Q_DECLARE_METATYPE(Qt::SplitBehavior)
+namespace {
+class tst_QStringTokenizer : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void constExpr() const;
+ void basics_data() const;
+ void basics() const;
+ void toContainer() const;
+};
+
+static QStringList skipped(const QStringList &sl)
+{
+ QStringList result;
+ result.reserve(sl.size());
+ for (const QString &s : sl) {
+ if (!s.isEmpty())
+ result.push_back(s);
+ }
+ return result;
+}
+
+QString toQString(QStringView str)
+{
+ return str.toString();
+}
+
+template <typename Container>
+QStringList toQStringList(const Container &c)
+{
+ QStringList r;
+ for (auto &&e : c)
+ r.push_back(toQString(e));
+ return r;
+}
+} // namespace
+
+void tst_QStringTokenizer::constExpr() const
+{
+ // compile-time checks
+ {
+ constexpr auto tok = qTokenize(u"a,b,c", u",");
+ Q_UNUSED(tok);
+ }
+ {
+ constexpr auto tok = qTokenize(u"a,b,c", u',');
+ Q_UNUSED(tok);
+ }
+}
+
+void tst_QStringTokenizer::basics_data() const
+{
+ QTest::addColumn<Qt::SplitBehavior>("sb");
+ QTest::addColumn<Qt::CaseSensitivity>("cs");
+
+#define ROW(sb, cs) \
+ do { QTest::addRow("%s/%s", #sb, #cs) << Qt::SplitBehavior{Qt::sb} << Qt::cs; } while (0)
+
+ ROW(KeepEmptyParts, CaseSensitive);
+ ROW(KeepEmptyParts, CaseInsensitive);
+ ROW(SkipEmptyParts, CaseSensitive);
+ ROW(SkipEmptyParts, CaseInsensitive);
+
+#undef ROW
+}
+
+void tst_QStringTokenizer::basics() const
+{
+ QFETCH(const Qt::SplitBehavior, sb);
+ QFETCH(const Qt::CaseSensitivity, cs);
+
+ auto expected = QStringList{"", "a", "b", "c", "d", "e", ""};
+ if (sb & Qt::SkipEmptyParts)
+ expected = skipped(expected);
+ QCOMPARE(toQStringList(qTokenize(u",a,b,c,d,e,", u',', sb, cs)), expected);
+ QCOMPARE(toQStringList(qTokenize(u",a,b,c,d,e,", u',', cs, sb)), expected);
+
+ {
+ auto tok = qTokenize(expected.join(u'x'), u"X" % QString(), Qt::CaseInsensitive);
+ // the temporary QStrings returned from join() and the QStringBuilder expression
+ // are now destroyed, but 'tok' should keep both alive
+ QCOMPARE(toQStringList(tok), expected);
+ }
+
+ using namespace std::string_literals;
+
+ {
+ auto tok = qTokenize(expected.join(u'x'), u"X"s, Qt::CaseInsensitive);
+ QCOMPARE(toQStringList(tok), expected);
+ }
+
+ {
+ auto tok = qTokenize(expected.join(u'x'), QLatin1Char('x'), cs, sb);
+ QCOMPARE(toQStringList(tok), expected);
+ }
+}
+
+void tst_QStringTokenizer::toContainer() const
+{
+ // QStringView value_type:
+ {
+ auto tok = qTokenize(u"a,b,c", u',');
+ auto v = tok.toContainer();
+ QVERIFY((std::is_same_v<decltype(v), QList<QStringView>>));
+ }
+ // QLatin1String value_type
+ {
+ auto tok = qTokenize(QLatin1String{"a,b,c"}, u',');
+ auto v = tok.toContainer();
+ QVERIFY((std::is_same_v<decltype(v), QList<QLatin1String>>));
+ }
+ // QLatin1String value_type into QStringList
+ {
+ auto tok = qTokenize(QLatin1String{"a,b,c"}, u',');
+ QStringList result;
+ tok.toContainer(result);
+ QCOMPARE(result, QStringList({"a", "b", "c"}));
+ }
+ // QLatin1String value_type into QStringList: rvalue overload
+ {
+ QStringList result;
+ qTokenize(QLatin1String{"a,b,c"}, u',').toContainer(result);
+ QCOMPARE(result, QStringList({"a", "b", "c"}));
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QStringTokenizer)
+#include "tst_qstringtokenizer.moc"
diff --git a/tests/auto/corelib/tools/qstringview/.gitignore b/tests/auto/corelib/text/qstringview/.gitignore
index 5f757d448a..5f757d448a 100644
--- a/tests/auto/corelib/tools/qstringview/.gitignore
+++ b/tests/auto/corelib/text/qstringview/.gitignore
diff --git a/tests/auto/corelib/text/qstringview/CMakeLists.txt b/tests/auto/corelib/text/qstringview/CMakeLists.txt
new file mode 100644
index 0000000000..ba5f540838
--- /dev/null
+++ b/tests/auto/corelib/text/qstringview/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstringview Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstringview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstringview
+ SOURCES
+ tst_qstringview.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp
new file mode 100644
index 0000000000..df3ef94371
--- /dev/null
+++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp
@@ -0,0 +1,914 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QStringView>
+#include <QStringTokenizer>
+#include <QString>
+#include <QChar>
+#include <QVarLengthArray>
+#include <QList>
+#if QT_CONFIG(cpp_winrt)
+# include <private/qt_winrtbase_p.h>
+#endif
+#include <private/qxmlstream_p.h>
+
+
+#include <QTest>
+
+#include <string>
+#include <string_view>
+#include <array>
+#include <vector>
+#include <algorithm>
+#include <memory>
+
+// for negative testing (can't convert from)
+#include <deque>
+#include <list>
+
+template <typename T>
+using CanConvert = std::is_convertible<T, QStringView>;
+
+static_assert(!CanConvert<QLatin1String>::value);
+static_assert(!CanConvert<const char*>::value);
+static_assert(!CanConvert<QByteArray>::value);
+
+// QStringView qchar_does_not_compile() { return QStringView(QChar('a')); }
+// QStringView qlatin1string_does_not_compile() { return QStringView(QLatin1String("a")); }
+// QStringView const_char_star_does_not_compile() { return QStringView("a"); }
+// QStringView qbytearray_does_not_compile() { return QStringView(QByteArray("a")); }
+
+//
+// QChar
+//
+
+static_assert(!CanConvert<QChar>::value);
+
+static_assert(CanConvert<QChar[123]>::value);
+
+static_assert(CanConvert< QString >::value);
+static_assert(CanConvert<const QString >::value);
+static_assert(CanConvert< QString&>::value);
+static_assert(CanConvert<const QString&>::value);
+
+//
+// ushort
+//
+
+static_assert(!CanConvert<ushort>::value);
+
+static_assert(CanConvert<ushort[123]>::value);
+
+static_assert(CanConvert< ushort*>::value);
+static_assert(CanConvert<const ushort*>::value);
+
+static_assert(CanConvert<QList<ushort>>::value);
+static_assert(CanConvert<QVarLengthArray<ushort>>::value);
+static_assert(CanConvert<std::vector<ushort>>::value);
+static_assert(CanConvert<std::array<ushort, 123>>::value);
+static_assert(!CanConvert<std::deque<ushort>>::value);
+static_assert(!CanConvert<std::list<ushort>>::value);
+
+//
+// char16_t
+//
+
+static_assert(!CanConvert<char16_t>::value);
+
+static_assert(CanConvert< char16_t*>::value);
+static_assert(CanConvert<const char16_t*>::value);
+
+static_assert(CanConvert< std::u16string >::value);
+static_assert(CanConvert<const std::u16string >::value);
+static_assert(CanConvert< std::u16string&>::value);
+static_assert(CanConvert<const std::u16string&>::value);
+
+static_assert(CanConvert< std::u16string_view >::value);
+static_assert(CanConvert<const std::u16string_view >::value);
+static_assert(CanConvert< std::u16string_view&>::value);
+static_assert(CanConvert<const std::u16string_view&>::value);
+
+static_assert(CanConvert<QList<char16_t>>::value);
+static_assert(CanConvert<QVarLengthArray<char16_t>>::value);
+static_assert(CanConvert<std::vector<char16_t>>::value);
+static_assert(CanConvert<std::array<char16_t, 123>>::value);
+static_assert(!CanConvert<std::deque<char16_t>>::value);
+static_assert(!CanConvert<std::list<char16_t>>::value);
+
+static_assert(CanConvert<QtPrivate::XmlStringRef>::value);
+
+//
+// wchar_t
+//
+
+constexpr bool CanConvertFromWCharT =
+#ifdef Q_OS_WIN
+ true
+#else
+ false
+#endif
+ ;
+
+static_assert(!CanConvert<wchar_t>::value);
+
+static_assert(CanConvert< wchar_t*>::value == CanConvertFromWCharT);
+static_assert(CanConvert<const wchar_t*>::value == CanConvertFromWCharT);
+
+static_assert(CanConvert< std::wstring >::value == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring >::value == CanConvertFromWCharT);
+static_assert(CanConvert< std::wstring&>::value == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring&>::value == CanConvertFromWCharT);
+
+static_assert(CanConvert< std::wstring_view >::value == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring_view >::value == CanConvertFromWCharT);
+static_assert(CanConvert< std::wstring_view&>::value == CanConvertFromWCharT);
+static_assert(CanConvert<const std::wstring_view&>::value == CanConvertFromWCharT);
+
+static_assert(CanConvert<QList<wchar_t>>::value == CanConvertFromWCharT);
+static_assert(CanConvert<QVarLengthArray<wchar_t>>::value == CanConvertFromWCharT);
+static_assert(CanConvert<std::vector<wchar_t>>::value == CanConvertFromWCharT);
+static_assert(CanConvert<std::array<wchar_t, 123>>::value == CanConvertFromWCharT);
+static_assert(!CanConvert<std::deque<wchar_t>>::value);
+static_assert(!CanConvert<std::list<wchar_t>>::value);
+
+#if QT_CONFIG(cpp_winrt)
+
+//
+// winrt::hstring (QTBUG-111886)
+//
+
+static_assert(CanConvert< winrt::hstring >::value);
+static_assert(CanConvert<const winrt::hstring >::value);
+static_assert(CanConvert< winrt::hstring&>::value);
+static_assert(CanConvert<const winrt::hstring&>::value);
+
+#endif // QT_CONFIG(cpp_winrt)
+
+class tst_QStringView : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void constExpr() const;
+ void basics() const;
+ void literals() const;
+ void fromArray() const;
+ void at() const;
+
+ void arg() const;
+
+ void fromQString() const;
+
+ void fromQCharStar() const
+ {
+ const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
+ fromLiteral(str);
+ }
+
+ void fromUShortStar() const
+ {
+ const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0' };
+ fromLiteral(str);
+ }
+
+ void fromChar16TStar() const
+ {
+ fromLiteral(u"Hello, World!");
+ }
+
+ void fromWCharTStar() const
+ {
+#ifdef Q_OS_WIN
+ fromLiteral(L"Hello, World!");
+#else
+ QSKIP("This is a Windows-only test");
+#endif
+ }
+
+ void fromQCharRange() const
+ {
+ const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
+ fromRange(std::begin(str), std::end(str));
+ }
+
+ void fromUShortRange() const
+ {
+ const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
+ fromRange(std::begin(str), std::end(str));
+ }
+
+ void fromChar16TRange() const
+ {
+ const char16_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
+ fromRange(std::begin(str), std::end(str));
+ }
+
+ void fromWCharTRange() const
+ {
+#ifdef Q_OS_WIN
+ const wchar_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
+ fromRange(std::begin(str), std::end(str));
+#else
+ QSKIP("This is a Windows-only test");
+#endif
+ }
+
+ // std::basic_string
+ void fromStdStringWCharT() const
+ {
+#ifdef Q_OS_WIN
+ fromStdString<wchar_t>();
+#else
+ QSKIP("This is a Windows-only test");
+#endif
+ }
+ void fromStdStringChar16T() const
+ {
+ fromStdString<char16_t>();
+ }
+
+ void fromUShortContainers() const
+ {
+ fromContainers<ushort>();
+ }
+
+ void fromQCharContainers() const
+ {
+ fromContainers<QChar>();
+ }
+
+ void fromChar16TContainers() const
+ {
+ fromContainers<char16_t>();
+ }
+
+ void fromWCharTContainers() const
+ {
+#ifdef Q_OS_WIN
+ fromContainers<wchar_t>();
+#else
+ QSKIP("This is a Windows-only test");
+#endif
+ }
+
+ void comparison();
+
+ void overloadResolution();
+
+ void tokenize_data() const;
+ void tokenize() const;
+
+ void std_stringview_conversion();
+
+private:
+ template <typename String>
+ void conversion_tests(String arg) const;
+ template <typename Char>
+ void fromLiteral(const Char *arg) const;
+ template <typename Char>
+ void fromRange(const Char *first, const Char *last) const;
+ template <typename Char, typename Container>
+ void fromContainer() const;
+ template <typename Char>
+ void fromContainers() const;
+ template <typename Char>
+ void fromStdString() const { fromContainer<Char, std::basic_string<Char> >(); }
+};
+
+void tst_QStringView::constExpr() const
+{
+ // compile-time checks
+ {
+ constexpr QStringView sv;
+ static_assert(sv.size() == 0);
+ static_assert(sv.isNull());
+ static_assert(sv.empty());
+ static_assert(sv.isEmpty());
+ static_assert(sv.utf16() == nullptr);
+
+ constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
+ static_assert(sv2.isNull());
+ static_assert(sv2.empty());
+ }
+ {
+ constexpr QStringView sv = nullptr;
+ Q_STATIC_ASSERT(sv.size() == 0);
+ Q_STATIC_ASSERT(sv.isNull());
+ Q_STATIC_ASSERT(sv.empty());
+ Q_STATIC_ASSERT(sv.isEmpty());
+ Q_STATIC_ASSERT(sv.utf16() == nullptr);
+ }
+ {
+ constexpr QStringView sv = u"";
+ static_assert(sv.size() == 0);
+ static_assert(!sv.isNull());
+ static_assert(sv.empty());
+ static_assert(sv.isEmpty());
+ static_assert(sv.utf16() != nullptr);
+
+ constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
+ static_assert(!sv2.isNull());
+ static_assert(sv2.empty());
+ }
+ {
+ constexpr QStringView sv = u"Hello";
+ static_assert(sv.size() == 5);
+ static_assert(!sv.empty());
+ static_assert(!sv.isEmpty());
+ static_assert(!sv.isNull());
+ static_assert(*sv.utf16() == 'H');
+ static_assert(sv[0] == QLatin1Char('H'));
+ static_assert(sv.at(0) == QLatin1Char('H'));
+ static_assert(sv.front() == QLatin1Char('H'));
+ static_assert(sv.first() == QLatin1Char('H'));
+ static_assert(sv[4] == QLatin1Char('o'));
+ static_assert(sv.at(4) == QLatin1Char('o'));
+ static_assert(sv.back() == QLatin1Char('o'));
+ static_assert(sv.last() == QLatin1Char('o'));
+
+ constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
+ static_assert(!sv2.isNull());
+ static_assert(!sv2.empty());
+ static_assert(sv2.size() == 5);
+ }
+ {
+ static_assert(QStringView(u"Hello").size() == 5);
+ constexpr QStringView sv = u"Hello";
+ static_assert(sv.size() == 5);
+ static_assert(!sv.empty());
+ static_assert(!sv.isEmpty());
+ static_assert(!sv.isNull());
+ static_assert(*sv.utf16() == 'H');
+ static_assert(sv[0] == QLatin1Char('H'));
+ static_assert(sv.at(0) == QLatin1Char('H'));
+ static_assert(sv.front() == QLatin1Char('H'));
+ static_assert(sv.first() == QLatin1Char('H'));
+ static_assert(sv[4] == QLatin1Char('o'));
+ static_assert(sv.at(4) == QLatin1Char('o'));
+ static_assert(sv.back() == QLatin1Char('o'));
+ static_assert(sv.last() == QLatin1Char('o'));
+
+ constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
+ static_assert(!sv2.isNull());
+ static_assert(!sv2.empty());
+ static_assert(sv2.size() == 5);
+
+ constexpr char16_t *null = nullptr;
+ constexpr QStringView sv3(null);
+ static_assert(sv3.isNull());
+ static_assert(sv3.isEmpty());
+ static_assert(sv3.size() == 0);
+ }
+}
+
+void tst_QStringView::basics() const
+{
+ QStringView sv1;
+
+ // a default-constructed QStringView is null:
+ QVERIFY(sv1.isNull());
+ // which implies it's empty();
+ QVERIFY(sv1.isEmpty());
+
+ QStringView sv2;
+
+ QVERIFY(sv2 == sv1);
+ QVERIFY(!(sv2 != sv1));
+}
+
+void tst_QStringView::literals() const
+{
+ const char16_t hello[] = u"Hello";
+ const char16_t longhello[] =
+ u"Hello World. This is a much longer message, to exercise qustrlen.";
+ const char16_t withnull[] = u"a\0zzz";
+ static_assert(sizeof(longhello) >= 16);
+
+ QCOMPARE(QStringView(hello).size(), 5);
+ QCOMPARE(QStringView(hello + 0).size(), 5); // forces decay to pointer
+ QStringView sv = hello;
+ QCOMPARE(sv.size(), 5);
+ QVERIFY(!sv.empty());
+ QVERIFY(!sv.isEmpty());
+ QVERIFY(!sv.isNull());
+ QCOMPARE(*sv.utf16(), 'H');
+ QCOMPARE(sv[0], QLatin1Char('H'));
+ QCOMPARE(sv.at(0), QLatin1Char('H'));
+ QCOMPARE(sv.front(), QLatin1Char('H'));
+ QCOMPARE(sv.first(), QLatin1Char('H'));
+ QCOMPARE(sv[4], QLatin1Char('o'));
+ QCOMPARE(sv.at(4), QLatin1Char('o'));
+ QCOMPARE(sv.back(), QLatin1Char('o'));
+ QCOMPARE(sv.last(), QLatin1Char('o'));
+
+ QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
+ QVERIFY(!sv2.isNull());
+ QVERIFY(!sv2.empty());
+ QCOMPARE(sv2.size(), 5);
+
+ QStringView sv3(longhello);
+ QCOMPARE(size_t(sv3.size()), sizeof(longhello)/sizeof(longhello[0]) - 1);
+ QCOMPARE(sv3.last(), QLatin1Char('.'));
+ sv3 = longhello;
+ QCOMPARE(size_t(sv3.size()), sizeof(longhello)/sizeof(longhello[0]) - 1);
+
+ for (int i = 0; i < sv3.size(); ++i) {
+ QStringView sv4(longhello + i);
+ QCOMPARE(size_t(sv4.size()), sizeof(longhello)/sizeof(longhello[0]) - 1 - i);
+ QCOMPARE(sv4.last(), QLatin1Char('.'));
+ sv4 = longhello + i;
+ QCOMPARE(size_t(sv4.size()), sizeof(longhello)/sizeof(longhello[0]) - 1 - i);
+ }
+
+ // these are different results
+ QCOMPARE(size_t(QStringView(withnull).size()), size_t(1));
+ QCOMPARE(size_t(QStringView::fromArray(withnull).size()), sizeof(withnull)/sizeof(withnull[0]));
+ QCOMPARE(QStringView(withnull + 0).size(), qsizetype(1));
+}
+
+void tst_QStringView::fromArray() const
+{
+ static constexpr char16_t hello[] = u"Hello\0abc\0\0.";
+
+ constexpr QStringView sv = QStringView::fromArray(hello);
+ QCOMPARE(sv.size(), 13);
+ QVERIFY(!sv.empty());
+ QVERIFY(!sv.isEmpty());
+ QVERIFY(!sv.isNull());
+ QCOMPARE(*sv.data(), 'H');
+ QCOMPARE(sv[0], 'H');
+ QCOMPARE(sv.at(0), 'H');
+ QCOMPARE(sv.front(), 'H');
+ QCOMPARE(sv.first(), 'H');
+ QCOMPARE(sv[4], 'o');
+ QCOMPARE(sv.at(4), 'o');
+ QCOMPARE(sv[5], '\0');
+ QCOMPARE(sv.at(5), '\0');
+ QCOMPARE(*(sv.data() + sv.size() - 2), '.');
+ QCOMPARE(sv.back(), '\0');
+ QCOMPARE(sv.last(), '\0');
+
+ const char16_t bytes[] = {u'a', u'b', u'c'};
+ QStringView sv2 = QStringView::fromArray(bytes);
+ QCOMPARE(sv2.data(), reinterpret_cast<const QChar *>(bytes + 0));
+ QCOMPARE(sv2.size(), 3);
+ QCOMPARE(sv2.first(), u'a');
+ QCOMPARE(sv2.last(), u'c');
+}
+
+void tst_QStringView::at() const
+{
+ QString hello("Hello");
+ QStringView sv(hello);
+ QCOMPARE(sv.at(0), QChar('H')); QCOMPARE(sv[0], QChar('H'));
+ QCOMPARE(sv.at(1), QChar('e')); QCOMPARE(sv[1], QChar('e'));
+ QCOMPARE(sv.at(2), QChar('l')); QCOMPARE(sv[2], QChar('l'));
+ QCOMPARE(sv.at(3), QChar('l')); QCOMPARE(sv[3], QChar('l'));
+ QCOMPARE(sv.at(4), QChar('o')); QCOMPARE(sv[4], QChar('o'));
+}
+
+void tst_QStringView::arg() const
+{
+ // nullness checks
+ QCOMPARE(QStringView().arg(QStringView()), "");
+ QCOMPARE(QStringView(u"%1").arg(QStringView()), "");
+
+#define CHECK1(pattern, arg1, expected) \
+ do { \
+ auto p = QStringView(u"" pattern); \
+ QCOMPARE(p.arg(QLatin1String(arg1)), expected); \
+ QCOMPARE(p.arg(u"" arg1), expected); \
+ QCOMPARE(p.arg(QStringLiteral(arg1)), expected); \
+ QCOMPARE(p.arg(QString(QLatin1String(arg1))), expected); \
+ } while (false) \
+ /*end*/
+#define CHECK2(pattern, arg1, arg2, expected) \
+ do { \
+ auto p = QStringView(u"" pattern); \
+ QCOMPARE(p.arg(QLatin1String(arg1), QLatin1String(arg2)), expected); \
+ QCOMPARE(p.arg(u"" arg1, QLatin1String(arg2)), expected); \
+ QCOMPARE(p.arg(QLatin1String(arg1), u"" arg2), expected); \
+ QCOMPARE(p.arg(u"" arg1, u"" arg2), expected); \
+ } while (false) \
+ /*end*/
+
+ CHECK1("", "World", "");
+ CHECK1("%1", "World", "World");
+ CHECK1("!%1?", "World", "!World?");
+ CHECK1("%1%1", "World", "WorldWorld");
+ CHECK1("%1%2", "World", "World%2");
+ CHECK1("%2%1", "World", "%2World");
+
+ CHECK2("", "Hello", "World", "");
+ CHECK2("%1", "Hello", "World", "Hello");
+ CHECK2("!%1, %2?", "Hello", "World", "!Hello, World?");
+ CHECK2("%1%1", "Hello", "World", "HelloHello");
+ CHECK2("%1%2", "Hello", "World", "HelloWorld");
+ CHECK2("%2%1", "Hello", "World", "WorldHello");
+
+#undef CHECK2
+#undef CHECK1
+
+ QCOMPARE(QStringView(u" %2 %2 %1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), " \r \r c C ");
+}
+
+void tst_QStringView::fromQString() const
+{
+ QString null;
+ QString empty = "";
+
+ QVERIFY( QStringView(null).isNull());
+ QVERIFY( QStringView(null).isEmpty());
+ QVERIFY( QStringView(empty).isEmpty());
+ QVERIFY(!QStringView(empty).isNull());
+
+ conversion_tests(QString("Hello World!"));
+}
+
+void tst_QStringView::tokenize_data() const
+{
+ // copied from tst_QString
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<QString>("sep");
+ QTest::addColumn<QStringList>("result");
+
+ QTest::newRow("1") << "a,b,c" << "," << (QStringList() << "a" << "b" << "c");
+ QTest::newRow("2") << QString("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile")
+ << " "
+ << (QStringList() << "-rw-r--r--" << "" << "1" << "0" << "" << "0" << ""
+ << "519240" << "Jul" << "" << "9" << "" << "2002"
+ << "bigfile");
+ QTest::newRow("one-empty") << "" << " " << (QStringList() << "");
+ QTest::newRow("two-empty") << " " << " " << (QStringList() << "" << "");
+ QTest::newRow("three-empty") << " " << " " << (QStringList() << "" << "" << "");
+
+ QTest::newRow("all-empty") << "" << "" << (QStringList() << "" << "");
+ QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
+}
+
+void tst_QStringView::tokenize() const
+{
+ QFETCH(const QString, str);
+ QFETCH(const QString, sep);
+ QFETCH(const QStringList, result);
+
+ // lvalue QString
+ {
+ auto rit = result.cbegin();
+ for (auto sv : QStringTokenizer{str, sep})
+ QCOMPARE(sv, *rit++);
+ }
+ {
+ auto rit = result.cbegin();
+ for (auto sv : QStringView{str}.tokenize(sep))
+ QCOMPARE(sv, *rit++);
+ }
+
+ // rvalue QString
+ {
+ auto rit = result.cbegin();
+ for (auto sv : QStringTokenizer{str, QString{sep}})
+ QCOMPARE(sv, *rit++);
+ }
+ {
+ auto rit = result.cbegin();
+ for (auto sv : QStringView{str}.tokenize(QString{sep}))
+ QCOMPARE(sv, *rit++);
+ }
+
+ // (rvalue) QChar
+ if (sep.size() == 1) {
+ auto rit = result.cbegin();
+ for (auto sv : QStringTokenizer{str, sep.front()})
+ QCOMPARE(sv, *rit++);
+ }
+ if (sep.size() == 1) {
+ auto rit = result.cbegin();
+ for (auto sv : QStringView{str}.tokenize(sep.front()))
+ QCOMPARE(sv, *rit++);
+ }
+
+ // (rvalue) char16_t
+ if (sep.size() == 1) {
+ auto rit = result.cbegin();
+ for (auto sv : QStringTokenizer{str, *qToStringViewIgnoringNull(sep).utf16()})
+ QCOMPARE(sv, *rit++);
+ }
+ if (sep.size() == 1) {
+ auto rit = result.cbegin();
+ for (auto sv : QStringView{str}.tokenize(*qToStringViewIgnoringNull(sep).utf16()))
+ QCOMPARE(sv, *rit++);
+ }
+
+ // char16_t literal
+ const auto make_literal = [](const QString &sep) {
+ auto literal = std::make_unique<char16_t[]>(sep.size() + 1);
+ const auto to_char16_t = [](QChar c) { return char16_t{c.unicode()}; };
+ std::transform(sep.cbegin(), sep.cend(), literal.get(), to_char16_t);
+ return literal;
+ };
+ const std::unique_ptr<const char16_t[]> literal = make_literal(sep);
+ {
+ auto rit = result.cbegin();
+ for (auto sv : QStringTokenizer{str, literal.get()})
+ QCOMPARE(sv, *rit++);
+ }
+ {
+ auto rit = result.cbegin();
+ for (auto sv : QStringView{str}.tokenize(literal.get()))
+ QCOMPARE(sv, *rit++);
+ }
+
+#ifdef __cpp_lib_ranges
+ // lvalue QString
+ {
+ QStringList actual;
+ const QStringTokenizer tok{str, sep};
+ std::ranges::transform(tok, std::back_inserter(actual),
+ [](auto sv) { return sv.toString(); });
+ QCOMPARE(result, actual);
+ }
+
+ // rvalue QString
+ {
+ QStringList actual;
+ const QStringTokenizer tok{str, QString{sep}};
+ std::ranges::transform(tok, std::back_inserter(actual),
+ [](auto sv) { return sv.toString(); });
+ QCOMPARE(result, actual);
+ }
+
+ // (rvalue) QChar
+ if (sep.size() == 1) {
+ QStringList actual;
+ const QStringTokenizer tok{str, sep.front()};
+ std::ranges::transform(tok, std::back_inserter(actual),
+ [](auto sv) { return sv.toString(); });
+ QCOMPARE(result, actual);
+ }
+#endif // __cpp_lib_ranges
+}
+
+template <typename Char>
+void tst_QStringView::fromLiteral(const Char *arg) const
+{
+ const Char *null = nullptr;
+ const Char empty[] = { Char{} };
+
+ QCOMPARE(QStringView(null).size(), qsizetype(0));
+ QCOMPARE(QStringView(null).data(), nullptr);
+ QCOMPARE(QStringView(empty).size(), qsizetype(0));
+ QCOMPARE(static_cast<const void*>(QStringView(empty).data()),
+ static_cast<const void*>(empty));
+
+ QVERIFY( QStringView(null).isNull());
+ QVERIFY( QStringView(null).isEmpty());
+ QVERIFY( QStringView(empty).isEmpty());
+ QVERIFY(!QStringView(empty).isNull());
+
+ conversion_tests(arg);
+}
+
+template <typename Char>
+void tst_QStringView::fromRange(const Char *first, const Char *last) const
+{
+ const Char *null = nullptr;
+ QCOMPARE(QStringView(null, null).size(), 0);
+ QCOMPARE(QStringView(null, null).data(), nullptr);
+ QCOMPARE(QStringView(first, first).size(), 0);
+ QCOMPARE(static_cast<const void*>(QStringView(first, first).data()),
+ static_cast<const void*>(first));
+
+ const auto sv = QStringView(first, last);
+ QCOMPARE(sv.size(), last - first);
+ QCOMPARE(static_cast<const void*>(sv.data()),
+ static_cast<const void*>(first));
+
+ // can't call conversion_tests() here, as it requires a single object
+}
+
+template <typename Char, typename Container>
+void tst_QStringView::fromContainer() const
+{
+ const QString s = "Hello World!";
+
+ Container c;
+ // unspecified whether empty containers make null QStringViews
+ QVERIFY(QStringView(c).isEmpty());
+
+ QCOMPARE(sizeof(Char), sizeof(QChar));
+
+ const auto *data = reinterpret_cast<const Char *>(s.utf16());
+ std::copy(data, data + s.size(), std::back_inserter(c));
+ conversion_tests(std::move(c));
+}
+
+template <typename Char>
+void tst_QStringView::fromContainers() const
+{
+ fromContainer<Char, QList<Char>>();
+ fromContainer<Char, QVarLengthArray<Char>>();
+ fromContainer<Char, std::vector<Char>>();
+}
+
+namespace help {
+template <typename T>
+size_t size(const T &t) { return size_t(t.size()); }
+template <typename T>
+size_t size(const T *t)
+{
+ size_t result = 0;
+ if (t) {
+ while (*t++)
+ ++result;
+ }
+ return result;
+}
+size_t size(const QChar *t)
+{
+ size_t result = 0;
+ if (t) {
+ while (!t++->isNull())
+ ++result;
+ }
+ return result;
+}
+
+template <typename T>
+decltype(auto) cbegin(const T &t) { return t.begin(); }
+template <typename T>
+const T * cbegin(const T *t) { return t; }
+
+template <typename T>
+decltype(auto) cend(const T &t) { return t.end(); }
+template <typename T>
+const T * cend(const T *t) { return t + size(t); }
+
+template <typename T>
+decltype(auto) crbegin(const T &t) { return t.rbegin(); }
+template <typename T>
+std::reverse_iterator<const T*> crbegin(const T *t) { return std::reverse_iterator<const T*>(cend(t)); }
+
+template <typename T>
+decltype(auto) crend(const T &t) { return t.rend(); }
+template <typename T>
+std::reverse_iterator<const T*> crend(const T *t) { return std::reverse_iterator<const T*>(cbegin(t)); }
+
+} // namespace help
+
+template <typename String>
+void tst_QStringView::conversion_tests(String string) const
+{
+ // copy-construct:
+ {
+ QStringView sv = string;
+
+ QCOMPARE(help::size(sv), help::size(string));
+
+ // check iterators:
+
+ QVERIFY(std::equal(help::cbegin(string), help::cend(string),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(sv.cbegin(), sv.size())));
+ QVERIFY(std::equal(help::cbegin(string), help::cend(string),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(sv.begin(), sv.size())));
+ QVERIFY(std::equal(help::crbegin(string), help::crend(string),
+ sv.crbegin()));
+ QVERIFY(std::equal(help::crbegin(string), help::crend(string),
+ sv.rbegin()));
+
+ QCOMPARE(sv, string);
+ }
+
+ QStringView sv;
+
+ // copy-assign:
+ {
+ sv = string;
+
+ QCOMPARE(help::size(sv), help::size(string));
+
+ // check relational operators:
+
+ QCOMPARE(sv, string);
+ QCOMPARE(string, sv);
+
+ QVERIFY(!(sv != string));
+ QVERIFY(!(string != sv));
+
+ QVERIFY(!(sv < string));
+ QVERIFY(sv <= string);
+ QVERIFY(!(sv > string));
+ QVERIFY(sv >= string);
+
+ QVERIFY(!(string < sv));
+ QVERIFY(string <= sv);
+ QVERIFY(!(string > sv));
+ QVERIFY(string >= sv);
+ }
+
+ // copy-construct from rvalue (QStringView never assumes ownership):
+ {
+ QStringView sv2 = std::move(string);
+ QCOMPARE(sv2, sv);
+ QCOMPARE(sv2, string);
+ }
+
+ // copy-assign from rvalue (QStringView never assumes ownership):
+ {
+ QStringView sv2;
+ sv2 = std::move(string);
+ QCOMPARE(sv2, sv);
+ QCOMPARE(sv2, string);
+ }
+}
+
+void tst_QStringView::comparison()
+{
+ const QStringView aa = u"aa";
+ const QStringView upperAa = u"AA";
+ const QStringView bb = u"bb";
+
+ QVERIFY(aa == aa);
+ QVERIFY(aa != bb);
+ QVERIFY(aa < bb);
+ QVERIFY(bb > aa);
+
+ QCOMPARE(aa.compare(aa), 0);
+ QVERIFY(aa.compare(upperAa) != 0);
+ QCOMPARE(aa.compare(upperAa, Qt::CaseInsensitive), 0);
+ QVERIFY(aa.compare(bb) < 0);
+ QVERIFY(bb.compare(aa) > 0);
+}
+
+namespace QStringViewOverloadResolution {
+static void test(QString) = delete;
+static void test(QStringView) {}
+}
+
+// Compile-time only test: overload resolution prefers QStringView over QString
+void tst_QStringView::overloadResolution()
+{
+ {
+ QChar qcharArray[42] = {};
+ QStringViewOverloadResolution::test(qcharArray);
+ QChar *qcharPointer = qcharArray;
+ QStringViewOverloadResolution::test(qcharPointer);
+ }
+
+ {
+ ushort ushortArray[42] = {};
+ QStringViewOverloadResolution::test(ushortArray);
+ ushort *ushortPointer = ushortArray;
+ QStringViewOverloadResolution::test(ushortPointer);
+ }
+
+#if defined(Q_OS_WIN)
+ {
+ wchar_t wchartArray[42] = {};
+ QStringViewOverloadResolution::test(wchartArray);
+ QStringViewOverloadResolution::test(L"test");
+ }
+#endif
+
+ {
+ char16_t char16Array[] = u"test";
+ QStringViewOverloadResolution::test(char16Array);
+ char16_t *char16Pointer = char16Array;
+ QStringViewOverloadResolution::test(char16Pointer);
+ }
+
+ {
+ std::u16string string;
+ QStringViewOverloadResolution::test(string);
+ QStringViewOverloadResolution::test(std::as_const(string));
+ QStringViewOverloadResolution::test(std::move(string));
+ }
+}
+
+void tst_QStringView::std_stringview_conversion()
+{
+ static_assert(std::is_convertible_v<QStringView, std::u16string_view>);
+
+ QStringView s;
+ std::u16string_view sv(s);
+ QCOMPARE(sv, std::u16string_view());
+
+ s = u"";
+ sv = s;
+ QCOMPARE(s.size(), 0);
+ QCOMPARE(sv.size(), size_t(0));
+ QCOMPARE(sv, std::u16string_view());
+
+ s = u"Hello";
+ sv = s;
+ QCOMPARE(sv, std::u16string_view(u"Hello"));
+
+ s = QStringView::fromArray(u"Hello\0world");
+ sv = s;
+ QCOMPARE(s.size(), 12);
+ QCOMPARE(sv.size(), size_t(12));
+ QCOMPARE(sv, std::u16string_view(u"Hello\0world\0", 12));
+}
+
+QTEST_APPLESS_MAIN(tst_QStringView)
+#include "tst_qstringview.moc"
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/.gitignore b/tests/auto/corelib/text/qtextboundaryfinder/.gitignore
index bd0df58233..bd0df58233 100644
--- a/tests/auto/corelib/tools/qtextboundaryfinder/.gitignore
+++ b/tests/auto/corelib/text/qtextboundaryfinder/.gitignore
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/CMakeLists.txt b/tests/auto/corelib/text/qtextboundaryfinder/CMakeLists.txt
new file mode 100644
index 0000000000..17e8583aab
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtextboundaryfinder Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtextboundaryfinder LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+file(GLOB_RECURSE test_data
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*
+)
+
+qt_internal_add_test(tst_qtextboundaryfinder
+ SOURCES
+ tst_qtextboundaryfinder.cpp
+ TESTDATA ${test_data}
+)
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/data/GraphemeBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/GraphemeBreakTest.txt
new file mode 100644
index 0000000000..4c1ed512e4
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/data/GraphemeBreakTest.txt
@@ -0,0 +1,1215 @@
+# GraphemeBreakTest-15.1.0.txt
+# Date: 2023-08-07, 15:52:55 GMT
+# © 2023 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see https://www.unicode.org/reports/tr44/
+#
+# Default Grapheme_Cluster_Break Test
+#
+# Format:
+# <string> (# <comment>)?
+# <string> contains hex Unicode code points, with
+# ÷ wherever there is a break opportunity, and
+# × wherever there is not.
+# <comment> the format can change, but currently it shows:
+# - the sample character name
+# - (x) the Grapheme_Cluster_Break property value for the sample character
+# - [x] the rule that determines whether there is a break or not,
+# as listed in the Rules section of GraphemeBreakTest.html
+#
+# These samples may be extended or changed in the future.
+#
+÷ 0020 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0020 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0020 × 0308 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0020 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0020 × 0A03 ÷ # ÷ [0.2] SPACE (Other) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0020 × 0308 × 0A03 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0020 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0020 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0020 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0020 × 0308 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0020 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0020 × 0308 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0020 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0020 × 0308 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0020 × 0900 ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 × 0308 × 0900 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 × 0308 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 ÷ 0904 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0904 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 ÷ 0D4E ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0D4E ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0020 ÷ 0915 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0915 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0020 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0020 × 0308 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 093C ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 0308 × 093C ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 094D ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 0308 × 094D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0020 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000D ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000D ÷ 034F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 000D ÷ 0308 × 034F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000D ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000D ÷ 0A03 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000D ÷ 0308 × 0A03 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000D ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000D ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000D ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000D ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000D ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000D ÷ 0900 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0308 × 0900 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0308 × 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0904 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0904 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0D4E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0D4E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000D ÷ 0915 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0915 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 000D ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 093C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 0308 × 093C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 094D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 0308 × 094D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 000D ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000A ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 000A ÷ 034F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 000A ÷ 0308 × 034F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000A ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 000A ÷ 0A03 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000A ÷ 0308 × 0A03 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 000A ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 000A ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 000A ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 000A ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 000A ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 000A ÷ 0900 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0308 × 0900 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0308 × 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0904 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0904 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0D4E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0D4E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 000A ÷ 0915 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0915 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 000A ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 093C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 0308 × 093C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 094D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 0308 × 094D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 000A ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0001 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0001 ÷ 034F ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0001 ÷ 0308 × 034F ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0001 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0001 ÷ 0A03 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0001 ÷ 0308 × 0A03 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0001 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0001 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0001 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0001 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0001 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0001 ÷ 0900 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0308 × 0900 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0308 × 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0904 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0904 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0D4E ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0D4E ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0001 ÷ 0915 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0915 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0001 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0001 ÷ 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 093C ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 0308 × 093C ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 094D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 0308 × 094D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0001 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 034F ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 034F × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 034F ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 034F × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 034F ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 034F × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 034F ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 034F × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 034F × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 034F × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 034F ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 034F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 034F ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 034F × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 034F × 0A03 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 034F × 0308 × 0A03 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 034F ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 034F × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 034F ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 034F × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 034F ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 034F × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 034F ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 034F × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 034F ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 034F × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 034F × 0900 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F × 0308 × 0900 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F × 0308 ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F ÷ 0D4E ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F × 0308 ÷ 0D4E ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 034F ÷ 0915 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 034F × 0308 ÷ 0915 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 034F ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 034F × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 034F × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 034F × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 034F × 093C ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 034F × 0308 × 093C ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 034F × 094D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 034F × 0308 × 094D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 034F × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 034F × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 034F ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 034F × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1F1E6 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 1F1E6 × 0308 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F1E6 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1F1E6 × 0A03 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0A03 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1F1E6 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F1E6 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1F1E6 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1F1E6 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1F1E6 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1F1E6 × 0900 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0900 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 ÷ 0904 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0904 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 ÷ 0D4E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0D4E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1F1E6 ÷ 0915 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0915 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 1F1E6 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 093C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 0308 × 093C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 094D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 0308 × 094D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 1F1E6 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0600 × 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] SPACE (Other) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0600 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0600 × 0308 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0600 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0600 × 0308 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0600 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0600 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0600 × 0308 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0600 × 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0600 × 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0600 × 0A03 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0600 × 0308 × 0A03 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0600 × 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0600 × 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0600 × 0308 ÷ 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0600 × 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0600 × 0308 ÷ 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0600 × AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0600 × 0308 ÷ AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0600 × AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0600 × 0308 ÷ AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0600 × 0900 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0308 × 0900 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0308 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0904 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0904 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0D4E ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0D4E ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0600 × 0915 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0915 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0600 × 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] WATCH (ExtPict) ÷ [0.3]
+÷ 0600 × 0308 ÷ 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0600 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 0308 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 093C ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 0308 × 093C ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 094D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 0308 × 094D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 0308 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0600 × 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] <reserved-0378> (Other) ÷ [0.3]
+÷ 0600 × 0308 ÷ 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0A03 ÷ 0020 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0020 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0A03 ÷ 000D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 000D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0A03 ÷ 000A ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 000A ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0A03 ÷ 0001 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0001 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0A03 × 034F ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0A03 × 0308 × 034F ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0A03 ÷ 1F1E6 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0A03 ÷ 0600 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0600 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0A03 × 0A03 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0A03 × 0308 × 0A03 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0A03 ÷ 1100 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 1100 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0A03 ÷ 1160 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 1160 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0A03 ÷ 11A8 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 11A8 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0A03 ÷ AC00 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0A03 × 0308 ÷ AC00 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0A03 ÷ AC01 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0A03 × 0308 ÷ AC01 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0A03 × 0900 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 × 0308 × 0900 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 × 0903 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 × 0308 × 0903 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 ÷ 0904 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0904 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 ÷ 0D4E ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0D4E ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0A03 ÷ 0915 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0915 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0A03 ÷ 231A ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 231A ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0A03 × 0300 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 0308 × 0300 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 093C ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 0308 × 093C ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 094D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 0308 × 094D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 200D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0A03 × 0308 × 200D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0A03 ÷ 0378 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0A03 × 0308 ÷ 0378 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1100 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1100 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1100 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1100 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1100 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1100 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1100 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 1100 × 0308 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 1100 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1100 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1100 × 0A03 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1100 × 0308 × 0A03 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1100 × 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1100 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1100 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1100 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1100 × AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1100 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1100 × AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1100 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1100 × 0900 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 ÷ 0904 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0904 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 ÷ 0D4E ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0D4E ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1100 ÷ 0915 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0915 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 1100 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1100 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1100 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 093C ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 0308 × 093C ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 094D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 0308 × 094D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 1100 × 0308 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 1100 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1100 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1160 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1160 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1160 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1160 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1160 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1160 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 1160 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 1160 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 1160 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1160 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 1160 × 0A03 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1160 × 0308 × 0A03 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 1160 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1160 × 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1160 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 1160 × 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1160 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 1160 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1160 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 1160 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1160 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 1160 × 0900 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 ÷ 0904 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0904 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 ÷ 0D4E ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0D4E ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 1160 ÷ 0915 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0915 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 1160 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1160 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1160 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 093C ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 0308 × 093C ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 094D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 0308 × 094D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 1160 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 1160 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 1160 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 11A8 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 11A8 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 11A8 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 11A8 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 11A8 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 11A8 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 11A8 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 11A8 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 11A8 × 0A03 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 11A8 × 0308 × 0A03 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 11A8 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 11A8 × 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 11A8 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 11A8 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 11A8 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 11A8 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 11A8 × 0900 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 ÷ 0904 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0904 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 ÷ 0D4E ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0D4E ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 11A8 ÷ 0915 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0915 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 11A8 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 11A8 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 093C ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 0308 × 093C ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 094D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 0308 × 094D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 11A8 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 11A8 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 11A8 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC00 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC00 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC00 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC00 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC00 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC00 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC00 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ AC00 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ AC00 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC00 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC00 × 0A03 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC00 × 0308 × 0A03 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC00 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC00 × 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC00 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC00 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC00 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC00 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC00 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC00 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC00 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC00 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 ÷ 0904 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0904 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 ÷ 0D4E ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0D4E ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC00 ÷ 0915 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0915 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ AC00 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ AC00 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ AC00 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 0308 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 0308 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ AC00 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ AC00 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC00 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC01 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ AC01 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC01 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ AC01 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC01 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ AC01 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ AC01 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ AC01 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ AC01 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ AC01 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ AC01 × 0A03 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC01 × 0308 × 0A03 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ AC01 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC01 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC01 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ AC01 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC01 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ AC01 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC01 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ AC01 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC01 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ AC01 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 ÷ 0904 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0904 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 ÷ 0D4E ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0D4E ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ AC01 ÷ 0915 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0915 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ AC01 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ AC01 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ AC01 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 0308 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 0308 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0900 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0900 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0900 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0900 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0900 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0900 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0900 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0900 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0900 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0900 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0900 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0900 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0900 × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0900 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0900 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0900 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0900 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0900 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0900 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0900 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0900 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0900 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0900 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0900 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0900 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0900 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0900 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0900 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0900 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0900 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0900 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0903 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0903 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0903 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0903 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0903 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0903 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0903 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0903 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0903 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0903 × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0903 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0903 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0903 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0903 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0903 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0903 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0903 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0903 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0903 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0903 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0903 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0903 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0903 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0903 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0903 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0903 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0903 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0904 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0904 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0904 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0904 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0904 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0904 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0904 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0904 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0904 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0904 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0904 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0904 × 0A03 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0904 × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0904 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0904 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0904 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0904 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0904 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0904 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0904 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0904 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0904 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0904 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0904 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0904 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0904 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0904 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0904 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 200D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0904 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0904 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0904 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0D4E × 0020 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] SPACE (Other) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0020 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0D4E ÷ 000D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 000D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0D4E ÷ 000A ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 000A ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0D4E ÷ 0001 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0001 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0D4E × 034F ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0D4E × 0308 × 034F ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0D4E × 1F1E6 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0D4E × 0600 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0600 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0D4E × 0A03 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0D4E × 0308 × 0A03 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0D4E × 1100 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 1100 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0D4E × 1160 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 1160 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0D4E × 11A8 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 11A8 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0D4E × AC00 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0D4E × 0308 ÷ AC00 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0D4E × AC01 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0D4E × 0308 ÷ AC01 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0D4E × 0900 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0308 × 0900 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0903 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0308 × 0903 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0904 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0904 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0D4E ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0D4E ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0D4E × 0915 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0915 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0D4E × 231A ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] WATCH (ExtPict) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 231A ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0D4E × 0300 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 0308 × 0300 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 093C ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 0308 × 093C ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 094D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 0308 × 094D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 200D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 0308 × 200D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0D4E × 0378 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] <reserved-0378> (Other) ÷ [0.3]
+÷ 0D4E × 0308 ÷ 0378 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0915 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0915 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0915 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0915 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0915 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0915 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0915 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0915 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0915 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0915 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0915 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0915 × 0A03 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0915 × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0915 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0915 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0915 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0915 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0915 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0915 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0915 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0915 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0915 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0915 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0915 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0915 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0915 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0915 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 200D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0915 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0915 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0915 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 231A ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 231A × 0308 ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 231A ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 231A × 0308 ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 231A ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 231A × 0308 ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 231A ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 231A × 0308 ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 231A × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 231A × 0308 × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 231A ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 231A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 231A ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 231A × 0308 ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 231A × 0A03 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 231A × 0308 × 0A03 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 231A ÷ 1100 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 231A × 0308 ÷ 1100 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 231A ÷ 1160 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 231A × 0308 ÷ 1160 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 231A ÷ 11A8 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 231A × 0308 ÷ 11A8 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 231A ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 231A × 0308 ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 231A ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 231A × 0308 ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 231A × 0900 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A × 0308 × 0900 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A × 0308 × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A ÷ 0904 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A × 0308 ÷ 0904 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A ÷ 0D4E ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A × 0308 ÷ 0D4E ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 231A ÷ 0915 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 231A × 0308 ÷ 0915 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 231A ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 231A × 0308 ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 231A × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 231A × 0308 × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 231A × 093C ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 231A × 0308 × 093C ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 231A × 094D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 231A × 0308 × 094D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 231A × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 231A × 0308 × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 231A ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 231A × 0308 ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0300 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0300 × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0300 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0300 × 0A03 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0300 × 0308 × 0A03 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0300 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0300 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0300 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0300 × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0300 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0300 × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0300 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0300 × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0300 × 0900 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 × 0308 × 0900 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 ÷ 0D4E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0D4E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0300 ÷ 0915 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0915 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0300 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0300 × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 093C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 0308 × 093C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 094D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 0308 × 094D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 093C ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 093C × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 093C ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 093C × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 093C ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 093C × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 093C ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 093C × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 093C × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 093C × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 093C ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 093C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 093C ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 093C × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 093C × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 093C × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 093C ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 093C × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 093C ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 093C × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 093C ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 093C × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 093C ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 093C × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 093C ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 093C × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 093C × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 093C ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 093C × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 093C ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 093C × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 093C × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 093C × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 093C × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 093C × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 093C × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 093C × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 093C × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 093C × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 093C ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 093C × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 094D ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 094D × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 094D ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 094D × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 094D ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 094D × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 094D ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 094D × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 094D × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 094D × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 094D ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 094D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 094D ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 094D × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 094D × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 094D × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 094D ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 094D × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 094D ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 094D × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 094D ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 094D × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 094D ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 094D × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 094D ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 094D × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 094D × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 094D ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 094D × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 094D ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 094D × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 094D × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 094D × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 094D × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 094D × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 094D × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 094D × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 094D × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 094D × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 094D ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 094D × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 200D × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 200D × 0308 × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 200D ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 200D × 0308 ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 200D × 0A03 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 200D × 0308 × 0A03 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 200D ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 200D × 0308 ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 200D ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 200D × 0308 ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 200D ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 200D × 0308 ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 200D ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 200D × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 200D ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 200D × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 200D × 0900 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D × 0308 × 0900 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D ÷ 0904 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D × 0308 ÷ 0904 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D ÷ 0D4E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D × 0308 ÷ 0D4E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 200D ÷ 0915 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 200D × 0308 ÷ 0915 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 200D ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 200D × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 200D × 093C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 200D × 0308 × 093C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 200D × 094D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 200D × 0308 × 094D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 200D ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 200D × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0378 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 0378 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0378 × 0308 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0378 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0378 × 0308 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0378 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
+÷ 0378 × 034F ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0378 × 0308 × 034F ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3]
+÷ 0378 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0378 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
+÷ 0378 × 0A03 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0378 × 0308 × 0A03 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3]
+÷ 0378 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 0378 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0378 × 0308 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
+÷ 0378 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0378 × 0308 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
+÷ 0378 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0378 × 0308 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
+÷ 0378 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0378 × 0308 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
+÷ 0378 × 0900 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 × 0308 × 0900 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 × 0308 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 ÷ 0904 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0904 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 ÷ 0D4E ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0D4E ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3]
+÷ 0378 ÷ 0915 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0915 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0378 ÷ 231A ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0378 × 0308 ÷ 231A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0378 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 0308 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 093C ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 0308 × 093C ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 094D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 0308 × 094D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0378 × 0308 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0378 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 0378 × 0308 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
+÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3]
+÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC LETTER NOON (Other) ÷ [0.3]
+÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
+÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC00 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ AC01 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
+÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 200D ÷ 1F1E7 × 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3]
+÷ 0061 × 0308 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 × 0903 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 0061 ÷ 0600 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) × [9.2] LATIN SMALL LETTER B (Other) ÷ [0.3]
+÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3]
+÷ 0061 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3]
+÷ 0061 × 1F3FF ÷ 1F476 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [0.3]
+÷ 1F6D1 × 200D × 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 0061 × 200D ÷ 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] UPPER BLADE SCISSORS (Other) ÷ [0.3]
+÷ 0061 × 200D ÷ 2701 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] UPPER BLADE SCISSORS (Other) ÷ [0.3]
+÷ 0915 ÷ 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 094D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 094D × 094D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 094D × 200D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 093C × 200D × 094D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 093C × 094D × 200D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 094D × 0924 × 094D × 092F ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER YA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 094D ÷ 0061 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] LATIN SMALL LETTER A (Other) ÷ [0.3]
+÷ 0061 × 094D ÷ 0924 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 003F × 094D ÷ 0924 ÷ # ÷ [0.2] QUESTION MARK (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+÷ 0915 × 094D × 094D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3]
+#
+# Lines: 1187
+#
+# EOF
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/data/LineBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/LineBreakTest.txt
new file mode 100644
index 0000000000..614bf33fa8
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/data/LineBreakTest.txt
@@ -0,0 +1,10306 @@
+# LineBreakTest-15.1.0.txt
+# Date: 2023-08-08, 11:38:16 GMT
+# © 2023 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see https://www.unicode.org/reports/tr44/
+#
+# Default Line_Break Test
+#
+# Format:
+# <string> (# <comment>)?
+# <string> contains hex Unicode code points, with
+# ÷ wherever there is a break opportunity, and
+# × wherever there is not.
+# <comment> the format can change, but currently it shows:
+# - the sample character name
+# - (x) the Line_Break property value for the sample character
+# - [x] the rule that determines whether there is a break or not,
+# as listed in the Rules section of LineBreakTest.html
+#
+# Note:
+# The Line_Break tests use tailoring of numbers described in
+# Example 7 of Section 8.2, "Examples of Customization" of UAX #14.
+#
+# These samples may be extended or changed in the future.
+#
+× 1B05 ÷ 1B05 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B05 × 0020 ÷ 1B05 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B05 × 0308 ÷ 1B05 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B05 ÷ 0023 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B05 × 0020 ÷ 0023 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B05 × 0308 ÷ 0023 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B05 ÷ 11003 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B05 × 0020 ÷ 11003 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B05 × 0308 ÷ 11003 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B05 ÷ 1BC0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B05 × 0020 ÷ 1BC0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B05 × 0308 ÷ 1BC0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B05 ÷ 2014 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1B05 × 0020 ÷ 2014 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1B05 × 0308 ÷ 2014 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1B05 × 0009 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B05 × 0020 ÷ 0009 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B05 × 0308 × 0009 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B05 ÷ 00B4 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B05 × 0020 ÷ 00B4 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B05 × 0308 ÷ 00B4 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B05 × 000B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B05 × 0020 × 000B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B05 × 0308 × 000B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 000B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B05 ÷ FFFC ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B05 × 0020 ÷ FFFC ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B05 × 0308 ÷ FFFC ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B05 × 007D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B05 × 0020 × 007D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B05 × 0308 × 007D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 007D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B05 × 000D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B05 × 0020 × 000D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B05 × 0308 × 000D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 000D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B05 × 0021 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B05 × 0020 × 0021 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B05 × 0308 × 0021 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 0021 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B05 × 00A0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B05 × 0020 ÷ 00A0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B05 × 0308 × 00A0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B05 ÷ AC00 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B05 × 0020 ÷ AC00 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B05 × 0308 ÷ AC00 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B05 ÷ AC01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B05 × 0020 ÷ AC01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B05 × 0308 ÷ AC01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B05 ÷ 05D0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B05 × 0020 ÷ 05D0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B05 × 0308 ÷ 05D0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B05 × 002D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B05 × 0020 ÷ 002D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B05 × 0308 × 002D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 002D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B05 ÷ 1B50 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B05 × 0020 ÷ 1B50 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B05 × 0308 ÷ 1B50 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B05 × 2024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B05 × 0020 ÷ 2024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B05 × 0308 × 2024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B05 × 002C ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B05 × 0020 × 002C ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B05 × 0308 × 002C ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 002C ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B05 ÷ 1100 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B05 × 0020 ÷ 1100 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B05 × 0308 ÷ 1100 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B05 ÷ 11A8 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B05 × 0020 ÷ 11A8 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B05 × 0308 ÷ 11A8 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B05 ÷ 1160 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B05 × 0020 ÷ 1160 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B05 × 0308 ÷ 1160 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B05 × 000A ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B05 × 0020 × 000A ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B05 × 0308 × 000A ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 000A ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B05 × 0085 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B05 × 0020 × 0085 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B05 × 0308 × 0085 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 0085 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B05 × 17D6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B05 × 0020 ÷ 17D6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B05 × 0308 × 17D6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B05 ÷ 0030 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B05 × 0020 ÷ 0030 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B05 × 0308 ÷ 0030 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B05 ÷ 2329 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B05 × 0020 ÷ 2329 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B05 × 0308 ÷ 2329 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B05 ÷ 0025 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B05 × 0020 ÷ 0025 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B05 × 0308 ÷ 0025 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B05 ÷ 0024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B05 × 0020 ÷ 0024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B05 × 0308 ÷ 0024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B05 × 0022 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1B05 × 0020 ÷ 0022 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1B05 × 0308 × 0022 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1B05 × 0020 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B05 × 0020 × 0020 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 0020 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B05 × 002F ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B05 × 0020 × 002F ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B05 × 0308 × 002F ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 002F ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B05 × 1BF2 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [28.12] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B05 × 0020 ÷ 1BF2 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B05 × 0308 × 1BF2 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.12] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B05 × 1B44 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [28.12] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B05 × 0020 ÷ 1B44 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B05 × 0308 × 1B44 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.12] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B05 × 2060 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B05 × 0020 × 2060 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B05 × 0308 × 2060 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 2060 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B05 × 200B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B05 × 0020 × 200B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B05 × 0308 × 200B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 200B ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B05 ÷ 1F1E6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B05 × 0020 ÷ 1F1E6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B05 × 0308 ÷ 1F1E6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B05 ÷ 261D ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B05 × 0020 ÷ 261D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B05 × 0308 ÷ 261D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 261D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B05 ÷ 1F3FB ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B05 × 0020 ÷ 1F3FB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B05 × 0308 ÷ 1F3FB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B05 × 00AB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B05 × 0020 ÷ 00AB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B05 × 0308 × 00AB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B05 × 00BB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B05 × 0020 × 00BB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B05 × 0308 × 00BB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 00BB ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B05 × 0029 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B05 × 0020 × 0029 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B05 × 0308 × 0029 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B05 × 0308 × 0020 × 0029 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B05 ÷ 0028 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B05 × 0020 ÷ 0028 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B05 × 0308 ÷ 0028 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B05 × 0001 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B05 × 0020 ÷ 0001 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B05 × 0308 × 0001 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B05 × 200D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B05 × 0020 ÷ 200D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B05 × 0308 × 200D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 200D ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B05 ÷ 00A7 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B05 × 0020 ÷ 00A7 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B05 × 0308 ÷ 00A7 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B05 ÷ 50005 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B05 × 0020 ÷ 50005 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B05 × 0308 ÷ 50005 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B05 ÷ 0E01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B05 × 0020 ÷ 0E01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B05 × 0308 ÷ 0E01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B05 × 3041 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B05 × 0020 ÷ 3041 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B05 × 0308 × 3041 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B05 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] BALINESE LETTER AKARA (AK) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 ÷ 1B05 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0023 × 0020 ÷ 1B05 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0023 × 0308 ÷ 1B05 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0023 × 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 × 0020 ÷ 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 × 0308 × 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0023 ÷ 11003 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0023 × 0020 ÷ 11003 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0023 × 0308 ÷ 11003 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0023 ÷ 1BC0 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0023 × 0020 ÷ 1BC0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0023 × 0308 ÷ 1BC0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0023 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0020 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0308 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0023 × 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 × 0020 ÷ 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 × 0308 × 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0023 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 0020 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 0308 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0023 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 × 0020 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 × 0308 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 × 0308 × 0020 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0023 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 0020 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 0308 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0023 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0020 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0308 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 0308 × 0020 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0023 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0020 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0308 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0308 × 0020 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0023 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 0020 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 0308 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0023 × 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 × 0020 ÷ 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 × 0308 × 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0023 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 × 0020 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 × 0308 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0023 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 0020 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 0308 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0023 × 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 0020 ÷ 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 0308 × 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0023 × 002D ÷ # × [0.3] NUMBER SIGN (AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 × 0020 ÷ 002D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 × 0308 × 002D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 002D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0023 ÷ 1B50 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0023 × 0020 ÷ 1B50 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0023 × 0308 ÷ 1B50 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0023 × 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 0020 ÷ 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 0308 × 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0023 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 0023 × 0020 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0023 × 0308 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0023 × 0308 × 0020 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0023 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 × 0020 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 × 0308 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0023 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 × 0020 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 × 0308 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0023 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 0020 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 0308 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0023 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0020 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0308 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0308 × 0020 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0023 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 0020 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 0308 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0023 × 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0020 ÷ 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0308 × 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0023 × 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0020 ÷ 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0308 × 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0023 ÷ 2329 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0023 × 0020 ÷ 2329 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0023 × 0308 ÷ 2329 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0023 × 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0020 ÷ 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0308 × 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0023 × 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0020 ÷ 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0308 × 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0023 × 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0020 ÷ 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0308 × 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0023 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 0020 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0023 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 0020 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 0308 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0023 × 0308 × 0020 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0023 ÷ 1BF2 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0023 × 0020 ÷ 1BF2 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0023 × 0308 ÷ 1BF2 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0023 ÷ 1B44 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0023 × 0020 ÷ 1B44 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0023 × 0308 ÷ 1B44 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0023 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 0020 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 0308 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 0308 × 0020 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0023 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 × 0020 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 × 0308 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 × 0308 × 0020 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0023 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 × 0020 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 × 0308 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0023 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 × 0020 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 × 0308 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0023 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0020 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0308 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0023 × 00AB ÷ # × [0.3] NUMBER SIGN (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0023 × 0020 ÷ 00AB ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0023 × 0308 × 00AB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0023 × 00BB ÷ # × [0.3] NUMBER SIGN (AL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0023 × 0020 × 00BB ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0023 × 0308 × 00BB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0023 × 0308 × 0020 × 00BB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0023 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0023 × 0020 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0023 × 0308 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0023 × 0308 × 0020 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0023 × 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0023 × 0020 ÷ 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0023 × 0308 × 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0023 × 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 0020 ÷ 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 0308 × 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0023 × 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 0020 ÷ 200D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 0308 × 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0023 × 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 0020 ÷ 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 0308 × 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0023 × 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0020 ÷ 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0308 × 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0023 × 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 0020 ÷ 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 0308 × 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0023 × 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 × 0020 ÷ 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 × 0308 × 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0023 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11003 × 1B05 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [28.11] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11003 × 0020 ÷ 1B05 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11003 × 0308 × 1B05 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.11] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11003 ÷ 0023 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11003 × 0020 ÷ 0023 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11003 × 0308 ÷ 0023 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11003 ÷ 11003 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11003 × 0020 ÷ 11003 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11003 × 0308 ÷ 11003 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11003 × 1BC0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [28.11] BATAK LETTER A (AS) ÷ [0.3]
+× 11003 × 0020 ÷ 1BC0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 11003 × 0308 × 1BC0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.11] BATAK LETTER A (AS) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 11003 ÷ 2014 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 11003 × 0020 ÷ 2014 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 11003 × 0308 ÷ 2014 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 11003 × 0009 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11003 × 0020 ÷ 0009 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11003 × 0308 × 0009 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11003 ÷ 00B4 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11003 × 0020 ÷ 00B4 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11003 × 0308 ÷ 00B4 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11003 × 000B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11003 × 0020 × 000B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11003 × 0308 × 000B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11003 × 0308 × 0020 × 000B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11003 ÷ FFFC ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11003 × 0020 ÷ FFFC ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11003 × 0308 ÷ FFFC ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11003 × 007D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11003 × 0020 × 007D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11003 × 0308 × 007D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11003 × 0308 × 0020 × 007D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11003 × 000D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11003 × 0020 × 000D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11003 × 0308 × 000D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11003 × 0308 × 0020 × 000D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11003 × 0021 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11003 × 0020 × 0021 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11003 × 0308 × 0021 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11003 × 0308 × 0020 × 0021 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11003 × 00A0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11003 × 0020 ÷ 00A0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11003 × 0308 × 00A0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11003 ÷ AC00 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11003 × 0020 ÷ AC00 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11003 × 0308 ÷ AC00 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11003 ÷ AC01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11003 × 0020 ÷ AC01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11003 × 0308 ÷ AC01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11003 ÷ 05D0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11003 × 0020 ÷ 05D0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11003 × 0308 ÷ 05D0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11003 × 002D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11003 × 0020 ÷ 002D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11003 × 0308 × 002D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 002D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11003 ÷ 1B50 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11003 × 0020 ÷ 1B50 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11003 × 0308 ÷ 1B50 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11003 × 2024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11003 × 0020 ÷ 2024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11003 × 0308 × 2024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11003 × 002C ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11003 × 0020 × 002C ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11003 × 0308 × 002C ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 11003 × 0308 × 0020 × 002C ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11003 ÷ 1100 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11003 × 0020 ÷ 1100 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11003 × 0308 ÷ 1100 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11003 ÷ 11A8 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11003 × 0020 ÷ 11A8 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11003 × 0308 ÷ 11A8 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11003 ÷ 1160 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11003 × 0020 ÷ 1160 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11003 × 0308 ÷ 1160 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11003 × 000A ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11003 × 0020 × 000A ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11003 × 0308 × 000A ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11003 × 0308 × 0020 × 000A ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11003 × 0085 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11003 × 0020 × 0085 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11003 × 0308 × 0085 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11003 × 0308 × 0020 × 0085 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11003 × 17D6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11003 × 0020 ÷ 17D6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11003 × 0308 × 17D6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11003 ÷ 0030 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11003 × 0020 ÷ 0030 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11003 × 0308 ÷ 0030 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11003 ÷ 2329 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11003 × 0020 ÷ 2329 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11003 × 0308 ÷ 2329 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11003 ÷ 0025 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11003 × 0020 ÷ 0025 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11003 × 0308 ÷ 0025 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11003 ÷ 0024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11003 × 0020 ÷ 0024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11003 × 0308 ÷ 0024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11003 × 0022 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 11003 × 0020 ÷ 0022 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 11003 × 0308 × 0022 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 11003 × 0020 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11003 × 0020 × 0020 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 11003 × 0308 × 0020 × 0020 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11003 × 002F ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11003 × 0020 × 002F ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11003 × 0308 × 002F ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 11003 × 0308 × 0020 × 002F ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11003 ÷ 1BF2 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11003 × 0020 ÷ 1BF2 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11003 × 0308 ÷ 1BF2 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11003 ÷ 1B44 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11003 × 0020 ÷ 1B44 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11003 × 0308 ÷ 1B44 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11003 × 2060 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11003 × 0020 × 2060 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11003 × 0308 × 2060 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11003 × 0308 × 0020 × 2060 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11003 × 200B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11003 × 0020 × 200B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11003 × 0308 × 200B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11003 × 0308 × 0020 × 200B ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11003 ÷ 1F1E6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11003 × 0020 ÷ 1F1E6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11003 × 0308 ÷ 1F1E6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11003 ÷ 261D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11003 × 0020 ÷ 261D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11003 × 0308 ÷ 261D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 261D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11003 ÷ 1F3FB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11003 × 0020 ÷ 1F3FB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11003 × 0308 ÷ 1F3FB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11003 × 00AB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11003 × 0020 ÷ 00AB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11003 × 0308 × 00AB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11003 × 00BB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11003 × 0020 × 00BB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11003 × 0308 × 00BB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11003 × 0308 × 0020 × 00BB ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11003 × 0029 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11003 × 0020 × 0029 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11003 × 0308 × 0029 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11003 × 0308 × 0020 × 0029 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11003 ÷ 0028 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11003 × 0020 ÷ 0028 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11003 × 0308 ÷ 0028 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11003 × 0001 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11003 × 0020 ÷ 0001 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11003 × 0308 × 0001 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11003 × 200D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11003 × 0020 ÷ 200D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11003 × 0308 × 200D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 200D ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11003 ÷ 00A7 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11003 × 0020 ÷ 00A7 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11003 × 0308 ÷ 00A7 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11003 ÷ 50005 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11003 × 0020 ÷ 50005 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11003 × 0308 ÷ 50005 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11003 ÷ 0E01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11003 × 0020 ÷ 0E01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11003 × 0308 ÷ 0E01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11003 × 3041 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11003 × 0020 ÷ 3041 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11003 × 0308 × 3041 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11003 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] BRAHMI SIGN JIHVAMULIYA (AP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BC0 ÷ 1B05 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1B05 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1B05 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BC0 ÷ 0023 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0023 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BC0 × 0308 ÷ 0023 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BC0 ÷ 11003 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BC0 × 0020 ÷ 11003 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BC0 × 0308 ÷ 11003 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BC0 ÷ 1BC0 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1BC0 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1BC0 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BC0 ÷ 2014 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1BC0 × 0020 ÷ 2014 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1BC0 × 0308 ÷ 2014 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1BC0 × 0009 ÷ # × [0.3] BATAK LETTER A (AS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0009 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BC0 × 0308 × 0009 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BC0 ÷ 00B4 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BC0 × 0020 ÷ 00B4 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BC0 × 0308 ÷ 00B4 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BC0 × 000B ÷ # × [0.3] BATAK LETTER A (AS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BC0 × 0020 × 000B ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BC0 × 0308 × 000B ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 000B ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BC0 ÷ FFFC ÷ # × [0.3] BATAK LETTER A (AS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BC0 × 0020 ÷ FFFC ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BC0 × 0308 ÷ FFFC ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BC0 × 007D ÷ # × [0.3] BATAK LETTER A (AS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BC0 × 0020 × 007D ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BC0 × 0308 × 007D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 007D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BC0 × 000D ÷ # × [0.3] BATAK LETTER A (AS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BC0 × 0020 × 000D ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BC0 × 0308 × 000D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 000D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BC0 × 0021 ÷ # × [0.3] BATAK LETTER A (AS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BC0 × 0020 × 0021 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BC0 × 0308 × 0021 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 0021 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BC0 × 00A0 ÷ # × [0.3] BATAK LETTER A (AS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 00A0 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BC0 × 0308 × 00A0 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BC0 ÷ AC00 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BC0 × 0020 ÷ AC00 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BC0 × 0308 ÷ AC00 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BC0 ÷ AC01 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BC0 × 0020 ÷ AC01 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BC0 × 0308 ÷ AC01 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BC0 ÷ 05D0 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 05D0 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BC0 × 0308 ÷ 05D0 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BC0 × 002D ÷ # × [0.3] BATAK LETTER A (AS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BC0 × 0020 ÷ 002D ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BC0 × 0308 × 002D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BC0 ÷ 1B50 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1B50 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1B50 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BC0 × 2024 ÷ # × [0.3] BATAK LETTER A (AS) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BC0 × 0020 ÷ 2024 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BC0 × 0308 × 2024 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BC0 × 002C ÷ # × [0.3] BATAK LETTER A (AS) × [13.02] COMMA (IS) ÷ [0.3]
+× 1BC0 × 0020 × 002C ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1BC0 × 0308 × 002C ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 002C ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1BC0 ÷ 1100 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1100 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1100 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BC0 ÷ 11A8 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BC0 × 0020 ÷ 11A8 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BC0 × 0308 ÷ 11A8 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BC0 ÷ 1160 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1160 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1160 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BC0 × 000A ÷ # × [0.3] BATAK LETTER A (AS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BC0 × 0020 × 000A ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BC0 × 0308 × 000A ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 000A ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BC0 × 0085 ÷ # × [0.3] BATAK LETTER A (AS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BC0 × 0020 × 0085 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BC0 × 0308 × 0085 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 0085 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BC0 × 17D6 ÷ # × [0.3] BATAK LETTER A (AS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BC0 × 0020 ÷ 17D6 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BC0 × 0308 × 17D6 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BC0 ÷ 0030 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0030 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BC0 × 0308 ÷ 0030 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BC0 ÷ 2329 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BC0 × 0020 ÷ 2329 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BC0 × 0308 ÷ 2329 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BC0 ÷ 0025 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0025 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BC0 × 0308 ÷ 0025 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BC0 ÷ 0024 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0024 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BC0 × 0308 ÷ 0024 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BC0 × 0022 ÷ # × [0.3] BATAK LETTER A (AS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0022 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1BC0 × 0308 × 0022 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1BC0 × 0020 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BC0 × 0020 × 0020 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 0020 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BC0 × 002F ÷ # × [0.3] BATAK LETTER A (AS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1BC0 × 0020 × 002F ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1BC0 × 0308 × 002F ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 002F ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1BC0 × 1BF2 ÷ # × [0.3] BATAK LETTER A (AS) × [28.12] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1BF2 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BC0 × 0308 × 1BF2 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.12] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BC0 × 1B44 ÷ # × [0.3] BATAK LETTER A (AS) × [28.12] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1B44 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BC0 × 0308 × 1B44 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.12] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BC0 × 2060 ÷ # × [0.3] BATAK LETTER A (AS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BC0 × 0020 × 2060 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BC0 × 0308 × 2060 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 2060 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BC0 × 200B ÷ # × [0.3] BATAK LETTER A (AS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BC0 × 0020 × 200B ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BC0 × 0308 × 200B ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 200B ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BC0 ÷ 1F1E6 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1F1E6 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1F1E6 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BC0 ÷ 261D ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BC0 × 0020 ÷ 261D ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BC0 × 0308 ÷ 261D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BC0 ÷ 1F3FB ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BC0 × 0020 ÷ 1F3FB ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BC0 × 0308 ÷ 1F3FB ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BC0 × 00AB ÷ # × [0.3] BATAK LETTER A (AS) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BC0 × 0020 ÷ 00AB ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BC0 × 0308 × 00AB ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BC0 × 00BB ÷ # × [0.3] BATAK LETTER A (AS) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BC0 × 0020 × 00BB ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BC0 × 0308 × 00BB ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 00BB ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BC0 × 0029 ÷ # × [0.3] BATAK LETTER A (AS) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BC0 × 0020 × 0029 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BC0 × 0308 × 0029 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BC0 × 0308 × 0020 × 0029 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BC0 ÷ 0028 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0028 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BC0 × 0308 ÷ 0028 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BC0 × 0001 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0001 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BC0 × 0308 × 0001 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BC0 × 200D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BC0 × 0020 ÷ 200D ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BC0 × 0308 × 200D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BC0 ÷ 00A7 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 00A7 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BC0 × 0308 ÷ 00A7 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BC0 ÷ 50005 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 50005 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BC0 × 0308 ÷ 50005 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BC0 ÷ 0E01 ÷ # × [0.3] BATAK LETTER A (AS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BC0 × 0020 ÷ 0E01 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BC0 × 0308 ÷ 0E01 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BC0 × 3041 ÷ # × [0.3] BATAK LETTER A (AS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BC0 × 0020 ÷ 3041 ÷ # × [0.3] BATAK LETTER A (AS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BC0 × 0308 × 3041 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BC0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] BATAK LETTER A (AS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 ÷ 1B05 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2014 × 0020 ÷ 1B05 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2014 × 0308 ÷ 1B05 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2014 ÷ 0023 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 0020 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 0308 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2014 ÷ 11003 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2014 × 0020 ÷ 11003 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2014 × 0308 ÷ 11003 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2014 ÷ 1BC0 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2014 × 0020 ÷ 1BC0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2014 × 0308 ÷ 1BC0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2014 × 2014 ÷ # × [0.3] EM DASH (B2) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0020 × 2014 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0308 × 2014 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0308 × 0020 × 2014 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [17.0] EM DASH (B2) ÷ [0.3]
+× 2014 × 0009 ÷ # × [0.3] EM DASH (B2) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 × 0020 ÷ 0009 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 × 0308 × 0009 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2014 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 0020 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 0308 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2014 × 000B ÷ # × [0.3] EM DASH (B2) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 × 0020 × 000B ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 × 0308 × 000B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 × 0308 × 0020 × 000B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2014 ÷ FFFC ÷ # × [0.3] EM DASH (B2) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 0020 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 0308 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2014 × 007D ÷ # × [0.3] EM DASH (B2) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0020 × 007D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0308 × 007D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 0308 × 0020 × 007D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2014 × 000D ÷ # × [0.3] EM DASH (B2) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0020 × 000D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0308 × 000D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0308 × 0020 × 000D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2014 × 0021 ÷ # × [0.3] EM DASH (B2) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 0020 × 0021 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 0308 × 0021 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0021 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2014 × 00A0 ÷ # × [0.3] EM DASH (B2) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 × 0020 ÷ 00A0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 × 0308 × 00A0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2014 ÷ AC00 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 × 0020 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 × 0308 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2014 ÷ AC01 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 × 0020 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 × 0308 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2014 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 0020 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 0308 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2014 × 002D ÷ # × [0.3] EM DASH (B2) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 × 0020 ÷ 002D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 × 0308 × 002D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 002D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2014 ÷ 1B50 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2014 × 0020 ÷ 1B50 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2014 × 0308 ÷ 1B50 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2014 × 2024 ÷ # × [0.3] EM DASH (B2) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 0020 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 0308 × 2024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2014 × 002C ÷ # × [0.3] EM DASH (B2) × [13.02] COMMA (IS) ÷ [0.3]
+× 2014 × 0020 × 002C ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2014 × 0308 × 002C ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 2014 × 0308 × 0020 × 002C ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2014 ÷ 1100 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 × 0020 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 × 0308 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2014 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 × 0020 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 × 0308 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2014 ÷ 1160 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 0020 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 0308 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2014 × 000A ÷ # × [0.3] EM DASH (B2) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0020 × 000A ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0308 × 000A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0308 × 0020 × 000A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2014 × 0085 ÷ # × [0.3] EM DASH (B2) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 0020 × 0085 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 0308 × 0085 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0085 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2014 × 17D6 ÷ # × [0.3] EM DASH (B2) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 × 0020 ÷ 17D6 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 × 0308 × 17D6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2014 ÷ 0030 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 × 0020 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 × 0308 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2014 ÷ 2329 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2014 × 0020 ÷ 2329 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2014 × 0308 ÷ 2329 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2014 ÷ 0025 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 × 0020 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 × 0308 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2014 ÷ 0024 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0020 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0308 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2014 × 0022 ÷ # × [0.3] EM DASH (B2) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0020 ÷ 0022 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0308 × 0022 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2014 × 0020 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 0020 × 0020 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0020 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2014 × 002F ÷ # × [0.3] EM DASH (B2) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 0020 × 002F ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 0308 × 002F ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 0308 × 0020 × 002F ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2014 ÷ 1BF2 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2014 × 0020 ÷ 1BF2 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2014 × 0308 ÷ 1BF2 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2014 ÷ 1B44 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2014 × 0020 ÷ 1B44 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2014 × 0308 ÷ 1B44 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2014 × 2060 ÷ # × [0.3] EM DASH (B2) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 0020 × 2060 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 0308 × 2060 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 0308 × 0020 × 2060 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2014 × 200B ÷ # × [0.3] EM DASH (B2) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 × 0020 × 200B ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 × 0308 × 200B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 × 0308 × 0020 × 200B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2014 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 × 0020 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 × 0308 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2014 ÷ 261D ÷ # × [0.3] EM DASH (B2) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 × 0020 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 × 0308 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2014 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0020 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0308 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2014 × 00AB ÷ # × [0.3] EM DASH (B2) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2014 × 0020 ÷ 00AB ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2014 × 0308 × 00AB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2014 × 00BB ÷ # × [0.3] EM DASH (B2) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2014 × 0020 × 00BB ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2014 × 0308 × 00BB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2014 × 0308 × 0020 × 00BB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2014 × 0029 ÷ # × [0.3] EM DASH (B2) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2014 × 0020 × 0029 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2014 × 0308 × 0029 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2014 × 0308 × 0020 × 0029 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2014 ÷ 0028 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2014 × 0020 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2014 × 0308 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2014 × 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 0020 ÷ 0001 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 0308 × 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2014 × 200D ÷ # × [0.3] EM DASH (B2) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 × 0020 ÷ 200D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 × 0308 × 200D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 200D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2014 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 × 0020 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 × 0308 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2014 ÷ 50005 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 × 0020 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 × 0308 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2014 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 0020 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 0308 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2014 × 3041 ÷ # × [0.3] EM DASH (B2) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 × 0020 ÷ 3041 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 × 0308 × 3041 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2014 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 ÷ 1B05 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0009 × 0020 ÷ 1B05 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0009 × 0308 ÷ 1B05 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0009 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 × 0020 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 × 0308 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0009 ÷ 11003 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0009 × 0020 ÷ 11003 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0009 × 0308 ÷ 11003 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0009 ÷ 1BC0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0009 × 0020 ÷ 1BC0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0009 × 0308 ÷ 1BC0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0009 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0020 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0308 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0009 × 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 × 0020 ÷ 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 × 0308 × 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0009 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 0020 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 0308 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0009 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 × 0020 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 × 0308 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 × 0308 × 0020 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0009 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 0020 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 0308 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0009 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0020 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0308 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 0308 × 0020 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0009 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0020 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0308 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0308 × 0020 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0009 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 × 0020 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 × 0308 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0009 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 × 0020 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 × 0308 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0009 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 × 0020 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 × 0308 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0009 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 × 0020 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 × 0308 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0009 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 0020 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 0308 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0009 × 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 × 0020 ÷ 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 × 0308 × 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0009 ÷ 1B50 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0009 × 0020 ÷ 1B50 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0009 × 0308 ÷ 1B50 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0009 × 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 0020 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 0308 × 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0009 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] COMMA (IS) ÷ [0.3]
+× 0009 × 0020 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0009 × 0308 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0009 × 0308 × 0020 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0009 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 × 0020 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 × 0308 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0009 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 × 0020 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 × 0308 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0009 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 0020 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 0308 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0009 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0020 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0308 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0308 × 0020 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0009 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 0020 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 0308 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0009 × 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 × 0020 ÷ 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 × 0308 × 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0009 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 × 0020 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 × 0308 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0009 ÷ 2329 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0009 × 0020 ÷ 2329 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0009 × 0308 ÷ 2329 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0009 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 × 0020 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 × 0308 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0009 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0020 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0308 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0009 × 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0020 ÷ 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0308 × 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0009 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 0020 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0009 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 0020 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 0308 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0009 × 0308 × 0020 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0009 ÷ 1BF2 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0009 × 0020 ÷ 1BF2 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0009 × 0308 ÷ 1BF2 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0009 ÷ 1B44 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0009 × 0020 ÷ 1B44 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0009 × 0308 ÷ 1B44 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0009 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 0020 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 0308 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 0308 × 0020 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0009 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 × 0020 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 × 0308 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 × 0308 × 0020 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0009 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 × 0308 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0009 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 × 0020 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 × 0308 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0009 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0020 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0308 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0009 × 00AB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0009 × 0020 ÷ 00AB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0009 × 0308 × 00AB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0009 × 00BB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0009 × 0020 × 00BB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0009 × 0308 × 00BB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0009 × 0308 × 0020 × 00BB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0009 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0009 × 0020 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0009 × 0308 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0009 × 0308 × 0020 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0009 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0009 × 0020 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0009 × 0308 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0009 × 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 0020 ÷ 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 0308 × 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0009 × 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 × 0020 ÷ 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 × 0308 × 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0009 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 × 0020 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 × 0308 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0009 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 × 0020 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 × 0308 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0009 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 0020 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 0308 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0009 × 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 × 0020 ÷ 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 × 0308 × 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0009 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 1B05 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00B4 × 0020 ÷ 1B05 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00B4 × 0308 × 1B05 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00B4 × 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 0308 × 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00B4 × 11003 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00B4 × 0020 ÷ 11003 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00B4 × 0308 × 11003 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00B4 × 1BC0 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] BATAK LETTER A (AS) ÷ [0.3]
+× 00B4 × 0020 ÷ 1BC0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00B4 × 0308 × 1BC0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] BATAK LETTER A (AS) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00B4 × 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0020 ÷ 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0308 × 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00B4 × 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 0020 ÷ 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 0308 × 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00B4 × 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 0020 ÷ 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 0308 × 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00B4 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 × 0020 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 × 0308 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00B4 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 0020 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 0308 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00B4 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0020 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0308 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00B4 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0020 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0308 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00B4 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 0020 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 0308 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00B4 × 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × 0020 ÷ 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × 0308 × 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00B4 × AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × 0020 ÷ AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × 0308 × AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00B4 × AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 0020 ÷ AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 0308 × AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00B4 × 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 0020 ÷ 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 0308 × 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00B4 × 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 0020 ÷ 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 0308 × 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00B4 × 1B50 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00B4 × 0020 ÷ 1B50 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00B4 × 0308 × 1B50 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00B4 × 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 0020 ÷ 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 0308 × 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00B4 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] COMMA (IS) ÷ [0.3]
+× 00B4 × 0020 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00B4 × 0308 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00B4 × 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 0020 ÷ 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 0308 × 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00B4 × 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 0020 ÷ 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 0308 × 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00B4 × 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 0020 ÷ 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 0308 × 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00B4 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0020 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0308 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00B4 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 0020 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 0308 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00B4 × 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0020 ÷ 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0308 × 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00B4 × 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0020 ÷ 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0308 × 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00B4 × 2329 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00B4 × 0020 ÷ 2329 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00B4 × 0308 × 2329 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00B4 × 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0020 ÷ 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0308 × 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00B4 × 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0020 ÷ 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0308 × 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00B4 × 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0020 ÷ 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0308 × 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00B4 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 0020 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00B4 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 0020 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 0308 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00B4 × 1BF2 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00B4 × 0020 ÷ 1BF2 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00B4 × 0308 × 1BF2 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00B4 × 1B44 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00B4 × 0020 ÷ 1B44 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00B4 × 0308 × 1B44 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00B4 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 0020 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 0308 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00B4 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 0020 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 0308 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00B4 × 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 0020 ÷ 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 0308 × 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00B4 × 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 0020 ÷ 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 0308 × 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00B4 × 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0020 ÷ 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0308 × 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00B4 × 00AB ÷ # × [0.3] ACUTE ACCENT (BB) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00B4 × 0020 ÷ 00AB ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00B4 × 0308 × 00AB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00B4 × 00BB ÷ # × [0.3] ACUTE ACCENT (BB) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00B4 × 0020 × 00BB ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00B4 × 0308 × 00BB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 00BB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00B4 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00B4 × 0020 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00B4 × 0308 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00B4 × 0308 × 0020 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00B4 × 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00B4 × 0020 ÷ 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00B4 × 0308 × 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00B4 × 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 0020 ÷ 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 0308 × 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00B4 × 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 0020 ÷ 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 0308 × 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00B4 × 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 0308 × 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00B4 × 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0308 × 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00B4 × 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 0020 ÷ 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 0308 × 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00B4 × 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0020 ÷ 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0308 × 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00B4 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 1B05 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1B05 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1B05 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000B ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 0308 × 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000B ÷ 11003 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000B ÷ 0020 ÷ 11003 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000B ÷ 0308 ÷ 11003 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 11003 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000B ÷ 1BC0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1BC0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1BC0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000B ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0020 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0308 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000B ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 0308 × 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000B ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 0308 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000B ÷ 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ 0020 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ 0308 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000B ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 0020 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 0308 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000B ÷ 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0020 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0308 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000B ÷ 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0020 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0308 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000B ÷ 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 0020 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 0308 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000B ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ 0308 × 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000B ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ 0020 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ 0308 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000B ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 0020 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 0308 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000B ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 0308 × 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000B ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 0020 ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 0308 × 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000B ÷ 1B50 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1B50 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1B50 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000B ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 0020 ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 0308 × 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000B ÷ 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMMA (IS) ÷ [0.3]
+× 000B ÷ 0020 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000B ÷ 0308 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000B ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000B ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 0020 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 0308 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000B ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000B ÷ 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0020 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0308 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000B ÷ 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 0020 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 0308 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000B ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0020 ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0308 × 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000B ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0308 × 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000B ÷ 2329 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000B ÷ 0020 ÷ 2329 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000B ÷ 0308 ÷ 2329 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 2329 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000B ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0308 × 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000B ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0308 × 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000B ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0308 × 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000B ÷ 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [0.3]
+× 000B ÷ 0020 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 0020 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 0308 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000B ÷ 1BF2 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1BF2 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1BF2 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000B ÷ 1B44 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1B44 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1B44 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000B ÷ 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 0020 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 0308 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000B ÷ 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 0020 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 0308 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000B ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000B ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 0020 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 0308 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000B ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000B ÷ 00AB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00AB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000B ÷ 0308 × 00AB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00AB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000B ÷ 00BB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000B ÷ 0020 × 00BB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000B ÷ 0308 × 00BB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 00BB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000B ÷ 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000B ÷ 0020 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000B ÷ 0308 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000B ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000B ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000B ÷ 0308 × 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000B ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 0308 × 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000B ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 0020 ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 0308 × 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000B ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 0308 × 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000B ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0308 × 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000B ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 0020 ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000B ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0020 ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0308 × 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000B ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC ÷ 1B05 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× FFFC × 0020 ÷ 1B05 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× FFFC × 0308 ÷ 1B05 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× FFFC ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC × 0020 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC × 0308 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× FFFC ÷ 11003 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× FFFC × 0020 ÷ 11003 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× FFFC × 0308 ÷ 11003 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 11003 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× FFFC ÷ 1BC0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] BATAK LETTER A (AS) ÷ [0.3]
+× FFFC × 0020 ÷ 1BC0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× FFFC × 0308 ÷ 1BC0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] BATAK LETTER A (AS) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× FFFC ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] EM DASH (B2) ÷ [0.3]
+× FFFC × 0020 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× FFFC × 0308 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] EM DASH (B2) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× FFFC ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC × 0020 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC × 0308 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× FFFC ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 0020 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 0308 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× FFFC × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC × 0020 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC × 0308 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC × 0308 × 0020 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× FFFC ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 0020 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 0308 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0020 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0308 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 0308 × 0020 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× FFFC × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0020 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0308 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0308 × 0020 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× FFFC × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 0020 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 0308 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× FFFC × 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC × 0020 ÷ 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC × 0308 × 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× FFFC ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC × 0020 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC × 0308 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× FFFC ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC × 0020 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC × 0308 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× FFFC ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC × 0020 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC × 0308 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× FFFC ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC × 0020 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC × 0308 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× FFFC ÷ 1B50 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× FFFC × 0020 ÷ 1B50 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× FFFC × 0308 ÷ 1B50 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× FFFC ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 0020 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 0308 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× FFFC × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] COMMA (IS) ÷ [0.3]
+× FFFC × 0020 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× FFFC × 0308 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× FFFC × 0308 × 0020 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× FFFC ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC × 0020 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC × 0308 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× FFFC ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC × 0020 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC × 0308 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× FFFC ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 0020 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 0308 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× FFFC × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0020 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0308 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0308 × 0020 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× FFFC × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC × 0020 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC × 0308 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× FFFC ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC × 0020 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC × 0308 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× FFFC ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC × 0020 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC × 0308 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× FFFC ÷ 2329 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× FFFC × 0020 ÷ 2329 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× FFFC × 0308 ÷ 2329 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 2329 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× FFFC ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC × 0020 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC × 0308 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× FFFC ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0020 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0308 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× FFFC × 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0020 ÷ 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0308 × 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× FFFC × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 0020 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× FFFC × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 0020 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 0308 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× FFFC × 0308 × 0020 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× FFFC ÷ 1BF2 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× FFFC × 0020 ÷ 1BF2 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× FFFC × 0308 ÷ 1BF2 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× FFFC ÷ 1B44 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× FFFC × 0020 ÷ 1B44 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× FFFC × 0308 ÷ 1B44 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× FFFC × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 0020 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 0308 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 0308 × 0020 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× FFFC × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC × 0020 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC × 0308 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC × 0308 × 0020 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× FFFC ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC × 0020 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC × 0308 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× FFFC ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC × 0020 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC × 0308 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× FFFC ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0020 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0308 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× FFFC × 00AB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× FFFC × 0020 ÷ 00AB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× FFFC × 0308 × 00AB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00AB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× FFFC × 00BB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× FFFC × 0020 × 00BB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× FFFC × 0308 × 00BB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× FFFC × 0308 × 0020 × 00BB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× FFFC × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× FFFC × 0020 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× FFFC × 0308 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× FFFC × 0308 × 0020 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× FFFC ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× FFFC × 0020 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× FFFC × 0308 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× FFFC × 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 0020 ÷ 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 0308 × 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× FFFC × 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC × 0020 ÷ 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC × 0308 × 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× FFFC ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC × 0020 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC × 0308 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× FFFC ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC × 0020 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC × 0308 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× FFFC ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC × 0020 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC × 0308 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× FFFC ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC × 0020 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC × 0308 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× FFFC × 0308 × 0020 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D ÷ 1B05 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 007D × 0020 ÷ 1B05 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 007D × 0308 ÷ 1B05 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 007D ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D × 0020 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D × 0308 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 007D ÷ 11003 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 007D × 0020 ÷ 11003 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 007D × 0308 ÷ 11003 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 11003 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 007D ÷ 1BC0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 007D × 0020 ÷ 1BC0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 007D × 0308 ÷ 1BC0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 007D ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0020 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0308 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 007D × 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D × 0020 ÷ 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D × 0308 × 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 007D ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 0308 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 007D × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D × 0020 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D × 0308 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 007D ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 0020 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 0308 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 007D × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0020 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0308 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007D × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0020 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0308 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 007D × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 0020 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 0308 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 007D × 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D × 0308 × 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 007D ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D × 0020 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D × 0308 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 007D ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D × 0020 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D × 0308 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 007D ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 0308 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 007D × 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D × 0020 ÷ 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D × 0308 × 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 007D ÷ 1B50 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 007D × 0020 ÷ 1B50 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 007D × 0308 ÷ 1B50 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 007D × 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 0020 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 0308 × 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 007D × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] COMMA (IS) ÷ [0.3]
+× 007D × 0020 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 007D × 0308 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 007D × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 007D ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D × 0020 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D × 0308 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 007D ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D × 0308 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 007D ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 0020 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 0308 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 007D × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0020 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0308 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 007D × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 0020 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 0308 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 007D × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D × 0020 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D × 0308 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D × 0308 × 0020 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 007D ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D × 0020 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D × 0308 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 007D ÷ 2329 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 007D × 0020 ÷ 2329 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 007D × 0308 ÷ 2329 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 2329 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 007D ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D × 0020 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D × 0308 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 007D ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0020 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0308 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 007D × 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0020 ÷ 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0308 × 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 007D × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 0020 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 007D × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 007D × 0020 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 007D × 0308 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 007D × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 007D ÷ 1BF2 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 007D × 0020 ÷ 1BF2 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 007D × 0308 ÷ 1BF2 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 007D ÷ 1B44 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 007D × 0020 ÷ 1B44 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 007D × 0308 ÷ 1B44 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 007D × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 0020 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 0308 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 007D × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D × 0020 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D × 0308 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 007D ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D × 0308 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 007D ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D × 0020 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D × 0308 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 007D ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0308 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 007D × 00AB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 007D × 0020 ÷ 00AB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 007D × 0308 × 00AB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00AB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 007D × 00BB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 007D × 0020 × 00BB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 007D × 0308 × 00BB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 007D × 0308 × 0020 × 00BB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 007D × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 007D × 0020 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 007D × 0308 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 007D × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 007D ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 007D × 0020 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 007D × 0308 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 007D × 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 0020 ÷ 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 0308 × 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 007D × 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D × 0020 ÷ 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D × 0308 × 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 007D ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D × 0308 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 007D ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D × 0020 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D × 0308 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 007D ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 0308 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 007D × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D × 0020 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D × 0308 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 007D × 0308 × 0020 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 1B05 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1B05 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1B05 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000D ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 0308 × 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000D ÷ 11003 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000D ÷ 0020 ÷ 11003 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000D ÷ 0308 ÷ 11003 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 11003 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000D ÷ 1BC0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] BATAK LETTER A (AS) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1BC0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1BC0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000D ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0020 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0308 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000D ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 0308 × 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000D ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 0308 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000D ÷ 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ 0020 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ 0308 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000D ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 0020 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 0308 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000D ÷ 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0020 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0308 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000D ÷ 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0020 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0308 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000D ÷ 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 0020 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 0308 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000D ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ 0308 × 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000D ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ 0020 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ 0308 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000D ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 0020 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 0308 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000D ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 0308 × 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000D ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 0020 ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 0308 × 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000D ÷ 1B50 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1B50 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1B50 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000D ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 0020 ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 0308 × 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000D ÷ 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMMA (IS) ÷ [0.3]
+× 000D ÷ 0020 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000D ÷ 0308 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000D ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000D ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 0020 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 0308 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000D ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000D × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) × [5.01] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0020 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0308 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000D ÷ 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 0020 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 0308 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000D ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0020 ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0308 × 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000D ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0308 × 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000D ÷ 2329 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000D ÷ 0020 ÷ 2329 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000D ÷ 0308 ÷ 2329 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 2329 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000D ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0308 × 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000D ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0308 × 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000D ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0308 × 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000D ÷ 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [0.3]
+× 000D ÷ 0020 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000D ÷ 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 0020 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 0308 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000D ÷ 1BF2 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1BF2 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1BF2 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000D ÷ 1B44 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1B44 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1B44 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000D ÷ 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 0020 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 0308 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000D ÷ 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 0020 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 0308 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000D ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000D ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 0020 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 0308 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000D ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000D ÷ 00AB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00AB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000D ÷ 0308 × 00AB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00AB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000D ÷ 00BB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000D ÷ 0020 × 00BB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000D ÷ 0308 × 00BB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 00BB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000D ÷ 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000D ÷ 0020 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000D ÷ 0308 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000D ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000D ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000D ÷ 0308 × 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000D ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 0308 × 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000D ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 0020 ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 0308 × 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000D ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 0308 × 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000D ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0308 × 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000D ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 0020 ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000D ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0020 ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0308 × 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 ÷ 1B05 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0021 × 0020 ÷ 1B05 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0021 × 0308 ÷ 1B05 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0021 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 × 0020 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 × 0308 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0021 ÷ 11003 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0021 × 0020 ÷ 11003 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0021 × 0308 ÷ 11003 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0021 ÷ 1BC0 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0021 × 0020 ÷ 1BC0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0021 × 0308 ÷ 1BC0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0021 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0020 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0308 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0021 × 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 × 0020 ÷ 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 × 0308 × 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0021 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 0020 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 0308 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0021 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 × 0020 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 × 0308 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 × 0308 × 0020 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0021 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 0020 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 0308 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0021 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0020 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0308 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 0308 × 0020 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0021 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0020 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0308 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0308 × 0020 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0021 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 0020 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 0308 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0021 × 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 × 0020 ÷ 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 × 0308 × 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0021 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 × 0020 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 × 0308 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0021 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 × 0020 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 × 0308 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0021 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 0020 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 0308 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0021 × 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 × 0020 ÷ 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 × 0308 × 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0021 ÷ 1B50 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0021 × 0020 ÷ 1B50 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0021 × 0308 ÷ 1B50 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0021 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 0020 ÷ 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 0308 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] COMMA (IS) ÷ [0.3]
+× 0021 × 0020 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0021 × 0308 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0021 × 0308 × 0020 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0021 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 × 0020 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 × 0308 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0021 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 × 0020 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 × 0308 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0021 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 0020 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 0308 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0021 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0020 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0308 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0308 × 0020 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0021 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 0020 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 0308 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0021 × 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 × 0020 ÷ 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 × 0308 × 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0021 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 × 0020 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 × 0308 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0021 ÷ 2329 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0021 × 0020 ÷ 2329 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0021 × 0308 ÷ 2329 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0021 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 × 0020 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 × 0308 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0021 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0020 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0308 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0021 × 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0020 ÷ 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0308 × 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0021 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 0020 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0021 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 0020 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 0308 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0021 × 0308 × 0020 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0021 ÷ 1BF2 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0021 × 0020 ÷ 1BF2 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0021 × 0308 ÷ 1BF2 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0021 ÷ 1B44 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0021 × 0020 ÷ 1B44 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0021 × 0308 ÷ 1B44 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0021 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 0020 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 0308 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 0308 × 0020 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0021 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 × 0020 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 × 0308 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 × 0308 × 0020 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0021 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 × 0020 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 × 0308 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0021 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 × 0020 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 × 0308 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0021 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0020 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0308 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0021 × 00AB ÷ # × [0.3] EXCLAMATION MARK (EX) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0021 × 0020 ÷ 00AB ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0021 × 0308 × 00AB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0021 × 00BB ÷ # × [0.3] EXCLAMATION MARK (EX) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0021 × 0020 × 00BB ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0021 × 0308 × 00BB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0021 × 0308 × 0020 × 00BB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0021 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0021 × 0020 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0021 × 0308 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0021 × 0308 × 0020 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0021 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0021 × 0020 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0021 × 0308 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0021 × 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 0020 ÷ 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 0308 × 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0021 × 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 × 0020 ÷ 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 × 0308 × 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0021 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 × 0020 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 × 0308 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0021 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 × 0020 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 × 0308 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0021 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 0020 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 0308 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0021 × 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 × 0020 ÷ 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 × 0308 × 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0021 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 1B05 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A0 × 0020 ÷ 1B05 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A0 × 0308 × 1B05 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A0 × 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 0308 × 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A0 × 11003 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A0 × 0020 ÷ 11003 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A0 × 0308 × 11003 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A0 × 1BC0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A0 × 0020 ÷ 1BC0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A0 × 0308 × 1BC0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A0 × 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0020 ÷ 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0308 × 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A0 × 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 0020 ÷ 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 0308 × 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A0 × 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 0020 ÷ 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 0308 × 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A0 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × 0020 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × 0308 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A0 × FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 0020 ÷ FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 0308 × FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A0 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0020 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0308 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A0 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0020 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0308 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A0 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 0020 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 0308 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A0 × 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × 0020 ÷ 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × 0308 × 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A0 × AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × 0020 ÷ AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × 0308 × AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A0 × AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 0020 ÷ AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 0308 × AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A0 × 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 0020 ÷ 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 0308 × 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A0 × 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 0020 ÷ 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 0308 × 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A0 × 1B50 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A0 × 0020 ÷ 1B50 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A0 × 0308 × 1B50 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A0 × 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 0020 ÷ 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 0308 × 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A0 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] COMMA (IS) ÷ [0.3]
+× 00A0 × 0020 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A0 × 0308 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] COMMA (IS) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A0 × 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 0020 ÷ 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 0308 × 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A0 × 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 0020 ÷ 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 0308 × 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A0 × 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 0020 ÷ 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 0308 × 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A0 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0020 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0308 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A0 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 0020 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 0308 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A0 × 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0020 ÷ 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0308 × 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A0 × 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0020 ÷ 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0308 × 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A0 × 2329 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A0 × 0020 ÷ 2329 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A0 × 0308 × 2329 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A0 × 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0020 ÷ 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0308 × 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A0 × 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0020 ÷ 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0308 × 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A0 × 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0020 ÷ 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0308 × 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A0 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 0020 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A0 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 0020 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 0308 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A0 × 1BF2 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A0 × 0020 ÷ 1BF2 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A0 × 0308 × 1BF2 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A0 × 1B44 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A0 × 0020 ÷ 1B44 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A0 × 0308 × 1B44 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A0 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 0020 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 0308 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A0 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 0020 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 0308 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A0 × 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 0020 ÷ 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 0308 × 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A0 × 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 0020 ÷ 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 0308 × 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A0 × 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0020 ÷ 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0308 × 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A0 × 00AB ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A0 × 0020 ÷ 00AB ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A0 × 0308 × 00AB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A0 × 00BB ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A0 × 0020 × 00BB ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A0 × 0308 × 00BB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 00BB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A0 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A0 × 0020 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A0 × 0308 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A0 × 0308 × 0020 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A0 × 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A0 × 0020 ÷ 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A0 × 0308 × 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A0 × 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 0020 ÷ 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 0308 × 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A0 × 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 0020 ÷ 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 0308 × 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A0 × 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 0308 × 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A0 × 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0308 × 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A0 × 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 0020 ÷ 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 0308 × 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A0 × 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0020 ÷ 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0308 × 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC00 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC00 × 0308 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC00 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC00 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC00 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC00 × 0308 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC00 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC00 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC00 × 0308 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC00 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC00 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 × 0308 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC00 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC00 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 × 0308 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC00 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC00 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0308 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC00 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0308 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC00 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 0308 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC00 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 × 0308 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC00 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC00 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC00 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC00 × 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 × 0308 × 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC00 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC00 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC00 × 0308 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC00 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 0308 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC00 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] COMMA (IS) ÷ [0.3]
+× AC00 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC00 × 0308 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× AC00 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC00 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC00 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 0308 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC00 × 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 0308 × 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC00 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0308 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC00 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 0308 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC00 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 × 0308 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC00 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC00 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC00 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC00 × 0308 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC00 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 × 0308 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC00 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC00 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0308 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC00 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC00 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 0308 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× AC00 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC00 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC00 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC00 × 0308 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC00 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC00 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC00 × 0308 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC00 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 0308 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC00 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 × 0308 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC00 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC00 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 × 0308 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC00 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC00 × 00AB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC00 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC00 × 0308 × 00AB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC00 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC00 × 0020 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC00 × 0308 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC00 × 0308 × 0020 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC00 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC00 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC00 × 0308 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC00 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC00 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC00 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC00 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC00 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 0308 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC00 × 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 × 0308 × 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC00 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC00 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC00 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC00 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 × 0308 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC00 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC01 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC01 × 0308 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× AC01 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× AC01 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC01 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC01 × 0308 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× AC01 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC01 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC01 × 0308 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× AC01 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× AC01 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 × 0308 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× AC01 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× AC01 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 × 0308 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× AC01 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× AC01 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0308 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× AC01 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0308 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× AC01 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 0308 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× AC01 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 × 0308 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× AC01 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× AC01 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× AC01 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× AC01 × 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 × 0308 × 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× AC01 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC01 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC01 × 0308 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× AC01 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 0308 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× AC01 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] COMMA (IS) ÷ [0.3]
+× AC01 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC01 × 0308 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× AC01 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× AC01 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× AC01 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 × 0308 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× AC01 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 0308 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× AC01 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0308 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× AC01 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 0308 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× AC01 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 × 0308 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× AC01 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× AC01 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC01 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC01 × 0308 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× AC01 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 × 0308 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× AC01 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× AC01 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0308 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× AC01 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× AC01 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 0308 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× AC01 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× AC01 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC01 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC01 × 0308 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× AC01 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC01 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC01 × 0308 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× AC01 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 0308 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× AC01 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 × 0308 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× AC01 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× AC01 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 × 0308 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× AC01 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× AC01 × 00AB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC01 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC01 × 0308 × 00AB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× AC01 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC01 × 0020 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC01 × 0308 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC01 × 0308 × 0020 × 00BB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× AC01 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC01 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC01 × 0308 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC01 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× AC01 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC01 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC01 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× AC01 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 0308 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× AC01 × 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 × 0308 × 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× AC01 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× AC01 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× AC01 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× AC01 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 × 0308 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× AC01 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 ÷ 1B05 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 05D0 × 0020 ÷ 1B05 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 05D0 × 0308 ÷ 1B05 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 05D0 × 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 × 0308 × 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 05D0 ÷ 11003 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 05D0 × 0020 ÷ 11003 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 05D0 × 0308 ÷ 11003 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 05D0 ÷ 1BC0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 05D0 × 0020 ÷ 1BC0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 05D0 × 0308 ÷ 1BC0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 05D0 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0020 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0308 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 05D0 × 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 × 0020 ÷ 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 × 0308 × 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 05D0 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 0020 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 0308 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 05D0 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 × 0020 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 × 0308 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 05D0 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 0020 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 0308 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 05D0 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0020 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0308 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 05D0 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0020 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0308 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 05D0 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 0020 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 0308 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 05D0 × 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 × 0020 ÷ 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 × 0308 × 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 05D0 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 × 0020 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 × 0308 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 05D0 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 0020 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 0308 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 05D0 × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 0020 ÷ 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 0308 × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 05D0 × 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 × 0020 ÷ 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 × 0308 × 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 05D0 ÷ 1B50 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 05D0 × 0020 ÷ 1B50 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 05D0 × 0308 ÷ 1B50 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 05D0 × 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 0020 ÷ 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 0308 × 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 05D0 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] COMMA (IS) ÷ [0.3]
+× 05D0 × 0020 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 05D0 × 0308 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 05D0 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 × 0020 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 × 0308 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 05D0 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 × 0020 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 × 0308 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 05D0 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 0020 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 0308 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 05D0 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0020 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0308 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 05D0 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 0020 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 0308 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 05D0 × 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0020 ÷ 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0308 × 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 05D0 × 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0020 ÷ 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0308 × 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 05D0 ÷ 2329 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 05D0 × 0020 ÷ 2329 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 05D0 × 0308 ÷ 2329 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 05D0 × 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0020 ÷ 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0308 × 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 05D0 × 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0020 ÷ 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0308 × 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 05D0 × 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0020 ÷ 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0308 × 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 05D0 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 0020 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 05D0 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 0020 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 0308 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 05D0 ÷ 1BF2 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 05D0 × 0020 ÷ 1BF2 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 05D0 × 0308 ÷ 1BF2 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 05D0 ÷ 1B44 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 05D0 × 0020 ÷ 1B44 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 05D0 × 0308 ÷ 1B44 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 05D0 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 0020 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 0308 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 05D0 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 × 0020 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 × 0308 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 05D0 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 × 0020 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 × 0308 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 05D0 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 × 0020 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 × 0308 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 05D0 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0020 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0308 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 05D0 × 00AB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 05D0 × 0020 ÷ 00AB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 05D0 × 0308 × 00AB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 05D0 × 00BB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 05D0 × 0020 × 00BB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 05D0 × 0308 × 00BB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 00BB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 05D0 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 05D0 × 0020 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 05D0 × 0308 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 05D0 × 0308 × 0020 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 05D0 × 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 05D0 × 0020 ÷ 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 05D0 × 0308 × 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 05D0 × 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 0020 ÷ 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 0308 × 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 05D0 × 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 0020 ÷ 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 0308 × 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 05D0 × 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 0308 × 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 05D0 × 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0308 × 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 05D0 × 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 0020 ÷ 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 0308 × 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 05D0 × 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0020 ÷ 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0308 × 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 05D0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D ÷ 1B05 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002D × 0020 ÷ 1B05 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002D × 0308 ÷ 1B05 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002D ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D × 0020 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D × 0308 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002D ÷ 11003 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002D × 0020 ÷ 11003 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002D × 0308 ÷ 11003 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002D ÷ 1BC0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002D × 0020 ÷ 1BC0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002D × 0308 ÷ 1BC0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002D ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0020 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0308 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002D × 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D × 0020 ÷ 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D × 0308 × 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002D ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 0020 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 0308 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002D × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D × 0020 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D × 0308 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D × 0308 × 0020 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002D ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 0020 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 0308 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002D × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0020 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0308 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 0308 × 0020 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002D × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0020 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0308 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0308 × 0020 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002D × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D × 0020 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D × 0308 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D × 0308 × 0020 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002D ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D × 0020 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D × 0308 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002D ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D × 0020 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D × 0308 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002D ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D × 0020 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D × 0308 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002D ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 0020 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 0308 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002D × 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D × 0020 ÷ 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D × 0308 × 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002D ÷ 1B50 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002D × 0020 ÷ 1B50 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002D × 0308 ÷ 1B50 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002D × 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 0020 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 0308 × 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002D × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] COMMA (IS) ÷ [0.3]
+× 002D × 0020 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002D × 0308 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 002D × 0308 × 0020 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002D ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D × 0020 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D × 0308 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002D ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D × 0020 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D × 0308 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002D ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 0020 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 0308 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002D × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0020 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0308 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0308 × 0020 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002D × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 0020 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 0308 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 0308 × 0020 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002D × 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0020 ÷ 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0308 × 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002D × 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [25.02] DIGIT ZERO (NU) ÷ [0.3]
+× 002D × 0020 ÷ 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002D × 0308 × 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.02] DIGIT ZERO (NU) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002D ÷ 2329 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002D × 0020 ÷ 2329 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002D × 0308 ÷ 2329 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002D ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D × 0020 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D × 0308 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002D ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0020 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0308 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002D × 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0020 ÷ 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0308 × 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002D × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 0020 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 0308 × 0020 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002D × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002D × 0020 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002D × 0308 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 002D × 0308 × 0020 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002D ÷ 1BF2 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002D × 0020 ÷ 1BF2 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002D × 0308 ÷ 1BF2 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002D ÷ 1B44 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002D × 0020 ÷ 1B44 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002D × 0308 ÷ 1B44 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002D × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 0020 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 0308 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 0308 × 0020 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002D × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D × 0020 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D × 0308 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D × 0308 × 0020 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002D ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D × 0020 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D × 0308 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002D ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D × 0020 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D × 0308 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002D ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0020 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0308 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002D × 00AB ÷ # × [0.3] HYPHEN-MINUS (HY) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002D × 0020 ÷ 00AB ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002D × 0308 × 00AB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002D × 00BB ÷ # × [0.3] HYPHEN-MINUS (HY) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002D × 0020 × 00BB ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002D × 0308 × 00BB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002D × 0308 × 0020 × 00BB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002D × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002D × 0020 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002D × 0308 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002D × 0308 × 0020 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002D ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002D × 0020 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002D × 0308 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002D × 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 0020 ÷ 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 0308 × 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002D × 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D × 0020 ÷ 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D × 0308 × 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002D ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D × 0020 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D × 0308 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002D ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D × 0020 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D × 0308 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002D ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 0020 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 0308 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002D × 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D × 0020 ÷ 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D × 0308 × 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B50 ÷ 1B05 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B50 × 0020 ÷ 1B05 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B50 × 0308 ÷ 1B05 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B50 ÷ 0023 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B50 × 0020 ÷ 0023 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B50 × 0308 ÷ 0023 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B50 ÷ 11003 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B50 × 0020 ÷ 11003 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B50 × 0308 ÷ 11003 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B50 ÷ 1BC0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B50 × 0020 ÷ 1BC0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B50 × 0308 ÷ 1BC0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B50 ÷ 2014 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1B50 × 0020 ÷ 2014 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1B50 × 0308 ÷ 2014 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1B50 × 0009 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B50 × 0020 ÷ 0009 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B50 × 0308 × 0009 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B50 ÷ 00B4 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B50 × 0020 ÷ 00B4 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B50 × 0308 ÷ 00B4 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B50 × 000B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B50 × 0020 × 000B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B50 × 0308 × 000B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 000B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B50 ÷ FFFC ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B50 × 0020 ÷ FFFC ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B50 × 0308 ÷ FFFC ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B50 × 007D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B50 × 0020 × 007D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B50 × 0308 × 007D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 007D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B50 × 000D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B50 × 0020 × 000D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B50 × 0308 × 000D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 000D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B50 × 0021 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B50 × 0020 × 0021 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B50 × 0308 × 0021 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 0021 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B50 × 00A0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B50 × 0020 ÷ 00A0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B50 × 0308 × 00A0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B50 ÷ AC00 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B50 × 0020 ÷ AC00 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B50 × 0308 ÷ AC00 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B50 ÷ AC01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B50 × 0020 ÷ AC01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B50 × 0308 ÷ AC01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B50 ÷ 05D0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B50 × 0020 ÷ 05D0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B50 × 0308 ÷ 05D0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B50 × 002D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B50 × 0020 ÷ 002D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B50 × 0308 × 002D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 002D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B50 ÷ 1B50 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B50 × 0020 ÷ 1B50 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B50 × 0308 ÷ 1B50 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B50 × 2024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B50 × 0020 ÷ 2024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B50 × 0308 × 2024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B50 × 002C ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B50 × 0020 × 002C ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B50 × 0308 × 002C ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 002C ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B50 ÷ 1100 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B50 × 0020 ÷ 1100 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B50 × 0308 ÷ 1100 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B50 ÷ 11A8 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B50 × 0020 ÷ 11A8 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B50 × 0308 ÷ 11A8 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B50 ÷ 1160 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B50 × 0020 ÷ 1160 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B50 × 0308 ÷ 1160 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B50 × 000A ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B50 × 0020 × 000A ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B50 × 0308 × 000A ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 000A ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B50 × 0085 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B50 × 0020 × 0085 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B50 × 0308 × 0085 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 0085 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B50 × 17D6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B50 × 0020 ÷ 17D6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B50 × 0308 × 17D6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B50 ÷ 0030 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B50 × 0020 ÷ 0030 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B50 × 0308 ÷ 0030 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B50 ÷ 2329 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B50 × 0020 ÷ 2329 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B50 × 0308 ÷ 2329 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B50 × 0025 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 1B50 × 0020 ÷ 0025 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B50 × 0308 × 0025 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B50 ÷ 0024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B50 × 0020 ÷ 0024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B50 × 0308 ÷ 0024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B50 × 0022 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1B50 × 0020 ÷ 0022 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1B50 × 0308 × 0022 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1B50 × 0020 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B50 × 0020 × 0020 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 0020 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B50 × 002F ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B50 × 0020 × 002F ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B50 × 0308 × 002F ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 002F ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B50 ÷ 1BF2 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B50 × 0020 ÷ 1BF2 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B50 × 0308 ÷ 1BF2 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B50 ÷ 1B44 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B50 × 0020 ÷ 1B44 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B50 × 0308 ÷ 1B44 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B50 × 2060 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B50 × 0020 × 2060 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B50 × 0308 × 2060 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 2060 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B50 × 200B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B50 × 0020 × 200B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B50 × 0308 × 200B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 200B ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B50 ÷ 1F1E6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B50 × 0020 ÷ 1F1E6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B50 × 0308 ÷ 1F1E6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B50 ÷ 261D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B50 × 0020 ÷ 261D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B50 × 0308 ÷ 261D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 261D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B50 ÷ 1F3FB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B50 × 0020 ÷ 1F3FB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B50 × 0308 ÷ 1F3FB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B50 × 00AB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B50 × 0020 ÷ 00AB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B50 × 0308 × 00AB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B50 × 00BB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B50 × 0020 × 00BB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B50 × 0308 × 00BB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 00BB ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B50 × 0029 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B50 × 0020 × 0029 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B50 × 0308 × 0029 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B50 × 0308 × 0020 × 0029 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B50 ÷ 0028 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B50 × 0020 ÷ 0028 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B50 × 0308 ÷ 0028 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B50 × 0001 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B50 × 0020 ÷ 0001 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B50 × 0308 × 0001 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B50 × 200D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B50 × 0020 ÷ 200D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B50 × 0308 × 200D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 200D ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B50 ÷ 00A7 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B50 × 0020 ÷ 00A7 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B50 × 0308 ÷ 00A7 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B50 ÷ 50005 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B50 × 0020 ÷ 50005 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B50 × 0308 ÷ 50005 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B50 ÷ 0E01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B50 × 0020 ÷ 0E01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B50 × 0308 ÷ 0E01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B50 × 3041 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B50 × 0020 ÷ 3041 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B50 × 0308 × 3041 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B50 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] BALINESE DIGIT ZERO (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 ÷ 1B05 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2024 × 0020 ÷ 1B05 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2024 × 0308 ÷ 1B05 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2024 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 × 0020 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 × 0308 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2024 ÷ 11003 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2024 × 0020 ÷ 11003 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2024 × 0308 ÷ 11003 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2024 ÷ 1BC0 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2024 × 0020 ÷ 1BC0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2024 × 0308 ÷ 1BC0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2024 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0020 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0308 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2024 × 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 × 0020 ÷ 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 × 0308 × 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2024 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 0020 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 0308 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2024 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 × 0020 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 × 0308 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 × 0308 × 0020 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2024 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 0020 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 0308 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2024 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0020 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0308 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 0308 × 0020 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2024 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0020 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0308 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0308 × 0020 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2024 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 0020 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 0308 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2024 × 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 × 0020 ÷ 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 × 0308 × 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2024 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 × 0020 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 × 0308 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2024 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 × 0020 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 × 0308 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2024 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 0020 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 0308 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2024 × 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 × 0020 ÷ 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 × 0308 × 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2024 ÷ 1B50 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2024 × 0020 ÷ 1B50 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2024 × 0308 ÷ 1B50 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2024 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 0020 ÷ 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 0308 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] COMMA (IS) ÷ [0.3]
+× 2024 × 0020 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2024 × 0308 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 2024 × 0308 × 0020 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2024 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 × 0020 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 × 0308 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2024 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 × 0020 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 × 0308 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2024 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 0020 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 0308 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2024 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0020 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0308 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0308 × 0020 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2024 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 0020 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 0308 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2024 × 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 × 0020 ÷ 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 × 0308 × 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2024 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 × 0020 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 × 0308 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2024 ÷ 2329 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2024 × 0020 ÷ 2329 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2024 × 0308 ÷ 2329 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2024 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 × 0020 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 × 0308 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2024 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0020 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0308 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2024 × 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0020 ÷ 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0308 × 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2024 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 0020 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2024 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 0020 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 0308 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 2024 × 0308 × 0020 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2024 ÷ 1BF2 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2024 × 0020 ÷ 1BF2 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2024 × 0308 ÷ 1BF2 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2024 ÷ 1B44 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2024 × 0020 ÷ 1B44 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2024 × 0308 ÷ 1B44 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2024 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 0020 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 0308 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 0308 × 0020 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2024 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 × 0020 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 × 0308 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 × 0308 × 0020 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2024 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 × 0020 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 × 0308 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2024 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 × 0020 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 × 0308 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2024 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0020 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0308 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2024 × 00AB ÷ # × [0.3] ONE DOT LEADER (IN) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2024 × 0020 ÷ 00AB ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2024 × 0308 × 00AB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2024 × 00BB ÷ # × [0.3] ONE DOT LEADER (IN) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2024 × 0020 × 00BB ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2024 × 0308 × 00BB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2024 × 0308 × 0020 × 00BB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2024 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2024 × 0020 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2024 × 0308 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2024 × 0308 × 0020 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2024 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2024 × 0020 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2024 × 0308 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2024 × 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 0020 ÷ 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 0308 × 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2024 × 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 × 0020 ÷ 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 × 0308 × 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2024 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 × 0020 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 × 0308 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2024 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 × 0020 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 × 0308 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2024 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 0020 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 0308 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2024 × 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 × 0020 ÷ 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 × 0308 × 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2024 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C ÷ 1B05 ÷ # × [0.3] COMMA (IS) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002C × 0020 ÷ 1B05 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002C × 0308 ÷ 1B05 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002C × 0023 ÷ # × [0.3] COMMA (IS) × [29.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C × 0020 ÷ 0023 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C × 0308 × 0023 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0023 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002C ÷ 11003 ÷ # × [0.3] COMMA (IS) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002C × 0020 ÷ 11003 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002C × 0308 ÷ 11003 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 11003 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002C ÷ 1BC0 ÷ # × [0.3] COMMA (IS) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002C × 0020 ÷ 1BC0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002C × 0308 ÷ 1BC0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002C ÷ 2014 ÷ # × [0.3] COMMA (IS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0020 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0308 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002C × 0009 ÷ # × [0.3] COMMA (IS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C × 0020 ÷ 0009 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C × 0308 × 0009 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0009 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002C ÷ 00B4 ÷ # × [0.3] COMMA (IS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 0020 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 0308 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002C × 000B ÷ # × [0.3] COMMA (IS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C × 0020 × 000B ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C × 0308 × 000B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C × 0308 × 0020 × 000B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002C ÷ FFFC ÷ # × [0.3] COMMA (IS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 0020 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 0308 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002C × 007D ÷ # × [0.3] COMMA (IS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0020 × 007D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0308 × 007D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 0308 × 0020 × 007D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002C × 000D ÷ # × [0.3] COMMA (IS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0020 × 000D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0308 × 000D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0308 × 0020 × 000D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002C × 0021 ÷ # × [0.3] COMMA (IS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 0020 × 0021 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 0308 × 0021 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 0308 × 0020 × 0021 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002C × 00A0 ÷ # × [0.3] COMMA (IS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C × 0020 ÷ 00A0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C × 0308 × 00A0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002C ÷ AC00 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C × 0020 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C × 0308 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002C ÷ AC01 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 0020 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 0308 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002C × 05D0 ÷ # × [0.3] COMMA (IS) × [29.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 0020 ÷ 05D0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 0308 × 05D0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002C × 002D ÷ # × [0.3] COMMA (IS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C × 0020 ÷ 002D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C × 0308 × 002D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 002D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002C ÷ 1B50 ÷ # × [0.3] COMMA (IS) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002C × 0020 ÷ 1B50 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002C × 0308 ÷ 1B50 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002C × 2024 ÷ # × [0.3] COMMA (IS) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 0020 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 0308 × 2024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002C × 002C ÷ # × [0.3] COMMA (IS) × [13.02] COMMA (IS) ÷ [0.3]
+× 002C × 0020 × 002C ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002C × 0308 × 002C ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 002C × 0308 × 0020 × 002C ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002C ÷ 1100 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C × 0020 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C × 0308 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002C ÷ 11A8 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C × 0020 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C × 0308 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002C ÷ 1160 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 0020 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 0308 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002C × 000A ÷ # × [0.3] COMMA (IS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0020 × 000A ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0308 × 000A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0308 × 0020 × 000A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002C × 0085 ÷ # × [0.3] COMMA (IS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 0020 × 0085 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 0308 × 0085 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 0308 × 0020 × 0085 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002C × 17D6 ÷ # × [0.3] COMMA (IS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C × 0020 ÷ 17D6 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C × 0308 × 17D6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002C ÷ 0030 ÷ # × [0.3] COMMA (IS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C × 0020 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C × 0308 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002C ÷ 2329 ÷ # × [0.3] COMMA (IS) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002C × 0020 ÷ 2329 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002C × 0308 ÷ 2329 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 2329 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002C ÷ 0025 ÷ # × [0.3] COMMA (IS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C × 0020 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C × 0308 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002C ÷ 0024 ÷ # × [0.3] COMMA (IS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0020 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0308 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002C × 0022 ÷ # × [0.3] COMMA (IS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0020 ÷ 0022 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0308 × 0022 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0022 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002C × 0020 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 0020 × 0020 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 0308 × 0020 × 0020 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002C × 002F ÷ # × [0.3] COMMA (IS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002C × 0020 × 002F ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002C × 0308 × 002F ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 002C × 0308 × 0020 × 002F ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002C ÷ 1BF2 ÷ # × [0.3] COMMA (IS) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002C × 0020 ÷ 1BF2 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002C × 0308 ÷ 1BF2 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002C ÷ 1B44 ÷ # × [0.3] COMMA (IS) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002C × 0020 ÷ 1B44 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002C × 0308 ÷ 1B44 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002C × 2060 ÷ # × [0.3] COMMA (IS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 0020 × 2060 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 0308 × 2060 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 0308 × 0020 × 2060 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002C × 200B ÷ # × [0.3] COMMA (IS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C × 0020 × 200B ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C × 0308 × 200B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C × 0308 × 0020 × 200B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002C ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C × 0020 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C × 0308 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002C ÷ 261D ÷ # × [0.3] COMMA (IS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C × 0020 ÷ 261D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C × 0308 ÷ 261D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 261D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002C ÷ 1F3FB ÷ # × [0.3] COMMA (IS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0020 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0308 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002C × 00AB ÷ # × [0.3] COMMA (IS) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002C × 0020 ÷ 00AB ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002C × 0308 × 00AB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00AB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002C × 00BB ÷ # × [0.3] COMMA (IS) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002C × 0020 × 00BB ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002C × 0308 × 00BB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002C × 0308 × 0020 × 00BB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002C × 0029 ÷ # × [0.3] COMMA (IS) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002C × 0020 × 0029 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002C × 0308 × 0029 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002C × 0308 × 0020 × 0029 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002C ÷ 0028 ÷ # × [0.3] COMMA (IS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002C × 0020 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002C × 0308 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002C × 0001 ÷ # × [0.3] COMMA (IS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 0020 ÷ 0001 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 0308 × 0001 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0001 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002C × 200D ÷ # × [0.3] COMMA (IS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 0020 ÷ 200D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 0308 × 200D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 200D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002C × 00A7 ÷ # × [0.3] COMMA (IS) × [29.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 0020 ÷ 00A7 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 0308 × 00A7 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002C × 50005 ÷ # × [0.3] COMMA (IS) × [29.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0020 ÷ 50005 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0308 × 50005 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 50005 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002C × 0E01 ÷ # × [0.3] COMMA (IS) × [29.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 0020 ÷ 0E01 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 0308 × 0E01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002C × 3041 ÷ # × [0.3] COMMA (IS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0020 ÷ 3041 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0308 × 3041 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002C × 0308 × 0020 ÷ 3041 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 ÷ 1B05 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1100 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1100 × 0308 ÷ 1B05 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1100 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1100 ÷ 11003 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1100 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1100 × 0308 ÷ 11003 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1100 ÷ 1BC0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1100 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1100 × 0308 ÷ 1BC0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1100 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1100 × 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 × 0308 × 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1100 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1100 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 × 0020 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 × 0308 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1100 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1100 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0020 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0308 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1100 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0020 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0308 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1100 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 0020 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 0308 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1100 × 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × 0308 × 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1100 × AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × 0308 × AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1100 × AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 × 0308 × AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1100 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1100 × 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 × 0020 ÷ 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 × 0308 × 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1100 ÷ 1B50 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1100 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1100 × 0308 ÷ 1B50 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1100 × 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 0308 × 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1100 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] COMMA (IS) ÷ [0.3]
+× 1100 × 0020 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1100 × 0308 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1100 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1100 × 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 × 0308 × 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1100 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 0308 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1100 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 0308 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1100 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0020 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0308 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1100 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 0020 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 0308 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1100 × 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 × 0308 × 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1100 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1100 ÷ 2329 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1100 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1100 × 0308 ÷ 2329 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1100 × 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 × 0308 × 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1100 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1100 × 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0308 × 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1100 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 0020 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1100 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 0020 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 0308 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1100 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1100 ÷ 1BF2 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1100 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1100 × 0308 ÷ 1BF2 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1100 ÷ 1B44 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1100 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1100 × 0308 ÷ 1B44 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1100 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 0020 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 0308 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1100 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 × 0020 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 × 0308 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1100 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1100 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 × 0020 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 × 0308 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1100 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1100 × 00AB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1100 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1100 × 0308 × 00AB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1100 × 00BB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1100 × 0020 × 00BB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1100 × 0308 × 00BB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1100 × 0308 × 0020 × 00BB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1100 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1100 × 0020 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1100 × 0308 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1100 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1100 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1100 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1100 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1100 × 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 0308 × 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1100 × 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 × 0020 ÷ 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 × 0308 × 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1100 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1100 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1100 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 × 0308 × 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1100 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 ÷ 1B05 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11A8 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11A8 × 0308 ÷ 1B05 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 11A8 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 11A8 ÷ 11003 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11A8 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11A8 × 0308 ÷ 11003 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 11A8 ÷ 1BC0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 11A8 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 11A8 × 0308 ÷ 1BC0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 11A8 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 11A8 × 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 × 0308 × 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 11A8 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 11A8 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 × 0020 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 × 0308 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 11A8 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 11A8 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0020 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0308 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 11A8 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0020 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0308 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 11A8 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 0020 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 0308 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 11A8 × 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 × 0308 × 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 11A8 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 11A8 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 11A8 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11A8 × 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 × 0308 × 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 11A8 ÷ 1B50 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11A8 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11A8 × 0308 ÷ 1B50 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 11A8 × 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 0308 × 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 11A8 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] COMMA (IS) ÷ [0.3]
+× 11A8 × 0020 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11A8 × 0308 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 11A8 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 11A8 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 × 0308 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 11A8 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 0308 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0020 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0308 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 11A8 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 0020 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 0308 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 11A8 × 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 × 0308 × 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 11A8 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 11A8 ÷ 2329 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11A8 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11A8 × 0308 ÷ 2329 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 11A8 × 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 × 0308 × 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 11A8 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 11A8 × 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0308 × 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 11A8 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 0020 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 11A8 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 0020 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 0308 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 11A8 ÷ 1BF2 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11A8 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11A8 × 0308 ÷ 1BF2 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 11A8 ÷ 1B44 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11A8 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11A8 × 0308 ÷ 1B44 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 11A8 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 0020 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 0308 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 11A8 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 × 0020 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 × 0308 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 11A8 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 11A8 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 × 0308 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 11A8 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 11A8 × 00AB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11A8 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11A8 × 0308 × 00AB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 11A8 × 00BB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11A8 × 0020 × 00BB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11A8 × 0308 × 00BB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 00BB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 11A8 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11A8 × 0020 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11A8 × 0308 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11A8 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 11A8 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11A8 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11A8 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 11A8 × 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 0308 × 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 11A8 × 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 × 0308 × 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 11A8 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 11A8 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 11A8 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 11A8 × 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 × 0308 × 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 11A8 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 ÷ 1B05 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1160 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1160 × 0308 ÷ 1B05 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1160 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1160 ÷ 11003 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1160 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1160 × 0308 ÷ 11003 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1160 ÷ 1BC0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1160 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1160 × 0308 ÷ 1BC0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1160 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1160 × 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 × 0308 × 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1160 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1160 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 × 0020 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 × 0308 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1160 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1160 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0020 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0308 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1160 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0020 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0308 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1160 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 0020 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 0308 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1160 × 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 × 0308 × 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1160 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1160 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1160 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1160 × 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 × 0308 × 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1160 ÷ 1B50 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1160 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1160 × 0308 ÷ 1B50 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1160 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0308 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] COMMA (IS) ÷ [0.3]
+× 1160 × 0020 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1160 × 0308 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1160 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1160 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1160 × 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 0308 × 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 0308 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0020 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0308 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1160 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 0020 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 0308 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1160 × 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 × 0308 × 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1160 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1160 ÷ 2329 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1160 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1160 × 0308 ÷ 2329 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1160 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 × 0308 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1160 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1160 × 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0308 × 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1160 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 0020 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1160 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 0020 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 0308 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1160 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1160 ÷ 1BF2 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1160 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1160 × 0308 ÷ 1BF2 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1160 ÷ 1B44 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1160 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1160 × 0308 ÷ 1B44 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1160 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 0020 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 0308 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1160 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 × 0020 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 × 0308 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1160 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1160 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 × 0308 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1160 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1160 × 00AB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1160 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1160 × 0308 × 00AB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1160 × 00BB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1160 × 0020 × 00BB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1160 × 0308 × 00BB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1160 × 0308 × 0020 × 00BB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1160 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1160 × 0020 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1160 × 0308 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1160 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1160 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1160 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1160 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1160 × 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 0308 × 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1160 × 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 × 0308 × 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1160 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1160 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1160 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1160 × 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 × 0308 × 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1160 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 1B05 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1B05 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1B05 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 000A ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 0308 × 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 000A ÷ 11003 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000A ÷ 0020 ÷ 11003 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000A ÷ 0308 ÷ 11003 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 11003 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 000A ÷ 1BC0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] BATAK LETTER A (AS) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1BC0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1BC0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 000A ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0020 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0308 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 000A ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 0308 × 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 000A ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 0308 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 000A ÷ 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ 0020 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ 0308 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 000A ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 0020 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 0308 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 000A ÷ 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0020 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0308 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 000A ÷ 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0020 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0308 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 000A ÷ 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 0020 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 0308 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 000A ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ 0308 × 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 000A ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ 0020 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ 0308 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 000A ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 0020 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 0308 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 000A ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 0308 × 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 000A ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 0020 ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 0308 × 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 000A ÷ 1B50 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1B50 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1B50 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 000A ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 0020 ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 0308 × 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 000A ÷ 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMMA (IS) ÷ [0.3]
+× 000A ÷ 0020 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000A ÷ 0308 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 000A ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 000A ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 0020 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 0308 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 000A ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 000A ÷ 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0020 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0308 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 000A ÷ 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 0020 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 0308 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 000A ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0020 ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0308 × 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 000A ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0308 × 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 000A ÷ 2329 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000A ÷ 0020 ÷ 2329 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000A ÷ 0308 ÷ 2329 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 2329 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 000A ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0308 × 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 000A ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0308 × 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 000A ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0308 × 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 000A ÷ 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [0.3]
+× 000A ÷ 0020 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 000A ÷ 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 0020 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 0308 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 000A ÷ 1BF2 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1BF2 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1BF2 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 000A ÷ 1B44 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1B44 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1B44 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 000A ÷ 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 0020 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 0308 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 000A ÷ 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 0020 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 0308 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 000A ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 000A ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 0020 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 0308 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 000A ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 000A ÷ 00AB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00AB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000A ÷ 0308 × 00AB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00AB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 000A ÷ 00BB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000A ÷ 0020 × 00BB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000A ÷ 0308 × 00BB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 00BB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 000A ÷ 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000A ÷ 0020 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000A ÷ 0308 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000A ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 000A ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000A ÷ 0308 × 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 000A ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 0308 × 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 000A ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 0020 ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 0308 × 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 000A ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 0308 × 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 000A ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0308 × 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 000A ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 0020 ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 000A ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0020 ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0308 × 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000A ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 1B05 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1B05 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1B05 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0085 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0085 ÷ 11003 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 11003 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 11003 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 11003 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0085 ÷ 1BC0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] BATAK LETTER A (AS) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1BC0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1BC0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0085 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0085 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 0308 × 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0085 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0085 ÷ 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ 0020 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ 0308 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0085 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 0020 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 0308 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0085 ÷ 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0020 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0308 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0085 ÷ 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0020 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0308 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0085 ÷ 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 0020 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 0308 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0085 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ 0308 × 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0085 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ 0020 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ 0308 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0085 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 0020 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 0308 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0085 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 0308 × 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0085 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 0308 × 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0085 ÷ 1B50 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1B50 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1B50 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0085 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 0308 × 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0085 ÷ 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 0020 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 0308 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0085 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0085 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0085 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0085 ÷ 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0020 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0308 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0085 ÷ 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 0020 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 0308 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0085 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0308 × 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0085 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0308 × 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0085 ÷ 2329 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 2329 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 2329 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 2329 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0085 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0308 × 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0085 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0308 × 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0085 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0308 × 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0085 ÷ 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 0020 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0085 ÷ 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 0020 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 0308 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0085 ÷ 1BF2 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1BF2 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1BF2 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0085 ÷ 1B44 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1B44 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1B44 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0085 ÷ 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 0020 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 0308 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0085 ÷ 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 0020 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 0308 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0085 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0085 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0085 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0085 ÷ 00AB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00AB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0085 ÷ 0308 × 00AB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00AB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0085 ÷ 00BB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0085 ÷ 0020 × 00BB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0085 ÷ 0308 × 00BB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 00BB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0085 ÷ 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0085 ÷ 0020 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0085 ÷ 0308 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0085 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0085 ÷ 0308 × 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0085 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0085 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0085 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0085 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0085 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0085 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0020 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0308 × 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 ÷ 1B05 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 17D6 × 0020 ÷ 1B05 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 17D6 × 0308 ÷ 1B05 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 17D6 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 17D6 ÷ 11003 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 17D6 × 0020 ÷ 11003 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 17D6 × 0308 ÷ 11003 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 17D6 ÷ 1BC0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 17D6 × 0020 ÷ 1BC0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 17D6 × 0308 ÷ 1BC0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 17D6 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0020 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0308 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 17D6 × 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 × 0020 ÷ 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 × 0308 × 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 17D6 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 0020 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 0308 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 17D6 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 × 0020 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 × 0308 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 17D6 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 0020 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 0308 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 17D6 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0020 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0308 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 17D6 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0020 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0308 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 17D6 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 0020 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 0308 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 17D6 × 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 × 0020 ÷ 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 × 0308 × 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 17D6 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 × 0020 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 × 0308 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 17D6 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 × 0020 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 × 0308 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 17D6 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 0020 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 0308 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 17D6 × 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 × 0020 ÷ 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 × 0308 × 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 17D6 ÷ 1B50 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 17D6 × 0020 ÷ 1B50 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 17D6 × 0308 ÷ 1B50 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 17D6 × 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 0020 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 0308 × 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 17D6 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] COMMA (IS) ÷ [0.3]
+× 17D6 × 0020 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 17D6 × 0308 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 17D6 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 × 0020 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 × 0308 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 17D6 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 × 0020 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 × 0308 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 17D6 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 0020 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 0308 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 17D6 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0020 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0308 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 17D6 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 0020 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 0308 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 17D6 × 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 × 0020 ÷ 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 × 0308 × 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 17D6 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 × 0020 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 × 0308 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 17D6 ÷ 2329 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 17D6 × 0020 ÷ 2329 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 17D6 × 0308 ÷ 2329 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 17D6 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 × 0020 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 × 0308 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 17D6 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0020 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0308 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 17D6 × 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0020 ÷ 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0308 × 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 17D6 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 0020 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 17D6 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 0020 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 0308 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 17D6 ÷ 1BF2 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 17D6 × 0020 ÷ 1BF2 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 17D6 × 0308 ÷ 1BF2 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 17D6 ÷ 1B44 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 17D6 × 0020 ÷ 1B44 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 17D6 × 0308 ÷ 1B44 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 17D6 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 0020 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 0308 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 17D6 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 × 0020 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 × 0308 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 17D6 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 × 0020 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 × 0308 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 17D6 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 × 0020 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 × 0308 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 17D6 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0020 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0308 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 17D6 × 00AB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 17D6 × 0020 ÷ 00AB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 17D6 × 0308 × 00AB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 17D6 × 00BB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 17D6 × 0020 × 00BB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 17D6 × 0308 × 00BB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 00BB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 17D6 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 17D6 × 0020 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 17D6 × 0308 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 17D6 × 0308 × 0020 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 17D6 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 17D6 × 0020 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 17D6 × 0308 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 17D6 × 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 0020 ÷ 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 0308 × 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 17D6 × 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 × 0020 ÷ 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 × 0308 × 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 17D6 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 17D6 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 17D6 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 0020 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 0308 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 17D6 × 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 × 0020 ÷ 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 × 0308 × 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 17D6 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 ÷ 1B05 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0030 × 0020 ÷ 1B05 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0030 × 0308 ÷ 1B05 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0030 × 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 × 0020 ÷ 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 × 0308 × 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0030 ÷ 11003 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0030 × 0020 ÷ 11003 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0030 × 0308 ÷ 11003 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0030 ÷ 1BC0 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0030 × 0020 ÷ 1BC0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0030 × 0308 ÷ 1BC0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0030 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0020 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0308 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0030 × 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 × 0020 ÷ 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 × 0308 × 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0030 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 0020 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 0308 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0030 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 × 0020 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 × 0308 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 × 0308 × 0020 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0030 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 0020 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 0308 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0030 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0020 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0308 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 0308 × 0020 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0030 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0020 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0308 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0308 × 0020 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0030 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 0020 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 0308 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0030 × 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 × 0020 ÷ 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 × 0308 × 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0030 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 × 0020 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 × 0308 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0030 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 0020 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 0308 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0030 × 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 0020 ÷ 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 0308 × 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0030 × 002D ÷ # × [0.3] DIGIT ZERO (NU) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 × 0020 ÷ 002D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 × 0308 × 002D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 002D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0030 ÷ 1B50 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0030 × 0020 ÷ 1B50 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0030 × 0308 ÷ 1B50 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0030 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 0020 ÷ 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 0308 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] COMMA (IS) ÷ [0.3]
+× 0030 × 0020 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0030 × 0308 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] COMMA (IS) ÷ [0.3]
+× 0030 × 0308 × 0020 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0030 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 × 0020 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 × 0308 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0030 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 × 0020 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 × 0308 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0030 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 0020 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 0308 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0030 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0020 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0308 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0308 × 0020 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0030 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 0020 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 0308 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0030 × 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0020 ÷ 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0308 × 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0030 × 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0020 ÷ 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0308 × 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0030 ÷ 2329 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0030 × 0020 ÷ 2329 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0030 × 0308 ÷ 2329 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0030 × 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [25.05] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0020 ÷ 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0308 × 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.05] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0030 × 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [25.05] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0020 ÷ 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0308 × 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.05] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0030 × 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0020 ÷ 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0308 × 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0030 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 0020 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0030 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 0020 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 0308 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] SOLIDUS (SY) ÷ [0.3]
+× 0030 × 0308 × 0020 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0030 ÷ 1BF2 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0030 × 0020 ÷ 1BF2 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0030 × 0308 ÷ 1BF2 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0030 ÷ 1B44 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0030 × 0020 ÷ 1B44 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0030 × 0308 ÷ 1B44 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0030 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 0020 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 0308 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 0308 × 0020 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0030 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 × 0020 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 × 0308 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 × 0308 × 0020 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0030 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 × 0020 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 × 0308 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0030 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 × 0020 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 × 0308 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0030 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0020 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0308 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0030 × 00AB ÷ # × [0.3] DIGIT ZERO (NU) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0030 × 0020 ÷ 00AB ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0030 × 0308 × 00AB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0030 × 00BB ÷ # × [0.3] DIGIT ZERO (NU) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0030 × 0020 × 00BB ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0030 × 0308 × 00BB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0030 × 0308 × 0020 × 00BB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0030 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [25.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0030 × 0020 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0030 × 0308 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0030 × 0308 × 0020 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0030 × 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0030 × 0020 ÷ 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0030 × 0308 × 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0030 × 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 0020 ÷ 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 0308 × 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0030 × 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 0020 ÷ 200D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 0308 × 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0030 × 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 0020 ÷ 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 0308 × 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0030 × 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0020 ÷ 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0308 × 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0030 × 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 0020 ÷ 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 0308 × 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0030 × 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0020 ÷ 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0308 × 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0030 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2329 × 1B05 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2329 × 0020 × 1B05 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2329 × 0308 × 1B05 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1B05 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2329 × 0023 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2329 × 0020 × 0023 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2329 × 0308 × 0023 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0023 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2329 × 11003 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2329 × 0020 × 11003 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2329 × 0308 × 11003 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2329 × 0308 × 0020 × 11003 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2329 × 1BC0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2329 × 0020 × 1BC0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2329 × 0308 × 1BC0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1BC0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2329 × 2014 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 2329 × 0020 × 2014 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 2329 × 0308 × 2014 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EM DASH (B2) ÷ [0.3]
+× 2329 × 0308 × 0020 × 2014 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 2329 × 0009 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2329 × 0020 × 0009 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2329 × 0308 × 0009 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0009 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2329 × 00B4 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2329 × 0020 × 00B4 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2329 × 0308 × 00B4 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2329 × 0308 × 0020 × 00B4 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2329 × 000B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2329 × 0020 × 000B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2329 × 0308 × 000B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2329 × 0308 × 0020 × 000B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2329 × FFFC ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2329 × 0020 × FFFC ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2329 × 0308 × FFFC ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2329 × 0308 × 0020 × FFFC ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2329 × 007D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2329 × 0020 × 007D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2329 × 0308 × 007D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 007D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2329 × 000D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2329 × 0020 × 000D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2329 × 0308 × 000D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2329 × 0308 × 0020 × 000D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2329 × 0021 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2329 × 0020 × 0021 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2329 × 0308 × 0021 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0021 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2329 × 00A0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2329 × 0020 × 00A0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2329 × 0308 × 00A0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 00A0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2329 × AC00 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2329 × 0020 × AC00 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2329 × 0308 × AC00 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2329 × 0308 × 0020 × AC00 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2329 × AC01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2329 × 0020 × AC01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2329 × 0308 × AC01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2329 × 0308 × 0020 × AC01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2329 × 05D0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2329 × 0020 × 05D0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2329 × 0308 × 05D0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 05D0 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2329 × 002D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2329 × 0020 × 002D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2329 × 0308 × 002D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2329 × 0308 × 0020 × 002D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2329 × 1B50 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2329 × 0020 × 1B50 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2329 × 0308 × 1B50 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1B50 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2329 × 2024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2329 × 0020 × 2024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2329 × 0308 × 2024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2329 × 0308 × 0020 × 2024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2329 × 002C ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2329 × 0020 × 002C ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2329 × 0308 × 002C ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 2329 × 0308 × 0020 × 002C ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2329 × 1100 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2329 × 0020 × 1100 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2329 × 0308 × 1100 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1100 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2329 × 11A8 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2329 × 0020 × 11A8 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2329 × 0308 × 11A8 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2329 × 0308 × 0020 × 11A8 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2329 × 1160 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2329 × 0020 × 1160 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2329 × 0308 × 1160 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1160 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2329 × 000A ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2329 × 0020 × 000A ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2329 × 0308 × 000A ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2329 × 0308 × 0020 × 000A ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2329 × 0085 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2329 × 0020 × 0085 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2329 × 0308 × 0085 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0085 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2329 × 17D6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2329 × 0020 × 17D6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2329 × 0308 × 17D6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2329 × 0308 × 0020 × 17D6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2329 × 0030 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2329 × 0020 × 0030 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2329 × 0308 × 0030 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0030 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2329 × 2329 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2329 × 0020 × 2329 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2329 × 0308 × 2329 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2329 × 0308 × 0020 × 2329 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2329 × 0025 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2329 × 0020 × 0025 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2329 × 0308 × 0025 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0025 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2329 × 0024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2329 × 0020 × 0024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2329 × 0308 × 0024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0024 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2329 × 0022 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2329 × 0020 × 0022 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2329 × 0308 × 0022 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0022 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2329 × 0020 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2329 × 0020 × 0020 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2329 × 0308 × 0020 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0020 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2329 × 002F ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2329 × 0020 × 002F ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2329 × 0308 × 002F ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 2329 × 0308 × 0020 × 002F ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2329 × 1BF2 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2329 × 0020 × 1BF2 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2329 × 0308 × 1BF2 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1BF2 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2329 × 1B44 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2329 × 0020 × 1B44 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2329 × 0308 × 1B44 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1B44 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2329 × 2060 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2329 × 0020 × 2060 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2329 × 0308 × 2060 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2329 × 0308 × 0020 × 2060 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2329 × 200B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2329 × 0020 × 200B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2329 × 0308 × 200B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2329 × 0308 × 0020 × 200B ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2329 × 1F1E6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2329 × 0020 × 1F1E6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2329 × 0308 × 1F1E6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1F1E6 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2329 × 261D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2329 × 0020 × 261D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2329 × 0308 × 261D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2329 × 0308 × 0020 × 261D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2329 × 1F3FB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2329 × 0020 × 1F3FB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2329 × 0308 × 1F3FB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2329 × 0308 × 0020 × 1F3FB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2329 × 00AB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2329 × 0020 × 00AB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2329 × 0308 × 00AB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2329 × 0308 × 0020 × 00AB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2329 × 00BB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2329 × 0020 × 00BB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2329 × 0308 × 00BB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2329 × 0308 × 0020 × 00BB ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2329 × 0029 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2329 × 0020 × 0029 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2329 × 0308 × 0029 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0029 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2329 × 0028 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2329 × 0020 × 0028 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2329 × 0308 × 0028 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0028 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2329 × 0001 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2329 × 0020 × 0001 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2329 × 0308 × 0001 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0001 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2329 × 200D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2329 × 0020 × 200D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2329 × 0308 × 200D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2329 × 0308 × 0020 × 200D ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2329 × 00A7 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2329 × 0020 × 00A7 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2329 × 0308 × 00A7 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 00A7 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2329 × 50005 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2329 × 0020 × 50005 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2329 × 0308 × 50005 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 50005 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2329 × 0E01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2329 × 0020 × 0E01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2329 × 0308 × 0E01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2329 × 0308 × 0020 × 0E01 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2329 × 3041 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2329 × 0020 × 3041 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2329 × 0308 × 3041 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2329 × 0308 × 0020 × 3041 ÷ # × [0.3] LEFT-POINTING ANGLE BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 ÷ 1B05 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0025 × 0020 ÷ 1B05 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0025 × 0308 ÷ 1B05 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0025 × 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 × 0020 ÷ 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 × 0308 × 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0025 ÷ 11003 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0025 × 0020 ÷ 11003 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0025 × 0308 ÷ 11003 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0025 ÷ 1BC0 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0025 × 0020 ÷ 1BC0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0025 × 0308 ÷ 1BC0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0025 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0020 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0308 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0025 × 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 × 0020 ÷ 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 × 0308 × 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0025 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 0020 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 0308 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0025 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 × 0020 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 × 0308 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 × 0308 × 0020 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0025 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 0020 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 0308 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0025 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0020 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0308 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 0308 × 0020 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0025 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0020 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0308 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0308 × 0020 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0025 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 0020 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 0308 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0025 × 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 × 0020 ÷ 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 × 0308 × 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0025 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 × 0020 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 × 0308 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0025 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 0020 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 0308 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0025 × 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 0020 ÷ 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 0308 × 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0025 × 002D ÷ # × [0.3] PERCENT SIGN (PO) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 × 0020 ÷ 002D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 × 0308 × 002D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 002D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0025 ÷ 1B50 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0025 × 0020 ÷ 1B50 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0025 × 0308 ÷ 1B50 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0025 × 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 0020 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 0308 × 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0025 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] COMMA (IS) ÷ [0.3]
+× 0025 × 0020 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0025 × 0308 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0025 × 0308 × 0020 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0025 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 × 0020 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 × 0308 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0025 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 × 0020 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 × 0308 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0025 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 0020 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 0308 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0025 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0020 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0308 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0308 × 0020 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0025 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 0020 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 0308 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0025 × 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0020 ÷ 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0308 × 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0025 × 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 × 0020 ÷ 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 × 0308 × 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0025 ÷ 2329 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0025 × 0020 ÷ 2329 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0025 × 0308 ÷ 2329 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0025 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 × 0020 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 × 0308 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0025 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0020 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0308 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0025 × 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0020 ÷ 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0308 × 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0025 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 0020 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0025 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 0020 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 0308 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0025 × 0308 × 0020 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0025 ÷ 1BF2 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0025 × 0020 ÷ 1BF2 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0025 × 0308 ÷ 1BF2 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0025 ÷ 1B44 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0025 × 0020 ÷ 1B44 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0025 × 0308 ÷ 1B44 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0025 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 0020 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 0308 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 0308 × 0020 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0025 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 × 0020 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 × 0308 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 × 0308 × 0020 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0025 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 × 0020 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 × 0308 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0025 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 × 0020 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 × 0308 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0025 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0020 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0308 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0025 × 00AB ÷ # × [0.3] PERCENT SIGN (PO) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0025 × 0020 ÷ 00AB ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0025 × 0308 × 00AB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0025 × 00BB ÷ # × [0.3] PERCENT SIGN (PO) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0025 × 0020 × 00BB ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0025 × 0308 × 00BB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0025 × 0308 × 0020 × 00BB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0025 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0025 × 0020 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0025 × 0308 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0025 × 0308 × 0020 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0025 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0025 × 0020 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0025 × 0308 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0025 × 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 0020 ÷ 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 0308 × 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0025 × 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 0020 ÷ 200D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 0308 × 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0025 × 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 0020 ÷ 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 0308 × 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0025 × 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0020 ÷ 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0308 × 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0025 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0020 ÷ 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0308 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0020 ÷ 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0308 × 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0025 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 ÷ 1B05 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0024 × 0020 ÷ 1B05 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0024 × 0308 ÷ 1B05 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0024 × 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 × 0020 ÷ 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 × 0308 × 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0024 ÷ 11003 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0024 × 0020 ÷ 11003 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0024 × 0308 ÷ 11003 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0024 ÷ 1BC0 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0024 × 0020 ÷ 1BC0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0024 × 0308 ÷ 1BC0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0024 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0020 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0308 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0024 × 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 × 0020 ÷ 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 × 0308 × 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0024 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 0020 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 0308 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0024 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 × 0020 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 × 0308 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 × 0308 × 0020 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0024 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 0020 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 0308 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0024 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0020 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0308 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 0308 × 0020 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0024 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0020 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0308 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0308 × 0020 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0024 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 0020 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 0308 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0024 × 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × 0020 ÷ 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × 0308 × 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0024 × AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × 0020 ÷ AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × 0308 × AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0024 × AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 0020 ÷ AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 0308 × AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0024 × 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 0020 ÷ 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 0308 × 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0024 × 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 0020 ÷ 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 0308 × 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0024 × 1B50 ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0024 × 0020 ÷ 1B50 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0024 × 0308 × 1B50 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0024 × 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 0020 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 0308 × 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0024 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] COMMA (IS) ÷ [0.3]
+× 0024 × 0020 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0024 × 0308 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0024 × 0308 × 0020 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0024 × 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 0020 ÷ 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 0308 × 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0024 × 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 0020 ÷ 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 0308 × 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0024 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 0020 ÷ 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 0308 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0024 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0020 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0308 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0308 × 0020 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0024 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 0020 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 0308 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0024 × 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0020 ÷ 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0308 × 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0024 × 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 0020 ÷ 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 0308 × 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 ÷ 2329 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0024 × 0020 ÷ 2329 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0024 × 0308 ÷ 2329 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0024 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 0020 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 0308 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0020 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0308 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0024 × 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0020 ÷ 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0308 × 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0024 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 0020 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0024 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 0020 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 0308 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0024 × 0308 × 0020 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0024 ÷ 1BF2 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0024 × 0020 ÷ 1BF2 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0024 × 0308 ÷ 1BF2 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0024 ÷ 1B44 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0024 × 0020 ÷ 1B44 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0024 × 0308 ÷ 1B44 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0024 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 0020 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 0308 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 0308 × 0020 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0024 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 × 0020 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 × 0308 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 × 0308 × 0020 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0024 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 0020 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 0308 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0024 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0020 ÷ 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0308 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0020 ÷ 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0308 × 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0024 × 00AB ÷ # × [0.3] DOLLAR SIGN (PR) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0024 × 0020 ÷ 00AB ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0024 × 0308 × 00AB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0024 × 00BB ÷ # × [0.3] DOLLAR SIGN (PR) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0024 × 0020 × 00BB ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0024 × 0308 × 00BB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0024 × 0308 × 0020 × 00BB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0024 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0024 × 0020 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0024 × 0308 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0024 × 0308 × 0020 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0024 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0024 × 0020 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0024 × 0308 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0024 × 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 0020 ÷ 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 0308 × 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0024 × 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 0020 ÷ 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 0308 × 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0024 × 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 0020 ÷ 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 0308 × 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0024 × 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0020 ÷ 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0308 × 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0024 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 0020 ÷ 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 0308 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0024 × 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0020 ÷ 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0308 × 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0024 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 1B05 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0022 × 0020 ÷ 1B05 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0022 × 0308 × 1B05 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0022 × 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 0020 ÷ 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 0308 × 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0022 × 11003 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0022 × 0020 ÷ 11003 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0022 × 0308 × 11003 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0022 × 1BC0 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] BATAK LETTER A (AS) ÷ [0.3]
+× 0022 × 0020 ÷ 1BC0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0022 × 0308 × 1BC0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BATAK LETTER A (AS) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0022 × 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] EM DASH (B2) ÷ [0.3]
+× 0022 × 0020 ÷ 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0022 × 0308 × 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EM DASH (B2) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0022 × 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 0020 ÷ 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 0308 × 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0022 × 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 0020 ÷ 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 0308 × 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0022 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × 0020 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × 0308 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × 0308 × 0020 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0022 × FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 0020 ÷ FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 0308 × FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0022 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0020 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0308 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 0308 × 0020 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0022 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0020 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0308 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0308 × 0020 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0022 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 0020 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 0308 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0022 × 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × 0020 ÷ 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × 0308 × 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0022 × AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × 0020 ÷ AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × 0308 × AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0022 × AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 0020 ÷ AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 0308 × AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0022 × 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 0020 ÷ 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 0308 × 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0022 × 002D ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 0020 ÷ 002D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 0308 × 002D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 002D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0022 × 1B50 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0022 × 0020 ÷ 1B50 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0022 × 0308 × 1B50 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0022 × 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 0020 ÷ 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 0308 × 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0022 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] COMMA (IS) ÷ [0.3]
+× 0022 × 0020 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0022 × 0308 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0022 × 0308 × 0020 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0022 × 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 0020 ÷ 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 0308 × 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0022 × 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 0020 ÷ 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 0308 × 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0022 × 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 0020 ÷ 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 0308 × 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0022 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0020 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0308 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0308 × 0020 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0022 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 0020 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 0308 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0022 × 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0020 ÷ 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0308 × 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0022 × 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0020 ÷ 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0308 × 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0022 × 2329 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0022 × 0020 ÷ 2329 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0022 × 0308 × 2329 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0022 × 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0020 ÷ 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0308 × 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0022 × 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0020 ÷ 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0308 × 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0022 × 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0020 ÷ 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0308 × 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0022 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 0020 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0022 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 0020 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 0308 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 0308 × 0020 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0022 × 1BF2 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0022 × 0020 ÷ 1BF2 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0022 × 0308 × 1BF2 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0022 × 1B44 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0022 × 0020 ÷ 1B44 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0022 × 0308 × 1B44 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0022 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 0020 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 0308 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 0308 × 0020 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0022 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 0020 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 0308 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 0308 × 0020 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0022 × 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 0020 ÷ 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 0308 × 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0022 × 261D ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 0020 ÷ 261D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 0308 × 261D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 261D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0022 × 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0020 ÷ 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0308 × 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0022 × 00AB ÷ # × [0.3] QUOTATION MARK (QU) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0022 × 0020 ÷ 00AB ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0022 × 0308 × 00AB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0022 × 00BB ÷ # × [0.3] QUOTATION MARK (QU) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0022 × 0020 × 00BB ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0022 × 0308 × 00BB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0022 × 0308 × 0020 × 00BB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0022 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0022 × 0020 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0022 × 0308 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0022 × 0308 × 0020 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0022 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0022 × 0020 ÷ 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0022 × 0308 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0022 × 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 0020 ÷ 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 0308 × 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0022 × 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 0020 ÷ 200D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 0308 × 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0022 × 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 0020 ÷ 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 0308 × 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0022 × 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0020 ÷ 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0308 × 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0022 × 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 0020 ÷ 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 0308 × 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0022 × 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0020 ÷ 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0308 × 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0022 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 ÷ 1B05 ÷ # × [0.3] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0020 × 0020 ÷ 1B05 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1B05 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1B05 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 × 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0020 ÷ 11003 ÷ # × [0.3] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0020 × 0020 ÷ 11003 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 11003 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 11003 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0020 ÷ 1BC0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0020 × 0020 ÷ 1BC0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1BC0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0020 × 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 × 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 ÷ 0308 × 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 × 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0020 × 000B ÷ # × [0.3] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 × 0020 × 000B ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 ÷ 0308 × 000B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 000B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 × 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 ÷ 0308 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0020 × 007D ÷ # × [0.3] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 × 0020 × 007D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 ÷ 0308 × 007D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 007D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0020 × 000D ÷ # × [0.3] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 × 0020 × 000D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 ÷ 0308 × 000D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 000D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0020 × 0021 ÷ # × [0.3] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 × 0020 × 0021 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 ÷ 0308 × 0021 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0021 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 × 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 ÷ 0308 × 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 × 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 ÷ 0308 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 × 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 ÷ 0308 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 × 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 ÷ 0308 × 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 × 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 ÷ 0308 × 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0020 ÷ 1B50 ÷ # × [0.3] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0020 × 0020 ÷ 1B50 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1B50 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1B50 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 × 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 ÷ 0308 × 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0020 × 002C ÷ # × [0.3] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0020 × 0020 × 002C ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0020 ÷ 0308 × 002C ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 002C ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 × 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 × 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 × 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0020 × 000A ÷ # × [0.3] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 × 0020 × 000A ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 ÷ 0308 × 000A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 000A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0020 × 0085 ÷ # × [0.3] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 × 0020 × 0085 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 ÷ 0308 × 0085 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0085 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 × 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 ÷ 0308 × 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 × 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 ÷ 0308 × 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0020 ÷ 2329 ÷ # × [0.3] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0020 × 0020 ÷ 2329 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 2329 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 2329 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 × 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 ÷ 0308 × 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 × 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 ÷ 0308 × 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 × 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 ÷ 0308 × 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0020 × 0020 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 × 0020 × 0020 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0020 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0020 × 002F ÷ # × [0.3] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0020 × 0020 × 002F ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0020 ÷ 0308 × 002F ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 002F ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0020 ÷ 1BF2 ÷ # × [0.3] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0020 × 0020 ÷ 1BF2 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1BF2 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0020 ÷ 1B44 ÷ # × [0.3] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0020 × 0020 ÷ 1B44 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1B44 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1B44 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0020 × 2060 ÷ # × [0.3] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 × 0020 × 2060 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 ÷ 0308 × 2060 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 2060 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0020 × 200B ÷ # × [0.3] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 × 0020 × 200B ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 ÷ 0308 × 200B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 200B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 × 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 × 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 × 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 ÷ 0308 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0020 ÷ 00AB ÷ # × [0.3] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0020 × 0020 ÷ 00AB ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0020 ÷ 0308 × 00AB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00AB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0020 × 00BB ÷ # × [0.3] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0020 × 0020 × 00BB ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0020 ÷ 0308 × 00BB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 00BB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0020 × 0029 ÷ # × [0.3] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0020 × 0020 × 0029 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0020 ÷ 0308 × 0029 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 × 0029 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0020 × 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0020 ÷ 0308 × 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 × 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 × 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 × 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 × 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 × 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 × 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 ÷ 0308 × 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0020 ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F ÷ 1B05 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002F × 0020 ÷ 1B05 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002F × 0308 ÷ 1B05 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 002F ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F × 0020 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F × 0308 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 002F ÷ 11003 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002F × 0020 ÷ 11003 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002F × 0308 ÷ 11003 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 11003 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 002F ÷ 1BC0 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002F × 0020 ÷ 1BC0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002F × 0308 ÷ 1BC0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 002F ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0020 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0308 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 002F × 0009 ÷ # × [0.3] SOLIDUS (SY) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F × 0020 ÷ 0009 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F × 0308 × 0009 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0009 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 002F ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 0020 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 0308 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 002F × 000B ÷ # × [0.3] SOLIDUS (SY) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F × 0020 × 000B ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F × 0308 × 000B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F × 0308 × 0020 × 000B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 002F ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 0020 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 0308 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 002F × 007D ÷ # × [0.3] SOLIDUS (SY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0020 × 007D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0308 × 007D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 0308 × 0020 × 007D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 002F × 000D ÷ # × [0.3] SOLIDUS (SY) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0020 × 000D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0308 × 000D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0308 × 0020 × 000D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 002F × 0021 ÷ # × [0.3] SOLIDUS (SY) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 0020 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 0308 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 0308 × 0020 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 002F × 00A0 ÷ # × [0.3] SOLIDUS (SY) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F × 0020 ÷ 00A0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F × 0308 × 00A0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 002F ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F × 0020 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F × 0308 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 002F ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 0020 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 0308 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 002F × 05D0 ÷ # × [0.3] SOLIDUS (SY) × [21.2] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 0020 ÷ 05D0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 0308 × 05D0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.2] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 002F × 002D ÷ # × [0.3] SOLIDUS (SY) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F × 0020 ÷ 002D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F × 0308 × 002D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 002D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 002F ÷ 1B50 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002F × 0020 ÷ 1B50 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002F × 0308 ÷ 1B50 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 002F × 2024 ÷ # × [0.3] SOLIDUS (SY) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 0020 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 0308 × 2024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 002F × 002C ÷ # × [0.3] SOLIDUS (SY) × [13.02] COMMA (IS) ÷ [0.3]
+× 002F × 0020 × 002C ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002F × 0308 × 002C ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 002F × 0308 × 0020 × 002C ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 002F ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F × 0020 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F × 0308 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 002F ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F × 0020 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F × 0308 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 002F ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 0020 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 0308 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 002F × 000A ÷ # × [0.3] SOLIDUS (SY) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0020 × 000A ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0308 × 000A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0308 × 0020 × 000A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 002F × 0085 ÷ # × [0.3] SOLIDUS (SY) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 0020 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 0308 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 0308 × 0020 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 002F × 17D6 ÷ # × [0.3] SOLIDUS (SY) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F × 0020 ÷ 17D6 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F × 0308 × 17D6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 002F ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F × 0020 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F × 0308 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 002F ÷ 2329 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002F × 0020 ÷ 2329 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002F × 0308 ÷ 2329 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 2329 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 002F ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F × 0020 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F × 0308 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 002F ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0020 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0308 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 002F × 0022 ÷ # × [0.3] SOLIDUS (SY) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0020 ÷ 0022 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0308 × 0022 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0022 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 002F × 0020 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 0020 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 0308 × 0020 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002F × 002F ÷ # × [0.3] SOLIDUS (SY) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002F × 0020 × 002F ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002F × 0308 × 002F ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 002F × 0308 × 0020 × 002F ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 002F ÷ 1BF2 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002F × 0020 ÷ 1BF2 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002F × 0308 ÷ 1BF2 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 002F ÷ 1B44 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002F × 0020 ÷ 1B44 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002F × 0308 ÷ 1B44 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 002F × 2060 ÷ # × [0.3] SOLIDUS (SY) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 0020 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 0308 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 0308 × 0020 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 002F × 200B ÷ # × [0.3] SOLIDUS (SY) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F × 0020 × 200B ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F × 0308 × 200B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F × 0308 × 0020 × 200B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 002F ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F × 0020 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F × 0308 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 002F ÷ 261D ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F × 0020 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F × 0308 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 002F ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0020 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0308 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 002F × 00AB ÷ # × [0.3] SOLIDUS (SY) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002F × 0020 ÷ 00AB ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002F × 0308 × 00AB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00AB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 002F × 00BB ÷ # × [0.3] SOLIDUS (SY) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002F × 0020 × 00BB ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002F × 0308 × 00BB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002F × 0308 × 0020 × 00BB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 002F × 0029 ÷ # × [0.3] SOLIDUS (SY) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002F × 0020 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002F × 0308 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002F × 0308 × 0020 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 002F ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002F × 0020 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002F × 0308 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 002F × 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 0020 ÷ 0001 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 0308 × 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 002F × 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F × 0020 ÷ 200D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F × 0308 × 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 002F ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F × 0020 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F × 0308 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 002F ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F × 0020 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F × 0308 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 002F ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 0020 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 0308 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 002F × 3041 ÷ # × [0.3] SOLIDUS (SY) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F × 0020 ÷ 3041 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F × 0308 × 3041 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 002F × 0308 × 0020 ÷ 3041 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BF2 ÷ 1B05 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1B05 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1B05 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1BF2 ÷ 0023 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0023 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BF2 × 0308 ÷ 0023 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1BF2 ÷ 11003 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BF2 × 0020 ÷ 11003 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BF2 × 0308 ÷ 11003 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1BF2 ÷ 1BC0 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1BC0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1BC0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1BF2 ÷ 2014 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1BF2 × 0020 ÷ 2014 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1BF2 × 0308 ÷ 2014 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1BF2 × 0009 ÷ # × [0.3] BATAK PANGOLAT (VF) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0009 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BF2 × 0308 × 0009 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1BF2 ÷ 00B4 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BF2 × 0020 ÷ 00B4 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BF2 × 0308 ÷ 00B4 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1BF2 × 000B ÷ # × [0.3] BATAK PANGOLAT (VF) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BF2 × 0020 × 000B ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BF2 × 0308 × 000B ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 000B ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1BF2 ÷ FFFC ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BF2 × 0020 ÷ FFFC ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BF2 × 0308 ÷ FFFC ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1BF2 × 007D ÷ # × [0.3] BATAK PANGOLAT (VF) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BF2 × 0020 × 007D ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BF2 × 0308 × 007D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 007D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1BF2 × 000D ÷ # × [0.3] BATAK PANGOLAT (VF) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BF2 × 0020 × 000D ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BF2 × 0308 × 000D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 000D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1BF2 × 0021 ÷ # × [0.3] BATAK PANGOLAT (VF) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BF2 × 0020 × 0021 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BF2 × 0308 × 0021 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 0021 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1BF2 × 00A0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 00A0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BF2 × 0308 × 00A0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1BF2 ÷ AC00 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BF2 × 0020 ÷ AC00 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BF2 × 0308 ÷ AC00 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1BF2 ÷ AC01 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BF2 × 0020 ÷ AC01 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BF2 × 0308 ÷ AC01 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1BF2 ÷ 05D0 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 05D0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BF2 × 0308 ÷ 05D0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1BF2 × 002D ÷ # × [0.3] BATAK PANGOLAT (VF) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BF2 × 0020 ÷ 002D ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BF2 × 0308 × 002D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 002D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1BF2 ÷ 1B50 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1B50 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1B50 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1BF2 × 2024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BF2 × 0020 ÷ 2024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BF2 × 0308 × 2024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1BF2 × 002C ÷ # × [0.3] BATAK PANGOLAT (VF) × [13.02] COMMA (IS) ÷ [0.3]
+× 1BF2 × 0020 × 002C ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1BF2 × 0308 × 002C ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 002C ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1BF2 ÷ 1100 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1100 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1100 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1BF2 ÷ 11A8 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BF2 × 0020 ÷ 11A8 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BF2 × 0308 ÷ 11A8 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1BF2 ÷ 1160 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1160 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1160 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1BF2 × 000A ÷ # × [0.3] BATAK PANGOLAT (VF) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BF2 × 0020 × 000A ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BF2 × 0308 × 000A ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 000A ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1BF2 × 0085 ÷ # × [0.3] BATAK PANGOLAT (VF) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BF2 × 0020 × 0085 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BF2 × 0308 × 0085 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 0085 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1BF2 × 17D6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BF2 × 0020 ÷ 17D6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BF2 × 0308 × 17D6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1BF2 ÷ 0030 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0030 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BF2 × 0308 ÷ 0030 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1BF2 ÷ 2329 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BF2 × 0020 ÷ 2329 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BF2 × 0308 ÷ 2329 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1BF2 ÷ 0025 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0025 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BF2 × 0308 ÷ 0025 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1BF2 ÷ 0024 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BF2 × 0308 ÷ 0024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1BF2 × 0022 ÷ # × [0.3] BATAK PANGOLAT (VF) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0022 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1BF2 × 0308 × 0022 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1BF2 × 0020 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BF2 × 0020 × 0020 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 0020 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1BF2 × 002F ÷ # × [0.3] BATAK PANGOLAT (VF) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1BF2 × 0020 × 002F ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1BF2 × 0308 × 002F ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 002F ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1BF2 ÷ 1BF2 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1BF2 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1BF2 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1BF2 ÷ 1B44 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1B44 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1B44 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1BF2 × 2060 ÷ # × [0.3] BATAK PANGOLAT (VF) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BF2 × 0020 × 2060 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BF2 × 0308 × 2060 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 2060 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1BF2 × 200B ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BF2 × 0020 × 200B ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BF2 × 0308 × 200B ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 200B ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1BF2 ÷ 1F1E6 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1F1E6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1F1E6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1BF2 ÷ 261D ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BF2 × 0020 ÷ 261D ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BF2 × 0308 ÷ 261D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 261D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1BF2 ÷ 1F3FB ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BF2 × 0020 ÷ 1F3FB ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BF2 × 0308 ÷ 1F3FB ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1BF2 × 00AB ÷ # × [0.3] BATAK PANGOLAT (VF) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BF2 × 0020 ÷ 00AB ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BF2 × 0308 × 00AB ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1BF2 × 00BB ÷ # × [0.3] BATAK PANGOLAT (VF) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BF2 × 0020 × 00BB ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BF2 × 0308 × 00BB ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 00BB ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1BF2 × 0029 ÷ # × [0.3] BATAK PANGOLAT (VF) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BF2 × 0020 × 0029 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BF2 × 0308 × 0029 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BF2 × 0308 × 0020 × 0029 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1BF2 ÷ 0028 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0028 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BF2 × 0308 ÷ 0028 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1BF2 × 0001 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0001 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BF2 × 0308 × 0001 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1BF2 × 200D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BF2 × 0020 ÷ 200D ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BF2 × 0308 × 200D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 200D ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1BF2 ÷ 00A7 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 00A7 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BF2 × 0308 ÷ 00A7 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1BF2 ÷ 50005 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 50005 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BF2 × 0308 ÷ 50005 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1BF2 ÷ 0E01 ÷ # × [0.3] BATAK PANGOLAT (VF) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BF2 × 0020 ÷ 0E01 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BF2 × 0308 ÷ 0E01 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1BF2 × 3041 ÷ # × [0.3] BATAK PANGOLAT (VF) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BF2 × 0020 ÷ 3041 ÷ # × [0.3] BATAK PANGOLAT (VF) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BF2 × 0308 × 3041 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1BF2 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] BATAK PANGOLAT (VF) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B44 ÷ 1B05 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B44 × 0020 ÷ 1B05 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B44 × 0308 ÷ 1B05 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1B44 ÷ 0023 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B44 × 0020 ÷ 0023 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B44 × 0308 ÷ 0023 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1B44 ÷ 11003 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B44 × 0020 ÷ 11003 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B44 × 0308 ÷ 11003 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1B44 ÷ 1BC0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B44 × 0020 ÷ 1BC0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B44 × 0308 ÷ 1BC0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1B44 ÷ 2014 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1B44 × 0020 ÷ 2014 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1B44 × 0308 ÷ 2014 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1B44 × 0009 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B44 × 0020 ÷ 0009 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B44 × 0308 × 0009 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1B44 ÷ 00B4 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B44 × 0020 ÷ 00B4 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B44 × 0308 ÷ 00B4 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1B44 × 000B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B44 × 0020 × 000B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B44 × 0308 × 000B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 000B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1B44 ÷ FFFC ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B44 × 0020 ÷ FFFC ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B44 × 0308 ÷ FFFC ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1B44 × 007D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B44 × 0020 × 007D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B44 × 0308 × 007D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 007D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1B44 × 000D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B44 × 0020 × 000D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B44 × 0308 × 000D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 000D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1B44 × 0021 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B44 × 0020 × 0021 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B44 × 0308 × 0021 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 0021 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1B44 × 00A0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B44 × 0020 ÷ 00A0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B44 × 0308 × 00A0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1B44 ÷ AC00 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B44 × 0020 ÷ AC00 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B44 × 0308 ÷ AC00 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1B44 ÷ AC01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B44 × 0020 ÷ AC01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B44 × 0308 ÷ AC01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1B44 ÷ 05D0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B44 × 0020 ÷ 05D0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B44 × 0308 ÷ 05D0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1B44 × 002D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B44 × 0020 ÷ 002D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B44 × 0308 × 002D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 002D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1B44 ÷ 1B50 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B44 × 0020 ÷ 1B50 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B44 × 0308 ÷ 1B50 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1B44 × 2024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B44 × 0020 ÷ 2024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B44 × 0308 × 2024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1B44 × 002C ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B44 × 0020 × 002C ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B44 × 0308 × 002C ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 002C ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1B44 ÷ 1100 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B44 × 0020 ÷ 1100 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B44 × 0308 ÷ 1100 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1B44 ÷ 11A8 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B44 × 0020 ÷ 11A8 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B44 × 0308 ÷ 11A8 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1B44 ÷ 1160 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B44 × 0020 ÷ 1160 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B44 × 0308 ÷ 1160 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1B44 × 000A ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B44 × 0020 × 000A ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B44 × 0308 × 000A ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 000A ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1B44 × 0085 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B44 × 0020 × 0085 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B44 × 0308 × 0085 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 0085 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1B44 × 17D6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B44 × 0020 ÷ 17D6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B44 × 0308 × 17D6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1B44 ÷ 0030 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B44 × 0020 ÷ 0030 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B44 × 0308 ÷ 0030 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1B44 ÷ 2329 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B44 × 0020 ÷ 2329 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B44 × 0308 ÷ 2329 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1B44 ÷ 0025 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B44 × 0020 ÷ 0025 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B44 × 0308 ÷ 0025 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1B44 ÷ 0024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B44 × 0020 ÷ 0024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B44 × 0308 ÷ 0024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1B44 × 0022 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1B44 × 0020 ÷ 0022 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1B44 × 0308 × 0022 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1B44 × 0020 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B44 × 0020 × 0020 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 0020 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1B44 × 002F ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B44 × 0020 × 002F ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B44 × 0308 × 002F ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 002F ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1B44 ÷ 1BF2 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B44 × 0020 ÷ 1BF2 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B44 × 0308 ÷ 1BF2 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1B44 ÷ 1B44 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B44 × 0020 ÷ 1B44 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B44 × 0308 ÷ 1B44 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1B44 × 2060 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B44 × 0020 × 2060 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B44 × 0308 × 2060 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 2060 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1B44 × 200B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B44 × 0020 × 200B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B44 × 0308 × 200B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 200B ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1B44 ÷ 1F1E6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B44 × 0020 ÷ 1F1E6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B44 × 0308 ÷ 1F1E6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1B44 ÷ 261D ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B44 × 0020 ÷ 261D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B44 × 0308 ÷ 261D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 261D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1B44 ÷ 1F3FB ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B44 × 0020 ÷ 1F3FB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B44 × 0308 ÷ 1F3FB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1B44 × 00AB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B44 × 0020 ÷ 00AB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B44 × 0308 × 00AB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1B44 × 00BB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B44 × 0020 × 00BB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B44 × 0308 × 00BB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 00BB ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1B44 × 0029 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B44 × 0020 × 0029 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B44 × 0308 × 0029 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B44 × 0308 × 0020 × 0029 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1B44 ÷ 0028 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B44 × 0020 ÷ 0028 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B44 × 0308 ÷ 0028 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1B44 × 0001 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B44 × 0020 ÷ 0001 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B44 × 0308 × 0001 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1B44 × 200D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B44 × 0020 ÷ 200D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B44 × 0308 × 200D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 200D ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1B44 ÷ 00A7 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B44 × 0020 ÷ 00A7 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B44 × 0308 ÷ 00A7 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1B44 ÷ 50005 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B44 × 0020 ÷ 50005 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B44 × 0308 ÷ 50005 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1B44 ÷ 0E01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B44 × 0020 ÷ 0E01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B44 × 0308 ÷ 0E01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1B44 × 3041 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B44 × 0020 ÷ 3041 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B44 × 0308 × 3041 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1B44 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] BALINESE ADEG ADEG (VI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 1B05 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2060 × 0020 ÷ 1B05 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2060 × 0308 × 1B05 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 2060 × 0023 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 0020 ÷ 0023 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 0308 × 0023 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 2060 × 11003 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2060 × 0020 ÷ 11003 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2060 × 0308 × 11003 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 2060 × 1BC0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] BATAK LETTER A (AS) ÷ [0.3]
+× 2060 × 0020 ÷ 1BC0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2060 × 0308 × 1BC0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] BATAK LETTER A (AS) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 2060 × 2014 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EM DASH (B2) ÷ [0.3]
+× 2060 × 0020 ÷ 2014 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2060 × 0308 × 2014 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EM DASH (B2) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 2060 × 0009 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 0020 ÷ 0009 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 0308 × 0009 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 2060 × 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 0020 ÷ 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 0308 × 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 2060 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × 0020 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × 0308 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × 0308 × 0020 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 2060 × FFFC ÷ # × [0.3] WORD JOINER (WJ) × [11.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 0020 ÷ FFFC ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 0308 × FFFC ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 2060 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0020 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0308 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 0308 × 0020 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 2060 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0020 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0308 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0308 × 0020 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 2060 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 0020 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 0308 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 2060 × 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × 0020 ÷ 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × 0308 × 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 2060 × AC00 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × 0020 ÷ AC00 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × 0308 × AC00 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 2060 × AC01 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 0020 ÷ AC01 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 0308 × AC01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 2060 × 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 0020 ÷ 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 0308 × 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 2060 × 002D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 0020 ÷ 002D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 0308 × 002D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 002D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 2060 × 1B50 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2060 × 0020 ÷ 1B50 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2060 × 0308 × 1B50 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 2060 × 2024 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 0020 ÷ 2024 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 0308 × 2024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2060 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [11.02] COMMA (IS) ÷ [0.3]
+× 2060 × 0020 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2060 × 0308 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] COMMA (IS) ÷ [0.3]
+× 2060 × 0308 × 0020 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 2060 × 1100 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 0020 ÷ 1100 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 0308 × 1100 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 2060 × 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 0020 ÷ 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 0308 × 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 2060 × 1160 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 0020 ÷ 1160 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 0308 × 1160 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 2060 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0020 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0308 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0308 × 0020 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 2060 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 0020 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 0308 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 2060 × 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0020 ÷ 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0308 × 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 2060 × 0030 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0020 ÷ 0030 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0308 × 0030 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 2060 × 2329 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2060 × 0020 ÷ 2329 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2060 × 0308 × 2329 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 2060 × 0025 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0020 ÷ 0025 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0308 × 0025 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 2060 × 0024 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0020 ÷ 0024 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0308 × 0024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 2060 × 0022 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0020 ÷ 0022 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0308 × 0022 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 2060 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 0020 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 2060 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [11.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 0020 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 0308 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 0308 × 0020 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 2060 × 1BF2 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2060 × 0020 ÷ 1BF2 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2060 × 0308 × 1BF2 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 2060 × 1B44 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2060 × 0020 ÷ 1B44 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2060 × 0308 × 1B44 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 2060 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 0020 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 0308 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 0308 × 0020 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 0020 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 0308 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 0308 × 0020 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 2060 × 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 0020 ÷ 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 0308 × 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 2060 × 261D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 0020 ÷ 261D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 0308 × 261D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 261D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 2060 × 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0020 ÷ 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0308 × 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 2060 × 00AB ÷ # × [0.3] WORD JOINER (WJ) × [11.02] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2060 × 0020 ÷ 00AB ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2060 × 0308 × 00AB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 2060 × 00BB ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2060 × 0020 × 00BB ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2060 × 0308 × 00BB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2060 × 0308 × 0020 × 00BB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2060 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2060 × 0020 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2060 × 0308 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2060 × 0308 × 0020 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 2060 × 0028 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2060 × 0020 ÷ 0028 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2060 × 0308 × 0028 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 2060 × 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 0020 ÷ 0001 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 0308 × 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 2060 × 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 0020 ÷ 200D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 0308 × 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 2060 × 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 0020 ÷ 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 0308 × 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 2060 × 50005 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0020 ÷ 50005 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0308 × 50005 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 2060 × 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 0020 ÷ 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 0308 × 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 2060 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0020 ÷ 3041 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0308 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 2060 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B ÷ 1B05 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200B × 0020 ÷ 1B05 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1B05 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1B05 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200B ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B ÷ 0308 × 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200B ÷ 11003 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200B × 0020 ÷ 11003 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200B ÷ 0308 ÷ 11003 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 11003 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200B ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200B × 0020 ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200B ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EM DASH (B2) ÷ [0.3]
+× 200B × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EM DASH (B2) ÷ [0.3]
+× 200B ÷ 0308 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 200B ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B ÷ 0308 × 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200B ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B ÷ 0308 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200B × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B × 0020 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B ÷ 0308 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200B ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B ÷ 0308 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200B ÷ 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B × 0020 ÷ 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B ÷ 0308 × 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200B × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B × 0020 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B ÷ 0308 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200B ÷ 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B × 0020 ÷ 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B ÷ 0308 × 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200B ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B ÷ 0308 × 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200B ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B ÷ 0308 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200B ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B ÷ 0308 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200B ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B ÷ 0308 × 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200B ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B ÷ 0308 × 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200B ÷ 1B50 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200B × 0020 ÷ 1B50 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1B50 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1B50 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200B ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B ÷ 0308 × 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200B ÷ 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMMA (IS) ÷ [0.3]
+× 200B × 0020 ÷ 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] COMMA (IS) ÷ [0.3]
+× 200B ÷ 0308 × 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 200B ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200B ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B ÷ 0308 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200B ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200B × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B × 0020 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B ÷ 0308 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200B × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B ÷ 0308 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200B ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B ÷ 0308 × 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200B ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200B × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200B ÷ 0308 × 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200B ÷ 2329 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200B × 0020 ÷ 2329 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200B ÷ 0308 ÷ 2329 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 2329 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200B ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200B × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200B ÷ 0308 × 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200B ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B ÷ 0308 × 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200B ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200B × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200B ÷ 0308 × 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200B × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200B ÷ 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] SOLIDUS (SY) ÷ [0.3]
+× 200B × 0020 ÷ 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] SOLIDUS (SY) ÷ [0.3]
+× 200B ÷ 0308 × 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 200B ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200B × 0020 ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200B ÷ 1B44 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200B × 0020 ÷ 1B44 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1B44 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1B44 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200B ÷ 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WORD JOINER (WJ) ÷ [0.3]
+× 200B × 0020 ÷ 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WORD JOINER (WJ) ÷ [0.3]
+× 200B ÷ 0308 × 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200B × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B × 0020 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B ÷ 0308 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200B ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200B ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B ÷ 0308 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200B ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B ÷ 0308 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200B ÷ 00AB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200B × 0020 ÷ 00AB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200B ÷ 0308 × 00AB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00AB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200B ÷ 00BB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200B × 0020 ÷ 00BB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200B ÷ 0308 × 00BB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 00BB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200B ÷ 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200B × 0020 ÷ 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200B ÷ 0308 × 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200B ÷ 0308 × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200B ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200B × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200B ÷ 0308 × 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200B ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B ÷ 0308 × 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200B ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B ÷ 0308 × 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200B ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B ÷ 0308 × 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200B ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B ÷ 0308 × 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200B ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200B ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B ÷ 0308 × 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200B ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 ÷ 1B05 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1B05 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1B05 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F1E6 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F1E6 ÷ 11003 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 11003 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 11003 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F1E6 ÷ 1BC0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1BC0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1BC0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F1E6 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F1E6 × 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 × 0308 × 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F1E6 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F1E6 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 × 0020 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 × 0308 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F1E6 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 0020 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 0308 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F1E6 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0020 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0308 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F1E6 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0020 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0308 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F1E6 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 0020 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 0308 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F1E6 × 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 × 0308 × 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F1E6 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 × 0020 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 × 0308 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F1E6 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 × 0020 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 × 0308 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F1E6 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F1E6 × 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 × 0308 × 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F1E6 ÷ 1B50 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1B50 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1B50 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F1E6 × 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 0308 × 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F1E6 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F1E6 × 0020 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F1E6 × 0308 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F1E6 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F1E6 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F1E6 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F1E6 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0020 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0308 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F1E6 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 0020 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 0308 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F1E6 × 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 × 0308 × 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F1E6 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F1E6 ÷ 2329 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 2329 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 2329 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F1E6 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F1E6 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F1E6 × 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0308 × 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F1E6 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 0020 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F1E6 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 0020 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 0308 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F1E6 ÷ 1BF2 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1BF2 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1BF2 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F1E6 ÷ 1B44 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1B44 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1B44 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F1E6 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 0020 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 0308 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F1E6 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 0020 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 0308 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F1E6 × 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 × 0308 × 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F1E6 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F1E6 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F1E6 × 00AB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00AB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F1E6 × 0308 × 00AB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F1E6 × 00BB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F1E6 × 0020 × 00BB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F1E6 × 0308 × 00BB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 00BB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F1E6 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F1E6 × 0020 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F1E6 × 0308 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F1E6 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F1E6 × 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F1E6 × 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F1E6 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F1E6 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F1E6 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 0308 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F1E6 × 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 × 0020 ÷ 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 × 0308 × 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F1E6 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D ÷ 1B05 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 261D × 0020 ÷ 1B05 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 261D × 0308 ÷ 1B05 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 261D ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D × 0020 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D × 0308 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 261D ÷ 11003 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 261D × 0020 ÷ 11003 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 261D × 0308 ÷ 11003 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 11003 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 261D ÷ 1BC0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 261D × 0020 ÷ 1BC0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 261D × 0308 ÷ 1BC0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 261D ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0020 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0308 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 261D × 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D × 0020 ÷ 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D × 0308 × 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 261D ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 0020 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 0308 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 261D × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D × 0020 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D × 0308 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D × 0308 × 0020 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 261D ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 0020 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 0308 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 261D × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0020 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0308 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 0308 × 0020 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 261D × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0020 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0308 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0308 × 0020 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 261D × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 0020 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 0308 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 0308 × 0020 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 261D × 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D × 0020 ÷ 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D × 0308 × 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 261D ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D × 0020 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D × 0308 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 261D ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D × 0020 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D × 0308 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 261D ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 0020 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 0308 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 261D × 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D × 0020 ÷ 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D × 0308 × 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 261D ÷ 1B50 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 261D × 0020 ÷ 1B50 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 261D × 0308 ÷ 1B50 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 261D × 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0020 ÷ 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0308 × 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] COMMA (IS) ÷ [0.3]
+× 261D × 0020 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 261D × 0308 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 261D × 0308 × 0020 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 261D ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D × 0020 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D × 0308 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 261D ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D × 0020 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D × 0308 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 261D ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 0020 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 0308 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0020 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0308 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0308 × 0020 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 261D × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 0020 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 0308 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 0308 × 0020 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 261D × 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D × 0020 ÷ 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D × 0308 × 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 261D ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D × 0020 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D × 0308 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 261D ÷ 2329 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 261D × 0020 ÷ 2329 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 261D × 0308 ÷ 2329 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 2329 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 261D × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 261D × 0020 ÷ 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 261D × 0308 × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 261D ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0020 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0308 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 261D × 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0020 ÷ 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0308 × 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 261D × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 0020 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 0308 × 0020 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 261D × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 261D × 0020 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 261D × 0308 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 261D × 0308 × 0020 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 261D ÷ 1BF2 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 261D × 0020 ÷ 1BF2 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 261D × 0308 ÷ 1BF2 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 261D ÷ 1B44 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 261D × 0020 ÷ 1B44 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 261D × 0308 ÷ 1B44 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 261D × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 0020 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 0308 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 0308 × 0020 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 261D × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D × 0020 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D × 0308 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D × 0308 × 0020 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 261D ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D × 0020 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D × 0308 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 261D ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 0020 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 0308 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 261D × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [30.21] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0020 ÷ 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0308 × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.21] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 261D × 00AB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 261D × 0020 ÷ 00AB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 261D × 0308 × 00AB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00AB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 261D × 00BB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 261D × 0020 × 00BB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 261D × 0308 × 00BB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 261D × 0308 × 0020 × 00BB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 261D × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 261D × 0020 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 261D × 0308 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 261D × 0308 × 0020 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 261D ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 261D × 0020 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 261D × 0308 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 261D × 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 0020 ÷ 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 0308 × 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 261D × 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D × 0020 ÷ 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D × 0308 × 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 261D ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D × 0020 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D × 0308 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 261D ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D × 0020 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D × 0308 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 261D ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 0020 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 0308 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 261D × 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D × 0020 ÷ 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D × 0308 × 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 261D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB ÷ 1B05 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1B05 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1B05 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 1F3FB ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 1F3FB ÷ 11003 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F3FB × 0020 ÷ 11003 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F3FB × 0308 ÷ 11003 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 11003 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 1F3FB ÷ 1BC0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1BC0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1BC0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 1F3FB ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0020 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0308 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 1F3FB × 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB × 0308 × 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 1F3FB ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 0308 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 1F3FB × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB × 0020 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB × 0308 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 1F3FB ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 0020 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 0308 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 1F3FB × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0020 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0308 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 1F3FB × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0020 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0308 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 1F3FB × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 0020 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 0308 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 1F3FB × 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB × 0308 × 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 1F3FB ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB × 0020 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB × 0308 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 1F3FB ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB × 0020 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB × 0308 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 1F3FB ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 1F3FB × 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB × 0020 ÷ 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB × 0308 × 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 1F3FB ÷ 1B50 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1B50 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1B50 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 1F3FB × 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 0020 ÷ 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 0308 × 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1F3FB × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F3FB × 0020 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F3FB × 0308 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 1F3FB ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 1F3FB ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB × 0020 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB × 0308 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1F3FB ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1F3FB × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0020 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0308 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 1F3FB × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 0020 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 0308 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 1F3FB × 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB × 0020 ÷ 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB × 0308 × 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 1F3FB ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 1F3FB ÷ 2329 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F3FB × 0020 ÷ 2329 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F3FB × 0308 ÷ 2329 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 2329 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 1F3FB × 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB × 0308 × 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 1F3FB ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 1F3FB × 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0308 × 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 1F3FB × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 0020 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 1F3FB × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 0020 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 0308 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 1F3FB ÷ 1BF2 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1BF2 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1BF2 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 1F3FB ÷ 1B44 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1B44 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1B44 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 1F3FB × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 0020 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 0308 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 1F3FB × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB × 0020 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB × 0308 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 1F3FB ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 1F3FB ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB × 0020 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB × 0308 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 1F3FB ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0020 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0308 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 1F3FB × 00AB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00AB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F3FB × 0308 × 00AB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00AB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 1F3FB × 00BB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F3FB × 0020 × 00BB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F3FB × 0308 × 00BB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 00BB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F3FB × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F3FB × 0020 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F3FB × 0308 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F3FB × 0308 × 0020 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 1F3FB ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 1F3FB × 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 0308 × 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 1F3FB × 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB × 0020 ÷ 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB × 0308 × 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 1F3FB ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 1F3FB ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 1F3FB ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 0020 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 0308 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1F3FB × 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB × 0020 ÷ 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB × 0308 × 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 1F3FB × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00AB × 1B05 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00AB × 0020 × 1B05 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00AB × 0308 × 1B05 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1B05 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00AB × 0023 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] NUMBER SIGN (AL) ÷ [0.3]
+× 00AB × 0020 × 0023 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] NUMBER SIGN (AL) ÷ [0.3]
+× 00AB × 0308 × 0023 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] NUMBER SIGN (AL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0023 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] NUMBER SIGN (AL) ÷ [0.3]
+× 00AB × 11003 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00AB × 0020 × 11003 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00AB × 0308 × 11003 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00AB × 0308 × 0020 × 11003 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00AB × 1BC0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] BATAK LETTER A (AS) ÷ [0.3]
+× 00AB × 0020 × 1BC0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] BATAK LETTER A (AS) ÷ [0.3]
+× 00AB × 0308 × 1BC0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] BATAK LETTER A (AS) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1BC0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] BATAK LETTER A (AS) ÷ [0.3]
+× 00AB × 2014 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] EM DASH (B2) ÷ [0.3]
+× 00AB × 0020 × 2014 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] EM DASH (B2) ÷ [0.3]
+× 00AB × 0308 × 2014 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] EM DASH (B2) ÷ [0.3]
+× 00AB × 0308 × 0020 × 2014 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] EM DASH (B2) ÷ [0.3]
+× 00AB × 0009 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00AB × 0020 × 0009 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00AB × 0308 × 0009 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0009 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00AB × 00B4 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] ACUTE ACCENT (BB) ÷ [0.3]
+× 00AB × 0020 × 00B4 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] ACUTE ACCENT (BB) ÷ [0.3]
+× 00AB × 0308 × 00B4 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] ACUTE ACCENT (BB) ÷ [0.3]
+× 00AB × 0308 × 0020 × 00B4 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] ACUTE ACCENT (BB) ÷ [0.3]
+× 00AB × 000B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00AB × 0020 × 000B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00AB × 0308 × 000B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00AB × 0308 × 0020 × 000B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00AB × FFFC ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00AB × 0020 × FFFC ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00AB × 0308 × FFFC ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00AB × 0308 × 0020 × FFFC ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00AB × 007D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00AB × 0020 × 007D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00AB × 0308 × 007D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 007D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00AB × 000D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00AB × 0020 × 000D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00AB × 0308 × 000D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00AB × 0308 × 0020 × 000D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00AB × 0021 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00AB × 0020 × 0021 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00AB × 0308 × 0021 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0021 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00AB × 00A0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00AB × 0020 × 00A0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00AB × 0308 × 00A0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 00A0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00AB × AC00 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00AB × 0020 × AC00 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00AB × 0308 × AC00 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00AB × 0308 × 0020 × AC00 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00AB × AC01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00AB × 0020 × AC01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00AB × 0308 × AC01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00AB × 0308 × 0020 × AC01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00AB × 05D0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00AB × 0020 × 05D0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00AB × 0308 × 05D0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 05D0 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00AB × 002D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00AB × 0020 × 002D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00AB × 0308 × 002D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00AB × 0308 × 0020 × 002D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00AB × 1B50 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00AB × 0020 × 1B50 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00AB × 0308 × 1B50 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1B50 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00AB × 2024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] ONE DOT LEADER (IN) ÷ [0.3]
+× 00AB × 0020 × 2024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] ONE DOT LEADER (IN) ÷ [0.3]
+× 00AB × 0308 × 2024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] ONE DOT LEADER (IN) ÷ [0.3]
+× 00AB × 0308 × 0020 × 2024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] ONE DOT LEADER (IN) ÷ [0.3]
+× 00AB × 002C ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [13.02] COMMA (IS) ÷ [0.3]
+× 00AB × 0020 × 002C ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00AB × 0308 × 002C ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 00AB × 0308 × 0020 × 002C ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00AB × 1100 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00AB × 0020 × 1100 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00AB × 0308 × 1100 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1100 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00AB × 11A8 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00AB × 0020 × 11A8 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00AB × 0308 × 11A8 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00AB × 0308 × 0020 × 11A8 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00AB × 1160 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00AB × 0020 × 1160 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00AB × 0308 × 1160 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1160 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00AB × 000A ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00AB × 0020 × 000A ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00AB × 0308 × 000A ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00AB × 0308 × 0020 × 000A ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00AB × 0085 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00AB × 0020 × 0085 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00AB × 0308 × 0085 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0085 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00AB × 17D6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00AB × 0020 × 17D6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00AB × 0308 × 17D6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00AB × 0308 × 0020 × 17D6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00AB × 0030 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] DIGIT ZERO (NU) ÷ [0.3]
+× 00AB × 0020 × 0030 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] DIGIT ZERO (NU) ÷ [0.3]
+× 00AB × 0308 × 0030 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] DIGIT ZERO (NU) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0030 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] DIGIT ZERO (NU) ÷ [0.3]
+× 00AB × 2329 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00AB × 0020 × 2329 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00AB × 0308 × 2329 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00AB × 0308 × 0020 × 2329 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00AB × 0025 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] PERCENT SIGN (PO) ÷ [0.3]
+× 00AB × 0020 × 0025 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] PERCENT SIGN (PO) ÷ [0.3]
+× 00AB × 0308 × 0025 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] PERCENT SIGN (PO) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0025 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] PERCENT SIGN (PO) ÷ [0.3]
+× 00AB × 0024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] DOLLAR SIGN (PR) ÷ [0.3]
+× 00AB × 0020 × 0024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] DOLLAR SIGN (PR) ÷ [0.3]
+× 00AB × 0308 × 0024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] DOLLAR SIGN (PR) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0024 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] DOLLAR SIGN (PR) ÷ [0.3]
+× 00AB × 0022 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] QUOTATION MARK (QU) ÷ [0.3]
+× 00AB × 0020 × 0022 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] QUOTATION MARK (QU) ÷ [0.3]
+× 00AB × 0308 × 0022 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] QUOTATION MARK (QU) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0022 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] QUOTATION MARK (QU) ÷ [0.3]
+× 00AB × 0020 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) ÷ [0.3]
+× 00AB × 0020 × 0020 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00AB × 0308 × 0020 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0020 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00AB × 002F ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00AB × 0020 × 002F ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00AB × 0308 × 002F ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 00AB × 0308 × 0020 × 002F ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00AB × 1BF2 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00AB × 0020 × 1BF2 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00AB × 0308 × 1BF2 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1BF2 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00AB × 1B44 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00AB × 0020 × 1B44 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00AB × 0308 × 1B44 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1B44 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00AB × 2060 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00AB × 0020 × 2060 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00AB × 0308 × 2060 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00AB × 0308 × 0020 × 2060 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00AB × 200B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00AB × 0020 × 200B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00AB × 0308 × 200B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00AB × 0308 × 0020 × 200B ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00AB × 1F1E6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00AB × 0020 × 1F1E6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00AB × 0308 × 1F1E6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1F1E6 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00AB × 261D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00AB × 0020 × 261D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00AB × 0308 × 261D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00AB × 0308 × 0020 × 261D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00AB × 1F3FB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00AB × 0020 × 1F3FB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00AB × 0308 × 1F3FB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00AB × 0308 × 0020 × 1F3FB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00AB × 00AB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00AB × 0020 × 00AB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00AB × 0308 × 00AB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00AB × 0308 × 0020 × 00AB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00AB × 00BB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00AB × 0020 × 00BB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00AB × 0308 × 00BB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00AB × 0308 × 0020 × 00BB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00AB × 0029 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00AB × 0020 × 0029 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00AB × 0308 × 0029 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0029 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00AB × 0028 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00AB × 0020 × 0028 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00AB × 0308 × 0028 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0028 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00AB × 0001 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00AB × 0020 × 0001 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00AB × 0308 × 0001 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0001 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00AB × 200D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00AB × 0020 × 200D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00AB × 0308 × 200D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00AB × 0308 × 0020 × 200D ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00AB × 00A7 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00AB × 0020 × 00A7 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00AB × 0308 × 00A7 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 00A7 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00AB × 50005 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00AB × 0020 × 50005 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00AB × 0308 × 50005 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 50005 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00AB × 0E01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00AB × 0020 × 0E01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00AB × 0308 × 0E01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00AB × 0308 × 0020 × 0E01 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00AB × 3041 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [15.11] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00AB × 0020 × 3041 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00AB × 0308 × 3041 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00AB × 0308 × 0020 × 3041 ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.11] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00BB × 1B05 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00BB × 0020 ÷ 1B05 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00BB × 0308 × 1B05 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00BB × 0023 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
+× 00BB × 0020 ÷ 0023 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00BB × 0308 × 0023 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00BB × 11003 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00BB × 0020 ÷ 11003 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00BB × 0308 × 11003 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 11003 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00BB × 1BC0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] BATAK LETTER A (AS) ÷ [0.3]
+× 00BB × 0020 ÷ 1BC0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00BB × 0308 × 1BC0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BATAK LETTER A (AS) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00BB × 2014 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] EM DASH (B2) ÷ [0.3]
+× 00BB × 0020 ÷ 2014 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00BB × 0308 × 2014 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EM DASH (B2) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00BB × 0009 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00BB × 0020 ÷ 0009 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00BB × 0308 × 0009 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00BB × 00B4 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 00BB × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00BB × 0308 × 00B4 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00BB × 000B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00BB × 0020 × 000B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00BB × 0308 × 000B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00BB × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00BB × FFFC ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00BB × 0020 ÷ FFFC ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00BB × 0308 × FFFC ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00BB × 007D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00BB × 0020 × 007D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00BB × 0308 × 007D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00BB × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00BB × 000D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00BB × 0020 × 000D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00BB × 0308 × 000D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00BB × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00BB × 0021 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00BB × 0020 × 0021 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00BB × 0308 × 0021 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00BB × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00BB × 00A0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00BB × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00BB × 0308 × 00A0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00BB × AC00 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00BB × 0020 ÷ AC00 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00BB × 0308 × AC00 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00BB × AC01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00BB × 0020 ÷ AC01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00BB × 0308 × AC01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00BB × 05D0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00BB × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00BB × 0308 × 05D0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00BB × 002D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00BB × 0020 ÷ 002D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00BB × 0308 × 002D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00BB × 1B50 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00BB × 0020 ÷ 1B50 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00BB × 0308 × 1B50 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00BB × 2024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 00BB × 0020 ÷ 2024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00BB × 0308 × 2024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00BB × 002C ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] COMMA (IS) ÷ [0.3]
+× 00BB × 0020 × 002C ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00BB × 0308 × 002C ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 00BB × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00BB × 1100 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00BB × 0020 ÷ 1100 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00BB × 0308 × 1100 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00BB × 11A8 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00BB × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00BB × 0308 × 11A8 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00BB × 1160 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00BB × 0020 ÷ 1160 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00BB × 0308 × 1160 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00BB × 000A ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00BB × 0020 × 000A ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00BB × 0308 × 000A ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00BB × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00BB × 0085 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00BB × 0020 × 0085 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00BB × 0308 × 0085 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00BB × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00BB × 17D6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00BB × 0020 ÷ 17D6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00BB × 0308 × 17D6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00BB × 0030 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
+× 00BB × 0020 ÷ 0030 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00BB × 0308 × 0030 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00BB × 2329 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00BB × 0020 ÷ 2329 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00BB × 0308 × 2329 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 2329 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00BB × 0025 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
+× 00BB × 0020 ÷ 0025 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00BB × 0308 × 0025 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00BB × 0024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 00BB × 0020 ÷ 0024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00BB × 0308 × 0024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00BB × 0022 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00BB × 0020 ÷ 0022 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00BB × 0308 × 0022 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00BB × 0020 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [0.3]
+× 00BB × 0020 × 0020 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00BB × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00BB × 002F ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00BB × 0020 × 002F ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00BB × 0308 × 002F ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 00BB × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00BB × 1BF2 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00BB × 0020 ÷ 1BF2 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00BB × 0308 × 1BF2 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00BB × 1B44 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00BB × 0020 ÷ 1B44 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00BB × 0308 × 1B44 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00BB × 2060 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00BB × 0020 × 2060 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00BB × 0308 × 2060 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00BB × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00BB × 200B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00BB × 0020 × 200B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00BB × 0308 × 200B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00BB × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00BB × 1F1E6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00BB × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00BB × 0308 × 1F1E6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00BB × 261D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00BB × 0020 ÷ 261D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00BB × 0308 × 261D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00BB × 1F3FB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00BB × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00BB × 0308 × 1F3FB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00BB × 00AB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00BB × 0020 ÷ 00AB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00BB × 0308 × 00AB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 00AB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00BB × 00BB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00BB × 0020 × 00BB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00BB × 0308 × 00BB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00BB × 0308 × 0020 × 00BB ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00BB × 0029 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00BB × 0020 × 0029 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00BB × 0308 × 0029 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00BB × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00BB × 0028 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00BB × 0020 ÷ 0028 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00BB × 0308 × 0028 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00BB × 0001 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00BB × 0020 ÷ 0001 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00BB × 0308 × 0001 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00BB × 200D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00BB × 0020 ÷ 200D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00BB × 0308 × 200D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00BB × 00A7 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00BB × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00BB × 0308 × 00A7 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00BB × 50005 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00BB × 0020 ÷ 50005 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00BB × 0308 × 50005 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00BB × 0E01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00BB × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00BB × 0308 × 0E01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00BB × 3041 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00BB × 0020 ÷ 3041 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00BB × 0308 × 3041 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00BB × 0308 × 0020 ÷ 3041 ÷ # × [0.3] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 ÷ 1B05 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0029 × 0020 ÷ 1B05 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0029 × 0308 ÷ 1B05 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0029 × 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [30.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 × 0308 × 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0029 ÷ 11003 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0029 × 0020 ÷ 11003 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0029 × 0308 ÷ 11003 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0029 ÷ 1BC0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0029 × 0020 ÷ 1BC0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0029 × 0308 ÷ 1BC0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0029 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0308 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0029 × 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 × 0308 × 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0029 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 0308 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0029 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 × 0020 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 × 0308 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0029 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 0308 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0029 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0020 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0308 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0029 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0020 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0308 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0029 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 0020 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 0308 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0029 × 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 × 0308 × 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0029 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 × 0308 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0029 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 0308 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0029 × 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [30.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 0308 × 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0029 × 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 × 0020 ÷ 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 × 0308 × 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0029 ÷ 1B50 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0029 × 0020 ÷ 1B50 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0029 × 0308 ÷ 1B50 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0029 × 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 0308 × 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0029 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [13.02] COMMA (IS) ÷ [0.3]
+× 0029 × 0020 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0029 × 0308 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0029 × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0029 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 × 0308 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0029 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 × 0308 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0029 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 0308 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0029 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0020 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0308 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0029 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 0020 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 0308 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0029 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0020 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0308 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0308 × 0020 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0029 × 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [30.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 × 0308 × 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0029 ÷ 2329 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0029 × 0020 ÷ 2329 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0029 × 0308 ÷ 2329 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0029 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 × 0308 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0029 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0308 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0029 × 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0308 × 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0029 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 0020 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0029 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 0020 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 0308 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0029 × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0029 ÷ 1BF2 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0029 × 0020 ÷ 1BF2 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0029 × 0308 ÷ 1BF2 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0029 ÷ 1B44 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0029 × 0020 ÷ 1B44 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0029 × 0308 ÷ 1B44 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0029 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 0020 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 0308 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0029 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 × 0020 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 × 0308 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0029 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 × 0308 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0029 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 × 0020 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 × 0308 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0029 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0308 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0029 × 00AB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0029 × 0020 ÷ 00AB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0029 × 0308 × 00AB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0029 × 00BB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0029 × 0020 × 00BB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0029 × 0308 × 00BB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0029 × 0308 × 0020 × 00BB ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0029 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0029 × 0020 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0029 × 0308 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0029 × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0029 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0029 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0029 × 0308 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0029 × 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 0308 × 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0029 × 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 0020 ÷ 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 0308 × 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0029 × 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [30.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 0308 × 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0029 × 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [30.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0308 × 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0029 × 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [30.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 0308 × 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0029 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0020 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0308 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0029 × 0308 × 0020 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP_CP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 1B05 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0028 × 0020 × 1B05 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0028 × 0308 × 1B05 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1B05 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0028 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 0020 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 0308 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0028 × 11003 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0028 × 0020 × 11003 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0028 × 0308 × 11003 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0028 × 0308 × 0020 × 11003 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0028 × 1BC0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0028 × 0020 × 1BC0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0028 × 0308 × 1BC0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1BC0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0028 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0020 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0308 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
+× 0028 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 0020 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 0308 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0028 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 0020 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 0308 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0028 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × 0020 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × 0308 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × 0308 × 0020 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0028 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 0020 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 0308 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 0308 × 0020 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0028 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0020 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0308 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0028 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0020 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0308 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0308 × 0020 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0028 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 0020 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 0308 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0028 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × 0020 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × 0308 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0028 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × 0020 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × 0308 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × 0308 × 0020 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0028 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 0020 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 0308 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 0308 × 0020 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0028 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 0020 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 0308 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0028 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 0020 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 0308 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 0308 × 0020 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0028 × 1B50 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0028 × 0020 × 1B50 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0028 × 0308 × 1B50 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1B50 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0028 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 0020 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 0308 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0028 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [13.02] COMMA (IS) ÷ [0.3]
+× 0028 × 0020 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0028 × 0308 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0028 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 0020 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 0308 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0028 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 0020 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 0308 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 0308 × 0020 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0028 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 0020 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 0308 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0028 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0020 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0308 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0308 × 0020 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0028 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 0020 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 0308 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0028 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0020 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0308 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0028 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0020 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0308 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0028 × 2329 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0028 × 0020 × 2329 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0028 × 0308 × 2329 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2329 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0028 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0020 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0308 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0028 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0020 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0308 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0028 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0020 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0308 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0028 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 0020 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 0308 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0028 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 0020 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 0308 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 0308 × 0020 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0028 × 1BF2 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0028 × 0020 × 1BF2 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0028 × 0308 × 1BF2 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1BF2 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0028 × 1B44 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0028 × 0020 × 1B44 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0028 × 0308 × 1B44 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1B44 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0028 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 0020 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 0308 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 0308 × 0020 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0028 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 0020 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 0308 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 0308 × 0020 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0028 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 0020 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 0308 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0028 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 0020 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 0308 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 0308 × 0020 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0028 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0020 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0308 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 0308 × 0020 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0028 × 00AB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0028 × 0020 × 00AB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0028 × 0308 × 00AB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00AB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0028 × 00BB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0028 × 0020 × 00BB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0028 × 0308 × 00BB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00BB ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0028 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0028 × 0020 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0028 × 0308 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0028 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0028 × 0020 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0028 × 0308 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0028 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 0020 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 0308 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0028 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 0020 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 0308 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 0308 × 0020 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0028 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 0020 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 0308 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0028 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0020 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0308 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0028 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 0020 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 0308 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 0308 × 0020 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0028 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0020 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0308 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0028 × 0308 × 0020 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 ÷ 1B05 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0001 × 0020 ÷ 1B05 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0001 × 0308 ÷ 1B05 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0001 × 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 × 0020 ÷ 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 × 0308 × 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0001 ÷ 11003 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0001 × 0020 ÷ 11003 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0001 × 0308 ÷ 11003 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0001 ÷ 1BC0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0001 × 0020 ÷ 1BC0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0001 × 0308 ÷ 1BC0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0001 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0020 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0308 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0001 × 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 × 0020 ÷ 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 × 0308 × 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0001 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 0020 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 0308 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0001 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 × 0020 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 × 0308 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 × 0308 × 0020 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0001 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 0020 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 0308 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0001 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0020 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0308 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 0308 × 0020 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0001 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0020 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0308 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0308 × 0020 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0001 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 0020 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 0308 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0001 × 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 × 0020 ÷ 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 × 0308 × 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0001 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 × 0020 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 × 0308 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0001 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 0020 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 0308 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0001 × 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 0020 ÷ 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 0308 × 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0001 × 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 × 0020 ÷ 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 × 0308 × 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0001 ÷ 1B50 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0001 × 0020 ÷ 1B50 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0001 × 0308 ÷ 1B50 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0001 × 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 0020 ÷ 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 0308 × 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0001 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 0001 × 0020 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0001 × 0308 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 0001 × 0308 × 0020 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0001 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 × 0020 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 × 0308 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0001 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 × 0020 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 × 0308 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0001 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 0020 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 0308 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0001 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0020 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0308 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0308 × 0020 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0001 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 0020 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 0308 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0001 × 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0020 ÷ 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0308 × 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0001 × 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0020 ÷ 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0308 × 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0001 ÷ 2329 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0001 × 0020 ÷ 2329 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0001 × 0308 ÷ 2329 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0001 × 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0020 ÷ 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0308 × 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0001 × 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0020 ÷ 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0308 × 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0001 × 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0020 ÷ 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0308 × 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0001 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 0020 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0001 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 0020 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 0308 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 0001 × 0308 × 0020 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0001 ÷ 1BF2 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0001 × 0020 ÷ 1BF2 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0001 × 0308 ÷ 1BF2 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0001 ÷ 1B44 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0001 × 0020 ÷ 1B44 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0001 × 0308 ÷ 1B44 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0001 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 0020 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 0308 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 0308 × 0020 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0001 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 × 0020 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 × 0308 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 × 0308 × 0020 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0001 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 × 0020 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 × 0308 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0001 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 × 0020 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 × 0308 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0001 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0020 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0308 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0001 × 00AB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0001 × 0020 ÷ 00AB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0001 × 0308 × 00AB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0001 × 00BB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0001 × 0020 × 00BB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0001 × 0308 × 00BB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0001 × 0308 × 0020 × 00BB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0001 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0001 × 0020 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0001 × 0308 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0001 × 0308 × 0020 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0001 × 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0001 × 0020 ÷ 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0001 × 0308 × 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0001 × 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 0020 ÷ 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 0308 × 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0001 × 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 0020 ÷ 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 0308 × 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0001 × 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 0020 ÷ 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 0308 × 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0001 × 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0020 ÷ 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0308 × 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0001 × 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 0020 ÷ 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 0308 × 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0001 × 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0020 ÷ 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0308 × 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0001 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 1B05 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200D × 0020 ÷ 1B05 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200D × 0308 ÷ 1B05 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 200D × 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 0308 × 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 200D × 11003 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200D × 0020 ÷ 11003 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200D × 0308 ÷ 11003 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 11003 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 200D × 1BC0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] BATAK LETTER A (AS) ÷ [0.3]
+× 200D × 0020 ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200D × 0308 ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 200D × 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] EM DASH (B2) ÷ [0.3]
+× 200D × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0308 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 200D × 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 0308 × 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 200D × 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 0308 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 200D × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × 0020 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × 0308 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × 0308 × 0020 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 200D × FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 0308 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 200D × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0020 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0308 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 0308 × 0020 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 200D × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0020 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0308 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0308 × 0020 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 200D × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 0308 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 0308 × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 200D × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 0308 × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × 0308 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 200D × AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 0308 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 200D × 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 0308 × 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 200D × 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 0308 × 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 200D × 1B50 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200D × 0020 ÷ 1B50 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200D × 0308 ÷ 1B50 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 200D × 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 0308 × 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 200D × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMMA (IS) ÷ [0.3]
+× 200D × 0020 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 200D × 0308 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
+× 200D × 0308 × 0020 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 200D × 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 0308 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 200D × 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 0308 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 200D × 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 0308 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 200D × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0020 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0308 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0308 × 0020 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 200D × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 0308 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 0308 × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 200D × 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0308 × 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 200D × 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0308 × 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 200D × 2329 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200D × 0020 ÷ 2329 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200D × 0308 ÷ 2329 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 2329 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 200D × 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0308 × 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 200D × 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0308 × 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 200D × 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0308 × 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 200D × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 0308 × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 200D × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] SOLIDUS (SY) ÷ [0.3]
+× 200D × 0020 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 200D × 0308 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
+× 200D × 0308 × 0020 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 200D × 1BF2 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200D × 0020 ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200D × 0308 ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 200D × 1B44 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200D × 0020 ÷ 1B44 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200D × 0308 ÷ 1B44 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 200D × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 0308 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 0308 × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 200D × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 0020 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 0308 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 0308 × 0020 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 200D × 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 0308 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 200D × 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 0308 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 200D × 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0308 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 200D × 00AB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200D × 0020 ÷ 00AB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200D × 0308 × 00AB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00AB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 200D × 00BB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200D × 0020 × 00BB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200D × 0308 × 00BB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200D × 0308 × 0020 × 00BB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 200D × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200D × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200D × 0308 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200D × 0308 × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 200D × 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200D × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200D × 0308 × 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 200D × 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 0308 × 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 200D × 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 0308 × 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 200D × 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 0308 × 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 200D × 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0308 × 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 200D × 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 0308 × 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 200D × 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0308 × 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 ÷ 1B05 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A7 × 0020 ÷ 1B05 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A7 × 0308 ÷ 1B05 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 00A7 × 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 × 0308 × 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 00A7 ÷ 11003 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A7 × 0020 ÷ 11003 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A7 × 0308 ÷ 11003 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 00A7 ÷ 1BC0 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A7 × 0020 ÷ 1BC0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A7 × 0308 ÷ 1BC0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 00A7 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0020 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0308 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 00A7 × 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 × 0020 ÷ 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 × 0308 × 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 00A7 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 0020 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 0308 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 00A7 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 × 0020 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 × 0308 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 00A7 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 0020 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 0308 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 00A7 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0020 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0308 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 00A7 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0020 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0308 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 00A7 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 0020 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 0308 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 00A7 × 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 × 0020 ÷ 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 × 0308 × 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 00A7 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 × 0020 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 × 0308 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 00A7 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 0020 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 0308 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 00A7 × 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 0020 ÷ 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 0308 × 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 00A7 × 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 × 0020 ÷ 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 × 0308 × 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 00A7 ÷ 1B50 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A7 × 0020 ÷ 1B50 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A7 × 0308 ÷ 1B50 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 00A7 × 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 0020 ÷ 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 0308 × 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 00A7 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A7 × 0020 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A7 × 0308 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 00A7 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 × 0020 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 × 0308 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 00A7 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 × 0020 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 × 0308 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 00A7 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 0020 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 0308 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 00A7 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0020 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0308 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 00A7 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 0020 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 0308 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 00A7 × 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0020 ÷ 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0308 × 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 00A7 × 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0020 ÷ 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0308 × 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 00A7 ÷ 2329 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A7 × 0020 ÷ 2329 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A7 × 0308 ÷ 2329 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 00A7 × 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0020 ÷ 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0308 × 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 00A7 × 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0020 ÷ 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0308 × 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 00A7 × 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0020 ÷ 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0308 × 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 00A7 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 0020 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 00A7 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 0020 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 0308 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 00A7 ÷ 1BF2 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A7 × 0020 ÷ 1BF2 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A7 × 0308 ÷ 1BF2 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 00A7 ÷ 1B44 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A7 × 0020 ÷ 1B44 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A7 × 0308 ÷ 1B44 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 00A7 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 0020 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 0308 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 00A7 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 × 0020 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 × 0308 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 00A7 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 × 0020 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 × 0308 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 00A7 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 × 0020 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 × 0308 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 00A7 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0020 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0308 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 00A7 × 00AB ÷ # × [0.3] SECTION SIGN (AI_AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A7 × 0020 ÷ 00AB ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A7 × 0308 × 00AB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 00A7 × 00BB ÷ # × [0.3] SECTION SIGN (AI_AL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A7 × 0020 × 00BB ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A7 × 0308 × 00BB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 00BB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 00A7 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A7 × 0020 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A7 × 0308 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A7 × 0308 × 0020 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 00A7 × 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A7 × 0020 ÷ 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A7 × 0308 × 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 00A7 × 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 0020 ÷ 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 0308 × 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 00A7 × 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 0020 ÷ 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 0308 × 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 00A7 × 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 0308 × 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 00A7 × 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0308 × 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 00A7 × 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 0020 ÷ 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 0308 × 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 00A7 × 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0020 ÷ 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0308 × 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 00A7 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 ÷ 1B05 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 50005 × 0020 ÷ 1B05 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 50005 × 0308 ÷ 1B05 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 50005 × 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 × 0020 ÷ 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 × 0308 × 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 50005 ÷ 11003 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 50005 × 0020 ÷ 11003 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 50005 × 0308 ÷ 11003 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 50005 ÷ 1BC0 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 50005 × 0020 ÷ 1BC0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 50005 × 0308 ÷ 1BC0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 50005 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0020 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0308 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 50005 × 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 × 0020 ÷ 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 × 0308 × 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 50005 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 0020 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 0308 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 50005 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 × 0020 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 × 0308 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 × 0308 × 0020 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 50005 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 0020 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 0308 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 50005 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0020 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0308 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 0308 × 0020 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 50005 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0020 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0308 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0308 × 0020 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 50005 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 0020 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 0308 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 50005 × 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 × 0020 ÷ 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 × 0308 × 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 50005 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 × 0020 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 × 0308 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 50005 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 0020 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 0308 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 50005 × 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 0020 ÷ 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 0308 × 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 50005 × 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 × 0020 ÷ 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 × 0308 × 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 50005 ÷ 1B50 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 50005 × 0020 ÷ 1B50 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 50005 × 0308 ÷ 1B50 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 50005 × 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 0020 ÷ 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 0308 × 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 50005 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 50005 × 0020 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 50005 × 0308 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 50005 × 0308 × 0020 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 50005 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 × 0020 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 × 0308 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 50005 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 × 0020 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 × 0308 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 50005 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 0020 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 0308 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 50005 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0020 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0308 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0308 × 0020 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 50005 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 0020 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 0308 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 50005 × 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0020 ÷ 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0308 × 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 50005 × 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0020 ÷ 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0308 × 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 50005 ÷ 2329 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 50005 × 0020 ÷ 2329 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 50005 × 0308 ÷ 2329 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 50005 × 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0020 ÷ 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0308 × 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 50005 × 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0020 ÷ 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0308 × 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 50005 × 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0020 ÷ 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0308 × 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 50005 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 0020 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 50005 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 0020 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 0308 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 50005 × 0308 × 0020 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 50005 ÷ 1BF2 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 50005 × 0020 ÷ 1BF2 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 50005 × 0308 ÷ 1BF2 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 50005 ÷ 1B44 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 50005 × 0020 ÷ 1B44 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 50005 × 0308 ÷ 1B44 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 50005 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 0020 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 0308 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 0308 × 0020 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 50005 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 × 0020 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 × 0308 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 × 0308 × 0020 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 50005 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 × 0020 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 × 0308 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 50005 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 × 0020 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 × 0308 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 50005 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0020 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0308 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 50005 × 00AB ÷ # × [0.3] <reserved-50005> (XX_AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 50005 × 0020 ÷ 00AB ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 50005 × 0308 × 00AB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 50005 × 00BB ÷ # × [0.3] <reserved-50005> (XX_AL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 50005 × 0020 × 00BB ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 50005 × 0308 × 00BB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 50005 × 0308 × 0020 × 00BB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 50005 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 50005 × 0020 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 50005 × 0308 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 50005 × 0308 × 0020 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 50005 × 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 50005 × 0020 ÷ 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 50005 × 0308 × 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 50005 × 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 0020 ÷ 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 0308 × 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 50005 × 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 0020 ÷ 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 0308 × 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 50005 × 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 0020 ÷ 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 0308 × 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 50005 × 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0020 ÷ 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0308 × 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 50005 × 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 0020 ÷ 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 0308 × 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 50005 × 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0020 ÷ 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0308 × 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 50005 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 ÷ 1B05 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0E01 × 0020 ÷ 1B05 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0E01 × 0308 ÷ 1B05 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 0E01 × 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 × 0308 × 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 0E01 ÷ 11003 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0E01 × 0020 ÷ 11003 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0E01 × 0308 ÷ 11003 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 0E01 ÷ 1BC0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0E01 × 0020 ÷ 1BC0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0E01 × 0308 ÷ 1BC0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 0E01 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0020 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0308 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 0E01 × 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 × 0020 ÷ 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 × 0308 × 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 0E01 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 0020 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 0308 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 0E01 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 × 0020 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 × 0308 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 0E01 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 0020 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 0308 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 0E01 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0020 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0308 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0E01 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0020 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0308 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 0E01 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 0020 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 0308 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0E01 × 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 × 0020 ÷ 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 × 0308 × 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 0E01 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 × 0020 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 × 0308 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 0E01 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 0020 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 0308 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 0E01 × 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 0020 ÷ 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 0308 × 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 0E01 × 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 0020 ÷ 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 0308 × 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 ÷ 1B50 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0E01 × 0020 ÷ 1B50 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0E01 × 0308 ÷ 1B50 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 0E01 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 0020 ÷ 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 0308 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0E01 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] COMMA (IS) ÷ [0.3]
+× 0E01 × 0020 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0E01 × 0308 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 0E01 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 × 0020 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 × 0308 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 0E01 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 × 0020 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 × 0308 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 0E01 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 0020 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 0308 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 0E01 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0020 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0308 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 0E01 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 0020 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 0308 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 0E01 × 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0020 ÷ 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0308 × 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 0E01 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0020 ÷ 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0308 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 0E01 ÷ 2329 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0E01 × 0020 ÷ 2329 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0E01 × 0308 ÷ 2329 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 0E01 × 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0020 ÷ 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0308 × 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0020 ÷ 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0308 × 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 0E01 × 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0020 ÷ 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0308 × 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 0E01 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 0020 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0E01 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 0020 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 0308 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 0E01 ÷ 1BF2 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0E01 × 0020 ÷ 1BF2 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0E01 × 0308 ÷ 1BF2 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 0E01 ÷ 1B44 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0E01 × 0020 ÷ 1B44 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0E01 × 0308 ÷ 1B44 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 0E01 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 0020 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 0308 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 0E01 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 × 0020 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 × 0308 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 0E01 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 × 0020 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 × 0308 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 0E01 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 × 0020 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 × 0308 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0E01 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0020 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0308 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0E01 × 00AB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0E01 × 0020 ÷ 00AB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0E01 × 0308 × 00AB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 0E01 × 00BB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0E01 × 0020 × 00BB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0E01 × 0308 × 00BB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 00BB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0E01 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0E01 × 0020 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0E01 × 0308 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0E01 × 0308 × 0020 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0E01 × 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0E01 × 0020 ÷ 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0E01 × 0308 × 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 0E01 × 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 0020 ÷ 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 0308 × 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 0E01 × 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 0020 ÷ 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 0308 × 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 0E01 × 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 0308 × 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 0E01 × 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0308 × 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 0E01 × 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 0020 ÷ 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 0308 × 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0E01 × 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0020 ÷ 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0308 × 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0E01 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 ÷ 1B05 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 3041 × 0020 ÷ 1B05 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 3041 × 0308 ÷ 1B05 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1B05 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE LETTER AKARA (AK) ÷ [0.3]
+× 3041 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 × 0020 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 × 0308 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
+× 3041 ÷ 11003 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 3041 × 0020 ÷ 11003 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 3041 × 0308 ÷ 11003 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 11003 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BRAHMI SIGN JIHVAMULIYA (AP) ÷ [0.3]
+× 3041 ÷ 1BC0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 3041 × 0020 ÷ 1BC0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 3041 × 0308 ÷ 1BC0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK LETTER A (AS) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1BC0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK LETTER A (AS) ÷ [0.3]
+× 3041 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0020 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0308 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
+× 3041 × 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 × 0020 ÷ 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 × 0308 × 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
+× 3041 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 0020 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 0308 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
+× 3041 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 × 0020 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 × 0308 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 × 0308 × 0020 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
+× 3041 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 0020 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 0308 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× 3041 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0020 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0308 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 0308 × 0020 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 3041 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0020 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0308 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0308 × 0020 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+× 3041 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 0020 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 0308 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 3041 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 × 0020 ÷ 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 × 0308 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
+× 3041 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 × 0020 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 × 0308 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
+× 3041 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 × 0020 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 × 0308 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
+× 3041 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 0020 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 0308 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 3041 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 × 0020 ÷ 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 × 0308 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
+× 3041 ÷ 1B50 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 3041 × 0020 ÷ 1B50 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 3041 × 0308 ÷ 1B50 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1B50 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE DIGIT ZERO (ID) ÷ [0.3]
+× 3041 × 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 0020 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 0308 × 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 3041 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] COMMA (IS) ÷ [0.3]
+× 3041 × 0020 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 3041 × 0308 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
+× 3041 × 0308 × 0020 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
+× 3041 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 × 0020 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 × 0308 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
+× 3041 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 × 0020 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 × 0308 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 3041 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 0020 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 0308 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 3041 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0020 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0308 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0308 × 0020 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+× 3041 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 0020 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 0308 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
+× 3041 × 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 × 0020 ÷ 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 × 0308 × 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
+× 3041 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 × 0020 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 × 0308 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
+× 3041 ÷ 2329 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 3041 × 0020 ÷ 2329 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 3041 × 0308 ÷ 2329 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 2329 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING ANGLE BRACKET (OP) ÷ [0.3]
+× 3041 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 × 0020 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 × 0308 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
+× 3041 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0020 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0308 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
+× 3041 × 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0020 ÷ 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0308 × 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
+× 3041 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 0020 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 3041 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 0020 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 0308 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
+× 3041 × 0308 × 0020 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
+× 3041 ÷ 1BF2 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 3041 × 0020 ÷ 1BF2 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 3041 × 0308 ÷ 1BF2 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1BF2 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BATAK PANGOLAT (VF) ÷ [0.3]
+× 3041 ÷ 1B44 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 3041 × 0020 ÷ 1B44 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 3041 × 0308 ÷ 1B44 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1B44 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] BALINESE ADEG ADEG (VI) ÷ [0.3]
+× 3041 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 0020 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 0308 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 0308 × 0020 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 3041 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 × 0020 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 × 0308 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 × 0308 × 0020 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
+× 3041 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 × 0020 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 × 0308 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+× 3041 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 0020 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 0308 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0020 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0308 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 3041 × 00AB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 3041 × 0020 ÷ 00AB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 3041 × 0308 × 00AB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00AB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) ÷ [0.3]
+× 3041 × 00BB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 3041 × 0020 × 00BB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 3041 × 0308 × 00BB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 3041 × 0308 × 0020 × 00BB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 3041 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 3041 × 0020 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 3041 × 0308 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 3041 × 0308 × 0020 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 3041 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 3041 × 0020 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 3041 × 0308 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) ÷ [0.3]
+× 3041 × 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 0020 ÷ 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 0308 × 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
+× 3041 × 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 × 0020 ÷ 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 × 0308 × 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
+× 3041 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 × 0020 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 × 0308 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
+× 3041 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 × 0020 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 × 0308 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
+× 3041 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 0020 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 0308 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 3041 × 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0020 ÷ 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0308 × 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) × [5.01] <LINE FEED (LF)> (LF) ÷ [5.03] LATIN SMALL LETTER A (AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [0.3]
+× 0061 × 0308 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [0.3]
+× 0020 ÷ 200D × 0646 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] ARABIC LETTER NOON (AL) ÷ [0.3]
+× 0646 × 200D × 0020 ÷ # × [0.3] ARABIC LETTER NOON (AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 000B ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 000D ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 0085 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 200D × 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 3041 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
+× 2060 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 0308 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] NO-BREAK SPACE (GL) ÷ [0.3]
+× 200D × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] SOLIDUS (SY) ÷ [0.3]
+× 2014 × 2014 ÷ # × [0.3] EM DASH (B2) × [17.0] EM DASH (B2) ÷ [0.3]
+× 3041 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
+× FFFC ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
+× 3041 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
+× 0E01 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0021 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 2024 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 0030 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 261D × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
+× 0E01 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
+× 0024 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
+× 0024 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 0025 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
+× 1100 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 1160 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 11A8 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
+× 1160 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [22.0] ONE DOT LEADER (IN) ÷ [0.3]
+× 1160 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.01] PERCENT SIGN (PO) ÷ [0.3]
+× 0024 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
+× 261D × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [30.21] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
+× 0066 × 0069 × 006E × 0061 × 006C ÷ # × [0.3] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) ÷ [0.3]
+× 0063 × 0061 × 006E × 0027 × 0074 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER T (AL) ÷ [0.3]
+× 0063 × 0061 × 006E × 2019 × 0074 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN SMALL LETTER T (AL) ÷ [0.3]
+× 0027 × 0063 × 0061 × 006E × 0027 × 0020 ÷ 006E × 006F × 0074 ÷ # × [0.3] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] APOSTROPHE (QU) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER T (AL) ÷ [0.3]
+× 0063 × 0061 × 006E × 0020 ÷ 0027 × 006E × 006F × 0074 × 0027 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER T (AL) × [19.01] APOSTROPHE (QU) ÷ [0.3]
+× 0062 × 0075 × 0067 × 0028 × 0073 × 0029 × 0020 × 0020 × 0020 × 0020 × 0020 ÷ # × [0.3] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 0062 × 0075 × 0067 × 0028 × 0073 × 0029 × 00A0 × 0020 × 0020 × 0020 × 0020 × 0020 ÷ # × [0.3] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [12.1] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
+× 002E × 002E ÷ 307E ÷ 3059 × 3002 ÷ 0058 × 004D × 004C ÷ 306E × 002E × 002E ÷ # × [0.3] FULL STOP (IS) × [13.02] FULL STOP (IS) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [999.0] HIRAGANA LETTER SU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN CAPITAL LETTER X (AL) × [28.0] LATIN CAPITAL LETTER M (AL) × [28.0] LATIN CAPITAL LETTER L (AL) ÷ [999.0] HIRAGANA LETTER NO (ID) × [13.02] FULL STOP (IS) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0061 × 0062 × 00AD ÷ 0062 × 0079 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER Y (AL) ÷ [0.3]
+× 002D × 0033 ÷ # × [0.3] HYPHEN-MINUS (HY) × [25.02] DIGIT THREE (NU) ÷ [0.3]
+× 0065 × 002E × 0067 × 002E ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [13.02] FULL STOP (IS) × [29.0] LATIN SMALL LETTER G (AL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 4E00 × 002E ÷ 4E00 × 002E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4E00 (ID) × [13.02] FULL STOP (IS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0061 × 0020 × 0020 ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0061 × 0020 × 0020 × 200B ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0061 × 0020 ÷ 0308 × 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0031 × 0308 × 0062 × 0028 × 0061 × 0029 × 002D ÷ 0028 × 0062 × 0029 ÷ # × [0.3] DIGIT ONE (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] LATIN SMALL LETTER B (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER B (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0067 × 0069 × 0076 × 0065 × 0020 ÷ 0062 × 006F × 006F × 006B × 0028 × 0073 × 0029 × 002E ÷ # × [0.3] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER K (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 307E ÷ 0028 × 3059 × 0029 ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] HIRAGANA LETTER SU (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0066 × 0069 × 006E × 0064 × 0020 × 002E × 0063 × 006F × 006D ÷ # × [0.3] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [7.01] SPACE (SP) × [13.02] FULL STOP (IS) × [29.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) ÷ [0.3]
+× 0065 × 0071 × 0075 × 0061 × 006C × 0073 × 0020 × 002E ÷ 0033 × 0035 × 0020 ÷ 0063 × 0065 × 006E × 0074 × 0073 ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [25.03] DIGIT FIVE (NU) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0068 × 0065 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) ÷ [0.3]
+× 007B × 0073 × 007D ÷ 0068 × 0065 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) ÷ [0.3]
+× 02C8 × 0073 × 0049 × 006C × 0259 × 0062 × 0028 × 0259 × 0029 × 006C ÷ # × [0.3] MODIFIER LETTER VERTICAL LINE (BB) × [21.04] LATIN SMALL LETTER S (AL) × [28.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER SCHWA (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER SCHWA (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER L (AL) ÷ [0.3]
+× 02C8 × 0073 × 0049 × 006C × 0259 × 0062 × 007B × 0259 × 007D ÷ 006C ÷ # × [0.3] MODIFIER LETTER VERTICAL LINE (BB) × [21.04] LATIN SMALL LETTER S (AL) × [28.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER SCHWA (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER SCHWA (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0029 × 002E ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 002E × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] FULL STOP (IS) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0029 × 0021 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0021 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 005C ÷ 0028 × 0073 × 005C × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [24.03] REVERSE SOLIDUS (PR) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [24.03] REVERSE SOLIDUS (PR) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 0028 × 0020 × 0073 × 0020 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D × 002E ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D × 0021 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 005C ÷ 007B × 0073 × 005C × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [24.03] REVERSE SOLIDUS (PR) ÷ [999.0] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [24.03] REVERSE SOLIDUS (PR) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0065 × 007B × 0020 × 0073 × 0020 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [7.01] SPACE (SP) × [14.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0063 × 006F × 0064 × 0028 × 0065 × 0029 × 2026 ÷ 0028 × 0073 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [22.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0028 × 0063 × 006F × 0064 × 0028 × 0065 × 0029 × 2026 × 0029 × 0073 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [22.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 0063 × 006F × 0064 × 007B × 0065 × 007D × 2026 ÷ 007B × 0073 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [22.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 007B × 0063 × 006F × 0064 × 007B × 0065 × 007D × 2026 × 007D ÷ 0073 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [22.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 002D × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 00AD × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 2011 × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 0029 × 002D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 0029 × 00AD ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0028 × 0063 × 006F × 006E × 0029 × 2011 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 002D × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 00AD × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 2011 × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 007D × 002D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 007D × 00AD ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 007B × 0063 × 006F × 006E × 007D × 2011 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
+× 0063 × 0072 × 0065 × 0301 × 0028 × 0065 × 0301 × 0029 ÷ 0028 × 0065 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0063 × 0072 × 0065 × 0301 × 005B × 0065 × 0072 × 007C ÷ 0065 × 0301 × 0028 × 0065 × 0029 ÷ 0028 × 0073 × 0029 × 005D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT SQUARE BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [21.01] VERTICAL LINE (BA) ÷ [999.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT SQUARE BRACKET (CP_CP30) ÷ [0.3]
+× 0063 × 0072 × 0065 × 0301 × 007B × 0065 × 0072 × 007C ÷ 0065 × 0301 × 0028 × 0065 × 0029 ÷ 0028 × 0073 × 0029 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [21.01] VERTICAL LINE (BA) ÷ [999.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 0308 × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 00AB × 0308 × 00BB × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 00AB × 0020 × 0308 × 0020 × 00BB × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 0020 ÷ 0028 × 0020 × 0308 × 0020 × 0029 × 0020 ÷ 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 202F × 0028 × 0020 × 0308 × 0020 × 0029 × 202F × 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] LEFT PARENTHESIS (OP_OP30) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 0308 × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 00AB × 0308 × 00BB × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.11] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 00AB × 0020 × 0308 × 0020 × 00BB × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 0020 ÷ 007B × 0020 × 0308 × 0020 × 007D × 0020 ÷ 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) ÷ [18.0] LEFT CURLY BRACKET (OP_OP30) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 202F × 007B × 0020 × 0308 × 0020 × 007D × 202F × 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] LEFT CURLY BRACKET (OP_OP30) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD ÷ 2011 × 0029 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD × 0029 × 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 0029 × 00AD ÷ 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD ÷ 2011 × 007D ÷ 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD × 007D × 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 007D × 00AD ÷ 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 006F × 0070 × 0065 × 0072 × 0061 × 0074 × 006F × 0072 × 005B × 005D ÷ 0028 × 0030 × 0029 × 003B ÷ # × [0.3] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [30.01] LEFT SQUARE BRACKET (OP_OP30) × [13.02] RIGHT SQUARE BRACKET (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] DIGIT ZERO (NU) × [25.04] RIGHT PARENTHESIS (CP_CP30) × [13.02] SEMICOLON (IS) ÷ [0.3]
+× 006F × 0070 × 0065 × 0072 × 0061 × 0074 × 006F × 0072 × 005B × 005D ÷ 0028 × 0029 ÷ 007B × 007D ÷ # × [0.3] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [30.01] LEFT SQUARE BRACKET (OP_OP30) × [13.02] RIGHT SQUARE BRACKET (CP_CP30) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] LEFT CURLY BRACKET (OP_OP30) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 672C ÷ 0028 × 3092 × 0029 ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 0028 × 300C × 3092 × 300D × 0029 ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 300C × 0028 × 3092 × 0029 × 300D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LEFT PARENTHESIS (OP_OP30) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 007B × 3092 × 007D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CURLY BRACKET (OP_OP30) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 007B × 300C × 3092 × 300D × 007D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CURLY BRACKET (OP_OP30) × [14.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 672C ÷ 005B × 0028 × 3092 × 0029 × 005D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT SQUARE BRACKET (OP_OP30) × [14.0] LEFT PARENTHESIS (OP_OP30) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT SQUARE BRACKET (CP_CP30) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 0028 × 30CB × 30E5 × 30FC × 30FB × 0029 ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 0028 × 30CB × 30E5 × 30FC × 0029 × 30FB ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [16.0] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 007B × 30CB × 30E5 × 30FC × 30FB × 007D ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 007B × 30CB × 30E5 × 30FC × 007D × 30FB ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [13.02] RIGHT CURLY BRACKET (CL) × [16.0] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 0028 × 1850 × 1846 × 1851 × 1846 ÷ 1806 × 0029 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 0028 × 1850 × 1846 × 1851 × 1846 × 0029 ÷ 1806 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [21.04] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 007B × 1850 × 1846 × 1851 × 1846 ÷ 1806 × 007D ÷ 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 007B × 1850 × 1846 × 1851 × 1846 × 007D ÷ 1806 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [21.04] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
+× 0028 × 0068 × 0074 × 0074 × 0070 × 003A × 002F × 002F × 0029 × 0078 × 006E × 002D × 002D ÷ 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER P (AL) × [13.02] COLON (IS) × [13.02] SOLIDUS (SY) × [13.02] SOLIDUS (SY) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [30.02] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 007B × 0068 × 0074 × 0074 × 0070 × 003A × 002F × 002F × 007D ÷ 0078 × 006E × 002D × 002D ÷ 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER P (AL) × [13.02] COLON (IS) × [13.02] SOLIDUS (SY) × [13.02] SOLIDUS (SY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 0028 × 0030 × 002C × 0031 × 0029 × 002B × 0028 × 0032 × 002C × 0033 × 0029 × 2295 × 0028 × 2212 × 0034 × 002C × 0035 × 0029 × 2296 × 0028 × 0036 × 002C × 0037 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] DIGIT ZERO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT ONE (NU) × [25.04] RIGHT PARENTHESIS (CP_CP30) × [25.05] PLUS SIGN (PR) × [25.01] LEFT PARENTHESIS (OP_OP30) × [14.0] DIGIT TWO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT THREE (NU) × [25.04] RIGHT PARENTHESIS (CP_CP30) × [30.02] CIRCLED PLUS (AI_AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] MINUS SIGN (PR) × [25.01] DIGIT FOUR (NU) × [25.03] COMMA (IS) × [25.04] DIGIT FIVE (NU) × [25.04] RIGHT PARENTHESIS (CP_CP30) × [30.02] CIRCLED MINUS (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] DIGIT SIX (NU) × [25.03] COMMA (IS) × [25.04] DIGIT SEVEN (NU) × [25.04] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 007B × 0030 × 002C × 0031 × 007D × 002B × 007B × 0032 × 002C × 0033 × 007D ÷ 2295 × 007B × 2212 × 0034 × 002C × 0035 × 007D ÷ 2296 × 007B × 0036 × 002C × 0037 × 007D ÷ # × [0.3] LEFT CURLY BRACKET (OP_OP30) × [14.0] DIGIT ZERO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT ONE (NU) × [25.04] RIGHT CURLY BRACKET (CL) × [25.05] PLUS SIGN (PR) × [25.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] DIGIT TWO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT THREE (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [999.0] CIRCLED PLUS (AI_AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] MINUS SIGN (PR) × [25.01] DIGIT FOUR (NU) × [25.03] COMMA (IS) × [25.04] DIGIT FIVE (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [999.0] CIRCLED MINUS (AL) × [30.01] LEFT CURLY BRACKET (OP_OP30) × [14.0] DIGIT SIX (NU) × [25.03] COMMA (IS) × [25.04] DIGIT SEVEN (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
+× 0061 × 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 0061 × 0062 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0061 × 0062 × 0020 ÷ 0063 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) ÷ [0.3]
+× 0061 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0939 × 093F × 0928 × 094D × 0926 × 0940 × 0020 ÷ # × [0.3] DEVANAGARI LETTER HA (AL) × [9.0] DEVANAGARI VOWEL SIGN I (CM1_CM) × [28.0] DEVANAGARI LETTER NA (AL) × [9.0] DEVANAGARI SIGN VIRAMA (CM1_CM) × [28.0] DEVANAGARI LETTER DA (AL) × [9.0] DEVANAGARI VOWEL SIGN II (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 092F × 0938 × 0917 × 0941 × 091A × 093F × 0924 × 0940 × 092F × 0938 × 093E × 0020 ÷ # × [0.3] DEVANAGARI LETTER YA (AL) × [28.0] DEVANAGARI LETTER SA (AL) × [28.0] DEVANAGARI LETTER GA (AL) × [9.0] DEVANAGARI VOWEL SIGN U (CM1_CM) × [28.0] DEVANAGARI LETTER CA (AL) × [9.0] DEVANAGARI VOWEL SIGN I (CM1_CM) × [28.0] DEVANAGARI LETTER TA (AL) × [9.0] DEVANAGARI VOWEL SIGN II (CM1_CM) × [28.0] DEVANAGARI LETTER YA (AL) × [28.0] DEVANAGARI LETTER SA (AL) × [9.0] DEVANAGARI VOWEL SIGN AA (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
+× 5370 ÷ 672C ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5370 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
+× 5165 ÷ 529B ÷ 3057 ÷ 30A8 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5165 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-529B (ID) ÷ [999.0] HIRAGANA LETTER SI (ID) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 4F4D × 3002 ÷ 8A18 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F4D (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8A18 (ID) ÷ [0.3]
+× 672C × 3002 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 967A × 300D ÷ 306E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-967A (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
+× 3057 × 3087 ÷ 3046 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) ÷ [0.3]
+× 307E ÷ 0061 ÷ 672C ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× C5C6 ÷ C5B4 ÷ C694 × 0020 ÷ 006F × 0072 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE EOBS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× 307E ÷ 0061 × 0062 × 0020 ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 3067 ÷ 4F7F ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [0.3]
+× 3059 ÷ 308B ÷ # × [0.3] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
+× 306E ÷ 30D1 ÷ 30F3 ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
+× 3046 × 3000 ÷ 3048 × 3000 ÷ 304A × 300D ÷ # × [0.3] HIRAGANA LETTER U (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER E (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER O (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [0.3]
+× 308B × 0020 ÷ C740 ÷ C601 × 0020 ÷ 306B ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE EUN (H3) ÷ [999.0] HANGUL SYLLABLE YEONG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
+× 3057 × 3087 ÷ 3046 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 30E0 ÷ 306E ÷ 4E00 ÷ # × [0.3] KATAKANA LETTER MU (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) ÷ [0.3]
+× 30D5 ÷ 30EA ÷ # × [0.3] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) ÷ [0.3]
+× 30D5 ÷ 30EA × 30FC ÷ 767E ÷ # × [0.3] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-767E (ID) ÷ [0.3]
+× 30D4 × 30E5 × 30FC ÷ 30BF ÷ 3067 ÷ 4F7F ÷ 7528 ÷ 3059 ÷ 308B ÷ # × [0.3] KATAKANA LETTER PI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER TA (ID) ÷ [999.0] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-7528 (ID) ÷ [999.0] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
+× 30BF × 30FC ÷ 30AD × 30FC ÷ 3092 ÷ 62BC ÷ # × [0.3] KATAKANA LETTER TA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-62BC (ID) ÷ [0.3]
+× 30B7 × 30E7 ÷ 30F3 ÷ # × [0.3] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 0020 ÷ 0915 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] DEVANAGARI LETTER KA (AL) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 0020 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 0033 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] DIGIT THREE (NU) ÷ [0.3]
+× 0061 × 0062 × 002E × 0020 ÷ 0032 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT TWO (NU) ÷ [0.3]
+× 0041 × 002E ÷ 0031 × 0020 ÷ BABB ÷ # × [0.3] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT ONE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× BD24 ÷ C5B4 × 002E × 0020 ÷ 0041 × 002E ÷ 0032 × 0020 ÷ BCFC ÷ # × [0.3] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE BOL (H3) ÷ [0.3]
+× BD10 ÷ C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0033 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE BWA (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0034 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT FOUR (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 300C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] LEFT CORNER BRACKET (OP) ÷ [0.3]
+× 306B ÷ 300C × 30D0 ÷ 0028 × 0062 × 0061 × 0029 × 300D ÷ 3084 ÷ 300C × 30B9 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER BA (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER YA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER SU (ID) ÷ [0.3]
+× 308B ÷ 300C × 0055 × 004B ÷ 30DD ÷ 30F3 ÷ 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] HIRAGANA LETTER RU (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LATIN CAPITAL LETTER U (AL) × [28.0] LATIN CAPITAL LETTER K (AL) ÷ [999.0] KATAKANA LETTER PO (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [999.0] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 306F × 3001 ÷ 300C × 003D × 0072 × 0061 × 006E × 0064 × 0028 × 0029 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] EQUALS SIGN (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 3067 × 3001 ÷ 300C × 0021 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER DE (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 8A33 ÷ 300C × 3059 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A33 (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SU (ID) ÷ [0.3]
+× 3066 ÷ 300C × BD24 ÷ C5B4 × 003F × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TE (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 306E ÷ 300C × 305D ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SO (ID) ÷ [0.3]
+× 306F ÷ 300C × 30A8 ÷ # × [0.3] HIRAGANA LETTER HA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 4F8B × FF1A ÷ 300C × 3042 × 3000 ÷ 3044 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER A (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER I (ID) ÷ [0.3]
+× 304F × 3001 ÷ 300C × D3C9 ÷ C591 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER KU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE PYEONG (H3) ÷ [999.0] HANGUL SYLLABLE YANG (H3) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
+× 306B ÷ 300C × C81C ÷ BAA9 ÷ 0028 × 984C ÷ 540D × 0029 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE JE (H2) ÷ [999.0] HANGUL SYLLABLE MOG (H3) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] CJK UNIFIED IDEOGRAPH-984C (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
+× 5178 ÷ 300E × 30A6 × 30A3 ÷ 30AD ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5178 (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] KATAKANA LETTER U (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) ÷ [0.3]
+× 3067 ÷ 300E × 82F1 ÷ 8A9E ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] CJK UNIFIED IDEOGRAPH-82F1 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8A9E (ID) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0020 ÷ 672C ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0020 ÷ 307E ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0028 × 0073 × 0029 × 0020 ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 308B × 3002 ÷ 0064 × 006F × 0067 ÷ FF08 × 72AC × FF09 ÷ 3092 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-72AC (ID) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 672C ÷ FF08 × 307E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 672C × 0020 ÷ 0028 × 0061 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 70B9 × 0020 ÷ 005B × 7DE8 ÷ 96C6 × 005D ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-70B9 (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT SQUARE BRACKET (OP_OP30) × [14.0] CJK UNIFIED IDEOGRAPH-7DE8 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-96C6 (ID) × [13.02] RIGHT SQUARE BRACKET (CP_CP30) ÷ [0.3]
+× 0061 × 0028 × 0073 × 0029 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [30.01] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [0.3]
+× FF08 × 30B6 × 30FB ÷ 30AF ÷ 30A4 × 30C3 ÷ 30AF × 30FB ÷ 30D6 ÷ # × [0.3] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER ZA (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] KATAKANA LETTER I (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER BU (ID) ÷ [0.3]
+× 0070 ÷ FF08 × 30AF ÷ 30A4 × 30C3 ÷ 30AF × 30FB ÷ 30D6 ÷ # × [0.3] LATIN SMALL LETTER P (AL) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER KU (ID) ÷ [999.0] KATAKANA LETTER I (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER BU (ID) ÷ [0.3]
+× 0061 × 0062 ÷ FF08 × 30AF ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 0028 × 5370 ÷ 672C × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP_OP30) × [14.0] CJK UNIFIED IDEOGRAPH-5370 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [0.3]
+× 30B9 ÷ FF08 × 3044 ÷ # × [0.3] KATAKANA LETTER SU (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER I (ID) ÷ [0.3]
+× 30C9 ÷ FF08 × 30DD ÷ # × [0.3] KATAKANA LETTER DO (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER PO (ID) ÷ [0.3]
+× 30C9 × 0020 ÷ 0028 × 8CEA ÷ # × [0.3] KATAKANA LETTER DO (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) × [14.0] CJK UNIFIED IDEOGRAPH-8CEA (ID) ÷ [0.3]
+× 0073 × 0029 × 300D ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0061 × FF09 × 300F ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] RIGHT WHITE CORNER BRACKET (CL) ÷ [0.3]
+× 308B × 300D × FF09 ÷ 306F ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) ÷ [999.0] HIRAGANA LETTER HA (ID) ÷ [0.3]
+× 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
+× 0072 × 006B × 0029 × 300D ÷ 3082 ÷ # × [0.3] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER K (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MO (ID) ÷ [0.3]
+× 30AF ÷ 0028 × 0061 × 0062 × 0020 ÷ 0063 × 0064 × 0029 × 300D ÷ 3082 ÷ # × [0.3] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER D (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MO (ID) ÷ [0.3]
+× 30F3 × 30FB ÷ 30DE × 30FC ÷ 30AF ÷ 0028 × 0065 × 0078 ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER X (AL) ÷ [0.3]
+× 30DE × 30FC ÷ 0028 × 006D × 0061 × 0029 × 300D ÷ 306A ÷ # × [0.3] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER NA (ID) ÷ [0.3]
+× 30AC ÷ 30EF × 300D × 3002 ÷ 3053 ÷ # × [0.3] KATAKANA LETTER GA (ID) ÷ [999.0] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
+× 30AF × 300D ÷ 307E ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 30EF × 300D × 3002 ÷ 3053 ÷ # × [0.3] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
+× 30AF × 300D ÷ 307E × 3001 ÷ 672C ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 30AF × 300D × 3001 ÷ 30AF ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 30C7 × 30A3 ÷ 30A2 ÷ FF08 × 0061 × 0062 × FF09 × 300F ÷ # × [0.3] KATAKANA LETTER DE (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER A (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] RIGHT WHITE CORNER BRACKET (CL) ÷ [0.3]
+× CABD ÷ C774 ÷ C5D0 ÷ C694 × 003F × 300D ÷ 3068 ÷ 805E ÷ # × [0.3] HANGUL SYLLABLE JJOG (H3) ÷ [999.0] HANGUL SYLLABLE I (H2) ÷ [999.0] HANGUL SYLLABLE E (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-805E (ID) ÷ [0.3]
+× 540D × 0029 ÷ C740 × 0020 ÷ C54C ÷ C544 ÷ C694 × 003F × 300D ÷ 3068 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HANGUL SYLLABLE EUN (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE AL (H3) ÷ [999.0] HANGUL SYLLABLE A (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 8CA8 × 0029 × 0020 ÷ 002D × 0020 ÷ 0028 × 0070 × 006F ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8CA8 (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [0.3]
+× 91CF × 0029 × 0020 × 301C × 0020 ÷ 0028 × 0070 × 006F ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-91CF (ID) × [13.02] RIGHT PARENTHESIS (CP_CP30) × [7.01] SPACE (SP) × [16.0] WAVE DASH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [0.3]
+× 30C9 ÷ 91CD × FF09 × 0020 × 301C × 0020 ÷ 529B × 30FB ÷ 91CD ÷ # × [0.3] KATAKANA LETTER DO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-91CD (ID) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [7.01] SPACE (SP) × [16.0] WAVE DASH (NS) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-529B (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-91CD (ID) ÷ [0.3]
+× 0061 × 0062 × 0022 × FF08 × 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [19.01] QUOTATION MARK (QU) × [19.02] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 306F × 0020 ÷ 0022 × 0073 × 0022 × 0020 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) × [19.02] LATIN SMALL LETTER S (AL) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [0.3]
+× 306F × 3001 × 0022 × 0054 × 0068 × 0065 × 0020 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [19.01] QUOTATION MARK (QU) × [19.02] LATIN CAPITAL LETTER T (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 0064 × 006F × 0067 × 0022 × 0020 ÷ 3092 ÷ # × [0.3] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER G (AL) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 0039 × 0030 × 0022 × 0020 ÷ 3068 ÷ # × [0.3] DIGIT NINE (NU) × [25.03] DIGIT ZERO (NU) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 30B9 × 30FB ÷ 30AA × 30FC ÷ 30D0 × 30FC × 30FB ÷ 30B6 × 30FB ÷ 30EC ÷ # × [0.3] KATAKANA LETTER SU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER O (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER BA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER ZA (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER RE (ID) ÷ [0.3]
+× 30B9 × 30FB ÷ 30B8 × 30E3 ÷ 30F3 ÷ # × [0.3] KATAKANA LETTER SU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER ZI (ID) × [21.03] KATAKANA LETTER SMALL YA (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
+× 30F3 × 30FB ÷ 30D5 × 30A9 × 30C3 ÷ 30AF ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER HU (ID) × [21.03] KATAKANA LETTER SMALL O (CJ_NS) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 30A4 ÷ 30B8 × 30FC × 30FB ÷ 30C9 × 30C3 ÷ 30B0 × 3001 ÷ 548C ÷ # × [0.3] KATAKANA LETTER I (ID) ÷ [999.0] KATAKANA LETTER ZI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER DO (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER GU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-548C (ID) ÷ [0.3]
+× 30E1 × 30FC ÷ 30B7 × 30E7 ÷ 30F3 × 30FB ÷ 30DE × 30FC ÷ 30AF ÷ # × [0.3] KATAKANA LETTER ME (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 30F3 × 30FB ÷ 30AF ÷ 0028 × 0061 ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [14.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
+× 30B7 × 30E7 ÷ 30F3 × 30FB ÷ 30DE ÷ # × [0.3] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) ÷ [0.3]
+× 672C × 003A × 0020 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [0.3]
+× 672C × 003A × 0020 ÷ 30AF ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER KU (ID) ÷ [0.3]
+× 51FA ÷ 5178 × 003A × 0020 ÷ 30D5 ÷ 30EA × 30FC ÷ 767E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-51FA (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5178 (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-767E (ID) ÷ [0.3]
+× 5F8C × 2026 ÷ 306B ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5F8C (ID) × [22.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
+× 3057 × 3087 ÷ 3046 × 3002 × 3002 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 304D × 3001 × 0021 × 0021 × 3001 × 0021 × 0021 × 0021 ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER KI (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 306F × 3001 × 003F ÷ 3068 × 0021 ÷ 3092 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] QUESTION MARK (EX) ÷ [999.0] HIRAGANA LETTER TO (ID) × [13.01] EXCLAMATION MARK (EX) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 305F × 3001 × 2049 ÷ 0028 × 0021 × 003F × 0029 ÷ 306E ÷ # × [0.3] HIRAGANA LETTER TA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [16.0] EXCLAMATION QUESTION MARK (NS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [13.01] EXCLAMATION MARK (EX) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
+× 3084 × 3001 × 2048 ÷ 0028 × 003F × 0021 × 0029 ÷ 306E ÷ # × [0.3] HIRAGANA LETTER YA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [16.0] QUESTION EXCLAMATION MARK (NS) ÷ [999.0] LEFT PARENTHESIS (OP_OP30) × [13.01] QUESTION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP_CP30) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
+× 305F × 0020 ÷ 203D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TA (ID) × [7.01] SPACE (SP) ÷ [18.0] INTERROBANG (NS) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 305B × FF01 ÷ 0031 × 0030 × 0030 × 0025 ÷ 306E ÷ 5B8C ÷ # × [0.3] HIRAGANA LETTER SE (ID) × [13.01] FULLWIDTH EXCLAMATION MARK (EX) ÷ [999.0] DIGIT ONE (NU) × [25.03] DIGIT ZERO (NU) × [25.03] DIGIT ZERO (NU) × [25.05] PERCENT SIGN (PO) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B8C (ID) ÷ [0.3]
+× 0032 × 0033 ÷ 672C ÷ # × [0.3] DIGIT TWO (NU) × [25.03] DIGIT THREE (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 30A1 ÷ 30D9 × 30C3 ÷ 30C8 ÷ 0032 × 0036 ÷ 5B57 ÷ 3092 ÷ # × [0.3] KATAKANA LETTER SMALL A (CJ_NS) ÷ [999.0] KATAKANA LETTER BE (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER TO (ID) ÷ [999.0] DIGIT TWO (NU) × [25.03] DIGIT SIX (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B57 (ID) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 4F8B × FF1A ÷ 00A3 × 0032 × 0033 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] POUND SIGN (PR) × [25.01] DIGIT TWO (NU) × [25.03] DIGIT THREE (NU) ÷ [0.3]
+× 8A18 ÷ 53F7 × 0020 ÷ 00A3 × 3002 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A18 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-53F7 (ID) × [7.01] SPACE (SP) ÷ [18.0] POUND SIGN (PR) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 308C ÷ 308B × 3002 ÷ 0071 × 0075 ÷ # × [0.3] HIRAGANA LETTER RE (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) ÷ [0.3]
+× 307E × 3002 ÷ # × [0.3] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
+× 307E × 3002 ÷ 0061 × 0062 × 0020 ÷ # × [0.3] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
+× 308B × 3002 ÷ 6570 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-6570 (ID) ÷ [0.3]
+× 308B × 3002 ÷ 3053 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
+× 3044 × 3002 ÷ 30D1 ÷ # × [0.3] HIRAGANA LETTER I (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [0.3]
+× 30AC ÷ 30EF × 300D × 3002 ÷ 3053 ÷ 308C ÷ # × [0.3] KATAKANA LETTER GA (ID) ÷ [999.0] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [999.0] HIRAGANA LETTER RE (ID) ÷ [0.3]
+× 8A9E ÷ 306E ÷ 0069 × 006F ÷ 306E × 3001 ÷ 0032 ÷ 5B57 ÷ 3092 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A9E (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [999.0] HIRAGANA LETTER NO (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B57 (ID) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
+× 3001 ÷ 548C ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-548C (ID) ÷ [0.3]
+× 3001 ÷ 30BF ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER TA (ID) ÷ [0.3]
+× 3001 ÷ 304B ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] HIRAGANA LETTER KA (ID) ÷ [0.3]
+× 3001 ÷ 3053 ÷ 308C ÷ 3067 ÷ 306F × 0020 ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [999.0] HIRAGANA LETTER RE (ID) ÷ [999.0] HIRAGANA LETTER DE (ID) ÷ [999.0] HIRAGANA LETTER HA (ID) × [7.01] SPACE (SP) ÷ [0.3]
+× 3057 × 3001 ÷ 0061 × 0062 ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
+× 0061 ÷ 1F1E6 ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
+× 1F1F7 × 1F1FA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [0.3]
+× 1F1F7 × 1F1FA ÷ 1F1F8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [30.13] REGIONAL INDICATOR SYMBOL LETTER S (RI) ÷ [0.3]
+× 1F1F7 × 1F1FA ÷ 1F1F8 × 1F1EA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [30.13] REGIONAL INDICATOR SYMBOL LETTER S (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER E (RI) ÷ [0.3]
+× 1F1F7 × 1F1FA × 200B ÷ 1F1F8 × 1F1EA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER S (RI) × [30.12] REGIONAL INDICATOR SYMBOL LETTER E (RI) ÷ [0.3]
+× 05D0 × 002D × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.02] HYPHEN-MINUS (HY) × [21.1] HEBREW LETTER ALEF (HL) ÷ [0.3]
+× 11F26 ÷ 11F02 × 11F2D ÷ 11F26 × 11F42 × 11F26 ÷ 11F31 × 11F41 ÷ # × [0.3] KAWI LETTER PA (AK) ÷ [999.0] KAWI SIGN REPHA (AP) × [28.11] KAWI LETTER LA (AK) ÷ [999.0] KAWI LETTER PA (AK) × [28.12] KAWI CONJOINER (VI) × [28.13] KAWI LETTER PA (AK) ÷ [999.0] KAWI LETTER SA (AK) × [9.0] KAWI SIGN KILLER (CM1_CM) ÷ [0.3]
+× 1BD7 × 1BEC ÷ 1BD2 × 1BEA × 1BC9 × 1BF3 ÷ 1BC2 × 1BE7 × 1BC9 × 1BF3 ÷ # × [0.3] BATAK LETTER NORTHERN TA (AS) × [9.0] BATAK VOWEL SIGN O (CM1_CM) ÷ [999.0] BATAK LETTER RA (AS) × [9.0] BATAK VOWEL SIGN I (CM1_CM) × [28.14] BATAK LETTER NA (AS) × [28.12] BATAK PANONGONAN (VF) ÷ [999.0] BATAK LETTER HA (AS) × [9.0] BATAK VOWEL SIGN E (CM1_CM) × [28.14] BATAK LETTER NA (AS) × [28.12] BATAK PANONGONAN (VF) ÷ [0.3]
+× 1B18 ÷ 1B27 × 1B44 × 200C × 1B2B × 1B38 ÷ 1B31 × 1B44 × 1B1D × 1B36 ÷ # × [0.3] BALINESE LETTER CA (AK) ÷ [999.0] BALINESE LETTER PA (AK) × [28.12] BALINESE ADEG ADEG (VI) × [9.0] ZERO WIDTH NON-JOINER (CM1_CM) × [28.13] BALINESE LETTER MA (AK) × [9.0] BALINESE VOWEL SIGN SUKU (CM1_CM) ÷ [999.0] BALINESE LETTER SA SAPA (AK) × [28.12] BALINESE ADEG ADEG (VI) × [28.13] BALINESE LETTER TA LATIK (AK) × [9.0] BALINESE VOWEL SIGN ULU (CM1_CM) ÷ [0.3]
+× 0065 × 25CC × 0302 × 25CC × 0323 ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [28.0] DOTTED CIRCLE (AL) × [9.0] COMBINING CIRCUMFLEX ACCENT (CM1_CM) × [28.0] DOTTED CIRCLE (AL) × [9.0] COMBINING DOT BELOW (CM1_CM) ÷ [0.3]
+× 25CC × 1B44 × 1B2C ÷ # × [0.3] DOTTED CIRCLE (AL) × [28.12] BALINESE ADEG ADEG (VI) × [28.13] BALINESE LETTER YA (AK) ÷ [0.3]
+× 25CC × 1B44 × 25CC × 1B44 × 1B2C ÷ # × [0.3] DOTTED CIRCLE (AL) × [28.12] BALINESE ADEG ADEG (VI) × [28.13] DOTTED CIRCLE (AL) × [28.12] BALINESE ADEG ADEG (VI) × [28.13] BALINESE LETTER YA (AK) ÷ [0.3]
+× 25CC × A9B3 × A9C0 × A9A0 ÷ # × [0.3] DOTTED CIRCLE (AL) × [9.0] JAVANESE SIGN CECAK TELU (CM1_CM) × [28.12] JAVANESE PANGKON (VI) × [28.13] JAVANESE LETTER TA (AK) ÷ [0.3]
+× 201D × 004A × 006F × 002C × 0020 ÷ 006E × 00E5 × 0072 × 2019 × 006E × 0020 ÷ 0064 × 0061 × 0020 ÷ 0068 × 0061 × 0020 ÷ 0067 × 00E5 × 0074 × 0074 × 0020 ÷ 0065 × 0074 × 0074 × 0020 ÷ 0073 × 0074 × 00F6 × 0063 × 006B × 0020 ÷ 0074 × 0065 × 002C × 0020 ÷ 0073 × 00E5 × 0020 ÷ 006B × 006F × 006D × 006D × 0065 × 0072 × 2019 × 006E × 0020 ÷ 0074 × 0065 × 0020 ÷ 0065 × 0020 ÷ 00E5 × 002C × 0020 ÷ 00E5 × 0020 ÷ 0069 × 0020 ÷ 00E5 × 0061 × 0020 ÷ 00E4 × 0020 ÷ 0065 × 0020 ÷ 00F6 × 002E × 201D × 000A ÷ 201D × 0056 × 0061 × 0073 × 0061 × 201D × 002C × 0020 ÷ 0073 × 0061 × 2019 × 006E × 002E × 000A ÷ 201D × 00C5 × 0020 ÷ 0069 × 0020 ÷ 00E5 × 0061 × 0020 ÷ 00E4 × 0020 ÷ 0065 × 0020 ÷ 00F6 × 201D × 002C × 0020 ÷ 0073 × 0061 × 0020 ÷ 006A × 0061 × 002E ÷ # × [0.3] RIGHT DOUBLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN CAPITAL LETTER J (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER R (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER K (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER E (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [13.02] FULL STOP (IS) × [15.21] RIGHT DOUBLE QUOTATION MARK (QU_QU_Pf) × [6.0] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT DOUBLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN CAPITAL LETTER V (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER A (AL) × [15.21] RIGHT DOUBLE QUOTATION MARK (QU_QU_Pf) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER A (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN SMALL LETTER N (AL) × [13.02] FULL STOP (IS) × [6.0] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT DOUBLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN CAPITAL LETTER A WITH RING ABOVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [15.21] RIGHT DOUBLE QUOTATION MARK (QU_QU_Pf) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER J (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0045 × 006E × 0020 ÷ 0067 × 00E5 × 006E × 0067 × 0020 ÷ 0075 × 006E × 0064 × 0066 × 00F6 × 006C × 006C × 0020 ÷ 0064 × 0065 × 0074 × 0020 ÷ 0068 × 006F × 006E × 006F × 006D × 0020 ÷ 0064 × 006F × 0063 × 006B × 002C × 0020 ÷ 006D × 0065 × 0064 × 0061 × 006E × 0020 ÷ 0068 × 0061 × 006E × 0020 ÷ 0073 × 006C × 00E4 × 0070 × 0061 × 0064 × 0065 × 0020 ÷ 0070 × 00E5 × 0020 ÷ 0064 × 0065 × 0074 × 0020 ÷ 0076 × 00E5 × 0074 × 0061 × 0020 ÷ 0068 × 00F6 × 0065 × 0074 × 003A × 0020 ÷ 00BB × 0056 × 0061 × 0072 × 0066 × 00F6 × 0072 × 0020 ÷ 00E4 × 0072 × 0020 ÷ 0068 × 00F6 × 0065 × 0074 × 0020 ÷ 0072 × 0065 × 0064 × 0061 × 006E × 0020 ÷ 0074 × 006F × 0072 × 0072 × 0074 × 0020 ÷ 006F × 0063 × 0068 × 0020 ÷ 0069 × 006E × 006B × 00F6 × 0072 × 0074 × 0020 ÷ 0064 × 00E4 × 0072 × 0020 ÷ 0062 × 006F × 0072 × 0074 × 0061 × 0020 ÷ 0070 × 00E5 × 0020 ÷ 0053 × 006F × 006C × 0062 × 0061 × 0063 × 006B × 0065 × 006E × 002C × 0020 ÷ 006F × 0063 × 0068 × 0020 ÷ 0068 × 00E4 × 0072 × 0020 ÷ 0068 × 006F × 0073 × 0020 ÷ 006F × 0073 × 0073 × 0020 ÷ 00E4 × 0072 × 0020 ÷ 0064 × 0065 × 0074 × 0020 ÷ 0076 × 00E5 × 0074 × 0074 × 003F × 00BB × 0020 ÷ 2014 × 0020 ÷ 00BB × 0044 × 00E4 × 0072 × 0066 × 00F6 × 0072 × 0020 ÷ 0061 × 0074 × 0074 × 0020 ÷ 0064 × 0065 × 0020 ÷ 0068 × 0061 × 0020 ÷ 006F × 0066 × 0074 × 0061 × 0072 × 0065 × 0020 ÷ 0073 × 006F × 006C × 0020 ÷ 00E4 × 006E × 0020 ÷ 0076 × 0069 × 002E × 00BB ÷ # × [0.3] LATIN CAPITAL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER L (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER K (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN CAPITAL LETTER V (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER H (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER S (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER H (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER A WITH RING ABOVE (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [13.01] QUESTION MARK (EX) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN CAPITAL LETTER D (AL) × [28.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER O WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER L (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH DIAERESIS (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER I (AL) × [13.02] FULL STOP (IS) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 0076 × 006F × 0075 × 0073 × 0020 ÷ 006D × 0065 × 0020 ÷ 0068 × 0065 × 0075 × 0072 × 0074 × 0065 × 007A × 002C × 0020 ÷ 0076 × 006F × 0075 × 0073 × 0020 ÷ 0064 × 0069 × 0074 × 0065 × 0073 × 0020 × 003A × 0020 ÷ 00AB × 0020 × 0045 × 0078 × 0063 × 0075 × 0073 × 0065 × 007A × 002D ÷ 006D × 006F × 0069 × 002C × 0020 × 00BB × 0020 ÷ 0065 × 0074 × 0020 ÷ 0076 × 006F × 0075 × 0073 × 0020 ÷ 0063 × 0072 × 006F × 0079 × 0065 × 007A × 0020 ÷ 0071 × 0075 × 0065 × 0020 ÷ 0063 × 0065 × 006C × 0061 × 0020 ÷ 0073 × 0075 × 0066 × 0066 × 0069 × 0074 × 0020 × 003F ÷ # × [0.3] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER E (AL) × [28.0] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER I (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER Y (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) × [13.01] QUESTION MARK (EX) ÷ [0.3]
+× 006A × 2019 × 0061 × 0069 × 0020 ÷ 0064 × 0069 × 0074 × 0020 × 003A × 0020 ÷ 00AB × 0020 × 0045 × 0078 × 0063 × 0075 × 0073 × 0065 × 007A × 002D ÷ 006D × 006F × 0069 × 002E × 0020 × 00BB × 0020 ÷ 0049 × 006C × 0020 ÷ 006D × 0065 × 0020 ÷ 0073 × 0065 × 006D × 0062 × 006C × 0065 × 0020 ÷ 0064 × 006F × 006E × 0063 × 0020 ÷ 0071 × 0075 × 0065 × 0020 ÷ 0063 × 2019 × 0065 × 0073 × 0074 × 0020 ÷ 0061 × 0073 × 0073 × 0065 × 007A × 002E ÷ # × [0.3] LATIN SMALL LETTER J (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER E (AL) × [28.0] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER I (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER C (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0045 × 0074 × 0020 ÷ 0076 × 0069 × 0073 × 0065 × 0020 ÷ 0061 × 0075 × 0020 ÷ 0066 × 0072 × 006F × 006E × 0074 × 0020 ÷ 006D × 006F × 006E × 0020 ÷ 0070 × 00E8 × 0072 × 0065 × 0020 ÷ 0065 × 006E × 0020 ÷ 0063 × 0072 × 0069 × 0061 × 006E × 0074 × 0020 × 003A × 0020 ÷ 00AB × 0020 × 0043 × 0061 × 0072 × 0061 × 006D × 0062 × 0061 × 0020 × 0021 × 0020 × 00BB × 2028 ÷ 004C × 0065 × 0020 ÷ 0063 × 006F × 0075 × 0070 × 0020 ÷ 0070 × 0061 × 0073 × 0073 × 0061 × 0020 ÷ 0073 × 0069 × 0020 ÷ 0070 × 0072 × 00E8 × 0073 × 002C × 0020 ÷ 0071 × 0075 × 0065 × 0020 ÷ 006C × 0065 × 0020 ÷ 0063 × 0068 × 0061 × 0070 × 0065 × 0061 × 0075 × 0020 ÷ 0074 × 006F × 006D × 0062 × 0061 × 2028 ÷ 0045 × 0074 × 0020 ÷ 0071 × 0075 × 0065 × 0020 ÷ 006C × 0065 × 0020 ÷ 0063 × 0068 × 0065 × 0076 × 0061 × 006C × 0020 ÷ 0066 × 0069 × 0074 × 0020 ÷ 0075 × 006E × 0020 ÷ 00E9 × 0063 × 0061 × 0072 × 0074 × 0020 ÷ 0065 × 006E × 0020 ÷ 0061 × 0072 × 0072 × 0069 × 00E8 × 0072 × 0065 × 002E × 2028 ÷ 00AB × 0020 × 0044 × 006F × 006E × 006E × 0065 × 002D ÷ 006C × 0075 × 0069 × 0020 ÷ 0074 × 006F × 0075 × 0074 × 0020 ÷ 0064 × 0065 × 0020 ÷ 006D × 00EA × 006D × 0065 × 0020 ÷ 00E0 × 0020 ÷ 0062 × 006F × 0069 × 0072 × 0065 × 002C × 0020 × 00BB × 0020 ÷ 0064 × 0069 × 0074 × 0020 ÷ 006D × 006F × 006E × 0020 ÷ 0070 × 00E8 × 0072 × 0065 × 002E ÷ # × [0.3] LATIN CAPITAL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER U (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E WITH GRAVE (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [6.0] LINE SEPARATOR (BK) ÷ [4.0] LATIN CAPITAL LETTER L (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER P (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E WITH GRAVE (AL) × [28.0] LATIN SMALL LETTER S (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER U (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [6.0] LINE SEPARATOR (BK) ÷ [4.0] LATIN CAPITAL LETTER E (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E WITH ACUTE (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E WITH GRAVE (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [13.02] FULL STOP (IS) × [6.0] LINE SEPARATOR (BK) ÷ [4.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER E (AL) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E WITH CIRCUMFLEX (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A WITH GRAVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E WITH GRAVE (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 00AB × 0020 × 004A × 0065 × 0020 ÷ 006D × 0065 × 0020 ÷ 0073 × 0075 × 0069 × 0073 × 0020 ÷ 0076 × 0065 × 006E × 0067 × 00E9 × 0020 ÷ 005B × 2026 × 005D × 2029 ÷ 00BB × 0020 ÷ 004F × 006E × 0020 ÷ 006E × 0065 × 0020 ÷ 006D × 0065 × 0020 ÷ 0076 × 0065 × 0072 × 0072 × 0061 × 0020 ÷ 006E × 0069 × 0020 ÷ 0070 × 0061 × 0072 × 006C × 0065 × 0072 × 0020 ÷ 006E × 0069 × 0020 ÷ 00E9 × 0063 × 0072 × 0069 × 0072 × 0065 × 0020 × 003B × 0020 ÷ 0076 × 006F × 0075 × 0073 × 0020 ÷ 0061 × 0075 × 0072 × 0065 × 007A × 0020 ÷ 0065 × 0075 × 0020 ÷ 006D × 0065 × 0073 × 0020 ÷ 0064 × 0065 × 0072 × 006E × 0069 × 00E8 × 0072 × 0065 × 0073 × 0020 ÷ 0070 × 0061 × 0072 × 006F × 006C × 0065 × 0073 × 0020 ÷ 0063 × 006F × 006D × 006D × 0065 × 0020 ÷ 006D × 0065 × 0073 × 0020 ÷ 0064 × 0065 × 0072 × 006E × 0069 × 00E8 × 0072 × 0065 × 0073 × 0020 ÷ 0061 × 0064 × 006F × 0072 × 0061 × 0074 × 0069 × 006F × 006E × 0073 × 002E × 2029 ÷ 00BB × 0020 ÷ 004A × 002E × 0020 ÷ 0053 × 002E × 0020 × 00BB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER J (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER E WITH ACUTE (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT SQUARE BRACKET (OP_OP30) × [14.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT SQUARE BRACKET (CP_CP30) × [6.0] PARAGRAPH SEPARATOR (BK) ÷ [4.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E WITH ACUTE (AL) × [28.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) × [13.02] SEMICOLON (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER U (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E WITH GRAVE (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E WITH GRAVE (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER S (AL) × [13.02] FULL STOP (IS) × [6.0] PARAGRAPH SEPARATOR (BK) ÷ [4.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER J (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER S (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 2014 × 0020 ÷ 004B × 0068 × 00F4 × 006E × 0067 × 0020 ÷ 0061 × 0069 × 0020 ÷ 0068 × 00E3 × 006D × 0020 ÷ 0062 × 0061 × 006F × 0020 ÷ 0067 × 0069 × 1EDD × 0020 ÷ 006D × 00E0 × 0020 ÷ 0062 × 00E2 × 0079 × 0020 ÷ 0067 × 0069 × 1EDD × 0020 ÷ 0068 × 00E3 × 006D × 002C × 0020 ÷ 0074 × 0068 × 1EBF × 0020 ÷ 006E × 00F3 × 0020 ÷ 006D × 1EDB × 0069 × 0020 ÷ 00AB × 0020 × 006D × 1EDB × 0069 × 0020 × 00BB × 002E ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER K (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER O WITH CIRCUMFLEX (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A WITH TILDE (AL) × [28.0] LATIN SMALL LETTER M (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER O (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O WITH HORN AND GRAVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER A WITH GRAVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A WITH CIRCUMFLEX (AL) × [28.0] LATIN SMALL LETTER Y (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O WITH HORN AND GRAVE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER A WITH TILDE (AL) × [28.0] LATIN SMALL LETTER M (AL) × [13.02] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O WITH ACUTE (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER O WITH HORN AND ACUTE (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER O WITH HORN AND ACUTE (AL) × [28.0] LATIN SMALL LETTER I (AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [13.02] FULL STOP (IS) ÷ [0.3]
+× 0050 × 0061 × 0073 × 0020 ÷ 0075 × 006E × 0065 × 0020 ÷ 0063 × 0069 × 0074 × 0061 × 0074 × 0069 × 006F × 006E × 0020 ÷ 00BB × 005A × 0069 × 0074 × 0061 × 0074 × 00AB × 0020 ÷ 0050 × 0061 × 0073 × 0020 ÷ 0075 × 006E × 0065 × 0020 ÷ 0063 × 0069 × 0074 × 0061 × 0074 × 0069 × 006F × 006E × 0020 ÷ 006E × 006F × 006E × 0020 ÷ 0070 × 006C × 0075 × 0073 ÷ # × [0.3] LATIN CAPITAL LETTER P (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [19.02] LATIN CAPITAL LETTER Z (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER P (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
+× 00AB × 0020 × 0043 × 0069 × 0074 × 0061 × 0074 × 0069 × 006F × 006E × 0020 × 00BB × 200B ÷ 004B × 0065 × 0069 × 006E × 0020 ÷ 005A × 0069 × 0074 × 0061 × 0074 × 200B ÷ 00AB × 0020 × 0041 × 0075 × 0074 × 0072 × 0065 × 0020 ÷ 0063 × 0069 × 0074 × 0061 × 0074 × 0069 × 006F × 006E × 0020 × 00BB ÷ # × [0.3] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER C (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] LATIN CAPITAL LETTER K (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER Z (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pi) × [7.01] SPACE (SP) × [15.11] LATIN CAPITAL LETTER A (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) × [15.21] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU_QU_Pf) ÷ [0.3]
+× 1F02C × 1F3FF ÷ # × [0.3] <reserved-1F02C> (Other) × [30.22] EMOJI MODIFIER FITZPATRICK TYPE-6 (EM) ÷ [0.3]
+× 00A9 ÷ 1F3FF ÷ # × [0.3] COPYRIGHT SIGN (AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (EM) ÷ [0.3]
+#
+# Lines: 10274
+#
+# EOF
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/data/SentenceBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/SentenceBreakTest.txt
new file mode 100644
index 0000000000..d2d28275b0
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/data/SentenceBreakTest.txt
@@ -0,0 +1,540 @@
+# SentenceBreakTest-15.1.0.txt
+# Date: 2023-04-05, 20:41:29 GMT
+# © 2023 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see https://www.unicode.org/reports/tr44/
+#
+# Default Sentence_Break Test
+#
+# Format:
+# <string> (# <comment>)?
+# <string> contains hex Unicode code points, with
+# ÷ wherever there is a break opportunity, and
+# × wherever there is not.
+# <comment> the format can change, but currently it shows:
+# - the sample character name
+# - (x) the Sentence_Break property value for the sample character
+# - [x] the rule that determines whether there is a break or not,
+# as listed in the Rules section of SentenceBreakTest.html
+#
+# These samples may be extended or changed in the future.
+#
+÷ 0001 × 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0001 × 0308 × 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0001 × 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 × 0308 × 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 × 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 × 0308 × 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 × 0085 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0001 × 0308 × 0085 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0001 × 0009 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0001 × 0308 × 0009 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0001 × 0061 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0001 × 0308 × 0061 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0001 × 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0001 × 0308 × 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0001 × 01BB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0001 × 0308 × 01BB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0001 × 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0001 × 0308 × 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0001 × 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0001 × 0308 × 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0001 × 0021 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0001 × 0308 × 0021 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0001 × 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0001 × 0308 × 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0001 × 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0001 × 0308 × 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0001 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0001 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000D ÷ 0308 × 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D ÷ 0308 × 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0308 × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0085 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 000D ÷ 0308 × 0085 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 000D ÷ 0009 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 000D ÷ 0308 × 0009 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 000D ÷ 0308 × 0061 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 000D ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 000D ÷ 0308 × 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 000D ÷ 01BB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 000D ÷ 0308 × 01BB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 000D ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000D ÷ 0308 × 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000D ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 000D ÷ 0308 × 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 000D ÷ 0021 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 000D ÷ 0308 × 0021 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 000D ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 000D ÷ 0308 × 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 000D ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
+÷ 000D ÷ 0308 × 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 000D ÷ 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000A ÷ 0308 × 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 0308 × 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0308 × 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0085 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 000A ÷ 0308 × 0085 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 000A ÷ 0009 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 000A ÷ 0308 × 0009 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 000A ÷ 0308 × 0061 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 000A ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 000A ÷ 0308 × 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 000A ÷ 01BB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 000A ÷ 0308 × 01BB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 000A ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000A ÷ 0308 × 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000A ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 000A ÷ 0308 × 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 000A ÷ 0021 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 000A ÷ 0308 × 0021 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 000A ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 000A ÷ 0308 × 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 000A ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
+÷ 000A ÷ 0308 × 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 000A ÷ 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0085 ÷ 0001 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0001 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0085 ÷ 000D ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0085 ÷ 0308 × 000D ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0085 ÷ 000A ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0085 ÷ 0308 × 000A ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0085 ÷ 0085 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0085 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0085 ÷ 0009 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0009 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0085 ÷ 0061 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0061 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0085 ÷ 0041 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0041 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0085 ÷ 01BB ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0085 ÷ 0308 × 01BB ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0085 ÷ 0030 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0030 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0085 ÷ 002E ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0085 ÷ 0308 × 002E ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0085 ÷ 0021 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0021 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0085 ÷ 0022 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0022 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0085 ÷ 002C ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
+÷ 0085 ÷ 0308 × 002C ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0085 ÷ 00AD ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0085 ÷ 0308 × 00AD ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0085 ÷ 0300 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0085 ÷ 0308 × 0300 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0009 × 0001 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0009 × 0308 × 0001 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0009 × 000D ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0009 × 0308 × 000D ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0009 × 000A ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0009 × 0308 × 000A ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0009 × 0085 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0009 × 0308 × 0085 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0009 × 0009 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0009 × 0308 × 0009 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0009 × 0061 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0009 × 0308 × 0061 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0009 × 0041 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0009 × 0308 × 0041 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0009 × 01BB ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0009 × 0308 × 01BB ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0009 × 0030 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0009 × 0308 × 0030 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0009 × 002E ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0009 × 0308 × 002E ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0009 × 0021 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0009 × 0308 × 0021 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0009 × 0022 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0009 × 0308 × 0022 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0009 × 002C ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0009 × 0308 × 002C ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0009 × 00AD ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0009 × 0308 × 00AD ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0009 × 0300 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0009 × 0308 × 0300 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 × 0308 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 × 0308 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 × 0308 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0061 × 0308 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0061 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0061 × 0308 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0061 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0061 × 0308 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0061 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0061 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0061 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0061 × 0308 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0061 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0061 × 0308 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0061 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0061 × 0308 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0061 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0061 × 0308 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0061 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0061 × 0308 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0061 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0041 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0041 × 0308 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0041 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0041 × 0308 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0041 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0041 × 0308 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0041 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0041 × 0308 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0041 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0041 × 0308 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0041 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0041 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0041 × 0308 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0041 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0041 × 0308 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0041 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0041 × 0308 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0041 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0041 × 0308 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0041 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0041 × 0308 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 01BB × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 01BB × 0308 × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 01BB × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 01BB × 0308 × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 01BB × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 01BB × 0308 × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 01BB × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 01BB × 0308 × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 01BB × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 01BB × 0308 × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 01BB × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 01BB × 0308 × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 01BB × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 01BB × 0308 × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 01BB × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 01BB × 0308 × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 01BB × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 01BB × 0308 × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 01BB × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 01BB × 0308 × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 01BB × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 01BB × 0308 × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 01BB × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 01BB × 0308 × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 01BB × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 01BB × 0308 × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 01BB × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 01BB × 0308 × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 01BB × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 01BB × 0308 × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0030 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0030 × 0308 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0030 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0030 × 0308 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0030 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0030 × 0308 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0030 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0030 × 0308 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0030 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0030 × 0308 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0030 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0030 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0030 × 0308 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0030 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0030 × 0308 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0030 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0030 × 0308 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0030 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0030 × 0308 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0030 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0030 × 0308 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002E × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002E × 0308 × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002E × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002E × 0308 × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002E × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 002E × 0308 × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 002E × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 002E × 0308 × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 002E × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 002E × 0308 × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 002E ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 002E × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002E × 0308 × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002E × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] FULL STOP (ATerm) ÷ [0.3]
+÷ 002E × 0308 × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3]
+÷ 002E × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 002E × 0308 × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 002E × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 002E × 0308 × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 002E × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] COMMA (SContinue) ÷ [0.3]
+÷ 002E × 0308 × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3]
+÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0021 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0021 × 0308 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0021 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0021 × 0308 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0021 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0021 × 0308 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0021 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0021 × 0308 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0021 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0021 × 0308 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0021 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0021 × 0308 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0021 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0021 × 0308 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0021 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0021 × 0308 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0021 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0021 × 0308 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0021 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] FULL STOP (ATerm) ÷ [0.3]
+÷ 0021 × 0308 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3]
+÷ 0021 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0021 × 0308 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0021 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0021 × 0308 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0021 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] COMMA (SContinue) ÷ [0.3]
+÷ 0021 × 0308 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3]
+÷ 0021 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0021 × 0308 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0021 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0021 × 0308 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0022 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0022 × 0308 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0022 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0022 × 0308 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0022 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0022 × 0308 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0022 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0022 × 0308 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0022 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0022 × 0308 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0022 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0022 × 0308 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0022 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0022 × 0308 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0022 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0022 × 0308 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0022 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0022 × 0308 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0022 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0022 × 0308 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0022 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0022 × 0308 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0022 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0022 × 0308 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0022 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0022 × 0308 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002C × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002C × 0308 × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002C × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002C × 0308 × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002C × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002C × 0308 × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002C × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 002C × 0308 × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 002C × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 002C × 0308 × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 002C × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 002C × 0308 × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 002C × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 002C × 0308 × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 002C × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 002C × 0308 × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 002C × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002C × 0308 × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002C × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 002C × 0308 × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 002C × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 002C × 0308 × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 002C × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 002C × 0308 × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 002C × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 002C × 0308 × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 00AD × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 00AD × 0308 × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 00AD × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 00AD × 0308 × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 00AD × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 00AD × 0308 × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 00AD × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 00AD × 0308 × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 00AD × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 00AD × 0308 × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 00AD × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 00AD × 0308 × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 00AD × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 00AD × 0308 × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 00AD × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 00AD × 0308 × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 00AD × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 00AD × 0308 × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 00AD × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 00AD × 0308 × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 00AD × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 00AD × 0308 × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 00AD × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 00AD × 0308 × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 00AD × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 00AD × 0308 × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0300 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0300 × 0308 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0300 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 × 0308 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 × 0308 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0300 × 0308 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
+÷ 0300 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0300 × 0308 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
+÷ 0300 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0300 × 0308 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0300 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0300 × 0308 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 0300 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0300 × 0308 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
+÷ 0300 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0300 × 0308 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0300 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0300 × 0308 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0300 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0300 × 0308 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
+÷ 0300 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0300 × 0308 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
+÷ 0300 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0300 × 0308 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
+÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
+÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
+÷ 0020 × 200D × 0646 ÷ # ÷ [0.2] SPACE (Sp) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] ARABIC LETTER NOON (OLetter) ÷ [0.3]
+÷ 0646 × 200D × 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (OLetter) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] SPACE (Sp) ÷ [0.3]
+÷ 0028 × 0022 × 0047 × 006F × 002E × 0022 × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3]
+÷ 0028 × 201C × 0047 × 006F × 003F × 201D × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] QUESTION MARK (STerm) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3]
+÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E × 0020 × 0069 × 0073 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER S (Lower) ÷ [0.3]
+÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 003F × 0020 ÷ 0048 × 0065 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [9.0] SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0033 × 002E × 0034 ÷ # ÷ [0.2] DIGIT THREE (Numeric) × [998.0] FULL STOP (ATerm) × [6.0] DIGIT FOUR (Numeric) ÷ [0.3]
+÷ 0063 × 002E × 0064 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3]
+÷ 0043 × 002E × 0064 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3]
+÷ 0063 × 002E × 0044 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3]
+÷ 0043 × 002E × 0044 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 2018 × 0028 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 2018 × 0028 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 0029 × 000A ÷ 0308 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 0074 × 0068 × 0065 × 0020 × 0072 × 0065 × 0073 × 0070 × 002E × 0020 × 006C × 0065 × 0061 × 0064 × 0065 × 0072 × 0073 × 0020 × 0061 × 0072 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] LATIN SMALL LETTER P (Lower) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER L (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
+÷ 5B57 × 002E ÷ 5B57 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E ÷ 5B83 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3]
+÷ 0065 × 0074 × 0063 × 002E × 3002 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.1] IDEOGRAPHIC FULL STOP (STerm) ÷ [0.3]
+÷ 5B57 × 3002 ÷ 5B83 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] IDEOGRAPHIC FULL STOP (STerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3]
+÷ 0021 × 0020 × 0020 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] SPACE (Sp) × [10.0] SPACE (Sp) ÷ [0.3]
+÷ 0061 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) ÷ [0.3]
+÷ 0061 × 002E × 000D × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 × 002E × 000D × 000A ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Sp) ÷ [0.3]
+÷ 0061 × 002E × 000D × 000A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
+÷ 0041 × 002E × 000D × 000A ÷ 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
+÷ 2060 × 0028 × 2060 × 0022 × 2060 × 0047 × 2060 × 006F × 2060 × 002E × 2060 × 0022 × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0028 × 2060 × 201C × 2060 × 0047 × 2060 × 006F × 2060 × 003F × 2060 × 201D × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 0020 × 2060 × 0069 × 2060 × 0073 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 003F × 2060 × 0020 × 2060 ÷ 0048 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0033 × 2060 × 002E × 2060 × 0034 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] DIGIT THREE (Numeric) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [6.0] DIGIT FOUR (Numeric) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0063 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0043 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0063 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0043 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 2018 × 2060 × 0028 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 2018 × 2060 × 0028 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 000A ÷ 2060 × 0308 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [4.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 0020 × 2060 × 0072 × 2060 × 0065 × 2060 × 0073 × 2060 × 0070 × 2060 × 002E × 2060 × 0020 × 2060 × 006C × 2060 × 0065 × 2060 × 0061 × 2060 × 0064 × 2060 × 0065 × 2060 × 0072 × 2060 × 0073 × 2060 × 0020 × 2060 × 0061 × 2060 × 0072 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER P (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER L (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 5B57 × 2060 × 002E × 2060 ÷ 5B57 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 3002 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.1] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 5B57 × 2060 × 3002 × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0021 × 2060 × 0020 × 2060 × 0020 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] EXCLAMATION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [10.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0061 × 2060 × 002E × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0061 × 2060 × 002E × 2060 × 000D ÷ 2060 × 000A ÷ 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WORD JOINER (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0061 × 2060 × 002E × 2060 × 000D ÷ 2060 × 000A ÷ 0020 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WORD JOINER (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0061 × 2060 × 002E × 2060 × 000D ÷ 2060 × 000A ÷ 0061 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WORD JOINER (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 × 0041 × 2060 × 002E × 2060 × 000D ÷ 2060 × 000A ÷ 0041 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WORD JOINER (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
+#
+# Lines: 512
+#
+# EOF
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.html b/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.html
new file mode 100644
index 0000000000..5d5d443ffc
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.html
@@ -0,0 +1,248 @@
+<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>
+<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
+<title>Word Break Chart</title>
+<style type='text/css'>
+td, th { vertical-align: top }
+</style></head>
+<body bgcolor='#FFFFFF'>
+<h2>Word_Break Chart</h2>
+<p><b>Unicode Version:</b> 15.1.0</p>
+<p><b>Date:</b> 2023-03-31, 14:30:32 GMT</p>
+<p>This page illustrates the application of the Word_Break specification. The material here is informative, not normative.</p> <p>The first chart shows where breaks would appear between different sample characters or strings. The sample characters are chosen mechanically to represent the different properties used by the specification.</p><p>Each cell shows the break-status for the position between the character(s) in its row header and the character(s) in its column header. The × symbol indicates no break, while the ÷ symbol indicated a break. The cells with × are also shaded to make it easier to scan the table. For example, in the cell at the intersection of the row headed by “CR” and the column headed by “LF”, there is a × symbol, indicating that there is no break between CR and LF.</p>
+<p>After the heavy blue line in the table are additional rows, either with different sample characters or for sequences, such as “ALetter MidLetter”. Some column headers may be composed, reflecting “treat as” or “ignore” rules.</p>
+<p>If your browser handles titles (tooltips), then hovering the mouse over the row header will show a sample character of that type. Hovering over a column header will show the sample character, plus its abbreviated general category and script. Hovering over the intersected cells shows the rule number that produces the break-status. For example, hovering over the cell at the intersection of ExtendNumLet and ALetter shows ×, with the rule 13.2. Checking below the table, rule 13.2 is “ExtendNumLet × (AHLetter | Numeric | Katakana)”, which is the one that applies to that case. Note that a rule is invoked only when no lower-numbered rules have applied.</p>
+<h3><a href='#table' name='table'>Table</a></h3>
+<table border='1' cellspacing='0' width='100%'><tr><th width='4%'></th><th width='4%' class='lbclass' title='U+0001 <START OF HEADING>, gc=Cc, sc=Zyyy'>Other</th><th width='4%' class='lbclass' title='U+000D <CARRIAGE RETURN (CR)>, gc=Cc, sc=Zyyy'>CR</th><th width='4%' class='lbclass' title='U+000A <LINE FEED (LF)>, gc=Cc, sc=Zyyy'>LF</th><th width='4%' class='lbclass' title='U+000B <LINE TABULATION>, gc=Cc, sc=Zyyy'>Newline</th><th width='4%' class='lbclass' title='U+3031 VERTICAL KANA REPEAT MARK, gc=Lm, sc=Zyyy'>Katakana</th><th width='4%' class='lbclass' title='U+0041 LATIN CAPITAL LETTER A, gc=Lu, sc=Latn'>ALetter</th><th width='4%' class='lbclass' title='U+003A COLON, gc=Po, sc=Zyyy'>MidLetter</th><th width='4%' class='lbclass' title='U+002C COMMA, gc=Po, sc=Zyyy'>MidNum</th><th width='4%' class='lbclass' title='U+002E FULL STOP, gc=Po, sc=Zyyy'>MidNumLet</th><th width='4%' class='lbclass' title='U+0030 DIGIT ZERO, gc=Nd, sc=Zyyy'>Numeric</th><th width='4%' class='lbclass' title='U+005F LOW LINE, gc=Pc, sc=Zyyy'>ExtendNumLet</th><th width='4%' class='lbclass' title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A, gc=So, sc=Zyyy'>RI</th><th width='4%' class='lbclass' title='U+05D0 HEBREW LETTER ALEF, gc=Lo, sc=Hebr'>Hebrew_Letter</th><th width='4%' class='lbclass' title='U+0022 QUOTATION MARK, gc=Po, sc=Zyyy'>Double_Quote</th><th width='4%' class='lbclass' title='U+0027 APOSTROPHE, gc=Po, sc=Zyyy'>Single_Quote</th><th width='4%' class='lbclass' title='U+231A WATCH, gc=So, sc=Zyyy'>ExtPict</th><th width='4%' class='lbclass' title='U+0020 SPACE, gc=Zs, sc=Zyyy'>WSegSpace</th><th width='4%' class='lbclass' title='U+00AD SOFT HYPHEN, gc=Cf, sc=Zyyy'>Format_FE</th><th width='4%' class='lbclass' title='U+0300 COMBINING GRAVE ACCENT, gc=Mn, sc=Zinh'>Extend_FE</th><th width='4%' class='lbclass' title='U+200D ZERO WIDTH JOINER, gc=Cf, sc=Zinh'>ZWJ_FE</th></tr>
+<tr><th class='lbclass' title='U+0001 <START OF HEADING>'>Other</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+000D <CARRIAGE RETURN (CR)>'>CR</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th></tr>
+<tr><th class='lbclass' title='U+000A <LINE FEED (LF)>'>LF</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th></tr>
+<tr><th class='lbclass' title='U+000B <LINE TABULATION>'>Newline</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th><th title='3.1' class='pairItem'>÷</th></tr>
+<tr><th class='lbclass' title='U+3031 VERTICAL KANA REPEAT MARK'>Katakana</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='13.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0041 LATIN CAPITAL LETTER A'>ALetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='9.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+003A COLON'>MidLetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+002C COMMA'>MidNum</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+002E FULL STOP'>MidNumLet</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0030 DIGIT ZERO'>Numeric</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='10.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='8.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='10.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+005F LOW LINE'>ExtendNumLet</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='13.2' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A'>RI</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='15.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+05D0 HEBREW LETTER ALEF'>Hebrew_Letter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='9.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='7.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0022 QUOTATION MARK'>Double_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0027 APOSTROPHE'>Single_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+231A WATCH'>ExtPict</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0020 SPACE'>WSegSpace</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='3.4' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+00AD SOFT HYPHEN'>Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0300 COMBINING GRAVE ACCENT'>Extend_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+200D ZERO WIDTH JOINER'>ZWJ_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='3.3' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><td bgcolor='#0000FF' colSpan='21' style='font-size: 1px'>&nbsp;</td></tr>
+<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+2060 WORD JOINER'>ALetter Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='9.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='13.1' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='5.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+003A COLON'>ALetter MidLetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+0027 APOSTROPHE'>ALetter Single_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+0027 APOSTROPHE, U+2060 WORD JOINER'>ALetter Single_Quote Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='7.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0061 LATIN SMALL LETTER A, U+002C COMMA'>ALetter MidNum</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+003A COLON'>Numeric MidLetter</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+0027 APOSTROPHE'>Numeric Single_Quote</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='11.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+002C COMMA'>Numeric MidNum</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='11.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+<tr><th class='lbclass' title='U+0031 DIGIT ONE, U+002E FULL STOP, U+2060 WORD JOINER'>Numeric MidNumLet Format_FE</th><th title='999.0' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='3.2' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='11.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='999.0' class='pairItem'>÷</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th><th title='4.0' bgcolor='#CCCCFF' class='pairItem'>×</th></tr>
+</table>
+<h3><a href='#rules' name='rules'>Rules</a></h3>
+<p>This section shows the rules. They are mechanically modified for programmatic generation of the tables and test code, and thus do not match the UAX rules precisely. In particular:</p><ol><li>The rules are cast into a form that is more like regular expressions.</li><li>The rules “sot ÷”, “÷ eot”, and “÷ Any” are added mechanically, and have artificial numbers.</li><li>The rules are given decimal numbers using tenths, and are written without prefix. For example, rule WB13a is given the number 13.1.</li><li>Any “treat as” or “ignore” rules are handled as discussed in UAX #29, and thus reflected in a transformation of the rules usually not visible here. In addition, final rules like “Any ÷ Any” may be recast as the equivalent expression “÷ Any”.</li><li>In some cases, the numbering and form of a rule is changed due to “treat as” rules.</li></ol><p>For the original rules and the macro values they use, see UAX #29.</p>
+<table>
+<tr><th style='text-align:right'><a href='#r0.2' name='r0.2'>0.2</a></th><td style='text-align:right'>sot </td><td>÷</td><td></td></tr>
+<tr><th style='text-align:right'><a href='#r0.3' name='r0.3'>0.3</a></th><td style='text-align:right'></td><td>÷</td><td> eot</td></tr>
+<tr><th style='text-align:right'><a href='#r3.0' name='r3.0'>3.0</a></th><td style='text-align:right'>CR </td><td>×</td><td> LF</td></tr>
+<tr><th style='text-align:right'><a href='#r3.1' name='r3.1'>3.1</a></th><td style='text-align:right'>(Newline | CR | LF) </td><td>÷</td><td></td></tr>
+<tr><th style='text-align:right'><a href='#r3.2' name='r3.2'>3.2</a></th><td style='text-align:right'></td><td>÷</td><td> (Newline | CR | LF)</td></tr>
+<tr><th style='text-align:right'><a href='#r3.3' name='r3.3'>3.3</a></th><td style='text-align:right'>ZWJ </td><td>×</td><td> ExtPict</td></tr>
+<tr><th style='text-align:right'><a href='#r3.4' name='r3.4'>3.4</a></th><td style='text-align:right'>WSegSpace </td><td>×</td><td> WSegSpace</td></tr>
+<tr><th style='text-align:right'><a href='#r4.0' name='r4.0'>4.0</a></th><td style='text-align:right'>[^ Newline CR LF ] </td><td>×</td><td> [Format Extend ZWJ]</td></tr>
+<tr><th style='text-align:right'><a href='#r5.0' name='r5.0'>5.0</a></th><td style='text-align:right'>AHLetter </td><td>×</td><td> AHLetter</td></tr>
+<tr><th style='text-align:right'><a href='#r6.0' name='r6.0'>6.0</a></th><td style='text-align:right'>AHLetter </td><td>×</td><td> (MidLetter | MidNumLetQ) AHLetter</td></tr>
+<tr><th style='text-align:right'><a href='#r7.0' name='r7.0'>7.0</a></th><td style='text-align:right'>AHLetter (MidLetter | MidNumLetQ) </td><td>×</td><td> AHLetter</td></tr>
+<tr><th style='text-align:right'><a href='#r7.1' name='r7.1'>7.1</a></th><td style='text-align:right'>Hebrew_Letter </td><td>×</td><td> Single_Quote</td></tr>
+<tr><th style='text-align:right'><a href='#r7.2' name='r7.2'>7.2</a></th><td style='text-align:right'>Hebrew_Letter </td><td>×</td><td> Double_Quote Hebrew_Letter</td></tr>
+<tr><th style='text-align:right'><a href='#r7.3' name='r7.3'>7.3</a></th><td style='text-align:right'>Hebrew_Letter Double_Quote </td><td>×</td><td> Hebrew_Letter</td></tr>
+<tr><th style='text-align:right'><a href='#r8.0' name='r8.0'>8.0</a></th><td style='text-align:right'>Numeric </td><td>×</td><td> Numeric</td></tr>
+<tr><th style='text-align:right'><a href='#r9.0' name='r9.0'>9.0</a></th><td style='text-align:right'>AHLetter </td><td>×</td><td> Numeric</td></tr>
+<tr><th style='text-align:right'><a href='#r10.0' name='r10.0'>10.0</a></th><td style='text-align:right'>Numeric </td><td>×</td><td> AHLetter</td></tr>
+<tr><th style='text-align:right'><a href='#r11.0' name='r11.0'>11.0</a></th><td style='text-align:right'>Numeric (MidNum | MidNumLetQ) </td><td>×</td><td> Numeric</td></tr>
+<tr><th style='text-align:right'><a href='#r12.0' name='r12.0'>12.0</a></th><td style='text-align:right'>Numeric </td><td>×</td><td> (MidNum | MidNumLetQ) Numeric</td></tr>
+<tr><th style='text-align:right'><a href='#r13.0' name='r13.0'>13.0</a></th><td style='text-align:right'>Katakana </td><td>×</td><td> Katakana</td></tr>
+<tr><th style='text-align:right'><a href='#r13.1' name='r13.1'>13.1</a></th><td style='text-align:right'>(AHLetter | Numeric | Katakana | ExtendNumLet) </td><td>×</td><td> ExtendNumLet</td></tr>
+<tr><th style='text-align:right'><a href='#r13.2' name='r13.2'>13.2</a></th><td style='text-align:right'>ExtendNumLet </td><td>×</td><td> (AHLetter | Numeric | Katakana)</td></tr>
+<tr><th style='text-align:right'><a href='#r15.0' name='r15.0'>15.0</a></th><td style='text-align:right'>^ (RI RI)* RI </td><td>×</td><td> RI</td></tr>
+<tr><th style='text-align:right'><a href='#r16.0' name='r16.0'>16.0</a></th><td style='text-align:right'>[^RI] (RI RI)* RI </td><td>×</td><td> RI</td></tr>
+<tr><th style='text-align:right'><a href='#r999.0' name='r999.0'>999.0</a></th><td style='text-align:right'></td><td>÷</td><td> Any</td></tr>
+</table>
+<h3><a href='#samples' name='samples'>Sample Strings</a></h3>
+<p>The following samples illustrate the application of the rules. The blue lines indicate possible break points. If your browser supports titles (tooltips), then positioning the mouse over each character will show its name, while positioning between characters shows the number of the rule responsible for the break-status.</p>
+<table>
+<tr><th style='text-align:right'><a href='#s1' name='s1'>1</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+000D &lt;CARRIAGE RETURN (CR)&gt; (CR)'>&#x25A1;</span><span title='3.0'><span>&nbsp;</span>&nbsp;</span><span title='U+000A &lt;LINE FEED (LF)&gt; (LF)'>&#x25A1;</span><span title='3.1'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='3.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+000A &lt;LINE FEED (LF)&gt; (LF)'>&#x25A1;</span><span title='3.1'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s2' name='s2'>2</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s3' name='s3'>3</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0646 ARABIC LETTER NOON (ALetter)'>&#x646;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s4' name='s4'>4</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0646 ARABIC LETTER NOON (ALetter)'>&#x646;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s5' name='s5'>5</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0671 ARABIC LETTER ALEF WASLA (ALetter)'>&#x671;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0644 ARABIC LETTER LAM (ALetter)'>&#x644;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0631 ARABIC LETTER REH (ALetter)'>&#x631;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+064E ARABIC FATHA (Extend_FE)'>&#x25CC;&#x64E;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0651 ARABIC SHADDA (Extend_FE)'>&#x25CC;&#x651;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+062D ARABIC LETTER HAH (ALetter)'>&#x62D;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0650 ARABIC KASRA (Extend_FE)'>&#x25CC;&#x650;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+064A ARABIC LETTER YEH (ALetter)'>&#x64A;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0645 ARABIC LETTER MEEM (ALetter)'>&#x645;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0650 ARABIC KASRA (Extend_FE)'>&#x25CC;&#x650;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+06DD ARABIC END OF AYAH (Numeric)'>&#x25A1;</span><span title='8.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0661 ARABIC-INDIC DIGIT ONE (Numeric)'>&#x661;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s6' name='s6'>6</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0721 SYRIAC LETTER MIM (ALetter)'>&#x721;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0719 SYRIAC LETTER ZAIN (ALetter)'>&#x719;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0721 SYRIAC LETTER MIM (ALetter)'>&#x721;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0718 SYRIAC LETTER WAW (ALetter)'>&#x718;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+072A SYRIAC LETTER RISH (ALetter)'>&#x72A;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0710 SYRIAC LETTER ALAPH (ALetter)'>&#x710;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+070F SYRIAC ABBREVIATION MARK (ALetter)'>&#x25A1;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+071D SYRIAC LETTER YUDH (ALetter)'>&#x71D;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0717 SYRIAC LETTER HE (ALetter)'>&#x717;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s7' name='s7'>7</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+072C SYRIAC LETTER TAW (ALetter)'>&#x72C;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+070F SYRIAC ABBREVIATION MARK (ALetter)'>&#x25A1;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+072B SYRIAC LETTER SHIN (ALetter)'>&#x72B;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0712 SYRIAC LETTER BETH (ALetter)'>&#x712;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0718 SYRIAC LETTER WAW (ALetter)'>&#x718;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s8' name='s8'>8</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s9' name='s9'>9</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='6.0'><span>&nbsp;</span>&nbsp;</span><span title='U+003A COLON (MidLetter)'>:</span><span title='7.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s10' name='s10'>10</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+003A COLON (MidLetter)'>:</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+003A COLON (MidLetter)'>:</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s11' name='s11'>11</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+05D0 HEBREW LETTER ALEF (Hebrew_Letter)'>&#x5D0;</span><span title='7.1'><span>&nbsp;</span>&nbsp;</span><span title='U+0027 APOSTROPHE (Single_Quote)'>'</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s12' name='s12'>12</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+05D0 HEBREW LETTER ALEF (Hebrew_Letter)'>&#x5D0;</span><span title='7.2'><span>&nbsp;</span>&nbsp;</span><span title='U+0022 QUOTATION MARK (Double_Quote)'>&quot;</span><span title='7.3'><span>&nbsp;</span>&nbsp;</span><span title='U+05D0 HEBREW LETTER ALEF (Hebrew_Letter)'>&#x5D0;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s13' name='s13'>13</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='9.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='8.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='10.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s14' name='s14'>14</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='12.0'><span>&nbsp;</span>&nbsp;</span><span title='U+002C COMMA (MidNum)'>,</span><span title='11.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s15' name='s15'>15</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+002C COMMA (MidNum)'>,</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+002C COMMA (MidNum)'>,</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s16' name='s16'>16</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+3031 VERTICAL KANA REPEAT MARK (Katakana)'>&#x3031;</span><span title='13.0'><span>&nbsp;</span>&nbsp;</span><span title='U+3031 VERTICAL KANA REPEAT MARK (Katakana)'>&#x3031;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s17' name='s17'>17</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.2'><span>&nbsp;</span>&nbsp;</span><span title='U+0030 DIGIT ZERO (Numeric)'>0</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.2'><span>&nbsp;</span>&nbsp;</span><span title='U+3031 VERTICAL KANA REPEAT MARK (Katakana)'>&#x3031;</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s18' name='s18'>18</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.1'><span>&nbsp;</span>&nbsp;</span><span title='U+005F LOW LINE (ExtendNumLet)'>_</span><span title='13.2'><span>&nbsp;</span>&nbsp;</span><span title='U+0041 LATIN CAPITAL LETTER A (ALetter)'>A</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s19' name='s19'>19</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='15.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s20' name='s20'>20</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s21' name='s21'>21</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s22' name='s22'>22</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s23' name='s23'>23</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A (RI)'>&#x1F1E6;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E7 REGIONAL INDICATOR SYMBOL LETTER B (RI)'>&#x1F1E7;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F1E8 REGIONAL INDICATOR SYMBOL LETTER C (RI)'>&#x1F1E8;</span><span title='16.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F1E9 REGIONAL INDICATOR SYMBOL LETTER D (RI)'>&#x1F1E9;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s24' name='s24'>24</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s25' name='s25'>25</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s26' name='s26'>26</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s27' name='s27'>27</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+2701 UPPER BLADE SCISSORS (Other)'>&#x2701;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+2701 UPPER BLADE SCISSORS (Other)'>&#x2701;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s28' name='s28'>28</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+2701 UPPER BLADE SCISSORS (Other)'>&#x2701;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s29' name='s29'>29</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F476 BABY (ExtPict)'>&#x1F476;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s30' name='s30'>30</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s31' name='s31'>31</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+1F3FF EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE)'>&#x1F3FF;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s32' name='s32'>32</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s33' name='s33'>33</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='3.3'><span>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s34' name='s34'>34</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+1F6D1 OCTAGONAL SIGN (ExtPict)'>&#x1F6D1;</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s35' name='s35'>35</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+200D ZERO WIDTH JOINER (ZWJ_FE)'>&#x25A1;</span><span title='4.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0308 COMBINING DIAERESIS (Extend_FE)'>&#x25CC;&#x308;</span><span title='5.0'><span>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+<tr><th style='text-align:right'><a href='#s36' name='s36'>36</a></th><td><font size='5'>
+<span title='0.2'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0061 LATIN SMALL LETTER A (ALetter)'>a</span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='3.4'><span>&nbsp;</span>&nbsp;</span><span title='U+0020 SPACE (WSegSpace)'> </span><span title='999.0'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span><span title='U+0062 LATIN SMALL LETTER B (ALetter)'>b</span><span title='0.3'><span style='border-right: 1px solid blue'>&nbsp;</span>&nbsp;</span>
+</font></td></tr>
+</table>
+<hr width='50%'>
+<div align='center'>
+<center>
+<table cellspacing='0' cellpadding='0' border='0'>
+<tr>
+<td><a href='https://www.unicode.org/copyright.html'>
+<img src='https://www.unicode.org/img/hb_notice.gif' border='0' alt='Access to Copyright and terms of use' width='216' height='50'></a></td>
+</tr>
+</table>
+</center>
+</div>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.txt
new file mode 100644
index 0000000000..10a111a97c
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.txt
@@ -0,0 +1,1854 @@
+# WordBreakTest-15.1.0.txt
+# Date: 2023-03-31, 14:30:32 GMT
+# © 2023 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see https://www.unicode.org/reports/tr44/
+#
+# Default Word_Break Test
+#
+# Format:
+# <string> (# <comment>)?
+# <string> contains hex Unicode code points, with
+# ÷ wherever there is a break opportunity, and
+# × wherever there is not.
+# <comment> the format can change, but currently it shows:
+# - the sample character name
+# - (x) the Word_Break property value for the sample character
+# - [x] the rule that determines whether there is a break or not,
+# as listed in the Rules section of WordBreakTest.html
+#
+# These samples may be extended or changed in the future.
+#
+÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 × 0308 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0001 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 × 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0001 ÷ 000B ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0001 × 0308 ÷ 000B ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0001 ÷ 3031 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0001 × 0308 ÷ 3031 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0001 ÷ 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0001 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0001 × 0308 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0001 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0001 × 0308 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0001 ÷ 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0001 × 0308 ÷ 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0001 ÷ 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0001 ÷ 005F ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0001 × 0308 ÷ 005F ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0001 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0001 ÷ 05D0 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0001 × 0308 ÷ 05D0 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0001 ÷ 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0001 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0001 × 0308 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0001 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0001 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0001 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0001 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0001 × 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0001 ÷ 0061 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0001 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0001 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000D ÷ 000B ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 000B ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 000D ÷ 3031 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 000D ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 000D ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COLON (MidLetter) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000D ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000D ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000D ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000D ÷ 005F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000D ÷ 05D0 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000D ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000D ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] WATCH (ExtPict) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000D ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] SPACE (WSegSpace) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 000D ÷ 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 000D ÷ 0061 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000A ÷ 000B ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 000B ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 000A ÷ 3031 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 000A ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 000A ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COLON (MidLetter) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000A ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000A ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000A ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000A ÷ 005F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000A ÷ 05D0 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000A ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000A ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] WATCH (ExtPict) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000A ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] SPACE (WSegSpace) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 000A ÷ 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 000A ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0001 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 000B ÷ 000D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 000B ÷ 000A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 000B ÷ 000B ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 000B ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 000B ÷ 3031 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 000B ÷ 0041 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 000B ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COLON (MidLetter) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000B ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000B ÷ 002E ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000B ÷ 0030 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 000B ÷ 005F ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 000B ÷ 1F1E6 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 000B ÷ 05D0 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000B ÷ 0022 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000B ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 231A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] WATCH (ExtPict) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 000B ÷ 0020 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] SPACE (WSegSpace) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 000B ÷ 00AD ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0300 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000B ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 000B ÷ 200D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 000B ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 000B ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000B ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 000B ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 ÷ 0001 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0001 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 3031 ÷ 000D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 3031 × 0308 ÷ 000D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 3031 ÷ 000A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 3031 × 0308 ÷ 000A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 3031 ÷ 000B ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 3031 × 0308 ÷ 000B ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 3031 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 3031 × 0308 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 3031 ÷ 0041 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0041 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 3031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 3031 × 0308 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 3031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 3031 × 0308 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 3031 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 3031 × 0308 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 3031 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 3031 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 3031 × 0308 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 3031 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 3031 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 3031 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 3031 × 0308 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 3031 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 ÷ 231A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 3031 × 0308 ÷ 231A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 3031 ÷ 0020 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0020 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 3031 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 3031 × 0308 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 3031 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 3031 × 0308 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 3031 × 200D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 3031 × 0308 × 200D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 3031 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 3031 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 3031 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 ÷ 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0041 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0041 ÷ 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0041 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0041 ÷ 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0041 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0041 ÷ 000B ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0041 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0041 ÷ 3031 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0041 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0041 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0041 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0041 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0041 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0041 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0041 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0041 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0041 × 0308 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0041 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0041 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0041 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0041 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0041 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0041 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 ÷ 231A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0041 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0041 ÷ 0020 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0041 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0041 × 200D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0041 × 0308 × 200D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0041 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0041 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0041 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0041 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0041 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A ÷ 0001 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 003A ÷ 000D ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 003A ÷ 000A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 003A ÷ 000B ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 003A ÷ 3031 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 003A ÷ 0041 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 003A × 0308 ÷ 0041 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 003A ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 003A ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 003A ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 003A ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 003A ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 003A ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 003A ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A ÷ 231A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 003A × 0308 ÷ 231A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 003A ÷ 0020 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 003A × 0308 ÷ 0020 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 003A × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 003A × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 003A × 200D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 003A × 0308 × 200D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 003A ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C ÷ 0001 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002C ÷ 000D ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002C ÷ 000A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002C ÷ 000B ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 002C ÷ 3031 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 002C ÷ 0041 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 002C ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002C ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002C ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002C ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002C ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 002C ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002C ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C ÷ 231A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 002C × 0308 ÷ 231A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 002C ÷ 0020 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 002C × 0308 ÷ 0020 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002C × 200D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 002C × 0308 × 200D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002E ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002E × 0308 ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002E ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002E × 0308 ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002E ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 002E × 0308 ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 002E ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 002E × 0308 ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 002E ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E × 0308 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002E × 0308 ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002E ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002E × 0308 ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002E ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 002E × 0308 ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 002E ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 002E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 002E ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002E × 0308 ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002E ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002E ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E ÷ 231A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 002E × 0308 ÷ 231A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 002E ÷ 0020 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 002E × 0308 ÷ 0020 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002E × 200D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 002E × 0308 × 200D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 002E ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0030 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0030 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0030 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0030 ÷ 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0030 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0030 ÷ 000B ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0030 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0030 ÷ 3031 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0030 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0030 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0030 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0030 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0030 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0030 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0030 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0030 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0030 × 0308 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0030 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0030 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0030 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0030 × 0308 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0030 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0030 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 ÷ 231A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0030 × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0030 ÷ 0020 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0030 × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0030 × 200D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0030 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0030 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0030 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0030 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0030 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0030 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F ÷ 0001 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 005F × 0308 ÷ 0001 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 005F ÷ 000D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 005F × 0308 ÷ 000D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 005F ÷ 000A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 005F × 0308 ÷ 000A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 005F ÷ 000B ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 005F × 0308 ÷ 000B ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 005F × 3031 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 005F × 0308 × 3031 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 005F × 0041 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 005F × 0308 × 0041 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 005F ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 005F × 0308 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 005F ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 005F × 0308 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 005F ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 005F × 0308 ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 005F × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 005F × 0308 × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 005F × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 005F × 0308 × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 005F ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 005F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 005F × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 005F × 0308 × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 005F ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 005F × 0308 ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F ÷ 231A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 005F × 0308 ÷ 231A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 005F ÷ 0020 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 005F × 0308 ÷ 0020 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 005F × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 005F × 0308 × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 005F × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 005F × 0308 × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 005F × 200D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 005F × 0308 × 200D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 005F × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 005F × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 005F × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 005F × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 005F × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 005F × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 005F × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 1F1E6 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 1F1E6 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 1F1E6 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 1F1E6 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 1F1E6 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 1F1E6 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 1F1E6 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 1F1E6 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F1E6 × 0308 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [15.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 1F1E6 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 1F1E6 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 1F1E6 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 1F1E6 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 1F1E6 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 1F1E6 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 1F1E6 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 05D0 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 05D0 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 05D0 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 05D0 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 05D0 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 05D0 × 0308 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 05D0 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 05D0 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 05D0 × 0308 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 05D0 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 05D0 × 0308 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 05D0 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 05D0 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 05D0 × 0308 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 05D0 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0308 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 ÷ 231A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 231A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 05D0 ÷ 0020 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 0020 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 05D0 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 05D0 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 05D0 × 200D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 200D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 05D0 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0022 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0022 × 0308 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0022 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0022 × 0308 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0022 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0022 × 0308 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0022 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0022 × 0308 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0022 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0022 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 × 0308 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0022 × 0308 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0022 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0022 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0022 × 0308 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0022 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0022 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0022 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0022 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0022 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 ÷ 231A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0022 × 0308 ÷ 231A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0022 ÷ 0020 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0020 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0022 × 200D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0022 × 0308 × 200D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0022 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0027 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 ÷ 231A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0027 × 0308 ÷ 231A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0027 ÷ 0020 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0020 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0027 × 200D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 231A ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 231A × 0308 ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 231A ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 231A × 0308 ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 231A ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 231A × 0308 ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 231A ÷ 000B ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 231A × 0308 ÷ 000B ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 231A ÷ 3031 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 231A × 0308 ÷ 3031 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 231A ÷ 0041 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 231A × 0308 ÷ 0041 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 231A ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 231A × 0308 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 231A ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 231A × 0308 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 231A ÷ 002E ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 231A × 0308 ÷ 002E ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 231A ÷ 0030 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 231A × 0308 ÷ 0030 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 231A ÷ 005F ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 231A × 0308 ÷ 005F ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 231A ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 231A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 231A ÷ 05D0 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 231A × 0308 ÷ 05D0 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 231A ÷ 0022 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 231A × 0308 ÷ 0022 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 231A ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 231A × 0308 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 231A ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 231A × 0308 ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 231A ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 231A × 0308 ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 231A × 00AD ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 231A × 0308 × 00AD ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 231A × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 231A × 0308 × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 231A × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 231A × 0308 × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 231A ÷ 0061 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 231A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 231A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 231A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 231A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 231A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 231A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 231A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 231A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 231A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 231A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 231A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 231A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 231A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 231A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 231A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 231A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 231A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0020 ÷ 000B ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0020 × 0308 ÷ 000B ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0020 ÷ 3031 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0020 × 0308 ÷ 3031 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0020 ÷ 0041 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0041 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0020 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0020 × 0308 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0020 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0020 × 0308 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0020 ÷ 002E ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0020 × 0308 ÷ 002E ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0020 ÷ 0030 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0030 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0020 ÷ 005F ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0020 × 0308 ÷ 005F ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0020 ÷ 05D0 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0020 × 0308 ÷ 05D0 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0020 ÷ 0022 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0022 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0020 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0020 ÷ 231A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0020 × 0308 ÷ 231A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0020 × 0020 ÷ # ÷ [0.2] SPACE (WSegSpace) × [3.4] SPACE (WSegSpace) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0020 × 00AD ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0020 × 0308 × 00AD ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0020 ÷ 0061 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0020 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0020 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0020 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0020 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0020 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0020 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0020 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0020 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0020 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 00AD ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 00AD × 0308 ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 00AD ÷ 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 00AD × 0308 ÷ 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 00AD ÷ 000B ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 00AD × 0308 ÷ 000B ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 00AD ÷ 3031 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 00AD × 0308 ÷ 3031 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 00AD ÷ 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 00AD ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 00AD × 0308 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 00AD ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 00AD × 0308 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 00AD ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 00AD × 0308 ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 00AD ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 00AD ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 00AD × 0308 ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 00AD ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 00AD × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 00AD ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 00AD × 0308 ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 00AD ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD ÷ 231A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 00AD × 0308 ÷ 231A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 00AD ÷ 0020 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0020 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 00AD × 200D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 00AD × 0308 × 200D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 00AD ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 00AD ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 00AD ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0300 ÷ 000B ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0300 × 0308 ÷ 000B ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0300 ÷ 3031 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0300 × 0308 ÷ 3031 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0300 ÷ 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0300 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0300 × 0308 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0300 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0300 × 0308 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0300 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0300 × 0308 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0300 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0300 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0300 × 0308 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0300 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0300 × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0300 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0300 × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0300 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0300 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0300 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 200D ÷ 000B ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 200D × 0308 ÷ 000B ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 200D ÷ 3031 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 200D × 0308 ÷ 3031 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 200D ÷ 0041 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 200D × 0308 ÷ 0041 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 200D ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 200D × 0308 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 200D ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 200D × 0308 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 200D ÷ 002E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 200D × 0308 ÷ 002E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 200D ÷ 0030 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 200D × 0308 ÷ 0030 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 200D ÷ 005F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 200D × 0308 ÷ 005F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 200D ÷ 05D0 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 200D × 0308 ÷ 05D0 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 200D ÷ 0022 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 200D × 0308 ÷ 0022 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 200D ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 200D × 0308 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 200D × 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] WATCH (ExtPict) ÷ [0.3]
+÷ 200D × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 200D × 00AD ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 200D × 0308 × 00AD ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 200D ÷ 0061 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 200D × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 200D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 200D × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 200D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 200D × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 200D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 200D × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 200D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 200D × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 200D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 200D × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 200D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 200D × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 200D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 200D × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 200D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 200D × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 × 2060 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 × 2060 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 × 2060 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 × 2060 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 003A × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 × 003A × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 003A × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 003A × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 003A × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 × 003A × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 003A × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 003A × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 × 0027 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0061 ÷ 002C × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 003A × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 × 002C × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 002C × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 002C × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 002C × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 002C × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 002C × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 002C × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 × 002C × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
+÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
+÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] ARABIC LETTER NOON (ALetter) ÷ [0.3]
+÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3]
+÷ 0671 × 0644 × 0631 × 064E × 0651 × 062D × 0650 × 064A × 0645 × 0650 ÷ 0020 ÷ 06DD × 0661 ÷ # ÷ [0.2] ARABIC LETTER ALEF WASLA (ALetter) × [5.0] ARABIC LETTER LAM (ALetter) × [5.0] ARABIC LETTER REH (ALetter) × [4.0] ARABIC FATHA (Extend_FE) × [4.0] ARABIC SHADDA (Extend_FE) × [5.0] ARABIC LETTER HAH (ALetter) × [4.0] ARABIC KASRA (Extend_FE) × [5.0] ARABIC LETTER YEH (ALetter) × [5.0] ARABIC LETTER MEEM (ALetter) × [4.0] ARABIC KASRA (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [999.0] ARABIC END OF AYAH (Numeric) × [8.0] ARABIC-INDIC DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0721 × 0719 × 0721 × 0718 × 072A × 0710 ÷ 0020 ÷ 070F × 071D × 0717 ÷ # ÷ [0.2] SYRIAC LETTER MIM (ALetter) × [5.0] SYRIAC LETTER ZAIN (ALetter) × [5.0] SYRIAC LETTER MIM (ALetter) × [5.0] SYRIAC LETTER WAW (ALetter) × [5.0] SYRIAC LETTER RISH (ALetter) × [5.0] SYRIAC LETTER ALAPH (ALetter) ÷ [999.0] SPACE (WSegSpace) ÷ [999.0] SYRIAC ABBREVIATION MARK (ALetter) × [5.0] SYRIAC LETTER YUDH (ALetter) × [5.0] SYRIAC LETTER HE (ALetter) ÷ [0.3]
+÷ 072C × 070F × 072B × 0712 × 0718 ÷ # ÷ [0.2] SYRIAC LETTER TAW (ALetter) × [5.0] SYRIAC ABBREVIATION MARK (ALetter) × [5.0] SYRIAC LETTER SHIN (ALetter) × [5.0] SYRIAC LETTER BETH (ALetter) × [5.0] SYRIAC LETTER WAW (ALetter) ÷ [0.3]
+÷ 0041 × 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0041 × 003A × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0041 ÷ 003A ÷ 003A ÷ 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0022 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.2] QUOTATION MARK (Double_Quote) × [7.3] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0041 × 0030 × 0030 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0030 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0030 ÷ 002C ÷ 002C ÷ 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 3031 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0041 × 005F × 0030 × 005F × 3031 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0041 × 005F × 005F × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 200D × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [999.0] BABY (ExtPict) ÷ [0.3]
+÷ 1F6D1 × 200D × 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 0061 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] UPPER BLADE SCISSORS (Other) ÷ [0.3]
+÷ 0061 × 200D × 2701 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] UPPER BLADE SCISSORS (Other) ÷ [0.3]
+÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] BABY (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [0.3]
+÷ 1F6D1 × 1F3FF ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [0.3]
+÷ 200D × 1F6D1 × 1F3FF ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [0.3]
+÷ 200D × 1F6D1 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 200D × 1F6D1 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 1F6D1 ÷ 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) ÷ [999.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3]
+÷ 0061 × 0308 × 200D × 0308 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 0061 ÷ 0020 × 0020 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] SPACE (WSegSpace) × [3.4] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
+#
+# Lines: 1826
+#
+# EOF
diff --git a/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
new file mode 100644
index 0000000000..560b4a47dd
--- /dev/null
+++ b/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
@@ -0,0 +1,861 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QScopedValueRollback>
+
+#include <qtextboundaryfinder.h>
+#include <qfile.h>
+#include <qdebug.h>
+#include <qlist.h>
+#include <qset.h>
+
+#include <algorithm>
+
+using namespace Qt::Literals::StringLiterals;
+
+class tst_QTextBoundaryFinder : public QObject
+{
+ Q_OBJECT
+private slots:
+#ifdef QT_BUILD_INTERNAL
+ void graphemeBoundariesDefault_data();
+ void graphemeBoundariesDefault();
+ void wordBoundariesDefault_data();
+ void wordBoundariesDefault();
+ void sentenceBoundariesDefault_data();
+ void sentenceBoundariesDefault();
+ void lineBoundariesDefault_data();
+ void lineBoundariesDefault();
+#endif
+
+ void graphemeBoundaries_manual_data();
+ void graphemeBoundaries_manual();
+
+ void wordBoundaries_manual_data();
+ void wordBoundaries_manual();
+ void sentenceBoundaries_manual_data();
+ void sentenceBoundaries_manual();
+ void lineBoundaries_manual_data();
+ void lineBoundaries_manual();
+
+ void emptyText_data();
+ void emptyText();
+ void fastConstructor();
+ void assignmentOperator();
+ void isAtSoftHyphen_data();
+ void isAtSoftHyphen();
+};
+
+
+QT_BEGIN_NAMESPACE
+namespace QTest {
+
+template<>
+inline char *toString(const QTextBoundaryFinder::BoundaryReasons &flags)
+{
+ return qstrdup(QByteArray::number(int(flags)).constData());
+}
+
+template<>
+inline char *toString(const QList<int> &list)
+{
+ QByteArray s;
+ for (QList<int>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) {
+ if (!s.isEmpty())
+ s += ", ";
+ s += QByteArray::number(*it);
+ }
+ s = "{ " + s + " }";
+ return qstrdup(s.constData());
+}
+
+} // namespace QTest
+QT_END_NAMESPACE
+
+#ifdef QT_BUILD_INTERNAL
+static void generateDataFromFile(const QString &fname, const QSet<QString> &skipSet = {})
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int> >("expectedBreakPositions");
+
+ QString testFile = QFINDTESTDATA(fname);
+ QVERIFY2(!testFile.isEmpty(), (fname.toLatin1() + QByteArray(" not found!")));
+ QFile f(testFile);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+
+ int linenum = 0;
+ while (!f.atEnd()) {
+ linenum++;
+
+ QByteArray line = f.readLine();
+ if (line.startsWith('#'))
+ continue;
+
+ QString test = QString::fromUtf8(line);
+ QString comments;
+ int hash = test.indexOf('#');
+ if (hash > 0) {
+ comments = test.mid(hash + 1).simplified();
+ test = test.left(hash);
+ }
+
+ QString testString;
+ QList<int> expectedBreakPositions;
+ const QStringList parts = test.simplified().split(QLatin1Char(' '), Qt::SkipEmptyParts);
+ for (const QString &part : parts) {
+ if (part.size() == 1) {
+ if (part.at(0).unicode() == 0xf7)
+ expectedBreakPositions.append(testString.size());
+ else
+ QVERIFY(part.at(0).unicode() == 0xd7);
+ continue;
+ }
+ bool ok = true;
+ uint ucs4 = part.toInt(&ok, 16);
+ QVERIFY(ok && ucs4 > 0);
+ if (QChar::requiresSurrogates(ucs4)) {
+ testString.append(QChar::highSurrogate(ucs4));
+ testString.append(QChar::lowSurrogate(ucs4));
+ } else {
+ testString.append(QChar(ucs4));
+ }
+ }
+ QVERIFY(!testString.isEmpty());
+ QVERIFY(!expectedBreakPositions.isEmpty());
+
+ bool skip = false;
+
+ if (!comments.isEmpty()) {
+ const QStringList lst = comments.simplified().split(QLatin1Char(' '), Qt::SkipEmptyParts);
+ comments.clear();
+ for (const QString &part : lst) {
+ if (part.size() == 1) {
+ if (part.at(0).unicode() == 0xf7)
+ comments += QLatin1Char('+');
+ else if (part.at(0).unicode() == 0xd7)
+ comments += QLatin1Char('x');
+ continue;
+ }
+ if (part.startsWith(QLatin1Char('(')) && part.endsWith(QLatin1Char(')'))) {
+ skip |= skipSet.contains(part.sliced(1, part.length() - 2));
+ comments += part;
+ }
+ }
+ }
+
+ const QByteArray nm = "line #" + QByteArray::number(linenum) + ": " + comments.toLatin1();
+
+ if (skip)
+ qDebug() << "Skipping" << nm;
+ else
+ QTest::newRow(nm.constData()) << testString << expectedBreakPositions;
+ }
+}
+#endif
+
+static void doTestData(const QString &testString, const QList<int> &expectedBreakPositions,
+ QTextBoundaryFinder::BoundaryType type,
+ QTextBoundaryFinder::BoundaryReasons reasons = QTextBoundaryFinder::BreakOpportunity)
+{
+ QVERIFY(!testString.isEmpty());
+
+ QTextBoundaryFinder boundaryFinder(type, testString);
+
+ // test toNextBoundary()
+ {
+ QList<int> actualBreakPositions;
+ do {
+ QVERIFY(boundaryFinder.isAtBoundary());
+ if (boundaryFinder.boundaryReasons() & reasons)
+ actualBreakPositions.append(boundaryFinder.position());
+ } while (boundaryFinder.toNextBoundary() != -1);
+ QCOMPARE(actualBreakPositions, expectedBreakPositions);
+ }
+ QCOMPARE(boundaryFinder.position(), -1);
+ QVERIFY(!boundaryFinder.isAtBoundary());
+ QVERIFY(boundaryFinder.boundaryReasons() == QTextBoundaryFinder::NotAtBoundary);
+
+ // test toPreviousBoundary()
+ {
+ QList<int> expectedBreakPositionsRev = expectedBreakPositions;
+ std::sort(expectedBreakPositionsRev.begin(), expectedBreakPositionsRev.end(), std::greater<int>());
+
+ QList<int> actualBreakPositions;
+ boundaryFinder.toEnd();
+ do {
+ QVERIFY(boundaryFinder.isAtBoundary());
+ if (boundaryFinder.boundaryReasons() & reasons)
+ actualBreakPositions.append(boundaryFinder.position());
+ } while (boundaryFinder.toPreviousBoundary() != -1);
+ QCOMPARE(actualBreakPositions, expectedBreakPositionsRev);
+ }
+ QCOMPARE(boundaryFinder.position(), -1);
+ QVERIFY(!boundaryFinder.isAtBoundary());
+ QVERIFY(boundaryFinder.boundaryReasons() == QTextBoundaryFinder::NotAtBoundary);
+
+ // test boundaryReasons()
+ for (int i = 0; i <= testString.size(); ++i) {
+ boundaryFinder.setPosition(i);
+ QCOMPARE(!!(boundaryFinder.boundaryReasons() & reasons), expectedBreakPositions.contains(i));
+ }
+}
+
+#ifdef QT_BUILD_INTERNAL
+
+QT_BEGIN_NAMESPACE
+extern Q_AUTOTEST_EXPORT int qt_initcharattributes_default_algorithm_only;
+QT_END_NAMESPACE
+
+void tst_QTextBoundaryFinder::graphemeBoundariesDefault_data()
+{
+
+ // QTBUG-121907: We are not using Unicode grapheme segmentation for Indic scripts.
+ QSet<QString> skipSet = {u"ConjunctLinkingScripts_LinkingConsonant"_s};
+ generateDataFromFile("data/GraphemeBreakTest.txt", skipSet);
+}
+
+void tst_QTextBoundaryFinder::graphemeBoundariesDefault()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
+ qt_initcharattributes_default_algorithm_only++;
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Grapheme);
+}
+
+void tst_QTextBoundaryFinder::wordBoundariesDefault_data()
+{
+ generateDataFromFile("data/WordBreakTest.txt");
+}
+
+void tst_QTextBoundaryFinder::wordBoundariesDefault()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
+ qt_initcharattributes_default_algorithm_only++;
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Word);
+}
+
+void tst_QTextBoundaryFinder::sentenceBoundariesDefault_data()
+{
+ generateDataFromFile("data/SentenceBreakTest.txt");
+}
+
+void tst_QTextBoundaryFinder::sentenceBoundariesDefault()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
+ qt_initcharattributes_default_algorithm_only++;
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Sentence);
+}
+
+void tst_QTextBoundaryFinder::lineBoundariesDefault_data()
+{
+ // QTBUG-121907: Indic line breaking is not supported
+ QSet<QString> skipSet = {u"AK"_s, u"AP"_s, u"AS"_s, u"VI"_s, u"VF"_s};
+
+ generateDataFromFile("data/LineBreakTest.txt", skipSet);
+}
+
+void tst_QTextBoundaryFinder::lineBoundariesDefault()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
+ qt_initcharattributes_default_algorithm_only++;
+
+ expectedBreakPositions.prepend(0); // ### QTBF generates a boundary at start of text
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
+}
+#endif // QT_BUILD_INTERNAL
+
+void tst_QTextBoundaryFinder::graphemeBoundaries_manual_data()
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int>>("expectedBreakPositions");
+
+ {
+ // QTBUG-94951
+ QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xD83D), QChar(0xDCF2), // U+1F4F2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT
+ QChar(0xD83D), QChar(0xDCE9), // U+1F4E9 ENVELOPE WITH DOWNWARDS ARROW ABOVE
+ };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+
+ QList<int> expectedBreakPositions{0, 2, 4, 6};
+ QTest::newRow("+EXTPICxEXT+EXTPIC+EXTPIC+") << testString << expectedBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+
+ QList<int> expectedBreakPositions{0, 2, 4};
+ QTest::newRow("+EXTPICxEXT+EXTPICxEXT+") << testString << expectedBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+
+ QList<int> expectedBreakPositions{0, 4, 7};
+ QTest::newRow("+EXTPICxEXTxEXTxEXT+EXTPICxEXTxEXT+") << testString << expectedBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0x200D), // U+200D ZERO WIDTH JOINER
+ QChar(0xD83D), QChar(0xDCF2), // U+1F4F2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+
+ QList<int> expectedBreakPositions{0, 7};
+ QTest::newRow("+EXTPICxEXTxEXTxZWJxEXTPICxEXTxEXT+") << testString << expectedBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0x200D), // U+200D ZERO WIDTH JOINER
+ QChar(0x0041), // U+0041 LATIN CAPITAL LETTER A
+ QChar(0xD83D), QChar(0xDCF2), // U+1F4F2 MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT
+ };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+
+ QList<int> expectedBreakPositions{0, 4, 5, 7};
+ QTest::newRow("+EXTPICxEXTxEXTxZWJ+Any+EXTPIC+") << testString << expectedBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x2764), // U+2764 HEAVY BLACK HEART
+ QChar(0xFE0F), // U+FE0F VARIATION SELECTOR-16
+ QChar(0xD83C), QChar(0xDDEA), // U+1F1EA REGIONAL INDICATOR SYMBOL LETTER E
+ QChar(0xD83C), QChar(0xDDFA), // U+1F1FA REGIONAL INDICATOR SYMBOL LETTER U
+ QChar(0xD83C), QChar(0xDDEA), // U+1F1EA REGIONAL INDICATOR SYMBOL LETTER E
+ QChar(0xD83C), QChar(0xDDFA), // U+1F1FA REGIONAL INDICATOR SYMBOL LETTER U
+ QChar(0xD83C), QChar(0xDDEA), // U+1F1EA REGIONAL INDICATOR SYMBOL LETTER E
+ QChar(0x0041), // U+0041 LATIN CAPITAL LETTER A
+ };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+
+ QList<int> expectedBreakPositions{0, 2, 6, 10, 12, 13};
+ QTest::newRow("+EXTPICxEXT+RIxRI+RIxRI+RI+ANY+") << testString << expectedBreakPositions;
+ }
+}
+
+void tst_QTextBoundaryFinder::graphemeBoundaries_manual()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Grapheme);
+}
+
+void tst_QTextBoundaryFinder::wordBoundaries_manual_data()
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int> >("expectedBreakPositions");
+ QTest::addColumn<QList<int> >("expectedStartPositions");
+ QTest::addColumn<QList<int> >("expectedEndPositions");
+
+ {
+ QChar s[] = { QChar(0x000D), QChar(0x000A), QChar(0x000A) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 2 << 3;
+
+ QTest::newRow("+CRxLF+LF+") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x000D), QChar(0x0308), QChar(0x000A), QChar(0x000A) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 2 << 3 << 4;
+
+ QTest::newRow("+CR+FE+LF+LF+") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 3 << 4 << 7 << 8 << 11 << 12 << 14 << 17 << 18 << 21 << 22 << 25 << 26;
+ expectedStartPositions << 0 << 4 << 8 << 14 << 18 << 22;
+ expectedEndPositions << 3 << 7 << 11 << 17 << 21 << 25;
+
+ QTest::newRow("words1") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Hello (sad) world !"));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 5 << 6 << 7 << 10 << 11 << 12 << 17 << 18 << 19;
+ expectedStartPositions << 0 << 7 << 12;
+ expectedEndPositions << 5 << 10 << 17;
+
+ QTest::newRow("words2") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("mr.Hamster"));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 2 << 3 << 10;
+ expectedStartPositions << 0 << 3;
+ expectedEndPositions << 2 << 10;
+
+ QTest::newRow("words3") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("This is a sample buffer.Please test me . He's don't Le'Clerk."));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 4 << 5 << 7 << 12 << 13 << 14 << 20 << 21 << 27 << 28 << 34
+ << 35 << 39 << 40 << 42 << 43 << 44 << 49 << 53 << 54 << 59 << 60
+ << 68 << 69;
+ expectedStartPositions << 0 << 5 << 12 << 14 << 21 << 28 << 35 << 40 << 49 << 54 << 60;
+ expectedEndPositions << 4 << 7 << 13 << 20 << 27 << 34 << 39 << 42 << 53 << 59 << 68;
+
+ QTest::newRow("words4") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ // text with trailing space
+ QString testString(QString::fromUtf8("Please test me. Finish "));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 6 << 7 << 11 << 12 << 14 << 15 << 16 << 22 << 23;
+ expectedStartPositions << 0 << 7 << 12 << 16;
+ expectedEndPositions << 6 << 11 << 14 << 22;
+
+ QTest::newRow("qtbug6498") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+
+ // Sample Strings from WordBreakTest.html
+ {
+ QChar s[] = { QChar(0x0063), QChar(0x0061), QChar(0x006E), QChar(0x0027), QChar(0x0074) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 5;
+ expectedStartPositions << 0;
+ expectedEndPositions << 5;
+
+ QTest::newRow("ts 1") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x0063), QChar(0x0061), QChar(0x006E), QChar(0x2019), QChar(0x0074) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 5;
+ expectedStartPositions << 0;
+ expectedEndPositions << 5;
+
+ QTest::newRow("ts 2") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x0061), QChar(0x0062), QChar(0x00AD), QChar(0x0062), QChar(0x0061) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 5;
+ expectedStartPositions << 0;
+ expectedEndPositions << 5;
+
+ QTest::newRow("ts 3") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x0061), QChar(0x0024), QChar(0x002D), QChar(0x0033),
+ QChar(0x0034), QChar(0x002C), QChar(0x0035), QChar(0x0036),
+ QChar(0x0037), QChar(0x002E), QChar(0x0031), QChar(0x0034),
+ QChar(0x0025), QChar(0x0062) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 2 << 3 << 12 << 13 << 14;
+ expectedStartPositions << 0 << 3 << 13;
+ expectedEndPositions << 1 << 12 << 14;
+
+ QTest::newRow("ts 4") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x0033), QChar(0x0061) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 2;
+ expectedStartPositions << 0;
+ expectedEndPositions << 2;
+
+ QTest::newRow("ts 5") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x2060), QChar(0x0063), QChar(0x2060), QChar(0x0061),
+ QChar(0x2060), QChar(0x006E), QChar(0x2060), QChar(0x0027),
+ QChar(0x2060), QChar(0x0074), QChar(0x2060), QChar(0x2060) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 12;
+ expectedStartPositions << 1;
+ expectedEndPositions << 12;
+
+ QTest::newRow("ts 1e") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x2060), QChar(0x0063), QChar(0x2060), QChar(0x0061),
+ QChar(0x2060), QChar(0x006E), QChar(0x2060), QChar(0x2019),
+ QChar(0x2060), QChar(0x0074), QChar(0x2060), QChar(0x2060) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 12;
+ expectedStartPositions << 1;
+ expectedEndPositions << 12;
+
+ QTest::newRow("ts 2e") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x2060), QChar(0x0061), QChar(0x2060), QChar(0x0062),
+ QChar(0x2060), QChar(0x00AD), QChar(0x2060), QChar(0x0062),
+ QChar(0x2060), QChar(0x0061), QChar(0x2060), QChar(0x2060) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 12;
+ expectedStartPositions << 1;
+ expectedEndPositions << 12;
+
+ QTest::newRow("ts 3e") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x2060), QChar(0x0061), QChar(0x2060), QChar(0x0024),
+ QChar(0x2060), QChar(0x002D), QChar(0x2060), QChar(0x0033),
+ QChar(0x2060), QChar(0x0034), QChar(0x2060), QChar(0x002C),
+ QChar(0x2060), QChar(0x0035), QChar(0x2060), QChar(0x0036),
+ QChar(0x2060), QChar(0x0037), QChar(0x2060), QChar(0x002E),
+ QChar(0x2060), QChar(0x0031), QChar(0x2060), QChar(0x0034),
+ QChar(0x2060), QChar(0x0025), QChar(0x2060), QChar(0x0062),
+ QChar(0x2060), QChar(0x2060) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 3 << 5 << 7 << 25 << 27 << 30;
+ expectedStartPositions << 1 << 7 << 27;
+ expectedEndPositions << 3 << 25 << 30;
+
+ QTest::newRow("ts 4e") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+ {
+ QChar s[] = { QChar(0x2060), QChar(0x0033), QChar(0x2060), QChar(0x0061),
+ QChar(0x2060), QChar(0x2060) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
+ expectedBreakPositions << 0 << 1 << 6;
+ expectedStartPositions << 1;
+ expectedEndPositions << 6;
+
+ QTest::newRow("ts 5e") << testString << expectedBreakPositions
+ << expectedStartPositions << expectedEndPositions;
+ }
+}
+
+void tst_QTextBoundaryFinder::wordBoundaries_manual()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+ QFETCH(QList<int>, expectedStartPositions);
+ QFETCH(QList<int>, expectedEndPositions);
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Word);
+ doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Word, QTextBoundaryFinder::StartOfItem);
+ doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Word, QTextBoundaryFinder::EndOfItem);
+}
+
+void tst_QTextBoundaryFinder::sentenceBoundaries_manual_data()
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int> >("expectedBreakPositions");
+
+ {
+ QChar s[] = { QChar(0x000D), QChar(0x000A), QChar(0x000A) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 2 << 3;
+
+ QTest::newRow("+CRxLF+LF+") << testString << expectedBreakPositions;
+ }
+ {
+ QChar s[] = { QChar(0x000D), QChar(0x0308), QChar(0x000A), QChar(0x000A) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 1 << 3 << 4;
+
+ QTest::newRow("+CR+FExLF+LF+") << testString << expectedBreakPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 14 << 26;
+
+ QTest::newRow("data1") << testString << expectedBreakPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Diga-nos qualé a sua opinião"));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 28;
+
+ QTest::newRow("data2") << testString << expectedBreakPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("mr.Hamster"));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 3 << 10;
+
+ QTest::newRow("data3") << testString << expectedBreakPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Doing TEST, doing another test."));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 31;
+
+ QTest::newRow("data4") << testString << expectedBreakPositions;
+ }
+}
+
+void tst_QTextBoundaryFinder::sentenceBoundaries_manual()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ QVERIFY(expectedBreakPositions.size() >= 2);
+ QList<int> expectedStartPositions = expectedBreakPositions; expectedStartPositions.removeLast();
+ QList<int> expectedEndPositions = expectedBreakPositions; expectedEndPositions.removeFirst();
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Sentence);
+ doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Sentence, QTextBoundaryFinder::StartOfItem);
+ doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Sentence, QTextBoundaryFinder::EndOfItem);
+}
+
+void tst_QTextBoundaryFinder::lineBoundaries_manual_data()
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int> >("expectedBreakPositions");
+ QTest::addColumn<QList<int> >("expectedMandatoryBreakPositions");
+
+ {
+ QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
+ QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
+ expectedBreakPositions << 0 << 4 << 8 << 14 << 18 << 22 << 26;
+ expectedMandatoryBreakPositions << 0 << 14 << 26;
+
+ QTest::newRow("data1") << testString << expectedBreakPositions
+ << expectedMandatoryBreakPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Diga-nos qualé a sua opinião"));
+ QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
+ expectedBreakPositions << 0 << 5 << 9 << 15 << 17 << 21 << 28;
+ expectedMandatoryBreakPositions << 0 << 28;
+
+ QTest::newRow("data2") << testString << expectedBreakPositions
+ << expectedMandatoryBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x000D), QChar(0x0308), QChar(0x000A), QChar(0x000A), QChar(0x0020) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
+ expectedBreakPositions << 0 << 1 << 3 << 4 << 5;
+ expectedMandatoryBreakPositions << 0 << 1 << 3 << 4 << 5;
+
+ QTest::newRow("x(CR)+(FE)x(LF)+(LF)+(SP)+") << testString << expectedBreakPositions
+ << expectedMandatoryBreakPositions;
+ }
+ {
+ QChar s[] = { QChar(0x000A), QChar(0x2E80), QChar(0x0308), QChar(0x0023), QChar(0x0023) };
+ QString testString(s, sizeof(s)/sizeof(QChar));
+ QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
+ expectedBreakPositions << 0 << 1 << 3 << 5;
+ expectedMandatoryBreakPositions << 0 << 1 << 5;
+
+ QTest::newRow("x(LF)+(ID)x(CM)+(AL)x(AL)+") << testString << expectedBreakPositions
+ << expectedMandatoryBreakPositions;
+ }
+ {
+ QChar s[] = { QChar(0x000A), QChar(0x0308), QChar(0x0023), QChar(0x0023) };
+ QString testString(s, sizeof(s)/sizeof(QChar));
+ QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
+ expectedBreakPositions << 0 << 1 << 4;
+ expectedMandatoryBreakPositions << 0 << 1 << 4;
+
+ QTest::newRow("x(LF)+(CM)x(AL)x(AL)+") << testString << expectedBreakPositions
+ << expectedMandatoryBreakPositions;
+ }
+
+ {
+ QChar s[] = { QChar(0x0061), QChar(0x00AD), QChar(0x0062), QChar(0x0009), QChar(0x0063), QChar(0x0064) };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
+ expectedBreakPositions << 0 << 2 << 4 << 6;
+ expectedMandatoryBreakPositions << 0 << 6;
+
+ QTest::newRow("x(AL)x(BA)+(AL)x(BA)+(AL)x(AL)+") << testString << expectedBreakPositions
+ << expectedMandatoryBreakPositions;
+ }
+}
+
+void tst_QTextBoundaryFinder::lineBoundaries_manual()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+ QFETCH(QList<int>, expectedMandatoryBreakPositions);
+
+ QVERIFY(expectedMandatoryBreakPositions.size() >= 2);
+ QList<int> expectedStartPositions = expectedMandatoryBreakPositions; expectedStartPositions.removeLast();
+ QList<int> expectedEndPositions = expectedMandatoryBreakPositions; expectedEndPositions.removeFirst();
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
+ doTestData(testString, expectedMandatoryBreakPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::MandatoryBreak);
+ doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::StartOfItem);
+ doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::EndOfItem);
+}
+
+Q_DECLARE_METATYPE(QTextBoundaryFinder)
+
+void tst_QTextBoundaryFinder::emptyText_data()
+{
+ QTest::addColumn<QTextBoundaryFinder>("boundaryFinder");
+
+ QString empty;
+ QString notEmpty(QLatin1String("not empty"));
+ uchar attrs[11];
+
+ QTextBoundaryFinder invalidFinder(QTextBoundaryFinder::Word, empty);
+ QTest::newRow("empty1") << invalidFinder;
+ QTextBoundaryFinder finder(invalidFinder);
+ QTest::newRow("empty2") << finder;
+ finder = QTextBoundaryFinder(QTextBoundaryFinder::Grapheme, notEmpty);
+ finder = invalidFinder;
+ QTest::newRow("empty3") << finder;
+ QTest::newRow("empty4") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, 0, 0);
+ QTest::newRow("empty5") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, attrs, 11);
+}
+
+void tst_QTextBoundaryFinder::emptyText()
+{
+ QFETCH(QTextBoundaryFinder, boundaryFinder);
+
+ QCOMPARE(boundaryFinder.position(), 0);
+ QCOMPARE(boundaryFinder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
+
+ boundaryFinder.toNextBoundary();
+ QCOMPARE(boundaryFinder.position(), -1);
+ QCOMPARE(boundaryFinder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
+}
+
+void tst_QTextBoundaryFinder::fastConstructor()
+{
+ QString text("Hello World");
+ QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text.constData(), text.size(), /*buffer*/0, /*buffer size*/0);
+
+ QCOMPARE(finder.position(), 0);
+ QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem);
+
+ finder.toNextBoundary();
+ QCOMPARE(finder.position(), 5);
+ QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem);
+
+ finder.toNextBoundary();
+ QCOMPARE(finder.position(), 6);
+ QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem);
+
+ finder.toNextBoundary();
+ QCOMPARE(finder.position(), text.size());
+ QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem);
+
+ finder.toNextBoundary();
+ QCOMPARE(finder.position(), -1);
+ QCOMPARE(finder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
+}
+
+void tst_QTextBoundaryFinder::assignmentOperator()
+{
+ QString text(QLatin1String("Hello World"));
+
+ QTextBoundaryFinder invalidFinder;
+ QVERIFY(!invalidFinder.isValid());
+ QCOMPARE(invalidFinder.string(), QString());
+
+ QTextBoundaryFinder validFinder(QTextBoundaryFinder::Word, text);
+ QVERIFY(validFinder.isValid());
+ QCOMPARE(validFinder.string(), text);
+
+ QTextBoundaryFinder finder(QTextBoundaryFinder::Line, QLatin1String("dummy"));
+ QVERIFY(finder.isValid());
+
+ finder = invalidFinder;
+ QVERIFY(!finder.isValid());
+ QCOMPARE(finder.string(), QString());
+
+ finder = validFinder;
+ QVERIFY(finder.isValid());
+ QCOMPARE(finder.string(), text);
+}
+
+void tst_QTextBoundaryFinder::isAtSoftHyphen_data()
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int> >("expectedBreakPositions");
+ QTest::addColumn<QList<int> >("expectedSoftHyphenPositions");
+
+ {
+ QString testString = QString::fromUtf8("I a-m break-able");
+ testString.replace(QLatin1Char('-'), QChar(QChar::SoftHyphen));
+ QList<int> expectedBreakPositions, expectedSoftHyphenPositions;
+ expectedBreakPositions << 0 << 2 << 4 << 6 << 12 << 16;
+ expectedSoftHyphenPositions << 4 << 12;
+
+ QTest::newRow("Soft Hyphen") << testString << expectedBreakPositions
+ << expectedSoftHyphenPositions;
+ }
+}
+
+void tst_QTextBoundaryFinder::isAtSoftHyphen()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+ QFETCH(QList<int>, expectedSoftHyphenPositions);
+
+ doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
+ doTestData(testString, expectedSoftHyphenPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::SoftHyphen);
+}
+
+QTEST_MAIN(tst_QTextBoundaryFinder)
+#include "tst_qtextboundaryfinder.moc"
diff --git a/tests/auto/corelib/text/qunicodetools/CMakeLists.txt b/tests/auto/corelib/text/qunicodetools/CMakeLists.txt
new file mode 100644
index 0000000000..fe7d8e35e2
--- /dev/null
+++ b/tests/auto/corelib/text/qunicodetools/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qunicodetools Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qunicodetools LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qunicodetools
+ SOURCES
+ tst_qunicodetools.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
diff --git a/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp b/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp
new file mode 100644
index 0000000000..774c01c73b
--- /dev/null
+++ b/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp
@@ -0,0 +1,199 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qchar.h>
+#include <qfile.h>
+#include <qstringlist.h>
+#include <private/qunicodetables_p.h>
+#include <private/qunicodetools_p.h>
+
+class tst_QUnicodeTools : public QObject
+{
+ Q_OBJECT
+private slots:
+ void lineBreakClass();
+ void graphemeBreakClass_data();
+ void graphemeBreakClass();
+ void wordBreakClass_data();
+ void wordBreakClass();
+ void sentenceBreakClass_data();
+ void sentenceBreakClass();
+};
+
+void tst_QUnicodeTools::lineBreakClass()
+{
+ QVERIFY(QUnicodeTables::lineBreakClass(0x0029) == QUnicodeTables::LineBreak_CP);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x0041) == QUnicodeTables::LineBreak_AL);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x0033) == QUnicodeTables::LineBreak_NU);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x00ad) == QUnicodeTables::LineBreak_BA);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x05d0) == QUnicodeTables::LineBreak_HL);
+ QVERIFY(QUnicodeTables::lineBreakClass(0xfffc) == QUnicodeTables::LineBreak_CB);
+ QVERIFY(QUnicodeTables::lineBreakClass(0xe0164) == QUnicodeTables::LineBreak_CM);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x2f9a4) == QUnicodeTables::LineBreak_ID);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x10000) == QUnicodeTables::LineBreak_AL);
+ QVERIFY(QUnicodeTables::lineBreakClass(0x1f1e6) == QUnicodeTables::LineBreak_RI);
+
+ // mapped to AL:
+ QVERIFY(QUnicodeTables::lineBreakClass(0xfffd) == QUnicodeTables::LineBreak_AL); // AI -> AL
+ QVERIFY(QUnicodeTables::lineBreakClass(0x100000) == QUnicodeTables::LineBreak_AL); // XX -> AL
+}
+
+static void verifyCharClassPattern(QString str, qulonglong pattern,
+ QUnicodeTools::CharAttributeOptions type)
+{
+ QUnicodeTools::ScriptItemArray scriptItems;
+ QUnicodeTools::initScripts(str, &scriptItems);
+ QCharAttributes cleared;
+ memset(&cleared, 0, sizeof(QCharAttributes));
+ QList<QCharAttributes> attributes(str.size() + 1, cleared);
+ QUnicodeTools::initCharAttributes(str, scriptItems.data(), scriptItems.size(),
+ attributes.data(), type);
+
+ qulonglong bit = 1ull << str.size();
+ Q_ASSERT(str.size() < std::numeric_limits<decltype(bit)>::digits);
+ for (qsizetype i = 0; i < str.size(); ++i) {
+ bit >>= 1;
+ bool test = pattern & bit;
+ bool isSet = false;
+ switch (type) {
+ case QUnicodeTools::GraphemeBreaks:
+ isSet = attributes[i].graphemeBoundary;
+ break;
+ case QUnicodeTools::WordBreaks:
+ isSet = attributes[i].wordBreak;
+ break;
+ case QUnicodeTools::SentenceBreaks:
+ isSet = attributes[i].sentenceBoundary;
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ };
+ QVERIFY2(isSet == test,
+ qPrintable(QString("Character #%1: 0x%2, isSet: %3")
+ .arg(i).arg(str[i].unicode(), 0, 16).arg(isSet)));
+ }
+}
+
+void tst_QUnicodeTools::graphemeBreakClass_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<int>("pattern");
+
+ // A grapheme cluster is a set of unicode code points that is
+ // seen as a single character.
+ // The pattern has one bit per code point.
+ // A pattern bit is set whenever a new grapheme cluster begins.
+ // A pattern bit is cleared for every code point that modifies
+ // the current graphene cluster.
+
+ QTest::addRow("g and combining diaeresis")
+ << u8"g\u0308"
+ << 0b10;
+ QTest::addRow("hangul gag single")
+ << u8"\uAC01"
+ << 0b1;
+ QTest::addRow("hangul gag cluster")
+ << u8"\u1100\u1161\u11A8"
+ << 0b100;
+ QTest::addRow("thai ko")
+ << u8"\u0E01"
+ << 0b1;
+ QTest::addRow("tamil ni")
+ << u8"\u0BA8\u0BBF"
+ << 0b10;
+ QTest::addRow("thai e")
+ << u8"\u0E40"
+ << 0b1;
+ QTest::addRow("thai kam")
+ << u8"\u0E01\u0E33"
+ << 0b10;
+ QTest::addRow("devanagari ssi")
+ << u8"\u0937\u093F"
+ << 0b10;
+ QTest::addRow("thai am")
+ << u8"\u0E33"
+ << 0b1;
+ QTest::addRow("devanagari ssa")
+ << u8"\u0937"
+ << 0b1;
+ QTest::addRow("devanagari i")
+ << u8"\u093F"
+ << 0b1;
+ QTest::addRow("devanagari kshi")
+ << u8"\u0915\u094D\u0937\u093F"
+ << 0b1000;
+}
+
+void tst_QUnicodeTools::graphemeBreakClass()
+{
+ QFETCH(QString, str);
+ QFETCH(int, pattern);
+
+ verifyCharClassPattern(str, pattern, QUnicodeTools::GraphemeBreaks);
+}
+
+void tst_QUnicodeTools::wordBreakClass_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<qulonglong>("pattern");
+
+ // Word boundaries are used for things like selection and whole word search.
+ // Typically they are beginning of words, whitespaces and punctuation.
+
+ QTest::addRow("two words")
+ << "two words"
+ << 0b100110000ULL;
+ // breaks at beginning of words and space
+ QTest::addRow("three words")
+ << "The quick fox"
+ << 0b1001100001100ULL;
+ // breaks at beginning of words and spaces
+ QTest::addRow("quoted")
+ << u8"The quick (\"brown\") fox"
+ << 0b10011000011'110000'111100ULL;
+ // as above plus quotes and parentesis
+ QTest::addRow("long")
+ << "The quick (\"brown\") fox can’t jump 32.3 feet, right?"
+ << 0b10011000011'110000'11110011000011000110001100011100001ULL;
+ // as above plus commma and question mark
+ // but decimal separator and apostrophes are not word breaks
+}
+
+void tst_QUnicodeTools::wordBreakClass()
+{
+ QFETCH(QString, str);
+ QFETCH(qulonglong, pattern);
+
+ verifyCharClassPattern(str, pattern, QUnicodeTools::WordBreaks);
+}
+
+void tst_QUnicodeTools::sentenceBreakClass_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::addColumn<qulonglong>("pattern");
+
+ // Sentence boundaries are at the beginning of each new sentence
+
+ QTest::addRow("one sentence")
+ << "One sentence."
+ << 0b1000000000000ULL;
+ QTest::addRow("two sentences")
+ << "One sentence. One more."
+ << 0b10000000000000100000000ULL;
+ QTest::addRow("question")
+ << "Who said \"Hey you?\" I did."
+ << 0b100000000'000000000'00100000ULL;
+}
+
+void tst_QUnicodeTools::sentenceBreakClass()
+{
+ QFETCH(QString, str);
+ QFETCH(qulonglong, pattern);
+
+ verifyCharClassPattern(str, pattern, QUnicodeTools::SentenceBreaks);
+}
+
+QTEST_APPLESS_MAIN(tst_QUnicodeTools)
+#include "tst_qunicodetools.moc"
diff --git a/tests/auto/corelib/text/shared/test_number_shared.h b/tests/auto/corelib/text/shared/test_number_shared.h
new file mode 100644
index 0000000000..e121144e7c
--- /dev/null
+++ b/tests/auto/corelib/text/shared/test_number_shared.h
@@ -0,0 +1,105 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <limits>
+#include <QtCore/qstring.h>
+#include <QtCore/qlocale.h>
+
+struct NumberDoubleTestData
+{
+ double d;
+ char f;
+ int p;
+ QLatin1String expected;
+ QLatin1String optTitle = {}; // optional
+ // Tests with same (f, p, expected) should use optTitle to avoid duplicate data tags.
+};
+
+template<typename Fun>
+inline void add_number_double_shared_data(Fun addTestRowFunction)
+{
+ constexpr double nan = std::numeric_limits<double>::quiet_NaN();
+ constexpr double inf = std::numeric_limits<double>::infinity();
+ const static NumberDoubleTestData data[] {
+ { 0.0, 'f', 0, QLatin1String("0") },
+ { 0.0, 'e', 0, QLatin1String("0e+00") },
+ { 0.0, 'e', 1, QLatin1String("0.0e+00") },
+ { 0.0001, 'f', 0, QLatin1String("0"), QLatin1String("0(.0001)") },
+ { 0.1234, 'f', 5, QLatin1String("0.12340") },
+ { -0.1234, 'f', 5, QLatin1String("-0.12340") },
+ { 0.0000000314, 'f', 12, QLatin1String("0.000000031400") },
+ { -0.0000000314, 'f', 12, QLatin1String("-0.000000031400") },
+ { -100000, 'f', 15, QLatin1String("-100000.000000000000000") },
+ { 0.5 + qSqrt(1.25), 'f', 15, QLatin1String("1.618033988749895") },
+ { 0.5 + qSqrt(1.25), 'e', 15, QLatin1String("1.618033988749895e+00") },
+ { 1.7976931348623157e+308, 'f', 120,
+ QLatin1String(
+ "17976931348623157081452742373170435679807056752584499659891747680315726078002853"
+ "87605895586327668781715404589535143824642343213268894641827684675467035375169860"
+ "49910576551282076245490090389328944075868508455133942304583236903222948165808559"
+ "332123348274797826204144723168738177180919299881250404026184124858368."
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000"),
+ QLatin1String("Big number, high precision") },
+ { 1.0, 'f', 350,
+ QLatin1String(
+ "1.0000000000000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000"),
+ QLatin1String("Very high precision 1") },
+ { 1.0e-308, 'f', 350,
+ QLatin1String("0."
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000000000000"
+ "000000000000999999999999999909326625337248461995470489"),
+ QLatin1String("Very small number, very high precision") },
+ { std::numeric_limits<double>::epsilon(), 'g', 10, QLatin1String("2.220446049e-16") },
+ { 0.0001, 'e', 1, QLatin1String("1.0e-04") },
+ { 1e8, 'e', 1, QLatin1String("1.0e+08") },
+ { -1e8, 'e', 1, QLatin1String("-1.0e+08") },
+ { 1.1e-8, 'e', 6, QLatin1String("1.100000e-08") },
+ { -1.1e-8, 'e', 6, QLatin1String("-1.100000e-08") },
+ { 1.1e+8, 'e', 6, QLatin1String("1.100000e+08") },
+ { -1.1e+8, 'e', 6, QLatin1String("-1.100000e+08") },
+ { 100000, 'f', 0, QLatin1String("100000") },
+ // Increasingly small fraction, test how/when 'g' switches to scientific notation:
+ { 0.001, 'g', 6, QLatin1String("0.001") },
+ { 0.0001, 'g', 6, QLatin1String("0.0001") },
+ { 0.00001, 'g', 6, QLatin1String("1e-05") },
+ { 0.000001, 'g', 6, QLatin1String("1e-06") },
+ // FloatingPointShortest is relied upon by various facilities:
+ { 1.0, 'g', QLocale::FloatingPointShortest, QLatin1String("1") },
+ { 0.01, 'g', QLocale::FloatingPointShortest, QLatin1String("0.01") },
+ { 123.456, 'g', QLocale::FloatingPointShortest, QLatin1String("123.456") },
+ { 12.12, 'g', QLocale::FloatingPointShortest, QLatin1String("12.12") },
+ { 0.000001, 'g', QLocale::FloatingPointShortest, QLatin1String("1e-06") },
+ { 100000, 'g', QLocale::FloatingPointShortest, QLatin1String("1e+05") },
+ // inf and nan testing:
+ { inf, 'g', QLocale::FloatingPointShortest, QLatin1String("inf") },
+ { -inf, 'g', QLocale::FloatingPointShortest, QLatin1String("-inf") },
+ { nan, 'g', QLocale::FloatingPointShortest, QLatin1String("nan") },
+ { inf, 'f', 15, QLatin1String("inf") },
+ { -inf, 'f', 15, QLatin1String("-inf") },
+ { nan, 'f', 15, QLatin1String("nan") },
+ { inf, 'e', 2, QLatin1String("inf") },
+ { -inf, 'e', 2, QLatin1String("-inf") },
+ { nan, 'e', 2, QLatin1String("nan") },
+ // Negative precision (except QLocale::F.P.Shortest) defaults to 6:
+ { 0.001, 'f', -50, QLatin1String("0.001000") },
+ { 0.0001, 'f', -62, QLatin1String("0.000100") },
+ { 0.00001, 'f', -11, QLatin1String("0.000010") },
+ { 0.000001, 'f', -41, QLatin1String("0.000001") },
+ { 0.0000001, 'f', -21, QLatin1String("0.000000") },
+ // Some rounding tests
+ { 10.5, 'f', 0, QLatin1String("11") },
+ { 12.05, 'f', 1, QLatin1String("12.1") },
+ { 14.500000000000001, 'f', 0, QLatin1String("15") },
+ { 16.5000000000000001, 'f', 0, QLatin1String("17") },
+ };
+ for (auto datum : data)
+ addTestRowFunction(datum);
+}
diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt
new file mode 100644
index 0000000000..68110b652b
--- /dev/null
+++ b/tests/auto/corelib/thread/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(QT_BUILD_WASM_BATCHED_TESTS) # not all tests currently work in WebAssembly
+ add_subdirectory(qatomicint)
+ add_subdirectory(qatomicinteger)
+ add_subdirectory(qatomicpointer)
+ add_subdirectory(qfuturesynchronizer)
+ add_subdirectory(qmutexlocker)
+ add_subdirectory(qreadlocker)
+ add_subdirectory(qresultstore)
+ add_subdirectory(qwritelocker)
+ return()
+endif()
+
+if(QT_FEATURE_thread)
+ add_subdirectory(qatomicint)
+ add_subdirectory(qatomicinteger)
+ add_subdirectory(qatomicpointer)
+ add_subdirectory(qresultstore)
+ if(QT_FEATURE_concurrent AND NOT INTEGRITY)
+ add_subdirectory(qfuture)
+ endif()
+ add_subdirectory(qfuturesynchronizer)
+ add_subdirectory(qmutex)
+ add_subdirectory(qmutexlocker)
+ add_subdirectory(qreadlocker)
+ add_subdirectory(qreadwritelock)
+ add_subdirectory(qsemaphore)
+ # QTBUG-85364
+ if(NOT CMAKE_CROSSCOMPILING)
+ add_subdirectory(qthread)
+ endif()
+ add_subdirectory(qthreadonce)
+ add_subdirectory(qthreadpool)
+ add_subdirectory(qthreadstorage)
+ add_subdirectory(qwaitcondition)
+ add_subdirectory(qwritelocker)
+ if(NOT INTEGRITY)
+ add_subdirectory(qpromise)
+ endif()
+endif()
+
+# QTBUG-87431
+if(TARGET Qt::Concurrent AND NOT INTEGRITY)
+ add_subdirectory(qfuturewatcher)
+endif()
diff --git a/tests/auto/corelib/thread/qatomicint/CMakeLists.txt b/tests/auto/corelib/thread/qatomicint/CMakeLists.txt
new file mode 100644
index 0000000000..239f3cce87
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicint/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicint Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicint LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicint
+ SOURCES
+ tst_qatomicint.cpp
+)
diff --git a/tests/auto/corelib/thread/qatomicint/qatomicint.pro b/tests/auto/corelib/thread/qatomicint/qatomicint.pro
deleted file mode 100644
index 89ac465e81..0000000000
--- a/tests/auto/corelib/thread/qatomicint/qatomicint.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qatomicint
-QT = core testlib
-SOURCES = tst_qatomicint.cpp
diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
index cc197cabba..63cb494c11 100644
--- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
+++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
@@ -1,36 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QAtomicInt>
#include <QCoreApplication>
+#include <QElapsedTimer>
#include <limits.h>
@@ -84,7 +60,7 @@ private:
};
template <int I>
-static inline void assemblyMarker(void *ptr = 0)
+static inline void assemblyMarker(void *ptr = nullptr)
{
puts((char *)ptr + I);
}
@@ -104,12 +80,12 @@ static void warningFreeHelperTemplate()
assemblyMarker<1>(&i);
// the loads sometimes generate no assembly output
- i.load();
+ i.loadRelaxed();
assemblyMarker<11>(&i);
i.loadAcquire();
assemblyMarker<12>(&i);
- i.store(newValue);
+ i.storeRelaxed(newValue);
assemblyMarker<21>(&i);
i.storeRelease(newValue);
assemblyMarker<22>(&i);
@@ -153,17 +129,11 @@ template <bool> inline void booleanHelper()
template <typename Atomic>
static void constexprFunctionsHelperTemplate()
{
-#ifdef Q_COMPILER_CONSTEXPR
// this is a compile-time test only
- booleanHelper<Atomic::isReferenceCountingNative()>();
booleanHelper<Atomic::isReferenceCountingWaitFree()>();
- booleanHelper<Atomic::isTestAndSetNative()>();
booleanHelper<Atomic::isTestAndSetWaitFree()>();
- booleanHelper<Atomic::isFetchAndStoreNative()>();
booleanHelper<Atomic::isFetchAndStoreWaitFree()>();
- booleanHelper<Atomic::isFetchAndAddNative()>();
booleanHelper<Atomic::isFetchAndAddWaitFree()>();
-#endif
}
void tst_QAtomicInt::warningFreeHelper()
@@ -176,10 +146,8 @@ void tst_QAtomicInt::warningFreeHelper()
warningFreeHelperTemplate<unsigned int, QBasicAtomicInteger<unsigned int> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<int> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<unsigned int> >();
-# ifdef Q_COMPILER_UNICODE_STRINGS
warningFreeHelperTemplate<qint16, QBasicAtomicInteger<char32_t> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<char32_t> >();
-# endif
// pointer-sized integers are always supported:
warningFreeHelperTemplate<int, QBasicAtomicInteger<qptrdiff> >();
@@ -193,25 +161,19 @@ void tst_QAtomicInt::warningFreeHelper()
constexprFunctionsHelperTemplate<QBasicAtomicInteger<long int> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<unsigned long int> >();
-#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
warningFreeHelperTemplate<qint16, QBasicAtomicInteger<qint16> >();
warningFreeHelperTemplate<quint16, QBasicAtomicInteger<quint16> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<qint16> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<quint16> >();
-# ifdef Q_COMPILER_UNICODE_STRINGS
warningFreeHelperTemplate<qint16, QBasicAtomicInteger<char16_t> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<char16_t> >();
-# endif
-#endif
-#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
warningFreeHelperTemplate<char, QBasicAtomicInteger<char> >();
warningFreeHelperTemplate<signed char, QBasicAtomicInteger<signed char> >();
warningFreeHelperTemplate<unsigned char, QBasicAtomicInteger<unsigned char> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<char> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<signed char> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<unsigned char> >();
-#endif
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
#if !defined(__i386__) || (defined(Q_CC_GNU) && defined(__OPTIMIZE__))
@@ -236,28 +198,16 @@ template <typename T> struct TypeInStruct { T type; };
void tst_QAtomicInt::alignment()
{
-#ifdef Q_ALIGNOF
- // this will cause a build error if the alignment isn't the same
- char dummy1[Q_ALIGNOF(QBasicAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1];
- char dummy2[Q_ALIGNOF(QAtomicInt) == Q_ALIGNOF(TypeInStruct<int>) ? 1 : -1];
- (void)dummy1; (void)dummy2;
+ static_assert(alignof(QBasicAtomicInt) == alignof(TypeInStruct<int>));
+ static_assert(alignof(QBasicAtomicInt) == alignof(TypeInStruct<int>));
-#ifdef Q_ATOMIC_INT32_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<int>), Q_ALIGNOF(TypeInStruct<int>));
-#endif
-
-#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<short>), Q_ALIGNOF(TypeInStruct<short>));
-#endif
-
-#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<char>), Q_ALIGNOF(TypeInStruct<char>));
-#endif
-
-#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
- QCOMPARE(Q_ALIGNOF(QBasicAtomicInteger<qlonglong>), Q_ALIGNOF(TypeInStruct<qlonglong>));
-#endif
+ QCOMPARE(alignof(QBasicAtomicInteger<int>), alignof(TypeInStruct<int>));
+ QCOMPARE(alignof(QBasicAtomicInteger<short>), alignof(TypeInStruct<short>));
+ QCOMPARE(alignof(QBasicAtomicInteger<char>), alignof(TypeInStruct<char>));
+#if !defined(Q_PROCESSOR_X86_32) && defined(Q_ATOMIC_INT64_IS_SUPPORTED)
+ // The alignment is different on x86_32
+ QCOMPARE(alignof(QBasicAtomicInteger<qlonglong>), alignof(TypeInStruct<qlonglong>));
#endif
}
@@ -281,9 +231,9 @@ void tst_QAtomicInt::constructor()
{
QFETCH(int, value);
QAtomicInt atomic1(value);
- QCOMPARE(atomic1.load(), value);
+ QCOMPARE(atomic1.loadRelaxed(), value);
QAtomicInt atomic2 = value;
- QCOMPARE(atomic2.load(), value);
+ QCOMPARE(atomic2.loadRelaxed(), value);
}
void tst_QAtomicInt::copy_constructor_data()
@@ -293,16 +243,16 @@ void tst_QAtomicInt::copy_constructor()
{
QFETCH(int, value);
QAtomicInt atomic1(value);
- QCOMPARE(atomic1.load(), value);
+ QCOMPARE(atomic1.loadRelaxed(), value);
QAtomicInt atomic2(atomic1);
- QCOMPARE(atomic2.load(), value);
+ QCOMPARE(atomic2.loadRelaxed(), value);
QAtomicInt atomic3 = atomic1;
- QCOMPARE(atomic3.load(), value);
+ QCOMPARE(atomic3.loadRelaxed(), value);
QAtomicInt atomic4(atomic2);
- QCOMPARE(atomic4.load(), value);
+ QCOMPARE(atomic4.loadRelaxed(), value);
QAtomicInt atomic5 = atomic2;
- QCOMPARE(atomic5.load(), value);
+ QCOMPARE(atomic5.loadRelaxed(), value);
}
void tst_QAtomicInt::assignment_operator_data()
@@ -326,13 +276,13 @@ void tst_QAtomicInt::assignment_operator()
{
QAtomicInt atomic1 = value;
atomic1 = newval;
- QCOMPARE(atomic1.load(), newval);
+ QCOMPARE(atomic1.loadRelaxed(), newval);
atomic1 = value;
- QCOMPARE(atomic1.load(), value);
+ QCOMPARE(atomic1.loadRelaxed(), value);
QAtomicInt atomic2 = newval;
atomic1 = atomic2;
- QCOMPARE(atomic1.load(), atomic2.load());
+ QCOMPARE(atomic1.loadRelaxed(), atomic2.loadRelaxed());
}
}
@@ -400,7 +350,7 @@ void tst_QAtomicInt::ref()
QFETCH(int, value);
QAtomicInt x = value;
QTEST(x.ref() ? 1 : 0, "result");
- QTEST(x.load(), "expected");
+ QTEST(x.loadRelaxed(), "expected");
}
void tst_QAtomicInt::deref_data()
@@ -419,7 +369,7 @@ void tst_QAtomicInt::deref()
QFETCH(int, value);
QAtomicInt x = value;
QTEST(x.deref() ? 1 : 0, "result");
- QTEST(x.load(), "expected");
+ QTEST(x.loadRelaxed(), "expected");
}
void tst_QAtomicInt::isTestAndSetNative()
@@ -531,7 +481,6 @@ void tst_QAtomicInt::testAndSet()
QTEST(atomic.testAndSetOrdered(expected, newval), "result");
}
-#ifdef Q_ATOMIC_INT32_IS_SUPPORTED
QFETCH(bool, result);
// the new implementation has the version that loads the current value
@@ -566,7 +515,6 @@ void tst_QAtomicInt::testAndSet()
if (!result)
QCOMPARE(currentval, value);
}
-#endif
}
void tst_QAtomicInt::isFetchAndStoreNative()
@@ -635,25 +583,25 @@ void tst_QAtomicInt::fetchAndStore()
{
QAtomicInt atomic = value;
QCOMPARE(atomic.fetchAndStoreRelaxed(newval), value);
- QCOMPARE(atomic.load(), newval);
+ QCOMPARE(atomic.loadRelaxed(), newval);
}
{
QAtomicInt atomic = value;
QCOMPARE(atomic.fetchAndStoreAcquire(newval), value);
- QCOMPARE(atomic.load(), newval);
+ QCOMPARE(atomic.loadRelaxed(), newval);
}
{
QAtomicInt atomic = value;
QCOMPARE(atomic.fetchAndStoreRelease(newval), value);
- QCOMPARE(atomic.load(), newval);
+ QCOMPARE(atomic.loadRelaxed(), newval);
}
{
QAtomicInt atomic = value;
QCOMPARE(atomic.fetchAndStoreOrdered(newval), value);
- QCOMPARE(atomic.load(), newval);
+ QCOMPARE(atomic.loadRelaxed(), newval);
}
}
@@ -728,7 +676,6 @@ void tst_QAtomicInt::fetchAndAdd_data()
QTest::newRow("7272+2181") << 7272 << 2181;
QTest::newRow("0+-1") << 0 << -1;
- QTest::newRow("1+0") << 1 << 0;
QTest::newRow("1+-2") << 1 << -2;
QTest::newRow("2+-1") << 2 << -1;
QTest::newRow("10+-21") << 10 << -21;
@@ -744,7 +691,6 @@ void tst_QAtomicInt::fetchAndAdd_data()
QTest::newRow("5451+-4362") << 5451 << -4362;
QTest::newRow("7272+-2181") << 7272 << -2181;
- QTest::newRow("0+1") << 0 << 1;
QTest::newRow("-1+0") << -1 << 0;
QTest::newRow("-1+2") << -1 << 2;
QTest::newRow("-2+1") << -2 << 1;
@@ -772,28 +718,28 @@ void tst_QAtomicInt::fetchAndAdd()
QAtomicInt atomic = value1;
result = atomic.fetchAndAddRelaxed(value2);
QCOMPARE(result, value1);
- QCOMPARE(atomic.load(), value1 + value2);
+ QCOMPARE(atomic.loadRelaxed(), value1 + value2);
}
{
QAtomicInt atomic = value1;
result = atomic.fetchAndAddAcquire(value2);
QCOMPARE(result, value1);
- QCOMPARE(atomic.load(), value1 + value2);
+ QCOMPARE(atomic.loadRelaxed(), value1 + value2);
}
{
QAtomicInt atomic = value1;
result = atomic.fetchAndAddRelease(value2);
QCOMPARE(result, value1);
- QCOMPARE(atomic.load(), value1 + value2);
+ QCOMPARE(atomic.loadRelaxed(), value1 + value2);
}
{
QAtomicInt atomic = value1;
result = atomic.fetchAndAddOrdered(value2);
QCOMPARE(result, value1);
- QCOMPARE(atomic.load(), value1 + value2);
+ QCOMPARE(atomic.loadRelaxed(), value1 + value2);
}
}
@@ -844,21 +790,24 @@ void tst_QAtomicInt::operators()
QCOMPARE(int(atomic), x);
QCOMPARE(int(atomic), 0x13);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
x = (atomic ^= atomic);
QCOMPARE(int(atomic), x);
QCOMPARE(int(atomic), 0);
+QT_WARNING_POP
}
void tst_QAtomicInt::testAndSet_loop()
{
- QTime stopWatch;
+ QElapsedTimer stopWatch;
stopWatch.start();
int iterations = 10000000;
QAtomicInt val=0;
for (int i = 0; i < iterations; ++i) {
- int v = val.load();
+ int v = val.loadRelaxed();
QVERIFY(val.testAndSetRelaxed(v, v+1));
if ((i % 1000) == 999) {
if (stopWatch.elapsed() > 60 * 1000) {
@@ -881,14 +830,14 @@ void tst_QAtomicInt::fetchAndAdd_loop()
QAtomicInt val=0;
for (int i = 0; i < iterations; ++i) {
const int prev = val.fetchAndAddRelaxed(1);
- QCOMPARE(prev, val.load() -1);
+ QCOMPARE(prev, val.loadRelaxed() -1);
}
}
class FetchAndAddThread : public QThread
{
public:
- void run()
+ void run() override
{
for (int i = 0; i < iterations; ++i)
@@ -919,7 +868,7 @@ void tst_QAtomicInt::fetchAndAdd_threadedLoop()
t1.wait();
t2.wait();
- QCOMPARE(val.load(), 0);
+ QCOMPARE(val.loadRelaxed(), 0);
}
QTEST_MAIN(tst_QAtomicInt)
diff --git a/tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt
new file mode 100644
index 0000000000..03a6323a1f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(char)
+add_subdirectory(char16_t)
+add_subdirectory(char32_t)
+add_subdirectory(int)
+add_subdirectory(long)
+add_subdirectory(qlonglong)
+add_subdirectory(qptrdiff)
+add_subdirectory(quintptr)
+add_subdirectory(qulonglong)
+add_subdirectory(schar)
+add_subdirectory(short)
+add_subdirectory(uchar)
+add_subdirectory(uint)
+add_subdirectory(ulong)
+add_subdirectory(ushort)
+add_subdirectory(wchar_t)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt
new file mode 100644
index 0000000000..882a9298f6
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_char Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_char LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_char
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=char
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_char
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/char/char.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/char/char.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt
new file mode 100644
index 0000000000..8e53b59689
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char16_t/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_char16_t Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_char16_t LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_char16_t
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=char16_t
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_char16_t
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt
new file mode 100644
index 0000000000..5881d475f4
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char32_t/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_char32_t Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_char32_t LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_char32_t
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=char32_t
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_char32_t
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt
new file mode 100644
index 0000000000..0915e77a8d
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/int/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_int Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_int LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_int
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=int
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_int
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/int/int.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/int/int.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt
new file mode 100644
index 0000000000..adf6638bfa
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/long/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_long Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_long LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_long
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=long
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_long
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/long/long.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/long/long.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
deleted file mode 100644
index f1030d41ef..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
+++ /dev/null
@@ -1,11 +0,0 @@
-# Get our build type from the directory name
-TYPE = $$basename(_PRO_FILE_PWD_)
-dn = $$dirname(_PRO_FILE_PWD_)
-FORCE = $$basename(dn)
-suffix = $$TYPE
-
-CONFIG += testcase
-QT = core testlib
-TARGET = tst_qatomicinteger_$$lower($$suffix)
-SOURCES = $$PWD/tst_qatomicinteger.cpp
-DEFINES += QATOMIC_TEST_TYPE=$$TYPE tst_QAtomicIntegerXX=tst_QAtomicInteger_$$suffix
diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
deleted file mode 100644
index 09458bd9c3..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- char \
- char16_t \
- char32_t \
- int \
- long \
- qlonglong \
- qptrdiff \
- quintptr \
- qulonglong \
- schar \
- short \
- uchar \
- uint \
- ulong \
- ushort \
- wchar_t \
diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt
new file mode 100644
index 0000000000..2ec977d7cb
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qlonglong/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_qlonglong Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_qlonglong LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_qlonglong
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=qlonglong
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_qlonglong
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt
new file mode 100644
index 0000000000..a2450931d5
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_qptrdiff Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_qptrdiff LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_qptrdiff
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=qptrdiff
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_qptrdiff
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt
new file mode 100644
index 0000000000..98302b5d07
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/quintptr/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_quintptr Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_quintptr LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_quintptr
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=quintptr
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_quintptr
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt
new file mode 100644
index 0000000000..13acfc3e2b
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qulonglong/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_qulonglong Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_qulonglong LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_qulonglong
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=qulonglong
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_qulonglong
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt
new file mode 100644
index 0000000000..127f752cc2
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/schar/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_schar Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_schar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_schar
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=schar
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_schar
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt
new file mode 100644
index 0000000000..df9d2af4c3
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/short/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_short Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_short LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_short
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=short
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_short
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/short/short.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/short/short.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
index 32e5b8ee56..d1a8a8f729 100644
--- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
+++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
@@ -1,62 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifdef QT_ATOMIC_FORCE_CXX11
-// We need to check if this compiler has C++11 atomics and constexpr support.
-// We can't rely on qcompilerdetection.h because it forces all of qglobal.h to
-// be included, which causes qbasicatomic.h to be included too.
-// Incomplete, but ok
-# if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1500 && (__cplusplus >= 201103L || defined(__INTEL_CXX11_MODE__))
-# elif defined(__clang__) && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
-# if !__has_feature(cxx_constexpr) || !__has_feature(cxx_atomic) || !__has_include(<atomic>)
-# undef QT_ATOMIC_FORCE_CXX11
-# endif
-# elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
-# elif defined(_MSC_VER)
- // We need MSVC 2015 because of: atomics (2012), constexpr (2015), and unrestricted unions (2015).
- // Support for constexpr is not working completely on MSVC 2015 but it's enough for the test.
-# else
-# undef QT_ATOMIC_FORCE_CXX11
-# endif
-
-# ifndef QT_ATOMIC_FORCE_CXX11
-# undef QATOMIC_TEST_TYPE
-# define QATOMIC_TEST_TYPE unsupported
-# endif
-#endif
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest>
+#include <QTest>
#include <QAtomicInt>
#include <limits>
#include <limits.h>
#include <wchar.h>
+#if !defined(Q_ATOMIC_INT8_IS_SUPPORTED)
+# error "QAtomicInteger for 8-bit types must be supported!"
+#endif
+#if !defined(Q_ATOMIC_INT16_IS_SUPPORTED)
+# error "QAtomicInteger for 16-bit types must be supported!"
+#endif
#if !defined(Q_ATOMIC_INT32_IS_SUPPORTED)
# error "QAtomicInteger for 32-bit types must be supported!"
#endif
@@ -65,35 +22,21 @@
#endif
// always supported types:
+#define TYPE_SUPPORTED_char 1
+#define TYPE_SUPPORTED_uchar 1
+#define TYPE_SUPPORTED_schar 1
+#define TYPE_SUPPORTED_short 1
+#define TYPE_SUPPORTED_ushort 1
+#define TYPE_SUPPORTED_char16_t 1
+#define TYPE_SUPPORTED_wchar_t 1
#define TYPE_SUPPORTED_int 1
#define TYPE_SUPPORTED_uint 1
#define TYPE_SUPPORTED_long 1
#define TYPE_SUPPORTED_ulong 1
#define TYPE_SUPPORTED_qptrdiff 1
#define TYPE_SUPPORTED_quintptr 1
-#if (defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__-0) > 2) \
- || (defined(WCHAR_MAX) && (WCHAR_MAX-0 > 0x10000))
-# define TYPE_SUPPORTED_wchar_t 1
-#endif
-#ifdef Q_COMPILER_UNICODE_STRINGS
-# define TYPE_SUPPORTED_char32_t 1
-#endif
+#define TYPE_SUPPORTED_char32_t 1
-#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
-# define TYPE_SUPPORTED_char 1
-# define TYPE_SUPPORTED_uchar 1
-# define TYPE_SUPPORTED_schar 1
-#endif
-#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
-# define TYPE_SUPPORTED_short 1
-# define TYPE_SUPPORTED_ushort 1
-# ifdef Q_COMPILER_UNICODE_STRINGS
-# define TYPE_SUPPORTED_char16_t 1
-# endif
-# ifndef TYPE_SUPPORTED_wchar_t
-# define TYPE_SUPPORTED_wchar_t 1
-# endif
-#endif
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
# define TYPE_SUPPORTED_qlonglong 1
# define TYPE_SUPPORTED_qulonglong 1
@@ -121,6 +64,7 @@ typedef signed char schar;
typedef TEST_TYPE Type;
typedef Type T; // shorthand
+using U = std::make_unsigned_t<T>;
enum {
TypeIsUnsigned = Type(-1) > Type(0),
TypeIsSigned = !TypeIsUnsigned
@@ -131,6 +75,8 @@ template <> struct LargeIntTemplate<true> { typedef quint64 Type; };
template <> struct LargeIntTemplate<false> { typedef qint64 Type; };
typedef LargeIntTemplate<TypeIsUnsigned>::Type LargeInt;
+namespace {
+
class tst_QAtomicIntegerXX : public QObject
{
Q_OBJECT
@@ -188,7 +134,7 @@ template <bool> inline void booleanHelper() { }
void tst_QAtomicIntegerXX::static_checks()
{
- Q_STATIC_ASSERT(sizeof(QAtomicInteger<T>) == sizeof(T));
+ static_assert(sizeof(QAtomicInteger<T>) == sizeof(T));
// statements with no effect
(void) QAtomicInteger<T>::isReferenceCountingNative();
@@ -200,17 +146,11 @@ void tst_QAtomicIntegerXX::static_checks()
(void) QAtomicInteger<T>::isFetchAndAddNative();
(void) QAtomicInteger<T>::isFetchAndAddWaitFree();
-#ifdef Q_COMPILER_CONSTEXPR
// this is a compile-time test only
- booleanHelper<QAtomicInteger<T>::isReferenceCountingNative()>();
booleanHelper<QAtomicInteger<T>::isReferenceCountingWaitFree()>();
- booleanHelper<QAtomicInteger<T>::isTestAndSetNative()>();
booleanHelper<QAtomicInteger<T>::isTestAndSetWaitFree()>();
- booleanHelper<QAtomicInteger<T>::isFetchAndStoreNative()>();
booleanHelper<QAtomicInteger<T>::isFetchAndStoreWaitFree()>();
- booleanHelper<QAtomicInteger<T>::isFetchAndAddNative()>();
booleanHelper<QAtomicInteger<T>::isFetchAndAddWaitFree()>();
-#endif
}
void tst_QAtomicIntegerXX::addData()
@@ -270,13 +210,13 @@ void tst_QAtomicIntegerXX::constructor()
QFETCH(LargeInt, value);
QAtomicInteger<T> atomic(value);
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QAtomicInteger<T> atomic2 = value;
- QCOMPARE(atomic2.load(), T(value));
+ QCOMPARE(atomic2.loadRelaxed(), T(value));
- QVERIFY(atomic.load() >= std::numeric_limits<T>::min());
- QVERIFY(atomic.load() <= std::numeric_limits<T>::max());
+ QVERIFY(atomic.loadRelaxed() >= std::numeric_limits<T>::min());
+ QVERIFY(atomic.loadRelaxed() <= std::numeric_limits<T>::max());
}
void tst_QAtomicIntegerXX::copy()
@@ -285,17 +225,17 @@ void tst_QAtomicIntegerXX::copy()
QAtomicInteger<T> atomic(value);
QAtomicInteger<T> copy(atomic);
- QCOMPARE(copy.load(), atomic.load());
+ QCOMPARE(copy.loadRelaxed(), atomic.loadRelaxed());
QAtomicInteger<T> copy2 = atomic;
- QCOMPARE(copy2.load(), atomic.load());
+ QCOMPARE(copy2.loadRelaxed(), atomic.loadRelaxed());
// move
- QAtomicInteger<T> copy3(qMove(copy));
- QCOMPARE(copy3.load(), atomic.load());
+ QAtomicInteger<T> copy3(std::move(copy));
+ QCOMPARE(copy3.loadRelaxed(), atomic.loadRelaxed());
- QAtomicInteger<T> copy4 = qMove(copy2);
- QCOMPARE(copy4.load(), atomic.load());
+ QAtomicInteger<T> copy4 = std::move(copy2);
+ QCOMPARE(copy4.loadRelaxed(), atomic.loadRelaxed());
}
void tst_QAtomicIntegerXX::assign()
@@ -305,24 +245,24 @@ void tst_QAtomicIntegerXX::assign()
QAtomicInteger<T> atomic(value);
QAtomicInteger<T> copy;
copy = atomic;
- QCOMPARE(copy.load(), atomic.load());
+ QCOMPARE(copy.loadRelaxed(), atomic.loadRelaxed());
QAtomicInteger<T> copy2;
copy2 = atomic; // operator=(const QAtomicInteger &)
- QCOMPARE(copy2.load(), atomic.load());
+ QCOMPARE(copy2.loadRelaxed(), atomic.loadRelaxed());
QAtomicInteger<T> copy2bis;
- copy2bis = atomic.load(); // operator=(T)
- QCOMPARE(copy2bis.load(), atomic.load());
+ copy2bis = atomic.loadRelaxed(); // operator=(T)
+ QCOMPARE(copy2bis.loadRelaxed(), atomic.loadRelaxed());
// move
QAtomicInteger<T> copy3;
- copy3 = qMove(copy);
- QCOMPARE(copy3.load(), atomic.load());
+ copy3 = std::move(copy);
+ QCOMPARE(copy3.loadRelaxed(), atomic.loadRelaxed());
QAtomicInteger<T> copy4;
- copy4 = qMove(copy2);
- QCOMPARE(copy4.load(), atomic.load());
+ copy4 = std::move(copy2);
+ QCOMPARE(copy4.loadRelaxed(), atomic.loadRelaxed());
}
void tst_QAtomicIntegerXX::operatorInteger()
@@ -331,7 +271,7 @@ void tst_QAtomicIntegerXX::operatorInteger()
QAtomicInteger<T> atomic(value);
T val2 = atomic;
- QCOMPARE(val2, atomic.load());
+ QCOMPARE(val2, atomic.loadRelaxed());
QCOMPARE(val2, T(value));
}
@@ -346,53 +286,39 @@ void tst_QAtomicIntegerXX::loadAcquireStoreRelease()
QCOMPARE(atomic.loadAcquire(), T(~value));
atomic.storeRelease(value);
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
}
void tst_QAtomicIntegerXX::refDeref()
{
QFETCH(LargeInt, value);
- const bool needToPreventOverflow = TypeIsSigned && value == std::numeric_limits<T>::max();
- const bool needToPreventUnderflow = TypeIsSigned && value == std::numeric_limits<T>::min();
- T nextValue = T(value);
- if (!needToPreventOverflow)
- ++nextValue;
- T prevValue = T(value);
- if (!needToPreventUnderflow)
- --prevValue;
+
+ // We perform arithmetic using the unsigned type U to avoid signed
+ // integer overflows in the non-atomic portion (atomics have well-defined,
+ // two's complement overflow, even signed ones).
+ T nextValue = T(U(value) + 1);
+ T prevValue = T(U(value) - 1);
QAtomicInteger<T> atomic(value);
- if (!needToPreventOverflow) {
QCOMPARE(atomic.ref(), (nextValue != 0));
- QCOMPARE(atomic.load(), nextValue);
+ QCOMPARE(atomic.loadRelaxed(), nextValue);
QCOMPARE(atomic.deref(), (value != 0));
- }
- QCOMPARE(atomic.load(), T(value));
- if (!needToPreventUnderflow) {
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.deref(), (prevValue != 0));
- QCOMPARE(atomic.load(), prevValue);
+ QCOMPARE(atomic.loadRelaxed(), prevValue);
QCOMPARE(atomic.ref(), (value != 0));
- }
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
- if (!needToPreventOverflow) {
QCOMPARE(++atomic, nextValue);
QCOMPARE(--atomic, T(value));
- }
- if (!needToPreventUnderflow) {
QCOMPARE(--atomic, prevValue);
QCOMPARE(++atomic, T(value));
- }
- if (!needToPreventOverflow) {
QCOMPARE(atomic++, T(value));
QCOMPARE(atomic--, nextValue);
- }
- if (!needToPreventUnderflow) {
QCOMPARE(atomic--, T(value));
QCOMPARE(atomic++, prevValue);
- }
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
}
void tst_QAtomicIntegerXX::testAndSet()
@@ -402,16 +328,16 @@ void tst_QAtomicIntegerXX::testAndSet()
QAtomicInteger<T> atomic(value);
QVERIFY(atomic.testAndSetRelaxed(value, newValue));
- QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.loadRelaxed(), newValue);
QVERIFY(!atomic.testAndSetRelaxed(value, newValue));
QVERIFY(atomic.testAndSetRelaxed(newValue, value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QVERIFY(atomic.testAndSetAcquire(value, newValue));
- QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.loadRelaxed(), newValue);
QVERIFY(!atomic.testAndSetAcquire(value, newValue));
QVERIFY(atomic.testAndSetAcquire(newValue, value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QVERIFY(atomic.testAndSetRelease(value, newValue));
QCOMPARE(atomic.loadAcquire(), newValue);
@@ -434,18 +360,18 @@ void tst_QAtomicIntegerXX::testAndSet3()
QAtomicInteger<T> atomic(value);
QVERIFY(atomic.testAndSetRelaxed(value, newValue, oldValue));
- QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.loadRelaxed(), newValue);
QVERIFY(!atomic.testAndSetRelaxed(value, newValue, oldValue));
QCOMPARE(oldValue, newValue);
QVERIFY(atomic.testAndSetRelaxed(newValue, value, oldValue));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QVERIFY(atomic.testAndSetAcquire(value, newValue, oldValue));
- QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.loadRelaxed(), newValue);
QVERIFY(!atomic.testAndSetAcquire(value, newValue, oldValue));
QCOMPARE(oldValue, newValue);
QVERIFY(atomic.testAndSetAcquire(newValue, value, oldValue));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QVERIFY(atomic.testAndSetRelease(value, newValue, oldValue));
QCOMPARE(atomic.loadAcquire(), newValue);
@@ -469,14 +395,14 @@ void tst_QAtomicIntegerXX::fetchAndStore()
QAtomicInteger<T> atomic(value);
QCOMPARE(atomic.fetchAndStoreRelaxed(newValue), T(value));
- QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.loadRelaxed(), newValue);
QCOMPARE(atomic.fetchAndStoreRelaxed(value), newValue);
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndStoreAcquire(newValue), T(value));
- QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.loadRelaxed(), newValue);
QCOMPARE(atomic.fetchAndStoreAcquire(value), newValue);
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndStoreRelease(newValue), T(value));
QCOMPARE(atomic.loadAcquire(), newValue);
@@ -494,80 +420,55 @@ void tst_QAtomicIntegerXX::fetchAndAdd()
QFETCH(LargeInt, value);
QAtomicInteger<T> atomic(value);
+ // We perform the additions using the unsigned type U to avoid signed
+ // integer overflows in the non-atomic portion (atomics have well-defined,
+ // two's complement overflow, even signed ones).
T parcel1 = 42;
T parcel2 = T(0-parcel1);
+ T newValue1 = T(U(value) + parcel1);
+ T newValue2 = T(U(value) + parcel2);
- const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() + parcel2;
- const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() + parcel1;
-
- T newValue1 = T(value);
- if (!needToPreventOverflow)
- newValue1 += parcel1;
- T newValue2 = T(value);
- if (!needToPreventUnderflow)
- newValue2 += parcel2;
-
- if (!needToPreventOverflow) {
QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), T(value));
- QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.loadRelaxed(), newValue1);
QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), newValue1);
- }
- QCOMPARE(atomic.load(), T(value));
- if (!needToPreventUnderflow) {
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), T(value));
- QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.loadRelaxed(), newValue2);
QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), newValue2);
- }
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
- if (!needToPreventOverflow) {
QCOMPARE(atomic.fetchAndAddAcquire(parcel1), T(value));
- QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.loadRelaxed(), newValue1);
QCOMPARE(atomic.fetchAndAddAcquire(parcel2), newValue1);
- }
- QCOMPARE(atomic.load(), T(value));
- if (!needToPreventUnderflow) {
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndAddAcquire(parcel2), T(value));
- QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.loadRelaxed(), newValue2);
QCOMPARE(atomic.fetchAndAddAcquire(parcel1), newValue2);
- }
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
- if (!needToPreventOverflow) {
QCOMPARE(atomic.fetchAndAddRelease(parcel1), T(value));
QCOMPARE(atomic.loadAcquire(), newValue1);
QCOMPARE(atomic.fetchAndAddRelease(parcel2), newValue1);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
- if (!needToPreventUnderflow) {
QCOMPARE(atomic.fetchAndAddRelease(parcel2), T(value));
QCOMPARE(atomic.loadAcquire(), newValue2);
QCOMPARE(atomic.fetchAndAddRelease(parcel1), newValue2);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
- if (!needToPreventOverflow) {
QCOMPARE(atomic.fetchAndAddOrdered(parcel1), T(value));
QCOMPARE(atomic.loadAcquire(), newValue1);
QCOMPARE(atomic.fetchAndAddOrdered(parcel2), newValue1);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
- if (!needToPreventUnderflow) {
QCOMPARE(atomic.fetchAndAddOrdered(parcel2), T(value));
QCOMPARE(atomic.loadAcquire(), newValue2);
QCOMPARE(atomic.fetchAndAddOrdered(parcel1), newValue2);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
// operator+=
- if (!needToPreventOverflow) {
QCOMPARE(atomic += parcel1, newValue1);
QCOMPARE(atomic += parcel2, T(value));
- }
- if (!needToPreventUnderflow) {
QCOMPARE(atomic += parcel2, newValue2);
QCOMPARE(atomic += parcel1, T(value));
- }
}
void tst_QAtomicIntegerXX::fetchAndSub()
@@ -575,80 +476,55 @@ void tst_QAtomicIntegerXX::fetchAndSub()
QFETCH(LargeInt, value);
QAtomicInteger<T> atomic(value);
+ // We perform the subtractions using the unsigned type U to avoid signed
+ // integer underrflows in the non-atomic portion (atomics have well-defined,
+ // two's complement underflow, even signed ones).
T parcel1 = 42;
T parcel2 = T(0-parcel1);
+ T newValue1 = T(U(value) - parcel1);
+ T newValue2 = T(U(value) - parcel2);
- const bool needToPreventOverflow = TypeIsSigned && value > std::numeric_limits<T>::max() - parcel1;
- const bool needToPreventUnderflow = TypeIsSigned && value < std::numeric_limits<T>::min() - parcel2;
-
- T newValue1 = T(value);
- if (!needToPreventUnderflow)
- newValue1 -= parcel1;
- T newValue2 = T(value);
- if (!needToPreventOverflow)
- newValue2 -= parcel2;
-
- if (!needToPreventUnderflow) {
QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), T(value));
- QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.loadRelaxed(), newValue1);
QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), newValue1);
- }
- QCOMPARE(atomic.load(), T(value));
- if (!needToPreventOverflow) {
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), T(value));
- QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.loadRelaxed(), newValue2);
QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), newValue2);
- }
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
- if (!needToPreventUnderflow) {
QCOMPARE(atomic.fetchAndSubAcquire(parcel1), T(value));
- QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.loadRelaxed(), newValue1);
QCOMPARE(atomic.fetchAndSubAcquire(parcel2), newValue1);
- }
- QCOMPARE(atomic.load(), T(value));
- if (!needToPreventOverflow) {
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndSubAcquire(parcel2), T(value));
- QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.loadRelaxed(), newValue2);
QCOMPARE(atomic.fetchAndSubAcquire(parcel1), newValue2);
- }
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
- if (!needToPreventUnderflow) {
QCOMPARE(atomic.fetchAndSubRelease(parcel1), T(value));
QCOMPARE(atomic.loadAcquire(), newValue1);
QCOMPARE(atomic.fetchAndSubRelease(parcel2), newValue1);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
- if (!needToPreventOverflow) {
QCOMPARE(atomic.fetchAndSubRelease(parcel2), T(value));
QCOMPARE(atomic.loadAcquire(), newValue2);
QCOMPARE(atomic.fetchAndSubRelease(parcel1), newValue2);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
- if (!needToPreventUnderflow) {
QCOMPARE(atomic.fetchAndSubOrdered(parcel1), T(value));
QCOMPARE(atomic.loadAcquire(), newValue1);
QCOMPARE(atomic.fetchAndSubOrdered(parcel2), newValue1);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
- if (!needToPreventOverflow) {
QCOMPARE(atomic.fetchAndSubOrdered(parcel2), T(value));
QCOMPARE(atomic.loadAcquire(), newValue2);
QCOMPARE(atomic.fetchAndSubOrdered(parcel1), newValue2);
- }
QCOMPARE(atomic.loadAcquire(), T(value));
// operator-=
- if (!needToPreventUnderflow) {
QCOMPARE(atomic -= parcel1, newValue1);
QCOMPARE(atomic -= parcel2, T(value));
- }
- if (!needToPreventOverflow) {
QCOMPARE(atomic -= parcel2, newValue2);
QCOMPARE(atomic -= parcel1, T(value));
- }
}
void tst_QAtomicIntegerXX::fetchAndOr()
@@ -662,32 +538,32 @@ void tst_QAtomicIntegerXX::fetchAndOr()
QCOMPARE(atomic.fetchAndOrRelaxed(zero), T(value));
QCOMPARE(atomic.fetchAndOrRelaxed(one), T(value));
- QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.loadRelaxed(), T(value | 1));
QCOMPARE(atomic.fetchAndOrRelaxed(minusOne), T(value | 1));
- QCOMPARE(atomic.load(), minusOne);
+ QCOMPARE(atomic.loadRelaxed(), minusOne);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic.fetchAndOrAcquire(zero), T(value));
QCOMPARE(atomic.fetchAndOrAcquire(one), T(value));
- QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.loadRelaxed(), T(value | 1));
QCOMPARE(atomic.fetchAndOrAcquire(minusOne), T(value | 1));
- QCOMPARE(atomic.load(), minusOne);
+ QCOMPARE(atomic.loadRelaxed(), minusOne);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic.fetchAndOrRelease(zero), T(value));
QCOMPARE(atomic.fetchAndOrRelease(one), T(value));
- QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.loadRelaxed(), T(value | 1));
QCOMPARE(atomic.fetchAndOrRelease(minusOne), T(value | 1));
- QCOMPARE(atomic.load(), minusOne);
+ QCOMPARE(atomic.loadRelaxed(), minusOne);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic.fetchAndOrOrdered(zero), T(value));
QCOMPARE(atomic.fetchAndOrOrdered(one), T(value));
- QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.loadRelaxed(), T(value | 1));
QCOMPARE(atomic.fetchAndOrOrdered(minusOne), T(value | 1));
- QCOMPARE(atomic.load(), minusOne);
+ QCOMPARE(atomic.loadRelaxed(), minusOne);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic |= zero, T(value));
QCOMPARE(atomic |= one, T(value | 1));
QCOMPARE(atomic |= minusOne, minusOne);
@@ -703,37 +579,37 @@ void tst_QAtomicIntegerXX::fetchAndAnd()
T minusOne = T(~0);
QCOMPARE(atomic.fetchAndAndRelaxed(minusOne), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndAndRelaxed(f), T(value));
- QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.loadRelaxed(), T(value & 0xf));
QCOMPARE(atomic.fetchAndAndRelaxed(zero), T(value & 0xf));
- QCOMPARE(atomic.load(), zero);
+ QCOMPARE(atomic.loadRelaxed(), zero);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic.fetchAndAndAcquire(minusOne), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndAndAcquire(f), T(value));
- QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.loadRelaxed(), T(value & 0xf));
QCOMPARE(atomic.fetchAndAndAcquire(zero), T(value & 0xf));
- QCOMPARE(atomic.load(), zero);
+ QCOMPARE(atomic.loadRelaxed(), zero);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic.fetchAndAndRelease(minusOne), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndAndRelease(f), T(value));
- QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.loadRelaxed(), T(value & 0xf));
QCOMPARE(atomic.fetchAndAndRelease(zero), T(value & 0xf));
- QCOMPARE(atomic.load(), zero);
+ QCOMPARE(atomic.loadRelaxed(), zero);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic.fetchAndAndOrdered(minusOne), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndAndOrdered(f), T(value));
- QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.loadRelaxed(), T(value & 0xf));
QCOMPARE(atomic.fetchAndAndOrdered(zero), T(value & 0xf));
- QCOMPARE(atomic.load(), zero);
+ QCOMPARE(atomic.loadRelaxed(), zero);
- atomic.store(value);
+ atomic.storeRelaxed(value);
QCOMPARE(atomic &= minusOne, T(value));
QCOMPARE(atomic &= f, T(value & 0xf));
QCOMPARE(atomic &= zero, zero);
@@ -749,48 +625,48 @@ void tst_QAtomicIntegerXX::fetchAndXor()
T minusOne = T(~0);
QCOMPARE(atomic.fetchAndXorRelaxed(zero), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorRelaxed(pattern), T(value));
- QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.loadRelaxed(), T(value ^ pattern));
QCOMPARE(atomic.fetchAndXorRelaxed(pattern), T(value ^ pattern));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorRelaxed(minusOne), T(value));
- QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.loadRelaxed(), T(~value));
QCOMPARE(atomic.fetchAndXorRelaxed(minusOne), T(~value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorAcquire(zero), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorAcquire(pattern), T(value));
- QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.loadRelaxed(), T(value ^ pattern));
QCOMPARE(atomic.fetchAndXorAcquire(pattern), T(value ^ pattern));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorAcquire(minusOne), T(value));
- QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.loadRelaxed(), T(~value));
QCOMPARE(atomic.fetchAndXorAcquire(minusOne), T(~value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorRelease(zero), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorRelease(pattern), T(value));
- QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.loadRelaxed(), T(value ^ pattern));
QCOMPARE(atomic.fetchAndXorRelease(pattern), T(value ^ pattern));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorRelease(minusOne), T(value));
- QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.loadRelaxed(), T(~value));
QCOMPARE(atomic.fetchAndXorRelease(minusOne), T(~value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorOrdered(zero), T(value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorOrdered(pattern), T(value));
- QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.loadRelaxed(), T(value ^ pattern));
QCOMPARE(atomic.fetchAndXorOrdered(pattern), T(value ^ pattern));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic.fetchAndXorOrdered(minusOne), T(value));
- QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.loadRelaxed(), T(~value));
QCOMPARE(atomic.fetchAndXorOrdered(minusOne), T(~value));
- QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.loadRelaxed(), T(value));
QCOMPARE(atomic ^= zero, T(value));
QCOMPARE(atomic ^= pattern, T(value ^ pattern));
@@ -798,8 +674,9 @@ void tst_QAtomicIntegerXX::fetchAndXor()
QCOMPARE(atomic ^= minusOne, T(~value));
QCOMPARE(atomic ^= minusOne, T(value));
}
-
-#include "tst_qatomicinteger.moc"
+}
QTEST_APPLESS_MAIN(tst_QAtomicIntegerXX)
+#include "tst_qatomicinteger.moc"
+
diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt
new file mode 100644
index 0000000000..95d88d31a6
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/uchar/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_uchar Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_uchar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_uchar
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=uchar
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_uchar
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt
new file mode 100644
index 0000000000..2ab977ef6a
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/uint/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_uint Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_uint LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_uint
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=uint
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_uint
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt
new file mode 100644
index 0000000000..7707bd53b5
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/ulong/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_ulong Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_ulong LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_ulong
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=ulong
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_ulong
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt
new file mode 100644
index 0000000000..667e9eade6
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/ushort/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_ushort Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_ushort LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_ushort
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=ushort
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_ushort
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt b/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt
new file mode 100644
index 0000000000..0e2d084b58
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/wchar_t/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicinteger_wchar_t Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicinteger_wchar_t LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicinteger_wchar_t
+ SOURCES
+ ../tst_qatomicinteger.cpp
+ DEFINES
+ QATOMIC_TEST_TYPE=wchar_t
+ tst_QAtomicIntegerXX=tst_QAtomicInteger_wchar_t
+)
diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
deleted file mode 100644
index 1e97d5cbae..0000000000
--- a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
+++ /dev/null
@@ -1 +0,0 @@
-include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt b/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt
new file mode 100644
index 0000000000..cd8df9db66
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicpointer/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qatomicpointer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicpointer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicpointer
+ SOURCES
+ tst_qatomicpointer.cpp
+)
diff --git a/tests/auto/corelib/thread/qatomicpointer/qatomicpointer.pro b/tests/auto/corelib/thread/qatomicpointer/qatomicpointer.pro
deleted file mode 100644
index cce822da6e..0000000000
--- a/tests/auto/corelib/thread/qatomicpointer/qatomicpointer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qatomicpointer
-QT = core testlib
-SOURCES = tst_qatomicpointer.cpp
diff --git a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
index 0200473cae..347831819e 100644
--- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
+++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qatomic.h>
#include <limits.h>
@@ -73,12 +48,12 @@ void tst_QAtomicPointer::warningFreeHelper()
{
qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only.");
- QBasicAtomicPointer<WFHC> p = Q_BASIC_ATOMIC_INITIALIZER(0);
+ QBasicAtomicPointer<WFHC> p = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
- p.load()->bar();
+ p.loadRelaxed()->bar();
- WFHC *expectedValue = 0;
- WFHC *newValue = 0;
+ WFHC *expectedValue = nullptr;
+ WFHC *newValue = nullptr;
qptrdiff valueToAdd = 0;
p.testAndSetRelaxed(expectedValue, newValue);
@@ -108,26 +83,22 @@ void tst_QAtomicPointer::warningFree()
void tst_QAtomicPointer::alignment()
{
-#ifdef Q_ALIGNOF
- // this will cause a build error if the alignment isn't the same
- char dummy[Q_ALIGNOF(QBasicAtomicPointer<void>) == Q_ALIGNOF(void*) ? 1 : -1];
- (void)dummy;
-#endif
+ static_assert(alignof(QBasicAtomicPointer<void>) == alignof(void*));
}
void tst_QAtomicPointer::constructor()
{
void *one = this;
QAtomicPointer<void> atomic1 = one;
- QCOMPARE(atomic1.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), one);
void *two = &one;
QAtomicPointer<void> atomic2 = two;
- QCOMPARE(atomic2.load(), two);
+ QCOMPARE(atomic2.loadRelaxed(), two);
void *three = &two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic3.loadRelaxed(), three);
}
void tst_QAtomicPointer::copy_constructor()
@@ -135,20 +106,20 @@ void tst_QAtomicPointer::copy_constructor()
void *one = this;
QAtomicPointer<void> atomic1 = one;
QAtomicPointer<void> atomic1_copy = atomic1;
- QCOMPARE(atomic1_copy.load(), one);
- QCOMPARE(atomic1_copy.load(), atomic1.load());
+ QCOMPARE(atomic1_copy.loadRelaxed(), one);
+ QCOMPARE(atomic1_copy.loadRelaxed(), atomic1.loadRelaxed());
void *two = &one;
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic2_copy = atomic2;
- QCOMPARE(atomic2_copy.load(), two);
- QCOMPARE(atomic2_copy.load(), atomic2.load());
+ QCOMPARE(atomic2_copy.loadRelaxed(), two);
+ QCOMPARE(atomic2_copy.loadRelaxed(), atomic2.loadRelaxed());
void *three = &two;
QAtomicPointer<void> atomic3 = three;
QAtomicPointer<void> atomic3_copy = atomic3;
- QCOMPARE(atomic3_copy.load(), three);
- QCOMPARE(atomic3_copy.load(), atomic3.load());
+ QCOMPARE(atomic3_copy.loadRelaxed(), three);
+ QCOMPARE(atomic3_copy.loadRelaxed(), atomic3.loadRelaxed());
}
void tst_QAtomicPointer::assignment_operator()
@@ -161,17 +132,17 @@ void tst_QAtomicPointer::assignment_operator()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
atomic1 = two;
atomic2 = three;
atomic3 = one;
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
void tst_QAtomicPointer::isTestAndSetNative()
@@ -234,17 +205,17 @@ void tst_QAtomicPointer::testAndSet()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QVERIFY(atomic1.testAndSetRelaxed(one, two));
QVERIFY(atomic2.testAndSetRelaxed(two, three));
QVERIFY(atomic3.testAndSetRelaxed(three, one));
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
{
@@ -252,17 +223,17 @@ void tst_QAtomicPointer::testAndSet()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QVERIFY(atomic1.testAndSetAcquire(one, two));
QVERIFY(atomic2.testAndSetAcquire(two, three));
QVERIFY(atomic3.testAndSetAcquire(three, one));
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
{
@@ -270,17 +241,17 @@ void tst_QAtomicPointer::testAndSet()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QVERIFY(atomic1.testAndSetRelease(one, two));
QVERIFY(atomic2.testAndSetRelease(two, three));
QVERIFY(atomic3.testAndSetRelease(three, one));
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
{
@@ -288,17 +259,17 @@ void tst_QAtomicPointer::testAndSet()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QVERIFY(atomic1.testAndSetOrdered(one, two));
QVERIFY(atomic2.testAndSetOrdered(two, three));
QVERIFY(atomic3.testAndSetOrdered(three, one));
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
}
@@ -362,17 +333,17 @@ void tst_QAtomicPointer::fetchAndStore()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QCOMPARE(atomic1.fetchAndStoreRelaxed(two), one);
QCOMPARE(atomic2.fetchAndStoreRelaxed(three), two);
QCOMPARE(atomic3.fetchAndStoreRelaxed(one), three);
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
{
@@ -380,17 +351,17 @@ void tst_QAtomicPointer::fetchAndStore()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QCOMPARE(atomic1.fetchAndStoreAcquire(two), one);
QCOMPARE(atomic2.fetchAndStoreAcquire(three), two);
QCOMPARE(atomic3.fetchAndStoreAcquire(one), three);
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
{
@@ -398,17 +369,17 @@ void tst_QAtomicPointer::fetchAndStore()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QCOMPARE(atomic1.fetchAndStoreRelease(two), one);
QCOMPARE(atomic2.fetchAndStoreRelease(three), two);
QCOMPARE(atomic3.fetchAndStoreRelease(one), three);
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
{
@@ -416,17 +387,17 @@ void tst_QAtomicPointer::fetchAndStore()
QAtomicPointer<void> atomic2 = two;
QAtomicPointer<void> atomic3 = three;
- QCOMPARE(atomic1.load(), one);
- QCOMPARE(atomic2.load(), two);
- QCOMPARE(atomic3.load(), three);
+ QCOMPARE(atomic1.loadRelaxed(), one);
+ QCOMPARE(atomic2.loadRelaxed(), two);
+ QCOMPARE(atomic3.loadRelaxed(), three);
QCOMPARE(atomic1.fetchAndStoreOrdered(two), one);
QCOMPARE(atomic2.fetchAndStoreOrdered(three), two);
QCOMPARE(atomic3.fetchAndStoreOrdered(one), three);
- QCOMPARE(atomic1.load(), two);
- QCOMPARE(atomic2.load(), three);
- QCOMPARE(atomic3.load(), one);
+ QCOMPARE(atomic1.loadRelaxed(), two);
+ QCOMPARE(atomic2.loadRelaxed(), three);
+ QCOMPARE(atomic3.loadRelaxed(), one);
}
}
@@ -530,66 +501,66 @@ void tst_QAtomicPointer::fetchAndAdd()
// cast to void* in order to avoid QCOMPARE to compare string content of the char*
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddRelaxed(valueToAdd)), static_cast<void*>(pc));
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddRelaxed(-valueToAdd)), static_cast<void*>(pc + valueToAdd));
- QCOMPARE(static_cast<void*>(pointer1.load()), static_cast<void*>(pc));
+ QCOMPARE(static_cast<void*>(pointer1.loadRelaxed()), static_cast<void*>(pc));
QAtomicPointer<short> pointer2 = ps;
QCOMPARE(pointer2.fetchAndAddRelaxed(valueToAdd), ps);
QCOMPARE(pointer2.fetchAndAddRelaxed(-valueToAdd), ps + valueToAdd);
- QCOMPARE(pointer2.load(), ps);
+ QCOMPARE(pointer2.loadRelaxed(), ps);
QAtomicPointer<int> pointer3 = pi;
QCOMPARE(pointer3.fetchAndAddRelaxed(valueToAdd), pi);
QCOMPARE(pointer3.fetchAndAddRelaxed(-valueToAdd), pi + valueToAdd);
- QCOMPARE(pointer3.load(), pi);
+ QCOMPARE(pointer3.loadRelaxed(), pi);
}
{
QAtomicPointer<char> pointer1 = pc;
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddAcquire(valueToAdd)), static_cast<void*>(pc));
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddAcquire(-valueToAdd)), static_cast<void*>(pc + valueToAdd));
- QCOMPARE(static_cast<void*>(pointer1.load()), static_cast<void*>(pc));
+ QCOMPARE(static_cast<void*>(pointer1.loadRelaxed()), static_cast<void*>(pc));
QAtomicPointer<short> pointer2 = ps;
QCOMPARE(pointer2.fetchAndAddAcquire(valueToAdd), ps);
QCOMPARE(pointer2.fetchAndAddAcquire(-valueToAdd), ps + valueToAdd);
- QCOMPARE(pointer2.load(), ps);
+ QCOMPARE(pointer2.loadRelaxed(), ps);
QAtomicPointer<int> pointer3 = pi;
QCOMPARE(pointer3.fetchAndAddAcquire(valueToAdd), pi);
QCOMPARE(pointer3.fetchAndAddAcquire(-valueToAdd), pi + valueToAdd);
- QCOMPARE(pointer3.load(), pi);
+ QCOMPARE(pointer3.loadRelaxed(), pi);
}
{
QAtomicPointer<char> pointer1 = pc;
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddRelease(valueToAdd)), static_cast<void*>(pc));
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddRelease(-valueToAdd)), static_cast<void*>(pc + valueToAdd));
- QCOMPARE(static_cast<void*>(pointer1.load()), static_cast<void*>(pc));
+ QCOMPARE(static_cast<void*>(pointer1.loadRelaxed()), static_cast<void*>(pc));
QAtomicPointer<short> pointer2 = ps;
QCOMPARE(pointer2.fetchAndAddRelease(valueToAdd), ps);
QCOMPARE(pointer2.fetchAndAddRelease(-valueToAdd), ps + valueToAdd);
- QCOMPARE(pointer2.load(), ps);
+ QCOMPARE(pointer2.loadRelaxed(), ps);
QAtomicPointer<int> pointer3 = pi;
QCOMPARE(pointer3.fetchAndAddRelease(valueToAdd), pi);
QCOMPARE(pointer3.fetchAndAddRelease(-valueToAdd), pi + valueToAdd);
- QCOMPARE(pointer3.load(), pi);
+ QCOMPARE(pointer3.loadRelaxed(), pi);
}
{
QAtomicPointer<char> pointer1 = pc;
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddOrdered(valueToAdd)), static_cast<void*>(pc));
QCOMPARE(static_cast<void*>(pointer1.fetchAndAddOrdered(-valueToAdd)), static_cast<void*>(pc + valueToAdd));
- QCOMPARE(static_cast<void*>(pointer1.load()), static_cast<void*>(pc));
+ QCOMPARE(static_cast<void*>(pointer1.loadRelaxed()), static_cast<void*>(pc));
QAtomicPointer<short> pointer2 = ps;
QCOMPARE(pointer2.fetchAndAddOrdered(valueToAdd), ps);
QCOMPARE(pointer2.fetchAndAddOrdered(-valueToAdd), ps + valueToAdd);
- QCOMPARE(pointer2.load(), ps);
+ QCOMPARE(pointer2.loadRelaxed(), ps);
QAtomicPointer<int> pointer3 = pi;
QCOMPARE(pointer3.fetchAndAddOrdered(valueToAdd), pi);
QCOMPARE(pointer3.fetchAndAddOrdered(-valueToAdd), pi + valueToAdd);
- QCOMPARE(pointer3.load(), pi);
+ QCOMPARE(pointer3.loadRelaxed(), pi);
}
}
template <typename T> void constAndVolatile_helper()
{
- T *one = 0;
+ T *one = nullptr;
T *two = &one;
T *three = &two;
@@ -598,34 +569,34 @@ template <typename T> void constAndVolatile_helper()
QAtomicPointer<T> atomic2 = two;
QAtomicPointer<T> atomic3 = three;
- QVERIFY(atomic1.load() == one);
- QVERIFY(atomic2.load() == two);
- QVERIFY(atomic3.load() == three);
+ QVERIFY(atomic1.loadRelaxed() == one);
+ QVERIFY(atomic2.loadRelaxed() == two);
+ QVERIFY(atomic3.loadRelaxed() == three);
QVERIFY(atomic1.fetchAndStoreRelaxed(two) == one);
QVERIFY(atomic2.fetchAndStoreRelaxed(three) == two);
QVERIFY(atomic3.fetchAndStoreRelaxed(one) == three);
- QVERIFY(atomic1.load() == two);
- QVERIFY(atomic2.load() == three);
- QVERIFY(atomic3.load() == one);
+ QVERIFY(atomic1.loadRelaxed() == two);
+ QVERIFY(atomic2.loadRelaxed() == three);
+ QVERIFY(atomic3.loadRelaxed() == one);
}
{
QAtomicPointer<T> atomic1 = one;
QAtomicPointer<T> atomic2 = two;
QAtomicPointer<T> atomic3 = three;
- QVERIFY(atomic1.load() == one);
- QVERIFY(atomic2.load() == two);
- QVERIFY(atomic3.load() == three);
+ QVERIFY(atomic1.loadRelaxed() == one);
+ QVERIFY(atomic2.loadRelaxed() == two);
+ QVERIFY(atomic3.loadRelaxed() == three);
QVERIFY(atomic1.testAndSetRelaxed(one, two));
QVERIFY(atomic2.testAndSetRelaxed(two, three));
QVERIFY(atomic3.testAndSetRelaxed(three, one));
- QVERIFY(atomic1.load() == two);
- QVERIFY(atomic2.load() == three);
- QVERIFY(atomic3.load() == one);
+ QVERIFY(atomic1.loadRelaxed() == two);
+ QVERIFY(atomic2.loadRelaxed() == three);
+ QVERIFY(atomic3.loadRelaxed() == one);
}
}
@@ -649,8 +620,8 @@ void tst_QAtomicPointer::forwardDeclared()
// this is just a compilation test
QAtomicPointer<ForwardDeclared> ptr;
ContainsForwardDeclared cfd;
- Q_UNUSED(ptr);
- Q_UNUSED(cfd);
+ Q_UNUSED(ptr)
+ Q_UNUSED(cfd)
QVERIFY(true);
}
@@ -665,7 +636,7 @@ template <typename T> static void operators_helper()
{
// Test that QBasicAtomicPointer also has operator= and cast operators
// We've been using them for QAtomicPointer<T> elsewhere
- QBasicAtomicPointer<T> atomic = Q_BASIC_ATOMIC_INITIALIZER(0);
+ QBasicAtomicPointer<T> atomic = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
atomic = one;
QCOMPARE(Ptr(atomic), one);
}
diff --git a/tests/auto/corelib/thread/qfuture/CMakeLists.txt b/tests/auto/corelib/thread/qfuture/CMakeLists.txt
new file mode 100644
index 0000000000..aa989f3df1
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuture/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfuture Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfuture LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfuture
+ SOURCES
+ tst_qfuture.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+qt_internal_extend_target(tst_qfuture CONDITION MSVC
+ COMPILE_OPTIONS
+ /bigobj
+)
+
+qt_internal_undefine_global_definition(tst_qfuture QT_NO_JAVA_STYLE_ITERATORS)
diff --git a/tests/auto/corelib/thread/qfuture/qfuture.pro b/tests/auto/corelib/thread/qfuture/qfuture.pro
deleted file mode 100644
index b1667760d6..0000000000
--- a/tests/auto/corelib/thread/qfuture/qfuture.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfuture
-QT = core core-private testlib
-SOURCES = tst_qfuture.cpp
-DEFINES += QT_STRICT_ITERATORS
diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
index b8c82c2ea0..3fc796514d 100644
--- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
+++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
@@ -1,73 +1,189 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QCoreApplication>
-#include <QDebug>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#define QFUTURE_TEST
-#include <QtTest/QtTest>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QSemaphore>
+#include <QTestEventLoop>
+#include <QTimer>
+#include <QSignalSpy>
+#include <QVarLengthArray>
+#include <QSet>
+#include <QList>
+#include <private/qobject_p.h>
+
+#include <QTest>
#include <qfuture.h>
#include <qfuturewatcher.h>
#include <qresultstore.h>
#include <qthreadpool.h>
#include <qexception.h>
#include <qrandom.h>
+#include <QtConcurrent/qtconcurrentrun.h>
#include <private/qfutureinterface_p.h>
+#include <forward_list>
+#include <list>
+#include <vector>
+#include <memory>
+#include <set>
+
// COM interface macro.
#if defined(Q_OS_WIN) && defined(interface)
# undef interface
#endif
-struct ResultStoreInt : QtPrivate::ResultStoreBase
+using namespace std::chrono_literals;
+static constexpr auto DefaultWaitTime = 2s;
+
+using namespace Qt::StringLiterals;
+
+class SenderObject : public QObject
{
- ~ResultStoreInt() { clear<int>(); }
+ Q_OBJECT
+
+public:
+ void emitNoArg() { emit noArgSignal(); }
+ void emitIntArg(int value) { emit intArgSignal(value); }
+ void emitConstRefArg(const QString &value) { emit constRefArg(value); }
+ void emitMultipleArgs(int value1, double value2, const QString &value3)
+ {
+ emit multipleArgs(value1, value2, value3);
+ }
+ void emitTupleArgSignal(const std::tuple<int, double, QString> &t) { emit tupleArgSignal(t); }
+ void emitMultiArgsWithTupleSignal1(int value, const std::tuple<int, double, QString> &t)
+ {
+ emit multiArgsWithTupleSignal1(value, t);
+ }
+ void emitMultiArgsWithTupleSignal2(const std::tuple<int, double, QString> &t, int value)
+ {
+ emit multiArgsWithTupleSignal2(t, value);
+ }
+ void emitMultiArgsWithPairSignal1(int value, const std::pair<int, double> &p)
+ {
+ emit multiArgsWithPairSignal1(value, p);
+ }
+ void emitMultiArgsWithPairSignal2(const std::pair<int, double> &p, int value)
+ {
+ emit multiArgsWithPairSignal2(p, value);
+ }
+
+ void emitNoArgPrivateSignal() { emit noArgPrivateSignal(QPrivateSignal()); }
+ void emitIntArgPrivateSignal(int value) { emit intArgPrivateSignal(value, QPrivateSignal()); }
+ void emitMultiArgsPrivateSignal(int value1, double value2, const QString &value3)
+ {
+ emit multiArgsPrivateSignal(value1, value2, value3, QPrivateSignal());
+ }
+ void emitTupleArgPrivateSignal(const std::tuple<int, double, QString> &t)
+ {
+ emit tupleArgPrivateSignal(t, QPrivateSignal());
+ }
+ void emitMultiArgsWithTuplePrivateSignal1(int value, const std::tuple<int, double, QString> &t)
+ {
+ emit multiArgsWithTuplePrivateSignal1(value, t, QPrivateSignal());
+ }
+ void emitMultiArgsWithTuplePrivateSignal2(const std::tuple<int, double, QString> &t, int value)
+ {
+ emit multiArgsWithTuplePrivateSignal2(t, value, QPrivateSignal());
+ }
+ void emitMultiArgsWithPairPrivateSignal1(int value, const std::pair<int, double> &p)
+ {
+ emit multiArgsWithPairPrivateSignal1(value, p, QPrivateSignal());
+ }
+ void emitMultiArgsWithPairPrivateSignal2(const std::pair<int, double> &p, int value)
+ {
+ emit multiArgsWithPairPrivateSignal2(p, value, QPrivateSignal());
+ }
+
+signals:
+ void noArgSignal();
+ void intArgSignal(int value);
+ void constRefArg(const QString &value);
+ void multipleArgs(int value1, double value2, const QString &value3);
+ void tupleArgSignal(const std::tuple<int, double, QString> &t);
+ void multiArgsWithTupleSignal1(int value, const std::tuple<int, double, QString> &t);
+ void multiArgsWithTupleSignal2(const std::tuple<int, double, QString> &t, int value);
+ void multiArgsWithPairSignal1(int value, const std::pair<int, double> &p);
+ void multiArgsWithPairSignal2(const std::pair<int, double> &p, int value);
+
+ // Private signals
+ void noArgPrivateSignal(QPrivateSignal);
+ void intArgPrivateSignal(int value, QPrivateSignal);
+ void multiArgsPrivateSignal(int value1, double value2, const QString &value3, QPrivateSignal);
+ void tupleArgPrivateSignal(const std::tuple<int, double, QString> &t, QPrivateSignal);
+ void multiArgsWithTuplePrivateSignal1(int value, const std::tuple<int, double, QString> &t,
+ QPrivateSignal);
+ void multiArgsWithTuplePrivateSignal2(const std::tuple<int, double, QString> &t, int value,
+ QPrivateSignal);
+ void multiArgsWithPairPrivateSignal1(int value, const std::pair<int, double> &p,
+ QPrivateSignal);
+ void multiArgsWithPairPrivateSignal2(const std::pair<int, double> &p, int value,
+ QPrivateSignal);
+};
+
+class LambdaThread : public QThread
+{
+public:
+ LambdaThread(std::function<void ()> fn)
+ :m_fn(fn)
+ {
+
+ }
+
+ void run() override
+ {
+ m_fn();
+ }
+
+private:
+ std::function<void ()> m_fn;
+};
+
+// Emulates QWidget behavior by deleting its children early in the destructor
+// instead of leaving it to ~QObject()
+class FakeQWidget : public QObject
+{
+ Q_OBJECT
+public:
+ ~FakeQWidget() override {
+ auto *d = QObjectPrivate::get(this);
+ d->deleteChildren();
+ }
};
+using UniquePtr = std::unique_ptr<int>;
+
class tst_QFuture: public QObject
{
Q_OBJECT
private slots:
void resultStore();
void future();
+ void futureToVoid();
void futureInterface();
void refcounting();
void cancel();
+ void cancelAndFinish();
void statePropagation();
void multipleResults();
void indexedResults();
void progress();
+ void setProgressRange();
+ void progressWithRange();
void progressText();
void resultsAfterFinished();
void resultsAsList();
- void implicitConversions();
void iterators();
+ void iteratorsThread();
+#if QT_DEPRECATED_SINCE(6, 0)
void pause();
+ void suspendCheckPaused();
+#endif
+ void suspend();
void throttling();
void voidConversions();
#ifndef QT_NO_EXCEPTIONS
@@ -75,6 +191,86 @@ private slots:
void nestedExceptions();
#endif
void nonGlobalThreadPool();
+
+ void then();
+ void thenForMoveOnlyTypes();
+ void thenOnCanceledFuture();
+#ifndef QT_NO_EXCEPTIONS
+ void thenOnExceptionFuture();
+ void thenThrows();
+ void onFailed();
+ void onFailedTestCallables();
+ void onFailedForMoveOnlyTypes();
+#endif
+ void onCanceled();
+ void cancelContinuations();
+ void continuationsWithContext_data();
+ void continuationsWithContext();
+ void continuationsWithMoveOnlyLambda();
+#if 0
+ // TODO: enable when QFuture::takeResults() is enabled
+ void takeResults();
+#endif
+ void takeResult();
+ void runAndTake();
+ void resultsReadyAt_data();
+ void resultsReadyAt();
+ void takeResultWorksForTypesWithoutDefaultCtor();
+ void canceledFutureIsNotValid();
+ void signalConnect();
+ void waitForFinished();
+
+ void rejectResultOverwrite_data();
+ void rejectResultOverwrite();
+ void rejectPendingResultOverwrite_data() { rejectResultOverwrite_data(); }
+ void rejectPendingResultOverwrite();
+
+ void createReadyFutures();
+ void continuationsAfterReadyFutures();
+
+ void getFutureInterface();
+ void convertQMetaType();
+
+ void whenAllIterators();
+ void whenAllIteratorsWithCanceled();
+ void whenAllIteratorsWithFailed();
+ void whenAllDifferentTypes();
+ void whenAllDifferentTypesWithCanceled();
+ void whenAllDifferentTypesWithFailed();
+ void whenAnyIterators();
+ void whenAnyIteratorsWithCanceled();
+ void whenAnyIteratorsWithFailed();
+ void whenAnyDifferentTypes();
+ void whenAnyDifferentTypesWithCanceled();
+ void whenAnyDifferentTypesWithFailed();
+
+ void continuationOverride();
+ void continuationsDontLeak();
+ void cancelAfterFinishWithContinuations();
+
+ void unwrap();
+
+private:
+ using size_type = std::vector<int>::size_type;
+
+ static void testSingleResult(const UniquePtr &p);
+ static void testSingleResult(const std::vector<int> &v);
+ template<class T>
+ static void testSingleResult(const T &unknown);
+ template<class T>
+ static void testFutureTaken(QFuture<T> &noMoreFuture);
+ template<class T>
+ static void testTakeResults(QFuture<T> future, size_type resultCount);
+};
+
+class IntResultsCleaner
+{
+public:
+ IntResultsCleaner(QtPrivate::ResultStoreBase &s) : store(s) { }
+ ~IntResultsCleaner() { store.clear<int>(); }
+
+private:
+ QtPrivate::ResultStoreBase &store;
};
void tst_QFuture::resultStore()
@@ -84,7 +280,9 @@ void tst_QFuture::resultStore()
int int2 = 2;
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
QCOMPARE(store.begin(), store.end());
QCOMPARE(store.resultAt(0), store.end());
QCOMPARE(store.resultAt(1), store.end());
@@ -92,7 +290,9 @@ void tst_QFuture::resultStore()
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(-1, &int0);
store.addResult(1, &int1);
QtPrivate::ResultIteratorBase it = store.begin();
@@ -110,11 +310,13 @@ void tst_QFuture::resultStore()
QVERIFY(it == store.end());
}
- QVector<int> vec0 = QVector<int>() << 2 << 3;
- QVector<int> vec1 = QVector<int>() << 4 << 5;
+ QList<int> vec0 = QList<int>() << 2 << 3;
+ QList<int> vec1 = QList<int>() << 4 << 5;
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(-1, &vec0, 2);
store.addResults(-1, &vec1, 2);
QtPrivate::ResultIteratorBase it = store.begin();
@@ -137,7 +339,9 @@ void tst_QFuture::resultStore()
QCOMPARE(it, store.end());
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(-1, &int0);
store.addResults(-1, &vec1, 2);
store.addResult(-1, &int1);
@@ -168,7 +372,9 @@ void tst_QFuture::resultStore()
QCOMPARE(store.resultAt(4), store.end());
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(-1, &int0);
store.addResults(-1, &vec0);
store.addResult(-1, &int1);
@@ -198,7 +404,9 @@ void tst_QFuture::resultStore()
QCOMPARE(store.resultAt(3).value<int>(), int1);
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(-1, &int0);
store.addResults(-1, &vec0);
store.addResult(200, &int1);
@@ -210,7 +418,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(1, &int1);
store.addResult(0, &int0);
store.addResult(-1, &int2);
@@ -221,7 +431,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
QCOMPARE(store.contains(0), false);
QCOMPARE(store.contains(1), false);
QCOMPARE(store.contains(INT_MAX), false);
@@ -229,7 +441,9 @@ void tst_QFuture::resultStore()
{
// Test filter mode, where "gaps" in the result array aren't allowed.
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResult(0, &int0);
@@ -263,7 +477,9 @@ void tst_QFuture::resultStore()
{
// test canceled results
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResult(0, &int0);
@@ -300,7 +516,9 @@ void tst_QFuture::resultStore()
{
// test addResult return value
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResult(0, &int0);
@@ -346,7 +564,9 @@ void tst_QFuture::resultStore()
{
// test resultCount in non-filtered mode. It should always be possible
// to iterate through the results 0 to resultCount.
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(0, &int0);
QCOMPARE(store.count(), 1);
@@ -360,7 +580,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(2, &int0);
QCOMPARE(store.count(), 0);
@@ -372,7 +594,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(2, &vec1);
QCOMPARE(store.count(), 0);
@@ -384,7 +608,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(2, &vec1);
QCOMPARE(store.count(), 0);
@@ -392,7 +618,9 @@ void tst_QFuture::resultStore()
QCOMPARE(store.count(), 4);
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -404,7 +632,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -417,7 +647,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -427,7 +659,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -440,7 +674,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(1, &int0);
store.addResult(3, &int0);
store.addResults(6, &vec0);
@@ -455,7 +691,9 @@ void tst_QFuture::resultStore()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResult(1, &int0);
store.addResult(3, &int0);
@@ -483,7 +721,9 @@ void tst_QFuture::resultStore()
QCOMPARE(store.contains(7), false);
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addCanceledResult(0);
QCOMPARE(store.contains(0), false);
@@ -519,6 +759,19 @@ void tst_QFuture::future()
QCOMPARE(intFuture2.isFinished(), true);
}
+void tst_QFuture::futureToVoid()
+{
+ QPromise<int> p;
+ QFuture<int> future = p.future();
+
+ p.start();
+ p.setProgressValue(42);
+ p.finish();
+
+ QFuture<void> voidFuture = QFuture<void>(future);
+ QCOMPARE(voidFuture.progressValue(), 42);
+}
+
class IntResult : public QFutureInterface<int>
{
public:
@@ -563,7 +816,7 @@ void tst_QFuture::futureInterface()
{
QFutureInterface<int> i;
i.reportStarted();
- i.reportResult(10);
+ QVERIFY(i.reportResult(10));
future = i.future();
i.reportFinished();
}
@@ -584,7 +837,7 @@ void tst_QFuture::futureInterface()
QCOMPARE(intFuture.isStarted(), true);
QCOMPARE(intFuture.isFinished(), false);
- result.reportFinished(&value);
+ QVERIFY(result.reportFinished(&value));
QCOMPARE(intFuture.isStarted(), true);
QCOMPARE(intFuture.isFinished(), true);
@@ -608,6 +861,36 @@ void tst_QFuture::futureInterface()
VoidResult a;
a.run().waitForFinished();
}
+
+ {
+ QFutureInterface<int> i1;
+ QVERIFY(i1.reportResult(1));
+ QFutureInterface<int> i2;
+ QVERIFY(i2.reportResult(2));
+ swap(i1, i2); // ADL must resolve this
+ QCOMPARE(i1.resultReference(0), 2);
+ QCOMPARE(i2.resultReference(0), 1);
+ }
+
+ {
+ QFutureInterface<int> fi;
+ fi.reportStarted();
+ QVERIFY(!fi.reportResults(QList<int> {}));
+ fi.reportFinished();
+
+ QVERIFY(fi.results().empty());
+ }
+
+ {
+ QFutureInterface<int> fi;
+ fi.reportStarted();
+ QList<int> values = { 1, 2, 3 };
+ QVERIFY(fi.reportResults(values));
+ QVERIFY(!fi.reportResults(QList<int> {}));
+ fi.reportFinished();
+
+ QCOMPARE(fi.results(), values);
+ }
}
template <typename T>
@@ -716,7 +999,40 @@ void tst_QFuture::cancel()
result = 3;
futureInterface.reportResult(&result);
futureInterface.reportFinished();
- QCOMPARE(f.results(), QList<int>());
+ QVERIFY(f.results().isEmpty());
+ }
+}
+
+void tst_QFuture::cancelAndFinish()
+{
+ {
+ QFutureInterface<void> fi;
+
+ fi.reportStarted();
+ fi.cancelAndFinish();
+
+ QVERIFY(fi.isStarted());
+ QVERIFY(!fi.isRunning());
+ QVERIFY(!fi.isSuspended());
+ QVERIFY(!fi.isSuspending());
+ QVERIFY(fi.isCanceled());
+ QVERIFY(fi.isFinished());
+ }
+
+ // The same with suspended state
+ {
+ QFutureInterface<void> fi;
+
+ fi.reportStarted();
+ fi.setSuspended(true);
+ fi.cancelAndFinish();
+
+ QVERIFY(fi.isStarted());
+ QVERIFY(!fi.isRunning());
+ QVERIFY(!fi.isSuspended());
+ QVERIFY(!fi.isSuspending());
+ QVERIFY(fi.isCanceled());
+ QVERIFY(fi.isFinished());
}
}
@@ -767,15 +1083,15 @@ void tst_QFuture::multipleResults()
int result;
result = 1;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
QCOMPARE(f.resultAt(0), 1);
result = 2;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
QCOMPARE(f.resultAt(1), 2);
result = 3;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
result = 4;
a.reportFinished(&result);
@@ -786,13 +1102,13 @@ void tst_QFuture::multipleResults()
QList<int> fasit = QList<int>() << 1 << 2 << 3 << 4;
{
QList<int> results;
- foreach(int result, f)
+ for (int result : std::as_const(f))
results.append(result);
QCOMPARE(results, fasit);
}
{
QList<int> results;
- foreach(int result, copy)
+ for (int result : std::as_const(copy))
results.append(result);
QCOMPARE(results, fasit);
}
@@ -816,16 +1132,16 @@ void tst_QFuture::indexedResults()
QChar result;
result = 'B';
- Interface.reportResult(&result, 1);
+ QVERIFY(Interface.reportResult(&result, 1));
QCOMPARE(f.resultAt(1), result);
result = 'A';
- Interface.reportResult(&result, 0);
+ QVERIFY(Interface.reportResult(&result, 0));
QCOMPARE(f.resultAt(0), result);
result = 'C';
- Interface.reportResult(&result); // no index
+ QVERIFY(Interface.reportResult(&result)); // no index
QCOMPARE(f.resultAt(2), result);
Interface.reportFinished();
@@ -841,22 +1157,22 @@ void tst_QFuture::indexedResults()
int result;
result = 0;
- Interface.reportResult(&result, 0);
+ QVERIFY(Interface.reportResult(&result, 0));
QVERIFY(f.isResultReadyAt(0));
QCOMPARE(f.resultAt(0), 0);
result = 3;
- Interface.reportResult(&result, 3);
+ QVERIFY(Interface.reportResult(&result, 3));
QVERIFY(f.isResultReadyAt(3));
QCOMPARE(f.resultAt(3), 3);
result = 2;
- Interface.reportResult(&result, 2);
+ QVERIFY(Interface.reportResult(&result, 2));
QVERIFY(f.isResultReadyAt(2));
QCOMPARE(f.resultAt(2), 2);
result = 4;
- Interface.reportResult(&result); // no index
+ QVERIFY(Interface.reportResult(&result)); // no index
QVERIFY(f.isResultReadyAt(4));
QCOMPARE(f.resultAt(4), 4);
@@ -887,6 +1203,55 @@ void tst_QFuture::progress()
QCOMPARE (f.progressValue(), 50);
}
+void tst_QFuture::setProgressRange()
+{
+ QFutureInterface<int> i;
+
+ QCOMPARE(i.progressMinimum(), 0);
+ QCOMPARE(i.progressMaximum(), 0);
+
+ i.setProgressRange(10, 5);
+
+ QCOMPARE(i.progressMinimum(), 10);
+ QCOMPARE(i.progressMaximum(), 10);
+
+ i.setProgressRange(5, 10);
+
+ QCOMPARE(i.progressMinimum(), 5);
+ QCOMPARE(i.progressMaximum(), 10);
+}
+
+void tst_QFuture::progressWithRange()
+{
+ QFutureInterface<int> i;
+ QFuture<int> f;
+
+ i.reportStarted();
+ f = i.future();
+
+ QCOMPARE(i.progressValue(), 0);
+
+ i.setProgressRange(5, 10);
+
+ QCOMPARE(i.progressValue(), 5);
+
+ i.setProgressValue(20);
+
+ QCOMPARE(i.progressValue(), 5);
+
+ i.setProgressValue(9);
+
+ QCOMPARE(i.progressValue(), 9);
+
+ i.setProgressRange(5, 7);
+
+ QCOMPARE(i.progressValue(), 5);
+
+ i.reportFinished();
+
+ QCOMPARE(f.progressValue(), 5);
+}
+
void tst_QFuture::progressText()
{
QFutureInterface<void> i;
@@ -913,7 +1278,7 @@ void tst_QFuture::resultsAfterFinished()
QCOMPARE(f.resultCount(), 0);
result = 1;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
QCOMPARE(f.resultAt(0), 1);
a.reportFinished();
@@ -921,7 +1286,7 @@ void tst_QFuture::resultsAfterFinished()
QCOMPARE(f.resultAt(0), 1);
QCOMPARE(f.resultCount(), 1);
result = 2;
- a.reportResult(&result);
+ QVERIFY(!a.reportResult(&result));
QCOMPARE(f.resultCount(), 1);
}
// cancel it
@@ -934,7 +1299,7 @@ void tst_QFuture::resultsAfterFinished()
QCOMPARE(f.resultCount(), 0);
result = 1;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
QCOMPARE(f.resultAt(0), 1);
QCOMPARE(f.resultCount(), 1);
@@ -944,7 +1309,7 @@ void tst_QFuture::resultsAfterFinished()
QCOMPARE(f.resultCount(), 1);
result = 2;
- a.reportResult(&result);
+ QVERIFY(!a.reportResult(&result));
a.reportFinished();
}
}
@@ -957,9 +1322,9 @@ void tst_QFuture::resultsAsList()
int result;
result = 1;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
result = 2;
- a.reportResult(&result);
+ QVERIFY(a.reportResult(&result));
a.reportFinished();
@@ -967,25 +1332,6 @@ void tst_QFuture::resultsAsList()
QCOMPARE(results, QList<int>() << 1 << 2);
}
-/*
- Test that QFuture<T> can be implicitly converted to T
-*/
-void tst_QFuture::implicitConversions()
-{
- QFutureInterface<QString> iface;
- iface.reportStarted();
-
- QFuture<QString> f(&iface);
-
- const QString input("FooBar 2000");
- iface.reportFinished(&input);
-
- const QString result = f;
- QCOMPARE(result, input);
- QCOMPARE(QString(f), input);
- QCOMPARE(static_cast<QString>(f), input);
-}
-
void tst_QFuture::iterators()
{
{
@@ -1034,13 +1380,13 @@ void tst_QFuture::iterators()
QVERIFY(c2 != c1);
int x1 = *i1;
- Q_UNUSED(x1);
+ Q_UNUSED(x1)
int x2 = *i2;
- Q_UNUSED(x2);
+ Q_UNUSED(x2)
int y1 = *c1;
- Q_UNUSED(y1);
+ Q_UNUSED(y1)
int y2 = *c2;
- Q_UNUSED(y2);
+ Q_UNUSED(y2)
}
{
@@ -1092,10 +1438,10 @@ void tst_QFuture::iterators()
QCOMPARE(x1, y1);
QCOMPARE(x2, y2);
- int i1Size = i1->size();
- int i2Size = i2->size();
- int c1Size = c1->size();
- int c2Size = c2->size();
+ auto i1Size = i1->size();
+ auto i2Size = i2->size();
+ auto c1Size = c1->size();
+ auto c2Size = c2->size();
QCOMPARE(i1Size, c1Size);
QCOMPARE(i2Size, c2Size);
@@ -1144,6 +1490,53 @@ void tst_QFuture::iterators()
}
}
}
+void tst_QFuture::iteratorsThread()
+{
+ const int expectedResultCount = 10;
+ QFutureInterface<int> futureInterface;
+
+ // Create result producer thread. The results are
+ // produced with delays in order to make the consumer
+ // wait.
+ QSemaphore sem;
+ LambdaThread thread = {[=, &futureInterface, &sem](){
+ for (int i = 1; i <= expectedResultCount; i += 2) {
+ int result = i;
+ futureInterface.reportResult(&result);
+ result = i + 1;
+ futureInterface.reportResult(&result);
+ }
+
+ sem.acquire(2);
+ futureInterface.reportFinished();
+ }};
+
+ futureInterface.reportStarted();
+ QFuture<int> future = futureInterface.future();
+
+ // Iterate over results while the thread is producing them.
+ thread.start();
+ int resultCount = 0;
+ int resultSum = 0;
+ for (int result : future) {
+ sem.release();
+ ++resultCount;
+ resultSum += result;
+ }
+ thread.wait();
+
+ QCOMPARE(resultCount, expectedResultCount);
+ QCOMPARE(resultSum, expectedResultCount * (expectedResultCount + 1) / 2);
+
+ // Reverse iterate
+ resultSum = 0;
+ QFutureIterator<int> it(future);
+ it.toBack();
+ while (it.hasPrevious())
+ resultSum += it.previous();
+
+ QCOMPARE(resultSum, expectedResultCount * (expectedResultCount + 1) / 2);
+}
class SignalSlotObject : public QObject
{
@@ -1190,6 +1583,9 @@ public:
QSet<int> reportedProgress;
};
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
void tst_QFuture::pause()
{
QFutureInterface<void> Interface;
@@ -1210,6 +1606,102 @@ void tst_QFuture::pause()
Interface.reportFinished();
}
+void tst_QFuture::suspendCheckPaused()
+{
+ QFutureInterface<void> interface;
+
+ interface.reportStarted();
+ QFuture<void> f = interface.future();
+ QVERIFY(!f.isSuspended());
+
+ interface.reportSuspended();
+ QVERIFY(!f.isSuspended());
+
+ f.pause();
+ QVERIFY(!f.isSuspended());
+ QVERIFY(f.isPaused());
+
+ // resume when still pausing
+ f.resume();
+ QVERIFY(!f.isSuspended());
+ QVERIFY(!f.isPaused());
+
+ // pause again
+ f.pause();
+ QVERIFY(!f.isSuspended());
+ QVERIFY(f.isPaused());
+
+ interface.reportSuspended();
+ QVERIFY(f.isSuspended());
+ QVERIFY(f.isPaused());
+
+ // resume after suspended
+ f.resume();
+ QVERIFY(!f.isSuspended());
+ QVERIFY(!f.isPaused());
+
+ // pause again and cancel
+ f.pause();
+ interface.reportSuspended();
+
+ interface.reportCanceled();
+ QVERIFY(!f.isSuspended());
+ QVERIFY(!f.isPaused());
+ QVERIFY(f.isCanceled());
+
+ interface.reportFinished();
+}
+
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+
+void tst_QFuture::suspend()
+{
+ QFutureInterface<void> interface;
+
+ interface.reportStarted();
+ QFuture<void> f = interface.future();
+ QVERIFY(!f.isSuspended());
+
+ interface.reportSuspended();
+ QVERIFY(!f.isSuspended());
+ QVERIFY(!f.isSuspending());
+
+ f.suspend();
+ QVERIFY(f.isSuspending());
+ QVERIFY(!f.isSuspended());
+
+ // resume when still suspending
+ f.resume();
+ QVERIFY(!f.isSuspending());
+ QVERIFY(!f.isSuspended());
+
+ // suspend again
+ f.suspend();
+ QVERIFY(f.isSuspending());
+ QVERIFY(!f.isSuspended());
+
+ interface.reportSuspended();
+ QVERIFY(!f.isSuspending());
+ QVERIFY(f.isSuspended());
+
+ // resume after suspended
+ f.resume();
+ QVERIFY(!f.isSuspending());
+ QVERIFY(!f.isSuspended());
+
+ // suspend again and cancel
+ f.suspend();
+ interface.reportSuspended();
+
+ interface.reportCanceled();
+ QVERIFY(!f.isSuspending());
+ QVERIFY(!f.isSuspended());
+ QVERIFY(f.isCanceled());
+
+ interface.reportFinished();
+}
+
class ResultObject : public QObject
{
Q_OBJECT
@@ -1254,12 +1746,10 @@ void tst_QFuture::voidConversions()
QFuture<int> intFuture(&iface);
int value = 10;
- iface.reportFinished(&value);
+ QVERIFY(iface.reportFinished(&value));
QFuture<void> voidFuture(intFuture);
voidFuture = intFuture;
-
- QVERIFY(voidFuture == intFuture);
}
{
@@ -1269,7 +1759,7 @@ void tst_QFuture::voidConversions()
iface.reportStarted();
QFuture<QList<int> > listFuture(&iface);
- iface.reportResult(QList<int>() << 1 << 2 << 3);
+ QVERIFY(iface.reportResult(QList<int>() << 1 << 2 << 3));
voidFuture = listFuture;
}
QCOMPARE(voidFuture.resultCount(), 0);
@@ -1324,6 +1814,23 @@ QFuture<void> createDerivedExceptionFuture()
return f;
}
+struct TestException
+{
+};
+
+QFuture<int> createCustomExceptionFuture()
+{
+ QFutureInterface<int> i;
+ i.reportStarted();
+ QFuture<int> f = i.future();
+ int r = 0;
+ i.reportResult(r);
+ auto exception = std::make_exception_ptr(TestException());
+ i.reportException(exception);
+ i.reportFinished();
+ return f;
+}
+
void tst_QFuture::exceptions()
{
// test throwing from waitForFinished
@@ -1379,7 +1886,7 @@ void tst_QFuture::exceptions()
bool caught = false;
try {
foreach (int e, f.results()) {
- Q_UNUSED(e);
+ Q_UNUSED(e)
QFAIL("did not get exception");
}
} catch (QException &) {
@@ -1408,6 +1915,18 @@ void tst_QFuture::exceptions()
}
QVERIFY(caught);
}
+
+ // Custom exceptions
+ {
+ QFuture<int> f = createCustomExceptionFuture();
+ bool caught = false;
+ try {
+ f.result();
+ } catch (const TestException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
}
class MyClass
@@ -1434,7 +1953,7 @@ void tst_QFuture::nestedExceptions()
{
try {
MyClass m;
- Q_UNUSED(m);
+ Q_UNUSED(m)
throw 0;
} catch (int) {}
@@ -1445,7 +1964,7 @@ void tst_QFuture::nestedExceptions()
void tst_QFuture::nonGlobalThreadPool()
{
- static Q_CONSTEXPR int Answer = 42;
+ static constexpr int Answer = 42;
struct UselessTask : QRunnable, QFutureInterface<int>
{
@@ -1462,7 +1981,7 @@ void tst_QFuture::nonGlobalThreadPool()
void run() override
{
const int ms = 100 + (QRandomGenerator::global()->bounded(100) - 100/2);
- QThread::msleep(ms);
+ QThread::sleep(std::chrono::milliseconds{ms});
reportResult(Answer);
reportFinished();
}
@@ -1472,7 +1991,7 @@ void tst_QFuture::nonGlobalThreadPool()
const int numTasks = QThread::idealThreadCount();
- QVector<QFuture<int> > futures;
+ QList<QFuture<int>> futures;
futures.reserve(numTasks);
for (int i = 0; i < numTasks; ++i)
@@ -1490,5 +2009,3349 @@ void tst_QFuture::nonGlobalThreadPool()
}
}
+void tst_QFuture::then()
+{
+ {
+ struct Add
+ {
+
+ static int addTwo(int arg) { return arg + 2; }
+
+ int operator()(int arg) const { return arg + 3; }
+ };
+
+ QFutureInterface<int> promise;
+ QFuture<int> then = promise.future()
+ .then([](int res) { return res + 1; }) // lambda
+ .then(Add::addTwo) // function
+ .then(Add()); // functor
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ const int result = 0;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(then.result(), result + 6);
+ }
+
+ // then() on a ready future
+ {
+ QFutureInterface<int> promise;
+ promise.reportStarted();
+
+ const int result = 0;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ QFuture<int> then = promise.future()
+ .then([](int res1) { return res1 + 1; })
+ .then([](int res2) { return res2 + 2; })
+ .then([](int res3) { return res3 + 3; });
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(then.result(), result + 6);
+ }
+
+ // Continuation of QFuture<void>
+ {
+ int result = 0;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then([&]() { result += 1; })
+ .then([&]() { result += 2; })
+ .then([&]() { result += 3; });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(result, 6);
+ }
+
+ // Continuation returns QFuture<void>
+ {
+ QFutureInterface<int> promise;
+ int value;
+ QFuture<void> then =
+ promise.future().then([](int res) { return res * 2; }).then([&](int prevResult) {
+ value = prevResult;
+ });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ const int result = 5;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(value, result * 2);
+ }
+
+ // Continuations taking a QFuture argument.
+ {
+ int value = 0;
+ QFutureInterface<int> promise;
+ QFuture<void> then = promise.future()
+ .then([](QFuture<int> f1) { return f1.result() + 1; })
+ .then([&](QFuture<int> f2) { value = f2.result() + 2; })
+ .then([&](QFuture<void> f3) {
+ QVERIFY(f3.isFinished());
+ value += 3;
+ });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ const int result = 0;
+ promise.reportResult(result);
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(value, 6);
+ }
+
+ // Continuations use a new thread
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then(QtFuture::Launch::Async,
+ [&]() { threadId1 = QThread::currentThreadId(); })
+ .then([&]() { threadId2 = QThread::currentThreadId(); });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QVERIFY(threadId1 != QThread::currentThreadId());
+ QVERIFY(threadId2 != QThread::currentThreadId());
+ QVERIFY(threadId1 == threadId2);
+ }
+
+ // Continuation inherits the launch policy of its parent (QtFuture::Launch::Sync)
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then(QtFuture::Launch::Sync,
+ [&]() { threadId1 = QThread::currentThreadId(); })
+ .then(QtFuture::Launch::Inherit,
+ [&]() { threadId2 = QThread::currentThreadId(); });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QVERIFY(threadId1 == QThread::currentThreadId());
+ QVERIFY(threadId2 == QThread::currentThreadId());
+ QVERIFY(threadId1 == threadId2);
+ }
+
+ // Continuation inherits the launch policy of its parent (QtFuture::Launch::Async)
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+ QFuture<void> then = promise.future()
+ .then(QtFuture::Launch::Async,
+ [&]() { threadId1 = QThread::currentThreadId(); })
+ .then(QtFuture::Launch::Inherit,
+ [&]() { threadId2 = QThread::currentThreadId(); });
+
+ promise.reportStarted();
+ QVERIFY(!then.isStarted());
+ QVERIFY(!then.isFinished());
+
+ promise.reportFinished();
+
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QVERIFY(threadId1 != QThread::currentThreadId());
+ QVERIFY(threadId2 != QThread::currentThreadId());
+ }
+
+ // Continuations use a custom thread pool
+ {
+ QFutureInterface<void> promise;
+ QThreadPool pool;
+ QVERIFY(pool.waitForDone(0)); // pool is not busy yet
+ QSemaphore semaphore;
+ QFuture<void> then = promise.future().then(&pool, [&]() { semaphore.acquire(); });
+
+ promise.reportStarted();
+ promise.reportFinished();
+
+ // Make sure the custom thread pool is busy on running the continuation
+ QVERIFY(!pool.waitForDone(0));
+ semaphore.release();
+ then.waitForFinished();
+
+ QVERIFY(then.isStarted());
+ QVERIFY(then.isFinished());
+ QCOMPARE(then.d.threadPool(), &pool);
+ }
+
+ // Continuation inherits parent's thread pool
+ {
+ Qt::HANDLE threadId1 = nullptr;
+ Qt::HANDLE threadId2 = nullptr;
+ QFutureInterface<void> promise;
+
+ QThreadPool pool;
+ QFuture<void> then1 = promise.future().then(&pool, [&]() {
+ threadId1 = QThread::currentThreadId();
+ });
+
+ promise.reportStarted();
+ promise.reportFinished();
+
+ then1.waitForFinished();
+ QVERIFY(pool.waitForDone()); // The pool is not busy after the first continuation is done
+
+ QSemaphore semaphore;
+ QFuture<void> then2 = then1.then(QtFuture::Launch::Inherit, [&]() {
+ semaphore.acquire();
+ threadId2 = QThread::currentThreadId();
+ });
+
+ QVERIFY(!pool.waitForDone(0)); // The pool is busy running the 2nd continuation
+
+ semaphore.release();
+ then2.waitForFinished();
+
+ QVERIFY(then2.isStarted());
+ QVERIFY(then2.isFinished());
+ QCOMPARE(then1.d.threadPool(), then2.d.threadPool());
+ QCOMPARE(then2.d.threadPool(), &pool);
+ QVERIFY(threadId1 != QThread::currentThreadId());
+ QVERIFY(threadId2 != QThread::currentThreadId());
+ }
+
+ // QTBUG-106083 & QTBUG-105182
+ {
+ QThread thread;
+ thread.start();
+
+ QObject context;
+ context.moveToThread(&thread);
+
+ auto future = QtConcurrent::run([] {
+ return 42;
+ }).then([] (int result) {
+ return result + 1;
+ }).then(&context, [] (int result) {
+ return result + 1;
+ });
+ QCOMPARE(future.result(), 44);
+ thread.quit();
+ thread.wait();
+ }
+}
+
+template<class Type, class Callable>
+bool runThenForMoveOnly(Callable &&callable)
+{
+ QFutureInterface<Type> promise;
+ auto future = promise.future();
+
+ auto then = future.then(std::forward<Callable>(callable));
+
+ promise.reportStarted();
+ if constexpr (!std::is_same_v<Type, void>)
+ promise.reportAndMoveResult(std::make_unique<int>(42));
+ promise.reportFinished();
+ then.waitForFinished();
+
+ bool success = true;
+ if constexpr (!std::is_same_v<decltype(then), QFuture<void>>)
+ success &= *then.takeResult() == 42;
+
+ if constexpr (!std::is_same_v<Type, void>)
+ success &= !future.isValid();
+
+ return success;
+}
+
+void tst_QFuture::thenForMoveOnlyTypes()
+{
+ QVERIFY(runThenForMoveOnly<UniquePtr>([](UniquePtr res) { return res; }));
+ QVERIFY(runThenForMoveOnly<UniquePtr>([](UniquePtr res) { Q_UNUSED(res); }));
+ QVERIFY(runThenForMoveOnly<UniquePtr>([](QFuture<UniquePtr> res) { return res.takeResult(); }));
+ QVERIFY(runThenForMoveOnly<void>([] { return std::make_unique<int>(42); }));
+}
+
+template<class T>
+QFuture<T> createCanceledFuture()
+{
+ QFutureInterface<T> promise;
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+ return promise.future();
+}
+
+void tst_QFuture::thenOnCanceledFuture()
+{
+ // Continuations on a canceled future
+ {
+ int thenResult = 0;
+ QFuture<void> then = createCanceledFuture<void>().then([&]() { ++thenResult; }).then([&]() {
+ ++thenResult;
+ });
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+
+ // QFuture gets canceled after continuations are set
+ {
+ QFutureInterface<void> promise;
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then([&]() { ++thenResult; }).then([&]() { ++thenResult; });
+
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Same with QtFuture::Launch::Async
+
+ // Continuations on a canceled future
+ {
+ int thenResult = 0;
+ QFuture<void> then = createCanceledFuture<void>()
+ .then(QtFuture::Launch::Async, [&]() { ++thenResult; })
+ .then([&]() { ++thenResult; });
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+
+ // QFuture gets canceled after continuations are set
+ {
+ QFutureInterface<void> promise;
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&]() { ++thenResult; }).then([&]() {
+ ++thenResult;
+ });
+
+ promise.reportStarted();
+ promise.reportCanceled();
+ promise.reportFinished();
+
+ QVERIFY(then.isCanceled());
+ QCOMPARE(thenResult, 0);
+ }
+}
+
+#ifndef QT_NO_EXCEPTIONS
+void tst_QFuture::thenOnExceptionFuture()
+{
+ {
+ QFutureInterface<int> promise;
+
+ int thenResult = 0;
+ QFuture<void> then = promise.future().then([&](int res) { thenResult = res; });
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Exception handled inside the continuation
+ {
+ QFutureInterface<int> promise;
+
+ bool caught = false;
+ bool caughtByContinuation = false;
+ bool success = false;
+ int thenResult = 0;
+ QFuture<void> then = promise.future()
+ .then([&](QFuture<int> res) {
+ try {
+ thenResult = res.result();
+ } catch (QException &) {
+ caughtByContinuation = true;
+ }
+ })
+ .then([&]() { success = true; });
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+
+ QCOMPARE(thenResult, 0);
+ QVERIFY(!caught);
+ QVERIFY(caughtByContinuation);
+ QVERIFY(success);
+ }
+
+ // Exception future
+ {
+ QFutureInterface<int> promise;
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ int thenResult = 0;
+ QFuture<void> then = promise.future().then([&](int res) { thenResult = res; });
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Same with QtFuture::Launch::Async
+ {
+ QFutureInterface<int> promise;
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&](int res) { thenResult = res; });
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+
+ // Exception future
+ {
+ QFutureInterface<int> promise;
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ int thenResult = 0;
+ QFuture<void> then =
+ promise.future().then(QtFuture::Launch::Async, [&](int res) { thenResult = res; });
+
+ bool caught = false;
+ try {
+ then.waitForFinished();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ QCOMPARE(thenResult, 0);
+ }
+}
+
+template<class Exception, bool hasTestMsg = false>
+QFuture<void> createExceptionContinuation(QtFuture::Launch policy = QtFuture::Launch::Sync)
+{
+ QFutureInterface<void> promise;
+
+ auto then = promise.future().then(policy, [] {
+ if constexpr (hasTestMsg)
+ throw Exception("TEST");
+ else
+ throw Exception();
+ });
+
+ promise.reportStarted();
+ promise.reportFinished();
+
+ return then;
+}
+
+void tst_QFuture::thenThrows()
+{
+ // Continuation throws a QException
+ {
+ auto future = createExceptionContinuation<QException>();
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
+
+ // Continuation throws an exception derived from QException
+ {
+ auto future = createExceptionContinuation<DerivedException>();
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ caught = true;
+ } catch (const std::exception &) {
+ QFAIL("The exception should be caught by the above catch block.");
+ }
+
+ QVERIFY(caught);
+ }
+
+ // Continuation throws std::exception
+ {
+ auto future = createExceptionContinuation<std::runtime_error, true>();
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ QFAIL("The exception should be caught by the below catch block.");
+ } catch (const std::exception &e) {
+ QCOMPARE(e.what(), "TEST");
+ caught = true;
+ }
+
+ QVERIFY(caught);
+ }
+
+ // Same with QtFuture::Launch::Async
+ {
+ auto future = createExceptionContinuation<QException>(QtFuture::Launch::Async);
+
+ bool caught = false;
+ try {
+ future.waitForFinished();
+ } catch (const QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
+}
+
+void tst_QFuture::onFailed()
+{
+ // Ready exception void future
+ {
+ int checkpoint = 0;
+ auto future = createExceptionFuture().then([&] { checkpoint = 1; }).onFailed([&] {
+ checkpoint = 2;
+ });
+
+ try {
+ future.waitForFinished();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 2);
+ }
+
+ // std::exception handler
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw std::exception();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 2);
+ QCOMPARE(res, -1);
+ }
+
+ // then() throws an exception derived from QException
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw DerivedException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 1);
+ QCOMPARE(res, -1);
+ }
+
+ // then() throws a custom exception
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw TestException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 3);
+ QCOMPARE(res, -1);
+ }
+
+ // Custom exception handler
+ {
+ struct TestException
+ {
+ };
+
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw TestException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const TestException &) {
+ checkpoint = 2;
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 3;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 4;
+ }
+ QCOMPARE(checkpoint, 2);
+ QCOMPARE(res, -1);
+ }
+
+ // Handle all exceptions
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw QException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&] {
+ checkpoint = 1;
+ return -1;
+ })
+ .onFailed([&](const QException &) {
+ checkpoint = 2;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 1);
+ QCOMPARE(res, -1);
+ }
+
+ // Handler throws exception
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw QException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const QException &) {
+ checkpoint = 1;
+ throw QException();
+ return -1;
+ })
+ .onFailed([&] {
+ checkpoint = 2;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 2);
+ QCOMPARE(res, -1);
+ }
+
+ // No handler for exception
+ {
+ QFutureInterface<int> promise;
+
+ int checkpoint = 0;
+ auto then = promise.future()
+ .then([&](int res) {
+ throw QException();
+ return res;
+ })
+ .then([&](int res) { return res + 1; })
+ .onFailed([&](const std::exception &) {
+ checkpoint = 1;
+ throw std::exception();
+ return -1;
+ })
+ .onFailed([&](QException &) {
+ checkpoint = 2;
+ return -1;
+ });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+
+ int res = 0;
+ try {
+ res = then.result();
+ } catch (...) {
+ checkpoint = 3;
+ }
+ QCOMPARE(checkpoint, 3);
+ QCOMPARE(res, 0);
+ }
+
+ // onFailed on a canceled future
+ {
+ auto future = createCanceledFuture<int>()
+ .then([](int) { return 42; })
+ .onCanceled([] { return -1; })
+ .onFailed([] { return -2; });
+ QCOMPARE(future.result(), -1);
+ }
+}
+
+template<class Callable>
+bool runForCallable(Callable &&handler)
+{
+ QFuture<int> future = createExceptionResultFuture()
+ .then([&](int) { return 1; })
+ .onFailed(std::forward<Callable>(handler));
+
+ int res = 0;
+ try {
+ res = future.result();
+ } catch (...) {
+ return false;
+ }
+ return res == -1;
+}
+
+int foo()
+{
+ return -1;
+}
+
+void tst_QFuture::onFailedTestCallables()
+{
+ QVERIFY(runForCallable([&] { return -1; }));
+ QVERIFY(runForCallable(foo));
+ QVERIFY(runForCallable(&foo));
+
+ std::function<int()> func = foo;
+ QVERIFY(runForCallable(func));
+
+ struct Functor1
+ {
+ int operator()() { return -1; }
+ static int foo() { return -1; }
+ };
+ QVERIFY(runForCallable(Functor1()));
+ QVERIFY(runForCallable(Functor1::foo));
+
+ struct Functor2
+ {
+ int operator()() const { return -1; }
+ static int foo() { return -1; }
+ };
+ QVERIFY(runForCallable(Functor2()));
+
+ struct Functor3
+ {
+ int operator()() const noexcept { return -1; }
+ static int foo() { return -1; }
+ };
+ QVERIFY(runForCallable(Functor3()));
+}
+
+template<class Callable>
+bool runOnFailedForMoveOnly(Callable &&callable)
+{
+ QFutureInterface<UniquePtr> promise;
+ auto future = promise.future();
+
+ auto failedFuture = future.onFailed(std::forward<Callable>(callable));
+
+ promise.reportStarted();
+ QException e;
+ promise.reportException(e);
+ promise.reportFinished();
+
+ return *failedFuture.takeResult() == -1;
+}
+
+void tst_QFuture::onFailedForMoveOnlyTypes()
+{
+ QVERIFY(runOnFailedForMoveOnly([](const QException &) { return std::make_unique<int>(-1); }));
+ QVERIFY(runOnFailedForMoveOnly([] { return std::make_unique<int>(-1); }));
+}
+
+#endif // QT_NO_EXCEPTIONS
+
+void tst_QFuture::onCanceled()
+{
+ // Canceled int future
+ {
+ auto future = createCanceledFuture<int>().then([](int) { return 42; }).onCanceled([] {
+ return -1;
+ });
+ QCOMPARE(future.result(), -1);
+ }
+
+ // Canceled void future
+ {
+ int checkpoint = 0;
+ auto future = createCanceledFuture<void>().then([&] { checkpoint = 42; }).onCanceled([&] {
+ checkpoint = -1;
+ });
+ QCOMPARE(checkpoint, -1);
+ }
+
+ // onCanceled propagates result
+ {
+ QFutureInterface<int> promise;
+ auto future =
+ promise.future().then([](int res) { return res; }).onCanceled([] { return -1; });
+
+ promise.reportStarted();
+ promise.reportResult(42);
+ promise.reportFinished();
+ QCOMPARE(future.result(), 42);
+ }
+
+ // onCanceled propagates move-only result
+ {
+ QFutureInterface<UniquePtr> promise;
+ auto future = promise.future().then([](UniquePtr res) { return res; }).onCanceled([] {
+ return std::make_unique<int>(-1);
+ });
+
+ promise.reportStarted();
+ promise.reportAndMoveResult(std::make_unique<int>(42));
+ promise.reportFinished();
+ QCOMPARE(*future.takeResult(), 42);
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // onCanceled propagates exceptions
+ {
+ QFutureInterface<int> promise;
+ auto future = promise.future()
+ .then([](int res) {
+ throw std::runtime_error("error");
+ return res;
+ })
+ .onCanceled([] { return 2; })
+ .onFailed([] { return 3; });
+
+ promise.reportStarted();
+ promise.reportResult(1);
+ promise.reportFinished();
+ QCOMPARE(future.result(), 3);
+ }
+
+ // onCanceled throws
+ {
+ auto future = createCanceledFuture<int>()
+ .then([](int) { return 42; })
+ .onCanceled([] {
+ throw std::runtime_error("error");
+ return -1;
+ })
+ .onFailed([] { return -2; });
+
+ QCOMPARE(future.result(), -2);
+ }
+
+#endif // QT_NO_EXCEPTIONS
+}
+
+void tst_QFuture::cancelContinuations()
+{
+ // The chain is cancelled in the middle of execution of continuations
+ {
+ QPromise<int> promise;
+
+ int checkpoint = 0;
+ auto future = promise.future().then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).then([&](int value) {
+ ++checkpoint;
+ promise.future().cancel();
+ return value + 1;
+ }).then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).onCanceled([] {
+ return -1;
+ });
+
+ promise.start();
+ promise.addResult(42);
+ promise.finish();
+
+ QCOMPARE(future.result(), -1);
+ QCOMPARE(checkpoint, 2);
+ }
+
+ // The chain is cancelled before the execution of continuations
+ {
+ auto f = QtFuture::makeReadyValueFuture(42);
+ f.cancel();
+
+ int checkpoint = 0;
+ auto future = f.then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).onCanceled([] {
+ return -1;
+ });
+
+ QCOMPARE(future.result(), -1);
+ QCOMPARE(checkpoint, 0);
+ }
+
+ // The chain is canceled partially, through an intermediate future
+ {
+ QPromise<int> promise;
+
+ int checkpoint = 0;
+ auto intermediate = promise.future().then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ });
+
+ auto future = intermediate.then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).onCanceled([] {
+ return -1;
+ });
+
+ promise.start();
+ promise.addResult(42);
+
+ // This should cancel only the chain starting from intermediate
+ intermediate.cancel();
+
+ promise.finish();
+
+ QCOMPARE(future.result(), -1);
+ QCOMPARE(checkpoint, 1);
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // The chain is cancelled in the middle of execution of continuations,
+ // while there's an exception in the chain, which is handled inside
+ // the continuations.
+ {
+ QPromise<int> promise;
+
+ int checkpoint = 0;
+ auto future = promise.future().then([&](int value) {
+ ++checkpoint;
+ throw QException();
+ return value + 1;
+ }).then([&](QFuture<int> future) {
+ try {
+ auto res = future.result();
+ Q_UNUSED(res);
+ } catch (const QException &) {
+ ++checkpoint;
+ }
+ return 2;
+ }).then([&](int value) {
+ ++checkpoint;
+ promise.future().cancel();
+ return value + 1;
+ }).then([&](int value) {
+ ++checkpoint;
+ return value + 1;
+ }).onCanceled([] {
+ return -1;
+ });
+
+ promise.start();
+ promise.addResult(42);
+ promise.finish();
+
+ QCOMPARE(future.result(), -1);
+ QCOMPARE(checkpoint, 3);
+ }
+#endif // QT_NO_EXCEPTIONS
+
+ // Check notifications from QFutureWatcher
+ {
+ QPromise<void> p;
+ auto f = p.future();
+
+ auto f1 = f.then([] {});
+ auto f2 = f1.then([] {});
+
+ QFutureWatcher<void> watcher1, watcher2;
+ int state = 0;
+ QObject::connect(&watcher1, &QFutureWatcher<void>::started, [&] {
+ QCOMPARE(state, 0);
+ ++state;
+ });
+ QObject::connect(&watcher1, &QFutureWatcher<void>::canceled, [&] {
+ QCOMPARE(state, 1);
+ ++state;
+ });
+ QObject::connect(&watcher1, &QFutureWatcher<void>::finished, [&] {
+ QCOMPARE(state, 2);
+ ++state;
+ });
+ QObject::connect(&watcher2, &QFutureWatcher<void>::started, [&] {
+ QCOMPARE(state, 3);
+ ++state;
+ });
+ QObject::connect(&watcher2, &QFutureWatcher<void>::canceled, [&] {
+ QCOMPARE(state, 4);
+ ++state;
+ });
+ QObject::connect(&watcher2, &QFutureWatcher<int>::finished, [&] {
+ QCOMPARE(state, 5);
+ ++state;
+ });
+
+ watcher1.setFuture(f1);
+ watcher2.setFuture(f2);
+
+ p.start();
+ f.cancel();
+ p.finish();
+
+ qApp->processEvents();
+
+ QCOMPARE(state, 6);
+ QVERIFY(watcher1.isFinished());
+ QVERIFY(watcher1.isCanceled());
+ QVERIFY(watcher2.isFinished());
+ QVERIFY(watcher2.isCanceled());
+ }
+
+ // Cancel continuations with context (QTBUG-108790)
+ {
+ // This test should pass with ASan
+ auto future = QtConcurrent::run([] {});
+ future.then(this, [] {});
+ future.waitForFinished();
+ future.cancel();
+ }
+}
+
+void tst_QFuture::continuationsWithContext_data()
+{
+ QTest::addColumn<bool>("inOtherThread");
+ QTest::addRow("in-other-thread") << true;
+ QTest::addRow("in-main-thread-qtbug119406") << false;
+}
+
+void tst_QFuture::continuationsWithContext()
+{
+ QFETCH(bool, inOtherThread);
+
+ auto tstThread = QThread::currentThread();
+ QThread *thread = inOtherThread ? new QThread
+ : tstThread;
+ auto context = new QObject();
+
+ const auto cleanupGuard = qScopeGuard([&] {
+ context->deleteLater();
+ if (thread != tstThread) {
+ thread->quit();
+ thread->wait();
+ delete thread;
+ }
+ });
+
+ if (inOtherThread) {
+ thread->start();
+ context->moveToThread(thread);
+ }
+
+ // .then()
+ {
+ QPromise<int> promise;
+ auto future = promise.future()
+ .then([&](int val) {
+ if (QThread::currentThread() != tstThread)
+ return 0;
+ return val + 1;
+ })
+ .then(context,
+ [&](int val) {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return val + 1;
+ })
+ .then([&](int val) {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return val + 1;
+ });
+ promise.start();
+ promise.addResult(0);
+ promise.finish();
+ QCOMPARE(future.result(), 3);
+ }
+
+ // .onCanceled
+ {
+ QPromise<int> promise;
+ auto future = promise.future()
+ .onCanceled(context,
+ [&] {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return 1;
+ })
+ .then([&](int val) {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return val + 1;
+ });
+ promise.start();
+ promise.future().cancel();
+ promise.finish();
+ QCOMPARE(future.result(), 2);
+ }
+
+ // Cancellation when the context object is destroyed
+ {
+ // Use something like QWidget which deletes its children early, i.e.
+ // before ~QObject() runs. This behavior can lead to side-effects
+ // like QPointers to the parent not being set to nullptr during child
+ // object destruction.
+ QPointer shortLivedContext = new FakeQWidget();
+ shortLivedContext->moveToThread(thread);
+
+ QPromise<int> promise;
+ auto future = promise.future()
+ .then(shortLivedContext, [&](int val) {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return val + 1000;
+ })
+ .onCanceled([&, ptr=QPointer(shortLivedContext)] {
+ if (QThread::currentThread() != thread)
+ return 0;
+ if (ptr)
+ return 1;
+ return 2;
+ });
+ promise.start();
+
+ QMetaObject::invokeMethod(shortLivedContext, [&]() {
+ delete shortLivedContext;
+ }, inOtherThread ? Qt::BlockingQueuedConnection
+ : Qt::DirectConnection);
+
+ promise.finish();
+ QCOMPARE(future.result(), 2);
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // .onFaled()
+ {
+ QPromise<void> promise;
+ auto future = promise.future()
+ .then([&] {
+ if (QThread::currentThread() != tstThread)
+ return 0;
+ throw std::runtime_error("error");
+ })
+ .onFailed(context,
+ [&] {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return 1;
+ })
+ .then([&](int val) {
+ if (QThread::currentThread() != thread)
+ return 0;
+ return val + 1;
+ });
+ promise.start();
+ promise.finish();
+ QCOMPARE(future.result(), 2);
+ }
+#endif // QT_NO_EXCEPTIONS
+}
+
+void tst_QFuture::continuationsWithMoveOnlyLambda()
+{
+ // .then()
+ {
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future = QtFuture::makeReadyVoidFuture()
+ .then([p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+ // .then() with thread pool
+ {
+ QThreadPool pool;
+
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future = QtFuture::makeReadyVoidFuture()
+ .then(&pool, [p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+ // .then() with context
+ {
+ QObject object;
+
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future = QtFuture::makeReadyVoidFuture()
+ .then(&object, [p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+
+ // .onCanceled()
+ {
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future =
+ createCanceledFuture<int>().onCanceled([p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+
+ // .onCanceled() with context
+ {
+ QObject object;
+
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future = createCanceledFuture<int>().onCanceled(
+ &object, [p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // .onFailed()
+ {
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future = QtFuture::makeExceptionalFuture<int>(QException())
+ .onFailed([p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+ // .onFailed() with context
+ {
+ QObject object;
+
+ std::unique_ptr<int> uniquePtr(new int(42));
+ auto future = QtFuture::makeExceptionalFuture<int>(QException())
+ .onFailed(&object, [p = std::move(uniquePtr)] { return *p; });
+ QCOMPARE(future.result(), 42);
+ }
+#endif // QT_NO_EXCEPTIONS
+}
+
+void tst_QFuture::testSingleResult(const UniquePtr &p)
+{
+ QVERIFY(p.get() != nullptr);
+}
+
+void tst_QFuture::testSingleResult(const std::vector<int> &v)
+{
+ QVERIFY(!v.empty());
+}
+
+template<class T>
+void tst_QFuture::testSingleResult(const T &unknown)
+{
+ Q_UNUSED(unknown)
+}
+
+
+template<class T>
+void tst_QFuture::testFutureTaken(QFuture<T> &noMoreFuture)
+{
+ QCOMPARE(noMoreFuture.isValid(), false);
+ QCOMPARE(noMoreFuture.resultCount(), 0);
+ QCOMPARE(noMoreFuture.progressValue(), 0);
+}
+
+template<class T>
+void tst_QFuture::testTakeResults(QFuture<T> future, size_type resultCount)
+{
+ auto copy = future;
+ QVERIFY(future.isFinished());
+ QVERIFY(future.isValid());
+ QCOMPARE(size_type(future.resultCount()), resultCount);
+ QVERIFY(copy.isFinished());
+ QVERIFY(copy.isValid());
+ QCOMPARE(size_type(copy.resultCount()), resultCount);
+
+ auto vec = future.takeResults();
+ QCOMPARE(vec.size(), resultCount);
+
+ for (const auto &r : vec) {
+ testSingleResult(r);
+ if (QTest::currentTestFailed())
+ return;
+ }
+
+ testFutureTaken(future);
+ if (QTest::currentTestFailed())
+ return;
+ testFutureTaken(copy);
+}
+
+#if 0
+void tst_QFuture::takeResults()
+{
+ // Test takeResults() for movable types (whether or not copyable).
+
+ // std::unique_ptr<int> supports only move semantics:
+ QFutureInterface<UniquePtr> moveIface;
+ moveIface.reportStarted();
+
+ // std::vector<int> supports both copy and move:
+ QFutureInterface<std::vector<int>> copyIface;
+ copyIface.reportStarted();
+
+ const int expectedCount = 10;
+
+ for (int i = 0; i < expectedCount; ++i) {
+ QVERIFY(moveIface.reportAndMoveResult(UniquePtr{new int(0b101010)}, i));
+ QVERIFY(copyIface.reportAndMoveResult(std::vector<int>{1,2,3,4,5}, i));
+ }
+
+ moveIface.reportFinished();
+ copyIface.reportFinished();
+
+ testTakeResults(moveIface.future(), size_type(expectedCount));
+ if (QTest::currentTestFailed())
+ return;
+
+ testTakeResults(copyIface.future(), size_type(expectedCount));
+}
+#endif
+
+void tst_QFuture::takeResult()
+{
+ QFutureInterface<UniquePtr> iface;
+ iface.reportStarted();
+ QVERIFY(iface.reportAndMoveResult(UniquePtr{new int(0b101010)}, 0));
+ iface.reportFinished();
+
+ auto future = iface.future();
+ QVERIFY(future.isFinished());
+ QVERIFY(future.isValid());
+ QCOMPARE(future.resultCount(), 1);
+
+ auto result = future.takeResult();
+ testFutureTaken(future);
+ if (QTest::currentTestFailed())
+ return;
+ testSingleResult(result);
+}
+
+void tst_QFuture::runAndTake()
+{
+ // Test if a 'moving' future can be used by
+ // QtConcurrent::run.
+
+ auto rabbit = [](){
+ // Let's wait a bit to give the test below some time
+ // to sync up with us with its watcher.
+ QThread::currentThread()->sleep(std::chrono::milliseconds{100});
+ return UniquePtr(new int(10));
+ };
+
+ QTestEventLoop loop;
+ QFutureWatcher<UniquePtr> watcha;
+ connect(&watcha, &QFutureWatcher<UniquePtr>::finished, [&loop](){
+ loop.exitLoop();
+ });
+
+ auto gotcha = QtConcurrent::run(rabbit);
+ watcha.setFuture(gotcha);
+
+ loop.enterLoop(500ms);
+ if (loop.timeout())
+ QSKIP("Failed to run the task, nothing to test");
+
+ gotcha = watcha.future();
+#if 0
+ // TODO: enable when QFuture::takeResults() is enabled
+ testTakeResults(gotcha, size_type(1));
+#endif
+}
+
+void tst_QFuture::resultsReadyAt_data()
+{
+ QTest::addColumn<bool>("testMove");
+
+ QTest::addRow("reportResult") << false;
+ QTest::addRow("reportAndMoveResult") << true;
+}
+
+void tst_QFuture::resultsReadyAt()
+{
+ QFETCH(const bool, testMove);
+
+ QFutureInterface<int> iface;
+ QFutureWatcher<int> watcher;
+ watcher.setFuture(iface.future());
+
+ QTestEventLoop eventProcessor;
+ connect(&watcher, &QFutureWatcher<int>::finished, &eventProcessor, &QTestEventLoop::exitLoop);
+
+ const int nExpectedResults = 4;
+ int reported = 0;
+ int taken = 0;
+ connect(&watcher, &QFutureWatcher<int>::resultsReadyAt,
+ [&iface, &reported, &taken](int begin, int end)
+ {
+ auto future = iface.future();
+ QVERIFY(end - begin > 0);
+ for (int i = begin; i < end; ++i, ++reported) {
+ QVERIFY(future.isResultReadyAt(i));
+ taken |= 1 << i;
+ }
+ });
+
+ auto report = [&iface, testMove](int index)
+ {
+ int dummyResult = 0b101010;
+ if (testMove)
+ QVERIFY(iface.reportAndMoveResult(std::move(dummyResult), index));
+ else
+ QVERIFY(iface.reportResult(&dummyResult, index));
+ };
+
+ const QSignalSpy readyCounter(&watcher, &QFutureWatcher<int>::resultsReadyAt);
+ QTimer::singleShot(0, [&iface, &report]{
+ // With filter mode == true, the result may go into the pending results.
+ // Reporting it as ready will allow an application to try and access the
+ // result, crashing on invalid (store.end()) iterator dereferenced.
+ iface.setFilterMode(true);
+ iface.reportStarted();
+ report(0);
+ report(1);
+ // This one - should not be reported (it goes into pending):
+ report(3);
+ // Let's close the 'gap' and make them all ready:
+ report(-1);
+ iface.reportFinished();
+ });
+
+ // Run event loop, QCoreApplication::postEvent is in use
+ // in QFutureInterface:
+ eventProcessor.enterLoop(DefaultWaitTime);
+ QVERIFY(!eventProcessor.timeout());
+ if (QTest::currentTestFailed()) // Failed in our lambda observing 'ready at'
+ return;
+
+ QCOMPARE(reported, nExpectedResults);
+ QCOMPARE(nExpectedResults, iface.future().resultCount());
+ QCOMPARE(readyCounter.size(), 3);
+ QCOMPARE(taken, 0b1111);
+}
+
+template <class T>
+auto makeFutureInterface(T &&result)
+{
+ QFutureInterface<T> f;
+
+ f.reportStarted();
+ f.reportResult(std::forward<T>(result));
+ f.reportFinished();
+
+ return f;
+}
+
+void tst_QFuture::takeResultWorksForTypesWithoutDefaultCtor()
+{
+ struct Foo
+ {
+ Foo() = delete;
+ explicit Foo(int i) : _i(i) {}
+
+ int _i = -1;
+ };
+
+ auto f = makeFutureInterface(Foo(42));
+
+ QCOMPARE(f.takeResult()._i, 42);
+}
+void tst_QFuture::canceledFutureIsNotValid()
+{
+ auto f = makeFutureInterface(42);
+
+ f.cancel();
+
+ QVERIFY(!f.isValid());
+}
+
+void tst_QFuture::signalConnect()
+{
+ const int intValue = 42;
+ const double doubleValue = 42.5;
+ const QString stringValue = "42";
+
+ using TupleType = std::tuple<int, double, QString>;
+ const TupleType tuple(intValue, doubleValue, stringValue);
+
+ using PairType = std::pair<int, double>;
+ const PairType pair(intValue, doubleValue);
+
+ // No arg
+ {
+ SenderObject sender;
+ auto future =
+ QtFuture::connect(&sender, &SenderObject::noArgSignal).then([] { return true; });
+ sender.emitNoArg();
+ QCOMPARE(future.result(), true);
+ }
+
+ // One arg
+ {
+ SenderObject sender;
+ auto future = QtFuture::connect(&sender, &SenderObject::intArgSignal).then([](int value) {
+ return value;
+ });
+ sender.emitIntArg(42);
+ QCOMPARE(future.result(), 42);
+ }
+
+ // Const ref arg
+ {
+ SenderObject sender;
+ auto future =
+ QtFuture::connect(&sender, &SenderObject::constRefArg).then([](QString value) {
+ return value;
+ });
+ sender.emitConstRefArg(QString("42"));
+ QCOMPARE(future.result(), "42");
+ }
+
+ // Multiple args
+ {
+ SenderObject sender;
+ auto future =
+ QtFuture::connect(&sender, &SenderObject::multipleArgs).then([](TupleType values) {
+ return values;
+ });
+ sender.emitMultipleArgs(intValue, doubleValue, stringValue);
+ auto result = future.result();
+ QCOMPARE(result, tuple);
+ }
+
+ // Single std::tuple arg
+ {
+ SenderObject sender;
+ QFuture<TupleType> future = QtFuture::connect(&sender, &SenderObject::tupleArgSignal);
+ sender.emitTupleArgSignal(tuple);
+ auto result = future.result();
+ QCOMPARE(result, tuple);
+ }
+
+ // Multi-args signal(int, std::tuple)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<int, TupleType>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithTupleSignal1);
+ sender.emitMultiArgsWithTupleSignal1(142, tuple);
+ const auto [v, t] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(t, tuple);
+ }
+
+ // Multi-args signal(std::tuple, int)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<TupleType, int>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithTupleSignal2);
+ sender.emitMultiArgsWithTupleSignal2(tuple, 142);
+ const auto [t, v] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(t, tuple);
+ }
+
+ // Multi-args signal(int, std::pair)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<int, PairType>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithPairSignal1);
+ sender.emitMultiArgsWithPairSignal1(142, pair);
+ const auto [v, p] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(p, pair);
+ }
+
+ // Multi-args signal(std::pair, int)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<PairType, int>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithPairSignal2);
+ sender.emitMultiArgsWithPairSignal2(pair, 142);
+ const auto [p, v] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(p, pair);
+ }
+
+ // No arg private signal
+ {
+ SenderObject sender;
+ auto future = QtFuture::connect(&sender, &SenderObject::noArgPrivateSignal).then([] {
+ return true;
+ });
+ sender.emitNoArgPrivateSignal();
+ QCOMPARE(future.result(), true);
+ }
+
+ // One arg private signal
+ {
+ SenderObject sender;
+ auto future =
+ QtFuture::connect(&sender, &SenderObject::intArgPrivateSignal).then([](int value) {
+ return value;
+ });
+ sender.emitIntArgPrivateSignal(42);
+ QCOMPARE(future.result(), 42);
+ }
+
+ // Multi-args private signal
+ {
+ SenderObject sender;
+ auto future = QtFuture::connect(&sender, &SenderObject::multiArgsPrivateSignal)
+ .then([](TupleType values) { return values; });
+ sender.emitMultiArgsPrivateSignal(intValue, doubleValue, stringValue);
+ auto result = future.result();
+ QCOMPARE(result, tuple);
+ }
+
+ // Single std::tuple arg private signal
+ {
+ SenderObject sender;
+ QFuture<TupleType> future =
+ QtFuture::connect(&sender, &SenderObject::tupleArgPrivateSignal);
+ sender.emitTupleArgPrivateSignal(tuple);
+ auto result = future.result();
+ QCOMPARE(result, tuple);
+ }
+
+ // Multi-args private signal(int, std::tuple)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<int, TupleType>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithTuplePrivateSignal1);
+ sender.emitMultiArgsWithTuplePrivateSignal1(142, tuple);
+ const auto [v, t] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(t, tuple);
+ }
+
+ // Multi-args private signal(std::tuple, int)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<TupleType, int>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithTuplePrivateSignal2);
+ sender.emitMultiArgsWithTuplePrivateSignal2(tuple, 142);
+ const auto [t, v] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(t, tuple);
+ }
+
+ // Multi-args private signal(int, std::pair)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<int, PairType>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithPairPrivateSignal1);
+ sender.emitMultiArgsWithPairPrivateSignal1(142, pair);
+ const auto [v, p] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(p, pair);
+ }
+
+ // Multi-args private signal(std::pair, int)
+ {
+ SenderObject sender;
+ QFuture<std::tuple<PairType, int>> future =
+ QtFuture::connect(&sender, &SenderObject::multiArgsWithPairPrivateSignal2);
+ sender.emitMultiArgsWithPairPrivateSignal2(pair, 142);
+ const auto [p, v] = future.result();
+ QCOMPARE(v, 142);
+ QCOMPARE(p, pair);
+ }
+
+ // Sender destroyed
+ {
+ SenderObject *sender = new SenderObject();
+
+ auto future = QtFuture::connect(sender, &SenderObject::intArgSignal);
+
+ QSignalSpy spy(sender, &QObject::destroyed);
+ sender->deleteLater();
+
+ spy.wait();
+
+ QVERIFY(future.isCanceled());
+ QVERIFY(!future.isValid());
+ }
+
+ // Signal emitted, causing Sender to be destroyed
+ {
+ SenderObject *sender = new SenderObject();
+
+ auto future = QtFuture::connect(sender, &SenderObject::intArgSignal);
+ future.then([sender](int) {
+ // Scenario: Sender no longer needed, so it's deleted
+ delete sender;
+ });
+
+ QSignalSpy spy(sender, &SenderObject::destroyed);
+ emit sender->intArgSignal(5);
+ spy.wait();
+
+ QVERIFY(future.isFinished());
+ QVERIFY(!future.isCanceled());
+ QVERIFY(future.isValid());
+ }
+
+ // Connect to nullptr
+ {
+ SenderObject *sender = nullptr;
+ auto future = QtFuture::connect(sender, &SenderObject::intArgSignal);
+ QVERIFY(future.isFinished());
+ QVERIFY(future.isCanceled());
+ QVERIFY(!future.isValid());
+ }
+
+ // Connect to non-signal
+ {
+ SenderObject sender;
+
+#if defined(Q_CC_MSVC_ONLY) && (Q_CC_MSVC < 1940 || __cplusplus < 202002L)
+#define EXPECT_FUTURE_CONNECT_FAIL() QEXPECT_FAIL("", "QTBUG-101761, test fails on Windows/MSVC", Continue)
+#else
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in SenderObject");
+#define EXPECT_FUTURE_CONNECT_FAIL()
+#endif
+
+ auto future = QtFuture::connect(&sender, &SenderObject::emitNoArg);
+ EXPECT_FUTURE_CONNECT_FAIL();
+ QVERIFY(future.isFinished());
+ EXPECT_FUTURE_CONNECT_FAIL();
+ QVERIFY(future.isCanceled());
+ EXPECT_FUTURE_CONNECT_FAIL();
+ QVERIFY(!future.isValid());
+#undef EXPECT_FUTURE_CONNECT_FAIL
+ }
+}
+
+void tst_QFuture::waitForFinished()
+{
+ QFutureInterface<void> fi;
+ auto future = fi.future();
+
+ QScopedPointer<QThread> waitingThread (QThread::create([&] {
+ future.waitForFinished();
+ }));
+
+ waitingThread->start();
+
+ QVERIFY(!waitingThread->wait(200));
+ QVERIFY(!waitingThread->isFinished());
+
+ fi.reportStarted();
+ QVERIFY(!waitingThread->wait(200));
+ QVERIFY(!waitingThread->isFinished());
+
+ fi.reportFinished();
+
+ QVERIFY(waitingThread->wait());
+ QVERIFY(waitingThread->isFinished());
+}
+
+void tst_QFuture::rejectResultOverwrite_data()
+{
+ QTest::addColumn<bool>("filterMode");
+ QTest::addColumn<QList<int>>("initResults");
+
+ QTest::addRow("filter-mode-on-1-result") << true << QList<int>({ 456 });
+ QTest::addRow("filter-mode-on-N-results") << true << QList<int>({ 456, 789 });
+ QTest::addRow("filter-mode-off-1-result") << false << QList<int>({ 456 });
+ QTest::addRow("filter-mode-off-N-results") << false << QList<int>({ 456, 789 });
+}
+
+void tst_QFuture::rejectResultOverwrite()
+{
+ QFETCH(bool, filterMode);
+ QFETCH(QList<int>, initResults);
+
+ QFutureInterface<int> iface;
+ iface.setFilterMode(filterMode);
+ auto f = iface.future();
+ QFutureWatcher<int> watcher;
+ watcher.setFuture(f);
+
+ QTestEventLoop eventProcessor;
+ // control the loop by suspend
+ connect(&watcher, &QFutureWatcher<int>::suspending, &eventProcessor, &QTestEventLoop::exitLoop);
+ // internal machinery always emits resultsReadyAt
+ QSignalSpy resultCounter(&watcher, &QFutureWatcher<int>::resultsReadyAt);
+
+ // init
+ if (initResults.size() == 1)
+ QVERIFY(iface.reportResult(initResults[0]));
+ else
+ QVERIFY(iface.reportResults(initResults));
+ QCOMPARE(f.resultCount(), initResults.size());
+ QCOMPARE(f.resultAt(0), initResults[0]);
+ QCOMPARE(f.results(), initResults);
+
+ QTimer::singleShot(50, [&f]() {
+ f.suspend(); // should exit the loop
+ });
+ // Run event loop, QCoreApplication::postEvent is in use
+ // in QFutureInterface:
+ eventProcessor.enterLoop(DefaultWaitTime);
+ QVERIFY(!eventProcessor.timeout());
+ QCOMPARE(resultCounter.size(), 1);
+ f.resume();
+
+ // overwrite with lvalue
+ {
+ int result = -1;
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResult(result, 0));
+ QCOMPARE(f.resultCount(), originalCount);
+ QCOMPARE(f.resultAt(0), initResults[0]);
+ }
+ // overwrite with rvalue
+ {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResult(-1, 0));
+ QCOMPARE(f.resultCount(), originalCount);
+ QCOMPARE(f.resultAt(0), initResults[0]);
+ }
+ // overwrite with array
+ {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResults(QList<int> { -1, -2, -3 }, 0));
+ QCOMPARE(f.resultCount(), originalCount);
+ QCOMPARE(f.resultAt(0), initResults[0]);
+ }
+
+ // special case: add result by different index, overlapping with the vector
+ if (initResults.size() > 1) {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResult(-1, 1));
+ QCOMPARE(f.resultCount(), originalCount);
+ QCOMPARE(f.resultAt(1), initResults[1]);
+ }
+
+ QTimer::singleShot(50, [&f]() {
+ f.suspend(); // should exit the loop
+ });
+ eventProcessor.enterLoop(DefaultWaitTime);
+ QVERIFY(!eventProcessor.timeout());
+ QCOMPARE(resultCounter.size(), 1);
+ f.resume();
+ QCOMPARE(f.results(), initResults);
+}
+
+void tst_QFuture::rejectPendingResultOverwrite()
+{
+ QFETCH(bool, filterMode);
+ QFETCH(QList<int>, initResults);
+
+ QFutureInterface<int> iface;
+ iface.setFilterMode(filterMode);
+ auto f = iface.future();
+ QFutureWatcher<int> watcher;
+ watcher.setFuture(f);
+
+ QTestEventLoop eventProcessor;
+ // control the loop by suspend
+ connect(&watcher, &QFutureWatcher<int>::suspending, &eventProcessor, &QTestEventLoop::exitLoop);
+ // internal machinery always emits resultsReadyAt
+ QSignalSpy resultCounter(&watcher, &QFutureWatcher<int>::resultsReadyAt);
+
+ // init
+ if (initResults.size() == 1)
+ QVERIFY(iface.reportResult(initResults[0], 1));
+ else
+ QVERIFY(iface.reportResults(initResults, 1));
+ QCOMPARE(f.resultCount(), 0); // not visible yet
+ if (!filterMode) {
+ QCOMPARE(f.resultAt(1), initResults[0]);
+ QCOMPARE(f.results(), initResults);
+
+ QTimer::singleShot(50, [&f]() {
+ f.suspend(); // should exit the loop
+ });
+ // Run event loop, QCoreApplication::postEvent is in use
+ // in QFutureInterface:
+ eventProcessor.enterLoop(DefaultWaitTime);
+ QVERIFY(!eventProcessor.timeout());
+ QCOMPARE(resultCounter.size(), 1);
+ f.resume();
+ }
+
+ // overwrite with lvalue
+ {
+ int result = -1;
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResult(result, 1));
+ QCOMPARE(f.resultCount(), originalCount);
+ if (!filterMode)
+ QCOMPARE(f.resultAt(1), initResults[0]);
+ }
+ // overwrite with rvalue
+ {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResult(-1, 1));
+ QCOMPARE(f.resultCount(), originalCount);
+ if (!filterMode)
+ QCOMPARE(f.resultAt(1), initResults[0]);
+ }
+ // overwrite with array
+ {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResults(QList<int> { -1, -2 }, 1));
+ QCOMPARE(f.resultCount(), originalCount);
+ if (!filterMode)
+ QCOMPARE(f.resultAt(1), initResults[0]);
+ }
+ // special case: add result by different index, overlapping with the vector
+ if (initResults.size() > 1) {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!iface.reportResult(-1, 2));
+ QCOMPARE(f.resultCount(), originalCount);
+ if (!filterMode)
+ QCOMPARE(f.resultAt(2), initResults[1]);
+ }
+
+ if (!filterMode) {
+ QTimer::singleShot(50, [&f]() {
+ f.suspend(); // should exit the loop
+ });
+ eventProcessor.enterLoop(DefaultWaitTime);
+ QVERIFY(!eventProcessor.timeout());
+ QCOMPARE(resultCounter.size(), 1);
+ f.resume();
+ }
+
+ QVERIFY(iface.reportResult(123, 0)); // make results at 0 and 1 accessible
+ QCOMPARE(f.resultCount(), initResults.size() + 1);
+ QCOMPARE(f.resultAt(1), initResults[0]);
+ initResults.prepend(123);
+ QCOMPARE(f.results(), initResults);
+}
+
+void tst_QFuture::createReadyFutures()
+{
+#if QT_DEPRECATED_SINCE(6, 10)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ // using const T &
+ {
+ const int val = 42;
+ QFuture<int> f = QtFuture::makeReadyFuture(val);
+ QCOMPARE(f.result(), val);
+ }
+
+ // using T
+ {
+ int val = 42;
+ QFuture<int> f = QtFuture::makeReadyFuture(val);
+ QCOMPARE(f.result(), val);
+ }
+
+ // using T &&
+ {
+ auto f = QtFuture::makeReadyFuture(std::make_unique<int>(42));
+ QCOMPARE(*f.takeResult(), 42);
+ }
+
+ // using void
+ {
+ auto f = QtFuture::makeReadyFuture();
+ QVERIFY(f.isStarted());
+ QVERIFY(!f.isRunning());
+ QVERIFY(f.isFinished());
+ }
+
+ // using const QList<T> &
+ {
+ const QList<int> values { 1, 2, 3 };
+ auto f = QtFuture::makeReadyFuture(values);
+ QCOMPARE(f.resultCount(), 3);
+ QCOMPARE(f.results(), values);
+ }
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 10)
+
+ // test makeReadyValueFuture<T>()
+ {
+ const int val = 42;
+ auto f = QtFuture::makeReadyValueFuture(val);
+ QCOMPARE_EQ(f.result(), val);
+
+ int otherVal = 42;
+ f = QtFuture::makeReadyValueFuture(otherVal);
+ QCOMPARE_EQ(f.result(), otherVal);
+ }
+ {
+ auto f = QtFuture::makeReadyValueFuture(std::make_unique<int>(42));
+ QCOMPARE(*f.takeResult(), 42);
+ }
+ // test makeReadyVoidFuture()
+ {
+ auto f = QtFuture::makeReadyVoidFuture();
+ QVERIFY(f.isStarted());
+ QVERIFY(!f.isRunning());
+ QVERIFY(f.isFinished());
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // using QException
+ {
+ QException e;
+ auto f = QtFuture::makeExceptionalFuture<int>(e);
+ bool caught = false;
+ try {
+ f.result();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
+
+ // using std::exception_ptr and QFuture<void>
+ {
+ auto exception = std::make_exception_ptr(TestException());
+ auto f = QtFuture::makeExceptionalFuture(exception);
+ bool caught = false;
+ try {
+ f.waitForFinished();
+ } catch (TestException &) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ }
+#endif
+
+ // testing makeReadyRangeFuture with various containers
+ {
+ const QList<int> expectedResult{1, 2, 3};
+
+ const QList<int> list{1, 2, 3};
+ auto f = QtFuture::makeReadyRangeFuture(list);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ QVarLengthArray<int> varArray{1, 2, 3};
+ f = QtFuture::makeReadyRangeFuture(varArray);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ std::vector<int> vec{1, 2, 3};
+ f = QtFuture::makeReadyRangeFuture(std::move(vec));
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ f = QtFuture::makeReadyRangeFuture(std::array<int, 3>{1, 2, 3});
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ f = QtFuture::makeReadyRangeFuture(std::list<int>{1, 2, 3});
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ std::forward_list<int> fwdlist{1, 2, 3};
+ f = QtFuture::makeReadyRangeFuture(fwdlist);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ const QSet<int> qset{1, 2, 3};
+ f = QtFuture::makeReadyRangeFuture(qset);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ auto result = f.results();
+ std::sort(result.begin(), result.end());
+ QCOMPARE_EQ(result, expectedResult);
+
+ const QMap<QString, int> qmap{
+ {"one", 1},
+ {"two", 2},
+ {"three", 3}
+ };
+ f = QtFuture::makeReadyRangeFuture(qmap);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ result = f.results();
+ std::sort(result.begin(), result.end());
+ QCOMPARE_EQ(result, expectedResult);
+
+ std::set<int> stdset{1, 2, 3};
+ f = QtFuture::makeReadyRangeFuture(stdset);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ result = f.results();
+ std::sort(result.begin(), result.end());
+ QCOMPARE_EQ(result, expectedResult);
+
+ // testing ValueType[N] overload
+ const int c_array[] = {1, 2, 3};
+ f = QtFuture::makeReadyRangeFuture(c_array);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ f = QtFuture::makeReadyRangeFuture({1, 2, 3});
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+ }
+ // testing makeReadyRangeFuture with a more complex underlying type
+ {
+ QObject obj1;
+ QObject obj2;
+ QObject obj3;
+
+ const QList<QObject*> expectedResult{&obj1, &obj2, &obj3};
+
+ const QList<QObject*> list{&obj1, &obj2, &obj3};
+ auto f = QtFuture::makeReadyRangeFuture(list);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ std::list<QObject*> stdlist{&obj1, &obj2, &obj3};
+ f = QtFuture::makeReadyRangeFuture(std::move(stdlist));
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+
+ QObject* const c_array[] = {&obj1, &obj2, &obj3};
+ f = QtFuture::makeReadyRangeFuture(c_array);
+ QCOMPARE_EQ(f.resultCount(), 3);
+ QCOMPARE_EQ(f.results(), expectedResult);
+ }
+}
+
+void tst_QFuture::continuationsAfterReadyFutures()
+{
+ // continuations without a context
+ {
+ QFuture<int> f = QtFuture::makeReadyValueFuture(42)
+ .then([](int val) {
+ return val + 10;
+ })
+ .onCanceled([]() {
+ return -1;
+ });
+ QCOMPARE(f.result(), 52);
+ }
+ {
+ auto rangeF = QtFuture::makeReadyRangeFuture({1, 2, 3});
+ QFuture<int> f = rangeF
+ .then([vals = rangeF.results()](auto) {
+ return vals.last();
+ })
+ .onCanceled([]() {
+ return -1;
+ });
+ QCOMPARE(f.result(), 3);
+ }
+ {
+ QFuture<int> f = QtFuture::makeReadyVoidFuture()
+ .then([]() {
+ return 1;
+ })
+ .onCanceled([]() {
+ return -1;
+ });
+ QCOMPARE(f.result(), 1);
+ }
+#ifndef QT_NO_EXCEPTIONS
+ {
+ QException e;
+ QFuture<int> f = QtFuture::makeExceptionalFuture<int>(e)
+ .then([](int) {
+ return 1;
+ })
+ .onCanceled([]() {
+ return -1;
+ })
+ .onFailed([](const QException &) {
+ return -2;
+ });
+ QCOMPARE(f.result(), -2);
+ }
+#endif
+
+ // continuations with a context
+ QObject context;
+ {
+ QFuture<int> f = QtFuture::makeReadyValueFuture(42)
+ .then(&context, [](int val) {
+ return val + 10;
+ })
+ .onCanceled([]() {
+ return -1;
+ });
+ QCOMPARE(f.result(), 52);
+ }
+ {
+ auto rangeF = QtFuture::makeReadyRangeFuture({1, 2, 3});
+ QFuture<int> f = rangeF
+ .then(&context, [vals = rangeF.results()](auto) {
+ return vals.last();
+ })
+ .onCanceled([]() {
+ return -1;
+ });
+ QCOMPARE(f.result(), 3);
+ }
+ {
+ QFuture<int> f = QtFuture::makeReadyVoidFuture()
+ .then(&context, []() {
+ return 1;
+ })
+ .onCanceled([]() {
+ return -1;
+ });
+ QCOMPARE(f.result(), 1);
+ }
+#ifndef QT_NO_EXCEPTIONS
+ {
+ QException e;
+ QFuture<int> f = QtFuture::makeExceptionalFuture<int>(e)
+ .then(&context, [](int) {
+ return 1;
+ })
+ .onCanceled([]() {
+ return -1;
+ })
+ .onFailed([](const QException &) {
+ return -2;
+ });
+ QCOMPARE(f.result(), -2);
+ }
+#endif
+}
+
+void tst_QFuture::getFutureInterface()
+{
+ const int val = 42;
+ QFuture<int> f = QtFuture::makeReadyValueFuture(val);
+
+ auto interface = QFutureInterfaceBase::get(f);
+ QCOMPARE(interface.resultCount(), 1);
+}
+
+void tst_QFuture::convertQMetaType()
+{
+ const auto intType = QMetaType::fromType<QFuture<int>>();
+ const auto voidType = QMetaType::fromType<QFuture<void>>();
+
+ QVERIFY(QMetaType::canConvert(intType, voidType));
+
+ const int val = 42;
+ QFuture<int> f = QtFuture::makeReadyValueFuture(val);
+ auto variant = QVariant::fromValue(f);
+ QVERIFY(variant.convert(voidType));
+
+ const auto voidFuture = variant.value<QFuture<void>>();
+ QVERIFY(voidFuture.isValid());
+ QVERIFY(voidFuture.isFinished());
+}
+
+template<class OutputContainer>
+void testWhenAllIterators()
+{
+ QPromise<int> p0;
+ QPromise<int> p1;
+ QPromise<int> p2;
+ QList<QFuture<int>> futures = { p0.future(), p1.future(), p2.future() };
+
+ bool finished = false;
+ QFuture<OutputContainer> whenAll;
+ if constexpr (std::is_same_v<QList<QFuture<int>>, OutputContainer>)
+ whenAll = QtFuture::whenAll(futures.begin(), futures.end());
+ else
+ whenAll = QtFuture::whenAll<OutputContainer>(futures.begin(), futures.end());
+ whenAll.then([&](const OutputContainer &output) {
+ QCOMPARE(output.size(), 3u);
+ QCOMPARE(output[0].result(), 0);
+ QCOMPARE(output[1].result(), 1);
+ QCOMPARE(output[2].result(), 2);
+ finished = true;
+ });
+ QVERIFY(whenAll.isRunning());
+
+ p0.start();
+ p0.addResult(0);
+ p0.finish();
+ QVERIFY(whenAll.isRunning());
+
+ p2.start();
+ p2.addResult(2);
+ p2.finish();
+ QVERIFY(whenAll.isRunning());
+
+ p1.start();
+ p1.addResult(1);
+ p1.finish();
+ QVERIFY(!whenAll.isRunning());
+ QVERIFY(finished);
+
+ // Try with empty sequence
+ QFuture<OutputContainer> whenAllEmpty;
+ if constexpr (std::is_same_v<QList<QFuture<int>>, OutputContainer>)
+ whenAllEmpty = QtFuture::whenAll(futures.end(), futures.end());
+ else
+ whenAllEmpty = QtFuture::whenAll<OutputContainer>(futures.end(), futures.end());
+ QVERIFY(whenAllEmpty.isStarted());
+ QVERIFY(whenAllEmpty.isFinished());
+ QVERIFY(whenAllEmpty.result().empty());
+}
+
+void tst_QFuture::whenAllIterators()
+{
+ // Try with different output containers
+ testWhenAllIterators<QList<QFuture<int>>>();
+ if (QTest::currentTestFailed())
+ QSKIP("testWhenAllIterators() with QList failed!");
+
+ testWhenAllIterators<std::vector<QFuture<int>>>();
+ if (QTest::currentTestFailed())
+ QSKIP("testWhenAllIterators() with std::vector failed!");
+
+ testWhenAllIterators<QVarLengthArray<QFuture<int>>>();
+ if (QTest::currentTestFailed())
+ QSKIP("testWhenAllIterators() with QVarLengthArray failed!");
+}
+
+void tst_QFuture::whenAllIteratorsWithCanceled()
+{
+ QPromise<int> p0;
+ QPromise<int> p1;
+ QList<QFuture<int>> futures = { p0.future(), p1.future() };
+ bool finished = false;
+ auto whenAll = QtFuture::whenAll(futures.begin(), futures.end())
+ .then([&](const QList<QFuture<int>> &results) {
+ QCOMPARE(results.size(), 2);
+ QVERIFY(results[0].isCanceled());
+ QVERIFY(!results[1].isCanceled());
+ QCOMPARE(results[1].result(), 1);
+ finished = true;
+ });
+
+ p0.start();
+ p0.future().cancel();
+ p0.finish();
+ QVERIFY(!finished);
+
+ p1.start();
+ p1.addResult(1);
+ p1.finish();
+ QVERIFY(finished);
+}
+
+void tst_QFuture::whenAllIteratorsWithFailed()
+{
+#ifndef QT_NO_EXCEPTIONS
+ QPromise<int> p0;
+ QPromise<int> p1;
+ QList<QFuture<int>> futures = { p0.future(), p1.future() };
+ bool finished = false;
+ auto whenAll = QtFuture::whenAll(futures.begin(), futures.end())
+ .then([&](QList<QFuture<int>> results) {
+ QCOMPARE(results.size(), 2);
+ QCOMPARE(results[1].result(), 1);
+ // A shorter way of handling the exception
+ results[0].onFailed([&](const QException &) {
+ finished = true;
+ return 0;
+ });
+ });
+
+ p0.start();
+ p0.setException(QException());
+ p0.finish();
+ QVERIFY(!finished);
+
+ p1.start();
+ p1.addResult(1);
+ p1.finish();
+ QVERIFY(finished);
+#else
+ QSKIP("Exceptions are disabled, skipping the test");
+#endif
+}
+
+// A helper for std::visit, see https://en.cppreference.com/w/cpp/utility/variant/visit
+template<class... Ts>
+struct overloaded : public Ts...
+{
+ using Ts::operator()...;
+};
+
+// explicit deduction guide
+template<class... Ts>
+overloaded(Ts...)->overloaded<Ts...>;
+
+template<class OutputContainer>
+void testWhenAllDifferentTypes()
+{
+ QPromise<int> pInt1;
+ QPromise<int> pInt2;
+ QPromise<void> pVoid;
+
+ using Futures = std::variant<QFuture<int>, QFuture<int>, QFuture<void>>;
+
+ QFuture<OutputContainer> whenAll;
+ if constexpr (std::is_same_v<QList<Futures>, OutputContainer>) {
+ whenAll = QtFuture::whenAll(pInt1.future(), pInt2.future(), pVoid.future());
+ } else {
+ whenAll =
+ QtFuture::whenAll<OutputContainer>(pInt1.future(), pInt2.future(), pVoid.future());
+ }
+
+ int sumOfInts = 0;
+ whenAll.then([&](const OutputContainer &results) {
+ for (auto future : results) {
+ std::visit(overloaded {
+ [&](const QFuture<int> &f) {
+ QVERIFY(f.isFinished());
+ sumOfInts += f.result();
+ },
+ [](const QFuture<void> &f) { QVERIFY(f.isFinished()); },
+ },
+ future);
+ }
+ });
+
+ pVoid.start();
+ pVoid.finish();
+ QVERIFY(whenAll.isRunning());
+
+ pInt2.start();
+ pInt2.addResult(2);
+ pInt2.finish();
+ QVERIFY(whenAll.isRunning());
+ QCOMPARE(sumOfInts, 0);
+
+ pInt1.start();
+ pInt1.addResult(1);
+ pInt1.finish();
+ QVERIFY(!whenAll.isRunning());
+ QCOMPARE(sumOfInts, 3);
+}
+
+void tst_QFuture::whenAllDifferentTypes()
+{
+ using Futures = std::variant<QFuture<int>, QFuture<int>, QFuture<void>>;
+ testWhenAllDifferentTypes<QList<Futures>>();
+ if (QTest::currentTestFailed())
+ QSKIP("testWhenAllDifferentTypes() with QList failed!");
+
+ testWhenAllDifferentTypes<std::vector<Futures>>();
+ if (QTest::currentTestFailed())
+ QSKIP("testWhenAllDifferentTypes() with std::vector failed!");
+
+ testWhenAllDifferentTypes<QVarLengthArray<Futures>>();
+ if (QTest::currentTestFailed())
+ QSKIP("testWhenAllDifferentTypes() with QVarLengthArray failed!");
+}
+
+void tst_QFuture::whenAllDifferentTypesWithCanceled()
+{
+ QPromise<int> pInt;
+ QPromise<QString> pString;
+
+ const QString someValue = u"some value"_s;
+
+ bool finished = false;
+ using Futures = std::variant<QFuture<int>, QFuture<QString>>;
+ auto whenAll = QtFuture::whenAll(pInt.future(), pString.future())
+ .then([&](const QList<Futures> &results) {
+ finished = true;
+ for (auto future : results) {
+ std::visit(overloaded {
+ [](const QFuture<int> &f) {
+ QVERIFY(f.isFinished());
+ QVERIFY(f.isCanceled());
+ },
+ [&](const QFuture<QString> &f) {
+ QVERIFY(f.isFinished());
+ QCOMPARE(f.result(), someValue);
+ },
+ },
+ future);
+ }
+ });
+
+ pString.start();
+ pString.addResult(someValue);
+ pString.finish();
+ QVERIFY(!finished);
+
+ pInt.start();
+ pInt.future().cancel();
+ pInt.finish();
+ QVERIFY(finished);
+}
+
+void tst_QFuture::whenAllDifferentTypesWithFailed()
+{
+#ifndef QT_NO_EXCEPTIONS
+ QPromise<int> pInt;
+ QPromise<QString> pString;
+
+ const QString someValue = u"some value"_s;
+
+ bool finished = false;
+ using Futures = std::variant<QFuture<int>, QFuture<QString>>;
+ auto whenAll = QtFuture::whenAll(pInt.future(), pString.future())
+ .then([&](const QList<Futures> &results) {
+ finished = true;
+ for (auto future : results) {
+ std::visit(overloaded {
+ [](QFuture<int> f) {
+ QVERIFY(f.isFinished());
+ bool failed = false;
+ // A shorter way of handling the exception
+ f.onFailed([&](const QException &) {
+ failed = true;
+ return -1;
+ });
+ QVERIFY(failed);
+ },
+ [&](const QFuture<QString> &f) {
+ QVERIFY(f.isFinished());
+ QCOMPARE(f.result(), someValue);
+ },
+ },
+ future);
+ }
+ });
+
+ pInt.start();
+ pInt.setException(QException());
+ pInt.finish();
+ QVERIFY(!finished);
+
+ pString.start();
+ pString.addResult(someValue);
+ pString.finish();
+ QVERIFY(finished);
+#else
+ QSKIP("Exceptions are disabled, skipping the test")
+#endif
+}
+
+void tst_QFuture::whenAnyIterators()
+{
+ QPromise<int> p0;
+ QPromise<int> p1;
+ QPromise<int> p2;
+ QList<QFuture<int>> futures = { p0.future(), p1.future(), p2.future() };
+
+ auto whenAny = QtFuture::whenAny(futures.begin(), futures.end());
+ int count = 0;
+ whenAny.then([&](const QtFuture::WhenAnyResult<int> &result) {
+ QCOMPARE(result.index, 1);
+ QCOMPARE(result.future.result(), 1);
+ QVERIFY(!futures[0].isFinished());
+ QVERIFY(futures[1].isFinished());
+ QVERIFY(!futures[2].isFinished());
+ ++count;
+ });
+
+ p0.start();
+ p1.start();
+ p2.start();
+ p0.addResult(0);
+ p1.addResult(1);
+ p2.addResult(2);
+ QVERIFY(!whenAny.isFinished());
+ QCOMPARE(count, 0);
+
+ p1.finish();
+ QVERIFY(whenAny.isFinished());
+ QCOMPARE(count, 1);
+
+ p0.finish();
+ QCOMPARE(count, 1);
+
+ p2.finish();
+ QCOMPARE(count, 1);
+
+ auto whenAnyEmpty = QtFuture::whenAny(futures.end(), futures.end());
+ QVERIFY(whenAnyEmpty.isStarted());
+ QVERIFY(whenAnyEmpty.isFinished());
+ QCOMPARE(whenAnyEmpty.result().index, -1);
+ auto whenAnyEmptyResult = whenAnyEmpty.result().future;
+ QVERIFY(whenAnyEmptyResult.isStarted());
+ QVERIFY(whenAnyEmptyResult.isFinished());
+ QVERIFY(whenAnyEmptyResult.isCanceled());
+}
+
+void tst_QFuture::whenAnyIteratorsWithCanceled()
+{
+ QPromise<int> p0;
+ QPromise<int> p1;
+ QList<QFuture<int>> futures = { p0.future(), p1.future() };
+ int count = 0;
+ auto whenAny = QtFuture::whenAny(futures.begin(), futures.end())
+ .then([&](const QtFuture::WhenAnyResult<int> &result) {
+ QCOMPARE(result.index, 1);
+ QVERIFY(result.future.isCanceled());
+ QVERIFY(!futures[0].isFinished());
+ QVERIFY(futures[1].isFinished());
+ ++count;
+ });
+
+ p1.start();
+ p1.future().cancel();
+ p1.finish();
+ QVERIFY(whenAny.isFinished());
+ QCOMPARE(count, 1);
+
+ p0.start();
+ p0.addResult(0);
+ p0.finish();
+ QCOMPARE(count, 1);
+}
+
+void tst_QFuture::whenAnyIteratorsWithFailed()
+{
+#ifndef QT_NO_EXCEPTIONS
+ QPromise<int> p0;
+ QPromise<int> p1;
+ QList<QFuture<int>> futures = { p0.future(), p1.future() };
+ int count = 0;
+ auto whenAny = QtFuture::whenAny(futures.begin(), futures.end())
+ .then([&](QtFuture::WhenAnyResult<int> result) {
+ QCOMPARE(result.index, 1);
+ QVERIFY(p1.future().isFinished());
+ QVERIFY(!p0.future().isFinished());
+ // A shorter way of handling the exception
+ result.future.onFailed([&](const QException &) {
+ ++count;
+ return 0;
+ });
+ });
+
+ p1.start();
+ p1.setException(QException());
+ p1.finish();
+ QCOMPARE(count, 1);
+
+ p0.start();
+ p0.addResult(0);
+ p0.finish();
+ QCOMPARE(count, 1);
+#else
+ QSKIP("Exceptions are disabled, skipping the test")
+#endif
+}
+
+void tst_QFuture::whenAnyDifferentTypes()
+{
+ QPromise<int> pInt1;
+ QPromise<int> pInt2;
+ QPromise<void> pVoid;
+
+ auto whenAny = QtFuture::whenAny(pInt1.future(), pInt2.future(), pVoid.future());
+ int count = 0;
+ whenAny.then([&](const std::variant<QFuture<int>, QFuture<int>, QFuture<void>> &result) {
+ QCOMPARE(result.index(), 1u);
+ std::visit(overloaded { [&](const QFuture<int> &future) {
+ QVERIFY(future.isFinished());
+ QCOMPARE(future.result(), 2);
+ ++count;
+ },
+ [](auto) { QFAIL("The wrong future completed."); }
+ },
+ result);
+ });
+
+ pInt2.start();
+ pInt1.start();
+ pVoid.start();
+ pInt1.addResult(1);
+ pInt2.addResult(2);
+
+ QVERIFY(!whenAny.isFinished());
+ QCOMPARE(count, 0);
+
+ pInt2.finish();
+ QVERIFY(whenAny.isFinished());
+ QCOMPARE(count, 1);
+
+ pInt1.finish();
+ QCOMPARE(count, 1);
+
+ pVoid.finish();
+ QCOMPARE(count, 1);
+}
+
+void tst_QFuture::whenAnyDifferentTypesWithCanceled()
+{
+ QPromise<int> pInt;
+ QPromise<void> pVoid;
+
+ int count = 0;
+ auto whenAny = QtFuture::whenAny(pInt.future(), pVoid.future())
+ .then([&](const std::variant<QFuture<int>, QFuture<void>> &result) {
+ QCOMPARE(result.index(), 0u);
+ std::visit(overloaded { [&](const QFuture<int> &future) {
+ QVERIFY(future.isFinished());
+ QVERIFY(future.isCanceled());
+ ++count;
+ },
+ [](auto) {
+ QFAIL("The wrong future completed.");
+ }
+ },
+ result);
+ });
+
+ pInt.start();
+ pInt.future().cancel();
+ pInt.finish();
+ QCOMPARE(count, 1);
+
+ pVoid.start();
+ pVoid.finish();
+ QCOMPARE(count, 1);
+}
+
+void tst_QFuture::whenAnyDifferentTypesWithFailed()
+{
+#ifndef QT_NO_EXCEPTIONS
+ QPromise<int> pInt;
+ QPromise<void> pVoid;
+
+ int count = 0;
+ auto whenAny = QtFuture::whenAny(pInt.future(), pVoid.future())
+ .then([&](const std::variant<QFuture<int>, QFuture<void>> &result) {
+ QCOMPARE(result.index(), 0u);
+ std::visit(overloaded { [&](QFuture<int> future) {
+ QVERIFY(future.isFinished());
+ // A shorter way of handling the exception
+ future.onFailed([&](const QException &) {
+ ++count;
+ return -1;
+ });
+ },
+ [](auto) {
+ QFAIL("The wrong future completed.");
+ }
+ },
+ result);
+ });
+
+ pInt.start();
+ pInt.setException(QException());
+ pInt.finish();
+ QCOMPARE(count, 1);
+
+ pVoid.start();
+ pVoid.finish();
+ QCOMPARE(count, 1);
+#else
+ QSKIP("Exceptions are disabled, skipping the test")
+#endif
+}
+
+void tst_QFuture::continuationOverride()
+{
+ QPromise<int> p;
+ bool firstExecuted = false;
+ bool secondExecuted = false;
+
+ QTest::ignoreMessage(QtWarningMsg,
+ "Adding a continuation to a future which already has a continuation. "
+ "The existing continuation is overwritten.");
+
+ QFuture<int> f1 = p.future();
+ f1.then([&firstExecuted](int) {
+ firstExecuted = true;
+ });
+
+ QFuture<int> f2 = p.future();
+ f2.then([&secondExecuted](int) {
+ secondExecuted = true;
+ });
+
+ p.start();
+ p.addResult(42);
+ p.finish();
+
+ QVERIFY(p.future().isFinished());
+ QVERIFY(!firstExecuted);
+ QVERIFY(secondExecuted);
+}
+
+struct InstanceCounter
+{
+ InstanceCounter() { ++count; }
+ InstanceCounter(const InstanceCounter &) { ++count; }
+ ~InstanceCounter() { --count; }
+ static int count;
+};
+int InstanceCounter::count = 0;
+
+void tst_QFuture::continuationsDontLeak()
+{
+ {
+ // QFuture isn't started and isn't finished (has no state)
+ QPromise<InstanceCounter> promise;
+ auto future = promise.future();
+
+ bool continuationIsRun = false;
+ future.then([future, &continuationIsRun](InstanceCounter) { continuationIsRun = true; });
+
+ promise.addResult(InstanceCounter {});
+
+ QVERIFY(!continuationIsRun);
+ }
+ QCOMPARE(InstanceCounter::count, 0);
+
+ {
+ // QFuture is started, but not finished
+ QPromise<InstanceCounter> promise;
+ auto future = promise.future();
+
+ bool continuationIsRun = false;
+ future.then([future, &continuationIsRun](InstanceCounter) { continuationIsRun = true; });
+
+ promise.start();
+ promise.addResult(InstanceCounter {});
+
+ QVERIFY(!continuationIsRun);
+ }
+ QCOMPARE(InstanceCounter::count, 0);
+
+ {
+ // QFuture is started and finished, the continuation is run
+ QPromise<InstanceCounter> promise;
+ auto future = promise.future();
+
+ bool continuationIsRun = false;
+ future.then([future, &continuationIsRun](InstanceCounter) {
+ QVERIFY(future.isFinished());
+ continuationIsRun = true;
+ });
+
+ promise.start();
+ promise.addResult(InstanceCounter {});
+ promise.finish();
+
+ QVERIFY(continuationIsRun);
+ }
+ QCOMPARE(InstanceCounter::count, 0);
+
+ {
+ // QTBUG-116731: Must pass with ASan enabled
+ bool continuationIsRun = false;
+ auto f = QtFuture::makeReadyValueFuture(42);
+ QtFuture::whenAll(f).then([&](auto) { continuationIsRun = true; });
+ QVERIFY(continuationIsRun);
+ }
+
+ {
+ // QTBUG-116731: Must pass with ASan enabled
+ bool continuationIsRun = false;
+ auto f = QtFuture::makeReadyValueFuture(42);
+ QList fs{f};
+ QtFuture::whenAll(fs.begin(), fs.end()).then([&](auto) { continuationIsRun = true; });
+ QVERIFY(continuationIsRun);
+ }
+
+ {
+ // QTBUG-116731: Must pass with ASan enabled
+ bool continuationIsRun = false;
+ auto f = QtFuture::makeReadyValueFuture(42);
+ QtFuture::whenAny(f).then([&](auto) { continuationIsRun = true; });
+ QVERIFY(continuationIsRun);
+ }
+
+ {
+ // QTBUG-116731: Must pass with ASan enabled
+ bool continuationIsRun = false;
+ auto f = QtFuture::makeReadyValueFuture(42);
+ QList fs{f};
+ QtFuture::whenAny(fs.begin(), fs.end()).then([&](auto) { continuationIsRun = true; });
+ QVERIFY(continuationIsRun);
+ }
+}
+
+// This test checks that we do not get use-after-free
+void tst_QFuture::cancelAfterFinishWithContinuations()
+{
+ QFuture<void> future;
+ bool continuationIsRun = false;
+ bool cancelCalled = false;
+ {
+ QPromise<void> promise;
+ future = promise.future();
+
+ future.then([&continuationIsRun]() {
+ continuationIsRun = true;
+ }).onCanceled([&cancelCalled]() {
+ cancelCalled = true;
+ });
+
+ promise.start();
+ promise.finish();
+ }
+
+ QVERIFY(continuationIsRun);
+ future.cancel();
+ QVERIFY(!cancelCalled);
+}
+
+void tst_QFuture::unwrap()
+{
+ // The nested future succeeds
+ {
+ QPromise<int> p;
+ QFuture<QFuture<int>> f = p.future().then([] (int value) {
+ QFuture<int> nested = QtConcurrent::run([value] {
+ return value + 1;
+ });
+ return nested;
+ });
+
+ QFuture<int> unwrapped = f.unwrap();
+ QVERIFY(!unwrapped.isStarted());
+ QVERIFY(!unwrapped.isFinished());
+
+ p.start();
+ p.addResult(42);
+ p.finish();
+
+ unwrapped.waitForFinished();
+
+ QVERIFY(unwrapped.isStarted());
+ QVERIFY(unwrapped.isFinished());
+ QCOMPARE(unwrapped.result(), 43);
+ }
+
+ // The nested future succeeds with multiple results
+ {
+ QPromise<int> p;
+ QFuture<QFuture<int>> f = p.future().then([] (int value) {
+ QPromise<int> nested;
+ nested.start();
+ nested.addResult(++value);
+ nested.addResult(++value);
+ nested.addResult(++value);
+ nested.finish();
+ return nested.future();
+ });
+
+ QFuture<int> unwrapped = f.unwrap();
+ QVERIFY(!unwrapped.isStarted());
+ QVERIFY(!unwrapped.isFinished());
+
+ p.start();
+ p.addResult(42);
+ p.finish();
+
+ f.waitForFinished();
+
+ QVERIFY(unwrapped.isStarted());
+ QVERIFY(unwrapped.isFinished());
+ QCOMPARE(unwrapped.results(), QList<int>() << 43 << 44 << 45);
+ }
+
+ // The chain is canceled, check that unwrap() propagates the cancellation.
+ {
+ QPromise<int> p;
+ QFuture<int> f = p.future().then([] (int value) {
+ QFuture<int> nested = QtConcurrent::run([value] {
+ return value + 1;
+ });
+ return nested;
+ }).unwrap().then([] (int result) {
+ return result;
+ }).onCanceled([] {
+ return -1;
+ });
+
+ p.start();
+ p.future().cancel();
+ p.finish();
+
+ f.waitForFinished();
+
+ QVERIFY(f.isStarted());
+ QVERIFY(f.isFinished());
+ QCOMPARE(f.result(), -1);
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // The chain has an exception, check that unwrap() propagates it.
+ {
+ QPromise<int> p;
+ QFuture<int> f = p.future().then([] (int value) {
+ QFuture<int> nested = QtConcurrent::run([value] {
+ return value + 1;
+ });
+ return nested;
+ }).unwrap().then([] (int result) {
+ return result;
+ }).onFailed([] (QException &) {
+ return -1;
+ });
+
+ p.start();
+ p.setException(QException());
+ p.finish();
+
+ f.waitForFinished();
+
+ QVERIFY(f.isStarted());
+ QVERIFY(f.isFinished());
+ QCOMPARE(f.result(), -1);
+ }
+
+#endif // QT_NO_EXCEPTIONS
+
+ // The nested future is canceled
+ {
+ QPromise<int> p;
+ QFuture<int> f = p.future().then([] (int value) {
+ QFuture<int> nested = QtConcurrent::run([value] {
+ return value + 1;
+ });
+ nested.cancel();
+ return nested;
+ }).unwrap().then([] (int result) {
+ return result;
+ }).onCanceled([] {
+ return -1;
+ });
+
+ p.start();
+ p.addResult(42);
+ p.finish();
+
+ f.waitForFinished();
+
+ QVERIFY(f.isStarted());
+ QVERIFY(f.isFinished());
+ QCOMPARE(f.result(), -1);
+ }
+
+#ifndef QT_NO_EXCEPTIONS
+ // The nested future fails with an exception
+ {
+ QPromise<int> p;
+ QFuture<int> f = p.future().then([] (int value) {
+ QFuture<int> nested = QtConcurrent::run([value] {
+ throw QException();
+ return value + 1;
+ });
+ return nested;
+ }).unwrap().then([] (int result) {
+ return result;
+ }).onFailed([] (QException &) {
+ return -1;
+ });
+
+ p.start();
+ p.addResult(42);
+ p.finish();
+
+ f.waitForFinished();
+
+ QVERIFY(f.isStarted());
+ QVERIFY(f.isFinished());
+ QCOMPARE(f.result(), -1);
+ }
+#endif // QT_NO_EXCEPTIONS
+
+ // Check that continuations are called in the right order
+ {
+ QPromise<void> p;
+
+ std::atomic<bool> firstThenInvoked = false;
+ std::atomic<bool> secondThenInvoked = false;
+ std::atomic<bool> nestedThenInvoked = false;
+ auto f = p.future().then([&] {
+ if (!firstThenInvoked && !secondThenInvoked && !nestedThenInvoked)
+ firstThenInvoked = true;
+ QFuture<void> nested = QtConcurrent::run([&] {
+ QVERIFY(firstThenInvoked);
+ QVERIFY(!nestedThenInvoked);
+ QVERIFY(!secondThenInvoked);
+ nestedThenInvoked = true;
+ });
+ return nested;
+ }).unwrap().then([&] {
+ QVERIFY(firstThenInvoked);
+ QVERIFY(nestedThenInvoked);
+ QVERIFY(!secondThenInvoked);
+ secondThenInvoked = true;
+ });
+
+ QVERIFY(!firstThenInvoked);
+ QVERIFY(!nestedThenInvoked);
+ QVERIFY(!secondThenInvoked);
+
+ p.start();
+ p.finish();
+
+ f.waitForFinished();
+
+ if (QTest::currentTestFailed())
+ return;
+
+ QVERIFY(firstThenInvoked);
+ QVERIFY(nestedThenInvoked);
+ QVERIFY(secondThenInvoked);
+ }
+
+ // Unwrap multiple nested futures
+ {
+ QPromise<int> p;
+ QFuture<QFuture<QFuture<int>>> f = p.future().then([] (int value) {
+ QFuture<QFuture<int>> nested = QtConcurrent::run([value] {
+ QFuture<int> doubleNested = QtConcurrent::run([value] {
+ return value + 1;
+ });
+ return doubleNested;
+ });
+ return nested;
+ });
+
+ QFuture<int> unwrapped = f.unwrap();
+ QVERIFY(!unwrapped.isStarted());
+ QVERIFY(!unwrapped.isFinished());
+
+ p.start();
+ p.addResult(42);
+ p.finish();
+
+ unwrapped.waitForFinished();
+
+ QVERIFY(unwrapped.isStarted());
+ QVERIFY(unwrapped.isFinished());
+ QCOMPARE(unwrapped.result(), 43);
+ }
+
+ // Unwrap multiple nested void futures
+ {
+ QPromise<void> p;
+ std::atomic<bool> nestedInvoked = false;
+ std::atomic<bool> doubleNestedInvoked = false;
+ QFuture<QFuture<QFuture<void>>> f = p.future().then([&] {
+ QFuture<QFuture<void>> nested = QtConcurrent::run([&] {
+ QFuture<void> doubleNested = QtConcurrent::run([&] {
+ doubleNestedInvoked = true;
+ });
+ nestedInvoked = true;
+ return doubleNested;
+ });
+ return nested;
+ });
+
+ QFuture<void> unwrapped = f.unwrap();
+ QVERIFY(!nestedInvoked);
+ QVERIFY(!doubleNestedInvoked);
+ QVERIFY(!unwrapped.isStarted());
+ QVERIFY(!unwrapped.isFinished());
+
+ p.start();
+ p.finish();
+
+ unwrapped.waitForFinished();
+
+ QVERIFY(unwrapped.isStarted());
+ QVERIFY(unwrapped.isFinished());
+ QVERIFY(nestedInvoked);
+ QVERIFY(doubleNestedInvoked);
+ }
+}
+
QTEST_MAIN(tst_QFuture)
#include "tst_qfuture.moc"
diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt b/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt
new file mode 100644
index 0000000000..c0f4561c51
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuturesynchronizer/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfuturesynchronizer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfuturesynchronizer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfuturesynchronizer
+ SOURCES
+ tst_qfuturesynchronizer.cpp
+)
diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro b/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro
deleted file mode 100644
index 0d20117ed0..0000000000
--- a/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfuturesynchronizer
-QT = core testlib
-SOURCES = tst_qfuturesynchronizer.cpp
diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp b/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp
index 2a8a340925..62ad4f872a 100644
--- a/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp
+++ b/tests/auto/corelib/thread/qfuturesynchronizer/tst_qfuturesynchronizer.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QtCore/qfuturesynchronizer.h>
#include <QtCore/qfuture.h>
@@ -38,6 +13,7 @@ class tst_QFutureSynchronizer : public QObject
private Q_SLOTS:
void construction();
+ void setFutureAliasingExistingMember();
void addFuture();
void cancelOnWait();
void clearFutures();
@@ -58,6 +34,38 @@ void tst_QFutureSynchronizer::construction()
QCOMPARE(synchronizerWithFuture.futures().size(), 1);
}
+void tst_QFutureSynchronizer::setFutureAliasingExistingMember()
+{
+ //
+ // GIVEN: a QFutureSynchronizer with one QFuture:
+ //
+ QFutureSynchronizer synchronizer(QtFuture::makeReadyValueFuture(42));
+
+ //
+ // WHEN: calling setFuture() with an alias of the QFuture already in `synchronizer`:
+ //
+ for (int i = 0; i < 2; ++i) {
+ // The next line triggers -Wdangling-reference, but it's a FP because
+ // of implicit sharing. We cannot keep a copy of synchronizer.futures()
+ // around to avoid the warning, as the extra copy would cause a detach()
+ // of m_futures inside setFuture() with the consequence that `f` no longer
+ // aliases an element in m_futures, which is the goal of this test.
+QT_WARNING_PUSH
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1301
+QT_WARNING_DISABLE_GCC("-Wdangling-reference")
+#endif
+ const auto &f = synchronizer.futures().constFirst();
+QT_WARNING_POP
+ synchronizer.setFuture(f);
+ }
+
+ //
+ // THEN: it didn't crash
+ //
+ QCOMPARE(synchronizer.futures().size(), 1);
+ QCOMPARE(synchronizer.futures().constFirst().result(), 42);
+}
+
void tst_QFutureSynchronizer::addFuture()
{
QFutureSynchronizer<void> synchronizer;
@@ -107,7 +115,7 @@ void tst_QFutureSynchronizer::futures()
synchronizer.addFuture(future);
}
- QCOMPARE(futures, synchronizer.futures());
+ QCOMPARE(futures.size(), synchronizer.futures().size());
}
void tst_QFutureSynchronizer::setFuture()
@@ -122,7 +130,6 @@ void tst_QFutureSynchronizer::setFuture()
QFuture<void> future;
synchronizer.setFuture(future);
QCOMPARE(synchronizer.futures().size(), 1);
- QCOMPARE(synchronizer.futures().first(), future);
}
void tst_QFutureSynchronizer::waitForFinished()
diff --git a/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt b/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt
new file mode 100644
index 0000000000..65417199a3
--- /dev/null
+++ b/tests/auto/corelib/thread/qfuturewatcher/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfuturewatcher Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfuturewatcher LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfuturewatcher
+ SOURCES
+ tst_qfuturewatcher.cpp
+ LIBRARIES
+ Qt::Concurrent
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qfuturewatcher/qfuturewatcher.pro b/tests/auto/corelib/thread/qfuturewatcher/qfuturewatcher.pro
deleted file mode 100644
index d0e8b4c982..0000000000
--- a/tests/auto/corelib/thread/qfuturewatcher/qfuturewatcher.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfuturewatcher
-QT = core core-private testlib concurrent
-SOURCES = tst_qfuturewatcher.cpp
diff --git a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp
index b2ef516b4e..40aa89ded4 100644
--- a/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp
+++ b/tests/auto/corelib/thread/qfuturewatcher/tst_qfuturewatcher.cpp
@@ -1,40 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
#include <QDebug>
-#include <QtTest/QtTest>
+#include <QElapsedTimer>
+#include <QSignalSpy>
#include <QtConcurrent>
#include <private/qfutureinterface_p.h>
using namespace QtConcurrent;
+using namespace std::chrono_literals;
-#include <QtTest/QtTest>
+#include <QTest>
//#define PRINT
@@ -45,8 +22,11 @@ private slots:
void startFinish();
void progressValueChanged();
void canceled();
+ void cancelAndFinish_data();
+ void cancelAndFinish();
void resultAt();
void resultReadyAt();
+ void orderedResultReadyAt();
void futureSignals();
void watchFinishedFuture();
void watchCanceledFuture();
@@ -56,14 +36,20 @@ private slots:
void sharedFutureInterface();
void changeFuture();
void cancelEvents();
+#if QT_DEPRECATED_SINCE(6, 0)
void pauseEvents();
- void finishedState();
+ void pausedSuspendedOrder();
+#endif
+ void suspendEvents();
+ void suspended();
+ void suspendedEventsOrder();
void throttling();
void incrementalMapResults();
void incrementalFilterResults();
void qfutureSynchronizer();
void warnRace();
void matchFlags();
+ void checkStateConsistency();
};
void sleeper()
@@ -75,20 +61,31 @@ void tst_QFutureWatcher::startFinish()
{
QFutureWatcher<void> futureWatcher;
- QSignalSpy startedSpy(&futureWatcher, &QFutureWatcher<void>::started);
- QSignalSpy finishedSpy(&futureWatcher, &QFutureWatcher<void>::finished);
-
- QVERIFY(startedSpy.isValid());
- QVERIFY(finishedSpy.isValid());
+ int startedCount = 0;
+ int finishedCount = 0;
+ QObject::connect(&futureWatcher, &QFutureWatcher<void>::started,
+ [&startedCount, &finishedCount](){
+ ++startedCount;
+ QCOMPARE(startedCount, 1);
+ QCOMPARE(finishedCount, 0);
+ });
+ QObject::connect(&futureWatcher, &QFutureWatcher<void>::finished,
+ [&startedCount, &finishedCount](){
+ ++finishedCount;
+ QCOMPARE(startedCount, 1);
+ QCOMPARE(finishedCount, 1);
+ });
futureWatcher.setFuture(QtConcurrent::run(sleeper));
- QVERIFY(startedSpy.wait());
- QCOMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 0);
futureWatcher.future().waitForFinished();
- QVERIFY(finishedSpy.wait());
- QCOMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 1);
+
+ // waitForFinished() may unblock before asynchronous
+ // started() and finished() signals are delivered to the main thread.
+ // prosessEvents() should empty the pending queue.
+ qApp->processEvents();
+
+ QCOMPARE(startedCount, 1);
+ QCOMPARE(finishedCount, 1);
}
void mapSleeper(int &)
@@ -96,9 +93,9 @@ void mapSleeper(int &)
QTest::qSleep(100);
}
-QSet<int> progressValues;
-QSet<QString> progressTexts;
-QMutex mutex;
+static QSet<int> progressValues;
+static QSet<QString> progressTexts;
+static QMutex mutex;
class ProgressObject : public QObject
{
Q_OBJECT
@@ -173,7 +170,7 @@ class CancelObject : public QObject
Q_OBJECT
public:
bool wasCanceled;
- CancelObject() : wasCanceled(false) {};
+ CancelObject() : wasCanceled(false) {}
public slots:
void cancel();
};
@@ -211,12 +208,48 @@ void tst_QFutureWatcher::canceled()
future.waitForFinished();
}
-class IntTask : public RunFunctionTask<int>
+void tst_QFutureWatcher::cancelAndFinish_data()
+{
+ QTest::addColumn<bool>("isCanceled");
+ QTest::addColumn<bool>("isFinished");
+
+ QTest::addRow("running") << false << false;
+ QTest::addRow("canceled") << true << false;
+ QTest::addRow("finished") << false << true;
+ QTest::addRow("canceledAndFinished") << true << true;
+}
+
+void tst_QFutureWatcher::cancelAndFinish()
+{
+ QFETCH(bool, isCanceled);
+ QFETCH(bool, isFinished);
+
+ QFutureInterface<void> fi;
+ QFutureWatcher<void> futureWatcher;
+ QSignalSpy finishedSpy(&futureWatcher, &QFutureWatcher<void>::finished);
+ QSignalSpy canceledSpy(&futureWatcher, &QFutureWatcher<void>::canceled);
+ futureWatcher.setFuture(fi.future());
+
+ fi.reportStarted();
+
+ if (isCanceled)
+ fi.cancel();
+ if (isFinished)
+ fi.reportFinished();
+
+ fi.cancelAndFinish();
+
+ // The signals should be emitted only once
+ QTRY_COMPARE(canceledSpy.size(), 1);
+ QTRY_COMPARE(finishedSpy.size(), 1);
+}
+
+class IntTask : public RunFunctionTaskBase<int>
{
public:
- void runFunctor()
+ void runFunctor() override
{
- result = 10;
+ promise.reportResult(10);
}
};
@@ -248,6 +281,28 @@ void tst_QFutureWatcher::resultReadyAt()
QVERIFY(resultSpy.wait());
}
+void tst_QFutureWatcher::orderedResultReadyAt()
+{
+ for (int i = 0; i < 1000; ++i) {
+ QObject context;
+ QFuture<QString> f = run([](QPromise<QString> &fi) {
+ fi.addResult("First");
+ fi.addResult("Second");
+ });
+ QList<int> actualIndices;
+
+ QFutureWatcher<QString> watcher;
+ connect(&watcher, &QFutureWatcherBase::resultReadyAt, &context,
+ [&actualIndices](int index) { actualIndices.append(index); });
+ watcher.setFuture(f);
+ f.waitForFinished();
+ QCoreApplication::processEvents();
+ const QList<int> expectedIndices{0, 1};
+ QCOMPARE(actualIndices.size(), expectedIndices.size());
+ QCOMPARE(actualIndices, expectedIndices);
+ }
+}
+
class SignalSlotObject : public QObject
{
Q_OBJECT
@@ -318,21 +373,21 @@ void tst_QFutureWatcher::futureSignals()
const int progress = 1;
a.setProgressValue(progress);
- QTRY_COMPARE(progressSpy.count(), 2);
+ QTRY_COMPARE(progressSpy.size(), 2);
QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 0);
QCOMPARE(progressSpy.takeFirst().at(0).toInt(), 1);
const int result = 10;
a.reportResult(&result);
QVERIFY(resultReadySpy.wait());
- QCOMPARE(resultReadySpy.count(), 1);
+ QCOMPARE(resultReadySpy.size(), 1);
a.reportFinished(&result);
- QTRY_COMPARE(resultReadySpy.count(), 2);
+ QTRY_COMPARE(resultReadySpy.size(), 2);
QCOMPARE(resultReadySpy.takeFirst().at(0).toInt(), 0); // check the index
QCOMPARE(resultReadySpy.takeFirst().at(0).toInt(), 1);
- QCOMPARE(finishedSpy.count(), 1);
+ QCOMPARE(finishedSpy.size(), 1);
}
}
@@ -371,10 +426,10 @@ void tst_QFutureWatcher::watchFinishedFuture()
watcher.setFuture(f);
QVERIFY(finishedSpy.wait());
- QCOMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 1);
- QCOMPARE(resultReadySpy.count(), 1);
- QCOMPARE(canceledSpy.count(), 0);
+ QCOMPARE(startedSpy.size(), 1);
+ QCOMPARE(finishedSpy.size(), 1);
+ QCOMPARE(resultReadySpy.size(), 1);
+ QCOMPARE(canceledSpy.size(), 0);
}
void tst_QFutureWatcher::watchCanceledFuture()
@@ -405,10 +460,10 @@ void tst_QFutureWatcher::watchCanceledFuture()
watcher.setFuture(f);
QVERIFY(finishedSpy.wait());
- QCOMPARE(startedSpy.count(), 1);
- QCOMPARE(finishedSpy.count(), 1);
- QCOMPARE(resultReadySpy.count(), 0);
- QCOMPARE(canceledSpy.count(), 1);
+ QCOMPARE(startedSpy.size(), 1);
+ QCOMPARE(finishedSpy.size(), 1);
+ QCOMPARE(resultReadySpy.size(), 0);
+ QCOMPARE(canceledSpy.size(), 1);
}
void tst_QFutureWatcher::disconnectRunningFuture()
@@ -431,28 +486,28 @@ void tst_QFutureWatcher::disconnectRunningFuture()
const int result = 10;
a.reportResult(&result);
QVERIFY(resultReadySpy.wait());
- QCOMPARE(resultReadySpy.count(), 1);
+ QCOMPARE(resultReadySpy.size(), 1);
delete watcher;
a.reportResult(&result);
QTest::qWait(10);
- QCOMPARE(resultReadySpy.count(), 1);
+ QCOMPARE(resultReadySpy.size(), 1);
a.reportFinished(&result);
QTest::qWait(10);
- QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy.size(), 0);
}
const int maxProgress = 100000;
-class ProgressEmitterTask : public RunFunctionTask<void>
+class ProgressEmitterTask : public RunFunctionTaskBase<void>
{
public:
- void runFunctor()
+ void runFunctor() override
{
- setProgressRange(0, maxProgress);
+ promise.setProgressRange(0, maxProgress);
for (int p = 0; p <= maxProgress; ++p)
- setProgressValue(p);
+ promise.setProgressValue(p);
}
};
@@ -469,30 +524,31 @@ void tst_QFutureWatcher::tooMuchProgress()
QObject::connect(&f, SIGNAL(progressValueChanged(int)), &o, SLOT(registerProgress(int)));
f.setFuture((new ProgressEmitterTask())->start());
- QTestEventLoop::instance().enterLoop(5);
+ // Android reports ca. 10k progressValueChanged per second
+ QTestEventLoop::instance().enterLoop(15);
QVERIFY(!QTestEventLoop::instance().timeout());
QVERIFY(progressValues.contains(maxProgress));
}
template <typename T>
-class ProgressTextTask : public RunFunctionTask<T>
+class ProgressTextTask : public RunFunctionTaskBase<T>
{
public:
- void runFunctor()
+ void runFunctor() override
{
- this->setProgressValueAndText(1, QLatin1String("Foo 1"));
+ this->promise.setProgressValueAndText(1, QLatin1String("Foo 1"));
- while (this->isProgressUpdateNeeded() == false)
+ while (this->promise.isProgressUpdateNeeded() == false)
QTest::qSleep(1);
- this->setProgressValueAndText(2, QLatin1String("Foo 2"));
+ this->promise.setProgressValueAndText(2, QLatin1String("Foo 2"));
- while (this->isProgressUpdateNeeded() == false)
+ while (this->promise.isProgressUpdateNeeded() == false)
QTest::qSleep(1);
- this->setProgressValueAndText(3, QLatin1String("Foo 3"));
+ this->promise.setProgressValueAndText(3, QLatin1String("Foo 3"));
- while (this->isProgressUpdateNeeded() == false)
+ while (this->promise.isProgressUpdateNeeded() == false)
QTest::qSleep(1);
- this->setProgressValueAndText(4, QLatin1String("Foo 4"));
+ this->promise.setProgressValueAndText(4, QLatin1String("Foo 4"));
}
};
@@ -545,12 +601,21 @@ void callInterface(T &obj)
obj.isFinished();
obj.isRunning();
obj.isCanceled();
- obj.isPaused();
+ obj.isSuspended();
+ obj.isSuspending();
obj.cancel();
- obj.pause();
+ obj.suspend();
obj.resume();
+ obj.toggleSuspended();
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ obj.isPaused();
+ obj.pause();
obj.togglePaused();
+QT_WARNING_POP
+#endif
obj.waitForFinished();
const T& objConst = obj;
@@ -563,7 +628,14 @@ void callInterface(T &obj)
objConst.isFinished();
objConst.isRunning();
objConst.isCanceled();
+ objConst.isSuspending();
+ objConst.isSuspended();
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
objConst.isPaused();
+QT_WARNING_POP
+#endif
}
template <typename T>
@@ -624,14 +696,14 @@ void tst_QFutureWatcher::changeFuture()
watcher.setFuture(b); // But oh no! we're switching to another future
QTest::qWait(10); // before the event gets delivered.
- QCOMPARE(resultReadySpy.count(), 0);
+ QCOMPARE(resultReadySpy.size(), 0);
watcher.setFuture(a);
watcher.setFuture(b);
watcher.setFuture(a); // setting it back gets us one event, not two.
QVERIFY(resultReadySpy.wait());
- QCOMPARE(resultReadySpy.count(), 1);
+ QCOMPARE(resultReadySpy.size(), 1);
}
// Test that events aren't delivered from canceled futures
@@ -659,9 +731,12 @@ void tst_QFutureWatcher::cancelEvents()
QVERIFY(finishedSpy.wait());
- QCOMPARE(resultReadySpy.count(), 0);
+ QCOMPARE(resultReadySpy.size(), 0);
}
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
// Tests that events from paused futures are saved and
// delivered on resume.
void tst_QFutureWatcher::pauseEvents()
@@ -677,18 +752,22 @@ void tst_QFutureWatcher::pauseEvents()
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
QVERIFY(resultReadySpy.isValid());
+ QSignalSpy pauseSpy(&watcher, &QFutureWatcher<int>::paused);
+ QVERIFY(pauseSpy.isValid());
+
watcher.setFuture(iface.future());
watcher.pause();
+ QTRY_COMPARE(pauseSpy.size(), 1);
+
int value = 0;
iface.reportFinished(&value);
- QTest::qWait(10);
- QCOMPARE(resultReadySpy.count(), 0);
+ // A result is reported, although the watcher is paused.
+ // The corresponding event should be also reported.
+ QTRY_COMPARE(resultReadySpy.size(), 1);
watcher.resume();
- QTRY_VERIFY2(!resultReadySpy.isEmpty(), "Result didn't arrive");
- QCOMPARE(resultReadySpy.count(), 1);
}
{
QFutureInterface<int> iface;
@@ -714,32 +793,209 @@ void tst_QFutureWatcher::pauseEvents()
a.resume(); // should give us no results.
QTest::qWait(10);
- QCOMPARE(resultReadySpy.count(), 0);
+ QCOMPARE(resultReadySpy.size(), 0);
}
}
-// Test that the finished state for the watcher gets
-// set when the finished event is delivered.
-// This means it will lag the finished state for the future,
-// but makes it more useful.
-void tst_QFutureWatcher::finishedState()
+void tst_QFutureWatcher::pausedSuspendedOrder()
{
- QFutureInterface<int> iface;
+ QFutureInterface<void> iface;
iface.reportStarted();
- QFuture<int> future = iface.future();
+
+ QFutureWatcher<void> watcher;
+
+ QSignalSpy pausedSpy(&watcher, &QFutureWatcher<void>::paused);
+ QVERIFY(pausedSpy.isValid());
+
+ QSignalSpy suspendedSpy(&watcher, &QFutureWatcher<void>::suspended);
+ QVERIFY(suspendedSpy.isValid());
+
+ bool pausedBeforeSuspended = false;
+ bool notSuspendedBeforePaused = false;
+ connect(&watcher, &QFutureWatcher<void>::paused,
+ [&] { notSuspendedBeforePaused = (suspendedSpy.size() == 0); });
+ connect(&watcher, &QFutureWatcher<void>::suspended,
+ [&] { pausedBeforeSuspended = (pausedSpy.size() == 1); });
+
+ watcher.setFuture(iface.future());
+ iface.reportSuspended();
+
+ // Make sure reportPaused() is ignored if the state is not paused
+ pausedSpy.wait(100);
+ QCOMPARE(pausedSpy.size(), 0);
+ QCOMPARE(suspendedSpy.size(), 0);
+
+ iface.setPaused(true);
+ iface.reportSuspended();
+
+ QTRY_COMPARE(suspendedSpy.size(), 1);
+ QCOMPARE(pausedSpy.size(), 1);
+ QVERIFY(notSuspendedBeforePaused);
+ QVERIFY(pausedBeforeSuspended);
+
+ iface.reportFinished();
+}
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 0)
+
+// Tests that events from suspended futures are saved and
+// delivered on resume.
+void tst_QFutureWatcher::suspendEvents()
+{
+ {
+ QFutureInterface<int> iface;
+ iface.reportStarted();
+
+ QFutureWatcher<int> watcher;
+
+ SignalSlotObject object;
+ connect(&watcher, &QFutureWatcher<int>::resultReadyAt, &object,
+ &SignalSlotObject::resultReadyAt);
+ QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
+ QVERIFY(resultReadySpy.isValid());
+
+ QSignalSpy suspendingSpy(&watcher, &QFutureWatcher<int>::suspending);
+ QVERIFY(suspendingSpy.isValid());
+
+ watcher.setFuture(iface.future());
+ watcher.suspend();
+
+ QTRY_COMPARE(suspendingSpy.size(), 1);
+
+ int value = 0;
+ iface.reportFinished(&value);
+
+ // A result is reported, although the watcher is paused.
+ // The corresponding event should be also reported.
+ QTRY_COMPARE(resultReadySpy.size(), 1);
+
+ watcher.resume();
+ }
+ {
+ QFutureInterface<int> iface;
+ iface.reportStarted();
+
+ QFuture<int> a = iface.future();
+
+ QFutureWatcher<int> watcher;
+
+ SignalSlotObject object;
+ connect(&watcher, &QFutureWatcher<int>::resultReadyAt, &object,
+ &SignalSlotObject::resultReadyAt);
+ QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
+ QVERIFY(resultReadySpy.isValid());
+
+ watcher.setFuture(a);
+ a.suspend();
+
+ int value = 0;
+ iface.reportFinished(&value);
+
+ QFuture<int> b;
+ watcher.setFuture(b); // If we watch b instead, resuming a
+ a.resume(); // should give us no results.
+
+ QTest::qWait(10);
+ QCOMPARE(resultReadySpy.size(), 0);
+ }
+}
+
+void tst_QFutureWatcher::suspended()
+{
QFutureWatcher<int> watcher;
- QSignalSpy startedSpy(&watcher, &QFutureWatcher<int>::started);
+ QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ QSignalSpy pausedSpy(&watcher, &QFutureWatcher<int>::paused);
+QT_WARNING_POP
+#endif
+ QSignalSpy suspendingSpy(&watcher, &QFutureWatcher<int>::suspending);
+ QSignalSpy suspendedSpy(&watcher, &QFutureWatcher<int>::suspended);
QSignalSpy finishedSpy(&watcher, &QFutureWatcher<int>::finished);
+ const int numValues = 25;
+ std::vector<int> values(numValues, 0);
+ std::atomic_int count = 0;
+
+ QThreadPool pool;
+ pool.setMaxThreadCount(3);
+
+ QFuture<int> future = QtConcurrent::mapped(&pool, values, [&](int value) {
+ ++count;
+ // Sleep, to make sure not all threads will start at once.
+ QThread::sleep(50ms);
+ return value;
+ });
watcher.setFuture(future);
- QVERIFY(startedSpy.wait());
- iface.reportFinished();
- QVERIFY(future.isFinished());
- QVERIFY(!watcher.isFinished());
+ // Allow some threads to start before suspending.
+ QThread::sleep(200ms);
- QVERIFY(finishedSpy.wait());
- QVERIFY(watcher.isFinished());
+ watcher.suspend();
+ watcher.suspend();
+ QTRY_COMPARE(suspendedSpy.size(), 1); // suspended() should be emitted only once
+ QCOMPARE(suspendingSpy.size(), 2); // suspending() is emitted as many times as requested
+#if QT_DEPRECATED_SINCE(6, 0)
+ QCOMPARE(pausedSpy.size(), 2); // paused() is emitted as many times as requested
+#endif
+
+ // Make sure QFutureWatcher::resultReadyAt() is emitted only for already started threads.
+ const auto resultReadyAfterPaused = resultReadySpy.size();
+ QCOMPARE(resultReadyAfterPaused, count);
+
+ // Make sure no more results are reported before resuming.
+ QThread::sleep(200ms);
+ QCOMPARE(resultReadyAfterPaused, resultReadySpy.size());
+ resultReadySpy.clear();
+
+ watcher.resume();
+ QTRY_COMPARE(finishedSpy.size(), 1);
+
+ // Make sure that no more suspended() signals have been emitted.
+ QCOMPARE(suspendedSpy.size(), 1);
+
+ // Make sure the rest of results were reported after resume.
+ QCOMPARE(resultReadySpy.size(), numValues - resultReadyAfterPaused);
+}
+
+void tst_QFutureWatcher::suspendedEventsOrder()
+{
+ QFutureInterface<void> iface;
+ iface.reportStarted();
+
+ QFutureWatcher<void> watcher;
+
+ QSignalSpy suspendingSpy(&watcher, &QFutureWatcher<void>::suspending);
+ QVERIFY(suspendingSpy.isValid());
+
+ QSignalSpy suspendedSpy(&watcher, &QFutureWatcher<void>::suspended);
+ QVERIFY(suspendedSpy.isValid());
+
+ bool suspendingBeforeSuspended = false;
+ bool notSuspendedBeforeSuspending = false;
+ connect(&watcher, &QFutureWatcher<void>::suspending,
+ [&] { notSuspendedBeforeSuspending = (suspendedSpy.size() == 0); });
+ connect(&watcher, &QFutureWatcher<void>::suspended,
+ [&] { suspendingBeforeSuspended = (suspendingSpy.size() == 1); });
+
+ watcher.setFuture(iface.future());
+ iface.reportSuspended();
+
+ // Make sure reportPaused() is ignored if the state is not paused
+ suspendingSpy.wait(100);
+ QCOMPARE(suspendingSpy.size(), 0);
+ QCOMPARE(suspendedSpy.size(), 0);
+
+ iface.setSuspended(true);
+ iface.reportSuspended();
+
+ QTRY_COMPARE(suspendedSpy.size(), 1);
+ QCOMPARE(suspendingSpy.size(), 1);
+ QVERIFY(notSuspendedBeforeSuspending);
+ QVERIFY(suspendingBeforeSuspended);
+
+ iface.reportFinished();
}
/*
@@ -765,7 +1021,7 @@ void tst_QFutureWatcher::throttling()
QVERIFY(iface.isThrottled());
- QTRY_COMPARE(resultSpy.count(), resultCount); // Process the results
+ QTRY_COMPARE(resultSpy.size(), resultCount); // Process the results
QVERIFY(!iface.isThrottled());
@@ -878,7 +1134,7 @@ void tst_QFutureWatcher::incrementalFilterResults()
void tst_QFutureWatcher::qfutureSynchronizer()
{
int taskCount = 1000;
- QTime t;
+ QElapsedTimer t;
t.start();
{
@@ -907,7 +1163,7 @@ public:
void tst_QFutureWatcher::warnRace()
{
-#ifndef Q_OS_MAC //I don't know why it is not working on mac
+#ifndef Q_OS_DARWIN // I don't know why it is not working on mac
#ifndef QT_NO_DEBUG
QTest::ignoreMessage(QtWarningMsg, "QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race");
#endif
@@ -936,6 +1192,55 @@ void tst_QFutureWatcher::matchFlags()
QCOMPARE(watcher.isFinished(), future.isFinished());
}
+void tst_QFutureWatcher::checkStateConsistency()
+{
+#define CHECK_FAIL(state) \
+ do { \
+ if (QTest::currentTestFailed()) \
+ QFAIL("checkState() failed, QFutureWatcher has inconistent state after " state "!"); \
+ } while (false)
+
+ QFutureWatcher<void> futureWatcher;
+
+ auto checkState = [&futureWatcher] {
+ QCOMPARE(futureWatcher.isStarted(), futureWatcher.future().isStarted());
+ QCOMPARE(futureWatcher.isRunning(), futureWatcher.future().isRunning());
+ QCOMPARE(futureWatcher.isCanceled(), futureWatcher.future().isCanceled());
+ QCOMPARE(futureWatcher.isSuspended(), futureWatcher.future().isSuspended());
+ QCOMPARE(futureWatcher.isSuspending(), futureWatcher.future().isSuspending());
+ QCOMPARE(futureWatcher.isFinished(), futureWatcher.future().isFinished());
+ };
+
+ checkState();
+ CHECK_FAIL("default-constructing");
+
+ QFutureInterface<void> fi;
+ futureWatcher.setFuture(fi.future());
+ checkState();
+ CHECK_FAIL("setting future");
+
+ fi.reportStarted();
+ checkState();
+ CHECK_FAIL("starting");
+
+ fi.future().suspend();
+ checkState();
+ CHECK_FAIL("suspending");
+
+ fi.reportSuspended();
+ checkState();
+ CHECK_FAIL("suspended");
+
+ fi.reportCanceled();
+ checkState();
+ CHECK_FAIL("canceling");
+
+ fi.reportFinished();
+ checkState();
+ CHECK_FAIL("finishing");
+
+#undef CHECK_FAIL
+}
QTEST_MAIN(tst_QFutureWatcher)
#include "tst_qfuturewatcher.moc"
diff --git a/tests/auto/corelib/thread/qmutex/CMakeLists.txt b/tests/auto/corelib/thread/qmutex/CMakeLists.txt
new file mode 100644
index 0000000000..5a92a2bffd
--- /dev/null
+++ b/tests/auto/corelib/thread/qmutex/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmutex Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmutex LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmutex
+ SOURCES
+ tst_qmutex.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qmutex/qmutex.pro b/tests/auto/corelib/thread/qmutex/qmutex.pro
deleted file mode 100644
index cb9d364b71..0000000000
--- a/tests/auto/corelib/thread/qmutex/qmutex.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmutex
-QT = core testlib
-SOURCES = tst_qmutex.cpp
-win32:QT += core-private
diff --git a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp
index 7fb9a861d7..4753444ab9 100644
--- a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp
+++ b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp
@@ -1,40 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSemaphore>
#include <qatomic.h>
#include <qcoreapplication.h>
#include <qelapsedtimer.h>
#include <qmutex.h>
#include <qthread.h>
+#include <qvarlengtharray.h>
#include <qwaitcondition.h>
+#include <private/qvolatile_p.h>
+
+using namespace std::chrono_literals;
class tst_QMutex : public QObject
{
@@ -46,11 +26,9 @@ public:
Milliseconds,
Seconds,
};
- Q_ENUM(TimeUnit);
+ Q_ENUM(TimeUnit)
private slots:
- void convertToMilliseconds_data();
- void convertToMilliseconds();
void tryLock_non_recursive();
void try_lock_for_non_recursive();
void try_lock_until_non_recursive();
@@ -68,10 +46,11 @@ private slots:
static const int iterations = 100;
-QAtomicInt lockCount(0);
-QMutex normalMutex, recursiveMutex(QMutex::Recursive);
-QSemaphore testsTurn;
-QSemaphore threadsTurn;
+static QAtomicInt lockCount(0);
+static QMutex normalMutex;
+static QRecursiveMutex recursiveMutex;
+static QSemaphore testsTurn;
+static QSemaphore threadsTurn;
/*
Depending on the OS, tryWaits may return early than expected because of the
@@ -82,128 +61,22 @@ QSemaphore threadsTurn;
enum {
#ifdef Q_OS_WIN
systemTimersResolution = 16,
+#elif defined(Q_OS_QNX)
+ systemTimersResolution = 10,
#else
systemTimersResolution = 1,
#endif
waitTime = 100
};
-#if QT_HAS_INCLUDE(<chrono>)
-static Q_CONSTEXPR std::chrono::milliseconds waitTimeAsDuration(waitTime);
-#endif
-
-void tst_QMutex::convertToMilliseconds_data()
-{
- QTest::addColumn<TimeUnit>("unit");
- QTest::addColumn<double>("doubleValue");
- QTest::addColumn<qint64>("intValue");
- QTest::addColumn<qint64>("expected");
-
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires <chrono>");
-#endif
-
- auto add = [](TimeUnit unit, double d, long long i, qint64 expected) {
- const QScopedArrayPointer<char> enumName(QTest::toString(unit));
- QTest::addRow("%s:%f:%lld", enumName.data(), d, i)
- << unit << d << qint64(i) << expected;
- };
-
- auto forAllUnitsAdd = [=](double d, long long i, qint64 expected) {
- for (auto unit : {TimeUnit::Nanoseconds, TimeUnit::Microseconds, TimeUnit::Milliseconds, TimeUnit::Seconds})
- add(unit, d, i, expected);
- };
-
- forAllUnitsAdd(-0.5, -1, 0); // all negative values result in 0
-
- forAllUnitsAdd(0, 0, 0);
-
- add(TimeUnit::Nanoseconds, 1, 1, 1);
- add(TimeUnit::Nanoseconds, 1000 * 1000, 1000 * 1000, 1);
- add(TimeUnit::Nanoseconds, 1000 * 1000 + 0.5, 1000 * 1000 + 1, 2);
-
- add(TimeUnit::Microseconds, 1, 1, 1);
- add(TimeUnit::Microseconds, 1000, 1000, 1);
- add(TimeUnit::Microseconds, 1000 + 0.5, 1000 + 1, 2);
-
- add(TimeUnit::Milliseconds, 1, 1, 1);
- add(TimeUnit::Milliseconds, 1.5, 2, 2);
-
- add(TimeUnit::Seconds, 0.9991, 1, 1000);
-
- //
- // overflowing int results in INT_MAX (equivalent to a spurious wakeup after ~24 days); check it:
- //
-
- // spot on:
- add(TimeUnit::Nanoseconds, INT_MAX * 1000. * 1000, INT_MAX * Q_INT64_C(1000) * 1000, INT_MAX);
- add(TimeUnit::Microseconds, INT_MAX * 1000., INT_MAX * Q_INT64_C(1000), INT_MAX);
- add(TimeUnit::Milliseconds, INT_MAX, INT_MAX, INT_MAX);
-
- // minimally above:
- add(TimeUnit::Nanoseconds, INT_MAX * 1000. * 1000 + 1, INT_MAX * Q_INT64_C(1000) * 1000 + 1, INT_MAX);
- add(TimeUnit::Microseconds, INT_MAX * 1000. + 1, INT_MAX * Q_INT64_C(1000) + 1, INT_MAX);
- add(TimeUnit::Milliseconds, INT_MAX + 1., INT_MAX + Q_INT64_C(1), INT_MAX);
- add(TimeUnit::Seconds, INT_MAX / 1000. + 1, INT_MAX / 1000 + 1, INT_MAX);
-
- // minimally below:
- add(TimeUnit::Nanoseconds, INT_MAX * 1000. * 1000 - 1, INT_MAX * Q_INT64_C(1000) * 1000 - 1, INT_MAX);
- add(TimeUnit::Microseconds, INT_MAX * 1000. - 1, INT_MAX * Q_INT64_C(1000) - 1, INT_MAX);
- add(TimeUnit::Milliseconds, INT_MAX - 0.1, INT_MAX , INT_MAX);
-
-}
-
-void tst_QMutex::convertToMilliseconds()
-{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires <chrono>");
-#else
- QFETCH(TimeUnit, unit);
- QFETCH(double, doubleValue);
- QFETCH(qint64, intValue);
- QFETCH(qint64, expected);
-
- Q_CONSTEXPR qint64 maxShort = std::numeric_limits<short>::max();
- Q_CONSTEXPR qint64 maxInt = std::numeric_limits<int>::max();
- Q_CONSTEXPR qint64 maxUInt = std::numeric_limits<uint>::max();
-
- switch (unit) {
-#define CASE(Unit, Period) \
- case TimeUnit::Unit: \
- DO(double, Period, doubleValue); \
- if (intValue < maxShort) \
- DO(short, Period, short(intValue)); \
- if (intValue < maxInt) \
- DO(int, Period, int(intValue)); \
- DO(qint64, Period, intValue); \
- if (intValue >= 0) { \
- if (intValue < maxUInt) \
- DO(uint, Period, uint(intValue)); \
- DO(quint64, Period, quint64(intValue)); \
- } \
- break
-#define DO(Rep, Period, val) \
- do { \
- const std::chrono::duration<Rep, Period> wait((val)); \
- QCOMPARE(QMutex::convertToMilliseconds(wait), expected); \
- } while (0)
-
- CASE(Nanoseconds, std::nano);
- CASE(Microseconds, std::micro);
- CASE(Milliseconds, std::milli);
- CASE(Seconds, std::ratio<1>);
-#undef DO
-#undef CASE
- }
-#endif
-}
+static constexpr std::chrono::milliseconds waitTimeAsDuration(waitTime);
void tst_QMutex::tryLock_non_recursive()
{
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
testsTurn.release();
@@ -226,19 +99,19 @@ void tst_QMutex::tryLock_non_recursive()
QElapsedTimer timer;
timer.start();
QVERIFY(!normalMutex.tryLock(waitTime));
- QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution);
+ QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution);
testsTurn.release();
// TEST 4: thread can acquire lock, timeout = waitTime
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.tryLock(waitTime));
- QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution);
+ QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
timer.start();
// it's non-recursive, so the following lock needs to fail
QVERIFY(!normalMutex.tryLock(waitTime));
- QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution);
+ QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
testsTurn.release();
@@ -252,7 +125,7 @@ void tst_QMutex::tryLock_non_recursive()
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.tryLock(0));
- QVERIFY(timer.elapsed() < waitTime + systemTimersResolution);
+ QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(!normalMutex.tryLock(0));
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
@@ -263,7 +136,7 @@ void tst_QMutex::tryLock_non_recursive()
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.tryLock(3000));
- QVERIFY(timer.elapsed() < 3000 + systemTimersResolution);
+ QCOMPARE_LT(timer.elapsed(), 3000 + systemTimersResolution);
normalMutex.unlock();
testsTurn.release();
@@ -274,47 +147,47 @@ void tst_QMutex::tryLock_non_recursive()
Thread thread;
thread.start();
- // TEST 1: thread can't acquire lock
+ qDebug("TEST 1: thread can't acquire lock");
testsTurn.acquire();
normalMutex.lock();
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
threadsTurn.release();
- // TEST 2: thread can acquire lock
+ qDebug("TEST 2: thread can acquire lock");
testsTurn.acquire();
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
threadsTurn.release();
- // TEST 3: thread can't acquire lock, timeout = waitTime
+ qDebug("TEST 3: thread can't acquire lock, timeout = waitTime");
testsTurn.acquire();
normalMutex.lock();
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
threadsTurn.release();
- // TEST 4: thread can acquire lock, timeout = waitTime
+ qDebug("TEST 4: thread can acquire lock, timeout = waitTime");
testsTurn.acquire();
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
threadsTurn.release();
- // TEST 5: thread can't acquire lock, timeout = 0
+ qDebug("TEST 5: thread can't acquire lock, timeout = 0");
testsTurn.acquire();
normalMutex.lock();
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
threadsTurn.release();
- // TEST 6: thread can acquire lock, timeout = 0
+ qDebug("TEST 6: thread can acquire lock, timeout = 0");
testsTurn.acquire();
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
threadsTurn.release();
- // TEST 7: thread can acquire lock, timeout = 3000 (QTBUG-24795)
+ qDebug("TEST 7: thread can acquire lock, timeout = 3000 (QTBUG-24795)");
testsTurn.acquire();
normalMutex.lock();
threadsTurn.release();
- QThread::msleep(100);
+ QThread::sleep(100ms);
normalMutex.unlock();
// wait for thread to finish
@@ -323,14 +196,12 @@ void tst_QMutex::tryLock_non_recursive()
thread.wait();
}
-void tst_QMutex::try_lock_for_non_recursive() {
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires <chrono>");
-#else
+void tst_QMutex::try_lock_for_non_recursive()
+{
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
testsTurn.release();
@@ -353,19 +224,19 @@ void tst_QMutex::try_lock_for_non_recursive() {
QElapsedTimer timer;
timer.start();
QVERIFY(!normalMutex.try_lock_for(waitTimeAsDuration));
- QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution);
+ QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution);
testsTurn.release();
// TEST 4: thread can acquire lock, timeout = waitTime
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.try_lock_for(waitTimeAsDuration));
- QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution);
+ QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
timer.start();
// it's non-recursive, so the following lock needs to fail
QVERIFY(!normalMutex.try_lock_for(waitTimeAsDuration));
- QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution);
+ QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
testsTurn.release();
@@ -379,7 +250,7 @@ void tst_QMutex::try_lock_for_non_recursive() {
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.try_lock_for(std::chrono::milliseconds::zero()));
- QVERIFY(timer.elapsed() < waitTime + systemTimersResolution);
+ QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(!normalMutex.try_lock_for(std::chrono::milliseconds::zero()));
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
@@ -390,7 +261,7 @@ void tst_QMutex::try_lock_for_non_recursive() {
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.try_lock_for(std::chrono::milliseconds(3000)));
- QVERIFY(timer.elapsed() < 3000 + systemTimersResolution);
+ QCOMPARE_LT(timer.elapsed(), 3000 + systemTimersResolution);
normalMutex.unlock();
testsTurn.release();
@@ -441,25 +312,21 @@ void tst_QMutex::try_lock_for_non_recursive() {
testsTurn.acquire();
normalMutex.lock();
threadsTurn.release();
- QThread::msleep(100);
+ QThread::sleep(100ms);
normalMutex.unlock();
// wait for thread to finish
testsTurn.acquire();
threadsTurn.release();
thread.wait();
-#endif
}
void tst_QMutex::try_lock_until_non_recursive()
{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires <chrono>");
-#else
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
const std::chrono::milliseconds systemTimersResolutionAsDuration(systemTimersResolution);
testsTurn.release();
@@ -482,19 +349,19 @@ void tst_QMutex::try_lock_until_non_recursive()
threadsTurn.acquire();
auto endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(!normalMutex.try_lock_until(endTimePoint));
- QVERIFY(std::chrono::steady_clock::now() >= endTimePoint - systemTimersResolutionAsDuration);
+ QCOMPARE_GE(std::chrono::steady_clock::now(), endTimePoint - systemTimersResolutionAsDuration);
testsTurn.release();
// TEST 4: thread can acquire lock, timeout = waitTime
threadsTurn.acquire();
endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(normalMutex.try_lock_until(endTimePoint));
- QVERIFY(std::chrono::steady_clock::now() <= endTimePoint + systemTimersResolutionAsDuration);
+ QCOMPARE_LE(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
// it's non-recursive, so the following lock needs to fail
QVERIFY(!normalMutex.try_lock_until(endTimePoint));
- QVERIFY(std::chrono::steady_clock::now() >= endTimePoint - systemTimersResolutionAsDuration);
+ QCOMPARE_GE(std::chrono::steady_clock::now(), endTimePoint - systemTimersResolutionAsDuration);
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
testsTurn.release();
@@ -508,7 +375,7 @@ void tst_QMutex::try_lock_until_non_recursive()
threadsTurn.acquire();
endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(normalMutex.try_lock_until(std::chrono::steady_clock::now()));
- QVERIFY(std::chrono::steady_clock::now() < endTimePoint + systemTimersResolutionAsDuration);
+ QCOMPARE_LT(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(!normalMutex.try_lock_until(std::chrono::steady_clock::now()));
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
@@ -519,7 +386,7 @@ void tst_QMutex::try_lock_until_non_recursive()
threadsTurn.acquire();
endTimePoint = std::chrono::steady_clock::now() + std::chrono::milliseconds(3000);
QVERIFY(normalMutex.try_lock_until(endTimePoint));
- QVERIFY(std::chrono::steady_clock::now() < endTimePoint + systemTimersResolutionAsDuration);
+ QCOMPARE_LT(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration);
normalMutex.unlock();
testsTurn.release();
@@ -570,14 +437,13 @@ void tst_QMutex::try_lock_until_non_recursive()
testsTurn.acquire();
normalMutex.lock();
threadsTurn.release();
- QThread::msleep(100);
+ QThread::sleep(100ms);
normalMutex.unlock();
// wait for thread to finish
testsTurn.acquire();
threadsTurn.release();
thread.wait();
-#endif
}
void tst_QMutex::tryLock_recursive()
@@ -585,7 +451,7 @@ void tst_QMutex::tryLock_recursive()
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
testsTurn.release();
@@ -608,14 +474,14 @@ void tst_QMutex::tryLock_recursive()
QElapsedTimer timer;
timer.start();
QVERIFY(!recursiveMutex.tryLock(waitTime));
- QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution);
+ QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution);
QVERIFY(!recursiveMutex.tryLock(0));
testsTurn.release();
threadsTurn.acquire();
timer.start();
QVERIFY(recursiveMutex.tryLock(waitTime));
- QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution);
+ QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(recursiveMutex.tryLock(waitTime));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
@@ -633,7 +499,7 @@ void tst_QMutex::tryLock_recursive()
threadsTurn.acquire();
timer.start();
QVERIFY(recursiveMutex.tryLock(0));
- QVERIFY(timer.elapsed() < waitTime + systemTimersResolution);
+ QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(recursiveMutex.tryLock(0));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
@@ -706,15 +572,11 @@ void tst_QMutex::tryLock_recursive()
void tst_QMutex::try_lock_for_recursive()
{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires <chrono>");
-#else
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
- const std::chrono::milliseconds systemTimersResolutionAsDuration(systemTimersResolution);
testsTurn.release();
threadsTurn.acquire();
@@ -736,14 +598,14 @@ void tst_QMutex::try_lock_for_recursive()
QElapsedTimer timer;
timer.start();
QVERIFY(!recursiveMutex.try_lock_for(waitTimeAsDuration));
- QVERIFY(timer.elapsed() >= waitTime - systemTimersResolution);
+ QCOMPARE_GE(timer.elapsed(), waitTime - systemTimersResolution);
QVERIFY(!recursiveMutex.try_lock_for(std::chrono::milliseconds::zero()));
testsTurn.release();
threadsTurn.acquire();
timer.start();
QVERIFY(recursiveMutex.try_lock_for(waitTimeAsDuration));
- QVERIFY(timer.elapsed() <= waitTime + systemTimersResolution);
+ QCOMPARE_LE(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(recursiveMutex.try_lock_for(waitTimeAsDuration));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
@@ -761,7 +623,7 @@ void tst_QMutex::try_lock_for_recursive()
threadsTurn.acquire();
timer.start();
QVERIFY(recursiveMutex.try_lock_for(std::chrono::milliseconds::zero()));
- QVERIFY(timer.elapsed() < waitTime + systemTimersResolution);
+ QCOMPARE_LT(timer.elapsed(), waitTime + systemTimersResolution);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(recursiveMutex.try_lock_for(std::chrono::milliseconds::zero()));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
@@ -830,18 +692,14 @@ void tst_QMutex::try_lock_for_recursive()
testsTurn.acquire();
threadsTurn.release();
thread.wait();
-#endif
}
void tst_QMutex::try_lock_until_recursive()
{
-#if !QT_HAS_INCLUDE(<chrono>)
- QSKIP("This test requires <chrono>");
-#else
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
const std::chrono::milliseconds systemTimersResolutionAsDuration(systemTimersResolution);
testsTurn.release();
@@ -864,14 +722,14 @@ void tst_QMutex::try_lock_until_recursive()
threadsTurn.acquire();
auto endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(!recursiveMutex.try_lock_until(endTimePoint));
- QVERIFY(std::chrono::steady_clock::now() >= endTimePoint - systemTimersResolutionAsDuration);
+ QCOMPARE_GE(std::chrono::steady_clock::now(), endTimePoint - systemTimersResolutionAsDuration);
QVERIFY(!recursiveMutex.try_lock());
testsTurn.release();
threadsTurn.acquire();
endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(recursiveMutex.try_lock_until(endTimePoint));
- QVERIFY(std::chrono::steady_clock::now() <= endTimePoint + systemTimersResolutionAsDuration);
+ QCOMPARE_LE(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(recursiveMutex.try_lock_until(endTimePoint));
@@ -890,7 +748,7 @@ void tst_QMutex::try_lock_until_recursive()
threadsTurn.acquire();
endTimePoint = std::chrono::steady_clock::now() + waitTimeAsDuration;
QVERIFY(recursiveMutex.try_lock_until(std::chrono::steady_clock::now()));
- QVERIFY(std::chrono::steady_clock::now() <= endTimePoint + systemTimersResolutionAsDuration);
+ QCOMPARE_LE(std::chrono::steady_clock::now(), endTimePoint + systemTimersResolutionAsDuration);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(recursiveMutex.try_lock_until(std::chrono::steady_clock::now()));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
@@ -959,7 +817,6 @@ void tst_QMutex::try_lock_until_recursive()
testsTurn.acquire();
threadsTurn.release();
thread.wait();
-#endif
}
class mutex_Thread : public QThread
@@ -972,7 +829,7 @@ public:
inline mutex_Thread(QMutex &m) : test_mutex(m) { }
- void run()
+ void run() override
{
test_mutex.lock();
@@ -993,11 +850,11 @@ public:
QMutex mutex;
QWaitCondition cond;
- QMutex &test_mutex;
+ QRecursiveMutex &test_mutex;
- inline rmutex_Thread(QMutex &m) : test_mutex(m) { }
+ inline rmutex_Thread(QRecursiveMutex &m) : test_mutex(m) { }
- void run()
+ void run() override
{
test_mutex.lock();
test_mutex.lock();
@@ -1024,7 +881,7 @@ void tst_QMutex::lock_unlock_locked_tryLock()
QMutex mutex;
mutex_Thread thread(mutex);
- QMutex rmutex(QMutex::Recursive);
+ QRecursiveMutex rmutex;
rmutex_Thread rthread(rmutex);
for (int i = 0; i < iterations; ++i) {
@@ -1085,8 +942,8 @@ void tst_QMutex::lock_unlock_locked_tryLock()
}
}
-enum { one_minute = 6 * 1000, //not really one minute, but else it is too long.
- threadCount = 10 };
+constexpr int one_minute = 6 * 1000; // not really one minute, but else it is too long.
+constexpr int threadCount = 10;
class StressTestThread : public QThread
{
@@ -1101,7 +958,7 @@ public:
t.start();
QThread::start();
}
- void run()
+ void run() override
{
while (t.elapsed() < one_minute) {
mutex.lock();
@@ -1132,7 +989,7 @@ void tst_QMutex::stressTest()
for (int i = 1; i < threadCount; ++i)
QVERIFY(threads[i].wait(10000));
QCOMPARE(StressTestThread::errorCount, 0);
- qDebug("locked %d times", int(StressTestThread::lockCount.load()));
+ qDebug("locked %d times", int(StressTestThread::lockCount.loadRelaxed()));
}
class TryLockRaceThread : public QThread
@@ -1140,7 +997,7 @@ class TryLockRaceThread : public QThread
public:
static QMutex mutex;
- void run()
+ void run() override
{
QElapsedTimer t;
t.start();
@@ -1186,12 +1043,13 @@ void tst_QMutex::tryLockDeadlock()
struct TrylockThread : QThread {
TrylockThread(QMutex &mut) : mut(mut) {}
QMutex &mut;
- void run() {
+ void run() override
+ {
for (int i = 0; i < 100000; ++i) {
if (mut.tryLock(0)) {
- if ((++tryLockDeadlockCounter) != 1)
+ if (QtPrivate::volatilePreIncrement(tryLockDeadlockCounter) != 1)
++tryLockDeadlockFailureCount;
- if ((--tryLockDeadlockCounter) != 0)
+ if (QtPrivate::volatilePreDecrement(tryLockDeadlockCounter) != 0)
++tryLockDeadlockFailureCount;
mut.unlock();
}
@@ -1208,9 +1066,9 @@ void tst_QMutex::tryLockDeadlock()
for (int i = 0; i < 100000; ++i) {
mut.lock();
- if ((++tryLockDeadlockCounter) != 1)
+ if (QtPrivate::volatilePreIncrement(tryLockDeadlockCounter) != 1)
++tryLockDeadlockFailureCount;
- if ((--tryLockDeadlockCounter) != 0)
+ if (QtPrivate::volatilePreDecrement(tryLockDeadlockCounter) != 0)
++tryLockDeadlockFailureCount;
mut.unlock();
}
@@ -1239,7 +1097,8 @@ void tst_QMutex::tryLockNegative()
QMutex &mut;
int timeout;
int tryLockResult;
- void run() {
+ void run() override
+ {
tryLockResult = mut.tryLock(timeout);
mut.unlock();
}
@@ -1281,33 +1140,33 @@ public:
t.start();
QThread::start();
}
- void run()
+ void run() override
{
quint64 i = 0;
while (t.elapsed() < one_minute) {
i++;
- uint nb = (i * 9 + lockCount.load() * 13) % threadCount;
+ uint nb = (i * 9 + uint(lockCount.loadRelaxed()) * 13) % threadCount;
QMutexLocker locker(&mutex[nb]);
- if (sentinel[nb].load()) errorCount.ref();
+ if (sentinel[nb].loadRelaxed()) errorCount.ref();
if (sentinel[nb].fetchAndAddRelaxed(5)) errorCount.ref();
if (!sentinel[nb].testAndSetRelaxed(5, 0)) errorCount.ref();
- if (sentinel[nb].load()) errorCount.ref();
+ if (sentinel[nb].loadRelaxed()) errorCount.ref();
lockCount.ref();
- nb = (nb * 17 + i * 5 + lockCount.load() * 3) % threadCount;
+ nb = (nb * 17 + i * 5 + uint(lockCount.loadRelaxed()) * 3) % threadCount;
if (mutex[nb].tryLock()) {
- if (sentinel[nb].load()) errorCount.ref();
+ if (sentinel[nb].loadRelaxed()) errorCount.ref();
if (sentinel[nb].fetchAndAddRelaxed(16)) errorCount.ref();
if (!sentinel[nb].testAndSetRelaxed(16, 0)) errorCount.ref();
- if (sentinel[nb].load()) errorCount.ref();
+ if (sentinel[nb].loadRelaxed()) errorCount.ref();
lockCount.ref();
mutex[nb].unlock();
}
- nb = (nb * 15 + i * 47 + lockCount.load() * 31) % threadCount;
+ nb = (nb * 15 + i * 47 + uint(lockCount.loadRelaxed()) * 31) % threadCount;
if (mutex[nb].tryLock(2)) {
- if (sentinel[nb].load()) errorCount.ref();
+ if (sentinel[nb].loadRelaxed()) errorCount.ref();
if (sentinel[nb].fetchAndAddRelaxed(53)) errorCount.ref();
if (!sentinel[nb].testAndSetRelaxed(53, 0)) errorCount.ref();
- if (sentinel[nb].load()) errorCount.ref();
+ if (sentinel[nb].loadRelaxed()) errorCount.ref();
lockCount.ref();
mutex[nb].unlock();
}
@@ -1321,14 +1180,15 @@ QAtomicInt MoreStressTestThread::errorCount = 0;
void tst_QMutex::moreStress()
{
- MoreStressTestThread threads[threadCount];
- for (int i = 0; i < threadCount; ++i)
- threads[i].start();
+ QVarLengthArray<MoreStressTestThread, threadCount> threads(qMin(QThread::idealThreadCount(),
+ int(threadCount)));
+ for (auto &thread : threads)
+ thread.start();
QVERIFY(threads[0].wait(one_minute + 10000));
- for (int i = 1; i < threadCount; ++i)
- QVERIFY(threads[i].wait(10000));
- qDebug("locked %d times", MoreStressTestThread::lockCount.load());
- QCOMPARE(MoreStressTestThread::errorCount.load(), 0);
+ for (auto &thread : threads)
+ QVERIFY(thread.wait(10000));
+ qDebug("locked %d times", MoreStressTestThread::lockCount.loadRelaxed());
+ QCOMPARE(MoreStressTestThread::errorCount.loadRelaxed(), 0);
}
diff --git a/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt b/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt
new file mode 100644
index 0000000000..7b2d6dc1c2
--- /dev/null
+++ b/tests/auto/corelib/thread/qmutexlocker/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmutexlocker Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmutexlocker LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmutexlocker
+ SOURCES
+ tst_qmutexlocker.cpp
+)
diff --git a/tests/auto/corelib/thread/qmutexlocker/qmutexlocker.pro b/tests/auto/corelib/thread/qmutexlocker/qmutexlocker.pro
deleted file mode 100644
index 76ec0471ca..0000000000
--- a/tests/auto/corelib/thread/qmutexlocker/qmutexlocker.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmutexlocker
-QT = core testlib
-SOURCES = tst_qmutexlocker.cpp
diff --git a/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp b/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp
index 67db5d1458..6ccab04c27 100644
--- a/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp
+++ b/tests/auto/corelib/thread/qmutexlocker/tst_qmutexlocker.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QCoreApplication>
#include <QMutexLocker>
@@ -36,7 +11,7 @@
class tst_QMutexLockerThread : public QThread
{
public:
- QMutex mutex;
+ QRecursiveMutex mutex;
QSemaphore semaphore, testSemaphore;
void waitForTest()
@@ -45,10 +20,6 @@ public:
testSemaphore.acquire();
}
- tst_QMutexLockerThread()
- : mutex(QMutex::Recursive)
- {
- }
};
class tst_QMutexLocker : public QObject
@@ -71,6 +42,7 @@ private slots:
void scopeTest();
void unlockAndRelockTest();
void lockerStateTest();
+ void moveSemantics();
};
void tst_QMutexLocker::scopeTest()
@@ -78,12 +50,13 @@ void tst_QMutexLocker::scopeTest()
class ScopeTestThread : public tst_QMutexLockerThread
{
public:
- void run()
+ void run() override
{
waitForTest();
{
QMutexLocker locker(&mutex);
+ QVERIFY(locker.isLocked());
waitForTest();
}
@@ -114,7 +87,7 @@ void tst_QMutexLocker::scopeTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
@@ -123,19 +96,26 @@ void tst_QMutexLocker::unlockAndRelockTest()
class UnlockAndRelockThread : public tst_QMutexLockerThread
{
public:
- void run()
+ void run() override
{
QMutexLocker locker(&mutex);
+ QVERIFY(locker.isLocked());
waitForTest();
+ QVERIFY(locker.isLocked());
locker.unlock();
+ QVERIFY(!locker.isLocked());
waitForTest();
+ QVERIFY(!locker.isLocked());
locker.relock();
+ QVERIFY(locker.isLocked());
waitForTest();
+
+ QVERIFY(locker.isLocked());
}
};
@@ -161,7 +141,7 @@ void tst_QMutexLocker::unlockAndRelockTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
void tst_QMutexLocker::lockerStateTest()
@@ -169,14 +149,17 @@ void tst_QMutexLocker::lockerStateTest()
class LockerStateThread : public tst_QMutexLockerThread
{
public:
- void run()
+ void run() override
{
{
QMutexLocker locker(&mutex);
- locker.relock();
+ QVERIFY(locker.isLocked());
+
locker.unlock();
+ QVERIFY(!locker.isLocked());
waitForTest();
+ QVERIFY(!locker.isLocked());
}
waitForTest();
@@ -201,7 +184,73 @@ void tst_QMutexLocker::lockerStateTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
+}
+
+void tst_QMutexLocker::moveSemantics()
+{
+ {
+ QMutexLocker<QMutex> locker(nullptr);
+ QVERIFY(!locker.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+
+ QMutexLocker locker2(std::move(locker));
+ QVERIFY(!locker.isLocked());
+ QVERIFY(!locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), nullptr);
+ }
+
+ QMutex mutex;
+
+ {
+ QMutexLocker locker(&mutex);
+ QVERIFY(locker.isLocked());
+ QCOMPARE(locker.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+
+ QMutexLocker locker2(std::move(locker));
+ QVERIFY(!locker.isLocked());
+ QVERIFY(locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+ }
+
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+
+ {
+ QMutex mutex;
+ QMutexLocker locker(&mutex);
+ QVERIFY(locker.isLocked());
+ QCOMPARE(locker.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+
+ locker.unlock();
+ QVERIFY(!locker.isLocked());
+ QCOMPARE(locker.mutex(), &mutex);
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+
+ QMutexLocker locker2(std::move(locker));
+ QVERIFY(!locker.isLocked());
+ QVERIFY(!locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), &mutex);
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
+
+ locker2.relock();
+ QVERIFY(!locker.isLocked());
+ QVERIFY(locker2.isLocked());
+ QCOMPARE(locker.mutex(), nullptr);
+ QCOMPARE(locker2.mutex(), &mutex);
+ QVERIFY(!mutex.tryLock());
+ }
+
+ QVERIFY(mutex.tryLock());
+ mutex.unlock();
}
QTEST_MAIN(tst_QMutexLocker)
diff --git a/tests/auto/corelib/thread/qpromise/CMakeLists.txt b/tests/auto/corelib/thread/qpromise/CMakeLists.txt
new file mode 100644
index 0000000000..c1ca30b34a
--- /dev/null
+++ b/tests/auto/corelib/thread/qpromise/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpromise Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpromise LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qpromise
+ SOURCES
+ tst_qpromise.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp b/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp
new file mode 100644
index 0000000000..2cef0dca95
--- /dev/null
+++ b/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp
@@ -0,0 +1,158 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+// Note: this file is published under a license that is different from a default
+// test sources license. This is intentional to comply with default
+// snippet license.
+
+#include <QCoreApplication>
+#include <QTest>
+
+#include <qfuture.h>
+#include <qfuturewatcher.h>
+#include <qpromise.h>
+#include <qscopedpointer.h>
+#include <qsharedpointer.h>
+
+class snippet_QPromise
+{
+public:
+ static void basicExample();
+ static void multithreadExample();
+ static void suspendExample();
+};
+
+void snippet_QPromise::basicExample()
+{
+#if QT_CONFIG(cxx11_future)
+//! [basic]
+ QPromise<int> promise;
+ QFuture<int> future = promise.future();
+
+ QScopedPointer<QThread> thread(QThread::create([] (QPromise<int> promise) {
+ promise.start(); // notifies QFuture that the computation is started
+ promise.addResult(42);
+ promise.finish(); // notifies QFuture that the computation is finished
+ }, std::move(promise)));
+ thread->start();
+
+ future.waitForFinished(); // blocks until QPromise::finish is called
+ future.result(); // returns 42
+//! [basic]
+
+ QCOMPARE(future.result(), 42);
+ thread->wait();
+#endif
+}
+
+void snippet_QPromise::multithreadExample()
+{
+#if QT_CONFIG(cxx11_future)
+//! [multithread_init]
+ QSharedPointer<QPromise<int>> sharedPromise(new QPromise<int>());
+ QFuture<int> future = sharedPromise->future();
+
+ // ...
+
+ sharedPromise->start();
+//! [multithread_init]
+
+//! [multithread_main]
+ // here, QPromise is shared between threads via a smart pointer
+ QScopedPointer<QThread> threads[] = {
+ QScopedPointer<QThread>(QThread::create([] (auto sharedPromise) {
+ sharedPromise->addResult(0, 0); // adds value 0 by index 0
+ }, sharedPromise)),
+ QScopedPointer<QThread>(QThread::create([] (auto sharedPromise) {
+ sharedPromise->addResult(-1, 1); // adds value -1 by index 1
+ }, sharedPromise)),
+ QScopedPointer<QThread>(QThread::create([] (auto sharedPromise) {
+ sharedPromise->addResult(-2, 2); // adds value -2 by index 2
+ }, sharedPromise)),
+ // ...
+ };
+ // start all threads
+ for (auto& t : threads)
+ t->start();
+
+ // ...
+
+ future.resultAt(0); // waits until result at index 0 becomes available. returns value 0
+ future.resultAt(1); // waits until result at index 1 becomes available. returns value -1
+ future.resultAt(2); // waits until result at index 2 becomes available. returns value -2
+//! [multithread_main]
+
+ QCOMPARE(future.resultAt(0), 0);
+ QCOMPARE(future.resultAt(1), -1);
+ QCOMPARE(future.resultAt(2), -2);
+
+ for (auto& t : threads)
+ t->wait();
+//! [multithread_cleanup]
+ sharedPromise->finish();
+//! [multithread_cleanup]
+#endif
+}
+
+void snippet_QPromise::suspendExample()
+{
+#if QT_CONFIG(cxx11_future)
+//! [suspend_start]
+ // Create promise and future
+ QPromise<int> promise;
+ QFuture<int> future = promise.future();
+
+ promise.start();
+ // Start a computation thread that supports suspension and cancellation
+ QScopedPointer<QThread> thread(QThread::create([] (QPromise<int> promise) {
+ for (int i = 0; i < 100; ++i) {
+ promise.addResult(i);
+ promise.suspendIfRequested(); // support suspension
+ if (promise.isCanceled()) // support cancellation
+ break;
+ }
+ promise.finish();
+ }, std::move(promise)));
+ thread->start();
+//! [suspend_start]
+
+//! [suspend_suspend]
+ future.suspend();
+//! [suspend_suspend]
+
+ // wait in calling thread until future.isSuspended() becomes true or do
+ // something meanwhile
+ while (!future.isSuspended()) {
+ QThread::msleep(50);
+ }
+
+//! [suspend_intermediateResults]
+ future.resultCount(); // returns some number between 0 and 100
+ for (int i = 0; i < future.resultCount(); ++i) {
+ // process results available before suspension
+ }
+//! [suspend_intermediateResults]
+
+ // at least one result is available due to the logic inside a thread
+ QVERIFY(future.resultCount() > 0);
+ QVERIFY(future.resultCount() <= 100);
+ for (int i = 0; i < future.resultCount(); ++i) {
+ QCOMPARE(future.resultAt(i), i);
+ }
+
+//! [suspend_end]
+ future.resume(); // resumes computation, this call will unblock the promise
+ // alternatively, call future.cancel() to stop the computation
+
+ future.waitForFinished();
+ future.results(); // returns all computation results - array of values from 0 to 99
+//! [suspend_end]
+
+ thread->wait();
+
+ QCOMPARE(future.resultCount(), 100);
+ QList<int> expected(100);
+ std::iota(expected.begin(), expected.end(), 0);
+ QCOMPARE(future.results(), expected);
+#endif
+}
diff --git a/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp b/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp
new file mode 100644
index 0000000000..2c12e41c93
--- /dev/null
+++ b/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp
@@ -0,0 +1,784 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QCoreApplication>
+#include <QDebug>
+
+#define QPROMISE_TEST
+
+#include <QTest>
+#include <qfuture.h>
+#include <qfuturewatcher.h>
+#include <qpromise.h>
+
+#include <algorithm>
+#include <memory>
+#include <chrono>
+
+using namespace std::chrono_literals;
+
+class tst_QPromise : public QObject
+{
+ Q_OBJECT
+private slots:
+ // simple test cases
+ void promise();
+ void futureFromPromise();
+ void addResult();
+ void addResultWithBracedInitializer();
+ void addResultOutOfOrder();
+#ifndef QT_NO_EXCEPTIONS
+ void setException();
+#endif
+ void cancel();
+ void progress();
+
+ // complicated test cases
+ void addInThread();
+ void addInThreadMoveOnlyObject(); // separate test case - QTBUG-84736
+ void reportFromMultipleThreads();
+ void reportFromMultipleThreadsByMovedPromise();
+ void doNotCancelWhenFinished();
+#ifndef QT_NO_EXCEPTIONS
+ void cancelWhenDestroyed();
+#endif
+ void cancelWhenReassigned();
+ void cancelWhenDestroyedWithoutStarting();
+ void cancelWhenDestroyedRunsContinuations();
+ void cancelWhenDestroyedWithFailureHandler(); // QTBUG-114606
+ void continuationsRunWhenFinished();
+ void finishWhenSwapped();
+ void cancelWhenMoved();
+ void waitUntilResumed();
+ void waitUntilCanceled();
+
+ // snippets (external):
+ void snippet_basicExample();
+ void snippet_multithreadExample();
+ void snippet_suspendExample();
+};
+
+struct TrivialType { int field = 0; };
+struct CopyOnlyType {
+ constexpr CopyOnlyType(int field = 0) noexcept : field(field) {}
+ CopyOnlyType(const CopyOnlyType &) = default;
+ CopyOnlyType& operator=(const CopyOnlyType &) = default;
+ ~CopyOnlyType() = default;
+
+ int field;
+};
+struct MoveOnlyType {
+ Q_DISABLE_COPY(MoveOnlyType)
+ constexpr MoveOnlyType(int field = 0) noexcept : field(field) {}
+ MoveOnlyType(MoveOnlyType &&) = default;
+ MoveOnlyType& operator=(MoveOnlyType &&) = default;
+ ~MoveOnlyType() = default;
+
+ int field;
+};
+bool operator==(const CopyOnlyType &a, const CopyOnlyType &b) { return a.field == b.field; }
+bool operator==(const MoveOnlyType &a, const MoveOnlyType &b) { return a.field == b.field; }
+
+// A wrapper for a test function, calls the function, if it fails, reports failure
+#define RUN_TEST_FUNC(test, ...) \
+do { \
+ test(__VA_ARGS__); \
+ if (QTest::currentTestFailed()) \
+ QFAIL("Test case " #test "(" #__VA_ARGS__ ") failed"); \
+} while (false)
+
+#if QT_CONFIG(cxx11_future)
+// std::thread-like wrapper that ensures that the thread is joined at the end of
+// a scope to prevent potential std::terminate
+struct ThreadWrapper
+{
+ std::unique_ptr<QThread> t;
+ template<typename Function>
+ ThreadWrapper(Function &&f) : t(QThread::create(std::forward<Function>(f)))
+ {
+ t->start();
+ }
+ void join() { t->wait(); }
+ ~ThreadWrapper()
+ {
+ t->wait();
+ }
+};
+#endif
+
+void tst_QPromise::promise()
+{
+ const auto testCanCreatePromise = [] (auto promise) {
+ promise.start();
+ promise.suspendIfRequested(); // should not block on its own
+ promise.finish();
+ };
+
+ RUN_TEST_FUNC(testCanCreatePromise, QPromise<void>());
+ RUN_TEST_FUNC(testCanCreatePromise, QPromise<int>());
+ RUN_TEST_FUNC(testCanCreatePromise, QPromise<QList<float>>());
+ RUN_TEST_FUNC(testCanCreatePromise, QPromise<TrivialType>());
+ RUN_TEST_FUNC(testCanCreatePromise, QPromise<CopyOnlyType>());
+ RUN_TEST_FUNC(testCanCreatePromise, QPromise<MoveOnlyType>());
+}
+
+void tst_QPromise::futureFromPromise()
+{
+ const auto testCanCreateFutureFromPromise = [] (auto promise) {
+ auto future = promise.future();
+ QVERIFY(!future.isValid());
+
+ promise.start();
+ QCOMPARE(future.isStarted(), true);
+ QVERIFY(future.isValid());
+
+ promise.finish();
+ QCOMPARE(future.isFinished(), true);
+ QVERIFY(future.isValid());
+
+ future.waitForFinished();
+ };
+
+ RUN_TEST_FUNC(testCanCreateFutureFromPromise, QPromise<void>());
+ RUN_TEST_FUNC(testCanCreateFutureFromPromise, QPromise<double>());
+ RUN_TEST_FUNC(testCanCreateFutureFromPromise, QPromise<QList<int>>());
+ RUN_TEST_FUNC(testCanCreateFutureFromPromise, QPromise<TrivialType>());
+ RUN_TEST_FUNC(testCanCreateFutureFromPromise, QPromise<CopyOnlyType>());
+ RUN_TEST_FUNC(testCanCreateFutureFromPromise, QPromise<MoveOnlyType>());
+}
+
+void tst_QPromise::addResult()
+{
+ QPromise<int> promise;
+ auto f = promise.future();
+
+ // add as lvalue
+ int resultAt0 = 456;
+ {
+ QVERIFY(promise.addResult(resultAt0));
+ QCOMPARE(f.resultCount(), 1);
+ QCOMPARE(f.result(), resultAt0);
+ QCOMPARE(f.resultAt(0), resultAt0);
+ }
+ // add as rvalue
+ {
+ int result = 789;
+ QVERIFY(promise.addResult(789));
+ QCOMPARE(f.resultCount(), 2);
+ QCOMPARE(f.resultAt(1), result);
+ }
+ // add at position
+ {
+ int result = 56238;
+ QVERIFY(promise.addResult(result, 2));
+ QCOMPARE(f.resultCount(), 3);
+ QCOMPARE(f.resultAt(2), result);
+ }
+ // add multiple results in one go:
+ {
+ QList results = {42, 4242, 424242};
+ QVERIFY(promise.addResults(results));
+ QCOMPARE(f.resultCount(), 6);
+ QCOMPARE(f.resultAt(3), 42);
+ QCOMPARE(f.resultAt(4), 4242);
+ QCOMPARE(f.resultAt(5), 424242);
+ }
+ // add as lvalue at position and overwrite
+ {
+ int result = -1;
+ const auto originalCount = f.resultCount();
+ QVERIFY(!promise.addResult(result, 0));
+ QCOMPARE(f.resultCount(), originalCount);
+ QCOMPARE(f.resultAt(0), resultAt0); // overwrite does not work
+ }
+ // add as rvalue at position and overwrite
+ {
+ const auto originalCount = f.resultCount();
+ QVERIFY(!promise.addResult(-1, 0));
+ QCOMPARE(f.resultCount(), originalCount);
+ QCOMPARE(f.resultAt(0), resultAt0); // overwrite does not work
+ }
+}
+
+void tst_QPromise::addResultWithBracedInitializer() // QTBUG-111826
+{
+ struct MyClass
+ {
+ QString strValue;
+ int intValue = 0;
+#ifndef __cpp_aggregate_paren_init // make emplacement work with MyClass
+ MyClass(QString s, int i) : strValue(std::move(s)), intValue(i) {}
+#endif
+ };
+
+ {
+ QPromise<MyClass> myPromise;
+ myPromise.addResult({"bar", 1});
+ }
+
+ {
+ QPromise<MyClass> myPromise;
+ myPromise.emplaceResult("bar", 1);
+ }
+}
+
+void tst_QPromise::addResultOutOfOrder()
+{
+ // Compare results available in QFuture to expected results
+ const auto compareResults = [] (const auto &future, auto expected) {
+ QCOMPARE(future.resultCount(), expected.size());
+ // index based loop
+ for (int i = 0; i < future.resultCount(); ++i)
+ QCOMPARE(future.resultAt(i), expected.at(i));
+ // iterator based loop
+ QVERIFY(std::equal(future.begin(), future.end(), expected.begin()));
+ };
+
+ // out of order results without a gap
+ {
+ QPromise<int> promise;
+ auto f = promise.future();
+ QVERIFY(promise.addResult(456, 1));
+ QCOMPARE(f.resultCount(), 0);
+ QVERIFY(promise.addResult(123, 0));
+
+ QList<int> expected({123, 456});
+ RUN_TEST_FUNC(compareResults, f, expected);
+ QCOMPARE(f.results(), expected);
+ }
+
+ // out of order results with a gap that is closed "later"
+ {
+ QPromise<int> promise;
+ auto f = promise.future();
+ QVERIFY(promise.addResult(0, 0));
+ QVERIFY(promise.addResult(1, 1));
+ QVERIFY(promise.addResult(3, 3)); // intentional gap here
+
+ QList<int> expectedWhenGapExists({0, 1});
+ RUN_TEST_FUNC(compareResults, f, expectedWhenGapExists);
+ QCOMPARE(f.resultAt(3), 3);
+
+ QList<int> expectedWhenNoGap({0, 1, 2, 3});
+ QVERIFY(promise.addResult(2, 2)); // fill a gap with a value
+ RUN_TEST_FUNC(compareResults, f, expectedWhenNoGap);
+ QCOMPARE(f.results(), expectedWhenNoGap);
+ }
+}
+
+#ifndef QT_NO_EXCEPTIONS
+void tst_QPromise::setException()
+{
+ struct TestException {}; // custom exception class
+ const auto testExceptionCaught = [] (auto promise, const auto& exception) {
+ auto f = promise.future();
+ promise.start();
+ promise.setException(exception);
+ promise.finish();
+
+ bool caught = false;
+ try {
+ f.waitForFinished();
+ } catch (const QException&) {
+ caught = true;
+ } catch (const TestException&) {
+ caught = true;
+ }
+ QVERIFY(caught);
+ };
+
+ RUN_TEST_FUNC(testExceptionCaught, QPromise<void>(), QException());
+ RUN_TEST_FUNC(testExceptionCaught, QPromise<int>(), QException());
+ RUN_TEST_FUNC(testExceptionCaught, QPromise<void>(),
+ std::make_exception_ptr(TestException()));
+ RUN_TEST_FUNC(testExceptionCaught, QPromise<int>(),
+ std::make_exception_ptr(TestException()));
+ RUN_TEST_FUNC(testExceptionCaught, QPromise<CopyOnlyType>(),
+ std::make_exception_ptr(TestException()));
+ RUN_TEST_FUNC(testExceptionCaught, QPromise<MoveOnlyType>(),
+ std::make_exception_ptr(TestException()));
+}
+#endif
+
+void tst_QPromise::cancel()
+{
+ const auto testCancel = [] (auto promise) {
+ auto f = promise.future();
+ f.cancel();
+ QCOMPARE(promise.isCanceled(), true);
+ };
+
+ testCancel(QPromise<void>());
+ testCancel(QPromise<int>());
+ testCancel(QPromise<CopyOnlyType>());
+ testCancel(QPromise<MoveOnlyType>());
+}
+
+void tst_QPromise::progress()
+{
+ const auto testProgress = [] (auto promise) {
+ auto f = promise.future();
+
+ promise.setProgressRange(0, 2);
+ QCOMPARE(f.progressMinimum(), 0);
+ QCOMPARE(f.progressMaximum(), 2);
+
+ QCOMPARE(f.progressValue(), 0);
+ promise.setProgressValue(1);
+ QCOMPARE(f.progressValue(), 1);
+ promise.setProgressValue(0); // decrement
+ QCOMPARE(f.progressValue(), 1);
+ promise.setProgressValue(10); // out of range
+ QCOMPARE(f.progressValue(), 1);
+
+ promise.setProgressRange(0, 100);
+ promise.setProgressValueAndText(50, u8"50%");
+ QCOMPARE(f.progressValue(), 50);
+ QCOMPARE(f.progressText(), u8"50%");
+ };
+
+ RUN_TEST_FUNC(testProgress, QPromise<void>());
+ RUN_TEST_FUNC(testProgress, QPromise<int>());
+ RUN_TEST_FUNC(testProgress, QPromise<CopyOnlyType>());
+ RUN_TEST_FUNC(testProgress, QPromise<MoveOnlyType>());
+}
+
+void tst_QPromise::addInThread()
+{
+#if QT_CONFIG(cxx11_future)
+ const auto testAddResult = [] (auto promise, const auto &result) {
+ promise.start();
+ auto f = promise.future();
+ // move construct QPromise
+ ThreadWrapper thr([p = std::move(promise), &result] () mutable {
+ p.addResult(result);
+ });
+ // Waits for result first
+ QCOMPARE(f.result(), result);
+ QCOMPARE(f.resultAt(0), result);
+ };
+
+ RUN_TEST_FUNC(testAddResult, QPromise<int>(), 42);
+ RUN_TEST_FUNC(testAddResult, QPromise<QString>(), u8"42");
+ RUN_TEST_FUNC(testAddResult, QPromise<CopyOnlyType>(), CopyOnlyType{99});
+#endif
+}
+
+void tst_QPromise::addInThreadMoveOnlyObject()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<MoveOnlyType> promise;
+ promise.start();
+ auto f = promise.future();
+
+ ThreadWrapper thr([p = std::move(promise)] () mutable {
+ p.addResult(MoveOnlyType{-11});
+ });
+
+ // Iterators wait for result first
+ for (auto& result : f)
+ QCOMPARE(result, MoveOnlyType{-11});
+#endif
+}
+
+void tst_QPromise::reportFromMultipleThreads()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<int> promise;
+ auto f = promise.future();
+ promise.start();
+
+ ThreadWrapper threads[] = {
+ ThreadWrapper([&promise] () mutable { promise.addResult(42); }),
+ ThreadWrapper([&promise] () mutable { promise.addResult(43); }),
+ ThreadWrapper([&promise] () mutable { promise.addResult(44); }),
+ };
+ for (auto& t : threads)
+ t.join();
+ promise.finish();
+
+ QList<int> expected = {42, 43, 44};
+ for (auto actual : f.results()) {
+ QVERIFY(std::find(expected.begin(), expected.end(), actual) != expected.end());
+ expected.removeOne(actual);
+ }
+#endif
+}
+
+void tst_QPromise::reportFromMultipleThreadsByMovedPromise()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<int> initialPromise;
+ auto f = initialPromise.future();
+ {
+ // Move QPromise into local scope: local QPromise (as being
+ // move-constructed) must be able to set results, QFuture must still
+ // hold correct references to results.
+ auto promise = std::move(initialPromise);
+ promise.start();
+ ThreadWrapper threads[] = {
+ ThreadWrapper([&promise] () mutable { promise.addResult(42); }),
+ ThreadWrapper([&promise] () mutable { promise.addResult(43); }),
+ ThreadWrapper([&promise] () mutable { promise.addResult(44); }),
+ };
+ for (auto& t : threads)
+ t.join();
+ promise.finish();
+ }
+
+ QCOMPARE(f.isFinished(), true);
+ QCOMPARE(f.isValid(), true);
+
+ QList<int> expected = {42, 43, 44};
+ for (auto actual : f.results()) {
+ QVERIFY(std::find(expected.begin(), expected.end(), actual) != expected.end());
+ expected.removeOne(actual);
+ }
+#endif
+}
+
+void tst_QPromise::doNotCancelWhenFinished()
+{
+#if QT_CONFIG(cxx11_future)
+ const auto testFinishedPromise = [] (auto promise) {
+ auto f = promise.future();
+ promise.start();
+
+ // Finish QPromise inside thread, destructor must not call cancel()
+ ThreadWrapper([p = std::move(promise)] () mutable { p.finish(); }).join();
+
+ f.waitForFinished();
+
+ QCOMPARE(f.isFinished(), true);
+ QCOMPARE(f.isCanceled(), false);
+ };
+
+ RUN_TEST_FUNC(testFinishedPromise, QPromise<void>());
+ RUN_TEST_FUNC(testFinishedPromise, QPromise<int>());
+ RUN_TEST_FUNC(testFinishedPromise, QPromise<QString>());
+ RUN_TEST_FUNC(testFinishedPromise, QPromise<CopyOnlyType>());
+ RUN_TEST_FUNC(testFinishedPromise, QPromise<MoveOnlyType>());
+#endif
+}
+
+#ifndef QT_NO_EXCEPTIONS
+void tst_QPromise::cancelWhenDestroyed()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<int> initialPromise;
+ auto f = initialPromise.future();
+
+ try {
+ // Move QPromise to local scope. On destruction, it must call cancel().
+ auto promise = std::move(initialPromise);
+ promise.start();
+ ThreadWrapper threads[] = {
+ ThreadWrapper([&promise] () mutable { promise.addResult(42); }),
+ ThreadWrapper([&promise] () mutable { promise.addResult(43); }),
+ ThreadWrapper([&promise] () mutable { promise.addResult(44); }),
+ };
+ for (auto& t : threads)
+ t.join();
+ throw "Throw in the middle, we lose our promise here, finish() not called!";
+ promise.finish();
+ } catch (...) {}
+
+ QCOMPARE(f.isFinished(), true);
+ QCOMPARE(f.isCanceled(), true);
+
+ // Results are still available despite throw
+ QList<int> expected = {42, 43, 44};
+ for (auto actual : f.results()) {
+ QVERIFY(std::find(expected.begin(), expected.end(), actual) != expected.end());
+ expected.removeOne(actual);
+ }
+#endif
+}
+#endif
+
+void tst_QPromise::cancelWhenReassigned()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<int> promise;
+ auto f = promise.future();
+ promise.start();
+
+ ThreadWrapper thr([p = std::move(promise)] () mutable {
+ QThread::sleep(100ms);
+ p = QPromise<int>(); // assign new promise, old must be correctly destroyed
+ });
+
+ f.waitForFinished(); // wait for the old promise
+
+ QCOMPARE(f.isFinished(), true);
+ QCOMPARE(f.isCanceled(), true);
+#endif
+}
+
+template <typename T>
+static inline void testCancelWhenDestroyedWithoutStarting()
+{
+ QFuture<T> future;
+ {
+ QPromise<T> promise;
+ future = promise.future();
+ }
+ future.waitForFinished();
+ QVERIFY(!future.isStarted());
+ QVERIFY(future.isCanceled());
+ QVERIFY(future.isFinished());
+}
+
+void tst_QPromise::cancelWhenDestroyedWithoutStarting()
+{
+ testCancelWhenDestroyedWithoutStarting<void>();
+ testCancelWhenDestroyedWithoutStarting<int>();
+ testCancelWhenDestroyedWithoutStarting<CopyOnlyType>();
+ testCancelWhenDestroyedWithoutStarting<MoveOnlyType>();
+}
+
+template <typename T>
+static inline void testCancelWhenDestroyedRunsContinuations()
+{
+ QFuture<T> future;
+ bool onCanceledCalled = false;
+ bool thenCalled = false;
+ {
+ QPromise<T> promise;
+ future = promise.future();
+ future.then([&] (auto&&) {
+ thenCalled = true;
+ }).onCanceled([&] () {
+ onCanceledCalled = true;
+ });
+ }
+ QVERIFY(future.isFinished());
+ QVERIFY(!thenCalled);
+ QVERIFY(onCanceledCalled);
+}
+
+void tst_QPromise::cancelWhenDestroyedRunsContinuations()
+{
+ testCancelWhenDestroyedRunsContinuations<void>();
+ testCancelWhenDestroyedRunsContinuations<int>();
+ testCancelWhenDestroyedRunsContinuations<CopyOnlyType>();
+ testCancelWhenDestroyedRunsContinuations<MoveOnlyType>();
+}
+
+template <typename T>
+static inline void testCancelWhenDestroyedWithFailureHandler()
+{
+ QFuture<T> future;
+ bool onFailedCalled = false;
+ bool thenCalled = false;
+ {
+ QPromise<T> promise;
+ future = promise.future();
+ future
+ .onFailed([&] () {
+ onFailedCalled = true;
+ if constexpr (!std::is_same_v<void, T>)
+ return T{};
+ })
+ .then([&] (auto&&) {
+ thenCalled = true;
+ });
+ }
+ QVERIFY(future.isFinished());
+ QVERIFY(!onFailedCalled);
+ QVERIFY(!thenCalled);
+}
+
+void tst_QPromise::cancelWhenDestroyedWithFailureHandler()
+{
+#ifndef QT_NO_EXCEPTIONS
+ testCancelWhenDestroyedWithFailureHandler<void>();
+ testCancelWhenDestroyedWithFailureHandler<int>();
+ testCancelWhenDestroyedWithFailureHandler<CopyOnlyType>();
+ testCancelWhenDestroyedWithFailureHandler<MoveOnlyType>();
+#else
+ QSKIP("Exceptions are disabled, skipping the test");
+#endif
+}
+
+template <typename T>
+static inline void testContinuationsRunWhenFinished()
+{
+ QPromise<T> promise;
+ QFuture<T> future = promise.future();
+
+ bool thenCalled = false;
+ future.then([&] (auto&&) {
+ thenCalled = true;
+ });
+
+ promise.start();
+ if constexpr (!std::is_void_v<T>) {
+ promise.addResult(T{});
+ }
+ promise.finish();
+
+ QVERIFY(thenCalled);
+}
+
+void tst_QPromise::continuationsRunWhenFinished()
+{
+ testContinuationsRunWhenFinished<void>();
+ testContinuationsRunWhenFinished<int>();
+ testContinuationsRunWhenFinished<CopyOnlyType>();
+ testContinuationsRunWhenFinished<MoveOnlyType>();
+}
+
+void tst_QPromise::finishWhenSwapped()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<int> promise1;
+ auto f1 = promise1.future();
+ promise1.start();
+
+ QPromise<int> promise2;
+ auto f2 = promise2.future();
+ promise2.start();
+
+ ThreadWrapper thr([&promise1, &promise2] () mutable {
+ QThread::sleep(100ms);
+ promise1.addResult(0);
+ promise2.addResult(1);
+ swap(promise1, promise2); // ADL must resolve this
+ promise1.addResult(2);
+ promise2.addResult(3);
+ promise1.finish(); // this finish is for future #2
+ promise2.finish(); // this finish is for future #1
+ });
+
+ f1.waitForFinished();
+ f2.waitForFinished();
+
+ // Future #1 and #2 are finished inside thread
+ QCOMPARE(f1.isFinished(), true);
+ QCOMPARE(f1.isCanceled(), false);
+
+ QCOMPARE(f2.isFinished(), true);
+ QCOMPARE(f2.isCanceled(), false);
+
+ QCOMPARE(f1.resultAt(0), 0);
+ QCOMPARE(f1.resultAt(1), 3);
+
+ QCOMPARE(f2.resultAt(0), 1);
+ QCOMPARE(f2.resultAt(1), 2);
+#endif
+}
+
+template <typename T>
+void testCancelWhenMoved()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<T> promise1;
+ auto f1 = promise1.future();
+ promise1.start();
+
+ QPromise<T> promise2;
+ auto f2 = promise2.future();
+ promise2.start();
+
+ // Move promises to local scope to test cancellation behavior
+ ThreadWrapper thr([p1 = std::move(promise1), p2 = std::move(promise2)] () mutable {
+ QThread::sleep(100ms);
+ p1 = std::move(p2);
+ p1.finish(); // this finish is for future #2
+ });
+
+ f1.waitForFinished();
+ f2.waitForFinished();
+
+ // Future #1 is implicitly cancelled inside thread
+ QCOMPARE(f1.isFinished(), true);
+ QCOMPARE(f1.isCanceled(), true);
+
+ // Future #2 is explicitly finished inside thread
+ QCOMPARE(f2.isFinished(), true);
+ QCOMPARE(f2.isCanceled(), false);
+#endif
+}
+
+void tst_QPromise::cancelWhenMoved()
+{
+ testCancelWhenMoved<void>();
+ testCancelWhenMoved<int>();
+ testCancelWhenMoved<CopyOnlyType>();
+ testCancelWhenMoved<MoveOnlyType>();
+}
+
+void tst_QPromise::waitUntilResumed()
+{
+#if !QT_CONFIG(cxx11_future)
+ QSKIP("This test requires QThread::create");
+#else
+ QPromise<int> promise;
+ promise.start();
+ auto f = promise.future();
+ f.suspend();
+
+ ThreadWrapper thr([p = std::move(promise)] () mutable {
+ p.suspendIfRequested();
+ p.addResult(42); // result added after suspend
+ p.finish();
+ });
+
+ while (!f.isSuspended()) { // busy wait until worker thread suspends
+ QCOMPARE(f.isFinished(), false); // exit condition in case of failure
+ QThread::sleep(50ms); // allow another thread to actually carry on
+ }
+
+ f.resume();
+ f.waitForFinished();
+
+ QCOMPARE(f.resultCount(), 1);
+ QCOMPARE(f.result(), 42);
+#endif
+}
+
+void tst_QPromise::waitUntilCanceled()
+{
+#if QT_CONFIG(cxx11_future)
+ QPromise<int> promise;
+ promise.start();
+ auto f = promise.future();
+ f.suspend();
+
+ ThreadWrapper thr([p = std::move(promise)] () mutable {
+ p.suspendIfRequested();
+ p.addResult(42); // result not added due to QFuture::cancel()
+ p.finish();
+ });
+
+ while (!f.isSuspended()) { // busy wait until worker thread suspends
+ QCOMPARE(f.isFinished(), false); // exit condition in case of failure
+ QThread::sleep(50ms); // allow another thread to actually carry on
+ }
+
+ f.cancel();
+ f.waitForFinished();
+
+ QCOMPARE(f.resultCount(), 0);
+#endif
+}
+
+// Below is a quick and dirty hack to make snippets a part of a test suite
+#include "snippet_qpromise.cpp"
+void tst_QPromise::snippet_basicExample()
+{
+ snippet_QPromise::basicExample();
+}
+
+void tst_QPromise::snippet_multithreadExample()
+{
+ snippet_QPromise::multithreadExample();
+}
+
+void tst_QPromise::snippet_suspendExample()
+{
+ snippet_QPromise::suspendExample();
+}
+
+QTEST_MAIN(tst_QPromise)
+#include "tst_qpromise.moc"
diff --git a/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt b/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt
new file mode 100644
index 0000000000..7e80a4df81
--- /dev/null
+++ b/tests/auto/corelib/thread/qreadlocker/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qreadlocker Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qreadlocker LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qreadlocker
+ SOURCES
+ tst_qreadlocker.cpp
+)
diff --git a/tests/auto/corelib/thread/qreadlocker/qreadlocker.pro b/tests/auto/corelib/thread/qreadlocker/qreadlocker.pro
deleted file mode 100644
index ba46786750..0000000000
--- a/tests/auto/corelib/thread/qreadlocker/qreadlocker.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qreadlocker
-QT = core testlib
-SOURCES = tst_qreadlocker.cpp
diff --git a/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp b/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp
index 7d1b3709c2..e21f80c05d 100644
--- a/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp
+++ b/tests/auto/corelib/thread/qreadlocker/tst_qreadlocker.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QCoreApplication>
#include <QReadLocker>
@@ -73,7 +48,7 @@ void tst_QReadLocker::scopeTest()
class ScopeTestThread : public tst_QReadLockerThread
{
public:
- void run()
+ void run() override
{
waitForTest();
@@ -109,7 +84,7 @@ void tst_QReadLocker::scopeTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
@@ -118,7 +93,7 @@ void tst_QReadLocker::unlockAndRelockTest()
class UnlockAndRelockThread : public tst_QReadLockerThread
{
public:
- void run()
+ void run() override
{
QReadLocker locker(&lock);
@@ -156,7 +131,7 @@ void tst_QReadLocker::unlockAndRelockTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
void tst_QReadLocker::lockerStateTest()
@@ -164,7 +139,7 @@ void tst_QReadLocker::lockerStateTest()
class LockerStateThread : public tst_QReadLockerThread
{
public:
- void run()
+ void run() override
{
{
QReadLocker locker(&lock);
@@ -196,7 +171,7 @@ void tst_QReadLocker::lockerStateTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
QTEST_MAIN(tst_QReadLocker)
diff --git a/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt b/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt
new file mode 100644
index 0000000000..5ed3012e04
--- /dev/null
+++ b/tests/auto/corelib/thread/qreadwritelock/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qreadwritelock Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qreadwritelock LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qreadwritelock
+ SOURCES
+ tst_qreadwritelock.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/thread/qreadwritelock/qreadwritelock.pro b/tests/auto/corelib/thread/qreadwritelock/qreadwritelock.pro
deleted file mode 100644
index c108c3d8af..0000000000
--- a/tests/auto/corelib/thread/qreadwritelock/qreadwritelock.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qreadwritelock
-QT = core testlib
-SOURCES = tst_qreadwritelock.cpp
diff --git a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp
index 8e97229752..86dfa5faff 100644
--- a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp
+++ b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp
@@ -1,49 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSemaphore>
#include <qcoreapplication.h>
#include <qreadwritelock.h>
+#include <qelapsedtimer.h>
#include <qmutex.h>
#include <qthread.h>
#include <qwaitcondition.h>
+#include <private/qemulationdetector_p.h>
+#include <private/qvolatile_p.h>
#ifdef Q_OS_UNIX
#include <unistd.h>
#endif
-#if defined(Q_OS_WIN)
-# include <qt_windows.h>
-# ifndef Q_OS_WINRT
-# define sleep(X) Sleep(X)
-# else
-# define sleep(X) WaitForSingleObjectEx(GetCurrentThread(), X, FALSE);
-# endif
-#endif
//on solaris, threads that loop on the release bool variable
//needs to sleep more than 1 usec.
@@ -55,6 +26,8 @@
#include <stdio.h>
+using namespace std::chrono_literals;
+
class tst_QReadWriteLock : public QObject
{
Q_OBJECT
@@ -187,10 +160,10 @@ void tst_QReadWriteLock::readWriteLockUnlockLoop()
}
-QAtomicInt lockCount(0);
-QReadWriteLock readWriteLock;
-QSemaphore testsTurn;
-QSemaphore threadsTurn;
+static QAtomicInt lockCount(0);
+static QReadWriteLock readWriteLock;
+static QSemaphore testsTurn;
+static QSemaphore threadsTurn;
void tst_QReadWriteLock::tryReadLock()
@@ -217,7 +190,7 @@ void tst_QReadWriteLock::tryReadLock()
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
testsTurn.release();
@@ -237,7 +210,7 @@ void tst_QReadWriteLock::tryReadLock()
testsTurn.release();
threadsTurn.acquire();
- QTime timer;
+ QElapsedTimer timer;
timer.start();
QVERIFY(!readWriteLock.tryLockForRead(1000));
QVERIFY(timer.elapsed() >= 1000);
@@ -334,7 +307,7 @@ void tst_QReadWriteLock::tryWriteLock()
{
public:
Thread() : failureCount(0) { }
- void run()
+ void run() override
{
testsTurn.release();
@@ -406,8 +379,8 @@ void tst_QReadWriteLock::tryWriteLock()
}
}
-bool threadDone;
-QAtomicInt release;
+static bool threadDone;
+static QAtomicInt release;
/*
write-lock
@@ -419,7 +392,7 @@ class WriteLockThread : public QThread
public:
QReadWriteLock &testRwlock;
inline WriteLockThread(QReadWriteLock &l) : testRwlock(l) { }
- void run()
+ void run() override
{
testRwlock.lockForWrite();
testRwlock.unlock();
@@ -437,7 +410,7 @@ class ReadLockThread : public QThread
public:
QReadWriteLock &testRwlock;
inline ReadLockThread(QReadWriteLock &l) : testRwlock(l) { }
- void run()
+ void run() override
{
testRwlock.lockForRead();
testRwlock.unlock();
@@ -454,10 +427,10 @@ class WriteLockReleasableThread : public QThread
public:
QReadWriteLock &testRwlock;
inline WriteLockReleasableThread(QReadWriteLock &l) : testRwlock(l) { }
- void run()
+ void run() override
{
testRwlock.lockForWrite();
- while(release.load()==false) {
+ while (release.loadRelaxed() == false) {
RWTESTSLEEP
}
testRwlock.unlock();
@@ -474,10 +447,10 @@ class ReadLockReleasableThread : public QThread
public:
QReadWriteLock &testRwlock;
inline ReadLockReleasableThread(QReadWriteLock &l) : testRwlock(l) { }
- void run()
+ void run() override
{
testRwlock.lockForRead();
- while(release.load()==false) {
+ while (release.loadRelaxed() == false) {
RWTESTSLEEP
}
testRwlock.unlock();
@@ -497,10 +470,10 @@ class ReadLockLoopThread : public QThread
public:
QReadWriteLock &testRwlock;
int runTime;
- int holdTime;
- int waitTime;
+ std::chrono::milliseconds holdTime;
+ std::chrono::milliseconds waitTime;
bool print;
- QTime t;
+ QElapsedTimer t;
inline ReadLockLoopThread(QReadWriteLock &l, int runTime, int holdTime=0, int waitTime=0, bool print=false)
:testRwlock(l)
,runTime(runTime)
@@ -508,15 +481,15 @@ public:
,waitTime(waitTime)
,print(print)
{ }
- void run()
+ void run() override
{
t.start();
while (t.elapsed()<runTime) {
testRwlock.lockForRead();
if(print) printf("reading\n");
- if (holdTime) msleep(holdTime);
+ if (holdTime > 0ms) sleep(holdTime);
testRwlock.unlock();
- if (waitTime) msleep(waitTime);
+ if (waitTime > 0ms) sleep(waitTime);
}
}
};
@@ -533,10 +506,10 @@ class WriteLockLoopThread : public QThread
public:
QReadWriteLock &testRwlock;
int runTime;
- int holdTime;
- int waitTime;
+ std::chrono::milliseconds holdTime;
+ std::chrono::milliseconds waitTime;
bool print;
- QTime t;
+ QElapsedTimer t;
inline WriteLockLoopThread(QReadWriteLock &l, int runTime, int holdTime=0, int waitTime=0, bool print=false)
:testRwlock(l)
,runTime(runTime)
@@ -544,20 +517,20 @@ public:
,waitTime(waitTime)
,print(print)
{ }
- void run()
+ void run() override
{
t.start();
while (t.elapsed() < runTime) {
testRwlock.lockForWrite();
if (print) printf(".");
- if (holdTime) msleep(holdTime);
+ if (holdTime > 0ms) sleep(holdTime);
testRwlock.unlock();
- if (waitTime) msleep(waitTime);
+ if (waitTime > 0ms) sleep(waitTime);
}
}
};
-volatile int count=0;
+static volatile int count = 0;
/*
for(runTime msecs)
@@ -572,16 +545,16 @@ class WriteLockCountThread : public QThread
public:
QReadWriteLock &testRwlock;
int runTime;
- int waitTime;
+ std::chrono::milliseconds waitTime;
int maxval;
- QTime t;
+ QElapsedTimer t;
inline WriteLockCountThread(QReadWriteLock &l, int runTime, int waitTime, int maxval)
:testRwlock(l)
,runTime(runTime)
,waitTime(waitTime)
,maxval(maxval)
{ }
- void run()
+ void run() override
{
t.start();
while (t.elapsed() < runTime) {
@@ -589,15 +562,11 @@ public:
if(count)
qFatal("Non-zero count at start of write! (%d)",count );
// printf(".");
- int i;
- for(i=0; i<maxval; ++i) {
- volatile int lc=count;
- ++lc;
- count=lc;
- }
+ for (int i = 0; i < maxval; ++i)
+ QtPrivate::volatilePreIncrement(count);
count=0;
testRwlock.unlock();
- msleep(waitTime);
+ sleep(waitTime);
}
}
};
@@ -614,14 +583,14 @@ class ReadLockCountThread : public QThread
public:
QReadWriteLock &testRwlock;
int runTime;
- int waitTime;
- QTime t;
+ std::chrono::milliseconds waitTime;
+ QElapsedTimer t;
inline ReadLockCountThread(QReadWriteLock &l, int runTime, int waitTime)
:testRwlock(l)
,runTime(runTime)
,waitTime(waitTime)
{ }
- void run()
+ void run() override
{
t.start();
while (t.elapsed() < runTime) {
@@ -629,7 +598,7 @@ public:
if(count)
qFatal("Non-zero count at Read! (%d)",count );
testRwlock.unlock();
- msleep(waitTime);
+ sleep(waitTime);
}
}
};
@@ -646,7 +615,7 @@ void tst_QReadWriteLock::readLockBlockRelease()
threadDone=false;
ReadLockThread rlt(testLock);
rlt.start();
- sleep(1);
+ QThread::sleep(1s);
testLock.unlock();
rlt.wait();
QVERIFY(threadDone);
@@ -663,7 +632,7 @@ void tst_QReadWriteLock::writeLockBlockRelease()
threadDone=false;
WriteLockThread wlt(testLock);
wlt.start();
- sleep(1);
+ QThread::sleep(1s);
testLock.unlock();
wlt.wait();
QVERIFY(threadDone);
@@ -676,17 +645,17 @@ void tst_QReadWriteLock::multipleReadersBlockRelease()
{
QReadWriteLock testLock;
- release.store(false);
+ release.storeRelaxed(false);
threadDone=false;
ReadLockReleasableThread rlt1(testLock);
ReadLockReleasableThread rlt2(testLock);
rlt1.start();
rlt2.start();
- sleep(1);
+ QThread::sleep(1s);
WriteLockThread wlt(testLock);
wlt.start();
- sleep(1);
- release.store(true);
+ QThread::sleep(1s);
+ release.storeRelaxed(true);
wlt.wait();
rlt1.wait();
rlt2.wait();
@@ -698,27 +667,29 @@ void tst_QReadWriteLock::multipleReadersBlockRelease()
*/
void tst_QReadWriteLock::multipleReadersLoop()
{
- int time=500;
- int hold=250;
- int wait=0;
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Flaky on QEMU, QTBUG-96103");
+
+ constexpr int time = 500;
+ constexpr int hold = 250;
+ constexpr int wait = 0;
#if defined (Q_OS_HPUX)
- const int numthreads=50;
+ constexpr int NumThreads = 50;
#elif defined(Q_OS_VXWORKS)
- const int numthreads=40;
+ constexpr int NumThreads = 40;
#else
- const int numthreads=75;
+ constexpr int NumThreads = 75;
#endif
QReadWriteLock testLock;
- ReadLockLoopThread *threads[numthreads];
- int i;
- for (i=0; i<numthreads; ++i)
- threads[i] = new ReadLockLoopThread(testLock, time, hold, wait);
- for (i=0; i<numthreads; ++i)
- threads[i]->start();
- for (i=0; i<numthreads; ++i)
- threads[i]->wait();
- for (i=0; i<numthreads; ++i)
- delete threads[i];
+ ReadLockLoopThread *threads[NumThreads];
+ for (auto &thread : threads)
+ thread = new ReadLockLoopThread(testLock, time, hold, wait);
+ for (auto thread : threads)
+ thread->start();
+ for (auto thread : threads)
+ thread->wait();
+ for (auto thread : threads)
+ delete thread;
}
/*
@@ -726,21 +697,20 @@ void tst_QReadWriteLock::multipleReadersLoop()
*/
void tst_QReadWriteLock::multipleWritersLoop()
{
- int time=500;
- int wait=0;
- int hold=0;
- const int numthreads=50;
- QReadWriteLock testLock;
- WriteLockLoopThread *threads[numthreads];
- int i;
- for (i=0; i<numthreads; ++i)
- threads[i] = new WriteLockLoopThread(testLock, time, hold, wait);
- for (i=0; i<numthreads; ++i)
- threads[i]->start();
- for (i=0; i<numthreads; ++i)
- threads[i]->wait();
- for (i=0; i<numthreads; ++i)
- delete threads[i];
+ constexpr int time = 500;
+ constexpr int wait = 0;
+ constexpr int hold = 0;
+ constexpr int numthreads = 50;
+ QReadWriteLock testLock;
+ WriteLockLoopThread *threads[numthreads];
+ for (auto &thread : threads)
+ thread = new WriteLockLoopThread(testLock, time, hold, wait);
+ for (auto thread : threads)
+ thread->start();
+ for (auto thread : threads)
+ thread->wait();
+ for (auto thread : threads)
+ delete thread;
}
/*
@@ -748,40 +718,36 @@ void tst_QReadWriteLock::multipleWritersLoop()
*/
void tst_QReadWriteLock::multipleReadersWritersLoop()
{
- //int time=INT_MAX;
- int time=10000;
- int readerThreads=20;
- int readerWait=0;
- int readerHold=1;
-
- int writerThreads=2;
- int writerWait=500;
- int writerHold=50;
-
- QReadWriteLock testLock;
- ReadLockLoopThread *readers[1024];
- WriteLockLoopThread *writers[1024];
- int i;
-
- for (i=0; i<readerThreads; ++i)
- readers[i] = new ReadLockLoopThread(testLock, time, readerHold, readerWait, false);
- for (i=0; i<writerThreads; ++i)
- writers[i] = new WriteLockLoopThread(testLock, time, writerHold, writerWait, false);
-
- for (i=0; i<readerThreads; ++i)
- readers[i]->start(QThread::NormalPriority);
- for (i=0; i<writerThreads; ++i)
- writers[i]->start(QThread::IdlePriority);
-
- for (i=0; i<readerThreads; ++i)
- readers[i]->wait();
- for (i=0; i<writerThreads; ++i)
- writers[i]->wait();
-
- for (i=0; i<readerThreads; ++i)
- delete readers[i];
- for (i=0; i<writerThreads; ++i)
- delete writers[i];
+ constexpr int time = 10000; // INT_MAX
+ constexpr int readerThreads = 20;
+ constexpr int readerWait = 0;
+ constexpr int readerHold = 1;
+
+ constexpr int writerThreads = 2;
+ constexpr int writerWait = 500;
+ constexpr int writerHold = 50;
+
+ QReadWriteLock testLock;
+ ReadLockLoopThread *readers[readerThreads];
+ WriteLockLoopThread *writers[writerThreads];
+
+ for (auto &thread : readers)
+ thread = new ReadLockLoopThread(testLock, time, readerHold, readerWait, false);
+ for (auto &thread : writers)
+ thread = new WriteLockLoopThread(testLock, time, writerHold, writerWait, false);
+ for (auto thread : readers)
+ thread->start(QThread::NormalPriority);
+ for (auto thread : writers)
+ thread->start(QThread::IdlePriority);
+
+ for (auto thread : readers)
+ thread->wait();
+ for (auto thread : writers)
+ thread->wait();
+ for (auto thread : readers)
+ delete thread;
+ for (auto thread : writers)
+ delete thread;
}
/*
@@ -790,39 +756,35 @@ void tst_QReadWriteLock::multipleReadersWritersLoop()
*/
void tst_QReadWriteLock::countingTest()
{
- //int time=INT_MAX;
- int time=10000;
- int readerThreads=20;
- int readerWait=1;
-
- int writerThreads=3;
- int writerWait=150;
- int maxval=10000;
-
- QReadWriteLock testLock;
- ReadLockCountThread *readers[1024];
- WriteLockCountThread *writers[1024];
- int i;
-
- for (i=0; i<readerThreads; ++i)
- readers[i] = new ReadLockCountThread(testLock, time, readerWait);
- for (i=0; i<writerThreads; ++i)
- writers[i] = new WriteLockCountThread(testLock, time, writerWait, maxval);
-
- for (i=0; i<readerThreads; ++i)
- readers[i]->start(QThread::NormalPriority);
- for (i=0; i<writerThreads; ++i)
- writers[i]->start(QThread::LowestPriority);
-
- for (i=0; i<readerThreads; ++i)
- readers[i]->wait();
- for (i=0; i<writerThreads; ++i)
- writers[i]->wait();
-
- for (i=0; i<readerThreads; ++i)
- delete readers[i];
- for (i=0; i<writerThreads; ++i)
- delete writers[i];
+ constexpr int time = 10000; // INT_MAX
+ constexpr int readerThreads = 20;
+ constexpr int readerWait = 1;
+
+ constexpr int writerThreads = 3;
+ constexpr int writerWait = 150;
+ constexpr int maxval = 10000;
+
+ QReadWriteLock testLock;
+ ReadLockCountThread *readers[readerThreads];
+ WriteLockCountThread *writers[writerThreads];
+
+ for (auto &thread : readers)
+ thread = new ReadLockCountThread(testLock, time, readerWait);
+ for (auto &thread : writers)
+ thread = new WriteLockCountThread(testLock, time, writerWait, maxval);
+ for (auto thread : readers)
+ thread->start(QThread::NormalPriority);
+ for (auto thread : writers)
+ thread->start(QThread::LowestPriority);
+
+ for (auto thread : readers)
+ thread->wait();
+ for (auto thread : writers)
+ thread->wait();
+ for (auto thread : readers)
+ delete thread;
+ for (auto thread : writers)
+ delete thread;
}
void tst_QReadWriteLock::limitedReaders()
@@ -848,7 +810,7 @@ class DeleteOnUnlockThread : public QThread
public:
DeleteOnUnlockThread(QReadWriteLock **lock, QWaitCondition *startup, QMutex *waitMutex)
:m_lock(lock), m_startup(startup), m_waitMutex(waitMutex) {}
- void run()
+ void run() override
{
m_waitMutex->lock();
m_startup->wakeAll();
@@ -867,13 +829,13 @@ private:
void tst_QReadWriteLock::deleteOnUnlock()
{
- QReadWriteLock *lock = 0;
+ QReadWriteLock *lock = nullptr;
QWaitCondition startup;
QMutex waitMutex;
DeleteOnUnlockThread thread2(&lock, &startup, &waitMutex);
- QTime t;
+ QElapsedTimer t;
t.start();
while(t.elapsed() < 4000) {
lock = new QReadWriteLock();
@@ -899,7 +861,7 @@ void tst_QReadWriteLock::uncontendedLocks()
uint count=0;
int millisecs=1000;
{
- QTime t;
+ QElapsedTimer t;
t.start();
while(t.elapsed() <millisecs)
{
@@ -908,7 +870,7 @@ void tst_QReadWriteLock::uncontendedLocks()
}
{
QReadWriteLock rwlock;
- QTime t;
+ QElapsedTimer t;
t.start();
while(t.elapsed() <millisecs)
{
@@ -919,7 +881,7 @@ void tst_QReadWriteLock::uncontendedLocks()
}
{
QReadWriteLock rwlock;
- QTime t;
+ QElapsedTimer t;
t.start();
while(t.elapsed() <millisecs)
{
@@ -946,7 +908,7 @@ void tst_QReadWriteLock::recursiveReadLock()
QReadWriteLock *lock;
bool tryLockForWriteResult;
- void run()
+ void run() override
{
testsTurn.release();
@@ -1041,7 +1003,7 @@ void tst_QReadWriteLock::recursiveWriteLock()
QReadWriteLock *lock;
bool tryLockForReadResult;
- void run()
+ void run() override
{
testsTurn.release();
diff --git a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt
new file mode 100644
index 0000000000..0f9d8d9e52
--- /dev/null
+++ b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qresultstore Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qresultstore LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qresultstore
+ SOURCES
+ tst_qresultstore.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/thread/qresultstore/qresultstore.pro b/tests/auto/corelib/thread/qresultstore/qresultstore.pro
deleted file mode 100644
index bbebe0976b..0000000000
--- a/tests/auto/corelib/thread/qresultstore/qresultstore.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qresultstore
-QT = core-private testlib
-SOURCES = tst_qresultstore.cpp
-DEFINES += QT_STRICT_ITERATORS
diff --git a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp
index fba617e34d..265b2cd1f6 100644
--- a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp
+++ b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp
@@ -1,40 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qresultstore.h>
using namespace QtPrivate;
-struct ResultStoreInt : ResultStoreBase
+class IntResultsCleaner
{
- ~ResultStoreInt() { clear<int>(); }
+public:
+ IntResultsCleaner(QtPrivate::ResultStoreBase &s) : store(s) { }
+ ~IntResultsCleaner() { store.clear<int>(); }
+
+private:
+ QtPrivate::ResultStoreBase &store;
};
class tst_QtConcurrentResultStore : public QObject
@@ -53,12 +33,14 @@ private slots:
void filterMode();
void addCanceledResult();
void count();
+ void pendingResultsDoNotLeak_data();
+ void pendingResultsDoNotLeak();
private:
int int0;
int int1;
int int2;
- QVector<int> vec0;
- QVector<int> vec1;
+ QList<int> vec0;
+ QList<int> vec1;
};
void tst_QtConcurrentResultStore::init()
@@ -66,8 +48,8 @@ void tst_QtConcurrentResultStore::init()
int0 = 0;
int1 = 1;
int2 = 2;
- vec0 = QVector<int>() << 2 << 3;
- vec1 = QVector<int>() << 4 << 5;
+ vec0 = QList<int> { 2, 3 };
+ vec1 = QList<int> { 4, 5 };
}
void tst_QtConcurrentResultStore::construction()
@@ -85,7 +67,9 @@ void tst_QtConcurrentResultStore::iterators()
QCOMPARE(store.resultAt(1), store.end());
}
{
- ResultStoreInt storebase;
+ QtPrivate::ResultStoreBase storebase;
+ IntResultsCleaner cleanGuard(storebase);
+
storebase.addResult(-1, &int0); // note to self: adding a pointer to the stack here is ok since
storebase.addResult(1, &int1); // ResultStoreBase does not take ownership, only ResultStore<> does.
ResultIteratorBase it = storebase.begin();
@@ -108,7 +92,9 @@ void tst_QtConcurrentResultStore::addResult()
{
{
// test addResult return value
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
QCOMPARE(store.addResult(0, &int0), 0);
@@ -154,7 +140,9 @@ void tst_QtConcurrentResultStore::addResult()
void tst_QtConcurrentResultStore::addResults()
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(-1, &vec0);
store.addResults(-1, &vec1);
ResultIteratorBase it = store.begin();
@@ -175,11 +163,21 @@ void tst_QtConcurrentResultStore::addResults()
++it;
QCOMPARE(it, store.end());
+
+ QList<int> empty;
+ const auto countBefore = store.count();
+ QCOMPARE(store.addResults(countBefore, &empty), -1);
+ QCOMPARE(store.count(), countBefore);
+
+ QCOMPARE(store.addResults(countBefore, &vec1), countBefore);
+ QCOMPARE(store.count(), countBefore + vec1.size());
}
void tst_QtConcurrentResultStore::resultIndex()
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(-1, &int0);
store.addResults(-1, &vec0);
store.addResult(-1, &int1);
@@ -212,7 +210,9 @@ void tst_QtConcurrentResultStore::resultIndex()
void tst_QtConcurrentResultStore::resultAt()
{
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(-1, &int0);
store.addResults(-1, &vec0);
store.addResult(200, &int1);
@@ -223,7 +223,9 @@ void tst_QtConcurrentResultStore::resultAt()
QCOMPARE(store.resultAt(200).value<int>(), int1);
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(1, &int1);
store.addResult(0, &int0);
store.addResult(-1, &int2);
@@ -237,7 +239,9 @@ void tst_QtConcurrentResultStore::resultAt()
void tst_QtConcurrentResultStore::contains()
{
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
QCOMPARE(store.contains(0), false);
QCOMPARE(store.contains(1), false);
QCOMPARE(store.contains(INT_MAX), false);
@@ -249,7 +253,9 @@ void tst_QtConcurrentResultStore::contains()
QVERIFY(store.contains(int2));
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(1, &int0);
store.addResult(3, &int0);
store.addResults(6, &vec0);
@@ -264,7 +270,9 @@ void tst_QtConcurrentResultStore::contains()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResult(1, &int0);
store.addResult(3, &int0);
@@ -292,7 +300,9 @@ void tst_QtConcurrentResultStore::contains()
QCOMPARE(store.contains(7), false);
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addCanceledResult(0);
QCOMPARE(store.contains(0), false);
@@ -306,7 +316,9 @@ void tst_QtConcurrentResultStore::contains()
void tst_QtConcurrentResultStore::filterMode()
{
// Test filter mode, where "gaps" in the result array aren't allowed.
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
QCOMPARE(store.filterMode(), false);
store.setFilterMode(true);
QVERIFY(store.filterMode());
@@ -338,12 +350,22 @@ void tst_QtConcurrentResultStore::filterMode()
QCOMPARE(store.contains(6), true);
QCOMPARE(store.contains(7), true);
QCOMPARE(store.contains(8), false);
+
+ QList<int> empty;
+ const auto countBefore = store.count();
+ QCOMPARE(store.addResults(countBefore, &empty), -1);
+ QCOMPARE(store.count(), countBefore);
+
+ QCOMPARE(store.addResult(countBefore, &int2), countBefore);
+ QCOMPARE(store.count(), countBefore + 1);
}
void tst_QtConcurrentResultStore::addCanceledResult()
{
// test canceled results
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResult(0, &int0);
@@ -383,7 +405,9 @@ void tst_QtConcurrentResultStore::count()
{
// test resultCount in non-filtered mode. It should always be possible
// to iterate through the results 0 to resultCount.
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(0, &int0);
QCOMPARE(store.count(), 1);
@@ -397,7 +421,9 @@ void tst_QtConcurrentResultStore::count()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResult(2, &int0);
QCOMPARE(store.count(), 0);
@@ -409,7 +435,9 @@ void tst_QtConcurrentResultStore::count()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(2, &vec1);
QCOMPARE(store.count(), 0);
@@ -421,7 +449,9 @@ void tst_QtConcurrentResultStore::count()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(2, &vec1);
QCOMPARE(store.count(), 0);
@@ -429,7 +459,9 @@ void tst_QtConcurrentResultStore::count()
QCOMPARE(store.count(), 4);
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -441,7 +473,9 @@ void tst_QtConcurrentResultStore::count()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -454,7 +488,9 @@ void tst_QtConcurrentResultStore::count()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -464,7 +500,9 @@ void tst_QtConcurrentResultStore::count()
}
{
- ResultStoreInt store;
+ QtPrivate::ResultStoreBase store;
+ IntResultsCleaner cleanGuard(store);
+
store.setFilterMode(true);
store.addResults(3, &vec1);
QCOMPARE(store.count(), 0);
@@ -477,5 +515,75 @@ void tst_QtConcurrentResultStore::count()
}
}
+// simplified version of CountedObject from tst_qarraydata.cpp
+struct CountedObject
+{
+ CountedObject() : id(liveCount++)
+ { }
+
+ CountedObject(const CountedObject &other) : id(other.id)
+ {
+ ++liveCount;
+ }
+
+ ~CountedObject()
+ {
+ --liveCount;
+ }
+
+ CountedObject &operator=(const CountedObject &) = default;
+
+ struct LeakChecker
+ {
+ LeakChecker()
+ : previousLiveCount(liveCount)
+ {
+ }
+
+ ~LeakChecker()
+ {
+ QCOMPARE(liveCount, previousLiveCount);
+ }
+
+ private:
+ const size_t previousLiveCount;
+ };
+
+ size_t id = 0;
+ static size_t liveCount;
+};
+
+size_t CountedObject::liveCount = 0;
+
+void tst_QtConcurrentResultStore::pendingResultsDoNotLeak_data()
+{
+ QTest::addColumn<bool>("filterMode");
+
+ QTest::addRow("filter-mode-off") << false;
+ QTest::addRow("filter-mode-on") << true;
+}
+
+void tst_QtConcurrentResultStore::pendingResultsDoNotLeak()
+{
+ QFETCH(bool, filterMode);
+ CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker)
+
+ QtPrivate::ResultStoreBase store;
+ auto cleanGaurd = qScopeGuard([&] { store.clear<CountedObject>(); });
+
+ store.setFilterMode(filterMode);
+
+ // lvalue
+ auto lvalueObj = CountedObject();
+ store.addResult(42, &lvalueObj);
+
+ // rvalue
+ store.moveResult(43, CountedObject());
+
+ // array
+ auto lvalueListOfObj = QList<CountedObject>({CountedObject(), CountedObject()});
+ store.addResults(44, &lvalueListOfObj);
+}
+
QTEST_MAIN(tst_QtConcurrentResultStore)
#include "tst_qresultstore.moc"
diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
index 0786f50417..ecd42cff7c 100644
--- a/tests/auto/corelib/thread/qsemaphore/BLACKLIST
+++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
@@ -1,8 +1,2 @@
-[tryAcquireWithTimeout:0.2s]
-windows
-osx-10.12
-osx-10.13
-[tryAcquireWithTimeout:2s]
-windows
-osx-10.12
-osx-10.13
+[tryAcquireWithTimeout]
+macos
diff --git a/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt b/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt
new file mode 100644
index 0000000000..9f8a87558a
--- /dev/null
+++ b/tests/auto/corelib/thread/qsemaphore/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsemaphore Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsemaphore LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsemaphore
+ SOURCES
+ tst_qsemaphore.cpp
+)
diff --git a/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro b/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro
deleted file mode 100644
index 5a0f0337e6..0000000000
--- a/tests/auto/corelib/thread/qsemaphore/qsemaphore.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsemaphore
-QT = core testlib
-SOURCES = tst_qsemaphore.cpp
diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp
index b7134d0454..3bb1e1960c 100644
--- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp
+++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp
@@ -1,37 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qcoreapplication.h>
#include <qthread.h>
#include <qsemaphore.h>
+#include <chrono>
+
+using namespace std::chrono_literals;
+
class tst_QSemaphore : public QObject
{
Q_OBJECT
@@ -47,9 +26,10 @@ private slots:
void tryAcquireWithTimeoutForever();
void producerConsumer();
void raii();
+ void stdCompat();
};
-static QSemaphore *semaphore = 0;
+static QSemaphore *semaphore = nullptr;
class ThreadOne : public QThread
{
@@ -57,7 +37,7 @@ public:
ThreadOne() {}
protected:
- void run()
+ void run() override
{
int i = 0;
while ( i < 100 ) {
@@ -76,7 +56,7 @@ public:
ThreadN(int n) :N(n) { }
protected:
- void run()
+ void run() override
{
int i = 0;
while ( i < 100 ) {
@@ -106,7 +86,7 @@ void tst_QSemaphore::acquire()
QVERIFY(t2.wait(4000));
delete semaphore;
- semaphore = 0;
+ semaphore = nullptr;
}
// old incrementN() test
@@ -126,7 +106,7 @@ void tst_QSemaphore::acquire()
QVERIFY(t2.wait(4000));
delete semaphore;
- semaphore = 0;
+ semaphore = nullptr;
}
QSemaphore semaphore;
@@ -166,7 +146,7 @@ void tst_QSemaphore::multiRelease()
};
QSemaphore sem;
- QVector<Thread *> threads;
+ QList<Thread *> threads;
threads.resize(4);
for (Thread *&t : threads)
@@ -177,7 +157,7 @@ void tst_QSemaphore::multiRelease()
// wait for all threads to reach the sem.acquire() and then
// release them all
QTest::qSleep(1);
- sem.release(threads.size());
+ sem.release(int(threads.size()));
for (Thread *&t : threads)
t->wait();
@@ -200,7 +180,7 @@ void tst_QSemaphore::multiAcquireRelease()
};
QSemaphore sem;
- QVector<Thread *> threads;
+ QList<Thread *> threads;
threads.resize(4);
for (Thread *&t : threads)
@@ -323,69 +303,69 @@ void tst_QSemaphore::tryAcquireWithTimeout()
QCOMPARE(semaphore.available(), 1);
time.start();
QVERIFY(!semaphore.tryAcquire(2, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 1);
semaphore.release();
QCOMPARE(semaphore.available(), 2);
time.start();
QVERIFY(!semaphore.tryAcquire(3, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 2);
semaphore.release(10);
QCOMPARE(semaphore.available(), 12);
time.start();
QVERIFY(!semaphore.tryAcquire(100, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 12);
semaphore.release(10);
QCOMPARE(semaphore.available(), 22);
time.start();
QVERIFY(!semaphore.tryAcquire(100, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 22);
time.start();
QVERIFY(semaphore.tryAcquire(1, timeout));
- FUZZYCOMPARE(time.elapsed(), 0);
+ FUZZYCOMPARE(int(time.elapsed()), 0);
QCOMPARE(semaphore.available(), 21);
time.start();
QVERIFY(semaphore.tryAcquire(1, timeout));
- FUZZYCOMPARE(time.elapsed(), 0);
+ FUZZYCOMPARE(int(time.elapsed()), 0);
QCOMPARE(semaphore.available(), 20);
time.start();
QVERIFY(semaphore.tryAcquire(10, timeout));
- FUZZYCOMPARE(time.elapsed(), 0);
+ FUZZYCOMPARE(int(time.elapsed()), 0);
QCOMPARE(semaphore.available(), 10);
time.start();
QVERIFY(semaphore.tryAcquire(10, timeout));
- FUZZYCOMPARE(time.elapsed(), 0);
+ FUZZYCOMPARE(int(time.elapsed()), 0);
QCOMPARE(semaphore.available(), 0);
// should not be able to acquire more
time.start();
QVERIFY(!semaphore.tryAcquire(1, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 0);
time.start();
QVERIFY(!semaphore.tryAcquire(1, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 0);
time.start();
QVERIFY(!semaphore.tryAcquire(10, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 0);
time.start();
QVERIFY(!semaphore.tryAcquire(10, timeout));
- FUZZYCOMPARE(time.elapsed(), timeout);
+ FUZZYCOMPARE(int(time.elapsed()), timeout);
QCOMPARE(semaphore.available(), 0);
#undef FUZZYCOMPARE
@@ -400,7 +380,7 @@ void tst_QSemaphore::tryAcquireWithTimeoutStarvation()
QSemaphore *semaphore;
int amountToConsume, timeout;
- void run()
+ void run() override
{
startup.release();
forever {
@@ -481,7 +461,7 @@ const char alphabet[] = "ACGTH";
const int AlphabetSize = sizeof(alphabet) - 1;
const int BufferSize = 4096; // GCD of BufferSize and alphabet size must be 1
-char buffer[BufferSize];
+static char buffer[BufferSize];
const int ProducerChunkSize = 3;
const int ConsumerChunkSize = 7;
@@ -491,16 +471,16 @@ const int Multiplier = 10;
// ProducerChunkSize, ConsumerChunkSize, and BufferSize
const int DataSize = ProducerChunkSize * ConsumerChunkSize * BufferSize * Multiplier;
-QSemaphore freeSpace(BufferSize);
-QSemaphore usedSpace;
+static QSemaphore freeSpace(BufferSize);
+static QSemaphore usedSpace;
class Producer : public QThread
{
public:
- void run();
+ void run() override;
};
-static const int Timeout = 60 * 1000; // 1min
+static const auto Timeout = 1min;
void Producer::run()
{
@@ -521,7 +501,7 @@ void Producer::run()
class Consumer : public QThread
{
public:
- void run();
+ void run() override;
};
void Consumer::run()
@@ -599,5 +579,34 @@ void tst_QSemaphore::raii()
QCOMPARE(sem.available(), 49);
}
+void tst_QSemaphore::stdCompat()
+{
+ QSemaphore sem(1);
+
+ auto now = [] { return std::chrono::steady_clock::now(); };
+
+ QVERIFY(sem.try_acquire());
+ QCOMPARE(sem.available(), 0);
+ QVERIFY(!sem.try_acquire_for(10ms));
+ QCOMPARE(sem.available(), 0);
+ QVERIFY(!sem.try_acquire_until(now() + 10ms));
+ QCOMPARE(sem.available(), 0);
+
+ sem.release(2);
+
+ QVERIFY(sem.try_acquire());
+ QVERIFY(sem.try_acquire_for(5ms));
+ QCOMPARE(sem.available(), 0);
+ QVERIFY(!sem.try_acquire_until(now() + 5ms));
+ QCOMPARE(sem.available(), 0);
+
+ sem.release(3);
+
+ QVERIFY(sem.try_acquire());
+ QVERIFY(sem.try_acquire_for(5s));
+ QVERIFY(sem.try_acquire_until(now() + 5s));
+ QCOMPARE(sem.available(), 0);
+}
+
QTEST_MAIN(tst_QSemaphore)
#include "tst_qsemaphore.moc"
diff --git a/tests/auto/corelib/thread/qthread/BLACKLIST b/tests/auto/corelib/thread/qthread/BLACKLIST
index d75249454f..08e9912455 100644
--- a/tests/auto/corelib/thread/qthread/BLACKLIST
+++ b/tests/auto/corelib/thread/qthread/BLACKLIST
@@ -1,2 +1,3 @@
[wait3_slowDestructor]
-windows
+windows-10
+
diff --git a/tests/auto/corelib/thread/qthread/CMakeLists.txt b/tests/auto/corelib/thread/qthread/CMakeLists.txt
new file mode 100644
index 0000000000..abcea1ef9c
--- /dev/null
+++ b/tests/auto/corelib/thread/qthread/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qthread Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qthread LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qthread
+ SOURCES
+ tst_qthread.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/thread/qthread/qthread.pro b/tests/auto/corelib/thread/qthread/qthread.pro
deleted file mode 100644
index 37552f1fca..0000000000
--- a/tests/auto/corelib/thread/qthread/qthread.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qthread
-QT = core testlib
-SOURCES = tst_qthread.cpp
-qtConfig(c++14):CONFIG += c++14
-qtConfig(c++1z):CONFIG += c++1z
-
-INCLUDEPATH += ../../../../shared/
-HEADERS += ../../../../shared/emulationdetector.h
diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
index d73dcc1b6d..b163235d81 100644
--- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp
+++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
@@ -1,47 +1,32 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QTestEventLoop>
+#include <QSignalSpy>
+#include <QSemaphore>
+#include <QAbstractEventDispatcher>
+#if defined(Q_OS_WIN32)
+#include <QWinEventNotifier>
+#endif
#include <qcoreapplication.h>
-#include <qdatetime.h>
+#include <qelapsedtimer.h>
#include <qmutex.h>
#include <qthread.h>
#include <qtimer.h>
#include <qwaitcondition.h>
#include <qdebug.h>
#include <qmetaobject.h>
+#include <qscopeguard.h>
+#include <private/qobject_p.h>
+#include <private/qthread_p.h>
#ifdef Q_OS_UNIX
#include <pthread.h>
#endif
#if defined(Q_OS_WIN)
-#include <windows.h>
+#include <qt_windows.h>
#if defined(Q_OS_WIN32)
#include <process.h>
#endif
@@ -51,7 +36,9 @@
#include <exception>
#endif
-#include "emulationdetector.h"
+#include <QtTest/private/qemulationdetector_p.h>
+
+using namespace std::chrono_literals;
class tst_QThread : public QObject
{
@@ -66,6 +53,7 @@ private slots:
void setStackSize();
void exit();
void start();
+ void startSlotUsedInStringBasedLookups();
void terminate();
void quit();
void started();
@@ -85,6 +73,7 @@ private slots:
void adoptedThreadExecFinished();
void adoptMultipleThreads();
void adoptMultipleThreadsOverlap();
+ void adoptedThreadBindingStatus();
void exitAndStart();
void exitAndExec();
@@ -106,10 +95,23 @@ private slots:
void quitLock();
void create();
+ void createDestruction();
+ void threadIdReuse();
+
+ void terminateAndPrematureDestruction();
+ void terminateAndDoubleDestruction();
+
+ void bindingListCleanupAfterDelete();
};
enum { one_minute = 60 * 1000, five_minutes = 5 * one_minute };
+template <class Int>
+static QString msgElapsed(Int elapsed)
+{
+ return QString::fromLatin1("elapsed: %1").arg(elapsed);
+}
+
class SignalRecorder : public QObject
{
Q_OBJECT
@@ -121,7 +123,7 @@ public:
{ }
bool wasActivated()
- { return activationCount.load() > 0; }
+ { return activationCount.loadRelaxed() > 0; }
public slots:
void slot();
@@ -135,11 +137,13 @@ class Current_Thread : public QThread
public:
Qt::HANDLE id;
QThread *thread;
+ bool runCalledInCurrentThread = false;
- void run()
+ void run() override
{
id = QThread::currentThreadId();
thread = QThread::currentThread();
+ runCalledInCurrentThread = thread->isCurrentThread();
}
};
@@ -149,7 +153,7 @@ public:
QMutex mutex;
QWaitCondition cond;
- void run()
+ void run() override
{
QMutexLocker locker(&mutex);
cond.wakeOne();
@@ -174,7 +178,7 @@ public:
int code;
int result;
- void run()
+ void run() override
{
Simple_Thread::run();
if (object) {
@@ -189,7 +193,7 @@ public:
class Terminate_Thread : public Simple_Thread
{
public:
- void run()
+ void run() override
{
setTerminationEnabled(false);
{
@@ -218,7 +222,7 @@ public:
Quit_Object *object;
int result;
- void run()
+ void run() override
{
Simple_Thread::run();
if (object) {
@@ -235,29 +239,31 @@ public:
enum SleepType { Second, Millisecond, Microsecond };
SleepType sleepType;
- int interval;
+ ulong interval;
- int elapsed; // result, in *MILLISECONDS*
+ qint64 elapsed; // result, in *MILLISECONDS*
- void run()
+ void run() override
{
QMutexLocker locker(&mutex);
elapsed = 0;
- QTime time;
- time.start();
+ QElapsedTimer timer;
+ timer.start();
+ std::chrono::nanoseconds dur{0};
switch (sleepType) {
case Second:
- sleep(interval);
+ dur = std::chrono::seconds{interval};
break;
case Millisecond:
- msleep(interval);
+ dur = std::chrono::milliseconds{interval};
break;
case Microsecond:
- usleep(interval);
+ dur = std::chrono::microseconds{interval};
break;
}
- elapsed = time.elapsed();
+ sleep(dur);
+ elapsed = timer.elapsed();
cond.wakeOne();
}
@@ -266,25 +272,30 @@ public:
void tst_QThread::currentThreadId()
{
Current_Thread thread;
- thread.id = 0;
- thread.thread = 0;
+ thread.id = nullptr;
+ thread.thread = nullptr;
thread.start();
QVERIFY(thread.wait(five_minutes));
- QVERIFY(thread.id != 0);
+ QVERIFY(thread.id != nullptr);
QVERIFY(thread.id != QThread::currentThreadId());
+ QVERIFY(!thread.isCurrentThread());
+ QVERIFY(!thread.thread->isCurrentThread());
+ QVERIFY(thread.QThread::thread()->isCurrentThread());
+ QVERIFY(thread.runCalledInCurrentThread);
+ QVERIFY(qApp->thread()->isCurrentThread());
}
void tst_QThread::currentThread()
{
- QVERIFY(QThread::currentThread() != 0);
+ QVERIFY(QThread::currentThread() != nullptr);
QCOMPARE(QThread::currentThread(), thread());
Current_Thread thread;
- thread.id = 0;
- thread.thread = 0;
+ thread.id = nullptr;
+ thread.thread = nullptr;
thread.start();
QVERIFY(thread.wait(five_minutes));
- QCOMPARE(thread.thread, (QThread *)&thread);
+ QCOMPARE(thread.thread, static_cast<QThread *>(&thread));
}
void tst_QThread::idealThreadCount()
@@ -423,7 +434,7 @@ void tst_QThread::exit()
delete thread.object;
Exit_Thread thread2;
- thread2.object = 0;
+ thread2.object = nullptr;
thread2.code = 53;
thread2.result = 0;
QMutexLocker locker2(&thread2.mutex);
@@ -463,11 +474,65 @@ void tst_QThread::start()
}
}
+class QThreadStarter : public QObject
+{
+ Q_OBJECT
+public:
+ using QObject::QObject;
+Q_SIGNALS:
+ void start(QThread::Priority);
+};
+
+class QThreadSelfStarter : public QThread
+{
+ Q_OBJECT
+public:
+ using QThread::QThread;
+
+ void check()
+ {
+ QVERIFY(connect(this, SIGNAL(starting(Priority)),
+ this, SLOT(start(Priority))));
+ QVERIFY(QMetaObject::invokeMethod(this, "start", Q_ARG(Priority, IdlePriority)));
+ }
+
+Q_SIGNALS:
+ void starting(Priority);
+};
+
+void tst_QThread::startSlotUsedInStringBasedLookups()
+{
+ // QTBUG-124723
+
+ QThread thread;
+ {
+ QThreadStarter starter;
+ QVERIFY(QObject::connect(&starter, SIGNAL(start(QThread::Priority)),
+ &thread, SLOT(start(QThread::Priority))));
+ }
+ {
+ QThreadSelfStarter selfStarter;
+ selfStarter.check();
+ if (QTest::currentTestFailed())
+ return;
+ selfStarter.exit();
+ selfStarter.wait(30s);
+ }
+ QVERIFY(QMetaObject::invokeMethod(&thread, "start",
+ Q_ARG(QThread::Priority, QThread::IdlePriority)));
+ thread.exit();
+ thread.wait(30s);
+}
+
void tst_QThread::terminate()
{
-#if defined(Q_OS_WINRT) || defined(Q_OS_ANDROID)
- QSKIP("Thread termination is not supported on WinRT or Android.");
+#if defined(Q_OS_ANDROID)
+ QSKIP("Thread termination is not supported on Android.");
#endif
+#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+ QSKIP("Thread termination might result in stack underflow address sanitizer errors.");
+#endif
+
Terminate_Thread thread;
{
QMutexLocker locker(&thread.mutex);
@@ -499,7 +564,7 @@ void tst_QThread::quit()
delete thread.object;
Quit_Thread thread2;
- thread2.object = 0;
+ thread2.object = nullptr;
thread2.result = -1;
QMutexLocker locker2(&thread2.mutex);
thread2.start();
@@ -531,9 +596,13 @@ void tst_QThread::finished()
void tst_QThread::terminated()
{
-#if defined(Q_OS_WINRT) || defined(Q_OS_ANDROID)
- QSKIP("Thread termination is not supported on WinRT or Android.");
+#if defined(Q_OS_ANDROID)
+ QSKIP("Thread termination is not supported on Android.");
#endif
+#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+ QSKIP("Thread termination might result in stack underflow address sanitizer errors.");
+#endif
+
SignalRecorder recorder;
Terminate_Thread thread;
connect(&thread, SIGNAL(finished()), &recorder, SLOT(slot()), Qt::DirectConnection);
@@ -557,7 +626,7 @@ void tst_QThread::exec()
MultipleExecThread() : res1(-2), res2(-2) { }
- void run()
+ void run() override
{
{
Exit_Object o;
@@ -591,7 +660,7 @@ void tst_QThread::sleep()
thread.interval = 2;
thread.start();
QVERIFY(thread.wait(five_minutes));
- QVERIFY(thread.elapsed >= 2000);
+ QVERIFY2(thread.elapsed >= 2000, qPrintable(msgElapsed(thread.elapsed)));
}
void tst_QThread::msleep()
@@ -601,11 +670,10 @@ void tst_QThread::msleep()
thread.interval = 120;
thread.start();
QVERIFY(thread.wait(five_minutes));
-#if defined (Q_OS_WIN)
- // Since the resolution of QTime is so coarse...
- QVERIFY(thread.elapsed >= 100);
+#if defined (Q_OS_WIN) // May no longer be needed
+ QVERIFY2(thread.elapsed >= 100, qPrintable(msgElapsed(thread.elapsed)));
#else
- QVERIFY(thread.elapsed >= 120);
+ QVERIFY2(thread.elapsed >= 120, qPrintable(msgElapsed(thread.elapsed)));
#endif
}
@@ -616,11 +684,10 @@ void tst_QThread::usleep()
thread.interval = 120000;
thread.start();
QVERIFY(thread.wait(five_minutes));
-#if defined (Q_OS_WIN)
- // Since the resolution of QTime is so coarse...
- QVERIFY(thread.elapsed >= 100);
+#if defined (Q_OS_WIN) // May no longer be needed
+ QVERIFY2(thread.elapsed >= 100, qPrintable(msgElapsed(thread.elapsed)));
#else
- QVERIFY(thread.elapsed >= 120);
+ QVERIFY2(thread.elapsed >= 120, qPrintable(msgElapsed(thread.elapsed)));
#endif
}
@@ -642,9 +709,9 @@ void noop(void*) { }
class NativeThreadWrapper
{
public:
- NativeThreadWrapper() : qthread(0), waitForStop(false) {}
- void start(FunctionPointer functionPointer = noop, void *data = 0);
- void startAndWait(FunctionPointer functionPointer = noop, void *data = 0);
+ NativeThreadWrapper() : qthread(nullptr), waitForStop(false) {}
+ void start(FunctionPointer functionPointer = noop, void *data = nullptr);
+ void startAndWait(FunctionPointer functionPointer = noop, void *data = nullptr);
void join();
void setWaitForStop() { waitForStop = true; }
void stop();
@@ -668,10 +735,8 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data)
this->functionPointer = functionPointer;
this->data = data;
#if defined Q_OS_UNIX
- const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this);
- Q_UNUSED(state);
-#elif defined(Q_OS_WINRT)
- nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL);
+ const int state = pthread_create(&nativeThreadHandle, nullptr, NativeThreadWrapper::runUnix, this);
+ Q_UNUSED(state)
#elif defined Q_OS_WIN
unsigned thrdid = 0;
nativeThreadHandle = (Qt::HANDLE) _beginthreadex(NULL, 0, NativeThreadWrapper::runWin, this, 0, &thrdid);
@@ -688,7 +753,7 @@ void NativeThreadWrapper::startAndWait(FunctionPointer functionPointer, void *da
void NativeThreadWrapper::join()
{
#if defined Q_OS_UNIX
- pthread_join(nativeThreadHandle, 0);
+ pthread_join(nativeThreadHandle, nullptr);
#elif defined Q_OS_WIN
WaitForSingleObjectEx(nativeThreadHandle, INFINITE, FALSE);
CloseHandle(nativeThreadHandle);
@@ -718,7 +783,7 @@ void *NativeThreadWrapper::runUnix(void *that)
nativeThreadWrapper->stopCondition.wait(lock.mutex());
}
- return 0;
+ return nullptr;
}
unsigned WIN_FIX_STDCALL NativeThreadWrapper::runWin(void *data)
@@ -734,12 +799,12 @@ void NativeThreadWrapper::stop()
stopCondition.wakeOne();
}
-bool threadAdoptedOk = false;
-QThread *mainThread;
+static bool threadAdoptedOk = false;
+static QThread *mainThread;
void testNativeThreadAdoption(void *)
{
- threadAdoptedOk = (QThread::currentThreadId() != 0
- && QThread::currentThread() != 0
+ threadAdoptedOk = (QThread::currentThreadId() != nullptr
+ && QThread::currentThread() != nullptr
&& QThread::currentThread() != mainThread);
}
void tst_QThread::nativeThreadAdoption()
@@ -767,14 +832,15 @@ void adoptedThreadAffinityFunction(void *arg)
void tst_QThread::adoptedThreadAffinity()
{
- QThread *affinity[2] = { 0, 0 };
+ QThread *affinity[2] = { nullptr, nullptr };
NativeThreadWrapper thread;
thread.startAndWait(adoptedThreadAffinityFunction, affinity);
thread.join();
- // adopted thread should have affinity to itself
- QCOMPARE(affinity[0], affinity[1]);
+ // adopted thread (deleted) should have affinity to itself
+ QCOMPARE(static_cast<const void *>(affinity[0]),
+ static_cast<const void *>(affinity[1]));
}
void tst_QThread::adoptedThreadSetPriority()
@@ -881,7 +947,7 @@ void tst_QThread::adoptMultipleThreads()
#else
const int numThreads = 5;
#endif
- QVector<NativeThreadWrapper*> nativeThreads;
+ QList<NativeThreadWrapper*> nativeThreads;
SignalRecorder recorder;
@@ -902,7 +968,7 @@ void tst_QThread::adoptMultipleThreads()
QTestEventLoop::instance().enterLoop(5);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(recorder.activationCount.load(), numThreads);
+ QCOMPARE(recorder.activationCount.loadRelaxed(), numThreads);
}
void tst_QThread::adoptMultipleThreadsOverlap()
@@ -913,7 +979,7 @@ void tst_QThread::adoptMultipleThreadsOverlap()
#else
const int numThreads = 5;
#endif
- QVector<NativeThreadWrapper*> nativeThreads;
+ QList<NativeThreadWrapper*> nativeThreads;
SignalRecorder recorder;
@@ -939,18 +1005,32 @@ void tst_QThread::adoptMultipleThreadsOverlap()
QTestEventLoop::instance().enterLoop(5);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(recorder.activationCount.load(), numThreads);
+ QCOMPARE(recorder.activationCount.loadRelaxed(), numThreads);
+}
+
+void tst_QThread::adoptedThreadBindingStatus()
+{
+ NativeThreadWrapper nativeThread;
+ nativeThread.setWaitForStop();
+
+ nativeThread.startAndWait();
+ QVERIFY(nativeThread.qthread);
+ auto privThread = static_cast<QThreadPrivate *>(QObjectPrivate::get(nativeThread.qthread));
+ QVERIFY(privThread->m_statusOrPendingObjects.bindingStatus());
+
+ nativeThread.stop();
+ nativeThread.join();
}
// Disconnects on WinCE
void tst_QThread::stressTest()
{
- if (EmulationDetector::isRunningArmOnX86())
+ if (QTestPrivate::isRunningArmOnX86())
QSKIP("Qemu uses too much memory for each thread. Test would run out of memory.");
- QTime t;
- t.start();
- while (t.elapsed() < one_minute) {
+ QElapsedTimer timer;
+ timer.start();
+ while (timer.elapsed() < one_minute) {
Current_Thread t;
t.start();
t.wait(one_minute);
@@ -1000,7 +1080,8 @@ void tst_QThread::exitAndExec()
QSemaphore sem1;
QSemaphore sem2;
volatile int value;
- void run() {
+ void run() override
+ {
sem1.acquire();
value = exec(); //First entrence
sem2.release();
@@ -1051,7 +1132,7 @@ public:
QWaitCondition cond1;
QWaitCondition cond2;
- void run()
+ void run() override
{
QMutexLocker locker(&mutex);
cond1.wait(&mutex);
@@ -1067,17 +1148,19 @@ void tst_QThread::wait2()
timer.start();
QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
qint64 elapsed = timer.elapsed(); // On Windows, we sometimes get (WaitTime - 9).
- QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 10, qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed)));
+ QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 10,
+ qPrintable(msgElapsed(elapsed)));
timer.start();
thread.cond1.wakeOne();
QVERIFY(thread.wait(/*Waiting_Thread::WaitTime * 1.4*/));
elapsed = timer.elapsed();
- QVERIFY2(elapsed - Waiting_Thread::WaitTime >= -1, qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed)));
+ QVERIFY2(elapsed - Waiting_Thread::WaitTime >= -1,
+ qPrintable(msgElapsed(elapsed)));
}
-
-class SlowSlotObject : public QObject {
+class SlowSlotObject : public QObject
+{
Q_OBJECT
public:
QMutex mutex;
@@ -1093,28 +1176,29 @@ void tst_QThread::wait3_slowDestructor()
{
SlowSlotObject slow;
QThread thread;
- QObject::connect(&thread, SIGNAL(finished()), &slow, SLOT(slowSlot()), Qt::DirectConnection);
-
- enum { WaitTime = 1800 };
+ QObject::connect(&thread, &QThread::finished,
+ &slow, &SlowSlotObject::slowSlot, Qt::DirectConnection);
QElapsedTimer timer;
thread.start();
thread.quit();
- //the quit function will cause the thread to finish and enter the slowSlot that is blocking
+ // Calling quit() will cause the thread to finish and enter the blocking slowSlot().
timer.start();
- QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
- qint64 elapsed = timer.elapsed();
- QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 1, qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed)));
-
- slow.cond.wakeOne();
- //now the thread should finish quickly
+ {
+ // Ensure thread finishes quickly after the checks - regardless of success:
+ QScopeGuard wakeSlow([&slow]() -> void { slow.cond.wakeOne(); });
+ QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
+ const qint64 elapsed = timer.elapsed();
+ QVERIFY2(elapsed >= Waiting_Thread::WaitTime - 1,
+ qPrintable(QString::fromLatin1("elapsed: %1").arg(elapsed)));
+ }
QVERIFY(thread.wait(one_minute));
}
void tst_QThread::destroyFinishRace()
{
- class Thread : public QThread { void run() {} };
+ class Thread : public QThread { void run() override {} };
for (int i = 0; i < 15; i++) {
Thread *thr = new Thread;
connect(thr, SIGNAL(finished()), thr, SLOT(deleteLater()));
@@ -1134,9 +1218,10 @@ void tst_QThread::startFinishRace()
class Thread : public QThread {
public:
Thread() : i (50) {}
- void run() {
+ void run() override
+ {
i--;
- if (!i) disconnect(this, SIGNAL(finished()), 0, 0);
+ if (!i) disconnect(this, SIGNAL(finished()), nullptr, nullptr);
}
int i;
};
@@ -1157,7 +1242,7 @@ void tst_QThread::startFinishRace()
void tst_QThread::startAndQuitCustomEventLoop()
{
struct Thread : QThread {
- void run() { QEventLoop().exec(); }
+ void run() override { QEventLoop().exec(); }
};
for (int i = 0; i < 5; i++) {
@@ -1202,32 +1287,25 @@ void tst_QThread::isRunningInFinished()
}
}
-QT_BEGIN_NAMESPACE
-Q_CORE_EXPORT uint qGlobalPostedEventsCount();
-QT_END_NAMESPACE
-
-class DummyEventDispatcher : public QAbstractEventDispatcher {
+class DummyEventDispatcher : public QAbstractEventDispatcherV2
+{
+ Q_OBJECT
public:
- DummyEventDispatcher() : QAbstractEventDispatcher() {}
- bool processEvents(QEventLoop::ProcessEventsFlags) {
- visited.store(true);
+ bool processEvents(QEventLoop::ProcessEventsFlags) override {
+ visited.storeRelaxed(true);
emit awake();
QCoreApplication::sendPostedEvents();
return false;
}
- bool hasPendingEvents() {
- return qGlobalPostedEventsCount();
- }
- void registerSocketNotifier(QSocketNotifier *) {}
- void unregisterSocketNotifier(QSocketNotifier *) {}
- void registerTimer(int, int, Qt::TimerType, QObject *) {}
- bool unregisterTimer(int ) { return false; }
- bool unregisterTimers(QObject *) { return false; }
- QList<TimerInfo> registeredTimers(QObject *) const { return QList<TimerInfo>(); }
- int remainingTime(int) { return 0; }
- void wakeUp() {}
- void interrupt() {}
- void flush() {}
+ void registerSocketNotifier(QSocketNotifier *) override {}
+ void unregisterSocketNotifier(QSocketNotifier *) override {}
+ void registerTimer(Qt::TimerId, Duration, Qt::TimerType, QObject *) override {}
+ bool unregisterTimer(Qt::TimerId) override { return false; }
+ bool unregisterTimers(QObject *) override { return false; }
+ QList<TimerInfoV2> timersForObject(QObject *) const override { return {}; }
+ Duration remainingTime(Qt::TimerId) const override { return 0s; }
+ void wakeUp() override {}
+ void interrupt() override {}
#ifdef Q_OS_WIN
bool registerEventNotifier(QWinEventNotifier *) { return false; }
@@ -1272,7 +1350,7 @@ void tst_QThread::customEventDispatcher()
QMetaObject::invokeMethod(&obj, "visit", Qt::QueuedConnection);
loop.exec();
// test that the ED has really been used
- QVERIFY(ed->visited.load());
+ QVERIFY(ed->visited.loadRelaxed());
QPointer<DummyEventDispatcher> weak_ed(ed);
QVERIFY(!weak_ed.isNull());
@@ -1287,7 +1365,7 @@ class Job : public QObject
{
Q_OBJECT
public:
- Job(QThread *thread, int deleteDelay, bool *flag, QObject *parent = 0)
+ Job(QThread *thread, int deleteDelay, bool *flag, QObject *parent = nullptr)
: QObject(parent), quitLocker(thread), exitThreadCalled(*flag)
{
exitThreadCalled = false;
@@ -1330,13 +1408,12 @@ void tst_QThread::quitLock()
QCOMPARE(job->thread(), &thread);
loop.exec();
QVERIFY(exitThreadCalled);
+
+ delete job;
}
void tst_QThread::create()
{
-#if !QT_CONFIG(cxx11_future)
- QSKIP("This test requires QThread::create");
-#else
{
const auto &function = [](){};
QScopedPointer<QThread> thread(QThread::create(function));
@@ -1443,7 +1520,6 @@ void tst_QThread::create()
QCOMPARE(i, 42);
}
-#if defined(__cpp_init_captures) && __cpp_init_captures >= 201304
{
int i = 0;
MoveOnlyValue mo(123);
@@ -1455,9 +1531,7 @@ void tst_QThread::create()
QVERIFY(thread->wait());
QCOMPARE(i, 123);
}
-#endif // __cpp_init_captures
-#ifdef QTHREAD_HAS_VARIADIC_CREATE
{
int i = 0;
const auto &function = [&i](MoveOnlyValue &&mo) { i = mo.v; };
@@ -1480,10 +1554,8 @@ void tst_QThread::create()
QVERIFY(thread->wait());
QCOMPARE(i, -1);
}
-#endif // QTHREAD_HAS_VARIADIC_CREATE
}
-#ifdef QTHREAD_HAS_VARIADIC_CREATE
{
// simple parameter passing
int i = 0;
@@ -1577,12 +1649,70 @@ void tst_QThread::create()
const auto &function = [](const ThrowWhenCopying &){};
QScopedPointer<QThread> thread;
ThrowWhenCopying t;
- QVERIFY_EXCEPTION_THROWN(thread.reset(QThread::create(function, t)), ThreadException);
+ QVERIFY_THROWS_EXCEPTION(ThreadException, thread.reset(QThread::create(function, t)));
QVERIFY(!thread);
}
#endif // QT_NO_EXCEPTIONS
-#endif // QTHREAD_HAS_VARIADIC_CREATE
-#endif // QT_CONFIG(cxx11_future)
+}
+
+void tst_QThread::createDestruction()
+{
+ for (int delay : {0, 10, 20}) {
+ auto checkForInterruptions = []() {
+ for (;;) {
+ if (QThread::currentThread()->isInterruptionRequested())
+ return;
+ QThread::sleep(1ms);
+ }
+ };
+
+ QScopedPointer<QThread> thread(QThread::create(checkForInterruptions));
+ QSignalSpy finishedSpy(thread.get(), &QThread::finished);
+ QVERIFY(finishedSpy.isValid());
+
+ thread->start();
+ if (delay)
+ QThread::msleep(delay);
+ thread.reset();
+
+ QCOMPARE(finishedSpy.size(), 1);
+ }
+
+ for (int delay : {0, 10, 20}) {
+ auto runEventLoop = []() {
+ QEventLoop loop;
+ loop.exec();
+ };
+
+ QScopedPointer<QThread> thread(QThread::create(runEventLoop));
+ QSignalSpy finishedSpy(thread.get(), &QThread::finished);
+ QVERIFY(finishedSpy.isValid());
+
+ thread->start();
+ if (delay)
+ QThread::msleep(delay);
+ thread.reset();
+
+ QCOMPARE(finishedSpy.size(), 1);
+ }
+
+ for (int delay : {0, 10, 20}) {
+ auto runEventLoop = [delay]() {
+ if (delay)
+ QThread::msleep(delay);
+ QEventLoop loop;
+ loop.exec();
+ };
+
+ QScopedPointer<QThread> thread(QThread::create(runEventLoop));
+ QSignalSpy finishedSpy(thread.get(), &QThread::finished);
+ QVERIFY(finishedSpy.isValid());
+
+ thread->start();
+ thread.reset();
+
+ QCOMPARE(finishedSpy.size(), 1);
+ }
}
class StopableJob : public QObject
@@ -1623,5 +1753,155 @@ void tst_QThread::requestTermination()
QVERIFY(!thread.isInterruptionRequested());
}
+/*
+ This is a regression test for QTBUG-96846.
+
+ Incorrect system thread ID cleanup can cause QThread::wait() to report that
+ a thread is trying to wait for itself.
+*/
+void tst_QThread::threadIdReuse()
+{
+ // It's important that those thread ID's are not accessed concurrently
+ Qt::HANDLE threadId1;
+
+ auto thread1Fn = [&threadId1]() -> void { threadId1 = QThread::currentThreadId(); };
+ QScopedPointer<QThread> thread1(QThread::create(thread1Fn));
+ thread1->start();
+ QVERIFY(thread1->wait());
+
+ // If the system thread allocated for thread1 is destroyed before thread2 is started,
+ // at least on some versions of Linux the system thread ID for thread2 would be the
+ // same as one that was used for thread1.
+
+ // The system thread may be alive for some time after returning from QThread::wait()
+ // because the implementation is using detachable threads, so some additional time is
+ // required for the system thread to terminate. Not waiting long enough here would result
+ // in a new system thread ID being allocated for thread2 and this test passing even without
+ // a fix for QTBUG-96846.
+ bool threadIdReused = false;
+
+ for (int i = 0; i < 42; i++) {
+ QThread::sleep(1ms);
+
+ Qt::HANDLE threadId2;
+ bool waitOk = false;
+
+ auto waitForThread1 = [&thread1, &threadId2, &waitOk]() -> void {
+ threadId2 = QThread::currentThreadId();
+ waitOk = thread1->wait();
+ };
+
+ QScopedPointer<QThread> thread2(QThread::create(waitForThread1));
+ thread2->start();
+ QVERIFY(thread2->wait());
+ QVERIFY(waitOk);
+
+ if (threadId1 == threadId2) {
+ qDebug("Thread ID reused at iteration %d", i);
+ threadIdReused = true;
+ break;
+ }
+ }
+
+ if (!threadIdReused) {
+ QSKIP("Thread ID was not reused");
+ }
+}
+
+class WaitToRun_Thread : public QThread
+{
+ Q_OBJECT
+public:
+ void run() override
+ {
+ emit running();
+ QThread::exec();
+ }
+
+Q_SIGNALS:
+ void running();
+};
+
+
+void tst_QThread::terminateAndPrematureDestruction()
+{
+#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+ QSKIP("Thread termination might result in stack underflow address sanitizer errors.");
+#endif
+
+ WaitToRun_Thread thread;
+ QSignalSpy spy(&thread, &WaitToRun_Thread::running);
+ thread.start();
+ QVERIFY(spy.wait(500));
+
+ QScopedPointer<QObject> obj(new QObject);
+ QPointer<QObject> pObj(obj.data());
+ obj->deleteLater();
+
+ thread.terminate();
+ QVERIFY2(pObj, "object was deleted prematurely!");
+ thread.wait(500);
+}
+
+void tst_QThread::terminateAndDoubleDestruction()
+{
+#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+ QSKIP("Thread termination might result in stack underflow address sanitizer errors.");
+#endif
+
+ class ChildObject : public QObject
+ {
+ public:
+ ChildObject(QObject *parent)
+ : QObject(parent)
+ {
+ QSignalSpy spy(&thread, &WaitToRun_Thread::running);
+ thread.start();
+ spy.wait(500);
+ }
+
+ ~ChildObject()
+ {
+ QVERIFY2(!inDestruction, "Double object destruction!");
+ inDestruction = true;
+ thread.terminate();
+ thread.wait(500);
+ }
+
+ bool inDestruction = false;
+ WaitToRun_Thread thread;
+ };
+
+ class TestObject : public QObject
+ {
+ public:
+ TestObject()
+ : child(new ChildObject(this))
+ {
+ }
+
+ ~TestObject()
+ {
+ child->deleteLater();
+ }
+
+ ChildObject *child = nullptr;
+ };
+
+ TestObject obj;
+}
+
+void tst_QThread::bindingListCleanupAfterDelete()
+{
+ QThread t;
+ auto optr = std::make_unique<QObject>();
+ optr->moveToThread(&t);
+ auto threadPriv = static_cast<QThreadPrivate *>(QObjectPrivate::get(&t));
+ auto list = threadPriv->m_statusOrPendingObjects.list();
+ QVERIFY(list);
+ optr.reset();
+ QVERIFY(list->empty());
+}
+
QTEST_MAIN(tst_QThread)
#include "tst_qthread.moc"
diff --git a/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt b/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt
new file mode 100644
index 0000000000..2c92ca002e
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadonce/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qthreadonce Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qthreadonce LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qthreadonce
+ SOURCES
+ qthreadonce.cpp
+ tst_qthreadonce.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp
index d27884197a..b32f455241 100644
--- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp
+++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qplatformdefs.h"
@@ -32,7 +7,7 @@
#include "qmutex.h"
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, onceInitializationMutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, onceInitializationMutex)
enum QOnceExtra {
MustRunCode = 0x01,
diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h
index e5918b8fa5..1f804433e4 100644
--- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h
+++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QTHREADONCE_H
diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.pro b/tests/auto/corelib/thread/qthreadonce/qthreadonce.pro
deleted file mode 100644
index e8b95a06a7..0000000000
--- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qthreadonce
-QT = core testlib
-SOURCES = tst_qthreadonce.cpp
-
-# Don't use gcc's threadsafe statics
-# Note: some versions of gcc generate invalid code with this option...
-# Some versions of gcc don't even have it, so disable it
-#*-g++*:QMAKE_CXXFLAGS += -fno-threadsafe-statics
-
-# Temporary:
-SOURCES += qthreadonce.cpp
diff --git a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp
index a9af182ed8..37e1f744f3 100644
--- a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp
+++ b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp
@@ -1,33 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
+#include <QSemaphore>
#include <qcoreapplication.h>
#include <qmutex.h>
@@ -35,11 +11,14 @@
#include <qwaitcondition.h>
#include "qthreadonce.h"
+#include <QtTest/private/qemulationdetector_p.h>
+
class tst_QThreadOnce : public QObject
{
Q_OBJECT
private slots:
+ void initTestCase();
void sameThread();
void sameThread_data();
void multipleThreads();
@@ -51,12 +30,18 @@ private slots:
#endif
};
+void tst_QThreadOnce::initTestCase()
+{
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Flaky on QEMU, QTBUG-94737");
+}
+
class SingletonObject: public QObject
{
Q_OBJECT
public:
static int runCount;
- SingletonObject() { val.store(42); ++runCount; }
+ SingletonObject() { val.storeRelaxed(42); ++runCount; }
~SingletonObject() { }
QBasicAtomicInt val;
@@ -77,7 +62,7 @@ public:
~IncrementThread() { wait(); }
protected:
- void run()
+ void run() override
{
sem2.release();
sem1.acquire(); // synchronize
@@ -112,7 +97,7 @@ void tst_QThreadOnce::sameThread()
QCOMPARE(controlVariable, 1);
static QSingleton<SingletonObject> s;
- QTEST((int)s->val.load(), "expectedValue");
+ QTEST(int(s->val.loadRelaxed()), "expectedValue");
s->val.ref();
QCOMPARE(SingletonObject::runCount, 1);
@@ -134,7 +119,7 @@ void tst_QThreadOnce::multipleThreads()
QCOMPARE(controlVariable, 0); // nothing must have set them yet
SingletonObject::runCount = 0;
- IncrementThread::runCount.store(0);
+ IncrementThread::runCount.storeRelaxed(0);
// wait for all of them to be ready
sem2.acquire(NumberOfThreads);
@@ -145,7 +130,7 @@ void tst_QThreadOnce::multipleThreads()
delete parent;
QCOMPARE(controlVariable, 1);
- QCOMPARE((int)IncrementThread::runCount.load(), NumberOfThreads);
+ QCOMPARE(int(IncrementThread::runCount.loadRelaxed()), NumberOfThreads);
QCOMPARE(SingletonObject::runCount, 1);
}
diff --git a/tests/auto/corelib/thread/qthreadpool/BLACKLIST b/tests/auto/corelib/thread/qthreadpool/BLACKLIST
deleted file mode 100644
index fc49731687..0000000000
--- a/tests/auto/corelib/thread/qthreadpool/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[expiryTimeoutRace]
-osx
-linux
diff --git a/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt b/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt
new file mode 100644
index 0000000000..fee9c541db
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadpool/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qthreadpool Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qthreadpool LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qthreadpool
+ SOURCES
+ tst_qthreadpool.cpp
+)
diff --git a/tests/auto/corelib/thread/qthreadpool/qthreadpool.pro b/tests/auto/corelib/thread/qthreadpool/qthreadpool.pro
deleted file mode 100644
index eac4ef9365..0000000000
--- a/tests/auto/corelib/thread/qthreadpool/qthreadpool.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qthreadpool
-QT = core testlib
-SOURCES = tst_qthreadpool.cpp
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 838431cd5a..2006016d47 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -1,33 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtTest/QtTest>
-#include <qdatetime.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QSemaphore>
+
+#include <qelapsedtimer.h>
+#include <qrunnable.h>
#include <qthreadpool.h>
#include <qstring.h>
#include <qmutex.h>
@@ -36,6 +15,8 @@
#include <unistd.h>
#endif
+using namespace std::chrono_literals;
+
typedef void (*FunctionPointer)();
class FunctionPointerTask : public QRunnable
@@ -43,7 +24,7 @@ class FunctionPointerTask : public QRunnable
public:
FunctionPointerTask(FunctionPointer function)
:function(function) {}
- void run() { function(); }
+ void run() override { function(); }
private:
FunctionPointer function;
};
@@ -64,6 +45,8 @@ public:
private slots:
void runFunction();
+ void runFunction2();
+ void runFunction3();
void createThreadRunFunction();
void runMultiple();
void waitcomplete();
@@ -71,6 +54,7 @@ private slots:
void singleton();
void destruction();
void threadRecycling();
+ void threadPriority();
void expiryTimeout();
void expiryTimeoutRace();
#ifndef QT_NO_EXCEPTIONS
@@ -84,6 +68,8 @@ private slots:
void releaseThread_data();
void releaseThread();
void reserveAndStart();
+ void reserveAndStart2();
+ void releaseAndBlock();
void start();
void tryStart();
void tryStartPeakThreadCount();
@@ -92,7 +78,7 @@ private slots:
void priorityStart();
void waitForDone();
void clear();
- void cancel();
+ void clearWithAutoDelete();
void tryTake();
void waitForDoneTimeout();
void destroyingWaitsForTasksToFinish();
@@ -100,13 +86,15 @@ private slots:
void stressTest();
void takeAllAndIncreaseMaxThreadCount();
void waitForDoneAfterTake();
+ void threadReuse();
+ void nullFunctions();
private:
QMutex m_functionTestMutex;
};
-QMutex *tst_QThreadPool::functionTestMutex = 0;
+QMutex *tst_QThreadPool::functionTestMutex = nullptr;
tst_QThreadPool::tst_QThreadPool()
{
@@ -115,10 +103,10 @@ tst_QThreadPool::tst_QThreadPool()
tst_QThreadPool::~tst_QThreadPool()
{
- tst_QThreadPool::functionTestMutex = 0;
+ tst_QThreadPool::functionTestMutex = nullptr;
}
-int testFunctionCount;
+static int testFunctionCount;
void sleepTestFunction()
{
@@ -153,22 +141,64 @@ void noSleepTestFunctionMutex()
tst_QThreadPool::functionTestMutex->unlock();
}
+constexpr int DefaultWaitForDoneTimeout = 1 * 60 * 1000; // 1min
+// Using qFatal instead of QVERIFY to force exit if threads are still running after timeout.
+// Otherwise, QCoreApplication will still wait for the stale threads and never exit the test.
+#define WAIT_FOR_DONE(manager) \
+ if ((manager).waitForDone(DefaultWaitForDoneTimeout)) {} else \
+ qFatal("waitForDone returned false. Aborting to stop background threads.")
+
+// uses explicit timeout in dtor's waitForDone() to avoid tests hanging overly long
+class TestThreadPool : public QThreadPool
+{
+public:
+ using QThreadPool::QThreadPool;
+ ~TestThreadPool() { WAIT_FOR_DONE(*this); }
+};
+
void tst_QThreadPool::runFunction()
{
{
- QThreadPool manager;
+ TestThreadPool manager;
testFunctionCount = 0;
- manager.start(createTask(noSleepTestFunction));
+ manager.start(noSleepTestFunction);
}
QCOMPARE(testFunctionCount, 1);
}
+void tst_QThreadPool::runFunction2()
+{
+ int localCount = 0;
+ {
+ TestThreadPool manager;
+ manager.start([&]() { ++localCount; });
+ }
+ QCOMPARE(localCount, 1);
+}
+
+struct DeleteCheck
+{
+ static bool s_deleted;
+ ~DeleteCheck() { s_deleted = true; }
+};
+bool DeleteCheck::s_deleted = false;
+
+void tst_QThreadPool::runFunction3()
+{
+ std::unique_ptr<DeleteCheck> ptr(new DeleteCheck);
+ {
+ TestThreadPool manager;
+ manager.start([my_ptr = std::move(ptr)]() { });
+ }
+ QVERIFY(DeleteCheck::s_deleted);
+}
+
void tst_QThreadPool::createThreadRunFunction()
{
{
- QThreadPool manager;
+ TestThreadPool manager;
testFunctionCount = 0;
- manager.start(createTask(noSleepTestFunction));
+ manager.start(noSleepTestFunction);
}
QCOMPARE(testFunctionCount, 1);
@@ -179,27 +209,27 @@ void tst_QThreadPool::runMultiple()
const int runs = 10;
{
- QThreadPool manager;
+ TestThreadPool manager;
testFunctionCount = 0;
for (int i = 0; i < runs; ++i) {
- manager.start(createTask(sleepTestFunctionMutex));
+ manager.start(sleepTestFunctionMutex);
}
}
QCOMPARE(testFunctionCount, runs);
{
- QThreadPool manager;
+ TestThreadPool manager;
testFunctionCount = 0;
for (int i = 0; i < runs; ++i) {
- manager.start(createTask(noSleepTestFunctionMutex));
+ manager.start(noSleepTestFunctionMutex);
}
}
QCOMPARE(testFunctionCount, runs);
{
- QThreadPool manager;
+ TestThreadPool manager;
for (int i = 0; i < 500; ++i)
- manager.start(createTask(emptyFunct));
+ manager.start(emptyFunct);
}
}
@@ -208,28 +238,29 @@ void tst_QThreadPool::waitcomplete()
testFunctionCount = 0;
const int runs = 500;
for (int i = 0; i < 500; ++i) {
+ // TestThreadPool pool; // no, we're checking ~QThreadPool()'s waitForDone()
QThreadPool pool;
- pool.start(createTask(noSleepTestFunction));
+ pool.start(noSleepTestFunction);
}
QCOMPARE(testFunctionCount, runs);
}
-QAtomicInt ran; // bool
+static QAtomicInt ran; // bool
class TestTask : public QRunnable
{
public:
- void run()
+ void run() override
{
- ran.store(true);
+ ran.storeRelaxed(true);
}
};
void tst_QThreadPool::runTask()
{
- QThreadPool manager;
- ran.store(false);
+ TestThreadPool manager;
+ ran.storeRelaxed(false);
manager.start(new TestTask());
- QTRY_VERIFY(ran.load());
+ QTRY_VERIFY(ran.loadRelaxed());
}
/*
@@ -237,16 +268,16 @@ void tst_QThreadPool::runTask()
*/
void tst_QThreadPool::singleton()
{
- ran.store(false);
+ ran.storeRelaxed(false);
QThreadPool::globalInstance()->start(new TestTask());
- QTRY_VERIFY(ran.load());
+ QTRY_VERIFY(ran.loadRelaxed());
}
-QAtomicInt *value = 0;
+static QAtomicInt *value = nullptr;
class IntAccessor : public QRunnable
{
public:
- void run()
+ void run() override
{
for (int i = 0; i < 100; ++i) {
value->ref();
@@ -267,16 +298,16 @@ void tst_QThreadPool::destruction()
threadManager->start(new IntAccessor());
delete threadManager;
delete value;
- value = 0;
+ value = nullptr;
}
-QSemaphore threadRecyclingSemaphore;
-QThread *recycledThread = 0;
+static QSemaphore threadRecyclingSemaphore;
+static QThread *recycledThread = nullptr;
class ThreadRecorderTask : public QRunnable
{
public:
- void run()
+ void run() override
{
recycledThread = QThread::currentThread();
threadRecyclingSemaphore.release();
@@ -288,7 +319,7 @@ public:
*/
void tst_QThreadPool::threadRecycling()
{
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.start(new ThreadRecorderTask());
threadRecyclingSemaphore.acquire();
@@ -309,6 +340,25 @@ void tst_QThreadPool::threadRecycling()
QCOMPARE(thread2, thread3);
}
+/*
+ Test that the thread priority from the thread created by the pool matches
+ the one configured on the pool.
+*/
+void tst_QThreadPool::threadPriority()
+{
+ QThread::Priority priority = QThread::HighPriority;
+ TestThreadPool threadPool;
+ threadPool.setThreadPriority(priority);
+
+ threadPool.start(new ThreadRecorderTask());
+ threadRecyclingSemaphore.acquire();
+ QThread *thread = recycledThread;
+
+ QTest::qSleep(100);
+
+ QCOMPARE(thread->priority(), priority);
+}
+
class ExpiryTimeoutTask : public QRunnable
{
public:
@@ -317,12 +367,12 @@ public:
QSemaphore semaphore;
ExpiryTimeoutTask()
- : thread(0), runCount(0)
+ : thread(nullptr), runCount(0)
{
setAutoDelete(false);
}
- void run()
+ void run() override
{
thread = QThread::currentThread();
runCount.ref();
@@ -334,7 +384,7 @@ void tst_QThreadPool::expiryTimeout()
{
ExpiryTimeoutTask task;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setMaxThreadCount(1);
int expiryTimeout = threadPool.expiryTimeout();
@@ -344,7 +394,7 @@ void tst_QThreadPool::expiryTimeout()
// run the task
threadPool.start(&task);
QVERIFY(task.semaphore.tryAcquire(1, 10000));
- QCOMPARE(task.runCount.load(), 1);
+ QCOMPARE(task.runCount.loadRelaxed(), 1);
QVERIFY(!task.thread->wait(100));
// thread should expire
QThread *firstThread = task.thread;
@@ -353,7 +403,7 @@ void tst_QThreadPool::expiryTimeout()
// run task again, thread should be restarted
threadPool.start(&task);
QVERIFY(task.semaphore.tryAcquire(1, 10000));
- QCOMPARE(task.runCount.load(), 2);
+ QCOMPARE(task.runCount.loadRelaxed(), 2);
QVERIFY(!task.thread->wait(100));
// thread should expire again
QVERIFY(task.thread->wait(10000));
@@ -368,21 +418,18 @@ void tst_QThreadPool::expiryTimeout()
void tst_QThreadPool::expiryTimeoutRace() // QTBUG-3786
{
-#ifdef Q_OS_WIN
- QSKIP("This test is unstable on Windows. See QTBUG-3786.");
-#endif
ExpiryTimeoutTask task;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setMaxThreadCount(1);
threadPool.setExpiryTimeout(50);
const int numTasks = 20;
for (int i = 0; i < numTasks; ++i) {
threadPool.start(&task);
- QThread::msleep(50); // exactly the same as the expiry timeout
+ QThread::sleep(50ms); // exactly the same as the expiry timeout
}
QVERIFY(task.semaphore.tryAcquire(numTasks, 10000));
- QCOMPARE(task.runCount.load(), numTasks);
+ QCOMPARE(task.runCount.loadRelaxed(), numTasks);
QVERIFY(threadPool.waitForDone(2000));
}
@@ -390,7 +437,7 @@ void tst_QThreadPool::expiryTimeoutRace() // QTBUG-3786
class ExceptionTask : public QRunnable
{
public:
- void run()
+ void run() override
{
throw new int;
}
@@ -400,7 +447,7 @@ void tst_QThreadPool::exceptions()
{
ExceptionTask task;
{
- QThreadPool threadPool;
+ TestThreadPool threadPool;
// Uncomment this for a nice crash.
// threadPool.start(&task);
}
@@ -429,6 +476,9 @@ void tst_QThreadPool::setMaxThreadCount()
QFETCH(int, limit);
QThreadPool *threadPool = QThreadPool::globalInstance();
int savedLimit = threadPool->maxThreadCount();
+ auto restoreThreadCount = qScopeGuard([=]{
+ threadPool->setMaxThreadCount(savedLimit);
+ });
// maxThreadCount() should always return the previous argument to
// setMaxThreadCount(), regardless of input
@@ -441,7 +491,7 @@ void tst_QThreadPool::setMaxThreadCount()
// setting the limit on children should have no effect on the parent
{
- QThreadPool threadPool2(threadPool);
+ TestThreadPool threadPool2(threadPool);
savedLimit = threadPool2.maxThreadCount();
// maxThreadCount() should always return the previous argument to
@@ -464,65 +514,64 @@ void tst_QThreadPool::setMaxThreadCountStartsAndStopsThreads()
WaitingTask() { setAutoDelete(false); }
- void run()
+ void run() override
{
waitForStarted.release();
waitToFinish.acquire();
}
};
- QThreadPool threadPool;
- threadPool.setMaxThreadCount(1);
+ TestThreadPool threadPool;
+ threadPool.setMaxThreadCount(-1); // docs say we'll always start at least one
- WaitingTask *task = new WaitingTask;
- threadPool.start(task);
- QVERIFY(task->waitForStarted.tryAcquire(1, 1000));
+ WaitingTask task;
+ threadPool.start(&task);
+ QVERIFY(task.waitForStarted.tryAcquire(1, 1000));
// thread limit is 1, cannot start more tasks
- threadPool.start(task);
- QVERIFY(!task->waitForStarted.tryAcquire(1, 1000));
+ threadPool.start(&task);
+ QVERIFY(!task.waitForStarted.tryAcquire(1, 1000));
// increasing the limit by 1 should start the task immediately
threadPool.setMaxThreadCount(2);
- QVERIFY(task->waitForStarted.tryAcquire(1, 1000));
+ QVERIFY(task.waitForStarted.tryAcquire(1, 1000));
// ... but we still cannot start more tasks
- threadPool.start(task);
- QVERIFY(!task->waitForStarted.tryAcquire(1, 1000));
+ threadPool.start(&task);
+ QVERIFY(!task.waitForStarted.tryAcquire(1, 1000));
// increasing the limit should be able to start more than one at a time
- threadPool.start(task);
+ threadPool.start(&task);
threadPool.setMaxThreadCount(4);
- QVERIFY(task->waitForStarted.tryAcquire(2, 1000));
+ QVERIFY(task.waitForStarted.tryAcquire(2, 1000));
// ... but we still cannot start more tasks
- threadPool.start(task);
- threadPool.start(task);
- QVERIFY(!task->waitForStarted.tryAcquire(2, 1000));
+ threadPool.start(&task);
+ threadPool.start(&task);
+ QVERIFY(!task.waitForStarted.tryAcquire(2, 1000));
// decreasing the thread limit should cause the active thread count to go down
threadPool.setMaxThreadCount(2);
QCOMPARE(threadPool.activeThreadCount(), 4);
- task->waitToFinish.release(2);
+ task.waitToFinish.release(2);
QTest::qWait(1000);
QCOMPARE(threadPool.activeThreadCount(), 2);
// ... and we still cannot start more tasks
- threadPool.start(task);
- threadPool.start(task);
- QVERIFY(!task->waitForStarted.tryAcquire(2, 1000));
+ threadPool.start(&task);
+ threadPool.start(&task);
+ QVERIFY(!task.waitForStarted.tryAcquire(2, 1000));
// start all remaining tasks
- threadPool.start(task);
- threadPool.start(task);
- threadPool.start(task);
- threadPool.start(task);
+ threadPool.start(&task);
+ threadPool.start(&task);
+ threadPool.start(&task);
+ threadPool.start(&task);
threadPool.setMaxThreadCount(8);
- QVERIFY(task->waitForStarted.tryAcquire(6, 1000));
+ QVERIFY(task.waitForStarted.tryAcquire(6, 1000));
- task->waitToFinish.release(10);
+ task.waitToFinish.release(10);
threadPool.waitForDone();
- delete task;
}
void tst_QThreadPool::reserveThread_data()
@@ -534,7 +583,11 @@ void tst_QThreadPool::reserveThread()
{
QFETCH(int, limit);
QThreadPool *threadpool = QThreadPool::globalInstance();
- int savedLimit = threadpool->maxThreadCount();
+ const int savedLimit = threadpool->maxThreadCount();
+ auto restoreThreadCount = qScopeGuard([=]{
+ threadpool->setMaxThreadCount(savedLimit);
+ });
+
threadpool->setMaxThreadCount(limit);
// reserve up to the limit
@@ -556,7 +609,7 @@ void tst_QThreadPool::reserveThread()
// reserving threads in children should not effect the parent
{
- QThreadPool threadpool2(threadpool);
+ TestThreadPool threadpool2(threadpool);
threadpool2.setMaxThreadCount(limit);
// reserve up to the limit
@@ -583,9 +636,6 @@ void tst_QThreadPool::reserveThread()
while (threadpool2.activeThreadCount() > 0)
threadpool2.releaseThread();
}
-
- // reset limit on global QThreadPool
- threadpool->setMaxThreadCount(savedLimit);
}
void tst_QThreadPool::releaseThread_data()
@@ -597,7 +647,10 @@ void tst_QThreadPool::releaseThread()
{
QFETCH(int, limit);
QThreadPool *threadpool = QThreadPool::globalInstance();
- int savedLimit = threadpool->maxThreadCount();
+ const int savedLimit = threadpool->maxThreadCount();
+ auto restoreThreadCount = qScopeGuard([=]{
+ threadpool->setMaxThreadCount(savedLimit);
+ });
threadpool->setMaxThreadCount(limit);
// reserve up to the limit
@@ -620,7 +673,7 @@ void tst_QThreadPool::releaseThread()
// releasing threads in children should not effect the parent
{
- QThreadPool threadpool2(threadpool);
+ TestThreadPool threadpool2(threadpool);
threadpool2.setMaxThreadCount(limit);
// reserve up to the limit
@@ -645,9 +698,6 @@ void tst_QThreadPool::releaseThread()
QCOMPARE(threadpool2.activeThreadCount(), 0);
QCOMPARE(threadpool->activeThreadCount(), 0);
}
-
- // reset limit on global QThreadPool
- threadpool->setMaxThreadCount(savedLimit);
}
void tst_QThreadPool::reserveAndStart() // QTBUG-21051
@@ -661,7 +711,7 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051
WaitingTask() { setAutoDelete(false); }
- void run()
+ void run() override
{
count.ref();
waitForStarted.release();
@@ -672,6 +722,10 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051
// Set up
QThreadPool *threadpool = QThreadPool::globalInstance();
int savedLimit = threadpool->maxThreadCount();
+ auto restoreThreadCount = qScopeGuard([=]{
+ threadpool->setMaxThreadCount(savedLimit);
+ });
+
threadpool->setMaxThreadCount(1);
QCOMPARE(threadpool->activeThreadCount(), 0);
@@ -679,40 +733,137 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051
threadpool->reserveThread();
QCOMPARE(threadpool->activeThreadCount(), 1);
- // start a task, to get a running thread
- WaitingTask *task = new WaitingTask;
- threadpool->start(task);
+ // start a task, to get a running thread, works since one thread is always allowed
+ WaitingTask task;
+ threadpool->start(&task);
QCOMPARE(threadpool->activeThreadCount(), 2);
- task->waitForStarted.acquire();
- task->waitBeforeDone.release();
- QTRY_COMPARE(task->count.load(), 1);
+ // tryStart() will fail since activeThreadCount() >= maxThreadCount() and one thread is already running
+ QVERIFY(!threadpool->tryStart(&task));
+ QTRY_COMPARE(threadpool->activeThreadCount(), 2);
+ task.waitForStarted.acquire();
+ task.waitBeforeDone.release();
+ QTRY_COMPARE(task.count.loadRelaxed(), 1);
QTRY_COMPARE(threadpool->activeThreadCount(), 1);
- // now the thread is waiting, but tryStart() will fail since activeThreadCount() >= maxThreadCount()
- QVERIFY(!threadpool->tryStart(task));
+ // start() will wake up the waiting thread.
+ threadpool->start(&task);
+ QTRY_COMPARE(threadpool->activeThreadCount(), 2);
+ QTRY_COMPARE(task.count.loadRelaxed(), 2);
+ WaitingTask task2;
+ // startOnReservedThread() will try to take the reserved task, but end up waiting instead
+ threadpool->startOnReservedThread(&task2);
+ QTRY_COMPARE(threadpool->activeThreadCount(), 1);
+ task.waitForStarted.acquire();
+ task.waitBeforeDone.release();
QTRY_COMPARE(threadpool->activeThreadCount(), 1);
+ task2.waitForStarted.acquire();
+ task2.waitBeforeDone.release();
- // start() will therefore do a failing tryStart(), followed by enqueueTask()
- // which will actually wake up the waiting thread.
- threadpool->start(task);
- QTRY_COMPARE(threadpool->activeThreadCount(), 2);
- task->waitForStarted.acquire();
- task->waitBeforeDone.release();
- QTRY_COMPARE(task->count.load(), 2);
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
+}
+
+void tst_QThreadPool::reserveAndStart2()
+{
+ class WaitingTask : public QRunnable
+ {
+ public:
+ QSemaphore waitBeforeDone;
+
+ WaitingTask() { setAutoDelete(false); }
+
+ void run() override
+ {
+ waitBeforeDone.acquire();
+ }
+ };
+
+ // Set up
+ QThreadPool *threadpool = QThreadPool::globalInstance();
+ int savedLimit = threadpool->maxThreadCount();
+ auto restoreThreadCount = qScopeGuard([=]{
+ threadpool->setMaxThreadCount(savedLimit);
+ });
+ threadpool->setMaxThreadCount(2);
+
+ // reserve
+ threadpool->reserveThread();
+
+ // start two task, to get a running thread and one queued
+ WaitingTask task1, task2, task3;
+ threadpool->start(&task1);
+ // one running thread, one reserved:
+ QCOMPARE(threadpool->activeThreadCount(), 2);
+ // task2 starts queued
+ threadpool->start(&task2);
+ QCOMPARE(threadpool->activeThreadCount(), 2);
+ // startOnReservedThread() will take the reserved thread however, bypassing the queue
+ threadpool->startOnReservedThread(&task3);
+ // two running threads, none reserved:
+ QCOMPARE(threadpool->activeThreadCount(), 2);
+ task3.waitBeforeDone.release();
+ // task3 can finish even if all other tasks are blocking
+ // then task2 will use the previously reserved thread
+ task2.waitBeforeDone.release();
QTRY_COMPARE(threadpool->activeThreadCount(), 1);
+ task1.waitBeforeDone.release();
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
+}
+
+void tst_QThreadPool::releaseAndBlock()
+{
+ class WaitingTask : public QRunnable
+ {
+ public:
+ QSemaphore waitBeforeDone;
+ WaitingTask() { setAutoDelete(false); }
+
+ void run() override
+ {
+ waitBeforeDone.acquire();
+ }
+ };
+
+ // Set up
+ QThreadPool *threadpool = QThreadPool::globalInstance();
+ const int savedLimit = threadpool->maxThreadCount();
+ auto restoreThreadCount = qScopeGuard([=]{
+ threadpool->setMaxThreadCount(savedLimit);
+ });
+
+ threadpool->setMaxThreadCount(1);
+ QCOMPARE(threadpool->activeThreadCount(), 0);
+
+ // start a task, to get a running thread, works since one thread is always allowed
+ WaitingTask task1, task2;
+ threadpool->start(&task1);
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+
+ // tryStart() will fail since activeThreadCount() >= maxThreadCount() and one thread is already running
+ QVERIFY(!threadpool->tryStart(&task2));
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+
+ // Use release without reserve to account for the blocking thread.
threadpool->releaseThread();
QTRY_COMPARE(threadpool->activeThreadCount(), 0);
- delete task;
+ // Now we can start task2
+ QVERIFY(threadpool->tryStart(&task2));
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+ task2.waitBeforeDone.release();
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
- threadpool->setMaxThreadCount(savedLimit);
+ threadpool->reserveThread();
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+ task1.waitBeforeDone.release();
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
}
-QAtomicInt count;
+static QAtomicInt count;
class CountingRunnable : public QRunnable
{
- public: void run()
+public:
+ void run() override
{
count.ref();
}
@@ -721,14 +872,14 @@ class CountingRunnable : public QRunnable
void tst_QThreadPool::start()
{
const int runs = 1000;
- count.store(0);
+ count.storeRelaxed(0);
{
- QThreadPool threadPool;
+ TestThreadPool threadPool;
for (int i = 0; i< runs; ++i) {
threadPool.start(new CountingRunnable());
}
}
- QCOMPARE(count.load(), runs);
+ QCOMPARE(count.loadRelaxed(), runs);
}
void tst_QThreadPool::tryStart()
@@ -740,29 +891,29 @@ void tst_QThreadPool::tryStart()
WaitingTask() { setAutoDelete(false); }
- void run()
+ void run() override
{
semaphore.acquire();
count.ref();
}
};
- count.store(0);
+ count.storeRelaxed(0);
WaitingTask task;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
for (int i = 0; i < threadPool.maxThreadCount(); ++i) {
threadPool.start(&task);
}
QVERIFY(!threadPool.tryStart(&task));
task.semaphore.release(threadPool.maxThreadCount());
- threadPool.waitForDone();
- QCOMPARE(count.load(), threadPool.maxThreadCount());
+ WAIT_FOR_DONE(threadPool);
+ QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount());
}
-QMutex mutex;
-QAtomicInt activeThreads;
-QAtomicInt peakActiveThreads;
+static QMutex mutex;
+static QAtomicInt activeThreads;
+static QAtomicInt peakActiveThreads;
void tst_QThreadPool::tryStartPeakThreadCount()
{
class CounterTask : public QRunnable
@@ -770,12 +921,12 @@ void tst_QThreadPool::tryStartPeakThreadCount()
public:
CounterTask() { setAutoDelete(false); }
- void run()
+ void run() override
{
{
QMutexLocker lock(&mutex);
activeThreads.ref();
- peakActiveThreads.store(qMax(peakActiveThreads.load(), activeThreads.load()));
+ peakActiveThreads.storeRelaxed(qMax(peakActiveThreads.loadRelaxed(), activeThreads.loadRelaxed()));
}
QTest::qWait(100);
@@ -787,19 +938,19 @@ void tst_QThreadPool::tryStartPeakThreadCount()
};
CounterTask task;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
- for (int i = 0; i < 20; ++i) {
+ for (int i = 0; i < 4*QThread::idealThreadCount(); ++i) {
if (threadPool.tryStart(&task) == false)
QTest::qWait(10);
}
- QCOMPARE(peakActiveThreads.load(), QThread::idealThreadCount());
+ QCOMPARE(peakActiveThreads.loadRelaxed(), QThread::idealThreadCount());
for (int i = 0; i < 20; ++i) {
if (threadPool.tryStart(&task) == false)
QTest::qWait(10);
}
- QCOMPARE(peakActiveThreads.load(), QThread::idealThreadCount());
+ QCOMPARE(peakActiveThreads.loadRelaxed(), QThread::idealThreadCount());
}
void tst_QThreadPool::tryStartCount()
@@ -809,14 +960,14 @@ void tst_QThreadPool::tryStartCount()
public:
SleeperTask() { setAutoDelete(false); }
- void run()
+ void run() override
{
QTest::qWait(50);
}
};
SleeperTask task;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
const int runs = 5;
for (int i = 0; i < runs; ++i) {
@@ -844,7 +995,7 @@ void tst_QThreadPool::priorityStart()
public:
QSemaphore &sem;
Holder(QSemaphore &sem) : sem(sem) {}
- void run()
+ void run() override
{
sem.acquire();
}
@@ -854,9 +1005,9 @@ void tst_QThreadPool::priorityStart()
public:
QAtomicPointer<QRunnable> &ptr;
Runner(QAtomicPointer<QRunnable> &ptr) : ptr(ptr) {}
- void run()
+ void run() override
{
- ptr.testAndSetRelaxed(0, this);
+ ptr.testAndSetRelaxed(nullptr, this);
}
};
@@ -864,7 +1015,7 @@ void tst_QThreadPool::priorityStart()
QSemaphore sem;
QAtomicPointer<QRunnable> firstStarted;
QRunnable *expected;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setMaxThreadCount(1); // start only one thread at a time
// queue the holder first
@@ -876,36 +1027,37 @@ void tst_QThreadPool::priorityStart()
threadPool.start(expected = new Runner(firstStarted), 1); // priority 1
sem.release();
- QVERIFY(threadPool.waitForDone());
- QCOMPARE(firstStarted.load(), expected);
+ WAIT_FOR_DONE(threadPool);
+ QCOMPARE(firstStarted.loadRelaxed(), expected);
}
void tst_QThreadPool::waitForDone()
{
- QTime total, pass;
+ QElapsedTimer total, pass;
total.start();
+ pass.start();
- QThreadPool threadPool;
+ TestThreadPool threadPool;
while (total.elapsed() < 10000) {
int runs;
- count.store(runs = 0);
+ count.storeRelaxed(runs = 0);
pass.restart();
while (pass.elapsed() < 100) {
threadPool.start(new CountingRunnable());
++runs;
}
- threadPool.waitForDone();
- QCOMPARE(count.load(), runs);
+ WAIT_FOR_DONE(threadPool);
+ QCOMPARE(count.loadRelaxed(), runs);
- count.store(runs = 0);
+ count.storeRelaxed(runs = 0);
pass.restart();
while (pass.elapsed() < 100) {
threadPool.start(new CountingRunnable());
threadPool.start(new CountingRunnable());
runs += 2;
}
- threadPool.waitForDone();
- QCOMPARE(count.load(), runs);
+ WAIT_FOR_DONE(threadPool);
+ QCOMPARE(count.loadRelaxed(), runs);
}
}
@@ -918,7 +1070,7 @@ void tst_QThreadPool::waitForDoneTimeout()
QMutex &mutex;
explicit BlockedTask(QMutex &m) : mutex(m) {}
- void run()
+ void run() override
{
mutex.lock();
mutex.unlock();
@@ -926,7 +1078,7 @@ void tst_QThreadPool::waitForDoneTimeout()
}
};
- QThreadPool threadPool;
+ TestThreadPool threadPool;
mutex.lock();
threadPool.start(new BlockedTask(mutex));
@@ -943,96 +1095,48 @@ void tst_QThreadPool::clear()
public:
QSemaphore & sem;
BlockingRunnable(QSemaphore & sem) : sem(sem){}
- void run()
+ void run() override
{
sem.acquire();
count.ref();
}
};
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setMaxThreadCount(10);
int runs = 2 * threadPool.maxThreadCount();
- count.store(0);
+ count.storeRelaxed(0);
for (int i = 0; i <= runs; i++) {
threadPool.start(new BlockingRunnable(sem));
}
threadPool.clear();
sem.release(threadPool.maxThreadCount());
- threadPool.waitForDone();
- QCOMPARE(count.load(), threadPool.maxThreadCount());
+ WAIT_FOR_DONE(threadPool);
+ QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount());
}
-void tst_QThreadPool::cancel()
+void tst_QThreadPool::clearWithAutoDelete()
{
- QSemaphore sem(0);
- QSemaphore startedThreads(0);
-
- class BlockingRunnable : public QRunnable
+ class MyRunnable : public QRunnable
{
public:
- QSemaphore & sem;
- QSemaphore &startedThreads;
- QAtomicInt &dtorCounter;
- QAtomicInt &runCounter;
- int dummy;
-
- explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r)
- : sem(s), startedThreads(started), dtorCounter(c), runCounter(r){}
-
- ~BlockingRunnable()
- {
- dtorCounter.fetchAndAddRelaxed(1);
- }
-
- void run()
- {
- startedThreads.release();
- runCounter.fetchAndAddRelaxed(1);
- sem.acquire();
- count.ref();
- }
- };
-
- enum {
- MaxThreadCount = 3,
- OverProvisioning = 2,
- runs = MaxThreadCount * OverProvisioning
+ MyRunnable() {}
+ void run() override { QThread::sleep(30us); }
};
- QThreadPool threadPool;
- threadPool.setMaxThreadCount(MaxThreadCount);
- BlockingRunnable *runnables[runs];
-
- // ensure that the QThreadPool doesn't deadlock if any of the checks fail
- // and cause an early return:
- const QSemaphoreReleaser semReleaser(sem, runs);
-
- count.store(0);
- QAtomicInt dtorCounter = 0;
- QAtomicInt runCounter = 0;
- for (int i = 0; i < runs; i++) {
- runnables[i] = new BlockingRunnable(sem, startedThreads, dtorCounter, runCounter);
- runnables[i]->setAutoDelete(i != 0 && i != (runs-1)); //one which will run and one which will not
- threadPool.cancel(runnables[i]); //verify NOOP for jobs not in the queue
- threadPool.start(runnables[i]);
- }
- // wait for all worker threads to have started up:
- QVERIFY(startedThreads.tryAcquire(MaxThreadCount, 60*1000 /* 1min */));
-
- for (int i = 0; i < runs; i++) {
- threadPool.cancel(runnables[i]);
+ TestThreadPool threadPool;
+ threadPool.setMaxThreadCount(4);
+ const int loopCount = 20;
+ const int batchSize = 500;
+ // Should not crash see QTBUG-87092
+ for (int i = 0; i < loopCount; i++) {
+ threadPool.clear();
+ for (int j = 0; j < batchSize; j++) {
+ auto *runnable = new MyRunnable();
+ runnable->setAutoDelete(true);
+ threadPool.start(runnable);
+ }
}
- runnables[0]->dummy = 0; //valgrind will catch this if cancel() is crazy enough to delete currently running jobs
- runnables[runs-1]->dummy = 0;
- QCOMPARE(dtorCounter.load(), runs - threadPool.maxThreadCount() - 1);
- sem.release(threadPool.maxThreadCount());
- threadPool.waitForDone();
- QCOMPARE(runCounter.load(), threadPool.maxThreadCount());
- QCOMPARE(count.load(), threadPool.maxThreadCount());
- QCOMPARE(dtorCounter.load(), runs - 2);
- delete runnables[0]; //if the pool deletes them then we'll get double-free crash
- delete runnables[runs-1];
}
void tst_QThreadPool::tryTake()
@@ -1052,7 +1156,7 @@ void tst_QThreadPool::tryTake()
explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r)
: sem(s), startedThreads(started), dtorCounter(c), runCounter(r) {}
- ~BlockingRunnable()
+ ~BlockingRunnable() override
{
dtorCounter.fetchAndAddRelaxed(1);
}
@@ -1072,7 +1176,7 @@ void tst_QThreadPool::tryTake()
Runs = MaxThreadCount * OverProvisioning
};
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setMaxThreadCount(MaxThreadCount);
BlockingRunnable *runnables[Runs];
@@ -1080,7 +1184,7 @@ void tst_QThreadPool::tryTake()
// and cause an early return:
const QSemaphoreReleaser semReleaser(sem, Runs);
- count.store(0);
+ count.storeRelaxed(0);
QAtomicInt dtorCounter = 0;
QAtomicInt runCounter = 0;
for (int i = 0; i < Runs; i++) {
@@ -1102,36 +1206,37 @@ void tst_QThreadPool::tryTake()
}
runnables[0]->dummy = 0; // valgrind will catch this if tryTake() is crazy enough to delete currently running jobs
- QCOMPARE(dtorCounter.load(), int(Runs - MaxThreadCount));
+ QCOMPARE(dtorCounter.loadRelaxed(), int(Runs - MaxThreadCount));
sem.release(MaxThreadCount);
- threadPool.waitForDone();
- QCOMPARE(runCounter.load(), int(MaxThreadCount));
- QCOMPARE(count.load(), int(MaxThreadCount));
- QCOMPARE(dtorCounter.load(), int(Runs - 1));
+ WAIT_FOR_DONE(threadPool);
+ QCOMPARE(runCounter.loadRelaxed(), int(MaxThreadCount));
+ QCOMPARE(count.loadRelaxed(), int(MaxThreadCount));
+ QCOMPARE(dtorCounter.loadRelaxed(), int(Runs - 1));
delete runnables[0]; // if the pool deletes them then we'll get double-free crash
}
void tst_QThreadPool::destroyingWaitsForTasksToFinish()
{
- QTime total, pass;
+ QElapsedTimer total, pass;
total.start();
+ pass.start();
while (total.elapsed() < 10000) {
int runs;
- count.store(runs = 0);
+ count.storeRelaxed(runs = 0);
{
- QThreadPool threadPool;
+ TestThreadPool threadPool;
pass.restart();
while (pass.elapsed() < 100) {
threadPool.start(new CountingRunnable());
++runs;
}
}
- QCOMPARE(count.load(), runs);
+ QCOMPARE(count.loadRelaxed(), runs);
- count.store(runs = 0);
+ count.storeRelaxed(runs = 0);
{
- QThreadPool threadPool;
+ TestThreadPool threadPool;
pass.restart();
while (pass.elapsed() < 100) {
threadPool.start(new CountingRunnable());
@@ -1139,7 +1244,7 @@ void tst_QThreadPool::destroyingWaitsForTasksToFinish()
runs += 2;
}
}
- QCOMPARE(count.load(), runs);
+ QCOMPARE(count.loadRelaxed(), runs);
}
}
@@ -1167,16 +1272,16 @@ void tst_QThreadPool::stackSize()
}
- void run()
+ void run() override
{
*stackSize = QThread::currentThread()->stackSize();
}
};
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setStackSize(targetStackSize);
threadPool.start(new StackSizeChecker(&threadStackSize));
- QVERIFY(threadPool.waitForDone(30000)); // 30s timeout
+ WAIT_FOR_DONE(threadPool);
QCOMPARE(threadStackSize, targetStackSize);
}
@@ -1198,13 +1303,13 @@ void tst_QThreadPool::stressTest()
semaphore.acquire();
}
- void run()
+ void run() override
{
semaphore.release();
}
};
- QTime total;
+ QElapsedTimer total;
total.start();
while (total.elapsed() < 30000) {
Task t;
@@ -1224,7 +1329,8 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
setAutoDelete(false);
}
- void run() {
+ void run() override
+ {
m_mainBarrier->release();
m_threadBarrier->acquire();
}
@@ -1236,24 +1342,24 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
QSemaphore mainBarrier;
QSemaphore taskBarrier;
- QThreadPool threadPool;
+ TestThreadPool threadPool;
threadPool.setMaxThreadCount(1);
- Task *task1 = new Task(&mainBarrier, &taskBarrier);
- Task *task2 = new Task(&mainBarrier, &taskBarrier);
- Task *task3 = new Task(&mainBarrier, &taskBarrier);
+ Task task1(&mainBarrier, &taskBarrier);
+ Task task2(&mainBarrier, &taskBarrier);
+ Task task3(&mainBarrier, &taskBarrier);
- threadPool.start(task1);
- threadPool.start(task2);
- threadPool.start(task3);
+ threadPool.start(&task1);
+ threadPool.start(&task2);
+ threadPool.start(&task3);
mainBarrier.acquire(1);
QCOMPARE(threadPool.activeThreadCount(), 1);
- QVERIFY(!threadPool.tryTake(task1));
- QVERIFY(threadPool.tryTake(task2));
- QVERIFY(threadPool.tryTake(task3));
+ QVERIFY(!threadPool.tryTake(&task1));
+ QVERIFY(threadPool.tryTake(&task2));
+ QVERIFY(threadPool.tryTake(&task3));
// A bad queue implementation can segfault here because two consecutive items in the queue
// have been taken
@@ -1267,13 +1373,9 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
taskBarrier.release(1);
- threadPool.waitForDone();
+ WAIT_FOR_DONE(threadPool);
QCOMPARE(threadPool.activeThreadCount(), 0);
-
- delete task1;
- delete task2;
- delete task3;
}
void tst_QThreadPool::waitForDoneAfterTake()
@@ -1286,7 +1388,7 @@ void tst_QThreadPool::waitForDoneAfterTake()
, m_threadBarrier(threadBarrier)
{}
- void run()
+ void run() override
{
m_mainBarrier->release();
m_threadBarrier->acquire();
@@ -1304,7 +1406,7 @@ void tst_QThreadPool::waitForDoneAfterTake()
// Blocks the tasks from completing their run function
QSemaphore threadBarrier;
- QThreadPool manager;
+ TestThreadPool manager;
manager.setMaxThreadCount(threadCount);
// Fill all the threads with runnables that wait for the threadBarrier
@@ -1319,9 +1421,9 @@ void tst_QThreadPool::waitForDoneAfterTake()
// This sets the queue elements to nullptr in QThreadPool and we want to test that
// the threads keep going through the queue after encountering a nullptr.
for (int i = 0; i < threadCount; i++) {
- QRunnable *runnable = createTask(emptyFunct);
- manager.start(runnable);
- QVERIFY(manager.tryTake(runnable));
+ QScopedPointer<QRunnable> runnable(createTask(emptyFunct));
+ manager.start(runnable.get());
+ QVERIFY(manager.tryTake(runnable.get()));
}
// Add another runnable that will not be removed
@@ -1335,12 +1437,55 @@ void tst_QThreadPool::waitForDoneAfterTake()
// Release runnables that are waiting and expect all runnables to complete
threadBarrier.release(threadCount);
+}
- // Using qFatal instead of QVERIFY to force exit if threads are still running after timeout.
- // Otherwise, QCoreApplication will still wait for the stale threads and never exit the test.
- if (!manager.waitForDone(5 * 60 * 1000))
- qFatal("waitForDone returned false. Aborting to stop background threads.");
+/*
+ Try trigger reuse of expired threads and check that all tasks execute.
+ This is a regression test for QTBUG-72872.
+*/
+void tst_QThreadPool::threadReuse()
+{
+ TestThreadPool manager;
+ manager.setExpiryTimeout(-1);
+ manager.setMaxThreadCount(1);
+
+ constexpr int repeatCount = 10000;
+ constexpr int timeoutMs = 1000;
+ QSemaphore sem;
+
+ for (int i = 0; i < repeatCount; i++) {
+ manager.start([&sem]() { sem.release(); });
+ manager.start([&sem]() { sem.release(); });
+ manager.releaseThread();
+ QVERIFY(sem.tryAcquire(2, timeoutMs));
+ manager.reserveThread();
+ }
+}
+
+void tst_QThreadPool::nullFunctions()
+{
+ const auto expectWarning = [] {
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg,
+ "Trying to create null QRunnable. This may stop working.");
+ };
+ // Note this is not necessarily testing intended behavior, only undocumented behavior.
+ // If this is changed it should be noted in Behavioral Changes.
+ FunctionPointer nullFunction = nullptr;
+ std::function<void()> nullStdFunction(nullptr);
+ {
+ TestThreadPool manager;
+ // should not crash:
+ expectWarning();
+ manager.start(nullFunction);
+ expectWarning();
+ manager.start(nullStdFunction);
+ // should fail (and not leak):
+ expectWarning();
+ QVERIFY(!manager.tryStart(nullStdFunction));
+ expectWarning();
+ QVERIFY(!manager.tryStart(nullFunction));
+ }
}
QTEST_MAIN(tst_QThreadPool);
diff --git a/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt b/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt
new file mode 100644
index 0000000000..14d8d7dd40
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadstorage/CMakeLists.txt
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qthreadstorage Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qthreadstorage LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qthreadstorage
+ SOURCES
+ tst_qthreadstorage.cpp
+)
+
+## Scopes:
+#####################################################################
+
+if(NOT ANDROID)
+ add_subdirectory(crashonexit)
+ if(QT_FEATURE_process)
+ add_dependencies(tst_qthreadstorage crashOnExit_helper)
+ endif()
+endif()
diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt b/tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt
new file mode 100644
index 0000000000..4d62e61a36
--- /dev/null
+++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## crashonexit Binary:
+#####################################################################
+
+qt_internal_add_executable(crashOnExit_helper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.."
+ INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qthreadstorage/crashOnExit_helper"
+ SOURCES
+ crashOnExit.cpp
+)
diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp
index 5a42156b85..3b3a4d4813 100644
--- a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp
+++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashOnExit.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtCore/QThreadStorage>
diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro
deleted file mode 100644
index 57bd78bcee..0000000000
--- a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-SOURCES += crashOnExit.cpp
-debug_and_release {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/crashOnExit_helper
- } else {
- TARGET = ../../release/crashOnExit_helper
- }
-} else {
- TARGET = ../crashOnExit_helper
-}
-QT = core
-CONFIG += cmdline
-
-# This app is testdata for tst_qthreadstorage
-target.path = $$[QT_INSTALL_TESTS]/tst_qthreadstorage/$$TARGET
-INSTALLS += target
diff --git a/tests/auto/corelib/thread/qthreadstorage/qthreadstorage.pro b/tests/auto/corelib/thread/qthreadstorage/qthreadstorage.pro
deleted file mode 100644
index 432c564ba1..0000000000
--- a/tests/auto/corelib/thread/qthreadstorage/qthreadstorage.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-TEMPLATE = subdirs
-
-!android:!winrt {
- test.depends = crashonexit
- SUBDIRS += crashonexit
-}
-
-SUBDIRS += test
diff --git a/tests/auto/corelib/thread/qthreadstorage/test/test.pro b/tests/auto/corelib/thread/qthreadstorage/test/test.pro
deleted file mode 100644
index d2f21f48f0..0000000000
--- a/tests/auto/corelib/thread/qthreadstorage/test/test.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-debug_and_release {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qthreadstorage
- !android:!winrt: TEST_HELPER_INSTALLS = ../../debug/crashonexit_helper
- } else {
- TARGET = ../../release/tst_qthreadstorage
- !android:!winrt: TEST_HELPER_INSTALLS = ../../release/crashonexit_helper
- }
-} else {
- TARGET = ../tst_qthreadstorage
- !android:!winrt: TEST_HELPER_INSTALLS = ../crashonexit_helper
-}
-CONFIG += console
-QT = core testlib
-SOURCES = ../tst_qthreadstorage.cpp
diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
index ef5d3452d5..ca382cf60c 100644
--- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
+++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
@@ -1,32 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
+#include <QTestEventLoop>
#include <qcoreapplication.h>
#include <qmutex.h>
@@ -76,7 +55,7 @@ void tst_QThreadStorage::hasLocalData()
QVERIFY(!pointers.hasLocalData());
pointers.setLocalData(new Pointer);
QVERIFY(pointers.hasLocalData());
- pointers.setLocalData(0);
+ pointers.setLocalData(nullptr);
QVERIFY(!pointers.hasLocalData());
}
@@ -88,8 +67,8 @@ void tst_QThreadStorage::localData()
pointers.setLocalData(p);
QVERIFY(pointers.hasLocalData());
QCOMPARE(pointers.localData(), p);
- pointers.setLocalData(0);
- QCOMPARE(pointers.localData(), (Pointer *)0);
+ pointers.setLocalData(nullptr);
+ QCOMPARE(pointers.localData(), nullptr);
QVERIFY(!pointers.hasLocalData());
}
@@ -102,8 +81,8 @@ void tst_QThreadStorage::localData_const()
pointers.setLocalData(p);
QVERIFY(pointers.hasLocalData());
QCOMPARE(const_pointers.localData(), p);
- pointers.setLocalData(0);
- QCOMPARE(const_pointers.localData(), (Pointer *)0);
+ pointers.setLocalData(nullptr);
+ QCOMPARE(const_pointers.localData(), nullptr);
QVERIFY(!pointers.hasLocalData());
}
@@ -113,7 +92,7 @@ void tst_QThreadStorage::setLocalData()
QVERIFY(!pointers.hasLocalData());
pointers.setLocalData(new Pointer);
QVERIFY(pointers.hasLocalData());
- pointers.setLocalData(0);
+ pointers.setLocalData(nullptr);
QVERIFY(!pointers.hasLocalData());
}
@@ -129,7 +108,7 @@ public:
: pointers(p)
{ }
- void run()
+ void run() override
{
pointers.setLocalData(new Pointer);
@@ -157,7 +136,7 @@ void tst_QThreadStorage::autoDelete()
QCOMPARE(Pointer::count, c);
}
-bool threadStorageOk;
+static bool threadStorageOk;
void testAdoptedThreadStorageWin(void *p)
{
QThreadStorage<Pointer *> *pointers = reinterpret_cast<QThreadStorage<Pointer *> *>(p);
@@ -180,17 +159,10 @@ void testAdoptedThreadStorageWin(void *p)
}
QObject::connect(QThread::currentThread(), SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
}
-#ifdef Q_OS_WINRT
-unsigned __stdcall testAdoptedThreadStorageWinRT(void *p)
-{
- testAdoptedThreadStorageWin(p);
- return 0;
-}
-#endif
void *testAdoptedThreadStorageUnix(void *pointers)
{
testAdoptedThreadStorageWin(pointers);
- return 0;
+ return nullptr;
}
void tst_QThreadStorage::adoptedThreads()
{
@@ -201,14 +173,9 @@ void tst_QThreadStorage::adoptedThreads()
{
#ifdef Q_OS_UNIX
pthread_t thread;
- const int state = pthread_create(&thread, 0, testAdoptedThreadStorageUnix, &pointers);
+ const int state = pthread_create(&thread, nullptr, testAdoptedThreadStorageUnix, &pointers);
QCOMPARE(state, 0);
- pthread_join(thread, 0);
-#elif defined Q_OS_WINRT
- HANDLE thread;
- thread = (HANDLE) _beginthreadex(NULL, 0, testAdoptedThreadStorageWinRT, &pointers, 0, 0);
- QVERIFY(thread);
- WaitForSingleObjectEx(thread, INFINITE, FALSE);
+ pthread_join(thread, nullptr);
#elif defined Q_OS_WIN
HANDLE thread;
thread = (HANDLE)_beginthread(testAdoptedThreadStorageWin, 0, &pointers);
@@ -224,7 +191,7 @@ void tst_QThreadStorage::adoptedThreads()
QTRY_COMPARE(Pointer::count, c);
}
-QBasicAtomicInt cleanupOrder = Q_BASIC_ATOMIC_INITIALIZER(0);
+static QBasicAtomicInt cleanupOrder = Q_BASIC_ATOMIC_INITIALIZER(0);
class First
{
@@ -261,7 +228,7 @@ void tst_QThreadStorage::ensureCleanupOrder()
: first(first), second(second)
{ }
- void run()
+ void run() override
{
// set in reverse order, but shouldn't matter, the data
// will be deleted in the order the thread storage objects
@@ -305,11 +272,14 @@ static inline bool runCrashOnExit(const QString &binary, QString *errorMessage)
void tst_QThreadStorage::crashOnExit()
{
+#ifdef Q_OS_ANDROID
+ QSKIP("Can't start QProcess to run a custom user binary on Android");
+#endif
#if !QT_CONFIG(process)
QSKIP("No qprocess support", SkipAll);
#else
QString errorMessage;
- QVERIFY2(runCrashOnExit("crashOnExit_helper", &errorMessage),
+ QVERIFY2(runCrashOnExit("./crashOnExit_helper", &errorMessage),
qPrintable(errorMessage));
#endif
}
@@ -352,14 +322,14 @@ void tst_QThreadStorage::leakInDestructor()
Thread(QThreadStorage<ThreadStorageLocalDataTester *> &t) : tls(t) { }
- void run()
+ void run() override
{
QVERIFY(!tls.hasLocalData());
tls.setLocalData(new ThreadStorageLocalDataTester);
QVERIFY(tls.hasLocalData());
}
};
- int c = SPointer::count.load();
+ int c = SPointer::count.loadRelaxed();
QThreadStorage<ThreadStorageLocalDataTester *> tls;
@@ -383,7 +353,7 @@ void tst_QThreadStorage::leakInDestructor()
QVERIFY(t3.wait());
//check all the constructed things have been destructed
- QCOMPARE(int(SPointer::count.load()), c);
+ QCOMPARE(int(SPointer::count.loadRelaxed()), c);
}
class ThreadStorageResetLocalDataTester {
@@ -404,14 +374,14 @@ void tst_QThreadStorage::resetInDestructor()
class Thread : public QThread
{
public:
- void run()
+ void run() override
{
QVERIFY(!ThreadStorageResetLocalDataTesterTls()->hasLocalData());
ThreadStorageResetLocalDataTesterTls()->setLocalData(new ThreadStorageResetLocalDataTester);
QVERIFY(ThreadStorageResetLocalDataTesterTls()->hasLocalData());
}
};
- int c = SPointer::count.load();
+ int c = SPointer::count.loadRelaxed();
Thread t1;
Thread t2;
@@ -424,7 +394,7 @@ void tst_QThreadStorage::resetInDestructor()
QVERIFY(t3.wait());
//check all the constructed things have been destructed
- QCOMPARE(int(SPointer::count.load()), c);
+ QCOMPARE(int(SPointer::count.loadRelaxed()), c);
}
@@ -440,7 +410,8 @@ void tst_QThreadStorage::valueBased()
Thread(QThreadStorage<SPointer> &t1, QThreadStorage<QString> &t2, QThreadStorage<int> &t3)
: tlsSPointer(t1), tlsString(t2), tlsInt(t3) { }
- void run() {
+ void run() override
+ {
/*QVERIFY(!tlsSPointer.hasLocalData());
QVERIFY(!tlsString.hasLocalData());
QVERIFY(!tlsInt.hasLocalData());*/
@@ -475,7 +446,7 @@ void tst_QThreadStorage::valueBased()
QThreadStorage<QString> tlsString;
QThreadStorage<int> tlsInt;
- int c = SPointer::count.load();
+ int c = SPointer::count.loadRelaxed();
Thread t1(tlsSPointer, tlsString, tlsInt);
Thread t2(tlsSPointer, tlsString, tlsInt);
@@ -495,7 +466,7 @@ void tst_QThreadStorage::valueBased()
QVERIFY(t2.wait());
QVERIFY(t3.wait());
- QCOMPARE(c, int(SPointer::count.load()));
+ QCOMPARE(c, int(SPointer::count.loadRelaxed()));
}
diff --git a/tests/auto/corelib/thread/qwaitcondition/BLACKLIST b/tests/auto/corelib/thread/qwaitcondition/BLACKLIST
deleted file mode 100644
index 3ff336576b..0000000000
--- a/tests/auto/corelib/thread/qwaitcondition/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[wakeOne]
-windows
diff --git a/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt b/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt
new file mode 100644
index 0000000000..0a2830622e
--- /dev/null
+++ b/tests/auto/corelib/thread/qwaitcondition/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qwaitcondition Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qwaitcondition LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qwaitcondition
+ SOURCES
+ tst_qwaitcondition.cpp
+)
diff --git a/tests/auto/corelib/thread/qwaitcondition/qwaitcondition.pro b/tests/auto/corelib/thread/qwaitcondition/qwaitcondition.pro
deleted file mode 100644
index 2098d9dd2f..0000000000
--- a/tests/auto/corelib/thread/qwaitcondition/qwaitcondition.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qwaitcondition
-QT = core testlib
-SOURCES = tst_qwaitcondition.cpp
diff --git a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
index 126cb6b180..4e3413afe8 100644
--- a/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
+++ b/tests/auto/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QReadWriteLock>
#include <qatomic.h>
#include <qcoreapplication.h>
@@ -77,7 +53,7 @@ public:
inline wait_QMutex_Thread_1()
{ }
- void run()
+ void run() override
{
mutex.lock();
cond.wakeOne();
@@ -95,10 +71,10 @@ public:
QWaitCondition *cond;
inline wait_QMutex_Thread_2()
- : mutex(0), cond(0)
+ : mutex(nullptr), cond(nullptr)
{ }
- void run()
+ void run() override
{
mutex->lock();
started.wakeOne();
@@ -116,7 +92,7 @@ public:
inline wait_QReadWriteLock_Thread_1()
{ }
- void run()
+ void run() override
{
readWriteLock.lockForWrite();
cond.wakeOne();
@@ -134,10 +110,10 @@ public:
QWaitCondition *cond;
inline wait_QReadWriteLock_Thread_2()
- : readWriteLock(0), cond(0)
+ : readWriteLock(nullptr), cond(nullptr)
{ }
- void run()
+ void run() override
{
readWriteLock->lockForRead();
started.wakeOne();
@@ -392,13 +368,13 @@ public:
QWaitCondition *cond;
inline wake_Thread()
- : mutex(0), cond(0)
+ : mutex(nullptr), cond(nullptr)
{ }
static inline void sleep(ulong s)
- { QThread::sleep(s); }
+ { QThread::sleep(std::chrono::seconds{s}); }
- void run()
+ void run() override
{
Q_ASSERT(count);
Q_ASSERT(mutex);
@@ -424,13 +400,13 @@ public:
QWaitCondition *cond;
inline wake_Thread_2()
- : readWriteLock(0), cond(0)
+ : readWriteLock(nullptr), cond(nullptr)
{ }
static inline void sleep(ulong s)
- { QThread::sleep(s); }
+ { QThread::sleep(std::chrono::seconds{s}); }
- void run()
+ void run() override
{
Q_ASSERT(count);
Q_ASSERT(readWriteLock);
@@ -481,7 +457,7 @@ void tst_QWaitCondition::wakeOne()
}
mutex.unlock();
- QCOMPARE(count.load(), ThreadCount);
+ QCOMPARE(count.loadRelaxed(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; ++x) {
@@ -502,10 +478,10 @@ void tst_QWaitCondition::wakeOne()
}
QCOMPARE(exited, 1);
- QCOMPARE(count.load(), ThreadCount - (x + 1));
+ QCOMPARE(count.loadRelaxed(), ThreadCount - (x + 1));
}
- QCOMPARE(count.load(), 0);
+ QCOMPARE(count.loadRelaxed(), 0);
// QReadWriteLock
QReadWriteLock readWriteLock;
@@ -530,7 +506,7 @@ void tst_QWaitCondition::wakeOne()
}
readWriteLock.unlock();
- QCOMPARE(count.load(), ThreadCount);
+ QCOMPARE(count.loadRelaxed(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; ++x) {
@@ -551,10 +527,10 @@ void tst_QWaitCondition::wakeOne()
}
QCOMPARE(exited, 1);
- QCOMPARE(count.load(), ThreadCount - (x + 1));
+ QCOMPARE(count.loadRelaxed(), ThreadCount - (x + 1));
}
- QCOMPARE(count.load(), 0);
+ QCOMPARE(count.loadRelaxed(), 0);
}
// wake up threads, two at a time
@@ -585,7 +561,7 @@ void tst_QWaitCondition::wakeOne()
}
mutex.unlock();
- QCOMPARE(count.load(), ThreadCount);
+ QCOMPARE(count.loadRelaxed(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; x += 2) {
@@ -608,10 +584,10 @@ void tst_QWaitCondition::wakeOne()
}
QCOMPARE(exited, 2);
- QCOMPARE(count.load(), ThreadCount - (x + 2));
+ QCOMPARE(count.loadRelaxed(), ThreadCount - (x + 2));
}
- QCOMPARE(count.load(), 0);
+ QCOMPARE(count.loadRelaxed(), 0);
// QReadWriteLock
QReadWriteLock readWriteLock;
@@ -636,7 +612,7 @@ void tst_QWaitCondition::wakeOne()
}
readWriteLock.unlock();
- QCOMPARE(count.load(), ThreadCount);
+ QCOMPARE(count.loadRelaxed(), ThreadCount);
// wake up threads one at a time
for (x = 0; x < ThreadCount; x += 2) {
@@ -659,10 +635,10 @@ void tst_QWaitCondition::wakeOne()
}
QCOMPARE(exited, 2);
- QCOMPARE(count.load(), ThreadCount - (x + 2));
+ QCOMPARE(count.loadRelaxed(), ThreadCount - (x + 2));
}
- QCOMPARE(count.load(), 0);
+ QCOMPARE(count.loadRelaxed(), 0);
}
}
@@ -692,7 +668,7 @@ void tst_QWaitCondition::wakeAll()
}
mutex.unlock();
- QCOMPARE(count.load(), ThreadCount);
+ QCOMPARE(count.loadRelaxed(), ThreadCount);
// wake up all threads at once
mutex.lock();
@@ -707,7 +683,7 @@ void tst_QWaitCondition::wakeAll()
}
QCOMPARE(exited, ThreadCount);
- QCOMPARE(count.load(), 0);
+ QCOMPARE(count.loadRelaxed(), 0);
// QReadWriteLock
QReadWriteLock readWriteLock;
@@ -728,7 +704,7 @@ void tst_QWaitCondition::wakeAll()
}
readWriteLock.unlock();
- QCOMPARE(count.load(), ThreadCount);
+ QCOMPARE(count.loadRelaxed(), ThreadCount);
// wake up all threads at once
readWriteLock.lockForWrite();
@@ -743,7 +719,7 @@ void tst_QWaitCondition::wakeAll()
}
QCOMPARE(exited, ThreadCount);
- QCOMPARE(count.load(), 0);
+ QCOMPARE(count.loadRelaxed(), 0);
}
}
@@ -764,7 +740,8 @@ public:
QWaitCondition *startup;
QWaitCondition *waitCondition;
- void run() {
+ void run() override
+ {
mutex->lock();
ready = true;
@@ -796,7 +773,8 @@ public:
QWaitCondition *startup;
QWaitCondition *waitCondition;
- void run() {
+ void run() override
+ {
readWriteLock->lockForWrite();
ready = true;
diff --git a/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt b/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt
new file mode 100644
index 0000000000..5345522ea5
--- /dev/null
+++ b/tests/auto/corelib/thread/qwritelocker/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qwritelocker Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qwritelocker LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qwritelocker
+ SOURCES
+ tst_qwritelocker.cpp
+)
diff --git a/tests/auto/corelib/thread/qwritelocker/qwritelocker.pro b/tests/auto/corelib/thread/qwritelocker/qwritelocker.pro
deleted file mode 100644
index a6c4f70b8d..0000000000
--- a/tests/auto/corelib/thread/qwritelocker/qwritelocker.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qwritelocker
-QT = core testlib
-SOURCES = tst_qwritelocker.cpp
diff --git a/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp b/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp
index 876c18c721..b4e6b45dbd 100644
--- a/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp
+++ b/tests/auto/corelib/thread/qwritelocker/tst_qwritelocker.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QCoreApplication>
#include <QWriteLocker>
@@ -73,7 +48,7 @@ void tst_QWriteLocker::scopeTest()
class ScopeTestThread : public tst_QWriteLockerThread
{
public:
- void run()
+ void run() override
{
waitForTest();
@@ -109,7 +84,7 @@ void tst_QWriteLocker::scopeTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
@@ -118,7 +93,7 @@ void tst_QWriteLocker::unlockAndRelockTest()
class UnlockAndRelockThread : public tst_QWriteLockerThread
{
public:
- void run()
+ void run() override
{
QWriteLocker locker(&lock);
@@ -156,7 +131,7 @@ void tst_QWriteLocker::unlockAndRelockTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
void tst_QWriteLocker::lockerStateTest()
@@ -164,7 +139,7 @@ void tst_QWriteLocker::lockerStateTest()
class LockerStateThread : public tst_QWriteLockerThread
{
public:
- void run()
+ void run() override
{
{
QWriteLocker locker(&lock);
@@ -196,7 +171,7 @@ void tst_QWriteLocker::lockerStateTest()
QVERIFY(thread->wait());
delete thread;
- thread = 0;
+ thread = nullptr;
}
QTEST_MAIN(tst_QWriteLocker)
diff --git a/tests/auto/corelib/thread/thread.pro b/tests/auto/corelib/thread/thread.pro
deleted file mode 100644
index 90b8d6806e..0000000000
--- a/tests/auto/corelib/thread/thread.pro
+++ /dev/null
@@ -1,27 +0,0 @@
-TEMPLATE=subdirs
-
-qtConfig(thread) {
- SUBDIRS=\
- qatomicint \
- qatomicinteger \
- qatomicpointer \
- qresultstore \
- qfuture \
- qfuturesynchronizer \
- qmutex \
- qmutexlocker \
- qreadlocker \
- qreadwritelock \
- qsemaphore \
- qthread \
- qthreadonce \
- qthreadpool \
- qthreadstorage \
- qwaitcondition \
- qwritelocker
-}
-
-qtHaveModule(concurrent) {
- SUBDIRS += \
- qfuturewatcher
-}
diff --git a/tests/auto/corelib/time/CMakeLists.txt b/tests/auto/corelib/time/CMakeLists.txt
new file mode 100644
index 0000000000..f2dfbfa527
--- /dev/null
+++ b/tests/auto/corelib/time/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qcalendar)
+add_subdirectory(qdate)
+add_subdirectory(qdatetime)
+add_subdirectory(qdatetimeparser)
+add_subdirectory(qtime)
+add_subdirectory(qtimezone)
diff --git a/tests/auto/corelib/time/qcalendar/CMakeLists.txt b/tests/auto/corelib/time/qcalendar/CMakeLists.txt
new file mode 100644
index 0000000000..5b1b2dfc2a
--- /dev/null
+++ b/tests/auto/corelib/time/qcalendar/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcalendar Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcalendar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcalendar
+ SOURCES
+ tst_qcalendar.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp
new file mode 100644
index 0000000000..61999202d2
--- /dev/null
+++ b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp
@@ -0,0 +1,454 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <QCalendar>
+#include <private/qgregoriancalendar_p.h>
+Q_DECLARE_METATYPE(QCalendar::System)
+
+class tst_QCalendar : public QObject
+{
+ Q_OBJECT
+private:
+ void checkYear(const QCalendar &cal, int year, bool normal=false);
+
+private slots:
+ void basic_data();
+ void basic();
+ void unspecified_data() { basic_data(); }
+ void unspecified();
+ void nameCase();
+ void specific_data();
+ void specific();
+ void daily_data() { basic_data(); }
+ void daily();
+ void testYearMonthDate();
+ void properties_data();
+ void properties();
+ void aliases();
+
+ void gregory();
+};
+
+static void checkCenturyResolution(const QCalendar &cal, const QCalendar::YearMonthDay &base)
+{
+ quint8 weekDayMask = 0;
+ for (int offset = -7; offset < 8; ++offset) {
+ const auto probe = QDate(base.year, base.month, base.day, cal).addYears(100 * offset, cal);
+ const int dow = cal.dayOfWeek(probe);
+ if (probe.isValid() && dow > 0 && dow < 8)
+ weekDayMask |= 1 << quint8(dow - 1);
+ }
+ for (int j = 1; j < 8; ++j) {
+ const bool seen = weekDayMask & (1 << quint8(j - 1));
+ const QDate check = cal.matchCenturyToWeekday(base, j);
+ if (check.isValid()) {
+ const auto parts = cal.partsFromDate(check);
+ const int dow = cal.dayOfWeek(check);
+ QCOMPARE(dow, j);
+ QCOMPARE(parts.day, base.day);
+ QCOMPARE(parts.month, base.month);
+ int gap = parts.year - base.year;
+ if (!cal.hasYearZero() && (parts.year > 0) != (base.year > 0))
+ gap += parts.year > 0 ? -1 : +1;
+ auto report = qScopeGuard([parts, base]() {
+ qDebug("Wrongly matched year: %d replaced %d", parts.year, base.year);
+ });
+ QCOMPARE(gap % 100, 0);
+ // We searched 7 centuries each side of base.
+ if (seen) {
+ QCOMPARE_LT(gap / 100, 8);
+ QCOMPARE_GT(gap / 100, -8);
+ } else {
+ QVERIFY(gap / 100 >= 8 || gap / 100 <= -8);
+ }
+ report.dismiss();
+ } else {
+ auto report = qScopeGuard([j, base]() {
+ qDebug("Missed dow[%d] for %d/%d/%d", j, base.year, base.month, base.day);
+ });
+ QVERIFY(!seen);
+ report.dismiss();
+ }
+ }
+}
+
+// Support for basic():
+void tst_QCalendar::checkYear(const QCalendar &cal, int year, bool normal)
+{
+ const int moons = cal.monthsInYear(year);
+ // Months are numbered from 1 to moons:
+ QVERIFY(moons > 0);
+ QVERIFY(!cal.isDateValid(year, moons + 1, 1));
+ QVERIFY(!cal.isDateValid(year, 0, 1));
+ QVERIFY(!QDate(year, 0, 1, cal).isValid());
+ QVERIFY(moons <= cal.maximumMonthsInYear());
+ QCOMPARE(cal.standaloneMonthName(QLocale::c(), moons + 1, year), QString());
+ QCOMPARE(cal.monthName(QLocale::c(), 0, year), QString());
+
+ const int days = cal.daysInYear(year);
+ QVERIFY(days > 0);
+
+ int sum = 0;
+ const int longest = cal.maximumDaysInMonth();
+ for (int i = moons; i > 0; --i) {
+ const int last = cal.daysInMonth(i, year);
+ sum += last;
+ // Valid month has some days and no more than max:
+ QVERIFY(last > 0);
+ QVERIFY(last <= longest);
+ // Days are numbered from 1 to last:
+ QVERIFY(cal.isDateValid(year, i, 1));
+ QVERIFY(cal.isDateValid(year, i, last));
+ QVERIFY(!cal.isDateValid(year, i, 0));
+ QVERIFY(!cal.isDateValid(year, i, last + 1));
+ if (normal) // Unspecified year gets same daysInMonth():
+ QCOMPARE(cal.daysInMonth(i), last);
+
+ checkCenturyResolution(cal, {year, i, (last + 1) / 2});
+ if (QTest::currentTestFailed())
+ return;
+ }
+ // Months add up to the whole year:
+ QCOMPARE(sum, days);
+}
+
+#define CHECKYEAR(cal, year) checkYear(cal, year); \
+ if (QTest::currentTestFailed()) \
+ return
+
+#define NORMALYEAR(cal, year) checkYear(cal, year, true); \
+ if (QTest::currentTestFailed()) \
+ return
+
+void tst_QCalendar::basic_data()
+{
+ QTest::addColumn<QCalendar::System>("system");
+
+ QMetaEnum e = QCalendar::staticMetaObject.enumerator(0);
+ Q_ASSERT(qstrcmp(e.name(), "System") == 0);
+
+ for (int i = 0; i <= int(QCalendar::System::Last); ++i) {
+ // There may be gaps in the enum's numbering; and Last is a duplicate:
+ if (e.value(i) != -1 && qstrcmp(e.key(i), "Last"))
+ QTest::newRow(e.key(i)) << QCalendar::System(e.value(i));
+ }
+}
+
+void tst_QCalendar::basic()
+{
+ QFETCH(QCalendar::System, system);
+ QCalendar cal(system);
+ QVERIFY(cal.isValid());
+ QCOMPARE(QCalendar(cal.name()).isGregorian(), cal.isGregorian());
+ QCOMPARE(QCalendar(cal.name()).name(), cal.name());
+
+ if (cal.hasYearZero()) {
+ CHECKYEAR(cal, 0);
+ } else {
+ QCOMPARE(cal.monthsInYear(0), 0);
+ QCOMPARE(cal.daysInYear(0), 0);
+ QVERIFY(!cal.isDateValid(0, 1, 1));
+ QVERIFY(!QDate(0, 1, 1, cal).isValid());
+ }
+
+ if (cal.isProleptic()) {
+ CHECKYEAR(cal, -1);
+ } else {
+ QCOMPARE(cal.monthsInYear(-1), 0);
+ QCOMPARE(cal.daysInYear(-1), 0);
+ QVERIFY(!cal.isDateValid(-1, 1, 1));
+ }
+
+ // Look for a leap year in the last decade.
+ int year = QDate::currentDate().year(cal);
+ for (int i = 10; i > 0 && !cal.isLeapYear(year); --i)
+ --year;
+ if (cal.isLeapYear(year)) {
+ // ... and a non-leap year within a decade before it.
+ int leap = year--;
+ for (int i = 10; i > 0 && cal.isLeapYear(year); --i)
+ year--;
+ if (!cal.isLeapYear(year))
+ QVERIFY(cal.daysInYear(year) < cal.daysInYear(leap));
+
+ CHECKYEAR(cal, leap);
+ }
+ // Either year is non-leap or we have a decade of leap years together;
+ // expect daysInMonth() to treat year the same as unspecified.
+ NORMALYEAR(cal, year);
+}
+
+void tst_QCalendar::unspecified()
+{
+ QFETCH(QCalendar::System, system);
+ QCalendar cal(system);
+
+ const QDate today = QDate::currentDate();
+ const int thisYear = today.year();
+ QCOMPARE(cal.monthsInYear(QCalendar::Unspecified), cal.maximumMonthsInYear());
+ for (int month = cal.maximumMonthsInYear(); month > 0; month--) {
+ const int days = cal.daysInMonth(month);
+ int count = 0;
+ // 19 years = one Metonic cycle (used by some lunar calendars)
+ for (int i = 19; i > 0; --i) {
+ if (cal.daysInMonth(month, thisYear - i) == days)
+ count++;
+ }
+ // Require a majority of the years tested:
+ QVERIFY2(count > 9, "Default daysInMonth() should be for a normal year");
+ }
+}
+
+void tst_QCalendar::nameCase()
+{
+ QVERIFY(QCalendar::availableCalendars().contains(QStringLiteral("Gregorian")));
+}
+
+void tst_QCalendar::specific_data()
+{
+ QTest::addColumn<QCalendar::System>("system");
+ // Date in that system:
+ QTest::addColumn<QString>("monthName");
+ QTest::addColumn<int>("sysyear");
+ QTest::addColumn<int>("sysmonth");
+ QTest::addColumn<int>("sysday");
+ // Gregorian equivalent:
+ QTest::addColumn<int>("gregyear");
+ QTest::addColumn<int>("gregmonth");
+ QTest::addColumn<int>("gregday");
+
+#define ADDROW(cal, monthName, year, month, day, gy, gm, gd) \
+ QTest::newRow(#cal) << QCalendar::System::cal << QStringLiteral(monthName) \
+ << year << month << day << gy << gm << gd
+
+ ADDROW(Gregorian, "January", 1970, 1, 1, 1970, 1, 1);
+
+ // One known specific date, for each calendar
+#ifndef QT_BOOTSTRAPPED
+ // Julian 1582-10-4 was followed by Gregorian 1582-10-15
+ ADDROW(Julian, "October", 1582, 10, 4, 1582, 10, 14);
+ // Milankovic matches Gregorian for a few centuries
+ ADDROW(Milankovic, "March", 1923, 3, 20, 1923, 3, 20);
+#endif
+
+#if QT_CONFIG(jalalicalendar)
+ // Jalali year 1355 started on Gregorian 1976-3-21:
+ ADDROW(Jalali, "Farvardin", 1355, 1, 1, 1976, 3, 21);
+#endif // jalali
+#if QT_CONFIG(islamiccivilcalendar)
+ // TODO: confirm this is correct
+ ADDROW(IslamicCivil, "Muharram", 1, 1, 1, 622, 7, 19);
+#endif
+
+#undef ADDROW
+}
+
+void tst_QCalendar::specific()
+{
+ QFETCH(QCalendar::System, system);
+ QFETCH(const QString, monthName);
+ QFETCH(int, sysyear);
+ QFETCH(int, sysmonth);
+ QFETCH(int, sysday);
+ QFETCH(int, gregyear);
+ QFETCH(int, gregmonth);
+ QFETCH(int, gregday);
+
+ const QCalendar cal(system);
+ QCOMPARE(cal.monthName(QLocale::c(), sysmonth), monthName);
+ const QDate date(sysyear, sysmonth, sysday, cal), gregory(gregyear, gregmonth, gregday);
+ QCOMPARE(date, gregory);
+ QCOMPARE(gregory.year(cal), sysyear);
+ QCOMPARE(gregory.month(cal), sysmonth);
+ QCOMPARE(gregory.day(cal), sysday);
+ QCOMPARE(date.year(), gregyear);
+ QCOMPARE(date.month(), gregmonth);
+ QCOMPARE(date.day(), gregday);
+}
+
+void tst_QCalendar::daily()
+{
+ QFETCH(QCalendar::System, system);
+ QCalendar calendar(system);
+ const quint64 startJDN = 0, endJDN = 2488070;
+ // Iterate from -4713-01-01 (Julian calendar) to 2100-01-01
+ for (quint64 expect = startJDN; expect <= endJDN; ++expect)
+ {
+ QDate date = QDate::fromJulianDay(expect);
+ auto parts = calendar.partsFromDate(date);
+ if (!parts.isValid())
+ continue;
+
+ const int year = date.year(calendar);
+ QCOMPARE(year, parts.year);
+ const int month = date.month(calendar);
+ QCOMPARE(month, parts.month);
+ const int day = date.day(calendar);
+ QCOMPARE(day, parts.day);
+ const quint64 actual = QDate(year, month, day, calendar).toJulianDay();
+ QCOMPARE(actual, expect);
+ }
+}
+
+void tst_QCalendar::testYearMonthDate()
+{
+ QCalendar::YearMonthDay defYMD;
+ QCOMPARE(defYMD.year, QCalendar::Unspecified);
+ QCOMPARE(defYMD.month, QCalendar::Unspecified);
+ QCOMPARE(defYMD.day, QCalendar::Unspecified);
+
+ QCalendar::YearMonthDay ymd2020(2020);
+ QCOMPARE(ymd2020.year, 2020);
+ QCOMPARE(ymd2020.month, 1);
+ QCOMPARE(ymd2020.day, 1);
+
+ QVERIFY(!QCalendar::YearMonthDay(
+ QCalendar::Unspecified, QCalendar::Unspecified, QCalendar::Unspecified).isValid());
+ QVERIFY(!QCalendar::YearMonthDay(
+ QCalendar::Unspecified, QCalendar::Unspecified, 1).isValid());
+ QVERIFY(!QCalendar::YearMonthDay(
+ QCalendar::Unspecified, 1, QCalendar::Unspecified).isValid());
+ QVERIFY(QCalendar::YearMonthDay(
+ QCalendar::Unspecified, 1, 1).isValid());
+ QVERIFY(!QCalendar::YearMonthDay(
+ 2020, QCalendar::Unspecified, QCalendar::Unspecified).isValid());
+ QVERIFY(!QCalendar::YearMonthDay(
+ 2020, QCalendar::Unspecified, 1).isValid());
+ QVERIFY(!QCalendar::YearMonthDay(
+ 2020, 1, QCalendar::Unspecified).isValid());
+ QVERIFY(QCalendar::YearMonthDay(
+ 2020, 1, 1).isValid());
+}
+
+void tst_QCalendar::properties_data()
+{
+ QTest::addColumn<QCalendar::System>("system");
+ QTest::addColumn<bool>("gregory");
+ QTest::addColumn<bool>("lunar");
+ QTest::addColumn<bool>("luniSolar");
+ QTest::addColumn<bool>("solar");
+ QTest::addColumn<bool>("proleptic");
+ QTest::addColumn<bool>("yearZero");
+ QTest::addColumn<int>("monthMax");
+ QTest::addColumn<int>("monthMin");
+ QTest::addColumn<int>("yearMax");
+ QTest::addColumn<QString>("name");
+
+ QTest::addRow("Gregorian")
+ << QCalendar::System::Gregorian << true << false << false << true << true << false
+ << 31 << 28 << 12 << QStringLiteral("Gregorian");
+#ifndef QT_BOOTSTRAPPED
+ QTest::addRow("Julian")
+ << QCalendar::System::Julian << false << false << false << true << true << false
+ << 31 << 28 << 12 << QStringLiteral("Julian");
+ QTest::addRow("Milankovic")
+ << QCalendar::System::Milankovic << false << false << false << true << true << false
+ << 31 << 28 << 12 << QStringLiteral("Milankovic");
+#endif
+
+#if QT_CONFIG(jalalicalendar)
+ QTest::addRow("Jalali")
+ << QCalendar::System::Jalali << false << false << false << true << true << false
+ << 31 << 29 << 12 << QStringLiteral("Jalali");
+#endif
+#if QT_CONFIG(islamiccivilcalendar)
+ QTest::addRow("IslamicCivil")
+ << QCalendar::System::IslamicCivil << false << true << false << false << true << false
+ << 30 << 29 << 12 << QStringLiteral("Islamic Civil");
+#endif
+}
+
+void tst_QCalendar::properties()
+{
+ QFETCH(const QCalendar::System, system);
+ QFETCH(const bool, gregory);
+ QFETCH(const bool, lunar);
+ QFETCH(const bool, luniSolar);
+ QFETCH(const bool, solar);
+ QFETCH(const bool, proleptic);
+ QFETCH(const bool, yearZero);
+ QFETCH(const int, monthMax);
+ QFETCH(const int, monthMin);
+ QFETCH(const int, yearMax);
+ QFETCH(const QString, name);
+
+ const QCalendar cal(system);
+ QCOMPARE(cal.isGregorian(), gregory);
+ QCOMPARE(cal.isLunar(), lunar);
+ QCOMPARE(cal.isLuniSolar(), luniSolar);
+ QCOMPARE(cal.isSolar(), solar);
+ QCOMPARE(cal.isProleptic(), proleptic);
+ QCOMPARE(cal.hasYearZero(), yearZero);
+ QCOMPARE(cal.maximumDaysInMonth(), monthMax);
+ QCOMPARE(cal.minimumDaysInMonth(), monthMin);
+ QCOMPARE(cal.maximumMonthsInYear(), yearMax);
+ QCOMPARE(cal.name(), name);
+}
+
+void tst_QCalendar::aliases()
+{
+ QCOMPARE(QCalendar(u"gregory").name(), u"Gregorian");
+#if QT_CONFIG(jalalicalendar)
+ QCOMPARE(QCalendar(u"Persian").name(), u"Jalali");
+#endif
+#if QT_CONFIG(islamiccivilcalendar)
+ // Exercise all constructors from name, while we're at it:
+ QCOMPARE(QCalendar(u"islamic-civil").name(), u"Islamic Civil");
+ QCOMPARE(QCalendar(QLatin1String("islamic")).name(), u"Islamic Civil");
+ QCOMPARE(QCalendar(QStringLiteral("Islamic")).name(), u"Islamic Civil");
+#endif
+
+ // Invalid is handled gracefully:
+ QCOMPARE(QCalendar(u"").name(), QString());
+ QCOMPARE(QCalendar(QCalendar::System::User).name(), QString());
+}
+
+void tst_QCalendar::gregory()
+{
+ // Test QGregorianCalendar's internal-use methods.
+
+ // Julian day number 0 is in 4713; and reach past the end of four-digit years:
+ for (int year = -4720; year < 12345; ++year) {
+ // Test yearStartWeekDay() and yearSharingWeekDays() are consistent with
+ // dateToJulianDay() and weekDayOfJulian():
+ if (!year) // No year zero.
+ continue;
+ const auto first = QGregorianCalendar::julianFromParts(year, 1, 1);
+ QVERIFY2(first, "Only year zero should lack a first day");
+ QCOMPARE(QGregorianCalendar::yearStartWeekDay(year),
+ QGregorianCalendar::weekDayOfJulian(*first));
+ const auto last = QGregorianCalendar::julianFromParts(year, 12, 31);
+ QVERIFY2(last, "Only year zero should lack a last day");
+
+ const int lastTwo = (year + (year < 0 ? 1 : 0)) % 100 + (year < -1 ? 100 : 0);
+ const QDate probe(year, lastTwo && lastTwo <= 12 ? lastTwo : 8,
+ lastTwo <= 31 && lastTwo > 12 ? lastTwo : 17);
+ const int match = QGregorianCalendar::yearSharingWeekDays(probe);
+ // A post-epoch year, no later than 2400 (implies four-digit):
+ QVERIFY(match >= 1970);
+ QVERIFY(match <= 2400);
+ // Either that's the year we started with or:
+ if (match != year) {
+ // Its last two digits can't be mistaken for month or day:
+ QVERIFY(match % 100 != probe.month());
+ QVERIFY(match % 100 != probe.day());
+ // If that wasn't in danger of happening, with year positive, they match lastTwo:
+ if (year > 0 && lastTwo > 31)
+ QCOMPARE(match % 100, lastTwo);
+ // Its first and last days of the year match those of year:
+ auto day = QGregorianCalendar::julianFromParts(match, 1, 1);
+ QVERIFY(day);
+ QCOMPARE(QGregorianCalendar::weekDayOfJulian(*day),
+ QGregorianCalendar::weekDayOfJulian(*first));
+ day = QGregorianCalendar::julianFromParts(match, 12, 31);
+ QVERIFY(day);
+ QCOMPARE(QGregorianCalendar::weekDayOfJulian(*day),
+ QGregorianCalendar::weekDayOfJulian(*last));
+ }
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QCalendar)
+#include "tst_qcalendar.moc"
diff --git a/tests/auto/corelib/tools/qdate/.gitignore b/tests/auto/corelib/time/qdate/.gitignore
index 70945d4a86..70945d4a86 100644
--- a/tests/auto/corelib/tools/qdate/.gitignore
+++ b/tests/auto/corelib/time/qdate/.gitignore
diff --git a/tests/auto/corelib/time/qdate/CMakeLists.txt b/tests/auto/corelib/time/qdate/CMakeLists.txt
new file mode 100644
index 0000000000..4d0f04a967
--- /dev/null
+++ b/tests/auto/corelib/time/qdate/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdate Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdate LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdate
+ SOURCES
+ tst_qdate.cpp
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_KEYWORDS
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/time/qdate/tst_qdate.cpp b/tests/auto/corelib/time/qdate/tst_qdate.cpp
new file mode 100644
index 0000000000..cacdad307f
--- /dev/null
+++ b/tests/auto/corelib/time/qdate/tst_qdate.cpp
@@ -0,0 +1,1759 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QDateTime>
+#include <QTest>
+
+#include <QLocale>
+#include <QMap>
+#include <QTimeZone>
+
+#include <private/qglobal_p.h> // for the icu feature test
+#include <private/qcomparisontesthelper_p.h>
+#include <private/qdatetime_p.h>
+#if !QT_CONFIG(timezone)
+# include <private/qtenvironmentvariables_p.h> // for qTzName()
+#endif
+
+using namespace QtPrivate::DateTimeConstants;
+using namespace Qt::StringLiterals;
+
+#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
+# define USING_WIN_TZ
+#endif
+
+class tst_QDate : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void isNull_data();
+ void isNull();
+ void isValid_data();
+ void isValid();
+ void julianDay_data();
+ void julianDay();
+ void dayOfWeek_data();
+ void dayOfWeek();
+ void dayOfYear_data();
+ void dayOfYear();
+ void daysInMonth_data();
+ void daysInMonth();
+ void daysInYear_data();
+ void daysInYear();
+ void getDate();
+ void weekNumber_invalid_data();
+ void weekNumber_invalid();
+ void weekNumber_data();
+ void weekNumber();
+ void startOfDay_endOfDay_data();
+ void startOfDay_endOfDay();
+ void startOfDay_endOfDay_fixed_data();
+ void startOfDay_endOfDay_fixed();
+ void startOfDay_endOfDay_bounds();
+ void julianDaysLimits();
+ void addDays_data();
+ void addDays();
+ void addMonths_data();
+ void addMonths();
+ void addYears_data();
+ void addYears();
+ void daysTo();
+ void orderingCompiles();
+ void operator_eq_eq_data();
+ void operator_eq_eq();
+ void ordering_data();
+ void ordering();
+ void ordering_chrono_types();
+ void operator_insert_extract_data();
+ void operator_insert_extract();
+#if QT_CONFIG(datestring)
+ void fromStringDateFormat_data();
+ void fromStringDateFormat();
+# if QT_CONFIG(datetimeparser)
+ void fromStringFormat_data();
+ void fromStringFormat();
+# endif
+ void toStringFormat_data();
+ void toStringFormat();
+ void toStringDateFormat_data();
+ void toStringDateFormat();
+#endif
+ void isLeapYear();
+ void yearsZeroToNinetyNine();
+ void printNegativeYear_data() const;
+ void printNegativeYear() const;
+#if QT_CONFIG(datestring)
+ void roundtripString() const;
+#endif
+ void roundtrip() const;
+ void qdebug() const;
+private:
+ QDate defDate() const { return QDate(1900, 1, 1); }
+
+ QDate epochDate() const {
+ using namespace QtPrivate::DateTimeConstants;
+ Q_ASSERT(JULIAN_DAY_FOR_EPOCH == QDate(1970, 1, 1).toJulianDay());
+ return QDate::fromJulianDay(JULIAN_DAY_FOR_EPOCH);
+ }
+
+ static constexpr qint64 minJd = JulianDayMin;
+ static constexpr qint64 maxJd = JulianDayMax;
+ QDate invalidDate() const { return QDate(); }
+};
+
+Q_DECLARE_METATYPE(Qt::DateFormat)
+
+void tst_QDate::isNull_data()
+{
+ QTest::addColumn<qint64>("jd");
+ QTest::addColumn<bool>("null");
+
+ QTest::newRow("qint64 min") << std::numeric_limits<qint64>::min() << true;
+ QTest::newRow("minJd - 1") << minJd - 1 << true;
+ QTest::newRow("minJd") << minJd << false;
+ QTest::newRow("minJd + 1") << minJd + 1 << false;
+ QTest::newRow("maxJd - 1") << maxJd - 1 << false;
+ QTest::newRow("maxJd") << maxJd << false;
+ QTest::newRow("maxJd + 1") << maxJd + 1 << true;
+ QTest::newRow("qint64 max") << std::numeric_limits<qint64>::max() << true;
+}
+
+void tst_QDate::isNull()
+{
+ QFETCH(qint64, jd);
+
+ QDate d = QDate::fromJulianDay(jd);
+ QTEST(d.isNull(), "null");
+}
+
+void tst_QDate::isValid_data()
+{
+ qint64 nullJd = std::numeric_limits<qint64>::min();
+
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<qint64>("jd");
+ QTest::addColumn<bool>("valid");
+
+ QTest::newRow("0-0-0") << 0 << 0 << 0 << nullJd << false;
+ QTest::newRow("month 0") << 2000 << 0 << 1 << nullJd << false;
+ QTest::newRow("day 0") << 2000 << 1 << 0 << nullJd << false;
+
+ QTest::newRow("month 13") << 2000 << 13 << 1 << nullJd << false;
+
+ // test leap years
+ QTest::newRow("non-leap") << 2006 << 2 << 29 << nullJd << false;
+ QTest::newRow("normal leap") << 2004 << 2 << 29 << qint64(2453065) << true;
+ QTest::newRow("century leap 1900") << 1900 << 2 << 29 << nullJd << false;
+ QTest::newRow("century leap 2100") << 2100 << 2 << 29 << nullJd << false;
+ QTest::newRow("400-years leap 2000") << 2000 << 2 << 29 << qint64(2451604) << true;
+ QTest::newRow("400-years leap 2400") << 2400 << 2 << 29 << qint64(2597701) << true;
+ QTest::newRow("400-years leap 1600") << 1600 << 2 << 29 << qint64(2305507) << true;
+ QTest::newRow("year 0") << 0 << 2 << 27 << nullJd << false;
+
+ // Test end of four-digit years:
+ QTest::newRow("late") << 9999 << 12 << 31 << qint64(5373484) << true;
+
+ // test the number of days in months:
+ QTest::newRow("jan") << 2000 << 1 << 31 << qint64(2451575) << true;
+ QTest::newRow("feb") << 2000 << 2 << 29 << qint64(2451604) << true; // same data as 400-years leap
+ QTest::newRow("mar") << 2000 << 3 << 31 << qint64(2451635) << true;
+ QTest::newRow("apr") << 2000 << 4 << 30 << qint64(2451665) << true;
+ QTest::newRow("may") << 2000 << 5 << 31 << qint64(2451696) << true;
+ QTest::newRow("jun") << 2000 << 6 << 30 << qint64(2451726) << true;
+ QTest::newRow("jul") << 2000 << 7 << 31 << qint64(2451757) << true;
+ QTest::newRow("aug") << 2000 << 8 << 31 << qint64(2451788) << true;
+ QTest::newRow("sep") << 2000 << 9 << 30 << qint64(2451818) << true;
+ QTest::newRow("oct") << 2000 << 10 << 31 << qint64(2451849) << true;
+ QTest::newRow("nov") << 2000 << 11 << 30 << qint64(2451879) << true;
+ QTest::newRow("dec") << 2000 << 12 << 31 << qint64(2451910) << true;
+
+ // and invalid dates:
+ QTest::newRow("ijan") << 2000 << 1 << 32 << nullJd << false;
+ QTest::newRow("ifeb") << 2000 << 2 << 30 << nullJd << false;
+ QTest::newRow("imar") << 2000 << 3 << 32 << nullJd << false;
+ QTest::newRow("iapr") << 2000 << 4 << 31 << nullJd << false;
+ QTest::newRow("imay") << 2000 << 5 << 32 << nullJd << false;
+ QTest::newRow("ijun") << 2000 << 6 << 31 << nullJd << false;
+ QTest::newRow("ijul") << 2000 << 7 << 32 << nullJd << false;
+ QTest::newRow("iaug") << 2000 << 8 << 32 << nullJd << false;
+ QTest::newRow("isep") << 2000 << 9 << 31 << nullJd << false;
+ QTest::newRow("ioct") << 2000 << 10 << 32 << nullJd << false;
+ QTest::newRow("inov") << 2000 << 11 << 31 << nullJd << false;
+ QTest::newRow("idec") << 2000 << 12 << 32 << nullJd << false;
+
+ // the beginning of the Julian Day calendar:
+ QTest::newRow("jd earliest formula") << -4800 << 1 << 1 << qint64( -31738) << true;
+ QTest::newRow("jd -1") << -4714 << 11 << 23 << qint64( -1) << true;
+ QTest::newRow("jd 0") << -4714 << 11 << 24 << qint64( 0) << true;
+ QTest::newRow("jd 1") << -4714 << 11 << 25 << qint64( 1) << true;
+ QTest::newRow("jd latest formula") << 1400000 << 12 << 31 << qint64(513060925) << true;
+}
+
+#if __cpp_lib_chrono >= 201907L
+// QDate has a bigger range than year_month_date. The tests use this bigger
+// range. However building a year_month_time with "out of range" data has
+// unspecified results, so don't do that. See [time.cal.year],
+// [time.cal.month], [time.cal.day]. Also, std::chrono::year has a year 0, so
+// take that into account.
+static std::optional<std::chrono::year_month_day> convertToStdYearMonthDay(int y, int m, int d)
+{
+ using namespace std::chrono;
+
+ if (y >= int((year::min)())
+ && y <= int((year::max)())
+ && m >= 0
+ && m <= 255
+ && d >= 0
+ && d <= 255)
+ {
+ if (y < 0)
+ ++y;
+ return std::make_optional(year(y) / m / d);
+ }
+
+ return std::nullopt;
+}
+#endif
+
+void tst_QDate::isValid()
+{
+ QFETCH(int, year);
+ QFETCH(int, month);
+ QFETCH(int, day);
+ QFETCH(qint64, jd);
+ QFETCH(bool, valid);
+
+ QCOMPARE(QDate::isValid(year, month, day), valid);
+
+ QDate d;
+ d.setDate(year, month, day);
+ QCOMPARE(d.isValid(), valid);
+ QCOMPARE(d.toJulianDay(), jd);
+
+ if (valid) {
+ QCOMPARE(d.year(), year);
+ QCOMPARE(d.month(), month);
+ QCOMPARE(d.day(), day);
+#if __cpp_lib_chrono >= 201907L
+ std::optional<std::chrono::year_month_day> ymd = convertToStdYearMonthDay(year, month, day);
+ if (ymd) {
+ QDate d = *ymd;
+ QCOMPARE(d.year(), year);
+ QCOMPARE(d.month(), month);
+ QCOMPARE(d.day(), day);
+
+ const std::chrono::sys_days qdateSysDays = d.toStdSysDays();
+ const std::chrono::sys_days ymdSysDays = *ymd;
+ QCOMPARE(qdateSysDays, ymdSysDays);
+ }
+#endif
+ } else {
+ QCOMPARE(d.year(), 0);
+ QCOMPARE(d.month(), 0);
+ QCOMPARE(d.day(), 0);
+ }
+}
+
+void tst_QDate::julianDay_data()
+{
+ isValid_data();
+}
+
+void tst_QDate::julianDay()
+{
+ QFETCH(int, year);
+ QFETCH(int, month);
+ QFETCH(int, day);
+ QFETCH(qint64, jd);
+
+ {
+ QDate d;
+ d.setDate(year, month, day);
+ QCOMPARE(d.toJulianDay(), jd);
+ }
+
+ if (jd != std::numeric_limits<qint64>::min()) {
+ QDate d = QDate::fromJulianDay(jd);
+ QCOMPARE(d.year(), year);
+ QCOMPARE(d.month(), month);
+ QCOMPARE(d.day(), day);
+ }
+}
+
+void tst_QDate::dayOfWeek_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<int>("dayOfWeek");
+
+ QTest::newRow("data0") << 0 << 0 << 0 << 0;
+ QTest::newRow("data1") << 2000 << 1 << 3 << 1;
+ QTest::newRow("data2") << 2000 << 1 << 4 << 2;
+ QTest::newRow("data3") << 2000 << 1 << 5 << 3;
+ QTest::newRow("data4") << 2000 << 1 << 6 << 4;
+ QTest::newRow("data5") << 2000 << 1 << 7 << 5;
+ QTest::newRow("data6") << 2000 << 1 << 8 << 6;
+ QTest::newRow("data7") << 2000 << 1 << 9 << 7;
+ QTest::newRow("data8") << -4800 << 1 << 1 << 1;
+ QTest::newRow("data9") << -4800 << 1 << 2 << 2;
+ QTest::newRow("data10") << -4800 << 1 << 3 << 3;
+ QTest::newRow("data11") << -4800 << 1 << 4 << 4;
+ QTest::newRow("data12") << -4800 << 1 << 5 << 5;
+ QTest::newRow("data13") << -4800 << 1 << 6 << 6;
+ QTest::newRow("data14") << -4800 << 1 << 7 << 7;
+ QTest::newRow("data15") << -4800 << 1 << 8 << 1;
+}
+
+void tst_QDate::dayOfWeek()
+{
+ QFETCH(int, year);
+ QFETCH(int, month);
+ QFETCH(int, day);
+ QFETCH(int, dayOfWeek);
+
+ QDate dt(year, month, day);
+ QCOMPARE(dt.dayOfWeek(), dayOfWeek);
+}
+
+void tst_QDate::dayOfYear_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<int>("dayOfYear");
+
+ QTest::newRow("data0") << 0 << 0 << 0 << 0;
+ QTest::newRow("data1") << 2000 << 1 << 1 << 1;
+ QTest::newRow("data2") << 2000 << 1 << 2 << 2;
+ QTest::newRow("data3") << 2000 << 1 << 3 << 3;
+ QTest::newRow("data4") << 2000 << 12 << 31 << 366;
+ QTest::newRow("data5") << 2001 << 12 << 31 << 365;
+ QTest::newRow("data6") << 1815 << 1 << 1 << 1;
+ QTest::newRow("data7") << 1815 << 12 << 31 << 365;
+ QTest::newRow("data8") << 1500 << 1 << 1 << 1;
+ QTest::newRow("data9") << 1500 << 12 << 31 << 365;
+ QTest::newRow("data10") << -1500 << 1 << 1 << 1;
+ QTest::newRow("data11") << -1500 << 12 << 31 << 365;
+ QTest::newRow("data12") << -4800 << 1 << 1 << 1;
+ QTest::newRow("data13") << -4800 << 12 << 31 << 365;
+}
+
+void tst_QDate::dayOfYear()
+{
+ QFETCH(int, year);
+ QFETCH(int, month);
+ QFETCH(int, day);
+ QFETCH(int, dayOfYear);
+
+ QDate dt(year, month, day);
+ QCOMPARE(dt.dayOfYear(), dayOfYear);
+}
+
+void tst_QDate::daysInMonth_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<int>("daysInMonth");
+
+ QTest::newRow("data0") << 0 << 0 << 0 << 0;
+ QTest::newRow("data1") << 2000 << 1 << 1 << 31;
+ QTest::newRow("data2") << 2000 << 2 << 1 << 29;
+ QTest::newRow("data3") << 2000 << 3 << 1 << 31;
+ QTest::newRow("data4") << 2000 << 4 << 1 << 30;
+ QTest::newRow("data5") << 2000 << 5 << 1 << 31;
+ QTest::newRow("data6") << 2000 << 6 << 1 << 30;
+ QTest::newRow("data7") << 2000 << 7 << 1 << 31;
+ QTest::newRow("data8") << 2000 << 8 << 1 << 31;
+ QTest::newRow("data9") << 2000 << 9 << 1 << 30;
+ QTest::newRow("data10") << 2000 << 10 << 1 << 31;
+ QTest::newRow("data11") << 2000 << 11 << 1 << 30;
+ QTest::newRow("data12") << 2000 << 12 << 1 << 31;
+ QTest::newRow("data13") << 2001 << 2 << 1 << 28;
+ QTest::newRow("data14") << 2000 << 0 << 1 << 0;
+}
+
+void tst_QDate::daysInMonth()
+{
+ QFETCH(int, year);
+ QFETCH(int, month);
+ QFETCH(int, day);
+ QFETCH(int, daysInMonth);
+
+ QDate dt(year, month, day);
+ QCOMPARE(dt.daysInMonth(), daysInMonth);
+}
+
+void tst_QDate::daysInYear_data()
+{
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<int>("expectedDaysInYear");
+
+ QTest::newRow("2000, 1, 1") << QDate(2000, 1, 1) << 366;
+ QTest::newRow("2001, 1, 1") << QDate(2001, 1, 1) << 365;
+ QTest::newRow("4, 1, 1") << QDate(4, 1, 1) << 366;
+ QTest::newRow("5, 1, 1") << QDate(5, 1, 1) << 365;
+ QTest::newRow("0, 0, 0") << QDate(0, 0, 0) << 0;
+}
+
+void tst_QDate::daysInYear()
+{
+ QFETCH(QDate, date);
+ QFETCH(int, expectedDaysInYear);
+
+ QCOMPARE(date.daysInYear(), expectedDaysInYear);
+}
+
+void tst_QDate::getDate()
+{
+ int y, m, d;
+ QDate dt(2000, 1, 1);
+ dt.getDate(&y, &m, &d);
+ QCOMPARE(y, 2000);
+ QCOMPARE(m, 1);
+ QCOMPARE(d, 1);
+ dt.setDate(0, 0, 0);
+ dt.getDate(&y, &m, &d);
+ QCOMPARE(y, 0);
+ QCOMPARE(m, 0);
+ QCOMPARE(d, 0);
+}
+
+void tst_QDate::weekNumber_data()
+{
+ QTest::addColumn<int>("expectedWeekNum");
+ QTest::addColumn<int>("expectedYearNum");
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+
+ enum { Thursday = 4 };
+ bool wasLastYearLong = false; // 1999 was not a long (53-week) year
+ bool isLongYear;
+
+ // full 400-year cycle for Jan 1, 4 and Dec 28, 31
+ for (int yr = 2000; yr < 2400; ++yr, wasLastYearLong = isLongYear) {
+ QByteArray yrstr = QByteArray::number(yr);
+ int wday = QDate(yr, 1, 1).dayOfWeek();
+
+ // the year is 53-week long if Jan 1 is Thursday or, if it's a leap year, a Wednesday
+ isLongYear = (wday == Thursday) || (QDate::isLeapYear(yr) && wday == Thursday - 1);
+
+ // Jan 4 is always on week 1
+ QTest::newRow(yrstr + "-01-04") << 1 << yr << yr << 1 << 4;
+
+ // Dec 28 is always on the last week
+ QTest::newRow(yrstr + "-12-28") << (52 + isLongYear) << yr << yr << 12 << 28;
+
+ // Jan 1 is on either on week 1 or on the last week of the previous year
+ QTest::newRow(yrstr + "-01-01")
+ << (wday <= Thursday ? 1 : 52 + wasLastYearLong)
+ << (wday <= Thursday ? yr : yr - 1)
+ << yr << 1 << 1;
+
+ // Dec 31 is either on the last week or week 1 of the next year
+ wday = QDate(yr, 12, 31).dayOfWeek();
+ QTest::newRow(yrstr + "-12-31")
+ << (wday >= Thursday ? 52 + isLongYear : 1)
+ << (wday >= Thursday ? yr : yr + 1)
+ << yr << 12 << 31;
+ }
+}
+
+void tst_QDate::weekNumber()
+{
+ int yearNumber;
+ QFETCH( int, year );
+ QFETCH( int, month );
+ QFETCH( int, day );
+ QFETCH( int, expectedWeekNum );
+ QFETCH( int, expectedYearNum );
+ QDate dt1( year, month, day );
+ QCOMPARE( dt1.weekNumber( &yearNumber ), expectedWeekNum );
+ QCOMPARE( yearNumber, expectedYearNum );
+}
+
+void tst_QDate::weekNumber_invalid_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+
+ //next we fill it with data
+ QTest::newRow( "data0" ) << 0 << 0 << 0;
+ QTest::newRow( "data1" ) << 2001 << 1 << 32;
+ QTest::newRow( "data2" ) << 1999 << 2 << 29;
+}
+
+void tst_QDate::weekNumber_invalid()
+{
+ QDate dt;
+ int yearNumber;
+ QCOMPARE( dt.weekNumber( &yearNumber ), 0 );
+}
+
+/* The MS backend tends to lack data for historical transitions. So some of the
+ transition-based tests will get wrong results, that we can't do anything
+ about, when using that backend. Rather than complicating the #if-ery more,
+ overtly record, in a flags column, which we need to ignore and merely make
+ the testing of these flags subject to #if-ery.
+
+ Android appears to lack at least one other.
+*/
+enum BackendKludge { IgnoreStart = 1, IgnoreEnd = 2, };
+Q_DECLARE_FLAGS(BackendKludges, BackendKludge)
+Q_DECLARE_OPERATORS_FOR_FLAGS(BackendKludges)
+
+void tst_QDate::startOfDay_endOfDay_data()
+{
+ QTest::addColumn<QDate>("date"); // Typically a spring-forward.
+ // A zone in which that date's start and end are worth checking:
+ QTest::addColumn<QTimeZone>("zone");
+ // The start and end times in that zone:
+ QTest::addColumn<QTime>("start");
+ QTest::addColumn<QTime>("end");
+ // Ignored for backends that don't need it:
+ QTest::addColumn<BackendKludges>("kludge");
+
+ const QTime early(0, 0), late(23, 59, 59, 999), invalid(QDateTime().time());
+ constexpr BackendKludges Clean = {};
+ constexpr BackendKludges IgnoreBoth = IgnoreStart | IgnoreEnd;
+#ifdef USING_WIN_TZ
+ constexpr BackendKludges MsNoStart = IgnoreStart;
+ constexpr BackendKludges MsNoBoth = IgnoreBoth;
+#else
+ constexpr BackendKludges MsNoStart = Clean;
+ constexpr BackendKludges MsNoBoth = Clean;
+ // And use IgnoreBoth directly for the one transition Android lacks.
+#endif
+ const QTimeZone UTC(QTimeZone::UTC);
+
+ using Bound = std::numeric_limits<qint64>;
+ const auto dateAtMillis = [UTC](qint64 millis) {
+ return QDateTime::fromMSecsSinceEpoch(millis, UTC).date();
+ };
+
+ // UTC and fixed offset are always available and predictable:
+ QTest::newRow("epoch") << epochDate() << UTC << early << late << Clean;
+
+ // First and last days in QDateTime's supported range:
+ QTest::newRow("earliest")
+ << dateAtMillis(Bound::min()) << UTC << invalid << late << Clean;
+ QTest::newRow("latest")
+ << dateAtMillis(Bound::max()) << UTC << early << invalid << Clean;
+
+ const struct {
+ const char *test;
+ const char *zone;
+ const QDate day;
+ const QTime start;
+ const QTime end;
+ const BackendKludges msOpt;
+ } transitions[] = {
+ // The western Mexico time-zones skipped the first hour of 1970.
+ { "BajaMexico", "America/Hermosillo", QDate(1970, 1, 1), QTime(1, 0), late, MsNoStart },
+
+ // Compare tst_QDateTime::fromStringDateFormat(ISO 24:00 in DST).
+ { "Brazil", "America/Sao_Paulo", QDate(2008, 10, 19), QTime(1, 0), late, Clean },
+
+ // Several southern zones within EET (but not the northern ones) spent
+ // part of the 1990s using midnight as spring transition.
+ { "Sofia", "Europe/Sofia", QDate(1994, 3, 27), QTime(1, 0), late, MsNoStart },
+
+ // Two Pacific zones skipped days to get on the west of the
+ // International Date Line; those days have neither start nor end.
+ { "Kiritimati", "Pacific/Kiritimati", QDate(1994, 12, 31), invalid, invalid, IgnoreBoth },
+ { "Samoa", "Pacific/Apia", QDate(2011, 12, 30), invalid, invalid, MsNoBoth },
+
+ // TODO: find other zones with transitions at/crossing midnight.
+ };
+ const QTimeZone local = QTimeZone::LocalTime;
+
+#if QT_CONFIG(timezone)
+ const QTimeZone sys = QTimeZone::systemTimeZone();
+ QVERIFY2(sys.isValid(), "Test depends on properly configured system");
+ for (const auto &tran : transitions) {
+ if (QTimeZone zone(tran.zone); zone.isValid()) {
+ QTest::newRow(tran.test)
+ << tran.day << zone << tran.start << tran.end << tran.msOpt;
+ if (zone == sys) {
+ QTest::addRow("Local=%s", tran.test)
+ << tran.day << local << tran.start << tran.end << tran.msOpt;
+ }
+ }
+ }
+#else
+ const auto isLocalZone = [](const char *zone) {
+ const QLatin1StringView name(zone);
+ for (int i = 0; i < 2; ++i) {
+ if (qTzName(i) == name)
+ return true;
+ }
+ return false;
+ };
+ for (const auto &tran : transitions) {
+ if (isLocalZone(tran.zone)) { // Might need a different name to match
+ QTest::addRow("Local=%s", tran.test)
+ << tran.day << local << tran.start << tran.end << tran.msOpt;
+ }
+ }
+#endif // timezone
+}
+
+void tst_QDate::startOfDay_endOfDay()
+{
+ QFETCH(const QDate, date);
+ QFETCH(const QTimeZone, zone);
+ QFETCH(const QTime, start);
+ QFETCH(const QTime, end);
+#if defined(USING_WIN_TZ) || defined(Q_OS_ANDROID) // Coping with backend limitations.
+ QFETCH(const BackendKludges, kludge);
+#define UNLESSKLUDGE(flag) if (!kludge.testFlag(flag))
+#else
+#define UNLESSKLUDGE(flag)
+#endif
+ QVERIFY(zone.isValid());
+
+ QDateTime front(date.startOfDay(zone)), back(date.endOfDay(zone));
+ if (end.isValid())
+ QCOMPARE(date.addDays(1).startOfDay(zone).addMSecs(-1), back);
+ if (start.isValid())
+ QCOMPARE(date.addDays(-1).endOfDay(zone).addMSecs(1), front);
+
+ if (start.isValid()) {
+ QVERIFY(front.isValid());
+ QCOMPARE(front.date(), date);
+ UNLESSKLUDGE(IgnoreStart) QCOMPARE(front.time(), start);
+ } else UNLESSKLUDGE(IgnoreStart) {
+ auto report = qScopeGuard([front]() { qDebug() << "Start of day:" << front; });
+ QVERIFY(!front.isValid());
+ report.dismiss();
+ }
+ if (end.isValid()) {
+ QVERIFY(back.isValid());
+ QCOMPARE(back.date(), date);
+ UNLESSKLUDGE(IgnoreEnd) QCOMPARE(back.time(), end);
+ } else UNLESSKLUDGE(IgnoreEnd) {
+ auto report = qScopeGuard([back]() { qDebug() << "End of day:" << back; });
+ QVERIFY(!back.isValid());
+ report.dismiss();
+ }
+#undef UNLESSKLUDGE
+}
+
+void tst_QDate::startOfDay_endOfDay_fixed_data()
+{
+ QTest::addColumn<QDate>("date");
+
+ const qint64 kilo(1000);
+ using Bounds = std::numeric_limits<qint64>;
+ const auto UTC = QTimeZone::UTC;
+ const QDateTime first(QDateTime::fromMSecsSinceEpoch(Bounds::min() + 1, UTC));
+ const QDateTime start32sign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(-0x80000000) * kilo, UTC));
+ const QDateTime end32sign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(0x80000000) * kilo, UTC));
+ const QDateTime end32unsign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(0x100000000) * kilo, UTC));
+ const QDateTime last(QDateTime::fromMSecsSinceEpoch(Bounds::max(), UTC));
+
+ QTest::newRow("epoch") << epochDate();
+ QTest::newRow("y2k-leap-day") << QDate(2000, 2, 29);
+ QTest::newRow("start-1900") << QDate(1900, 1, 1); // QTBUG-99747
+ // Just outside the start and end of 32-bit time_t:
+ QTest::newRow("pre-sign32") << QDate(start32sign.date().year(), 1, 1);
+ QTest::newRow("post-sign32") << QDate(end32sign.date().year(), 12, 31);
+ QTest::newRow("post-uint32") << QDate(end32unsign.date().year(), 12, 31);
+ // Just inside the start and end of QDateTime's range:
+ QTest::newRow("first-full") << first.date().addDays(1);
+ QTest::newRow("last-full") << last.date().addDays(-1);
+}
+
+void tst_QDate::startOfDay_endOfDay_fixed()
+{
+ const QTime early(0, 0), late(23, 59, 59, 999);
+ QFETCH(QDate, date);
+
+ QDateTime start(date.startOfDay(QTimeZone::UTC));
+ QDateTime end(date.endOfDay(QTimeZone::UTC));
+ QCOMPARE(start.date(), date);
+ QCOMPARE(end.date(), date);
+ QCOMPARE(start.time(), early);
+ QCOMPARE(end.time(), late);
+ QCOMPARE(date.addDays(1).startOfDay(QTimeZone::UTC).addMSecs(-1), end);
+ QCOMPARE(date.addDays(-1).endOfDay(QTimeZone::UTC).addMSecs(1), start);
+ for (int offset = -60 * 16; offset <= 60 * 16; offset += 65) {
+ const auto zone = QTimeZone::fromSecondsAheadOfUtc(offset);
+ start = date.startOfDay(zone);
+ end = date.endOfDay(zone);
+ QCOMPARE(start.date(), date);
+ QCOMPARE(end.date(), date);
+ QCOMPARE(start.time(), early);
+ QCOMPARE(end.time(), late);
+ QCOMPARE(date.addDays(1).startOfDay(zone).addMSecs(-1), end);
+ QCOMPARE(date.addDays(-1).endOfDay(zone).addMSecs(1), start);
+ }
+
+ // Minimal testing for LocalTime and TimeZone
+ QCOMPARE(date.startOfDay().date(), date);
+ QCOMPARE(date.endOfDay().date(), date);
+#if QT_CONFIG(timezone)
+ const QTimeZone cet("Europe/Oslo");
+ if (cet.isValid()) {
+ QCOMPARE(date.startOfDay(cet).date(), date);
+ QCOMPARE(date.endOfDay(cet).date(), date);
+ }
+#endif
+}
+
+void tst_QDate::startOfDay_endOfDay_bounds()
+{
+ // Check the days in which QDateTime's range starts and ends:
+ using Bounds = std::numeric_limits<qint64>;
+ const auto UTC = QTimeZone::UTC;
+ const QDateTime
+ first(QDateTime::fromMSecsSinceEpoch(Bounds::min(), UTC)),
+ last(QDateTime::fromMSecsSinceEpoch(Bounds::max(), UTC)),
+ epoch(QDateTime::fromMSecsSinceEpoch(0, UTC));
+ // First, check these *are* the start and end of QDateTime's range:
+ QVERIFY(first.isValid());
+ QVERIFY(last.isValid());
+ QVERIFY(first < epoch);
+ QVERIFY(last > epoch);
+ QVERIFY(!first.addMSecs(-1).isValid() || first.addMSecs(-1) > first);
+ QVERIFY(!last.addMSecs(1).isValid() || last.addMSecs(1) < last);
+
+ // Now test start/end methods with them:
+ QCOMPARE(first.date().endOfDay(UTC).time(), QTime(23, 59, 59, 999));
+ QCOMPARE(last.date().startOfDay(UTC).time(), QTime(0, 0));
+ QVERIFY(!first.date().startOfDay(UTC).isValid());
+ QVERIFY(!last.date().endOfDay(UTC).isValid());
+
+ // Test for QTBUG-100873, shouldn't assert:
+ const QDate qdteMin(1752, 9, 14); // Used by QDateTimeEdit
+ QCOMPARE(qdteMin.startOfDay(UTC).date(), qdteMin);
+ QCOMPARE(qdteMin.startOfDay().date(), qdteMin);
+#if QT_CONFIG(timezone)
+ const QTimeZone sys = QTimeZone::systemTimeZone();
+ QVERIFY2(sys.isValid(), "Test depends on properly configured system");
+ QCOMPARE(qdteMin.startOfDay(sys).date(), qdteMin);
+ QTimeZone berlin("Europe/Berlin");
+ if (berlin.isValid())
+ QCOMPARE(qdteMin.startOfDay(berlin).date(), qdteMin);
+#endif
+}
+
+void tst_QDate::julianDaysLimits()
+{
+ qint64 min = std::numeric_limits<qint64>::min();
+ qint64 max = std::numeric_limits<qint64>::max();
+
+ QDate maxDate = QDate::fromJulianDay(maxJd);
+ QDate minDate = QDate::fromJulianDay(minJd);
+ QDate zeroDate = QDate::fromJulianDay(0);
+
+ QDate dt = QDate::fromJulianDay(min);
+ QCOMPARE(dt.isValid(), false);
+ dt = QDate::fromJulianDay(minJd - 1);
+ QCOMPARE(dt.isValid(), false);
+ dt = QDate::fromJulianDay(minJd);
+ QCOMPARE(dt.isValid(), true);
+ dt = QDate::fromJulianDay(minJd + 1);
+ QCOMPARE(dt.isValid(), true);
+ dt = QDate::fromJulianDay(maxJd - 1);
+ QCOMPARE(dt.isValid(), true);
+ dt = QDate::fromJulianDay(maxJd);
+ QCOMPARE(dt.isValid(), true);
+ dt = QDate::fromJulianDay(maxJd + 1);
+ QCOMPARE(dt.isValid(), false);
+ dt = QDate::fromJulianDay(max);
+ QCOMPARE(dt.isValid(), false);
+
+ dt = maxDate.addDays(1);
+ QCOMPARE(dt.isValid(), false);
+ dt = maxDate.addDays(0);
+ QCOMPARE(dt.isValid(), true);
+ dt = maxDate.addDays(-1);
+ QCOMPARE(dt.isValid(), true);
+ dt = maxDate.addDays(max);
+ QCOMPARE(dt.isValid(), false);
+ dt = maxDate.addDays(min);
+ QCOMPARE(dt.isValid(), false);
+
+ dt = minDate.addDays(-1);
+ QCOMPARE(dt.isValid(), false);
+ dt = minDate.addDays(0);
+ QCOMPARE(dt.isValid(), true);
+ dt = minDate.addDays(1);
+ QCOMPARE(dt.isValid(), true);
+ dt = minDate.addDays(min);
+ QCOMPARE(dt.isValid(), false);
+ dt = minDate.addDays(max);
+ QCOMPARE(dt.isValid(), false);
+
+ dt = zeroDate.addDays(-1);
+ QCOMPARE(dt.isValid(), true);
+ dt = zeroDate.addDays(0);
+ QCOMPARE(dt.isValid(), true);
+ dt = zeroDate.addDays(1);
+ QCOMPARE(dt.isValid(), true);
+ dt = zeroDate.addDays(min);
+ QCOMPARE(dt.isValid(), false);
+ dt = zeroDate.addDays(max);
+ QCOMPARE(dt.isValid(), false);
+}
+
+void tst_QDate::addDays()
+{
+ QFETCH( int, year );
+ QFETCH( int, month );
+ QFETCH( int, day );
+ QFETCH( int, amountToAdd );
+ QFETCH( int, expectedYear );
+ QFETCH( int, expectedMonth );
+ QFETCH( int, expectedDay );
+
+ QDate dt( year, month, day );
+ QDate dt2 = dt.addDays( amountToAdd );
+
+ QCOMPARE( dt2.year(), expectedYear );
+ QCOMPARE( dt2.month(), expectedMonth );
+ QCOMPARE( dt2.day(), expectedDay );
+
+#if __cpp_lib_chrono >= 201907L
+ QDate dt3 = dt.addDuration( std::chrono::days( amountToAdd ) );
+
+ QCOMPARE( dt3.year(), expectedYear );
+ QCOMPARE( dt3.month(), expectedMonth );
+ QCOMPARE( dt3.day(), expectedDay );
+#endif
+}
+
+void tst_QDate::addDays_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<int>("amountToAdd");
+ QTest::addColumn<int>("expectedYear");
+ QTest::addColumn<int>("expectedMonth");
+ QTest::addColumn<int>("expectedDay");
+
+ QTest::newRow( "data0" ) << 2000 << 1 << 1 << 1 << 2000 << 1 << 2;
+ QTest::newRow( "data1" ) << 2000 << 1 << 31 << 1 << 2000 << 2 << 1;
+ QTest::newRow( "data2" ) << 2000 << 2 << 28 << 1 << 2000 << 2 << 29;
+ QTest::newRow( "data3" ) << 2000 << 2 << 29 << 1 << 2000 << 3 << 1;
+ QTest::newRow( "data4" ) << 2000 << 12 << 31 << 1 << 2001 << 1 << 1;
+ QTest::newRow( "data5" ) << 2001 << 2 << 28 << 1 << 2001 << 3 << 1;
+ QTest::newRow( "data6" ) << 2001 << 2 << 28 << 30 << 2001 << 3 << 30;
+ QTest::newRow( "data7" ) << 2001 << 3 << 30 << 5 << 2001 << 4 << 4;
+
+ QTest::newRow( "data8" ) << 2000 << 1 << 1 << -1 << 1999 << 12 << 31;
+ QTest::newRow( "data9" ) << 2000 << 1 << 31 << -1 << 2000 << 1 << 30;
+ QTest::newRow( "data10" ) << 2000 << 2 << 28 << -1 << 2000 << 2 << 27;
+ QTest::newRow( "data11" ) << 2001 << 2 << 28 << -30 << 2001 << 1 << 29;
+
+ QTest::newRow( "data12" ) << -4713 << 1 << 2 << -2 << -4714 << 12 << 31;
+ QTest::newRow( "data13" ) << -4713 << 1 << 2 << 2 << -4713 << 1 << 4;
+
+ QTest::newRow( "invalid" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0;
+}
+
+void tst_QDate::addMonths()
+{
+ QFETCH( int, year );
+ QFETCH( int, month );
+ QFETCH( int, day );
+ QFETCH( int, amountToAdd );
+ QFETCH( int, expectedYear );
+ QFETCH( int, expectedMonth );
+ QFETCH( int, expectedDay );
+
+ QDate dt( year, month, day );
+ dt = dt.addMonths( amountToAdd );
+
+ QCOMPARE( dt.year(), expectedYear );
+ QCOMPARE( dt.month(), expectedMonth );
+ QCOMPARE( dt.day(), expectedDay );
+}
+
+void tst_QDate::addMonths_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<int>("amountToAdd");
+ QTest::addColumn<int>("expectedYear");
+ QTest::addColumn<int>("expectedMonth");
+ QTest::addColumn<int>("expectedDay");
+
+ QTest::newRow( "data0" ) << 2000 << 1 << 1 << 1 << 2000 << 2 << 1;
+ QTest::newRow( "data1" ) << 2000 << 1 << 31 << 1 << 2000 << 2 << 29;
+ QTest::newRow( "data2" ) << 2000 << 2 << 28 << 1 << 2000 << 3 << 28;
+ QTest::newRow( "data3" ) << 2000 << 2 << 29 << 1 << 2000 << 3 << 29;
+ QTest::newRow( "data4" ) << 2000 << 12 << 31 << 1 << 2001 << 1 << 31;
+ QTest::newRow( "data5" ) << 2001 << 2 << 28 << 1 << 2001 << 3 << 28;
+ QTest::newRow( "data6" ) << 2001 << 2 << 28 << 12 << 2002 << 2 << 28;
+ QTest::newRow( "data7" ) << 2000 << 2 << 29 << 12 << 2001 << 2 << 28;
+ QTest::newRow( "data8" ) << 2000 << 10 << 15 << 4 << 2001 << 2 << 15;
+
+ QTest::newRow( "data9" ) << 2000 << 1 << 1 << -1 << 1999 << 12 << 1;
+ QTest::newRow( "data10" ) << 2000 << 1 << 31 << -1 << 1999 << 12 << 31;
+ QTest::newRow( "data11" ) << 2000 << 12 << 31 << -1 << 2000 << 11 << 30;
+ QTest::newRow( "data12" ) << 2001 << 2 << 28 << -12 << 2000 << 2 << 28;
+ QTest::newRow( "data13" ) << 2000 << 1 << 31 << -7 << 1999 << 6 << 30;
+ QTest::newRow( "data14" ) << 2000 << 2 << 29 << -12 << 1999 << 2 << 28;
+
+ // year sign change:
+ QTest::newRow( "data15" ) << 1 << 1 << 1 << -1 << -1 << 12 << 1;
+ QTest::newRow( "data16" ) << 1 << 1 << 1 << -12 << -1 << 1 << 1;
+ QTest::newRow( "data17" ) << -1 << 12 << 1 << 1 << 1 << 1 << 1;
+ QTest::newRow( "data18" ) << -1 << 1 << 1 << 12 << 1 << 1 << 1;
+ QTest::newRow( "data19" ) << -2 << 1 << 1 << 12 << -1 << 1 << 1;
+
+ QTest::newRow( "invalid" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0;
+}
+
+void tst_QDate::addYears()
+{
+ QFETCH( int, year );
+ QFETCH( int, month );
+ QFETCH( int, day );
+ QFETCH( int, amountToAdd );
+ QFETCH( int, expectedYear );
+ QFETCH( int, expectedMonth );
+ QFETCH( int, expectedDay );
+
+ QDate dt( year, month, day );
+ dt = dt.addYears( amountToAdd );
+
+ QCOMPARE( dt.year(), expectedYear );
+ QCOMPARE( dt.month(), expectedMonth );
+ QCOMPARE( dt.day(), expectedDay );
+}
+
+void tst_QDate::addYears_data()
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<int>("month");
+ QTest::addColumn<int>("day");
+ QTest::addColumn<int>("amountToAdd");
+ QTest::addColumn<int>("expectedYear");
+ QTest::addColumn<int>("expectedMonth");
+ QTest::addColumn<int>("expectedDay");
+
+ QTest::newRow( "data0" ) << 2000 << 1 << 1 << 1 << 2001 << 1 << 1;
+ QTest::newRow( "data1" ) << 2000 << 1 << 31 << 1 << 2001 << 1 << 31;
+ QTest::newRow( "data2" ) << 2000 << 2 << 28 << 1 << 2001 << 2 << 28;
+ QTest::newRow( "data3" ) << 2000 << 2 << 29 << 1 << 2001 << 2 << 28;
+ QTest::newRow( "data4" ) << 2000 << 12 << 31 << 1 << 2001 << 12 << 31;
+ QTest::newRow( "data5" ) << 2001 << 2 << 28 << 3 << 2004 << 2 << 28;
+ QTest::newRow( "data6" ) << 2000 << 2 << 29 << 4 << 2004 << 2 << 29;
+
+ QTest::newRow( "data7" ) << 2000 << 1 << 31 << -1 << 1999 << 1 << 31;
+ QTest::newRow( "data9" ) << 2000 << 2 << 29 << -1 << 1999 << 2 << 28;
+ QTest::newRow( "data10" ) << 2000 << 12 << 31 << -1 << 1999 << 12 << 31;
+ QTest::newRow( "data11" ) << 2001 << 2 << 28 << -3 << 1998 << 2 << 28;
+ QTest::newRow( "data12" ) << 2000 << 2 << 29 << -4 << 1996 << 2 << 29;
+ QTest::newRow( "data13" ) << 2000 << 2 << 29 << -5 << 1995 << 2 << 28;
+
+ QTest::newRow( "data14" ) << 2000 << 1 << 1 << -1999 << 1 << 1 << 1;
+ QTest::newRow( "data15" ) << 2000 << 1 << 1 << -2000 << -1 << 1 << 1;
+ QTest::newRow( "data16" ) << 2000 << 1 << 1 << -2001 << -2 << 1 << 1;
+ QTest::newRow( "data17" ) << -2000 << 1 << 1 << 1999 << -1 << 1 << 1;
+ QTest::newRow( "data18" ) << -2000 << 1 << 1 << 2000 << 1 << 1 << 1;
+ QTest::newRow( "data19" ) << -2000 << 1 << 1 << 2001 << 2 << 1 << 1;
+
+ QTest::newRow( "invalid" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0;
+}
+
+void tst_QDate::daysTo()
+{
+ QDate dt1(2000, 1, 1);
+ QDate dt2(2000, 1, 5);
+ QCOMPARE(dt1.daysTo(dt2), (qint64) 4);
+ QCOMPARE(dt2.daysTo(dt1), (qint64) -4);
+
+ dt1.setDate(0, 0, 0);
+ QCOMPARE(dt1.daysTo(dt2), (qint64) 0);
+ dt1.setDate(2000, 1, 1);
+ dt2.setDate(0, 0, 0);
+ QCOMPARE(dt1.daysTo(dt2), (qint64) 0);
+
+
+ QDate maxDate = QDate::fromJulianDay(maxJd);
+ QDate minDate = QDate::fromJulianDay(minJd);
+ QDate zeroDate = QDate::fromJulianDay(0);
+
+ QCOMPARE(maxDate.daysTo(minDate), minJd - maxJd);
+ QCOMPARE(minDate.daysTo(maxDate), maxJd - minJd);
+ QCOMPARE(maxDate.daysTo(zeroDate), -maxJd);
+ QCOMPARE(zeroDate.daysTo(maxDate), maxJd);
+ QCOMPARE(minDate.daysTo(zeroDate), -minJd);
+ QCOMPARE(zeroDate.daysTo(minDate), minJd);
+}
+
+void tst_QDate::orderingCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QDate>();
+#if __cpp_lib_chrono >= 201907L
+ QTestPrivate::testAllComparisonOperatorsCompile<QDate, std::chrono::year_month_day>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QDate, std::chrono::year_month_day_last>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QDate, std::chrono::year_month_weekday>();
+ QTestPrivate::testAllComparisonOperatorsCompile<QDate, std::chrono::year_month_weekday_last>();
+#endif
+}
+
+void tst_QDate::operator_eq_eq_data()
+{
+ QTest::addColumn<QDate>("d1");
+ QTest::addColumn<QDate>("d2");
+ QTest::addColumn<bool>("expectEqual");
+
+ QTest::newRow("data0") << QDate(2000,1,2) << QDate(2000,1,2) << true;
+ QTest::newRow("data1") << QDate(2001,12,5) << QDate(2001,12,5) << true;
+ QTest::newRow("data2") << QDate(2001,12,5) << QDate(2001,12,5) << true;
+ QTest::newRow("data3") << QDate(2001,12,5) << QDate(2002,12,5) << false;
+
+ QDate date1(1900, 1, 1);
+ QDate date2 = date1.addDays(1);
+ QDate date3 = date1.addDays(-1);
+ QDate date4 = date1.addMonths(1);
+ QDate date5 = date1.addMonths(-1);
+ QDate date6 = date1.addYears(1);
+ QDate date7 = date1.addYears(-1);
+
+ QTest::newRow("data4") << date2 << date3 << false;
+ QTest::newRow("data5") << date4 << date5 << false;
+ QTest::newRow("data6") << date6 << date7 << false;
+ QTest::newRow("data7") << date1 << date2 << false;
+ QTest::newRow("data8") << date1 << date3 << false;
+ QTest::newRow("data9") << date1 << date4 << false;
+ QTest::newRow("data10") << date1 << date5 << false;
+ QTest::newRow("data11") << date1 << date6 << false;
+ QTest::newRow("data12") << date1 << date7 << false;
+}
+
+void tst_QDate::operator_eq_eq()
+{
+ QFETCH(QDate, d1);
+ QFETCH(QDate, d2);
+ QFETCH(bool, expectEqual);
+
+ QT_TEST_EQUALITY_OPS(d1, d2, expectEqual);
+
+ if (expectEqual)
+ QVERIFY(qHash(d1) == qHash(d2));
+}
+
+void tst_QDate::ordering_data()
+{
+ QTest::addColumn<QDate>("left");
+ QTest::addColumn<QDate>("right");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrdering");
+
+ QTest::newRow("2000-1-2_vs_2000-1-2")
+ << QDate(2000, 1, 2) << QDate(2000, 1, 2) << Qt::strong_ordering::equivalent;
+ QTest::newRow("2001-12-4_vs_2001-12-5")
+ << QDate(2001, 12, 4) << QDate(2001, 12, 5) << Qt::strong_ordering::less;
+ QTest::newRow("2001-11-5_vs_2001-12-5")
+ << QDate(2001, 11, 5) << QDate(2001, 12, 5) << Qt::strong_ordering::less;
+ QTest::newRow("2000-12-5_vs_2001-12-5")
+ << QDate(2000, 12, 5) << QDate(2001, 12, 5) << Qt::strong_ordering::less;
+ QTest::newRow("2002-12-5_vs_2001-12-5")
+ << QDate(2002, 12, 5) << QDate(2001, 12, 5) << Qt::strong_ordering::greater;
+ QTest::newRow("2001-12-5_vs_2001-11-5")
+ << QDate(2001, 12, 5) << QDate(2001, 11, 5) << Qt::strong_ordering::greater;
+ QTest::newRow("2001-12-6_vs_2001-12-5")
+ << QDate(2001, 12, 6) << QDate(2001, 12, 5) << Qt::strong_ordering::greater;
+}
+
+void tst_QDate::ordering()
+{
+ QFETCH(QDate, left);
+ QFETCH(QDate, right);
+ QFETCH(Qt::strong_ordering, expectedOrdering);
+
+ QT_TEST_ALL_COMPARISON_OPS(left, right, expectedOrdering);
+}
+
+void tst_QDate::ordering_chrono_types()
+{
+#if __cpp_lib_chrono >= 201907L
+ using namespace std::chrono;
+ QDate friday(2001, 11, 30); // the 5th Friday of November 2001
+ // std::chrono::year_month_day
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_day(2001y, November, 29d),
+ Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_day(2001y, November, 30d),
+ Qt::strong_ordering::equivalent);
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_day(2001y, December, 1d),
+ Qt::strong_ordering::less);
+
+ // std::chrono::year_month_day_last
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_day_last(2001y, {October / last}),
+ Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_day_last(2001y, {November / last}),
+ Qt::strong_ordering::equivalent);
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_day_last(2001y, {December / last}),
+ Qt::strong_ordering::less);
+
+ // std::chrono::year_month_weekday
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_weekday(2001y, November, Thursday[5]),
+ Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_weekday(2001y, November, Friday[5]),
+ Qt::strong_ordering::equivalent);
+ QT_TEST_ALL_COMPARISON_OPS(friday, year_month_weekday(2001y, December, Saturday[1]),
+ Qt::strong_ordering::less);
+
+ // std::chrono::year_month_weekday_last
+ QDate thursday(2001, 11, 29); // the last Thursday of November 2001
+ QT_TEST_ALL_COMPARISON_OPS(thursday, year_month_weekday_last(2001y, November, Wednesday[last]),
+ Qt::strong_ordering::greater);
+ QT_TEST_ALL_COMPARISON_OPS(thursday, year_month_weekday_last(2001y, November, Thursday[last]),
+ Qt::strong_ordering::equivalent);
+ QT_TEST_ALL_COMPARISON_OPS(thursday, year_month_weekday_last(2001y, November, Friday[last]),
+ Qt::strong_ordering::less);
+#else
+ QSKIP("This test requires C++20-level <chrono> support enabled in the standard library.");
+#endif // __cpp_lib_chrono >= 201907L
+}
+
+Q_DECLARE_METATYPE(QDataStream::Version)
+
+void tst_QDate::operator_insert_extract_data()
+{
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<QDataStream::Version>("dataStreamVersion");
+
+ QMap<QDataStream::Version, QString> versionsToTest;
+ versionsToTest.insert(QDataStream::Qt_1_0, QString::fromLatin1("Qt_1_0"));
+ versionsToTest.insert(QDataStream::Qt_2_0, QString::fromLatin1("Qt_2_0"));
+ versionsToTest.insert(QDataStream::Qt_2_1, QString::fromLatin1("Qt_2_1"));
+ versionsToTest.insert(QDataStream::Qt_3_0, QString::fromLatin1("Qt_3_0"));
+ versionsToTest.insert(QDataStream::Qt_3_1, QString::fromLatin1("Qt_3_1"));
+ versionsToTest.insert(QDataStream::Qt_3_3, QString::fromLatin1("Qt_3_3"));
+ versionsToTest.insert(QDataStream::Qt_4_0, QString::fromLatin1("Qt_4_0"));
+ versionsToTest.insert(QDataStream::Qt_4_1, QString::fromLatin1("Qt_4_1"));
+ versionsToTest.insert(QDataStream::Qt_4_2, QString::fromLatin1("Qt_4_2"));
+ versionsToTest.insert(QDataStream::Qt_4_3, QString::fromLatin1("Qt_4_3"));
+ versionsToTest.insert(QDataStream::Qt_4_4, QString::fromLatin1("Qt_4_4"));
+ versionsToTest.insert(QDataStream::Qt_4_5, QString::fromLatin1("Qt_4_5"));
+ versionsToTest.insert(QDataStream::Qt_4_6, QString::fromLatin1("Qt_4_6"));
+ versionsToTest.insert(QDataStream::Qt_4_7, QString::fromLatin1("Qt_4_7"));
+ versionsToTest.insert(QDataStream::Qt_4_8, QString::fromLatin1("Qt_4_8"));
+ versionsToTest.insert(QDataStream::Qt_4_9, QString::fromLatin1("Qt_4_9"));
+ versionsToTest.insert(QDataStream::Qt_5_0, QString::fromLatin1("Qt_5_0"));
+
+ for (QMap<QDataStream::Version, QString>::ConstIterator it = versionsToTest.constBegin();
+ it != versionsToTest.constEnd(); ++it) {
+ const QString &version(it.value());
+ QTest::newRow(("(invalid) " + version).toLocal8Bit().constData()) << invalidDate() << it.key();
+ QTest::newRow(("(1, 1, 1) " + version).toLocal8Bit().constData()) << QDate(1, 1, 1) << it.key();
+ QTest::newRow(("(-1, 1, 1) " + version).toLocal8Bit().constData()) << QDate(-1, 1, 1) << it.key();
+ QTest::newRow(("(1995, 5, 20) " + version).toLocal8Bit().constData()) << QDate(1995, 5, 20) << it.key();
+
+ // Test minimums for quint32/qint64.
+ if (it.key() >= QDataStream::Qt_5_0)
+ QTest::newRow(("(-4714, 11, 24) " + version).toLocal8Bit().constData()) << QDate(-4714, 11, 24) << it.key();
+ else
+ QTest::newRow(("(-4713, 1, 2) " + version).toLocal8Bit().constData()) << QDate(-4713, 1, 2) << it.key();
+ }
+}
+
+void tst_QDate::operator_insert_extract()
+{
+ QFETCH(QDate, date);
+ QFETCH(QDataStream::Version, dataStreamVersion);
+
+ QByteArray byteArray;
+ QDataStream dataStream(&byteArray, QIODevice::ReadWrite);
+ dataStream.setVersion(dataStreamVersion);
+ dataStream << date;
+ dataStream.device()->reset();
+ QDate deserialised;
+ dataStream >> deserialised;
+ QCOMPARE(dataStream.status(), QDataStream::Ok);
+
+ QCOMPARE(deserialised, date);
+}
+
+#if QT_CONFIG(datetimeparser)
+void tst_QDate::fromStringDateFormat_data()
+{
+ QTest::addColumn<QString>("dateStr");
+ QTest::addColumn<Qt::DateFormat>("dateFormat");
+ QTest::addColumn<QDate>("expectedDate");
+
+ QTest::newRow("text0") << QString("Sat May 20 1995") << Qt::TextDate << QDate(1995, 5, 20);
+ QTest::newRow("text1") << QString("Tue Dec 17 2002") << Qt::TextDate << QDate(2002, 12, 17);
+ QTest::newRow("text2") << QDate(1999, 11, 14).toString(Qt::TextDate) << Qt::TextDate << QDate(1999, 11, 14);
+ QTest::newRow("text3") << QString("xxx Jan 1 0999") << Qt::TextDate << QDate(999, 1, 1);
+ QTest::newRow("text3b") << QString("xxx Jan 1 999") << Qt::TextDate << QDate(999, 1, 1);
+ QTest::newRow("text4") << QString("xxx Jan 1 12345") << Qt::TextDate << QDate(12345, 1, 1);
+ QTest::newRow("text5") << QString("xxx Jan 1 -0001") << Qt::TextDate << QDate(-1, 1, 1);
+ QTest::newRow("text6") << QString("xxx Jan 1 -4712") << Qt::TextDate << QDate(-4712, 1, 1);
+ QTest::newRow("text7") << QString("xxx Nov 25 -4713") << Qt::TextDate << QDate(-4713, 11, 25);
+ QTest::newRow("text, empty") << QString() << Qt::TextDate << QDate();
+ QTest::newRow("text, 3 part") << QString("part1 part2 part3") << Qt::TextDate << QDate();
+ QTest::newRow("text, invalid month name") << QString("Wed BabytownFrolics 8 2012") << Qt::TextDate << QDate();
+ QTest::newRow("text, invalid day") << QString("Wed May Wilhelm 2012") << Qt::TextDate << QDate();
+ QTest::newRow("text, invalid year") << QString("Wed May 8 Cats") << Qt::TextDate << QDate();
+
+ QTest::newRow("iso0") << QString("1995-05-20") << Qt::ISODate << QDate(1995, 5, 20);
+ QTest::newRow("iso1") << QString("2002-12-17") << Qt::ISODate << QDate(2002, 12, 17);
+ QTest::newRow("iso2") << QDate(1999, 11, 14).toString(Qt::ISODate) << Qt::ISODate << QDate(1999, 11, 14);
+ QTest::newRow("iso3") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1);
+ QTest::newRow("iso3b") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1);
+ QTest::newRow("iso4") << QString("2000101101") << Qt::ISODate << QDate();
+ QTest::newRow("iso5") << QString("2000/01/01") << Qt::ISODate << QDate(2000, 1, 1);
+ QTest::newRow("iso6") << QString("2000-01-01 blah") << Qt::ISODate << QDate(2000, 1, 1);
+ QTest::newRow("iso7") << QString("2000-01-011blah") << Qt::ISODate << QDate();
+ QTest::newRow("iso8") << QString("2000-01-01blah") << Qt::ISODate << QDate(2000, 1, 1);
+ QTest::newRow("iso9") << QString("-001-01-01") << Qt::ISODate << QDate();
+ QTest::newRow("iso10") << QString("99999-01-01") << Qt::ISODate << QDate();
+
+ // Test Qt::RFC2822Date format (RFC 2822).
+ QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
+ QTest::newRow("RFC 2822 after space")
+ << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
+ QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << epochDate();
+ QTest::newRow("RFC 2822 with day after space")
+ << QString::fromLatin1(" Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << epochDate();
+ // No timezone
+ QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
+ << Qt::RFC2822Date << epochDate();
+ // No time specified
+ QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
+ << Qt::RFC2822Date << QDate(2002, 11, 1);
+ QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
+ << Qt::RFC2822Date << QDate(2002, 11, 1);
+ QTest::newRow("RFC 2822 malformed time")
+ << QString::fromLatin1("01 Nov 2002 0:") << Qt::RFC2822Date << QDate();
+ // Test invalid month, day, year
+ QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character at front")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character both ends")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..") << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 2822 invalid character 2 at front")
+ << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100") << Qt::RFC2822Date << QDate();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 2822 (not invalid)")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QDate(2012, 1, 1);
+
+ // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive).
+ QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
+ QTest::newRow("RFC 850 and 1036 after space")
+ << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDate(1987, 2, 13);
+ // No timezone
+ QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
+ << Qt::RFC2822Date << epochDate();
+ // No time specified
+ QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
+ << Qt::RFC2822Date << QDate(2002, 11, 1);
+ // Test invalid characters.
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character at front")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character both ends")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..")
+ << Qt::RFC2822Date << QDate();
+ QTest::newRow("RFC 850 and 1036 invalid character 2 at front")
+ << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDate();
+ // Again, check the text in the "invalid character" tests isn't the source of invalidity:
+ QTest::newRow("RFC 850 and 1036 (not invalid)")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDate(2012, 1, 1);
+
+ QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDate();
+}
+
+void tst_QDate::fromStringDateFormat()
+{
+ QFETCH(QString, dateStr);
+ QFETCH(Qt::DateFormat, dateFormat);
+ QFETCH(QDate, expectedDate);
+
+ QCOMPARE(QDate::fromString(dateStr, dateFormat), expectedDate);
+}
+
+void tst_QDate::fromStringFormat_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<int>("baseYear");
+ QTest::addColumn<QDate>("expected");
+
+ QTest::newRow("empty") << u""_s << u""_s << 1900 << defDate();
+ QTest::newRow("space-as-empty") << u" "_s << u""_s << 1900 << invalidDate();
+ QTest::newRow("space") << u" "_s << u" "_s << 1900 << defDate();
+ QTest::newRow("mispunc") << u"-%$%#"_s << u"$*(#@"_s << 1900 << invalidDate();
+ QTest::newRow("literal-d") << u"d"_s << u"'d'"_s << 1900 << defDate();
+ QTest::newRow("greedy") << u"101010"_s << u"dMyy"_s << 1900 << QDate(1910, 10, 10);
+ QTest::newRow("greedy-miss") << u"101010b"_s << u"dMyy"_s << 1900 << invalidDate();
+ QTest::newRow("January") << u"January"_s << u"MMMM"_s << 1900 << defDate();
+ QTest::newRow("mistext") << u"ball"_s << u"balle"_s << 1900 << invalidDate();
+ QTest::newRow("text") << u"balleh"_s << u"balleh"_s << 1900 << defDate();
+ QTest::newRow("yearless:19") << u"10.01.1"_s << u"M.dd.d"_s << 1900 << QDate(1900, 10, 1);
+ QTest::newRow("yearless:20") << u"10.01.1"_s << u"M.dd.d"_s << 2000 << QDate(2000, 10, 1);
+ QTest::newRow("neg-month") << u"-1.01.1"_s << u"M.dd.d"_s << 1900 << invalidDate();
+ QTest::newRow("greedy-break") << u"11010"_s << u"dMMyy"_s << 1900 << invalidDate();
+ QTest::newRow("neg-day") << u"-2"_s << u"d"_s << 1900 << invalidDate();
+ QTest::newRow("Md:132") << u"132"_s << u"Md"_s << 1900 << invalidDate();
+ QTest::newRow("February") << u"February"_s << u"MMMM"_s << 1900 << QDate(1900, 2, 1);
+
+ QTest::newRow("mon-aug-8th")
+ << u"Mon August 8 2005"_s << u"ddd MMMM d yyyy"_s << 1900 << QDate(2005, 8, 8);
+ QTest::newRow("year-match-20000") << u"2000:00"_s << u"yyyy:yy"_s << 1900 << QDate(2000, 1, 1);
+ QTest::newRow("year-match-1999") << u"1999:99"_s << u"yyyy:yy"_s << 1900 << QDate(1999, 1, 1);
+ QTest::newRow("year-match-2099") << u"2099:99"_s << u"yyyy:yy"_s << 1900 << QDate(2099, 1, 1);
+ QTest::newRow("year-match-2001") << u"2001:01"_s << u"yyyy:yy"_s << 1900 << QDate(2001, 1, 1);
+ QTest::newRow("just-yy-1999") << u"99"_s << u"yy"_s << 1900 << QDate(1999, 1, 1);
+ QTest::newRow("just-yy-1901") << u"01"_s << u"yy"_s << 1900 << QDate(1901, 1, 1);
+ QTest::newRow("just-yy-2001") << u"01"_s << u"yy"_s << 1970 << QDate(2001, 1, 1);
+
+ QTest::newRow("Monday") << u"Monday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 1);
+ QTest::newRow("Tuesday") << u"Tuesday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 2);
+ QTest::newRow("Wednesday") << u"Wednesday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 3);
+ QTest::newRow("Thursday") << u"Thursday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 4);
+ QTest::newRow("Friday") << u"Friday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 5);
+ QTest::newRow("Saturday") << u"Saturday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 6);
+ QTest::newRow("Sunday") << u"Sunday"_s << u"dddd"_s << 1900 << QDate(1900, 1, 7);
+
+ QTest::newRow("Mon06") << u"Monday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 2);
+ QTest::newRow("Tues06") << u"Tuesday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 3);
+ QTest::newRow("Wed06") << u"Wednesday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 4);
+ QTest::newRow("Thu06") << u"Thursday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 5);
+ QTest::newRow("Fri06") << u"Friday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 6);
+ QTest::newRow("Sat06") << u"Saturday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 7);
+ QTest::newRow("Sun06") << u"Sunday 2006"_s << u"dddd yyyy"_s << 1900 << QDate(2006, 1, 1);
+ QTest::newRow("Tue07Mar")
+ << u"Tuesday 2007 March"_s << u"dddd yyyy MMMM"_s << 1900 << QDate(2007, 3, 6);
+
+ QTest::newRow("21May2006")
+ << u"21052006"_s << u"ddMMyyyy"_s << 1900 << QDate(2006, 5, 21);
+ QTest::newRow("21May06:19")
+ << u"210506"_s << u"ddMMyy"_s << 1900 << QDate(1906, 5, 21);
+ QTest::newRow("21May06:20")
+ << u"210506"_s << u"ddMMyy"_s << 1970 << QDate(2006, 5, 21);
+ QTest::newRow("21/May/2006")
+ << u"21/5/2006"_s << u"d/M/yyyy"_s << 1900 << QDate(2006, 5, 21);
+ QTest::newRow("21/5/06")
+ << u"21/5/06"_s << u"d/M/yy"_s << 1900 << QDate(1906, 5, 21);
+ QTest::newRow("21/5/06:19")
+ << u"21/5/06"_s << u"d/M/yy"_s << 1900 << QDate(1906, 5, 21);
+ QTest::newRow("21/5/06:20")
+ << u"21/5/06"_s << u"d/M/yy"_s << 1910 << QDate(2006, 5, 21);
+ QTest::newRow("2006May21")
+ << u"20060521"_s << u"yyyyMMdd"_s << 1900 << QDate(2006, 5, 21);
+ QTest::newRow("06May21:19")
+ << u"060521"_s << u"yyMMdd"_s << 1900 << QDate(1906, 5, 21);
+ QTest::newRow("06May21:20")
+ << u"060521"_s << u"yyMMdd"_s << 1907 << QDate(2006, 5, 21);
+ QTest::newRow("lateMarch")
+ << u"9999-03-06"_s << u"yyyy-MM-dd"_s << 1900 << QDate(9999, 3, 6);
+ QTest::newRow("late")
+ << u"9999-12-31"_s << u"yyyy-MM-dd"_s << 1900 << QDate(9999, 12, 31);
+
+ QTest::newRow("quoted-dd")
+ << u"21dd-05-2006"_s << u"dd'dd'-MM-yyyy"_s << 1900 << QDate(2006, 5, 21);
+ QTest::newRow("quoted-MM")
+ << u"21-MM05-2006"_s << u"dd-'MM'MM-yyyy"_s << 1900 << QDate(2006, 5, 21);
+ QTest::newRow("quotes-empty")
+ << u"21-'05-2006"_s << u"dd-MM-''yy"_s << 1900 << QDate(2006, 5, 21);
+
+ // Test unicode handling.
+ QTest::newRow("Unicode in format string")
+ << QString(u8"2020🤣09🤣21") << QString(u8"yyyy🤣MM🤣dd") << 1900 << QDate(2020, 9, 21);
+ QTest::newRow("Unicode-in-format-string-quoted-emoji")
+ << QString(u8"🤣🤣2020👍09🤣21") << QString(u8"'🤣🤣'yyyy👍MM🤣dd") << 1900
+ << QDate(2020, 9, 21);
+ QTest::newRow("Unicode-in-quoted-dd-format-string")
+ << QString(u8"🤣🤣2020👍09🤣21dd") << QString(u8"🤣🤣yyyy👍MM🤣dd'dd'") << 1900
+ << QDate(2020, 9, 21);
+ QTest::newRow("Unicode-in-all-formats-quoted-string")
+ << QString(u8"🤣🤣yyyy2020👍MM09🤣21dd") << QString(u8"🤣🤣'yyyy'yyyy👍'MM'MM🤣dd'dd'")
+ << 1900 << QDate(2020, 9, 21);
+
+ // QTBUG-84334
+ QTest::newRow("-ve year: front, nosep")
+ << u"-20060521"_s << u"yyyyMMdd"_s << 1900 << QDate(-2006, 5, 21);
+ QTest::newRow("-ve year: mid, nosep")
+ << u"05-200621"_s << u"MMyyyydd"_s << 1900 << QDate(-2006, 5, 21);
+ QTest::newRow("-ve year: back, nosep")
+ << u"0521-2006"_s << u"MMddyyyy"_s << 1900 << QDate(-2006, 5, 21);
+ // - as separator should not interfere with negative year numbers:
+ QTest::newRow("-ve year: front, dash")
+ << u"-2006-05-21"_s << u"yyyy-MM-dd"_s << 1900 << QDate(-2006, 5, 21);
+ QTest::newRow("positive year: front, dash")
+ << u"-2006-05-21"_s << u"-yyyy-MM-dd"_s << 1900 << QDate(2006, 5, 21);
+ QTest::newRow("-ve year: mid, dash")
+ << u"05--2006-21"_s << u"MM-yyyy-dd"_s << 1900 << QDate(-2006, 5, 21);
+ QTest::newRow("-ve year: back, dash")
+ << u"05-21--2006"_s << u"MM-dd-yyyy"_s << 1900 << QDate(-2006, 5, 21);
+ // negative three digit year numbers should be rejected:
+ QTest::newRow("-ve 3digit year: front")
+ << u"-206-05-21"_s << u"yyyy-MM-dd"_s << 1900 << QDate();
+ QTest::newRow("-ve 3digit year: mid")
+ << u"05--206-21"_s << u"MM-yyyy-dd"_s << 1900 << QDate();
+ QTest::newRow("-ve 3digit year: back")
+ << u"05-21--206"_s << u"MM-dd-yyyy"_s << 1900 << QDate();
+ // negative month numbers should be rejected:
+ QTest::newRow("-ve 2digit month: mid")
+ << u"2060--05-21"_s << u"yyyy-MM-dd"_s << 1900 << QDate();
+ QTest::newRow("-ve 2digit month: front")
+ << u"-05-2060-21"_s << u"MM-yyyy-dd"_s << 1900 << QDate();
+ QTest::newRow("-ve 2digit month: back")
+ << u"21-2060--05"_s << u"dd-yyyy-MM"_s << 1900 << QDate();
+ // negative single digit month numbers should be rejected:
+ QTest::newRow("-ve 1digit month: mid")
+ << u"2060--5-21"_s << u"yyyy-MM-dd"_s << 1900 << QDate();
+ QTest::newRow("-ve 1digit month: front")
+ << u"-5-2060-21"_s << u"MM-yyyy-dd"_s << 1900 << QDate();
+ QTest::newRow("-ve 1digit month: back")
+ << u"21-2060--5"_s << u"dd-yyyy-MM"_s << 1900 << QDate();
+ // negative day numbers should be rejected:
+ QTest::newRow("-ve 2digit day: front")
+ << u"-21-2060-05"_s << u"dd-yyyy-MM"_s << 1900 << QDate();
+ QTest::newRow("-ve 2digit day: mid")
+ << u"2060--21-05"_s << u"yyyy-dd-MM"_s << 1900 << QDate();
+ QTest::newRow("-ve 2digit day: back")
+ << u"05-2060--21"_s << u"MM-yyyy-dd"_s << 1900 << QDate();
+ // negative single digit day numbers should be rejected:
+ QTest::newRow("-ve 1digit day: front")
+ << u"-2-2060-05"_s << u"dd-yyyy-MM"_s << 1900 << QDate();
+ QTest::newRow("-ve 1digit day: mid")
+ << u"05--2-2060"_s << u"MM-dd-yyyy"_s << 1900 << QDate();
+ QTest::newRow("-ve 1digit day: back")
+ << u"2060-05--2"_s << u"yyyy-MM-dd"_s << 1900 << QDate();
+ // positive three digit year numbers should be rejected:
+ QTest::newRow("3digit year, front") << u"206-05-21"_s << u"yyyy-MM-dd"_s << 1900 << QDate();
+ QTest::newRow("3digit year, mid") << u"05-206-21"_s << u"MM-yyyy-dd"_s << 1900 << QDate();
+ QTest::newRow("3digit year, back") << u"05-21-206"_s << u"MM-dd-yyyy"_s << 1900 << QDate();
+ // positive five digit year numbers should be rejected:
+ QTest::newRow("5digit year, front")
+ << u"00206-05-21"_s << u"yyyy-MM-dd"_s << 1900 << QDate();
+ QTest::newRow("5digit year, mid")
+ << u"05-00206-21"_s << u"MM-yyyy-dd"_s << 1900 << QDate();
+ QTest::newRow("5digit year, back")
+ << u"05-21-00206"_s << u"MM-dd-yyyy"_s << 1900 << QDate();
+
+ QTest::newRow("dash separator, no year at end")
+ << u"05-21-"_s << u"dd-MM-yyyy"_s << 1900 << QDate();
+ QTest::newRow("slash separator, no year at end")
+ << u"11/05/"_s << u"d/MM/yyyy"_s << 1900 << QDate();
+
+ // QTBUG-84349
+ QTest::newRow("+ sign in year field") << u"+0200322"_s << u"yyyyMMdd"_s << 1900 << QDate();
+ QTest::newRow("+ sign in month field") << u"2020+322"_s << u"yyyyMMdd"_s << 1900 << QDate();
+ QTest::newRow("+ sign in day field") << u"202003+1"_s << u"yyyyMMdd"_s << 1900 << QDate();
+}
+
+
+void tst_QDate::fromStringFormat()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, format);
+ QFETCH(int, baseYear);
+ QFETCH(QDate, expected);
+
+ QDate dt = QDate::fromString(string, format, baseYear);
+ QEXPECT_FAIL("quotes-empty", "QTBUG-110669: doubled single-quotes in format mishandled",
+ Continue);
+ QCOMPARE(dt, expected);
+}
+#endif // datetimeparser
+
+#if QT_CONFIG(datestring)
+void tst_QDate::toStringFormat_data()
+{
+ QTest::addColumn<QDate>("t");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("str");
+
+ QTest::newRow( "data0" ) << QDate(1995,5,20) << QString("d-M-yy") << QString("20-5-95");
+ QTest::newRow( "data1" ) << QDate(2002,12,17) << QString("dd-MM-yyyy") << QString("17-12-2002");
+ QTest::newRow( "data2" ) << QDate(1995,5,20) << QString("M-yy") << QString("5-95");
+ QTest::newRow( "data3" ) << QDate(2002,12,17) << QString("dd") << QString("17");
+ QTest::newRow( "data4" ) << QDate() << QString("dd-mm-yyyy") << QString();
+}
+
+void tst_QDate::toStringFormat()
+{
+ QFETCH( QDate, t );
+ QFETCH( QString, format );
+ QFETCH( QString, str );
+
+ QCOMPARE( t.toString( format ), str );
+}
+
+void tst_QDate::toStringDateFormat_data()
+{
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<Qt::DateFormat>("format");
+ QTest::addColumn<QString>("expectedStr");
+
+ QTest::newRow("data0") << QDate(1,1,1) << Qt::ISODate << QString("0001-01-01");
+ QTest::newRow("data1") << QDate(11,1,1) << Qt::ISODate << QString("0011-01-01");
+ QTest::newRow("data2") << QDate(111,1,1) << Qt::ISODate << QString("0111-01-01");
+ QTest::newRow("data3") << QDate(1974,12,1) << Qt::ISODate << QString("1974-12-01");
+ QTest::newRow("year < 0") << QDate(-1,1,1) << Qt::ISODate << QString();
+ QTest::newRow("year > 9999") << QDate(10000, 1, 1) << Qt::ISODate << QString();
+ QTest::newRow("RFC2822Date") << QDate(1974,12,1) << Qt::RFC2822Date << QString("01 Dec 1974");
+ QTest::newRow("ISODateWithMs") << QDate(1974,12,1) << Qt::ISODateWithMs << QString("1974-12-01");
+}
+
+void tst_QDate::toStringDateFormat()
+{
+ QFETCH(QDate, date);
+ QFETCH(Qt::DateFormat, format);
+ QFETCH(QString, expectedStr);
+
+ QCOMPARE(date.toString(format), expectedStr);
+}
+#endif // datestring
+
+void tst_QDate::isLeapYear()
+{
+ QVERIFY(QDate::isLeapYear(-4801));
+ QVERIFY(!QDate::isLeapYear(-4800));
+ QVERIFY(QDate::isLeapYear(-4445));
+ QVERIFY(!QDate::isLeapYear(-4444));
+ QVERIFY(!QDate::isLeapYear(-6));
+ QVERIFY(QDate::isLeapYear(-5));
+ QVERIFY(!QDate::isLeapYear(-4));
+ QVERIFY(!QDate::isLeapYear(-3));
+ QVERIFY(!QDate::isLeapYear(-2));
+ QVERIFY(QDate::isLeapYear(-1));
+ QVERIFY(!QDate::isLeapYear(0)); // Doesn't exist
+ QVERIFY(!QDate::isLeapYear(1));
+ QVERIFY(!QDate::isLeapYear(2));
+ QVERIFY(!QDate::isLeapYear(3));
+ QVERIFY(QDate::isLeapYear(4));
+ QVERIFY(!QDate::isLeapYear(7));
+ QVERIFY(QDate::isLeapYear(8));
+ QVERIFY(!QDate::isLeapYear(100));
+ QVERIFY(QDate::isLeapYear(400));
+ QVERIFY(!QDate::isLeapYear(700));
+ QVERIFY(!QDate::isLeapYear(1500));
+ QVERIFY(QDate::isLeapYear(1600));
+ QVERIFY(!QDate::isLeapYear(1700));
+ QVERIFY(!QDate::isLeapYear(1800));
+ QVERIFY(!QDate::isLeapYear(1900));
+ QVERIFY(QDate::isLeapYear(2000));
+ QVERIFY(!QDate::isLeapYear(2100));
+ QVERIFY(!QDate::isLeapYear(2200));
+ QVERIFY(!QDate::isLeapYear(2300));
+ QVERIFY(QDate::isLeapYear(2400));
+ QVERIFY(!QDate::isLeapYear(2500));
+ QVERIFY(!QDate::isLeapYear(2600));
+ QVERIFY(!QDate::isLeapYear(2700));
+ QVERIFY(QDate::isLeapYear(2800));
+
+ for (int i = -4713; i <= 10000; ++i) {
+ if (i == 0)
+ continue;
+ QVERIFY(!QDate(i, 2, 29).isValid() == !QDate::isLeapYear(i));
+ }
+}
+
+void tst_QDate::yearsZeroToNinetyNine()
+{
+ {
+ QDate dt(-1, 2, 3);
+ QCOMPARE(dt.year(), -1);
+ QCOMPARE(dt.month(), 2);
+ QCOMPARE(dt.day(), 3);
+ }
+
+ {
+ QDate dt(1, 2, 3);
+ QCOMPARE(dt.year(), 1);
+ QCOMPARE(dt.month(), 2);
+ QCOMPARE(dt.day(), 3);
+ }
+
+ {
+ QDate dt(99, 2, 3);
+ QCOMPARE(dt.year(), 99);
+ QCOMPARE(dt.month(), 2);
+ QCOMPARE(dt.day(), 3);
+ }
+
+ QVERIFY(!QDate::isValid(0, 2, 3));
+ QVERIFY(QDate::isValid(1, 2, 3));
+ QVERIFY(QDate::isValid(-1, 2, 3));
+
+ {
+ QDate dt;
+ dt.setDate(1, 2, 3);
+ QCOMPARE(dt.year(), 1);
+ QCOMPARE(dt.month(), 2);
+ QCOMPARE(dt.day(), 3);
+
+ dt.setDate(0, 2, 3);
+ QVERIFY(!dt.isValid());
+ }
+}
+
+void tst_QDate::printNegativeYear_data() const
+{
+ QTest::addColumn<int>("year");
+ QTest::addColumn<QString>("expect");
+ QTest::newRow("millennium") << -1000 << QStringLiteral("-1000");
+ QTest::newRow("century") << -500 << QStringLiteral("-0500");
+ QTest::newRow("decade") << -20 << QStringLiteral("-0020");
+ QTest::newRow("year") << -7 << QStringLiteral("-0007");
+}
+
+void tst_QDate::printNegativeYear() const
+{
+ QFETCH(int, year);
+ QFETCH(QString, expect);
+ expect.replace(QLatin1Char('-'), QLocale().negativeSign());
+
+ QDate date(year, 3, 4);
+ QVERIFY(date.isValid());
+ QCOMPARE(date.year(), year);
+ QCOMPARE(date.toString(QLatin1String("yyyy")), expect);
+}
+
+#if QT_CONFIG(datestring)
+void tst_QDate::roundtripString() const
+{
+ /* This code path should not result in warnings. */
+ const QDate date(QDate::currentDate());
+ QCOMPARE(date.fromString(date.toString(Qt::TextDate), Qt::TextDate), date);
+
+ const QDateTime now(QDateTime::currentDateTime());
+ // TextDate discards milliseconds, so clip to whole second:
+ const QDateTime when = now.addMSecs(-now.time().msec());
+ QCOMPARE(when.fromString(when.toString(Qt::TextDate), Qt::TextDate), when);
+}
+#endif
+
+void tst_QDate::roundtrip() const
+{
+ // Test round trip, this exercises setDate(), isValid(), isLeapYear(),
+ // year(), month(), day(), julianDayFromDate(), and getDateFromJulianDay()
+ // to ensure they are internally consistent (but doesn't guarantee correct)
+
+ // Test Julian round trip around JD 0 and the c++ integer division rounding
+ // problem point (eg. negative numbers) in the conversion functions.
+ QDate testDate;
+ QDate loopDate = QDate::fromJulianDay(-50001); // 1 Jan 4850 BC
+ while (loopDate.toJulianDay() <= 5150) { // 31 Dec 4700 BC
+ testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
+ QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
+ loopDate = loopDate.addDays(1);
+ }
+
+ // Test Julian round trip in both BC and AD
+ loopDate = QDate::fromJulianDay(1684901); // 1 Jan 100 BC
+ while (loopDate.toJulianDay() <= 1757949) { // 31 Dec 100 AD
+ testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
+ QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
+ loopDate = loopDate.addDays(1);
+ }
+
+ // Test Gregorian round trip during current useful period
+ loopDate = QDate::fromJulianDay(2378497); // 1 Jan 1900 AD
+ while (loopDate.toJulianDay() <= 2488433) { // 31 Dec 2100 AD
+ testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
+ QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
+ loopDate = loopDate.addDays(1);
+ }
+
+ // Test Gregorian round trip at top end of widget/format range
+ loopDate = QDate::fromJulianDay(5336961); // 1 Jan 9900 AD
+ while (loopDate.toJulianDay() <= 5373484) { // 31 Dec 9999 AD
+ testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
+ QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
+ loopDate = loopDate.addDays(1);
+ }
+
+ // Test Gregorian round trip at top end of conversion range
+ loopDate = QDate::fromJulianDay(maxJd);
+ while (loopDate.toJulianDay() >= maxJd - 146397) {
+ testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
+ QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
+ loopDate = loopDate.addDays(-1);
+ }
+
+ // Test Gregorian round trip at low end of conversion range
+ loopDate = QDate::fromJulianDay(minJd);
+ while (loopDate.toJulianDay() <= minJd + 146397) {
+ testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
+ QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
+ loopDate = loopDate.addDays(1);
+ }
+
+#if __cpp_lib_chrono >= 201907L
+ // Test roundtrip for from/to std::chrono conversions.
+ // Compile-time test, to verify it's all constexpr.
+ using namespace std::chrono;
+ {
+ constexpr sys_days expected{days{minJd}};
+ constexpr sys_days actual{QDate::fromStdSysDays(expected).toStdSysDays()};
+ static_assert(actual == expected);
+ }
+ {
+ // constexpr year_month_day expected{sys_days{days{maxJd}}}; // Overflow at least on MSVC
+ constexpr year_month_day expected{1970y, January, 1d};
+ constexpr sys_days actual{QDate(expected).toStdSysDays()};
+ static_assert(actual == sys_days(expected));
+ }
+ {
+ constexpr year_month_day_last expected{2001y, {October / last}};
+ constexpr sys_days actual{QDate(expected).toStdSysDays()};
+ static_assert(actual == sys_days(expected));
+ }
+ {
+ constexpr year_month_weekday expected{2001y, December, Saturday[1]};
+ constexpr sys_days actual{QDate(expected).toStdSysDays()};
+ static_assert(actual == sys_days(expected));
+ }
+ {
+ constexpr year_month_weekday_last expected{2001y, November, Friday[last]};
+ constexpr sys_days actual{QDate(expected).toStdSysDays()};
+ static_assert(actual == sys_days(expected));
+ }
+#endif // __cpp_lib_chrono >= 201907L
+}
+
+void tst_QDate::qdebug() const
+{
+ QTest::ignoreMessage(QtDebugMsg, "QDate(Invalid)");
+ qDebug() << QDate();
+ QTest::ignoreMessage(QtDebugMsg, "QDate(\"1983-08-07\")");
+ qDebug() << QDate(1983, 8, 7);
+}
+
+QTEST_APPLESS_MAIN(tst_QDate)
+#include "tst_qdate.moc"
diff --git a/tests/auto/corelib/tools/qdatetime/.gitignore b/tests/auto/corelib/time/qdatetime/.gitignore
index 7784f3a3eb..7784f3a3eb 100644
--- a/tests/auto/corelib/tools/qdatetime/.gitignore
+++ b/tests/auto/corelib/time/qdatetime/.gitignore
diff --git a/tests/auto/corelib/time/qdatetime/CMakeLists.txt b/tests/auto/corelib/time/qdatetime/CMakeLists.txt
new file mode 100644
index 0000000000..499369c131
--- /dev/null
+++ b/tests/auto/corelib/time/qdatetime/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdatetime Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatetime LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdatetime
+ SOURCES
+ tst_qdatetime.cpp
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_KEYWORDS
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qdatetime CONDITION APPLE
+ SOURCES
+ tst_qdatetime_mac.mm
+ LIBRARIES
+ ${FWFoundation}
+)
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
new file mode 100644
index 0000000000..f9c6afc795
--- /dev/null
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -0,0 +1,4841 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QDateTime>
+#include <QTest>
+
+#include <QTimeZone>
+#include <private/qdatetime_p.h>
+#include <private/qtenvironmentvariables_p.h> // for qTzSet(), qTzName()
+#include <private/qcomparisontesthelper_p.h>
+
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+# if !QT_CONFIG(icu)
+// The native MS back-end for time-zones lacks info about historic transitions:
+# define INADEQUATE_TZ_DATA
+# endif
+#endif
+#ifdef Q_OS_ANDROID // Also seems to lack full-day zone transitions:
+# define INADEQUATE_TZ_DATA
+#endif
+
+using namespace Qt::StringLiterals;
+
+class tst_QDateTime : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QDateTime();
+
+public Q_SLOTS:
+ void initTestCase();
+private Q_SLOTS:
+ void ctor();
+ void operator_eq();
+ void moveSemantics();
+ void isNull();
+ void isValid();
+ void date();
+ void time();
+#if QT_DEPRECATED_SINCE(6, 9)
+ void timeSpec();
+#endif
+ void toSecsSinceEpoch_data();
+ void toSecsSinceEpoch();
+ void daylightSavingsTimeChange_data();
+ void daylightSavingsTimeChange();
+ void springForward_data();
+ void springForward();
+ void setDate();
+ void setTime_data();
+ void setTime();
+ void setTimeZone_data();
+ void setTimeZone();
+#if QT_DEPRECATED_SINCE(6, 9)
+ void setTimeSpec_data();
+ void setTimeSpec();
+#endif
+ void setSecsSinceEpoch();
+ void setMSecsSinceEpoch_data();
+ void setMSecsSinceEpoch();
+ void fromSecsSinceEpoch();
+ void fromMSecsSinceEpoch_data() { setMSecsSinceEpoch_data(); }
+ void fromMSecsSinceEpoch();
+#if QT_CONFIG(datestring)
+ void toString_isoDate_data();
+ void toString_isoDate();
+ void toString_isoDate_extra();
+ void toString_textDate_data();
+ void toString_textDate();
+ void toString_textDate_extra();
+ void toString_rfcDate_data();
+ void toString_rfcDate();
+ void toString_enumformat();
+ void toString_strformat();
+#endif
+ void addDays();
+ void addInvalid();
+ void addMonths();
+ void addMonths_data();
+ void addYears();
+ void addYears_data();
+ void addSecs_data();
+ void addSecs();
+ void addMSecs_data();
+ void addMSecs();
+#if QT_DEPRECATED_SINCE(6, 9)
+ void toTimeSpec_data();
+ void toTimeSpec();
+ void toLocalTime_data() { toTimeSpec_data(); }
+ void toLocalTime();
+ void toUTC_data() { toTimeSpec_data(); }
+ void toUTC();
+ void toUTC_extra();
+#endif
+ void daysTo();
+ void secsTo_data();
+ void secsTo();
+ void msecsTo_data() { addMSecs_data(); }
+ void msecsTo();
+ void orderingCompiles();
+ void operator_eqeq_data();
+ void operator_eqeq();
+ void ordering_data();
+ void ordering();
+ void operator_insert_extract_data();
+ void operator_insert_extract();
+ void currentDateTime();
+ void currentDateTimeUtc();
+ void currentDateTimeUtc2();
+#if QT_CONFIG(datestring)
+ void fromStringDateFormat_data();
+ void fromStringDateFormat();
+# if QT_CONFIG(datetimeparser)
+ void fromStringStringFormat_data();
+ void fromStringStringFormat();
+ void fromStringStringFormat_localTimeZone_data();
+ void fromStringStringFormat_localTimeZone();
+# endif
+#endif
+
+ void offsetFromUtc();
+#if QT_DEPRECATED_SINCE(6, 9)
+ void setOffsetFromUtc();
+ void toOffsetFromUtc();
+#endif
+
+ void zoneAtTime_data();
+ void zoneAtTime();
+ void timeZoneAbbreviation();
+
+ void getDate();
+
+ void fewDigitsInYear() const;
+ void printNegativeYear() const;
+#if QT_CONFIG(datetimeparser)
+ void roundtripTextDate() const;
+#endif
+ void utcOffsetLessThan() const;
+
+ void isDaylightTime() const;
+ void daylightTransitions() const;
+ void timeZones() const;
+ void systemTimeZoneChange_data() const;
+ void systemTimeZoneChange() const;
+
+ void invalid_data() const;
+ void invalid() const;
+ void range() const;
+
+ void macTypes();
+
+ void stdCompatibilitySysTime_data();
+ void stdCompatibilitySysTime();
+ void stdCompatibilityLocalTime_data();
+ void stdCompatibilityLocalTime();
+#if QT_CONFIG(timezone)
+ void stdCompatibilityZonedTime_data();
+ void stdCompatibilityZonedTime();
+#endif
+
+private:
+ /*
+ Various zones close to UTC (notably Iceland, the WET zones and several in
+ West Africa) or nominally assigned to it historically (north Canada, the
+ Antarctic) and those that have crossed the international date-line (by
+ skipping or repeating a day) don't have a consistent answer to "which side
+ of UTC is it ?" So the various LocalTimeType members may be different.
+ */
+ enum LocalTimeType { LocalTimeIsUtc = 0, LocalTimeAheadOfUtc = 1, LocalTimeBehindUtc = -1};
+ const LocalTimeType solarMeanType, epochTimeType, futureTimeType, distantTimeType;
+ static constexpr auto UTC = QTimeZone::UTC;
+ static constexpr qint64 epochJd = Q_INT64_C(2440588);
+ int preZoneFix;
+ bool zoneIsCET;
+
+ static LocalTimeType timeTypeFor(qint64 jand, qint64 juld)
+ {
+ constexpr uint day = 24 * 3600; // in seconds
+ QDateTime jan = QDateTime::fromSecsSinceEpoch(jand * day);
+ QDateTime jul = QDateTime::fromSecsSinceEpoch(juld * day);
+ if (jan.date().toJulianDay() < jand + epochJd || jul.date().toJulianDay() < juld + epochJd)
+ return LocalTimeBehindUtc;
+ if (jan.date().toJulianDay() > jand + epochJd || jul.date().toJulianDay() > juld + epochJd
+ || jan.time().hour() > 0 || jul.time().hour() > 0) {
+ return LocalTimeAheadOfUtc;
+ }
+ return LocalTimeIsUtc;
+ }
+
+ class TimeZoneRollback
+ {
+ const QByteArray prior;
+ public:
+ // Save the previous timezone so we can restore it afterwards, otherwise
+ // later tests may break:
+ explicit TimeZoneRollback(const QByteArray &zone) : prior(qgetenv("TZ"))
+ { reset(zone); }
+ void reset(const QByteArray &zone)
+ {
+ qputenv("TZ", zone);
+ qTzSet();
+ }
+ ~TimeZoneRollback()
+ {
+ if (prior.isNull())
+ qunsetenv("TZ");
+ else
+ qputenv("TZ", prior);
+ qTzSet();
+ }
+ };
+};
+
+Q_DECLARE_METATYPE(Qt::TimeSpec)
+Q_DECLARE_METATYPE(Qt::DateFormat)
+
+tst_QDateTime::tst_QDateTime() :
+ // UTC starts of January and July in the commented years:
+ solarMeanType(timeTypeFor(-62091, -61910)), // 1800
+ epochTimeType(timeTypeFor(0, 181)), // 1970
+ // Use stable future, to which current rule is extrapolated, as surrogate for variable current:
+ futureTimeType(timeTypeFor(24837, 25018)), // 2038
+ // The glibc functions only handle DST as far as a 32-bit signed day-count
+ // from some date in 1970 reaches; the future extreme of that is in the
+ // second half of 5'881'580 CE. Beyond 5'881'581 CE it treats all zones as
+ // being in their January state, regardless of time of year. So use data for
+ // this later year for tests of QDateTime's upper bound.
+ distantTimeType(timeTypeFor(0x800000adLL, 0x80000162LL))
+{
+ /*
+ Due to some jurisdictions changing their zones and rules, it's possible
+ for a non-CET zone to accidentally match CET at a few tested moments but
+ be different a few years later or earlier. This would lead to tests
+ failing if run in the partially-aliasing zone (e.g. Algeria, Lybia). So
+ test thoroughly; ideally at every mid-winter or mid-summer in whose
+ half-year any test below assumes zoneIsCET means what it says. (Tests at
+ or near a DST transition implicate both of the half-years that meet
+ there.) Years outside the +ve half of 32-bit time_t's range, however,
+ might not be properly handled by our work-arounds for the MS backend and
+ 32-bit time_t; so don't probe them here.
+ */
+ zoneIsCET = (QDateTime(QDate(2038, 1, 19), QTime(4, 14, 7)).toSecsSinceEpoch() == 0x7fffffff
+ // Entries a year apart robustly differ by multiples of day.
+ && QDate(2015, 7, 1).startOfDay().toSecsSinceEpoch() == 1435701600
+ && QDate(2015, 1, 1).startOfDay().toSecsSinceEpoch() == 1420066800
+ && QDate(2013, 7, 1).startOfDay().toSecsSinceEpoch() == 1372629600
+ && QDate(2013, 1, 1).startOfDay().toSecsSinceEpoch() == 1356994800
+ && QDate(2012, 7, 1).startOfDay().toSecsSinceEpoch() == 1341093600
+ && QDate(2012, 1, 1).startOfDay().toSecsSinceEpoch() == 1325372400
+ && QDate(2008, 7, 1).startOfDay().toSecsSinceEpoch() == 1214863200
+ && QDate(2004, 1, 1).startOfDay().toSecsSinceEpoch() == 1072911600
+ && QDate(2000, 1, 1).startOfDay().toSecsSinceEpoch() == 946681200
+ && QDate(1990, 7, 1).startOfDay().toSecsSinceEpoch() == 646783200
+ && QDate(1990, 1, 1).startOfDay().toSecsSinceEpoch() == 631148400
+ && QDate(1979, 1, 1).startOfDay().toSecsSinceEpoch() == 283993200
+ && QDateTime(QDate(1970, 1, 1), QTime(1, 0)).toSecsSinceEpoch() == 0);
+ // Use .toMSecsSinceEpoch() if you really need to test anything earlier.
+
+ /*
+ Zones which currently appear to be CET may have distinct offsets before
+ the advent of time-zones. The date used here is the eve of the birth of
+ Dr. William Hyde Wollaston, who first proposed a uniform national time,
+ instead of local mean time:
+ */
+ preZoneFix = zoneIsCET ? QDate(1766, 8, 5).startOfDay().offsetFromUtc() - 3600 : 0;
+ // Madrid, actually west of Greenwich, uses CET as if it were an hour east
+ // of Greenwich; allow that the fix might be more than an hour, either way:
+ Q_ASSERT(preZoneFix > -7200 && preZoneFix < 7200);
+ // So it's OK to add it to a QTime() between 02:00 and 22:00, but otherwise
+ // we must add it to the QDateTime constructed from it.
+}
+
+void tst_QDateTime::initTestCase()
+{
+ // Never construct a message like this in an i18n context...
+ const char *typemsg1 = "exactly";
+ const char *typemsg2 = "and therefore not";
+ switch (futureTimeType) {
+ case LocalTimeIsUtc:
+ break;
+ case LocalTimeBehindUtc:
+ typemsg1 = "behind";
+ break;
+ case LocalTimeAheadOfUtc:
+ typemsg1 = "ahead of";
+ typemsg2 = zoneIsCET ? "and is" : "but isn't";
+ break;
+ }
+
+ qDebug() << "Current local time detected to be"
+ << typemsg1
+ << "UTC"
+ << typemsg2
+ << "the Central European timezone";
+}
+
+void tst_QDateTime::ctor()
+{
+ QDateTime dt1(QDate(2004, 1, 2), QTime(1, 2, 3));
+ QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
+ QDateTime dt2(QDate(2004, 1, 2), QTime(1, 2, 3));
+ QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
+ QDateTime dt3(QDate(2004, 1, 2), QTime(1, 2, 3), UTC);
+ QCOMPARE(dt3.timeSpec(), Qt::UTC);
+
+ QVERIFY(dt1 == dt2);
+ if (zoneIsCET) {
+ QVERIFY(dt1 != dt3);
+ QVERIFY(dt1 < dt3);
+ QVERIFY(dt1.addSecs(3600).toUTC() == dt3);
+ }
+
+ // Test OffsetFromUTC constructors
+ QDate offsetDate(2013, 1, 1);
+ QTime offsetTime(1, 2, 3);
+
+ QDateTime offset1(offsetDate, offsetTime, QTimeZone::fromSecondsAheadOfUtc(0));
+ QCOMPARE(offset1.timeSpec(), Qt::UTC);
+ QCOMPARE(offset1.offsetFromUtc(), 0);
+ QCOMPARE(offset1.date(), offsetDate);
+ QCOMPARE(offset1.time(), offsetTime);
+
+ QDateTime offset2(offsetDate, offsetTime,
+ QTimeZone::fromDurationAheadOfUtc(std::chrono::seconds{}));
+ QCOMPARE(offset2.timeSpec(), Qt::UTC);
+ QCOMPARE(offset2.offsetFromUtc(), 0);
+ QCOMPARE(offset2.date(), offsetDate);
+ QCOMPARE(offset2.time(), offsetTime);
+
+ QDateTime offset3(offsetDate, offsetTime, QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QCOMPARE(offset3.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(offset3.offsetFromUtc(), 60 * 60);
+ QCOMPARE(offset3.date(), offsetDate);
+ QCOMPARE(offset3.time(), offsetTime);
+
+ QDateTime offset4(offsetDate, QTime(0, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QCOMPARE(offset4.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(offset4.offsetFromUtc(), 60 * 60);
+ QCOMPARE(offset4.date(), offsetDate);
+ QCOMPARE(offset4.time(), QTime(0, 0));
+}
+
+void tst_QDateTime::operator_eq()
+{
+ QVERIFY(QDateTime() != QDate(1970, 1, 1).startOfDay()); // QTBUG-79006
+ QDateTime dt1(QDate(2004, 3, 24), QTime(23, 45, 57), UTC);
+ QDateTime dt2(QDate(2005, 3, 11), QTime(0, 0), UTC);
+ dt2 = dt1;
+ QVERIFY(dt1 == dt2);
+}
+
+void tst_QDateTime::moveSemantics()
+{
+ QDateTime dt1{QDate{2004, 3, 24}, QTime{23, 45, 57}, UTC};
+ QDateTime dt2{QDate{2005, 3, 11}, QTime{0, 0}, UTC};
+ QDateTime copy = dt1;
+ QDateTime moved = std::move(dt1);
+ QCOMPARE(copy, moved);
+ copy = dt2;
+ moved = std::move(dt2);
+ QCOMPARE(copy, moved);
+}
+
+void tst_QDateTime::isNull()
+{
+ QDateTime dt1;
+ QVERIFY(dt1.isNull());
+ dt1.setDate(QDate());
+ QVERIFY(dt1.isNull());
+ dt1.setTime(QTime());
+ QVERIFY(dt1.isNull());
+ dt1.setTimeZone(UTC);
+ QVERIFY(dt1.isNull());
+
+ dt1.setTime(QTime(12, 34, 56));
+ QVERIFY(!dt1.isNull());
+ dt1.setTime(QTime()); // Date still invalid, so this really clears time.
+ QVERIFY(dt1.isNull());
+ dt1.setDate(QDate(2004, 1, 2));
+ QVERIFY(!dt1.isNull());
+ dt1.setTime(QTime(12, 34, 56));
+ QVERIFY(!dt1.isNull());
+ dt1.setTime(QTime()); // Actually sets time to QTime(0, 0), as date is still valid.
+ QVERIFY(!dt1.isNull());
+ dt1.setDate(QDate()); // Time remains valid
+ QVERIFY(!dt1.isNull());
+ dt1.setTime(QTime()); // Now really sets time invalid, too
+ QVERIFY(dt1.isNull());
+
+ // Either date or time non-null => date-time isn't null:
+ QVERIFY(!QDateTime(QDate(), QTime(0, 0)).isNull());
+ QVERIFY(!QDateTime(QDate(2022, 2, 16), QTime()).isNull());
+}
+
+void tst_QDateTime::isValid()
+{
+ QDateTime dt1;
+ QVERIFY(!dt1.isValid());
+ dt1.setDate(QDate());
+ QVERIFY(!dt1.isValid());
+ dt1.setTime(QTime());
+ QVERIFY(!dt1.isValid());
+ dt1.setTimeZone(UTC);
+ QVERIFY(!dt1.isValid());
+
+ dt1.setDate(QDate(2004, 1, 2));
+ QVERIFY(dt1.isValid());
+ dt1.setTime(QTime()); // Effectively QTime(0, 0)
+ QVERIFY(dt1.isValid());
+ dt1.setDate(QDate());
+ QVERIFY(!dt1.isValid());
+ dt1.setTime(QTime(12, 34, 56));
+ QVERIFY(!dt1.isValid());
+ dt1.setTime(QTime()); // Does sets time invalid, as date is invalid
+ QVERIFY(!dt1.isValid());
+ dt1.setDate(QDate(2004, 1, 2)); // Kicks time back to QTime(0, 0)
+ QVERIFY(dt1.isValid());
+
+ // Invalid date => invalid date-time:
+ QVERIFY(!QDateTime(QDate(), QTime(0, 0)).isValid());
+ // Invalid time gets replaced with QTime(0, 0) when date is valid:
+ QVERIFY(QDateTime(QDate(2022, 2, 16), QTime()).isValid());
+}
+
+void tst_QDateTime::date()
+{
+ QDateTime dt1(QDate(2004, 3, 24), QTime(23, 45, 57));
+ QCOMPARE(dt1.date(), QDate(2004, 3, 24));
+
+ QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57));
+ QCOMPARE(dt2.date(), QDate(2004, 3, 25));
+
+ QDateTime dt3(QDate(2004, 3, 24), QTime(23, 45, 57), UTC);
+ QCOMPARE(dt3.date(), QDate(2004, 3, 24));
+
+ QDateTime dt4(QDate(2004, 3, 25), QTime(0, 45, 57), UTC);
+ QCOMPARE(dt4.date(), QDate(2004, 3, 25));
+}
+
+void tst_QDateTime::time()
+{
+ QDateTime dt1(QDate(2004, 3, 24), QTime(23, 45, 57));
+ QCOMPARE(dt1.time(), QTime(23, 45, 57));
+
+ QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57));
+ QCOMPARE(dt2.time(), QTime(0, 45, 57));
+
+ QDateTime dt3(QDate(2004, 3, 24), QTime(23, 45, 57), UTC);
+ QCOMPARE(dt3.time(), QTime(23, 45, 57));
+
+ QDateTime dt4(QDate(2004, 3, 25), QTime(0, 45, 57), UTC);
+ QCOMPARE(dt4.time(), QTime(0, 45, 57));
+}
+
+#if QT_DEPRECATED_SINCE(6, 9)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QDateTime::timeSpec()
+{
+ QDateTime dt1(QDate(2004, 1, 24), QTime(23, 45, 57));
+ QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.addDays(0).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.addMonths(0).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.addMonths(6).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.addYears(0).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.addSecs(0).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.addSecs(86400 * 185).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.toTimeSpec(Qt::LocalTime).timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt1.toTimeSpec(Qt::UTC).timeSpec(), Qt::UTC);
+
+ QDateTime dt2(QDate(2004, 1, 24), QTime(23, 45, 57));
+ QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
+
+ QDateTime dt3(QDate(2004, 1, 25), QTime(0, 45, 57), UTC);
+ QCOMPARE(dt3.timeSpec(), Qt::UTC);
+
+ QDateTime dt4 = QDateTime::currentDateTime();
+ QCOMPARE(dt4.timeSpec(), Qt::LocalTime);
+}
+QT_WARNING_POP
+#endif
+
+void tst_QDateTime::setDate()
+{
+ QDateTime dt1(QDate(2004, 3, 25), QTime(0, 45, 57), UTC);
+ dt1.setDate(QDate(2004, 6, 25));
+ QCOMPARE(dt1.date(), QDate(2004, 6, 25));
+ QCOMPARE(dt1.time(), QTime(0, 45, 57));
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+
+ QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57));
+ dt2.setDate(QDate(2004, 6, 25));
+ QCOMPARE(dt2.date(), QDate(2004, 6, 25));
+ QCOMPARE(dt2.time(), QTime(0, 45, 57));
+ QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
+
+ QDateTime dt3(QDate(4004, 3, 25), QTime(0, 45, 57), UTC);
+ dt3.setDate(QDate(4004, 6, 25));
+ QCOMPARE(dt3.date(), QDate(4004, 6, 25));
+ QCOMPARE(dt3.time(), QTime(0, 45, 57));
+ QCOMPARE(dt3.timeSpec(), Qt::UTC);
+
+ QDateTime dt4(QDate(4004, 3, 25), QTime(0, 45, 57));
+ dt4.setDate(QDate(4004, 6, 25));
+ QCOMPARE(dt4.date(), QDate(4004, 6, 25));
+ QCOMPARE(dt4.time(), QTime(0, 45, 57));
+ QCOMPARE(dt4.timeSpec(), Qt::LocalTime);
+
+ QDateTime dt5(QDate(1760, 3, 25), QTime(0, 45, 57), UTC);
+ dt5.setDate(QDate(1760, 6, 25));
+ QCOMPARE(dt5.date(), QDate(1760, 6, 25));
+ QCOMPARE(dt5.time(), QTime(0, 45, 57));
+ QCOMPARE(dt5.timeSpec(), Qt::UTC);
+
+ QDateTime dt6(QDate(1760, 3, 25), QTime(0, 45, 57));
+ dt6.setDate(QDate(1760, 6, 25));
+ QCOMPARE(dt6.date(), QDate(1760, 6, 25));
+ QCOMPARE(dt6.time(), QTime(0, 45, 57));
+ QCOMPARE(dt6.timeSpec(), Qt::LocalTime);
+}
+
+void tst_QDateTime::setTime_data()
+{
+ QTest::addColumn<QDateTime>("dateTime");
+ QTest::addColumn<QTime>("newTime");
+
+ QTest::newRow("data0")
+ << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), UTC) << QTime(23, 11, 22);
+ QTest::newRow("data1")
+ << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57)) << QTime(23, 11, 22);
+ QTest::newRow("data2")
+ << QDateTime(QDate(4004, 3, 25), QTime(0, 45, 57), UTC) << QTime(23, 11, 22);
+ QTest::newRow("data3")
+ << QDateTime(QDate(4004, 3, 25), QTime(0, 45, 57)) << QTime(23, 11, 22);
+ QTest::newRow("data4")
+ << QDateTime(QDate(1760, 3, 25), QTime(0, 45, 57), UTC) << QTime(23, 11, 22);
+ QTest::newRow("data5")
+ << QDateTime(QDate(1760, 3, 25), QTime(0, 45, 57)) << QTime(23, 11, 22);
+
+ QTest::newRow("set on std/dst") << QDateTime::currentDateTime() << QTime(23, 11, 22);
+}
+
+void tst_QDateTime::setTime()
+{
+ QFETCH(QDateTime, dateTime);
+ QFETCH(QTime, newTime);
+
+ const QDate expectedDate(dateTime.date());
+ const Qt::TimeSpec expectedTimeSpec(dateTime.timeSpec());
+
+ dateTime.setTime(newTime);
+
+ QCOMPARE(dateTime.date(), expectedDate);
+ QCOMPARE(dateTime.time(), newTime);
+ QCOMPARE(dateTime.timeSpec(), expectedTimeSpec);
+}
+
+void tst_QDateTime::setTimeZone_data()
+{
+ QTest::addColumn<QDateTime>("dateTime");
+ QTest::addColumn<QTimeZone>("zone");
+ const QDate day(2004, 3, 25);
+ const QTime time(0, 45, 57);
+ struct {
+ const char *id;
+ QTimeZone zone;
+ } data[] = {
+ { nullptr, QTimeZone() }, // For time-zone, when supported.
+ { "UTC", UTC },
+ { "LocalTime", QTimeZone() },
+ { "Offset", QTimeZone::fromSecondsAheadOfUtc(3600) }
+ };
+#if QT_CONFIG(timezone)
+ const QTimeZone cet("Europe/Oslo");
+ if (cet.isValid()) {
+ data[0].zone = cet;
+ data[0].id = "Zone";
+ }
+#endif
+ for (const auto &from : data) {
+ if (from.id) {
+ for (const auto &to : data) {
+ if (to.id) {
+ QTest::addRow("%s => %s", from.id, to.id)
+ << QDateTime(day, time, from.zone) << to.zone;
+ }
+ }
+ }
+ }
+}
+
+void tst_QDateTime::setTimeZone()
+{
+ QFETCH(QDateTime, dateTime);
+ QFETCH(QTimeZone, zone);
+
+ // QDateTime::setTimeZone() preserves the date and time rather than
+ // converting to the new time representation.
+ const QDate expectedDate(dateTime.date());
+ const QTime expectedTime(dateTime.time());
+
+ dateTime.setTimeZone(zone);
+
+ QCOMPARE(dateTime.date(), expectedDate);
+ QCOMPARE(dateTime.time(), expectedTime);
+ QCOMPARE(dateTime.timeRepresentation(), zone);
+}
+
+#if QT_DEPRECATED_SINCE(6, 9)
+void tst_QDateTime::setTimeSpec_data()
+{
+ QTest::addColumn<QDateTime>("dateTime");
+ QTest::addColumn<Qt::TimeSpec>("newTimeSpec");
+
+ QTest::newRow("UTC => UTC")
+ << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), UTC) << Qt::UTC;
+ QTest::newRow("UTC => LocalTime")
+ << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), UTC) << Qt::LocalTime;
+ QTest::newRow("UTC => OffsetFromUTC")
+ << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), UTC) << Qt::OffsetFromUTC;
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QDateTime::setTimeSpec()
+{
+ QFETCH(QDateTime, dateTime);
+ QFETCH(Qt::TimeSpec, newTimeSpec);
+
+ const QDate expectedDate(dateTime.date());
+ const QTime expectedTime(dateTime.time());
+
+ dateTime.setTimeSpec(newTimeSpec);
+
+ QCOMPARE(dateTime.date(), expectedDate);
+ QCOMPARE(dateTime.time(), expectedTime);
+ if (newTimeSpec == Qt::OffsetFromUTC)
+ QCOMPARE(dateTime.timeSpec(), Qt::UTC);
+ else
+ QCOMPARE(dateTime.timeSpec(), newTimeSpec);
+}
+QT_WARNING_POP
+#endif
+
+void tst_QDateTime::setSecsSinceEpoch()
+{
+ QDateTime dt1;
+ dt1.setSecsSinceEpoch(0);
+ QCOMPARE(dt1.toUTC(), QDate(1970, 1, 1).startOfDay(UTC));
+ QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
+
+ dt1.setTimeZone(UTC);
+ dt1.setSecsSinceEpoch(0);
+ QCOMPARE(dt1, QDate(1970, 1, 1).startOfDay(UTC));
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+
+ dt1.setSecsSinceEpoch(123456);
+ QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), UTC));
+ if (zoneIsCET) {
+ QDateTime dt2;
+ dt2.setSecsSinceEpoch(123456);
+ QCOMPARE(dt2, QDateTime(QDate(1970, 1, 2), QTime(11, 17, 36)));
+ }
+
+ dt1.setSecsSinceEpoch((uint)(quint32)-123456);
+ QCOMPARE(dt1, QDateTime(QDate(2106, 2, 5), QTime(20, 10, 40), UTC));
+ if (zoneIsCET) {
+ QDateTime dt2;
+ dt2.setSecsSinceEpoch((uint)(quint32)-123456);
+ QCOMPARE(dt2, QDateTime(QDate(2106, 2, 5), QTime(21, 10, 40)));
+ }
+
+ dt1.setSecsSinceEpoch(1214567890);
+ QCOMPARE(dt1, QDateTime(QDate(2008, 6, 27), QTime(11, 58, 10), UTC));
+ if (zoneIsCET) {
+ QDateTime dt2;
+ dt2.setSecsSinceEpoch(1214567890);
+ QCOMPARE(dt2, QDateTime(QDate(2008, 6, 27), QTime(13, 58, 10)));
+ }
+
+ dt1.setSecsSinceEpoch(0x7FFFFFFF);
+ QCOMPARE(dt1, QDateTime(QDate(2038, 1, 19), QTime(3, 14, 7), UTC));
+ if (zoneIsCET) {
+ QDateTime dt2;
+ dt2.setSecsSinceEpoch(0x7FFFFFFF);
+ QCOMPARE(dt2, QDateTime(QDate(2038, 1, 19), QTime(4, 14, 7)));
+ }
+
+ dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ dt1.setSecsSinceEpoch(123456);
+ QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), UTC));
+ QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
+
+ // Only testing UTC; see fromSecsSinceEpoch() for fuller test.
+ dt1.setTimeZone(UTC);
+ const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000;
+ dt1.setSecsSinceEpoch(maxSeconds);
+ QVERIFY(dt1.isValid());
+ dt1.setSecsSinceEpoch(-maxSeconds);
+ QVERIFY(dt1.isValid());
+ dt1.setSecsSinceEpoch(maxSeconds + 1);
+ QVERIFY(!dt1.isValid());
+ dt1.setSecsSinceEpoch(0);
+ QVERIFY(dt1.isValid());
+ dt1.setSecsSinceEpoch(-maxSeconds - 1);
+ QVERIFY(!dt1.isValid());
+}
+
+void tst_QDateTime::setMSecsSinceEpoch_data()
+{
+ QTest::addColumn<qint64>("msecs");
+ QTest::addColumn<QDateTime>("utc");
+ QTest::addColumn<QDateTime>("cet");
+
+ QTest::newRow("zero")
+ << Q_INT64_C(0)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(1, 0));
+ QTest::newRow("+1ms")
+ << Q_INT64_C(+1)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0, 1), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(1, 0, 0, 1));
+ QTest::newRow("+1s")
+ << Q_INT64_C(+1000)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 1), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(1, 0, 1));
+ QTest::newRow("-1ms")
+ << Q_INT64_C(-1)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59, 999), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59, 999));
+ QTest::newRow("-1s")
+ << Q_INT64_C(-1000)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59));
+ QTest::newRow("123456789")
+ << Q_INT64_C(123456789)
+ << QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36, 789), UTC)
+ << QDateTime(QDate(1970, 1, 2), QTime(11, 17, 36, 789));
+ QTest::newRow("-123456789")
+ << Q_INT64_C(-123456789)
+ << QDateTime(QDate(1969, 12, 30), QTime(13, 42, 23, 211), UTC)
+ << QDateTime(QDate(1969, 12, 30), QTime(14, 42, 23, 211));
+ QTest::newRow("post-32-bit-time_t")
+ << (Q_INT64_C(1000) << 32)
+ << QDateTime(QDate(2106, 2, 7), QTime(6, 28, 16), UTC)
+ << QDateTime(QDate(2106, 2, 7), QTime(7, 28, 16));
+ QTest::newRow("very-large")
+ << (Q_INT64_C(123456) << 32)
+ << QDateTime(QDate(18772, 8, 15), QTime(1, 8, 14, 976), UTC)
+ << QDateTime(QDate(18772, 8, 15), QTime(3, 8, 14, 976));
+ QTest::newRow("old min (Tue Nov 25 00:00:00 -4714)")
+ << Q_INT64_C(-210866716800000)
+ << QDateTime(QDate::fromJulianDay(1), QTime(0, 0), UTC)
+ << QDateTime(QDate::fromJulianDay(1), QTime(1, 0)).addSecs(preZoneFix);
+ QTest::newRow("old max (Tue Jun 3 21:59:59 5874898)")
+ << Q_INT64_C(185331720376799999)
+ << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(21, 59, 59, 999), UTC)
+ << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(23, 59, 59, 999));
+ QTest::newRow("min")
+ << std::numeric_limits<qint64>::min()
+ << QDateTime(QDate(-292275056, 5, 16), QTime(16, 47, 4, 192), UTC)
+ << QDateTime(QDate(-292275056, 5, 16), QTime(17, 47, 4, 192).addSecs(preZoneFix));
+ QTest::newRow("max")
+ << std::numeric_limits<qint64>::max()
+ << QDateTime(QDate(292278994, 8, 17), QTime(7, 12, 55, 807), UTC)
+ << QDateTime(QDate(292278994, 8, 17), QTime(9, 12, 55, 807));
+}
+
+void tst_QDateTime::setMSecsSinceEpoch()
+{
+ QFETCH(qint64, msecs);
+ QFETCH(QDateTime, utc);
+ QFETCH(QDateTime, cet);
+ using Bound = std::numeric_limits<qint64>;
+
+ QDateTime dt;
+ dt.setTimeZone(UTC);
+ dt.setMSecsSinceEpoch(msecs);
+
+ QCOMPARE(dt, utc);
+ QCOMPARE(dt.date(), utc.date());
+ QCOMPARE(dt.time(), utc.time());
+ QCOMPARE(dt.timeSpec(), Qt::UTC);
+
+ {
+ QDateTime dt1 = QDateTime::fromMSecsSinceEpoch(msecs, UTC);
+ QCOMPARE(dt1, utc);
+ QCOMPARE(dt1.date(), utc.date());
+ QCOMPARE(dt1.time(), utc.time());
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+ }
+ {
+ QDateTime dt1(utc.date(), utc.time(), UTC);
+ QCOMPARE(dt1, utc);
+ QCOMPARE(dt1.date(), utc.date());
+ QCOMPARE(dt1.time(), utc.time());
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+ }
+ {
+ // used to fail to clear the ShortData bit, causing corruption
+ QDateTime dt1 = dt.addDays(0);
+ QCOMPARE(dt1, utc);
+ QCOMPARE(dt1.date(), utc.date());
+ QCOMPARE(dt1.time(), utc.time());
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+ }
+
+ if (zoneIsCET && (msecs == Bound::max()
+ // LocalTime will also overflow for min in a CET zone west
+ // of Greenwich (Europe/Madrid):
+ || (preZoneFix < -3600 && msecs == Bound::min()))) {
+ QVERIFY(!cet.isValid()); // overflows
+ } else if (zoneIsCET) {
+ QVERIFY(cet.isValid());
+ QCOMPARE(dt.toLocalTime(), cet);
+
+ // Test converting from LocalTime to UTC back to LocalTime.
+ QDateTime localDt;
+ localDt.setTimeZone(QTimeZone::LocalTime);
+ localDt.setMSecsSinceEpoch(msecs);
+
+ QCOMPARE(localDt, utc);
+ QCOMPARE(localDt.timeSpec(), Qt::LocalTime);
+
+ // Compare result for LocalTime to TimeZone
+ QDateTime dt2;
+#if QT_CONFIG(timezone)
+ QTimeZone europe("Europe/Oslo");
+ dt2.setTimeZone(europe);
+#endif
+ dt2.setMSecsSinceEpoch(msecs);
+ if (cet.date().year() >= 1970 || cet.date() == utc.date())
+ QCOMPARE(dt2.date(), cet.date());
+
+ // Don't compare the time if the date is too early: prior to the early
+ // 20th century, timezones in Europe were not standardised. Limit to the
+ // same year-range as we used when determining zoneIsCET:
+ if (cet.date().year() >= 1970 && cet.date().year() <= 2037)
+ QCOMPARE(dt2.time(), cet.time());
+#if QT_CONFIG(timezone)
+ QCOMPARE(dt2.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt2.timeZone(), europe);
+#endif
+ }
+
+ QCOMPARE(dt.toMSecsSinceEpoch(), msecs);
+ QCOMPARE(qint64(dt.toSecsSinceEpoch()), msecs / 1000);
+
+ QDateTime reference(QDate(1970, 1, 1), QTime(0, 0), UTC);
+ QCOMPARE(dt, reference.addMSecs(msecs));
+
+ // Tests that we correctly recognize when we fall off the extremities:
+ if (msecs == Bound::max()) {
+ QDateTime off(QDate(1970, 1, 1).startOfDay(QTimeZone::fromSecondsAheadOfUtc(1)));
+ off.setMSecsSinceEpoch(msecs);
+ QVERIFY(!off.isValid());
+ } else if (msecs == Bound::min()) {
+ QDateTime off(QDate(1970, 1, 1).startOfDay(QTimeZone::fromSecondsAheadOfUtc(-1)));
+ off.setMSecsSinceEpoch(msecs);
+ QVERIFY(!off.isValid());
+ }
+
+ // Check overflow; only robust if local time is the same at epoch as relevant bound.
+ // See setting of LocalTimeType values for details.
+ if (epochTimeType == LocalTimeAheadOfUtc
+ ? distantTimeType == LocalTimeAheadOfUtc && msecs == Bound::max()
+ : (solarMeanType == LocalTimeBehindUtc && msecs == Bound::min()
+ && epochTimeType == LocalTimeBehindUtc)) {
+ QDateTime curt = QDate(1970, 1, 1).startOfDay(); // initially in short-form
+ curt.setMSecsSinceEpoch(msecs); // Overflows due to offset
+ QVERIFY(!curt.isValid());
+ }
+}
+
+void tst_QDateTime::fromMSecsSinceEpoch()
+{
+ QFETCH(qint64, msecs);
+ QFETCH(QDateTime, utc);
+ QFETCH(QDateTime, cet);
+ using Bound = std::numeric_limits<qint64>;
+
+ QDateTime dtLocal = QDateTime::fromMSecsSinceEpoch(msecs);
+ QDateTime dtUtc = QDateTime::fromMSecsSinceEpoch(msecs, UTC);
+ QDateTime dtOffset
+ = QDateTime::fromMSecsSinceEpoch(msecs, QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ // LocalTime will overflow for "min" or "max" tests, depending on whether
+ // you're East or West of Greenwich. In UTC, we won't overflow. If we're
+ // actually west of Greenwich but (e.g. Europe/Madrid) our zone claims east,
+ // "min" can also overflow (case only caught if local time is CET).
+ const bool localOverflow =
+ (distantTimeType == LocalTimeAheadOfUtc && (msecs == Bound::max() || preZoneFix < -3600))
+ || (solarMeanType == LocalTimeBehindUtc && msecs == Bound::min());
+ if (!localOverflow) // Can fail if offset changes sign, e.g. Alaska, Philippines.
+ QCOMPARE(dtLocal, utc);
+
+ QCOMPARE(dtUtc, utc);
+ QCOMPARE(dtUtc.date(), utc.date());
+ QCOMPARE(dtUtc.time(), utc.time());
+
+ if (msecs == Bound::max()) { // Offset is positive, so overflows max
+ QVERIFY(!dtOffset.isValid());
+ } else {
+ QCOMPARE(dtOffset, utc);
+ QCOMPARE(dtOffset.offsetFromUtc(), 60*60);
+ QCOMPARE(dtOffset.time(), utc.time().addMSecs(60*60*1000));
+ }
+
+ if (zoneIsCET) {
+ QCOMPARE(dtLocal.toLocalTime(), cet);
+ QCOMPARE(dtUtc.toLocalTime(), cet);
+ if (msecs != Bound::max())
+ QCOMPARE(dtOffset.toLocalTime(), cet);
+ }
+
+ if (!localOverflow)
+ QCOMPARE(dtLocal.toMSecsSinceEpoch(), msecs);
+ QCOMPARE(dtUtc.toMSecsSinceEpoch(), msecs);
+ if (msecs != Bound::max())
+ QCOMPARE(dtOffset.toMSecsSinceEpoch(), msecs);
+
+ if (!localOverflow)
+ QCOMPARE(qint64(dtLocal.toSecsSinceEpoch()), msecs / 1000);
+ QCOMPARE(qint64(dtUtc.toSecsSinceEpoch()), msecs / 1000);
+ if (msecs != Bound::max())
+ QCOMPARE(qint64(dtOffset.toSecsSinceEpoch()), msecs / 1000);
+
+ QDateTime reference(QDate(1970, 1, 1), QTime(0, 0), UTC);
+ if (!localOverflow)
+ QCOMPARE(dtLocal, reference.addMSecs(msecs));
+ QCOMPARE(dtUtc, reference.addMSecs(msecs));
+ if (msecs != Bound::max())
+ QCOMPARE(dtOffset, reference.addMSecs(msecs));
+}
+
+void tst_QDateTime::fromSecsSinceEpoch()
+{
+ // Compare setSecsSinceEpoch()
+ const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000;
+ const QDateTime early = QDateTime::fromSecsSinceEpoch(-maxSeconds, UTC);
+ const QDateTime late = QDateTime::fromSecsSinceEpoch(maxSeconds, UTC);
+
+ QVERIFY(late.isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, UTC).isValid());
+ QVERIFY(early.isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, UTC).isValid());
+
+ // Local time: need to adjust for its zone offset
+ const int lateOffset = late.addYears(-1).toLocalTime().offsetFromUtc();
+#if QT_CONFIG(timezone)
+ // Check what system zone believes in, as it's used as fall-back to cope
+ // with times outside the system time_t functions' range, or overflow on the
+ // results of using those functions. (It seems glibc's handling of
+ // Australasian zones parts company with the IANA DB after about 5881580 CE,
+ // leaving NZ in permanent DST after that, for example.) Of course, if
+ // that's less than lateOffset (as it is for glibc's similar handling of
+ // MET), the fall-back code will also fail when the primary code fails, so
+ // use the lesser of these late offsets.
+ const int lateZone = qMin(QTimeZone::systemTimeZone().offsetFromUtc(late), lateOffset);
+#else
+ const int lateZone = lateOffset;
+#endif
+
+ const qint64 last = maxSeconds - qMax(lateZone, 0);
+ QVERIFY(QDateTime::fromSecsSinceEpoch(last).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(last + 1).isValid());
+ const qint64 first = -maxSeconds - qMin(early.addYears(1).toLocalTime().offsetFromUtc(), 0);
+ QVERIFY(QDateTime::fromSecsSinceEpoch(first).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(first - 1).isValid());
+
+ // Use an offset for which .toUTC()'s return would flip the validity:
+ QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds - 7200,
+ QTimeZone::fromSecondsAheadOfUtc(7200)).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds - 7199,
+ QTimeZone::fromSecondsAheadOfUtc(7200)).isValid());
+ QVERIFY(QDateTime::fromSecsSinceEpoch(7200 - maxSeconds,
+ QTimeZone::fromSecondsAheadOfUtc(-7200)).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(7199 - maxSeconds,
+ QTimeZone::fromSecondsAheadOfUtc(-7200)).isValid());
+
+#if QT_CONFIG(timezone)
+ // As for offset, use zones each side of UTC:
+ const QTimeZone west("UTC-02:00"), east("UTC+02:00");
+ QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, west).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, east).isValid());
+ QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, east).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, west).isValid());
+#endif // timezone
+}
+
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
+void tst_QDateTime::toString_isoDate_data()
+{
+ QTest::addColumn<QDateTime>("datetime");
+ QTest::addColumn<Qt::DateFormat>("format");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("localtime")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34))
+ << Qt::ISODate << QString("1978-11-09T13:28:34");
+ QTest::newRow("UTC")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), UTC)
+ << Qt::ISODate << QString("1978-11-09T13:28:34Z");
+ QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
+ dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(19800));
+ QTest::newRow("positive OffsetFromUTC")
+ << dt << Qt::ISODate
+ << QString("1978-11-09T13:28:34+05:30");
+ dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-7200));
+ QTest::newRow("negative OffsetFromUTC")
+ << dt << Qt::ISODate
+ << QString("1978-11-09T13:28:34-02:00");
+ dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-900));
+ QTest::newRow("negative non-integral OffsetFromUTC")
+ << dt << Qt::ISODate
+ << QString("1978-11-09T13:28:34-00:15");
+ QTest::newRow("invalid") // ISODate < 2019 doesn't allow -ve year numbers; QTBUG-91070
+ << QDateTime(QDate(-1, 11, 9), QTime(13, 28, 34), UTC)
+ << Qt::ISODate << QString();
+ QTest::newRow("without-ms")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34, 20))
+ << Qt::ISODate << QString("1978-11-09T13:28:34");
+ QTest::newRow("with-ms")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34, 20))
+ << Qt::ISODateWithMs << QString("1978-11-09T13:28:34.020");
+}
+
+void tst_QDateTime::toString_isoDate()
+{
+ QFETCH(const QDateTime, datetime);
+ QFETCH(const Qt::DateFormat, format);
+ QFETCH(const QString, expected);
+
+ const QString result = datetime.toString(format);
+ QCOMPARE(result, expected);
+
+ const QDateTime resultDatetime = QDateTime::fromString(result, format);
+ if (QByteArrayView(QTest::currentDataTag()) == "invalid") {
+ QCOMPARE(resultDatetime, QDateTime());
+ } else {
+ const QDateTime when =
+ QByteArrayView(QTest::currentDataTag()) == "without-ms"
+ ? datetime.addMSecs(-datetime.time().msec()) : datetime;
+ QCOMPARE(resultDatetime.toMSecsSinceEpoch(), when.toMSecsSinceEpoch());
+ QCOMPARE(resultDatetime, when);
+ QCOMPARE(resultDatetime.date(), when.date());
+ QCOMPARE(resultDatetime.time(), when.time());
+ QCOMPARE(resultDatetime.timeSpec(), when.timeSpec());
+ QCOMPARE(resultDatetime.offsetFromUtc(), when.offsetFromUtc());
+ }
+}
+
+void tst_QDateTime::toString_isoDate_extra()
+{
+ QDateTime dt = QDateTime::fromMSecsSinceEpoch(0, UTC);
+ QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T00:00:00Z"));
+#if QT_CONFIG(timezone)
+ QTimeZone PST("America/Vancouver");
+ if (PST.isValid()) {
+ dt = QDateTime::fromMSecsSinceEpoch(0, PST);
+ QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1969-12-31T16:00:00-08:00"));
+ } else {
+ qDebug("Missed zone test: no America/Vancouver zone available");
+ }
+ QTimeZone CET("Europe/Berlin");
+ if (CET.isValid()) {
+ dt = QDateTime::fromMSecsSinceEpoch(0, CET);
+ QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T01:00:00+01:00"));
+ } else {
+ qDebug("Missed zone test: no Europe/Berlin zone available");
+ }
+#endif // timezone
+}
+
+void tst_QDateTime::toString_textDate_data()
+{
+ QTest::addColumn<QDateTime>("datetime");
+ QTest::addColumn<QString>("expected");
+
+ const QString wednesdayJanuary = QLocale::c().dayName(3, QLocale::ShortFormat)
+ + ' ' + QLocale::c().monthName(1, QLocale::ShortFormat);
+
+ // ### Qt 7 GMT: change to UTC - see matching QDateTime::fromString() comment
+ QTest::newRow("localtime") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3))
+ << wednesdayJanuary + QString(" 2 01:02:03 2013");
+ QTest::newRow("utc") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3), UTC)
+ << wednesdayJanuary + QString(" 2 01:02:03 2013 GMT");
+ QTest::newRow("offset+") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3),
+ QTimeZone::fromSecondsAheadOfUtc(10 * 60 * 60))
+ << wednesdayJanuary + QString(" 2 01:02:03 2013 GMT+1000");
+ QTest::newRow("offset-") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3),
+ QTimeZone::fromSecondsAheadOfUtc(-10 * 60 * 60))
+ << wednesdayJanuary + QString(" 2 01:02:03 2013 GMT-1000");
+ QTest::newRow("invalid") << QDateTime()
+ << QString("");
+}
+
+void tst_QDateTime::toString_textDate()
+{
+ QFETCH(QDateTime, datetime);
+ QFETCH(QString, expected);
+
+ QString result = datetime.toString(Qt::TextDate);
+ QCOMPARE(result, expected);
+
+#if QT_CONFIG(datetimeparser)
+ QDateTime resultDatetime = QDateTime::fromString(result, Qt::TextDate);
+ QCOMPARE(resultDatetime, datetime);
+ QCOMPARE(resultDatetime.date(), datetime.date());
+ QCOMPARE(resultDatetime.time(), datetime.time());
+ QCOMPARE(resultDatetime.timeSpec(), datetime.timeSpec());
+ QCOMPARE(resultDatetime.offsetFromUtc(), datetime.offsetFromUtc());
+#endif
+}
+
+void tst_QDateTime::toString_textDate_extra()
+{
+ // ### Qt 7 GMT: change to UTC - see matching QDateTime::fromString() comment
+ auto endsWithGmt = [](const QDateTime &dt) {
+ return dt.toString().endsWith(QLatin1String("GMT"));
+ };
+ QDateTime dt = QDateTime::fromMSecsSinceEpoch(0);
+ QVERIFY(!endsWithGmt(dt));
+ dt = QDateTime::fromMSecsSinceEpoch(0, UTC).toLocalTime();
+ QVERIFY(!endsWithGmt(dt));
+
+#if QT_CONFIG(timezone)
+ if (QTimeZone::systemTimeZone().offsetFromUtc(dt))
+ QVERIFY(dt.toString() != QLatin1String("Thu Jan 1 00:00:00 1970"));
+ else
+ QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 00:00:00 1970"));
+
+ QTimeZone PST("America/Vancouver");
+ if (PST.isValid()) {
+ dt = QDateTime::fromMSecsSinceEpoch(0, PST);
+ QCOMPARE(dt.toString(), QLatin1String("Wed Dec 31 16:00:00 1969 UTC-08:00"));
+ dt = dt.toLocalTime();
+ QVERIFY(!endsWithGmt(dt));
+ } else {
+ qDebug("Missed zone test: no America/Vancouver zone available");
+ }
+ QTimeZone CET("Europe/Berlin");
+ if (CET.isValid()) {
+ dt = QDateTime::fromMSecsSinceEpoch(0, CET);
+ QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 01:00:00 1970 UTC+01:00"));
+ dt = dt.toLocalTime();
+ QVERIFY(!endsWithGmt(dt));
+ } else {
+ qDebug("Missed zone test: no Europe/Berlin zone available");
+ }
+#else // timezone
+ if (dt.offsetFromUtc())
+ QVERIFY(dt.toString() != QLatin1String("Thu Jan 1 00:00:00 1970"));
+ else
+ QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 00:00:00 1970"));
+#endif
+ dt = QDateTime::fromMSecsSinceEpoch(0, UTC);
+ QVERIFY(endsWithGmt(dt));
+}
+
+void tst_QDateTime::toString_rfcDate_data()
+{
+ QTest::addColumn<QDateTime>("dt");
+ QTest::addColumn<QString>("formatted");
+
+ if (zoneIsCET) {
+ QTest::newRow("localtime")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34))
+ << QString("09 Nov 1978 13:28:34 +0100");
+ }
+ QTest::newRow("UTC")
+ << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), UTC)
+ << QString("09 Nov 1978 13:28:34 +0000");
+ QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
+ dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(19800));
+ QTest::newRow("positive OffsetFromUTC")
+ << dt
+ << QString("09 Nov 1978 13:28:34 +0530");
+ dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-7200));
+ QTest::newRow("negative OffsetFromUTC")
+ << dt
+ << QString("09 Nov 1978 13:28:34 -0200");
+ QTest::newRow("invalid")
+ << QDateTime(QDate(1978, 13, 9), QTime(13, 28, 34), UTC)
+ << QString();
+ QTest::newRow("999 milliseconds UTC")
+ << QDateTime(QDate(2000, 1, 1), QTime(13, 28, 34, 999), UTC)
+ << QString("01 Jan 2000 13:28:34 +0000");
+}
+
+void tst_QDateTime::toString_rfcDate()
+{
+ QFETCH(QDateTime, dt);
+ QFETCH(QString, formatted);
+
+ // Set to non-English locale to confirm still uses English
+ QLocale oldLocale;
+ QLocale::setDefault(QLocale("de_DE"));
+ QString actual(dt.toString(Qt::RFC2822Date));
+ QLocale::setDefault(oldLocale);
+ QCOMPARE(actual, formatted);
+}
+
+void tst_QDateTime::toString_enumformat()
+{
+ QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56));
+
+ QString str1 = dt1.toString(Qt::TextDate);
+ QVERIFY(!str1.isEmpty()); // It's locale-dependent everywhere
+
+ QString str2 = dt1.toString(Qt::ISODate);
+ QCOMPARE(str2, QString("1995-05-20T12:34:56"));
+}
+
+void tst_QDateTime::toString_strformat()
+{
+ // Most tests are in QLocale, just test that the api works.
+ QDate testDate(2013, 1, 1);
+ QTime testTime(1, 2, 3, 456);
+ QDateTime testDateTime(testDate, testTime, UTC);
+ QCOMPARE(testDate.toString("yyyy-MM-dd"), QString("2013-01-01"));
+ QCOMPARE(testTime.toString("hh:mm:ss"), QString("01:02:03"));
+ QCOMPARE(testTime.toString("hh:mm:ss.zz"), QString("01:02:03.456"));
+ QCOMPARE(testDateTime.toString("yyyy-MM-dd hh:mm:ss t"), QString("2013-01-01 01:02:03 UTC"));
+ QCOMPARE(testDateTime.toString("yyyy-MM-dd hh:mm:ss tt"), QString("2013-01-01 01:02:03 +0000"));
+ QCOMPARE(testDateTime.toString("yyyy-MM-dd hh:mm:ss ttt"), QString("2013-01-01 01:02:03 +00:00"));
+ QCOMPARE(testDateTime.toString("yyyy-MM-dd hh:mm:ss tttt"), QString("2013-01-01 01:02:03 UTC"));
+}
+#endif // datestring
+
+void tst_QDateTime::addDays()
+{
+ const QTimeZone zones[] = {
+ QTimeZone(QTimeZone::LocalTime),
+ QTimeZone(QTimeZone::UTC),
+#if QT_CONFIG(timezone)
+ QTimeZone("Europe/Oslo"),
+#endif
+ QTimeZone::fromSecondsAheadOfUtc(3600)
+ };
+ for (const auto &zone : zones) {
+ QDateTime dt = QDateTime(QDate(2004, 1, 1), QTime(12, 34, 56), zone).addDays(185);
+ QVERIFY(dt.date().year() == 2004 && dt.date().month() == 7 && dt.date().day() == 4);
+ QVERIFY(dt.time().hour() == 12 && dt.time().minute() == 34 && dt.time().second() == 56
+ && dt.time().msec() == 0);
+ QCOMPARE(dt.timeRepresentation(), zone);
+
+ dt = dt.addDays(-185);
+ QCOMPARE(dt.date(), QDate(2004, 1, 1));
+ QCOMPARE(dt.time(), QTime(12, 34, 56));
+
+ // Test we can do this before time-zones existed:
+ dt = QDateTime(QDate(1704, 1, 1), QTime(12, 0), zone).addDays(185);
+ QCOMPARE(dt.date(), QDate(1704, 7, 4));
+ QCOMPARE(dt.time(), QTime(12, 0));
+ QCOMPARE(dt.timeRepresentation(), zone);
+ }
+
+ QDateTime dt(QDate(1752, 9, 14), QTime(12, 34, 56));
+ while (dt.date().year() < 8000) {
+ int year = dt.date().year();
+ if (QDate::isLeapYear(year + 1))
+ dt = dt.addDays(366);
+ else
+ dt = dt.addDays(365);
+ QCOMPARE(dt.date(), QDate(year + 1, 9, 14));
+ QCOMPARE(dt.time(), QTime(12, 34, 56));
+ }
+
+ // Test preserves TimeSpec
+ QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0), UTC);
+ QDateTime dt2 = dt1.addDays(2);
+ QCOMPARE(dt2.date(), QDate(2013, 1, 3));
+ QCOMPARE(dt2.time(), QTime(0, 0));
+ QCOMPARE(dt2.timeSpec(), Qt::UTC);
+
+ dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0));
+ dt2 = dt1.addDays(2);
+ QCOMPARE(dt2.date(), QDate(2013, 1, 3));
+ QCOMPARE(dt2.time(), QTime(0, 0));
+ QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
+
+ dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ dt2 = dt1.addDays(2);
+ QCOMPARE(dt2.date(), QDate(2013, 1, 3));
+ QCOMPARE(dt2.time(), QTime(0, 0));
+ QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(dt2.offsetFromUtc(), 60 * 60);
+
+#if QT_CONFIG(timezone)
+ const QTimeZone cet("Europe/Oslo");
+ if (cet.isValid()) {
+ dt1 = QDate(2022, 1, 10).startOfDay(cet);
+ dt2 = dt1.addDays(2); // QTBUG-99668: should not assert
+ QCOMPARE(dt2.date(), QDate(2022, 1, 12));
+ QCOMPARE(dt2.time(), QTime(0, 0));
+ QCOMPARE(dt2.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt2.timeZone(), cet);
+ }
+# ifndef INADEQUATE_TZ_DATA
+ if (const QTimeZone lint("Pacific/Kiritimati"); lint.isValid()) {
+ // Line Islands Time skipped Sat 1994-12-31:
+ dt1 = QDateTime(QDate(1994, 12, 30), QTime(12, 0), lint);
+ dt2 = QDateTime(QDate(1995, 1, 1), QTime(12, 0), lint);
+ // Trying to step into the hole gets the other side:
+ QCOMPARE(dt1.addDays(1), dt2);
+ QCOMPARE(dt2.addDays(-1), dt1);
+ // But the other side is in fact two days away:
+ QCOMPARE(dt1.addDays(2), dt2);
+ QCOMPARE(dt2.addDays(-2), dt1);
+ QCOMPARE(dt1.daysTo(dt2), 2);
+ }
+# ifndef Q_OS_DARWIN
+ if (const QTimeZone alaska("America/Anchorage"); alaska.isValid()) {
+ // On Julian date 1867, Sat Oct 7 (at 14:31 local solar mean time for
+ // Anchorage, 15:30 LMT in Sitka, which hosted the transfer ceremony)
+ // Russia sold Alaska to the USA, which changed the calendar to
+ // Gregorian, hence the date to Fri Oct 18. Compare addSecs:Alaska-Day.
+ // Friday evening and Saturday morning were repeated, with different dates.
+ // Friday noon, as described by the Russians:
+ dt1 = QDateTime(QDate(1867, 10, 6, QCalendar(QCalendar::System::Julian)),
+ QTime(12, 0), alaska);
+ // Sunday noon, as described by the Americans:
+ dt2 = QDateTime(QDate(1867, 10, 20), QTime(12, 0), alaska);
+ // Three elapsed days, but daysTo() and addDays only see two:
+ QCOMPARE(dt1.addDays(2), dt2);
+ QCOMPARE(dt2.addDays(-2), dt1);
+ QCOMPARE(dt1.daysTo(dt2), 2);
+ // Stepping into the duplicated day (Julian 7th, Gregorian 19th) gets
+ // the nearer side, with the same nominal date (and time):
+ QCOMPARE(dt1.addDays(1).date(), dt2.addDays(-1).date());
+ QCOMPARE(dt1.addDays(1).time(), dt2.addDays(-1).time());
+ QCOMPARE(dt1.addDays(1).daysTo(dt2.addDays(-1)), 0);
+ // Yet they differ by a day:
+ QCOMPARE_NE(dt1.addDays(1), dt2.addDays(-1));
+ QCOMPARE(dt1.addDays(1).secsTo(dt2.addDays(-1)), 24 * 60 * 60);
+ // Stepping from one duplicate one day towards the other jumps it:
+ QCOMPARE(dt1, dt2.addDays(-1).addDays(-1));
+ QCOMPARE(dt1.addDays(1).addDays(1), dt2);
+ }
+# endif // Darwin
+# endif // inadequate zone data
+#endif // timezone
+
+ // Baja Mexico has a transition at the epoch, see fromStringDateFormat_data().
+ if (QDateTime(QDate(1969, 12, 30), QTime(0, 0)).secsTo(
+ QDateTime(QDate(1970, 1, 2), QTime(0, 0))) == 3 * 24 * 60 * 60) {
+ // Test last UTC second of 1969 *is* valid (despite being time_t(-1))
+ dt1 = QDateTime(QDate(1969, 12, 30), QTime(23, 59, 59), UTC).toLocalTime().addDays(1);
+ QVERIFY(dt1.isValid());
+ QCOMPARE(dt1.toSecsSinceEpoch(), -1);
+ dt2 = QDateTime(QDate(1970, 1, 1), QTime(23, 59, 59), UTC).toLocalTime().addDays(-1);
+ QVERIFY(dt2.isValid());
+ QCOMPARE(dt2.toSecsSinceEpoch(), -1);
+ }
+}
+
+void tst_QDateTime::addInvalid()
+{
+ QDateTime bad;
+ QVERIFY(!bad.isValid());
+ QVERIFY(bad.isNull());
+
+ QDateTime offset = bad.addDays(2);
+ QVERIFY(offset.isNull());
+ offset = bad.addMonths(-1);
+ QVERIFY(offset.isNull());
+ offset = bad.addYears(23);
+ QVERIFY(offset.isNull());
+ offset = bad.addSecs(73);
+ QVERIFY(offset.isNull());
+ offset = bad.addMSecs(73);
+ QVERIFY(offset.isNull());
+
+ QDateTime bound = QDateTime::fromMSecsSinceEpoch(std::numeric_limits<qint64>::min(), UTC);
+ QVERIFY(bound.isValid());
+ offset = bound.addMSecs(-1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addSecs(-1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addDays(-1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addMonths(-1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addYears(-1);
+ QVERIFY(!offset.isValid());
+
+ bound.setMSecsSinceEpoch(std::numeric_limits<qint64>::max());
+ QVERIFY(bound.isValid());
+ offset = bound.addMSecs(1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addSecs(1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addDays(1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addMonths(1);
+ QVERIFY(!offset.isValid());
+ offset = bound.addYears(1);
+ QVERIFY(!offset.isValid());
+}
+
+void tst_QDateTime::addMonths_data()
+{
+ QTest::addColumn<int>("months");
+ QTest::addColumn<QDate>("resultDate");
+
+ QTest::newRow("-15") << -15 << QDate(2002, 10, 31);
+ QTest::newRow("-14") << -14 << QDate(2002, 11, 30);
+ QTest::newRow("-13") << -13 << QDate(2002, 12, 31);
+ QTest::newRow("-12") << -12 << QDate(2003, 1, 31);
+
+ QTest::newRow("-11") << -11 << QDate(2003, 2, 28);
+ QTest::newRow("-10") << -10 << QDate(2003, 3, 31);
+ QTest::newRow("-9") << -9 << QDate(2003, 4, 30);
+ QTest::newRow("-8") << -8 << QDate(2003, 5, 31);
+ QTest::newRow("-7") << -7 << QDate(2003, 6, 30);
+ QTest::newRow("-6") << -6 << QDate(2003, 7, 31);
+ QTest::newRow("-5") << -5 << QDate(2003, 8, 31);
+ QTest::newRow("-4") << -4 << QDate(2003, 9, 30);
+ QTest::newRow("-3") << -3 << QDate(2003, 10, 31);
+ QTest::newRow("-2") << -2 << QDate(2003, 11, 30);
+ QTest::newRow("-1") << -1 << QDate(2003, 12, 31);
+ QTest::newRow("0") << 0 << QDate(2004, 1, 31);
+ QTest::newRow("1") << 1 << QDate(2004, 2, 29);
+ QTest::newRow("2") << 2 << QDate(2004, 3, 31);
+ QTest::newRow("3") << 3 << QDate(2004, 4, 30);
+ QTest::newRow("4") << 4 << QDate(2004, 5, 31);
+ QTest::newRow("5") << 5 << QDate(2004, 6, 30);
+ QTest::newRow("6") << 6 << QDate(2004, 7, 31);
+ QTest::newRow("7") << 7 << QDate(2004, 8, 31);
+ QTest::newRow("8") << 8 << QDate(2004, 9, 30);
+ QTest::newRow("9") << 9 << QDate(2004, 10, 31);
+ QTest::newRow("10") << 10 << QDate(2004, 11, 30);
+ QTest::newRow("11") << 11 << QDate(2004, 12, 31);
+ QTest::newRow("12") << 12 << QDate(2005, 1, 31);
+ QTest::newRow("13") << 13 << QDate(2005, 2, 28);
+ QTest::newRow("14") << 14 << QDate(2005, 3, 31);
+ QTest::newRow("15") << 15 << QDate(2005, 4, 30);
+}
+
+void tst_QDateTime::addMonths()
+{
+ QFETCH(int, months);
+ QFETCH(QDate, resultDate);
+
+ QDate testDate(2004, 1, 31);
+ QTime testTime(12, 34, 56);
+ QDateTime start(testDate, testTime);
+ QDateTime end = start.addMonths(months);
+ QCOMPARE(end.date(), resultDate);
+ QCOMPARE(end.time(), testTime);
+ QCOMPARE(end.timeSpec(), Qt::LocalTime);
+
+ start = QDateTime(testDate, testTime, UTC);
+ end = start.addMonths(months);
+ QCOMPARE(end.date(), resultDate);
+ QCOMPARE(end.time(), testTime);
+ QCOMPARE(end.timeSpec(), Qt::UTC);
+
+ start = QDateTime(testDate, testTime, QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ end = start.addMonths(months);
+ QCOMPARE(end.date(), resultDate);
+ QCOMPARE(end.time(), testTime);
+ QCOMPARE(end.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(end.offsetFromUtc(), 60 * 60);
+}
+
+void tst_QDateTime::addYears_data()
+{
+ QTest::addColumn<int>("years1");
+ QTest::addColumn<int>("years2");
+ QTest::addColumn<QDate>("startDate");
+ QTest::addColumn<QDate>("resultDate");
+
+ QTest::newRow("0") << 0 << 0 << QDate(1752, 9, 14) << QDate(1752, 9, 14);
+ QTest::newRow("4000 - 4000") << 4000 << -4000 << QDate(1752, 9, 14) << QDate(1752, 9, 14);
+ QTest::newRow("10") << 10 << 0 << QDate(1752, 9, 14) << QDate(1762, 9, 14);
+ QTest::newRow("0 leap year") << 0 << 0 << QDate(1760, 2, 29) << QDate(1760, 2, 29);
+ QTest::newRow("1 leap year") << 1 << 0 << QDate(1760, 2, 29) << QDate(1761, 2, 28);
+ QTest::newRow("2 leap year") << 2 << 0 << QDate(1760, 2, 29) << QDate(1762, 2, 28);
+ QTest::newRow("3 leap year") << 3 << 0 << QDate(1760, 2, 29) << QDate(1763, 2, 28);
+ QTest::newRow("4 leap year") << 4 << 0 << QDate(1760, 2, 29) << QDate(1764, 2, 29);
+
+ QTest::newRow("toNegative1") << -2000 << 0 << QDate(1752, 9, 14) << QDate(-249, 9, 14);
+ QTest::newRow("toNegative2") << -1752 << 0 << QDate(1752, 9, 14) << QDate(-1, 9, 14);
+ QTest::newRow("toNegative3") << -1751 << 0 << QDate(1752, 9, 14) << QDate(1, 9, 14);
+ QTest::newRow("toPositive1") << 2000 << 0 << QDate(-1752, 9, 14) << QDate(249, 9, 14);
+ QTest::newRow("toPositive2") << 1752 << 0 << QDate(-1752, 9, 14) << QDate(1, 9, 14);
+ QTest::newRow("toPositive3") << 1751 << 0 << QDate(-1752, 9, 14) << QDate(-1, 9, 14);
+}
+
+void tst_QDateTime::addYears()
+{
+ QFETCH(int, years1);
+ QFETCH(int, years2);
+ QFETCH(QDate, startDate);
+ QFETCH(QDate, resultDate);
+
+ QTime testTime(14, 25, 36);
+ QDateTime start(startDate, testTime);
+ QDateTime end = start.addYears(years1).addYears(years2);
+ QCOMPARE(end.date(), resultDate);
+ QCOMPARE(end.time(), testTime);
+ QCOMPARE(end.timeSpec(), Qt::LocalTime);
+
+ start = QDateTime(startDate, testTime, UTC);
+ end = start.addYears(years1).addYears(years2);
+ QCOMPARE(end.date(), resultDate);
+ QCOMPARE(end.time(), testTime);
+ QCOMPARE(end.timeSpec(), Qt::UTC);
+
+ start = QDateTime(startDate, testTime, QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ end = start.addYears(years1).addYears(years2);
+ QCOMPARE(end.date(), resultDate);
+ QCOMPARE(end.time(), testTime);
+ QCOMPARE(end.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(end.offsetFromUtc(), 60 * 60);
+}
+
+void tst_QDateTime::addMSecs_data()
+{
+ QTest::addColumn<QDateTime>("dt");
+ QTest::addColumn<qint64>("nsecs");
+ QTest::addColumn<QDateTime>("result");
+
+ const QTime standardTime(12, 34, 56);
+ const QTime daylightTime(13, 34, 56);
+ const qint64 daySecs(86400);
+
+ QTest::newRow("utc0")
+ << QDateTime(QDate(2004, 1, 1), standardTime, UTC) << daySecs
+ << QDateTime(QDate(2004, 1, 2), standardTime, UTC);
+ QTest::newRow("utc1")
+ << QDateTime(QDate(2004, 1, 1), standardTime, UTC) << (daySecs * 185)
+ << QDateTime(QDate(2004, 7, 4), standardTime, UTC);
+ QTest::newRow("utc2")
+ << QDateTime(QDate(2004, 1, 1), standardTime, UTC) << (daySecs * 366)
+ << QDateTime(QDate(2005, 1, 1), standardTime, UTC);
+ QTest::newRow("utc3")
+ << QDateTime(QDate(1760, 1, 1), standardTime, UTC) << daySecs
+ << QDateTime(QDate(1760, 1, 2), standardTime, UTC);
+ QTest::newRow("utc4")
+ << QDateTime(QDate(1760, 1, 1), standardTime, UTC) << (daySecs * 185)
+ << QDateTime(QDate(1760, 7, 4), standardTime, UTC);
+ QTest::newRow("utc5")
+ << QDateTime(QDate(1760, 1, 1), standardTime, UTC) << (daySecs * 366)
+ << QDateTime(QDate(1761, 1, 1), standardTime, UTC);
+ QTest::newRow("utc6")
+ << QDateTime(QDate(4000, 1, 1), standardTime, UTC) << daySecs
+ << QDateTime(QDate(4000, 1, 2), standardTime, UTC);
+ QTest::newRow("utc7")
+ << QDateTime(QDate(4000, 1, 1), standardTime, UTC) << (daySecs * 185)
+ << QDateTime(QDate(4000, 7, 4), standardTime, UTC);
+ QTest::newRow("utc8")
+ << QDateTime(QDate(4000, 1, 1), standardTime, UTC) << (daySecs * 366)
+ << QDateTime(QDate(4001, 1, 1), standardTime, UTC);
+ QTest::newRow("utc9")
+ << QDateTime(QDate(4000, 1, 1), standardTime, UTC) << qint64(0)
+ << QDateTime(QDate(4000, 1, 1), standardTime, UTC);
+
+ if (zoneIsCET) {
+ QTest::newRow("cet0")
+ << QDateTime(QDate(2004, 1, 1), standardTime) << daySecs
+ << QDateTime(QDate(2004, 1, 2), standardTime);
+ QTest::newRow("cet1")
+ << QDateTime(QDate(2004, 1, 1), standardTime) << (daySecs * 185)
+ << QDateTime(QDate(2004, 7, 4), daylightTime);
+ QTest::newRow("cet2")
+ << QDateTime(QDate(2004, 1, 1), standardTime) << (daySecs * 366)
+ << QDateTime(QDate(2005, 1, 1), standardTime);
+ QTest::newRow("cet3")
+ << QDateTime(QDate(1760, 1, 1), standardTime) << daySecs
+ << QDateTime(QDate(1760, 1, 2), standardTime);
+ QTest::newRow("cet4")
+ << QDateTime(QDate(1760, 1, 1), standardTime) << (daySecs * 185)
+ << QDateTime(QDate(1760, 7, 4), standardTime);
+ QTest::newRow("cet5")
+ << QDateTime(QDate(1760, 1, 1), standardTime) << (daySecs * 366)
+ << QDateTime(QDate(1761, 1, 1), standardTime);
+ QTest::newRow("cet6")
+ << QDateTime(QDate(4000, 1, 1), standardTime) << daySecs
+ << QDateTime(QDate(4000, 1, 2), standardTime);
+ QTest::newRow("cet7")
+ << QDateTime(QDate(4000, 1, 1), standardTime) << (daySecs * 185)
+ << QDateTime(QDate(4000, 7, 4), daylightTime);
+ QTest::newRow("cet8")
+ << QDateTime(QDate(4000, 1, 1), standardTime) << (daySecs * 366)
+ << QDateTime(QDate(4001, 1, 1), standardTime);
+ QTest::newRow("cet9")
+ << QDateTime(QDate(4000, 1, 1), standardTime) << qint64(0)
+ << QDateTime(QDate(4000, 1, 1), standardTime);
+ }
+
+ // Year sign change
+ QTest::newRow("toNegative")
+ << QDateTime(QDate(1, 1, 1), QTime(0, 0), UTC) << qint64(-1)
+ << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59), UTC);
+ QTest::newRow("toPositive")
+ << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59), UTC) << qint64(1)
+ << QDateTime(QDate(1, 1, 1), QTime(0, 0), UTC);
+
+ QTest::newRow("invalid") << QDateTime() << qint64(1) << QDateTime();
+
+ // Check Offset details are preserved
+ QTest::newRow("offset0")
+ << QDateTime(QDate(2013, 1, 1), QTime(1, 2, 3), QTimeZone::fromSecondsAheadOfUtc(60 * 60))
+ << qint64(60 * 60)
+ << QDateTime(QDate(2013, 1, 1), QTime(2, 2, 3), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ // Check last second of 1969
+ QTest::newRow("epoch-1s-utc")
+ << QDate(1970, 1, 1).startOfDay(UTC) << qint64(-1)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59), UTC);
+ QTest::newRow("epoch-1s-local")
+ << QDate(1970, 1, 1).startOfDay() << qint64(-1)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59));
+ QTest::newRow("epoch-1s-utc-as-local")
+ << QDate(1970, 1, 1).startOfDay(UTC).toLocalTime() << qint64(-1)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59), UTC).toLocalTime();
+
+ // Overflow and Underflow
+ const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000;
+ QTest::newRow("after-last")
+ << QDateTime::fromSecsSinceEpoch(maxSeconds, UTC) << qint64(1) << QDateTime();
+ QTest::newRow("to-last")
+ << QDateTime::fromSecsSinceEpoch(maxSeconds - 1, UTC) << qint64(1)
+ << QDateTime::fromSecsSinceEpoch(maxSeconds, UTC);
+ QTest::newRow("before-first")
+ << QDateTime::fromSecsSinceEpoch(-maxSeconds, UTC) << qint64(-1) << QDateTime();
+ QTest::newRow("to-first")
+ << QDateTime::fromSecsSinceEpoch(1 - maxSeconds, UTC) << qint64(-1)
+ << QDateTime::fromSecsSinceEpoch(-maxSeconds, UTC);
+
+#if QT_CONFIG(timezone)
+ if (const QTimeZone cet("Europe/Oslo"); cet.isValid()) {
+ QTest::newRow("CET-spring-forward")
+ << QDateTime(QDate(2023, 3, 26), QTime(1, 30), cet) << qint64(60 * 60)
+ << QDateTime(QDate(2023, 3, 26), QTime(3, 30), cet);
+ QTest::newRow("CET-fall-back")
+ << QDateTime(QDate(2023, 10, 29), QTime(1, 30), cet) << qint64(3 * 60 * 60)
+ << QDateTime(QDate(2023, 10, 29), QTime(3, 30), cet);
+ }
+# ifndef INADEQUATE_TZ_DATA
+ const QTimeZone lint("Pacific/Kiritimati");
+ if (lint.isValid()) {
+ // Line Islands Time skipped Sat 1994-12-31:
+ QTest::newRow("Kiritimati-day-off")
+ << QDateTime(QDate(1994, 12, 30), QTime(23, 30), lint) << qint64(60 * 60)
+ << QDateTime(QDate(1995, 1, 1), QTime(0, 30), lint);
+ }
+# ifndef Q_OS_DARWIN
+ if (const QTimeZone alaska("America/Anchorage"); alaska.isValid()) {
+ // On Julian date 1867, Sat Oct 7 (at 14:31 local solar mean time for
+ // Anchorage, 15:30 LMT in Sitka, which hosted the transfer ceremony)
+ // Russia sold Alaska to the USA, which changed the calendar to
+ // Gregorian, hence the date to Fri Oct 18. Contrast addDays().
+ const QDate sat(1867, 10, 19);
+ Q_ASSERT(sat == QDate(1867, 10, 7, QCalendar(QCalendar::System::Julian)));
+ // At the start of the day, it was Sat 7th; by evening it was Fri 18th;
+ // then the next day was Sat 19th.
+ QTest::newRow("Alaska-Day")
+ // The actual morning of the hand-over:
+ << QDateTime(sat, QTime(6, 0), alaska) << qint64(12 * 60 * 60)
+ // The evening of the same day.
+ << QDateTime(sat, QTime(18, 0), alaska).addDays(-1);
+ }
+# endif // Darwin
+# endif // inadequate zone data
+#endif // timezone
+}
+
+void tst_QDateTime::addSecs_data()
+{
+ addMSecs_data();
+
+ const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000;
+ // Results would be representable, but the step isn't
+ QTest::newRow("leap-up")
+ << QDateTime::fromSecsSinceEpoch(-1, UTC) << 1 + maxSeconds << QDateTime();
+ QTest::newRow("leap-down")
+ << QDateTime::fromSecsSinceEpoch(1, UTC) << -1 - maxSeconds << QDateTime();
+}
+
+void tst_QDateTime::addSecs()
+{
+ QFETCH(const QDateTime, dt);
+ QFETCH(const qint64, nsecs);
+ QFETCH(const QDateTime, result);
+ QDateTime test = dt.addSecs(nsecs);
+ QDateTime test2 = dt + std::chrono::seconds(nsecs);
+ QDateTime test3 = dt;
+ test3 += std::chrono::seconds(nsecs);
+ if (!result.isValid()) {
+ QVERIFY(!test.isValid());
+ QVERIFY(!test2.isValid());
+ QVERIFY(!test3.isValid());
+ } else {
+ QCOMPARE(test, result);
+ QCOMPARE(test2, result);
+ QCOMPARE(test3, result);
+ QCOMPARE(test.timeSpec(), dt.timeSpec());
+ QCOMPARE(test2.timeSpec(), dt.timeSpec());
+ QCOMPARE(test3.timeSpec(), dt.timeSpec());
+ if (test.timeSpec() == Qt::OffsetFromUTC) {
+ QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc());
+ QCOMPARE(test2.offsetFromUtc(), dt.offsetFromUtc());
+ QCOMPARE(test3.offsetFromUtc(), dt.offsetFromUtc());
+ }
+ QCOMPARE(result.addSecs(-nsecs), dt);
+ QCOMPARE(result - std::chrono::seconds(nsecs), dt);
+ test3 -= std::chrono::seconds(nsecs);
+ QCOMPARE(test3, dt);
+ QCOMPARE(dt.secsTo(result), nsecs);
+ }
+}
+
+void tst_QDateTime::addMSecs()
+{
+ QFETCH(const QDateTime, dt);
+ QFETCH(const qint64, nsecs);
+ QFETCH(const QDateTime, result);
+
+ const auto verify = [&](const QDateTime &test) {
+ if (!result.isValid()) {
+ QVERIFY(!test.isValid());
+ } else {
+ QCOMPARE(test, result);
+ QCOMPARE(test.timeSpec(), dt.timeSpec());
+ if (test.timeSpec() == Qt::OffsetFromUTC)
+ QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc());
+ QCOMPARE(result.addMSecs(qint64(-nsecs) * 1000), dt);
+ }
+ };
+#define VERIFY(datum) \
+ verify(datum); \
+ if (QTest::currentTestFailed()) \
+ return
+
+ VERIFY(dt.addMSecs(qint64(nsecs) * 1000));
+ VERIFY(dt.addDuration(std::chrono::seconds(nsecs)));
+ VERIFY(dt.addDuration(std::chrono::milliseconds(nsecs * 1000)));
+#undef VERIFY
+}
+
+#if QT_DEPRECATED_SINCE(6, 9)
+void tst_QDateTime::toTimeSpec_data()
+{
+ if (!zoneIsCET)
+ QSKIP("Not tested with timezone other than Central European (CET/CEST)");
+
+ QTest::addColumn<QDateTime>("fromUtc");
+ QTest::addColumn<QDateTime>("fromLocal");
+
+ QTime utcTime(4, 20, 30);
+ QTime localStandardTime(5, 20, 30);
+ QTime localDaylightTime(6, 20, 30);
+
+ QTest::newRow("winter1")
+ << QDateTime(QDate(2004, 1, 1), utcTime, UTC)
+ << QDateTime(QDate(2004, 1, 1), localStandardTime);
+ QTest::newRow("winter2")
+ << QDateTime(QDate(2004, 2, 29), utcTime, UTC)
+ << QDateTime(QDate(2004, 2, 29), localStandardTime);
+ QTest::newRow("winter3")
+ << QDateTime(QDate(1760, 2, 29), utcTime, UTC)
+ << QDateTime(QDate(1760, 2, 29), localStandardTime.addSecs(preZoneFix));
+ QTest::newRow("winter4")
+ << QDateTime(QDate(6000, 2, 29), utcTime, UTC)
+ << QDateTime(QDate(6000, 2, 29), localStandardTime);
+
+ // Test mktime boundaries (1970 - 2038) and adjustDate().
+ QTest::newRow("1969/12/31 23:00 UTC")
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 0), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0));
+ QTest::newRow("1969/12/31 23:59:59 UTC")
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59), UTC)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59));
+ QTest::newRow("2037/12/31 23:00 UTC")
+ << QDateTime(QDate(2037, 12, 31), QTime(23, 0), UTC)
+ << QDateTime(QDate(2038, 1, 1), QTime(0, 0));
+
+ QTest::newRow("-271821/4/20 00:00 UTC (JavaScript min date, start of day)")
+ << QDateTime(QDate(-271821, 4, 20), QTime(0, 0), UTC)
+ << QDateTime(QDate(-271821, 4, 20), QTime(1, 0)).addSecs(preZoneFix);
+ QTest::newRow("-271821/4/20 23:00 UTC (JavaScript min date, end of day)")
+ << QDateTime(QDate(-271821, 4, 20), QTime(23, 0), UTC)
+ << QDateTime(QDate(-271821, 4, 21), QTime(0, 0)).addSecs(preZoneFix);
+
+ if (zoneIsCET) {
+ QTest::newRow("summer1")
+ << QDateTime(QDate(2004, 6, 30), utcTime, UTC)
+ << QDateTime(QDate(2004, 6, 30), localDaylightTime);
+ QTest::newRow("summer2")
+ << QDateTime(QDate(1760, 6, 30), utcTime, UTC)
+ << QDateTime(QDate(1760, 6, 30), localStandardTime.addSecs(preZoneFix));
+ QTest::newRow("summer3")
+ << QDateTime(QDate(4000, 6, 30), utcTime, UTC)
+ << QDateTime(QDate(4000, 6, 30), localDaylightTime);
+
+ QTest::newRow("275760/9/23 00:00 UTC (JavaScript max date, start of day)")
+ << QDate(275760, 9, 23).startOfDay(UTC)
+ << QDateTime(QDate(275760, 9, 23), QTime(2, 0));
+
+ QTest::newRow("275760/9/23 22:00 UTC (JavaScript max date, end of day)")
+ << QDateTime(QDate(275760, 9, 23), QTime(22, 0), UTC)
+ << QDate(275760, 9, 24).startOfDay();
+ }
+
+ QTest::newRow("msec")
+ << QDateTime(QDate(4000, 6, 30), utcTime.addMSecs(1), UTC)
+ << QDateTime(QDate(4000, 6, 30), localDaylightTime.addMSecs(1));
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QDateTime::toTimeSpec()
+{
+ QFETCH(QDateTime, fromUtc);
+ QFETCH(QDateTime, fromLocal);
+
+ QDateTime utcToUtc = fromUtc.toTimeSpec(Qt::UTC);
+ QDateTime localToLocal = fromLocal.toTimeSpec(Qt::LocalTime);
+ QDateTime utcToLocal = fromUtc.toTimeSpec(Qt::LocalTime);
+ QDateTime localToUtc = fromLocal.toTimeSpec(Qt::UTC);
+ QDateTime utcToOffset = fromUtc.toTimeSpec(Qt::OffsetFromUTC);
+ QDateTime localToOffset = fromLocal.toTimeSpec(Qt::OffsetFromUTC);
+
+ QCOMPARE(utcToUtc, fromUtc);
+ QCOMPARE(utcToUtc.date(), fromUtc.date());
+ QCOMPARE(utcToUtc.time(), fromUtc.time());
+ QCOMPARE(utcToUtc.timeSpec(), Qt::UTC);
+
+ QCOMPARE(localToLocal, fromLocal);
+ QCOMPARE(localToLocal.date(), fromLocal.date());
+ QCOMPARE(localToLocal.time(), fromLocal.time());
+ QCOMPARE(localToLocal.timeSpec(), Qt::LocalTime);
+
+ QCOMPARE(utcToLocal, fromLocal);
+ QCOMPARE(utcToLocal.date(), fromLocal.date());
+ QCOMPARE(utcToLocal.time(), fromLocal.time());
+ QCOMPARE(utcToLocal.timeSpec(), Qt::LocalTime);
+ QCOMPARE(utcToLocal.toTimeSpec(Qt::UTC), fromUtc);
+
+ QCOMPARE(localToUtc, fromUtc);
+ QCOMPARE(localToUtc.date(), fromUtc.date());
+ QCOMPARE(localToUtc.time(), fromUtc.time());
+ QCOMPARE(localToUtc.timeSpec(), Qt::UTC);
+ QCOMPARE(localToUtc.toTimeSpec(Qt::LocalTime), fromLocal);
+
+ QCOMPARE(utcToUtc, localToUtc);
+ QCOMPARE(utcToUtc.date(), localToUtc.date());
+ QCOMPARE(utcToUtc.time(), localToUtc.time());
+ QCOMPARE(utcToUtc.timeSpec(), Qt::UTC);
+
+ QCOMPARE(utcToLocal, localToLocal);
+ QCOMPARE(utcToLocal.date(), localToLocal.date());
+ QCOMPARE(utcToLocal.time(), localToLocal.time());
+ QCOMPARE(utcToLocal.timeSpec(), Qt::LocalTime);
+
+ // OffsetToUTC becomes UTC
+ QCOMPARE(utcToOffset, fromUtc);
+ QCOMPARE(utcToOffset.date(), fromUtc.date());
+ QCOMPARE(utcToOffset.time(), fromUtc.time());
+ QCOMPARE(utcToOffset.timeSpec(), Qt::UTC);
+ QCOMPARE(utcToOffset.toTimeSpec(Qt::UTC), fromUtc);
+
+ QCOMPARE(localToOffset, fromUtc);
+ QCOMPARE(localToOffset.date(), fromUtc.date());
+ QCOMPARE(localToOffset.time(), fromUtc.time());
+ QCOMPARE(localToOffset.timeSpec(), Qt::UTC);
+ QCOMPARE(localToOffset.toTimeSpec(Qt::LocalTime), fromLocal);
+}
+
+void tst_QDateTime::toLocalTime()
+{
+ QFETCH(QDateTime, fromUtc);
+ QFETCH(QDateTime, fromLocal);
+
+ QCOMPARE(fromLocal.toLocalTime(), fromLocal);
+ QCOMPARE(fromUtc.toLocalTime(), fromLocal);
+ QCOMPARE(fromUtc.toLocalTime(), fromLocal.toLocalTime());
+}
+
+void tst_QDateTime::toUTC()
+{
+ QFETCH(QDateTime, fromUtc);
+ QFETCH(QDateTime, fromLocal);
+
+ QCOMPARE(fromUtc.toUTC(), fromUtc);
+ QCOMPARE(fromLocal.toUTC(), fromUtc);
+ QCOMPARE(fromUtc.toUTC(), fromLocal.toUTC());
+}
+
+void tst_QDateTime::toUTC_extra()
+{
+ QDateTime dt = QDateTime::currentDateTime();
+ if (dt.time().msec() == 0)
+ dt.setTime(dt.time().addMSecs(1));
+ QString s = dt.toString("zzz");
+ QString t = dt.toUTC().toString("zzz");
+ QCOMPARE(s, t);
+}
+QT_WARNING_POP
+#endif // 6.9 deprecation
+
+void tst_QDateTime::daysTo()
+{
+ QDateTime dt1(QDate(1760, 1, 2).startOfDay());
+ QDateTime dt2(QDate(1760, 2, 2).startOfDay());
+ QDateTime dt3(QDate(1760, 3, 2).startOfDay());
+
+ QCOMPARE(dt1.daysTo(dt2), (qint64) 31);
+ QCOMPARE(dt1.addDays(31), dt2);
+
+ QCOMPARE(dt2.daysTo(dt3), (qint64) 29);
+ QCOMPARE(dt2.addDays(29), dt3);
+
+ QCOMPARE(dt1.daysTo(dt3), (qint64) 60);
+ QCOMPARE(dt1.addDays(60), dt3);
+
+ QCOMPARE(dt2.daysTo(dt1), (qint64) -31);
+ QCOMPARE(dt2.addDays(-31), dt1);
+
+ QCOMPARE(dt3.daysTo(dt2), (qint64) -29);
+ QCOMPARE(dt3.addDays(-29), dt2);
+
+ QCOMPARE(dt3.daysTo(dt1), (qint64) -60);
+ QCOMPARE(dt3.addDays(-60), dt1);
+}
+
+void tst_QDateTime::secsTo_data()
+{
+ addSecs_data();
+
+ QTest::newRow("disregard milliseconds #1")
+ << QDateTime(QDate(2012, 3, 7), QTime(0, 58)) << qint64(60)
+ << QDateTime(QDate(2012, 3, 7), QTime(0, 59, 0, 400));
+
+ QTest::newRow("disregard milliseconds #2")
+ << QDateTime(QDate(2012, 3, 7), QTime(0, 59)) << qint64(60)
+ << QDateTime(QDate(2012, 3, 7), QTime(1, 0, 0, 400));
+}
+
+void tst_QDateTime::secsTo()
+{
+ QFETCH(const QDateTime, dt);
+ QFETCH(const qint64, nsecs);
+ QFETCH(const QDateTime, result);
+
+ if (result.isValid()) {
+ QCOMPARE(dt.secsTo(result), (qint64)nsecs);
+ QCOMPARE(result.secsTo(dt), (qint64)-nsecs);
+ QVERIFY((dt == result) == (0 == nsecs));
+ QVERIFY((dt != result) == (0 != nsecs));
+ QVERIFY((dt < result) == (0 < nsecs));
+ QVERIFY((dt <= result) == (0 <= nsecs));
+ QVERIFY((dt > result) == (0 > nsecs));
+ QVERIFY((dt >= result) == (0 >= nsecs));
+ } else {
+ QVERIFY(dt.secsTo(result) == 0);
+ QVERIFY(result.secsTo(dt) == 0);
+ }
+}
+
+void tst_QDateTime::msecsTo()
+{
+ QFETCH(const QDateTime, dt);
+ QFETCH(const qint64, nsecs);
+ QFETCH(const QDateTime, result);
+
+ if (result.isValid()) {
+ QCOMPARE(dt.msecsTo(result), qint64(nsecs) * 1000);
+ QCOMPARE(result - dt, std::chrono::milliseconds(nsecs * 1000));
+ QCOMPARE(result.msecsTo(dt), -qint64(nsecs) * 1000);
+ QCOMPARE(dt - result, -std::chrono::milliseconds(nsecs * 1000));
+ QVERIFY((dt == result) == (0 == (qint64(nsecs) * 1000)));
+ QVERIFY((dt != result) == (0 != (qint64(nsecs) * 1000)));
+ QVERIFY((dt < result) == (0 < (qint64(nsecs) * 1000)));
+ QVERIFY((dt <= result) == (0 <= (qint64(nsecs) * 1000)));
+ QVERIFY((dt > result) == (0 > (qint64(nsecs) * 1000)));
+ QVERIFY((dt >= result) == (0 >= (qint64(nsecs) * 1000)));
+ } else {
+ QVERIFY(dt.msecsTo(result) == 0);
+ QCOMPARE(result - dt, std::chrono::milliseconds(0));
+ QVERIFY(result.msecsTo(dt) == 0);
+ QCOMPARE(dt - result, std::chrono::milliseconds(0));
+ }
+}
+
+void tst_QDateTime::orderingCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QDateTime>();
+}
+
+void tst_QDateTime::currentDateTime()
+{
+ time_t buf1, buf2;
+ ::time(&buf1);
+ QDateTime lowerBound;
+ lowerBound.setSecsSinceEpoch(buf1);
+
+ QDateTime dt1 = QDateTime::currentDateTime();
+ QDateTime dt2 = QDateTime::currentDateTime().toLocalTime();
+ QDateTime dt3 = QDateTime::currentDateTime().toUTC();
+
+ ::time(&buf2);
+
+ QDateTime upperBound;
+ upperBound.setSecsSinceEpoch(buf2);
+ // Note we must add 2 seconds here because time() may return up to
+ // 1 second difference from the more accurate method used by QDateTime::currentDateTime()
+ upperBound = upperBound.addSecs(2);
+
+ auto reporter = qScopeGuard([=]() {
+ qInfo("\n"
+ "lowerBound: %lld\n"
+ "dt1: %lld\n"
+ "dt2: %lld\n"
+ "dt3: %lld\n"
+ "upperBound: %lld\n",
+ lowerBound.toSecsSinceEpoch(),
+ dt1.toSecsSinceEpoch(),
+ dt2.toSecsSinceEpoch(),
+ dt3.toSecsSinceEpoch(),
+ upperBound.toSecsSinceEpoch());
+ });
+
+ QCOMPARE_LT(lowerBound, upperBound);
+ QCOMPARE_LE(lowerBound, dt1);
+ QCOMPARE_LT(dt1, upperBound);
+ QCOMPARE_LE(lowerBound, dt2);
+ QCOMPARE_LT(dt2, upperBound);
+ QCOMPARE_LE(lowerBound, dt3);
+ QCOMPARE_LT(dt3, upperBound);
+ reporter.dismiss();
+
+ QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt3.timeSpec(), Qt::UTC);
+}
+
+void tst_QDateTime::currentDateTimeUtc()
+{
+ time_t buf1, buf2;
+ ::time(&buf1);
+
+ QDateTime lowerBound;
+ lowerBound.setSecsSinceEpoch(buf1);
+
+ QDateTime dt1 = QDateTime::currentDateTimeUtc();
+ QDateTime dt2 = QDateTime::currentDateTimeUtc().toLocalTime();
+ QDateTime dt3 = QDateTime::currentDateTimeUtc().toUTC();
+
+ ::time(&buf2);
+
+ QDateTime upperBound;
+ upperBound.setSecsSinceEpoch(buf2);
+ // Note we must add 2 seconds here because time() may return up to
+ // 1 second difference from the more accurate method used by QDateTime::currentDateTime()
+ upperBound = upperBound.addSecs(2);
+
+ auto reporter = qScopeGuard([=]() {
+ qInfo("\n"
+ "lowerBound: %lld\n"
+ "dt1: %lld\n"
+ "dt2: %lld\n"
+ "dt3: %lld\n"
+ "upperBound: %lld\n",
+ lowerBound.toSecsSinceEpoch(),
+ dt1.toSecsSinceEpoch(),
+ dt2.toSecsSinceEpoch(),
+ dt3.toSecsSinceEpoch(),
+ upperBound.toSecsSinceEpoch());
+ });
+
+ QCOMPARE_LT(lowerBound, upperBound);
+ QCOMPARE_LE(lowerBound, dt1);
+ QCOMPARE_LT(dt1, upperBound);
+ QCOMPARE_LE(lowerBound, dt2);
+ QCOMPARE_LT(dt2, upperBound);
+ QCOMPARE_LE(lowerBound, dt3);
+ QCOMPARE_LT(dt3, upperBound);
+ reporter.dismiss();
+
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+ QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
+ QCOMPARE(dt3.timeSpec(), Qt::UTC);
+}
+
+void tst_QDateTime::currentDateTimeUtc2()
+{
+ QDateTime local, utc;
+ qint64 msec;
+
+ // check that we got all down to the same milliseconds
+ int i = 20;
+ bool ok = false;
+ do {
+ local = QDateTime::currentDateTime();
+ utc = QDateTime::currentDateTimeUtc();
+ msec = QDateTime::currentMSecsSinceEpoch();
+ ok = local.time().msec() == utc.time().msec()
+ && utc.time().msec() == (msec % 1000);
+ } while (--i && !ok);
+
+ if (!i)
+ QSKIP("Failed to get the dates within 1 ms of each other");
+
+ // seconds and milliseconds should be the same:
+ QCOMPARE(utc.time().second(), local.time().second());
+ QCOMPARE(utc.time().msec(), local.time().msec());
+ QCOMPARE(msec % 1000, qint64(local.time().msec()));
+ QCOMPARE(msec / 1000 % 60, qint64(local.time().second()));
+
+ // the two dates should be equal, actually
+ QCOMPARE(local.toUTC(), utc);
+ QCOMPARE(utc.toLocalTime(), local);
+
+ // and finally, the SecsSinceEpoch should equal our number
+ QCOMPARE(qint64(utc.toSecsSinceEpoch()), msec / 1000);
+ QCOMPARE(qint64(local.toSecsSinceEpoch()), msec / 1000);
+ QCOMPARE(utc.toMSecsSinceEpoch(), msec);
+ QCOMPARE(local.toMSecsSinceEpoch(), msec);
+}
+
+void tst_QDateTime::toSecsSinceEpoch_data()
+{
+ QTest::addColumn<QDate>("date");
+
+ QTest::newRow("start-1800") << QDate(1800, 1, 1);
+ QTest::newRow("start-1969") << QDate(1969, 1, 1);
+ QTest::newRow("start-2002") << QDate(2002, 1, 1);
+ QTest::newRow("mid-2002") << QDate(2002, 6, 1);
+ QTest::newRow("start-2038") << QDate(2038, 1, 1);
+ QTest::newRow("star-trek-1st-contact") << QDate(2063, 4, 5);
+ QTest::newRow("start-2107") << QDate(2107, 1, 1);
+}
+
+void tst_QDateTime::toSecsSinceEpoch()
+{
+ const QTime noon(12, 0);
+ QFETCH(const QDate, date);
+ const QDateTime dateTime(date, noon);
+ QVERIFY(dateTime.isValid());
+
+ const qint64 asSecsSinceEpoch = dateTime.toSecsSinceEpoch();
+ QCOMPARE(asSecsSinceEpoch, dateTime.toMSecsSinceEpoch() / 1000);
+ QCOMPARE(QDateTime::fromSecsSinceEpoch(asSecsSinceEpoch), dateTime);
+}
+
+void tst_QDateTime::daylightSavingsTimeChange_data()
+{
+ QTest::addColumn<QDate>("inDST");
+ QTest::addColumn<QDate>("outDST");
+ QTest::addColumn<int>("days"); // from in to out; -ve if reversed
+ QTest::addColumn<int>("months");
+
+ QTest::newRow("Autumn") << QDate(2006, 8, 1) << QDate(2006, 12, 1)
+ << 122 << 4;
+
+ QTest::newRow("Spring") << QDate(2006, 5, 1) << QDate(2006, 2, 1)
+ << -89 << -3;
+}
+
+void tst_QDateTime::daylightSavingsTimeChange()
+{
+ // This has grown from a regression test for an old bug where starting with
+ // a date in DST and then moving to a date outside it (or vice-versa) caused
+ // 1-hour jumps in time when addSecs() was called.
+ //
+ // The bug was caused by QDateTime knowing more than it lets show.
+ // Internally, if it knows, QDateTime stores a flag indicating if the time is
+ // DST or not. If it doesn't, it sets to "LocalUnknown". The problem happened
+ // because some functions did not reset the flag when moving in or out of DST.
+
+ // WARNING: This only tests anything if there's a Daylight Savings Time change
+ // in the current time-zone between inDST and outDST.
+ // This is true for Central European Time and may be elsewhere.
+
+ QFETCH(QDate, inDST);
+ QFETCH(QDate, outDST);
+ QFETCH(int, days);
+ QFETCH(int, months);
+
+ // First with simple construction
+ QDateTime dt = outDST.startOfDay();
+ int outDSTsecs = dt.toSecsSinceEpoch();
+
+ dt.setDate(inDST);
+ dt = dt.addSecs(1);
+ QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 1)));
+
+ // now using addDays:
+ dt = dt.addDays(days).addSecs(1);
+ QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 2)));
+
+ // ... and back again:
+ dt = dt.addDays(-days).addSecs(1);
+ QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 3)));
+
+ // now using addMonths:
+ dt = dt.addMonths(months).addSecs(1);
+ QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 4)));
+
+ // ... and back again:
+ dt = dt.addMonths(-months).addSecs(1);
+ QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 5)));
+
+ // now using fromSecsSinceEpoch
+ dt = QDateTime::fromSecsSinceEpoch(outDSTsecs);
+ QCOMPARE(dt, outDST.startOfDay());
+
+ dt.setDate(inDST);
+ dt = dt.addSecs(60);
+ QCOMPARE(dt, QDateTime(inDST, QTime(0, 1)));
+
+ // using addMonths:
+ dt = dt.addMonths(months).addSecs(60);
+ QCOMPARE(dt, QDateTime(outDST, QTime(0, 2)));
+ // back again:
+ dt = dt.addMonths(-months).addSecs(60);
+ QCOMPARE(dt, QDateTime(inDST, QTime(0, 3)));
+
+ // using addDays:
+ dt = dt.addDays(days).addSecs(60);
+ QCOMPARE(dt, QDateTime(outDST, QTime(0, 4)));
+ // back again:
+ dt = dt.addDays(-days).addSecs(60);
+ QCOMPARE(dt, QDateTime(inDST, QTime(0, 5)));
+
+ // Now use the result of a UTC -> LocalTime conversion
+ dt = outDST.startOfDay().toUTC();
+ dt = QDateTime(dt.date(), dt.time(), UTC).toLocalTime();
+ QCOMPARE(dt, QDateTime(outDST, QTime(0, 0)));
+
+ // using addDays:
+ dt = dt.addDays(-days).addSecs(3600);
+ QCOMPARE(dt, QDateTime(inDST, QTime(1, 0)));
+ // back again
+ dt = dt.addDays(days).addSecs(3600);
+ QCOMPARE(dt, QDateTime(outDST, QTime(2, 0)));
+
+ // using addMonths:
+ dt = dt.addMonths(-months).addSecs(3600);
+ QCOMPARE(dt, QDateTime(inDST, QTime(3, 0)));
+ // back again:
+ dt = dt.addMonths(months).addSecs(3600);
+ QCOMPARE(dt, QDateTime(outDST, QTime(4, 0)));
+
+ // using setDate:
+ dt.setDate(inDST);
+ dt = dt.addSecs(3600);
+ QCOMPARE(dt, QDateTime(inDST, QTime(5, 0)));
+}
+
+void tst_QDateTime::springForward_data()
+{
+ QTest::addColumn<QTimeZone>("zone");
+ QTest::addColumn<QDate>("day"); // day of DST transition
+ QTest::addColumn<QTime>("time"); // in the "missing hour"
+ QTest::addColumn<int>("step"); // days to step; +ve from before, -ve from after
+ QTest::addColumn<int>("adjust"); // minutes ahead of UTC on day stepped from
+
+ /*
+ Zone tests compare a summer and winter moment's SecsSinceEpoch to known values.
+ This could in principle be flawed (two DST-using zones in the same
+ hemisphere with the same DST and standard times but different transition
+ times) but no actual example is known where this is a problem. Please
+ document any such conflicts, if discovered.
+
+ See http://www.timeanddate.com/time/zones/ for data on more candidates to
+ test. Note, however, that the IANA DB disagrees with it for some zones,
+ and is authoritative.
+ */
+
+ const QTimeZone local(QTimeZone::LocalTime);
+ const uint winter = QDate(2015, 1, 1).startOfDay(local).toSecsSinceEpoch();
+ const uint summer = QDate(2015, 7, 1).startOfDay(local).toSecsSinceEpoch();
+
+ if (winter == 1420066800 && summer == 1435701600) {
+ QTest::newRow("Local (CET) from day before")
+ << local << QDate(2015, 3, 29) << QTime(2, 30) << 1 << 60;
+ QTest::newRow("Local (CET) from day after")
+ << local << QDate(2015, 3, 29) << QTime(2, 30) << -1 << 120;
+ } else if (winter == 1420063200 && summer == 1435698000) {
+ // EET: but there's some variation in the date and time.
+ // Asia/{Amman,Beirut,Gaza,Hebron}, Europe/Chisinau and Israel: at start of
+ QDate date(2015, 3, 29); // Sunday by default.
+ QTime time(0, 30);
+ if (auto thursday = QDate(2015, 3, 26); thursday.startOfDay(local).time() > time) {
+ // Asia/Damascus: start of March 26th.
+ date = thursday;
+ } else if (auto friday = QDate(2015, 3, 27); friday.startOfDay(local).time() > time) {
+ // Israel, Asia/{Jerusalem,Tel_Aviv}: start of March 27th (IANA DB).
+ date = friday;
+ } else if (friday.startOfDay(local).addSecs(2 * 60 * 60).time() == QTime(3, 0)) {
+ // Israel, Asia/{Jerusalem,Tel_Aviv} according to glibc at 02:00 on March 27th.
+ date = friday;
+ time = QTime(2, 30);
+ } else if (date.startOfDay(local).time() < time) {
+ // Most of Europeean EET, e.g. Finland.
+ time = QTime(3, 30);
+ }
+ QTest::newRow("Local (EET) from day before")
+ << local << date << time << 1 << 120;
+ QTest::newRow("Local (EET) from day after")
+ << local << date << time << -1 << 180;
+ } else if (winter == 1420070400 && summer == 1435705200) {
+ // Western European Time, WET/WEST; a.k.a. GMT/BST
+ QTest::newRow("Local (WET) from day before")
+ << local << QDate(2015, 3, 29) << QTime(1, 30) << 1 << 0;
+ QTest::newRow("Local (WET) from day after")
+ << local << QDate(2015, 3, 29) << QTime(1, 30) << -1 << 60;
+ } else if (winter == 1420099200 && summer == 1435734000) {
+ // Western USA, Canada: Pacific Time (e.g. US/Pacific)
+ QDate date(2015, 3, 8);
+ // America/Ensenada did its transition on April 5th, like the rest of Mexico.
+ if (QDate(2015, 4, 1).startOfDay().toSecsSinceEpoch() == 1427875200)
+ date = QDate(2015, 4, 5);
+ QTest::newRow("Local (PT) from day before")
+ << local << date << QTime(2, 30) << 1 << -480;
+ QTest::newRow("Local (PT) from day after")
+ << local << date << QTime(2, 30) << -1 << -420;
+ } else if (winter == 1420088400 && summer == 1435723200) {
+ // Eastern USA, Canada: Eastern Time (e.g. US/Eastern)
+ // Havana matches offset and date, but at midnight.
+ const QTime start = QDate(2015, 3, 8).startOfDay(local).time();
+ const QTime when = start == QTime(0, 0) ? QTime(2, 30) : QTime(0, 30);
+ QTest::newRow("Local(ET) from day before")
+ << local << QDate(2015, 3, 8) << when << 1 << -300;
+ QTest::newRow("Local(ET) from day after")
+ << local << QDate(2015, 3, 8) << when << -1 << -240;
+#if !QT_CONFIG(timezone)
+ } else {
+ // Includes the numbers you need to test for your zone, as above:
+ QString msg(QString::fromLatin1("No spring forward test data for this TZ (%1, %2)"
+ ).arg(winter).arg(summer));
+ QSKIP(qPrintable(msg));
+#endif
+ }
+#if QT_CONFIG(timezone)
+ if (const QTimeZone cet("Europe/Oslo"); cet.isValid()) {
+ QTest::newRow("CET from day before")
+ << cet << QDate(2015, 3, 29) << QTime(2, 30) << 1 << 60;
+ QTest::newRow("CET from day after")
+ << cet << QDate(2015, 3, 29) << QTime(2, 30) << -1 << 120;
+ }
+ if (const QTimeZone eet("Europe/Helsinki"); eet.isValid()) {
+ QTest::newRow("EET from day before")
+ << eet << QDate(2015, 3, 29) << QTime(3, 30) << 1 << 120;
+ QTest::newRow("EET from day after")
+ << eet << QDate(2015, 3, 29) << QTime(3, 30) << -1 << 180;
+ }
+ if (const QTimeZone wet("Europe/Lisbon"); wet.isValid()) {
+ QTest::newRow("WET from day before")
+ << wet << QDate(2015, 3, 29) << QTime(1, 30) << 1 << 0;
+ QTest::newRow("WET from day after")
+ << wet << QDate(2015, 3, 29) << QTime(1, 30) << -1 << 60;
+ }
+ if (const QTimeZone pacific("America/Vancouver"); pacific.isValid()) {
+ QTest::newRow("PT from day before")
+ << pacific << QDate(2015, 3, 8) << QTime(2, 30) << 1 << -480;
+ QTest::newRow("PT from day after")
+ << pacific << QDate(2015, 3, 8) << QTime(2, 30) << -1 << -420;
+ }
+ if (const QTimeZone eastern("America/Ottawa"); eastern.isValid()) {
+ QTest::newRow("ET from day before")
+ << eastern << QDate(2015, 3, 8) << QTime(2, 30) << 1 << -300;
+ QTest::newRow("ET from day after")
+ << eastern << QDate(2015, 3, 8) << QTime(2, 30) << -1 << -240;
+ }
+#endif
+}
+
+void tst_QDateTime::springForward()
+{
+ QFETCH(QTimeZone, zone);
+ QFETCH(QDate, day);
+ QFETCH(QTime, time);
+ QFETCH(int, step);
+ QFETCH(int, adjust);
+
+ QDateTime direct = QDateTime(day.addDays(-step), time, zone).addDays(step);
+ QVERIFY(direct.isValid());
+ QCOMPARE(direct.date(), day);
+ QCOMPARE(direct.time().minute(), time.minute());
+ QCOMPARE(direct.time().second(), time.second());
+ const int off = step < 0 ? -1 : 1;
+ QCOMPARE(direct.time().hour() - time.hour(), off);
+ // adjust is the offset on the other side of the gap:
+ QCOMPARE(direct.offsetFromUtc(), (adjust + off * 60) * 60);
+
+ // Repeat, but getting there via .toTimeZone(). Apply adjust to datetime,
+ // not time, as the time wraps round if the adjustment crosses midnight.
+ QDateTime detour = QDateTime(day.addDays(-step), time,
+ UTC).addSecs(-60 * adjust).toTimeZone(zone);
+ QCOMPARE(detour.time(), time);
+ detour = detour.addDays(step);
+ // Insist on consistency:
+ QCOMPARE(detour, direct);
+ QCOMPARE(detour.offsetFromUtc(), direct.offsetFromUtc());
+}
+
+void tst_QDateTime::operator_eqeq_data()
+{
+ QTest::addColumn<QDateTime>("dt1");
+ QTest::addColumn<QDateTime>("dt2");
+ QTest::addColumn<bool>("expectEqual");
+ QTest::addColumn<bool>("checkEuro");
+
+ QDateTime dateTime1(QDate(2012, 6, 20), QTime(14, 33, 2, 500));
+ QDateTime dateTime1a = dateTime1.addMSecs(1);
+ QDateTime dateTime2(QDate(2012, 20, 6), QTime(14, 33, 2, 500)); // Invalid
+ QDateTime dateTime2a = dateTime2.addMSecs(-1); // Still invalid
+ QDateTime dateTime3(QDate(1970, 1, 1), QTime(0, 0), UTC); // UTC epoch
+ QDateTime dateTime3a = dateTime3.addDays(1);
+ QDateTime dateTime3b = dateTime3.addDays(-1);
+ // Ensure that different times may be equal when considering timezone.
+ QDateTime dateTime3c(dateTime3.addSecs(3600));
+ dateTime3c.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(3600));
+ QDateTime dateTime3d(dateTime3.addSecs(-3600));
+ dateTime3d.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-3600));
+ QDateTime dateTime3e(dateTime3.date(), dateTime3.time()); // Local time's epoch
+
+ QTest::newRow("data0") << dateTime1 << dateTime1 << true << false;
+ QTest::newRow("data1") << dateTime2 << dateTime2 << true << false;
+ QTest::newRow("data2") << dateTime1a << dateTime1a << true << false;
+ QTest::newRow("data3") << dateTime1 << dateTime2 << false << false;
+ QTest::newRow("data4") << dateTime1 << dateTime1a << false << false;
+ QTest::newRow("data5") << dateTime2 << dateTime2a << true << false;
+ QTest::newRow("data6") << dateTime2 << dateTime3 << false << false;
+ QTest::newRow("data7") << dateTime3 << dateTime3a << false << false;
+ QTest::newRow("data8") << dateTime3 << dateTime3b << false << false;
+ QTest::newRow("data9") << dateTime3a << dateTime3b << false << false;
+ QTest::newRow("data10") << dateTime3 << dateTime3c << true << false;
+ QTest::newRow("data11") << dateTime3 << dateTime3d << true << false;
+ QTest::newRow("data12") << dateTime3c << dateTime3d << true << false;
+ if (epochTimeType == LocalTimeIsUtc)
+ QTest::newRow("data13") << dateTime3 << dateTime3e << true << false;
+ // ... but a zone (sometimes) ahead of or behind UTC (e.g. Europe/London)
+ // might agree with UTC about the epoch, all the same.
+
+ QTest::newRow("invalid == invalid") << QDateTime() << QDateTime() << true << false;
+ QTest::newRow("invalid != valid #1") << QDateTime() << dateTime1 << false << false;
+
+ if (zoneIsCET) {
+ QTest::newRow("data14")
+ << QDateTime(QDate(2004, 1, 2), QTime(2, 2, 3))
+ << QDateTime(QDate(2004, 1, 2), QTime(1, 2, 3), UTC) << true << true;
+ QTest::newRow("local-fall-back") // Sun, 31 Oct 2004, 02:30, both ways round:
+ << QDateTime::fromMSecsSinceEpoch(Q_INT64_C(1099186200000))
+ << QDateTime::fromMSecsSinceEpoch(Q_INT64_C(1099182600000))
+ << false << false;
+ }
+#if QT_CONFIG(timezone)
+ const QTimeZone CET("Europe/Oslo");
+ if (CET.isValid()) {
+ QTest::newRow("CET-fall-back") // Sun, 31 Oct 2004, 02:30, both ways round:
+ << QDateTime::fromMSecsSinceEpoch(Q_INT64_C(1099186200000), CET)
+ << QDateTime::fromMSecsSinceEpoch(Q_INT64_C(1099182600000), CET)
+ << false << false;
+ }
+#endif
+}
+
+void tst_QDateTime::operator_eqeq()
+{
+ QFETCH(QDateTime, dt1);
+ QFETCH(QDateTime, dt2);
+ QFETCH(bool, expectEqual);
+ QFETCH(bool, checkEuro);
+
+ QT_TEST_EQUALITY_OPS(dt1, dt1, true);
+ QT_TEST_EQUALITY_OPS(dt2, dt2, true);
+ QT_TEST_EQUALITY_OPS(dt1, dt2, expectEqual);
+
+ QVERIFY(dt1 != QDateTime::currentDateTime());
+ QVERIFY(dt2 != QDateTime::currentDateTime());
+
+ QVERIFY(dt1.toUTC() == dt1.toUTC());
+
+ if (expectEqual)
+ QVERIFY(qHash(dt1) == qHash(dt2));
+
+ if (checkEuro && zoneIsCET) {
+ QVERIFY(dt1.toUTC() == dt2);
+ QVERIFY(dt1 == dt2.toLocalTime());
+ }
+}
+
+void tst_QDateTime::ordering_data()
+{
+ QTest::addColumn<QDateTime>("left");
+ QTest::addColumn<QDateTime>("right");
+ QTest::addColumn<Qt::weak_ordering>("expectedOrdering");
+
+ Q_CONSTINIT static const auto constructName = [](const QDateTime &dt) -> QByteArray {
+ if (dt.isNull())
+ return "null";
+ if (!dt.isValid())
+ return "invalid";
+ return dt.toString(Qt::ISODateWithMs).toLatin1();
+ };
+
+ Q_CONSTINIT static const auto generateRow =
+ [](const QDateTime &left, const QDateTime &right, Qt::weak_ordering ordering) {
+ const QByteArray leftStr = constructName(left);
+ const QByteArray rightStr = constructName(right);
+ QTest::addRow("%s_vs_%s", leftStr.constData(), rightStr.constData())
+ << left << right << ordering;
+ };
+
+ QDateTime june(QDate(2012, 6, 20), QTime(14, 33, 2, 500));
+ QDateTime juneLater = june.addMSecs(1);
+ QDateTime badDay(QDate(2012, 20, 6), QTime(14, 33, 2, 500)); // Invalid
+ QDateTime epoch(QDate(1970, 1, 1), QTime(0, 0), UTC); // UTC epoch
+ QDateTime nextDay = epoch.addDays(1);
+ QDateTime prevDay = epoch.addDays(-1);
+ // Ensure that different times may be equal when considering timezone.
+ QDateTime epochEast1h(epoch.addSecs(3600));
+ epochEast1h.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(3600));
+ QDateTime epochWest1h(epoch.addSecs(-3600));
+ epochWest1h.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-3600));
+ QDateTime local1970(epoch.date(), epoch.time()); // Local time's epoch
+
+ generateRow(june, june, Qt::weak_ordering::equivalent);
+ generateRow(june, juneLater, Qt::weak_ordering::less);
+ generateRow(june, badDay, Qt::weak_ordering::greater);
+ generateRow(badDay, QDateTime(), Qt::weak_ordering::equivalent);
+ generateRow(june, QDateTime(), Qt::weak_ordering::greater);
+ generateRow(epoch, nextDay, Qt::weak_ordering::less);
+ generateRow(epoch, prevDay, Qt::weak_ordering::greater);
+ generateRow(epoch, epochEast1h, Qt::weak_ordering::equivalent);
+ generateRow(epoch, epochWest1h, Qt::weak_ordering::equivalent);
+ generateRow(epochEast1h, epochWest1h, Qt::weak_ordering::equivalent);
+ if (epochTimeType == LocalTimeIsUtc)
+ generateRow(epoch, local1970, Qt::weak_ordering::equivalent);
+}
+
+void tst_QDateTime::ordering()
+{
+ QFETCH(QDateTime, left);
+ QFETCH(QDateTime, right);
+ QFETCH(Qt::weak_ordering, expectedOrdering);
+
+ QT_TEST_ALL_COMPARISON_OPS(left, right, expectedOrdering);
+}
+
+Q_DECLARE_METATYPE(QDataStream::Version)
+
+void tst_QDateTime::operator_insert_extract_data()
+{
+ QTest::addColumn<int>("yearNumber");
+ QTest::addColumn<QByteArray>("serialiseAs");
+ QTest::addColumn<QByteArray>("deserialiseAs");
+ QTest::addColumn<QDataStream::Version>("dataStreamVersion");
+
+ const QByteArray westernAustralia("AWST-8AWDT-9,M10.5.0,M3.5.0/03:00:00");
+ const QByteArray hawaii("HAW10");
+
+ const QDataStream tmpDataStream;
+ const int thisVersion = tmpDataStream.version();
+ for (int version = QDataStream::Qt_1_0; version <= thisVersion; ++version) {
+ const QDataStream::Version dataStreamVersion = static_cast<QDataStream::Version>(version);
+ const QByteArray vN = QByteArray::number(dataStreamVersion);
+ QTest::addRow("v%d WA => HAWAII %d", version, 2012)
+ << 2012 << westernAustralia << hawaii << dataStreamVersion;
+ QTest::addRow("v%d WA => WA %d", version, 2012)
+ << 2012 << westernAustralia << westernAustralia << dataStreamVersion;
+ QTest::addRow("v%d HAWAII => WA %d", version, -2012)
+ << -2012 << hawaii << westernAustralia << dataStreamVersion;
+ QTest::addRow("v%d HAWAII => HAWAII %d", version, 2012)
+ << 2012 << hawaii << hawaii << dataStreamVersion;
+ }
+}
+
+void tst_QDateTime::operator_insert_extract()
+{
+ QFETCH(int, yearNumber);
+ QFETCH(QByteArray, serialiseAs);
+ QFETCH(QByteArray, deserialiseAs);
+ QFETCH(QDataStream::Version, dataStreamVersion);
+
+ // Start off in a certain timezone.
+ TimeZoneRollback useZone(serialiseAs);
+
+ // It is important that dateTime is created after the time zone shift
+ QDateTime dateTime(QDate(yearNumber, 8, 14), QTime(8, 0));
+ QDateTime dateTimeAsUTC(dateTime.toUTC());
+
+ QByteArray byteArray;
+ {
+ QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
+ dataStream.setVersion(dataStreamVersion);
+ if (dataStreamVersion == QDataStream::Qt_5_0) {
+ // Qt 5 serialises as UTC and converts back to the stored timeSpec when
+ // deserialising; we don't need to do it ourselves...
+ dataStream << dateTime << dateTime;
+ } else {
+ // ... but other versions don't, so we have to here.
+ dataStream << dateTimeAsUTC << dateTimeAsUTC;
+ // We'll also make sure that a deserialised local datetime is the same
+ // time of day (potentially different UTC time), regardless of which
+ // timezone it was serialised in. E.g.: Tue Aug 14 08:00:00 2012
+ // serialised in WST should be deserialised as Tue Aug 14 08:00:00 2012
+ // HST.
+ dataStream << dateTime;
+ }
+ }
+
+ // Ensure that a change in timezone between serialisation and deserialisation
+ // still results in identical UTC-converted datetimes.
+ useZone.reset(deserialiseAs);
+ QDateTime expectedLocalTime(dateTimeAsUTC.toLocalTime()); // *After* resetting zone.
+ QCOMPARE(expectedLocalTime, dateTimeAsUTC); // Different description, same moment in time.
+ {
+ // Deserialise whole QDateTime at once.
+ QDataStream dataStream(&byteArray, QIODevice::ReadOnly);
+ dataStream.setVersion(dataStreamVersion);
+ QDateTime deserialised;
+ dataStream >> deserialised;
+
+ if (dataStreamVersion == QDataStream::Qt_5_0) {
+ // Ensure local time is still correct. Again, Qt 5 handles the timeSpec
+ // conversion (in this case, UTC => LocalTime) for us when deserialising.
+ QCOMPARE(deserialised, expectedLocalTime);
+ } else {
+ if (dataStreamVersion < QDataStream::Qt_4_0) {
+ // Versions lower than Qt 4 don't serialise the timeSpec, instead
+ // assuming that everything is LocalTime.
+ deserialised.setTimeZone(UTC);
+ }
+ // Qt 4.* versions do serialise the timeSpec, so we only need to convert from UTC here.
+ deserialised = deserialised.toLocalTime();
+
+ QCOMPARE(deserialised, expectedLocalTime);
+ }
+ // Sanity check UTC times (operator== already converts its operands to UTC before comparing).
+ QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
+
+ // Deserialise each component individually.
+ QDate deserialisedDate;
+ dataStream >> deserialisedDate;
+ QTime deserialisedTime;
+ dataStream >> deserialisedTime;
+ qint8 deserialisedSpec;
+ if (dataStreamVersion >= QDataStream::Qt_4_0)
+ dataStream >> deserialisedSpec;
+ deserialised = QDateTime(deserialisedDate, deserialisedTime, UTC);
+ QCOMPARE(deserialised.toLocalTime(), deserialised);
+ const auto isLocalTime = [](qint8 spec) -> bool {
+ // The spec is in fact a QDateTimePrivate::Spec, not Qt::TimeSpec;
+ // and no offset or zone is stored, so only UTC and LocalTime are
+ // really supported. Fortunately this test only uses those.
+ const auto decoded = static_cast<QDateTimePrivate::Spec>(spec);
+ return decoded != QDateTimePrivate::UTC && decoded != QDateTimePrivate::OffsetFromUTC;
+ };
+ if (dataStreamVersion >= QDataStream::Qt_4_0 && isLocalTime(deserialisedSpec))
+ deserialised = deserialised.toTimeZone(QTimeZone::LocalTime);
+ // Ensure local time is still correct.
+ QCOMPARE(deserialised, expectedLocalTime);
+ // Sanity check UTC times.
+ QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
+
+ if (dataStreamVersion != QDataStream::Qt_5_0) {
+ // Deserialised local datetime should be the same time of day,
+ // regardless of which timezone it was serialised in.
+ QDateTime localDeserialized;
+ dataStream >> localDeserialized;
+ QCOMPARE(localDeserialized, dateTime);
+ }
+ }
+}
+
+#if QT_CONFIG(datestring)
+void tst_QDateTime::fromStringDateFormat_data()
+{
+ QTest::addColumn<QString>("dateTimeStr");
+ QTest::addColumn<Qt::DateFormat>("dateFormat");
+ QTest::addColumn<QDateTime>("expected");
+
+ // Fails 1970 start dates in western Mexico
+ // due to changing from PST to MST at the start of 1970.
+ const bool goodEpochStart = QDateTime(QDate(1970, 1, 1), QTime(0, 0)).isValid();
+
+ // Test Qt::TextDate format.
+ QTest::newRow("text date") << QString::fromLatin1("Tue Jun 17 08:00:10 2003")
+ << Qt::TextDate << QDateTime(QDate(2003, 6, 17), QTime(8, 0, 10));
+ QTest::newRow("text date Year 0999") << QString::fromLatin1("Tue Jun 17 08:00:10 0999")
+ << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10));
+ QTest::newRow("text date Year 999") << QString::fromLatin1("Tue Jun 17 08:00:10 999")
+ << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10));
+ QTest::newRow("text date Year 12345") << QString::fromLatin1("Tue Jun 17 08:00:10 12345")
+ << Qt::TextDate << QDateTime(QDate(12345, 6, 17), QTime(8, 0, 10));
+ QTest::newRow("text date Year -4712") << QString::fromLatin1("Tue Jan 1 00:01:02 -4712")
+ << Qt::TextDate << QDateTime(QDate(-4712, 1, 1), QTime(0, 1, 2));
+ QTest::newRow("text data1") << QString::fromLatin1("Thu Jan 2 12:34 1970")
+ << Qt::TextDate << QDateTime(QDate(1970, 1, 2), QTime(12, 34));
+ if (goodEpochStart) {
+ QTest::newRow("text epoch year after time")
+ << QString::fromLatin1("Thu Jan 1 00:00:00 1970") << Qt::TextDate
+ << QDate(1970, 1, 1).startOfDay();
+ QTest::newRow("text epoch spaced")
+ << QString::fromLatin1(" Thu Jan 1 00:00:00 1970 ")
+ << Qt::TextDate << QDate(1970, 1, 1).startOfDay();
+ QTest::newRow("text epoch time after year")
+ << QString::fromLatin1("Thu Jan 1 1970 00:00:00")
+ << Qt::TextDate << QDate(1970, 1, 1).startOfDay();
+ }
+ QTest::newRow("text epoch terse")
+ << QString::fromLatin1("Thu Jan 1 00 1970") << Qt::TextDate << QDateTime();
+ QTest::newRow("text epoch stray :00")
+ << QString::fromLatin1("Thu Jan 1 00:00:00:00 1970") << Qt::TextDate << QDateTime();
+ QTest::newRow("text data6") << QString::fromLatin1("Thu Jan 1 00:00:00")
+ << Qt::TextDate << QDateTime();
+ QTest::newRow("text bad offset") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 UTC+foo")
+ << Qt::TextDate << QDateTime();
+ QTest::newRow("text UTC early") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 UTC")
+ << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ QTest::newRow("text UTC-3 early") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 UTC-0300")
+ << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(3, 12, 34), UTC);
+ QTest::newRow("text UTC+3 early") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 UTC+0300")
+ << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(21, 12, 34), UTC);
+ QTest::newRow("text UTC+1 early") << QString::fromLatin1("Thu Jan 1 1970 00:12:34 UTC+0100")
+ << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(23, 12, 34), UTC);
+ // We produce use GMT as prefix, so need to parse it:
+ QTest::newRow("text GMT early")
+ << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT") << Qt::TextDate
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ QTest::newRow("text GMT+3 early")
+ << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+0300") << Qt::TextDate
+ << QDateTime(QDate(1969, 12, 31), QTime(21, 12, 34), UTC);
+ // ... and we match (only) it case-insensitively:
+ QTest::newRow("text gmt early")
+ << QString::fromLatin1("Thu Jan 1 00:12:34 1970 gmt") << Qt::TextDate
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+
+ QTest::newRow("text empty") << QString::fromLatin1("")
+ << Qt::TextDate << QDateTime();
+ QTest::newRow("text too many parts") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 UTC +0100")
+ << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid month name") << QString::fromLatin1("Thu Jaz 1 1970 00:12:34")
+ << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid date") << QString::fromLatin1("Thu Jan 32 1970 00:12:34")
+ << Qt::TextDate << QDateTime();
+ QTest::newRow("text pre-5.2 MS-Win format") // Support dropped in 6.2
+ << QString::fromLatin1("Thu 1. Jan 00:00:00 1970") << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid day")
+ << QString::fromLatin1("Thu Jan XX 1970 00:12:34") << Qt::TextDate << QDateTime();
+ QTest::newRow("text misplaced day")
+ << QString::fromLatin1("Thu 1 Jan 00:00:00 1970") << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid year end")
+ << QString::fromLatin1("Thu Jan 1 00:00:00 19X0") << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid year early")
+ << QString::fromLatin1("Thu Jan 1 19X0 00:00:00") << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid hour")
+ << QString::fromLatin1("Thu Jan 1 1970 0X:00:00") << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid minute")
+ << QString::fromLatin1("Thu Jan 1 1970 00:0X:00") << Qt::TextDate << QDateTime();
+ QTest::newRow("text invalid second")
+ << QString::fromLatin1("Thu Jan 1 1970 00:00:0X") << Qt::TextDate << QDateTime();
+ QTest::newRow("text non-UTC offset")
+ << QString::fromLatin1("Thu Jan 1 1970 00:00:00 DMT") << Qt::TextDate << QDateTime();
+ QTest::newRow("text bad UTC offset")
+ << QString::fromLatin1("Thu Jan 1 1970 00:00:00 UTCx0200") << Qt::TextDate << QDateTime();
+ QTest::newRow("text bad UTC hour")
+ << QString::fromLatin1("Thu Jan 1 1970 00:00:00 UTC+0X00") << Qt::TextDate << QDateTime();
+ QTest::newRow("text bad UTC minute")
+ << QString::fromLatin1("Thu Jan 1 1970 00:00:00 UTC+000X") << Qt::TextDate << QDateTime();
+
+ QTest::newRow("text second fraction")
+ << QString::fromLatin1("Mon May 6 2013 01:02:03.456")
+ << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456));
+ QTest::newRow("text max milli")
+ << QString::fromLatin1("Mon May 6 2013 01:02:03.999499999")
+ << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 999));
+ QTest::newRow("text milli wrap")
+ << QString::fromLatin1("Mon May 6 2013 01:02:03.9995")
+ << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 4));
+ QTest::newRow("text last milli") // Special case, don't round up to invalid:
+ << QString::fromLatin1("Mon May 6 2013 23:59:59.9999999999")
+ << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(23, 59, 59, 999));
+ QTest::newRow("text Sunday lunch")
+ << QStringLiteral("Sun Dec 1 13:02:00 1974") << Qt::TextDate
+ << QDateTime(QDate(1974, 12, 1), QTime(13, 2));
+
+ // Test Qt::ISODate format.
+ QTest::newRow("trailing space") // QTBUG-80445
+ << QString("2000-01-02 03:04:05.678 ") << Qt::ISODate << QDateTime();
+
+ // Invalid spaces (but keeping field widths correct):
+ QTest::newRow("space before millis")
+ << QString("2000-01-02 03:04:05. 678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space after seconds")
+ << QString("2000-01-02 03:04:5 .678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space before seconds")
+ << QString("2000-01-02 03:04: 5.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space after minutes")
+ << QString("2000-01-02 03:4 :05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space before minutes")
+ << QString("2000-01-02 03: 4:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space after hour")
+ << QString("2000-01-02 3 :04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space before hour")
+ << QString("2000-01-02 3:04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space after day")
+ << QString("2000-01-2 03:04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space before day")
+ << QString("2000-01- 2 03:04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space after month")
+ << QString("2000-1 -02 03:04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space before month")
+ << QString("2000- 1-02 03:04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("space after year")
+ << QString("200 -01-02 03:04:05.678") << Qt::ISODate << QDateTime();
+
+ // Spaces as separators:
+ QTest::newRow("sec-milli space")
+ << QString("2000-01-02 03:04:05 678") << Qt::ISODate
+ << QDateTime();
+ QTest::newRow("min-sec space")
+ << QString("2000-01-02 03:04 05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("hour-min space")
+ << QString("2000-01-02 03 04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("mon-day space")
+ << QString("2000-01 02 03:04:05.678") << Qt::ISODate << QDateTime();
+ QTest::newRow("year-mon space")
+ << QString("2000 01-02 03:04:05.678") << Qt::ISODate << QDateTime();
+
+ // Normal usage:
+ QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00")
+ << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("ISO +00:01") << QString::fromLatin1("1987-02-13T13:24:51+00:01")
+ << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(13, 23, 51), UTC);
+ QTest::newRow("ISO -01:00") << QString::fromLatin1("1987-02-13T13:24:51-01:00")
+ << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), UTC);
+ QTest::newRow("ISO -00:01") << QString::fromLatin1("1987-02-13T13:24:51-00:01")
+ << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(13, 25, 51), UTC);
+ QTest::newRow("ISO +0000") << QString::fromLatin1("1970-01-01T00:12:34+0000")
+ << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ QTest::newRow("ISO +00:00") << QString::fromLatin1("1970-01-01T00:12:34+00:00")
+ << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ QTest::newRow("ISO -03") << QString::fromLatin1("2014-12-15T12:37:09-03")
+ << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9), UTC);
+ QTest::newRow("ISO zzz-03") << QString::fromLatin1("2014-12-15T12:37:09.745-03")
+ << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9, 745), UTC);
+ QTest::newRow("ISO -3") << QString::fromLatin1("2014-12-15T12:37:09-3")
+ << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9), UTC);
+ QTest::newRow("ISO zzz-3") << QString::fromLatin1("2014-12-15T12:37:09.745-3")
+ << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9, 745), UTC);
+ QTest::newRow("ISO lower-case") << QString::fromLatin1("2005-06-28T07:57:30.002z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), UTC);
+ // No time specified - defaults to Qt::LocalTime.
+ QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01")
+ << Qt::ISODate << QDate(2002, 10, 1).startOfDay();
+ // Excess digits in milliseconds, round correctly:
+ QTest::newRow("ISO") << QString::fromLatin1("2005-06-28T07:57:30.0010000000Z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), UTC);
+ QTest::newRow("ISO rounding") << QString::fromLatin1("2005-06-28T07:57:30.0015Z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), UTC);
+ // ... and accept comma as separator:
+ QTest::newRow("ISO with comma 1") << QString::fromLatin1("2005-06-28T07:57:30,0040000000Z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4), UTC);
+ QTest::newRow("ISO with comma 2") << QString::fromLatin1("2005-06-28T07:57:30,0015Z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), UTC);
+ QTest::newRow("ISO with comma 3") << QString::fromLatin1("2005-06-28T07:57:30,0014Z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), UTC);
+ QTest::newRow("ISO with comma 4") << QString::fromLatin1("2005-06-28T07:57:30,1Z")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 100), UTC);
+ QTest::newRow("ISO with comma 5") << QString::fromLatin1("2005-06-28T07:57:30,11")
+ << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 110));
+ // 24:00:00 Should be next day according to ISO 8601 section 4.2.3.
+ QTest::newRow("ISO 24:00") << QString::fromLatin1("2012-06-04T24:00:00")
+ << Qt::ISODate << QDate(2012, 6, 5).startOfDay();
+#if QT_CONFIG(timezone)
+ const QByteArray sysId = QTimeZone::systemTimeZoneId();
+ const bool midnightSkip = sysId == "America/Sao_Paulo" || sysId == "America/Asuncion"
+ || sysId == "America/Cordoba" || sysId == "America/Argentina/Cordoba"
+ || sysId == "America/Campo_Grande"
+ || sysId == "America/Cuiaba" || sysId == "America/Buenos_Aires"
+ || sysId == "America/Argentina/Buenos_Aires"
+ || sysId == "America/Argentina/Tucuman" || sysId == "Brazil/East";
+ QTest::newRow("ISO 24:00 in DST") // Midnight spring forward in some of South America.
+ << QString::fromLatin1("2008-10-18T24:00") << Qt::ISODate
+ << QDateTime(QDate(2008, 10, 19), QTime(midnightSkip ? 1 : 0, 0));
+#endif
+ QTest::newRow("ISO 24:00 end of month")
+ << QString::fromLatin1("2012-06-30T24:00:00")
+ << Qt::ISODate << QDate(2012, 7, 1).startOfDay();
+ QTest::newRow("ISO 24:00 end of year")
+ << QString::fromLatin1("2012-12-31T24:00:00")
+ << Qt::ISODate << QDate(2013, 1, 1).startOfDay();
+ QTest::newRow("ISO 24:00, fract ms")
+ << QString::fromLatin1("2012-01-01T24:00:00.000")
+ << Qt::ISODate << QDate(2012, 1, 2).startOfDay();
+ QTest::newRow("ISO 24:00 end of year, fract ms")
+ << QString::fromLatin1("2012-12-31T24:00:00.000")
+ << Qt::ISODate << QDate(2013, 1, 1).startOfDay();
+ // Test fractional seconds.
+ QTest::newRow("ISO .0 of a second (period)")
+ << QString::fromLatin1("2012-01-01T08:00:00.0")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0));
+ QTest::newRow("ISO .00 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.00")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0));
+ QTest::newRow("ISO .000 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.000")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0));
+ QTest::newRow("ISO .1 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,1")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 100));
+ QTest::newRow("ISO .99 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,99")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 990));
+ QTest::newRow("ISO .998 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,998")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 998));
+ QTest::newRow("ISO .999 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,999")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 999));
+ QTest::newRow("ISO .3335 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,3335")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 334));
+ QTest::newRow("ISO .333333 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,333333")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 333));
+ QTest::newRow("ISO .00009 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.00009")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0));
+ QTest::newRow("ISO second fraction") << QString::fromLatin1("2013-05-06T01:02:03.456")
+ << Qt::ISODate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456));
+ QTest::newRow("ISO max milli")
+ << QString::fromLatin1("2013-05-06T01:02:03.999499999")
+ << Qt::ISODate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 999));
+ QTest::newRow("ISO milli wrap")
+ << QString::fromLatin1("2013-05-06T01:02:03.9995")
+ << Qt::ISODate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 4));
+ QTest::newRow("ISO last milli") // Does round up and overflow into new day:
+ << QString::fromLatin1("2013-05-06T23:59:59.9999999999")
+ << Qt::ISODate << QDate(2013, 5, 7).startOfDay();
+ QTest::newRow("ISO no fraction specified")
+ << QString::fromLatin1("2012-01-01T08:00:00.") << Qt::ISODate << QDateTime();
+ // Test invalid characters (should ignore invalid characters at end of string).
+ QTest::newRow("ISO invalid character at end") << QString::fromLatin1("2012-01-01T08:00:00!")
+ << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO invalid character at front") << QString::fromLatin1("!2012-01-01T08:00:00")
+ << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO invalid character both ends") << QString::fromLatin1("!2012-01-01T08:00:00!")
+ << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO invalid character at front, 2 at back") << QString::fromLatin1("!2012-01-01T08:00:00..")
+ << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO invalid character 2 at front") << QString::fromLatin1("!!2012-01-01T08:00:00")
+ << Qt::ISODate << QDateTime();
+ // Test fractional minutes.
+ QTest::newRow("ISO .0 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.0")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0));
+ QTest::newRow("ISO .8 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.8")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48));
+ QTest::newRow("ISO .99999 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.99999")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999));
+ QTest::newRow("ISO .0 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,0")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0));
+ QTest::newRow("ISO .8 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,8")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48));
+ QTest::newRow("ISO .99999 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,99999")
+ << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999));
+ QTest::newRow("ISO empty") << QString::fromLatin1("") << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO short") << QString::fromLatin1("2017-07-01T") << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO zoned date")
+ << QString::fromLatin1("2017-07-01Z") << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO zoned empty time")
+ << QString::fromLatin1("2017-07-01TZ") << Qt::ISODate << QDateTime();
+ QTest::newRow("ISO mis-punctuated")
+ << QString::fromLatin1("2018/01/30 ") << Qt::ISODate << QDateTime();
+
+ // Test Qt::RFC2822Date format (RFC 2822).
+ QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("RFC 2822 after space +0100")
+ << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("RFC 2822 with day +0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("RFC 2822 with day after space +0100")
+ << QString::fromLatin1(" Fri, 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("RFC 2822 -0100") << QString::fromLatin1("13 Feb 1987 13:24:51 -0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), UTC);
+ QTest::newRow("RFC 2822 with day -0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 -0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), UTC);
+ QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ QTest::newRow("RFC 2822 missing space before +0100")
+ << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34+0100") << Qt::RFC2822Date << QDateTime();
+ // No timezone assume UTC
+ QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ // No time specified
+ QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
+ << Qt::RFC2822Date << QDateTime();
+
+ QTest::newRow("RFC 2822 malformed time (truncated)")
+ << QString::fromLatin1("01 Nov 2002 0:") << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 malformed time (hour)")
+ << QString::fromLatin1("01 Nov 2002 7:35:21") << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 malformed time (minute)")
+ << QString::fromLatin1("01 Nov 2002 07:5:21") << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 malformed time (second)")
+ << QString::fromLatin1("01 Nov 2002 07:35:1") << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 malformed time (fraction-second)")
+ << QString::fromLatin1("01 Nov 2002 07:35:15.200") << Qt::RFC2822Date << QDateTime();
+
+ // Test invalid month, day, year
+ QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ // Test invalid characters.
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 invalid character at front")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 invalid character both ends")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 2822 invalid character 2 at front")
+ << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 2822 (not invalid)")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0), UTC);
+
+ // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive).
+ QTest::newRow("RFC 850 and 1036 +0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("RFC 1036 after space +0100")
+ << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), UTC);
+ QTest::newRow("RFC 850 and 1036 -0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 -0100")
+ << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), UTC);
+ QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ // No timezone assume UTC
+ QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
+ << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), UTC);
+ // No time specified
+ QTest::newRow("RFC 850 and 1036 date only")
+ << QString::fromLatin1("Fri Nov 01 2002")
+ << Qt::RFC2822Date << QDateTime();
+ // Test invalid characters.
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character at front")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character both ends")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..")
+ << Qt::RFC2822Date << QDateTime();
+ QTest::newRow("RFC 850 and 1036 invalid character 2 at front")
+ << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDateTime();
+ // Again, check the text in the "invalid character" tests isn't the source of invalidity:
+ QTest::newRow("RFC 850 and 1036 (not invalid)")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0), UTC);
+
+ QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDateTime();
+}
+
+void tst_QDateTime::fromStringDateFormat()
+{
+ QFETCH(QString, dateTimeStr);
+ QFETCH(Qt::DateFormat, dateFormat);
+ QFETCH(QDateTime, expected);
+
+ QDateTime dateTime = QDateTime::fromString(dateTimeStr, dateFormat);
+ QCOMPARE(dateTime, expected);
+}
+
+# if QT_CONFIG(datetimeparser)
+void tst_QDateTime::fromStringStringFormat_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<int>("baseYear");
+ QTest::addColumn<QDateTime>("expected");
+
+ // Indian/Cocos had a transition at the start of 1900, so its Jan 1st starts
+ // at 00:02:20 on that day; this leads to perverse results. QTBUG-77948.
+ if (const QDate defDate(1900, 1, 1); defDate.startOfDay().time() == QTime(0, 0)) {
+ QTest::newRow("dMyy-only:19")
+ << u"101010"_s << u"dMyy"_s << 1900 << QDate(1910, 10, 10).startOfDay();
+ QTest::newRow("dMyy-only:20")
+ << u"101010"_s << u"dMyy"_s << 1911 << QDate(2010, 10, 10).startOfDay();
+ QTest::newRow("secs-repeat-valid")
+ << u"1010"_s << u"sss"_s << 1900 << QDateTime(defDate, QTime(0, 0, 10));
+ QTest::newRow("pm-only")
+ << u"pm"_s << u"ap"_s << 1900 << QDateTime(defDate, QTime(12, 0));
+ QTest::newRow("date-only:19")
+ << u"10 Oct 10"_s << u"dd MMM yy"_s << 1900 << QDate(1910, 10, 10).startOfDay();
+ QTest::newRow("date-only:20")
+ << u"10 Oct 10"_s << u"dd MMM yy"_s << 1950 << QDate(2010, 10, 10).startOfDay();
+ QTest::newRow("dow-date-only")
+ << u"Fri December 3 2004"_s << u"ddd MMMM d yyyy"_s << 1900
+ << QDate(2004, 12, 3).startOfDay();
+ QTest::newRow("dow-mon-yr-only")
+ << u"Thu January 2004"_s << u"ddd MMMM yyyy"_s << 1900
+ << QDate(2004, 1, 1).startOfDay();
+ }
+ QTest::newRow("yy=24/Mar/20") // QTBUG-123579
+ << u"Wed, 20 Mar 24 16:17:00"_s << u"ddd, dd MMM yy HH:mm:ss"_s << 1900
+ << QDateTime(QDate(2024, 3, 20), QTime(16, 17));
+ QTest::newRow("secs-conflict") << u"1020"_s << u"sss"_s << 1900 << QDateTime();
+ QTest::newRow("secs-split-conflict")
+ << u"10hello20"_s << u"ss'hello'ss"_s << 1900 << QDateTime();
+ QTest::newRow("nomatch-quote-twice") << u"10"_s << u"''"_s << 1900 << QDateTime();
+ QTest::newRow("momatch-quote") << u"10"_s << u"'"_s << 1900 << QDateTime();
+ QTest::newRow("nomatch-am-pm") << u"foo"_s << u"ap"_s << 1900 << QDateTime();
+ // Day non-conflict should not hide earlier year conflict (1963-03-01 was a
+ // Friday; asking for Thursday moves this, without conflict, to the 7th):
+ QTest::newRow("year-conflict")
+ << u"77 03 1963 Thu"_s << u"yy MM yyyy ddd"_s << 1900 << QDateTime();
+ QTest::newRow("Feb-overflow") << u"30.02.2004"_s << u"dd.MM.yyyy"_s << 1900 << QDateTime();
+ QTest::newRow("Jan-overflow") << u"32.01.2004"_s << u"dd.MM.yyyy"_s << 1900 << QDateTime();
+ QTest::newRow("zulu-time-with-z-centisec")
+ << u"2005-06-28T07:57:30.01Z"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 10), UTC);
+ QTest::newRow("zulu-time-with-zz-decisec")
+ << u"2005-06-28T07:57:30.1Z"_s << u"yyyy-MM-ddThh:mm:ss.zzt"_s << 1900
+ << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 100), UTC);
+ QTest::newRow("zulu-time-with-zzz-centisec")
+ << u"2005-06-28T07:57:30.01Z"_s << u"yyyy-MM-ddThh:mm:ss.zzzt"_s << 1900
+ << QDateTime(); // Invalid because too few digits for zzz
+ QTest::newRow("zulu-time-with-z-millisec")
+ << u"2005-06-28T07:57:30.001Z"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 1), UTC);
+ QTest::newRow("utc-time-spec-as:UTC+0")
+ << u"2005-06-28T07:57:30.001UTC+0"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), UTC);
+ QTest::newRow("utc-time-spec-as:UTC-0")
+ << u"2005-06-28T07:57:30.001UTC-0"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), UTC);
+ QTest::newRow("offset-from-utc:UTC+1")
+ << u"2001-09-13T07:33:01.001 UTC+1"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime(QDate(2001, 9, 13), QTime(7, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(3600));
+ QTest::newRow("offset-from-utc:UTC-11:01")
+ << u"2008-09-13T07:33:01.001 UTC-11:01"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime(QDate(2008, 9, 13), QTime(7, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(-39660));
+ QTest::newRow("offset-from-utc:UTC+02:57")
+ << u"2001-09-15T09:33:01.001UTC+02:57"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2001, 9, 15), QTime(9, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(10620));
+ QTest::newRow("offset-from-utc:-03:00") // RFC 3339 offset format
+ << u"2001-09-15T09:33:01.001-03:00"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2001, 9, 15), QTime(9, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(-10800));
+ QTest::newRow("offset-from-utc:+0205") // ISO 8601 basic offset format
+ << u"2001-09-15T09:33:01.001+0205"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2001, 9, 15), QTime(9, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(7500));
+ QTest::newRow("offset-from-utc:-0401") // ISO 8601 basic offset format
+ << u"2001-09-15T09:33:01.001-0401"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime(QDate(2001, 9, 15), QTime(9, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(-14460));
+ QTest::newRow("offset-from-utc:+10") // ISO 8601 basic (hour-only) offset format
+ << u"2001-09-15T09:33:01.001 +10"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime(QDate(2001, 9, 15), QTime(9, 33, 1, 1),
+ QTimeZone::fromSecondsAheadOfUtc(36000));
+ QTest::newRow("offset-from-utc:UTC+10:00") // Time-spec specifier at the beginning
+ << u"UTC+10:00 2008-10-13T07:33"_s << u"t yyyy-MM-ddThh:mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(7, 33),
+ QTimeZone::fromSecondsAheadOfUtc(36000));
+ QTest::newRow("offset-from-utc:UTC-03:30") // Time-spec specifier in the middle
+ << u"2008-10-13 UTC-03:30 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(-12600));
+ QTest::newRow("offset-from-utc:UTC-2") // Time-spec specifier joined with text/time
+ << u"2008-10-13 UTC-2Z11.50"_s << u"yyyy-MM-dd tZhh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(-7200));
+ QTest::newRow("offset-from-utc:followed-by-colon")
+ << u"2008-10-13 UTC-0100:11.50"_s << u"yyyy-MM-dd t:hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(-3600));
+ QTest::newRow("offset-from-utc:late-colon")
+ << u"2008-10-13 UTC+05T:11.50"_s << u"yyyy-MM-dd tT:hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(18000));
+ QTest::newRow("offset-from-utc:merged-with-time")
+ << u"2008-10-13 UTC+010011.50"_s << u"yyyy-MM-dd thh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(3600));
+ QTest::newRow("offset-from-utc:double-colon-delimiter")
+ << u"2008-10-13 UTC+12::11.50"_s << u"yyyy-MM-dd t::hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(43200));
+ QTest::newRow("offset-from-utc:3-digit-with-colon")
+ << u"2008-10-13 -4:30 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(-16200));
+ QTest::newRow("offset-from-utc:with-colon-merged-with-time")
+ << u"2008-10-13 UTC+01:0011.50"_s << u"yyyy-MM-dd thh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ QTimeZone::fromSecondsAheadOfUtc(3600));
+ QTest::newRow("invalid-offset-from-utc:out-of-range")
+ << u"2001-09-15T09:33:01.001-50"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:single-digit-format")
+ << u"2001-09-15T09:33:01.001+5"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:three-digit-format")
+ << u"2001-09-15T09:33:01.001-701"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:three-digit-minutes")
+ << u"2001-09-15T09:33:01.001+11:570"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:single-digit-minutes")
+ << u"2001-09-15T09:33:01.001+11:5"_s << u"yyyy-MM-ddThh:mm:ss.zt"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:invalid-sign-symbol")
+ << u"2001-09-15T09:33:01.001 ~11:30"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:symbol-in-hours")
+ << u"2001-09-15T09:33:01.001 UTC+o8:30"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:symbol-in-minutes")
+ << u"2001-09-15T09:33:01.001 UTC+08:3i"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:UTC+123") // Invalid offset (UTC and 3 digit format)
+ << u"2001-09-15T09:33:01.001 UTC+123"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:UTC+00005") // Invalid offset with leading zeroes
+ << u"2001-09-15T09:33:01.001 UTC+00005"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:three-digit-with-colon-delimiter")
+ << u"2008-10-13 +123:11.50"_s << u"yyyy-MM-dd t:hh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:double-colon-as-part-of-offset")
+ << u"2008-10-13 UTC+12::11.50"_s << u"yyyy-MM-dd thh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:single-colon-as-part-of-offset")
+ << u"2008-10-13 UTC+12::11.50"_s << u"yyyy-MM-dd t:hh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:starts-with-colon")
+ << u"2008-10-13 UTC+:59 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:empty-offset")
+ << u"2008-10-13 UTC+ 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:time-section-instead-of-offset")
+ << u"2008-10-13 UTC+11.50"_s << u"yyyy-MM-dd thh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:missing-minutes-if-colon")
+ << u"2008-10-13 +05: 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:1-digit-minutes-if-colon")
+ << u"2008-10-13 UTC+05:1 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-time-spec:random-symbol")
+ << u"2001-09-15T09:33:01.001 $"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-time-spec:random-digit")
+ << u"2001-09-15T09:33:01.001 1"_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900
+ << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:merged-with-time")
+ << u"2008-10-13 UTC+0111.50"_s << u"yyyy-MM-dd thh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-offset-from-utc:with-colon-3-digit-merged-with-time")
+ << u"2008-10-13 UTC+01:011.50"_s << u"yyyy-MM-dd thh.mm"_s << 1900 << QDateTime();
+ QTest::newRow("invalid-time-spec:empty")
+ << u"2001-09-15T09:33:01.001 "_s << u"yyyy-MM-ddThh:mm:ss.z t"_s << 1900 << QDateTime();
+#if QT_CONFIG(timezone)
+ QTimeZone southBrazil("America/Sao_Paulo");
+ if (southBrazil.isValid()) {
+ QTest::newRow("spring-forward-midnight")
+ // NB: no hour field, so hour takes its default, 0, so that
+ // default can be over-ridden:
+ << u"2008-10-19 23:45.678 America/Sao_Paulo"_s << u"yyyy-MM-dd mm:ss.zzz t"_s << 1900
+ // That's in the hour skipped - expect the matching time after
+ // the spring-forward, in DST:
+ << QDateTime(QDate(2008, 10, 19), QTime(1, 23, 45, 678), southBrazil);
+ }
+
+ QTimeZone berlintz("Europe/Berlin");
+ if (berlintz.isValid()) {
+ QTest::newRow("begin-of-high-summer-time-with-tz")
+ << u"1947-05-11 03:23:45.678 Europe/Berlin"_s << u"yyyy-MM-dd hh:mm:ss.zzz t"_s
+ // That's in the hour skipped - expecting an invalid DateTime
+ << 1900 << QDateTime(QDate(1947, 5, 11), QTime(3, 23, 45, 678), berlintz);
+ }
+#endif
+ QTest::newRow("late")
+ << u"9999-12-31T23:59:59.999Z"_s << u"yyyy-MM-ddThh:mm:ss.zZ"_s << 1900
+ << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
+ // Separators match /([^aAdhHMmstyz]*)/
+ QTest::newRow("oddly-separated") // To show broken-separator's format is valid.
+ << u"2018 wilful long working block relief 12-19T21:09 cruel blurb encore flux"_s
+ << u"yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux"_s
+ << 1900 << QDateTime(QDate(2018, 12, 19), QTime(21, 9));
+ QTest::newRow("broken-separator")
+ << u"2018 wilful"_s
+ << u"yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux"_s
+ << 1900 << QDateTime();
+ QTest::newRow("broken-terminator")
+ << u"2018 wilful long working block relief 12-19T21:09 cruel"_s
+ << u"yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux"_s
+ << 1900 << QDateTime();
+
+ // test unicode
+ QTest::newRow("unicode handling")
+ << QString(u8"2005🤣06🤣28T07🤣57🤣30.001Z")
+ << QString(u8"yyyy🤣MM🤣ddThh🤣mm🤣ss.zt") << 1900
+ << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), UTC);
+
+ // Two tests derived from malformed ASN.1 strings (QTBUG-84349):
+ QTest::newRow("curft+ASN.1:UTC")
+ << u"22+221102233Z"_s << u"yyMMddHHmmsst"_s << 1900 << QDateTime();
+ QTest::newRow("curft+ASN.1:Generalized")
+ << u"9922+221102233Z"_s << u"yyyyMMddHHmmsst"_s << 1900 << QDateTime();
+ // Verify baseYear needed by plain ASN.1 works:
+ QTest::newRow("ASN.1:UTC-start")
+ << u"500101000000Z"_s << u"yyMMddHHmmsst"_s << 1950
+ << QDate(1950, 1, 1).startOfDay(QTimeZone::UTC);
+ QTest::newRow("ASN.1:UTC-end")
+ << u"491231235959Z"_s << u"yyMMddHHmmsst"_s << 1950
+ << QDate(2049, 12, 31).endOfDay(QTimeZone::UTC).addMSecs(-999);
+
+ // fuzzer test
+ QTest::newRow("integer overflow found by fuzzer")
+ << u"EEE1200000MUB"_s << u"t"_s << 1900 << QDateTime();
+
+ // Rich time-zone specifiers (QTBUG-95966):
+ const auto east3hours = QTimeZone::fromSecondsAheadOfUtc(10800);
+ QTest::newRow("timezone-tt-with-offset:+0300")
+ << u"2008-10-13 +0300 11.50"_s << u"yyyy-MM-dd tt hh.mm"_s
+ << 1900 << QDateTime(QDate(2008, 10, 13), QTime(11, 50), east3hours);
+ QTest::newRow("timezone-ttt-with-offset:+03:00")
+ << u"2008-10-13 +03:00 11.50"_s << u"yyyy-MM-dd ttt hh.mm"_s
+ << 1900 << QDateTime(QDate(2008, 10, 13), QTime(11, 50), east3hours);
+ QTest::newRow("timezone-tttt-with-offset:+03:00")
+ << u"2008-10-13 +03:00 11.50"_s << u"yyyy-MM-dd tttt hh.mm"_s
+ << 1900 << QDateTime(); // Offset not valid when zone name expected.
+}
+
+void tst_QDateTime::fromStringStringFormat()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, format);
+ QFETCH(int, baseYear);
+ QFETCH(QDateTime, expected);
+
+ QDateTime dt = QDateTime::fromString(string, format, baseYear);
+
+ QCOMPARE(dt, expected);
+ if (expected.isValid()) {
+ QCOMPARE(dt.timeSpec(), expected.timeSpec());
+ QCOMPARE(dt.timeRepresentation(), dt.timeRepresentation());
+ } else {
+ QCOMPARE(dt.isValid(), expected.isValid());
+ QCOMPARE(dt.toMSecsSinceEpoch(), expected.toMSecsSinceEpoch());
+ }
+}
+
+void tst_QDateTime::fromStringStringFormat_localTimeZone_data()
+{
+ QTest::addColumn<QByteArray>("localTimeZone");
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<int>("baseYear");
+ QTest::addColumn<QDateTime>("expected");
+
+#if QT_CONFIG(timezone)
+ bool lacksRows = true;
+ // Note that the localTimeZone needn't match the zone used in the string and
+ // expected date-time; indeed, having them different is probably best.
+ // Both zones need to be valid; GMT always is, so is a safe one to use for
+ // whichever the test-case doesn't care about (if that applies to either).
+ QTimeZone etcGmtWithOffset("Etc/GMT+3");
+ if (etcGmtWithOffset.isValid()) {
+ lacksRows = false;
+ QTest::newRow("local-timezone-t-with-zone:Etc/GMT+3")
+ << "GMT"_ba << u"2008-10-13 Etc/GMT+3 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50), etcGmtWithOffset);
+ QTest::newRow("local-timezone-tttt-with-zone:Etc/GMT+3")
+ << "GMT"_ba << u"2008-10-13 Etc/GMT+3 11.50"_s << u"yyyy-MM-dd tttt hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50), etcGmtWithOffset);
+ }
+ QTest::newRow("local-timezone-tt-with-zone:Etc/GMT+3")
+ << "GMT"_ba << u"2008-10-13 Etc/GMT+3 11.50"_s << u"yyyy-MM-dd tt hh.mm"_s << 1900
+ << QDateTime(); // Zone name not valid when offset expected
+ QTest::newRow("local-timezone-ttt-with-zone:Etc/GMT+3")
+ << "GMT"_ba << u"2008-10-13 Etc/GMT+3 11.50"_s << u"yyyy-MM-dd ttt hh.mm"_s << 1900
+ << QDateTime(); // Zone name not valid when offset expected
+ QTimeZone gmtWithOffset("GMT-2");
+ if (gmtWithOffset.isValid()) {
+ lacksRows = false;
+ QTest::newRow("local-timezone-with-offset:GMT-2")
+ << "GMT"_ba << u"2008-10-13 GMT-2 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50), gmtWithOffset);
+ }
+ QTimeZone gmt("GMT");
+ if (gmt.isValid()) {
+ lacksRows = false;
+ const bool fullyLocal = ([]() {
+ TimeZoneRollback useZone("GMT");
+ return qTzName(0) == u"GMT"_s;
+ })();
+ QTest::newRow("local-timezone-with-offset:GMT")
+ << "GMT"_ba << u"2008-10-13 GMT 11.50"_s << u"yyyy-MM-dd t hh.mm"_s << 1900
+ << QDateTime(QDate(2008, 10, 13), QTime(11, 50),
+ fullyLocal ? QTimeZone(QTimeZone::LocalTime) : gmt);
+ }
+ QTimeZone helsinki("Europe/Helsinki");
+ if (helsinki.isValid()) {
+ lacksRows = false;
+ // QTBUG-96861: QAsn1Element::toDateTime() tripped over an assert due to
+ // the first 20m 11s of 1921-05-01 being skipped, so the parser's
+ // attempt to construct a local time after scanning yyMM tripped up on
+ // the start of the day, when the zone backend lacked transition data.
+ // (Because QDTP tries to use local time until it reads the final zone
+ // field, constructing a new QDT after reading each field, hence
+ // transiently wanting 1921-05-01 00:00:00 before reading the dd field.)
+ QTest::newRow("Helsinki-joins-EET:19")
+ << "Europe/Helsinki"_ba << u"210506000000Z"_s << u"yyMMddHHmmsst"_s << 1900
+ << QDateTime(QDate(1921, 5, 6), QTime(0, 0), UTC);
+ // Strictly, ASN.1 wants us to parse that with a different baseYear, so
+ // check that, too, but tweak to match the 1921 transition's mid-point:
+ QTest::newRow("Helsinki-joins-EET:20")
+ << "Europe/Helsinki"_ba << u"210501001006Z"_s << u"yyMMddHHmmsst"_s << 1950
+ << QDateTime(QDate(2021, 5, 1), QTime(0, 10, 6), UTC);
+ }
+ if (lacksRows)
+ QSKIP("Testcases all use zones unsupported on this platform");
+#else
+ QSKIP("Test only possible with timezone support enabled");
+#endif
+}
+
+void tst_QDateTime::fromStringStringFormat_localTimeZone()
+{
+ QFETCH(QByteArray, localTimeZone);
+ TimeZoneRollback useZone(localTimeZone); // enforce test's time zone
+ fromStringStringFormat(); // call basic fromStringStringFormat test
+}
+# endif // datetimeparser
+#endif // datestring
+
+void tst_QDateTime::offsetFromUtc()
+{
+ /* Check default value. */
+ QCOMPARE(QDateTime().offsetFromUtc(), 0);
+
+ // Offset constructor
+ QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
+ QVERIFY(dt1.timeRepresentation().isValid());
+#if QT_CONFIG(timezone)
+ QVERIFY(dt1.timeZone().isValid());
+#endif
+ dt1 = QDateTime(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(-60 * 60));
+ QCOMPARE(dt1.offsetFromUtc(), -60 * 60);
+
+ // UTC should be 0 offset
+ QDateTime dt2(QDate(2013, 1, 1), QTime(0, 0), UTC);
+ QCOMPARE(dt2.offsetFromUtc(), 0);
+
+ // LocalTime should vary
+ if (zoneIsCET) {
+ // Time definitely in Standard Time so 1 hour ahead
+ QDateTime dt3 = QDate(2013, 1, 1).startOfDay();
+ QCOMPARE(dt3.offsetFromUtc(), 1 * 60 * 60);
+ // Time definitely in Daylight Time so 2 hours ahead
+ QDateTime dt4 = QDate(2013, 6, 1).startOfDay();
+ QCOMPARE(dt4.offsetFromUtc(), 2 * 60 * 60);
+ } else {
+ qDebug("Skipped some tests specific to Central European Time "
+ "(CET/CEST), e.g. TZ=Europe/Oslo");
+ }
+
+#if QT_CONFIG(timezone)
+ QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0), QTimeZone("Pacific/Auckland"));
+ QCOMPARE(dt5.offsetFromUtc(), 46800);
+
+ QDateTime dt6(QDate(2013, 6, 1), QTime(0, 0), QTimeZone("Pacific/Auckland"));
+ QCOMPARE(dt6.offsetFromUtc(), 43200);
+#endif
+}
+
+#if QT_DEPRECATED_SINCE(6, 9)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QDateTime::setOffsetFromUtc()
+{
+ /* Basic tests. */
+ {
+ QDateTime dt(QDateTime::currentDateTime());
+ dt.setTimeSpec(Qt::LocalTime);
+
+ dt.setOffsetFromUtc(0);
+ QCOMPARE(dt.offsetFromUtc(), 0);
+ QCOMPARE(dt.timeSpec(), Qt::UTC);
+
+ dt.setOffsetFromUtc(-100);
+ QCOMPARE(dt.offsetFromUtc(), -100);
+ QCOMPARE(dt.timeSpec(), Qt::OffsetFromUTC);
+ }
+
+ /* Test detaching. */
+ {
+ QDateTime dt(QDateTime::currentDateTime());
+ QDateTime dt2(dt);
+ int offset2 = dt2.offsetFromUtc();
+
+ dt.setOffsetFromUtc(501);
+
+ QCOMPARE(dt.offsetFromUtc(), 501);
+ QCOMPARE(dt2.offsetFromUtc(), offset2);
+ }
+
+ /* Check copying. */
+ {
+ QDateTime dt(QDateTime::currentDateTime());
+ dt.setOffsetFromUtc(502);
+ QCOMPARE(dt.offsetFromUtc(), 502);
+
+ QDateTime dt2(dt);
+ QCOMPARE(dt2.offsetFromUtc(), 502);
+ }
+
+ /* Check assignment. */
+ {
+ QDateTime dt(QDateTime::currentDateTime());
+ dt.setOffsetFromUtc(502);
+ QDateTime dt2;
+ dt2 = dt;
+
+ QCOMPARE(dt2.offsetFromUtc(), 502);
+ }
+
+ // Check spec persists
+ QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0), Qt::OffsetFromUTC, 60 * 60);
+ dt1.setMSecsSinceEpoch(123456789);
+ QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
+ dt1.setSecsSinceEpoch(123456789);
+ QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
+
+ // Check datastream serialises the offset seconds
+ QByteArray tmp;
+ {
+ QDataStream ds(&tmp, QIODevice::WriteOnly);
+ ds << dt1;
+ }
+ QDateTime dt2;
+ {
+ QDataStream ds(&tmp, QIODevice::ReadOnly);
+ ds >> dt2;
+ }
+ QCOMPARE(dt2, dt1);
+ QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(dt2.offsetFromUtc(), 60 * 60);
+}
+
+void tst_QDateTime::toOffsetFromUtc()
+{
+ QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0), QTimeZone::UTC);
+
+ QDateTime dt2 = dt1.toOffsetFromUtc(60 * 60);
+ QCOMPARE(dt2, dt1);
+ QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(dt2.date(), QDate(2013, 1, 1));
+ QCOMPARE(dt2.time(), QTime(1, 0));
+
+ dt2 = dt1.toOffsetFromUtc(0);
+ QCOMPARE(dt2, dt1);
+ QCOMPARE(dt2.timeSpec(), Qt::UTC);
+ QCOMPARE(dt2.date(), QDate(2013, 1, 1));
+ QCOMPARE(dt2.time(), QTime(0, 0));
+
+ dt2 = dt1.toTimeSpec(Qt::OffsetFromUTC);
+ QCOMPARE(dt2, dt1);
+ QCOMPARE(dt2.timeSpec(), Qt::UTC);
+ QCOMPARE(dt2.date(), QDate(2013, 1, 1));
+ QCOMPARE(dt2.time(), QTime(0, 0));
+}
+QT_WARNING_POP
+#endif // 6.9 deprecation
+
+void tst_QDateTime::zoneAtTime_data()
+{
+ QTest::addColumn<QByteArray>("ianaID");
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<int>("offset");
+#define ADDROW(name, zone, date, offset) \
+ QTest::newRow(name) << QByteArray(zone) << (date) << (offset)
+
+ // Check DST handling around epoch:
+ {
+ QDate epoch(1970, 1, 1);
+ ADDROW("epoch:UTC", "UTC", epoch, 0);
+ // Paris and Berlin skipped DST around 1970; but Rome used it.
+ ADDROW("epoch:CET", "Europe/Rome", epoch, 3600);
+ ADDROW("epoch:PST", "America/Vancouver", epoch, -8 * 3600);
+ ADDROW("epoch:EST", "America/New_York", epoch, -5 * 3600);
+ }
+ {
+ // QDateTime now takes account of DST even before the epoch.
+ QDate summer69(1969, 8, 15); // Woodstock started
+ ADDROW("summer69:UTC", "UTC", summer69, 0);
+ ADDROW("summer69:CET", "Europe/Rome", summer69, 2 * 3600);
+ ADDROW("summer69:PST", "America/Vancouver", summer69, -7 * 3600);
+ ADDROW("summer69:EST", "America/New_York", summer69, -4 * 3600);
+ }
+ {
+ // ... and has always taken it into account since:
+ QDate summer70(1970, 8, 26); // Isle of Wight festival
+ ADDROW("summer70:UTC", "UTC", summer70, 0);
+ ADDROW("summer70:CET", "Europe/Rome", summer70, 2 * 3600);
+ ADDROW("summer70:PST", "America/Vancouver", summer70, -7 * 3600);
+ ADDROW("summer70:EST", "America/New_York", summer70, -4 * 3600);
+ }
+
+#ifdef Q_OS_ANDROID // QTBUG-68835; gets offset 0 for the affected tests.
+# define NONANDROIDROW(name, zone, date, offset)
+#else
+# define NONANDROIDROW(name, zone, date, offset) ADDROW(name, zone, date, offset)
+#endif
+
+#ifndef Q_OS_WIN
+ // Bracket a few noteworthy transitions:
+ ADDROW("before:ACWST", "Australia/Eucla", QDate(1974, 10, 26), 31500); // 8:45
+ NONANDROIDROW("after:ACWST", "Australia/Eucla", QDate(1974, 10, 27), 35100); // 9:45
+ NONANDROIDROW("before:NPT", "Asia/Kathmandu", QDate(1985, 12, 31), 19800); // 5:30
+ ADDROW("after:NPT", "Asia/Kathmandu", QDate(1986, 1, 1), 20700); // 5:45
+ // The two that have skipped a day (each):
+ NONANDROIDROW("before:LINT", "Pacific/Kiritimati", QDate(1994, 12, 30), -36000);
+ ADDROW("after:LINT", "Pacific/Kiritimati", QDate(1995, 1, 2), 14 * 3600);
+ ADDROW("after:WST", "Pacific/Apia", QDate(2011, 12, 31), 14 * 3600);
+#endif // MS lacks ACWST, NPT; doesn't grok date-line crossings; and Windows 7 lacks LINT.
+ ADDROW("before:WST", "Pacific/Apia", QDate(2011, 12, 29), -36000);
+#undef ADDROW
+}
+
+void tst_QDateTime::zoneAtTime()
+{
+#if QT_CONFIG(timezone)
+ QFETCH(QByteArray, ianaID);
+ QFETCH(QDate, date);
+ QFETCH(int, offset);
+ const QTime noon(12, 0);
+
+ QTimeZone zone(ianaID);
+ QVERIFY(zone.isValid());
+ QCOMPARE(QDateTime(date, noon, zone).offsetFromUtc(), offset);
+ QCOMPARE(zone.offsetFromUtc(QDateTime(date, noon, zone)), offset);
+#else
+ QSKIP("Needs timezone feature enabled");
+#endif
+}
+
+void tst_QDateTime::timeZoneAbbreviation()
+{
+ QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QCOMPARE(dt1.timeZoneAbbreviation(), QString("UTC+01:00"));
+ QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(-60 * 60));
+ QCOMPARE(dt2.timeZoneAbbreviation(), QString("UTC-01:00"));
+
+ QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0), UTC);
+ QCOMPARE(dt3.timeZoneAbbreviation(), QString("UTC"));
+
+ // LocalTime should vary
+ if (zoneIsCET) {
+ // Time definitely in Standard Time
+ QDateTime dt4 = QDate(2013, 1, 1).startOfDay();
+ /* Note that MET is functionally an alias for CET (their zoneinfo files
+ differ only in the first letter of the abbreviations), unlike the
+ various zones that give CET as their abbreviation.
+ */
+ {
+ const auto abbrev = dt4.timeZoneAbbreviation();
+ auto reporter = qScopeGuard([abbrev]() {
+ qDebug() << "Unexpected abbreviation" << abbrev;
+ });
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "Windows only reports long name (QTBUG-32759)", Continue);
+#endif
+ QVERIFY(abbrev == u"CET"_s || abbrev == u"MET"_s);
+ reporter.dismiss();
+ }
+ // Time definitely in Daylight Time
+ QDateTime dt5 = QDate(2013, 6, 1).startOfDay();
+ {
+ const auto abbrev = dt5.timeZoneAbbreviation();
+ auto reporter = qScopeGuard([abbrev]() {
+ qDebug() << "Unexpected abbreviation" << abbrev;
+ });
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "Windows only reports long name (QTBUG-32759)", Continue);
+#endif
+ QVERIFY(abbrev == u"CEST"_s || abbrev == u"MEST"_s);
+ reporter.dismiss();
+ }
+ } else {
+ qDebug("(Skipped some CET-only tests)");
+ }
+
+#if QT_CONFIG(timezone)
+ const QTimeZone berlin("Europe/Berlin");
+ const QDateTime jan(QDate(2013, 1, 1).startOfDay(berlin));
+ const QDateTime jul(QDate(2013, 7, 1).startOfDay(berlin));
+
+ QCOMPARE(jan.timeZoneAbbreviation(), berlin.abbreviation(jan));
+ QCOMPARE(jul.timeZoneAbbreviation(), berlin.abbreviation(jul));
+#endif
+}
+
+void tst_QDateTime::getDate()
+{
+ {
+ int y = -33, m = -44, d = -55;
+ QDate date;
+ date.getDate(&y, &m, &d);
+ QCOMPARE(date.year(), y);
+ QCOMPARE(date.month(), m);
+ QCOMPARE(date.day(), d);
+
+ date.getDate(0, 0, 0);
+ }
+
+ {
+ int y = -33, m = -44, d = -55;
+ QDate date(1998, 5, 24);
+ date.getDate(0, &m, 0);
+ date.getDate(&y, 0, 0);
+ date.getDate(0, 0, &d);
+
+ QCOMPARE(date.year(), y);
+ QCOMPARE(date.month(), m);
+ QCOMPARE(date.day(), d);
+ }
+}
+
+void tst_QDateTime::fewDigitsInYear() const
+{
+ const QDateTime three(QDate(300, 10, 11).startOfDay());
+ QCOMPARE(three.toString(QLatin1String("yyyy-MM-dd")), QString::fromLatin1("0300-10-11"));
+
+ const QDateTime two(QDate(20, 10, 11).startOfDay());
+ QCOMPARE(two.toString(QLatin1String("yyyy-MM-dd")), QString::fromLatin1("0020-10-11"));
+
+ const QDateTime yyTwo(QDate(30, 10, 11).startOfDay());
+ QCOMPARE(yyTwo.toString(QLatin1String("yy-MM-dd")), QString::fromLatin1("30-10-11"));
+
+ const QDateTime yyOne(QDate(4, 10, 11).startOfDay());
+ QCOMPARE(yyOne.toString(QLatin1String("yy-MM-dd")), QString::fromLatin1("04-10-11"));
+}
+
+void tst_QDateTime::printNegativeYear() const
+{
+ {
+ QDateTime date(QDate(-20, 10, 11).startOfDay());
+ QVERIFY(date.isValid());
+ QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0020"));
+ }
+
+ {
+ QDateTime date(QDate(-3, 10, 11).startOfDay());
+ QVERIFY(date.isValid());
+ QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0003"));
+ }
+
+ {
+ QDateTime date(QDate(-400, 10, 11).startOfDay());
+ QVERIFY(date.isValid());
+ QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0400"));
+ }
+}
+
+#if QT_CONFIG(datetimeparser)
+void tst_QDateTime::roundtripTextDate() const
+{
+ /* This code path should not result in warnings. */
+ const QDateTime now(QDateTime::currentDateTime());
+ // TextDate drops millis:
+ const QDateTime theDateTime(now.addMSecs(-now.time().msec()));
+ QCOMPARE(QDateTime::fromString(theDateTime.toString(Qt::TextDate), Qt::TextDate), theDateTime);
+}
+#endif
+
+void tst_QDateTime::utcOffsetLessThan() const
+{
+ QDateTime dt1(QDate(2002, 10, 10), QTime(0, 0));
+ QDateTime dt2(dt1);
+
+ dt1.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-(2 * 60 * 60))); // Minus two hours.
+ dt2.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(-(3 * 60 * 60))); // Minus three hours.
+
+ QVERIFY(dt1 != dt2);
+ QVERIFY(!(dt1 == dt2));
+ QVERIFY(dt1 < dt2);
+ QVERIFY(!(dt2 < dt1));
+}
+
+void tst_QDateTime::isDaylightTime() const
+{
+ QDateTime utc1(QDate(2012, 1, 1), QTime(0, 0), UTC);
+ QVERIFY(!utc1.isDaylightTime());
+ QDateTime utc2(QDate(2012, 6, 1), QTime(0, 0), UTC);
+ QVERIFY(!utc2.isDaylightTime());
+
+ QDateTime offset1(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QVERIFY(!offset1.isDaylightTime());
+ QDateTime offset2(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
+ QVERIFY(!offset2.isDaylightTime());
+
+ if (zoneIsCET) {
+ QDateTime cet1(QDate(2012, 1, 1), QTime(0, 0));
+ QVERIFY(!cet1.isDaylightTime());
+ QDateTime cet2(QDate(2012, 6, 1), QTime(0, 0));
+ QVERIFY(cet2.isDaylightTime());
+ } else {
+ qDebug("Skipped some tests specific to Central European Time "
+ "(CET/CEST), e.g. TZ=Europe/Oslo");
+ }
+}
+
+void tst_QDateTime::daylightTransitions() const
+{
+ if (!zoneIsCET)
+ QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
+
+ // CET transitions occur at 01:00:00 UTC on last Sunday in March and October
+ // 2011-03-27 02:00:00 CET became 03:00:00 CEST at msecs = 1301187600000
+ // 2011-10-30 03:00:00 CEST became 02:00:00 CET at msecs = 1319936400000
+ // 2012-03-25 02:00:00 CET became 03:00:00 CEST at msecs = 1332637200000
+ // 2012-10-28 03:00:00 CEST became 02:00:00 CET at msecs = 1351386000000
+ QCOMPARE(QDate(2012, 3, 25).dayOfWeek(), 7);
+ QCOMPARE(QDate(2012, 10, 28).dayOfWeek(), 7);
+ const qint64 spring2012 = 1332637200000;
+ const qint64 autumn2012 = 1351386000000;
+ const qint64 msecsOneHour = 3600000;
+ QCOMPARE(spring2012, QDateTime(QDate(2012, 3, 25), QTime(1, 0), UTC).toMSecsSinceEpoch());
+ QCOMPARE(autumn2012, QDateTime(QDate(2012, 10, 28), QTime(1, 0), UTC).toMSecsSinceEpoch());
+
+ // Test for correct behviour for StandardTime -> DaylightTime transition, i.e. missing hour
+
+ // Test setting date, time in missing hour will be invalid
+
+ QDateTime before(QDate(2012, 3, 25), QTime(1, 59, 59, 999));
+ QVERIFY(before.isValid());
+ QVERIFY(!before.isDaylightTime());
+ QCOMPARE(before.date(), QDate(2012, 3, 25));
+ QCOMPARE(before.time(), QTime(1, 59, 59, 999));
+ QCOMPARE(before.toMSecsSinceEpoch(), spring2012 - 1);
+
+ QDateTime entering(QDate(2012, 3, 25), QTime(2, 0),
+ QDateTime::TransitionResolution::PreferBefore);
+ QVERIFY(entering.isValid());
+ QVERIFY(!entering.isDaylightTime());
+ QCOMPARE(entering.date(), QDate(2012, 3, 25));
+ QCOMPARE(entering.time(), QTime(1, 0));
+ // QDateTimeParser relies on toMSecsSinceEpoch() to still work:
+ QCOMPARE(entering.toMSecsSinceEpoch(), spring2012 - msecsOneHour);
+
+ QDateTime leaving(QDate(2012, 3, 25), QTime(2, 0),
+ QDateTime::TransitionResolution::PreferAfter);
+ QVERIFY(leaving.isValid());
+ QVERIFY(leaving.isDaylightTime());
+ QCOMPARE(leaving.date(), QDate(2012, 3, 25));
+ QCOMPARE(leaving.time(), QTime(3, 0));
+ // QDateTimeParser relies on toMSecsSinceEpoch to still work:
+ QCOMPARE(leaving.toMSecsSinceEpoch(), spring2012);
+
+ QDateTime after(QDate(2012, 3, 25), QTime(3, 0));
+ QVERIFY(after.isValid());
+ QVERIFY(after.isDaylightTime());
+ QCOMPARE(after.date(), QDate(2012, 3, 25));
+ QCOMPARE(after.time(), QTime(3, 0));
+ QCOMPARE(after.toMSecsSinceEpoch(), spring2012);
+
+ // Test round-tripping of msecs
+
+ before.setMSecsSinceEpoch(spring2012 - 1);
+ QVERIFY(before.isValid());
+ QCOMPARE(before.date(), QDate(2012, 3, 25));
+ QCOMPARE(before.time(), QTime(1, 59, 59, 999));
+ QCOMPARE(before.toMSecsSinceEpoch(), spring2012 -1);
+
+ after.setMSecsSinceEpoch(spring2012);
+ QVERIFY(after.isValid());
+ QCOMPARE(after.date(), QDate(2012, 3, 25));
+ QCOMPARE(after.time(), QTime(3, 0));
+ QCOMPARE(after.toMSecsSinceEpoch(), spring2012);
+
+ // Test changing time spec re-validates the date/time
+ QDateTime utc(QDate(2012, 3, 25), QTime(2, 0), UTC);
+ QVERIFY(utc.isValid());
+ QCOMPARE(utc.date(), QDate(2012, 3, 25));
+ QCOMPARE(utc.time(), QTime(2, 0));
+ utc.setTimeZone(QTimeZone::LocalTime); // Resolved to RelativeToBefore.
+ QVERIFY(utc.isValid());
+ QCOMPARE(utc.date(), QDate(2012, 3, 25));
+ QCOMPARE(utc.time(), QTime(3, 0));
+ utc.setTimeZone(UTC); // Preserves the changed time().
+ QVERIFY(utc.isValid());
+ QCOMPARE(utc.date(), QDate(2012, 3, 25));
+ QCOMPARE(utc.time(), QTime(3, 0));
+
+ // Test date maths, if result falls in missing hour then becomes next
+ // hour (or is always invalid; mktime() may reject gap-times).
+
+ QDateTime test(QDate(2011, 3, 25), QTime(2, 0));
+ QVERIFY(test.isValid());
+ test = test.addYears(1);
+ const bool handled = test.isValid();
+#define CHECK_SPRING_FORWARD(test) \
+ if (test.isValid()) { \
+ QCOMPARE(test.date(), QDate(2012, 3, 25)); \
+ QCOMPARE(test.time(), QTime(3, 0)); \
+ } else { \
+ QVERIFY(!handled); \
+ }
+ CHECK_SPRING_FORWARD(test);
+
+ test = QDateTime(QDate(2012, 2, 25), QTime(2, 0));
+ QVERIFY(test.isValid());
+ test = test.addMonths(1);
+ CHECK_SPRING_FORWARD(test);
+
+ test = QDateTime(QDate(2012, 3, 24), QTime(2, 0));
+ QVERIFY(test.isValid());
+ test = test.addDays(1);
+ CHECK_SPRING_FORWARD(test);
+
+ test = QDateTime(QDate(2012, 3, 25), QTime(1, 0));
+ QVERIFY(test.isValid());
+ QCOMPARE(test.toMSecsSinceEpoch(), spring2012 - msecsOneHour);
+ test = test.addMSecs(msecsOneHour);
+ CHECK_SPRING_FORWARD(test);
+ if (handled)
+ QCOMPARE(test.toMSecsSinceEpoch(), spring2012);
+#undef CHECK_SPRING_FORWARD
+
+ // Test for correct behviour for DaylightTime -> StandardTime transition, fall-back
+
+ QDateTime autumnMidnight = QDate(2012, 10, 28).startOfDay();
+ QVERIFY(autumnMidnight.isValid());
+ QCOMPARE(autumnMidnight.date(), QDate(2012, 10, 28));
+ QCOMPARE(autumnMidnight.time(), QTime(0, 0));
+ QCOMPARE(autumnMidnight.toMSecsSinceEpoch(), autumn2012 - 3 * msecsOneHour);
+
+ QDateTime startFirst = autumnMidnight.addMSecs(2 * msecsOneHour);
+ QVERIFY(startFirst.isValid());
+ QCOMPARE(startFirst, QDateTime(QDate(2012, 10, 28), QTime(2, 0),
+ QDateTime::TransitionResolution::PreferBefore));
+ QCOMPARE(startFirst.date(), QDate(2012, 10, 28));
+ QCOMPARE(startFirst.time(), QTime(2, 0));
+ QCOMPARE(startFirst.toMSecsSinceEpoch(), autumn2012 - msecsOneHour);
+
+ // 1 msec before transition is 2:59:59.999 FirstOccurrence
+ QDateTime endFirst = startFirst.addMSecs(msecsOneHour - 1);
+ QVERIFY(endFirst.isValid());
+ QCOMPARE(endFirst,
+ QDateTime(QDate(2012, 10, 28), QTime(2, 59, 59, 999),
+ QDateTime::TransitionResolution::PreferBefore));
+ QCOMPARE(endFirst.date(), QDate(2012, 10, 28));
+ QCOMPARE(endFirst.time(), QTime(2, 59, 59, 999));
+ QCOMPARE(endFirst.toMSecsSinceEpoch(), autumn2012 - 1);
+
+ // At the transition, starting the second pass
+ QDateTime startRepeat = endFirst.addMSecs(1);
+ QVERIFY(startRepeat.isValid());
+ QCOMPARE(startRepeat, QDateTime(QDate(2012, 10, 28), QTime(2, 0),
+ QDateTime::TransitionResolution::PreferAfter));
+ QCOMPARE(startRepeat.date(), QDate(2012, 10, 28));
+ QCOMPARE(startRepeat.time(), QTime(2, 0));
+ QCOMPARE(startRepeat.toMSecsSinceEpoch(), autumn2012);
+
+ // 59:59.999 after transition is 2:59:59.999 SecondOccurrence
+ QDateTime endRepeat = endFirst.addMSecs(msecsOneHour);
+ QVERIFY(endRepeat.isValid());
+ QCOMPARE(endRepeat,
+ QDateTime(QDate(2012, 10, 28), QTime(2, 59, 59, 999),
+ QDateTime::TransitionResolution::PreferAfter));
+ QCOMPARE(endRepeat.date(), QDate(2012, 10, 28));
+ QCOMPARE(endRepeat.time(), QTime(2, 59, 59, 999));
+ QCOMPARE(endRepeat.toMSecsSinceEpoch(), autumn2012 + msecsOneHour - 1);
+
+ // 1 hour after transition is 3:00:00 (not ambiguous)
+ QDateTime hourAfter = endRepeat.addMSecs(1);
+ QVERIFY(hourAfter.isValid());
+ QCOMPARE(hourAfter, QDateTime(QDate(2012, 10, 28), QTime(3, 0)));
+ QCOMPARE(hourAfter.date(), QDate(2012, 10, 28));
+ QCOMPARE(hourAfter.time(), QTime(3, 0));
+ QCOMPARE(hourAfter.toMSecsSinceEpoch(), autumn2012 + msecsOneHour);
+
+ // Test round-tripping of msecs
+
+ // 1 hour before transition is 2:00:00 FirstOccurrence
+ startFirst.setMSecsSinceEpoch(autumn2012 - msecsOneHour);
+ QVERIFY(startFirst.isValid());
+ QCOMPARE(startFirst.date(), QDate(2012, 10, 28));
+ QCOMPARE(startFirst.time(), QTime(2, 0));
+ QCOMPARE(startFirst.toMSecsSinceEpoch(), autumn2012 - msecsOneHour);
+
+ // 1 msec before transition is 2:59:59.999 FirstOccurrence
+ endFirst.setMSecsSinceEpoch(autumn2012 - 1);
+ QVERIFY(endFirst.isValid());
+ QCOMPARE(endFirst.date(), QDate(2012, 10, 28));
+ QCOMPARE(endFirst.time(), QTime(2, 59, 59, 999));
+ QCOMPARE(endFirst.toMSecsSinceEpoch(), autumn2012 - 1);
+
+ // At transition is 2:00:00 SecondOccurrence
+ startRepeat.setMSecsSinceEpoch(autumn2012);
+ QVERIFY(startRepeat.isValid());
+ QCOMPARE(startRepeat.date(), QDate(2012, 10, 28));
+ QCOMPARE(startRepeat.time(), QTime(2, 0));
+ QCOMPARE(startRepeat.toMSecsSinceEpoch(), autumn2012);
+
+ // 59:59.999 after transition is 2:59:59.999 SecondOccurrence
+ endRepeat.setMSecsSinceEpoch(autumn2012 + msecsOneHour - 1);
+ QVERIFY(endRepeat.isValid());
+ QCOMPARE(endRepeat.date(), QDate(2012, 10, 28));
+ QCOMPARE(endRepeat.time(), QTime(2, 59, 59, 999));
+ QCOMPARE(endRepeat.toMSecsSinceEpoch(), autumn2012 + msecsOneHour - 1);
+
+ // 1 hour after transition is 3:00:00 (unambiguous)
+ hourAfter.setMSecsSinceEpoch(autumn2012 + msecsOneHour);
+ QVERIFY(hourAfter.isValid());
+ QCOMPARE(hourAfter.date(), QDate(2012, 10, 28));
+ QCOMPARE(hourAfter.time(), QTime(3, 0));
+ QCOMPARE(hourAfter.toMSecsSinceEpoch(), autumn2012 + msecsOneHour);
+
+ // Test date maths
+
+ // Add year to a DST moment to hit start of first pass:
+ test = QDateTime(QDate(2011, 10, 28), QTime(2, 0));
+ QVERIFY(test.isDaylightTime()); // Before last Sunday in month
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QVERIFY(test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0));
+ // QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(2, 0), Prior));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 - msecsOneHour);
+
+ // Subtract year from post-tran time to hit start of second pass:
+ test = QDateTime(QDate(2013, 10, 28), QTime(2, 0));
+ QVERIFY(!test.isDaylightTime()); // After last Sundy in month
+ test = test.addYears(-1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0));
+ // QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(2, 0), Post));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012);
+
+ // Add year to get to after the repeated hour
+ test = QDateTime(QDate(2011, 10, 28), QTime(3, 0));
+ QVERIFY(test.isDaylightTime()); // Before last Sunday in month
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(3, 0)));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 + msecsOneHour);
+
+ // Add year to start of first pass:
+ test = QDateTime(QDate(2011, 10, 30), QTime(1, 0)).addMSecs(msecsOneHour);
+ QVERIFY(test.isDaylightTime());
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime()); // After last Sunday in month
+ QCOMPARE(test.date(), QDate(2012, 10, 30));
+ QCOMPARE(test.time(), QTime(2, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 30), QTime(2, 0)));
+
+ // Add year to start of second pass:
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0)).addMSecs(-msecsOneHour);
+ QVERIFY(!test.isDaylightTime());
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime()); // Same as before
+ QCOMPARE(test.date(), QDate(2012, 10, 30));
+ QCOMPARE(test.time(), QTime(2, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 30), QTime(2, 0)));
+
+ // Add year to after second pass:
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0));
+ QVERIFY(!test.isDaylightTime());
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 30));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 30), QTime(3, 0)));
+
+
+ // Add month to get to start of first pass
+ test = QDateTime(QDate(2012, 9, 28), QTime(2, 0));
+ QVERIFY(test.isDaylightTime());
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QVERIFY(test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0));
+ // QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(2, 0), Prior));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 - msecsOneHour);
+
+ // Add month to get to after second pass (unambiguous)
+ test = QDateTime(QDate(2012, 9, 28), QTime(3, 0));
+ QVERIFY(test.isDaylightTime());
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(3, 0)));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 + msecsOneHour);
+
+ // Add month to start of first pass
+ test = QDateTime(QDate(2011, 10, 30), QTime(1, 0)).addMSecs(msecsOneHour);
+ QVERIFY(test.isDaylightTime());
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2011, 11, 30));
+ QCOMPARE(test.time(), QTime(2, 0));
+ QCOMPARE(test, QDateTime(QDate(2011, 11, 30), QTime(2, 0)));
+
+ // Add month to end of second pass
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0)).addMSecs(-msecsOneHour);
+ QVERIFY(!test.isDaylightTime());
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2011, 11, 30));
+ QCOMPARE(test.time(), QTime(2, 0));
+ QCOMPARE(test, QDateTime(QDate(2011, 11, 30), QTime(2, 0)));
+
+ // Add month to after after second pass (unambiguous)
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0));
+ QVERIFY(!test.isDaylightTime());
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2011, 11, 30));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2011, 11, 30), QTime(3, 0)));
+
+
+ // Add day to get to start of first pass
+ test = QDateTime(QDate(2012, 10, 27), QTime(2, 0));
+ QVERIFY(test.isDaylightTime());
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QVERIFY(test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0));
+ // QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(2, 0), Prior));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 - msecsOneHour);
+
+ // Add day to get to after second pass (unambiguous)
+ test = QDateTime(QDate(2012, 10, 27), QTime(3, 0));
+ QVERIFY(test.isDaylightTime());
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(3, 0)));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 + msecsOneHour);
+
+ // Add day to start of first pass
+ test = QDateTime(QDate(2011, 10, 30), QTime(1, 0)).addMSecs(msecsOneHour);
+ QVERIFY(test.isDaylightTime());
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2011, 10, 31));
+ QCOMPARE(test.time(), QTime(2, 0));
+ QCOMPARE(test, QDateTime(QDate(2011, 10, 31), QTime(2, 0)));
+
+ // Add day to start of second pass
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0)).addMSecs(-msecsOneHour);
+ QVERIFY(!test.isDaylightTime());
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2011, 10, 31));
+ QCOMPARE(test.time(), QTime(2, 0));
+ QCOMPARE(test, QDateTime(QDate(2011, 10, 31), QTime(2, 0)));
+
+ // Add day to after second pass (unambiguous)
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0));
+ QVERIFY(!test.isDaylightTime());
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2011, 10, 31));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2011, 10, 31), QTime(3, 0)));
+
+
+ // Add hour to get to start of first pass
+ test = QDateTime(QDate(2012, 10, 28), QTime(1, 0));
+ QVERIFY(test.isDaylightTime());
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QVERIFY(test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0));
+ // QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(2, 0), Prior));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 - msecsOneHour);
+
+ // Add hour to start of first pass to get to start of second pass
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0));
+ // QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(2, 0), Post));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012);
+
+ // Add hour to start of second pass to get to after second pass
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QVERIFY(!test.isDaylightTime());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0));
+ QCOMPARE(test, QDateTime(QDate(2012, 10, 28), QTime(3, 0)));
+ QCOMPARE(test.toMSecsSinceEpoch(), autumn2012 + msecsOneHour);
+}
+
+void tst_QDateTime::timeZones() const
+{
+#if QT_CONFIG(timezone)
+ QTimeZone invalidTz = QTimeZone("Vulcan/ShiKahr");
+ QVERIFY(!invalidTz.isValid());
+ QDateTime invalidDateTime = QDateTime(QDate(2000, 1, 1), QTime(0, 0), invalidTz);
+ QVERIFY(!invalidDateTime.isValid());
+ QCOMPARE(invalidDateTime.date(), QDate(2000, 1, 1));
+ QCOMPARE(invalidDateTime.time(), QTime(0, 0));
+
+ QTimeZone nzTz = QTimeZone("Pacific/Auckland");
+ QTimeZone nzTzOffset = QTimeZone(12 * 3600);
+
+ // During Standard Time NZ is +12:00
+ QDateTime utcStd(QDate(2012, 6, 1), QTime(0, 0), UTC);
+ QDateTime nzStd(QDate(2012, 6, 1), QTime(12, 0), nzTz);
+ QDateTime nzStdOffset(QDate(2012, 6, 1), QTime(12, 0), nzTzOffset);
+
+ QVERIFY(nzStd.isValid());
+ QCOMPARE(nzStd.timeSpec(), Qt::TimeZone);
+ QCOMPARE(nzStd.date(), QDate(2012, 6, 1));
+ QCOMPARE(nzStd.time(), QTime(12, 0));
+ QVERIFY(nzStd.timeZone() == nzTz);
+ QCOMPARE(nzStd.timeZone().id(), QByteArray("Pacific/Auckland"));
+ QCOMPARE(nzStd.offsetFromUtc(), 43200);
+ QVERIFY(!nzStd.isDaylightTime());
+ QCOMPARE(nzStd.toMSecsSinceEpoch(), utcStd.toMSecsSinceEpoch());
+
+ QVERIFY(nzStdOffset.isValid());
+ QCOMPARE(nzStdOffset.timeSpec(), Qt::TimeZone);
+ QCOMPARE(nzStdOffset.date(), QDate(2012, 6, 1));
+ QCOMPARE(nzStdOffset.time(), QTime(12, 0));
+ QVERIFY(nzStdOffset.timeZone() == nzTzOffset);
+ QCOMPARE(nzStdOffset.timeZone().id(), QByteArray("UTC+12:00"));
+ QCOMPARE(nzStdOffset.offsetFromUtc(), 43200);
+ QVERIFY(!nzStdOffset.isDaylightTime());
+ QCOMPARE(nzStdOffset.toMSecsSinceEpoch(), utcStd.toMSecsSinceEpoch());
+
+ // During Daylight Time NZ is +13:00
+ QDateTime utcDst(QDate(2012, 1, 1), QTime(0, 0), UTC);
+ QDateTime nzDst(QDate(2012, 1, 1), QTime(13, 0), nzTz);
+
+ QVERIFY(nzDst.isValid());
+ QCOMPARE(nzDst.date(), QDate(2012, 1, 1));
+ QCOMPARE(nzDst.time(), QTime(13, 0));
+ QCOMPARE(nzDst.offsetFromUtc(), 46800);
+ QVERIFY(nzDst.isDaylightTime());
+ QCOMPARE(nzDst.toMSecsSinceEpoch(), utcDst.toMSecsSinceEpoch());
+
+ QDateTime utc = nzStd.toUTC();
+ QCOMPARE(utc.date(), utcStd.date());
+ QCOMPARE(utc.time(), utcStd.time());
+
+ utc = nzDst.toUTC();
+ QCOMPARE(utc.date(), utcDst.date());
+ QCOMPARE(utc.time(), utcDst.time());
+
+ // Crash test, QTBUG-80146:
+ QVERIFY(!nzStd.toTimeZone(QTimeZone()).isValid());
+
+ // Sydney is 2 hours behind New Zealand
+ QTimeZone ausTz = QTimeZone("Australia/Sydney");
+ QDateTime aus = nzStd.toTimeZone(ausTz);
+ QCOMPARE(aus.date(), QDate(2012, 6, 1));
+ QCOMPARE(aus.time(), QTime(10, 0));
+
+ QDateTime dt1(QDate(2012, 6, 1), QTime(0, 0), UTC);
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+ dt1.setTimeZone(nzTz);
+ QCOMPARE(dt1.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt1.date(), QDate(2012, 6, 1));
+ QCOMPARE(dt1.time(), QTime(0, 0));
+ QCOMPARE(dt1.timeZone(), nzTz);
+
+ QDateTime dt2 = QDateTime::fromSecsSinceEpoch(1338465600, nzTz);
+ QCOMPARE(dt2.date(), dt1.date());
+ QCOMPARE(dt2.time(), dt1.time());
+ QCOMPARE(dt2.timeSpec(), dt1.timeSpec());
+ QCOMPARE(dt2.timeRepresentation(), dt1.timeRepresentation());
+
+ QDateTime dt3 = QDateTime::fromMSecsSinceEpoch(1338465600000, nzTz);
+ QCOMPARE(dt3.date(), dt1.date());
+ QCOMPARE(dt3.time(), dt1.time());
+ QCOMPARE(dt3.timeSpec(), dt1.timeSpec());
+ QCOMPARE(dt3.timeRepresentation(), dt1.timeRepresentation());
+
+ // The start of year 1 should be *describable* in any zone (QTBUG-78051)
+ dt3 = QDateTime(QDate(1, 1, 1), QTime(0, 0), ausTz);
+ QVERIFY(dt3.isValid());
+ // Likewise the end of year -1 (a.k.a. 1 BCE).
+ dt3 = dt3.addMSecs(-1);
+ QVERIFY(dt3.isValid());
+ QCOMPARE(dt3, QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59, 999), ausTz));
+
+ // Check datastream serialises the time zone
+ QByteArray tmp;
+ {
+ QDataStream ds(&tmp, QIODevice::WriteOnly);
+ ds << dt1;
+ }
+ QDateTime dt4;
+ {
+ QDataStream ds(&tmp, QIODevice::ReadOnly);
+ ds >> dt4;
+ }
+ QCOMPARE(dt4, dt1);
+ QCOMPARE(dt4.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt4.timeZone(), nzTz);
+
+ // Check handling of transition times
+ QTimeZone cet("Europe/Oslo");
+
+ // Standard Time to Daylight Time 2013 on 2013-03-31 is 2:00 local time / 1:00 UTC
+ const qint64 gapMSecs = 1364691600000;
+ QCOMPARE(gapMSecs, QDateTime(QDate(2013, 3, 31), QTime(1, 0), UTC).toMSecsSinceEpoch());
+
+ // Test MSecs to local
+ // - Test 1 msec before tran = 01:59:59.999
+ QDateTime beforeGap = QDateTime::fromMSecsSinceEpoch(gapMSecs - 1, cet);
+ QCOMPARE(beforeGap.date(), QDate(2013, 3, 31));
+ QCOMPARE(beforeGap.time(), QTime(1, 59, 59, 999));
+ // - Test at tran = 03:00:00
+ QDateTime atGap = QDateTime::fromMSecsSinceEpoch(gapMSecs, cet);
+ QCOMPARE(atGap.date(), QDate(2013, 3, 31));
+ QCOMPARE(atGap.time(), QTime(3, 0));
+
+ // Test local to MSecs
+ // - Test 1 msec before tran = 01:59:59.999
+ beforeGap = QDateTime(QDate(2013, 3, 31), QTime(1, 59, 59, 999), cet);
+ QCOMPARE(beforeGap.toMSecsSinceEpoch(), gapMSecs - 1);
+ // - Test at tran = 03:00:00
+ atGap = QDateTime(QDate(2013, 3, 31), QTime(3, 0), cet);
+ QCOMPARE(atGap.toMSecsSinceEpoch(), gapMSecs);
+ // - Test transition hole, setting 03:00:00 is valid
+ atGap = QDateTime(QDate(2013, 3, 31), QTime(3, 0), cet);
+ QVERIFY(atGap.isValid());
+ QCOMPARE(atGap.date(), QDate(2013, 3, 31));
+ QCOMPARE(atGap.time(), QTime(3, 0));
+ QCOMPARE(atGap.toMSecsSinceEpoch(), gapMSecs);
+ // - Test transition hole, setting 02:00:00 is invalid
+ QDateTime inGap = QDateTime(QDate(2013, 3, 31), QTime(2, 0), cet);
+ QVERIFY(inGap.isValid());
+ QCOMPARE(inGap.date(), QDate(2013, 3, 31));
+ QCOMPARE(inGap.time(), QTime(3, 0));
+ QCOMPARE(inGap.offsetFromUtc(), 7200);
+ // - Test transition hole, 02:59:59.999 was skipped:
+ inGap = QDateTime(QDate(2013, 3, 31), QTime(2, 59, 59, 999), cet);
+ QVERIFY(inGap.isValid());
+ QCOMPARE(inGap.date(), QDate(2013, 3, 31));
+ QCOMPARE(inGap.time(), QTime(3, 59, 59, 999));
+ QCOMPARE(inGap.offsetFromUtc(), 7200);
+ // Test similar for local time, if it's CET:
+ if (zoneIsCET) {
+ inGap = QDateTime(QDate(2013, 3, 31), QTime(2, 30));
+ QVERIFY(inGap.isValid());
+ QCOMPARE(inGap.date(), QDate(2013, 3, 31));
+ QCOMPARE(inGap.offsetFromUtc(), 7200);
+ QCOMPARE(inGap.time(), QTime(3, 30));
+ }
+
+ // Test a gap more than 1'141'707.91-years from 1970, outside ShortData's range,
+ // The zone version is non-short in any case, but check it anyway.
+ // However, we can only test this if the underlying OS believes CET continues
+ // exercising DST indefinitely; Darwin, for example, assumes we'll have all
+ // kicked the habit by the end of 2100.
+ constexpr int longYear = 1'143'678;
+ constexpr qint64 millisInWeek = qint64(7) * 24 * 60 * 60 * 1000;
+ if (QDateTime(QDate(longYear, 3, 24), QTime(12, 0), cet).msecsTo(
+ QDateTime(QDate(longYear, 3, 31), QTime(12, 0), cet)) < millisInWeek) {
+ inGap = QDateTime(QDate(longYear, 3, 27), QTime(2, 30), cet);
+ QVERIFY(inGap.isValid());
+ QCOMPARE(inGap.date(), QDate(longYear, 3, 27));
+ QCOMPARE(inGap.time(), QTime(3, 30));
+ QCOMPARE(inGap.offsetFromUtc(), 7200);
+ } else {
+ qDebug("Skipping far-future check beyond zoned end of DST");
+ }
+ if (zoneIsCET && QDateTime(QDate(longYear, 3, 24), QTime(12, 0)).msecsTo(
+ QDateTime(QDate(longYear, 3, 31), QTime(12, 0))) < millisInWeek) {
+ inGap = QDateTime(QDate(longYear, 3, 27), QTime(2, 30));
+ QVERIFY(inGap.isValid());
+ QCOMPARE(inGap.date(), QDate(longYear, 3, 27));
+ QCOMPARE(inGap.offsetFromUtc(), 7200);
+ QCOMPARE(inGap.time(), QTime(3, 30));
+ } else {
+ qDebug(zoneIsCET ? "Skipping far-future check beyond local end of DST"
+ : "Skipping CET-specific test");
+ }
+
+ // Standard Time to Daylight Time 2013 on 2013-10-27 is 3:00 local time / 1:00 UTC
+ const qint64 replayMSecs = 1382835600000;
+ QCOMPARE(replayMSecs, QDateTime(QDate(2013, 10, 27), QTime(1, 0), UTC).toMSecsSinceEpoch());
+
+ // Test MSecs to local
+ // - Test 1 hour before tran = 02:00:00 local first occurrence
+ QDateTime startFirst = QDateTime::fromMSecsSinceEpoch(replayMSecs - 3600000, cet);
+ QCOMPARE(startFirst.date(), QDate(2013, 10, 27));
+ QCOMPARE(startFirst.time(), QTime(2, 0));
+ // - Test 1 msec before tran = 02:59:59.999 local first occurrence
+ QDateTime endFirst = QDateTime::fromMSecsSinceEpoch(replayMSecs - 1, cet);
+ QCOMPARE(endFirst.date(), QDate(2013, 10, 27));
+ QCOMPARE(endFirst.time(), QTime(2, 59, 59, 999));
+ // - Test at tran = 03:00:00 local becomes 02:00:00 local second occurrence
+ QDateTime startRepeat = QDateTime::fromMSecsSinceEpoch(replayMSecs, cet);
+ QCOMPARE(startRepeat.date(), QDate(2013, 10, 27));
+ QCOMPARE(startRepeat.time(), QTime(2, 0));
+ // - Test 59 mins after tran = 02:59:59.999 local second occurrence
+ QDateTime endRepeat = QDateTime::fromMSecsSinceEpoch(replayMSecs + 3600000 -1, cet);
+ QCOMPARE(endRepeat.date(), QDate(2013, 10, 27));
+ QCOMPARE(endRepeat.time(), QTime(2, 59, 59, 999));
+ // - Test 1 hour after tran = 03:00:00 local
+ QDateTime hourAfter = QDateTime::fromMSecsSinceEpoch(replayMSecs + 3600000, cet);
+ QCOMPARE(hourAfter.date(), QDate(2013, 10, 27));
+ QCOMPARE(hourAfter.time(), QTime(3, 0));
+
+ // TODO (QTBUG-79923): Compare to results of direct QDateTime(date, time, cet, fold)
+ // construction; see Prior/Post commented-out tests.
+
+ // Test local to MSecs
+ // - Test first occurrence 02:00:00 = 1 hour before tran
+ startFirst = QDateTime(QDate(2013, 10, 27), QTime(1, 59, 59), cet).addSecs(1);
+ // QCOMPARE(startFirst, QDateTime(QDate(2013, 10, 27), QTime(2, 0), cet, Prior));
+ QCOMPARE(startFirst.toMSecsSinceEpoch(), replayMSecs - 3600000);
+ // - Test first occurrence 02:59:59.999 = 1 msec before tran
+ endFirst = startFirst.addMSecs(3599999);
+ // QCOMPARE(endFirst, QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet, Prior));
+ QCOMPARE(endFirst.toMSecsSinceEpoch(), replayMSecs - 1);
+ // - Test second occurrence 02:00:00 = at tran
+ startRepeat = endFirst.addMSecs(1);
+ // QCOMPARE(startRepeat, QDateTime(QDate(2013, 10, 27), QTime(2, 0), cet, Post));
+ QCOMPARE(startRepeat.toMSecsSinceEpoch(), replayMSecs);
+ // - Test second occurrence 02:59:59.999 = 1 msec before 1 hour after tran
+ endRepeat = startRepeat.addMSecs(3599999);
+ // QCOMPARE(endRepeat, QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet, Post));
+ QCOMPARE(endRepeat.toMSecsSinceEpoch(), replayMSecs + 3600000 - 1);
+ // - Test 03:00:00 = 1 hour after tran (no ambiguity)
+ hourAfter = endRepeat.addMSecs(1);
+ QCOMPARE(hourAfter, QDateTime(QDate(2013, 10, 27), QTime(3, 0), cet));
+ QCOMPARE(hourAfter.toMSecsSinceEpoch(), replayMSecs + 3600000);
+
+ // Test Time Zone that has transitions but no future transitions afer a given date
+ QTimeZone sgt("Asia/Singapore");
+ QDateTime future(QDate(2015, 1, 1), QTime(0, 0), sgt);
+ QVERIFY(future.isValid());
+ QCOMPARE(future.offsetFromUtc(), 28800);
+#else
+ QSKIP("Needs timezone feature enabled");
+#endif
+}
+
+void tst_QDateTime::systemTimeZoneChange_data() const
+{
+ QTest::addColumn<QDate>("date");
+ QTest::newRow("short") << QDate(1970, 1, 1);
+ QTest::newRow("2012") << QDate(2012, 6, 1); // short on 64-bit, pimpled on 32-bit
+ QTest::newRow("pimpled") << QDate(1150000, 6, 1);
+}
+
+void tst_QDateTime::systemTimeZoneChange() const
+{
+ QFETCH(const QDate, date);
+ const QTime early(2, 15, 30);
+
+ // Start out in Brisbane time:
+ TimeZoneRollback useZone(QByteArray("AEST-10:00"));
+ if (QDateTime(date, early).offsetFromUtc() != 600 * 60)
+ QSKIP("Test depends on system support for changing zone to AEST-10:00");
+#if QT_CONFIG(timezone)
+ QVERIFY(QTimeZone::systemTimeZone().isValid());
+#endif
+
+ const QDateTime localDate = QDateTime(date, early);
+ const QDateTime utcDate = QDateTime(date, early, UTC);
+ const qint64 localMsecs = localDate.toMSecsSinceEpoch();
+ const qint64 utcMsecs = utcDate.toMSecsSinceEpoch();
+#if QT_CONFIG(timezone)
+ const QTimeZone aest("Australia/Brisbane"); // no transitions since 1992
+ // Check that Australia/Brisbane is known:
+ QVERIFY(aest.isValid());
+ const QDateTime tzDate = QDateTime(date, early, aest);
+
+ // Check we got the right zone !
+ QVERIFY(tzDate.timeZone().isValid());
+ QCOMPARE(tzDate.timeZone(), aest);
+ const qint64 tzMsecs = tzDate.toMSecsSinceEpoch();
+#endif
+
+ // Change to Indian time
+ useZone.reset(QByteArray("IST-05:30"));
+ if (QDateTime(date, early).offsetFromUtc() != 330 * 60)
+ QSKIP("Test depends on system support for changing zone to IST-05:30");
+#if QT_CONFIG(timezone)
+ QVERIFY(QTimeZone::systemTimeZone().isValid());
+#endif
+
+ QCOMPARE(localDate, QDateTime(date, early));
+ // Note: localDate.toMSecsSinceEpoch == localMsecs, unchanged, iff localDate is pimpled.
+ QVERIFY(localMsecs != QDateTime(date, early).toMSecsSinceEpoch());
+ QCOMPARE(utcDate, QDateTime(date, early, UTC));
+ QCOMPARE(utcDate.toMSecsSinceEpoch(), utcMsecs);
+#if QT_CONFIG(timezone)
+ QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs);
+ QCOMPARE(tzDate.timeZone(), aest);
+ QCOMPARE(tzDate, QDateTime(date, early, aest));
+#endif
+}
+
+void tst_QDateTime::invalid_data() const
+{
+ QTest::addColumn<QDateTime>("when");
+ QTest::addColumn<Qt::TimeSpec>("spec");
+ QTest::addColumn<bool>("goodZone");
+ QTest::newRow("default") << QDateTime() << Qt::LocalTime << true;
+
+ QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1));
+ QTest::newRow("simple") << invalidDate << Qt::LocalTime << true;
+ QTest::newRow("UTC") << invalidDate.toUTC() << Qt::UTC << true;
+ QTest::newRow("offset")
+ << invalidDate.toTimeZone(QTimeZone::fromSecondsAheadOfUtc(3600)) << Qt::OffsetFromUTC
+ << true;
+#if QT_CONFIG(timezone)
+ QTest::newRow("CET")
+ << invalidDate.toTimeZone(QTimeZone("Europe/Oslo")) << Qt::TimeZone << true;
+
+ // Crash tests, QTBUG-80146:
+ QTest::newRow("nozone+construct")
+ << QDateTime(QDate(1970, 1, 1), QTime(12, 0), QTimeZone())
+ << Qt::TimeZone << false;
+ QTest::newRow("nozone+fromMSecs")
+ << QDateTime::fromMSecsSinceEpoch(42, QTimeZone()) << Qt::TimeZone << false;
+ QDateTime valid(QDate(1970, 1, 1), QTime(12, 0), UTC);
+ QTest::newRow("tonozone") << valid.toTimeZone(QTimeZone()) << Qt::TimeZone << false;
+#endif
+}
+
+void tst_QDateTime::invalid() const
+{
+ QFETCH(QDateTime, when);
+ QFETCH(Qt::TimeSpec, spec);
+ QFETCH(bool, goodZone);
+ QVERIFY(!when.isValid());
+ QCOMPARE(when.timeSpec(), spec);
+ QCOMPARE(when.timeZoneAbbreviation(), QString());
+ if (!goodZone)
+ QCOMPARE(when.toMSecsSinceEpoch(), 0);
+ QVERIFY(!when.isDaylightTime());
+ QCOMPARE(when.timeRepresentation().isValid(), goodZone);
+}
+
+void tst_QDateTime::range() const
+{
+ using Bounds = std::numeric_limits<qint64>;
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(Bounds::min() + 1, UTC).date().year(),
+ int(QDateTime::YearRange::First));
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(Bounds::max() - 1, UTC).date().year(),
+ int(QDateTime::YearRange::Last));
+ constexpr qint64 millisPerDay = 24 * 3600 * 1000;
+ constexpr qint64 wholeDays = Bounds::max() / millisPerDay;
+ constexpr qint64 millisRemainder = Bounds::max() % millisPerDay;
+ QVERIFY(QDateTime(QDate(1970, 1, 1).addDays(wholeDays),
+ QTime::fromMSecsSinceStartOfDay(millisRemainder),
+ UTC).isValid());
+ QVERIFY(!QDateTime(QDate(1970, 1, 1).addDays(wholeDays),
+ QTime::fromMSecsSinceStartOfDay(millisRemainder + 1),
+ UTC).isValid());
+ QVERIFY(QDateTime(QDate(1970, 1, 1).addDays(-wholeDays - 1),
+ QTime::fromMSecsSinceStartOfDay(3600 * 24000 - millisRemainder - 1),
+ UTC).isValid());
+ QVERIFY(!QDateTime(QDate(1970, 1, 1).addDays(-wholeDays - 1),
+ QTime::fromMSecsSinceStartOfDay(3600 * 24000 - millisRemainder - 2),
+ UTC).isValid());
+}
+
+void tst_QDateTime::macTypes()
+{
+#ifndef Q_OS_DARWIN
+ QSKIP("This is a Apple-only test");
+#else
+ extern void tst_QDateTime_macTypes(); // in qdatetime_mac.mm
+ tst_QDateTime_macTypes();
+#endif
+}
+
+#if __cpp_lib_chrono >= 201907L
+using StdSysMillis = std::chrono::sys_time<std::chrono::milliseconds>;
+Q_DECLARE_METATYPE(StdSysMillis);
+#endif
+
+void tst_QDateTime::stdCompatibilitySysTime_data()
+{
+#if __cpp_lib_chrono >= 201907L
+ QTest::addColumn<StdSysMillis>("sysTime");
+ QTest::addColumn<QDateTime>("expected");
+
+ using namespace std::chrono;
+
+ QTest::newRow("zero")
+ << StdSysMillis(0s)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0), UTC);
+ QTest::newRow("1s")
+ << StdSysMillis(1s)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 1), UTC);
+ QTest::newRow("1ms")
+ << StdSysMillis(1ms)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0, 1), UTC);
+ QTest::newRow("365d")
+ << StdSysMillis(days(365))
+ << QDateTime(QDate(1971, 1, 1), QTime(0, 0), UTC);
+ QTest::newRow("-1s")
+ << StdSysMillis(-1s)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59), UTC);
+ QTest::newRow("-1ms")
+ << StdSysMillis(-1ms)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59, 999), UTC);
+
+ {
+ // The first leap second occurred on 30 June 1972 at 23:59:60.
+ // Check that QDateTime does not take that leap second into account (like sys_time)
+ const year_month_day firstLeapSecondDate = 1972y/July/1;
+ const sys_days firstLeapSecondDateAsSysDays = firstLeapSecondDate;
+ QTest::newRow("first_leap_second")
+ << StdSysMillis(firstLeapSecondDateAsSysDays)
+ << QDateTime(QDate(1972, 7, 1), QTime(0, 0), UTC);
+ }
+
+ {
+ // Random date
+ const sys_days date = 2000y/January/31;
+ const StdSysMillis dateTime = date + 3h + 10min + 42s;
+ QTest::newRow("2000-01-31 03:10:42")
+ << dateTime
+ << QDateTime(QDate(2000, 1, 31), QTime(3, 10, 42), UTC);
+ }
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+
+void tst_QDateTime::stdCompatibilitySysTime()
+{
+#if __cpp_lib_chrono >= 201907L
+ QFETCH(StdSysMillis, sysTime);
+ QFETCH(QDateTime, expected);
+
+ using namespace std::chrono;
+
+ // system_clock in milliseconds -> QDateTime
+ QDateTime dtFromSysTime = QDateTime::fromStdTimePoint(sysTime);
+ QCOMPARE(dtFromSysTime, expected);
+ QCOMPARE(dtFromSysTime.timeSpec(), Qt::UTC);
+
+ // QDateTime -> system_clock in milliseconds
+ StdSysMillis sysTimeFromDt = dtFromSysTime.toStdSysMilliseconds();
+ QCOMPARE(sysTimeFromDt, sysTime);
+
+ // system_clock in seconds -> QDateTime
+ sys_seconds sysTimeSecs = floor<seconds>(sysTime);
+ QDateTime dtFromSysSeconds = QDateTime::fromStdTimePoint(sysTimeSecs);
+ QDateTime expectedInSeconds = expected.addMSecs(-expected.time().msec()); // "floor"
+ QCOMPARE(dtFromSysSeconds, expectedInSeconds);
+ QCOMPARE(dtFromSysSeconds.timeSpec(), Qt::UTC);
+
+ // QDateTime -> system_clock in seconds
+ sys_seconds sysTimeFromDtSecs = dtFromSysSeconds.toStdSysSeconds();
+ QCOMPARE(sysTimeFromDtSecs, sysTimeSecs);
+
+ // utc_clock in milliseconds -> QDateTime
+ utc_time<std::chrono::milliseconds> utcTime = utc_clock::from_sys(sysTime);
+ QDateTime dtFromUtcTime = QDateTime::fromStdTimePoint(utcTime);
+ QCOMPARE(dtFromUtcTime, expected);
+ QCOMPARE(dtFromUtcTime.timeSpec(), Qt::UTC);
+
+ // QDateTime -> system_clock in milliseconds
+ sysTimeFromDt = dtFromUtcTime.toStdSysMilliseconds();
+ QCOMPARE(sysTimeFromDt, sysTime);
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+
+#if __cpp_lib_chrono >= 201907L
+using StdLocalMillis = std::chrono::local_time<std::chrono::milliseconds>;
+Q_DECLARE_METATYPE(StdLocalMillis);
+#endif
+
+void tst_QDateTime::stdCompatibilityLocalTime_data()
+{
+#if __cpp_lib_chrono >= 201907L
+ QTest::addColumn<StdLocalMillis>("localTime");
+ QTest::addColumn<QDateTime>("expected");
+
+ using namespace std::chrono;
+
+ QTest::newRow("zero")
+ << StdLocalMillis(0s)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0));
+ QTest::newRow("1s")
+ << StdLocalMillis(1s)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 1));
+ QTest::newRow("1ms")
+ << StdLocalMillis(1ms)
+ << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0, 1));
+ QTest::newRow("365d")
+ << StdLocalMillis(days(365))
+ << QDateTime(QDate(1971, 1, 1), QTime(0, 0));
+ QTest::newRow("-1s")
+ << StdLocalMillis(-1s)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59));
+ QTest::newRow("-1ms")
+ << StdLocalMillis(-1ms)
+ << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59, 999));
+ {
+ // Random date
+ const local_days date = local_days(2000y/January/31);
+ const StdLocalMillis dateTime = date + 3h + 10min + 42s;
+ QTest::newRow("2000-01-31 03:10:42")
+ << dateTime
+ << QDateTime(QDate(2000, 1, 31), QTime(3, 10, 42));
+ }
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+
+void tst_QDateTime::stdCompatibilityLocalTime()
+{
+#if __cpp_lib_chrono >= 201907L
+ QFETCH(StdLocalMillis, localTime);
+ QFETCH(QDateTime, expected);
+
+ using namespace std::chrono;
+
+ QDateTime dtFromLocalTime = QDateTime::fromStdLocalTime(localTime);
+ QCOMPARE(dtFromLocalTime, expected);
+ QCOMPARE(dtFromLocalTime.timeSpec(), Qt::LocalTime);
+
+ const time_zone *tz = current_zone();
+ QVERIFY(tz);
+ const StdSysMillis sysMillis = tz->to_sys(localTime);
+ QCOMPARE(dtFromLocalTime.toStdSysMilliseconds(), sysMillis);
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+
+#if QT_CONFIG(timezone)
+#if __cpp_lib_chrono >= 201907L
+using StdZonedMillis = std::chrono::zoned_time<std::chrono::milliseconds>;
+Q_DECLARE_METATYPE(StdZonedMillis);
+#endif
+
+void tst_QDateTime::stdCompatibilityZonedTime_data()
+{
+#if __cpp_lib_chrono >= 201907L
+ QTest::addColumn<StdZonedMillis>("zonedTime");
+ QTest::addColumn<QDateTime>("expected");
+
+ using namespace std::chrono;
+ using namespace std::literals;
+
+ const char timeZoneName[] = "Europe/Oslo";
+ const QTimeZone timeZone(timeZoneName);
+
+ {
+ StdZonedMillis zs(timeZoneName, local_days(2021y/1/1));
+ QTest::addRow("localTimeOslo")
+ << zs
+ << QDateTime(QDate(2021, 1, 1), QTime(0, 0), timeZone);
+ }
+ {
+ StdZonedMillis zs(timeZoneName, sys_days(2021y/1/1));
+ QTest::addRow("sysTimeOslo")
+ << zs
+ << QDateTime(QDate(2021, 1, 1), QTime(1, 0), timeZone);
+ }
+ {
+ StdZonedMillis zs(timeZoneName, sys_days(2021y/7/1));
+ QTest::addRow("sysTimeOslo summer")
+ << zs
+ << QDateTime(QDate(2021, 7, 1), QTime(2, 0), timeZone);
+ }
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+
+void tst_QDateTime::stdCompatibilityZonedTime()
+{
+#if __cpp_lib_chrono >= 201907L
+ QFETCH(StdZonedMillis, zonedTime);
+ QFETCH(QDateTime, expected);
+
+ QDateTime dtFromZonedTime = QDateTime::fromStdZonedTime(zonedTime);
+ QCOMPARE(dtFromZonedTime, expected);
+ QCOMPARE(dtFromZonedTime.timeSpec(), Qt::TimeZone);
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+#endif // QT_CONFIG(timezone)
+
+QTEST_APPLESS_MAIN(tst_QDateTime)
+#include "tst_qdatetime.moc"
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime_mac.mm b/tests/auto/corelib/time/qdatetime/tst_qdatetime_mac.mm
new file mode 100644
index 0000000000..08379ccb41
--- /dev/null
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime_mac.mm
@@ -0,0 +1,47 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2014 Petroules Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QDateTime>
+#include <QTest>
+
+#include <QtCore/private/qcore_mac_p.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Foundation/Foundation.h>
+
+void tst_QDateTime_macTypes()
+{
+ // QDateTime <-> CFDate
+
+ static const int kMsPerSecond = 1000;
+
+ for (int i = 0; i < kMsPerSecond; ++i) {
+ QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(i);
+ const CFDateRef cfDate = qtDateTime.toCFDate();
+ QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTime);
+ CFRelease(cfDate);
+ }
+ {
+ QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0);
+ const CFDateRef cfDate = qtDateTime.toCFDate();
+ QDateTime qtDateTimeCopy(qtDateTime);
+ qtDateTime.setSecsSinceEpoch(10000); // modify
+ QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTimeCopy);
+ }
+ // QDateTime <-> NSDate
+ for (int i = 0; i < kMsPerSecond; ++i) {
+ QMacAutoReleasePool pool;
+ QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(i);
+ const NSDate *nsDate = qtDateTime.toNSDate();
+ QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTime);
+ }
+ {
+ QMacAutoReleasePool pool;
+ QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0);
+ const NSDate *nsDate = qtDateTime.toNSDate();
+ QDateTime qtDateTimeCopy(qtDateTime);
+ qtDateTime.setSecsSinceEpoch(10000); // modify
+ QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTimeCopy);
+ }
+}
diff --git a/tests/auto/corelib/time/qdatetimeparser/.gitignore b/tests/auto/corelib/time/qdatetimeparser/.gitignore
new file mode 100644
index 0000000000..880d073ac8
--- /dev/null
+++ b/tests/auto/corelib/time/qdatetimeparser/.gitignore
@@ -0,0 +1 @@
+tst_qdatetimeparser
diff --git a/tests/auto/corelib/time/qdatetimeparser/CMakeLists.txt b/tests/auto/corelib/time/qdatetimeparser/CMakeLists.txt
new file mode 100644
index 0000000000..6bdd66ebfc
--- /dev/null
+++ b/tests/auto/corelib/time/qdatetimeparser/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdatetimeparser Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatetimeparser LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qdatetimeparser
+ SOURCES
+ tst_qdatetimeparser.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/time/qdatetimeparser/tst_qdatetimeparser.cpp b/tests/auto/corelib/time/qdatetimeparser/tst_qdatetimeparser.cpp
new file mode 100644
index 0000000000..bfc811eebe
--- /dev/null
+++ b/tests/auto/corelib/time/qdatetimeparser/tst_qdatetimeparser.cpp
@@ -0,0 +1,211 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <private/qdatetimeparser_p.h>
+
+using namespace Qt::StringLiterals;
+
+QT_BEGIN_NAMESPACE
+
+// access to needed members in QDateTimeParser
+class QDTPUnitTestParser : public QDateTimeParser
+{
+public:
+ QDTPUnitTestParser() : QDateTimeParser(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit) { }
+
+ // forward data structures
+ using QDateTimeParser::ParsedSection;
+ using QDateTimeParser::State;
+
+ // function to manipulate private internals
+ void setText(QString text) { m_text = text; }
+
+ // forwarding of methods
+ using QDateTimeParser::parseSection;
+};
+
+bool operator==(const QDTPUnitTestParser::ParsedSection &a,
+ const QDTPUnitTestParser::ParsedSection &b)
+{
+ return a.value == b.value && a.used == b.used && a.zeroes == b.zeroes && a.state == b.state;
+}
+
+// pretty printing for ParsedSection
+char *toString(const QDTPUnitTestParser::ParsedSection &section)
+{
+ using QTest::toString;
+ return toString(QByteArray("ParsedSection(") + "state=" + QByteArray::number(section.state)
+ + ", value=" + QByteArray::number(section.value)
+ + ", used=" + QByteArray::number(section.used)
+ + ", zeros=" + QByteArray::number(section.zeroes) + ")");
+}
+
+QT_END_NAMESPACE
+
+class tst_QDateTimeParser : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void reparse();
+ void parseSection_data();
+ void parseSection();
+
+ void intermediateYear_data();
+ void intermediateYear();
+};
+
+void tst_QDateTimeParser::reparse()
+{
+ const QDateTime when = QDate(2023, 6, 15).startOfDay();
+ // QTBUG-114575: 6.2 through 6.5 got back a bogus Qt::TimeZone (with zero offset):
+ const auto expect = ([](QStringView name) {
+ // When local time is UTC or a fixed offset from it, the parser prefers
+ // to interpret a UTC or offset suffix as such, rather than as local
+ // time (thereby avoiding DST-ness checks). We have to match that here.
+ if (name == "UTC"_L1)
+ return Qt::UTC;
+ if (name.startsWith(u'+') || name.startsWith(u'-')) {
+ if (std::all_of(name.begin() + 1, name.end(), [](QChar ch) { return ch == u'0'; }))
+ return Qt::UTC;
+ if (std::all_of(name.begin() + 1, name.end(), [](QChar ch) { return ch.isDigit(); }))
+ return Qt::OffsetFromUTC;
+ // Potential hh:mm offset ? Not yet seen as local tzname[] entry.
+ }
+ return Qt::LocalTime;
+ });
+
+ const QStringView format = u"dd/MM/yyyy HH:mm t";
+ QDateTimeParser who(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit);
+ QVERIFY(who.parseFormat(format));
+ {
+ // QDTP defaults to the system locale.
+ const auto state = who.parse(QLocale::system().toString(when, format), -1, when, false);
+ QCOMPARE(state.state, QDateTimeParser::Acceptable);
+ QVERIFY(!state.conflicts);
+ QCOMPARE(state.padded, 0);
+ QCOMPARE(state.value.timeSpec(), expect(when.timeZoneAbbreviation()));
+ QCOMPARE(state.value, when);
+ }
+ {
+ // QDT::toString() uses the C locale:
+ who.setDefaultLocale(QLocale::c());
+ const QString zoneName = ([when]() {
+#if QT_CONFIG(timezone)
+ if (QLocale::c() != QLocale::system()) {
+ const QString local = when.timeRepresentation().displayName(
+ when, QTimeZone::ShortName, QLocale::c());
+ if (!local.isEmpty())
+ return local;
+ }
+#endif
+ return when.timeZoneAbbreviation();
+ })();
+ const auto state = who.parse(when.toString(format), -1, when, false);
+ QCOMPARE(state.state, QDateTimeParser::Acceptable);
+ QVERIFY(!state.conflicts);
+ QCOMPARE(state.padded, 0);
+ QCOMPARE(state.value.timeSpec(), expect(zoneName));
+ QCOMPARE(state.value, when);
+ }
+}
+
+void tst_QDateTimeParser::parseSection_data()
+{
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<int>("sectionIndex");
+ QTest::addColumn<int>("offset");
+ QTest::addColumn<QDTPUnitTestParser::ParsedSection>("expected");
+
+ using ParsedSection = QDTPUnitTestParser::ParsedSection;
+ using State = QDTPUnitTestParser::State;
+ QTest::newRow("short-year-begin")
+ << "yyyy_MM_dd" << "200_12_15" << 0 << 0
+ << ParsedSection(State::Intermediate ,200, 3, 0);
+
+ QTest::newRow("short-year-middle")
+ << "MM-yyyy-dd" << "12-200-15" << 1 << 3
+ << ParsedSection(State::Intermediate, 200, 3, 0);
+
+ QTest::newRow("negative-year-middle-5")
+ << "MM-yyyy-dd" << "12--2000-15" << 1 << 3
+ << ParsedSection(State::Acceptable, -2000, 5, 0);
+
+ QTest::newRow("short-negative-year-middle-4")
+ << "MM-yyyy-dd" << "12--200-15" << 1 << 3
+ << ParsedSection(State::Intermediate, -200, 4, 0);
+
+ QTest::newRow("short-negative-year-middle-3")
+ << "MM-yyyy-dd" << "12--20-15" << 1 << 3
+ << ParsedSection(State::Intermediate, -20, 3, 0);
+
+ QTest::newRow("short-negative-year-middle-2")
+ << "MM-yyyy-dd" << "12--2-15" << 1 << 3
+ << ParsedSection(State::Intermediate, -2, 2, 0);
+
+ QTest::newRow("short-negative-year-middle-1")
+ << "MM-yyyy-dd" << "12---15" << 1 << 3
+ << ParsedSection(State::Intermediate, 0, 1, 0);
+
+ // Here the -15 will be understood as year, with separator and day omitted,
+ // although it could equally be read as month and day with missing year.
+ QTest::newRow("short-negative-year-middle-0")
+ << "MM-yyyy-dd" << "12--15" << 1 << 3
+ << ParsedSection(State::Intermediate, -15, 3, 0);
+}
+
+void tst_QDateTimeParser::parseSection()
+{
+ QFETCH(QString, format);
+ QFETCH(QString, input);
+ QFETCH(int, sectionIndex);
+ QFETCH(int, offset);
+ QFETCH(QDTPUnitTestParser::ParsedSection, expected);
+
+ QDTPUnitTestParser testParser;
+
+ QVERIFY(testParser.parseFormat(format));
+ QDateTime val(QDate(1900, 1, 1).startOfDay());
+
+ testParser.setText(input);
+ auto result = testParser.parseSection(val, sectionIndex, offset);
+ QCOMPARE(result, expected);
+}
+
+void tst_QDateTimeParser::intermediateYear_data()
+{
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QDate>("expected");
+
+ QTest::newRow("short-year-begin")
+ << "yyyy_MM_dd" << "200_12_15" << QDate(200, 12, 15);
+ QTest::newRow("short-year-mid")
+ << "MM_yyyy_dd" << "12_200_15" << QDate(200, 12, 15);
+ QTest::newRow("short-year-end")
+ << "MM_dd_yyyy" << "12_15_200" << QDate(200, 12, 15);
+}
+
+void tst_QDateTimeParser::intermediateYear()
+{
+ QFETCH(QString, format);
+ QFETCH(QString, input);
+ QFETCH(QDate, expected);
+
+ QDateTimeParser testParser(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit);
+
+ QVERIFY(testParser.parseFormat(format));
+
+ // Indian/Cocos has a transition at the start of 1900, so it started this
+ // day at 00:02:20, throwing a time offset into QDTP.
+ QDateTime val(QDate(1900, 1, 1).startOfDay());
+ const QDateTimeParser::StateNode tmp = testParser.parse(input, -1, val, false);
+ QCOMPARE(tmp.state, QDateTimeParser::Intermediate);
+ QCOMPARE(tmp.value.date(), expected);
+}
+
+QTEST_APPLESS_MAIN(tst_QDateTimeParser)
+
+#include "tst_qdatetimeparser.moc"
diff --git a/tests/auto/corelib/tools/qtime/.gitignore b/tests/auto/corelib/time/qtime/.gitignore
index 26a4c65cc2..26a4c65cc2 100644
--- a/tests/auto/corelib/tools/qtime/.gitignore
+++ b/tests/auto/corelib/time/qtime/.gitignore
diff --git a/tests/auto/corelib/time/qtime/CMakeLists.txt b/tests/auto/corelib/time/qtime/CMakeLists.txt
new file mode 100644
index 0000000000..6fe2968107
--- /dev/null
+++ b/tests/auto/corelib/time/qtime/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtime Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtime LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtime
+ SOURCES
+ tst_qtime.cpp
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_KEYWORDS
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/time/qtime/tst_qtime.cpp b/tests/auto/corelib/time/qtime/tst_qtime.cpp
new file mode 100644
index 0000000000..c0fdb07115
--- /dev/null
+++ b/tests/auto/corelib/time/qtime/tst_qtime.cpp
@@ -0,0 +1,691 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <private/qglobal_p.h>
+#include <private/qcomparisontesthelper_p.h>
+#include <QTest>
+#include "qdatetime.h"
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+# include <locale.h>
+#endif
+
+class tst_QTime : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void msecsTo_data();
+ void msecsTo();
+ void secsTo_data();
+ void secsTo();
+ void setHMS_data();
+ void setHMS();
+ void hour_data();
+ void hour();
+ void isValid();
+ void isNull();
+ void addMSecs_data();
+ void addMSecs();
+ void addSecs_data();
+ void addSecs();
+ void orderingCompiles();
+ void operator_eq_eq_data();
+ void operator_eq_eq();
+ void ordering_data();
+ void ordering();
+#if QT_CONFIG(datestring)
+# if QT_CONFIG(datetimeparser)
+ void fromStringFormat_data();
+ void fromStringFormat();
+# endif
+ void fromStringDateFormat_data();
+ void fromStringDateFormat();
+ void toStringDateFormat_data();
+ void toStringDateFormat();
+ void toStringFormat_data();
+ void toStringFormat();
+#endif
+ void msecsSinceStartOfDay_data();
+ void msecsSinceStartOfDay();
+
+private:
+ QTime invalidTime() { return QTime(-1, -1, -1); }
+};
+
+Q_DECLARE_METATYPE(Qt::DateFormat)
+
+void tst_QTime::addSecs_data()
+{
+ QTest::addColumn<QTime>("t1");
+ QTest::addColumn<int>("i");
+ QTest::addColumn<QTime>("exp");
+
+ QTest::newRow("Data0") << QTime(0,0,0) << 200 << QTime(0,3,20);
+ QTest::newRow("Data1") << QTime(0,0,0) << 20 << QTime(0,0,20);
+ QTest::newRow("overflow")
+ << QTime(0,0,0) << (INT_MAX / 1000 + 1)
+ << QTime::fromMSecsSinceStartOfDay(((INT_MAX / 1000 + 1) % 86400) * 1000);
+}
+
+void tst_QTime::addSecs()
+{
+ QFETCH( QTime, t1 );
+ QFETCH( int, i );
+ QTime t2;
+ t2 = t1.addSecs( i );
+ QFETCH( QTime, exp );
+ QCOMPARE( t2, exp );
+}
+
+void tst_QTime::addMSecs_data()
+{
+ QTest::addColumn<QTime>("t1");
+ QTest::addColumn<int>("i");
+ QTest::addColumn<QTime>("exp");
+
+ // start with testing positive values
+ QTest::newRow( "Data1_0") << QTime(0,0,0,0) << 2000 << QTime(0,0,2,0);
+ QTest::newRow( "Data1_1") << QTime(0,0,0,0) << 200 << QTime(0,0,0,200);
+ QTest::newRow( "Data1_2") << QTime(0,0,0,0) << 20 << QTime(0,0,0,20);
+ QTest::newRow( "Data1_3") << QTime(0,0,0,1) << 1 << QTime(0,0,0,2);
+ QTest::newRow( "Data1_4") << QTime(0,0,0,0) << 0 << QTime(0,0,0,0);
+
+ QTest::newRow( "Data2_0") << QTime(0,0,0,98) << 0 << QTime(0,0,0,98);
+ QTest::newRow( "Data2_1") << QTime(0,0,0,98) << 1 << QTime(0,0,0,99);
+ QTest::newRow( "Data2_2") << QTime(0,0,0,98) << 2 << QTime(0,0,0,100);
+ QTest::newRow( "Data2_3") << QTime(0,0,0,98) << 3 << QTime(0,0,0,101);
+
+ QTest::newRow( "Data3_0") << QTime(0,0,0,998) << 0 << QTime(0,0,0,998);
+ QTest::newRow( "Data3_1") << QTime(0,0,0,998) << 1 << QTime(0,0,0,999);
+ QTest::newRow( "Data3_2") << QTime(0,0,0,998) << 2 << QTime(0,0,1,0);
+ QTest::newRow( "Data3_3") << QTime(0,0,0,998) << 3 << QTime(0,0,1,1);
+
+ QTest::newRow( "Data4_0") << QTime(0,0,1,995) << 4 << QTime(0,0,1,999);
+ QTest::newRow( "Data4_1") << QTime(0,0,1,995) << 5 << QTime(0,0,2,0);
+ QTest::newRow( "Data4_2") << QTime(0,0,1,995) << 6 << QTime(0,0,2,1);
+ QTest::newRow( "Data4_3") << QTime(0,0,1,995) << 100 << QTime(0,0,2,95);
+ QTest::newRow( "Data4_4") << QTime(0,0,1,995) << 105 << QTime(0,0,2,100);
+
+ QTest::newRow( "Data5_0") << QTime(0,0,59,995) << 4 << QTime(0,0,59,999);
+ QTest::newRow( "Data5_1") << QTime(0,0,59,995) << 5 << QTime(0,1,0,0);
+ QTest::newRow( "Data5_2") << QTime(0,0,59,995) << 6 << QTime(0,1,0,1);
+ QTest::newRow( "Data5_3") << QTime(0,0,59,995) << 1006 << QTime(0,1,1,1);
+
+ QTest::newRow( "Data6_0") << QTime(0,59,59,995) << 4 << QTime(0,59,59,999);
+ QTest::newRow( "Data6_1") << QTime(0,59,59,995) << 5 << QTime(1,0,0,0);
+ QTest::newRow( "Data6_2") << QTime(0,59,59,995) << 6 << QTime(1,0,0,1);
+ QTest::newRow( "Data6_3") << QTime(0,59,59,995) << 106 << QTime(1,0,0,101);
+ QTest::newRow( "Data6_4") << QTime(0,59,59,995) << 1004 << QTime(1,0,0,999);
+ QTest::newRow( "Data6_5") << QTime(0,59,59,995) << 1005 << QTime(1,0,1,0);
+ QTest::newRow( "Data6_6") << QTime(0,59,59,995) << 61006 << QTime(1,1,1,1);
+
+ QTest::newRow( "Data7_0") << QTime(23,59,59,995) << 0 << QTime(23,59,59,995);
+ QTest::newRow( "Data7_1") << QTime(23,59,59,995) << 4 << QTime(23,59,59,999);
+ QTest::newRow( "Data7_2") << QTime(23,59,59,995) << 5 << QTime(0,0,0,0);
+ QTest::newRow( "Data7_3") << QTime(23,59,59,995) << 6 << QTime(0,0,0,1);
+ QTest::newRow( "Data7_4") << QTime(23,59,59,995) << 7 << QTime(0,0,0,2);
+
+ // must test negative values too...
+ QTest::newRow( "Data11_0") << QTime(0,0,2,0) << -2000 << QTime(0,0,0,0);
+ QTest::newRow( "Data11_1") << QTime(0,0,0,200) << -200 << QTime(0,0,0,0);
+ QTest::newRow( "Data11_2") << QTime(0,0,0,20) << -20 << QTime(0,0,0,0);
+ QTest::newRow( "Data11_3") << QTime(0,0,0,2) << -1 << QTime(0,0,0,1);
+ QTest::newRow( "Data11_4") << QTime(0,0,0,0) << -0 << QTime(0,0,0,0);
+
+ QTest::newRow( "Data12_0") << QTime(0,0,0,98) << -0 << QTime(0,0,0,98);
+ QTest::newRow( "Data12_1") << QTime(0,0,0,99) << -1 << QTime(0,0,0,98);
+ QTest::newRow( "Data12_2") << QTime(0,0,0,100) << -2 << QTime(0,0,0,98);
+ QTest::newRow( "Data12_3") << QTime(0,0,0,101) << -3 << QTime(0,0,0,98);
+
+ QTest::newRow( "Data13_0") << QTime(0,0,0,998) << -0 << QTime(0,0,0,998);
+ QTest::newRow( "Data13_1") << QTime(0,0,0,999) << -1 << QTime(0,0,0,998);
+ QTest::newRow( "Data13_2") << QTime(0,0,1,0) << -2 << QTime(0,0,0,998);
+ QTest::newRow( "Data13_3") << QTime(0,0,1,1) << -3 << QTime(0,0,0,998);
+
+ QTest::newRow( "Data14_0") << QTime(0,0,1,999) << -4 << QTime(0,0,1,995);
+ QTest::newRow( "Data14_1") << QTime(0,0,2,0) << -5 << QTime(0,0,1,995);
+ QTest::newRow( "Data14_2") << QTime(0,0,2,1) << -6 << QTime(0,0,1,995);
+ QTest::newRow( "Data14_3") << QTime(0,0,2,95) << -100 << QTime(0,0,1,995);
+ QTest::newRow( "Data14_4") << QTime(0,0,2,100) << -105 << QTime(0,0,1,995);
+
+ QTest::newRow( "Data15_0") << QTime(0,0,59,999) << -4 << QTime(0,0,59,995);
+ QTest::newRow( "Data15_1") << QTime(0,1,0,0) << -5 << QTime(0,0,59,995);
+ QTest::newRow( "Data15_2") << QTime(0,1,0,1) << -6 << QTime(0,0,59,995);
+ QTest::newRow( "Data15_3") << QTime(0,1,1,1) << -1006 << QTime(0,0,59,995);
+
+ QTest::newRow( "Data16_0") << QTime(0,59,59,999) << -4 << QTime(0,59,59,995);
+ QTest::newRow( "Data16_1") << QTime(1,0,0,0) << -5 << QTime(0,59,59,995);
+ QTest::newRow( "Data16_2") << QTime(1,0,0,1) << -6 << QTime(0,59,59,995);
+ QTest::newRow( "Data16_3") << QTime(1,0,0,101) << -106 << QTime(0,59,59,995);
+ QTest::newRow( "Data16_4") << QTime(1,0,0,999) << -1004 << QTime(0,59,59,995);
+ QTest::newRow( "Data16_5") << QTime(1,0,1,0) << -1005 << QTime(0,59,59,995);
+ QTest::newRow( "Data16_6") << QTime(1,1,1,1) << -61006 << QTime(0,59,59,995);
+
+ QTest::newRow( "Data17_0") << QTime(23,59,59,995) << -0 << QTime(23,59,59,995);
+ QTest::newRow( "Data17_1") << QTime(23,59,59,999) << -4 << QTime(23,59,59,995);
+ QTest::newRow( "Data17_2") << QTime(0,0,0,0) << -5 << QTime(23,59,59,995);
+ QTest::newRow( "Data17_3") << QTime(0,0,0,1) << -6 << QTime(23,59,59,995);
+ QTest::newRow( "Data17_4") << QTime(0,0,0,2) << -7 << QTime(23,59,59,995);
+
+ QTest::newRow( "Data18_0" ) << invalidTime() << 1 << invalidTime();
+}
+
+void tst_QTime::addMSecs()
+{
+ QFETCH( QTime, t1 );
+ QFETCH( int, i );
+ QTime t2;
+ t2 = t1.addMSecs( i );
+ QFETCH( QTime, exp );
+ QCOMPARE( t2, exp );
+}
+
+void tst_QTime::isNull()
+{
+ QTime t1;
+ QVERIFY( t1.isNull() );
+ QTime t2(0,0,0);
+ QVERIFY( !t2.isNull() );
+ QTime t3(0,0,1);
+ QVERIFY( !t3.isNull() );
+ QTime t4(0,0,0,1);
+ QVERIFY( !t4.isNull() );
+ QTime t5(23,59,59);
+ QVERIFY( !t5.isNull() );
+}
+
+void tst_QTime::isValid()
+{
+ QTime t1;
+ QVERIFY( !t1.isValid() );
+ QTime t2(24,0,0,0);
+ QVERIFY( !t2.isValid() );
+ QTime t3(23,60,0,0);
+ QVERIFY( !t3.isValid() );
+ QTime t4(23,0,-1,0);
+ QVERIFY( !t4.isValid() );
+ QTime t5(23,0,60,0);
+ QVERIFY( !t5.isValid() );
+ QTime t6(23,0,0,1000);
+ QVERIFY( !t6.isValid() );
+}
+
+void tst_QTime::hour_data()
+{
+ QTest::addColumn<int>("hour");
+ QTest::addColumn<int>("minute");
+ QTest::addColumn<int>("sec");
+ QTest::addColumn<int>("msec");
+
+ QTest::newRow( "data0" ) << 0 << 0 << 0 << 0;
+ QTest::newRow( "data1" ) << 0 << 0 << 0 << 1;
+ QTest::newRow( "data2" ) << 1 << 2 << 3 << 4;
+ QTest::newRow( "data3" ) << 2 << 12 << 13 << 65;
+ QTest::newRow( "data4" ) << 23 << 59 << 59 << 999;
+ QTest::newRow( "data5" ) << -1 << -1 << -1 << -1;
+}
+
+void tst_QTime::hour()
+{
+ QFETCH( int, hour );
+ QFETCH( int, minute );
+ QFETCH( int, sec );
+ QFETCH( int, msec );
+
+ QTime t1( hour, minute, sec, msec );
+ QCOMPARE( t1.hour(), hour );
+ QCOMPARE( t1.minute(), minute );
+ QCOMPARE( t1.second(), sec );
+ QCOMPARE( t1.msec(), msec );
+}
+
+void tst_QTime::setHMS_data()
+{
+ QTest::addColumn<int>("hour");
+ QTest::addColumn<int>("minute");
+ QTest::addColumn<int>("sec");
+
+ QTest::newRow( "data0" ) << 0 << 0 << 0;
+ QTest::newRow( "data1" ) << 1 << 2 << 3;
+ QTest::newRow( "data2" ) << 0 << 59 << 0;
+ QTest::newRow( "data3" ) << 0 << 59 << 59;
+ QTest::newRow( "data4" ) << 23 << 0 << 0;
+ QTest::newRow( "data5" ) << 23 << 59 << 0;
+ QTest::newRow( "data6" ) << 23 << 59 << 59;
+ QTest::newRow( "data7" ) << -1 << -1 << -1;
+}
+
+void tst_QTime::setHMS()
+{
+ QFETCH( int, hour );
+ QFETCH( int, minute );
+ QFETCH( int, sec );
+
+ QTime t(3,4,5);
+ t.setHMS( hour, minute, sec );
+ QCOMPARE( t.hour(), hour );
+ QCOMPARE( t.minute(), minute );
+ QCOMPARE( t.second(), sec );
+}
+
+void tst_QTime::secsTo_data()
+{
+ QTest::addColumn<QTime>("t1");
+ QTest::addColumn<QTime>("t2");
+ QTest::addColumn<int>("delta");
+
+ QTest::newRow( "data0" ) << QTime(0,0,0) << QTime(0,0,59) << 59;
+ QTest::newRow( "data1" ) << QTime(0,0,0) << QTime(0,1,0) << 60;
+ QTest::newRow( "data2" ) << QTime(0,0,0) << QTime(0,10,0) << 600;
+ QTest::newRow( "data3" ) << QTime(0,0,0) << QTime(23,59,59) << 86399;
+ QTest::newRow( "data4" ) << QTime(-1, -1, -1) << QTime(0, 0, 0) << 0;
+ QTest::newRow( "data5" ) << QTime(0, 0, 0) << QTime(-1, -1, -1) << 0;
+ QTest::newRow( "data6" ) << QTime(-1, -1, -1) << QTime(-1, -1, -1) << 0;
+ QTest::newRow("disregard msec (1s)") << QTime(12, 30, 1, 500) << QTime(12, 30, 2, 400) << 1;
+ QTest::newRow("disregard msec (0s)") << QTime(12, 30, 1, 500) << QTime(12, 30, 1, 900) << 0;
+ QTest::newRow("disregard msec (-1s)") << QTime(12, 30, 2, 400) << QTime(12, 30, 1, 500) << -1;
+ QTest::newRow("disregard msec (-0s)") << QTime(12, 30, 1, 900) << QTime(12, 30, 1, 500) << 0;
+}
+
+void tst_QTime::secsTo()
+{
+ QFETCH( QTime, t1 );
+ QFETCH( QTime, t2 );
+ QFETCH( int, delta );
+
+ QCOMPARE( t1.secsTo( t2 ), delta );
+}
+
+void tst_QTime::msecsTo_data()
+{
+ QTest::addColumn<QTime>("t1");
+ QTest::addColumn<QTime>("t2");
+ QTest::addColumn<int>("delta");
+
+ QTest::newRow( "data0" ) << QTime(0,0,0,0) << QTime(0,0,0,0) << 0;
+ QTest::newRow( "data1" ) << QTime(0,0,0,0) << QTime(0,0,1,0) << 1000;
+ QTest::newRow( "data2" ) << QTime(0,0,0,0) << QTime(0,0,10,0) << 10000;
+ QTest::newRow( "data3" ) << QTime(0,0,0,0) << QTime(23,59,59,0) << 86399000;
+ QTest::newRow( "data4" ) << QTime(-1, -1, -1, -1) << QTime(0, 0, 0, 0) << 0;
+ QTest::newRow( "data5" ) << QTime(0, 0, 0, 0) << QTime(-1, -1, -1, -1) << 0;
+ QTest::newRow( "data6" ) << QTime(-1, -1, -1, -1) << QTime(-1, -1, -1, -1) << 0;
+}
+
+void tst_QTime::msecsTo()
+{
+ QFETCH( QTime, t1 );
+ QFETCH( QTime, t2 );
+ QFETCH( int, delta );
+
+ QCOMPARE( t1.msecsTo( t2 ), delta );
+}
+
+void tst_QTime::orderingCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QTime>();
+}
+
+void tst_QTime::operator_eq_eq_data()
+{
+ QTest::addColumn<QTime>("t1");
+ QTest::addColumn<QTime>("t2");
+ QTest::addColumn<bool>("expectEqual");
+
+ QTime time1(0, 0, 0, 0);
+ QTime time2 = time1.addMSecs(1);
+ QTime time3 = time1.addMSecs(-1);
+ QTime time4(23, 59, 59, 999);
+
+ QTest::newRow("data0") << time1 << time2 << false;
+ QTest::newRow("data1") << time2 << time3 << false;
+ QTest::newRow("data2") << time4 << time1 << false;
+ QTest::newRow("data3") << time1 << time1 << true;
+ QTest::newRow("data4") << QTime(12,34,56,20) << QTime(12,34,56,20) << true;
+ QTest::newRow("data5") << QTime(01,34,56,20) << QTime(13,34,56,20) << false;
+}
+
+void tst_QTime::operator_eq_eq()
+{
+ QFETCH(QTime, t1);
+ QFETCH(QTime, t2);
+ QFETCH(bool, expectEqual);
+
+ QT_TEST_EQUALITY_OPS(t1, t2, expectEqual);
+
+ if (expectEqual)
+ QVERIFY(qHash(t1) == qHash(t2));
+}
+
+void tst_QTime::ordering_data()
+{
+ QTest::addColumn<QTime>("left");
+ QTest::addColumn<QTime>("right");
+ QTest::addColumn<Qt::strong_ordering>("expectedOrdering");
+
+ auto generateRow = [](QTime t1, QTime t2, Qt::strong_ordering ordering) {
+ const QByteArray t1Str = t1.toString("hh:mm:ss.zz").toLatin1();
+ const QByteArray t2Str = t2.toString("hh:mm:ss.zz").toLatin1();
+ QTest::addRow("%s_vs_%s", t1Str.constData(), t2Str.constData()) << t1 << t2 << ordering;
+ };
+
+ generateRow(QTime(0, 0), QTime(0, 0), Qt::strong_ordering::equivalent);
+ generateRow(QTime(12, 34, 56, 20), QTime(12, 34, 56, 30), Qt::strong_ordering::less);
+ generateRow(QTime(13, 34, 46, 20), QTime(13, 34, 56, 20), Qt::strong_ordering::less);
+ generateRow(QTime(13, 24, 56, 20), QTime(13, 34, 56, 20), Qt::strong_ordering::less);
+ generateRow(QTime(12, 34, 56, 20), QTime(13, 34, 56, 20), Qt::strong_ordering::less);
+ generateRow(QTime(14, 34, 56, 20), QTime(13, 34, 56, 20), Qt::strong_ordering::greater);
+ generateRow(QTime(13, 44, 56, 20), QTime(13, 34, 56, 20), Qt::strong_ordering::greater);
+ generateRow(QTime(13, 34, 56, 20), QTime(13, 34, 46, 20), Qt::strong_ordering::greater);
+ generateRow(QTime(13, 34, 56, 30), QTime(13, 34, 56, 20), Qt::strong_ordering::greater);
+}
+
+void tst_QTime::ordering()
+{
+ QFETCH(QTime, left);
+ QFETCH(QTime, right);
+ QFETCH(Qt::strong_ordering, expectedOrdering);
+
+ QT_TEST_ALL_COMPARISON_OPS(left, right, expectedOrdering);
+}
+
+#if QT_CONFIG(datestring)
+# if QT_CONFIG(datetimeparser)
+void tst_QTime::fromStringFormat_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QTime>("expected");
+
+ QTest::newRow("data0") << QString("1010") << QString("mmm") << QTime(0, 10, 0);
+ QTest::newRow("data1") << QString("00") << QString("hm") << invalidTime();
+ QTest::newRow("data2") << QString("10am") << QString("hap") << QTime(10, 0, 0);
+ QTest::newRow("data3") << QString("10pm") << QString("hap") << QTime(22, 0, 0);
+ QTest::newRow("data4") << QString("10pmam") << QString("hapap") << invalidTime();
+ QTest::newRow("data5") << QString("1070") << QString("hhm") << invalidTime();
+ QTest::newRow("data6") << QString("1011") << QString("hh") << invalidTime();
+ QTest::newRow("data7") << QString("25") << QString("hh") << invalidTime();
+ QTest::newRow("data8") << QString("22pm") << QString("Hap") << QTime(22, 0, 0);
+ QTest::newRow("data9") << QString("2221") << QString("hhhh") << invalidTime();
+ // Parsing of am/pm indicators is case-insensitive
+ QTest::newRow("pm-upper") << QString("02:23PM") << QString("hh:mmAp") << QTime(14, 23);
+ QTest::newRow("pm-lower") << QString("02:23pm") << QString("hh:mmaP") << QTime(14, 23);
+ QTest::newRow("pm-as-upper") << QString("02:23Pm") << QString("hh:mmAP") << QTime(14, 23);
+ QTest::newRow("pm-as-lower") << QString("02:23pM") << QString("hh:mmap") << QTime(14, 23);
+ // Millisecond parsing must interpolate 0s only at the end and notice them at the start.
+ QTest::newRow("short-msecs-lt100")
+ << QString("10:12:34:045") << QString("hh:m:ss:z") << QTime(10, 12, 34, 45);
+ QTest::newRow("short-msecs-gt100")
+ << QString("10:12:34:45") << QString("hh:m:ss:z") << QTime(10, 12, 34, 450);
+ QTest::newRow("late")
+ << QString("23:59:59.999") << QString("hh:mm:ss.z") << QTime(23, 59, 59, 999);
+
+ // Test unicode handling.
+ QTest::newRow("emoji in format string 1")
+ << QString("12👍31:25.05") << QString("hh👍mm:ss.z") << QTime(12, 31, 25, 50);
+ QTest::newRow("emoji in format string 2")
+ << QString("💖12👍31🌈25😺05🚀") << QString("💖hh👍mm🌈ss😺z🚀") << QTime(12, 31, 25, 50);
+}
+
+void tst_QTime::fromStringFormat()
+{
+ QFETCH(QString, string);
+ QFETCH(QString, format);
+ QFETCH(QTime, expected);
+
+ QTime dt = QTime::fromString(string, format);
+ QCOMPARE(dt, expected);
+}
+# endif // datetimeparser
+
+void tst_QTime::fromStringDateFormat_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<Qt::DateFormat>("format");
+ QTest::addColumn<QTime>("expected");
+
+ QTest::newRow("TextDate - zero") << QString("00:00:00") << Qt::TextDate << QTime(0, 0);
+ QTest::newRow("TextDate - ordinary")
+ << QString("10:12:34") << Qt::TextDate << QTime(10, 12, 34);
+ QTest::newRow("TextDate - milli-max")
+ << QString("19:03:54.998601") << Qt::TextDate << QTime(19, 3, 54, 999);
+ QTest::newRow("TextDate - milli-wrap")
+ << QString("19:03:54.999601") << Qt::TextDate << QTime(19, 3, 55);
+ QTest::newRow("TextDate - no-secs")
+ << QString("10:12") << Qt::TextDate << QTime(10, 12);
+ QTest::newRow("TextDate - midnight-nowrap")
+ << QString("23:59:59.9999") << Qt::TextDate << QTime(23, 59, 59, 999);
+ QTest::newRow("TextDate - invalid, minutes") << QString::fromLatin1("23:XX:00") << Qt::TextDate << invalidTime();
+ QTest::newRow("TextDate - invalid, minute fraction") << QString::fromLatin1("23:00.123456") << Qt::TextDate << invalidTime();
+ QTest::newRow("TextDate - invalid, seconds") << QString::fromLatin1("23:00:XX") << Qt::TextDate << invalidTime();
+ QTest::newRow("TextDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::TextDate
+ << invalidTime();
+ QTest::newRow("TextDate - midnight 24") << QString("24:00:00") << Qt::TextDate << QTime();
+
+ QTest::newRow("IsoDate - valid, start of day, omit seconds") << QString::fromLatin1("00:00") << Qt::ISODate << QTime(0, 0, 0);
+ QTest::newRow("IsoDate - valid, omit seconds") << QString::fromLatin1("22:21") << Qt::ISODate << QTime(22, 21, 0);
+ QTest::newRow("IsoDate - minute fraction") // 60 * 0.816666 = 48.99996 should round up:
+ << QString::fromLatin1("22:21.816666") << Qt::ISODate << QTime(22, 21, 49);
+ QTest::newRow("IsoDate - valid, omit seconds (2)") << QString::fromLatin1("23:59") << Qt::ISODate << QTime(23, 59, 0);
+ QTest::newRow("IsoDate - valid, end of day") << QString::fromLatin1("23:59:59") << Qt::ISODate << QTime(23, 59, 59);
+
+ QTest::newRow("IsoDate - invalid, empty string") << QString::fromLatin1("") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, too many hours") << QString::fromLatin1("25:00") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, too many minutes") << QString::fromLatin1("10:70") << Qt::ISODate << invalidTime();
+ // This is a valid time if it happens on June 30 or December 31 (leap seconds).
+ QTest::newRow("IsoDate - invalid, too many seconds") << QString::fromLatin1("23:59:60") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, minutes") << QString::fromLatin1("23:XX:00") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, not enough minutes") << QString::fromLatin1("23:0") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, minute fraction") << QString::fromLatin1("23:00,XX") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, seconds") << QString::fromLatin1("23:00:XX") << Qt::ISODate << invalidTime();
+ QTest::newRow("IsoDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::ISODate
+ << invalidTime();
+ QTest::newRow("IsoDate - zero") << QString("00:00:00") << Qt::ISODate << QTime(0, 0);
+ QTest::newRow("IsoDate - ordinary") << QString("10:12:34") << Qt::ISODate << QTime(10, 12, 34);
+ QTest::newRow("IsoDate - milli-max")
+ << QString("19:03:54.998601") << Qt::ISODate << QTime(19, 3, 54, 999);
+ QTest::newRow("IsoDate - milli-wrap")
+ << QString("19:03:54.999601") << Qt::ISODate << QTime(19, 3, 55);
+ QTest::newRow("IsoDate - midnight-nowrap")
+ << QString("23:59:59.9999") << Qt::ISODate << QTime(23, 59, 59, 999);
+ QTest::newRow("IsoDate - midnight 24")
+ << QString("24:00:00") << Qt::ISODate << QTime(0, 0);
+ QTest::newRow("IsoDate - minute fraction midnight")
+ << QString("24:00,0") << Qt::ISODate << QTime(0, 0);
+
+ // Test Qt::RFC2822Date format (RFC 2822).
+ QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 after space")
+ << QString::fromLatin1(" 13 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ QTest::newRow("RFC 2822 with day after space")
+ << QString::fromLatin1(" Thu, 01 Jan 1970 00:12:34 +0000")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ // No timezone
+ QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ // No time specified
+ QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 malformed time")
+ << QString::fromLatin1("01 Nov 2002 0:") << Qt::RFC2822Date << QTime();
+ // Test invalid month, day, year are ignored:
+ QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 invalid day name") << QString::fromLatin1("Mud, 23 Feb 1987 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Feb 0000 13:24:51 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ // Test invalid characters:
+ QTest::newRow("RFC 2822 invalid character at end")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character at front")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character both ends")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100!")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character at front, 2 at back")
+ << QString::fromLatin1("!01 Jan 2012 08:00:00 +0100..")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 2822 invalid character 2 at front")
+ << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << invalidTime();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 2822 (not invalid)")
+ << QString::fromLatin1("01 Jan 2012 08:00:00 +0100")
+ << Qt::RFC2822Date << QTime(8, 0, 0);
+
+ // Test Qt::RFC2822Date format (RFC 850 and 1036, permissive).
+ QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ QTest::newRow("RFC 850 and 1036 after space")
+ << QString::fromLatin1(" Fri Feb 13 13:24:51 1987 +0100")
+ << Qt::RFC2822Date << QTime(13, 24, 51);
+ // No timezone
+ QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
+ << Qt::RFC2822Date << QTime(0, 12, 34);
+ // No time specified
+ QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
+ << Qt::RFC2822Date << invalidTime();
+ // Test invalid characters.
+ QTest::newRow("RFC 850 and 1036 invalid character at end")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 850 and 1036 invalid character at front")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 850 and 1036 invalid character both ends")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100!")
+ << Qt::RFC2822Date << invalidTime();
+ QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back")
+ << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0100..")
+ << Qt::RFC2822Date << invalidTime();
+ // The common date text used by the "invalid character" tests, just to be
+ // sure *it's* not what's invalid:
+ QTest::newRow("RFC 850 and 1036 no invalid character")
+ << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100")
+ << Qt::RFC2822Date << QTime(8, 0, 0);
+
+ QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidTime();
+}
+
+void tst_QTime::fromStringDateFormat()
+{
+ QFETCH(QString, string);
+ QFETCH(Qt::DateFormat, format);
+ QFETCH(QTime, expected);
+
+ QTime dt = QTime::fromString(string, format);
+ QCOMPARE(dt, expected);
+}
+
+void tst_QTime::toStringDateFormat_data()
+{
+ QTest::addColumn<QTime>("time");
+ QTest::addColumn<Qt::DateFormat>("format");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("00:00:00.000") << QTime(0, 0, 0, 0) << Qt::TextDate << QString("00:00:00");
+ QTest::newRow("ISO 00:00:00.000") << QTime(0, 0, 0, 0) << Qt::ISODate << QString("00:00:00");
+ QTest::newRow("Text 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::TextDate << QString("10:12:34");
+ QTest::newRow("ISO 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::ISODate << QString("10:12:34");
+ QTest::newRow("Text 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::TextDate << QString("10:12:34");
+ QTest::newRow("ISO 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::ISODate << QString("10:12:34");
+ QTest::newRow("Text 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::TextDate << QString("10:12:34");
+ QTest::newRow("ISO 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::ISODate << QString("10:12:34");
+ QTest::newRow("RFC2822Date") << QTime(10, 12, 34, 999) << Qt::RFC2822Date << QString("10:12:34");
+ QTest::newRow("ISOWithMs 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::ISODateWithMs << QString("10:12:34.000");
+ QTest::newRow("ISOWithMs 10:12:34.020") << QTime(10, 12, 34, 20) << Qt::ISODateWithMs << QString("10:12:34.020");
+ QTest::newRow("ISOWithMs 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::ISODateWithMs << QString("10:12:34.999");
+}
+
+void tst_QTime::toStringDateFormat()
+{
+ QFETCH(QTime, time);
+ QFETCH(Qt::DateFormat, format);
+ QFETCH(QString, expected);
+
+ QCOMPARE(time.toString(format), expected);
+}
+
+void tst_QTime::toStringFormat_data()
+{
+ QTest::addColumn<QTime>("t");
+ QTest::addColumn<QString>("format");
+ QTest::addColumn<QString>("str");
+
+ QTest::newRow( "midnight" ) << QTime(0,0,0,0) << QString("h:m:s:z") << QString("0:0:0:0");
+ QTest::newRow( "full" ) << QTime(10,12,34,53) << QString("hh:mm:ss:zzz") << QString("10:12:34:053");
+ QTest::newRow( "short-msecs-lt100" ) << QTime(10,12,34,45) << QString("hh:m:ss:z") << QString("10:12:34:045");
+ QTest::newRow( "short-msecs-gt100" ) << QTime(10,12,34,450) << QString("hh:m:ss:z") << QString("10:12:34:45");
+ QTest::newRow( "am-pm" ) << QTime(10,12,34,45) << QString("hh:ss ap") << QString("10:34 am");
+ QTest::newRow( "AM-PM" ) << QTime(22,12,34,45) << QString("hh:zzz AP") << QString("10:045 PM");
+ QTest::newRow( "invalid" ) << QTime(230,230,230,230) << QString("hh:mm:ss") << QString();
+ QTest::newRow( "empty format" ) << QTime(4,5,6,6) << QString("") << QString("");
+}
+
+void tst_QTime::toStringFormat()
+{
+ QFETCH( QTime, t );
+ QFETCH( QString, format );
+ QFETCH( QString, str );
+
+ QCOMPARE( t.toString( format ), str );
+}
+#endif // datestring
+
+void tst_QTime::msecsSinceStartOfDay_data()
+{
+ QTest::addColumn<int>("msecs");
+ QTest::addColumn<bool>("isValid");
+ QTest::addColumn<int>("hour");
+ QTest::addColumn<int>("minute");
+ QTest::addColumn<int>("second");
+ QTest::addColumn<int>("msec");
+
+ QTest::newRow("00:00:00.000") << 0 << true
+ << 0 << 0 << 0 << 0;
+ QTest::newRow("01:00:00.001") << ((1 * 3600 * 1000) + 1) << true
+ << 1 << 0 << 0 << 1;
+ QTest::newRow("03:04:05.678") << ((3 * 3600 + 4 * 60 + 5) * 1000 + 678) << true
+ << 3 << 4 << 5 << 678;
+ QTest::newRow("23:59:59.999") << ((23 * 3600 + 59 * 60 + 59) * 1000 + 999) << true
+ << 23 << 59 << 59 << 999;
+ QTest::newRow("24:00:00.000") << ((24 * 3600) * 1000) << false
+ << -1 << -1 << -1 << -1;
+ QTest::newRow("-1 invalid") << -1 << false
+ << -1 << -1 << -1 << -1;
+}
+
+void tst_QTime::msecsSinceStartOfDay()
+{
+ QFETCH(int, msecs);
+ QFETCH(bool, isValid);
+ QFETCH(int, hour);
+ QFETCH(int, minute);
+ QFETCH(int, second);
+ QFETCH(int, msec);
+
+ QTime time = QTime::fromMSecsSinceStartOfDay(msecs);
+ QCOMPARE(time.isValid(), isValid);
+ if (msecs >= 0)
+ QCOMPARE(time.msecsSinceStartOfDay(), msecs);
+ else
+ QCOMPARE(time.msecsSinceStartOfDay(), 0);
+ QCOMPARE(time.hour(), hour);
+ QCOMPARE(time.minute(), minute);
+ QCOMPARE(time.second(), second);
+ QCOMPARE(time.msec(), msec);
+}
+
+QTEST_APPLESS_MAIN(tst_QTime)
+#include "tst_qtime.moc"
diff --git a/tests/auto/corelib/time/qtimezone/CMakeLists.txt b/tests/auto/corelib/time/qtimezone/CMakeLists.txt
new file mode 100644
index 0000000000..612bab0db5
--- /dev/null
+++ b/tests/auto/corelib/time/qtimezone/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtimezone Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtimezone LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtimezone
+ SOURCES
+ tst_qtimezone.cpp
+ DEFINES
+ QT_NO_FOREACH
+ QT_NO_KEYWORDS
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::TestPrivate
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qtimezone CONDITION QT_FEATURE_icu
+ LIBRARIES
+ ICU::i18n ICU::uc ICU::data
+)
+
+qt_internal_extend_target(tst_qtimezone CONDITION APPLE
+ SOURCES
+ tst_qtimezone_darwin.mm
+ LIBRARIES
+ ${FWFoundation}
+)
diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
new file mode 100644
index 0000000000..a350ffeb04
--- /dev/null
+++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
@@ -0,0 +1,1879 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <qtimezone.h>
+#include <private/qtimezoneprivate_p.h>
+#include <private/qcomparisontesthelper_p.h>
+
+#include <qlocale.h>
+
+#if defined(Q_OS_WIN)
+#include <QOperatingSystemVersion>
+#endif
+
+#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
+# define USING_WIN_TZ
+#endif
+
+class tst_QTimeZone : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ // Public class default system tests
+ void createTest();
+ void nullTest();
+ void assign();
+ void compareCompiles();
+ void compare_data();
+ void compare();
+ void timespec();
+ void offset();
+ void dataStreamTest();
+#if QT_CONFIG(timezone)
+ void asBackendZone();
+ void systemZone();
+ void isTimeZoneIdAvailable();
+ void availableTimeZoneIds();
+ void utcOffsetId_data();
+ void utcOffsetId();
+ void specificTransition_data();
+ void specificTransition();
+ void transitionEachZone_data();
+ void transitionEachZone();
+ void checkOffset_data();
+ void checkOffset();
+ void stressTest();
+ void windowsId();
+ void isValidId_data();
+ void isValidId();
+ void serialize();
+ void malformed();
+ // Backend tests
+ void utcTest();
+ void icuTest();
+ void tzTest();
+ void macTest();
+ void darwinTypes();
+ void winTest();
+ void localeSpecificDisplayName_data();
+ void localeSpecificDisplayName();
+ void stdCompatibility_data();
+ void stdCompatibility();
+#endif // timezone backends
+
+private:
+ void printTimeZone(const QTimeZone &tz);
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(timezone)
+ // Generic tests of privates, called by implementation-specific private tests:
+ void testCetPrivate(const QTimeZonePrivate &tzp);
+ void testEpochTranPrivate(const QTimeZonePrivate &tzp);
+#endif // QT_BUILD_INTERNAL && timezone backends
+ // Set to true to print debug output, test Display Names and run long stress tests
+ static constexpr bool debug = false;
+};
+
+void tst_QTimeZone::printTimeZone(const QTimeZone &tz)
+{
+ QDateTime now = QDateTime::currentDateTime();
+ QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC);
+ QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC);
+ qDebug() << "";
+ qDebug() << "Time Zone = " << tz;
+ qDebug() << "";
+ qDebug() << "Is Valid = " << tz.isValid();
+ qDebug() << "";
+ qDebug() << "Zone ID = " << tz.id();
+ qDebug() << "Territory = " << QLocale::territoryToString(tz.territory());
+ qDebug() << "Comment = " << tz.comment();
+ qDebug() << "";
+ qDebug() << "Locale = " << QLocale().name();
+ qDebug() << "Name Long = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName);
+ qDebug() << "Name Short = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::ShortName);
+ qDebug() << "Name Offset = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName);
+ qDebug() << "Name Long DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::LongName);
+ qDebug() << "Name Short DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName);
+ qDebug() << "Name Offset DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName);
+ qDebug() << "Name Long Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::LongName);
+ qDebug() << "Name Short Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::ShortName);
+ qDebug() << "Name Offset Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName);
+ qDebug() << "";
+ QLocale locale = QLocale(QStringLiteral("de_DE"));
+ qDebug() << "Locale = " << locale.name();
+ qDebug() << "Name Long = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName, locale);
+ qDebug() << "Name Short = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, locale);
+ qDebug() << "Name Offset = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, locale);
+ qDebug() << "Name Long DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::LongName,locale);
+ qDebug() << "Name Short DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, locale);
+ qDebug() << "Name Offset DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, locale);
+ qDebug() << "Name Long Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::LongName, locale);
+ qDebug() << "Name Short Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, locale);
+ qDebug() << "Name Offset Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, locale);
+ qDebug() << "";
+ qDebug() << "Abbreviation Now = " << tz.abbreviation(now);
+ qDebug() << "Abbreviation on 1 Jan = " << tz.abbreviation(jan);
+ qDebug() << "Abbreviation on 1 June = " << tz.abbreviation(jun);
+ qDebug() << "";
+ qDebug() << "Offset on 1 January = " << tz.offsetFromUtc(jan);
+ qDebug() << "Offset on 1 June = " << tz.offsetFromUtc(jun);
+ qDebug() << "Offset Now = " << tz.offsetFromUtc(now);
+ qDebug() << "";
+ qDebug() << "UTC Offset Now = " << tz.standardTimeOffset(now);
+ qDebug() << "UTC Offset on 1 January = " << tz.standardTimeOffset(jan);
+ qDebug() << "UTC Offset on 1 June = " << tz.standardTimeOffset(jun);
+ qDebug() << "";
+ qDebug() << "DST Offset on 1 January = " << tz.daylightTimeOffset(jan);
+ qDebug() << "DST Offset on 1 June = " << tz.daylightTimeOffset(jun);
+ qDebug() << "DST Offset Now = " << tz.daylightTimeOffset(now);
+ qDebug() << "";
+ qDebug() << "Has DST = " << tz.hasDaylightTime();
+ qDebug() << "Is DST Now = " << tz.isDaylightTime(now);
+ qDebug() << "Is DST on 1 January = " << tz.isDaylightTime(jan);
+ qDebug() << "Is DST on 1 June = " << tz.isDaylightTime(jun);
+ qDebug() << "";
+ qDebug() << "Has Transitions = " << tz.hasTransitions();
+ qDebug() << "Transition after 1 Jan = " << tz.nextTransition(jan).atUtc;
+ qDebug() << "Transition after 1 Jun = " << tz.nextTransition(jun).atUtc;
+ qDebug() << "Transition before 1 Jan = " << tz.previousTransition(jan).atUtc;
+ qDebug() << "Transition before 1 Jun = " << tz.previousTransition(jun).atUtc;
+ qDebug() << "";
+}
+
+void tst_QTimeZone::createTest()
+{
+ const QTimeZone tz("Pacific/Auckland");
+
+ if (debug)
+ printTimeZone(tz);
+
+ // If the tz is not valid then skip as is probably using the UTC backend which is tested later
+ if (!tz.isValid())
+ QSKIP("System lacks zone used for test"); // This returns.
+
+ QCOMPARE(tz.id(), "Pacific/Auckland");
+ // Comparison tests:
+ const QTimeZone same("Pacific/Auckland");
+ QCOMPARE((tz == same), true);
+ QCOMPARE((tz != same), false);
+ const QTimeZone other("Australia/Sydney");
+ QCOMPARE((tz == other), false);
+ QCOMPARE((tz != other), true);
+
+ QCOMPARE(tz.territory(), QLocale::NewZealand);
+
+ QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC);
+ QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC);
+ QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0), QTimeZone::UTC);
+
+ QCOMPARE(tz.offsetFromUtc(jan), 13 * 3600);
+ QCOMPARE(tz.offsetFromUtc(jun), 12 * 3600);
+
+ QCOMPARE(tz.standardTimeOffset(jan), 12 * 3600);
+ QCOMPARE(tz.standardTimeOffset(jun), 12 * 3600);
+
+ QCOMPARE(tz.daylightTimeOffset(jan), 3600);
+ QCOMPARE(tz.daylightTimeOffset(jun), 0);
+
+ QCOMPARE(tz.hasDaylightTime(), true);
+ QCOMPARE(tz.isDaylightTime(jan), true);
+ QCOMPARE(tz.isDaylightTime(jun), false);
+
+ // Only test transitions if host system supports them
+ if (tz.hasTransitions()) {
+ QTimeZone::OffsetData tran = tz.nextTransition(jan);
+ // 2012-04-01 03:00 NZDT, +13 -> +12
+ QCOMPARE(tran.atUtc,
+ QDateTime(QDate(2012, 4, 1), QTime(3, 0),
+ QTimeZone::fromSecondsAheadOfUtc(13 * 3600)));
+ QCOMPARE(tran.offsetFromUtc, 12 * 3600);
+ QCOMPARE(tran.standardTimeOffset, 12 * 3600);
+ QCOMPARE(tran.daylightTimeOffset, 0);
+
+ tran = tz.nextTransition(jun);
+ // 2012-09-30 02:00 NZST, +12 -> +13
+ QCOMPARE(tran.atUtc,
+ QDateTime(QDate(2012, 9, 30), QTime(2, 0),
+ QTimeZone::fromSecondsAheadOfUtc(12 * 3600)));
+ QCOMPARE(tran.offsetFromUtc, 13 * 3600);
+ QCOMPARE(tran.standardTimeOffset, 12 * 3600);
+ QCOMPARE(tran.daylightTimeOffset, 3600);
+
+ tran = tz.previousTransition(jan);
+ // 2011-09-25 02:00 NZST, +12 -> +13
+ QCOMPARE(tran.atUtc,
+ QDateTime(QDate(2011, 9, 25), QTime(2, 0),
+ QTimeZone::fromSecondsAheadOfUtc(12 * 3600)));
+ QCOMPARE(tran.offsetFromUtc, 13 * 3600);
+ QCOMPARE(tran.standardTimeOffset, 12 * 3600);
+ QCOMPARE(tran.daylightTimeOffset, 3600);
+
+ tran = tz.previousTransition(jun);
+ // 2012-04-01 03:00 NZDT, +13 -> +12 (again)
+ QCOMPARE(tran.atUtc,
+ QDateTime(QDate(2012, 4, 1), QTime(3, 0),
+ QTimeZone::fromSecondsAheadOfUtc(13 * 3600)));
+ QCOMPARE(tran.offsetFromUtc, 12 * 3600);
+ QCOMPARE(tran.standardTimeOffset, 12 * 3600);
+ QCOMPARE(tran.daylightTimeOffset, 0);
+
+ QTimeZone::OffsetDataList expected;
+ // Reuse 2012's fall-back data for 2011-04-03:
+ tran.atUtc = QDateTime(QDate(2011, 4, 3), QTime(3, 0),
+ QTimeZone::fromSecondsAheadOfUtc(13 * 3600));
+ expected << tran;
+ // 2011's spring-forward:
+ tran.atUtc = QDateTime(QDate(2011, 9, 25), QTime(2, 0),
+ QTimeZone::fromSecondsAheadOfUtc(12 * 3600));
+ tran.offsetFromUtc = 13 * 3600;
+ tran.daylightTimeOffset = 3600;
+ expected << tran;
+ QTimeZone::OffsetDataList result = tz.transitions(janPrev, jan);
+ QCOMPARE(result.size(), expected.size());
+ for (int i = 0; i < expected.size(); ++i) {
+ QCOMPARE(result.at(i).atUtc, expected.at(i).atUtc);
+ QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
+ QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
+ QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
+ }
+ }
+}
+
+void tst_QTimeZone::nullTest()
+{
+ QTimeZone nullTz1;
+ QTimeZone nullTz2;
+ QTimeZone utc("UTC");
+
+ // Validity tests
+ QCOMPARE(nullTz1.isValid(), false);
+ QCOMPARE(nullTz2.isValid(), false);
+ QCOMPARE(utc.isValid(), true);
+
+ // Comparison tests
+ QCOMPARE((nullTz1 == nullTz2), true);
+ QCOMPARE((nullTz1 != nullTz2), false);
+ QCOMPARE((nullTz1 == utc), false);
+ QCOMPARE((nullTz1 != utc), true);
+
+ // Assignment tests
+ nullTz2 = utc;
+ QCOMPARE(nullTz2.isValid(), true);
+ utc = nullTz1;
+ QCOMPARE(utc.isValid(), false);
+
+ QCOMPARE(nullTz1.id(), QByteArray());
+ QCOMPARE(nullTz1.territory(), QLocale::AnyTerritory);
+ QCOMPARE(nullTz1.comment(), QString());
+
+ QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC);
+ QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC);
+ QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0), QTimeZone::UTC);
+
+ QCOMPARE(nullTz1.abbreviation(jan), QString());
+ QCOMPARE(nullTz1.displayName(jan), QString());
+ QCOMPARE(nullTz1.displayName(QTimeZone::StandardTime), QString());
+
+ QCOMPARE(nullTz1.offsetFromUtc(jan), 0);
+ QCOMPARE(nullTz1.offsetFromUtc(jun), 0);
+
+ QCOMPARE(nullTz1.standardTimeOffset(jan), 0);
+ QCOMPARE(nullTz1.standardTimeOffset(jun), 0);
+
+ QCOMPARE(nullTz1.daylightTimeOffset(jan), 0);
+ QCOMPARE(nullTz1.daylightTimeOffset(jun), 0);
+
+ QCOMPARE(nullTz1.hasDaylightTime(), false);
+ QCOMPARE(nullTz1.isDaylightTime(jan), false);
+ QCOMPARE(nullTz1.isDaylightTime(jun), false);
+
+ QTimeZone::OffsetData data = nullTz1.offsetData(jan);
+ constexpr auto invalidOffset = std::numeric_limits<int>::min();
+ QCOMPARE(data.atUtc, QDateTime());
+ QCOMPARE(data.offsetFromUtc, invalidOffset);
+ QCOMPARE(data.standardTimeOffset, invalidOffset);
+ QCOMPARE(data.daylightTimeOffset, invalidOffset);
+
+ QCOMPARE(nullTz1.hasTransitions(), false);
+
+ data = nullTz1.nextTransition(jan);
+ QCOMPARE(data.atUtc, QDateTime());
+ QCOMPARE(data.offsetFromUtc, invalidOffset);
+ QCOMPARE(data.standardTimeOffset, invalidOffset);
+ QCOMPARE(data.daylightTimeOffset, invalidOffset);
+
+ data = nullTz1.previousTransition(jan);
+ QCOMPARE(data.atUtc, QDateTime());
+ QCOMPARE(data.offsetFromUtc, invalidOffset);
+ QCOMPARE(data.standardTimeOffset, invalidOffset);
+ QCOMPARE(data.daylightTimeOffset, invalidOffset);
+}
+
+void tst_QTimeZone::assign()
+{
+ QTimeZone assignee;
+ QCOMPARE(assignee.timeSpec(), Qt::TimeZone);
+ assignee = QTimeZone();
+ QCOMPARE(assignee.timeSpec(), Qt::TimeZone);
+ assignee = QTimeZone::UTC;
+ QCOMPARE(assignee.timeSpec(), Qt::UTC);
+ assignee = QTimeZone::LocalTime;
+ QCOMPARE(assignee.timeSpec(), Qt::LocalTime);
+ assignee = QTimeZone();
+ QCOMPARE(assignee.timeSpec(), Qt::TimeZone);
+ assignee = QTimeZone::fromSecondsAheadOfUtc(1);
+ QCOMPARE(assignee.timeSpec(), Qt::OffsetFromUTC);
+ assignee = QTimeZone::fromSecondsAheadOfUtc(0);
+ QCOMPARE(assignee.timeSpec(), Qt::UTC);
+#if QT_CONFIG(timezone)
+ {
+ const QTimeZone cet("Europe/Oslo");
+ assignee = cet;
+ QCOMPARE(assignee.timeSpec(), Qt::TimeZone);
+ }
+#endif
+}
+
+void tst_QTimeZone::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QTimeZone>();
+}
+
+void tst_QTimeZone::compare_data()
+{
+ QTest::addColumn<QTimeZone>("left");
+ QTest::addColumn<QTimeZone>("right");
+ QTest::addColumn<bool>("expectedEqual");
+
+ const QTimeZone local;
+ const QTimeZone utc(QTimeZone::UTC);
+ const auto secondEast = QTimeZone::fromSecondsAheadOfUtc(1);
+ const auto zeroOffset = QTimeZone::fromSecondsAheadOfUtc(0);
+ const auto durationEast = QTimeZone::fromDurationAheadOfUtc(std::chrono::seconds{1});
+
+ QTest::newRow("local vs default-constructed") << local << QTimeZone() << true;
+ QTest::newRow("local vs UTC") << local << utc << false;
+ QTest::newRow("local vs secondEast") << local << secondEast << false;
+ QTest::newRow("secondEast vs UTC") << secondEast << utc << false;
+ QTest::newRow("UTC vs zeroOffset") << utc << zeroOffset << true;
+ QTest::newRow("secondEast vs durationEast") << secondEast << durationEast << true;
+}
+
+void tst_QTimeZone::compare()
+{
+ QFETCH(QTimeZone, left);
+ QFETCH(QTimeZone, right);
+ QFETCH(bool, expectedEqual);
+
+ QT_TEST_EQUALITY_OPS(left, right, expectedEqual);
+}
+
+void tst_QTimeZone::timespec()
+{
+ using namespace std::chrono_literals;
+ QCOMPARE(QTimeZone().timeSpec(), Qt::TimeZone);
+ QCOMPARE(QTimeZone(QTimeZone::UTC).timeSpec(), Qt::UTC);
+ QCOMPARE(QTimeZone(QTimeZone::LocalTime).timeSpec(), Qt::LocalTime);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(0).timeSpec(), Qt::UTC);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(0s).timeSpec(), Qt::UTC);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(0min).timeSpec(), Qt::UTC);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(0h).timeSpec(), Qt::UTC);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(1).timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(-1).timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(36000).timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(-36000).timeSpec(), Qt::OffsetFromUTC);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(3h - 20min +17s).timeSpec(), Qt::OffsetFromUTC);
+ {
+ const QTimeZone zone;
+ QCOMPARE(zone.timeSpec(), Qt::TimeZone);
+ }
+ {
+ const QTimeZone zone = { QTimeZone::UTC };
+ QCOMPARE(zone.timeSpec(), Qt::UTC);
+ }
+ {
+ const QTimeZone zone = { QTimeZone::LocalTime };
+ QCOMPARE(zone.timeSpec(), Qt::LocalTime);
+ }
+ {
+ const auto zone = QTimeZone::fromSecondsAheadOfUtc(0);
+ QCOMPARE(zone.timeSpec(), Qt::UTC);
+ }
+ {
+ const auto zone = QTimeZone::fromDurationAheadOfUtc(0s);
+ QCOMPARE(zone.timeSpec(), Qt::UTC);
+ }
+ {
+ const auto zone = QTimeZone::fromSecondsAheadOfUtc(1);
+ QCOMPARE(zone.timeSpec(), Qt::OffsetFromUTC);
+ }
+ {
+ const auto zone = QTimeZone::fromDurationAheadOfUtc(1s);
+ QCOMPARE(zone.timeSpec(), Qt::OffsetFromUTC);
+ }
+#if QT_CONFIG(timezone)
+ QCOMPARE(QTimeZone("Europe/Oslo").timeSpec(), Qt::TimeZone);
+#endif
+}
+
+void tst_QTimeZone::offset()
+{
+ QCOMPARE(QTimeZone().fixedSecondsAheadOfUtc(), 0);
+ QCOMPARE(QTimeZone(QTimeZone::UTC).fixedSecondsAheadOfUtc(), 0);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(0).fixedSecondsAheadOfUtc(), 0);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(std::chrono::seconds{}).fixedSecondsAheadOfUtc(), 0);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(std::chrono::minutes{}).fixedSecondsAheadOfUtc(), 0);
+ QCOMPARE(QTimeZone::fromDurationAheadOfUtc(std::chrono::hours{}).fixedSecondsAheadOfUtc(), 0);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(1).fixedSecondsAheadOfUtc(), 1);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(-1).fixedSecondsAheadOfUtc(), -1);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(36000).fixedSecondsAheadOfUtc(), 36000);
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(-36000).fixedSecondsAheadOfUtc(), -36000);
+ {
+ const QTimeZone zone;
+ QCOMPARE(zone.fixedSecondsAheadOfUtc(), 0);
+ }
+ {
+ const QTimeZone zone = { QTimeZone::UTC };
+ QCOMPARE(zone.fixedSecondsAheadOfUtc(), 0);
+ }
+ {
+ const auto zone = QTimeZone::fromSecondsAheadOfUtc(0);
+ QCOMPARE(zone.fixedSecondsAheadOfUtc(), 0);
+ }
+ {
+ const auto zone = QTimeZone::fromDurationAheadOfUtc(std::chrono::seconds{});
+ QCOMPARE(zone.fixedSecondsAheadOfUtc(), 0);
+ }
+ {
+ const auto zone = QTimeZone::fromSecondsAheadOfUtc(1);
+ QCOMPARE(zone.fixedSecondsAheadOfUtc(), 1);
+ }
+ {
+ const auto zone = QTimeZone::fromDurationAheadOfUtc(std::chrono::seconds{1});
+ QCOMPARE(zone.fixedSecondsAheadOfUtc(), 1);
+ }
+#if QT_CONFIG(timezone)
+ QCOMPARE(QTimeZone("Europe/Oslo").fixedSecondsAheadOfUtc(), 0);
+#endif
+}
+
+void tst_QTimeZone::dataStreamTest()
+{
+#ifndef QT_NO_DATASTREAM
+ // Test the OffsetFromUtc backend serialization. First with a custom timezone:
+ QTimeZone tz1("QST", 123456, "Qt Standard Time", "QST", QLocale::Norway, "Qt Testing");
+ QByteArray tmp;
+ {
+ QDataStream ds(&tmp, QIODevice::WriteOnly);
+ ds << tz1;
+ }
+ QTimeZone tz2("UTC");
+ {
+ QDataStream ds(&tmp, QIODevice::ReadOnly);
+ ds >> tz2;
+ }
+ QCOMPARE(tz2.id(), QByteArray("QST"));
+ QCOMPARE(tz2.comment(), QString("Qt Testing"));
+ QCOMPARE(tz2.territory(), QLocale::Norway);
+ QCOMPARE(tz2.abbreviation(QDateTime::currentDateTime()), QString("QST"));
+ QCOMPARE(tz2.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QLocale()),
+ QString("Qt Standard Time"));
+ QCOMPARE(tz2.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, QLocale()),
+ QString("Qt Standard Time"));
+ QCOMPARE(tz2.offsetFromUtc(QDateTime::currentDateTime()), 123456);
+
+ // And then with a standard IANA timezone (QTBUG-60595):
+ tz1 = QTimeZone("UTC");
+ QCOMPARE(tz1.isValid(), true);
+ {
+ QDataStream ds(&tmp, QIODevice::WriteOnly);
+ ds << tz1;
+ }
+ {
+ QDataStream ds(&tmp, QIODevice::ReadOnly);
+ ds >> tz2;
+ }
+ QCOMPARE(tz2.isValid(), true);
+ QCOMPARE(tz2.id(), tz1.id());
+
+ // Test the system backend serialization
+ tz1 = QTimeZone("Pacific/Auckland");
+
+ // If not valid then probably using the UTC system backend so skip
+ if (!tz1.isValid())
+ return;
+
+ {
+ QDataStream ds(&tmp, QIODevice::WriteOnly);
+ ds << tz1;
+ }
+ tz2 = QTimeZone("UTC");
+ {
+ QDataStream ds(&tmp, QIODevice::ReadOnly);
+ ds >> tz2;
+ }
+ QCOMPARE(tz2.id(), tz1.id());
+#endif
+}
+
+#if QT_CONFIG(timezone)
+void tst_QTimeZone::asBackendZone()
+{
+ QCOMPARE(QTimeZone(QTimeZone::LocalTime).asBackendZone(), QTimeZone::systemTimeZone());
+ QCOMPARE(QTimeZone(QTimeZone::UTC).asBackendZone(), QTimeZone::utc());
+ QCOMPARE(QTimeZone::fromSecondsAheadOfUtc(-300).asBackendZone(), QTimeZone(-300));
+ QTimeZone cet("Europe/Oslo");
+ QCOMPARE(cet.asBackendZone(), cet);
+}
+
+void tst_QTimeZone::systemZone()
+{
+ const QTimeZone zone = QTimeZone::systemTimeZone();
+ QVERIFY2(zone.isValid(),
+ "Invalid system zone setting, tests are doomed on misconfigured system.");
+ // This may fail on Windows if CLDR data doesn't map system MS ID to IANA ID:
+ QCOMPARE(zone.id(), QTimeZone::systemTimeZoneId());
+ QCOMPARE(zone, QTimeZone(QTimeZone::systemTimeZoneId()));
+ // Check it behaves the same as local-time:
+ const QDate dates[] = {
+ QDate::fromJulianDay(0), // far in the distant past (LMT)
+ QDate(1625, 6, 8), // Before time-zones (date of Cassini's birth)
+ QDate(1901, 12, 13), // Last day before 32-bit time_t's range
+ QDate(1969, 12, 31), // Last day before the epoch
+ QDate(1970, 0, 0), // Start of epoch
+ QDate(2000, 2, 29), // An anomalous leap day
+ QDate(2038, 1, 20) // First day after 32-bit time_t's range
+ };
+ for (const auto &date : dates)
+ QCOMPARE(date.startOfDay(QTimeZone::LocalTime), date.startOfDay(zone));
+
+#if __cpp_lib_chrono >= 201907L
+ const std::chrono::time_zone *currentTimeZone = std::chrono::current_zone();
+ QCOMPARE(QByteArrayView(currentTimeZone->name()), QByteArrayView(zone.id()));
+#endif
+}
+
+void tst_QTimeZone::isTimeZoneIdAvailable()
+{
+ const QList<QByteArray> available = QTimeZone::availableTimeZoneIds();
+ for (const QByteArray &id : available) {
+ QVERIFY2(QTimeZone::isTimeZoneIdAvailable(id), id);
+ QVERIFY2(QTimeZone(id).isValid(), id);
+ QCOMPARE(QTimeZone(id).id(), id);
+ }
+ for (qint32 offset = QTimeZone::MinUtcOffsetSecs;
+ offset <= QTimeZone::MinUtcOffsetSecs; ++offset) {
+ const QByteArray id = QTimeZone(offset).id();
+ QVERIFY2(QTimeZone::isTimeZoneIdAvailable(id), id);
+ QVERIFY2(QTimeZone(id).isValid(), id);
+ QCOMPARE(QTimeZone(id).id(), id);
+ }
+}
+
+void tst_QTimeZone::utcOffsetId_data()
+{
+ QTest::addColumn<QByteArray>("id");
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<int>("offset"); // ignored unless valid
+
+ // Some of these are actual CLDR zone IDs, some are known Windows IDs; the
+ // rest rely on parsing the offset. Since CLDR and Windows may add to their
+ // known IDs, which fall in which category may vary. Only the CLDR and
+ // Windows ones are known to isTimeZoneAvailable() or listed in
+ // availableTimeZoneIds().
+#define ROW(name, valid, offset) \
+ QTest::newRow(name) << QByteArray(name) << valid << offset
+
+ // See qtbase/util/locale_database/cldr2qtimezone.py for source
+ // CLDR v35.1 IDs:
+ ROW("UTC", true, 0);
+ ROW("UTC-14:00", true, -50400);
+ ROW("UTC-13:00", true, -46800);
+ ROW("UTC-12:00", true, -43200);
+ ROW("UTC-11:00", true, -39600);
+ ROW("UTC-10:00", true, -36000);
+ ROW("UTC-09:00", true, -32400);
+ ROW("UTC-08:00", true, -28800);
+ ROW("UTC-07:00", true, -25200);
+ ROW("UTC-06:00", true, -21600);
+ ROW("UTC-05:00", true, -18000);
+ ROW("UTC-04:30", true, -16200);
+ ROW("UTC-04:00", true, -14400);
+ ROW("UTC-03:30", true, -12600);
+ ROW("UTC-03:00", true, -10800);
+ ROW("UTC-02:00", true, -7200);
+ ROW("UTC-01:00", true, -3600);
+ ROW("UTC-00:00", true, 0);
+ ROW("UTC+00:00", true, 0);
+ ROW("UTC+01:00", true, 3600);
+ ROW("UTC+02:00", true, 7200);
+ ROW("UTC+03:00", true, 10800);
+ ROW("UTC+03:30", true, 12600);
+ ROW("UTC+04:00", true, 14400);
+ ROW("UTC+04:30", true, 16200);
+ ROW("UTC+05:00", true, 18000);
+ ROW("UTC+05:30", true, 19800);
+ ROW("UTC+05:45", true, 20700);
+ ROW("UTC+06:00", true, 21600);
+ ROW("UTC+06:30", true, 23400);
+ ROW("UTC+07:00", true, 25200);
+ ROW("UTC+08:00", true, 28800);
+ ROW("UTC+08:30", true, 30600);
+ ROW("UTC+09:00", true, 32400);
+ ROW("UTC+09:30", true, 34200);
+ ROW("UTC+10:00", true, 36000);
+ ROW("UTC+11:00", true, 39600);
+ ROW("UTC+12:00", true, 43200);
+ ROW("UTC+13:00", true, 46800);
+ ROW("UTC+14:00", true, 50400);
+
+ // Windows IDs known to CLDR v35.1:
+ ROW("UTC-11", true, -39600);
+ ROW("UTC-09", true, -32400);
+ ROW("UTC-08", true, -28800);
+ ROW("UTC-8", true, -28800);
+ ROW("UTC-2:5", true, -7500);
+ ROW("UTC-02", true, -7200);
+ ROW("UTC+2", true, 7200);
+ ROW("UTC+2:5", true, 7500);
+ ROW("UTC+12", true, 43200);
+ ROW("UTC+13", true, 46800);
+ // Encountered in bug reports:
+ ROW("UTC+10", true, 36000); // QTBUG-77738
+
+ // Bounds:
+ ROW("UTC+23", true, 82800);
+ ROW("UTC-23", true, -82800);
+ ROW("UTC+23:59", true, 86340);
+ ROW("UTC-23:59", true, -86340);
+ ROW("UTC+23:59:59", true, 86399);
+ ROW("UTC-23:59:59", true, -86399);
+
+ // Out of range
+ ROW("UTC+24:0:0", false, 0);
+ ROW("UTC-24:0:0", false, 0);
+ ROW("UTC+0:60:0", false, 0);
+ ROW("UTC-0:60:0", false, 0);
+ ROW("UTC+0:0:60", false, 0);
+ ROW("UTC-0:0:60", false, 0);
+
+ // Malformed
+ ROW("UTC+", false, 0);
+ ROW("UTC-", false, 0);
+ ROW("UTC10", false, 0);
+ ROW("UTC:10", false, 0);
+ ROW("UTC+cabbage", false, 0);
+ ROW("UTC+10:rice", false, 0);
+ ROW("UTC+9:3:oat", false, 0);
+ ROW("UTC+9+3", false, 0);
+ ROW("UTC+9-3", false, 0);
+ ROW("UTC+9:3-4", false, 0);
+ ROW("UTC+9:3:4:more", false, 0);
+ ROW("UTC+9:3:4:5", false, 0);
+}
+
+void tst_QTimeZone::utcOffsetId()
+{
+ QFETCH(QByteArray, id);
+ QFETCH(bool, valid);
+ QTimeZone zone(id);
+ QCOMPARE(zone.isValid(), valid);
+ if (valid) {
+ QDateTime epoch(QDate(1970, 1, 1), QTime(0, 0), QTimeZone::UTC);
+ QFETCH(int, offset);
+ QCOMPARE(zone.offsetFromUtc(epoch), offset);
+ QVERIFY(!zone.hasDaylightTime());
+
+ // zone.id() will be an IANA ID with zero minutes field if original was
+ // a UTC offset by a whole number of hours. It will also zero-pad a
+ // single-digit hour or minute to two digits.
+ if (const qsizetype cut = id.indexOf(':'); cut >= 0) {
+ if (id.size() == cut + 2) // "...:m" -> "...:0m"
+ id.insert(cut + 1, '0');
+ } else if (zone.id().contains(':')) {
+ id += ":00";
+ }
+ if (id.indexOf(':') == 5) // UTC±h:mm -> UTC±0h:mm
+ id.insert(4, '0');
+
+ QCOMPARE(zone.id(), id);
+ }
+}
+
+void tst_QTimeZone::specificTransition_data()
+{
+ QTest::addColumn<QByteArray>("zone");
+ QTest::addColumn<QDate>("start");
+ QTest::addColumn<QDate>("stop");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QDateTime>("atUtc");
+ // In seconds:
+ QTest::addColumn<int>("offset");
+ QTest::addColumn<int>("stdoff");
+ QTest::addColumn<int>("dstoff");
+#ifdef Q_OS_ANDROID
+ if (!QTimeZone("Europe/Moscow").hasTransitions())
+ QSKIP("Android time-zone back-end has no transition data");
+#endif
+
+ // Moscow ditched DST on 2010-10-31 but has since changed standard offset twice.
+#ifdef USING_WIN_TZ
+ // Win7 is too old to know about this transition:
+ if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7)
+#endif
+ {
+ QTest::newRow("Moscow/2014") // From original bug-report
+ << QByteArray("Europe/Moscow")
+ << QDate(2011, 4, 1) << QDate(2021, 12, 31) << 1
+ << QDateTime(QDate(2014, 10, 26), QTime(2, 0),
+ QTimeZone::fromSecondsAheadOfUtc(4 * 3600)).toUTC()
+ << 3 * 3600 << 3 * 3600 << 0;
+ }
+ QTest::newRow("Moscow/2011") // Transition on 2011-03-27
+ << QByteArray("Europe/Moscow")
+ << QDate(2010, 11, 1) << QDate(2014, 10, 25) << 1
+ << QDateTime(QDate(2011, 3, 27), QTime(2, 0),
+ QTimeZone::fromSecondsAheadOfUtc(3 * 3600)).toUTC()
+ << 4 * 3600 << 4 * 3600 << 0;
+}
+
+void tst_QTimeZone::specificTransition()
+{
+ // Regression test for QTBUG-42021 (on MS-Win)
+ QFETCH(QByteArray, zone);
+ QFETCH(QDate, start);
+ QFETCH(QDate, stop);
+ QFETCH(int, count);
+ // No attempt to check abbreviations; to much cross-platform variation.
+ QFETCH(QDateTime, atUtc);
+ QFETCH(int, offset);
+ QFETCH(int, stdoff);
+ QFETCH(int, dstoff);
+
+ QTimeZone timeZone(zone);
+ if (!timeZone.isValid())
+ QSKIP("Missing time-zone data");
+ QTimeZone::OffsetDataList transits =
+ timeZone.transitions(start.startOfDay(timeZone), stop.endOfDay(timeZone));
+ QCOMPARE(transits.size(), count);
+ if (count) {
+ const QTimeZone::OffsetData &transition = transits.at(0);
+ QCOMPARE(transition.offsetFromUtc, offset);
+ QCOMPARE(transition.standardTimeOffset, stdoff);
+ QCOMPARE(transition.daylightTimeOffset, dstoff);
+ QCOMPARE(transition.atUtc, atUtc);
+ }
+}
+
+void tst_QTimeZone::transitionEachZone_data()
+{
+ QTest::addColumn<QByteArray>("zone");
+ QTest::addColumn<qint64>("secs");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<int>("stop");
+
+ const struct {
+ qint64 baseSecs;
+ int start, stop;
+ int year;
+ } table[] = {
+ { 1288488600, -4, 8, 2010 }, // 2010-10-31 01:30 UTC; Europe, Russia
+ { 25666200, 3, 12, 1970 }, // 1970-10-25 01:30 UTC; North America
+ };
+
+ const auto zones = QTimeZone::availableTimeZoneIds();
+ for (const auto &entry : table) {
+ for (const QByteArray &zone : zones) {
+ QTest::addRow("%s@%d", zone.constData(), entry.year)
+ << zone << entry.baseSecs << entry.start << entry.stop;
+ }
+ }
+}
+
+void tst_QTimeZone::transitionEachZone()
+{
+ // Regression test: round-trip fromMsecs/toMSecs should be idempotent; but
+ // various zones failed during fall-back transitions.
+ QFETCH(const QByteArray, zone);
+ QFETCH(const qint64, secs);
+ QFETCH(const int, start);
+ QFETCH(const int, stop);
+ const QTimeZone named(zone);
+ if (!named.isValid())
+ QSKIP("Supposedly available zone is not valid");
+ if (named.id() != zone)
+ QSKIP("Supposedly available zone's id does not match");
+
+ for (int i = start; i < stop; i++) {
+#ifdef USING_WIN_TZ
+ // See QTBUG-64985: MS's TZ APIs' misdescription of Europe/Samara leads
+ // to mis-disambiguation of its fall-back here.
+ if (zone == "Europe/Samara" && i == -3)
+ continue;
+#endif
+ const qint64 here = secs + i * 3600;
+ const QDateTime when = QDateTime::fromSecsSinceEpoch(here, named);
+ const qint64 stamp = when.toMSecsSinceEpoch();
+ if (here * 1000 != stamp) {
+ // (The +1 is due to using _1_:30 as baseSecs.)
+ qDebug("Failing at half past %d UTC (offset %d in %s)", i + 1, when.offsetFromUtc(),
+ QLocale::territoryToString(named.territory()).toUtf8().constData());
+ }
+ QCOMPARE(stamp % 1000, 0);
+ QCOMPARE(here - stamp / 1000, 0);
+ }
+}
+
+void tst_QTimeZone::checkOffset_data()
+{
+ QTest::addColumn<QTimeZone>("zone");
+ QTest::addColumn<QDateTime>("when");
+ QTest::addColumn<int>("netOffset");
+ QTest::addColumn<int>("stdOffset");
+ QTest::addColumn<int>("dstOffset");
+
+ const QTimeZone UTC = QTimeZone::UTC;
+ QTest::addRow("UTC")
+ << UTC << QDate(1970, 1, 1).startOfDay(UTC) << 0 << 0 << 0;
+ const auto east = QTimeZone::fromSecondsAheadOfUtc(28'800); // 8 hours
+ QTest::addRow("UTC+8")
+ << east << QDate(2000, 2, 29).startOfDay(east) << 28'800 << 28'800 << 0;
+ const auto west = QTimeZone::fromDurationAheadOfUtc(std::chrono::hours{-8});
+ QTest::addRow("UTC-8")
+ << west << QDate(2100, 2, 28).startOfDay(west) << -28'800 << -28'800 << 0;
+
+ struct {
+ const char *zone, *nick;
+ int year, month, day, hour, min, sec;
+ int std, dst;
+ } table[] = {
+ // Exercise the UTC-backend:
+ { "UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 },
+ // Zone with no transitions (QTBUG-74614, QTBUG-74666, when TZ backend uses minimal data)
+ { "Etc/UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 },
+ { "Etc/UTC", "pre_int32", 1901, 12, 13, 20, 45, 51, 0, 0 },
+ { "Etc/UTC", "post_int32", 2038, 1, 19, 3, 14, 9, 0, 0 },
+ { "Etc/UTC", "post_uint32", 2106, 2, 7, 6, 28, 17, 0, 0 },
+ { "Etc/UTC", "initial", -292275056, 5, 16, 16, 47, 5, 0, 0 },
+ { "Etc/UTC", "final", 292278994, 8, 17, 7, 12, 55, 0, 0 },
+ // Kyiv: regression test for QTBUG-64122 (on MS):
+ { "Europe/Kyiv", "summer", 2017, 10, 27, 12, 0, 0, 2 * 3600, 3600 },
+ { "Europe/Kyiv", "winter", 2017, 10, 29, 12, 0, 0, 2 * 3600, 0 }
+ };
+ for (const auto &entry : table) {
+ QTimeZone zone(entry.zone);
+ if (zone.isValid()) {
+ QTest::addRow("%s@%s", entry.zone, entry.nick)
+ << zone
+ << QDateTime(QDate(entry.year, entry.month, entry.day),
+ QTime(entry.hour, entry.min, entry.sec), zone)
+ << entry.dst + entry.std << entry.std << entry.dst;
+ } else {
+ qWarning("Skipping %s@%s test as zone is invalid", entry.zone, entry.nick);
+ }
+ }
+}
+
+void tst_QTimeZone::checkOffset()
+{
+ QFETCH(QTimeZone, zone);
+ QFETCH(QDateTime, when);
+ QFETCH(int, netOffset);
+ QFETCH(int, stdOffset);
+ QFETCH(int, dstOffset);
+
+ QVERIFY(zone.isValid()); // It was when _data() added the row !
+ QCOMPARE(zone.offsetFromUtc(when), netOffset);
+ QCOMPARE(zone.standardTimeOffset(when), stdOffset);
+ QCOMPARE(zone.daylightTimeOffset(when), dstOffset);
+ QCOMPARE(zone.isDaylightTime(when), dstOffset != 0);
+
+ // Also test offsetData(), which gets all this data in one go:
+ const auto data = zone.offsetData(when);
+ QCOMPARE(data.atUtc, when);
+ QCOMPARE(data.offsetFromUtc, netOffset);
+ QCOMPARE(data.standardTimeOffset, stdOffset);
+ QCOMPARE(data.daylightTimeOffset, dstOffset);
+}
+
+void tst_QTimeZone::availableTimeZoneIds()
+{
+ if (debug) {
+ qDebug() << "";
+ qDebug() << "Available Time Zones" ;
+ qDebug() << QTimeZone::availableTimeZoneIds();
+ qDebug() << "";
+ qDebug() << "Available Time Zones in the US";
+ qDebug() << QTimeZone::availableTimeZoneIds(QLocale::UnitedStates);
+ qDebug() << "";
+ qDebug() << "Available Time Zones with UTC Offset 0";
+ qDebug() << QTimeZone::availableTimeZoneIds(0);
+ qDebug() << "";
+ } else {
+ //Just test the calls work, we cannot know what any test machine has available
+ QList<QByteArray> listAll = QTimeZone::availableTimeZoneIds();
+ QList<QByteArray> listUs = QTimeZone::availableTimeZoneIds(QLocale::UnitedStates);
+ QList<QByteArray> listZero = QTimeZone::availableTimeZoneIds(0);
+ }
+}
+
+void tst_QTimeZone::stressTest()
+{
+ const auto UTC = QTimeZone::UTC;
+ const QList<QByteArray> idList = QTimeZone::availableTimeZoneIds();
+ for (const QByteArray &id : idList) {
+ QTimeZone testZone = QTimeZone(id);
+ QCOMPARE(testZone.isValid(), true);
+ QCOMPARE(testZone.id(), id);
+ QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0), UTC);
+ testZone.territory();
+ testZone.comment();
+ testZone.displayName(testDate);
+ testZone.displayName(QTimeZone::DaylightTime);
+ testZone.displayName(QTimeZone::StandardTime);
+ testZone.abbreviation(testDate);
+ testZone.offsetFromUtc(testDate);
+ testZone.standardTimeOffset(testDate);
+ testZone.daylightTimeOffset(testDate);
+ testZone.hasDaylightTime();
+ testZone.isDaylightTime(testDate);
+ testZone.offsetData(testDate);
+ testZone.hasTransitions();
+ testZone.nextTransition(testDate);
+ testZone.previousTransition(testDate);
+ // Dates known to be outside possible tz file pre-calculated rules range
+ QDateTime lowDate1 = QDateTime(QDate(1800, 1, 1), QTime(0, 0), UTC);
+ QDateTime lowDate2 = QDateTime(QDate(1800, 6, 1), QTime(0, 0), UTC);
+ QDateTime highDate1 = QDateTime(QDate(2200, 1, 1), QTime(0, 0), UTC);
+ QDateTime highDate2 = QDateTime(QDate(2200, 6, 1), QTime(0, 0), UTC);
+ testZone.nextTransition(lowDate1);
+ testZone.nextTransition(lowDate2);
+ testZone.previousTransition(lowDate2);
+ testZone.previousTransition(lowDate2);
+ testZone.nextTransition(highDate1);
+ testZone.nextTransition(highDate2);
+ testZone.previousTransition(highDate1);
+ testZone.previousTransition(highDate2);
+ if (debug) {
+ // This could take a long time, depending on platform and database
+ qDebug() << "Stress test calculating transistions for" << testZone.id();
+ testZone.transitions(lowDate1, highDate1);
+ }
+ testDate.setTimeZone(testZone);
+ testDate.isValid();
+ testDate.offsetFromUtc();
+ testDate.timeZoneAbbreviation();
+ }
+}
+
+void tst_QTimeZone::windowsId()
+{
+/*
+ Current Windows zones for "Central Standard Time":
+ Region IANA Id(s)
+ Default "America/Chicago"
+ Canada "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute"
+ Mexico "America/Matamoros"
+ USA "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee"
+ "America/North_Dakota/Beulah America/North_Dakota/Center"
+ "America/North_Dakota/New_Salem"
+ AnyTerritory "CST6CDT"
+*/
+ QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chicago"),
+ QByteArray("Central Standard Time"));
+ QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Resolute"),
+ QByteArray("Central Standard Time"));
+
+ // Partials shouldn't match
+ QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chi"), QByteArray());
+ QCOMPARE(QTimeZone::ianaIdToWindowsId("InvalidZone"), QByteArray());
+ QCOMPARE(QTimeZone::ianaIdToWindowsId(QByteArray()), QByteArray());
+
+ // Check default value
+ QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time"),
+ QByteArray("America/Chicago"));
+ QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::Canada),
+ QByteArray("America/Winnipeg"));
+ QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::AnyTerritory),
+ QByteArray("CST6CDT"));
+ QCOMPARE(QTimeZone::windowsIdToDefaultIanaId(QByteArray()), QByteArray());
+
+ {
+ // With no country, expect sorted list of all zones for ID
+ const QList<QByteArray> list = {
+ "America/Chicago", "America/Indiana/Knox", "America/Indiana/Tell_City",
+ "America/Matamoros", "America/Menominee", "America/North_Dakota/Beulah",
+ "America/North_Dakota/Center", "America/North_Dakota/New_Salem",
+ "America/Ojinaga", "America/Rainy_River", "America/Rankin_Inlet",
+ "America/Resolute", "America/Winnipeg", "CST6CDT"
+ };
+ QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time"), list);
+ }
+ {
+ // Check country with no match returns empty list
+ const QList<QByteArray> empty;
+ QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::NewZealand),
+ empty);
+ }
+ {
+ // Check valid country returns list in preference order
+ const QList<QByteArray> list = {
+ "America/Winnipeg", "America/Rainy_River", "America/Rankin_Inlet", "America/Resolute"
+ };
+ QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Canada), list);
+ }
+ {
+ const QList<QByteArray> list = { "America/Matamoros", "America/Ojinaga" };
+ QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Mexico), list);
+ }
+ {
+ const QList<QByteArray> list = {
+ "America/Chicago", "America/Indiana/Knox", "America/Indiana/Tell_City",
+ "America/Menominee", "America/North_Dakota/Beulah", "America/North_Dakota/Center",
+ "America/North_Dakota/New_Salem"
+ };
+ QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::UnitedStates),
+ list);
+ }
+ {
+ const QList<QByteArray> list = { "CST6CDT" };
+ QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::AnyTerritory),
+ list);
+ }
+ {
+ // Check empty if given no windowsId:
+ const QList<QByteArray> empty;
+ QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray()), empty);
+ QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray(), QLocale::AnyTerritory), empty);
+ }
+}
+
+void tst_QTimeZone::isValidId_data()
+{
+#ifdef QT_BUILD_INTERNAL
+ QTest::addColumn<QByteArray>("input");
+ QTest::addColumn<bool>("valid");
+
+ // a-z, A-Z, 0-9, '.', '-', '_' are valid chars
+ // Can't start with '-'
+ // Parts separated by '/', each part min 1 and max of 14 chars
+ // (Android has parts with lengths up to 17, so tolerates this as a special case.)
+#define TESTSET(name, section, valid) \
+ QTest::newRow(name " front") << QByteArray(section "/xyz/xyz") << valid; \
+ QTest::newRow(name " middle") << QByteArray("xyz/" section "/xyz") << valid; \
+ QTest::newRow(name " back") << QByteArray("xyz/xyz/" section) << valid
+
+ // a-z, A-Z, 0-9, '.', '-', '_' are valid chars
+ // Can't start with '-'
+ // Parts separated by '/', each part min 1 and max of 14 chars
+ TESTSET("empty", "", false);
+ TESTSET("minimal", "m", true);
+#if defined(Q_OS_ANDROID) || QT_CONFIG(icu)
+ TESTSET("maximal", "East-Saskatchewan", true); // Android actually uses this
+ TESTSET("too long", "North-Saskatchewan", false); // ... but thankfully not this.
+#else
+ TESTSET("maximal", "12345678901234", true);
+ TESTSET("maximal twice", "12345678901234/12345678901234", true);
+ TESTSET("too long", "123456789012345", false);
+ TESTSET("too-long/maximal", "123456789012345/12345678901234", false);
+ TESTSET("maximal/too-long", "12345678901234/123456789012345", false);
+#endif
+
+ TESTSET("bad hyphen", "-hyphen", false);
+ TESTSET("good hyphen", "hy-phen", true);
+
+ TESTSET("valid char _", "_", true);
+ TESTSET("valid char .", ".", true);
+ TESTSET("valid char :", ":", true);
+ TESTSET("valid char +", "+", true);
+ TESTSET("valid char A", "A", true);
+ TESTSET("valid char Z", "Z", true);
+ TESTSET("valid char a", "a", true);
+ TESTSET("valid char z", "z", true);
+ TESTSET("valid char 0", "0", true);
+ TESTSET("valid char 9", "9", true);
+
+ TESTSET("valid pair az", "az", true);
+ TESTSET("valid pair AZ", "AZ", true);
+ TESTSET("valid pair 09", "09", true);
+ TESTSET("valid pair .z", ".z", true);
+ TESTSET("valid pair _z", "_z", true);
+ TESTSET("invalid pair -z", "-z", false);
+
+ TESTSET("valid triple a/z", "a/z", true);
+ TESTSET("valid triple a.z", "a.z", true);
+ TESTSET("valid triple a-z", "a-z", true);
+ TESTSET("valid triple a_z", "a_z", true);
+ TESTSET("invalid triple a z", "a z", false);
+ TESTSET("invalid triple a\\z", "a\\z", false);
+ TESTSET("invalid triple a,z", "a,z", false);
+
+ TESTSET("invalid space", " ", false);
+ TESTSET("invalid char ^", "^", false);
+ TESTSET("invalid char \"", "\"", false);
+ TESTSET("invalid char $", "$", false);
+ TESTSET("invalid char %", "%", false);
+ TESTSET("invalid char &", "&", false);
+ TESTSET("invalid char (", "(", false);
+ TESTSET("invalid char )", ")", false);
+ TESTSET("invalid char =", "=", false);
+ TESTSET("invalid char -", "-", false);
+ TESTSET("invalid char ?", "?", false);
+ TESTSET("invalid char ß", "ß", false);
+ TESTSET("invalid char \\x01", "\x01", false);
+ TESTSET("invalid char ' '", " ", false);
+
+#undef TESTSET
+
+ QTest::newRow("az alone") << QByteArray("az") << true;
+ QTest::newRow("AZ alone") << QByteArray("AZ") << true;
+ QTest::newRow("09 alone") << QByteArray("09") << true;
+ QTest::newRow("a/z alone") << QByteArray("a/z") << true;
+ QTest::newRow("a.z alone") << QByteArray("a.z") << true;
+ QTest::newRow("a-z alone") << QByteArray("a-z") << true;
+ QTest::newRow("a_z alone") << QByteArray("a_z") << true;
+ QTest::newRow(".z alone") << QByteArray(".z") << true;
+ QTest::newRow("_z alone") << QByteArray("_z") << true;
+ QTest::newRow("a z alone") << QByteArray("a z") << false;
+ QTest::newRow("a\\z alone") << QByteArray("a\\z") << false;
+ QTest::newRow("a,z alone") << QByteArray("a,z") << false;
+ QTest::newRow("/z alone") << QByteArray("/z") << false;
+ QTest::newRow("-z alone") << QByteArray("-z") << false;
+#if defined(Q_OS_ANDROID) || QT_CONFIG(icu)
+ QTest::newRow("long alone") << QByteArray("12345678901234567") << true;
+ QTest::newRow("over-long alone") << QByteArray("123456789012345678") << false;
+#else
+ QTest::newRow("long alone") << QByteArray("12345678901234") << true;
+ QTest::newRow("over-long alone") << QByteArray("123456789012345") << false;
+#endif
+
+#else
+ QSKIP("This test requires a Qt -developer-build.");
+#endif // QT_BUILD_INTERNAL
+}
+
+void tst_QTimeZone::isValidId()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QByteArray, input);
+ QFETCH(bool, valid);
+
+ QCOMPARE(QTimeZonePrivate::isValidId(input), valid);
+#endif
+}
+
+void tst_QTimeZone::serialize()
+{
+ int parts = 0;
+#ifndef QT_NO_DEBUG_STREAM
+ QTest::ignoreMessage(QtDebugMsg, "QTimeZone(\"\")");
+ qDebug() << QTimeZone(); // to verify no crash
+ parts++;
+#endif
+#ifndef QT_NO_DATASTREAM
+ QByteArray blob;
+ {
+ QDataStream stream(&blob, QIODevice::WriteOnly);
+ stream << QTimeZone("Europe/Oslo") << QTimeZone(420) << QTimeZone() << qint64(-1);
+ }
+ QDataStream stream(&blob, QIODevice::ReadOnly);
+ QTimeZone invalid, offset, oslo;
+ qint64 minusone;
+ stream >> oslo >> offset >> invalid >> minusone;
+ QCOMPARE(oslo, QTimeZone("Europe/Oslo"));
+ QCOMPARE(offset, QTimeZone(420));
+ QVERIFY(!invalid.isValid());
+ QCOMPARE(minusone, qint64(-1));
+ parts++;
+#endif
+ if (!parts)
+ QSKIP("No serialization enabled");
+}
+
+void tst_QTimeZone::malformed()
+{
+ // Regression test for QTBUG-92808
+ // Strings that look enough like a POSIX zone specifier that the constructor
+ // accepts them, but the specifier is invalid.
+ // Must not crash or trigger assertions when calling offsetFromUtc()
+ const QDateTime now = QDateTime::currentDateTime();
+ QTimeZone barf("QUT4tCZ0 , /");
+ if (barf.isValid())
+ QCOMPARE(barf.offsetFromUtc(now), 0);
+ barf = QTimeZone("QtC+09,,MA");
+ if (barf.isValid())
+ QCOMPARE(barf.offsetFromUtc(now), 0);
+ barf = QTimeZone("UTCC+14:00,-,");
+ if (barf.isValid())
+ QCOMPARE(barf.daylightTimeOffset(now), -14 * 3600);
+}
+
+void tst_QTimeZone::utcTest()
+{
+#ifdef QT_BUILD_INTERNAL
+ // Test default UTC constructor
+ QUtcTimeZonePrivate tzp;
+ QCOMPARE(tzp.isValid(), true);
+ QCOMPARE(tzp.id(), QByteArray("UTC"));
+ QCOMPARE(tzp.territory(), QLocale::AnyTerritory);
+ QCOMPARE(tzp.abbreviation(0), QString("UTC"));
+ QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QLocale()), QString("UTC"));
+ QCOMPARE(tzp.offsetFromUtc(0), 0);
+ QCOMPARE(tzp.standardTimeOffset(0), 0);
+ QCOMPARE(tzp.daylightTimeOffset(0), 0);
+ QCOMPARE(tzp.hasDaylightTime(), false);
+ QCOMPARE(tzp.hasTransitions(), false);
+
+ // Test create from UTC Offset:
+ QDateTime now = QDateTime::currentDateTime();
+ QTimeZone tz(36000);
+ QVERIFY(tz.isValid());
+ QCOMPARE(tz.id(), QByteArray("UTC+10:00"));
+ QCOMPARE(tz.offsetFromUtc(now), 36000);
+ QCOMPARE(tz.standardTimeOffset(now), 36000);
+ QCOMPARE(tz.daylightTimeOffset(now), 0);
+
+ tz = QTimeZone(15 * 3600); // no IANA ID, so uses minimal id, skipping :00 minutes
+ QVERIFY(tz.isValid());
+ QCOMPARE(tz.id(), QByteArray("UTC+15"));
+ QCOMPARE(tz.offsetFromUtc(now), 15 * 3600);
+ QCOMPARE(tz.standardTimeOffset(now), 15 * 3600);
+ QCOMPARE(tz.daylightTimeOffset(now), 0);
+
+ // Test validity range of UTC offsets:
+ int min = QTimeZone::MinUtcOffsetSecs;
+ int max = QTimeZone::MaxUtcOffsetSecs;
+ QCOMPARE(QTimeZone(min - 1).isValid(), false);
+ QCOMPARE(QTimeZone(min).isValid(), true);
+ QCOMPARE(QTimeZone(min + 1).isValid(), true);
+ QCOMPARE(QTimeZone(max - 1).isValid(), true);
+ QCOMPARE(QTimeZone(max).isValid(), true);
+ QCOMPARE(QTimeZone(max + 1).isValid(), false);
+
+ // Test create from standard name (preserves :00 for minutes in id):
+ tz = QTimeZone("UTC+10:00");
+ QVERIFY(tz.isValid());
+ QCOMPARE(tz.id(), QByteArray("UTC+10:00"));
+ QCOMPARE(tz.offsetFromUtc(now), 36000);
+ QCOMPARE(tz.standardTimeOffset(now), 36000);
+ QCOMPARE(tz.daylightTimeOffset(now), 0);
+
+ // Test create custom zone
+ tz = QTimeZone("QST", 123456, "Qt Standard Time", "QST", QLocale::Norway, "Qt Testing");
+ QCOMPARE(tz.isValid(), true);
+ QCOMPARE(tz.id(), QByteArray("QST"));
+ QCOMPARE(tz.comment(), QString("Qt Testing"));
+ QCOMPARE(tz.territory(), QLocale::Norway);
+ QCOMPARE(tz.abbreviation(now), QString("QST"));
+ QCOMPARE(tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QLocale()),
+ QString("Qt Standard Time"));
+ QCOMPARE(tz.offsetFromUtc(now), 123456);
+ QCOMPARE(tz.standardTimeOffset(now), 123456);
+ QCOMPARE(tz.daylightTimeOffset(now), 0);
+#endif // QT_BUILD_INTERNAL
+}
+
+// Relies on local variable names: zone tzp and locale enUS.
+#define ZONE_DNAME_CHECK(type, name, val) \
+ QCOMPARE(tzp.displayName(QTimeZone::type, QTimeZone::name, enUS), \
+ QStringLiteral(val));
+
+void tst_QTimeZone::icuTest()
+{
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu)
+ // Known datetimes
+ qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
+ qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
+
+ // Test default constructor
+ QIcuTimeZonePrivate tzpd;
+ QVERIFY(tzpd.isValid());
+
+ // Test invalid is not available:
+ QVERIFY(!tzpd.isTimeZoneIdAvailable("Gondwana/Erewhon"));
+ // and construction gives an invalid result:
+ QIcuTimeZonePrivate tzpi("Gondwana/Erewhon");
+ QCOMPARE(tzpi.isValid(), false);
+
+ // Test named constructor
+ QIcuTimeZonePrivate tzp("Europe/Berlin");
+ QVERIFY(tzp.isValid());
+
+ // Only test names in debug mode, names used can vary by ICU version installed
+ if (debug) {
+ // Test display names by type
+ QLocale enUS("en_US");
+ ZONE_DNAME_CHECK(StandardTime, LongName, "Central European Standard Time");
+ ZONE_DNAME_CHECK(StandardTime, ShortName, "GMT+01:00");
+ ZONE_DNAME_CHECK(StandardTime, OffsetName, "UTC+01:00");
+ ZONE_DNAME_CHECK(DaylightTime, LongName, "Central European Summer Time");
+ ZONE_DNAME_CHECK(DaylightTime, ShortName, "GMT+02:00");
+ ZONE_DNAME_CHECK(DaylightTime, OffsetName, "UTC+02:00");
+ // ICU C api does not support Generic Time yet, C++ api does
+ ZONE_DNAME_CHECK(GenericTime, LongName, "Central European Standard Time");
+ ZONE_DNAME_CHECK(GenericTime, ShortName, "GMT+01:00");
+ ZONE_DNAME_CHECK(GenericTime, OffsetName, "UTC+01:00");
+
+ // Test Abbreviations
+ QCOMPARE(tzp.abbreviation(std), QString("CET"));
+ QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
+ }
+
+ testCetPrivate(tzp);
+ if (QTest::currentTestFailed())
+ return;
+ testEpochTranPrivate(QIcuTimeZonePrivate("America/Toronto"));
+#endif // icu
+}
+
+void tst_QTimeZone::tzTest()
+{
+#if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID
+ const auto UTC = QTimeZone::UTC;
+ // Known datetimes
+ qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
+ qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
+
+ // Test default constructor
+ QTzTimeZonePrivate tzpd;
+ QVERIFY(tzpd.isValid());
+
+ // Test invalid constructor
+ QTzTimeZonePrivate tzpi("Gondwana/Erewhon");
+ QVERIFY(!tzpi.isValid());
+
+ // Test named constructor
+ QTzTimeZonePrivate tzp("Europe/Berlin");
+ QVERIFY(tzp.isValid());
+
+ // Test POSIX-format value for $TZ:
+ QTimeZone tzposix("MET-1METDST-2,M3.5.0/02:00:00,M10.5.0/03:00:00");
+ QVERIFY(tzposix.isValid());
+ QVERIFY(tzposix.hasDaylightTime());
+
+ // RHEL has been seen with this as Africa/Casablanca's POSIX rule:
+ QTzTimeZonePrivate permaDst("<+00>0<+01>,0/0,J365/25");
+ const QTimeZone utcP1("UTC+01:00"); // Should always have same offset as permaDst
+ QVERIFY(permaDst.isValid());
+ QVERIFY(permaDst.hasDaylightTime());
+ QVERIFY(permaDst.isDaylightTime(QDate(2020, 1, 1).startOfDay(utcP1).toMSecsSinceEpoch()));
+ QVERIFY(permaDst.isDaylightTime(QDate(2020, 12, 31).endOfDay(utcP1).toMSecsSinceEpoch()));
+ // Note that the final /25 could be misunderstood as putting a fall-back at
+ // 1am on the next year's Jan 1st; check we don't do that:
+ QVERIFY(permaDst.isDaylightTime(
+ QDateTime(QDate(2020, 1, 1), QTime(1, 30), utcP1).toMSecsSinceEpoch()));
+ // It shouldn't have any transitions. QTimeZone::hasTransitions() only says
+ // whether the backend supports them, so ask for transitions in a wide
+ // enough interval that one would show up, if there are any:
+ QVERIFY(permaDst.transitions(QDate(2015, 1, 1).startOfDay(UTC).toMSecsSinceEpoch(),
+ QDate(2020, 1, 1).startOfDay(UTC).toMSecsSinceEpoch()
+ ).isEmpty());
+
+ QTimeZone tzBrazil("BRT+3"); // parts of Northern Brazil, as a POSIX rule
+ QVERIFY(tzBrazil.isValid());
+ QCOMPARE(tzBrazil.offsetFromUtc(QDateTime(QDate(1111, 11, 11).startOfDay())), -10800);
+
+ // Test display names by type, either ICU or abbreviation only
+ QLocale enUS("en_US");
+ // Only test names in debug mode, names used can vary by ICU version installed
+ if (debug) {
+#if QT_CONFIG(icu)
+ ZONE_DNAME_CHECK(StandardTime, LongName, "Central European Standard Time");
+ ZONE_DNAME_CHECK(StandardTime, ShortName, "GMT+01:00");
+ ZONE_DNAME_CHECK(StandardTime, OffsetName, "UTC+01:00");
+ ZONE_DNAME_CHECK(DaylightTime, LongName, "Central European Summer Time");
+ ZONE_DNAME_CHECK(DaylightTime, ShortName, "GMT+02:00");
+ ZONE_DNAME_CHECK(DaylightTime, OffsetName, "UTC+02:00");
+ // ICU C api does not support Generic Time yet, C++ api does
+ ZONE_DNAME_CHECK(GenericTime, LongName, "Central European Standard Time");
+ ZONE_DNAME_CHECK(GenericTime, ShortName, "GMT+01:00");
+ ZONE_DNAME_CHECK(GenericTime, OffsetName, "UTC+01:00");
+#else
+ ZONE_DNAME_CHECK(StandardTime, LongName, "CET");
+ ZONE_DNAME_CHECK(StandardTime, ShortName, "CET");
+ ZONE_DNAME_CHECK(StandardTime, OffsetName, "CET");
+ ZONE_DNAME_CHECK(DaylightTime, LongName, "CEST");
+ ZONE_DNAME_CHECK(DaylightTime, ShortName, "CEST");
+ ZONE_DNAME_CHECK(DaylightTime, OffsetName, "CEST");
+ ZONE_DNAME_CHECK(GenericTime, LongName, "CET");
+ ZONE_DNAME_CHECK(GenericTime, ShortName, "CET");
+ ZONE_DNAME_CHECK(GenericTime, OffsetName, "CET");
+#endif // icu
+
+ // Test Abbreviations
+ QCOMPARE(tzp.abbreviation(std), QString("CET"));
+ QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
+ }
+
+ testCetPrivate(tzp);
+ if (QTest::currentTestFailed())
+ return;
+ testEpochTranPrivate(QTzTimeZonePrivate("America/Toronto"));
+ if (QTest::currentTestFailed())
+ return;
+
+ // Test first and last transition rule
+ // Warning: This could vary depending on age of TZ file!
+
+ // Test low date uses first rule found
+ constexpr qint64 ancient = -Q_INT64_C(9999999999999);
+ // Note: Depending on the OS in question, the database may be carrying the
+ // Local Mean Time. which for Berlin is 0:53:28
+ QTimeZonePrivate::Data dat = tzp.data(ancient);
+ QCOMPARE(dat.atMSecsSinceEpoch, ancient);
+ QCOMPARE(dat.daylightTimeOffset, 0);
+ if (dat.abbreviation == "LMT") {
+ QCOMPARE(dat.standardTimeOffset, 3208);
+ } else {
+ QCOMPARE(dat.standardTimeOffset, 3600);
+
+ constexpr qint64 invalidTime = std::numeric_limits<qint64>::min();
+ constexpr int invalidOffset = std::numeric_limits<int>::min();
+ // Test previous to low value is invalid
+ dat = tzp.previousTransition(ancient);
+ QCOMPARE(dat.atMSecsSinceEpoch, invalidTime);
+ QCOMPARE(dat.standardTimeOffset, invalidOffset);
+ QCOMPARE(dat.daylightTimeOffset, invalidOffset);
+ }
+
+ dat = tzp.nextTransition(ancient);
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch,
+ QTimeZone::fromSecondsAheadOfUtc(3600)),
+ QDateTime(QDate(1893, 4, 1), QTime(0, 6, 32),
+ QTimeZone::fromSecondsAheadOfUtc(3600)));
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 0);
+
+ // Date-times late enough to exercise POSIX rules:
+ qint64 stdHi = QDate(2100, 1, 1).startOfDay(UTC).toMSecsSinceEpoch();
+ qint64 dstHi = QDate(2100, 6, 1).startOfDay(UTC).toMSecsSinceEpoch();
+ // Relevant last Sundays in October and March:
+ QCOMPARE(Qt::DayOfWeek(QDate(2099, 10, 25).dayOfWeek()), Qt::Sunday);
+ QCOMPARE(Qt::DayOfWeek(QDate(2100, 3, 28).dayOfWeek()), Qt::Sunday);
+ QCOMPARE(Qt::DayOfWeek(QDate(2100, 10, 31).dayOfWeek()), Qt::Sunday);
+
+ dat = tzp.data(stdHi);
+ QCOMPARE(dat.atMSecsSinceEpoch - stdHi, qint64(0));
+ QCOMPARE(dat.offsetFromUtc, 3600);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 0);
+
+ dat = tzp.data(dstHi);
+ QCOMPARE(dat.atMSecsSinceEpoch - dstHi, qint64(0));
+ QCOMPARE(dat.offsetFromUtc, 7200);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 3600);
+
+ dat = tzp.previousTransition(stdHi);
+ QCOMPARE(dat.abbreviation, QStringLiteral("CET"));
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2099, 10, 25), QTime(3, 0), QTimeZone::fromSecondsAheadOfUtc(7200)));
+ QCOMPARE(dat.offsetFromUtc, 3600);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 0);
+
+ dat = tzp.previousTransition(dstHi);
+ QCOMPARE(dat.abbreviation, QStringLiteral("CEST"));
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2100, 3, 28), QTime(2, 0), QTimeZone::fromSecondsAheadOfUtc(3600)));
+ QCOMPARE(dat.offsetFromUtc, 7200);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 3600);
+
+ dat = tzp.nextTransition(stdHi);
+ QCOMPARE(dat.abbreviation, QStringLiteral("CEST"));
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2100, 3, 28), QTime(2, 0), QTimeZone::fromSecondsAheadOfUtc(3600)));
+ QCOMPARE(dat.offsetFromUtc, 7200);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 3600);
+
+ dat = tzp.nextTransition(dstHi);
+ QCOMPARE(dat.abbreviation, QStringLiteral("CET"));
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch,
+ QTimeZone::fromSecondsAheadOfUtc(3600)),
+ QDateTime(QDate(2100, 10, 31), QTime(3, 0), QTimeZone::fromSecondsAheadOfUtc(7200)));
+ QCOMPARE(dat.offsetFromUtc, 3600);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 0);
+
+ // Test TZ timezone vs UTC timezone for non-whole-hour negative offset:
+ QTzTimeZonePrivate tztz1("America/Caracas");
+ QUtcTimeZonePrivate tzutc1("UTC-04:30");
+ QVERIFY(tztz1.isValid());
+ QVERIFY(tzutc1.isValid());
+ QTzTimeZonePrivate::Data datatz1 = tztz1.data(std);
+ QTzTimeZonePrivate::Data datautc1 = tzutc1.data(std);
+ QCOMPARE(datatz1.offsetFromUtc, datautc1.offsetFromUtc);
+
+ // Test TZ timezone vs UTC timezone for non-whole-hour positive offset:
+ QTzTimeZonePrivate tztz2k("Asia/Kolkata"); // New name
+ QTzTimeZonePrivate tztz2c("Asia/Calcutta"); // Legacy name
+ // Can't assign QtzTZP, so use a reference; prefer new name.
+ QTzTimeZonePrivate &tztz2 = tztz2k.isValid() ? tztz2k : tztz2c;
+ QUtcTimeZonePrivate tzutc2("UTC+05:30");
+ QVERIFY2(tztz2.isValid(), tztz2.id().constData());
+ QVERIFY(tzutc2.isValid());
+ QTzTimeZonePrivate::Data datatz2 = tztz2.data(std);
+ QTzTimeZonePrivate::Data datautc2 = tzutc2.data(std);
+ QCOMPARE(datatz2.offsetFromUtc, datautc2.offsetFromUtc);
+
+ // Test a timezone with an abbreviation that isn't all letters:
+ QTzTimeZonePrivate tzBarnaul("Asia/Barnaul");
+ if (tzBarnaul.isValid()) {
+ QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07"));
+
+ // first full day of the new rule (tzdata2016b)
+ QDateTime dt(QDate(2016, 3, 28), QTime(0, 0), UTC);
+ QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07"));
+ }
+#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN
+}
+
+void tst_QTimeZone::macTest()
+{
+#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_DARWIN)
+ // Known datetimes
+ qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
+ qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
+
+ // Test default constructor
+ QMacTimeZonePrivate tzpd;
+ QVERIFY(tzpd.isValid());
+
+ // Test invalid constructor
+ QMacTimeZonePrivate tzpi("Gondwana/Erewhon");
+ QCOMPARE(tzpi.isValid(), false);
+
+ // Test named constructor
+ QMacTimeZonePrivate tzp("Europe/Berlin");
+ QVERIFY(tzp.isValid());
+
+ // Only test names in debug mode, names used can vary by version
+ if (debug) {
+ // Test display names by type
+ QLocale enUS("en_US");
+ ZONE_DNAME_CHECK(StandardTime, LongName, "Central European Standard Time");
+ ZONE_DNAME_CHECK(StandardTime, ShortName, "GMT+01:00");
+ ZONE_DNAME_CHECK(StandardTime, OffsetName, "UTC+01:00");
+ ZONE_DNAME_CHECK(DaylightTime, LongName, "Central European Summer Time");
+ ZONE_DNAME_CHECK(DaylightTime, ShortName, "GMT+02:00");
+ ZONE_DNAME_CHECK(DaylightTime, OffsetName, "UTC+02:00");
+ // ICU C api does not support Generic Time yet, C++ api does
+ ZONE_DNAME_CHECK(GenericTime, LongName, "Central European Time");
+ ZONE_DNAME_CHECK(GenericTime, ShortName, "Germany Time");
+ ZONE_DNAME_CHECK(GenericTime, OffsetName, "UTC+01:00");
+
+ // Test Abbreviations
+ QCOMPARE(tzp.abbreviation(std), QString("CET"));
+ QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
+ }
+
+ testCetPrivate(tzp);
+ if (QTest::currentTestFailed())
+ return;
+ testEpochTranPrivate(QMacTimeZonePrivate("America/Toronto"));
+#endif // QT_BUILD_INTERNAL && Q_OS_DARWIN
+}
+
+void tst_QTimeZone::darwinTypes()
+{
+#ifndef Q_OS_DARWIN
+ QSKIP("This is an Apple-only test");
+#else
+ extern void tst_QTimeZone_darwinTypes(); // in tst_qtimezone_darwin.mm
+ tst_QTimeZone_darwinTypes();
+#endif
+}
+
+void tst_QTimeZone::winTest()
+{
+#if defined(QT_BUILD_INTERNAL) && defined(USING_WIN_TZ)
+ // Known datetimes
+ qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
+ qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
+
+ // Test default constructor
+ QWinTimeZonePrivate tzpd;
+ if (debug)
+ qDebug() << "System ID = " << tzpd.id()
+ << tzpd.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QLocale())
+ << tzpd.displayName(QTimeZone::GenericTime, QTimeZone::LongName, QLocale());
+ QVERIFY(tzpd.isValid());
+
+ // Test invalid constructor
+ QWinTimeZonePrivate tzpi("Gondwana/Erewhon");
+ QCOMPARE(tzpi.isValid(), false);
+
+ // Test named constructor
+ QWinTimeZonePrivate tzp("Europe/Berlin");
+ QVERIFY(tzp.isValid());
+
+ // Only test names in debug mode, names used can vary by version
+ if (debug) {
+ // Test display names by type
+ QLocale enUS("en_US");
+ ZONE_DNAME_CHECK(StandardTime, LongName, "W. Europe Standard Time");
+ ZONE_DNAME_CHECK(StandardTime, ShortName, "W. Europe Standard Time");
+ ZONE_DNAME_CHECK(StandardTime, OffsetName, "UTC+01:00");
+ ZONE_DNAME_CHECK(DaylightTime, LongName, "W. Europe Daylight Time");
+ ZONE_DNAME_CHECK(DaylightTime, ShortName, "W. Europe Daylight Time");
+ ZONE_DNAME_CHECK(DaylightTime, OffsetName, "UTC+02:00");
+ ZONE_DNAME_CHECK(GenericTime, LongName,
+ "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna");
+ ZONE_DNAME_CHECK(GenericTime, ShortName,
+ "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna");
+ ZONE_DNAME_CHECK(GenericTime, OffsetName, "UTC+01:00");
+
+ // Test Abbreviations
+ QCOMPARE(tzp.abbreviation(std), QString("W. Europe Standard Time"));
+ QCOMPARE(tzp.abbreviation(dst), QString("W. Europe Daylight Time"));
+ }
+
+ testCetPrivate(tzp);
+ if (QTest::currentTestFailed())
+ return;
+ testEpochTranPrivate(QWinTimeZonePrivate("America/Toronto"));
+#endif // QT_BUILD_INTERNAL && USING_WIN_TZ
+}
+
+#undef ZONE_DNAME_CHECK
+
+void tst_QTimeZone::localeSpecificDisplayName_data()
+{
+#ifdef USING_WIN_TZ
+ QSKIP("MS backend does not use locale parameter");
+#endif
+ QTest::addColumn<QByteArray>("zoneName");
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QTimeZone::TimeType>("timeType");
+ QTest::addColumn<QString>("expectedName");
+
+ QStringList names;
+ QLocale locale;
+ // Pick a non-system locale; German or French
+ if (QLocale::system().language() != QLocale::German) {
+ locale = QLocale(QLocale::German);
+ names << QString("Mitteleurop\u00e4ische Normalzeit")
+ << QString("Mitteleurop\u00e4ische Sommerzeit");
+ } else {
+ locale = QLocale(QLocale::French);
+ names << QString("heure normale d\u2019Europe centrale")
+ << QString("heure d\u2019\u00E9t\u00E9 d\u2019Europe centrale");
+ }
+
+ qsizetype index = 0;
+ QTest::newRow("Berlin, standard time")
+ << QByteArray("Europe/Berlin") << locale << QTimeZone::StandardTime
+ << names.at(index++);
+
+ QTest::newRow("Berlin, summer time")
+ << QByteArray("Europe/Berlin") << locale << QTimeZone::DaylightTime
+ << names.at(index++);
+}
+
+void tst_QTimeZone::localeSpecificDisplayName()
+{
+ // This test checks that QTimeZone::displayName() correctly uses the
+ // specified locale, NOT the system locale (see QTBUG-101460).
+ QFETCH(QByteArray, zoneName);
+ QFETCH(QLocale, locale);
+ QFETCH(QTimeZone::TimeType, timeType);
+ QFETCH(QString, expectedName);
+
+ QTimeZone zone(zoneName);
+ QVERIFY(zone.isValid());
+
+ const QString localeName = zone.displayName(timeType, QTimeZone::LongName, locale);
+ QCOMPARE(localeName, expectedName);
+}
+
+#ifdef QT_BUILD_INTERNAL
+// Test each private produces the same basic results for CET
+void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
+{
+ // Known datetimes
+ const auto UTC = QTimeZone::UTC;
+ const auto eastOneHour = QTimeZone::fromSecondsAheadOfUtc(3600);
+ qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
+ qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
+ qint64 prev = QDateTime(QDate(2011, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
+
+ QCOMPARE(tzp.offsetFromUtc(std), 3600);
+ QCOMPARE(tzp.offsetFromUtc(dst), 7200);
+
+ QCOMPARE(tzp.standardTimeOffset(std), 3600);
+ QCOMPARE(tzp.standardTimeOffset(dst), 3600);
+
+ QCOMPARE(tzp.daylightTimeOffset(std), 0);
+ QCOMPARE(tzp.daylightTimeOffset(dst), 3600);
+
+ QCOMPARE(tzp.hasDaylightTime(), true);
+ QCOMPARE(tzp.isDaylightTime(std), false);
+ QCOMPARE(tzp.isDaylightTime(dst), true);
+
+ QTimeZonePrivate::Data dat = tzp.data(std);
+ QCOMPARE(dat.atMSecsSinceEpoch, std);
+ QCOMPARE(dat.offsetFromUtc, 3600);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 0);
+ QCOMPARE(dat.abbreviation, tzp.abbreviation(std));
+
+ dat = tzp.data(dst);
+ QCOMPARE(dat.atMSecsSinceEpoch, dst);
+ QCOMPARE(dat.offsetFromUtc, 7200);
+ QCOMPARE(dat.standardTimeOffset, 3600);
+ QCOMPARE(dat.daylightTimeOffset, 3600);
+ QCOMPARE(dat.abbreviation, tzp.abbreviation(dst));
+
+ // Only test transitions if host system supports them
+ if (tzp.hasTransitions()) {
+ QTimeZonePrivate::Data tran = tzp.nextTransition(std);
+ // 2012-03-25 02:00 CET, +1 -> +2
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2012, 3, 25), QTime(2, 0), eastOneHour));
+ QCOMPARE(tran.offsetFromUtc, 7200);
+ QCOMPARE(tran.standardTimeOffset, 3600);
+ QCOMPARE(tran.daylightTimeOffset, 3600);
+
+ tran = tzp.nextTransition(dst);
+ // 2012-10-28 03:00 CEST, +2 -> +1
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2012, 10, 28), QTime(3, 0),
+ QTimeZone::fromSecondsAheadOfUtc(2 * 3600)));
+ QCOMPARE(tran.offsetFromUtc, 3600);
+ QCOMPARE(tran.standardTimeOffset, 3600);
+ QCOMPARE(tran.daylightTimeOffset, 0);
+
+ tran = tzp.previousTransition(std);
+ // 2011-10-30 03:00 CEST, +2 -> +1
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2011, 10, 30), QTime(3, 0),
+ QTimeZone::fromSecondsAheadOfUtc(2 * 3600)));
+ QCOMPARE(tran.offsetFromUtc, 3600);
+ QCOMPARE(tran.standardTimeOffset, 3600);
+ QCOMPARE(tran.daylightTimeOffset, 0);
+
+ tran = tzp.previousTransition(dst);
+ // 2012-03-25 02:00 CET, +1 -> +2 (again)
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(2012, 3, 25), QTime(2, 0), eastOneHour));
+ QCOMPARE(tran.offsetFromUtc, 7200);
+ QCOMPARE(tran.standardTimeOffset, 3600);
+ QCOMPARE(tran.daylightTimeOffset, 3600);
+
+ QTimeZonePrivate::DataList expected;
+ // 2011-03-27 02:00 CET, +1 -> +2
+ tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 3, 27), QTime(2, 0),
+ eastOneHour).toMSecsSinceEpoch();
+ tran.offsetFromUtc = 7200;
+ tran.standardTimeOffset = 3600;
+ tran.daylightTimeOffset = 3600;
+ expected << tran;
+ // 2011-10-30 03:00 CEST, +2 -> +1
+ tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 10, 30), QTime(3, 0),
+ QTimeZone::fromSecondsAheadOfUtc(2 * 3600)
+ ).toMSecsSinceEpoch();
+ tran.offsetFromUtc = 3600;
+ tran.standardTimeOffset = 3600;
+ tran.daylightTimeOffset = 0;
+ expected << tran;
+ QTimeZonePrivate::DataList result = tzp.transitions(prev, std);
+ QCOMPARE(result.size(), expected.size());
+ for (int i = 0; i < expected.size(); ++i) {
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(result.at(i).atMSecsSinceEpoch, eastOneHour),
+ QDateTime::fromMSecsSinceEpoch(expected.at(i).atMSecsSinceEpoch, eastOneHour));
+ QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
+ QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
+ QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
+ }
+ }
+}
+
+// Needs a zone with DST around the epoch; currently America/Toronto (EST5EDT)
+void tst_QTimeZone::testEpochTranPrivate(const QTimeZonePrivate &tzp)
+{
+ if (!tzp.hasTransitions())
+ return; // test only viable for transitions
+
+ const auto UTC = QTimeZone::UTC;
+ const auto hour = std::chrono::hours{1};
+ QTimeZonePrivate::Data tran = tzp.nextTransition(0); // i.e. first after epoch
+ // 1970-04-26 02:00 EST, -5 -> -4
+ const QDateTime after = QDateTime(QDate(1970, 4, 26), QTime(2, 0),
+ QTimeZone::fromDurationAheadOfUtc(-5 * hour));
+ const QDateTime found = QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC);
+#ifdef USING_WIN_TZ // MS gets the date wrong: 5th April instead of 26th.
+ QCOMPARE(found.toOffsetFromUtc(-5 * 3600).time(), after.time());
+#else
+ QCOMPARE(found, after);
+#endif
+ QCOMPARE(tran.offsetFromUtc, -4 * 3600);
+ QCOMPARE(tran.standardTimeOffset, -5 * 3600);
+ QCOMPARE(tran.daylightTimeOffset, 3600);
+
+ // Pre-epoch time-zones might not be supported at all:
+ tran = tzp.nextTransition(QDateTime(QDate(1601, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch());
+ if (tran.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs()
+ // Toronto *did* have a transition before 1970 (DST since 1918):
+ && tran.atMSecsSinceEpoch < 0) {
+ // ... but, if they are, we should be able to search back to them:
+ tran = tzp.previousTransition(0); // i.e. last before epoch
+ // 1969-10-26 02:00 EDT, -4 -> -5
+ QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
+ QDateTime(QDate(1969, 10, 26), QTime(2, 0),
+ QTimeZone::fromDurationAheadOfUtc(-4 * hour)));
+ QCOMPARE(tran.offsetFromUtc, -5 * 3600);
+ QCOMPARE(tran.standardTimeOffset, -5 * 3600);
+ QCOMPARE(tran.daylightTimeOffset, 0);
+ } else {
+ // Do not use QSKIP(): that would discard the rest of this sub-test's caller.
+ qDebug() << "No support for pre-epoch time-zone transitions";
+ }
+}
+#endif // QT_BUILD_INTERNAL
+
+#if __cpp_lib_chrono >= 201907L
+Q_DECLARE_METATYPE(const std::chrono::time_zone *);
+#endif
+
+void tst_QTimeZone::stdCompatibility_data()
+{
+#if __cpp_lib_chrono >= 201907L
+ QTest::addColumn<const std::chrono::time_zone *>("timeZone");
+ const std::chrono::tzdb &tzdb = std::chrono::get_tzdb();
+ qDebug() << "Using tzdb version:" << QByteArrayView(tzdb.version);
+
+ for (const std::chrono::time_zone &zone : tzdb.zones)
+ QTest::addRow(zone.name().data()) << &zone;
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+
+void tst_QTimeZone::stdCompatibility()
+{
+#if __cpp_lib_chrono >= 201907L
+ QFETCH(const std::chrono::time_zone *, timeZone);
+ QByteArrayView zoneName = QByteArrayView(timeZone->name());
+ QTimeZone tz = QTimeZone::fromStdTimeZonePtr(timeZone);
+ if (tz.isValid()) {
+ QCOMPARE(tz.id(), zoneName);
+ } else {
+ // QTBUG-102187: a few timezones reported by tzdb might not be
+ // recognized by QTimeZone. This happens for instance on Windows, where
+ // tzdb is using ICU, whose database does not match QTimeZone's.
+ const bool isKnownUnknown =
+ !zoneName.contains('/')
+ || zoneName == "Antarctica/Troll"
+ || zoneName.startsWith("SystemV/");
+ QVERIFY(isKnownUnknown);
+ }
+#else
+ QSKIP("This test requires C++20's <chrono>.");
+#endif
+}
+#endif // timezone backends
+
+QTEST_APPLESS_MAIN(tst_QTimeZone)
+#include "tst_qtimezone.moc"
diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm b/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm
new file mode 100644
index 0000000000..f4ef15036d
--- /dev/null
+++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm
@@ -0,0 +1,43 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/QTimeZone>
+#include <QTest>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Foundation/Foundation.h>
+
+void tst_QTimeZone_darwinTypes()
+{
+#if QT_CONFIG(timezone)
+ // QTimeZone <-> CFTimeZone
+ {
+ QTimeZone qtTimeZone("America/Los_Angeles");
+ const CFTimeZoneRef cfTimeZone = qtTimeZone.toCFTimeZone();
+ QCOMPARE(QTimeZone::fromCFTimeZone(cfTimeZone), qtTimeZone);
+ CFRelease(cfTimeZone);
+ }
+ {
+ CFTimeZoneRef cfTimeZone = CFTimeZoneCreateWithName(kCFAllocatorDefault,
+ CFSTR("America/Los_Angeles"), false);
+ const QTimeZone qtTimeZone = QTimeZone::fromCFTimeZone(cfTimeZone);
+ QVERIFY(CFEqual(qtTimeZone.toCFTimeZone(), cfTimeZone));
+ CFRelease(cfTimeZone);
+ }
+ // QTimeZone <-> NSTimeZone
+ {
+ NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QTimeZone qtTimeZone("America/Los_Angeles");
+ const NSTimeZone *nsTimeZone = qtTimeZone.toNSTimeZone();
+ QCOMPARE(QTimeZone::fromNSTimeZone(nsTimeZone), qtTimeZone);
+ [autoreleasepool release];
+ }
+ {
+ NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ NSTimeZone *nsTimeZone = [NSTimeZone timeZoneWithName:@"America/Los_Angeles"];
+ const QTimeZone qtTimeZone = QTimeZone::fromNSTimeZone(nsTimeZone);
+ QVERIFY([qtTimeZone.toNSTimeZone() isEqual:nsTimeZone]);
+ [autoreleasepool release];
+ }
+#endif // feature timezone
+}
diff --git a/tests/auto/corelib/tools/CMakeLists.txt b/tests/auto/corelib/tools/CMakeLists.txt
new file mode 100644
index 0000000000..5cca2e2df6
--- /dev/null
+++ b/tests/auto/corelib/tools/CMakeLists.txt
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_subdirectory(qatomicscopedvaluerollback)
+if(NOT INTEGRITY)
+ add_subdirectory(collections)
+endif()
+add_subdirectory(containerapisymmetry)
+add_subdirectory(qalgorithms)
+add_subdirectory(qarraydata)
+add_subdirectory(qbitarray)
+add_subdirectory(qcache)
+add_subdirectory(qcommandlineparser)
+add_subdirectory(qcontiguouscache)
+add_subdirectory(qcryptographichash)
+add_subdirectory(qduplicatetracker)
+add_subdirectory(qeasingcurve)
+add_subdirectory(qexplicitlyshareddatapointer)
+add_subdirectory(qflatmap)
+if(QT_FEATURE_private_tests)
+ add_subdirectory(qfreelist)
+endif()
+add_subdirectory(qhash)
+add_subdirectory(qhashfunctions)
+add_subdirectory(qhashseed)
+add_subdirectory(qline)
+add_subdirectory(qlist)
+add_subdirectory(qmakearray)
+add_subdirectory(qmap)
+add_subdirectory(qmargins)
+add_subdirectory(qmessageauthenticationcode)
+if(NOT INTEGRITY)
+ add_subdirectory(qoffsetstringarray)
+endif()
+add_subdirectory(qpair)
+add_subdirectory(qpoint)
+add_subdirectory(qpointf)
+add_subdirectory(qqueue)
+add_subdirectory(qrect)
+add_subdirectory(qringbuffer)
+add_subdirectory(qscopedpointer)
+add_subdirectory(qscopedvaluerollback)
+add_subdirectory(qscopeguard)
+add_subdirectory(qtaggedpointer)
+add_subdirectory(qtyperevision)
+add_subdirectory(qset)
+add_subdirectory(qsharedpointer)
+add_subdirectory(qsize)
+add_subdirectory(qsizef)
+add_subdirectory(qspan)
+add_subdirectory(qstl)
+add_subdirectory(quniquehandle)
+add_subdirectory(qvarlengtharray)
+add_subdirectory(qversionnumber)
+add_subdirectory(qtimeline)
+if(APPLE)
+ add_subdirectory(qmacautoreleasepool)
+endif()
diff --git a/tests/auto/corelib/tools/collections/CMakeLists.txt b/tests/auto/corelib/tools/collections/CMakeLists.txt
new file mode 100644
index 0000000000..687d88b2e4
--- /dev/null
+++ b/tests/auto/corelib/tools/collections/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_collections Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_collections LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_collections
+ SOURCES
+ tst_collections.cpp
+)
+
+qt_internal_undefine_global_definition(tst_collections QT_NO_JAVA_STYLE_ITERATORS)
diff --git a/tests/auto/corelib/tools/collections/collections.pro b/tests/auto/corelib/tools/collections/collections.pro
deleted file mode 100644
index 5c04515fa0..0000000000
--- a/tests/auto/corelib/tools/collections/collections.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-TARGET = tst_collections
-SOURCES += tst_collections.cpp
-QT = core testlib
-
-# This test does not work with strict iterators
-DEFINES -= QT_STRICT_ITERATORS
diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp
index b40b1f0624..2fab6cae3a 100644
--- a/tests/auto/corelib/tools/collections/tst_collections.cpp
+++ b/tests/auto/corelib/tools/collections/tst_collections.cpp
@@ -1,38 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#undef QT_NO_FOREACH // this file tests Q_FOREACH over containers (centralize in a tst_qforeach?)
// test the container forwards
#include <QtContainerFwd>
static QCache<int, int> *cacheX;
static QHash<int, int> *hashX;
-static QLinkedList<int> *linkedListX;
static QList<int> *listX;
static QMap<int, int> *mapX;
static QMultiHash<int, int> *multiHashX;
@@ -43,13 +18,12 @@ static QSet<int> *setX;
static QStack<int> *stackX;
static QVarLengthArray<int> *varLengthArrayX;
static QVarLengthArray<int, 512> *varLengthArrayY;
-static QVector<int> *vectorX;
+static QList<int> *vectorX;
void foo()
{
cacheX = 0;
hashX = 0;
- linkedListX = 0;
listX = 0;
mapX = 0;
multiHashX = 0;
@@ -63,32 +37,29 @@ void foo()
vectorX = 0;
}
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QVector>
+#include <QScopedPointer>
+#include <QThread>
+#include <QSemaphore>
#include <algorithm>
-#include "qalgorithms.h"
#include "qbitarray.h"
#include "qbytearray.h"
#include "qcache.h"
#include "qhash.h"
-#include "qlinkedlist.h"
#include "qlist.h"
#include "qmap.h"
#include "qpair.h"
-#include "qregexp.h"
+#include "qregularexpression.h"
#include "qset.h"
#include "qstack.h"
#include "qstring.h"
#include "qstringlist.h"
#include "qvarlengtharray.h"
-#include "qvector.h"
#include "qqueue.h"
-QT_BEGIN_NAMESPACE
-template class QList<int>;
-QT_END_NAMESPACE
-
class tst_Collections : public QObject
{
Q_OBJECT
@@ -97,7 +68,6 @@ private slots:
void typeinfo();
void qstring();
void list();
- void linkedList();
void vector();
void byteArray();
void stack();
@@ -105,10 +75,11 @@ private slots:
void map();
void bitArray();
void cache();
+#if QT_CONFIG(regularexpression)
void regexp();
+#endif
void pair();
void sharableQList();
- void sharableQLinkedList();
void sharableQVector();
void sharableQMap();
void sharableQHash();
@@ -120,8 +91,6 @@ private slots:
void vector_stl();
void list_stl_data();
void list_stl();
- void linkedlist_stl_data();
- void linkedlist_stl();
void q_init();
void pointersize();
void containerInstantiation();
@@ -133,12 +102,27 @@ private slots:
void foreach_2();
void insert_remove_loop();
+
+ void detachAssociativeContainerQMap() { detachAssociativeContainerImpl<QMap>(); }
+ void detachAssociativeContainerQMultiMap() { detachAssociativeContainerImpl<QMultiMap>(); }
+ void detachAssociativeContainerQHash() { detachAssociativeContainerImpl<QHash>(); }
+ void detachAssociativeContainerQMultiHash() { detachAssociativeContainerImpl<QMultiHash>(); }
+
+private:
+ template <template<typename, typename> typename Container>
+ void detachAssociativeContainerImpl();
};
struct LargeStatic {
static int count;
LargeStatic():c(count) { ++count; }
LargeStatic(const LargeStatic& o):c(o.c) { ++count; }
+ LargeStatic &operator=(const LargeStatic &o)
+ {
+ c = o.c;
+ ++count;
+ return *this;
+ };
~LargeStatic() { --count; }
int c;
int data[8];
@@ -156,7 +140,7 @@ struct Movable {
int Movable::count = 0;
QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(Movable, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
@@ -164,10 +148,155 @@ struct Pod {
int i1, i2;
};
+// Compile-time checks for recursive containers
+struct Dummy
+{
+ bool operator==(const Dummy &) const { return false; }
+ bool operator<(const Dummy &) const { return false; }
+};
+
+struct RecursiveList : public QList<RecursiveList> {};
+struct RecursiveSet : public QSet<RecursiveSet> {};
+struct RecursiveMapV : public QMap<Dummy, RecursiveMapV> {};
+struct RecursiveMapK : public QMap<RecursiveMapK, Dummy> {};
+struct RecursiveMultiMapV : public QMultiMap<Dummy, RecursiveMultiMapV> {};
+struct RecursiveMultiMapK : public QMultiMap<RecursiveMultiMapK, Dummy> {};
+struct RecursiveHashV : public QHash<Dummy, RecursiveHashV> {};
+struct RecursiveHashK : public QHash<RecursiveHashK, Dummy> {};
+struct RecursiveMultiHashV : public QMultiHash<Dummy, RecursiveMultiHashV> {};
+struct RecursiveMultiHashK : public QMultiHash<RecursiveMultiHashK, Dummy> {};
+
+struct Empty {};
+struct NoCmpParamRecursiveMapV : public QMap<Empty, NoCmpParamRecursiveMapV> {};
+struct NoCmpParamRecursiveMapK : public QMap<NoCmpParamRecursiveMapK, Empty> {};
+struct NoCmpParamRecursiveMultiMapV : public QMultiMap<Empty, NoCmpParamRecursiveMultiMapV> {};
+struct NoCmpParamRecursiveMultiMapK : public QMultiMap<NoCmpParamRecursiveMultiMapK, Empty> {};
+struct NoCmpParamRecursiveHashV : public QHash<Empty, NoCmpParamRecursiveHashV> {};
+struct NoCmpParamRecursiveHashK : public QHash<NoCmpParamRecursiveHashK, Empty> {};
+struct NoCmpParamRecursiveMultiHashV : public QMultiHash<Empty, NoCmpParamRecursiveMultiHashV> {};
+struct NoCmpParamRecursiveMultiHashK : public QMultiHash<NoCmpParamRecursiveMultiHashK, Empty> {};
+
+struct NoCmpRecursiveList : public QList<NoCmpRecursiveList>
+{
+ bool operator==(const RecursiveList &) const = delete;
+ bool operator<(const RecursiveList &) const = delete;
+};
+struct NoCmpRecursiveSet : public QSet<NoCmpRecursiveSet>
+{
+ bool operator==(const NoCmpRecursiveSet &) const = delete;
+};
+struct NoCmpRecursiveMapV : public QMap<Dummy, NoCmpRecursiveMapV>
+{
+ bool operator==(const NoCmpRecursiveMapV &) const = delete;
+};
+struct NoCmpRecursiveMapK : public QMap<NoCmpRecursiveMapK, Dummy>
+{
+ bool operator==(const NoCmpRecursiveMapK &) const = delete;
+};
+struct NoCmpRecursiveMultiMapV : public QMultiMap<Dummy, NoCmpRecursiveMultiMapV>
+{
+ bool operator==(const NoCmpRecursiveMultiMapV &) const = delete;
+};
+struct NoCmpRecursiveMultiMapK : public QMultiMap<NoCmpRecursiveMultiMapK, Dummy>
+{
+ bool operator==(const NoCmpRecursiveMultiMapK &) const = delete;
+};
+struct NoCmpRecursiveHashV : public QHash<Dummy, NoCmpRecursiveHashV>
+{
+ bool operator==(const NoCmpRecursiveHashV &) const = delete;
+};
+struct NoCmpRecursiveHashK : public QHash<NoCmpRecursiveHashK, Dummy>
+{
+ bool operator==(const NoCmpRecursiveHashK &) const = delete;
+};
+struct NoCmpRecursiveMultiHashV : public QMultiHash<Dummy, NoCmpRecursiveMultiHashV>
+{
+ bool operator==(const NoCmpRecursiveMultiHashV &) const = delete;
+};
+struct NoCmpRecursiveMultiHashK : public QMultiHash<NoCmpRecursiveMultiHashK, Dummy>
+{
+ bool operator==(const NoCmpRecursiveMultiHashK &) const = delete;
+};
+
+uint qHash(const Dummy &) { return 0; }
+uint qHash(const RecursiveSet &) { return 0; }
+uint qHash(const RecursiveHashK &) { return 0; }
+uint qHash(const RecursiveHashV &) { return 0; }
+uint qHash(const RecursiveMultiHashK &) { return 0; }
+uint qHash(const RecursiveMultiHashV &) { return 0; }
+
+Q_DECLARE_METATYPE(RecursiveList);
+Q_DECLARE_METATYPE(RecursiveSet);
+Q_DECLARE_METATYPE(RecursiveMapV);
+Q_DECLARE_METATYPE(RecursiveMapK);
+Q_DECLARE_METATYPE(RecursiveMultiMapV);
+Q_DECLARE_METATYPE(RecursiveMultiMapK);
+Q_DECLARE_METATYPE(RecursiveHashV);
+Q_DECLARE_METATYPE(RecursiveHashK);
+Q_DECLARE_METATYPE(RecursiveMultiHashV);
+Q_DECLARE_METATYPE(RecursiveMultiHashK);
+
+Q_DECLARE_METATYPE(NoCmpParamRecursiveMapV);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveMapK);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiMapV);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiMapK);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveHashK);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveHashV);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashK);
+Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashV);
+
+Q_DECLARE_METATYPE(NoCmpRecursiveList);
+Q_DECLARE_METATYPE(NoCmpRecursiveMapV);
+Q_DECLARE_METATYPE(NoCmpRecursiveMapK);
+Q_DECLARE_METATYPE(NoCmpRecursiveMultiMapV);
+Q_DECLARE_METATYPE(NoCmpRecursiveMultiMapK);
+Q_DECLARE_METATYPE(NoCmpRecursiveHashV);
+Q_DECLARE_METATYPE(NoCmpRecursiveHashK);
+Q_DECLARE_METATYPE(NoCmpRecursiveMultiHashV);
+Q_DECLARE_METATYPE(NoCmpRecursiveMultiHashK);
+
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveList>);
+static_assert(QTypeTraits::has_operator_less_than_v<RecursiveList>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveSet>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveMapV>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveMapK>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiMapV>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiMapK>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveHashV>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveHashK>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiHashV>);
+static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiHashK>);
+
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMapV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMapK>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiMapV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiMapK>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashK>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashK>);
+
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveList>);
+static_assert(!QTypeTraits::has_operator_less_than_v<NoCmpRecursiveList>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveSet>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMapV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMapK>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiMapV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiMapK>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveHashV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveHashK>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiHashV>);
+static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiHashK>);
+
+template <typename T>
+constexpr inline bool has_prepend_v = true;
+template <typename T, qsizetype N>
+constexpr inline bool has_prepend_v<QVarLengthArray<T,N>> = false; // deprecated in Qt 6.3
+
void tst_Collections::typeinfo()
{
- QVERIFY(QTypeInfo<int*>::isPointer);
- QVERIFY(!QTypeInfo<int>::isPointer);
+ QVERIFY(std::is_pointer_v<int*>);
+ QVERIFY(!std::is_pointer_v<int>);
QVERIFY(QTypeInfo<QString>::isComplex);
QVERIFY(!QTypeInfo<int>::isComplex);
}
@@ -189,16 +318,6 @@ void tst_Collections::list()
QVERIFY(list.size() == 6);
QVERIFY(list.end() - list.begin() == list.size());
-#if !defined(Q_CC_MSVC) && !defined(Q_CC_SUN)
- QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true);
- QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false);
-#endif
- QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1);
- QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1);
- QVERIFY(qUpperBound(list.begin(), list.end(), 2) == list.begin() + 2);
- QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end());
- QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end());
- QVERIFY(qUpperBound(list.begin(), list.end(), 9) == list.end());
{
int sum = 0;
QListIterator<int> i(list);
@@ -411,7 +530,7 @@ void tst_Collections::list()
list << "one" << "two" << "one" << "two";
QVERIFY(!list.removeOne("three"));
QVERIFY(list.removeOne("two"));
- QCOMPARE(list, QList<QString>() << "one" << "one" << "two");;
+ QCOMPARE(list, QList<QString>() << "one" << "one" << "two");
QVERIFY(list.removeOne("two"));
QCOMPARE(list, QList<QString>() << "one" << "one");
QVERIFY(!list.removeOne("two"));
@@ -470,7 +589,10 @@ void tst_Collections::list()
{
QList<int> list;
list.append(1);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
list = list;
+QT_WARNING_POP
QVERIFY(list.size() == 1);
}
}
@@ -484,7 +606,7 @@ void tst_Collections::list()
}
{
- QVector<QString> vector(5);
+ QList<QString> vector(5);
vector[0] = "99";
vector[4] ="100";
QList<QString> list = vector.toList();
@@ -560,19 +682,12 @@ void tst_Collections::list()
list << "foo" << "bar";
QVERIFY(!list.isEmpty());
- list.insert(-1, "lessthanzero");
- QCOMPARE(list.at(0), QString("lessthanzero"));
-
list.insert(0, "atzero");
QCOMPARE(list.at(0), QString("atzero"));
- int listCount = list.count();
+ int listCount = list.size();
list.insert(listCount, "atcount");
QCOMPARE(list.at(listCount), QString("atcount"));
-
- listCount = list.count();
- list.insert(listCount + 1, "beyondcount");
- QCOMPARE(list.at(listCount), QString("beyondcount"));
}
{
@@ -580,73 +695,73 @@ void tst_Collections::list()
list1 << 0 << 1 << 2 << 3;
list1.removeFirst();
- list1.swap(0, 0);
+ list1.swapItemsAt(0, 0);
QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
- list1.swap(1, 1);
+ list1.swapItemsAt(1, 1);
QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
- list1.swap(2, 2);
+ list1.swapItemsAt(2, 2);
QVERIFY(list1 == QList<int>() << 1 << 2 << 3);
- list1.swap(0, 1);
+ list1.swapItemsAt(0, 1);
QVERIFY(list1 == QList<int>() << 2 << 1 << 3);
- list1.swap(0, 2);
+ list1.swapItemsAt(0, 2);
QVERIFY(list1 == QList<int>() << 3 << 1 << 2);
- list1.swap(1, 2);
+ list1.swapItemsAt(1, 2);
QVERIFY(list1 == QList<int>() << 3 << 2 << 1);
- list1.swap(1, 2);
+ list1.swapItemsAt(1, 2);
QVERIFY(list1 == QList<int>() << 3 << 1 << 2);
QList<QString> list2;
list2 << "1" << "2" << "3";
- list2.swap(0, 0);
+ list2.swapItemsAt(0, 0);
QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
- list2.swap(1, 1);
+ list2.swapItemsAt(1, 1);
QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
- list2.swap(2, 2);
+ list2.swapItemsAt(2, 2);
QVERIFY(list2 == QList<QString>() << "1" << "2" << "3");
- list2.swap(0, 1);
+ list2.swapItemsAt(0, 1);
QVERIFY(list2 == QList<QString>() << "2" << "1" << "3");
- list2.swap(0, 2);
+ list2.swapItemsAt(0, 2);
QVERIFY(list2 == QList<QString>() << "3" << "1" << "2");
- list2.swap(1, 2);
+ list2.swapItemsAt(1, 2);
QVERIFY(list2 == QList<QString>() << "3" << "2" << "1");
- list2.swap(1, 2);
+ list2.swapItemsAt(1, 2);
QVERIFY(list2 == QList<QString>() << "3" << "1" << "2");
QList<double> list3;
list3 << 1.0 << 2.0 << 3.0;
- list3.swap(0, 0);
+ list3.swapItemsAt(0, 0);
QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
- list3.swap(1, 1);
+ list3.swapItemsAt(1, 1);
QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
- list3.swap(2, 2);
+ list3.swapItemsAt(2, 2);
QVERIFY(list3 == QList<double>() << 1.0 << 2.0 << 3.0);
- list3.swap(0, 1);
+ list3.swapItemsAt(0, 1);
QVERIFY(list3 == QList<double>() << 2.0 << 1.0 << 3.0);
- list3.swap(0, 2);
+ list3.swapItemsAt(0, 2);
QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0);
- list3.swap(1, 2);
+ list3.swapItemsAt(1, 2);
QVERIFY(list3 == QList<double>() << 3.0 << 2.0 << 1.0);
- list3.swap(1, 2);
+ list3.swapItemsAt(1, 2);
QVERIFY(list3 == QList<double>() << 3.0 << 1.0 << 2.0);
}
@@ -745,231 +860,9 @@ void tst_Collections::list()
}
}
-void tst_Collections::linkedList()
-{
- {
- QLinkedList<int> list;
- QVERIFY(list.isEmpty());
- list.append(1);
- list.push_back(2);
- list += (3);
- list << 4 << 5 << 6;
- QVERIFY(!list.isEmpty());
- QVERIFY(list.size() == 6);
- {
- int sum = 0;
- QLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- sum += i.next();
- }
- QVERIFY(sum == 21);
- }
- {
- int sum = 0;
- QLinkedList<int>::const_iterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 21);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext())
- i.setValue(2*i.next());
- }
- {
- int sum = 0;
- QLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious())
- sum += i.previous();
- QVERIFY(sum == 2*21);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious())
- i.setValue(2*i.previous());
- }
- {
- int sum = 0;
- QLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious())
- sum += i.previous();
- QVERIFY(sum == 2*2*21);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.next();
- i.insert(a);
- }
- }
- {
- int sum = 0;
- QLinkedList<int>::iterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 2*2*2*21);
- }
- {
- int duplicates = 0;
- QLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.next();
- if (i.hasNext() && a == i.peekNext())
- duplicates++;
- }
- QVERIFY(duplicates == 6);
- }
- {
- int duplicates = 0;
- QLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious()) {
- int a = i.previous();
- if (i.hasPrevious() && a == i.peekPrevious())
- duplicates++;
- }
- QVERIFY(duplicates == 6);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.next();
- if (i.hasNext() &&
- i.peekNext() == a)
- i.remove();
- }
- }
- {
- int duplicates = 0;
- QMutableLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious()) {
- int a = i.previous();
- if (i.hasPrevious() && a == i.peekPrevious())
- duplicates++;
- }
- QVERIFY(duplicates == 0);
- }
- {
- QVERIFY(list.size() == 6);
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.peekNext();
- i.insert(42);
- QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
- i.next();
- }
- QVERIFY(list.size() == 12);
- i.toFront();
- while (i.findNext(42))
- i.remove();
- }
- {
- QLinkedList<int> l;
- l << 4 << 8 << 12 << 16 << 20 << 24;
- QVERIFY(l == list);
- QLinkedList<int> copy = list;
- list += list;
- QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
- l += copy;
- QVERIFY(l == list);
- list = copy;
- }
- {
- QLinkedList<int> copy = list;
- list.prepend(999);
- list.append(999);
- QVERIFY(list.contains(999));
- QVERIFY(list.count(999) == 2);
- list.removeAll(999);
- QVERIFY(list == copy);
- }
- {
- QLinkedList<QString> list;
- list << "one" << "two" << "three" << "four" << "five" << "six";
- while (!list.isEmpty())
- list.removeAll(list.first());
- }
- {
- QLinkedList<QString> list;
- list << "one" << "two" << "one" << "two";
- QVERIFY(!list.removeOne("three"));
- QVERIFY(list.removeOne("two"));
- QCOMPARE(list, QLinkedList<QString>() << "one" << "one" << "two");;
- QVERIFY(list.removeOne("two"));
- QCOMPARE(list, QLinkedList<QString>() << "one" << "one");
- QVERIFY(!list.removeOne("two"));
- QCOMPARE(list, QLinkedList<QString>() << "one" << "one");
- QVERIFY(list.removeOne("one"));
- QCOMPARE(list, QLinkedList<QString>() << "one");
- QVERIFY(list.removeOne("one"));
- QVERIFY(list.isEmpty());
- QVERIFY(!list.removeOne("one"));
- QVERIFY(list.isEmpty());
- }
- {
- list.clear();
- QVERIFY(list.isEmpty());
- QVERIFY(list.begin() == list.end());
- QLinkedListIterator<int> i(list);
- QVERIFY(!i.hasNext() && !i.hasPrevious());
- }
- }
-
- {
- QLinkedList<QString> list;
- list.append("Hello");
-
- QLinkedList<QString>::iterator it = list.begin();
- QVERIFY((*it)[0] == QChar('H'));
- QVERIFY(it->constData()[0] == QChar('H'));
- it->replace(QChar('H'), QChar('X'));
- QCOMPARE(list.first(), QLatin1String("Xello"));
-
- QLinkedList<QString>::const_iterator cit = list.constBegin();
- QCOMPARE((*cit).toLower(), QLatin1String("xello"));
- QCOMPARE(cit->toUpper(), QLatin1String("XELLO"));
-
- cit = list.cbegin();
- QCOMPARE((*cit).toLower(), QLatin1String("xello"));
- QCOMPARE(cit->toUpper(), QLatin1String("XELLO"));
- }
-
- {
- QLinkedList<QString> list;
- list << "alpha" << "beta";
- list += list;
- QVERIFY(list.size() == 4);
- QCOMPARE(*list.begin(), QLatin1String("alpha"));
- QCOMPARE(*(list.begin() + 1), QLatin1String("beta"));
- QCOMPARE(*(list.begin() + 2), QLatin1String("alpha"));
- QCOMPARE(*(list.begin() + 3), QLatin1String("beta"));
- }
-
- {
- QLinkedList<int> a;
- QCOMPARE(a.startsWith(1), false);
- QCOMPARE(a.endsWith(1), false);
- a.append(1);
- QCOMPARE(a.startsWith(1), true);
- QCOMPARE(a.startsWith(2), false);
- QCOMPARE(a.endsWith(1), true);
- QCOMPARE(a.endsWith(2), false);
- a.append(2);
- QCOMPARE(a.startsWith(1), true);
- QCOMPARE(a.startsWith(2), false);
- QCOMPARE(a.endsWith(1), false);
- QCOMPARE(a.endsWith(2), true);
- }
-};
-
-
void tst_Collections::vector()
{
- QVector<int> v1;
+ QList<int> v1;
v1 << 1 << 2 << 3;
QVector<int> v2;
v2 << 4 << 5;
@@ -994,16 +887,8 @@ void tst_Collections::vector()
v.append(2);
QVERIFY(*v.begin() == 2);
v.prepend(1);
-
- v << 3 << 4 << 5 << 6;
- QVERIFY(std::binary_search(v.begin(), v.end(), 2) == true);
- QVERIFY(std::binary_search(v.begin(), v.end(), 9) == false);
- QVERIFY(qBinaryFind(v.begin(), v.end(), 2) == v.begin() + 1);
- QVERIFY(qLowerBound(v.begin(), v.end(), 2) == v.begin() + 1);
- QVERIFY(qUpperBound(v.begin(), v.end(), 2) == v.begin() + 2);
- QVERIFY(qBinaryFind(v.begin(), v.end(), 9) == v.end());
- QVERIFY(qLowerBound(v.begin(), v.end(), 9) == v.end());
- QVERIFY(qUpperBound(v.begin(), v.end(), 9) == v.end());
+ QVERIFY(*v.begin() == 1);
+ QVERIFY(*(v.begin() + 1) == 2);
v.clear();
v << 1 << 2 << 3;
@@ -1061,7 +946,7 @@ void tst_Collections::vector()
QVERIFY(LargeStatic::count == originalLargeStaticCount);
{
QVector<LargeStatic> vector;
- LargeStatic *dummy = 0;
+ LargeStatic *dummy = nullptr;
for (int i = 0; i < 10000; ++i) {
delete dummy;
dummy = new LargeStatic;
@@ -1083,7 +968,7 @@ void tst_Collections::vector()
QVERIFY(Movable::count == originalMovableCount);
{
QVector<Movable> vector;
- Movable *dummy = 0;
+ Movable *dummy = nullptr;
for (int i = 0; i < 10000; ++i) {
delete dummy;
dummy = new Movable;
@@ -1226,6 +1111,16 @@ void tst_Collections::byteArray()
QVERIFY(hello.indexOf('l',2) == 2);
QVERIFY(hello.indexOf('l',3) == 3);
+ QByteArray empty;
+ QCOMPARE(empty.indexOf("x"), -1);
+ QCOMPARE(empty.lastIndexOf("x"), -1);
+ QCOMPARE(empty.lastIndexOf("x", 0), -1);
+ QCOMPARE(empty.count("x"), 0);
+ QCOMPARE(empty.indexOf(""), 0);
+ QCOMPARE(empty.lastIndexOf(""), 0);
+ QCOMPARE(empty.lastIndexOf("", -1), -1);
+ QCOMPARE(empty.count(""), 1);
+
QByteArray large = "000 100 200 300 400 500 600 700 800 900";
QVERIFY(large.indexOf("700") == 28);
@@ -1341,7 +1236,7 @@ void tst_Collections::stack()
stack.push(1);
stack.push(2);
stack.push(3);
- QVectorIterator<int> i = stack;
+ QListIterator<int> i = stack;
i.toBack();
int sum = 0;
while (i.hasPrevious())
@@ -1368,19 +1263,19 @@ void tst_Collections::hash()
{
typedef QHash<QString, QString> Hash;
Hash hash;
- QString key;
+ QString key = QLatin1String(" ");
for (int i = 0; i < 10; ++i) {
- key[0] = i + '0';
+ key[0] = QChar(i + '0');
for (int j = 0; j < 10; ++j) {
- key[1] = j + '0';
+ key[1] = QChar(j + '0');
hash.insert(key, "V" + key);
}
}
for (int i = 0; i < 10; ++i) {
- key[0] = i + '0';
+ key[0] = QChar(i + '0');
for (int j = 0; j < 10; ++j) {
- key[1] = j + '0';
+ key[1] = QChar(j + '0');
hash.remove(key);
}
}
@@ -1395,6 +1290,8 @@ void tst_Collections::hash()
QVERIFY(hash.size() == 2);
QVERIFY(!hash.isEmpty());
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
{
Hash hash2 = hash;
hash2 = hash;
@@ -1407,6 +1304,7 @@ void tst_Collections::hash()
QVERIFY(hash2.isEmpty());
}
QVERIFY(hash.size() == 2);
+QT_WARNING_POP
{
Hash hash2 = hash;
@@ -1543,19 +1441,13 @@ void tst_Collections::hash()
QHash<int, int> hash;
for (int i = 0; i < 1000; ++i)
hash.insert(i, i);
- QVERIFY(hash.capacity() == 1031);
- hash.squeeze();
- QVERIFY(hash.capacity() == 521);
-
- hash.insert(12345, 12345);
- QVERIFY(hash.capacity() == 1031);
+ QVERIFY(hash.capacity() > 1000);
for (int j = 0; j < 900; ++j)
hash.remove(j);
- QVERIFY(hash.capacity() == 257);
+ QVERIFY(hash.capacity() > 1000);
hash.squeeze();
- QVERIFY(hash.capacity() == 67);
- hash.reserve(0);
+ QVERIFY(hash.capacity() < 200);
}
}
@@ -1579,22 +1471,30 @@ void tst_Collections::hash()
}
{
- QHash<int, QString> hash1, hash2;
- hash1.insertMulti(1, "Alpha");
- hash1.insertMulti(1, "Gamma");
- hash2.insertMulti(1, "Beta");
- hash2.insertMulti(1, "Gamma");
- hash2.insertMulti(1, "Gamma");
+ QMultiHash<int, QString> hash1, hash2;
+ hash1.insert(1, "Alpha");
+ hash1.insert(1, "Gamma");
+ hash2.insert(1, "Beta");
+ hash2.insert(1, "Gamma");
+ hash2.insert(1, "Gamma");
hash1.unite(hash2);
QCOMPARE(hash1.size(), 5);
- QCOMPARE(hash1.values(),
- (QList<QString>() << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha"));
+ auto values = hash1.values();
+ std::sort(values.begin(), values.end());
+ QList<QString> expected;
+ expected << "Gamma" << "Gamma" << "Beta" << "Gamma" << "Alpha";
+ std::sort(expected.begin(), expected.end());
+ QCOMPARE(values, expected);
hash2 = hash1;
hash2.unite(hash2);
QCOMPARE(hash2.size(), 10);
- QCOMPARE(hash2.values(), hash1.values() + hash1.values());
+ values = hash2.values();
+ std::sort(values.begin(), values.end());
+ expected += expected;
+ std::sort(expected.begin(), expected.end());
+ QCOMPARE(values, expected);
}
}
@@ -1616,6 +1516,8 @@ void tst_Collections::map()
QVERIFY(map.size() == 2);
QVERIFY(!map.isEmpty());
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
{
Map map2 = map;
map2 = map;
@@ -1628,6 +1530,7 @@ void tst_Collections::map()
QVERIFY(map2.isEmpty());
}
QVERIFY(map.size() == 2);
+QT_WARNING_POP
{
Map map2 = map;
@@ -1900,12 +1803,12 @@ void tst_Collections::map()
}
{
- QMap<int, QString> map1, map2;
- map1.insertMulti(1, "Alpha");
- map1.insertMulti(1, "Gamma");
- map2.insertMulti(1, "Beta");
- map2.insertMulti(1, "Gamma");
- map2.insertMulti(1, "Gamma");
+ QMultiMap<int, QString> map1, map2;
+ map1.insert(1, "Alpha");
+ map1.insert(1, "Gamma");
+ map2.insert(1, "Beta");
+ map2.insert(1, "Gamma");
+ map2.insert(1, "Gamma");
map1.unite(map2);
QCOMPARE(map1.size(), 5);
@@ -1950,11 +1853,21 @@ void tst_Collections::qstring()
QVERIFY (hello.contains('e') != false);
QVERIFY(hello.indexOf('e') == 1);
- QVERIFY(hello.indexOf('e', -10) == 1);
+ QVERIFY(hello.indexOf('e', -10) == -1);
QVERIFY(hello.indexOf('l') == 2);
QVERIFY(hello.indexOf('l',2) == 2);
QVERIFY(hello.indexOf('l',3) == 3);
+ QString empty;
+ QCOMPARE(empty.indexOf("x"), -1);
+ QCOMPARE(empty.lastIndexOf("x"), -1);
+ QCOMPARE(empty.lastIndexOf("x", 0), -1);
+ QCOMPARE(empty.count("x"), 0);
+ QCOMPARE(empty.indexOf(""), 0);
+ QCOMPARE(empty.lastIndexOf(""), 0);
+ QCOMPARE(empty.lastIndexOf("", -1), -1);
+ QCOMPARE(empty.count(""), 1);
+
QString large = "000 100 200 300 400 500 600 700 800 900";
QVERIFY(large.indexOf("700") == 28);
@@ -1964,6 +1877,20 @@ void tst_Collections::qstring()
QVERIFY(large.lastIndexOf("700", 28) == 28);
QVERIFY(large.lastIndexOf("700", 27) == -1);
+ QCOMPARE(large.indexOf(""), 0);
+ QCOMPARE(large.indexOf(QString()), 0);
+ QCOMPARE(large.indexOf(QLatin1String()), 0);
+ QCOMPARE(large.indexOf(QStringView()), 0);
+ QCOMPARE(large.lastIndexOf(""), large.size());
+ QCOMPARE(large.lastIndexOf("", -1), large.size() - 1);
+ QCOMPARE(large.lastIndexOf(QString()), large.size());
+ QCOMPARE(large.lastIndexOf(QLatin1String()), large.size());
+ QCOMPARE(large.lastIndexOf(QStringView()), large.size());
+ QCOMPARE(large.count(""), large.size() + 1);
+ QCOMPARE(large.count(QString()), large.size() + 1);
+ QCOMPARE(large.count(QLatin1String()), large.size() + 1);
+ QCOMPARE(large.count(QStringView()), large.size() + 1);
+
QVERIFY(large.contains("200"));
QVERIFY(!large.contains("201"));
QVERIFY(large.contains('3'));
@@ -2011,13 +1938,8 @@ void tst_Collections::qstring()
QString nonNull = "";
QVERIFY(null.left(10).isNull());
QVERIFY(null.mid(0).isNull());
-
- QVERIFY(null == QString::null);
- QVERIFY(QString::null == null);
- QVERIFY(nonNull != QString::null);
- QVERIFY(QString::null != nonNull);
- QVERIFY(null == nonNull);
- QVERIFY(QString::null == QString::null);
+ QVERIFY(null.isNull());
+ QVERIFY(!nonNull.isNull());
QString fill = "123";
fill.fill('a');
@@ -2097,8 +2019,8 @@ void tst_Collections::qstring()
s = "ascii";
s += QChar((uchar) 0xb0);
QVERIFY(s.toUtf8() != s.toLatin1());
- QCOMPARE(s[s.length()-1].unicode(), (ushort)0xb0);
- QCOMPARE(s.left(s.length()-1), QLatin1String("ascii"));
+ QCOMPARE(s[s.size()-1].unicode(), char16_t(0xb0));
+ QCOMPARE(s.left(s.size()-1), QLatin1String("ascii"));
QVERIFY(s == QString::fromUtf8(s.toUtf8().constData()));
@@ -2150,7 +2072,7 @@ void tst_Collections::qstring()
QString str = "Hello";
- QString cstr = QString::fromRawData(str.unicode(), str.length());
+ QString cstr = QString::fromRawData(str.unicode(), str.size());
QCOMPARE(str, QLatin1String("Hello"));
QCOMPARE(cstr, QLatin1String("Hello"));
cstr.clear();
@@ -2285,13 +2207,15 @@ void tst_Collections::cache()
}
+#if QT_CONFIG(regularexpression)
void tst_Collections::regexp()
{
- QRegExp rx("^\\d\\d?$");
- QVERIFY(rx.indexIn("123") == -1);
- QVERIFY(rx.indexIn("-6") == -1);
- QVERIFY(rx.indexIn("6") == 0) ;
+ QRegularExpression rx("^\\d\\d?$");
+ QVERIFY(!rx.match("123").hasMatch());
+ QVERIFY(!rx.match("-6").hasMatch());
+ QVERIFY(rx.match("6").hasMatch()) ;
}
+#endif
void tst_Collections::pair()
{
@@ -2342,18 +2266,6 @@ void populate(QList<int> &container)
}
template <>
-void populate(QLinkedList<int> &container)
-{
- container << 1 << 2 << 4 << 8;
-}
-
-template <>
-void populate(QVector<int> &container)
-{
- container << 1 << 2 << 4 << 8;
-}
-
-template <>
void populate(QMap<int, int> &container)
{
container.insert(1, 1);
@@ -2425,7 +2337,7 @@ void testContainer()
c1 = newInstance<Container>();
QVERIFY(c1.size() == 4);
QVERIFY(c1 == newInstance<Container>());
- Container c2 = qMove(c1);
+ Container c2 = std::move(c1);
QVERIFY(c2.size() == 4);
QVERIFY(c2 == newInstance<Container>());
}
@@ -2442,11 +2354,6 @@ void tst_Collections::sharableQList()
TEST_SEQUENTIAL_CONTAINER(List);
}
-void tst_Collections::sharableQLinkedList()
-{
- TEST_SEQUENTIAL_CONTAINER(LinkedList);
-}
-
void tst_Collections::sharableQVector()
{
TEST_SEQUENTIAL_CONTAINER(Vector);
@@ -2531,14 +2438,18 @@ void tst_Collections::conversions()
QCOMPARE(list2.size(), 4);
QVERIFY(list2 == (QList<QString>() << STUFF));
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
QSet<QString> set1 = list1.toSet();
+#else
+ QSet<QString> set1(list1.begin(), list1.end());
+#endif
QCOMPARE(set1.size(), 3);
QVERIFY(set1.contains("A"));
QVERIFY(set1.contains("B"));
QVERIFY(set1.contains("C"));
QVERIFY(!set1.contains("D"));
- QList<QString> list3 = set1.toList();
+ QList<QString> list3 = set1.values();
QCOMPARE(list3.size(), 3);
QVERIFY(list3.contains("A"));
QVERIFY(list3.contains("B"));
@@ -2546,9 +2457,11 @@ void tst_Collections::conversions()
QVERIFY(!list3.contains("D"));
QVERIFY(QList<int>().toVector().isEmpty());
- QVERIFY(QList<int>().toSet().isEmpty());
QVERIFY(QVector<int>().toList().isEmpty());
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QVERIFY(QList<int>().toSet().isEmpty());
QVERIFY(QSet<int>().toList().isEmpty());
+#endif
}
{
@@ -2563,14 +2476,22 @@ void tst_Collections::conversions()
QCOMPARE(list2.size(), 4);
QVERIFY(list2 == (QList<QString>() << STUFF));
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
QSet<QString> set1 = QSet<QString>::fromList(list1);
+#else
+ QSet<QString> set1(list1.begin(), list1.end());
+#endif
QCOMPARE(set1.size(), 3);
QVERIFY(set1.contains("A"));
QVERIFY(set1.contains("B"));
QVERIFY(set1.contains("C"));
QVERIFY(!set1.contains("D"));
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
QList<QString> list3 = QList<QString>::fromSet(set1);
+#else
+ QList<QString> list3 = set1.values();
+#endif
QCOMPARE(list3.size(), 3);
QVERIFY(list3.contains("A"));
QVERIFY(list3.contains("B"));
@@ -2578,9 +2499,11 @@ void tst_Collections::conversions()
QVERIFY(!list3.contains("D"));
QVERIFY(QVector<int>::fromList(QList<int>()).isEmpty());
- QVERIFY(QSet<int>::fromList(QList<int>()).isEmpty());
QVERIFY(QList<int>::fromVector(QVector<int>()).isEmpty());
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QVERIFY(QSet<int>::fromList(QList<int>()).isEmpty());
QVERIFY(QList<int>::fromSet(QSet<int>()).isEmpty());
+#endif
}
#undef STUFF
}
@@ -2606,7 +2529,7 @@ template <class Container>
void testLinkedListLikeStlIterators()
{
Container fake;
- typename Container::value_type t;
+ typename Container::value_type t = {};
fake << t;
typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
@@ -2639,7 +2562,7 @@ void testListLikeStlIterators()
testLinkedListLikeStlIterators<Container>();
Container fake;
- typename Container::value_type t;
+ typename Container::value_type t = {};
fake << t;
typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
@@ -2722,8 +2645,10 @@ void testMapLikeStlIterators()
QString t;
fake.insert(k, t);
- typename Container::iterator i1 = fake.begin(), i2 = i1 + 1;
- typename Container::const_iterator c1 = i1, c2 = c1 + 1;
+ typename Container::iterator i1 = fake.begin(), i2 = i1;
+ ++i2;
+ typename Container::const_iterator c1 = i1, c2 = c1;
+ ++c2;
QVERIFY(i1 == i1);
QVERIFY(i1 == c1);
@@ -2733,8 +2658,6 @@ void testMapLikeStlIterators()
QVERIFY(i2 == c2);
QVERIFY(c2 == i2);
QVERIFY(c2 == c2);
- QVERIFY(1 + i1 == i1 + 1);
- QVERIFY(1 + c1 == c1 + 1);
QVERIFY(i1 != i2);
QVERIFY(i1 != c2);
@@ -2748,14 +2671,12 @@ void testMapLikeStlIterators()
void tst_Collections::constAndNonConstStlIterators()
{
- testListLikeStlIterators<QList<int> >();
- testListLikeStlIterators<QStringList >();
- testLinkedListLikeStlIterators<QLinkedList<int> >();
- testListLikeStlIterators<QVector<int> >();
- testMapLikeStlIterators<QMap<QString, QString> >();
- testMapLikeStlIterators<QMultiMap<QString, QString> >();
- testMapLikeStlIterators<QHash<QString, QString> >();
- testMapLikeStlIterators<QMultiHash<QString, QString> >();
+ testListLikeStlIterators<QList<int>>();
+ testListLikeStlIterators<QStringList>();
+ testMapLikeStlIterators<QMap<QString, QString>>();
+ testMapLikeStlIterators<QMultiMap<QString, QString>>();
+ testMapLikeStlIterators<QHash<QString, QString>>();
+ testMapLikeStlIterators<QMultiHash<QString, QString>>();
}
void tst_Collections::vector_stl_data()
@@ -2772,44 +2693,25 @@ void tst_Collections::vector_stl()
{
QFETCH(QStringList, elements);
- QVector<QString> vector;
- for (int i = 0; i < elements.count(); ++i)
+ QList<QString> vector;
+ for (int i = 0; i < elements.size(); ++i)
vector << elements.at(i);
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
std::vector<QString> stdVector = vector.toStdVector();
-
+#else
+ std::vector<QString> stdVector(vector.begin(), vector.end());
+#endif
QCOMPARE(int(stdVector.size()), elements.size());
std::vector<QString>::const_iterator it = stdVector.begin();
for (uint j = 0; j < stdVector.size() && it != stdVector.end(); ++j, ++it)
QCOMPARE(*it, vector[j]);
- QCOMPARE(QVector<QString>::fromStdVector(stdVector), vector);
-}
-
-void tst_Collections::linkedlist_stl_data()
-{
- list_stl_data();
-}
-
-void tst_Collections::linkedlist_stl()
-{
- QFETCH(QStringList, elements);
-
- QLinkedList<QString> list;
- for (int i = 0; i < elements.count(); ++i)
- list << elements.at(i);
-
- std::list<QString> stdList = list.toStdList();
-
- QCOMPARE(int(stdList.size()), elements.size());
-
- std::list<QString>::const_iterator it = stdList.begin();
- QLinkedList<QString>::const_iterator it2 = list.cbegin();
- for (uint j = 0; j < stdList.size(); ++j, ++it, ++it2)
- QCOMPARE(*it, *it2);
-
- QCOMPARE(QLinkedList<QString>::fromStdList(stdList), list);
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QCOMPARE(QList<QString>::fromStdVector(stdVector), vector);
+#endif
+ QCOMPARE(QList<QString>(stdVector.begin(), stdVector.end()), vector);
}
void tst_Collections::list_stl_data()
@@ -2827,10 +2729,14 @@ void tst_Collections::list_stl()
QFETCH(QStringList, elements);
QList<QString> list;
- for (int i = 0; i < elements.count(); ++i)
+ for (int i = 0; i < elements.size(); ++i)
list << elements.at(i);
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
std::list<QString> stdList = list.toStdList();
+#else
+ std::list<QString> stdList(list.begin(), list.end());
+#endif
QCOMPARE(int(stdList.size()), elements.size());
@@ -2838,11 +2744,14 @@ void tst_Collections::list_stl()
for (uint j = 0; j < stdList.size() && it != stdList.end(); ++j, ++it)
QCOMPARE(*it, list[j]);
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
QCOMPARE(QList<QString>::fromStdList(stdList), list);
+#endif
+ QCOMPARE(QList<QString>(stdList.begin(), stdList.end()), list);
}
template <typename T>
-T qtInit(T * = 0)
+T qtInit(T * = nullptr)
{
return T();
}
@@ -2852,9 +2761,9 @@ void tst_Collections::q_init()
QCOMPARE(qtInit<int>(), 0);
QCOMPARE(qtInit<double>(), 0.0);
QCOMPARE(qtInit<QString>(), QString());
- QCOMPARE(qtInit<int *>(), static_cast<int *>(0));
- QCOMPARE(qtInit<double *>(), static_cast<double *>(0));
- QCOMPARE(qtInit<QString *>(), static_cast<QString *>(0));
+ QCOMPARE(qtInit<int *>(), static_cast<int *>(nullptr));
+ QCOMPARE(qtInit<double *>(), static_cast<double *>(nullptr));
+ QCOMPARE(qtInit<QString *>(), static_cast<QString *>(nullptr));
QCOMPARE(qtInit<Pod>().i1, 0);
QCOMPARE(qtInit<Pod>().i2, 0);
}
@@ -2868,6 +2777,7 @@ class LessThanComparable
{
public:
bool operator<(const LessThanComparable &) const { return true; }
+ bool operator==(const LessThanComparable &) const { return true; }
};
class EqualsComparable
@@ -2876,7 +2786,7 @@ public:
bool operator==(const EqualsComparable &) const { return true; }
};
-uint qHash(const EqualsComparable &)
+size_t qHash(const EqualsComparable &)
{
return 0;
}
@@ -2908,11 +2818,11 @@ void instantiateContainer()
constIt = constContainer.end();
constIt = constContainer.cend();
container.constEnd();
- Q_UNUSED(constIt)
+ Q_UNUSED(constIt);
container.clear();
container.contains(value);
- container.count();
+ container.size();
container.empty();
container.isEmpty();
container.size();
@@ -2931,11 +2841,7 @@ void instantiateMutableIterationContainer()
typename ContainerType::iterator it;
it = container.begin();
it = container.end();
- Q_UNUSED(it)
-
- // QSet lacks count(T).
- const ValueType value = ValueType();
- container.count(value);
+ Q_UNUSED(it);
}
template <typename ContainerType, typename ValueType>
@@ -2943,10 +2849,9 @@ void instantiateSequence()
{
instantiateMutableIterationContainer<ContainerType, ValueType>();
-// QVector lacks removeAll(T)
-// ValueType value = ValueType();
-// ContainerType container;
-// container.removeAll(value);
+ ValueType value = ValueType();
+ ContainerType container;
+ container.removeAll(value);
}
template <typename ContainerType, typename ValueType>
@@ -3001,14 +2906,12 @@ void instantiatePairAssociative()
{
instantiateMutableIterationContainer<ContainerType, KeyType>();
- typename ContainerType::iterator it;
- typename ContainerType::const_iterator constIt;
const KeyType key = KeyType();
const ValueType value = ValueType();
ContainerType container;
const ContainerType constContainer(container);
- it = container.insert(key, value);
+ auto it = container.insert(key, value);
container.erase(it);
container.find(key);
container.constFind(key);
@@ -3019,11 +2922,10 @@ void instantiatePairAssociative()
constContainer.keys();
container.remove(key);
container.take(key);
- container.unite(constContainer);
+ container.insert(constContainer);
container.value(key);
container.value(key, value);
container.values();
- container.values(key);
container[key];
const int foo = constContainer[key];
Q_UNUSED(foo);
@@ -3052,15 +2954,6 @@ void tst_Collections::containerInstantiation()
typedef QSet<EqualsComparable> Set;
instantiateAssociative<Set, EqualsComparable>();
- //Instantiate QLinkedList member functions.
- typedef QLinkedList<EqualsComparable> LinkedList;
- instantiateSequence<LinkedList, EqualsComparable> ();
- {
- EqualsComparable value;
- LinkedList list;
- list.removeAll(value);
- }
-
//Instantiate QList member functions.
typedef QList<EqualsComparable> List;
instantiateRandomAccess<List, EqualsComparable>();
@@ -3070,10 +2963,6 @@ void tst_Collections::containerInstantiation()
list.removeAll(value);
}
- //Instantiate QVector member functions.
- typedef QVector<EqualsComparable> Vector;
- instantiateRandomAccess<Vector, EqualsComparable>();
-
//Instantiate QQueue member functions.
typedef QQueue<EqualsComparable> Queue;
instantiateRandomAccess<Queue, EqualsComparable>();
@@ -3111,7 +3000,7 @@ void tst_Collections::qtimerList()
template <typename Container>
void testContainerTypedefs(Container container)
{
- Q_UNUSED(container)
+ Q_UNUSED(container);
{ QVERIFY_TYPE(typename Container::value_type); }
{ QVERIFY_TYPE(typename Container::iterator); }
{ QVERIFY_TYPE(typename Container::const_iterator); }
@@ -3125,7 +3014,7 @@ void testContainerTypedefs(Container container)
template <typename Container>
void testPairAssociativeContainerTypedefs(Container container)
{
- Q_UNUSED(container)
+ Q_UNUSED(container);
// TODO: Not sure how to define value_type for our associative containers
// { QVERIFY_TYPE(typename Container::value_type); }
@@ -3147,7 +3036,7 @@ void testPairAssociativeContainerTypedefs(Container container)
template <typename Container>
void testSetContainerTypedefs(Container container)
{
- Q_UNUSED(container)
+ Q_UNUSED(container);
{ QVERIFY_TYPE(typename Container::iterator); }
{ QVERIFY_TYPE(typename Container::const_iterator); }
{ QVERIFY_TYPE(typename Container::reference); }
@@ -3164,10 +3053,8 @@ void testSetContainerTypedefs(Container container)
*/
void tst_Collections::containerTypedefs()
{
- testContainerTypedefs(QVector<int>());
testContainerTypedefs(QStack<int>());
testContainerTypedefs(QList<int>());
- testContainerTypedefs(QLinkedList<int>());
testContainerTypedefs(QQueue<int>());
testPairAssociativeContainerTypedefs(QMap<int, int>());
@@ -3183,34 +3070,40 @@ class T2;
void tst_Collections::forwardDeclared()
{
- { typedef QHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QMultiHash<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QMultiMap<Key1, T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QPair<T1, T2> C; C *x = 0; Q_UNUSED(x) }
- { typedef QList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QLinkedList<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QVector<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) }
- { typedef QStack<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) Q_UNUSED(i) Q_UNUSED(j) }
- { typedef QQueue<T1> C; C *x = 0; C::iterator i; C::const_iterator j; Q_UNUSED(x) }
- { typedef QSet<T1> C; C *x = 0; /* C::iterator i; */ C::const_iterator j; Q_UNUSED(x) }
-}
-
-#if defined(Q_ALIGNOF) && defined(Q_DECL_ALIGN)
-
-class Q_DECL_ALIGN(4) Aligned4
-{
- char i;
-public:
- Aligned4(int i = 0) : i(i) {}
+#define TEST(...) do { \
+ using C = __VA_ARGS__; \
+ C *x = nullptr; \
+ C::iterator i; \
+ C::const_iterator j; \
+ Q_UNUSED(x); \
+ Q_UNUSED(i); \
+ Q_UNUSED(j); \
+ } while (false)
+
+ TEST(QHash<Key1, T1>);
+ TEST(QMap<Key1, T1>);
+ TEST(QMultiMap<Key1, T1>);
+ TEST(QList<T1>);
+ TEST(QVector<T1>);
+ TEST(QStack<T1>);
+ TEST(QQueue<T1>);
+ TEST(QSet<T1>);
+#undef TEST
- enum { PreferredAlignment = 4 };
+ {
+ using C = QPair<T1, T2>;
+ C *x = nullptr;
+ Q_UNUSED(x);
+ }
- inline bool operator==(const Aligned4 &other) const { return i == other.i; }
- inline bool operator<(const Aligned4 &other) const { return i < other.i; }
- friend inline int qHash(const Aligned4 &a) { return qHash(a.i); }
-};
-Q_STATIC_ASSERT(Q_ALIGNOF(Aligned4) % 4 == 0);
+ {
+ using C = QSet<T1>;
+ C *x = nullptr;
+ C::const_iterator j;
+ Q_UNUSED(x);
+ Q_UNUSED(j);
+ }
+}
#if defined(Q_PROCESSOR_ARM)
# if defined(Q_COMPILER_ALIGNAS) && defined(__BIGGEST_ALIGNMENT__)
@@ -3224,19 +3117,30 @@ Q_STATIC_ASSERT(Q_ALIGNOF(Aligned4) % 4 == 0);
# define BIGGEST_ALIGNMENT_TO_TEST 128
#endif
-class Q_DECL_ALIGN(BIGGEST_ALIGNMENT_TO_TEST) AlignedBiggest
+template <size_t Alignment>
+class alignas(Alignment) AlignedClass
{
char i;
+
public:
- AlignedBiggest(int i = 0) : i(i) {}
+ AlignedClass(int i = 0) : i(i) {}
- enum { PreferredAlignment = BIGGEST_ALIGNMENT_TO_TEST };
+ enum { PreferredAlignment = Alignment };
- inline bool operator==(const AlignedBiggest &other) const { return i == other.i; }
- inline bool operator<(const AlignedBiggest &other) const { return i < other.i; }
- friend inline int qHash(const AlignedBiggest &a) { return qHash(a.i); }
+ inline bool operator==(const AlignedClass &other) const { return i == other.i; }
+ inline bool operator<(const AlignedClass &other) const { return i < other.i; }
+ friend inline size_t qHash(const AlignedClass &a) { return qHash(a.i); }
};
-Q_STATIC_ASSERT(Q_ALIGNOF(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0);
+
+using Aligned4 = AlignedClass<4>;
+static_assert(alignof(Aligned4) % 4 == 0);
+
+using AlignedStdMax = AlignedClass<alignof(std::max_align_t)>;
+static_assert(alignof(AlignedStdMax) % alignof(std::max_align_t) == 0);
+
+using AlignedBiggest = AlignedClass<BIGGEST_ALIGNMENT_TO_TEST>;
+static_assert(BIGGEST_ALIGNMENT_TO_TEST > alignof(std::max_align_t), "Not overly aligned");
+static_assert(alignof(AlignedBiggest) % BIGGEST_ALIGNMENT_TO_TEST == 0);
template<typename C>
void testVectorAlignment()
@@ -3293,27 +3197,31 @@ void testAssociativeContainerAlignment()
void tst_Collections::alignment()
{
- testVectorAlignment<QVector<Aligned4> >();
- testVectorAlignment<QVector<AlignedBiggest> >();
+ testVectorAlignment<QList<Aligned4> >();
+ testVectorAlignment<QList<AlignedStdMax> >();
+ testVectorAlignment<QList<AlignedBiggest> >();
+
testContiguousCacheAlignment<QContiguousCache<Aligned4> >();
+ testContiguousCacheAlignment<QContiguousCache<AlignedStdMax> >();
testContiguousCacheAlignment<QContiguousCache<AlignedBiggest> >();
+
+ // there's no guarentee that std::map supports over-aligned types
testAssociativeContainerAlignment<QMap<Aligned4, Aligned4> >();
- testAssociativeContainerAlignment<QMap<Aligned4, AlignedBiggest> >();
- testAssociativeContainerAlignment<QMap<AlignedBiggest, Aligned4> >();
- testAssociativeContainerAlignment<QMap<AlignedBiggest, AlignedBiggest> >();
+ testAssociativeContainerAlignment<QMap<Aligned4, AlignedStdMax> >();
+ testAssociativeContainerAlignment<QMap<AlignedStdMax, Aligned4> >();
+ testAssociativeContainerAlignment<QMap<AlignedStdMax, AlignedStdMax> >();
+
testAssociativeContainerAlignment<QHash<Aligned4, Aligned4> >();
+ testAssociativeContainerAlignment<QHash<Aligned4, AlignedStdMax> >();
testAssociativeContainerAlignment<QHash<Aligned4, AlignedBiggest> >();
+ testAssociativeContainerAlignment<QHash<AlignedStdMax, Aligned4> >();
+ testAssociativeContainerAlignment<QHash<AlignedStdMax, AlignedStdMax> >();
+ testAssociativeContainerAlignment<QHash<AlignedStdMax, AlignedBiggest> >();
testAssociativeContainerAlignment<QHash<AlignedBiggest, Aligned4> >();
+ testAssociativeContainerAlignment<QHash<AlignedBiggest, AlignedStdMax> >();
testAssociativeContainerAlignment<QHash<AlignedBiggest, AlignedBiggest> >();
}
-#else
-void tst_Collections::alignment()
-{
- QSKIP("Compiler doesn't support necessary extension keywords");
-}
-#endif
-
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
template<template<class> class C>
@@ -3337,7 +3245,7 @@ template<template<class> class C> void QTBUG13079_collectionInsideCollectionImpl
QCOMPARE(nodeList.first().s, QString::fromLatin1("child"));
nodeList = nodeList.first().children;
- QCOMPARE(nodeList.count(), 0);
+ QCOMPARE(nodeList.size(), 0);
nodeList << QTBUG13079_Node<C>();
}
@@ -3362,12 +3270,12 @@ template<template<class, class> class C> void QTBUG13079_collectionInsideCollect
QCOMPARE(nodeMap[12].s, QString::fromLatin1("child"));
nodeMap = nodeMap[12].children;
- QCOMPARE(nodeMap.count(), 0);
+ QCOMPARE(nodeMap.size(), 0);
nodeMap[42] = QTBUG13079_NodeAssoc<C>();
}
-quint32 qHash(const QTBUG13079_Node<QSet> &)
+size_t qHash(const QTBUG13079_Node<QSet> &)
{
return 0;
}
@@ -3423,14 +3331,13 @@ void tst_Collections::QTBUG13079_collectionInsideCollection()
QTBUG13079_collectionInsideCollectionImpl<QVector>();
QTBUG13079_collectionInsideCollectionImpl<QStack>();
QTBUG13079_collectionInsideCollectionImpl<QList>();
- QTBUG13079_collectionInsideCollectionImpl<QLinkedList>();
QTBUG13079_collectionInsideCollectionImpl<QQueue>();
{
QSet<QTBUG13079_Node<QSet> > nodeSet;
nodeSet << QTBUG13079_Node<QSet>();
nodeSet = nodeSet.begin()->children;
- QCOMPARE(nodeSet.count(), 0);
+ QCOMPARE(nodeSet.size(), 0);
}
QTBUG13079_collectionInsideCollectionAssocImpl<QMap>();
@@ -3452,7 +3359,7 @@ template<class Container> void foreach_test_arrays(const Container &container)
set << val;
i++;
}
- QCOMPARE(set.count(), container.count());
+ QCOMPARE(set.size(), container.size());
//modify the container while iterating.
Container c2 = container;
@@ -3489,12 +3396,9 @@ void tst_Collections::foreach_2()
varl2 << i;
varl3 << i;
}
- QCOMPARE(varl1.count(), intlist.count());
- QCOMPARE(varl2.count(), intlist.count());
- QCOMPARE(varl3.count(), intlist.count());
- foreach_test_arrays(varl1);
- foreach_test_arrays(varl2);
- foreach_test_arrays(varl3);
+ QCOMPARE(varl1.size(), intlist.size());
+ QCOMPARE(varl2.size(), intlist.size());
+ QCOMPARE(varl3.size(), intlist.size());
QVarLengthArray<QString> varl4;
QVarLengthArray<QString, 3> varl5;
@@ -3504,12 +3408,9 @@ void tst_Collections::foreach_2()
varl5 << str;
varl6 << str;
}
- QCOMPARE(varl4.count(), strlist.count());
- QCOMPARE(varl5.count(), strlist.count());
- QCOMPARE(varl6.count(), strlist.count());
- foreach_test_arrays(varl4);
- foreach_test_arrays(varl5);
- foreach_test_arrays(varl6);
+ QCOMPARE(varl4.size(), strlist.size());
+ QCOMPARE(varl5.size(), strlist.size());
+ QCOMPARE(varl6.size(), strlist.size());
}
struct IntOrString
@@ -3530,14 +3431,17 @@ template<class Container> void insert_remove_loop_impl()
t.append(T(IntOrString(1)));
t << (T(IntOrString(2)));
t += (T(IntOrString(3)));
- t.prepend(T(IntOrString(4)));
+ if constexpr (has_prepend_v<Container>)
+ t.prepend(T(IntOrString(4)));
+ else
+ t.insert(t.cbegin(), T(IntOrString(4)));
t.insert(2, 3 , T(IntOrString(5)));
t.insert(4, T(IntOrString(6)));
t.insert(t.begin() + 2, T(IntOrString(7)));
t.insert(t.begin() + 5, 3, T(IntOrString(8)));
int expect1[] = { 4 , 1 , 7, 5 , 5 , 8, 8, 8, 6, 5, 2 , 3 };
- QCOMPARE(size_t(t.count()), sizeof(expect1)/sizeof(int));
- for (int i = 0; i < t.count(); i++) {
+ QCOMPARE(size_t(t.size()), sizeof(expect1)/sizeof(int));
+ for (int i = 0; i < t.size(); i++) {
QCOMPARE(t[i], T(IntOrString(expect1[i])));
}
@@ -3551,8 +3455,8 @@ template<class Container> void insert_remove_loop_impl()
t.remove(7);
t.remove(2, 3);
int expect2[] = { 4 , 1 , 9, 8, 6, 5, 2 , 3 };
- QCOMPARE(size_t(t.count()), sizeof(expect2)/sizeof(int));
- for (int i = 0; i < t.count(); i++) {
+ QCOMPARE(size_t(t.size()), sizeof(expect2)/sizeof(int));
+ for (int i = 0; i < t.size(); i++) {
QCOMPARE(t[i], T(IntOrString(expect2[i])));
}
@@ -3564,16 +3468,16 @@ template<class Container> void insert_remove_loop_impl()
}
int expect3[] = { 1 , 9, 5, 3 };
- QCOMPARE(size_t(t.count()), sizeof(expect3)/sizeof(int));
- for (int i = 0; i < t.count(); i++) {
+ QCOMPARE(size_t(t.size()), sizeof(expect3)/sizeof(int));
+ for (int i = 0; i < t.size(); i++) {
QCOMPARE(t[i], T(IntOrString(expect3[i])));
}
t.erase(t.begin() + 1, t.end() - 1);
int expect4[] = { 1 , 3 };
- QCOMPARE(size_t(t.count()), sizeof(expect4)/sizeof(int));
- for (int i = 0; i < t.count(); i++) {
+ QCOMPARE(size_t(t.size()), sizeof(expect4)/sizeof(int));
+ for (int i = 0; i < t.size(); i++) {
QCOMPARE(t[i], T(IntOrString(expect4[i])));
}
@@ -3590,62 +3494,108 @@ template<class Container> void insert_remove_loop_impl()
int expect5[] = { 1, 1, 2, 3*3, 3, 3*3+1, 10, 11*11, 11, 11*11+1, 12 , 13*13, 13, 13*13+1, 14,
15*15, 15, 15*15+1, 16 , 17*17, 17, 17*17+1 ,18 , 19*19, 19, 19*19+1, 20, 21*21, 21, 21*21+1 };
- QCOMPARE(size_t(t.count()), sizeof(expect5)/sizeof(int));
- for (int i = 0; i < t.count(); i++) {
+ QCOMPARE(size_t(t.size()), sizeof(expect5)/sizeof(int));
+ for (int i = 0; i < t.size(); i++) {
QCOMPARE(t[i], T(IntOrString(expect5[i])));
}
-}
+ t.clear();
+ t << T(IntOrString(1)) << T(IntOrString(2)) << T(IntOrString(3)) << T(IntOrString(4));
+ t.insert(2, 4, T(IntOrString(9)));
+ t.insert(2, 4, T(IntOrString(7)));
-//Add insert(int, int, T) so it has the same interface as QVector and QVarLengthArray for the test.
-template<typename T>
-struct ExtList : QList<T> {
- using QList<T>::insert;
- void insert(int before, int n, const T&x) {
- while (n--) {
- this->insert(before, x );
- }
- }
- void insert(typename QList<T>::iterator before, int n, const T&x) {
- while (n--) {
- before = this->insert(before, x);
- }
+ int expect6[] = { 1, 2, 7, 7, 7, 7, 9, 9, 9, 9, 3, 4 };
+ QCOMPARE(size_t(t.size()), sizeof(expect6)/sizeof(int));
+ for (int i = 0; i < t.size(); i++) {
+ QCOMPARE(t[i], T(IntOrString(expect6[i])));
}
- void remove(int i) {
- this->removeAt(i);
- }
- void remove(int i, int n) {
- while (n--) {
- this->removeAt(i);
- }
- }
-};
+}
+
+
+template<typename T>
+using ExtList = QList<T>;
void tst_Collections::insert_remove_loop()
{
- insert_remove_loop_impl<ExtList<int> >();
- insert_remove_loop_impl<ExtList<QString> >();
- insert_remove_loop_impl<QVector<int> >();
- insert_remove_loop_impl<QVector<QString> >();
- insert_remove_loop_impl<QVarLengthArray<int> >();
- insert_remove_loop_impl<QVarLengthArray<QString> >();
- insert_remove_loop_impl<QVarLengthArray<int, 10> >();
- insert_remove_loop_impl<QVarLengthArray<QString, 10> >();
- insert_remove_loop_impl<QVarLengthArray<int, 3> >();
- insert_remove_loop_impl<QVarLengthArray<QString, 3> >();
- insert_remove_loop_impl<QVarLengthArray<int, 15> >();
- insert_remove_loop_impl<QVarLengthArray<QString, 15> >();
-
- insert_remove_loop_impl<ExtList<std::string> >();
- insert_remove_loop_impl<QVector<std::string> >();
- insert_remove_loop_impl<QVarLengthArray<std::string> >();
- insert_remove_loop_impl<QVarLengthArray<std::string, 10> >();
- insert_remove_loop_impl<QVarLengthArray<std::string, 3> >();
- insert_remove_loop_impl<QVarLengthArray<std::string, 15> >();
+ insert_remove_loop_impl<ExtList<int>>();
+ insert_remove_loop_impl<ExtList<QString>>();
+ insert_remove_loop_impl<QList<int>>();
+ insert_remove_loop_impl<QList<QString>>();
+ insert_remove_loop_impl<QVarLengthArray<int>>();
+ insert_remove_loop_impl<QVarLengthArray<QString>>();
+ insert_remove_loop_impl<QVarLengthArray<int, 10>>();
+ insert_remove_loop_impl<QVarLengthArray<QString, 10>>();
+ insert_remove_loop_impl<QVarLengthArray<int, 3>>();
+ insert_remove_loop_impl<QVarLengthArray<QString, 3>>();
+ insert_remove_loop_impl<QVarLengthArray<int, 15>>();
+ insert_remove_loop_impl<QVarLengthArray<QString, 15>>();
+
+ insert_remove_loop_impl<ExtList<std::string>>();
+ insert_remove_loop_impl<QList<std::string>>();
+ insert_remove_loop_impl<QVarLengthArray<std::string>>();
+ insert_remove_loop_impl<QVarLengthArray<std::string, 10>>();
+ insert_remove_loop_impl<QVarLengthArray<std::string, 3>>();
+ insert_remove_loop_impl<QVarLengthArray<std::string, 15>>();
+}
+
+template <template<typename, typename> typename Container>
+void tst_Collections::detachAssociativeContainerImpl()
+{
+ constexpr int RUNS = 50;
+
+ for (int run = 0; run < RUNS; ++run) {
+ Container<int, int> container;
+
+ for (int i = 0; i < 1'000; ++i) {
+ container.insert(i, i);
+ container.insert(i, i); // for multi-keyed containers
+ }
+
+ const auto it = container.constBegin();
+ const auto &key = it.key();
+ const auto &value = it.value();
+ const auto keyCopy = key;
+ const auto valueCopy = value;
+
+ QSemaphore sem1, sem2;
+ auto detachInAnotherThread = [&sem1, &sem2, copy = container]() mutable {
+ sem1.release();
+ sem2.acquire();
+ copy.clear(); // <==
+ };
+
+ QScopedPointer thread(QThread::create(std::move(detachInAnotherThread)));
+ thread->start();
+
+ sem2.release();
+ sem1.acquire();
+
+ // The following call may detach (because the container is
+ // shared), and then use key/value to search+insert.
+ //
+ // This means that key/value, as references, have to be valid
+ // throughout the insertion procedure. Note that they are
+ // references into the container *itself*; and that the
+ // insertion procedure is working on a new (detached) copy of
+ // the container's payload.
+ //
+ // There is now a possible scenario in which the clear() above
+ // finds the copy's refcount at 1, hence not perform a detach,
+ // and destroy its payload. But key/value were references into
+ // *that* payload (it's the payload that `container` itself
+ // used to share). If inside insert() we don't take extra
+ // measures to keep the payload alive, now they're dangling and
+ // the insertion will malfunction.
+
+ container.insert(key, value);
+
+ QVERIFY(container.contains(keyCopy));
+ QCOMPARE(container.value(keyCopy), valueCopy);
+
+ thread->wait();
+ }
}
-
-
QTEST_APPLESS_MAIN(tst_Collections)
#include "tst_collections.moc"
diff --git a/tests/auto/corelib/tools/containerapisymmetry/CMakeLists.txt b/tests/auto/corelib/tools/containerapisymmetry/CMakeLists.txt
new file mode 100644
index 0000000000..0ae1092043
--- /dev/null
+++ b/tests/auto/corelib/tools/containerapisymmetry/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_containerapisymmetry Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_containerapisymmetry LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_containerapisymmetry
+ SOURCES
+ tst_containerapisymmetry.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro b/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro
deleted file mode 100644
index 30dc8026ef..0000000000
--- a/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-TARGET = tst_containerapisymmetry
-SOURCES += tst_containerapisymmetry.cpp
-QT = core testlib
-
-# This test does not work with strict iterators
-DEFINES -= QT_STRICT_ITERATORS
diff --git a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
index 3b8111f1a3..5eb9dbfa36 100644
--- a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
+++ b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
@@ -1,99 +1,1266 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include "qbytearray.h"
-#include "qlinkedlist.h"
+#include "qdebug.h"
+#include "qhash.h"
+#include "qmap.h"
+#include "qset.h"
#include "qlist.h"
#include "qstring.h"
#include "qvarlengtharray.h"
-#include "qvector.h"
-#include <vector> // for reference
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <list>
+#include <set>
+#include <sstream>
+#include <map>
+#include <forward_list>
+#include <unordered_set>
+#include <unordered_map>
+#include <q20vector.h> // For reference
+
+QT_BEGIN_NAMESPACE
+std::ostream &operator<<(std::ostream &os, const QChar &c)
+{
+ Q_ASSERT(c == QLatin1Char{c.toLatin1()});
+ return os << c.toLatin1();
+}
+std::istream &operator>>(std::istream &os, QChar &c)
+{
+ char cL1;
+ os >> cL1;
+ c = QLatin1Char{cL1};
+ return os;
+}
+QT_END_NAMESPACE
+
+struct Movable
+{
+ explicit Movable(int i = 0) noexcept
+ : i(i)
+ {
+ ++instanceCount;
+ }
+
+ Movable(const Movable &m)
+ : i(m.i)
+ {
+ ++instanceCount;
+ }
+
+ ~Movable()
+ {
+ --instanceCount;
+ }
+
+ int i;
+ static int instanceCount;
+
+ friend std::ostream &operator<<(std::ostream &os, const Movable &m)
+ { return os << m.i; }
+ friend std::istream &operator>>(std::istream &os, Movable &m)
+ { return os >> m.i; }
+};
+
+int Movable::instanceCount = 0;
+bool operator==(Movable lhs, Movable rhs) noexcept { return lhs.i == rhs.i; }
+bool operator!=(Movable lhs, Movable rhs) noexcept { return lhs.i != rhs.i; }
+bool operator<(Movable lhs, Movable rhs) noexcept { return lhs.i < rhs.i; }
+
+size_t qHash(Movable m, size_t seed = 0) noexcept { return qHash(m.i, seed); }
+QDebug &operator<<(QDebug &d, Movable m)
+{
+ const QDebugStateSaver saver(d);
+ return d.nospace() << "Movable(" << m.i << ")";
+}
+
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(Movable, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+
+struct Complex
+{
+ explicit Complex(int i = 0) noexcept
+ : i(i)
+ {
+ ++instanceCount;
+ }
+
+ Complex(const Complex &c)
+ : i(c.i)
+ {
+ ++instanceCount;
+ }
+
+ ~Complex()
+ {
+ --instanceCount;
+ }
+ constexpr Complex &operator=(const Complex &o) noexcept
+ { i = o.i; return *this; }
+
+ int i;
+ static int instanceCount;
+
+ friend std::ostream &operator<<(std::ostream &os, const Complex &c)
+ { return os << c.i; }
+ friend std::istream &operator>>(std::istream &os, Complex &c)
+ { return os >> c.i; }
+};
+
+int Complex::instanceCount = 0;
+bool operator==(Complex lhs, Complex rhs) noexcept { return lhs.i == rhs.i; }
+bool operator!=(Complex lhs, Complex rhs) noexcept { return lhs.i != rhs.i; }
+bool operator<(Complex lhs, Complex rhs) noexcept { return lhs.i < rhs.i; }
+
+size_t qHash(Complex c, size_t seed = 0) noexcept { return qHash(c.i, seed); }
+QDebug &operator<<(QDebug &d, Complex c)
+{
+ const QDebugStateSaver saver(d);
+ return d.nospace() << "Complex(" << c.i << ")";
+}
+
+
+struct DuplicateStrategyTestType
+{
+ explicit DuplicateStrategyTestType(int i = 0) noexcept
+ : i(i),
+ j(++counter)
+ {
+ }
+
+ int i;
+ int j;
+
+ static int counter;
+};
+
+int DuplicateStrategyTestType::counter = 0;
+
+// only look at the i member, not j. j allows us to identify which instance
+// gets inserted in containers that don't allow for duplicates
+bool operator==(DuplicateStrategyTestType lhs, DuplicateStrategyTestType rhs) noexcept
+{
+ return lhs.i == rhs.i;
+}
+
+bool operator!=(DuplicateStrategyTestType lhs, DuplicateStrategyTestType rhs) noexcept
+{
+ return lhs.i != rhs.i;
+}
+
+bool operator<(DuplicateStrategyTestType lhs, DuplicateStrategyTestType rhs) noexcept
+{
+ return lhs.i < rhs.i;
+}
+
+size_t qHash(DuplicateStrategyTestType c, size_t seed = 0) noexcept
+{
+ return qHash(c.i, seed);
+}
+
+bool reallyEqual(DuplicateStrategyTestType lhs, DuplicateStrategyTestType rhs) noexcept
+{
+ return lhs.i == rhs.i && lhs.j == rhs.j;
+}
+
+QDebug &operator<<(QDebug &d, DuplicateStrategyTestType c)
+{
+ const QDebugStateSaver saver(d);
+ return d.nospace() << "DuplicateStrategyTestType(" << c.i << "," << c.j << ")";
+}
+
+
+namespace std {
+template<>
+struct hash<Movable>
+{
+ std::size_t operator()(Movable m) const noexcept
+ {
+ return hash<int>()(m.i);
+ }
+};
+
+template<>
+struct hash<Complex>
+{
+ std::size_t operator()(Complex m) const noexcept
+ {
+ return hash<int>()(m.i);
+ }
+};
+
+template<>
+struct hash<DuplicateStrategyTestType>
+{
+ std::size_t operator()(DuplicateStrategyTestType m) const noexcept
+ {
+ return hash<int>()(m.i);
+ }
+};
+}
+
+// work around the fact that QVarLengthArray has a non-type
+// template parameter, and that breaks non_associative_container_duplicates_strategy
+template<typename T>
+class VarLengthArray : public QVarLengthArray<T>
+{
+public:
+ using QVarLengthArray<T>::QVarLengthArray;
+};
class tst_ContainerApiSymmetry : public QObject
{
Q_OBJECT
+ int m_movableInstanceCount;
+ int m_complexInstanceCount;
+
+private Q_SLOTS:
+ void init();
+ void cleanup();
+
+private:
+ template <typename Container>
+ void ranged_ctor_non_associative_impl() const;
+
+ template<template<typename ... T> class Container>
+ void non_associative_container_duplicates_strategy() const;
+
+ template <typename Container>
+ void ranged_ctor_associative_impl() const;
+
+private Q_SLOTS:
+ // non associative
+ void ranged_ctor_std_vector_int() { ranged_ctor_non_associative_impl<std::vector<int>>(); }
+ void ranged_ctor_std_vector_char() { ranged_ctor_non_associative_impl<std::vector<char>>(); }
+ void ranged_ctor_std_vector_QChar() { ranged_ctor_non_associative_impl<std::vector<QChar>>(); }
+ void ranged_ctor_std_vector_Movable() { ranged_ctor_non_associative_impl<std::vector<Movable>>(); }
+ void ranged_ctor_std_vector_Complex() { ranged_ctor_non_associative_impl<std::vector<Complex>>(); }
+ void ranged_ctor_std_vector_duplicates_strategy() { non_associative_container_duplicates_strategy<std::vector>(); }
+
+ void ranged_ctor_QVarLengthArray_int() { ranged_ctor_non_associative_impl<QVarLengthArray<int>>(); }
+ void ranged_ctor_QVarLengthArray_Movable() { ranged_ctor_non_associative_impl<QVarLengthArray<Movable>>(); }
+ void ranged_ctor_QVarLengthArray_Complex() { ranged_ctor_non_associative_impl<QVarLengthArray<Complex>>(); }
+ void ranged_ctor_QVarLengthArray_duplicates_strategy() { non_associative_container_duplicates_strategy<VarLengthArray>(); } // note the VarLengthArray passed
+
+ void ranged_ctor_QList_int() { ranged_ctor_non_associative_impl<QList<int>>(); }
+ void ranged_ctor_QList_char() { ranged_ctor_non_associative_impl<QList<char>>(); }
+ void ranged_ctor_QList_QChar() { ranged_ctor_non_associative_impl<QList<QChar>>(); }
+ void ranged_ctor_QList_Movable() { ranged_ctor_non_associative_impl<QList<Movable>>(); }
+ void ranged_ctor_QList_Complex() { ranged_ctor_non_associative_impl<QList<Complex>>(); }
+ void ranged_ctor_QList_duplicates_strategy() { non_associative_container_duplicates_strategy<QList>(); }
+
+ void ranged_ctor_std_list_int() { ranged_ctor_non_associative_impl<std::list<int>>(); }
+ void ranged_ctor_std_list_Movable() { ranged_ctor_non_associative_impl<std::list<Movable>>(); }
+ void ranged_ctor_std_list_Complex() { ranged_ctor_non_associative_impl<std::list<Complex>>(); }
+ void ranged_ctor_std_list_duplicates_strategy() { non_associative_container_duplicates_strategy<std::list>(); }
+
+ void ranged_ctor_std_forward_list_int() { ranged_ctor_non_associative_impl<std::forward_list<int>>(); }
+ void ranged_ctor_std_forward_list_Movable() {ranged_ctor_non_associative_impl<std::forward_list<Movable>>(); }
+ void ranged_ctor_std_forward_list_Complex() { ranged_ctor_non_associative_impl<std::forward_list<Complex>>(); }
+ void ranged_ctor_std_forward_list_duplicates_strategy() { non_associative_container_duplicates_strategy<std::forward_list>(); }
+
+ void ranged_ctor_std_set_int() { ranged_ctor_non_associative_impl<std::set<int>>(); }
+ void ranged_ctor_std_set_Movable() { ranged_ctor_non_associative_impl<std::set<Movable>>(); }
+ void ranged_ctor_std_set_Complex() { ranged_ctor_non_associative_impl<std::set<Complex>>(); }
+ void ranged_ctor_std_set_duplicates_strategy() { non_associative_container_duplicates_strategy<std::set>(); }
+
+ void ranged_ctor_std_multiset_int() { ranged_ctor_non_associative_impl<std::multiset<int>>(); }
+ void ranged_ctor_std_multiset_Movable() { ranged_ctor_non_associative_impl<std::multiset<Movable>>(); }
+ void ranged_ctor_std_multiset_Complex() { ranged_ctor_non_associative_impl<std::multiset<Complex>>(); }
+ void ranged_ctor_std_multiset_duplicates_strategy() { non_associative_container_duplicates_strategy<std::multiset>(); }
+
+ void ranged_ctor_std_unordered_set_int() { ranged_ctor_non_associative_impl<std::unordered_set<int>>(); }
+ void ranged_ctor_std_unordered_set_Movable() { ranged_ctor_non_associative_impl<std::unordered_set<Movable>>(); }
+ void ranged_ctor_std_unordered_set_Complex() { ranged_ctor_non_associative_impl<std::unordered_set<Complex>>(); }
+ void ranged_ctor_std_unordered_set_duplicates_strategy() { non_associative_container_duplicates_strategy<std::unordered_set>(); }
+
+ void ranged_ctor_std_unordered_multiset_int() { ranged_ctor_non_associative_impl<std::unordered_multiset<int>>(); }
+ void ranged_ctor_std_unordered_multiset_Movable() { ranged_ctor_non_associative_impl<std::unordered_multiset<Movable>>(); }
+ void ranged_ctor_std_unordered_multiset_Complex() { ranged_ctor_non_associative_impl<std::unordered_multiset<Complex>>(); }
+ void ranged_ctor_std_unordered_multiset_duplicates_strategy() { non_associative_container_duplicates_strategy<std::unordered_multiset>(); }
+
+ void ranged_ctor_QSet_int() { ranged_ctor_non_associative_impl<QSet<int>>(); }
+ void ranged_ctor_QSet_Movable() { ranged_ctor_non_associative_impl<QSet<Movable>>(); }
+ void ranged_ctor_QSet_Complex() { ranged_ctor_non_associative_impl<QSet<Complex>>(); }
+ void ranged_ctor_QSet_duplicates_strategy() { non_associative_container_duplicates_strategy<QSet>(); }
+
+ // associative
+ void ranged_ctor_std_map_int() { ranged_ctor_associative_impl<std::map<int, int>>(); }
+ void ranged_ctor_std_map_Movable() { ranged_ctor_associative_impl<std::map<Movable, int>>(); }
+ void ranged_ctor_std_map_Complex() { ranged_ctor_associative_impl<std::map<Complex, int>>(); }
+
+ void ranged_ctor_std_multimap_int() { ranged_ctor_associative_impl<std::multimap<int, int>>(); }
+ void ranged_ctor_std_multimap_Movable() { ranged_ctor_associative_impl<std::multimap<Movable, int>>(); }
+ void ranged_ctor_std_multimap_Complex() { ranged_ctor_associative_impl<std::multimap<Complex, int>>(); }
+
+ void ranged_ctor_unordered_map_int() { ranged_ctor_associative_impl<std::unordered_map<int, int>>(); }
+ void ranged_ctor_unordered_map_Movable() { ranged_ctor_associative_impl<std::unordered_map<Movable, Movable>>(); }
+ void ranged_ctor_unordered_map_Complex() { ranged_ctor_associative_impl<std::unordered_map<Complex, Complex>>(); }
+
+ void ranged_ctor_QHash_int() { ranged_ctor_associative_impl<QHash<int, int>>(); }
+ void ranged_ctor_QHash_Movable() { ranged_ctor_associative_impl<QHash<Movable, int>>(); }
+ void ranged_ctor_QHash_Complex() { ranged_ctor_associative_impl<QHash<Complex, int>>(); }
+
+ void ranged_ctor_unordered_multimap_int() { ranged_ctor_associative_impl<std::unordered_multimap<int, int>>(); }
+ void ranged_ctor_unordered_multimap_Movable() { ranged_ctor_associative_impl<std::unordered_multimap<Movable, Movable>>(); }
+ void ranged_ctor_unordered_multimap_Complex() { ranged_ctor_associative_impl<std::unordered_multimap<Complex, Complex>>(); }
+
+ void ranged_ctor_QMultiHash_int() { ranged_ctor_associative_impl<QMultiHash<int, int>>(); }
+ void ranged_ctor_QMultiHash_Movable() { ranged_ctor_associative_impl<QMultiHash<Movable, int>>(); }
+ void ranged_ctor_QMultiHash_Complex() { ranged_ctor_associative_impl<QMultiHash<Complex, int>>(); }
+
+private:
+ template <typename Container>
+ void resize_impl() const;
+
+private Q_SLOTS:
+ void resize_std_vector() { resize_impl<std::vector<int>>(); }
+ void resize_QList() { resize_impl<QList<qintptr>>(); }
+ void resize_QVarLengthArray() { resize_impl<QVarLengthArray<int>>(); }
+ void resize_QString() { resize_impl<QString>(); }
+ void resize_QByteArray() { resize_impl<QByteArray>(); }
+
+private:
+ template <typename Container>
+ void copesWithValueTypesWithConstMembers_impl();
+
+ struct ConstMember {
+ #ifndef __cpp_aggregate_paren_init // also check that we can emplace aggregates (C++20 only)
+ explicit ConstMember(int n) : n(n) {}
+ #endif
+ const int n;
+
+ friend bool operator==(const ConstMember &lhs, const ConstMember &rhs) noexcept
+ { return lhs.n == rhs.n; }
+ friend bool operator!=(const ConstMember &lhs, const ConstMember &rhs) noexcept
+ { return !(lhs == rhs); }
+ };
+
+private Q_SLOTS:
+ void copesWithValueTypesWithConstMembers_std_vector() { copesWithValueTypesWithConstMembers_impl<std::vector<ConstMember>>(); }
+ void copesWithValueTypesWithConstMembers_QVarLengthArray() { copesWithValueTypesWithConstMembers_impl<QVarLengthArray<ConstMember, 2>>(); }
+
+private:
+ template <typename Container>
+ void assign_impl() const;
+
+private Q_SLOTS:
+ void assign_std_vector() { assign_impl<std::vector<int>>(); };
+ void assign_std_string() { assign_impl<std::string>(); }
+ void assign_QVarLengthArray() { assign_impl<QVarLengthArray<int, 4>>(); };
+ void assign_QList() { assign_impl<QList<int>>(); }
+ void assign_QByteArray() { assign_impl<QByteArray>(); }
+ void assign_QString() { assign_impl<QString>(); }
+
private:
template <typename Container>
void front_back_impl() const;
private Q_SLOTS:
void front_back_std_vector() { front_back_impl<std::vector<int>>(); }
- void front_back_QVector() { front_back_impl<QVector<int>>(); }
void front_back_QList() { front_back_impl<QList<qintptr>>(); }
- void front_back_QLinkedList() { front_back_impl<QLinkedList<int>>(); }
void front_back_QVarLengthArray() { front_back_impl<QVarLengthArray<int>>(); }
void front_back_QString() { front_back_impl<QString>(); }
- void front_back_QStringRef() { front_back_impl<QStringRef>(); }
void front_back_QStringView() { front_back_impl<QStringView>(); }
void front_back_QLatin1String() { front_back_impl<QLatin1String>(); }
void front_back_QByteArray() { front_back_impl<QByteArray>(); }
+
+private:
+ template <typename Container>
+ void erase_impl() const;
+
+ template <typename Container>
+ void erase_if_impl() const;
+
+ template <typename Container>
+ void erase_if_associative_impl() const;
+
+ template <typename Container>
+ void member_erase_impl() const;
+
+ template <typename Container>
+ void member_erase_associative_impl() const;
+
+ template <typename Container>
+ void member_erase_set_impl() const;
+
+private Q_SLOTS:
+ void erase_QList() { erase_impl<QList<int>>(); }
+ void erase_QVarLengthArray() { erase_impl<QVarLengthArray<int>>(); }
+ void erase_QString() { erase_impl<QString>(); }
+ void erase_QByteArray() { erase_impl<QByteArray>(); }
+ void erase_std_vector() { erase_impl<std::vector<int>>(); }
+
+ void erase_if_QList() { erase_if_impl<QList<int>>(); }
+ void erase_if_QVarLengthArray() { erase_if_impl<QVarLengthArray<int>>(); }
+ void erase_if_QSet() { erase_if_impl<QSet<int>>(); }
+ void erase_if_QString() { erase_if_impl<QString>(); }
+ void erase_if_QByteArray() { erase_if_impl<QByteArray>(); }
+ void erase_if_std_vector() { erase_if_impl<std::vector<int>>(); }
+ void erase_if_QMap() { erase_if_associative_impl<QMap<int, int>>(); }
+ void erase_if_QMultiMap() {erase_if_associative_impl<QMultiMap<int, int>>(); }
+ void erase_if_QHash() { erase_if_associative_impl<QHash<int, int>>(); }
+ void erase_if_QMultiHash() { erase_if_associative_impl<QMultiHash<int, int>>(); }
+
+ void member_erase_QList() { member_erase_impl<QList<int>>(); }
+ void member_erase_QVarLengthArray() { member_erase_impl<QVarLengthArray<int>>(); }
+ void member_erase_QString() { member_erase_impl<QString>(); }
+ void member_erase_QByteArray() { member_erase_impl<QByteArray>(); }
+ void member_erase_QSet() { member_erase_set_impl<QSet<int>>(); }
+
+ void member_erase_QMap() { member_erase_associative_impl<QMap<int, int>>(); }
+ void member_erase_QMultiMap() {member_erase_associative_impl<QMultiMap<int, int>>(); }
+ void member_erase_QHash() { member_erase_associative_impl<QHash<int, int>>(); }
+ void member_erase_QMultiHash() { member_erase_associative_impl<QMultiHash<int, int>>(); }
+
+private:
+ template <typename Container>
+ void keyValueRange_impl() const;
+
+private Q_SLOTS:
+ void keyValueRange_QMap() { keyValueRange_impl<QMap<int, int>>(); }
+ void keyValueRange_QMultiMap() { keyValueRange_impl<QMultiMap<int, int>>(); }
+ void keyValueRange_QHash() { keyValueRange_impl<QHash<int, int>>(); }
+ void keyValueRange_QMultiHash() { keyValueRange_impl<QMultiHash<int, int>>(); }
+};
+
+void tst_ContainerApiSymmetry::init()
+{
+ m_movableInstanceCount = Movable::instanceCount;
+ m_complexInstanceCount = Complex::instanceCount;
+}
+
+void tst_ContainerApiSymmetry::cleanup()
+{
+ // very simple leak check
+ QCOMPARE(Movable::instanceCount, m_movableInstanceCount);
+ QCOMPARE(Complex::instanceCount, m_complexInstanceCount);
+}
+
+template <typename Container>
+Container createContainerReference()
+{
+ using V = typename Container::value_type;
+
+ return {V(0), V(1), V(2), V(0)};
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::ranged_ctor_non_associative_impl() const
+{
+ using V = typename Container::value_type;
+
+ // the double V(0) is deliberate
+ const auto reference = createContainerReference<Container>();
+
+ // plain array
+ const V values1[] = { V(0), V(1), V(2), V(0) };
+
+ const Container c1(values1, values1 + sizeof(values1)/sizeof(values1[0]));
+
+ // from QList
+ QList<V> l2;
+ l2 << V(0) << V(1) << V(2) << V(0);
+
+ const Container c2a(l2.begin(), l2.end());
+ const Container c2b(l2.cbegin(), l2.cend());
+
+ // from std::list
+ std::list<V> l3;
+ l3.push_back(V(0));
+ l3.push_back(V(1));
+ l3.push_back(V(2));
+ l3.push_back(V(0));
+ const Container c3a(l3.begin(), l3.end());
+
+ // from const std::list
+ const std::list<V> l3c = l3;
+ const Container c3b(l3c.begin(), l3c.end());
+
+ // from itself
+ const Container c4(reference.begin(), reference.end());
+
+ // from stringsteam (= pure input_iterator)
+ const Container c5 = [&] {
+ {
+ std::stringstream ss;
+ for (auto &v : values1)
+ ss << v << ' ';
+ ss.seekg(0);
+ return Container(std::istream_iterator<V>{ss},
+ std::istream_iterator<V>{});
+ }
+ }();
+
+ QCOMPARE(c1, reference);
+ QCOMPARE(c2a, reference);
+ QCOMPARE(c2b, reference);
+ QCOMPARE(c3a, reference);
+ QCOMPARE(c3b, reference);
+ QCOMPARE(c4, reference);
+ QCOMPARE(c5, reference);
+}
+
+
+// type traits for detecting whether a non-associative container
+// accepts duplicated values, and if it doesn't, whether construction/insertion
+// prefer the new values (overwriting) or the old values (rejecting)
+
+struct ContainerAcceptsDuplicateValues {};
+struct ContainerOverwritesDuplicateValues {};
+struct ContainerRejectsDuplicateValues {};
+
+template<typename Container>
+struct ContainerDuplicatedValuesStrategy {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::vector<T...>> : ContainerAcceptsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<QList<T...>> : ContainerAcceptsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<QVarLengthArray<T...>> : ContainerAcceptsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<VarLengthArray<T...>> : ContainerAcceptsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::list<T...>> : ContainerAcceptsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::forward_list<T...>> : ContainerAcceptsDuplicateValues {};
+
+// assuming https://cplusplus.github.io/LWG/lwg-active.html#2844 resolution
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::set<T...>> : ContainerRejectsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::multiset<T...>> : ContainerAcceptsDuplicateValues {};
+
+// assuming https://cplusplus.github.io/LWG/lwg-active.html#2844 resolution
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::unordered_set<T...>> : ContainerRejectsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<std::unordered_multiset<T...>> : ContainerAcceptsDuplicateValues {};
+
+template<typename ... T>
+struct ContainerDuplicatedValuesStrategy<QSet<T...>> : ContainerRejectsDuplicateValues {};
+
+template<typename Container>
+void non_associative_container_check_duplicates_impl(const std::initializer_list<DuplicateStrategyTestType> &reference, const Container &c, ContainerAcceptsDuplicateValues)
+{
+ // do a deep check for equality, not ordering
+ QVERIFY(std::distance(reference.begin(), reference.end()) == std::distance(c.begin(), c.end()));
+ QVERIFY(std::is_permutation(reference.begin(), reference.end(), c.begin(), &reallyEqual));
+}
+
+enum class IterationOnReference
+{
+ ForwardIteration,
+ ReverseIteration
};
+template<typename Container>
+void non_associative_container_check_duplicates_impl_no_duplicates(const std::initializer_list<DuplicateStrategyTestType> &reference, const Container &c, IterationOnReference ior)
+{
+ std::vector<DuplicateStrategyTestType> valuesAlreadySeen;
+
+ // iterate on reference forward or backwards, depending on ior. this will give
+ // us the expected semantics when checking for duplicated values into c
+ auto it = [&reference, ior]() {
+ switch (ior) {
+ case IterationOnReference::ForwardIteration: return reference.begin();
+ case IterationOnReference::ReverseIteration: return reference.end() - 1;
+ };
+ return std::initializer_list<DuplicateStrategyTestType>::const_iterator();
+ }();
+
+ const auto &end = [&reference, ior]() {
+ switch (ior) {
+ case IterationOnReference::ForwardIteration: return reference.end();
+ case IterationOnReference::ReverseIteration: return reference.begin() - 1;
+ };
+ return std::initializer_list<DuplicateStrategyTestType>::const_iterator();
+ }();
+
+ while (it != end) {
+ const auto &value = *it;
+
+ // check that there is indeed the same value in the container (using operator==)
+ const auto &valueInContainerIterator = std::find(c.begin(), c.end(), value);
+ QVERIFY(valueInContainerIterator != c.end());
+ QVERIFY(value == *valueInContainerIterator);
+
+ // if the value is a duplicate, we don't expect to find it in the container
+ // (when doing a deep comparison). otherwise it should be there
+
+ const auto &valuesAlreadySeenIterator = std::find(valuesAlreadySeen.cbegin(), valuesAlreadySeen.cend(), value);
+ const bool valueIsDuplicated = (valuesAlreadySeenIterator != valuesAlreadySeen.cend());
+
+ const auto &reallyEqualCheck = [&value](const DuplicateStrategyTestType &v) { return reallyEqual(value, v); };
+ QCOMPARE(std::find_if(c.begin(), c.end(), reallyEqualCheck) == c.end(), valueIsDuplicated);
+
+ valuesAlreadySeen.push_back(value);
+
+ switch (ior) {
+ case IterationOnReference::ForwardIteration:
+ ++it;
+ break;
+ case IterationOnReference::ReverseIteration:
+ --it;
+ break;
+ };
+ }
+
+}
+
+template<typename Container>
+void non_associative_container_check_duplicates_impl(const std::initializer_list<DuplicateStrategyTestType> &reference, const Container &c, ContainerRejectsDuplicateValues)
+{
+ non_associative_container_check_duplicates_impl_no_duplicates(reference, c, IterationOnReference::ForwardIteration);
+}
+
+template<typename Container>
+void non_associative_container_check_duplicates_impl(const std::initializer_list<DuplicateStrategyTestType> &reference, const Container &c, ContainerOverwritesDuplicateValues)
+{
+ non_associative_container_check_duplicates_impl_no_duplicates(reference, c, IterationOnReference::ReverseIteration);
+}
+
+template<typename Container>
+void non_associative_container_check_duplicates(const std::initializer_list<DuplicateStrategyTestType> &reference, const Container &c)
+{
+ non_associative_container_check_duplicates_impl(reference, c, ContainerDuplicatedValuesStrategy<Container>());
+}
+
+template<template<class ... T> class Container>
+void tst_ContainerApiSymmetry::non_associative_container_duplicates_strategy() const
+{
+ // first and last are "duplicates" -- they compare equal for operator==,
+ // but they differ when using reallyEqual
+ const std::initializer_list<DuplicateStrategyTestType> reference{ DuplicateStrategyTestType{0},
+ DuplicateStrategyTestType{1},
+ DuplicateStrategyTestType{2},
+ DuplicateStrategyTestType{0} };
+ Container<DuplicateStrategyTestType> c1{reference};
+ non_associative_container_check_duplicates(reference, c1);
+
+ Container<DuplicateStrategyTestType> c2{reference.begin(), reference.end()};
+ non_associative_container_check_duplicates(reference, c2);
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::ranged_ctor_associative_impl() const
+{
+ using K = typename Container::key_type;
+ using V = typename Container::mapped_type;
+
+ // The double K(0) is deliberate. The order of the elements matters:
+ // * for unique-key STL containers, the first one should be the one inserted (cf. LWG 2844)
+ // * for unique-key Qt containers, the last one should be the one inserted
+ // * for multi-key sorted containers, the order of insertion of identical keys is also the
+ // iteration order (which establishes the equality of the containers)
+ // (although nothing of this is being tested here, that deserves its own testing)
+ const Container reference{
+ { K(0), V(1000) },
+ { K(1), V(1001) },
+ { K(2), V(1002) },
+ { K(0), V(1003) }
+ };
+
+ // Note that using anything not convertible to std::pair doesn't work for
+ // std containers. Their ranged construction is defined in terms of
+ // insert(value_type), which for std associative containers is
+ // std::pair<const K, T>.
+
+ // plain array
+ const std::pair<K, V> values1[] = {
+ std::make_pair(K(0), V(1000)),
+ std::make_pair(K(1), V(1001)),
+ std::make_pair(K(2), V(1002)),
+ std::make_pair(K(0), V(1003))
+ };
+
+ const Container c1(values1, values1 + sizeof(values1)/sizeof(values1[0]));
+
+ // from QList
+ QList<std::pair<K, V>> l2;
+ l2 << std::make_pair(K(0), V(1000))
+ << std::make_pair(K(1), V(1001))
+ << std::make_pair(K(2), V(1002))
+ << std::make_pair(K(0), V(1003));
+
+ const Container c2a(l2.begin(), l2.end());
+ const Container c2b(l2.cbegin(), l2.cend());
+
+ // from std::list
+ std::list<std::pair<K, V>> l3;
+ l3.push_back(std::make_pair(K(0), V(1000)));
+ l3.push_back(std::make_pair(K(1), V(1001)));
+ l3.push_back(std::make_pair(K(2), V(1002)));
+ l3.push_back(std::make_pair(K(0), V(1003)));
+ const Container c3a(l3.begin(), l3.end());
+
+ // from const std::list
+ const std::list<std::pair<K, V>> l3c = l3;
+ const Container c3b(l3c.begin(), l3c.end());
+
+ // from itself
+ const Container c4(reference.begin(), reference.end());
+
+ QCOMPARE(c1, reference);
+ QCOMPARE(c2a, reference);
+ QCOMPARE(c2b, reference);
+ QCOMPARE(c3a, reference);
+ QCOMPARE(c3b, reference);
+ QCOMPARE(c4, reference);
+}
+
template <typename Container>
Container make(int size)
{
Container c;
- int i = 1;
- while (size--)
- c.push_back(typename Container::value_type(i++));
+ c.reserve(size);
+ using V = typename Container::value_type;
+ int i = 0;
+ std::generate_n(std::inserter(c, c.end()), size, [&i] { return V(++i); });
+ return c;
+}
+
+template <typename Container>
+Container makeAssociative(int size)
+{
+ using K = typename Container::key_type;
+ using V = typename Container::mapped_type;
+ Container c;
+ for (int i = 1; i <= size; ++i)
+ c.insert(K(i), V(i));
return c;
}
static QString s_string = QStringLiteral("\1\2\3\4\5\6\7");
-template <> QStringRef make(int size) { return s_string.leftRef(size); }
+template <> QString make(int size) { return s_string.left(size); }
template <> QStringView make(int size) { return QStringView(s_string).left(size); }
template <> QLatin1String make(int size) { return QLatin1String("\1\2\3\4\5\6\7", size); }
+template <> QByteArray make(int size) { return QByteArray("\1\2\3\4\5\6\7", size); }
template <typename T> T clean(T &&t) { return std::forward<T>(t); }
-inline QChar clean(QCharRef ch) { return ch; }
-inline char clean(QByteRef ch) { return ch; }
inline char clean(QLatin1Char ch) { return ch.toLatin1(); }
template <typename Container>
+void tst_ContainerApiSymmetry::resize_impl() const
+{
+ using V = typename Container::value_type;
+ using S = typename Container::size_type;
+ auto c = make<Container>(3);
+ QCOMPARE(c.size(), S(3));
+ c.resize(4, V(5));
+ QCOMPARE(std::size(c), S(4));
+ QCOMPARE(c.back(), V(5));
+
+ // ctor/resize symmetry:
+ {
+ Container c1(S(5), V(4));
+ QCOMPARE(c1.size(), S(5));
+
+ Container c2;
+ c2.resize(S(5), V(4));
+ QCOMPARE(c2.size(), S(5));
+
+ QCOMPARE(c1, c2);
+ }
+}
+
+template <typename T>
+[[maybe_unused]]
+constexpr bool is_vector_v = false;
+template <typename...Args>
+constexpr bool is_vector_v<std::vector<Args...>> = true;
+
+template <typename Container, typename Value>
+void wrap_resize(Container &c, typename Container::size_type n, const Value &v)
+{
+#ifdef __GLIBCXX__ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83981
+ if constexpr (is_vector_v<Container>) {
+ while (c.size() < n)
+ c.push_back(v);
+ } else
+#endif
+ {
+ c.resize(n, v);
+ }
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::copesWithValueTypesWithConstMembers_impl()
+{
+ // The problem:
+ //
+ // using V = ConstMember;
+ // V v{42};
+ // assert(v.n == 42); // OK
+ // new (&v) V{24};
+ // assert(v.n == 24); // UB in C++17: v.n could still be 42 (C++17 [basic.life]/8)
+ // // OK in C++20 (C++20 [basic.life]/8)
+ // assert(std::launder(&v)->n == 24); // OK
+ // assert(v.n == 24); // _still_ UB!
+ //
+ // Containers:
+ // - must not expose this problem
+ // - must compile in the first place, even though V
+ // - is not assignable
+ // - is not default-constructible
+
+ using S = typename Container::size_type;
+ using V = typename Container::value_type;
+
+ Container c;
+ // the following are all functions that by rights should not require the type to be
+ // - default-constructible
+ // - assignable
+ // make sure they work
+ c.reserve(S(5));
+ c.shrink_to_fit();
+ wrap_resize(c, 1, V(42));
+ QCOMPARE(c[0], V(42));
+ wrap_resize(c, 2, V(48));
+ QCOMPARE(c[0], V(42));
+ QCOMPARE(c[1], V(48));
+ c.clear();
+ c.emplace_back(24);
+ QCOMPARE(c.front(), V(24));
+ c.push_back(V(41));
+ QCOMPARE(c.back(), V(41));
+ {
+ const auto v142 = V(142);
+ c.push_back(v142);
+ }
+ QCOMPARE(c.size(), S(3));
+ QCOMPARE(c[0], V(24));
+ QCOMPARE(c[1], V(41));
+ QCOMPARE(c[2], V(142));
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::assign_impl() const
+{
+#define CHECK(Arr, ComparisonData, Sz_n, Sz_e) \
+ QCOMPARE(Sz_n, Sz_e); \
+ for (const auto &e : Arr) \
+ QCOMPARE(e, ComparisonData) \
+ /*end*/
+#define RET_CHECK(...) \
+ do { \
+ if constexpr (std::is_void_v<decltype( __VA_ARGS__ )>) { \
+ /* e.g. std::vector */ \
+ __VA_ARGS__ ; \
+ } else { \
+ /* e.g. std::basic_string */ \
+ auto &&r = __VA_ARGS__ ; \
+ QCOMPARE_EQ(&r, &c); \
+ } \
+ } while (false) \
+ /* end */
+ using V = typename Container::value_type;
+ using S = typename Container::size_type;
+ auto tData = V(65);
+ {
+ // fill version
+ auto c = make<Container>(4);
+ const S oldCapacity = c.capacity();
+ RET_CHECK(c.assign(4, tData));
+ CHECK(c, tData, c.size(), S(4));
+ QCOMPARE_EQ(c.capacity(), oldCapacity);
+
+ tData = V(66);
+ c.assign(8, tData); // may reallocate
+ CHECK(c, tData, c.size(), S(8));
+
+ const S grownCapacity = c.capacity();
+ c.assign(0, tData);
+ CHECK(c, tData, c.size(), S(0));
+ QCOMPARE_EQ(c.capacity(), grownCapacity);
+ }
+ {
+ // range version for non input iterator
+ auto c = make<Container>(4);
+ auto iter = make<Container>(1);
+
+ iter.assign(8, tData);
+ RET_CHECK(c.assign(iter.begin(), iter.end())); // may reallocate
+ CHECK(c, tData, c.size(), S(8));
+
+ const S oldCapacity = c.capacity();
+ c.assign(iter.begin(), iter.begin());
+ CHECK(c, tData, c.size(), S(0));
+ QCOMPARE_EQ(c.capacity(), oldCapacity);
+ }
+ {
+ // range version for input iterator
+ auto c = make<Container>(4);
+ const S oldCapacity = c.capacity();
+
+ std::stringstream ss;
+ ss << tData << ' ' << tData << ' ';
+ RET_CHECK(c.assign(std::istream_iterator<V>{ss}, std::istream_iterator<V>{}));
+ CHECK(c, tData, c.size(), S(2));
+ QCOMPARE_EQ(c.capacity(), oldCapacity);
+
+ ss.str("");
+ ss.clear();
+ tData = V(66);
+ ss << tData << ' ' << tData << ' ' << tData << ' ' << tData << ' ';
+ c.assign(std::istream_iterator<V>{ss}, std::istream_iterator<V>{});
+ CHECK(c, tData, c.size(), S(4));
+ QCOMPARE_EQ(c.capacity(), oldCapacity);
+
+ ss.str("");
+ ss.clear();
+ tData = V(67);
+ ss << tData << ' ' << tData << ' ' << tData << ' ' << tData << ' '
+ << tData << ' ' << tData << ' ' << tData << ' ';
+ c.assign(std::istream_iterator<V>{ss}, std::istream_iterator<V>{}); // may reallocate
+ CHECK(c, tData, c.size(), S(7));
+ }
+ {
+ // initializer-list version
+ auto c = make<Container>(4);
+ const S oldCapacity = c.capacity();
+ std::initializer_list<V> list = {tData, tData, tData};
+ RET_CHECK(c.assign(list));
+ CHECK(c, tData, c.size(), S(3));
+ QCOMPARE_EQ(c.capacity(), oldCapacity);
+ }
+
+#undef RET_CHECK
+#undef CHECK
+}
+
+template<typename Container>
void tst_ContainerApiSymmetry::front_back_impl() const
{
using V = typename Container::value_type;
auto c1 = make<Container>(1);
QCOMPARE(clean(c1.front()), V(1));
QCOMPARE(clean(c1.back()), V(1));
- QCOMPARE(clean(qAsConst(c1).front()), V(1));
- QCOMPARE(clean(qAsConst(c1).back()), V(1));
+ QCOMPARE(clean(std::as_const(c1).front()), V(1));
+ QCOMPARE(clean(std::as_const(c1).back()), V(1));
auto c2 = make<Container>(2);
QCOMPARE(clean(c2.front()), V(1));
QCOMPARE(clean(c2.back()), V(2));
- QCOMPARE(clean(qAsConst(c2).front()), V(1));
- QCOMPARE(clean(qAsConst(c2).back()), V(2));
+ QCOMPARE(clean(std::as_const(c2).front()), V(1));
+ QCOMPARE(clean(std::as_const(c2).back()), V(2));
+}
+
+namespace {
+struct Conv {
+ template <typename T>
+ static int toInt(T i) { return i; }
+ static int toInt(QChar ch) { return ch.unicode(); }
+};
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::erase_impl() const
+{
+ using S = typename Container::size_type;
+ using V = typename Container::value_type;
+ auto c = make<Container>(7); // {1, 2, 3, 4, 5, 6, 7}
+ QCOMPARE(c.size(), S(7));
+
+ using q20::erase; // For std::vector
+ auto result = erase(c, V(1));
+ QCOMPARE(result, S(1));
+ QCOMPARE(c.size(), S(6));
+
+ result = erase(c, V(5));
+ QCOMPARE(result, S(1));
+ QCOMPARE(c.size(), S(5));
+
+ result = erase(c, V(123));
+ QCOMPARE(result, S(0));
+ QCOMPARE(c.size(), S(5));
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::erase_if_impl() const
+{
+ using S = typename Container::size_type;
+ using V = typename Container::value_type;
+ auto c = make<Container>(7); // {1, 2, 3, 4, 5, 6, 7}
+ QCOMPARE(c.size(), S(7));
+
+ decltype(c.size()) oldSize, count;
+
+ oldSize = c.size();
+ count = 0;
+
+ using q20::erase_if; // For std::vector
+
+ S result = erase_if(c, [&](V i) { ++count; return Conv::toInt(i) % 2 == 0; });
+ QCOMPARE(result, S(3));
+ QCOMPARE(c.size(), S(4));
+ QCOMPARE(count, oldSize);
+
+ oldSize = c.size();
+ count = 0;
+ result = erase_if(c, [&](V i) { ++count; return Conv::toInt(i) % 123 == 0; });
+ QCOMPARE(result, S(0));
+ QCOMPARE(c.size(), S(4));
+ QCOMPARE(count, oldSize);
+
+ oldSize = c.size();
+ count = 0;
+ result = erase_if(c, [&](V i) { ++count; return Conv::toInt(i) % 3 == 0; });
+ QCOMPARE(result, S(1));
+ QCOMPARE(c.size(), S(3));
+ QCOMPARE(count, oldSize);
+
+ oldSize = c.size();
+ count = 0;
+ result = erase_if(c, [&](V i) { ++count; return Conv::toInt(i) % 2 == 1; });
+ QCOMPARE(result, S(3));
+ QCOMPARE(c.size(), S(0));
+ QCOMPARE(count, oldSize);
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::erase_if_associative_impl() const
+{
+ using S = typename Container::size_type;
+ using K = typename Container::key_type;
+ using V = typename Container::mapped_type;
+ using I = typename Container::iterator;
+ using P = std::pair<const K &, V &>;
+
+ auto c = makeAssociative<Container>(20);
+ QCOMPARE(c.size(), S(20));
+
+ auto result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 2 == 0; });
+ QCOMPARE(result, S(10));
+ QCOMPARE(c.size(), S(10));
+
+ result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 3 == 0; });
+ QCOMPARE(result, S(3));
+ QCOMPARE(c.size(), S(7));
+
+ result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 42 == 0; });
+ QCOMPARE(result, S(0));
+ QCOMPARE(c.size(), S(7));
+
+ result = erase_if(c, [](const P &p) { return Conv::toInt(p.first) % 2 == 1; });
+ QCOMPARE(result, S(7));
+ QCOMPARE(c.size(), S(0));
+
+ // same, but with a predicate taking a Qt iterator
+ c = makeAssociative<Container>(20);
+ QCOMPARE(c.size(), S(20));
+
+ result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 2 == 0; });
+ QCOMPARE(result, S(10));
+ QCOMPARE(c.size(), S(10));
+
+ result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 3 == 0; });
+ QCOMPARE(result, S(3));
+ QCOMPARE(c.size(), S(7));
+
+ result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 42 == 0; });
+ QCOMPARE(result, S(0));
+ QCOMPARE(c.size(), S(7));
+
+ result = erase_if(c, [](const I &it) { return Conv::toInt(it.key()) % 2 == 1; });
+ QCOMPARE(result, S(7));
+ QCOMPARE(c.size(), S(0));
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::member_erase_impl() const
+{
+ using S = typename Container::size_type;
+ using V = typename Container::value_type;
+ const S size = 7;
+ auto c = make<Container>(size); // {1, 2, 3, 4, 5, 6, 7}
+ QCOMPARE(c.size(), size);
+
+ auto copy = c;
+ // Container::erase() returns an iterator, not const_iterator
+ auto it = c.erase(c.cbegin(), c.cbegin());
+ static_assert(std::is_same_v<decltype(it), typename Container::iterator>);
+ QCOMPARE(c.size(), size);
+ const V newVal{100};
+ QCOMPARE_NE(*it, newVal);
+ *it = newVal;
+ QCOMPARE(it, c.cbegin());
+ QCOMPARE(*c.cbegin(), newVal);
+
+ QCOMPARE(std::find(copy.cbegin(), copy.cend(), newVal), copy.cend());
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::member_erase_associative_impl() const
+{
+ using S = typename Container::size_type;
+ using V = typename Container::mapped_type;
+
+ const S size = 20;
+ auto c = makeAssociative<Container>(size);
+ QCOMPARE(c.size(), size);
+
+ // Verify Container::erase() returns iterator, not const_iterator
+ auto it = c.erase(c.cbegin());
+ static_assert(std::is_same_v<decltype(it), typename Container::iterator>);
+ QCOMPARE(c.size(), size - 1);
+ QCOMPARE(it, c.cbegin());
+ const auto current = it.value();
+ it.value() = current + V(5);
+ QCOMPARE(c.cbegin().value(),current + V(5));
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::member_erase_set_impl() const
+{
+ using S = typename Container::size_type;
+
+ const S size = 20;
+ auto c = make<Container>(size);
+ QCOMPARE(c.size(), size);
+
+ // Verify Container::erase() returns iterator, not const_iterator
+ auto it = c.erase(c.cbegin());
+ static_assert(std::is_same_v<decltype(it), typename Container::iterator>);
+ QCOMPARE(c.size(), size - 1);
+ QCOMPARE(it, c.cbegin());
+}
+
+template <typename Container>
+void tst_ContainerApiSymmetry::keyValueRange_impl() const
+{
+ constexpr int COUNT = 20;
+
+ using K = typename Container::key_type;
+ using V = typename Container::mapped_type;
+ QVector<K> keys;
+ keys.reserve(COUNT);
+ QVector<V> values;
+ values.reserve(COUNT);
+
+ auto c = makeAssociative<Container>(COUNT);
+ auto returnC = [&](){ return c; };
+
+ const auto verify = [](QVector<K> v, int count, int offset = 0) -> bool {
+ if (v.size() != count)
+ return false;
+ std::sort(v.begin(), v.end());
+ for (int i = 0; i < count; ++i) {
+ // vector is indexed from 0, but makeAssociative starts from 1
+ if (v[i] != i + 1 + offset)
+ return false;
+ }
+ return true;
+ };
+
+ // Check that the range has the right size
+ auto range = c.asKeyValueRange();
+ QCOMPARE(std::distance(range.begin(), range.end()), COUNT);
+
+ auto constRange = std::as_const(c).asKeyValueRange();
+ QCOMPARE(std::distance(constRange.begin(), constRange.end()), COUNT);
+
+ auto rvalueRange = returnC().asKeyValueRange();
+ QCOMPARE(std::distance(rvalueRange.begin(), rvalueRange.end()), COUNT);
+
+ // auto, mutating
+ keys.clear(); values.clear();
+ for (auto [key, value] : c.asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value);
+ QCOMPARE(c.value(key), value);
+ ++value;
+ QCOMPARE(key, value - 1);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT));
+
+ // auto, non-mutating
+ keys.clear(); values.clear();
+ for (auto [key, value] : c.asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value - 1);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT, 1));
+
+ // auto &&, mutating
+ keys.clear(); values.clear();
+ for (auto &&[key, value] : c.asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value - 1);
+ QCOMPARE(c.value(key), value);
+ ++value;
+ QCOMPARE(key, value - 2);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT, 1));
+
+ // auto, non-mutating (const map)
+ keys.clear(); values.clear();
+ for (auto [key, value] : std::as_const(c).asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value - 2);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT, 2));
+
+ // auto &&, non-mutating (const map)
+ keys.clear(); values.clear();
+ for (auto &&[key, value] : std::as_const(c).asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value - 2);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT, 2));
+
+ // auto, non-mutating (rvalue map)
+ keys.clear(); values.clear();
+ for (auto [key, value] : returnC().asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value - 2);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT, 2));
+
+ // auto &&, non-mutating (rvalue map)
+ keys.clear(); values.clear();
+ for (auto &&[key, value] : returnC().asKeyValueRange()) {
+ keys << key;
+ values << value;
+ QCOMPARE(key, value - 2);
+ QCOMPARE(c.value(key), value);
+ }
+ QVERIFY(verify(keys, COUNT));
+ QVERIFY(verify(values, COUNT, 2));
}
QTEST_APPLESS_MAIN(tst_ContainerApiSymmetry)
diff --git a/tests/auto/corelib/tools/qalgorithms/CMakeLists.txt b/tests/auto/corelib/tools/qalgorithms/CMakeLists.txt
new file mode 100644
index 0000000000..9e87144a4c
--- /dev/null
+++ b/tests/auto/corelib/tools/qalgorithms/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qalgorithms Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qalgorithms LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qalgorithms
+ SOURCES
+ tst_qalgorithms.cpp
+)
diff --git a/tests/auto/corelib/tools/qalgorithms/qalgorithms.pro b/tests/auto/corelib/tools/qalgorithms/qalgorithms.pro
deleted file mode 100644
index 0e6e830185..0000000000
--- a/tests/auto/corelib/tools/qalgorithms/qalgorithms.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qalgorithms
-QT = core testlib
-SOURCES = tst_qalgorithms.cpp
diff --git a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp
index 72299402f0..8d68a7a270 100644
--- a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp
+++ b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "../../../../../src/corelib/tools/qalgorithms.h"
-#include <QtTest/QtTest>
+#include <QTest>
+
+QT_WARNING_DISABLE_DEPRECATED
#include <iostream>
#include <iomanip>
@@ -35,10 +12,10 @@
#include <iterator>
#include <algorithm>
#include <qalgorithms.h>
-#include <QStringList>
-#include <QString>
+#include <QList>
#include <QRandomGenerator>
-#include <QVector>
+#include <QString>
+#include <QStringList>
#define Q_TEST_PERFORMANCE 0
@@ -48,25 +25,9 @@ class tst_QAlgorithms : public QObject
{
Q_OBJECT
private slots:
- void test_qLowerBound_data();
- void test_qLowerBound();
- void test_qUpperBound_data();
- void test_qUpperBound();
- void test_qBinaryFind_data();
- void test_qBinaryFind();
- void qBinaryFindOneEntry();
void swap();
void swap2();
- void sortEmptyList();
- void sortedList();
- void sortAPItest();
- void stableSortTest();
- void stableSortCorrectnessTest_data();
- void stableSortCorrectnessTest();
void convenienceAPI();
- void qCountIterators() const;
- void qCountContainer() const;
- void binaryFindOnLargeContainer() const;
void popCount08_data() { popCount_data_impl(sizeof(quint8 )); }
void popCount16_data() { popCount_data_impl(sizeof(quint16)); }
@@ -96,9 +57,6 @@ private slots:
void countLeading64() { countLeading_impl<quint64>(); }
private:
-#if Q_TEST_PERFORMANCE
- void performance();
-#endif
void popCount_data_impl(size_t sizeof_T_Int);
template <typename T_Int>
void popCount_impl();
@@ -112,151 +70,18 @@ private:
void countLeading_impl();
};
-class TestInt
-{
-public:
- TestInt(int number) :m_number(number) {} ;
- TestInt() : m_number(0) {};
- bool operator<(const TestInt &other) const { ++TestInt::lessThanRefCount; return (m_number < other.m_number); }
- int m_number;
-static long int lessThanRefCount;
-};
-
-long int TestInt::lessThanRefCount;
-
-
-QStringList dataSetTypes = QStringList() << "Random" << "Ascending"
- << "Descending" << "Equal" << "Duplicates" << "Almost Sorted" ;
-
-template <typename DataType>
-QVector<DataType> generateData(QString dataSetType, const int length)
+template <typename T> struct PrintIfFailed
{
- QVector<DataType> container;
- if (dataSetType == "Random") {
- for (int i = 0; i < length; ++i)
- container.append(QRandomGenerator::global()->generate());
- } else if (dataSetType == "Ascending") {
- for (int i = 0; i < length; ++i)
- container.append(i);
- } else if (dataSetType == "Descending") {
- for (int i = 0; i < length; ++i)
- container.append(length - i);
- } else if (dataSetType == "Equal") {
- for (int i = 0; i < length; ++i)
- container.append(43);
- } else if (dataSetType == "Duplicates") {
- for (int i = 0; i < length; ++i)
- container.append(i % 10);
- } else if (dataSetType == "Almost Sorted") {
- for (int i = 0; i < length; ++i)
- container.append(i);
- for (int i = 0; i <= length / 10; ++i) {
- const int iswap = i * 9;
- DataType tmp = container.at(iswap);
- container[iswap] = container.at(iswap + 1);
- container[iswap + 1] = tmp;
- }
+ T value;
+ PrintIfFailed(T v) : value(v) {}
+ ~PrintIfFailed()
+ {
+ if (!QTest::currentTestFailed())
+ return;
+ qWarning() << "Original value was" << Qt::hex << Qt::showbase << T(value);
}
- return container;
-}
-
-struct ResultSet
-{
- int numSorts;
- long int lessThanRefCount;
};
-
-template <typename ContainerType, typename Algorithm>
-ResultSet testRun(ContainerType &container, Algorithm &algorithm, int millisecs)
-{
- TestInt::lessThanRefCount = 0;
- int count = 0;
- QTime t;
- t.start();
- while(t.elapsed() < millisecs) {
- ++count;
- algorithm(container);
- }
- ResultSet result;
- result.numSorts = count;
- result.lessThanRefCount = TestInt::lessThanRefCount;
- return result;
-}
-
-template <typename ContainerType, typename LessThan>
-bool isSorted(ContainerType &container, LessThan lessThan)
-{
- for (int i=0; i < container.count() - 1; ++i)
- if (lessThan(container.at(i+1), container.at(i))) {
- return false;
- }
- return true;
-}
-
-template <typename ContainerType>
-bool isSorted(ContainerType &container)
-{
- return isSorted(container, qLess<typename ContainerType::value_type>());
-}
-
-
-#if Q_TEST_PERFORMANCE
-void printHeader(QStringList &headers)
-{
- cout << setw(10) << setiosflags(ios_base::left) << " ";
- for (int h = 0; h < headers.count(); ++h) {
- cout << setw(20) << setiosflags(ios_base::left) << headers.at(h).toLatin1().constData();
- }
- cout << endl;
-}
-
-template <typename ContainerType>
-void print(ContainerType testContainer)
-{
- typedef typename ContainerType::value_type T;
-
- foreach(T value, testContainer) {
- cout << value << " ";
- }
-
- cout << endl;
-}
-
-template <typename Algorithm, typename DataType>
-QList<ResultSet> testAlgorithm(Algorithm &algorithm, QStringList dataSetTypes, int size, int time)
-{
- QList<ResultSet> results;
- foreach(QString dataSetType, dataSetTypes) {
- QVector<DataType> container = generateData<DataType>(dataSetType, size);
- results.append(testRun(container, algorithm, time));
- if (!isSorted(container))
- qWarning("%s: container is not sorted after test", Q_FUNC_INFO);
- }
- return results;
-}
-
-template <typename Algorithm, typename DataType>
-void testAlgorithm(Algorithm algorithm, QStringList &dataSetTypes)
-{
- QList<int> sizes = QList<int>() << 5 << 15 << 35 << 70 << 200 << 1000 << 10000;
- printHeader(dataSetTypes);
- for (int s = 0; s < sizes.count(); ++s){
- cout << setw(10) << setiosflags(ios_base::left)<< sizes.at(s);
- QList<ResultSet> results =
- testAlgorithm<Algorithm, DataType>(algorithm, dataSetTypes, sizes.at(s), 100);
- foreach(ResultSet result, results) {
- stringstream numSorts;
- numSorts << setiosflags(ios_base::left) << setw(10) << result.numSorts;
- stringstream lessThan;
- lessThan << setiosflags(ios_base::left) << setw(10) << result.lessThanRefCount / result.numSorts;
- cout << numSorts.str() << lessThan.str();
- }
- cout << endl;
- }
-}
-#endif
-
void tst_QAlgorithms::swap()
{
{
@@ -329,42 +154,42 @@ void tst_QAlgorithms::swap()
}
{
- void *a = 0, *b = 0;
+ void *a = nullptr, *b = nullptr;
qSwap(a, b);
}
{
- const void *a = 0, *b = 0;
+ const void *a = nullptr, *b = nullptr;
qSwap(a, b);
}
{
- QString *a = 0, *b = 0;
+ QString *a = nullptr, *b = nullptr;
qSwap(a, b);
}
{
- const QString *a = 0, *b = 0;
+ const QString *a = nullptr, *b = nullptr;
qSwap(a, b);
}
{
- QString **a = 0, **b = 0;
+ QString **a = nullptr, **b = nullptr;
qSwap(a, b);
}
{
- const QString **a = 0, **b = 0;
+ const QString **a = nullptr, **b = nullptr;
qSwap(a, b);
}
{
- QString * const *a = 0, * const *b = 0;
+ QString * const *a = nullptr, * const *b = nullptr;
qSwap(a, b);
}
{
- const QString * const *a = 0, * const *b = 0;
+ const QString * const *a = nullptr, * const *b = nullptr;
qSwap(a, b);
}
}
@@ -391,676 +216,35 @@ void tst_QAlgorithms::swap2()
}
}
-void tst_QAlgorithms::sortEmptyList()
-{
- // Only test if it crashes
- QStringList stringList;
- stringList.sort();
- QVERIFY(true);
-}
-
-void tst_QAlgorithms::sortedList()
-{
- QList<int> list;
- list << 4 << 3 << 6;
-
- ::qSort(list.begin(), list.end());
-
- QCOMPARE(list.count(), 3);
- QCOMPARE(list.at(0), 3);
- QCOMPARE(list.at(1), 4);
- QCOMPARE(list.at(2), 6);
-
- list.insert(qUpperBound(list.begin(), list.end(), 5), 5);
- list.insert(qUpperBound(list.begin(), list.end(), 1), 1);
- list.insert(qUpperBound(list.begin(), list.end(), 8), 8);
-
- QCOMPARE(list.count(), 6);
- QCOMPARE(list.at(0), 1);
- QCOMPARE(list.at(1), 3);
- QCOMPARE(list.at(2), 4);
- QCOMPARE(list.at(3), 5);
- QCOMPARE(list.at(4), 6);
- QCOMPARE(list.at(5), 8);
-}
-
-
-void tst_QAlgorithms::test_qLowerBound_data()
-{
- QTest::addColumn<QList<int> >("data");
- QTest::addColumn<int>("resultValue");
- QTest::addColumn<int>("resultIndex");
-
- QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2 << 1;
-}
-
-void tst_QAlgorithms::test_qLowerBound()
-{
- QFETCH(QList<int>, data);
- QFETCH(int, resultValue);
- QFETCH(int, resultIndex);
-
-
- QCOMPARE(qLowerBound(data.constBegin(), data.constEnd(), resultValue), data.constBegin() + resultIndex);
- QCOMPARE(qLowerBound(data.begin(), data.end(), resultValue), data.begin() + resultIndex);
- QCOMPARE(qLowerBound(data, resultValue), data.constBegin() + resultIndex);
- QCOMPARE(qLowerBound(data.constBegin(), data.constEnd(), resultValue, qLess<int>()), data.constBegin() + resultIndex);
-}
-
-void tst_QAlgorithms::test_qUpperBound_data()
-{
- QTest::addColumn<QList<int> >("data");
- QTest::addColumn<int>("resultValue");
- QTest::addColumn<int>("resultIndex");
-
- QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2 << 3;
-}
-
-void tst_QAlgorithms::test_qUpperBound()
-{
- QFETCH(QList<int>, data);
- QFETCH(int, resultValue);
- QFETCH(int, resultIndex);
-
- QCOMPARE(qUpperBound(data.constBegin(), data.constEnd(), resultValue), data.constBegin() + resultIndex);
- QCOMPARE(qUpperBound(data.begin(), data.end(), resultValue), data.begin() + resultIndex);
- QCOMPARE(qUpperBound(data, resultValue), data.constBegin() + resultIndex);
- QCOMPARE(qUpperBound(data.constBegin(), data.constEnd(), resultValue, qLess<int>()), data.constBegin() + resultIndex);
-}
-
-void tst_QAlgorithms::test_qBinaryFind_data()
-{
- QTest::addColumn<QList<int> >("data");
- QTest::addColumn<int>("resultValue"); // -42 means not found
-
- QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2;
- QTest::newRow("sorted-end") << (QList<int>() << -5 << -2 << 0 << 8) << 8;
- QTest::newRow("sorted-beginning") << (QList<int>() << -5 << -2 << 0 << 8) << -5;
- QTest::newRow("sorted-duplicate-beginning") << (QList<int>() << -5 << -5 << -2 << 0 << 8) << -5;
- QTest::newRow("empty") << (QList<int>()) << -42;
- QTest::newRow("not found 1 ") << (QList<int>() << 1 << 5 << 8 << 65) << -42;
- QTest::newRow("not found 2 ") << (QList<int>() << -456 << -5 << 8 << 65) << -42;
-}
-
-void tst_QAlgorithms::test_qBinaryFind()
-{
- QFETCH(QList<int>, data);
- QFETCH(int, resultValue);
-
- //-42 means not found
- if (resultValue == -42) {
- QVERIFY(qBinaryFind(data.constBegin(), data.constEnd(), resultValue) == data.constEnd());
- QVERIFY(qBinaryFind(data, resultValue) == data.constEnd());
- QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue) == data.end());
- QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue, qLess<int>()) == data.end());
- return;
- }
-
- QCOMPARE(*qBinaryFind(data.constBegin(), data.constEnd(), resultValue), resultValue);
- QCOMPARE(*qBinaryFind(data.begin(), data.end(), resultValue), resultValue);
- QCOMPARE(*qBinaryFind(data, resultValue), resultValue);
- QCOMPARE(*qBinaryFind(data.constBegin(), data.constEnd(), resultValue, qLess<int>()), resultValue);
-}
-
-void tst_QAlgorithms::qBinaryFindOneEntry()
-{
- QList<int> list;
- list << 2;
-
- QVERIFY(::qBinaryFind(list.constBegin(), list.constEnd(), 2) != list.constEnd());
-}
-
-
-void tst_QAlgorithms::sortAPItest()
-{
- QVector<int> testVector = generateData<int>("Random", 101);
- qSort(testVector);
- QVERIFY(isSorted(testVector));
- qSort(testVector.begin(), testVector.end());
- QVERIFY(isSorted(testVector));
- qSort(testVector.begin(), testVector.end(), qLess<int>());
- QVERIFY(isSorted(testVector));
-
- testVector = generateData<int>("Random", 71);
- qStableSort(testVector);
- QVERIFY(isSorted(testVector));
- qStableSort(testVector.begin(), testVector.end());
- QVERIFY(isSorted(testVector));
- qStableSort(testVector.begin(), testVector.end(), qLess<int>());
- QVERIFY(isSorted(testVector));
-
- QList<int> testList = generateData<int>("Random", 101).toList();
- qSort(testList);
- QVERIFY(isSorted(testList));
- qSort(testList.begin(), testList.end());
- QVERIFY(isSorted(testList));
- qSort(testList.begin(), testList.end(), qLess<int>());
- QVERIFY(isSorted(testList));
-
- testList = generateData<int>("Random", 71).toList();
- qStableSort(testList);
- QVERIFY(isSorted(testList));
- qStableSort(testList.begin(), testList.end());
- QVERIFY(isSorted(testList));
- qStableSort(testList.begin(), testList.end(), qLess<int>());
- QVERIFY(isSorted(testList));
-}
-
-
-class StableSortTest
-{
-public:
- StableSortTest(){};
- StableSortTest(int Major, int Minor) : Major(Major), Minor(Minor) {}
- bool operator<(const StableSortTest &other) const {return (Major < other.Major); }
- bool testMinor(const StableSortTest &other) const {return Minor < other.Minor; }
-
-int Major;
-int Minor;
-};
-
-ostream &operator<<(ostream &out, const StableSortTest& obj) { out << obj.Major << "-" << obj.Minor; return out; }
-
-QVector<StableSortTest> createStableTestVector()
-{
- QVector<StableSortTest> stableTestVector;
- for (int i=500; i>=0; --i) {
- for (int j=0; j<10; ++j) {
- stableTestVector.append(StableSortTest(i, j));
- }
- }
- return stableTestVector;
-}
-
-template <typename ContainerType, typename LessThan>
-bool isStableSorted(ContainerType &container, LessThan lessThan)
-{
- for (int i=0; i < container.count() - 1; ++i) {
- //not sorted?
- if (lessThan(container.at(i + 1), container.at(i)))
- return false;
- // equal?
- if (lessThan(container.at(i), container.at(i + 1)))
- continue;
- // minor version?
- if(container.at(i + 1).testMinor(container.at(i)))
- return false;
- }
- return true;
-}
-
-void tst_QAlgorithms::stableSortTest()
-{
- // Selftests:
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- qSort(stableTestVector.begin(), stableTestVector.end(), qLess<StableSortTest>());
- QVERIFY(isSorted(stableTestVector, qLess<StableSortTest>()));
- QVERIFY(!isStableSorted(stableTestVector, qLess<StableSortTest>()));
- }
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- qSort(stableTestVector.begin(), stableTestVector.end(), qGreater<StableSortTest>());
- QVERIFY(isSorted(stableTestVector, qGreater<StableSortTest>()));
- QVERIFY(!isStableSorted(stableTestVector, qGreater<StableSortTest>()));
- }
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- qSort(stableTestVector.begin(), stableTestVector.end(), qGreater<StableSortTest>());
- QVERIFY(!isSorted(stableTestVector, qLess<StableSortTest>()));
- QVERIFY(!isStableSorted(stableTestVector, qGreater<StableSortTest>()));
- }
-
-
- // Stable sort with qLess
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- std::stable_sort(stableTestVector.begin(), stableTestVector.end(), qLess<StableSortTest>());
- QVERIFY(isSorted(stableTestVector, qLess<StableSortTest>()));
- QVERIFY(isStableSorted(stableTestVector, qLess<StableSortTest>()));
- }
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- qStableSort(stableTestVector.begin(), stableTestVector.end(), qLess<StableSortTest>());
- QVERIFY(isSorted(stableTestVector, qLess<StableSortTest>()));
- QVERIFY(isStableSorted(stableTestVector, qLess<StableSortTest>()));
- }
-
- // Stable sort with qGreater
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- std::stable_sort(stableTestVector.begin(), stableTestVector.end(), qGreater<StableSortTest>());
- QVERIFY(isSorted(stableTestVector, qGreater<StableSortTest>()));
- QVERIFY(isStableSorted(stableTestVector, qGreater<StableSortTest>()));
- }
-
- {
- QVector<StableSortTest> stableTestVector = createStableTestVector();
- qStableSort(stableTestVector.begin(), stableTestVector.end(), qGreater<StableSortTest>());
- QVERIFY(isSorted(stableTestVector, qGreater<StableSortTest>()));
- QVERIFY(isStableSorted(stableTestVector, qGreater<StableSortTest>()));
- }
-}
-
-
-void tst_QAlgorithms::stableSortCorrectnessTest_data()
-{
- const int dataSize = 1000;
- QTest::addColumn<QVector<int> >("unsorted");
- QTest::newRow("From documentation") << (QVector<int>() << 33 << 12 << 68 << 6 << 12);
- QTest::newRow("Equal") << (generateData<int>("Equal", dataSize));
- QTest::newRow("Ascending") << (generateData<int>("Ascending", dataSize));
- QTest::newRow("Descending") << (generateData<int>("Descending", dataSize));
- QTest::newRow("Duplicates") << (generateData<int>("Duplicates", dataSize));
- QTest::newRow("Almost Sorted") << (generateData<int>("Almost Sorted", dataSize));
- QTest::newRow("Random") << (generateData<int>("Random", dataSize));
-}
-
-void tst_QAlgorithms::stableSortCorrectnessTest()
-{
- QFETCH(QVector<int>, unsorted);
-
- QVector<int> sorted = unsorted;
- qStableSort(sorted.begin(), sorted.end());
-
- // Verify that sorted contains the same numbers as unsorted.
- foreach(int value, unsorted) {
- QVERIFY(sorted.contains(value));
- int unsortedCount = 0;
- qCount(unsorted.begin(), unsorted.end(), value, unsortedCount);
- int sortedCount = 0;
- qCount(sorted.begin(), sorted.end(), value, sortedCount);
- QCOMPARE(sortedCount, unsortedCount);
- }
-
- QVERIFY(isSorted(sorted));
-}
-
void tst_QAlgorithms::convenienceAPI()
{
// Compile-test for QAlgorithm convenience functions.
- QList<int> list, list2;
-
- qCopy(list.begin(), list.end(), list2.begin());
- qCopyBackward(list.begin(), list.end(), list2.begin());
- qEqual(list.begin(), list.end(), list2.begin());
-
- qFill(list, 1);
- qFill(list.begin(), list.end(), 1);
-
- qFind(list, 1);
- qFind(list.begin(), list.end(), 1);
-
- int count1 = 0 , count2 = 0, count3 = 0;
- qCount(list, 1, count1);
- qCount(list.begin(), list.end(), 1, count2);
- QCOMPARE(count1, count2);
- QCOMPARE(count2, count3);
-
- qSort(list);
- qSort(list.begin(), list.end());
- qSort(list.begin(), list.end(), qLess<int>());
-
- qStableSort(list);
- qStableSort(list.begin(), list.end());
- qStableSort(list.begin(), list.end(), qLess<int>());
-
- qLowerBound(list, 1);;
- qLowerBound(list.begin(), list.end(), 1);
- qLowerBound(list.begin(), list.end(), 1, qLess<int>());
-
- qUpperBound(list, 1);
- qUpperBound(list.begin(), list.end(), 1);
- qUpperBound(list.begin(), list.end(), 1, qLess<int>());
-
- qBinaryFind(list, 1);
- qBinaryFind(list.begin(), list.end(), 1);
- qBinaryFind(list.begin(), list.end(), 1, qLess<int>());
QList<int *> pointerList;
qDeleteAll(pointerList);
qDeleteAll(pointerList.begin(), pointerList.end());
}
-template <typename DataType>
-class QuickSortHelper
-{
-public:
- void operator()(QVector<DataType> list)
- {
- ::qSort(list);
- }
-};
-
-template <typename DataType>
-class StableSortHelper
-{
-public:
- void operator()(QVector<DataType> list)
- {
- ::qStableSort(list);
- }
-};
-
-template <typename DataType>
-class StlSortHelper
-{
-public:
- void operator()(QVector<DataType> list)
- {
- std::sort(list.begin(), list.end());
- }
-};
-
-template <typename DataType>
-class StlStableSortHelper
-{
-public:
- void operator()(QVector<DataType> list)
- {
- std::stable_sort(list.begin(), list.end());
- }
-};
-
-#if Q_TEST_PERFORMANCE
-void tst_QAlgorithms::performance()
-{
- cout << endl << "Quick sort" << endl;
- testAlgorithm<QuickSortHelper<TestInt>, TestInt>(QuickSortHelper<TestInt>(), dataSetTypes);
- cout << endl << "stable sort" << endl;
- testAlgorithm<StableSortHelper<TestInt>, TestInt>(StableSortHelper<TestInt>(), dataSetTypes);
- cout << endl << "std::sort" << endl;
- testAlgorithm<StlSortHelper<TestInt>, TestInt>(StlSortHelper<TestInt>(), dataSetTypes);
- cout << endl << "std::stable_sort" << endl;
- testAlgorithm<StlStableSortHelper<TestInt>, TestInt>(StlStableSortHelper<TestInt>(), dataSetTypes);
-/*
- cout << endl << "Sorting lists of ints" << endl;
- cout << endl << "Quick sort" << endl;
- testAlgorithm<QuickSortHelper<int>, int>(QuickSortHelper<int>(), dataSetTypes);
- cout << endl << "std::sort" << endl;
- testAlgorithm<StlSortHelper<int>, int>(StlSortHelper<int>(), dataSetTypes);
- cout << endl << "std::stable_sort" << endl;
- testAlgorithm<StlStableSortHelper<int>, int>(StlStableSortHelper<int>(), dataSetTypes);
-*/
-}
-#endif
-
-void tst_QAlgorithms::qCountIterators() const
-{
- QList<int> list;
- list << 3 << 3 << 6 << 6 << 6 << 8;
-
- {
- int countOf7 = 0;
- ::qCount(list.begin(), list.end(), 7, countOf7);
- QCOMPARE(countOf7, 0);
- }
-
- {
- int countOf3 = 0;
- ::qCount(list.begin(), list.end(), 3, countOf3);
- QCOMPARE(countOf3, 2);
- }
-
- {
- int countOf6 = 0;
- ::qCount(list.begin(), list.end(), 6, countOf6);
- QCOMPARE(countOf6, 3);
- }
-
- {
- int countOf8 = 0;
- ::qCount(list.begin(), list.end(), 8, countOf8);
- QCOMPARE(countOf8, 1);
- }
-
- /* Check that we add to the count, not set it. */
- {
- int countOf8 = 5;
- ::qCount(list.begin(), list.end(), 8, countOf8);
- QCOMPARE(countOf8, 6);
- }
-}
-
-void tst_QAlgorithms::qCountContainer() const
-{
- QList<int> list;
- list << 3 << 3 << 6 << 6 << 6 << 8;
-
- {
- int countOf7 = 0;
- ::qCount(list, 7, countOf7);
- QCOMPARE(countOf7, 0);
- }
-
- {
- int countOf3 = 0;
- ::qCount(list, 3, countOf3);
- QCOMPARE(countOf3, 2);
- }
-
- {
- int countOf6 = 0;
- ::qCount(list, 6, countOf6);
- QCOMPARE(countOf6, 3);
- }
-
- {
- int countOf8 = 0;
- ::qCount(list, 8, countOf8);
- QCOMPARE(countOf8, 1);
- }
-
- /* Check that we add to the count, not set it. */
- {
- int countOf8 = 5;
- ::qCount(list, 8, countOf8);
- QCOMPARE(countOf8, 6);
- }
-}
-
-class RAI
-{
- public:
- typedef int difference_type;
- typedef int value_type;
- typedef std::random_access_iterator_tag iterator_category;
- typedef int *pointer;
- typedef int &reference;
-
- RAI(int searched = 5, int hidePos = 4, int len = 10)
- : curPos_(0)
- , length_(len)
- , searchedVal_(searched)
- , searchedValPos_(hidePos)
- {
- }
-
- int at(int pos) const
- {
- if (pos == searchedValPos_) {
- return searchedVal_;
- }
- else if (pos < searchedValPos_) {
- return searchedVal_ - 1;
- }
-
- return searchedVal_ + 1;
- }
-
- RAI begin() const
- {
- RAI rai = *this;
- rai.setCurPos(0);
- return rai;
- }
-
- RAI end() const
- {
- RAI rai = *this;
- rai.setCurPos(length_);
- return rai;
- }
-
- int pos() const
- {
- return curPos();
- }
-
- int size() const
- {
- return length_;
- }
-
- RAI operator+(int i) const
- {
- RAI rai = *this;
- rai.setCurPos( rai.curPos() + i );
- if (rai.curPos() > length_) {
- rai.setCurPos(length_);
- }
- return rai;
- }
-
- RAI operator-(int i) const
- {
- RAI rai = *this;
- rai.setCurPos( rai.curPos() - i );
- if (rai.curPos() < 0) {
- rai.setCurPos(0);
- }
- return rai;
- }
-
- int operator-(const RAI& it) const
- {
- return curPos() - it.curPos();
- }
-
- RAI& operator+=(int i)
- {
- setCurPos( curPos() + i );
- if (curPos() > length_) {
- setCurPos(length_);
- }
- return *this;
- }
-
- RAI& operator-=(int i)
- {
- setCurPos( curPos() - i);
- if (curPos() < 0) {
- setCurPos(0);
- }
- return *this;
- }
-
- RAI& operator++()
- {
- if (curPos() < length_) {
- setCurPos( curPos() + 1 );
- }
- return *this;
- }
-
- RAI operator++(int)
- {
- RAI rai = *this;
-
- if (curPos() < length_) {
- setCurPos( curPos() + 1 );
- }
-
- return rai;
- }
-
- RAI& operator--()
- {
- if (curPos() > 0) {
- setCurPos( curPos() - 1 );
- }
- return *this;
- }
-
- RAI operator--(int)
- {
- RAI rai = *this;
-
- if (curPos() > 0) {
- setCurPos( curPos() - 1 );
- }
-
- return rai;
- }
-
- bool operator==(const RAI& rai) const
- {
- return rai.curPos() == curPos();
- }
-
- bool operator!=(const RAI& rai) const
- {
- return !operator==(rai);
- }
-
- int operator*() const
- {
- return at(curPos());
- }
-
- int operator[](int i) const
- {
- return at(i);
- }
-
- private:
-
- int curPos() const
- {
- return curPos_;
- }
-
- void setCurPos(int pos)
- {
- curPos_ = pos;
- }
-
- int curPos_;
- int length_;
- int searchedVal_;
- int searchedValPos_;
-};
-
-void tst_QAlgorithms::binaryFindOnLargeContainer() const
-{
- const int len = 2 * 1000 * 1000 * 537;
- const int pos = len - 12345;
- RAI rai(5, pos, len);
-
- RAI foundIt = qBinaryFind(rai.begin(), rai.end(), 5);
- QCOMPARE(foundIt.pos(), 1073987655);
-}
-
// alternative implementation of qPopulationCount for comparison:
-static Q_DECL_CONSTEXPR const uint bitsSetInNibble[] = {
+static constexpr const uint bitsSetInNibble[] = {
0, 1, 1, 2, 1, 2, 2, 3,
1, 2, 2, 3, 2, 3, 3, 4,
};
-Q_STATIC_ASSERT(sizeof bitsSetInNibble / sizeof *bitsSetInNibble == 16);
+static_assert(sizeof bitsSetInNibble / sizeof *bitsSetInNibble == 16);
-static Q_DECL_CONSTEXPR uint bitsSetInByte(quint8 byte)
+static constexpr uint bitsSetInByte(quint8 byte)
{
return bitsSetInNibble[byte & 0xF] + bitsSetInNibble[byte >> 4];
}
-static Q_DECL_CONSTEXPR uint bitsSetInShort(quint16 word)
+static constexpr uint bitsSetInShort(quint16 word)
{
return bitsSetInByte(word & 0xFF) + bitsSetInByte(word >> 8);
}
-static Q_DECL_CONSTEXPR uint bitsSetInInt(quint32 word)
+static constexpr uint bitsSetInInt(quint32 word)
{
return bitsSetInShort(word & 0xFFFF) + bitsSetInShort(word >> 16);
}
-static Q_DECL_CONSTEXPR uint bitsSetInInt64(quint64 word)
+static constexpr uint bitsSetInInt64(quint64 word)
{
return bitsSetInInt(word & 0xFFFFFFFF) + bitsSetInInt(word >> 32);
}
@@ -1077,23 +261,26 @@ void tst_QAlgorithms::popCount_data_impl(size_t sizeof_T_Int)
const uint bits = bitsSetInByte(byte);
const quint64 value = static_cast<quint64>(byte);
const quint64 input = value << ((i % sizeof_T_Int) * 8U);
- QTest::addRow("0x%016llx", input) << input << bits;
+ QTest::addRow("%u-bits", i) << input << bits;
}
// and some random ones:
- if (sizeof_T_Int >= 8)
+ if (sizeof_T_Int >= 8) {
for (size_t i = 0; i < 1000; ++i) {
const quint64 input = QRandomGenerator::global()->generate64();
- QTest::addRow("0x%016llx", input) << input << bitsSetInInt64(input);
+ QTest::addRow("random-%zu", i) << input << bitsSetInInt64(input);
}
- else if (sizeof_T_Int >= 2)
- for (size_t i = 0; i < 1000 ; ++i) {
- const quint32 input = QRandomGenerator::global()->generate();
- if (sizeof_T_Int >= 4)
- QTest::addRow("0x%08x", input) << quint64(input) << bitsSetInInt(input);
- else
- QTest::addRow("0x%04x", quint16(input & 0xFFFF)) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF);
+ } else if (sizeof_T_Int >= 2) {
+ for (size_t i = 0; i < 1000 ; ++i) {
+ const quint32 input = QRandomGenerator::global()->generate();
+ if (sizeof_T_Int >= 4) {
+ QTest::addRow("random-%zu", i) << quint64(input) << bitsSetInInt(input);
+ } else {
+ QTest::addRow("random-%zu", i)
+ << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF);
}
+ }
+ }
}
template <typename T_Int>
@@ -1103,22 +290,23 @@ void tst_QAlgorithms::popCount_impl()
QFETCH(uint, expected);
const T_Int value = static_cast<T_Int>(input);
-
+ PrintIfFailed pf(value);
QCOMPARE(qPopulationCount(value), expected);
}
+// Number of test-cases per offset into each size (arbitrary):
+static constexpr int casesPerOffset = 3;
+
void tst_QAlgorithms::countTrailing_data_impl(size_t sizeof_T_Int)
{
using namespace QTest;
addColumn<quint64>("input");
addColumn<uint>("expected");
- int nibs = sizeof_T_Int*2;
-
- newRow(("0x"+QByteArray::number(0,16).rightJustified(nibs,'0')).constData()) << Q_UINT64_C(0) << uint(sizeof_T_Int*8);
+ addRow("0") << Q_UINT64_C(0) << uint(sizeof_T_Int*8);
for (uint i = 0; i < sizeof_T_Int*8; ++i) {
const quint64 input = Q_UINT64_C(1) << i;
- newRow(("0x"+QByteArray::number(input,16).rightJustified(nibs,'0')).constData()) << input << i;
+ addRow("bit-%u", i) << input << i;
}
quint64 type_mask;
@@ -1129,12 +317,12 @@ void tst_QAlgorithms::countTrailing_data_impl(size_t sizeof_T_Int)
// and some random ones:
for (uint i = 0; i < sizeof_T_Int*8; ++i) {
- for (uint j = 0; j < sizeof_T_Int*3; ++j) { // 3 is arbitrary
+ const quint64 b = Q_UINT64_C(1) << i;
+ const quint64 mask = ((~(b - 1)) ^ b) & type_mask;
+ for (uint j = 0; j < sizeof_T_Int * casesPerOffset; ++j) {
const quint64 r = QRandomGenerator::global()->generate64();
- const quint64 b = Q_UINT64_C(1) << i;
- const quint64 mask = ((~(b-1)) ^ b) & type_mask;
const quint64 input = (r&mask) | b;
- newRow(("0x"+QByteArray::number(input,16).rightJustified(nibs,'0')).constData()) << input << i;
+ addRow("%u-bits-random-%u", i, j) << input << i;
}
}
}
@@ -1146,7 +334,7 @@ void tst_QAlgorithms::countTrailing_impl()
QFETCH(uint, expected);
const T_Int value = static_cast<T_Int>(input);
-
+ PrintIfFailed pf(value);
QCOMPARE(qCountTrailingZeroBits(value), expected);
}
@@ -1156,22 +344,20 @@ void tst_QAlgorithms::countLeading_data_impl(size_t sizeof_T_Int)
addColumn<quint64>("input");
addColumn<uint>("expected");
- int nibs = sizeof_T_Int*2;
-
- newRow(("0x"+QByteArray::number(0,16).rightJustified(nibs,'0')).constData()) << Q_UINT64_C(0) << uint(sizeof_T_Int*8);
+ addRow("0") << Q_UINT64_C(0) << uint(sizeof_T_Int*8);
for (uint i = 0; i < sizeof_T_Int*8; ++i) {
const quint64 input = Q_UINT64_C(1) << i;
- newRow(("0x"+QByteArray::number(input,16).rightJustified(nibs,'0')).constData()) << input << uint(sizeof_T_Int*8-i-1);
+ addRow("bit-%u", i) << input << uint(sizeof_T_Int*8-i-1);
}
// and some random ones:
for (uint i = 0; i < sizeof_T_Int*8; ++i) {
- for (uint j = 0; j < sizeof_T_Int*3; ++j) { // 3 is arbitrary
+ const quint64 b = Q_UINT64_C(1) << i;
+ const quint64 mask = b - 1;
+ for (uint j = 0; j < sizeof_T_Int * casesPerOffset; ++j) {
const quint64 r = QRandomGenerator::global()->generate64();
- const quint64 b = Q_UINT64_C(1) << i;
- const quint64 mask = b-1;
const quint64 input = (r&mask) | b;
- newRow(("0x"+QByteArray::number(input,16).rightJustified(nibs,'0')).constData()) << input << uint(sizeof_T_Int*8-i-1);
+ addRow("%u-bits-random-%u", i, j) << input << uint(sizeof_T_Int*8-i-1);
}
}
}
@@ -1183,7 +369,7 @@ void tst_QAlgorithms::countLeading_impl()
QFETCH(uint, expected);
const T_Int value = static_cast<T_Int>(input);
-
+ PrintIfFailed pf(value);
QCOMPARE(qCountLeadingZeroBits(value), expected);
}
diff --git a/tests/auto/corelib/tools/qarraydata/CMakeLists.txt b/tests/auto/corelib/tools/qarraydata/CMakeLists.txt
new file mode 100644
index 0000000000..1d84630de2
--- /dev/null
+++ b/tests/auto/corelib/tools/qarraydata/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qarraydata Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qarraydata LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qarraydata
+ EXCEPTIONS
+ SOURCES
+ simplevector.h
+ tst_qarraydata.cpp
+)
diff --git a/tests/auto/corelib/tools/qarraydata/qarraydata.pro b/tests/auto/corelib/tools/qarraydata/qarraydata.pro
deleted file mode 100644
index ee3faa9ad7..0000000000
--- a/tests/auto/corelib/tools/qarraydata/qarraydata.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TARGET = tst_qarraydata
-SOURCES += $$PWD/tst_qarraydata.cpp
-HEADERS += $$PWD/simplevector.h
-QT = core testlib
-CONFIG += testcase
diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h
index 9dd8b05796..b92cd4a887 100644
--- a/tests/auto/corelib/tools/qarraydata/simplevector.h
+++ b/tests/auto/corelib/tools/qarraydata/simplevector.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QARRAY_TEST_SIMPLE_VECTOR_H
@@ -32,6 +7,7 @@
#include <QtCore/qarraydata.h>
#include <QtCore/qarraydatapointer.h>
+#include <QtCore/qvarlengtharray.h>
#include <algorithm>
@@ -40,61 +16,64 @@ struct SimpleVector
{
private:
typedef QTypedArrayData<T> Data;
+ typedef QArrayDataPointer<T> DataPointer;
public:
typedef T value_type;
- typedef typename Data::iterator iterator;
- typedef typename Data::const_iterator const_iterator;
+ typedef T *iterator;
+ typedef const T *const_iterator;
SimpleVector()
{
}
- explicit SimpleVector(size_t n)
- : d(Data::allocate(n))
+ explicit SimpleVector(size_t n, bool capacityReserved = false)
+ : d(n)
{
if (n)
d->appendInitialize(n);
+ if (capacityReserved)
+ d.setFlag(QArrayData::CapacityReserved);
}
- SimpleVector(size_t n, const T &t)
- : d(Data::allocate(n))
+ SimpleVector(size_t n, const T &t, bool capacityReserved = false)
+ : d(n)
{
if (n)
d->copyAppend(n, t);
+ if (capacityReserved)
+ d.setFlag(QArrayData::CapacityReserved);
}
- SimpleVector(const T *begin, const T *end)
- : d(Data::allocate(end - begin))
+ SimpleVector(const T *begin, const T *end, bool capacityReserved = false)
+ : d(end - begin)
{
if (end - begin)
d->copyAppend(begin, end);
+ if (capacityReserved)
+ d.setFlag(QArrayData::CapacityReserved);
}
- SimpleVector(QArrayDataPointerRef<T> ptr)
- : d(ptr)
+ SimpleVector(Data *header, T *data, size_t len = 0)
+ : d(header, data, len)
{
}
- explicit SimpleVector(Data *ptr)
- : d(ptr)
+ SimpleVector(const QArrayDataPointer<T> &other)
+ : d(other)
{
}
- bool empty() const { return d->size == 0; }
+ bool empty() const { return d.size == 0; }
bool isNull() const { return d.isNull(); }
bool isEmpty() const { return this->empty(); }
- bool isStatic() const { return d->ref.isStatic(); }
- bool isShared() const { return d->ref.isShared(); }
+ bool isStatic() const { return !d.isMutable(); }
+ bool isShared() const { return d->isShared(); }
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- bool isSharable() const { return d->ref.isSharable(); }
- void setSharable(bool sharable) { d.setSharable(sharable); }
-#endif
- size_t size() const { return d->size; }
- size_t capacity() const { return d->alloc; }
+ size_t size() const { return d.size; }
+ size_t capacity() const { return d->constAllocatedCapacity(); }
iterator begin() { detach(); return d->begin(); }
iterator end() { detach(); return d->end(); }
@@ -143,18 +122,19 @@ public:
return;
if (n <= capacity()) {
- if (d->capacityReserved)
+ if (d->flags() & Data::CapacityReserved)
return;
- if (!d->ref.isShared()) {
- d->capacityReserved = 1;
+ if (!d->isShared()) {
+ d.setFlag(Data::CapacityReserved);
return;
}
}
- SimpleVector detached(Data::allocate(qMax(n, size()),
- d->detachFlags() | Data::CapacityReserved));
- if (size())
+ SimpleVector detached(DataPointer(qMax(n, size())));
+ if (size()) {
detached.d->copyAppend(constBegin(), constEnd());
+ detached.d->setFlag(QArrayData::CapacityReserved);
+ }
detached.swap(*this);
}
@@ -163,9 +143,8 @@ public:
if (size() == newSize)
return;
- if (d.needsDetach() || newSize > capacity()) {
- SimpleVector detached(Data::allocate(
- d->detachCapacity(newSize), d->detachFlags()));
+ if (d->needsDetach() || newSize > capacity()) {
+ SimpleVector detached(DataPointer(d->detachCapacity(newSize)));
if (newSize) {
if (newSize < size()) {
const T *const begin = constBegin();
@@ -198,46 +177,10 @@ public:
if (first == last)
return;
- T *const begin = d->begin();
- if (d.needsDetach()
- || capacity() - size() < size_t(last - first)) {
- SimpleVector detached(Data::allocate(
- d->detachCapacity(size() + (last - first)),
- d->detachFlags() | Data::Grow));
-
- detached.d->copyAppend(first, last);
- detached.d->copyAppend(begin, begin + d->size);
- detached.swap(*this);
-
- return;
- }
-
- d->insert(begin, first, last);
+ d->insert(0, first, last - first);
}
- void append(const_iterator first, const_iterator last)
- {
- if (first == last)
- return;
-
- if (d.needsDetach()
- || capacity() - size() < size_t(last - first)) {
- SimpleVector detached(Data::allocate(
- d->detachCapacity(size() + (last - first)),
- d->detachFlags() | Data::Grow));
-
- if (d->size) {
- const T *const begin = constBegin();
- detached.d->copyAppend(begin, begin + d->size);
- }
- detached.d->copyAppend(first, last);
- detached.swap(*this);
-
- return;
- }
-
- d->copyAppend(first, last);
- }
+ void append(const_iterator first, const_iterator last) { d->growAppend(first, last); }
void insert(int position, const_iterator first, const_iterator last)
{
@@ -257,37 +200,13 @@ public:
if (first == last)
return;
- const iterator begin = d->begin();
- const iterator where = begin + position;
- const iterator end = begin + d->size;
- if (d.needsDetach()
- || capacity() - size() < size_t(last - first)) {
- SimpleVector detached(Data::allocate(
- d->detachCapacity(size() + (last - first)),
- d->detachFlags() | Data::Grow));
-
- if (position)
- detached.d->copyAppend(begin, where);
- detached.d->copyAppend(first, last);
- detached.d->copyAppend(where, end);
- detached.swap(*this);
-
- return;
- }
-
- if ((first >= where && first < end)
- || (last > where && last <= end)) {
- // Copy overlapping data first and only then shuffle it into place
- iterator start = d->begin() + position;
- iterator middle = d->end();
-
- d->copyAppend(first, last);
- std::rotate(start, middle, d->end());
-
+ if (first >= d.begin() && first <= d.end()) {
+ QVarLengthArray<T> copy(first, last);
+ insert(position, copy.begin(), copy.end());
return;
}
- d->insert(where, first, last);
+ d->insert(position, first, last - first);
}
void erase(iterator first, iterator last)
@@ -298,10 +217,8 @@ public:
const T *const begin = d->begin();
const T *const end = begin + d->size;
- if (d.needsDetach()) {
- SimpleVector detached(Data::allocate(
- d->detachCapacity(size() - (last - first)),
- d->detachFlags()));
+ if (d->needsDetach()) {
+ SimpleVector detached(DataPointer(d->detachCapacity(size() - (last - first))));
if (first != begin)
detached.d->copyAppend(begin, first);
detached.d->copyAppend(last, end);
@@ -313,7 +230,7 @@ public:
if (last == end)
d->truncate(end - first);
else
- d->erase(first, last);
+ d->erase(first, last - first);
}
void swap(SimpleVector &other)
@@ -331,10 +248,9 @@ public:
d.detach();
}
- static SimpleVector fromRawData(const T *data, size_t size,
- QArrayData::AllocationOptions options = Data::Default)
+ static SimpleVector fromRawData(const T *data, size_t size)
{
- return SimpleVector(Data::fromRawData(data, size, options));
+ return SimpleVector(QArrayDataPointer<T>::fromRawData(data, size));
}
private:
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index a00c962510..e7a84d57ee 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -1,56 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
+
+#include <QTest>
#include <QtCore/QString>
#include <QtCore/qarraydata.h>
#include "simplevector.h"
-struct SharedNullVerifier
-{
- SharedNullVerifier()
- {
- Q_ASSERT(QArrayData::shared_null[0].ref.isStatic());
- Q_ASSERT(QArrayData::shared_null[0].ref.isShared());
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- Q_ASSERT(QArrayData::shared_null[0].ref.isSharable());
-#endif
- }
-};
-
-// This is meant to verify/ensure that shared_null is not being dynamically
-// initialized and stays away from the order-of-static-initialization fiasco.
-//
-// Of course, if this was to fail, qmake and the build should have crashed and
-// burned before we ever got to this point :-)
-SharedNullVerifier globalInit;
+#include <array>
+#include <tuple>
+#include <algorithm>
+#include <vector>
+#include <set>
+#include <stdexcept>
+#include <functional>
+#include <memory>
+
+// A wrapper for a test function. Calls a function, if it fails, reports failure
+#define RUN_TEST_FUNC(test, ...) \
+do { \
+ test(__VA_ARGS__); \
+ if (QTest::currentTestFailed()) \
+ QFAIL("Test case " #test "(" #__VA_ARGS__ ") failed"); \
+} while (false)
class tst_QArrayData : public QObject
{
@@ -58,8 +32,6 @@ class tst_QArrayData : public QObject
private slots:
void referenceCounting();
- void sharedNullEmpty();
- void staticData();
void simpleVector();
void simpleVectorReserve_data();
void simpleVectorReserve();
@@ -71,20 +43,28 @@ private slots:
void alignment();
void typedData();
void gccBug43247();
+ void arrayOps_data();
void arrayOps();
+ void arrayOps2_data();
void arrayOps2();
- void setSharable_data();
- void setSharable();
+ void arrayOpsExtra_data();
+ void arrayOpsExtra();
void fromRawData_data();
void fromRawData();
void literals();
-#if defined(Q_COMPILER_VARIADIC_MACROS) && defined(Q_COMPILER_LAMBDA)
void variadicLiterals();
-#endif
-#ifdef Q_COMPILER_RVALUE_REFS
void rValueReferences();
-#endif
void grow();
+ void freeSpace_data();
+ void freeSpace();
+ void dataPointerAllocate_data();
+ void dataPointerAllocate();
+ void selfEmplaceBackwards();
+ void selfEmplaceForward();
+#ifndef QT_NO_EXCEPTIONS
+ void relocateWithExceptions_data();
+ void relocateWithExceptions();
+#endif // QT_NO_EXCEPTIONS
};
template <class T> const T &const_(const T &t) { return t; }
@@ -93,158 +73,42 @@ void tst_QArrayData::referenceCounting()
{
{
// Reference counting initialized to 1 (owned)
- QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(1) }, 0, 0, 0, 0 };
-
- QCOMPARE(array.ref.atomic.load(), 1);
+ QArrayData array = { Q_BASIC_ATOMIC_INITIALIZER(1), {}, 0 };
- QVERIFY(!array.ref.isStatic());
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QVERIFY(array.ref.isSharable());
-#endif
+ QCOMPARE(array.ref_.loadRelaxed(), 1);
- QVERIFY(array.ref.ref());
- QCOMPARE(array.ref.atomic.load(), 2);
+ QVERIFY(array.ref());
+ QCOMPARE(array.ref_.loadRelaxed(), 2);
- QVERIFY(array.ref.deref());
- QCOMPARE(array.ref.atomic.load(), 1);
+ QVERIFY(array.deref());
+ QCOMPARE(array.ref_.loadRelaxed(), 1);
- QVERIFY(array.ref.ref());
- QCOMPARE(array.ref.atomic.load(), 2);
+ QVERIFY(array.ref());
+ QCOMPARE(array.ref_.loadRelaxed(), 2);
- QVERIFY(array.ref.deref());
- QCOMPARE(array.ref.atomic.load(), 1);
+ QVERIFY(array.deref());
+ QCOMPARE(array.ref_.loadRelaxed(), 1);
- QVERIFY(!array.ref.deref());
- QCOMPARE(array.ref.atomic.load(), 0);
+ QVERIFY(!array.deref());
+ QCOMPARE(array.ref_.loadRelaxed(), 0);
// Now would be a good time to free/release allocated data
}
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- {
- // Reference counting initialized to 0 (non-sharable)
- QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 };
-
- QCOMPARE(array.ref.atomic.load(), 0);
-
- QVERIFY(!array.ref.isStatic());
- QVERIFY(!array.ref.isSharable());
-
- QVERIFY(!array.ref.ref());
- // Reference counting fails, data should be copied
- QCOMPARE(array.ref.atomic.load(), 0);
-
- QVERIFY(!array.ref.deref());
- QCOMPARE(array.ref.atomic.load(), 0);
-
- // Free/release data
- }
-#endif
-
- {
- // Reference counting initialized to -1 (static read-only data)
- QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
-
- QCOMPARE(array.ref.atomic.load(), -1);
-
- QVERIFY(array.ref.isStatic());
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QVERIFY(array.ref.isSharable());
-#endif
-
- QVERIFY(array.ref.ref());
- QCOMPARE(array.ref.atomic.load(), -1);
-
- QVERIFY(array.ref.deref());
- QCOMPARE(array.ref.atomic.load(), -1);
-
- }
-}
-
-void tst_QArrayData::sharedNullEmpty()
-{
- QArrayData *null = const_cast<QArrayData *>(QArrayData::shared_null);
- QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0);
-
- QVERIFY(null->ref.isStatic());
- QVERIFY(null->ref.isShared());
-
- QVERIFY(empty->ref.isStatic());
- QVERIFY(empty->ref.isShared());
-
- QCOMPARE(null->ref.atomic.load(), -1);
- QCOMPARE(empty->ref.atomic.load(), -1);
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QVERIFY(null->ref.isSharable());
- QVERIFY(empty->ref.isSharable());
-#endif
-
- QVERIFY(null->ref.ref());
- QVERIFY(empty->ref.ref());
-
- QCOMPARE(null->ref.atomic.load(), -1);
- QCOMPARE(empty->ref.atomic.load(), -1);
-
- QVERIFY(null->ref.deref());
- QVERIFY(empty->ref.deref());
-
- QCOMPARE(null->ref.atomic.load(), -1);
- QCOMPARE(empty->ref.atomic.load(), -1);
-
- QVERIFY(null != empty);
-
- QCOMPARE(null->size, 0);
- QCOMPARE(null->alloc, 0u);
- QCOMPARE(null->capacityReserved, 0u);
-
- QCOMPARE(empty->size, 0);
- QCOMPARE(empty->alloc, 0u);
- QCOMPARE(empty->capacityReserved, 0u);
-}
-
-void tst_QArrayData::staticData()
-{
- QStaticArrayData<char, 10> charArray = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(char, 10),
- { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
- };
- QStaticArrayData<int, 10> intArray = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
- };
- QStaticArrayData<double, 10> doubleArray = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(double, 10),
- { 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f }
- };
-
- QCOMPARE(charArray.header.size, 10);
- QCOMPARE(intArray.header.size, 10);
- QCOMPARE(doubleArray.header.size, 10);
-
- QCOMPARE(charArray.header.data(), reinterpret_cast<void *>(&charArray.data));
- QCOMPARE(intArray.header.data(), reinterpret_cast<void *>(&intArray.data));
- QCOMPARE(doubleArray.header.data(), reinterpret_cast<void *>(&doubleArray.data));
}
void tst_QArrayData::simpleVector()
{
- QArrayData data0 = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
- QStaticArrayData<int, 7> data1 = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 7),
- { 0, 1, 2, 3, 4, 5, 6 }
- };
-
+ int data[] = { 0, 1, 2, 3, 4, 5, 6 };
int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
SimpleVector<int> v1;
SimpleVector<int> v2(v1);
- SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0));
- SimpleVector<int> v4(static_cast<QTypedArrayData<int> *>(&data1.header));
- SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0));
- SimpleVector<int> v6(static_cast<QTypedArrayData<int> *>(&data1.header));
- SimpleVector<int> v7(10, 5);
- SimpleVector<int> v8(array, array + sizeof(array)/sizeof(*array));
+ SimpleVector<int> v3(nullptr, (int *)nullptr, 0);
+ SimpleVector<int> v4(nullptr, data, 0);
+ SimpleVector<int> v5(nullptr, data, 1);
+ SimpleVector<int> v6(nullptr, data, 7);
+ const SimpleVector<int> v7(10, 5);
+ const SimpleVector<int> v8(array, array + sizeof(array)/sizeof(*array));
v3 = v1;
v1.swap(v3);
@@ -263,7 +127,7 @@ void tst_QArrayData::simpleVector()
QVERIFY(v2.isEmpty());
QVERIFY(v3.isEmpty());
QVERIFY(v4.isEmpty());
- QVERIFY(v5.isEmpty());
+ QVERIFY(!v5.isEmpty());
QVERIFY(!v6.isEmpty());
QVERIFY(!v7.isEmpty());
QVERIFY(!v8.isEmpty());
@@ -272,7 +136,7 @@ void tst_QArrayData::simpleVector()
QCOMPARE(v2.size(), size_t(0));
QCOMPARE(v3.size(), size_t(0));
QCOMPARE(v4.size(), size_t(0));
- QCOMPARE(v5.size(), size_t(0));
+ QCOMPARE(v5.size(), size_t(1));
QCOMPARE(v6.size(), size_t(7));
QCOMPARE(v7.size(), size_t(10));
QCOMPARE(v8.size(), size_t(10));
@@ -306,17 +170,6 @@ void tst_QArrayData::simpleVector()
QVERIFY(!v7.isShared());
QVERIFY(!v8.isShared());
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QVERIFY(v1.isSharable());
- QVERIFY(v2.isSharable());
- QVERIFY(v3.isSharable());
- QVERIFY(v4.isSharable());
- QVERIFY(v5.isSharable());
- QVERIFY(v6.isSharable());
- QVERIFY(v7.isSharable());
- QVERIFY(v8.isSharable());
-#endif
-
QVERIFY(v1.isSharedWith(v2));
QVERIFY(v1.isSharedWith(v3));
QVERIFY(v1.isSharedWith(v4));
@@ -332,13 +185,13 @@ void tst_QArrayData::simpleVector()
QVERIFY(v1 == v2);
QVERIFY(v1 == v3);
QVERIFY(v1 == v4);
- QVERIFY(v1 == v5);
+ QVERIFY(v1 != v5);
QVERIFY(!(v1 == v6));
QVERIFY(v1 != v6);
QVERIFY(v4 != v6);
QVERIFY(v5 != v6);
- QVERIFY(!(v1 != v5));
+ QVERIFY(!(v1 == v5));
QVERIFY(v1 < v6);
QVERIFY(!(v6 < v1));
@@ -383,7 +236,7 @@ void tst_QArrayData::simpleVector()
{
int count = 0;
- Q_FOREACH (int value, v7) {
+ for (int value : v7) {
QCOMPARE(value, 5);
++count;
}
@@ -393,7 +246,7 @@ void tst_QArrayData::simpleVector()
{
int count = 0;
- Q_FOREACH (int value, v8) {
+ for (int value : v8) {
QCOMPARE(value, count);
++count;
}
@@ -498,71 +351,6 @@ void tst_QArrayData::simpleVector()
for (int i = 0; i < 120; ++i)
QCOMPARE(v1[i], v8[i % 10]);
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- {
- v7.setSharable(true);
- QVERIFY(v7.isSharable());
-
- SimpleVector<int> copy1(v7);
- QVERIFY(copy1.isSharedWith(v7));
-
- v7.setSharable(false);
- QVERIFY(!v7.isSharable());
-
- QVERIFY(!copy1.isSharedWith(v7));
- QCOMPARE(v7.size(), copy1.size());
- for (size_t i = 0; i < copy1.size(); ++i)
- QCOMPARE(v7[i], copy1[i]);
-
- SimpleVector<int> clone(v7);
- QVERIFY(!clone.isSharedWith(v7));
- QCOMPARE(clone.size(), copy1.size());
- for (size_t i = 0; i < copy1.size(); ++i)
- QCOMPARE(clone[i], copy1[i]);
-
- v7.setSharable(true);
- QVERIFY(v7.isSharable());
-
- SimpleVector<int> copy2(v7);
- QVERIFY(copy2.isSharedWith(v7));
- }
-
- {
- SimpleVector<int> null;
- SimpleVector<int> empty(0, 5);
-
- QVERIFY(null.isSharable());
- QVERIFY(empty.isSharable());
-
- null.setSharable(true);
- empty.setSharable(true);
-
- QVERIFY(null.isSharable());
- QVERIFY(empty.isSharable());
-
- QVERIFY(null.isEmpty());
- QVERIFY(empty.isEmpty());
-
- null.setSharable(false);
- empty.setSharable(false);
-
- QVERIFY(!null.isSharable());
- QVERIFY(!empty.isSharable());
-
- QVERIFY(null.isEmpty());
- QVERIFY(empty.isEmpty());
-
- null.setSharable(true);
- empty.setSharable(true);
-
- QVERIFY(null.isSharable());
- QVERIFY(empty.isSharable());
-
- QVERIFY(null.isEmpty());
- QVERIFY(empty.isEmpty());
- }
-#endif
}
Q_DECLARE_METATYPE(SimpleVector<int>)
@@ -577,15 +365,10 @@ void tst_QArrayData::simpleVectorReserve_data()
QTest::newRow("empty") << SimpleVector<int>(0, 42) << size_t(0) << size_t(0);
QTest::newRow("non-empty") << SimpleVector<int>(5, 42) << size_t(5) << size_t(5);
- static const QStaticArrayData<int, 15> array = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 15),
- { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } };
- QArrayDataPointerRef<int> p = {
- static_cast<QTypedArrayData<int> *>(
- const_cast<QArrayData *>(&array.header)) };
+ static const int array[] =
+ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
- QTest::newRow("static") << SimpleVector<int>(p) << size_t(0) << size_t(15);
- QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array.data, 15) << size_t(0) << size_t(15);
+ QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array, 15) << size_t(0) << size_t(15);
}
void tst_QArrayData::simpleVectorReserve()
@@ -641,55 +424,34 @@ struct Deallocator
size_t objectSize;
size_t alignment;
- QVector<QArrayData *> headers;
+ QList<QArrayData *> headers;
};
Q_DECLARE_METATYPE(const QArrayData *)
-Q_DECLARE_METATYPE(QArrayData::AllocationOptions)
+Q_DECLARE_METATYPE(QArrayData::ArrayOptions)
void tst_QArrayData::allocate_data()
{
QTest::addColumn<size_t>("objectSize");
QTest::addColumn<size_t>("alignment");
- QTest::addColumn<QArrayData::AllocationOptions>("allocateOptions");
- QTest::addColumn<bool>("isCapacityReserved");
- QTest::addColumn<bool>("isSharable"); // ### Qt6: remove
- QTest::addColumn<const QArrayData *>("commonEmpty");
+ QTest::addColumn<bool>("grow");
struct {
char const *typeName;
size_t objectSize;
size_t alignment;
} types[] = {
- { "char", sizeof(char), Q_ALIGNOF(char) },
- { "short", sizeof(short), Q_ALIGNOF(short) },
- { "void *", sizeof(void *), Q_ALIGNOF(void *) }
+ { "char", sizeof(char), alignof(char) },
+ { "short", sizeof(short), alignof(short) },
+ { "void *", sizeof(void *), alignof(void *) }
};
- QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0);
- QVERIFY(shared_empty);
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable);
- QVERIFY(unsharable_empty);
-#endif
-
struct {
char const *description;
- QArrayData::AllocationOptions allocateOptions;
- bool isCapacityReserved;
- bool isSharable;
- const QArrayData *commonEmpty;
+ bool grow;
} options[] = {
- { "Default", QArrayData::Default, false, true, shared_empty },
- { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty },
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- { "Reserved | Unsharable",
- QArrayData::CapacityReserved | QArrayData::Unsharable, true, false,
- unsharable_empty },
- { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty },
-#endif
- { "Grow", QArrayData::Grow, false, true, shared_empty }
+ { "Default", false },
+ { "Grow", true }
};
for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
@@ -699,48 +461,36 @@ void tst_QArrayData::allocate_data()
+ QLatin1String(": ")
+ QLatin1String(options[j].description)))
<< types[i].objectSize << types[i].alignment
- << options[j].allocateOptions << options[j].isCapacityReserved
- << options[j].isSharable << options[j].commonEmpty;
+ << options[j].grow;
}
void tst_QArrayData::allocate()
{
QFETCH(size_t, objectSize);
QFETCH(size_t, alignment);
- QFETCH(QArrayData::AllocationOptions, allocateOptions);
- QFETCH(bool, isCapacityReserved);
- QFETCH(const QArrayData *, commonEmpty);
+ QFETCH(bool, grow);
// Minimum alignment that can be requested is that of QArrayData.
// Typically, this alignment is sizeof(void *) and ensured by malloc.
- size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData));
-
- // Shared Empty
- QCOMPARE(QArrayData::allocate(objectSize, minAlignment, 0,
- QArrayData::AllocationOptions(allocateOptions)), commonEmpty);
+ size_t minAlignment = qMax(alignment, alignof(QArrayData));
Deallocator keeper(objectSize, minAlignment);
keeper.headers.reserve(1024);
- for (int capacity = 1; capacity <= 1024; capacity <<= 1) {
- QArrayData *data = QArrayData::allocate(objectSize, minAlignment,
- capacity, QArrayData::AllocationOptions(allocateOptions));
+ for (qsizetype capacity = 1; capacity <= 1024; capacity <<= 1) {
+ QArrayData *data;
+ void *dataPointer = QArrayData::allocate(&data, objectSize, minAlignment, capacity, grow ? QArrayData::Grow : QArrayData::KeepSize);
+
keeper.headers.append(data);
- QCOMPARE(data->size, 0);
- if (allocateOptions & QArrayData::Grow)
- QVERIFY(data->alloc > uint(capacity));
+ if (grow)
+ QCOMPARE_GE(data->allocatedCapacity(), capacity);
else
- QCOMPARE(data->alloc, uint(capacity));
- QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QFETCH(bool, isSharable);
- QCOMPARE(data->ref.isSharable(), isSharable);
-#endif
+ QCOMPARE(data->allocatedCapacity(), capacity);
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
- ::memset(data->data(), 'A', objectSize * capacity);
+ ::memset(dataPointer, 'A', objectSize * capacity);
}
}
@@ -748,52 +498,41 @@ void tst_QArrayData::reallocate()
{
QFETCH(size_t, objectSize);
QFETCH(size_t, alignment);
- QFETCH(QArrayData::AllocationOptions, allocateOptions);
- QFETCH(bool, isCapacityReserved);
-
- // Maximum alignment that can be requested is that of QArrayData,
- // otherwise, we can't use reallocate().
- Q_ASSERT(alignment <= Q_ALIGNOF(QArrayData));
+ QFETCH(bool, grow);
// Minimum alignment that can be requested is that of QArrayData.
// Typically, this alignment is sizeof(void *) and ensured by malloc.
- size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData));
+ size_t minAlignment = qMax(alignment, alignof(QArrayData));
int capacity = 10;
Deallocator keeper(objectSize, minAlignment);
- QArrayData *data = QArrayData::allocate(objectSize, minAlignment, capacity,
- QArrayData::AllocationOptions(allocateOptions) & ~QArrayData::Grow);
+ QArrayData *data;
+ void *dataPointer = QArrayData::allocate(&data, objectSize, minAlignment, capacity, grow ? QArrayData::Grow : QArrayData::KeepSize);
keeper.headers.append(data);
- memset(data->data(), 'A', objectSize * capacity);
- data->size = capacity;
+ memset(dataPointer, 'A', objectSize * capacity);
// now try to reallocate
int newCapacity = 40;
- data = QArrayData::reallocateUnaligned(data, objectSize, newCapacity,
- QArrayData::AllocationOptions(allocateOptions));
+ auto pair = QArrayData::reallocateUnaligned(data, dataPointer, objectSize, newCapacity, grow ? QArrayData::Grow : QArrayData::KeepSize);
+ data = pair.first;
+ dataPointer = pair.second;
QVERIFY(data);
keeper.headers.clear();
keeper.headers.append(data);
- QCOMPARE(data->size, capacity);
- if (allocateOptions & QArrayData::Grow)
- QVERIFY(data->alloc > uint(newCapacity));
+ if (grow)
+ QVERIFY(data->allocatedCapacity() > newCapacity);
else
- QCOMPARE(data->alloc, uint(newCapacity));
- QCOMPARE(data->capacityReserved, uint(isCapacityReserved));
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QFETCH(bool, isSharable);
- QCOMPARE(data->ref.isSharable(), isSharable);
-#endif
+ QCOMPARE(data->allocatedCapacity(), newCapacity);
for (int i = 0; i < capacity; ++i)
- QCOMPARE(static_cast<char *>(data->data())[i], 'A');
+ QCOMPARE(static_cast<char *>(dataPointer)[i], 'A');
}
class Unaligned
{
- char dummy[8];
+ Q_DECL_UNUSED_MEMBER char dummy[8];
};
void tst_QArrayData::alignment_data()
@@ -812,95 +551,51 @@ void tst_QArrayData::alignment()
// Minimum alignment that can be requested is that of QArrayData.
// Typically, this alignment is sizeof(void *) and ensured by malloc.
- size_t minAlignment = qMax(alignment, Q_ALIGNOF(QArrayData));
+ size_t minAlignment = qMax(alignment, alignof(QArrayData));
Deallocator keeper(sizeof(Unaligned), minAlignment);
keeper.headers.reserve(100);
for (int i = 0; i < 100; ++i) {
- QArrayData *data = QArrayData::allocate(sizeof(Unaligned),
- minAlignment, 8, QArrayData::Default);
+ QArrayData *data;
+ void *dataPointer = QArrayData::allocate(&data, sizeof(Unaligned), minAlignment, 8, QArrayData::KeepSize);
keeper.headers.append(data);
QVERIFY(data);
- QCOMPARE(data->size, 0);
- QVERIFY(data->alloc >= uint(8));
+ QVERIFY(data->allocatedCapacity() >= uint(8));
// These conditions should hold as long as header and array are
// allocated together
- QVERIFY(data->offset >= qptrdiff(sizeof(QArrayData)));
- QVERIFY(data->offset <= qptrdiff(sizeof(QArrayData)
- + minAlignment - Q_ALIGNOF(QArrayData)));
+ qptrdiff offset = reinterpret_cast<char *>(dataPointer) -
+ reinterpret_cast<char *>(data);
+ QVERIFY(offset >= qptrdiff(sizeof(QArrayData)));
+ QVERIFY(offset <= qptrdiff(sizeof(QArrayData)
+ + minAlignment - alignof(QArrayData)));
// Data is aligned
- QCOMPARE(quintptr(quintptr(data->data()) % alignment), quintptr(0u));
+ QCOMPARE(quintptr(quintptr(dataPointer) % alignment), quintptr(0u));
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
- ::memset(data->data(), 'A', sizeof(Unaligned) * 8);
+ ::memset(dataPointer, 'A', sizeof(Unaligned) * 8);
}
}
void tst_QArrayData::typedData()
{
- QStaticArrayData<int, 10> data = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
- };
- QCOMPARE(data.header.size, 10);
-
- {
- QTypedArrayData<int> *array =
- static_cast<QTypedArrayData<int> *>(&data.header);
- QCOMPARE(array->data(), data.data);
-
- int j = 0;
- for (QTypedArrayData<int>::iterator iter = array->begin();
- iter != array->end(); ++iter, ++j)
- QCOMPARE((const int *)iter, data.data + j);
- QCOMPARE(j, 10);
- }
-
- {
- const QTypedArrayData<int> *array =
- static_cast<const QTypedArrayData<int> *>(&data.header);
-
- QCOMPARE(array->data(), data.data);
-
- int j = 0;
- for (QTypedArrayData<int>::const_iterator iter = array->begin();
- iter != array->end(); ++iter, ++j)
- QCOMPARE((const int *)iter, data.data + j);
- QCOMPARE(j, 10);
- }
-
- {
- QTypedArrayData<int> *null = QTypedArrayData<int>::sharedNull();
- QTypedArrayData<int> *empty = QTypedArrayData<int>::allocate(0);
-
- QVERIFY(null != empty);
-
- QCOMPARE(null->size, 0);
- QCOMPARE(empty->size, 0);
-
- QCOMPARE(null->begin(), null->end());
- QCOMPARE(empty->begin(), empty->end());
- }
-
-
{
Deallocator keeper(sizeof(char),
- Q_ALIGNOF(QTypedArrayData<char>::AlignmentDummy));
- QArrayData *array = QTypedArrayData<char>::allocate(10);
+ alignof(QTypedArrayData<char>::AlignmentDummy));
+ QPair<QTypedArrayData<char> *, char *> pair = QTypedArrayData<char>::allocate(10);
+ QArrayData *array = pair.first;
keeper.headers.append(array);
QVERIFY(array);
- QCOMPARE(array->size, 0);
- QCOMPARE(array->alloc, 10u);
+ QCOMPARE(array->allocatedCapacity(), qsizetype(10));
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
- ::memset(array->data(), 0, 10 * sizeof(char));
+ ::memset(pair.second, 0, 10 * sizeof(char));
keeper.headers.clear();
QTypedArrayData<short>::deallocate(array);
@@ -910,17 +605,17 @@ void tst_QArrayData::typedData()
{
Deallocator keeper(sizeof(short),
- Q_ALIGNOF(QTypedArrayData<short>::AlignmentDummy));
- QArrayData *array = QTypedArrayData<short>::allocate(10);
+ alignof(QTypedArrayData<short>::AlignmentDummy));
+ QPair<QTypedArrayData<short> *, short *> pair = QTypedArrayData<short>::allocate(10);
+ QArrayData *array = pair.first;
keeper.headers.append(array);
QVERIFY(array);
- QCOMPARE(array->size, 0);
- QCOMPARE(array->alloc, 10u);
+ QCOMPARE(array->allocatedCapacity(), qsizetype(10));
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
- ::memset(array->data(), 0, 10 * sizeof(short));
+ ::memset(pair.second, 0, 10 * sizeof(short));
keeper.headers.clear();
QTypedArrayData<short>::deallocate(array);
@@ -930,17 +625,17 @@ void tst_QArrayData::typedData()
{
Deallocator keeper(sizeof(double),
- Q_ALIGNOF(QTypedArrayData<double>::AlignmentDummy));
- QArrayData *array = QTypedArrayData<double>::allocate(10);
+ alignof(QTypedArrayData<double>::AlignmentDummy));
+ QPair<QTypedArrayData<double> *, double *> pair = QTypedArrayData<double>::allocate(10);
+ QArrayData *array = pair.first;
keeper.headers.append(array);
QVERIFY(array);
- QCOMPARE(array->size, 0);
- QCOMPARE(array->alloc, 10u);
+ QCOMPARE(array->allocatedCapacity(), qsizetype(10));
// Check that the allocated array can be used. Best tested with a
// memory checker, such as valgrind, running.
- ::memset(array->data(), 0, 10 * sizeof(double));
+ ::memset(pair.second, 0, 10 * sizeof(double));
keeper.headers.clear();
QTypedArrayData<double>::deallocate(array);
@@ -953,7 +648,7 @@ void tst_QArrayData::gccBug43247()
{
// This test tries to verify QArrayData is not affected by GCC optimizer
// bug #43247.
- // Reported on GCC 4.4.3, Linux, affects QVector
+ // Reported on GCC 4.4.3, Linux, affects QList
QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (3)");
QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (4)");
@@ -962,7 +657,7 @@ void tst_QArrayData::gccBug43247()
QTest::ignoreMessage(QtDebugMsg, "GCC Optimization bug #43247 not triggered (7)");
SimpleVector<int> array(10, 0);
- // QVector<int> vector(10, 0);
+ // QList<int> list(10, 0);
for (int i = 0; i < 10; ++i) {
if (i >= 3 && i < 8)
@@ -972,7 +667,7 @@ void tst_QArrayData::gccBug43247()
// line lets the compiler assume i == 0, and the conditional above is
// skipped.
QVERIFY(array.at(i) == 0);
- // QVERIFY(vector.at(i) == 0);
+ // QVERIFY(list.at(i) == 0);
}
}
@@ -1033,11 +728,25 @@ struct CountedObject
static size_t liveCount;
};
+bool operator==(const CountedObject &lhs, const CountedObject &rhs)
+{
+ return lhs.id == rhs.id; // TODO: anything better than this?
+}
+
size_t CountedObject::liveCount = 0;
+void tst_QArrayData::arrayOps_data()
+{
+ QTest::addColumn<bool>("capacityReserved");
+
+ QTest::newRow("default") << false;
+ QTest::newRow("capacity-reserved") << true;
+}
+
void tst_QArrayData::arrayOps()
{
- CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker)
+ QFETCH(bool, capacityReserved);
+ CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker);
const int intArray[5] = { 80, 101, 100, 114, 111 };
const QString stringArray[5] = {
@@ -1049,9 +758,12 @@ void tst_QArrayData::arrayOps()
};
const CountedObject objArray[5];
- QVERIFY(!QTypeInfo<int>::isComplex && !QTypeInfo<int>::isStatic);
- QVERIFY(QTypeInfo<QString>::isComplex && !QTypeInfo<QString>::isStatic);
- QVERIFY(QTypeInfo<CountedObject>::isComplex && QTypeInfo<CountedObject>::isStatic);
+ static_assert(!QTypeInfo<int>::isComplex);
+ static_assert(QTypeInfo<int>::isRelocatable);
+ static_assert(QTypeInfo<QString>::isComplex);
+ static_assert(QTypeInfo<QString>::isRelocatable);
+ static_assert(QTypeInfo<CountedObject>::isComplex);
+ static_assert(!QTypeInfo<CountedObject>::isRelocatable);
QCOMPARE(CountedObject::liveCount, size_t(5));
for (size_t i = 0; i < 5; ++i)
@@ -1059,9 +771,9 @@ void tst_QArrayData::arrayOps()
////////////////////////////////////////////////////////////////////////////
// copyAppend (I)
- SimpleVector<int> vi(intArray, intArray + 5);
- SimpleVector<QString> vs(stringArray, stringArray + 5);
- SimpleVector<CountedObject> vo(objArray, objArray + 5);
+ SimpleVector<int> vi(intArray, intArray + 5, capacityReserved);
+ SimpleVector<QString> vs(stringArray, stringArray + 5, capacityReserved);
+ SimpleVector<CountedObject> vo(objArray, objArray + 5, capacityReserved);
QCOMPARE(CountedObject::liveCount, size_t(10));
for (int i = 0; i < 5; ++i) {
@@ -1087,9 +799,9 @@ void tst_QArrayData::arrayOps()
QString referenceString = QLatin1String("reference");
CountedObject referenceObject;
- vi = SimpleVector<int>(5, referenceInt);
- vs = SimpleVector<QString>(5, referenceString);
- vo = SimpleVector<CountedObject>(5, referenceObject);
+ vi = SimpleVector<int>(5, referenceInt, capacityReserved);
+ vs = SimpleVector<QString>(5, referenceString, capacityReserved);
+ vo = SimpleVector<CountedObject>(5, referenceObject, capacityReserved);
QCOMPARE(vi.size(), size_t(5));
QCOMPARE(vs.size(), size_t(5));
@@ -1101,8 +813,11 @@ void tst_QArrayData::arrayOps()
QVERIFY(vs[i].isSharedWith(referenceString));
QCOMPARE(vo[i].id, referenceObject.id);
- QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
- | CountedObject::DefaultConstructed);
+
+ // A temporary object is created as DefaultConstructed |
+ // CopyConstructed, then it is used instead of the original value to
+ // construct elements in the container which are CopyConstructed only
+ //QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed);
}
////////////////////////////////////////////////////////////////////////////
@@ -1152,8 +867,14 @@ void tst_QArrayData::arrayOps()
QVERIFY(vs[i].isSharedWith(stringArray[i % 5]));
QCOMPARE(vo[i].id, objArray[i % 5].id);
- QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed
- | CountedObject::CopyAssigned);
+
+ // Insertion at begin (prepend) caused the elements to move, meaning
+ // that instead of being displaced, newly added elements got constructed
+ // in uninitialized memory with DefaultConstructed | CopyConstructed
+ // ### QArrayData::insert does copy assign some of the values, so this test doesn't
+ // work
+// QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed
+// | CountedObject::CopyConstructed);
}
for (int i = 5; i < 15; ++i) {
@@ -1161,8 +882,8 @@ void tst_QArrayData::arrayOps()
QVERIFY(vs[i].isSharedWith(stringArray[i % 5]));
QCOMPARE(vo[i].id, objArray[i % 5].id);
- QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
- | CountedObject::CopyAssigned);
+// QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
+// | CountedObject::CopyAssigned);
}
for (int i = 15; i < 20; ++i) {
@@ -1170,8 +891,8 @@ void tst_QArrayData::arrayOps()
QVERIFY(vs[i].isSharedWith(referenceString));
QCOMPARE(vo[i].id, referenceObject.id);
- QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
- | CountedObject::CopyAssigned);
+// QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
+// | CountedObject::CopyAssigned);
}
for (int i = 20; i < 25; ++i) {
@@ -1186,8 +907,8 @@ void tst_QArrayData::arrayOps()
// Depending on implementation of rotate, final assignment can be:
// - straight from source: DefaultConstructed | CopyAssigned
// - through a temporary: CopyConstructed | CopyAssigned
- QCOMPARE(vo[i].flags & CountedObject::CopyAssigned,
- int(CountedObject::CopyAssigned));
+// QCOMPARE(vo[i].flags & CountedObject::CopyAssigned,
+// int(CountedObject::CopyAssigned));
}
for (int i = 25; i < 30; ++i) {
@@ -1195,20 +916,26 @@ void tst_QArrayData::arrayOps()
QVERIFY(vs[i].isSharedWith(referenceString));
QCOMPARE(vo[i].id, referenceObject.id);
- QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
- | CountedObject::CopyAssigned);
+// QCOMPARE(int(vo[i].flags), CountedObject::CopyConstructed
+// | CountedObject::CopyAssigned);
}
}
+void tst_QArrayData::arrayOps2_data()
+{
+ arrayOps_data();
+}
+
void tst_QArrayData::arrayOps2()
{
- CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker)
+ QFETCH(bool, capacityReserved);
+ CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker);
////////////////////////////////////////////////////////////////////////////
// appendInitialize
- SimpleVector<int> vi(5);
- SimpleVector<QString> vs(5);
- SimpleVector<CountedObject> vo(5);
+ SimpleVector<int> vi(5, capacityReserved);
+ SimpleVector<QString> vs(5, capacityReserved);
+ SimpleVector<CountedObject> vo(5, capacityReserved);
QCOMPARE(vi.size(), size_t(5));
QCOMPARE(vs.size(), size_t(5));
@@ -1317,6 +1044,8 @@ void tst_QArrayData::arrayOps2()
QVERIFY(vs[i].isNull());
QCOMPARE(vo[i].id, i);
+ // Erasing not from begin always shifts left - consistency with
+ // std::vector::erase. Elements before erase position are not affected.
QCOMPARE(int(vo[i].flags), CountedObject::DefaultConstructed
| CountedObject::CopyConstructed);
}
@@ -1340,154 +1069,631 @@ void tst_QArrayData::arrayOps2()
}
}
-Q_DECLARE_METATYPE(QArrayDataPointer<int>)
+void tst_QArrayData::arrayOpsExtra_data()
+{
+ dataPointerAllocate_data();
+}
-static inline bool arrayIsFilledWith(const QArrayDataPointer<int> &array,
- int fillValue, size_t size)
+void tst_QArrayData::arrayOpsExtra()
{
- const int *iter = array->begin();
- const int *const end = array->end();
+ QSKIP("Skipped while changing QArrayData operations.", SkipAll);
+ QFETCH(QArrayData::GrowthPosition, GrowthPosition);
+ CountedObject::LeakChecker leakChecker; Q_UNUSED(leakChecker);
+
+ constexpr size_t inputSize = 5;
+ const std::array<int, inputSize> intArray = { 80, 101, 100, 114, 111 };
+ const std::array<QString, inputSize> stringArray = {
+ QLatin1String("just"), QLatin1String("for"), QLatin1String("testing"), QLatin1String("a"),
+ QLatin1String("vector")
+ };
+ const std::array<CountedObject, inputSize> objArray;
- for (size_t i = 0; i < size; ++i, ++iter)
- if (*iter != fillValue)
- return false;
+ QVERIFY(!QTypeInfo<int>::isComplex && QTypeInfo<int>::isRelocatable);
+ QVERIFY(QTypeInfo<QString>::isComplex && QTypeInfo<QString>::isRelocatable);
+ QVERIFY(QTypeInfo<CountedObject>::isComplex && !QTypeInfo<CountedObject>::isRelocatable);
- if (iter != end)
- return false;
+ QCOMPARE(CountedObject::liveCount, inputSize);
+ for (size_t i = 0; i < 5; ++i)
+ QCOMPARE(objArray[i].id, i);
- return true;
-}
+ const auto setupDataPointers = [&GrowthPosition] (size_t capacity, size_t initialSize = 0) {
+ const qsizetype alloc = qsizetype(capacity);
+ auto i = QArrayDataPointer<int>::allocateGrow(QArrayDataPointer<int>(), alloc, GrowthPosition);
+ auto s = QArrayDataPointer<QString>::allocateGrow(QArrayDataPointer<QString>(), alloc, GrowthPosition);
+ auto o = QArrayDataPointer<CountedObject>::allocateGrow(QArrayDataPointer<CountedObject>(), alloc, GrowthPosition);
+ if (initialSize) {
+ i->appendInitialize(initialSize);
+ s->appendInitialize(initialSize);
+ o->appendInitialize(initialSize);
+ }
-void tst_QArrayData::setSharable_data()
-{
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QTest::addColumn<QArrayDataPointer<int> >("array");
- QTest::addColumn<size_t>("size");
- QTest::addColumn<size_t>("capacity");
- QTest::addColumn<bool>("isCapacityReserved");
- QTest::addColumn<int>("fillValue");
+ // assign unique values
+ std::generate(i.begin(), i.end(), [] () { static int i = 0; return i++; });
+ std::generate(s.begin(), s.end(), [] () { static int i = 0; return QString::number(i++); });
+ std::generate(o.begin(), o.end(), [] () { return CountedObject(); });
+ return std::make_tuple(i, s, o);
+ };
- QArrayDataPointer<int> null;
- QArrayDataPointer<int> empty; empty.clear();
+ const auto cloneArrayDataPointer = [] (auto &dataPointer, size_t capacity) {
+ using ArrayPointer = std::decay_t<decltype(dataPointer)>;
+ ArrayPointer copy{qsizetype(capacity)};
+ copy->copyAppend(dataPointer.begin(), dataPointer.end());
+ return copy;
+ };
- static QStaticArrayData<int, 10> staticArrayData = {
- Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(int, 10),
- { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
- };
+ // Test allocation first
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ auto [intData, strData, objData] = setupDataPointers(inputSize);
+ QVERIFY(intData.size == 0);
+ QVERIFY(intData.d_ptr() != nullptr);
+ QVERIFY(size_t(intData.constAllocatedCapacity()) >= inputSize);
+ QVERIFY(intData.data() != nullptr);
+
+ QVERIFY(strData.size == 0);
+ QVERIFY(strData.d_ptr() != nullptr);
+ QVERIFY(size_t(strData.constAllocatedCapacity()) >= inputSize);
+ QVERIFY(strData.data() != nullptr);
+
+ QVERIFY(objData.size == 0);
+ QVERIFY(objData.d_ptr() != nullptr);
+ QVERIFY(size_t(objData.constAllocatedCapacity()) >= inputSize);
+ QVERIFY(objData.data() != nullptr);
+ }
- QArrayDataPointer<int> emptyReserved(QTypedArrayData<int>::allocate(5,
- QArrayData::CapacityReserved));
- QArrayDataPointer<int> nonEmpty(QTypedArrayData<int>::allocate(5,
- QArrayData::Default));
- QArrayDataPointer<int> nonEmptyExtraCapacity(
- QTypedArrayData<int>::allocate(10, QArrayData::Default));
- QArrayDataPointer<int> nonEmptyReserved(QTypedArrayData<int>::allocate(15,
- QArrayData::CapacityReserved));
- QArrayDataPointer<int> staticArray(
- static_cast<QTypedArrayData<int> *>(&staticArrayData.header));
- QArrayDataPointer<int> rawData(
- QTypedArrayData<int>::fromRawData(staticArrayData.data, 10));
-
- nonEmpty->copyAppend(5, 1);
- nonEmptyExtraCapacity->copyAppend(5, 1);
- nonEmptyReserved->copyAppend(7, 2);
-
- QTest::newRow("shared-null") << null << size_t(0) << size_t(0) << false << 0;
- QTest::newRow("shared-empty") << empty << size_t(0) << size_t(0) << false << 0;
- // unsharable-empty implicitly tested in shared-empty
- QTest::newRow("empty-reserved") << emptyReserved << size_t(0) << size_t(5) << true << 0;
- QTest::newRow("non-empty") << nonEmpty << size_t(5) << size_t(5) << false << 1;
- QTest::newRow("non-empty-extra-capacity") << nonEmptyExtraCapacity << size_t(5) << size_t(10) << false << 1;
- QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2;
- QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3;
- QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3;
-#endif
-}
+ // copyAppend (iterator version)
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testCopyAppend = [&] (auto &dataPointer, auto first, auto last) {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+ const size_t distance = std::distance(first, last);
+
+ dataPointer->appendIteratorRange(first, last);
+ QCOMPARE(size_t(dataPointer.size), originalSize + distance);
+ size_t i = 0;
+ for (; i < originalSize; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], *(first + (i - originalSize)));
+ };
-void tst_QArrayData::setSharable()
-{
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QFETCH(QArrayDataPointer<int>, array);
- QFETCH(size_t, size);
- QFETCH(size_t, capacity);
- QFETCH(bool, isCapacityReserved);
- QFETCH(int, fillValue);
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+ // empty range
+ const std::array<int, 0> emptyIntArray{};
+ const std::array<QString, 0> emptyStrArray{};
+ const std::array<CountedObject, 0> emptyObjArray{};
+ RUN_TEST_FUNC(testCopyAppend, intData, emptyIntArray.begin(), emptyIntArray.end());
+ RUN_TEST_FUNC(testCopyAppend, strData, emptyStrArray.begin(), emptyStrArray.end());
+ RUN_TEST_FUNC(testCopyAppend, objData, emptyObjArray.begin(), emptyObjArray.end());
+
+ // from arbitrary iterators
+ RUN_TEST_FUNC(testCopyAppend, intData, intArray.begin(), intArray.end());
+ RUN_TEST_FUNC(testCopyAppend, strData, stringArray.begin(), stringArray.end());
+ RUN_TEST_FUNC(testCopyAppend, objData, objArray.begin(), objArray.end());
+
+ // append to full
+ const size_t intDataFreeSpace = intData.freeSpaceAtEnd();
+// QVERIFY(intDataFreeSpace > 0);
+ const size_t strDataFreeSpace = strData.freeSpaceAtEnd();
+// QVERIFY(strDataFreeSpace > 0);
+ const size_t objDataFreeSpace = objData.freeSpaceAtEnd();
+// QVERIFY(objDataFreeSpace > 0);
+ const std::vector<int> intVec(intDataFreeSpace, int(55));
+ const std::vector<QString> strVec(strDataFreeSpace, QLatin1String("filler"));
+ const std::vector<CountedObject> objVec(objDataFreeSpace, CountedObject());
+ RUN_TEST_FUNC(testCopyAppend, intData, intVec.begin(), intVec.end());
+ RUN_TEST_FUNC(testCopyAppend, strData, strVec.begin(), strVec.end());
+ RUN_TEST_FUNC(testCopyAppend, objData, objVec.begin(), objVec.end());
+ QCOMPARE(intData.size, intData.constAllocatedCapacity() - intData.freeSpaceAtBegin());
+ QCOMPARE(strData.size, strData.constAllocatedCapacity() - strData.freeSpaceAtBegin());
+ QCOMPARE(objData.size, objData.constAllocatedCapacity() - objData.freeSpaceAtBegin());
+ }
- QVERIFY(array->ref.isShared()); // QTest has a copy
- QVERIFY(array->ref.isSharable());
+ // copyAppend (iterator version) - special case of copying from self iterators
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testCopyAppendSelf = [&] (auto &dataPointer, auto first, auto last) {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+ const size_t distance = std::distance(first, last);
+ auto firstCopy = copy->begin() + std::distance(dataPointer->begin(), first);
+
+ dataPointer->copyAppend(first, last);
+ QCOMPARE(size_t(dataPointer.size), originalSize + distance);
+ size_t i = 0;
+ for (; i < originalSize; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], *(firstCopy + (i - originalSize)));
+ };
- QCOMPARE(size_t(array->size), size);
- QCOMPARE(size_t(array->alloc), capacity);
- QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
- QVERIFY(arrayIsFilledWith(array, fillValue, size));
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+ // make no free space at the end
+ intData->appendInitialize(intData.size + intData.freeSpaceAtEnd());
+ strData->appendInitialize(strData.size + strData.freeSpaceAtEnd());
+ objData->appendInitialize(objData.size + objData.freeSpaceAtEnd());
+
+ // make all values unique. this would ensure that we do not have erroneously passed test
+ int i = 0;
+ std::generate(intData.begin(), intData.end(), [&i] () { return i++; });
+ std::generate(strData.begin(), strData.end(), [&i] () { return QString::number(i++); });
+ std::generate(objData.begin(), objData.end(), [] () { return CountedObject(); });
+
+ // sanity checks:
+ if (GrowthPosition & QArrayData::GrowsAtBeginning) {
+ QVERIFY(intData.freeSpaceAtBegin() > 0);
+ QVERIFY(strData.freeSpaceAtBegin() > 0);
+ QVERIFY(objData.freeSpaceAtBegin() > 0);
+ }
+ QVERIFY(intData.freeSpaceAtBegin() <= intData.size);
+ QVERIFY(strData.freeSpaceAtBegin() <= strData.size);
+ QVERIFY(objData.freeSpaceAtBegin() <= objData.size);
+ QVERIFY(intData.freeSpaceAtEnd() == 0);
+ QVERIFY(strData.freeSpaceAtEnd() == 0);
+ QVERIFY(objData.freeSpaceAtEnd() == 0);
+
+ // now, append to full size causing the data to move internally. passed
+ // iterators that refer to the object itself must be used correctly
+ RUN_TEST_FUNC(testCopyAppendSelf, intData, intData.begin(),
+ intData.begin() + intData.freeSpaceAtBegin());
+ RUN_TEST_FUNC(testCopyAppendSelf, strData, strData.begin(),
+ strData.begin() + strData.freeSpaceAtBegin());
+ RUN_TEST_FUNC(testCopyAppendSelf, objData, objData.begin(),
+ objData.begin() + objData.freeSpaceAtBegin());
+ }
- // shared-null becomes shared-empty, may otherwise detach
- array.setSharable(true);
+ // copyAppend (value version)
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testCopyAppend = [&] (auto &dataPointer, size_t n, auto value) {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+
+ dataPointer->copyAppend(n, value);
+ QCOMPARE(size_t(dataPointer.size), originalSize + n);
+ size_t i = 0;
+ for (; i < originalSize; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], value);
+ };
- QVERIFY(array->ref.isSharable());
- QVERIFY(arrayIsFilledWith(array, fillValue, size));
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+ // no values
+ RUN_TEST_FUNC(testCopyAppend, intData, 0, int());
+ RUN_TEST_FUNC(testCopyAppend, strData, 0, QString());
+ RUN_TEST_FUNC(testCopyAppend, objData, 0, CountedObject());
+
+ // several values
+ RUN_TEST_FUNC(testCopyAppend, intData, inputSize, int(5));
+ RUN_TEST_FUNC(testCopyAppend, strData, inputSize, QLatin1String("42"));
+ RUN_TEST_FUNC(testCopyAppend, objData, inputSize, CountedObject());
+
+ // from self
+ RUN_TEST_FUNC(testCopyAppend, intData, 2, intData.data()[3]);
+ RUN_TEST_FUNC(testCopyAppend, strData, 2, strData.data()[3]);
+ RUN_TEST_FUNC(testCopyAppend, objData, 2, objData.data()[3]);
+
+ // append to full
+ const size_t intDataFreeSpace = intData.constAllocatedCapacity() - intData.size;
+ QVERIFY(intDataFreeSpace > 0);
+ const size_t strDataFreeSpace = strData.constAllocatedCapacity() - strData.size;
+ QVERIFY(strDataFreeSpace > 0);
+ const size_t objDataFreeSpace = objData.constAllocatedCapacity() - objData.size;
+ QVERIFY(objDataFreeSpace > 0);
+ RUN_TEST_FUNC(testCopyAppend, intData, intDataFreeSpace, int(-1));
+ RUN_TEST_FUNC(testCopyAppend, strData, strDataFreeSpace, QLatin1String("foo"));
+ RUN_TEST_FUNC(testCopyAppend, objData, objDataFreeSpace, CountedObject());
+ QCOMPARE(intData.size, intData.constAllocatedCapacity());
+ QCOMPARE(strData.size, strData.constAllocatedCapacity());
+ QCOMPARE(objData.size, objData.constAllocatedCapacity());
+ }
+ // copyAppend (value version) - special case of copying self value
{
- QArrayDataPointer<int> copy(array);
- QVERIFY(array->ref.isShared());
- QVERIFY(array->ref.isSharable());
- QCOMPARE(copy.data(), array.data());
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testCopyAppendSelf = [&] (auto &dataPointer, size_t n, const auto &value) {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+ auto valueCopy = value;
+
+ dataPointer->copyAppend(n, value);
+ QCOMPARE(size_t(dataPointer.size), originalSize + n);
+ size_t i = 0;
+ for (; i < originalSize; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], valueCopy);
+ };
+
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+ // make no free space at the end
+ intData->appendInitialize(intData.size + intData.freeSpaceAtEnd());
+ strData->appendInitialize(strData.size + strData.freeSpaceAtEnd());
+ objData->appendInitialize(objData.size + objData.freeSpaceAtEnd());
+
+ // make all values unique. this would ensure that we do not have erroneously passed test
+ int i = 0;
+ std::generate(intData.begin(), intData.end(), [&i] () { return i++; });
+ std::generate(strData.begin(), strData.end(), [&i] () { return QString::number(i++); });
+ std::generate(objData.begin(), objData.end(), [] () { return CountedObject(); });
+
+ // sanity checks:
+ if (GrowthPosition & QArrayData::GrowsAtBeginning) {
+ QVERIFY(intData.freeSpaceAtBegin() > 0);
+ QVERIFY(strData.freeSpaceAtBegin() > 0);
+ QVERIFY(objData.freeSpaceAtBegin() > 0);
+ }
+ QVERIFY(intData.freeSpaceAtEnd() == 0);
+ QVERIFY(strData.freeSpaceAtEnd() == 0);
+ QVERIFY(objData.freeSpaceAtEnd() == 0);
+
+ // now, append to full size causing the data to move internally. passed
+ // value that refers to the object itself must be used correctly
+ RUN_TEST_FUNC(testCopyAppendSelf, intData, intData.freeSpaceAtBegin(), intData.data()[0]);
+ RUN_TEST_FUNC(testCopyAppendSelf, strData, strData.freeSpaceAtBegin(), strData.data()[0]);
+ RUN_TEST_FUNC(testCopyAppendSelf, objData, objData.freeSpaceAtBegin(), objData.data()[0]);
}
- // Unshare, must detach
- array.setSharable(false);
+ // moveAppend
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ // now there's only one version that accepts "T*" as input parameters
+ const auto testMoveAppend = [&] (auto &dataPointer, const auto &source)
+ {
+ const size_t originalSize = dataPointer.size;
+ const size_t addedSize = std::distance(source.begin(), source.end());
+ auto sourceCopy = source;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+
+ dataPointer->moveAppend(sourceCopy.data(), sourceCopy.data() + sourceCopy.size());
+ QCOMPARE(size_t(dataPointer.size), originalSize + addedSize);
+ size_t i = 0;
+ for (; i < originalSize; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], source[i - originalSize]);
+ };
- // Immutability (alloc == 0) is lost on detach, as is additional capacity
- // if capacityReserved flag is not set.
- if ((capacity == 0 && size != 0)
- || (!isCapacityReserved && capacity > size))
- capacity = size;
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+ // empty range
+ RUN_TEST_FUNC(testMoveAppend, intData, std::array<int, 0>{});
+ RUN_TEST_FUNC(testMoveAppend, strData, std::array<QString, 0>{});
+ RUN_TEST_FUNC(testMoveAppend, objData, std::array<CountedObject, 0>{});
+
+ // non-empty range
+ RUN_TEST_FUNC(testMoveAppend, intData, intArray);
+ RUN_TEST_FUNC(testMoveAppend, strData, stringArray);
+ RUN_TEST_FUNC(testMoveAppend, objData, objArray);
+
+ // append to full
+ const size_t intDataFreeSpace = intData.constAllocatedCapacity() - intData.size;
+ QVERIFY(intDataFreeSpace > 0);
+ const size_t strDataFreeSpace = strData.constAllocatedCapacity() - strData.size;
+ QVERIFY(strDataFreeSpace > 0);
+ const size_t objDataFreeSpace = objData.constAllocatedCapacity() - objData.size;
+ QVERIFY(objDataFreeSpace > 0);
+ RUN_TEST_FUNC(testMoveAppend, intData, std::vector<int>(intDataFreeSpace, int(55)));
+ RUN_TEST_FUNC(testMoveAppend, strData,
+ std::vector<QString>(strDataFreeSpace, QLatin1String("barbaz")));
+ RUN_TEST_FUNC(testMoveAppend, objData,
+ std::vector<CountedObject>(objDataFreeSpace, CountedObject()));
+ QCOMPARE(intData.size, intData.constAllocatedCapacity());
+ QCOMPARE(strData.size, strData.constAllocatedCapacity());
+ QCOMPARE(objData.size, objData.constAllocatedCapacity());
+ }
- QVERIFY(!array->ref.isShared());
- QVERIFY(!array->ref.isSharable());
+ // moveAppend - special case of moving from self (this is legal yet rather useless)
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testMoveAppendSelf = [&] (auto &dataPointer, auto first, auto last) {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+ const size_t addedSize = std::distance(first, last);
+ const size_t firstPos = std::distance(dataPointer->begin(), first);
+ auto firstCopy = copy->begin() + firstPos;
+
+ dataPointer->moveAppend(first, last);
+ QCOMPARE(size_t(dataPointer.size), originalSize + addedSize);
+ size_t i = 0;
+ for (; i < originalSize; ++i) {
+ if (i >= firstPos && i < (firstPos + addedSize)) // skip "moved from" chunk
+ continue;
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ }
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], *(firstCopy + (i - originalSize)));
+ };
- QCOMPARE(size_t(array->size), size);
- QCOMPARE(size_t(array->alloc), capacity);
- QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
- QVERIFY(arrayIsFilledWith(array, fillValue, size));
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+ // make no free space at the end
+ intData->appendInitialize(intData.size + intData.freeSpaceAtEnd());
+ strData->appendInitialize(strData.size + strData.freeSpaceAtEnd());
+ objData->appendInitialize(objData.size + objData.freeSpaceAtEnd());
+
+ // make all values unique. this would ensure that we do not have erroneously passed test
+ int i = 0;
+ std::generate(intData.begin(), intData.end(), [&i] () { return i++; });
+ std::generate(strData.begin(), strData.end(), [&i] () { return QString::number(i++); });
+ std::generate(objData.begin(), objData.end(), [] () { return CountedObject(); });
+
+ // sanity checks:
+ if (GrowthPosition & QArrayData::GrowsAtBeginning) {
+ QVERIFY(intData.freeSpaceAtBegin() > 0);
+ QVERIFY(strData.freeSpaceAtBegin() > 0);
+ QVERIFY(objData.freeSpaceAtBegin() > 0);
+ }
+ QVERIFY(intData.freeSpaceAtBegin() <= intData.size);
+ QVERIFY(strData.freeSpaceAtBegin() <= strData.size);
+ QVERIFY(objData.freeSpaceAtBegin() <= objData.size);
+ QVERIFY(intData.freeSpaceAtEnd() == 0);
+ QVERIFY(strData.freeSpaceAtEnd() == 0);
+ QVERIFY(objData.freeSpaceAtEnd() == 0);
+
+ // now, append to full size causing the data to move internally. passed
+ // iterators that refer to the object itself must be used correctly
+ RUN_TEST_FUNC(testMoveAppendSelf, intData, intData.begin(),
+ intData.begin() + intData.freeSpaceAtBegin());
+ RUN_TEST_FUNC(testMoveAppendSelf, strData, strData.begin(),
+ strData.begin() + strData.freeSpaceAtBegin());
+ RUN_TEST_FUNC(testMoveAppendSelf, objData, objData.begin(),
+ objData.begin() + objData.freeSpaceAtBegin());
+ }
+ // truncate
{
- QArrayDataPointer<int> copy(array);
- QVERIFY(!array->ref.isShared());
- QVERIFY(!array->ref.isSharable());
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testTruncate = [&] (auto &dataPointer, size_t newSize)
+ {
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+ dataPointer->truncate(newSize);
+ QCOMPARE(size_t(dataPointer.size), newSize);
+ for (size_t i = 0; i < newSize; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ };
- // Null/empty is always shared
- QCOMPARE(copy->ref.isShared(), !(size || isCapacityReserved));
- QVERIFY(copy->ref.isSharable());
+ auto [intData, strData, objData] = setupDataPointers(inputSize, inputSize);
+ // truncate one
+ RUN_TEST_FUNC(testTruncate, intData, inputSize - 1);
+ RUN_TEST_FUNC(testTruncate, strData, inputSize - 1);
+ RUN_TEST_FUNC(testTruncate, objData, inputSize - 1);
- QCOMPARE(size_t(copy->size), size);
- QCOMPARE(size_t(copy->alloc), capacity);
- QCOMPARE(bool(copy->capacityReserved), isCapacityReserved);
- QVERIFY(arrayIsFilledWith(copy, fillValue, size));
+ // truncate all
+ RUN_TEST_FUNC(testTruncate, intData, 0);
+ RUN_TEST_FUNC(testTruncate, strData, 0);
+ RUN_TEST_FUNC(testTruncate, objData, 0);
}
- // Make sharable, again
- array.setSharable(true);
+ // insert
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testInsertRange = [&] (auto &dataPointer, size_t pos, auto first, auto last)
+ {
+ const size_t originalSize = dataPointer.size;
+ const size_t distance = std::distance(first, last);
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+
+ dataPointer->insert(pos, first, last - first);
+ QCOMPARE(size_t(dataPointer.size), originalSize + distance);
+ size_t i = 0;
+ for (; i < pos; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < pos + distance; ++i)
+ QCOMPARE(dataPointer.data()[i], *(first + (i - pos)));
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i - distance]);
+ };
- QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
- QVERIFY(array->ref.isSharable());
+ const auto testInsertValue = [&] (auto &dataPointer, size_t pos, size_t n, auto value)
+ {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+
+ dataPointer->insert(pos, n, value);
+ QCOMPARE(size_t(dataPointer.size), originalSize + n);
+ size_t i = 0;
+ for (; i < pos; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < pos + n; ++i)
+ QCOMPARE(dataPointer.data()[i], value);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i - n]);
+ };
+
+ auto [intData, strData, objData] = setupDataPointers(100, 10);
+
+ // empty ranges
+ RUN_TEST_FUNC(testInsertRange, intData, 0, intArray.data(), intArray.data());
+ RUN_TEST_FUNC(testInsertRange, strData, 0, stringArray.data(), stringArray.data());
+ RUN_TEST_FUNC(testInsertRange, objData, 0, objArray.data(), objArray.data());
+ RUN_TEST_FUNC(testInsertValue, intData, 1, 0, int());
+ RUN_TEST_FUNC(testInsertValue, strData, 1, 0, QString());
+ RUN_TEST_FUNC(testInsertValue, objData, 1, 0, CountedObject());
+
+ // insert at the beginning
+ RUN_TEST_FUNC(testInsertRange, intData, 0, intArray.data(), intArray.data() + 1);
+ RUN_TEST_FUNC(testInsertRange, strData, 0, stringArray.data(), stringArray.data() + 1);
+ RUN_TEST_FUNC(testInsertRange, objData, 0, objArray.data(), objArray.data() + 1);
+ RUN_TEST_FUNC(testInsertValue, intData, 0, 1, int(-100));
+ RUN_TEST_FUNC(testInsertValue, strData, 0, 1, QLatin1String("12"));
+ RUN_TEST_FUNC(testInsertValue, objData, 0, 1, CountedObject());
+
+ // insert into the middle (with the left part of the data being smaller)
+ RUN_TEST_FUNC(testInsertRange, intData, 1, intArray.data() + 2, intArray.data() + 4);
+ RUN_TEST_FUNC(testInsertRange, strData, 1, stringArray.data() + 2, stringArray.data() + 4);
+ RUN_TEST_FUNC(testInsertRange, objData, 1, objArray.data() + 2, objArray.data() + 4);
+ RUN_TEST_FUNC(testInsertValue, intData, 2, 2, int(11));
+ RUN_TEST_FUNC(testInsertValue, strData, 2, 2, QLatin1String("abcdefxdeadbeef"));
+ RUN_TEST_FUNC(testInsertValue, objData, 2, 2, CountedObject());
+
+ // insert into the middle (with the right part of the data being smaller)
+ RUN_TEST_FUNC(testInsertRange, intData, intData.size - 1, intArray.data(),
+ intArray.data() + intArray.size());
+ RUN_TEST_FUNC(testInsertRange, strData, strData.size - 1, stringArray.data(),
+ stringArray.data() + stringArray.size());
+ RUN_TEST_FUNC(testInsertRange, objData, objData.size - 1, objArray.data(),
+ objArray.data() + objArray.size());
+ RUN_TEST_FUNC(testInsertValue, intData, intData.size - 3, 3, int(512));
+ RUN_TEST_FUNC(testInsertValue, strData, strData.size - 3, 3, QLatin1String("foo"));
+ RUN_TEST_FUNC(testInsertValue, objData, objData.size - 3, 3, CountedObject());
+
+ // insert at the end
+ RUN_TEST_FUNC(testInsertRange, intData, intData.size, intArray.data(), intArray.data() + 3);
+ RUN_TEST_FUNC(testInsertRange, strData, strData.size, stringArray.data(),
+ stringArray.data() + 3);
+ RUN_TEST_FUNC(testInsertRange, objData, objData.size, objArray.data(), objArray.data() + 3);
+ RUN_TEST_FUNC(testInsertValue, intData, intData.size, 1, int(-42));
+ RUN_TEST_FUNC(testInsertValue, strData, strData.size, 1, QLatin1String("hello, world"));
+ RUN_TEST_FUNC(testInsertValue, objData, objData.size, 1, CountedObject());
+ }
+
+ // insert - special case of inserting from self value. this test only makes
+ // sense for prepend - insert at begin.
+ {
+ const auto testInsertValueSelf = [&] (auto &dataPointer, size_t n, const auto &value) {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+ auto valueCopy = value;
+
+ dataPointer->insert(0, n, value);
+ QCOMPARE(size_t(dataPointer.size), originalSize + n);
+ size_t i = 0;
+ for (; i < n; ++i)
+ QCOMPARE(dataPointer.data()[i], valueCopy);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i - n]);
+ };
- QCOMPARE(size_t(array->size), size);
- QCOMPARE(size_t(array->alloc), capacity);
- QCOMPARE(bool(array->capacityReserved), isCapacityReserved);
- QVERIFY(arrayIsFilledWith(array, fillValue, size));
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ auto [intData, strData, objData] = setupDataPointers(inputSize * 2, inputSize / 2);
+
+ // make no free space at the begin
+ intData->insert(0, intData.freeSpaceAtBegin(), intData.data()[0]);
+ strData->insert(0, strData.freeSpaceAtBegin(), strData.data()[0]);
+ objData->insert(0, objData.freeSpaceAtBegin(), objData.data()[0]);
+
+ // make all values unique. this would ensure that we do not have erroneously passed test
+ int i = 0;
+ std::generate(intData.begin(), intData.end(), [&i] () { return i++; });
+ std::generate(strData.begin(), strData.end(), [&i] () { return QString::number(i++); });
+ std::generate(objData.begin(), objData.end(), [] () { return CountedObject(); });
+
+ // sanity checks:
+ QVERIFY(intData.freeSpaceAtEnd() > 0);
+ QVERIFY(strData.freeSpaceAtEnd() > 0);
+ QVERIFY(objData.freeSpaceAtEnd() > 0);
+ QVERIFY(intData.freeSpaceAtBegin() == 0);
+ QVERIFY(strData.freeSpaceAtBegin() == 0);
+ QVERIFY(objData.freeSpaceAtBegin() == 0);
+
+ // now, prepend to full size causing the data to move internally. passed
+ // value that refers to the object itself must be used correctly
+ RUN_TEST_FUNC(testInsertValueSelf, intData, intData.freeSpaceAtEnd(),
+ intData.data()[intData.size - 1]);
+ RUN_TEST_FUNC(testInsertValueSelf, strData, strData.freeSpaceAtEnd(),
+ strData.data()[strData.size - 1]);
+ RUN_TEST_FUNC(testInsertValueSelf, objData, objData.freeSpaceAtEnd(),
+ objData.data()[objData.size - 1]);
+ }
+ // emplace
{
- QArrayDataPointer<int> copy(array);
- QVERIFY(array->ref.isShared());
- QCOMPARE(copy.data(), array.data());
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ // testing simple case when emplacing a copy of the same type
+ const auto testEmplace = [&] (auto &dataPointer, size_t pos, auto value)
+ {
+ const size_t originalSize = dataPointer.size;
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+
+ dataPointer->emplace(pos, value);
+ QCOMPARE(size_t(dataPointer.size), originalSize + 1);
+ size_t i = 0;
+ for (; i < pos; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ QCOMPARE(dataPointer.data()[i++], value);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i - 1]);
+ };
+
+ auto [intData, strData, objData] = setupDataPointers(20, 5);
+
+ // emplace at the beginning
+ RUN_TEST_FUNC(testEmplace, intData, 0, int(2));
+ RUN_TEST_FUNC(testEmplace, strData, 0, QLatin1String("foo"));
+ RUN_TEST_FUNC(testEmplace, objData, 0, CountedObject());
+ // emplace into the middle (with the left part of the data being smaller)
+ RUN_TEST_FUNC(testEmplace, intData, 1, int(-1));
+ RUN_TEST_FUNC(testEmplace, strData, 1, QLatin1String("bar"));
+ RUN_TEST_FUNC(testEmplace, objData, 1, CountedObject());
+ // emplace into the middle (with the right part of the data being smaller)
+ RUN_TEST_FUNC(testEmplace, intData, intData.size - 2, int(42));
+ RUN_TEST_FUNC(testEmplace, strData, strData.size - 2, QLatin1String("baz"));
+ RUN_TEST_FUNC(testEmplace, objData, objData.size - 2, CountedObject());
+ // emplace at the end
+ RUN_TEST_FUNC(testEmplace, intData, intData.size, int(123));
+ RUN_TEST_FUNC(testEmplace, strData, strData.size, QLatin1String("bak"));
+ RUN_TEST_FUNC(testEmplace, objData, objData.size, CountedObject());
}
- QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved));
- QVERIFY(array->ref.isSharable());
-#endif
+ // erase
+ {
+ CountedObject::LeakChecker localLeakChecker; Q_UNUSED(localLeakChecker);
+ const auto testErase = [&] (auto &dataPointer, auto first, auto last)
+ {
+ const size_t originalSize = dataPointer.size;
+ const size_t distance = std::distance(first, last);
+ const size_t pos = std::distance(dataPointer.begin(), first);
+ auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
+
+ dataPointer->erase(first, last - first);
+ QCOMPARE(size_t(dataPointer.size), originalSize - distance);
+ size_t i = 0;
+ for (; i < pos; ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i]);
+ for (; i < size_t(dataPointer.size); ++i)
+ QCOMPARE(dataPointer.data()[i], copy.data()[i + distance]);
+ };
+
+ auto [intData, strData, objData] = setupDataPointers(100, 100);
+
+ // erase chunk from the beginning
+ RUN_TEST_FUNC(testErase, intData, intData.begin(), intData.begin() + 10);
+ RUN_TEST_FUNC(testErase, strData, strData.begin(), strData.begin() + 10);
+ RUN_TEST_FUNC(testErase, objData, objData.begin(), objData.begin() + 10);
+
+ // erase chunk from the end
+ RUN_TEST_FUNC(testErase, intData, intData.end() - 10, intData.end());
+ RUN_TEST_FUNC(testErase, strData, strData.end() - 10, strData.end());
+ RUN_TEST_FUNC(testErase, objData, objData.end() - 10, objData.end());
+
+ // erase the middle chunk
+ RUN_TEST_FUNC(testErase, intData, intData.begin() + (intData.size / 2) - 5,
+ intData.begin() + (intData.size / 2) + 5);
+ RUN_TEST_FUNC(testErase, strData, strData.begin() + (strData.size / 2) - 5,
+ strData.begin() + (strData.size / 2) + 5);
+ RUN_TEST_FUNC(testErase, objData, objData.begin() + (objData.size / 2) - 5,
+ objData.begin() + (objData.size / 2) + 5);
+
+ // erase chunk in the left part of the data
+ RUN_TEST_FUNC(testErase, intData, intData.begin() + 1, intData.begin() + 6);
+ RUN_TEST_FUNC(testErase, strData, strData.begin() + 1, strData.begin() + 6);
+ RUN_TEST_FUNC(testErase, objData, objData.begin() + 1, objData.begin() + 6);
+
+ // erase chunk in the right part of the data
+ RUN_TEST_FUNC(testErase, intData, intData.end() - 6, intData.end() - 1);
+ RUN_TEST_FUNC(testErase, strData, strData.end() - 6, strData.end() - 1);
+ RUN_TEST_FUNC(testErase, objData, objData.end() - 6, objData.end() - 1);
+
+ // erase all
+ RUN_TEST_FUNC(testErase, intData, intData.begin(), intData.end());
+ RUN_TEST_FUNC(testErase, strData, strData.begin(), strData.end());
+ RUN_TEST_FUNC(testErase, objData, objData.begin(), objData.end());
+ }
}
+Q_DECLARE_METATYPE(QArrayDataPointer<int>)
+
struct ResetOnDtor
{
ResetOnDtor()
@@ -1521,51 +1727,20 @@ void fromRawData_impl()
{
// Default: Immutable, sharable
SimpleVector<T> raw = SimpleVector<T>::fromRawData(array,
- sizeof(array)/sizeof(array[0]), QArrayData::Default);
+ sizeof(array)/sizeof(array[0]));
QCOMPARE(raw.size(), size_t(11));
QCOMPARE((const T *)raw.constBegin(), array);
QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0])));
- QVERIFY(!raw.isShared());
+ QVERIFY(raw.isShared());
QVERIFY(SimpleVector<T>(raw).isSharedWith(raw));
- QVERIFY(!raw.isShared());
+ QVERIFY(raw.isShared());
// Detach
QCOMPARE(raw.back(), T(11));
QVERIFY((const T *)raw.constBegin() != array);
}
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- {
- // Immutable, unsharable
- SimpleVector<T> raw = SimpleVector<T>::fromRawData(array,
- sizeof(array)/sizeof(array[0]), QArrayData::Unsharable);
-
- QCOMPARE(raw.size(), size_t(11));
- QCOMPARE((const T *)raw.constBegin(), array);
- QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0])));
-
- SimpleVector<T> copy(raw);
- QVERIFY(!copy.isSharedWith(raw));
- QVERIFY(!raw.isShared());
-
- QCOMPARE(copy.size(), size_t(11));
-
- for (size_t i = 0; i < 11; ++i) {
- QCOMPARE(const_(copy)[i], const_(raw)[i]);
- QCOMPARE(const_(copy)[i], T(i + 1));
- }
-
- QCOMPARE(raw.size(), size_t(11));
- QCOMPARE((const T *)raw.constBegin(), array);
- QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0])));
-
- // Detach
- QCOMPARE(raw.back(), T(11));
- QVERIFY((const T *)raw.constBegin() != array);
- }
-#endif
}
void tst_QArrayData::fromRawData_data()
@@ -1597,94 +1772,94 @@ void tst_QArrayData::literals()
{
{
QArrayDataPointer<char> d = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ");
- QCOMPARE(d->size, 10 + 1);
+ QCOMPARE(d.size, 10 + 1);
for (int i = 0; i < 10; ++i)
- QCOMPARE(d->data()[i], char('A' + i));
+ QCOMPARE(d.data()[i], char('A' + i));
}
{
- // wchar_t is not necessarily 2-bytes
- QArrayDataPointer<wchar_t> d = Q_ARRAY_LITERAL(wchar_t, L"ABCDEFGHIJ");
- QCOMPARE(d->size, 10 + 1);
+ QList<char> l(Q_ARRAY_LITERAL(char, "ABCDEFGHIJ"));
+ QCOMPARE(l.size(), 11);
+ QCOMPARE(l.capacity(), 0);
for (int i = 0; i < 10; ++i)
- QCOMPARE(d->data()[i], wchar_t('A' + i));
+ QCOMPARE(l.at(i), char('A' + i));
+
+ (void)l.begin(); // "detach"
+
+ QCOMPARE(l.size(), 11);
+ QVERIFY(l.capacity() >= l.size());
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(l[i], char('A' + i));
}
{
- SimpleVector<char> v = Q_ARRAY_LITERAL(char, "ABCDEFGHIJ");
-
- QVERIFY(!v.isNull());
- QVERIFY(!v.isEmpty());
- QCOMPARE(v.size(), size_t(11));
- // v.capacity() is unspecified, for now
+ // wchar_t is not necessarily 2-bytes
+ QArrayDataPointer<wchar_t> d = Q_ARRAY_LITERAL(wchar_t, L"ABCDEFGHIJ");
+ QCOMPARE(d.size, 10 + 1);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d.data()[i], wchar_t('A' + i));
+ }
-#if defined(Q_COMPILER_VARIADIC_MACROS) && defined(Q_COMPILER_LAMBDA)
- QVERIFY(v.isStatic());
-#endif
+ struct LiteralType {
+ int value;
+ constexpr LiteralType(int v = 0) : value(v) {}
+ };
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QVERIFY(v.isSharable());
-#endif
- QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd());
+ {
+ QArrayDataPointer<LiteralType> d = Q_ARRAY_LITERAL(LiteralType, LiteralType(0), LiteralType(1), LiteralType(2));
+ QCOMPARE(d->size, 3);
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(d->data()[i].value, i);
+ }
- for (int i = 0; i < 10; ++i)
- QCOMPARE(const_(v)[i], char('A' + i));
- QCOMPARE(const_(v)[10], char('\0'));
+ {
+ QList<LiteralType> l(Q_ARRAY_LITERAL(LiteralType, LiteralType(0), LiteralType(1), LiteralType(2)));
+ QCOMPARE(l.size(), 3);
+ QCOMPARE(l.capacity(), 0);
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(l.at(i).value, i);
+ l.squeeze(); // shouldn't detach
+ QCOMPARE(l.capacity(), 0);
+
+ (void)l.begin(); // "detach"
+
+ QCOMPARE(l.size(), 3);
+ QVERIFY(l.capacity() >= l.size());
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(l[i].value, i);
}
}
-#if defined(Q_COMPILER_VARIADIC_MACROS) && defined(Q_COMPILER_LAMBDA)
// Variadic Q_ARRAY_LITERAL need to be available in the current configuration.
void tst_QArrayData::variadicLiterals()
{
{
QArrayDataPointer<int> d =
Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
- QCOMPARE(d->size, 10);
+ QCOMPARE(d.size, 10);
for (int i = 0; i < 10; ++i)
- QCOMPARE(d->data()[i], i);
+ QCOMPARE(d.data()[i], i);
}
{
QArrayDataPointer<char> d = Q_ARRAY_LITERAL(char,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
- QCOMPARE(d->size, 10);
+ QCOMPARE(d.size, 10);
for (int i = 0; i < 10; ++i)
- QCOMPARE(d->data()[i], char('A' + i));
+ QCOMPARE(d.data()[i], char('A' + i));
}
{
QArrayDataPointer<const char *> d = Q_ARRAY_LITERAL(const char *,
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J");
- QCOMPARE(d->size, 10);
+ QCOMPARE(d.size, 10);
for (int i = 0; i < 10; ++i) {
- QCOMPARE(d->data()[i][0], char('A' + i));
- QCOMPARE(d->data()[i][1], '\0');
+ QCOMPARE(d.data()[i][0], char('A' + i));
+ QCOMPARE(d.data()[i][1], '\0');
}
}
-
- {
- SimpleVector<int> v = Q_ARRAY_LITERAL(int, 0, 1, 2, 3, 4, 5, 6);
-
- QVERIFY(!v.isNull());
- QVERIFY(!v.isEmpty());
- QCOMPARE(v.size(), size_t(7));
- // v.capacity() is unspecified, for now
-
- QVERIFY(v.isStatic());
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QVERIFY(v.isSharable());
-#endif
- QCOMPARE((const int *)(v.constBegin() + v.size()), (const int *)v.constEnd());
-
- for (int i = 0; i < 7; ++i)
- QCOMPARE(const_(v)[i], i);
- }
}
-#endif
-#ifdef Q_COMPILER_RVALUE_REFS
// std::remove_reference is in C++11, but requires library support
template <class T> struct RemoveReference { typedef T Type; };
template <class T> struct RemoveReference<T &> { typedef T Type; };
@@ -1706,17 +1881,17 @@ struct CompilerHasCxx11ImplicitMoves
struct DetectConstructor
{
- Q_DECL_CONSTEXPR DetectConstructor()
+ constexpr DetectConstructor()
: constructor(DefaultConstructor)
{
}
- Q_DECL_CONSTEXPR DetectConstructor(const DetectConstructor &)
+ constexpr DetectConstructor(const DetectConstructor &)
: constructor(CopyConstructor)
{
}
- Q_DECL_CONSTEXPR DetectConstructor(DetectConstructor &&)
+ constexpr DetectConstructor(DetectConstructor &&)
: constructor(MoveConstructor)
{
}
@@ -1767,7 +1942,6 @@ void tst_QArrayData::rValueReferences()
QCOMPARE(v3.size(), size_t(1));
QCOMPARE(v3.front(), 42);
}
-#endif
void tst_QArrayData::grow()
{
@@ -1817,5 +1991,546 @@ void tst_QArrayData::grow()
}
}
+void tst_QArrayData::freeSpace_data()
+{
+ QTest::addColumn<size_t>("n");
+
+ for (const size_t n : {1, 3, 5, 7, 16, 25}) {
+ QString suffix = QString::number(n) + QLatin1String("-elements");
+ QTest::newRow(qPrintable(QLatin1String("alloc-") + suffix))
+ << n;
+ }
+}
+
+void tst_QArrayData::freeSpace()
+{
+ QFETCH(size_t, n);
+ const auto testFreeSpace = [] (auto dummy, qsizetype n) {
+ using Type = std::decay_t<decltype(dummy)>;
+ using DataPointer = QArrayDataPointer<Type>;
+ Q_UNUSED(dummy);
+ const qsizetype capacity = n + 1;
+ auto ptr = DataPointer::allocateGrow(DataPointer(), capacity, QArrayData::GrowsAtEnd);
+ const auto alloc = qsizetype(ptr.constAllocatedCapacity());
+ QVERIFY(alloc >= capacity);
+ QCOMPARE(ptr.freeSpaceAtBegin() + ptr.freeSpaceAtEnd(), alloc);
+ };
+ RUN_TEST_FUNC(testFreeSpace, char(0), n);
+ RUN_TEST_FUNC(testFreeSpace, char16_t(0), n);
+ RUN_TEST_FUNC(testFreeSpace, int(0), n);
+ RUN_TEST_FUNC(testFreeSpace, QString(), n);
+ RUN_TEST_FUNC(testFreeSpace, CountedObject(), n);
+}
+
+void tst_QArrayData::dataPointerAllocate_data()
+{
+ QTest::addColumn<QArrayData::GrowthPosition>("GrowthPosition");
+
+ QTest::newRow("at-end") << QArrayData::GrowsAtEnd;
+ QTest::newRow("at-begin") << QArrayData::GrowsAtBeginning;
+}
+
+void tst_QArrayData::dataPointerAllocate()
+{
+ QFETCH(QArrayData::GrowthPosition, GrowthPosition);
+ const auto createDataPointer = [] (qsizetype capacity, auto initValue) {
+ using Type = std::decay_t<decltype(initValue)>;
+ Q_UNUSED(initValue);
+ return QArrayDataPointer<Type>(capacity);
+ };
+
+ const auto testRealloc = [&] (qsizetype capacity, qsizetype newSize, auto initValue) {
+ using Type = std::decay_t<decltype(initValue)>;
+ using DataPointer = QArrayDataPointer<Type>;
+
+ auto oldDataPointer = createDataPointer(capacity, initValue);
+ oldDataPointer->insert(0, 1, initValue);
+ oldDataPointer->insert(0, 1, initValue); // trigger prepend
+ QVERIFY(!oldDataPointer.needsDetach());
+
+ auto newDataPointer = DataPointer::allocateGrow(oldDataPointer, newSize, GrowthPosition);
+ const auto newAlloc = newDataPointer.constAllocatedCapacity();
+ const auto freeAtBegin = newDataPointer.freeSpaceAtBegin();
+ const auto freeAtEnd = newDataPointer.freeSpaceAtEnd();
+
+ QVERIFY(newAlloc >= oldDataPointer.constAllocatedCapacity());
+ QCOMPARE(freeAtBegin + freeAtEnd, newAlloc);
+ if (GrowthPosition == QArrayData::GrowsAtBeginning) {
+ QVERIFY(freeAtBegin > 0);
+ } else if (GrowthPosition & QArrayData::GrowsAtEnd) {
+ QCOMPARE(freeAtBegin, oldDataPointer.freeSpaceAtBegin());
+ QVERIFY(freeAtEnd > 0);
+ }
+ };
+
+ for (size_t n : {10, 512, 1000}) {
+ RUN_TEST_FUNC(testRealloc, n, n + 1, int(0));
+ RUN_TEST_FUNC(testRealloc, n, n + 1, char('a'));
+ RUN_TEST_FUNC(testRealloc, n, n + 1, char16_t(u'a'));
+ RUN_TEST_FUNC(testRealloc, n, n + 1, QString("hello, world!"));
+ RUN_TEST_FUNC(testRealloc, n, n + 1, CountedObject());
+ }
+
+ const auto testDetachRealloc = [&] (qsizetype capacity, qsizetype newSize, auto initValue) {
+ using Type = std::decay_t<decltype(initValue)>;
+ using DataPointer = QArrayDataPointer<Type>;
+
+ auto oldDataPointer = createDataPointer(capacity, initValue);
+ oldDataPointer->insert(0, 1, initValue); // trigger prepend
+ auto oldDataPointerCopy = oldDataPointer; // force detach later
+ QVERIFY(oldDataPointer.needsDetach());
+
+ auto newDataPointer = DataPointer::allocateGrow(oldDataPointer, oldDataPointer->detachCapacity(newSize), GrowthPosition);
+ const auto newAlloc = newDataPointer.constAllocatedCapacity();
+ const auto freeAtBegin = newDataPointer.freeSpaceAtBegin();
+ const auto freeAtEnd = newDataPointer.freeSpaceAtEnd();
+
+ QVERIFY(newAlloc > oldDataPointer.constAllocatedCapacity());
+ QCOMPARE(freeAtBegin + freeAtEnd, newAlloc);
+ if (GrowthPosition == QArrayData::GrowsAtBeginning) {
+ QVERIFY(freeAtBegin > 0);
+ } else if (GrowthPosition & QArrayData::GrowsAtEnd) {
+ QCOMPARE(freeAtBegin, oldDataPointer.freeSpaceAtBegin());
+ QVERIFY(freeAtEnd > 0);
+ }
+ };
+
+ for (size_t n : {10, 512, 1000}) {
+ RUN_TEST_FUNC(testDetachRealloc, n, n + 1, int(0));
+ RUN_TEST_FUNC(testDetachRealloc, n, n + 1, char('a'));
+ RUN_TEST_FUNC(testDetachRealloc, n, n + 1, char16_t(u'a'));
+ RUN_TEST_FUNC(testDetachRealloc, n, n + 1, QString("hello, world!"));
+ RUN_TEST_FUNC(testDetachRealloc, n, n + 1, CountedObject());
+ }
+}
+
+struct MyQStringWrapper : public QString
+{
+ bool movedTo = false;
+ bool movedFrom = false;
+ MyQStringWrapper() = default;
+ MyQStringWrapper(QChar c) : QString(c) { }
+ MyQStringWrapper(MyQStringWrapper &&other) : QString(std::move(static_cast<QString &>(other)))
+ {
+ movedTo = true;
+ movedFrom = other.movedFrom;
+ other.movedFrom = true;
+ }
+ MyQStringWrapper &operator=(MyQStringWrapper &&other)
+ {
+ QString::operator=(std::move(static_cast<QString &>(other)));
+ movedTo = true;
+ movedFrom = other.movedFrom;
+ other.movedFrom = true;
+ return *this;
+ }
+ MyQStringWrapper(const MyQStringWrapper &) = default;
+ MyQStringWrapper &operator=(const MyQStringWrapper &) = default;
+ ~MyQStringWrapper() = default;
+};
+
+struct MyMovableQString : public MyQStringWrapper
+{
+ MyMovableQString() = default;
+ MyMovableQString(QChar c) : MyQStringWrapper(c) { }
+
+private:
+ friend bool operator==(const MyMovableQString &a, QChar c)
+ {
+ return static_cast<QString>(a) == QString(c);
+ }
+
+ friend bool operator==(const MyMovableQString &a, const MyMovableQString &b)
+ {
+ return static_cast<QString>(a) == static_cast<QString>(b);
+ }
+};
+
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(MyMovableQString, Q_RELOCATABLE_TYPE);
+QT_END_NAMESPACE
+static_assert(QTypeInfo<MyMovableQString>::isComplex);
+static_assert(QTypeInfo<MyMovableQString>::isRelocatable);
+
+struct MyComplexQString : public MyQStringWrapper
+{
+ MyComplexQString() = default;
+ MyComplexQString(QChar c) : MyQStringWrapper(c) { }
+
+private:
+ friend bool operator==(const MyComplexQString &a, QChar c)
+ {
+ return static_cast<QString>(a) == QString(c);
+ }
+
+ friend bool operator==(const MyComplexQString &a, const MyComplexQString &b)
+ {
+ return static_cast<QString>(a) == static_cast<QString>(b);
+ }
+};
+static_assert(QTypeInfo<MyComplexQString>::isComplex);
+static_assert(!QTypeInfo<MyComplexQString>::isRelocatable);
+
+void tst_QArrayData::selfEmplaceBackwards()
+{
+ const auto createDataPointer = [](qsizetype capacity, int spaceAtEnd, auto dummy) {
+ using Type = std::decay_t<decltype(dummy)>;
+ Q_UNUSED(dummy);
+ auto [header, ptr] = QTypedArrayData<Type>::allocate(capacity, QArrayData::Grow);
+ // do custom adjustments to make sure there's free space at end
+ ptr += header->alloc - spaceAtEnd;
+ return QArrayDataPointer(header, ptr);
+ };
+
+ const auto testSelfEmplace = [&](auto dummy, int spaceAtEnd, auto initValues) {
+ auto adp = createDataPointer(100, spaceAtEnd, dummy);
+ for (auto v : initValues) {
+ adp->emplace(adp.size, v);
+ }
+ QVERIFY(!adp.freeSpaceAtEnd());
+ QVERIFY(adp.freeSpaceAtBegin());
+
+ adp->emplace(adp.size, adp.data()[0]);
+ for (qsizetype i = 0; i < adp.size - 1; ++i) {
+ QCOMPARE(adp.data()[i], initValues[i]);
+ }
+ QCOMPARE(adp.data()[adp.size - 1], initValues[0]);
+
+ adp->emplace(adp.size, std::move(adp.data()[0]));
+ for (qsizetype i = 1; i < adp.size - 2; ++i) {
+ QCOMPARE(adp.data()[i], initValues[i]);
+ }
+ QCOMPARE(adp.data()[adp.size - 2], initValues[0]);
+ QCOMPARE(adp.data()[0].movedFrom, true);
+ QCOMPARE(adp.data()[adp.size - 1], initValues[0]);
+ QCOMPARE(adp.data()[adp.size - 1].movedTo, true);
+ };
+
+ QList<QChar> movableObjs { u'a', u'b', u'c', u'd' };
+ RUN_TEST_FUNC(testSelfEmplace, MyMovableQString(), 4, movableObjs);
+ QList<QChar> complexObjs { u'a', u'b', u'c', u'd' };
+ RUN_TEST_FUNC(testSelfEmplace, MyComplexQString(), 4, complexObjs);
+}
+
+void tst_QArrayData::selfEmplaceForward()
+{
+ const auto createDataPointer = [](qsizetype capacity, int spaceAtBegin, auto dummy) {
+ using Type = std::decay_t<decltype(dummy)>;
+ Q_UNUSED(dummy);
+ auto [header, ptr] = QTypedArrayData<Type>::allocate(capacity, QArrayData::Grow);
+ // do custom adjustments to make sure there's free space at end
+ ptr += spaceAtBegin;
+ return QArrayDataPointer(header, ptr);
+ };
+
+ const auto testSelfEmplace = [&](auto dummy, int spaceAtBegin, auto initValues) {
+ // need a -1 below as the first emplace will go towards the end (as the array is still empty)
+ auto adp = createDataPointer(100, spaceAtBegin - 1, dummy);
+ auto reversedInitValues = initValues;
+ std::reverse(reversedInitValues.begin(), reversedInitValues.end());
+ for (auto v : reversedInitValues) {
+ adp->emplace(0, v);
+ }
+ QVERIFY(!adp.freeSpaceAtBegin());
+ QVERIFY(adp.freeSpaceAtEnd());
+
+ adp->emplace(0, adp.data()[adp.size - 1]);
+ for (qsizetype i = 1; i < adp.size; ++i) {
+ QCOMPARE(adp.data()[i], initValues[i - 1]);
+ }
+ QCOMPARE(adp.data()[0], initValues[spaceAtBegin - 1]);
+
+ adp->emplace(0, std::move(adp.data()[adp.size - 1]));
+ for (qsizetype i = 2; i < adp.size - 1; ++i) {
+ QCOMPARE(adp.data()[i], initValues[i - 2]);
+ }
+ QCOMPARE(adp.data()[1], initValues[spaceAtBegin - 1]);
+ QCOMPARE(adp.data()[adp.size - 1].movedFrom, true);
+ QCOMPARE(adp.data()[0], initValues[spaceAtBegin - 1]);
+ QCOMPARE(adp.data()[0].movedTo, true);
+ };
+
+ QList<QChar> movableObjs { u'a', u'b', u'c', u'd' };
+ RUN_TEST_FUNC(testSelfEmplace, MyMovableQString(), 4, movableObjs);
+ QList<QChar> complexObjs { u'a', u'b', u'c', u'd' };
+ RUN_TEST_FUNC(testSelfEmplace, MyComplexQString(), 4, complexObjs);
+}
+
+#ifndef QT_NO_EXCEPTIONS
+struct ThrowingTypeWatcher
+{
+ std::vector<void *> destroyedAddrs;
+ bool watch = false;
+
+ void destroyed(void *addr)
+ {
+ if (watch)
+ destroyedAddrs.push_back(addr);
+ }
+};
+
+ThrowingTypeWatcher &throwingTypeWatcher()
+{
+ static ThrowingTypeWatcher global;
+ return global;
+}
+
+struct ThrowingType
+{
+ static unsigned int throwOnce;
+ static constexpr char throwString[] = "Requested to throw";
+ enum MoveCase {
+ MoveRightNoOverlap,
+ MoveRightOverlap,
+ MoveLeftNoOverlap,
+ MoveLeftOverlap,
+ };
+ enum ThrowCase {
+ NoThrow,
+ ThrowInUninitializedRegion,
+ ThrowInOverlapRegion,
+ };
+
+ // reinforce basic checkers with std::shared_ptr which happens to signal
+ // very explicitly about use-after-free and so on under ASan
+ std::shared_ptr<int> doubleFreeHelper = std::shared_ptr<int>(new int(42));
+ int id = 0;
+
+ void checkThrow()
+ {
+ // deferred throw
+ if (throwOnce > 0) {
+ --throwOnce;
+ if (throwOnce == 0) {
+ throw std::runtime_error(throwString);
+ }
+ }
+ return;
+ }
+
+ void copy(const ThrowingType &other) noexcept(false)
+ {
+ doubleFreeHelper = other.doubleFreeHelper;
+ id = other.id;
+ checkThrow();
+ }
+
+ ThrowingType(int val = 0) noexcept(false) : id(val) { checkThrow(); }
+ ThrowingType(const ThrowingType &other) noexcept(false) { copy(other); }
+ ThrowingType &operator=(const ThrowingType &other) noexcept(false)
+ {
+ copy(other);
+ return *this;
+ }
+ ThrowingType(ThrowingType &&other) noexcept(false) { copy(other); }
+ ThrowingType &operator=(ThrowingType &&other) noexcept(false)
+ {
+ copy(other);
+ return *this;
+ }
+ ~ThrowingType() noexcept(true)
+ {
+ throwingTypeWatcher().destroyed(this); // notify global watcher
+ id = -1;
+ // if we're in dtor but use_count is 0, it's double free
+ QVERIFY(doubleFreeHelper.use_count() > 0);
+ }
+
+ friend bool operator==(const ThrowingType &a, const ThrowingType &b) { return a.id == b.id; }
+};
+
+unsigned int ThrowingType::throwOnce = 0;
+static_assert(!QTypeInfo<ThrowingType>::isRelocatable);
+
+void tst_QArrayData::relocateWithExceptions_data()
+{
+ QTest::addColumn<ThrowingType::MoveCase>("moveCase");
+ QTest::addColumn<ThrowingType::ThrowCase>("throwCase");
+ // Not throwing
+ QTest::newRow("no-throw-move-right-no-overlap")
+ << ThrowingType::MoveRightNoOverlap << ThrowingType::NoThrow;
+ QTest::newRow("no-throw-move-right-overlap")
+ << ThrowingType::MoveRightOverlap << ThrowingType::NoThrow;
+ QTest::newRow("no-throw-move-left-no-overlap")
+ << ThrowingType::MoveLeftNoOverlap << ThrowingType::NoThrow;
+ QTest::newRow("no-throw-move-left-overlap")
+ << ThrowingType::MoveLeftOverlap << ThrowingType::NoThrow;
+ // Throwing in uninitialized region
+ QTest::newRow("throw-in-uninit-region-move-right-no-overlap")
+ << ThrowingType::MoveRightNoOverlap << ThrowingType::ThrowInUninitializedRegion;
+ QTest::newRow("throw-in-uninit-region-move-right-overlap")
+ << ThrowingType::MoveRightOverlap << ThrowingType::ThrowInUninitializedRegion;
+ QTest::newRow("throw-in-uninit-region-move-left-no-overlap")
+ << ThrowingType::MoveLeftNoOverlap << ThrowingType::ThrowInUninitializedRegion;
+ QTest::newRow("throw-in-uninit-region-move-left-overlap")
+ << ThrowingType::MoveLeftOverlap << ThrowingType::ThrowInUninitializedRegion;
+ // Throwing in overlap region
+ QTest::newRow("throw-in-overlap-region-move-right-overlap")
+ << ThrowingType::MoveRightOverlap << ThrowingType::ThrowInOverlapRegion;
+ QTest::newRow("throw-in-overlap-region-move-left-overlap")
+ << ThrowingType::MoveLeftOverlap << ThrowingType::ThrowInOverlapRegion;
+}
+
+void tst_QArrayData::relocateWithExceptions()
+{
+ // Assume that non-throwing moves perform correctly. Otherwise, all previous
+ // tests would've failed. Test only what happens when exceptions are thrown.
+ QFETCH(ThrowingType::MoveCase, moveCase);
+ QFETCH(ThrowingType::ThrowCase, throwCase);
+
+ struct ThrowingTypeLeakChecker
+ {
+ ThrowingType::MoveCase moveCase;
+ ThrowingType::ThrowCase throwCase;
+ size_t containerSize = 0;
+
+ ThrowingTypeLeakChecker(ThrowingType::MoveCase mc, ThrowingType::ThrowCase tc)
+ : moveCase(mc), throwCase(tc)
+ {
+ }
+
+ void start(qsizetype size)
+ {
+ containerSize = size_t(size);
+ throwingTypeWatcher().watch = true;
+ }
+
+ ~ThrowingTypeLeakChecker()
+ {
+ const size_t destroyedElementsCount = throwingTypeWatcher().destroyedAddrs.size();
+ const size_t destroyedElementsUniqueCount =
+ std::set<void *>(throwingTypeWatcher().destroyedAddrs.begin(),
+ throwingTypeWatcher().destroyedAddrs.end())
+ .size();
+
+ // reset the global watcher first and only then verify things
+ throwingTypeWatcher().watch = false;
+ throwingTypeWatcher().destroyedAddrs.clear();
+
+ size_t deletedByRelocate = 0;
+ switch (throwCase) {
+ case ThrowingType::NoThrow:
+ // if no overlap, N elements from old range. otherwise, N - 1
+ // elements from old range
+ if (moveCase == ThrowingType::MoveLeftNoOverlap
+ || moveCase == ThrowingType::MoveRightNoOverlap) {
+ deletedByRelocate = containerSize;
+ } else {
+ deletedByRelocate = containerSize - 1;
+ }
+ break;
+ case ThrowingType::ThrowInUninitializedRegion:
+ // 1 relocated element from uninitialized region
+ deletedByRelocate = 1u;
+ break;
+ case ThrowingType::ThrowInOverlapRegion:
+ // 2 relocated elements from uninitialized region
+ deletedByRelocate = 2u;
+ break;
+ default:
+ QFAIL("Unknown throwCase");
+ }
+
+ QCOMPARE(destroyedElementsCount, deletedByRelocate + containerSize);
+ QCOMPARE(destroyedElementsUniqueCount, destroyedElementsCount);
+ }
+ };
+
+ const auto setDeferredThrow = [throwCase]() {
+ switch (throwCase) {
+ case ThrowingType::NoThrow:
+ break; // do nothing
+ case ThrowingType::ThrowInUninitializedRegion:
+ ThrowingType::throwOnce = 2;
+ break;
+ case ThrowingType::ThrowInOverlapRegion:
+ ThrowingType::throwOnce = 3;
+ break;
+ default:
+ QFAIL("Unknown throwCase");
+ }
+ };
+
+ const auto createDataPointer = [](qsizetype capacity, qsizetype initSize) {
+ QArrayDataPointer<ThrowingType> qadp(capacity);
+ qadp->appendInitialize(initSize);
+ int i = 0;
+ std::generate(qadp.begin(), qadp.end(), [&i]() { return ThrowingType(i++); });
+ return qadp;
+ };
+
+ switch (moveCase) {
+ case ThrowingType::MoveRightNoOverlap: {
+ ThrowingTypeLeakChecker watch(moveCase, throwCase);
+ auto storage = createDataPointer(20, 3);
+ QVERIFY(storage.freeSpaceAtEnd() > 3);
+
+ watch.start(storage.size);
+ try {
+ setDeferredThrow();
+ storage->relocate(4);
+ if (throwCase != ThrowingType::NoThrow)
+ QFAIL("Unreachable line!");
+ } catch (const std::runtime_error &e) {
+ QCOMPARE(std::string(e.what()), ThrowingType::throwString);
+ }
+ break;
+ }
+ case ThrowingType::MoveRightOverlap: {
+ ThrowingTypeLeakChecker watch(moveCase, throwCase);
+ auto storage = createDataPointer(20, 3);
+ QVERIFY(storage.freeSpaceAtEnd() > 3);
+
+ watch.start(storage.size);
+ try {
+ setDeferredThrow();
+ storage->relocate(2);
+ if (throwCase != ThrowingType::NoThrow)
+ QFAIL("Unreachable line!");
+ } catch (const std::runtime_error &e) {
+ QCOMPARE(std::string(e.what()), ThrowingType::throwString);
+ }
+ break;
+ }
+ case ThrowingType::MoveLeftNoOverlap: {
+ ThrowingTypeLeakChecker watch(moveCase, throwCase);
+ auto storage = createDataPointer(20, 2);
+ storage->insert(0, 1, ThrowingType(42));
+ QVERIFY(storage.freeSpaceAtBegin() > 3);
+
+ watch.start(storage.size);
+ try {
+ setDeferredThrow();
+ storage->relocate(-4);
+ if (throwCase != ThrowingType::NoThrow)
+ QFAIL("Unreachable line!");
+ } catch (const std::runtime_error &e) {
+ QCOMPARE(std::string(e.what()), ThrowingType::throwString);
+ }
+ break;
+ }
+ case ThrowingType::MoveLeftOverlap: {
+ ThrowingTypeLeakChecker watch(moveCase, throwCase);
+ auto storage = createDataPointer(20, 2);
+ storage->insert(0, 1, ThrowingType(42));
+ QVERIFY(storage.freeSpaceAtBegin() > 3);
+
+ watch.start(storage.size);
+ try {
+ setDeferredThrow();
+ storage->relocate(-2);
+ if (throwCase != ThrowingType::NoThrow)
+ QFAIL("Unreachable line!");
+ } catch (const std::runtime_error &e) {
+ QCOMPARE(std::string(e.what()), ThrowingType::throwString);
+ }
+ break;
+ }
+ default:
+ QFAIL("Unknown ThrowingType::MoveCase");
+ };
+}
+#endif // QT_NO_EXCEPTIONS
+
QTEST_APPLESS_MAIN(tst_QArrayData)
#include "tst_qarraydata.moc"
diff --git a/tests/auto/corelib/tools/qarraydata_strictiterators/qarraydata_strictiterators.pro b/tests/auto/corelib/tools/qarraydata_strictiterators/qarraydata_strictiterators.pro
deleted file mode 100644
index b01fbd84d1..0000000000
--- a/tests/auto/corelib/tools/qarraydata_strictiterators/qarraydata_strictiterators.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-include(../qarraydata/qarraydata.pro)
-TARGET = tst_qarraydata_strictiterators
-DEFINES += QT_STRICT_ITERATORS=1 tst_QArrayData=tst_QArrayData_StrictIterators
diff --git a/tests/auto/corelib/tools/qatomicscopedvaluerollback/CMakeLists.txt b/tests/auto/corelib/tools/qatomicscopedvaluerollback/CMakeLists.txt
new file mode 100644
index 0000000000..b20e56421f
--- /dev/null
+++ b/tests/auto/corelib/tools/qatomicscopedvaluerollback/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qatomicscopedvaluerollback LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qatomicscopedvaluerollback
+ SOURCES
+ tst_qatomicscopedvaluerollback.cpp
+)
diff --git a/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp b/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp
new file mode 100644
index 0000000000..89bd1d7ff6
--- /dev/null
+++ b/tests/auto/corelib/tools/qatomicscopedvaluerollback/tst_qatomicscopedvaluerollback.cpp
@@ -0,0 +1,164 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtCore/qatomicscopedvaluerollback.h>
+
+#include <QTest>
+
+class tst_QAtomicScopedValueRollback : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void leavingScope();
+ void leavingScopeAfterCommit();
+ void rollbackToPreviousCommit();
+ void exceptions();
+ void earlyExitScope();
+private:
+ void earlyExitScope_helper(int exitpoint, std::atomic<int> &member);
+};
+
+void tst_QAtomicScopedValueRollback::leavingScope()
+{
+ QAtomicInt i = 0;
+ QBasicAtomicInteger<bool> b = false;
+ std::atomic<bool> b2 = false;
+ int x = 0, y = 42;
+ QBasicAtomicPointer<int> p = &x;
+
+ //test rollback on going out of scope
+ {
+ QAtomicScopedValueRollback ri(i);
+ QAtomicScopedValueRollback rb(b);
+ QAtomicScopedValueRollback rb2(b2, true);
+ QAtomicScopedValueRollback rp(p);
+ QCOMPARE(b.loadRelaxed(), false);
+ QCOMPARE(b2, true);
+ QCOMPARE(i.loadRelaxed(), 0);
+ QCOMPARE(p.loadRelaxed(), &x);
+ b.storeRelaxed(true);
+ i.storeRelaxed(1);
+ p.storeRelaxed(&y);
+ QCOMPARE(b.loadRelaxed(), true);
+ QCOMPARE(i.loadRelaxed(), 1);
+ QCOMPARE(p.loadRelaxed(), &y);
+ }
+ QCOMPARE(b.loadRelaxed(), false);
+ QCOMPARE(b2, false);
+ QCOMPARE(i.loadRelaxed(), 0);
+ QCOMPARE(p.loadRelaxed(), &x);
+}
+
+void tst_QAtomicScopedValueRollback::leavingScopeAfterCommit()
+{
+ std::atomic<int> i = 0;
+ QAtomicInteger<bool> b = false;
+
+ //test rollback on going out of scope
+ {
+ QAtomicScopedValueRollback ri(i);
+ QAtomicScopedValueRollback rb(b);
+ QCOMPARE(b.loadRelaxed(), false);
+ QCOMPARE(i, 0);
+ b.storeRelaxed(true);
+ i = 1;
+ QCOMPARE(b.loadRelaxed(), true);
+ QCOMPARE(i, 1);
+ ri.commit();
+ rb.commit();
+ }
+ QCOMPARE(b.loadRelaxed(), true);
+ QCOMPARE(i, 1);
+}
+
+void tst_QAtomicScopedValueRollback::rollbackToPreviousCommit()
+{
+ QBasicAtomicInt i = 0;
+ {
+ QAtomicScopedValueRollback ri(i);
+ i++;
+ ri.commit();
+ i++;
+ }
+ QCOMPARE(i.loadRelaxed(), 1);
+ {
+ QAtomicScopedValueRollback ri1(i);
+ i++;
+ ri1.commit();
+ i++;
+ ri1.commit();
+ i++;
+ }
+ QCOMPARE(i.loadRelaxed(), 3);
+}
+
+void tst_QAtomicScopedValueRollback::exceptions()
+{
+ std::atomic<bool> b = false;
+ bool caught = false;
+ QT_TRY
+ {
+ QAtomicScopedValueRollback rb(b);
+ b = true;
+ QT_THROW(std::bad_alloc()); //if Qt compiled without exceptions this is noop
+ rb.commit(); //if Qt compiled without exceptions, true is committed
+ }
+ QT_CATCH(...)
+ {
+ caught = true;
+ }
+ QCOMPARE(b, !caught); //expect false if exception was thrown, true otherwise
+}
+
+void tst_QAtomicScopedValueRollback::earlyExitScope()
+{
+ QAtomicInt ai = 0;
+ std::atomic<int> aj = 0;
+ while (true) {
+ QAtomicScopedValueRollback ri(ai);
+ ++ai;
+ aj = ai.loadRelaxed();
+ if (ai.loadRelaxed() > 8) break;
+ ri.commit();
+ }
+ QCOMPARE(ai.loadRelaxed(), 8);
+ QCOMPARE(aj.load(), 9);
+
+ for (int i = 0; i < 5; ++i) {
+ aj = 1;
+ earlyExitScope_helper(i, aj);
+ QCOMPARE(aj.load(), 1 << i);
+ }
+}
+
+static void operator*=(std::atomic<int> &lhs, int rhs)
+{
+ int expected = lhs.load();
+ while (!lhs.compare_exchange_weak(expected, expected * rhs))
+ ;
+}
+
+void tst_QAtomicScopedValueRollback::earlyExitScope_helper(int exitpoint, std::atomic<int>& member)
+{
+ QAtomicScopedValueRollback r(member);
+ member *= 2;
+ if (exitpoint == 0)
+ return;
+ r.commit();
+ member *= 2;
+ if (exitpoint == 1)
+ return;
+ r.commit();
+ member *= 2;
+ if (exitpoint == 2)
+ return;
+ r.commit();
+ member *= 2;
+ if (exitpoint == 3)
+ return;
+ r.commit();
+}
+
+QTEST_MAIN(tst_QAtomicScopedValueRollback)
+#include "tst_qatomicscopedvaluerollback.moc"
diff --git a/tests/auto/corelib/tools/qbitarray/CMakeLists.txt b/tests/auto/corelib/tools/qbitarray/CMakeLists.txt
new file mode 100644
index 0000000000..ac3bd24bd5
--- /dev/null
+++ b/tests/auto/corelib/tools/qbitarray/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qbitarray Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qbitarray LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qbitarray
+ SOURCES
+ tst_qbitarray.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/tools/qbitarray/qbitarray.pro b/tests/auto/corelib/tools/qbitarray/qbitarray.pro
deleted file mode 100644
index 1e7185b600..0000000000
--- a/tests/auto/corelib/tools/qbitarray/qbitarray.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qbitarray
-QT = core testlib
-SOURCES = tst_qbitarray.cpp
diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
index d19eac7530..f52a368aa9 100644
--- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
+++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
@@ -1,47 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qcomparisontesthelper_p.h>
#include <QtCore/QBuffer>
#include <QtCore/QDataStream>
#include "qbitarray.h"
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qscopeguard.h>
+
/**
* Helper function to initialize a bitarray from a string
*/
static QBitArray QStringToQBitArray(const QString &str)
{
QBitArray ba;
- ba.resize(str.length());
+ ba.resize(str.size());
int i;
QChar tru('1');
- for (i = 0; i < str.length(); i++)
+ for (i = 0; i < str.size(); i++)
{
if (str.at(i) == tru)
{
@@ -51,10 +30,18 @@ static QBitArray QStringToQBitArray(const QString &str)
return ba;
}
+static QBitArray detached(QBitArray a)
+{
+ a.detach();
+ return a;
+}
+
class tst_QBitArray : public QObject
{
Q_OBJECT
private slots:
+ void compareCompiles();
+ void canHandleIntMaxBits();
void size_data();
void size();
void countBits_data();
@@ -68,12 +55,21 @@ private slots:
// operator &=
void operator_andeq_data();
void operator_andeq();
+ // operator &
+ void operator_and_data() { operator_andeq_data(); }
+ void operator_and();
// operator |=
void operator_oreq_data();
void operator_oreq();
+ // operator |
+ void operator_or_data() { operator_oreq_data(); }
+ void operator_or();
// operator ^=
void operator_xoreq_data();
void operator_xoreq();
+ // operator ^
+ void operator_xor_data() { operator_xoreq_data(); }
+ void operator_xor();
// operator ~
void operator_neg_data();
void operator_neg();
@@ -84,8 +80,66 @@ private slots:
void operator_noteq();
void resize();
+ void fromBits_data();
+ void fromBits();
+
+ void toUInt32_data();
+ void toUInt32();
};
+void tst_QBitArray::compareCompiles()
+{
+ QTestPrivate::testEqualityOperatorsCompile<QBitArray>();
+}
+
+void tst_QBitArray::canHandleIntMaxBits()
+{
+ QElapsedTimer timer;
+ timer.start();
+ const auto print = qScopeGuard([&] {
+ qDebug("Function took %lldms", qlonglong(timer.elapsed()));
+ });
+
+ try {
+ constexpr qsizetype Size1 = sizeof(void*) > sizeof(int) ? qsizetype(INT_MAX) + 2 :
+ INT_MAX - 2;
+ constexpr qsizetype Size2 = Size1 + 2;
+
+ QBitArray ba(Size1, true);
+ QCOMPARE(ba.size(), Size1);
+ QCOMPARE(ba.at(Size1 - 1), true);
+
+ ba.resize(Size2);
+ QCOMPARE(ba.size(), Size2);
+ QCOMPARE(ba.at(Size1 - 1), true);
+ QCOMPARE(ba.at(Size1), false);
+ QCOMPARE(ba.at(Size2 - 1), false);
+
+ QByteArray serialized;
+ if constexpr (sizeof(void*) > sizeof(int)) {
+ QDataStream ds(&serialized, QIODevice::WriteOnly);
+ ds.setVersion(QDataStream::Qt_5_15);
+ ds << ba;
+ QCOMPARE(ds.status(), QDataStream::Status::SizeLimitExceeded);
+ serialized.clear();
+ }
+ {
+ QDataStream ds(&serialized, QIODevice::WriteOnly);
+ ds << ba;
+ QCOMPARE(ds.status(), QDataStream::Status::Ok);
+ }
+ {
+ QDataStream ds(serialized);
+ QBitArray ba2;
+ ds >> ba2;
+ QCOMPARE(ds.status(), QDataStream::Status::Ok);
+ QT_TEST_EQUALITY_OPS(ba, ba2, true);
+ }
+ } catch (const std::bad_alloc &) {
+ QSKIP("Failed to allocate sufficient memory");
+ }
+}
+
void tst_QBitArray::size_data()
{
//create the testtable instance and define the elements
@@ -145,7 +199,6 @@ void tst_QBitArray::countBits_data()
QTest::newRow("11111111111111111111111111111111") << QString("11111111111111111111111111111111") << 32 << 32;
QTest::newRow("11111111111111111111111111111111111111111111111111111111")
<< QString("11111111111111111111111111111111111111111111111111111111") << 56 << 56;
- QTest::newRow("00000000000000000000000000000000000") << QString("00000000000000000000000000000000000") << 35 << 0;
QTest::newRow("00000000000000000000000000000000") << QString("00000000000000000000000000000000") << 32 << 0;
QTest::newRow("00000000000000000000000000000000000000000000000000000000")
<< QString("00000000000000000000000000000000000000000000000000000000") << 56 << 0;
@@ -163,6 +216,8 @@ void tst_QBitArray::countBits()
bits.setBit(i);
}
+ QCOMPARE(bits.size(), numBits);
+ // NOLINTNEXTLINE(qt-port-to-std-compatible-api): We want to test count() and size()
QCOMPARE(bits.count(), numBits);
QCOMPARE(bits.count(true), onBits);
QCOMPARE(bits.count(false), numBits - onBits);
@@ -218,14 +273,20 @@ void tst_QBitArray::isEmpty()
QVERIFY(!a1.isEmpty());
QVERIFY(!a1.isNull());
QVERIFY(a1.size() == 2);
+
+ QT_TEST_EQUALITY_OPS(a1, a2, false);
+ QT_TEST_EQUALITY_OPS(a2, a3, false);
+ QT_TEST_EQUALITY_OPS(QBitArray(), QBitArray(), true);
+ a3 = a2;
+ QT_TEST_EQUALITY_OPS(a2, a3, true);
}
void tst_QBitArray::swap()
{
QBitArray b1 = QStringToQBitArray("1"), b2 = QStringToQBitArray("10");
b1.swap(b2);
- QCOMPARE(b1,QStringToQBitArray("10"));
- QCOMPARE(b2,QStringToQBitArray("1"));
+ QT_TEST_EQUALITY_OPS(b1,QStringToQBitArray("10"), true);
+ QT_TEST_EQUALITY_OPS(b2,QStringToQBitArray("1"), true);
}
void tst_QBitArray::fill()
@@ -275,7 +336,7 @@ void tst_QBitArray::toggleBit()
input.toggleBit(index);
- QCOMPARE(input, res);
+ QT_TEST_EQUALITY_OPS(input, res, true);
}
void tst_QBitArray::operator_andeq_data()
@@ -320,9 +381,64 @@ void tst_QBitArray::operator_andeq()
QFETCH(QBitArray, input2);
QFETCH(QBitArray, res);
- input1&=input2;
+ QBitArray result = input1;
+ result &= input2;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1;
+ result &= std::move(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1;
+ result &= detached(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is commutative
+ result = input2;
+ result &= input1;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2;
+ result &= std::move(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2;
+ result &= detached(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is idempotent
+ result &= result;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result &= std::move(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result &= detached(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+}
- QCOMPARE(input1, res);
+void tst_QBitArray::operator_and()
+{
+ QFETCH(QBitArray, input1);
+ QFETCH(QBitArray, input2);
+ QFETCH(QBitArray, res);
+
+ QBitArray result = input1 & input2;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1 & QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1 & detached(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is commutative
+ result = input2 & input1;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2 & QBitArray(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2 & detached(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is idempotent
+ result = result & result;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = result & QBitArray(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = result & detached(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
}
void tst_QBitArray::operator_oreq_data()
@@ -371,9 +487,64 @@ void tst_QBitArray::operator_oreq()
QFETCH(QBitArray, input2);
QFETCH(QBitArray, res);
- input1|=input2;
+ QBitArray result = input1;
+ result |= input2;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1;
+ result |= QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1;
+ result |= detached(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is commutative
+ result = input2;
+ result |= input1;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2;
+ result |= QBitArray(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2;
+ result |= detached(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is idempotent
+ result |= result;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result |= QBitArray(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result |= detached(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+}
+
+void tst_QBitArray::operator_or()
+{
+ QFETCH(QBitArray, input1);
+ QFETCH(QBitArray, input2);
+ QFETCH(QBitArray, res);
- QCOMPARE(input1, res);
+ QBitArray result = input1 | input2;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1 | QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1 | detached(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is commutative
+ result = input2 | input1;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2 | QBitArray(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2 | detached(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is idempotent
+ result = result | result;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = result | QBitArray(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = result | detached(result);
+ QT_TEST_EQUALITY_OPS(result, res, true);
}
void tst_QBitArray::operator_xoreq_data()
@@ -420,11 +591,102 @@ void tst_QBitArray::operator_xoreq()
QFETCH(QBitArray, input2);
QFETCH(QBitArray, res);
- input1^=input2;
-
- QCOMPARE(input1, res);
+ QBitArray result = input1;
+ result ^= input2;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1;
+ result ^= QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1;
+ result ^= detached(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is commutative
+ result = input2;
+ result ^= input1;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2;
+ result ^= QBitArray(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2;
+ result ^= detached(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // XORing with oneself is nilpotent
+ result = input1;
+ result ^= input1;
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true);
+ result = input1;
+ result ^= QBitArray(result);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true);
+ result = input1;
+ result ^= detached(result);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true);
+
+ result = input2;
+ result ^= input2;
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true);
+ result = input2;
+ result ^= QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true);
+ result = input2;
+ result ^= detached(input2);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true);
+
+ result = res;
+ result ^= res;
+ QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true);
+ result = res;
+ result ^= QBitArray(res);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true);
+ result = res;
+ result ^= detached(res);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true);
}
+void tst_QBitArray::operator_xor()
+{
+ QFETCH(QBitArray, input1);
+ QFETCH(QBitArray, input2);
+ QFETCH(QBitArray, res);
+
+ QBitArray result = input1 ^ input2;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1 ^ QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input1 ^ detached(input2);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // operation is commutative
+ result = input2 ^ input1;
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2 ^ QBitArray(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+ result = input2 ^ detached(input1);
+ QT_TEST_EQUALITY_OPS(result, res, true);
+
+ // XORing with oneself is nilpotent
+ result = input1 ^ input1;
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true);
+ result = input1 ^ QBitArray(input1);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true);
+ result = input1 ^ detached(input1);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true);
+
+ result = input2 ^ input2;
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true);
+ result = input2 ^ QBitArray(input2);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true);
+ result = input2 ^ detached(input2);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true);
+
+ result = res ^ res;
+ QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true);
+ result = res ^ QBitArray(res);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true);
+ result = res ^ detached(res);
+ QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true);
+}
void tst_QBitArray::operator_neg_data()
{
@@ -472,7 +734,8 @@ void tst_QBitArray::operator_neg()
input = ~input;
- QCOMPARE(input, res);
+ QT_TEST_EQUALITY_OPS(input, res, true);
+ QT_TEST_EQUALITY_OPS(~~input, res, true); // performs two in-place negations
}
void tst_QBitArray::datastream_data()
@@ -492,7 +755,6 @@ void tst_QBitArray::datastream_data()
QTest::newRow("11111111111111111111111111111111") << QString("11111111111111111111111111111111") << 32 << 32;
QTest::newRow("11111111111111111111111111111111111111111111111111111111")
<< QString("11111111111111111111111111111111111111111111111111111111") << 56 << 56;
- QTest::newRow("00000000000000000000000000000000000") << QString("00000000000000000000000000000000000") << 35 << 0;
QTest::newRow("00000000000000000000000000000000") << QString("00000000000000000000000000000000") << 32 << 0;
QTest::newRow("00000000000000000000000000000000000000000000000000000000")
<< QString("00000000000000000000000000000000000000000000000000000000") << 56 << 0;
@@ -514,7 +776,7 @@ void tst_QBitArray::datastream()
bits.setBit(i);
}
- QCOMPARE(bits.count(), numBits);
+ QCOMPARE(bits.size(), numBits);
QCOMPARE(bits.count(true), onBits);
QCOMPARE(bits.count(false), numBits - onBits);
@@ -529,19 +791,19 @@ void tst_QBitArray::datastream()
QBitArray array1, array2, array3;
stream2 >> array1 >> array2 >> array3;
- QCOMPARE(array1.count(), numBits);
+ QCOMPARE(array1.size(), numBits);
QCOMPARE(array1.count(true), onBits);
QCOMPARE(array1.count(false), numBits - onBits);
- QCOMPARE(array1, bits);
- QCOMPARE(array2, bits);
- QCOMPARE(array3, bits);
+ QT_TEST_EQUALITY_OPS(array1, bits, true);
+ QT_TEST_EQUALITY_OPS(array2, bits, true);
+ QT_TEST_EQUALITY_OPS(array3, bits, true);
}
void tst_QBitArray::invertOnNull() const
{
QBitArray a;
- QCOMPARE(a = ~a, QBitArray());
+ QT_TEST_EQUALITY_OPS(a = ~a, QBitArray(), true);
}
void tst_QBitArray::operator_noteq_data()
@@ -582,7 +844,7 @@ void tst_QBitArray::operator_noteq()
QFETCH(bool, res);
bool b = input1 != input2;
- QCOMPARE(b, res);
+ QT_TEST_EQUALITY_OPS(b, res, true);
}
void tst_QBitArray::resize()
@@ -591,23 +853,168 @@ void tst_QBitArray::resize()
QBitArray a = QStringToQBitArray(QString("11"));
a.resize(10);
QVERIFY(a.size() == 10);
- QCOMPARE( a, QStringToQBitArray(QString("1100000000")) );
+ QT_TEST_EQUALITY_OPS( a, QStringToQBitArray(QString("1100000000")), true);
a.setBit(9);
a.resize(9);
// now the bit in a should have been gone:
- QCOMPARE( a, QStringToQBitArray(QString("110000000")) );
+ QT_TEST_EQUALITY_OPS( a, QStringToQBitArray(QString("110000000")), true);
// grow the array back and check the new bit
a.resize(10);
- QCOMPARE( a, QStringToQBitArray(QString("1100000000")) );
+ QT_TEST_EQUALITY_OPS( a, QStringToQBitArray(QString("1100000000")), true);
// other test with and
a.resize(9);
QBitArray b = QStringToQBitArray(QString("1111111111"));
b &= a;
- QCOMPARE( b, QStringToQBitArray(QString("1100000000")) );
+ QT_TEST_EQUALITY_OPS( b, QStringToQBitArray(QString("1100000000")), true);
+
+}
+
+void tst_QBitArray::fromBits_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("size");
+ QTest::addColumn<QBitArray>("expected");
+
+ QTest::newRow("empty") << QByteArray() << 0 << QBitArray();
+
+ auto add = [](const QByteArray &tag, const char *data) {
+ QTest::newRow(tag) << QByteArray(data, (tag.size() + 7) / 8) << tag.size()
+ << QStringToQBitArray(tag);
+ };
+
+ // "0" to "0000000000000000"
+ for (int i = 1; i < 16; ++i) {
+ char zero[2] = { 0, 0 };
+ QByteArray pattern(i, '0');
+ add(pattern, zero);
+ }
+
+ // "1" to "1111111111111111"
+ for (int i = 1; i < 16; ++i) {
+ char one[2] = { '\xff', '\xff' };
+ QByteArray pattern(i, '1');
+ add(pattern, one);
+ }
+
+ // trailing 0 and 1
+ char zero = 1;
+ char one = 0;
+ QByteArray pzero = "1";
+ QByteArray pone = "0";
+ for (int i = 2; i < 8; ++i) {
+ zero <<= 1;
+ pzero.prepend('0');
+ add(pzero, &zero);
+
+ one = (one << 1) | 1;
+ pone.prepend('1');
+ add(pone, &one);
+ }
+}
+
+void tst_QBitArray::fromBits()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, size);
+ QFETCH(QBitArray, expected);
+ QBitArray fromBits = QBitArray::fromBits(data, size);
+ QT_TEST_EQUALITY_OPS(fromBits, expected, true);
+
+ QT_TEST_EQUALITY_OPS(QBitArray::fromBits(fromBits.bits(), fromBits.size()), expected, true);
+}
+
+void tst_QBitArray::toUInt32_data()
+{
+ QTest::addColumn<QBitArray>("data");
+ QTest::addColumn<int>("endianness");
+ QTest::addColumn<bool>("check");
+ QTest::addColumn<quint32>("result");
+
+ QTest::newRow("ctor") << QBitArray()
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(0);
+
+ QTest::newRow("empty") << QBitArray(0)
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(0);
+
+ QTest::newRow("LittleEndian4") << QStringToQBitArray(QString("0111"))
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(14);
+
+ QTest::newRow("BigEndian4") << QStringToQBitArray(QString("0111"))
+ << static_cast<int>(QSysInfo::Endian::BigEndian)
+ << true
+ << quint32(7);
+
+ QTest::newRow("LittleEndian8") << QStringToQBitArray(QString("01111111"))
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(254);
+
+ QTest::newRow("BigEndian8") << QStringToQBitArray(QString("01111111"))
+ << static_cast<int>(QSysInfo::Endian::BigEndian)
+ << true
+ << quint32(127);
+
+ QTest::newRow("LittleEndian16") << QStringToQBitArray(QString("0111111111111111"))
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(65534);
+
+ QTest::newRow("BigEndian16") << QStringToQBitArray(QString("0111111111111111"))
+ << static_cast<int>(QSysInfo::Endian::BigEndian)
+ << true
+ << quint32(32767);
+
+ QTest::newRow("LittleEndian31") << QBitArray(31, true)
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(2147483647);
+
+ QTest::newRow("BigEndian31") << QBitArray(31, true)
+ << static_cast<int>(QSysInfo::Endian::BigEndian)
+ << true
+ << quint32(2147483647);
+
+ QTest::newRow("LittleEndian32") << QBitArray(32, true)
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << true
+ << quint32(4294967295);
+
+ QTest::newRow("BigEndian32") << QBitArray(32, true)
+ << static_cast<int>(QSysInfo::Endian::BigEndian)
+ << true
+ << quint32(4294967295);
+
+ QTest::newRow("LittleEndian33") << QBitArray(33, true)
+ << static_cast<int>(QSysInfo::Endian::LittleEndian)
+ << false
+ << quint32(0);
+
+ QTest::newRow("BigEndian33") << QBitArray(33, true)
+ << static_cast<int>(QSysInfo::Endian::BigEndian)
+ << false
+ << quint32(0);
+}
+
+void tst_QBitArray::toUInt32()
+{
+ QFETCH(QBitArray, data);
+ QFETCH(int, endianness);
+ QFETCH(bool, check);
+ QFETCH(quint32, result);
+ bool ok = false;
+
+ QCOMPARE(data.toUInt32(static_cast<QSysInfo::Endian>(endianness), &ok), result);
+ QCOMPARE(ok, check);
}
QTEST_APPLESS_MAIN(tst_QBitArray)
diff --git a/tests/auto/corelib/tools/qbytearray/android_testdata.qrc b/tests/auto/corelib/tools/qbytearray/android_testdata.qrc
deleted file mode 100644
index 5d42f0f627..0000000000
--- a/tests/auto/corelib/tools/qbytearray/android_testdata.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>rfc3252.txt</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/tools/qbytearray/qbytearray.pro b/tests/auto/corelib/tools/qbytearray/qbytearray.pro
deleted file mode 100644
index c2101b0611..0000000000
--- a/tests/auto/corelib/tools/qbytearray/qbytearray.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qbytearray
-QT = core-private testlib
-SOURCES = tst_qbytearray.cpp
-
-TESTDATA += rfc3252.txt
-
-mac {
- OBJECTIVE_SOURCES += tst_qbytearray_mac.mm
- LIBS += -framework Foundation
-}
-
-android:!android-embedded {
- RESOURCES += \
- android_testdata.qrc
-}
diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
deleted file mode 100644
index 1ed41793dc..0000000000
--- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
+++ /dev/null
@@ -1,2344 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include <qbytearray.h>
-#include <qfile.h>
-#include <qhash.h>
-#include <limits.h>
-#include <private/qtools_p.h>
-
-class tst_QByteArray : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QByteArray();
-private slots:
- void swap();
- void qChecksum_data();
- void qChecksum();
- void qCompress_data();
-#ifndef QT_NO_COMPRESS
- void qCompress();
- void qUncompressCorruptedData_data();
- void qUncompressCorruptedData();
- void qCompressionZeroTermination();
-#endif
- void constByteArray();
- void leftJustified();
- void rightJustified();
- void setNum();
- void startsWith_data();
- void startsWith();
- void startsWith_char();
- void endsWith_data();
- void endsWith();
- void endsWith_char();
- void reverseIterators();
- void split_data();
- void split();
- void base64_data();
- void base64();
- void fromBase64_data();
- void fromBase64();
- void qvsnprintf();
- void qstrlen();
- void qstrnlen();
- void qstrcpy();
- void qstrncpy();
- void qstricmp_data();
- void qstricmp();
- void qstricmp_singularities();
- void qstrnicmp_singularities();
- void chop_data();
- void chop();
- void prepend();
- void prependExtended_data();
- void prependExtended();
- void append();
- void appendExtended_data();
- void appendExtended();
- void insert();
- void insertExtended_data();
- void insertExtended();
- void remove_data();
- void remove();
- void replace_data();
- void replace();
- void replaceWithSpecifiedLength();
- void indexOf_data();
- void indexOf();
- void lastIndexOf_data();
- void lastIndexOf();
- void toULong_data();
- void toULong();
- void toULongLong_data();
- void toULongLong();
-
- void number();
- void toInt_data();
- void toInt();
- void toDouble_data();
- void toDouble();
- void blockSizeCalculations();
-
- void resizeAfterFromRawData();
- void appendAfterFromRawData();
- void toFromHex_data();
- void toFromHex();
- void toFromPercentEncoding();
- void fromPercentEncoding_data();
- void fromPercentEncoding();
- void toPercentEncoding_data();
- void toPercentEncoding();
- void toPercentEncoding2_data();
- void toPercentEncoding2();
-
- void compare_data();
- void compare();
- void compareCharStar_data();
- void compareCharStar();
-
- void repeatedSignature() const;
- void repeated() const;
- void repeated_data() const;
-
- void byteRefDetaching() const;
-
- void reserve();
- void reserveExtended_data();
- void reserveExtended();
- void movablity_data();
- void movablity();
-#if defined(Q_COMPILER_LAMBDA)
- void literals();
-#endif
- void toUpperLower_data();
- void toUpperLower();
- void isUpper();
- void isLower();
-
- void macTypes();
-
- void stdString();
-};
-
-static const struct StaticByteArrays {
- struct Standard {
- QByteArrayData data;
- const char string[8];
- } standard;
- struct NotNullTerminated {
- QByteArrayData data;
- const char string[8];
- } notNullTerminated;
- struct Shifted {
- QByteArrayData data;
- const char dummy; // added to change offset of string
- const char string[8];
- } shifted;
- struct ShiftedNotNullTerminated {
- QByteArrayData data;
- const char dummy; // added to change offset of string
- const char string[8];
- } shiftedNotNullTerminated;
-
-} statics = {{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(4), "data"}
- ,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(4), "dataBAD"}
- ,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(4, sizeof(QByteArrayData) + sizeof(char)), 0, "data"}
- ,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(4, sizeof(QByteArrayData) + sizeof(char)), 0, "dataBAD"}
- };
-
-static const QByteArrayDataPtr staticStandard = { const_cast<QByteArrayData *>(&statics.standard.data) };
-static const QByteArrayDataPtr staticNotNullTerminated = { const_cast<QByteArrayData *>(&statics.notNullTerminated.data) };
-static const QByteArrayDataPtr staticShifted = { const_cast<QByteArrayData *>(&statics.shifted.data) };
-static const QByteArrayDataPtr staticShiftedNotNullTerminated = { const_cast<QByteArrayData *>(&statics.shiftedNotNullTerminated.data) };
-
-template <class T> const T &verifyZeroTermination(const T &t) { return t; }
-
-QByteArray verifyZeroTermination(const QByteArray &ba)
-{
- // This test does some evil stuff, it's all supposed to work.
-
- QByteArray::DataPtr baDataPtr = const_cast<QByteArray &>(ba).data_ptr();
-
- // Skip if isStatic() or fromRawData(), as those offer no guarantees
- if (baDataPtr->ref.isStatic()
- || baDataPtr->offset != QByteArray().data_ptr()->offset)
- return ba;
-
- int baSize = ba.size();
- char baTerminator = ba.constData()[baSize];
- if ('\0' != baTerminator)
- return QString::fromLatin1(
- "*** Result ('%1') not null-terminated: 0x%2 ***").arg(QString::fromLatin1(ba))
- .arg(baTerminator, 2, 16, QChar('0')).toLatin1();
-
- // Skip mutating checks on shared strings
- if (baDataPtr->ref.isShared())
- return ba;
-
- const char *baData = ba.constData();
- const QByteArray baCopy(baData, baSize); // Deep copy
-
- const_cast<char *>(baData)[baSize] = 'x';
- if ('x' != ba.constData()[baSize]) {
- return "*** Failed to replace null-terminator in "
- "result ('" + ba + "') ***";
- }
- if (ba != baCopy) {
- return "*** Result ('" + ba + "') differs from its copy "
- "after null-terminator was replaced ***";
- }
- const_cast<char *>(baData)[baSize] = '\0'; // Restore sanity
-
- return ba;
-}
-
-// Overriding QTest's QCOMPARE, to check QByteArray for null termination
-#undef QCOMPARE
-#define QCOMPARE(actual, expected) \
- do { \
- if (!QTest::qCompare(verifyZeroTermination(actual), expected, \
- #actual, #expected, __FILE__, __LINE__)) \
- return; \
- } while (0) \
- /**/
-#undef QTEST
-#define QTEST(actual, testElement) \
- do { \
- if (!QTest::qTest(verifyZeroTermination(actual), testElement, \
- #actual, #testElement, __FILE__, __LINE__)) \
- return; \
- } while (0) \
- /**/
-
-tst_QByteArray::tst_QByteArray()
-{
-}
-
-void tst_QByteArray::qChecksum_data()
-{
- QTest::addColumn<QByteArray>("data");
- QTest::addColumn<uint>("len");
- QTest::addColumn<Qt::ChecksumType>("standard");
- QTest::addColumn<uint>("checksum");
-
- // Examples from ISO 14443-3
- QTest::newRow("1") << QByteArray("\x00\x00") << 2U << Qt::ChecksumItuV41 << 0x1EA0U;
- QTest::newRow("2") << QByteArray("\x12\x34") << 2U << Qt::ChecksumItuV41 << 0xCF26U;
- QTest::newRow("3") << QByteArray("\x00\x00\x00") << 3U << Qt::ChecksumIso3309 << 0xC6CCU;
- QTest::newRow("4") << QByteArray("\x0F\xAA\xFF") << 3U << Qt::ChecksumIso3309 << 0xD1FCU;
- QTest::newRow("5") << QByteArray("\x0A\x12\x34\x56") << 4U << Qt::ChecksumIso3309 << 0xF62CU;
-}
-
-void tst_QByteArray::qChecksum()
-{
- QFETCH(QByteArray, data);
- QFETCH(uint, len);
- QFETCH(Qt::ChecksumType, standard);
- QFETCH(uint, checksum);
-
- if (standard == Qt::ChecksumIso3309) {
- QCOMPARE(::qChecksum(data.constData(), len), static_cast<quint16>(checksum));
- }
- QCOMPARE(::qChecksum(data.constData(), len, standard), static_cast<quint16>(checksum));
-}
-
-void tst_QByteArray::qCompress_data()
-{
- QTest::addColumn<QByteArray>("ba");
-
- const int size1 = 1024*1024;
- QByteArray ba1( size1, 0 );
-
- QTest::newRow( "00" ) << QByteArray();
-
- int i;
- for ( i=0; i<size1; i++ )
- ba1[i] = (char)( i / 1024 );
- QTest::newRow( "01" ) << ba1;
-
- for ( i=0; i<size1; i++ )
- ba1[i] = (char)( i % 256 );
- QTest::newRow( "02" ) << ba1;
-
- ba1.fill( 'A' );
- QTest::newRow( "03" ) << ba1;
-
- QFile file( QFINDTESTDATA("rfc3252.txt") );
- QVERIFY( file.open(QIODevice::ReadOnly) );
- QTest::newRow( "04" ) << file.readAll();
-}
-
-#ifndef QT_NO_COMPRESS
-void tst_QByteArray::qCompress()
-{
- QFETCH( QByteArray, ba );
- QByteArray compressed = ::qCompress( ba );
- QTEST( ::qUncompress( compressed ), "ba" );
-}
-
-void tst_QByteArray::qUncompressCorruptedData_data()
-{
- QTest::addColumn<QByteArray>("in");
-
- QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4);
- QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4);
- QTest::newRow("0x3f000000") << QByteArray("\x3f\x00\x00\x00", 4);
- QTest::newRow("0x3fffffff") << QByteArray("\x3f\xff\xff\xff", 4);
- QTest::newRow("0x7fffff00") << QByteArray("\x7f\xff\xff\x00", 4);
- QTest::newRow("0x7fffffff") << QByteArray("\x7f\xff\xff\xff", 4);
- QTest::newRow("0x80000000") << QByteArray("\x80\x00\x00\x00", 4);
- QTest::newRow("0x800000ff") << QByteArray("\x80\x00\x00\xff", 4);
- QTest::newRow("0xcf000000") << QByteArray("\xcf\x00\x00\x00", 4);
- QTest::newRow("0xcfffffff") << QByteArray("\xcf\xff\xff\xff", 4);
- QTest::newRow("0xffffff00") << QByteArray("\xff\xff\xff\x00", 4);
- QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4);
-}
-
-// Corrupt data causes this test to lock up on HP-UX / PA-RISC with gcc,
-// SOLARIS, and Windows.
-// This test is expected to produce some warning messages in the test output.
-void tst_QByteArray::qUncompressCorruptedData()
-{
-#if !(defined(Q_OS_HPUX) && !defined(__ia64) && defined(Q_CC_GNU)) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_WIN)
- QFETCH(QByteArray, in);
-
- QByteArray res;
- res = ::qUncompress(in);
- QCOMPARE(res, QByteArray());
-
- res = ::qUncompress(in + "blah");
- QCOMPARE(res, QByteArray());
-#else
- QSKIP("This test freezes on this platform");
-#endif
-}
-
-void tst_QByteArray::qCompressionZeroTermination()
-{
- QString s = "Hello, I'm a string.";
- QByteArray ba = ::qUncompress(::qCompress(s.toLocal8Bit()));
- QVERIFY((int) *(ba.data() + ba.size()) == 0);
-}
-
-#endif
-
-void tst_QByteArray::constByteArray()
-{
- const char *ptr = "abc";
- QByteArray cba = QByteArray::fromRawData(ptr, 3);
- QVERIFY(cba.constData() == ptr);
- cba.squeeze();
- QVERIFY(cba.constData() == ptr);
- cba.detach();
- QVERIFY(cba.size() == 3);
- QVERIFY(cba.capacity() == 3);
- QVERIFY(cba.constData() != ptr);
- QVERIFY(cba.constData()[0] == 'a');
- QVERIFY(cba.constData()[1] == 'b');
- QVERIFY(cba.constData()[2] == 'c');
- QVERIFY(cba.constData()[3] == '\0');
-}
-
-void tst_QByteArray::leftJustified()
-{
- QByteArray a;
- a = "ABC";
- QCOMPARE(a.leftJustified(5,'-'), QByteArray("ABC--"));
- QCOMPARE(a.leftJustified(4,'-'), QByteArray("ABC-"));
- QCOMPARE(a.leftJustified(4), QByteArray("ABC "));
- QCOMPARE(a.leftJustified(3), QByteArray("ABC"));
- QCOMPARE(a.leftJustified(2), QByteArray("ABC"));
- QCOMPARE(a.leftJustified(1), QByteArray("ABC"));
- QCOMPARE(a.leftJustified(0), QByteArray("ABC"));
-
- QByteArray n;
- QVERIFY(!n.leftJustified(3).isNull()); // I expected true
- QCOMPARE(a.leftJustified(4,' ',true), QByteArray("ABC "));
- QCOMPARE(a.leftJustified(3,' ',true), QByteArray("ABC"));
- QCOMPARE(a.leftJustified(2,' ',true), QByteArray("AB"));
- QCOMPARE(a.leftJustified(1,' ',true), QByteArray("A"));
- QCOMPARE(a.leftJustified(0,' ',true), QByteArray(""));
-}
-
-void tst_QByteArray::rightJustified()
-{
- QByteArray a;
- a="ABC";
- QCOMPARE(a.rightJustified(5,'-'),QByteArray("--ABC"));
- QCOMPARE(a.rightJustified(4,'-'),QByteArray("-ABC"));
- QCOMPARE(a.rightJustified(4),QByteArray(" ABC"));
- QCOMPARE(a.rightJustified(3),QByteArray("ABC"));
- QCOMPARE(a.rightJustified(2),QByteArray("ABC"));
- QCOMPARE(a.rightJustified(1),QByteArray("ABC"));
- QCOMPARE(a.rightJustified(0),QByteArray("ABC"));
-
- QByteArray n;
- QVERIFY(!n.rightJustified(3).isNull()); // I expected true
- QCOMPARE(a.rightJustified(4,'-',true),QByteArray("-ABC"));
- QCOMPARE(a.rightJustified(4,' ',true),QByteArray(" ABC"));
- QCOMPARE(a.rightJustified(3,' ',true),QByteArray("ABC"));
- QCOMPARE(a.rightJustified(2,' ',true),QByteArray("AB"));
- QCOMPARE(a.rightJustified(1,' ',true),QByteArray("A"));
- QCOMPARE(a.rightJustified(0,' ',true),QByteArray(""));
- QCOMPARE(a,QByteArray("ABC"));
-}
-
-void tst_QByteArray::setNum()
-{
- QByteArray a;
- QCOMPARE(a.setNum(-1), QByteArray("-1"));
- QCOMPARE(a.setNum(0), QByteArray("0"));
- QCOMPARE(a.setNum(0, 2), QByteArray("0"));
- QCOMPARE(a.setNum(0, 36), QByteArray("0"));
- QCOMPARE(a.setNum(1), QByteArray("1"));
- QCOMPARE(a.setNum(35, 36), QByteArray("z"));
- QCOMPARE(a.setNum(37, 2), QByteArray("100101"));
- QCOMPARE(a.setNum(37, 36), QByteArray("11"));
-
- // Negative numbers are only properly supported for base 10.
- QCOMPARE(a.setNum(short(-1), 16), QByteArray("ffff"));
- QCOMPARE(a.setNum(int(-1), 16), QByteArray("ffffffff"));
- QCOMPARE(a.setNum(qlonglong(-1), 16), QByteArray("ffffffffffffffff"));
-
- QCOMPARE(a.setNum(short(-1), 10), QByteArray("-1"));
- QCOMPARE(a.setNum(int(-1), 10), QByteArray("-1"));
- QCOMPARE(a.setNum(qlonglong(-1), 10), QByteArray("-1"));
-
- QCOMPARE(a.setNum(-123), QByteArray("-123"));
- QCOMPARE(a.setNum(0x123,16), QByteArray("123"));
- QCOMPARE(a.setNum((short)123), QByteArray("123"));
-
- QCOMPARE(a.setNum(1.23), QByteArray("1.23"));
- QCOMPARE(a.setNum(1.234567), QByteArray("1.23457"));
-
- // Note that there are no 'long' overloads, so not all of the
- // QString::setNum() tests can be re-used.
- QCOMPARE(a.setNum(Q_INT64_C(123)), QByteArray("123"));
- // 2^40 == 1099511627776
- QCOMPARE(a.setNum(Q_INT64_C(-1099511627776)), QByteArray("-1099511627776"));
- QCOMPARE(a.setNum(Q_UINT64_C(1099511627776)), QByteArray("1099511627776"));
- QCOMPARE(a.setNum(Q_INT64_C(9223372036854775807)), // LLONG_MAX
- QByteArray("9223372036854775807"));
- QCOMPARE(a.setNum(-Q_INT64_C(9223372036854775807) - Q_INT64_C(1)),
- QByteArray("-9223372036854775808"));
- QCOMPARE(a.setNum(Q_UINT64_C(18446744073709551615)), // ULLONG_MAX
- QByteArray("18446744073709551615"));
- QCOMPARE(a.setNum(0.000000000931322574615478515625), QByteArray("9.31323e-10"));
-}
-
-void tst_QByteArray::startsWith_data()
-{
- QTest::addColumn<QByteArray>("ba");
- QTest::addColumn<QByteArray>("sw");
- QTest::addColumn<bool>("result");
-
- QTest::newRow("01") << QByteArray() << QByteArray() << true;
- QTest::newRow("02") << QByteArray() << QByteArray("") << true;
- QTest::newRow("03") << QByteArray() << QByteArray("hallo") << false;
-
- QTest::newRow("04") << QByteArray("") << QByteArray() << true;
- QTest::newRow("05") << QByteArray("") << QByteArray("") << true;
- QTest::newRow("06") << QByteArray("") << QByteArray("h") << false;
-
- QTest::newRow("07") << QByteArray("hallo") << QByteArray("h") << true;
- QTest::newRow("08") << QByteArray("hallo") << QByteArray("hallo") << true;
- QTest::newRow("09") << QByteArray("hallo") << QByteArray("") << true;
- QTest::newRow("10") << QByteArray("hallo") << QByteArray("hallohallo") << false;
- QTest::newRow("11") << QByteArray("hallo") << QByteArray() << true;
-}
-
-void tst_QByteArray::startsWith()
-{
- QFETCH(QByteArray, ba);
- QFETCH(QByteArray, sw);
- QFETCH(bool, result);
-
- QVERIFY(ba.startsWith(sw) == result);
-
- if (sw.isNull()) {
- QVERIFY(ba.startsWith((char*)0) == result);
- } else {
- QVERIFY(ba.startsWith(sw.data()) == result);
- }
-}
-
-void tst_QByteArray::startsWith_char()
-{
- QVERIFY(QByteArray("hallo").startsWith('h'));
- QVERIFY(!QByteArray("hallo").startsWith('\0'));
- QVERIFY(!QByteArray("hallo").startsWith('o'));
- QVERIFY(QByteArray("h").startsWith('h'));
- QVERIFY(!QByteArray("h").startsWith('\0'));
- QVERIFY(!QByteArray("h").startsWith('o'));
- QVERIFY(!QByteArray("hallo").startsWith('l'));
- QVERIFY(!QByteArray("").startsWith('\0'));
- QVERIFY(!QByteArray("").startsWith('a'));
- QVERIFY(!QByteArray().startsWith('a'));
- QVERIFY(!QByteArray().startsWith('\0'));
-}
-
-void tst_QByteArray::endsWith_data()
-{
- QTest::addColumn<QByteArray>("ba");
- QTest::addColumn<QByteArray>("sw");
- QTest::addColumn<bool>("result");
-
- QTest::newRow("01") << QByteArray() << QByteArray() << true;
- QTest::newRow("02") << QByteArray() << QByteArray("") << true;
- QTest::newRow("03") << QByteArray() << QByteArray("hallo") << false;
-
- QTest::newRow("04") << QByteArray("") << QByteArray() << true;
- QTest::newRow("05") << QByteArray("") << QByteArray("") << true;
- QTest::newRow("06") << QByteArray("") << QByteArray("h") << false;
-
- QTest::newRow("07") << QByteArray("hallo") << QByteArray("o") << true;
- QTest::newRow("08") << QByteArray("hallo") << QByteArray("hallo") << true;
- QTest::newRow("09") << QByteArray("hallo") << QByteArray("") << true;
- QTest::newRow("10") << QByteArray("hallo") << QByteArray("hallohallo") << false;
- QTest::newRow("11") << QByteArray("hallo") << QByteArray() << true;
-}
-
-void tst_QByteArray::endsWith()
-{
- QFETCH(QByteArray, ba);
- QFETCH(QByteArray, sw);
- QFETCH(bool, result);
-
- QVERIFY(ba.endsWith(sw) == result);
-
- if (sw.isNull()) {
- QVERIFY(ba.endsWith((char*)0) == result);
- } else {
- QVERIFY(ba.endsWith(sw.data()) == result);
- }
-}
-
-void tst_QByteArray::endsWith_char()
-{
- QVERIFY(QByteArray("hallo").endsWith('o'));
- QVERIFY(!QByteArray("hallo").endsWith('\0'));
- QVERIFY(!QByteArray("hallo").endsWith('h'));
- QVERIFY(QByteArray("h").endsWith('h'));
- QVERIFY(!QByteArray("h").endsWith('\0'));
- QVERIFY(!QByteArray("h").endsWith('o'));
- QVERIFY(!QByteArray("hallo").endsWith('l'));
- QVERIFY(!QByteArray("").endsWith('\0'));
- QVERIFY(!QByteArray("").endsWith('a'));
- QVERIFY(!QByteArray().endsWith('a'));
- QVERIFY(!QByteArray().endsWith('\0'));
-}
-
-void tst_QByteArray::reverseIterators()
-{
- QByteArray s = "1234";
- QByteArray sr = s;
- std::reverse(sr.begin(), sr.end());
- const QByteArray &csr = sr;
- QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin()));
- QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin()));
- QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin()));
- QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin()));
- QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin()));
- QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin()));
-}
-
-void tst_QByteArray::split_data()
-{
- QTest::addColumn<QByteArray>("sample");
- QTest::addColumn<int>("size");
-
- QTest::newRow("1") << QByteArray("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile") << 14;
- QTest::newRow("2") << QByteArray("abcde") << 1;
- QTest::newRow("one empty") << QByteArray("") << 1;
- QTest::newRow("two empty") << QByteArray(" ") << 2;
- QTest::newRow("three empty") << QByteArray(" ") << 3;
-
-}
-
-void tst_QByteArray::split()
-{
- QFETCH(QByteArray, sample);
- QFETCH(int, size);
-
- QList<QByteArray> list = sample.split(' ');
- QCOMPARE(list.count(), size);
-}
-
-void tst_QByteArray::swap()
-{
- QByteArray b1 = "b1", b2 = "b2";
- b1.swap(b2);
- QCOMPARE(b1, QByteArray("b2"));
- QCOMPARE(b2, QByteArray("b1"));
-}
-
-void tst_QByteArray::base64_data()
-{
- QTest::addColumn<QByteArray>("rawdata");
- QTest::addColumn<QByteArray>("base64");
-
- QTest::newRow("1") << QByteArray("") << QByteArray("");
- QTest::newRow("2") << QByteArray("1") << QByteArray("MQ==");
- QTest::newRow("3") << QByteArray("12") << QByteArray("MTI=");
- QTest::newRow("4") << QByteArray("123") << QByteArray("MTIz");
- QTest::newRow("5") << QByteArray("1234") << QByteArray("MTIzNA==");
- QTest::newRow("6") << QByteArray("\n") << QByteArray("Cg==");
- QTest::newRow("7") << QByteArray("a\n") << QByteArray("YQo=");
- QTest::newRow("8") << QByteArray("ab\n") << QByteArray("YWIK");
- QTest::newRow("9") << QByteArray("abc\n") << QByteArray("YWJjCg==");
- QTest::newRow("a") << QByteArray("abcd\n") << QByteArray("YWJjZAo=");
- QTest::newRow("b") << QByteArray("abcde\n") << QByteArray("YWJjZGUK");
- QTest::newRow("c") << QByteArray("abcdef\n") << QByteArray("YWJjZGVmCg==");
- QTest::newRow("d") << QByteArray("abcdefg\n") << QByteArray("YWJjZGVmZwo=");
- QTest::newRow("e") << QByteArray("abcdefgh\n") << QByteArray("YWJjZGVmZ2gK");
-
- QByteArray ba;
- ba.resize(256);
- for (int i = 0; i < 256; ++i)
- ba[i] = i;
- QTest::newRow("f") << ba << QByteArray("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==");
-
- QTest::newRow("g") << QByteArray("foo\0bar", 7) << QByteArray("Zm9vAGJhcg==");
- QTest::newRow("h") << QByteArray("f\xd1oo\x9ctar") << QByteArray("ZtFvb5x0YXI=");
- QTest::newRow("i") << QByteArray("\"\0\0\0\0\0\0\"", 8) << QByteArray("IgAAAAAAACI=");
-}
-
-
-void tst_QByteArray::base64()
-{
- QFETCH(QByteArray, rawdata);
- QFETCH(QByteArray, base64);
-
- QByteArray arr = QByteArray::fromBase64(base64);
- QCOMPARE(arr, rawdata);
-
- QByteArray arr64 = rawdata.toBase64();
- QCOMPARE(arr64, base64);
-
- arr64 = rawdata.toBase64(QByteArray::Base64Encoding);
- QCOMPARE(arr64, base64);
-
- QByteArray base64noequals = base64;
- base64noequals.replace('=', "");
- arr64 = rawdata.toBase64(QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals);
- QCOMPARE(arr64, base64noequals);
-
- QByteArray base64url = base64;
- base64url.replace('/', '_').replace('+', '-');
- arr64 = rawdata.toBase64(QByteArray::Base64UrlEncoding);
- QCOMPARE(arr64, base64url);
-
- QByteArray base64urlnoequals = base64url;
- base64urlnoequals.replace('=', "");
- arr64 = rawdata.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
- QCOMPARE(arr64, base64urlnoequals);
-}
-
-//different from the previous test as the input are invalid
-void tst_QByteArray::fromBase64_data()
-{
- QTest::addColumn<QByteArray>("rawdata");
- QTest::addColumn<QByteArray>("base64");
-
- QTest::newRow("1") << QByteArray("") << QByteArray(" ");
- QTest::newRow("2") << QByteArray("1") << QByteArray("MQ");
- QTest::newRow("3") << QByteArray("12") << QByteArray("MTI ");
- QTest::newRow("4") << QByteArray("123") << QByteArray("M=TIz");
- QTest::newRow("5") << QByteArray("1234") << QByteArray("MTI zN A ");
- QTest::newRow("6") << QByteArray("\n") << QByteArray("Cg");
- QTest::newRow("7") << QByteArray("a\n") << QByteArray("======YQo=");
- QTest::newRow("8") << QByteArray("ab\n") << QByteArray("Y\nWIK");
- QTest::newRow("9") << QByteArray("abc\n") << QByteArray("YWJjCg==");
- QTest::newRow("a") << QByteArray("abcd\n") << QByteArray("YWJ\1j\x9cZAo=");
- QTest::newRow("b") << QByteArray("abcde\n") << QByteArray("YW JjZ\n G\tUK");
- QTest::newRow("c") << QByteArray("abcdef\n") << QByteArray("YWJjZGVmCg=");
- QTest::newRow("d") << QByteArray("abcdefg\n") << QByteArray("YWJ\rjZGVmZwo");
- QTest::newRow("e") << QByteArray("abcdefgh\n") << QByteArray("YWJjZGVmZ2gK");
-
- QByteArray ba;
- ba.resize(256);
- for (int i = 0; i < 256; ++i)
- ba[i] = i;
- QTest::newRow("f") << ba << QByteArray("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Nj\n"
- "c4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1u\n"
- "b3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpa\n"
- "anqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd\n"
- "3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w== ");
-
-
- QTest::newRow("g") << QByteArray("foo\0bar", 7) << QByteArray("Zm9vAGJhcg");
- QTest::newRow("h") << QByteArray("f\xd1oo\x9ctar") << QByteArray("ZtFvb5x0YXI=");
- QTest::newRow("i") << QByteArray("\"\0\0\0\0\0\0\"", 8) << QByteArray("IgAAAAAAACI");
-
-}
-
-
-void tst_QByteArray::fromBase64()
-{
- QFETCH(QByteArray, rawdata);
- QFETCH(QByteArray, base64);
-
- QByteArray arr = QByteArray::fromBase64(base64);
- QCOMPARE(arr, rawdata);
-
- arr = QByteArray::fromBase64(base64, QByteArray::Base64Encoding);
- QCOMPARE(arr, rawdata);
-
- // try "base64url" encoding
- QByteArray base64url = base64;
- base64url.replace('/', '_').replace('+', '-');
- arr = QByteArray::fromBase64(base64url, QByteArray::Base64UrlEncoding);
- QCOMPARE(arr, rawdata);
-
- if (base64 != base64url) {
- // check that the invalid decodings fail
- arr = QByteArray::fromBase64(base64, QByteArray::Base64UrlEncoding);
- QVERIFY(arr != rawdata);
- arr = QByteArray::fromBase64(base64url, QByteArray::Base64Encoding);
- QVERIFY(arr != rawdata);
- }
-}
-
-void tst_QByteArray::qvsnprintf()
-{
- char buf[20];
- memset(buf, 42, sizeof(buf));
-
- QCOMPARE(::qsnprintf(buf, 10, "%s", "bubu"), 4);
- QCOMPARE(static_cast<const char *>(buf), "bubu");
-#ifndef Q_CC_MSVC
- // MSVC implementation of vsnprintf overwrites bytes after null terminator so this would fail.
- QCOMPARE(buf[5], char(42));
-#endif
-
- memset(buf, 42, sizeof(buf));
- QCOMPARE(::qsnprintf(buf, 5, "%s", "bubu"), 4);
- QCOMPARE(static_cast<const char *>(buf), "bubu");
- QCOMPARE(buf[5], char(42));
-
- memset(buf, 42, sizeof(buf));
-#ifdef Q_OS_WIN
- // VS 2005 uses the Qt implementation of vsnprintf.
-# if defined(_MSC_VER)
- QCOMPARE(::qsnprintf(buf, 3, "%s", "bubu"), -1);
- QCOMPARE(static_cast<const char*>(buf), "bu");
-# else
- // windows has to do everything different, of course.
- QCOMPARE(::qsnprintf(buf, 3, "%s", "bubu"), -1);
- buf[19] = '\0';
- QCOMPARE(static_cast<const char *>(buf), "bub****************");
-# endif
-#else
- QCOMPARE(::qsnprintf(buf, 3, "%s", "bubu"), 4);
- QCOMPARE(static_cast<const char*>(buf), "bu");
-#endif
- QCOMPARE(buf[4], char(42));
-
-#ifndef Q_OS_WIN
- memset(buf, 42, sizeof(buf));
- QCOMPARE(::qsnprintf(buf, 10, ""), 0);
-#endif
-}
-
-
-void tst_QByteArray::qstrlen()
-{
- const char *src = "Something about ... \0 a string.";
- QCOMPARE(::qstrlen((char*)0), (uint)0);
- QCOMPARE(::qstrlen(src), (uint)20);
-}
-
-void tst_QByteArray::qstrnlen()
-{
- const char *src = "Something about ... \0 a string.";
- QCOMPARE(::qstrnlen((char*)0, 1), (uint)0);
- QCOMPARE(::qstrnlen(src, 31), (uint)20);
- QCOMPARE(::qstrnlen(src, 19), (uint)19);
- QCOMPARE(::qstrnlen(src, 21), (uint)20);
- QCOMPARE(::qstrnlen(src, 20), (uint)20);
-}
-
-void tst_QByteArray::qstrcpy()
-{
- const char *src = "Something about ... \0 a string.";
- const char *expected = "Something about ... ";
- char dst[128];
-
- QCOMPARE(::qstrcpy(0, 0), (char*)0);
- QCOMPARE(::qstrcpy(dst, 0), (char*)0);
-
- QCOMPARE(::qstrcpy(dst ,src), (char *)dst);
- QCOMPARE((char *)dst, const_cast<char *>(expected));
-}
-
-void tst_QByteArray::qstrncpy()
-{
- QByteArray src(1024, 'a'), dst(1024, 'b');
-
- // dst == nullptr
- QCOMPARE(::qstrncpy(0, src.data(), 0), (char*)0);
- QCOMPARE(::qstrncpy(0, src.data(), 10), (char*)0);
-
- // src == nullptr
- QCOMPARE(::qstrncpy(dst.data(), 0, 0), (char*)0);
- QCOMPARE(::qstrncpy(dst.data(), 0, 10), (char*)0);
-
- // valid pointers, but len == 0
- QCOMPARE(::qstrncpy(dst.data(), src.data(), 0), dst.data());
- QCOMPARE(*dst.data(), 'b'); // must not have written to dst
-
- // normal copy
- QCOMPARE(::qstrncpy(dst.data(), src.data(), src.size()), dst.data());
-
- src = QByteArray( "Tumdelidum" );
- QCOMPARE(QByteArray(::qstrncpy(dst.data(), src.data(), src.size())),
- QByteArray("Tumdelidu"));
-
- // normal copy with length is longer than necessary
- src = QByteArray( "Tumdelidum\0foo" );
- dst.resize(128*1024);
- QCOMPARE(QByteArray(::qstrncpy(dst.data(), src.data(), dst.size())),
- QByteArray("Tumdelidum"));
-}
-
-void tst_QByteArray::qstricmp_data()
-{
- QTest::addColumn<QString>("str1");
- QTest::addColumn<QString>("str2");
-
- QTest::newRow("equal 1") << "abcEdb" << "abcEdb";
- QTest::newRow("equal 2") << "abcEdb" << "ABCeDB";
- QTest::newRow("equal 3") << "ABCEDB" << "abcedb";
- QTest::newRow("less 1") << "abcdef" << "abcdefg";
- QTest::newRow("less 2") << "abcdeF" << "abcdef";
- QTest::newRow("greater 1") << "abcdef" << "abcdeF";
- QTest::newRow("greater 2") << "abcdefg" << "abcdef";
-}
-
-void tst_QByteArray::qstricmp()
-{
- QFETCH(QString, str1);
- QFETCH(QString, str2);
-
- int expected = strcmp(str1.toUpper().toLatin1(),
- str2.toUpper().toLatin1());
- if ( expected != 0 ) {
- expected = (expected < 0 ? -1 : 1);
- }
- int actual = ::qstricmp(str1.toLatin1(), str2.toLatin1());
- if ( actual != 0 ) {
- actual = (actual < 0 ? -1 : 1);
- }
- QCOMPARE(actual, expected);
-
- actual = ::qstricmp("012345679abcd" + str1.toLatin1(), "012345679AbCd" + str2.toLatin1());
- if ( actual != 0 ) {
- actual = (actual < 0 ? -1 : 1);
- }
- QCOMPARE(actual, expected);
-
- actual = str1.toLatin1().compare(str2.toLatin1(), Qt::CaseInsensitive);
- if ( actual != 0 ) {
- actual = (actual < 0 ? -1 : 1);
- }
- QCOMPARE(actual, expected);
-
- actual = str1.toLatin1().compare(str2.toLatin1().constData(), Qt::CaseInsensitive);
- if ( actual != 0 ) {
- actual = (actual < 0 ? -1 : 1);
- }
- QCOMPARE(actual, expected);
-}
-
-void tst_QByteArray::qstricmp_singularities()
-{
- QCOMPARE(::qstricmp(0, 0), 0);
- QVERIFY(::qstricmp(0, "a") < 0);
- QVERIFY(::qstricmp("a", 0) > 0);
- QCOMPARE(::qstricmp("", ""), 0);
- QCOMPARE(QByteArray().compare(nullptr, Qt::CaseInsensitive), 0);
- QCOMPARE(QByteArray().compare("", Qt::CaseInsensitive), 0);
- QVERIFY(QByteArray("a").compare(nullptr, Qt::CaseInsensitive) > 0);
- QVERIFY(QByteArray("a").compare("", Qt::CaseInsensitive) > 0);
- QVERIFY(QByteArray().compare("a", Qt::CaseInsensitive) < 0);
-}
-
-void tst_QByteArray::qstrnicmp_singularities()
-{
- QCOMPARE(::qstrnicmp(0, 0, 123), 0);
- QVERIFY(::qstrnicmp(0, "a", 123) != 0);
- QVERIFY(::qstrnicmp("a", 0, 123) != 0);
- QCOMPARE(::qstrnicmp("", "", 123), 0);
- QCOMPARE(::qstrnicmp("a", "B", 0), 0);
- QCOMPARE(QByteArray().compare(QByteArray(), Qt::CaseInsensitive), 0);
- QVERIFY(QByteArray().compare(QByteArray("a"), Qt::CaseInsensitive) < 0);
- QVERIFY(QByteArray("a").compare(QByteArray(), Qt::CaseInsensitive) > 0);
-}
-
-void tst_QByteArray::chop_data()
-{
- QTest::addColumn<QByteArray>("src");
- QTest::addColumn<int>("choplength");
- QTest::addColumn<QByteArray>("expected");
-
- QTest::newRow("1") << QByteArray("short1") << 128 << QByteArray();
- QTest::newRow("2") << QByteArray("short2") << int(strlen("short2"))
- << QByteArray();
- QTest::newRow("3") << QByteArray("abcdef\0foo", 10) << 2
- << QByteArray("abcdef\0f", 8);
- QTest::newRow("4") << QByteArray("STARTTLS\r\n") << 2
- << QByteArray("STARTTLS");
- QTest::newRow("5") << QByteArray("") << 1 << QByteArray();
- QTest::newRow("6") << QByteArray("foo") << 0 << QByteArray("foo");
- QTest::newRow("7") << QByteArray(0) << 28 << QByteArray();
-}
-
-void tst_QByteArray::chop()
-{
- QFETCH(QByteArray, src);
- QFETCH(int, choplength);
- QFETCH(QByteArray, expected);
-
- src.chop(choplength);
- QCOMPARE(src, expected);
-}
-
-void tst_QByteArray::prepend()
-{
- QByteArray ba("foo");
- QCOMPARE(ba.prepend((char*)0), QByteArray("foo"));
- QCOMPARE(ba.prepend(QByteArray()), QByteArray("foo"));
- QCOMPARE(ba.prepend("1"), QByteArray("1foo"));
- QCOMPARE(ba.prepend(QByteArray("2")), QByteArray("21foo"));
- QCOMPARE(ba.prepend('3'), QByteArray("321foo"));
- QCOMPARE(ba.prepend(-1, 'x'), QByteArray("321foo"));
- QCOMPARE(ba.prepend(3, 'x'), QByteArray("xxx321foo"));
- QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 xxx321foo", 11));
-}
-
-void tst_QByteArray::prependExtended_data()
-{
- QTest::addColumn<QByteArray>("array");
- QTest::newRow("literal") << QByteArray(QByteArrayLiteral("data"));
- QTest::newRow("standard") << QByteArray(staticStandard);
- QTest::newRow("shifted") << QByteArray(staticShifted);
- QTest::newRow("notNullTerminated") << QByteArray(staticNotNullTerminated);
- QTest::newRow("shiftedNotNullTerminated") << QByteArray(staticShiftedNotNullTerminated);
- QTest::newRow("non static data") << QByteArray("data");
- QTest::newRow("from raw data") << QByteArray::fromRawData("data", 4);
- QTest::newRow("from raw data not terminated") << QByteArray::fromRawData("dataBAD", 4);
-}
-
-void tst_QByteArray::prependExtended()
-{
- QFETCH(QByteArray, array);
-
- QCOMPARE(QByteArray().prepend(array), QByteArray("data"));
- QCOMPARE(QByteArray("").prepend(array), QByteArray("data"));
-
- QCOMPARE(array.prepend((char*)0), QByteArray("data"));
- QCOMPARE(array.prepend(QByteArray()), QByteArray("data"));
- QCOMPARE(array.prepend("1"), QByteArray("1data"));
- QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data"));
- QCOMPARE(array.prepend('3'), QByteArray("321data"));
- QCOMPARE(array.prepend(-1, 'x'), QByteArray("321data"));
- QCOMPARE(array.prepend(3, 'x'), QByteArray("xxx321data"));
- QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 xxx321data", 12));
- QCOMPARE(array.size(), 12);
-}
-
-void tst_QByteArray::append()
-{
- QByteArray ba("foo");
- QCOMPARE(ba.append((char*)0), QByteArray("foo"));
- QCOMPARE(ba.append(QByteArray()), QByteArray("foo"));
- QCOMPARE(ba.append("1"), QByteArray("foo1"));
- QCOMPARE(ba.append(QByteArray("2")), QByteArray("foo12"));
- QCOMPARE(ba.append('3'), QByteArray("foo123"));
- QCOMPARE(ba.append(-1, 'x'), QByteArray("foo123"));
- QCOMPARE(ba.append(3, 'x'), QByteArray("foo123xxx"));
- QCOMPARE(ba.append("\0"), QByteArray("foo123xxx"));
- QCOMPARE(ba.append("\0", 1), QByteArray::fromRawData("foo123xxx\0", 10));
- QCOMPARE(ba.size(), 10);
-}
-
-void tst_QByteArray::appendExtended_data()
-{
- prependExtended_data();
-}
-
-void tst_QByteArray::appendExtended()
-{
- QFETCH(QByteArray, array);
-
- QCOMPARE(QByteArray().append(array), QByteArray("data"));
- QCOMPARE(QByteArray("").append(array), QByteArray("data"));
-
- QCOMPARE(array.append((char*)0), QByteArray("data"));
- QCOMPARE(array.append(QByteArray()), QByteArray("data"));
- QCOMPARE(array.append("1"), QByteArray("data1"));
- QCOMPARE(array.append(QByteArray("2")), QByteArray("data12"));
- QCOMPARE(array.append('3'), QByteArray("data123"));
- QCOMPARE(array.append(-1, 'x'), QByteArray("data123"));
- QCOMPARE(array.append(3, 'x'), QByteArray("data123xxx"));
- QCOMPARE(array.append("\0"), QByteArray("data123xxx"));
- QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123xxx\0", 11));
- QCOMPARE(array.size(), 11);
-}
-
-void tst_QByteArray::insert()
-{
- QByteArray ba("Meal");
- QCOMPARE(ba.insert(1, QByteArray("ontr")), QByteArray("Montreal"));
- QCOMPARE(ba.insert(ba.size(), "foo"), QByteArray("Montrealfoo"));
-
- ba = QByteArray("13");
- QCOMPARE(ba.insert(1, QByteArray("2")), QByteArray("123"));
-
- ba = "ac";
- QCOMPARE(ba.insert(1, 'b'), QByteArray("abc"));
- QCOMPARE(ba.size(), 3);
-
- ba = "ac";
- QCOMPARE(ba.insert(-1, 3, 'x'), QByteArray("ac"));
- QCOMPARE(ba.insert(1, 3, 'x'), QByteArray("axxxc"));
- QCOMPARE(ba.insert(6, 3, 'x'), QByteArray("axxxc xxx"));
- QCOMPARE(ba.size(), 9);
-
- ba = "ikl";
- QCOMPARE(ba.insert(1, "j"), QByteArray("ijkl"));
- QCOMPARE(ba.size(), 4);
-
- ba = "ab";
- QCOMPARE(ba.insert(1, "\0X\0", 3), QByteArray::fromRawData("a\0X\0b", 5));
- QCOMPARE(ba.size(), 5);
-}
-
-void tst_QByteArray::insertExtended_data()
-{
- prependExtended_data();
-}
-
-void tst_QByteArray::insertExtended()
-{
- QFETCH(QByteArray, array);
- QCOMPARE(array.insert(1, "i"), QByteArray("diata"));
- QCOMPARE(array.insert(1, 3, 'x'), QByteArray("dxxxiata"));
- QCOMPARE(array.size(), 8);
-}
-
-void tst_QByteArray::remove_data()
-{
- QTest::addColumn<QByteArray>("src");
- QTest::addColumn<int>("position");
- QTest::addColumn<int>("length");
- QTest::addColumn<QByteArray>("expected");
-
- QTest::newRow("1") << QByteArray("Montreal") << 1 << 4
- << QByteArray("Meal");
- QTest::newRow("2") << QByteArray() << 10 << 10 << QByteArray();
- QTest::newRow("3") << QByteArray("hi") << 0 << 10 << QByteArray();
- QTest::newRow("4") << QByteArray("Montreal") << 4 << 100
- << QByteArray("Mont");
-
- // index out of range
- QTest::newRow("5") << QByteArray("Montreal") << 8 << 1
- << QByteArray("Montreal");
- QTest::newRow("6") << QByteArray("Montreal") << 18 << 4
- << QByteArray("Montreal");
-}
-
-void tst_QByteArray::remove()
-{
- QFETCH(QByteArray, src);
- QFETCH(int, position);
- QFETCH(int, length);
- QFETCH(QByteArray, expected);
- QCOMPARE(src.remove(position, length), expected);
-}
-
-void tst_QByteArray::replace_data()
-{
- QTest::addColumn<QByteArray>("src");
- QTest::addColumn<int>("pos");
- QTest::addColumn<int>("len");
- QTest::addColumn<QByteArray>("after");
- QTest::addColumn<QByteArray>("expected");
-
- QTest::newRow("1") << QByteArray("Say yes!") << 4 << 3
- << QByteArray("no") << QByteArray("Say no!");
- QTest::newRow("2") << QByteArray("rock and roll") << 5 << 3
- << QByteArray("&") << QByteArray("rock & roll");
- QTest::newRow("3") << QByteArray("foo") << 3 << 0 << QByteArray("bar")
- << QByteArray("foobar");
- QTest::newRow("4") << QByteArray() << 0 << 0 << QByteArray() << QByteArray();
- // index out of range
- QTest::newRow("5") << QByteArray() << 3 << 0 << QByteArray("hi")
- << QByteArray(" hi");
- // Optimized path
- QTest::newRow("6") << QByteArray("abcdef") << 3 << 12 << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijkl");
- QTest::newRow("7") << QByteArray("abcdef") << 3 << 4 << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijkl");
- QTest::newRow("8") << QByteArray("abcdef") << 3 << 3 << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijkl");
- QTest::newRow("9") << QByteArray("abcdef") << 3 << 2 << QByteArray("abcdefghijkl") << QByteArray("abcabcdefghijklf");
- QTest::newRow("10") << QByteArray("abcdef") << 2 << 2 << QByteArray("xx") << QByteArray("abxxef");
-}
-
-void tst_QByteArray::replace()
-{
- QFETCH(QByteArray, src);
- QFETCH(int, pos);
- QFETCH(int, len);
- QFETCH(QByteArray, after);
- QFETCH(QByteArray, expected);
-
- QByteArray str1 = src;
- QByteArray str2 = src;
-
- QCOMPARE(str1.replace(pos, len, after).constData(), expected.constData());
- QCOMPARE(str2.replace(pos, len, after.data()), expected);
-}
-
-void tst_QByteArray::replaceWithSpecifiedLength()
-{
- const char after[] = "zxc\0vbnmqwert";
- int lenAfter = 6;
- QByteArray ba("abcdefghjk");
- ba.replace(0,2,after,lenAfter);
-
- const char _expected[] = "zxc\0vbcdefghjk";
- QByteArray expected(_expected,sizeof(_expected)-1);
- QCOMPARE(ba,expected);
-}
-
-void tst_QByteArray::indexOf_data()
-{
- QTest::addColumn<QByteArray>("haystack");
- QTest::addColumn<QByteArray>("needle");
- QTest::addColumn<int>("startpos");
- QTest::addColumn<int>("expected");
-
- QTest::newRow( "1" ) << QByteArray("abc") << QByteArray("a") << 0 << 0;
- QTest::newRow( "2" ) << QByteArray("abc") << QByteArray("A") << 0 << -1;
- QTest::newRow( "3" ) << QByteArray("abc") << QByteArray("a") << 1 << -1;
- QTest::newRow( "4" ) << QByteArray("abc") << QByteArray("A") << 1 << -1;
- QTest::newRow( "5" ) << QByteArray("abc") << QByteArray("b") << 0 << 1;
- QTest::newRow( "6" ) << QByteArray("abc") << QByteArray("B") << 0 << -1;
- QTest::newRow( "7" ) << QByteArray("abc") << QByteArray("b") << 1 << 1;
- QTest::newRow( "8" ) << QByteArray("abc") << QByteArray("B") << 1 << -1;
- QTest::newRow( "9" ) << QByteArray("abc") << QByteArray("b") << 2 << -1;
- QTest::newRow( "10" ) << QByteArray("abc") << QByteArray("c") << 0 << 2;
- QTest::newRow( "11" ) << QByteArray("abc") << QByteArray("C") << 0 << -1;
- QTest::newRow( "12" ) << QByteArray("abc") << QByteArray("c") << 1 << 2;
- QTest::newRow( "13" ) << QByteArray("abc") << QByteArray("C") << 1 << -1;
- QTest::newRow( "14" ) << QByteArray("abc") << QByteArray("c") << 2 << 2;
- QTest::newRow( "15" ) << QByteArray("aBc") << QByteArray("bc") << 0 << -1;
- QTest::newRow( "16" ) << QByteArray("aBc") << QByteArray("Bc") << 0 << 1;
- QTest::newRow( "17" ) << QByteArray("aBc") << QByteArray("bC") << 0 << -1;
- QTest::newRow( "18" ) << QByteArray("aBc") << QByteArray("BC") << 0 << -1;
-
- static const char h19[] = {'x', 0x00, (char)0xe7, 0x25, 0x1c, 0x0a};
- static const char n19[] = {0x00, 0x00, 0x01, 0x00};
- QTest::newRow( "19" ) << QByteArray(h19, sizeof(h19))
- << QByteArray(n19, sizeof(n19)) << 0 << -1;
-
- QTest::newRow( "empty" ) << QByteArray("") << QByteArray("x") << 0 << -1;
- QTest::newRow( "null" ) << QByteArray() << QByteArray("x") << 0 << -1;
- QTest::newRow( "null-in-null") << QByteArray() << QByteArray() << 0 << 0;
- QTest::newRow( "empty-in-null") << QByteArray() << QByteArray("") << 0 << 0;
- QTest::newRow( "null-in-empty") << QByteArray("") << QByteArray() << 0 << 0;
- QTest::newRow( "empty-in-empty") << QByteArray("") << QByteArray("") << 0 << 0;
-
- QByteArray veryBigHaystack(500, 'a');
- veryBigHaystack += 'B';
- QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << 0;
- QTest::newRow("BoyerMooreStressTest2") << QByteArray(veryBigHaystack + 'c') << QByteArray(veryBigHaystack) << 0 << 0;
- QTest::newRow("BoyerMooreStressTest3") << QByteArray('c' + veryBigHaystack) << QByteArray(veryBigHaystack) << 0 << 1;
- QTest::newRow("BoyerMooreStressTest4") << QByteArray(veryBigHaystack) << QByteArray(veryBigHaystack + 'c') << 0 << -1;
- QTest::newRow("BoyerMooreStressTest5") << QByteArray(veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1;
- QTest::newRow("BoyerMooreStressTest6") << QByteArray('d' + veryBigHaystack) << QByteArray('c' + veryBigHaystack) << 0 << -1;
- QTest::newRow("BoyerMooreStressTest7") << QByteArray(veryBigHaystack + 'c') << QByteArray('c' + veryBigHaystack) << 0 << -1;
-}
-
-void tst_QByteArray::indexOf()
-{
- QFETCH( QByteArray, haystack );
- QFETCH( QByteArray, needle );
- QFETCH( int, startpos );
- QFETCH( int, expected );
-
- bool hasNull = needle.contains('\0');
-
- QCOMPARE( haystack.indexOf(needle, startpos), expected );
- if (!hasNull)
- QCOMPARE( haystack.indexOf(needle.data(), startpos), expected );
- if (needle.size() == 1)
- QCOMPARE( haystack.indexOf(needle.at(0), startpos), expected );
-
- if (startpos == 0) {
- QCOMPARE( haystack.indexOf(needle), expected );
- if (!hasNull)
- QCOMPARE( haystack.indexOf(needle.data()), expected );
- if (needle.size() == 1)
- QCOMPARE( haystack.indexOf(needle.at(0)), expected );
- }
-}
-
-void tst_QByteArray::lastIndexOf_data()
-{
- QTest::addColumn<QByteArray>("haystack");
- QTest::addColumn<QByteArray>("needle");
- QTest::addColumn<int>("startpos");
- QTest::addColumn<int>("expected");
-
- QTest::newRow( "1" ) << QByteArray("abc") << QByteArray("a") << 0 << 0;
- QTest::newRow( "2" ) << QByteArray("abc") << QByteArray("A") << 0 << -1;
- QTest::newRow( "3" ) << QByteArray("abc") << QByteArray("a") << 1 << 0;
- QTest::newRow( "4" ) << QByteArray("abc") << QByteArray("A") << 1 << -1;
- QTest::newRow( "5" ) << QByteArray("abc") << QByteArray("a") << -1 << 0;
- QTest::newRow( "6" ) << QByteArray("abc") << QByteArray("b") << 0 << -1;
- QTest::newRow( "7" ) << QByteArray("abc") << QByteArray("B") << 0 << -1;
- QTest::newRow( "8" ) << QByteArray("abc") << QByteArray("b") << 1 << 1;
- QTest::newRow( "9" ) << QByteArray("abc") << QByteArray("B") << 1 << -1;
- QTest::newRow( "10" ) << QByteArray("abc") << QByteArray("b") << 2 << 1;
- QTest::newRow( "11" ) << QByteArray("abc") << QByteArray("b") << -1 << 1;
- QTest::newRow( "12" ) << QByteArray("abc") << QByteArray("c") << 0 << -1;
- QTest::newRow( "13" ) << QByteArray("abc") << QByteArray("C") << 0 << -1;
- QTest::newRow( "14" ) << QByteArray("abc") << QByteArray("c") << 1 << -1;
- QTest::newRow( "15" ) << QByteArray("abc") << QByteArray("C") << 1 << -1;
- QTest::newRow( "16" ) << QByteArray("abc") << QByteArray("c") << 2 << 2;
- QTest::newRow( "17" ) << QByteArray("abc") << QByteArray("c") << -1 << 2;
- QTest::newRow( "18" ) << QByteArray("aBc") << QByteArray("bc") << 0 << -1;
- QTest::newRow( "19" ) << QByteArray("aBc") << QByteArray("Bc") << 0 << -1;
- QTest::newRow( "20" ) << QByteArray("aBc") << QByteArray("Bc") << 2 << 1;
- QTest::newRow( "21" ) << QByteArray("aBc") << QByteArray("Bc") << 1 << 1;
- QTest::newRow( "22" ) << QByteArray("aBc") << QByteArray("Bc") << -1 << 1;
- QTest::newRow( "23" ) << QByteArray("aBc") << QByteArray("bC") << 0 << -1;
- QTest::newRow( "24" ) << QByteArray("aBc") << QByteArray("BC") << 0 << -1;
-
- static const char h25[] = {0x00, (char)0xbc, 0x03, 0x10, 0x0a };
- static const char n25[] = {0x00, 0x00, 0x01, 0x00};
- QTest::newRow( "25" ) << QByteArray(h25, sizeof(h25))
- << QByteArray(n25, sizeof(n25)) << 0 << -1;
-
- QTest::newRow( "empty" ) << QByteArray("") << QByteArray("x") << -1 << -1;
- QTest::newRow( "null" ) << QByteArray() << QByteArray("x") << -1 << -1;
- QTest::newRow( "null-in-null") << QByteArray() << QByteArray() << -1 << 0;
- QTest::newRow( "empty-in-null") << QByteArray() << QByteArray("") << -1 << 0;
- QTest::newRow( "null-in-empty") << QByteArray("") << QByteArray() << -1 << 0;
- QTest::newRow( "empty-in-empty") << QByteArray("") << QByteArray("") << -1 << 0;
-}
-
-void tst_QByteArray::lastIndexOf()
-{
- QFETCH( QByteArray, haystack );
- QFETCH( QByteArray, needle );
- QFETCH( int, startpos );
- QFETCH( int, expected );
-
- bool hasNull = needle.contains('\0');
-
- QCOMPARE( haystack.lastIndexOf(needle, startpos), expected );
- if (!hasNull)
- QCOMPARE( haystack.lastIndexOf(needle.data(), startpos), expected );
- if (needle.size() == 1)
- QCOMPARE( haystack.lastIndexOf(needle.at(0), startpos), expected );
-
- if (startpos == -1) {
- QCOMPARE( haystack.lastIndexOf(needle), expected );
- if (!hasNull)
- QCOMPARE( haystack.lastIndexOf(needle.data()), expected );
- if (needle.size() == 1)
- QCOMPARE( haystack.lastIndexOf(needle.at(0)), expected );
- }
-}
-
-void tst_QByteArray::number()
-{
- QCOMPARE(QString(QByteArray::number((quint64) 0)),
- QString(QByteArray("0")));
- QCOMPARE(QString(QByteArray::number(Q_UINT64_C(0xFFFFFFFFFFFFFFFF))),
- QString(QByteArray("18446744073709551615")));
- QCOMPARE(QString(QByteArray::number(Q_INT64_C(0xFFFFFFFFFFFFFFFF))),
- QString(QByteArray("-1")));
- QCOMPARE(QString(QByteArray::number(qint64(0))),
- QString(QByteArray("0")));
- QCOMPARE(QString(QByteArray::number(Q_INT64_C(0x7FFFFFFFFFFFFFFF))),
- QString(QByteArray("9223372036854775807")));
- QCOMPARE(QString(QByteArray::number(Q_INT64_C(0x8000000000000000))),
- QString(QByteArray("-9223372036854775808")));
-}
-
-// defined later
-extern const char globalChar;
-
-void tst_QByteArray::toInt_data()
-{
- QTest::addColumn<QByteArray>("string");
- QTest::addColumn<int>("base");
- QTest::addColumn<int>("expectednumber");
- QTest::addColumn<bool>("expectedok");
-
- QTest::newRow("base 10") << QByteArray("100") << 10 << int(100) << true;
- QTest::newRow("base 16-1") << QByteArray("100") << 16 << int(256) << true;
- QTest::newRow("base 16-2") << QByteArray("0400") << 16 << int(1024) << true;
- QTest::newRow("base 2") << QByteArray("1111") << 2 << int(15) << true;
- QTest::newRow("base 8") << QByteArray("100") << 8 << int(64) << true;
- QTest::newRow("base 0-1") << QByteArray("0x10") << 0 << int(16) << true;
- QTest::newRow("base 0-2") << QByteArray("10") << 0 << int(10) << true;
- QTest::newRow("base 0-3") << QByteArray("010") << 0 << int(8) << true;
- QTest::newRow("empty") << QByteArray() << 0 << int(0) << false;
-
- QTest::newRow("leading space") << QByteArray(" 100") << 10 << int(100) << true;
- QTest::newRow("trailing space") << QByteArray("100 ") << 10 << int(100) << true;
- QTest::newRow("leading junk") << QByteArray("x100") << 10 << int(0) << false;
- QTest::newRow("trailing junk") << QByteArray("100x") << 10 << int(0) << false;
-
- // using fromRawData
- QTest::newRow("raw1") << QByteArray::fromRawData("1", 1) << 10 << 1 << true;
- QTest::newRow("raw2") << QByteArray::fromRawData("1foo", 1) << 10 << 1 << true;
- QTest::newRow("raw3") << QByteArray::fromRawData("12", 1) << 10 << 1 << true;
- QTest::newRow("raw4") << QByteArray::fromRawData("123456789", 1) << 10 << 1 << true;
- QTest::newRow("raw5") << QByteArray::fromRawData("123456789", 2) << 10 << 12 << true;
-
- QTest::newRow("raw-static") << QByteArray::fromRawData(&globalChar, 1) << 10 << 1 << true;
-}
-
-void tst_QByteArray::toInt()
-{
- QFETCH( QByteArray, string );
- QFETCH( int, base );
- QFETCH( int, expectednumber );
- QFETCH( bool, expectedok );
-
- bool ok;
- int number = string.toInt(&ok, base);
-
- QCOMPARE( ok, expectedok );
- QCOMPARE( number, expectednumber );
-}
-
-void tst_QByteArray::toDouble_data()
-{
- QTest::addColumn<QByteArray>("string");
- QTest::addColumn<double>("expectedNumber");
- QTest::addColumn<bool>("expectedOk");
-
- QTest::newRow("decimal") << QByteArray("1.2345") << 1.2345 << true;
- QTest::newRow("exponent lowercase") << QByteArray("1.2345e+01") << 12.345 << true;
- QTest::newRow("exponent uppercase") << QByteArray("1.2345E+02") << 123.45 << true;
- QTest::newRow("leading spaces") << QByteArray(" \n\r\t1.2345") << 1.2345 << true;
- QTest::newRow("trailing spaces") << QByteArray("1.2345 \n\r\t") << 1.2345 << true;
- QTest::newRow("leading junk") << QByteArray("x1.2345") << 0.0 << false;
- QTest::newRow("trailing junk") << QByteArray("1.2345x") << 0.0 << false;
-}
-
-void tst_QByteArray::toDouble()
-{
- QFETCH(QByteArray, string);
- QFETCH(double, expectedNumber);
- QFETCH(bool, expectedOk);
-
- bool ok;
- const double number = string.toDouble(&ok);
-
- QCOMPARE(ok, expectedOk);
- QCOMPARE(number, expectedNumber);
-}
-
-void tst_QByteArray::toULong_data()
-{
- QTest::addColumn<QByteArray>("str");
- QTest::addColumn<int>("base");
- QTest::addColumn<ulong>("result");
- QTest::addColumn<bool>("ok");
-
- ulong LongMaxPlusOne = (ulong)LONG_MAX + 1;
- QTest::newRow("LONG_MAX+1") << QString::number(LongMaxPlusOne).toLatin1() << 10 << LongMaxPlusOne << true;
- QTest::newRow("default") << QByteArray() << 10 << 0UL << false;
- QTest::newRow("empty") << QByteArray("") << 10 << 0UL << false;
- QTest::newRow("ulong1") << QByteArray("3234567890") << 10 << 3234567890UL << true;
- QTest::newRow("ulong2") << QByteArray("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true;
-
- QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << 100UL << true;
- QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << 100UL << true;
- QTest::newRow("leading junk") << QByteArray("x100") << 10 << 0UL << false;
- QTest::newRow("trailing junk") << QByteArray("100x") << 10 << 0UL << false;
-}
-
-void tst_QByteArray::toULong()
-{
- QFETCH(QByteArray, str);
- QFETCH(int, base);
- QFETCH(ulong, result);
- QFETCH(bool, ok);
-
- bool b;
- QCOMPARE(str.toULong(0, base), result);
- QCOMPARE(str.toULong(&b, base), result);
- QCOMPARE(b, ok);
-}
-
-void tst_QByteArray::toULongLong_data()
-{
- QTest::addColumn<QByteArray>("str");
- QTest::addColumn<int>("base");
- QTest::addColumn<qulonglong>("result");
- QTest::addColumn<bool>("ok");
-
- QTest::newRow("default") << QByteArray() << 10 << (qulonglong)0 << false;
- QTest::newRow("out of base bound") << QByteArray("c") << 10 << (qulonglong)0 << false;
-
- QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << qulonglong(100) << true;
- QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << qulonglong(100) << true;
- QTest::newRow("leading junk") << QByteArray("x100") << 10 << qulonglong(0) << false;
- QTest::newRow("trailing junk") << QByteArray("100x") << 10 << qulonglong(0) << false;
-}
-
-void tst_QByteArray::toULongLong()
-{
- QFETCH(QByteArray, str);
- QFETCH(int, base);
- QFETCH(qulonglong, result);
- QFETCH(bool, ok);
-
- bool b;
- QCOMPARE(str.toULongLong(0, base), result);
- QCOMPARE(str.toULongLong(&b, base), result);
- QCOMPARE(b, ok);
-}
-
-static bool checkSize(size_t value, size_t min)
-{
- return value >= min && value <= INT_MAX;
-}
-
-// global functions defined in qbytearray.cpp
-void tst_QByteArray::blockSizeCalculations()
-{
- // Not very important, but please behave :-)
- QCOMPARE(qCalculateBlockSize(0, 1), size_t(0));
- QVERIFY(qCalculateGrowingBlockSize(0, 1).size <= MaxAllocSize);
- QVERIFY(qCalculateGrowingBlockSize(0, 1).elementCount <= MaxAllocSize);
-
- // boundary condition
- QCOMPARE(qCalculateBlockSize(MaxAllocSize, 1), size_t(MaxAllocSize));
- QCOMPARE(qCalculateBlockSize(MaxAllocSize/2, 2), size_t(MaxAllocSize) - 1);
- QCOMPARE(qCalculateBlockSize(MaxAllocSize/2, 2, 1), size_t(MaxAllocSize));
- QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize, 1).size, size_t(MaxAllocSize));
- QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize, 1).elementCount, size_t(MaxAllocSize));
- QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2, 2, 1).size, size_t(MaxAllocSize));
- QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2, 2, 1).elementCount, size_t(MaxAllocSize)/2);
-
- // error conditions
- QCOMPARE(qCalculateBlockSize(uint(MaxAllocSize) + 1, 1), size_t(~0));
- QCOMPARE(qCalculateBlockSize(size_t(-1), 1), size_t(~0));
- QCOMPARE(qCalculateBlockSize(MaxAllocSize, 1, 1), size_t(~0));
- QCOMPARE(qCalculateBlockSize(MaxAllocSize/2 + 1, 2), size_t(~0));
- QCOMPARE(qCalculateGrowingBlockSize(uint(MaxAllocSize) + 1, 1).size, size_t(~0));
- QCOMPARE(qCalculateGrowingBlockSize(MaxAllocSize/2 + 1, 2).size, size_t(~0));
-
- // overflow conditions
- // on 32-bit platforms, (1 << 16) * (1 << 16) = (1 << 32) which is zero
- QCOMPARE(qCalculateBlockSize(1 << 16, 1 << 16), size_t(~0));
- QCOMPARE(qCalculateBlockSize(MaxAllocSize/4, 16), size_t(~0));
- // on 32-bit platforms, (1 << 30) * 3 + (1 << 30) would overflow to zero
- QCOMPARE(qCalculateBlockSize(1U << 30, 3, 1U << 30), size_t(~0));
-
- // exact block sizes
- for (int i = 1; i < 1 << 31; i <<= 1) {
- QCOMPARE(qCalculateBlockSize(0, 1, i), size_t(i));
- QCOMPARE(qCalculateBlockSize(i, 1), size_t(i));
- QCOMPARE(qCalculateBlockSize(i + i/2, 1), size_t(i + i/2));
- }
- for (int i = 1; i < 1 << 30; i <<= 1) {
- QCOMPARE(qCalculateBlockSize(i, 2), 2 * size_t(i));
- QCOMPARE(qCalculateBlockSize(i, 2, 1), 2 * size_t(i) + 1);
- QCOMPARE(qCalculateBlockSize(i, 2, 16), 2 * size_t(i) + 16);
- }
-
- // growing sizes
- for (int i = 1; i < 1 << 31; i <<= 1) {
- QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1).size, i));
- QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1).elementCount, i));
- QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 16).size, i));
- QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 16).elementCount, i));
- QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 24).size, i));
- QVERIFY(checkSize(qCalculateGrowingBlockSize(i, 1, 16).elementCount, i));
- }
-
- // growth should be limited
- for (int elementSize = 1; elementSize < (1<<8); elementSize <<= 1) {
- size_t alloc = 1;
- forever {
- QVERIFY(checkSize(qCalculateGrowingBlockSize(alloc, elementSize).size, alloc * elementSize));
- size_t newAlloc = qCalculateGrowingBlockSize(alloc, elementSize).elementCount;
- QVERIFY(checkSize(newAlloc, alloc));
- if (newAlloc == alloc)
- break; // no growth, we're at limit
- alloc = newAlloc;
- }
- QVERIFY(checkSize(alloc, size_t(MaxAllocSize) / elementSize));
-
- // the next allocation should be invalid
- QCOMPARE(qCalculateGrowingBlockSize(alloc + 1, elementSize).size, size_t(~0));
- }
-}
-
-void tst_QByteArray::resizeAfterFromRawData()
-{
- QByteArray buffer("hello world");
-
- QByteArray array = QByteArray::fromRawData(buffer.constData(), buffer.size());
- QVERIFY(array.constData() == buffer.constData());
- array.resize(5);
- QVERIFY(array.constData() == buffer.constData());
-}
-
-void tst_QByteArray::appendAfterFromRawData()
-{
- QByteArray arr;
- {
- char data[] = "X";
- arr += QByteArray::fromRawData(data, sizeof(data));
- data[0] = 'Y';
- }
- QCOMPARE(arr.at(0), 'X');
-}
-
-void tst_QByteArray::toFromHex_data()
-{
- QTest::addColumn<QByteArray>("str");
- QTest::addColumn<char>("sep");
- QTest::addColumn<QByteArray>("hex");
- QTest::addColumn<QByteArray>("hex_alt1");
-
- QTest::newRow("Qt is great! (default)")
- << QByteArray("Qt is great!")
- << '\0'
- << QByteArray("517420697320677265617421")
- << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21");
-
- QTest::newRow("Qt is great! (with space)")
- << QByteArray("Qt is great!")
- << ' '
- << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21")
- << QByteArray("51 74 20 69 73 20 67 72 65 61 74 21");
-
- QTest::newRow("Qt is great! (with minus)")
- << QByteArray("Qt is great!")
- << '-'
- << QByteArray("51-74-20-69-73-20-67-72-65-61-74-21")
- << QByteArray("51-74-20-69-73-20-67-72-65-61-74-21");
-
- QTest::newRow("Qt is so great!")
- << QByteArray("Qt is so great!")
- << '\0'
- << QByteArray("517420697320736f20677265617421")
- << QByteArray("51 74 20 69 73 20 73 6f 20 67 72 65 61 74 21");
-
- QTest::newRow("default-constructed")
- << QByteArray()
- << '\0'
- << QByteArray()
- << QByteArray();
-
- QTest::newRow("default-constructed (with space)")
- << QByteArray()
- << ' '
- << QByteArray()
- << QByteArray();
-
- QTest::newRow("empty")
- << QByteArray("")
- << '\0'
- << QByteArray("")
- << QByteArray("");
-
- QTest::newRow("empty (with space)")
- << QByteArray("")
- << ' '
- << QByteArray("")
- << QByteArray("");
-
- QTest::newRow("array-of-null")
- << QByteArray("\0", 1)
- << '\0'
- << QByteArray("00")
- << QByteArray("0");
-
- QTest::newRow("no-leading-zero")
- << QByteArray("\xf")
- << '\0'
- << QByteArray("0f")
- << QByteArray("f");
-
- QTest::newRow("single-byte")
- << QByteArray("\xaf")
- << '\0'
- << QByteArray("af")
- << QByteArray("xaf");
-
- QTest::newRow("no-leading-zero")
- << QByteArray("\xd\xde\xad\xc0\xde")
- << '\0'
- << QByteArray("0ddeadc0de")
- << QByteArray("ddeadc0de");
-
- QTest::newRow("garbage")
- << QByteArray("\xC\xde\xeC\xea\xee\xDe\xee\xee")
- << '\0'
- << QByteArray("0cdeeceaeedeeeee")
- << QByteArray("Code less. Create more. Deploy everywhere.");
-
- QTest::newRow("under-defined-1")
- << QByteArray("\x1\x23")
- << '\0'
- << QByteArray("0123")
- << QByteArray("x123");
-
- QTest::newRow("under-defined-2")
- << QByteArray("\x12\x34")
- << '\0'
- << QByteArray("1234")
- << QByteArray("x1234");
-}
-
-void tst_QByteArray::toFromHex()
-{
- QFETCH(QByteArray, str);
- QFETCH(char, sep);
- QFETCH(QByteArray, hex);
- QFETCH(QByteArray, hex_alt1);
-
- if (sep == 0) {
- const QByteArray th = str.toHex();
- QCOMPARE(th.size(), hex.size());
- QCOMPARE(th, hex);
- }
-
- {
- const QByteArray th = str.toHex(sep);
- QCOMPARE(th.size(), hex.size());
- QCOMPARE(th, hex);
- }
-
- {
- const QByteArray fh = QByteArray::fromHex(hex);
- QCOMPARE(fh.size(), str.size());
- QCOMPARE(fh, str);
- }
-
- QCOMPARE(QByteArray::fromHex(hex_alt1), str);
-}
-
-void tst_QByteArray::toFromPercentEncoding()
-{
- QByteArray arr("Qt is great!");
-
- QByteArray data = arr.toPercentEncoding();
- QCOMPARE(QString(data), QString("Qt%20is%20great%21"));
- QCOMPARE(QByteArray::fromPercentEncoding(data), arr);
-
- data = arr.toPercentEncoding("! ", "Qt");
- QCOMPARE(QString(data), QString("%51%74 is grea%74!"));
- QCOMPARE(QByteArray::fromPercentEncoding(data), arr);
-
- data = arr.toPercentEncoding(QByteArray(), "abcdefghijklmnopqrstuvwxyz", 'Q');
- QCOMPARE(QString(data), QString("Q51Q74Q20Q69Q73Q20Q67Q72Q65Q61Q74Q21"));
- QCOMPARE(QByteArray::fromPercentEncoding(data, 'Q'), arr);
-
- // verify that to/from percent encoding preserves nullity
- arr = "";
- QVERIFY(arr.isEmpty());
- QVERIFY(!arr.isNull());
- QVERIFY(arr.toPercentEncoding().isEmpty());
- QVERIFY(!arr.toPercentEncoding().isNull());
- QVERIFY(QByteArray::fromPercentEncoding("").isEmpty());
- QVERIFY(!QByteArray::fromPercentEncoding("").isNull());
-
- arr = QByteArray();
- QVERIFY(arr.isEmpty());
- QVERIFY(arr.isNull());
- QVERIFY(arr.toPercentEncoding().isEmpty());
- QVERIFY(arr.toPercentEncoding().isNull());
- QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isEmpty());
- QVERIFY(QByteArray::fromPercentEncoding(QByteArray()).isNull());
-}
-
-void tst_QByteArray::fromPercentEncoding_data()
-{
- QTest::addColumn<QByteArray>("encodedString");
- QTest::addColumn<QByteArray>("decodedString");
-
- QTest::newRow("NormalString") << QByteArray("filename") << QByteArray("filename");
- QTest::newRow("NormalStringEncoded") << QByteArray("file%20name") << QByteArray("file name");
- QTest::newRow("JustEncoded") << QByteArray("%20") << QByteArray(" ");
- QTest::newRow("HTTPUrl") << QByteArray("http://qt-project.org") << QByteArray("http://qt-project.org");
- QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt-project%20org") << QByteArray("http://qt-project org");
- QTest::newRow("EmptyString") << QByteArray("") << QByteArray("");
- QTest::newRow("Task27166") << QByteArray("Fran%C3%A7aise") << QByteArray("Française");
-}
-
-void tst_QByteArray::fromPercentEncoding()
-{
- QFETCH(QByteArray, encodedString);
- QFETCH(QByteArray, decodedString);
-
- QCOMPARE(QByteArray::fromPercentEncoding(encodedString), decodedString);
-}
-
-void tst_QByteArray::toPercentEncoding_data()
-{
- QTest::addColumn<QByteArray>("decodedString");
- QTest::addColumn<QByteArray>("encodedString");
-
- QTest::newRow("NormalString") << QByteArray("filename") << QByteArray("filename");
- QTest::newRow("NormalStringEncoded") << QByteArray("file name") << QByteArray("file%20name");
- QTest::newRow("JustEncoded") << QByteArray(" ") << QByteArray("%20");
- QTest::newRow("HTTPUrl") << QByteArray("http://qt-project.org") << QByteArray("http%3A//qt-project.org");
- QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt-project org") << QByteArray("http%3A//qt-project%20org");
- QTest::newRow("EmptyString") << QByteArray("") << QByteArray("");
- QTest::newRow("Task27166") << QByteArray("Française") << QByteArray("Fran%C3%A7aise");
-}
-
-void tst_QByteArray::toPercentEncoding()
-{
- QFETCH(QByteArray, decodedString);
- QFETCH(QByteArray, encodedString);
-
- QCOMPARE(decodedString.toPercentEncoding("/.").constData(), encodedString.constData());
-}
-
-void tst_QByteArray::toPercentEncoding2_data()
-{
- QTest::addColumn<QByteArray>("original");
- QTest::addColumn<QByteArray>("encoded");
- QTest::addColumn<QByteArray>("excludeInEncoding");
- QTest::addColumn<QByteArray>("includeInEncoding");
-
- QTest::newRow("test_01") << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
- << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
- << QByteArray("")
- << QByteArray("");
- QTest::newRow("test_02") << QByteArray("{\t\n\r^\"abc}")
- << QByteArray("%7B%09%0A%0D%5E%22abc%7D")
- << QByteArray("")
- << QByteArray("");
- QTest::newRow("test_03") << QByteArray("://?#[]@!$&'()*+,;=")
- << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D")
- << QByteArray("")
- << QByteArray("");
- QTest::newRow("test_04") << QByteArray("://?#[]@!$&'()*+,;=")
- << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=")
- << QByteArray("!$&'()*+,;=")
- << QByteArray("");
- QTest::newRow("test_05") << QByteArray("abcd")
- << QByteArray("a%62%63d")
- << QByteArray("")
- << QByteArray("bc");
-}
-
-void tst_QByteArray::toPercentEncoding2()
-{
- QFETCH(QByteArray, original);
- QFETCH(QByteArray, encoded);
- QFETCH(QByteArray, excludeInEncoding);
- QFETCH(QByteArray, includeInEncoding);
-
- QByteArray encodedData = original.toPercentEncoding(excludeInEncoding, includeInEncoding);
- QCOMPARE(encodedData.constData(), encoded.constData());
- QCOMPARE(original, QByteArray::fromPercentEncoding(encodedData));
-}
-
-void tst_QByteArray::compare_data()
-{
- QTest::addColumn<QByteArray>("str1");
- QTest::addColumn<QByteArray>("str2");
- QTest::addColumn<int>("result");
-
- QTest::newRow("null") << QByteArray() << QByteArray() << 0;
- QTest::newRow("null-empty")<< QByteArray() << QByteArray("") << 0;
- QTest::newRow("empty-null")<< QByteArray("") << QByteArray() << 0;
- QTest::newRow("null-full") << QByteArray() << QByteArray("abc") << -1;
- QTest::newRow("full-null") << QByteArray("abc") << QByteArray() << +1;
- QTest::newRow("empty-full")<< QByteArray("") << QByteArray("abc") << -1;
- QTest::newRow("full-empty")<< QByteArray("abc") << QByteArray("") << +1;
- QTest::newRow("rawempty-full") << QByteArray::fromRawData("abc", 0) << QByteArray("abc") << -1;
- QTest::newRow("full-rawempty") << QByteArray("abc") << QByteArray::fromRawData("abc", 0) << +1;
-
- QTest::newRow("equal 1") << QByteArray("abc") << QByteArray("abc") << 0;
- QTest::newRow("equal 2") << QByteArray::fromRawData("abc", 3) << QByteArray("abc") << 0;
- QTest::newRow("equal 3") << QByteArray::fromRawData("abcdef", 3) << QByteArray("abc") << 0;
- QTest::newRow("equal 4") << QByteArray("abc") << QByteArray::fromRawData("abc", 3) << 0;
- QTest::newRow("equal 5") << QByteArray("abc") << QByteArray::fromRawData("abcdef", 3) << 0;
- QTest::newRow("equal 6") << QByteArray("a\0bc", 4) << QByteArray("a\0bc", 4) << 0;
- QTest::newRow("equal 7") << QByteArray::fromRawData("a\0bcdef", 4) << QByteArray("a\0bc", 4) << 0;
- QTest::newRow("equal 8") << QByteArray("a\0bc", 4) << QByteArray::fromRawData("a\0bcdef", 4) << 0;
-
- QTest::newRow("less 1") << QByteArray("000") << QByteArray("abc") << -1;
- QTest::newRow("less 2") << QByteArray::fromRawData("00", 3) << QByteArray("abc") << -1;
- QTest::newRow("less 3") << QByteArray("000") << QByteArray::fromRawData("abc", 3) << -1;
- QTest::newRow("less 4") << QByteArray("abc", 3) << QByteArray("abc", 4) << -1;
- QTest::newRow("less 5") << QByteArray::fromRawData("abc\0", 3) << QByteArray("abc\0", 4) << -1;
- QTest::newRow("less 6") << QByteArray("a\0bc", 4) << QByteArray("a\0bd", 4) << -1;
-
- QTest::newRow("greater 1") << QByteArray("abc") << QByteArray("000") << +1;
- QTest::newRow("greater 2") << QByteArray("abc") << QByteArray::fromRawData("00", 3) << +1;
- QTest::newRow("greater 3") << QByteArray("abcd") << QByteArray::fromRawData("abcd", 3) << +1;
- QTest::newRow("greater 4") << QByteArray("a\0bc", 4) << QByteArray("a\0bb", 4) << +1;
-}
-
-void tst_QByteArray::compare()
-{
- QFETCH(QByteArray, str1);
- QFETCH(QByteArray, str2);
- QFETCH(int, result);
-
- const bool isEqual = result == 0;
- const bool isLess = result < 0;
- const bool isGreater = result > 0;
-
- int cmp = str1.compare(str2);
- if (cmp)
- cmp = (cmp < 0 ? -1 : 1);
-
- QCOMPARE(cmp, result);
-
- // basic tests:
- QCOMPARE(str1 == str2, isEqual);
- QCOMPARE(str1 < str2, isLess);
- QCOMPARE(str1 > str2, isGreater);
-
- // composed tests:
- QCOMPARE(str1 <= str2, isLess || isEqual);
- QCOMPARE(str1 >= str2, isGreater || isEqual);
- QCOMPARE(str1 != str2, !isEqual);
-
- // inverted tests:
- QCOMPARE(str2 == str1, isEqual);
- QCOMPARE(str2 < str1, isGreater);
- QCOMPARE(str2 > str1, isLess);
-
- // composed, inverted tests:
- QCOMPARE(str2 <= str1, isGreater || isEqual);
- QCOMPARE(str2 >= str1, isLess || isEqual);
- QCOMPARE(str2 != str1, !isEqual);
-
- if (isEqual)
- QVERIFY(qHash(str1) == qHash(str2));
-}
-
-void tst_QByteArray::compareCharStar_data()
-{
- QTest::addColumn<QByteArray>("str1");
- QTest::addColumn<QString>("string2");
- QTest::addColumn<int>("result");
-
- QTest::newRow("null-null") << QByteArray() << QString() << 0;
- QTest::newRow("null-empty") << QByteArray() << "" << 0;
- QTest::newRow("null-full") << QByteArray() << "abc" << -1;
- QTest::newRow("empty-null") << QByteArray("") << QString() << 0;
- QTest::newRow("empty-empty") << QByteArray("") << "" << 0;
- QTest::newRow("empty-full") << QByteArray("") << "abc" << -1;
- QTest::newRow("raw-null") << QByteArray::fromRawData("abc", 0) << QString() << 0;
- QTest::newRow("raw-empty") << QByteArray::fromRawData("abc", 0) << QString("") << 0;
- QTest::newRow("raw-full") << QByteArray::fromRawData("abc", 0) << "abc" << -1;
-
- QTest::newRow("full-null") << QByteArray("abc") << QString() << +1;
- QTest::newRow("full-empty") << QByteArray("abc") << "" << +1;
-
- QTest::newRow("equal1") << QByteArray("abc") << "abc" << 0;
- QTest::newRow("equal2") << QByteArray("abcd", 3) << "abc" << 0;
- QTest::newRow("equal3") << QByteArray::fromRawData("abcd", 3) << "abc" << 0;
-
- QTest::newRow("less1") << QByteArray("ab") << "abc" << -1;
- QTest::newRow("less2") << QByteArray("abb") << "abc" << -1;
- QTest::newRow("less3") << QByteArray::fromRawData("abc", 2) << "abc" << -1;
- QTest::newRow("less4") << QByteArray("", 1) << "abc" << -1;
- QTest::newRow("less5") << QByteArray::fromRawData("", 1) << "abc" << -1;
- QTest::newRow("less6") << QByteArray("a\0bc", 4) << "a.bc" << -1;
-
- QTest::newRow("greater1") << QByteArray("ac") << "abc" << +1;
- QTest::newRow("greater2") << QByteArray("abd") << "abc" << +1;
- QTest::newRow("greater3") << QByteArray("abcd") << "abc" << +1;
- QTest::newRow("greater4") << QByteArray::fromRawData("abcd", 4) << "abc" << +1;
-}
-
-void tst_QByteArray::compareCharStar()
-{
- QFETCH(QByteArray, str1);
- QFETCH(QString, string2);
- QFETCH(int, result);
-
- const bool isEqual = result == 0;
- const bool isLess = result < 0;
- const bool isGreater = result > 0;
- QByteArray qba = string2.toLatin1();
- const char *str2 = qba.constData();
- if (string2.isNull())
- str2 = 0;
-
- // basic tests:
- QCOMPARE(str1 == str2, isEqual);
- QCOMPARE(str1 < str2, isLess);
- QCOMPARE(str1 > str2, isGreater);
-
- // composed tests:
- QCOMPARE(str1 <= str2, isLess || isEqual);
- QCOMPARE(str1 >= str2, isGreater || isEqual);
- QCOMPARE(str1 != str2, !isEqual);
-
- // inverted tests:
- QCOMPARE(str2 == str1, isEqual);
- QCOMPARE(str2 < str1, isGreater);
- QCOMPARE(str2 > str1, isLess);
-
- // composed, inverted tests:
- QCOMPARE(str2 <= str1, isGreater || isEqual);
- QCOMPARE(str2 >= str1, isLess || isEqual);
- QCOMPARE(str2 != str1, !isEqual);
-}
-
-void tst_QByteArray::repeatedSignature() const
-{
- /* repated() should be a const member. */
- const QByteArray string;
- string.repeated(3);
-}
-
-void tst_QByteArray::repeated() const
-{
- QFETCH(QByteArray, string);
- QFETCH(QByteArray, expected);
- QFETCH(int, count);
-
- QCOMPARE(string.repeated(count), expected);
-}
-
-void tst_QByteArray::repeated_data() const
-{
- QTest::addColumn<QByteArray>("string" );
- QTest::addColumn<QByteArray>("expected" );
- QTest::addColumn<int>("count" );
-
- /* Empty strings. */
- QTest::newRow("data1")
- << QByteArray()
- << QByteArray()
- << 0;
-
- QTest::newRow("data2")
- << QByteArray()
- << QByteArray()
- << -1004;
-
- QTest::newRow("data3")
- << QByteArray()
- << QByteArray()
- << 1;
-
- QTest::newRow("data4")
- << QByteArray()
- << QByteArray()
- << 5;
-
- /* On simple string. */
- QTest::newRow("data5")
- << QByteArray("abc")
- << QByteArray()
- << -1004;
-
- QTest::newRow("data6")
- << QByteArray("abc")
- << QByteArray()
- << -1;
-
- QTest::newRow("data7")
- << QByteArray("abc")
- << QByteArray()
- << 0;
-
- QTest::newRow("data8")
- << QByteArray("abc")
- << QByteArray("abc")
- << 1;
-
- QTest::newRow("data9")
- << QByteArray(("abc"))
- << QByteArray(("abcabc"))
- << 2;
-
- QTest::newRow("data10")
- << QByteArray(("abc"))
- << QByteArray(("abcabcabc"))
- << 3;
-
- QTest::newRow("data11")
- << QByteArray(("abc"))
- << QByteArray(("abcabcabcabc"))
- << 4;
-
- QTest::newRow("static not null terminated")
- << QByteArray(staticNotNullTerminated)
- << QByteArray("datadatadatadata")
- << 4;
- QTest::newRow("static standard")
- << QByteArray(staticStandard)
- << QByteArray("datadatadatadata")
- << 4;
- QTest::newRow("static shifted not null terminated")
- << QByteArray(staticShiftedNotNullTerminated)
- << QByteArray("datadatadatadata")
- << 4;
- QTest::newRow("static shifted")
- << QByteArray(staticShifted)
- << QByteArray("datadatadatadata")
- << 4;
-}
-
-void tst_QByteArray::byteRefDetaching() const
-{
- {
- QByteArray str = "str";
- QByteArray copy;
- copy[0] = 'S';
-
- QCOMPARE(str, QByteArray("str"));
- }
-
- {
- char buf[] = { 's', 't', 'r' };
- QByteArray str = QByteArray::fromRawData(buf, 3);
- str[0] = 'S';
-
- QCOMPARE(buf[0], char('s'));
- }
-
- {
- static const char buf[] = { 's', 't', 'r' };
- QByteArray str = QByteArray::fromRawData(buf, 3);
-
- // this causes a crash in most systems if the detaching doesn't work
- str[0] = 'S';
-
- QCOMPARE(buf[0], char('s'));
- }
-}
-
-void tst_QByteArray::reserve()
-{
- int capacity = 100;
- QByteArray qba;
- qba.reserve(capacity);
- QVERIFY(qba.capacity() == capacity);
- char *data = qba.data();
-
- for (int i = 0; i < capacity; i++) {
- qba.resize(i);
- QVERIFY(capacity == qba.capacity());
- QVERIFY(data == qba.data());
- }
-
- qba.resize(capacity);
-
- QByteArray copy = qba;
- qba.reserve(capacity / 2);
- QCOMPARE(qba.size(), capacity); // we didn't shrink the size!
- QCOMPARE(qba.capacity(), capacity);
- QCOMPARE(copy.capacity(), capacity);
-
- qba = copy;
- qba.reserve(capacity * 2);
- QCOMPARE(qba.size(), capacity);
- QCOMPARE(qba.capacity(), capacity * 2);
- QCOMPARE(copy.capacity(), capacity);
- QVERIFY(qba.constData() != data);
-
- QByteArray nil1, nil2;
- nil1.reserve(0);
- nil2.squeeze();
- nil1.squeeze();
- nil2.reserve(0);
-}
-
-void tst_QByteArray::reserveExtended_data()
-{
- prependExtended_data();
-}
-
-void tst_QByteArray::reserveExtended()
-{
- QFETCH(QByteArray, array);
- array.reserve(1024);
- QVERIFY(array.capacity() == 1024);
- QCOMPARE(array, QByteArray("data"));
- array.squeeze();
- QCOMPARE(array, QByteArray("data"));
- QCOMPARE(array.capacity(), array.size());
-}
-
-void tst_QByteArray::movablity_data()
-{
- QTest::addColumn<QByteArray>("array");
-
- QTest::newRow("0x00000000") << QByteArray("\x00\x00\x00\x00", 4);
- QTest::newRow("0x000000ff") << QByteArray("\x00\x00\x00\xff", 4);
- QTest::newRow("0xffffffff") << QByteArray("\xff\xff\xff\xff", 4);
- QTest::newRow("empty") << QByteArray("");
- QTest::newRow("null") << QByteArray();
- QTest::newRow("sss") << QByteArray(3, 's');
-
- prependExtended_data();
-}
-
-void tst_QByteArray::movablity()
-{
- QFETCH(QByteArray, array);
-
- QVERIFY(!QTypeInfo<QByteArray>::isStatic);
-
- const int size = array.size();
- const bool isEmpty = array.isEmpty();
- const bool isNull = array.isNull();
- const int capacity = array.capacity();
-
- QByteArray memSpace;
-
- // we need only memory space not the instance
- memSpace.~QByteArray();
- // move array -> memSpace
- memcpy(&memSpace, &array, sizeof(QByteArray));
- // reconstruct empty QByteArray
- new (&array) QByteArray;
-
- QCOMPARE(memSpace.size(), size);
- QCOMPARE(memSpace.isEmpty(), isEmpty);
- QCOMPARE(memSpace.isNull(), isNull);
- QCOMPARE(memSpace.capacity(), capacity);
-
- // try to not crash
- memSpace.toLower();
- memSpace.toUpper();
- memSpace.prepend('a');
- memSpace.append("b", 1);
- memSpace.squeeze();
- memSpace.reserve(array.size() + 16);
-
- QByteArray copy(memSpace);
-
- // reinitialize base values
- const int newSize = size + 2;
- const bool newIsEmpty = false;
- const bool newIsNull = false;
- const int newCapacity = 16;
-
- // move back memSpace -> array
- array.~QByteArray();
- memcpy(&array, &memSpace, sizeof(QByteArray));
- // reconstruct empty QByteArray
- new (&memSpace) QByteArray;
-
- QCOMPARE(array.size(), newSize);
- QCOMPARE(array.isEmpty(), newIsEmpty);
- QCOMPARE(array.isNull(), newIsNull);
- QCOMPARE(array.capacity(), newCapacity);
- QVERIFY(array.startsWith('a'));
- QVERIFY(array.endsWith('b'));
-
- QCOMPARE(copy.size(), newSize);
- QCOMPARE(copy.isEmpty(), newIsEmpty);
- QCOMPARE(copy.isNull(), newIsNull);
- QCOMPARE(copy.capacity(), newCapacity);
- QVERIFY(copy.startsWith('a'));
- QVERIFY(copy.endsWith('b'));
-
- // try to not crash
- array.squeeze();
- array.reserve(array.size() + 3);
- QVERIFY(true);
-}
-
-#if defined(Q_COMPILER_LAMBDA)
-// Only tested on c++0x compliant compiler or gcc
-void tst_QByteArray::literals()
-{
- QByteArray str(QByteArrayLiteral("abcd"));
-
- QVERIFY(str.length() == 4);
- QVERIFY(str == "abcd");
- QVERIFY(str.data_ptr()->ref.isStatic());
- QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData));
-
- const char *s = str.constData();
- QByteArray str2 = str;
- QVERIFY(str2.constData() == s);
-
- // detach on non const access
- QVERIFY(str.data() != s);
-
- QVERIFY(str2.constData() == s);
- QVERIFY(str2.data() != s);
-}
-#endif
-
-void tst_QByteArray::toUpperLower_data()
-{
- QTest::addColumn<QByteArray>("input");
- QTest::addColumn<QByteArray>("upper");
- QTest::addColumn<QByteArray>("lower");
-
- QTest::newRow("empty") << QByteArray() << QByteArray() << QByteArray();
- QTest::newRow("literal") << QByteArrayLiteral("Hello World")
- << QByteArrayLiteral("HELLO WORLD")
- << QByteArrayLiteral("hello world");
- QTest::newRow("ascii") << QByteArray("Hello World, this is a STRING")
- << QByteArray("HELLO WORLD, THIS IS A STRING")
- << QByteArray("hello world, this is a string");
- QTest::newRow("latin1") << QByteArray("R\311sum\351")
- << QByteArray("R\311SUM\311")
- << QByteArray("r\351sum\351");
- QTest::newRow("nul") << QByteArray("a\0B", 3) << QByteArray("A\0B", 3) << QByteArray("a\0b", 3);
-}
-
-void tst_QByteArray::toUpperLower()
-{
- QFETCH(QByteArray, input);
- QFETCH(QByteArray, upper);
- QFETCH(QByteArray, lower);
- QCOMPARE(lower.toLower(), lower);
- QCOMPARE(upper.toUpper(), upper);
- QCOMPARE(input.toUpper(), upper);
- QCOMPARE(input.toLower(), lower);
-
- QByteArray copy = input;
- QCOMPARE(qMove(copy).toUpper(), upper);
- copy = input;
- copy.detach();
- QCOMPARE(qMove(copy).toUpper(), upper);
-
- copy = input;
- QCOMPARE(qMove(copy).toLower(), lower);
- copy = input;
- copy.detach();
- QCOMPARE(qMove(copy).toLower(), lower);
-
- copy = lower;
- QCOMPARE(qMove(copy).toLower(), lower);
- copy = lower;
- copy.detach();
- QCOMPARE(qMove(copy).toLower(), lower);
-
- copy = upper;
- QCOMPARE(qMove(copy).toUpper(), upper);
- copy = upper;
- copy.detach();
- QCOMPARE(qMove(copy).toUpper(), upper);
-}
-
-void tst_QByteArray::isUpper()
-{
- QVERIFY(!QByteArray().isUpper());
- QVERIFY(!QByteArray("").isUpper());
- QVERIFY(QByteArray("TEXT").isUpper());
- QVERIFY(QByteArray("\xD0\xDE").isUpper());
- QVERIFY(!QByteArray("\xD7").isUpper()); // multiplication sign is not upper
- QVERIFY(!QByteArray("\xDF").isUpper()); // sz ligature is not upper
- QVERIFY(!QByteArray("text").isUpper());
- QVERIFY(!QByteArray("Text").isUpper());
- QVERIFY(!QByteArray("tExt").isUpper());
- QVERIFY(!QByteArray("teXt").isUpper());
- QVERIFY(!QByteArray("texT").isUpper());
- QVERIFY(!QByteArray("TExt").isUpper());
- QVERIFY(!QByteArray("teXT").isUpper());
- QVERIFY(!QByteArray("tEXt").isUpper());
- QVERIFY(!QByteArray("tExT").isUpper());
- QVERIFY(!QByteArray("@ABYZ[").isUpper());
- QVERIFY(!QByteArray("@abyz[").isUpper());
- QVERIFY(!QByteArray("`ABYZ{").isUpper());
- QVERIFY(!QByteArray("`abyz{").isUpper());
-}
-
-void tst_QByteArray::isLower()
-{
- QVERIFY(!QByteArray().isLower());
- QVERIFY(!QByteArray("").isLower());
- QVERIFY(QByteArray("text").isLower());
- QVERIFY(QByteArray("\xE0\xFF").isLower());
- QVERIFY(!QByteArray("\xF7").isLower()); // division sign is not lower
- QVERIFY(!QByteArray("Text").isLower());
- QVERIFY(!QByteArray("tExt").isLower());
- QVERIFY(!QByteArray("teXt").isLower());
- QVERIFY(!QByteArray("texT").isLower());
- QVERIFY(!QByteArray("TExt").isLower());
- QVERIFY(!QByteArray("teXT").isLower());
- QVERIFY(!QByteArray("tEXt").isLower());
- QVERIFY(!QByteArray("tExT").isLower());
- QVERIFY(!QByteArray("TEXT").isLower());
- QVERIFY(!QByteArray("@ABYZ[").isLower());
- QVERIFY(!QByteArray("@abyz[").isLower());
- QVERIFY(!QByteArray("`ABYZ{").isLower());
- QVERIFY(!QByteArray("`abyz{").isLower());
-}
-
-void tst_QByteArray::macTypes()
-{
-#ifndef Q_OS_MAC
- QSKIP("This is a Apple-only test");
-#else
- extern void tst_QByteArray_macTypes(); // in qbytearray_mac.mm
- tst_QByteArray_macTypes();
-#endif
-}
-
-void tst_QByteArray::stdString()
-{
- std::string stdstr( "QByteArray" );
-
- const QByteArray stlqt = QByteArray::fromStdString(stdstr);
- QCOMPARE(stlqt.length(), int(stdstr.length()));
- QCOMPARE(stlqt.data(), stdstr.c_str());
- QCOMPARE(stlqt.toStdString(), stdstr);
-
- std::string utf8str( "Nøt æscii" );
- const QByteArray u8 = QByteArray::fromStdString(utf8str);
- const QByteArray l1 = QString::fromUtf8(u8).toLatin1();
- std::string l1str = l1.toStdString();
- QVERIFY(l1str.length() < utf8str.length());
-}
-
-
-const char globalChar = '1';
-
-QTEST_MAIN(tst_QByteArray)
-#include "tst_qbytearray.moc"
diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm b/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm
deleted file mode 100644
index 98146e3525..0000000000
--- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch>
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QByteArray>
-#include <QtTest/QtTest>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-void tst_QByteArray_macTypes()
-{
- // QByteArray <-> CFData
- {
- QByteArray qtByteArray("test bytearray");
- const CFDataRef cfData = qtByteArray.toCFData();
- QCOMPARE(QByteArray::fromCFData(cfData), qtByteArray);
- CFRelease(cfData);
- }
- {
- QByteArray qtByteArray("test bytearray");
- const CFDataRef cfData = qtByteArray.toCFData();
- QByteArray qtByteArrayCopy(qtByteArray);
- qtByteArray = qtByteArray.toUpper(); // modify
- QCOMPARE(QByteArray::fromCFData(cfData), qtByteArrayCopy);
- }
- // QByteArray <-> CFData Raw
- {
- QByteArray qtByteArray("test bytearray");
- const CFDataRef cfData = qtByteArray.toRawCFData();
- const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
- QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
- CFRelease(cfData);
- }
- {
- const UInt8 data[] = "cfdata test";
- const CFDataRef cfData = CFDataCreate(kCFAllocatorDefault, data, sizeof(data));
- const UInt8 * cfDataPtr = CFDataGetBytePtr(cfData);
- QByteArray qtByteArray = QByteArray::fromRawCFData(cfData);
- QCOMPARE(reinterpret_cast<const UInt8*>(qtByteArray.constData()), cfDataPtr);
- CFRelease(cfData);
- }
- // QByteArray <-> NSData
- {
- QMacAutoReleasePool pool;
- QByteArray qtByteArray("test bytearray");
- const NSData *nsData = qtByteArray.toNSData();
- QCOMPARE(QByteArray::fromNSData(nsData), qtByteArray);
- }
- {
- QMacAutoReleasePool pool;
- QByteArray qtByteArray("test bytearray");
- const NSData *nsData = qtByteArray.toNSData();
- QByteArray qtByteArrayCopy(qtByteArray);
- qtByteArray = qtByteArray.toUpper(); // modify
- QCOMPARE(QByteArray::fromNSData(nsData), qtByteArrayCopy);
- }
- // QByteArray <-> NSData Raw
- {
- QMacAutoReleasePool pool;
- QByteArray qtByteArray("test bytearray");
- const NSData *nsData = qtByteArray.toRawNSData();
- QCOMPARE([nsData bytes], qtByteArray.constData());
- }
- {
- QMacAutoReleasePool pool;
- const char data[] = "nsdata test";
- const NSData *nsData = [NSData dataWithBytes:data length:sizeof(data)];
- QByteArray qtByteArray = QByteArray::fromRawNSData(nsData);
- QCOMPARE(qtByteArray.constData(), [nsData bytes]);
- }
-}
diff --git a/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro b/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro
deleted file mode 100644
index 6c05c288cf..0000000000
--- a/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qbytearraylist
-QT = core testlib
-SOURCES = tst_qbytearraylist.cpp
diff --git a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
deleted file mode 100644
index 85b4c4bfb7..0000000000
--- a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 by Southwest Research Institute (R)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qbytearraylist.h>
-
-#include <qmetatype.h>
-
-Q_DECLARE_METATYPE(QByteArrayList)
-
-class tst_QByteArrayList : public QObject
-{
- Q_OBJECT
-private slots:
- void join() const;
- void join_data() const;
- void joinByteArray() const;
- void joinByteArray_data() const;
- void joinChar() const;
- void joinChar_data() const;
- void joinEmptiness() const;
-
- void operator_plus() const;
- void operator_plus_data() const;
-
- void initializerList() const;
-};
-
-void tst_QByteArrayList::join() const
-{
- QFETCH(QByteArrayList, input);
- QFETCH(QByteArray, expectedResult);
-
- QCOMPARE(input.join(), expectedResult);
-}
-
-void tst_QByteArrayList::join_data() const
-{
- QTest::addColumn<QByteArrayList>("input");
- QTest::addColumn<QByteArray>("expectedResult");
-
- QTest::newRow("data1") << QByteArrayList()
- << QByteArray();
-
- QTest::newRow("data2") << (QByteArrayList() << "one")
- << QByteArray("one");
-
- QTest::newRow("data3") << (QByteArrayList() << "a" << "b")
- << QByteArray("ab");
-
- QTest::newRow("data4") << (QByteArrayList() << "a" << "b" << "c")
- << QByteArray("abc");
-}
-
-void tst_QByteArrayList::joinByteArray() const
-{
- QFETCH(QByteArrayList, input);
- QFETCH(QByteArray, separator);
- QFETCH(QByteArray, expectedResult);
-
- QCOMPARE(input.join(separator), expectedResult);
-}
-
-void tst_QByteArrayList::joinByteArray_data() const
-{
- QTest::addColumn<QByteArrayList>("input");
- QTest::addColumn<QByteArray>("separator");
- QTest::addColumn<QByteArray>("expectedResult");
-
- QTest::newRow("data1") << QByteArrayList()
- << QByteArray()
- << QByteArray();
-
- QTest::newRow("data2") << QByteArrayList()
- << QByteArray("separator")
- << QByteArray();
-
- QTest::newRow("data3") << (QByteArrayList() << "one")
- << QByteArray("separator")
- << QByteArray("one");
-
- QTest::newRow("data4") << (QByteArrayList() << "a" << "b")
- << QByteArray(" ")
- << QByteArray("a b");
-
- QTest::newRow("data5") << (QByteArrayList() << "a" << "b" << "c")
- << QByteArray(" ")
- << QByteArray("a b c");
-
- QTest::newRow("data6") << (QByteArrayList() << "a" << "b" << "c")
- << QByteArray()
- << QByteArray("abc");
-
- QTest::newRow("data7") << (QByteArrayList() << "a" << "b" << "c")
- << QByteArray("") //empty
- << QByteArray("abc");
-}
-
-void tst_QByteArrayList::joinChar() const
-{
- QFETCH(QByteArrayList, input);
- QFETCH(char, separator);
- QFETCH(QByteArray, expectedResult);
-
- QCOMPARE(input.join(separator), expectedResult);
-}
-
-void tst_QByteArrayList::joinChar_data() const
-{
- QTest::addColumn<QByteArrayList>("input");
- QTest::addColumn<char>("separator");
- QTest::addColumn<QByteArray>("expectedResult");
-
- QTest::newRow("data1") << QByteArrayList()
- << ' '
- << QByteArray();
-
- QTest::newRow("data2") << (QByteArrayList() << "a a" << "b")
- << ' '
- << QByteArray("a a b");
-
- QTest::newRow("data3") << (QByteArrayList() << "a" << "b" << "c c")
- << ' '
- << QByteArray("a b c c");
-}
-
-void tst_QByteArrayList::joinEmptiness() const
-{
- QByteArrayList list;
- QByteArray string = list.join(QByteArray());
-
- QVERIFY(string.isEmpty());
- QVERIFY(string.isNull());
-}
-
-void tst_QByteArrayList::operator_plus() const
-{
- QFETCH(QByteArrayList, lhs);
- QFETCH(QByteArrayList, rhs);
- QFETCH(QByteArrayList, expectedResult);
-
- // operator+ for const lvalues
- {
- const QByteArrayList bal1 = lhs;
- const QByteArrayList bal2 = rhs;
- QCOMPARE(bal1 + bal2, expectedResult);
- }
- {
- const QList<QByteArray> lba1 = lhs;
- const QByteArrayList bal2 = rhs;
- QCOMPARE(lba1 + bal2, expectedResult);
- }
- {
- const QByteArrayList bal1 = lhs;
- const QList<QByteArray> lba2 = rhs;
- QCOMPARE(bal1 + lba2, expectedResult);
- }
- {
- const QList<QByteArray> lba1 = lhs;
- const QList<QByteArray> lba2 = rhs;
- QCOMPARE(lba1 + lba2, QList<QByteArray>(expectedResult)); // check we don't mess with old code
- }
-
- // operator+ for rvalues (only lhs)
- {
- QByteArrayList bal1 = lhs;
- const QByteArrayList bal2 = rhs;
- QCOMPARE(qMove(bal1) + bal2, expectedResult);
- }
- {
- QList<QByteArray> lba1 = lhs;
- const QByteArrayList bal2 = rhs;
- QCOMPARE(qMove(lba1) + bal2, expectedResult);
- }
- {
- QByteArrayList bal1 = lhs;
- const QList<QByteArray> lba2 = rhs;
- QCOMPARE(qMove(bal1) + lba2, expectedResult);
- }
- {
- QList<QByteArray> lba1 = lhs;
- const QList<QByteArray> lba2 = rhs;
- QCOMPARE(qMove(lba1) + lba2, QList<QByteArray>(expectedResult)); // check we don't mess with old code
- }
-
- // operator += for const lvalues
- {
- QByteArrayList bal1 = lhs;
- const QByteArrayList bal2 = rhs;
- QCOMPARE(bal1 += bal2, expectedResult);
- }
- {
- QByteArrayList bal1 = lhs;
- const QList<QByteArray> lba2 = rhs;
- QCOMPARE(bal1 += lba2, expectedResult);
- }
- {
- QList<QByteArray> lba1 = lhs;
- const QByteArrayList bal2 = rhs;
- QCOMPARE(lba1 += bal2, QList<QByteArray>(expectedResult));
- }
-
- QByteArrayList t1 = lhs;
- QByteArrayList t2 = rhs;
-
- QCOMPARE(qMove(t1) + t2, expectedResult);
-}
-
-void tst_QByteArrayList::operator_plus_data() const
-{
- QTest::addColumn<QByteArrayList>("lhs");
- QTest::addColumn<QByteArrayList>("rhs");
- QTest::addColumn<QByteArrayList>("expectedResult");
-
- QTest::newRow("simpl") << ( QByteArrayList() << "a" )
- << ( QByteArrayList() << "b" << "c" )
- << ( QByteArrayList() << "a" << "b" << "c" );
-
- QTest::newRow("blank1") << QByteArrayList()
- << QByteArrayList()
- << QByteArrayList();
-
- QTest::newRow("blank2") << ( QByteArrayList() )
- << ( QByteArrayList() << "b" << "c" )
- << ( QByteArrayList() << "b" << "c" );
-
- QTest::newRow("empty1") << ( QByteArrayList() << "" )
- << ( QByteArrayList() << "b" << "c" )
- << ( QByteArrayList() << "" << "b" << "c" );
-
- QTest::newRow("empty2") << ( QByteArrayList() << "a" )
- << ( QByteArrayList() << "" << "c" )
- << ( QByteArrayList() << "a" << "" << "c" );
-}
-
-void tst_QByteArrayList::initializerList() const
-{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
- // constructor
- QByteArrayList v1 = {QByteArray("hello"),"world",QByteArray("plop")};
- QCOMPARE(v1, (QByteArrayList() << "hello" << "world" << "plop"));
- QCOMPARE(v1, (QByteArrayList{"hello","world","plop"}));
- // assignment operator (through implicit temporary)
- QByteArrayList v2;
- v2 = {QByteArray("hello"),"world",QByteArray("plop")};
- QCOMPARE(v2, v1);
-#else
- QSKIP("This test requires C++11 initializer_list support in the compiler.");
-#endif
-}
-
-QTEST_APPLESS_MAIN(tst_QByteArrayList)
-#include "tst_qbytearraylist.moc"
diff --git a/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro b/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro
deleted file mode 100644
index 9d4d5964c9..0000000000
--- a/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qbytearraymatcher
-QT = core testlib
-SOURCES = tst_qbytearraymatcher.cpp
-contains(QT_CONFIG, c++14):CONFIG += c++14
diff --git a/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp b/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp
deleted file mode 100644
index 647a3ae379..0000000000
--- a/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-
-#include <qbytearraymatcher.h>
-
-// COM interface
-#if defined(Q_OS_WIN) && defined(interface)
-# undef interface
-#endif
-
-class tst_QByteArrayMatcher : public QObject
-{
- Q_OBJECT
-
-private slots:
- void interface();
- void indexIn();
- void staticByteArrayMatcher();
-};
-
-void tst_QByteArrayMatcher::interface()
-{
- const char needle[] = "abc123";
- QByteArray haystack(500, 'a');
- haystack.insert(6, "123");
- haystack.insert(31, "abc");
- haystack.insert(42, "abc123");
- haystack.insert(84, "abc123");
-
- QByteArrayMatcher matcher1;
-
- matcher1 = QByteArrayMatcher(QByteArray(needle));
- QByteArrayMatcher matcher2;
- matcher2.setPattern(QByteArray(needle));
-
- QByteArrayMatcher matcher3 = QByteArrayMatcher(QByteArray(needle));
- QByteArrayMatcher matcher4(needle, sizeof(needle) - 1);
- QByteArrayMatcher matcher5(matcher2);
- QByteArrayMatcher matcher6;
- matcher6 = matcher3;
-
- QCOMPARE(matcher1.indexIn(haystack), 42);
- QCOMPARE(matcher2.indexIn(haystack), 42);
- QCOMPARE(matcher3.indexIn(haystack), 42);
- QCOMPARE(matcher4.indexIn(haystack), 42);
- QCOMPARE(matcher5.indexIn(haystack), 42);
- QCOMPARE(matcher6.indexIn(haystack), 42);
-
- QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.length()), 42);
-
- QCOMPARE(matcher1.indexIn(haystack, 43), 84);
- QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.length(), 43), 84);
- QCOMPARE(matcher1.indexIn(haystack, 85), -1);
- QCOMPARE(matcher1.indexIn(haystack.constData(), haystack.length(), 85), -1);
-
- QByteArrayMatcher matcher7(QByteArray("123"));
- QCOMPARE(matcher7.indexIn(haystack), 6);
-
- matcher7 = QByteArrayMatcher(QByteArray("abc"));
- QCOMPARE(matcher7.indexIn(haystack), 31);
-
- matcher7.setPattern(matcher4.pattern());
- QCOMPARE(matcher7.indexIn(haystack), 42);
-}
-
-#define LONG_STRING__32 "abcdefghijklmnopqrstuvwxyz012345"
-#define LONG_STRING__64 LONG_STRING__32 LONG_STRING__32
-#define LONG_STRING_128 LONG_STRING__64 LONG_STRING__64
-#define LONG_STRING_256 LONG_STRING_128 LONG_STRING_128
-
-void tst_QByteArrayMatcher::indexIn()
-{
- const char p_data[] = { 0x0, 0x0, 0x1 };
- QByteArray pattern(p_data, sizeof(p_data));
-
- QByteArray haystack(8, '\0');
- haystack[7] = 0x1;
-
- QByteArrayMatcher matcher;
-
- matcher = QByteArrayMatcher(pattern);
- QCOMPARE(matcher.indexIn(haystack, 0), 5);
- QCOMPARE(matcher.indexIn(haystack, 1), 5);
- QCOMPARE(matcher.indexIn(haystack, 2), 5);
-
- matcher.setPattern(pattern);
- QCOMPARE(matcher.indexIn(haystack, 0), 5);
- QCOMPARE(matcher.indexIn(haystack, 1), 5);
- QCOMPARE(matcher.indexIn(haystack, 2), 5);
-
- QByteArray allChars(256, Qt::Uninitialized);
- for (int i = 0; i < 256; ++i)
- allChars[i] = char(i);
-
- matcher = QByteArrayMatcher(allChars);
- haystack = LONG_STRING__32 "x" + matcher.pattern();
- QCOMPARE(matcher.indexIn(haystack, 0), 33);
- QCOMPARE(matcher.indexIn(haystack, 1), 33);
- QCOMPARE(matcher.indexIn(haystack, 2), 33);
- QCOMPARE(matcher.indexIn(haystack, 33), 33);
- QCOMPARE(matcher.indexIn(haystack, 34), -1);
-
- matcher = QByteArrayMatcher(LONG_STRING_256);
- haystack = LONG_STRING__32 "x" + matcher.pattern();
- QCOMPARE(matcher.indexIn(haystack, 0), 33);
- QCOMPARE(matcher.indexIn(haystack, 1), 33);
- QCOMPARE(matcher.indexIn(haystack, 2), 33);
- QCOMPARE(matcher.indexIn(haystack, 33), 33);
- QCOMPARE(matcher.indexIn(haystack, 34), -1);
-}
-
-void tst_QByteArrayMatcher::staticByteArrayMatcher()
-{
- {
- static Q_RELAXED_CONSTEXPR auto smatcher = qMakeStaticByteArrayMatcher("Hello");
- QCOMPARE(smatcher.pattern(), QByteArrayLiteral("Hello"));
-
- QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!")), 0);
- QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 0), 0);
- QCOMPARE(smatcher.indexIn(QByteArray("Hello, World!"), 1), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aHello, World!")), 1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaHello, World!")), 2);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaHello, World!")), 3);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello, World!")), 4);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello, World!")), 5);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello, World!")), 6);
- QCOMPARE(smatcher.indexIn(QByteArray("HHello, World!")), 1);
- QCOMPARE(smatcher.indexIn(QByteArray("HeHello, World!")), 2);
- QCOMPARE(smatcher.indexIn(QByteArray("HelHello, World!")), 3);
- QCOMPARE(smatcher.indexIn(QByteArray("HellHello, World!")), 4);
- QCOMPARE(smatcher.indexIn(QByteArray("HellaHello, World!")), 5);
- QCOMPARE(smatcher.indexIn(QByteArray("HellauHello, World!")), 6);
- QCOMPARE(smatcher.indexIn(QByteArray("aHella, World!")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaHella, World!")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaHella, World!")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella, World!")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella, World!")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella, World!")), -1);
-
- QCOMPARE(smatcher.indexIn(QByteArray("aHello")), 1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaHello")), 2);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaHello")), 3);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaHello")), 4);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHello")), 5);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHello")), 6);
- QCOMPARE(smatcher.indexIn(QByteArray("HHello")), 1);
- QCOMPARE(smatcher.indexIn(QByteArray("HeHello")), 2);
- QCOMPARE(smatcher.indexIn(QByteArray("HelHello")), 3);
- QCOMPARE(smatcher.indexIn(QByteArray("HellHello")), 4);
- QCOMPARE(smatcher.indexIn(QByteArray("HellaHello")), 5);
- QCOMPARE(smatcher.indexIn(QByteArray("HellauHello")), 6);
- QCOMPARE(smatcher.indexIn(QByteArray("aHella")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaHella")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaHella")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaHella")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaHella")), -1);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaaHella")), -1);
- }
-
- {
- static Q_RELAXED_CONSTEXPR auto smatcher = qMakeStaticByteArrayMatcher(LONG_STRING_256);
- QCOMPARE(smatcher.pattern(), QByteArrayLiteral(LONG_STRING_256));
-
- QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256)), 1);
- QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256)), 2);
- QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256)), 3);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256)), 4);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256)), 5);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256)), 6);
- QCOMPARE(smatcher.indexIn(QByteArray("a" LONG_STRING_256 "a")), 1);
- QCOMPARE(smatcher.indexIn(QByteArray("aa" LONG_STRING_256 "a")), 2);
- QCOMPARE(smatcher.indexIn(QByteArray("aaa" LONG_STRING_256 "a")), 3);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaa" LONG_STRING_256 "a")), 4);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaa" LONG_STRING_256 "a")), 5);
- QCOMPARE(smatcher.indexIn(QByteArray("aaaaaa" LONG_STRING_256 "a")), 6);
- QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__32 "x" LONG_STRING_256)), 33);
- QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING__64 "x" LONG_STRING_256)), 65);
- QCOMPARE(smatcher.indexIn(QByteArray(LONG_STRING_128 "x" LONG_STRING_256)), 129);
- }
-
-}
-
-#undef LONG_STRING_256
-#undef LONG_STRING_128
-#undef LONG_STRING__64
-#undef LONG_STRING__32
-
-QTEST_APPLESS_MAIN(tst_QByteArrayMatcher)
-#include "tst_qbytearraymatcher.moc"
diff --git a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro b/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro
deleted file mode 100644
index e23018f96a..0000000000
--- a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TARGET = tst_qbytedatabuffer
-CONFIG += testcase
-QT = core-private testlib
-SOURCES += tst_qbytedatabuffer.cpp
diff --git a/tests/auto/corelib/tools/qbytedatabuffer/tst_qbytedatabuffer.cpp b/tests/auto/corelib/tools/qbytedatabuffer/tst_qbytedatabuffer.cpp
deleted file mode 100644
index 59f4d153e6..0000000000
--- a/tests/auto/corelib/tools/qbytedatabuffer/tst_qbytedatabuffer.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QTest>
-#include <private/qbytedata_p.h>
-// for QIODEVICE_BUFFERSIZE macro (== 16384):
-#include <private/qiodevice_p.h>
-
-class tst_QByteDataBuffer : public QObject
-{
- Q_OBJECT
-private Q_SLOTS:
- void canReadLine();
- void positionHandling();
- void appendBuffer();
- void readCompleteBuffer_data();
- void readCompleteBuffer();
- void readPartialBuffer_data();
- void readPartialBuffer();
-private:
- void readBuffer(int size, int readSize);
-};
-
-void tst_QByteDataBuffer::canReadLine()
-{
- QByteDataBuffer buf;
- buf.append(QByteArray("a"));
- buf.append(QByteArray("\nb"));
- QVERIFY(buf.canReadLine());
- QVERIFY(buf.getChar() == 'a');
- QVERIFY(buf.canReadLine());
- QVERIFY(buf.getChar() == '\n');
- QVERIFY(!buf.canReadLine());
-}
-
-void tst_QByteDataBuffer::positionHandling()
-{
- QByteDataBuffer buf;
- buf.append(QByteArray("abc"));
- buf.append(QByteArray("def"));
-
- QCOMPARE(buf.byteAmount(), (qlonglong)6);
- QCOMPARE(buf.sizeNextBlock(), (qlonglong)3);
-
- QCOMPARE(buf.getChar(), 'a');
- QCOMPARE(buf.byteAmount(), (qlonglong)5);
- QCOMPARE(buf.sizeNextBlock(), (qlonglong)2);
-
- QVERIFY(!strcmp(buf[0].constData(), "bc"));
- QCOMPARE(buf.getChar(), 'b');
- QCOMPARE(buf.byteAmount(), (qlonglong)4);
- QCOMPARE(buf.sizeNextBlock(), (qlonglong)1);
-
- QByteArray tmp("ab");
- buf.prepend(tmp);
- QCOMPARE(buf.byteAmount(), (qlonglong)6);
- QVERIFY(!strcmp(buf.readAll().constData(), "abcdef"));
- QCOMPARE(buf.byteAmount(), (qlonglong)0);
-
- QByteDataBuffer buf2;
- buf2.append(QByteArray("abc"));
- buf2.getChar();
- QCOMPARE(buf2.read(), QByteArray("bc"));
-}
-
-void tst_QByteDataBuffer::appendBuffer()
-{
- QByteDataBuffer buf;
- buf.append(QByteArray("\1\2\3"));
- buf.getChar();
-
- QByteDataBuffer tmp;
- tmp.append(buf);
- QCOMPARE(tmp.readAll(), buf.readAll());
-}
-
-static QByteArray makeByteArray(int size)
-{
- QByteArray array;
- array.resize(size);
- char *data = array.data();
- for (int i = 0; i < size; ++i)
- data[i] = i % 256;
- return array;
-}
-
-
-void tst_QByteDataBuffer::readBuffer(int size, int readSize)
-{
- QByteArray data = makeByteArray(size);
-
- QByteDataBuffer buf;
- buf.append(data);
-
- QByteArray tmp;
- tmp.resize(size);
-
- QBENCHMARK_ONCE {
- for (int i = 0; i < (size - 1) / readSize + 1; ++i)
- buf.read(tmp.data() + i * readSize, readSize);
- }
-
- QCOMPARE(data.size(), tmp.size());
- QCOMPARE(data, tmp);
-}
-
-void tst_QByteDataBuffer::readCompleteBuffer_data()
-{
- QTest::addColumn<int>("size");
- QTest::newRow("10B") << (int)10;
- QTest::newRow("1MB") << (int)1e6;
- QTest::newRow("5MB") << (int)5e6;
- QTest::newRow("10MB") << (int)10e6;
-}
-
-void tst_QByteDataBuffer::readCompleteBuffer()
-{
- QFETCH(int, size);
- readBuffer(size, size);
-}
-
-void tst_QByteDataBuffer::readPartialBuffer_data()
-{
- readCompleteBuffer_data();
-}
-
-void tst_QByteDataBuffer::readPartialBuffer()
-{
- QFETCH(int, size);
- // QIODevice::readAll() reads in QIODEVICE_BUFFERSIZE size
- // increments.
- readBuffer(size, QIODEVICE_BUFFERSIZE);
-}
-
-QTEST_MAIN(tst_QByteDataBuffer)
-#include "tst_qbytedatabuffer.moc"
diff --git a/tests/auto/corelib/tools/qcache/CMakeLists.txt b/tests/auto/corelib/tools/qcache/CMakeLists.txt
new file mode 100644
index 0000000000..8ffe942d70
--- /dev/null
+++ b/tests/auto/corelib/tools/qcache/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcache Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcache LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcache
+ SOURCES
+ tst_qcache.cpp
+)
diff --git a/tests/auto/corelib/tools/qcache/qcache.pro b/tests/auto/corelib/tools/qcache/qcache.pro
deleted file mode 100644
index 07488ef40f..0000000000
--- a/tests/auto/corelib/tools/qcache/qcache.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qcache
-QT = core testlib
-SOURCES = tst_qcache.cpp
diff --git a/tests/auto/corelib/tools/qcache/tst_qcache.cpp b/tests/auto/corelib/tools/qcache/tst_qcache.cpp
index d880953c1c..5fccb8f1d0 100644
--- a/tests/auto/corelib/tools/qcache/tst_qcache.cpp
+++ b/tests/auto/corelib/tools/qcache/tst_qcache.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qcache.h>
@@ -37,6 +12,7 @@ public slots:
void initTestCase();
void cleanupTestCase();
private slots:
+ void empty();
void maxCost();
void setMaxCost();
void totalCost();
@@ -47,6 +23,10 @@ private slots:
void remove();
void take();
void axioms_on_key_type();
+ void largeCache();
+ void internalChainOrderAfterEntryUpdate();
+ void emplaceLowerCost();
+ void trimWithMovingAcrossSpans();
};
@@ -72,6 +52,21 @@ void tst_QCache::cleanupTestCase()
QCOMPARE(Foo::count, 0);
}
+void tst_QCache::empty()
+{
+ QCache<int, int> cache;
+ QCOMPARE(cache.size(), 0);
+ QCOMPARE(cache.count(), 0);
+ QVERIFY(cache.isEmpty());
+ QVERIFY(!cache.contains(1));
+ QCOMPARE(cache.keys().size(), 0);
+ QCOMPARE(cache.take(1), nullptr);
+ QVERIFY(!cache.remove(1));
+ QCOMPARE(cache.object(1), nullptr);
+ QCOMPARE(cache[1], nullptr);
+ QCOMPARE(cache.totalCost(), 0);
+}
+
void tst_QCache::maxCost()
{
QCache<QString, int> cache1, cache2(100), cache3(200), cache4(-50);
@@ -356,6 +351,7 @@ struct KeyType
int foo;
KeyType(int x) : foo(x) {}
+ constexpr KeyType(const KeyType &o) noexcept : foo(o.foo) {}
private:
KeyType &operator=(const KeyType &);
@@ -377,7 +373,7 @@ bool operator==(const KeyType &key1, const KeyType &key2)
return key1.foo == key2.foo;
}
-uint qHash(const KeyType &key)
+size_t qHash(const KeyType &key)
{
return qHash(key.foo);
}
@@ -398,5 +394,115 @@ void tst_QCache::axioms_on_key_type()
QVERIFY(sizeof(QHash<int, int>) == sizeof(void *));
}
+void tst_QCache::largeCache()
+{
+ QCache<int, int> cache;
+ cache.setMaxCost(500);
+ for (int i = 0; i < 1000; ++i) {
+ for (int j = 0; j < qMax(0, i - 500); ++j)
+ QVERIFY(!cache.contains(j));
+ for (int j = qMax(0, i - 500); j < i; ++j)
+ QVERIFY(cache.contains(j));
+ cache.insert(i, new int);
+ }
+ cache.clear();
+ QVERIFY(cache.size() == 0);
+}
+
+// The internal chain could lose track of some objects.
+// Make sure it doesn't happen again.
+void tst_QCache::internalChainOrderAfterEntryUpdate()
+{
+ QCache<QString, int> cache;
+ cache.setMaxCost(20);
+ cache.insert(QString::number(1), new int, 1);
+ cache.insert(QString::number(2), new int, 1);
+ cache.insert(QString::number(1), new int, 1);
+ // If the chain is still 'in order' then setting maxCost == 0 should
+ // a. not crash, and
+ // b. remove all the elements in the QHash
+ cache.setMaxCost(0);
+ QCOMPARE(cache.size(), 0);
+}
+
+void tst_QCache::emplaceLowerCost()
+{
+ QCache<QString, int> cache;
+ cache.setMaxCost(5);
+ cache.insert("a", new int, 3); // insert high cost
+ cache.insert("a", new int, 1); // and then exchange it with a lower-cost object
+ QCOMPARE(cache.totalCost(), 1);
+ cache.remove("a"); // then remove the object
+ // The cache should now have a cost == 0 and be empty.
+ QCOMPARE(cache.totalCost(), 0);
+ QVERIFY(cache.isEmpty());
+}
+
+struct TrivialHashType {
+ int i = -1;
+ size_t hash = 0;
+
+ TrivialHashType(int i, size_t hash) : i(i), hash(hash) {}
+ TrivialHashType(const TrivialHashType &o) noexcept = default;
+ TrivialHashType &operator=(const TrivialHashType &o) noexcept = default;
+ TrivialHashType(TrivialHashType &&o) noexcept : i(o.i), hash(o.hash) {
+ o.i = -1;
+ o.hash = 0;
+ }
+ TrivialHashType &operator=(TrivialHashType &&o) noexcept {
+ i = o.i;
+ hash = o.hash;
+ o.i = -1;
+ o.hash = 0;
+ return *this;
+ }
+
+
+ friend bool operator==(const TrivialHashType &lhs, const TrivialHashType &rhs)
+ {
+ return lhs.i == rhs.i;
+ }
+};
+quint64 qHash(TrivialHashType t, size_t seed = 0)
+{
+ Q_UNUSED(seed);
+ return t.hash;
+}
+
+// During trim(), if the Node we have a pointer to in the function is moved
+// to another span in the hash table, our pointer would end up pointing to
+// garbage memory. Test that this no longer happens
+void tst_QCache::trimWithMovingAcrossSpans()
+{
+ qsizetype numBuckets = [](){
+ QHash<int, int> h;
+ h.reserve(1);
+ // Beholden to QHash internals:
+ return h.capacity() << 1;
+ }();
+
+ QCache<TrivialHashType, int> cache;
+ cache.setMaxCost(1000);
+
+ auto lastBucketInSpan = size_t(numBuckets - 1);
+ // If this fails then the test is no longer valid
+ QCOMPARE(QHashPrivate::GrowthPolicy::bucketForHash(numBuckets, lastBucketInSpan),
+ lastBucketInSpan);
+
+ // Pad some space so we have two spans:
+ for (int i = 2; i < numBuckets; ++i)
+ cache.insert({i, 0}, nullptr);
+
+ // These two are vying for the last bucket in the first span,
+ // when '0' is deleted, '1' is moved across the span boundary,
+ // invalidating any pointer to its Node.
+ cache.insert({0, lastBucketInSpan}, nullptr);
+ cache.insert({1, lastBucketInSpan}, nullptr);
+
+ QCOMPARE(cache.size(), numBuckets);
+ cache.setMaxCost(0);
+ QCOMPARE(cache.size(), 0);
+}
+
QTEST_APPLESS_MAIN(tst_QCache)
#include "tst_qcache.moc"
diff --git a/tests/auto/corelib/tools/qchar/qchar.pro b/tests/auto/corelib/tools/qchar/qchar.pro
deleted file mode 100644
index 70c1222988..0000000000
--- a/tests/auto/corelib/tools/qchar/qchar.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qchar
-QT = core-private testlib
-SOURCES = tst_qchar.cpp
-
-TESTDATA += data/NormalizationTest.txt
-
-android:!android-embedded {
- RESOURCES += \
- testdata.qrc
-}
diff --git a/tests/auto/corelib/tools/qchar/testdata.qrc b/tests/auto/corelib/tools/qchar/testdata.qrc
deleted file mode 100644
index 7b3fb2461c..0000000000
--- a/tests/auto/corelib/tools/qchar/testdata.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>data/NormalizationTest.txt</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
deleted file mode 100644
index cf4f6d21e2..0000000000
--- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp
+++ /dev/null
@@ -1,1021 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qchar.h>
-#include <qfile.h>
-#include <qstringlist.h>
-#include <private/qunicodetables_p.h>
-
-class tst_QChar : public QObject
-{
- Q_OBJECT
-private slots:
- void fromChar16_t();
- void fromWchar_t();
- void operator_eqeq_null();
- void operators_data();
- void operators();
- void toUpper();
- void toLower();
- void toTitle();
- void toCaseFolded();
- void isDigit_data();
- void isDigit();
- void isLetter_data();
- void isLetter();
- void isLetterOrNumber_data();
- void isLetterOrNumber();
- void isPrint();
- void isUpper();
- void isLower();
- void isTitleCase();
- void isSpace_data();
- void isSpace();
- void isSpaceSpecial();
- void category();
- void direction();
- void joiningType();
- void combiningClass();
- void digitValue();
- void mirroredChar();
- void decomposition();
- void lineBreakClass();
- void script();
- void normalization_data();
- void normalization();
- void normalization_manual();
- void normalizationCorrections();
- void unicodeVersion();
-};
-
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
-
-void tst_QChar::fromChar16_t()
-{
-#if defined(Q_COMPILER_UNICODE_STRINGS)
- QChar aUmlaut = u'\u00E4'; // German small letter a-umlaut
- QCOMPARE(aUmlaut, QChar(0xE4));
- QChar replacementCharacter = u'\uFFFD';
- QCOMPARE(replacementCharacter, QChar(QChar::ReplacementCharacter));
-#else
- QSKIP("This test requires C++11 char16_t support enabled in the compiler.");
-#endif
-}
-
-void tst_QChar::fromWchar_t()
-{
-#if defined(Q_OS_WIN)
- QChar aUmlaut = L'\u00E4'; // German small letter a-umlaut
- QCOMPARE(aUmlaut, QChar(0xE4));
- QChar replacementCharacter = L'\uFFFD';
- QCOMPARE(replacementCharacter, QChar(QChar::ReplacementCharacter));
-#else
- QSKIP("This is a Windows-only test.");
-#endif
-}
-
-void tst_QChar::operator_eqeq_null()
-{
- {
- const QChar ch = QLatin1Char(' ');
-#define CHECK(NUL) \
- do { \
- QVERIFY(!(ch == NUL)); \
- QVERIFY( ch != NUL ); \
- QVERIFY(!(ch < NUL)); \
- QVERIFY( ch > NUL ); \
- QVERIFY(!(ch <= NUL)); \
- QVERIFY( ch >= NUL ); \
- QVERIFY(!(NUL == ch )); \
- QVERIFY( NUL != ch ); \
- QVERIFY( NUL < ch ); \
- QVERIFY(!(NUL > ch )); \
- QVERIFY( NUL <= ch ); \
- QVERIFY(!(NUL >= ch )); \
- } while (0)
-
- CHECK(0);
- CHECK('\0');
-#undef CHECK
- }
- {
- const QChar ch = QLatin1Char('\0');
-#define CHECK(NUL) \
- do { \
- QVERIFY( ch == NUL ); \
- QVERIFY(!(ch != NUL)); \
- QVERIFY(!(ch < NUL)); \
- QVERIFY(!(ch > NUL)); \
- QVERIFY( ch <= NUL ); \
- QVERIFY( ch >= NUL ); \
- QVERIFY( NUL == ch ); \
- QVERIFY(!(NUL != ch )); \
- QVERIFY(!(NUL < ch )); \
- QVERIFY(!(NUL > ch )); \
- QVERIFY( NUL <= ch ); \
- QVERIFY( NUL >= ch ); \
- } while (0)
-
- CHECK(0);
- CHECK('\0');
-#undef CHECK
- }
-}
-
-void tst_QChar::operators_data()
-{
- QTest::addColumn<QChar>("lhs");
- QTest::addColumn<QChar>("rhs");
-
- for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < 3; ++j)
- QTest::addRow("'\\%d' (op) '\\%d'", i, j)
- << QChar(ushort(i)) << QChar(ushort(j));
- }
-}
-
-void tst_QChar::operators()
-{
- QFETCH(QChar, lhs);
- QFETCH(QChar, rhs);
-
-#define CHECK(op) QCOMPARE((lhs op rhs), (lhs.unicode() op rhs.unicode()))
- CHECK(==);
- CHECK(!=);
- CHECK(< );
- CHECK(> );
- CHECK(<=);
- CHECK(>=);
-#undef CHECK
-}
-
-void tst_QChar::toUpper()
-{
- QVERIFY(QChar('a').toUpper() == 'A');
- QVERIFY(QChar('A').toUpper() == 'A');
- QVERIFY(QChar(0x1c7).toUpper().unicode() == 0x1c7);
- QVERIFY(QChar(0x1c8).toUpper().unicode() == 0x1c7);
- QVERIFY(QChar(0x1c9).toUpper().unicode() == 0x1c7);
- QVERIFY(QChar(0x25c).toUpper().unicode() == 0xa7ab);
- QVERIFY(QChar(0x29e).toUpper().unicode() == 0xa7b0);
- QVERIFY(QChar(0x1d79).toUpper().unicode() == 0xa77d);
- QVERIFY(QChar(0x0265).toUpper().unicode() == 0xa78d);
-
- QVERIFY(QChar::toUpper('a') == 'A');
- QVERIFY(QChar::toUpper('A') == 'A');
- QVERIFY(QChar::toUpper(0xdf) == 0xdf); // german sharp s
- QVERIFY(QChar::toUpper(0x1c7) == 0x1c7);
- QVERIFY(QChar::toUpper(0x1c8) == 0x1c7);
- QVERIFY(QChar::toUpper(0x1c9) == 0x1c7);
- QVERIFY(QChar::toUpper(0x25c) == 0xa7ab);
- QVERIFY(QChar::toUpper(0x29e) == 0xa7b0);
- QVERIFY(QChar::toUpper(0x1d79) == 0xa77d);
- QVERIFY(QChar::toUpper(0x0265) == 0xa78d);
-
- QVERIFY(QChar::toUpper(0x10400) == 0x10400);
- QVERIFY(QChar::toUpper(0x10428) == 0x10400);
-}
-
-void tst_QChar::toLower()
-{
- QVERIFY(QChar('A').toLower() == 'a');
- QVERIFY(QChar('a').toLower() == 'a');
- QVERIFY(QChar(0x1c7).toLower().unicode() == 0x1c9);
- QVERIFY(QChar(0x1c8).toLower().unicode() == 0x1c9);
- QVERIFY(QChar(0x1c9).toLower().unicode() == 0x1c9);
- QVERIFY(QChar(0xa77d).toLower().unicode() == 0x1d79);
- QVERIFY(QChar(0xa78d).toLower().unicode() == 0x0265);
- QVERIFY(QChar(0xa7ab).toLower().unicode() == 0x25c);
- QVERIFY(QChar(0xa7b1).toLower().unicode() == 0x287);
-
- QVERIFY(QChar::toLower('a') == 'a');
- QVERIFY(QChar::toLower('A') == 'a');
- QVERIFY(QChar::toLower(0x1c7) == 0x1c9);
- QVERIFY(QChar::toLower(0x1c8) == 0x1c9);
- QVERIFY(QChar::toLower(0x1c9) == 0x1c9);
- QVERIFY(QChar::toLower(0xa77d) == 0x1d79);
- QVERIFY(QChar::toLower(0xa78d) == 0x0265);
- QVERIFY(QChar::toLower(0xa7ab) == 0x25c);
- QVERIFY(QChar::toLower(0xa7b1) == 0x287);
-
- QVERIFY(QChar::toLower(0x10400) == 0x10428);
- QVERIFY(QChar::toLower(0x10428) == 0x10428);
-}
-
-void tst_QChar::toTitle()
-{
- QVERIFY(QChar('a').toTitleCase() == 'A');
- QVERIFY(QChar('A').toTitleCase() == 'A');
- QVERIFY(QChar(0x1c7).toTitleCase().unicode() == 0x1c8);
- QVERIFY(QChar(0x1c8).toTitleCase().unicode() == 0x1c8);
- QVERIFY(QChar(0x1c9).toTitleCase().unicode() == 0x1c8);
- QVERIFY(QChar(0x1d79).toTitleCase().unicode() == 0xa77d);
- QVERIFY(QChar(0x0265).toTitleCase().unicode() == 0xa78d);
-
- QVERIFY(QChar::toTitleCase('a') == 'A');
- QVERIFY(QChar::toTitleCase('A') == 'A');
- QVERIFY(QChar::toTitleCase(0xdf) == 0xdf); // german sharp s
- QVERIFY(QChar::toTitleCase(0x1c7) == 0x1c8);
- QVERIFY(QChar::toTitleCase(0x1c8) == 0x1c8);
- QVERIFY(QChar::toTitleCase(0x1c9) == 0x1c8);
- QVERIFY(QChar::toTitleCase(0x1d79) == 0xa77d);
- QVERIFY(QChar::toTitleCase(0x0265) == 0xa78d);
-
- QVERIFY(QChar::toTitleCase(0x10400) == 0x10400);
- QVERIFY(QChar::toTitleCase(0x10428) == 0x10400);
-}
-
-void tst_QChar::toCaseFolded()
-{
- QVERIFY(QChar('a').toCaseFolded() == 'a');
- QVERIFY(QChar('A').toCaseFolded() == 'a');
- QVERIFY(QChar(0x1c7).toCaseFolded().unicode() == 0x1c9);
- QVERIFY(QChar(0x1c8).toCaseFolded().unicode() == 0x1c9);
- QVERIFY(QChar(0x1c9).toCaseFolded().unicode() == 0x1c9);
- QVERIFY(QChar(0xa77d).toCaseFolded().unicode() == 0x1d79);
- QVERIFY(QChar(0xa78d).toCaseFolded().unicode() == 0x0265);
- QVERIFY(QChar(0xa7ab).toCaseFolded().unicode() == 0x25c);
- QVERIFY(QChar(0xa7b1).toCaseFolded().unicode() == 0x287);
-
- QVERIFY(QChar::toCaseFolded('a') == 'a');
- QVERIFY(QChar::toCaseFolded('A') == 'a');
- QVERIFY(QChar::toCaseFolded(0x1c7) == 0x1c9);
- QVERIFY(QChar::toCaseFolded(0x1c8) == 0x1c9);
- QVERIFY(QChar::toCaseFolded(0x1c9) == 0x1c9);
- QVERIFY(QChar::toCaseFolded(0xa77d) == 0x1d79);
- QVERIFY(QChar::toCaseFolded(0xa78d) == 0x0265);
- QVERIFY(QChar::toCaseFolded(0xa7ab) == 0x25c);
- QVERIFY(QChar::toCaseFolded(0xa7b1) == 0x287);
-
- QVERIFY(QChar::toCaseFolded(0x10400) == 0x10428);
- QVERIFY(QChar::toCaseFolded(0x10428) == 0x10428);
-
- QVERIFY(QChar::toCaseFolded(0xb5) == 0x3bc);
-}
-
-void tst_QChar::isDigit_data()
-{
- QTest::addColumn<ushort>("ucs");
- QTest::addColumn<bool>("expected");
-
- for (ushort ucs = 0; ucs < 256; ++ucs) {
- bool isDigit = (ucs <= '9' && ucs >= '0');
- const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
- QTest::newRow(tag.constData()) << ucs << isDigit;
- }
-}
-
-void tst_QChar::isDigit()
-{
- QFETCH(ushort, ucs);
- QFETCH(bool, expected);
- QCOMPARE(QChar(ucs).isDigit(), expected);
-}
-
-static bool isExpectedLetter(ushort ucs)
-{
- return (ucs >= 'a' && ucs <= 'z') || (ucs >= 'A' && ucs <= 'Z')
- || ucs == 0xAA || ucs == 0xB5 || ucs == 0xBA
- || (ucs >= 0xC0 && ucs <= 0xD6)
- || (ucs >= 0xD8 && ucs <= 0xF6)
- || (ucs >= 0xF8 && ucs <= 0xFF);
-}
-
-void tst_QChar::isLetter_data()
-{
- QTest::addColumn<ushort>("ucs");
- QTest::addColumn<bool>("expected");
-
- for (ushort ucs = 0; ucs < 256; ++ucs) {
- const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
- QTest::newRow(tag.constData()) << ucs << isExpectedLetter(ucs);
- }
-}
-
-void tst_QChar::isLetter()
-{
- QFETCH(ushort, ucs);
- QFETCH(bool, expected);
- QCOMPARE(QChar(ucs).isLetter(), expected);
-}
-
-void tst_QChar::isLetterOrNumber_data()
-{
- QTest::addColumn<ushort>("ucs");
- QTest::addColumn<bool>("expected");
-
- for (ushort ucs = 0; ucs < 256; ++ucs) {
- bool isLetterOrNumber = isExpectedLetter(ucs)
- || (ucs >= '0' && ucs <= '9')
- || ucs == 0xB2 || ucs == 0xB3 || ucs == 0xB9
- || (ucs >= 0xBC && ucs <= 0xBE);
- const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
- QTest::newRow(tag.constData()) << ucs << isLetterOrNumber;
- }
-}
-
-void tst_QChar::isLetterOrNumber()
-{
- QFETCH(ushort, ucs);
- QFETCH(bool, expected);
- QCOMPARE(QChar(ucs).isLetterOrNumber(), expected);
-}
-
-void tst_QChar::isPrint()
-{
- // noncharacters, reserved (General_Gategory =Cn)
- QVERIFY(!QChar(0x2064).isPrint());
- QVERIFY(!QChar(0x2069).isPrint());
- QVERIFY(!QChar(0xfdd0).isPrint());
- QVERIFY(!QChar(0xfdef).isPrint());
- QVERIFY(!QChar(0xfff0).isPrint());
- QVERIFY(!QChar(0xfff8).isPrint());
- QVERIFY(!QChar(0xfffe).isPrint());
- QVERIFY(!QChar(0xffff).isPrint());
- QVERIFY(!QChar::isPrint(0xe0000));
- QVERIFY(!QChar::isPrint(0xe0002));
- QVERIFY(!QChar::isPrint(0xe001f));
- QVERIFY(!QChar::isPrint(0xe0080));
- QVERIFY(!QChar::isPrint(0xe00ff));
-
- // Other_Default_Ignorable_Code_Point, Variation_Selector
- QVERIFY(QChar(0x034f).isPrint());
- QVERIFY(QChar(0x115f).isPrint());
- QVERIFY(QChar(0x180b).isPrint());
- QVERIFY(QChar(0x180d).isPrint());
- QVERIFY(QChar(0x3164).isPrint());
- QVERIFY(QChar(0xfe00).isPrint());
- QVERIFY(QChar(0xfe0f).isPrint());
- QVERIFY(QChar(0xffa0).isPrint());
- QVERIFY(QChar::isPrint(0xe0100));
- QVERIFY(QChar::isPrint(0xe01ef));
-
- // Cf, Cs, Cc, White_Space, Annotation Characters
- QVERIFY(!QChar(0x0008).isPrint());
- QVERIFY(!QChar(0x000a).isPrint());
- QVERIFY(QChar(0x0020).isPrint());
- QVERIFY(QChar(0x00a0).isPrint());
- QVERIFY(!QChar(0x00ad).isPrint());
- QVERIFY(!QChar(0x0085).isPrint());
- QVERIFY(!QChar(0xd800).isPrint());
- QVERIFY(!QChar(0xdc00).isPrint());
- QVERIFY(!QChar(0xfeff).isPrint());
- QVERIFY(!QChar::isPrint(0x1d173));
-
- QVERIFY(QChar('0').isPrint());
- QVERIFY(QChar('A').isPrint());
- QVERIFY(QChar('a').isPrint());
-
- QVERIFY(QChar(0x0370).isPrint()); // assigned in 5.1
- QVERIFY(QChar(0x0524).isPrint()); // assigned in 5.2
- QVERIFY(QChar(0x0526).isPrint()); // assigned in 6.0
- QVERIFY(QChar(0x08a0).isPrint()); // assigned in 6.1
- QVERIFY(!QChar(0x1aff).isPrint()); // not assigned
- QVERIFY(QChar(0x1e9e).isPrint()); // assigned in 5.1
- QVERIFY(QChar::isPrint(0x1b000)); // assigned in 6.0
- QVERIFY(QChar::isPrint(0x110d0)); // assigned in 5.1
- QVERIFY(!QChar::isPrint(0x1bca0)); // assigned in 7.0
-}
-
-void tst_QChar::isUpper()
-{
- QVERIFY(QChar('A').isUpper());
- QVERIFY(QChar('Z').isUpper());
- QVERIFY(!QChar('a').isUpper());
- QVERIFY(!QChar('z').isUpper());
- QVERIFY(!QChar('?').isUpper());
- QVERIFY(QChar(0xC2).isUpper()); // A with ^
- QVERIFY(!QChar(0xE2).isUpper()); // a with ^
-
- for (uint codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
- if (QChar::isUpper(codepoint))
- QVERIFY(codepoint == QChar::toUpper(codepoint));
- }
-}
-
-void tst_QChar::isLower()
-{
- QVERIFY(!QChar('A').isLower());
- QVERIFY(!QChar('Z').isLower());
- QVERIFY(QChar('a').isLower());
- QVERIFY(QChar('z').isLower());
- QVERIFY(!QChar('?').isLower());
- QVERIFY(!QChar(0xC2).isLower()); // A with ^
- QVERIFY(QChar(0xE2).isLower()); // a with ^
-
- for (uint codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
- if (QChar::isLower(codepoint))
- QVERIFY(codepoint == QChar::toLower(codepoint));
- }
-}
-
-void tst_QChar::isTitleCase()
-{
- for (uint codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
- if (QChar::isTitleCase(codepoint))
- QVERIFY(codepoint == QChar::toTitleCase(codepoint));
- }
-}
-
-void tst_QChar::isSpace_data()
-{
- QTest::addColumn<ushort>("ucs");
- QTest::addColumn<bool>("expected");
-
- for (ushort ucs = 0; ucs < 256; ++ucs) {
- bool isSpace = (ucs <= 0x0D && ucs >= 0x09) || ucs == 0x20 || ucs == 0xA0 || ucs == 0x85;
- const QByteArray tag = "0x" + QByteArray::number(ucs, 16);
- QTest::newRow(tag.constData()) << ucs << isSpace;
- }
-}
-
-void tst_QChar::isSpace()
-{
- QFETCH(ushort, ucs);
- QFETCH(bool, expected);
- QCOMPARE(QChar(ucs).isSpace(), expected);
-}
-
-void tst_QChar::isSpaceSpecial()
-{
- QVERIFY(!QChar(QChar::Null).isSpace());
- QVERIFY(QChar(QChar::Nbsp).isSpace());
- QVERIFY(QChar(QChar::ParagraphSeparator).isSpace());
- QVERIFY(QChar(QChar::LineSeparator).isSpace());
- QVERIFY(QChar(0x1680).isSpace());
-}
-
-void tst_QChar::category()
-{
- QVERIFY(QChar('a').category() == QChar::Letter_Lowercase);
- QVERIFY(QChar('A').category() == QChar::Letter_Uppercase);
-
- QVERIFY(QChar::category('a') == QChar::Letter_Lowercase);
- QVERIFY(QChar::category('A') == QChar::Letter_Uppercase);
-
- QVERIFY(QChar::category(0xe0100) == QChar::Mark_NonSpacing);
- QVERIFY(QChar::category(0xeffff) != QChar::Other_PrivateUse);
- QVERIFY(QChar::category(0xf0000) == QChar::Other_PrivateUse);
- QVERIFY(QChar::category(0xf0001) == QChar::Other_PrivateUse);
-
- QVERIFY(QChar::category(0xd900) == QChar::Other_Surrogate);
- QVERIFY(QChar::category(0xdc00) == QChar::Other_Surrogate);
- QVERIFY(QChar::category(0xdc01) == QChar::Other_Surrogate);
-
- QVERIFY(QChar::category(0x1aff) == QChar::Other_NotAssigned);
- QVERIFY(QChar::category(0x10fffd) == QChar::Other_PrivateUse);
- QVERIFY(QChar::category(0x10ffff) == QChar::Other_NotAssigned);
- QVERIFY(QChar::category(0x110000) == QChar::Other_NotAssigned);
-}
-
-void tst_QChar::direction()
-{
- QVERIFY(QChar::direction(0x200E) == QChar::DirL);
- QVERIFY(QChar::direction(0x200F) == QChar::DirR);
- QVERIFY(QChar::direction(0x202A) == QChar::DirLRE);
- QVERIFY(QChar::direction(0x202B) == QChar::DirRLE);
- QVERIFY(QChar::direction(0x202C) == QChar::DirPDF);
- QVERIFY(QChar::direction(0x202D) == QChar::DirLRO);
- QVERIFY(QChar::direction(0x202E) == QChar::DirRLO);
- QVERIFY(QChar::direction(0x2066) == QChar::DirLRI);
- QVERIFY(QChar::direction(0x2067) == QChar::DirRLI);
- QVERIFY(QChar::direction(0x2068) == QChar::DirFSI);
- QVERIFY(QChar::direction(0x2069) == QChar::DirPDI);
-
- QVERIFY(QChar('a').direction() == QChar::DirL);
- QVERIFY(QChar('0').direction() == QChar::DirEN);
- QVERIFY(QChar(0x627).direction() == QChar::DirAL);
- QVERIFY(QChar(0x5d0).direction() == QChar::DirR);
-
- QVERIFY(QChar::direction('a') == QChar::DirL);
- QVERIFY(QChar::direction('0') == QChar::DirEN);
- QVERIFY(QChar::direction(0x627) == QChar::DirAL);
- QVERIFY(QChar::direction(0x5d0) == QChar::DirR);
-
- QVERIFY(QChar::direction(0xE01DA) == QChar::DirNSM);
- QVERIFY(QChar::direction(0xf0000) == QChar::DirL);
- QVERIFY(QChar::direction(0xE0030) == QChar::DirBN);
- QVERIFY(QChar::direction(0x2FA17) == QChar::DirL);
-}
-
-void tst_QChar::joiningType()
-{
- QVERIFY(QChar('a').joiningType() == QChar::Joining_None);
- QVERIFY(QChar('0').joiningType() == QChar::Joining_None);
- QVERIFY(QChar(0x0627).joiningType() == QChar::Joining_Right);
- QVERIFY(QChar(0x05d0).joiningType() == QChar::Joining_None);
- QVERIFY(QChar(0x00ad).joiningType() == QChar::Joining_Transparent);
- QVERIFY(QChar(0xA872).joiningType() == QChar::Joining_Left);
-
- QVERIFY(QChar::joiningType('a') == QChar::Joining_None);
- QVERIFY(QChar::joiningType('0') == QChar::Joining_None);
- QVERIFY(QChar::joiningType(0x0627) == QChar::Joining_Right);
- QVERIFY(QChar::joiningType(0x05d0) == QChar::Joining_None);
- QVERIFY(QChar::joiningType(0x00ad) == QChar::Joining_Transparent);
-
- QVERIFY(QChar::joiningType(0xE01DA) == QChar::Joining_Transparent);
- QVERIFY(QChar::joiningType(0xf0000) == QChar::Joining_None);
- QVERIFY(QChar::joiningType(0xE0030) == QChar::Joining_Transparent);
- QVERIFY(QChar::joiningType(0x2FA17) == QChar::Joining_None);
-
- QVERIFY(QChar::joiningType(0xA872) == QChar::Joining_Left);
- QVERIFY(QChar::joiningType(0x10ACD) == QChar::Joining_Left);
- QVERIFY(QChar::joiningType(0x10AD7) == QChar::Joining_Left);
-}
-
-void tst_QChar::combiningClass()
-{
- QVERIFY(QChar('a').combiningClass() == 0);
- QVERIFY(QChar('0').combiningClass() == 0);
- QVERIFY(QChar(0x627).combiningClass() == 0);
- QVERIFY(QChar(0x5d0).combiningClass() == 0);
-
- QVERIFY(QChar::combiningClass('a') == 0);
- QVERIFY(QChar::combiningClass('0') == 0);
- QVERIFY(QChar::combiningClass(0x627) == 0);
- QVERIFY(QChar::combiningClass(0x5d0) == 0);
-
- QVERIFY(QChar::combiningClass(0xE01DA) == 0);
- QVERIFY(QChar::combiningClass(0xf0000) == 0);
- QVERIFY(QChar::combiningClass(0xE0030) == 0);
- QVERIFY(QChar::combiningClass(0x2FA17) == 0);
-
- QVERIFY(QChar::combiningClass(0x300) == 230);
-
- QVERIFY(QChar::combiningClass(0x1d244) == 230);
-
-}
-
-void tst_QChar::unicodeVersion()
-{
- QVERIFY(QChar('a').unicodeVersion() == QChar::Unicode_1_1);
- QVERIFY(QChar('0').unicodeVersion() == QChar::Unicode_1_1);
- QVERIFY(QChar(0x627).unicodeVersion() == QChar::Unicode_1_1);
- QVERIFY(QChar(0x5d0).unicodeVersion() == QChar::Unicode_1_1);
-
- QVERIFY(QChar::unicodeVersion('a') == QChar::Unicode_1_1);
- QVERIFY(QChar::unicodeVersion('0') == QChar::Unicode_1_1);
- QVERIFY(QChar::unicodeVersion(0x627) == QChar::Unicode_1_1);
- QVERIFY(QChar::unicodeVersion(0x5d0) == QChar::Unicode_1_1);
-
- QVERIFY(QChar(0x0591).unicodeVersion() == QChar::Unicode_2_0);
- QVERIFY(QChar::unicodeVersion(0x0591) == QChar::Unicode_2_0);
-
- QVERIFY(QChar(0x20AC).unicodeVersion() == QChar::Unicode_2_1_2);
- QVERIFY(QChar::unicodeVersion(0x20AC) == QChar::Unicode_2_1_2);
- QVERIFY(QChar(0xfffc).unicodeVersion() == QChar::Unicode_2_1_2);
- QVERIFY(QChar::unicodeVersion(0xfffc) == QChar::Unicode_2_1_2);
-
- QVERIFY(QChar(0x01f6).unicodeVersion() == QChar::Unicode_3_0);
- QVERIFY(QChar::unicodeVersion(0x01f6) == QChar::Unicode_3_0);
-
- QVERIFY(QChar(0x03F4).unicodeVersion() == QChar::Unicode_3_1);
- QVERIFY(QChar::unicodeVersion(0x03F4) == QChar::Unicode_3_1);
- QVERIFY(QChar::unicodeVersion(0x10300) == QChar::Unicode_3_1);
-
- QVERIFY(QChar(0x0220).unicodeVersion() == QChar::Unicode_3_2);
- QVERIFY(QChar::unicodeVersion(0x0220) == QChar::Unicode_3_2);
- QVERIFY(QChar::unicodeVersion(0xFF5F) == QChar::Unicode_3_2);
-
- QVERIFY(QChar(0x0221).unicodeVersion() == QChar::Unicode_4_0);
- QVERIFY(QChar::unicodeVersion(0x0221) == QChar::Unicode_4_0);
- QVERIFY(QChar::unicodeVersion(0x10000) == QChar::Unicode_4_0);
-
- QVERIFY(QChar(0x0237).unicodeVersion() == QChar::Unicode_4_1);
- QVERIFY(QChar::unicodeVersion(0x0237) == QChar::Unicode_4_1);
- QVERIFY(QChar::unicodeVersion(0x10140) == QChar::Unicode_4_1);
-
- QVERIFY(QChar(0x0242).unicodeVersion() == QChar::Unicode_5_0);
- QVERIFY(QChar::unicodeVersion(0x0242) == QChar::Unicode_5_0);
- QVERIFY(QChar::unicodeVersion(0x12000) == QChar::Unicode_5_0);
-
- QVERIFY(QChar(0x0370).unicodeVersion() == QChar::Unicode_5_1);
- QVERIFY(QChar::unicodeVersion(0x0370) == QChar::Unicode_5_1);
- QVERIFY(QChar::unicodeVersion(0x1f093) == QChar::Unicode_5_1);
-
- QVERIFY(QChar(0x0524).unicodeVersion() == QChar::Unicode_5_2);
- QVERIFY(QChar::unicodeVersion(0x0524) == QChar::Unicode_5_2);
- QVERIFY(QChar::unicodeVersion(0x2b734) == QChar::Unicode_5_2);
-
- QVERIFY(QChar(0x26ce).unicodeVersion() == QChar::Unicode_6_0);
- QVERIFY(QChar::unicodeVersion(0x26ce) == QChar::Unicode_6_0);
- QVERIFY(QChar::unicodeVersion(0x1f618) == QChar::Unicode_6_0);
-
- QVERIFY(QChar(0xa69f).unicodeVersion() == QChar::Unicode_6_1);
- QVERIFY(QChar::unicodeVersion(0xa69f) == QChar::Unicode_6_1);
- QVERIFY(QChar::unicodeVersion(0x1f600) == QChar::Unicode_6_1);
-
- QVERIFY(QChar(0x20ba).unicodeVersion() == QChar::Unicode_6_2);
- QVERIFY(QChar::unicodeVersion(0x20ba) == QChar::Unicode_6_2);
-
- QVERIFY(QChar(0x061c).unicodeVersion() == QChar::Unicode_6_3);
- QVERIFY(QChar::unicodeVersion(0x061c) == QChar::Unicode_6_3);
-
- QVERIFY(QChar(0x20bd).unicodeVersion() == QChar::Unicode_7_0);
- QVERIFY(QChar::unicodeVersion(0x20bd) == QChar::Unicode_7_0);
- QVERIFY(QChar::unicodeVersion(0x16b00) == QChar::Unicode_7_0);
-
- QVERIFY(QChar(0x08b3).unicodeVersion() == QChar::Unicode_8_0);
- QVERIFY(QChar::unicodeVersion(0x08b3) == QChar::Unicode_8_0);
- QVERIFY(QChar::unicodeVersion(0x108e0) == QChar::Unicode_8_0);
-
- QVERIFY(QChar(0x09ff).unicodeVersion() == QChar::Unicode_Unassigned);
- QVERIFY(QChar::unicodeVersion(0x09ff) == QChar::Unicode_Unassigned);
- QVERIFY(QChar::unicodeVersion(0x110000) == QChar::Unicode_Unassigned);
-}
-
-void tst_QChar::digitValue()
-{
- QVERIFY(QChar('9').digitValue() == 9);
- QVERIFY(QChar('0').digitValue() == 0);
- QVERIFY(QChar('a').digitValue() == -1);
-
- QVERIFY(QChar::digitValue('9') == 9);
- QVERIFY(QChar::digitValue('0') == 0);
-
- QVERIFY(QChar::digitValue(0x1049) == 9);
- QVERIFY(QChar::digitValue(0x1040) == 0);
-
- QVERIFY(QChar::digitValue(0xd800) == -1);
- QVERIFY(QChar::digitValue(0x110000) == -1);
-}
-
-void tst_QChar::mirroredChar()
-{
- QVERIFY(QChar(0x169B).hasMirrored());
- QVERIFY(QChar(0x169B).mirroredChar() == QChar(0x169C));
- QVERIFY(QChar(0x169C).hasMirrored());
- QVERIFY(QChar(0x169C).mirroredChar() == QChar(0x169B));
-
- QVERIFY(QChar(0x301A).hasMirrored());
- QVERIFY(QChar(0x301A).mirroredChar() == QChar(0x301B));
- QVERIFY(QChar(0x301B).hasMirrored());
- QVERIFY(QChar(0x301B).mirroredChar() == QChar(0x301A));
-}
-
-void tst_QChar::decomposition()
-{
- // Hangul syllables
- for (uint ucs = 0xac00; ucs <= 0xd7af; ++ucs) {
- QChar::Decomposition expected = QChar::unicodeVersion(ucs) > QChar::Unicode_Unassigned ? QChar::Canonical : QChar::NoDecomposition;
- QString desc = QString::fromLatin1("ucs = 0x%1, tag = %2, expected = %3")
- .arg(QString::number(ucs, 16)).arg(QChar::decompositionTag(ucs)).arg(expected);
- QVERIFY2(QChar::decompositionTag(ucs) == expected, desc.toLatin1());
- }
-
- QVERIFY(QChar(0xa0).decompositionTag() == QChar::NoBreak);
- QVERIFY(QChar(0xa8).decompositionTag() == QChar::Compat);
- QVERIFY(QChar(0x41).decompositionTag() == QChar::NoDecomposition);
-
- QVERIFY(QChar::decompositionTag(0xa0) == QChar::NoBreak);
- QVERIFY(QChar::decompositionTag(0xa8) == QChar::Compat);
- QVERIFY(QChar::decompositionTag(0x41) == QChar::NoDecomposition);
-
- QVERIFY(QChar::decomposition(0xa0) == QString(QChar(0x20)));
- QVERIFY(QChar::decomposition(0xc0) == (QString(QChar(0x41)) + QString(QChar(0x300))));
-
- {
- QString str;
- str += QChar(QChar::highSurrogate(0x1D157));
- str += QChar(QChar::lowSurrogate(0x1D157));
- str += QChar(QChar::highSurrogate(0x1D165));
- str += QChar(QChar::lowSurrogate(0x1D165));
- QVERIFY(QChar::decomposition(0x1D15e) == str);
- }
-
- {
- QString str;
- str += QChar(0x1100);
- str += QChar(0x1161);
- QVERIFY(QChar::decomposition(0xac00) == str);
- }
- {
- QString str;
- str += QChar(0x110c);
- str += QChar(0x1165);
- str += QChar(0x11b7);
- QVERIFY(QChar::decomposition(0xc810) == str);
- }
-}
-
-void tst_QChar::lineBreakClass()
-{
- QVERIFY(QUnicodeTables::lineBreakClass(0x0029) == QUnicodeTables::LineBreak_CP);
- QVERIFY(QUnicodeTables::lineBreakClass(0x0041) == QUnicodeTables::LineBreak_AL);
- QVERIFY(QUnicodeTables::lineBreakClass(0x0033) == QUnicodeTables::LineBreak_NU);
- QVERIFY(QUnicodeTables::lineBreakClass(0x00ad) == QUnicodeTables::LineBreak_BA);
- QVERIFY(QUnicodeTables::lineBreakClass(0x05d0) == QUnicodeTables::LineBreak_HL);
- QVERIFY(QUnicodeTables::lineBreakClass(0xfffc) == QUnicodeTables::LineBreak_CB);
- QVERIFY(QUnicodeTables::lineBreakClass(0xe0164) == QUnicodeTables::LineBreak_CM);
- QVERIFY(QUnicodeTables::lineBreakClass(0x2f9a4) == QUnicodeTables::LineBreak_ID);
- QVERIFY(QUnicodeTables::lineBreakClass(0x10000) == QUnicodeTables::LineBreak_AL);
- QVERIFY(QUnicodeTables::lineBreakClass(0x1f1e6) == QUnicodeTables::LineBreak_RI);
-
- // mapped to AL:
- QVERIFY(QUnicodeTables::lineBreakClass(0xfffd) == QUnicodeTables::LineBreak_AL); // AI -> AL
- QVERIFY(QUnicodeTables::lineBreakClass(0x100000) == QUnicodeTables::LineBreak_AL); // XX -> AL
-}
-
-void tst_QChar::script()
-{
- QVERIFY(QChar::script(0x0020) == QChar::Script_Common);
- QVERIFY(QChar::script(0x0041) == QChar::Script_Latin);
- QVERIFY(QChar::script(0x0375) == QChar::Script_Greek);
- QVERIFY(QChar::script(0x0400) == QChar::Script_Cyrillic);
- QVERIFY(QChar::script(0x0531) == QChar::Script_Armenian);
- QVERIFY(QChar::script(0x0591) == QChar::Script_Hebrew);
- QVERIFY(QChar::script(0x0600) == QChar::Script_Arabic);
- QVERIFY(QChar::script(0x0700) == QChar::Script_Syriac);
- QVERIFY(QChar::script(0x0780) == QChar::Script_Thaana);
- QVERIFY(QChar::script(0x07c0) == QChar::Script_Nko);
- QVERIFY(QChar::script(0x0900) == QChar::Script_Devanagari);
- QVERIFY(QChar::script(0x0981) == QChar::Script_Bengali);
- QVERIFY(QChar::script(0x0a01) == QChar::Script_Gurmukhi);
- QVERIFY(QChar::script(0x0a81) == QChar::Script_Gujarati);
- QVERIFY(QChar::script(0x0b01) == QChar::Script_Oriya);
- QVERIFY(QChar::script(0x0b82) == QChar::Script_Tamil);
- QVERIFY(QChar::script(0x0c01) == QChar::Script_Telugu);
- QVERIFY(QChar::script(0x0c82) == QChar::Script_Kannada);
- QVERIFY(QChar::script(0x0d02) == QChar::Script_Malayalam);
- QVERIFY(QChar::script(0x0d82) == QChar::Script_Sinhala);
- QVERIFY(QChar::script(0x0e01) == QChar::Script_Thai);
- QVERIFY(QChar::script(0x0e81) == QChar::Script_Lao);
- QVERIFY(QChar::script(0x0f00) == QChar::Script_Tibetan);
- QVERIFY(QChar::script(0x1000) == QChar::Script_Myanmar);
- QVERIFY(QChar::script(0x10a0) == QChar::Script_Georgian);
- QVERIFY(QChar::script(0x1100) == QChar::Script_Hangul);
- QVERIFY(QChar::script(0x1680) == QChar::Script_Ogham);
- QVERIFY(QChar::script(0x16a0) == QChar::Script_Runic);
- QVERIFY(QChar::script(0x1780) == QChar::Script_Khmer);
- QVERIFY(QChar::script(0x200c) == QChar::Script_Inherited);
- QVERIFY(QChar::script(0x200d) == QChar::Script_Inherited);
- QVERIFY(QChar::script(0x1018a) == QChar::Script_Greek);
- QVERIFY(QChar::script(0x1f130) == QChar::Script_Common);
- QVERIFY(QChar::script(0xe0100) == QChar::Script_Inherited);
-}
-
-void tst_QChar::normalization_data()
-{
- QTest::addColumn<QStringList>("columns");
- QTest::addColumn<int>("part");
-
- int linenum = 0;
- int part = 0;
-
- QString testFile = QFINDTESTDATA("data/NormalizationTest.txt");
- QVERIFY2(!testFile.isEmpty(), "data/NormalizationTest.txt not found!");
- QFile f(testFile);
- QVERIFY(f.exists());
-
- f.open(QIODevice::ReadOnly);
-
- while (!f.atEnd()) {
- linenum++;
-
- QByteArray line;
- line.resize(1024);
- int len = f.readLine(line.data(), 1024);
- line.resize(len-1);
-
- int comment = line.indexOf('#');
- if (comment >= 0)
- line = line.left(comment);
-
- if (line.startsWith('@')) {
- if (line.startsWith("@Part") && line.size() > 5 && QChar(line.at(5)).isDigit())
- part = QChar(line.at(5)).digitValue();
- continue;
- }
-
- if (line.isEmpty())
- continue;
-
- line = line.trimmed();
- if (line.endsWith(';'))
- line.truncate(line.length()-1);
-
- QList<QByteArray> l = line.split(';');
-
- QCOMPARE(l.size(), 5);
-
- QStringList columns;
- for (int i = 0; i < 5; ++i) {
- columns.append(QString());
-
- QList<QByteArray> c = l.at(i).split(' ');
- QVERIFY(!c.isEmpty());
-
- for (int j = 0; j < c.size(); ++j) {
- bool ok;
- uint uc = c.at(j).toInt(&ok, 16);
- if (!QChar::requiresSurrogates(uc)) {
- columns[i].append(QChar(uc));
- } else {
- // convert to utf16
- columns[i].append(QChar(QChar::highSurrogate(uc)));
- columns[i].append(QChar(QChar::lowSurrogate(uc)));
- }
- }
- }
-
-
- const QByteArray nm = "line #" + QByteArray::number(linenum) + " (part "
- + QByteArray::number(part);
- QTest::newRow(nm.constData()) << columns << part;
- }
-}
-
-void tst_QChar::normalization()
-{
- QFETCH(QStringList, columns);
- QFETCH(int, part);
-
- Q_UNUSED(part)
-
- // CONFORMANCE:
- // 1. The following invariants must be true for all conformant implementations
- //
- // NFC
- // c2 == NFC(c1) == NFC(c2) == NFC(c3)
- // c4 == NFC(c4) == NFC(c5)
-
- QVERIFY(columns[1] == columns[0].normalized(QString::NormalizationForm_C));
- QVERIFY(columns[1] == columns[1].normalized(QString::NormalizationForm_C));
- QVERIFY(columns[1] == columns[2].normalized(QString::NormalizationForm_C));
- QVERIFY(columns[3] == columns[3].normalized(QString::NormalizationForm_C));
- QVERIFY(columns[3] == columns[4].normalized(QString::NormalizationForm_C));
-
- // NFD
- // c3 == NFD(c1) == NFD(c2) == NFD(c3)
- // c5 == NFD(c4) == NFD(c5)
-
- QVERIFY(columns[2] == columns[0].normalized(QString::NormalizationForm_D));
- QVERIFY(columns[2] == columns[1].normalized(QString::NormalizationForm_D));
- QVERIFY(columns[2] == columns[2].normalized(QString::NormalizationForm_D));
- QVERIFY(columns[4] == columns[3].normalized(QString::NormalizationForm_D));
- QVERIFY(columns[4] == columns[4].normalized(QString::NormalizationForm_D));
-
- // NFKC
- // c4 == NFKC(c1) == NFKC(c2) == NFKC(c3) == NFKC(c4) == NFKC(c5)
-
- QVERIFY(columns[3] == columns[0].normalized(QString::NormalizationForm_KC));
- QVERIFY(columns[3] == columns[1].normalized(QString::NormalizationForm_KC));
- QVERIFY(columns[3] == columns[2].normalized(QString::NormalizationForm_KC));
- QVERIFY(columns[3] == columns[3].normalized(QString::NormalizationForm_KC));
- QVERIFY(columns[3] == columns[4].normalized(QString::NormalizationForm_KC));
-
- // NFKD
- // c5 == NFKD(c1) == NFKD(c2) == NFKD(c3) == NFKD(c4) == NFKD(c5)
-
- QVERIFY(columns[4] == columns[0].normalized(QString::NormalizationForm_KD));
- QVERIFY(columns[4] == columns[1].normalized(QString::NormalizationForm_KD));
- QVERIFY(columns[4] == columns[2].normalized(QString::NormalizationForm_KD));
- QVERIFY(columns[4] == columns[3].normalized(QString::NormalizationForm_KD));
- QVERIFY(columns[4] == columns[4].normalized(QString::NormalizationForm_KD));
-
- // 2. For every code point X assigned in this version of Unicode that is not specifically
- // listed in Part 1, the following invariants must be true for all conformant
- // implementations:
- //
- // X == NFC(X) == NFD(X) == NFKC(X) == NFKD(X)
-
- // #################
-
-}
-
-void tst_QChar::normalization_manual()
-{
- {
- QString decomposed;
- decomposed += QChar(0x41);
- decomposed += QChar(0x0221); // assigned in 4.0
- decomposed += QChar(0x300);
-
- QVERIFY(decomposed.normalized(QString::NormalizationForm_C, QChar::Unicode_3_2) == decomposed);
-
- decomposed[1] = QChar(0x037f); // unassigned in 6.1
-
- QVERIFY(decomposed.normalized(QString::NormalizationForm_C) == decomposed);
- }
- {
- QString composed;
- composed += QChar(0xc0);
- QString decomposed;
- decomposed += QChar(0x41);
- decomposed += QChar(0x300);
-
- QVERIFY(composed.normalized(QString::NormalizationForm_D) == decomposed);
- QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed);
- QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed);
- QVERIFY(composed.normalized(QString::NormalizationForm_KC) == composed);
- }
- {
- QString composed;
- composed += QChar(0xa0);
- QString decomposed;
- decomposed += QChar(0x20);
-
- QVERIFY(composed.normalized(QString::NormalizationForm_D) == composed);
- QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed);
- QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed);
- QVERIFY(composed.normalized(QString::NormalizationForm_KC) == decomposed);
- }
- {
- QString composed;
- composed += QChar(0x0061);
- composed += QChar(0x00f2);
- QString decomposed;
- decomposed += QChar(0x0061);
- decomposed += QChar(0x006f);
- decomposed += QChar(0x0300);
-
- QVERIFY(decomposed.normalized(QString::NormalizationForm_D) == decomposed);
- QVERIFY(decomposed.normalized(QString::NormalizationForm_C) == composed);
- QVERIFY(decomposed.normalized(QString::NormalizationForm_KD) == decomposed);
- QVERIFY(decomposed.normalized(QString::NormalizationForm_KC) == composed);
- }
- { // hangul
- QString composed;
- composed += QChar(0xc154);
- composed += QChar(0x11f0);
- QString decomposed;
- decomposed += QChar(0x1109);
- decomposed += QChar(0x1167);
- decomposed += QChar(0x11f0);
-
- QVERIFY(composed.normalized(QString::NormalizationForm_D) == decomposed);
- QVERIFY(composed.normalized(QString::NormalizationForm_C) == composed);
- QVERIFY(composed.normalized(QString::NormalizationForm_KD) == decomposed);
- QVERIFY(composed.normalized(QString::NormalizationForm_KC) == composed);
-
- QVERIFY(decomposed.normalized(QString::NormalizationForm_D) == decomposed);
- QVERIFY(decomposed.normalized(QString::NormalizationForm_C) == composed);
- QVERIFY(decomposed.normalized(QString::NormalizationForm_KD) == decomposed);
- QVERIFY(decomposed.normalized(QString::NormalizationForm_KC) == composed);
- }
-}
-
-void tst_QChar::normalizationCorrections()
-{
- QString s;
- s.append(QChar(0xf951));
-
- QString n = s.normalized(QString::NormalizationForm_D);
- QString res;
- res.append(QChar(0x964b));
- QCOMPARE(n, res);
-
- n = s.normalized(QString::NormalizationForm_D, QChar::Unicode_3_1);
- res.clear();
- res.append(QChar(0x96fb));
- QCOMPARE(n, res);
-
- s.clear();
- s += QChar(QChar::highSurrogate(0x2f868));
- s += QChar(QChar::lowSurrogate(0x2f868));
-
- n = s.normalized(QString::NormalizationForm_C);
- res.clear();
- res += QChar(0x36fc);
- QCOMPARE(n, res);
-
- n = s.normalized(QString::NormalizationForm_C, QChar::Unicode_3_1);
- res.clear();
- res += QChar(0xd844);
- res += QChar(0xdf6a);
- QCOMPARE(n, res);
-
- n = s.normalized(QString::NormalizationForm_C, QChar::Unicode_3_2);
- QCOMPARE(n, res);
-}
-
-
-QTEST_APPLESS_MAIN(tst_QChar)
-#include "tst_qchar.moc"
diff --git a/tests/auto/corelib/tools/qcollator/qcollator.pro b/tests/auto/corelib/tools/qcollator/qcollator.pro
deleted file mode 100644
index 2f3995a75f..0000000000
--- a/tests/auto/corelib/tools/qcollator/qcollator.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qcollator
-QT = core-private testlib
-SOURCES = tst_qcollator.cpp
-DEFINES += QT_NO_CAST_TO_ASCII
-qtConfig(icu): DEFINES += QT_USE_ICU
diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp
deleted file mode 100644
index 72f88a235d..0000000000
--- a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include <qlocale.h>
-#include <qcollator.h>
-#include <private/qglobal_p.h>
-
-#include <cstring>
-
-class tst_QCollator : public QObject
-{
- Q_OBJECT
-
-private Q_SLOTS:
- void moveSemantics();
-
- void compare_data();
- void compare();
-
- void state();
-};
-
-#ifdef Q_COMPILER_RVALUE_REFS
-static bool dpointer_is_null(QCollator &c)
-{
- char mem[sizeof c];
- using namespace std;
- memcpy(mem, &c, sizeof c);
- for (size_t i = 0; i < sizeof c; ++i)
- if (mem[i])
- return false;
- return true;
-}
-#endif
-
-void tst_QCollator::moveSemantics()
-{
-#ifdef Q_COMPILER_RVALUE_REFS
- const QLocale de_AT(QLocale::German, QLocale::Austria);
-
- QCollator c1(de_AT);
- QCOMPARE(c1.locale(), de_AT);
-
- QCollator c2(std::move(c1));
- QCOMPARE(c2.locale(), de_AT);
- QVERIFY(dpointer_is_null(c1));
-
- QCollator c3(c1);
- QVERIFY(dpointer_is_null(c3));
-
- c1 = std::move(c2);
- QCOMPARE(c1.locale(), de_AT);
- QVERIFY(dpointer_is_null(c2));
-#else
- QSKIP("The compiler is not in C++11 mode or does not support move semantics.");
-#endif
-}
-
-
-void tst_QCollator::compare_data()
-{
- QTest::addColumn<QString>("locale");
- QTest::addColumn<QString>("s1");
- QTest::addColumn<QString>("s2");
- QTest::addColumn<int>("result");
- QTest::addColumn<int>("caseInsensitiveResult");
- QTest::addColumn<bool>("numericMode");
- QTest::addColumn<bool>("ignorePunctuation");
- QTest::addColumn<int>("punctuationResult"); // Test ignores punctuation *and case*
-
- /*
- It's hard to test English, because it's treated differently
- on different platforms. For example, on Linux, it uses the
- iso14651_t1 template file, which happens to provide good
- defaults for Swedish. OS X seems to do a pure bytewise
- comparison of Latin-1 values, although I'm not sure. So I
- just test digits to make sure that it's not totally broken.
- */
- QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1 << 1 << false << false << 1;
- QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1 << -1 << false << false << -1;
- QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1 << -1 << false << false << -1;
- QTest::newRow("english4") << QString("en_US") << QString("a") << QString("b") << -1 << -1 << false << false << -1;
- QTest::newRow("english5") << QString("en_US") << QString("test 9") << QString("test 19") << -1 << -1 << true << false << -1;
- QTest::newRow("english6") << QString("en_US") << QString("test 9") << QString("test_19") << -1 << -1 << true << true << -1;
- QTest::newRow("english7") << QString("en_US") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
- QTest::newRow("english8") << QString("en_US") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
-
- /*
- In Swedish, a with ring above (E5) comes before a with
- diaresis (E4), which comes before o diaresis (F6), which
- all come after z.
- */
- QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1 << -1 << false << false << -1;
- QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
- QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
- QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
- QTest::newRow("swedish5") << QString("sv_SE") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
- QTest::newRow("swedish6") << QString("sv_SE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
- QTest::newRow("swedish7") << QString("sv_SE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
- QTest::newRow("swedish8") << QString("sv_SE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
-
-
- /*
- In Norwegian, ae (E6) comes before o with stroke (D8), which
- comes before a with ring above (E5).
- */
- QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1 << -1 << false << false << -1;
- QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
- QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1 << -1 << false << false << -1;
- QTest::newRow("norwegian4") << QString("no_NO") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
- QTest::newRow("norwegian5") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
- QTest::newRow("norwegian6") << QString("no_NO") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
- QTest::newRow("norwegian7") << QString("no_NO") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
- QTest::newRow("norwegian8") << QString("no_NO") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
-
- /*
- In German, z comes *after* a with diaresis (E4),
- which comes before o diaresis (F6).
- */
- QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("a") << QString::fromLatin1("\xe4") << -1 << -1 << false << false << -1;
- QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("b") << QString::fromLatin1("\xe4") << 1 << 1 << false << false << 1;
- QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1 << 1 << false << false << 1;
- QTest::newRow("german4") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false << false << -1;
- QTest::newRow("german5") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1 << 1 << false << false << 1;
- QTest::newRow("german6") << QString("de_DE") << QString::fromLatin1("\xc0") << QString::fromLatin1("\xe0") << 1 << 0 << false << false << 0;
- QTest::newRow("german7") << QString("de_DE") << QString::fromLatin1("\xd6") << QString::fromLatin1("\xf6") << 1 << 0 << false << false << 0;
- QTest::newRow("german8") << QString("de_DE") << QString::fromLatin1("oe") << QString::fromLatin1("\xf6") << 1 << 1 << false << false << 1;
- QTest::newRow("german9") << QString("de_DE") << QString("A") << QString("a") << 1 << 0 << false << false << 0;
- QTest::newRow("german10") << QString("de_DE") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
- QTest::newRow("german11") << QString("de_DE") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
- QTest::newRow("german12") << QString("de_DE") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
- QTest::newRow("german13") << QString("de_DE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
-
- /*
- French sorting of e and e with acute accent
- */
- QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1 << false << false << 1;
- QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1 << false << false << 1;
- QTest::newRow("french3") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("d") << 1 << 1 << false << false << 1;
- QTest::newRow("french4") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("f") << -1 << -1 << false << false << -1;
- QTest::newRow("french5") << QString("fr_FR") << QString("9") << QString("19") << -1 << -1 << true << false << -1;
- QTest::newRow("french6") << QString("fr_FR") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1;
- QTest::newRow("french7") << QString("fr_FR") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1;
- QTest::newRow("french8") << QString("fr_FR") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0;
-
- // C locale: case sensitive [A-Z] < [a-z] but case insensitive [Aa] < [Bb] <...< [Zz]
- const QString C = QStringLiteral("C");
- QTest::newRow("C:ABBA:AaaA") << C << QStringLiteral("ABBA") << QStringLiteral("AaaA") << -1 << 1 << false << false << 1;
- QTest::newRow("C:AZa:aAZ") << C << QStringLiteral("AZa") << QStringLiteral("aAZ") << -1 << 1 << false << false << 1;
-}
-
-void tst_QCollator::compare()
-{
- QFETCH(QString, locale);
- QFETCH(QString, s1);
- QFETCH(QString, s2);
- QFETCH(int, result);
- QFETCH(int, caseInsensitiveResult);
- QFETCH(bool, numericMode);
- QFETCH(bool, ignorePunctuation);
- QFETCH(int, punctuationResult);
-
- QCollator collator(locale);
- // Need to canonicalize sign to -1, 0 or 1, as .compare() can produce any -ve for <, any +ve for >.
- auto asSign = [](int compared) {
- return compared < 0 ? -1 : compared > 0 ? 1 : 0;
- };
-
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- if (collator.locale() != QLocale())
- QSKIP("Posix implementation of collation only supports default locale");
-#endif
-
- if (numericMode)
- collator.setNumericMode(true);
-
- QCOMPARE(asSign(collator.compare(s1, s2)), result);
- collator.setCaseSensitivity(Qt::CaseInsensitive);
- QCOMPARE(asSign(collator.compare(s1, s2)), caseInsensitiveResult);
-#if !QT_CONFIG(iconv)
- collator.setIgnorePunctuation(ignorePunctuation);
- QCOMPARE(asSign(collator.compare(s1, s2)), punctuationResult);
-#endif
-}
-
-
-void tst_QCollator::state()
-{
- QCollator c;
- c.setCaseSensitivity(Qt::CaseInsensitive);
- c.setLocale(QLocale::German);
-
- c.compare(QString("a"), QString("b"));
-
- QCOMPARE(c.caseSensitivity(), Qt::CaseInsensitive);
- QCOMPARE(c.locale(), QLocale(QLocale::German));
-
- c.setLocale(QLocale::French);
- c.setNumericMode(true);
- c.setIgnorePunctuation(true);
- c.setLocale(QLocale::Norwegian);
-
- QCOMPARE(c.caseSensitivity(), Qt::CaseInsensitive);
- QCOMPARE(c.numericMode(), true);
- QCOMPARE(c.ignorePunctuation(), true);
- QCOMPARE(c.locale(), QLocale(QLocale::Norwegian));
-
-}
-
-QTEST_APPLESS_MAIN(tst_QCollator)
-
-#include "tst_qcollator.moc"
diff --git a/tests/auto/corelib/tools/qcommandlineparser/CMakeLists.txt b/tests/auto/corelib/tools/qcommandlineparser/CMakeLists.txt
new file mode 100644
index 0000000000..5aa8bd2500
--- /dev/null
+++ b/tests/auto/corelib/tools/qcommandlineparser/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcommandlineparser Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcommandlineparser LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcommandlineparser
+ SOURCES
+ tst_qcommandlineparser.cpp
+)
+add_subdirectory(testhelper)
+if(QT_FEATURE_process AND NOT ANDROID)
+ add_dependencies(tst_qcommandlineparser qcommandlineparser_test_helper)
+endif()
diff --git a/tests/auto/corelib/tools/qcommandlineparser/qcommandlineparser.pro b/tests/auto/corelib/tools/qcommandlineparser/qcommandlineparser.pro
deleted file mode 100644
index a9aedc4c0d..0000000000
--- a/tests/auto/corelib/tools/qcommandlineparser/qcommandlineparser.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += tst_qcommandlineparser.pro testhelper/qcommandlineparser_test_helper.pro
diff --git a/tests/auto/corelib/tools/qcommandlineparser/testhelper/CMakeLists.txt b/tests/auto/corelib/tools/qcommandlineparser/testhelper/CMakeLists.txt
new file mode 100644
index 0000000000..20cec30a9c
--- /dev/null
+++ b/tests/auto/corelib/tools/qcommandlineparser/testhelper/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## qcommandlineparser_test_helper Binary:
+#####################################################################
+
+qt_internal_add_executable(qcommandlineparser_test_helper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ qcommandlineparser_test_helper.cpp
+)
diff --git a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp
index b9bcecd607..b5f178a3d1 100644
--- a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp
+++ b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 David Faure <faure@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2013 David Faure <faure@kde.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDebug>
#include <QCoreApplication>
@@ -74,10 +49,6 @@ int main(int argc, char *argv[])
hiddenOption.setDescription(QStringLiteral("THIS SHOULD NEVER APPEAR"));
hiddenOption.setFlags(QCommandLineOption::HiddenFromHelp);
parser.addOption(hiddenOption);
- QCommandLineOption hiddenOption2(QStringList() << QStringLiteral("hidden2"));
- hiddenOption2.setDescription(QStringLiteral("NEITHER SHOULD THIS"));
- hiddenOption2.setHidden(true);
- parser.addOption(hiddenOption2);
// This program supports different options depending on the "command" (first argument).
// Call parse() to find out the positional arguments.
@@ -95,6 +66,13 @@ int main(int argc, char *argv[])
parser.process(app);
const QString size = parser.value("size");
printf("Resizing %s to %s and saving to %s\n", qPrintable(parser.value("load")), qPrintable(size), qPrintable(parser.value("o")));
+ } else if (command == "long") {
+ // A very long option (QTBUG-79926)
+ QCommandLineOption longOption(QStringList{QStringLiteral("looooooooooooong-option"), QStringLiteral("looooong-opt-alias")});
+ longOption.setDescription(QStringLiteral("Short description"));
+ longOption.setValueName(QStringLiteral("looooooooooooong-value-name"));
+ parser.addOption(longOption);
+ parser.process(app);
} else {
// Call process again, to handle unknown options this time.
parser.process(app);
diff --git a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro
deleted file mode 100644
index 5020658835..0000000000
--- a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += cmdline
-QT = core
-DESTDIR = ./
-
-SOURCES += qcommandlineparser_test_helper.cpp
diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
index 62c29229e1..812cf2d1b3 100644
--- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
+++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
@@ -1,32 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 David Faure <faure@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 David Faure <faure@kde.org>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#if QT_CONFIG(process)
+#include <QProcess>
+#endif
#include <QtCore/QCommandLineParser>
Q_DECLARE_METATYPE(char**)
@@ -44,6 +23,7 @@ private slots:
// In-process tests
void testInvalidOptions();
+ void testDuplicateOption();
void testPositionalArguments();
void testBooleanOption_data();
void testBooleanOption();
@@ -62,6 +42,7 @@ private slots:
void testDefaultValue();
void testProcessNotCalled();
void testEmptyArgsList();
+ void testNoApplication();
void testMissingOptionValue();
void testStdinArgument_data();
void testStdinArgument();
@@ -74,6 +55,10 @@ private slots:
void testHelpOption_data();
void testHelpOption();
void testQuoteEscaping();
+ void testUnknownOption();
+ void testHelpAll_data();
+ void testHelpAll();
+ void testVeryLongOptionNames();
};
static char *empty_argv[] = { 0 };
@@ -103,6 +88,15 @@ void tst_QCommandLineParser::testInvalidOptions()
QVERIFY(!parser.addOption(QCommandLineOption(QStringLiteral("-v"), QStringLiteral("Displays version information."))));
}
+void tst_QCommandLineParser::testDuplicateOption()
+{
+ QCoreApplication app(empty_argc, empty_argv);
+ QCommandLineParser parser;
+ QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("h"), QStringLiteral("Hostname."), QStringLiteral("hostname"))));
+ QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: already having an option named \"h\"");
+ parser.addHelpOption();
+}
+
void tst_QCommandLineParser::testPositionalArguments()
{
QCoreApplication app(empty_argc, empty_argv);
@@ -132,6 +126,7 @@ void tst_QCommandLineParser::testBooleanOption()
QVERIFY(parser.parse(args));
QCOMPARE(parser.optionNames(), expectedOptionNames);
QCOMPARE(parser.isSet("b"), expectedIsSet);
+ QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: option not expecting values: \"b\"");
QCOMPARE(parser.values("b"), QStringList());
QCOMPARE(parser.positionalArguments(), QStringList());
// Should warn on typos
@@ -169,6 +164,7 @@ void tst_QCommandLineParser::testOptionsAndPositional()
QVERIFY(parser.parse(args));
QCOMPARE(parser.optionNames(), expectedOptionNames);
QCOMPARE(parser.isSet("b"), expectedIsSet);
+ QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: option not expecting values: \"b\"");
QCOMPARE(parser.values("b"), QStringList());
QCOMPARE(parser.positionalArguments(), expectedPositionalArguments);
}
@@ -367,6 +363,7 @@ void tst_QCommandLineParser::testProcessNotCalled()
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: call process() or parse() before isSet");
QVERIFY(!parser.isSet("b"));
QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: call process() or parse() before values");
+ QTest::ignoreMessage(QtWarningMsg, "QCommandLineParser: option not expecting values: \"b\"");
QCOMPARE(parser.values("b"), QStringList());
}
@@ -378,6 +375,34 @@ void tst_QCommandLineParser::testEmptyArgsList()
QVERIFY(!parser.parse(QStringList())); // invalid call, argv[0] is missing
}
+void tst_QCommandLineParser::testNoApplication()
+{
+ QCommandLineOption option(QStringLiteral("param"), QStringLiteral("Pass parameter to the backend."));
+ option.setValueName("key=value");
+ QCommandLineParser parser;
+ QVERIFY(parser.addOption(option));
+ {
+ QVERIFY(parser.parse(QStringList() << "tst" << "--param" << "key1=value1"));
+ QVERIFY(parser.isSet("param"));
+ QCOMPARE(parser.values("param"), QStringList() << "key1=value1");
+ QCOMPARE(parser.value("param"), QString("key1=value1"));
+ }
+ {
+ QVERIFY(parser.parse(QStringList() << "tst" << "--param" << "key1=value1" << "--param" << "key2=value2"));
+ QVERIFY(parser.isSet("param"));
+ QCOMPARE(parser.values("param"), QStringList() << "key1=value1" << "key2=value2");
+ QCOMPARE(parser.value("param"), QString("key2=value2"));
+ }
+
+ const QString expected =
+ "Usage: <executable_name> [options]\n"
+ "\n"
+ "Options:\n"
+ " --param <key=value> Pass parameter to the backend.\n";
+
+ QCOMPARE(parser.helpText(), expected);
+}
+
void tst_QCommandLineParser::testMissingOptionValue()
{
QCoreApplication app(empty_argc, empty_argv);
@@ -426,37 +451,40 @@ void tst_QCommandLineParser::testSingleDashWordOptionModes_data()
QTest::addColumn<QStringList>("commandLine");
QTest::addColumn<QStringList>("expectedOptionNames");
QTest::addColumn<QStringList>("expectedOptionValues");
+ QTest::addColumn<QStringList>("invalidOptionValues");
QTest::newRow("collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-abc" << "val")
- << (QStringList() << "a" << "b" << "c") << (QStringList() << QString() << QString() << "val");
+ << (QStringList() << "a" << "b" << "c") << (QStringList() << QString() << QString() << "val")
+ << (QStringList() << "a" << "b");
QTest::newRow("collapsed_with_equalsign_value") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-abc=val")
- << (QStringList() << "a" << "b" << "c") << (QStringList() << QString() << QString() << "val");
+ << (QStringList() << "a" << "b" << "c") << (QStringList() << QString() << QString() << "val")
+ << (QStringList() << "a" << "b");
QTest::newRow("collapsed_explicit_longoption") << QCommandLineParser::ParseAsCompactedShortOptions << QStringList("--nn")
- << QStringList("nn") << QStringList();
+ << QStringList("nn") << QStringList() << QStringList();
QTest::newRow("collapsed_longoption_value") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "--abc" << "val")
- << QStringList("abc") << QStringList("val");
+ << QStringList("abc") << QStringList("val") << QStringList();
QTest::newRow("compiler") << QCommandLineParser::ParseAsCompactedShortOptions << QStringList("-cab")
- << QStringList("c") << QStringList("ab");
+ << QStringList("c") << QStringList("ab") << QStringList();
QTest::newRow("compiler_with_space") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-c" << "val")
- << QStringList("c") << QStringList("val");
+ << QStringList("c") << QStringList("val") << QStringList();
QTest::newRow("implicitlylong") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-abc" << "val")
- << QStringList("abc") << QStringList("val");
+ << QStringList("abc") << QStringList("val") << QStringList();
QTest::newRow("implicitlylong_equal") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-abc=val")
- << QStringList("abc") << QStringList("val");
+ << QStringList("abc") << QStringList("val") << QStringList();
QTest::newRow("implicitlylong_longoption") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "--nn")
- << QStringList("nn") << QStringList();
+ << QStringList("nn") << QStringList() << QStringList();
QTest::newRow("implicitlylong_longoption_value") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "--abc" << "val")
- << QStringList("abc") << QStringList("val");
+ << QStringList("abc") << QStringList("val") << QStringList();
QTest::newRow("implicitlylong_with_space") << QCommandLineParser::ParseAsCompactedShortOptions << (QStringList() << "-c" << "val")
- << QStringList("c") << QStringList("val");
+ << QStringList("c") << QStringList("val") << QStringList();
QTest::newRow("forceshort_detached") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-I" << "45")
- << QStringList("I") << QStringList("45");
+ << QStringList("I") << QStringList("45") << QStringList();
QTest::newRow("forceshort_attached") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-I46")
- << QStringList("I") << QStringList("46");
+ << QStringList("I") << QStringList("46") << QStringList();
QTest::newRow("forceshort_mixed") << QCommandLineParser::ParseAsLongOptions << (QStringList() << "-I45" << "-nn")
- << (QStringList() << "I" << "nn") << QStringList("45");
+ << (QStringList() << "I" << "nn") << QStringList("45") << QStringList();
}
void tst_QCommandLineParser::testSingleDashWordOptionModes()
@@ -465,6 +493,7 @@ void tst_QCommandLineParser::testSingleDashWordOptionModes()
QFETCH(QStringList, commandLine);
QFETCH(QStringList, expectedOptionNames);
QFETCH(QStringList, expectedOptionValues);
+ QFETCH(QStringList, invalidOptionValues);
commandLine.prepend("tst_QCommandLineParser");
@@ -481,14 +510,19 @@ void tst_QCommandLineParser::testSingleDashWordOptionModes()
QVERIFY(parser.addOption(forceShort));
QVERIFY(parser.parse(commandLine));
QCOMPARE(parser.optionNames(), expectedOptionNames);
- for (int i = 0; i < expectedOptionValues.count(); ++i)
- QCOMPARE(parser.value(parser.optionNames().at(i)), expectedOptionValues.at(i));
+ for (int i = 0; i < expectedOptionValues.size(); ++i) {
+ const QString option = parser.optionNames().at(i);
+ if (invalidOptionValues.contains(option)) {
+ QByteArray msg = QLatin1String("QCommandLineParser: option not expecting values: \"%1\"").arg(option).toLatin1();
+ QTest::ignoreMessage(QtWarningMsg, msg.data());
+ }
+ QCOMPARE(parser.value(option), expectedOptionValues.at(i));
+ }
QCOMPARE(parser.unknownOptionNames(), QStringList());
}
void tst_QCommandLineParser::testCpp11StyleInitialization()
{
-#if defined(Q_COMPILER_INITIALIZER_LISTS) && defined(Q_COMPILER_UNIFORM_INIT)
QCoreApplication app(empty_argc, empty_argv);
QCommandLineParser parser;
@@ -502,19 +536,15 @@ void tst_QCommandLineParser::testCpp11StyleInitialization()
QVERIFY(parser.parse({"tst_QCommandLineParser", "-a", "-vvv", "--infile=in.txt"}));
QCOMPARE(parser.optionNames(), (QStringList{"a", "v", "v", "v", "infile"}));
QCOMPARE(parser.value("infile"), QString("in.txt"));
-#else
- QSKIP("This test requires C++11 uniform initialization support in the compiler.");
-#endif
}
void tst_QCommandLineParser::testVersionOption()
{
#if !QT_CONFIG(process)
QSKIP("This test requires QProcess support");
-#else
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#elif defined(Q_OS_ANDROID)
QSKIP("Deploying executable applications to file system on Android not supported.");
-#endif
+#else
QCoreApplication app(empty_argc, empty_argv);
QProcess process;
@@ -531,7 +561,8 @@ void tst_QCommandLineParser::testVersionOption()
static const char expectedOptionsHelp[] =
"Options:\n"
- " -h, --help Displays this help.\n"
+ " -h, --help Displays help on commandline options.\n"
+ " --help-all Displays help, including generic Qt options.\n"
" -v, --version Displays version information.\n"
" --load <url> Load file from URL.\n"
" -o, --output <file> Set output file.\n"
@@ -565,8 +596,8 @@ void tst_QCommandLineParser::testHelpOption_data()
" parsingMode The parsing mode to test.\n"
" command The command to execute.\n");
#ifdef Q_OS_WIN
- expectedOutput.replace(" -h, --help Displays this help.\n",
- " -?, -h, --help Displays this help.\n");
+ expectedOutput.replace(" -h, --help Displays help on commandline options.\n",
+ " -?, -h, --help Displays help on commandline options.\n");
expectedOutput.replace("testhelper/", "testhelper\\");
#endif
@@ -578,10 +609,9 @@ void tst_QCommandLineParser::testHelpOption()
{
#if !QT_CONFIG(process)
QSKIP("This test requires QProcess support");
-#else
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#elif defined(Q_OS_ANDROID)
QSKIP("Deploying executable applications to file system on Android not supported.");
-#endif
+#else
QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
QFETCH(QString, expectedHelpOutput);
@@ -614,8 +644,8 @@ void tst_QCommandLineParser::testHelpOption()
"Arguments:\n"
" resize Resize the object to a new size.\n";
#ifdef Q_OS_WIN
- expectedResizeHelp.replace(" -h, --help Displays this help.\n",
- " -?, -h, --help Displays this help.\n");
+ expectedResizeHelp.replace(" -h, --help Displays help on commandline options.\n",
+ " -?, -h, --help Displays help on commandline options.\n");
expectedResizeHelp.replace("testhelper/", "testhelper\\");
#endif
QCOMPARE(output, QString(expectedResizeHelp));
@@ -626,7 +656,7 @@ void tst_QCommandLineParser::testQuoteEscaping()
{
#if !QT_CONFIG(process)
QSKIP("This test requires QProcess support");
-#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#elif defined(Q_OS_ANDROID)
QSKIP("Deploying executable applications to file system on Android not supported.");
#else
QCoreApplication app(empty_argc, empty_argv);
@@ -648,6 +678,112 @@ void tst_QCommandLineParser::testQuoteEscaping()
#endif // QT_CONFIG(process)
}
+void tst_QCommandLineParser::testUnknownOption()
+{
+#if !QT_CONFIG(process)
+ QSKIP("This test requires QProcess support");
+#elif defined(Q_OS_ANDROID)
+ QSKIP("Deploying executable applications to file system on Android not supported.");
+#else
+ QCoreApplication app(empty_argc, empty_argv);
+ QProcess process;
+ process.start("testhelper/qcommandlineparser_test_helper", QStringList() <<
+ QString::number(QCommandLineParser::ParseAsLongOptions) <<
+ "-unknown-option");
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ process.setReadChannel(QProcess::StandardError);
+ QString output = process.readAll();
+ QVERIFY2(output.contains("qcommandlineparser_test_helper"), qPrintable(output)); // separate in case of .exe extension
+ QVERIFY2(output.contains(": Unknown option 'unknown-option'"), qPrintable(output));
+#endif // QT_CONFIG(process)
+}
+
+void tst_QCommandLineParser::testHelpAll_data()
+{
+ QTest::addColumn<QCommandLineParser::SingleDashWordOptionMode>("parsingMode");
+ QTest::addColumn<QString>("expectedHelpOutput");
+
+ QString expectedOutput = QString::fromLatin1(
+ "Usage: testhelper/qcommandlineparser_test_helper [options] parsingMode command\n"
+ "Test helper\n"
+ "\n")
+ + QString::fromLatin1(expectedOptionsHelp) +
+ QString::fromLatin1(
+ " --qmljsdebugger <value> Activates the QML/JS debugger with a specified\n"
+ " port. The value must be of format\n"
+ " port:1234[,block]. \"block\" makes the application\n"
+ " wait for a connection.\n"
+ "\n"
+ "Arguments:\n"
+ " parsingMode The parsing mode to test.\n"
+ " command The command to execute.\n");
+#ifdef Q_OS_WIN
+ expectedOutput.replace(" -h, --help Displays help on commandline options.\n",
+ " -?, -h, --help Displays help on commandline options.\n");
+ expectedOutput.replace("testhelper/", "testhelper\\");
+#endif
+
+ QTest::newRow("collapsed") << QCommandLineParser::ParseAsCompactedShortOptions << expectedOutput;
+ QTest::newRow("long") << QCommandLineParser::ParseAsLongOptions << expectedOutput;
+}
+
+void tst_QCommandLineParser::testHelpAll()
+{
+#if !QT_CONFIG(process)
+ QSKIP("This test requires QProcess support");
+#else
+#ifdef Q_OS_ANDROID
+ QSKIP("Deploying executable applications to file system on Android not supported.");
+#endif
+
+ QFETCH(QCommandLineParser::SingleDashWordOptionMode, parsingMode);
+ QFETCH(QString, expectedHelpOutput);
+ QCoreApplication app(empty_argc, empty_argv);
+ QProcess process;
+ process.start("testhelper/qcommandlineparser_test_helper", QStringList() << QString::number(parsingMode) << "--help-all");
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QString output = process.readAll();
+#ifdef Q_OS_WIN
+ output.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
+#endif
+ QCOMPARE(output.split('\n'), expectedHelpOutput.split('\n')); // easier to debug than the next line, on failure
+ QCOMPARE(output, expectedHelpOutput);
+#endif // QT_CONFIG(process)
+}
+
+void tst_QCommandLineParser::testVeryLongOptionNames()
+{
+#if !QT_CONFIG(process)
+ QSKIP("This test requires QProcess support");
+#elif defined(Q_OS_ANDROID)
+ QSKIP("Deploying executable applications to file system on Android not supported.");
+#else
+
+ QCoreApplication app(empty_argc, empty_argv);
+ QProcess process;
+ process.start("testhelper/qcommandlineparser_test_helper", QStringList() << "0" << "long" << "--help");
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QString output = process.readAll();
+#ifdef Q_OS_WIN
+ output.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
+#endif
+ const QStringList lines = output.split('\n');
+ const int last = lines.size() - 1;
+ // Let's not compare everything, just the final parts.
+ QCOMPARE(lines.at(last - 7), " cdefghijklmnopqrstuvwxyz");
+ QCOMPARE(lines.at(last - 6), " --looooooooooooong-option, --looooong-opt-alias <l Short description");
+ QCOMPARE(lines.at(last - 5), " ooooooooooooong-value-name>");
+ QCOMPARE(lines.at(last - 4), "");
+ QCOMPARE(lines.at(last - 3), "Arguments:");
+ QCOMPARE(lines.at(last - 2), " parsingMode The parsing mode to test.");
+ QCOMPARE(lines.at(last - 1), " command The command to execute.");
+
+#endif // QT_CONFIG(process)
+}
+
QTEST_APPLESS_MAIN(tst_QCommandLineParser)
#include "tst_qcommandlineparser.moc"
diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.pro b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.pro
deleted file mode 100644
index 75b74bbf4d..0000000000
--- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qcommandlineparser
-QT = core testlib
-SOURCES = tst_qcommandlineparser.cpp
diff --git a/tests/auto/corelib/tools/qcontiguouscache/CMakeLists.txt b/tests/auto/corelib/tools/qcontiguouscache/CMakeLists.txt
new file mode 100644
index 0000000000..5c32c34023
--- /dev/null
+++ b/tests/auto/corelib/tools/qcontiguouscache/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcontiguouscache Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcontiguouscache LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qcontiguouscache
+ SOURCES
+ tst_qcontiguouscache.cpp
+)
diff --git a/tests/auto/corelib/tools/qcontiguouscache/qcontiguouscache.pro b/tests/auto/corelib/tools/qcontiguouscache/qcontiguouscache.pro
deleted file mode 100644
index d79bd16c76..0000000000
--- a/tests/auto/corelib/tools/qcontiguouscache/qcontiguouscache.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qcontiguouscache
-QT = core testlib
-SOURCES = tst_qcontiguouscache.cpp
diff --git a/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp b/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp
index 31a5f93822..ca110b1240 100644
--- a/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp
+++ b/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QObject>
#include <QTest>
@@ -68,27 +43,31 @@ void tst_QContiguousCache::assignment()
// copy:
cc1 = cc2;
// move:
- cc1 = qMove(cc2);
+ cc1 = std::move(cc2);
}
void tst_QContiguousCache::empty()
{
QContiguousCache<int> c(10);
QCOMPARE(c.capacity(), 10);
+ QCOMPARE(c.size(), 0);
+ // NOLINTNEXTLINE(qt-port-to-std-compatible-api): Test both size() and count()
QCOMPARE(c.count(), 0);
QVERIFY(c.isEmpty());
c.append(1);
+ // NOLINTNEXTLINE(qt-port-to-std-compatible-api): Test both size() and count()
QCOMPARE(c.count(), 1);
+ QCOMPARE(c.size(), 1);
QVERIFY(!c.isEmpty());
c.clear();
QCOMPARE(c.capacity(), 10);
- QCOMPARE(c.count(), 0);
+ QCOMPARE(c.size(), 0);
QVERIFY(c.isEmpty());
c.prepend(1);
- QCOMPARE(c.count(), 1);
+ QCOMPARE(c.size(), 1);
QVERIFY(!c.isEmpty());
c.clear();
- QCOMPARE(c.count(), 0);
+ QCOMPARE(c.size(), 0);
QVERIFY(c.isEmpty());
QCOMPARE(c.capacity(), 10);
}
@@ -99,32 +78,32 @@ void tst_QContiguousCache::swap()
c1.append(1);
c1.swap(c2);
QCOMPARE(c1.capacity(), 100);
- QCOMPARE(c1.count(), 0 );
+ QCOMPARE(c1.size(), 0 );
QCOMPARE(c2.capacity(), 10 );
- QCOMPARE(c2.count(), 1 );
+ QCOMPARE(c2.size(), 1 );
}
void tst_QContiguousCache::append_data()
{
- QTest::addColumn<int>("start");
- QTest::addColumn<int>("count");
- QTest::addColumn<int>("cacheSize");
+ QTest::addColumn<qsizetype>("start");
+ QTest::addColumn<qsizetype>("count");
+ QTest::addColumn<qsizetype>("cacheSize");
QTest::addColumn<bool>("invalidIndexes");
- QTest::newRow("0+30[10]") << 0 << 30 << 10 << false;
- QTest::newRow("300+30[10]") << 300 << 30 << 10 << false;
- QTest::newRow("MAX-10+30[10]") << INT_MAX-10 << 30 << 10 << true;
+ QTest::newRow("0+30[10]") << qsizetype(0) << qsizetype(30) << qsizetype(10) << false;
+ QTest::newRow("300+30[10]") << qsizetype(300) << qsizetype(30) << qsizetype(10) << false;
+ QTest::newRow("MAX-10+30[10]") << std::numeric_limits<qsizetype>::max()-10 << qsizetype(30) << qsizetype(10) << true;
}
void tst_QContiguousCache::append()
{
- QFETCH(int, start);
- QFETCH(int, count);
- QFETCH(int, cacheSize);
+ QFETCH(qsizetype, start);
+ QFETCH(qsizetype, count);
+ QFETCH(qsizetype, cacheSize);
QFETCH(bool, invalidIndexes);
- int i, j;
- QContiguousCache<int> c(cacheSize);
+ qsizetype i, j;
+ QContiguousCache<qsizetype> c(cacheSize);
i = 1;
QCOMPARE(c.available(), cacheSize);
@@ -134,10 +113,10 @@ void tst_QContiguousCache::append()
c.insert(start, i++);
while (i < count) {
c.append(i);
- QCOMPARE(c.available(), qMax(0, cacheSize - i));
- QCOMPARE(c.first(), qMax(1, i-cacheSize+1));
+ QCOMPARE(c.available(), qMax(qsizetype(0), cacheSize - i));
+ QCOMPARE(c.first(), qMax(qsizetype(1), i-cacheSize+1));
QCOMPARE(c.last(), i);
- QCOMPARE(c.count(), qMin(i, cacheSize));
+ QCOMPARE(c.size(), qMin(i, cacheSize));
QCOMPARE(c.isFull(), i >= cacheSize);
i++;
}
@@ -150,7 +129,7 @@ void tst_QContiguousCache::append()
// test taking from end until empty.
for (j = 0; j < cacheSize; j++, i--) {
QCOMPARE(c.takeLast(), i-1);
- QCOMPARE(c.count(), cacheSize-j-1);
+ QCOMPARE(c.size(), cacheSize-j-1);
QCOMPARE(c.available(), j+1);
QVERIFY(!c.isFull());
QCOMPARE(c.isEmpty(), j==cacheSize-1);
@@ -188,7 +167,7 @@ void tst_QContiguousCache::prepend()
QCOMPARE(c.available(), qMax(0, cacheSize - i));
QCOMPARE(c.last(), qMax(1, i-cacheSize+1));
QCOMPARE(c.first(), i);
- QCOMPARE(c.count(), qMin(i, cacheSize));
+ QCOMPARE(c.size(), qMin(i, cacheSize));
QCOMPARE(c.isFull(), i >= cacheSize);
i++;
}
@@ -201,7 +180,7 @@ void tst_QContiguousCache::prepend()
// test taking from start until empty.
for (j = 0; j < cacheSize; j++, i--) {
QCOMPARE(c.takeFirst(), i-1);
- QCOMPARE(c.count(), cacheSize-j-1);
+ QCOMPARE(c.size(), cacheSize-j-1);
QCOMPARE(c.available(), j+1);
QVERIFY(!c.isFull());
QCOMPARE(c.isEmpty(), j==cacheSize-1);
@@ -244,7 +223,7 @@ public:
return *this;
}
- int refCount() const { return d->ref.load(); }
+ int refCount() const { return d->ref.loadRelaxed(); }
private:
RefCountingClassData *d;
};
@@ -321,7 +300,7 @@ void tst_QContiguousCache::setCapacity()
for (i = 280; i < 310; ++i)
contiguousCache.insert(i, i);
QCOMPARE(contiguousCache.capacity(), 100);
- QCOMPARE(contiguousCache.count(), 30);
+ QCOMPARE(contiguousCache.size(), 30);
QCOMPARE(contiguousCache.firstIndex(), 280);
QCOMPARE(contiguousCache.lastIndex(), 309);
@@ -333,7 +312,7 @@ void tst_QContiguousCache::setCapacity()
contiguousCache.setCapacity(150);
QCOMPARE(contiguousCache.capacity(), 150);
- QCOMPARE(contiguousCache.count(), 30);
+ QCOMPARE(contiguousCache.size(), 30);
QCOMPARE(contiguousCache.firstIndex(), 280);
QCOMPARE(contiguousCache.lastIndex(), 309);
@@ -345,7 +324,7 @@ void tst_QContiguousCache::setCapacity()
contiguousCache.setCapacity(20);
QCOMPARE(contiguousCache.capacity(), 20);
- QCOMPARE(contiguousCache.count(), 20);
+ QCOMPARE(contiguousCache.size(), 20);
QCOMPARE(contiguousCache.firstIndex(), 290);
QCOMPARE(contiguousCache.lastIndex(), 309);
diff --git a/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt b/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt
new file mode 100644
index 0000000000..8a0c08fcad
--- /dev/null
+++ b/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qcryptographichash Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcryptographichash LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+# Collect test data
+file(GLOB_RECURSE test_data_glob
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ data/*)
+list(APPEND test_data ${test_data_glob})
+
+qt_internal_add_test(tst_qcryptographichash
+ SOURCES
+ tst_qcryptographichash.cpp
+ TESTDATA ${test_data}
+)
+
+if(QT_FEATURE_sanitize_address)
+ set_property(TEST tst_qcryptographichash APPEND PROPERTY ENVIRONMENT "QTEST_FUNCTION_TIMEOUT=900000")
+endif()
diff --git a/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro b/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro
deleted file mode 100644
index 8d3957a524..0000000000
--- a/tests/auto/corelib/tools/qcryptographichash/qcryptographichash.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qcryptographichash
-QT = core testlib
-SOURCES = tst_qcryptographichash.cpp
-
-TESTDATA += data/*
-
-android:!android-embedded {
- RESOURCES += \
- testdata.qrc
-}
diff --git a/tests/auto/corelib/tools/qcryptographichash/testdata.qrc b/tests/auto/corelib/tools/qcryptographichash/testdata.qrc
deleted file mode 100644
index 8f7bcea63c..0000000000
--- a/tests/auto/corelib/tools/qcryptographichash/testdata.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>data/2c1517dad3678f03917f15849b052fd5.md5</file>
- <file>data/d41d8cd98f00b204e9800998ecf8427e.md5</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
index 3eef7631c8..c08afd67c4 100644
--- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
+++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
@@ -1,36 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QScopeGuard>
+#include <QCryptographicHash>
#include <QtCore/QMetaEnum>
+#include <thread>
+
Q_DECLARE_METATYPE(QCryptographicHash::Algorithm)
class tst_QCryptographicHash : public QObject
@@ -44,9 +23,25 @@ private slots:
void sha1();
void sha3_data();
void sha3();
+ void keccak();
+ void keccak_data();
+ void blake2_data();
+ void blake2();
void files_data();
void files();
+ void hashLength_data();
void hashLength();
+ void addDataAcceptsNullByteArrayView_data() { hashLength_data(); }
+ void addDataAcceptsNullByteArrayView();
+ void move();
+ void swap();
+ // keep last
+ void moreThan4GiBOfData_data();
+ void moreThan4GiBOfData();
+ void keccakBufferOverflow();
+private:
+ void ensureLargeData();
+ std::vector<char> large;
};
void tst_QCryptographicHash::repeated_result_data()
@@ -60,19 +55,23 @@ void tst_QCryptographicHash::repeated_result()
QCryptographicHash::Algorithm _algo = QCryptographicHash::Algorithm(algo);
QCryptographicHash hash(_algo);
+ QCOMPARE_EQ(hash.algorithm(), _algo);
+
QFETCH(QByteArray, first);
hash.addData(first);
QFETCH(QByteArray, hash_first);
- QByteArray result = hash.result();
+ QByteArrayView result = hash.resultView();
QCOMPARE(result, hash_first);
+ QCOMPARE(result, hash.resultView());
QCOMPARE(result, hash.result());
hash.reset();
hash.addData(first);
- result = hash.result();
+ result = hash.resultView();
QCOMPARE(result, hash_first);
QCOMPARE(result, hash.result());
+ QCOMPARE(result, hash.resultView());
}
void tst_QCryptographicHash::intermediary_result_data()
@@ -153,6 +152,27 @@ void tst_QCryptographicHash::intermediary_result_data()
<< QByteArray("abc") << QByteArray("abc")
<< QByteArray::fromHex("B751850B1A57168A5693CD924B6B096E08F621827444F70D884F5D0240D2712E10E116E9192AF3C91A7EC57647E3934057340B4CF408D5A56592F8274EEC53F0")
<< QByteArray::fromHex("BB582DA40D15399ACF62AFCBBD6CFC9EE1DD5129B1EF9935DD3B21668F1A73D7841018BE3B13F281C3A8E9DA7EDB60F57B9F9F1C04033DF4CE3654B7B2ADB310");
+
+ QTest::newRow("keccak_224_abc_abc")
+ << int(QCryptographicHash::Keccak_224)
+ << QByteArray("abc") << QByteArray("abc")
+ << QByteArray::fromHex("c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8")
+ << QByteArray::fromHex("048330e7c7c8b4a41ab713b3a6f958d77b8cf3ee969930f1584dd550");
+ QTest::newRow("keccak_256_abc_abc")
+ << int(QCryptographicHash::Keccak_256)
+ << QByteArray("abc") << QByteArray("abc")
+ << QByteArray::fromHex("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
+ << QByteArray::fromHex("9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21");
+ QTest::newRow("keccak_384_abc_abc")
+ << int(QCryptographicHash::Keccak_384)
+ << QByteArray("abc") << QByteArray("abc")
+ << QByteArray::fromHex("f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e")
+ << QByteArray::fromHex("d733b87d392d270889d3da23ae113f349e25574b445f319cde4cd3f877c753e9e3c65980421339b3a131457ff393939f");
+ QTest::newRow("keccak_512_abc_abc")
+ << int(QCryptographicHash::Keccak_512)
+ << QByteArray("abc") << QByteArray("abc")
+ << QByteArray::fromHex("18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96")
+ << QByteArray::fromHex("a7c392d2a42155761ca76bddde1c47d55486b007edf465397bfb9dfa74d11c8f0d7c86cd29415283f1b5e7f655cec25b869c9e9c33a8986f0b38542fb12bfb93");
}
void tst_QCryptographicHash::intermediary_result()
@@ -165,16 +185,14 @@ void tst_QCryptographicHash::intermediary_result()
hash.addData(first);
QFETCH(QByteArray, hash_first);
- QByteArray result = hash.result();
- QCOMPARE(result, hash_first);
+ QCOMPARE(hash.resultView(), hash_first);
// don't reset
QFETCH(QByteArray, second);
QFETCH(QByteArray, hash_firstsecond);
hash.addData(second);
- result = hash.result();
- QCOMPARE(result, hash_firstsecond);
+ QCOMPARE(hash.resultView(), hash_firstsecond);
hash.reset();
}
@@ -195,10 +213,7 @@ void tst_QCryptographicHash::sha1()
// SHA1(A million repetitions of "a") =
// 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
- QByteArray as;
- for (int i = 0; i < 1000000; ++i)
- as += 'a';
- QCOMPARE(QCryptographicHash::hash(as, QCryptographicHash::Sha1).toHex().toUpper(),
+ QCOMPARE(QCryptographicHash::hash(QByteArray(1'000'000, 'a'), QCryptographicHash::Sha1).toHex().toUpper(),
QByteArray("34AA973CD4C4DAA4F61EEB2BDBAD27316534016F"));
}
@@ -264,6 +279,172 @@ void tst_QCryptographicHash::sha3()
QCOMPARE(result, expectedResult);
}
+void tst_QCryptographicHash::keccak_data()
+{
+ QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+#define ROW(Tag, Algorithm, Input, Result) \
+ QTest::newRow(Tag) << Algorithm << QByteArrayLiteral(Input) << QByteArray::fromHex(Result)
+
+ ROW("keccak_224_pangram",
+ QCryptographicHash::Keccak_224,
+ "The quick brown fox jumps over the lazy dog",
+ "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe");
+
+ ROW("keccak_224_pangram_dot",
+ QCryptographicHash::Keccak_224,
+ "The quick brown fox jumps over the lazy dog.",
+ "c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab");
+
+ ROW("keccak_256_pangram",
+ QCryptographicHash::Keccak_256,
+ "The quick brown fox jumps over the lazy dog",
+ "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15");
+
+ ROW("keccak_256_pangram_dot",
+ QCryptographicHash::Keccak_256,
+ "The quick brown fox jumps over the lazy dog.",
+ "578951e24efd62a3d63a86f7cd19aaa53c898fe287d2552133220370240b572d");
+
+ ROW("keccak_384_pangram",
+ QCryptographicHash::Keccak_384,
+ "The quick brown fox jumps over the lazy dog",
+ "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3");
+
+ ROW("keccak_384_pangram_dot",
+ QCryptographicHash::Keccak_384,
+ "The quick brown fox jumps over the lazy dog.",
+ "9ad8e17325408eddb6edee6147f13856ad819bb7532668b605a24a2d958f88bd5c169e56dc4b2f89ffd325f6006d820b");
+
+ ROW("skeccak_512_pangram",
+ QCryptographicHash::Keccak_512,
+ "The quick brown fox jumps over the lazy dog",
+ "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609");
+
+ ROW("keccak_512_pangram_dot",
+ QCryptographicHash::Keccak_512,
+ "The quick brown fox jumps over the lazy dog.",
+ "ab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760");
+
+#undef ROW
+}
+
+void tst_QCryptographicHash::keccak()
+{
+ QFETCH(QCryptographicHash::Algorithm, algorithm);
+ QFETCH(QByteArray, data);
+ QFETCH(QByteArray, expectedResult);
+
+ const auto result = QCryptographicHash::hash(data, algorithm);
+ QCOMPARE(result, expectedResult);
+}
+
+void tst_QCryptographicHash::blake2_data()
+{
+ QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+#define ROW(Tag, Algorithm, Input, Result) \
+ QTest::newRow(Tag) << Algorithm << QByteArrayLiteral(Input) << QByteArray::fromHex(Result)
+
+ // BLAKE2b
+ ROW("blake2b_160_pangram",
+ QCryptographicHash::Blake2b_160,
+ "The quick brown fox jumps over the lazy dog",
+ "3c523ed102ab45a37d54f5610d5a983162fde84f");
+
+ ROW("blake2b_160_pangram_dot",
+ QCryptographicHash::Blake2b_160,
+ "The quick brown fox jumps over the lazy dog.",
+ "d0c8bb0bdd830296d1d4f4348176699ccccc16bb");
+
+ ROW("blake2b_256_pangram",
+ QCryptographicHash::Blake2b_256,
+ "The quick brown fox jumps over the lazy dog",
+ "01718cec35cd3d796dd00020e0bfecb473ad23457d063b75eff29c0ffa2e58a9");
+
+ ROW("blake2b_256_pangram_dot",
+ QCryptographicHash::Blake2b_256,
+ "The quick brown fox jumps over the lazy dog.",
+ "69d7d3b0afba81826d27024c17f7f183659ed0812cf27b382eaef9fdc29b5712");
+
+ ROW("blake2b_384_pangram",
+ QCryptographicHash::Blake2b_384,
+ "The quick brown fox jumps over the lazy dog",
+ "b7c81b228b6bd912930e8f0b5387989691c1cee1e65aade4da3b86a3c9f678fc8018f6ed9e2906720c8d2a3aeda9c03d");
+
+ ROW("blake2b_384_pangram_dot",
+ QCryptographicHash::Blake2b_384,
+ "The quick brown fox jumps over the lazy dog.",
+ "16d65de1a3caf1c26247234c39af636284c7e19ca448c0de788272081410778852c94d9cef6b939968d4f872c7f78337");
+
+ ROW("blake2b_512_pangram",
+ QCryptographicHash::Blake2b_512,
+ "The quick brown fox jumps over the lazy dog",
+ "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918");
+
+ ROW("blake2b_512_pangram_dot",
+ QCryptographicHash::Blake2b_512,
+ "The quick brown fox jumps over the lazy dog.",
+ "87af9dc4afe5651b7aa89124b905fd214bf17c79af58610db86a0fb1e0194622a4e9d8e395b352223a8183b0d421c0994b98286cbf8c68a495902e0fe6e2bda2");
+
+ // BLAKE2s
+ ROW("blake2s_128_pangram",
+ QCryptographicHash::Blake2s_128,
+ "The quick brown fox jumps over the lazy dog",
+ "96fd07258925748a0d2fb1c8a1167a73");
+
+ ROW("blake2s_128_pangram_dot",
+ QCryptographicHash::Blake2s_128,
+ "The quick brown fox jumps over the lazy dog.",
+ "1f298f2e1f9c2490e506c2308f64e7c0");
+
+ ROW("blake2s_160_pangram",
+ QCryptographicHash::Blake2s_160,
+ "The quick brown fox jumps over the lazy dog",
+ "5a604fec9713c369e84b0ed68daed7d7504ef240");
+
+ ROW("blake2s_160_pangram_dot",
+ QCryptographicHash::Blake2s_160,
+ "The quick brown fox jumps over the lazy dog.",
+ "cd4a863226463aac852662d16275d399966e3ffe");
+
+ ROW("blake2s_224_pangram",
+ QCryptographicHash::Blake2s_224,
+ "The quick brown fox jumps over the lazy dog",
+ "e4e5cb6c7cae41982b397bf7b7d2d9d1949823ae78435326e8db4912");
+
+ ROW("blake2s_224_pangram_dot",
+ QCryptographicHash::Blake2s_224,
+ "The quick brown fox jumps over the lazy dog.",
+ "fd1557500ef49f308882969507acd18a13e155c26f8fcd82f9bf2ff7");
+
+ ROW("blake2s_256_pangram",
+ QCryptographicHash::Blake2s_256,
+ "The quick brown fox jumps over the lazy dog",
+ "606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812");
+
+ ROW("blake2s_256_pangram_dot",
+ QCryptographicHash::Blake2s_256,
+ "The quick brown fox jumps over the lazy dog.",
+ "95bca6e1b761dca1323505cc629949a0e03edf11633cc7935bd8b56f393afcf2");
+
+#undef ROW
+}
+
+void tst_QCryptographicHash::blake2()
+{
+ QFETCH(QCryptographicHash::Algorithm, algorithm);
+ QFETCH(QByteArray, data);
+ QFETCH(QByteArray, expectedResult);
+
+ const auto result = QCryptographicHash::hash(data, algorithm);
+ QCOMPARE(result, expectedResult);
+}
+
void tst_QCryptographicHash::files_data() {
QTest::addColumn<QString>("filename");
QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
@@ -293,14 +474,192 @@ void tst_QCryptographicHash::files()
}
}
-void tst_QCryptographicHash::hashLength()
+void tst_QCryptographicHash::hashLength_data()
{
+ QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
auto metaEnum = QMetaEnum::fromType<QCryptographicHash::Algorithm>();
for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) {
auto algorithm = QCryptographicHash::Algorithm(value);
- QByteArray output = QCryptographicHash::hash(QByteArrayLiteral("test"), algorithm);
- QCOMPARE(QCryptographicHash::hashLength(algorithm), output.length());
+ QTest::addRow("%s", metaEnum.key(i)) << algorithm;
+ }
+}
+
+void tst_QCryptographicHash::hashLength()
+{
+ QFETCH(const QCryptographicHash::Algorithm, algorithm);
+
+ qsizetype expectedSize;
+ if (algorithm == QCryptographicHash::NumAlgorithms) {
+ // It's UB to call ::hash() with NumAlgorithms, but hashLength() is
+ // fine and returns 0 for invalid values:
+ expectedSize = 0;
+ } else {
+ expectedSize = QCryptographicHash::hash("test", algorithm).size();
+ }
+ QCOMPARE(QCryptographicHash::hashLength(algorithm), expectedSize);
+}
+
+void tst_QCryptographicHash::addDataAcceptsNullByteArrayView()
+{
+ QFETCH(const QCryptographicHash::Algorithm, algorithm);
+
+ if (!QCryptographicHash::supportsAlgorithm(algorithm))
+ QSKIP("QCryptographicHash doesn't support this algorithm");
+
+ QCryptographicHash hash1(algorithm);
+ hash1.addData("meep");
+ hash1.addData(QByteArrayView{}); // after other data
+
+ QCryptographicHash hash2(algorithm);
+ hash2.addData(QByteArrayView{}); // before any other data
+ hash2.addData("meep");
+
+ const auto expected = QCryptographicHash::hash("meep", algorithm);
+
+ QCOMPARE(hash1.resultView(), expected);
+ QCOMPARE(hash2.resultView(), expected);
+}
+
+void tst_QCryptographicHash::move()
+{
+ QCryptographicHash hash1(QCryptographicHash::Sha1);
+ hash1.addData("a");
+
+ // move constructor
+ auto hash2(std::move(hash1));
+ hash2.addData("b");
+
+ // move assign operator
+ QCryptographicHash hash3(QCryptographicHash::Sha256);
+ hash3.addData("no effect on the end result");
+ hash3 = std::move(hash2);
+ hash3.addData("c");
+
+ QCOMPARE(hash3.resultView(), QByteArray::fromHex("A9993E364706816ABA3E25717850C26C9CD0D89D"));
+}
+
+void tst_QCryptographicHash::swap()
+{
+ QCryptographicHash hash1(QCryptographicHash::Sha1);
+ QCryptographicHash hash2(QCryptographicHash::Sha256);
+
+ hash1.addData("da");
+ hash2.addData("te");
+
+ hash1.swap(hash2);
+
+ hash2.addData("ta");
+ hash1.addData("st");
+
+ QCOMPARE(hash2.result(), QCryptographicHash::hash("data", QCryptographicHash::Sha1));
+ QCOMPARE(hash1.result(), QCryptographicHash::hash("test", QCryptographicHash::Sha256));
+}
+
+void tst_QCryptographicHash::ensureLargeData()
+{
+#if QT_POINTER_SIZE > 4
+ QElapsedTimer timer;
+ timer.start();
+ const size_t GiB = 1024 * 1024 * 1024;
+ if (large.size() == 4 * GiB + 1)
+ return;
+ try {
+ large.resize(4 * GiB + 1, '\0');
+ } catch (const std::bad_alloc &) {
+ QSKIP("Could not allocate 4GiB plus one byte of RAM.");
+ }
+ QCOMPARE(large.size(), 4 * GiB + 1);
+ large.back() = '\1';
+ qDebug("created dataset in %lld ms", timer.elapsed());
+#endif
+}
+
+void tst_QCryptographicHash::moreThan4GiBOfData_data()
+{
+#if QT_POINTER_SIZE > 4
+ if (ensureLargeData(); large.empty())
+ return;
+ QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
+ auto me = QMetaEnum::fromType<QCryptographicHash::Algorithm>();
+ auto row = [me] (QCryptographicHash::Algorithm algo) {
+ QTest::addRow("%s", me.valueToKey(int(algo))) << algo;
+ };
+ // these are reasonably fast (O(secs))
+ row(QCryptographicHash::Md4);
+ row(QCryptographicHash::Md5);
+ row(QCryptographicHash::Sha1);
+ if (!qgetenv("QTEST_ENVIRONMENT").split(' ').contains("ci")) {
+ // This is important but so slow (O(minute)) that, on CI, it tends to time out.
+ // Retain it for manual runs, all the same, as most dev machines will be fast enough.
+ row(QCryptographicHash::Sha512);
+ }
+ // the rest is just too slow
+#else
+ QSKIP("This test is 64-bit only.");
+#endif
+}
+
+void tst_QCryptographicHash::moreThan4GiBOfData()
+{
+ QFETCH(const QCryptographicHash::Algorithm, algorithm);
+
+ using MaybeThread = std::thread;
+
+ QElapsedTimer timer;
+ timer.start();
+ const auto sg = qScopeGuard([&] {
+ qDebug() << algorithm << "test finished in" << timer.restart() << "ms";
+ });
+
+ const auto view = QByteArrayView{large};
+ const auto first = view.first(view.size() / 2);
+ const auto last = view.sliced(view.size() / 2);
+
+ QByteArray single;
+ QByteArray chunked;
+
+ auto t = MaybeThread{[&] {
+ QCryptographicHash h(algorithm);
+ h.addData(view);
+ single = h.result();
+ }};
+ {
+ QCryptographicHash h(algorithm);
+ h.addData(first);
+ h.addData(last);
+ chunked = h.result();
}
+ t.join();
+
+ QCOMPARE(single, chunked);
+}
+
+void tst_QCryptographicHash::keccakBufferOverflow()
+{
+#if QT_POINTER_SIZE == 4
+ QSKIP("This is a 64-bit-only test");
+#else
+
+ if (ensureLargeData(); large.empty())
+ return;
+
+ QElapsedTimer timer;
+ timer.start();
+ const auto sg = qScopeGuard([&] {
+ qDebug() << "test finished in" << timer.restart() << "ms";
+ });
+
+ constexpr qsizetype magic = INT_MAX/4;
+ QCOMPARE_GE(large.size(), size_t(magic + 1));
+
+ QCryptographicHash hash(QCryptographicHash::Algorithm::Keccak_224);
+ const auto first = QByteArrayView{large}.first(1);
+ const auto second = QByteArrayView{large}.sliced(1, magic);
+ hash.addData(first);
+ hash.addData(second);
+ (void)hash.resultView();
+ QVERIFY(true); // didn't crash
+#endif
}
QTEST_MAIN(tst_QCryptographicHash)
diff --git a/tests/auto/corelib/tools/qdate/qdate.pro b/tests/auto/corelib/tools/qdate/qdate.pro
deleted file mode 100644
index dd7c6cb888..0000000000
--- a/tests/auto/corelib/tools/qdate/qdate.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdate
-QT = core testlib
-SOURCES = tst_qdate.cpp
diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp
deleted file mode 100644
index ce1e5730dd..0000000000
--- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp
+++ /dev/null
@@ -1,1505 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qdatetime.h>
-#include <qlocale.h>
-
-class tst_QDate : public QObject
-{
- Q_OBJECT
-private slots:
- void isNull_data();
- void isNull();
- void isValid_data();
- void isValid();
- void julianDay_data();
- void julianDay();
- void dayOfWeek_data();
- void dayOfWeek();
- void dayOfYear_data();
- void dayOfYear();
- void daysInMonth_data();
- void daysInMonth();
- void daysInYear_data();
- void daysInYear();
- void getDate();
- void weekNumber_invalid_data();
- void weekNumber_invalid();
- void weekNumber_data();
- void weekNumber();
- void julianDaysLimits();
- void addDays_data();
- void addDays();
- void addMonths_data();
- void addMonths();
- void addYears_data();
- void addYears();
- void daysTo();
- void operator_eq_eq_data();
- void operator_eq_eq();
- void operator_lt();
- void operator_gt();
- void operator_lt_eq();
- void operator_gt_eq();
- void operator_insert_extract_data();
- void operator_insert_extract();
- void fromStringDateFormat_data();
- void fromStringDateFormat();
- void fromStringFormat_data();
- void fromStringFormat();
- void toStringFormat_data();
- void toStringFormat();
- void toStringDateFormat_data();
- void toStringDateFormat();
- void isLeapYear();
- void yearsZeroToNinetyNine();
- void negativeYear() const;
- void printNegativeYear() const;
- void roundtripGermanLocale() const;
- void shortDayName() const;
- void standaloneShortDayName() const;
- void longDayName() const;
- void standaloneLongDayName() const;
- void shortMonthName() const;
- void standaloneShortMonthName() const;
- void longMonthName() const;
- void standaloneLongMonthName() const;
- void roundtrip() const;
- void qdebug() const;
-private:
- QDate defDate() const { return QDate(1900, 1, 1); }
- QDate invalidDate() const { return QDate(); }
-};
-
-Q_DECLARE_METATYPE(Qt::DateFormat)
-
-void tst_QDate::isNull_data()
-{
- QTest::addColumn<qint64>("jd");
- QTest::addColumn<bool>("null");
-
- qint64 minJd = Q_INT64_C(-784350574879);
- qint64 maxJd = Q_INT64_C( 784354017364);
-
- QTest::newRow("qint64 min") << std::numeric_limits<qint64>::min() << true;
- QTest::newRow("minJd - 1") << minJd - 1 << true;
- QTest::newRow("minJd") << minJd << false;
- QTest::newRow("minJd + 1") << minJd + 1 << false;
- QTest::newRow("maxJd - 1") << maxJd - 1 << false;
- QTest::newRow("maxJd") << maxJd << false;
- QTest::newRow("maxJd + 1") << maxJd + 1 << true;
- QTest::newRow("qint64 max") << std::numeric_limits<qint64>::max() << true;
-}
-
-void tst_QDate::isNull()
-{
- QFETCH(qint64, jd);
-
- QDate d = QDate::fromJulianDay(jd);
- QTEST(d.isNull(), "null");
-}
-
-void tst_QDate::isValid_data()
-{
- qint64 nullJd = std::numeric_limits<qint64>::min();
-
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<qint64>("jd");
- QTest::addColumn<bool>("valid");
-
- QTest::newRow("0-0-0") << 0 << 0 << 0 << nullJd << false;
- QTest::newRow("month 0") << 2000 << 0 << 1 << nullJd << false;
- QTest::newRow("day 0") << 2000 << 1 << 0 << nullJd << false;
-
- QTest::newRow("month 13") << 2000 << 13 << 1 << nullJd << false;
-
- // test leap years
- QTest::newRow("non-leap") << 2006 << 2 << 29 << nullJd << false;
- QTest::newRow("normal leap") << 2004 << 2 << 29 << qint64(2453065) << true;
- QTest::newRow("century leap 1900") << 1900 << 2 << 29 << nullJd << false;
- QTest::newRow("century leap 2100") << 2100 << 2 << 29 << nullJd << false;
- QTest::newRow("400-years leap 2000") << 2000 << 2 << 29 << qint64(2451604) << true;
- QTest::newRow("400-years leap 2400") << 2400 << 2 << 29 << qint64(2597701) << true;
- QTest::newRow("400-years leap 1600") << 1600 << 2 << 29 << qint64(2305507) << true;
- QTest::newRow("year 0") << 0 << 2 << 27 << nullJd << false;
-
- // Test end of four-digit years:
- QTest::newRow("late") << 9999 << 12 << 31 << qint64(5373484) << true;
-
- // test the number of days in months:
- QTest::newRow("jan") << 2000 << 1 << 31 << qint64(2451575) << true;
- QTest::newRow("feb") << 2000 << 2 << 29 << qint64(2451604) << true; // same data as 400-years leap
- QTest::newRow("mar") << 2000 << 3 << 31 << qint64(2451635) << true;
- QTest::newRow("apr") << 2000 << 4 << 30 << qint64(2451665) << true;
- QTest::newRow("may") << 2000 << 5 << 31 << qint64(2451696) << true;
- QTest::newRow("jun") << 2000 << 6 << 30 << qint64(2451726) << true;
- QTest::newRow("jul") << 2000 << 7 << 31 << qint64(2451757) << true;
- QTest::newRow("aug") << 2000 << 8 << 31 << qint64(2451788) << true;
- QTest::newRow("sep") << 2000 << 9 << 30 << qint64(2451818) << true;
- QTest::newRow("oct") << 2000 << 10 << 31 << qint64(2451849) << true;
- QTest::newRow("nov") << 2000 << 11 << 30 << qint64(2451879) << true;
- QTest::newRow("dec") << 2000 << 12 << 31 << qint64(2451910) << true;
-
- // and invalid dates:
- QTest::newRow("ijan") << 2000 << 1 << 32 << nullJd << false;
- QTest::newRow("ifeb") << 2000 << 2 << 30 << nullJd << false;
- QTest::newRow("imar") << 2000 << 3 << 32 << nullJd << false;
- QTest::newRow("iapr") << 2000 << 4 << 31 << nullJd << false;
- QTest::newRow("imay") << 2000 << 5 << 32 << nullJd << false;
- QTest::newRow("ijun") << 2000 << 6 << 31 << nullJd << false;
- QTest::newRow("ijul") << 2000 << 7 << 32 << nullJd << false;
- QTest::newRow("iaug") << 2000 << 8 << 32 << nullJd << false;
- QTest::newRow("isep") << 2000 << 9 << 31 << nullJd << false;
- QTest::newRow("ioct") << 2000 << 10 << 32 << nullJd << false;
- QTest::newRow("inov") << 2000 << 11 << 31 << nullJd << false;
- QTest::newRow("idec") << 2000 << 12 << 32 << nullJd << false;
-
- // the beginning of the Julian Day calendar:
- QTest::newRow("jd earliest formula") << -4800 << 1 << 1 << qint64( -31738) << true;
- QTest::newRow("jd -1") << -4714 << 11 << 23 << qint64( -1) << true;
- QTest::newRow("jd 0") << -4714 << 11 << 24 << qint64( 0) << true;
- QTest::newRow("jd 1") << -4714 << 11 << 25 << qint64( 1) << true;
- QTest::newRow("jd latest formula") << 1400000 << 12 << 31 << qint64(513060925) << true;
-}
-
-void tst_QDate::isValid()
-{
- QFETCH(int, year);
- QFETCH(int, month);
- QFETCH(int, day);
- QFETCH(qint64, jd);
- QFETCH(bool, valid);
-
- QCOMPARE(QDate::isValid(year, month, day), valid);
-
- QDate d;
- d.setDate(year, month, day);
- QCOMPARE(d.isValid(), valid);
- QCOMPARE(d.toJulianDay(), jd);
-
- if (valid) {
- QCOMPARE(d.year(), year);
- QCOMPARE(d.month(), month);
- QCOMPARE(d.day(), day);
- } else {
- QCOMPARE(d.year(), 0);
- QCOMPARE(d.month(), 0);
- QCOMPARE(d.day(), 0);
- }
-}
-
-void tst_QDate::julianDay_data()
-{
- isValid_data();
-}
-
-void tst_QDate::julianDay()
-{
- QFETCH(int, year);
- QFETCH(int, month);
- QFETCH(int, day);
- QFETCH(qint64, jd);
-
- {
- QDate d;
- d.setDate(year, month, day);
- QCOMPARE(d.toJulianDay(), jd);
- }
-
- if (jd != std::numeric_limits<qint64>::min()) {
- QDate d = QDate::fromJulianDay(jd);
- QCOMPARE(d.year(), year);
- QCOMPARE(d.month(), month);
- QCOMPARE(d.day(), day);
- }
-}
-
-void tst_QDate::dayOfWeek_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<int>("dayOfWeek");
-
- QTest::newRow("data0") << 0 << 0 << 0 << 0;
- QTest::newRow("data1") << 2000 << 1 << 3 << 1;
- QTest::newRow("data2") << 2000 << 1 << 4 << 2;
- QTest::newRow("data3") << 2000 << 1 << 5 << 3;
- QTest::newRow("data4") << 2000 << 1 << 6 << 4;
- QTest::newRow("data5") << 2000 << 1 << 7 << 5;
- QTest::newRow("data6") << 2000 << 1 << 8 << 6;
- QTest::newRow("data7") << 2000 << 1 << 9 << 7;
- QTest::newRow("data8") << -4800 << 1 << 1 << 1;
- QTest::newRow("data9") << -4800 << 1 << 2 << 2;
- QTest::newRow("data10") << -4800 << 1 << 3 << 3;
- QTest::newRow("data11") << -4800 << 1 << 4 << 4;
- QTest::newRow("data12") << -4800 << 1 << 5 << 5;
- QTest::newRow("data13") << -4800 << 1 << 6 << 6;
- QTest::newRow("data14") << -4800 << 1 << 7 << 7;
- QTest::newRow("data15") << -4800 << 1 << 8 << 1;
-}
-
-void tst_QDate::dayOfWeek()
-{
- QFETCH(int, year);
- QFETCH(int, month);
- QFETCH(int, day);
- QFETCH(int, dayOfWeek);
-
- QDate dt(year, month, day);
- QCOMPARE(dt.dayOfWeek(), dayOfWeek);
-}
-
-void tst_QDate::dayOfYear_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<int>("dayOfYear");
-
- QTest::newRow("data0") << 0 << 0 << 0 << 0;
- QTest::newRow("data1") << 2000 << 1 << 1 << 1;
- QTest::newRow("data2") << 2000 << 1 << 2 << 2;
- QTest::newRow("data3") << 2000 << 1 << 3 << 3;
- QTest::newRow("data4") << 2000 << 12 << 31 << 366;
- QTest::newRow("data5") << 2001 << 12 << 31 << 365;
- QTest::newRow("data6") << 1815 << 1 << 1 << 1;
- QTest::newRow("data7") << 1815 << 12 << 31 << 365;
- QTest::newRow("data8") << 1500 << 1 << 1 << 1;
- QTest::newRow("data9") << 1500 << 12 << 31 << 365;
- QTest::newRow("data10") << -1500 << 1 << 1 << 1;
- QTest::newRow("data11") << -1500 << 12 << 31 << 365;
- QTest::newRow("data12") << -4800 << 1 << 1 << 1;
- QTest::newRow("data13") << -4800 << 12 << 31 << 365;
-}
-
-void tst_QDate::dayOfYear()
-{
- QFETCH(int, year);
- QFETCH(int, month);
- QFETCH(int, day);
- QFETCH(int, dayOfYear);
-
- QDate dt(year, month, day);
- QCOMPARE(dt.dayOfYear(), dayOfYear);
-}
-
-void tst_QDate::daysInMonth_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<int>("daysInMonth");
-
- QTest::newRow("data0") << 0 << 0 << 0 << 0;
- QTest::newRow("data1") << 2000 << 1 << 1 << 31;
- QTest::newRow("data2") << 2000 << 2 << 1 << 29;
- QTest::newRow("data3") << 2000 << 3 << 1 << 31;
- QTest::newRow("data4") << 2000 << 4 << 1 << 30;
- QTest::newRow("data5") << 2000 << 5 << 1 << 31;
- QTest::newRow("data6") << 2000 << 6 << 1 << 30;
- QTest::newRow("data7") << 2000 << 7 << 1 << 31;
- QTest::newRow("data8") << 2000 << 8 << 1 << 31;
- QTest::newRow("data9") << 2000 << 9 << 1 << 30;
- QTest::newRow("data10") << 2000 << 10 << 1 << 31;
- QTest::newRow("data11") << 2000 << 11 << 1 << 30;
- QTest::newRow("data12") << 2000 << 12 << 1 << 31;
- QTest::newRow("data13") << 2001 << 2 << 1 << 28;
- QTest::newRow("data14") << 2000 << 0 << 1 << 0;
-}
-
-void tst_QDate::daysInMonth()
-{
- QFETCH(int, year);
- QFETCH(int, month);
- QFETCH(int, day);
- QFETCH(int, daysInMonth);
-
- QDate dt(year, month, day);
- QCOMPARE(dt.daysInMonth(), daysInMonth);
-}
-
-void tst_QDate::daysInYear_data()
-{
- QTest::addColumn<QDate>("date");
- QTest::addColumn<int>("expectedDaysInYear");
-
- QTest::newRow("2000, 1, 1") << QDate(2000, 1, 1) << 366;
- QTest::newRow("2001, 1, 1") << QDate(2001, 1, 1) << 365;
- QTest::newRow("4, 1, 1") << QDate(4, 1, 1) << 366;
- QTest::newRow("5, 1, 1") << QDate(5, 1, 1) << 365;
- QTest::newRow("0, 0, 0") << QDate(0, 0, 0) << 0;
-}
-
-void tst_QDate::daysInYear()
-{
- QFETCH(QDate, date);
- QFETCH(int, expectedDaysInYear);
-
- QCOMPARE(date.daysInYear(), expectedDaysInYear);
-}
-
-void tst_QDate::getDate()
-{
- int y, m, d;
- QDate dt(2000, 1, 1);
- dt.getDate(&y, &m, &d);
- QCOMPARE(y, 2000);
- QCOMPARE(m, 1);
- QCOMPARE(d, 1);
- dt.setDate(0, 0, 0);
- dt.getDate(&y, &m, &d);
- QCOMPARE(y, 0);
- QCOMPARE(m, 0);
- QCOMPARE(d, 0);
-}
-
-void tst_QDate::weekNumber_data()
-{
- QTest::addColumn<int>("expectedWeekNum");
- QTest::addColumn<int>("expectedYearNum");
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
-
- enum { Thursday = 4 };
- bool wasLastYearLong = false; // 1999 was not a long (53-week) year
- bool isLongYear;
-
- // full 400-year cycle for Jan 1, 4 and Dec 28, 31
- for (int yr = 2000; yr < 2400; ++yr, wasLastYearLong = isLongYear) {
- QByteArray yrstr = QByteArray::number(yr);
- int wday = QDate(yr, 1, 1).dayOfWeek();
-
- // the year is 53-week long if Jan 1 is Thursday or, if it's a leap year, a Wednesday
- isLongYear = (wday == Thursday) || (QDate::isLeapYear(yr) && wday == Thursday - 1);
-
- // Jan 4 is always on week 1
- QTest::newRow(yrstr + "-01-04") << 1 << yr << yr << 1 << 4;
-
- // Dec 28 is always on the last week
- QTest::newRow(yrstr + "-12-28") << (52 + isLongYear) << yr << yr << 12 << 28;
-
- // Jan 1 is on either on week 1 or on the last week of the previous year
- QTest::newRow(yrstr + "-01-01")
- << (wday <= Thursday ? 1 : 52 + wasLastYearLong)
- << (wday <= Thursday ? yr : yr - 1)
- << yr << 1 << 1;
-
- // Dec 31 is either on the last week or week 1 of the next year
- wday = QDate(yr, 12, 31).dayOfWeek();
- QTest::newRow(yrstr + "-12-31")
- << (wday >= Thursday ? 52 + isLongYear : 1)
- << (wday >= Thursday ? yr : yr + 1)
- << yr << 12 << 31;
- }
-}
-
-void tst_QDate::weekNumber()
-{
- int yearNumber;
- QFETCH( int, year );
- QFETCH( int, month );
- QFETCH( int, day );
- QFETCH( int, expectedWeekNum );
- QFETCH( int, expectedYearNum );
- QDate dt1( year, month, day );
- QCOMPARE( dt1.weekNumber( &yearNumber ), expectedWeekNum );
- QCOMPARE( yearNumber, expectedYearNum );
-}
-
-void tst_QDate::weekNumber_invalid_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
-
- //next we fill it with data
- QTest::newRow( "data0" ) << 0 << 0 << 0;
- QTest::newRow( "data1" ) << 2001 << 1 << 32;
- QTest::newRow( "data2" ) << 1999 << 2 << 29;
-}
-
-void tst_QDate::weekNumber_invalid()
-{
- QDate dt;
- int yearNumber;
- QCOMPARE( dt.weekNumber( &yearNumber ), 0 );
-}
-
-void tst_QDate::julianDaysLimits()
-{
- qint64 min = std::numeric_limits<qint64>::min();
- qint64 max = std::numeric_limits<qint64>::max();
- qint64 minJd = Q_INT64_C(-784350574879);
- qint64 maxJd = Q_INT64_C( 784354017364);
-
- QDate maxDate = QDate::fromJulianDay(maxJd);
- QDate minDate = QDate::fromJulianDay(minJd);
- QDate zeroDate = QDate::fromJulianDay(0);
-
- QDate dt = QDate::fromJulianDay(min);
- QCOMPARE(dt.isValid(), false);
- dt = QDate::fromJulianDay(minJd - 1);
- QCOMPARE(dt.isValid(), false);
- dt = QDate::fromJulianDay(minJd);
- QCOMPARE(dt.isValid(), true);
- dt = QDate::fromJulianDay(minJd + 1);
- QCOMPARE(dt.isValid(), true);
- dt = QDate::fromJulianDay(maxJd - 1);
- QCOMPARE(dt.isValid(), true);
- dt = QDate::fromJulianDay(maxJd);
- QCOMPARE(dt.isValid(), true);
- dt = QDate::fromJulianDay(maxJd + 1);
- QCOMPARE(dt.isValid(), false);
- dt = QDate::fromJulianDay(max);
- QCOMPARE(dt.isValid(), false);
-
- dt = maxDate.addDays(1);
- QCOMPARE(dt.isValid(), false);
- dt = maxDate.addDays(0);
- QCOMPARE(dt.isValid(), true);
- dt = maxDate.addDays(-1);
- QCOMPARE(dt.isValid(), true);
- dt = maxDate.addDays(max);
- QCOMPARE(dt.isValid(), false);
- dt = maxDate.addDays(min);
- QCOMPARE(dt.isValid(), false);
-
- dt = minDate.addDays(-1);
- QCOMPARE(dt.isValid(), false);
- dt = minDate.addDays(0);
- QCOMPARE(dt.isValid(), true);
- dt = minDate.addDays(1);
- QCOMPARE(dt.isValid(), true);
- dt = minDate.addDays(min);
- QCOMPARE(dt.isValid(), false);
- dt = minDate.addDays(max);
- QCOMPARE(dt.isValid(), false);
-
- dt = zeroDate.addDays(-1);
- QCOMPARE(dt.isValid(), true);
- dt = zeroDate.addDays(0);
- QCOMPARE(dt.isValid(), true);
- dt = zeroDate.addDays(1);
- QCOMPARE(dt.isValid(), true);
- dt = zeroDate.addDays(min);
- QCOMPARE(dt.isValid(), false);
- dt = zeroDate.addDays(max);
- QCOMPARE(dt.isValid(), false);
-}
-
-void tst_QDate::addDays()
-{
- QFETCH( int, year );
- QFETCH( int, month );
- QFETCH( int, day );
- QFETCH( int, amountToAdd );
- QFETCH( int, expectedYear );
- QFETCH( int, expectedMonth );
- QFETCH( int, expectedDay );
-
- QDate dt( year, month, day );
- dt = dt.addDays( amountToAdd );
-
- QCOMPARE( dt.year(), expectedYear );
- QCOMPARE( dt.month(), expectedMonth );
- QCOMPARE( dt.day(), expectedDay );
-}
-
-void tst_QDate::addDays_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<int>("amountToAdd");
- QTest::addColumn<int>("expectedYear");
- QTest::addColumn<int>("expectedMonth");
- QTest::addColumn<int>("expectedDay");
-
- QTest::newRow( "data0" ) << 2000 << 1 << 1 << 1 << 2000 << 1 << 2;
- QTest::newRow( "data1" ) << 2000 << 1 << 31 << 1 << 2000 << 2 << 1;
- QTest::newRow( "data2" ) << 2000 << 2 << 28 << 1 << 2000 << 2 << 29;
- QTest::newRow( "data3" ) << 2000 << 2 << 29 << 1 << 2000 << 3 << 1;
- QTest::newRow( "data4" ) << 2000 << 12 << 31 << 1 << 2001 << 1 << 1;
- QTest::newRow( "data5" ) << 2001 << 2 << 28 << 1 << 2001 << 3 << 1;
- QTest::newRow( "data6" ) << 2001 << 2 << 28 << 30 << 2001 << 3 << 30;
- QTest::newRow( "data7" ) << 2001 << 3 << 30 << 5 << 2001 << 4 << 4;
-
- QTest::newRow( "data8" ) << 2000 << 1 << 1 << -1 << 1999 << 12 << 31;
- QTest::newRow( "data9" ) << 2000 << 1 << 31 << -1 << 2000 << 1 << 30;
- QTest::newRow( "data10" ) << 2000 << 2 << 28 << -1 << 2000 << 2 << 27;
- QTest::newRow( "data11" ) << 2001 << 2 << 28 << -30 << 2001 << 1 << 29;
-
- QTest::newRow( "data12" ) << -4713 << 1 << 2 << -2 << -4714 << 12 << 31;
- QTest::newRow( "data13" ) << -4713 << 1 << 2 << 2 << -4713 << 1 << 4;
-
- QTest::newRow( "invalid" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0;
-}
-
-void tst_QDate::addMonths()
-{
- QFETCH( int, year );
- QFETCH( int, month );
- QFETCH( int, day );
- QFETCH( int, amountToAdd );
- QFETCH( int, expectedYear );
- QFETCH( int, expectedMonth );
- QFETCH( int, expectedDay );
-
- QDate dt( year, month, day );
- dt = dt.addMonths( amountToAdd );
-
- QCOMPARE( dt.year(), expectedYear );
- QCOMPARE( dt.month(), expectedMonth );
- QCOMPARE( dt.day(), expectedDay );
-}
-
-void tst_QDate::addMonths_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<int>("amountToAdd");
- QTest::addColumn<int>("expectedYear");
- QTest::addColumn<int>("expectedMonth");
- QTest::addColumn<int>("expectedDay");
-
- QTest::newRow( "data0" ) << 2000 << 1 << 1 << 1 << 2000 << 2 << 1;
- QTest::newRow( "data1" ) << 2000 << 1 << 31 << 1 << 2000 << 2 << 29;
- QTest::newRow( "data2" ) << 2000 << 2 << 28 << 1 << 2000 << 3 << 28;
- QTest::newRow( "data3" ) << 2000 << 2 << 29 << 1 << 2000 << 3 << 29;
- QTest::newRow( "data4" ) << 2000 << 12 << 31 << 1 << 2001 << 1 << 31;
- QTest::newRow( "data5" ) << 2001 << 2 << 28 << 1 << 2001 << 3 << 28;
- QTest::newRow( "data6" ) << 2001 << 2 << 28 << 12 << 2002 << 2 << 28;
- QTest::newRow( "data7" ) << 2000 << 2 << 29 << 12 << 2001 << 2 << 28;
- QTest::newRow( "data8" ) << 2000 << 10 << 15 << 4 << 2001 << 2 << 15;
-
- QTest::newRow( "data9" ) << 2000 << 1 << 1 << -1 << 1999 << 12 << 1;
- QTest::newRow( "data10" ) << 2000 << 1 << 31 << -1 << 1999 << 12 << 31;
- QTest::newRow( "data11" ) << 2000 << 12 << 31 << -1 << 2000 << 11 << 30;
- QTest::newRow( "data12" ) << 2001 << 2 << 28 << -12 << 2000 << 2 << 28;
- QTest::newRow( "data13" ) << 2000 << 1 << 31 << -7 << 1999 << 6 << 30;
- QTest::newRow( "data14" ) << 2000 << 2 << 29 << -12 << 1999 << 2 << 28;
-
- // year sign change:
- QTest::newRow( "data15" ) << 1 << 1 << 1 << -1 << -1 << 12 << 1;
- QTest::newRow( "data16" ) << 1 << 1 << 1 << -12 << -1 << 1 << 1;
- QTest::newRow( "data17" ) << -1 << 12 << 1 << 1 << 1 << 1 << 1;
- QTest::newRow( "data18" ) << -1 << 1 << 1 << 12 << 1 << 1 << 1;
- QTest::newRow( "data19" ) << -2 << 1 << 1 << 12 << -1 << 1 << 1;
-
- QTest::newRow( "invalid" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0;
-}
-
-void tst_QDate::addYears()
-{
- QFETCH( int, year );
- QFETCH( int, month );
- QFETCH( int, day );
- QFETCH( int, amountToAdd );
- QFETCH( int, expectedYear );
- QFETCH( int, expectedMonth );
- QFETCH( int, expectedDay );
-
- QDate dt( year, month, day );
- dt = dt.addYears( amountToAdd );
-
- QCOMPARE( dt.year(), expectedYear );
- QCOMPARE( dt.month(), expectedMonth );
- QCOMPARE( dt.day(), expectedDay );
-}
-
-void tst_QDate::addYears_data()
-{
- QTest::addColumn<int>("year");
- QTest::addColumn<int>("month");
- QTest::addColumn<int>("day");
- QTest::addColumn<int>("amountToAdd");
- QTest::addColumn<int>("expectedYear");
- QTest::addColumn<int>("expectedMonth");
- QTest::addColumn<int>("expectedDay");
-
- QTest::newRow( "data0" ) << 2000 << 1 << 1 << 1 << 2001 << 1 << 1;
- QTest::newRow( "data1" ) << 2000 << 1 << 31 << 1 << 2001 << 1 << 31;
- QTest::newRow( "data2" ) << 2000 << 2 << 28 << 1 << 2001 << 2 << 28;
- QTest::newRow( "data3" ) << 2000 << 2 << 29 << 1 << 2001 << 2 << 28;
- QTest::newRow( "data4" ) << 2000 << 12 << 31 << 1 << 2001 << 12 << 31;
- QTest::newRow( "data5" ) << 2001 << 2 << 28 << 3 << 2004 << 2 << 28;
- QTest::newRow( "data6" ) << 2000 << 2 << 29 << 4 << 2004 << 2 << 29;
-
- QTest::newRow( "data7" ) << 2000 << 1 << 31 << -1 << 1999 << 1 << 31;
- QTest::newRow( "data9" ) << 2000 << 2 << 29 << -1 << 1999 << 2 << 28;
- QTest::newRow( "data10" ) << 2000 << 12 << 31 << -1 << 1999 << 12 << 31;
- QTest::newRow( "data11" ) << 2001 << 2 << 28 << -3 << 1998 << 2 << 28;
- QTest::newRow( "data12" ) << 2000 << 2 << 29 << -4 << 1996 << 2 << 29;
- QTest::newRow( "data13" ) << 2000 << 2 << 29 << -5 << 1995 << 2 << 28;
-
- QTest::newRow( "data14" ) << 2000 << 1 << 1 << -1999 << 1 << 1 << 1;
- QTest::newRow( "data15" ) << 2000 << 1 << 1 << -2000 << -1 << 1 << 1;
- QTest::newRow( "data16" ) << 2000 << 1 << 1 << -2001 << -2 << 1 << 1;
- QTest::newRow( "data17" ) << -2000 << 1 << 1 << 1999 << -1 << 1 << 1;
- QTest::newRow( "data18" ) << -2000 << 1 << 1 << 2000 << 1 << 1 << 1;
- QTest::newRow( "data19" ) << -2000 << 1 << 1 << 2001 << 2 << 1 << 1;
-
- QTest::newRow( "invalid" ) << 0 << 0 << 0 << 1 << 0 << 0 << 0;
-}
-
-void tst_QDate::daysTo()
-{
- qint64 minJd = Q_INT64_C(-784350574879);
- qint64 maxJd = Q_INT64_C( 784354017364);
-
- QDate dt1(2000, 1, 1);
- QDate dt2(2000, 1, 5);
- QCOMPARE(dt1.daysTo(dt2), (qint64) 4);
- QCOMPARE(dt2.daysTo(dt1), (qint64) -4);
-
- dt1.setDate(0, 0, 0);
- QCOMPARE(dt1.daysTo(dt2), (qint64) 0);
- dt1.setDate(2000, 1, 1);
- dt2.setDate(0, 0, 0);
- QCOMPARE(dt1.daysTo(dt2), (qint64) 0);
-
-
- QDate maxDate = QDate::fromJulianDay(maxJd);
- QDate minDate = QDate::fromJulianDay(minJd);
- QDate zeroDate = QDate::fromJulianDay(0);
-
- QCOMPARE(maxDate.daysTo(minDate), minJd - maxJd);
- QCOMPARE(minDate.daysTo(maxDate), maxJd - minJd);
- QCOMPARE(maxDate.daysTo(zeroDate), -maxJd);
- QCOMPARE(zeroDate.daysTo(maxDate), maxJd);
- QCOMPARE(minDate.daysTo(zeroDate), -minJd);
- QCOMPARE(zeroDate.daysTo(minDate), minJd);
-}
-
-void tst_QDate::operator_eq_eq_data()
-{
- QTest::addColumn<QDate>("d1");
- QTest::addColumn<QDate>("d2");
- QTest::addColumn<bool>("expectEqual");
-
- QTest::newRow("data0") << QDate(2000,1,2) << QDate(2000,1,2) << true;
- QTest::newRow("data1") << QDate(2001,12,5) << QDate(2001,12,5) << true;
- QTest::newRow("data2") << QDate(2001,12,5) << QDate(2001,12,5) << true;
- QTest::newRow("data3") << QDate(2001,12,5) << QDate(2002,12,5) << false;
-
- QDate date1(1900, 1, 1);
- QDate date2 = date1.addDays(1);
- QDate date3 = date1.addDays(-1);
- QDate date4 = date1.addMonths(1);
- QDate date5 = date1.addMonths(-1);
- QDate date6 = date1.addYears(1);
- QDate date7 = date1.addYears(-1);
-
- QTest::newRow("data4") << date2 << date3 << false;
- QTest::newRow("data5") << date4 << date5 << false;
- QTest::newRow("data6") << date6 << date7 << false;
- QTest::newRow("data7") << date1 << date2 << false;
- QTest::newRow("data8") << date1 << date3 << false;
- QTest::newRow("data9") << date1 << date4 << false;
- QTest::newRow("data10") << date1 << date5 << false;
- QTest::newRow("data11") << date1 << date6 << false;
- QTest::newRow("data12") << date1 << date7 << false;
-}
-
-void tst_QDate::operator_eq_eq()
-{
- QFETCH(QDate, d1);
- QFETCH(QDate, d2);
- QFETCH(bool, expectEqual);
-
- bool equal = d1 == d2;
- QCOMPARE(equal, expectEqual);
- bool notEqual = d1 != d2;
- QCOMPARE(notEqual, !expectEqual);
-
- if (equal)
- QVERIFY(qHash(d1) == qHash(d2));
-}
-
-void tst_QDate::operator_lt()
-{
- QDate d1(2000,1,2);
- QDate d2(2000,1,2);
- QVERIFY( !(d1 < d2) );
-
- d1 = QDate(2001,12,4);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 < d2 );
-
- d1 = QDate(2001,11,5);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 < d2 );
-
- d1 = QDate(2000,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 < d2 );
-
- d1 = QDate(2002,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 < d2) );
-
- d1 = QDate(2001,12,5);
- d2 = QDate(2001,11,5);
- QVERIFY( !(d1 < d2) );
-
- d1 = QDate(2001,12,6);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 < d2) );
-}
-
-void tst_QDate::operator_gt()
-{
- QDate d1(2000,1,2);
- QDate d2(2000,1,2);
- QVERIFY( !(d1 > d2) );
-
- d1 = QDate(2001,12,4);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 > d2) );
-
- d1 = QDate(2001,11,5);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 > d2) );
-
- d1 = QDate(2000,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 > d2) );
-
- d1 = QDate(2002,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 > d2 );
-
- d1 = QDate(2001,12,5);
- d2 = QDate(2001,11,5);
- QVERIFY( d1 > d2 );
-
- d1 = QDate(2001,12,6);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 > d2 );
-}
-
-void tst_QDate::operator_lt_eq()
-{
- QDate d1(2000,1,2);
- QDate d2(2000,1,2);
- QVERIFY( d1 <= d2 );
-
- d1 = QDate(2001,12,4);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 <= d2 );
-
- d1 = QDate(2001,11,5);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 <= d2 );
-
- d1 = QDate(2000,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 <= d2 );
-
- d1 = QDate(2002,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 <= d2) );
-
- d1 = QDate(2001,12,5);
- d2 = QDate(2001,11,5);
- QVERIFY( !(d1 <= d2) );
-
- d1 = QDate(2001,12,6);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 <= d2) );
-}
-
-void tst_QDate::operator_gt_eq()
-{
- QDate d1(2000,1,2);
- QDate d2(2000,1,2);
- QVERIFY( d1 >= d2 );
-
- d1 = QDate(2001,12,4);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 >= d2) );
-
- d1 = QDate(2001,11,5);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 >= d2) );
-
- d1 = QDate(2000,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( !(d1 >= d2) );
-
- d1 = QDate(2002,12,5);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 >= d2 );
-
- d1 = QDate(2001,12,5);
- d2 = QDate(2001,11,5);
- QVERIFY( d1 >= d2 );
-
- d1 = QDate(2001,12,6);
- d2 = QDate(2001,12,5);
- QVERIFY( d1 >= d2 );
-}
-
-Q_DECLARE_METATYPE(QDataStream::Version)
-
-void tst_QDate::operator_insert_extract_data()
-{
- QTest::addColumn<QDate>("date");
- QTest::addColumn<QDataStream::Version>("dataStreamVersion");
-
- QMap<QDataStream::Version, QString> versionsToTest;
- versionsToTest.insert(QDataStream::Qt_1_0, QString::fromLatin1("Qt_1_0"));
- versionsToTest.insert(QDataStream::Qt_2_0, QString::fromLatin1("Qt_2_0"));
- versionsToTest.insert(QDataStream::Qt_2_1, QString::fromLatin1("Qt_2_1"));
- versionsToTest.insert(QDataStream::Qt_3_0, QString::fromLatin1("Qt_3_0"));
- versionsToTest.insert(QDataStream::Qt_3_1, QString::fromLatin1("Qt_3_1"));
- versionsToTest.insert(QDataStream::Qt_3_3, QString::fromLatin1("Qt_3_3"));
- versionsToTest.insert(QDataStream::Qt_4_0, QString::fromLatin1("Qt_4_0"));
- versionsToTest.insert(QDataStream::Qt_4_1, QString::fromLatin1("Qt_4_1"));
- versionsToTest.insert(QDataStream::Qt_4_2, QString::fromLatin1("Qt_4_2"));
- versionsToTest.insert(QDataStream::Qt_4_3, QString::fromLatin1("Qt_4_3"));
- versionsToTest.insert(QDataStream::Qt_4_4, QString::fromLatin1("Qt_4_4"));
- versionsToTest.insert(QDataStream::Qt_4_5, QString::fromLatin1("Qt_4_5"));
- versionsToTest.insert(QDataStream::Qt_4_6, QString::fromLatin1("Qt_4_6"));
- versionsToTest.insert(QDataStream::Qt_4_7, QString::fromLatin1("Qt_4_7"));
- versionsToTest.insert(QDataStream::Qt_4_8, QString::fromLatin1("Qt_4_8"));
- versionsToTest.insert(QDataStream::Qt_4_9, QString::fromLatin1("Qt_4_9"));
- versionsToTest.insert(QDataStream::Qt_5_0, QString::fromLatin1("Qt_5_0"));
-
- for (QMap<QDataStream::Version, QString>::ConstIterator it = versionsToTest.constBegin();
- it != versionsToTest.constEnd(); ++it) {
- const QString &version(it.value());
- QTest::newRow(("(invalid) " + version).toLocal8Bit().constData()) << invalidDate() << it.key();
- QTest::newRow(("(1, 1, 1) " + version).toLocal8Bit().constData()) << QDate(1, 1, 1) << it.key();
- QTest::newRow(("(-1, 1, 1) " + version).toLocal8Bit().constData()) << QDate(-1, 1, 1) << it.key();
- QTest::newRow(("(1995, 5, 20) " + version).toLocal8Bit().constData()) << QDate(1995, 5, 20) << it.key();
-
- // Test minimums for quint32/qint64.
- if (it.key() >= QDataStream::Qt_5_0)
- QTest::newRow(("(-4714, 11, 24) " + version).toLocal8Bit().constData()) << QDate(-4714, 11, 24) << it.key();
- else
- QTest::newRow(("(-4713, 1, 2) " + version).toLocal8Bit().constData()) << QDate(-4713, 1, 2) << it.key();
- }
-}
-
-void tst_QDate::operator_insert_extract()
-{
- QFETCH(QDate, date);
- QFETCH(QDataStream::Version, dataStreamVersion);
-
- QByteArray byteArray;
- QDataStream dataStream(&byteArray, QIODevice::ReadWrite);
- dataStream.setVersion(dataStreamVersion);
- dataStream << date;
- dataStream.device()->reset();
- QDate deserialised;
- dataStream >> deserialised;
- QCOMPARE(dataStream.status(), QDataStream::Ok);
-
- QCOMPARE(deserialised, date);
-}
-
-void tst_QDate::fromStringDateFormat_data()
-{
- QTest::addColumn<QString>("dateStr");
- QTest::addColumn<Qt::DateFormat>("dateFormat");
- QTest::addColumn<QDate>("expectedDate");
-
- QTest::newRow("text0") << QString("Sat May 20 1995") << Qt::TextDate << QDate(1995, 5, 20);
- QTest::newRow("text1") << QString("Tue Dec 17 2002") << Qt::TextDate << QDate(2002, 12, 17);
- QTest::newRow("text2") << QDate(1999, 11, 14).toString(Qt::TextDate) << Qt::TextDate << QDate(1999, 11, 14);
- QTest::newRow("text3") << QString("xxx Jan 1 0999") << Qt::TextDate << QDate(999, 1, 1);
- QTest::newRow("text3b") << QString("xxx Jan 1 999") << Qt::TextDate << QDate(999, 1, 1);
- QTest::newRow("text4") << QString("xxx Jan 1 12345") << Qt::TextDate << QDate(12345, 1, 1);
- QTest::newRow("text5") << QString("xxx Jan 1 -0001") << Qt::TextDate << QDate(-1, 1, 1);
- QTest::newRow("text6") << QString("xxx Jan 1 -4712") << Qt::TextDate << QDate(-4712, 1, 1);
- QTest::newRow("text7") << QString("xxx Nov 25 -4713") << Qt::TextDate << QDate(-4713, 11, 25);
- QTest::newRow("text, empty") << QString() << Qt::TextDate << QDate();
- QTest::newRow("text, 3 part") << QString("part1 part2 part3") << Qt::TextDate << QDate();
- QTest::newRow("text, invalid month name") << QString("Wed BabytownFrolics 8 2012") << Qt::TextDate << QDate();
- QTest::newRow("text, invalid day") << QString("Wed May Wilhelm 2012") << Qt::TextDate << QDate();
- QTest::newRow("text, invalid year") << QString("Wed May 8 Cats") << Qt::TextDate << QDate();
-
- QTest::newRow("iso0") << QString("1995-05-20") << Qt::ISODate << QDate(1995, 5, 20);
- QTest::newRow("iso1") << QString("2002-12-17") << Qt::ISODate << QDate(2002, 12, 17);
- QTest::newRow("iso2") << QDate(1999, 11, 14).toString(Qt::ISODate) << Qt::ISODate << QDate(1999, 11, 14);
- QTest::newRow("iso3") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1);
- QTest::newRow("iso3b") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1);
- QTest::newRow("iso4") << QString("2000101101") << Qt::ISODate << QDate();
- QTest::newRow("iso5") << QString("2000/01/01") << Qt::ISODate << QDate(2000, 1, 1);
- QTest::newRow("iso6") << QString("2000-01-01 blah") << Qt::ISODate << QDate(2000, 1, 1);
- QTest::newRow("iso7") << QString("2000-01-011blah") << Qt::ISODate << QDate();
- QTest::newRow("iso8") << QString("2000-01-01blah") << Qt::ISODate << QDate(2000, 1, 1);
- QTest::newRow("iso9") << QString("-001-01-01") << Qt::ISODate << QDate();
- QTest::newRow("iso10") << QString("99999-01-01") << Qt::ISODate << QDate();
-
- // Test Qt::RFC2822Date format (RFC 2822).
- QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QDate(1987, 2, 13);
- QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
- << Qt::RFC2822Date << QDate(1970, 1, 1);
- // No timezone
- QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
- << Qt::RFC2822Date << QDate(1970, 1, 1);
- // No time specified
- QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
- << Qt::RFC2822Date << QDate(2002, 11, 1);
- QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
- << Qt::RFC2822Date << QDate(2002, 11, 1);
- // Test invalid month, day, year
- QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
- << Qt::RFC2822Date << QDate();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
- << Qt::RFC2822Date << QDate(2012, 1, 1);
- QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << QDate();
-
- // Test Qt::RFC2822Date format (RFC 850 and 1036).
- QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
- << Qt::RFC2822Date << QDate(1987, 2, 13);
- // No timezone
- QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
- << Qt::RFC2822Date << QDate(1970, 1, 1);
- // No time specified
- QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
- << Qt::RFC2822Date << QDate(2002, 11, 1);
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
- << Qt::RFC2822Date << QDate(2012, 1, 1);
- QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
- << Qt::RFC2822Date << QDate();
- QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000")
- << Qt::RFC2822Date << QDate();
-
- QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDate();
-}
-
-void tst_QDate::fromStringDateFormat()
-{
- QFETCH(QString, dateStr);
- QFETCH(Qt::DateFormat, dateFormat);
- QFETCH(QDate, expectedDate);
-
- QCOMPARE(QDate::fromString(dateStr, dateFormat), expectedDate);
-}
-
-void tst_QDate::fromStringFormat_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QDate>("expected");
-
- // Undo this (inline the C-locale versions) for ### Qt 6
- // Get localized names:
- QString january = QDate::longMonthName(1);
- QString february = QDate::longMonthName(2);
- QString march = QDate::longMonthName(3);
- QString august = QDate::longMonthName(8);
- QString mon = QDate::shortDayName(1);
- QString monday = QDate::longDayName(1);
- QString tuesday = QDate::longDayName(2);
- QString wednesday = QDate::longDayName(3);
- QString thursday = QDate::longDayName(4);
- QString friday = QDate::longDayName(5);
- QString saturday = QDate::longDayName(6);
- QString sunday = QDate::longDayName(7);
-
- QTest::newRow("data0") << QString("") << QString("") << defDate();
- QTest::newRow("data1") << QString(" ") << QString("") << invalidDate();
- QTest::newRow("data2") << QString(" ") << QString(" ") << defDate();
- QTest::newRow("data3") << QString("-%$%#") << QString("$*(#@") << invalidDate();
- QTest::newRow("data4") << QString("d") << QString("'d'") << defDate();
- QTest::newRow("data5") << QString("101010") << QString("dMyy") << QDate(1910, 10, 10);
- QTest::newRow("data6") << QString("101010b") << QString("dMyy") << invalidDate();
- QTest::newRow("data7") << january << QString("MMMM") << defDate();
- QTest::newRow("data8") << QString("ball") << QString("balle") << invalidDate();
- QTest::newRow("data9") << QString("balleh") << QString("balleh") << defDate();
- QTest::newRow("data10") << QString("10.01.1") << QString("M.dd.d") << QDate(defDate().year(), 10, 1);
- QTest::newRow("data11") << QString("-1.01.1") << QString("M.dd.d") << invalidDate();
- QTest::newRow("data12") << QString("11010") << QString("dMMyy") << invalidDate();
- QTest::newRow("data13") << QString("-2") << QString("d") << invalidDate();
- QTest::newRow("data14") << QString("132") << QString("Md") << invalidDate();
- QTest::newRow("data15") << february << QString("MMMM") << QDate(defDate().year(), 2, 1);
-
- QString date = mon + QLatin1Char(' ') + august + " 8 2005";
- QTest::newRow("data16") << date << QString("ddd MMMM d yyyy") << QDate(2005, 8, 8);
- QTest::newRow("data17") << QString("2000:00") << QString("yyyy:yy") << QDate(2000, 1, 1);
- QTest::newRow("data18") << QString("1999:99") << QString("yyyy:yy") << QDate(1999, 1, 1);
- QTest::newRow("data19") << QString("2099:99") << QString("yyyy:yy") << QDate(2099, 1, 1);
- QTest::newRow("data20") << QString("2001:01") << QString("yyyy:yy") << QDate(2001, 1, 1);
- QTest::newRow("data21") << QString("99") << QString("yy") << QDate(1999, 1, 1);
- QTest::newRow("data22") << QString("01") << QString("yy") << QDate(1901, 1, 1);
-
- QTest::newRow("data23") << monday << QString("dddd") << QDate(1900, 1, 1);
- QTest::newRow("data24") << tuesday << QString("dddd") << QDate(1900, 1, 2);
- QTest::newRow("data25") << wednesday << QString("dddd") << QDate(1900, 1, 3);
- QTest::newRow("data26") << thursday << QString("dddd") << QDate(1900, 1, 4);
- QTest::newRow("data27") << friday << QString("dddd") << QDate(1900, 1, 5);
- QTest::newRow("data28") << saturday << QString("dddd") << QDate(1900, 1, 6);
- QTest::newRow("data29") << sunday << QString("dddd") << QDate(1900, 1, 7);
-
- QTest::newRow("data30") << monday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 2);
- QTest::newRow("data31") << tuesday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 3);
- QTest::newRow("data32") << wednesday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 4);
- QTest::newRow("data33") << thursday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 5);
- QTest::newRow("data34") << friday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 6);
- QTest::newRow("data35") << saturday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 7);
- QTest::newRow("data36") << sunday + " 2006" << QString("dddd yyyy") << QDate(2006, 1, 1);
-
- QTest::newRow("data37") << tuesday + " 2007 " + march << QString("dddd yyyy MMMM") << QDate(2007, 3, 6);
-
- QTest::newRow("data38") << QString("21052006") << QString("ddMMyyyy") << QDate(2006,5,21);
- QTest::newRow("data39") << QString("210506") << QString("ddMMyy") << QDate(1906,5,21);
- QTest::newRow("data40") << QString("21/5/2006") << QString("d/M/yyyy") << QDate(2006,5,21);
- QTest::newRow("data41") << QString("21/5/06") << QString("d/M/yy") << QDate(1906,5,21);
- QTest::newRow("data42") << QString("20060521") << QString("yyyyMMdd") << QDate(2006,5,21);
- QTest::newRow("data43") << QString("060521") << QString("yyMMdd") << QDate(1906,5,21);
- QTest::newRow("lateMarch") << QString("9999-03-06") << QString("yyyy-MM-dd") << QDate(9999, 3, 6);
- QTest::newRow("late") << QString("9999-12-31") << QString("yyyy-MM-dd") << QDate(9999, 12, 31);
-}
-
-
-void tst_QDate::fromStringFormat()
-{
- QFETCH(QString, string);
- QFETCH(QString, format);
- QFETCH(QDate, expected);
-
- QDate dt = QDate::fromString(string, format);
- QCOMPARE(dt, expected);
-}
-
-void tst_QDate::toStringFormat_data()
-{
- QTest::addColumn<QDate>("t");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QString>("str");
-
- QTest::newRow( "data0" ) << QDate(1995,5,20) << QString("d-M-yy") << QString("20-5-95");
- QTest::newRow( "data1" ) << QDate(2002,12,17) << QString("dd-MM-yyyy") << QString("17-12-2002");
- QTest::newRow( "data2" ) << QDate(1995,5,20) << QString("M-yy") << QString("5-95");
- QTest::newRow( "data3" ) << QDate(2002,12,17) << QString("dd") << QString("17");
- QTest::newRow( "data4" ) << QDate() << QString("dd-mm-yyyy") << QString();
-}
-
-void tst_QDate::toStringFormat()
-{
- QFETCH( QDate, t );
- QFETCH( QString, format );
- QFETCH( QString, str );
-
- QCOMPARE( t.toString( format ), str );
-}
-
-void tst_QDate::toStringDateFormat_data()
-{
- QTest::addColumn<QDate>("date");
- QTest::addColumn<Qt::DateFormat>("format");
- QTest::addColumn<QString>("expectedStr");
-
- QTest::newRow("data0") << QDate(1,1,1) << Qt::ISODate << QString("0001-01-01");
- QTest::newRow("data1") << QDate(11,1,1) << Qt::ISODate << QString("0011-01-01");
- QTest::newRow("data2") << QDate(111,1,1) << Qt::ISODate << QString("0111-01-01");
- QTest::newRow("data3") << QDate(1974,12,1) << Qt::ISODate << QString("1974-12-01");
- QTest::newRow("year < 0") << QDate(-1,1,1) << Qt::ISODate << QString();
- QTest::newRow("year > 9999") << QDate(-1,1,1) << Qt::ISODate << QString();
- QTest::newRow("RFC2822Date") << QDate(1974,12,1) << Qt::RFC2822Date << QString("01 Dec 1974");
- QTest::newRow("ISODateWithMs") << QDate(1974,12,1) << Qt::ISODateWithMs << QString("1974-12-01");
-}
-
-void tst_QDate::toStringDateFormat()
-{
- QFETCH(QDate, date);
- QFETCH(Qt::DateFormat, format);
- QFETCH(QString, expectedStr);
-
- QCOMPARE(date.toString(Qt::SystemLocaleShortDate), QLocale::system().toString(date, QLocale::ShortFormat));
- QCOMPARE(date.toString(Qt::DefaultLocaleShortDate), QLocale().toString(date, QLocale::ShortFormat));
- QCOMPARE(date.toString(Qt::SystemLocaleLongDate), QLocale::system().toString(date, QLocale::LongFormat));
- QCOMPARE(date.toString(Qt::DefaultLocaleLongDate), QLocale().toString(date, QLocale::LongFormat));
- QLocale::setDefault(QLocale::German);
- QCOMPARE(date.toString(Qt::SystemLocaleShortDate), QLocale::system().toString(date, QLocale::ShortFormat));
- QCOMPARE(date.toString(Qt::DefaultLocaleShortDate), QLocale().toString(date, QLocale::ShortFormat));
- QCOMPARE(date.toString(Qt::SystemLocaleLongDate), QLocale::system().toString(date, QLocale::LongFormat));
- QCOMPARE(date.toString(Qt::DefaultLocaleLongDate), QLocale().toString(date, QLocale::LongFormat));
-
- QCOMPARE(date.toString(format), expectedStr);
-}
-
-void tst_QDate::isLeapYear()
-{
- QVERIFY(QDate::isLeapYear(-4801));
- QVERIFY(!QDate::isLeapYear(-4800));
- QVERIFY(QDate::isLeapYear(-4445));
- QVERIFY(!QDate::isLeapYear(-4444));
- QVERIFY(!QDate::isLeapYear(-6));
- QVERIFY(QDate::isLeapYear(-5));
- QVERIFY(!QDate::isLeapYear(-4));
- QVERIFY(!QDate::isLeapYear(-3));
- QVERIFY(!QDate::isLeapYear(-2));
- QVERIFY(QDate::isLeapYear(-1));
- QVERIFY(!QDate::isLeapYear(0)); // Doesn't exist
- QVERIFY(!QDate::isLeapYear(1));
- QVERIFY(!QDate::isLeapYear(2));
- QVERIFY(!QDate::isLeapYear(3));
- QVERIFY(QDate::isLeapYear(4));
- QVERIFY(!QDate::isLeapYear(7));
- QVERIFY(QDate::isLeapYear(8));
- QVERIFY(!QDate::isLeapYear(100));
- QVERIFY(QDate::isLeapYear(400));
- QVERIFY(!QDate::isLeapYear(700));
- QVERIFY(!QDate::isLeapYear(1500));
- QVERIFY(QDate::isLeapYear(1600));
- QVERIFY(!QDate::isLeapYear(1700));
- QVERIFY(!QDate::isLeapYear(1800));
- QVERIFY(!QDate::isLeapYear(1900));
- QVERIFY(QDate::isLeapYear(2000));
- QVERIFY(!QDate::isLeapYear(2100));
- QVERIFY(!QDate::isLeapYear(2200));
- QVERIFY(!QDate::isLeapYear(2300));
- QVERIFY(QDate::isLeapYear(2400));
- QVERIFY(!QDate::isLeapYear(2500));
- QVERIFY(!QDate::isLeapYear(2600));
- QVERIFY(!QDate::isLeapYear(2700));
- QVERIFY(QDate::isLeapYear(2800));
-
- for (int i = -4713; i <= 10000; ++i) {
- if (i == 0)
- continue;
- QVERIFY(!QDate(i, 2, 29).isValid() == !QDate::isLeapYear(i));
- }
-}
-
-void tst_QDate::yearsZeroToNinetyNine()
-{
- {
- QDate dt(-1, 2, 3);
- QCOMPARE(dt.year(), -1);
- QCOMPARE(dt.month(), 2);
- QCOMPARE(dt.day(), 3);
- }
-
- {
- QDate dt(1, 2, 3);
- QCOMPARE(dt.year(), 1);
- QCOMPARE(dt.month(), 2);
- QCOMPARE(dt.day(), 3);
- }
-
- {
- QDate dt(99, 2, 3);
- QCOMPARE(dt.year(), 99);
- QCOMPARE(dt.month(), 2);
- QCOMPARE(dt.day(), 3);
- }
-
- QVERIFY(!QDate::isValid(0, 2, 3));
- QVERIFY(QDate::isValid(1, 2, 3));
- QVERIFY(QDate::isValid(-1, 2, 3));
-
-#if QT_DEPRECATED_SINCE(5,0)
- {
- QDate dt;
- dt.setYMD(1, 2, 3);
- QCOMPARE(dt.year(), 1901);
- QCOMPARE(dt.month(), 2);
- QCOMPARE(dt.day(), 3);
- }
-#endif
-
- {
- QDate dt;
- dt.setDate(1, 2, 3);
- QCOMPARE(dt.year(), 1);
- QCOMPARE(dt.month(), 2);
- QCOMPARE(dt.day(), 3);
-
- dt.setDate(0, 2, 3);
- QVERIFY(!dt.isValid());
- }
-}
-
-
-void tst_QDate::negativeYear() const
-{
- QDate y(-20, 3, 4);
- QVERIFY(y.isValid());
- QCOMPARE(y.year(), -20);
-}
-
-void tst_QDate::printNegativeYear() const
-{
- {
- QDate date(-500, 3, 4);
- QVERIFY(date.isValid());
- QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0500"));
- }
-
- {
- QDate date(-10, 3, 4);
- QVERIFY(date.isValid());
- QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0010"));
- }
-
- {
- QDate date(-2, 3, 4);
- QVERIFY(date.isValid());
- QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0002"));
- }
-}
-
-void tst_QDate::roundtripGermanLocale() const
-{
- /* This code path should not result in warnings. */
- const QDate theDate(QDate::currentDate());
- theDate.fromString(theDate.toString(Qt::TextDate), Qt::TextDate);
-
- const QDateTime theDateTime(QDateTime::currentDateTime());
- theDateTime.fromString(theDateTime.toString(Qt::TextDate), Qt::TextDate);
-}
-
-void tst_QDate::shortDayName() const
-{
- QCOMPARE(QDate::shortDayName(0), QString());
- QCOMPARE(QDate::shortDayName(8), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::shortDayName(1), QLatin1String("Mon"));
- QCOMPARE(QDate::shortDayName(7), QLatin1String("Sun"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 7; ++i) {
- QCOMPARE(QDate::shortDayName(i), locale.dayName(i, QLocale::ShortFormat));
- }
-}
-
-void tst_QDate::standaloneShortDayName() const
-{
- QCOMPARE(QDate::shortDayName(0, QDate::StandaloneFormat), QString());
- QCOMPARE(QDate::shortDayName(8, QDate::StandaloneFormat), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::shortDayName(1, QDate::StandaloneFormat), QLatin1String("Mon"));
- QCOMPARE(QDate::shortDayName(7, QDate::StandaloneFormat), QLatin1String("Sun"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 7; ++i) {
- QCOMPARE(QDate::shortDayName(i, QDate::StandaloneFormat), locale.standaloneDayName(i, QLocale::ShortFormat));
- }
-}
-
-void tst_QDate::longDayName() const
-{
- QCOMPARE(QDate::longDayName(0), QString());
- QCOMPARE(QDate::longDayName(8), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::longDayName(1), QLatin1String("Monday"));
- QCOMPARE(QDate::longDayName(7), QLatin1String("Sunday"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 7; ++i) {
- QCOMPARE(QDate::longDayName(i), locale.dayName(i, QLocale::LongFormat));
- }
-}
-
-void tst_QDate::standaloneLongDayName() const
-{
- QCOMPARE(QDate::longDayName(0, QDate::StandaloneFormat), QString());
- QCOMPARE(QDate::longDayName(8, QDate::StandaloneFormat), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::longDayName(1, QDate::StandaloneFormat), QLatin1String("Monday"));
- QCOMPARE(QDate::longDayName(7, QDate::StandaloneFormat), QLatin1String("Sunday"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 7; ++i) {
- QCOMPARE(QDate::longDayName(i, QDate::StandaloneFormat), locale.standaloneDayName(i, QLocale::LongFormat));
- }
-}
-
-void tst_QDate::shortMonthName() const
-{
- QCOMPARE(QDate::shortMonthName(0), QString());
- QCOMPARE(QDate::shortMonthName(13), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::shortMonthName(1), QLatin1String("Jan"));
- QCOMPARE(QDate::shortMonthName(8), QLatin1String("Aug"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 12; ++i) {
- QCOMPARE(QDate::shortMonthName(i), locale.monthName(i, QLocale::ShortFormat));
- }
-}
-
-void tst_QDate::standaloneShortMonthName() const
-{
- QCOMPARE(QDate::shortMonthName(0, QDate::StandaloneFormat), QString());
- QCOMPARE(QDate::shortMonthName(13, QDate::StandaloneFormat), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::shortMonthName(1, QDate::StandaloneFormat), QLatin1String("Jan"));
- QCOMPARE(QDate::shortMonthName(8, QDate::StandaloneFormat), QLatin1String("Aug"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 12; ++i) {
- QCOMPARE(QDate::shortMonthName(i, QDate::StandaloneFormat), locale.standaloneMonthName(i, QLocale::ShortFormat));
- }
-}
-
-void tst_QDate::longMonthName() const
-{
- QCOMPARE(QDate::longMonthName(0), QString());
- QCOMPARE(QDate::longMonthName(13), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::longMonthName(1), QLatin1String("January"));
- QCOMPARE(QDate::longMonthName(8), QLatin1String("August"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 12; ++i) {
- QCOMPARE(QDate::longMonthName(i), locale.monthName(i, QLocale::LongFormat));
- }
-}
-
-void tst_QDate::standaloneLongMonthName() const
-{
- QCOMPARE(QDate::longMonthName(0, QDate::StandaloneFormat), QString());
- QCOMPARE(QDate::longMonthName(13, QDate::StandaloneFormat), QString());
-
- if (QLocale::system().language() == QLocale::C) {
- QCOMPARE(QDate::longMonthName(1, QDate::StandaloneFormat), QLatin1String("January"));
- QCOMPARE(QDate::longMonthName(8, QDate::StandaloneFormat), QLatin1String("August"));
- }
-
- QLocale locale = QLocale::system();
- for(int i = 1; i <= 12; ++i) {
- QCOMPARE(QDate::longMonthName(i, QDate::StandaloneFormat), locale.standaloneMonthName(i, QLocale::LongFormat));
- }
-}
-
-void tst_QDate::roundtrip() const
-{
- // Test round trip, this exercises setDate(), isValid(), isLeapYear(),
- // year(), month(), day(), julianDayFromDate(), and getDateFromJulianDay()
- // to ensure they are internally consistent (but doesn't guarantee correct)
-
- // Test Julian round trip around JD 0 and the c++ integer division rounding
- // problem point (eg. negative numbers) in the conversion functions.
- QDate testDate;
- QDate loopDate = QDate::fromJulianDay(-50001); // 1 Jan 4850 BC
- while (loopDate.toJulianDay() <= 5150) { // 31 Dec 4700 BC
- testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
- QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
- loopDate = loopDate.addDays(1);
- }
-
- // Test Julian round trip in both BC and AD
- loopDate = QDate::fromJulianDay(1684901); // 1 Jan 100 BC
- while (loopDate.toJulianDay() <= 1757949) { // 31 Dec 100 AD
- testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
- QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
- loopDate = loopDate.addDays(1);
- }
-
- // Test Gregorian round trip during current useful period
- loopDate = QDate::fromJulianDay(2378497); // 1 Jan 1900 AD
- while (loopDate.toJulianDay() <= 2488433) { // 31 Dec 2100 AD
- testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
- QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
- loopDate = loopDate.addDays(1);
- }
-
- // Test Gregorian round trip at top end of widget/format range
- loopDate = QDate::fromJulianDay(5336961); // 1 Jan 9900 AD
- while (loopDate.toJulianDay() <= 5373484) { // 31 Dec 9999 AD
- testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
- QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
- loopDate = loopDate.addDays(1);
- }
-
- qint64 minJd = Q_INT64_C(-784350574879);
- qint64 maxJd = Q_INT64_C( 784354017364);
-
- // Test Gregorian round trip at top end of conversion range
- loopDate = QDate::fromJulianDay(maxJd);
- while (loopDate.toJulianDay() >= maxJd - 146397) {
- testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
- QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
- loopDate = loopDate.addDays(-1);
- }
-
- // Test Gregorian round trip at low end of conversion range
- loopDate = QDate::fromJulianDay(minJd);
- while (loopDate.toJulianDay() <= minJd + 146397) {
- testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day());
- QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay());
- loopDate = loopDate.addDays(1);
- }
-}
-
-void tst_QDate::qdebug() const
-{
- QTest::ignoreMessage(QtDebugMsg, "QDate(Invalid)");
- qDebug() << QDate();
- QTest::ignoreMessage(QtDebugMsg, "QDate(\"1983-08-07\")");
- qDebug() << QDate(1983, 8, 7);
-}
-
-QTEST_APPLESS_MAIN(tst_QDate)
-#include "tst_qdate.moc"
diff --git a/tests/auto/corelib/tools/qdatetime/BLACKLIST b/tests/auto/corelib/tools/qdatetime/BLACKLIST
deleted file mode 100644
index 3a42ee066b..0000000000
--- a/tests/auto/corelib/tools/qdatetime/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[timeZoneAbbreviation]
-osx
diff --git a/tests/auto/corelib/tools/qdatetime/qdatetime.pro b/tests/auto/corelib/tools/qdatetime/qdatetime.pro
deleted file mode 100644
index 742eb47075..0000000000
--- a/tests/auto/corelib/tools/qdatetime/qdatetime.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qdatetime
-QT = core-private testlib
-SOURCES = tst_qdatetime.cpp
-
-# For some reason using optimization here triggers a compiler issue, which causes an exception
-# However, the code is correct
-msvc {
- !build_pass:message ( "Compiler issue, removing -O1 flag" )
- QMAKE_CFLAGS_RELEASE -= -O1
- QMAKE_CXXFLAGS_RELEASE -= -O1
-}
-
-mac {
- OBJECTIVE_SOURCES += tst_qdatetime_mac.mm
- LIBS += -framework Foundation
-}
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
deleted file mode 100644
index b128ccebc5..0000000000
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ /dev/null
@@ -1,3508 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <time.h>
-#include <qdatetime.h>
-#include <private/qdatetime_p.h>
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-# include <locale.h>
-#endif
-
-#ifdef Q_OS_WIN
-# include <qt_windows.h>
-# if defined(Q_OS_WINRT)
-# define tzset()
-# endif
-#endif
-
-class tst_QDateTime : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QDateTime();
-
- static QString str( int y, int month, int d, int h, int min, int s );
- static QDateTime dt( const QString& str );
-public slots:
- void initTestCase();
- void init();
-private slots:
- void ctor();
- void operator_eq();
- void isNull();
- void isValid();
- void date();
- void time();
- void timeSpec();
- void toSecsSinceEpoch_data();
- void toSecsSinceEpoch();
- void daylightSavingsTimeChange_data();
- void daylightSavingsTimeChange();
- void springForward_data();
- void springForward();
- void setDate();
- void setTime_data();
- void setTime();
- void setTimeSpec_data();
- void setTimeSpec();
- void setSecsSinceEpoch();
- void setMSecsSinceEpoch_data();
- void setMSecsSinceEpoch();
- void fromMSecsSinceEpoch_data();
- void fromMSecsSinceEpoch();
- void toString_isoDate_data();
- void toString_isoDate();
- void toString_isoDate_extra();
- void toString_textDate_data();
- void toString_textDate();
- void toString_textDate_extra();
- void toString_rfcDate_data();
- void toString_rfcDate();
- void toString_enumformat();
- void toString_strformat();
- void addDays();
- void addMonths();
- void addMonths_data();
- void addYears();
- void addYears_data();
- void addSecs_data();
- void addSecs();
- void addMSecs_data();
- void addMSecs();
- void toTimeSpec_data();
- void toTimeSpec();
- void toLocalTime_data();
- void toLocalTime();
- void toUTC_data();
- void toUTC();
- void daysTo();
- void secsTo_data();
- void secsTo();
- void msecsTo_data();
- void msecsTo();
- void operator_eqeq_data();
- void operator_eqeq();
- void operator_insert_extract_data();
- void operator_insert_extract();
- void currentDateTime();
- void currentDateTimeUtc();
- void currentDateTimeUtc2();
- void fromStringDateFormat_data();
- void fromStringDateFormat();
- void fromStringStringFormat_data();
- void fromStringStringFormat();
- void fromStringStringFormatLocale_data();
- void fromStringStringFormatLocale();
-#ifdef Q_OS_WIN
- void fromString_LOCALE_ILDATE();
-#endif
- void fromStringToStringLocale_data();
- void fromStringToStringLocale();
-
- void offsetFromUtc();
- void setOffsetFromUtc();
- void toOffsetFromUtc();
-
- void zoneAtTime_data();
- void zoneAtTime();
- void timeZoneAbbreviation();
-
- void getDate();
-
- void fewDigitsInYear() const;
- void printNegativeYear() const;
- void roundtripGermanLocale() const;
- void utcOffsetLessThan() const;
-
- void isDaylightTime() const;
- void daylightTransitions() const;
- void timeZones() const;
-#if defined(Q_OS_UNIX)
- void systemTimeZoneChange() const;
-#endif
-
- void invalid() const;
-
- void macTypes();
-
-private:
- enum { LocalTimeIsUtc = 0, LocalTimeAheadOfUtc = 1, LocalTimeBehindUtc = -1} localTimeType;
- bool zoneIsCET;
- QDate defDate() const { return QDate(1900, 1, 1); }
- QTime defTime() const { return QTime(0, 0, 0); }
- QDateTime defDateTime() const { return QDateTime(defDate(), defTime()); }
- QDateTime invalidDateTime() const { return QDateTime(invalidDate(), invalidTime()); }
- QDate invalidDate() const { return QDate(); }
- QTime invalidTime() const { return QTime(-1, -1, -1); }
-
- class TimeZoneRollback
- {
- const QByteArray prior;
- public:
- // Save the previous timezone so we can restore it afterwards, otherwise
- // later tests may break:
- explicit TimeZoneRollback(const QByteArray &zone) : prior(qgetenv("TZ"))
- { reset(zone); }
- void reset(const QByteArray &zone)
- {
- qputenv("TZ", zone.constData());
- tzset();
- }
- ~TimeZoneRollback()
- {
- if (prior.isNull())
- qunsetenv("TZ");
- else
- qputenv("TZ", prior.constData());
- tzset();
- }
- };
-};
-
-Q_DECLARE_METATYPE(Qt::TimeSpec)
-Q_DECLARE_METATYPE(Qt::DateFormat)
-
-tst_QDateTime::tst_QDateTime()
-{
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- // Some tests depend on C locale - BF&I it with belt *and* braces:
- qputenv("LC_ALL", "C");
- setlocale(LC_ALL, "C");
- // Need to do this as early as possible, before anything accesses the
- // QSystemLocale singleton; once it exists, there's no changing it.
-#endif // remove for ### Qt 6
-
- /*
- Due to some jurisdictions changing their zones and rules, it's possible
- for a non-CET zone to accidentally match CET at a few tested moments but
- be different a few years later or earlier. This would lead to tests
- failing if run in the partially-aliasing zone (e.g. Algeria, Lybia). So
- test thoroughly; ideally at every mid-winter or mid-summer in whose
- half-year any test below assumes zoneIsCET means what it says. (Tests at
- or near a DST transition implicate both of the half-years that meet
- there.) Years outside the 1970--2038 range, however, are likely not
- properly handled by the TZ-database; and QDateTime explicitly handles them
- differently, so don't probe them here.
- */
- const uint day = 24 * 3600; // in seconds
- zoneIsCET = (QDateTime(QDate(2038, 1, 19), QTime(4, 14, 7)).toSecsSinceEpoch() == 0x7fffffff
- // Entries a year apart robustly differ by multiples of day.
- && QDateTime(QDate(2015, 7, 1), QTime()).toSecsSinceEpoch() == 1435701600
- && QDateTime(QDate(2015, 1, 1), QTime()).toSecsSinceEpoch() == 1420066800
- && QDateTime(QDate(2013, 7, 1), QTime()).toSecsSinceEpoch() == 1372629600
- && QDateTime(QDate(2013, 1, 1), QTime()).toSecsSinceEpoch() == 1356994800
- && QDateTime(QDate(2012, 7, 1), QTime()).toSecsSinceEpoch() == 1341093600
- && QDateTime(QDate(2012, 1, 1), QTime()).toSecsSinceEpoch() == 1325372400
- && QDateTime(QDate(2008, 7, 1), QTime()).toSecsSinceEpoch() == 1214863200
- && QDateTime(QDate(2004, 1, 1), QTime()).toSecsSinceEpoch() == 1072911600
- && QDateTime(QDate(2000, 1, 1), QTime()).toSecsSinceEpoch() == 946681200
- && QDateTime(QDate(1990, 7, 1), QTime()).toSecsSinceEpoch() == 646783200
- && QDateTime(QDate(1990, 1, 1), QTime()).toSecsSinceEpoch() == 631148400
- && QDateTime(QDate(1979, 1, 1), QTime()).toSecsSinceEpoch() == 283993200
- // .toSecsSinceEpoch() returns -1 for everything before this:
- && QDateTime(QDate(1970, 1, 1), QTime(1, 0, 0)).toSecsSinceEpoch() == 0);
- // Use .toMSecsSinceEpoch() if you really need to test anything earlier.
-
- /*
- Again, rule changes can cause a TZ to look like UTC at some sample dates
- but deviate at some date relevant to a test using localTimeType. These
- tests mostly use years outside the 1970--2038 range for which TZ data is
- credible, so we can't helpfully be exhaustive. So scan a sample of years'
- starts and middles.
- */
- const int sampled = 3;
- // UTC starts of months in 2004, 2038 and 1970:
- qint64 jans[sampled] = { 12418 * day, 24837 * day, 0 };
- qint64 juls[sampled] = { 12600 * day, 25018 * day, 181 * day };
- localTimeType = LocalTimeIsUtc;
- for (int i = sampled; i-- > 0; ) {
- QDateTime jan = QDateTime::fromSecsSinceEpoch(jans[i]);
- QDateTime jul = QDateTime::fromSecsSinceEpoch(juls[i]);
- if (jan.date().year() < 1970 || jul.date().month() < 7) {
- localTimeType = LocalTimeBehindUtc;
- break;
- } else if (jan.time().hour() > 0 || jul.time().hour() > 0
- || jan.date().day() > 1 || jul.date().day() > 1) {
- localTimeType = LocalTimeAheadOfUtc;
- break;
- }
- }
- /*
- Even so, TZ=Africa/Algiers will fail fromMSecsSinceEpoch(-1) because it
- switched from WET without DST (i.e. UTC) in the late 1960s to WET with DST
- for all of 1970 - so they had a DST transition *on the epoch*. They've
- since switched to CET with no DST, making life simple; but our tests for
- mistakes around the epoch can't tell the difference between what Algeria
- really did and the symptoms we can believe a bug might produce: there's
- not much we can do about that, that wouldn't hide real bugs.
- */
-}
-
-void tst_QDateTime::initTestCase()
-{
- // Never construct a message like this in an i18n context...
- const char *typemsg1 = "exactly";
- const char *typemsg2 = "and therefore not";
- switch (localTimeType) {
- case LocalTimeIsUtc:
- break;
- case LocalTimeBehindUtc:
- typemsg1 = "behind";
- break;
- case LocalTimeAheadOfUtc:
- typemsg1 = "ahead of";
- typemsg2 = zoneIsCET ? "and is" : "but isn't";
- break;
- }
-
- qDebug() << "Current local time detected to be"
- << typemsg1
- << "UTC"
- << typemsg2
- << "the Central European timezone";
-}
-
-void tst_QDateTime::init()
-{
-#if defined(Q_OS_WIN32)
- SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
-#endif
-}
-
-QString tst_QDateTime::str( int y, int month, int d, int h, int min, int s )
-{
- return QDateTime( QDate(y, month, d), QTime(h, min, s) ).toString( Qt::ISODate );
-}
-
-QDateTime tst_QDateTime::dt( const QString& str )
-{
- if ( str == "INVALID" ) {
- return QDateTime();
- } else {
- return QDateTime::fromString( str, Qt::ISODate );
- }
-}
-
-void tst_QDateTime::ctor()
-{
- QDateTime dt1(QDate(2004, 1, 2), QTime(1, 2, 3));
- QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
- QDateTime dt2(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::LocalTime);
- QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
- QDateTime dt3(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::UTC);
- QCOMPARE(dt3.timeSpec(), Qt::UTC);
-
- QVERIFY(dt1 == dt2);
- if (zoneIsCET) {
- QVERIFY(dt1 != dt3);
- QVERIFY(dt1 < dt3);
- QVERIFY(dt1.addSecs(3600).toUTC() == dt3);
- }
-
- // Test OffsetFromUTC constructors
- QDate offsetDate(2013, 1, 1);
- QTime offsetTime(1, 2, 3);
-
- QDateTime offset1(offsetDate, offsetTime, Qt::OffsetFromUTC);
- QCOMPARE(offset1.timeSpec(), Qt::UTC);
- QCOMPARE(offset1.offsetFromUtc(), 0);
- QCOMPARE(offset1.date(), offsetDate);
- QCOMPARE(offset1.time(), offsetTime);
-
- QDateTime offset2(offsetDate, offsetTime, Qt::OffsetFromUTC, 0);
- QCOMPARE(offset2.timeSpec(), Qt::UTC);
- QCOMPARE(offset2.offsetFromUtc(), 0);
- QCOMPARE(offset2.date(), offsetDate);
- QCOMPARE(offset2.time(), offsetTime);
-
- QDateTime offset3(offsetDate, offsetTime, Qt::OffsetFromUTC, 60 * 60);
- QCOMPARE(offset3.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(offset3.offsetFromUtc(), 60 * 60);
- QCOMPARE(offset3.date(), offsetDate);
- QCOMPARE(offset3.time(), offsetTime);
-
- QDateTime offset4(offsetDate, QTime(), Qt::OffsetFromUTC, 60 * 60);
- QCOMPARE(offset4.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(offset4.offsetFromUtc(), 60 * 60);
- QCOMPARE(offset4.date(), offsetDate);
- QCOMPARE(offset4.time(), QTime(0, 0, 0));
-}
-
-void tst_QDateTime::operator_eq()
-{
- QDateTime dt1(QDate(2004, 3, 24), QTime(23, 45, 57), Qt::UTC);
- QDateTime dt2(QDate(2005, 3, 11), QTime(), Qt::UTC);
- dt2 = dt1;
- QVERIFY(dt1 == dt2);
-}
-
-void tst_QDateTime::isNull()
-{
- QDateTime dt1;
- QVERIFY(dt1.isNull());
- dt1.setDate(QDate());
- QVERIFY(dt1.isNull());
- dt1.setTime(QTime());
- QVERIFY(dt1.isNull());
- dt1.setTimeSpec(Qt::UTC);
- QVERIFY(dt1.isNull()); // maybe it should return false?
-
- dt1.setDate(QDate(2004, 1, 2));
- QVERIFY(!dt1.isNull());
- dt1.setTime(QTime(12, 34, 56));
- QVERIFY(!dt1.isNull());
- dt1.setTime(QTime());
- QVERIFY(!dt1.isNull());
-}
-
-void tst_QDateTime::isValid()
-{
- QDateTime dt1;
- QVERIFY(!dt1.isValid());
- dt1.setDate(QDate());
- QVERIFY(!dt1.isValid());
- dt1.setTime(QTime());
- QVERIFY(!dt1.isValid());
- dt1.setTimeSpec(Qt::UTC);
- QVERIFY(!dt1.isValid());
-
- dt1.setDate(QDate(2004, 1, 2));
- QVERIFY(dt1.isValid());
- dt1.setDate(QDate());
- QVERIFY(!dt1.isValid());
- dt1.setTime(QTime(12, 34, 56));
- QVERIFY(!dt1.isValid());
- dt1.setTime(QTime());
- QVERIFY(!dt1.isValid());
-}
-
-void tst_QDateTime::date()
-{
- QDateTime dt1(QDate(2004, 3, 24), QTime(23, 45, 57), Qt::LocalTime);
- QCOMPARE(dt1.date(), QDate(2004, 3, 24));
-
- QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::LocalTime);
- QCOMPARE(dt2.date(), QDate(2004, 3, 25));
-
- QDateTime dt3(QDate(2004, 3, 24), QTime(23, 45, 57), Qt::UTC);
- QCOMPARE(dt3.date(), QDate(2004, 3, 24));
-
- QDateTime dt4(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC);
- QCOMPARE(dt4.date(), QDate(2004, 3, 25));
-}
-
-void tst_QDateTime::time()
-{
- QDateTime dt1(QDate(2004, 3, 24), QTime(23, 45, 57), Qt::LocalTime);
- QCOMPARE(dt1.time(), QTime(23, 45, 57));
-
- QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::LocalTime);
- QCOMPARE(dt2.time(), QTime(0, 45, 57));
-
- QDateTime dt3(QDate(2004, 3, 24), QTime(23, 45, 57), Qt::UTC);
- QCOMPARE(dt3.time(), QTime(23, 45, 57));
-
- QDateTime dt4(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC);
- QCOMPARE(dt4.time(), QTime(0, 45, 57));
-}
-
-void tst_QDateTime::timeSpec()
-{
- QDateTime dt1(QDate(2004, 1, 24), QTime(23, 45, 57));
- QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.addDays(0).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.addMonths(0).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.addMonths(6).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.addYears(0).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.addSecs(0).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.addSecs(86400 * 185).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.toTimeSpec(Qt::LocalTime).timeSpec(), Qt::LocalTime);
- QCOMPARE(dt1.toTimeSpec(Qt::UTC).timeSpec(), Qt::UTC);
-
- QDateTime dt2(QDate(2004, 1, 24), QTime(23, 45, 57), Qt::LocalTime);
- QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
-
- QDateTime dt3(QDate(2004, 1, 25), QTime(0, 45, 57), Qt::UTC);
- QCOMPARE(dt3.timeSpec(), Qt::UTC);
-
- QDateTime dt4 = QDateTime::currentDateTime();
- QCOMPARE(dt4.timeSpec(), Qt::LocalTime);
-}
-
-void tst_QDateTime::setDate()
-{
- QDateTime dt1(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC);
- dt1.setDate(QDate(2004, 6, 25));
- QCOMPARE(dt1.date(), QDate(2004, 6, 25));
- QCOMPARE(dt1.time(), QTime(0, 45, 57));
- QCOMPARE(dt1.timeSpec(), Qt::UTC);
-
- QDateTime dt2(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::LocalTime);
- dt2.setDate(QDate(2004, 6, 25));
- QCOMPARE(dt2.date(), QDate(2004, 6, 25));
- QCOMPARE(dt2.time(), QTime(0, 45, 57));
- QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
-
- QDateTime dt3(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::UTC);
- dt3.setDate(QDate(4004, 6, 25));
- QCOMPARE(dt3.date(), QDate(4004, 6, 25));
- QCOMPARE(dt3.time(), QTime(0, 45, 57));
- QCOMPARE(dt3.timeSpec(), Qt::UTC);
-
- QDateTime dt4(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::LocalTime);
- dt4.setDate(QDate(4004, 6, 25));
- QCOMPARE(dt4.date(), QDate(4004, 6, 25));
- QCOMPARE(dt4.time(), QTime(0, 45, 57));
- QCOMPARE(dt4.timeSpec(), Qt::LocalTime);
-
- QDateTime dt5(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::UTC);
- dt5.setDate(QDate(1760, 6, 25));
- QCOMPARE(dt5.date(), QDate(1760, 6, 25));
- QCOMPARE(dt5.time(), QTime(0, 45, 57));
- QCOMPARE(dt5.timeSpec(), Qt::UTC);
-
- QDateTime dt6(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::LocalTime);
- dt6.setDate(QDate(1760, 6, 25));
- QCOMPARE(dt6.date(), QDate(1760, 6, 25));
- QCOMPARE(dt6.time(), QTime(0, 45, 57));
- QCOMPARE(dt6.timeSpec(), Qt::LocalTime);
-}
-
-void tst_QDateTime::setTime_data()
-{
- QTest::addColumn<QDateTime>("dateTime");
- QTest::addColumn<QTime>("newTime");
-
- QTest::newRow("data0") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << QTime(23, 11, 22);
- QTest::newRow("data1") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::LocalTime) << QTime(23, 11, 22);
- QTest::newRow("data2") << QDateTime(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::UTC) << QTime(23, 11, 22);
- QTest::newRow("data3") << QDateTime(QDate(4004, 3, 25), QTime(0, 45, 57), Qt::LocalTime) << QTime(23, 11, 22);
- QTest::newRow("data4") << QDateTime(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::UTC) << QTime(23, 11, 22);
- QTest::newRow("data5") << QDateTime(QDate(1760, 3, 25), QTime(0, 45, 57), Qt::LocalTime) << QTime(23, 11, 22);
-
- QTest::newRow("set on std/dst") << QDateTime::currentDateTime() << QTime(23, 11, 22);
-}
-
-void tst_QDateTime::setTime()
-{
- QFETCH(QDateTime, dateTime);
- QFETCH(QTime, newTime);
-
- const QDate expectedDate(dateTime.date());
- const Qt::TimeSpec expectedTimeSpec(dateTime.timeSpec());
-
- dateTime.setTime(newTime);
-
- QCOMPARE(dateTime.date(), expectedDate);
- QCOMPARE(dateTime.time(), newTime);
- QCOMPARE(dateTime.timeSpec(), expectedTimeSpec);
-}
-
-void tst_QDateTime::setTimeSpec_data()
-{
- QTest::addColumn<QDateTime>("dateTime");
- QTest::addColumn<Qt::TimeSpec>("newTimeSpec");
-
- QTest::newRow("UTC => UTC") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << Qt::UTC;
- QTest::newRow("UTC => LocalTime") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << Qt::LocalTime;
- QTest::newRow("UTC => OffsetFromUTC") << QDateTime(QDate(2004, 3, 25), QTime(0, 45, 57), Qt::UTC) << Qt::OffsetFromUTC;
-}
-
-void tst_QDateTime::setTimeSpec()
-{
- QFETCH(QDateTime, dateTime);
- QFETCH(Qt::TimeSpec, newTimeSpec);
-
- const QDate expectedDate(dateTime.date());
- const QTime expectedTime(dateTime.time());
-
- dateTime.setTimeSpec(newTimeSpec);
-
- QCOMPARE(dateTime.date(), expectedDate);
- QCOMPARE(dateTime.time(), expectedTime);
- if (newTimeSpec == Qt::OffsetFromUTC)
- QCOMPARE(dateTime.timeSpec(), Qt::UTC);
- else
- QCOMPARE(dateTime.timeSpec(), newTimeSpec);
-}
-
-void tst_QDateTime::setSecsSinceEpoch()
-{
- QDateTime dt1;
- dt1.setSecsSinceEpoch(0);
- QCOMPARE(dt1.toUTC(), QDateTime(QDate(1970, 1, 1), QTime(), Qt::UTC));
- QCOMPARE(dt1.timeSpec(), Qt::LocalTime);
-
- dt1.setTimeSpec(Qt::UTC);
- dt1.setSecsSinceEpoch(0);
- QCOMPARE(dt1, QDateTime(QDate(1970, 1, 1), QTime(), Qt::UTC));
- QCOMPARE(dt1.timeSpec(), Qt::UTC);
-
- dt1.setSecsSinceEpoch(123456);
- QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), Qt::UTC));
- if (zoneIsCET) {
- QDateTime dt2;
- dt2.setSecsSinceEpoch(123456);
- QCOMPARE(dt2, QDateTime(QDate(1970, 1, 2), QTime(11, 17, 36), Qt::LocalTime));
- }
-
- dt1.setSecsSinceEpoch((uint)(quint32)-123456);
- QCOMPARE(dt1, QDateTime(QDate(2106, 2, 5), QTime(20, 10, 40), Qt::UTC));
- if (zoneIsCET) {
- QDateTime dt2;
- dt2.setSecsSinceEpoch((uint)(quint32)-123456);
- QCOMPARE(dt2, QDateTime(QDate(2106, 2, 5), QTime(21, 10, 40), Qt::LocalTime));
- }
-
- dt1.setSecsSinceEpoch(1214567890);
- QCOMPARE(dt1, QDateTime(QDate(2008, 6, 27), QTime(11, 58, 10), Qt::UTC));
- if (zoneIsCET) {
- QDateTime dt2;
- dt2.setSecsSinceEpoch(1214567890);
- QCOMPARE(dt2, QDateTime(QDate(2008, 6, 27), QTime(13, 58, 10), Qt::LocalTime));
- }
-
- dt1.setSecsSinceEpoch(0x7FFFFFFF);
- QCOMPARE(dt1, QDateTime(QDate(2038, 1, 19), QTime(3, 14, 7), Qt::UTC));
- if (zoneIsCET) {
- QDateTime dt2;
- dt2.setSecsSinceEpoch(0x7FFFFFFF);
- QCOMPARE(dt2, QDateTime(QDate(2038, 1, 19), QTime(4, 14, 7), Qt::LocalTime));
- }
-
- dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 60 * 60);
- dt1.setSecsSinceEpoch(123456);
- QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), Qt::UTC));
- QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
-}
-
-void tst_QDateTime::setMSecsSinceEpoch_data()
-{
- QTest::addColumn<qint64>("msecs");
- QTest::addColumn<QDateTime>("utc");
- QTest::addColumn<QDateTime>("cet");
-
- QTest::newRow("zero")
- << Q_INT64_C(0)
- << QDateTime(QDate(1970, 1, 1), QTime(), Qt::UTC)
- << QDateTime(QDate(1970, 1, 1), QTime(1, 0));
- QTest::newRow("-1")
- << Q_INT64_C(-1)
- << QDateTime(QDate(1969, 12, 31), QTime(23, 59, 59, 999), Qt::UTC)
- << QDateTime(QDate(1970, 1, 1), QTime(0, 59, 59, 999));
- QTest::newRow("123456789")
- << Q_INT64_C(123456789)
- << QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36, 789), Qt::UTC)
- << QDateTime(QDate(1970, 1, 2), QTime(11, 17, 36, 789), Qt::LocalTime);
- QTest::newRow("-123456789")
- << Q_INT64_C(-123456789)
- << QDateTime(QDate(1969, 12, 30), QTime(13, 42, 23, 211), Qt::UTC)
- << QDateTime(QDate(1969, 12, 30), QTime(14, 42, 23, 211), Qt::LocalTime);
- QTest::newRow("non-time_t")
- << (Q_INT64_C(1000) << 32)
- << QDateTime(QDate(2106, 2, 7), QTime(6, 28, 16), Qt::UTC)
- << QDateTime(QDate(2106, 2, 7), QTime(7, 28, 16));
- QTest::newRow("very-large")
- << (Q_INT64_C(123456) << 32)
- << QDateTime(QDate(18772, 8, 15), QTime(1, 8, 14, 976), Qt::UTC)
- << QDateTime(QDate(18772, 8, 15), QTime(3, 8, 14, 976));
- QTest::newRow("old min (Tue Nov 25 00:00:00 -4714)")
- << Q_INT64_C(-210866716800000)
- << QDateTime(QDate::fromJulianDay(1), QTime(), Qt::UTC)
- << QDateTime(QDate::fromJulianDay(1), QTime(1, 0));
- QTest::newRow("old max (Tue Jun 3 21:59:59 5874898)")
- << Q_INT64_C(185331720376799999)
- << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(21, 59, 59, 999), Qt::UTC)
- << QDateTime(QDate::fromJulianDay(0x7fffffff), QTime(23, 59, 59, 999));
- QTest::newRow("min")
- // Use -max(), which is min() + 1, to simplify filtering out overflow cases:
- << -std::numeric_limits<qint64>::max()
- << QDateTime(QDate(-292275056, 5, 16), QTime(16, 47, 4, 193), Qt::UTC)
- << QDateTime(QDate(-292275056, 5, 16), QTime(17, 47, 4, 193), Qt::LocalTime);
- QTest::newRow("max")
- << std::numeric_limits<qint64>::max()
- << QDateTime(QDate(292278994, 8, 17), QTime(7, 12, 55, 807), Qt::UTC)
- << QDateTime(QDate(292278994, 8, 17), QTime(9, 12, 55, 807), Qt::LocalTime);
-}
-
-void tst_QDateTime::setMSecsSinceEpoch()
-{
- QFETCH(qint64, msecs);
- QFETCH(QDateTime, utc);
- QFETCH(QDateTime, cet);
-
- QDateTime dt;
- dt.setTimeSpec(Qt::UTC);
- dt.setMSecsSinceEpoch(msecs);
-
- QCOMPARE(dt, utc);
- QCOMPARE(dt.date(), utc.date());
- QCOMPARE(dt.time(), utc.time());
- QCOMPARE(dt.timeSpec(), Qt::UTC);
-
- {
- QDateTime dt1 = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC);
- QCOMPARE(dt1, utc);
- QCOMPARE(dt1.date(), utc.date());
- QCOMPARE(dt1.time(), utc.time());
- QCOMPARE(dt1.timeSpec(), Qt::UTC);
- }
- {
- QDateTime dt1(utc.date(), utc.time(), Qt::UTC);
- QCOMPARE(dt1, utc);
- QCOMPARE(dt1.date(), utc.date());
- QCOMPARE(dt1.time(), utc.time());
- QCOMPARE(dt1.timeSpec(), Qt::UTC);
- }
- {
- // used to fail to clear the ShortData bit, causing corruption
- QDateTime dt1 = dt.addDays(0);
- QCOMPARE(dt1, utc);
- QCOMPARE(dt1.date(), utc.date());
- QCOMPARE(dt1.time(), utc.time());
- QCOMPARE(dt1.timeSpec(), Qt::UTC);
- }
-
- if (zoneIsCET) {
- QCOMPARE(dt.toLocalTime(), cet);
-
- // Test converting from LocalTime to UTC back to LocalTime.
- QDateTime localDt;
- localDt.setTimeSpec(Qt::LocalTime);
- localDt.setMSecsSinceEpoch(msecs);
-
- // LocalTime will overflow for max
- if (msecs != std::numeric_limits<qint64>::max())
- QCOMPARE(localDt, utc);
- QCOMPARE(localDt.timeSpec(), Qt::LocalTime);
-
- // Compare result for LocalTime to TimeZone
- QTimeZone europe("Europe/Oslo");
- QDateTime dt2;
- dt2.setTimeZone(europe);
- dt2.setMSecsSinceEpoch(msecs);
- QCOMPARE(dt2.date(), cet.date());
-
- // don't compare the time if the date is too early or too late: prior
- // to 1916, timezones in Europe were not standardised and some OS APIs
- // have hard limits. Let's restrict it to the 32-bit Unix range
- if (dt2.date().year() >= 1970 && dt2.date().year() <= 2037)
- QCOMPARE(dt2.time(), cet.time());
- QCOMPARE(dt2.timeSpec(), Qt::TimeZone);
- QCOMPARE(dt2.timeZone(), europe);
- }
-
- QCOMPARE(dt.toMSecsSinceEpoch(), msecs);
-
- if (quint64(msecs / 1000) < 0xFFFFFFFF) {
- QCOMPARE(qint64(dt.toSecsSinceEpoch()), msecs / 1000);
- }
-
- QDateTime reference(QDate(1970, 1, 1), QTime(), Qt::UTC);
- QCOMPARE(dt, reference.addMSecs(msecs));
-}
-
-void tst_QDateTime::fromMSecsSinceEpoch_data()
-{
- setMSecsSinceEpoch_data();
-}
-
-void tst_QDateTime::fromMSecsSinceEpoch()
-{
- QFETCH(qint64, msecs);
- QFETCH(QDateTime, utc);
- QFETCH(QDateTime, cet);
-
- QDateTime dtLocal = QDateTime::fromMSecsSinceEpoch(msecs, Qt::LocalTime);
- QDateTime dtUtc = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC);
- QDateTime dtOffset = QDateTime::fromMSecsSinceEpoch(msecs, Qt::OffsetFromUTC, 60*60);
-
- // LocalTime will overflow for "min" or "max" tests, depending on whether
- // you're East or West of Greenwich. In UTC, we won't overflow.
- if (localTimeType == LocalTimeIsUtc
- || msecs != std::numeric_limits<qint64>::max() * localTimeType)
- QCOMPARE(dtLocal, utc);
-
- QCOMPARE(dtUtc, utc);
- QCOMPARE(dtUtc.date(), utc.date());
- QCOMPARE(dtUtc.time(), utc.time());
-
- QCOMPARE(dtOffset, utc);
- QCOMPARE(dtOffset.offsetFromUtc(), 60*60);
- // // OffsetFromUTC will overflow for max
- if (msecs != std::numeric_limits<qint64>::max())
- QCOMPARE(dtOffset.time(), utc.time().addMSecs(60*60*1000));
-
- if (zoneIsCET) {
- QCOMPARE(dtLocal.toLocalTime(), cet);
- QCOMPARE(dtUtc.toLocalTime(), cet);
- QCOMPARE(dtOffset.toLocalTime(), cet);
- }
-
- // LocalTime will overflow for max
- if (msecs != std::numeric_limits<qint64>::max())
- QCOMPARE(dtLocal.toMSecsSinceEpoch(), msecs);
- QCOMPARE(dtUtc.toMSecsSinceEpoch(), msecs);
- QCOMPARE(dtOffset.toMSecsSinceEpoch(), msecs);
-
- if (quint64(msecs / 1000) < 0xFFFFFFFF) {
- QCOMPARE(qint64(dtLocal.toSecsSinceEpoch()), msecs / 1000);
- QCOMPARE(qint64(dtUtc.toSecsSinceEpoch()), msecs / 1000);
- QCOMPARE(qint64(dtOffset.toSecsSinceEpoch()), msecs / 1000);
- }
-
- QDateTime reference(QDate(1970, 1, 1), QTime(), Qt::UTC);
- // LocalTime will overflow for max
- if (msecs != std::numeric_limits<qint64>::max())
- QCOMPARE(dtLocal, reference.addMSecs(msecs));
- QCOMPARE(dtUtc, reference.addMSecs(msecs));
- QCOMPARE(dtOffset, reference.addMSecs(msecs));
-}
-
-void tst_QDateTime::toString_isoDate_data()
-{
- QTest::addColumn<QDateTime>("datetime");
- QTest::addColumn<Qt::DateFormat>("format");
- QTest::addColumn<QString>("expected");
-
- QTest::newRow("localtime")
- << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34))
- << Qt::ISODate << QString("1978-11-09T13:28:34");
- QTest::newRow("UTC")
- << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC)
- << Qt::ISODate << QString("1978-11-09T13:28:34Z");
- QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
- dt.setOffsetFromUtc(19800);
- QTest::newRow("positive OffsetFromUTC")
- << dt << Qt::ISODate
- << QString("1978-11-09T13:28:34+05:30");
- dt.setUtcOffset(-7200);
- QTest::newRow("negative OffsetFromUTC")
- << dt << Qt::ISODate
- << QString("1978-11-09T13:28:34-02:00");
- dt.setUtcOffset(-900);
- QTest::newRow("negative non-integral OffsetFromUTC")
- << dt << Qt::ISODate
- << QString("1978-11-09T13:28:34-00:15");
- QTest::newRow("invalid")
- << QDateTime(QDate(-1, 11, 9), QTime(13, 28, 34), Qt::UTC)
- << Qt::ISODate << QString();
- QTest::newRow("without-ms")
- << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34, 20))
- << Qt::ISODate << QString("1978-11-09T13:28:34");
- QTest::newRow("with-ms")
- << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34, 20))
- << Qt::ISODateWithMs << QString("1978-11-09T13:28:34.020");
-}
-
-void tst_QDateTime::toString_isoDate()
-{
- QFETCH(QDateTime, datetime);
- QFETCH(Qt::DateFormat, format);
- QFETCH(QString, expected);
-
- QLocale oldLocale;
- QLocale::setDefault(QLocale("en_US"));
-
- QString result = datetime.toString(format);
- QCOMPARE(result, expected);
-
- QDateTime resultDatetime = QDateTime::fromString(result, format);
- // If expecting invalid result the datetime may still be valid, i.e. year < 0 or > 9999
- if (!expected.isEmpty()) {
- QEXPECT_FAIL("without-ms", "Qt::ISODate truncates milliseconds (QTBUG-56552)", Abort);
-
- QCOMPARE(resultDatetime, datetime);
- QCOMPARE(resultDatetime.date(), datetime.date());
- QCOMPARE(resultDatetime.time(), datetime.time());
- QCOMPARE(resultDatetime.timeSpec(), datetime.timeSpec());
- QCOMPARE(resultDatetime.utcOffset(), datetime.utcOffset());
- } else {
- QCOMPARE(resultDatetime, QDateTime());
- }
-
- QLocale::setDefault(oldLocale);
-}
-
-void tst_QDateTime::toString_isoDate_extra()
-{
- QDateTime dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC);
- QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T00:00:00Z"));
-#if QT_CONFIG(timezone)
- QTimeZone PST("America/Vancouver");
- if (PST.isValid()) {
- dt = QDateTime::fromMSecsSinceEpoch(0, PST);
- QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1969-12-31T16:00:00-08:00"));
- } else {
- qDebug("Missed zone test: no America/Vancouver zone available");
- }
- QTimeZone CET("Europe/Berlin");
- if (CET.isValid()) {
- dt = QDateTime::fromMSecsSinceEpoch(0, CET);
- QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T01:00:00+01:00"));
- } else {
- qDebug("Missed zone test: no Europe/Berlin zone available");
- }
-#endif // timezone
-}
-
-void tst_QDateTime::toString_textDate_data()
-{
- QTest::addColumn<QDateTime>("datetime");
- QTest::addColumn<QString>("expected");
-
- QString wednesdayJanuary = QDate::shortDayName(3) + ' ' + QDate::shortMonthName(1);
-
- QTest::newRow("localtime") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3), Qt::LocalTime)
- << wednesdayJanuary + QString(" 2 01:02:03 2013");
- QTest::newRow("utc") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3), Qt::UTC)
- << wednesdayJanuary + QString(" 2 01:02:03 2013 GMT");
- QTest::newRow("offset+") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3), Qt::OffsetFromUTC,
- 10 * 60 * 60)
- << wednesdayJanuary + QString(" 2 01:02:03 2013 GMT+1000");
- QTest::newRow("offset-") << QDateTime(QDate(2013, 1, 2), QTime(1, 2, 3), Qt::OffsetFromUTC,
- -10 * 60 * 60)
- << wednesdayJanuary + QString(" 2 01:02:03 2013 GMT-1000");
- QTest::newRow("invalid") << QDateTime()
- << QString("");
-}
-
-void tst_QDateTime::toString_textDate()
-{
- QFETCH(QDateTime, datetime);
- QFETCH(QString, expected);
-
- QString result = datetime.toString(Qt::TextDate);
- QCOMPARE(result, expected);
-
- QDateTime resultDatetime = QDateTime::fromString(result, Qt::TextDate);
- QCOMPARE(resultDatetime, datetime);
- QCOMPARE(resultDatetime.date(), datetime.date());
- QCOMPARE(resultDatetime.time(), datetime.time());
- QCOMPARE(resultDatetime.timeSpec(), datetime.timeSpec());
- QCOMPARE(resultDatetime.utcOffset(), datetime.utcOffset());
-}
-
-void tst_QDateTime::toString_textDate_extra()
-{
- QLatin1String GMT("GMT");
- QDateTime dt = QDateTime::fromMSecsSinceEpoch(0, Qt::LocalTime);
- QVERIFY(!dt.toString().endsWith(GMT));
- dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC).toLocalTime();
- QVERIFY(!dt.toString().endsWith(GMT));
- if (QTimeZone::systemTimeZone().offsetFromUtc(dt))
- QVERIFY(dt.toString() != QLatin1String("Thu Jan 1 00:00:00 1970"));
- else
- QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 00:00:00 1970"));
-#if QT_CONFIG(timezone)
-# if defined Q_OS_UNIX && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID
-# define CORRECT_ZONE_ABBREV
-# endif // QTBUG-57320, QTBUG-57298, QTBUG-68833
-
- QTimeZone PST("America/Vancouver");
- if (PST.isValid()) {
- dt = QDateTime::fromMSecsSinceEpoch(0, PST);
-# ifdef CORRECT_ZONE_ABBREV
- QCOMPARE(dt.toString(), QLatin1String("Wed Dec 31 16:00:00 1969 PST"));
-# else
- QVERIFY(dt.toString().startsWith(QLatin1String("Wed Dec 31 16:00:00 1969 ")));
-# endif
- dt = dt.toLocalTime();
- QVERIFY(!dt.toString().endsWith(GMT));
- } else {
- qDebug("Missed zone test: no America/Vancouver zone available");
- }
- QTimeZone CET("Europe/Berlin");
- if (CET.isValid()) {
- dt = QDateTime::fromMSecsSinceEpoch(0, CET);
-# ifdef CORRECT_ZONE_ABBREV
- QCOMPARE(dt.toString(), QLatin1String("Thu Jan 1 01:00:00 1970 CET"));
-# else
- QVERIFY(dt.toString().startsWith(QLatin1String("Thu Jan 1 01:00:00 1970 ")));
-# endif
- dt = dt.toLocalTime();
- QVERIFY(!dt.toString().endsWith(GMT));
- } else {
- qDebug("Missed zone test: no Europe/Berlin zone available");
- }
-#endif // timezone
- dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC);
- QVERIFY(dt.toString().endsWith(GMT));
-}
-
-void tst_QDateTime::toString_rfcDate_data()
-{
- QTest::addColumn<QDateTime>("dt");
- QTest::addColumn<QString>("formatted");
-
- if (zoneIsCET) {
- QTest::newRow("localtime")
- << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34))
- << QString("09 Nov 1978 13:28:34 +0100");
- }
- QTest::newRow("UTC")
- << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC)
- << QString("09 Nov 1978 13:28:34 +0000");
- QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34));
- dt.setUtcOffset(19800);
- QTest::newRow("positive OffsetFromUTC")
- << dt
- << QString("09 Nov 1978 13:28:34 +0530");
- dt.setUtcOffset(-7200);
- QTest::newRow("negative OffsetFromUTC")
- << dt
- << QString("09 Nov 1978 13:28:34 -0200");
- QTest::newRow("invalid")
- << QDateTime(QDate(1978, 13, 9), QTime(13, 28, 34), Qt::UTC)
- << QString();
- QTest::newRow("999 milliseconds UTC")
- << QDateTime(QDate(2000, 1, 1), QTime(13, 28, 34, 999), Qt::UTC)
- << QString("01 Jan 2000 13:28:34 +0000");
-}
-
-void tst_QDateTime::toString_rfcDate()
-{
- QFETCH(QDateTime, dt);
- QFETCH(QString, formatted);
-
- // Set to non-English locale to confirm still uses English
- QLocale oldLocale;
- QLocale::setDefault(QLocale("de_DE"));
- QCOMPARE(dt.toString(Qt::RFC2822Date), formatted);
- QLocale::setDefault(oldLocale);
-}
-
-void tst_QDateTime::toString_enumformat()
-{
- QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56));
-
-
- QString str1 = dt1.toString(Qt::TextDate);
- QVERIFY(!str1.isEmpty()); // It's locale dependent everywhere
-
- QString str2 = dt1.toString(Qt::ISODate);
- QCOMPARE(str2, QString("1995-05-20T12:34:56"));
-
- QString str3 = dt1.toString(Qt::LocalDate);
- QVERIFY(!str3.isEmpty());
- //check for date/time components in any order
- //year may be 2 or 4 digits
- QVERIFY(str3.contains("95"));
- //day and month may be in numeric or word form
- QVERIFY(str3.contains("12"));
- QVERIFY(str3.contains("34"));
- //seconds may be absent
-}
-
-void tst_QDateTime::addDays()
-{
- for (int pass = 0; pass < 2; ++pass) {
- QDateTime dt(QDate(2004, 1, 1), QTime(12, 34, 56), pass == 0 ? Qt::LocalTime : Qt::UTC);
- dt = dt.addDays(185);
- QVERIFY(dt.date().year() == 2004 && dt.date().month() == 7 && dt.date().day() == 4);
- QVERIFY(dt.time().hour() == 12 && dt.time().minute() == 34 && dt.time().second() == 56
- && dt.time().msec() == 0);
- QCOMPARE(dt.timeSpec(), (pass == 0 ? Qt::LocalTime : Qt::UTC));
-
- dt = dt.addDays(-185);
- QCOMPARE(dt.date(), QDate(2004, 1, 1));
- QCOMPARE(dt.time(), QTime(12, 34, 56));
- }
-
- QDateTime dt(QDate(1752, 9, 14), QTime(12, 34, 56));
- while (dt.date().year() < 8000) {
- int year = dt.date().year();
- if (QDate::isLeapYear(year + 1))
- dt = dt.addDays(366);
- else
- dt = dt.addDays(365);
- QCOMPARE(dt.date(), QDate(year + 1, 9, 14));
- QCOMPARE(dt.time(), QTime(12, 34, 56));
- }
-
- // Test preserves TimeSpec
- QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime dt2 = dt1.addDays(2);
- QCOMPARE(dt2.date(), QDate(2013, 1, 3));
- QCOMPARE(dt2.time(), QTime(0, 0, 0));
- QCOMPARE(dt2.timeSpec(), Qt::UTC);
-
- dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
- dt2 = dt1.addDays(2);
- QCOMPARE(dt2.date(), QDate(2013, 1, 3));
- QCOMPARE(dt2.time(), QTime(0, 0, 0));
- QCOMPARE(dt2.timeSpec(), Qt::LocalTime);
-
- dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 60*60);
- dt2 = dt1.addDays(2);
- QCOMPARE(dt2.date(), QDate(2013, 1, 3));
- QCOMPARE(dt2.time(), QTime(0, 0, 0));
- QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(dt2.offsetFromUtc(), 60 * 60);
-
- // ### test invalid QDateTime()
-}
-
-
-void tst_QDateTime::addMonths_data()
-{
- QTest::addColumn<int>("months");
- QTest::addColumn<QDate>("resultDate");
-
- QTest::newRow("-15") << -15 << QDate(2002, 10, 31);
- QTest::newRow("-14") << -14 << QDate(2002, 11, 30);
- QTest::newRow("-13") << -13 << QDate(2002, 12, 31);
- QTest::newRow("-12") << -12 << QDate(2003, 1, 31);
-
- QTest::newRow("-11") << -11 << QDate(2003, 2, 28);
- QTest::newRow("-10") << -10 << QDate(2003, 3, 31);
- QTest::newRow("-9") << -9 << QDate(2003, 4, 30);
- QTest::newRow("-8") << -8 << QDate(2003, 5, 31);
- QTest::newRow("-7") << -7 << QDate(2003, 6, 30);
- QTest::newRow("-6") << -6 << QDate(2003, 7, 31);
- QTest::newRow("-5") << -5 << QDate(2003, 8, 31);
- QTest::newRow("-4") << -4 << QDate(2003, 9, 30);
- QTest::newRow("-3") << -3 << QDate(2003, 10, 31);
- QTest::newRow("-2") << -2 << QDate(2003, 11, 30);
- QTest::newRow("-1") << -1 << QDate(2003, 12, 31);
- QTest::newRow("0") << 0 << QDate(2004, 1, 31);
- QTest::newRow("1") << 1 << QDate(2004, 2, 29);
- QTest::newRow("2") << 2 << QDate(2004, 3, 31);
- QTest::newRow("3") << 3 << QDate(2004, 4, 30);
- QTest::newRow("4") << 4 << QDate(2004, 5, 31);
- QTest::newRow("5") << 5 << QDate(2004, 6, 30);
- QTest::newRow("6") << 6 << QDate(2004, 7, 31);
- QTest::newRow("7") << 7 << QDate(2004, 8, 31);
- QTest::newRow("8") << 8 << QDate(2004, 9, 30);
- QTest::newRow("9") << 9 << QDate(2004, 10, 31);
- QTest::newRow("10") << 10 << QDate(2004, 11, 30);
- QTest::newRow("11") << 11 << QDate(2004, 12, 31);
- QTest::newRow("12") << 12 << QDate(2005, 1, 31);
- QTest::newRow("13") << 13 << QDate(2005, 2, 28);
- QTest::newRow("14") << 14 << QDate(2005, 3, 31);
- QTest::newRow("15") << 15 << QDate(2005, 4, 30);
-}
-
-void tst_QDateTime::addMonths()
-{
- QFETCH(int, months);
- QFETCH(QDate, resultDate);
-
- QDate testDate(2004, 1, 31);
- QTime testTime(12, 34, 56);
- QDateTime start(testDate, testTime);
- QDateTime end = start.addMonths(months);
- QCOMPARE(end.date(), resultDate);
- QCOMPARE(end.time(), testTime);
- QCOMPARE(end.timeSpec(), Qt::LocalTime);
-
- start = QDateTime(testDate, testTime, Qt::UTC);
- end = start.addMonths(months);
- QCOMPARE(end.date(), resultDate);
- QCOMPARE(end.time(), testTime);
- QCOMPARE(end.timeSpec(), Qt::UTC);
-
- start = QDateTime(testDate, testTime, Qt::OffsetFromUTC, 60 * 60);
- end = start.addMonths(months);
- QCOMPARE(end.date(), resultDate);
- QCOMPARE(end.time(), testTime);
- QCOMPARE(end.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(end.offsetFromUtc(), 60 * 60);
-}
-
-void tst_QDateTime::addYears_data()
-{
- QTest::addColumn<int>("years1");
- QTest::addColumn<int>("years2");
- QTest::addColumn<QDate>("startDate");
- QTest::addColumn<QDate>("resultDate");
-
- QTest::newRow("0") << 0 << 0 << QDate(1752, 9, 14) << QDate(1752, 9, 14);
- QTest::newRow("4000 - 4000") << 4000 << -4000 << QDate(1752, 9, 14) << QDate(1752, 9, 14);
- QTest::newRow("10") << 10 << 0 << QDate(1752, 9, 14) << QDate(1762, 9, 14);
- QTest::newRow("0 leap year") << 0 << 0 << QDate(1760, 2, 29) << QDate(1760, 2, 29);
- QTest::newRow("1 leap year") << 1 << 0 << QDate(1760, 2, 29) << QDate(1761, 2, 28);
- QTest::newRow("2 leap year") << 2 << 0 << QDate(1760, 2, 29) << QDate(1762, 2, 28);
- QTest::newRow("3 leap year") << 3 << 0 << QDate(1760, 2, 29) << QDate(1763, 2, 28);
- QTest::newRow("4 leap year") << 4 << 0 << QDate(1760, 2, 29) << QDate(1764, 2, 29);
-
- QTest::newRow("toNegative1") << -2000 << 0 << QDate(1752, 9, 14) << QDate(-249, 9, 14);
- QTest::newRow("toNegative2") << -1752 << 0 << QDate(1752, 9, 14) << QDate(-1, 9, 14);
- QTest::newRow("toNegative3") << -1751 << 0 << QDate(1752, 9, 14) << QDate(1, 9, 14);
- QTest::newRow("toPositive1") << 2000 << 0 << QDate(-1752, 9, 14) << QDate(249, 9, 14);
- QTest::newRow("toPositive2") << 1752 << 0 << QDate(-1752, 9, 14) << QDate(1, 9, 14);
- QTest::newRow("toPositive3") << 1751 << 0 << QDate(-1752, 9, 14) << QDate(-1, 9, 14);
-}
-
-void tst_QDateTime::addYears()
-{
- QFETCH(int, years1);
- QFETCH(int, years2);
- QFETCH(QDate, startDate);
- QFETCH(QDate, resultDate);
-
- QTime testTime(14, 25, 36);
- QDateTime start(startDate, testTime);
- QDateTime end = start.addYears(years1).addYears(years2);
- QCOMPARE(end.date(), resultDate);
- QCOMPARE(end.time(), testTime);
- QCOMPARE(end.timeSpec(), Qt::LocalTime);
-
- start = QDateTime(startDate, testTime, Qt::UTC);
- end = start.addYears(years1).addYears(years2);
- QCOMPARE(end.date(), resultDate);
- QCOMPARE(end.time(), testTime);
- QCOMPARE(end.timeSpec(), Qt::UTC);
-
- start = QDateTime(startDate, testTime, Qt::OffsetFromUTC, 60 * 60);
- end = start.addYears(years1).addYears(years2);
- QCOMPARE(end.date(), resultDate);
- QCOMPARE(end.time(), testTime);
- QCOMPARE(end.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(end.offsetFromUtc(), 60 * 60);
-}
-
-void tst_QDateTime::addSecs_data()
-{
- QTest::addColumn<QDateTime>("dt");
- QTest::addColumn<int>("nsecs");
- QTest::addColumn<QDateTime>("result");
-
- QTime standardTime(12, 34, 56);
- QTime daylightTime(13, 34, 56);
-
- QTest::newRow("utc0") << QDateTime(QDate(2004, 1, 1), standardTime, Qt::UTC) << 86400
- << QDateTime(QDate(2004, 1, 2), standardTime, Qt::UTC);
- QTest::newRow("utc1") << QDateTime(QDate(2004, 1, 1), standardTime, Qt::UTC) << (86400 * 185)
- << QDateTime(QDate(2004, 7, 4), standardTime, Qt::UTC);
- QTest::newRow("utc2") << QDateTime(QDate(2004, 1, 1), standardTime, Qt::UTC) << (86400 * 366)
- << QDateTime(QDate(2005, 1, 1), standardTime, Qt::UTC);
- QTest::newRow("utc3") << QDateTime(QDate(1760, 1, 1), standardTime, Qt::UTC) << 86400
- << QDateTime(QDate(1760, 1, 2), standardTime, Qt::UTC);
- QTest::newRow("utc4") << QDateTime(QDate(1760, 1, 1), standardTime, Qt::UTC) << (86400 * 185)
- << QDateTime(QDate(1760, 7, 4), standardTime, Qt::UTC);
- QTest::newRow("utc5") << QDateTime(QDate(1760, 1, 1), standardTime, Qt::UTC) << (86400 * 366)
- << QDateTime(QDate(1761, 1, 1), standardTime, Qt::UTC);
- QTest::newRow("utc6") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::UTC) << 86400
- << QDateTime(QDate(4000, 1, 2), standardTime, Qt::UTC);
- QTest::newRow("utc7") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::UTC) << (86400 * 185)
- << QDateTime(QDate(4000, 7, 4), standardTime, Qt::UTC);
- QTest::newRow("utc8") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::UTC) << (86400 * 366)
- << QDateTime(QDate(4001, 1, 1), standardTime, Qt::UTC);
- QTest::newRow("utc9") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::UTC) << 0
- << QDateTime(QDate(4000, 1, 1), standardTime, Qt::UTC);
-
- if (zoneIsCET) {
- QTest::newRow("cet0") << QDateTime(QDate(2004, 1, 1), standardTime, Qt::LocalTime) << 86400
- << QDateTime(QDate(2004, 1, 2), standardTime, Qt::LocalTime);
- QTest::newRow("cet1") << QDateTime(QDate(2004, 1, 1), standardTime, Qt::LocalTime) << (86400 * 185)
- << QDateTime(QDate(2004, 7, 4), daylightTime, Qt::LocalTime);
- QTest::newRow("cet2") << QDateTime(QDate(2004, 1, 1), standardTime, Qt::LocalTime) << (86400 * 366)
- << QDateTime(QDate(2005, 1, 1), standardTime, Qt::LocalTime);
- QTest::newRow("cet3") << QDateTime(QDate(1760, 1, 1), standardTime, Qt::LocalTime) << 86400
- << QDateTime(QDate(1760, 1, 2), standardTime, Qt::LocalTime);
- QTest::newRow("cet4") << QDateTime(QDate(1760, 1, 1), standardTime, Qt::LocalTime) << (86400 * 185)
- << QDateTime(QDate(1760, 7, 4), standardTime, Qt::LocalTime);
- QTest::newRow("cet5") << QDateTime(QDate(1760, 1, 1), standardTime, Qt::LocalTime) << (86400 * 366)
- << QDateTime(QDate(1761, 1, 1), standardTime, Qt::LocalTime);
- QTest::newRow("cet6") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::LocalTime) << 86400
- << QDateTime(QDate(4000, 1, 2), standardTime, Qt::LocalTime);
- QTest::newRow("cet7") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::LocalTime) << (86400 * 185)
- << QDateTime(QDate(4000, 7, 4), daylightTime, Qt::LocalTime);
- QTest::newRow("cet8") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::LocalTime) << (86400 * 366)
- << QDateTime(QDate(4001, 1, 1), standardTime, Qt::LocalTime);
- QTest::newRow("cet9") << QDateTime(QDate(4000, 1, 1), standardTime, Qt::LocalTime) << 0
- << QDateTime(QDate(4000, 1, 1), standardTime, Qt::LocalTime);
- }
-
- // Year sign change
- QTest::newRow("toNegative") << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC)
- << -1
- << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59), Qt::UTC);
- QTest::newRow("toPositive") << QDateTime(QDate(-1, 12, 31), QTime(23, 59, 59), Qt::UTC)
- << 1
- << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC);
-
- QTest::newRow("invalid") << invalidDateTime() << 1 << invalidDateTime();
-
- // Check Offset details are preserved
- QTest::newRow("offset0") << QDateTime(QDate(2013, 1, 1), QTime(1, 2, 3),
- Qt::OffsetFromUTC, 60 * 60)
- << 60 * 60
- << QDateTime(QDate(2013, 1, 1), QTime(2, 2, 3),
- Qt::OffsetFromUTC, 60 * 60);
-}
-
-void tst_QDateTime::addSecs()
-{
- QFETCH(QDateTime, dt);
- QFETCH(int, nsecs);
- QFETCH(QDateTime, result);
- QDateTime test = dt.addSecs(nsecs);
- QCOMPARE(test, result);
- QCOMPARE(test.timeSpec(), dt.timeSpec());
- if (test.timeSpec() == Qt::OffsetFromUTC)
- QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc());
- QCOMPARE(result.addSecs(-nsecs), dt);
-}
-
-void tst_QDateTime::addMSecs_data()
-{
- addSecs_data();
-}
-
-void tst_QDateTime::addMSecs()
-{
- QFETCH(QDateTime, dt);
- QFETCH(int, nsecs);
- QFETCH(QDateTime, result);
-
- QDateTime test = dt.addMSecs(qint64(nsecs) * 1000);
- QCOMPARE(test, result);
- QCOMPARE(test.timeSpec(), dt.timeSpec());
- if (test.timeSpec() == Qt::OffsetFromUTC)
- QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc());
- QCOMPARE(result.addMSecs(qint64(-nsecs) * 1000), dt);
-}
-
-void tst_QDateTime::toTimeSpec_data()
-{
- QTest::addColumn<QDateTime>("fromUtc");
- QTest::addColumn<QDateTime>("fromLocal");
-
- QTime utcTime(4, 20, 30);
- QTime localStandardTime(5, 20, 30);
- QTime localDaylightTime(6, 20, 30);
-
- QTest::newRow("winter1") << QDateTime(QDate(2004, 1, 1), utcTime, Qt::UTC)
- << QDateTime(QDate(2004, 1, 1), localStandardTime, Qt::LocalTime);
- QTest::newRow("winter2") << QDateTime(QDate(2004, 2, 29), utcTime, Qt::UTC)
- << QDateTime(QDate(2004, 2, 29), localStandardTime, Qt::LocalTime);
- QTest::newRow("winter3") << QDateTime(QDate(1760, 2, 29), utcTime, Qt::UTC)
- << QDateTime(QDate(1760, 2, 29), localStandardTime, Qt::LocalTime);
- QTest::newRow("winter4") << QDateTime(QDate(6000, 2, 29), utcTime, Qt::UTC)
- << QDateTime(QDate(6000, 2, 29), localStandardTime, Qt::LocalTime);
-
- // Test mktime boundaries (1970 - 2038) and adjustDate().
- QTest::newRow("1969/12/31 23:00 UTC")
- << QDateTime(QDate(1969, 12, 31), QTime(23, 0, 0), Qt::UTC)
- << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
- QTest::newRow("2037/12/31 23:00 UTC")
- << QDateTime(QDate(2037, 12, 31), QTime(23, 0, 0), Qt::UTC)
- << QDateTime(QDate(2038, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
-
- QTest::newRow("-271821/4/20 00:00 UTC (JavaScript min date, start of day)")
- << QDateTime(QDate(-271821, 4, 20), QTime(0, 0, 0), Qt::UTC)
- << QDateTime(QDate(-271821, 4, 20), QTime(1, 0, 0), Qt::LocalTime);
- QTest::newRow("-271821/4/20 23:00 UTC (JavaScript min date, end of day)")
- << QDateTime(QDate(-271821, 4, 20), QTime(23, 0, 0), Qt::UTC)
- << QDateTime(QDate(-271821, 4, 21), QTime(0, 0, 0), Qt::LocalTime);
-
- if (zoneIsCET) {
- QTest::newRow("summer1") << QDateTime(QDate(2004, 6, 30), utcTime, Qt::UTC)
- << QDateTime(QDate(2004, 6, 30), localDaylightTime, Qt::LocalTime);
- QTest::newRow("summer2") << QDateTime(QDate(1760, 6, 30), utcTime, Qt::UTC)
- << QDateTime(QDate(1760, 6, 30), localStandardTime, Qt::LocalTime);
- QTest::newRow("summer3") << QDateTime(QDate(4000, 6, 30), utcTime, Qt::UTC)
- << QDateTime(QDate(4000, 6, 30), localDaylightTime, Qt::LocalTime);
-
- QTest::newRow("275760/9/23 00:00 UTC (JavaScript max date, start of day)")
- << QDateTime(QDate(275760, 9, 23), QTime(0, 0, 0), Qt::UTC)
- << QDateTime(QDate(275760, 9, 23), QTime(2, 0, 0), Qt::LocalTime);
-
- QTest::newRow("275760/9/23 22:00 UTC (JavaScript max date, end of day)")
- << QDateTime(QDate(275760, 9, 23), QTime(22, 0, 0), Qt::UTC)
- << QDateTime(QDate(275760, 9, 24), QTime(0, 0, 0), Qt::LocalTime);
- }
-
- QTest::newRow("msec") << QDateTime(QDate(4000, 6, 30), utcTime.addMSecs(1), Qt::UTC)
- << QDateTime(QDate(4000, 6, 30), localDaylightTime.addMSecs(1), Qt::LocalTime);
-}
-
-void tst_QDateTime::toTimeSpec()
-{
- if (zoneIsCET) {
- QFETCH(QDateTime, fromUtc);
- QFETCH(QDateTime, fromLocal);
-
- QDateTime utcToUtc = fromUtc.toTimeSpec(Qt::UTC);
- QDateTime localToLocal = fromLocal.toTimeSpec(Qt::LocalTime);
- QDateTime utcToLocal = fromUtc.toTimeSpec(Qt::LocalTime);
- QDateTime localToUtc = fromLocal.toTimeSpec(Qt::UTC);
- QDateTime utcToOffset = fromUtc.toTimeSpec(Qt::OffsetFromUTC);
- QDateTime localToOffset = fromLocal.toTimeSpec(Qt::OffsetFromUTC);
-
- QCOMPARE(utcToUtc, fromUtc);
- QCOMPARE(utcToUtc.date(), fromUtc.date());
- QCOMPARE(utcToUtc.time(), fromUtc.time());
- QCOMPARE(utcToUtc.timeSpec(), Qt::UTC);
-
- QCOMPARE(localToLocal, fromLocal);
- QCOMPARE(localToLocal.date(), fromLocal.date());
- QCOMPARE(localToLocal.time(), fromLocal.time());
- QCOMPARE(localToLocal.timeSpec(), Qt::LocalTime);
-
- QCOMPARE(utcToLocal, fromLocal);
- QCOMPARE(utcToLocal.date(), fromLocal.date());
- QCOMPARE(utcToLocal.time(), fromLocal.time());
- QCOMPARE(utcToLocal.timeSpec(), Qt::LocalTime);
- QCOMPARE(utcToLocal.toTimeSpec(Qt::UTC), fromUtc);
-
- QCOMPARE(localToUtc, fromUtc);
- QCOMPARE(localToUtc.date(), fromUtc.date());
- QCOMPARE(localToUtc.time(), fromUtc.time());
- QCOMPARE(localToUtc.timeSpec(), Qt::UTC);
- QCOMPARE(localToUtc.toTimeSpec(Qt::LocalTime), fromLocal);
-
- QCOMPARE(utcToUtc, localToUtc);
- QCOMPARE(utcToUtc.date(), localToUtc.date());
- QCOMPARE(utcToUtc.time(), localToUtc.time());
- QCOMPARE(utcToUtc.timeSpec(), Qt::UTC);
-
- QCOMPARE(utcToLocal, localToLocal);
- QCOMPARE(utcToLocal.date(), localToLocal.date());
- QCOMPARE(utcToLocal.time(), localToLocal.time());
- QCOMPARE(utcToLocal.timeSpec(), Qt::LocalTime);
-
- // OffsetToUTC becomes UTC
- QCOMPARE(utcToOffset, fromUtc);
- QCOMPARE(utcToOffset.date(), fromUtc.date());
- QCOMPARE(utcToOffset.time(), fromUtc.time());
- QCOMPARE(utcToOffset.timeSpec(), Qt::UTC);
- QCOMPARE(utcToOffset.toTimeSpec(Qt::UTC), fromUtc);
-
- QCOMPARE(localToOffset, fromUtc);
- QCOMPARE(localToOffset.date(), fromUtc.date());
- QCOMPARE(localToOffset.time(), fromUtc.time());
- QCOMPARE(localToOffset.timeSpec(), Qt::UTC);
- QCOMPARE(localToOffset.toTimeSpec(Qt::LocalTime), fromLocal);
- } else {
- QSKIP("Not tested with timezone other than Central European (CET/CEST)");
- }
-}
-
-void tst_QDateTime::toLocalTime_data()
-{
- toTimeSpec_data();
-}
-
-void tst_QDateTime::toLocalTime()
-{
- if (zoneIsCET) {
- QFETCH(QDateTime, fromUtc);
- QFETCH(QDateTime, fromLocal);
-
- QCOMPARE(fromLocal.toLocalTime(), fromLocal);
- QCOMPARE(fromUtc.toLocalTime(), fromLocal);
- QCOMPARE(fromUtc.toLocalTime(), fromLocal.toLocalTime());
- } else {
- QSKIP("Not tested with timezone other than Central European (CET/CEST)");
- }
-}
-
-void tst_QDateTime::toUTC_data()
-{
- toTimeSpec_data();
-}
-
-void tst_QDateTime::toUTC()
-{
- if (zoneIsCET) {
- QFETCH(QDateTime, fromUtc);
- QFETCH(QDateTime, fromLocal);
-
- QCOMPARE(fromUtc.toUTC(), fromUtc);
- QCOMPARE(fromLocal.toUTC(), fromUtc);
- QCOMPARE(fromUtc.toUTC(), fromLocal.toUTC());
- } else {
- QSKIP("Not tested with timezone other than Central European (CET/CEST)");
- }
-
- QDateTime dt = QDateTime::currentDateTime();
- if(dt.time().msec() == 0){
- dt.setTime(dt.time().addMSecs(1));
- }
- QString s = dt.toString("zzz");
- QString t = dt.toUTC().toString("zzz");
- QCOMPARE(s, t);
-}
-
-void tst_QDateTime::daysTo()
-{
- QDateTime dt1(QDate(1760, 1, 2), QTime());
- QDateTime dt2(QDate(1760, 2, 2), QTime());
- QDateTime dt3(QDate(1760, 3, 2), QTime());
-
- QCOMPARE(dt1.daysTo(dt2), (qint64) 31);
- QCOMPARE(dt1.addDays(31), dt2);
-
- QCOMPARE(dt2.daysTo(dt3), (qint64) 29);
- QCOMPARE(dt2.addDays(29), dt3);
-
- QCOMPARE(dt1.daysTo(dt3), (qint64) 60);
- QCOMPARE(dt1.addDays(60), dt3);
-
- QCOMPARE(dt2.daysTo(dt1), (qint64) -31);
- QCOMPARE(dt2.addDays(-31), dt1);
-
- QCOMPARE(dt3.daysTo(dt2), (qint64) -29);
- QCOMPARE(dt3.addDays(-29), dt2);
-
- QCOMPARE(dt3.daysTo(dt1), (qint64) -60);
- QCOMPARE(dt3.addDays(-60), dt1);
-}
-
-void tst_QDateTime::secsTo_data()
-{
- addSecs_data();
-
- QTest::newRow("disregard milliseconds #1")
- << QDateTime(QDate(2012, 3, 7), QTime(0, 58, 0, 0)) << 60
- << QDateTime(QDate(2012, 3, 7), QTime(0, 59, 0, 400));
-
- QTest::newRow("disregard milliseconds #2")
- << QDateTime(QDate(2012, 3, 7), QTime(0, 59, 0, 0)) << 60
- << QDateTime(QDate(2012, 3, 7), QTime(1, 0, 0, 400));
-}
-
-void tst_QDateTime::secsTo()
-{
- QFETCH(QDateTime, dt);
- QFETCH(int, nsecs);
- QFETCH(QDateTime, result);
-
- if (dt.isValid()) {
- QCOMPARE(dt.secsTo(result), (qint64)nsecs);
- QCOMPARE(result.secsTo(dt), (qint64)-nsecs);
- QVERIFY((dt == result) == (0 == nsecs));
- QVERIFY((dt != result) == (0 != nsecs));
- QVERIFY((dt < result) == (0 < nsecs));
- QVERIFY((dt <= result) == (0 <= nsecs));
- QVERIFY((dt > result) == (0 > nsecs));
- QVERIFY((dt >= result) == (0 >= nsecs));
- } else {
- QVERIFY(dt.secsTo(result) == 0);
- QVERIFY(result.secsTo(dt) == 0);
- }
-}
-
-void tst_QDateTime::msecsTo_data()
-{
- addMSecs_data();
-}
-
-void tst_QDateTime::msecsTo()
-{
- QFETCH(QDateTime, dt);
- QFETCH(int, nsecs);
- QFETCH(QDateTime, result);
-
- if (dt.isValid()) {
- QCOMPARE(dt.msecsTo(result), qint64(nsecs) * 1000);
- QCOMPARE(result.msecsTo(dt), -qint64(nsecs) * 1000);
- QVERIFY((dt == result) == (0 == (qint64(nsecs) * 1000)));
- QVERIFY((dt != result) == (0 != (qint64(nsecs) * 1000)));
- QVERIFY((dt < result) == (0 < (qint64(nsecs) * 1000)));
- QVERIFY((dt <= result) == (0 <= (qint64(nsecs) * 1000)));
- QVERIFY((dt > result) == (0 > (qint64(nsecs) * 1000)));
- QVERIFY((dt >= result) == (0 >= (qint64(nsecs) * 1000)));
- } else {
- QVERIFY(dt.msecsTo(result) == 0);
- QVERIFY(result.msecsTo(dt) == 0);
- }
-}
-
-void tst_QDateTime::currentDateTime()
-{
- time_t buf1, buf2;
- ::time(&buf1);
- QDateTime lowerBound;
- lowerBound.setSecsSinceEpoch(buf1);
-
- QDateTime dt1 = QDateTime::currentDateTime();
- QDateTime dt2 = QDateTime::currentDateTime().toLocalTime();
- QDateTime dt3 = QDateTime::currentDateTime().toUTC();
-
- ::time(&buf2);
-
- QDateTime upperBound;
- upperBound.setSecsSinceEpoch(buf2);
- // Note we must add 2 seconds here because time() may return up to
- // 1 second difference from the more accurate method used by QDateTime::currentDateTime()
- upperBound = upperBound.addSecs(2);
-
- QString details = QString("\n"
- "lowerBound: %1\n"
- "dt1: %2\n"
- "dt2: %3\n"
- "dt3: %4\n"
- "upperBound: %5\n")
- .arg(lowerBound.toSecsSinceEpoch())
- .arg(dt1.toSecsSinceEpoch())
- .arg(dt2.toSecsSinceEpoch())
- .arg(dt3.toSecsSinceEpoch())
- .arg(upperBound.toSecsSinceEpoch());
-
- QVERIFY2(lowerBound < upperBound, qPrintable(details));
-
- QVERIFY2(lowerBound <= dt1, qPrintable(details));
- QVERIFY2(dt1 < upperBound, qPrintable(details));
- QVERIFY2(lowerBound <= dt2, qPrintable(details));
- QVERIFY2(dt2 < upperBound, qPrintable(details));
- QVERIFY2(lowerBound <= dt3, qPrintable(details));
- QVERIFY2(dt3 < upperBound, qPrintable(details));
-
- QVERIFY(dt1.timeSpec() == Qt::LocalTime);
- QVERIFY(dt2.timeSpec() == Qt::LocalTime);
- QVERIFY(dt3.timeSpec() == Qt::UTC);
-}
-
-void tst_QDateTime::currentDateTimeUtc()
-{
- time_t buf1, buf2;
- ::time(&buf1);
-
- QDateTime lowerBound;
- lowerBound.setSecsSinceEpoch(buf1);
-
- QDateTime dt1 = QDateTime::currentDateTimeUtc();
- QDateTime dt2 = QDateTime::currentDateTimeUtc().toLocalTime();
- QDateTime dt3 = QDateTime::currentDateTimeUtc().toUTC();
-
- ::time(&buf2);
-
- QDateTime upperBound;
- upperBound.setSecsSinceEpoch(buf2);
- // Note we must add 2 seconds here because time() may return up to
- // 1 second difference from the more accurate method used by QDateTime::currentDateTime()
- upperBound = upperBound.addSecs(2);
-
- QString details = QString("\n"
- "lowerBound: %1\n"
- "dt1: %2\n"
- "dt2: %3\n"
- "dt3: %4\n"
- "upperBound: %5\n")
- .arg(lowerBound.toSecsSinceEpoch())
- .arg(dt1.toSecsSinceEpoch())
- .arg(dt2.toSecsSinceEpoch())
- .arg(dt3.toSecsSinceEpoch())
- .arg(upperBound.toSecsSinceEpoch());
-
- QVERIFY2(lowerBound < upperBound, qPrintable(details));
-
- QVERIFY2(lowerBound <= dt1, qPrintable(details));
- QVERIFY2(dt1 < upperBound, qPrintable(details));
- QVERIFY2(lowerBound <= dt2, qPrintable(details));
- QVERIFY2(dt2 < upperBound, qPrintable(details));
- QVERIFY2(lowerBound <= dt3, qPrintable(details));
- QVERIFY2(dt3 < upperBound, qPrintable(details));
-
- QVERIFY(dt1.timeSpec() == Qt::UTC);
- QVERIFY(dt2.timeSpec() == Qt::LocalTime);
- QVERIFY(dt3.timeSpec() == Qt::UTC);
-}
-
-void tst_QDateTime::currentDateTimeUtc2()
-{
- QDateTime local, utc;
- qint64 msec;
-
- // check that we got all down to the same milliseconds
- int i = 20;
- bool ok = false;
- do {
- local = QDateTime::currentDateTime();
- utc = QDateTime::currentDateTimeUtc();
- msec = QDateTime::currentMSecsSinceEpoch();
- ok = local.time().msec() == utc.time().msec()
- && utc.time().msec() == (msec % 1000);
- } while (--i && !ok);
-
- if (!i)
- QSKIP("Failed to get the dates within 1 ms of each other");
-
- // seconds and milliseconds should be the same:
- QCOMPARE(utc.time().second(), local.time().second());
- QCOMPARE(utc.time().msec(), local.time().msec());
- QCOMPARE(msec % 1000, qint64(local.time().msec()));
- QCOMPARE(msec / 1000 % 60, qint64(local.time().second()));
-
- // the two dates should be equal, actually
- QCOMPARE(local.toUTC(), utc);
- QCOMPARE(utc.toLocalTime(), local);
-
- // and finally, the SecsSinceEpoch should equal our number
- QCOMPARE(qint64(utc.toSecsSinceEpoch()), msec / 1000);
- QCOMPARE(qint64(local.toSecsSinceEpoch()), msec / 1000);
- QCOMPARE(utc.toMSecsSinceEpoch(), msec);
- QCOMPARE(local.toMSecsSinceEpoch(), msec);
-}
-
-void tst_QDateTime::toSecsSinceEpoch_data()
-{
- QTest::addColumn<QString>("dateTimeStr");
- QTest::addColumn<bool>("res");
-
- QTest::newRow( "data1" ) << str( 1800, 1, 1, 12, 0, 0 ) << false;
- QTest::newRow( "data2" ) << str( 1969, 1, 1, 12, 0, 0 ) << false;
- QTest::newRow( "data3" ) << str( 2002, 1, 1, 12, 0, 0 ) << true;
- QTest::newRow( "data4" ) << str( 2002, 6, 1, 12, 0, 0 ) << true;
- QTest::newRow( "data5" ) << QString("INVALID") << false;
- QTest::newRow( "data6" ) << str( 2038, 1, 1, 12, 0, 0 ) << true;
- QTest::newRow( "data7" ) << str( 2063, 4, 5, 12, 0, 0 ) << true; // the day of First Contact
- QTest::newRow( "data8" ) << str( 2107, 1, 1, 12, 0, 0 )
- << bool( sizeof(uint) > 32 && sizeof(time_t) > 32 );
-}
-
-void tst_QDateTime::toSecsSinceEpoch()
-{
- QFETCH( QString, dateTimeStr );
- QDateTime datetime = dt( dateTimeStr );
-
- qint64 asSecsSinceEpoch = datetime.toSecsSinceEpoch();
- uint asTime_t = datetime.toTime_t();
- QFETCH( bool, res );
- if (res) {
- QVERIFY( asTime_t != (uint)-1 );
- } else {
- QVERIFY( asTime_t == (uint)-1 );
- }
- QCOMPARE(asSecsSinceEpoch, datetime.toMSecsSinceEpoch() / 1000);
-
- if ( asTime_t != (uint) -1 ) {
- QDateTime datetime2 = QDateTime::fromTime_t( asTime_t );
- QCOMPARE(datetime, datetime2);
- }
- QDateTime datetime2 = QDateTime::fromSecsSinceEpoch(asSecsSinceEpoch);
- QCOMPARE(datetime, datetime2);
-}
-
-void tst_QDateTime::daylightSavingsTimeChange_data()
-{
- QTest::addColumn<QDate>("inDST");
- QTest::addColumn<QDate>("outDST");
- QTest::addColumn<int>("days"); // from in to out; -ve if reversed
- QTest::addColumn<int>("months");
-
- QTest::newRow("Autumn") << QDate(2006, 8, 1) << QDate(2006, 12, 1)
- << 122 << 4;
-
- QTest::newRow("Spring") << QDate(2006, 5, 1) << QDate(2006, 2, 1)
- << -89 << -3;
-}
-
-void tst_QDateTime::daylightSavingsTimeChange()
-{
- // This has grown from a regression test for an old bug where starting with
- // a date in DST and then moving to a date outside it (or vice-versa) caused
- // 1-hour jumps in time when addSecs() was called.
- //
- // The bug was caused by QDateTime knowing more than it lets show.
- // Internally, if it knows, QDateTime stores a flag indicating if the time is
- // DST or not. If it doesn't, it sets to "LocalUnknown". The problem happened
- // because some functions did not reset the flag when moving in or out of DST.
-
- // WARNING: This only tests anything if there's a Daylight Savings Time change
- // in the current locale between inDST and outDST.
- // This is true for Central European Time and may be elsewhere.
-
- QFETCH(QDate, inDST);
- QFETCH(QDate, outDST);
- QFETCH(int, days);
- QFETCH(int, months);
-
- // First with simple construction
- QDateTime dt = QDateTime(outDST, QTime(0, 0, 0), Qt::LocalTime);
- int outDSTsecs = dt.toSecsSinceEpoch();
-
- dt.setDate(inDST);
- dt = dt.addSecs(1);
- QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 1)));
-
- // now using addDays:
- dt = dt.addDays(days).addSecs(1);
- QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 2)));
-
- // ... and back again:
- dt = dt.addDays(-days).addSecs(1);
- QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 3)));
-
- // now using addMonths:
- dt = dt.addMonths(months).addSecs(1);
- QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 4)));
-
- // ... and back again:
- dt = dt.addMonths(-months).addSecs(1);
- QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 5)));
-
- // now using fromSecsSinceEpoch
- dt = QDateTime::fromSecsSinceEpoch(outDSTsecs);
- QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 0)));
-
- dt.setDate(inDST);
- dt = dt.addSecs(60);
- QCOMPARE(dt, QDateTime(inDST, QTime(0, 1, 0)));
-
- // using addMonths:
- dt = dt.addMonths(months).addSecs(60);
- QCOMPARE(dt, QDateTime(outDST, QTime(0, 2, 0)));
- // back again:
- dt = dt.addMonths(-months).addSecs(60);
- QCOMPARE(dt, QDateTime(inDST, QTime(0, 3, 0)));
-
- // using addDays:
- dt = dt.addDays(days).addSecs(60);
- QCOMPARE(dt, QDateTime(outDST, QTime(0, 4, 0)));
- // back again:
- dt = dt.addDays(-days).addSecs(60);
- QCOMPARE(dt, QDateTime(inDST, QTime(0, 5, 0)));
-
- // Now use the result of a UTC -> LocalTime conversion
- dt = QDateTime(outDST, QTime(0, 0, 0), Qt::LocalTime).toUTC();
- dt = QDateTime(dt.date(), dt.time(), Qt::UTC).toLocalTime();
- QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 0)));
-
- // using addDays:
- dt = dt.addDays(-days).addSecs(3600);
- QCOMPARE(dt, QDateTime(inDST, QTime(1, 0, 0)));
- // back again
- dt = dt.addDays(days).addSecs(3600);
- QCOMPARE(dt, QDateTime(outDST, QTime(2, 0, 0)));
-
- // using addMonths:
- dt = dt.addMonths(-months).addSecs(3600);
- QCOMPARE(dt, QDateTime(inDST, QTime(3, 0, 0)));
- // back again:
- dt = dt.addMonths(months).addSecs(3600);
- QCOMPARE(dt, QDateTime(outDST, QTime(4, 0, 0)));
-
- // using setDate:
- dt.setDate(inDST);
- dt = dt.addSecs(3600);
- QCOMPARE(dt, QDateTime(inDST, QTime(5, 0, 0)));
-}
-
-void tst_QDateTime::springForward_data()
-{
- QTest::addColumn<QDate>("day"); // day of DST transition
- QTest::addColumn<QTime>("time"); // in the "missing hour"
- QTest::addColumn<int>("step"); // days to step; +ve from before, -ve from after
- QTest::addColumn<int>("adjust"); // minutes ahead of UTC on day stepped from
-
- /*
- Zone tests compare a summer and winter moment's SecsSinceEpoch to known values.
- This could in principle be flawed (two DST-using zones in the same
- hemisphere with the same DST and standard times but different transition
- times) but no actual example is known where this is a problem. Please
- document any such conflicts, if discovered.
-
- See http://www.timeanddate.com/time/zones/ for data on more candidates to
- test.
- */
-
- uint winter = QDateTime(QDate(2015, 1, 1), QTime()).toSecsSinceEpoch();
- uint summer = QDateTime(QDate(2015, 7, 1), QTime()).toSecsSinceEpoch();
-
- if (winter == 1420066800 && summer == 1435701600) {
- QTest::newRow("CET from day before") << QDate(2015, 3, 29) << QTime(2, 30, 0) << 1 << 60;
- QTest::newRow("CET from day after") << QDate(2015, 3, 29) << QTime(2, 30, 0) << -1 << 120;
- } else if (winter == 1420063200 && summer == 1435698000) {
- // e.g. Finland, where our CI runs ...
- QTest::newRow("EET from day before") << QDate(2015, 3, 29) << QTime(3, 30, 0) << 1 << 120;
- QTest::newRow("EET from day after") << QDate(2015, 3, 29) << QTime(3, 30, 0) << -1 << 180;
- } else if (winter == 1420070400 && summer == 1435705200) {
- // Western European Time, WET/WEST; a.k.a. GMT/BST
- QTest::newRow("WET from day before") << QDate(2015, 3, 29) << QTime(1, 30, 0) << 1 << 0;
- QTest::newRow("WET from day after") << QDate(2015, 3, 29) << QTime(1, 30, 0) << -1 << 60;
- } else if (winter == 1420099200 && summer == 1435734000) {
- // Western USA, Canada: Pacific Time (e.g. US/Pacific)
- QTest::newRow("PT from day before") << QDate(2015, 3, 8) << QTime(2, 30, 0) << 1 << -480;
- QTest::newRow("PT from day after") << QDate(2015, 3, 8) << QTime(2, 30, 0) << -1 << -420;
- } else if (winter == 1420088400 && summer == 1435723200) {
- // Eastern USA, Canada: Eastern Time (e.g. US/Eastern)
- QTest::newRow("ET from day before") << QDate(2015, 3, 8) << QTime(2, 30, 0) << 1 << -300;
- QTest::newRow("ET from day after") << QDate(2015, 3, 8) << QTime(2, 30, 0) << -1 << -240;
- } else {
- // Includes the numbers you need to test for your zone, as above:
- QString msg(QString::fromLatin1("No spring forward test data for this TZ (%1, %2)"
- ).arg(winter).arg(summer));
- QSKIP(qPrintable(msg));
- }
-}
-
-void tst_QDateTime::springForward()
-{
- QFETCH(QDate, day);
- QFETCH(QTime, time);
- QFETCH(int, step);
- QFETCH(int, adjust);
-
- QDateTime direct = QDateTime(day.addDays(-step), time, Qt::LocalTime).addDays(step);
- if (direct.isValid()) { // mktime() may deem a time in the gap invalid
- QCOMPARE(direct.date(), day);
- QCOMPARE(direct.time().minute(), time.minute());
- QCOMPARE(direct.time().second(), time.second());
- int off = direct.time().hour() - time.hour();
- QVERIFY(off == 1 || off == -1);
- // Note: function doc claims always +1, but this should be reviewed !
- }
-
- // Repeat, but getting there via .toLocalTime():
- QDateTime detour = QDateTime(day.addDays(-step),
- time.addSecs(-60 * adjust),
- Qt::UTC).toLocalTime();
- QCOMPARE(detour.time(), time);
- detour = detour.addDays(step);
- // Insist on consistency:
- if (direct.isValid())
- QCOMPARE(detour, direct);
- else
- QVERIFY(!detour.isValid());
-}
-
-void tst_QDateTime::operator_eqeq_data()
-{
- QTest::addColumn<QDateTime>("dt1");
- QTest::addColumn<QDateTime>("dt2");
- QTest::addColumn<bool>("expectEqual");
- QTest::addColumn<bool>("checkEuro");
-
- QDateTime dateTime1(QDate(2012, 6, 20), QTime(14, 33, 2, 500));
- QDateTime dateTime1a = dateTime1.addMSecs(1);
- QDateTime dateTime2(QDate(2012, 20, 6), QTime(14, 33, 2, 500));
- QDateTime dateTime2a = dateTime2.addMSecs(-1);
- QDateTime dateTime3(QDate(1970, 1, 1), QTime(0, 0, 0, 0), Qt::UTC); // UTC epoch
- QDateTime dateTime3a = dateTime3.addDays(1);
- QDateTime dateTime3b = dateTime3.addDays(-1);
- // Ensure that different times may be equal when considering timezone.
- QDateTime dateTime3c(dateTime3.addSecs(3600));
- dateTime3c.setOffsetFromUtc(3600);
- QDateTime dateTime3d(dateTime3.addSecs(-3600));
- dateTime3d.setOffsetFromUtc(-3600);
- QDateTime dateTime3e(dateTime3.date(), dateTime3.time()); // Local time's epoch
-
- QTest::newRow("data0") << dateTime1 << dateTime1 << true << false;
- QTest::newRow("data1") << dateTime2 << dateTime2 << true << false;
- QTest::newRow("data2") << dateTime1a << dateTime1a << true << false;
- QTest::newRow("data3") << dateTime1 << dateTime2 << false << false;
- QTest::newRow("data4") << dateTime1 << dateTime1a << false << false;
- QTest::newRow("data5") << dateTime2 << dateTime2a << false << false;
- QTest::newRow("data6") << dateTime2 << dateTime3 << false << false;
- QTest::newRow("data7") << dateTime3 << dateTime3a << false << false;
- QTest::newRow("data8") << dateTime3 << dateTime3b << false << false;
- QTest::newRow("data9") << dateTime3a << dateTime3b << false << false;
- QTest::newRow("data10") << dateTime3 << dateTime3c << true << false;
- QTest::newRow("data11") << dateTime3 << dateTime3d << true << false;
- QTest::newRow("data12") << dateTime3c << dateTime3d << true << false;
- if (localTimeType == LocalTimeIsUtc)
- QTest::newRow("data13") << dateTime3 << dateTime3e << true << false;
- // ... but a zone (sometimes) ahead of or behind UTC (e.g. Europe/London)
- // might agree with UTC about the epoch, all the same.
-
- QTest::newRow("invalid == invalid") << invalidDateTime() << invalidDateTime() << true << false;
- QTest::newRow("invalid == valid #1") << invalidDateTime() << dateTime1 << false << false;
-
- if (zoneIsCET) {
- QTest::newRow("data14") << QDateTime(QDate(2004, 1, 2), QTime(2, 2, 3), Qt::LocalTime)
- << QDateTime(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::UTC) << true << true;
- }
-}
-
-void tst_QDateTime::operator_eqeq()
-{
- QFETCH(QDateTime, dt1);
- QFETCH(QDateTime, dt2);
- QFETCH(bool, expectEqual);
- QFETCH(bool, checkEuro);
-
- QVERIFY(dt1 == dt1);
- QVERIFY(!(dt1 != dt1));
-
- QVERIFY(dt2 == dt2);
- QVERIFY(!(dt2 != dt2));
-
- QVERIFY(dt1 != QDateTime::currentDateTime());
- QVERIFY(dt2 != QDateTime::currentDateTime());
-
- QVERIFY(dt1.toUTC() == dt1.toUTC());
-
- bool equal = dt1 == dt2;
- QCOMPARE(equal, expectEqual);
- bool notEqual = dt1 != dt2;
- QCOMPARE(notEqual, !expectEqual);
-
- if (equal)
- QVERIFY(qHash(dt1) == qHash(dt2));
-
- if (checkEuro && zoneIsCET) {
- QVERIFY(dt1.toUTC() == dt2);
- QVERIFY(dt1 == dt2.toLocalTime());
- }
-}
-
-Q_DECLARE_METATYPE(QDataStream::Version)
-
-void tst_QDateTime::operator_insert_extract_data()
-{
- QTest::addColumn<QDateTime>("dateTime");
- QTest::addColumn<QString>("serialiseAs");
- QTest::addColumn<QString>("deserialiseAs");
- QTest::addColumn<QDataStream::Version>("dataStreamVersion");
-
- const QDateTime positiveYear(QDateTime(QDate(2012, 8, 14), QTime(8, 0, 0), Qt::LocalTime));
- const QDateTime negativeYear(QDateTime(QDate(-2012, 8, 14), QTime(8, 0, 0), Qt::LocalTime));
-
- const QString westernAustralia(QString::fromLatin1("AWST-8AWDT-9,M10.5.0,M3.5.0/03:00:00"));
- const QString hawaii(QString::fromLatin1("HAW10"));
-
- const QDataStream tmpDataStream;
- const int thisVersion = tmpDataStream.version();
- for (int version = QDataStream::Qt_1_0; version <= thisVersion; ++version) {
- const QDataStream::Version dataStreamVersion = static_cast<QDataStream::Version>(version);
- const QByteArray vN = QByteArray::number(dataStreamVersion);
- const QByteArray pY = positiveYear.toString().toLatin1();
- QTest::newRow(('v' + vN + " WA => HAWAII " + pY).constData())
- << positiveYear << westernAustralia << hawaii << dataStreamVersion;
- QTest::newRow(('v' + vN + " WA => WA " + pY).constData())
- << positiveYear << westernAustralia << westernAustralia << dataStreamVersion;
- QTest::newRow(('v' + vN + " HAWAII => WA " + negativeYear.toString().toLatin1()).constData())
- << negativeYear << hawaii << westernAustralia << dataStreamVersion;
- QTest::newRow(('v' + vN + " HAWAII => HAWAII " + pY).constData())
- << positiveYear << hawaii << hawaii << dataStreamVersion;
- }
-}
-
-void tst_QDateTime::operator_insert_extract()
-{
- QFETCH(QDateTime, dateTime);
- QFETCH(QString, serialiseAs);
- QFETCH(QString, deserialiseAs);
- QFETCH(QDataStream::Version, dataStreamVersion);
-
- // Start off in a certain timezone.
- TimeZoneRollback useZone(serialiseAs.toLocal8Bit());
- QDateTime dateTimeAsUTC(dateTime.toUTC());
-
- QByteArray byteArray;
- {
- QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
- dataStream.setVersion(dataStreamVersion);
- if (dataStreamVersion == QDataStream::Qt_5_0) {
- // Qt 5 serialises as UTC and converts back to the stored timeSpec when
- // deserialising; we don't need to do it ourselves...
- dataStream << dateTime << dateTime;
- } else {
- // ... but other versions don't, so we have to here.
- dataStream << dateTimeAsUTC << dateTimeAsUTC;
- // We'll also make sure that a deserialised local datetime is the same
- // time of day (potentially different UTC time), regardless of which
- // timezone it was serialised in. E.g.: Tue Aug 14 08:00:00 2012
- // serialised in WST should be deserialised as Tue Aug 14 08:00:00 2012
- // HST.
- dataStream << dateTime;
- }
- }
-
- // Ensure that a change in timezone between serialisation and deserialisation
- // still results in identical UTC-converted datetimes.
- useZone.reset(deserialiseAs.toLocal8Bit());
- QDateTime expectedLocalTime(dateTimeAsUTC.toLocalTime());
- {
- // Deserialise whole QDateTime at once.
- QDataStream dataStream(&byteArray, QIODevice::ReadOnly);
- dataStream.setVersion(dataStreamVersion);
- QDateTime deserialised;
- dataStream >> deserialised;
-
- if (dataStreamVersion == QDataStream::Qt_5_0) {
- // Ensure local time is still correct. Again, Qt 5 handles the timeSpec
- // conversion (in this case, UTC => LocalTime) for us when deserialising.
- QCOMPARE(deserialised, expectedLocalTime);
- } else {
- if (dataStreamVersion < QDataStream::Qt_4_0) {
- // Versions lower than Qt 4 don't serialise the timeSpec, instead
- // assuming that everything is LocalTime.
- deserialised.setTimeSpec(Qt::UTC);
- }
- // Qt 4.* versions do serialise the timeSpec, so we only need to convert from UTC here.
- deserialised = deserialised.toLocalTime();
-
- QCOMPARE(deserialised, expectedLocalTime);
- }
- // Sanity check UTC times (operator== already converts its operands to UTC before comparing).
- QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
-
- // Deserialise each component individually.
- QDate deserialisedDate;
- dataStream >> deserialisedDate;
- QTime deserialisedTime;
- dataStream >> deserialisedTime;
- qint8 deserialisedSpec;
- if (dataStreamVersion >= QDataStream::Qt_4_0)
- dataStream >> deserialisedSpec;
- deserialised = QDateTime(deserialisedDate, deserialisedTime, Qt::UTC);
- if (dataStreamVersion >= QDataStream::Qt_4_0)
- deserialised = deserialised.toTimeSpec(static_cast<Qt::TimeSpec>(deserialisedSpec));
- // Ensure local time is still correct.
- QCOMPARE(deserialised, expectedLocalTime);
- // Sanity check UTC times.
- QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
-
- if (dataStreamVersion != QDataStream::Qt_5_0) {
- // Deserialised local datetime should be the same time of day,
- // regardless of which timezone it was serialised in.
- QDateTime localDeserialized;
- dataStream >> localDeserialized;
- QCOMPARE(localDeserialized, dateTime);
- }
- }
-}
-
-void tst_QDateTime::toString_strformat()
-{
- // Most tests are in QLocale, just test that the api works.
- QDate testDate(2013, 1, 1);
- QTime testTime(1, 2, 3);
- QDateTime testDateTime(testDate, testTime, Qt::UTC);
- QCOMPARE(testDate.toString("yyyy-MM-dd"), QString("2013-01-01"));
- QCOMPARE(testTime.toString("hh:mm:ss"), QString("01:02:03"));
- QCOMPARE(testDateTime.toString("yyyy-MM-dd hh:mm:ss t"), QString("2013-01-01 01:02:03 UTC"));
-}
-
-void tst_QDateTime::fromStringDateFormat_data()
-{
- QTest::addColumn<QString>("dateTimeStr");
- QTest::addColumn<Qt::DateFormat>("dateFormat");
- QTest::addColumn<QDateTime>("expected");
-
- // Test Qt::TextDate format.
- QTest::newRow("text date") << QString::fromLatin1("Tue Jun 17 08:00:10 2003")
- << Qt::TextDate << QDateTime(QDate(2003, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime);
- QTest::newRow("text date Year 0999") << QString::fromLatin1("Tue Jun 17 08:00:10 0999")
- << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime);
- QTest::newRow("text date Year 999") << QString::fromLatin1("Tue Jun 17 08:00:10 999")
- << Qt::TextDate << QDateTime(QDate(999, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime);
- QTest::newRow("text date Year 12345") << QString::fromLatin1("Tue Jun 17 08:00:10 12345")
- << Qt::TextDate << QDateTime(QDate(12345, 6, 17), QTime(8, 0, 10, 0), Qt::LocalTime);
- QTest::newRow("text date Year -4712") << QString::fromLatin1("Tue Jan 1 00:01:02 -4712")
- << Qt::TextDate << QDateTime(QDate(-4712, 1, 1), QTime(0, 1, 2, 0), Qt::LocalTime);
- QTest::newRow("text data0") << QString::fromLatin1("Thu Jan 1 00:00:00 1970")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
- QTest::newRow("text data1") << QString::fromLatin1("Thu Jan 2 12:34 1970")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 2), QTime(12, 34, 0), Qt::LocalTime);
- QTest::newRow("text data2") << QString::fromLatin1("Thu Jan 1 00 1970")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text data3") << QString::fromLatin1("Thu Jan 1 00:00:00:00 1970")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text data4") << QString::fromLatin1("Thu 1. Jan 00:00:00 1970")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::LocalTime);
- QTest::newRow("text data5") << QString::fromLatin1(" Thu Jan 1 00:00:00 1970 ")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
- QTest::newRow("text data6") << QString::fromLatin1("Thu Jan 1 00:00:00")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text data7") << QString::fromLatin1("Thu Jan 1 1970 00:00:00")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
- QTest::newRow("text data8") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+foo")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text data9") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("text data10") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT-0300")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(3, 12, 34), Qt::UTC);
- QTest::newRow("text data11") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 GMT+0300")
- << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(21, 12, 34), Qt::UTC);
- QTest::newRow("text data12") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 gmt")
- << Qt::TextDate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("text data13") << QString::fromLatin1("Thu Jan 1 1970 00:12:34 GMT+0100")
- << Qt::TextDate << QDateTime(QDate(1969, 12, 31), QTime(23, 12, 34), Qt::UTC);
- QTest::newRow("text empty") << QString::fromLatin1("")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text too many parts") << QString::fromLatin1("Thu Jan 1 00:12:34 1970 gmt +0100")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid month name") << QString::fromLatin1("Thu Jaz 1 1970 00:12:34")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid date") << QString::fromLatin1("Thu Jan 32 1970 00:12:34")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid day #1") << QString::fromLatin1("Thu Jan XX 1970 00:12:34")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid day #2") << QString::fromLatin1("Thu X. Jan 00:00:00 1970")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid day #3") << QString::fromLatin1("Thu 1 Jan 00:00:00 1970")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid year #1") << QString::fromLatin1("Thu 1. Jan 00:00:00 19X0")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid year #2") << QString::fromLatin1("Thu 1. Jan 19X0 00:00:00")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid hour") << QString::fromLatin1("Thu 1. Jan 1970 0X:00:00")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid minute") << QString::fromLatin1("Thu 1. Jan 1970 00:0X:00")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid second") << QString::fromLatin1("Thu 1. Jan 1970 00:00:0X")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid gmt specifier #1") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 DMT")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid gmt specifier #2") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMTx0200")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid gmt hour") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMT+0X00")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text invalid gmt minute") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMT+000X")
- << Qt::TextDate << invalidDateTime();
- QTest::newRow("text second fraction") << QString::fromLatin1("Mon 6. May 2013 01:02:03.456")
- << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456));
-
- // Test Qt::ISODate format.
- QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00")
- << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
- QTest::newRow("ISO +00:01") << QString::fromLatin1("1987-02-13T13:24:51+00:01")
- << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(13, 23, 51), Qt::UTC);
- QTest::newRow("ISO -01:00") << QString::fromLatin1("1987-02-13T13:24:51-01:00")
- << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
- QTest::newRow("ISO -00:01") << QString::fromLatin1("1987-02-13T13:24:51-00:01")
- << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(13, 25, 51), Qt::UTC);
- QTest::newRow("ISO +0000") << QString::fromLatin1("1970-01-01T00:12:34+0000")
- << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("ISO +00:00") << QString::fromLatin1("1970-01-01T00:12:34+00:00")
- << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("ISO -03") << QString::fromLatin1("2014-12-15T12:37:09-03")
- << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9), Qt::UTC);
- QTest::newRow("ISO zzz-03") << QString::fromLatin1("2014-12-15T12:37:09.745-03")
- << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9, 745), Qt::UTC);
- QTest::newRow("ISO -3") << QString::fromLatin1("2014-12-15T12:37:09-3")
- << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9), Qt::UTC);
- QTest::newRow("ISO zzz-3") << QString::fromLatin1("2014-12-15T12:37:09.745-3")
- << Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9, 745), Qt::UTC);
- // No time specified - defaults to Qt::LocalTime.
- QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01")
- << Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO") << QString::fromLatin1("2005-06-28T07:57:30.0010000000Z")
- << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC);
- QTest::newRow("ISO with comma 1") << QString::fromLatin1("2005-06-28T07:57:30,0040000000Z")
- << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4), Qt::UTC);
- QTest::newRow("ISO with comma 2") << QString::fromLatin1("2005-06-28T07:57:30,0015Z")
- << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC);
- QTest::newRow("ISO with comma 3") << QString::fromLatin1("2005-06-28T07:57:30,0014Z")
- << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC);
- QTest::newRow("ISO with comma 4") << QString::fromLatin1("2005-06-28T07:57:30,1Z")
- << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 100), Qt::UTC);
- QTest::newRow("ISO with comma 5") << QString::fromLatin1("2005-06-28T07:57:30,11")
- << Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 110), Qt::LocalTime);
- // 24:00:00 Should be next day according to ISO 8601 section 4.2.3.
- QTest::newRow("ISO 24:00") << QString::fromLatin1("2012-06-04T24:00:00")
- << Qt::ISODate << QDateTime(QDate(2012, 6, 5), QTime(0, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO 24:00 end of month") << QString::fromLatin1("2012-06-30T24:00:00")
- << Qt::ISODate << QDateTime(QDate(2012, 7, 1), QTime(0, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO 24:00 end of year") << QString::fromLatin1("2012-12-31T24:00:00")
- << Qt::ISODate << QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO 24:00, fract ms") << QString::fromLatin1("2012-01-01T24:00:00.000")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 2), QTime(0, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO 24:00 end of year, fract ms") << QString::fromLatin1("2012-12-31T24:00:00.000")
- << Qt::ISODate << QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0, 0), Qt::LocalTime);
- // Test fractional seconds.
- QTest::newRow("ISO .0 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.0")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO .00 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.00")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO .000 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.000")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO .1 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,1")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 100), Qt::LocalTime);
- QTest::newRow("ISO .99 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,99")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 990), Qt::LocalTime);
- QTest::newRow("ISO .998 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,998")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 998), Qt::LocalTime);
- QTest::newRow("ISO .999 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,999")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 999), Qt::LocalTime);
- QTest::newRow("ISO .3335 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,3335")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 334), Qt::LocalTime);
- QTest::newRow("ISO .333333 of a second (comma)") << QString::fromLatin1("2012-01-01T08:00:00,333333")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 333), Qt::LocalTime);
- QTest::newRow("ISO .00009 of a second (period)") << QString::fromLatin1("2012-01-01T08:00:00.00009")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO no fract specified") << QString::fromLatin1("2012-01-01T08:00:00.")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("ISO invalid character at end") << QString::fromLatin1("2012-01-01T08:00:00!")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO invalid character at front") << QString::fromLatin1("!2012-01-01T08:00:00")
- << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO invalid character both ends") << QString::fromLatin1("!2012-01-01T08:00:00!")
- << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO invalid character at front, 2 at back") << QString::fromLatin1("!2012-01-01T08:00:00..")
- << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO invalid character 2 at front") << QString::fromLatin1("!!2012-01-01T08:00:00")
- << Qt::ISODate << invalidDateTime();
- // Test fractional minutes.
- QTest::newRow("ISO .0 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.0")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO .8 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.8")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48, 0), Qt::LocalTime);
- QTest::newRow("ISO .99999 of a minute (period)") << QString::fromLatin1("2012-01-01T08:00.99999")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999), Qt::LocalTime);
- QTest::newRow("ISO .0 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,0")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 0, 0), Qt::LocalTime);
- QTest::newRow("ISO .8 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,8")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 48, 0), Qt::LocalTime);
- QTest::newRow("ISO .99999 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,99999")
- << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999), Qt::LocalTime);
- QTest::newRow("ISO empty") << QString::fromLatin1("") << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO short") << QString::fromLatin1("2017-07-01T") << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO zoned date") << QString::fromLatin1("2017-07-01Z") << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO zoned empty time") << QString::fromLatin1("2017-07-01TZ") << Qt::ISODate << invalidDateTime();
- QTest::newRow("ISO mis-punctuated") << QString::fromLatin1("2018/01/30 ") << Qt::ISODate << invalidDateTime();
-
- // Test Qt::RFC2822Date format (RFC 2822).
- QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
- QTest::newRow("RFC 2822 with day +0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
- QTest::newRow("RFC 2822 -0100") << QString::fromLatin1("13 Feb 1987 13:24:51 -0100")
- << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
- QTest::newRow("RFC 2822 with day -0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 -0100")
- << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
- QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- // No timezone assume UTC
- QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- // No time specified
- QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
- << Qt::RFC2822Date << invalidDateTime();
- // Test invalid month, day, year
- QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
- << Qt::RFC2822Date << invalidDateTime();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
- << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
- QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << invalidDateTime();
-
- // Test Qt::RFC2822Date format (RFC 850 and 1036).
- QTest::newRow("RFC 850 and 1036 +0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
- << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
- QTest::newRow("RFC 850 and 1036 -0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 -0100")
- << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC);
- QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- // No timezone assume UTC
- QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
- << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC);
- // No time specified
- QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
- << Qt::RFC2822Date << invalidDateTime();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
- << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC);
- QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
- << Qt::RFC2822Date << invalidDateTime();
- QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000")
- << Qt::RFC2822Date << invalidDateTime();
-
- QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidDateTime();
-}
-
-void tst_QDateTime::fromStringDateFormat()
-{
- QFETCH(QString, dateTimeStr);
- QFETCH(Qt::DateFormat, dateFormat);
- QFETCH(QDateTime, expected);
-
- QDateTime dateTime = QDateTime::fromString(dateTimeStr, dateFormat);
- QCOMPARE(dateTime, expected);
-}
-
-void tst_QDateTime::fromStringStringFormat_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QDateTime>("expected");
-
- QTest::newRow("data0") << QString("101010") << QString("dMyy") << QDateTime(QDate(1910, 10, 10), QTime());
- QTest::newRow("data1") << QString("1020") << QString("sss") << invalidDateTime();
- QTest::newRow("data2") << QString("1010") << QString("sss") << QDateTime(defDate(), QTime(0, 0, 10));
- QTest::newRow("data3") << QString("10hello20") << QString("ss'hello'ss") << invalidDateTime();
- QTest::newRow("data4") << QString("10") << QString("''") << invalidDateTime();
- QTest::newRow("data5") << QString("10") << QString("'") << invalidDateTime();
- QTest::newRow("data6") << QString("pm") << QString("ap") << QDateTime(defDate(), QTime(12, 0, 0));
- QTest::newRow("data7") << QString("foo") << QString("ap") << invalidDateTime();
- // Day non-conflict should not hide earlier year conflict (1963-03-01 was a
- // Friday; asking for Thursday moves this, without conflict, to the 7th):
- QTest::newRow("data8") << QString("77 03 1963 Thu") << QString("yy MM yyyy ddd") << invalidDateTime();
- QTest::newRow("data9") << QString("101010") << QString("dMyy") << QDateTime(QDate(1910, 10, 10), QTime());
- QTest::newRow("data10") << QString("101010") << QString("dMyy") << QDateTime(QDate(1910, 10, 10), QTime());
- QTest::newRow("data11") << QString("10 Oct 10") << QString("dd MMM yy") << QDateTime(QDate(1910, 10, 10), QTime());
- QTest::newRow("data12") << QString("Fri December 3 2004") << QString("ddd MMMM d yyyy") << QDateTime(QDate(2004, 12, 3), QTime());
- QTest::newRow("data13") << QString("30.02.2004") << QString("dd.MM.yyyy") << invalidDateTime();
- QTest::newRow("data14") << QString("32.01.2004") << QString("dd.MM.yyyy") << invalidDateTime();
- QTest::newRow("data15") << QString("Thu January 2004") << QString("ddd MMMM yyyy") << QDateTime(QDate(2004, 1, 1), QTime());
- QTest::newRow("data16") << QString("2005-06-28T07:57:30.001Z")
- << QString("yyyy-MM-ddThh:mm:ss.zt")
- << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 1), Qt::UTC);
-#if QT_CONFIG(timezone)
- QTimeZone southBrazil("America/Sao_Paulo");
- if (southBrazil.isValid()) {
- QTest::newRow("spring-forward-midnight")
- << QString("2008-10-19 23:45.678 America/Sao_Paulo") << QString("yyyy-MM-dd mm:ss.zzz t")
- << QDateTime(QDate(2008, 10, 19), QTime(1, 23, 45, 678), southBrazil);
- }
-#endif
- QTest::newRow("late") << QString("9999-12-31T23:59:59.999Z")
- << QString("yyyy-MM-ddThh:mm:ss.zZ")
- << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
- // Separators match /([^aAdhHMmstyz]*)/
- QTest::newRow("oddly-separated") // To show broken-separator's format is valid.
- << QStringLiteral("2018 wilful long working block relief 12-19T21:09 cruel blurb encore flux")
- << QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux")
- << QDateTime(QDate(2018, 12, 19), QTime(21, 9));
- QTest::newRow("broken-separator")
- << QStringLiteral("2018 wilful")
- << QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux")
- << invalidDateTime();
- QTest::newRow("broken-terminator")
- << QStringLiteral("2018 wilful long working block relief 12-19T21:09 cruel")
- << QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux")
- << invalidDateTime();
-}
-
-void tst_QDateTime::fromStringStringFormat()
-{
- QFETCH(QString, string);
- QFETCH(QString, format);
- QFETCH(QDateTime, expected);
-
- QDateTime dt = QDateTime::fromString(string, format);
-
- QCOMPARE(dt, expected);
-}
-
-void tst_QDateTime::fromStringStringFormatLocale_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QLocale>("locale");
- QTest::addColumn<QDateTime>("expected");
-
- QLocale c = QLocale::c();
- QDateTime dt(QDate(2017, 02, 25), QTime(17, 21, 25));
-
- // The formats correspond to the locale formats, with the timezone removed.
- // We hardcode them in case an update to the locale DB changes them.
-
- QTest::newRow("C:long") << "Saturday, 25 February 2017 17:21:25" << "dddd, d MMMM yyyy HH:mm:ss" << c << dt;
- QTest::newRow("C:short") << "25 Feb 2017 17:21:25" << "d MMM yyyy HH:mm:ss" << c << dt;
- QTest::newRow("C:narrow") << "25 Feb 2017 17:21:25" << "d MMM yyyy HH:mm:ss" << c << dt;
-
- QLocale fr(QLocale::French);
- QTest::newRow("fr:long") << "Samedi 25 février 2017 17:21:25" << "dddd d MMMM yyyy HH:mm:ss" << fr << dt;
- QTest::newRow("fr:short") << "25/02/2017 17:21" << "dd/MM/yyyy HH:mm" << fr << dt.addSecs(-25);
-
- // In Turkish, the word for Friday ("Cuma") is a prefix for the word for
- // Saturday ("Cumartesi")
- QLocale tr(QLocale::Turkish);
- QTest::newRow("tr:long") << "25 Şubat 2017 Cumartesi 17:21:25" << "d MMMM yyyy dddd HH:mm:ss" << tr << dt;
- QTest::newRow("tr:long2") << "24 Şubat 2017 Cuma 17:21:25" << "d MMMM yyyy dddd HH:mm:ss" << tr << dt.addDays(-1);
- QTest::newRow("tr:mashed") << "25 Şubat2017 Cumartesi17:21:25" << "d MMMMyyyy ddddHH:mm:ss" << tr << dt;
- QTest::newRow("tr:mashed2") << "24 Şubat2017 Cuma17:21:25" << "d MMMMyyyy ddddHH:mm:ss" << tr << dt.addDays(-1);
- QTest::newRow("tr:short") << "25.02.2017 17:21" << "d.MM.yyyy HH:mm" << tr << dt.addSecs(-25);
-}
-
-void tst_QDateTime::fromStringStringFormatLocale()
-{
- QFETCH(QString, string);
- QFETCH(QString, format);
- QFETCH(QLocale, locale);
- QFETCH(QDateTime, expected);
-
- QDateTime parsed = locale.toDateTime(string, format);
- QCOMPARE(parsed, expected);
-
- parsed = locale.toDateTime(string.toLower(), format);
- QCOMPARE(parsed, expected);
-
- parsed = locale.toDateTime(string.toUpper(), format);
- QCOMPARE(parsed, expected);
-}
-
-#ifdef Q_OS_WIN
-// Windows only
-void tst_QDateTime::fromString_LOCALE_ILDATE()
-{
- QString date1 = QLatin1String("Sun 1. Dec 13:02:00 1974");
- QString date2 = QLatin1String("Sun Dec 1 13:02:00 1974");
-
- QDateTime ref(QDate(1974, 12, 1), QTime(13, 2));
- QCOMPARE(ref, QDateTime::fromString(date2, Qt::TextDate));
- QCOMPARE(ref, QDateTime::fromString(date1, Qt::TextDate));
-}
-#endif
-
-void tst_QDateTime::fromStringToStringLocale_data()
-{
- QTest::addColumn<QDateTime>("dateTime");
-
- QTest::newRow("data0") << QDateTime(QDate(1999, 1, 18), QTime(11, 49, 00));
-}
-
-void tst_QDateTime::fromStringToStringLocale()
-{
- QFETCH(QDateTime, dateTime);
-
- QLocale def;
- QLocale::setDefault(QLocale(QLocale::French, QLocale::France));
-#define ROUNDTRIP(format) \
- QCOMPARE(QDateTime::fromString(dateTime.toString(format), format), dateTime)
-
- ROUNDTRIP(Qt::DefaultLocaleShortDate);
- ROUNDTRIP(Qt::SystemLocaleShortDate);
-
- // obsolete
- ROUNDTRIP(Qt::SystemLocaleDate);
- ROUNDTRIP(Qt::LocaleDate);
-
- ROUNDTRIP(Qt::DefaultLocaleLongDate);
- ROUNDTRIP(Qt::SystemLocaleLongDate);
-#undef ROUNDTRIP
- QLocale::setDefault(def);
-}
-
-void tst_QDateTime::offsetFromUtc()
-{
- /* Check default value. */
- QCOMPARE(QDateTime().offsetFromUtc(), 0);
-
- // Offset constructor
- QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60);
- QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
- QVERIFY(dt1.timeZone().isValid());
- dt1 = QDateTime(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60);
- QCOMPARE(dt1.offsetFromUtc(), -60 * 60);
-
- // UTC should be 0 offset
- QDateTime dt2(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QCOMPARE(dt2.offsetFromUtc(), 0);
-
- // LocalTime should vary
- if (zoneIsCET) {
- // Time definitely in Standard Time so 1 hour ahead
- QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
- QCOMPARE(dt3.offsetFromUtc(), 1 * 60 * 60);
- // Time definitely in Daylight Time so 2 hours ahead
- QDateTime dt4(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime);
- QCOMPARE(dt4.offsetFromUtc(), 2 * 60 * 60);
- } else {
- QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
- }
-
- QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Pacific/Auckland"));
- QCOMPARE(dt5.offsetFromUtc(), 46800);
-
- QDateTime dt6(QDate(2013, 6, 1), QTime(0, 0, 0), QTimeZone("Pacific/Auckland"));
- QCOMPARE(dt6.offsetFromUtc(), 43200);
-}
-
-void tst_QDateTime::setOffsetFromUtc()
-{
- /* Basic tests. */
- {
- QDateTime dt(QDateTime::currentDateTime());
- dt.setTimeSpec(Qt::LocalTime);
-
- dt.setOffsetFromUtc(0);
- QCOMPARE(dt.offsetFromUtc(), 0);
- QCOMPARE(dt.timeSpec(), Qt::UTC);
-
- dt.setOffsetFromUtc(-100);
- QCOMPARE(dt.offsetFromUtc(), -100);
- QCOMPARE(dt.timeSpec(), Qt::OffsetFromUTC);
- }
-
- /* Test detaching. */
- {
- QDateTime dt(QDateTime::currentDateTime());
- QDateTime dt2(dt);
- int offset2 = dt2.offsetFromUtc();
-
- dt.setOffsetFromUtc(501);
-
- QCOMPARE(dt.offsetFromUtc(), 501);
- QCOMPARE(dt2.offsetFromUtc(), offset2);
- }
-
- /* Check copying. */
- {
- QDateTime dt(QDateTime::currentDateTime());
- dt.setOffsetFromUtc(502);
- QCOMPARE(dt.offsetFromUtc(), 502);
-
- QDateTime dt2(dt);
- QCOMPARE(dt2.offsetFromUtc(), 502);
- }
-
- /* Check assignment. */
- {
- QDateTime dt(QDateTime::currentDateTime());
- dt.setOffsetFromUtc(502);
- QDateTime dt2;
- dt2 = dt;
-
- QCOMPARE(dt2.offsetFromUtc(), 502);
- }
-
- // Check spec persists
- QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 60 * 60);
- dt1.setMSecsSinceEpoch(123456789);
- QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
- dt1.setSecsSinceEpoch(123456789);
- QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(dt1.offsetFromUtc(), 60 * 60);
-
- // Check datastream serialises the offset seconds
- QByteArray tmp;
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << dt1;
- }
- QDateTime dt2;
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> dt2;
- }
- QCOMPARE(dt2, dt1);
- QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(dt2.offsetFromUtc(), 60 * 60);
-}
-
-void tst_QDateTime::toOffsetFromUtc()
-{
- QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC);
-
- QDateTime dt2 = dt1.toOffsetFromUtc(60 * 60);
- QCOMPARE(dt2, dt1);
- QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC);
- QCOMPARE(dt2.date(), QDate(2013, 1, 1));
- QCOMPARE(dt2.time(), QTime(1, 0, 0));
-
- dt2 = dt1.toOffsetFromUtc(0);
- QCOMPARE(dt2, dt1);
- QCOMPARE(dt2.timeSpec(), Qt::UTC);
- QCOMPARE(dt2.date(), QDate(2013, 1, 1));
- QCOMPARE(dt2.time(), QTime(0, 0, 0));
-
- dt2 = dt1.toTimeSpec(Qt::OffsetFromUTC);
- QCOMPARE(dt2, dt1);
- QCOMPARE(dt2.timeSpec(), Qt::UTC);
- QCOMPARE(dt2.date(), QDate(2013, 1, 1));
- QCOMPARE(dt2.time(), QTime(0, 0, 0));
-}
-
-void tst_QDateTime::zoneAtTime_data()
-{
- QTest::addColumn<QByteArray>("ianaID");
- QTest::addColumn<QDate>("date");
- QTest::addColumn<int>("offset");
-#define ADDROW(name, zone, date, offset) \
- QTest::newRow(name) << QByteArray(zone) << (date) << (offset)
-
- // Check DST handling around epoch:
- {
- QDate epoch(1970, 1, 1);
- ADDROW("epoch:UTC", "UTC", epoch, 0);
- // Paris and Berlin skipped DST around 1970; but Rome used it.
- ADDROW("epoch:CET", "Europe/Rome", epoch, 3600);
- ADDROW("epoch:PST", "America/Vancouver", epoch, -8 * 3600);
- ADDROW("epoch:EST", "America/New_York", epoch, -5 * 3600);
- }
- {
- // QDateTime deliberately ignores DST before the epoch.
- QDate summer69(1969, 8, 15); // Woodstock started
- ADDROW("summer69:UTC", "UTC", summer69, 0);
- ADDROW("summer69:CET", "Europe/Rome", summer69, 3600);
- ADDROW("summer69:PST", "America/Vancouver", summer69, -8 * 3600);
- ADDROW("summer69:EST", "America/New_York", summer69, -5 * 3600);
- }
- {
- // ... but takes it into account after:
- QDate summer70(1970, 8, 26); // Isle of Wight festival
- ADDROW("summer70:UTC", "UTC", summer70, 0);
- ADDROW("summer70:CET", "Europe/Rome", summer70, 2 * 3600);
- ADDROW("summer70:PST", "America/Vancouver", summer70, -7 * 3600);
- ADDROW("summer70:EST", "America/New_York", summer70, -4 * 3600);
- }
-
-#ifdef Q_OS_ANDROID // QTBUG-68835; gets offset 0 for the affected tests.
-# define NONANDROIDROW(name, zone, date, offset)
-#else
-# define NONANDROIDROW(name, zone, date, offset) ADDROW(name, zone, date, offset)
-#endif
-
-#ifndef Q_OS_WIN
- // Bracket a few noteworthy transitions:
- ADDROW("before:ACWST", "Australia/Eucla", QDate(1974, 10, 26), 31500); // 8:45
- NONANDROIDROW("after:ACWST", "Australia/Eucla", QDate(1974, 10, 27), 35100); // 9:45
- NONANDROIDROW("before:NPT", "Asia/Kathmandu", QDate(1985, 12, 31), 19800); // 5:30
- ADDROW("after:NPT", "Asia/Kathmandu", QDate(1986, 1, 1), 20700); // 5:45
- // The two that have skipped a day (each):
- NONANDROIDROW("before:LINT", "Pacific/Kiritimati", QDate(1994, 12, 30), -36000);
- ADDROW("after:LINT", "Pacific/Kiritimati", QDate(1995, 1, 2), 14 * 3600);
- ADDROW("after:WST", "Pacific/Apia", QDate(2011, 12, 31), 14 * 3600);
-#endif // MS lacks ACWST, NPT; doesn't grok date-line crossings; and Windows 7 lacks LINT.
- ADDROW("before:WST", "Pacific/Apia", QDate(2011, 12, 29), -36000);
-#undef ADDROW
-}
-
-void tst_QDateTime::zoneAtTime()
-{
- QFETCH(QByteArray, ianaID);
- QFETCH(QDate, date);
- QFETCH(int, offset);
- const QTime noon(12, 0);
-
- QTimeZone zone(ianaID);
- QVERIFY(zone.isValid());
- QCOMPARE(QDateTime(date, noon, zone).offsetFromUtc(), offset);
- if (date.year() < 1970)
- QCOMPARE(zone.standardTimeOffset(QDateTime(date, noon, zone)), offset);
- else // zone.offsetFromUtc *does* include DST, even before epoch
- QCOMPARE(zone.offsetFromUtc(QDateTime(date, noon, zone)), offset);
-}
-
-void tst_QDateTime::timeZoneAbbreviation()
-{
- QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60);
- QCOMPARE(dt1.timeZoneAbbreviation(), QString("UTC+01:00"));
- QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60);
- QCOMPARE(dt2.timeZoneAbbreviation(), QString("UTC-01:00"));
-
- QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QCOMPARE(dt3.timeZoneAbbreviation(), QString("UTC"));
-
- // LocalTime should vary
- if (zoneIsCET) {
- // Time definitely in Standard Time
- QDateTime dt4(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "Windows only reports long name (QTBUG-32759)", Continue);
-#endif
- QCOMPARE(dt4.timeZoneAbbreviation(), QStringLiteral("CET"));
- // Time definitely in Daylight Time
- QDateTime dt5(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime);
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "Windows only reports long name (QTBUG-32759)", Continue);
-#endif
- QCOMPARE(dt5.timeZoneAbbreviation(), QStringLiteral("CEST"));
- } else {
- qDebug("(Skipped some CET-only tests)");
- }
-
-#ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837)
- const QString cet(QStringLiteral("GMT+01:00"));
- const QString cest(QStringLiteral("GMT+02:00"));
-#elif defined Q_OS_DARWIN
- const QString cet(QStringLiteral("GMT+1"));
- const QString cest(QStringLiteral("GMT+2"));
-#else
- const QString cet(QStringLiteral("CET"));
- const QString cest(QStringLiteral("CEST"));
-#endif
-
- QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "Windows only reports long names (QTBUG-32759)", Continue);
-#endif
- QCOMPARE(dt5.timeZoneAbbreviation(), cet);
- QDateTime dt6(QDate(2013, 6, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "Windows only reports long names (QTBUG-32759)", Continue);
-#endif
- QCOMPARE(dt6.timeZoneAbbreviation(), cest);
-}
-
-void tst_QDateTime::getDate()
-{
- {
- int y = -33, m = -44, d = -55;
- QDate date;
- date.getDate(&y, &m, &d);
- QVERIFY(date.year() == y);
- QVERIFY(date.month() == m);
- QVERIFY(date.day() == d);
-
- date.getDate(0, 0, 0);
- }
-
- {
- int y = -33, m = -44, d = -55;
- QDate date(1998, 5, 24);
- date.getDate(0, &m, 0);
- date.getDate(&y, 0, 0);
- date.getDate(0, 0, &d);
-
- QVERIFY(date.year() == y);
- QVERIFY(date.month() == m);
- QVERIFY(date.day() == d);
- }
-}
-
-void tst_QDateTime::fewDigitsInYear() const
-{
- const QDateTime three(QDate(300, 10, 11), QTime());
- QCOMPARE(three.toString(QLatin1String("yyyy-MM-dd")), QString::fromLatin1("0300-10-11"));
-
- const QDateTime two(QDate(20, 10, 11), QTime());
- QCOMPARE(two.toString(QLatin1String("yyyy-MM-dd")), QString::fromLatin1("0020-10-11"));
-
- const QDateTime yyTwo(QDate(30, 10, 11), QTime());
- QCOMPARE(yyTwo.toString(QLatin1String("yy-MM-dd")), QString::fromLatin1("30-10-11"));
-
- const QDateTime yyOne(QDate(4, 10, 11), QTime());
- QCOMPARE(yyOne.toString(QLatin1String("yy-MM-dd")), QString::fromLatin1("04-10-11"));
-}
-
-void tst_QDateTime::printNegativeYear() const
-{
- {
- QDateTime date(QDate(-20, 10, 11));
- QVERIFY(date.isValid());
- QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0020"));
- }
-
- {
- QDateTime date(QDate(-3, 10, 11));
- QVERIFY(date.isValid());
- QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0003"));
- }
-
- {
- QDateTime date(QDate(-400, 10, 11));
- QVERIFY(date.isValid());
- QCOMPARE(date.toString(QLatin1String("yyyy")), QString::fromLatin1("-0400"));
- }
-}
-
-void tst_QDateTime::roundtripGermanLocale() const
-{
- /* This code path should not result in warnings. */
- const QDateTime theDateTime(QDateTime::currentDateTime());
- theDateTime.fromString(theDateTime.toString(Qt::TextDate), Qt::TextDate);
-}
-
-void tst_QDateTime::utcOffsetLessThan() const
-{
- QDateTime dt1(QDate(2002, 10, 10), QTime(0, 0, 0));
- QDateTime dt2(dt1);
-
- dt1.setOffsetFromUtc(-(2 * 60 * 60)); // Minus two hours.
- dt2.setOffsetFromUtc(-(3 * 60 * 60)); // Minus three hours.
-
- QVERIFY(dt1 != dt2);
- QVERIFY(!(dt1 == dt2));
- QVERIFY(dt1 < dt2);
- QVERIFY(!(dt2 < dt1));
-}
-
-void tst_QDateTime::isDaylightTime() const
-{
- QDateTime utc1(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QVERIFY(!utc1.isDaylightTime());
- QDateTime utc2(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QVERIFY(!utc2.isDaylightTime());
-
- QDateTime offset1(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 1 * 60 * 60);
- QVERIFY(!offset1.isDaylightTime());
- QDateTime offset2(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 1 * 60 * 60);
- QVERIFY(!offset2.isDaylightTime());
-
- if (zoneIsCET) {
- QDateTime cet1(QDate(2012, 1, 1), QTime(0, 0, 0));
- QVERIFY(!cet1.isDaylightTime());
- QDateTime cet2(QDate(2012, 6, 1), QTime(0, 0, 0));
- QVERIFY(cet2.isDaylightTime());
- } else {
- QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
- }
-}
-
-void tst_QDateTime::daylightTransitions() const
-{
- if (zoneIsCET) {
- // CET transitions occur at 01:00:00 UTC on last Sunday in March and October
- // 2011-03-27 02:00:00 CET became 03:00:00 CEST at msecs = 1301187600000
- // 2011-10-30 03:00:00 CEST became 02:00:00 CET at msecs = 1319936400000
- // 2012-03-25 02:00:00 CET became 03:00:00 CEST at msecs = 1332637200000
- // 2012-10-28 03:00:00 CEST became 02:00:00 CET at msecs = 1351386000000
- const qint64 daylight2012 = 1332637200000;
- const qint64 standard2012 = 1351386000000;
- const qint64 msecsOneHour = 3600000;
-
- // Test for correct behviour for StandardTime -> DaylightTime transition, i.e. missing hour
-
- // Test setting date, time in missing hour will be invalid
-
- QDateTime before(QDate(2012, 3, 25), QTime(1, 59, 59, 999));
- QVERIFY(before.isValid());
- QCOMPARE(before.date(), QDate(2012, 3, 25));
- QCOMPARE(before.time(), QTime(1, 59, 59, 999));
- QCOMPARE(before.toMSecsSinceEpoch(), daylight2012 - 1);
-
- QDateTime missing(QDate(2012, 3, 25), QTime(2, 0, 0));
- QVERIFY(!missing.isValid());
- QCOMPARE(missing.date(), QDate(2012, 3, 25));
- QCOMPARE(missing.time(), QTime(2, 0, 0));
-
- QDateTime after(QDate(2012, 3, 25), QTime(3, 0, 0));
- QVERIFY(after.isValid());
- QCOMPARE(after.date(), QDate(2012, 3, 25));
- QCOMPARE(after.time(), QTime(3, 0, 0));
- QCOMPARE(after.toMSecsSinceEpoch(), daylight2012);
-
- // Test round-tripping of msecs
-
- before.setMSecsSinceEpoch(daylight2012 - 1);
- QVERIFY(before.isValid());
- QCOMPARE(before.date(), QDate(2012, 3, 25));
- QCOMPARE(before.time(), QTime(1, 59, 59, 999));
- QCOMPARE(before.toMSecsSinceEpoch(), daylight2012 -1);
-
- after.setMSecsSinceEpoch(daylight2012);
- QVERIFY(after.isValid());
- QCOMPARE(after.date(), QDate(2012, 3, 25));
- QCOMPARE(after.time(), QTime(3, 0, 0));
- QCOMPARE(after.toMSecsSinceEpoch(), daylight2012);
-
- // Test changing time spec re-validates the date/time
-
- QDateTime utc(QDate(2012, 3, 25), QTime(2, 00, 0), Qt::UTC);
- QVERIFY(utc.isValid());
- QCOMPARE(utc.date(), QDate(2012, 3, 25));
- QCOMPARE(utc.time(), QTime(2, 0, 0));
- utc.setTimeSpec(Qt::LocalTime);
- QVERIFY(!utc.isValid());
- QCOMPARE(utc.date(), QDate(2012, 3, 25));
- QCOMPARE(utc.time(), QTime(2, 0, 0));
- utc.setTimeSpec(Qt::UTC);
- QVERIFY(utc.isValid());
- QCOMPARE(utc.date(), QDate(2012, 3, 25));
- QCOMPARE(utc.time(), QTime(2, 0, 0));
-
- // Test date maths, if result falls in missing hour then becomes next
- // hour (or is always invalid; mktime() may reject gap-times).
-
- QDateTime test(QDate(2011, 3, 25), QTime(2, 0, 0));
- QVERIFY(test.isValid());
- test = test.addYears(1);
- const bool handled = test.isValid();
-#define CHECK_SPRING_FORWARD(test) \
- if (test.isValid()) { \
- QCOMPARE(test.date(), QDate(2012, 3, 25)); \
- QCOMPARE(test.time(), QTime(3, 0, 0)); \
- } else { \
- QVERIFY(!handled); \
- }
- CHECK_SPRING_FORWARD(test);
-
- test = QDateTime(QDate(2012, 2, 25), QTime(2, 0, 0));
- QVERIFY(test.isValid());
- test = test.addMonths(1);
- CHECK_SPRING_FORWARD(test);
-
- test = QDateTime(QDate(2012, 3, 24), QTime(2, 0, 0));
- QVERIFY(test.isValid());
- test = test.addDays(1);
- CHECK_SPRING_FORWARD(test);
-
- test = QDateTime(QDate(2012, 3, 25), QTime(1, 0, 0));
- QVERIFY(test.isValid());
- QCOMPARE(test.toMSecsSinceEpoch(), daylight2012 - msecsOneHour);
- test = test.addMSecs(msecsOneHour);
- CHECK_SPRING_FORWARD(test);
- if (handled)
- QCOMPARE(test.toMSecsSinceEpoch(), daylight2012);
-#undef CHECK_SPRING_FORWARD
-
- // Test for correct behviour for DaylightTime -> StandardTime transition, i.e. second occurrence
-
- // Test setting date and time in first and second occurrence will be valid
-
- // 1 hour before transition is 2:00:00 FirstOccurrence
- QDateTime hourBefore(QDate(2012, 10, 28), QTime(2, 0, 0));
- QVERIFY(hourBefore.isValid());
- QCOMPARE(hourBefore.date(), QDate(2012, 10, 28));
- QCOMPARE(hourBefore.time(), QTime(2, 0, 0));
-#ifdef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(hourBefore.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
-
- // 1 msec before transition is 2:59:59.999 FirstOccurrence
- QDateTime msecBefore(QDate(2012, 10, 28), QTime(2, 59, 59, 999));
- QVERIFY(msecBefore.isValid());
- QCOMPARE(msecBefore.date(), QDate(2012, 10, 28));
- QCOMPARE(msecBefore.time(), QTime(2, 59, 59, 999));
-#if defined(Q_OS_DARWIN) || defined(Q_OS_WIN) || defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
- // Win and Mac uses SecondOccurrence here
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_MAC
- QCOMPARE(msecBefore.toMSecsSinceEpoch(), standard2012 - 1);
-
- // At transition is 2:00:00 SecondOccurrence
- QDateTime atTran(QDate(2012, 10, 28), QTime(2, 0, 0));
- QVERIFY(atTran.isValid());
- QCOMPARE(atTran.date(), QDate(2012, 10, 28));
- QCOMPARE(atTran.time(), QTime(2, 0, 0));
-#ifndef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(atTran.toMSecsSinceEpoch(), standard2012);
-
- // 59:59.999 after transition is 2:59:59.999 SecondOccurrence
- QDateTime afterTran(QDate(2012, 10, 28), QTime(2, 59, 59, 999));
- QVERIFY(afterTran.isValid());
- QCOMPARE(afterTran.date(), QDate(2012, 10, 28));
- QCOMPARE(afterTran.time(), QTime(2, 59, 59, 999));
-#ifdef __GLIBCXX__
- // Linux (i.e. glibc) mktime bug reuses last calculation
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_UNIX
- QCOMPARE(afterTran.toMSecsSinceEpoch(), standard2012 + msecsOneHour - 1);
-
- // 1 hour after transition is 3:00:00 FirstOccurrence
- QDateTime hourAfter(QDate(2012, 10, 28), QTime(3, 0, 0));
- QVERIFY(hourAfter.isValid());
- QCOMPARE(hourAfter.date(), QDate(2012, 10, 28));
- QCOMPARE(hourAfter.time(), QTime(3, 0, 0));
- QCOMPARE(hourAfter.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
-
- // Test round-tripping of msecs
-
- // 1 hour before transition is 2:00:00 FirstOccurrence
- hourBefore.setMSecsSinceEpoch(standard2012 - msecsOneHour);
- QVERIFY(hourBefore.isValid());
- QCOMPARE(hourBefore.date(), QDate(2012, 10, 28));
- QCOMPARE(hourBefore.time(), QTime(2, 0, 0));
- QCOMPARE(hourBefore.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
-
- // 1 msec before transition is 2:59:59.999 FirstOccurrence
- msecBefore.setMSecsSinceEpoch(standard2012 - 1);
- QVERIFY(msecBefore.isValid());
- QCOMPARE(msecBefore.date(), QDate(2012, 10, 28));
- QCOMPARE(msecBefore.time(), QTime(2, 59, 59, 999));
- QCOMPARE(msecBefore.toMSecsSinceEpoch(), standard2012 - 1);
-
- // At transition is 2:00:00 SecondOccurrence
- atTran.setMSecsSinceEpoch(standard2012);
- QVERIFY(atTran.isValid());
- QCOMPARE(atTran.date(), QDate(2012, 10, 28));
- QCOMPARE(atTran.time(), QTime(2, 0, 0));
- QCOMPARE(atTran.toMSecsSinceEpoch(), standard2012);
-
- // 59:59.999 after transition is 2:59:59.999 SecondOccurrence
- afterTran.setMSecsSinceEpoch(standard2012 + msecsOneHour - 1);
- QVERIFY(afterTran.isValid());
- QCOMPARE(afterTran.date(), QDate(2012, 10, 28));
- QCOMPARE(afterTran.time(), QTime(2, 59, 59, 999));
- QCOMPARE(afterTran.toMSecsSinceEpoch(), standard2012 + msecsOneHour - 1);
-
- // 1 hour after transition is 3:00:00 FirstOccurrence
- hourAfter.setMSecsSinceEpoch(standard2012 + msecsOneHour);
- QVERIFY(hourAfter.isValid());
- QCOMPARE(hourAfter.date(), QDate(2012, 10, 28));
- QCOMPARE(hourAfter.time(), QTime(3, 0, 0));
- QCOMPARE(hourAfter.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
-
- // Test date maths, result is always FirstOccurrence
-
- // Add year to get to tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 28), QTime(2, 0, 0));
- test = test.addYears(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-#ifdef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
-
- // Add year to get to after tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 28), QTime(3, 0, 0));
- test = test.addYears(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(3, 0, 0));
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
-
- // Add year to tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0));
- test = test.addYears(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 30));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-
- // Add year to tran SecondOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0)); // TODO SecondOccurrence
- test = test.addYears(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 30));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-
- // Add year to after tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(3, 0, 0));
- test = test.addYears(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 30));
- QCOMPARE(test.time(), QTime(3, 0, 0));
-
-
- // Add month to get to tran FirstOccurrence
- test = QDateTime(QDate(2012, 9, 28), QTime(2, 0, 0));
- test = test.addMonths(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-#ifdef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
-
- // Add month to get to after tran FirstOccurrence
- test = QDateTime(QDate(2012, 9, 28), QTime(3, 0, 0));
- test = test.addMonths(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(3, 0, 0));
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
-
- // Add month to tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0));
- test = test.addMonths(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2011, 11, 30));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-
- // Add month to tran SecondOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0)); // TODO SecondOccurrence
- test = test.addMonths(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2011, 11, 30));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-
- // Add month to after tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(3, 0, 0));
- test = test.addMonths(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2011, 11, 30));
- QCOMPARE(test.time(), QTime(3, 0, 0));
-
-
- // Add day to get to tran FirstOccurrence
- test = QDateTime(QDate(2012, 10, 27), QTime(2, 0, 0));
- test = test.addDays(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-#ifdef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
-
- // Add day to get to after tran FirstOccurrence
- test = QDateTime(QDate(2012, 10, 27), QTime(3, 0, 0));
- test = test.addDays(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(3, 0, 0));
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
-
- // Add day to tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0));
- test = test.addDays(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2011, 10, 31));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-
- // Add day to tran SecondOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0)); // TODO SecondOccurrence
- test = test.addDays(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2011, 10, 31));
- QCOMPARE(test.time(), QTime(2, 0, 0));
-
- // Add day to after tran FirstOccurrence
- test = QDateTime(QDate(2011, 10, 30), QTime(3, 0, 0));
- test = test.addDays(1);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2011, 10, 31));
- QCOMPARE(test.time(), QTime(3, 0, 0));
-
-
- // Add hour to get to tran FirstOccurrence
- test = QDateTime(QDate(2012, 10, 28), QTime(1, 0, 0));
- test = test.addMSecs(msecsOneHour);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
- QCOMPARE(test.time(), QTime(2, 0, 0));
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
-
- // Add hour to tran FirstOccurrence to get to tran SecondOccurrence
- test = QDateTime(QDate(2012, 10, 28), QTime(2, 0, 0));
- test = test.addMSecs(msecsOneHour);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
-#ifdef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.time(), QTime(2, 0, 0));
-#ifdef Q_OS_WIN
- // Windows uses SecondOccurrence
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012);
-
- // Add hour to tran SecondOccurrence to get to after tran FirstOccurrence
- test = QDateTime(QDate(2012, 10, 28), QTime(2, 0, 0)); // TODO SecondOccurrence
- test = test.addMSecs(msecsOneHour);
- QVERIFY(test.isValid());
- QCOMPARE(test.date(), QDate(2012, 10, 28));
-#if defined(Q_OS_DARWIN) || defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
- // Mac uses FirstOccurrence, Windows uses SecondOccurrence, Linux uses last calculation
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.time(), QTime(3, 0, 0));
-#if defined(Q_OS_DARWIN) || defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
- // Mac uses FirstOccurrence, Windows uses SecondOccurrence, Linux uses last calculation
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
-
- } else {
- QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
- }
-}
-
-void tst_QDateTime::timeZones() const
-{
- QTimeZone invalidTz = QTimeZone("Vulcan/ShiKahr");
- QCOMPARE(invalidTz.isValid(), false);
- QDateTime invalidDateTime = QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0), invalidTz);
- QCOMPARE(invalidDateTime.isValid(), false);
- QCOMPARE(invalidDateTime.date(), QDate(2000, 1, 1));
- QCOMPARE(invalidDateTime.time(), QTime(0, 0, 0));
-
- QTimeZone nzTz = QTimeZone("Pacific/Auckland");
- QTimeZone nzTzOffset = QTimeZone(12 * 3600);
-
- // During Standard Time NZ is +12:00
- QDateTime utcStd(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime nzStd(QDate(2012, 6, 1), QTime(12, 0, 0), nzTz);
- QDateTime nzStdOffset(QDate(2012, 6, 1), QTime(12, 0, 0), nzTzOffset);
-
- QCOMPARE(nzStd.isValid(), true);
- QCOMPARE(nzStd.timeSpec(), Qt::TimeZone);
- QCOMPARE(nzStd.date(), QDate(2012, 6, 1));
- QCOMPARE(nzStd.time(), QTime(12, 0, 0));
- QVERIFY(nzStd.timeZone() == nzTz);
- QCOMPARE(nzStd.timeZone().id(), QByteArray("Pacific/Auckland"));
- QCOMPARE(nzStd.offsetFromUtc(), 43200);
- QCOMPARE(nzStd.isDaylightTime(), false);
- QCOMPARE(nzStd.toMSecsSinceEpoch(), utcStd.toMSecsSinceEpoch());
-
- QCOMPARE(nzStdOffset.isValid(), true);
- QCOMPARE(nzStdOffset.timeSpec(), Qt::TimeZone);
- QCOMPARE(nzStdOffset.date(), QDate(2012, 6, 1));
- QCOMPARE(nzStdOffset.time(), QTime(12, 0, 0));
- QVERIFY(nzStdOffset.timeZone() == nzTzOffset);
- QCOMPARE(nzStdOffset.timeZone().id(), QByteArray("UTC+12:00"));
- QCOMPARE(nzStdOffset.offsetFromUtc(), 43200);
- QCOMPARE(nzStdOffset.isDaylightTime(), false);
- QCOMPARE(nzStdOffset.toMSecsSinceEpoch(), utcStd.toMSecsSinceEpoch());
-
- // During Daylight Time NZ is +13:00
- QDateTime utcDst(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime nzDst(QDate(2012, 1, 1), QTime(13, 0, 0), nzTz);
-
- QCOMPARE(nzDst.isValid(), true);
- QCOMPARE(nzDst.date(), QDate(2012, 1, 1));
- QCOMPARE(nzDst.time(), QTime(13, 0, 0));
- QCOMPARE(nzDst.offsetFromUtc(), 46800);
- QCOMPARE(nzDst.isDaylightTime(), true);
- QCOMPARE(nzDst.toMSecsSinceEpoch(), utcDst.toMSecsSinceEpoch());
-
- QDateTime utc = nzStd.toUTC();
- QCOMPARE(utc.date(), utcStd.date());
- QCOMPARE(utc.time(), utcStd.time());
-
- utc = nzDst.toUTC();
- QCOMPARE(utc.date(), utcDst.date());
- QCOMPARE(utc.time(), utcDst.time());
-
- // Sydney is 2 hours behind New Zealand
- QTimeZone ausTz = QTimeZone("Australia/Sydney");
- QDateTime aus = nzStd.toTimeZone(ausTz);
- QCOMPARE(aus.date(), QDate(2012, 6, 1));
- QCOMPARE(aus.time(), QTime(10, 0, 0));
-
- QDateTime dt1(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QCOMPARE(dt1.timeSpec(), Qt::UTC);
- dt1.setTimeZone(nzTz);
- QCOMPARE(dt1.timeSpec(), Qt::TimeZone);
- QCOMPARE(dt1.date(), QDate(2012, 6, 1));
- QCOMPARE(dt1.time(), QTime(0, 0, 0));
- QCOMPARE(dt1.timeZone(), nzTz);
-
- QDateTime dt2 = QDateTime::fromSecsSinceEpoch(1338465600, nzTz);
- QCOMPARE(dt2.date(), dt1.date());
- QCOMPARE(dt2.time(), dt1.time());
- QCOMPARE(dt2.timeSpec(), dt1.timeSpec());
- QCOMPARE(dt2.timeZone(), dt1.timeZone());
-
- QDateTime dt3 = QDateTime::fromMSecsSinceEpoch(1338465600000, nzTz);
- QCOMPARE(dt3.date(), dt1.date());
- QCOMPARE(dt3.time(), dt1.time());
- QCOMPARE(dt3.timeSpec(), dt1.timeSpec());
- QCOMPARE(dt3.timeZone(), dt1.timeZone());
-
- // Check datastream serialises the time zone
- QByteArray tmp;
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << dt1;
- }
- QDateTime dt4;
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> dt4;
- }
- QCOMPARE(dt4, dt1);
- QCOMPARE(dt4.timeSpec(), Qt::TimeZone);
- QCOMPARE(dt4.timeZone(), nzTz);
-
- // Check handling of transition times
- QTimeZone cet("Europe/Oslo");
-
- // Standard Time to Daylight Time 2013 on 2013-03-31 is 2:00 local time / 1:00 UTC
- qint64 stdToDstMSecs = 1364691600000;
-
- // Test MSecs to local
- // - Test 1 msec before tran = 01:59:59.999
- QDateTime beforeDst = QDateTime::fromMSecsSinceEpoch(stdToDstMSecs - 1, cet);
- QCOMPARE(beforeDst.date(), QDate(2013, 3, 31));
- QCOMPARE(beforeDst.time(), QTime(1, 59, 59, 999));
- // - Test at tran = 03:00:00
- QDateTime atDst = QDateTime::fromMSecsSinceEpoch(stdToDstMSecs, cet);
- QCOMPARE(atDst.date(), QDate(2013, 3, 31));
- QCOMPARE(atDst.time(), QTime(3, 0, 0));
-
- // Test local to MSecs
- // - Test 1 msec before tran = 01:59:59.999
- beforeDst = QDateTime(QDate(2013, 3, 31), QTime(1, 59, 59, 999), cet);
- QCOMPARE(beforeDst.toMSecsSinceEpoch(), stdToDstMSecs - 1);
- // - Test at tran = 03:00:00
- atDst = QDateTime(QDate(2013, 3, 31), QTime(3, 0, 0), cet);
- QCOMPARE(atDst.toMSecsSinceEpoch(), stdToDstMSecs);
- // - Test transition hole, setting 03:00:00 is valid
- atDst = QDateTime(QDate(2013, 3, 31), QTime(3, 0, 0), cet);
- QVERIFY(atDst.isValid());
- QCOMPARE(atDst.date(), QDate(2013, 3, 31));
- QCOMPARE(atDst.time(), QTime(3, 0, 0));
- QCOMPARE(atDst.toMSecsSinceEpoch(), stdToDstMSecs);
- // - Test transition hole, setting 02:00:00 is invalid
- atDst = QDateTime(QDate(2013, 3, 31), QTime(2, 0, 0), cet);
- QVERIFY(!atDst.isValid());
- QCOMPARE(atDst.date(), QDate(2013, 3, 31));
- QCOMPARE(atDst.time(), QTime(2, 0, 0));
- // - Test transition hole, setting 02:59:59.999 is invalid
- atDst = QDateTime(QDate(2013, 3, 31), QTime(2, 59, 59, 999), cet);
- QVERIFY(!atDst.isValid());
- QCOMPARE(atDst.date(), QDate(2013, 3, 31));
- QCOMPARE(atDst.time(), QTime(2, 59, 59, 999));
-
- // Standard Time to Daylight Time 2013 on 2013-10-27 is 3:00 local time / 1:00 UTC
- qint64 dstToStdMSecs = 1382835600000;
-
- // Test MSecs to local
- // - Test 1 hour before tran = 02:00:00 local first occurrence
- QDateTime hourBeforeStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs - 3600000, cet);
- QCOMPARE(hourBeforeStd.date(), QDate(2013, 10, 27));
- QCOMPARE(hourBeforeStd.time(), QTime(2, 0, 0));
- // - Test 1 msec before tran = 02:59:59.999 local first occurrence
- QDateTime msecBeforeStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs - 1, cet);
- QCOMPARE(msecBeforeStd.date(), QDate(2013, 10, 27));
- QCOMPARE(msecBeforeStd.time(), QTime(2, 59, 59, 999));
- // - Test at tran = 03:00:00 local becomes 02:00:00 local second occurrence
- QDateTime atStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs, cet);
- QCOMPARE(atStd.date(), QDate(2013, 10, 27));
- QCOMPARE(atStd.time(), QTime(2, 0, 0));
- // - Test 59 mins after tran = 02:59:59.999 local second occurrence
- QDateTime afterStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs + 3600000 -1, cet);
- QCOMPARE(afterStd.date(), QDate(2013, 10, 27));
- QCOMPARE(afterStd.time(), QTime(2, 59, 59, 999));
- // - Test 1 hour after tran = 03:00:00 local
- QDateTime hourAfterStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs + 3600000, cet);
- QCOMPARE(hourAfterStd.date(), QDate(2013, 10, 27));
- QCOMPARE(hourAfterStd.time(), QTime(3, 00, 00));
-
- // Test local to MSecs
- // - Test first occurrence 02:00:00 = 1 hour before tran
- hourBeforeStd = QDateTime(QDate(2013, 10, 27), QTime(2, 0, 0), cet);
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
- QCOMPARE(hourBeforeStd.toMSecsSinceEpoch(), dstToStdMSecs - 3600000);
- // - Test first occurrence 02:59:59.999 = 1 msec before tran
- msecBeforeStd = QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet);
- QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
- QCOMPARE(msecBeforeStd.toMSecsSinceEpoch(), dstToStdMSecs - 1);
- // - Test second occurrence 02:00:00 = at tran
- atStd = QDateTime(QDate(2013, 10, 27), QTime(2, 0, 0), cet);
- QCOMPARE(atStd.toMSecsSinceEpoch(), dstToStdMSecs);
- // - Test second occurrence 03:00:00 = 59 mins after tran
- afterStd = QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet);
- QCOMPARE(afterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000 - 1);
- // - Test 03:00:00 = 1 hour after tran
- hourAfterStd = QDateTime(QDate(2013, 10, 27), QTime(3, 0, 0), cet);
- QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000);
-
- // Test Time Zone that has transitions but no future transitions afer a given date
- QTimeZone sgt("Asia/Singapore");
- QDateTime future(QDate(2015, 1, 1), QTime(0, 0, 0), sgt);
- QVERIFY(future.isValid());
- QCOMPARE(future.offsetFromUtc(), 28800);
-}
-
-#if defined(Q_OS_UNIX)
-// Currently disabled on Windows as adjusting the timezone
-// requires additional privileges that aren't normally
-// enabled for a process. This can be achieved by calling
-// AdjustTokenPrivileges() and then SetTimeZoneInformation(),
-// which will require linking to a different library to access that API.
-static void setTimeZone(const QByteArray &tz)
-{
- qputenv("TZ", tz);
- ::tzset();
-
-// following left for future reference, see comment above
-// #if defined(Q_OS_WIN32)
-// ::_tzset();
-// #endif
-}
-
-void tst_QDateTime::systemTimeZoneChange() const
-{
- struct ResetTZ {
- QByteArray original;
- ResetTZ() : original(qgetenv("TZ")) {}
- ~ResetTZ() { setTimeZone(original); }
- } scopedReset;
-
- // Set the timezone to Brisbane time
- setTimeZone(QByteArray("AEST-10:00"));
-
- QDateTime localDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime);
- QDateTime utcDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC);
- QDateTime tzDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), QTimeZone("Australia/Brisbane"));
- qint64 localMsecs = localDate.toMSecsSinceEpoch();
- qint64 utcMsecs = utcDate.toMSecsSinceEpoch();
- qint64 tzMsecs = tzDate.toMSecsSinceEpoch();
-
- // check that Australia/Brisbane is known
- QVERIFY(tzDate.timeZone().isValid());
-
- // Change to Indian time
- setTimeZone(QByteArray("IST-05:30"));
-
- QCOMPARE(localDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime));
- QVERIFY(localMsecs != localDate.toMSecsSinceEpoch());
- QCOMPARE(utcDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC));
- QCOMPARE(utcDate.toMSecsSinceEpoch(), utcMsecs);
- QCOMPARE(tzDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), QTimeZone("Australia/Brisbane")));
- QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs);
-}
-#endif
-
-void tst_QDateTime::invalid() const
-{
- QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1));
- QCOMPARE(invalidDate.isValid(), false);
- QCOMPARE(invalidDate.timeSpec(), Qt::LocalTime);
-
- QDateTime utcDate = invalidDate.toUTC();
- QCOMPARE(utcDate.isValid(), false);
- QCOMPARE(utcDate.timeSpec(), Qt::UTC);
-
- QDateTime offsetDate = invalidDate.toOffsetFromUtc(3600);
- QCOMPARE(offsetDate.isValid(), false);
- QCOMPARE(offsetDate.timeSpec(), Qt::OffsetFromUTC);
-
- QDateTime tzDate = invalidDate.toTimeZone(QTimeZone("Europe/Oslo"));
- QCOMPARE(tzDate.isValid(), false);
- QCOMPARE(tzDate.timeSpec(), Qt::TimeZone);
-}
-
-void tst_QDateTime::macTypes()
-{
-#ifndef Q_OS_MAC
- QSKIP("This is a Apple-only test");
-#else
- extern void tst_QDateTime_macTypes(); // in qdatetime_mac.mm
- tst_QDateTime_macTypes();
-#endif
-}
-
-QTEST_APPLESS_MAIN(tst_QDateTime)
-#include "tst_qdatetime.moc"
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm
deleted file mode 100644
index f73c7b9d5d..0000000000
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 Petroules Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QDateTime>
-#include <QtTest/QtTest>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-void tst_QDateTime_macTypes()
-{
- // QDateTime <-> CFDate
-
- static const int kMsPerSecond = 1000;
-
- for (int i = 0; i < kMsPerSecond; ++i) {
- QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(i);
- const CFDateRef cfDate = qtDateTime.toCFDate();
- QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTime);
- CFRelease(cfDate);
- }
- {
- QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0);
- const CFDateRef cfDate = qtDateTime.toCFDate();
- QDateTime qtDateTimeCopy(qtDateTime);
- qtDateTime.setTime_t(10000); // modify
- QCOMPARE(QDateTime::fromCFDate(cfDate), qtDateTimeCopy);
- }
- // QDateTime <-> NSDate
- for (int i = 0; i < kMsPerSecond; ++i) {
- QMacAutoReleasePool pool;
- QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(i);
- const NSDate *nsDate = qtDateTime.toNSDate();
- QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTime);
- }
- {
- QMacAutoReleasePool pool;
- QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0);
- const NSDate *nsDate = qtDateTime.toNSDate();
- QDateTime qtDateTimeCopy(qtDateTime);
- qtDateTime.setTime_t(10000); // modify
- QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTimeCopy);
- }
-}
diff --git a/tests/auto/corelib/tools/qduplicatetracker/CMakeLists.txt b/tests/auto/corelib/tools/qduplicatetracker/CMakeLists.txt
new file mode 100644
index 0000000000..13645c50b8
--- /dev/null
+++ b/tests/auto/corelib/tools/qduplicatetracker/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qduplicatetracker Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qduplicatetracker LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qduplicatetracker
+ SOURCES
+ tst_qduplicatetracker.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
new file mode 100644
index 0000000000..ad0b6abbc7
--- /dev/null
+++ b/tests/auto/corelib/tools/qduplicatetracker/tst_qduplicatetracker.cpp
@@ -0,0 +1,230 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest/QtTest>
+
+#include <QtCore/private/qduplicatetracker_p.h>
+
+#include <QObject>
+
+#include <string>
+#include <utility>
+
+class tst_QDuplicateTracker : public QObject
+{
+ Q_OBJECT
+private slots:
+ void hasSeen();
+ void clear();
+ void appendTo();
+ void appendTo_special();
+};
+
+void tst_QDuplicateTracker::hasSeen()
+{
+ {
+ QDuplicateTracker<int, 2> tracker;
+ QVERIFY(!tracker.hasSeen(0));
+ QVERIFY(tracker.hasSeen(0));
+ QVERIFY(!tracker.hasSeen(1));
+ QVERIFY(tracker.hasSeen(1));
+ // past the prealloc amount
+ QVERIFY(!tracker.hasSeen(2));
+ QVERIFY(tracker.hasSeen(2));
+ }
+
+ {
+ QDuplicateTracker<QString, 2> tracker;
+ QString string1("string1");
+ QString string2("string2");
+ QString string2_2("string2");
+ QString string3("string3");
+
+ // Move when seen
+ QVERIFY(!tracker.hasSeen(string1));
+ QVERIFY(tracker.hasSeen(std::move(string1)));
+
+ // Move when unseen
+ QVERIFY(!tracker.hasSeen(std::move(string2)));
+ QVERIFY(tracker.hasSeen(string2_2));
+
+ // Past the prealloc amount
+ QVERIFY(!tracker.hasSeen(string3));
+ QVERIFY(tracker.hasSeen(string3));
+ }
+
+ {
+ QDuplicateTracker<std::string, 2> tracker;
+ std::string string1("string1");
+ std::string string2("string2");
+ std::string string2_2("string2");
+ std::string string3("string3");
+
+ // Move when seen
+ QVERIFY(!tracker.hasSeen(string1));
+ QVERIFY(tracker.hasSeen(std::move(string1)));
+
+ // Move when unseen
+ QVERIFY(!tracker.hasSeen(std::move(string2)));
+ QVERIFY(tracker.hasSeen(string2_2));
+
+ // Past the prealloc amount
+ QVERIFY(!tracker.hasSeen(string3));
+ QVERIFY(tracker.hasSeen(string3));
+ }
+
+}
+
+void tst_QDuplicateTracker::clear()
+{
+ QDuplicateTracker<int, 2> tracker;
+ QVERIFY(!tracker.hasSeen(0));
+ QVERIFY(tracker.hasSeen(0));
+ QVERIFY(!tracker.hasSeen(1));
+ QVERIFY(tracker.hasSeen(1));
+
+ tracker.clear();
+ QVERIFY(!tracker.hasSeen(0));
+ QVERIFY(tracker.hasSeen(0));
+ QVERIFY(!tracker.hasSeen(1));
+ QVERIFY(tracker.hasSeen(1));
+}
+
+void tst_QDuplicateTracker::appendTo()
+{
+ QDuplicateTracker<int, 2> tracker;
+ QVERIFY(!tracker.hasSeen(0));
+ QVERIFY(!tracker.hasSeen(1));
+ QList<int> a;
+ a.append(-1);
+ tracker.appendTo(a);
+ std::sort(a.begin(), a.end());
+ QCOMPARE(a, QList<int>({ -1, 0, 1 }));
+
+ QList<int> b;
+ tracker.appendTo(b);
+ std::sort(b.begin(), b.end());
+ QCOMPARE(b, QList<int>({ 0, 1 }));
+
+ QVERIFY(!tracker.hasSeen(2));
+ QList<int> c;
+ std::move(tracker).appendTo(c);
+ std::sort(c.begin(), c.end());
+ QCOMPARE(c, QList<int>({ 0, 1, 2 }));
+ if (QDuplicateTracker<int, 2>::uses_pmr) {
+ // the following is only true if we use the std container
+ QVERIFY(!tracker.hasSeen(0));
+ QVERIFY(!tracker.hasSeen(1));
+ QVERIFY(!tracker.hasSeen(2));
+ }
+}
+
+struct ConstructionCounted
+{
+ ConstructionCounted(int i) : i(i) { }
+ ConstructionCounted(ConstructionCounted &&other) noexcept
+ : i(other.i), copies(other.copies), moves(other.moves + 1)
+ {
+ // set to some easily noticeable values
+ other.i = -64;
+ other.copies = -64;
+ other.moves = -64;
+ }
+ ConstructionCounted &operator=(ConstructionCounted &&other) noexcept
+ {
+ ConstructionCounted moved = std::move(other);
+ swap(moved);
+ // set to some easily noticeable values
+ other.i = -64;
+ other.copies = -64;
+ other.moves = -64;
+ return *this;
+ }
+ ConstructionCounted(const ConstructionCounted &other) noexcept
+ : i(other.i), copies(other.copies + 1), moves(other.moves)
+ {
+ }
+ ConstructionCounted &operator=(const ConstructionCounted &other) noexcept
+ {
+ ConstructionCounted copy = other;
+ swap(copy);
+ return *this;
+ }
+ ~ConstructionCounted() = default;
+
+ friend bool operator==(const ConstructionCounted &lhs, const ConstructionCounted &rhs)
+ {
+ return lhs.i == rhs.i;
+ }
+
+ QString toString() { return QString::number(i); }
+
+ void swap(ConstructionCounted &other)
+ {
+ std::swap(copies, other.copies);
+ std::swap(i, other.i);
+ std::swap(moves, other.moves);
+ }
+
+ int i;
+ int copies = 0;
+ int moves = 0;
+};
+
+// for std::unordered_set
+namespace std {
+template<>
+struct hash<ConstructionCounted>
+{
+ std::size_t operator()(const ConstructionCounted &c) const noexcept { return c.i; }
+};
+}
+
+// for QSet
+size_t qHash(const ConstructionCounted &c, std::size_t seed = 0)
+{
+ return qHash(c.i, seed);
+}
+
+void tst_QDuplicateTracker::appendTo_special()
+{
+ QDuplicateTracker<ConstructionCounted> tracker(3);
+ QVERIFY(!tracker.hasSeen(1));
+ QVERIFY(!tracker.hasSeen(2));
+ QVERIFY(!tracker.hasSeen(3));
+
+ QVERIFY(tracker.hasSeen(1));
+ QVERIFY(tracker.hasSeen(2));
+ QVERIFY(tracker.hasSeen(3));
+ {
+ QList<ConstructionCounted> a;
+ a.reserve(3);
+ tracker.appendTo(a);
+ for (const auto &counter : a) {
+ QCOMPARE(counter.moves, 1);
+ QCOMPARE(counter.copies, 1);
+ }
+ }
+ QVERIFY(tracker.hasSeen(1));
+ QVERIFY(tracker.hasSeen(2));
+ QVERIFY(tracker.hasSeen(3));
+ {
+ QList<ConstructionCounted> a;
+ a.reserve(3);
+ std::move(tracker).appendTo(a);
+ if (QDuplicateTracker<ConstructionCounted>::uses_pmr) {
+ // the following is only true if we use the std container
+ for (const auto &counter : a) {
+ QCOMPARE(counter.moves, 2);
+ QCOMPARE(counter.copies, 0);
+ }
+ QVERIFY(!tracker.hasSeen(1));
+ QVERIFY(!tracker.hasSeen(2));
+ QVERIFY(!tracker.hasSeen(3));
+ }
+ }
+}
+
+QTEST_MAIN(tst_QDuplicateTracker)
+
+#include "tst_qduplicatetracker.moc"
diff --git a/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt b/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt
new file mode 100644
index 0000000000..3f76f8a38f
--- /dev/null
+++ b/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qeasingcurve Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qeasingcurve LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qeasingcurve
+ SOURCES
+ tst_qeasingcurve.cpp
+)
diff --git a/tests/auto/corelib/tools/qeasingcurve/qeasingcurve.pro b/tests/auto/corelib/tools/qeasingcurve/qeasingcurve.pro
deleted file mode 100644
index 80c5a94a83..0000000000
--- a/tests/auto/corelib/tools/qeasingcurve/qeasingcurve.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qeasingcurve
-QT = core testlib
-SOURCES = tst_qeasingcurve.cpp
diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
index 0196dd2d23..fc8c1a3e5c 100644
--- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
+++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
@@ -1,38 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qeasingcurve.h>
-#ifdef Q_COMPILER_RVALUE_REFS // cpp11() slot
-# include <utility> // for std::move()
-#endif
+#include <utility> // for std::move()
class tst_QEasingCurve : public QObject
{
@@ -55,6 +28,8 @@ private slots:
void testCbrtFloat();
void cpp11();
void quadraticEquation();
+ void streamInOut_data();
+ void streamInOut();
};
void tst_QEasingCurve::type()
@@ -399,11 +374,16 @@ void tst_QEasingCurve::valueForProgress()
// in theory the baseline should't have an error of more than 0.00005 due to how its rounded,
// but due to FP imprecision, we have to adjust the error a bit more.
const qreal errorBound = 0.00006;
- for (int i = 0; i < at.count(); ++i) {
+ for (int i = 0; i < at.size(); ++i) {
const qreal ex = expected.at(i);
const qreal error = qAbs(ex - curve.valueForProgress(at.at(i)/qreal(100)));
QVERIFY(error <= errorBound);
}
+
+ if (type != QEasingCurve::SineCurve && type != QEasingCurve::CosineCurve) {
+ QVERIFY( !(curve.valueForProgress(0) > 0) );
+ QVERIFY( !(curve.valueForProgress(1) < 1) );
+ }
#endif
}
@@ -423,9 +403,9 @@ void tst_QEasingCurve::setCustomType()
QCOMPARE(curve.valueForProgress(0.15), 0.1);
QCOMPARE(curve.valueForProgress(0.20), 0.2);
QCOMPARE(curve.valueForProgress(0.25), 0.2);
- // QTBUG-69947, MinGW 7.3 returns 0.2
+ // QTBUG-69947, MinGW 7.3, 8.1 x86 returns 0.2
#if defined(Q_CC_MINGW)
-#if !defined(__GNUC__) || __GNUC__ != 7 || __GNUC_MINOR__ < 3
+#if !defined(__GNUC__) || defined(__MINGW64__)
QCOMPARE(curve.valueForProgress(0.30), 0.3);
#endif
#endif
@@ -496,7 +476,7 @@ class tst_QEasingProperties : public QObject
Q_OBJECT
Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing)
public:
- tst_QEasingProperties(QObject *parent = 0) : QObject(parent) {}
+ tst_QEasingProperties(QObject *parent = nullptr) : QObject(parent) {}
QEasingCurve easing() const { return e; }
void setEasing(const QEasingCurve& value) { e = value; }
@@ -541,10 +521,9 @@ void tst_QEasingCurve::properties()
void tst_QEasingCurve::metaTypes()
{
- QVERIFY(QMetaType::type("QEasingCurve") == QMetaType::QEasingCurve);
+ QVERIFY(QMetaType::fromName("QEasingCurve").id() == QMetaType::QEasingCurve);
- QCOMPARE(QByteArray(QMetaType::typeName(QMetaType::QEasingCurve)),
- QByteArray("QEasingCurve"));
+ QCOMPARE(QByteArray(QMetaType(QMetaType::QEasingCurve).name()), QByteArray("QEasingCurve"));
QVERIFY(QMetaType::isRegistered(QMetaType::QEasingCurve));
@@ -595,18 +574,18 @@ void tst_QEasingCurve::bezierSpline_data()
static inline void setupBezierSpline(QEasingCurve *easingCurve, const QString &string)
{
- QStringList pointStr = string.split(QLatin1Char(' '));
+ const QStringList pointStr = string.split(QLatin1Char(' '));
- QVector<QPointF> points;
- foreach (const QString &str, pointStr) {
+ QList<QPointF> points;
+ for (const QString &str : pointStr) {
QStringList coordStr = str.split(QLatin1Char(','));
QPointF point(coordStr.first().toDouble(), coordStr.last().toDouble());
points.append(point);
}
- QVERIFY(points.count() % 3 == 0);
+ QVERIFY(points.size() % 3 == 0);
- for (int i = 0; i < points.count() / 3; i++) {
+ for (int i = 0; i < points.size() / 3; i++) {
QPointF c1 = points.at(i * 3);
QPointF c2 = points.at(i * 3 + 1);
QPointF p1 = points.at(i * 3 + 2);
@@ -624,7 +603,7 @@ void tst_QEasingCurve::bezierSpline()
setupBezierSpline(&bezierEasingCurve, definition);
const qreal errorBound = 0.002;
- for (int i = 0; i < at.count(); ++i) {
+ for (int i = 0; i < at.size(); ++i) {
const qreal ex = expected.at(i);
const qreal value = bezierEasingCurve.valueForProgress(at.at(i)/qreal(100));
const qreal error = qAbs(ex - value);
@@ -632,6 +611,9 @@ void tst_QEasingCurve::bezierSpline()
QCOMPARE(value, ex);
QVERIFY(error <= errorBound);
}
+
+ QVERIFY( !(bezierEasingCurve.valueForProgress(0) > 0) );
+ QVERIFY( !(bezierEasingCurve.valueForProgress(1) < 1) );
}
void tst_QEasingCurve::tcbSpline_data()
@@ -660,11 +642,11 @@ void tst_QEasingCurve::tcbSpline_data()
static inline void setupTCBSpline(QEasingCurve *easingCurve, const QString &string)
{
- QStringList pointStr = string.split(QLatin1Char(' '));
+ const QStringList pointStr = string.split(QLatin1Char(' '));
- foreach (const QString &str, pointStr) {
+ for (const QString &str : pointStr) {
QStringList coordStr = str.split(QLatin1Char(','));
- Q_ASSERT(coordStr.count() == 5);
+ Q_ASSERT(coordStr.size() == 5);
QPointF point(coordStr.first().toDouble(), coordStr.at(1).toDouble());
qreal t = coordStr.at(2).toDouble();
qreal c = coordStr.at(3).toDouble();
@@ -683,7 +665,7 @@ void tst_QEasingCurve::tcbSpline()
setupTCBSpline(&tcbEasingCurve, definition);
const qreal errorBound = 0.002;
- for (int i = 0; i < at.count(); ++i) {
+ for (int i = 0; i < at.size(); ++i) {
const qreal ex = expected.at(i);
const qreal value = tcbEasingCurve.valueForProgress(at.at(i)/qreal(100));
const qreal error = qAbs(ex - value);
@@ -691,6 +673,9 @@ void tst_QEasingCurve::tcbSpline()
QCOMPARE(value, ex);
QVERIFY(error <= errorBound);
}
+
+ QVERIFY( !(tcbEasingCurve.valueForProgress(0) > 0) );
+ QVERIFY( !(tcbEasingCurve.valueForProgress(1) < 1) );
}
/*This is single precision code for a cubic root used inside the spline easing curve.
@@ -792,7 +777,6 @@ void tst_QEasingCurve::testCbrtFloat()
void tst_QEasingCurve::cpp11()
{
-#ifdef Q_COMPILER_RVALUE_REFS
{
QEasingCurve ec( QEasingCurve::InOutBack );
QEasingCurve copy = std::move(ec); // move ctor
@@ -807,7 +791,6 @@ void tst_QEasingCurve::cpp11()
QCOMPARE( copy.type(), QEasingCurve::InOutBack );
QCOMPARE( ec.type(), type );
}
-#endif
}
void tst_QEasingCurve::quadraticEquation() {
@@ -879,5 +862,36 @@ void tst_QEasingCurve::quadraticEquation() {
}
}
+void tst_QEasingCurve::streamInOut_data()
+{
+ QTest::addColumn<int>("version");
+ QTest::addColumn<bool>("equality");
+
+ QTest::newRow("5.11") << int(QDataStream::Qt_5_11) << false;
+ QTest::newRow("5.13") << int(QDataStream::Qt_5_13) << true;
+}
+
+void tst_QEasingCurve::streamInOut()
+{
+ QFETCH(int, version);
+ QFETCH(bool, equality);
+
+ QEasingCurve orig;
+ orig.addCubicBezierSegment(QPointF(0.43, 0.0025), QPointF(0.38, 0.51), QPointF(0.57, 0.99));
+
+ QEasingCurve copy;
+
+ QByteArray data;
+ QDataStream dsw(&data,QIODevice::WriteOnly);
+ QDataStream dsr(&data,QIODevice::ReadOnly);
+
+ dsw.setVersion(version);
+ dsr.setVersion(version);
+ dsw << orig;
+ dsr >> copy;
+
+ QCOMPARE(copy == orig, equality);
+}
+
QTEST_MAIN(tst_QEasingCurve)
#include "tst_qeasingcurve.moc"
diff --git a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/CMakeLists.txt b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/CMakeLists.txt
new file mode 100644
index 0000000000..280918e302
--- /dev/null
+++ b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qexplicitlyshareddatapointer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qexplicitlyshareddatapointer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qexplicitlyshareddatapointer
+ SOURCES
+ tst_qexplicitlyshareddatapointer.cpp
+)
diff --git a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro
deleted file mode 100644
index 45fe1f60fe..0000000000
--- a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/qexplicitlyshareddatapointer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qexplicitlyshareddatapointer
-QT = core testlib
-SOURCES = tst_qexplicitlyshareddatapointer.cpp
diff --git a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
index e89e634841..5e105a090a 100644
--- a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
+++ b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <QtCore/QSharedData>
/*!
@@ -79,8 +54,8 @@ public:
class Derived : public Base
{
public:
- virtual Base *clone() { return new Derived(*this); }
- virtual bool isBase() const { return false; }
+ virtual Base *clone() override { return new Derived(*this); }
+ virtual bool isBase() const override { return false; }
};
QT_BEGIN_NAMESPACE
@@ -169,7 +144,7 @@ void tst_QExplicitlySharedDataPointer::data() const
pointer.data();
/* Check that this cast is possible. */
- static_cast<const MyClass *>(pointer.data());
+ Q_UNUSED(static_cast<const MyClass *>(pointer.data()));
QVERIFY(! (pointer == nullptr));
QVERIFY(! (nullptr == pointer));
@@ -181,7 +156,7 @@ void tst_QExplicitlySharedDataPointer::data() const
pointer.data();
/* Check that this cast is possible. */
- static_cast<const MyClass *>(pointer.data());
+ Q_UNUSED(static_cast<const MyClass *>(pointer.data()));
}
/* Must not mutate the pointer. */
@@ -190,8 +165,8 @@ void tst_QExplicitlySharedDataPointer::data() const
pointer.data();
/* Check that these casts are possible. */
- static_cast<MyClass *>(pointer.data());
- static_cast<const MyClass *>(pointer.data());
+ Q_UNUSED(static_cast<MyClass *>(pointer.data()));
+ Q_UNUSED(static_cast<const MyClass *>(pointer.data()));
}
/* Must not mutate the pointer. */
@@ -200,8 +175,8 @@ void tst_QExplicitlySharedDataPointer::data() const
pointer.data();
/* Check that these casts are possible. */
- static_cast<MyClass *>(pointer.data());
- static_cast<const MyClass *>(pointer.data());
+ Q_UNUSED(static_cast<MyClass *>(pointer.data()));
+ Q_UNUSED(static_cast<const MyClass *>(pointer.data()));
}
}
@@ -248,4 +223,3 @@ void tst_QExplicitlySharedDataPointer::swap() const
QTEST_MAIN(tst_QExplicitlySharedDataPointer)
#include "tst_qexplicitlyshareddatapointer.moc"
-// vim: et:ts=4:sw=4:sts=4
diff --git a/tests/auto/corelib/tools/qflatmap/CMakeLists.txt b/tests/auto/corelib/tools/qflatmap/CMakeLists.txt
new file mode 100644
index 0000000000..bc98c669fc
--- /dev/null
+++ b/tests/auto/corelib/tools/qflatmap/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qflatmap Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qflatmap LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qflatmap
+ SOURCES
+ tst_qflatmap.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp b/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp
new file mode 100644
index 0000000000..986cf2407b
--- /dev/null
+++ b/tests/auto/corelib/tools/qflatmap/tst_qflatmap.cpp
@@ -0,0 +1,732 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#define QT_USE_QSTRINGBUILDER
+#define QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT
+
+#include <QTest>
+
+#include <private/qflatmap_p.h>
+#include <qbytearray.h>
+#include <qstring.h>
+#include <qstringview.h>
+#include <qvarlengtharray.h>
+
+#include <algorithm>
+#include <list>
+#include <tuple>
+
+static constexpr bool is_even(int n) { return n % 2 == 0; }
+static constexpr bool is_empty(QAnyStringView v) { return v.isEmpty(); }
+
+namespace {
+template <typename P>
+constexpr inline bool is_pair_impl_v = false;
+template <typename T, typename S>
+constexpr inline bool is_pair_impl_v<std::pair<T,S>> = true;
+template <typename P>
+constexpr inline bool is_pair_v = is_pair_impl_v<std::decay_t<P>>;
+template <typename P>
+using if_pair = std::enable_if_t<is_pair_v<P>, bool>;
+}
+
+class tst_QFlatMap : public QObject
+{
+ Q_OBJECT
+private slots:
+ void constructing();
+ void constAccess();
+ void insertion();
+ void insertRValuesAndLValues();
+ void removal();
+ void extraction();
+ void iterators();
+ void remove_if_pair() { remove_if_impl([](const auto &p) -> if_pair<decltype(p)> { return is_even(p.first) && is_empty(p.second); }); }
+ void remove_if_key_value() { remove_if_impl([](const auto &k, const auto &v) { return is_even(k) && is_empty(v); }); }
+ void remove_if_key() { remove_if_impl([](int k) { return is_even(k); }, true); }
+ void statefulComparator();
+ void transparency_using();
+ void transparency_struct();
+ void try_emplace_and_insert_or_assign();
+ void viewIterators();
+ void varLengthArray();
+
+private:
+ template <typename Compare>
+ void transparency_impl();
+ template <typename Predicate>
+ void remove_if_impl(Predicate p, bool removeNonEmptyValues = false);
+};
+
+void tst_QFlatMap::constructing()
+{
+ using Map = QFlatMap<int, QByteArray>;
+ Map fmDefault;
+ QVERIFY(fmDefault.isEmpty());
+ QCOMPARE(fmDefault.size(), Map::size_type(0));
+ QCOMPARE(fmDefault.size(), fmDefault.count());
+
+ auto key_compare = fmDefault.key_comp();
+ auto selfbuilt_value_compare
+ = [&key_compare](const Map::value_type &a, const Map::value_type &b)
+ {
+ return key_compare(a.first, b.first);
+ };
+ auto value_compare = fmDefault.value_comp();
+
+ Map::key_container_type kv = { 6, 2, 1 };
+ Map::mapped_container_type mv = { "foo", "bar", "baz" };
+ Map fmCopy{kv, mv};
+ QCOMPARE(fmCopy.size(), Map::size_type(3));
+ QVERIFY(std::is_sorted(fmCopy.begin(), fmCopy.end(), selfbuilt_value_compare));
+ QVERIFY(std::is_sorted(fmCopy.begin(), fmCopy.end(), value_compare));
+
+ Map fmMove{
+ Map::key_container_type{ 6, 2, 1 },
+ Map::mapped_container_type{ "foo", "bar", "baz" }
+ };
+ QCOMPARE(fmMove.size(), Map::size_type(3));
+ QVERIFY(std::is_sorted(fmMove.begin(), fmMove.end(), value_compare));
+
+ auto fmInitList = Map{ { 1, 2 }, { "foo", "bar" } };
+ QVERIFY(std::is_sorted(fmInitList.begin(), fmInitList.end(), value_compare));
+
+ auto fmRange = Map(fmCopy.begin(), fmCopy.end());
+ QVERIFY(std::is_sorted(fmRange.begin(), fmRange.end(), value_compare));
+
+ kv.clear();
+ mv.clear();
+ std::vector<Map::value_type> sv;
+ for (auto it = fmRange.begin(); it != fmRange.end(); ++it) {
+ kv.push_back(it->first);
+ mv.push_back(it->second);
+ sv.push_back(*it);
+ }
+ auto fmFromSortedVectorCopy = Map(Qt::OrderedUniqueRange, kv, mv);
+ auto fmFromSortedVectorMove = Map(Qt::OrderedUniqueRange, Map::key_container_type(kv),
+ Map::mapped_container_type(mv));
+ auto fmFromSortedInitList = Map(Qt::OrderedUniqueRange, { { 1, "foo" }, { 2, "bar" } });
+ auto fmFromSortedRange = Map(Qt::OrderedUniqueRange, sv.begin(), sv.end());
+}
+
+void tst_QFlatMap::constAccess()
+{
+ using Map = QFlatMap<QByteArray, QByteArray>;
+ const Map m{ { { "foo", "FOO" }, { "bar", "BAR" } } };
+
+ const std::vector<Map::value_type> v{ { "foo", "FOO" }, { "bar", "BAR" } };
+
+ QCOMPARE(m.value("foo").data(), "FOO");
+ QCOMPARE(m.value("bar").data(), "BAR");
+ QCOMPARE(m.value("nix"), QByteArray());
+ QCOMPARE(m.value("nix", "NIX").data(), "NIX");
+ QCOMPARE(m["foo"].data(), "FOO");
+ QCOMPARE(m["bar"].data(), "BAR");
+ QCOMPARE(m["nix"], QByteArray());
+ QVERIFY(m.contains("foo"));
+ QVERIFY(!m.contains("nix"));
+}
+
+void tst_QFlatMap::insertion()
+{
+ using Map = QFlatMap<QByteArray, QByteArray>;
+ Map m;
+ QByteArray foo = "foo";
+ m[foo] = foo.toUpper();
+ m["bar"] = "BAR";
+ m["baz"] = "BAZ";
+ QVERIFY(m.insert("oof", "eek").second);
+ QVERIFY(!m.insert("oof", "OOF").second);
+ const std::vector<Map::value_type> container = { { "bla", "BLA" }, { "blubb", "BLUBB" } };
+ m.insert(container.begin(), container.end());
+ QCOMPARE(m.value("foo").data(), "FOO");
+ QCOMPARE(m.value("bar").data(), "BAR");
+ QCOMPARE(m.value("baz").data(), "BAZ");
+ QCOMPARE(m.value("oof").data(), "eek");
+ QCOMPARE(m.value("bla").data(), "BLA");
+ QCOMPARE(m.value("blubb").data(), "BLUBB");
+
+ Map::value_type a1[] = { { "narf", "NARF" },
+ { "zort", "ZORT" },
+ { "troz", "TROZ" } };
+ Map::value_type a2[] = { { "gnampf", "GNAMPF" },
+ { "narf", "NARFFFF" },
+ { "narf", "NARFFFFF" },
+ { "narf", "NARFFFFFF" } };
+ m.insert(std::begin(a1), std::end(a1));
+ m.insert(Qt::OrderedUniqueRange, std::begin(a2), std::end(a2));
+ QCOMPARE(m.size(), 10);
+ QCOMPARE(m.value("narf").data(), "NARF");
+ QCOMPARE(m.value("gnampf").data(), "GNAMPF");
+}
+
+void tst_QFlatMap::insertRValuesAndLValues()
+{
+ using Map = QFlatMap<QByteArray, QByteArray>;
+ const QByteArray foo = QByteArrayLiteral("foo");
+ const QByteArray bar = QByteArrayLiteral("bar");
+
+ auto rvalue = [](const QByteArray &ba) { return ba; };
+#define lvalue(x) x
+
+ {
+ Map m;
+ QVERIFY( m.insert(lvalue(foo), lvalue(bar)).second);
+ QVERIFY(!m.insert(lvalue(foo), lvalue(bar)).second);
+ }
+
+ {
+ Map m;
+ QVERIFY( m.insert(lvalue(foo), rvalue(bar)).second);
+ QVERIFY(!m.insert(lvalue(foo), rvalue(bar)).second);
+ }
+
+ {
+ Map m;
+ QVERIFY( m.insert(rvalue(foo), lvalue(bar)).second);
+ QVERIFY(!m.insert(rvalue(foo), lvalue(bar)).second);
+ }
+
+ {
+ Map m;
+ QVERIFY( m.insert(rvalue(foo), rvalue(bar)).second);
+ QVERIFY(!m.insert(rvalue(foo), rvalue(bar)).second);
+ }
+
+#undef lvalue
+}
+
+void tst_QFlatMap::extraction()
+{
+ using Map = QFlatMap<int, QByteArray>;
+ Map::key_container_type expectedKeys = { 1, 2, 3 };
+ Map::mapped_container_type expectedValues = { "een", "twee", "dree" };
+ Map m(Qt::OrderedUniqueRange, expectedKeys, expectedValues);
+ auto keys = m.keys();
+ auto values = m.values();
+ QCOMPARE(keys, expectedKeys);
+ QCOMPARE(values, expectedValues);
+ Map::containers c = std::move(m).extract();
+ QCOMPARE(c.keys, expectedKeys);
+ QCOMPARE(c.values, expectedValues);
+}
+
+void tst_QFlatMap::iterators()
+{
+ using Map = QFlatMap<int, QByteArray>;
+ auto m = Map{ Qt::OrderedUniqueRange, { { 1, "foo" }, { 2, "bar" }, { 3, "baz" } } };
+ {
+ // forward / backward
+ Map::iterator a = m.begin();
+ QVERIFY(a != m.end());
+ QCOMPARE(a.key(), 1);
+ QCOMPARE(a.value(), "foo");
+ ++a;
+ QCOMPARE(a.key(), 2);
+ QCOMPARE(a.value(), "bar");
+ Map::iterator b = a++;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(2, "bar"));
+ QCOMPARE(++a, m.end());
+ --a;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ a.value() = "buzz";
+ b = a--;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar"));
+ QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(3, "buzz"));
+ b.value() = "baz";
+
+ // random access
+ a = m.begin();
+ a += 2;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ a = m.begin() + 1;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar"));
+ a = 1 + m.begin();
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar"));
+ a = m.end() - 1;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ b = m.end();
+ b -= 1;
+ QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(3, "baz"));
+ QCOMPARE(m.end() - m.begin(), m.size());
+
+ // comparison
+ a = m.begin() + m.size() - 1;
+ b = m.end() - 1;
+ QVERIFY(a == b);
+ a = m.begin();
+ b = m.end();
+ QVERIFY(a < b);
+ QVERIFY(a <= b);
+ QVERIFY(b > a);
+ QVERIFY(b >= a);
+ a = b;
+ QVERIFY(!(a < b));
+ QVERIFY(a <= b);
+ QVERIFY(!(b > a));
+ QVERIFY(b >= a);
+
+ // de-referencing
+ a = m.begin();
+ auto ref0 = *a;
+ QCOMPARE(ref0.first, 1);
+ QCOMPARE(ref0.second, "foo");
+ auto ref1 = a[1];
+ QCOMPARE(ref1.first, 2);
+ QCOMPARE(ref1.second, "bar");
+ }
+ {
+ // forward / backward
+ Map::const_iterator a = m.cbegin();
+ QVERIFY(a != m.cend());
+ QCOMPARE(a.key(), 1);
+ QCOMPARE(a.value(), "foo");
+ ++a;
+ QCOMPARE(a.key(), 2);
+ QCOMPARE(a.value(), "bar");
+ Map::const_iterator b = a++;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(2, "bar"));
+ QCOMPARE(++a, m.cend());
+ --a;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ b = a--;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar"));
+
+ // random access
+ a = m.cbegin();
+ a += 2;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ a = m.cbegin() + 1;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar"));
+ a = 1 + m.cbegin();
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(2, "bar"));
+ a = m.cend() - 1;
+ QCOMPARE(std::tie(a.key(), a.value()), std::make_tuple(3, "baz"));
+ b = m.cend();
+ b -= 1;
+ QCOMPARE(std::tie(b.key(), b.value()), std::make_tuple(3, "baz"));
+ QCOMPARE(m.cend() - m.cbegin(), m.size());
+
+ // comparison
+ a = m.cbegin() + m.size() - 1;
+ b = m.cend() - 1;
+ QVERIFY(a == b);
+ a = m.cbegin();
+ b = m.cend();
+ QVERIFY(a < b);
+ QVERIFY(a <= b);
+ QVERIFY(b > a);
+ QVERIFY(b >= a);
+ a = b;
+ QVERIFY(!(a < b));
+ QVERIFY(a <= b);
+ QVERIFY(!(b > a));
+ QVERIFY(b >= a);
+
+ // de-referencing
+ a = m.cbegin();
+ auto ref0 = *a;
+ QCOMPARE(ref0.first, 1);
+ QCOMPARE(ref0.second, "foo");
+ auto ref1 = a[1];
+ QCOMPARE(ref1.first, 2);
+ QCOMPARE(ref1.second, "bar");
+ }
+ {
+ Map::iterator it = m.begin();
+ Map::const_iterator cit = it;
+ Q_UNUSED(it);
+ Q_UNUSED(cit);
+ }
+ {
+ std::list<Map::value_type> revlst;
+ std::copy(m.begin(), m.end(), std::front_inserter(revlst));
+ std::vector<Map::value_type> v0;
+ std::copy(revlst.begin(), revlst.end(), std::back_inserter(v0));
+ std::vector<Map::value_type> v1;
+ std::copy(m.rbegin(), m.rend(), std::back_inserter(v1));
+ const Map cm = m;
+ std::vector<Map::value_type> v2;
+ std::copy(cm.rbegin(), cm.rend(), std::back_inserter(v2));
+ std::vector<Map::value_type> v3;
+ std::copy(m.crbegin(), m.crend(), std::back_inserter(v3));
+ QCOMPARE(v0, v1);
+ QCOMPARE(v1, v2);
+ QCOMPARE(v2, v3);
+ }
+}
+
+template <typename Pred>
+void tst_QFlatMap::remove_if_impl(Pred p, bool removeNonEmptyValues)
+{
+ // empty stays empty:
+ {
+ QFlatMap<int, QString> m;
+ QCOMPARE(m.remove_if(p), 0);
+ QVERIFY(m.isEmpty());
+ }
+ // a matching element is removed:
+ {
+ {
+ QFlatMap<int, QString> m;
+ m.insert_or_assign(0, "");
+ QCOMPARE(m.remove_if(p), 1);
+ QVERIFY(m.isEmpty());
+ }
+ if (removeNonEmptyValues) {
+ QFlatMap<int, QString> m;
+ m.insert_or_assign(0, "x");
+ QCOMPARE(m.remove_if(p), 1);
+ QVERIFY(m.isEmpty());
+ }
+ }
+ // a non-matching element is not removed:
+ {
+ {
+ QFlatMap<int, QString> m;
+ m.insert_or_assign(1, "");
+ QCOMPARE(m.remove_if(p), 0);
+ QVERIFY(m.contains(1));
+ QVERIFY(m[1].isEmpty());
+ }
+ if (removeNonEmptyValues) {
+ QFlatMap<int, QString> m;
+ m.insert_or_assign(1, "x");
+ QCOMPARE(m.remove_if(p), 0);
+ QVERIFY(m.contains(1));
+ QCOMPARE(m[1], "x");
+ }
+ }
+ // of matching and non-matching elements, only matching ones are removed:
+ {
+ {
+ QFlatMap<int, QString> m;
+ m.insert_or_assign(0, "");
+ m.insert_or_assign(1, "");
+ const auto copy = m;
+ QCOMPARE(m.remove_if(p), 1);
+ QCOMPARE(copy.size(), 2);
+ QCOMPARE(copy[0], "");
+ QCOMPARE(copy[1], "");
+ QCOMPARE(m.size(), 1);
+ QVERIFY(m.contains(1));
+ QVERIFY(m[1].isEmpty());
+ }
+ {
+ QFlatMap<int, QString> m;
+ m.insert_or_assign(1, "");
+ m.insert_or_assign(2, "");
+ QCOMPARE(m.remove_if(p), 1);
+ QCOMPARE(m.size(), 1);
+ QVERIFY(m.contains(1));
+ QVERIFY(m[1].isEmpty());
+ }
+ }
+}
+
+void tst_QFlatMap::removal()
+{
+ using Map = QFlatMap<int, QByteArray>;
+ Map m({ { 2, "bar" }, { 3, "baz" }, { 1, "foo" } });
+ QCOMPARE(m.value(2).data(), "bar");
+ QCOMPARE(m.take(2).data(), "bar");
+ QVERIFY(!m.contains(2));
+ QCOMPARE(m.size(), Map::size_type(2));
+ QVERIFY(m.remove(1));
+ QVERIFY(!m.contains(1));
+ QVERIFY(!m.remove(1));
+ QCOMPARE(m.size(), Map::size_type(1));
+ m.clear();
+ QVERIFY(m.isEmpty());
+ QVERIFY(m.empty());
+
+ m[1] = "een";
+ m[2] = "twee";
+ m[3] = "dree";
+ auto it = m.lower_bound(1);
+ QCOMPARE(it.key(), 1);
+ it = m.erase(it);
+ QCOMPARE(it.key(), 2);
+ QVERIFY(!m.contains(1));
+}
+
+void tst_QFlatMap::statefulComparator()
+{
+ struct CountingCompare {
+ mutable int count = 0;
+
+ bool operator()(const QString &lhs, const QString &rhs) const
+ {
+ ++count;
+ return lhs < rhs;
+ }
+ };
+
+ using Map = QFlatMap<QString, QString, CountingCompare>;
+ auto m1 = Map{ { "en", "een"}, { "to", "twee" }, { "tre", "dree" } };
+ QVERIFY(m1.key_comp().count > 0);
+ auto m2 = Map(m1.key_comp());
+ QCOMPARE(m2.key_comp().count, m1.key_comp().count);
+ m2.insert(m1.begin(), m1.end());
+ QVERIFY(m2.key_comp().count > m1.key_comp().count);
+}
+
+void tst_QFlatMap::transparency_using()
+{
+ struct StringViewCompare
+ {
+ using is_transparent [[maybe_unused]] = void;
+ bool operator()(QAnyStringView lhs, QAnyStringView rhs) const
+ {
+ return lhs < rhs;
+ }
+ };
+ transparency_impl<StringViewCompare>();
+}
+
+void tst_QFlatMap::transparency_struct()
+{
+ struct StringViewCompare
+ {
+ struct is_transparent {};
+ bool operator()(QAnyStringView lhs, QAnyStringView rhs) const
+ {
+ return lhs < rhs;
+ }
+ };
+ transparency_impl<StringViewCompare>();
+}
+
+template <typename StringViewCompare>
+void tst_QFlatMap::transparency_impl()
+{
+ using Map = QFlatMap<QString, QString, StringViewCompare>;
+ auto m = Map{ { "one", "een" }, { "two", "twee" }, { "three", "dree" } };
+
+ const QString numbers = "one two three";
+ const QStringView sv1{numbers.constData(), 3};
+ const QStringView sv2{numbers.constData() + 4, 3};
+ const QStringView sv3{numbers.constData() + 8, 5};
+ QCOMPARE(m.lower_bound(sv1).value(), "een");
+ QCOMPARE(m.value(sv1), "een");
+ QCOMPARE(m.lower_bound(sv2).value(), "twee");
+ QCOMPARE(m.value(sv2), "twee");
+ QCOMPARE(m.lower_bound(sv3).value(), "dree");
+ QCOMPARE(m.value(sv3), "dree");
+
+ QVERIFY(m.contains(sv2));
+ auto twee = m.take(sv2);
+ static_assert(std::is_same_v<decltype(twee), QString>);
+ QCOMPARE(twee, "twee");
+ QVERIFY(!m.contains(sv2));
+
+ QVERIFY(m.contains(QLatin1String("one")));
+ QVERIFY(m.remove(QAnyStringView(u8"one")));
+ QVERIFY(!m.contains(QLatin1String("one")));
+}
+
+void tst_QFlatMap::try_emplace_and_insert_or_assign()
+{
+ using Map = QFlatMap<QByteArray, QByteArray>;
+
+ const QByteArray foo = QByteArrayLiteral("foo");
+ const qsizetype qqq_1 = 3;
+ const char qqq_2 = 'q';
+ const QByteArray qqq = QByteArray(qqq_1, qqq_2);
+
+ auto sb = [] (const auto &str) { return str % ""; };
+ auto rvalue = [](const auto &x) { return x; };
+#define lvalue(x) x
+#define CHECKS() \
+ do { \
+ QVERIFY(!m.try_emplace(rvalue(foo), lvalue(foo)).second); \
+ QCOMPARE(m.value(foo), qqq); \
+ QVERIFY(!m.try_emplace(lvalue(foo), lvalue(foo)).second); \
+ QCOMPARE(m.value(foo), qqq); \
+ QVERIFY(!m.try_emplace(lvalue(foo), sb(foo)).second); \
+ QCOMPARE(m.value(foo), qqq); \
+ QVERIFY(!m.try_emplace(rvalue(foo), sb(foo)).second); \
+ QCOMPARE(m.value(foo), qqq); \
+ } while (0) \
+ /* end */
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(lvalue(foo), lvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.insert_or_assign(lvalue(foo), lvalue(foo)).second);
+ QCOMPARE(m.value(foo), foo);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.insert_or_assign(lvalue(foo), lvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.try_emplace(lvalue(foo), lvalue(foo)).second);
+ QCOMPARE(m.value(foo), qqq);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(lvalue(foo), rvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.insert_or_assign(lvalue(foo), rvalue(foo)).second);
+ QCOMPARE(m.value(foo), foo);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.insert_or_assign(lvalue(foo), rvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.try_emplace(lvalue(foo), rvalue(foo)).second);
+ QCOMPARE(m.value(foo), qqq);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(lvalue(foo), qqq_1, qqq_2).second);
+ QCOMPARE(m.value(foo), qqq);
+ CHECKS();
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(lvalue(foo), sb(qqq)).second);
+ QCOMPARE(m.value(foo), qqq);
+ CHECKS();
+ QVERIFY(!m.insert_or_assign(lvalue(foo), sb(foo)).second);
+ QCOMPARE(m.value(foo), foo);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.insert_or_assign(lvalue(foo), sb(qqq)).second);
+ QCOMPARE(m.value(foo), qqq);
+ CHECKS();
+ QVERIFY(!m.try_emplace(lvalue(foo), sb(foo)).second);
+ QCOMPARE(m.value(foo), qqq);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(rvalue(foo), lvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.insert_or_assign(rvalue(foo), lvalue(foo)).second);
+ QCOMPARE(m.value(foo), foo);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.insert_or_assign(rvalue(foo), lvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.try_emplace(rvalue(foo), lvalue(foo)).second);
+ QCOMPARE(m.value(foo), qqq);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(rvalue(foo), rvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.insert_or_assign(rvalue(foo), rvalue(foo)).second);
+ QCOMPARE(m.value(foo), foo);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.insert_or_assign(rvalue(foo), rvalue(qqq)).second);
+ CHECKS();
+ QVERIFY(!m.try_emplace(rvalue(foo), rvalue(foo)).second);
+ QCOMPARE(m.value(foo), qqq);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(rvalue(foo), qqq_1, qqq_2).second);
+ QCOMPARE(m.value(foo), qqq);
+ CHECKS();
+ }
+
+ {
+ Map m;
+ QVERIFY(m.try_emplace(rvalue(foo), sb(qqq)).second);
+ QCOMPARE(m.value(foo), qqq);
+ CHECKS();
+ QVERIFY(!m.insert_or_assign(rvalue(foo), sb(foo)).second);
+ QCOMPARE(m.value(foo), foo);
+ }
+
+ {
+ Map m;
+ QVERIFY(m.insert_or_assign(rvalue(foo), sb(qqq)).second);
+ QCOMPARE(m.value(foo), qqq);
+ CHECKS();
+ QVERIFY(!m.try_emplace(rvalue(foo), sb(foo)).second);
+ QCOMPARE(m.value(foo), qqq);
+ }
+#undef CHECKS
+#undef lvalue
+}
+
+void tst_QFlatMap::viewIterators()
+{
+ using Map = QFlatMap<QByteArray, QByteArray>;
+ Map m({ { "yksi", "een"}, { "kaksi", "twee" }, { "kolme", "dree" } });
+ {
+ std::vector<QByteArray> keys;
+ std::transform(m.begin(), m.end(), std::back_inserter(keys),
+ [](const Map::value_type &v)
+ {
+ return v.first;
+ });
+ auto it = keys.begin();
+ QCOMPARE(*it, "kaksi");
+ QCOMPARE(it->size(), 5);
+ ++it;
+ QCOMPARE(*it, "kolme");
+ it++;
+ QCOMPARE(*it, "yksi");
+ ++it;
+ QCOMPARE(it, keys.end());
+ --it;
+ QCOMPARE(*it, "yksi");
+ it--;
+ QCOMPARE(*it, "kolme");
+ }
+ {
+ std::vector<QByteArray> values;
+ std::transform(m.begin(), m.end(), std::back_inserter(values),
+ [](const Map::value_type &v)
+ {
+ return v.second;
+ });
+ auto it = values.begin();
+ QCOMPARE(*it, "twee");
+ QCOMPARE(it->size(), 4);
+ ++it;
+ QCOMPARE(*it, "dree");
+ it++;
+ QCOMPARE(*it, "een");
+ ++it;
+ QCOMPARE(it, values.end());
+ --it;
+ QCOMPARE(*it, "een");
+ it--;
+ QCOMPARE(*it, "dree");
+ }
+}
+
+void tst_QFlatMap::varLengthArray()
+{
+ using Map = QVarLengthFlatMap<int, QByteArray, 1024>;
+ Map m(Qt::OrderedUniqueRange, { { 2, "twee" } });
+ m.insert_or_assign(1, "een");
+ m.remove(1);
+ QVERIFY(!m.isEmpty());
+ m.remove(2);
+ QVERIFY(m.isEmpty());
+}
+
+QTEST_APPLESS_MAIN(tst_QFlatMap)
+#include "tst_qflatmap.moc"
diff --git a/tests/auto/corelib/tools/qfreelist/CMakeLists.txt b/tests/auto/corelib/tools/qfreelist/CMakeLists.txt
new file mode 100644
index 0000000000..a37d3131f5
--- /dev/null
+++ b/tests/auto/corelib/tools/qfreelist/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qfreelist Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfreelist LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qfreelist
+ SOURCES
+ tst_qfreelist.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qfreelist/qfreelist.pro b/tests/auto/corelib/tools/qfreelist/qfreelist.pro
deleted file mode 100644
index 4825987bcf..0000000000
--- a/tests/auto/corelib/tools/qfreelist/qfreelist.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qfreelist
-QT = core-private testlib
-SOURCES = tst_qfreelist.cpp
-!qtConfig(private_tests): SOURCES += $$QT_SOURCE_TREE/src/corelib/tools/qfreelist.cpp
diff --git a/tests/auto/corelib/tools/qfreelist/tst_qfreelist.cpp b/tests/auto/corelib/tools/qfreelist/tst_qfreelist.cpp
index a09bcd5121..a45fa6d400 100644
--- a/tests/auto/corelib/tools/qfreelist/tst_qfreelist.cpp
+++ b/tests/auto/corelib/tools/qfreelist/tst_qfreelist.cpp
@@ -1,38 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtCore/QElapsedTimer>
#include <QtCore/QList>
#include <QtCore/QThread>
#include <private/qfreelist_p.h>
-#include <QtTest/QtTest>
+#include <QTest>
class tst_QFreeList : public QObject
{
@@ -120,7 +94,7 @@ class FreeListThread : public QThread
public:
inline FreeListThread() : QThread() { }
- inline void run()
+ inline void run() override
{
QElapsedTimer t;
t.start();
@@ -141,7 +115,7 @@ public:
needToRelease << i;
} while (t.elapsed() < TimeLimit);
- foreach (int x, needToRelease)
+ for (int x : std::as_const(needToRelease))
freelist.release(x);
}
};
diff --git a/tests/auto/corelib/tools/qhash/CMakeLists.txt b/tests/auto/corelib/tools/qhash/CMakeLists.txt
new file mode 100644
index 0000000000..8702b8bf23
--- /dev/null
+++ b/tests/auto/corelib/tools/qhash/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qhash Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qhash LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qhash
+ SOURCES
+ tst_qhash.cpp
+)
+
+qt_internal_undefine_global_definition(tst_qhash QT_NO_JAVA_STYLE_ITERATORS)
diff --git a/tests/auto/corelib/tools/qhash/qhash.pro b/tests/auto/corelib/tools/qhash/qhash.pro
deleted file mode 100644
index 79ffd4e9d1..0000000000
--- a/tests/auto/corelib/tools/qhash/qhash.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qhash
-QT = core testlib
-SOURCES = $$PWD/tst_qhash.cpp
diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
index 0015efacfa..b3dbdfa40c 100644
--- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp
+++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
@@ -1,38 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <QTest>
+
+#include <qdebug.h>
#include <qhash.h>
#include <qmap.h>
+#include <qscopeguard.h>
+#include <qset.h>
#include <algorithm>
#include <vector>
+#include <unordered_set>
+#include <string>
+
+#include <qsemaphore.h>
+
+using namespace Qt::StringLiterals;
class tst_QHash : public QObject
{
@@ -40,7 +24,9 @@ class tst_QHash : public QObject
private slots:
void insert1();
void erase();
+ void erase_edge_case();
void key();
+ void keys();
void swap();
void count(); // copied from tst_QMap
@@ -52,30 +38,77 @@ private slots:
void qhash();
void take(); // copied from tst_QMap
void operator_eq(); // slightly modified from tst_QMap
+ void heterogeneousSearch();
+ void heterogeneousSearchConstKey();
+ void heterogeneousSearchByteArray();
+ void heterogeneousSearchString();
+ void heterogeneousSearchLatin1String();
+
void rehash_isnt_quadratic();
void dont_need_default_constructor();
void qmultihash_specific();
+ void qmultihash_qhash_rvalue_ref_ctor();
+ void qmultihash_qhash_rvalue_ref_unite();
+ void qmultihashUnite();
+ void qmultihashSize();
+ void qmultihashHeterogeneousSearch();
+ void qmultihashHeterogeneousSearchConstKey();
+ void qmultihashHeterogeneousSearchByteArray();
+ void qmultihashHeterogeneousSearchString();
+ void qmultihashHeterogeneousSearchLatin1String();
void compare();
void compare2();
void iterators(); // sligthly modified from tst_QMap
+ void multihashIterators();
+ void iteratorsInEmptyHash();
void keyIterator();
+ void multihashKeyIterator();
void keyValueIterator();
+ void multihashKeyValueIterator();
+ void keyValueIteratorInEmptyHash();
void keys_values_uniqueKeys(); // slightly modified from tst_QMap
- void noNeedlessRehashes();
void const_shared_null();
void twoArguments_qHash();
void initializerList();
void eraseValidIteratorOnSharedHash();
void equal_range();
+ void insert_hash();
+ void multiHashStoresInReverseInsertionOrder();
+
+ void emplace();
+
+ void badHashFunction();
+ void hashOfHash();
+
+ void stdHash();
+
+ void countInEmptyHash();
+ void removeInEmptyHash();
+ void valueInEmptyHash();
+ void fineTuningInEmptyHash();
+
+ void reserveShared();
+ void reserveLessThanCurrentAmount();
+ void reserveKeepCapacity_data();
+ void reserveKeepCapacity();
+
+ void QTBUG98265();
+
+ void detachAndReferences();
+
+ void lookupUsingKeyIterator();
+
+ void squeeze();
+ void squeezeShared();
};
struct IdentityTracker {
int value, id;
};
-inline uint qHash(IdentityTracker key) { return qHash(key.value); }
+inline size_t qHash(IdentityTracker key) { return qHash(key.value); }
inline bool operator==(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value == rhs.value; }
@@ -84,6 +117,8 @@ struct Foo {
Foo():c(count) { ++count; }
Foo(const Foo& o):c(o.c) { ++count; }
~Foo() { --count; }
+ constexpr Foo &operator=(const Foo &o) noexcept { c = o.c; return *this; }
+
int c;
int data[8];
};
@@ -94,26 +129,53 @@ int Foo::count = 0;
class MyClass
{
public:
- MyClass() { ++count;
+ MyClass()
+ {
+ ++count;
}
- MyClass( const QString& c) {
- count++; str = c;
+ MyClass( const QString& c)
+ {
+ count++;
+ str = c;
+ }
+ MyClass(const QString &a, const QString &b)
+ {
+ count++;
+ str = a + b;
}
~MyClass() {
count--;
}
MyClass( const MyClass& c ) {
- count++; str = c.str;
+ count++;
+ ++copies;
+ str = c.str;
}
MyClass &operator =(const MyClass &o) {
- str = o.str; return *this;
+ str = o.str;
+ ++copies;
+ return *this;
+ }
+ MyClass(MyClass &&c) {
+ count++;
+ ++moves;
+ str = c.str;
+ }
+ MyClass &operator =(MyClass &&o) {
+ str = o.str;
+ ++moves;
+ return *this;
}
QString str;
static int count;
+ static int copies;
+ static int moves;
};
-int MyClass::count = 0;
+int MyClass::count = 0;
+int MyClass::copies = 0;
+int MyClass::moves = 0;
typedef QHash<QString, MyClass> MyMap;
@@ -123,13 +185,13 @@ void tst_QHash::count()
{
MyMap map;
MyMap map2( map );
- QCOMPARE( map.count(), 0 );
- QCOMPARE( map2.count(), 0 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map2.size(), 0 );
QCOMPARE( MyClass::count, 0 );
// detach
map2["Hallo"] = MyClass( "Fritz" );
- QCOMPARE( map.count(), 0 );
- QCOMPARE( map2.count(), 1 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map2.size(), 1 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 1 );
#endif
@@ -139,11 +201,11 @@ void tst_QHash::count()
{
typedef QHash<QString, MyClass> Map;
Map map;
- QCOMPARE( map.count(), 0);
+ QCOMPARE( map.size(), 0);
map.insert( "Torben", MyClass("Weis") );
- QCOMPARE( map.count(), 1 );
+ QCOMPARE( map.size(), 1 );
map.insert( "Claudia", MyClass("Sorg") );
- QCOMPARE( map.count(), 2 );
+ QCOMPARE( map.size(), 2 );
map.insert( "Lars", MyClass("Linzbach") );
map.insert( "Matthias", MyClass("Ettrich") );
map.insert( "Sue", MyClass("Paludo") );
@@ -151,7 +213,7 @@ void tst_QHash::count()
map.insert( "Haavard", MyClass("Nord") );
map.insert( "Arnt", MyClass("Gulbrandsen") );
map.insert( "Paul", MyClass("Tvete") );
- QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.size(), 9 );
map.insert( "Paul", MyClass("Tvete 1") );
map.insert( "Paul", MyClass("Tvete 2") );
map.insert( "Paul", MyClass("Tvete 3") );
@@ -159,68 +221,68 @@ void tst_QHash::count()
map.insert( "Paul", MyClass("Tvete 5") );
map.insert( "Paul", MyClass("Tvete 6") );
- QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.size(), 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
Map map2( map );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.insert( "Kay", MyClass("Roemer") );
- QVERIFY( map2.count() == 10 );
- QVERIFY( map.count() == 9 );
+ QVERIFY( map2.size() == 10 );
+ QVERIFY( map.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 19 );
#endif
map2 = map;
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.insert( "Kay", MyClass("Roemer") );
- QVERIFY( map2.count() == 10 );
+ QVERIFY( map2.size() == 10 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 19 );
#endif
map2.clear();
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2 = map;
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.clear();
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map.remove( "Lars" );
- QVERIFY( map.count() == 8 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 8 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 8 );
#endif
map.remove( "Mist" );
- QVERIFY( map.count() == 8 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 8 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 8 );
#endif
@@ -234,22 +296,22 @@ void tst_QHash::count()
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 1 );
#endif
- QVERIFY( map.count() == 1 );
+ QVERIFY( map.size() == 1 );
(void)map["Torben"].str;
(void)map["Lars"].str;
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 2 );
#endif
- QVERIFY( map.count() == 2 );
+ QVERIFY( map.size() == 2 );
const Map& cmap = map;
(void)cmap["Depp"].str;
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 2 );
#endif
- QVERIFY( map.count() == 2 );
- QVERIFY( cmap.count() == 2 );
+ QVERIFY( map.size() == 2 );
+ QVERIFY( cmap.size() == 2 );
}
QCOMPARE( MyClass::count, 0 );
{
@@ -273,19 +335,19 @@ void tst_QHash::insert1()
{
typedef QHash<QString, QString> Hash;
Hash hash;
- QString key;
+ QString key = QLatin1String(" ");
for (int i = 0; i < 10; ++i) {
- key[0] = i + '0';
+ key[0] = QChar(i + '0');
for (int j = 0; j < 10; ++j) {
- key[1] = j + '0';
+ key[1] = QChar(j + '0');
hash.insert(key, "V" + key);
}
}
for (int i = 0; i < 10; ++i) {
- key[0] = i + '0';
+ key[0] = QChar(i + '0');
for (int j = 0; j < 10; ++j) {
- key[1] = j + '0';
+ key[1] = QChar(j + '0');
hash.remove(key);
}
}
@@ -300,6 +362,8 @@ void tst_QHash::insert1()
QVERIFY(hash.size() == 2);
QVERIFY(!hash.isEmpty());
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
{
Hash hash2 = hash;
hash2 = hash;
@@ -312,6 +376,7 @@ void tst_QHash::insert1()
QVERIFY(hash2.isEmpty());
}
QVERIFY(hash.size() == 2);
+QT_WARNING_POP
{
Hash hash2 = hash;
@@ -441,6 +506,7 @@ void tst_QHash::insert1()
{
QHash<IdentityTracker, int> hash;
QCOMPARE(hash.size(), 0);
+ QVERIFY(!hash.isDetached());
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(hash.insert(id00, id00.id).key().id, id00.id);
@@ -450,20 +516,6 @@ void tst_QHash::insert1()
QCOMPARE(hash.find(searchKey).value(), id01.id); // last-inserted value
QCOMPARE(hash.find(searchKey).key().id, id00.id); // but first-inserted key
}
- {
- QMultiHash<IdentityTracker, int> hash;
- QCOMPARE(hash.size(), 0);
- const int dummy = -1;
- IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
- QCOMPARE(hash.insert(id00, id00.id).key().id, id00.id);
- QCOMPARE(hash.size(), 1);
- QCOMPARE(hash.insert(id01, id01.id).key().id, id01.id);
- QCOMPARE(hash.size(), 2);
- QMultiHash<IdentityTracker, int>::const_iterator pos = hash.constFind(searchKey);
- QCOMPARE(pos.value(), pos.key().id); // key fits to value it was inserted with
- ++pos;
- QCOMPARE(pos.value(), pos.key().id); // key fits to value it was inserted with
- }
}
void tst_QHash::erase()
@@ -490,13 +542,75 @@ void tst_QHash::erase()
++n;
}
QVERIFY(n == 3);
- QHash<int, int> h2;
- h2.insertMulti(20, 41);
- h2.insertMulti(20, 42);
+
+ QMultiHash<int, int> h2;
+ h2.insert(20, 41);
+ h2.insert(20, 42);
QVERIFY(h2.size() == 2);
- it1 = h2.erase(h2.begin());
- it1 = h2.erase(h2.begin());
- QVERIFY(it1 == h2.end());
+ auto bit = h2.begin();
+ auto mit = h2.erase(bit);
+ mit = h2.erase(h2.begin());
+ QVERIFY(mit == h2.end());
+
+ h2 = QMultiHash<int, int>();
+ h2.emplace(1, 1);
+ h2.emplace(1, 2);
+ h2.emplace(3, 1);
+ h2.emplace(3, 4);
+ QMultiHash<int, int> h3 = h2;
+ auto it = h3.constFind(3);
+ ++it;
+ QVERIFY(h3.isSharedWith(h2));
+ it = h3.erase(it);
+ QVERIFY(!h3.isSharedWith(h2));
+ if (it != h3.cend()) {
+ auto it2 = h3.constFind(it.key());
+ QCOMPARE(it, it2);
+ }
+}
+
+/*
+ With a specific seed we could end up in a situation where, upon deleting the
+ last entry in a QHash, the returned iterator would not point to the end()
+ iterator.
+*/
+void tst_QHash::erase_edge_case()
+{
+ QHashSeed::setDeterministicGlobalSeed();
+ auto resetSeed = qScopeGuard([&]() {
+ QHashSeed::resetRandomGlobalSeed();
+ });
+
+ QHash<int, int> h1;
+ h1.reserve(2);
+ qsizetype capacity = h1.capacity();
+ // Beholden to QHash internals:
+ qsizetype numBuckets = capacity << 1;
+
+ // Find some keys which will both be slotted into the last bucket:
+ int keys[2];
+ int index = 0;
+ for (qsizetype i = 0; i < numBuckets * 4 && index < 2; ++i) {
+ const size_t hash = qHash(i, QHashSeed::globalSeed());
+ const size_t bucketForHash = QHashPrivate::GrowthPolicy::bucketForHash(numBuckets, hash);
+ if (qsizetype(bucketForHash) == numBuckets - 1)
+ keys[index++] = i;
+ }
+ QCOMPARE(index, 2); // Sanity check. If this fails then the test needs an update!
+
+ // As mentioned earlier these are both calculated to be in the last bucket:
+ h1.insert(keys[0], 4);
+ h1.insert(keys[1], 6);
+ // As a sanity-check, make sure that the key we inserted last is the first one (because its
+ // allocation to the last bucket would make it wrap around):
+ // NOTE: If this fails this then this test may need an update!!!
+ QCOMPARE(h1.constBegin().key(), keys[1]);
+ // Then we delete the last entry:
+ QHash<int, int>::iterator it1 = h1.begin();
+ ++it1;
+ it1 = h1.erase(it1);
+ // Now, since we deleted the last entry, the iterator should be at the end():
+ QVERIFY(it1 == h1.end());
}
void tst_QHash::key()
@@ -507,6 +621,7 @@ void tst_QHash::key()
QHash<QString, int> hash1;
QCOMPARE(hash1.key(1), QString());
QCOMPARE(hash1.key(1, def), def);
+ QVERIFY(!hash1.isDetached());
hash1.insert("one", 1);
QCOMPARE(hash1.key(1), QLatin1String("one"));
@@ -537,6 +652,7 @@ void tst_QHash::key()
QHash<int, QString> hash2;
QCOMPARE(hash2.key("one"), 0);
QCOMPARE(hash2.key("one", def), def);
+ QVERIFY(!hash2.isDetached());
hash2.insert(1, "one");
QCOMPARE(hash2.key("one"), 1);
@@ -568,6 +684,62 @@ void tst_QHash::key()
QCOMPARE(hash2.key("zero"), 0);
QCOMPARE(hash2.key("zero", def), 0);
}
+
+ {
+ const int def = -1;
+ QMultiHash<int, QString> hash;
+ QCOMPARE(hash.key("val"), 0);
+ QCOMPARE(hash.key("val", def), def);
+ QVERIFY(!hash.isDetached());
+
+ hash.insert(1, "value1");
+ hash.insert(1, "value2");
+ hash.insert(2, "value1");
+
+ QCOMPARE(hash.key("value2"), 1);
+ const auto key = hash.key("value1");
+ QVERIFY(key == 1 || key == 2);
+ QCOMPARE(hash.key("value"), 0);
+ QCOMPARE(hash.key("value", def), def);
+ }
+}
+
+template <typename T>
+QList<T> sorted(const QList<T> &list)
+{
+ QList<T> res = list;
+ std::sort(res.begin(), res.end());
+ return res;
+}
+
+void tst_QHash::keys()
+{
+ {
+ QHash<QString, int> hash;
+ QVERIFY(hash.keys().isEmpty());
+ QVERIFY(hash.keys(1).isEmpty());
+ QVERIFY(!hash.isDetached());
+
+ hash.insert("key1", 1);
+ hash.insert("key2", 2);
+ hash.insert("key3", 1);
+
+ QCOMPARE(sorted(hash.keys()), QStringList({ "key1", "key2", "key3" }));
+ QCOMPARE(sorted(hash.keys(1)), QStringList({ "key1", "key3" }));
+ }
+ {
+ QMultiHash<QString, int> hash;
+ QVERIFY(hash.keys().isEmpty());
+ QVERIFY(hash.keys(1).isEmpty());
+ QVERIFY(!hash.isDetached());
+
+ hash.insert("key1", 1);
+ hash.insert("key2", 1);
+ hash.insert("key1", 2);
+
+ QCOMPARE(sorted(hash.keys()), QStringList({ "key1", "key1", "key2" }));
+ QCOMPARE(sorted(hash.keys(1)), QStringList({ "key1", "key2" }));
+ }
}
void tst_QHash::swap()
@@ -597,6 +769,25 @@ void tst_QHash::clear()
QVERIFY( map.isEmpty() );
}
QCOMPARE( MyClass::count, int(0) );
+
+ {
+ QMultiHash<QString, MyClass> multiHash;
+ multiHash.clear();
+ QVERIFY(multiHash.isEmpty());
+
+ multiHash.insert("key", MyClass("value0"));
+ QVERIFY(!multiHash.isEmpty());
+ multiHash.clear();
+ QVERIFY(multiHash.isEmpty());
+
+ multiHash.insert("key0", MyClass("value0"));
+ multiHash.insert("key0", MyClass("value1"));
+ multiHash.insert("key1", MyClass("value2"));
+ QVERIFY(!multiHash.isEmpty());
+ multiHash.clear();
+ QVERIFY(multiHash.isEmpty());
+ }
+ QCOMPARE(MyClass::count, int(0));
}
//copied from tst_QMap
void tst_QHash::empty()
@@ -604,24 +795,31 @@ void tst_QHash::empty()
QHash<int, QString> map1;
QVERIFY(map1.isEmpty());
+ QVERIFY(map1.empty());
map1.insert(1, "one");
QVERIFY(!map1.isEmpty());
+ QVERIFY(!map1.empty());
map1.clear();
QVERIFY(map1.isEmpty());
-
+ QVERIFY(map1.empty());
}
//copied from tst_QMap
void tst_QHash::find()
{
+ const QHash<int, QString> constEmptyHash;
+ QVERIFY(constEmptyHash.find(1) == constEmptyHash.end());
+ QVERIFY(!constEmptyHash.isDetached());
+
QHash<int, QString> map1;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
QVERIFY(map1.find(1) == map1.end());
+ QVERIFY(!map1.isDetached());
map1.insert(1,"Mensch");
map1.insert(1,"Mayer");
@@ -630,14 +828,25 @@ void tst_QHash::find()
QCOMPARE(map1.find(1).value(), QLatin1String("Mayer"));
QCOMPARE(map1.find(2).value(), QLatin1String("Hej"));
- for(i = 3; i < 10; ++i) {
+ const QMultiHash<int, QString> constEmptyMultiHash;
+ QVERIFY(constEmptyMultiHash.find(1) == constEmptyMultiHash.cend());
+ QVERIFY(constEmptyMultiHash.find(1, "value") == constEmptyMultiHash.cend());
+ QVERIFY(!constEmptyMultiHash.isDetached());
+
+ QMultiHash<int, QString> emptyMultiHash;
+ QVERIFY(emptyMultiHash.find(1) == emptyMultiHash.end());
+ QVERIFY(emptyMultiHash.find(1, "value") == emptyMultiHash.end());
+ QVERIFY(!emptyMultiHash.isDetached());
+
+ QMultiHash<int, QString> multiMap(map1);
+ for (i = 3; i < 10; ++i) {
compareString = testString.arg(i);
- map1.insertMulti(4, compareString);
+ multiMap.insert(4, compareString);
}
- QHash<int, QString>::const_iterator it=map1.constFind(4);
+ auto it = multiMap.constFind(4);
- for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ for (i = 9; i > 2 && it != multiMap.constEnd() && it.key() == 4; --i) {
compareString = testString.arg(i);
QVERIFY(it.value() == compareString);
++it;
@@ -655,6 +864,7 @@ void tst_QHash::constFind()
int i,count=0;
QVERIFY(map1.constFind(1) == map1.constEnd());
+ QVERIFY(!map1.isDetached());
map1.insert(1,"Mensch");
map1.insert(1,"Mayer");
@@ -663,14 +873,19 @@ void tst_QHash::constFind()
QCOMPARE(map1.constFind(1).value(), QLatin1String("Mayer"));
QCOMPARE(map1.constFind(2).value(), QLatin1String("Hej"));
- for(i = 3; i < 10; ++i) {
+ QMultiHash<int, QString> emptyMultiHash;
+ QVERIFY(emptyMultiHash.constFind(1) == emptyMultiHash.constEnd());
+ QVERIFY(!emptyMultiHash.isDetached());
+
+ QMultiHash<int, QString> multiMap(map1);
+ for (i = 3; i < 10; ++i) {
compareString = testString.arg(i);
- map1.insertMulti(4, compareString);
+ multiMap.insert(4, compareString);
}
- QHash<int, QString>::const_iterator it=map1.constFind(4);
+ auto it = multiMap.constFind(4);
- for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ for (i = 9; i > 2 && it != multiMap.constEnd() && it.key() == 4; --i) {
compareString = testString.arg(i);
QVERIFY(it.value() == compareString);
++it;
@@ -685,12 +900,15 @@ void tst_QHash::contains()
QHash<int, QString> map1;
int i;
+ QVERIFY(!map1.contains(1));
+ QVERIFY(!map1.isDetached());
+
map1.insert(1, "one");
QVERIFY(map1.contains(1));
- for(i=2; i < 100; ++i)
+ for (i=2; i < 100; ++i)
map1.insert(i, "teststring");
- for(i=99; i > 1; --i)
+ for (i=99; i > 1; --i)
QVERIFY(map1.contains(i));
map1.remove(43);
@@ -703,16 +921,31 @@ class QGlobalQHashSeedResetter
int oldSeed;
public:
// not entirely correct (may lost changes made by another thread between the query
- // of the old and the setting of the new seed), but qSetGlobalQHashSeed doesn't
+ // of the old and the setting of the new seed), but setHashSeed() can't
// return the old value, so this is the best we can do:
explicit QGlobalQHashSeedResetter(int newSeed)
- : oldSeed(qGlobalQHashSeed())
+ : oldSeed(getHashSeed())
{
- qSetGlobalQHashSeed(newSeed);
+ setHashSeed(newSeed);
}
~QGlobalQHashSeedResetter()
{
- qSetGlobalQHashSeed(oldSeed);
+ setHashSeed(oldSeed);
+ }
+
+private:
+ // The functions are implemented to replace the deprecated
+ // qGlobalQHashSeed() and qSetGlobalQHashSeed()
+ static int getHashSeed()
+ {
+ return int(QHashSeed::globalSeed() & INT_MAX);
+ }
+ static void setHashSeed(int seed)
+ {
+ if (seed == 0)
+ QHashSeed::setDeterministicGlobalSeed();
+ else
+ QHashSeed::resetRandomGlobalSeed();
}
};
@@ -763,13 +996,33 @@ void tst_QHash::qhash()
//copied from tst_QMap
void tst_QHash::take()
{
- QHash<int, QString> map;
+ {
+ QHash<int, QString> map;
+ QCOMPARE(map.take(1), QString());
+ QVERIFY(!map.isDetached());
- map.insert(2, "zwei");
- map.insert(3, "drei");
+ map.insert(2, "zwei");
+ map.insert(3, "drei");
- QCOMPARE(map.take(3), QLatin1String("drei"));
- QVERIFY(!map.contains(3));
+ QCOMPARE(map.take(3), QLatin1String("drei"));
+ QVERIFY(!map.contains(3));
+ }
+ {
+ QMultiHash<int, QString> hash;
+ QCOMPARE(hash.take(1), QString());
+ QVERIFY(!hash.isDetached());
+
+ hash.insert(1, "value1");
+ hash.insert(2, "value2");
+ hash.insert(1, "value3");
+
+ // The docs tell that if there are multiple values for a key, then the
+ // most recent is returned.
+ QCOMPARE(hash.take(1), "value3");
+ QCOMPARE(hash.take(1), "value1");
+ QCOMPARE(hash.take(1), QString());
+ QCOMPARE(hash.take(2), "value2");
+ }
}
// slightly modified from tst_QMap
@@ -854,33 +1107,33 @@ void tst_QHash::operator_eq()
// regardless of insertion or iteration order
{
- QHash<int, int> a;
- QHash<int, int> b;
+ QMultiHash<int, int> a;
+ QMultiHash<int, int> b;
- a.insertMulti(0, 0);
- a.insertMulti(0, 1);
+ a.insert(0, 0);
+ a.insert(0, 1);
- b.insertMulti(0, 1);
- b.insertMulti(0, 0);
+ b.insert(0, 1);
+ b.insert(0, 0);
QVERIFY(a == b);
QVERIFY(!(a != b));
}
{
- QHash<int, int> a;
- QHash<int, int> b;
+ QMultiHash<int, int> a;
+ QMultiHash<int, int> b;
enum { Count = 100 };
for (int key = 0; key < Count; ++key) {
for (int value = 0; value < Count; ++value)
- a.insertMulti(key, value);
+ a.insert(key, value);
}
for (int key = Count - 1; key >= 0; --key) {
for (int value = 0; value < Count; ++value)
- b.insertMulti(key, value);
+ b.insert(key, value);
}
QVERIFY(a == b);
@@ -888,8 +1141,8 @@ void tst_QHash::operator_eq()
}
{
- QHash<int, int> a;
- QHash<int, int> b;
+ QMultiHash<int, int> a;
+ QMultiHash<int, int> b;
enum {
Count = 100,
@@ -899,7 +1152,7 @@ void tst_QHash::operator_eq()
for (int key = 0; key < Count; ++key) {
for (int value = 0; value < Count; ++value)
- a.insertMulti(key, value);
+ a.insert(key, value);
}
// Generates two permutations of [0, Count) for the keys and values,
@@ -908,7 +1161,7 @@ void tst_QHash::operator_eq()
for (int k = 0; k < Count; ++k) {
const int key = (k * KeyStep) % Count;
for (int v = 0; v < Count; ++v)
- b.insertMulti(key, (v * ValueStep) % Count);
+ b.insert(key, (v * ValueStep) % Count);
}
QVERIFY(a == b);
@@ -916,16 +1169,232 @@ void tst_QHash::operator_eq()
}
}
+#ifdef __cpp_concepts
+struct HeterogeneousHashingType
+{
+ inline static int conversionCount = 0;
+ QString s;
+
+ Q_IMPLICIT operator QString() const
+ {
+ ++conversionCount;
+ return s;
+ }
+
+ // std::equality_comparable_with requires we be self-comparable too
+ friend bool operator==(const HeterogeneousHashingType &t1, const HeterogeneousHashingType &t2) = default;
+
+ friend bool operator==(const QString &string, const HeterogeneousHashingType &tester)
+ { return tester.s == string; }
+ friend bool operator!=(const QString &string, const HeterogeneousHashingType &tester)
+ { return !(tester.s == string); }
+
+ friend size_t qHash(const HeterogeneousHashingType &tester, size_t seed)
+ { return qHash(tester.s, seed); }
+};
+QT_BEGIN_NAMESPACE
+template <> struct QHashHeterogeneousSearch<QString, HeterogeneousHashingType> : std::true_type {};
+template <> struct QHashHeterogeneousSearch<HeterogeneousHashingType, QString> : std::true_type {};
+QT_END_NAMESPACE
+static_assert(std::is_same_v<QString, std::common_type_t<QString, HeterogeneousHashingType>>);
+static_assert(std::equality_comparable_with<QString, HeterogeneousHashingType>);
+static_assert(QHashPrivate::HeterogeneouslySearchableWith<QString, HeterogeneousHashingType>);
+static_assert(QHashPrivate::HeterogeneouslySearchableWith<HeterogeneousHashingType, QString>);
+
+template <typename T> struct HeterogeneousSearchTestHelper
+{
+ static void resetCounter() {}
+ static void checkCounter() {}
+};
+template <> struct HeterogeneousSearchTestHelper<HeterogeneousHashingType>
+{
+ static void resetCounter()
+ {
+ HeterogeneousHashingType::conversionCount = 0;
+ }
+ static void checkCounter()
+ {
+ QTest::setThrowOnFail(true);
+ auto scopeExit = qScopeGuard([] { QTest::setThrowOnFail(false); });
+ QCOMPARE(HeterogeneousHashingType::conversionCount, 0);
+ }
+};
+#else
+using HeterogeneousHashingType = QString;
+#endif
+
+template <template <typename, typename> class Hash, typename String, typename View, typename Converter>
+static void heterogeneousSearchTest(const QList<std::remove_const_t<String>> &keys, Converter conv)
+{
+#ifdef __cpp_concepts
+ using Helper = HeterogeneousSearchTestHelper<View>;
+ String key = keys.last();
+ String otherKey = keys.first();
+ auto keyHolder = conv(key);
+ auto otherKeyHolder = conv(otherKey);
+ View keyView(keyHolder);
+ View otherKeyView(otherKeyHolder);
+
+ Hash<String, qsizetype> hash;
+ static constexpr bool IsMultiHash = !std::is_same_v<decltype(hash.remove(String())), bool>;
+ hash[key] = keys.size();
+
+ Helper::resetCounter();
+ QVERIFY(hash.contains(keyView));
+ QCOMPARE_EQ(hash.count(keyView), 1);
+ QCOMPARE_EQ(hash.value(keyView), keys.size());
+ QCOMPARE_EQ(hash.value(keyView, -1), keys.size());
+ QCOMPARE_EQ(std::as_const(hash)[keyView], keys.size());
+ QCOMPARE_EQ(hash.find(keyView), hash.begin());
+ QCOMPARE_EQ(std::as_const(hash).find(keyView), hash.constBegin());
+ QCOMPARE_EQ(hash.constFind(keyView), hash.constBegin());
+ QCOMPARE_EQ(hash.equal_range(keyView), std::make_pair(hash.begin(), hash.end()));
+ QCOMPARE_EQ(std::as_const(hash).equal_range(keyView),
+ std::make_pair(hash.constBegin(), hash.constEnd()));
+ Helper::checkCounter();
+
+ QVERIFY(!hash.contains(otherKeyView));
+ QCOMPARE_EQ(hash.count(otherKeyView), 0);
+ QCOMPARE_EQ(hash.value(otherKeyView), 0);
+ QCOMPARE_EQ(hash.value(otherKeyView, -1), -1);
+ QCOMPARE_EQ(std::as_const(hash)[otherKeyView], 0);
+ QCOMPARE_EQ(hash.find(otherKeyView), hash.end());
+ QCOMPARE_EQ(std::as_const(hash).find(otherKeyView), hash.constEnd());
+ QCOMPARE_EQ(hash.constFind(otherKeyView), hash.constEnd());
+ QCOMPARE_EQ(hash.equal_range(otherKeyView), std::make_pair(hash.end(), hash.end()));
+ QCOMPARE_EQ(std::as_const(hash).equal_range(otherKeyView),
+ std::make_pair(hash.constEnd(), hash.constEnd()));
+ Helper::checkCounter();
+
+ // non-const versions
+ QCOMPARE_EQ(hash[keyView], keys.size()); // already there
+ Helper::checkCounter();
+
+ QCOMPARE_EQ(hash[otherKeyView], 0); // inserts
+ Helper::resetCounter();
+ hash[otherKeyView] = INT_MAX;
+ Helper::checkCounter();
+
+ if constexpr (IsMultiHash) {
+ hash.insert(key, keys.size());
+ QCOMPARE_EQ(hash.count(keyView), 2);
+
+ // not depending on which of the two the current implementation finds
+ QCOMPARE_NE(hash.value(keyView), 0);
+ QCOMPARE_NE(hash.value(keyView, -1000), -1000);
+ QCOMPARE_NE(std::as_const(hash)[keyView], 0);
+ QCOMPARE_NE(hash.find(keyView), hash.end());
+ QCOMPARE_NE(std::as_const(hash).find(keyView), hash.constEnd());
+ QCOMPARE_NE(hash.constFind(keyView), hash.constEnd());
+ QCOMPARE_NE(hash.equal_range(keyView), std::make_pair(hash.end(), hash.end()));
+ QCOMPARE_NE(std::as_const(hash).equal_range(keyView),
+ std::make_pair(hash.constEnd(), hash.constEnd()));
+
+ // QMultiHash-specific functions
+ QVERIFY(hash.contains(keyView, keys.size()));
+ QCOMPARE_EQ(hash.count(keyView, 0), 0);
+ QCOMPARE_EQ(hash.count(keyView, keys.size()), 2);
+ QCOMPARE_EQ(hash.values(keyView), QList<qsizetype>({ keys.size(), keys.size() }));
+
+ hash.insert(key, -keys.size());
+ QCOMPARE_EQ(hash.count(keyView), 3);
+ QCOMPARE_EQ(hash.find(keyView, 0), hash.end());
+ QCOMPARE_NE(hash.find(keyView, keys.size()), hash.end());
+ QCOMPARE_NE(hash.find(keyView, -keys.size()), hash.end());
+ QCOMPARE_EQ(std::as_const(hash).find(keyView, 0), hash.constEnd());
+ QCOMPARE_NE(std::as_const(hash).find(keyView, keys.size()), hash.constEnd());
+ QCOMPARE_NE(std::as_const(hash).find(keyView, -keys.size()), hash.constEnd());
+ QCOMPARE_EQ(hash.constFind(keyView, 0), hash.constEnd());
+ QCOMPARE_NE(hash.constFind(keyView, keys.size()), hash.constEnd());
+ QCOMPARE_NE(hash.constFind(keyView, -keys.size()), hash.constEnd());
+
+ // removals
+ QCOMPARE_EQ(hash.remove(keyView, -keys.size()), 1);
+ QCOMPARE_EQ(hash.remove(keyView), 2);
+ } else {
+ // removals
+ QCOMPARE_EQ(hash.remove(keyView), true);
+ }
+
+ QCOMPARE_EQ(hash.take(otherKeyView), INT_MAX);
+ QVERIFY(hash.isEmpty());
+ Helper::checkCounter();
+
+ // repeat with more keys
+ for (qsizetype i = 0; i < keys.size() - 1; ++i) {
+ hash.insert(keys[i], -(i + 1));
+ hash.insert(keys[i], i + 1);
+ }
+
+ QVERIFY(!hash.contains(keyView));
+ QCOMPARE_EQ(hash.count(keyView), 0);
+ QCOMPARE_EQ(hash.value(keyView), 0);
+ QCOMPARE_EQ(hash.value(keyView, -1), -1);
+ QCOMPARE_EQ(std::as_const(hash)[keyView], 0);
+ QCOMPARE_EQ(hash.find(keyView), hash.end());
+ QCOMPARE_EQ(hash.constFind(keyView), hash.constEnd());
+ Helper::checkCounter();
+#else
+ Q_UNUSED(keys);
+ Q_UNUSED(conv);
+ QSKIP("This feature requires C++20 (concepts)");
+#endif
+}
+
+template <template <typename, typename> class Hash, typename String, typename View>
+static void heterogeneousSearchTest(const QList<std::remove_const_t<String>> &keys)
+{
+ heterogeneousSearchTest<Hash, String, View>(keys, [](const String &s) { return View(s); });
+}
+
+template <template <typename, typename> class Hash, typename T>
+static void heterogeneousSearchLatin1String(T)
+{
+ if constexpr (!T::value) {
+ QSKIP("QLatin1StringView and QString do not have the same hash on this platform");
+ } else {
+ // similar to the above
+ auto toLatin1 = [](const QString &s) { return s.toLatin1(); };
+ heterogeneousSearchTest<Hash, QString, QLatin1StringView>({ "Hello", {}, "World" }, toLatin1);
+ }
+}
+
+void tst_QHash::heterogeneousSearch()
+{
+ heterogeneousSearchTest<QHash, QString, HeterogeneousHashingType>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::heterogeneousSearchConstKey()
+{
+ // QHash<const QString, X> seen in the wild (e.g. Qt Creator)
+ heterogeneousSearchTest<QHash, const QString, HeterogeneousHashingType>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::heterogeneousSearchByteArray()
+{
+ heterogeneousSearchTest<QHash, QByteArray, QByteArrayView>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::heterogeneousSearchString()
+{
+ heterogeneousSearchTest<QHash, QString, QStringView>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::heterogeneousSearchLatin1String()
+{
+ ::heterogeneousSearchLatin1String<QHash>(QHashHeterogeneousSearch<QString, QLatin1StringView>{});
+}
+
void tst_QHash::compare()
{
QHash<int, QString> hash1,hash2;
QString testString = "Teststring %1";
int i;
- for(i = 0; i < 1000; ++i)
+ for (i = 0; i < 1000; ++i)
hash1.insert(i,testString.arg(i));
- for(--i; i >= 0; --i)
+ for (--i; i >= 0; --i)
hash2.insert(i,testString.arg(i));
hash1.squeeze();
@@ -946,39 +1415,39 @@ void tst_QHash::compare()
void tst_QHash::compare2()
{
- QHash<int, int> a;
- QHash<int, int> b;
+ QMultiHash<int, int> a;
+ QMultiHash<int, int> b;
- a.insertMulti(17, 1);
- a.insertMulti(17 * 2, 1);
- b.insertMulti(17 * 2, 1);
- b.insertMulti(17, 1);
+ a.insert(17, 1);
+ a.insert(17 * 2, 1);
+ b.insert(17 * 2, 1);
+ b.insert(17, 1);
QVERIFY(a == b);
QVERIFY(b == a);
- a.insertMulti(17, 2);
- a.insertMulti(17 * 2, 3);
- b.insertMulti(17 * 2, 3);
- b.insertMulti(17, 2);
+ a.insert(17, 2);
+ a.insert(17 * 2, 3);
+ b.insert(17 * 2, 3);
+ b.insert(17, 2);
QVERIFY(a == b);
QVERIFY(b == a);
- a.insertMulti(17, 4);
- a.insertMulti(17 * 2, 5);
- b.insertMulti(17 * 2, 4);
- b.insertMulti(17, 5);
+ a.insert(17, 4);
+ a.insert(17 * 2, 5);
+ b.insert(17 * 2, 4);
+ b.insert(17, 5);
QVERIFY(!(a == b));
QVERIFY(!(b == a));
a.clear();
b.clear();
- a.insertMulti(1, 1);
- a.insertMulti(1, 2);
- a.insertMulti(1, 3);
- b.insertMulti(1, 1);
- b.insertMulti(1, 2);
- b.insertMulti(1, 3);
- b.insertMulti(1, 4);
+ a.insert(1, 1);
+ a.insert(1, 2);
+ a.insert(1, 3);
+ b.insert(1, 1);
+ b.insert(1, 2);
+ b.insert(1, 3);
+ b.insert(1, 4);
QVERIFY(!(a == b));
QVERIFY(!(b == a));
}
@@ -992,7 +1461,7 @@ void tst_QHash::iterators()
QString testString1;
int i;
- for(i = 1; i < 100; ++i)
+ for (i = 1; i < 100; ++i)
hash.insert(i, testString.arg(i));
//to get some chaos in the hash
@@ -1009,18 +1478,13 @@ void tst_QHash::iterators()
QVERIFY(stlIt.value() == testMap.value(1));
- stlIt+=5;
+ for (int i = 0; i < 5; ++i)
+ ++stlIt;
QVERIFY(stlIt.value() == testMap.value(6));
stlIt++;
QVERIFY(stlIt.value() == testMap.value(7));
- stlIt-=3;
- QVERIFY(stlIt.value() == testMap.value(4));
-
- stlIt--;
- QVERIFY(stlIt.value() == testMap.value(3));
-
testMap.clear();
//STL-Style const-iterators
@@ -1034,18 +1498,13 @@ void tst_QHash::iterators()
QVERIFY(cstlIt.value() == testMap.value(1));
- cstlIt+=5;
+ for (int i = 0; i < 5; ++i)
+ ++cstlIt;
QVERIFY(cstlIt.value() == testMap.value(6));
cstlIt++;
QVERIFY(cstlIt.value() == testMap.value(7));
- cstlIt-=3;
- QVERIFY(cstlIt.value() == testMap.value(4));
-
- cstlIt--;
- QVERIFY(cstlIt.value() == testMap.value(3));
-
testMap.clear();
//Java-Style iterators
@@ -1067,14 +1526,7 @@ void tst_QHash::iterators()
QVERIFY(javaIt.value() == testMap.value(i));
}
- ++i;
- while(javaIt.hasPrevious()) {
- --i;
- javaIt.previous();
- QVERIFY(javaIt.value() == testMap.value(i));
- }
-
- //peekNext() peekPrevious()
+ //peekNext()
javaIt.toFront();
javaIt.next();
while(javaIt.hasNext()) {
@@ -1082,25 +1534,147 @@ void tst_QHash::iterators()
testString1 = javaIt.peekNext().value();
javaIt.next();
QVERIFY(javaIt.value() == testString1);
- QCOMPARE(javaIt.peekPrevious().value(), testString1);
}
- while(javaIt.hasPrevious()) {
- testString = javaIt.value();
- testString1 = javaIt.peekPrevious().value();
- javaIt.previous();
- QVERIFY(javaIt.value() == testString1);
- QCOMPARE(javaIt.peekNext().value(), testString1);
+}
+
+void tst_QHash::multihashIterators()
+{
+ QMultiHash<int, QString> hash;
+ QMap<int, QString> referenceMap;
+ QString testString = "Teststring %1-%2";
+ int i = 0;
+
+ // Add 5 elements for each key
+ for (i = 0; i < 10; ++i) {
+ for (int j = 0; j < 5; ++j)
+ hash.insert(i, testString.arg(i, j));
}
+
+ hash.squeeze();
+
+ // Verify that iteration is reproducible.
+
+ // STL iterator
+ QMultiHash<int, QString>::iterator stlIt;
+
+ for (stlIt = hash.begin(), i = 1; stlIt != hash.end(); ++stlIt, ++i)
+ referenceMap.insert(i, *stlIt);
+
+ stlIt = hash.begin();
+ QCOMPARE(*stlIt, referenceMap[1]);
+
+ for (i = 0; i < 5; ++i)
+ stlIt++;
+ QCOMPARE(*stlIt, referenceMap[6]);
+
+ for (i = 0; i < 44; ++i)
+ stlIt++;
+ QCOMPARE(*stlIt, referenceMap[50]);
+
+ // const STL iterator
+ referenceMap.clear();
+ QMultiHash<int, QString>::const_iterator cstlIt;
+
+ for (cstlIt = hash.cbegin(), i = 1; cstlIt != hash.cend(); ++cstlIt, ++i)
+ referenceMap.insert(i, *cstlIt);
+
+ cstlIt = hash.cbegin();
+ QCOMPARE(*cstlIt, referenceMap[1]);
+
+ for (i = 0; i < 5; ++i)
+ cstlIt++;
+ QCOMPARE(*cstlIt, referenceMap[6]);
+
+ for (i = 0; i < 44; ++i)
+ cstlIt++;
+ QCOMPARE(*cstlIt, referenceMap[50]);
+
+ // Java-Style iterator
+ referenceMap.clear();
+ QMultiHashIterator<int, QString> javaIt(hash);
+
+ // walk through
+ i = 0;
+ while (javaIt.hasNext()) {
+ ++i;
+ javaIt.next();
+ referenceMap.insert(i, javaIt.value());
+ }
+ javaIt.toFront();
+ i = 0;
+ while (javaIt.hasNext()) {
+ ++i;
+ javaIt.next();
+ QCOMPARE(javaIt.value(), referenceMap.value(i));
+ }
+
+ // peekNext()
+ javaIt.toFront();
+ javaIt.next();
+ QString nextValue;
+ while (javaIt.hasNext()) {
+ nextValue = javaIt.peekNext().value();
+ javaIt.next();
+ QCOMPARE(javaIt.value(), nextValue);
+ }
+}
+
+template<typename T>
+void iteratorsInEmptyHashTestMethod()
+{
+ T hash;
+ using ConstIter = typename T::const_iterator;
+ ConstIter it1 = hash.cbegin();
+ ConstIter it2 = hash.constBegin();
+ QVERIFY(it1 == it2 && it2 == ConstIter());
+ QVERIFY(!hash.isDetached());
+
+ ConstIter it3 = hash.cend();
+ ConstIter it4 = hash.constEnd();
+ QVERIFY(it3 == it4 && it4 == ConstIter());
+ QVERIFY(!hash.isDetached());
+
+ // to call const overloads of begin() and end()
+ const T hash2;
+ ConstIter it5 = hash2.begin();
+ ConstIter it6 = hash2.end();
+ QVERIFY(it5 == it6 && it6 == ConstIter());
+ QVERIFY(!hash2.isDetached());
+
+ T hash3;
+ using Iter = typename T::iterator;
+ Iter it7 = hash3.end();
+ QVERIFY(it7 == Iter());
+ QVERIFY(!hash3.isDetached());
+
+ Iter it8 = hash3.begin(); // calls detach()
+ QVERIFY(it8 == Iter());
+ QVERIFY(hash3.isDetached());
+}
+
+void tst_QHash::iteratorsInEmptyHash()
+{
+ iteratorsInEmptyHashTestMethod<QHash<int, QString>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ iteratorsInEmptyHashTestMethod<QMultiHash<int, QString>>();
}
void tst_QHash::keyIterator()
{
QHash<int, int> hash;
+ using KeyIterator = QHash<int, int>::key_iterator;
+ KeyIterator it1 = hash.keyBegin();
+ KeyIterator it2 = hash.keyEnd();
+ QVERIFY(it1 == it2 && it2 == KeyIterator());
+ QVERIFY(!hash.isDetached());
+
for (int i = 0; i < 100; ++i)
hash.insert(i, i*100);
- QHash<int, int>::key_iterator key_it = hash.keyBegin();
+ KeyIterator key_it = hash.keyBegin();
QHash<int, int>::const_iterator it = hash.cbegin();
for (int i = 0; i < 100; ++i) {
QCOMPARE(*key_it, it.key());
@@ -1114,15 +1688,55 @@ void tst_QHash::keyIterator()
QVERIFY(key_it != hash.keyEnd());
QCOMPARE(*key_it, it.key());
QCOMPARE(*(key_it++), (it++).key());
- QCOMPARE(*(key_it--), (it--).key());
- QCOMPARE(*(++key_it), (++it).key());
- QCOMPARE(*(--key_it), (--it).key());
+ if (key_it != hash.keyEnd()) {
+ QVERIFY(it != hash.cend());
+ ++key_it;
+ ++it;
+ if (key_it != hash.keyEnd())
+ QCOMPARE(*key_it, it.key());
+ else
+ QVERIFY(it == hash.cend());
+ }
QCOMPARE(std::count(hash.keyBegin(), hash.keyEnd(), 99), 1);
// DefaultConstructible test
- typedef QHash<int, int>::key_iterator keyIterator;
- Q_STATIC_ASSERT(std::is_default_constructible<keyIterator>::value);
+ static_assert(std::is_default_constructible<KeyIterator>::value);
+}
+
+void tst_QHash::multihashKeyIterator()
+{
+ QMultiHash<int, int> hash;
+
+ using KeyIterator = QMultiHash<int, int>::key_iterator;
+ KeyIterator it1 = hash.keyBegin();
+ KeyIterator it2 = hash.keyEnd();
+ QVERIFY(it1 == it2 && it2 == KeyIterator());
+ QVERIFY(!hash.isDetached());
+
+ for (int i = 0; i < 10; ++i) {
+ for (int j = 0; j < 5; ++j)
+ hash.insert(i, i * 100 + j);
+ }
+
+ KeyIterator keyIt = hash.keyBegin();
+ QMultiHash<int, int>::const_iterator it = hash.cbegin();
+ while (keyIt != hash.keyEnd() && it != hash.cend()) {
+ QCOMPARE(*keyIt, it.key());
+ keyIt++;
+ it++;
+ }
+
+ keyIt = std::find(hash.keyBegin(), hash.keyEnd(), 5);
+ it = std::find(hash.cbegin(), hash.cend(), 5 * 100 + 2);
+
+ QVERIFY(keyIt != hash.keyEnd());
+ QCOMPARE(*keyIt, it.key());
+
+ QCOMPARE(std::count(hash.keyBegin(), hash.keyEnd(), 9), 5);
+
+ // DefaultConstructible test
+ static_assert(std::is_default_constructible<KeyIterator>::value);
}
void tst_QHash::keyValueIterator()
@@ -1143,6 +1757,12 @@ void tst_QHash::keyValueIterator()
entry_type pair(it.key(), it.value());
QCOMPARE(*key_value_it, pair);
+ QCOMPARE(key_value_it->first, pair.first);
+ QCOMPARE(key_value_it->second, pair.second);
+ QCOMPARE(&(*key_value_it).first, &it.key());
+ QCOMPARE(&key_value_it->first, &it.key());
+ QCOMPARE(&(*key_value_it).second, &it.value());
+ QCOMPARE(&key_value_it->second, &it.value());
++key_value_it;
++it;
}
@@ -1161,31 +1781,105 @@ void tst_QHash::keyValueIterator()
++it;
++key_value_it;
- QCOMPARE(*key_value_it, entry_type(it.key(), it.value()));
-
- --it;
- --key_value_it;
- QCOMPARE(*key_value_it, entry_type(it.key(), it.value()));
-
- ++it;
- ++key_value_it;
- QCOMPARE(*key_value_it, entry_type(it.key(), it.value()));
+ if (it != hash.cend())
+ QCOMPARE(*key_value_it, entry_type(it.key(), it.value()));
+ else
+ QVERIFY(key_value_it == hash.constKeyValueEnd());
- --it;
- --key_value_it;
- QCOMPARE(*key_value_it, entry_type(it.key(), it.value()));
key = 99;
value = 99 * 100;
QCOMPARE(std::count(hash.constKeyValueBegin(), hash.constKeyValueEnd(), entry_type(key, value)), 1);
}
+void tst_QHash::multihashKeyValueIterator()
+{
+ QMultiHash<int, int> hash;
+ using EntryType = QHash<int, int>::const_key_value_iterator::value_type;
+
+ for (int i = 0; i < 10; ++i) {
+ for (int j = 0; j < 5; j++)
+ hash.insert(i, i * 100 + j);
+ }
+
+ auto keyValueIt = hash.constKeyValueBegin();
+ auto it = hash.cbegin();
+
+ for (int i = 0; i < hash.size(); ++i) {
+ QVERIFY(keyValueIt != hash.constKeyValueEnd());
+ QVERIFY(it != hash.cend());
+
+ EntryType pair(it.key(), it.value());
+ QCOMPARE(*keyValueIt, pair);
+ QCOMPARE(keyValueIt->first, pair.first);
+ QCOMPARE(keyValueIt->second, pair.second);
+ ++keyValueIt;
+ ++it;
+ }
+
+ QVERIFY(keyValueIt == hash.constKeyValueEnd());
+ QVERIFY(it == hash.cend());
+
+ int key = 5;
+ int value = key * 100 + 3;
+ EntryType pair(key, value);
+ keyValueIt = std::find(hash.constKeyValueBegin(), hash.constKeyValueEnd(), pair);
+ it = std::find(hash.cbegin(), hash.cend(), value);
+
+ QVERIFY(keyValueIt != hash.constKeyValueEnd());
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ key = 9;
+ value = key * 100 + 4;
+ const auto numItems =
+ std::count(hash.constKeyValueBegin(), hash.constKeyValueEnd(), EntryType(key, value));
+ QCOMPARE(numItems, 1);
+}
+
+template<typename T>
+void keyValueIteratorInEmptyHashTestMethod()
+{
+ T hash;
+ using ConstKeyValueIter = typename T::const_key_value_iterator;
+
+ ConstKeyValueIter it1 = hash.constKeyValueBegin();
+ ConstKeyValueIter it2 = hash.constKeyValueEnd();
+ QVERIFY(it1 == it2 && it2 == ConstKeyValueIter());
+ QVERIFY(!hash.isDetached());
+
+ const T hash2;
+ ConstKeyValueIter it3 = hash2.keyValueBegin();
+ ConstKeyValueIter it4 = hash2.keyValueEnd();
+ QVERIFY(it3 == it4 && it4 == ConstKeyValueIter());
+ QVERIFY(!hash.isDetached());
+
+ T hash3;
+ using KeyValueIter = typename T::key_value_iterator;
+
+ KeyValueIter it5 = hash3.keyValueEnd();
+ QVERIFY(it5 == KeyValueIter());
+ QVERIFY(!hash3.isDetached());
+
+ KeyValueIter it6 = hash3.keyValueBegin(); // calls detach()
+ QVERIFY(it6 == KeyValueIter());
+ QVERIFY(hash3.isDetached());
+}
+
+void tst_QHash::keyValueIteratorInEmptyHash()
+{
+ keyValueIteratorInEmptyHashTestMethod<QHash<int, int>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ keyValueIteratorInEmptyHashTestMethod<QMultiHash<int, int>>();
+}
+
void tst_QHash::rehash_isnt_quadratic()
{
// this test should be incredibly slow if rehash() is quadratic
for (int j = 0; j < 5; ++j) {
QHash<int, int> testHash;
for (int i = 0; i < 500000; ++i)
- testHash.insertMulti(1, 1);
+ testHash.insert(i, 1);
}
}
@@ -1217,16 +1911,24 @@ void tst_QHash::dont_need_default_constructor()
void tst_QHash::qmultihash_specific()
{
QMultiHash<int, int> hash1;
+
+ QVERIFY(!hash1.contains(1));
+ QVERIFY(!hash1.contains(1, 2));
+ QVERIFY(!hash1.isDetached());
+
for (int i = 1; i <= 9; ++i) {
+ QVERIFY(!hash1.contains(i));
for (int j = 1; j <= i; ++j) {
int k = i * 10 + j;
QVERIFY(!hash1.contains(i, k));
hash1.insert(i, k);
QVERIFY(hash1.contains(i, k));
}
+ QVERIFY(hash1.contains(i));
}
for (int i = 1; i <= 9; ++i) {
+ QVERIFY(hash1.contains(i));
for (int j = 1; j <= i; ++j) {
int k = i * 10 + j;
QVERIFY(hash1.contains(i, k));
@@ -1234,26 +1936,26 @@ void tst_QHash::qmultihash_specific()
}
QVERIFY(hash1.contains(9, 99));
- QCOMPARE(hash1.count(), 45);
+ QCOMPARE(hash1.size(), 45);
hash1.remove(9, 99);
QVERIFY(!hash1.contains(9, 99));
- QCOMPARE(hash1.count(), 44);
+ QCOMPARE(hash1.size(), 44);
hash1.remove(9, 99);
QVERIFY(!hash1.contains(9, 99));
- QCOMPARE(hash1.count(), 44);
+ QCOMPARE(hash1.size(), 44);
hash1.remove(1, 99);
- QCOMPARE(hash1.count(), 44);
+ QCOMPARE(hash1.size(), 44);
hash1.insert(1, 99);
hash1.insert(1, 99);
- QCOMPARE(hash1.count(), 46);
+ QCOMPARE(hash1.size(), 46);
hash1.remove(1, 99);
- QCOMPARE(hash1.count(), 44);
+ QCOMPARE(hash1.size(), 44);
hash1.remove(1, 99);
- QCOMPARE(hash1.count(), 44);
+ QCOMPARE(hash1.size(), 44);
{
QMultiHash<int, int>::const_iterator i = hash1.constFind(1, 11);
@@ -1298,6 +2000,12 @@ void tst_QHash::qmultihash_specific()
QVERIFY(i.value() == 98);
}
+ QCOMPARE(hash1.count(9), 8);
+ QCOMPARE(hash1.size(), 44);
+ hash1.remove(9);
+ QCOMPARE(hash1.count(9), 0);
+ QCOMPARE(hash1.size(), 36);
+
{
QMultiHash<int, int> map1;
map1.insert(42, 1);
@@ -1312,73 +2020,397 @@ void tst_QHash::qmultihash_specific()
map2.insert(42, 1);
map2.insert(10, 2);
map2.insert(48, 3);
- QCOMPARE(map1.count(), map2.count());
+ QCOMPARE(map1.size(), map2.size());
QVERIFY(map1.remove(42,5));
+ QVERIFY(map1 != map2);
QVERIFY(map2.remove(42,5));
QVERIFY(map1 == map2);
+
+ QHash<int, int> hash;
+ hash.insert(-1, -1);
+ map2.unite(hash);
+ QCOMPARE(map2.size(), 6);
+ QCOMPARE(map2[-1], -1);
}
}
-template <typename T>
-QList<T> sorted(const QList<T> &list)
+void tst_QHash::qmultihash_qhash_rvalue_ref_ctor()
{
- QList<T> res = list;
- std::sort(res.begin(), res.end());
- return res;
+ // QHash is empty
+ {
+ QHash<int, MyClass> hash;
+ QMultiHash<int, MyClass> multiHash(std::move(hash));
+ QVERIFY(multiHash.isEmpty());
+ }
+
+ // QHash is detached
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QHash<int, MyClass> hash;
+ hash.emplace(0, "a");
+ hash.emplace(1, "b");
+ QMultiHash<int, MyClass> multiHash(std::move(hash));
+ QCOMPARE(multiHash.size(), 2);
+ QCOMPARE(multiHash[0].str, QString("a"));
+ QCOMPARE(multiHash[1].str, QString("b"));
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 2);
+ QCOMPARE(MyClass::count, 2);
+ }
+
+ // QHash is shared
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QHash<int, MyClass> hash;
+ hash.emplace(0, "a");
+ hash.emplace(1, "b");
+ QHash<int, MyClass> hash2(hash);
+ QMultiHash<int, MyClass> multiHash(std::move(hash));
+ QCOMPARE(multiHash.size(), 2);
+ QCOMPARE(multiHash[0].str, QString("a"));
+ QCOMPARE(multiHash[1].str, QString("b"));
+ QCOMPARE(MyClass::copies, 2);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 4);
+ }
+}
+
+void tst_QHash::qmultihash_qhash_rvalue_ref_unite()
+{
+ // QHash is empty
+ {
+ QHash<int, MyClass> hash;
+ QMultiHash<int, MyClass> multiHash;
+ multiHash.unite(std::move(hash));
+ QVERIFY(multiHash.isEmpty());
+ }
+
+ // QHash is detached
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QHash<int, MyClass> hash;
+ hash.emplace(0, "a");
+ hash.emplace(1, "b");
+ QMultiHash<int, MyClass> multiHash;
+ multiHash.unite(std::move(hash));
+ QCOMPARE(multiHash.size(), 2);
+ QCOMPARE(multiHash[0].str, QString("a"));
+ QCOMPARE(multiHash[1].str, QString("b"));
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 2);
+ QCOMPARE(MyClass::count, 2);
+ }
+
+ // QHash is shared
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QHash<int, MyClass> hash;
+ hash.emplace(0, "a");
+ hash.emplace(1, "b");
+ QHash<int, MyClass> hash2(hash);
+ QMultiHash<int, MyClass> multiHash;
+ multiHash.unite(std::move(hash));
+ QCOMPARE(multiHash.size(), 2);
+ QCOMPARE(multiHash[0].str, QString("a"));
+ QCOMPARE(multiHash[1].str, QString("b"));
+ QCOMPARE(MyClass::copies, 2);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 4);
+ }
+
+ // QMultiHash already contains an item with the same key
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QHash<int, MyClass> hash;
+ hash.emplace(0, "a");
+ hash.emplace(1, "b");
+ QMultiHash<int, MyClass> multiHash;
+ multiHash.emplace(0, "c");
+ multiHash.unite(std::move(hash));
+ QCOMPARE(multiHash.size(), 3);
+ const auto aRange = multiHash.equal_range(0);
+ QCOMPARE(std::distance(aRange.first, aRange.second), 2);
+ auto it = aRange.first;
+ QCOMPARE(it->str, QString("a"));
+ QCOMPARE((++it)->str, QString("c"));
+ QCOMPARE(multiHash[1].str, QString("b"));
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 2);
+ QCOMPARE(MyClass::count, 3);
+ }
+}
+
+void tst_QHash::qmultihashUnite()
+{
+ // Joining two multi hashes, first is empty
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QMultiHash<int, MyClass> hash1;
+ QMultiHash<int, MyClass> hash2;
+ hash2.emplace(0, "a");
+ hash2.emplace(1, "b");
+
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+
+ hash1.unite(hash2);
+ // hash1 is empty, so we just share the data between hash1 and hash2
+ QCOMPARE(hash1.size(), 2);
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+ }
+ // Joining two multi hashes, second is empty
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QMultiHash<int, MyClass> hash1;
+ QMultiHash<int, MyClass> hash2;
+ hash1.emplace(0, "a");
+ hash1.emplace(1, "b");
+
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+
+ hash1.unite(hash2);
+ // hash2 is empty, so nothing happens
+ QVERIFY(hash2.isEmpty());
+ QVERIFY(!hash2.isDetached());
+ QCOMPARE(hash1.size(), 2);
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+ }
+ // Joining two multi hashes
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QMultiHash<int, MyClass> hash1;
+ QMultiHash<int, MyClass> hash2;
+ hash1.emplace(0, "a");
+ hash1.emplace(1, "b");
+ hash2.emplace(0, "c");
+ hash2.emplace(1, "d");
+
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 4);
+
+ hash1.unite(hash2);
+ QCOMPARE(hash1.size(), 4);
+ QCOMPARE(MyClass::copies, 2);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 6);
+ }
+
+ // operator+() uses unite() internally.
+
+ // using operator+(), hash1 is empty
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QMultiHash<int, MyClass> hash1;
+ QMultiHash<int, MyClass> hash2;
+ hash2.emplace(0, "a");
+ hash2.emplace(1, "b");
+
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+
+ auto hash3 = hash1 + hash2;
+ // hash1 is empty, so we just share the data between hash3 and hash2
+ QCOMPARE(hash1.size(), 0);
+ QCOMPARE(hash2.size(), 2);
+ QCOMPARE(hash3.size(), 2);
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+ }
+ // using operator+(), hash2 is empty
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QMultiHash<int, MyClass> hash1;
+ QMultiHash<int, MyClass> hash2;
+ hash1.emplace(0, "a");
+ hash1.emplace(1, "b");
+
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+
+ auto hash3 = hash1 + hash2;
+ // hash2 is empty, so we just share the data between hash3 and hash1
+ QCOMPARE(hash1.size(), 2);
+ QCOMPARE(hash2.size(), 0);
+ QCOMPARE(hash3.size(), 2);
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 2);
+ }
+ // using operator+()
+ {
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+ QMultiHash<int, MyClass> hash1;
+ QMultiHash<int, MyClass> hash2;
+ hash1.emplace(0, "a");
+ hash1.emplace(1, "b");
+ hash2.emplace(0, "c");
+ hash2.emplace(1, "d");
+
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 4);
+
+ auto hash3 = hash1 + hash2;
+ QCOMPARE(hash1.size(), 2);
+ QCOMPARE(hash2.size(), 2);
+ QCOMPARE(hash3.size(), 4);
+ QCOMPARE(MyClass::copies, 4);
+ QCOMPARE(MyClass::moves, 0);
+ QCOMPARE(MyClass::count, 8);
+ }
+}
+
+void tst_QHash::qmultihashSize()
+{
+ // QMultiHash has an extra m_size member that counts the number of values,
+ // while d->size (shared with QHash) counts the number of distinct keys.
+ {
+ QMultiHash<int, int> hash;
+ QCOMPARE(hash.size(), 0);
+ QVERIFY(hash.isEmpty());
+
+ hash.insert(0, 42);
+ QCOMPARE(hash.size(), 1);
+ QVERIFY(!hash.isEmpty());
+
+ hash.insert(0, 42);
+ QCOMPARE(hash.size(), 2);
+ QVERIFY(!hash.isEmpty());
+
+ hash.emplace(0, 42);
+ QCOMPARE(hash.size(), 3);
+ QVERIFY(!hash.isEmpty());
+
+ QCOMPARE(hash.take(0), 42);
+ QCOMPARE(hash.size(), 2);
+ QVERIFY(!hash.isEmpty());
+
+ QCOMPARE(hash.remove(0), 2);
+ QCOMPARE(hash.size(), 0);
+ QVERIFY(hash.isEmpty());
+ }
+
+ {
+ QMultiHash<int, int> hash;
+ hash.emplace(0, 0);
+ hash.emplace(0, 0);
+ QCOMPARE(hash.size(), 2);
+ QVERIFY(!hash.isEmpty());
+
+ hash.emplace(0, 1);
+ QCOMPARE(hash.size(), 3);
+ QVERIFY(!hash.isEmpty());
+
+ QCOMPARE(hash.remove(0, 0), 2);
+ QCOMPARE(hash.size(), 1);
+ QVERIFY(!hash.isEmpty());
+
+ hash.remove(0);
+ QCOMPARE(hash.size(), 0);
+ QVERIFY(hash.isEmpty());
+ }
+
+ {
+ QMultiHash<int, int> hash;
+
+ hash[0] = 0;
+ QCOMPARE(hash.size(), 1);
+ QVERIFY(!hash.isEmpty());
+
+ hash.replace(0, 1);
+ QCOMPARE(hash.size(), 1);
+ QVERIFY(!hash.isEmpty());
+
+ hash.insert(0, 1);
+ hash.erase(hash.cbegin());
+ QCOMPARE(hash.size(), 1);
+ QVERIFY(!hash.isEmpty());
+
+ hash.erase(hash.cbegin());
+ QCOMPARE(hash.size(), 0);
+ QVERIFY(hash.isEmpty());
+ }
+}
+
+void tst_QHash::qmultihashHeterogeneousSearch()
+{
+ heterogeneousSearchTest<QMultiHash, QString, HeterogeneousHashingType>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::qmultihashHeterogeneousSearchConstKey()
+{
+ heterogeneousSearchTest<QMultiHash, const QString, HeterogeneousHashingType>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::qmultihashHeterogeneousSearchByteArray()
+{
+ heterogeneousSearchTest<QMultiHash, QByteArray, QByteArrayView>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::qmultihashHeterogeneousSearchString()
+{
+ heterogeneousSearchTest<QMultiHash, QString, QStringView>({ "Hello", {}, "World" });
+}
+
+void tst_QHash::qmultihashHeterogeneousSearchLatin1String()
+{
+ ::heterogeneousSearchLatin1String<QMultiHash>(QHashHeterogeneousSearch<QString, QLatin1StringView>{});
}
void tst_QHash::keys_values_uniqueKeys()
{
- QHash<QString, int> hash;
+ QMultiHash<QString, int> hash;
QVERIFY(hash.uniqueKeys().isEmpty());
QVERIFY(hash.keys().isEmpty());
QVERIFY(hash.values().isEmpty());
+ QVERIFY(!hash.isDetached());
- hash.insertMulti("alpha", 1);
+ hash.insert("alpha", 1);
QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha"));
QVERIFY(hash.keys() == hash.uniqueKeys());
QVERIFY(hash.values() == (QList<int>() << 1));
- hash.insertMulti("beta", -2);
+ hash.insert("beta", -2);
QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha" << "beta"));
QVERIFY(hash.keys() == hash.uniqueKeys());
QVERIFY(sorted(hash.values()) == sorted(QList<int>() << 1 << -2));
- hash.insertMulti("alpha", 2);
+ hash.insert("alpha", 2);
QVERIFY(sorted(hash.uniqueKeys()) == (QList<QString>() << "alpha" << "beta"));
QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha" << "alpha" << "beta"));
QVERIFY(sorted(hash.values()) == sorted(QList<int>() << 2 << 1 << -2));
- hash.insertMulti("beta", 4);
+ hash.insert("beta", 4);
QVERIFY(sorted(hash.uniqueKeys()) == (QList<QString>() << "alpha" << "beta"));
QVERIFY(sorted(hash.keys()) == (QList<QString>() << "alpha" << "alpha" << "beta" << "beta"));
QVERIFY(sorted(hash.values()) == sorted(QList<int>() << 2 << 1 << 4 << -2));
}
-void tst_QHash::noNeedlessRehashes()
-{
- QHash<int, int> hash;
- for (int i = 0; i < 512; ++i) {
- int j = (i * 345) % 512;
- hash.insert(j, j);
- int oldCapacity = hash.capacity();
- hash[j] = j + 1;
- QCOMPARE(oldCapacity, hash.capacity());
- hash.insert(j, j + 1);
- QCOMPARE(oldCapacity, hash.capacity());
- }
-}
-
void tst_QHash::const_shared_null()
{
QHash<int, QString> hash2;
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QHash<int, QString> hash1;
- hash1.setSharable(false);
- QVERIFY(hash1.isDetached());
-
- hash2.setSharable(true);
-#endif
QVERIFY(!hash2.isDetached());
}
@@ -1387,52 +2419,52 @@ static int wrongqHashOverload = 0;
struct OneArgumentQHashStruct1 {};
bool operator==(const OneArgumentQHashStruct1 &, const OneArgumentQHashStruct1 &) { return false; }
-uint qHash(OneArgumentQHashStruct1) { return 0; }
+size_t qHash(OneArgumentQHashStruct1) { return 0; }
struct OneArgumentQHashStruct2 {};
bool operator==(const OneArgumentQHashStruct2 &, const OneArgumentQHashStruct2 &) { return false; }
-uint qHash(const OneArgumentQHashStruct2 &) { return 0; }
+size_t qHash(const OneArgumentQHashStruct2 &) { return 0; }
struct OneArgumentQHashStruct3 {};
bool operator==(const OneArgumentQHashStruct3 &, const OneArgumentQHashStruct3 &) { return false; }
-uint qHash(OneArgumentQHashStruct3) { return 0; }
-uint qHash(OneArgumentQHashStruct3 &, uint) { wrongqHashOverload = 1; return 0; }
+size_t qHash(OneArgumentQHashStruct3) { return 0; }
+size_t qHash(OneArgumentQHashStruct3 &, size_t) { wrongqHashOverload = 1; return 0; }
struct OneArgumentQHashStruct4 {};
bool operator==(const OneArgumentQHashStruct4 &, const OneArgumentQHashStruct4 &) { return false; }
-uint qHash(const OneArgumentQHashStruct4 &) { return 0; }
-uint qHash(OneArgumentQHashStruct4 &, uint) { wrongqHashOverload = 1; return 0; }
+size_t qHash(const OneArgumentQHashStruct4 &) { return 0; }
+size_t qHash(OneArgumentQHashStruct4 &, size_t) { wrongqHashOverload = 1; return 0; }
struct TwoArgumentsQHashStruct1 {};
bool operator==(const TwoArgumentsQHashStruct1 &, const TwoArgumentsQHashStruct1 &) { return false; }
-uint qHash(const TwoArgumentsQHashStruct1 &) { wrongqHashOverload = 1; return 0; }
-uint qHash(const TwoArgumentsQHashStruct1 &, uint) { return 0; }
+size_t qHash(const TwoArgumentsQHashStruct1 &) { wrongqHashOverload = 1; return 0; }
+size_t qHash(const TwoArgumentsQHashStruct1 &, size_t) { return 0; }
struct TwoArgumentsQHashStruct2 {};
bool operator==(const TwoArgumentsQHashStruct2 &, const TwoArgumentsQHashStruct2 &) { return false; }
-uint qHash(TwoArgumentsQHashStruct2) { wrongqHashOverload = 1; return 0; }
-uint qHash(const TwoArgumentsQHashStruct2 &, uint) { return 0; }
+size_t qHash(TwoArgumentsQHashStruct2) { wrongqHashOverload = 1; return 0; }
+size_t qHash(const TwoArgumentsQHashStruct2 &, size_t) { return 0; }
struct TwoArgumentsQHashStruct3 {};
bool operator==(const TwoArgumentsQHashStruct3 &, const TwoArgumentsQHashStruct3 &) { return false; }
-uint qHash(const TwoArgumentsQHashStruct3 &) { wrongqHashOverload = 1; return 0; }
-uint qHash(TwoArgumentsQHashStruct3, uint) { return 0; }
+size_t qHash(const TwoArgumentsQHashStruct3 &) { wrongqHashOverload = 1; return 0; }
+size_t qHash(TwoArgumentsQHashStruct3, size_t) { return 0; }
struct TwoArgumentsQHashStruct4 {};
bool operator==(const TwoArgumentsQHashStruct4 &, const TwoArgumentsQHashStruct4 &) { return false; }
-uint qHash(TwoArgumentsQHashStruct4) { wrongqHashOverload = 1; return 0; }
-uint qHash(TwoArgumentsQHashStruct4, uint) { return 0; }
+size_t qHash(TwoArgumentsQHashStruct4) { wrongqHashOverload = 1; return 0; }
+size_t qHash(TwoArgumentsQHashStruct4, size_t) { return 0; }
/*!
\internal
Check that QHash picks up the right overload.
The best one, for a type T, is the two-args version of qHash:
- either uint qHash(T, uint) or uint qHash(const T &, uint).
+ either size_t qHash(T, size_t) or size_t qHash(const T &, size_t).
If neither of these exists, then one between
- uint qHash(T) or uint qHash(const T &) must exist
+ size_t qHash(T) or size_t qHash(const T &) must exist
(and it gets selected instead).
*/
void tst_QHash::twoArguments_qHash()
@@ -1480,9 +2512,8 @@ void tst_QHash::twoArguments_qHash()
void tst_QHash::initializerList()
{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
QHash<int, QString> hash = {{1, "bar"}, {1, "hello"}, {2, "initializer_list"}};
- QCOMPARE(hash.count(), 2);
+ QCOMPARE(hash.size(), 2);
QCOMPARE(hash[1], QString("hello"));
QCOMPARE(hash[2], QString("initializer_list"));
@@ -1492,9 +2523,9 @@ void tst_QHash::initializerList()
// QCOMPARE(stdh[1], QString("bar"));
QMultiHash<QString, int> multiHash{{"il", 1}, {"il", 2}, {"il", 3}};
- QCOMPARE(multiHash.count(), 3);
+ QCOMPARE(multiHash.size(), 3);
QList<int> values = multiHash.values("il");
- QCOMPARE(values.count(), 3);
+ QCOMPARE(values.size(), 3);
QHash<int, int> emptyHash{};
QVERIFY(emptyHash.isEmpty());
@@ -1507,21 +2538,18 @@ void tst_QHash::initializerList()
QMultiHash<int, float> emptyPairs2{{}, {}};
QVERIFY(!emptyPairs2.isEmpty());
-#else
- QSKIP("Compiler doesn't support initializer lists");
-#endif
}
void tst_QHash::eraseValidIteratorOnSharedHash()
{
- QHash<int, int> a, b;
+ QMultiHash<int, int> a, b;
a.insert(10, 10);
- a.insertMulti(10, 25);
- a.insertMulti(10, 30);
+ a.insert(10, 25);
+ a.insert(10, 30);
a.insert(20, 20);
a.insert(40, 40);
- QHash<int, int>::iterator i = a.begin();
+ auto i = a.begin();
while (i.value() != 25)
++i;
@@ -1543,7 +2571,7 @@ void tst_QHash::eraseValidIteratorOnSharedHash()
void tst_QHash::equal_range()
{
- QHash<int, QString> hash;
+ QMultiHash<int, QString> hash;
auto result = hash.equal_range(0);
QCOMPARE(result.first, hash.end());
@@ -1556,7 +2584,7 @@ void tst_QHash::equal_range()
QCOMPARE(result.first, hash.find(1));
QVERIFY(std::distance(result.first, result.second) == 1);
- QHash<int, int> h1;
+ QMultiHash<int, int> h1;
{
auto p = h1.equal_range(0);
QVERIFY(p.first == p.second);
@@ -1607,7 +2635,7 @@ void tst_QHash::equal_range()
QVERIFY(p2.first == m1.begin() || p2.second == m1.end());
}
- const QHash<int, int> ch1 = h1;
+ const QMultiHash<int, int> ch1 = h1;
{
auto p1 = ch1.equal_range(9);
QVERIFY(p1.first == p1.second);
@@ -1633,10 +2661,17 @@ void tst_QHash::equal_range()
QVERIFY(p2.first == cm1.cbegin() || p2.second == cm1.cend());
}
- QHash<int, int> h2;
+ {
+ const QMultiHash<int, int> cm2;
+ auto p1 = cm2.equal_range(0);
+ QVERIFY(p1.first == cm2.end());
+ QVERIFY(p1.second == cm2.end());
+ }
+
+ QMultiHash<int, int> h2;
for (int i = 0; i < 8; ++i)
for (int j = 0; j < 8; ++j)
- h2.insertMulti(i, i*j);
+ h2.insert(i, i*j);
for (int i = 0; i < 8; ++i) {
auto pair = h2.equal_range(i);
@@ -1647,5 +2682,560 @@ void tst_QHash::equal_range()
}
}
+void tst_QHash::insert_hash()
+{
+ {
+ QHash<int, int> hash;
+ hash.insert(1, 1);
+ hash.insert(2, 2);
+ hash.insert(0, -1);
+
+ QHash<int, int> hash2;
+ hash2.insert(0, 0);
+ hash2.insert(3, 3);
+ hash2.insert(4, 4);
+
+ hash.insert(hash2);
+
+ QCOMPARE(hash.size(), 5);
+ for (int i = 0; i < 5; ++i)
+ QCOMPARE(hash[i], i);
+ }
+ {
+ QHash<int, int> hash;
+ hash.insert(0, 5);
+
+ QHash<int, int> hash2;
+
+ hash.insert(hash2);
+
+ QCOMPARE(hash.size(), 1);
+ QCOMPARE(hash[0], 5);
+ }
+ {
+ QHash<int, int> hash;
+ QHash<int, int> hash2;
+ hash2.insert(0, 5);
+
+ hash.insert(hash2);
+
+ QCOMPARE(hash.size(), 1);
+ QCOMPARE(hash[0], 5);
+ QCOMPARE(hash, hash2);
+ }
+ {
+ QHash<int, int> hash;
+ hash.insert(0, 7);
+ hash.insert(2, 5);
+ hash.insert(7, 55);
+
+ // insert into ourself, nothing should happen
+ hash.insert(hash);
+
+ QCOMPARE(hash.size(), 3);
+ QCOMPARE(hash[0], 7);
+ QCOMPARE(hash[2], 5);
+ QCOMPARE(hash[7], 55);
+ }
+}
+
+void tst_QHash::multiHashStoresInReverseInsertionOrder()
+{
+ const QString strings[] = {
+ u"zero"_s,
+ u"null"_s,
+ u"nada"_s,
+ };
+ {
+ QMultiHash<int, QString> hash;
+ for (const QString &string : strings)
+ hash.insert(0, string);
+ auto printOnFailure = qScopeGuard([&] { qDebug() << hash; });
+ QVERIFY(std::equal(hash.begin(), hash.end(),
+ std::rbegin(strings), std::rend(strings)));
+ printOnFailure.dismiss();
+ }
+}
+
+void tst_QHash::emplace()
+{
+ {
+ QHash<QString, MyClass> hash;
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+
+ hash.emplace(QString("a"), QString("a"));
+ QCOMPARE(hash["a"].str, "a");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ hash.emplace(QString("ab"), QString("ab"));
+ QCOMPARE(hash["ab"].str, "ab");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ hash.emplace(QString("ab"), QString("abc"));
+ QCOMPARE(hash["ab"].str, "abc");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 1);
+ }
+ {
+ QMultiHash<QString, MyClass> hash;
+ MyClass::copies = 0;
+ MyClass::moves = 0;
+
+ hash.emplace(QString("a"), QString("a"));
+ QCOMPARE(hash["a"].str, "a");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ hash.emplace(QString("ab"), QString("ab"));
+ QCOMPARE(hash["ab"].str, "ab");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ hash.emplace(QString("ab"), QString("abc"));
+ QCOMPARE(hash["ab"].str, "abc");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 0);
+ hash.emplaceReplace(QString("ab"), QString("abcd"));
+ QCOMPARE(hash["ab"].str, "abcd");
+ QCOMPARE(MyClass::copies, 0);
+ QCOMPARE(MyClass::moves, 1);
+ }
+}
+
+struct BadKey {
+ int k;
+ BadKey(int i) : k(i) {}
+ bool operator==(const BadKey &other) const
+ {
+ return k == other.k;
+ }
+};
+
+size_t qHash(BadKey, size_t seed)
+{
+ return seed;
+}
+
+void tst_QHash::badHashFunction()
+{
+ QHash<BadKey, int> hash;
+ for (int i = 0; i < 10000; ++i)
+ hash.insert(i, i);
+
+ for (int i = 0; i < 10000; ++i)
+ QCOMPARE(hash.value(i), i);
+
+ for (int i = 10000; i < 20000; ++i)
+ QVERIFY(!hash.contains(i));
+
+}
+
+void tst_QHash::hashOfHash()
+{
+ QHash<int, int> hash;
+ (void)qHash(hash);
+
+ QMultiHash<int, int> multiHash;
+ (void)qHash(multiHash);
+}
+
+template <bool HasQHash_>
+struct StdHashKeyType {
+ static inline constexpr bool HasQHash = HasQHash_;
+ static bool StdHashUsed;
+
+ int i;
+ friend bool operator==(const StdHashKeyType &lhs, const StdHashKeyType &rhs)
+ { return lhs.i == rhs.i; }
+};
+
+template <bool HasQHash>
+bool StdHashKeyType<HasQHash>::StdHashUsed = false;
+
+namespace std {
+template <bool HasQHash> struct hash<StdHashKeyType<HasQHash>>
+{
+ size_t operator()(const StdHashKeyType<HasQHash> &s, size_t seed = 0) const {
+ StdHashKeyType<HasQHash>::StdHashUsed = true;
+ return hash<int>()(s.i) ^ seed;
+ }
+};
+}
+
+template <bool HasQHash>
+std::enable_if_t<HasQHash, size_t>
+qHash(const StdHashKeyType<HasQHash> &s, size_t seed)
+{
+ return qHash(s.i, seed);
+}
+
+template <typename T>
+void stdHashImpl()
+{
+ QHash<T, int> hash;
+ for (int i = 0; i < 1000; ++i)
+ hash.insert(T{i}, i);
+
+ QCOMPARE(hash.size(), 1000);
+ for (int i = 0; i < 1000; ++i)
+ QCOMPARE(hash.value(T{i}, -1), i);
+
+ for (int i = 500; i < 1500; ++i)
+ hash.insert(T{i}, i);
+
+ QCOMPARE(hash.size(), 1500);
+ for (int i = 0; i < 1500; ++i)
+ QCOMPARE(hash.value(T{i}, -1), i);
+
+ qsizetype count = 0;
+ for (int i = -2000; i < 2000; ++i) {
+ if (hash.contains(T{i}))
+ ++count;
+ }
+ QCOMPARE(count, 1500);
+ QCOMPARE(T::StdHashUsed, !T::HasQHash);
+
+
+ std::unordered_set<T> set;
+ for (int i = 0; i < 1000; ++i)
+ set.insert(T{i});
+
+ for (int i = 500; i < 1500; ++i)
+ set.insert(T{i});
+
+ QCOMPARE(set.size(), size_t(1500));
+ count = 0;
+ for (int i = -2000; i < 2000; ++i)
+ count += qsizetype(set.count(T{i}));
+ QCOMPARE(count, 1500);
+ QVERIFY(T::StdHashUsed);
+}
+
+void tst_QHash::stdHash()
+{
+ stdHashImpl<StdHashKeyType<false>>();
+ stdHashImpl<StdHashKeyType<true>>();
+
+ QSet<std::string> strings{ "a", "b", "c" };
+ QVERIFY(strings.contains("a"));
+ QVERIFY(!strings.contains("z"));
+}
+
+void tst_QHash::countInEmptyHash()
+{
+ {
+ QHash<int, int> hash;
+ QCOMPARE(hash.size(), 0);
+ QCOMPARE(hash.count(42), 0);
+ }
+
+ {
+ QMultiHash<int, int> hash;
+ QCOMPARE(hash.size(), 0);
+ QCOMPARE(hash.count(42), 0);
+ QCOMPARE(hash.count(42, 1), 0);
+ }
+}
+
+void tst_QHash::removeInEmptyHash()
+{
+ {
+ QHash<QString, int> hash;
+ QCOMPARE(hash.remove("test"), false);
+ QVERIFY(!hash.isDetached());
+
+ using Iter = QHash<QString, int>::iterator;
+ const auto removed = hash.removeIf([](Iter) { return true; });
+ QCOMPARE(removed, 0);
+ }
+ {
+ QMultiHash<QString, int> hash;
+ QCOMPARE(hash.remove("key"), 0);
+ QCOMPARE(hash.remove("key", 1), 0);
+ QVERIFY(!hash.isDetached());
+
+ using Iter = QMultiHash<QString, int>::iterator;
+ const auto removed = hash.removeIf([](Iter) { return true; });
+ QCOMPARE(removed, 0);
+ }
+}
+
+template<typename T>
+void valueInEmptyHashTestFunction()
+{
+ T hash;
+ QCOMPARE(hash.value("key"), 0);
+ QCOMPARE(hash.value("key", -1), -1);
+ QVERIFY(hash.values().isEmpty());
+ QVERIFY(!hash.isDetached());
+
+ const T constHash;
+ QCOMPARE(constHash["key"], 0);
+}
+
+void tst_QHash::valueInEmptyHash()
+{
+ valueInEmptyHashTestFunction<QHash<QString, int>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ valueInEmptyHashTestFunction<QMultiHash<QString, int>>();
+}
+
+void tst_QHash::fineTuningInEmptyHash()
+{
+ QHash<QString, int> hash;
+ QCOMPARE(hash.capacity(), 0);
+ hash.squeeze();
+ QCOMPARE(hash.capacity(), 0);
+ QVERIFY(qFuzzyIsNull(hash.load_factor()));
+ QVERIFY(!hash.isDetached());
+
+ hash.reserve(10);
+ QVERIFY(hash.capacity() >= 10);
+ hash.squeeze();
+ QVERIFY(hash.capacity() > 0);
+}
+
+void tst_QHash::reserveShared()
+{
+ QHash<char, char> hash;
+ hash.insert('c', 'c');
+ auto hash2 = hash;
+
+ QCOMPARE(hash2.capacity(), hash.capacity());
+ auto oldCap = hash.capacity();
+
+ hash2.reserve(100); // This shouldn't crash
+
+ QVERIFY(hash2.capacity() >= 100);
+ QCOMPARE(hash.capacity(), oldCap);
+}
+
+void tst_QHash::reserveLessThanCurrentAmount()
+{
+ {
+ QHash<int, int> hash;
+ for (int i = 0; i < 1000; ++i)
+ hash.insert(i, i * 10);
+
+ // This used to hang in an infinite loop: QTBUG-102067
+ hash.reserve(1);
+
+ // Make sure that hash still has all elements
+ for (int i = 0; i < 1000; ++i)
+ QCOMPARE(hash.value(i), i * 10);
+ }
+ {
+ QMultiHash<int, int> hash;
+ for (int i = 0; i < 1000; ++i) {
+ hash.insert(i, i * 10);
+ hash.insert(i, i * 10 + 1);
+ }
+
+ // This used to hang in infinite loop: QTBUG-102067
+ hash.reserve(1);
+
+ // Make sure that hash still has all elements
+ for (int i = 0; i < 1000; ++i)
+ QCOMPARE(hash.values(i), QList<int>({ i * 10 + 1, i * 10 }));
+ }
+}
+
+void tst_QHash::reserveKeepCapacity_data()
+{
+ QTest::addColumn<qsizetype>("requested");
+ auto addRow = [](qsizetype requested) {
+ QTest::addRow("%td", ptrdiff_t(requested)) << requested;
+ };
+
+ QHash<int, int> testHash = {{1, 1}};
+ qsizetype minCapacity = testHash.capacity();
+ addRow(minCapacity - 1);
+ addRow(minCapacity + 0);
+ addRow(minCapacity + 1);
+ addRow(2 * minCapacity - 1);
+ addRow(2 * minCapacity + 0);
+ addRow(2 * minCapacity + 1);
+}
+
+void tst_QHash::reserveKeepCapacity()
+{
+ QFETCH(qsizetype, requested);
+
+ QHash<qsizetype, qsizetype> hash;
+ hash.reserve(requested);
+ qsizetype initialCapacity = hash.capacity();
+ QCOMPARE_GE(initialCapacity, requested);
+
+ // insert this many elements into the hash
+ for (qsizetype i = 0; i < requested; ++i)
+ hash.insert(i, i);
+
+ // it mustn't have increased capacity after inserting the elements
+ QCOMPARE(hash.capacity(), initialCapacity);
+}
+
+void tst_QHash::QTBUG98265()
+{
+ QMultiHash<QUuid, QByteArray> a;
+ QMultiHash<QUuid, QByteArray> b;
+ a.insert(QUuid("3e0dfb4d-90eb-43a4-bd54-88f5b69832c1"), QByteArray());
+ b.insert(QUuid("1b710ada-3dd7-432e-b7c8-e852e59f46a0"), QByteArray());
+
+ QVERIFY(a != b);
+}
+
+/*
+ Calling functions which take a const-ref argument for a key with a reference
+ to a key inside the hash itself should keep the key valid as long as it is
+ needed. If not users may get hard-to-debug races where CoW should've
+ shielded them.
+*/
+void tst_QHash::detachAndReferences()
+{
+ // Repeat a few times because it's not a guarantee
+ for (int i = 0; i < 50; ++i) {
+ QHash<char, char> hash;
+ hash.insert('a', 'a');
+ hash.insert('b', 'a');
+ hash.insert('c', 'a');
+ hash.insert('d', 'a');
+ hash.insert('e', 'a');
+ hash.insert('f', 'a');
+ hash.insert('g', 'a');
+
+ QSemaphore sem;
+ QSemaphore sem2;
+ std::thread th([&sem, &sem2, hash]() mutable {
+ sem.release();
+ sem2.acquire();
+ hash.reserve(100); // [2]: ...then this rehashes directly, without detaching
+ });
+
+ // The key is a reference to an entry in the hash. If we were already
+ // detached then no problem occurs! The problem happens because _after_
+ // we detach but before using the key the other thread resizes and
+ // rehashes, leaving our const-ref dangling.
+ auto it = hash.constBegin();
+ const auto &key = it.key(); // [3]: leaving our const-refs dangling
+ auto kCopy = key;
+ const auto &value = it.value();
+ auto vCopy = value;
+ sem2.release();
+ sem.acquire();
+ hash.insert(key, value); // [1]: this detaches first...
+
+ th.join();
+ QCOMPARE(hash.size(), 7);
+ QVERIFY(hash.contains(kCopy));
+ QCOMPARE(hash.value(kCopy), vCopy);
+ }
+}
+
+void tst_QHash::lookupUsingKeyIterator()
+{
+ QHash<QString, QString> hash;
+ hash.reserve(1);
+ qsizetype minCapacity = hash.capacity();
+ // Beholden to internal implementation details:
+ qsizetype rehashLimit = minCapacity == 64 ? 63 : 8;
+
+ for (char16_t c = u'a'; c <= u'a' + rehashLimit; ++c)
+ hash.insert(QString(QChar(c)), u"h"_s);
+
+ for (auto it = hash.keyBegin(), end = hash.keyEnd(); it != end; ++it)
+ QVERIFY(!hash[*it].isEmpty());
+}
+
+void tst_QHash::squeeze()
+{
+ {
+ QHash<int, int> hash;
+ hash.reserve(1000);
+ for (int i = 0; i < 10; ++i)
+ hash.insert(i, i * 10);
+ QVERIFY(hash.isDetached());
+ const size_t buckets = hash.bucket_count();
+ const qsizetype size = hash.size();
+
+ hash.squeeze();
+
+ QVERIFY(hash.bucket_count() < buckets);
+ QCOMPARE(hash.size(), size);
+ for (int i = 0; i < size; ++i)
+ QCOMPARE(hash.value(i), i * 10);
+ }
+ {
+ QMultiHash<int, int> hash;
+ hash.reserve(1000);
+ for (int i = 0; i < 10; ++i) {
+ hash.insert(i, i * 10);
+ hash.insert(i, i * 10 + 1);
+ }
+ QVERIFY(hash.isDetached());
+ const size_t buckets = hash.bucket_count();
+ const qsizetype size = hash.size();
+
+ hash.squeeze();
+
+ QVERIFY(hash.bucket_count() < buckets);
+ QCOMPARE(hash.size(), size);
+ for (int i = 0; i < (size / 2); ++i)
+ QCOMPARE(hash.values(i), QList<int>({ i * 10 + 1, i * 10 }));
+ }
+}
+
+void tst_QHash::squeezeShared()
+{
+ {
+ QHash<int, int> hash;
+ hash.reserve(1000);
+ for (int i = 0; i < 10; ++i)
+ hash.insert(i, i * 10);
+
+ QHash<int, int> other = hash;
+
+ // Check that when squeezing a hash with shared d_ptr, the number of
+ // buckets actually decreases.
+ QVERIFY(!other.isDetached());
+ const size_t buckets = other.bucket_count();
+ const qsizetype size = other.size();
+
+ other.squeeze();
+
+ QCOMPARE(hash.bucket_count(), buckets);
+ QVERIFY(other.bucket_count() < buckets);
+
+ QCOMPARE(other.size(), size);
+ for (int i = 0; i < size; ++i)
+ QCOMPARE(other.value(i), i * 10);
+ }
+ {
+ QMultiHash<int, int> hash;
+ hash.reserve(1000);
+ for (int i = 0; i < 10; ++i) {
+ hash.insert(i, i * 10);
+ hash.insert(i, i * 10 + 1);
+ }
+
+ QMultiHash<int, int> other = hash;
+
+ // Check that when squeezing a hash with shared d_ptr, the number of
+ // buckets actually decreases.
+ QVERIFY(!other.isDetached());
+ const size_t buckets = other.bucket_count();
+ const qsizetype size = other.size();
+
+ other.squeeze();
+
+ QCOMPARE(hash.bucket_count(), buckets);
+ QVERIFY(other.bucket_count() < buckets);
+
+ QCOMPARE(other.size(), size);
+ for (int i = 0; i < (size / 2); ++i)
+ QCOMPARE(other.values(i), QList<int>({ i * 10 + 1, i * 10 }));
+ }
+}
+
QTEST_APPLESS_MAIN(tst_QHash)
#include "tst_qhash.moc"
diff --git a/tests/auto/corelib/tools/qhash_strictiterators/qhash_strictiterators.pro b/tests/auto/corelib/tools/qhash_strictiterators/qhash_strictiterators.pro
deleted file mode 100644
index 715e9bf0c9..0000000000
--- a/tests/auto/corelib/tools/qhash_strictiterators/qhash_strictiterators.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-include(../qhash/qhash.pro)
-TARGET = tst_qhash_strictiterators
-DEFINES += QT_STRICT_ITERATORS tst_QHash=tst_QHash_StrictIterators
diff --git a/tests/auto/corelib/tools/qhashfunctions/CMakeLists.txt b/tests/auto/corelib/tools/qhashfunctions/CMakeLists.txt
new file mode 100644
index 0000000000..6cbba503dc
--- /dev/null
+++ b/tests/auto/corelib/tools/qhashfunctions/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qhashfunctions Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qhashfunctions LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qhashfunctions
+ SOURCES
+ tst_qhashfunctions.cpp
+)
diff --git a/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro b/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro
deleted file mode 100644
index 853e9f30e5..0000000000
--- a/tests/auto/corelib/tools/qhashfunctions/qhashfunctions.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qhashfunctions
-QT = core testlib
-SOURCES = $$PWD/tst_qhashfunctions.cpp
diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
index 124e3cdf00..00ee5763ed 100644
--- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
+++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
@@ -1,91 +1,339 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2024 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QVarLengthArray>
#include <qhash.h>
+#include <qfloat16.h>
#include <iterator>
#include <sstream>
#include <algorithm>
+#include <unordered_set>
+
class tst_QHashFunctions : public QObject
{
Q_OBJECT
public:
- enum {
- // random value
- RandomSeed = 1045982819
- };
- uint seed;
+ // random values
+ static constexpr quint64 ZeroSeed = 0;
+ static constexpr quint64 RandomSeed32 = 1045982819;
+ static constexpr quint64 RandomSeed64 = QtPrivate::QHashCombine{}(RandomSeed32, RandomSeed32);
+ size_t seed;
+
+ template <typename T1, typename T2> void stdPair_template(const T1 &t1, const T2 &t2);
public slots:
void initTestCase();
void init();
private Q_SLOTS:
- void consistent();
+ void unsignedIntegerConsistency_data();
+ void unsignedIntegerConsistency();
+ void signedIntegerConsistency_data();
+ void signedIntegerConsistency();
+ void extendedIntegerConsistency();
+ void floatingPointConsistency_data();
+ void floatingPointConsistency();
+ void stringConsistency_data();
+ void stringConsistency();
void qhash();
void qhash_of_empty_and_null_qstring();
void qhash_of_empty_and_null_qbytearray();
- void fp_qhash_of_zero_is_seed();
+ void qhash_of_zero_floating_points();
void qthash_data();
void qthash();
void range();
void rangeCommutative();
+ void stdHash();
+
+ void stdPair_int_int() { stdPair_template(1, 2); }
+ void stdPair_ulong_llong() { stdPair_template(1UL, -2LL); }
+ void stdPair_ullong_long() { stdPair_template(1ULL, -2L); }
+ void stdPair_string_int() { stdPair_template(QString("Hello"), 2); }
+ void stdPair_int_string() { stdPair_template(1, QString("Hello")); }
+ void stdPair_bytearray_string() { stdPair_template(QByteArray("Hello"), QString("World")); }
+ void stdPair_string_bytearray() { stdPair_template(QString("Hello"), QByteArray("World")); }
+ void stdPair_int_pairIntInt() { stdPair_template(1, std::make_pair(2, 3)); }
+ void stdPair_2x_pairIntInt() { stdPair_template(std::make_pair(1, 2), std::make_pair(2, 3)); }
+ void stdPair_string_pairIntInt() { stdPair_template(QString("Hello"), std::make_pair(42, -47)); } // QTBUG-92910
+ void stdPair_int_pairIntPairIntInt() { stdPair_template(1, std::make_pair(2, std::make_pair(3, 4))); }
+
+ void enum_int_consistent_hash_qtbug108032();
+
+#if QT_DEPRECATED_SINCE(6, 6)
void setGlobalQHashSeed();
+#endif
};
-void tst_QHashFunctions::consistent()
+void tst_QHashFunctions::initTestCase()
{
- // QString-like
- {
- const QString s = QStringLiteral("abcdefghijklmnopqrstuvxyz").repeated(16);
+ QTest::addColumn<quint64>("seedValue");
+
+ QTest::newRow("zero-seed") << ZeroSeed;
+ QTest::newRow("zero-seed-negated") << ~ZeroSeed;
+ QTest::newRow("non-zero-seed-32bit") << RandomSeed32;
+ QTest::newRow("non-zero-seed-32bit-negated")
+ << quint64{~quint32(RandomSeed32)}; // ensure this->seed gets same value on 32/64-bit
+ if constexpr (sizeof(size_t) == sizeof(quint64)) {
+ QTest::newRow("non-zero-seed-64bit") << RandomSeed64;
+ QTest::newRow("non-zero-seed-64bit-negated") << ~RandomSeed64;
+ }
+}
- QCOMPARE(qHash(s), qHash(QStringRef(&s)));
- QCOMPARE(qHash(s), qHash(QStringView(s)));
+void tst_QHashFunctions::init()
+{
+ QFETCH_GLOBAL(quint64, seedValue);
+ seed = size_t(seedValue);
+}
+
+template <typename T> static void addPositiveCommonRows()
+{
+ QTest::addRow("zero") << T(0);
+ QTest::addRow("positive_7bit") << T(42);
+ QTest::addRow("positive_15bit") << T(0x1f3f);
+ QTest::addRow("positive_31bit") << T(0x4b3d'93c4);
+ QTest::addRow("positive_63bit") << T(Q_INT64_C(0x39df'7338'4b14'fcb0));
+
+ QTest::addRow("SCHAR_MAX") << T(SCHAR_MAX);
+ QTest::addRow("SHRT_MAX") << T(SHRT_MAX);
+ QTest::addRow("INT_MAX") << T(INT_MAX);
+ QTest::addRow("LLONG_MAX") << T(LLONG_MAX);
+}
+
+void tst_QHashFunctions::signedIntegerConsistency_data()
+{
+ QTest::addColumn<qint64>("value");
+ addPositiveCommonRows<qint64>();
+ QTest::addRow("negative_7bit") << Q_INT64_C(-28);
+ QTest::addRow("negative_15bit") << Q_INT64_C(-0x387c);
+ QTest::addRow("negative_31bit") << qint64(-0x7713'30f9);
+
+ QTest::addRow("SCHAR_MIN") << qint64(SCHAR_MIN);
+ QTest::addRow("SHRT_MIN") << qint64(SHRT_MIN);
+ QTest::addRow("INT_MIN") << qint64(INT_MIN);
+ QTest::addRow("LLONG_MIN") << LLONG_MIN;
+}
+
+void tst_QHashFunctions::unsignedIntegerConsistency_data()
+{
+ QTest::addColumn<quint64>("value");
+ addPositiveCommonRows<quint64>();
+
+ QTest::addRow("positive_8bit") << Q_UINT64_C(0xE4);
+ QTest::addRow("positive_16bit") << Q_UINT64_C(0xcafe);
+ QTest::addRow("positive_32bit") << quint64(0xcafe'babe);
+
+ QTest::addRow("UCHAR_MAX") << quint64(UCHAR_MAX);
+ QTest::addRow("UHRT_MAX") << quint64(USHRT_MAX);
+ QTest::addRow("UINT_MAX") << quint64(UINT_MAX);
+ QTest::addRow("ULLONG_MAX") << ULLONG_MAX;
+}
+
+static void unsignedIntegerConsistency(quint64 value, size_t seed)
+{
+ quint8 v8 = quint8(value);
+ quint16 v16 = quint16(value);
+ quint32 v32 = quint32(value);
+
+ const auto hu8 = qHash(v8, seed);
+ const auto hu16 = qHash(v16, seed);
+ const auto hu32 = qHash(v32, seed);
+ const auto hu64 = qHash(value, seed);
+
+ if (v8 == value)
+ QCOMPARE(hu8, hu32);
+ if (v16 == value)
+ QCOMPARE(hu16, hu32);
+ if (v32 == value)
+ QCOMPARE(hu64, hu32);
+
+#if QT_SUPPORTS_INT128
+ const auto hu128 = qHash(quint128(value), seed);
+ QCOMPARE(hu128, hu64);
+#endif
+
+ // there are a few more unsigned types:
+#ifdef __cpp_char8_t
+ const auto hc8 = qHash(char8_t(value), seed);
+#endif
+ const auto hc16 = qHash(char16_t(value), seed);
+ const auto hc32 = qHash(char32_t(value), seed);
+#ifdef __cpp_char8_t
+ QCOMPARE(hc8, hu8);
+#endif
+ QCOMPARE(hc16, hu16);
+ QCOMPARE(hc32, hu32);
+}
+
+void tst_QHashFunctions::unsignedIntegerConsistency()
+{
+ QFETCH(quint64, value);
+ ::unsignedIntegerConsistency(value, seed);
+}
+
+void tst_QHashFunctions::signedIntegerConsistency()
+{
+ QFETCH(qint64, value);
+ qint8 v8 = qint8(value);
+ qint16 v16 = qint16(value);
+ qint32 v32 = qint32(value);
+
+ const auto hs8 = qHash(v8, seed);
+ const auto hs16 = qHash(v16, seed);
+ const auto hs32 = qHash(v32, seed);
+ const auto hs64 = qHash(value, seed);
+
+ if (v8 == value)
+ QCOMPARE(hs8, hs32);
+ if (v16 == value)
+ QCOMPARE(hs16, hs32);
+ if (v32 == value) {
+ // because of QTBUG-116080, this may not match, but we can't guarantee
+ // it mismatches 100% of the time either
+ if constexpr (sizeof(size_t) > sizeof(int) || QT_VERSION_MAJOR > 6)
+ QCOMPARE(hs64, hs32);
+ }
+
+#if QT_SUPPORTS_INT128
+ const auto hs128 = qHash(qint128(value), seed);
+ QCOMPARE(hs128, hs64);
+#endif
+
+ if (value > 0) {
+ quint64 u64 = quint64(value);
+ const auto hu64 = qHash(u64, seed);
+ QCOMPARE(hu64, hs64);
+ ::unsignedIntegerConsistency(u64, seed);
+ // by A == B && B == C -> A == C, we've shown hsXX == huXX for all XX
}
}
-void tst_QHashFunctions::initTestCase()
+void tst_QHashFunctions::extendedIntegerConsistency()
{
- Q_STATIC_ASSERT(int(RandomSeed) > 0);
+#ifdef QT_SUPPORTS_INT128
+ // We only need to check qint128 and quint128 consistency here.
+ qint128 v65bit = Q_INT128_C(0x1'abea'06b7'dcf5'106a);
+ qint128 v127bit = Q_INT128_C(0x387c'ac7a'22a0'5242'9ee9'bcaa'6a53'13af);
+
+ QCOMPARE(qHash(quint128(v65bit), seed), qHash(v65bit, seed));
+ QCOMPARE(qHash(quint128(v127bit), seed), qHash(v127bit, seed));
+#else
+ QSKIP("This platform does not support extended integer types.");
+#endif
+}
+
+void tst_QHashFunctions::floatingPointConsistency_data()
+{
+ QTest::addColumn<double>("value");
+ QTest::addRow("zero") << 0.0;
+
+ QTest::addRow("1.0") << 1.0;
+ QTest::addRow("infinity") << std::numeric_limits<double>::infinity();
+
+ QTest::addRow("fp16_epsilon") << double(std::numeric_limits<qfloat16>::epsilon());
+ QTest::addRow("fp16_min") << double(std::numeric_limits<qfloat16>::min());
+ QTest::addRow("fp16_max") << double(std::numeric_limits<qfloat16>::max());
+
+ QTest::addRow("float_epsilon") << double(std::numeric_limits<float>::epsilon());
+ QTest::addRow("float_min") << double(std::numeric_limits<float>::min());
+ QTest::addRow("float_max") << double(std::numeric_limits<float>::max());
- QTest::addColumn<uint>("seedValue");
- QTest::newRow("zero-seed") << 0U;
- QTest::newRow("non-zero-seed") << uint(RandomSeed);
+ QTest::addRow("double_epsilon") << double(std::numeric_limits<double>::epsilon());
+ QTest::addRow("double_min") << double(std::numeric_limits<double>::min());
+ QTest::addRow("double_max") << double(std::numeric_limits<double>::max());
}
-void tst_QHashFunctions::init()
+void tst_QHashFunctions::floatingPointConsistency()
{
- QFETCH_GLOBAL(uint, seedValue);
- seed = seedValue;
+ QFETCH(double, value);
+ long double lvalue = value;
+ float fp32 = float(value);
+ qfloat16 fp16 = qfloat16(value);
+
+ const auto hfld = qHash(lvalue, seed);
+ const auto hf64 = qHash(value, seed);
+ const auto hf32 = qHash(fp32, seed);
+ const auto hf16 = qHash(fp16, seed);
+
+ const auto hnfld = qHash(-lvalue, seed);
+ const auto hnf64 = qHash(-value, seed);
+ const auto hnf32 = qHash(-fp32, seed);
+ const auto hnf16 = qHash(-fp16, seed);
+
+ if (fp16 == fp32) {
+ QCOMPARE(hf16, hf32);
+ QCOMPARE(hnf16, hnf32);
+ }
+
+ // See QTBUG-116077; the rest isn't guaranteed to match (but we can't
+ // guarantee it will mismatch either).
+ return;
+
+ if (fp32 == value) {
+ QCOMPARE(hf32, hf64);
+ QCOMPARE(hnf32, hnf64);
+ }
+
+ QCOMPARE(hfld, hf64);
+ QCOMPARE(hnfld, hnf64);
+}
+
+void tst_QHashFunctions::stringConsistency_data()
+{
+ QTest::addColumn<QString>("value");
+ QTest::newRow("null") << QString();
+ QTest::newRow("empty") << "";
+ QTest::newRow("withnull") << QStringLiteral("A\0z");
+ QTest::newRow("short-ascii") << "Hello"; // 10 bytes
+ QTest::newRow("medium-ascii") << "Hello, World"; // 24 bytes
+ QTest::newRow("long-ascii") << QStringLiteral("abcdefghijklmnopqrstuvxyz").repeated(16);
+
+ QTest::newRow("short-latin1") << "Bokmål";
+ QTest::newRow("medium-latin1") << "Det går bra!"; // 24 bytes
+ QTest::newRow("long-latin1")
+ << R"(Alle mennesker er født frie og med samme menneskeverd og menneskerettigheter.
+ De er utstyrt med fornuft og samvittighet og bør handle mot hverandre i brorskapets ånd.)";
+
+ QTest::newRow("short-nonlatin1") << "Ελληνικά";
+ QTest::newRow("long-nonlatin1")
+ << R"('Ολοι οι άνθρωποι γεννιούνται ελεύθεροι και ίσοι στην αξιοπρέπεια και τα
+ δικαιώματα. Είναι προικισμένοι με λογική και συνείδηση, και οφείλουν να συμπεριφέρονται μεταξύ
+ τους με πνεύμα αδελφοσύνης.)";
+}
+
+void tst_QHashFunctions::stringConsistency()
+{
+ QFETCH(QString, value);
+ QStringView sv = value;
+ QByteArray u8ba = value.toUtf8();
+ QByteArray u8bav = u8ba;
+
+ // sanity checking:
+ QCOMPARE(sv.isNull(), value.isNull());
+ QCOMPARE(sv.isEmpty(), value.isEmpty());
+ QCOMPARE(u8ba.isNull(), value.isNull());
+ QCOMPARE(u8ba.isEmpty(), value.isEmpty());
+ QCOMPARE(u8bav.isNull(), value.isNull());
+ QCOMPARE(u8bav.isEmpty(), value.isEmpty());
+
+ QCOMPARE(qHash(sv, seed), qHash(value, seed));
+ QCOMPARE(qHash(u8bav, seed), qHash(u8ba, seed));
+
+ if (seed == 0 || QHashHeterogeneousSearch<QString, QLatin1StringView>::value) {
+ QByteArray l1ba = value.toLatin1();
+ QLatin1StringView l1sv(l1ba.data(), l1ba.size());
+#ifdef Q_PROCESSOR_ARM
+ // zero-extending aeshash not implemented on ARM
+#else
+ if (value == l1sv)
+ QCOMPARE(qHash(l1sv, seed), qHash(value, seed));
+#endif
+ }
}
void tst_QHashFunctions::qhash()
@@ -93,7 +341,6 @@ void tst_QHashFunctions::qhash()
{
QBitArray a1;
QBitArray a2;
- QCOMPARE(qHash(a1, seed), seed);
a1.resize(1);
a1.setBit(0, true);
@@ -101,8 +348,8 @@ void tst_QHashFunctions::qhash()
a2.resize(1);
a2.setBit(0, false);
- uint h1 = qHash(a1, seed);
- uint h2 = qHash(a2, seed);
+ size_t h1 = qHash(a1, seed);
+ size_t h2 = qHash(a2, seed);
QVERIFY(h1 != h2); // not guaranteed
@@ -120,14 +367,14 @@ void tst_QHashFunctions::qhash()
QVERIFY(h1 == h2);
a2.setBit(0, false);
- uint h3 = qHash(a2, seed);
+ size_t h3 = qHash(a2, seed);
QVERIFY(h2 != h3); // not guaranteed
a2.setBit(0, true);
QVERIFY(h2 == qHash(a2, seed));
a2.setBit(6, false);
- uint h4 = qHash(a2, seed);
+ size_t h4 = qHash(a2, seed);
QVERIFY(h2 != h4); // not guaranteed
a2.setBit(6, true);
@@ -173,10 +420,6 @@ void tst_QHashFunctions::qhash_of_empty_and_null_qstring()
QCOMPARE(null, empty);
QCOMPARE(qHash(null, seed), qHash(empty, seed));
- QStringRef nullRef, emptyRef(&empty);
- QCOMPARE(nullRef, emptyRef);
- QCOMPARE(qHash(nullRef, seed), qHash(emptyRef, seed));
-
QStringView nullView, emptyView(empty);
QCOMPARE(nullView, emptyView);
QCOMPARE(qHash(nullView, seed), qHash(emptyView, seed));
@@ -189,18 +432,11 @@ void tst_QHashFunctions::qhash_of_empty_and_null_qbytearray()
QCOMPARE(qHash(null, seed), qHash(empty, seed));
}
-void tst_QHashFunctions::fp_qhash_of_zero_is_seed()
+void tst_QHashFunctions::qhash_of_zero_floating_points()
{
- QCOMPARE(qHash(-0.0f, seed), seed);
- QCOMPARE(qHash( 0.0f, seed), seed);
-
- QCOMPARE(qHash(-0.0 , seed), seed);
- QCOMPARE(qHash( 0.0 , seed), seed);
-
-#ifndef Q_OS_DARWIN
- QCOMPARE(qHash(-0.0L, seed), seed);
- QCOMPARE(qHash( 0.0L, seed), seed);
-#endif
+ QCOMPARE(qHash(-0.0f, seed), qHash(0.0f, seed));
+ QCOMPARE(qHash(-0.0 , seed), qHash(0.0 , seed));
+ QCOMPARE(qHash(-0.0L, seed), qHash(0.0L, seed));
}
void tst_QHashFunctions::qthash_data()
@@ -224,10 +460,16 @@ void tst_QHashFunctions::qthash()
namespace SomeNamespace {
struct Hashable { int i; };
- inline uint qHash(Hashable h, uint seed = 0)
+ inline size_t qHash(Hashable h, size_t seed = 0)
{ return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); }
-}
+ struct AdlHashable {
+ int i;
+ private:
+ friend size_t qHash(AdlHashable h, size_t seed = 0)
+ { return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); }
+ };
+}
void tst_QHashFunctions::range()
{
static const int ints[] = {0, 1, 2, 3, 4, 5};
@@ -242,17 +484,23 @@ void tst_QHashFunctions::range()
{
// verify that the input iterator category suffices:
std::stringstream sstream;
- Q_STATIC_ASSERT((std::is_same<std::input_iterator_tag, std::istream_iterator<int>::iterator_category>::value));
+ static_assert((std::is_same<std::input_iterator_tag, std::istream_iterator<int>::iterator_category>::value));
std::copy(ints, ints + numInts, std::ostream_iterator<int>(sstream, " "));
sstream.seekg(0);
std::istream_iterator<int> it(sstream), end;
QCOMPARE(qHashRange(ints, ints + numInts, seed), qHashRange(it, end, seed));
}
- SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
- static const size_t numHashables = sizeof hashables / sizeof *hashables;
- // compile check: is qHash() found using ADL?
- (void)qHashRange(hashables, hashables + numHashables, seed);
+ {
+ SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found using ADL?
+ [[maybe_unused]] auto r = qHashRange(std::begin(hashables), std::end(hashables), seed);
+ }
+ {
+ SomeNamespace::AdlHashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found as a hidden friend?
+ [[maybe_unused]] auto r = qHashRange(std::begin(hashables), std::end(hashables), seed);
+ }
}
void tst_QHashFunctions::rangeCommutative()
@@ -275,14 +523,118 @@ void tst_QHashFunctions::rangeCommutative()
QCOMPARE(qHashRangeCommutative(ints, ints + numInts, seed), qHashRangeCommutative(it, end, seed));
}
- SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
- static const size_t numHashables = sizeof hashables / sizeof *hashables;
- // compile check: is qHash() found using ADL?
- (void)qHashRangeCommutative(hashables, hashables + numHashables, seed);
+ {
+ SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found using ADL?
+ [[maybe_unused]] auto r = qHashRangeCommutative(std::begin(hashables), std::end(hashables), seed);
+ }
+ {
+ SomeNamespace::AdlHashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found as a hidden friend?
+ [[maybe_unused]] auto r = qHashRangeCommutative(std::begin(hashables), std::end(hashables), seed);
+ }
+}
+
+// QVarLengthArray these days has a qHash() as a hidden friend.
+// This checks that QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH can deal with that:
+
+QT_BEGIN_NAMESPACE
+QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QVarLengthArray<QVector<int>>)
+QT_END_NAMESPACE
+
+void tst_QHashFunctions::stdHash()
+{
+ {
+ std::unordered_set<QVarLengthArray<QVector<int>>> s = {
+ {
+ {0, 1, 2},
+ {42, 43, 44},
+ {},
+ }, {
+ {11, 12, 13},
+ {},
+ },
+ };
+ QCOMPARE(s.size(), 2UL);
+ s.insert({
+ {11, 12, 13},
+ {},
+ });
+ QCOMPARE(s.size(), 2UL);
+ }
+
+ {
+ std::unordered_set<QString> s = {QStringLiteral("Hello"), QStringLiteral("World")};
+ QCOMPARE(s.size(), 2UL);
+ s.insert(QStringLiteral("Hello"));
+ QCOMPARE(s.size(), 2UL);
+ }
+
+ {
+ std::unordered_set<QStringView> s = {QStringLiteral("Hello"), QStringLiteral("World")};
+ QCOMPARE(s.size(), 2UL);
+ s.insert(QStringLiteral("Hello"));
+ QCOMPARE(s.size(), 2UL);
+ }
+
+ {
+ std::unordered_set<QLatin1String> s = {QLatin1String("Hello"), QLatin1String("World")};
+ QCOMPARE(s.size(), 2UL);
+ s.insert(QLatin1String("Hello"));
+ QCOMPARE(s.size(), 2UL);
+ }
+
+ {
+ std::unordered_set<QByteArray> s = {QByteArrayLiteral("Hello"), QByteArrayLiteral("World")};
+ QCOMPARE(s.size(), 2UL);
+ s.insert(QByteArray("Hello"));
+ QCOMPARE(s.size(), 2UL);
+ }
+
+ {
+ std::unordered_set<QChar> s = {u'H', u'W'};
+ QCOMPARE(s.size(), 2UL);
+ s.insert(u'H');
+ QCOMPARE(s.size(), 2UL);
+ }
+
+}
+
+template <typename T1, typename T2>
+void tst_QHashFunctions::stdPair_template(const T1 &t1, const T2 &t2)
+{
+ std::pair<T1, T2> dpair{};
+ std::pair<T1, T2> vpair{t1, t2};
+
+ // confirm proper working of the pair and of the underlying types
+ QVERIFY(t1 == t1);
+ QVERIFY(t2 == t2);
+ QCOMPARE(qHash(t1, seed), qHash(t1, seed));
+ QCOMPARE(qHash(t2, seed), qHash(t2, seed));
+
+ QVERIFY(dpair == dpair);
+ QVERIFY(vpair == vpair);
+
+ // therefore their hashes should be equal
+ QCOMPARE(qHash(dpair, seed), qHash(dpair, seed));
+ QCOMPARE(qHash(vpair, seed), qHash(vpair, seed));
+}
+
+void tst_QHashFunctions::enum_int_consistent_hash_qtbug108032()
+{
+ enum E { E1, E2, E3 };
+
+ static_assert(QHashPrivate::HasQHashSingleArgOverload<E>);
+
+ QCOMPARE(qHash(E1, seed), qHash(int(E1), seed));
+ QCOMPARE(qHash(E2, seed), qHash(int(E2), seed));
+ QCOMPARE(qHash(E3, seed), qHash(int(E3), seed));
}
+#if QT_DEPRECATED_SINCE(6, 6)
void tst_QHashFunctions::setGlobalQHashSeed()
{
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
// Setter works as advertised
qSetGlobalQHashSeed(0);
QCOMPARE(qGlobalQHashSeed(), 0);
@@ -295,7 +647,9 @@ void tst_QHashFunctions::setGlobalQHashSeed()
// Reset works as advertised
qSetGlobalQHashSeed(-1);
QVERIFY(qGlobalQHashSeed() > 0);
+QT_WARNING_POP
}
+#endif // QT_DEPRECATED_SINCE(6, 6)
QTEST_APPLESS_MAIN(tst_QHashFunctions)
#include "tst_qhashfunctions.moc"
diff --git a/tests/auto/corelib/tools/qhashseed/CMakeLists.txt b/tests/auto/corelib/tools/qhashseed/CMakeLists.txt
new file mode 100644
index 0000000000..27b4cce133
--- /dev/null
+++ b/tests/auto/corelib/tools/qhashseed/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qhashseed Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qhashseed LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qhashseed
+ SOURCES
+ tst_qhashseed.cpp
+)
+
+qt_internal_add_executable(tst_qhashseed_helper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ tst_qhashseed_helper.cpp
+)
diff --git a/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp b/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp
new file mode 100644
index 0000000000..99fc7c5772
--- /dev/null
+++ b/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp
@@ -0,0 +1,186 @@
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <qhashfunctions.h>
+#if QT_CONFIG(process)
+#include <qprocess.h>
+#endif
+
+class tst_QHashSeed : public QObject
+{
+ Q_OBJECT
+public:
+ static void initMain();
+
+private Q_SLOTS:
+ void initTestCase();
+ void environmentVariable_data();
+ void environmentVariable();
+ void deterministicSeed();
+ void reseeding();
+ void quality();
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+ void compatibilityApi();
+ void deterministicSeed_compat();
+#endif
+};
+
+void tst_QHashSeed::initMain()
+{
+ qunsetenv("QT_HASH_SEED");
+}
+
+void tst_QHashSeed::initTestCase()
+{
+ // in case the qunsetenv above didn't work
+ if (qEnvironmentVariableIsSet("QT_HASH_SEED"))
+ QSKIP("QT_HASH_SEED environment variable is set, please don't do that");
+}
+
+void tst_QHashSeed::environmentVariable_data()
+{
+#ifdef Q_OS_ANDROID
+ QSKIP("This test needs a helper binary, so is excluded from this platform.");
+#endif
+
+ QTest::addColumn<QByteArray>("envVar");
+ QTest::addColumn<bool>("isZero");
+ QTest::newRow("unset-environment") << QByteArray() << false;
+ QTest::newRow("empty-environment") << QByteArray("") << false;
+ QTest::newRow("zero-seed") << QByteArray("0") << true;
+}
+
+void tst_QHashSeed::environmentVariable()
+{
+ #if QT_CONFIG(process)
+ QFETCH(QByteArray, envVar);
+ QFETCH(bool, isZero);
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ if (envVar.isNull())
+ env.remove("QT_HASH_SEED");
+ else
+ env.insert("QT_HASH_SEED", envVar);
+
+ QProcess helper;
+ helper.setProcessEnvironment(env);
+ helper.setProgram("./tst_qhashseed_helper");
+ helper.start();
+ QVERIFY2(helper.waitForStarted(5000), qPrintable(helper.errorString()));
+ QVERIFY2(helper.waitForFinished(5000), qPrintable(helper.errorString()));
+ QCOMPARE(helper.exitStatus(), 0);
+
+ QByteArray line1 = helper.readLine().trimmed();
+ QByteArray line2 = helper.readLine().trimmed();
+ QCOMPARE(line2, line1);
+ QCOMPARE(line1 == "0", isZero);
+#endif
+}
+
+void tst_QHashSeed::deterministicSeed()
+{
+ QHashSeed::setDeterministicGlobalSeed();
+ QCOMPARE(size_t(QHashSeed::globalSeed()), size_t(0));
+
+ // now reset
+ QHashSeed::resetRandomGlobalSeed();
+ QVERIFY(QHashSeed::globalSeed() != 0);
+}
+
+void tst_QHashSeed::reseeding()
+{
+ constexpr int Iterations = 4;
+ size_t seeds[Iterations];
+ for (int i = 0; i < Iterations; ++i) {
+ seeds[i] = QHashSeed::globalSeed();
+ QHashSeed::resetRandomGlobalSeed();
+ }
+
+ // verify that they are all different
+ QString fmt = QStringLiteral("seeds[%1] = 0x%3, seeds[%2] = 0x%4");
+ for (int i = 0; i < Iterations; ++i) {
+ for (int j = i + 1; j < Iterations; ++j) {
+ QVERIFY2(seeds[i] != seeds[j],
+ qPrintable(fmt.arg(i).arg(j).arg(seeds[i], 16).arg(seeds[j], 16)));
+ }
+ }
+}
+
+void tst_QHashSeed::quality()
+{
+ // this "bad seed" is used internally in qhash.cpp and should never leak!
+ constexpr size_t BadSeed = size_t(Q_UINT64_C(0x5555'5555'5555'5555));
+
+ constexpr int Iterations = 24; // nicely divisible by 3
+ int oneThird = 0;
+ int badSeeds = 0;
+ int seedsToMinus1 = 0;
+ size_t ored = 0;
+
+ for (int i = 0; i < Iterations; ++i) {
+ size_t seed = QHashSeed::globalSeed();
+ ored |= seed;
+ int bits = qPopulationCount(quintptr(seed));
+ QVERIFY2(bits > 0, QByteArray::number(bits)); // mandatory
+
+ if (bits >= std::numeric_limits<size_t>::digits / 3)
+ ++oneThird;
+ if (seed == BadSeed)
+ ++badSeeds;
+ if (ored != size_t(-1))
+ ++seedsToMinus1;
+
+ QHashSeed::resetRandomGlobalSeed();
+ }
+
+ // report out
+ qInfo() << "Number of seeds until all bits became set:" << seedsToMinus1 << '/' << Iterations;
+ qInfo() << "Number of seeds with at least one third of the bits set:"
+ << oneThird << '/' << Iterations;
+
+ // we must have set all bits after all the iterations
+ QCOMPARE(ored, size_t(-1));
+
+ // at least one third of the seeds must have one third of all the bits set
+ QVERIFY(oneThird > (Iterations/3));
+
+ // at most one seed can be the bad seed, if 32-bit, none on 64-bit
+ if (std::numeric_limits<size_t>::digits > 32)
+ QCOMPARE(badSeeds, 0);
+ else
+ QVERIFY2(badSeeds <= 1, "badSeeds = " + QByteArray::number(badSeeds));
+
+ // we must have taken at most two thirds of the iterations to have set each
+ // bit at least once
+ QVERIFY2(seedsToMinus1 < 2*Iterations/3,
+ "seedsToMinus1 = " + QByteArray::number(seedsToMinus1));
+}
+
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QHashSeed::compatibilityApi()
+{
+ int oldSeed = qGlobalQHashSeed();
+ size_t newSeed = QHashSeed::globalSeed();
+
+ QCOMPARE(size_t(oldSeed), newSeed & size_t(INT_MAX));
+}
+
+void tst_QHashSeed::deterministicSeed_compat()
+{
+ // same as above, but using the compat API
+ qSetGlobalQHashSeed(0);
+ QCOMPARE(size_t(QHashSeed::globalSeed()), size_t(0));
+ QCOMPARE(qGlobalQHashSeed(), 0);
+
+ // now reset
+ qSetGlobalQHashSeed(-1);
+ QVERIFY(QHashSeed::globalSeed() != 0);
+ QVERIFY(qGlobalQHashSeed() != 0);
+ QVERIFY(qGlobalQHashSeed() != -1); // possible, but extremely unlikely
+}
+#endif // Qt 7
+
+QTEST_MAIN(tst_QHashSeed)
+#include "tst_qhashseed.moc"
diff --git a/tests/auto/corelib/tools/qhashseed/tst_qhashseed_helper.cpp b/tests/auto/corelib/tools/qhashseed/tst_qhashseed_helper.cpp
new file mode 100644
index 0000000000..25e7909870
--- /dev/null
+++ b/tests/auto/corelib/tools/qhashseed/tst_qhashseed_helper.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <qhashfunctions.h>
+#include <stdio.h>
+
+int main()
+{
+ // appless:
+ QHashSeed seed1 = QHashSeed::globalSeed();
+ QHashSeed seed2 = QHashSeed::globalSeed();
+ printf("%zu\n%zu\n", size_t(seed1), size_t(seed2));
+ return 0;
+}
diff --git a/tests/auto/corelib/tools/qlatin1string/.gitignore b/tests/auto/corelib/tools/qlatin1string/.gitignore
deleted file mode 100644
index dddf56b2df..0000000000
--- a/tests/auto/corelib/tools/qlatin1string/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qlatin1string
diff --git a/tests/auto/corelib/tools/qlatin1string/qlatin1string.pro b/tests/auto/corelib/tools/qlatin1string/qlatin1string.pro
deleted file mode 100644
index 61054b40e4..0000000000
--- a/tests/auto/corelib/tools/qlatin1string/qlatin1string.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG += testcase parallel_test
-TARGET = tst_qlatin1string
-QT = core testlib
-SOURCES = tst_qlatin1string.cpp
-DEFINES += QT_NO_CAST_TO_ASCII
-qtConfig(c++11): CONFIG += c++11
-qtConfig(c++14): CONFIG += c++14
-
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp
deleted file mode 100644
index dcfb0aa042..0000000000
--- a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include <QString>
-
-// Preserve QLatin1String-ness (QVariant(QLatin1String) creates a QVariant::String):
-struct QLatin1StringContainer {
- QLatin1String l1;
-};
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(QLatin1StringContainer, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QLatin1StringContainer)
-
-class tst_QLatin1String : public QObject
-{
- Q_OBJECT
-
-private Q_SLOTS:
- void at();
- void midLeftRight();
- void nullString();
- void emptyString();
- void iterators();
- void relationalOperators_data();
- void relationalOperators();
-};
-
-
-void tst_QLatin1String::at()
-{
- const QLatin1String l1("Hello World");
- QCOMPARE(l1.at(0), QLatin1Char('H'));
- QCOMPARE(l1.at(l1.size() - 1), QLatin1Char('d'));
- QCOMPARE(l1[0], QLatin1Char('H'));
- QCOMPARE(l1[l1.size() - 1], QLatin1Char('d'));
-}
-
-void tst_QLatin1String::midLeftRight()
-{
- const QLatin1String l1("Hello World");
- QCOMPARE(l1.mid(0), l1);
- QCOMPARE(l1.mid(0, l1.size()), l1);
- QCOMPARE(l1.left(l1.size()), l1);
- QCOMPARE(l1.right(l1.size()), l1);
-
- QCOMPARE(l1.mid(6), QLatin1String("World"));
- QCOMPARE(l1.mid(6, 5), QLatin1String("World"));
- QCOMPARE(l1.right(5), QLatin1String("World"));
-
- QCOMPARE(l1.mid(6, 1), QLatin1String("W"));
- QCOMPARE(l1.right(5).left(1), QLatin1String("W"));
-
- QCOMPARE(l1.left(5), QLatin1String("Hello"));
-}
-
-void tst_QLatin1String::nullString()
-{
- // default ctor
- {
- QLatin1String l1;
- QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
- QCOMPARE(l1.size(), 0);
-
- QString s = l1;
- QVERIFY(s.isNull());
- }
-
- // from nullptr
- {
- const char *null = nullptr;
- QLatin1String l1(null);
- QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
- QCOMPARE(l1.size(), 0);
-
- QString s = l1;
- QVERIFY(s.isNull());
- }
-
- // from null QByteArray
- {
- const QByteArray null;
- QVERIFY(null.isNull());
-
- QLatin1String l1(null);
- QEXPECT_FAIL("", "null QByteArrays become non-null QLatin1Strings...", Continue);
- QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(nullptr));
- QCOMPARE(l1.size(), 0);
-
- QString s = l1;
- QEXPECT_FAIL("", "null QByteArrays become non-null QLatin1Strings become non-null QStrings...", Continue);
- QVERIFY(s.isNull());
- }
-}
-
-void tst_QLatin1String::emptyString()
-{
- {
- const char *empty = "";
- QLatin1String l1(empty);
- QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty));
- QCOMPARE(l1.size(), 0);
-
- QString s = l1;
- QVERIFY(s.isEmpty());
- QVERIFY(!s.isNull());
- }
-
- {
- const char *notEmpty = "foo";
- QLatin1String l1(notEmpty, 0);
- QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(notEmpty));
- QCOMPARE(l1.size(), 0);
-
- QString s = l1;
- QVERIFY(s.isEmpty());
- QVERIFY(!s.isNull());
- }
-
- {
- const QByteArray empty = "";
- QLatin1String l1(empty);
- QCOMPARE(static_cast<const void*>(l1.data()), static_cast<const void*>(empty.constData()));
- QCOMPARE(l1.size(), 0);
-
- QString s = l1;
- QVERIFY(s.isEmpty());
- QVERIFY(!s.isNull());
- }
-}
-
-void tst_QLatin1String::iterators()
-{
- QLatin1String hello("hello");
- QLatin1String olleh("olleh");
-
- QVERIFY(std::equal(hello.begin(), hello.end(),
- olleh.rbegin()));
- QVERIFY(std::equal(hello.rbegin(), hello.rend(),
- QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size())));
-
- QVERIFY(std::equal(hello.cbegin(), hello.cend(),
- olleh.rbegin()));
- QVERIFY(std::equal(hello.crbegin(), hello.crend(),
- QT_MAKE_CHECKED_ARRAY_ITERATOR(olleh.begin(), olleh.size())));
-}
-
-void tst_QLatin1String::relationalOperators_data()
-{
- QTest::addColumn<QLatin1StringContainer>("lhs");
- QTest::addColumn<int>("lhsOrderNumber");
- QTest::addColumn<QLatin1StringContainer>("rhs");
- QTest::addColumn<int>("rhsOrderNumber");
-
- struct Data {
- QLatin1String l1;
- int order;
- } data[] = {
- { QLatin1String(), 0 },
- { QLatin1String(""), 0 },
- { QLatin1String("a"), 1 },
- { QLatin1String("aa"), 2 },
- { QLatin1String("b"), 3 },
- };
-
- for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) {
- for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) {
- QLatin1StringContainer l = { lhs->l1 }, r = { rhs->l1 };
- QTest::addRow("\"%s\" <> \"%s\"",
- lhs->l1.data() ? lhs->l1.data() : "nullptr",
- rhs->l1.data() ? rhs->l1.data() : "nullptr")
- << l << lhs->order << r << rhs->order;
- }
- }
-}
-
-void tst_QLatin1String::relationalOperators()
-{
- QFETCH(QLatin1StringContainer, lhs);
- QFETCH(int, lhsOrderNumber);
- QFETCH(QLatin1StringContainer, rhs);
- QFETCH(int, rhsOrderNumber);
-
-#define CHECK(op) \
- QCOMPARE(lhs.l1 op rhs.l1, lhsOrderNumber op rhsOrderNumber) \
- /*end*/
- CHECK(==);
- CHECK(!=);
- CHECK(< );
- CHECK(> );
- CHECK(<=);
- CHECK(>=);
-#undef CHECK
-}
-
-QTEST_APPLESS_MAIN(tst_QLatin1String)
-
-#include "tst_qlatin1string.moc"
diff --git a/tests/auto/corelib/tools/qline/CMakeLists.txt b/tests/auto/corelib/tools/qline/CMakeLists.txt
new file mode 100644
index 0000000000..17a3a1bcef
--- /dev/null
+++ b/tests/auto/corelib/tools/qline/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qline Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qline LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qline
+ SOURCES
+ tst_qline.cpp
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(tst_qline CONDITION UNIX AND NOT APPLE AND NOT HAIKU AND NOT INTEGRITY AND NOT VXWORKS
+ LIBRARIES
+ m
+)
diff --git a/tests/auto/corelib/tools/qline/qline.pro b/tests/auto/corelib/tools/qline/qline.pro
deleted file mode 100644
index 81e2f17118..0000000000
--- a/tests/auto/corelib/tools/qline/qline.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qline
-QT = core testlib
-SOURCES = tst_qline.cpp
-unix:!darwin:!vxworks:!haiku:!integrity: LIBS+=-lm
diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp
index ae65d8f697..51f1f8ac79 100644
--- a/tests/auto/corelib/tools/qline/tst_qline.cpp
+++ b/tests/auto/corelib/tools/qline/tst_qline.cpp
@@ -1,38 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qline.h>
-#include <math.h>
+#include <qmath.h>
-#ifndef M_2PI
-#define M_2PI 6.28318530717958647692528676655900576
-#endif
+#include <array>
class tst_QLine : public QObject
{
@@ -53,9 +26,6 @@ private slots:
void testNormalVector();
void testNormalVector_data();
- void testAngle();
- void testAngle_data();
-
void testAngle2();
void testAngle2_data();
@@ -65,13 +35,10 @@ private slots:
void testAngleTo_data();
void testSet();
-};
-// Square root of two
-#define SQRT2 1.4142135623731
-
-// Length of unit vector projected to x from 45 degrees
-#define UNITX_45 0.707106781186547
+ void toLineF_data();
+ void toLineF();
+};
const qreal epsilon = sizeof(qreal) == sizeof(double) ? 1e-8 : 1e-4;
@@ -205,7 +172,7 @@ void tst_QLine::testIntersection()
QPointF ip;
- QLineF::IntersectType itype = a.intersect(b, &ip);
+ QLineF::IntersectionType itype = a.intersects(b, &ip);
QCOMPARE(int(itype), type);
if (type != QLineF::NoIntersection) {
@@ -225,30 +192,46 @@ void tst_QLine::testLength_data()
QTest::addColumn<double>("vx");
QTest::addColumn<double>("vy");
- QTest::newRow("[1,0]*2") << 0.0 << 0.0 << 1.0 << 0.0 << 1.0 << 2.0 << 2.0 << 0.0;
- QTest::newRow("[0,1]*2") << 0.0 << 0.0 << 0.0 << 1.0 << 1.0 << 2.0 << 0.0 << 2.0;
- QTest::newRow("[-1,0]*2") << 0.0 << 0.0 << -1.0 << 0.0 << 1.0 << 2.0 << -2.0 << 0.0;
- QTest::newRow("[0,-1]*2") << 0.0 << 0.0 << 0.0 << -1.0 << 1.0 << 2.0 << 0.0 << -2.0;
- QTest::newRow("[1,1]->|1|") << 0.0 << 0.0 << 1.0 << 1.0
- << double(SQRT2) << 1.0 << double(UNITX_45) << double(UNITX_45);
+ // Test name: [dx,dy]->|lenToSet| (x1,x2)
+ // with the last part omitted if (0,0)
+ QTest::newRow("[1,0]->|2|") << 0.0 << 0.0 << 1.0 << 0.0 << 1.0 << 2.0 << 2.0 << 0.0;
+ QTest::newRow("[0,1]->|2|") << 0.0 << 0.0 << 0.0 << 1.0 << 1.0 << 2.0 << 0.0 << 2.0;
+ QTest::newRow("[-1,0]->|2|") << 0.0 << 0.0 << -1.0 << 0.0 << 1.0 << 2.0 << -2.0 << 0.0;
+ QTest::newRow("[0,-1]->|2|") << 0.0 << 0.0 << 0.0 << -1.0 << 1.0 << 2.0 << 0.0 << -2.0;
+ QTest::newRow("[1,1]->->|1|") << 0.0 << 0.0 << 1.0 << 1.0
+ << M_SQRT2 << 1.0 << M_SQRT1_2 << M_SQRT1_2;
QTest::newRow("[-1,1]->|1|") << 0.0 << 0.0 << -1.0 << 1.0
- << double(SQRT2) << 1.0 << double(-UNITX_45) << double(UNITX_45);
+ << M_SQRT2 << 1.0 << -M_SQRT1_2 << M_SQRT1_2;
QTest::newRow("[1,-1]->|1|") << 0.0 << 0.0 << 1.0 << -1.0
- << double(SQRT2) << 1.0 << double(UNITX_45) << double(-UNITX_45);
+ << M_SQRT2 << 1.0 << M_SQRT1_2 << -M_SQRT1_2;
QTest::newRow("[-1,-1]->|1|") << 0.0 << 0.0 << -1.0 << -1.0
- << double(SQRT2) << 1.0 << double(-UNITX_45) << double(-UNITX_45);
- QTest::newRow("[1,0]*2 (2,2)") << 2.0 << 2.0 << 3.0 << 2.0 << 1.0 << 2.0 << 2.0 << 0.0;
- QTest::newRow("[0,1]*2 (2,2)") << 2.0 << 2.0 << 2.0 << 3.0 << 1.0 << 2.0 << 0.0 << 2.0;
- QTest::newRow("[-1,0]*2 (2,2)") << 2.0 << 2.0 << 1.0 << 2.0 << 1.0 << 2.0 << -2.0 << 0.0;
- QTest::newRow("[0,-1]*2 (2,2)") << 2.0 << 2.0 << 2.0 << 1.0 << 1.0 << 2.0 << 0.0 << -2.0;
+ << M_SQRT2 << 1.0 << -M_SQRT1_2 << -M_SQRT1_2;
+ QTest::newRow("[1,0]->|2| (2,2)") << 2.0 << 2.0 << 3.0 << 2.0 << 1.0 << 2.0 << 2.0 << 0.0;
+ QTest::newRow("[0,1]->|2| (2,2)") << 2.0 << 2.0 << 2.0 << 3.0 << 1.0 << 2.0 << 0.0 << 2.0;
+ QTest::newRow("[-1,0]->|2| (2,2)") << 2.0 << 2.0 << 1.0 << 2.0 << 1.0 << 2.0 << -2.0 << 0.0;
+ QTest::newRow("[0,-1]->|2| (2,2)") << 2.0 << 2.0 << 2.0 << 1.0 << 1.0 << 2.0 << 0.0 << -2.0;
QTest::newRow("[1,1]->|1| (2,2)") << 2.0 << 2.0 << 3.0 << 3.0
- << double(SQRT2) << 1.0 << double(UNITX_45) << double(UNITX_45);
+ << M_SQRT2 << 1.0 << M_SQRT1_2 << M_SQRT1_2;
QTest::newRow("[-1,1]->|1| (2,2)") << 2.0 << 2.0 << 1.0 << 3.0
- << double(SQRT2) << 1.0 << double(-UNITX_45) << double(UNITX_45);
+ << M_SQRT2 << 1.0 << -M_SQRT1_2 << M_SQRT1_2;
QTest::newRow("[1,-1]->|1| (2,2)") << 2.0 << 2.0 << 3.0 << 1.0
- << double(SQRT2) << 1.0 << double(UNITX_45) << double(-UNITX_45);
+ << M_SQRT2 << 1.0 << M_SQRT1_2 << -M_SQRT1_2;
QTest::newRow("[-1,-1]->|1| (2,2)") << 2.0 << 2.0 << 1.0 << 1.0
- << double(SQRT2) << 1.0 << double(-UNITX_45) << double(-UNITX_45);
+ << M_SQRT2 << 1.0 << -M_SQRT1_2 << -M_SQRT1_2;
+ const double small = qSqrt(std::numeric_limits<qreal>::denorm_min()) / 8;
+ QTest::newRow("[small,small]->|2| (-small/2,-small/2)")
+ << -(small * .5) << -(small * .5) << (small * .5) << (small * .5)
+ << (small * M_SQRT2) << (2 * M_SQRT2) << 2.0 << 2.0;
+ const double tiny = std::numeric_limits<qreal>::min() / 2;
+ QTest::newRow("[tiny,tiny]->|2| (-tiny/2,-tiny/2)")
+ << -(tiny * .5) << -(tiny * .5) << (tiny * .5) << (tiny * .5)
+ << (tiny * M_SQRT2) << (2 * M_SQRT2) << 2.0 << 2.0;
+ QTest::newRow("[1+3e-13,1+4e-13]|1895| (1, 1)")
+ << 1.0 << 1.0 << (1 + 3e-13) << (1 + 4e-13)
+ << 5e-13 << 1895.0 << 1137.0 << 1516.0;
+ QTest::newRow("[4e-323,5e-324]|1892|") // Unavoidable underflow: denormals
+ << 0.0 << 0.0 << 4e-323 << 5e-324
+ << 4e-323 << 1892.0 << 4e-323 << 5e-324; // vx, vy values ignored
}
void tst_QLine::testLength()
@@ -266,9 +249,21 @@ void tst_QLine::testLength()
QCOMPARE(l.length(), qreal(length));
l.setLength(lengthToSet);
- QCOMPARE(l.length(), qreal(lengthToSet));
- QCOMPARE(l.dx(), qreal(vx));
- QCOMPARE(l.dy(), qreal(vy));
+
+ if constexpr (std::numeric_limits<double>::has_denorm != std::denorm_present) {
+ if (qstrcmp(QTest::currentDataTag(), "[tiny,tiny]->|2| (-tiny/2,-tiny/2)") == 0
+ || qstrcmp(QTest::currentDataTag(), "[4e-323,5e-324]|1892|") == 0) {
+ QSKIP("Skipping 'denorm' as this type lacks denormals on this system");
+ }
+ }
+ // Scaling tiny values up to big can be imprecise: don't try to test vx, vy
+ if (length > 0 && qFuzzyIsNull(length)) {
+ QVERIFY(l.length() > lengthToSet / 2 && l.length() < lengthToSet * 2);
+ } else {
+ QCOMPARE(l.length(), length > 0 ? qreal(lengthToSet) : qreal(length));
+ QCOMPARE(l.dx(), qreal(vx));
+ QCOMPARE(l.dy(), qreal(vy));
+ }
}
void tst_QLine::testCenter()
@@ -378,55 +373,6 @@ void tst_QLine::testNormalVector()
QCOMPARE(n.dy(), qreal(nvy));
}
-void tst_QLine::testAngle_data()
-{
- QTest::addColumn<double>("xa1");
- QTest::addColumn<double>("ya1");
- QTest::addColumn<double>("xa2");
- QTest::addColumn<double>("ya2");
- QTest::addColumn<double>("xb1");
- QTest::addColumn<double>("yb1");
- QTest::addColumn<double>("xb2");
- QTest::addColumn<double>("yb2");
- QTest::addColumn<double>("angle");
-
- QTest::newRow("parallel") << 1.0 << 1.0 << 3.0 << 4.0
- << 5.0 << 6.0 << 7.0 << 9.0
- << 0.0;
- QTest::newRow("[4,4]-[4,0]") << 1.0 << 1.0 << 5.0 << 5.0
- << 0.0 << 4.0 << 3.0 << 4.0
- << 45.0;
- QTest::newRow("[4,4]-[-4,0]") << 1.0 << 1.0 << 5.0 << 5.0
- << 3.0 << 4.0 << 0.0 << 4.0
- << 135.0;
-
- for (int i=0; i<180; ++i) {
- QTest::newRow(("angle:" + QByteArray::number(i)).constData())
- << 0.0 << 0.0 << double(cos(i*M_2PI/360)) << double(sin(i*M_2PI/360))
- << 0.0 << 0.0 << 1.0 << 0.0
- << double(i);
- }
-}
-
-void tst_QLine::testAngle()
-{
- QFETCH(double, xa1);
- QFETCH(double, ya1);
- QFETCH(double, xa2);
- QFETCH(double, ya2);
- QFETCH(double, xb1);
- QFETCH(double, yb1);
- QFETCH(double, xb2);
- QFETCH(double, yb2);
- QFETCH(double, angle);
-
- QLineF a(xa1, ya1, xa2, ya2);
- QLineF b(xb1, yb1, xb2, yb2);
-
- double resultAngle = a.angle(b);
- QCOMPARE(qRound(resultAngle), qRound(angle));
-}
-
void tst_QLine::testAngle2_data()
{
QTest::addColumn<qreal>("x1");
@@ -536,5 +482,35 @@ void tst_QLine::testAngleTo_data()
}
}
+void tst_QLine::toLineF_data()
+{
+ QTest::addColumn<QLine>("input");
+ QTest::addColumn<QLineF>("result");
+
+ auto row = [](int x1, int y1, int x2, int y2) {
+ QTest::addRow("((%d, %d)->(%d, %d))", x1, y1, x2, y2)
+ << QLine(x1, y1, x2, y2) << QLineF(x1, y1, x2, y2);
+ };
+ constexpr std::array samples = {-1, 0, 1};
+ for (int x1 : samples) {
+ for (int y1 : samples) {
+ for (int x2 : samples) {
+ for (int y2 : samples) {
+ row(x1, y1, x2, y2);
+ }
+ }
+ }
+ }
+}
+
+void tst_QLine::toLineF()
+{
+ QFETCH(const QLine, input);
+ QFETCH(const QLineF, result);
+
+ QCOMPARE(input.toLineF(), result);
+}
+
+
QTEST_MAIN(tst_QLine)
#include "tst_qline.moc"
diff --git a/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro b/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro
deleted file mode 100644
index 80630f78ad..0000000000
--- a/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qlinkedlist
-QT = core testlib
-SOURCES = tst_qlinkedlist.cpp
diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp
deleted file mode 100644
index f17d6695f0..0000000000
--- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp
+++ /dev/null
@@ -1,1107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QLinkedList>
-
-struct Movable
-{
- Movable(char input = 'j') : i(input), state(Constructed)
- {
- ++liveCount;
- }
- Movable(const Movable &other)
- : i(other.i)
- , state(Constructed)
- {
- check(other.state, Constructed);
- ++liveCount;
- }
-
- ~Movable()
- {
- check(state, Constructed);
- i = 0;
- --liveCount;
- state = Destructed;
- }
-
- bool operator ==(const Movable &other) const
- {
- check(state, Constructed);
- check(other.state, Constructed);
- return i == other.i;
- }
-
- Movable &operator=(const Movable &other)
- {
- check(state, Constructed);
- check(other.state, Constructed);
- i = other.i;
- return *this;
- }
- char i;
-
- static int getLiveCount() { return liveCount; }
-private:
- static int liveCount;
-
- enum State { Constructed = 106, Destructed = 110 };
- State state;
-
- static void check(const State state1, const State state2)
- {
- QCOMPARE(int(state1), int(state2));
- }
-};
-
-int Movable::liveCount = 0;
-
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(Movable);
-
-Q_DECLARE_METATYPE(QLinkedList<int>);
-
-
-int qHash(const Movable& movable)
-{
- return qHash(movable.i);
-}
-
-struct Complex
-{
- Complex(int val = 0)
- : value(val)
- , checkSum(this)
- {
- ++liveCount;
- }
-
- Complex(Complex const &other)
- : value(other.value)
- , checkSum(this)
- {
- ++liveCount;
- }
-
- Complex &operator=(Complex const &other)
- {
- check(); other.check();
-
- value = other.value;
- return *this;
- }
-
- ~Complex()
- {
- --liveCount;
- check();
- }
-
- operator int() const { return value; }
-
- bool operator==(Complex const &other) const
- {
- check(); other.check();
- return value == other.value;
- }
-
- void check() const
- {
- QVERIFY(this == checkSum);
- }
-
- static int getLiveCount() { return liveCount; }
-private:
- static int liveCount;
-
- int value;
- void *checkSum;
-};
-
-int Complex::liveCount = 0;
-
-Q_DECLARE_METATYPE(Complex);
-
-// Tests depend on the fact that:
-Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic);
-Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
-Q_STATIC_ASSERT(QTypeInfo<Complex>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex);
-
-class tst_QLinkedList : public QObject
-{
- Q_OBJECT
-private slots:
- void eraseValidIteratorsOnSharedList() const;
- void insertWithIteratorsOnSharedList() const;
- void lengthInt() const;
- void lengthMovable() const;
- void lengthComplex() const;
- void lengthSignature() const;
- void firstInt() const;
- void firstMovable() const;
- void firstComplex() const;
- void lastInt() const;
- void lastMovable() const;
- void lastComplex() const;
- void beginInt() const;
- void beginMovable() const;
- void beginComplex() const;
- void endInt() const;
- void endMovable() const;
- void endComplex() const;
- void containsInt() const;
- void containsMovable() const;
- void containsComplex() const;
- void countInt() const;
- void countMovable() const;
- void countComplex() const;
- void emptyInt() const;
- void emptyMovable() const;
- void emptyComplex() const;
- void endsWithInt() const;
- void endsWithMovable() const;
- void endsWithComplex() const;
- void removeAllInt() const;
- void removeAllMovable() const;
- void removeAllComplex() const;
- void removeOneInt() const;
- void removeOneMovable() const;
- void removeOneComplex() const;
- void reverseIterators() const;
- void startsWithInt() const;
- void startsWithMovable() const;
- void startsWithComplex() const;
- void takeFirstInt() const;
- void takeFirstMovable() const;
- void takeFirstComplex() const;
- void takeLastInt() const;
- void takeLastMovable() const;
- void takeLastComplex() const;
- void toStdListInt() const;
- void toStdListMovable() const;
- void toStdListComplex() const;
- void testOperatorsInt() const;
- void testOperatorsMovable() const;
- void testOperatorsComplex() const;
- void testSTLIteratorsInt() const;
- void testSTLIteratorsMovable() const;
- void testSTLIteratorsComplex() const;
-
- void initializeList() const;
-
- void constSharedNullInt() const;
- void constSharedNullMovable() const;
- void constSharedNullComplex() const;
-
- void setSharableInt() const;
-private:
- template<typename T> void length() const;
- template<typename T> void first() const;
- template<typename T> void last() const;
- template<typename T> void begin() const;
- template<typename T> void end() const;
- template<typename T> void contains() const;
- template<typename T> void count() const;
- template<typename T> void empty() const;
- template<typename T> void endsWith() const;
- template<typename T> void move() const;
- template<typename T> void removeAll() const;
- template<typename T> void removeOne() const;
- template<typename T> void startsWith() const;
- template<typename T> void swap() const;
- template<typename T> void takeFirst() const;
- template<typename T> void takeLast() const;
- template<typename T> void toStdList() const;
- template<typename T> void value() const;
-
- template<typename T> void testOperators() const;
- template<typename T> void testSTLIterators() const;
-
- template<typename T> void constSharedNull() const;
-
- int dummyForGuard;
-};
-
-template<typename T> struct SimpleValue
-{
- static T at(int index)
- {
- return values[index % maxSize];
- }
- static const uint maxSize = 7;
- static const T values[maxSize];
-};
-
-template<>
-const int SimpleValue<int>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
-template<>
-const Movable SimpleValue<Movable>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
-template<>
-const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
-
-// Make some macros for the tests to use in order to be slightly more readable...
-#define T_FOO SimpleValue<T>::at(0)
-#define T_BAR SimpleValue<T>::at(1)
-#define T_BAZ SimpleValue<T>::at(2)
-#define T_CAT SimpleValue<T>::at(3)
-#define T_DOG SimpleValue<T>::at(4)
-#define T_BLAH SimpleValue<T>::at(5)
-#define T_WEEE SimpleValue<T>::at(6)
-
-template<typename T>
-void tst_QLinkedList::length() const
-{
- /* Empty list. */
- {
- const QLinkedList<T> list;
- QCOMPARE(list.size(), 0);
- }
-
- /* One entry. */
- {
- QLinkedList<T> list;
- list.append(T_FOO);
- QCOMPARE(list.size(), 1);
- }
-
- /* Two entries. */
- {
- QLinkedList<T> list;
- list.append(T_FOO);
- list.append(T_BAR);
- QCOMPARE(list.size(), 2);
- }
-
- /* Three entries. */
- {
- QLinkedList<T> list;
- list.append(T_FOO);
- list.append(T_BAR);
- list.append(T_BAZ);
- QCOMPARE(list.size(), 3);
- }
-}
-
-void tst_QLinkedList::eraseValidIteratorsOnSharedList() const
-{
- QLinkedList<int> a, b;
- a.append(5);
- a.append(10);
- a.append(20);
- a.append(20);
- a.append(20);
- a.append(20);
- a.append(30);
-
- QLinkedList<int>::iterator i = a.begin();
- ++i;
- ++i;
- ++i;
- b = a;
- QLinkedList<int>::iterator r = a.erase(i);
- QCOMPARE(b.size(), 7);
- QCOMPARE(a.size(), 6);
- --r;
- --r;
- QCOMPARE(*r, 10); // Ensure that number 2 instance was removed;
-}
-
-void tst_QLinkedList::insertWithIteratorsOnSharedList() const
-{
- QLinkedList<int> a, b;
- a.append(5);
- a.append(10);
- a.append(20);
- QLinkedList<int>::iterator i = a.begin();
- ++i;
- ++i;
- b = a;
-
- QLinkedList<int>::iterator i2 = a.insert(i, 15);
- QCOMPARE(b.size(), 3);
- QCOMPARE(a.size(), 4);
- --i2;
- QCOMPARE(*i2, 10);
-}
-
-void tst_QLinkedList::lengthInt() const
-{
- length<int>();
-}
-
-void tst_QLinkedList::lengthMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- length<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::lengthComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- length<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-void tst_QLinkedList::lengthSignature() const
-{
- /* Constness. */
- {
- const QLinkedList<int> list;
- /* The function should be const. */
- list.size();
- }
-}
-
-template<typename T>
-void tst_QLinkedList::first() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR;
-
- QCOMPARE(list.first(), T_FOO);
-
- // remove an item, make sure it still works
- list.pop_front();
- QVERIFY(list.size() == 1);
- QCOMPARE(list.first(), T_BAR);
-}
-
-void tst_QLinkedList::firstInt() const
-{
- first<int>();
-}
-
-void tst_QLinkedList::firstMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- first<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::firstComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- first<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::last() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR;
-
- QCOMPARE(list.last(), T_BAR);
-
- // remove an item, make sure it still works
- list.pop_back();
- QVERIFY(list.size() == 1);
- QCOMPARE(list.last(), T_FOO);
-}
-
-void tst_QLinkedList::lastInt() const
-{
- last<int>();
-}
-
-void tst_QLinkedList::lastMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- last<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::lastComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- last<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::begin() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR;
-
- QCOMPARE(*list.begin(), T_FOO);
-
- // remove an item, make sure it still works
- list.pop_front();
- QVERIFY(list.size() == 1);
- QCOMPARE(*list.begin(), T_BAR);
-}
-
-void tst_QLinkedList::beginInt() const
-{
- begin<int>();
-}
-
-void tst_QLinkedList::beginMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- begin<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::beginComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- begin<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::end() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR;
-
- QCOMPARE(*--list.end(), T_BAR);
-
- // remove an item, make sure it still works
- list.pop_back();
- QVERIFY(list.size() == 1);
- QCOMPARE(*--list.end(), T_FOO);
-}
-
-void tst_QLinkedList::endInt() const
-{
- end<int>();
-}
-
-void tst_QLinkedList::endMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- end<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::endComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- end<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::contains() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- QVERIFY(list.contains(T_FOO));
- QVERIFY(list.contains(T_BLAH) != true);
-
- // add it and make sure it matches
- list.append(T_BLAH);
- QVERIFY(list.contains(T_BLAH));
-}
-
-void tst_QLinkedList::containsInt() const
-{
- contains<int>();
-}
-
-void tst_QLinkedList::containsMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- contains<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::containsComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- contains<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::count() const
-{
- QLinkedList<T> list;
-
- // starts empty
- QVERIFY(list.count() == 0);
-
- // goes up
- list.append(T_FOO);
- QVERIFY(list.count() == 1);
-
- // and up
- list.append(T_BAR);
- QVERIFY(list.count() == 2);
-
- // and down
- list.pop_back();
- QVERIFY(list.count() == 1);
-
- // and empty. :)
- list.pop_back();
- QVERIFY(list.count() == 0);
-}
-
-void tst_QLinkedList::countInt() const
-{
- count<int>();
-}
-
-void tst_QLinkedList::countMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- count<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::countComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- count<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::empty() const
-{
- QLinkedList<T> list;
-
- // make sure it starts empty
- QVERIFY(list.empty());
-
- // and doesn't stay empty
- list.append(T_FOO);
- QVERIFY(!list.empty());
-
- // and goes back to being empty
- list.pop_back();
- QVERIFY(list.empty());
-}
-
-void tst_QLinkedList::emptyInt() const
-{
- empty<int>();
-}
-
-void tst_QLinkedList::emptyMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- empty<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::emptyComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- empty<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::endsWith() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // test it returns correctly in both cases
- QVERIFY(list.endsWith(T_BAZ));
- QVERIFY(!list.endsWith(T_BAR));
-
- // remove an item and make sure the end item changes
- list.pop_back();
- QVERIFY(list.endsWith(T_BAR));
-}
-
-void tst_QLinkedList::endsWithInt() const
-{
- endsWith<int>();
-}
-
-void tst_QLinkedList::endsWithMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- endsWith<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::endsWithComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- endsWith<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::removeAll() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // remove one instance
- list.removeAll(T_BAR);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ);
-
- // many instances
- list << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ;
- list.removeAll(T_BAR);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ);
-
- // try remove something that doesn't exist
- list.removeAll(T_WEEE);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ);
-}
-
-void tst_QLinkedList::removeAllInt() const
-{
- removeAll<int>();
-}
-
-void tst_QLinkedList::removeAllMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- removeAll<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::removeAllComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- removeAll<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::removeOne() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // middle
- list.removeOne(T_BAR);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ);
-
- // start
- list.removeOne(T_FOO);
- QCOMPARE(list, QLinkedList<T>() << T_BAZ);
-
- // last
- list.removeOne(T_BAZ);
- QCOMPARE(list, QLinkedList<T>());
-
- // make sure it really only removes one :)
- list << T_FOO << T_FOO;
- list.removeOne(T_FOO);
- QCOMPARE(list, QLinkedList<T>() << T_FOO);
-
- // try remove something that doesn't exist
- list.removeOne(T_WEEE);
- QCOMPARE(list, QLinkedList<T>() << T_FOO);
-}
-
-void tst_QLinkedList::removeOneInt() const
-{
- removeOne<int>();
-}
-
-void tst_QLinkedList::removeOneMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- removeOne<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::removeOneComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- removeOne<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-void tst_QLinkedList::reverseIterators() const
-{
- QLinkedList<int> l;
- l << 1 << 2 << 3 << 4;
- QLinkedList<int> lr = l;
- std::reverse(lr.begin(), lr.end());
- const QLinkedList<int> &clr = lr;
- QVERIFY(std::equal(l.begin(), l.end(), lr.rbegin()));
- QVERIFY(std::equal(l.begin(), l.end(), lr.crbegin()));
- QVERIFY(std::equal(l.begin(), l.end(), clr.rbegin()));
- QVERIFY(std::equal(lr.rbegin(), lr.rend(), l.begin()));
- QVERIFY(std::equal(lr.crbegin(), lr.crend(), l.begin()));
- QVERIFY(std::equal(clr.rbegin(), clr.rend(), l.begin()));
-}
-
-template<typename T>
-void tst_QLinkedList::startsWith() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // make sure it starts ok
- QVERIFY(list.startsWith(T_FOO));
-
- // remove an item
- list.removeFirst();
- QVERIFY(list.startsWith(T_BAR));
-}
-
-void tst_QLinkedList::startsWithInt() const
-{
- startsWith<int>();
-}
-
-void tst_QLinkedList::startsWithMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- startsWith<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::startsWithComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- startsWith<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::takeFirst() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- QCOMPARE(list.takeFirst(), T_FOO);
- QVERIFY(list.size() == 2);
- QCOMPARE(list.takeFirst(), T_BAR);
- QVERIFY(list.size() == 1);
- QCOMPARE(list.takeFirst(), T_BAZ);
- QVERIFY(list.size() == 0);
-}
-
-void tst_QLinkedList::takeFirstInt() const
-{
- takeFirst<int>();
-}
-
-void tst_QLinkedList::takeFirstMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- takeFirst<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::takeFirstComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- takeFirst<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::takeLast() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- QCOMPARE(list.takeLast(), T_BAZ);
- QCOMPARE(list.takeLast(), T_BAR);
- QCOMPARE(list.takeLast(), T_FOO);
-}
-
-void tst_QLinkedList::takeLastInt() const
-{
- takeLast<int>();
-}
-
-void tst_QLinkedList::takeLastMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- takeLast<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::takeLastComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- takeLast<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::toStdList() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // yuck.
- std::list<T> slist;
- slist.push_back(T_FOO);
- slist.push_back(T_BAR);
- slist.push_back(T_BAZ);
-
- QCOMPARE(list.toStdList(), slist);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ);
-}
-
-void tst_QLinkedList::toStdListInt() const
-{
- toStdList<int>();
-}
-
-void tst_QLinkedList::toStdListMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- toStdList<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::toStdListComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- toStdList<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::testOperators() const
-{
- QLinkedList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- QLinkedList<T> listtwo;
- listtwo << T_FOO << T_BAR << T_BAZ;
-
- // test equal
- QVERIFY(list == listtwo);
-
- // not equal
- listtwo.append(T_CAT);
- QVERIFY(list != listtwo);
-
- // +=
- list += listtwo;
- QVERIFY(list.size() == 7);
- QVERIFY(listtwo.size() == 4);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ
- << T_FOO << T_BAR << T_BAZ << T_CAT);
-
- // =
- list = listtwo;
- QCOMPARE(list, listtwo);
- QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ << T_CAT);
-}
-
-void tst_QLinkedList::testOperatorsInt() const
-{
- testOperators<int>();
-}
-
-void tst_QLinkedList::testOperatorsMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- testOperators<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::testOperatorsComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- testOperators<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-template<typename T>
-void tst_QLinkedList::testSTLIterators() const
-{
- QLinkedList<T> list;
-
- // create a list
- list << T_FOO << T_BAR << T_BAZ;
- typename QLinkedList<T>::iterator it = list.begin();
- QCOMPARE(*it, T_FOO); it++;
- QCOMPARE(*it, T_BAR); it++;
- QCOMPARE(*it, T_BAZ); it++;
- QCOMPARE(it, list.end()); it--;
-
- // walk backwards
- QCOMPARE(*it, T_BAZ); it--;
- QCOMPARE(*it, T_BAR); it--;
- QCOMPARE(*it, T_FOO);
-
- // test erase
- it = list.erase(it);
- QVERIFY(list.size() == 2);
- QCOMPARE(*it, T_BAR);
-
- // test multiple erase
- it = list.erase(it, it + 2);
- QVERIFY(list.size() == 0);
- QCOMPARE(it, list.end());
-
- // insert again
- it = list.insert(it, T_FOO);
- QVERIFY(list.size() == 1);
- QCOMPARE(*it, T_FOO);
-
- // insert again
- it = list.insert(it, T_BAR);
- QVERIFY(list.size() == 2);
- QCOMPARE(*it++, T_BAR);
- QCOMPARE(*it, T_FOO);
-}
-
-void tst_QLinkedList::testSTLIteratorsInt() const
-{
- testSTLIterators<int>();
-}
-
-void tst_QLinkedList::testSTLIteratorsMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- testSTLIterators<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::testSTLIteratorsComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- testSTLIterators<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-void tst_QLinkedList::initializeList() const
-{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
- QLinkedList<int> v1 { 2, 3, 4 };
- QCOMPARE(v1, QLinkedList<int>() << 2 << 3 << 4);
- QCOMPARE(v1, (QLinkedList<int> { 2, 3, 4}));
-
- QLinkedList<QLinkedList<int>> v2{ v1, { 1 }, QLinkedList<int>(), { 2, 3, 4 } };
- QLinkedList<QLinkedList<int>> v3;
- v3 << v1 << (QLinkedList<int>() << 1) << QLinkedList<int>() << v1;
- QCOMPARE(v3, v2);
-#endif
-}
-
-
-template<typename T>
-void tst_QLinkedList::constSharedNull() const
-{
- QLinkedList<T> list2;
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QLinkedList<T> list1;
- list1.setSharable(false);
- QVERIFY(list1.isDetached());
-
- list2.setSharable(true);
-#endif
- QVERIFY(!list2.isDetached());
-}
-
-void tst_QLinkedList::constSharedNullInt() const
-{
- constSharedNull<int>();
-}
-
-void tst_QLinkedList::constSharedNullMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- constSharedNull<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
-
-void tst_QLinkedList::constSharedNullComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- constSharedNull<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
-
-
-void tst_QLinkedList::setSharableInt() const
-{
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QLinkedList<int> orglist;
- orglist << 0 << 1 << 2 << 3 << 4 << 5;
- int size = 6;
-
- QLinkedList<int> list;
- list = orglist;
-
- QVERIFY(!list.isDetached());
- list.setSharable(true);
-
- QCOMPARE(list.size(), size);
-
- {
- QLinkedList<int> copy(list);
- QVERIFY(!copy.isDetached());
- QVERIFY(copy.isSharedWith(list));
- }
-
- list.setSharable(false);
- QVERIFY(list.isDetached() || list.isSharedWith(QLinkedList<int>()));
-
- {
- QLinkedList<int> copy(list);
-
- QVERIFY(copy.isDetached() || copy.isSharedWith(QLinkedList<int>()));
- QCOMPARE(copy.size(), size);
- QCOMPARE(copy, list);
- }
-
- list.setSharable(true);
-
- {
- QLinkedList<int> copy(list);
-
- QVERIFY(!copy.isDetached());
- QVERIFY(copy.isSharedWith(list));
- }
-
- QLinkedList<int>::const_iterator it = list.constBegin();
- for (int i = 0; i < list.size(); ++i) {
- QCOMPARE(int(*it), i);
- ++it;
- }
-
- QCOMPARE(list.size(), size);
-#endif
-}
-
-QTEST_APPLESS_MAIN(tst_QLinkedList)
-#include "tst_qlinkedlist.moc"
diff --git a/tests/auto/corelib/tools/qlist/.gitignore b/tests/auto/corelib/tools/qlist/.gitignore
index df208b6e78..5520039486 100644
--- a/tests/auto/corelib/tools/qlist/.gitignore
+++ b/tests/auto/corelib/tools/qlist/.gitignore
@@ -1 +1 @@
-tst_qlist
+tst_qvector
diff --git a/tests/auto/corelib/tools/qlist/CMakeLists.txt b/tests/auto/corelib/tools/qlist/CMakeLists.txt
new file mode 100644
index 0000000000..fdcfcd7424
--- /dev/null
+++ b/tests/auto/corelib/tools/qlist/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qlist Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlist LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qlist
+ SOURCES
+ tst_qlist.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/tools/qlist/qlist.pro b/tests/auto/corelib/tools/qlist/qlist.pro
deleted file mode 100644
index 47f0140abb..0000000000
--- a/tests/auto/corelib/tools/qlist/qlist.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qlist
-QT = core testlib
-SOURCES = $$PWD/tst_qlist.cpp
diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp
index b3f8130d27..35d69e8433 100644
--- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp
+++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp
@@ -1,66 +1,64 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-#include <QList>
-
-template <typename T, class MemoryLayout>
-class is_qlist_array_memory_layout {
- struct No { char c; };
- struct Yes { No n[2]; };
- Q_STATIC_ASSERT(sizeof(No) != sizeof(Yes));
- static No check(...);
- static Yes check(MemoryLayout);
-public:
- enum { value = sizeof(check(typename QList<T>::MemoryLayout())) == sizeof(Yes) };
-};
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QAtomicInt>
+#include <QThread>
+#include <QSemaphore>
+#include <QAtomicScopedValueRollback>
+#include <qlist.h>
+
+
+#ifdef QT_COMPILER_HAS_LWG3346
+# if __has_include(<concepts>)
+# include <concepts>
+# if defined(__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L
+ static_assert(std::contiguous_iterator<QList<int>::iterator>);
+ static_assert(std::contiguous_iterator<QList<int>::const_iterator>);
+# endif
+# endif
+# if __has_include(<ranges>)
+# include <ranges>
+# if defined(__cpp_lib_ranges)
+ namespace rns = std::ranges;
+
+ static_assert(rns::contiguous_range<QList<int>>);
+ static_assert(rns::contiguous_range<const QList<int>>);
+# endif
+# endif
+#endif
struct Movable {
Movable(char input = 'j')
: i(input)
+ , that(this)
, state(Constructed)
{
- ++liveCount;
+ counter.fetchAndAddRelaxed(1);
}
Movable(const Movable &other)
: i(other.i)
+ , that(this)
+ , state(Constructed)
+ {
+ check(other.state, Constructed);
+ counter.fetchAndAddRelaxed(1);
+ }
+ Movable(Movable &&other)
+ : i(other.i)
+ , that(other.that)
, state(Constructed)
{
check(other.state, Constructed);
- ++liveCount;
+ counter.fetchAndAddRelaxed(1);
+ other.that = nullptr;
}
~Movable()
{
check(state, Constructed);
i = 0;
- --liveCount;
+ counter.fetchAndAddRelaxed(-1);
state = Destructed;
}
@@ -71,390 +69,449 @@ struct Movable {
return i == other.i;
}
- bool operator<(const Movable &other) const
+ Movable &operator=(const Movable &other)
{
check(state, Constructed);
check(other.state, Constructed);
- return i < other.i;
+ i = other.i;
+ that = this;
+ return *this;
}
-
- Movable &operator=(const Movable &other)
+ Movable &operator=(Movable &&other)
{
check(state, Constructed);
check(other.state, Constructed);
i = other.i;
+ that = other.that;
+ other.that = nullptr;
return *this;
}
+ bool wasConstructedAt(const Movable *other) const
+ {
+ return that == other;
+ }
char i;
-
- static int getLiveCount() { return liveCount; }
+ static QAtomicInt counter;
private:
- static int liveCount;
+ Movable *that; // used to check if an instance was moved
enum State { Constructed = 106, Destructed = 110 };
- uchar state;
+ State state;
- static void check(const uchar state1, const uchar state2)
+ static void check(const State state1, const State state2)
{
- QCOMPARE(state1, state2);
+ QCOMPARE(int(state1), int(state2));
}
};
-Q_STATIC_ASSERT(sizeof(Movable) < sizeof(void*));
-
-int Movable::liveCount = 0;
+inline size_t qHash(const Movable &key, size_t seed = 0) { return qHash(key.i, seed); }
+QAtomicInt Movable::counter = 0;
QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(Movable, Q_RELOCATABLE_TYPE);
QT_END_NAMESPACE
-
Q_DECLARE_METATYPE(Movable);
-int qHash(const Movable& movable)
-{
- return qHash(movable.i);
-}
-
-struct Optimal
-{
- Optimal(char input = 'j')
- : i(input),
- state(Constructed)
+struct Custom {
+ Custom(char input = 'j')
+ : i(input)
+ , that(this)
+ , state(Constructed)
{
- ++liveCount;
+ counter.fetchAndAddRelaxed(1);
}
- Optimal(const Optimal &other)
- : i(other.i),
- state(Constructed)
+ Custom(const Custom &other)
+ : that(this)
+ , state(Constructed)
{
- check(other.state, Constructed);
- ++liveCount;
+ check(&other);
+ counter.fetchAndAddRelaxed(1);
+ this->i = other.i;
}
-
- ~Optimal()
+ ~Custom()
{
- check(state, Constructed);
+ check(this);
i = 0;
- --liveCount;
+ counter.fetchAndAddRelaxed(-1);
state = Destructed;
+ QVERIFY(heapData.use_count() > 0); // otherwise it's double free
}
- bool operator ==(const Optimal &other) const
+ bool operator ==(const Custom &other) const
{
- check(state, Constructed);
- check(other.state, Constructed);
+ check(&other);
+ check(this);
return i == other.i;
}
- bool operator<(const Optimal &other) const
+ bool operator<(const Custom &other) const
{
- check(state, Constructed);
- check(other.state, Constructed);
+ check(&other);
+ check(this);
return i < other.i;
}
- Optimal &operator=(const Optimal &other)
+ Custom &operator=(const Custom &other)
{
- check(state, Constructed);
- check(other.state, Constructed);
+ check(&other);
+ check(this);
i = other.i;
return *this;
}
- char i;
+ static QAtomicInt counter;
- static int getLiveCount() { return liveCount; }
+ char i; // used to identify orgin of an instance
private:
- static int liveCount;
+ Custom *that; // used to check if an instance was moved
+ // shared_ptr triggers ASan/LSan and can track if double free happens, which
+ // is convenient to ensure there's no malfunctioning QList APIs
+ std::shared_ptr<int> heapData = std::shared_ptr<int>(new int(42));
enum State { Constructed = 106, Destructed = 110 };
- uchar state;
- char padding[sizeof(void*) - 2];
+ State state;
- static void check(const uchar state1, const uchar state2)
+ static void check(const Custom *c)
{
- QCOMPARE(state1, state2);
+ // check if c object has been moved
+ QCOMPARE(c, c->that);
+ QCOMPARE(int(c->state), int(Constructed));
}
};
+QAtomicInt Custom::counter = 0;
-Q_STATIC_ASSERT(sizeof(Optimal) == sizeof(void*));
+inline size_t qHash(const Custom &key, size_t seed = 0) { return qHash(key.i, seed); }
-int Optimal::liveCount = 0;
+Q_DECLARE_METATYPE(Custom);
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Optimal, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(Optimal);
-
-int qHash(const Optimal& key)
-{
- return qHash(key.i);
-}
+// tests depends on the fact that:
+static_assert(QTypeInfo<int>::isRelocatable);
+static_assert(!QTypeInfo<int>::isComplex);
+static_assert(QTypeInfo<Movable>::isRelocatable);
+static_assert(QTypeInfo<Movable>::isComplex);
+static_assert(!QTypeInfo<Custom>::isRelocatable);
+static_assert(QTypeInfo<Custom>::isComplex);
-struct Complex
+// leak checking utility:
+template<typename T>
+struct LeakChecker
{
- Complex(int val = 0)
- : value(val)
- , checkSum(this)
- {
- ++liveCount;
- }
-
- Complex(Complex const &other)
- : value(other.value)
- , checkSum(this)
- {
- ++liveCount;
- }
-
- Complex &operator=(Complex const &other)
- {
- check(); other.check();
-
- value = other.value;
- return *this;
- }
-
- ~Complex()
- {
- --liveCount;
- check();
- }
-
- operator int() const { return value; }
-
- bool operator==(Complex const &other) const
- {
- check(); other.check();
- return value == other.value;
- }
-
- bool operator<(Complex const &other) const
- {
- check(); other.check();
- return value < other.value;
- }
-
- void check() const
- {
- QVERIFY(this == checkSum);
- }
-
- static int getLiveCount() { return liveCount; }
-private:
- static int liveCount;
-
- int value;
- void *checkSum;
+ int instancesCount;
+ LeakChecker() : instancesCount(T::counter.loadAcquire()) { }
+ ~LeakChecker() { QCOMPARE(instancesCount, T::counter.loadAcquire()); }
};
-
-int Complex::liveCount = 0;
-
-Q_DECLARE_METATYPE(Complex);
-
-// Tests depend on the fact that:
-Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic);
-Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<Optimal>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Optimal>::isComplex);
-Q_STATIC_ASSERT(QTypeInfo<Complex>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex);
-// iow:
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<int, QListData::NotIndirectLayout> ::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<int, QListData::IndirectLayout> ::value));
-
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Optimal, QListData::InlineWithPaddingLayout> ::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Optimal, QListData::NotArrayCompatibleLayout>::value));
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Optimal, QListData::NotIndirectLayout> ::value));
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Optimal, QListData::ArrayCompatibleLayout> ::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Optimal, QListData::IndirectLayout> ::value));
-
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Movable, QListData::InlineWithPaddingLayout> ::value));
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Movable, QListData::NotArrayCompatibleLayout>::value));
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Movable, QListData::NotIndirectLayout> ::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Movable, QListData::ArrayCompatibleLayout> ::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Movable, QListData::IndirectLayout> ::value));
-
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Complex, QListData::InlineWithPaddingLayout> ::value));
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Complex, QListData::NotArrayCompatibleLayout>::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Complex, QListData::NotIndirectLayout> ::value));
-Q_STATIC_ASSERT((!is_qlist_array_memory_layout<Complex, QListData::ArrayCompatibleLayout> ::value));
-Q_STATIC_ASSERT(( is_qlist_array_memory_layout<Complex, QListData::IndirectLayout> ::value));
+template<> struct LeakChecker<int>{};
+template<> struct LeakChecker<QString>{};
+#define TST_QLIST_CHECK_LEAKS(Type) \
+ LeakChecker<Type> checker; \
+ Q_UNUSED(checker);
class tst_QList : public QObject
{
Q_OBJECT
private slots:
- void lengthOptimal() const;
- void lengthMovable() const;
- void lengthComplex() const;
- void lengthSignature() const;
- void appendOptimal() const;
- void appendMovable() const;
- void appendComplex() const;
- void prepend() const;
- void midOptimal() const;
- void midMovable() const;
- void midComplex() const;
- void atOptimal() const;
- void atMovable() const;
- void atComplex() const;
- void firstOptimal() const;
- void firstMovable() const;
- void firstComplex() const;
- void lastOptimal() const;
- void lastMovable() const;
- void lastComplex() const;
+ void constructors_empty() const;
+ void constructors_emptyReserveZero() const;
+ void constructors_emptyReserve() const;
+ void constructors_reserveAndInitialize() const;
+ void copyConstructorInt() const { copyConstructor<int>(); }
+ void copyConstructorMovable() const { copyConstructor<Movable>(); }
+ void copyConstructorCustom() const { copyConstructor<Custom>(); }
+ void assignmentInt() const { testAssignment<int>(); }
+ void assignmentMovable() const { testAssignment<Movable>(); }
+ void assignmentCustom() const { testAssignment<Custom>(); }
+ void assignFromInitializerListInt() const { assignFromInitializerList<int>(); }
+ void assignFromInitializerListMovable() const { assignFromInitializerList<Movable>(); }
+ void assignFromInitializerListCustom() const { assignFromInitializerList<Custom>(); }
+ void addInt() const { add<int>(); }
+ void addMovable() const { add<Movable>(); }
+ void addCustom() const { add<Custom>(); }
+ void appendInt() const { append<int>(); }
+ void appendMovable() const { append<Movable>(); }
+ void appendCustom() const { append<Custom>(); }
+ void appendRvalue() const;
+ void appendList() const;
+ void assignEmpty() const;
+ void assignInt() const { assign<int>(); }
+ void assignMovable() const { assign<Movable>(); }
+ void assignCustom() const { assign<Custom>(); }
+ void assignUsesPrependBuffer_int_data() { assignUsesPrependBuffer_data(); }
+ void assignUsesPrependBuffer_int() const { assignUsesPrependBuffer<int>(); }
+ void assignUsesPrependBuffer_Movable_data() { assignUsesPrependBuffer_data(); }
+ void assignUsesPrependBuffer_Movable() const { assignUsesPrependBuffer<Movable>(); }
+ void assignUsesPrependBuffer_Custom_data() { assignUsesPrependBuffer_data(); }
+ void assignUsesPrependBuffer_Custom() const { assignUsesPrependBuffer<Custom>(); }
+ void at() const;
+ void capacityInt() const { capacity<int>(); }
+ void capacityMovable() const { capacity<Movable>(); }
+ void capacityCustom() const { capacity<Custom>(); }
+ void clearInt() const { clear<int>(); }
+ void clearMovable() const { clear<Movable>(); }
+ void clearCustom() const { clear<Custom>(); }
+ void constData() const;
void constFirst() const;
void constLast() const;
- void beginOptimal() const;
- void beginMovable() const;
- void beginComplex() const;
- void endOptimal() const;
- void endMovable() const;
- void endComplex() const;
- void containsOptimal() const;
- void containsMovable() const;
- void containsComplex() const;
- void countOptimal() const;
- void countMovable() const;
- void countComplex() const;
- void emptyOptimal() const;
- void emptyMovable() const;
- void emptyComplex() const;
- void endsWithOptimal() const;
- void endsWithMovable() const;
- void endsWithComplex() const;
- void lastIndexOfOptimal() const;
- void lastIndexOfMovable() const;
- void lastIndexOfComplex() const;
- void moveOptimal() const;
- void moveMovable() const;
- void moveComplex() const;
- void removeAllOptimal() const;
- void removeAllMovable() const;
- void removeAllComplex() const;
- void removeAtOptimal() const;
- void removeAtMovable() const;
- void removeAtComplex() const;
- void removeOneOptimal() const;
- void removeOneMovable() const;
- void removeOneComplex() const;
- void replaceOptimal() const;
- void replaceMovable() const;
- void replaceComplex() const;
- void reverseIteratorsOptimal() const;
- void reverseIteratorsMovable() const;
- void reverseIteratorsComplex() const;
- void startsWithOptimal() const;
- void startsWithMovable() const;
- void startsWithComplex() const;
- void swapOptimal() const;
- void swapMovable() const;
- void swapComplex() const;
- void takeAtOptimal() const;
- void takeAtMovable() const;
- void takeAtComplex() const;
- void takeFirstOptimal() const;
- void takeFirstMovable() const;
- void takeFirstComplex() const;
- void takeLastOptimal() const;
- void takeLastMovable() const;
- void takeLastComplex() const;
- void toSetOptimal() const;
- void toSetMovable() const;
- void toSetComplex() const;
- void toStdListOptimal() const;
- void toStdListMovable() const;
- void toStdListComplex() const;
- void toVectorOptimal() const;
- void toVectorMovable() const;
- void toVectorComplex() const;
- void valueOptimal() const;
- void valueMovable() const;
- void valueComplex() const;
-
- void testOperatorsOptimal() const;
- void testOperatorsMovable() const;
- void testOperatorsComplex() const;
- void testSTLIteratorsOptimal() const;
- void testSTLIteratorsMovable() const;
- void testSTLIteratorsComplex() const;
-
- void initializeList() const;
-
- void constSharedNullOptimal() const;
- void constSharedNullMovable() const;
- void constSharedNullComplex() const;
- void setSharableInt_data() const;
- void setSharableInt() const;
- void setSharableComplex_data() const;
- void setSharableComplex() const;
- void eraseValidIteratorsOnSharedList() const;
- void insertWithValidIteratorsOnSharedList() const;
-
- void qhashOptimal() const { qhash<Optimal>(); }
+ void contains() const;
+ void countInt() const { count<int>(); }
+ void countMovable() const { count<Movable>(); }
+ void countCustom() const { count<Custom>(); }
+ void cpp17ctad() const;
+ void data() const;
+ void emptyInt() const { empty<int>(); }
+ void emptyMovable() const { empty<Movable>(); }
+ void emptyCustom() const { empty<Custom>(); }
+ void endsWith() const;
+ void eraseEmptyInt() const { eraseEmpty<int>(); }
+ void eraseEmptyMovable() const { eraseEmpty<Movable>(); }
+ void eraseEmptyCustom() const { eraseEmpty<Custom>(); }
+ void eraseEmptyReservedInt() const { eraseEmptyReserved<int>(); }
+ void eraseEmptyReservedMovable() const { eraseEmptyReserved<Movable>(); }
+ void eraseEmptyReservedCustom() const { eraseEmptyReserved<Custom>(); }
+ void eraseInt() const { erase<int>(false); }
+ void eraseIntShared() const { erase<int>(true); }
+ void eraseMovable() const { erase<Movable>(false); }
+ void eraseMovableShared() const { erase<Movable>(true); }
+ void eraseCustom() const { erase<Custom>(false); }
+ void eraseCustomShared() const { erase<Custom>(true); }
+ void eraseReservedInt() const { eraseReserved<int>(); }
+ void eraseReservedMovable() const { eraseReserved<Movable>(); }
+ void eraseReservedCustom() const { eraseReserved<Custom>(); }
+ void fillInt() const { fill<int>(); }
+ void fillMovable() const { fill<Movable>(); }
+ void fillCustom() const { fill<Custom>(); }
+ void fillDetachInt() const { fillDetach<int>(); }
+ void fillDetachMovable() const { fillDetach<Movable>(); }
+ void fillDetachCustom() const { fillDetach<Custom>(); }
+ void first() const;
+ void fromListInt() const { fromList<int>(); }
+ void fromListMovable() const { fromList<Movable>(); }
+ void fromListCustom() const { fromList<Custom>(); }
+ void indexOf() const;
+ void insertInt() const { insert<int>(); }
+ void insertMovable() const { insert<Movable>(); }
+ void insertCustom() const { insert<Custom>(); }
+ void insertZeroCount_data();
+ void insertZeroCount() const;
+ void isEmpty() const;
+ void last() const;
+ void lastIndexOf() const;
+ void mid() const;
+ void sliced() const;
+ void moveInt() const { move<int>(); }
+ void moveMovable() const { move<Movable>(); }
+ void moveCustom() const { move<Custom>(); }
+ void prependInt() const { prepend<int>(); }
+ void prependMovable() const { prepend<Movable>(); }
+ void prependCustom() const { prepend<Custom>(); }
+ void prependRvalue() const;
+ void qhashInt() const { qhash<int>(); }
void qhashMovable() const { qhash<Movable>(); }
- void qhashComplex() const { qhash<Complex>(); }
- void reserve() const;
+ void qhashCustom() const { qhash<Custom>(); }
+ void removeAllWithAlias() const;
+ void removeInt() const { remove<int>(); }
+ void removeMovable() const { remove<Movable>(); }
+ void removeCustom() const { remove<Custom>(); }
+ void removeFirstLast() const;
+ void resizePOD_data() const;
+ void resizePOD() const;
+ void resizeComplexMovable_data() const;
+ void resizeComplexMovable() const;
+ void resizeComplex_data() const;
+ void resizeComplex() const;
+ void resizeCtorAndDtor() const;
+ void resizeToZero() const;
+ void resizeToTheSameSize_data();
+ void resizeToTheSameSize() const;
+ void resizeForOverwrite() const;
+ void iterators() const;
+ void constIterators() const;
+ void reverseIterators() const;
+ void sizeInt() const { size<int>(); }
+ void sizeMovable() const { size<Movable>(); }
+ void sizeCustom() const { size<Custom>(); }
+ void startsWith() const;
+ void swapInt() const { swap<int>(); }
+ void swapMovable() const { swap<Movable>(); }
+ void swapCustom() const { swap<Custom>(); }
+ void toList() const;
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ void fromStdVector() const;
+ void toStdVector() const;
+#endif
+ void value() const;
+ void testOperators() const;
+ void reserve();
+ void reserveZero();
+ void initializeListInt() { initializeList<int>(); }
+ void initializeListMovable() { initializeList<Movable>(); }
+ void initializeListCustom() { initializeList<Custom>(); }
+ void const_shared_null();
+ void detachInt() const { detach<int>(); }
+ void detachMovable() const { detach<Movable>(); }
+ void detachCustom() const { detach<Custom>(); }
+ void detachThreadSafetyInt() const;
+ void detachThreadSafetyMovable() const;
+ void detachThreadSafetyCustom() const;
+ void insertMove() const;
+ void swapItemsAt() const;
+ void emplaceInt() { emplaceImpl<int>(); }
+ void emplaceCustom() { emplaceImpl<Custom>(); }
+ void emplaceMovable() { emplaceImpl<Movable>(); }
+ void emplaceConsistentWithStdVectorInt() { emplaceConsistentWithStdVectorImpl<int>(); }
+ void emplaceConsistentWithStdVectorCustom() { emplaceConsistentWithStdVectorImpl<Custom>(); }
+ void emplaceConsistentWithStdVectorMovable() { emplaceConsistentWithStdVectorImpl<Movable>(); }
+ void emplaceConsistentWithStdVectorQString() { emplaceConsistentWithStdVectorImpl<QString>(); }
+ void emplaceReturnsIterator();
+ void emplaceFront() const;
+ void emplaceFrontReturnsRef() const;
+ void emplaceBack();
+ void emplaceBackReturnsRef();
+ void emplaceWithElementFromTheSameContainer();
+ void emplaceWithElementFromTheSameContainer_data();
+ void replaceInt() const { replace<int>(); }
+ void replaceCustom() const { replace<Custom>(); }
+ void replaceMovable() const { replace<Movable>(); }
+ void fromReadOnlyData() const;
+ void reallocateCustomAlignedType_qtbug90359() const;
+ void reinsertToBeginInt_qtbug91360() const { reinsertToBegin<int>(); }
+ void reinsertToBeginMovable_qtbug91360() const { reinsertToBegin<Movable>(); }
+ void reinsertToBeginCustom_qtbug91360() const { reinsertToBegin<Custom>(); }
+ void reinsertToEndInt_qtbug91360() const { reinsertToEnd<int>(); }
+ void reinsertToEndMovable_qtbug91360() const { reinsertToEnd<Movable>(); }
+ void reinsertToEndCustom_qtbug91360() const { reinsertToEnd<Custom>(); }
+ void reinsertRangeToEndInt_qtbug91360() const { reinsertRangeToEnd<int>(); }
+ void reinsertRangeToEndMovable_qtbug91360() const { reinsertRangeToEnd<Movable>(); }
+ void reinsertRangeToEndCustom_qtbug91360() const { reinsertRangeToEnd<Custom>(); }
+ // QList reference stability tests:
+ void stability_reserveInt() const { stability_reserve<int>(); }
+ void stability_reserveMovable() const { stability_reserve<Movable>(); }
+ void stability_reserveCustom() const { stability_reserve<Custom>(); }
+ void stability_eraseInt() const { stability_erase<int>(); }
+ void stability_eraseMovable() const { stability_erase<Movable>(); }
+ void stability_eraseCustom() const { stability_erase<Custom>(); }
+ void stability_appendInt() const { stability_append<int>(); }
+ void stability_appendMovable() const { stability_append<Movable>(); }
+ void stability_appendCustom() const { stability_append<Custom>(); }
+ void stability_insertElementInt() const { stability_insertElement<int>(); }
+ void stability_insertElementMovable() const { stability_insertElement<Movable>(); }
+ void stability_insertElementCustom() const { stability_insertElement<Custom>(); }
+ void stability_emplaceInt() const { stability_emplace<int>(); }
+ void stability_emplaceMovable() const { stability_emplace<Movable>(); }
+ void stability_emplaceCustom() const { stability_emplace<Custom>(); }
+ void stability_resizeInt() const { stability_resize<int>(); }
+ void stability_resizeMovable() const { stability_resize<Movable>(); }
+ void stability_resizeCustom() const { stability_resize<Custom>(); }
+
private:
- template<typename T> void length() const;
+ template<typename T> void copyConstructor() const;
+ template<typename T> void testAssignment() const;
+ template<typename T> void add() const;
template<typename T> void append() const;
- template<typename T> void mid() const;
- template<typename T> void at() const;
- template<typename T> void first() const;
- template<typename T> void last() const;
- template<typename T> void begin() const;
- template<typename T> void end() const;
- template<typename T> void contains() const;
+ template<typename T> void assign() const;
+ void assignUsesPrependBuffer_data() const;
+ template<typename T> void assignUsesPrependBuffer() const;
+ template<typename T> void assignFromInitializerList() const;
+ template<typename T> void capacity() const;
+ template<typename T> void clear() const;
template<typename T> void count() const;
template<typename T> void empty() const;
- template<typename T> void endsWith() const;
- template<typename T> void lastIndexOf() const;
- template<typename T> void move() const;
+ template<typename T> void eraseEmpty() const;
+ template<typename T> void eraseEmptyReserved() const;
+ template<typename T> void erase(bool shared) const;
+ template<typename T> void eraseReserved() const;
+ template<typename T> void fill() const;
+ template<typename T> void fillDetach() const;
+ template<typename T> void fromList() const;
+ template<typename T> void insert() const;
template<typename T> void qhash() const;
- template<typename T> void removeAll() const;
- template<typename T> void removeAt() const;
- template<typename T> void removeOne() const;
- template<typename T> void replace() const;
- template<typename T> void reverseIterators() const;
- template<typename T> void startsWith() const;
+ template<typename T> void move() const;
+ template<typename T> void prepend() const;
+ template<typename T> void remove() const;
+ template<typename T> void size() const;
template<typename T> void swap() const;
- template<typename T> void takeAt() const;
- template<typename T> void takeFirst() const;
- template<typename T> void takeLast() const;
- template<typename T> void toSet() const;
- template<typename T> void toStdList() const;
- template<typename T> void toVector() const;
- template<typename T> void value() const;
-
- template<typename T> void testOperators() const;
- template<typename T> void testSTLIterators() const;
-
- template<typename T> void constSharedNull() const;
-
- int dummyForGuard;
+ template<typename T> void initializeList();
+ template<typename T> void detach() const;
+ template<typename T> void detachThreadSafety() const;
+ template<typename T> void emplaceImpl() const;
+ template<typename T> void emplaceConsistentWithStdVectorImpl() const;
+ template<typename T> void replace() const;
+ template<typename T, typename Reinsert>
+ void reinsert(Reinsert op) const;
+ template<typename T>
+ void reinsertToBegin() const
+ {
+ reinsert<T>([](QList<T> &list) {
+ list.prepend(list.back());
+ list.removeLast();
+ });
+ }
+ template<typename T>
+ void reinsertToEnd() const
+ {
+ reinsert<T>([](QList<T> &list) {
+ list.append(list.front());
+ list.removeFirst();
+ });
+ }
+ template<typename T>
+ void reinsertRangeToEnd() const
+ {
+ reinsert<T>([](QList<T> &list) {
+ list.append(list.begin(), list.begin() + 1);
+ list.removeFirst();
+ });
+ }
+ template<typename T>
+ void stability_reserve() const;
+ template<typename T>
+ void stability_erase() const;
+ template<typename T>
+ void stability_append() const;
+ template<typename T, typename Insert>
+ void stability_insert(Insert op) const;
+ template<typename T>
+ void stability_resize() const;
+
+ template<typename T>
+ void stability_insertElement() const
+ {
+ stability_insert<T>(
+ [](QList<T> &list, int pos, const T &value) { list.insert(pos, 1, value); });
+ }
+ template<typename T>
+ void stability_emplace() const
+ {
+ stability_insert<T>(
+ [](QList<T> &list, int pos, const T &value) { list.emplace(pos, value); });
+ }
};
+
template<typename T> struct SimpleValue
{
static T at(int index)
{
- return values[index % maxSize];
+ return Values[index % MaxIndex];
}
- static const uint maxSize = 7;
- static const T values[maxSize];
+
+ static QList<T> vector(int size)
+ {
+ QList<T> ret;
+ for (int i = 0; i < size; i++)
+ ret.append(at(i));
+ return ret;
+ }
+
+ static const uint MaxIndex = 6;
+ static const T Values[MaxIndex];
};
template<>
-const Optimal SimpleValue<Optimal>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
+const int SimpleValue<int>::Values[] = { 110, 105, 101, 114, 111, 98 };
template<>
-const Movable SimpleValue<Movable>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
+const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 };
template<>
-const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 };
+const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 };
// Make some macros for the tests to use in order to be slightly more readable...
#define T_FOO SimpleValue<T>::at(0)
@@ -463,720 +520,1564 @@ const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 }
#define T_CAT SimpleValue<T>::at(3)
#define T_DOG SimpleValue<T>::at(4)
#define T_BLAH SimpleValue<T>::at(5)
-#define T_WEEE SimpleValue<T>::at(6)
-template<typename T>
-void tst_QList::length() const
+// returns a pair of QList<T> and QList<T *>
+template<typename It>
+decltype(auto) qlistCopyAndReferenceFromRange(It first, It last)
{
- /* Empty list. */
- {
- const QList<T> list;
- QCOMPARE(list.length(), 0);
- }
+ using T = typename std::iterator_traits<It>::value_type;
+ QList<T> copy(first, last);
+ QList<T *> reference;
+ for (; first != last; ++first)
+ reference.append(std::addressof(*first));
+ return std::make_pair(copy, reference);
+}
- /* One entry. */
- {
- QList<T> list;
- list.append(T_FOO);
- QCOMPARE(list.length(), 1);
- }
+void tst_QList::constructors_empty() const
+{
+ QList<int> emptyInt;
+ QList<Movable> emptyMovable;
+ QList<Custom> emptyCustom;
+}
+
+void tst_QList::constructors_emptyReserveZero() const
+{
+ QList<int> emptyInt(0);
+ QList<Movable> emptyMovable(0);
+ QList<Custom> emptyCustom(0);
+}
+
+void tst_QList::constructors_emptyReserve() const
+{
+ // pre-reserve capacity
+ QList<int> myInt(5);
+ QVERIFY(myInt.capacity() == 5);
+ QList<Movable> myMovable(5);
+ QVERIFY(myMovable.capacity() == 5);
+ QList<Custom> myCustom(4);
+ QVERIFY(myCustom.capacity() == 4);
+}
+
+void tst_QList::constructors_reserveAndInitialize() const
+{
+ // default-initialise items
+
+ const QList<int> myInt(5, 42);
+ QVERIFY(myInt.capacity() == 5);
+ for (int meaningoflife : myInt)
+ QCOMPARE(meaningoflife, 42);
+
+ const QList<QString> myString(5, QString::fromLatin1("c++"));
+ QVERIFY(myString.capacity() == 5);
+ // make sure all items are initialised ok
+ for (const QString &meaningoflife : myString)
+ QCOMPARE(meaningoflife, QString::fromLatin1("c++"));
+
+ const QList<Custom> myCustom(5, Custom('n'));
+ QVERIFY(myCustom.capacity() == 5);
+ // make sure all items are initialised ok
+ for (Custom meaningoflife : myCustom)
+ QCOMPARE(meaningoflife.i, 'n');
+}
+
+template<typename T>
+void tst_QList::copyConstructor() const
+{
+ TST_QLIST_CHECK_LEAKS(T)
- /* Two entries. */
+ T value1(SimpleValue<T>::at(0));
+ T value2(SimpleValue<T>::at(1));
+ T value3(SimpleValue<T>::at(2));
+ T value4(SimpleValue<T>::at(3));
{
- QList<T> list;
- list.append(T_FOO);
- list.append(T_BAR);
- QCOMPARE(list.length(), 2);
+ QList<T> v1;
+ QList<T> v2(v1);
+ QCOMPARE(v1, v2);
}
-
- /* Three entries. */
{
- QList<T> list;
- list.append(T_FOO);
- list.append(T_BAR);
- list.append(T_BAZ);
- QCOMPARE(list.length(), 3);
+ QList<T> v1;
+ v1 << value1 << value2 << value3 << value4;
+ QList<T> v2(v1);
+ QCOMPARE(v1, v2);
}
}
-void tst_QList::lengthOptimal() const
+template<typename T>
+void tst_QList::testAssignment() const
{
- const int liveCount = Optimal::getLiveCount();
- length<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::lengthMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- length<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QList<T> v1(5);
+ QCOMPARE(v1.size(), 5);
+ QVERIFY(v1.isDetached());
+
+ QList<T> v2(7);
+ QCOMPARE(v2.size(), 7);
+ QVERIFY(v2.isDetached());
+
+ QVERIFY(!v1.isSharedWith(v2));
+
+ v1 = v2;
+
+ QVERIFY(!v1.isDetached());
+ QVERIFY(!v2.isDetached());
+ QVERIFY(v1.isSharedWith(v2));
+
+ const void *const data1 = v1.constData();
+ const void *const data2 = v2.constData();
+
+ QCOMPARE(data1, data2);
+
+ v1.clear();
+
+ QVERIFY(v2.isDetached());
+ QVERIFY(!v1.isSharedWith(v2));
+ QCOMPARE((void *)v2.constData(), data2);
}
-void tst_QList::lengthComplex() const
+template<typename T>
+void tst_QList::assignFromInitializerList() const
{
- const int liveCount = Complex::getLiveCount();
- length<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ T val1(SimpleValue<T>::at(1));
+ T val2(SimpleValue<T>::at(2));
+ T val3(SimpleValue<T>::at(3));
+
+ QList<T> v1 = {val1, val2, val3};
+ QCOMPARE(v1, QList<T>() << val1 << val2 << val3);
+ QCOMPARE(v1, (QList<T> {val1, val2, val3}));
+
+ v1 = {};
+ QCOMPARE(v1.size(), 0);
}
-void tst_QList::lengthSignature() const
+template<typename T>
+void tst_QList::add() const
{
- /* Constness. */
+ TST_QLIST_CHECK_LEAKS(T)
+
{
- const QList<int> list;
- /* The function should be const. */
- list.length();
+ QList<T> empty1;
+ QList<T> empty2;
+ QVERIFY((empty1 + empty2).isEmpty());
+ empty1 += empty2;
+ QVERIFY(empty1.isEmpty());
+ QVERIFY(empty2.isEmpty());
+ }
+ {
+ QList<T> v(12);
+ QList<T> empty;
+ QCOMPARE((v + empty), v);
+ v += empty;
+ QVERIFY(!v.isEmpty());
+ QCOMPARE(v.size(), 12);
+ QVERIFY(empty.isEmpty());
+ }
+ {
+ QList<T> v1(12);
+ QList<T> v2;
+ v2 += v1;
+ QVERIFY(!v1.isEmpty());
+ QCOMPARE(v1.size(), 12);
+ QVERIFY(!v2.isEmpty());
+ QCOMPARE(v2.size(), 12);
}
}
template<typename T>
void tst_QList::append() const
{
- /* test append(const QList<T> &) function */
- T one(T_FOO);
- T two(T_BAR);
- T three(T_BAZ);
- T four(T_CAT);
- QList<T> list1;
- QList<T> list2;
- QList<T> listTotal;
- list1.append(one);
- list1.append(two);
- list2.append(three);
- list2.append(four);
- list1.append(list2);
- listTotal.append(one);
- listTotal.append(two);
- listTotal.append(three);
- listTotal.append(four);
- QCOMPARE(list1, listTotal);
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::appendOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- append<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ {
+ QList<T> myvec;
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.size() == 1);
+ myvec.append(SimpleValue<T>::at(1));
+ QVERIFY(myvec.size() == 2);
+ myvec.append(SimpleValue<T>::at(2));
+ QVERIFY(myvec.size() == 3);
+
+ QCOMPARE(myvec, QList<T>() << SimpleValue<T>::at(0)
+ << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(2));
+ }
+ {
+ QList<T> v(2);
+ v.append(SimpleValue<T>::at(0));
+ QVERIFY(v.size() == 3);
+ QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
+ }
+ {
+ QList<T> v(2);
+ v.reserve(12);
+ v.append(SimpleValue<T>::at(0));
+ QVERIFY(v.size() == 3);
+ QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
+ }
+ {
+ QList<int> v;
+ v << 1 << 2 << 3;
+ QList<int> x;
+ x << 4 << 5 << 6;
+ v.append(x);
+
+ QList<int> combined;
+ combined << 1 << 2 << 3 << 4 << 5 << 6;
+
+ QCOMPARE(v, combined);
+ }
+ {
+ const QList<T> otherVec { SimpleValue<T>::at(0),
+ SimpleValue<T>::at(1),
+ SimpleValue<T>::at(2),
+ SimpleValue<T>::at(3) };
+ QList<T> myvec;
+ myvec.append(otherVec.cbegin(), otherVec.cbegin() + 3);
+ QCOMPARE(myvec.size(), 3);
+ QCOMPARE(myvec, QList<T>() << SimpleValue<T>::at(0)
+ << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(2));
+ }
+ {
+ QList<T> emptyVec;
+ QList<T> otherEmptyVec;
+
+ emptyVec.append(otherEmptyVec);
+
+ QVERIFY(emptyVec.isEmpty());
+ QVERIFY(!emptyVec.isDetached());
+ QVERIFY(!otherEmptyVec.isDetached());
+ }
+ {
+ QList<T> myvec { SimpleValue<T>::at(0), SimpleValue<T>::at(1) };
+ QList<T> emptyVec;
+
+ myvec.append(emptyVec);
+ QVERIFY(emptyVec.isEmpty());
+ QVERIFY(!emptyVec.isDetached());
+ QCOMPARE(myvec, QList<T>({ SimpleValue<T>::at(0), SimpleValue<T>::at(1) }));
+ }
}
-void tst_QList::appendMovable() const
+void tst_QList::assignEmpty() const
{
- const int liveCount = Movable::getLiveCount();
- append<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ // Test that the realloc branch in assign(it, it) doesn't crash.
+ using T = int;
+ QList<T> list;
+ QList<T> ref1 = list;
+ QVERIFY(list.d.needsDetach());
+ list.assign(list.begin(), list.begin());
+
+#if !defined Q_OS_QNX // QNX has problems with the empty istream_iterator
+ auto empty = std::istream_iterator<T>{};
+ list.squeeze();
+ QCOMPARE_EQ(list.capacity(), 0);
+ ref1 = list;
+ QVERIFY(list.d.needsDetach());
+ list.assign(empty, empty);
+#endif
}
-void tst_QList::appendComplex() const
+template <typename T>
+void tst_QList::assign() const
{
- const int liveCount = Complex::getLiveCount();
- append<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+ {
+ QList<T> myvec;
+ myvec.assign(2, T_FOO);
+ QVERIFY(myvec.isDetached());
+ QCOMPARE(myvec, QList<T>() << T_FOO << T_FOO);
+
+ QList<T> myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ myvec.assign(3, T_BAR);
+ QCOMPARE(myvec, QList<T>() << T_BAR << T_BAR << T_BAR);
+ QVERIFY(myvec.isDetached());
+ QVERIFY(myvecCopy.isDetached());
+ QVERIFY(!myvec.isSharedWith(myvecCopy));
+ QVERIFY(!myvecCopy.isSharedWith(myvec));
+ }
+ {
+ QList<T> myvec;
+ myvec.assign(4, T_FOO);
+ QVERIFY(myvec.isDetached());
+ QCOMPARE(myvec, QList<T>() << T_FOO << T_FOO << T_FOO << T_FOO);
+
+ QList<T> myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ myvecCopy.assign(myvec.begin(), myvec.begin() + 2);
+ QVERIFY(myvec.isDetached());
+ QVERIFY(myvecCopy.isDetached());
+ QVERIFY(!myvec.isSharedWith(myvecCopy));
+ QVERIFY(!myvecCopy.isSharedWith(myvec));
+ QCOMPARE(myvecCopy, QList<T>() << T_FOO << T_FOO);
+ }
}
-void tst_QList::prepend() const
+inline namespace Scenarios {
+Q_NAMESPACE
+enum ListState {
+ UnsharedList,
+ SharedList,
+};
+Q_ENUM_NS(ListState)
+enum RelationWithPrependBuffer {
+ FitsIntoFreeSpaceAtBegin,
+ FitsFreeSpaceAtBeginExactly,
+ ExceedsFreeSpaceAtBegin,
+ FitsFreeSpaceAtBeginPlusSizeExactly,
+ FullCapacity,
+};
+Q_ENUM_NS(RelationWithPrependBuffer)
+} // namespace Scenarios
+
+void tst_QList::assignUsesPrependBuffer_data() const
{
- QList<int *> list;
- int *t1 = new int(0);
- list.prepend(t1);
- QVERIFY(list.size() == 1);
- QVERIFY(list.at(0) == t1);
- int *t2 = new int(0);
- list.prepend(t2);
- QVERIFY(list.size() == 2);
- QVERIFY(list.at(0) == t2);
- QVERIFY(list.at(1) == t1);
- int *t3 = new int(0);
- list.prepend(t3);
- QVERIFY(list.size() == 3);
- QVERIFY(list.at(0) == t3);
- QVERIFY(list.at(1) == t2);
- QVERIFY(list.at(2) == t1);
- list.removeAll(t2);
- delete t2;
- QVERIFY(list.size() == 2);
- QVERIFY(list.at(0) == t3);
- QVERIFY(list.at(1) == t1);
- int *t4 = new int(0);
- list.prepend(t4);
- QVERIFY(list.size() == 3);
- QVERIFY(list.at(0) == t4);
- QVERIFY(list.at(1) == t3);
- QVERIFY(list.at(2) == t1);
- qDeleteAll(list);
- list.clear();
+ QTest::addColumn<ListState>("listState");
+ QTest::addColumn<RelationWithPrependBuffer>("relationWithPrependBuffer");
+
+ const auto sme = QMetaEnum::fromType<ListState>();
+ const auto rme = QMetaEnum::fromType<RelationWithPrependBuffer>();
+
+ for (int i = 0, s = sme.value(i); s != -1; s = sme.value(++i)) {
+ for (int j = 0, r = rme.value(j); r != -1; r = rme.value(++j)) {
+ QTest::addRow("%s-%s", sme.key(i), rme.key(j))
+ << ListState(s) << RelationWithPrependBuffer(r);
+ }
+ }
}
-template<typename T>
-void tst_QList::mid() const
+template <typename T>
+void tst_QList::assignUsesPrependBuffer() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ << T_CAT << T_DOG << T_BLAH << T_WEEE;
+ QFETCH(const ListState, listState);
+ QFETCH(const RelationWithPrependBuffer, relationWithPrependBuffer);
- QCOMPARE(list.mid(3, 3),
- QList<T>() << T_CAT << T_DOG << T_BLAH);
+ const auto capBegin = [](const QList<T> &l) {
+ return l.begin() - l.d.freeSpaceAtBegin();
+ };
+ const auto capEnd = [](const QList<T> &l) {
+ return l.end() + l.d.freeSpaceAtEnd();
+ };
- QList<T> list1;
- QCOMPARE(list1.mid(1, 1).length(), 0);
+ TST_QLIST_CHECK_LEAKS(T)
+ {
+ // Test the prepend optimization.
+ QList<T> withFreeSpaceAtBegin(16, T_FOO);
+ // try at most 100 times to create freeSpaceAtBegin():
+ for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i)
+ withFreeSpaceAtBegin.prepend(T_FOO);
+ QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1);
+
+ auto c = [&] {
+ switch (listState) {
+ case UnsharedList: return std::move(withFreeSpaceAtBegin);
+ case SharedList: return withFreeSpaceAtBegin;
+ }
+ Q_UNREACHABLE_RETURN(withFreeSpaceAtBegin);
+ }();
+
+ const auto n = [&] () -> qsizetype {
+ switch (relationWithPrependBuffer) {
+ case FitsIntoFreeSpaceAtBegin:
+ return qsizetype(1);
+ case FitsFreeSpaceAtBeginExactly:
+ return c.d.freeSpaceAtBegin();
+ case ExceedsFreeSpaceAtBegin:
+ return c.d.freeSpaceAtBegin() + 1;
+ case FitsFreeSpaceAtBeginPlusSizeExactly:
+ return c.d.freeSpaceAtBegin() + c.size();
+ case FullCapacity:
+ return c.capacity();
+ };
+ Q_UNREACHABLE_RETURN(0);
+ }();
+
+ const auto oldCapBegin = capBegin(c);
+ const auto oldCapEnd = capEnd(c);
+
+ const std::vector v(n, T_BAR);
+ c.assign(v.begin(), v.end());
+ QCOMPARE_EQ(c.d.freeSpaceAtBegin(), 0); // we used the prepend-buffer
+ if (listState != SharedList) {
+ // check that we didn't reallocate
+ QCOMPARE_EQ(capBegin(c), oldCapBegin);
+ QCOMPARE_EQ(capEnd(c), oldCapEnd);
+ }
+ }
}
-void tst_QList::midOptimal() const
+void tst_QList::appendRvalue() const
{
- const int liveCount = Optimal::getLiveCount();
- mid<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ QList<QString> v;
+ v.append("hello");
+ QString world = "world";
+ v.append(std::move(world));
+ QCOMPARE(v.front(), QString("hello"));
+ QCOMPARE(v.back(), QString("world"));
+
+ // check append rvalue to empty list
+ QList<QString> myvec;
+ QString test = "test";
+ myvec.append(std::move(test));
+ QCOMPARE(myvec.size(), 1);
+ QCOMPARE(myvec.front(), QString("test"));
}
-void tst_QList::midMovable() const
+struct ConstructionCounted
+{
+ ConstructionCounted(int i) : i(i) { }
+ ConstructionCounted(ConstructionCounted &&other) noexcept
+ : i(other.i), copies(other.copies), moves(other.moves + 1)
+ {
+ // set to some easily noticeable values
+ other.i = -64;
+ other.copies = -64;
+ other.moves = -64;
+ }
+ ConstructionCounted &operator=(ConstructionCounted &&other) noexcept
+ {
+ i = other.i;
+ copies = other.copies;
+ moves = other.moves + 1;
+ // set to some easily noticeable values
+ other.i = -64;
+ other.copies = -64;
+ other.moves = -64;
+ return *this;
+ }
+ ConstructionCounted(const ConstructionCounted &other) noexcept
+ : i(other.i), copies(other.copies + 1), moves(other.moves)
+ {
+ }
+ ConstructionCounted &operator=(const ConstructionCounted &other) noexcept
+ {
+ i = other.i;
+ copies = other.copies + 1;
+ moves = other.moves;
+ return *this;
+ }
+ ~ConstructionCounted() = default;
+
+ friend bool operator==(const ConstructionCounted &lhs, const ConstructionCounted &rhs)
+ {
+ return lhs.i == rhs.i;
+ }
+
+ QString toString() { return QString::number(i); }
+
+ int i;
+ int copies = 0;
+ int moves = 0;
+};
+QT_BEGIN_NAMESPACE
+namespace QTest {
+char *toString(const ConstructionCounted &cc)
{
- const int liveCount = Movable::getLiveCount();
- mid<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ char *str = new char[5];
+ qsnprintf(str, 4, "%d", cc.i);
+ return str;
}
+}
+QT_END_NAMESPACE
-void tst_QList::midComplex() const
+void tst_QList::appendList() const
{
- const int liveCount = Complex::getLiveCount();
- mid<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ // By const-ref
+ {
+ QList<int> v1 = { 1, 2, 3, 4 };
+ QList<int> v2 = { 5, 6, 7, 8 };
+ v1.append(v2);
+ QCOMPARE(v2.size(), 4);
+ QCOMPARE(v1.size(), 8);
+ QList<int> expected = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ QCOMPARE(v1, expected);
+
+ QList<int> doubleExpected = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
+ // append self to self
+ v1.append(v1);
+ QCOMPARE(v1.size(), 16);
+ QCOMPARE(v1, doubleExpected);
+ v1.resize(8);
+
+ // append to self, but was shared
+ QList v1_2(v1);
+ v1.append(v1);
+ QCOMPARE(v1_2.size(), 8);
+ QCOMPARE(v1_2, expected);
+ QCOMPARE(v1.size(), 16);
+ QCOMPARE(v1, doubleExpected);
+ v1.resize(8);
+
+ // append empty
+ QList<int> v3;
+ v1.append(v3);
+
+ // append to empty
+ QList<int> v4;
+ v4.append(v1);
+ QCOMPARE(v4, expected);
+
+ v1 = { 1, 2, 3, 4 };
+ // Using operators
+ // <<
+ QList<int> v5;
+ v5 << v1 << v2;
+ QCOMPARE(v5, expected);
+
+ // +=
+ QList<int> v6;
+ v6 += v1;
+ v6 += v2;
+ QCOMPARE(v6, expected);
+
+ // +
+ QCOMPARE(v1 + v2, expected);
+ }
+ // By move
+ {
+ QList<ConstructionCounted> v1 = { 1, 2, 3, 4 };
+ // Sanity check
+ QCOMPARE(v1.at(3).moves, 0);
+ QCOMPARE(v1.at(3).copies, 1); // because of initializer list
+
+ QList<ConstructionCounted> v2 = { 5, 6, 7, 8 };
+ v1.append(std::move(v2));
+ QCOMPARE(v1.size(), 8);
+ QList<ConstructionCounted> expected = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ QCOMPARE(v1, expected);
+ QCOMPARE(v1.at(0).copies, 1);
+ QCOMPARE(v1.at(0).moves, 1);
+
+ QCOMPARE(v1.at(4).copies, 1); // was v2.at(0)
+ QCOMPARE(v1.at(4).moves, 1);
+
+ // append move from empty
+ QList<ConstructionCounted> v3;
+ v1.append(std::move(v3));
+ QCOMPARE(v1.size(), 8);
+ QCOMPARE(v1, expected);
+
+ for (qsizetype i = 0; i < v1.size(); ++i) {
+ const auto &counter = v1.at(i);
+ QCOMPARE(counter.copies, 1);
+ QCOMPARE(counter.moves, 1);
+ }
+
+ // append move to empty
+ QList<ConstructionCounted> v4;
+ v4.reserve(64);
+ v4.append(std::move(v1));
+ QCOMPARE(v4.size(), 8);
+ QCOMPARE(v4, expected);
+
+ for (qsizetype i = 0; i < v4.size(); ++i) {
+ const auto &counter = v4.at(i);
+ QCOMPARE(counter.copies, 1);
+ QCOMPARE(counter.moves, 2);
+ }
+
+ QVERIFY(v4.capacity() >= 64);
+
+ v1.swap(v4); // swap back...
+
+ // append move from shared
+ QList<ConstructionCounted> v5 = { 1, 2, 3, 4 };
+ QList<ConstructionCounted> v5_2(v5);
+ v1.append(std::move(v5_2));
+ QCOMPARE(v1.size(), 12);
+ QList<ConstructionCounted> expectedTwelve = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4 };
+ QCOMPARE(v1, expectedTwelve);
+ QCOMPARE(v5.size(), 4);
+ QList<ConstructionCounted> expectedFour = { 1, 2, 3, 4 };
+ QCOMPARE(v5, expectedFour);
+
+ QCOMPARE(v5.at(0).copies, 1); // from constructing with std::initializer_list
+ QCOMPARE(v5.at(0).moves, 0);
+
+ // Using operators
+ // <<
+ QList<ConstructionCounted> v6;
+ v6.reserve(4);
+ v6 << (QList<ConstructionCounted>() << 1 << 2);
+ v6 << (QList<ConstructionCounted>() << 3 << 4);
+ QCOMPARE(v6, expectedFour);
+ QCOMPARE(v6.at(0).copies, 1);
+ QCOMPARE(v6.at(0).moves, 3);
+
+ // +=
+ QList<ConstructionCounted> v7;
+ v7 += (QList<ConstructionCounted>() << 1 << 2);
+ v7 += (QList<ConstructionCounted>() << 3 << 4);
+ QCOMPARE(v7, expectedFour);
+
+ // +
+ QList<ConstructionCounted> v8;
+ QCOMPARE(v8 + (QList<ConstructionCounted>() << 1 << 2 << 3 << 4), expectedFour);
+ v8 = { 1, 2 };
+ QCOMPARE(v8 + (QList<ConstructionCounted>() << 3 << 4), expectedFour);
+ }
}
-template<typename T>
void tst_QList::at() const
{
- // test at() and make sure it functions correctly with some simple list manipulation.
- QList<T> list;
+ QList<QString> myvec;
+ myvec << "foo" << "bar" << "baz";
- // create a list
- list << T_FOO << T_BAR << T_BAZ;
- QVERIFY(list.size() == 3);
- QCOMPARE(list.at(0), T_FOO);
- QCOMPARE(list.at(1), T_BAR);
- QCOMPARE(list.at(2), T_BAZ);
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec.at(0), QLatin1String("foo"));
+ QCOMPARE(myvec.at(1), QLatin1String("bar"));
+ QCOMPARE(myvec.at(2), QLatin1String("baz"));
// append an item
- list << T_CAT;
- QVERIFY(list.size() == 4);
- QCOMPARE(list.at(0), T_FOO);
- QCOMPARE(list.at(1), T_BAR);
- QCOMPARE(list.at(2), T_BAZ);
- QCOMPARE(list.at(3), T_CAT);
+ myvec << "hello";
+ QVERIFY(myvec.size() == 4);
+ QCOMPARE(myvec.at(0), QLatin1String("foo"));
+ QCOMPARE(myvec.at(1), QLatin1String("bar"));
+ QCOMPARE(myvec.at(2), QLatin1String("baz"));
+ QCOMPARE(myvec.at(3), QLatin1String("hello"));
// remove an item
- list.removeAt(1);
- QVERIFY(list.size() == 3);
- QCOMPARE(list.at(0), T_FOO);
- QCOMPARE(list.at(1), T_BAZ);
- QCOMPARE(list.at(2), T_CAT);
+ myvec.remove(1);
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec.at(0), QLatin1String("foo"));
+ QCOMPARE(myvec.at(1), QLatin1String("baz"));
+ QCOMPARE(myvec.at(2), QLatin1String("hello"));
}
-void tst_QList::atOptimal() const
+template<typename T>
+void tst_QList::capacity() const
{
- const int liveCount = Optimal::getLiveCount();
- at<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::atMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- at<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ QList<T> myvec;
-void tst_QList::atComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- at<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ // TODO: is this guaranteed? seems a safe assumption, but I suppose preallocation of a
+ // few items isn't an entirely unforseeable possibility.
+ QVERIFY(myvec.capacity() == 0);
+ QVERIFY(!myvec.isDetached());
+
+ // test it gets a size
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
+ QVERIFY(myvec.capacity() >= 3);
+
+ // make sure it grows ok
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
+ QVERIFY(myvec.capacity() >= 6);
+ // let's try squeeze a bit
+ myvec.remove(3);
+ myvec.remove(3);
+ myvec.remove(3);
+ myvec.squeeze();
+ QVERIFY(myvec.capacity() >= 3);
+
+ myvec.remove(0);
+ myvec.remove(0);
+ myvec.remove(0);
+ myvec.squeeze();
+ QVERIFY(myvec.capacity() == 0);
}
template<typename T>
-void tst_QList::first() const
+void tst_QList::clear() const
{
- QList<T> list;
- list << T_FOO << T_BAR;
+ TST_QLIST_CHECK_LEAKS(T)
- QCOMPARE(list.first(), T_FOO);
+ QList<T> myvec;
+ myvec.clear();
+ QVERIFY(!myvec.isDetached());
- // remove an item, make sure it still works
- list.pop_front();
- QVERIFY(list.size() == 1);
- QCOMPARE(list.first(), T_BAR);
-}
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
-void tst_QList::firstOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- first<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ const auto oldCapacity = myvec.capacity();
+ QCOMPARE(myvec.size(), 3);
+ myvec.clear();
+ QCOMPARE(myvec.size(), 0);
+ QCOMPARE(myvec.capacity(), oldCapacity);
}
-void tst_QList::firstMovable() const
+void tst_QList::constData() const
{
- const int liveCount = Movable::getLiveCount();
- first<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ int arr[] = { 42, 43, 44 };
+ QList<int> myvec;
+ QCOMPARE(myvec.constData(), nullptr);
+ QVERIFY(!myvec.isDetached());
-void tst_QList::firstComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- first<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ myvec << 42 << 43 << 44;
+
+ QCOMPARE(memcmp(myvec.constData(), reinterpret_cast<const int *>(&arr), sizeof(int) * 3), 0);
}
-void tst_QList::constFirst() const
+void tst_QList::contains() const
{
- // Based on tst_QVector::constFirst()
- QList<int> list;
- list << 69 << 42 << 3;
+ QList<QString> myvec;
- // test it starts ok
- QCOMPARE(list.constFirst(), 69);
- QVERIFY(list.isDetached());
+ QVERIFY(!myvec.contains(QLatin1String("test")));
+ QVERIFY(!myvec.isDetached());
- QList<int> listCopy = list;
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
-
- QCOMPARE(list.constFirst(), 69);
- QCOMPARE(listCopy.constFirst(), 69);
+ myvec << "aaa" << "bbb" << "ccc";
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ QVERIFY(myvec.contains(QLatin1String("aaa")));
+ QVERIFY(myvec.contains(QLatin1String("bbb")));
+ QVERIFY(myvec.contains(QLatin1String("ccc")));
+ QVERIFY(!myvec.contains(QLatin1String("I don't exist")));
- // test removal changes
- list.removeAt(0);
- QVERIFY(list.isDetached());
- QVERIFY(!list.isSharedWith(listCopy));
- QCOMPARE(list.constFirst(), 42);
- QCOMPARE(listCopy.constFirst(), 69);
+ // add it and make sure it does :)
+ myvec.append(QLatin1String("I don't exist"));
+ QVERIFY(myvec.contains(QLatin1String("I don't exist")));
+}
- listCopy = list;
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+template<typename T>
+void tst_QList::count() const
+{
+ TST_QLIST_CHECK_LEAKS(T)
- QCOMPARE(list.constFirst(), 42);
- QCOMPARE(listCopy.constFirst(), 42);
+ // total size
+ {
+ // zero size
+ QList<T> myvec;
+ QVERIFY(myvec.size() == 0);
+ QVERIFY(!myvec.isDetached());
+
+ // grow
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.size() == 1);
+ myvec.append(SimpleValue<T>::at(1));
+ QVERIFY(myvec.size() == 2);
+
+ // shrink
+ myvec.remove(0);
+ QVERIFY(myvec.size() == 1);
+ myvec.remove(0);
+ QVERIFY(myvec.size() == 0);
+ }
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ // count of items
+ {
+ QList<T> myvec;
+ QCOMPARE(myvec.count(SimpleValue<T>::at(0)), 0);
+ QVERIFY(!myvec.isDetached());
- // test prepend changes
- list.prepend(23);
- QVERIFY(list.isDetached());
- QVERIFY(!list.isSharedWith(listCopy));
- QCOMPARE(list.constFirst(), 23);
- QCOMPARE(listCopy.constFirst(), 42);
+ myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
- listCopy = list;
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ // initial tests
+ QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
+ QVERIFY(myvec.count(SimpleValue<T>::at(3)) == 0);
- QCOMPARE(list.constFirst(), 23);
- QCOMPARE(listCopy.constFirst(), 23);
+ // grow
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 2);
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ // shrink
+ myvec.remove(0);
+ QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
+ }
}
-void tst_QList::constLast() const
+void tst_QList::cpp17ctad() const
{
- // Based on tst_QVector::constLast()
- QList<int> list;
- list << 69 << 42 << 3;
+#define QVERIFY_IS_VECTOR_OF(obj, Type) \
+ QVERIFY2((std::is_same<decltype(obj), QList<Type>>::value), \
+ QMetaType::fromType<decltype(obj)::value_type>().name())
+#define CHECK(Type, One, Two, Three) \
+ do { \
+ const Type v[] = {One, Two, Three}; \
+ QList v1 = {One, Two, Three}; \
+ QVERIFY_IS_VECTOR_OF(v1, Type); \
+ QList v2(v1.begin(), v1.end()); \
+ QVERIFY_IS_VECTOR_OF(v2, Type); \
+ QList v3(std::begin(v), std::end(v)); \
+ QVERIFY_IS_VECTOR_OF(v3, Type); \
+ } while (false) \
+ /*end*/
+ CHECK(int, 1, 2, 3);
+ CHECK(double, 1.0, 2.0, 3.0);
+ CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
+#undef QVERIFY_IS_VECTOR_OF
+#undef CHECK
+}
- // test it starts ok
- QCOMPARE(list.constLast(), 3);
- QVERIFY(list.isDetached());
+void tst_QList::data() const
+{
+ QList<int> myvec;
+ QCOMPARE(myvec.data(), nullptr);
- QList<int> listCopy = list;
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ myvec << 42 << 43 << 44;
- QCOMPARE(list.constLast(), 3);
- QCOMPARE(listCopy.constLast(), 3);
+ // make sure it starts off ok
+ QCOMPARE(*(myvec.data() + 1), 43);
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ // alter it
+ *(myvec.data() + 1) = 69;
- // test removal changes
- list.removeLast();
- QVERIFY(list.isDetached());
- QVERIFY(!list.isSharedWith(listCopy));
- QCOMPARE(list.constLast(), 42);
- QCOMPARE(listCopy.constLast(), 3);
+ // check it altered
+ QCOMPARE(*(myvec.data() + 1), 69);
- listCopy = list;
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ int arr[] = { 42, 69, 44 };
+ QCOMPARE(memcmp(myvec.data(), reinterpret_cast<int *>(&arr), sizeof(int) * 3), 0);
- QCOMPARE(list.constLast(), 42);
- QCOMPARE(listCopy.constLast(), 42);
+ const QList<int> constVec = myvec;
+ QCOMPARE(memcmp(constVec.data(), reinterpret_cast<const int *>(&arr), sizeof(int) * 3), 0);
+ QVERIFY(!constVec.isDetached()); // const data() does not detach()
+}
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+template<typename T>
+void tst_QList::empty() const
+{
+ TST_QLIST_CHECK_LEAKS(T)
- // test prepend changes
- list.append(23);
- QVERIFY(list.isDetached());
- QVERIFY(!list.isSharedWith(listCopy));
- QCOMPARE(list.constLast(), 23);
- QCOMPARE(listCopy.constLast(), 42);
+ QList<T> myvec;
- listCopy = list;
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ // starts empty
+ QVERIFY(myvec.empty());
+ QVERIFY(!myvec.isDetached());
- QCOMPARE(list.constLast(), 23);
- QCOMPARE(listCopy.constLast(), 23);
+ // not empty
+ myvec.append(SimpleValue<T>::at(2));
+ QVERIFY(!myvec.empty());
- QVERIFY(!list.isDetached());
- QVERIFY(!listCopy.isDetached());
- QVERIFY(list.isSharedWith(listCopy));
- QVERIFY(listCopy.isSharedWith(list));
+ // empty again
+ myvec.remove(0);
+ QVERIFY(myvec.empty());
}
-template<typename T>
-void tst_QList::last() const
+void tst_QList::endsWith() const
{
- QList<T> list;
- list << T_FOO << T_BAR;
+ QList<int> myvec;
- QCOMPARE(list.last(), T_BAR);
+ // empty vector
+ QVERIFY(!myvec.endsWith(1));
- // remove an item, make sure it still works
- list.pop_back();
- QVERIFY(list.size() == 1);
- QCOMPARE(list.last(), T_FOO);
-}
+ // add the one, should work
+ myvec.append(1);
+ QVERIFY(myvec.endsWith(1));
-void tst_QList::lastOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- last<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ // add something else, fails now
+ myvec.append(3);
+ QVERIFY(!myvec.endsWith(1));
+
+ // remove it again :)
+ myvec.remove(1);
+ QVERIFY(myvec.endsWith(1));
}
-void tst_QList::lastMovable() const
+template<typename T>
+void tst_QList::eraseEmpty() const
{
- const int liveCount = Movable::getLiveCount();
- last<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> v;
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
}
-void tst_QList::lastComplex() const
+template<typename T>
+void tst_QList::eraseEmptyReserved() const
{
- const int liveCount = Complex::getLiveCount();
- last<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> v;
+ v.reserve(10);
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
}
template<typename T>
-void tst_QList::begin() const
+struct SharedVectorChecker
{
- QList<T> list;
- list << T_FOO << T_BAR;
+ SharedVectorChecker(const QList<T> &original, bool doCopyVector)
+ : originalSize(-1),
+ copy(0)
+ {
+ if (doCopyVector) {
+ originalSize = original.size();
+ copy = new QList<T>(original);
+ // this is unlikely to fail, but if the check in the destructor fails it's good to know that
+ // we were still alright here.
+ QCOMPARE(originalSize, copy->size());
+ }
+ }
- QCOMPARE(*list.begin(), T_FOO);
+ ~SharedVectorChecker()
+ {
+ if (copy)
+ QCOMPARE(copy->size(), originalSize);
+ delete copy;
+ }
- // remove an item, make sure it still works
- list.pop_front();
- QVERIFY(list.size() == 1);
- QCOMPARE(*list.begin(), T_BAR);
-}
+ int originalSize;
+ QList<T> *copy;
+};
-void tst_QList::beginOptimal() const
+template<typename T>
+void tst_QList::erase(bool shared) const
{
- const int liveCount = Optimal::getLiveCount();
- begin<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::beginMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- begin<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ // note: remove() is actually more efficient, and more dangerous, because it uses the
+ // non-detaching begin() / end() internally. you can also use constBegin() and constEnd() with
+ // erase(), but only using reinterpret_cast... because both iterator types are really just
+ // pointers. so we use a mix of erase() and remove() to cover more cases.
+ {
+ QList<T> v = SimpleValue<T>::vector(12);
+ SharedVectorChecker<T> svc(v, shared);
+ v.erase(v.begin());
+ QCOMPARE(v.size(), 11);
+ for (int i = 0; i < 11; i++)
+ QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
+ if (shared)
+ QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
+ }
+ {
+ QList<T> v = SimpleValue<T>::vector(12);
+ SharedVectorChecker<T> svc(v, shared);
+ v.remove(1);
+ QCOMPARE(v.size(), 11);
+ QCOMPARE(v.at(0), SimpleValue<T>::at(0));
+ for (int i = 1; i < 11; i++)
+ QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
+ v.erase(v.begin() + 1, v.end());
+ QCOMPARE(v.size(), 1);
+ QCOMPARE(v.at(0), SimpleValue<T>::at(0));
+ if (shared)
+ QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
+ }
+ {
+ QList<T> v = SimpleValue<T>::vector(12);
+ SharedVectorChecker<T> svc(v, shared);
+ v.erase(v.begin(), v.end() - 1);
+ QCOMPARE(v.size(), 1);
+ QCOMPARE(v.at(0), SimpleValue<T>::at(11));
+ if (shared)
+ QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
+ }
+ {
+ QList<T> v = SimpleValue<T>::vector(12);
+ SharedVectorChecker<T> svc(v, shared);
+ v.remove(5);
+ QCOMPARE(v.size(), 11);
+ for (int i = 0; i < 5; i++)
+ QCOMPARE(v.at(i), SimpleValue<T>::at(i));
+ for (int i = 5; i < 11; i++)
+ QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
+ v.erase(v.begin() + 1, v.end() - 1);
+ QCOMPARE(v.at(0), SimpleValue<T>::at(0));
+ QCOMPARE(v.at(1), SimpleValue<T>::at(11));
+ QCOMPARE(v.size(), 2);
+ if (shared)
+ QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
+ }
}
-void tst_QList::beginComplex() const
+template<typename T>
+void tst_QList::eraseReserved() const
{
- const int liveCount = Complex::getLiveCount();
- begin<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ {
+ QList<T> v(12);
+ v.reserve(16);
+ v.erase(v.begin());
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin(), v.end());
+ QCOMPARE(v.size(), 0);
+ }
+ {
+ QList<T> v(12);
+ v.reserve(16);
+ v.erase(v.begin() + 1);
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin() + 1, v.end());
+ QCOMPARE(v.size(), 1);
+ }
+ {
+ QList<T> v(12);
+ v.reserve(16);
+ v.erase(v.begin(), v.end() - 1);
+ QCOMPARE(v.size(), 1);
+ }
+ {
+ QList<T> v(12);
+ v.reserve(16);
+ v.erase(v.begin() + 5);
+ QCOMPARE(v.size(), 11);
+ v.erase(v.begin() + 1, v.end() - 1);
+ QCOMPARE(v.size(), 2);
+ }
}
template<typename T>
-void tst_QList::end() const
+void tst_QList::fill() const
{
- QList<T> list;
- list << T_FOO << T_BAR;
+ TST_QLIST_CHECK_LEAKS(T)
- QCOMPARE(*--list.end(), T_BAR);
+ QList<T> myvec;
- // remove an item, make sure it still works
- list.pop_back();
- QVERIFY(list.size() == 1);
- QCOMPARE(*--list.end(), T_FOO);
-}
+ // fill an empty list - it should resize
+ myvec.fill(SimpleValue<T>::at(1), 2);
+ QCOMPARE(myvec, QList<T>({ SimpleValue<T>::at(1), SimpleValue<T>::at(1) }));
-void tst_QList::endOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- end<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ // resize
+ myvec.resize(5);
+ myvec.fill(SimpleValue<T>::at(1));
+ QCOMPARE(myvec, QList<T>() << SimpleValue<T>::at(1) << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(1) << SimpleValue<T>::at(1)
+ << SimpleValue<T>::at(1));
-void tst_QList::endMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- end<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ // make sure it can resize itself too
+ myvec.fill(SimpleValue<T>::at(2), 10);
+ QCOMPARE(myvec, QList<T>() << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
+ << SimpleValue<T>::at(2) << SimpleValue<T>::at(2));
-void tst_QList::endComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- end<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ // make sure it can resize to smaller size as well
+ myvec.fill(SimpleValue<T>::at(3), 2);
+ QCOMPARE(myvec, QList<T>() << SimpleValue<T>::at(3) << SimpleValue<T>::at(3));
}
template<typename T>
-void tst_QList::contains() const
+void tst_QList::fillDetach() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ TST_QLIST_CHECK_LEAKS(T)
- QVERIFY(list.contains(T_FOO));
- QVERIFY(list.contains(T_BLAH) != true);
+ // detaches to the same size
+ {
+ QList<T> original = { SimpleValue<T>::at(1), SimpleValue<T>::at(1), SimpleValue<T>::at(1) };
+ QList<T> copy = original;
+ copy.fill(SimpleValue<T>::at(2));
+
+ QCOMPARE(original,
+ QList<T>({ SimpleValue<T>::at(1), SimpleValue<T>::at(1), SimpleValue<T>::at(1) }));
+ QCOMPARE(copy,
+ QList<T>({ SimpleValue<T>::at(2), SimpleValue<T>::at(2), SimpleValue<T>::at(2) }));
+ }
- // add it and make sure it matches
- list.append(T_BLAH);
- QVERIFY(list.contains(T_BLAH));
-}
+ // detaches and grows in size
+ {
+ QList<T> original = { SimpleValue<T>::at(1), SimpleValue<T>::at(1), SimpleValue<T>::at(1) };
+ QList<T> copy = original;
+ copy.fill(SimpleValue<T>::at(2), 5);
+
+ QCOMPARE(original,
+ QList<T>({ SimpleValue<T>::at(1), SimpleValue<T>::at(1), SimpleValue<T>::at(1) }));
+ QCOMPARE(copy,
+ QList<T>({ SimpleValue<T>::at(2), SimpleValue<T>::at(2), SimpleValue<T>::at(2),
+ SimpleValue<T>::at(2), SimpleValue<T>::at(2) }));
+ }
-void tst_QList::containsOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- contains<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ // detaches and shrinks in size
+ {
+ QList<T> original = { SimpleValue<T>::at(1), SimpleValue<T>::at(1), SimpleValue<T>::at(1) };
+ QList<T> copy = original;
+ copy.fill(SimpleValue<T>::at(2), 1);
-void tst_QList::containsMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- contains<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QCOMPARE(original,
+ QList<T>({ SimpleValue<T>::at(1), SimpleValue<T>::at(1), SimpleValue<T>::at(1) }));
+ QCOMPARE(copy, QList<T>({ SimpleValue<T>::at(2) }));
+ }
}
-void tst_QList::containsComplex() const
+void tst_QList::first() const
{
- const int liveCount = Complex::getLiveCount();
- contains<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<int> myvec;
+ myvec << 69 << 42 << 3;
+
+ // test it starts ok
+ QCOMPARE(myvec.first(), 69);
+ QCOMPARE(myvec.constFirst(), 69);
+
+ // test removal changes
+ myvec.remove(0);
+ QCOMPARE(myvec.first(), 42);
+ QCOMPARE(myvec.constFirst(), 42);
+
+ // test prepend changes
+ myvec.prepend(23);
+ QCOMPARE(myvec.first(), 23);
+ QCOMPARE(myvec.constFirst(), 23);
+
+
+ QCOMPARE(QList<int>().first(0), QList<int>());
+ QCOMPARE(myvec.first(0), QList<int>());
+ QCOMPARE(myvec.first(1), (QList<int>{23}));
+ QCOMPARE(myvec.first(2), (QList<int>{23, 42}));
+ QCOMPARE(myvec.first(3), myvec);
}
-template<typename T>
-void tst_QList::count() const
+void tst_QList::constFirst() const
{
- QList<T> list;
+ QList<int> myvec;
+ myvec << 69 << 42 << 3;
- // starts empty
- QVERIFY(list.count() == 0);
+ // test it starts ok
+ QCOMPARE(myvec.constFirst(), 69);
+ QVERIFY(myvec.isDetached());
- // goes up
- list.append(T_FOO);
- QVERIFY(list.count() == 1);
+ QList<int> myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
- // and up
- list.append(T_BAR);
- QVERIFY(list.count() == 2);
+ QCOMPARE(myvec.constFirst(), 69);
+ QCOMPARE(myvecCopy.constFirst(), 69);
- // and down
- list.pop_back();
- QVERIFY(list.count() == 1);
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
- // and empty. :)
- list.pop_back();
- QVERIFY(list.count() == 0);
-}
+ // test removal changes
+ myvec.remove(0);
+ QVERIFY(myvec.isDetached());
+ QVERIFY(!myvec.isSharedWith(myvecCopy));
+ QCOMPARE(myvec.constFirst(), 42);
+ QCOMPARE(myvecCopy.constFirst(), 69);
+
+ myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ QCOMPARE(myvec.constFirst(), 42);
+ QCOMPARE(myvecCopy.constFirst(), 42);
+
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
-void tst_QList::countOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- count<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ // test prepend changes
+ myvec.prepend(23);
+ QVERIFY(myvec.isDetached());
+ QVERIFY(!myvec.isSharedWith(myvecCopy));
+ QCOMPARE(myvec.constFirst(), 23);
+ QCOMPARE(myvecCopy.constFirst(), 42);
+
+ myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ QCOMPARE(myvec.constFirst(), 23);
+ QCOMPARE(myvecCopy.constFirst(), 23);
+
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
}
-void tst_QList::countMovable() const
+
+template<typename T>
+void tst_QList::fromList() const
{
- const int liveCount = Movable::getLiveCount();
- count<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> list;
+ list << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3);
+
+ QList<T> myvec;
+ myvec = QList<T>::fromList(list);
+
+ // test it worked ok
+ QCOMPARE(myvec, QList<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3));
+ QCOMPARE(list, QList<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3));
}
-void tst_QList::countComplex() const
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+void tst_QList::fromStdVector() const
{
- const int liveCount = Complex::getLiveCount();
- count<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ // stl = :(
+ std::vector<QString> svec;
+ svec.push_back(QLatin1String("aaa"));
+ svec.push_back(QLatin1String("bbb"));
+ svec.push_back(QLatin1String("ninjas"));
+ svec.push_back(QLatin1String("pirates"));
+ QList<QString> myvec = QList<QString>::fromStdVector(svec);
+
+ // test it converts ok
+ QCOMPARE(myvec, QList<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
}
+#endif
-template<typename T>
-void tst_QList::empty() const
+void tst_QList::indexOf() const
{
- QList<T> list;
+ QList<QString> myvec;
+
+ QCOMPARE(myvec.indexOf("A"), -1);
+ QCOMPARE(myvec.indexOf("A", 5), -1);
+ QVERIFY(!myvec.isDetached());
- // make sure it starts empty
- QVERIFY(list.empty());
+ myvec << "A" << "B" << "C" << "B" << "A";
- // and doesn't stay empty
- list.append(T_FOO);
- QVERIFY(!list.empty());
+ QVERIFY(myvec.indexOf("B") == 1);
+ QVERIFY(myvec.indexOf("B", 1) == 1);
+ QVERIFY(myvec.indexOf("B", 2) == 3);
+ QVERIFY(myvec.indexOf("X") == -1);
+ QVERIFY(myvec.indexOf("X", 2) == -1);
- // and goes back to being empty
- list.pop_back();
- QVERIFY(list.empty());
+ // add an X
+ myvec << "X";
+ QVERIFY(myvec.indexOf("X") == 5);
+ QVERIFY(myvec.indexOf("X", 5) == 5);
+ QVERIFY(myvec.indexOf("X", 6) == -1);
+
+ // remove first A
+ myvec.remove(0);
+ QVERIFY(myvec.indexOf("A") == 3);
+ QVERIFY(myvec.indexOf("A", 3) == 3);
+ QVERIFY(myvec.indexOf("A", 4) == -1);
}
-void tst_QList::emptyOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- empty<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+template <typename T>
+void tst_QList::insert() const
+{
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> myvec;
+ const T
+ tA = SimpleValue<T>::at(0),
+ tB = SimpleValue<T>::at(1),
+ tC = SimpleValue<T>::at(2),
+ tX = SimpleValue<T>::at(3),
+ tZ = SimpleValue<T>::at(4),
+ tT = SimpleValue<T>::at(5),
+ ti = SimpleValue<T>::at(6);
+ myvec << tA << tB << tC;
+ QList<T> myvec2 = myvec;
+
+ // first position
+ QCOMPARE(myvec.at(0), tA);
+ myvec.insert(0, tX);
+ QCOMPARE(myvec.at(0), tX);
+ QCOMPARE(myvec.at(1), tA);
+
+ QCOMPARE(myvec2.at(0), tA);
+ myvec2.insert(myvec2.begin(), tX);
+ QCOMPARE(myvec2.at(0), tX);
+ QCOMPARE(myvec2.at(1), tA);
+
+ // middle
+ myvec.insert(1, tZ);
+ QCOMPARE(myvec.at(0), tX);
+ QCOMPARE(myvec.at(1), tZ);
+ QCOMPARE(myvec.at(2), tA);
+
+ myvec2.insert(myvec2.begin() + 1, tZ);
+ QCOMPARE(myvec2.at(0), tX);
+ QCOMPARE(myvec2.at(1), tZ);
+ QCOMPARE(myvec2.at(2), tA);
+
+ // end
+ myvec.insert(5, tT);
+ QCOMPARE(myvec.at(5), tT);
+ QCOMPARE(myvec.at(4), tC);
+
+ myvec2.insert(myvec2.end(), tT);
+ QCOMPARE(myvec2.at(5), tT);
+ QCOMPARE(myvec2.at(4), tC);
+
+ // insert a lot of garbage in the middle
+ myvec.insert(2, 2, ti);
+ QCOMPARE(myvec, QList<T>() << tX << tZ << ti << ti
+ << tA << tB << tC << tT);
+
+ myvec2.insert(myvec2.begin() + 2, 2, ti);
+ QCOMPARE(myvec2, myvec);
+
+ // insert from references to the same container:
+ myvec.insert(0, 1, myvec[5]); // inserts tB
+ myvec2.insert(0, 1, myvec2[5]); // inserts tB
+ QCOMPARE(myvec, QList<T>() << tB << tX << tZ << ti << ti
+ << tA << tB << tC << tT);
+ QCOMPARE(myvec2, myvec);
+
+ myvec.insert(0, 1, const_cast<const QList<T>&>(myvec)[0]); // inserts tB
+ myvec2.insert(0, 1, const_cast<const QList<T>&>(myvec2)[0]); // inserts tB
+ QCOMPARE(myvec, QList<T>() << tB << tB << tX << tZ << ti << ti
+ << tA << tB << tC << tT);
+ QCOMPARE(myvec2, myvec);
+
+ // Different insert() into empty list overloads
+ {
+ QList<T> myvec;
+ auto it = myvec.insert(0, tA);
+ QCOMPARE(myvec.size(), 1);
+ QCOMPARE(myvec.front(), tA);
+ QCOMPARE(it, myvec.begin());
+ }
+ {
+ QList<T> myvec;
+ auto it = myvec.insert(0, 3, tX);
+ QCOMPARE(myvec.size(), 3);
+ QCOMPARE(myvec, QList<T>({ tX, tX, tX }));
+ QCOMPARE(it, myvec.begin());
+ }
+ {
+ QList<T> myvec;
+ auto it = myvec.insert(myvec.cbegin(), tA);
+ QCOMPARE(myvec.size(), 1);
+ QCOMPARE(myvec.front(), tA);
+ QCOMPARE(it, myvec.begin());
+ }
+ {
+ QList<T> myvec;
+ auto it = myvec.insert(myvec.cbegin(), 3, tX);
+ QCOMPARE(myvec.size(), 3);
+ QCOMPARE(myvec, QList<T>({ tX, tX, tX }));
+ QCOMPARE(it, myvec.begin());
+ }
+ {
+ QList<QString> myvec;
+ QString test = "test";
+ auto it = myvec.insert(0, std::move(test));
+ QCOMPARE(myvec.size(), 1);
+ QCOMPARE(myvec.front(), u"test");
+ QCOMPARE(it, myvec.begin());
+ }
+ {
+ QList<QString> myvec;
+ QString test = "test";
+ auto it = myvec.insert(myvec.cbegin(), std::move(test));
+ QCOMPARE(myvec.size(), 1);
+ QCOMPARE(myvec.front(), u"test");
+ QCOMPARE(it, myvec.begin());
+ }
}
-void tst_QList::emptyMovable() const
+void tst_QList::insertZeroCount_data()
{
- const int liveCount = Movable::getLiveCount();
- empty<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QTest::addColumn<int>("pos");
+ QTest::newRow("0") << 0;
+ QTest::newRow("1") << 1;
}
-void tst_QList::emptyComplex() const
+void tst_QList::insertZeroCount() const
{
- const int liveCount = Complex::getLiveCount();
- empty<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QFETCH(int, pos);
+ QList<int> x;
+ x << 0 << 0;
+ x.insert(pos, 0, 1);
+ QCOMPARE(x[pos], 0);
+ QList<int> y;
+ y = x;
+ y.insert(pos, 0, 2);
+ QCOMPARE(y[pos], 0);
}
-template<typename T>
-void tst_QList::endsWith() const
+void tst_QList::isEmpty() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ QList<QString> myvec;
- // test it returns correctly in both cases
- QVERIFY(list.endsWith(T_BAZ));
- QVERIFY(!list.endsWith(T_BAR));
+ // starts ok
+ QVERIFY(myvec.isEmpty());
+ QVERIFY(!myvec.isDetached());
- // remove an item and make sure the end item changes
- list.pop_back();
- QVERIFY(list.endsWith(T_BAR));
-}
+ // not empty now
+ myvec.append(QLatin1String("hello there"));
+ QVERIFY(!myvec.isEmpty());
-void tst_QList::endsWithOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- endsWith<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ // empty again
+ myvec.remove(0);
+ QVERIFY(myvec.isEmpty());
}
-void tst_QList::endsWithMovable() const
+void tst_QList::last() const
{
- const int liveCount = Movable::getLiveCount();
- endsWith<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QList<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // test starts ok
+ QCOMPARE(myvec.last(), QLatin1String("C"));
+ QCOMPARE(myvec.constLast(), QLatin1String("C"));
+
+ // test it changes ok
+ myvec.append(QLatin1String("X"));
+ QCOMPARE(myvec.last(), QLatin1String("X"));
+ QCOMPARE(myvec.constLast(), QLatin1String("X"));
+
+ // and remove again
+ myvec.remove(3);
+ QCOMPARE(myvec.last(), QLatin1String("C"));
+ QCOMPARE(myvec.constLast(), QLatin1String("C"));
+
+ QCOMPARE(QList<QString>().last(0), QList<QString>());
+ QCOMPARE(myvec.last(0), QList<QString>());
+ QCOMPARE(myvec.last(1), (QList<QString>{QLatin1String("C")}));
+ QCOMPARE(myvec.last(2), (QList<QString>{QLatin1String("B"), QLatin1String("C")}));
+ QCOMPARE(myvec.last(3), myvec);
}
-void tst_QList::endsWithComplex() const
+void tst_QList::constLast() const
{
- const int liveCount = Complex::getLiveCount();
- endsWith<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<int> myvec;
+ myvec << 69 << 42 << 3;
+
+ // test it starts ok
+ QCOMPARE(myvec.constLast(), 3);
+ QVERIFY(myvec.isDetached());
+
+ QList<int> myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ QCOMPARE(myvec.constLast(), 3);
+ QCOMPARE(myvecCopy.constLast(), 3);
+
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ // test removal changes
+ myvec.removeLast();
+ QVERIFY(myvec.isDetached());
+ QVERIFY(!myvec.isSharedWith(myvecCopy));
+ QCOMPARE(myvec.constLast(), 42);
+ QCOMPARE(myvecCopy.constLast(), 3);
+
+ myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ QCOMPARE(myvec.constLast(), 42);
+ QCOMPARE(myvecCopy.constLast(), 42);
+
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ // test prepend changes
+ myvec.append(23);
+ QVERIFY(myvec.isDetached());
+ QVERIFY(!myvec.isSharedWith(myvecCopy));
+ QCOMPARE(myvec.constLast(), 23);
+ QCOMPARE(myvecCopy.constLast(), 42);
+
+ myvecCopy = myvec;
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+
+ QCOMPARE(myvec.constLast(), 23);
+ QCOMPARE(myvecCopy.constLast(), 23);
+
+ QVERIFY(!myvec.isDetached());
+ QVERIFY(!myvecCopy.isDetached());
+ QVERIFY(myvec.isSharedWith(myvecCopy));
+ QVERIFY(myvecCopy.isSharedWith(myvec));
}
-template<typename T>
void tst_QList::lastIndexOf() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ QList<QString> myvec;
- // one instance of the target item
- QVERIFY(list.lastIndexOf(T_BAZ) == 2);
+ QCOMPARE(myvec.lastIndexOf("A"), -1);
+ QCOMPARE(myvec.lastIndexOf("A", 5), -1);
+ QVERIFY(!myvec.isDetached());
- // shouldn't find this
- QVERIFY(list.lastIndexOf(T_WEEE) == -1);
+ myvec << "A" << "B" << "C" << "B" << "A";
- // multiple instances
- list.append(T_BAZ);
- list.append(T_BAZ);
- QVERIFY(list.lastIndexOf(T_BAZ) == 4);
+ QVERIFY(myvec.lastIndexOf("B") == 3);
+ QVERIFY(myvec.lastIndexOf("B", 2) == 1);
+ QVERIFY(myvec.lastIndexOf("X") == -1);
+ QVERIFY(myvec.lastIndexOf("X", 2) == -1);
- // search from the middle to find the last one
- QVERIFY(list.lastIndexOf(T_BAZ, 3) == 3);
+ // add an X
+ myvec << "X";
+ QVERIFY(myvec.lastIndexOf("X") == 5);
+ QVERIFY(myvec.lastIndexOf("X", 5) == 5);
+ QVERIFY(myvec.lastIndexOf("X", 3) == -1);
- // try to find none
- QVERIFY(list.lastIndexOf(T_BAZ, 1) == -1);
+ // remove first A
+ myvec.remove(0);
+ QVERIFY(myvec.lastIndexOf("A") == 3);
+ QVERIFY(myvec.lastIndexOf("A", 3) == 3);
+ QVERIFY(myvec.lastIndexOf("A", 2) == -1);
}
-void tst_QList::lastIndexOfOptimal() const
+void tst_QList::mid() const
{
- const int liveCount = Optimal::getLiveCount();
- lastIndexOf<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ QList<QString> list;
+
+ QCOMPARE(list.mid(4, 2), QList<QString>());
+ QCOMPARE(list.mid(0, 3), QList<QString>());
+ QCOMPARE(list.mid(-2, 3), QList<QString>());
+ QVERIFY(!list.isDetached());
+
+ list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty";
+
+ QCOMPARE(list.mid(3, 3), QList<QString>() << "bak" << "buck" << "hello");
+ QCOMPARE(list.mid(6, 10), QList<QString>() << "kitty");
+ QCOMPARE(list.mid(-1, 20), list);
+ QCOMPARE(list.mid(4), QList<QString>() << "buck" << "hello" << "kitty");
}
-void tst_QList::lastIndexOfMovable() const
+void tst_QList::sliced() const
{
- const int liveCount = Movable::getLiveCount();
- lastIndexOf<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QList<QString> list;
+ list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty";
+
+ QCOMPARE(QList<QString>().sliced(0), QList<QString>());
+ QCOMPARE(QList<QString>().sliced(0, 0), QList<QString>());
+ QCOMPARE(list.sliced(3, 3), QList<QString>() << "bak" << "buck" << "hello");
+ QCOMPARE(list.sliced(3), QList<QString>() << "bak" << "buck" << "hello" << "kitty");
+ QCOMPARE(list.sliced(6, 1), QList<QString>() << "kitty");
+ QCOMPARE(list.sliced(6), QList<QString>() << "kitty");
+ QCOMPARE(list.sliced(0, list.size()), list);
+ QCOMPARE(list.sliced(0), list);
+ QCOMPARE(list.sliced(4), QList<QString>() << "buck" << "hello" << "kitty");
}
-void tst_QList::lastIndexOfComplex() const
+template <typename T>
+void tst_QList::qhash() const
{
- const int liveCount = Complex::getLiveCount();
- lastIndexOf<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> l1, l2;
+ QCOMPARE(qHash(l1), qHash(l2));
+ l1 << SimpleValue<T>::at(0);
+ l2 << SimpleValue<T>::at(0);
+ QCOMPARE(qHash(l1), qHash(l2));
}
-template<typename T>
+template <typename T>
void tst_QList::move() const
{
+ TST_QLIST_CHECK_LEAKS(T)
+
QList<T> list;
list << T_FOO << T_BAR << T_BAZ;
// move an item
- list.move(0, list.count() - 1);
+ list.move(0, list.size() - 1);
QCOMPARE(list, QList<T>() << T_BAR << T_BAZ << T_FOO);
// move it back
- list.move(list.count() - 1, 0);
+ list.move(list.size() - 1, 0);
QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ);
// move an item in the middle
@@ -1184,208 +2085,789 @@ void tst_QList::move() const
QCOMPARE(list, QList<T>() << T_BAR << T_FOO << T_BAZ);
}
-void tst_QList::moveOptimal() const
+template<typename T>
+void tst_QList::prepend() const
{
- const int liveCount = Optimal::getLiveCount();
- move<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::moveMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- move<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ QList<T> myvec;
-void tst_QList::moveComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- move<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
+ T val1 = SimpleValue<T>::at(0);
+ T val2 = SimpleValue<T>::at(1);
+ T val3 = SimpleValue<T>::at(2);
+ T val4 = SimpleValue<T>::at(3);
+ T val5 = SimpleValue<T>::at(4);
-template<typename T>
-void tst_QList::removeAll() const
-{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ // prepend to default-constructed empty list
+ myvec.prepend(val1);
+ QCOMPARE(myvec.size(), 1);
+ QCOMPARE(myvec.at(0), val1);
+ myvec.clear();
- // remove one instance
- list.removeAll(T_BAR);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAZ);
+ myvec << val1 << val2 << val3;
- // many instances
- list << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ;
- list.removeAll(T_BAR);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ);
+ // starts ok
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec.at(0), val1);
- // try remove something that doesn't exist
- list.removeAll(T_WEEE);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ);
-}
+ // add something
+ myvec.prepend(val4);
+ QCOMPARE(myvec.at(0), val4);
+ QCOMPARE(myvec.at(1), val1);
+ QVERIFY(myvec.size() == 4);
-void tst_QList::removeAllOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- removeAll<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ // something else
+ myvec.prepend(val5);
+ QCOMPARE(myvec.at(0), val5);
+ QCOMPARE(myvec.at(1), val4);
+ QCOMPARE(myvec.at(2), val1);
+ QVERIFY(myvec.size() == 5);
+
+ // clear and prepend to an empty vector
+ myvec.clear();
+ QVERIFY(myvec.size() == 0);
+ myvec.prepend(val5);
+ QVERIFY(myvec.size() == 1);
+ QCOMPARE(myvec.at(0), val5);
}
-void tst_QList::removeAllMovable() const
+void tst_QList::prependRvalue() const
{
- const int liveCount = Movable::getLiveCount();
- removeAll<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QList<QString> myvec;
+
+ QString hello = "hello";
+ QString world = "world";
+
+ myvec.prepend(std::move(world));
+ QCOMPARE(myvec.size(), 1);
+
+ myvec.prepend(std::move(hello));
+ QCOMPARE(myvec.size(), 2);
+ QCOMPARE(myvec, QList<QString>({ "hello", "world" }));
}
-void tst_QList::removeAllComplex() const
+void tst_QList::removeAllWithAlias() const
{
- const int liveCount = Complex::getLiveCount();
- removeAll<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<QString> strings;
+ strings << "One" << "Two" << "Three" << "One" /* must be distinct, but equal */;
+ QCOMPARE(strings.removeAll(strings.front()), 2); // will trigger asan/ubsan
}
template<typename T>
-void tst_QList::removeAt() const
-{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+void tst_QList::remove() const
+{
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> myvec;
+ T val1 = SimpleValue<T>::at(1);
+ T val2 = SimpleValue<T>::at(2);
+ T val3 = SimpleValue<T>::at(3);
+ T val4 = SimpleValue<T>::at(4);
+ T val5 = SimpleValue<T>::at(5);
+
+ // some operations on empty list
+ QVERIFY(!myvec.removeOne(val1));
+ QCOMPARE(myvec.removeAll(val2), 0);
+ auto count = myvec.removeIf([](const T&) { return true; });
+ QCOMPARE(count, 0);
+
+ myvec << val1 << val2 << val3 << val4;
+ myvec << val1 << val2 << val3 << val4;
+ myvec << val1 << val2 << val3 << val4;
+ // remove by index
+ myvec.remove(1);
+ QCOMPARE(myvec, QList<T>({ val1, val3, val4, val1, val2, val3, val4, val1, val2, val3, val4 }));
+ myvec.removeAt(6);
+ QCOMPARE(myvec, QList<T>({ val1, val3, val4, val1, val2, val3, val1, val2, val3, val4 }));
+
+ // removeOne()
+ QVERIFY(!myvec.removeOne(val5));
+ QVERIFY(myvec.removeOne(val2));
+ QCOMPARE(myvec, QList<T>({ val1, val3, val4, val1, val3, val1, val2, val3, val4 }));
+
+ QList<T> myvecCopy = myvec;
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+ // removeAll()
+ QCOMPARE(myvec.removeAll(val5), 0);
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+ QCOMPARE(myvec.removeAll(val1), 3);
+ QVERIFY(!myvecCopy.isSharedWith(myvec));
+ QCOMPARE(myvec, QList<T>({ val3, val4, val3, val2, val3, val4 }));
+ QCOMPARE(myvecCopy, QList<T>({ val1, val3, val4, val1, val3, val1, val2, val3, val4 }));
+ myvecCopy = myvec;
+ QVERIFY(myvecCopy.isSharedWith(myvec));
+ QCOMPARE(myvec.removeAll(val2), 1);
+ QVERIFY(!myvecCopy.isSharedWith(myvec));
+ QCOMPARE(myvec, QList<T>({ val3, val4, val3, val3, val4 }));
+ QCOMPARE(myvecCopy, QList<T>({ val3, val4, val3, val2, val3, val4 }));
+
+ // removeIf
+ count = myvec.removeIf([&val4](const T &val) { return val == val4; });
+ QCOMPARE(count, 2);
+ QCOMPARE(myvec, QList<T>({ val3, val3, val3 }));
+
+ // remove rest
+ myvec.remove(0, 3);
+ QCOMPARE(myvec, QList<T>());
+}
+
+struct RemoveLastTestClass
+{
+ RemoveLastTestClass() { other = 0; deleted = false; }
+ RemoveLastTestClass *other;
+ bool deleted;
+ ~RemoveLastTestClass()
+ {
+ deleted = true;
+ if (other)
+ other->other = 0;
+ }
+};
- // middle
- list.removeAt(1);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAZ);
+void tst_QList::removeFirstLast() const
+{
+ // pop_pack - pop_front
+ QList<int> t, t2;
+ t.append(1);
+ t.append(2);
+ t.append(3);
+ t.append(4);
+ t2 = t;
+ t.pop_front();
+ QCOMPARE(t.size(), 3);
+ QCOMPARE(t.at(0), 2);
+ t.pop_back();
+ QCOMPARE(t.size(), 2);
+ QCOMPARE(t.at(0), 2);
+ QCOMPARE(t.at(1), 3);
+
+ // takefirst - takeLast
+ int n1 = t2.takeLast();
+ QCOMPARE(t2.size(), 3);
+ QCOMPARE(n1, 4);
+ QCOMPARE(t2.at(0), 1);
+ QCOMPARE(t2.at(2), 3);
+ n1 = t2.takeFirst();
+ QCOMPARE(t2.size(), 2);
+ QCOMPARE(n1, 1);
+ QCOMPARE(t2.at(0), 2);
+ QCOMPARE(t2.at(1), 3);
+
+ // remove first
+ QList<int> x, y;
+ x.append(1);
+ x.append(2);
+ y = x;
+ x.removeFirst();
+ QCOMPARE(x.size(), 1);
+ QCOMPARE(y.size(), 2);
+ QCOMPARE(x.at(0), 2);
+
+ // remove Last
+ QList<RemoveLastTestClass> v;
+ v.resize(2);
+ v[0].other = &(v[1]);
+ v[1].other = &(v[0]);
+ // Check dtor - complex type
+ QVERIFY(v.at(0).other != 0);
+ v.removeLast();
+ QVERIFY(v.at(0).other == 0);
+ QCOMPARE(v.at(0).deleted, false);
+ // check iterator
+ int count = 0;
+ for (QList<RemoveLastTestClass>::const_iterator i = v.constBegin(); i != v.constEnd(); ++i) {
+ ++count;
+ QVERIFY(i->other == 0);
+ QCOMPARE(i->deleted, false);
+ }
+ // Check size
+ QCOMPARE(count, 1);
+ QCOMPARE(v.size(), 1);
+ v.removeLast();
+ QCOMPARE(v.size(), 0);
+ // Check if we do correct realloc
+ QList<int> v2, v3;
+ v2.append(1);
+ v2.append(2);
+ v3 = v2; // shared
+ v2.removeLast();
+ QCOMPARE(v2.size(), 1);
+ QCOMPARE(v3.size(), 2);
+ QCOMPARE(v2.at(0), 1);
+ QCOMPARE(v3.at(0), 1);
+ QCOMPARE(v3.at(1), 2);
+
+ // Remove last with shared
+ QList<int> z1, z2;
+ z1.append(9);
+ z2 = z1;
+ z1.removeLast();
+ QCOMPARE(z1.size(), 0);
+ QCOMPARE(z2.size(), 1);
+ QCOMPARE(z2.at(0), 9);
+}
+
+
+void tst_QList::resizePOD_data() const
+{
+ QTest::addColumn<QList<int> >("vector");
+ QTest::addColumn<int>("size");
+
+ QVERIFY(!QTypeInfo<int>::isComplex);
+ QVERIFY(QTypeInfo<int>::isRelocatable);
+
+ QList<int> null;
+ QList<int> empty(0, 5);
+ QList<int> emptyReserved;
+ QList<int> nonEmpty;
+ QList<int> nonEmptyReserved;
- // start
- list.removeAt(0);
- QCOMPARE(list, QList<T>() << T_BAZ);
+ emptyReserved.reserve(10);
+ nonEmptyReserved.reserve(15);
+ nonEmpty << 0 << 1 << 2 << 3 << 4;
+ nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6;
+ QVERIFY(emptyReserved.capacity() >= 10);
+ QVERIFY(nonEmptyReserved.capacity() >= 15);
- // final
- list.removeAt(0);
- QCOMPARE(list, QList<T>());
+ QTest::newRow("null") << null << 10;
+ QTest::newRow("null and 0 size") << null << 0;
+ QTest::newRow("empty") << empty << 10;
+ QTest::newRow("empty and 0 size") << empty << 0;
+ QTest::newRow("emptyReserved") << emptyReserved << 10;
+ QTest::newRow("nonEmpty") << nonEmpty << 10;
+ QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
}
-void tst_QList::removeAtOptimal() const
+void tst_QList::resizePOD() const
{
- const int liveCount = Optimal::getLiveCount();
- removeAt<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ QFETCH(QList<int>, vector);
+ QFETCH(int, size);
+
+ const int oldSize = vector.size();
+
+ vector.resize(size);
+ QCOMPARE(vector.size(), size);
+ QVERIFY(vector.capacity() >= size);
+ if (vector.isEmpty())
+ QVERIFY(!vector.isDetached());
+
+ for (int i = oldSize; i < size; ++i)
+ QVERIFY(vector[i] == 0); // check initialization
+
+ const int capacity = vector.capacity();
+
+ vector.clear();
+ QCOMPARE(vector.size(), 0);
+ QVERIFY(vector.capacity() <= capacity);
}
-void tst_QList::removeAtMovable() const
+void tst_QList::resizeComplexMovable_data() const
{
- const int liveCount = Movable::getLiveCount();
- removeAt<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QTest::addColumn<QList<Movable> >("vector");
+ QTest::addColumn<int>("size");
+
+ QVERIFY(QTypeInfo<Movable>::isComplex);
+ QVERIFY(QTypeInfo<Movable>::isRelocatable);
+
+ QList<Movable> null;
+ QList<Movable> empty(0, 'Q');
+ QList<Movable> emptyReserved;
+ QList<Movable> nonEmpty;
+ QList<Movable> nonEmptyReserved;
+
+ emptyReserved.reserve(10);
+ nonEmptyReserved.reserve(15);
+ nonEmpty << '0' << '1' << '2' << '3' << '4';
+ nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6';
+ QVERIFY(emptyReserved.capacity() >= 10);
+ QVERIFY(nonEmptyReserved.capacity() >= 15);
+
+ QTest::newRow("null") << null << 10;
+ QTest::newRow("null and 0 size") << null << 0;
+ QTest::newRow("empty") << empty << 10;
+ QTest::newRow("empty and 0 size") << empty << 0;
+ QTest::newRow("emptyReserved") << emptyReserved << 10;
+ QTest::newRow("nonEmpty") << nonEmpty << 10;
+ QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
}
-void tst_QList::removeAtComplex() const
+void tst_QList::resizeComplexMovable() const
{
- const int liveCount = Complex::getLiveCount();
- removeAt<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ const int items = Movable::counter.loadAcquire();
+ {
+ QFETCH(QList<Movable>, vector);
+ QFETCH(int, size);
+
+ const int oldSize = vector.size();
+
+ vector.resize(size);
+ QCOMPARE(vector.size(), size);
+ QVERIFY(vector.capacity() >= size);
+ if (vector.isEmpty())
+ QVERIFY(!vector.isDetached());
+ for (int i = oldSize; i < size; ++i)
+ QVERIFY(vector[i] == 'j'); // check initialization
+
+ const int capacity = vector.capacity();
+
+ vector.resize(0);
+ QCOMPARE(vector.size(), 0);
+ QVERIFY(vector.capacity() <= capacity);
+ }
+ QCOMPARE(items, Movable::counter.loadAcquire());
}
-template<typename T>
-void tst_QList::removeOne() const
+void tst_QList::resizeComplex_data() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // middle
- list.removeOne(T_BAR);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAZ);
+ QTest::addColumn<QList<Custom> >("vector");
+ QTest::addColumn<int>("size");
- // start
- list.removeOne(T_FOO);
- QCOMPARE(list, QList<T>() << T_BAZ);
+ QVERIFY(QTypeInfo<Custom>::isComplex);
+ QVERIFY(!QTypeInfo<Custom>::isRelocatable);
- // last
- list.removeOne(T_BAZ);
- QCOMPARE(list, QList<T>());
+ QList<Custom> null;
+ QList<Custom> empty(0, '0');
+ QList<Custom> emptyReserved;
+ QList<Custom> nonEmpty;
+ QList<Custom> nonEmptyReserved;
- // make sure it really only removes one :)
- list << T_FOO << T_FOO;
- list.removeOne(T_FOO);
- QCOMPARE(list, QList<T>() << T_FOO);
+ emptyReserved.reserve(10);
+ nonEmptyReserved.reserve(15);
+ nonEmpty << '0' << '1' << '2' << '3' << '4';
+ nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6';
+ QVERIFY(emptyReserved.capacity() >= 10);
+ QVERIFY(nonEmptyReserved.capacity() >= 15);
- // try remove something that doesn't exist
- list.removeOne(T_WEEE);
- QCOMPARE(list, QList<T>() << T_FOO);
+ QTest::newRow("null") << null << 10;
+ QTest::newRow("null and 0 size") << null << 0;
+ QTest::newRow("empty") << empty << 10;
+ QTest::newRow("empty and 0 size") << empty << 0;
+ QTest::newRow("emptyReserved") << emptyReserved << 10;
+ QTest::newRow("nonEmpty") << nonEmpty << 10;
+ QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
}
-void tst_QList::removeOneOptimal() const
+void tst_QList::resizeComplex() const
{
- const int liveCount = Optimal::getLiveCount();
- removeOne<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ const int items = Custom::counter.loadAcquire();
+ {
+ QFETCH(QList<Custom>, vector);
+ QFETCH(int, size);
+
+ int oldSize = vector.size();
+ vector.resize(size);
+ QCOMPARE(vector.size(), size);
+ QVERIFY(vector.capacity() >= size);
+ if (vector.isEmpty())
+ QVERIFY(!vector.isDetached());
+ for (int i = oldSize; i < size; ++i)
+ QVERIFY(vector[i].i == 'j'); // check default initialization
+
+ const int capacity = vector.capacity();
+
+ vector.resize(0);
+ QCOMPARE(vector.size(), 0);
+ QVERIFY(vector.isEmpty());
+ QVERIFY(vector.capacity() <= capacity);
+ }
+ QCOMPARE(Custom::counter.loadAcquire(), items);
}
-void tst_QList::removeOneMovable() const
+void tst_QList::resizeCtorAndDtor() const
{
- const int liveCount = Movable::getLiveCount();
- removeOne<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ const int items = Custom::counter.loadAcquire();
+ {
+ QList<Custom> null;
+ QList<Custom> empty(0, '0');
+ QList<Custom> emptyReserved;
+ QList<Custom> nonEmpty;
+ QList<Custom> nonEmptyReserved;
+
+ emptyReserved.reserve(10);
+ nonEmptyReserved.reserve(15);
+ nonEmpty << '0' << '1' << '2' << '3' << '4';
+ nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6';
+ QVERIFY(emptyReserved.capacity() >= 10);
+ QVERIFY(nonEmptyReserved.capacity() >= 15);
+
+ // start playing with vectors
+ null.resize(21);
+ nonEmpty.resize(2);
+ emptyReserved.resize(0);
+ nonEmpty.resize(0);
+ nonEmptyReserved.resize(2);
+ }
+ QCOMPARE(Custom::counter.loadAcquire(), items);
}
-void tst_QList::removeOneComplex() const
+void tst_QList::resizeToZero() const
{
- const int liveCount = Complex::getLiveCount();
- removeOne<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<int> x;
+ QList<int> y;
+ x << 1 << 2;
+ y = x;
+ y.resize(0);
+ QCOMPARE(y.size(), 0);
+ // grow back
+ y.resize(x.size());
+ QCOMPARE(y.size(), x.size());
+ // default initialized
+ QCOMPARE(y[0], 0);
+ QCOMPARE(y[1], 0);
}
-template<typename T>
-void tst_QList::replace() const
+void tst_QList::resizeToTheSameSize_data()
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // start
- list.replace(0, T_CAT);
- QCOMPARE(list, QList<T>() << T_CAT
- << T_BAR << T_BAZ);
-
- // middle
- list.replace(1, T_DOG);
- QCOMPARE(list, QList<T>() << T_CAT
- << T_DOG << T_BAZ);
-
- // end
- list.replace(2, T_BLAH);
- QCOMPARE(list, QList<T>() << T_CAT
- << T_DOG << T_BLAH);
+ QTest::addColumn<QList<int>>("x");
+ QTest::newRow("size 2") << QList({ 1, 2 });
+ QTest::newRow("size 0") << QList<int>();
}
-void tst_QList::replaceOptimal() const
+void tst_QList::resizeToTheSameSize() const
{
- const int liveCount = Optimal::getLiveCount();
- replace<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ QFETCH(QList<int>, x);
+ QList<int> y;
+ y = x;
+ y.resize(x.size());
+ QCOMPARE(y.size(), x.size());
}
-void tst_QList::replaceMovable() const
+void tst_QList::resizeForOverwrite() const
{
- const int liveCount = Movable::getLiveCount();
- replace<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ constexpr int BUILD_COUNT = 42;
+ {
+ // Smoke test
+ QList<int> l(BUILD_COUNT, Qt::Uninitialized);
+ l.resizeForOverwrite(l.size() + BUILD_COUNT);
+ }
+
+ {
+ const int beforeCounter = Movable::counter.loadRelaxed();
+ QList<Movable> l(BUILD_COUNT, Qt::Uninitialized);
+ const int after1Counter = Movable::counter.loadRelaxed();
+ QCOMPARE(after1Counter, beforeCounter + BUILD_COUNT);
+
+ l.resizeForOverwrite(l.size() + BUILD_COUNT);
+ const int after2Counter = Movable::counter.loadRelaxed();
+ QCOMPARE(after2Counter, after1Counter + BUILD_COUNT);
+ }
+
+ struct QtInitializationSupport {
+ bool wasInitialized;
+ QtInitializationSupport() : wasInitialized(true) {}
+ explicit QtInitializationSupport(Qt::Initialization) : wasInitialized(false) {}
+ };
+
+ {
+ QList<QtInitializationSupport> l(BUILD_COUNT);
+ for (const auto &elem : l)
+ QVERIFY(elem.wasInitialized);
+ l.resize(l.size() + BUILD_COUNT);
+ for (const auto &elem : l)
+ QVERIFY(elem.wasInitialized);
+ }
+
+ {
+ QList<QtInitializationSupport> l(BUILD_COUNT, Qt::Uninitialized);
+ for (const auto &elem : l)
+ QVERIFY(!elem.wasInitialized);
+ l.resizeForOverwrite(l.size() + BUILD_COUNT);
+ for (const auto &elem : l)
+ QVERIFY(!elem.wasInitialized);
+ }
}
-void tst_QList::replaceComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- replace<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+void tst_QList::iterators() const
+{
+ QList<int> v;
+
+ QCOMPARE(v.begin(), v.end());
+ QCOMPARE(v.rbegin(), v.rend());
+
+ qsizetype idx = 0;
+ for (; idx < 10; ++idx)
+ v.push_back(idx);
+
+ // stl-style iterators
+ idx = 0;
+ auto it = v.begin();
+ QCOMPARE(*it, idx);
+ // idx == 0
+
+ std::advance(it, 7);
+ idx += 7;
+ QCOMPARE(*it, idx);
+ // idx == 7
+
+ it++;
+ idx++;
+ QCOMPARE(*it, idx);
+ // idx == 8
+
+ ++it;
+ ++idx;
+ QCOMPARE(*it, idx);
+ // idx == 9
+
+ std::advance(it, -3);
+ idx -= 3;
+ QCOMPARE(*it, idx);
+ // idx == 6
+
+ it--;
+ idx--;
+ QCOMPARE(*it, idx);
+ // idx == 5
+
+ --it;
+ --idx;
+ QCOMPARE(*it, idx);
+ // idx == 4
+
+ it = it + 1;
+ idx = idx + 1;
+ QCOMPARE(*it, idx);
+ // idx == 5
+
+ it = it + ptrdiff_t(1);
+ idx = idx + 1;
+ QCOMPARE(*it, idx);
+ // idx == 6
+
+ it = it + qsizetype(1);
+ idx = idx + 1;
+ QCOMPARE(*it, idx);
+ // idx == 7
+
+ it = it - qsizetype(1);
+ idx = idx - 1;
+ QCOMPARE(*it, idx);
+ // idx == 6
+
+ it = it - ptrdiff_t(1);
+ idx = idx - 1;
+ QCOMPARE(*it, idx);
+ // idx == 5
+
+ it = it - 1;
+ idx = idx - 1;
+ QCOMPARE(*it, idx);
+ // idx == 4
+
+ it -= 1;
+ idx -= 1;
+ QCOMPARE(*it, idx);
+ // idx == 3
+
+ it -= qsizetype(1);
+ idx -= 1;
+ QCOMPARE(*it, idx);
+ // idx == 2
+
+ it -= ptrdiff_t(1);
+ idx -= 1;
+ QCOMPARE(*it, idx);
+ // idx == 1
+
+ it += ptrdiff_t(1);
+ idx += 1;
+ QCOMPARE(*it, idx);
+ // idx == 2
+
+ it += qsizetype(1);
+ idx += 1;
+ QCOMPARE(*it, idx);
+ // idx == 3
+
+ it += 1;
+ idx += 1;
+ QCOMPARE(*it, idx);
+ // idx == 4
+
+ *it = idx + 1;
+ QCOMPARE(*it, idx + 1);
+ *it = idx;
+
+ // stl-style reverse iterators
+ idx = v.size() - 1;
+ auto rit = v.rbegin();
+ QCOMPARE(*rit, idx);
+
+ *rit = idx + 1;
+ QCOMPARE(*rit, idx + 1);
+ *rit = idx;
+
+ std::advance(rit, 5);
+ idx -= 5;
+ QCOMPARE(*rit, idx);
+
+ ++rit;
+ --idx;
+ QCOMPARE(*rit, idx);
+
+ rit++;
+ idx--;
+ QCOMPARE(*rit, idx);
+
+ std::advance(rit, -4);
+ idx += 4;
+ QCOMPARE(*rit, idx);
+
+ --rit;
+ ++idx;
+ QCOMPARE(*rit, idx);
+
+ rit--;
+ idx++;
+ QCOMPARE(*rit, idx);
+}
+
+void tst_QList::constIterators() const
+{
+ const QList<int> constEmptyList;
+ QCOMPARE(constEmptyList.cbegin(), constEmptyList.cend());
+ QCOMPARE(constEmptyList.begin(), constEmptyList.cbegin());
+ QCOMPARE(constEmptyList.end(), constEmptyList.cend());
+ QCOMPARE(constEmptyList.constBegin(), constEmptyList.constEnd());
+ QCOMPARE(constEmptyList.constBegin(), constEmptyList.cbegin());
+ QCOMPARE(constEmptyList.constEnd(), constEmptyList.cend());
+ QVERIFY(!constEmptyList.isDetached());
+
+ const QList<int> v { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+ // stl-style iterators
+ qsizetype idx = 0;
+ auto it = v.cbegin();
+ QCOMPARE(*it, idx);
+ // idx == 0
+
+ std::advance(it, 7);
+ idx += 7;
+ QCOMPARE(*it, idx);
+ // idx == 7
+
+ it++;
+ idx++;
+ QCOMPARE(*it, idx);
+ // idx == 8
+
+ ++it;
+ ++idx;
+ QCOMPARE(*it, idx);
+ // idx == 9
+
+ std::advance(it, -3);
+ idx -= 3;
+ QCOMPARE(*it, idx);
+ // idx == 6
+
+ it--;
+ idx--;
+ QCOMPARE(*it, idx);
+ // idx == 5
+
+ --it;
+ --idx;
+ QCOMPARE(*it, idx);
+ // idx == 4
+
+ it = it + 1;
+ idx = idx + 1;
+ QCOMPARE(*it, idx);
+ // idx == 5
+
+ it = it + ptrdiff_t(1);
+ idx = idx + 1;
+ QCOMPARE(*it, idx);
+ // idx == 6
+
+ it = it + qsizetype(1);
+ idx = idx + 1;
+ QCOMPARE(*it, idx);
+ // idx == 7
+
+ it = it - qsizetype(1);
+ idx = idx - 1;
+ QCOMPARE(*it, idx);
+ // idx == 6
+
+ it = it - ptrdiff_t(1);
+ idx = idx - 1;
+ QCOMPARE(*it, idx);
+ // idx == 5
+
+ it = it - 1;
+ idx = idx - 1;
+ QCOMPARE(*it, idx);
+ // idx == 4
+
+ it -= 1;
+ idx -= 1;
+ QCOMPARE(*it, idx);
+ // idx == 3
+
+ it -= qsizetype(1);
+ idx -= 1;
+ QCOMPARE(*it, idx);
+ // idx == 2
+
+ it -= ptrdiff_t(1);
+ idx -= 1;
+ QCOMPARE(*it, idx);
+ // idx == 1
+
+ it += ptrdiff_t(1);
+ idx += 1;
+ QCOMPARE(*it, idx);
+ // idx == 2
+
+ it += qsizetype(1);
+ idx += 1;
+ QCOMPARE(*it, idx);
+ // idx == 3
+
+ it += 1;
+ idx += 1;
+ QCOMPARE(*it, idx);
+ // idx == 4
+
+ // stl-style reverse iterators
+ idx = v.size() - 1;
+ auto rit = v.crbegin();
+ QCOMPARE(*rit, idx);
+
+ std::advance(rit, 5);
+ idx -= 5;
+ QCOMPARE(*rit, idx);
+
+ ++rit;
+ --idx;
+ QCOMPARE(*rit, idx);
+
+ rit++;
+ idx--;
+ QCOMPARE(*rit, idx);
+
+ std::advance(rit, -4);
+ idx += 4;
+ QCOMPARE(*rit, idx);
+
+ --rit;
+ ++idx;
+ QCOMPARE(*rit, idx);
+
+ rit--;
+ idx++;
+ QCOMPARE(*rit, idx);
}
-template<typename T>
void tst_QList::reverseIterators() const
{
- QList<T> v;
- v << T_CAT << T_DOG << T_BLAH << T_BAZ;
- QList<T> vr = v;
+ QList<int> v;
+ v << 1 << 2 << 3 << 4;
+ QList<int> vr = v;
std::reverse(vr.begin(), vr.end());
- const QList<T> &cvr = vr;
+ const QList<int> &cvr = vr;
QVERIFY(std::equal(v.begin(), v.end(), vr.rbegin()));
QVERIFY(std::equal(v.begin(), v.end(), vr.crbegin()));
QVERIFY(std::equal(v.begin(), v.end(), cvr.rbegin()));
@@ -1394,690 +2876,1094 @@ void tst_QList::reverseIterators() const
QVERIFY(std::equal(cvr.rbegin(), cvr.rend(), v.begin()));
}
-void tst_QList::reverseIteratorsOptimal() const
+template<typename T>
+void tst_QList::size() const
{
- const int liveCount = Optimal::getLiveCount();
- reverseIterators<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::reverseIteratorsMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- reverseIterators<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ // also verify that length() is an alias to size()
-void tst_QList::reverseIteratorsComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- reverseIterators<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ // zero size
+ QList<T> myvec;
+ QVERIFY(myvec.size() == 0);
+ QCOMPARE(myvec.size(), myvec.size());
+ QVERIFY(!myvec.isDetached());
+
+ // grow
+ myvec.append(SimpleValue<T>::at(0));
+ QVERIFY(myvec.size() == 1);
+ QCOMPARE(myvec.size(), myvec.size());
+ myvec.append(SimpleValue<T>::at(1));
+ QVERIFY(myvec.size() == 2);
+ QCOMPARE(myvec.size(), myvec.size());
+
+ // shrink
+ myvec.remove(0);
+ QVERIFY(myvec.size() == 1);
+ QCOMPARE(myvec.size(), myvec.size());
+ myvec.remove(0);
+ QVERIFY(myvec.size() == 0);
+ QCOMPARE(myvec.size(), myvec.size());
}
-template<typename T>
+// ::squeeze() is tested in ::capacity().
+
void tst_QList::startsWith() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ QList<int> myvec;
- // make sure it starts ok
- QVERIFY(list.startsWith(T_FOO));
+ // empty vector
+ QVERIFY(!myvec.startsWith(1));
- // remove an item
- list.removeFirst();
- QVERIFY(list.startsWith(T_BAR));
+ // add the one, should work
+ myvec.prepend(1);
+ QVERIFY(myvec.startsWith(1));
+
+ // add something else, fails now
+ myvec.prepend(3);
+ QVERIFY(!myvec.startsWith(1));
+
+ // remove it again :)
+ myvec.remove(0);
+ QVERIFY(myvec.startsWith(1));
}
-void tst_QList::startsWithOptimal() const
+template<typename T>
+void tst_QList::swap() const
{
- const int liveCount = Optimal::getLiveCount();
- startsWith<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> v1, v2;
+ T val1 = SimpleValue<T>::at(0);
+ T val2 = SimpleValue<T>::at(1);
+ T val3 = SimpleValue<T>::at(2);
+ T val4 = SimpleValue<T>::at(3);
+ T val5 = SimpleValue<T>::at(4);
+ T val6 = SimpleValue<T>::at(5);
+ v1 << val1 << val2 << val3;
+ v2 << val4 << val5 << val6;
+
+ v1.swap(v2);
+ QCOMPARE(v1,QList<T>() << val4 << val5 << val6);
+ QCOMPARE(v2,QList<T>() << val1 << val2 << val3);
}
-void tst_QList::startsWithMovable() const
+void tst_QList::toList() const
{
- const int liveCount = Movable::getLiveCount();
- startsWith<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QList<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // make sure it converts and doesn't modify the original vector
+ QCOMPARE(myvec.toList(), QList<QString>() << "A" << "B" << "C");
+ QCOMPARE(myvec, QList<QString>() << "A" << "B" << "C");
}
-void tst_QList::startsWithComplex() const
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+void tst_QList::toStdVector() const
{
- const int liveCount = Complex::getLiveCount();
- startsWith<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ std::vector<QString> svec = myvec.toStdVector();
+ QCOMPARE(svec.at(0), QLatin1String("A"));
+ QCOMPARE(svec.at(1), QLatin1String("B"));
+ QCOMPARE(svec.at(2), QLatin1String("C"));
+
+ QCOMPARE(myvec, QList<QString>() << "A" << "B" << "C");
}
+#endif
-template<typename T>
-void tst_QList::swap() const
+void tst_QList::value() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ QList<QString> myvec;
- // swap
- list.swap(0, 2);
- QCOMPARE(list, QList<T>() << T_BAZ << T_BAR << T_FOO);
+ QCOMPARE(myvec.value(1), QString());
+ QCOMPARE(myvec.value(-1, QLatin1String("default")), QLatin1String("default"));
+ QVERIFY(!myvec.isDetached());
- // swap again
- list.swap(1, 2);
- QCOMPARE(list, QList<T>() << T_BAZ << T_FOO << T_BAR);
+ myvec << "A" << "B" << "C";
- QList<T> list2;
- list2 << T_DOG << T_BLAH;
+ // valid calls
+ QCOMPARE(myvec.value(0), QLatin1String("A"));
+ QCOMPARE(myvec.value(1), QLatin1String("B"));
+ QCOMPARE(myvec.value(2), QLatin1String("C"));
- list.swap(list2);
- QCOMPARE(list, QList<T>() << T_DOG << T_BLAH);
- QCOMPARE(list2, QList<T>() << T_BAZ << T_FOO << T_BAR);
-}
+ // default calls
+ QCOMPARE(myvec.value(-1), QString());
+ QCOMPARE(myvec.value(3), QString());
-void tst_QList::swapOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- swap<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ // test calls with a provided default, valid calls
+ QCOMPARE(myvec.value(0, QLatin1String("default")), QLatin1String("A"));
+ QCOMPARE(myvec.value(1, QLatin1String("default")), QLatin1String("B"));
+ QCOMPARE(myvec.value(2, QLatin1String("default")), QLatin1String("C"));
-void tst_QList::swapMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- swap<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ // test calls with a provided default that will return the default
+ QCOMPARE(myvec.value(-1, QLatin1String("default")), QLatin1String("default"));
+ QCOMPARE(myvec.value(3, QLatin1String("default")), QLatin1String("default"));
}
-void tst_QList::swapComplex() const
+void tst_QList::testOperators() const
{
- const int liveCount = Complex::getLiveCount();
- swap<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
+ QList<QString> myvec;
+ myvec << "A" << "B" << "C";
+ QList<QString> myvectwo;
+ myvectwo << "D" << "E" << "F";
+ QList<QString> combined;
+ combined << "A" << "B" << "C" << "D" << "E" << "F";
-template<typename T>
-void tst_QList::takeAt() const
-{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ // !=
+ QVERIFY(myvec != myvectwo);
- QCOMPARE(list.takeAt(0), T_FOO);
- QVERIFY(list.size() == 2);
- QCOMPARE(list.takeAt(1), T_BAZ);
- QVERIFY(list.size() == 1);
- QCOMPARE(list.takeAt(0), T_BAR);
- QVERIFY(list.size() == 0);
-}
+ // +
+ QCOMPARE(myvec + myvectwo, combined);
+ QCOMPARE(myvec, QList<QString>() << "A" << "B" << "C");
+ QCOMPARE(myvectwo, QList<QString>() << "D" << "E" << "F");
-void tst_QList::takeAtOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- takeAt<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ // +=
+ myvec += myvectwo;
+ QCOMPARE(myvec, combined);
+
+ // ==
+ QVERIFY(myvec == combined);
+
+ // <, >, <=, >=
+ QVERIFY(!(myvec < combined));
+ QVERIFY(!(myvec > combined));
+ QVERIFY( myvec <= combined);
+ QVERIFY( myvec >= combined);
+ combined.push_back("G");
+ QVERIFY( myvec < combined);
+ QVERIFY(!(myvec > combined));
+ QVERIFY( myvec <= combined);
+ QVERIFY(!(myvec >= combined));
+ QVERIFY(combined > myvec);
+ QVERIFY(combined >= myvec);
+
+ // []
+ QCOMPARE(myvec[0], QLatin1String("A"));
+ QCOMPARE(myvec[1], QLatin1String("B"));
+ QCOMPARE(myvec[2], QLatin1String("C"));
+ QCOMPARE(myvec[3], QLatin1String("D"));
+ QCOMPARE(myvec[4], QLatin1String("E"));
+ QCOMPARE(myvec[5], QLatin1String("F"));
}
-void tst_QList::takeAtMovable() const
+
+int fooCtor;
+int fooDtor;
+
+struct Foo
{
- const int liveCount = Movable::getLiveCount();
- takeAt<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ int *p;
+
+ Foo() { p = new int; ++fooCtor; }
+ Foo(const Foo &other) { Q_UNUSED(other); p = new int; ++fooCtor; }
+
+ void operator=(const Foo & /* other */) { }
-void tst_QList::takeAtComplex() const
+ ~Foo() { delete p; ++fooDtor; }
+};
+
+void tst_QList::reserve()
{
- const int liveCount = Complex::getLiveCount();
- takeAt<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ fooCtor = 0;
+ fooDtor = 0;
+ {
+ QList<Foo> a;
+ a.resize(2);
+ QCOMPARE(fooCtor, 2);
+ QList<Foo> b(a);
+ b.reserve(1);
+ QCOMPARE(b.size(), a.size());
+ QCOMPARE(fooDtor, 0);
+ }
+ QCOMPARE(fooCtor, fooDtor);
+}
+
+// This is a regression test for QTBUG-51758
+void tst_QList::reserveZero()
+{
+ QList<int> vec;
+ vec.detach();
+ vec.reserve(0); // should not crash
+ QCOMPARE(vec.size(), 0);
+ QCOMPARE(vec.capacity(), 0);
+ vec.squeeze();
+ QCOMPARE(vec.size(), 0);
+ QCOMPARE(vec.capacity(), 0);
+ vec.reserve(-1);
+ QCOMPARE(vec.size(), 0);
+ QCOMPARE(vec.capacity(), 0);
+ vec.append(42);
+ QCOMPARE(vec.size(), 1);
+ QVERIFY(vec.capacity() >= 1);
+
+ QList<int> vec2;
+ vec2.reserve(0); // should not crash either
+ vec2.reserve(-1);
+ vec2.squeeze();
+ QCOMPARE(vec2.size(), 0);
+ QCOMPARE(vec2.capacity(), 0);
+ QVERIFY(!vec2.isDetached());
}
template<typename T>
-void tst_QList::takeFirst() const
+void tst_QList::initializeList()
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ TST_QLIST_CHECK_LEAKS(T)
- QCOMPARE(list.takeFirst(), T_FOO);
- QVERIFY(list.size() == 2);
- QCOMPARE(list.takeFirst(), T_BAR);
- QVERIFY(list.size() == 1);
- QCOMPARE(list.takeFirst(), T_BAZ);
- QVERIFY(list.size() == 0);
-}
+ T val1(SimpleValue<T>::at(1));
+ T val2(SimpleValue<T>::at(2));
+ T val3(SimpleValue<T>::at(3));
+ T val4(SimpleValue<T>::at(4));
-void tst_QList::takeFirstOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- takeFirst<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ QList<T> v1 {val1, val2, val3};
+ QCOMPARE(v1, QList<T>() << val1 << val2 << val3);
+ QCOMPARE(v1, (QList<T> {val1, val2, val3}));
-void tst_QList::takeFirstMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- takeFirst<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QList<QList<T>> v2{ v1, {val4}, QList<T>(), {val1, val2, val3} };
+ QList<QList<T>> v3;
+ v3 << v1 << (QList<T>() << val4) << QList<T>() << v1;
+ QCOMPARE(v3, v2);
+
+ QList<T> v4({});
+ QCOMPARE(v4.size(), 0);
}
-void tst_QList::takeFirstComplex() const
+void tst_QList::const_shared_null()
{
- const int liveCount = Complex::getLiveCount();
- takeFirst<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<int> v2;
+ QVERIFY(!v2.isDetached());
}
template<typename T>
-void tst_QList::takeLast() const
+void tst_QList::detach() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ TST_QLIST_CHECK_LEAKS(T)
- QCOMPARE(list.takeLast(), T_BAZ);
- QCOMPARE(list.takeLast(), T_BAR);
- QCOMPARE(list.takeLast(), T_FOO);
+ {
+ // detach an empty vector
+ QList<T> v;
+ v.detach();
+ QVERIFY(!v.isDetached());
+ QCOMPARE(v.size(), 0);
+ QCOMPARE(v.capacity(), 0);
+ }
+ {
+ // detach an empty referenced vector
+ QList<T> v;
+ QList<T> ref(v);
+ QVERIFY(!v.isDetached());
+ v.detach();
+ QVERIFY(!v.isDetached());
+ QCOMPARE(v.size(), 0);
+ QCOMPARE(v.capacity(), 0);
+ }
+ {
+ // detach a not empty referenced vector
+ QList<T> v(31);
+ QList<T> ref(v);
+ QVERIFY(!v.isDetached());
+ v.detach();
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 31);
+ QCOMPARE(v.capacity(), 31);
+ }
+ {
+ // detach a not empty vector
+ QList<T> v(31);
+ QVERIFY(v.isDetached());
+ v.detach(); // detaching a detached vector
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 31);
+ QCOMPARE(v.capacity(), 31);
+ }
+ {
+ // detach a not empty vector with preallocated space
+ QList<T> v(3);
+ v.reserve(8);
+ QList<T> ref(v);
+ QVERIFY(!v.isDetached());
+ v.detach();
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 3);
+ QCOMPARE(v.capacity(), 8);
+ }
+ {
+ // detach a not empty vector with preallocated space
+ QList<T> v(3);
+ v.reserve(8);
+ QVERIFY(v.isDetached());
+ v.detach(); // detaching a detached vector
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 3);
+ QCOMPARE(v.capacity(), 8);
+ }
+ {
+ // detach a not empty, initialized vector
+ QList<T> v(7, SimpleValue<T>::at(1));
+ QList<T> ref(v);
+ QVERIFY(!v.isDetached());
+ v.detach();
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 7);
+ for (int i = 0; i < v.size(); ++i)
+ QCOMPARE(v[i], SimpleValue<T>::at(1));
+ }
+ {
+ // detach a not empty, initialized vector
+ QList<T> v(7, SimpleValue<T>::at(2));
+ QVERIFY(v.isDetached());
+ v.detach(); // detaching a detached vector
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 7);
+ for (int i = 0; i < v.size(); ++i)
+ QCOMPARE(v[i], SimpleValue<T>::at(2));
+ }
+ {
+ // detach a not empty, initialized vector with preallocated space
+ QList<T> v(7, SimpleValue<T>::at(3));
+ v.reserve(31);
+ QList<T> ref(v);
+ QVERIFY(!v.isDetached());
+ v.detach();
+ QVERIFY(v.isDetached());
+ QCOMPARE(v.size(), 7);
+ QCOMPARE(v.capacity(), 31);
+ for (int i = 0; i < v.size(); ++i)
+ QCOMPARE(v[i], SimpleValue<T>::at(3));
+ }
}
-void tst_QList::takeLastOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- takeLast<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+static QAtomicPointer<QList<int> > detachThreadSafetyDataInt;
+static QAtomicPointer<QList<Movable> > detachThreadSafetyDataMovable;
+static QAtomicPointer<QList<Custom> > detachThreadSafetyDataCustom;
-void tst_QList::takeLastMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- takeLast<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+template<typename T> QAtomicPointer<QList<T> > *detachThreadSafetyData();
+template<> QAtomicPointer<QList<int> > *detachThreadSafetyData() { return &detachThreadSafetyDataInt; }
+template<> QAtomicPointer<QList<Movable> > *detachThreadSafetyData() { return &detachThreadSafetyDataMovable; }
+template<> QAtomicPointer<QList<Custom> > *detachThreadSafetyData() { return &detachThreadSafetyDataCustom; }
-void tst_QList::takeLastComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- takeLast<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
+static QSemaphore detachThreadSafetyLock;
template<typename T>
-void tst_QList::toSet() const
+void tst_QList::detachThreadSafety() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(new QList<T>(SimpleValue<T>::vector(400)));
- // no duplicates
- QCOMPARE(list.toSet(), QSet<T>() << T_FOO << T_BAR << T_BAZ);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ);
+ static const uint threadsCount = 5;
- // duplicates (is this more of a QSet test?)
- list << T_FOO << T_BAR << T_BAZ;
- QCOMPARE(list.toSet(), QSet<T>() << T_FOO << T_BAR << T_BAZ);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ
- << T_FOO << T_BAR << T_BAZ);
-}
+ struct : QThread {
+ void run() override
+ {
+ QList<T> copy(*detachThreadSafetyData<T>()->loadRelaxed());
+ QVERIFY(!copy.isDetached());
+ detachThreadSafetyLock.release();
+ detachThreadSafetyLock.acquire(100);
+ copy.detach();
+ }
+ } threads[threadsCount];
-void tst_QList::toSetOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- toSet<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ for (uint i = 0; i < threadsCount; ++i)
+ threads[i].start();
+ QThread::yieldCurrentThread();
+ detachThreadSafetyLock.acquire(threadsCount);
-void tst_QList::toSetMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- toSet<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ // destroy static original data
+ delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(0);
-void tst_QList::toSetComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- toSet<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QVERIFY(threadsCount < 100);
+ detachThreadSafetyLock.release(threadsCount * 100);
+ QThread::yieldCurrentThread();
+
+ for (uint i = 0; i < threadsCount; ++i)
+ threads[i].wait();
}
-template<typename T>
-void tst_QList::toStdList() const
+void tst_QList::detachThreadSafetyInt() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // yuck.
- std::list<T> slist;
- slist.push_back(T_FOO);
- slist.push_back(T_BAR);
- slist.push_back(T_BAZ);
-
- QCOMPARE(list.toStdList(), slist);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ);
+ for (uint i = 0; i < 128; ++i)
+ detachThreadSafety<int>();
}
-void tst_QList::toStdListOptimal() const
+void tst_QList::detachThreadSafetyMovable() const
{
- const int liveCount = Optimal::getLiveCount();
- toStdList<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ const int instancesCount = Movable::counter.loadAcquire();
+ for (uint i = 0; i < 128; ++i) {
+ detachThreadSafety<Movable>();
+ QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
+ }
}
-void tst_QList::toStdListMovable() const
+void tst_QList::detachThreadSafetyCustom() const
{
- const int liveCount = Movable::getLiveCount();
- toStdList<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ const int instancesCount = Custom::counter.loadAcquire();
+ for (uint i = 0; i < 128; ++i) {
+ detachThreadSafety<Custom>();
+ QCOMPARE(Custom::counter.loadAcquire(), instancesCount);
+ }
}
-void tst_QList::toStdListComplex() const
+void tst_QList::insertMove() const
{
- const int liveCount = Complex::getLiveCount();
- toStdList<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ const int instancesCount = Movable::counter.loadAcquire();
+ {
+ QList<Movable> vec;
+ vec.reserve(7);
+ Movable m0;
+ Movable m1;
+ Movable m2;
+ Movable m3;
+ Movable m4;
+ Movable m5;
+ Movable m6;
+
+ vec.append(std::move(m3));
+ QVERIFY(m3.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m3));
+ vec.push_back(std::move(m4));
+ QVERIFY(m4.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m3));
+ QVERIFY(vec.at(1).wasConstructedAt(&m4));
+ vec.prepend(std::move(m1));
+ QVERIFY(m1.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m1));
+ QVERIFY(vec.at(1).wasConstructedAt(&m3));
+ QVERIFY(vec.at(2).wasConstructedAt(&m4));
+ vec.insert(1, std::move(m2));
+ QVERIFY(m2.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m1));
+ QVERIFY(vec.at(1).wasConstructedAt(&m2));
+ QVERIFY(vec.at(2).wasConstructedAt(&m3));
+ QVERIFY(vec.at(3).wasConstructedAt(&m4));
+ vec += std::move(m5);
+ QVERIFY(m5.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m1));
+ QVERIFY(vec.at(1).wasConstructedAt(&m2));
+ QVERIFY(vec.at(2).wasConstructedAt(&m3));
+ QVERIFY(vec.at(3).wasConstructedAt(&m4));
+ QVERIFY(vec.at(4).wasConstructedAt(&m5));
+ vec << std::move(m6);
+ QVERIFY(m6.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m1));
+ QVERIFY(vec.at(1).wasConstructedAt(&m2));
+ QVERIFY(vec.at(2).wasConstructedAt(&m3));
+ QVERIFY(vec.at(3).wasConstructedAt(&m4));
+ QVERIFY(vec.at(4).wasConstructedAt(&m5));
+ QVERIFY(vec.at(5).wasConstructedAt(&m6));
+ vec.push_front(std::move(m0));
+ QVERIFY(m0.wasConstructedAt(nullptr));
+ QVERIFY(vec.at(0).wasConstructedAt(&m0));
+ QVERIFY(vec.at(1).wasConstructedAt(&m1));
+ QVERIFY(vec.at(2).wasConstructedAt(&m2));
+ QVERIFY(vec.at(3).wasConstructedAt(&m3));
+ QVERIFY(vec.at(4).wasConstructedAt(&m4));
+ QVERIFY(vec.at(5).wasConstructedAt(&m5));
+ QVERIFY(vec.at(6).wasConstructedAt(&m6));
+
+ QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 14);
+ }
+ QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
}
-template<typename T>
-void tst_QList::toVector() const
+void tst_QList::swapItemsAt() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ QList<int> v;
+ v << 0 << 1 << 2 << 3;
+
+ v.swapItemsAt(0, 2);
+ QCOMPARE(v.at(0), 2);
+ QCOMPARE(v.at(2), 0);
- QCOMPARE(list.toVector(), QVector<T>() << T_FOO << T_BAR << T_BAZ);
+ auto copy = v;
+ copy.swapItemsAt(0, 2);
+ QCOMPARE(v.at(0), 2);
+ QCOMPARE(v.at(2), 0);
+ QCOMPARE(copy.at(0), 0);
+ QCOMPARE(copy.at(2), 2);
}
-void tst_QList::toVectorOptimal() const
+void tst_QList::emplaceReturnsIterator()
{
- const int liveCount = Optimal::getLiveCount();
- toVector<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ QList<Movable> vec;
+
+ vec.emplace(0, 'k')->i = 'p';
+
+ QCOMPARE(vec[0].i, 'p');
}
-void tst_QList::toVectorMovable() const
+void tst_QList::emplaceFront() const
{
- const int liveCount = Movable::getLiveCount();
- toVector<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QAtomicScopedValueRollback rollback(Movable::counter, 0);
+
+ QList<Movable> vec;
+ vec.emplaceFront('b');
+ QCOMPARE(Movable::counter, 1);
+
+ vec.emplaceFront('a');
+ QCOMPARE(Movable::counter, 2);
+
+ QCOMPARE(vec, QList<Movable>({ 'a', 'b' }));
}
-void tst_QList::toVectorComplex() const
+void tst_QList::emplaceFrontReturnsRef() const
{
- const int liveCount = Complex::getLiveCount();
- toVector<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QList<Movable> vec;
+
+ QCOMPARE(vec.emplaceFront('c').i, 'c');
+
+ vec.emplaceFront('b').i = 'a';
+
+ QCOMPARE(vec.front().i, 'a');
}
-template<typename T>
-void tst_QList::value() const
+void tst_QList::emplaceBack()
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
+ QAtomicScopedValueRollback rollback(Movable::counter, 0);
- // test real values
- QCOMPARE(list.value(0), T_FOO);
- QCOMPARE(list.value(2), T_BAZ);
+ QList<Movable> vec;
- // test empty default
- QCOMPARE(list.value(3), T());
- QCOMPARE(list.value(-1), T());
+ vec.emplaceBack('k');
- // test defaults
- T defaultT(T_WEEE);
- QCOMPARE(list.value(-1, defaultT), defaultT);
- QCOMPARE(list.value(3, defaultT), defaultT);
+ QCOMPARE(Movable::counter, 1);
}
-void tst_QList::valueOptimal() const
+void tst_QList::emplaceBackReturnsRef()
{
- const int liveCount = Optimal::getLiveCount();
- value<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ QList<Movable> vec;
+
+ vec.emplaceBack('k').i = 'p';
+
+ QCOMPARE(vec.at(0).i, 'p');
}
-void tst_QList::valueMovable() const
+void tst_QList::emplaceWithElementFromTheSameContainer()
{
- const int liveCount = Movable::getLiveCount();
- value<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QFETCH(int, elementPos);
+ QFETCH(int, insertPos);
+ QFETCH(bool, doCopy);
+
+ QList<QString> vec {"a", "b", "c", "d", "e"};
+ const QString e = vec[elementPos];
+
+ if (doCopy)
+ vec.emplace(insertPos, vec[elementPos]);
+ else
+ vec.emplace(insertPos, std::move(vec[elementPos]));
+
+ QCOMPARE(vec[insertPos], e);
}
-void tst_QList::valueComplex() const
+void tst_QList::emplaceWithElementFromTheSameContainer_data()
{
- const int liveCount = Complex::getLiveCount();
- value<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ QTest::addColumn<int>("elementPos");
+ QTest::addColumn<int>("insertPos");
+ QTest::addColumn<bool>("doCopy");
+
+ for (int i = 0; i < 2; ++i) {
+ const bool doCopy = i == 0;
+ const char *opName = doCopy ? "copy" : "move";
+
+ QTest::addRow("%s: begin -> end" , opName) << 0 << 5 << doCopy;
+ QTest::addRow("%s: begin -> middle", opName) << 0 << 2 << doCopy;
+ QTest::addRow("%s: middle -> begin" , opName) << 2 << 0 << doCopy;
+ QTest::addRow("%s: middle -> end" , opName) << 2 << 5 << doCopy;
+ QTest::addRow("%s: end -> middle", opName) << 4 << 2 << doCopy;
+ QTest::addRow("%s: end -> begin" , opName) << 4 << 0 << doCopy;
+ }
}
template<typename T>
-void tst_QList::testOperators() const
+void tst_QList::emplaceImpl() const
{
- QList<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- QList<T> listtwo;
- listtwo << T_FOO << T_BAR << T_BAZ;
+ TST_QLIST_CHECK_LEAKS(T)
- // test equal
- QVERIFY(list == listtwo);
+ QList<T> vec {'a', 'b', 'c', 'd'};
- // not equal
- listtwo.append(T_CAT);
- QVERIFY(list != listtwo);
+ vec.emplace(2, 'k');
- // +=
- list += listtwo;
- QVERIFY(list.size() == 7);
- QVERIFY(listtwo.size() == 4);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ
- << T_FOO << T_BAR << T_BAZ << T_CAT);
+ QCOMPARE(vec.size(), 5); // emplace adds new element
+ QCOMPARE(vec[2], T('k'));
- // =
- list = listtwo;
- QCOMPARE(list, listtwo);
- QCOMPARE(list, QList<T>() << T_FOO << T_BAR << T_BAZ << T_CAT);
+ vec.emplace(vec.end(), T('f'));
- // []
- QCOMPARE(list[0], T_FOO);
- QCOMPARE(list[list.size() - 1], T_CAT);
+ QCOMPARE(vec.size(), 6);
+ QCOMPARE(vec.back(), T('f'));
- // <, >, <=, >=
- QVERIFY(!(list < listtwo));
- QVERIFY(!(list > listtwo));
- QVERIFY( list <= listtwo);
- QVERIFY( list >= listtwo);
- listtwo.push_back(T_CAT);
- QVERIFY( list < listtwo);
- QVERIFY(!(list > listtwo));
- QVERIFY( list <= listtwo);
- QVERIFY(!(list >= listtwo));
- QVERIFY(listtwo > list);
- QVERIFY(listtwo >= list);
+ // emplace() into empty container
+ {
+ QList<T> vec;
+ vec.emplace(vec.begin(), 'a');
+ QCOMPARE(vec.size(), 1);
+ QCOMPARE(vec.front(), T('a'));
+ }
+ {
+ QList<T> vec;
+ vec.emplace(0, 'a');
+ QCOMPARE(vec.size(), 1);
+ QCOMPARE(vec.front(), T('a'));
+ }
}
-void tst_QList::testOperatorsOptimal() const
+template <typename T>
+void tst_QList::replace() const
{
- const int liveCount = Optimal::getLiveCount();
- testOperators<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ TST_QLIST_CHECK_LEAKS(T)
+
+ QList<T> vec { 'a', 'b', 'c', 'd' };
+ T e = 'e';
+ vec.replace(0, e);
+ QCOMPARE(vec[0], T('e'));
+
+ T f = 'f';
+ vec.replace(2, std::move(f));
+ QCOMPARE(vec[2], T('f'));
}
-void tst_QList::testOperatorsMovable() const
+template <class T>
+static void vecEq(const QList<T> &qVec, const std::vector<T> &stdVec)
{
- const int liveCount = Movable::getLiveCount();
- testOperators<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
+ QCOMPARE(std::size_t(qVec.size()), stdVec.size());
+ QVERIFY(std::equal(qVec.begin(), qVec.end(), stdVec.begin(), stdVec.end()));
}
-void tst_QList::testOperatorsComplex() const
+template <class T>
+static void squeezeVec(QList<T> &qVec, std::vector<T> &stdVec)
{
- const int liveCount = Complex::getLiveCount();
- testOperators<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ qVec.squeeze();
+ stdVec.shrink_to_fit();
}
template<typename T>
-void tst_QList::testSTLIterators() const
+void tst_QList::emplaceConsistentWithStdVectorImpl() const
{
- QList<T> list;
+ TST_QLIST_CHECK_LEAKS(T)
- // create a list
- list << T_FOO << T_BAR << T_BAZ;
- typename QList<T>::iterator it = list.begin();
- QCOMPARE(*it, T_FOO); it++;
- QCOMPARE(*it, T_BAR); it++;
- QCOMPARE(*it, T_BAZ); it++;
- QCOMPARE(it, list.end()); it--;
+ // fast-patch to make QString work with the old logic
+ const auto convert = [] (char i) {
+ if constexpr (std::is_same_v<QString, T>) {
+ return QChar(i);
+ } else {
+ return i;
+ }
+ };
- // walk backwards
- QCOMPARE(*it, T_BAZ); it--;
- QCOMPARE(*it, T_BAR); it--;
- QCOMPARE(*it, T_FOO);
+ QList<T> qVec {convert('a'), convert('b'), convert('c'), convert('d'), convert('e')};
+ std::vector<T> stdVec {convert('a'), convert('b'), convert('c'), convert('d'), convert('e')};
+ vecEq(qVec, stdVec);
- // test erase
- it = list.erase(it);
- QVERIFY(list.size() == 2);
- QCOMPARE(*it, T_BAR);
+ qVec.emplaceBack(convert('f'));
+ stdVec.emplace_back(convert('f'));
+ vecEq(qVec, stdVec);
- // test multiple erase
- it = list.erase(it, it + 2);
- QVERIFY(list.size() == 0);
- QCOMPARE(it, list.end());
+ qVec.emplace(3, convert('g'));
+ stdVec.emplace(stdVec.begin() + 3, convert('g'));
+ vecEq(qVec, stdVec);
- // insert again
- it = list.insert(it, T_FOO);
- QVERIFY(list.size() == 1);
- QCOMPARE(*it, T_FOO);
+ T t;
+ // while QList is safe with regards to emplacing elements moved from itself, it's UB
+ // for std::vector, so do the moving in two steps there.
+ qVec.emplaceBack(std::move(qVec[0]));
+ stdVec.emplace_back(std::move(t = std::move(stdVec[0])));
+ vecEq(qVec, stdVec);
- // insert again
- it = list.insert(it, T_BAR);
- QVERIFY(list.size() == 2);
- QCOMPARE(*it++, T_BAR);
- QCOMPARE(*it, T_FOO);
-}
+ squeezeVec(qVec, stdVec);
-void tst_QList::testSTLIteratorsOptimal() const
-{
- const int liveCount = Optimal::getLiveCount();
- testSTLIterators<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
-}
+ qVec.emplaceBack(std::move(qVec[1]));
+ stdVec.emplace_back(std::move(t = std::move(stdVec[1])));
+ vecEq(qVec, stdVec);
-void tst_QList::testSTLIteratorsMovable() const
-{
- const int liveCount = Movable::getLiveCount();
- testSTLIterators<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ squeezeVec(qVec, stdVec);
-void tst_QList::testSTLIteratorsComplex() const
-{
- const int liveCount = Complex::getLiveCount();
- testSTLIterators<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
-}
+ qVec.emplace(3, std::move(qVec[5]));
+ stdVec.emplace(stdVec.begin() + 3, std::move(t = std::move(stdVec[5])));
-void tst_QList::initializeList() const
-{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
- QList<int> v1{2,3,4};
- QCOMPARE(v1, QList<int>() << 2 << 3 << 4);
- QCOMPARE(v1, (QList<int>{2,3,4}));
+ vecEq(qVec, stdVec);
- QList<QList<int>> v2{ v1, {1}, QList<int>(), {2,3,4} };
- QList<QList<int>> v3;
- v3 << v1 << (QList<int>() << 1) << QList<int>() << v1;
- QCOMPARE(v3, v2);
-#endif
-}
+ qVec.emplaceBack(qVec[3]);
+ stdVec.emplace_back((t = stdVec[3]));
+ vecEq(qVec, stdVec);
-template<typename T>
-void tst_QList::constSharedNull() const
-{
- QList<T> list2;
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QList<T> list1;
- list1.setSharable(false);
- QVERIFY(list1.isDetached());
+ squeezeVec(qVec, stdVec);
- list2.setSharable(true);
-#endif
- QVERIFY(!list2.isDetached());
+ qVec.emplaceBack(qVec[4]);
+ stdVec.emplace_back((t = stdVec[4]));
+ vecEq(qVec, stdVec);
+
+ squeezeVec(qVec, stdVec);
+
+ qVec.emplace(5, qVec[7]);
+ stdVec.emplace(stdVec.begin() + 5, (t = stdVec[7]));
+ vecEq(qVec, stdVec);
}
-void tst_QList::constSharedNullOptimal() const
+void tst_QList::fromReadOnlyData() const
{
- const int liveCount = Optimal::getLiveCount();
- constSharedNull<Optimal>();
- QCOMPARE(liveCount, Optimal::getLiveCount());
+ {
+ QVector<char> d = QVector<char>::fromReadOnlyData("ABCDEFGHIJ");
+ QCOMPARE(d.capacity(), 0);
+ d.squeeze();
+ QCOMPARE(d.capacity(), 0);
+ QCOMPARE(d.size(), 10u + 1u);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d.data()[i], char('A' + i));
+ }
+
+ {
+ // wchar_t is not necessarily 2-bytes
+ QVector<wchar_t> d = QVector<wchar_t>::fromReadOnlyData(L"ABCDEFGHIJ");
+ QCOMPARE(d.size(), 10u + 1u);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(d.data()[i], wchar_t('A' + i));
+ QVERIFY(d.isDetached());
+ }
+
+ {
+ const char data[] = "ABCDEFGHIJ";
+ const QVector<char> v = QVector<char>::fromReadOnlyData(data);
+
+ QVERIFY(v.constData() == data);
+ QVERIFY(!v.isEmpty());
+ QCOMPARE(v.size(), qsizetype(11));
+ // v.capacity() is unspecified, for now
+
+ QCOMPARE((void*)(v.constBegin() + v.size()).operator->(), (void*)v.constEnd().operator->());
+
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(v[i], char('A' + i));
+ QCOMPARE(v[10], char('\0'));
+ }
+
+ {
+ struct LiteralType {
+ int value;
+ constexpr LiteralType(int v = 0) : value(v) {}
+ };
+ const LiteralType literal[] = {LiteralType(0), LiteralType(1), LiteralType(2)};
+
+ const QVector<LiteralType> d = QVector<LiteralType>::fromReadOnlyData(literal);
+ QCOMPARE(d.size(), 3);
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(d.data()[i].value, i);
+ }
}
-void tst_QList::constSharedNullMovable() const
+struct alignas(8) CustomAligned
{
- const int liveCount = Movable::getLiveCount();
- constSharedNull<Movable>();
- QCOMPARE(liveCount, Movable::getLiveCount());
-}
+ qint64 v = 0;
+ CustomAligned() = default;
+ CustomAligned(qint64 i) : v(i) { }
+ friend bool operator==(const CustomAligned &x, const CustomAligned &y) { return x.v == y.v; }
+};
-void tst_QList::constSharedNullComplex() const
+void tst_QList::reallocateCustomAlignedType_qtbug90359() const
{
- const int liveCount = Complex::getLiveCount();
- constSharedNull<Complex>();
- QCOMPARE(liveCount, Complex::getLiveCount());
+ // Note: a very special test that could only fail for specific alignments
+ constexpr bool canFail = (alignof(QArrayData) == 4) && (sizeof(QArrayData) == 12);
+ if constexpr (!canFail)
+ qWarning() << "This test will always succeed on this system.";
+ if constexpr (alignof(CustomAligned) > alignof(std::max_align_t))
+ QSKIP("The codepaths tested here wouldn't be executed.");
+
+ const QList<CustomAligned> expected({ 0, 1, 2, 3, 4, 5, 6 });
+ QList<CustomAligned> actual;
+ for (int i = 0; i < 7; ++i) {
+ actual.append(i);
+ QCOMPARE(actual.at(i), i);
+ }
+ QCOMPARE(actual, expected);
}
-template <class T>
-void generateSetSharableData()
+template<typename T, typename Reinsert>
+void tst_QList::reinsert(Reinsert op) const
{
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QTest::addColumn<QList<T> >("list");
- QTest::addColumn<int>("size");
+ TST_QLIST_CHECK_LEAKS(T)
- QTest::newRow("null") << QList<T>() << 0;
- QTest::newRow("non-empty") << (QList<T>() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5;
-#endif
+ QList<T> list(1);
+ // this constant is big enough for the QList to stop reallocating, after
+ // all, size is always less than 3
+ const int maxIters = 128;
+ for (int i = 0; i < maxIters; ++i) {
+ op(list);
+ }
+
+ // if QList continues to grow, it's an error
+ qsizetype capacity = list.capacity();
+ for (int i = 0, enoughIters = int(capacity) * 2; i < enoughIters; ++i) {
+ op(list);
+ QCOMPARE(capacity, list.capacity());
+ }
}
-template <class T>
-void runSetSharableTest()
+template<typename T>
+void tst_QList::stability_reserve() const
{
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QFETCH(QList<T>, list);
- QFETCH(int, size);
+ TST_QLIST_CHECK_LEAKS(T)
- QVERIFY(!list.isDetached()); // Shared with QTest
+ // NOTE: this test verifies that QList::constData() stays unchanged when
+ // inserting as much as requested by the reserve. This is specifically
+ // designed this way as in cases when QTypeInfo<T>::isRelocatable returns
+ // true, reallocation might use fast ::realloc() path which may in theory
+ // (and, actually, in practice) just expand the current memory area and thus
+ // keep QList::constData() unchanged, which means checks like
+ // QVERIFY(oldConstData != vec.constData()) are flaky. When
+ // QTypeInfo<T>::isRelocatable returns false, constData() will always change
+ // if a reallocation happens and this will fail the test. This should be
+ // sufficient on its own to test the stability requirements.
- list.setSharable(true);
+ {
+ QList<T> vec;
+ vec.reserve(64);
+ const T *ptr = vec.constData();
+ vec.append(QList<T>(64));
+ QCOMPARE(ptr, vec.constData());
+ }
- QCOMPARE(list.size(), size);
+ {
+ QList<T> vec;
+ vec.prepend(SimpleValue<T>::at(0));
+ vec.removeFirst();
+ vec.reserve(64);
+ const T *ptr = vec.constData();
+ vec.append(QList<T>(64));
+ QCOMPARE(ptr, vec.constData());
+ }
{
- QList<T> copy(list);
- QVERIFY(!copy.isDetached());
- QVERIFY(copy.isSharedWith(list));
+ QList<T> vec;
+ const T *ptr = vec.constData();
+ vec.reserve(vec.capacity());
+ QCOMPARE(ptr, vec.constData());
+ vec.append(QList<T>(vec.capacity()));
+ QCOMPARE(ptr, vec.constData());
}
- list.setSharable(false);
- QVERIFY(list.isDetached() || list.isSharedWith(QList<T>()));
+ {
+ QList<T> vec;
+ vec.prepend(SimpleValue<T>::at(0));
+ vec.removeFirst();
+ vec.reserve(vec.capacity());
+ const T *ptr = vec.constData();
+ vec.append(QList<T>(vec.capacity()));
+ QCOMPARE(ptr, vec.constData());
+ }
{
- QList<T> copy(list);
+ QList<T> vec;
+ vec.append(SimpleValue<T>::at(0));
+ vec.reserve(64);
+ const T *ptr = vec.constData();
+ vec.append(QList<T>(64 - vec.size())); // 1 element is already in the container
+ QCOMPARE(ptr, vec.constData());
+ QCOMPARE(vec.size(), 64);
+ QCOMPARE(vec.capacity(), 64);
+ const qsizetype oldCapacity = vec.capacity();
+ vec.append(SimpleValue<T>::at(1)); // will reallocate as this exceeds 64
+ QVERIFY(oldCapacity < vec.capacity());
+ }
- QVERIFY(copy.isDetached() || copy.isSharedWith(QList<T>()));
- QCOMPARE(copy.size(), size);
- QCOMPARE(copy, list);
+ {
+ QList<T> vec;
+ vec.prepend(SimpleValue<T>::at(0));
+ vec.reserve(64);
+ const T *ptr = vec.constData();
+ vec.append(QList<T>(64 - vec.size())); // 1 element is already in the container
+ QCOMPARE(ptr, vec.constData());
+ QCOMPARE(vec.size(), 64);
+ QCOMPARE(vec.capacity(), 64);
+ const qsizetype oldCapacity = vec.capacity();
+ vec.append(SimpleValue<T>::at(1)); // will reallocate as this exceeds 64
+ QVERIFY(oldCapacity < vec.capacity());
}
+}
+
+template<typename T>
+void tst_QList::stability_erase() const
+{
+ TST_QLIST_CHECK_LEAKS(T)
- list.setSharable(true);
+ // invalidated: [pos, end())
+ for (int pos = 1; pos < 10; ++pos) {
+ QList<T> v(10);
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ const auto ptr = v.constData();
- {
- QList<T> copy(list);
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.begin() + pos);
- QVERIFY(!copy.isDetached());
- QVERIFY(copy.isSharedWith(list));
+ v.remove(pos, 1);
+ QVERIFY(ptr == v.constData());
+ for (int i = 0; i < copy.size(); ++i)
+ QCOMPARE(*reference[i], copy[i]);
}
- for (int i = 0; i < list.size(); ++i)
- QCOMPARE(int(list[i]), i);
+ // 0 is a special case, because all values get invalidated
+ {
+ QList<T> v(10);
+ const auto ptr = v.constData();
+ v.remove(0, 2);
+ QVERIFY(ptr != v.constData()); // can do fast removal from begin()
+ }
- QCOMPARE(list.size(), size);
-#endif
+ // when erasing everything, leave the data pointer in place (not strictly
+ // required, but this makes more sense in general)
+ {
+ QList<T> v(10);
+ const auto ptr = v.constData();
+ v.remove(0, v.size());
+ QVERIFY(ptr == v.constData());
+ }
}
-void tst_QList::setSharableInt_data() const
+template<typename T>
+void tst_QList::stability_append() const
{
- generateSetSharableData<int>();
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::setSharableComplex_data() const
-{
- generateSetSharableData<Complex>();
-}
+ {
+ QList<T> v(10);
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ QList<T> src(1, SimpleValue<T>::at(0));
+ v.append(src.begin(), src.end());
+ QCOMPARE_LE(v.size(), v.capacity());
+
+ for (int i = 0; i < v.capacity() - v.size(); ++i) {
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.end());
+ v.append(SimpleValue<T>::at(i));
+ for (int i = 0; i < copy.size(); ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
+ }
-void tst_QList::setSharableInt() const
-{
- runSetSharableTest<int>();
+ {
+ QList<T> v;
+ v.reserve(10);
+ const qsizetype capacity = v.capacity();
+ const T *ptr = v.constData();
+ v.prepend(SimpleValue<T>::at(0));
+ // here we abuse the internal details of QList. since there's enough
+ // free space, QList should've only rearranged the data in memory,
+ // without reallocating.
+ QCOMPARE(capacity, v.capacity()); // otherwise cannot rely on ptr
+ const qsizetype freeSpaceAtBegin = v.constData() - ptr;
+ const qsizetype freeSpaceAtEnd = v.capacity() - v.size() - freeSpaceAtBegin;
+ QVERIFY(freeSpaceAtEnd > 0); // otherwise this test is useless
+ QVERIFY(v.size() + freeSpaceAtBegin + freeSpaceAtEnd == v.capacity());
+
+ for (int i = 0; i < freeSpaceAtEnd; ++i) {
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.end());
+ QList<T> src(1, SimpleValue<T>::at(i));
+ v.append(src.begin(), src.end());
+ for (int i = 0; i < copy.size(); ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
+ }
}
-void tst_QList::setSharableComplex() const
+template<typename T, typename Insert>
+void tst_QList::stability_insert(Insert op) const
{
- runSetSharableTest<Complex>();
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::eraseValidIteratorsOnSharedList() const
-{
- QList<int> a, b;
- a.push_back(10);
- a.push_back(20);
- a.push_back(30);
- QList<int>::iterator i = a.begin();
- ++i;
- b = a;
- a.erase(i);
- QCOMPARE(b.size(), 3);
- QCOMPARE(a.size(), 2);
- QCOMPARE(a.at(0), 10);
- QCOMPARE(a.at(1), 30);
+ // invalidated: [pos, end())
+ for (int pos = 1; pos <= 10; ++pos) {
+ QList<T> v(10);
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ v.append(SimpleValue<T>::at(0)); // causes growth
+ v.removeLast();
+ QCOMPARE(v.size(), 10);
+ QVERIFY(v.size() < v.capacity());
- a.push_back(40);
- a.push_back(50);
- a.push_back(60);
- QCOMPARE(a.size(), 5);
- i = a.begin();
- b = a;
- ++i;
- QList<int>::iterator j = i;
- ++j;
- ++j;
- a.erase(i, j); // remove 3 elements
- QCOMPARE(b.size(), 5);
- QCOMPARE(a.size(), 3);
- QCOMPARE(a.at(0), 10);
- QCOMPARE(a.at(1), 50);
-}
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.begin() + pos);
+ op(v, pos, SimpleValue<T>::at(0));
+ for (int i = 0; i < pos; ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
-void tst_QList::insertWithValidIteratorsOnSharedList() const
-{
- QList<int> a, b;
- a.push_back(10);
- a.push_back(20);
- a.push_back(30);
- QList<int>::iterator i = a.begin();
- ++i;
- b = a;
- a.insert(i, 15);
- QCOMPARE(a.size(), b.size() + 1);
- QCOMPARE(b.at(1), 20);
- QCOMPARE(a.at(1), 15);
+ for (int pos = 1; pos <= 10; ++pos) {
+ QList<T> v(10);
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ v.prepend(SimpleValue<T>::at(0)); // causes growth and free space at begin > 0
+ v.removeFirst();
+ QCOMPARE(v.size(), 10);
+ QVERIFY(v.size() < v.capacity());
+
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.begin() + pos);
+ op(v, pos, SimpleValue<T>::at(0));
+ for (int i = 0; i < pos; ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
}
-template <typename T>
-void tst_QList::qhash() const
+template<typename T>
+void tst_QList::stability_resize() const
{
- QList<T> l1, l2;
- QCOMPARE(qHash(l1), qHash(l2));
- l1 << T_BAR;
- l2 << T_BAR;
- QCOMPARE(qHash(l1), qHash(l2));
-}
+ TST_QLIST_CHECK_LEAKS(T)
-void tst_QList::reserve() const
-{
- // Note:
- // This test depends on QList's current behavior that ints are stored in the array itself.
- // This test would not work for QList<Complex>.
- int capacity = 100;
- QList<int> list;
- list.reserve(capacity);
- list << 0;
- int *data = &list[0];
+ {
+ QList<T> v(10);
+ v.reserve(15);
+ QVERIFY(v.size() < v.capacity());
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.end());
+
+ v.resize(15);
+ for (int i = 0; i < copy.size(); ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
- for (int i = 1; i < capacity; i++) {
- list << i;
- QCOMPARE(&list.at(0), data);
+ {
+ QList<T> v(10);
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.end());
+
+ v.resize(10);
+ for (int i = 0; i < 10; ++i)
+ QCOMPARE(*reference[i], copy[i]);
}
- QList<int> copy = list;
- list.reserve(capacity / 2);
- QCOMPARE(list.size(), capacity); // we didn't shrink the size!
+ {
+ QList<T> v(10);
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.end());
+
+ v.resize(5);
+ for (int i = 0; i < 5; ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
- copy = list;
- list.reserve(capacity * 2);
- QCOMPARE(list.size(), capacity);
- QVERIFY(&list.at(0) != data);
+ // special case due to prepend:
+ {
+ QList<T> v;
+ v.reserve(20);
+ const qsizetype capacity = v.capacity();
+ const T *ptr = v.constData();
+ v.prepend(SimpleValue<T>::at(0)); // now there's free space at begin
+ v.resize(10);
+ QVERIFY(v.size() < v.capacity());
+ // here we abuse the internal details of QList. since there's enough
+ // free space, QList should've only rearranged the data in memory,
+ // without reallocating.
+ QCOMPARE(capacity, v.capacity()); // otherwise cannot rely on ptr
+ const qsizetype freeSpaceAtBegin = v.constData() - ptr;
+ const qsizetype freeSpaceAtEnd = v.capacity() - v.size() - freeSpaceAtBegin;
+ QVERIFY(freeSpaceAtEnd > 0); // otherwise this test is useless
+ QVERIFY(v.size() + freeSpaceAtBegin + freeSpaceAtEnd == v.capacity());
+ int k = 0;
+ std::generate(v.begin(), v.end(), [&k]() { return SimpleValue<T>::at(k++); });
+ auto [copy, reference] = qlistCopyAndReferenceFromRange(v.begin(), v.end());
+
+ v.resize(v.size() + freeSpaceAtEnd);
+ for (int i = 0; i < copy.size(); ++i)
+ QCOMPARE(*reference[i], copy[i]);
+ }
}
-QTEST_APPLESS_MAIN(tst_QList)
+QTEST_MAIN(tst_QList)
#include "tst_qlist.moc"
diff --git a/tests/auto/corelib/tools/qlist_strictiterators/qlist_strictiterators.pro b/tests/auto/corelib/tools/qlist_strictiterators/qlist_strictiterators.pro
deleted file mode 100644
index e39ad38919..0000000000
--- a/tests/auto/corelib/tools/qlist_strictiterators/qlist_strictiterators.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-include(../qlist/qlist.pro)
-TARGET = tst_qlist_strictiterators
-DEFINES += QT_STRICT_ITERATORS tst_QList=tst_QList_StrictIterators
diff --git a/tests/auto/corelib/tools/qlocale/BLACKLIST b/tests/auto/corelib/tools/qlocale/BLACKLIST
deleted file mode 100644
index 3eac7c10ed..0000000000
--- a/tests/auto/corelib/tools/qlocale/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[formatTimeZone]
-osx
diff --git a/tests/auto/corelib/tools/qlocale/qlocale.pro b/tests/auto/corelib/tools/qlocale/qlocale.pro
deleted file mode 100644
index 5161200260..0000000000
--- a/tests/auto/corelib/tools/qlocale/qlocale.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS += test
-!winrt: SUBDIRS+=syslocaleapp
diff --git a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.cpp b/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.cpp
deleted file mode 100644
index 1e1bcc8c5f..0000000000
--- a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QLocale>
-#include <QCoreApplication>
-#include <QTextStream>
-
-int main(int argc, char** argv)
-{
- QCoreApplication app(argc, argv);
- QLocale l;
- QTextStream str(stdout);
- str << l.name();
-
- return 0;
-}
diff --git a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro b/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro
deleted file mode 100644
index 3e283c05a4..0000000000
--- a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-SOURCES += syslocaleapp.cpp
-DESTDIR = ./
-
-CONFIG += cmdline
-
-QT = core
-
diff --git a/tests/auto/corelib/tools/qlocale/test/test.pro b/tests/auto/corelib/tools/qlocale/test/test.pro
deleted file mode 100644
index f7243e99a7..0000000000
--- a/tests/auto/corelib/tools/qlocale/test/test.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-CONFIG += console testcase
-QT = core testlib core-private
-embedded: QT += gui
-SOURCES = ../tst_qlocale.cpp
-
-!qtConfig(doubleconversion):!qtConfig(system-doubleconversion) {
- DEFINES += QT_NO_DOUBLECONVERSION
-}
-
-TARGET = ../tst_qlocale
-win32 {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qlocale
- } else {
- TARGET = ../../release/tst_qlocale
- }
-}
-
-!android:!winrt: TEST_HELPER_INSTALLS = ../syslocaleapp/syslocaleapp
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
deleted file mode 100644
index 230ae4d8aa..0000000000
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ /dev/null
@@ -1,2998 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-#include <math.h>
-#include <qdebug.h>
-#include <qdir.h>
-#include <qfileinfo.h>
-#include <QScopedArrayPointer>
-#include <qtextcodec.h>
-#include <qdatetime.h>
-#if QT_CONFIG(process)
-# include <qprocess.h>
-#endif
-#include <float.h>
-#include <locale.h>
-
-#include <qlocale.h>
-#include <private/qlocale_p.h>
-#include <private/qlocale_tools_p.h>
-#include <qnumeric.h>
-
-#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
-# define QT_USE_FENV
-#endif
-
-#ifdef QT_USE_FENV
-# include <fenv.h>
-#endif
-
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
-# include <stdlib.h>
-#endif
-
-Q_DECLARE_METATYPE(QLocale::FormatType)
-
-class tst_QLocale : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QLocale();
-
-private slots:
- void initTestCase();
- void cleanupTestCase();
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- void windowsDefaultLocale();
-#endif
-#ifdef Q_OS_MAC
- void macDefaultLocale();
-#endif
-
- void ctor();
- void emptyCtor_data();
- void emptyCtor();
- void consistentC();
- void matchingLocales();
- void stringToDouble_data();
- void stringToDouble();
- void stringToFloat_data();
- void stringToFloat();
- void doubleToString_data();
- void doubleToString();
- void strtod_data();
- void strtod();
- void long_long_conversion_data();
- void long_long_conversion();
- void long_long_conversion_extra();
- void testInfAndNan();
- void fpExceptions();
- void negativeZero();
- void dayOfWeek();
- void dayOfWeek_data();
- void formatDate();
- void formatDate_data();
- void formatTime();
- void formatTime_data();
- void formatDateTime();
- void formatDateTime_data();
- void formatTimeZone();
- void toDateTime_data();
- void toDateTime();
- void negativeNumbers();
- void numberOptions();
- void dayName_data();
- void dayName();
- void standaloneDayName_data();
- void standaloneDayName();
- void underflowOverflow();
-
- void dateFormat();
- void timeFormat();
- void dateTimeFormat();
- void monthName();
- void standaloneMonthName();
-
- void defaultNumberingSystem_data();
- void defaultNumberingSystem();
-
- void ampm_data();
- void ampm();
- void currency();
- void quoteString();
- void uiLanguages();
- void weekendDays();
- void listPatterns();
-
- void measurementSystems_data();
- void measurementSystems();
- void QTBUG_26035_positivesign();
-
- void textDirection_data();
- void textDirection();
-
- void formattedDataSize_data();
- void formattedDataSize();
- void bcp47Name_data();
- void bcp47Name();
-
- void systemLocale_data();
- void systemLocale();
-
- // *** ORDER-DEPENDENCY *** (This Is Bad.)
- // Test order is determined by order of declaration here: *all* tests that
- // QLocale::setDefault() *must* appear *after* all other tests !
- void defaulted_ctor(); // This one must be the first of these.
- void legacyNames();
- void unixLocaleName_data();
- void unixLocaleName();
- void testNames_data();
- void testNames();
- // DO NOT add tests here unless they QLocale::setDefault(); see above.
-private:
- QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
- QString m_sysapp;
- QStringList cleanEnv;
- bool europeanTimeZone;
- void toReal_data();
-
- class TransientLocale
- {
- const int m_category;
- const char *const m_prior;
- public:
- TransientLocale(int category, const char *locale)
- : m_category(category), m_prior(setlocale(category, locale)) {}
- ~TransientLocale() { setlocale(m_category, m_prior); }
- };
-};
-
-tst_QLocale::tst_QLocale()
-{
- qRegisterMetaType<QLocale::FormatType>("QLocale::FormatType");
-
- // Test if in Central European Time zone
- uint x1 = QDateTime(QDate(1990, 1, 1), QTime()).toSecsSinceEpoch();
- uint x2 = QDateTime(QDate(1990, 6, 1), QTime()).toSecsSinceEpoch();
- europeanTimeZone = (x1 == 631148400 && x2 == 644191200);
-}
-
-void tst_QLocale::initTestCase()
-{
-#if QT_CONFIG(process)
-# ifdef Q_OS_ANDROID
- m_sysapp = QCoreApplication::applicationDirPath() + "/libsyslocaleapp.so";
-# else // !defined(Q_OS_ANDROID)
- const QString syslocaleapp_dir = QFINDTESTDATA("syslocaleapp");
- QVERIFY2(!syslocaleapp_dir.isEmpty(),
- qPrintable(QStringLiteral("Cannot find 'syslocaleapp' starting from ")
- + QDir::toNativeSeparators(QDir::currentPath())));
- m_sysapp = syslocaleapp_dir + QStringLiteral("/syslocaleapp");
-# ifdef Q_OS_WIN
- m_sysapp += QStringLiteral(".exe");
-# endif
-# endif // Q_OS_ANDROID
- const QFileInfo fi(m_sysapp);
- QVERIFY2(fi.exists() && fi.isExecutable(),
- qPrintable(QDir::toNativeSeparators(m_sysapp)
- + QStringLiteral(" does not exist or is not executable.")));
-
- // Get an environment free of any locale-related variables
- cleanEnv.clear();
- foreach (QString const& entry, QProcess::systemEnvironment()) {
- if (entry.startsWith("LANG=") || entry.startsWith("LC_") || entry.startsWith("LANGUAGE="))
- continue;
- cleanEnv << entry;
- }
-#endif // QT_CONFIG(process)
-}
-
-void tst_QLocale::cleanupTestCase()
-{}
-
-void tst_QLocale::ctor()
-{
- QLocale default_locale = QLocale::system();
- QLocale::Language default_lang = default_locale.language();
- QLocale::Country default_country = default_locale.country();
-
- qDebug("Default: %s/%s", QLocale::languageToString(default_lang).toLatin1().constData(),
- QLocale::countryToString(default_country).toLatin1().constData());
-
- {
- QLocale l;
- QVERIFY(l.language() == default_lang);
- QVERIFY(l.country() == default_country);
- }
-
-#define TEST_CTOR(req_lang, req_script, req_country, exp_lang, exp_script, exp_country) \
- { \
- QLocale l(QLocale::req_lang, QLocale::req_script, QLocale::req_country); \
- QCOMPARE((int)l.language(), (int)exp_lang); \
- QCOMPARE((int)l.script(), (int)exp_script); \
- QCOMPARE((int)l.country(), (int)exp_country); \
- }
-
- // Exact matches
- TEST_CTOR(Chinese, SimplifiedHanScript, China,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, TraditionalHanScript, Taiwan,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
- TEST_CTOR(Chinese, TraditionalHanScript, HongKong,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
-
- // Best match for AnyCountry
- TEST_CTOR(Chinese, SimplifiedHanScript, AnyCountry,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, TraditionalHanScript, AnyCountry,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
-
- // Best match for AnyScript (and change country to supported one, if necessary)
- TEST_CTOR(Chinese, AnyScript, China,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, AnyScript, Taiwan,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
- TEST_CTOR(Chinese, AnyScript, HongKong,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
- TEST_CTOR(Chinese, AnyScript, UnitedStates,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
-
- // Fully-specified not found; find best alternate country
- TEST_CTOR(Chinese, SimplifiedHanScript, Taiwan,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, SimplifiedHanScript, UnitedStates,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, TraditionalHanScript, China,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
- TEST_CTOR(Chinese, TraditionalHanScript, UnitedStates,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
-
- // Fully-specified not found; find best alternate script
- TEST_CTOR(Chinese, LatinScript, China,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, LatinScript, Taiwan,
- QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
-
- // Fully-specified not found; find best alternate country and script
- TEST_CTOR(Chinese, LatinScript, UnitedStates,
- QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
-
-#undef TEST_CTOR
-}
-
-void tst_QLocale::defaulted_ctor()
-{
- QLocale default_locale = QLocale::system();
- QLocale::Language default_lang = default_locale.language();
- QLocale::Country default_country = default_locale.country();
-
- qDebug("Default: %s/%s", QLocale::languageToString(default_lang).toLatin1().constData(),
- QLocale::countryToString(default_country).toLatin1().constData());
-
- {
- QLocale l(QLocale::C, QLocale::AnyCountry);
- QCOMPARE(l.language(), QLocale::C);
- QCOMPARE(l.country(), QLocale::AnyCountry);
- }
-
-#define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \
- { \
- QLocale l(QLocale::req_lang, QLocale::req_country); \
- QCOMPARE((int)l.language(), (int)exp_lang); \
- QCOMPARE((int)l.country(), (int)exp_country); \
- }
-
- TEST_CTOR(AnyLanguage, AnyCountry, default_lang, default_country)
- TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(Aymara, AnyCountry, default_lang, default_country)
- TEST_CTOR(Aymara, France, default_lang, default_country)
-
- TEST_CTOR(English, AnyCountry, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(French, France, QLocale::French, QLocale::France)
- TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(Spanish, LatinAmerica, QLocale::Spanish,
- QLocale::LatinAmerica)
-
- QLocale::setDefault(QLocale(QLocale::English, QLocale::France));
-
- {
- QLocale l;
- QVERIFY(l.language() == QLocale::English);
- QVERIFY(l.country() == QLocale::UnitedStates);
- }
-
- TEST_CTOR(French, France, QLocale::French, QLocale::France)
- TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(French, France, QLocale::French, QLocale::France)
- TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(Aymara, AnyCountry, QLocale::English, QLocale::UnitedStates)
-
- QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom));
-
- {
- QLocale l;
- QVERIFY(l.language() == QLocale::English);
- QVERIFY(l.country() == QLocale::UnitedKingdom);
- }
-
- TEST_CTOR(French, France, QLocale::French, QLocale::France)
- TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry)
-
- QLocale::setDefault(QLocale(QLocale::Aymara, QLocale::France));
-
- {
- QLocale l;
- QVERIFY(l.language() == QLocale::English);
- QVERIFY(l.country() == QLocale::UnitedKingdom);
- }
-
- TEST_CTOR(Aymara, AnyCountry, QLocale::English, QLocale::UnitedKingdom)
- TEST_CTOR(Aymara, France, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(English, AnyCountry, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(French, France, QLocale::French, QLocale::France)
- TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry)
-
- QLocale::setDefault(QLocale(QLocale::Aymara, QLocale::AnyCountry));
-
- {
- QLocale l;
- QVERIFY(l.language() == QLocale::English);
- QVERIFY(l.country() == QLocale::UnitedKingdom);
- }
-
- TEST_CTOR(Aymara, AnyCountry, QLocale::English, QLocale::UnitedKingdom)
- TEST_CTOR(Aymara, France, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(English, AnyCountry, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates)
- TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom)
-
- TEST_CTOR(French, France, QLocale::French, QLocale::France)
- TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry)
-
- TEST_CTOR(Arabic, AnyCountry, QLocale::Arabic, QLocale::Egypt)
- TEST_CTOR(Dutch, AnyCountry, QLocale::Dutch, QLocale::Netherlands)
- TEST_CTOR(German, AnyCountry, QLocale::German, QLocale::Germany)
- TEST_CTOR(Greek, AnyCountry, QLocale::Greek, QLocale::Greece)
- TEST_CTOR(Malay, AnyCountry, QLocale::Malay, QLocale::Malaysia)
- TEST_CTOR(Persian, AnyCountry, QLocale::Persian, QLocale::Iran)
- TEST_CTOR(Portuguese, AnyCountry, QLocale::Portuguese, QLocale::Brazil)
- TEST_CTOR(Serbian, AnyCountry, QLocale::Serbian, QLocale::Serbia)
- TEST_CTOR(Somali, AnyCountry, QLocale::Somali, QLocale::Somalia)
- TEST_CTOR(Spanish, AnyCountry, QLocale::Spanish, QLocale::Spain)
- TEST_CTOR(Swedish, AnyCountry, QLocale::Swedish, QLocale::Sweden)
- TEST_CTOR(Uzbek, AnyCountry, QLocale::Uzbek, QLocale::Uzbekistan)
-
-#undef TEST_CTOR
-#define TEST_CTOR(req_lc, exp_lang, exp_country) \
- { \
- QLocale l(req_lc); \
- QVERIFY2(l.language() == QLocale::exp_lang \
- && l.country() == QLocale::exp_country, \
- QString("requested: \"" + QString(req_lc) + "\", got: " \
- + QLocale::languageToString(l.language()) \
- + QLatin1Char('/') \
- + QLocale::countryToString(l.country())).toLatin1().constData()); \
- QCOMPARE(l, QLocale(QLocale::exp_lang, QLocale::exp_country)); \
- QCOMPARE(qHash(l), qHash(QLocale(QLocale::exp_lang, QLocale::exp_country))); \
- }
-
- QLocale::setDefault(QLocale(QLocale::C));
-
- TEST_CTOR("C", C, AnyCountry)
- TEST_CTOR("bla", C, AnyCountry)
- TEST_CTOR("zz", C, AnyCountry)
- TEST_CTOR("zz_zz", C, AnyCountry)
- TEST_CTOR("zz...", C, AnyCountry)
- TEST_CTOR("", C, AnyCountry)
- TEST_CTOR("en/", C, AnyCountry)
- TEST_CTOR(QString::null, C, AnyCountry)
- TEST_CTOR("en", English, UnitedStates)
- TEST_CTOR("en", English, UnitedStates)
- TEST_CTOR("en.", English, UnitedStates)
- TEST_CTOR("en@", English, UnitedStates)
- TEST_CTOR("en.@", English, UnitedStates)
- TEST_CTOR("en_", English, UnitedStates)
- TEST_CTOR("en_U", English, UnitedStates)
- TEST_CTOR("en_.", English, UnitedStates)
- TEST_CTOR("en_.@", English, UnitedStates)
- TEST_CTOR("en.bla", English, UnitedStates)
- TEST_CTOR("en@bla", English, UnitedStates)
- TEST_CTOR("en_blaaa", English, UnitedStates)
- TEST_CTOR("en_zz", English, UnitedStates)
- TEST_CTOR("en_GB", English, UnitedKingdom)
- TEST_CTOR("en_GB.bla", English, UnitedKingdom)
- TEST_CTOR("en_GB@.bla", English, UnitedKingdom)
- TEST_CTOR("en_GB@bla", English, UnitedKingdom)
- TEST_CTOR("en-GB", English, UnitedKingdom)
- TEST_CTOR("en-GB@bla", English, UnitedKingdom)
- TEST_CTOR("eo", Esperanto, World)
- TEST_CTOR("yi", Yiddish, World)
-
- QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal);
- TEST_CTOR("no", Norwegian, Norway)
- TEST_CTOR("nb", Norwegian, Norway)
- TEST_CTOR("nn", NorwegianNynorsk, Norway)
- TEST_CTOR("no_NO", Norwegian, Norway)
- TEST_CTOR("nb_NO", Norwegian, Norway)
- TEST_CTOR("nn_NO", NorwegianNynorsk, Norway)
- TEST_CTOR("es_ES", Spanish, Spain)
- TEST_CTOR("es_419", Spanish, LatinAmerica)
- TEST_CTOR("es-419", Spanish, LatinAmerica)
- TEST_CTOR("fr_MA", French, Morocco)
-
- // test default countries for languages
- TEST_CTOR("zh", Chinese, China)
- TEST_CTOR("zh-Hans", Chinese, China)
- TEST_CTOR("ne", Nepali, Nepal)
-
-#undef TEST_CTOR
-#define TEST_CTOR(req_lc, exp_lang, exp_script, exp_country) \
- { \
- QLocale l(req_lc); \
- QVERIFY2(l.language() == QLocale::exp_lang \
- && l.script() == QLocale::exp_script \
- && l.country() == QLocale::exp_country, \
- QString("requested: \"" + QString(req_lc) + "\", got: " \
- + QLocale::languageToString(l.language()) \
- + QLatin1Char('/') + QLocale::scriptToString(l.script()) \
- + QLatin1Char('/') + QLocale::countryToString(l.country())).toLatin1().constData()); \
- }
-
- TEST_CTOR("zh_CN", Chinese, SimplifiedHanScript, China)
- TEST_CTOR("zh_Hans_CN", Chinese, SimplifiedHanScript, China)
- TEST_CTOR("zh_Hans", Chinese, SimplifiedHanScript, China)
- TEST_CTOR("zh_Hant", Chinese, TraditionalHanScript, Taiwan)
- TEST_CTOR("zh_Hans_MO", Chinese, SimplifiedHanScript, Macau)
- TEST_CTOR("zh_Hant_MO", Chinese, TraditionalHanScript, Macau)
- TEST_CTOR("az_Latn_AZ", Azerbaijani, LatinScript, Azerbaijan)
- TEST_CTOR("ha_NG", Hausa, LatinScript, Nigeria)
-
- TEST_CTOR("ru", Russian, CyrillicScript, RussianFederation)
- TEST_CTOR("ru_Cyrl", Russian, CyrillicScript, RussianFederation)
-
-#undef TEST_CTOR
-}
-
-#if QT_CONFIG(process)
-static inline bool runSysApp(const QString &binary,
- const QStringList &env,
- QString *output,
- QString *errorMessage)
-{
- output->clear();
- errorMessage->clear();
- QProcess process;
- process.setEnvironment(env);
- process.start(binary);
- process.closeWriteChannel();
- if (!process.waitForStarted()) {
- *errorMessage = QLatin1String("Cannot start '") + binary
- + QLatin1String("': ") + process.errorString();
- return false;
- }
- if (!process.waitForFinished()) {
- process.kill();
- *errorMessage = QStringLiteral("Timeout waiting for ") + binary;
- return false;
- }
- *output = QString::fromLocal8Bit(process.readAllStandardOutput());
- return true;
-}
-
-static inline bool runSysAppTest(const QString &binary,
- QStringList baseEnv,
- const QString &requestedLocale,
- const QString &expectedOutput,
- QString *errorMessage)
-{
- QString output;
- baseEnv.append(QStringLiteral("LANG=") + requestedLocale);
- if (!runSysApp(binary, baseEnv, &output, errorMessage))
- return false;
-
- if (output.isEmpty()) {
- *errorMessage = QLatin1String("Empty output received for requested '") + requestedLocale
- + QLatin1String("' (expected '") + expectedOutput + QLatin1String("')");
- return false;
- }
- if (output != expectedOutput) {
- *errorMessage = QLatin1String("Output mismatch for requested '") + requestedLocale
- + QLatin1String("': Expected '") + expectedOutput + QLatin1String("', got '")
- + output + QLatin1String("'");
- return false;
- }
- return true;
-}
-#endif
-
-void tst_QLocale::emptyCtor_data()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#endif
-#ifdef Q_OS_ANDROID
- QSKIP("This test crashes on Android");
-#endif
-
- QTest::addColumn<QString>("expected");
-
-#define ADD_CTOR_TEST(give, expect) QTest::newRow(give) << QStringLiteral(expect);
-
- // For format and meaning, see:
- // http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
- // Note that the accepted values for fields are implementation-dependent;
- // the template is language[_territory][.codeset][@modifier]
-
- // Vanilla:
- ADD_CTOR_TEST("C", "C");
-
- // Standard forms:
- ADD_CTOR_TEST("en", "en_US");
- ADD_CTOR_TEST("en_GB", "en_GB");
- ADD_CTOR_TEST("de", "de_DE");
- // Norsk has some quirks:
- ADD_CTOR_TEST("no", "nb_NO");
- ADD_CTOR_TEST("nb", "nb_NO");
- ADD_CTOR_TEST("nn", "nn_NO");
- ADD_CTOR_TEST("no_NO", "nb_NO");
- ADD_CTOR_TEST("nb_NO", "nb_NO");
- ADD_CTOR_TEST("nn_NO", "nn_NO");
-
- // Not too fussy about case:
- ADD_CTOR_TEST("DE", "de_DE");
- ADD_CTOR_TEST("EN", "en_US");
-
- // Invalid fields
- ADD_CTOR_TEST("bla", "C");
- ADD_CTOR_TEST("zz", "C");
- ADD_CTOR_TEST("zz_zz", "C");
- ADD_CTOR_TEST("zz...", "C");
- ADD_CTOR_TEST("en.bla", "en_US");
-#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer))
- // See QTBUG-69875
- ADD_CTOR_TEST("en@bla", "en_US");
-#endif
- ADD_CTOR_TEST("en_blaaa", "en_US");
- ADD_CTOR_TEST("en_zz", "en_US");
- ADD_CTOR_TEST("en_GB.bla", "en_GB");
- ADD_CTOR_TEST("en_GB@.bla", "en_GB");
- ADD_CTOR_TEST("en_GB@bla", "en_GB");
-
- // Empty optional fields, but with punctuators supplied
- ADD_CTOR_TEST("en.", "en_US");
-#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer))
- // See QTBUG-69875
- ADD_CTOR_TEST("en@", "en_US");
-#endif
- ADD_CTOR_TEST("en.@", "en_US");
- ADD_CTOR_TEST("en_", "en_US");
- ADD_CTOR_TEST("en_.", "en_US");
- ADD_CTOR_TEST("en_.@", "en_US");
-#undef ADD_CTOR_TEST
-
-#if QT_CONFIG(process) // for runSysApp
- // Get default locale.
- QString defaultLoc;
- QString errorMessage;
- if (runSysApp(m_sysapp, cleanEnv, &defaultLoc, &errorMessage)) {
-#define ADD_CTOR_TEST(give) QTest::newRow(give) << defaultLoc;
- ADD_CTOR_TEST("en/");
- ADD_CTOR_TEST("asdfghj");
- ADD_CTOR_TEST("123456");
-#undef ADD_CTOR_TEST
- } else {
- qDebug() << "Skipping tests based on default locale" << qPrintable(errorMessage);
- }
-#endif // process
-}
-
-void tst_QLocale::emptyCtor()
-{
-#if QT_CONFIG(process) // for runSysAppTest
- QLatin1String request(QTest::currentDataTag());
- QFETCH(QString, expected);
-
- // Test constructor without arguments (see syslocaleapp/syslocaleapp.cpp)
- // Needs separate process because of caching of the system locale.
- QString errorMessage;
- QVERIFY2(runSysAppTest(m_sysapp, cleanEnv, request, expected, &errorMessage),
- qPrintable(errorMessage));
-
-#else
- // This won't be called, as _data() skipped out early.
-#endif // process
-}
-
-void tst_QLocale::legacyNames()
-{
- QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal);
- QLocale::setDefault(QLocale(QLocale::C));
-
-#define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \
- { \
- QLocale l(QLocale::req_lang, QLocale::req_country); \
- QCOMPARE((int)l.language(), (int)QLocale::exp_lang); \
- QCOMPARE((int)l.country(), (int)QLocale::exp_country); \
- }
-
- TEST_CTOR(Moldavian, Moldova, Romanian, Moldova)
- TEST_CTOR(Norwegian, AnyCountry, Norwegian, Norway)
- TEST_CTOR(SerboCroatian, Montenegro, Serbian, Montenegro)
- TEST_CTOR(Tagalog, AnyCountry, Filipino, Philippines)
-
-#undef TEST_CTOR
-
-#define TEST_CTOR(req_lc, exp_lang, exp_country) \
- { \
- QLocale l(req_lc); \
- QVERIFY2(l.language() == QLocale::exp_lang \
- && l.country() == QLocale::exp_country, \
- QString("requested: \"" + QString(req_lc) + "\", got: " \
- + QLocale::languageToString(l.language()) \
- + QLatin1Char('/') \
- + QLocale::countryToString(l.country())).toLatin1().constData()); \
- }
-
- TEST_CTOR("mo_MD", Romanian, Moldova)
- TEST_CTOR("no", Norwegian, Norway)
- TEST_CTOR("sh_ME", Serbian, Montenegro)
- TEST_CTOR("tl", Filipino, Philippines)
- TEST_CTOR("iw", Hebrew, Israel)
- TEST_CTOR("in", Indonesian, Indonesia)
-#undef TEST_CTOR
-}
-
-void tst_QLocale::consistentC()
-{
- const QLocale c(QLocale::C);
- QCOMPARE(c, QLocale::c());
- QCOMPARE(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyCountry));
- QVERIFY(QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
- QLocale::AnyCountry).contains(c));
-}
-
-void tst_QLocale::matchingLocales()
-{
- const QLocale c(QLocale::C);
- const QLocale ru_RU(QLocale::Russian, QLocale::Russia);
-
- QList<QLocale> locales = QLocale::matchingLocales(QLocale::C, QLocale::AnyScript, QLocale::AnyCountry);
- QCOMPARE(locales.size(), 1);
- QVERIFY(locales.contains(c));
-
- locales = QLocale::matchingLocales(QLocale::Russian, QLocale::CyrillicScript, QLocale::Russia);
- QCOMPARE(locales.size(), 1);
- QVERIFY(locales.contains(ru_RU));
-
- locales = QLocale::matchingLocales(QLocale::Russian, QLocale::AnyScript, QLocale::AnyCountry);
- QVERIFY(!locales.isEmpty());
- QVERIFY(!locales.contains(c));
- QVERIFY(locales.contains(ru_RU));
-
- locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::CyrillicScript, QLocale::AnyCountry);
- QVERIFY(!locales.isEmpty());
- QVERIFY(!locales.contains(c));
- QVERIFY(locales.contains(ru_RU));
-
- locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::Russia);
- QVERIFY(!locales.isEmpty());
- QVERIFY(!locales.contains(c));
- QVERIFY(locales.contains(ru_RU));
-}
-
-void tst_QLocale::unixLocaleName_data()
-{
- QTest::addColumn<QLocale::Language>("lang");
- QTest::addColumn<QLocale::Country>("land");
- QTest::addColumn<QString>("expect");
-
-#define ADDROW(nom, lang, land, name) \
- QTest::newRow(nom) << QLocale::lang << QLocale::land << QStringLiteral(name)
-
- ADDROW("C_any", C, AnyCountry, "C");
- ADDROW("en_any", English, AnyCountry, "en_US");
- ADDROW("en_GB", English, UnitedKingdom, "en_GB");
- ADDROW("ay_GB", Aymara, UnitedKingdom, "C");
-#undef ADDROW
-}
-
-void tst_QLocale::unixLocaleName()
-{
- QFETCH(QLocale::Language, lang);
- QFETCH(QLocale::Country, land);
- QFETCH(QString, expect);
-
- QLocale::setDefault(QLocale(QLocale::C));
-
- QLocale locale(lang, land);
- QCOMPARE(locale.name(), expect);
-}
-
-void tst_QLocale::toReal_data()
-{
- QTest::addColumn<QString>("locale_name");
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<bool>("good");
- QTest::addColumn<double>("num");
-
- QTest::newRow("C 1") << QString("C") << QString("1") << true << 1.0;
- QTest::newRow("C 1.0") << QString("C") << QString("1.0") << true << 1.0;
- QTest::newRow("C 1.234") << QString("C") << QString("1.234") << true << 1.234;
- QTest::newRow("C 1.234e-10") << QString("C") << QString("1.234e-10") << true << 1.234e-10;
- QTest::newRow("C 1.234E10") << QString("C") << QString("1.234E10") << true << 1.234e10;
- QTest::newRow("C 1e10") << QString("C") << QString("1e10") << true << 1.0e10;
- QTest::newRow("C 1e310") << QString("C") << QString("1e310") << false << std::numeric_limits<double>::infinity();
- QTest::newRow("C 1E310") << QString("C") << QString("1E310") << false << std::numeric_limits<double>::infinity();
- QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0;
- QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0;
- QTest::newRow("C 1 ") << QString("C") << QString("1 ") << true << 1.0;
- QTest::newRow("C 1 ") << QString("C") << QString("1 ") << true << 1.0;
-
- QTest::newRow("C 1,") << QString("C") << QString("1,") << false << 0.0;
- QTest::newRow("C 1,2") << QString("C") << QString("1,2") << false << 0.0;
- QTest::newRow("C 1,23") << QString("C") << QString("1,23") << false << 0.0;
- QTest::newRow("C 1,234") << QString("C") << QString("1,234") << true << 1234.0;
- QTest::newRow("C 1,234,") << QString("C") << QString("1,234,") << false << 0.0;
- QTest::newRow("C 1,234,5") << QString("C") << QString("1,234,5") << false << 0.0;
- QTest::newRow("C 1,234,56") << QString("C") << QString("1,234,56") << false << 0.0;
- QTest::newRow("C 1,234,567") << QString("C") << QString("1,234,567") << true << 1234567.0;
- QTest::newRow("C 1,234,567.") << QString("C") << QString("1,234,567.") << true << 1234567.0;
- QTest::newRow("C 1,234,567.8") << QString("C") << QString("1,234,567.8") << true << 1234567.8;
- QTest::newRow("C 1,234567.8") << QString("C") << QString("1,234567.8") << false << 0.0;
- QTest::newRow("C 12,34567.8") << QString("C") << QString("12,34567.8") << false << 0.0;
- QTest::newRow("C 1234,567.8") << QString("C") << QString("1234,567.8") << false << 0.0;
- QTest::newRow("C 1234567.8") << QString("C") << QString("1234567.8") << true << 1234567.8;
- QTest::newRow("C ,") << QString("C") << QString(",") << false << 0.0;
- QTest::newRow("C ,123") << QString("C") << QString(",123") << false << 0.0;
- QTest::newRow("C ,3") << QString("C") << QString(",3") << false << 0.0;
- QTest::newRow("C , 3") << QString("C") << QString(", 3") << false << 0.0;
- QTest::newRow("C , 3") << QString("C") << QString(", 3") << false << 0.0;
- QTest::newRow("C , 3.2") << QString("C") << QString(", 3.2") << false << 0.0;
- QTest::newRow("C , 3.2e2") << QString("C") << QString(", 3.2e2") << false << 0.0;
- QTest::newRow("C , e2") << QString("C") << QString(", e2") << false << 0.0;
- QTest::newRow("C 1,,234") << QString("C") << QString("1,,234") << false << 0.0;
-
- QTest::newRow("C empty") << QString("C") << QString("") << false << 0.0;
- QTest::newRow("C null") << QString("C") << QString() << false << 0.0;
- QTest::newRow("C .") << QString("C") << QString(".") << false << 0.0;
- QTest::newRow("C 1e") << QString("C") << QString("1e") << false << 0.0;
- QTest::newRow("C 1,0") << QString("C") << QString("1,0") << false << 0.0;
- QTest::newRow("C 1,000") << QString("C") << QString("1,000") << true << 1000.0;
- QTest::newRow("C 1,000e-6") << QString("C") << QString("1,000e-6") << true << 1000.0e-6;
- QTest::newRow("C 1e1.0") << QString("C") << QString("1e1.0") << false << 0.0;
- QTest::newRow("C 1e+") << QString("C") << QString("1e+") << false << 0.0;
- QTest::newRow("C 1e-") << QString("C") << QString("1e-") << false << 0.0;
-
- QTest::newRow("C .1") << QString("C") << QString(".1") << true << 0.1;
- QTest::newRow("C -.1") << QString("C") << QString("-.1") << true << -0.1;
- QTest::newRow("C 1.") << QString("C") << QString("1.") << true << 1.0;
- QTest::newRow("C 1.E10") << QString("C") << QString("1.E10") << true << 1.0e10;
- QTest::newRow("C 1e+10") << QString("C") << QString("1e+10") << true << 1.0e+10;
-
- QTest::newRow("de_DE 1.") << QString("de_DE") << QString("1.") << false << 0.0;
- QTest::newRow("de_DE 1.2") << QString("de_DE") << QString("1.2") << false << 0.0;
- QTest::newRow("de_DE 1.23") << QString("de_DE") << QString("1.23") << false << 0.0;
- QTest::newRow("de_DE 1.234") << QString("de_DE") << QString("1.234") << true << 1234.0;
- QTest::newRow("de_DE 1.234,") << QString("de_DE") << QString("1.234.") << false << 0.0;
- QTest::newRow("de_DE 1.234.5") << QString("de_DE") << QString("1.234.5") << false << 0.0;
- QTest::newRow("de_DE 1.234.56") << QString("de_DE") << QString("1.234.56") << false << 0.0;
- QTest::newRow("de_DE 1.234.567") << QString("de_DE") << QString("1.234.567") << true << 1234567.0;
- QTest::newRow("de_DE 1.234.567,") << QString("de_DE") << QString("1.234.567,") << true << 1234567.0;
- QTest::newRow("de_DE 1.234.567,8") << QString("de_DE") << QString("1.234.567,8") << true << 1234567.8;
- QTest::newRow("de_DE 1.234567,8") << QString("de_DE") << QString("1.234567,8") << false << 0.0;
- QTest::newRow("de_DE 12.34567,8") << QString("de_DE") << QString("12.34567,8") << false << 0.0;
- QTest::newRow("de_DE 1234.567,8") << QString("de_DE") << QString("1234.567,8") << false << 0.0;
- QTest::newRow("de_DE 1234567,8") << QString("de_DE") << QString("1234567,8") << true << 1234567.8;
- QTest::newRow("de_DE .123") << QString("de_DE") << QString(".123") << false << 0.0;
- QTest::newRow("de_DE .3") << QString("de_DE") << QString(".3") << false << 0.0;
- QTest::newRow("de_DE . 3") << QString("de_DE") << QString(". 3") << false << 0.0;
- QTest::newRow("de_DE . 3") << QString("de_DE") << QString(". 3") << false << 0.0;
- QTest::newRow("de_DE . 3,2") << QString("de_DE") << QString(". 3,2") << false << 0.0;
- QTest::newRow("de_DE . 3,2e2") << QString("de_DE") << QString(". 3,2e2") << false << 0.0;
- QTest::newRow("de_DE . e2") << QString("de_DE") << QString(". e2") << false << 0.0;
- QTest::newRow("de_DE 1..234") << QString("de_DE") << QString("1..234") << false << 0.0;
-
- QTest::newRow("de_DE 1") << QString("de_DE") << QString("1") << true << 1.0;
- QTest::newRow("de_DE 1.0") << QString("de_DE") << QString("1.0") << false << 0.0;
- QTest::newRow("de_DE 1.234e-10") << QString("de_DE") << QString("1.234e-10") << true << 1234.0e-10;
- QTest::newRow("de_DE 1.234E10") << QString("de_DE") << QString("1.234E10") << true << 1234.0e10;
- QTest::newRow("de_DE 1e10") << QString("de_DE") << QString("1e10") << true << 1.0e10;
- QTest::newRow("de_DE .1") << QString("de_DE") << QString(".1") << false << 0.0;
- QTest::newRow("de_DE -.1") << QString("de_DE") << QString("-.1") << false << 0.0;
- QTest::newRow("de_DE 1.E10") << QString("de_DE") << QString("1.E10") << false << 0.0;
- QTest::newRow("de_DE 1e+10") << QString("de_DE") << QString("1e+10") << true << 1.0e+10;
-
- QTest::newRow("de_DE 1,0") << QString("de_DE") << QString("1,0") << true << 1.0;
- QTest::newRow("de_DE 1,234") << QString("de_DE") << QString("1,234") << true << 1.234;
- QTest::newRow("de_DE 1,234e-10") << QString("de_DE") << QString("1,234e-10") << true << 1.234e-10;
- QTest::newRow("de_DE 1,234E10") << QString("de_DE") << QString("1,234E10") << true << 1.234e10;
- QTest::newRow("de_DE ,1") << QString("de_DE") << QString(",1") << true << 0.1;
- QTest::newRow("de_DE -,1") << QString("de_DE") << QString("-,1") << true << -0.1;
- QTest::newRow("de_DE 1,") << QString("de_DE") << QString("1,") << true << 1.0;
- QTest::newRow("de_DE 1,E10") << QString("de_DE") << QString("1,E10") << true << 1.0e10;
-
- QTest::newRow("de_DE empty") << QString("de_DE") << QString("") << false << 0.0;
- QTest::newRow("de_DE null") << QString("de_DE") << QString() << false << 0.0;
- QTest::newRow("de_DE .") << QString("de_DE") << QString(".") << false << 0.0;
- QTest::newRow("de_DE 1e") << QString("de_DE") << QString("1e") << false << 0.0;
- QTest::newRow("de_DE 1e1.0") << QString("de_DE") << QString("1e1.0") << false << 0.0;
- QTest::newRow("de_DE 1e+") << QString("de_DE") << QString("1e+") << false << 0.0;
- QTest::newRow("de_DE 1e-") << QString("de_DE") << QString("1e-") << false << 0.0;
-
- QTest::newRow("C 9,876543") << QString("C") << QString("9,876543") << false << 0.0;
- QTest::newRow("C 9,876543.2") << QString("C") << QString("9,876543.2") << false << 0.0;
- QTest::newRow("C 9,876543e-2") << QString("C") << QString("9,876543e-2") << false << 0.0;
- QTest::newRow("C 9,876543.0e-2") << QString("C") << QString("9,876543.0e-2") << false << 0.0;
-
- QTest::newRow("de_DE 9.876543") << QString("de_DE") << QString("9876.543") << false << 0.0;
- QTest::newRow("de_DE 9.876543,2") << QString("de_DE") << QString("9.876543,2") << false << 0.0;
- QTest::newRow("de_DE 9.876543e-2") << QString("de_DE") << QString("9.876543e-2") << false << 0.0;
- QTest::newRow("de_DE 9.876543,0e-2") << QString("de_DE") << QString("9.876543,0e-2") << false << 0.0;
- QTest::newRow("de_DE 9.876543e--2") << QString("de_DE") << QString("9.876543e")+QChar(8722)+QString("2") << false << 0.0;
- QTest::newRow("de_DE 9.876543,0e--2") << QString("de_DE") << QString("9.876543,0e")+QChar(8722)+QString("2") << false << 0.0;
-}
-
-void tst_QLocale::stringToDouble_data()
-{
- toReal_data();
- if (std::numeric_limits<double>::has_infinity) {
- double huge = std::numeric_limits<double>::infinity();
- QTest::newRow("C inf") << QString("C") << QString("inf") << true << huge;
- QTest::newRow("C +inf") << QString("C") << QString("+inf") << true << +huge;
- QTest::newRow("C -inf") << QString("C") << QString("-inf") << true << -huge;
- // Overflow:
- QTest::newRow("C huge") << QString("C") << QString("2e308") << false << huge;
- QTest::newRow("C -huge") << QString("C") << QString("-2e308") << false << -huge;
- }
- if (std::numeric_limits<double>::has_quiet_NaN)
- QTest::newRow("C qnan") << QString("C") << QString("NaN") << true << std::numeric_limits<double>::quiet_NaN();
-
- // In range (but outside float's range):
- QTest::newRow("C big") << QString("C") << QString("3.5e38") << true << 3.5e38;
- QTest::newRow("C -big") << QString("C") << QString("-3.5e38") << true << -3.5e38;
- QTest::newRow("C small") << QString("C") << QString("1e-45") << true << 1e-45;
- QTest::newRow("C -small") << QString("C") << QString("-1e-45") << true << -1e-45;
-
- // Underflow:
- QTest::newRow("C tiny") << QString("C") << QString("2e-324") << false << 0.;
- QTest::newRow("C -tiny") << QString("C") << QString("-2e-324") << false << 0.;
-}
-
-void tst_QLocale::stringToDouble()
-{
-#define MY_DOUBLE_EPSILON (2.22045e-16) // 1/2^{52}; double has a 53-bit mantissa
-
- QFETCH(QString, locale_name);
- QFETCH(QString, num_str);
- QFETCH(bool, good);
- QFETCH(double, num);
- QStringRef num_strRef = num_str.leftRef(-1);
-
- QLocale locale(locale_name);
- QCOMPARE(locale.name(), locale_name);
-
- bool ok;
- double d = locale.toDouble(num_str, &ok);
- QCOMPARE(ok, good);
-
- {
- // Make sure result is independent of locale:
- TransientLocale ignoreme(LC_ALL, "ar_SA");
- QCOMPARE(locale.toDouble(num_str, &ok), d);
- QCOMPARE(ok, good);
- }
-
- if (ok || std::isinf(num)) {
- // First use fuzzy-compare, then a more precise check:
- QCOMPARE(d, num);
- if (std::isfinite(num)) {
- double diff = d > num ? d - num : num - d;
- QVERIFY(diff <= MY_DOUBLE_EPSILON);
- }
- }
-
- d = locale.toDouble(num_strRef, &ok);
- QCOMPARE(ok, good);
-
- if (ok || std::isinf(num)) {
- QCOMPARE(d, num);
- if (std::isfinite(num)) {
- double diff = d > num ? d - num : num - d;
- QVERIFY(diff <= MY_DOUBLE_EPSILON);
- }
- }
-#undef MY_DOUBLE_EPSILON
-}
-
-void tst_QLocale::stringToFloat_data()
-{
- using Bounds = std::numeric_limits<float>;
- toReal_data();
- const QString C(QStringLiteral("C"));
- if (Bounds::has_infinity) {
- double huge = Bounds::infinity();
- QTest::newRow("C inf") << C << QString("inf") << true << huge;
- QTest::newRow("C +inf") << C << QString("+inf") << true << +huge;
- QTest::newRow("C -inf") << C << QString("-inf") << true << -huge;
- // Overflow float, but not double:
- QTest::newRow("C big") << C << QString("3.5e38") << false << huge;
- QTest::newRow("C -big") << C << QString("-3.5e38") << false << -huge;
- // Overflow double, too:
- QTest::newRow("C huge") << C << QString("2e308") << false << huge;
- QTest::newRow("C -huge") << C << QString("-2e308") << false << -huge;
- }
- if (Bounds::has_quiet_NaN)
- QTest::newRow("C qnan") << C << QString("NaN") << true << double(Bounds::quiet_NaN());
-
- // Minimal float: shouldn't underflow
- QTest::newRow("C float min")
- << C << QLocale::c().toString(Bounds::denorm_min()) << true << double(Bounds::denorm_min());
- QTest::newRow("C float -min")
- << C << QLocale::c().toString(-Bounds::denorm_min()) << true << -double(Bounds::denorm_min());
-
- // Underflow float, but not double:
- QTest::newRow("C small") << C << QString("7e-46") << false << 0.;
- QTest::newRow("C -small") << C << QString("-7e-46") << false << 0.;
- using Double = std::numeric_limits<double>;
- QTest::newRow("C double min")
- << C << QLocale::c().toString(Double::denorm_min()) << false << 0.0;
- QTest::newRow("C double -min")
- << C << QLocale::c().toString(-Double::denorm_min()) << false << 0.0;
-
- // Underflow double, too:
- QTest::newRow("C tiny") << C << QString("2e-324") << false << 0.;
- QTest::newRow("C -tiny") << C << QString("-2e-324") << false << 0.;
-}
-
-void tst_QLocale::stringToFloat()
-{
-#define MY_FLOAT_EPSILON (2.384e-7) // 1/2^{22}; float has a 23-bit mantissa
-
- QFETCH(QString, locale_name);
- QFETCH(QString, num_str);
- QFETCH(bool, good);
- QFETCH(double, num);
- QStringRef num_strRef = num_str.leftRef(-1);
- float fnum = num;
-
- QLocale locale(locale_name);
- QCOMPARE(locale.name(), locale_name);
-
- bool ok;
- float f = locale.toFloat(num_str, &ok);
- QCOMPARE(ok, good);
-
- {
- // Make sure result is independent of locale:
- TransientLocale ignoreme(LC_ALL, "ar_SA");
- QCOMPARE(locale.toFloat(num_str, &ok), f);
- QCOMPARE(ok, good);
- }
-
- if (ok || std::isinf(fnum)) {
- // First use fuzzy-compare, then a more precise check:
- QCOMPARE(f, fnum);
- if (std::isfinite(fnum)) {
- float diff = f > fnum ? f - fnum : fnum - f;
- QVERIFY(diff <= MY_FLOAT_EPSILON);
- }
- }
-
- f = locale.toFloat(num_strRef, &ok);
- QCOMPARE(ok, good);
-
- if (ok || std::isinf(fnum)) {
- QCOMPARE(f, fnum);
- if (std::isfinite(fnum)) {
- float diff = f > fnum ? f - fnum : fnum - f;
- QVERIFY(diff <= MY_FLOAT_EPSILON);
- }
- }
-#undef MY_FLOAT_EPSILON
-}
-
-void tst_QLocale::doubleToString_data()
-{
- QTest::addColumn<QString>("locale_name");
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<double>("num");
- QTest::addColumn<char>("mode");
- QTest::addColumn<int>("precision");
-
- int shortest = QLocale::FloatingPointShortest;
-
- QTest::newRow("C 3.4 f 5") << QString("C") << QString("3.40000") << 3.4 << 'f' << 5;
- QTest::newRow("C 3.4 f 0") << QString("C") << QString("3") << 3.4 << 'f' << 0;
- QTest::newRow("C 3.4 e 5") << QString("C") << QString("3.40000e+00") << 3.4 << 'e' << 5;
- QTest::newRow("C 3.4 e 0") << QString("C") << QString("3e+00") << 3.4 << 'e' << 0;
- QTest::newRow("C 3.4 g 5") << QString("C") << QString("3.4") << 3.4 << 'g' << 5;
- QTest::newRow("C 3.4 g 1") << QString("C") << QString("3") << 3.4 << 'g' << 1;
-
- QTest::newRow("C 3.4 f 1") << QString("C") << QString("3.4") << 3.4 << 'f' << 1;
- QTest::newRow("C 3.4 f -") << QString("C") << QString("3.4") << 3.4 << 'f' << shortest;
- QTest::newRow("C 3.4 e 1") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << 1;
- QTest::newRow("C 3.4 e -") << QString("C") << QString("3.4e+00") << 3.4 << 'e' << shortest;
- QTest::newRow("C 3.4 g 2") << QString("C") << QString("3.4") << 3.4 << 'g' << 2;
- QTest::newRow("C 3.4 g -") << QString("C") << QString("3.4") << 3.4 << 'g' << shortest;
-
- QTest::newRow("de_DE 3,4 f 1") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << 1;
- QTest::newRow("de_DE 3,4 f -") << QString("de_DE") << QString("3,4") << 3.4 << 'f' << shortest;
- QTest::newRow("de_DE 3,4 e 1") << QString("de_DE") << QString("3,4e+00") << 3.4 << 'e' << 1;
- QTest::newRow("de_DE 3,4 e -") << QString("de_DE") << QString("3,4e+00") << 3.4 << 'e' << shortest;
- QTest::newRow("de_DE 3,4 g 2") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << 2;
- QTest::newRow("de_DE 3,4 g -") << QString("de_DE") << QString("3,4") << 3.4 << 'g' << shortest;
-
- QTest::newRow("C 0.035003945 f 12") << QString("C") << QString("0.035003945000") << 0.035003945 << 'f' << 12;
- QTest::newRow("C 0.035003945 f 6") << QString("C") << QString("0.035004") << 0.035003945 << 'f' << 6;
- QTest::newRow("C 0.035003945 e 10") << QString("C") << QString("3.5003945000e-02") << 0.035003945 << 'e' << 10;
- QTest::newRow("C 0.035003945 e 4") << QString("C") << QString("3.5004e-02") << 0.035003945 << 'e' << 4;
- QTest::newRow("C 0.035003945 g 11") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 11;
- QTest::newRow("C 0.035003945 g 5") << QString("C") << QString("0.035004") << 0.035003945 << 'g' << 5;
-
- QTest::newRow("C 0.035003945 f 9") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << 9;
- QTest::newRow("C 0.035003945 f -") << QString("C") << QString("0.035003945") << 0.035003945 << 'f' << shortest;
- QTest::newRow("C 0.035003945 e 7") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << 7;
- QTest::newRow("C 0.035003945 e -") << QString("C") << QString("3.5003945e-02") << 0.035003945 << 'e' << shortest;
- QTest::newRow("C 0.035003945 g 8") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << 8;
- QTest::newRow("C 0.035003945 g -") << QString("C") << QString("0.035003945") << 0.035003945 << 'g' << shortest;
-
- QTest::newRow("de_DE 0,035003945 f 9") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << 9;
- QTest::newRow("de_DE 0,035003945 f -") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'f' << shortest;
- QTest::newRow("de_DE 0,035003945 e 7") << QString("de_DE") << QString("3,5003945e-02") << 0.035003945 << 'e' << 7;
- QTest::newRow("de_DE 0,035003945 e -") << QString("de_DE") << QString("3,5003945e-02") << 0.035003945 << 'e' << shortest;
- QTest::newRow("de_DE 0,035003945 g 8") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << 8;
- QTest::newRow("de_DE 0,035003945 g -") << QString("de_DE") << QString("0,035003945") << 0.035003945 << 'g' << shortest;
-
- QTest::newRow("C 0.000003945 f 12") << QString("C") << QString("0.000003945000") << 0.000003945 << 'f' << 12;
- QTest::newRow("C 0.000003945 f 6") << QString("C") << QString("0.000004") << 0.000003945 << 'f' << 6;
- QTest::newRow("C 0.000003945 e 6") << QString("C") << QString("3.945000e-06") << 0.000003945 << 'e' << 6;
- QTest::newRow("C 0.000003945 e 0") << QString("C") << QString("4e-06") << 0.000003945 << 'e' << 0;
- QTest::newRow("C 0.000003945 g 7") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 7;
- QTest::newRow("C 0.000003945 g 1") << QString("C") << QString("4e-06") << 0.000003945 << 'g' << 1;
-
- QTest::newRow("C 0.000003945 f 9") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << 9;
- QTest::newRow("C 0.000003945 f -") << QString("C") << QString("0.000003945") << 0.000003945 << 'f' << shortest;
- QTest::newRow("C 0.000003945 e 3") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << 3;
- QTest::newRow("C 0.000003945 e -") << QString("C") << QString("3.945e-06") << 0.000003945 << 'e' << shortest;
- QTest::newRow("C 0.000003945 g 4") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << 4;
- QTest::newRow("C 0.000003945 g -") << QString("C") << QString("3.945e-06") << 0.000003945 << 'g' << shortest;
-
- QTest::newRow("de_DE 0,000003945 f 9") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << 9;
- QTest::newRow("de_DE 0,000003945 f -") << QString("de_DE") << QString("0,000003945") << 0.000003945 << 'f' << shortest;
- QTest::newRow("de_DE 0,000003945 e 3") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'e' << 3;
- QTest::newRow("de_DE 0,000003945 e -") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'e' << shortest;
- QTest::newRow("de_DE 0,000003945 g 4") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'g' << 4;
- QTest::newRow("de_DE 0,000003945 g -") << QString("de_DE") << QString("3,945e-06") << 0.000003945 << 'g' << shortest;
-
- QTest::newRow("C 12456789012 f 3") << QString("C") << QString("12456789012.000") << 12456789012.0 << 'f' << 3;
- QTest::newRow("C 12456789012 e 13") << QString("C") << QString("1.2456789012000e+10") << 12456789012.0 << 'e' << 13;
- QTest::newRow("C 12456789012 e 7") << QString("C") << QString("1.2456789e+10") << 12456789012.0 << 'e' << 7;
- QTest::newRow("C 12456789012 g 14") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << 14;
- QTest::newRow("C 12456789012 g 8") << QString("C") << QString("1.2456789e+10") << 12456789012.0 << 'g' << 8;
-
- QTest::newRow("C 12456789012 f 0") << QString("C") << QString("12456789012") << 12456789012.0 << 'f' << 0;
- QTest::newRow("C 12456789012 f -") << QString("C") << QString("12456789012") << 12456789012.0 << 'f' << shortest;
- QTest::newRow("C 12456789012 e 10") << QString("C") << QString("1.2456789012e+10") << 12456789012.0 << 'e' << 10;
- QTest::newRow("C 12456789012 e -") << QString("C") << QString("1.2456789012e+10") << 12456789012.0 << 'e' << shortest;
- QTest::newRow("C 12456789012 g 11") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << 11;
- QTest::newRow("C 12456789012 g -") << QString("C") << QString("12456789012") << 12456789012.0 << 'g' << shortest;
-
- QTest::newRow("de_DE 12456789012 f 0") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'f' << 0;
- QTest::newRow("de_DE 12456789012 f -") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'f' << shortest;
- QTest::newRow("de_DE 12456789012 e 10") << QString("de_DE") << QString("1,2456789012e+10") << 12456789012.0 << 'e' << 10;
- QTest::newRow("de_DE 12456789012 e -") << QString("de_DE") << QString("1,2456789012e+10") << 12456789012.0 << 'e' << shortest;
- QTest::newRow("de_DE 12456789012 g 11") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'g' << 11;
- QTest::newRow("de_DE 12456789012 g -") << QString("de_DE") << QString("12.456.789.012") << 12456789012.0 << 'g' << shortest;
-}
-
-void tst_QLocale::doubleToString()
-{
- QFETCH(QString, locale_name);
- QFETCH(QString, num_str);
- QFETCH(double, num);
- QFETCH(char, mode);
- QFETCH(int, precision);
-
-#ifdef QT_NO_DOUBLECONVERSION
- if (precision == QLocale::FloatingPointShortest)
- QSKIP("'Shortest' double conversion is not that short without libdouble-conversion");
-#endif
-
- const QLocale locale(locale_name);
- QCOMPARE(locale.toString(num, mode, precision), num_str);
-
- TransientLocale ignoreme(LC_ALL, "de_DE");
- QCOMPARE(locale.toString(num, mode, precision), num_str);
-}
-
-void tst_QLocale::strtod_data()
-{
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<double>("num");
- QTest::addColumn<int>("processed");
- QTest::addColumn<bool>("ok");
-
- // plain numbers, success
- QTest::newRow("0") << QString("0") << 0.0 << 1 << true;
- QTest::newRow("0.") << QString("0.") << 0.0 << 2 << true;
- QTest::newRow("0.0") << QString("0.0") << 0.0 << 3 << true;
- QTest::newRow("0e+0") << QString("0e+0") << 0.0 << 4 << true;
- QTest::newRow("0e-0") << QString("0e-0") << 0.0 << 4 << true;
- QTest::newRow("0e+1") << QString("0e+1") << 0.0 << 4 << true;
- QTest::newRow("0e-1") << QString("0e-1") << 0.0 << 4 << true;
- QTest::newRow("0E+0") << QString("0E+0") << 0.0 << 4 << true;
- QTest::newRow("0E-0") << QString("0E-0") << 0.0 << 4 << true;
- QTest::newRow("0E+1") << QString("0E+1") << 0.0 << 4 << true;
- QTest::newRow("0E-1") << QString("0E-1") << 0.0 << 4 << true;
- QTest::newRow("3.4") << QString("3.4") << 3.4 << 3 << true;
- QTest::newRow("0.035003945") << QString("0.035003945") << 0.035003945 << 11 << true;
- QTest::newRow("3.5003945e-2") << QString("3.5003945e-2") << 0.035003945 << 12 << true;
- QTest::newRow("0.000003945") << QString("0.000003945") << 0.000003945 << 11 << true;
- QTest::newRow("3.945e-6") << QString("3.945e-6") << 0.000003945 << 8 << true;
- QTest::newRow("12456789012") << QString("12456789012") << 12456789012.0 << 11 << true;
- QTest::newRow("1.2456789012e10") << QString("1.2456789012e10") << 12456789012.0 << 15 << true;
-
- // starts with junk, fails
- QTest::newRow("a0") << QString("a0") << 0.0 << 0 << false;
- QTest::newRow("a0.") << QString("a0.") << 0.0 << 0 << false;
- QTest::newRow("a0.0") << QString("a0.0") << 0.0 << 0 << false;
- QTest::newRow("a3.4") << QString("a3.4") << 0.0 << 0 << false;
- QTest::newRow("b0.035003945") << QString("b0.035003945") << 0.0 << 0 << false;
- QTest::newRow("c3.5003945e-2") << QString("c3.5003945e-2") << 0.0 << 0 << false;
- QTest::newRow("d0.000003945") << QString("d0.000003945") << 0.0 << 0 << false;
- QTest::newRow("e3.945e-6") << QString("e3.945e-6") << 0.0 << 0 << false;
- QTest::newRow("f12456789012") << QString("f12456789012") << 0.0 << 0 << false;
- QTest::newRow("g1.2456789012e10") << QString("g1.2456789012e10") << 0.0 << 0 << false;
-
- // ends with junk, success
- QTest::newRow("0a") << QString("0a") << 0.0 << 1 << true;
- QTest::newRow("0.a") << QString("0.a") << 0.0 << 2 << true;
- QTest::newRow("0.0a") << QString("0.0a") << 0.0 << 3 << true;
- QTest::newRow("0e+0a") << QString("0e+0a") << 0.0 << 4 << true;
- QTest::newRow("0e-0a") << QString("0e-0a") << 0.0 << 4 << true;
- QTest::newRow("0e+1a") << QString("0e+1a") << 0.0 << 4 << true;
- QTest::newRow("0e-1a") << QString("0e-1a") << 0.0 << 4 << true;
- QTest::newRow("0E+0a") << QString("0E+0a") << 0.0 << 4 << true;
- QTest::newRow("0E-0a") << QString("0E-0a") << 0.0 << 4 << true;
- QTest::newRow("0E+1a") << QString("0E+1a") << 0.0 << 4 << true;
- QTest::newRow("0E-1a") << QString("0E-1a") << 0.0 << 4 << true;
- QTest::newRow("0.035003945b") << QString("0.035003945b") << 0.035003945 << 11 << true;
- QTest::newRow("3.5003945e-2c") << QString("3.5003945e-2c") << 0.035003945 << 12 << true;
- QTest::newRow("0.000003945d") << QString("0.000003945d") << 0.000003945 << 11 << true;
- QTest::newRow("3.945e-6e") << QString("3.945e-6e") << 0.000003945 << 8 << true;
- QTest::newRow("12456789012f") << QString("12456789012f") << 12456789012.0 << 11 << true;
- QTest::newRow("1.2456789012e10g") << QString("1.2456789012e10g") << 12456789012.0 << 15 << true;
-
- // "0x" prefix, success but only for the "0" before "x"
- QTest::newRow("0x0") << QString("0x0") << 0.0 << 1 << true;
- QTest::newRow("0x0.") << QString("0x0.") << 0.0 << 1 << true;
- QTest::newRow("0x0.0") << QString("0x0.0") << 0.0 << 1 << true;
- QTest::newRow("0x3.4") << QString("0x3.4") << 0.0 << 1 << true;
- QTest::newRow("0x0.035003945") << QString("0x0.035003945") << 0.0 << 1 << true;
- QTest::newRow("0x3.5003945e-2") << QString("0x3.5003945e-2") << 0.0 << 1 << true;
- QTest::newRow("0x0.000003945") << QString("0x0.000003945") << 0.0 << 1 << true;
- QTest::newRow("0x3.945e-6") << QString("0x3.945e-6") << 0.0 << 1 << true;
- QTest::newRow("0x12456789012") << QString("0x12456789012") << 0.0 << 1 << true;
- QTest::newRow("0x1.2456789012e10") << QString("0x1.2456789012e10") << 0.0 << 1 << true;
-
- // hexfloat is not supported (yet)
- QTest::newRow("0x1.921fb5p+1") << QString("0x1.921fb5p+1") << 0.0 << 1 << true;
-}
-
-void tst_QLocale::strtod()
-{
- QFETCH(QString, num_str);
- QFETCH(double, num);
- QFETCH(int, processed);
- QFETCH(bool, ok);
-
- QByteArray numData = num_str.toLatin1();
- const char *end = 0;
- bool actualOk = false;
- double result = qstrtod(numData.constData(), &end, &actualOk);
-
- QCOMPARE(result, num);
- QCOMPARE(actualOk, ok);
- QCOMPARE(static_cast<int>(end - numData.constData()), processed);
-
- // make sure neither QByteArray, QString or QLocale also work
- // (but they don't support incomplete parsing)
- if (processed == num_str.size() || processed == 0) {
- actualOk = false;
- QCOMPARE(num_str.toDouble(&actualOk), num);
- QCOMPARE(actualOk, ok);
-
- actualOk = false;
- QCOMPARE(numData.toDouble(&actualOk), num);
- QCOMPARE(actualOk, ok);
-
- actualOk = false;
- QCOMPARE(QLocale::c().toDouble(num_str, &actualOk), num);
- QCOMPARE(actualOk, ok);
- }
-
- // and QStringRef, but we can limit the length without allocating memory
- QStringRef num_strref(&num_str, 0, processed);
- actualOk = false;
- QCOMPARE(QLocale::c().toDouble(num_strref, &actualOk), num);
- QCOMPARE(actualOk, ok);
-}
-
-void tst_QLocale::long_long_conversion_data()
-{
- QTest::addColumn<QString>("locale_name");
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<bool>("good");
- QTest::addColumn<qlonglong>("num");
-
- QTest::newRow("C null") << QString("C") << QString() << false << (qlonglong) 0;
- QTest::newRow("C empty") << QString("C") << QString("") << false << (qlonglong) 0;
- QTest::newRow("C 1") << QString("C") << "1" << true << (qlonglong) 1;
- QTest::newRow("C 1,") << QString("C") << "1," << false << (qlonglong) 0;
- QTest::newRow("C 1,2") << QString("C") << "1,2" << false << (qlonglong) 0;
- QTest::newRow("C 1,23") << QString("C") << "1,23" << false << (qlonglong) 0;
- QTest::newRow("C 1,234") << QString("C") << "1,234" << true << (qlonglong) 1234;
- QTest::newRow("C 1234567") << QString("C") << "1234567" << true << (qlonglong) 1234567;
- QTest::newRow("C 1,234567") << QString("C") << "1,234567" << false << (qlonglong) 0;
- QTest::newRow("C 12,34567") << QString("C") << "12,34567" << false << (qlonglong) 0;
- QTest::newRow("C 123,4567") << QString("C") << "123,4567" << false << (qlonglong) 0;
- QTest::newRow("C 1234,567") << QString("C") << "1234,567" << false << (qlonglong) 0;
- QTest::newRow("C 12345,67") << QString("C") << "12345,67" << false << (qlonglong) 0;
- QTest::newRow("C 123456,7") << QString("C") << "123456,7" << false << (qlonglong) 0;
- QTest::newRow("C 1,234,567") << QString("C") << "1,234,567" << true << (qlonglong) 1234567;
-
- QTest::newRow("de_DE 1") << QString("de_DE") << "1" << true << (qlonglong) 1;
- QTest::newRow("de_DE 1.") << QString("de_DE") << "1." << false << (qlonglong) 0;
- QTest::newRow("de_DE 1.2") << QString("de_DE") << "1.2" << false << (qlonglong) 0;
- QTest::newRow("de_DE 1.23") << QString("de_DE") << "1.23" << false << (qlonglong) 0;
- QTest::newRow("de_DE 1.234") << QString("de_DE") << "1.234" << true << (qlonglong) 1234;
- QTest::newRow("de_DE 1234567") << QString("de_DE") << "1234567" << true << (qlonglong) 1234567;
- QTest::newRow("de_DE 1.234567") << QString("de_DE") << "1.234567" << false << (qlonglong) 0;
- QTest::newRow("de_DE 12.34567") << QString("de_DE") << "12.34567" << false << (qlonglong) 0;
- QTest::newRow("de_DE 123.4567") << QString("de_DE") << "123.4567" << false << (qlonglong) 0;
- QTest::newRow("de_DE 1234.567") << QString("de_DE") << "1234.567" << false << (qlonglong) 0;
- QTest::newRow("de_DE 12345.67") << QString("de_DE") << "12345.67" << false << (qlonglong) 0;
- QTest::newRow("de_DE 123456.7") << QString("de_DE") << "123456.7" << false << (qlonglong) 0;
- QTest::newRow("de_DE 1.234.567") << QString("de_DE") << "1.234.567" << true << (qlonglong) 1234567;
- QTest::newRow("de_DE 1.234.567 ldspcs") << QString("de_DE") << " 1.234.567" << true << (qlonglong) 1234567;
- QTest::newRow("de_DE 1.234.567 trspcs") << QString("de_DE") << "1.234.567 " << true << (qlonglong) 1234567;
- QTest::newRow("de_DE 1.234.567 ldtrspcs") << QString("de_DE") << " 1.234.567 " << true << (qlonglong) 1234567;
-
- // test that space is also accepted whenever QLocale::groupSeparator() == 0xa0 (which looks like space).
- QTest::newRow("nb_NO 123 groupsep") << QString("nb_NO") << QString("1")+QChar(0xa0)+QString("234") << true << (qlonglong) 1234;
- QTest::newRow("nb_NO 123 groupsep_space") << QString("nb_NO") << QString("1")+QChar(0x20)+QString("234") << true << (qlonglong) 1234;
-
- QTest::newRow("nb_NO 123 ldspcs") << QString("nb_NO") << " 123" << true << (qlonglong) 123;
- QTest::newRow("nb_NO 123 trspcs") << QString("nb_NO") << "123 " << true << (qlonglong) 123;
- QTest::newRow("nb_NO 123 ldtrspcs") << QString("nb_NO") << " 123 " << true << (qlonglong) 123;
-
- QTest::newRow("C 1234") << QString("C") << " 1234" << true << (qlonglong) 1234;
- QTest::newRow("C 1234 ") << QString("C") << "1234 " << true << (qlonglong) 1234;
- QTest::newRow("C 1234 ") << QString("C") << " 1234 " << true << (qlonglong) 1234;
-}
-
-void tst_QLocale::long_long_conversion()
-{
- QFETCH(QString, locale_name);
- QFETCH(QString, num_str);
- QFETCH(bool, good);
- QFETCH(qlonglong, num);
- QStringRef num_strRef = num_str.leftRef(-1);
-
- QLocale locale(locale_name);
- QCOMPARE(locale.name(), locale_name);
-
- bool ok;
- qlonglong l = locale.toLongLong(num_str, &ok);
- QCOMPARE(ok, good);
-
- if (ok)
- QCOMPARE(l, num);
-
- l = locale.toLongLong(num_strRef, &ok);
- QCOMPARE(ok, good);
-
- if (ok)
- QCOMPARE(l, num);
-}
-
-void tst_QLocale::long_long_conversion_extra()
-{
- QLocale l(QLocale::C);
- l.setNumberOptions(0);
- QCOMPARE(l.toString((qlonglong)1), QString("1"));
- QCOMPARE(l.toString((qlonglong)12), QString("12"));
- QCOMPARE(l.toString((qlonglong)123), QString("123"));
- QCOMPARE(l.toString((qlonglong)1234), QString("1,234"));
- QCOMPARE(l.toString((qlonglong)12345), QString("12,345"));
- QCOMPARE(l.toString((qlonglong)-1), QString("-1"));
- QCOMPARE(l.toString((qlonglong)-12), QString("-12"));
- QCOMPARE(l.toString((qlonglong)-123), QString("-123"));
- QCOMPARE(l.toString((qlonglong)-1234), QString("-1,234"));
- QCOMPARE(l.toString((qlonglong)-12345), QString("-12,345"));
- QCOMPARE(l.toString((qulonglong)1), QString("1"));
- QCOMPARE(l.toString((qulonglong)12), QString("12"));
- QCOMPARE(l.toString((qulonglong)123), QString("123"));
- QCOMPARE(l.toString((qulonglong)1234), QString("1,234"));
- QCOMPARE(l.toString((qulonglong)12345), QString("12,345"));
-}
-
-void tst_QLocale::testInfAndNan()
-{
- double neginf = log(0.0);
- double nan = sqrt(-1.0);
-
-#ifdef Q_OS_WIN
- // these cause INVALID floating point exception so we want to clear the status.
- _clear87();
-#endif
-
- QVERIFY(qIsInf(-neginf));
- QVERIFY(!qIsNaN(-neginf));
- QVERIFY(!qIsFinite(-neginf));
-
- QVERIFY(!qIsInf(nan));
- QVERIFY(qIsNaN(nan));
- QVERIFY(!qIsFinite(nan));
-
- QVERIFY(!qIsInf(1.234));
- QVERIFY(!qIsNaN(1.234));
- QVERIFY(qIsFinite(1.234));
-}
-
-void tst_QLocale::fpExceptions()
-{
-#ifndef _MCW_EM
-#define _MCW_EM 0x0008001F
-#endif
-#ifndef _EM_INEXACT
-#define _EM_INEXACT 0x00000001
-#endif
-
- // check that double-to-string conversion doesn't throw floating point exceptions when they are
- // enabled
-#ifdef Q_OS_WIN
- unsigned int oldbits = _control87(0, 0);
- _control87( 0 | _EM_INEXACT, _MCW_EM );
-#endif
-
-#ifdef QT_USE_FENV
- fenv_t envp;
- fegetenv(&envp);
- feclearexcept(FE_ALL_EXCEPT);
- feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID);
-#endif
-
- QString::number(1000.1245);
- QString::number(1.1);
- QString::number(0.0);
-
- QVERIFY(true);
-
-#ifdef Q_OS_WIN
- _clear87();
- _control87(oldbits, 0xFFFFF);
-#endif
-
-#ifdef QT_USE_FENV
- fesetenv(&envp);
-#endif
-}
-
-void tst_QLocale::negativeZero()
-{
- double negativeZero( 0.0 ); // Initialise to zero.
- uchar *ptr = (uchar *)&negativeZero;
- ptr[QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 7] = 0x80;
- QString s = QString::number(negativeZero);
- QCOMPARE(s, QString("0"));
-}
-
-void tst_QLocale::dayOfWeek_data()
-{
- QTest::addColumn<QDate>("date");
- QTest::addColumn<QString>("shortName");
- QTest::addColumn<QString>("longName");
-
- QTest::newRow("Sun") << QDate(2006, 1, 1) << "Sun" << "Sunday";
- QTest::newRow("Mon") << QDate(2006, 1, 2) << "Mon" << "Monday";
- QTest::newRow("Tue") << QDate(2006, 1, 3) << "Tue" << "Tuesday";
- QTest::newRow("Wed") << QDate(2006, 1, 4) << "Wed" << "Wednesday";
- QTest::newRow("Thu") << QDate(2006, 1, 5) << "Thu" << "Thursday";
- QTest::newRow("Fri") << QDate(2006, 1, 6) << "Fri" << "Friday";
- QTest::newRow("Sat") << QDate(2006, 1, 7) << "Sat" << "Saturday";
-}
-
-void tst_QLocale::dayOfWeek()
-{
- QFETCH(QDate, date);
- QFETCH(QString, shortName);
- QFETCH(QString, longName);
-
- QCOMPARE(QLocale::c().toString(date, "ddd"), shortName);
- QCOMPARE(QLocale::c().toString(date, "dddd"), longName);
-
- QCOMPARE(QLocale::c().toString(date, QStringViewLiteral("ddd")), shortName);
- QCOMPARE(QLocale::c().toString(date, QStringViewLiteral("dddd")), longName);
-}
-
-void tst_QLocale::formatDate_data()
-{
- QTest::addColumn<QDate>("date");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QString>("result");
-
- QTest::newRow("1") << QDate(1974, 12, 1) << "d/M/yyyy" << "1/12/1974";
- QTest::newRow("2") << QDate(1974, 12, 1) << "d/M/yyyyy" << "1/12/1974y";
- QTest::newRow("4") << QDate(1974, 1, 1) << "d/M/yyyy" << "1/1/1974";
- QTest::newRow("5") << QDate(1974, 1, 1) << "dd/MM/yyy" << "01/01/74y";
- QTest::newRow("6") << QDate(1974, 12, 1) << "ddd/MMM/yy" << "Sun/Dec/74";
- QTest::newRow("7") << QDate(1974, 12, 1) << "dddd/MMMM/y" << "Sunday/December/y";
- QTest::newRow("8") << QDate(1974, 12, 1) << "ddddd/MMMMM/yy" << "Sunday1/December12/74";
- QTest::newRow("9") << QDate(1974, 12, 1) << "'dddd'/MMMM/yy" << "dddd/December/74";
- QTest::newRow("10") << QDate(1974, 12, 1) << "d'dd'd/MMMM/yyy" << "1dd1/December/74y";
- QTest::newRow("11") << QDate(1974, 12, 1) << "d'dd'd/MMM'M'/yy" << "1dd1/DecM/74";
- QTest::newRow("12") << QDate(1974, 12, 1) << "d'd'dd/M/yy" << "1d01/12/74";
-
- QTest::newRow("20") << QDate(1974, 12, 1) << "foo" << "foo";
- QTest::newRow("21") << QDate(1974, 12, 1) << "'" << "";
- QTest::newRow("22") << QDate(1974, 12, 1) << "''" << "'";
- QTest::newRow("23") << QDate(1974, 12, 1) << "'''" << "'";
- QTest::newRow("24") << QDate(1974, 12, 1) << "\"" << "\"";
- QTest::newRow("25") << QDate(1974, 12, 1) << "\"\"" << "\"\"";
- QTest::newRow("26") << QDate(1974, 12, 1) << "\"yy\"" << "\"74\"";
- QTest::newRow("27") << QDate(1974, 12, 1) << "'\"yy\"'" << "\"yy\"";
- QTest::newRow("28") << QDate() << "'\"yy\"'" << "";
- QTest::newRow("29")
- << QDate(1974, 12, 1) << "hh:mm:ss.zzz ap d'd'dd/M/yy" << "hh:mm:ss.zzz ap 1d01/12/74";
-
- QTest::newRow("dd MMMM yyyy") << QDate(1, 1, 1) << "dd MMMM yyyy" << "01 January 0001";
-}
-
-void tst_QLocale::formatDate()
-{
- QFETCH(QDate, date);
- QFETCH(QString, format);
- QFETCH(QString, result);
-
- QLocale l(QLocale::C);
- QCOMPARE(l.toString(date, format), result);
- QCOMPARE(l.toString(date, QStringView(format)), result);
-}
-
-void tst_QLocale::formatTime_data()
-{
- QTest::addColumn<QTime>("time");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QString>("result");
-
- QTest::newRow("1") << QTime(1, 2, 3) << "h:m:s" << "1:2:3";
- QTest::newRow("3") << QTime(1, 2, 3) << "H:m:s" << "1:2:3";
- QTest::newRow("4") << QTime(1, 2, 3) << "hh:mm:ss" << "01:02:03";
- QTest::newRow("5") << QTime(1, 2, 3) << "HH:mm:ss" << "01:02:03";
- QTest::newRow("6") << QTime(1, 2, 3) << "hhh:mmm:sss" << "011:022:033";
-
- QTest::newRow("8") << QTime(14, 2, 3) << "h:m:s" << "14:2:3";
- QTest::newRow("9") << QTime(14, 2, 3) << "H:m:s" << "14:2:3";
- QTest::newRow("10") << QTime(14, 2, 3) << "hh:mm:ss" << "14:02:03";
- QTest::newRow("11") << QTime(14, 2, 3) << "HH:mm:ss" << "14:02:03";
- QTest::newRow("12") << QTime(14, 2, 3) << "hhh:mmm:sss" << "1414:022:033";
-
- QTest::newRow("14") << QTime(14, 2, 3) << "h:m:s ap" << "2:2:3 pm";
- QTest::newRow("15") << QTime(14, 2, 3) << "H:m:s AP" << "14:2:3 PM";
- QTest::newRow("16") << QTime(14, 2, 3) << "hh:mm:ss aap" << "02:02:03 pmpm";
- QTest::newRow("17") << QTime(14, 2, 3) << "HH:mm:ss AP aa" << "14:02:03 PM pmpm";
-
- QTest::newRow("18") << QTime(1, 2, 3) << "h:m:s ap" << "1:2:3 am";
- QTest::newRow("19") << QTime(1, 2, 3) << "H:m:s AP" << "1:2:3 AM";
-
- QTest::newRow("20") << QTime(1, 2, 3) << "foo" << "foo";
- QTest::newRow("21") << QTime(1, 2, 3) << "'" << "";
- QTest::newRow("22") << QTime(1, 2, 3) << "''" << "'";
- QTest::newRow("23") << QTime(1, 2, 3) << "'''" << "'";
- QTest::newRow("24") << QTime(1, 2, 3) << "\"" << "\"";
- QTest::newRow("25") << QTime(1, 2, 3) << "\"\"" << "\"\"";
- QTest::newRow("26") << QTime(1, 2, 3) << "\"H\"" << "\"1\"";
- QTest::newRow("27") << QTime(1, 2, 3) << "'\"H\"'" << "\"H\"";
-
- QTest::newRow("28") << QTime(1, 2, 3, 456) << "H:m:s.z" << "1:2:3.456";
- QTest::newRow("29") << QTime(1, 2, 3, 456) << "H:m:s.zz" << "1:2:3.456456";
- QTest::newRow("30") << QTime(1, 2, 3, 456) << "H:m:s.zzz" << "1:2:3.456";
- QTest::newRow("31") << QTime(1, 2, 3, 400) << "H:m:s.z" << "1:2:3.4";
- QTest::newRow("32") << QTime(1, 2, 3, 4) << "H:m:s.z" << "1:2:3.004";
- QTest::newRow("33") << QTime(1, 2, 3, 4) << "H:m:s.zzz" << "1:2:3.004";
- QTest::newRow("34") << QTime() << "H:m:s.zzz" << "";
- QTest::newRow("35") << QTime(1, 2, 3, 4) << "dd MM yyyy H:m:s.zzz" << "dd MM yyyy 1:2:3.004";
-}
-
-void tst_QLocale::formatTime()
-{
- QFETCH(QTime, time);
- QFETCH(QString, format);
- QFETCH(QString, result);
-
- QLocale l(QLocale::C);
- QCOMPARE(l.toString(time, format), result);
- QCOMPARE(l.toString(time, QStringView(format)), result);
-}
-
-
-void tst_QLocale::formatDateTime_data()
-{
- QTest::addColumn<QString>("localeName");
- QTest::addColumn<QDateTime>("dateTime");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QString>("result");
-
- QTest::newRow("1C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13))
- << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14";
- QTest::newRow("2C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "d/M/yyyyy h" << "1/12/1974y 15";
- QTest::newRow("4C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
- << "d/M/yyyy zzz" << "1/1/1974 000";
- QTest::newRow("5C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
- << "dd/MM/yyy z" << "01/01/74y 0";
- QTest::newRow("6C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "ddd/MMM/yy AP" << "Mon/Dec/74 PM";
- QTest::newRow("7C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "dddd/MMMM/y apa" << "Monday/December/y pmpm";
- QTest::newRow("8C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "ddddd/MMMMM/yy ss" << "Monday2/December12/74 13";
- QTest::newRow("9C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'dddd'/MMMM/yy s" << "dddd/December/74 13";
- QTest::newRow("10C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 4, 13))
- << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/December/74y 4m04";
- QTest::newRow("11C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 3))
- << "d'dd'd/MMM'M'/yysss" << "1dd1/DecM/74033";
- QTest::newRow("12C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "d'd'dd/M/yyh" << "1d01/12/7415";
-
- QTest::newRow("dd MMMM yyyy, hh:mm:ss") << "C" << QDateTime(QDate(1, 1, 1), QTime(12, 00, 00))
- << "dd MMMM yyyy, hh:mm:ss" << "01 January 0001, 12:00:00";
-
- QTest::newRow("20C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "foo" << "foo";
- QTest::newRow("21C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'" << "";
- QTest::newRow("22C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "''" << "'";
- QTest::newRow("23C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'''" << "'";
- QTest::newRow("24C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "\"" << "\"";
- QTest::newRow("25C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "\"\"" << "\"\"";
- QTest::newRow("26C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "\"yymm\"" << "\"7414\"";
- QTest::newRow("27C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'\"yymm\"'" << "\"yymm\"";
- QTest::newRow("28C") << "C" << QDateTime()
- << "'\"yymm\"'" << "";
-
- QTest::newRow("1no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13))
- << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14";
- QTest::newRow("2no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "d/M/yyyyy h" << "1/12/1974y 15";
- QTest::newRow("4no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
- << "d/M/yyyy zzz" << "1/1/1974 000";
- QTest::newRow("5no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
- << "dd/MM/yyy z" << "01/01/74y 0";
- QTest::newRow("6no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "ddd/MMM/yy AP" << "man./des./74 P.M.";
- QTest::newRow("7no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "dddd/MMMM/y apa" << "mandag/desember/y p.m.p.m.";
- QTest::newRow("8no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13";
- QTest::newRow("9no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'dddd'/MMMM/yy s" << "dddd/desember/74 13";
- QTest::newRow("10no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 4, 13))
- << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/desember/74y 4m04";
- QTest::newRow("11no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 3))
- << "d'dd'd/MMM'M'/yysss" << "1dd1/des.M/74033";
- QTest::newRow("12no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "d'd'dd/M/yyh" << "1d01/12/7415";
-
- QTest::newRow("20no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "foo" << "foo";
- QTest::newRow("21no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'" << "";
- QTest::newRow("22no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "''" << "'";
- QTest::newRow("23no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'''" << "'";
- QTest::newRow("24no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "\"" << "\"";
- QTest::newRow("25no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "\"\"" << "\"\"";
- QTest::newRow("26no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "\"yymm\"" << "\"7414\"";
- QTest::newRow("27no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
- << "'\"yymm\"'" << "\"yymm\"";
- QTest::newRow("28no_NO") << "no_NO" << QDateTime()
- << "'\"yymm\"'" << "";
-
- QDateTime testLongHour(QDate(1999, 12, 31), QTime(23, 59, 59, 999));
- QDateTime testShortHour(QDate(1999, 12, 31), QTime(3, 59, 59, 999));
- QDateTime testZeroHour(QDate(1999, 12, 31), QTime(0, 59, 59, 999));
-
- QTest::newRow("datetime0") << "en_US" << QDateTime()
- << QString("dd-MM-yyyy hh:mm:ss") << QString();
- QTest::newRow("datetime1") << "en_US" << testLongHour
- << QString("dd-'mmddyy'MM-yyyy hh:mm:ss.zzz")
- << QString("31-mmddyy12-1999 23:59:59.999");
- QTest::newRow("datetime2") << "en_US" << testLongHour
- << QString("dd-'apAP'MM-yyyy hh:mm:ss.zzz")
- << QString("31-apAP12-1999 23:59:59.999");
- QTest::newRow("datetime3") << "en_US" << testLongHour
- << QString("Apdd-MM-yyyy hh:mm:ss.zzz")
- << QString("PMp31-12-1999 11:59:59.999");
- QTest::newRow("datetime4") << "en_US" << testLongHour
- << QString("'ap'apdd-MM-yyyy 'AP'hh:mm:ss.zzz")
- << QString("appm31-12-1999 AP11:59:59.999");
- QTest::newRow("datetime5") << "en_US" << testLongHour
- << QString("'''") << QString("'");
- QTest::newRow("datetime6") << "en_US" << testLongHour
- << QString("'ap") << QString("ap");
- QTest::newRow("datetime7") << "en_US" << testLongHour
- << QString("' ' 'hh' hh") << QString(" hh 23");
- QTest::newRow("datetime8") << "en_US" << testLongHour
- << QString("d'foobar'") << QString("31foobar");
- QTest::newRow("datetime9") << "en_US" << testShortHour
- << QString("hhhhh") << QString("03033");
- QTest::newRow("datetime11") << "en_US" << testLongHour
- << QString("HHHhhhAaAPap") << QString("23231111PMpmPMpm");
- QTest::newRow("datetime12") << "en_US" << testShortHour
- << QString("HHHhhhAaAPap") << QString("033033AMamAMam");
- QTest::newRow("datetime13") << "en_US" << QDateTime(QDate(1974, 12, 1), QTime(14, 14, 20))
- << QString("hh''mm''ss dd''MM''yyyy")
- << QString("14'14'20 01'12'1974");
- QTest::newRow("AM no p") << "en_US" << testZeroHour
- << QString("hhAX") << QString("12AMX");
- QTest::newRow("AM no p, x 2") << "en_US" << testShortHour
- << QString("hhhhhaA") << QString("03033amAM");
- QTest::newRow("am 0 hour") << "en_US" << testZeroHour
- << QString("hAP") << QString("12AM");
- QTest::newRow("AM zero hour") << "en_US" << testZeroHour
- << QString("hhAP") << QString("12AM");
- QTest::newRow("dddd") << "en_US" << testZeroHour
- << QString("dddd") << QString("Friday");
- QTest::newRow("ddd") << "en_US" << testZeroHour
- << QString("ddd") << QString("Fri");
- QTest::newRow("MMMM") << "en_US" << testZeroHour
- << QString("MMMM") << QString("December");
- QTest::newRow("MMM") << "en_US" << testZeroHour
- << QString("MMM") << QString("Dec");
- QTest::newRow("empty") << "en_US" << testZeroHour
- << QString("") << QString("");
-}
-
-void tst_QLocale::formatDateTime()
-{
- QFETCH(QString, localeName);
- QFETCH(QDateTime, dateTime);
- QFETCH(QString, format);
- QFETCH(QString, result);
-
- QLocale l(localeName);
- QCOMPARE(l.toString(dateTime, format), result);
- QCOMPARE(l.toString(dateTime, QStringView(format)), result);
-}
-
-void tst_QLocale::formatTimeZone()
-{
- QLocale enUS("en_US");
-
- QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60);
- QCOMPARE(enUS.toString(dt1, "t"), QLatin1String("UTC+01:00"));
-
- QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60);
- QCOMPARE(enUS.toString(dt2, "t"), QLatin1String("UTC-01:00"));
-
- QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QCOMPARE(enUS.toString(dt3, "t"), QLatin1String("UTC"));
-
- // LocalTime should vary
- if (europeanTimeZone) {
- // Time definitely in Standard Time
- QDateTime dt4(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(enUS.toString(dt4, "t"), QLatin1String("CET"));
-
- // Time definitely in Daylight Time
- QDateTime dt5(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime);
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue);
-#endif // Q_OS_WIN
- QCOMPARE(enUS.toString(dt5, "t"), QLatin1String("CEST"));
- } else {
- qDebug("(Skipped some CET-only tests)");
- }
-
-#ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837)
- const QString cet(QStringLiteral("GMT+01:00"));
- const QString cest(QStringLiteral("GMT+02:00"));
-#elif defined Q_OS_DARWIN
- const QString cet(QStringLiteral("GMT+1"));
- const QString cest(QStringLiteral("GMT+2"));
-#else
- const QString cet(QStringLiteral("CET"));
- const QString cest(QStringLiteral("CEST"));
-#endif
-
- QDateTime dt6(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "QTimeZone windows backend only returns long name", Continue);
-#endif
- QCOMPARE(enUS.toString(dt6, "t"), cet);
-
- QDateTime dt7(QDate(2013, 6, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
-#ifdef Q_OS_WIN
- QEXPECT_FAIL("", "QTimeZone windows backend only returns long name", Continue);
-#endif
- QCOMPARE(enUS.toString(dt7, "t"), cest);
-
- // Current datetime should return current abbreviation
- QCOMPARE(enUS.toString(QDateTime::currentDateTime(), "t"),
- QDateTime::currentDateTime().timeZoneAbbreviation());
-
- // Time on its own will always be current local time zone
- QCOMPARE(enUS.toString(QTime(1, 2, 3), "t"),
- QDateTime::currentDateTime().timeZoneAbbreviation());
-}
-
-void tst_QLocale::toDateTime_data()
-{
- QTest::addColumn<QString>("localeName");
- QTest::addColumn<QDateTime>("result");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QString>("string");
-
- QTest::newRow("1C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 0))
- << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14";
- QTest::newRow("2C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
- << "d/M/yyyyy h" << "1/12/1974y 15";
- QTest::newRow("4C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 1))
- << "d/M/yyyy zzz" << "1/1/1974 001";
- QTest::newRow("5C") << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 1))
- << "dd/MM/yyy z" << "01/01/74y 001";
- QTest::newRow("5Cbis") << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 100))
- << "dd/MM/yyy z" << "01/01/74y 1";
- QTest::newRow("8C") << "C" << QDateTime(QDate(1974, 12, 2), QTime(0, 0, 13))
- << "ddddd/MMMMM/yy ss" << "Monday2/December12/74 13";
- QTest::newRow("9C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 13))
- << "'dddd'/MMMM/yy s" << "dddd/December/74 13";
- QTest::newRow("10C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 4, 0))
- << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/December/74y 4m04";
- QTest::newRow("11C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 3))
- << "d'dd'd/MMM'M'/yysss" << "1dd1/DecM/74033";
- QTest::newRow("12C") << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
- << "d'd'dd/M/yyh" << "1d01/12/7415";
- // Unpadded value for fixed-width field is wrong:
- QTest::newRow("bad-day-C") << "C" << QDateTime() << "dd-MMM-yy" << "4-Jun-11";
- QTest::newRow("bad-month-C") << "C" << QDateTime() << "d-MM-yy" << "4-6-11";
- QTest::newRow("bad-year-C") << "C" << QDateTime() << "d-MMM-yyyy" << "4-Jun-11";
- QTest::newRow("bad-hour-C") << "C" << QDateTime() << "d-MMM-yy hh:m" << "4-Jun-11 1:2";
- QTest::newRow("bad-min-C") << "C" << QDateTime() << "d-MMM-yy h:mm" << "4-Jun-11 1:2";
- QTest::newRow("bad-sec-C") << "C" << QDateTime() << "d-MMM-yy h:m:ss" << "4-Jun-11 1:2:3";
- QTest::newRow("bad-milli-C")
- << "C" << QDateTime() << "d-MMM-yy h:m:s.zzz" << "4-Jun-11 1:2:3.4";
- QTest::newRow("ok-C") << "C" << QDateTime(QDate(1911, 6, 4), QTime(1, 2, 3, 400))
- << "d-MMM-yy h:m:s.z" << "4-Jun-11 1:2:3.4";
-
- QTest::newRow("1no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 0))
- << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14";
- QTest::newRow("2no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
- << "d/M/yyyyy h" << "1/12/1974y 15";
- QTest::newRow("4no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0))
- << "d/M/yyyy zzz" << "1/1/1974 000";
- QTest::newRow("5no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0))
- << "dd/MM/yyy z" << "01/01/74y 0";
- QTest::newRow("8no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(0, 0, 13))
- << "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13";
- QTest::newRow("9no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 13))
- << "'dddd'/MMMM/yy s" << "dddd/desember/74 13";
- QTest::newRow("10no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 4, 0))
- << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/desember/74y 4m04";
- QTest::newRow("11no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 3))
- << "d'dd'd/MMM'M'/yysss" << "1dd1/des.M/74033";
- QTest::newRow("12no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
- << "d'd'dd/M/yyh" << "1d01/12/7415";
-
- QTest::newRow("RFC-1123")
- << "C" << QDateTime(QDate(2007, 11, 1), QTime(18, 8, 30))
- << "ddd, dd MMM yyyy hh:mm:ss 'GMT'" << "Thu, 01 Nov 2007 18:08:30 GMT";
-
- QTest::newRow("longFormat")
- << "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32))
- << "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM ";
-}
-
-void tst_QLocale::toDateTime()
-{
- QFETCH(QString, localeName);
- QFETCH(QDateTime, result);
- QFETCH(QString, format);
- QFETCH(QString, string);
-
- QLocale l(localeName);
- QCOMPARE(l.toDateTime(string, format), result);
- if (l.dateTimeFormat(QLocale::LongFormat) == format)
- QCOMPARE(l.toDateTime(string, QLocale::LongFormat), result);
-}
-
-#ifdef Q_OS_MAC
-
-// Format number string according to system locale settings.
-// Expected in format is US "1,234.56".
-QString systemLocaleFormatNumber(const QString &numberString)
-{
- QLocale locale = QLocale::system();
- QString numberStringCopy = numberString;
- return numberStringCopy.replace(QChar(','), QChar('G'))
- .replace(QChar('.'), QChar('D'))
- .replace(QChar('G'), locale.groupSeparator())
- .replace(QChar('D'), locale.decimalPoint());
-}
-
-void tst_QLocale::macDefaultLocale()
-{
- QLocale locale = QLocale::system();
-
- if (locale.name() != QLatin1String("en_US"))
- QSKIP("This test only tests for en_US");
-
- QTime invalidTime;
- QDate invalidDate;
- QCOMPARE(locale.toString(invalidTime, QLocale::ShortFormat), QString());
- QCOMPARE(locale.toString(invalidDate, QLocale::ShortFormat), QString());
- QCOMPARE(locale.toString(invalidTime, QLocale::NarrowFormat), QString());
- QCOMPARE(locale.toString(invalidDate, QLocale::NarrowFormat), QString());
- QCOMPARE(locale.toString(invalidTime, QLocale::LongFormat), QString());
- QCOMPARE(locale.toString(invalidDate, QLocale::LongFormat), QString());
-
- // On OS X the decimal point and group separator are configurable
- // independently of the locale. Verify that they have one of the
- // allowed values and are not the same.
- QVERIFY(locale.decimalPoint() == QChar('.') || locale.decimalPoint() == QChar(','));
- QVERIFY(locale.groupSeparator() == QChar(',')
- || locale.groupSeparator() == QChar('.')
- || locale.groupSeparator() == QChar('\xA0') // no-breaking space
- || locale.groupSeparator() == QChar('\'')
- || locale.groupSeparator() == QChar());
- QVERIFY(locale.decimalPoint() != locale.groupSeparator());
-
- // make sure we are using the system to parse them
- QCOMPARE(locale.toString(1234.56), systemLocaleFormatNumber(QString("1,234.56")));
-
- QTime testTime = QTime(1, 2, 3);
- QTime utcTime = QDateTime(QDate::currentDate(), testTime).toUTC().time();
- int diff = testTime.hour() - utcTime.hour();
-
- // Check if local time and utc time are on opposite sides of the 24-hour wrap-around.
- if (diff < -12)
- diff += 24;
- if (diff > 12)
- diff -= 24;
-
- const QString timeString = locale.toString(testTime, QLocale::LongFormat);
- QVERIFY(timeString.contains(QString("1:02:03")));
-
- // To run this test make sure "Curreny" is US Dollar in System Preferences->Language & Region->Advanced.
- if (locale.currencySymbol() == QString("$")) {
- QCOMPARE(locale.toCurrencyString(qulonglong(1234)),
- systemLocaleFormatNumber(QString("$1,234.00")));
- QCOMPARE(locale.toCurrencyString(double(1234.56)),
- systemLocaleFormatNumber(QString("$1,234.56")));
- }
-
- // Depending on the configured time zone, the time string might not
- // contain a GMT specifier. (Sometimes it just names the zone, like "CEST")
- QLatin1String gmt("GMT");
- if (timeString.contains(gmt) && diff) {
- QLatin1Char sign(diff < 0 ? '-' : '+');
- QString number(QString::number(qAbs(diff)));
- const QString expect = gmt + sign + number;
-
- if (diff < 10) {
- const QString zeroed = gmt + sign + QLatin1Char('0') + number;
-
- QVERIFY2(timeString.contains(expect) || timeString.contains(zeroed),
- qPrintable(QString("timeString `%1', expected GMT specifier `%2' or `%3'")
- .arg(timeString).arg(expect).arg(zeroed)));
- } else {
- QVERIFY2(timeString.contains(expect),
- qPrintable(QString("timeString `%1', expected GMT specifier `%2'")
- .arg(timeString).arg(expect)));
- }
- }
- QCOMPARE(locale.dayName(1), QString("Monday"));
- QCOMPARE(locale.dayName(7), QString("Sunday"));
- QCOMPARE(locale.monthName(1), QString("January"));
- QCOMPARE(locale.monthName(12), QString("December"));
- QCOMPARE(locale.quoteString("string"),
- QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d"));
- QCOMPARE(locale.quoteString("string", QLocale::AlternateQuotation),
- QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99"));
-
- QList<Qt::DayOfWeek> days;
- days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday;
- QCOMPARE(locale.weekdays(), days);
-
-}
-#endif // Q_OS_MAC
-
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-#include <qt_windows.h>
-
-static QString getWinLocaleInfo(LCTYPE type)
-{
- LCID id = GetThreadLocale();
- int cnt = GetLocaleInfo(id, type, 0, 0) * 2;
-
- if (cnt == 0) {
- qWarning().nospace() << "QLocale: empty windows locale info (" << type << ')';
- return QString();
- }
- cnt /= sizeof(wchar_t);
- QScopedArrayPointer<wchar_t> buf(new wchar_t[cnt]);
- cnt = GetLocaleInfo(id, type, buf.data(), cnt);
-
- if (cnt == 0) {
- qWarning().nospace() << "QLocale: empty windows locale info (" << type << ')';
- return QString();
- }
- return QString::fromWCharArray(buf.data());
-}
-
-static void setWinLocaleInfo(LCTYPE type, const QString &value)
-{
- LCID id = GetThreadLocale();
- SetLocaleInfo(id, type, reinterpret_cast<const wchar_t*>(value.utf16()));
-}
-
-#ifndef LOCALE_SSHORTTIME
-# define LOCALE_SSHORTTIME 0x00000079
-#endif
-
-class RestoreLocaleHelper {
-public:
- RestoreLocaleHelper() {
- m_decimal = getWinLocaleInfo(LOCALE_SDECIMAL);
- m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND);
- m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE);
- m_ldate = getWinLocaleInfo(LOCALE_SLONGDATE);
- m_time = getWinLocaleInfo(LOCALE_SSHORTTIME);
- }
-
- ~RestoreLocaleHelper() {
- // restore these, or the user will get a surprise
- setWinLocaleInfo(LOCALE_SDECIMAL, m_decimal);
- setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand);
- setWinLocaleInfo(LOCALE_SSHORTDATE, m_sdate);
- setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate);
- setWinLocaleInfo(LOCALE_SSHORTTIME, m_time);
-
- // make sure QLocale::system() gets updated
- QLocalePrivate::updateSystemPrivate();
- }
-
- QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
-
-};
-
-void tst_QLocale::windowsDefaultLocale()
-{
- RestoreLocaleHelper systemLocale;
- // set weird system defaults and make sure we're using them
- setWinLocaleInfo(LOCALE_SDECIMAL, QLatin1String("@"));
- setWinLocaleInfo(LOCALE_STHOUSAND, QLatin1String("?"));
- const QString shortDateFormat = QStringLiteral("d*M*yyyy");
- setWinLocaleInfo(LOCALE_SSHORTDATE, shortDateFormat);
- const QString longDateFormat = QStringLiteral("d@M@yyyy");
- setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat);
- const QString shortTimeFormat = QStringLiteral("h^m^s");
- setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat);
-
- // make sure QLocale::system() gets updated
- QLocalePrivate::updateSystemPrivate();
- QLocale locale = QLocale::system();
-
- // make sure we are seeing the system's format strings
- QCOMPARE(locale.decimalPoint(), QChar('@'));
- QCOMPARE(locale.groupSeparator(), QChar('?'));
- QCOMPARE(locale.dateFormat(QLocale::ShortFormat), shortDateFormat);
- QCOMPARE(locale.dateFormat(QLocale::LongFormat), longDateFormat);
- QCOMPARE(locale.timeFormat(QLocale::ShortFormat), shortTimeFormat);
- QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat),
- shortDateFormat + QLatin1Char(' ') + shortTimeFormat);
- const QString expectedLongDateTimeFormat
- = longDateFormat + QLatin1Char(' ') + QStringLiteral("h:mm:ss AP");
- QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat);
-
- // make sure we are using the system to parse them
- QCOMPARE(locale.toString(1234.56), QString("1?234@56"));
- QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat), QString("1*12*1974"));
- QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::NarrowFormat),
- locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat));
- QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::LongFormat), QString("1@12@1974"));
- const QString expectedFormattedShortTimeSeconds = QStringLiteral("1^2^3");
- const QString expectedFormattedShortTime = QStringLiteral("1^2");
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime);
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat),
- locale.toString(QTime(1,2,3), QLocale::ShortFormat));
- const QString expectedFormattedLongTime = QStringLiteral("1:02:03 AM");
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
- QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat),
- QStringLiteral("1*12*1974 ") + expectedFormattedShortTime);
- QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::NarrowFormat),
- locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat));
- QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::LongFormat),
- QStringLiteral("1@12@1974 ") + expectedFormattedLongTime);
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
-}
-#endif // Q_OS_WIN but !Q_OS_WINRT
-
-void tst_QLocale::numberOptions()
-{
- bool ok;
-
- QLocale locale(QLocale::C);
- QCOMPARE(locale.numberOptions(), QLocale::OmitGroupSeparator);
- QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
- QVERIFY(ok);
- QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
- QVERIFY(ok);
- QCOMPARE(locale.toString(12345), QString("12345"));
-
- locale.setNumberOptions(0);
- QCOMPARE(locale.numberOptions(), 0);
- QCOMPARE(locale.toInt(QString("12,345"), &ok), 12345);
- QVERIFY(ok);
- QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
- QVERIFY(ok);
- QCOMPARE(locale.toString(12345), QString("12,345"));
-
- locale.setNumberOptions(QLocale::RejectGroupSeparator);
- QCOMPARE(locale.numberOptions(), QLocale::RejectGroupSeparator);
- locale.toInt(QString("12,345"), &ok);
- QVERIFY(!ok);
- QCOMPARE(locale.toInt(QString("12345"), &ok), 12345);
- QVERIFY(ok);
- QCOMPARE(locale.toString(12345), QString("12,345"));
-
- QLocale locale2 = locale;
- QCOMPARE(locale2.numberOptions(), QLocale::RejectGroupSeparator);
-
- QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+01"));
- locale.setNumberOptions(QLocale::OmitLeadingZeroInExponent);
- QCOMPARE(locale.numberOptions(), QLocale::OmitLeadingZeroInExponent);
- QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+1"));
-
- locale.toDouble(QString("1.24e+01"), &ok);
- QVERIFY(ok);
- locale.setNumberOptions(QLocale::RejectLeadingZeroInExponent);
- QCOMPARE(locale.numberOptions(), QLocale::RejectLeadingZeroInExponent);
- locale.toDouble(QString("1.24e+1"), &ok);
- QVERIFY(ok);
- locale.toDouble(QString("1.24e+01"), &ok);
- QVERIFY(!ok);
-
- QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.4"));
- locale.setNumberOptions(QLocale::IncludeTrailingZeroesAfterDot);
- QCOMPARE(locale.numberOptions(), QLocale::IncludeTrailingZeroesAfterDot);
- QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.400"));
-
- locale.toDouble(QString("1.24e+01"), &ok);
- QVERIFY(ok);
- locale.toDouble(QString("1.2400e+01"), &ok);
- QVERIFY(ok);
- locale.toDouble(QString("12.4"), &ok);
- QVERIFY(ok);
- locale.toDouble(QString("12.400"), &ok);
- QVERIFY(ok);
- locale.setNumberOptions(QLocale::RejectTrailingZeroesAfterDot);
- QCOMPARE(locale.numberOptions(), QLocale::RejectTrailingZeroesAfterDot);
- locale.toDouble(QString("1.24e+01"), &ok);
- QVERIFY(ok);
- locale.toDouble(QString("1.2400e+01"), &ok);
- QVERIFY(!ok);
- locale.toDouble(QString("12.4"), &ok);
- QVERIFY(ok);
- locale.toDouble(QString("12.400"), &ok);
- QVERIFY(!ok);
-}
-
-void tst_QLocale::negativeNumbers()
-{
- QLocale locale(QLocale::C);
-
- bool ok;
- int i;
-
- i = locale.toInt(QLatin1String("-100"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -100);
-
- i = locale.toInt(QLatin1String("-1,000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -1000);
-
- i = locale.toInt(QLatin1String("-1000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -1000);
-
- i = locale.toInt(QLatin1String("-10,000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -10000);
-
- i = locale.toInt(QLatin1String("-10000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -10000);
-
- i = locale.toInt(QLatin1String("-100,000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -100000);
-
- i = locale.toInt(QLatin1String("-100000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -100000);
-
- i = locale.toInt(QLatin1String("-1,000,000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -1000000);
-
- i = locale.toInt(QLatin1String("-1000000"), &ok);
- QVERIFY(ok);
- QCOMPARE(i, -1000000);
-}
-
-#include <private/qlocale_p.h>
-#include <private/qlocale_data_p.h>
-
-static const int locale_data_count = sizeof(locale_data)/sizeof(locale_data[0]);
-
-void tst_QLocale::testNames_data()
-{
- QTest::addColumn<int>("language");
- QTest::addColumn<int>("country");
-
- QLocale::setDefault(QLocale(QLocale::C)); // Ensures predictable fall-backs
-
- for (int i = 0; i < locale_data_count; ++i) {
- const QLocaleData &item = locale_data[i];
-
- const QString testName = QLatin1String("data_") + QString::number(i) + QLatin1String(" (")
- + QLocale::languageToString((QLocale::Language)item.m_language_id)
- + QLatin1Char('/') + QLocale::countryToString((QLocale::Country)item.m_country_id)
- + QLatin1Char(')');
- QTest::newRow(testName.toLatin1().constData()) << (int)item.m_language_id << (int)item.m_country_id;
- }
-}
-
-void tst_QLocale::testNames()
-{
- QFETCH(int, language);
- QFETCH(int, country);
-
- QLocale l1((QLocale::Language)language, (QLocale::Country)country);
- if (language == QLocale::AnyLanguage && country == QLocale::AnyCountry)
- language = QLocale::C;
- QCOMPARE((int)l1.language(), language);
- QCOMPARE((int)l1.country(), country);
-
- QString name = l1.name();
-
- QLocale l2(name);
- QCOMPARE((int)l2.language(), language);
- QCOMPARE((int)l2.country(), country);
- QCOMPARE(l2.name(), name);
-
- QLocale l3(name + QLatin1String("@foo"));
- QCOMPARE((int)l3.language(), language);
- QCOMPARE((int)l3.country(), country);
- QCOMPARE(l3.name(), name);
-
- QLocale l4(name + QLatin1String(".foo"));
- QCOMPARE((int)l4.language(), language);
- QCOMPARE((int)l4.country(), country);
- QCOMPARE(l4.name(), name);
-
- if (language != QLocale::C) {
- int idx = name.indexOf(QLatin1Char('_'));
- QVERIFY(idx != -1);
- QString lang = name.left(idx);
-
- QCOMPARE((int)QLocale(lang).language(), language);
- QCOMPARE((int)QLocale(lang + QLatin1String("@foo")).language(), language);
- QCOMPARE((int)QLocale(lang + QLatin1String(".foo")).language(), language);
- }
-}
-
-void tst_QLocale::dayName_data()
-{
- QTest::addColumn<QString>("locale_name");
- QTest::addColumn<QString>("dayName");
- QTest::addColumn<int>("day");
- QTest::addColumn<QLocale::FormatType>("format");
-
- QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
-
- QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
- QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
- QTest::newRow("C narrow") << QString("C") << QString("7") << 7 << QLocale::NarrowFormat;
-
- QTest::newRow("ru_RU long")
- << QString("ru_RU")
- << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320"
- "\265\321\201\320\265\320\275\321\214\320\265")
- << 7 << QLocale::LongFormat;
- QTest::newRow("ru_RU short")
- << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
- QTest::newRow("ru_RU narrow")
- << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::NarrowFormat;
-}
-
-void tst_QLocale::dayName()
-{
- QFETCH(QString, locale_name);
- QFETCH(QString, dayName);
- QFETCH(int, day);
- QFETCH(QLocale::FormatType, format);
-
- QLocale l(locale_name);
- QCOMPARE(l.dayName(day, format), dayName);
-
- QLocale ir("ga_IE");
- QCOMPARE(ir.dayName(1, QLocale::ShortFormat), QLatin1String("Luan"));
- QCOMPARE(ir.dayName(7, QLocale::ShortFormat), QLatin1String("Domh"));
-
- QLocale gr("el_GR");
- QCOMPARE(gr.dayName(2, QLocale::ShortFormat), QString::fromUtf8("\316\244\317\201\316\257"));
- QCOMPARE(gr.dayName(4, QLocale::ShortFormat), QString::fromUtf8("\316\240\316\255\316\274"));
- QCOMPARE(gr.dayName(6, QLocale::ShortFormat), QString::fromUtf8("\316\243\316\254\316\262"));
-}
-
-void tst_QLocale::standaloneDayName_data()
-{
- QTest::addColumn<QString>("locale_name");
- QTest::addColumn<QString>("dayName");
- QTest::addColumn<int>("day");
- QTest::addColumn<QLocale::FormatType>("format");
-
- QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
-
- QTest::newRow("C invalid: 0 long") << QString("C") << QString() << 0 << QLocale::LongFormat;
- QTest::newRow("C invalid: 0 short") << QString("C") << QString() << 0 << QLocale::ShortFormat;
- QTest::newRow("C invalid: 0 narrow") << QString("C") << QString() << 0 << QLocale::NarrowFormat;
- QTest::newRow("C invalid: 8 long") << QString("C") << QString() << 8 << QLocale::LongFormat;
- QTest::newRow("C invalid: 8 short") << QString("C") << QString() << 8 << QLocale::ShortFormat;
- QTest::newRow("C invalid: 8 narrow") << QString("C") << QString() << 8 << QLocale::NarrowFormat;
-
- QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
- QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
- QTest::newRow("C narrow") << QString("C") << QString("S") << 7 << QLocale::NarrowFormat;
-
- QTest::newRow("ru_RU long")
- << QString("ru_RU")
- << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320"
- "\265\321\201\320\265\320\275\321\214\320\265")
- << 7 << QLocale::LongFormat;
- QTest::newRow("ru_RU short")
- << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
- QTest::newRow("ru_RU narrow")
- << QString("ru_RU") << QString::fromUtf8("\320\222") << 7 << QLocale::NarrowFormat;
-}
-
-void tst_QLocale::standaloneDayName()
-{
- QFETCH(QString, locale_name);
- QFETCH(QString, dayName);
- QFETCH(int, day);
- QFETCH(QLocale::FormatType, format);
-
- QLocale l(locale_name);
- QCOMPARE(l.standaloneDayName(day, format), dayName);
-}
-
-void tst_QLocale::underflowOverflow()
-{
- QString a(QLatin1String("0.") + QString(546, QLatin1Char('0')) + QLatin1String("1e10"));
- bool ok = false;
- double d = a.toDouble(&ok);
- QVERIFY(!ok);
- QCOMPARE(d, 0.0);
-
- a = QLatin1String("1e600");
- ok = false;
- d = a.toDouble(&ok);
- QVERIFY(!ok); // detectable overflow
- QVERIFY(qIsInf(d));
-
- a = QLatin1String("-1e600");
- ok = false;
- d = a.toDouble(&ok);
- QVERIFY(!ok); // detectable underflow
- QVERIFY(qIsInf(-d));
-
- a = QLatin1String("1e-600");
- ok = false;
- d = a.toDouble(&ok);
- QVERIFY(!ok);
- QCOMPARE(d, 0.0);
-
- a = QLatin1String("-9223372036854775809");
- a.toLongLong(&ok);
- QVERIFY(!ok);
-}
-
-void tst_QLocale::defaultNumberingSystem_data()
-{
- QTest::addColumn<QString>("expect");
-
- QTest::newRow("sk_SK") << QStringLiteral("123");
- QTest::newRow("ta_IN") << QStringLiteral("123");
- QTest::newRow("te_IN") << QStringLiteral("123");
- QTest::newRow("hi_IN") << QStringLiteral("123");
- QTest::newRow("gu_IN") << QStringLiteral("123");
- QTest::newRow("kn_IN") << QStringLiteral("123");
- QTest::newRow("pa_IN") << QStringLiteral("123");
- QTest::newRow("ne_IN") << QString::fromUtf8("१२३");
- QTest::newRow("mr_IN") << QString::fromUtf8("१२३");
- QTest::newRow("ml_IN") << QStringLiteral("123");
- QTest::newRow("kok_IN") << QStringLiteral("123");
-}
-
-void tst_QLocale::defaultNumberingSystem()
-{
- QFETCH(QString, expect);
- QLatin1String name(QTest::currentDataTag());
- QLocale locale(name);
- QCOMPARE(locale.toString(123), expect);
-}
-
-void tst_QLocale::ampm_data()
-{
- QTest::addColumn<QString>("morn");
- QTest::addColumn<QString>("even");
-
- QTest::newRow("C") << QStringLiteral("AM") << QStringLiteral("PM");
- QTest::newRow("de_DE") << QStringLiteral("AM") << QStringLiteral("PM");
- QTest::newRow("sv_SE") << QStringLiteral("fm") << QStringLiteral("em");
- QTest::newRow("nl_NL") << QStringLiteral("a.m.") << QStringLiteral("p.m.");
- QTest::newRow("uk_UA") << QString::fromUtf8("\320\264\320\277")
- << QString::fromUtf8("\320\277\320\277");
- QTest::newRow("tr_TR") << QString::fromUtf8("\303\226\303\226")
- << QString::fromUtf8("\303\226\123");
- QTest::newRow("id_ID") << QStringLiteral("AM") << QStringLiteral("PM");
- QTest::newRow("ta_LK") << QString::fromUtf8("முற்பகல்") << QString::fromUtf8("பிற்பகல்");
-}
-
-void tst_QLocale::ampm()
-{
- QFETCH(QString, morn);
- QFETCH(QString, even);
- QLatin1String name(QTest::currentDataTag());
- QLocale locale(name == QLatin1String("C") ? QLocale(QLocale::C) : QLocale(name));
- QCOMPARE(locale.amText(), morn);
- QCOMPARE(locale.pmText(), even);
-}
-
-void tst_QLocale::dateFormat()
-{
- const QLocale c(QLocale::C);
- // check that the NarrowFormat is the same as ShortFormat.
- QCOMPARE(c.dateFormat(QLocale::NarrowFormat), c.dateFormat(QLocale::ShortFormat));
-
- const QLocale no("no_NO");
- QCOMPARE(no.dateFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy"));
- QCOMPARE(no.dateFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy"));
- QCOMPARE(no.dateFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy"));
-
- const QLocale ca("en_CA");
- QCOMPARE(ca.dateFormat(QLocale::ShortFormat), QLatin1String("yyyy-MM-dd"));
- QCOMPARE(ca.dateFormat(QLocale::LongFormat), QLatin1String("dddd, MMMM d, yyyy"));
-
- const QLocale ja("ja_JP");
- QCOMPARE(ja.dateFormat(QLocale::ShortFormat), QLatin1String("yyyy/MM/dd"));
-
- const QLocale ir("ga_IE");
- QCOMPARE(ir.dateFormat(QLocale::ShortFormat), QLatin1String("dd/MM/yyyy"));
-}
-
-void tst_QLocale::timeFormat()
-{
- const QLocale c(QLocale::C);
- // check that the NarrowFormat is the same as ShortFormat.
- QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat));
-
- const QLocale no("no_NO");
- QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH.mm"));
- QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
- QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("HH.mm.ss t"));
-
- const QLocale id("id_ID");
- QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
- QCOMPARE(id.timeFormat(QLocale::LongFormat), QLatin1String("HH.mm.ss t"));
-
- const QLocale cat("ca_ES");
- QCOMPARE(cat.timeFormat(QLocale::ShortFormat), QLatin1String("H:mm"));
- QCOMPARE(cat.timeFormat(QLocale::LongFormat), QLatin1String("H:mm:ss t"));
-
- const QLocale bra("pt_BR");
- QCOMPARE(bra.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm"));
- QCOMPARE(bra.timeFormat(QLocale::LongFormat), QLatin1String("HH:mm:ss t"));
-}
-
-void tst_QLocale::dateTimeFormat()
-{
- const QLocale c(QLocale::C);
- // check that the NarrowFormat is the same as ShortFormat.
- QCOMPARE(c.dateTimeFormat(QLocale::NarrowFormat), c.dateTimeFormat(QLocale::ShortFormat));
-
- const QLocale no("no_NO");
- QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH.mm"));
- QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH.mm"));
- QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy HH.mm.ss t"));
-}
-
-void tst_QLocale::monthName()
-{
- const QLocale c(QLocale::C);
- QCOMPARE(c.monthName(0, QLocale::ShortFormat), QString());
- QCOMPARE(c.monthName(0, QLocale::LongFormat), QString());
- QCOMPARE(c.monthName(0, QLocale::NarrowFormat), QString());
- QCOMPARE(c.monthName(13, QLocale::ShortFormat), QString());
- QCOMPARE(c.monthName(13, QLocale::LongFormat), QString());
- QCOMPARE(c.monthName(13, QLocale::NarrowFormat), QString());
-
- QCOMPARE(c.monthName(1, QLocale::LongFormat), QLatin1String("January"));
- QCOMPARE(c.monthName(1, QLocale::ShortFormat), QLatin1String("Jan"));
- QCOMPARE(c.monthName(1, QLocale::NarrowFormat), QLatin1String("1"));
-
- const QLocale de("de_DE");
- QCOMPARE(de.monthName(12, QLocale::LongFormat), QLatin1String("Dezember"));
- QCOMPARE(de.monthName(12, QLocale::ShortFormat), QLatin1String("Dez."));
- // 'de' locale doesn't have narrow month name
- QCOMPARE(de.monthName(12, QLocale::NarrowFormat), QLatin1String("D"));
-
- QLocale ru("ru_RU");
- QCOMPARE(ru.monthName(1, QLocale::LongFormat),
- QString::fromUtf8("\321\217\320\275\320\262\320\260\321\200\321\217"));
- QCOMPARE(ru.monthName(1, QLocale::ShortFormat),
- QString::fromUtf8("\321\217\320\275\320\262\56"));
- QCOMPARE(ru.monthName(1, QLocale::NarrowFormat), QString::fromUtf8("\320\257"));
-
- QLocale ir("ga_IE");
- QCOMPARE(ir.monthName(1, QLocale::ShortFormat), QLatin1String("Ean"));
- QCOMPARE(ir.monthName(12, QLocale::ShortFormat), QLatin1String("Noll"));
-
- QLocale cz("cs_CZ");
- QCOMPARE(cz.monthName(1, QLocale::ShortFormat), QLatin1String("led"));
- QCOMPARE(cz.monthName(12, QLocale::ShortFormat), QLatin1String("pro"));
-}
-
-void tst_QLocale::standaloneMonthName()
-{
- const QLocale c(QLocale::C);
- QCOMPARE(c.monthName(0, QLocale::ShortFormat), QString());
- QCOMPARE(c.monthName(0, QLocale::LongFormat), QString());
- QCOMPARE(c.monthName(0, QLocale::NarrowFormat), QString());
- QCOMPARE(c.monthName(13, QLocale::ShortFormat), QString());
- QCOMPARE(c.monthName(13, QLocale::LongFormat), QString());
- QCOMPARE(c.monthName(13, QLocale::NarrowFormat), QString());
-
- QCOMPARE(c.standaloneMonthName(1, QLocale::LongFormat), QLatin1String("January"));
- QCOMPARE(c.standaloneMonthName(1, QLocale::ShortFormat), QLatin1String("Jan"));
-
- const QLocale de("de_DE");
- // For de_DE locale Unicode CLDR database doesn't contain standalone long months
- // so just checking if the return value is the same as in monthName().
- QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat), QLatin1String("Dezember"));
- QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat),
- de.monthName(12, QLocale::LongFormat));
- QCOMPARE(de.standaloneMonthName(12, QLocale::ShortFormat), QLatin1String("Dez"));
- QCOMPARE(de.standaloneMonthName(12, QLocale::NarrowFormat), QLatin1String("D"));
-
- QLocale ru("ru_RU");
- QCOMPARE(ru.standaloneMonthName(1, QLocale::LongFormat),
- QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c"));
- QCOMPARE(ru.standaloneMonthName(1, QLocale::ShortFormat),
- QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2."));
- QCOMPARE(ru.standaloneMonthName(1, QLocale::NarrowFormat), QString::fromUtf8("\xd0\xaf"));
-}
-
-void tst_QLocale::currency()
-{
- const QLocale c(QLocale::C);
- QCOMPARE(c.toCurrencyString(qulonglong(1234)), QString("1234"));
- QCOMPARE(c.toCurrencyString(qlonglong(-1234)), QString("-1234"));
- QCOMPARE(c.toCurrencyString(double(1234.56)), QString("1234.56"));
- QCOMPARE(c.toCurrencyString(double(-1234.56)), QString("-1234.56"));
- QCOMPARE(c.toCurrencyString(double(-1234.5678)), QString("-1234.57"));
- QCOMPARE(c.toCurrencyString(double(-1234.5678), NULL, 4), QString("-1234.5678"));
- QCOMPARE(c.toCurrencyString(double(-1234.56), NULL, 4), QString("-1234.5600"));
-
- const QLocale en_US("en_US");
- QCOMPARE(en_US.toCurrencyString(qulonglong(1234)), QString("$1,234"));
- QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("$-1,234"));
- QCOMPARE(en_US.toCurrencyString(double(1234.56)), QString("$1,234.56"));
- QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("$-1,234.56"));
- QCOMPARE(en_US.toCurrencyString(double(-1234.5678)), QString("$-1,234.57"));
- QCOMPARE(en_US.toCurrencyString(double(-1234.5678), NULL, 4), QString("$-1,234.5678"));
- QCOMPARE(en_US.toCurrencyString(double(-1234.56), NULL, 4), QString("$-1,234.5600"));
-
- const QLocale ru_RU("ru_RU");
- QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)),
- QString::fromUtf8("1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
- QCOMPARE(ru_RU.toCurrencyString(qlonglong(-1234)),
- QString::fromUtf8("-1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
- QCOMPARE(ru_RU.toCurrencyString(double(1234.56)),
- QString::fromUtf8("1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
- QCOMPARE(ru_RU.toCurrencyString(double(-1234.56)),
- QString::fromUtf8("-1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
-
- const QLocale de_DE("de_DE");
- QCOMPARE(de_DE.toCurrencyString(qulonglong(1234)),
- QString::fromUtf8("1.234\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(qulonglong(1234), QLatin1String("BAZ")),
- QString::fromUtf8("1.234\xc2\xa0" "BAZ"));
- QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234)),
- QString::fromUtf8("-1.234\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234), QLatin1String("BAZ")),
- QString::fromUtf8("-1.234\xc2\xa0" "BAZ"));
- QCOMPARE(de_DE.toCurrencyString(double(1234.56)),
- QString::fromUtf8("1.234,56\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(double(-1234.56)),
- QString::fromUtf8("-1.234,56\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")),
- QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ"));
-
- const QLocale es_CR(QLocale::Spanish, QLocale::CostaRica);
- QCOMPARE(es_CR.toCurrencyString(double(1565.25)),
- QString::fromUtf8("\xE2\x82\xA1" "1\xC2\xA0" "565,25"));
-
- const QLocale system = QLocale::system();
- QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO")));
-}
-
-void tst_QLocale::quoteString()
-{
- const QString someText("text");
- const QLocale c(QLocale::C);
- QCOMPARE(c.quoteString(someText), QString::fromUtf8("\x22" "text" "\x22"));
- QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation),
- QString::fromUtf8("\x27" "text" "\x27"));
-
- const QLocale de_CH("de_CH");
- QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xe2\x80\x9e" "text" "\xe2\x80\x9c"));
- QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation),
- QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98"));
-
-}
-
-void tst_QLocale::uiLanguages()
-{
- const QLocale c(QLocale::C);
- QCOMPARE(c.uiLanguages().size(), 1);
- QCOMPARE(c.uiLanguages().at(0), QLatin1String("C"));
-
- const QLocale en_US("en_US");
- QCOMPARE(en_US.uiLanguages().size(), 3);
- QCOMPARE(en_US.uiLanguages().at(0), QLatin1String("en"));
- QCOMPARE(en_US.uiLanguages().at(1), QLatin1String("en-US"));
- QCOMPARE(en_US.uiLanguages().at(2), QLatin1String("en-Latn-US"));
-
- const QLocale en_Latn_US("en_Latn_US");
- QCOMPARE(en_Latn_US.uiLanguages().size(), 3);
- QCOMPARE(en_Latn_US.uiLanguages().at(0), QLatin1String("en"));
- QCOMPARE(en_Latn_US.uiLanguages().at(1), QLatin1String("en-US"));
- QCOMPARE(en_Latn_US.uiLanguages().at(2), QLatin1String("en-Latn-US"));
-
- const QLocale en_GB("en_GB");
- QCOMPARE(en_GB.uiLanguages().size(), 2);
- QCOMPARE(en_GB.uiLanguages().at(0), QLatin1String("en-GB"));
- QCOMPARE(en_GB.uiLanguages().at(1), QLatin1String("en-Latn-GB"));
-
- const QLocale en_Dsrt_US("en_Dsrt_US");
- QCOMPARE(en_Dsrt_US.uiLanguages().size(), 2);
- QCOMPARE(en_Dsrt_US.uiLanguages().at(0), QLatin1String("en-Dsrt"));
- QCOMPARE(en_Dsrt_US.uiLanguages().at(1), QLatin1String("en-Dsrt-US"));
-
- const QLocale ru_RU("ru_RU");
- QCOMPARE(ru_RU.uiLanguages().size(), 3);
- QCOMPARE(ru_RU.uiLanguages().at(0), QLatin1String("ru"));
- QCOMPARE(ru_RU.uiLanguages().at(1), QLatin1String("ru-RU"));
- QCOMPARE(ru_RU.uiLanguages().at(2), QLatin1String("ru-Cyrl-RU"));
-
- const QLocale zh_Hant("zh_Hant");
- QCOMPARE(zh_Hant.uiLanguages().size(), 2);
- QCOMPARE(zh_Hant.uiLanguages().at(0), QLatin1String("zh-TW"));
- QCOMPARE(zh_Hant.uiLanguages().at(1), QLatin1String("zh-Hant-TW"));
-}
-
-void tst_QLocale::weekendDays()
-{
- const QLocale c(QLocale::C);
- QList<Qt::DayOfWeek> days;
- days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday;
- QCOMPARE(c.weekdays(), days);
-}
-
-void tst_QLocale::listPatterns()
-{
- QStringList sl1;
- QStringList sl2;
- sl2 << "aaa";
- QStringList sl3;
- sl3 << "aaa" << "bbb";
- QStringList sl4;
- sl4 << "aaa" << "bbb" << "ccc";
- QStringList sl5;
- sl5 << "aaa" << "bbb" << "ccc" << "ddd";
-
- const QLocale c(QLocale::C);
- QCOMPARE(c.createSeparatedList(sl1), QString(""));
- QCOMPARE(c.createSeparatedList(sl2), QString("aaa"));
- QCOMPARE(c.createSeparatedList(sl3), QString("aaa, bbb"));
- QCOMPARE(c.createSeparatedList(sl4), QString("aaa, bbb, ccc"));
- QCOMPARE(c.createSeparatedList(sl5), QString("aaa, bbb, ccc, ddd"));
-
- const QLocale en_US("en_US");
- QCOMPARE(en_US.createSeparatedList(sl1), QString(""));
- QCOMPARE(en_US.createSeparatedList(sl2), QString("aaa"));
- QCOMPARE(en_US.createSeparatedList(sl3), QString("aaa and bbb"));
- QCOMPARE(en_US.createSeparatedList(sl4), QString("aaa, bbb, and ccc"));
- QCOMPARE(en_US.createSeparatedList(sl5), QString("aaa, bbb, ccc, and ddd"));
-
- const QLocale zh_CN("zh_CN");
- QCOMPARE(zh_CN.createSeparatedList(sl1), QString(""));
- QCOMPARE(zh_CN.createSeparatedList(sl2), QString("aaa"));
- QCOMPARE(zh_CN.createSeparatedList(sl3), QString::fromUtf8("aaa" "\xe5\x92\x8c" "bbb"));
- QCOMPARE(zh_CN.createSeparatedList(sl4),
- QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe5\x92\x8c" "ccc"));
- QCOMPARE(zh_CN.createSeparatedList(sl5),
- QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81"
- "ccc" "\xe5\x92\x8c" "ddd"));
-}
-
-void tst_QLocale::measurementSystems_data()
-{
- QTest::addColumn<QLocale>("locale");
- QTest::addColumn<QLocale::MeasurementSystem>("system");
- QTest::newRow("en_US") << QLocale(QLocale::English, QLocale::UnitedStates) << QLocale::ImperialUSSystem;
- QTest::newRow("en_GB") << QLocale(QLocale::English, QLocale::UnitedKingdom) << QLocale::ImperialUKSystem;
- QTest::newRow("en_AU") << QLocale(QLocale::English, QLocale::Australia) << QLocale::MetricSystem;
- QTest::newRow("de") << QLocale(QLocale::German) << QLocale::MetricSystem;
-}
-
-void tst_QLocale::measurementSystems()
-{
- QFETCH(QLocale, locale);
- QFETCH(QLocale::MeasurementSystem, system);
- QCOMPARE(locale.measurementSystem(), system);
-}
-
-void tst_QLocale::QTBUG_26035_positivesign()
-{
- QLocale locale(QLocale::C);
- bool ok (false);
- QCOMPARE(locale.toInt(QString("+100,000"), &ok), 100000);
- QVERIFY(ok);
- ok = false;
- QCOMPARE(locale.toInt(QString("+100,000,000"), &ok), 100000000);
- QVERIFY(ok);
- ok = false;
- QCOMPARE(locale.toLongLong(QString("+100,000"), &ok), (qlonglong)100000);
- QVERIFY(ok);
- ok = false;
- QCOMPARE(locale.toLongLong(QString("+100,000,000"), &ok), (qlonglong)100000000);
- QVERIFY(ok);
-}
-
-void tst_QLocale::textDirection_data()
-{
- QTest::addColumn<int>("language");
- QTest::addColumn<int>("script");
- QTest::addColumn<bool>("rightToLeft");
-
- for (int language = QLocale::C; language <= QLocale::LastLanguage; ++language) {
- bool rightToLeft = false;
- switch (language) {
- // based on likelySubtags for RTL scripts
- case QLocale::AncientGreek:
- case QLocale::AncientNorthArabian:
- case QLocale::Arabic:
- case QLocale::Aramaic:
- case QLocale::Avestan:
- case QLocale::CentralKurdish:
- case QLocale::ClassicalMandaic:
- case QLocale::Divehi:
-// case QLocale::Fulah:
-// case QLocale::Hausa:
- case QLocale::Hebrew:
-// case QLocale::Hungarian:
- case QLocale::Kashmiri:
-// case QLocale::Kurdish:
- case QLocale::Lydian:
- case QLocale::Mandingo:
- case QLocale::ManichaeanMiddlePersian:
- case QLocale::Mazanderani:
- case QLocale::Mende:
- case QLocale::Meroitic:
- case QLocale::Nko:
- case QLocale::NorthernLuri:
- case QLocale::OldTurkish:
- case QLocale::Pahlavi:
- case QLocale::Parthian:
- case QLocale::Pashto:
- case QLocale::Persian:
- case QLocale::Phoenician:
- case QLocale::PrakritLanguage:
- case QLocale::Sabaean:
- case QLocale::Samaritan:
- case QLocale::Sindhi:
- case QLocale::Syriac:
- case QLocale::Uighur:
- case QLocale::Urdu:
- case QLocale::Yiddish:
- // false if there is no locale data for language:
- rightToLeft = (QLocale(QLocale::Language(language)).language()
- == QLocale::Language(language));
- break;
- default:
- break;
- }
- const QLatin1String testName = QLocalePrivate::languageToCode(QLocale::Language(language));
- QTest::newRow(qPrintable(testName)) << language << int(QLocale::AnyScript) << rightToLeft;
- }
- QTest::newRow("pa_Arab") << int(QLocale::Punjabi) << int(QLocale::ArabicScript) << true;
- QTest::newRow("uz_Arab") << int(QLocale::Uzbek) << int(QLocale::ArabicScript) << true;
-}
-
-void tst_QLocale::textDirection()
-{
- QFETCH(int, language);
- QFETCH(int, script);
- QFETCH(bool, rightToLeft);
-
- QLocale locale(QLocale::Language(language), QLocale::Script(script), QLocale::AnyCountry);
- QCOMPARE(locale.textDirection() == Qt::RightToLeft, rightToLeft);
-}
-
-void tst_QLocale::formattedDataSize_data()
-{
- QTest::addColumn<QLocale::Language>("language");
- QTest::addColumn<int>("decimalPlaces");
- QTest::addColumn<QLocale::DataSizeFormats>("units");
- QTest::addColumn<int>("bytes");
- QTest::addColumn<QString>("output");
-
- struct {
- const char *name;
- QLocale::Language lang;
- const char *bytes;
- const char abbrev;
- const char sep; // decimal separator
- } data[] = {
- { "English", QLocale::English, "bytes", 'B', '.' },
- { "French", QLocale::French, "octets", 'o', ',' },
- { "C", QLocale::C, "bytes", 'B', '.' }
- };
-
- for (const auto row : data) {
-#define ROWB(id, deci, num, text) \
- QTest::addRow("%s-%s", row.name, id) \
- << row.lang << deci << format \
- << num << (QString(text) + QChar(' ') + QString(row.bytes))
-#define ROWQ(id, deci, num, head, tail) \
- QTest::addRow("%s-%s", row.name, id) \
- << row.lang << deci << format \
- << num << (QString(head) + QChar(row.sep) + QString(tail) + QChar(row.abbrev))
-
- // Metatype system fails to handle raw enum members as format; needs variable
- {
- const QLocale::DataSizeFormats format = QLocale::DataSizeIecFormat;
- ROWB("IEC-0", 2, 0, "0");
- ROWB("IEC-10", 2, 10, "10");
- ROWQ("IEC-12Ki", 2, 12345, "12", "06 Ki");
- ROWQ("IEC-16Ki", 2, 16384, "16", "00 Ki");
- ROWQ("IEC-1235k", 2, 1234567, "1", "18 Mi");
- ROWQ("IEC-1374k", 2, 1374744, "1", "31 Mi");
- ROWQ("IEC-1234M", 2, 1234567890, "1", "15 Gi");
- }
- {
- const QLocale::DataSizeFormats format = QLocale::DataSizeTraditionalFormat;
- ROWB("Trad-0", 2, 0, "0");
- ROWB("Trad-10", 2, 10, "10");
- ROWQ("Trad-12Ki", 2, 12345, "12", "06 k");
- ROWQ("Trad-16Ki", 2, 16384, "16", "00 k");
- ROWQ("Trad-1235k", 2, 1234567, "1", "18 M");
- ROWQ("Trad-1374k", 2, 1374744, "1", "31 M");
- ROWQ("Trad-1234M", 2, 1234567890, "1", "15 G");
- }
- {
- const QLocale::DataSizeFormats format = QLocale::DataSizeSIFormat;
- ROWB("Decimal-0", 2, 0, "0");
- ROWB("Decimal-10", 2, 10, "10");
- ROWQ("Decimal-16Ki", 2, 16384, "16", "38 k");
- ROWQ("Decimal-1234k", 2, 1234567, "1", "23 M");
- ROWQ("Decimal-1374k", 2, 1374744, "1", "37 M");
- ROWQ("Decimal-1234M", 2, 1234567890, "1", "23 G");
- }
-#undef ROWQ
-#undef ROWB
- }
-
- // Languages which don't use a Latin alphabet
-
- const QLocale::DataSizeFormats iecFormat = QLocale::DataSizeIecFormat;
- const QLocale::DataSizeFormats traditionalFormat = QLocale::DataSizeTraditionalFormat;
- const QLocale::DataSizeFormats siFormat = QLocale::DataSizeSIFormat;
- const QLocale::Language lang = QLocale::Russian;
-
- QTest::newRow("Russian-IEC-0") << lang << 2 << iecFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
- QTest::newRow("Russian-IEC-10") << lang << 2 << iecFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
- // CLDR doesn't provide IEC prefixes (yet?) so they aren't getting translated
- QTest::newRow("Russian-IEC-12Ki") << lang << 2 << iecFormat << 12345 << QString("12,06 KiB");
- QTest::newRow("Russian-IEC-16Ki") << lang << 2 << iecFormat << 16384 << QString("16,00 KiB");
- QTest::newRow("Russian-IEC-1235k") << lang << 2 << iecFormat << 1234567 << QString("1,18 MiB");
- QTest::newRow("Russian-IEC-1374k") << lang << 2 << iecFormat << 1374744 << QString("1,31 MiB");
- QTest::newRow("Russian-IEC-1234M") << lang << 2 << iecFormat << 1234567890 << QString("1,15 GiB");
-
- QTest::newRow("Russian-Trad-0") << lang << 2 << traditionalFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
- QTest::newRow("Russian-Trad-10") << lang << 2 << traditionalFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
- QTest::newRow("Russian-Trad-12Ki") << lang << 2 << traditionalFormat << 12345 << QString("12,06 \u043A\u0411");
- QTest::newRow("Russian-Trad-16Ki") << lang << 2 << traditionalFormat << 16384 << QString("16,00 \u043A\u0411");
- QTest::newRow("Russian-Trad-1235k") << lang << 2 << traditionalFormat << 1234567 << QString("1,18 \u041C\u0411");
- QTest::newRow("Russian-Trad-1374k") << lang << 2 << traditionalFormat << 1374744 << QString("1,31 \u041C\u0411");
- QTest::newRow("Russian-Trad-1234M") << lang << 2 << traditionalFormat << 1234567890 << QString("1,15 \u0413\u0411");
-
- QTest::newRow("Russian-Decimal-0") << lang << 2 << siFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
- QTest::newRow("Russian-Decimal-10") << lang << 2 << siFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
- QTest::newRow("Russian-Decimal-16Ki") << lang << 2 << siFormat << 16384 << QString("16,38 \u043A\u0411");
- QTest::newRow("Russian-Decimal-1234k") << lang << 2 << siFormat << 1234567 << QString("1,23 \u041C\u0411");
- QTest::newRow("Russian-Decimal-1374k") << lang << 2 << siFormat << 1374744 << QString("1,37 \u041C\u0411");
- QTest::newRow("Russian-Decimal-1234M") << lang << 2 << siFormat << 1234567890 << QString("1,23 \u0413\u0411");
-}
-
-void tst_QLocale::formattedDataSize()
-{
- QFETCH(QLocale::Language, language);
- QFETCH(int, decimalPlaces);
- QFETCH(QLocale::DataSizeFormats, units);
- QFETCH(int, bytes);
- QFETCH(QString, output);
- QCOMPARE(QLocale(language).formattedDataSize(bytes, decimalPlaces, units), output);
-}
-
-void tst_QLocale::bcp47Name_data()
-{
- QTest::addColumn<QString>("expect");
-
- QTest::newRow("C") << QStringLiteral("en");
- QTest::newRow("en") << QStringLiteral("en");
- QTest::newRow("en_US") << QStringLiteral("en");
- QTest::newRow("en_GB") << QStringLiteral("en-GB");
- QTest::newRow("en_DE") << QStringLiteral("en-DE");
- QTest::newRow("de_DE") << QStringLiteral("de");
- QTest::newRow("sr_RS") << QStringLiteral("sr");
- QTest::newRow("sr_Cyrl_RS") << QStringLiteral("sr");
- QTest::newRow("sr_Latn_RS") << QStringLiteral("sr-Latn");
- QTest::newRow("sr_ME") << QStringLiteral("sr-ME");
- QTest::newRow("sr_Cyrl_ME") << QStringLiteral("sr-Cyrl-ME");
- QTest::newRow("sr_Latn_ME") << QStringLiteral("sr-ME");
-
- // Fall back to defaults when country isn't in CLDR for this language:
- QTest::newRow("sr_HR") << QStringLiteral("sr");
- QTest::newRow("sr_Cyrl_HR") << QStringLiteral("sr");
- QTest::newRow("sr_Latn_HR") << QStringLiteral("sr-Latn");
-}
-
-void tst_QLocale::bcp47Name()
-{
- QFETCH(QString, expect);
- QCOMPARE(QLocale(QLatin1String(QTest::currentDataTag())).bcp47Name(), expect);
-}
-
-class MySystemLocale : public QSystemLocale
-{
-public:
- MySystemLocale(const QLocale &locale) : m_locale(locale)
- {
- }
-
- QVariant query(QueryType /*type*/, QVariant /*in*/) const override
- {
- return QVariant();
- }
-
- QLocale fallbackUiLocale() const override
- {
- return m_locale;
- }
-
-private:
- const QLocale m_locale;
-};
-
-void tst_QLocale::systemLocale_data()
-{
- QTest::addColumn<QString>("name");
- QTest::addColumn<QLocale::Language>("language");
- QTest::addRow("catalan") << QString("ca") << QLocale::Catalan;
- QTest::addRow("ukrainian") << QString("uk") << QLocale::Ukrainian;
- QTest::addRow("german") << QString("de") << QLocale::German;
-}
-
-void tst_QLocale::systemLocale()
-{
- QLocale originalLocale;
- QLocale originalSystemLocale = QLocale::system();
-
- QFETCH(QString, name);
- QFETCH(QLocale::Language, language);
-
- {
- MySystemLocale sLocale(name);
- QCOMPARE(QLocale().language(), language);
- QCOMPARE(QLocale::system().language(), language);
- }
-
- QCOMPARE(QLocale(), originalLocale);
- QCOMPARE(QLocale::system(), originalSystemLocale);
-}
-
-QTEST_MAIN(tst_QLocale)
-#include "tst_qlocale.moc"
diff --git a/tests/auto/corelib/tools/qmacautoreleasepool/CMakeLists.txt b/tests/auto/corelib/tools/qmacautoreleasepool/CMakeLists.txt
new file mode 100644
index 0000000000..b968945ac6
--- /dev/null
+++ b/tests/auto/corelib/tools/qmacautoreleasepool/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmacautoreleasepool Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmacautoreleasepool LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmacautoreleasepool
+ SOURCES
+ tst_qmacautoreleasepool.mm
+ LIBRARIES
+ Qt::CorePrivate
+ ${FWFoundation}
+)
diff --git a/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro b/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro
deleted file mode 100644
index 8599596344..0000000000
--- a/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmacautoreleasepool
-QT = core testlib
-SOURCES = tst_qmacautoreleasepool.mm
-LIBS += -framework Foundation
diff --git a/tests/auto/corelib/tools/qmacautoreleasepool/tst_qmacautoreleasepool.mm b/tests/auto/corelib/tools/qmacautoreleasepool/tst_qmacautoreleasepool.mm
index 8f1069f419..e7923b47f3 100644
--- a/tests/auto/corelib/tools/qmacautoreleasepool/tst_qmacautoreleasepool.mm
+++ b/tests/auto/corelib/tools/qmacautoreleasepool/tst_qmacautoreleasepool.mm
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
+#include <QTest>
+
+#include <QtCore/private/qcore_mac_p.h>
#include <Foundation/Foundation.h>
@@ -37,7 +14,6 @@ private slots:
void noPool();
void rootLevelPool();
void stackAllocatedPool();
- void heapAllocatedPool();
};
static id lastDeallocedObject = nil;
@@ -86,26 +62,6 @@ void tst_QMacAutoreleasePool::stackAllocatedPool()
[pool drain];
}
-void tst_QMacAutoreleasePool::heapAllocatedPool()
-{
- // The special case, a pool allocated on the heap, or as a member of a
- // heap allocated object. This is not a supported use of QMacAutoReleasePool,
- // and will result in warnings if the pool is prematurely drained.
-
- NSObject *allocedObject = nil;
- {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- QMacAutoReleasePool *qtPool = nullptr;
- {
- qtPool = new QMacAutoReleasePool;
- allocedObject = [[[DeallocTracker alloc] init] autorelease];
- }
- [pool drain];
- delete qtPool;
- }
- QCOMPARE(lastDeallocedObject, allocedObject);
-}
-
QTEST_APPLESS_MAIN(tst_QMacAutoreleasePool)
#include "tst_qmacautoreleasepool.moc"
diff --git a/tests/auto/corelib/tools/qmakearray/CMakeLists.txt b/tests/auto/corelib/tools/qmakearray/CMakeLists.txt
new file mode 100644
index 0000000000..cec589628f
--- /dev/null
+++ b/tests/auto/corelib/tools/qmakearray/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmakearray Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmakearray LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmakearray
+ SOURCES
+ tst_qmakearray.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qmakearray/qmakearray.pro b/tests/auto/corelib/tools/qmakearray/qmakearray.pro
deleted file mode 100644
index abb3d9fdbc..0000000000
--- a/tests/auto/corelib/tools/qmakearray/qmakearray.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmakearray
-QT = core testlib core-private
-SOURCES = $$PWD/tst_qmakearray.cpp
diff --git a/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp b/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp
index e0d3f52719..1d796452b0 100644
--- a/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp
+++ b/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
+#include <QTest>
#include <private/qmakearray_p.h>
diff --git a/tests/auto/corelib/tools/qmap/CMakeLists.txt b/tests/auto/corelib/tools/qmap/CMakeLists.txt
new file mode 100644
index 0000000000..bddf9267f8
--- /dev/null
+++ b/tests/auto/corelib/tools/qmap/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmap Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmap LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmap
+ SOURCES
+ tst_qmap.cpp
+)
+
+qt_internal_undefine_global_definition(tst_qmap QT_NO_JAVA_STYLE_ITERATORS)
diff --git a/tests/auto/corelib/tools/qmap/qmap.pro b/tests/auto/corelib/tools/qmap/qmap.pro
deleted file mode 100644
index 27820a76c8..0000000000
--- a/tests/auto/corelib/tools/qmap/qmap.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmap
-QT = core testlib
-SOURCES = $$PWD/tst_qmap.cpp
diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp
index b39444e76f..6950dcf705 100644
--- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp
+++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp
@@ -1,42 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qmap.h>
-#include <QtTest/QtTest>
+#include <QTest>
+
#include <QDebug>
+#include <QScopeGuard>
+
+using namespace Qt::StringLiterals;
+QT_WARNING_DISABLE_DEPRECATED
class tst_QMap : public QObject
{
Q_OBJECT
protected:
- template <class KEY, class VALUE>
- void sanityCheckTree(const QMap<KEY, VALUE> &m, int calledFromLine);
+ template <class Map>
+ void sanityCheckTree(const Map &m, int calledFromLine);
public slots:
void init();
private slots:
@@ -46,6 +26,7 @@ private slots:
void beginEnd();
void firstLast();
void key();
+ void value();
void swap();
@@ -60,22 +41,38 @@ private slots:
void take();
void iterators();
+ void multimapIterators();
+ void iteratorsInEmptyMap();
void keyIterator();
+ void multimapKeyIterator();
void keyValueIterator();
+ void multimapKeyValueIterator();
+ void keyValueIteratorInEmptyMap();
void keys_values_uniqueKeys();
void qmultimap_specific();
void const_shared_null();
void equal_range();
- void setSharable();
void insert();
+ void insertMap();
void checkMostLeftNode();
void initializerList();
void testInsertWithHint();
void testInsertMultiWithHint();
void eraseValidIteratorOnSharedMap();
+ void removeElementsInMap();
+ void toStdMap();
+
+ void multiMapStoresInReverseInsertionOrder();
+
+ // Tests for deprecated APIs.
+#if QT_DEPRECATED_SINCE(6, 0)
+ void deprecatedInsertMulti();
+ void deprecatedIteratorApis();
+ void deprecatedInsert();
+#endif // QT_DEPRECATED_SINCE(6, 0)
};
struct IdentityTracker {
@@ -112,21 +109,22 @@ public:
int MyClass::count = 0;
typedef QMap<QString, MyClass> MyMap;
+typedef QMultiMap<QString, MyClass> MyMultiMap;
QDebug operator << (QDebug d, const MyClass &c) {
d << c.str;
return d;
}
-template <class KEY, class VALUE>
-void tst_QMap::sanityCheckTree(const QMap<KEY, VALUE> &m, int calledFromLine)
+template <class Map>
+void tst_QMap::sanityCheckTree(const Map &m, int calledFromLine)
{
QString possibleFrom;
possibleFrom.setNum(calledFromLine);
possibleFrom = "Called from line: " + possibleFrom;
int count = 0;
- typename QMap<KEY, VALUE>::const_iterator oldite = m.constBegin();
- for (typename QMap<KEY, VALUE>::const_iterator i = m.constBegin(); i != m.constEnd(); ++i) {
+ typename Map::const_iterator oldite = m.constBegin();
+ for (typename Map::const_iterator i = m.constBegin(); i != m.constEnd(); ++i) {
count++;
bool oldIteratorIsLarger = i.key() < oldite.key();
QVERIFY2(!oldIteratorIsLarger, possibleFrom.toUtf8());
@@ -174,13 +172,21 @@ void tst_QMap::count()
{
MyMap map;
MyMap map2( map );
- QCOMPARE( map.count(), 0 );
- QCOMPARE( map2.count(), 0 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map2.size(), 0 );
QCOMPARE( MyClass::count, int(0) );
+ QCOMPARE(map.count("key"), 0);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 0);
+ QVERIFY(!map.isDetached());
+ QVERIFY(!map2.isDetached());
// detach
map2["Hallo"] = MyClass( "Fritz" );
- QCOMPARE( map.count(), 0 );
- QCOMPARE( map2.count(), 1 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map.size(), 0 );
+ QCOMPARE( map2.size(), 1 );
+ QCOMPARE( map2.size(), 1 );
+ QVERIFY(!map.isDetached());
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 1 );
#endif
@@ -190,11 +196,11 @@ void tst_QMap::count()
{
typedef QMap<QString, MyClass> Map;
Map map;
- QCOMPARE( map.count(), 0);
+ QCOMPARE( map.size(), 0);
map.insert( "Torben", MyClass("Weis") );
- QCOMPARE( map.count(), 1 );
+ QCOMPARE( map.size(), 1 );
map.insert( "Claudia", MyClass("Sorg") );
- QCOMPARE( map.count(), 2 );
+ QCOMPARE( map.size(), 2 );
map.insert( "Lars", MyClass("Linzbach") );
map.insert( "Matthias", MyClass("Ettrich") );
map.insert( "Sue", MyClass("Paludo") );
@@ -202,7 +208,7 @@ void tst_QMap::count()
map.insert( "Haavard", MyClass("Nord") );
map.insert( "Arnt", MyClass("Gulbrandsen") );
map.insert( "Paul", MyClass("Tvete") );
- QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.size(), 9 );
map.insert( "Paul", MyClass("Tvete 1") );
map.insert( "Paul", MyClass("Tvete 2") );
map.insert( "Paul", MyClass("Tvete 3") );
@@ -210,69 +216,69 @@ void tst_QMap::count()
map.insert( "Paul", MyClass("Tvete 5") );
map.insert( "Paul", MyClass("Tvete 6") );
- QCOMPARE( map.count(), 9 );
+ QCOMPARE( map.size(), 9 );
QCOMPARE( map.count("Paul"), 1 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
Map map2( map );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.insert( "Kay", MyClass("Roemer") );
- QVERIFY( map2.count() == 10 );
- QVERIFY( map.count() == 9 );
+ QVERIFY( map2.size() == 10 );
+ QVERIFY( map.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 19 );
#endif
map2 = map;
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.insert( "Kay", MyClass("Roemer") );
- QVERIFY( map2.count() == 10 );
+ QVERIFY( map2.size() == 10 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 19 );
#endif
map2.clear();
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2 = map;
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 9 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 9 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map2.clear();
- QVERIFY( map.count() == 9 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 9 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 9 );
#endif
map.remove( "Lars" );
- QVERIFY( map.count() == 8 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 8 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 8 );
#endif
map.remove( "Mist" );
- QVERIFY( map.count() == 8 );
- QVERIFY( map2.count() == 0 );
+ QVERIFY( map.size() == 8 );
+ QVERIFY( map2.size() == 0 );
#ifndef Q_CC_SUN
QCOMPARE( MyClass::count, 8 );
#endif
@@ -286,22 +292,22 @@ void tst_QMap::count()
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 1 );
#endif
- QVERIFY( map.count() == 1 );
+ QVERIFY( map.size() == 1 );
(void)map["Torben"].str;
(void)map["Lars"].str;
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 2 );
#endif
- QVERIFY( map.count() == 2 );
+ QVERIFY( map.size() == 2 );
const Map& cmap = map;
(void)cmap["Depp"].str;
#ifndef Q_CC_SUN
QVERIFY( MyClass::count == 2 );
#endif
- QVERIFY( map.count() == 2 );
- QVERIFY( cmap.count() == 2 );
+ QVERIFY( map.size() == 2 );
+ QVERIFY( cmap.size() == 2 );
}
QCOMPARE( MyClass::count, 0 );
{
@@ -314,6 +320,45 @@ void tst_QMap::count()
QCOMPARE( MyClass::count, 0 );
}
QCOMPARE( MyClass::count, 0 );
+
+ {
+ QMultiMap<int, MyClass> map;
+ QMultiMap<int, MyClass> map2(map);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 0);
+ QCOMPARE(MyClass::count, 0);
+ QCOMPARE(map.count(1), 0);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 0);
+ QVERIFY(!map.isDetached());
+ QVERIFY(!map2.isDetached());
+
+ // detach
+ map2.insert(0, MyClass("value0"));
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 1);
+ QCOMPARE(map2.size(), 1);
+ QVERIFY(!map.isDetached());
+ QCOMPARE(MyClass::count, 1);
+
+ map2.insert(1, MyClass("value1"));
+ map2.insert(2, MyClass("value2"));
+ QCOMPARE(map2.size(), 3);
+ QCOMPARE(MyClass::count, 3);
+
+ map2.insert(0, MyClass("value0_1"));
+ map2.insert(0, MyClass("value0_2"));
+ QCOMPARE(map2.size(), 5);
+ QCOMPARE(map2.count(0), 3);
+ QCOMPARE(MyClass::count, 5);
+
+ map2.clear();
+ QCOMPARE(map2.size(), 0);
+ QCOMPARE(MyClass::count, 0);
+
+ }
+ QCOMPARE(MyClass::count, 0);
}
void tst_QMap::clear()
@@ -321,18 +366,40 @@ void tst_QMap::clear()
{
MyMap map;
map.clear();
- QVERIFY( map.isEmpty() );
+ QVERIFY(map.isEmpty());
+ QVERIFY(!map.isDetached());
map.insert( "key", MyClass( "value" ) );
+ QVERIFY(!map.isEmpty());
map.clear();
- QVERIFY( map.isEmpty() );
+ QVERIFY(map.isEmpty());
map.insert( "key0", MyClass( "value0" ) );
map.insert( "key0", MyClass( "value1" ) );
map.insert( "key1", MyClass( "value2" ) );
+ QVERIFY(!map.isEmpty());
map.clear();
sanityCheckTree(map, __LINE__);
- QVERIFY( map.isEmpty() );
+ QVERIFY(map.isEmpty());
}
- QCOMPARE( MyClass::count, int(0) );
+ QCOMPARE(MyClass::count, int(0));
+
+ {
+ MyMultiMap map;
+ map.clear();
+ QVERIFY(map.isEmpty());
+ QVERIFY(!map.isDetached());
+ map.insert( "key", MyClass( "value" ) );
+ QVERIFY(!map.isEmpty());
+ map.clear();
+ QVERIFY(map.isEmpty());
+ map.insert( "key0", MyClass( "value0" ) );
+ map.insert( "key0", MyClass( "value1" ) );
+ map.insert( "key1", MyClass( "value2" ) );
+ QVERIFY(!map.isEmpty());
+ map.clear();
+ sanityCheckTree(map, __LINE__);
+ QVERIFY(map.isEmpty());
+ }
+ QCOMPARE(MyClass::count, int(0));
}
void tst_QMap::beginEnd()
@@ -368,7 +435,12 @@ void tst_QMap::beginEnd()
// detach
map2.insert( "2", "c" );
QVERIFY( map.constBegin() == map.constBegin() );
- QVERIFY( map.constBegin() != map2.constBegin() );
+
+ // comparing iterators between two different std::map is UB (and raises an
+ // assertion failure with MSVC debug-mode iterators), so we compare the
+ // elements' addresses.
+ QVERIFY(&map.constBegin().key() != &map2.constBegin().key());
+ QVERIFY(&map.constBegin().value() != &map2.constBegin().value());
}
void tst_QMap::firstLast()
@@ -407,6 +479,7 @@ void tst_QMap::key()
QMap<QString, int> map1;
QCOMPARE(map1.key(1), QString());
QCOMPARE(map1.key(1, def), def);
+ QVERIFY(!map1.isDetached());
map1.insert("one", 1);
QCOMPARE(map1.key(1), QLatin1String("one"));
@@ -437,6 +510,7 @@ void tst_QMap::key()
QMap<int, QString> map2;
QCOMPARE(map2.key("one"), 0);
QCOMPARE(map2.key("one", def), def);
+ QVERIFY(!map2.isDetached());
map2.insert(1, "one");
QCOMPARE(map2.key("one"), 1);
@@ -468,6 +542,82 @@ void tst_QMap::key()
QCOMPARE(map2.key("zero"), 0);
QCOMPARE(map2.key("zero", def), 0);
}
+
+ {
+ int def = -1;
+ QMultiMap<int, QString> multiMap;
+ QCOMPARE(multiMap.key("value0"), 0);
+ QCOMPARE(multiMap.key("value0", def), def);
+ QVERIFY(!multiMap.isDetached());
+
+ multiMap.insert(1, "value1");
+ multiMap.insert(2, "value2");
+ multiMap.insert(1, "value1_1");
+
+ QCOMPARE(multiMap.key("value1"), 1);
+ QCOMPARE(multiMap.key("value1", def), 1);
+ QCOMPARE(multiMap.key("value1_1"), 1);
+ QCOMPARE(multiMap.key("value2"), 2);
+ QCOMPARE(multiMap.key("value3"), 0);
+ QCOMPARE(multiMap.key("value3", def), def);
+ }
+}
+
+void tst_QMap::value()
+{
+ const QString def = "default value";
+ {
+ QMap<int, QString> map;
+ QCOMPARE(map.value(1), QString());
+ QCOMPARE(map.value(1, def), def);
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ QCOMPARE(map.value(1), "value1");
+ QCOMPARE(map[1], "value1");
+ QCOMPARE(map.value(2), QString());
+ QCOMPARE(map.value(2, def), def);
+ QCOMPARE(map[2], QString());
+ QCOMPARE(map.size(), 2);
+
+ map.insert(2, "value2");
+ QCOMPARE(map.value(2), "value2");
+ QCOMPARE(map[2], "value2");
+
+ map.insert(1, "value3");
+ QCOMPARE(map.value(1), "value3");
+ QCOMPARE(map.value(1, def), "value3");
+ QCOMPARE(map[1], "value3");
+
+ const QMap<int, QString> constMap;
+ QVERIFY(!constMap.isDetached());
+ QCOMPARE(constMap.value(1, def), def);
+ QCOMPARE(constMap[1], QString());
+ QCOMPARE(constMap.size(), 0);
+ QVERIFY(!constMap.isDetached());
+ }
+ {
+ QMultiMap<int, QString> map;
+ QCOMPARE(map.value(1), QString());
+ QCOMPARE(map.value(1, def), def);
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ QCOMPARE(map.value(1), "value1");
+ QCOMPARE(map.value(2), QString());
+ QCOMPARE(map.value(2, def), def);
+
+ map.insert(2, "value2");
+ QCOMPARE(map.value(2), "value2");
+
+ map.insert(1, "value3");
+ // If multiple values exist, the most recently added is returned.
+ QCOMPARE(map.value(1), "value3");
+ QCOMPARE(map.value(1, def), "value3");
+
+ map.remove(1, "value3");
+ QCOMPARE(map.value(1), "value1");
+ }
}
void tst_QMap::swap()
@@ -490,16 +640,19 @@ void tst_QMap::operator_eq()
QMap<int, int> b;
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert(1,1);
b.insert(1,1);
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert(0,1);
b.insert(0,1);
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
// compare for inequality:
@@ -522,6 +675,7 @@ void tst_QMap::operator_eq()
QMap<QString, QString> b;
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert("Hello", "World");
@@ -530,6 +684,7 @@ void tst_QMap::operator_eq()
b.insert("Hello", "World");
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
a.insert("Goodbye", "cruel world");
@@ -546,6 +701,7 @@ void tst_QMap::operator_eq()
// empty keys and null keys match:
b.insert(QString(""), QString());
QVERIFY(a == b);
+ QCOMPARE(qHash(a), qHash(b));
QVERIFY(!(a != b));
}
@@ -560,64 +716,135 @@ void tst_QMap::operator_eq()
}
}
-void tst_QMap::empty()
+template <typename T>
+void emptyTestMethod()
{
- QMap<int, QString> map1;
+ T map;
- QVERIFY(map1.isEmpty());
+ QVERIFY(map.isEmpty());
+ QVERIFY(map.empty());
+ QVERIFY(!map.isDetached());
- map1.insert(1, "one");
- QVERIFY(!map1.isEmpty());
+ map.insert(1, "one");
+ QVERIFY(!map.isEmpty());
+ QVERIFY(!map.empty());
- map1.clear();
- QVERIFY(map1.isEmpty());
+ map.clear();
+ QVERIFY(map.isEmpty());
+ QVERIFY(map.empty());
+}
+void tst_QMap::empty()
+{
+ emptyTestMethod<QMap<int, QString>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ emptyTestMethod<QMultiMap<int, QString>>();
}
void tst_QMap::contains()
{
- QMap<int, QString> map1;
- int i;
+ {
+ QMap<int, QString> map1;
+ int i;
+
+ QVERIFY(!map1.contains(1));
+ QVERIFY(!map1.isDetached());
- map1.insert(1, "one");
- QVERIFY(map1.contains(1));
+ map1.insert(1, "one");
+ QVERIFY(map1.contains(1));
- for(i=2; i < 100; ++i)
- map1.insert(i, "teststring");
- for(i=99; i > 1; --i)
- QVERIFY(map1.contains(i));
+ for (i = 2; i < 100; ++i)
+ map1.insert(i, "teststring");
+ for (i = 99; i > 1; --i)
+ QVERIFY(map1.contains(i));
- map1.remove(43);
- QVERIFY(!map1.contains(43));
+ map1.remove(43);
+ QVERIFY(!map1.contains(43));
+ }
+
+ {
+ QMultiMap<int, QString> multiMap;
+ QVERIFY(!multiMap.contains(1));
+ QVERIFY(!multiMap.contains(1, "value1"));
+ QVERIFY(!multiMap.isDetached());
+
+ multiMap.insert(1, "value1");
+ multiMap.insert(2, "value2");
+ multiMap.insert(1, "value1_1");
+
+ QVERIFY(multiMap.contains(1));
+ QVERIFY(multiMap.contains(1, "value1"));
+ QVERIFY(multiMap.contains(1, "value1_1"));
+ QVERIFY(multiMap.contains(2));
+ QVERIFY(multiMap.contains(2, "value2"));
+ QVERIFY(!multiMap.contains(2, "invalid_value"));
+
+ QVERIFY(!multiMap.contains(3));
+ multiMap.insert(3, "value3");
+ QVERIFY(multiMap.contains(3));
+
+ multiMap.remove(3);
+ QVERIFY(!multiMap.contains(3));
+ }
}
void tst_QMap::find()
{
- QMap<int, QString> map1;
+ {
+ const QMap<int, QString> constMap;
+ QCOMPARE(constMap.find(1), constMap.end());
+ QVERIFY(!constMap.isDetached());
+
+ QMap<int, QString> map;
+ QCOMPARE(map.find(1), map.end());
+
+ map.insert(1, "value1");
+ map.insert(2, "value2");
+ map.insert(5, "value5");
+ map.insert(1, "value0");
+
+ QCOMPARE(map.find(1).value(), u"value0");
+ QCOMPARE(map.find(5).value(), u"value5");
+ QCOMPARE(map.find(2).value(), u"value2");
+ QCOMPARE(map.find(4), map.end());
+ }
+
+ const QMultiMap<int, QString> constMap;
+ QCOMPARE(constMap.find(1), constMap.end());
+ QCOMPARE(constMap.find(1, "value"), constMap.end());
+ QVERIFY(!constMap.isDetached());
+
+ QMultiMap<int, QString> map;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
- QVERIFY(map1.find(1) == map1.end());
+ QCOMPARE(map.find(1), map.end());
+ QCOMPARE(map.find(1, "value1"), map.end());
- map1.insert(1,"Mensch");
- map1.insert(1,"Mayer");
- map1.insert(2,"Hej");
+ map.insert(1,"Mensch");
+ map.insert(1,"Mayer");
+ map.insert(2,"Hej");
- QCOMPARE(map1.find(1).value(), QLatin1String("Mayer"));
- QCOMPARE(map1.find(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.find(1).value(), QLatin1String("Mayer"));
+ QCOMPARE(map.find(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.find(1, "Mensch").value(), QLatin1String("Mensch"));
+ QCOMPARE(map.find(1, "Unknown Value"), map.end());
- for(i = 3; i < 10; ++i) {
+ for (i = 3; i < 10; ++i) {
compareString = testString.arg(i);
- map1.insertMulti(4, compareString);
- QCOMPARE(map1.count(4), i - 2);
+ map.insert(4, compareString);
+ QCOMPARE(map.count(4), i - 2);
}
- QMap<int, QString>::const_iterator it=map1.constFind(4);
+ QMultiMap<int, QString>::iterator it = map.find(4);
- for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ for (i = 9; i > 2 && it != map.end() && it.key() == 4; --i) {
compareString = testString.arg(i);
QVERIFY(it.value() == compareString);
+ QCOMPARE(map.find(4, compareString), it);
++it;
++count;
}
@@ -626,32 +853,53 @@ void tst_QMap::find()
void tst_QMap::constFind()
{
- QMap<int, QString> map1;
+ {
+ QMap<int, QString> map;
+ QCOMPARE(map.constFind(1), map.constEnd());
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ map.insert(2, "value2");
+ map.insert(5, "value5");
+ map.insert(1, "value0");
+
+ QCOMPARE(map.constFind(1).value(), QLatin1String("value0"));
+ QCOMPARE(map.constFind(5).value(), QLatin1String("value5"));
+ QCOMPARE(map.constFind(2).value(), QLatin1String("value2"));
+ QCOMPARE(map.constFind(4), map.constEnd());
+ }
+
+ QMultiMap<int, QString> map;
QString testString="Teststring %0";
QString compareString;
int i,count=0;
- QVERIFY(map1.constFind(1) == map1.constEnd());
+ QCOMPARE(map.constFind(1), map.constEnd());
+ QCOMPARE(map.constFind(1, "value"), map.constEnd());
+ QVERIFY(!map.isDetached());
- map1.insert(1,"Mensch");
- map1.insert(1,"Mayer");
- map1.insert(2,"Hej");
+ map.insert(1,"Mensch");
+ map.insert(1,"Mayer");
+ map.insert(2,"Hej");
- QVERIFY(map1.constFind(4) == map1.constEnd());
+ QVERIFY(map.constFind(4) == map.constEnd());
- QCOMPARE(map1.constFind(1).value(), QLatin1String("Mayer"));
- QCOMPARE(map1.constFind(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.constFind(1).value(), QLatin1String("Mayer"));
+ QCOMPARE(map.constFind(2).value(), QLatin1String("Hej"));
+ QCOMPARE(map.constFind(1, "Mensch").value(), QLatin1String("Mensch"));
+ QCOMPARE(map.constFind(1, "Invalid Value"), map.constEnd());
- for(i = 3; i < 10; ++i) {
+ for (i = 3; i < 10; ++i) {
compareString = testString.arg(i);
- map1.insertMulti(4, compareString);
+ map.insert(4, compareString);
}
- QMap<int, QString>::const_iterator it=map1.constFind(4);
+ QMultiMap<int, QString>::const_iterator it = map.constFind(4);
- for(i = 9; i > 2 && it != map1.constEnd() && it.key() == 4; --i) {
+ for (i = 9; i > 2 && it != map.constEnd() && it.key() == 4; --i) {
compareString = testString.arg(i);
QVERIFY(it.value() == compareString);
+ QCOMPARE(map.constFind(4, compareString), it);
++it;
++count;
}
@@ -660,58 +908,128 @@ void tst_QMap::constFind()
void tst_QMap::lowerUpperBound()
{
- QMap<int, QString> map1;
+ {
+ const QMap<int, QString> emptyConstMap;
+ QCOMPARE(emptyConstMap.lowerBound(1), emptyConstMap.constEnd());
+ QCOMPARE(emptyConstMap.upperBound(1), emptyConstMap.constEnd());
+ QVERIFY(!emptyConstMap.isDetached());
+
+ const QMap<int, QString> constMap { qMakePair(1, "one"),
+ qMakePair(5, "five"),
+ qMakePair(10, "ten") };
+
+ QCOMPARE(constMap.lowerBound(-1).key(), 1);
+ QCOMPARE(constMap.lowerBound(1).key(), 1);
+ QCOMPARE(constMap.lowerBound(3).key(), 5);
+ QCOMPARE(constMap.lowerBound(12), constMap.constEnd());
+
+ QCOMPARE(constMap.upperBound(-1).key(), 1);
+ QCOMPARE(constMap.upperBound(1).key(), 5);
+ QCOMPARE(constMap.upperBound(3).key(), 5);
+ QCOMPARE(constMap.upperBound(12), constMap.constEnd());
+
+ QMap<int, QString> map;
+
+ map.insert(1, "one");
+ map.insert(5, "five");
+ map.insert(10, "ten");
+ map.insert(3, "three");
+ map.insert(7, "seven");
+
+ QCOMPARE(map.lowerBound(0).key(), 1);
+ QCOMPARE(map.lowerBound(1).key(), 1);
+ QCOMPARE(map.lowerBound(2).key(), 3);
+ QCOMPARE(map.lowerBound(3).key(), 3);
+ QCOMPARE(map.lowerBound(4).key(), 5);
+ QCOMPARE(map.lowerBound(5).key(), 5);
+ QCOMPARE(map.lowerBound(6).key(), 7);
+ QCOMPARE(map.lowerBound(7).key(), 7);
+ QCOMPARE(map.lowerBound(10).key(), 10);
+ QCOMPARE(map.lowerBound(999), map.end());
+
+ QCOMPARE(map.upperBound(0).key(), 1);
+ QCOMPARE(map.upperBound(1).key(), 3);
+ QCOMPARE(map.upperBound(2).key(), 3);
+ QCOMPARE(map.upperBound(3).key(), 5);
+ QCOMPARE(map.upperBound(7).key(), 10);
+ QCOMPARE(map.upperBound(10), map.end());
+ QCOMPARE(map.upperBound(999), map.end());
+ }
- map1.insert(1, "one");
- map1.insert(5, "five");
- map1.insert(10, "ten");
+ const QMultiMap<int, QString> emptyConstMap;
+ QCOMPARE(emptyConstMap.lowerBound(1), emptyConstMap.constEnd());
+ QCOMPARE(emptyConstMap.upperBound(1), emptyConstMap.constEnd());
+ QVERIFY(!emptyConstMap.isDetached());
+ const QMultiMap<int, QString> constMap { qMakePair(1, "one"),
+ qMakePair(5, "five"),
+ qMakePair(10, "ten") };
+
+ QCOMPARE(constMap.lowerBound(-1).key(), 1);
+ QCOMPARE(constMap.lowerBound(1).key(), 1);
+ QCOMPARE(constMap.lowerBound(3).key(), 5);
+ QCOMPARE(constMap.lowerBound(12), constMap.constEnd());
+
+ QCOMPARE(constMap.upperBound(-1).key(), 1);
+ QCOMPARE(constMap.upperBound(1).key(), 5);
+ QCOMPARE(constMap.upperBound(3).key(), 5);
+ QCOMPARE(constMap.upperBound(12), constMap.constEnd());
+
+ QMultiMap<int, QString> map;
+
+ map.insert(1, "one");
+ map.insert(5, "five");
+ map.insert(10, "ten");
//Copied from documentation
- QCOMPARE(map1.upperBound(0).key(), 1); // returns iterator to (1, "one")
- QCOMPARE(map1.upperBound(1).key(), 5); // returns iterator to (5, "five")
- QCOMPARE(map1.upperBound(2).key(), 5); // returns iterator to (5, "five")
- QVERIFY(map1.upperBound(10) == map1.end()); // returns end()
- QVERIFY(map1.upperBound(999) == map1.end()); // returns end()
-
- QCOMPARE(map1.lowerBound(0).key(), 1); // returns iterator to (1, "one")
- QCOMPARE(map1.lowerBound(1).key(), 1); // returns iterator to (1, "one")
- QCOMPARE(map1.lowerBound(2).key(), 5); // returns iterator to (5, "five")
- QCOMPARE(map1.lowerBound(10).key(), 10); // returns iterator to (10, "ten")
- QVERIFY(map1.lowerBound(999) == map1.end()); // returns end()
-
- map1.insert(3, "three");
- map1.insert(7, "seven");
- map1.insertMulti(7, "seven_2");
-
- QCOMPARE(map1.upperBound(0).key(), 1);
- QCOMPARE(map1.upperBound(1).key(), 3);
- QCOMPARE(map1.upperBound(2).key(), 3);
- QCOMPARE(map1.upperBound(3).key(), 5);
- QCOMPARE(map1.upperBound(7).key(), 10);
- QVERIFY(map1.upperBound(10) == map1.end());
- QVERIFY(map1.upperBound(999) == map1.end());
-
- QCOMPARE(map1.lowerBound(0).key(), 1);
- QCOMPARE(map1.lowerBound(1).key(), 1);
- QCOMPARE(map1.lowerBound(2).key(), 3);
- QCOMPARE(map1.lowerBound(3).key(), 3);
- QCOMPARE(map1.lowerBound(4).key(), 5);
- QCOMPARE(map1.lowerBound(5).key(), 5);
- QCOMPARE(map1.lowerBound(6).key(), 7);
- QCOMPARE(map1.lowerBound(7).key(), 7);
- QCOMPARE(map1.lowerBound(6).value(), QLatin1String("seven_2"));
- QCOMPARE(map1.lowerBound(7).value(), QLatin1String("seven_2"));
- QCOMPARE((++map1.lowerBound(6)).value(), QLatin1String("seven"));
- QCOMPARE((++map1.lowerBound(7)).value(), QLatin1String("seven"));
- QCOMPARE(map1.lowerBound(10).key(), 10);
- QVERIFY(map1.lowerBound(999) == map1.end());
+ QCOMPARE(map.upperBound(0).key(), 1); // returns iterator to (1, "one")
+ QCOMPARE(map.upperBound(1).key(), 5); // returns iterator to (5, "five")
+ QCOMPARE(map.upperBound(2).key(), 5); // returns iterator to (5, "five")
+ QVERIFY(map.upperBound(10) == map.end()); // returns end()
+ QVERIFY(map.upperBound(999) == map.end()); // returns end()
+
+ QCOMPARE(map.lowerBound(0).key(), 1); // returns iterator to (1, "one")
+ QCOMPARE(map.lowerBound(1).key(), 1); // returns iterator to (1, "one")
+ QCOMPARE(map.lowerBound(2).key(), 5); // returns iterator to (5, "five")
+ QCOMPARE(map.lowerBound(10).key(), 10); // returns iterator to (10, "ten")
+ QVERIFY(map.lowerBound(999) == map.end()); // returns end()
+
+ map.insert(3, "three");
+ map.insert(7, "seven");
+ map.insert(7, "seven_2");
+
+ QCOMPARE(map.upperBound(0).key(), 1);
+ QCOMPARE(map.upperBound(1).key(), 3);
+ QCOMPARE(map.upperBound(2).key(), 3);
+ QCOMPARE(map.upperBound(3).key(), 5);
+ QCOMPARE(map.upperBound(7).key(), 10);
+ QVERIFY(map.upperBound(10) == map.end());
+ QVERIFY(map.upperBound(999) == map.end());
+
+ QCOMPARE(map.lowerBound(0).key(), 1);
+ QCOMPARE(map.lowerBound(1).key(), 1);
+ QCOMPARE(map.lowerBound(2).key(), 3);
+ QCOMPARE(map.lowerBound(3).key(), 3);
+ QCOMPARE(map.lowerBound(4).key(), 5);
+ QCOMPARE(map.lowerBound(5).key(), 5);
+ QCOMPARE(map.lowerBound(6).key(), 7);
+ QCOMPARE(map.lowerBound(7).key(), 7);
+ QCOMPARE(map.lowerBound(6).value(), QLatin1String("seven_2"));
+ QCOMPARE(map.lowerBound(7).value(), QLatin1String("seven_2"));
+ QCOMPARE((++map.lowerBound(6)).value(), QLatin1String("seven"));
+ QCOMPARE((++map.lowerBound(7)).value(), QLatin1String("seven"));
+ QCOMPARE(map.lowerBound(10).key(), 10);
+ QVERIFY(map.lowerBound(999) == map.end());
}
void tst_QMap::mergeCompare()
{
- QMap<int, QString> map1, map2, map3, map1b, map2b;
+ QMultiMap<int, QString> map1, map2, map3, map1b, map2b, map4;
+
+ // unite with an empty map does nothing
+ map1.unite(map2);
+ QVERIFY(!map1.isDetached());
map1.insert(1,"ett");
map1.insert(3,"tre");
@@ -741,18 +1059,43 @@ void tst_QMap::mergeCompare()
map3.insert(4, "fyra");
map3.insert(5, "fem");
- QVERIFY(map1 == map3);
+ QCOMPARE(map1, map3);
+
+ map4.unite(map3);
+ QCOMPARE(map4, map3);
}
void tst_QMap::take()
{
- QMap<int, QString> map;
+ {
+ QMap<int, QString> map;
+ QCOMPARE(map.take(1), QString());
+ QVERIFY(!map.isDetached());
- map.insert(2, "zwei");
- map.insert(3, "drei");
+ map.insert(2, "zwei");
+ map.insert(3, "drei");
- QCOMPARE(map.take(3), QLatin1String("drei"));
- QVERIFY(!map.contains(3));
+ QCOMPARE(map.take(3), QLatin1String("drei"));
+ QVERIFY(!map.contains(3));
+ }
+
+ {
+ QMultiMap<int, QString> multiMap;
+ QCOMPARE(multiMap.take(1), QString());
+ QVERIFY(!multiMap.isDetached());
+
+ multiMap.insert(0, "value0");
+ multiMap.insert(1, "value1");
+ multiMap.insert(0, "value0_1");
+ multiMap.insert(0, "value0_2");
+
+ // The most recently inserted value is returned
+ QCOMPARE(multiMap.take(0), u"value0_2");
+ QCOMPARE(multiMap.take(0), u"value0_1");
+ QCOMPARE(multiMap.take(0), u"value0");
+ QCOMPARE(multiMap.take(0), QString());
+ QVERIFY(!multiMap.contains(0));
+ }
}
void tst_QMap::iterators()
@@ -769,13 +1112,13 @@ void tst_QMap::iterators()
QMap<int, QString>::iterator stlIt = map.begin();
QCOMPARE(stlIt.value(), QLatin1String("Teststring 1"));
- stlIt+=5;
+ std::advance(stlIt, 5);
QCOMPARE(stlIt.value(), QLatin1String("Teststring 6"));
stlIt++;
QCOMPARE(stlIt.value(), QLatin1String("Teststring 7"));
- stlIt-=3;
+ std::advance(stlIt, -3);
QCOMPARE(stlIt.value(), QLatin1String("Teststring 4"));
stlIt--;
@@ -790,13 +1133,13 @@ void tst_QMap::iterators()
QMap<int, QString>::const_iterator cstlIt = map.constBegin();
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 1"));
- cstlIt+=5;
+ std::advance(cstlIt, 5);
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 6"));
cstlIt++;
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 7"));
- cstlIt-=3;
+ std::advance(cstlIt, -3);
QCOMPARE(cstlIt.value(), QLatin1String("Teststring 4"));
cstlIt--;
@@ -832,14 +1175,125 @@ void tst_QMap::iterators()
}
}
+void tst_QMap::multimapIterators()
+{
+ QMultiMap<int, QString> map;
+ const QString testString = "Teststring %1-%2";
+
+ for (int i = 0; i < 5; ++i) {
+ // reverse order, because the last added is returned first.
+ for (int j = 4; j >= 0; --j)
+ map.insert(i, testString.arg(i).arg(j));
+ }
+
+ // STL-style iterators
+ auto stlIt = map.begin();
+ QCOMPARE(stlIt.value(), u"Teststring 0-0");
+
+ stlIt++;
+ QCOMPARE(stlIt.value(), u"Teststring 0-1");
+
+ std::advance(stlIt, 10);
+ QCOMPARE(stlIt.value(), u"Teststring 2-1");
+
+ std::advance(stlIt, -4);
+ QCOMPARE(stlIt.value(), u"Teststring 1-2");
+
+ stlIt--;
+ QCOMPARE(stlIt.value(), u"Teststring 1-1");
+
+ // STL-style const iterators
+ auto cstlIt = map.cbegin();
+ QCOMPARE(cstlIt.value(), u"Teststring 0-0");
+
+ cstlIt++;
+ QCOMPARE(cstlIt.value(), u"Teststring 0-1");
+
+ std::advance(cstlIt, 16);
+ QCOMPARE(cstlIt.value(), u"Teststring 3-2");
+
+ std::advance(cstlIt, -6);
+ QCOMPARE(cstlIt.value(), u"Teststring 2-1");
+
+ cstlIt--;
+ QCOMPARE(cstlIt.value(), u"Teststring 2-0");
+
+ // Java-style iterator
+ QMultiMapIterator javaIt(map);
+ int i = 0;
+ int j = 0;
+ while (javaIt.hasNext()) {
+ javaIt.next();
+ QCOMPARE(javaIt.value(), testString.arg(i).arg(j));
+ if (++j == 5) {
+ j = 0;
+ i++;
+ }
+ }
+
+ i = 4;
+ j = 4;
+ while (javaIt.hasPrevious()) {
+ javaIt.previous();
+ QCOMPARE(javaIt.value(), testString.arg(i).arg(j));
+ if (--j < 0) {
+ j = 4;
+ i--;
+ }
+ }
+}
+
+template <typename T>
+void iteratorsInEmptyMapTestMethod()
+{
+ T map;
+ using ConstIter = typename T::const_iterator;
+ ConstIter it1 = map.cbegin();
+ ConstIter it2 = map.constBegin();
+ QVERIFY(it1 == it2 && it2 == ConstIter());
+ QVERIFY(!map.isDetached());
+
+ ConstIter it3 = map.cend();
+ ConstIter it4 = map.constEnd();
+ QVERIFY(it3 == it4 && it4 == ConstIter());
+ QVERIFY(!map.isDetached());
+
+ // to call const overloads of begin() and end()
+ const T map2;
+ ConstIter it5 = map2.begin();
+ ConstIter it6 = map2.end();
+ QVERIFY(it5 == it6 && it6 == ConstIter());
+ QVERIFY(!map2.isDetached());
+
+ using Iter = typename T::iterator;
+ Iter it7 = map.begin();
+ Iter it8 = map.end();
+ QVERIFY(it7 == it8);
+}
+
+void tst_QMap::iteratorsInEmptyMap()
+{
+ iteratorsInEmptyMapTestMethod<QMap<int, int>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ iteratorsInEmptyMapTestMethod<QMultiMap<int, int>>();
+}
+
void tst_QMap::keyIterator()
{
QMap<int, int> map;
+ using KeyIterator = QMap<int, int>::key_iterator;
+ KeyIterator it1 = map.keyBegin();
+ KeyIterator it2 = map.keyEnd();
+ QVERIFY(it1 == it2 && it2 == KeyIterator());
+ QVERIFY(!map.isDetached());
+
for (int i = 0; i < 100; ++i)
map.insert(i, i*100);
- QMap<int, int>::key_iterator key_it = map.keyBegin();
+ KeyIterator key_it = map.keyBegin();
QMap<int, int>::const_iterator it = map.cbegin();
for (int i = 0; i < 100; ++i) {
QCOMPARE(*key_it, it.key());
@@ -860,8 +1314,48 @@ void tst_QMap::keyIterator()
QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 99), 1);
// DefaultConstructible test
- typedef QMap<int, int>::key_iterator keyIterator;
- Q_STATIC_ASSERT(std::is_default_constructible<keyIterator>::value);
+ static_assert(std::is_default_constructible<KeyIterator>::value);
+}
+
+void tst_QMap::multimapKeyIterator()
+{
+ QMultiMap<int, int> map;
+
+ using KeyIterator = QMultiMap<int, int>::key_iterator;
+ KeyIterator it1 = map.keyBegin();
+ KeyIterator it2 = map.keyEnd();
+ QVERIFY(it1 == it2 && it2 == KeyIterator());
+ QVERIFY(!map.isDetached());
+
+ for (int i = 0; i < 5; ++i) {
+ for (int j = 4; j >= 0; --j)
+ map.insert(i, 100 * i + j);
+ }
+
+ KeyIterator keyIt = map.keyBegin();
+ QMultiMap<int, int>::const_iterator it = map.cbegin();
+ for (int i = 0; i < 5; ++i) {
+ for (int j = 4; j >= 0; --j) {
+ QCOMPARE(*keyIt, it.key());
+ ++keyIt;
+ ++it;
+ }
+ }
+
+ keyIt = std::find(map.keyBegin(), map.keyEnd(), 3);
+ it = std::find(map.cbegin(), map.cend(), 3 * 100);
+
+ QVERIFY(keyIt != map.keyEnd());
+ QCOMPARE(*keyIt, it.key());
+ QCOMPARE(*(keyIt++), (it++).key());
+ QCOMPARE(*(keyIt--), (it--).key());
+ QCOMPARE(*(++keyIt), (++it).key());
+ QCOMPARE(*(--keyIt), (--it).key());
+
+ QCOMPARE(std::count(map.keyBegin(), map.keyEnd(), 2), 5);
+
+ // DefaultConstructible test
+ static_assert(std::is_default_constructible<KeyIterator>::value);
}
void tst_QMap::keyValueIterator()
@@ -881,6 +1375,12 @@ void tst_QMap::keyValueIterator()
entry_type pair(it.key(), it.value());
QCOMPARE(*key_value_it, pair);
+ QCOMPARE(key_value_it->first, pair.first);
+ QCOMPARE(key_value_it->second, pair.second);
+ QCOMPARE(&(*key_value_it).first, &it.key());
+ QCOMPARE(&key_value_it->first, &it.key());
+ QCOMPARE(&(*key_value_it).second, &it.value());
+ QCOMPARE(&key_value_it->second, &it.value());
++key_value_it;
++it;
}
@@ -917,32 +1417,168 @@ void tst_QMap::keyValueIterator()
QCOMPARE(std::count(map.constKeyValueBegin(), map.constKeyValueEnd(), entry_type(key, value)), 1);
}
+void tst_QMap::multimapKeyValueIterator()
+{
+ QMultiMap<int, int> map;
+ using EntryType = QMultiMap<int, int>::const_key_value_iterator::value_type;
+
+ for (int i = 0; i < 5; ++i) {
+ for (int j = 4; j >= 0; --j)
+ map.insert(i, 100 * i + j);
+ }
+
+ auto keyValueIt = map.constKeyValueBegin();
+ auto it = map.cbegin();
+
+ for (int i = 0; i < map.size(); ++i) {
+ QVERIFY(keyValueIt != map.constKeyValueEnd());
+ QVERIFY(it != map.cend());
+
+ EntryType pair(it.key(), it.value());
+ QCOMPARE(*keyValueIt, pair);
+ QCOMPARE(keyValueIt->first, pair.first);
+ QCOMPARE(keyValueIt->second, pair.second);
+ ++keyValueIt;
+ ++it;
+ }
+
+ QVERIFY(keyValueIt == map.constKeyValueEnd());
+ QVERIFY(it == map.cend());
+
+ int key = 3;
+ int value = 100 * 3;
+ keyValueIt = std::find(map.constKeyValueBegin(), map.constKeyValueEnd(), EntryType(key, value));
+ it = std::find(map.cbegin(), map.cend(), value);
+
+ QVERIFY(keyValueIt != map.constKeyValueEnd());
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ ++it;
+ ++keyValueIt;
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ --it;
+ --keyValueIt;
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ std::advance(it, 5);
+ std::advance(keyValueIt, 5);
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ std::advance(it, -5);
+ std::advance(keyValueIt, -5);
+ QCOMPARE(*keyValueIt, EntryType(it.key(), it.value()));
+
+ key = 2;
+ value = 100 * 2 + 2;
+ auto cnt = std::count(map.constKeyValueBegin(), map.constKeyValueEnd(), EntryType(key, value));
+ QCOMPARE(cnt, 1);
+}
+
+template <typename T>
+void keyValueIteratorInEmptyMapTestMethod()
+{
+ T map;
+ using ConstKeyValueIter = typename T::const_key_value_iterator;
+
+ ConstKeyValueIter it1 = map.constKeyValueBegin();
+ ConstKeyValueIter it2 = map.constKeyValueEnd();
+ QVERIFY(it1 == it2 && it2 == ConstKeyValueIter());
+ QVERIFY(!map.isDetached());
+
+ const T map2;
+ ConstKeyValueIter it3 = map2.keyValueBegin();
+ ConstKeyValueIter it4 = map2.keyValueEnd();
+ QVERIFY(it3 == it4 && it4 == ConstKeyValueIter());
+ QVERIFY(!map2.isDetached());
+
+ using KeyValueIter = typename T::key_value_iterator;
+
+ KeyValueIter it5 = map.keyValueBegin();
+ KeyValueIter it6 = map.keyValueEnd();
+ QVERIFY(it5 == it6);
+}
+
+void tst_QMap::keyValueIteratorInEmptyMap()
+{
+ keyValueIteratorInEmptyMapTestMethod<QMap<int, int>>();
+ if (QTest::currentTestFailed())
+ return;
+
+ keyValueIteratorInEmptyMapTestMethod<QMultiMap<int, int>>();
+}
+
void tst_QMap::keys_values_uniqueKeys()
{
- QMap<QString, int> map;
- QVERIFY(map.uniqueKeys().isEmpty());
+ {
+ QMap<QString, int> map;
+ QVERIFY(map.keys().isEmpty());
+ QVERIFY(map.keys(1).isEmpty());
+ QVERIFY(map.values().isEmpty());
+ QVERIFY(!map.isDetached());
+
+ map.insert("one", 1);
+ QCOMPARE(map.keys(), QStringList({ "one" }));
+ QCOMPARE(map.keys(1), QStringList({ "one" }));
+ QCOMPARE(map.values(), QList<int>({ 1 }));
+
+ map.insert("two", 2);
+ QCOMPARE(map.keys(), QStringList({ "one", "two" }));
+ QCOMPARE(map.keys(1), QStringList({ "one" }));
+ QCOMPARE(map.values(), QList<int>({ 1, 2 }));
+
+ map.insert("three", 2);
+ QCOMPARE(map.keys(), QStringList({ "one", "three", "two" }));
+ QCOMPARE(map.keys(2), QStringList({ "three", "two" }));
+ QCOMPARE(map.values(), QList<int>({ 1, 2, 2 }));
+
+ map.insert("one", 0);
+ QCOMPARE(map.keys(), QStringList({ "one", "three", "two" }));
+ QCOMPARE(map.keys(1), QStringList());
+ QCOMPARE(map.keys(0), QStringList({ "one" }));
+ QCOMPARE(map.keys(2), QStringList({ "three", "two" }));
+ QCOMPARE(map.values(), QList<int>({ 0, 2, 2 }));
+ }
+
+ QMultiMap<QString, int> map;
QVERIFY(map.keys().isEmpty());
+ QVERIFY(map.keys(1).isEmpty());
+ QVERIFY(map.uniqueKeys().isEmpty());
QVERIFY(map.values().isEmpty());
+ QVERIFY(map.values("key").isEmpty());
+ QVERIFY(!map.isDetached());
- map.insertMulti("alpha", 1);
+ map.insert("alpha", 1);
QVERIFY(map.keys() == (QList<QString>() << "alpha"));
- QVERIFY(map.uniqueKeys() == map.keys());
QVERIFY(map.values() == (QList<int>() << 1));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha" }));
- map.insertMulti("beta", -2);
+ map.insert("beta", -2);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "beta"));
- QVERIFY(map.keys() == map.uniqueKeys());
QVERIFY(map.values() == (QList<int>() << 1 << -2));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta" }));
- map.insertMulti("alpha", 2);
- QVERIFY(map.uniqueKeys() == (QList<QString>() << "alpha" << "beta"));
+ map.insert("alpha", 2);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "alpha" << "beta"));
QVERIFY(map.values() == (QList<int>() << 2 << 1 << -2));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta" }));
+ QVERIFY(map.values("alpha") == QList<int>({ 2, 1 }));
- map.insertMulti("beta", 4);
- QVERIFY(map.uniqueKeys() == (QList<QString>() << "alpha" << "beta"));
+ map.insert("beta", 4);
QVERIFY(map.keys() == (QList<QString>() << "alpha" << "alpha" << "beta" << "beta"));
QVERIFY(map.values() == (QList<int>() << 2 << 1 << 4 << -2));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta" }));
+ QVERIFY(map.values("alpha") == QList<int>({ 2, 1 }));
+ QVERIFY(map.values("beta") == QList<int>({ 4, -2 }));
+
+ map.insert("gamma", 2);
+ QVERIFY(map.keys() == QList<QString>({ "alpha", "alpha", "beta", "beta", "gamma" }));
+ QVERIFY(map.values() == QList<int>({ 2, 1, 4, -2, 2 }));
+ QVERIFY(map.uniqueKeys() == QList<QString>({ "alpha", "beta", "gamma" }));
+ QVERIFY(map.values("alpha") == QList<int>({ 2, 1 }));
+ QVERIFY(map.values("beta") == QList<int>({ 4, -2 }));
+ QVERIFY(map.values("gamma") == QList<int>({ 2 }));
+ QVERIFY(map.keys(2) == QList<QString>({ "alpha", "gamma" }));
}
void tst_QMap::qmultimap_specific()
@@ -965,26 +1601,26 @@ void tst_QMap::qmultimap_specific()
}
QVERIFY(map1.contains(9, 99));
- QCOMPARE(map1.count(), 45);
+ QCOMPARE(map1.size(), 45);
map1.remove(9, 99);
QVERIFY(!map1.contains(9, 99));
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.remove(9, 99);
QVERIFY(!map1.contains(9, 99));
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.remove(1, 99);
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.insert(1, 99);
map1.insert(1, 99);
- QCOMPARE(map1.count(), 46);
+ QCOMPARE(map1.size(), 46);
map1.remove(1, 99);
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
map1.remove(1, 99);
- QCOMPARE(map1.count(), 44);
+ QCOMPARE(map1.size(), 44);
{
QMultiMap<int, int>::const_iterator i = map1.constFind(1, 11);
@@ -1043,7 +1679,7 @@ void tst_QMap::qmultimap_specific()
map2.insert(42, 1);
map2.insert(10, 2);
map2.insert(48, 3);
- QCOMPARE(map1.count(), map2.count());
+ QCOMPARE(map1.size(), map2.size());
QVERIFY(map1.remove(42,5));
QVERIFY(map2.remove(42,5));
QVERIFY(map1 == map2);
@@ -1065,26 +1701,50 @@ void tst_QMap::qmultimap_specific()
void tst_QMap::const_shared_null()
{
QMap<int, QString> map2;
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QMap<int, QString> map1;
- map1.setSharable(false);
- QVERIFY(map1.isDetached());
-
- map2.setSharable(true);
-#endif
QVERIFY(!map2.isDetached());
}
void tst_QMap::equal_range()
{
- QMap<int, QString> map;
- const QMap<int, QString> &cmap = map;
+ {
+ const QMap<int, QString> constMap;
+ QCOMPARE(constMap.equal_range(1), qMakePair(constMap.constEnd(), constMap.constEnd()));
+ QVERIFY(!constMap.isDetached());
+
+ QMap<int, QString> map;
+ QCOMPARE(map.equal_range(1), qMakePair(map.end(), map.end()));
+
+ map.insert(1, "value1");
+ map.insert(5, "value5");
+ map.insert(1, "value0");
+
+ auto pair = map.equal_range(1);
+ QCOMPARE(pair.first.value(), "value0");
+ QCOMPARE(pair.second.value(), "value5");
+ auto b = map.find(1);
+ auto e = map.find(5);
+ QCOMPARE(pair, qMakePair(b, e));
+
+ pair = map.equal_range(3);
+ QCOMPARE(pair.first.value(), "value5");
+ QCOMPARE(pair.second.value(), "value5");
+ QCOMPARE(pair, qMakePair(e, e));
+
+ QCOMPARE(map.equal_range(10), qMakePair(map.end(), map.end()));
+ }
+
+ const QMultiMap<int, QString> constMap;
+ QCOMPARE(constMap.equal_range(1), qMakePair(constMap.constEnd(), constMap.constEnd()));
+ QVERIFY(!constMap.isDetached());
- QPair<QMap<int, QString>::iterator, QMap<int, QString>::iterator> result = map.equal_range(0);
+ QMultiMap<int, QString> map;
+ const QMultiMap<int, QString> &cmap = map;
+
+ QPair<QMultiMap<int, QString>::iterator, QMultiMap<int, QString>::iterator> result = map.equal_range(0);
QCOMPARE(result.first, map.end());
QCOMPARE(result.second, map.end());
- QPair<QMap<int, QString>::const_iterator, QMap<int, QString>::const_iterator> cresult = cmap.equal_range(0);
+ QPair<QMultiMap<int, QString>::const_iterator, QMultiMap<int, QString>::const_iterator> cresult = cmap.equal_range(0);
QCOMPARE(cresult.first, cmap.cend());
QCOMPARE(cresult.second, cmap.cend());
@@ -1141,7 +1801,7 @@ void tst_QMap::equal_range()
QCOMPARE(cresult.first, cmap.find(2));
QCOMPARE(cresult.second, cmap.find(4));
- map.insertMulti(1, "another one");
+ map.insert(1, "another one");
result = map.equal_range(1);
QCOMPARE(result.first, map.find(1));
@@ -1154,74 +1814,13 @@ void tst_QMap::equal_range()
QCOMPARE(map.count(1), 2);
}
-template <class T>
-const T &const_(const T &t)
-{
- return t;
-}
-
-void tst_QMap::setSharable()
-{
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- QMap<int, QString> map;
-
- map.insert(1, "um");
- map.insert(2, "dois");
- map.insert(4, "quatro");
- map.insert(5, "cinco");
-
- map.setSharable(true);
- QCOMPARE(map.size(), 4);
- QCOMPARE(const_(map)[4], QString("quatro"));
-
- {
- QMap<int, QString> copy(map);
-
- QVERIFY(!map.isDetached());
- QVERIFY(copy.isSharedWith(map));
- sanityCheckTree(copy, __LINE__);
- }
-
- map.setSharable(false);
- sanityCheckTree(map, __LINE__);
- QVERIFY(map.isDetached());
- QCOMPARE(map.size(), 4);
- QCOMPARE(const_(map)[4], QString("quatro"));
-
- {
- QMap<int, QString> copy(map);
-
- QVERIFY(map.isDetached());
- QVERIFY(copy.isDetached());
-
- QCOMPARE(copy.size(), 4);
- QCOMPARE(const_(copy)[4], QString("quatro"));
-
- QCOMPARE(map, copy);
- sanityCheckTree(map, __LINE__);
- sanityCheckTree(copy, __LINE__);
- }
-
- map.setSharable(true);
- QCOMPARE(map.size(), 4);
- QCOMPARE(const_(map)[4], QString("quatro"));
-
- {
- QMap<int, QString> copy(map);
-
- QVERIFY(!map.isDetached());
- QVERIFY(copy.isSharedWith(map));
- }
-#endif
-}
-
void tst_QMap::insert()
{
QMap<QString, float> map;
map.insert("cs/key1", 1);
map.insert("cs/key2", 2);
map.insert("cs/key1", 3);
- QCOMPARE(map.count(), 2);
+ QCOMPARE(map.size(), 2);
QMap<int, int> intMap;
for (int i = 0; i < 1000; ++i) {
@@ -1265,6 +1864,226 @@ void tst_QMap::insert()
}
}
+template <template <typename K, typename T> typename Map>
+void testDetachWhenInsert()
+{
+ const Map<int, int> referenceSource = {
+ { 0, 0 },
+ { 1, 1 },
+ { 2, 2 }
+ };
+
+ const Map<int, int> referenceDestination = {
+ { 0, 0 },
+ { 1, 1 },
+ { 2, 2 },
+ { 3, 3 }
+ };
+
+ // copy insertion of non-shared map
+ {
+ Map<int, int> source;
+ source.insert(0, 0);
+ source.insert(1, 1);
+ source.insert(2, 2);
+
+ Map<int, int> dest;
+ dest.insert(3, 3);
+ Map<int, int> destCopy = dest;
+
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(source); // QMap
+ else
+ dest.unite(source); // QMultiMap
+
+ QCOMPARE(source, referenceSource);
+ QCOMPARE(dest, referenceDestination);
+
+ QCOMPARE(destCopy.size(), 1); // unchanged
+ }
+
+ // copy insertion of shared map
+ {
+ Map<int, int> source;
+ source.insert(0, 0);
+ source.insert(1, 1);
+ source.insert(2, 2);
+ Map<int, int> sourceCopy = source;
+
+ Map<int, int> dest;
+ dest.insert(3, 3);
+ Map<int, int> destCopy = dest;
+
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(source); // QMap
+ else
+ dest.unite(source); // QMultiMap
+
+ QCOMPARE(source, referenceSource);
+ QCOMPARE(sourceCopy, referenceSource);
+
+ QCOMPARE(dest, referenceDestination);
+ QCOMPARE(destCopy.size(), 1); // unchanged
+ }
+
+ // move insertion of non-shared map
+ {
+ Map<int, int> source;
+ source.insert(0, 0);
+ source.insert(1, 1);
+ source.insert(2, 2);
+
+ Map<int, int> dest;
+ dest.insert(3, 3);
+ Map<int, int> destCopy = dest;
+
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(source); // QMap
+ else
+ dest.unite(source); // QMultiMap
+
+ QCOMPARE(dest, referenceDestination);
+ QCOMPARE(destCopy.size(), 1); // unchanged
+ }
+
+ // move insertion of shared map
+ {
+ Map<int, int> source;
+ source.insert(0, 0);
+ source.insert(1, 1);
+ source.insert(2, 2);
+ Map<int, int> sourceCopy = source;
+
+ Map<int, int> dest;
+ dest.insert(3, 3);
+ Map<int, int> destCopy = dest;
+
+ if constexpr (std::is_same_v<decltype(dest), QMap<int, int>>)
+ dest.insert(std::move(source)); // QMap
+ else
+ dest.unite(std::move(source)); // QMultiMap
+
+ QCOMPARE(sourceCopy, referenceSource);
+
+ QCOMPARE(dest, referenceDestination);
+ QCOMPARE(destCopy.size(), 1); // unchanged
+ }
+};
+
+void tst_QMap::insertMap()
+{
+ {
+ QMap<int, int> map1;
+ QMap<int, int> map2;
+ QVERIFY(map1.isEmpty());
+ QVERIFY(map2.isEmpty());
+
+ map1.insert(map2);
+ QVERIFY(map1.isEmpty());
+ QVERIFY(map2.isEmpty());
+ QVERIFY(!map1.isDetached());
+ QVERIFY(!map2.isDetached());
+ }
+ {
+ QMap<int, int> map;
+ map.insert(1, 1);
+ map.insert(2, 2);
+ map.insert(0, -1);
+
+ QMap<int, int> map2;
+ map2.insert(0, 0);
+ map2.insert(3, 3);
+ map2.insert(4, 4);
+
+ map.insert(map2);
+
+ QCOMPARE(map.size(), 5);
+ for (int i = 0; i < 5; ++i)
+ QCOMPARE(map[i], i);
+ }
+ {
+ QMap<int, int> map;
+ for (int i = 0; i < 10; ++i)
+ map.insert(i * 3, i);
+
+ QMap<int, int> map2;
+ for (int i = 0; i < 10; ++i)
+ map2.insert(i * 4, i);
+
+ map.insert(map2);
+
+ QCOMPARE(map.size(), 17);
+ for (int i = 0; i < 10; ++i) {
+ // i * 3 == i except for i = 4, 8
+ QCOMPARE(map[i * 3], (i && i % 4 == 0) ? i - (i / 4) : i);
+ QCOMPARE(map[i * 4], i);
+ }
+
+ auto it = map.cbegin();
+ int prev = it.key();
+ ++it;
+ for (auto end = map.cend(); it != end; ++it) {
+ QVERIFY(prev < it.key());
+ prev = it.key();
+ }
+ }
+ {
+ QMap<int, int> map;
+ map.insert(1, 1);
+
+ QMap<int, int> map2;
+
+ map.insert(map2);
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map[1], 1);
+ }
+ {
+ QMap<int, int> map;
+ QMap<int, int> map2;
+ map2.insert(1, 1);
+
+ map.insert(map2);
+ QCOMPARE(map.size(), 1);
+ QCOMPARE(map[1], 1);
+
+ QMap<int, int> map3;
+ map3.insert(std::move(map2));
+ QCOMPARE(map3, map);
+ }
+ {
+ QMap<int, int> map;
+ map.insert(0, 0);
+ map.insert(1, 1);
+ map.insert(2, 2);
+
+ // Test inserting into self, nothing should happen
+ map.insert(map);
+
+ QCOMPARE(map.size(), 3);
+ for (int i = 0; i < 3; ++i)
+ QCOMPARE(map[i], i);
+ }
+ {
+ // Here we use a QMultiMap and insert that into QMap,
+ // since it has multiple values with the same key the
+ // ordering is undefined so we won't test that, but
+ // make sure this isn't adding multiple entries with the
+ // same key to the QMap.
+ QMap<int, int> map;
+ map.insert(0, 0);
+
+ QMap<int, int> map2;
+ map2.insert(0, 1);
+
+ map.insert(map2);
+
+ QCOMPARE(map.size(), 1);
+ }
+
+ testDetachWhenInsert<QMap>();
+ testDetachWhenInsert<QMultiMap>();
+}
+
void tst_QMap::checkMostLeftNode()
{
QMap<int, int> map;
@@ -1319,9 +2138,8 @@ void tst_QMap::checkMostLeftNode()
void tst_QMap::initializerList()
{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
QMap<int, QString> map = {{1, "bar"}, {1, "hello"}, {2, "initializer_list"}};
- QCOMPARE(map.count(), 2);
+ QCOMPARE(map.size(), 2);
QCOMPARE(map[1], QString("hello"));
QCOMPARE(map[2], QString("initializer_list"));
@@ -1331,9 +2149,9 @@ void tst_QMap::initializerList()
// QCOMPARE(stdm[1], QString("bar"));
QMultiMap<QString, int> multiMap{{"il", 1}, {"il", 2}, {"il", 3}};
- QCOMPARE(multiMap.count(), 3);
+ QCOMPARE(multiMap.size(), 3);
QList<int> values = multiMap.values("il");
- QCOMPARE(values.count(), 3);
+ QCOMPARE(values.size(), 3);
QMap<int, int> emptyMap{};
QVERIFY(emptyMap.isEmpty());
@@ -1346,9 +2164,6 @@ void tst_QMap::initializerList()
QMultiMap<float, float> emptyPairs2{{}, {}};
QVERIFY(!emptyPairs2.isEmpty());
-#else
- QSKIP("Compiler doesn't support initializer lists");
-#endif
}
void tst_QMap::testInsertWithHint()
@@ -1416,65 +2231,64 @@ void tst_QMap::testInsertWithHint()
void tst_QMap::testInsertMultiWithHint()
{
- QMap<int, int> map;
+ QMultiMap<int, int> map;
- typedef QMap<int, int>::const_iterator cite; // Hack since we define QT_STRICT_ITERATORS
- map.insertMulti(cite(map.end()), 64, 65);
- map[128] = 129;
- map[256] = 257;
+ map.insert(map.end(), 64, 65);
+ map.insert(128, 129);
+ map.insert(256, 257);
sanityCheckTree(map, __LINE__);
- map.insertMulti(cite(map.end()), 512, 513);
- map.insertMulti(cite(map.end()), 512, 513 * 2);
+ map.insert(map.end(), 512, 513);
+ map.insert(map.end(), 512, 513 * 2);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 5);
- map.insertMulti(cite(map.end()), 256, 258); // wrong hint
+ map.insert(map.end(), 256, 258); // wrong hint
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 6);
- QMap<int, int>::iterator i = map.insertMulti(map.constBegin(), 256, 259); // wrong hint
+ QMultiMap<int, int>::iterator i = map.insert(map.constBegin(), 256, 259); // wrong hint
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 7);
- QMap<int, int>::iterator j = map.insertMulti(map.constBegin(), 69, 66);
+ QMultiMap<int, int>::iterator j = map.insert(map.constBegin(), 69, 66);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 8);
- j = map.insertMulti(cite(j), 68, 259);
+ j = map.insert(j, 68, 259);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 9);
- j = map.insertMulti(cite(j), 67, 67);
+ j = map.insert(j, 67, 67);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 10);
- i = map.insertMulti(cite(i), 256, 259);
+ i = map.insert(i, 256, 259);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 11);
- i = map.insertMulti(cite(i), 256, 260);
+ i = map.insert(i, 256, 260);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 12);
- map.insertMulti(cite(i), 64, 67);
+ map.insert(i, 64, 67);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 13);
- map.insertMulti(map.constBegin(), 20, 20);
+ map.insert(map.constBegin(), 20, 20);
sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 14);
}
void tst_QMap::eraseValidIteratorOnSharedMap()
{
- QMap<int, int> a, b;
+ QMultiMap<int, int> a, b;
a.insert(10, 10);
- a.insertMulti(10, 40);
- a.insertMulti(10, 25);
- a.insertMulti(10, 30);
+ a.insert(10, 40);
+ a.insert(10, 25);
+ a.insert(10, 30);
a.insert(20, 20);
- QMap<int, int>::iterator i = a.begin();
+ QMultiMap<int, int>::iterator i = a.begin();
while (i.value() != 25)
++i;
@@ -1494,12 +2308,12 @@ void tst_QMap::eraseValidIteratorOnSharedMap()
QCOMPARE(itemsWith10, 4);
// Border cases
- QMap <QString, QString> ms1, ms2, ms3;
+ QMultiMap <QString, QString> ms1, ms2, ms3;
+ ms1.insert("foo", "bar");
+ ms1.insert("foo", "quux");
ms1.insert("foo", "bar");
- ms1.insertMulti("foo", "quux");
- ms1.insertMulti("foo", "bar");
- QMap <QString, QString>::iterator si = ms1.begin();
+ QMultiMap <QString, QString>::iterator si = ms1.begin();
ms2 = ms1;
ms1.erase(si);
si = ms1.begin();
@@ -1522,5 +2336,314 @@ void tst_QMap::eraseValidIteratorOnSharedMap()
QCOMPARE(ms3.size(), 3);
}
+void tst_QMap::removeElementsInMap()
+{
+ // A class that causes an almost certain crash if its operator< is
+ // called on a destroyed object
+ struct SharedInt {
+ QSharedPointer<int> m_int;
+ explicit SharedInt(int i) : m_int(QSharedPointer<int>::create(i)) {}
+ bool operator<(const SharedInt &other) const { return *m_int < *other.m_int; }
+ };
+
+ {
+ QMap<int, int> map;
+ QCOMPARE(map.remove(1), 0);
+ QVERIFY(!map.isDetached());
+
+ auto cnt = map.removeIf([](QMap<int, int>::iterator) { return true; });
+ QCOMPARE(cnt, 0);
+ }
+ {
+ QMap<SharedInt, int> map {
+ { SharedInt(1), 1 },
+ { SharedInt(2), 2 },
+ { SharedInt(3), 3 },
+ { SharedInt(4), 4 },
+ { SharedInt(5), 5 },
+ };
+ QCOMPARE(map.size(), 5);
+
+ map.remove(SharedInt(1));
+ QCOMPARE(map.size(), 4);
+
+ map.remove(SharedInt(-1));
+ QCOMPARE(map.size(), 4);
+
+ QMap<SharedInt, int> map2 = map;
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(map2.size(), 4);
+
+ map.remove(SharedInt(3));
+ QCOMPARE(map.size(), 3);
+ QCOMPARE(map2.size(), 4);
+
+ map.remove(SharedInt(-1));
+ QCOMPARE(map.size(), 3);
+ QCOMPARE(map2.size(), 4);
+
+ map = map2;
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(map2.size(), 4);
+
+ map.remove(SharedInt(-1));
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(map2.size(), 4);
+
+ map.remove(map.firstKey());
+ QCOMPARE(map.size(), 3);
+ QCOMPARE(map2.size(), 4);
+
+ map.remove(map.lastKey());
+ QCOMPARE(map.size(), 2);
+ QCOMPARE(map2.size(), 4);
+
+ map = map2;
+ QCOMPARE(map.size(), 4);
+ QCOMPARE(map2.size(), 4);
+
+ auto size = map.size();
+ for (auto it = map.begin(); it != map.end(); ) {
+ const auto oldIt = it++;
+ size -= map.remove(oldIt.key());
+ QCOMPARE(map.size(), size);
+ QCOMPARE(map2.size(), 4);
+ }
+
+ QCOMPARE(map.size(), 0);
+ QCOMPARE(map2.size(), 4);
+
+ auto cnt = map2.removeIf([](auto it) { return (*it % 2) == 0; });
+ QCOMPARE(cnt, 2);
+ QCOMPARE(map2.size(), 2);
+ }
+
+ {
+ QMultiMap<int, int> map;
+ QCOMPARE(map.remove(1), 0);
+ QVERIFY(!map.isDetached());
+
+ auto cnt = map.removeIf([](QMultiMap<int, int>::iterator) { return true; });
+ QCOMPARE(cnt, 0);
+ }
+ {
+ QMultiMap<SharedInt, int> multimap {
+ { SharedInt(1), 10 },
+ { SharedInt(1), 11 },
+ { SharedInt(2), 2 },
+ { SharedInt(3), 30 },
+ { SharedInt(3), 31 },
+ { SharedInt(3), 32 },
+ { SharedInt(4), 4 },
+ { SharedInt(5), 5 },
+ { SharedInt(6), 60 },
+ { SharedInt(6), 61 },
+ { SharedInt(6), 60 },
+ { SharedInt(6), 62 },
+ { SharedInt(6), 60 },
+ { SharedInt(7), 7 },
+ };
+
+ QCOMPARE(multimap.size(), 14);
+
+ multimap.remove(SharedInt(1));
+ QCOMPARE(multimap.size(), 12);
+
+ multimap.remove(SharedInt(-1));
+ QCOMPARE(multimap.size(), 12);
+
+ QMultiMap<SharedInt, int> multimap2 = multimap;
+ QCOMPARE(multimap.size(), 12);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(SharedInt(3));
+ QCOMPARE(multimap.size(), 9);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(SharedInt(4));
+ QCOMPARE(multimap.size(), 8);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(SharedInt(-1));
+ QCOMPARE(multimap.size(), 8);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap = multimap2;
+ QCOMPARE(multimap.size(), 12);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(SharedInt(-1));
+ QCOMPARE(multimap.size(), 12);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(SharedInt(6), 60);
+ QCOMPARE(multimap.size(), 9);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap = multimap2;
+ QCOMPARE(multimap.size(), 12);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(SharedInt(6), 62);
+ QCOMPARE(multimap.size(), 11);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(multimap.firstKey());
+ QCOMPARE(multimap.size(), 10);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap.remove(multimap.lastKey());
+ QCOMPARE(multimap.size(), 9);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap = multimap2;
+ QCOMPARE(multimap.size(), 12);
+ QCOMPARE(multimap2.size(), 12);
+
+ auto itFor6 = multimap.find(SharedInt(6));
+ QVERIFY(itFor6 != multimap.end());
+ QCOMPARE(itFor6.value(), 60);
+ multimap.remove(itFor6.key(), itFor6.value());
+ QCOMPARE(multimap.size(), 9);
+ QCOMPARE(multimap2.size(), 12);
+
+ multimap = multimap2;
+ QCOMPARE(multimap.size(), 12);
+ QCOMPARE(multimap2.size(), 12);
+
+ auto size = multimap.size();
+ for (auto it = multimap.begin(); it != multimap.end();) {
+ const auto range = multimap.equal_range(it.key());
+ const auto oldIt = it;
+ it = range.second;
+ size -= multimap.remove(oldIt.key());
+ QCOMPARE(multimap.size(), size);
+ QCOMPARE(multimap2.size(), 12);
+ }
+
+ QCOMPARE(multimap.size(), 0);
+ QCOMPARE(multimap2.size(), 12);
+
+ auto cnt = multimap2.removeIf([](auto it) { return (*it % 2) == 0; });
+ QCOMPARE(cnt, 8);
+ QCOMPARE(multimap2.size(), 4);
+ }
+}
+
+template <typename QtMap, typename StdMap>
+void toStdMapTestMethod(const StdMap &expectedMap)
+{
+ QtMap map;
+ QVERIFY(map.isEmpty());
+ auto stdMap = map.toStdMap();
+ QVERIFY(stdMap.empty());
+ QVERIFY(!map.isDetached());
+
+ map.insert(1, "value1");
+ map.insert(2, "value2");
+ map.insert(3, "value3");
+ map.insert(1, "value0");
+
+ stdMap = map.toStdMap();
+ QCOMPARE(stdMap, expectedMap);
+}
+
+void tst_QMap::toStdMap()
+{
+ const std::map<int, QString> expectedMap { {1, "value0"}, {2, "value2"}, {3, "value3"} };
+ toStdMapTestMethod<QMap<int, QString>>(expectedMap);
+ if (QTest::currentTestFailed())
+ return;
+
+ const std::multimap<int, QString> expectedMultiMap {
+ {1, "value0"}, {1, "value1"}, {2, "value2"}, {3, "value3"} };
+ toStdMapTestMethod<QMultiMap<int, QString>>(expectedMultiMap);
+}
+
+void tst_QMap::multiMapStoresInReverseInsertionOrder()
+{
+ const QString strings[] = {
+ u"zero"_s,
+ u"null"_s,
+ u"nada"_s,
+ };
+ {
+ QMultiMap<int, QString> map;
+ for (const QString &string : strings)
+ map.insert(0, string);
+ auto printOnFailure = qScopeGuard([&] { qDebug() << map; });
+ QVERIFY(std::equal(map.begin(), map.end(),
+ std::rbegin(strings), std::rend(strings)));
+ printOnFailure.dismiss();
+ }
+}
+
+#if QT_DEPRECATED_SINCE(6, 0)
+void tst_QMap::deprecatedInsertMulti()
+{
+ QMultiMap<int, QString> referenceMap;
+ referenceMap.insert(1, "value1");
+ referenceMap.insert(2, "value2");
+ referenceMap.insert(3, "value3");
+ referenceMap.insert(1, "value1_2");
+ referenceMap.insert(referenceMap.find(2), 2, "value2_2");
+ referenceMap.insert(referenceMap.end(), 1, "value1_3");
+
+ QMultiMap<int, QString> deprecatedMap;
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ deprecatedMap.insertMulti(1, "value1");
+ deprecatedMap.insertMulti(2, "value2");
+ deprecatedMap.insertMulti(3, "value3");
+ deprecatedMap.insertMulti(1, "value1_2");
+ deprecatedMap.insertMulti(deprecatedMap.find(2), 2, "value2_2");
+ deprecatedMap.insertMulti(deprecatedMap.end(), 1, "value1_3");
+QT_WARNING_POP
+
+ QCOMPARE(deprecatedMap, referenceMap);
+}
+
+void tst_QMap::deprecatedIteratorApis()
+{
+ QMap<int, QString> map;
+ QString testString = "Teststring %1";
+ for (int i = 1; i < 100; ++i)
+ map.insert(i, testString.arg(i));
+
+ auto it = map.begin();
+ QCOMPARE(it.value(), QLatin1String("Teststring 1"));
+ QT_IGNORE_DEPRECATIONS(it += 5;)
+ QCOMPARE(it.value(), QLatin1String("Teststring 6"));
+ QT_IGNORE_DEPRECATIONS(it = it - 3;)
+ QCOMPARE(it.value(), QLatin1String("Teststring 3"));
+
+ auto cit = map.constBegin();
+ QCOMPARE(cit.value(), QLatin1String("Teststring 1"));
+ QT_IGNORE_DEPRECATIONS(cit += 5;)
+ QCOMPARE(cit.value(), QLatin1String("Teststring 6"));
+ QT_IGNORE_DEPRECATIONS(cit = cit - 3;)
+ QCOMPARE(cit.value(), QLatin1String("Teststring 3"));
+}
+
+void tst_QMap::deprecatedInsert()
+{
+ QMultiMap<int, QString> refMap;
+ refMap.insert(1, "value1");
+ refMap.insert(2, "value2");
+ refMap.insert(3, "value3");
+
+ QMultiMap<int, QString> depMap = refMap;
+
+ QMultiMap<int, QString> otherMap;
+ otherMap.insert(1, "value1_2");
+ otherMap.insert(3, "value3_2");
+ otherMap.insert(4, "value4");
+
+ refMap.unite(otherMap);
+ QT_IGNORE_DEPRECATIONS(depMap.insert(otherMap);)
+
+ QCOMPARE(refMap, depMap);
+}
+#endif // QT_DEPRECATED_SINCE(6, 0)
+
QTEST_APPLESS_MAIN(tst_QMap)
#include "tst_qmap.moc"
diff --git a/tests/auto/corelib/tools/qmap_strictiterators/qmap_strictiterators.pro b/tests/auto/corelib/tools/qmap_strictiterators/qmap_strictiterators.pro
deleted file mode 100644
index 6c1f4727c1..0000000000
--- a/tests/auto/corelib/tools/qmap_strictiterators/qmap_strictiterators.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-include(../qmap/qmap.pro)
-TARGET = tst_qmap_strictiterators
-DEFINES += QT_STRICT_ITERATORS tst_QMap=tst_QMap_StrictIterators
diff --git a/tests/auto/corelib/tools/qmargins/CMakeLists.txt b/tests/auto/corelib/tools/qmargins/CMakeLists.txt
new file mode 100644
index 0000000000..2e0ea797ff
--- /dev/null
+++ b/tests/auto/corelib/tools/qmargins/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmargins Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmargins LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmargins
+ SOURCES
+ tst_qmargins.cpp
+)
diff --git a/tests/auto/corelib/tools/qmargins/qmargins.pro b/tests/auto/corelib/tools/qmargins/qmargins.pro
deleted file mode 100644
index 696f9374a2..0000000000
--- a/tests/auto/corelib/tools/qmargins/qmargins.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmargins
-QT = core testlib
-SOURCES = tst_qmargins.cpp
diff --git a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp
index 2a35162ef0..2611f62f01 100644
--- a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp
+++ b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp
@@ -1,34 +1,40 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QMargins>
+#ifdef QVARIANT_H
+# error "This test requires qmargins.h to not include qvariant.h"
+#endif
+
+// don't assume <type_traits>
+template <typename T, typename U>
+constexpr inline bool my_is_same_v = false;
+template <typename T>
+constexpr inline bool my_is_same_v<T, T> = true;
+
+#define CHECK(cvref) \
+ static_assert(my_is_same_v<decltype(get<0>(std::declval<QMargins cvref >())), int cvref >); \
+ static_assert(my_is_same_v<decltype(get<1>(std::declval<QMargins cvref >())), int cvref >); \
+ static_assert(my_is_same_v<decltype(get<2>(std::declval<QMargins cvref >())), int cvref >); \
+ static_assert(my_is_same_v<decltype(get<3>(std::declval<QMargins cvref >())), int cvref >); \
+ \
+ static_assert(my_is_same_v<decltype(get<0>(std::declval<QMarginsF cvref >())), qreal cvref >); \
+ static_assert(my_is_same_v<decltype(get<1>(std::declval<QMarginsF cvref >())), qreal cvref >); \
+ static_assert(my_is_same_v<decltype(get<2>(std::declval<QMarginsF cvref >())), qreal cvref >); \
+ static_assert(my_is_same_v<decltype(get<3>(std::declval<QMarginsF cvref >())), qreal cvref >)
+
+CHECK(&);
+CHECK(const &);
+CHECK(&&);
+CHECK(const &&);
+
+#undef CHECK
+
+#include <QTest>
#include <qmargins.h>
+#include <array>
+
Q_DECLARE_METATYPE(QMargins)
class tst_QMargins : public QObject
@@ -36,12 +42,27 @@ class tst_QMargins : public QObject
Q_OBJECT
private slots:
void getSetCheck();
+#ifndef QT_NO_DATASTREAM
void dataStreamCheck();
+#endif
void operators();
+#ifndef QT_NO_DEBUG_STREAM
+ void debugStreamCheck();
+#endif
void getSetCheckF();
+#ifndef QT_NO_DATASTREAM
void dataStreamCheckF();
+#endif
void operatorsF();
+#ifndef QT_NO_DEBUG_STREAM
+ void debugStreamCheckF();
+#endif
+
+ void structuredBinding();
+
+ void toMarginsF_data();
+ void toMarginsF();
};
// Testing get/set functions
@@ -123,6 +144,19 @@ void tst_QMargins::operators()
QCOMPARE(-m3, QMargins(-10, -11, -12, -13));
}
+#ifndef QT_NO_DEBUG_STREAM
+// Testing QDebug operators
+void tst_QMargins::debugStreamCheck()
+{
+ QMargins m(10, 11, 12, 13);
+ const QString expected = "QMargins(10, 11, 12, 13)";
+ QString result;
+ QDebug(&result).nospace() << m;
+ QCOMPARE(result, expected);
+}
+#endif
+
+#ifndef QT_NO_DATASTREAM
// Testing QDataStream operators
void tst_QMargins::dataStreamCheck()
{
@@ -147,6 +181,7 @@ void tst_QMargins::dataStreamCheck()
QCOMPARE(marginsIn.bottom(), 6852);
}
}
+#endif
// Testing get/set functions
void tst_QMargins::getSetCheckF()
@@ -220,6 +255,7 @@ void tst_QMargins::operatorsF()
QCOMPARE(-m3, QMarginsF(-10.3, -11.4, -12.5, -13.6));
}
+#ifndef QT_NO_DATASTREAM
// Testing QDataStream operators
void tst_QMargins::dataStreamCheckF()
{
@@ -244,6 +280,102 @@ void tst_QMargins::dataStreamCheckF()
QCOMPARE(marginsIn.bottom(), 4.4);
}
}
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+// Testing QDebug operators
+void tst_QMargins::debugStreamCheckF()
+{
+ QMarginsF m(10.1, 11.2, 12.3, 13.4);
+ const QString expected = "QMarginsF(10.1, 11.2, 12.3, 13.4)";
+ QString result;
+ QDebug(&result).nospace() << m;
+ QCOMPARE(result, expected);
+}
+#endif
+
+void tst_QMargins::structuredBinding()
+{
+ {
+ QMargins m(1, 2, 3, 4);
+ auto [left, top, right, bottom] = m;
+ QCOMPARE(left, 1);
+ QCOMPARE(top, 2);
+ QCOMPARE(right, 3);
+ QCOMPARE(bottom, 4);
+ }
+ {
+ QMargins m(1, 2, 3, 4);
+ auto &[left, top, right, bottom] = m;
+ QCOMPARE(left, 1);
+ QCOMPARE(top, 2);
+ QCOMPARE(right, 3);
+ QCOMPARE(bottom, 4);
+
+ left = 10;
+ top = 20;
+ right = 30;
+ bottom = 40;
+ QCOMPARE(m.left(), 10);
+ QCOMPARE(m.top(), 20);
+ QCOMPARE(m.right(), 30);
+ QCOMPARE(m.bottom(), 40);
+ }
+ {
+ QMarginsF m(1.0, 2.0, 3.0, 4.0);
+ auto [left, top, right, bottom] = m;
+ QCOMPARE(left, 1.0);
+ QCOMPARE(top, 2.0);
+ QCOMPARE(right, 3.0);
+ QCOMPARE(bottom, 4.0);
+ }
+ {
+ QMarginsF m(1.0, 2.0, 3.0, 4.0);
+ auto &[left, top, right, bottom] = m;
+ QCOMPARE(left, 1.0);
+ QCOMPARE(top, 2.0);
+ QCOMPARE(right, 3.0);
+ QCOMPARE(bottom, 4.0);
+
+ left = 10.0;
+ top = 20.0;
+ right = 30.0;
+ bottom = 40.0;
+ QCOMPARE(m.left(), 10.0);
+ QCOMPARE(m.top(), 20.0);
+ QCOMPARE(m.right(), 30.0);
+ QCOMPARE(m.bottom(), 40.0);
+ }
+}
+
+void tst_QMargins::toMarginsF_data()
+{
+ QTest::addColumn<QMargins>("input");
+ QTest::addColumn<QMarginsF>("result");
+
+ auto row = [](int x1, int y1, int x2, int y2) {
+ QTest::addRow("(%d, %d, %d, %d)", x1, y1, x2, y2)
+ << QMargins(x1, y1, x2, y2) << QMarginsF(x1, y1, x2, y2);
+ };
+ constexpr std::array samples = {-1, 0, 1};
+ for (int x1 : samples) {
+ for (int y1 : samples) {
+ for (int x2 : samples) {
+ for (int y2 : samples) {
+ row(x1, y1, x2, y2);
+ }
+ }
+ }
+ }
+}
+
+void tst_QMargins::toMarginsF()
+{
+ QFETCH(const QMargins, input);
+ QFETCH(const QMarginsF, result);
+
+ QCOMPARE(input.toMarginsF(), result);
+}
QTEST_APPLESS_MAIN(tst_QMargins)
#include "tst_qmargins.moc"
diff --git a/tests/auto/corelib/tools/qmessageauthenticationcode/CMakeLists.txt b/tests/auto/corelib/tools/qmessageauthenticationcode/CMakeLists.txt
new file mode 100644
index 0000000000..a21481b7ba
--- /dev/null
+++ b/tests/auto/corelib/tools/qmessageauthenticationcode/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qmessageauthenticationcode Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmessageauthenticationcode LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qmessageauthenticationcode
+ SOURCES
+ tst_qmessageauthenticationcode.cpp
+)
diff --git a/tests/auto/corelib/tools/qmessageauthenticationcode/qmessageauthenticationcode.pro b/tests/auto/corelib/tools/qmessageauthenticationcode/qmessageauthenticationcode.pro
deleted file mode 100644
index a62b702f22..0000000000
--- a/tests/auto/corelib/tools/qmessageauthenticationcode/qmessageauthenticationcode.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qmessageauthenticationcode
-QT = core testlib
-SOURCES = tst_qmessageauthenticationcode.cpp
-
diff --git a/tests/auto/corelib/tools/qmessageauthenticationcode/tst_qmessageauthenticationcode.cpp b/tests/auto/corelib/tools/qmessageauthenticationcode/tst_qmessageauthenticationcode.cpp
index 2f8052fd4a..9e94ad77e9 100644
--- a/tests/auto/corelib/tools/qmessageauthenticationcode/tst_qmessageauthenticationcode.cpp
+++ b/tests/auto/corelib/tools/qmessageauthenticationcode/tst_qmessageauthenticationcode.cpp
@@ -1,47 +1,75 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QCryptographicHash>
+#include <QMessageAuthenticationCode>
+#include <QBuffer>
class tst_QMessageAuthenticationCode : public QObject
{
Q_OBJECT
private slots:
+ void repeated_setKey_data();
+ void repeated_setKey();
void result_data();
void result();
void result_incremental_data();
void result_incremental();
+ void addData_overloads_data();
+ void addData_overloads();
+ void move();
+ void swap();
};
Q_DECLARE_METATYPE(QCryptographicHash::Algorithm)
+void tst_QMessageAuthenticationCode::repeated_setKey_data()
+{
+ using A = QCryptographicHash::Algorithm;
+ QTest::addColumn<A>("algo");
+
+ const auto me = QMetaEnum::fromType<A>();
+ for (int i = 0, value; (value = me.value(i)) != -1; ++i)
+ QTest::addRow("%s", me.key(i)) << A(value);
+}
+
+void tst_QMessageAuthenticationCode::repeated_setKey()
+{
+ QFETCH(const QCryptographicHash::Algorithm, algo);
+
+ if (!QCryptographicHash::supportsAlgorithm(algo))
+ QSKIP("QCryptographicHash doesn't support this algorithm");
+
+ // GIVEN: two long keys, so we're sure the key needs to be hashed in order
+ // to fit into the hash algorithm's block
+
+ static const QByteArray key1(1024, 'a');
+ static const QByteArray key2(2048, 'b');
+
+ // WHEN: processing the same message
+
+ QMessageAuthenticationCode macX(algo);
+ QMessageAuthenticationCode mac1(algo, key1);
+ QMessageAuthenticationCode mac2(algo, key2);
+
+ const auto check = [](QMessageAuthenticationCode &mac) {
+ mac.addData("This is nonsense, ignore it, please.");
+ return mac.result();
+ };
+
+ macX.setKey(key1);
+ QCOMPARE(check(macX), check(mac1));
+
+ // THEN: the result does not depend on whether a new QMAC instance was used
+ // or an old one re-used (iow: setKey() reset()s)
+
+ macX.setKey(key2);
+ QCOMPARE(check(macX), check(mac2));
+}
+
void tst_QMessageAuthenticationCode::result_data()
{
QTest::addColumn<QCryptographicHash::Algorithm>("algo");
@@ -62,6 +90,15 @@ void tst_QMessageAuthenticationCode::result_data()
<< QByteArray()
<< QByteArray()
<< QByteArray::fromHex("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad");
+ QTest::newRow("sha384-empty") << QCryptographicHash::Sha384 << QByteArray() << QByteArray()
+ << QByteArray::fromHex(
+ "6c1f2ee938fad2e24bd91298474382ca218c75db3d83e114b3d43"
+ "67776d14d3551289e75e8209cd4b792302840234adc");
+ QTest::newRow("sha512-empty")
+ << QCryptographicHash::Sha512 << QByteArray() << QByteArray()
+ << QByteArray::fromHex(
+ "b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b"
+ "327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47");
// Some not-empty
QTest::newRow("md5") << QCryptographicHash::Md5
@@ -76,6 +113,17 @@ void tst_QMessageAuthenticationCode::result_data()
<< QByteArray("key")
<< QByteArray("The quick brown fox jumps over the lazy dog")
<< QByteArray::fromHex("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8");
+ QTest::newRow("sha384") << QCryptographicHash::Sha384 << QByteArray("key")
+ << QByteArray("The quick brown fox jumps over the lazy dog")
+ << QByteArray::fromHex(
+ "d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae"
+ "50700582a96cf35e1e554995fe4e03381c237");
+ QTest::newRow("sha512")
+ << QCryptographicHash::Sha512 << QByteArray("key")
+ << QByteArray("The quick brown fox jumps over the lazy dog")
+ << QByteArray::fromHex(
+ "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f"
+ "7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a");
// Some from rfc-2104
QTest::newRow("rfc-md5-1") << QCryptographicHash::Md5
@@ -99,11 +147,13 @@ void tst_QMessageAuthenticationCode::result()
QFETCH(QByteArray, message);
QFETCH(QByteArray, code);
- QMessageAuthenticationCode mac(algo);
- mac.setKey(key);
+ QMessageAuthenticationCode mac(algo, key);
mac.addData(message);
- QByteArray result = mac.result();
+ QByteArrayView resultView = mac.resultView();
+
+ QCOMPARE(resultView, code);
+ const auto result = QMessageAuthenticationCode::hash(message, key, algo);
QCOMPARE(result, code);
}
@@ -119,20 +169,98 @@ void tst_QMessageAuthenticationCode::result_incremental()
QFETCH(QByteArray, message);
QFETCH(QByteArray, code);
- int index = message.length() / 2;
+ int index = message.size() / 2;
QByteArray leftPart(message.mid(0, index));
QByteArray rightPart(message.mid(index));
QCOMPARE(leftPart + rightPart, message);
- QMessageAuthenticationCode mac(algo);
- mac.setKey(key);
+ QMessageAuthenticationCode mac(algo, key);
mac.addData(leftPart);
mac.addData(rightPart);
- QByteArray result = mac.result();
+ QByteArrayView result = mac.resultView();
QCOMPARE(result, code);
}
+void tst_QMessageAuthenticationCode::addData_overloads_data()
+{
+ result_data();
+}
+
+void tst_QMessageAuthenticationCode::addData_overloads()
+{
+ QFETCH(QCryptographicHash::Algorithm, algo);
+ QFETCH(QByteArray, key);
+ QFETCH(QByteArray, message);
+ QFETCH(QByteArray, code);
+
+ // overload using const char* and length
+ {
+ QMessageAuthenticationCode mac(algo);
+ mac.setKey(key);
+ mac.addData(message.constData(), message.size());
+ QByteArrayView result = mac.resultView();
+
+ QCOMPARE(result, code);
+ }
+
+ // overload using QIODevice
+ {
+ QBuffer buffer(&message);
+ buffer.open(QIODevice::ReadOnly);
+ QMessageAuthenticationCode mac(algo);
+ mac.setKey(key);
+ QVERIFY(mac.addData(&buffer));
+ QByteArrayView result = mac.resultView();
+ buffer.close();
+
+ QCOMPARE(result, code);
+ }
+}
+
+void tst_QMessageAuthenticationCode::move()
+{
+ const QByteArray key = "123";
+
+ QMessageAuthenticationCode src(QCryptographicHash::Sha1, key);
+ src.addData("a");
+
+ // move constructor
+ auto intermediary = std::move(src);
+ intermediary.addData("b");
+
+ // move assign operator
+ QMessageAuthenticationCode dst(QCryptographicHash::Sha256, key);
+ dst.addData("no effect on the end result");
+ dst = std::move(intermediary);
+ dst.addData("c");
+
+ QCOMPARE(dst.resultView(),
+ QMessageAuthenticationCode::hash("abc", key, QCryptographicHash::Sha1));
+}
+
+void tst_QMessageAuthenticationCode::swap()
+{
+ const QByteArray key1 = "123";
+ const QByteArray key2 = "abcdefg";
+
+ QMessageAuthenticationCode mac1(QCryptographicHash::Sha1, key1);
+ QMessageAuthenticationCode mac2(QCryptographicHash::Sha256, key2);
+
+ mac1.addData("da");
+ mac2.addData("te");
+
+ mac1.swap(mac2);
+
+ mac2.addData("ta");
+ mac1.addData("st");
+
+ QCOMPARE(mac2.resultView(),
+ QMessageAuthenticationCode::hash("data", key1, QCryptographicHash::Sha1));
+ QCOMPARE(mac1.resultView(),
+ QMessageAuthenticationCode::hash("test", key2, QCryptographicHash::Sha256));
+}
+
QTEST_MAIN(tst_QMessageAuthenticationCode)
#include "tst_qmessageauthenticationcode.moc"
diff --git a/tests/auto/corelib/tools/qoffsetstringarray/CMakeLists.txt b/tests/auto/corelib/tools/qoffsetstringarray/CMakeLists.txt
new file mode 100644
index 0000000000..d0205cfa15
--- /dev/null
+++ b/tests/auto/corelib/tools/qoffsetstringarray/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qoffsetstringarray Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qoffsetstringarray LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qoffsetstringarray
+ SOURCES
+ tst_qoffsetstringarray.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
+
+if (CLANG)
+ target_compile_options(tst_qoffsetstringarray
+ PUBLIC -fbracket-depth=512)
+elseif (GCC)
+ # fconstexpr-depth= defaults to 512
+endif()
diff --git a/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp
new file mode 100644
index 0000000000..dbb24e7af4
--- /dev/null
+++ b/tests/auto/corelib/tools/qoffsetstringarray/tst_qoffsetstringarray.cpp
@@ -0,0 +1,105 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+
+#include <private/qoffsetstringarray_p.h>
+
+
+class tst_QOffsetStringArray : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init();
+ void access();
+ void contains();
+};
+
+
+constexpr const auto messages = qOffsetStringArray(
+ "level - 0",
+ "level - 1",
+ "level - 2",
+ "level - 3",
+ "level - 4"
+);
+
+constexpr const auto messages257 = qOffsetStringArray(
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "end"
+);
+
+constexpr const auto messagesBigOffsets = qOffsetStringArray(
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90",
+ " 10 20 30 40 50 60 70 80 90"
+);
+
+void tst_QOffsetStringArray::init()
+{
+ static_assert(messages.m_string.size() == 50);
+ static_assert(messages.m_offsets.size() == 6);
+ static_assert(std::is_same_v<decltype(messages.m_offsets)::value_type, quint8>);
+
+ static_assert(messages257.m_offsets.size() == 258);
+ static_assert(messages257.m_string.size() == 260);
+ static_assert(std::is_same_v<decltype(messages257.m_offsets)::value_type, quint16>);
+
+ static_assert(messagesBigOffsets.m_offsets.size() == 5);
+ static_assert(messagesBigOffsets.m_string.size() == 364);
+ static_assert(std::is_same_v<decltype(messagesBigOffsets.m_offsets)::value_type, quint16>);
+}
+
+void tst_QOffsetStringArray::access()
+{
+ QCOMPARE(messages[0], "level - 0");
+ QCOMPARE(messages[1], "level - 1");
+ QCOMPARE(messages[2], "level - 2");
+ QCOMPARE(messages[3], "level - 3");
+ QCOMPARE(messages[4], "level - 4");
+ // out of bounds returns empty strings:
+ QCOMPARE(messages[5], "");
+ QCOMPARE(messages[6], "");
+}
+
+void tst_QOffsetStringArray::contains()
+{
+ QVERIFY(!messages.contains(""));
+ QVERIFY( messages.contains("level - 0"));
+ std::string l2 = "level - 2"; // make sure we don't compare pointer values
+ QVERIFY( messages.contains(l2));
+ QByteArray L4 = "Level - 4";
+ QVERIFY( messages.contains(L4, Qt::CaseInsensitive));
+ QVERIFY(!messages.contains(L4, Qt::CaseSensitive));
+}
+
+QTEST_APPLESS_MAIN(tst_QOffsetStringArray)
+#include "tst_qoffsetstringarray.moc"
diff --git a/tests/auto/corelib/tools/qpair/CMakeLists.txt b/tests/auto/corelib/tools/qpair/CMakeLists.txt
new file mode 100644
index 0000000000..2dd048e015
--- /dev/null
+++ b/tests/auto/corelib/tools/qpair/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpair Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpair LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qpair
+ SOURCES
+ tst_qpair.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/tools/qpair/qpair.pro b/tests/auto/corelib/tools/qpair/qpair.pro
deleted file mode 100644
index 659be887d3..0000000000
--- a/tests/auto/corelib/tools/qpair/qpair.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qpair
-QT = core testlib
-SOURCES = tst_qpair.cpp
diff --git a/tests/auto/corelib/tools/qpair/tst_qpair.cpp b/tests/auto/corelib/tools/qpair/tst_qpair.cpp
index 1d5f7536c8..0c9d87bb01 100644
--- a/tests/auto/corelib/tools/qpair/tst_qpair.cpp
+++ b/tests/auto/corelib/tools/qpair/tst_qpair.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QPair>
#include <QSize>
@@ -36,17 +11,19 @@ class tst_QPair : public QObject
Q_OBJECT
private Q_SLOTS:
void pairOfReferences();
+ void structuredBindings();
void testConstexpr();
void testConversions();
void taskQTBUG_48780_pairContainingCArray();
+ void testDeductionRules();
};
-class C { char _[4]; };
-class M { char _[4]; };
-class P { char _[4]; };
+class C { C() {} ~C() {} Q_DECL_UNUSED_MEMBER char _[4]; };
+class M { M() {} Q_DECL_UNUSED_MEMBER char _[4]; };
+class P { Q_DECL_UNUSED_MEMBER char _[4]; };
QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(M, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(M, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(P, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
@@ -61,35 +38,34 @@ typedef QPair<P,C> QPairPC;
typedef QPair<P,M> QPairPM;
typedef QPair<P,P> QPairPP;
-Q_STATIC_ASSERT( QTypeInfo<QPairCC>::isComplex);
-Q_STATIC_ASSERT( QTypeInfo<QPairCC>::isStatic );
+static_assert( QTypeInfo<QPairCC>::isComplex);
+static_assert( !QTypeInfo<QPairCC>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairCM>::isComplex);
-Q_STATIC_ASSERT( QTypeInfo<QPairCM>::isStatic );
+static_assert( QTypeInfo<QPairCM>::isComplex);
+static_assert( !QTypeInfo<QPairCM>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairCP>::isComplex);
-Q_STATIC_ASSERT( QTypeInfo<QPairCP>::isStatic );
+static_assert( QTypeInfo<QPairCP>::isComplex);
+static_assert( !QTypeInfo<QPairCP>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairMC>::isComplex);
-Q_STATIC_ASSERT( QTypeInfo<QPairMC>::isStatic );
+static_assert( QTypeInfo<QPairMC>::isComplex);
+static_assert( !QTypeInfo<QPairMC>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairMM>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<QPairMM>::isStatic );
+static_assert( QTypeInfo<QPairMM>::isComplex);
+static_assert( QTypeInfo<QPairMM>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairMP>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<QPairMP>::isStatic );
+static_assert( QTypeInfo<QPairMP>::isComplex);
+static_assert( QTypeInfo<QPairMP>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairPC>::isComplex);
-Q_STATIC_ASSERT( QTypeInfo<QPairPC>::isStatic );
+static_assert( QTypeInfo<QPairPC>::isComplex);
+static_assert( !QTypeInfo<QPairPC>::isRelocatable );
-Q_STATIC_ASSERT( QTypeInfo<QPairPM>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<QPairPM>::isStatic );
+static_assert( QTypeInfo<QPairPM>::isComplex);
+static_assert( QTypeInfo<QPairPM>::isRelocatable );
-Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isStatic );
+static_assert(!QTypeInfo<QPairPP>::isComplex);
+static_assert( QTypeInfo<QPairPP>::isRelocatable );
-Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isDummy );
-Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isPointer);
+static_assert(!std::is_pointer_v<QPairPP>);
void tst_QPair::pairOfReferences()
@@ -121,17 +97,67 @@ void tst_QPair::pairOfReferences()
QCOMPARE(p.second, QLatin1String("World"));
}
+void tst_QPair::structuredBindings()
+{
+ using PV = QPair<int, QString>;
+ using PR = QPair<int&, const QString&>;
+
+ {
+ PV pv = {42, "Hello"};
+ PR pr = {pv.first, pv.second};
+
+ auto [fv, sv] = pv;
+
+ fv = 24;
+ sv = "World";
+ QCOMPARE(fv, 24);
+ QCOMPARE(sv, "World");
+ QCOMPARE(pv.first, 42);
+ QCOMPARE(pv.second, "Hello");
+
+ auto [fr, sr] = pr;
+
+ fr = 2424;
+ // sr = "World"; // const
+ QCOMPARE(fr, 2424);
+ QCOMPARE(pv.first, 2424);
+ }
+
+ {
+ PV pv = {42, "Hello"};
+ PR pr = {pv.first, pv.second};
+
+ auto& [fv, sv] = pv;
+
+ fv = 24;
+ sv = "World";
+ QCOMPARE(fv, 24);
+ QCOMPARE(sv, "World");
+ QCOMPARE(pv.first, 24);
+ QCOMPARE(pv.second, "World");
+
+ auto& [fr, sr] = pr;
+
+ fr = 4242;
+ //sr = "2World"; // const
+
+ QCOMPARE(fr, 4242);
+ QCOMPARE(pr.first, 4242);
+ QCOMPARE(pv.first, 4242);
+ }
+}
+
void tst_QPair::testConstexpr()
{
- Q_CONSTEXPR QPair<int, double> pID = qMakePair(0, 0.0);
+ constexpr QPair<int, double> pID = qMakePair(0, 0.0);
Q_UNUSED(pID);
- Q_CONSTEXPR QPair<double, double> pDD = qMakePair(0.0, 0.0);
- Q_CONSTEXPR QPair<double, double> pDD2 = qMakePair(0, 0.0); // involes (rvalue) conversion ctor
- Q_CONSTEXPR bool equal = pDD2 == pDD;
+ constexpr QPair<double, double> pDD = qMakePair(0.0, 0.0);
+ constexpr QPair<double, double> pDD2 = qMakePair(0, 0.0); // involes (rvalue) conversion ctor
+ constexpr bool equal = pDD2 == pDD;
QVERIFY(equal);
- Q_CONSTEXPR QPair<QSize, int> pSI = qMakePair(QSize(4, 5), 6);
+ constexpr QPair<QSize, int> pSI = qMakePair(QSize(4, 5), 6);
Q_UNUSED(pSI);
}
@@ -202,5 +228,30 @@ void tst_QPair::taskQTBUG_48780_pairContainingCArray()
Q_UNUSED(pair);
}
+void tst_QPair::testDeductionRules()
+{
+#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201907L
+ QPair p1{1, 2};
+ static_assert(std::is_same<decltype(p1)::first_type, decltype(1)>::value);
+ static_assert(std::is_same<decltype(p1)::second_type, decltype(2)>::value);
+ QCOMPARE(p1.first, 1);
+ QCOMPARE(p1.second, 2);
+
+ QPair p2{QString("string"), 2};
+ static_assert(std::is_same<decltype(p2)::first_type, QString>::value);
+ static_assert(std::is_same<decltype(p2)::second_type, decltype(2)>::value);
+ QCOMPARE(p2.first, "string");
+ QCOMPARE(p2.second, 2);
+
+ QPair p3(p2);
+ static_assert(std::is_same<decltype(p3)::first_type, decltype(p2)::first_type>::value);
+ static_assert(std::is_same<decltype(p3)::second_type, decltype(p2)::second_type>::value);
+ QCOMPARE(p3.first, "string");
+ QCOMPARE(p3.second, 2);
+#else
+ QSKIP("Unsupported (requires C++20's CTAD for aliases)");
+#endif
+}
+
QTEST_APPLESS_MAIN(tst_QPair)
#include "tst_qpair.moc"
diff --git a/tests/auto/corelib/tools/qpoint/CMakeLists.txt b/tests/auto/corelib/tools/qpoint/CMakeLists.txt
new file mode 100644
index 0000000000..f1402d8815
--- /dev/null
+++ b/tests/auto/corelib/tools/qpoint/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpoint Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpoint LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qpoint
+ SOURCES
+ tst_qpoint.cpp
+)
diff --git a/tests/auto/corelib/tools/qpoint/qpoint.pro b/tests/auto/corelib/tools/qpoint/qpoint.pro
deleted file mode 100644
index 8321d08fe0..0000000000
--- a/tests/auto/corelib/tools/qpoint/qpoint.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qpoint
-QT = core testlib
-SOURCES = tst_qpoint.cpp
diff --git a/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp b/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp
index 8e184f3ef3..7fea787131 100644
--- a/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp
+++ b/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp
@@ -1,35 +1,35 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QPoint>
+#ifdef QVARIANT_H
+# error "This test requires qpoint.h to not include qvariant.h"
+#endif
+
+// don't assume <type_traits>
+template <typename T, typename U>
+constexpr inline bool my_is_same_v = false;
+template <typename T>
+constexpr inline bool my_is_same_v<T, T> = true;
+
+#define CHECK(cvref) \
+ static_assert(my_is_same_v<decltype(get<0>(std::declval<QPoint cvref >())), int cvref >); \
+ static_assert(my_is_same_v<decltype(get<1>(std::declval<QPoint cvref >())), int cvref >)
+
+CHECK(&);
+CHECK(const &);
+CHECK(&&);
+CHECK(const &&);
+
+#undef CHECK
+
+#include <QTest>
+#include <QBuffer>
#include <qpoint.h>
+#include <array>
+
class tst_QPoint : public QObject
{
Q_OBJECT
@@ -42,6 +42,11 @@ private slots:
void getSet_data();
void getSet();
+ void transposed();
+
+ void toPointF_data();
+ void toPointF();
+
void rx();
void ry();
@@ -73,6 +78,8 @@ private slots:
void stream_data();
void stream();
#endif
+
+ void structuredBinding();
};
void tst_QPoint::isNull()
@@ -126,6 +133,35 @@ void tst_QPoint::getSet()
QCOMPARE(point.y(), i);
}
+void tst_QPoint::toPointF_data()
+{
+ QTest::addColumn<QPoint>("input");
+ QTest::addColumn<QPointF>("result");
+
+ auto row = [](int x, int y) {
+ QTest::addRow("(%d, %d)", x, y) << QPoint(x, y) << QPointF(x, y);
+ };
+ constexpr std::array samples = {-1, 0, 1};
+ for (int x : samples) {
+ for (int y : samples) {
+ row(x, y);
+ }
+ }
+}
+
+void tst_QPoint::toPointF()
+{
+ QFETCH(const QPoint, input);
+ QFETCH(const QPointF, result);
+
+ QCOMPARE(input.toPointF(), result);
+}
+
+void tst_QPoint::transposed()
+{
+ QCOMPARE(QPoint(1, 2).transposed(), QPoint(2, 1));
+}
+
void tst_QPoint::rx()
{
const QPoint originalPoint(-1, 0);
@@ -339,6 +375,9 @@ void tst_QPoint::operator_eq()
QCOMPARE(equal, expectEqual);
bool notEqual = point1 != point2;
QCOMPARE(notEqual, !expectEqual);
+
+ if (equal)
+ QCOMPARE(qHash(point1), qHash(point2));
}
#ifndef QT_NO_DATASTREAM
@@ -371,5 +410,62 @@ void tst_QPoint::stream()
}
#endif
+void tst_QPoint::structuredBinding()
+{
+ {
+ QPoint p(1, 2);
+ auto [x, y] = p;
+ QCOMPARE(x, 1);
+ QCOMPARE(y, 2);
+
+ p.setX(42);
+ QCOMPARE(x, 1);
+ QCOMPARE(y, 2);
+
+ p.setY(-123);
+ QCOMPARE(x, 1);
+ QCOMPARE(y, 2);
+ }
+ {
+ QPoint p(1, 2);
+
+ auto &[x, y] = p;
+ QCOMPARE(x, 1);
+ QCOMPARE(y, 2);
+
+ x = 42;
+ QCOMPARE(x, 42);
+ QCOMPARE(p.x(), 42);
+ QCOMPARE(p.rx(), 42);
+ QCOMPARE(y, 2);
+ QCOMPARE(p.y(), 2);
+ QCOMPARE(p.ry(), 2);
+
+ y = -123;
+ QCOMPARE(x, 42);
+ QCOMPARE(p.x(), 42);
+ QCOMPARE(p.rx(), 42);
+ QCOMPARE(y, -123);
+ QCOMPARE(p.y(), -123);
+ QCOMPARE(p.ry(), -123);
+
+ p.setX(0);
+ QCOMPARE(x, 0);
+ QCOMPARE(p.x(), 0);
+ QCOMPARE(p.rx(), 0);
+ QCOMPARE(y, -123);
+ QCOMPARE(p.y(), -123);
+ QCOMPARE(p.ry(), -123);
+
+ p.ry() = 10;
+ QCOMPARE(x, 0);
+ QCOMPARE(p.x(), 0);
+ QCOMPARE(p.rx(), 0);
+ QCOMPARE(y, 10);
+ QCOMPARE(p.y(), 10);
+ QCOMPARE(p.ry(), 10);
+ }
+}
+
QTEST_MAIN(tst_QPoint)
#include "tst_qpoint.moc"
diff --git a/tests/auto/corelib/tools/qpointf/CMakeLists.txt b/tests/auto/corelib/tools/qpointf/CMakeLists.txt
new file mode 100644
index 0000000000..16e5a9036a
--- /dev/null
+++ b/tests/auto/corelib/tools/qpointf/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qpointf Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qpointf LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qpointf
+ SOURCES
+ tst_qpointf.cpp
+)
diff --git a/tests/auto/corelib/tools/qpointf/qpointf.pro b/tests/auto/corelib/tools/qpointf/qpointf.pro
deleted file mode 100644
index 5715b95d96..0000000000
--- a/tests/auto/corelib/tools/qpointf/qpointf.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qpointf
-QT = core testlib
-SOURCES = tst_qpointf.cpp
diff --git a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp
index d4ccdf7ba6..392c22c70a 100644
--- a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp
+++ b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp
@@ -1,32 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QPointF>
+#ifdef QVARIANT_H
+# error "This test requires qpoint.h to not include qvariant.h"
+#endif
+
+// don't assume <type_traits>
+template <typename T, typename U>
+constexpr inline bool my_is_same_v = false;
+template <typename T>
+constexpr inline bool my_is_same_v<T, T> = true;
+
+#define CHECK(cvref) \
+ static_assert(my_is_same_v<decltype(get<0>(std::declval<QPointF cvref >())), qreal cvref >); \
+ static_assert(my_is_same_v<decltype(get<1>(std::declval<QPointF cvref >())), qreal cvref >)
+
+CHECK(&);
+CHECK(const &);
+CHECK(&&);
+CHECK(const &&);
+
+#undef CHECK
+
+#include <QTest>
+#include <QBuffer>
#include <qpoint.h>
@@ -46,6 +44,8 @@ private slots:
void getSet_data();
void getSet();
+ void transposed();
+
void rx();
void ry();
@@ -84,6 +84,8 @@ private slots:
void stream();
#endif
+ void structuredBinding();
+
private:
const qreal QREAL_MIN;
const qreal QREAL_MAX;
@@ -154,6 +156,11 @@ void tst_QPointF::getSet()
QCOMPARE(point.y(), r);
}
+void tst_QPointF::transposed()
+{
+ QCOMPARE(QPointF(1, 2).transposed(), QPointF(2, 1));
+}
+
void tst_QPointF::rx()
{
const QPointF originalPoint(-1, 0);
@@ -374,7 +381,7 @@ void tst_QPointF::toPoint_data()
QTest::newRow("(0.0, 0.0) ==> (0, 0)") << QPointF(0, 0) << QPoint(0, 0);
QTest::newRow("(0.5, 0.5) ==> (1, 1)") << QPointF(0.5, 0.5) << QPoint(1, 1);
- QTest::newRow("(-0.5, -0.5) ==> (0, 0)") << QPointF(-0.5, -0.5) << QPoint(0, 0);
+ QTest::newRow("(-0.5, -0.5) ==> (-1, -1)") << QPointF(-0.5, -0.5) << QPoint(-1, -1);
}
void tst_QPointF::toPoint()
@@ -455,5 +462,63 @@ void tst_QPointF::compare()
QVERIFY(QPointF(1.9543e-14, -32.0) == QPointF(0.0, -32.0));
}
+
+void tst_QPointF::structuredBinding()
+{
+ {
+ QPointF p(1.5, 2.25);
+ auto [x, y] = p;
+ QCOMPARE(x, 1.5);
+ QCOMPARE(y, 2.25);
+
+ p.setX(42);
+ QCOMPARE(x, 1.5);
+ QCOMPARE(y, 2.25);
+
+ p.setY(-123);
+ QCOMPARE(x, 1.5);
+ QCOMPARE(y, 2.25);
+ }
+ {
+ QPointF p(1.5, 2.25);
+
+ auto &[x, y] = p;
+ QCOMPARE(x, 1.5);
+ QCOMPARE(y, 2.25);
+
+ x = 42.0;
+ QCOMPARE(x, 42.0);
+ QCOMPARE(p.x(), 42.0);
+ QCOMPARE(p.rx(), 42.0);
+ QCOMPARE(y, 2.25);
+ QCOMPARE(p.y(), 2.25);
+ QCOMPARE(p.ry(), 2.25);
+
+ y = -123.5;
+ QCOMPARE(x, 42.0);
+ QCOMPARE(p.x(), 42.0);
+ QCOMPARE(p.rx(), 42.0);
+ QCOMPARE(y, -123.5);
+ QCOMPARE(p.y(), -123.5);
+ QCOMPARE(p.ry(), -123.5);
+
+ p.setX(0.0);
+ QCOMPARE(x, 0.0);
+ QCOMPARE(p.x(), 0.0);
+ QCOMPARE(p.rx(), 0.0);
+ QCOMPARE(y, -123.5);
+ QCOMPARE(p.y(), -123.5);
+ QCOMPARE(p.ry(), -123.5);
+
+ p.ry() = 10.5;
+ QCOMPARE(x, 0.0);
+ QCOMPARE(p.x(), 0.0);
+ QCOMPARE(p.rx(), 0.0);
+ QCOMPARE(y, 10.5);
+ QCOMPARE(p.y(), 10.5);
+ QCOMPARE(p.ry(), 10.5);
+ }
+}
+
QTEST_MAIN(tst_QPointF)
#include "tst_qpointf.moc"
diff --git a/tests/auto/corelib/tools/qqueue/CMakeLists.txt b/tests/auto/corelib/tools/qqueue/CMakeLists.txt
new file mode 100644
index 0000000000..bf229eee6a
--- /dev/null
+++ b/tests/auto/corelib/tools/qqueue/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qqueue Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qqueue LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qqueue
+ SOURCES
+ tst_qqueue.cpp
+)
diff --git a/tests/auto/corelib/tools/qqueue/qqueue.pro b/tests/auto/corelib/tools/qqueue/qqueue.pro
deleted file mode 100644
index 55ceb65fbd..0000000000
--- a/tests/auto/corelib/tools/qqueue/qqueue.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qqueue
-QT = core testlib
-SOURCES = tst_qqueue.cpp
diff --git a/tests/auto/corelib/tools/qqueue/tst_qqueue.cpp b/tests/auto/corelib/tools/qqueue/tst_qqueue.cpp
index 6c391bd764..44d4c34768 100644
--- a/tests/auto/corelib/tools/qqueue/tst_qqueue.cpp
+++ b/tests/auto/corelib/tools/qqueue/tst_qqueue.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
+#include <QTest>
#include <qqueue.h>
class tst_QQueue : public QObject
diff --git a/tests/auto/corelib/tools/qrect/CMakeLists.txt b/tests/auto/corelib/tools/qrect/CMakeLists.txt
new file mode 100644
index 0000000000..a02e1c33a5
--- /dev/null
+++ b/tests/auto/corelib/tools/qrect/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qrect Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qrect LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qrect
+ SOURCES
+ tst_qrect.cpp
+)
diff --git a/tests/auto/corelib/tools/qrect/qrect.pro b/tests/auto/corelib/tools/qrect/qrect.pro
deleted file mode 100644
index 8ec31db215..0000000000
--- a/tests/auto/corelib/tools/qrect/qrect.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qrect
-QT = core testlib
-SOURCES = tst_qrect.cpp
diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp
index 1c2221ec29..0f3dd1a0ef 100644
--- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp
+++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp
@@ -1,37 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qrect.h>
#include <qmargins.h>
#include <limits.h>
#include <qdebug.h>
+#include <array>
class tst_QRect : public QObject
{
@@ -124,6 +100,9 @@ private slots:
void margins();
void marginsf();
+ void toRectF_data();
+ void toRectF();
+
void translate_data();
void translate();
@@ -164,14 +143,17 @@ private slots:
void intersectsRectF();
void containsRect_data();
void containsRect();
+ void containsRectNormalized();
void containsRectF_data();
void containsRectF();
void containsPoint_data();
void containsPoint();
+ void containsPointNormalized();
void containsPointF_data();
void containsPointF();
void smallRects() const;
void toRect();
+ void span();
};
// Used to work around some floating point precision problems.
@@ -372,17 +354,20 @@ void tst_QRect::normalized_data()
QTest::newRow( "LargestCoordQRect" ) << getQRectCase( LargestCoordQRect )
<< getQRectCase( LargestCoordQRect ); // overflow
QTest::newRow( "RandomQRect" ) << getQRectCase( RandomQRect ) << QRect( 100, 200, 11, 16 );
- QTest::newRow( "NegativeSizeQRect" ) << getQRectCase( NegativeSizeQRect ) << QRect(QPoint(-10,-10),QPoint(1,1));
+ QTest::newRow( "NegativeSizeQRect" ) << getQRectCase( NegativeSizeQRect ) << QRect(-9, -9, 10, 10);
QTest::newRow( "NegativePointQRect" ) << getQRectCase( NegativePointQRect ) << QRect( -10, -10, 5, 5 );
QTest::newRow( "NullQRect" ) << getQRectCase( NullQRect ) << getQRectCase( NullQRect );
QTest::newRow( "EmptyQRect" ) << getQRectCase( EmptyQRect ) << getQRectCase( EmptyQRect );
QTest::newRow( "ZeroWidth" ) << QRect(100, 200, 100, 0) << QRect(100, 200, 100, 0);
+ QTest::newRow( "ZeroHeight" ) << QRect(100, 200, 0, 100) << QRect(100, 200, 0, 100);
// Since "NegativeSizeQRect passes, I expect both of these to pass too.
// This passes, since height() returns -1 before normalization
- QTest::newRow( "NegativeHeight") << QRect(QPoint(100,201), QPoint(199,199)) << QRect(QPoint(100,199), QPoint(199,201));
+ QTest::newRow( "NegativeWidth") << QRect(QPoint(200,100), QSize(-1,100)) << QRect(QPoint(199,100), QSize(1,100));
+ QTest::newRow( "NegativeHeight") << QRect(QPoint(100,200), QSize(100,-1)) << QRect(QPoint(100,199), QSize(100,1));
+ QTest::newRow( "NegativeWidth2") << QRect(QPoint(200,100), QPoint(198,199)) << QRect(QPoint(199,100), QPoint(199,199));
// This, on the other hand height() returns 0 before normalization.
- QTest::newRow( "ZeroHeight1" ) << QRect(QPoint(100,200), QPoint(199,199)) << QRect(QPoint(100,199), QPoint(199,200));
- QTest::newRow( "ZeroHeight2" ) << QRect(QPoint(263,113), QPoint(136,112)) << QRect(QPoint(136,113), QPoint(263,112));
+ QTest::newRow( "ZeroHeight1" ) << QRect(QPoint(100,200), QPoint(199,199)) << QRect(QPoint(100,200), QPoint(199,199));
+ QTest::newRow( "ZeroHeight2" ) << QRect(QPoint(263,113), QPoint(136,112)) << QRect(QPoint(137,113), QPoint(262,112));
}
void tst_QRect::normalized()
@@ -390,7 +375,6 @@ void tst_QRect::normalized()
QFETCH(QRect, r);
QFETCH(QRect, nr);
- QEXPECT_FAIL("ZeroHeight1", "due to broken QRect definition (not possible to change, see QTBUG-22934)", Continue);
QCOMPARE(r.normalized(), nr);
}
@@ -478,6 +462,9 @@ void tst_QRect::right()
if (isLarge(r.width()))
return;
+ // width overflow
+ if (r.left() < r.right() && r.width() < 0)
+ return;
QCOMPARE(QRectF(r).right(), qreal(right+1));
}
@@ -510,6 +497,9 @@ void tst_QRect::bottom()
if (isLarge(r.height()))
return;
+ // height overflow
+ if (r.top() < r.bottom() && r.height() < 0)
+ return;
QCOMPARE(QRectF(r).bottom(), qreal(bottom + 1));
}
@@ -2515,16 +2505,11 @@ void tst_QRect::newMoveLeft_data()
{
// QTest::newRow( "LargestCoordQRect_MinimumInt" ) -- Not tested as it would cause an overflow
- QTest::newRow( "LargestCoordQRect_MiddleNegativeInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( MiddleNegativeInt )
- << QRect( QPoint( INT_MIN/2, INT_MIN ), QPoint(INT_MIN/2-1, INT_MAX ) );
- QTest::newRow( "LargestCoordQRect_ZeroInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( ZeroInt )
- << QRect( QPoint( 0, INT_MIN ), QPoint(-1, INT_MAX ) );
- QTest::newRow( "LargestCoordQRect_MiddlePositiveInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( MiddlePositiveInt )
- << QRect( QPoint( INT_MAX/2, INT_MIN ), QPoint(INT_MAX/2-1, INT_MAX ) );
- QTest::newRow( "LargestCoordQRect_MaximumInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( MaximumInt )
- << QRect( QPoint( INT_MAX, INT_MIN ), QPoint(INT_MAX-1, INT_MAX ) );
- QTest::newRow( "LargestCoordQRect_RandomInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( RandomInt )
- << QRect( QPoint( 4953, INT_MIN ), QPoint(4952, INT_MAX ) );
+ // QTest::newRow( "LargestCoordQRect_MiddleNegativeInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_ZeroInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_MiddlePositiveInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_MaximumInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_RandomInt" ) -- Not tested as it would cause an overflow
}
{
@@ -2684,16 +2669,11 @@ void tst_QRect::newMoveTop_data()
{
// QTest::newRow( "LargestCoordQRect_MinimumInt" ) -- Not tested as it would cause an overflow
- QTest::newRow( "LargestCoordQRect_MiddleNegativeInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( MiddleNegativeInt )
- << QRect( QPoint(INT_MIN,INT_MIN/2), QPoint(INT_MAX,INT_MIN/2-1) );
- QTest::newRow( "LargestCoordQRect_ZeroInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( ZeroInt )
- << QRect( QPoint(INT_MIN,0), QPoint(INT_MAX,-1) );
- QTest::newRow( "LargestCoordQRect_MiddlePositiveInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( MiddlePositiveInt )
- << QRect( QPoint(INT_MIN,INT_MAX/2), QPoint(INT_MAX,INT_MAX/2-1) );
- QTest::newRow( "LargestCoordQRect_MaximumInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( MaximumInt )
- << QRect( QPoint(INT_MIN,INT_MAX), QPoint(INT_MAX,INT_MAX-1) );
- QTest::newRow( "LargestCoordQRect_RandomInt" ) << getQRectCase( LargestCoordQRect ) << getIntCase( RandomInt )
- << QRect( QPoint(INT_MIN,4953), QPoint(INT_MAX,4952) );
+ // QTest::newRow( "LargestCoordQRect_MiddleNegativeInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_ZeroInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_MiddlePositiveInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_MaximumInt" ) -- Not tested as it would cause an overflow
+ // QTest::newRow( "LargestCoordQRect_RandomInt" ) -- Not tested as it would cause an overflow
}
{
@@ -3525,6 +3505,39 @@ void tst_QRect::marginsf()
QCOMPARE(a, rectangle.marginsRemoved(margins));
}
+void tst_QRect::toRectF_data()
+{
+ QTest::addColumn<QRect>("input");
+ QTest::addColumn<QRectF>("result");
+
+ auto row = [](int x1, int y1, int w, int h) {
+ // QRectF -> QRect conversion tries to maintain size(), not bottomRight(),
+ // so compare in (topLeft(), size()) space
+ QTest::addRow("((%d, %d) (%dx%d))", x1, y1, w, h)
+ << QRect({x1, y1}, QSize{w, h}) << QRectF(QPointF(x1, y1), QSizeF(w, h));
+ };
+ constexpr std::array samples = {-1, 0, 1};
+ for (int x1 : samples) {
+ for (int y1 : samples) {
+ for (int w : samples) {
+ for (int h : samples) {
+ row(x1, y1, w, h);
+ }
+ }
+ }
+ }
+}
+
+void tst_QRect::toRectF()
+{
+ QFETCH(const QRect, input);
+ QFETCH(const QRectF, result);
+
+ QCOMPARE(result.toRect(), input); // consistency check
+ QCOMPARE(input.toRectF(), result);
+}
+
+
void tst_QRect::translate_data()
{
QTest::addColumn<QRect>("r");
@@ -3931,15 +3944,15 @@ void tst_QRect::intersectedRect_data()
QTest::newRow("test 03") << QRect(0, 0, 10, 10) << QRect( 2, 2, 10, 10) << QRect(2, 2, 8, 8);
QTest::newRow("test 04") << QRect(0, 0, 10, 10) << QRect(20, 20, 10, 10) << QRect();
- QTest::newRow("test 05") << QRect(9, 9, -8, -8) << QRect( 2, 2, 6, 6) << QRect(2, 2, 6, 6);
- QTest::newRow("test 06") << QRect(9, 9, -8, -8) << QRect( 0, 0, 10, 10) << QRect(0, 0, 10, 10);
- QTest::newRow("test 07") << QRect(9, 9, -8, -8) << QRect( 2, 2, 10, 10) << QRect(2, 2, 8, 8);
- QTest::newRow("test 08") << QRect(9, 9, -8, -8) << QRect(20, 20, 10, 10) << QRect();
+ QTest::newRow("test 05") << QRect(10, 10, -10, -10) << QRect( 2, 2, 6, 6) << QRect(2, 2, 6, 6);
+ QTest::newRow("test 06") << QRect(10, 10, -10, -10) << QRect( 0, 0, 10, 10) << QRect(0, 0, 10, 10);
+ QTest::newRow("test 07") << QRect(10, 10, -10, -10) << QRect( 2, 2, 10, 10) << QRect(2, 2, 8, 8);
+ QTest::newRow("test 08") << QRect(10, 10, -10, -10) << QRect(20, 20, 10, 10) << QRect();
- QTest::newRow("test 09") << QRect(0, 0, 10, 10) << QRect( 7, 7, -4, -4) << QRect(2, 2, 6, 6);
- QTest::newRow("test 10") << QRect(0, 0, 10, 10) << QRect( 9, 9, -8, -8) << QRect(0, 0, 10, 10);
- QTest::newRow("test 11") << QRect(0, 0, 10, 10) << QRect(11, 11, -8, -8) << QRect(2, 2, 8, 8);
- QTest::newRow("test 12") << QRect(0, 0, 10, 10) << QRect(29, 29, -8, -8) << QRect();
+ QTest::newRow("test 09") << QRect(0, 0, 10, 10) << QRect( 6, 6, -4, -4) << QRect(2, 2, 4, 4);
+ QTest::newRow("test 10") << QRect(0, 0, 10, 10) << QRect(10, 10, -10, -10) << QRect(0, 0, 10, 10);
+ QTest::newRow("test 11") << QRect(0, 0, 10, 10) << QRect(12, 12, -10, -10) << QRect(2, 2, 8, 8);
+ QTest::newRow("test 12") << QRect(0, 0, 10, 10) << QRect(30, 30, -10, -10) << QRect();
QTest::newRow("test 13") << QRect(0, 0, 10, 10) << QRect() << QRect();
QTest::newRow("test 14") << QRect() << QRect(0, 0, 10, 10) << QRect();
@@ -4016,15 +4029,15 @@ void tst_QRect::unitedRect_data()
QTest::newRow("test 03") << QRect(0, 0, 10, 10) << QRect( 2, 2, 10, 10) << QRect(0, 0, 12, 12);
QTest::newRow("test 04") << QRect(0, 0, 10, 10) << QRect(20, 20, 10, 10) << QRect(0, 0, 30, 30);
- QTest::newRow("test 05") << QRect(9, 9, -8, -8) << QRect( 2, 2, 6, 6) << QRect(0, 0, 10, 10);
- QTest::newRow("test 06") << QRect(9, 9, -8, -8) << QRect( 0, 0, 10, 10) << QRect(0, 0, 10, 10);
- QTest::newRow("test 07") << QRect(9, 9, -8, -8) << QRect( 2, 2, 10, 10) << QRect(0, 0, 12, 12);
- QTest::newRow("test 08") << QRect(9, 9, -8, -8) << QRect(20, 20, 10, 10) << QRect(0, 0, 30, 30);
+ QTest::newRow("test 05") << QRect(10, 10, -10, -10) << QRect( 2, 2, 6, 6) << QRect(0, 0, 10, 10);
+ QTest::newRow("test 06") << QRect(10, 10, -10, -10) << QRect( 0, 0, 10, 10) << QRect(0, 0, 10, 10);
+ QTest::newRow("test 07") << QRect(10, 10, -10, -10) << QRect( 2, 2, 10, 10) << QRect(0, 0, 12, 12);
+ QTest::newRow("test 08") << QRect(10, 10, -10, -10) << QRect(20, 20, 10, 10) << QRect(0, 0, 30, 30);
QTest::newRow("test 09") << QRect(0, 0, 10, 10) << QRect( 7, 7, -4, -4) << QRect(0, 0, 10, 10);
QTest::newRow("test 10") << QRect(0, 0, 10, 10) << QRect( 9, 9, -8, -8) << QRect(0, 0, 10, 10);
- QTest::newRow("test 11") << QRect(0, 0, 10, 10) << QRect(11, 11, -8, -8) << QRect(0, 0, 12, 12);
- QTest::newRow("test 12") << QRect(0, 0, 10, 10) << QRect(29, 29, -8, -8) << QRect(0, 0, 30, 30);
+ QTest::newRow("test 11") << QRect(0, 0, 10, 10) << QRect(12, 12, -8, -8) << QRect(0, 0, 12, 12);
+ QTest::newRow("test 12") << QRect(0, 0, 10, 10) << QRect(30, 30, -8, -8) << QRect(0, 0, 30, 30);
QTest::newRow("test 13") << QRect() << QRect(10, 10, 10, 10) << QRect(10, 10, 10, 10);
QTest::newRow("test 14") << QRect(10, 10, 10, 10) << QRect() << QRect(10, 10, 10, 10);
@@ -4166,10 +4179,10 @@ void tst_QRect::containsRect_data()
QTest::newRow("test 03") << QRect(0, 0, 10, 10) << QRect( 2, 2, 10, 10) << false;
QTest::newRow("test 04") << QRect(0, 0, 10, 10) << QRect(20, 20, 10, 10) << false;
- QTest::newRow("test 05") << QRect(9, 9, -8, -8) << QRect( 2, 2, 6, 6) << true;
- QTest::newRow("test 06") << QRect(9, 9, -8, -8) << QRect( 0, 0, 10, 10) << true;
- QTest::newRow("test 07") << QRect(9, 9, -8, -8) << QRect( 2, 2, 10, 10) << false;
- QTest::newRow("test 08") << QRect(9, 9, -8, -8) << QRect(20, 20, 10, 10) << false;
+ QTest::newRow("test 05") << QRect(9, 9, -9, -9) << QRect( 2, 2, 6, 6) << true;
+ QTest::newRow("test 06") << QRect(9, 9, -9, -9) << QRect( 0, 0, 9, 9) << true;
+ QTest::newRow("test 07") << QRect(9, 9, -9, -9) << QRect( 2, 2, 9, 9) << false;
+ QTest::newRow("test 08") << QRect(9, 9, -9, -9) << QRect(20, 20, 10, 10) << false;
QTest::newRow("test 09") << QRect(0, 0, 10, 10) << QRect( 7, 7, -4, -4) << true;
QTest::newRow("test 10") << QRect(0, 0, 10, 10) << QRect( 9, 9, -8, -8) << true;
@@ -4190,6 +4203,18 @@ void tst_QRect::containsRect()
QVERIFY(rect1.contains(rect2) == contains);
}
+void tst_QRect::containsRectNormalized()
+{
+ QRect rect(QPoint(10, 10), QPoint(0,0));
+ QRect normalized = rect.normalized();
+ for (int i = -2 ; i < 12; ++i) {
+ for (int j = -2 ; j < 12; ++j) {
+ for (int k = -2 ; k <= 2; ++k)
+ QCOMPARE(rect.contains(QRect(i,j,k,k)), normalized.contains(QRect(i,j,k,k)));
+ }
+ }
+}
+
void tst_QRect::containsRectF_data()
{
QTest::addColumn<QRectF>("rect1");
@@ -4245,18 +4270,18 @@ void tst_QRect::containsPoint_data()
QTest::newRow("test 11") << QRect(0, 0, 10, 10) << QPoint( 1, 8) << true << true;
QTest::newRow("test 12") << QRect(0, 0, 10, 10) << QPoint( 8, 8) << true << true;
- QTest::newRow("test 13") << QRect(9, 9, -8, -8) << QPoint( 0, 0) << true << false;
- QTest::newRow("test 14") << QRect(9, 9, -8, -8) << QPoint( 0, 10) << false << false;
- QTest::newRow("test 15") << QRect(9, 9, -8, -8) << QPoint(10, 0) << false << false;
- QTest::newRow("test 16") << QRect(9, 9, -8, -8) << QPoint(10, 10) << false << false;
- QTest::newRow("test 17") << QRect(9, 9, -8, -8) << QPoint( 0, 9) << true << false;
- QTest::newRow("test 18") << QRect(9, 9, -8, -8) << QPoint( 9, 0) << true << false;
- QTest::newRow("test 19") << QRect(9, 9, -8, -8) << QPoint( 9, 9) << true << false;
- QTest::newRow("test 20") << QRect(9, 9, -8, -8) << QPoint( 1, 0) << true << false;
- QTest::newRow("test 21") << QRect(9, 9, -8, -8) << QPoint( 9, 1) << true << false;
- QTest::newRow("test 22") << QRect(9, 9, -8, -8) << QPoint( 1, 1) << true << true;
- QTest::newRow("test 23") << QRect(9, 9, -8, -8) << QPoint( 1, 8) << true << true;
- QTest::newRow("test 24") << QRect(9, 9, -8, -8) << QPoint( 8, 8) << true << true;
+ QTest::newRow("test 13") << QRect(9, 9, -9, -9) << QPoint( 0, 0) << true << false;
+ QTest::newRow("test 14") << QRect(9, 9, -9, -9) << QPoint( 0, 9) << false << false;
+ QTest::newRow("test 15") << QRect(9, 9, -9, -9) << QPoint( 9, 0) << false << false;
+ QTest::newRow("test 16") << QRect(9, 9, -9, -9) << QPoint( 9, 9) << false << false;
+ QTest::newRow("test 17") << QRect(9, 9, -9, -9) << QPoint( 0, 8) << true << false;
+ QTest::newRow("test 18") << QRect(9, 9, -9, -9) << QPoint( 8, 0) << true << false;
+ QTest::newRow("test 19") << QRect(9, 9, -9, -9) << QPoint( 8, 8) << true << false;
+ QTest::newRow("test 20") << QRect(9, 9, -9, -9) << QPoint( 1, 0) << true << false;
+ QTest::newRow("test 21") << QRect(9, 9, -9, -9) << QPoint( 8, 1) << true << false;
+ QTest::newRow("test 22") << QRect(9, 9, -9, -9) << QPoint( 1, 1) << true << true;
+ QTest::newRow("test 23") << QRect(9, 9, -9, -9) << QPoint( 1, 7) << true << true;
+ QTest::newRow("test 24") << QRect(9, 9, -9, -9) << QPoint( 7, 7) << true << true;
QTest::newRow("test 25") << QRect(-1, 1, 10, 10) << QPoint() << false << false;
QTest::newRow("test 26") << QRect() << QPoint(1, 1) << false << false;
@@ -4274,14 +4299,22 @@ void tst_QRect::containsPoint()
QVERIFY(rect.contains(point, true) == containsProper);
}
+void tst_QRect::containsPointNormalized()
+{
+ QRect rect(QPoint(10, 10), QPoint(0,0));
+ QRect normalized = rect.normalized();
+ for (int i = 0 ; i < 10; ++i) {
+ for (int j = 0 ; j < 10; ++j)
+ QCOMPARE(rect.contains(QPoint(i,j)), normalized.contains(QPoint(i,j)));
+ }
+}
+
void tst_QRect::containsPointF_data()
{
QTest::addColumn<QRectF>("rect");
QTest::addColumn<QPointF>("point");
QTest::addColumn<bool>("contains");
- QTest::newRow("test 27") << QRectF() << QPointF() << false;
-
QTest::newRow("test 01") << QRectF(0, 0, 10, 10) << QPointF( 0, 0) << true;
QTest::newRow("test 02") << QRectF(0, 0, 10, 10) << QPointF( 0, 10) << true;
QTest::newRow("test 03") << QRectF(0, 0, 10, 10) << QPointF(10, 0) << true;
@@ -4340,12 +4373,12 @@ void tst_QRect::toRect()
for (qreal h = 1.0; h < 2.0; h += 0.25) {
const QRectF rectf(x, y, w, h);
const QRectF rect = rectf.toRect();
- QVERIFY(qAbs(rect.x() - rectf.x()) < 1.0);
- QVERIFY(qAbs(rect.y() - rectf.y()) < 1.0);
- QVERIFY(qAbs(rect.width() - rectf.width()) < 1.0);
- QVERIFY(qAbs(rect.height() - rectf.height()) < 1.0);
- QVERIFY(qAbs(rect.right() - rectf.right()) < 1.0);
- QVERIFY(qAbs(rect.bottom() - rectf.bottom()) < 1.0);
+ QVERIFY(qAbs(rect.x() - rectf.x()) <= 0.75);
+ QVERIFY(qAbs(rect.y() - rectf.y()) <= 0.75);
+ QVERIFY(qAbs(rect.width() - rectf.width()) <= 0.75);
+ QVERIFY(qAbs(rect.height() - rectf.height()) <= 0.75);
+ QVERIFY(qAbs(rect.right() - rectf.right()) <= 0.75);
+ QVERIFY(qAbs(rect.bottom() - rectf.bottom()) <= 0.75);
const QRectF arect = rectf.toAlignedRect();
QVERIFY(qAbs(arect.x() - rectf.x()) < 1.0);
@@ -4363,5 +4396,16 @@ void tst_QRect::toRect()
}
}
+void tst_QRect::span()
+{
+ QCOMPARE(QRect::span(QPoint( 0, 1), QPoint(9, 10)), QRect(QPoint(0, 1), QPoint( 9, 10)));
+
+ QCOMPARE(QRect::span(QPoint(10, 9), QPoint(1, 0)), QRect(QPoint(1, 0), QPoint(10, 9)));
+
+ QCOMPARE(QRect::span(QPoint(10, 1), QPoint(0, 9)), QRect(QPoint(0, 1), QPoint(10, 9)));
+
+ QCOMPARE(QRect::span(QPoint( 1, 10), QPoint(9, 0)), QRect(QPoint(1, 0), QPoint( 9, 10)));
+}
+
QTEST_MAIN(tst_QRect)
#include "tst_qrect.moc"
diff --git a/tests/auto/corelib/tools/qregexp/.gitignore b/tests/auto/corelib/tools/qregexp/.gitignore
deleted file mode 100644
index e6e629ee2c..0000000000
--- a/tests/auto/corelib/tools/qregexp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qregexp
diff --git a/tests/auto/corelib/tools/qregexp/qregexp.pro b/tests/auto/corelib/tools/qregexp/qregexp.pro
deleted file mode 100644
index 5f6ff0a71c..0000000000
--- a/tests/auto/corelib/tools/qregexp/qregexp.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qregexp
-QT = core testlib
-SOURCES = tst_qregexp.cpp
diff --git a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp b/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp
deleted file mode 100644
index a8111af6c1..0000000000
--- a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp
+++ /dev/null
@@ -1,1386 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qregexp.h>
-
-const int N = 1;
-
-class tst_QRegExp : public QObject
-{
- Q_OBJECT
-private slots:
- void getSetCheck();
- void indexIn_data();
- void indexIn_addMoreRows(const QByteArray &stri);
- void indexIn();
- void lastIndexIn_data();
- void lastIndexIn();
- void matchedLength();
- void wildcard_data();
- void wildcard();
- void testEscapingWildcard_data();
- void testEscapingWildcard();
- void testInvalidWildcard_data();
- void testInvalidWildcard();
- void caretAnchoredOptimization();
- void isEmpty();
- void prepareEngineOptimization();
- void swap();
- void operator_eq();
-
- void exactMatch();
- void capturedTexts();
- void staticRegExp();
- void rainersSlowRegExpCopyBug();
- void nonExistingBackReferenceBug();
-
- void reentrancy();
- void threadsafeEngineCache();
-
- void posAndCapConsistency_data();
- void posAndCapConsistency();
- void interval();
- void validityCheck_data();
- void validityCheck();
- void escapeSequences();
-};
-
-// Testing get/set functions
-void tst_QRegExp::getSetCheck()
-{
- QRegExp obj1;
- // PatternSyntax QRegExp::patternSyntax()
- // void QRegExp::setPatternSyntax(PatternSyntax)
- obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::RegExp));
- QCOMPARE(QRegExp::PatternSyntax(QRegExp::RegExp), obj1.patternSyntax());
- obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::Wildcard));
- QCOMPARE(QRegExp::PatternSyntax(QRegExp::Wildcard), obj1.patternSyntax());
- obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::FixedString));
- QCOMPARE(QRegExp::PatternSyntax(QRegExp::FixedString), obj1.patternSyntax());
-}
-
-extern const char email[];
-
-void tst_QRegExp::lastIndexIn_data()
-{
- indexIn_data();
-}
-
-void tst_QRegExp::indexIn_data()
-{
- QTest::addColumn<QString>("regexpStr");
- QTest::addColumn<QString>("target");
- QTest::addColumn<int>("pos");
- QTest::addColumn<int>("len");
- QTest::addColumn<QStringList>("caps");
-
- for (int i = 0; i < N; ++i) {
- QByteArray stri;
- if (i > 0)
- stri.setNum(i);
-
- // anchors
- QTest::newRow(qPrintable(stri + "anc00")) << QString("a(?=)z") << QString("az") << 0 << 2 << QStringList();
- QTest::newRow(qPrintable(stri + "anc01")) << QString("a(?!)z") << QString("az") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "anc02")) << QString("a(?:(?=)|(?=))z") << QString("az") << 0 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc03")) << QString("a(?:(?=)|(?!))z") << QString("az") << 0 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc04")) << QString("a(?:(?!)|(?=))z") << QString("az") << 0 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc05")) << QString("a(?:(?!)|(?!))z") << QString("az") << -1 << -1
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc06")) << QString("a(?:(?=)|b)z") << QString("az") << 0 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc07")) << QString("a(?:(?=)|b)z") << QString("abz") << 0 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc08")) << QString("a(?:(?!)|b)z") << QString("az") << -1 << -1
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc09")) << QString("a(?:(?!)|b)z") << QString("abz") << 0 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc10")) << QString("a?(?=^b$)") << QString("ab") << -1 << -1
- << QStringList();
- QTest::newRow(qPrintable(stri + "anc11")) << QString("a?(?=^b$)") << QString("b") << 0 << 0
- << QStringList();
-
- // back-references
- QTest::newRow(qPrintable(stri + "bref00")) << QString("(a*)(\\1)") << QString("aaaaa") << 0 << 4
- << QStringList( QStringList() << "aa" << "aa" );
- QTest::newRow(qPrintable(stri + "bref01")) << QString("<(\\w*)>.+</\\1>") << QString("<b>blabla</b>bla</>")
- << 0 << 13 << QStringList( QStringList() << "b" );
- QTest::newRow(qPrintable(stri + "bref02")) << QString("<(\\w*)>.+</\\1>") << QString("<>blabla</b>bla</>")
- << 0 << 18 << QStringList( QStringList() << "" );
- QTest::newRow(qPrintable(stri + "bref03")) << QString("((a*\\2)\\2)") << QString("aaaa") << 0 << 4
- << QStringList( QStringList() << QString("aaaa") << "aa" );
- QTest::newRow(qPrintable(stri + "bref04")) << QString("^(aa+)\\1+$") << QString("aaaaaa") << 0 << 6
- << QStringList( QStringList() << QString("aa") );
- QTest::newRow(qPrintable(stri + "bref05")) << QString("^(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)"
- "\\14\\13\\12\\11\\10\\9\\8\\7\\6\\5\\4\\3\\2\\1")
- << QString("12345678910111213141413121110987654321") << 0 << 38
- << QStringList( QStringList() << "1" << "2" << "3" << "4" << "5" << "6"
- << "7" << "8" << "9" << "10" << "11"
- << "12" << "13" << "14");
-
- // captures
- QTest::newRow(qPrintable(stri + "cap00")) << QString("(a*)") << QString("") << 0 << 0
- << QStringList( QStringList() << QString("") );
- QTest::newRow(qPrintable(stri + "cap01")) << QString("(a*)") << QString("aaa") << 0 << 3
- << QStringList( QStringList() << "aaa" );
- QTest::newRow(qPrintable(stri + "cap02")) << QString("(a*)") << QString("baaa") << 0 << 0
- << QStringList( QStringList() << QString("") );
- QTest::newRow(qPrintable(stri + "cap03")) << QString("(a*)(a*)") << QString("aaa") << 0 << 3
- << QStringList( QStringList() << QString("aaa") << QString("") );
- QTest::newRow(qPrintable(stri + "cap04")) << QString("(a*)(b*)") << QString("aaabbb") << 0 << 6
- << QStringList( QStringList() << QString("aaa") << QString("bbb") );
- QTest::newRow(qPrintable(stri + "cap06")) << QString("(a*)a*") << QString("aaa") << 0 << 3
- << QStringList( QStringList() << QString("aaa") );
- QTest::newRow(qPrintable(stri + "cap07")) << QString("((a*a*)*)") << QString("aaa") << 0 << 3
- << QStringList( QStringList() << "aaa" << QString("aaa") );
- QTest::newRow(qPrintable(stri + "cap08")) << QString("(((a)*(b)*)*)") << QString("ababa") << 0 << 5
- << QStringList( QStringList() << QString("ababa") << QString("a") << QString("a")
- << "" );
- QTest::newRow(qPrintable(stri + "cap09")) << QString("(((a)*(b)*)c)*") << QString("") << 0 << 0
- << QStringList( QStringList() << QString("") << QString("") << QString("") << QString("") );
- QTest::newRow(qPrintable(stri + "cap10")) << QString("(((a)*(b)*)c)*") << QString("abc") << 0 << 3
- << QStringList( QStringList() << "abc" << "ab" << "a"
- << "b" );
- QTest::newRow(qPrintable(stri + "cap11")) << QString("(((a)*(b)*)c)*") << QString("abcc") << 0 << 4
- << QStringList( QStringList() << "c" << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "cap12")) << QString("(((a)*(b)*)c)*") << QString("abcac") << 0 << 5
- << QStringList( QStringList() << "ac" << "a" << "a" << "" );
- QTest::newRow(qPrintable(stri + "cap13")) << QString("(to|top)?(o|polo)?(gical|o?logical)")
- << QString("topological") << 0 << 11
- << QStringList( QStringList() << "top" << "o"
- << "logical" );
- QTest::newRow(qPrintable(stri + "cap14")) << QString("(a)+") << QString("aaaa") << 0 << 4
- << QStringList( QStringList() << "a" );
-
- // concatenation
- QTest::newRow(qPrintable(stri + "cat00")) << QString("") << QString("") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "cat01")) << QString("") << QString("a") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "cat02")) << QString("a") << QString("") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "cat03")) << QString("a") << QString("a") << 0 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "cat04")) << QString("a") << QString("b") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "cat05")) << QString("b") << QString("a") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "cat06")) << QString("ab") << QString("ab") << 0 << 2 << QStringList();
- QTest::newRow(qPrintable(stri + "cat07")) << QString("ab") << QString("ba") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "cat08")) << QString("abab") << QString("abbaababab") << 4 << 4 << QStringList();
-
- indexIn_addMoreRows(stri);
- }
-}
-
-void tst_QRegExp::indexIn_addMoreRows(const QByteArray &stri)
-{
- // from Perl Cookbook
- QTest::newRow(qPrintable(stri + "cook00")) << QString("^(m*)(d?c{0,3}|c[dm])(1?x{0,3}|x[lc])(v?i{0,3}|i[vx])$")
- << QString("mmxl") << 0 << 4
- << QStringList( QStringList() << "mm" << "" << "xl"
- << "" );
- QTest::newRow(qPrintable(stri + "cook01")) << QString("(\\S+)(\\s+)(\\S+)") << QString(" a b") << 1 << 5
- << QStringList( QStringList() << "a" << " " << "b" );
- QTest::newRow(qPrintable(stri + "cook02")) << QString("(\\w+)\\s*=\\s*(.*)\\s*$") << QString(" PATH=. ") << 1
- << 7 << QStringList( QStringList() << "PATH" << ". " );
- QTest::newRow(qPrintable(stri + "cook03")) << QString(".{80,}")
- << QString("0000000011111111222222223333333344444444555"
- "5555566666666777777778888888899999999000000"
- "00aaaaaaaa")
- << 0 << 96 << QStringList();
- QTest::newRow(qPrintable(stri + "cook04")) << QString("(\\d+)/(\\d+)/(\\d+) (\\d+):(\\d+):(\\d+)")
- << QString("1978/05/24 07:30:00") << 0 << 19
- << QStringList( QStringList() << "1978" << "05" << "24"
- << "07" << "30" << "00" );
- QTest::newRow(qPrintable(stri + "cook05")) << QString("/usr/bin") << QString("/usr/local/bin:/usr/bin")
- << 15 << 8 << QStringList();
- QTest::newRow(qPrintable(stri + "cook06")) << QString("%([0-9A-Fa-f]{2})") << QString("http://%7f") << 7 << 3
- << QStringList( QStringList() << "7f" );
- QTest::newRow(qPrintable(stri + "cook07")) << QString("/\\*.*\\*/") << QString("i++; /* increment i */") << 5
- << 17 << QStringList();
- QTest::newRow(qPrintable(stri + "cook08")) << QString("^\\s+") << QString(" aaa ") << 0 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "cook09")) << QString("\\s+$") << QString(" aaa ") << 6 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "cook10")) << QString("^.*::") << QString("Box::cat") << 0 << 5
- << QStringList();
- QTest::newRow(qPrintable(stri + "cook11")) << QString("^([01]?\\d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\"
- "d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-"
- "4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-4]\\d|25["
- "0-5])$")
- << QString("255.00.40.30") << 0 << 12
- << QStringList( QStringList() << "255" << "00" << "40"
- << "30" );
- QTest::newRow(qPrintable(stri + "cook12")) << QString("^.*/") << QString(" /usr/local/bin/moc") << 0 << 16
- << QStringList();
- QTest::newRow(qPrintable(stri + "cook13")) << QString(":co#(\\d+):") << QString("bla:co#55:") << 3 << 7
- << QStringList( QStringList() << "55" );
- QTest::newRow(qPrintable(stri + "cook14")) << QString("linux") << QString("alphalinuxinunix") << 5 << 5
- << QStringList();
- QTest::newRow(qPrintable(stri + "cook15")) << QString("(\\d+\\.?\\d*|\\.\\d+)") << QString("0.0.5") << 0 << 3
- << QStringList( QStringList() << "0.0" );
-
- // mathematical trivia
- QTest::newRow(qPrintable(stri + "math00")) << QString("^(a\\1*)$") << QString("a") << 0 << 1
- << QStringList( QStringList() << "a" );
- QTest::newRow(qPrintable(stri + "math01")) << QString("^(a\\1*)$") << QString("aa") << 0 << 2
- << QStringList( QStringList() << "aa" );
- QTest::newRow(qPrintable(stri + "math02")) << QString("^(a\\1*)$") << QString("aaa") << -1 << -1
- << QStringList( QStringList() << QString() );
- QTest::newRow(qPrintable(stri + "math03")) << QString("^(a\\1*)$") << QString("aaaa") << 0 << 4
- << QStringList( QStringList() << "aaaa" );
- QTest::newRow(qPrintable(stri + "math04")) << QString("^(a\\1*)$") << QString("aaaaa") << -1 << -1
- << QStringList( QStringList() << QString() );
- QTest::newRow(qPrintable(stri + "math05")) << QString("^(a\\1*)$") << QString("aaaaaa") << -1 << -1
- << QStringList( QStringList() << QString() );
- QTest::newRow(qPrintable(stri + "math06")) << QString("^(a\\1*)$") << QString("aaaaaaa") << -1 << -1
- << QStringList( QStringList() << QString() );
- QTest::newRow(qPrintable(stri + "math07")) << QString("^(a\\1*)$") << QString("aaaaaaaa") << 0 << 8
- << QStringList( QStringList() << "aaaaaaaa" );
- QTest::newRow(qPrintable(stri + "math08")) << QString("^(a\\1*)$") << QString("aaaaaaaaa") << -1 << -1
- << QStringList( QStringList() << QString() );
- QTest::newRow(qPrintable(stri + "math09")) << QString("^a(?:a(\\1a))*$") << QString("a") << 0 << 1
- << QStringList( QStringList() << "" );
- QTest::newRow(qPrintable(stri + "math10")) << QString("^a(?:a(\\1a))*$") << QString("aaa") << 0 << 3
- << QStringList( QStringList() << "a" );
-
- QTest::newRow(qPrintable(stri + "math13")) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
- "?=a$)))*a$")
- << QString("aaa") << 0 << 3
- << QStringList( QStringList() << "a" << "a" << "" );
- QTest::newRow(qPrintable(stri + "math14")) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
- "?=a$)))*a$")
- << QString("aaaaa") << 0 << 5
- << QStringList( QStringList() << "a" << "a" << "aa" );
- QTest::newRow(qPrintable(stri + "math17")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
- ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
- << QString("aaa") << 0 << 3
- << QStringList( QStringList() << "" << "" << "" << "aaa" << "a" << "aa" );
- QTest::newRow(qPrintable(stri + "math18")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
- ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
- << QString("aaaaa") << 0 << 5
- << QStringList( QStringList() << "aaaaa" << "a" << "aaa" << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "math19")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
- ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
- << QString("aaaaaaaa") << 0 << 8
- << QStringList( QStringList() << "" << "" << "" << "aaaaaaaa" << "a" << "aa" );
- QTest::newRow(qPrintable(stri + "math20")) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
- ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
- << QString("aaaaaaaaa") << -1 << -1
- << QStringList( QStringList() << QString()
- << QString()
- << QString()
- << QString()
- << QString()
- << QString() );
- QTest::newRow(qPrintable(stri + "math21")) << QString("^(aa+)\\1+$") << QString("aaaaaaaaaaaa") << 0 << 12
- << QStringList( QStringList() << "aa" );
-
- static const char * const squareRegExp[] = {
- "^a(?:(\\1aa)a)*$",
- "^(\\2(\\1a))+$",
- "^((\\2a)*)\\1\\2a$",
- 0
- };
-
- int ii = 0;
-
- while ( squareRegExp[ii] != 0 ) {
- for ( int j = 0; j < 100; j++ ) {
- const QString name = QString::asprintf( "square%.1d%.2d", ii, j );
-
- QString target = "";
- target.fill( 'a', j );
-
- int pos = -1;
- int len = -1;
-
- for ( int k = 1; k * k <= j; k++ ) {
- if ( k * k == j ) {
- pos = 0;
- len = j;
- break;
- }
- }
-
- QTest::newRow( name.toLatin1() ) << QString( squareRegExp[ii] ) << target
- << pos << len << QStringList( "IGNORE ME" );
- }
- ii++;
- }
-
- // miscellaneous
- QTest::newRow(qPrintable(stri + "misc00")) << QString(email)
- << QString("email123@example.com") << 0 << 20
- << QStringList();
- QTest::newRow(qPrintable(stri + "misc01")) << QString("[0-9]*\\.[0-9]+") << QString("pi = 3.14") << 5 << 4
- << QStringList();
-
- // or operator
- QTest::newRow(qPrintable(stri + "or00")) << QString("(?:|b)") << QString("xxx") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "or01")) << QString("(?:|b)") << QString("b") << 0 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "or02")) << QString("(?:b|)") << QString("") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "or03")) << QString("(?:b|)") << QString("b") << 0 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "or04")) << QString("(?:||b||)") << QString("") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "or05")) << QString("(?:||b||)") << QString("b") << 0 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "or06")) << QString("(?:a|b)") << QString("") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "or07")) << QString("(?:a|b)") << QString("cc") << -1 << -1 << QStringList();
- QTest::newRow(qPrintable(stri + "or08")) << QString("(?:a|b)") << QString("abc") << 0 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "or09")) << QString("(?:a|b)") << QString("cba") << 1 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "or10")) << QString("(?:ab|ba)") << QString("aba") << 0 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "or11")) << QString("(?:ab|ba)") << QString("bab") << 0 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "or12")) << QString("(?:ab|ba)") << QString("caba") << 1 << 2
- << QStringList();
- QTest::newRow(qPrintable(stri + "or13")) << QString("(?:ab|ba)") << QString("cbab") << 1 << 2
- << QStringList();
-
- // quantifiers
- QTest::newRow(qPrintable(stri + "qua00")) << QString("((([a-j])){0,0})") << QString("") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua01")) << QString("((([a-j])){0,0})") << QString("a") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua02")) << QString("((([a-j])){0,0})") << QString("xyz") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua03")) << QString("((([a-j]))?)") << QString("") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua04")) << QString("((([a-j]))?)") << QString("a") << 0 << 1
- << QStringList( QStringList() << "a" << "a" << "a" );
- QTest::newRow(qPrintable(stri + "qua05")) << QString("((([a-j]))?)") << QString("x") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua06")) << QString("((([a-j]))?)") << QString("ab") << 0 << 1
- << QStringList( QStringList() << "a" << "a" << "a" );
- QTest::newRow(qPrintable(stri + "qua07")) << QString("((([a-j]))?)") << QString("xa") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua08")) << QString("((([a-j])){0,3})") << QString("") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua09")) << QString("((([a-j])){0,3})") << QString("a") << 0 << 1
- << QStringList( QStringList() << "a" << "a" << "a" );
- QTest::newRow(qPrintable(stri + "qua10")) << QString("((([a-j])){0,3})") << QString("abcd") << 0 << 3
- << QStringList( QStringList() << "abc" << "c" << "c" );
- QTest::newRow(qPrintable(stri + "qua11")) << QString("((([a-j])){0,3})") << QString("abcde") << 0 << 3
- << QStringList( QStringList() << "abc" << "c" << "c" );
- QTest::newRow(qPrintable(stri + "qua12")) << QString("((([a-j])){2,4})") << QString("a") << -1 << -1
- << QStringList( QStringList() << QString()
- << QString()
- << QString() );
- QTest::newRow(qPrintable(stri + "qua13")) << QString("((([a-j])){2,4})") << QString("ab") << 0 << 2
- << QStringList( QStringList() << "ab" << "b" << "b" );
- QTest::newRow(qPrintable(stri + "qua14")) << QString("((([a-j])){2,4})") << QString("abcd") << 0 << 4
- << QStringList( QStringList() << "abcd" << "d" << "d" );
- QTest::newRow(qPrintable(stri + "qua15")) << QString("((([a-j])){2,4})") << QString("abcdef") << 0 << 4
- << QStringList( QStringList() << "abcd" << "d" << "d" );
- QTest::newRow(qPrintable(stri + "qua16")) << QString("((([a-j])){2,4})") << QString("xaybcd") << 3 << 3
- << QStringList( QStringList() << "bcd" << "d" << "d" );
- QTest::newRow(qPrintable(stri + "qua17")) << QString("((([a-j])){0,})") << QString("abcdefgh") << 0 << 8
- << QStringList( QStringList() << "abcdefgh" << "h" << "h" );
- QTest::newRow(qPrintable(stri + "qua18")) << QString("((([a-j])){,0})") << QString("abcdefgh") << 0 << 0
- << QStringList( QStringList() << "" << "" << "" );
- QTest::newRow(qPrintable(stri + "qua19")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("123332333") << 0
- << 9
- << QStringList( QStringList() << "123332333" << "2333"
- << "3" );
- QTest::newRow(qPrintable(stri + "qua20")) << QString("(1(2(3){3,4}){2,3}){1,2}")
- << QString("12333323333233331233332333323333") << 0 << 32
- << QStringList( QStringList() << "1233332333323333"
- << "23333" << "3" );
- QTest::newRow(qPrintable(stri + "qua21")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("") << -1 << -1
- << QStringList( QStringList() << QString()
- << QString()
- << QString() );
- QTest::newRow(qPrintable(stri + "qua22")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333") << -1
- << -1
- << QStringList( QStringList() << QString()
- << QString()
- << QString() );
- QTest::newRow(qPrintable(stri + "qua23")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333233") << -1
- << -1
- << QStringList( QStringList() << QString()
- << QString()
- << QString() );
- QTest::newRow(qPrintable(stri + "qua24")) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("122333") << -1
- << -1
- << QStringList( QStringList() << QString()
- << QString()
- << QString() );
-
- // star operator
- QTest::newRow(qPrintable(stri + "star00")) << QString("(?:)*") << QString("") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "star01")) << QString("(?:)*") << QString("abc") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "star02")) << QString("(?:a)*") << QString("") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "star03")) << QString("(?:a)*") << QString("a") << 0 << 1 << QStringList();
- QTest::newRow(qPrintable(stri + "star04")) << QString("(?:a)*") << QString("aaa") << 0 << 3 << QStringList();
- QTest::newRow(qPrintable(stri + "star05")) << QString("(?:a)*") << QString("bbbbaaa") << 0 << 0
- << QStringList();
- QTest::newRow(qPrintable(stri + "star06")) << QString("(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 0
- << QStringList();
- QTest::newRow(qPrintable(stri + "star07")) << QString("(?:b)*(?:a)*") << QString("") << 0 << 0
- << QStringList();
- QTest::newRow(qPrintable(stri + "star08")) << QString("(?:b)*(?:a)*") << QString("a") << 0 << 1
- << QStringList();
- QTest::newRow(qPrintable(stri + "star09")) << QString("(?:b)*(?:a)*") << QString("aaa") << 0 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "star10")) << QString("(?:b)*(?:a)*") << QString("bbbbaaa") << 0 << 7
- << QStringList();
- QTest::newRow(qPrintable(stri + "star11")) << QString("(?:b)*(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 7
- << QStringList();
- QTest::newRow(qPrintable(stri + "star12")) << QString("(?:a|b)*") << QString("c") << 0 << 0 << QStringList();
- QTest::newRow(qPrintable(stri + "star13")) << QString("(?:a|b)*") << QString("abac") << 0 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "star14")) << QString("(?:a|b|)*") << QString("c") << 0 << 0
- << QStringList();
- QTest::newRow(qPrintable(stri + "star15")) << QString("(?:a|b|)*") << QString("abac") << 0 << 3
- << QStringList();
- QTest::newRow(qPrintable(stri + "star16")) << QString("(?:ab|ba|b)*") << QString("abbbababbbaaab") << 0 << 11
- << QStringList();
-}
-
-void tst_QRegExp::exactMatch()
-{
- QRegExp rx_d( "\\d" );
- QRegExp rx_s( "\\s" );
- QRegExp rx_w( "\\w" );
- QRegExp rx_D( "\\D" );
- QRegExp rx_S( "\\S" );
- QRegExp rx_W( "\\W" );
-
- for ( int i = 0; i < 65536; i++ ) {
- QChar ch( i );
- bool is_d = ( ch.category() == QChar::Number_DecimalDigit );
- bool is_s = ch.isSpace();
- bool is_w = ( ch.isLetterOrNumber()
- || ch.isMark()
- || ch == '_' );
-
- QVERIFY( rx_d.exactMatch(QString(ch)) == is_d );
- QVERIFY( rx_s.exactMatch(QString(ch)) == is_s );
- QVERIFY( rx_w.exactMatch(QString(ch)) == is_w );
- QVERIFY( rx_D.exactMatch(QString(ch)) != is_d );
- QVERIFY( rx_S.exactMatch(QString(ch)) != is_s );
- QVERIFY( rx_W.exactMatch(QString(ch)) != is_w );
- }
-}
-
-void tst_QRegExp::capturedTexts()
-{
- QRegExp rx1("a*(a*)", Qt::CaseSensitive, QRegExp::RegExp);
- rx1.exactMatch("aaa");
- QCOMPARE(rx1.matchedLength(), 3);
- QCOMPARE(rx1.cap(0), QString("aaa"));
- QCOMPARE(rx1.cap(1), QString("aaa"));
-
- QRegExp rx2("a*(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
- rx2.exactMatch("aaa");
- QCOMPARE(rx2.matchedLength(), 3);
- QCOMPARE(rx2.cap(0), QString("aaa"));
- QCOMPARE(rx2.cap(1), QString(""));
-
- QRegExp rx3("(?:a|aa)(a*)", Qt::CaseSensitive, QRegExp::RegExp);
- rx3.exactMatch("aaa");
- QCOMPARE(rx3.matchedLength(), 3);
- QCOMPARE(rx3.cap(0), QString("aaa"));
- QCOMPARE(rx3.cap(1), QString("aa"));
-
- QRegExp rx4("(?:a|aa)(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
- rx4.exactMatch("aaa");
- QCOMPARE(rx4.matchedLength(), 3);
- QCOMPARE(rx4.cap(0), QString("aaa"));
- QCOMPARE(rx4.cap(1), QString("a"));
-
- QRegExp rx5("(a)*(a*)", Qt::CaseSensitive, QRegExp::RegExp);
- rx5.exactMatch("aaa");
- QCOMPARE(rx5.matchedLength(), 3);
- QCOMPARE(rx5.cap(0), QString("aaa"));
- QCOMPARE(rx5.cap(1), QString("a"));
- QCOMPARE(rx5.cap(2), QString("aa"));
-
- QRegExp rx6("(a)*(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
- rx6.exactMatch("aaa");
- QCOMPARE(rx6.matchedLength(), 3);
- QCOMPARE(rx6.cap(0), QString("aaa"));
- QCOMPARE(rx6.cap(1), QString("a"));
- QCOMPARE(rx6.cap(2), QString(""));
-
- QRegExp rx7("([A-Za-z_])([A-Za-z_0-9]*)");
- rx7.setCaseSensitivity(Qt::CaseSensitive);
- rx7.setPatternSyntax(QRegExp::RegExp);
- QCOMPARE(rx7.captureCount(), 2);
-
- int pos = rx7.indexIn("(10 + delta4) * 32");
- QCOMPARE(pos, 6);
- QCOMPARE(rx7.matchedLength(), 6);
- QCOMPARE(rx7.cap(0), QString("delta4"));
- QCOMPARE(rx7.cap(1), QString("d"));
- QCOMPARE(rx7.cap(2), QString("elta4"));
-}
-
-void tst_QRegExp::indexIn()
-{
- QFETCH( QString, regexpStr );
- QFETCH( QString, target );
- QFETCH( int, pos );
- QFETCH( int, len );
- QFETCH( QStringList, caps );
-
- caps.prepend( "dummy cap(0)" );
-
- {
- QRegExp rx( regexpStr );
- QVERIFY( rx.isValid() );
-
- int mypos = rx.indexIn( target );
- int mylen = rx.matchedLength();
- QStringList mycaps = rx.capturedTexts();
-
- QCOMPARE( mypos, pos );
- QCOMPARE( mylen, len );
- if ( caps.size() > 1 && caps[1] != "IGNORE ME" ) {
- QCOMPARE( mycaps.count(), caps.count() );
- for ( int i = 1; i < (int) mycaps.count(); i++ )
- QCOMPARE( mycaps[i], caps[i] );
- }
- }
-
- // same as above, but with RegExp2
- {
- QRegExp rx( regexpStr, Qt::CaseSensitive, QRegExp::RegExp2 );
- QVERIFY( rx.isValid() );
-
- int mypos = rx.indexIn( target );
- int mylen = rx.matchedLength();
- QStringList mycaps = rx.capturedTexts();
-
- QCOMPARE( mypos, pos );
- QCOMPARE( mylen, len );
- if ( caps.size() > 1 && caps[1] != "IGNORE ME" ) {
- QCOMPARE( mycaps.count(), caps.count() );
- for ( int i = 1; i < (int) mycaps.count(); i++ )
- QCOMPARE( mycaps[i], caps[i] );
- }
- }
-}
-
-void tst_QRegExp::lastIndexIn()
-{
- QFETCH( QString, regexpStr );
- QFETCH( QString, target );
- QFETCH( int, pos );
- QFETCH( int, len );
- QFETCH( QStringList, caps );
-
- caps.prepend( "dummy" );
-
- /*
- The test data was really designed for indexIn(), not
- lastIndexIn(), but it turns out that we can reuse much of that
- for lastIndexIn().
- */
-
- {
- QRegExp rx( regexpStr );
- QVERIFY( rx.isValid() );
-
- int mypos = rx.lastIndexIn( target, target.length() );
- int mylen = rx.matchedLength();
- QStringList mycaps = rx.capturedTexts();
-
- if ( mypos <= pos || pos == -1 ) {
- QCOMPARE( mypos, pos );
- QCOMPARE( mylen, len );
-
- if (caps.size() > 1 && caps[1] != "IGNORE ME") {
- QCOMPARE( mycaps.count(), caps.count() );
- for ( int i = 1; i < (int) mycaps.count(); i++ )
- QCOMPARE( mycaps[i], caps[i] );
- }
- }
- }
-
- {
- QRegExp rx( regexpStr, Qt::CaseSensitive, QRegExp::RegExp2 );
- QVERIFY( rx.isValid() );
-
- int mypos = rx.lastIndexIn( target, target.length() );
- int mylen = rx.matchedLength();
- QStringList mycaps = rx.capturedTexts();
-
- if ( mypos <= pos || pos == -1 ) {
- QCOMPARE( mypos, pos );
- QCOMPARE( mylen, len );
-
- if (caps.size() > 1 && caps[1] != "IGNORE ME") {
- QCOMPARE( mycaps.count(), caps.count() );
- for ( int i = 1; i < (int) mycaps.count(); i++ )
- QCOMPARE( mycaps[i], caps[i] );
- }
- }
- }
-}
-
-void tst_QRegExp::matchedLength()
-{
- QRegExp r1( "a+" );
- r1.exactMatch( "aaaba" );
- QCOMPARE( r1.matchedLength(), 3 );
-}
-
-const char email[] =
- "^[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff"
- "]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\x"
- "ff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:"
- "(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@"
- ",;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\""
- "]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?"
- ":\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x"
- "80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*"
- ")*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*"
- "(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\"
- "\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015("
- ")]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>"
- "@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\["
- "\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\"
- "x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\\\x"
- "80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\"
- "015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\"
- "\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*@[\\040\\t]*(?:\\([^\\\\\\x"
- "80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\"
- "015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\"
- "\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\["
- "\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037"
- "\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff"
- "])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80"
- "-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x"
- "80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]"
- "*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x"
- "80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\"
- "\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040"
- "\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\"
- "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xf"
- "f\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-"
- "\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015"
- "()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x8"
- "0-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*|(?:[^(\\040)<>@,;:\".\\\\\\[\\"
- "]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x"
- "80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^\\\\"
- "\\x80-\\xff\\n\\015\"]*)*\")[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\"
- "010\\012-\\037]*(?:(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x8"
- "0-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\"
- "x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)|\"[^\\\\"
- "\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015"
- "\"]*)*\")[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037]*)*<"
- "[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]"
- "|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xf"
- "f\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:@"
- "[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]"
- "|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xf"
- "f\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:["
- "^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:"
- "\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015"
- "\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
- "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
- "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
- "\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff"
- "\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*("
- "?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\x"
- "ff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-"
- "\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xf"
- "f])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\"
- "040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\"
- "([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\"
- "n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*(?:,["
- "\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|"
- "\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff"
- "\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*@[\\0"
- "40\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\("
- "[^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n"
- "\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\"
- "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\"
- "\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]"
- "]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()"
- "]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\"
- "x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015"
- "()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015"
- "()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^"
- "\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\0"
- "15()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x8"
- "0-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?"
- ":[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*("
- "?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\"
- "x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]"
- "*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*)*:[\\040\\t]*"
- "(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\"
- "\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015("
- ")]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)?(?:[^(\\040)"
- "<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\"
- "[\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^"
- "\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\"
- "\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\"
- "n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\"
- "\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\"
- "\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff"
- "\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^"
- "\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\"
- "\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\0"
- "37\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^"
- "\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
- "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
- "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
- "\\n\\015()]*)*\\)[\\040\\t]*)*)*@[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
- "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
- "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
- "\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\0"
- "37\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])"
- "|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040"
- "\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^"
- "\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\"
- "015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\0"
- "40\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\("
- "[^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n"
- "\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\"
- "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\"
- "\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]"
- "]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()"
- "]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\"
- "x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015"
- "()]*)*\\)[\\040\\t]*)*)*>)$";
-
-void tst_QRegExp::wildcard_data()
-{
- QTest::addColumn<QString>("rxp");
- QTest::addColumn<QString>("string");
- QTest::addColumn<int>("foundIndex");
-
- QTest::newRow( "data0" ) << QString("*.html") << QString("test.html") << 0;
- QTest::newRow( "data1" ) << QString("*.html") << QString("test.htm") << -1;
- QTest::newRow( "data2" ) << QString("bar*") << QString("foobarbaz") << 3;
- QTest::newRow( "data3" ) << QString("*") << QString("Qt Rocks!") << 0;
- QTest::newRow( "data4" ) << QString(".html") << QString("test.html") << 4;
- QTest::newRow( "data5" ) << QString(".h") << QString("test.cpp") << -1;
- QTest::newRow( "data6" ) << QString(".???l") << QString("test.html") << 4;
- QTest::newRow( "data7" ) << QString("?") << QString("test.html") << 0;
- QTest::newRow( "data8" ) << QString("?m") << QString("test.html") << 6;
- QTest::newRow( "data9" ) << QString(".h[a-z]ml") << QString("test.html") << 4;
- QTest::newRow( "data10" ) << QString(".h[A-Z]ml") << QString("test.html") << -1;
- QTest::newRow( "data11" ) << QString(".h[A-Z]ml") << QString("test.hTml") << 4;
-}
-
-void tst_QRegExp::wildcard()
-{
- QFETCH( QString, rxp );
- QFETCH( QString, string );
- QFETCH( int, foundIndex );
-
- QRegExp r( rxp );
- r.setPatternSyntax(QRegExp::WildcardUnix);
- QCOMPARE( r.indexIn( string ), foundIndex );
-}
-
-void tst_QRegExp::testEscapingWildcard_data(){
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QString>("teststring");
- QTest::addColumn<bool>("isMatching");
-
- QTest::newRow("[ Not escaped") << "[Qt;" << "[Qt;" << false;
- QTest::newRow("[ Escaped") << "\\[Qt;" << "[Qt;" << true;
-
- QTest::newRow("] Not escaped") << "]Ik;" << "]Ik;" << false;
- QTest::newRow("] Escaped") << "\\]Ip;" << "]Ip;" << true;
-
- QTest::newRow("? Not escaped valid") << "?Ou:" << ".Ou:" << true;
- QTest::newRow("? Not escaped invalid") << "?Tr;" << "Tr;" << false;
- QTest::newRow("? Escaped") << "\\?O;" << "?O;" << true;
-
- QTest::newRow("[] not escaped") << "[lL]" << "l" << true;
- QTest::newRow("[] escaped") << "\\[\\]" << "[]" << true;
-
- QTest::newRow("case [[]") << "[[abc]" << "[" << true;
- QTest::newRow("case []abc] match ]") << "[]abc]" << "]" << true;
- QTest::newRow("case []abc] match a") << "[]abc]" << "a" << true;
- QTest::newRow("case [abc] match a") << "[abc]" << "a" << true;
- QTest::newRow("case []] don't match [") << "[]abc]" << "[" << false;
- QTest::newRow("case [^]abc] match d") << "[^]abc]" << "d" << true;
- QTest::newRow("case [^]abc] don't match ]") << "[^]abc]" << "]" << false;
-
- QTest::newRow("* Not escaped with char") << "*Te;" << "12345Te;" << true;
- QTest::newRow("* Not escaped without char") << "*Ch;" << "Ch;" << true;
- QTest::newRow("* Not escaped invalid") << "*Ro;" << "o;" << false;
- QTest::newRow("* Escaped") << "\\[Cks;" << "[Cks;" << true;
-
- QTest::newRow("a true '\\' in input") << "\\Qt;" << "\\Qt;" << true;
- QTest::newRow("two true '\\' in input") << "\\\\Qt;" << "\\\\Qt;" << true;
- QTest::newRow("a '\\' at the end") << "\\\\Qt;\\" << "\\\\Qt;\\" << true;
-
- QTest::newRow("[]\\] matches ]") << "[]\\]" << "]" << true;
- QTest::newRow("[]\\] matches \\") << "[]\\]" << "\\" << true;
- QTest::newRow("[]\\] does not match [") << "[]\\]" << "[" << false;
- QTest::newRow("[]\\]a matches ]a") << "[]\\]a" << "]a" << true;
- QTest::newRow("[]\\]a matches \\a") << "[]\\]a" << "\\a" << true;
- QTest::newRow("[]\\]a does not match [a") << "[]\\]a" << "[a" << false;
-}
-
-void tst_QRegExp::testEscapingWildcard(){
- QFETCH(QString, pattern);
-
- QRegExp re(pattern);
- re.setPatternSyntax(QRegExp::WildcardUnix);
-
- QFETCH(QString, teststring);
- QFETCH(bool, isMatching);
- QCOMPARE(re.exactMatch(teststring), isMatching);
-}
-
-void tst_QRegExp::testInvalidWildcard_data(){
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<bool>("isValid");
-
- QTest::newRow("valid []") << "[abc]" << true;
- QTest::newRow("invalid [") << "[abc" << false;
- QTest::newRow("ending [") << "abc[" << false;
- QTest::newRow("ending ]") << "abc]" << false;
- QTest::newRow("ending [^") << "abc[^" << false;
- QTest::newRow("ending [\\") << "abc[\\" << false;
- QTest::newRow("ending []") << "abc[]" << false;
- QTest::newRow("ending [[") << "abc[[" << false;
-}
-
-void tst_QRegExp::testInvalidWildcard(){
- QFETCH(QString, pattern);
-
- QRegExp re(pattern);
- re.setPatternSyntax(QRegExp::Wildcard);
-
- QFETCH(bool, isValid);
- QCOMPARE(re.isValid(), isValid);
-}
-
-void tst_QRegExp::caretAnchoredOptimization()
-{
- QString s = "---babnana----";
- s.replace( QRegExp("^-*|(-*)$"), "" );
- QCOMPARE(s, QLatin1String("babnana"));
-
- s = "---babnana----";
- s.replace( QRegExp("^-*|(-{0,})$"), "" );
- QCOMPARE(s, QLatin1String("babnana"));
-
- s = "---babnana----";
- s.replace( QRegExp("^-*|(-{1,})$"), "" );
- QCOMPARE(s, QLatin1String("babnana"));
-
- s = "---babnana----";
- s.replace( QRegExp("^-*|(-+)$"), "" );
- QCOMPARE(s, QLatin1String("babnana"));
-}
-
-void tst_QRegExp::isEmpty()
-{
- QRegExp rx1;
- QVERIFY(rx1.isEmpty());
-
- QRegExp rx2 = rx1;
- QVERIFY(rx2.isEmpty());
-
- rx2.setPattern("");
- QVERIFY(rx2.isEmpty());
-
- rx2.setPattern("foo");
- QVERIFY(!rx2.isEmpty());
-
- rx2.setPattern(")(");
- QVERIFY(!rx2.isEmpty());
-
- rx2.setPattern("");
- QVERIFY(rx2.isEmpty());
-
- rx2.setPatternSyntax(QRegExp::Wildcard);
- rx2.setPattern("");
- QVERIFY(rx2.isEmpty());
-}
-
-static QRegExp re("foo.*bar");
-
-void tst_QRegExp::staticRegExp()
-{
- QVERIFY(re.exactMatch("fooHARRYbar"));
- // the actual test is that a static regexp should not crash
-}
-
-void tst_QRegExp::rainersSlowRegExpCopyBug()
-{
- // this test should take an extreme amount of time if QRegExp is broken
- QRegExp original(email);
- for (int i = 0; i < 100000; ++i) {
- QRegExp copy = original;
- (void)copy.exactMatch("~");
- QRegExp copy2 = original;
- }
-}
-
-void tst_QRegExp::nonExistingBackReferenceBug()
-{
- {
- QRegExp rx("<\\5>");
- QVERIFY(rx.isValid());
- QCOMPARE(rx.indexIn("<>"), 0);
- QCOMPARE(rx.capturedTexts(), QStringList("<>"));
- }
-
- {
- QRegExp rx("<\\1>");
- QVERIFY(rx.isValid());
- QCOMPARE(rx.indexIn("<>"), 0);
- QCOMPARE(rx.capturedTexts(), QStringList("<>"));
- }
-
- {
- QRegExp rx("(?:<\\1>)\\1\\5\\4");
- QVERIFY(rx.isValid());
- QCOMPARE(rx.indexIn("<>"), 0);
- QCOMPARE(rx.capturedTexts(), QStringList("<>"));
- }
-}
-
-class Thread : public QThread
-{
-public:
- Thread(const QRegExp &rx) : rx(rx) {}
-
- void run();
-
- QRegExp rx;
-};
-
-void Thread::run()
-{
- QString str = "abc";
- for (int i = 0; i < 10; ++i)
- str += str;
- str += "abbbdekcz";
- int x;
-
- for (int j = 0; j < 10000; ++j)
- x = rx.indexIn(str);
-
- QCOMPARE(x, 3072);
-}
-
-void tst_QRegExp::reentrancy()
-{
- QRegExp rx("(ab{2,}d?e?f?[g-z]?)c");
- Thread *threads[10];
-
- for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i) {
- threads[i] = new Thread(rx);
- threads[i]->start();
- }
-
- for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
- threads[i]->wait();
-
- for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
- delete threads[i];
-}
-
-class Thread2 : public QThread
-{
-public:
- void run();
-};
-
-void Thread2::run()
-{
- QRegExp rx("(ab{2,}d?e?f?[g-z]?)c");
- QString str = "abc";
- for (int i = 0; i < 10; ++i)
- str += str;
- str += "abbbdekcz";
- int x;
-
- for (int j = 0; j < 10000; ++j)
- x = rx.indexIn(str);
-
- QCOMPARE(x, 3072);
-}
-
-// Test that multiple threads can construct equal QRegExps.
-// (In the current QRegExp design each engine instatance will share
-// the same cache key, so the threads will race for the cache entry
-// in the global cache.)
-void tst_QRegExp::threadsafeEngineCache()
-{
- Thread2 *threads[10];
-
- for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i) {
- threads[i] = new Thread2();
- threads[i]->start();
- }
-
- for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
- threads[i]->wait();
-
- for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
- delete threads[i];
-}
-
-
-void tst_QRegExp::prepareEngineOptimization()
-{
- QRegExp rx0("(f?)(?:(o?)(o?))?");
-
- QRegExp rx1(rx0);
-
- QCOMPARE(rx1.capturedTexts(), QStringList() << "" << "" << "" << "");
- QCOMPARE(rx1.matchedLength(), -1);
- QCOMPARE(rx1.matchedLength(), -1);
- QCOMPARE(rx1.captureCount(), 3);
-
- QCOMPARE(rx1.exactMatch("foo"), true);
- QCOMPARE(rx1.matchedLength(), 3);
- QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
- QCOMPARE(rx1.captureCount(), 3);
- QCOMPARE(rx1.matchedLength(), 3);
- QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
- QCOMPARE(rx1.pos(3), 2);
-
- QCOMPARE(rx1.exactMatch("foo"), true);
- QCOMPARE(rx1.captureCount(), 3);
- QCOMPARE(rx1.matchedLength(), 3);
- QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
- QCOMPARE(rx1.pos(3), 2);
-
- QRegExp rx2 = rx1;
-
- QCOMPARE(rx1.captureCount(), 3);
- QCOMPARE(rx1.matchedLength(), 3);
- QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
- QCOMPARE(rx1.pos(3), 2);
-
- QCOMPARE(rx2.captureCount(), 3);
- QCOMPARE(rx2.matchedLength(), 3);
- QCOMPARE(rx2.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
- QCOMPARE(rx2.pos(3), 2);
-
- QCOMPARE(rx1.exactMatch("fo"), true);
- QCOMPARE(rx1.captureCount(), 3);
- QCOMPARE(rx1.matchedLength(), 2);
- QCOMPARE(rx1.capturedTexts(), QStringList() << "fo" << "f" << "o" << "");
- QCOMPARE(rx1.pos(2), 1);
-
- QRegExp rx3;
- QVERIFY(rx3.isValid());
-
- QRegExp rx4("foo", Qt::CaseInsensitive, QRegExp::RegExp);
- QVERIFY(rx4.isValid());
-
- QRegExp rx5("foo", Qt::CaseInsensitive, QRegExp::RegExp2);
- QVERIFY(rx5.isValid());
-
- QRegExp rx6("foo", Qt::CaseInsensitive, QRegExp::FixedString);
- QVERIFY(rx6.isValid());
-
- QRegExp rx7("foo", Qt::CaseInsensitive, QRegExp::Wildcard);
- QVERIFY(rx7.isValid());
-
- QRegExp rx8("][", Qt::CaseInsensitive, QRegExp::RegExp);
- QVERIFY(!rx8.isValid());
-
- QRegExp rx9("][", Qt::CaseInsensitive, QRegExp::RegExp2);
- QVERIFY(!rx9.isValid());
-
- QRegExp rx10("][", Qt::CaseInsensitive, QRegExp::Wildcard);
- QVERIFY(!rx10.isValid());
-
- QRegExp rx11("][", Qt::CaseInsensitive, QRegExp::FixedString);
- QVERIFY(rx11.isValid());
- QVERIFY(rx11.exactMatch("]["));
- QCOMPARE(rx11.matchedLength(), 2);
-
- rx11.setPatternSyntax(QRegExp::Wildcard);
- QVERIFY(!rx11.isValid());
- QCOMPARE(rx11.captureCount(), 0);
- QCOMPARE(rx11.matchedLength(), -1);
-
- rx11.setPatternSyntax(QRegExp::RegExp);
- QVERIFY(!rx11.isValid());
- QCOMPARE(rx11.captureCount(), 0);
- QCOMPARE(rx11.matchedLength(), -1);
-
- rx11.setPattern("(foo)");
- QVERIFY(rx11.isValid());
- QCOMPARE(rx11.captureCount(), 1);
- QCOMPARE(rx11.matchedLength(), -1);
-
- QCOMPARE(rx11.indexIn("ofoo"), 1);
- QCOMPARE(rx11.captureCount(), 1);
- QCOMPARE(rx11.matchedLength(), 3);
-
- rx11.setPatternSyntax(QRegExp::RegExp);
- QCOMPARE(rx11.captureCount(), 1);
- QCOMPARE(rx11.matchedLength(), 3);
-
- /*
- This behavior isn't entirely consistent with setPatter(),
- setPatternSyntax(), and setCaseSensitivity(), but I'm testing
- it here to ensure that it doesn't change subtly in future
- releases.
- */
- rx11.setMinimal(true);
- QCOMPARE(rx11.matchedLength(), 3);
- rx11.setMinimal(false);
- QCOMPARE(rx11.matchedLength(), 3);
-
- rx11.setPatternSyntax(QRegExp::Wildcard);
- QCOMPARE(rx11.captureCount(), 0);
- QCOMPARE(rx11.matchedLength(), -1);
-
- rx11.setPatternSyntax(QRegExp::RegExp);
- QCOMPARE(rx11.captureCount(), 1);
- QCOMPARE(rx11.matchedLength(), -1);
-}
-
-void tst_QRegExp::swap()
-{
- QRegExp r1(QLatin1String(".*")), r2(QLatin1String("a*"));
- r1.swap(r2);
- QCOMPARE(r1.pattern(),QLatin1String("a*"));
- QCOMPARE(r2.pattern(),QLatin1String(".*"));
-}
-
-void tst_QRegExp::operator_eq()
-{
- const int I = 2;
- const int J = 4;
- const int K = 2;
- const int ELL = 2;
- QRegExp rxtable[I * J * K * ELL];
- int n;
-
- n = 0;
- for (int i = 0; i < I; ++i) {
- for (int j = 0; j < J; ++j) {
- for (int k = 0; k < K; ++k) {
- for (int ell = 0; ell < ELL; ++ell) {
- Qt::CaseSensitivity cs = i == 0 ? Qt::CaseSensitive : Qt::CaseInsensitive;
- QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(j);
- bool minimal = k == 0;
-
- if (ell == 0) {
- QRegExp rx("foo", cs, syntax);
- rx.setMinimal(minimal);
- rxtable[n++] = rx;
- } else {
- QRegExp rx;
- rx.setPattern("bar");
- rx.setMinimal(true);
- rx.exactMatch("bar");
- rx.setCaseSensitivity(cs);
- rx.setMinimal(minimal);
- rx.setPattern("foo");
- rx.setPatternSyntax(syntax);
- rx.exactMatch("foo");
- rxtable[n++] = rx;
- }
- }
- }
- }
- }
-
- for (int i = 0; i < I * J * K * ELL; ++i) {
- for (int j = 0; j < I * J * K * ELL; ++j) {
- QCOMPARE(rxtable[i] == rxtable[j], i / ELL == j / ELL);
- QCOMPARE(rxtable[i] != rxtable[j], i / ELL != j / ELL);
- // this just happens to have no hash collisions. If at some point
- // we get collisions, restrict the test to only equal elements:
- QCOMPARE(qHash(rxtable[i]) == qHash(rxtable[j]), i / ELL == j / ELL);
- }
- }
-}
-
-// This test aims to ensure that the values returned by pos() and cap()
-// are consistent.
-void tst_QRegExp::posAndCapConsistency_data()
-{
- QTest::addColumn<QString>("reStr");
- QTest::addColumn<QString>("text");
- QTest::addColumn<int>("matchIndex");
-
- QTest::addColumn<int>("pos0");
- QTest::addColumn<int>("pos1");
- QTest::addColumn<int>("pos2");
-
- QTest::addColumn<QString>("cap0");
- QTest::addColumn<QString>("cap1");
- QTest::addColumn<QString>("cap2");
-
- QTest::newRow("no match")
- << QString("(a) (b)") << QString("b a") << -1
- << -1 << -1 << -1 << QString() << QString() << QString();
-
- QTest::newRow("both captures match")
- << QString("(a) (b)") << QString("a b") << 0
- << 0 << 0 << 2 << QString("a b") << QString("a") << QString("b");
-
- QTest::newRow("first capture matches @0")
- << QString("(a*)|(b*)") << QString("axx") << 0
- << 0 << 0 << -1 << QString("a") << QString("a") << QString();
- QTest::newRow("second capture matches @0")
- << QString("(a*)|(b*)") << QString("bxx") << 0
- << 0 << -1 << 0 << QString("b") << QString() << QString("b");
- QTest::newRow("first capture empty match @0")
- << QString("(a*)|(b*)") << QString("xx") << 0
- << 0 << -1 << -1 << QString("") << QString() << QString();
- QTest::newRow("second capture empty match @0")
- << QString("(a)|(b*)") << QString("xx") << 0
- << 0 << -1 << -1 << QString("") << QString() << QString();
-
- QTest::newRow("first capture matches @1")
- << QString("x(?:(a*)|(b*))") << QString("-xa") << 1
- << 1 << 2 << -1 << QString("xa") << QString("a") << QString();
- QTest::newRow("second capture matches @1")
- << QString("x(?:(a*)|(b*))") << QString("-xb") << 1
- << 1 << -1 << 2 << QString("xb") << QString() << QString("b");
- QTest::newRow("first capture empty match @1")
- << QString("x(?:(a*)|(b*))") << QString("-xx") << 1
- << 1 << -1 << -1 << QString("x") << QString() << QString();
- QTest::newRow("second capture empty match @1")
- << QString("x(?:(a)|(b*))") << QString("-xx") << 1
- << 1 << -1 << -1 << QString("x") << QString() << QString();
-
- QTest::newRow("first capture matches @2")
- << QString("(a)|(b)") << QString("xxa") << 2
- << 2 << 2 << -1 << QString("a") << QString("a") << QString();
- QTest::newRow("second capture matches @2")
- << QString("(a)|(b)") << QString("xxb") << 2
- << 2 << -1 << 2 << QString("b") << QString() << QString("b");
- QTest::newRow("no match - with options")
- << QString("(a)|(b)") << QString("xx") << -1
- << -1 << -1 << -1 << QString() << QString() << QString();
-
-}
-
-void tst_QRegExp::posAndCapConsistency()
-{
- QFETCH( QString, reStr );
- QFETCH( QString, text );
- QFETCH( int, matchIndex );
- QFETCH( int, pos0 );
- QFETCH( int, pos1 );
- QFETCH( int, pos2 );
- QFETCH( QString, cap0 );
- QFETCH( QString, cap1 );
- QFETCH( QString, cap2 );
-
- QRegExp re(reStr);
- QCOMPARE(re.captureCount(), 2);
- QCOMPARE(re.capturedTexts().size(), 3);
-
- QCOMPARE(re.indexIn(text), matchIndex);
-
- QCOMPARE( re.pos(0), pos0 );
- QCOMPARE( re.pos(1), pos1 );
- QCOMPARE( re.pos(2), pos2 );
-
- QCOMPARE( re.cap(0).isNull(), cap0.isNull() );
- QCOMPARE( re.cap(0), cap0 );
- QCOMPARE( re.cap(1).isNull(), cap1.isNull() );
- QCOMPARE( re.cap(1), cap1 );
- QCOMPARE( re.cap(2).isNull(), cap2.isNull() );
- QCOMPARE( re.cap(2), cap2 );
-}
-
-void tst_QRegExp::interval()
-{
- {
- QRegExp exp("a{0,1}");
- QVERIFY(exp.isValid());
- }
- {
- QRegExp exp("a{1,1}");
- QVERIFY(exp.isValid());
- }
- {
- QRegExp exp("a{1,0}");
- QVERIFY(!exp.isValid());
- }
-}
-
-void tst_QRegExp::validityCheck_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<bool>("validity");
- QTest::newRow("validity01") << QString() << true;
- QTest::newRow("validity02") << QString("abc.*abc") << true;
- QTest::newRow("validity03") << QString("[a-z") << false;
- QTest::newRow("validity04") << QString("a(b") << false;
-}
-
-void tst_QRegExp::validityCheck()
-{
- QFETCH(QString, pattern);
-
- QRegExp rx(pattern);
- QTEST(rx.isValid(), "validity");
- QCOMPARE(rx.matchedLength(), -1);
- QCOMPARE(rx.pos(), -1);
- QCOMPARE(rx.cap(), QString(""));
-
- QRegExp rx2(rx);
- QTEST(rx2.isValid(), "validity");
- QCOMPARE(rx2.matchedLength(), -1);
- QCOMPARE(rx2.pos(), -1);
- QCOMPARE(rx2.cap(), QString(""));
-}
-
-void tst_QRegExp::escapeSequences()
-{
- QString perlSyntaxSpecialChars("0123456789afnrtvbBdDwWsSx\\|[]{}()^$?+*");
- QString w3cXmlSchema11SyntaxSpecialChars("cCiIpP"); // as well as the perl ones
- QString pattern = QLatin1String("\\?");
- for (int i = ' '; i <= 127; ++i) {
- QLatin1Char c(i);
- if (perlSyntaxSpecialChars.indexOf(c) == -1) {
- pattern[1] = c;
- QRegExp rx(pattern, Qt::CaseSensitive, QRegExp::RegExp);
- // we'll never have c == 'a' since it's a special character
- const QString s = QLatin1String("aaa") + c + QLatin1String("aaa");
- QCOMPARE(rx.indexIn(s), 3);
-
- rx.setPatternSyntax(QRegExp::RegExp2);
- QCOMPARE(rx.indexIn(s), 3);
-
- if (w3cXmlSchema11SyntaxSpecialChars.indexOf(c) == -1) {
- rx.setPatternSyntax(QRegExp::W3CXmlSchema11);
- QCOMPARE(rx.indexIn(s), 3);
- }
- }
- }
-}
-
-
-QTEST_APPLESS_MAIN(tst_QRegExp)
-#include "tst_qregexp.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro b/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro
deleted file mode 100644
index ec8189717e..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qregularexpression
-QT = core testlib
-SOURCES = tst_qregularexpression.cpp
diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
deleted file mode 100644
index c02756d76a..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
+++ /dev/null
@@ -1,2254 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 Giuseppe D'Angelo <dangelog@gmail.com>.
-** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qstring.h>
-#include <qlist.h>
-#include <qstringlist.h>
-#include <qhash.h>
-
-#include <qobject.h>
-#include <qregularexpression.h>
-#include <qthread.h>
-
-Q_DECLARE_METATYPE(QRegularExpression::PatternOptions)
-Q_DECLARE_METATYPE(QRegularExpression::MatchType)
-Q_DECLARE_METATYPE(QRegularExpression::MatchOptions)
-
-class tst_QRegularExpression : public QObject
-{
- Q_OBJECT
-
-private slots:
- void defaultConstructors();
- void gettersSetters_data();
- void gettersSetters();
- void escape_data();
- void escape();
- void validity_data();
- void validity();
- void patternOptions_data();
- void patternOptions();
- void normalMatch_data();
- void normalMatch();
- void partialMatch_data();
- void partialMatch();
- void globalMatch_data();
- void globalMatch();
- void serialize_data();
- void serialize();
- void operatoreq_data();
- void operatoreq();
- void captureCount_data();
- void captureCount();
- void captureNames_data();
- void captureNames();
- void pcreJitStackUsage_data();
- void pcreJitStackUsage();
- void regularExpressionMatch_data();
- void regularExpressionMatch();
- void JOptionUsage_data();
- void JOptionUsage();
- void QStringAndQStringRefEquivalence();
- void threadSafety_data();
- void threadSafety();
-
- void wildcard_data();
- void wildcard();
- void testInvalidWildcard_data();
- void testInvalidWildcard();
-
-private:
- void provideRegularExpressions();
-};
-
-struct Match
-{
- Match()
- {
- clear();
- }
-
- void clear()
- {
- isValid = false;
- hasMatch = false;
- hasPartialMatch = false;
- captured.clear();
- namedCaptured.clear();
- }
-
- bool isValid;
- bool hasMatch;
- bool hasPartialMatch;
- QStringList captured;
- QHash<QString, QString> namedCaptured;
-};
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Match, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(Match)
-
-bool operator==(const QRegularExpressionMatch &rem, const Match &m)
-{
- if (rem.isValid() != m.isValid)
- return false;
- if (!rem.isValid())
- return true;
- if ((rem.hasMatch() != m.hasMatch) || (rem.hasPartialMatch() != m.hasPartialMatch))
- return false;
- if (rem.hasMatch() || rem.hasPartialMatch()) {
- if (rem.lastCapturedIndex() != (m.captured.size() - 1))
- return false;
- for (int i = 0; i <= rem.lastCapturedIndex(); ++i) {
- QString remCaptured = rem.captured(i);
- QString mCaptured = m.captured.at(i);
- if (remCaptured != mCaptured
- || remCaptured.isNull() != mCaptured.isNull()
- || remCaptured.isEmpty() != mCaptured.isEmpty()) {
- return false;
- }
- }
-
- for (auto it = m.namedCaptured.begin(), end = m.namedCaptured.end(); it != end; ++it) {
- const QString remCaptured = rem.captured(it.key());
- const QString mCaptured = it.value();
- if (remCaptured != mCaptured
- || remCaptured.isNull() != mCaptured.isNull()
- || remCaptured.isEmpty() != mCaptured.isEmpty()) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool operator==(const Match &m, const QRegularExpressionMatch &rem)
-{
- return operator==(rem, m);
-}
-
-bool operator!=(const QRegularExpressionMatch &rem, const Match &m)
-{
- return !operator==(rem, m);
-}
-
-bool operator!=(const Match &m, const QRegularExpressionMatch &rem)
-{
- return !operator==(m, rem);
-}
-
-
-bool operator==(const QRegularExpressionMatchIterator &iterator, const QVector<Match> &expectedMatchList)
-{
- QRegularExpressionMatchIterator i = iterator;
-
- for (const Match &expectedMatch : expectedMatchList) {
- if (!i.hasNext())
- return false;
-
- QRegularExpressionMatch match = i.next();
- if (match != expectedMatch)
- return false;
- }
-
- if (i.hasNext())
- return false;
-
- return true;
-}
-
-bool operator==(const QVector<Match> &expectedMatchList, const QRegularExpressionMatchIterator &iterator)
-{
- return operator==(iterator, expectedMatchList);
-}
-
-bool operator!=(const QRegularExpressionMatchIterator &iterator, const QVector<Match> &expectedMatchList)
-{
- return !operator==(iterator, expectedMatchList);
-}
-
-bool operator!=(const QVector<Match> &expectedMatchList, const QRegularExpressionMatchIterator &iterator)
-{
- return !operator==(expectedMatchList, iterator);
-}
-
-void consistencyCheck(const QRegularExpressionMatch &match)
-{
- if (match.isValid()) {
- QVERIFY(match.regularExpression().isValid());
- QVERIFY(!(match.hasMatch() && match.hasPartialMatch()));
-
- if (match.hasMatch() || match.hasPartialMatch()) {
- QVERIFY(match.lastCapturedIndex() >= 0);
- if (match.hasPartialMatch())
- QVERIFY(match.lastCapturedIndex() == 0);
-
- for (int i = 0; i <= match.lastCapturedIndex(); ++i) {
- int startPos = match.capturedStart(i);
- int endPos = match.capturedEnd(i);
- int length = match.capturedLength(i);
- QString captured = match.captured(i);
- QStringRef capturedRef = match.capturedRef(i);
- QStringView capturedView = match.capturedView(i);
-
- if (!captured.isNull()) {
- QVERIFY(startPos >= 0);
- QVERIFY(endPos >= 0);
- QVERIFY(length >= 0);
- QVERIFY(endPos >= startPos);
- QVERIFY((endPos - startPos) == length);
- QVERIFY(captured == capturedRef);
- QVERIFY(captured == capturedView);
- } else {
- QVERIFY(startPos == -1);
- QVERIFY(endPos == -1);
- QVERIFY((endPos - startPos) == length);
- QVERIFY(capturedRef.isNull());
- QVERIFY(capturedView.isNull());
- }
- }
- }
- } else {
- QVERIFY(!match.hasMatch());
- QVERIFY(!match.hasPartialMatch());
- QVERIFY(match.captured(0).isNull());
- QVERIFY(match.capturedStart(0) == -1);
- QVERIFY(match.capturedEnd(0) == -1);
- QVERIFY(match.capturedLength(0) == 0);
- }
-}
-
-void consistencyCheck(const QRegularExpressionMatchIterator &iterator)
-{
- QRegularExpressionMatchIterator i(iterator); // make a copy, we modify it
- if (i.isValid()) {
- while (i.hasNext()) {
- QRegularExpressionMatch peeked = i.peekNext();
- QRegularExpressionMatch match = i.next();
- consistencyCheck(peeked);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch() || match.hasPartialMatch());
- QCOMPARE(i.regularExpression(), match.regularExpression());
- QCOMPARE(i.matchOptions(), match.matchOptions());
- QCOMPARE(i.matchType(), match.matchType());
-
- QVERIFY(peeked.isValid() == match.isValid());
- QVERIFY(peeked.hasMatch() == match.hasMatch());
- QVERIFY(peeked.hasPartialMatch() == match.hasPartialMatch());
- QVERIFY(peeked.lastCapturedIndex() == match.lastCapturedIndex());
- for (int i = 0; i <= peeked.lastCapturedIndex(); ++i) {
- QVERIFY(peeked.captured(i) == match.captured(i));
- QVERIFY(peeked.capturedStart(i) == match.capturedStart(i));
- QVERIFY(peeked.capturedEnd(i) == match.capturedEnd(i));
- }
- }
- } else {
- QVERIFY(!i.hasNext());
- QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatchIterator::peekNext() called on an iterator already at end");
- QRegularExpressionMatch peeked = i.peekNext();
- QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatchIterator::next() called on an iterator already at end");
- QRegularExpressionMatch match = i.next();
- consistencyCheck(peeked);
- consistencyCheck(match);
- QVERIFY(!match.isValid());
- QVERIFY(!peeked.isValid());
- }
-
-}
-
-template<typename Result>
-static void prepareResultForNoMatchType(Result *r, const Result &orig)
-{
- Q_UNUSED(r);
- Q_UNUSED(orig);
-}
-
-static void prepareResultForNoMatchType(Match *m, const Match &orig)
-{
- m->isValid = orig.isValid;
-}
-
-template<typename QREMatch, typename QREMatchFunc, typename Subject, typename Result>
-static void testMatchImpl(const QRegularExpression &regexp,
- QREMatchFunc matchingMethod,
- const Subject &subject,
- int offset,
- QRegularExpression::MatchType matchType,
- QRegularExpression::MatchOptions matchOptions,
- const Result &result)
-{
- {
- const QREMatch m = (regexp.*matchingMethod)(subject, offset, matchType, matchOptions);
- consistencyCheck(m);
- QVERIFY(m == result);
- QCOMPARE(m.regularExpression(), regexp);
- QCOMPARE(m.matchType(), matchType);
- QCOMPARE(m.matchOptions(), matchOptions);
- }
- {
- // ignore the expected results provided by the match object --
- // we'll never get any result when testing the NoMatch type.
- // Just check the validity of the match here.
- Result realMatch;
- prepareResultForNoMatchType(&realMatch, result);
-
- const QREMatch m = (regexp.*matchingMethod)(subject, offset, QRegularExpression::NoMatch, matchOptions);
- consistencyCheck(m);
- QVERIFY(m == realMatch);
- QCOMPARE(m.regularExpression(), regexp);
- QCOMPARE(m.matchType(), QRegularExpression::NoMatch);
- QCOMPARE(m.matchOptions(), matchOptions);
- }
-}
-
-template<typename QREMatch, typename QREMatchFuncForString, typename QREMatchFuncForStringRef, typename Result>
-static void testMatch(const QRegularExpression &regexp,
- QREMatchFuncForString matchingMethodForString,
- QREMatchFuncForStringRef matchingMethodForStringRef,
- const QString &subject,
- int offset,
- QRegularExpression::MatchType matchType,
- QRegularExpression::MatchOptions matchOptions,
- const Result &result)
-{
- // test with QString as subject type
- testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result);
-
- // test with QStringRef as subject type
- testMatchImpl<QREMatch>(regexp,
- matchingMethodForStringRef,
- QStringRef(&subject, 0, subject.length()),
- offset,
- matchType,
- matchOptions,
- result);
-}
-
-typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
-typedef QRegularExpressionMatch (QRegularExpression::*QREMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
-typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringPMF)(const QString &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
-typedef QRegularExpressionMatchIterator (QRegularExpression::*QREGlobalMatchStringRefPMF)(const QStringRef &, int, QRegularExpression::MatchType, QRegularExpression::MatchOptions) const;
-
-void tst_QRegularExpression::provideRegularExpressions()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QRegularExpression::PatternOptions>("patternOptions");
-
- QTest::newRow("emptynull01") << QString()
- << QRegularExpression::PatternOptions(0);
- QTest::newRow("emptynull02") << QString()
- << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
- | QRegularExpression::DotMatchesEverythingOption
- | QRegularExpression::MultilineOption);
- QTest::newRow("emptynull03") << ""
- << QRegularExpression::PatternOptions(0);
- QTest::newRow("emptynull04") << ""
- << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
- | QRegularExpression::DotMatchesEverythingOption
- | QRegularExpression::MultilineOption);
-
- QTest::newRow("regexp01") << "a pattern"
- << QRegularExpression::PatternOptions(0);
- QTest::newRow("regexp02") << "^a (.*) more complicated(?<P>pattern)$"
- << QRegularExpression::PatternOptions(0);
- QTest::newRow("regexp03") << "(?:a) pAttErN"
- << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption);
- QTest::newRow("regexp04") << "a\nmultiline\npattern"
- << QRegularExpression::PatternOptions(QRegularExpression::MultilineOption);
- QTest::newRow("regexp05") << "an extended # IGNOREME\npattern"
- << QRegularExpression::PatternOptions(QRegularExpression::ExtendedPatternSyntaxOption);
- QTest::newRow("regexp06") << "a [sS]ingleline .* match"
- << QRegularExpression::PatternOptions(QRegularExpression::DotMatchesEverythingOption);
- QTest::newRow("regexp07") << "multiple.*options"
- << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
- | QRegularExpression::DotMatchesEverythingOption
- | QRegularExpression::MultilineOption
- | QRegularExpression::DontCaptureOption
- | QRegularExpression::InvertedGreedinessOption);
-
- QTest::newRow("unicode01") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$")
- << QRegularExpression::PatternOptions(0);
- QTest::newRow("unicode02") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$")
- << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
- | QRegularExpression::DotMatchesEverythingOption
- | QRegularExpression::InvertedGreedinessOption);
- QTest::newRow("unicode03") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f")
- << QRegularExpression::PatternOptions(0);
- QTest::newRow("unicode04") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f")
- << QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption
- | QRegularExpression::DotMatchesEverythingOption
- | QRegularExpression::InvertedGreedinessOption);
-}
-
-void tst_QRegularExpression::defaultConstructors()
-{
- QRegularExpression re;
- QCOMPARE(re.pattern(), QString());
- QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
-
- QRegularExpressionMatch match;
- QCOMPARE(match.regularExpression(), QRegularExpression());
- QCOMPARE(match.regularExpression(), re);
- QCOMPARE(match.matchType(), QRegularExpression::NoMatch);
- QCOMPARE(match.matchOptions(), QRegularExpression::NoMatchOption);
- QCOMPARE(match.hasMatch(), false);
- QCOMPARE(match.hasPartialMatch(), false);
- QCOMPARE(match.isValid(), true);
- QCOMPARE(match.lastCapturedIndex(), -1);
-
- QRegularExpressionMatchIterator iterator;
- QCOMPARE(iterator.regularExpression(), QRegularExpression());
- QCOMPARE(iterator.regularExpression(), re);
- QCOMPARE(iterator.matchType(), QRegularExpression::NoMatch);
- QCOMPARE(iterator.matchOptions(), QRegularExpression::NoMatchOption);
- QCOMPARE(iterator.isValid(), true);
- QCOMPARE(iterator.hasNext(), false);
-}
-
-void tst_QRegularExpression::gettersSetters_data()
-{
- provideRegularExpressions();
-}
-
-void tst_QRegularExpression::gettersSetters()
-{
- QFETCH(QString, pattern);
- QFETCH(QRegularExpression::PatternOptions, patternOptions);
- {
- QRegularExpression re;
- re.setPattern(pattern);
- QCOMPARE(re.pattern(), pattern);
- QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
- }
- {
- QRegularExpression re;
- re.setPatternOptions(patternOptions);
- QCOMPARE(re.pattern(), QString());
- QCOMPARE(re.patternOptions(), patternOptions);
- }
- {
- QRegularExpression re(pattern);
- QCOMPARE(re.pattern(), pattern);
- QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
- }
- {
- QRegularExpression re(pattern, patternOptions);
- QCOMPARE(re.pattern(), pattern);
- QCOMPARE(re.patternOptions(), patternOptions);
- }
-}
-
-void tst_QRegularExpression::escape_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<QString>("escaped");
- QTest::newRow("escape01") << "a normal pattern"
- << "a\\ normal\\ pattern";
-
- QTest::newRow("escape02") << "abcdefghijklmnopqrstuvzABCDEFGHIJKLMNOPQRSTUVZ1234567890_"
- << "abcdefghijklmnopqrstuvzABCDEFGHIJKLMNOPQRSTUVZ1234567890_";
-
- QTest::newRow("escape03") << "^\\ba\\b.*(?<NAME>reg|exp)$"
- << "\\^\\\\ba\\\\b\\.\\*\\(\\?\\<NAME\\>reg\\|exp\\)\\$";
-
- QString nulString("abcXabcXXabc");
- nulString[3] = nulString[7] = nulString[8] = QChar(0, 0);
- QTest::newRow("NUL") << nulString
- << "abc\\0abc\\0\\0abc";
-
- QTest::newRow("unicode01") << QString::fromUtf8("^s[ome] latin-1 \xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99 chars$")
- << QString::fromUtf8("\\^s\\[ome\\]\\ latin\\-1\\ \\\xc3\x80\\\xc3\x88\\\xc3\x8c\\\xc3\x92\\\xc3\x99\\ chars\\$");
- QTest::newRow("unicode02") << QString::fromUtf8("Unicode \xf0\x9d\x85\x9d \xf0\x9d\x85\x9e\xf0\x9d\x85\x9f")
- << QString::fromUtf8("Unicode\\ \\\xf0\x9d\x85\x9d\\ \\\xf0\x9d\x85\x9e\\\xf0\x9d\x85\x9f");
-
- QString unicodeAndNulString = QString::fromUtf8("^\xc3\x80\xc3\x88\xc3\x8cN\xc3\x92NN\xc3\x99 chars$");
- unicodeAndNulString[4] = unicodeAndNulString[6] = unicodeAndNulString[7] = QChar(0, 0);
- QTest::newRow("unicode03") << unicodeAndNulString
- << QString::fromUtf8("\\^\\\xc3\x80\\\xc3\x88\\\xc3\x8c\\0\\\xc3\x92\\0\\0\\\xc3\x99\\ chars\\$");
-}
-
-void tst_QRegularExpression::escape()
-{
- QFETCH(QString, string);
- QFETCH(QString, escaped);
- QCOMPARE(QRegularExpression::escape(string), escaped);
- QRegularExpression re(escaped);
- QCOMPARE(re.isValid(), true);
-}
-
-void tst_QRegularExpression::validity_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<bool>("validity");
-
- QTest::newRow("valid01") << "a pattern" << true;
- QTest::newRow("valid02") << "(a|pattern)" << true;
- QTest::newRow("valid03") << "a [pP]attern" << true;
- QTest::newRow("valid04") << "^(?<article>a).*(?<noun>pattern)$" << true;
- QTest::newRow("valid05") << "a \\P{Ll}attern" << true;
-
- QTest::newRow("invalid01") << "a pattern\\" << false;
- QTest::newRow("invalid02") << "(a|pattern" << false;
- QTest::newRow("invalid03") << "a \\P{BLAH}attern" << false;
-
- QString pattern;
- // 0xD800 (high surrogate) not followed by a low surrogate
- pattern = "abcdef";
- pattern[3] = QChar(0x00, 0xD8);
- QTest::newRow("invalidUnicode01") << pattern << false;
-}
-
-void tst_QRegularExpression::validity()
-{
- QFETCH(QString, pattern);
- QFETCH(bool, validity);
- QRegularExpression re(pattern);
- QCOMPARE(re.isValid(), validity);
- if (!validity)
- QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
- QRegularExpressionMatch match = re.match("a pattern");
- QCOMPARE(match.isValid(), validity);
- consistencyCheck(match);
-
- if (!validity)
- QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
- QRegularExpressionMatchIterator iterator = re.globalMatch("a pattern");
- QCOMPARE(iterator.isValid(), validity);
-}
-
-void tst_QRegularExpression::patternOptions_data()
-{
- QTest::addColumn<QRegularExpression>("regexp");
- QTest::addColumn<QString>("subject");
- QTest::addColumn<Match>("match");
-
- // none of these would successfully match if the respective
- // pattern option is not set
-
- Match m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << QString::fromUtf8("AbC\xc3\xa0");
- QTest::newRow("/i") << QRegularExpression(QString::fromUtf8("abc\xc3\x80"), QRegularExpression::CaseInsensitiveOption)
- << QString::fromUtf8("AbC\xc3\xa0")
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "abc123\n678def";
- QTest::newRow("/s") << QRegularExpression("\\Aabc.*def\\z", QRegularExpression::DotMatchesEverythingOption)
- << "abc123\n678def"
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "jumped over";
- QTest::newRow("/m") << QRegularExpression("^\\w+ \\w+$", QRegularExpression::MultilineOption)
- << "the quick fox\njumped over\nthe lazy\ndog"
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "abc 123456";
- QTest::newRow("/x") << QRegularExpression("\\w+ # a word\n"
- "\\ # a space\n"
- "\\w+ # another word",
- QRegularExpression::ExtendedPatternSyntaxOption)
- << "abc 123456 def"
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "the quick fox" << "the" << "quick fox";
- QTest::newRow("/U") << QRegularExpression("(.+) (.+?)", QRegularExpression::InvertedGreedinessOption)
- << "the quick fox"
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "the quick fox" << "quick";
- m.namedCaptured["named"] = "quick";
- QTest::newRow("no cap") << QRegularExpression("(\\w+) (?<named>\\w+) (\\w+)", QRegularExpression::DontCaptureOption)
- << "the quick fox"
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << QString::fromUtf8("abc\xc3\x80\xc3\xa0 12\xdb\xb1\xdb\xb2\xf0\x9d\x9f\x98")
- << QString::fromUtf8("abc\xc3\x80\xc3\xa0")
- << QString::fromUtf8("12\xdb\xb1\xdb\xb2\xf0\x9d\x9f\x98");
- QTest::newRow("unicode properties") << QRegularExpression("(\\w+) (\\d+)", QRegularExpression::UseUnicodePropertiesOption)
- << QString::fromUtf8("abc\xc3\x80\xc3\xa0 12\xdb\xb1\xdb\xb2\xf0\x9d\x9f\x98")
- << m;
-}
-
-void tst_QRegularExpression::patternOptions()
-{
- QFETCH(QRegularExpression, regexp);
- QFETCH(QString, subject);
- QFETCH(Match, match);
-
- QRegularExpressionMatch m = regexp.match(subject);
- consistencyCheck(m);
- QVERIFY(m == match);
-}
-
-void tst_QRegularExpression::normalMatch_data()
-{
- QTest::addColumn<QRegularExpression>("regexp");
- QTest::addColumn<QString>("subject");
- QTest::addColumn<int>("offset");
- QTest::addColumn<QRegularExpression::MatchOptions>("matchOptions");
- QTest::addColumn<Match>("match");
-
- Match m;
- int offset = 0;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "string" << "string";
- QTest::newRow("match01") << QRegularExpression("(\\bstring\\b)")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "a string" << "a" << "string";
- QTest::newRow("match02") << QRegularExpression("(\\w+) (\\w+)")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "a string" << "a" << "string";
- m.namedCaptured["article"] = "a";
- m.namedCaptured["noun"] = "string";
- QTest::newRow("match03") << QRegularExpression("(?<article>\\w+) (?<noun>\\w+)")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << " string" << QString() << "string";
- QTest::newRow("match04") << QRegularExpression("(\\w+)? (\\w+)")
- << " string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << " string" << QString("") << "string";
- QTest::newRow("match05") << QRegularExpression("(\\w*) (\\w+)")
- << " string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "c123def" << "c12" << "3" << "def";
- offset = 2;
- for (int i = 0; i <= offset; ++i) {
- QTest::newRow(("match06-offset" + QByteArray::number(i)).constData())
- << QRegularExpression("(\\w*)(\\d+)(\\w*)")
- << QStringLiteral("abc123def").mid(offset - i)
- << i
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
- }
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << QString("");
- offset = 9;
- for (int i = 0; i <= offset; ++i) {
- QTest::newRow(("match07-offset" + QByteArray::number(i)).constData())
- << QRegularExpression("\\w*")
- << QStringLiteral("abc123def").mid(offset - i)
- << i
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
- }
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << QString("a string") << QString("a string") << QString("");
- QTest::newRow("match08") << QRegularExpression("(.*)(.*)")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << QString("a string") << QString("") << QString("a string");
- QTest::newRow("match09") << QRegularExpression("(.*?)(.*)")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- // non existing names for capturing groups
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "a string" << "a" << "string";
- m.namedCaptured["article"] = "a";
- m.namedCaptured["noun"] = "string";
- m.namedCaptured["nonexisting1"] = QString();
- m.namedCaptured["nonexisting2"] = QString();
- m.namedCaptured["nonexisting3"] = QString();
- QTest::newRow("match10") << QRegularExpression("(?<article>\\w+) (?<noun>\\w+)")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "" << "";
- m.namedCaptured["digits"] = ""; // empty VS null
- m.namedCaptured["nonexisting"] = QString();
- QTest::newRow("match11") << QRegularExpression("(?<digits>\\d*)")
- << "abcde"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- // ***
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "bcd";
- QTest::newRow("match12")
- << QRegularExpression("\\Bbcd\\B")
- << "abcde"
- << 1
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- // ***
-
- m.clear();
- m.isValid = true;
- QTest::newRow("nomatch01") << QRegularExpression("\\d+")
- << "a string"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true;
- offset = 1;
- for (int i = 0; i <= offset; ++i) {
- QTest::newRow(("nomatch02-offset" + QByteArray::number(i)).constData())
- << QRegularExpression("(\\w+) (\\w+)")
- << QStringLiteral("a string").mid(offset - i)
- << i
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
- }
-
- m.clear();
- m.isValid = true;
- offset = 9;
- for (int i = 0; i <= offset; ++i) {
- QTest::newRow(("nomatch03-offset" + QByteArray::number(i)).constData())
- << QRegularExpression("\\w+")
- << QStringLiteral("abc123def").mid(offset - i)
- << i
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
- }
-
- // ***
-
- m.clear();
- m.isValid = true;
- QTest::newRow("anchoredmatch01") << QRegularExpression("\\d+")
- << "abc123def"
- << 0
- << QRegularExpression::MatchOptions(QRegularExpression::AnchoredMatchOption)
- << m;
-
- // ***
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "678";
- QTest::newRow("negativeoffset01") << QRegularExpression("\\d+")
- << "abc123def678ghi"
- << -6
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "678";
- QTest::newRow("negativeoffset02") << QRegularExpression("\\d+")
- << "abc123def678ghi"
- << -8
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "678ghi" << "678" << "ghi";
- QTest::newRow("negativeoffset03") << QRegularExpression("(\\d+)(\\w+)")
- << "abc123def678ghi"
- << -8
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true;
- QTest::newRow("negativeoffset04") << QRegularExpression("\\d+")
- << "abc123def678ghi"
- << -3
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "678";
- QTest::newRow("negativeoffset05") << QRegularExpression("^\\d+", QRegularExpression::MultilineOption)
- << "a\nbc123\ndef\n678gh\ni"
- << -10
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-}
-
-
-void tst_QRegularExpression::normalMatch()
-{
- QFETCH(QRegularExpression, regexp);
- QFETCH(QString, subject);
- QFETCH(int, offset);
- QFETCH(QRegularExpression::MatchOptions, matchOptions);
- QFETCH(Match, match);
-
- testMatch<QRegularExpressionMatch>(regexp,
- static_cast<QREMatchStringPMF>(&QRegularExpression::match),
- static_cast<QREMatchStringRefPMF>(&QRegularExpression::match),
- subject,
- offset,
- QRegularExpression::NormalMatch,
- matchOptions,
- match);
-}
-
-void tst_QRegularExpression::partialMatch_data()
-{
- QTest::addColumn<QRegularExpression>("regexp");
- QTest::addColumn<QString>("subject");
- QTest::addColumn<int>("offset");
- QTest::addColumn<QRegularExpression::MatchType>("matchType");
- QTest::addColumn<QRegularExpression::MatchOptions>("matchOptions");
- QTest::addColumn<Match>("match");
-
- Match m;
- int offset = 0;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "str";
- QTest::newRow("softmatch01") << QRegularExpression("string")
- << "a str"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << " str";
- QTest::newRow("softmatch02") << QRegularExpression("\\bstring\\b")
- << "a str"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << " str";
- QTest::newRow("softmatch03") << QRegularExpression("(\\bstring\\b)")
- << "a str"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "8 Dec 19";
- QTest::newRow("softmatch04") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
- << "8 Dec 19"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "8 Dec 1985" << "8" << "Dec" << "1985";
- QTest::newRow("softmatch05") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
- << "8 Dec 1985"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured << "def";
- QTest::newRow("softmatch06") << QRegularExpression("abc\\w+X|def")
- << "abcdef"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "abcdef";
- QTest::newRow("softmatch07") << QRegularExpression("abc\\w+X|defY")
- << "abcdef"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "def";
- offset = 1;
- for (int i = 0; i <= offset; ++i) {
- QTest::newRow(("softmatch08-offset" + QByteArray::number(i)).constData())
- << QRegularExpression("abc\\w+X|defY")
- << QStringLiteral("abcdef").mid(offset - i)
- << i
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
- }
-
- // ***
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "str";
- QTest::newRow("hardmatch01") << QRegularExpression("string")
- << "a str"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << " str";
- QTest::newRow("hardmatch02") << QRegularExpression("\\bstring\\b")
- << "a str"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << " str";
- QTest::newRow("hardmatch03") << QRegularExpression("(\\bstring\\b)")
- << "a str"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "8 Dec 19";
- QTest::newRow("hardmatch04") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
- << "8 Dec 19"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "8 Dec 1985";
- QTest::newRow("hardmatch05") << QRegularExpression("^(\\d{1,2}) (\\w{3}) (\\d{4})$")
- << "8 Dec 1985"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "abcdef";
- QTest::newRow("hardmatch06") << QRegularExpression("abc\\w+X|def")
- << "abcdef"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "abcdef";
- QTest::newRow("hardmatch07") << QRegularExpression("abc\\w+X|defY")
- << "abcdef"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "def";
- offset = 1;
- for (int i = 0; i <= offset; ++i) {
- QTest::newRow(("hardmatch08-offset" + QByteArray::number(i)).constData())
- << QRegularExpression("abc\\w+X|defY")
- << QStringLiteral("abcdef").mid(offset - i)
- << i
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
- }
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "ab";
- QTest::newRow("hardmatch09") << QRegularExpression("abc|ab")
- << "ab"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "abc";
- QTest::newRow("hardmatch10") << QRegularExpression("abc(def)?")
- << "abc"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true; m.hasPartialMatch = true;
- m.captured << "abc";
- QTest::newRow("hardmatch11") << QRegularExpression("(abc)*")
- << "abc"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
-
- // ***
-
- m.clear();
- m.isValid = true;
- QTest::newRow("nomatch01") << QRegularExpression("abc\\w+X|defY")
- << "123456"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true;
- QTest::newRow("nomatch02") << QRegularExpression("abc\\w+X|defY")
- << "123456"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true;
- QTest::newRow("nomatch03") << QRegularExpression("abc\\w+X|defY")
- << "ab123"
- << 0
- << QRegularExpression::PartialPreferCompleteMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
- m.clear();
- m.isValid = true;
- QTest::newRow("nomatch04") << QRegularExpression("abc\\w+X|defY")
- << "ab123"
- << 0
- << QRegularExpression::PartialPreferFirstMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << m;
-
-}
-
-void tst_QRegularExpression::partialMatch()
-{
- QFETCH(QRegularExpression, regexp);
- QFETCH(QString, subject);
- QFETCH(int, offset);
- QFETCH(QRegularExpression::MatchType, matchType);
- QFETCH(QRegularExpression::MatchOptions, matchOptions);
- QFETCH(Match, match);
-
- testMatch<QRegularExpressionMatch>(regexp,
- static_cast<QREMatchStringPMF>(&QRegularExpression::match),
- static_cast<QREMatchStringRefPMF>(&QRegularExpression::match),
- subject,
- offset,
- matchType,
- matchOptions,
- match);
-}
-
-void tst_QRegularExpression::globalMatch_data()
-{
- QTest::addColumn<QRegularExpression>("regexp");
- QTest::addColumn<QString>("subject");
- QTest::addColumn<int>("offset");
- QTest::addColumn<QRegularExpression::MatchType>("matchType");
- QTest::addColumn<QRegularExpression::MatchOptions>("matchOptions");
- QTest::addColumn<QVector<Match> >("matchList");
-
- QVector<Match> matchList;
- Match m;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the";
- matchList << m;
- m.captured = QStringList() << "quick";
- matchList << m;
- m.captured = QStringList() << "fox";
- matchList << m;
- QTest::newRow("globalmatch01") << QRegularExpression("\\w+")
- << "the quick fox"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the" << "t" << "he";
- matchList << m;
- m.captured = QStringList() << "quick" << "q" << "uick";
- matchList << m;
- m.captured = QStringList() << "fox" << "f" << "ox";
- matchList << m;
- QTest::newRow("globalmatch02") << QRegularExpression("(\\w+?)(\\w+)")
- << "the quick fox"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "ACA""GTG""CGA""AAA";
- matchList << m;
- m.captured = QStringList() << "AAA";
- matchList << m;
- m.captured = QStringList() << "AAG""GAA""AAG""AAA";
- matchList << m;
- m.captured = QStringList() << "AAA";
- matchList << m;
- QTest::newRow("globalmatch03") << QRegularExpression("\\G(?:\\w\\w\\w)*?AAA")
- << "ACA""GTG""CGA""AAA""AAA""AAG""GAA""AAG""AAA""AAA"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- QTest::newRow("globalmatch04") << QRegularExpression("(?:\\w\\w\\w)*?AAA")
- << "ACA""GTG""CGA""AAA""AAA""AAG""GAA""AAG""AAA""AAA"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::AnchoredMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "c";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "c";
- matchList << m;
- m.captured = QStringList() << "aabb";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
-
- QTest::newRow("globalmatch_emptycaptures01") << QRegularExpression("a*b*|c")
- << "ccaabbd"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "quick";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "fox";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
-
- QTest::newRow("globalmatch_emptycaptures02") << QRegularExpression(".*")
- << "the\nquick\nfox"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "quick";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "fox";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
-
- QTest::newRow("globalmatch_emptycaptures03") << QRegularExpression(".*")
- << "the\nquick\nfox\n"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "quick";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "fox";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
-
- QTest::newRow("globalmatch_emptycaptures04") << QRegularExpression("(*CRLF).*")
- << "the\r\nquick\r\nfox"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "quick";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "fox";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
-
- QTest::newRow("globalmatch_emptycaptures05") << QRegularExpression("(*CRLF).*")
- << "the\r\nquick\r\nfox\r\n"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "the";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "quick";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "fox";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "jumped";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
-
- QTest::newRow("globalmatch_emptycaptures06") << QRegularExpression("(*ANYCRLF).*")
- << "the\r\nquick\nfox\rjumped"
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << "ABC";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "DEF";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << "GHI";
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- QTest::newRow("globalmatch_emptycaptures07") << QRegularExpression("[\\x{0000}-\\x{FFFF}]*")
- << QString::fromUtf8("ABC""\xf0\x9d\x85\x9d""DEF""\xf0\x9d\x85\x9e""GHI")
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-
- matchList.clear();
- m.clear();
- m.isValid = true; m.hasMatch = true;
- m.captured = QStringList() << QString::fromUtf8("ABC""\xc3\x80");
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- m.captured = QStringList() << QString::fromUtf8("\xc3\x80""DEF""\xc3\x80");
- matchList << m;
- m.captured = QStringList() << "";
- matchList << m;
- QTest::newRow("globalmatch_emptycaptures08") << QRegularExpression("[\\x{0000}-\\x{FFFF}]*")
- << QString::fromUtf8("ABC""\xc3\x80""\xf0\x9d\x85\x9d""\xc3\x80""DEF""\xc3\x80")
- << 0
- << QRegularExpression::NormalMatch
- << QRegularExpression::MatchOptions(QRegularExpression::NoMatchOption)
- << matchList;
-}
-
-void tst_QRegularExpression::globalMatch()
-{
- QFETCH(QRegularExpression, regexp);
- QFETCH(QString, subject);
- QFETCH(int, offset);
- QFETCH(QRegularExpression::MatchType, matchType);
- QFETCH(QRegularExpression::MatchOptions, matchOptions);
- QFETCH(QVector<Match>, matchList);
-
- testMatch<QRegularExpressionMatchIterator>(regexp,
- static_cast<QREGlobalMatchStringPMF>(&QRegularExpression::globalMatch),
- static_cast<QREGlobalMatchStringRefPMF>(&QRegularExpression::globalMatch),
- subject,
- offset,
- matchType,
- matchOptions,
- matchList);
-}
-
-void tst_QRegularExpression::serialize_data()
-{
- provideRegularExpressions();
-}
-
-void tst_QRegularExpression::serialize()
-{
- QFETCH(QString, pattern);
- QFETCH(QRegularExpression::PatternOptions, patternOptions);
- QRegularExpression outRe(pattern, patternOptions);
-
- QByteArray buffer;
- {
- QDataStream out(&buffer, QIODevice::WriteOnly);
- out << outRe;
- }
- QRegularExpression inRe;
- {
- QDataStream in(&buffer, QIODevice::ReadOnly);
- in >> inRe;
- }
- QCOMPARE(inRe, outRe);
-}
-
-static void verifyEquality(const QRegularExpression &re1, const QRegularExpression &re2)
-{
- QVERIFY(re1 == re2);
- QVERIFY(re2 == re1);
- QCOMPARE(qHash(re1), qHash(re2));
- QVERIFY(!(re1 != re2));
- QVERIFY(!(re2 != re1));
-
- QRegularExpression re3(re1);
-
- QVERIFY(re1 == re3);
- QVERIFY(re3 == re1);
- QCOMPARE(qHash(re1), qHash(re3));
- QVERIFY(!(re1 != re3));
- QVERIFY(!(re3 != re1));
-
- QVERIFY(re2 == re3);
- QVERIFY(re3 == re2);
- QCOMPARE(qHash(re2), qHash(re3));
- QVERIFY(!(re2 != re3));
- QVERIFY(!(re3 != re2));
-
- re3 = re2;
- QVERIFY(re1 == re3);
- QVERIFY(re3 == re1);
- QCOMPARE(qHash(re1), qHash(re3));
- QVERIFY(!(re1 != re3));
- QVERIFY(!(re3 != re1));
-
- QVERIFY(re2 == re3);
- QVERIFY(re3 == re2);
- QCOMPARE(qHash(re2), qHash(re3));
- QVERIFY(!(re2 != re3));
- QVERIFY(!(re3 != re2));
-}
-
-void tst_QRegularExpression::operatoreq_data()
-{
- provideRegularExpressions();
-}
-
-void tst_QRegularExpression::operatoreq()
-{
- QFETCH(QString, pattern);
- QFETCH(QRegularExpression::PatternOptions, patternOptions);
- {
- QRegularExpression re1(pattern);
- QRegularExpression re2(pattern);
-
- verifyEquality(re1, re2);
- }
- {
- QRegularExpression re1(QString(), patternOptions);
- QRegularExpression re2(QString(), patternOptions);
-
- verifyEquality(re1, re2);
- }
- {
- QRegularExpression re1(pattern, patternOptions);
- QRegularExpression re2(pattern, patternOptions);
-
- verifyEquality(re1, re2);
- }
-}
-
-void tst_QRegularExpression::captureCount_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<int>("captureCount");
- QTest::newRow("captureCount01") << "a pattern" << 0;
- QTest::newRow("captureCount02") << "a.*pattern" << 0;
- QTest::newRow("captureCount03") << "(a) pattern" << 1;
- QTest::newRow("captureCount04") << "(a).*(pattern)" << 2;
- QTest::newRow("captureCount05") << "^(?<article>\\w+) (?<noun>\\w+)$" << 2;
- QTest::newRow("captureCount06") << "^(\\w+) (?<word>\\w+) (.)$" << 3;
- QTest::newRow("captureCount07") << "(?:non capturing) (capturing) (?<n>named) (?:non (capturing))" << 3;
- QTest::newRow("captureCount08") << "(?|(a)(b)|(c)(d))" << 2;
- QTest::newRow("captureCount09") << "(?|(a)(b)|(c)(d)(?:e))" << 2;
- QTest::newRow("captureCount10") << "(?|(a)(b)|(c)(d)(e)) (f)(g)" << 5;
- QTest::newRow("captureCount11") << "(?|(a)(b)|(c)(d)(e)) (f)(?:g)" << 4;
- QTest::newRow("captureCount_invalid01") << "(.*" << -1;
- QTest::newRow("captureCount_invalid02") << "\\" << -1;
- QTest::newRow("captureCount_invalid03") << "(?<noun)" << -1;
-}
-
-void tst_QRegularExpression::captureCount()
-{
- QFETCH(QString, pattern);
- QRegularExpression re(pattern);
-
- QTEST(re.captureCount(), "captureCount");
- if (!re.isValid())
- QCOMPARE(re.captureCount(), -1);
-}
-
-// the comma in the template breaks QFETCH...
-typedef QMultiHash<QString, int> StringToIntMap;
-Q_DECLARE_METATYPE(StringToIntMap)
-
-void tst_QRegularExpression::captureNames_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<StringToIntMap>("namedCapturesIndexMap");
- StringToIntMap map;
-
- QTest::newRow("captureNames01") << "a pattern" << map;
- QTest::newRow("captureNames02") << "a.*pattern" << map;
- QTest::newRow("captureNames03") << "(a) pattern" << map;
- QTest::newRow("captureNames04") << "(a).*(pattern)" << map;
-
- map.clear();
- map.replace("named", 1);
- QTest::newRow("captureNames05") << "a.*(?<named>pattern)" << map;
-
- map.clear();
- map.replace("named", 2);
- QTest::newRow("captureNames06") << "(a).*(?<named>pattern)" << map;
-
- map.clear();
- map.replace("name1", 1);
- map.replace("name2", 2);
- QTest::newRow("captureNames07") << "(?<name1>a).*(?<name2>pattern)" << map;
-
- map.clear();
- map.replace("name1", 2);
- map.replace("name2", 1);
- QTest::newRow("captureNames08") << "(?<name2>a).*(?<name1>pattern)" << map;
-
- map.clear();
- map.replace("date", 1);
- map.replace("month", 2);
- map.replace("year", 3);
- QTest::newRow("captureNames09") << "^(?<date>\\d\\d)/(?<month>\\d\\d)/(?<year>\\d\\d\\d\\d)$" << map;
-
- map.clear();
- map.replace("date", 2);
- map.replace("month", 1);
- map.replace("year", 3);
- QTest::newRow("captureNames10") << "^(?<month>\\d\\d)/(?<date>\\d\\d)/(?<year>\\d\\d\\d\\d)$" << map;
-
- map.clear();
- map.replace("noun", 2);
- QTest::newRow("captureNames11") << "(a)(?|(?<noun>b)|(?<noun>c))(d)" << map;
-
- map.clear();
- QTest::newRow("captureNames_invalid01") << "(.*" << map;
- QTest::newRow("captureNames_invalid02") << "\\" << map;
- QTest::newRow("captureNames_invalid03") << "(?<noun)" << map;
- QTest::newRow("captureNames_invalid04") << "(?|(?<noun1>a)|(?<noun2>b))" << map;
-}
-
-void tst_QRegularExpression::captureNames()
-{
- QFETCH(QString, pattern);
- QFETCH(StringToIntMap, namedCapturesIndexMap);
-
- QRegularExpression re(pattern);
-
- QStringList namedCaptureGroups = re.namedCaptureGroups();
- int namedCaptureGroupsCount = namedCaptureGroups.size();
-
- QCOMPARE(namedCaptureGroupsCount, re.captureCount() + 1);
-
- for (int i = 0; i < namedCaptureGroupsCount; ++i) {
- const QString &name = namedCaptureGroups.at(i);
-
- if (name.isEmpty()) {
- QVERIFY(!namedCapturesIndexMap.contains(name));
- } else {
- QVERIFY(namedCapturesIndexMap.contains(name));
- QCOMPARE(i, namedCapturesIndexMap.value(name));
- }
- }
-
-}
-
-void tst_QRegularExpression::pcreJitStackUsage_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QString>("subject");
- // these patterns cause enough backtrack (or even infinite recursion)
- // in the regexp engine, so that JIT requests more memory.
- QTest::newRow("jitstack01") << "(?(R)a*(?1)|((?R))b)" << "aaaabcde";
- QTest::newRow("jitstack02") << "(?(R)a*(?1)|((?R))b)" << "aaaaaaabcde";
-}
-
-void tst_QRegularExpression::pcreJitStackUsage()
-{
- QFETCH(QString, pattern);
- QFETCH(QString, subject);
-
- QRegularExpression re(pattern);
-
- QVERIFY(re.isValid());
- QRegularExpressionMatch match = re.match(subject);
- consistencyCheck(match);
- QRegularExpressionMatchIterator iterator = re.globalMatch(subject);
- consistencyCheck(iterator);
- while (iterator.hasNext()) {
- match = iterator.next();
- consistencyCheck(match);
- }
-}
-
-void tst_QRegularExpression::regularExpressionMatch_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QString>("subject");
-
- QTest::newRow("validity01") << "(?<digits>\\d+)" << "1234 abcd";
- QTest::newRow("validity02") << "(?<digits>\\d+) (?<alpha>\\w+)" << "1234 abcd";
-}
-
-void tst_QRegularExpression::regularExpressionMatch()
-{
- QFETCH(QString, pattern);
- QFETCH(QString, subject);
-
- QRegularExpression re(pattern);
-
- QVERIFY(re.isValid());
- QRegularExpressionMatch match = re.match(subject);
- consistencyCheck(match);
- QCOMPARE(match.captured("non-existing").isNull(), true);
- QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatch::captured: empty capturing group name passed");
- QCOMPARE(match.captured("").isNull(), true);
- QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionMatch::captured: empty capturing group name passed");
- QCOMPARE(match.captured(QString()).isNull(), true);
-}
-
-void tst_QRegularExpression::JOptionUsage_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<bool>("isValid");
- QTest::addColumn<bool>("JOptionUsed");
-
- QTest::newRow("joption-notused-01") << "a.*b" << true << false;
- QTest::newRow("joption-notused-02") << "^a(b)(c)$" << true << false;
- QTest::newRow("joption-notused-03") << "a(b)(?<c>d)|e" << true << false;
- QTest::newRow("joption-notused-04") << "(?<a>.)(?<a>.)" << false << false;
-
- QTest::newRow("joption-used-01") << "(?J)a.*b" << true << true;
- QTest::newRow("joption-used-02") << "(?-J)a.*b" << true << true;
- QTest::newRow("joption-used-03") << "(?J)(?<a>.)(?<a>.)" << true << true;
- QTest::newRow("joption-used-04") << "(?-J)(?<a>.)(?<a>.)" << false << true;
-
-}
-
-void tst_QRegularExpression::JOptionUsage()
-{
- QFETCH(QString, pattern);
- QFETCH(bool, isValid);
- QFETCH(bool, JOptionUsed);
-
- const QString warningMessage = QStringLiteral("QRegularExpressionPrivate::getPatternInfo(): the pattern '%1'\n is using the (?J) option; duplicate capturing group names are not supported by Qt");
-
- QRegularExpression re(pattern);
- if (isValid && JOptionUsed)
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warningMessage.arg(pattern)));
- QCOMPARE(re.isValid(), isValid);
-}
-
-void tst_QRegularExpression::QStringAndQStringRefEquivalence()
-{
- const QString subject = QStringLiteral("Mississippi");
- {
- const QRegularExpression re("\\Biss\\B");
- QVERIFY(re.isValid());
- {
- const QRegularExpressionMatch match = re.match(subject);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 1);
- QCOMPARE(match.capturedEnd(), 4);
- }
- {
- const QRegularExpressionMatch match = re.match(QStringRef(&subject));
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 1);
- QCOMPARE(match.capturedEnd(), 4);
- }
- {
- const QRegularExpressionMatch match = re.match(subject, 1);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 1);
- QCOMPARE(match.capturedEnd(), 4);
- }
- {
- const QRegularExpressionMatch match = re.match(QStringRef(&subject), 1);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 1);
- QCOMPARE(match.capturedEnd(), 4);
- }
- {
- const QRegularExpressionMatch match = re.match(subject.mid(1));
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
- }
- {
- const QRegularExpressionMatch match = re.match(subject.midRef(1));
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
- }
- {
- const QRegularExpressionMatch match = re.match(subject.mid(1), 1);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
- }
- {
- const QRegularExpressionMatch match = re.match(subject.midRef(1), 1);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
- }
- {
- const QRegularExpressionMatch match = re.match(subject, 4);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 4);
- QCOMPARE(match.capturedEnd(), 7);
- }
- {
- const QRegularExpressionMatch match = re.match(QStringRef(&subject), 4);
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 4);
- QCOMPARE(match.capturedEnd(), 7);
- }
- {
- const QRegularExpressionMatch match = re.match(subject.mid(4));
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(!match.hasMatch());
- }
- {
- const QRegularExpressionMatch match = re.match(subject.midRef(4));
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(!match.hasMatch());
- }
-
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match1 = i.next();
- consistencyCheck(match1);
- QVERIFY(match1.isValid());
- QVERIFY(match1.hasMatch());
- QCOMPARE(match1.captured(), QStringLiteral("iss"));
- QCOMPARE(match1.capturedStart(), 1);
- QCOMPARE(match1.capturedEnd(), 4);
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match2 = i.next();
- consistencyCheck(match2);
- QVERIFY(match2.isValid());
- QVERIFY(match2.hasMatch());
- QCOMPARE(match2.captured(), QStringLiteral("iss"));
- QCOMPARE(match2.capturedStart(), 4);
- QCOMPARE(match2.capturedEnd(), 7);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(QStringRef(&subject));
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match1 = i.next();
- consistencyCheck(match1);
- QVERIFY(match1.isValid());
- QVERIFY(match1.hasMatch());
- QCOMPARE(match1.captured(), QStringLiteral("iss"));
- QCOMPARE(match1.capturedStart(), 1);
- QCOMPARE(match1.capturedEnd(), 4);
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match2 = i.next();
- consistencyCheck(match2);
- QVERIFY(match2.isValid());
- QVERIFY(match2.hasMatch());
- QCOMPARE(match2.captured(), QStringLiteral("iss"));
- QCOMPARE(match2.capturedStart(), 4);
- QCOMPARE(match2.capturedEnd(), 7);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject, 1);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match1 = i.next();
- consistencyCheck(match1);
- QVERIFY(match1.isValid());
- QVERIFY(match1.hasMatch());
- QCOMPARE(match1.captured(), QStringLiteral("iss"));
- QCOMPARE(match1.capturedStart(), 1);
- QCOMPARE(match1.capturedEnd(), 4);
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match2 = i.next();
- consistencyCheck(match2);
- QVERIFY(match2.isValid());
- QVERIFY(match2.hasMatch());
- QCOMPARE(match2.captured(), QStringLiteral("iss"));
- QCOMPARE(match2.capturedStart(), 4);
- QCOMPARE(match2.capturedEnd(), 7);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(QStringRef(&subject), 1);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match1 = i.next();
- consistencyCheck(match1);
- QVERIFY(match1.isValid());
- QVERIFY(match1.hasMatch());
- QCOMPARE(match1.captured(), QStringLiteral("iss"));
- QCOMPARE(match1.capturedStart(), 1);
- QCOMPARE(match1.capturedEnd(), 4);
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match2 = i.next();
- consistencyCheck(match2);
- QVERIFY(match2.isValid());
- QVERIFY(match2.hasMatch());
- QCOMPARE(match2.captured(), QStringLiteral("iss"));
- QCOMPARE(match2.capturedStart(), 4);
- QCOMPARE(match2.capturedEnd(), 7);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(1));
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.midRef(1));
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(1), 1);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.midRef(1), 1);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(1), 1);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.midRef(1), 1);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 3);
- QCOMPARE(match.capturedEnd(), 6);
-
- QVERIFY(!i.hasNext());
- }
-
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject, 4);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 4);
- QCOMPARE(match.capturedEnd(), 7);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(QStringRef(&subject), 4);
- QVERIFY(i.isValid());
-
- consistencyCheck(i);
- QVERIFY(i.hasNext());
- const QRegularExpressionMatch match = i.next();
- consistencyCheck(match);
- QVERIFY(match.isValid());
- QVERIFY(match.hasMatch());
- QCOMPARE(match.captured(), QStringLiteral("iss"));
- QCOMPARE(match.capturedStart(), 4);
- QCOMPARE(match.capturedEnd(), 7);
-
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.mid(4));
- consistencyCheck(i);
- QVERIFY(i.isValid());
- QVERIFY(!i.hasNext());
- }
- {
- QRegularExpressionMatchIterator i = re.globalMatch(subject.midRef(4));
- consistencyCheck(i);
- QVERIFY(i.isValid());
- QVERIFY(!i.hasNext());
- }
- }
-}
-
-class MatcherThread : public QThread
-{
-public:
- explicit MatcherThread(const QRegularExpression &re, const QString &subject, QObject *parent = nullptr)
- : QThread(parent),
- m_re(re),
- m_subject(subject)
- {
- }
-
-private:
- static const int MATCH_ITERATIONS = 50;
-
- void run() override
- {
- yieldCurrentThread();
- for (int i = 0; i < MATCH_ITERATIONS; ++i)
- m_re.match(m_subject);
- }
-
- const QRegularExpression &m_re;
- const QString &m_subject;
-};
-
-void tst_QRegularExpression::threadSafety_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QString>("subject");
-
- int i = 0;
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcd";
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abd";
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abbbbcccd";
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abababcd";
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcabcd";
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abccccccababd";
-
- {
- QString subject(512*1024, QLatin1Char('x'));
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
- }
-
- // pcre2 does not support JIT for winrt. As this test row takes a long time without JIT we skip
- // it for winrt as it might time out in COIN.
-#ifndef Q_OS_WINRT
- {
- QString subject = "ab";
- subject.append(QString(512*1024, QLatin1Char('x')));
- subject.append("c");
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
- }
-#endif // Q_OS_WINRT
-
- {
- QString subject = "ab";
- subject.append(QString(512*1024, QLatin1Char('x')));
- subject.append("cd");
- QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
- }
-
- QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaabcde";
- QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaaaaabcde";
-}
-
-void tst_QRegularExpression::threadSafety()
-{
- QFETCH(QString, pattern);
- QFETCH(QString, subject);
-
- QElapsedTimer time;
- time.start();
- static const int THREAD_SAFETY_ITERATIONS = 50;
- const int threadCount = qMax(QThread::idealThreadCount(), 4);
-
- for (int threadSafetyIteration = 0; threadSafetyIteration < THREAD_SAFETY_ITERATIONS && time.elapsed() < 2000; ++threadSafetyIteration) {
- QRegularExpression re(pattern);
-
- QVector<MatcherThread *> threads;
- for (int i = 0; i < threadCount; ++i) {
- MatcherThread *thread = new MatcherThread(re, subject);
- thread->start();
- threads.push_back(thread);
- }
-
- for (int i = 0; i < threadCount; ++i)
- threads[i]->wait();
-
- qDeleteAll(threads);
- }
-}
-
-void tst_QRegularExpression::wildcard_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QString>("string");
- QTest::addColumn<int>("foundIndex");
-
- auto addRow = [](const char *pattern, const char *string, int foundIndex) {
- QTest::newRow(pattern) << pattern << string << foundIndex;
- };
-
- addRow("*.html", "test.html", 0);
- addRow("*.html", "test.htm", -1);
- addRow("*bar*", "foobarbaz", 0);
- addRow("*", "Qt Rocks!", 0);
- addRow("*.html", "test.html", 0);
- addRow("*.h", "test.cpp", -1);
- addRow("*.???l", "test.html", 0);
- addRow("*?", "test.html", 0);
- addRow("*?ml", "test.html", 0);
- addRow("*[*]", "test.html", -1);
- addRow("*[?]","test.html", -1);
- addRow("*[?]ml","test.h?ml", 0);
- addRow("*[[]ml","test.h[ml", 0);
- addRow("*[]]ml","test.h]ml", 0);
- addRow("*.h[a-z]ml", "test.html", 0);
- addRow("*.h[A-Z]ml", "test.html", -1);
- addRow("*.h[A-Z]ml", "test.hTml", 0);
- addRow("*.h[!A-Z]ml", "test.hTml", -1);
- addRow("*.h[!A-Z]ml", "test.html", 0);
- addRow("*.h[!T]ml", "test.hTml", -1);
- addRow("*.h[!T]ml", "test.html", 0);
- addRow("*.h[!T]m[!L]", "test.htmL", -1);
- addRow("*.h[!T]m[!L]", "test.html", 0);
- addRow("*.h[][!]ml", "test.h]ml", 0);
- addRow("*.h[][!]ml", "test.h[ml", 0);
- addRow("*.h[][!]ml", "test.h!ml", 0);
-
- addRow("foo/*/bar", "foo/baz/bar", 0);
- addRow("foo/(*)/bar", "foo/baz/bar", -1);
- addRow("foo/(*)/bar", "foo/(baz)/bar", 0);
- addRow("foo/?/bar", "foo/Q/bar", 0);
- addRow("foo/?/bar", "foo/Qt/bar", -1);
- addRow("foo/(?)/bar", "foo/Q/bar", -1);
- addRow("foo/(?)/bar", "foo/(Q)/bar", 0);
-
-#ifdef Q_OS_WIN
- addRow("foo\\*\\bar", "foo\\baz\\bar", 0);
- addRow("foo\\(*)\\bar", "foo\\baz\\bar", -1);
- addRow("foo\\(*)\\bar", "foo\\(baz)\\bar", 0);
- addRow("foo\\?\\bar", "foo\\Q\\bar", 0);
- addRow("foo\\?\\bar", "foo\\Qt\\bar", -1);
- addRow("foo\\(?)\\bar", "foo\\Q\\bar", -1);
- addRow("foo\\(?)\\bar", "foo\\(Q)\\bar", 0);
-#endif
-}
-
-void tst_QRegularExpression::wildcard()
-{
- QFETCH(QString, pattern);
- QFETCH(QString, string);
- QFETCH(int, foundIndex);
-
- QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
- QRegularExpressionMatch match = re.match(string);
-
- QCOMPARE(match.capturedStart(), foundIndex);
-}
-
-void tst_QRegularExpression::testInvalidWildcard_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<bool>("isValid");
-
- QTest::newRow("valid []") << "[abc]" << true;
- QTest::newRow("valid ending ]") << "abc]" << true;
- QTest::newRow("invalid [") << "[abc" << false;
- QTest::newRow("ending [") << "abc[" << false;
- QTest::newRow("ending [^") << "abc[^" << false;
- QTest::newRow("ending [\\") << "abc[\\" << false;
- QTest::newRow("ending []") << "abc[]" << false;
- QTest::newRow("ending [[") << "abc[[" << false;
-}
-
-void tst_QRegularExpression::testInvalidWildcard()
-{
- QFETCH(QString, pattern);
- QFETCH(bool, isValid);
-
- QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
- QCOMPARE(re.isValid(), isValid);
-}
-
-QTEST_APPLESS_MAIN(tst_QRegularExpression)
-
-#include "tst_qregularexpression.moc"
diff --git a/tests/auto/corelib/tools/qringbuffer/CMakeLists.txt b/tests/auto/corelib/tools/qringbuffer/CMakeLists.txt
new file mode 100644
index 0000000000..cfb7c6f461
--- /dev/null
+++ b/tests/auto/corelib/tools/qringbuffer/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qringbuffer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qringbuffer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qringbuffer
+ SOURCES
+ tst_qringbuffer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qringbuffer/qringbuffer.pro b/tests/auto/corelib/tools/qringbuffer/qringbuffer.pro
deleted file mode 100644
index c63544035a..0000000000
--- a/tests/auto/corelib/tools/qringbuffer/qringbuffer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qringbuffer
-QT = core-private testlib
-SOURCES = tst_qringbuffer.cpp
diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
index e355a7fcfb..c7b79cfae1 100644
--- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
+++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
@@ -1,35 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QBuffer>
+#include <QVarLengthArray>
#include <private/qringbuffer_p.h>
-#include <qvector.h>
+#include <qlist.h>
class tst_QRingBuffer : public QObject
{
@@ -37,6 +14,7 @@ class tst_QRingBuffer : public QObject
private slots:
void constructing();
void usingInVector();
+ void usingInVarLengthArray();
void readPointerAtPositionWriteRead();
void readPointerAtPositionEmptyRead();
void readPointerAtPositionWithHead();
@@ -82,10 +60,20 @@ void tst_QRingBuffer::constructing()
void tst_QRingBuffer::usingInVector()
{
QRingBuffer ringBuffer;
- QVector<QRingBuffer> buffers;
+ std::vector<QRingBuffer> buffers;
+
+ ringBuffer.reserve(5);
+ buffers.push_back(std::move(ringBuffer));
+ QCOMPARE(buffers[0].size(), Q_INT64_C(5));
+}
+
+void tst_QRingBuffer::usingInVarLengthArray()
+{
+ QRingBuffer ringBuffer;
+ QVarLengthArray<QRingBuffer, 42> buffers;
ringBuffer.reserve(5);
- buffers.append(ringBuffer);
+ buffers.push_back(std::move(ringBuffer));
QCOMPARE(buffers[0].size(), Q_INT64_C(5));
}
diff --git a/tests/auto/corelib/tools/qscopedpointer/CMakeLists.txt b/tests/auto/corelib/tools/qscopedpointer/CMakeLists.txt
new file mode 100644
index 0000000000..7bfcfdebbf
--- /dev/null
+++ b/tests/auto/corelib/tools/qscopedpointer/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qscopedpointer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qscopedpointer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qscopedpointer
+ SOURCES
+ tst_qscopedpointer.cpp
+)
diff --git a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro
deleted file mode 100644
index 5248ad5528..0000000000
--- a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qscopedpointer
-QT = core testlib
-SOURCES = tst_qscopedpointer.cpp
diff --git a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp
index b943b04e23..3468c97f42 100644
--- a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp
+++ b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QtCore/QScopedPointer>
/*!
@@ -61,6 +36,11 @@ private Q_SLOTS:
void comparison();
void array();
// TODO instanciate on const object
+
+ // Tests for deprecated APIs
+#if QT_DEPRECATED_SINCE(6, 1)
+ void deprecatedTake();
+#endif // QT_DEPRECATED_SINCE(6, 1)
};
void tst_QScopedPointer::defaultConstructor()
@@ -160,7 +140,7 @@ public:
class SubClass : public AbstractClass
{
public:
- virtual int member() const
+ virtual int member() const override
{
return 5;
}
@@ -252,7 +232,7 @@ void tst_QScopedPointer::negationOperatorSignature()
!p;
/* The return value should be bool. */
- static_cast<bool>(!p);
+ Q_UNUSED(static_cast<bool>(!p));
}
void tst_QScopedPointer::operatorBool()
@@ -302,7 +282,7 @@ void tst_QScopedPointer::isNullSignature()
const QScopedPointer<int> p(new int(69));
/* The signature should be const and return bool. */
- static_cast<bool>(p.isNull());
+ Q_UNUSED(static_cast<bool>(p.isNull()));
}
void tst_QScopedPointer::objectSize()
@@ -327,7 +307,7 @@ struct RefCounted
~RefCounted()
{
- QVERIFY( ref.load() == 0 );
+ QVERIFY( ref.loadRelaxed() == 0 );
instanceCount.deref();
}
@@ -367,94 +347,121 @@ void scopedPointerComparisonTest(const A1 &a1, const A2 &a2, const B &b)
QVERIFY(a2 != b);
}
+// tst_QScopedPointer::comparison creates two QScopedPointers referring to the
+// same memory. This will lead to double-deletion error during cleanup if we
+// use a default QScopedPointer{Array}Deleter. This DummyDeleter does nothing,
+// so we can safely reference the same memory from multiple QScopedPointer
+// instances, and manage the memory manually.
+// That is fine for the comparison() test, because its goal is to check the
+// object's (in)equality, not the memory management
+struct DummyDeleter
+{
+ static inline void cleanup(RefCounted *) noexcept {}
+ void operator()(RefCounted *pointer) const noexcept
+ {
+ cleanup(pointer);
+ }
+};
+
void tst_QScopedPointer::comparison()
{
- QCOMPARE( RefCounted::instanceCount.load(), 0 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 0 );
{
- RefCounted *a = new RefCounted;
- RefCounted *b = new RefCounted;
+ auto a = std::make_unique<RefCounted>();
+ auto b = std::make_unique<RefCounted>();
- QCOMPARE( RefCounted::instanceCount.load(), 2 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 2 );
- QScopedPointer<RefCounted> pa1(a);
- QScopedPointer<RefCounted> pa2(a);
- QScopedPointer<RefCounted> pb(b);
+ QScopedPointer<RefCounted, DummyDeleter> pa1(a.get());
+ QScopedPointer<RefCounted, DummyDeleter> pa2(a.get());
+ QScopedPointer<RefCounted, DummyDeleter> pb(b.get());
scopedPointerComparisonTest(pa1, pa1, pb);
scopedPointerComparisonTest(pa2, pa2, pb);
scopedPointerComparisonTest(pa1, pa2, pb);
- pa2.take();
-
- QCOMPARE( RefCounted::instanceCount.load(), 2 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 2 );
}
- QCOMPARE( RefCounted::instanceCount.load(), 0 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 0 );
{
- RefCounted *a = new RefCounted[42];
- RefCounted *b = new RefCounted[43];
+ auto a = std::make_unique<RefCounted[]>(42);
+ auto b = std::make_unique<RefCounted[]>(43);
- QCOMPARE( RefCounted::instanceCount.load(), 85 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 85 );
- QScopedArrayPointer<RefCounted> pa1(a);
- QScopedArrayPointer<RefCounted> pa2(a);
- QScopedArrayPointer<RefCounted> pb(b);
+ QScopedArrayPointer<RefCounted, DummyDeleter> pa1(a.get());
+ QScopedArrayPointer<RefCounted, DummyDeleter> pa2(a.get());
+ QScopedArrayPointer<RefCounted, DummyDeleter> pb(b.get());
scopedPointerComparisonTest(pa1, pa2, pb);
- pa2.take();
-
- QCOMPARE( RefCounted::instanceCount.load(), 85 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 85 );
}
- QCOMPARE( RefCounted::instanceCount.load(), 0 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 0 );
{
- // QScopedSharedPointer is an internal helper class -- it is unsupported!
-
RefCounted *a = new RefCounted;
RefCounted *b = new RefCounted;
- QCOMPARE( RefCounted::instanceCount.load(), 2 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 2 );
QSharedDataPointer<RefCounted> pa1(a);
QSharedDataPointer<RefCounted> pa2(a);
QSharedDataPointer<RefCounted> pb(b);
- QCOMPARE( a->ref.load(), 2 );
- QCOMPARE( b->ref.load(), 1 );
- QCOMPARE( RefCounted::instanceCount.load(), 2 );
+ QCOMPARE( a->ref.loadRelaxed(), 2 );
+ QCOMPARE( b->ref.loadRelaxed(), 1 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 2 );
scopedPointerComparisonTest(pa1, pa2, pb);
- QCOMPARE( RefCounted::instanceCount.load(), 2 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 2 );
}
- QCOMPARE( RefCounted::instanceCount.load(), 0 );
+ QCOMPARE( RefCounted::instanceCount.loadRelaxed(), 0 );
}
void tst_QScopedPointer::array()
{
- int instCount = RefCounted::instanceCount.load();
+ int instCount = RefCounted::instanceCount.loadRelaxed();
{
QScopedArrayPointer<RefCounted> array;
array.reset(new RefCounted[42]);
- QCOMPARE(instCount + 42, RefCounted::instanceCount.load());
+ QCOMPARE(instCount + 42, RefCounted::instanceCount.loadRelaxed());
}
- QCOMPARE(instCount, RefCounted::instanceCount.load());
+ QCOMPARE(instCount, RefCounted::instanceCount.loadRelaxed());
{
QScopedArrayPointer<RefCounted> array(new RefCounted[42]);
- QCOMPARE(instCount + 42, RefCounted::instanceCount.load());
+ QCOMPARE(instCount + 42, RefCounted::instanceCount.loadRelaxed());
array.reset(new RefCounted[28]);
- QCOMPARE(instCount + 28, RefCounted::instanceCount.load());
+ QCOMPARE(instCount + 28, RefCounted::instanceCount.loadRelaxed());
array.reset(0);
- QCOMPARE(instCount, RefCounted::instanceCount.load());
+ QCOMPARE(instCount, RefCounted::instanceCount.loadRelaxed());
}
- QCOMPARE(instCount, RefCounted::instanceCount.load());
+ QCOMPARE(instCount, RefCounted::instanceCount.loadRelaxed());
}
+#if QT_DEPRECATED_SINCE(6, 1)
+void tst_QScopedPointer::deprecatedTake()
+{
+ RefCounted *a = new RefCounted;
+
+ QScopedPointer<RefCounted> pa1(a);
+ QScopedPointer<RefCounted> pa2(a);
+
+ QCOMPARE(RefCounted::instanceCount.loadRelaxed(), 1);
+
+ QT_IGNORE_DEPRECATIONS(pa2.take();)
+
+ // check that pa2 holds nullptr, but the memory was not released
+ QVERIFY(pa2.isNull());
+ QCOMPARE(RefCounted::instanceCount.loadRelaxed(), 1);
+}
+#endif // QT_DEPRECATED_SINCE(6, 1)
QTEST_MAIN(tst_QScopedPointer)
#include "tst_qscopedpointer.moc"
diff --git a/tests/auto/corelib/tools/qscopedvaluerollback/CMakeLists.txt b/tests/auto/corelib/tools/qscopedvaluerollback/CMakeLists.txt
new file mode 100644
index 0000000000..359a910a0a
--- /dev/null
+++ b/tests/auto/corelib/tools/qscopedvaluerollback/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qscopedvaluerollback Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qscopedvaluerollback LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qscopedvaluerollback
+ SOURCES
+ tst_qscopedvaluerollback.cpp
+)
diff --git a/tests/auto/corelib/tools/qscopedvaluerollback/qscopedvaluerollback.pro b/tests/auto/corelib/tools/qscopedvaluerollback/qscopedvaluerollback.pro
deleted file mode 100644
index c9c0a029d3..0000000000
--- a/tests/auto/corelib/tools/qscopedvaluerollback/qscopedvaluerollback.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qscopedvaluerollback
-QT = core testlib
-SOURCES = tst_qscopedvaluerollback.cpp
diff --git a/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp b/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp
index 656dd6a6e3..3b493b4e75 100644
--- a/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp
+++ b/tests/auto/corelib/tools/qscopedvaluerollback/tst_qscopedvaluerollback.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-#include <QtTest/QtTest>
+#include <QTest>
#include <QtCore/QScopedValueRollback>
/*!
@@ -46,6 +21,7 @@ private Q_SLOTS:
void rollbackToPreviousCommit();
void exceptions();
void earlyExitScope();
+ void moveOnly();
private:
void earlyExitScope_helper(int exitpoint, int &member);
};
@@ -190,5 +166,17 @@ void tst_QScopedValueRollback::earlyExitScope_helper(int exitpoint, int& member)
r.commit();
}
+void tst_QScopedValueRollback::moveOnly()
+{
+ std::unique_ptr<int> uniquePtr;
+ std::unique_ptr<int> newVal(new int(5));
+ QVERIFY(!uniquePtr);
+ {
+ QScopedValueRollback<std::unique_ptr<int>> r(uniquePtr, std::move(newVal));
+ QVERIFY(uniquePtr);
+ }
+ QVERIFY(!uniquePtr);
+}
+
QTEST_MAIN(tst_QScopedValueRollback)
#include "tst_qscopedvaluerollback.moc"
diff --git a/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt b/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt
new file mode 100644
index 0000000000..6f6d664554
--- /dev/null
+++ b/tests/auto/corelib/tools/qscopeguard/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qscopeguard Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qscopeguard LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qscopeguard
+ SOURCES
+ tst_qscopeguard.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro b/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro
deleted file mode 100644
index 070d4b077c..0000000000
--- a/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qscopeguard
-QT = core testlib
-SOURCES = tst_qscopeguard.cpp
diff --git a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp
index f95d48f042..b7c2b952e2 100644
--- a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp
+++ b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp
@@ -1,53 +1,144 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QtCore/QScopeGuard>
+#include <optional>
+
/*!
- \class tst_QScopedGuard
+ \class tst_QScopeGuard
\internal
\since 5.11
- \brief Tests class QScopedCleanup and function qScopeGuard
+ \brief Tests class QScopeGuard and function qScopeGuard
*/
-class tst_QScopedGuard : public QObject
+class tst_QScopeGuard : public QObject
{
Q_OBJECT
private Q_SLOTS:
+ void construction();
+ void constructionFromLvalue();
+ void constructionFromRvalue();
+ void optionalGuard();
void leavingScope();
void exceptions();
};
+void func()
+{
+}
+
+int intFunc()
+{
+ return 0;
+}
+
+[[nodiscard]] int noDiscardFunc()
+{
+ return 0;
+}
+
+struct Callable
+{
+ Callable() { }
+ Callable(const Callable &other)
+ {
+ Q_UNUSED(other);
+ ++copied;
+ }
+ Callable(Callable &&other)
+ {
+ Q_UNUSED(other);
+ ++moved;
+ }
+ void operator()() { }
+
+ static int copied;
+ static int moved;
+ static void resetCounts()
+ {
+ copied = 0;
+ moved = 0;
+ }
+};
+
+int Callable::copied = 0;
+int Callable::moved = 0;
+
static int s_globalState = 0;
-void tst_QScopedGuard::leavingScope()
+void tst_QScopeGuard::construction()
+{
+ QScopeGuard fromLambda([] { });
+ QScopeGuard fromFunction(func);
+ QScopeGuard fromFunctionPointer(&func);
+ QScopeGuard fromNonVoidFunction(intFunc);
+ QScopeGuard fromNoDiscardFunction(noDiscardFunc);
+#ifndef __apple_build_version__
+ QScopeGuard fromStdFunction{std::function<void()>(func)};
+ std::function<void()> stdFunction(func);
+ QScopeGuard fromNamedStdFunction(stdFunction);
+#endif
+}
+
+void tst_QScopeGuard::constructionFromLvalue()
+{
+ Callable::resetCounts();
+ {
+ Callable callable;
+ QScopeGuard guard(callable);
+ }
+ QCOMPARE(Callable::copied, 1);
+ QCOMPARE(Callable::moved, 0);
+ Callable::resetCounts();
+ {
+ Callable callable;
+ auto guard = qScopeGuard(callable);
+ }
+ QCOMPARE(Callable::copied, 1);
+ QCOMPARE(Callable::moved, 0);
+}
+
+void tst_QScopeGuard::constructionFromRvalue()
+{
+ Callable::resetCounts();
+ {
+ Callable callable;
+ QScopeGuard guard(std::move(callable));
+ }
+ QCOMPARE(Callable::copied, 0);
+ QCOMPARE(Callable::moved, 1);
+ Callable::resetCounts();
+ {
+ Callable callable;
+ auto guard = qScopeGuard(std::move(callable));
+ }
+ QCOMPARE(Callable::copied, 0);
+ QCOMPARE(Callable::moved, 1);
+}
+
+void tst_QScopeGuard::optionalGuard()
+{
+ int i = 0;
+ auto lambda = [&] { ++i; };
+ std::optional sg = false ? std::optional{qScopeGuard(lambda)} : std::nullopt;
+ QVERIFY(!sg);
+ QCOMPARE(i, 0);
+ sg.emplace(qScopeGuard(lambda));
+ QVERIFY(sg);
+ sg->dismiss();
+ sg.reset();
+ QCOMPARE(i, 0);
+ sg.emplace(qScopeGuard(lambda));
+ QCOMPARE(i, 0);
+ sg.reset();
+ QCOMPARE(i, 1);
+}
+
+void tst_QScopeGuard::leavingScope()
{
auto cleanup = qScopeGuard([] { s_globalState++; QCOMPARE(s_globalState, 3); });
QCOMPARE(s_globalState, 0);
@@ -61,13 +152,13 @@ void tst_QScopedGuard::leavingScope()
s_globalState++;
}
-void tst_QScopedGuard::exceptions()
+void tst_QScopeGuard::exceptions()
{
s_globalState = 0;
bool caught = false;
QT_TRY
{
- auto cleanup = qScopeGuard([&caught] { s_globalState++; });
+ auto cleanup = qScopeGuard([] { s_globalState++; });
QT_THROW(std::bad_alloc()); //if Qt compiled without exceptions this is noop
s_globalState = 100;
}
@@ -81,5 +172,5 @@ void tst_QScopedGuard::exceptions()
}
-QTEST_MAIN(tst_QScopedGuard)
+QTEST_MAIN(tst_QScopeGuard)
#include "tst_qscopeguard.moc"
diff --git a/tests/auto/corelib/tools/qset/CMakeLists.txt b/tests/auto/corelib/tools/qset/CMakeLists.txt
new file mode 100644
index 0000000000..9e3e33ee7c
--- /dev/null
+++ b/tests/auto/corelib/tools/qset/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qset Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qset LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qset
+ SOURCES
+ tst_qset.cpp
+)
+
+qt_internal_undefine_global_definition(tst_qset QT_NO_JAVA_STYLE_ITERATORS)
diff --git a/tests/auto/corelib/tools/qset/qset.pro b/tests/auto/corelib/tools/qset/qset.pro
deleted file mode 100644
index 10ae3307d1..0000000000
--- a/tests/auto/corelib/tools/qset/qset.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qset
-QT = core testlib
-SOURCES = tst_qset.cpp
diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp
index 0b60350380..116d38112b 100644
--- a/tests/auto/corelib/tools/qset/tst_qset.cpp
+++ b/tests/auto/corelib/tools/qset/tst_qset.cpp
@@ -1,41 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//#define QT_STRICT_ITERATORS
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qset.h>
#include <qdebug.h>
int toNumber(const QString &str)
{
int res = 0;
- for (int i = 0; i < str.length(); ++i)
+ for (int i = 0; i < str.size(); ++i)
res = (res * 10) + str[i].digitValue();
return res;
}
@@ -54,14 +27,16 @@ private slots:
void detach();
void isDetached();
void clear();
+ void cpp17ctad();
void remove();
void contains();
void containsSet();
void begin();
void end();
void insert();
- void reverseIterators();
+ void insertConstructionCounted();
void setOperations();
+ void setOperationsOnEmptySet();
void stlIterator();
void stlMutableIterator();
void javaIterator();
@@ -70,13 +45,15 @@ private slots:
void initializerList();
void qhash();
void intersects();
+ void find();
+ void values();
};
struct IdentityTracker {
int value, id;
};
-inline uint qHash(IdentityTracker key) { return qHash(key.value); }
+inline size_t qHash(IdentityTracker key) { return qHash(key.value); }
inline bool operator==(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value == rhs.value; }
void tst_QSet::operator_eq()
@@ -162,43 +139,44 @@ void tst_QSet::size()
QSet<int> set;
QVERIFY(set.size() == 0);
QVERIFY(set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
+ QVERIFY(!set.isDetached());
set.insert(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.insert(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.insert(2);
QVERIFY(set.size() == 2);
QVERIFY(!set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.remove(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.remove(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.remove(2);
QVERIFY(set.size() == 0);
QVERIFY(set.isEmpty());
- QVERIFY(set.count() == set.size());
+ QVERIFY(set.size() == set.size());
QVERIFY(set.isEmpty() == set.empty());
}
@@ -207,6 +185,7 @@ void tst_QSet::capacity()
QSet<int> set;
int n = set.capacity();
QVERIFY(n == 0);
+ QVERIFY(!set.isDetached());
for (int i = 0; i < 1000; ++i) {
set.insert(i);
@@ -240,8 +219,12 @@ void tst_QSet::reserve()
void tst_QSet::squeeze()
{
QSet<int> set;
- int n = set.capacity();
- QVERIFY(n == 0);
+ QCOMPARE(set.capacity(), 0);
+
+ set.squeeze();
+ QCOMPARE(set.capacity(), 0);
+
+ QVERIFY(!set.isDetached());
set.reserve(1000);
QVERIFY(set.capacity() >= 1000);
@@ -251,22 +234,37 @@ void tst_QSet::squeeze()
for (int i = 0; i < 500; ++i)
set.insert(i);
- QVERIFY(set.capacity() >= 500 && set.capacity() < 10000);
+ QCOMPARE(set.size(), 500);
+
+ // squeezed capacity for 500 elements
+ qsizetype capacity = set.capacity(); // current implementation: 512
+ QCOMPARE_GE(capacity, set.size());
set.reserve(50000);
- QVERIFY(set.capacity() >= 50000);
+ QVERIFY(set.capacity() >= 50000); // current implementation: 65536
set.squeeze();
- QVERIFY(set.capacity() < 500);
+ QCOMPARE(set.capacity(), capacity);
+ // removing elements does not shed capacity
set.remove(499);
- QVERIFY(set.capacity() < 500);
+ QCOMPARE(set.capacity(), capacity);
set.insert(499);
- QVERIFY(set.capacity() >= 500);
+ QCOMPARE(set.capacity(), capacity);
+
+ // grow it beyond the current capacity
+ for (int i = set.size(); i <= capacity; ++i)
+ set.insert(i);
+ QCOMPARE(set.size(), capacity + 1);
+ QCOMPARE_GT(set.capacity(), capacity + 1);// current implementation: 2 * capacity (1024)
for (int i = 0; i < 500; ++i)
set.remove(i);
+
+ // removing elements does not shed capacity
+ QCOMPARE_GT(set.capacity(), capacity + 1);
+
set.squeeze();
QVERIFY(set.capacity() < 100);
}
@@ -310,6 +308,7 @@ void tst_QSet::clear()
set1.clear();
QVERIFY(set1.size() == 0);
+ QVERIFY(!set1.isDetached());
set1.insert("foo");
QVERIFY(set1.size() != 0);
@@ -325,24 +324,57 @@ void tst_QSet::clear()
QVERIFY(set2.size() == 0);
}
+void tst_QSet::cpp17ctad()
+{
+#define QVERIFY_IS_SET_OF(obj, Type) \
+ QVERIFY2((std::is_same<decltype(obj), QSet<Type>>::value), \
+ QMetaType::fromType<decltype(obj)::value_type>().name())
+#define CHECK(Type, One, Two, Three) \
+ do { \
+ const Type v[] = {One, Two, Three}; \
+ QSet v1 = {One, Two, Three}; \
+ QVERIFY_IS_SET_OF(v1, Type); \
+ QSet v2(v1.begin(), v1.end()); \
+ QVERIFY_IS_SET_OF(v2, Type); \
+ QSet v3(std::begin(v), std::end(v)); \
+ QVERIFY_IS_SET_OF(v3, Type); \
+ } while (false) \
+ /*end*/
+ CHECK(int, 1, 2, 3);
+ CHECK(double, 1.0, 2.0, 3.0);
+ CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
+#undef QVERIFY_IS_SET_OF
+#undef CHECK
+}
+
void tst_QSet::remove()
{
- QSet<QString> set1;
+ QSet<QString> set;
+ QCOMPARE(set.remove("test"), false);
+ QVERIFY(!set.isDetached());
+
+ const auto cnt = set.removeIf([](auto it) {
+ Q_UNUSED(it);
+ return true;
+ });
+ QCOMPARE(cnt, 0);
for (int i = 0; i < 500; ++i)
- set1.insert(QString::number(i));
+ set.insert(QString::number(i));
- QCOMPARE(set1.size(), 500);
+ QCOMPARE(set.size(), 500);
for (int j = 0; j < 500; ++j) {
- set1.remove(QString::number((j * 17) % 500));
- QCOMPARE(set1.size(), 500 - j - 1);
+ set.remove(QString::number((j * 17) % 500));
+ QCOMPARE(set.size(), 500 - j - 1);
}
}
void tst_QSet::contains()
{
QSet<QString> set1;
+ QVERIFY(!set1.contains("test"));
+ QVERIFY(!set1.isDetached());
for (int i = 0; i < 500; ++i) {
QVERIFY(!set1.contains(QString::number(i)));
@@ -367,6 +399,7 @@ void tst_QSet::containsSet()
// empty set contains the empty set
QVERIFY(set1.contains(set2));
+ QVERIFY(!set1.isDetached());
for (int i = 0; i < 500; ++i) {
set1.insert(QString::number(i));
@@ -388,6 +421,7 @@ void tst_QSet::containsSet()
// the empty set doesn't contain a filled set
QVERIFY(!set3.contains(set1));
+ QVERIFY(!set3.isDetached());
// verify const signature
const QSet<QString> set4;
@@ -409,6 +443,8 @@ void tst_QSet::begin()
QVERIFY(k == ell);
QVERIFY(i == k);
QVERIFY(j == ell);
+ QVERIFY(!set1.isDetached());
+ QVERIFY(!set2.isDetached());
}
set1.insert(44);
@@ -438,6 +474,31 @@ void tst_QSet::begin()
QVERIFY(i == k);
QVERIFY(j == ell);
}
+
+ const QSet<int> set3;
+ QSet<int> set4 = set3;
+
+ {
+ QSet<int>::const_iterator i = set3.begin();
+ QSet<int>::const_iterator j = set3.cbegin();
+ QSet<int>::const_iterator k = set4.begin();
+ QVERIFY(i == j);
+ QVERIFY(k == j);
+ QVERIFY(!set3.isDetached());
+ QVERIFY(set4.isDetached());
+ }
+
+ set4.insert(1);
+
+ {
+ QSet<int>::const_iterator i = set3.begin();
+ QSet<int>::const_iterator j = set3.cbegin();
+ QSet<int>::const_iterator k = set4.begin();
+ QVERIFY(i == j);
+ QVERIFY(k != j);
+ QVERIFY(!set3.isDetached());
+ QVERIFY(set4.isDetached());
+ }
}
void tst_QSet::end()
@@ -458,6 +519,9 @@ void tst_QSet::end()
QVERIFY(set1.constBegin() == set1.constEnd());
QVERIFY(set2.constBegin() == set2.constEnd());
+
+ QVERIFY(!set1.isDetached());
+ QVERIFY(!set2.isDetached());
}
set1.insert(44);
@@ -470,13 +534,13 @@ void tst_QSet::end()
QVERIFY(i == j);
QVERIFY(k == ell);
- QVERIFY(i != k);
- QVERIFY(j != ell);
QVERIFY(set1.constBegin() != set1.constEnd());
QVERIFY(set2.constBegin() == set2.constEnd());
+ QVERIFY(set1.constBegin() != set2.constBegin());
}
+
set2 = set1;
{
@@ -498,6 +562,37 @@ void tst_QSet::end()
set2.clear();
QVERIFY(set1.constBegin() == set1.constEnd());
QVERIFY(set2.constBegin() == set2.constEnd());
+
+ const QSet<int> set3;
+ QSet<int> set4 = set3;
+
+ {
+ QSet<int>::const_iterator i = set3.end();
+ QSet<int>::const_iterator j = set3.cend();
+ QSet<int>::const_iterator k = set4.end();
+ QVERIFY(i == j);
+ QVERIFY(k == j);
+ QVERIFY(!set3.isDetached());
+ QVERIFY(!set4.isDetached());
+
+ QVERIFY(set3.constBegin() == set3.constEnd());
+ QVERIFY(set4.constBegin() == set4.constEnd());
+ }
+
+ set4.insert(1);
+
+ {
+ QSet<int>::const_iterator i = set3.end();
+ QSet<int>::const_iterator j = set3.cend();
+ QSet<int>::const_iterator k = set4.end();
+ QVERIFY(i == j);
+ QVERIFY(k == j);
+ QVERIFY(!set3.isDetached());
+ QVERIFY(set4.isDetached());
+
+ QVERIFY(set3.constBegin() == set3.constEnd());
+ QVERIFY(set4.constBegin() != set4.constEnd());
+ }
}
void tst_QSet::insert()
@@ -551,19 +646,82 @@ void tst_QSet::insert()
}
}
-void tst_QSet::reverseIterators()
+struct ConstructionCounted
{
- QSet<int> s;
- s << 1 << 17 << 61 << 127 << 911;
- std::vector<int> v(s.begin(), s.end());
- std::reverse(v.begin(), v.end());
- const QSet<int> &cs = s;
- QVERIFY(std::equal(v.begin(), v.end(), s.rbegin()));
- QVERIFY(std::equal(v.begin(), v.end(), s.crbegin()));
- QVERIFY(std::equal(v.begin(), v.end(), cs.rbegin()));
- QVERIFY(std::equal(s.rbegin(), s.rend(), v.begin()));
- QVERIFY(std::equal(s.crbegin(), s.crend(), v.begin()));
- QVERIFY(std::equal(cs.rbegin(), cs.rend(), v.begin()));
+ ConstructionCounted(int i) : i(i) { }
+ ConstructionCounted(ConstructionCounted &&other) noexcept
+ : i(other.i), copies(other.copies), moves(other.moves + 1)
+ {
+ // set to some easily noticeable values
+ other.i = -64;
+ other.copies = -64;
+ other.moves = -64;
+ }
+ ConstructionCounted &operator=(ConstructionCounted &&other) noexcept
+ {
+ ConstructionCounted moved = std::move(other);
+ std::swap(*this, moved);
+ return *this;
+ }
+ ConstructionCounted(const ConstructionCounted &other) noexcept
+ : i(other.i), copies(other.copies + 1), moves(other.moves)
+ {
+ }
+ ConstructionCounted &operator=(const ConstructionCounted &other) noexcept
+ {
+ ConstructionCounted copy = other;
+ std::swap(*this, copy);
+ return *this;
+ }
+ ~ConstructionCounted() = default;
+
+ friend bool operator==(const ConstructionCounted &lhs, const ConstructionCounted &rhs)
+ {
+ return lhs.i == rhs.i;
+ }
+
+ QString toString() { return QString::number(i); }
+
+ int i;
+ int copies = 0;
+ int moves = 0;
+};
+
+size_t qHash(const ConstructionCounted &c, std::size_t seed = 0)
+{
+ return qHash(c.i, seed);
+}
+
+void tst_QSet::insertConstructionCounted()
+{
+ QSet<ConstructionCounted> set;
+
+ // copy-insert
+ ConstructionCounted toCopy(7);
+ auto inserted = set.insert(toCopy);
+ QCOMPARE(set.size(), 1);
+ auto element = set.begin();
+ QCOMPARE(inserted, element);
+ QCOMPARE(inserted->copies, 1);
+ QCOMPARE(inserted->moves, 1);
+ QCOMPARE(inserted->i, 7);
+
+ // move-insert
+ ConstructionCounted toMove(8);
+ inserted = set.insert(std::move(toMove));
+ element = set.find(8);
+ QCOMPARE(set.size(), 2);
+ QVERIFY(element != set.end());
+ QCOMPARE(inserted, element);
+ QCOMPARE(inserted->copies, 0);
+ QCOMPARE(inserted->moves, 1);
+ QCOMPARE(inserted->i, 8);
+
+ inserted = set.insert(std::move(toCopy)); // move-insert an existing value
+ QCOMPARE(set.size(), 2);
+ // The previously existing key is used as they compare equal:
+ QCOMPARE(inserted->copies, 1);
+ QCOMPARE(inserted->moves, 1);
}
void tst_QSet::setOperations()
@@ -664,6 +822,44 @@ void tst_QSet::setOperations()
QVERIFY(set18 == set8);
}
+void tst_QSet::setOperationsOnEmptySet()
+{
+ {
+ // Both sets are empty
+ QSet<int> set1;
+ QSet<int> set2;
+
+ set1.unite(set2);
+ QVERIFY(set1.isEmpty());
+ QVERIFY(!set1.isDetached());
+
+ set1.intersect(set2);
+ QVERIFY(set1.isEmpty());
+ QVERIFY(!set1.isDetached());
+
+ set1.subtract(set2);
+ QVERIFY(set1.isEmpty());
+ QVERIFY(!set1.isDetached());
+ }
+ {
+ // Second set is not empty
+ QSet<int> empty;
+ QSet<int> nonEmpty { 1, 2, 3 };
+
+ empty.intersect(nonEmpty);
+ QVERIFY(empty.isEmpty());
+ QVERIFY(!empty.isDetached());
+
+ empty.subtract(nonEmpty);
+ QVERIFY(empty.isEmpty());
+ QVERIFY(!empty.isDetached());
+
+ empty.unite(nonEmpty);
+ QCOMPARE(empty, nonEmpty);
+ QVERIFY(!empty.isDetached());
+ }
+}
+
void tst_QSet::stlIterator()
{
QSet<QString> set1;
@@ -679,16 +875,6 @@ void tst_QSet::stlIterator()
}
QVERIFY(sum == 24999 * 25000 / 2);
}
-
- {
- int sum = 0;
- QSet<QString>::const_iterator i = set1.end();
- while (i != set1.begin()) {
- --i;
- sum += toNumber(*i);
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
}
void tst_QSet::stlMutableIterator()
@@ -708,21 +894,10 @@ void tst_QSet::stlMutableIterator()
}
{
- int sum = 0;
- QSet<QString>::iterator i = set1.end();
- while (i != set1.begin()) {
- --i;
- sum += toNumber(*i);
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
QSet<QString> set2 = set1;
QSet<QString> set3 = set2;
QSet<QString>::iterator i = set2.begin();
- QSet<QString>::iterator j = set3.begin();
while (i != set2.end()) {
i = set2.erase(i);
@@ -730,24 +905,7 @@ void tst_QSet::stlMutableIterator()
QVERIFY(set2.isEmpty());
QVERIFY(!set3.isEmpty());
- j = set3.end();
- while (j != set3.begin()) {
- j--;
- if (j + 1 != set3.end())
- set3.erase(j + 1);
- }
- if (set3.begin() != set3.end())
- set3.erase(set3.begin());
-
- QVERIFY(set2.isEmpty());
- QVERIFY(set3.isEmpty());
-
-// #if QT_VERSION >= 0x050000
-// i = set2.insert("foo");
-// #else
- QSet<QString>::const_iterator k = set2.insert("foo");
- i = reinterpret_cast<QSet<QString>::iterator &>(k);
-// #endif
+ i = set2.insert("foo");
QCOMPARE(*i, QLatin1String("foo"));
}
}
@@ -776,59 +934,16 @@ void tst_QSet::javaIterator()
QVERIFY(sum == 24999 * 25000 / 2);
}
- {
- int sum = 0;
- QSetIterator<QString> i(set1);
- while (i.hasNext()) {
- i.next();
- sum += toNumber(i.peekPrevious());
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
- int sum = 0;
- QSetIterator<QString> i(set1);
- i.toBack();
- while (i.hasPrevious())
- sum += toNumber(i.previous());
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
- int sum = 0;
- QSetIterator<QString> i(set1);
- i.toBack();
- while (i.hasPrevious()) {
- sum += toNumber(i.peekPrevious());
- i.previous();
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
- int sum = 0;
- QSetIterator<QString> i(set1);
- i.toBack();
- while (i.hasPrevious()) {
- i.previous();
- sum += toNumber(i.peekNext());
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
int sum1 = 0;
int sum2 = 0;
QSetIterator<QString> i(set1);
QSetIterator<QString> j(set1);
- int n = 0;
while (i.hasNext()) {
QVERIFY(j.hasNext());
set1.remove(i.peekNext());
sum1 += toNumber(i.next());
sum2 += toNumber(j.next());
- ++n;
}
QVERIFY(!j.hasNext());
QVERIFY(sum1 == 24999 * 25000 / 2);
@@ -871,52 +986,10 @@ void tst_QSet::javaMutableIterator()
}
{
- int sum = 0;
- QMutableSetIterator<QString> i(set1);
- while (i.hasNext()) {
- i.next();
- sum += toNumber(i.peekPrevious());
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
- int sum = 0;
- QMutableSetIterator<QString> i(set1);
- i.toBack();
- while (i.hasPrevious())
- sum += toNumber(i.previous());
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
- int sum = 0;
- QMutableSetIterator<QString> i(set1);
- i.toBack();
- while (i.hasPrevious()) {
- sum += toNumber(i.peekPrevious());
- i.previous();
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
- int sum = 0;
- QMutableSetIterator<QString> i(set1);
- i.toBack();
- while (i.hasPrevious()) {
- i.previous();
- sum += toNumber(i.peekNext());
- }
- QVERIFY(sum == 24999 * 25000 / 2);
- }
-
- {
QSet<QString> set2 = set1;
QSet<QString> set3 = set2;
QMutableSetIterator<QString> i(set2);
- QMutableSetIterator<QString> j(set3);
while (i.hasNext()) {
i.next();
@@ -924,14 +997,6 @@ void tst_QSet::javaMutableIterator()
}
QVERIFY(set2.isEmpty());
QVERIFY(!set3.isEmpty());
-
- j.toBack();
- while (j.hasPrevious()) {
- j.previous();
- j.remove();
- }
- QVERIFY(set2.isEmpty());
- QVERIFY(set3.isEmpty());
}
}
@@ -955,9 +1020,8 @@ void tst_QSet::makeSureTheComfortFunctionsCompile()
void tst_QSet::initializerList()
{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
QSet<int> set = {1, 1, 2, 3, 4, 5};
- QCOMPARE(set.count(), 5);
+ QCOMPARE(set.size(), 5);
QVERIFY(set.contains(1));
QVERIFY(set.contains(2));
QVERIFY(set.contains(3));
@@ -966,7 +1030,7 @@ void tst_QSet::initializerList()
// check _which_ of the equal elements gets inserted (in the QHash/QMap case, it's the last):
const QSet<IdentityTracker> set2 = {{1, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};
- QCOMPARE(set2.count(), 5);
+ QCOMPARE(set2.size(), 5);
const int dummy = -1;
const IdentityTracker searchKey = {1, dummy};
QCOMPARE(set2.find(searchKey)->id, 0);
@@ -976,9 +1040,6 @@ void tst_QSet::initializerList()
QSet<int> set3{{}, {}, {}};
QVERIFY(!set3.isEmpty());
-#else
- QSKIP("Compiler doesn't support initializer lists");
-#endif
}
void tst_QSet::qhash()
@@ -988,38 +1049,40 @@ void tst_QSet::qhash()
//
{
// create some deterministic initial state:
- qSetGlobalQHashSeed(0);
+ QHashSeed::setDeterministicGlobalSeed();
QSet<int> s1;
s1.reserve(4);
s1 << 400 << 300 << 200 << 100;
- // also change the seed:
- qSetGlobalQHashSeed(0x10101010);
+ int retries = 128;
+ while (--retries >= 0) {
+ // reset the global seed to something different
+ QHashSeed::resetRandomGlobalSeed();
- QSet<int> s2;
- s2.reserve(100); // provoke different bucket counts
- s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too
+ QSet<int> s2;
+ s2.reserve(100); // provoke different bucket counts
+ s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too
+ QVERIFY(s1.capacity() != s2.capacity());
- QVERIFY(s1.capacity() != s2.capacity());
- QCOMPARE(s1, s2);
- QVERIFY(!std::equal(s1.cbegin(), s1.cend(), s2.cbegin())); // verify that the order _is_ different
- QCOMPARE(qHash(s1), qHash(s2));
+ // see if we got a _different_ order
+ if (std::equal(s1.cbegin(), s1.cend(), s2.cbegin()))
+ continue;
+
+ // check if the two QHashes still compare equal and produce the
+ // same hash, despite containing elements in different orders
+ QCOMPARE(s1, s2);
+ QCOMPARE(qHash(s1), qHash(s2));
+ }
+ QVERIFY2(retries != 0, "Could not find a QSet with a different order of elements even "
+ "after a lot of retries. This is unlikely, but possible.");
}
//
// check that sets of sets work:
//
{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
QSet<QSet<int> > intSetSet = { { 0, 1, 2 }, { 0, 1 }, { 1, 2 } };
-#else
- QSet<QSet<int> > intSetSet;
- QSet<int> intSet01, intSet12;
- intSet01 << 0 << 1;
- intSet12 << 1 << 2;
- intSetSet << intSet01 << intSet12 << (intSet01|intSet12);
-#endif
QCOMPARE(intSetSet.size(), 3);
}
}
@@ -1031,6 +1094,8 @@ void tst_QSet::intersects()
QVERIFY(!s1.intersects(s1));
QVERIFY(!s1.intersects(s2));
+ QVERIFY(!s1.isDetached());
+ QVERIFY(!s2.isDetached());
s1 << 100;
QVERIFY(s1.intersects(s1));
@@ -1042,7 +1107,7 @@ void tst_QSet::intersects()
s1 << 200;
QVERIFY(s1.intersects(s2));
- qSetGlobalQHashSeed(0x10101010);
+ QHashSeed::resetRandomGlobalSeed();
QSet<int> s3;
s3 << 500;
QVERIFY(!s1.intersects(s3));
@@ -1050,6 +1115,50 @@ void tst_QSet::intersects()
QVERIFY(s1.intersects(s3));
}
+void tst_QSet::find()
+{
+ QSet<int> set;
+ QCOMPARE(set.find(1), set.end());
+ QCOMPARE(set.constFind(1), set.constEnd());
+ QVERIFY(!set.isDetached());
+
+ set.insert(1);
+ set.insert(2);
+
+ QVERIFY(set.find(1) != set.end());
+ QVERIFY(set.constFind(2) != set.constEnd());
+ QVERIFY(set.find(3) == set.end());
+ QVERIFY(set.constFind(4) == set.constEnd());
+}
+
+template<typename T>
+QList<T> sorted(const QList<T> &list)
+{
+ QList<T> res = list;
+ std::sort(res.begin(), res.end());
+ return res;
+}
+
+void tst_QSet::values()
+{
+ QSet<int> set;
+ QVERIFY(set.values().isEmpty());
+ QVERIFY(!set.isDetached());
+
+ set.insert(1);
+ QCOMPARE(set.values(), QList<int> { 1 });
+
+ set.insert(10);
+ set.insert(5);
+ set.insert(2);
+
+ QCOMPARE(sorted(set.values()), QList<int>({ 1, 2, 5, 10 }));
+
+ set.remove(5);
+
+ QCOMPARE(sorted(set.values()), QList<int>({ 1, 2, 10 }));
+}
+
QTEST_APPLESS_MAIN(tst_QSet)
#include "tst_qset.moc"
diff --git a/tests/auto/corelib/tools/qsharedpointer/CMakeLists.txt b/tests/auto/corelib/tools/qsharedpointer/CMakeLists.txt
new file mode 100644
index 0000000000..0db0cba4c0
--- /dev/null
+++ b/tests/auto/corelib/tools/qsharedpointer/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsharedpointer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsharedpointer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsharedpointer
+ SOURCES
+ forwarddeclared.cpp
+ nontracked.cpp
+ wrapper.cpp
+ tst_qsharedpointer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
index d1bb89f549..c676924668 100644
--- a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "externaltests.h"
@@ -80,32 +55,34 @@ namespace QTest {
{
if (process.state() == QProcess::Running) {
process.terminate();
- QThread::msleep(20);
+ QThread::sleep(std::chrono::milliseconds{20});
if (process.state() == QProcess::Running)
process.kill();
}
}
+# ifdef Q_OS_UNIX
class QExternalProcess: public QProcess
{
- protected:
-#ifdef Q_OS_UNIX
- void setupChildProcess()
+ public:
+ QExternalProcess()
{
- // run in user code
- QProcess::setupChildProcess();
-
- if (processChannelMode() == ForwardedChannels) {
- // reopen /dev/tty into stdin
- int fd = ::open("/dev/tty", O_RDONLY);
- if (fd == -1)
- return;
- ::dup2(fd, 0);
- ::close(fd);
- }
+ setChildProcessModifier([this]() {
+ // run in user code
+ if (processChannelMode() == ForwardedChannels) {
+ // reopen /dev/tty into stdin
+ int fd = ::open("/dev/tty", O_RDONLY);
+ if (fd == -1)
+ return;
+ ::dup2(fd, 0);
+ ::close(fd);
+ }
+ });
}
-#endif
};
+# else
+ using QExternalProcess = QProcess;
+# endif
#endif // QT_CONFIG(process)
class QExternalTestPrivate
@@ -341,7 +318,7 @@ namespace QTest {
if (qtModules & QExternalTest::QtScript)
sourceCode += "#include <QtScript/QtScript>\n";
if (qtModules & QExternalTest::QtTest)
- sourceCode += "#include <QtTest/QtTest>\n";
+ sourceCode += "#include <QTest>\n";
if (qtModules & QExternalTest::QtDBus)
sourceCode += "#include <QtDBus/QtDBus>\n";
if (qtModules & QExternalTest::QtWebKit)
@@ -360,7 +337,7 @@ namespace QTest {
"}\n"
"\n"
"#ifdef Q_OS_WIN\n"
- "#include <windows.h>\n"
+ "#include <qt_windows.h>\n"
"#if defined(Q_CC_MSVC)\n"
"#include <crtdbg.h>\n"
"#endif\n"
@@ -588,7 +565,7 @@ namespace QTest {
<< QLatin1String("project.pro");
qmake.setWorkingDirectory(temporaryDirPath);
- QString cmd = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmake";
+ QString cmd = QLibraryInfo::path(QLibraryInfo::BinariesPath) + "/qmake";
#ifdef Q_OS_WIN
cmd.append(".exe");
#endif
diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.h b/tests/auto/corelib/tools/qsharedpointer/externaltests.h
index bae6adaefe..790ca61992 100644
--- a/tests/auto/corelib/tools/qsharedpointer/externaltests.h
+++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QTEST_EXTERNAL_TESTS_H
diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.pri b/tests/auto/corelib/tools/qsharedpointer/externaltests.pri
deleted file mode 100644
index 604bd7f59f..0000000000
--- a/tests/auto/corelib/tools/qsharedpointer/externaltests.pri
+++ /dev/null
@@ -1,6 +0,0 @@
-SOURCES += $$PWD/externaltests.cpp
-HEADERS += $$PWD/externaltests.h
-cleanedQMAKESPEC = $$replace(QMAKESPEC, \\\\, /)
-DEFINES += DEFAULT_MAKESPEC=\\\"$$cleanedQMAKESPEC\\\"
-
-cross_compile:DEFINES += QTEST_NO_RTTI QTEST_CROSS_COMPILED
diff --git a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp
index df343b5ebc..5a0af60c11 100644
--- a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "forwarddeclared.h"
#include "qsharedpointer.h"
diff --git a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h
index c72324841c..ba436d99cf 100644
--- a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h
+++ b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef FORWARDDECLARED_H
#define FORWARDDECLARED_H
diff --git a/tests/auto/corelib/tools/qsharedpointer/nontracked.cpp b/tests/auto/corelib/tools/qsharedpointer/nontracked.cpp
index e0780f8a9a..b572fa1b9f 100644
--- a/tests/auto/corelib/tools/qsharedpointer/nontracked.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/nontracked.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
/*
* This file exists because tst_qsharedpointer.cpp is compiled with
@@ -40,7 +15,7 @@
*/
#include <qsharedpointer.h>
-#include <QtTest>
+#include <QTest>
#include "nontracked.h"
diff --git a/tests/auto/corelib/tools/qsharedpointer/nontracked.h b/tests/auto/corelib/tools/qsharedpointer/nontracked.h
index 76af80d2d7..e10ea08a4d 100644
--- a/tests/auto/corelib/tools/qsharedpointer/nontracked.h
+++ b/tests/auto/corelib/tools/qsharedpointer/nontracked.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef NONTRACKED_H
#define NONTRACKED_H
diff --git a/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro b/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro
deleted file mode 100644
index 240137d563..0000000000
--- a/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsharedpointer
-QT = core testlib
-
-SOURCES = tst_qsharedpointer.cpp \
- forwarddeclared.cpp \
- nontracked.cpp \
- wrapper.cpp
-
-HEADERS = forwarddeclared.h \
- nontracked.h \
- wrapper.h
-
-TESTDATA += forwarddeclared.cpp forwarddeclared.h
-
-include(externaltests.pri)
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
index ade9c5e754..f42637a3fe 100644
--- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
@@ -1,49 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#define QT_SHAREDPOINTER_TRACK_POINTERS
#include "qsharedpointer.h"
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QPointer>
+#include <QRandomGenerator>
#include <QtCore/QHash>
+#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QThread>
-#include <QtCore/QVector>
+#include <QtCore/private/qvolatile_p.h>
-#include "externaltests.h"
#include "forwarddeclared.h"
#include "nontracked.h"
#include "wrapper.h"
+#include <array>
+#include <memory>
#include <stdlib.h>
#include <time.h>
-#ifdef Q_OS_UNIX
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
#include <sys/resource.h>
#endif
@@ -74,10 +54,9 @@ private slots:
void functionCallDownCast();
void upCast();
void qobjectWeakManagement();
- void noSharedPointerFromWeakQObject();
- void sharedPointerFromQObjectWithWeak();
void weakQObjectFromSharedPointer();
void objectCast();
+ void objectCastStdSharedPtr();
void differentPointers();
void virtualBaseDifferentPointers();
#ifndef QTEST_NO_RTTI
@@ -89,9 +68,8 @@ private slots:
#endif
void constCorrectness();
void customDeleter();
-#ifdef Q_COMPILER_LAMBDA
void lambdaCustomDeleter();
-#endif
+ void customDeleterOnNullptr();
void creating();
void creatingCvQualified();
void creatingVariadic();
@@ -104,12 +82,17 @@ private slots:
void sharedFromThis();
void constructorThrow();
+ void overloads();
void threadStressTest_data();
void threadStressTest();
void validConstructs();
+#if 0
void invalidConstructs_data();
void invalidConstructs();
+#endif
+ void ownerComparisons();
+
// let invalidConstructs be the last test, because it's the slowest;
// add new tests above this block
public slots:
@@ -126,7 +109,7 @@ public:
void tst_QSharedPointer::initTestCase()
{
-#if defined(Q_OS_UNIX)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
// The tests create a lot of threads, which require file descriptors. On systems like
// OS X low defaults such as 256 as the limit for the number of simultaneously
// open files is not sufficient.
@@ -147,7 +130,7 @@ QtSharedPointer::ExternalRefCountData *refCountData(const QSharedPointer<T> &b)
QtSharedPointer::ExternalRefCountData* data;
};
// sanity checks:
- Q_STATIC_ASSERT(sizeof(QSharedPointer<T>) == sizeof(Dummy));
+ static_assert(sizeof(QSharedPointer<T>) == sizeof(Dummy));
Q_ASSERT(static_cast<const Dummy*>(static_cast<const void*>(&b))->value == b.data());
return static_cast<const Dummy*>(static_cast<const void*>(&b))->data;
}
@@ -226,13 +209,17 @@ struct NoDefaultConstructorConstRef2
NoDefaultConstructorConstRef2(const QByteArray &ba, int i = 42) : str(QString::fromLatin1(ba)), i(i) {}
};
-#ifdef Q_COMPILER_RVALUE_REFS
struct NoDefaultConstructorRRef1
{
int &i;
NoDefaultConstructorRRef1(int &&i) : i(i) {}
};
-#endif
+
+struct NoDefaultConstructorRRef2
+{
+ std::unique_ptr<int> i;
+ NoDefaultConstructorRRef2(std::unique_ptr<int> &&i) : i(std::move(i)) {}
+};
void tst_QSharedPointer::basics_data()
{
@@ -290,8 +277,8 @@ void tst_QSharedPointer::basics()
QVERIFY(! (ptr == otherData));
QVERIFY(! (otherData == ptr));
}
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.load() == 1);
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.load() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.loadRelaxed() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.loadRelaxed() == 1);
{
// create another object:
@@ -303,8 +290,8 @@ void tst_QSharedPointer::basics()
// otherData is deleted here
}
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.load() == 1);
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.load() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.loadRelaxed() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.loadRelaxed() == 1);
{
// create a copy:
@@ -321,8 +308,8 @@ void tst_QSharedPointer::basics()
QCOMPARE(copy.get(), aData);
QVERIFY(copy == aData);
}
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.load() == 1);
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.load() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.loadRelaxed() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.loadRelaxed() == 1);
{
// create a weak reference:
@@ -331,6 +318,11 @@ void tst_QSharedPointer::basics()
QCOMPARE(!weak, isNull);
QCOMPARE(bool(weak), !isNull);
+ QCOMPARE(weak.isNull(), (weak == nullptr));
+ QCOMPARE(weak.isNull(), (nullptr == weak));
+ QCOMPARE(!weak.isNull(), (weak != nullptr));
+ QCOMPARE(!weak.isNull(), (nullptr != weak));
+
QVERIFY(ptr == weak);
QVERIFY(weak == ptr);
QVERIFY(! (ptr != weak));
@@ -354,8 +346,8 @@ void tst_QSharedPointer::basics()
QCOMPARE(strong.data(), aData);
QCOMPARE(strong.get(), aData);
}
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.load() == 1);
- QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.load() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->weakref.loadRelaxed() == 1);
+ QVERIFY(!refCountData(ptr) || refCountData(ptr)->strongref.loadRelaxed() == 1);
// aData is deleted here
}
@@ -416,6 +408,12 @@ void tst_QSharedPointer::nullptrOps()
QVERIFY(!p2.get());
QVERIFY(p1 == p2);
+ QWeakPointer<char> wp1 = p1;
+ QVERIFY(wp1 == nullptr);
+ QVERIFY(nullptr == wp1);
+ QCOMPARE(wp1, nullptr);
+ QCOMPARE(nullptr, wp1);
+
QSharedPointer<char> p3 = p1;
QVERIFY(p3 == p1);
QVERIFY(p3 == null);
@@ -442,6 +440,10 @@ void tst_QSharedPointer::nullptrOps()
QVERIFY(p4 != p2);
QVERIFY(p4 != null);
QVERIFY(p4 != p3);
+
+ QWeakPointer<char> wp2 = p4;
+ QVERIFY(wp2 != nullptr);
+ QVERIFY(nullptr != wp2);
}
void tst_QSharedPointer::swap()
@@ -501,7 +503,6 @@ void tst_QSharedPointer::swap()
void tst_QSharedPointer::moveSemantics()
{
-#ifdef Q_COMPILER_RVALUE_REFS
QSharedPointer<int> p1, p2(new int(42)), control = p2;
QVERIFY(p1 != control);
QVERIFY(p1.isNull());
@@ -554,9 +555,6 @@ void tst_QSharedPointer::moveSemantics()
QVERIFY(w1.isNull());
QVERIFY(w2.isNull());
QVERIFY(w3.isNull());
-#else
- QSKIP("This test requires C++11 rvalue/move semantics support in the compiler.");
-#endif
}
void tst_QSharedPointer::useOfForwardDeclared()
@@ -573,10 +571,10 @@ void tst_QSharedPointer::useOfForwardDeclared()
// move assignment:
QSharedPointer<ForwardDeclared> sp4;
- sp4 = qMove(sp);
+ sp4 = std::move(sp);
// and move constuction:
- QSharedPointer<ForwardDeclared> sp5 = qMove(sp2);
+ QSharedPointer<ForwardDeclared> sp5 = std::move(sp2);
// swapping:
sp4.swap(sp3);
@@ -588,6 +586,9 @@ void tst_QSharedPointer::useOfForwardDeclared()
void tst_QSharedPointer::memoryManagement()
{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
+
int generation = Data::generationCounter + 1;
int destructorCounter = Data::destructorCounter;
@@ -649,6 +650,7 @@ void tst_QSharedPointer::memoryManagement()
QVERIFY(ptr.isNull());
QVERIFY(ptr == 0);
QCOMPARE(ptr.data(), (Data*)0);
+QT_WARNING_POP
}
void tst_QSharedPointer::dropLastReferenceOfForwardDeclared()
@@ -734,12 +736,12 @@ public:
DerivedData() : moreData(0) { }
~DerivedData() { ++derivedDestructorCounter; }
- virtual void virtualDelete()
+ void virtualDelete() override
{
delete this;
}
- virtual int classLevel() { return 2; }
+ int classLevel() override { return 2; }
};
int DerivedData::derivedDestructorCounter = 0;
@@ -754,7 +756,7 @@ public:
class DiffPtrDerivedData: public Stuffing, public Data
{
public:
- virtual int classLevel() { return 3; }
+ int classLevel() override { return 3; }
};
class VirtualDerived: virtual public Data
@@ -763,15 +765,20 @@ public:
int moreData;
VirtualDerived() : moreData(0xc0ffee) { }
- virtual int classLevel() { return 4; }
+ int classLevel() override { return 4; }
};
void tst_QSharedPointer::downCast()
{
{
+ // copy construction
QSharedPointer<DerivedData> ptr = QSharedPointer<DerivedData>(new DerivedData);
+ QSharedPointer<DerivedData> copy = ptr;
QSharedPointer<Data> baseptr = qSharedPointerCast<Data>(ptr);
QSharedPointer<Data> other;
+ QWeakPointer<DerivedData> weak = ptr;
+ QWeakPointer<Data> baseweak = qSharedPointerCast<Data>(ptr);
+ QWeakPointer<Data> baseweak2 = qSharedPointerCast<Data>(weak);
QVERIFY(ptr == baseptr);
QVERIFY(baseptr == ptr);
@@ -782,11 +789,55 @@ void tst_QSharedPointer::downCast()
QVERIFY(other != ptr);
QVERIFY(! (ptr == other));
QVERIFY(! (other == ptr));
+
+ // copy assignments
+ baseptr = qSharedPointerCast<Data>(ptr);
+ baseweak = qSharedPointerCast<Data>(ptr);
+ baseweak2 = baseweak;
+
+ // move assignments (these don't actually move)
+ baseptr = qSharedPointerCast<Data>(std::move(ptr));
+ ptr = copy;
+ baseweak = qSharedPointerCast<Data>(std::move(ptr));
+ ptr = copy;
+ baseweak2 = qSharedPointerCast<Data>(std::move(baseweak));
+
+ // move construction (these don't actually move)
+ ptr = copy;
+ QSharedPointer<Data> ptr3(qSharedPointerCast<Data>(std::move(ptr)));
+ ptr = copy;
+ QWeakPointer<Data> baseweak3(qSharedPointerCast<Data>(std::move(ptr)));
+ ptr = copy;
+ QWeakPointer<Data> baseweak4(qSharedPointerCast<Data>(std::move(weak)));
}
{
+ // copy construction
QSharedPointer<DerivedData> ptr = QSharedPointer<DerivedData>(new DerivedData);
+ QSharedPointer<DerivedData> copy = ptr;
QSharedPointer<Data> baseptr = ptr;
+ QWeakPointer<DerivedData> weak = ptr;
+ QWeakPointer<Data> baseweak = ptr;
+ QWeakPointer<Data> baseweak2 = weak;
+
+ // copy assignments
+ baseptr = ptr;
+ baseweak = ptr;
+ baseweak2 = weak;
+
+ // move assignments (only the QSharedPointer-QSharedPointer actually moves)
+ baseweak = std::move(ptr);
+ baseweak2 = std::move(weak);
+ ptr = copy;
+ baseptr = std::move(ptr);
+
+ // move construction (only the QSharedPointer-QSharedPointer actually moves)
+ ptr = copy;
+ QWeakPointer<Data> baseweak3(std::move(ptr));
+ ptr = copy;
+ QWeakPointer<Data> baseweak4(std::move(weak));
+ ptr = copy;
+ QSharedPointer<Data> baseptr2(std::move(ptr));
}
int destructorCount;
@@ -843,15 +894,15 @@ void tst_QSharedPointer::upCast()
QVERIFY(baseptr == derivedptr);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QWeakPointer<DerivedData> derivedptr = qWeakPointerCast<DerivedData>(baseptr);
QVERIFY(baseptr == derivedptr);
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QWeakPointer<Data> weakptr = baseptr;
@@ -859,16 +910,16 @@ void tst_QSharedPointer::upCast()
QVERIFY(baseptr == derivedptr);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QSharedPointer<DerivedData> derivedptr = baseptr.staticCast<DerivedData>();
QVERIFY(baseptr == derivedptr);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
}
class OtherObject: public QObject
@@ -882,17 +933,18 @@ void tst_QSharedPointer::qobjectWeakManagement()
QWeakPointer<QObject> weak;
weak = QWeakPointer<QObject>();
QVERIFY(weak.isNull());
- QVERIFY(!weak.data());
+ QVERIFY(weak.toStrongRef().isNull());
}
{
QObject *obj = new QObject;
- QWeakPointer<QObject> weak(obj);
+ QSharedPointer<QObject> shared(obj);
+ QWeakPointer<QObject> weak(shared);
QVERIFY(!weak.isNull());
- QVERIFY(weak.data() == obj);
+ QVERIFY(weak.toStrongRef() == obj);
// now delete
- delete obj;
+ shared.reset();
QVERIFY(weak.isNull());
}
safetyCheck();
@@ -900,41 +952,14 @@ void tst_QSharedPointer::qobjectWeakManagement()
{
// same, bit with operator=
QObject *obj = new QObject;
+ QSharedPointer<QObject> shared(obj);
QWeakPointer<QObject> weak;
- weak = obj;
+ weak = shared;
QVERIFY(!weak.isNull());
- QVERIFY(weak.data() == obj);
+ QVERIFY(weak.toStrongRef() == obj);
// now delete
- delete obj;
- QVERIFY(weak.isNull());
- }
- safetyCheck();
-
- {
- // delete triggered by parent
- QObject *obj, *parent;
- parent = new QObject;
- obj = new QObject(parent);
- QWeakPointer<QObject> weak(obj);
-
- // now delete the parent
- delete parent;
- QVERIFY(weak.isNull());
- }
- safetyCheck();
-
- {
- // same as above, but set the parent after QWeakPointer is created
- QObject *obj, *parent;
- obj = new QObject;
- QWeakPointer<QObject> weak(obj);
-
- parent = new QObject;
- obj->setParent(parent);
-
- // now delete the parent
- delete parent;
+ shared.reset();
QVERIFY(weak.isNull());
}
safetyCheck();
@@ -942,16 +967,17 @@ void tst_QSharedPointer::qobjectWeakManagement()
{
// with two QWeakPointers
QObject *obj = new QObject;
- QWeakPointer<QObject> weak(obj);
+ QSharedPointer<QObject> shared(obj);
+ QWeakPointer<QObject> weak(shared);
{
- QWeakPointer<QObject> weak2(obj);
+ QWeakPointer<QObject> weak2(shared);
QVERIFY(!weak2.isNull());
QVERIFY(weak == weak2);
}
QVERIFY(!weak.isNull());
- delete obj;
+ shared.reset();
QVERIFY(weak.isNull());
}
safetyCheck();
@@ -959,13 +985,14 @@ void tst_QSharedPointer::qobjectWeakManagement()
{
// same, but delete the pointer while two QWeakPointers exist
QObject *obj = new QObject;
- QWeakPointer<QObject> weak(obj);
+ QSharedPointer<QObject> shared(obj);
+ QWeakPointer<QObject> weak(shared);
{
- QWeakPointer<QObject> weak2(obj);
+ QWeakPointer<QObject> weak2(shared);
QVERIFY(!weak2.isNull());
- delete obj;
+ shared.reset();
QVERIFY(weak.isNull());
QVERIFY(weak2.isNull());
}
@@ -974,51 +1001,17 @@ void tst_QSharedPointer::qobjectWeakManagement()
safetyCheck();
}
-void tst_QSharedPointer::noSharedPointerFromWeakQObject()
-{
- // you're not allowed to create a QSharedPointer from an unmanaged QObject
- QObject obj;
- QWeakPointer<QObject> weak(&obj);
-
- {
- QTest::ignoreMessage(QtWarningMsg , "QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
- QSharedPointer<QObject> strong = weak.toStrongRef();
- QVERIFY(strong.isNull());
- }
- {
- QTest::ignoreMessage(QtWarningMsg , "QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
- QSharedPointer<QObject> strong = weak;
- QVERIFY(strong.isNull());
- }
-
- QCOMPARE(weak.data(), &obj);
- // if something went wrong, we'll probably crash here
-}
-
-void tst_QSharedPointer::sharedPointerFromQObjectWithWeak()
+void tst_QSharedPointer::weakQObjectFromSharedPointer()
{
- QObject *ptr = new QObject;
- QWeakPointer<QObject> weak = ptr;
{
- QSharedPointer<QObject> shared(ptr);
+ QSharedPointer<QObject> shared(new QObject);
+ QWeakPointer<QObject> weak = shared;
QVERIFY(!weak.isNull());
- QCOMPARE(shared.data(), ptr);
- QCOMPARE(weak.data(), ptr);
- }
- QVERIFY(weak.isNull());
-}
-void tst_QSharedPointer::weakQObjectFromSharedPointer()
-{
- // this is the inverse of the above: you're allowed to create a QWeakPointer
- // from a managed QObject
- QSharedPointer<QObject> shared(new QObject);
- QWeakPointer<QObject> weak = shared.data();
- QVERIFY(!weak.isNull());
-
- // delete:
- shared.clear();
- QVERIFY(weak.isNull());
+ // delete:
+ shared.clear();
+ QVERIFY(weak.isNull());
+ }
}
void tst_QSharedPointer::objectCast()
@@ -1115,6 +1108,60 @@ void tst_QSharedPointer::objectCast()
safetyCheck();
}
+
+void tst_QSharedPointer::objectCastStdSharedPtr()
+{
+ {
+ OtherObject *data = new OtherObject;
+ std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
+ QVERIFY(baseptr.get() == data);
+
+ // perform successful object cast
+ std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(baseptr);
+ QVERIFY(ptr.get());
+ QVERIFY(ptr.get() == data);
+
+ QVERIFY(baseptr.get() == data);
+ }
+
+ {
+ OtherObject *data = new OtherObject;
+ std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
+ QVERIFY(baseptr.get() == data);
+
+ // perform successful object cast
+ std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(std::move(baseptr));
+ QVERIFY(ptr.get());
+ QVERIFY(ptr.get() == data);
+
+ QVERIFY(!baseptr.get());
+ }
+
+ {
+ QObject *data = new QObject;
+ std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
+ QVERIFY(baseptr.get() == data);
+
+ // perform unsuccessful object cast
+ std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(baseptr);
+ QVERIFY(!ptr.get());
+
+ QVERIFY(baseptr.get() == data);
+ }
+
+ {
+ QObject *data = new QObject;
+ std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
+ QVERIFY(baseptr.get() == data);
+
+ // perform unsuccessful object cast
+ std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(std::move(baseptr));
+ QVERIFY(!ptr.get());
+
+ QVERIFY(baseptr.get() == data);
+ }
+}
+
void tst_QSharedPointer::differentPointers()
{
{
@@ -1229,6 +1276,22 @@ void tst_QSharedPointer::virtualBaseDifferentPointers()
QVERIFY(baseptr == aBase);
}
safetyCheck();
+ {
+ VirtualDerived *aData = new VirtualDerived;
+
+ QSharedPointer<VirtualDerived> ptr = QSharedPointer<VirtualDerived>(aData);
+ QWeakPointer<VirtualDerived> wptr = ptr;
+
+ ptr.reset();
+ QVERIFY(wptr.toStrongRef().isNull());
+
+ QWeakPointer<Data> wptr2 = wptr;
+ QVERIFY(wptr2.toStrongRef().isNull());
+
+ QWeakPointer<Data> wptr3 = std::move(wptr);
+ QVERIFY(wptr3.toStrongRef().isNull());
+ }
+ safetyCheck();
}
#ifndef QTEST_NO_RTTI
@@ -1243,8 +1306,8 @@ void tst_QSharedPointer::dynamicCast()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QWeakPointer<Data> weakptr = baseptr;
@@ -1253,8 +1316,8 @@ void tst_QSharedPointer::dynamicCast()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QSharedPointer<DerivedData> derivedptr = baseptr.dynamicCast<DerivedData>();
@@ -1262,8 +1325,8 @@ void tst_QSharedPointer::dynamicCast()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
}
void tst_QSharedPointer::dynamicCastDifferentPointers()
@@ -1278,8 +1341,8 @@ void tst_QSharedPointer::dynamicCastDifferentPointers()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QWeakPointer<Data> weakptr = baseptr;
@@ -1288,8 +1351,8 @@ void tst_QSharedPointer::dynamicCastDifferentPointers()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QSharedPointer<DiffPtrDerivedData> derivedptr = baseptr.dynamicCast<DiffPtrDerivedData>();
@@ -1297,8 +1360,8 @@ void tst_QSharedPointer::dynamicCastDifferentPointers()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
Stuffing *nakedptr = dynamic_cast<Stuffing *>(baseptr.data());
@@ -1323,8 +1386,8 @@ void tst_QSharedPointer::dynamicCastVirtualBase()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QWeakPointer<Data> weakptr = baseptr;
@@ -1333,8 +1396,8 @@ void tst_QSharedPointer::dynamicCastVirtualBase()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QSharedPointer<VirtualDerived> derivedptr = baseptr.dynamicCast<VirtualDerived>();
@@ -1342,8 +1405,8 @@ void tst_QSharedPointer::dynamicCastVirtualBase()
QCOMPARE(derivedptr.data(), aData);
QCOMPARE(static_cast<Data *>(derivedptr.data()), baseptr.data());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
}
void tst_QSharedPointer::dynamicCastFailure()
@@ -1355,15 +1418,15 @@ void tst_QSharedPointer::dynamicCastFailure()
QSharedPointer<DerivedData> derivedptr = qSharedPointerDynamicCast<DerivedData>(baseptr);
QVERIFY(derivedptr.isNull());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
{
QSharedPointer<DerivedData> derivedptr = baseptr.dynamicCast<DerivedData>();
QVERIFY(derivedptr.isNull());
}
- QCOMPARE(int(refCountData(baseptr)->weakref.load()), 1);
- QCOMPARE(int(refCountData(baseptr)->strongref.load()), 1);
+ QCOMPARE(int(refCountData(baseptr)->weakref.loadRelaxed()), 1);
+ QCOMPARE(int(refCountData(baseptr)->strongref.loadRelaxed()), 1);
}
void tst_QSharedPointer::dynamicCastFailureNoLeak()
@@ -1670,7 +1733,6 @@ void tst_QSharedPointer::customDeleter()
safetyCheck();
}
-#ifdef Q_COMPILER_LAMBDA
// The compiler needs to be in C++11 mode and to support lambdas
void tst_QSharedPointer::lambdaCustomDeleter()
{
@@ -1698,7 +1760,33 @@ void tst_QSharedPointer::lambdaCustomDeleter()
}
safetyCheck();
}
-#endif
+
+void tst_QSharedPointer::customDeleterOnNullptr()
+{
+ Data *null = nullptr;
+ int callCount = 0;
+ auto deleter = [&callCount](Data *) { ++callCount; };
+ {
+ QSharedPointer<Data> ptr(null, deleter);
+ }
+ safetyCheck();
+ QCOMPARE(callCount, 1);
+
+ callCount = 0;
+ {
+ QSharedPointer<Data> ptr(nullptr, deleter);
+ }
+ safetyCheck();
+ QCOMPARE(callCount, 1);
+
+ callCount = 0;
+ {
+ QSharedPointer<Data> ptr1(null, deleter);
+ QSharedPointer<Data> ptr2(nullptr, deleter);
+ }
+ safetyCheck();
+ QCOMPARE(callCount, 2);
+}
void customQObjectDeleterFn(QObject *obj)
{
@@ -1734,8 +1822,8 @@ void tst_QSharedPointer::creating()
QCOMPARE(Data::destructorCounter, 1);
// valgrind will complain here if something happened to the pointer
- QVERIFY(d->weakref.load() == 1);
- QVERIFY(d->strongref.load() == 0);
+ QVERIFY(d->weakref.loadRelaxed() == 1);
+ QVERIFY(d->strongref.loadRelaxed() == 0);
}
safetyCheck();
@@ -1820,15 +1908,20 @@ void tst_QSharedPointer::creatingVariadic()
QCOMPARE(&ptr->i, &i);
}
{
- NoDefaultConstructorRRef1(1); // control check
- QSharedPointer<NoDefaultConstructorRRef1> ptr = QSharedPointer<NoDefaultConstructorRRef1>::create(1);
- QCOMPARE(ptr->i, 1);
-
NoDefaultConstructorRRef1(std::move(i)); // control check
- ptr = QSharedPointer<NoDefaultConstructorRRef1>::create(std::move(i));
+ QSharedPointer<NoDefaultConstructorRRef1> ptr = QSharedPointer<NoDefaultConstructorRRef1>::create(std::move(i));
QCOMPARE(ptr->i, i);
}
{
+ NoDefaultConstructorRRef2(std::unique_ptr<int>(new int(1))); // control check
+ QSharedPointer<NoDefaultConstructorRRef2> ptr = QSharedPointer<NoDefaultConstructorRRef2>::create(std::unique_ptr<int>(new int(1)));
+ QCOMPARE(*ptr->i, 1);
+
+ std::unique_ptr<int> p(new int(i));
+ ptr = QSharedPointer<NoDefaultConstructorRRef2>::create(std::move(p));
+ QCOMPARE(*ptr->i, i);
+ }
+ {
QString text("Hello, World");
NoDefaultConstructorRef2(text, 1); // control check
QSharedPointer<NoDefaultConstructorRef2> ptr = QSharedPointer<NoDefaultConstructorRef2>::create(text, 1);
@@ -1893,7 +1986,7 @@ class ThreadData
QAtomicInt * volatile ptr;
public:
ThreadData(QAtomicInt *p) : ptr(p) { }
- ~ThreadData() { ++ptr; }
+ ~ThreadData() { QtPrivate::volatilePreIncrement(ptr); }
void ref()
{
// if we're called after the destructor, we'll crash
@@ -1904,9 +1997,9 @@ public:
class StrongThread: public QThread
{
protected:
- void run()
+ void run() override
{
- usleep(QRandomGenerator::global()->bounded(2000));
+ sleep(std::chrono::microseconds{QRandomGenerator::global()->bounded(2000)});
ptr->ref();
ptr.clear();
}
@@ -1917,9 +2010,9 @@ public:
class WeakThread: public QThread
{
protected:
- void run()
+ void run() override
{
- usleep(QRandomGenerator::global()->bounded(2000));
+ sleep(std::chrono::microseconds{QRandomGenerator::global()->bounded(2000)});
QSharedPointer<ThreadData> ptr = weak;
if (ptr)
ptr->ref();
@@ -1963,9 +2056,9 @@ void tst_QSharedPointer::threadStressTest()
memset(guard2, 0, sizeof guard2);
for (int r = 0; r < 5; ++r) {
- QVector<QThread*> allThreads(6 * qMax(strongThreadCount, weakThreadCount) + 3, 0);
+ QList<QThread*> allThreads(6 * qMax(strongThreadCount, weakThreadCount) + 3, 0);
QSharedPointer<ThreadData> base = QSharedPointer<ThreadData>(new ThreadData(&counter));
- counter.store(0);
+ counter.storeRelaxed(0);
// set the pointers
for (int i = 0; i < strongThreadCount; ++i) {
@@ -1982,11 +2075,11 @@ void tst_QSharedPointer::threadStressTest()
base.clear();
// start threads
- for (int i = 0; i < allThreads.count(); ++i)
+ for (int i = 0; i < allThreads.size(); ++i)
if (allThreads[i]) allThreads[i]->start();
// wait for them to finish
- for (int i = 0; i < allThreads.count(); ++i)
+ for (int i = 0; i < allThreads.size(); ++i)
if (allThreads[i]) allThreads[i]->wait();
qDeleteAll(allThreads);
@@ -1999,12 +2092,12 @@ void tst_QSharedPointer::threadStressTest()
// verify that the count is the right range
int minValue = strongThreadCount;
int maxValue = strongThreadCount + weakThreadCount;
- QVERIFY(counter.load() >= minValue);
- QVERIFY(counter.load() <= maxValue);
+ QVERIFY(counter.loadRelaxed() >= minValue);
+ QVERIFY(counter.loadRelaxed() <= maxValue);
}
}
-template<typename Container, bool Ordered>
+template<typename Container, bool Ordered, bool Multi>
void hashAndMapTest()
{
typedef typename Container::key_type Key;
@@ -2049,26 +2142,30 @@ void hashAndMapTest()
QVERIFY(it == c.end());
}
- c.insertMulti(k1, Value(47));
- it = c.find(k1);
- QVERIFY(it != c.end());
- QCOMPARE(it.key(), k1);
- ++it;
- QVERIFY(it != c.end());
- QCOMPARE(it.key(), k1);
- ++it;
- if (Ordered)
- QVERIFY(it == c.end());
+ if (Multi) {
+ c.insert(k1, Value(47));
+ it = c.find(k1);
+ QVERIFY(it != c.end());
+ QCOMPARE(it.key(), k1);
+ ++it;
+ QVERIFY(it != c.end());
+ QCOMPARE(it.key(), k1);
+ ++it;
+ if (Ordered)
+ QVERIFY(it == c.end());
+ }
}
void tst_QSharedPointer::map()
{
- hashAndMapTest<QMap<QSharedPointer<int>, int>, true>();
+ hashAndMapTest<QMap<QSharedPointer<int>, int>, true, false>();
+ hashAndMapTest<QMultiMap<QSharedPointer<int>, int>, true, true>();
}
void tst_QSharedPointer::hash()
{
- hashAndMapTest<QHash<QSharedPointer<int>, int>, false>();
+ hashAndMapTest<QHash<QSharedPointer<int>, int>, false, false>();
+ hashAndMapTest<QMultiHash<QSharedPointer<int>, int>, false, true>();
}
void tst_QSharedPointer::validConstructs()
@@ -2077,7 +2174,10 @@ void tst_QSharedPointer::validConstructs()
Data *aData = new Data;
QSharedPointer<Data> ptr1 = QSharedPointer<Data>(aData);
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
ptr1 = ptr1; // valid
+QT_WARNING_POP
QSharedPointer<Data> ptr2(ptr1);
@@ -2089,6 +2189,7 @@ void tst_QSharedPointer::validConstructs()
}
}
+#if 0
typedef bool (QTest::QExternalTest:: * TestFunction)(const QByteArray &body);
Q_DECLARE_METATYPE(TestFunction)
void tst_QSharedPointer::invalidConstructs_data()
@@ -2217,12 +2318,12 @@ void tst_QSharedPointer::invalidConstructs_data()
QTest::newRow("weak-pointer-from-regular-pointer")
<< &QTest::QExternalTest::tryCompileFail
- << "Data *ptr = 0;\n"
+ << "Data *ptr = nullptr;\n"
"QWeakPointer<Data> weakptr(ptr);\n";
QTest::newRow("shared-pointer-implicit-from-uninitialized")
<< &QTest::QExternalTest::tryCompileFail
- << "Data *ptr = 0;\n"
+ << "Data *ptr = nullptr;\n"
"QSharedPointer<Data> weakptr = Qt::Uninitialized;\n";
QTest::newRow("incompatible-custom-deleter1")
@@ -2233,11 +2334,14 @@ void tst_QSharedPointer::invalidConstructs_data()
<< &QTest::QExternalTest::tryCompileFail
<< "struct IncompatibleCustomDeleter { void operator()(int *); };\n"
"QSharedPointer<Data> ptr(new Data, IncompatibleCustomDeleter());\n";
-#ifdef Q_COMPILER_LAMBDA
QTest::newRow("incompatible-custom-lambda-deleter")
<< &QTest::QExternalTest::tryCompileFail
<< "QSharedPointer<Data> ptr(new Data, [](int *) {});\n";
-#endif
+
+ QTest::newRow("incompatible-overload")
+ << &QTest::QExternalTest::tryCompileFail
+ << "void foo(QSharedPointer<DerivedData>) {}\n"
+ "void bar() { foo(QSharedPointer<Data>()); }\n";
}
void tst_QSharedPointer::invalidConstructs()
@@ -2295,6 +2399,7 @@ void tst_QSharedPointer::invalidConstructs()
QFAIL("Fail");
}
}
+#endif // #if 0
void tst_QSharedPointer::qvariantCast()
{
@@ -2320,50 +2425,6 @@ void tst_QSharedPointer::qvariantCast()
}
// Intentionally does not compile.
// QSharedPointer<int> sop = qSharedPointerFromVariant<int>(v);
-
- v = QVariant::fromValue(sp.toWeakRef());
-
- {
- QWeakPointer<QObject> other = qWeakPointerFromVariant<QObject>(v);
- QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
- }
- {
- QWeakPointer<QIODevice> other = qWeakPointerFromVariant<QIODevice>(v);
- QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
- }
- {
- QWeakPointer<QFile> other = qWeakPointerFromVariant<QFile>(v);
- QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
- }
- {
- QWeakPointer<QThread> other = qWeakPointerFromVariant<QThread>(v);
- QVERIFY(!other);
- }
-
- // Intentionally does not compile.
-// QWeakPointer<int> sop = qWeakPointerFromVariant<int>(v);
-
- QFile file;
- QWeakPointer<QFile> tracking = &file;
- tracking.data()->setObjectName("A test name");
- v = QVariant::fromValue(tracking);
-
- {
- QWeakPointer<QObject> other = qWeakPointerFromVariant<QObject>(v);
- QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
- }
- {
- QWeakPointer<QIODevice> other = qWeakPointerFromVariant<QIODevice>(v);
- QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
- }
- {
- QWeakPointer<QFile> other = qWeakPointerFromVariant<QFile>(v);
- QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
- }
- {
- QWeakPointer<QThread> other = qWeakPointerFromVariant<QThread>(v);
- QVERIFY(!other);
- }
}
class SomeClass : public QEnableSharedFromThis<SomeClass>
@@ -2668,7 +2729,7 @@ void tst_QSharedPointer::constructorThrow()
int childDestructorCounter = ThrowData::childDestructorCounter;
QSharedPointer<ThrowData> ptr;
- QVERIFY_EXCEPTION_THROWN(ptr = QSharedPointer<ThrowData>::create(), QString);
+ QVERIFY_THROWS_EXCEPTION(QString, ptr = QSharedPointer<ThrowData>::create());
QVERIFY(ptr.isNull());
QCOMPARE(ThrowData::childGenerationCounter, childGeneration + 1);
// destructor should never be called, if a constructor throws
@@ -2710,7 +2771,7 @@ namespace ReentrancyWhileDestructing {
{
QSharedPointer<IB> b;
- virtual QSharedPointer<IB> getB()
+ virtual QSharedPointer<IB> getB() override
{
return b;
}
@@ -2736,5 +2797,185 @@ void tst_QSharedPointer::reentrancyWhileDestructing()
ReentrancyWhileDestructing::A obj;
}
+namespace {
+struct Base1 {};
+struct Base2 {};
+
+struct Child1 : Base1 {};
+struct Child2 : Base2 {};
+
+template<template<typename> class SmartPtr>
+struct Overloaded
+{
+ std::array<int, 1> call(const SmartPtr<const Base1> &)
+ {
+ return {};
+ }
+ std::array<int, 2> call(const SmartPtr<const Base2> &)
+ {
+ return {};
+ }
+ static const constexpr uint base1Called = sizeof(std::array<int, 1>);
+ static const constexpr uint base2Called = sizeof(std::array<int, 2>);
+
+ void test()
+ {
+#define QVERIFY_CALLS(expr, base) static_assert(sizeof(call(expr)) == base##Called)
+ QVERIFY_CALLS(SmartPtr<Base1>{}, base1);
+ QVERIFY_CALLS(SmartPtr<Base2>{}, base2);
+ QVERIFY_CALLS(SmartPtr<const Base1>{}, base1);
+ QVERIFY_CALLS(SmartPtr<const Base2>{}, base2);
+ QVERIFY_CALLS(SmartPtr<Child1>{}, base1);
+ QVERIFY_CALLS(SmartPtr<Child2>{}, base2);
+ QVERIFY_CALLS(SmartPtr<const Child1>{}, base1);
+ QVERIFY_CALLS(SmartPtr<const Child2>{}, base2);
+#undef QVERIFY_CALLS
+ }
+};
+}
+
+void tst_QSharedPointer::overloads()
+{
+ Overloaded<QSharedPointer> sharedOverloaded;
+ sharedOverloaded.test();
+ Overloaded<QWeakPointer> weakOverloaded;
+ weakOverloaded.test();
+}
+
+void tst_QSharedPointer::ownerComparisons()
+{
+ using SP = QSharedPointer<int>;
+ using WP = QWeakPointer<int>;
+
+#define CHECK_EQ(a, b) \
+ do { \
+ QVERIFY(a.owner_equal(b)); \
+ QVERIFY(b.owner_equal(a)); \
+ QVERIFY(!a.owner_before(b)); \
+ QVERIFY(!b.owner_before(a)); \
+ QVERIFY(a.owner_hash() == b.owner_hash()); \
+ } while (false)
+
+#define CHECK_NOT_EQ(a, b) \
+ do { \
+ QVERIFY(!a.owner_equal(b)); \
+ QVERIFY(!b.owner_equal(a)); \
+ QVERIFY(a.owner_before(b) || b.owner_before(a)); \
+ } while (false)
+
+ // null
+ {
+ SP sp1;
+ SP sp2;
+ WP wp1 = sp1;
+ WP wp2;
+
+ CHECK_EQ(sp1, sp1);
+ CHECK_EQ(sp1, sp2);
+ CHECK_EQ(sp1, wp1);
+ CHECK_EQ(sp2, wp2);
+ CHECK_EQ(wp1, wp1);
+ CHECK_EQ(wp1, wp2);
+ CHECK_EQ(wp2, wp2);
+ }
+
+ // same owner
+ {
+ SP sp1 = SP::create(123);
+ SP sp2 = sp1;
+ WP wp1 = sp1;
+ SP wp2 = sp2;
+
+ CHECK_EQ(sp1, sp1);
+ CHECK_EQ(sp1, sp2);
+ CHECK_EQ(sp1, wp1);
+ CHECK_EQ(sp2, wp2);
+ CHECK_EQ(wp1, wp1);
+ CHECK_EQ(wp1, wp2);
+ }
+
+ // owning vs null
+ {
+ SP sp1 = SP::create(123);
+ SP sp2;
+ WP wp1 = sp1;
+ WP wp2 = sp2;
+
+ CHECK_EQ(sp1, sp1);
+ CHECK_NOT_EQ(sp1, sp2);
+ CHECK_EQ(sp1, wp1);
+ CHECK_EQ(sp2, wp2);
+ CHECK_EQ(wp1, wp1);
+ CHECK_NOT_EQ(wp1, wp2);
+ }
+
+ // different owners
+ {
+ SP sp1 = SP::create(123);
+ SP sp2 = SP::create(456);
+ WP wp1 = sp1;
+ WP wp2 = sp2;
+
+ CHECK_EQ(sp1, sp1);
+ CHECK_NOT_EQ(sp1, sp2);
+ CHECK_EQ(sp1, wp1);
+ CHECK_EQ(sp2, wp2);
+ CHECK_EQ(wp1, wp1);
+ CHECK_NOT_EQ(wp1, wp2);
+ }
+
+ // reset vs. null
+ {
+ SP sp1 = SP::create(123);
+ SP sp2;
+ WP wp1 = sp1;
+ WP wp2;
+
+ CHECK_EQ(sp1, sp1);
+ CHECK_NOT_EQ(sp1, sp2);
+ CHECK_EQ(sp1, wp1);
+ CHECK_NOT_EQ(sp1, wp2);
+ CHECK_EQ(wp1, wp1);
+ CHECK_NOT_EQ(wp1, wp2);
+
+ sp1.reset();
+
+ CHECK_EQ(sp1, sp1);
+ CHECK_EQ(sp1, sp2);
+ CHECK_NOT_EQ(sp1, wp1);
+ CHECK_EQ(sp2, wp2);
+ CHECK_EQ(wp1, wp1);
+ CHECK_NOT_EQ(wp1, wp2);
+ }
+
+ // expired weak pointers
+ {
+ WP wp1 = SP::create(123);
+ WP wp2;
+
+ CHECK_EQ(wp1, wp1);
+ CHECK_NOT_EQ(wp1, wp2);
+ }
+
+ {
+ WP wp1 = SP::create(123);
+ WP wp2 = wp1;
+
+ CHECK_EQ(wp1, wp1);
+ CHECK_EQ(wp1, wp2);
+ }
+
+ {
+ WP wp1 = SP::create(123);
+ WP wp2 = SP::create(456);
+
+ CHECK_EQ(wp1, wp1);
+ CHECK_EQ(wp2, wp2);
+ CHECK_NOT_EQ(wp1, wp2);
+ }
+#undef CHECK_EQ
+#undef CHECK_NOT_EQ
+}
+
QTEST_MAIN(tst_QSharedPointer)
#include "tst_qsharedpointer.moc"
diff --git a/tests/auto/corelib/tools/qsharedpointer/wrapper.cpp b/tests/auto/corelib/tools/qsharedpointer/wrapper.cpp
index 24a0cdc9c1..b39eee7d98 100644
--- a/tests/auto/corelib/tools/qsharedpointer/wrapper.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/wrapper.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
# undef QT_SHAREDPOINTER_TRACK_POINTERS
diff --git a/tests/auto/corelib/tools/qsharedpointer/wrapper.h b/tests/auto/corelib/tools/qsharedpointer/wrapper.h
index 18cea6e199..3b0bc09fed 100644
--- a/tests/auto/corelib/tools/qsharedpointer/wrapper.h
+++ b/tests/auto/corelib/tools/qsharedpointer/wrapper.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef WRAPPER_H
#define WRAPPER_H
diff --git a/tests/auto/corelib/tools/qsize/CMakeLists.txt b/tests/auto/corelib/tools/qsize/CMakeLists.txt
new file mode 100644
index 0000000000..91de696ddd
--- /dev/null
+++ b/tests/auto/corelib/tools/qsize/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsize Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsize LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsize
+ SOURCES
+ tst_qsize.cpp
+)
diff --git a/tests/auto/corelib/tools/qsize/qsize.pro b/tests/auto/corelib/tools/qsize/qsize.pro
deleted file mode 100644
index 9462e98e49..0000000000
--- a/tests/auto/corelib/tools/qsize/qsize.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsize
-QT = core testlib
-SOURCES = tst_qsize.cpp
diff --git a/tests/auto/corelib/tools/qsize/tst_qsize.cpp b/tests/auto/corelib/tools/qsize/tst_qsize.cpp
index 385ff18ce5..c9699c5e76 100644
--- a/tests/auto/corelib/tools/qsize/tst_qsize.cpp
+++ b/tests/auto/corelib/tools/qsize/tst_qsize.cpp
@@ -1,34 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QSize>
+#ifdef QVARIANT_H
+# error "This test requires qsize.h to not include qvariant.h"
+#endif
+
+// don't assume <type_traits>
+template <typename T, typename U>
+constexpr inline bool my_is_same_v = false;
+template <typename T>
+constexpr inline bool my_is_same_v<T, T> = true;
+
+#define CHECK(cvref) \
+ static_assert(my_is_same_v<decltype(get<0>(std::declval<QSize cvref >())), int cvref >); \
+ static_assert(my_is_same_v<decltype(get<1>(std::declval<QSize cvref >())), int cvref >)
+
+CHECK(&);
+CHECK(const &);
+CHECK(&&);
+CHECK(const &&);
+
+#undef CHECK
+
+#include <QTest>
#include <qsize.h>
+#include <array>
+
+Q_DECLARE_METATYPE(QMargins)
class tst_QSize : public QObject
{
@@ -43,8 +43,16 @@ private slots:
void boundedTo_data();
void boundedTo();
+ void grownOrShrunkBy_data();
+ void grownOrShrunkBy();
+
+ void toSizeF_data();
+ void toSizeF();
+
void transpose_data();
void transpose();
+
+ void structuredBinding();
};
// Testing get/set functions
@@ -186,6 +194,70 @@ void tst_QSize::boundedTo()
QCOMPARE( input1.boundedTo(input2), expected);
}
+void tst_QSize::grownOrShrunkBy_data()
+{
+ QTest::addColumn<QSize>("input");
+ QTest::addColumn<QMargins>("margins");
+ QTest::addColumn<QSize>("grown");
+ QTest::addColumn<QSize>("shrunk");
+
+ auto row = [](QSize i, QMargins m, QSize g, QSize s) {
+ QTest::addRow("{%d,%d}/{%d,%d,%d,%d}", i.width(), i.height(),
+ m.left(), m.top(), m.right(), m.bottom())
+ << i << m << g << s;
+ };
+
+ const QSize zero = {0, 0};
+ const QSize some = {100, 200};
+ const QMargins zeroMargins = {};
+ const QMargins negative = {-1, -2, -3, -4};
+ const QMargins positive = { 1, 2, 3, 4};
+
+ row(zero, zeroMargins, zero, zero);
+ row(zero, negative, {-4, -6}, { 4, 6});
+ row(zero, positive, { 4, 6}, {-4, -6});
+ row(some, zeroMargins, some, some);
+ row(some, negative, { 96, 194}, {104, 206});
+ row(some, positive, {104, 206}, { 96, 194});
+}
+
+void tst_QSize::grownOrShrunkBy()
+{
+ QFETCH(const QSize, input);
+ QFETCH(const QMargins, margins);
+ QFETCH(const QSize, grown);
+ QFETCH(const QSize, shrunk);
+
+ QCOMPARE(input.grownBy(margins), grown);
+ QCOMPARE(input.shrunkBy(margins), shrunk);
+ QCOMPARE(grown.shrunkBy(margins), input);
+ QCOMPARE(shrunk.grownBy(margins), input);
+}
+
+void tst_QSize::toSizeF_data()
+{
+ QTest::addColumn<QSize>("input");
+ QTest::addColumn<QSizeF>("result");
+
+ auto row = [](int w, int h) {
+ QTest::addRow("(%d, %d)", w, h) << QSize(w, h) << QSizeF(w, h);
+ };
+ constexpr std::array samples = {-1, 0, 1};
+ for (int w : samples) {
+ for (int h : samples) {
+ row(w, h);
+ }
+ }
+}
+
+void tst_QSize::toSizeF()
+{
+ QFETCH(const QSize, input);
+ QFETCH(const QSizeF, result);
+
+ QCOMPARE(input.toSizeF(), result);
+}
+
void tst_QSize::transpose_data()
{
QTest::addColumn<QSize>("input1");
@@ -206,5 +278,26 @@ void tst_QSize::transpose()
QCOMPARE(input1 , expected);
}
+void tst_QSize::structuredBinding()
+{
+ {
+ QSize size(10, 20);
+ auto [width, height] = size;
+ QCOMPARE(width, 10);
+ QCOMPARE(height, 20);
+ }
+ {
+ QSize size(30, 40);
+ auto &[width, height] = size;
+ QCOMPARE(width, 30);
+ QCOMPARE(height, 40);
+
+ width = 100;
+ height = 200;
+ QCOMPARE(size.width(), 100);
+ QCOMPARE(size.height(), 200);
+ }
+}
+
QTEST_APPLESS_MAIN(tst_QSize)
#include "tst_qsize.moc"
diff --git a/tests/auto/corelib/tools/qsizef/CMakeLists.txt b/tests/auto/corelib/tools/qsizef/CMakeLists.txt
new file mode 100644
index 0000000000..9adaafe2ea
--- /dev/null
+++ b/tests/auto/corelib/tools/qsizef/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qsizef Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qsizef LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qsizef
+ SOURCES
+ tst_qsizef.cpp
+)
diff --git a/tests/auto/corelib/tools/qsizef/qsizef.pro b/tests/auto/corelib/tools/qsizef/qsizef.pro
deleted file mode 100644
index f5ba220b06..0000000000
--- a/tests/auto/corelib/tools/qsizef/qsizef.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsizef
-QT = core testlib
-SOURCES = tst_qsizef.cpp
diff --git a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp
index 42801d63a9..ee33fa13b6 100644
--- a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp
+++ b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp
@@ -1,34 +1,32 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QSizeF>
+#ifdef QVARIANT_H
+# error "This test requires qsize.h to not include qvariant.h"
+#endif
+
+// don't assume <type_traits>
+template <typename T, typename U>
+constexpr inline bool my_is_same_v = false;
+template <typename T>
+constexpr inline bool my_is_same_v<T, T> = true;
+
+#define CHECK(cvref) \
+ static_assert(my_is_same_v<decltype(get<0>(std::declval<QSizeF cvref >())), qreal cvref >); \
+ static_assert(my_is_same_v<decltype(get<1>(std::declval<QSizeF cvref >())), qreal cvref >)
+
+CHECK(&);
+CHECK(const &);
+CHECK(&&);
+CHECK(const &&);
+
+#undef CHECK
+
+#include <QTest>
#include <qsize.h>
+Q_DECLARE_METATYPE(QMarginsF)
class tst_QSizeF : public QObject
{
@@ -45,8 +43,13 @@ private slots:
void boundedTo_data();
void boundedTo();
+ void grownOrShrunkBy_data();
+ void grownOrShrunkBy();
+
void transpose_data();
void transpose();
+
+ void structuredBinding();
};
void tst_QSizeF::isNull_data()
@@ -152,6 +155,46 @@ void tst_QSizeF::boundedTo() {
QCOMPARE( input1.boundedTo(input2), expected);
}
+void tst_QSizeF::grownOrShrunkBy_data()
+{
+ QTest::addColumn<QSizeF>("input");
+ QTest::addColumn<QMarginsF>("margins");
+ QTest::addColumn<QSizeF>("grown");
+ QTest::addColumn<QSizeF>("shrunk");
+
+ auto row = [](QSizeF i, QMarginsF m, QSizeF g, QSizeF s) {
+ QTest::addRow("{%g,%g}/{%g,%g,%g,%g}", i.width(), i.height(),
+ m.left(), m.top(), m.right(), m.bottom())
+ << i << m << g << s;
+ };
+
+ const QSizeF zero = {0, 0};
+ const QSizeF some = {100, 200};
+ const QMarginsF zeroMargins = {};
+ const QMarginsF negative = {-1, -2, -3, -4};
+ const QMarginsF positive = { 1, 2, 3, 4};
+
+ row(zero, zeroMargins, zero, zero);
+ row(zero, negative, {-4, -6}, { 4, 6});
+ row(zero, positive, { 4, 6}, {-4, -6});
+ row(some, zeroMargins, some, some);
+ row(some, negative, { 96, 194}, {104, 206});
+ row(some, positive, {104, 206}, { 96, 194});
+}
+
+void tst_QSizeF::grownOrShrunkBy()
+{
+ QFETCH(const QSizeF, input);
+ QFETCH(const QMarginsF, margins);
+ QFETCH(const QSizeF, grown);
+ QFETCH(const QSizeF, shrunk);
+
+ QCOMPARE(input.grownBy(margins), grown);
+ QCOMPARE(input.shrunkBy(margins), shrunk);
+ QCOMPARE(grown.shrunkBy(margins), input);
+ QCOMPARE(shrunk.grownBy(margins), input);
+}
+
void tst_QSizeF::transpose_data() {
QTest::addColumn<QSizeF>("input1");
QTest::addColumn<QSizeF>("expected");
@@ -170,5 +213,26 @@ void tst_QSizeF::transpose() {
QCOMPARE(input1 , expected);
}
+void tst_QSizeF::structuredBinding()
+{
+ {
+ QSizeF size(10.0, 20.0);
+ auto [width, height] = size;
+ QCOMPARE(width, 10.0);
+ QCOMPARE(height, 20.0);
+ }
+ {
+ QSizeF size(30.0, 40.0);
+ auto &[width, height] = size;
+ QCOMPARE(width, 30.0);
+ QCOMPARE(height, 40.0);
+
+ width = 100.0;
+ height = 200.0;
+ QCOMPARE(size.width(), 100.0);
+ QCOMPARE(size.height(), 200.0);
+ }
+}
+
QTEST_APPLESS_MAIN(tst_QSizeF)
#include "tst_qsizef.moc"
diff --git a/tests/auto/corelib/tools/qspan/CMakeLists.txt b/tests/auto/corelib/tools/qspan/CMakeLists.txt
new file mode 100644
index 0000000000..595d19dc43
--- /dev/null
+++ b/tests/auto/corelib/tools/qspan/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qspan LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qspan
+ SOURCES
+ tst_qspan.cpp
+)
diff --git a/tests/auto/corelib/tools/qspan/tst_qspan.cpp b/tests/auto/corelib/tools/qspan/tst_qspan.cpp
new file mode 100644
index 0000000000..91d2ecf739
--- /dev/null
+++ b/tests/auto/corelib/tools/qspan/tst_qspan.cpp
@@ -0,0 +1,450 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QSpan>
+
+#include <QList>
+#include <QTest>
+
+#include <algorithm>
+#include <array>
+#ifdef __cpp_lib_span
+#include <span>
+#endif
+#include <vector>
+
+namespace {
+
+struct NotNothrowMovable {
+ NotNothrowMovable(NotNothrowMovable &&) noexcept(false) {};
+ NotNothrowMovable &operator=(NotNothrowMovable &&) noexcept(false) { return *this; };
+};
+static_assert(!std::is_nothrow_move_constructible_v<NotNothrowMovable>);
+static_assert(!std::is_nothrow_move_assignable_v<NotNothrowMovable>);
+
+} // unnamed namespace
+
+//
+// QSpan is nothrow movable even if the payload type is not:
+//
+static_assert(std::is_nothrow_move_constructible_v<QSpan<NotNothrowMovable>>);
+static_assert(std::is_nothrow_move_constructible_v<QSpan<NotNothrowMovable, 42>>);
+static_assert(std::is_nothrow_move_constructible_v<QSpan<NotNothrowMovable, 0>>);
+
+static_assert(std::is_nothrow_move_assignable_v<QSpan<NotNothrowMovable>>);
+static_assert(std::is_nothrow_move_assignable_v<QSpan<NotNothrowMovable, 42>>);
+static_assert(std::is_nothrow_move_assignable_v<QSpan<NotNothrowMovable, 0>>);
+
+//
+// All QSpans are trivially destructible and trivially copyable:
+//
+static_assert(std::is_trivially_copyable_v<QSpan<NotNothrowMovable>>);
+static_assert(std::is_trivially_copyable_v<QSpan<NotNothrowMovable, 42>>);
+static_assert(std::is_trivially_copyable_v<QSpan<NotNothrowMovable, 0>>);
+
+static_assert(std::is_trivially_destructible_v<QSpan<NotNothrowMovable>>);
+static_assert(std::is_trivially_destructible_v<QSpan<NotNothrowMovable, 42>>);
+static_assert(std::is_trivially_destructible_v<QSpan<NotNothrowMovable, 0>>);
+
+//
+// Fixed-size QSpans implicitly convert to variable-sized ones:
+//
+static_assert(std::is_convertible_v<QSpan<int, 42>, QSpan<int>>);
+static_assert(std::is_convertible_v<QSpan<int, 0>, QSpan<int>>);
+
+#ifdef __cpp_lib_span
+static_assert(std::is_convertible_v<std::span<int, 42>, QSpan<int>>);
+static_assert(std::is_convertible_v<std::span<int, 0>, QSpan<int>>);
+
+#ifdef __cpp_lib_concepts
+// requires enable_borrowed_range
+static_assert(std::is_convertible_v<QSpan<int, 42>, std::span<int>>);
+static_assert(std::is_convertible_v<QSpan<int, 0>, std::span<int>>);
+#endif // __cpp_lib_concepts
+#endif // __cpp_lib_span
+
+//
+// Mutable spans implicitly convert to read-only ones, but not vice versa:
+//
+static_assert(std::is_convertible_v<QSpan<int>, QSpan<const int>>);
+static_assert(std::is_convertible_v<QSpan<int, 42>, QSpan<const int, 42>>);
+static_assert(std::is_convertible_v<QSpan<int, 0>, QSpan<const int, 0>>);
+
+static_assert(!std::is_convertible_v<QSpan<const int>, QSpan<int>>);
+static_assert(!std::is_convertible_v<QSpan<const int, 42>, QSpan<int, 42>>);
+static_assert(!std::is_convertible_v<QSpan<const int, 0>, QSpan<int, 0>>);
+
+#ifdef __cpp_lib_span
+static_assert(std::is_convertible_v<std::span<int>, QSpan<const int>>);
+static_assert(std::is_convertible_v<std::span<int, 42>, QSpan<const int, 42>>);
+static_assert(std::is_convertible_v<std::span<int, 0>, QSpan<const int, 0>>);
+
+static_assert(!std::is_convertible_v<std::span<const int>, QSpan<int>>);
+static_assert(!std::is_convertible_v<std::span<const int, 42>, QSpan<int, 42>>);
+static_assert(!std::is_convertible_v<std::span<const int, 0>, QSpan<int, 0>>);
+
+static_assert(std::is_convertible_v<QSpan<int>, std::span<const int>>);
+// fixed-size std::span constructors are explicit:
+static_assert(!std::is_convertible_v<QSpan<int, 42>, std::span<const int, 42>>);
+static_assert(!std::is_convertible_v<QSpan<int, 0>, std::span<const int, 0>>);
+// observe: is_convertible<From,To>, but is_constuctible<To,From>!
+static_assert(std::is_constructible_v<std::span<const int, 42>, QSpan<int, 42>>);
+static_assert(std::is_constructible_v<std::span<const int, 0>, QSpan<int, 0>>);
+
+static_assert(!std::is_convertible_v<QSpan<const int>, std::span<int>>);
+static_assert(!std::is_convertible_v<QSpan<const int, 42>, std::span<int, 42>>);
+static_assert(!std::is_convertible_v<QSpan<const int, 0>, std::span<int, 0>>);
+#endif // __cpp_lib_span
+
+// Spans don't convert from nonsense:
+static_assert(!std::is_constructible_v<QSpan<const int>, int&&>);
+
+// Span is constructible from initializer_list
+static_assert( std::is_convertible_v<std::initializer_list<int>, QSpan<const int>>);
+static_assert(!std::is_convertible_v<std::initializer_list<int>, QSpan< int>>);
+static_assert(!std::is_constructible_v<QSpan<int>, std::initializer_list<int>>);
+
+static_assert( std::is_convertible_v<std::initializer_list<int>, QSpan<const int, 4>>); // non-standard, but QSpan considers initializer_list a range
+static_assert( std::is_constructible_v<QSpan<const int, 4>, std::initializer_list<int>>);
+static_assert(!std::is_constructible_v<QSpan< int, 4>, std::initializer_list<int>>);
+
+class tst_QSpan : public QObject
+{
+ Q_OBJECT
+public:
+ using QObject::QObject;
+
+private Q_SLOTS:
+ void onlyZeroExtentSpansHaveDefaultCtors() const;
+ void zeroExtentSpansMaintainADataPointer() const;
+ void fromArray() const;
+ void fromStdArray() const;
+ void fromStdInitializerList() const;
+ void fromZeroSizeStdArray() const;
+ void fromStdVector() const;
+ void fromQList() const;
+ void fromInitList() const;
+
+private:
+ template <typename T, std::size_t N>
+ void check_nonempty_span(QSpan<T, N>, qsizetype expectedSize) const;
+ template <typename T, std::size_t N>
+ void check_empty_span_incl_subspans(QSpan<T, N>) const;
+ template <typename T, std::size_t N>
+ void check_empty_span(QSpan<T, N>) const;
+ template <typename T, std::size_t N>
+ void check_null_span(QSpan<T, N>) const;
+
+ template <std::size_t ExpectedExtent, typename C>
+ void from_container_impl(C &&c) const;
+ template <typename C>
+ void from_variable_size_container_impl(C &&c) const;
+};
+
+#define RETURN_IF_FAILED() \
+ do { if (QTest::currentTestFailed()) return; } while (false)
+
+void tst_QSpan::onlyZeroExtentSpansHaveDefaultCtors() const
+{
+ static_assert(std::is_nothrow_default_constructible_v<QSpan<int, 0>>);
+ static_assert(std::is_nothrow_default_constructible_v<QSpan<const int, 0>>);
+ static_assert(std::is_nothrow_default_constructible_v<QSpan<int>>);
+ static_assert(std::is_nothrow_default_constructible_v<QSpan<const int, 0>>);
+
+ QSpan<int, 0> si;
+ check_null_span(si);
+ RETURN_IF_FAILED();
+
+ QSpan<const int, 0> sci;
+ check_null_span(sci);
+ RETURN_IF_FAILED();
+
+ QSpan<int> sdi;
+ check_null_span(sdi);
+ RETURN_IF_FAILED();
+
+ QSpan<const int> sdci;
+ check_null_span(sdci);
+ RETURN_IF_FAILED();
+
+ static_assert(!std::is_default_constructible_v<QSpan<int, 1>>);
+ static_assert(!std::is_default_constructible_v<QSpan<const int, 42>>);
+}
+
+void tst_QSpan::zeroExtentSpansMaintainADataPointer() const
+{
+ int i;
+ QSpan<int, 0> si{&i, 0};
+ QCOMPARE(si.data(), &i);
+ check_empty_span_incl_subspans(si);
+ RETURN_IF_FAILED();
+
+ QSpan<const int, 0> sci{&i, 0};
+ QCOMPARE(sci.data(), &i);
+ check_empty_span_incl_subspans(sci);
+ RETURN_IF_FAILED();
+
+ QSpan<int, 0> sdi{&i, 0};
+ QCOMPARE(sdi.data(), &i);
+ check_empty_span_incl_subspans(sdi);
+ RETURN_IF_FAILED();
+
+ QSpan<const int, 0> sdci{&i, 0};
+ QCOMPARE(sdci.data(), &i);
+ check_empty_span_incl_subspans(sdci);
+ RETURN_IF_FAILED();
+}
+
+template <typename T, std::size_t N>
+void tst_QSpan::check_nonempty_span(QSpan<T, N> s, qsizetype expectedSize) const
+{
+ static_assert(N > 0);
+ QCOMPARE_GT(expectedSize, 0); // otherwise, use check_empty_span!
+
+ QVERIFY(!s.empty());
+ QVERIFY(!s.isEmpty());
+
+ QCOMPARE_EQ(s.size(), expectedSize);
+ QCOMPARE_NE(s.data(), nullptr);
+
+ QCOMPARE_NE(s.begin(), s.end());
+ QCOMPARE_NE(s.rbegin(), s.rend());
+ QCOMPARE_NE(s.cbegin(), s.cend());
+ QCOMPARE_NE(s.crbegin(), s.crend());
+
+ QCOMPARE_EQ(s.end() - s.begin(), s.size());
+ QCOMPARE_EQ(s.cend() - s.cbegin(), s.size());
+ QCOMPARE_EQ(s.rend() - s.rbegin(), s.size());
+ QCOMPARE_EQ(s.crend() - s.crbegin(), s.size());
+
+ QCOMPARE_EQ(std::addressof(s.front()), std::addressof(*s.begin()));
+ QCOMPARE_EQ(std::addressof(s.front()), std::addressof(*s.cbegin()));
+ QCOMPARE_EQ(std::addressof(s.front()), std::addressof(s[0]));
+ QCOMPARE_EQ(std::addressof(s.back()), std::addressof(*s.rbegin()));
+ QCOMPARE_EQ(std::addressof(s.back()), std::addressof(*s.crbegin()));
+ QCOMPARE_EQ(std::addressof(s.back()), std::addressof(s[s.size() - 1]));
+
+ // ### more?
+
+ if (expectedSize == 1) {
+ // don't run into Mandates: Offset >= Extent
+ if constexpr (N > 0) { // incl. N == std::dynamic_extent
+ check_empty_span_incl_subspans(s.template subspan<1>());
+ RETURN_IF_FAILED();
+ }
+ check_empty_span_incl_subspans(s.subspan(1));
+ RETURN_IF_FAILED();
+ } else {
+ // don't run into Mandates: Offset >= Extent
+ if constexpr (N > 1) { // incl. N == std::dynamic_extent
+ check_nonempty_span(s.template subspan<1>(), expectedSize - 1);
+ RETURN_IF_FAILED();
+ }
+ check_nonempty_span(s.subspan(1), expectedSize - 1);
+ RETURN_IF_FAILED();
+ }
+}
+
+template <typename T, std::size_t N>
+void tst_QSpan::check_empty_span(QSpan<T, N> s) const
+{
+ QVERIFY(s.empty());
+ QVERIFY(s.isEmpty());
+
+ QCOMPARE_EQ(s.size(), 0);
+
+ QCOMPARE_EQ(s.begin(), s.end());
+ QCOMPARE_EQ(s.cbegin(), s.cend());
+ QCOMPARE_EQ(s.rbegin(), s.rend());
+ QCOMPARE_EQ(s.crbegin(), s.crend());
+}
+
+template <typename T, std::size_t N>
+void tst_QSpan::check_empty_span_incl_subspans(QSpan<T, N> s) const
+{
+ check_empty_span(s);
+ RETURN_IF_FAILED();
+
+ {
+ const auto fi = s.template first<0>();
+ check_empty_span(fi);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(fi.data(), s.data());
+ }
+ {
+ const auto la = s.template last<0>();
+ check_empty_span(la);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(la.data(), s.data());
+ }
+ {
+ const auto ss = s.template subspan<0>();
+ check_empty_span(ss);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(ss.data(), s.data());
+ }
+ {
+ const auto ss = s.template subspan<0, 0>();
+ check_empty_span(ss);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(ss.data(), s.data());
+ }
+
+ {
+ const auto fi = s.first(0);
+ check_empty_span(fi);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(fi.data(), s.data());
+ }
+ {
+ const auto la = s.last(0);
+ check_empty_span(la);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(la.data(), s.data());
+ }
+ {
+ const auto ss = s.subspan(0);
+ check_empty_span(ss);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(ss.data(), s.data());
+ }
+ {
+ const auto ss = s.subspan(0, 0);
+ check_empty_span(ss);
+ RETURN_IF_FAILED();
+ QCOMPARE_EQ(ss.data(), s.data());
+ }
+}
+
+
+template<typename T, std::size_t N>
+void tst_QSpan::check_null_span(QSpan<T, N> s) const
+{
+ QCOMPARE_EQ(s.data(), nullptr);
+ QCOMPARE_EQ(s.begin(), nullptr);
+ QCOMPARE_EQ(s.cbegin(), nullptr);
+ QCOMPARE_EQ(s.end(), nullptr);
+ check_empty_span_incl_subspans(s);
+}
+
+template <std::size_t ExpectedExtent, typename C>
+void tst_QSpan::from_container_impl(C &&c) const
+{
+ const auto c_size = qsizetype(QSpanPrivate::adl_size(c));
+ const auto c_data = QSpanPrivate::adl_data(c);
+
+ using V = std::remove_reference_t<QSpanPrivate::range_reference_t<C>>;
+ {
+ QSpan si = c; // CTAD
+ static_assert(std::is_same_v<decltype(si), QSpan<V, ExpectedExtent>>);
+
+ QCOMPARE_EQ(si.size(), c_size);
+ QCOMPARE_EQ(si.data(), c_data);
+
+ check_nonempty_span(si, c_size);
+ RETURN_IF_FAILED();
+
+ QSpan<const int> sci = c;
+
+ QCOMPARE_EQ(sci.size(), c_size);
+ QCOMPARE_EQ(sci.data(), c_data);
+
+ check_nonempty_span(sci, c_size);
+ RETURN_IF_FAILED();
+ }
+ {
+ QSpan sci = std::as_const(c); // CTAD
+ static_assert(std::is_same_v<decltype(sci), QSpan<const int, ExpectedExtent>>);
+
+ QCOMPARE_EQ(sci.size(), c_size);
+ QCOMPARE_EQ(sci.data(), c_data);
+
+ check_nonempty_span(sci, c_size);
+ RETURN_IF_FAILED();
+ }
+}
+
+template <typename C>
+void tst_QSpan::from_variable_size_container_impl(C &&c) const
+{
+ constexpr auto E = q20::dynamic_extent;
+ from_container_impl<E>(std::forward<C>(c));
+}
+
+void tst_QSpan::fromArray() const
+{
+ int ai[] = {42, 84, 168, 336};
+ from_container_impl<4>(ai);
+}
+
+void tst_QSpan::fromStdArray() const
+{
+ std::array<int, 4> ai = {42, 84, 168, 336};
+ from_container_impl<4>(ai);
+}
+
+void tst_QSpan::fromStdInitializerList() const
+{
+ std::initializer_list<int> il = {42, 84, 168, 336};
+
+ QSpan sci = il; // CTAD
+ // special case: always deduced as <const int>:
+ static_assert(std::is_same_v<decltype(sci), QSpan<const int>>);
+
+ QCOMPARE_EQ(sci.size(), qsizetype(il.size()));
+ QCOMPARE_EQ(sci.data(), il.begin());
+
+ check_nonempty_span(sci, 4);
+ RETURN_IF_FAILED();
+}
+
+void tst_QSpan::fromZeroSizeStdArray() const
+{
+ std::array<int, 0> ai = {};
+ QSpan si = ai; // CTAD
+ static_assert(std::is_same_v<decltype(si), QSpan<int, 0>>);
+ QCOMPARE_EQ(si.data(), ai.data());
+
+ const std::array<int, 0> cai = {};
+ QSpan csi = cai; // CTAD
+ static_assert(std::is_same_v<decltype(csi), QSpan<const int, 0>>);
+ QCOMPARE_EQ(csi.data(), cai.data());
+
+ std::array<const int, 0> aci = {};
+ QSpan sci = aci; // CTAD
+ static_assert(std::is_same_v<decltype(sci), QSpan<const int, 0>>);
+ QCOMPARE_EQ(sci.data(), aci.data());
+
+ std::array<const int, 0> caci = {};
+ QSpan csci = caci; // CTAD
+ static_assert(std::is_same_v<decltype(csci), QSpan<const int, 0>>);
+ QCOMPARE_EQ(csci.data(), caci.data());
+}
+
+void tst_QSpan::fromStdVector() const
+{
+ std::vector<int> vi = {42, 84, 168, 336};
+ from_variable_size_container_impl(vi);
+}
+
+void tst_QSpan::fromQList() const
+{
+ QList<int> li = {42, 84, 168, 336};
+ from_variable_size_container_impl(li);
+}
+
+void tst_QSpan::fromInitList() const
+{
+ from_variable_size_container_impl(std::initializer_list<int>{42, 84, 168, 336});
+
+ auto l1 = [](QSpan<const int>){};
+ l1({1, 2, 3});
+
+ auto l2 = [](QSpan<const int, 3>){};
+ l2({4, 5, 6});
+}
+
+#undef RETURN_IF_FAILED
+
+QTEST_APPLESS_MAIN(tst_QSpan);
+#include "tst_qspan.moc"
diff --git a/tests/auto/corelib/tools/qstl/CMakeLists.txt b/tests/auto/corelib/tools/qstl/CMakeLists.txt
new file mode 100644
index 0000000000..b2f053e6ce
--- /dev/null
+++ b/tests/auto/corelib/tools/qstl/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qstl Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qstl LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qstl
+ SOURCES
+ tst_qstl.cpp
+)
diff --git a/tests/auto/corelib/tools/qstl/qstl.pro b/tests/auto/corelib/tools/qstl/qstl.pro
deleted file mode 100644
index e57e62b828..0000000000
--- a/tests/auto/corelib/tools/qstl/qstl.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstl
-QT = core testlib
-SOURCES = tst_qstl.cpp
diff --git a/tests/auto/corelib/tools/qstl/tst_qstl.cpp b/tests/auto/corelib/tools/qstl/tst_qstl.cpp
index 6114da55b4..43d40bc128 100644
--- a/tests/auto/corelib/tools/qstl/tst_qstl.cpp
+++ b/tests/auto/corelib/tools/qstl/tst_qstl.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+
+#include <QTest>
#include <qstring.h>
diff --git a/tests/auto/corelib/tools/qstring/double_data.h b/tests/auto/corelib/tools/qstring/double_data.h
deleted file mode 100644
index 0d59ecb5ff..0000000000
--- a/tests/auto/corelib/tools/qstring/double_data.h
+++ /dev/null
@@ -1,10023 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-struct SprintfDoubleData
-{
- const char *fmt;
- const char *expected;
- int bytes[8];
-};
-
-static const SprintfDoubleData g_sprintf_double_data[] = {
- { "%'1g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'3g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'50g", "00000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'.0g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'3.0g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'50.0g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'.1g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'1.1g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'50.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'.3g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'1.3g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'3.3g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'.50g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'1.50g", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'3.50g", "000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'50.50g", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'1G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'3G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'50G", "00000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'.0G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'3.0G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'50.0G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'.1G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'1.1G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'50.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'.3G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'1.3G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'3.3G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'.50G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-'1.50G", "0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0'3.50G", "000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-'50.50G", "0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'.0g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'3.0g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'50.0g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'1.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'50.1g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'1.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'3.3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'1.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'3.50g", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'50.50g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'.0G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'3.0G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'50.0G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'1.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'50.1G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'1.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'3.3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%+'.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%-+'1.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0+'3.50G", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0-+'50.50G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '3g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '.0g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '3.0g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '50.0g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '1.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '50.1g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '.3g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '1.3g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '3.3g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '.50g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '1.50g", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '3.50g", " 00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '50.50g", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '3G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '.0G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '3.0G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '50.0G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '1.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '50.1G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '.3G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '1.3G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '3.3G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% '.50G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- '1.50G", " 0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 '3.50G", " 00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- '50.50G", " 0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'.0g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'3.0g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'50.0g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'1.1g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'50.1g", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'1.3g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'3.3g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'1.50g", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'3.50g", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'50.50g", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'.0G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'3.0G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'50.0G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'1.1G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'50.1G", " +0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'1.3G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'3.3G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "% +'.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%- +'1.50G", "+0", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0 +'3.50G", "+00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%0- +'50.50G", "+0 ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'1g", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'3g", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'50g", "00000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'.0g", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'3.0g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'50.0g", "0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'.1g", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'1.1g", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'50.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'.3g", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'1.3g", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'3.3g", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'1.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'3.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'50.50g", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'1G", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'3G", "0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'50G", "00000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'.0G", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'3.0G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'50.0G", "0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'.1G", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'1.1G", "0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'50.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'.3G", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'1.3G", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'3.3G", "0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#'.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-'1.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0'3.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-'50.50G", "0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'1g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'3g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'3.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'50.0g", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'1.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'50.1g", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'1.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'3.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'1.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'3.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'50.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'1G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'3G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'3.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'50.0G", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'1.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'50.1G", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'1.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'3.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#+'.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#-+'1.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0+'3.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0-+'50.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '1g", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '3g", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '.0g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '3.0g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '50.0g", " 0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '1.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '50.1g", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '.3g", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '1.3g", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '3.3g", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '1.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '3.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '50.50g", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '1G", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '3G", " 0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '.0G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '3.0G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '50.0G", " 0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '1.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '50.1G", " 0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '.3G", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '1.3G", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '3.3G", " 0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# '.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- '1.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 '3.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- '50.50G", " 0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'1g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'3g", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'3.0g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'50.0g", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'1.1g", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'50.1g", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'1.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'3.3g", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'1.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'3.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'50.50g", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'1G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'3G", "+0.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000000.00000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'3.0G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'50.0G", "+0. ", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'1.1G", "+0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'50.1G", " +0.", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'1.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'3.3G", "+0.00", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%# +'.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#- +'1.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0 +'3.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%#0- +'50.50G", "+0.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { "%'1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'3.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'50.0g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'1.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'1.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'3.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'1.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'3.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'50.50g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'3.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'50.0G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'1.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'1.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'3.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-'1.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0'3.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-'50.50G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%+'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%-+'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0+'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0-+'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '3.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '50.0g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '1.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '1.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '3.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '1.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '3.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '50.50g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '3.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '50.0G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '1.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '1.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '3.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% '.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- '1.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 '3.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- '50.50G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "% +'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%- +'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0 +'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%0- +'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'3.0g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'50.0g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'1.1g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'1.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'3.3g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'1.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'3.50g", "nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'50.50g", "nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'3.0G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'50.0G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'1.1G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'1.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'3.3G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#'.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-'1.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0'3.50G", "NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-'50.50G", "NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#+'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#-+'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0+'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0-+'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '3.0g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '50.0g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '1.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '50.1g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '1.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '3.3g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '1.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '3.50g", " nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '50.50g", " nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '3.0G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '50.0G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '1.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '50.1G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '1.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '3.3G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# '.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- '1.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 '3.50G", " NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- '50.50G", " NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'50g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'3.0g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'50.0g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'1.1g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'50.1g", " +nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'1.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'3.3g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'1.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'3.50g", "+nan", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'50.50g", "+nan ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'50G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'3.0G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'50.0G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'1.1G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'50.1G", " +NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'1.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'3.3G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%# +'.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#- +'1.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0 +'3.50G", "+NAN", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%#0- +'50.50G", "+NAN ", { 0, 0, 0, 0, 0, 0, 248, 127 } },
- { "%'1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'3.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'50.0g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'1.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'1.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'3.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'1.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'3.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'50.50g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'3.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'50.0G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'1.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'1.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'3.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-'1.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0'3.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-'50.50G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%+'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%-+'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0+'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0-+'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '3.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '50.0g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '1.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '1.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '3.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '1.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '3.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '50.50g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '3.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '50.0G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '1.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '1.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '3.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% '.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- '1.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 '3.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- '50.50G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "% +'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%- +'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0 +'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%0- +'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'3.0g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'50.0g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'1.1g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'1.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'3.3g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'1.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'3.50g", "inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'50.50g", "inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'3.0G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'50.0G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'1.1G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'1.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'3.3G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#'.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-'1.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0'3.50G", "INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-'50.50G", "INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#+'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#-+'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0+'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0-+'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '3.0g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '50.0g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '1.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '50.1g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '1.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '3.3g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '1.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '3.50g", " inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '50.50g", " inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '3.0G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '50.0G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '1.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '50.1G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '1.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '3.3G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# '.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- '1.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 '3.50G", " INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- '50.50G", " INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'50g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'3.0g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'50.0g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'1.1g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'50.1g", " +inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'1.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'3.3g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'1.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'3.50g", "+inf", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'50.50g", "+inf ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'50G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'3.0G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'50.0G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'1.1G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'50.1G", " +INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'1.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'3.3G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%# +'.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#- +'1.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0 +'3.50G", "+INF", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%#0- +'50.50G", "+INF ", { 0, 0, 0, 0, 0, 0, 240, 127 } },
- { "%'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%+'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%-+'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0+'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0-+'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% '.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- '1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 '3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- '50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "% +'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%- +'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0 +'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%0- +'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#+'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#-+'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0+'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0-+'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# '.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- '1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 '3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- '50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'50g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'3.0g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'50.0g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'1.1g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'50.1g", " -inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'1.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'3.3g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'1.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'3.50g", "-inf", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'50.50g", "-inf ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'50G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'3.0G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'50.0G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'1.1G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'50.1G", " -INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'1.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'3.3G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%# +'.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#- +'1.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0 +'3.50G", "-INF", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%#0- +'50.50G", "-INF ", { 0, 0, 0, 0, 0, 0, 240, 255 } },
- { "%'1g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'3g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'50g", "00000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'.0g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'3.0g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'50.0g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'.1g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'1.1g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'50.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'.3g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'1.3g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'3.3g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'.50g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'1.50g", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'3.50g", "001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'50.50g", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'1G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'3G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'50G", "00000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'.0G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'3.0G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'50.0G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'.1G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'1.1G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'50.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'.3G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'1.3G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'3.3G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'.50G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-'1.50G", "1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0'3.50G", "001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-'50.50G", "1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'.0g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'3.0g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'50.0g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'1.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'50.1g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'1.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'3.3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'1.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'3.50g", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'50.50g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'.0G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'3.0G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'50.0G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'1.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'50.1G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'1.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'3.3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%+'.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%-+'1.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0+'3.50G", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0-+'50.50G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '3g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '.0g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '3.0g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '50.0g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '1.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '50.1g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '.3g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '1.3g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '3.3g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '.50g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '1.50g", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '3.50g", " 01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '50.50g", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '3G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '.0G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '3.0G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '50.0G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '1.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '50.1G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '.3G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '1.3G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '3.3G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% '.50G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- '1.50G", " 1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 '3.50G", " 01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- '50.50G", " 1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'.0g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'3.0g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'50.0g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'1.1g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'50.1g", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'1.3g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'3.3g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'1.50g", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'3.50g", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'50.50g", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'.0G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'3.0G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'50.0G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'1.1G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'50.1G", " +1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'1.3G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'3.3G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "% +'.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%- +'1.50G", "+1", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0 +'3.50G", "+01", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%0- +'50.50G", "+1 ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'1g", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'3g", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'.0g", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'3.0g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'50.0g", "1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'.1g", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'1.1g", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'50.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'.3g", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'1.3g", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'3.3g", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'1.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'3.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'50.50g", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'1G", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'3G", "1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'.0G", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'3.0G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'50.0G", "1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'.1G", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'1.1G", "1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'50.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'.3G", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'1.3G", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'3.3G", "1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#'.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-'1.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0'3.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-'50.50G", "1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'1g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'3g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'3.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'50.0g", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'1.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'50.1g", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'1.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'3.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'1.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'3.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'50.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'1G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'3G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'3.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'50.0G", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'1.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'50.1G", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'1.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'3.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#+'.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#-+'1.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0+'3.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0-+'50.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '1g", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '3g", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '.0g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '3.0g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '50.0g", " 1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '1.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '50.1g", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '.3g", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '1.3g", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '3.3g", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '1.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '3.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '50.50g", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '1G", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '3G", " 1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '.0G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '3.0G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '50.0G", " 1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '1.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '50.1G", " 1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '.3G", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '1.3G", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '3.3G", " 1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# '.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- '1.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 '3.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- '50.50G", " 1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'1g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'3g", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'3.0g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'50.0g", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'1.1g", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'50.1g", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'1.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'3.3g", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'1.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'3.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'50.50g", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'1G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'3G", "+1.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'3.0G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'50.0G", "+1. ", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'1.1G", "+1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'50.1G", " +1.", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'1.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'3.3G", "+1.00", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%# +'.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#- +'1.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0 +'3.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%#0- +'50.50G", "+1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 63 } },
- { "%'1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-'1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0'3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-'50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%+'.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%-+'1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0+'3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0-+'50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% '.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- '1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 '3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- '50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'50g", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'.0g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'3.0g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'50.0g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'1.1g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'50.1g", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'1.3g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'3.3g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'1.50g", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'3.50g", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'50.50g", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'50G", "-0000000000000000000000000000000000000000000000001", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'.0G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'3.0G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'50.0G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'1.1G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'50.1G", " -1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'1.3G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'3.3G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "% +'.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%- +'1.50G", "-1", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0 +'3.50G", "-01", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%0- +'50.50G", "-1 ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#'.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-'1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0'3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-'50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#+'.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#-+'1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0+'3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0-+'50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# '.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- '1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 '3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- '50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'1g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'3g", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'50g", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'3.0g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'50.0g", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'1.1g", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'50.1g", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'1.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'3.3g", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'1.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'3.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'50.50g", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'1G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'3G", "-1.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'50G", "-0000000000000000000000000000000000000000001.00000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'3.0G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'50.0G", "-1. ", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'1.1G", "-1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'50.1G", " -1.", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'1.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'3.3G", "-1.00", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%# +'.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#- +'1.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0 +'3.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%#0- +'50.50G", "-1.0000000000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 0, 240, 191 } },
- { "%'1g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'3g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'50g", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'.0g", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'3.0g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'50.0g", "2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'.1g", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'1.1g", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'50.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'1.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'3.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'1.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'3.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'50.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'1G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'3G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'50G", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'.0G", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'3.0G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'50.0G", "2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'.1G", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'1.1G", "2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'50.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'1.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'3.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-'1.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0'3.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-'50.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'.0g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'3.0g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'50.0g", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'1.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'50.1g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'.0G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'3.0G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'50.0G", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'1.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'50.1G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%+'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%-+'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0+'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0-+'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '1g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '3g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '.0g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '3.0g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '50.0g", " 2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '1.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '50.1g", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '1.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '3.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '1.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '3.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '50.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '1G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '3G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '.0G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '3.0G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '50.0G", " 2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '1.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '50.1G", " 2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '1.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '3.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% '.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- '1.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 '3.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- '50.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'.0g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'3.0g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'50.0g", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'1.1g", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'50.1g", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'.0G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'3.0G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'50.0G", "+2 ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'1.1G", "+2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'50.1G", " +2", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "% +'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%- +'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0 +'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%0- +'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'1g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'3g", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'.0g", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'3.0g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'50.0g", "2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'.1g", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'1.1g", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'50.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'1.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'3.3g", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'1.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'3.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'50.50g", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'1G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'3G", "1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'.0G", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'3.0G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'50.0G", "2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'.1G", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'1.1G", "2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'50.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'1.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'3.3G", "1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#'.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-'1.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0'3.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-'50.50G", "1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'3.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'50.0g", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'1.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'50.1g", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'3.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'50.0G", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'1.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'50.1G", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#+'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#-+'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0+'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0-+'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '1g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '3g", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '.0g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '3.0g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '50.0g", " 2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '1.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '50.1g", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '1.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '3.3g", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '1.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '3.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '50.50g", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '1G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '3G", " 1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '.0G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '3.0G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '50.0G", " 2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '1.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '50.1G", " 2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '1.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '3.3G", " 1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# '.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- '1.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 '3.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- '50.50G", " 1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'1g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'3g", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'3.0g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'50.0g", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'1.1g", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'50.1g", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'1.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'3.3g", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'1.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'3.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'50.50g", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'1G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'3G", "+1.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000001.57143", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'3.0G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'50.0G", "+2. ", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'1.1G", "+2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'50.1G", " +2.", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'1.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'3.3G", "+1.57", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%# +'.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#- +'1.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0 +'3.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%#0- +'50.50G", "+1.5714285714285713968507707249955274164676666259766", { 73, 146, 36, 73, 146, 36, 249, 63 } },
- { "%'1g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'3g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'50g", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'3.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'50.0g", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'1.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'1.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'3.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'1.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'3.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'50.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'1G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'3G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'50G", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'3.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'50.0G", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'1.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'1.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'3.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-'1.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0'3.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-'50.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%+'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%-+'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0+'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0-+'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '1g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '3g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '3.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '50.0g", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '1.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '1.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '3.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '1.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '3.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '50.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '1G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '3G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '3.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '50.0G", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '1.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '1.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '3.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% '.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- '1.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 '3.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- '50.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "% +'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%- +'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0 +'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%0- +'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'1g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'3g", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'50g", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'3.0g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'50.0g", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'1.1g", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'1.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'3.3g", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'1.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'3.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'50.50g", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'1G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'3G", "0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'50G", "0000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'3.0G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'50.0G", "0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'1.1G", "0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'1.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'3.3G", "0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#'.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-'1.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0'3.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-'50.50G", "0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#+'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#-+'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0+'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0-+'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '1g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '3g", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '50g", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '3.0g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '50.0g", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '1.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '50.1g", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '1.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '3.3g", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '1.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '3.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '50.50g", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '1G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '3G", " 0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '50G", " 000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '3.0G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '50.0G", " 0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '1.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '50.1G", " 0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '1.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '3.3G", " 0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# '.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- '1.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 '3.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- '50.50G", " 0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'1g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'3g", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'3.0g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'50.0g", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'1.1g", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'50.1g", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'1.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'3.3g", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'1.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'3.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'50.50g", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'1G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'3G", "+0.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000000000.636364", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'3.0G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'50.0G", "+0.6 ", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'1.1G", "+0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'50.1G", " +0.6", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'1.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'3.3G", "+0.636", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%# +'.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#- +'1.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0 +'3.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%#0- +'50.50G", "+0.63636363636363635354342704886221326887607574462891", { 93, 116, 209, 69, 23, 93, 228, 63 } },
- { "%'1g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'3g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'50g", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'.0g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'3.0g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'50.0g", "2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'.1g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'1.1g", "2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'50.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'1.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'3.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'.50g", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'1.50g", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'3.50g", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'50.50g", "1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'1G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'3G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'50G", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'.0G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'3.0G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'50.0G", "2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'.1G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'1.1G", "2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'50.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'1.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'3.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'.50G", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-'1.50G", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0'3.50G", "1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-'50.50G", "1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'3.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'50.0g", "+2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'1.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'50.1g", " +2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'1.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'3.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'50.50g", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'3.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'50.0G", "+2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'1.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'50.1G", " +2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%+'.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%-+'1.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0+'3.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0-+'50.50G", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '1g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '3g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '50g", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '.0g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '3.0g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '50.0g", " 2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '1.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '50.1g", " 2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '1.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '3.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '.50g", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '1.50g", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '3.50g", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '50.50g", " 1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '1G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '3G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '50G", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '.0G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '3.0G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '50.0G", " 2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '1.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '50.1G", " 2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '1.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '3.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% '.50G", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- '1.50G", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 '3.50G", " 1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- '50.50G", " 1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'3.0g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'50.0g", "+2e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'1.1g", "+2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'50.1g", " +2e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'1.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'3.50g", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'50.50g", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'3.0G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'50.0G", "+2E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'1.1G", "+2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'50.1G", " +2E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "% +'.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%- +'1.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0 +'3.50G", "+1,571.428571428571331125567667186260223388671875", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%0- +'50.50G", "+1,571.428571428571331125567667186260223388671875 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'1g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'3g", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'50g", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'.0g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'3.0g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'50.0g", "2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'.1g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'1.1g", "2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'50.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'1.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'3.3g", "1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'1.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'3.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'50.50g", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'1G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'3G", "1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'50G", "0000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'.0G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'3.0G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'50.0G", "2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'.1G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'1.1G", "2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'50.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'1.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'3.3G", "1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#'.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-'1.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0'3.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-'50.50G", "1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'3.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'50.0g", "+2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'1.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'50.1g", " +2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'1.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'3.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'50.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'3.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'50.0G", "+2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'1.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'50.1G", " +2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#+'.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#-+'1.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0+'3.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0-+'50.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '1g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '3g", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '50g", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '.0g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '3.0g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '50.0g", " 2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '1.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '50.1g", " 2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '1.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '3.3g", " 1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '1.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '3.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '50.50g", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '1G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '3G", " 1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '50G", " 000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '.0G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '3.0G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '50.0G", " 2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '1.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '50.1G", " 2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '1.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '3.3G", " 1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# '.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- '1.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 '3.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- '50.50G", " 1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'1g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'3g", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'3.0g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'50.0g", "+2.e+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'1.1g", "+2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'50.1g", " +2.e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'1.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'3.3g", "+1.57e+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'1.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'3.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'50.50g", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'1G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'3G", "+1,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000000001,571.43", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'3.0G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'50.0G", "+2.E+03 ", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'1.1G", "+2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'50.1G", " +2.E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'1.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'3.3G", "+1.57E+03", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%# +'.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#- +'1.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0 +'3.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%#0- +'50.50G", "+1,571.4285714285713311255676671862602233886718750000", { 219, 182, 109, 219, 182, 141, 152, 64 } },
- { "%'1g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'3g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'50g", "0000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'.0g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'3.0g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'50.0g", "2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'.1g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'1.1g", "2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'50.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'1.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'3.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'.50g", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'1.50g", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'3.50g", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'50.50g", "1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'1G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'3G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'50G", "0000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'.0G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'3.0G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'50.0G", "2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'.1G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'1.1G", "2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'50.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'1.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'3.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'.50G", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-'1.50G", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0'3.50G", "1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-'50.50G", "1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'3.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'50.0g", "+2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'1.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'50.1g", " +2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'1.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'3.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'50.50g", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'3.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'50.0G", "+2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'1.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'50.1G", " +2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%+'.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%-+'1.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0+'3.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0-+'50.50G", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '1g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '3g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '50g", " 000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '.0g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '3.0g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '50.0g", " 2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '1.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '50.1g", " 2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '1.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '3.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '.50g", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '1.50g", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '3.50g", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '50.50g", " 1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '1G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '3G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '50G", " 000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '.0G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '3.0G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '50.0G", " 2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '1.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '50.1G", " 2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '1.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '3.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% '.50G", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- '1.50G", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 '3.50G", " 1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- '50.50G", " 1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'3.0g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'50.0g", "+2e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'1.1g", "+2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'50.1g", " +2e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'1.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'3.50g", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'50.50g", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'3.0G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'50.0G", "+2E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'1.1G", "+2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'50.1G", " +2E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "% +'.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%- +'1.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0 +'3.50G", "+1,571,428.5714285713620483875274658203125", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%0- +'50.50G", "+1,571,428.5714285713620483875274658203125 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'1g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'3g", "1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'.0g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'3.0g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'50.0g", "2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'.1g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'1.1g", "2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'50.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'1.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'3.3g", "1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'1.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'3.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'50.50g", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'1G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'3G", "1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'.0G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'3.0G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'50.0G", "2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'.1G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'1.1G", "2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'50.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'1.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'3.3G", "1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#'.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-'1.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0'3.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-'50.50G", "1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'3.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'50.0g", "+2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'1.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'50.1g", " +2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'1.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'3.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'50.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'3.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'50.0G", "+2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'1.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'50.1G", " +2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#+'.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#-+'1.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0+'3.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0-+'50.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '1g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '3g", " 1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '.0g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '3.0g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '50.0g", " 2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '1.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '50.1g", " 2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '1.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '3.3g", " 1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '1.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '3.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '50.50g", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '1G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '3G", " 1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '.0G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '3.0G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '50.0G", " 2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '1.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '50.1G", " 2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '1.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '3.3G", " 1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# '.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- '1.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 '3.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- '50.50G", " 1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'1g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'3g", "+1.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.57143e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'3.0g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'50.0g", "+2.e+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'1.1g", "+2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'50.1g", " +2.e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'1.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'3.3g", "+1.57e+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'1.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'3.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'50.50g", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'1G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'3G", "+1.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.57143E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'3.0G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'50.0G", "+2.E+06 ", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'1.1G", "+2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'50.1G", " +2.E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'1.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'3.3G", "+1.57E+06", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%# +'.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#- +'1.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0 +'3.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%#0- +'50.50G", "+1,571,428.5714285713620483875274658203125000000000000", { 146, 36, 73, 146, 100, 250, 55, 65 } },
- { "%'1g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'3g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'50g", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'3.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'50.0g", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'1.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'1.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'3.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'1.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'3.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'50.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'1G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'3G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'50G", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'3.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'50.0G", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'1.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'1.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'3.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-'1.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0'3.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-'50.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%+'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%-+'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0+'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0-+'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '1g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '3g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '3.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '50.0g", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '1.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '1.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '3.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '1.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '3.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '50.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '1G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '3G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '3.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '50.0G", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '1.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '1.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '3.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% '.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- '1.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 '3.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- '50.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "% +'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%- +'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0 +'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%0- +'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'1g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'3g", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'3.0g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'50.0g", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'1.1g", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'1.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'3.3g", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'1.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'3.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'50.50g", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'1G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'3G", "0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'3.0G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'50.0G", "0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'1.1G", "0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'1.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'3.3G", "0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#'.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-'1.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0'3.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-'50.50G", "0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#+'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#-+'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0+'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0-+'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '1g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '3g", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '3.0g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '50.0g", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '1.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '50.1g", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '1.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '3.3g", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '1.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '3.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '50.50g", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '1G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '3G", " 0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '3.0G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '50.0G", " 0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '1.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '50.1G", " 0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '1.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '3.3G", " 0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# '.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- '1.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 '3.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- '50.50G", " 0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'1g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'3g", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'3.0g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'50.0g", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'1.1g", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'50.1g", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'1.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'3.3g", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'1.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'3.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'50.50g", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'1G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'3G", "+0.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000.00157143", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'3.0G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'50.0G", "+0.002 ", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'1.1G", "+0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'50.1G", " +0.002", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'1.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'3.3G", "+0.00157", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%# +'.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#- +'1.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0 +'3.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%#0- +'50.50G", "+0.0015714285714285714922605619037199176091235131025314", { 67, 84, 160, 148, 12, 191, 89, 63 } },
- { "%'1g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'3g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'50g", "0000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'.0g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'3.0g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'50.0g", "2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'.1g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'1.1g", "2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'50.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'1.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'3.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'1.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'3.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'50.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'1G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'3G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'50G", "0000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'.0G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'3.0G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'50.0G", "2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'.1G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'1.1G", "2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'50.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'1.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'3.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-'1.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0'3.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-'50.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'3.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'50.0g", "+2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'1.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'50.1g", " +2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'3.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'50.0G", "+2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'1.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'50.1G", " +2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%+'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%-+'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0+'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0-+'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '1g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '3g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '50g", " 000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '.0g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '3.0g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '50.0g", " 2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '1.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '50.1g", " 2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '1.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '3.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '1.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '3.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '50.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '1G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '3G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '50G", " 000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '.0G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '3.0G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '50.0G", " 2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '1.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '50.1G", " 2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '1.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '3.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% '.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- '1.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 '3.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- '50.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'3.0g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'50.0g", "+2e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'1.1g", "+2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'50.1g", " +2e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'3.0G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'50.0G", "+2E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'1.1G", "+2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'50.1G", " +2E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "% +'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%- +'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0 +'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%0- +'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'1g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'3g", "1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'.0g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'3.0g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'50.0g", "2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'.1g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'1.1g", "2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'50.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'1.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'3.3g", "1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'1.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'3.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'50.50g", "1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'1G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'3G", "1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'.0G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'3.0G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'50.0G", "2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'.1G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'1.1G", "2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'50.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'1.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'3.3G", "1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#'.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-'1.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0'3.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-'50.50G", "1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'3.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'50.0g", "+2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'1.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'50.1g", " +2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'3.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'50.0G", "+2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'1.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'50.1G", " +2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#+'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#-+'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0+'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0-+'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '1g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '3g", " 1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '.0g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '3.0g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '50.0g", " 2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '1.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '50.1g", " 2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '1.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '3.3g", " 1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '1.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '3.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '50.50g", " 1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '1G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '3G", " 1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '.0G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '3.0G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '50.0G", " 2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '1.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '50.1G", " 2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '1.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '3.3G", " 1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# '.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- '1.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 '3.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- '50.50G", " 1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'1g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'3g", "+1.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.57143e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'3.0g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'50.0g", "+2.e-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'1.1g", "+2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'50.1g", " +2.e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'1.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'3.3g", "+1.57e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'1.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'3.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'50.50g", "+1.5714285714285714482148486464962999775707430671901e-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'1G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'3G", "+1.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.57143E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'3.0G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'50.0G", "+2.E-06 ", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'1.1G", "+2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'50.1G", " +2.E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'1.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'3.3G", "+1.57E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%# +'.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#- +'1.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0 +'3.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%#0- +'50.50G", "+1.5714285714285714482148486464962999775707430671901E-06", { 222, 153, 139, 252, 59, 93, 186, 62 } },
- { "%'1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'50g", "000000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'3.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'50.0g", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'1.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'.3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'1.3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'3.3g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'1.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'3.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'50.50g", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'50G", "000000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'3.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'50.0G", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'1.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'.3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'1.3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'3.3G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-'1.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0'3.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-'50.50G", "0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'50g", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'1.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'3.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'1.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'3.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'50.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'50G", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'1.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'3.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%+'.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%-+'1.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0+'3.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0-+'50.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '50g", " 00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '3.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '50.0g", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '1.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '.3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '1.3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '3.3g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '1.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '3.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '50.50g", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '50G", " 00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '3.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '50.0G", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '1.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '.3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '1.3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '3.3G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% '.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- '1.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 '3.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- '50.50G", " 0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'50g", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'1.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'3.3g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'1.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'3.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'50.50g", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'50G", "+00000000000000000000000000000000000000000000000.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'1.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'3.3G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "% +'.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%- +'1.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0 +'3.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%0- +'50.50G", "+0.1000000000000000055511151231257827021181583404541", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'1g", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'3g", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'50g", "0000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'3.0g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'50.0g", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'1.1g", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'.3g", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'1.3g", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'3.3g", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'1.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'3.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'50.50g", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'1G", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'3G", "0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'50G", "0000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'3.0G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'50.0G", "0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'1.1G", "0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'.3G", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'1.3G", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'3.3G", "0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#'.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-'1.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0'3.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-'50.50G", "0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'1g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'3g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'50g", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'1.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'3.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'1.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'3.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'50.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'1G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'3G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'50G", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'1.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'3.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#+'.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#-+'1.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0+'3.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0-+'50.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '1g", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '3g", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '50g", " 000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '3.0g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '50.0g", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '1.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '50.1g", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '.3g", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '1.3g", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '3.3g", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '1.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '3.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '50.50g", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '1G", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '3G", " 0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '50G", " 000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '3.0G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '50.0G", " 0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '1.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '50.1G", " 0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '.3G", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '1.3G", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '3.3G", " 0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# '.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- '1.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 '3.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- '50.50G", " 0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'1g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'3g", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'3.0g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'50.0g", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'1.1g", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'50.1g", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'1.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'3.3g", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'1.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'3.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'50.50g", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'1G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'3G", "+0.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000000000.100000", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'3.0G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'50.0G", "+0.1 ", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'1.1G", "+0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'50.1G", " +0.1", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'1.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'3.3G", "+0.100", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%# +'.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#- +'1.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0 +'3.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%#0- +'50.50G", "+0.10000000000000000555111512312578270211815834045410", { 154, 153, 153, 153, 153, 153, 185, 63 } },
- { "%'1g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'50g", "0000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'.0g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'3.0g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'50.0g", "1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'.1g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'1.1g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'50.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'.3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'1.3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'3.3g", "1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'1.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'3.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'50.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'1G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'50G", "0000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'.0G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'3.0G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'50.0G", "1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'.1G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'1.1G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'50.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'.3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'1.3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'3.3G", "1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-'1.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0'3.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-'50.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'3.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'50.0g", "+1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'1.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'50.1g", " +1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'1.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'3.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'3.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'50.0G", "+1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'1.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'50.1G", " +1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'1.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'3.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%+'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%-+'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0+'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0-+'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '.0g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '3.0g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '50.0g", " 1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '1.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '50.1g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '.3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '1.3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '3.3g", " 1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '1.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '3.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '50.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '.0G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '3.0G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '50.0G", " 1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '1.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '50.1G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '.3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '1.3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '3.3G", " 1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% '.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- '1.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 '3.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- '50.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000001e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'3.0g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'50.0g", "+1e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'1.1g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'50.1g", " +1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'1.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'3.3g", "+1e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000001E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'3.0G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'50.0G", "+1E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'1.1G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'50.1G", " +1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'1.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'3.3G", "+1E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "% +'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%- +'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0 +'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%0- +'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'1g", "1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'3g", "1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'.0g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'3.0g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'50.0g", "1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'.1g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'1.1g", "1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'50.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'.3g", "1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'1.3g", "1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'3.3g", "1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'1.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'3.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'50.50g", "9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'1G", "1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'3G", "1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'.0G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'3.0G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'50.0G", "1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'.1G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'1.1G", "1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'50.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'.3G", "1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'1.3G", "1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'3.3G", "1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#'.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-'1.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0'3.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-'50.50G", "9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'1g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'3g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'3.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'50.0g", "+1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'1.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'50.1g", " +1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'1.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'3.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'1G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'3G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'3.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'50.0G", "+1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'1.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'50.1G", " +1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'1.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'3.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#+'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#-+'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0+'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0-+'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '1g", " 1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '3g", " 1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '.0g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '3.0g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '50.0g", " 1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '1.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '50.1g", " 1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '.3g", " 1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '1.3g", " 1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '3.3g", " 1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '1.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '3.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '50.50g", " 9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '1G", " 1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '3G", " 1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '.0G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '3.0G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '50.0G", " 1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '1.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '50.1G", " 1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '.3G", " 1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '1.3G", " 1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '3.3G", " 1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# '.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- '1.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 '3.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- '50.50G", " 9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'1g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'3g", "+1.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'3.0g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'50.0g", "+1.e-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'1.1g", "+1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'50.1g", " +1.e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'1.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'3.3g", "+1.00e-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'1.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'3.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'50.50g", "+9.9999999999999995474811182588625868561393872369081e-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'1G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'3G", "+1.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'3.0G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'50.0G", "+1.E-06 ", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'1.1G", "+1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'50.1G", " +1.E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'1.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'3.3G", "+1.00E-06", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%# +'.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#- +'1.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0 +'3.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%#0- +'50.50G", "+9.9999999999999995474811182588625868561393872369081E-07", { 141, 237, 181, 160, 247, 198, 176, 62 } },
- { "%'1g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'3g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'50g", "0000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'.0g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'3.0g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'50.0g", "1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'.1g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'1.1g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'50.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'.3g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'1.3g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'3.3g", "1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'.50g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'1.50g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'3.50g", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'50.50g", "100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'1G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'3G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'50G", "0000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'.0G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'3.0G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'50.0G", "1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'.1G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'1.1G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'50.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'.3G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'1.3G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'3.3G", "1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'.50G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-'1.50G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0'3.50G", "100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-'50.50G", "100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'1g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'3g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'3.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'50.0g", "+1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'1.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'50.1g", " +1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'1.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'3.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'1.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'3.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'50.50g", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'1G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'3G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'3.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'50.0G", "+1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'1.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'50.1G", " +1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'1.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'3.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%+'.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%-+'1.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0+'3.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0-+'50.50G", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '1g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '3g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '.0g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '3.0g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '50.0g", " 1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '1.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '50.1g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '.3g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '1.3g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '3.3g", " 1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '.50g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '1.50g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '3.50g", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '50.50g", " 100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '1G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '3G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '.0G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '3.0G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '50.0G", " 1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '1.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '50.1G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '.3G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '1.3G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '3.3G", " 1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% '.50G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- '1.50G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 '3.50G", " 100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- '50.50G", " 100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'1g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'3g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'3.0g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'50.0g", "+1e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'1.1g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'50.1g", " +1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'1.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'3.3g", "+1e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'1.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'3.50g", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'50.50g", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'1G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'3G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'3.0G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'50.0G", "+1E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'1.1G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'50.1G", " +1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'1.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'3.3G", "+1E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "% +'.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%- +'1.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0 +'3.50G", "+100,000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%0- +'50.50G", "+100,000 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'1g", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'3g", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'50g", "000000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'.0g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'3.0g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'50.0g", "1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'.1g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'1.1g", "1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'50.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'.3g", "1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'1.3g", "1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'3.3g", "1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'1.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'3.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'50.50g", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'1G", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'3G", "100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'50G", "000000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'.0G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'3.0G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'50.0G", "1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'.1G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'1.1G", "1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'50.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'.3G", "1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'1.3G", "1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'3.3G", "1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#'.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-'1.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0'3.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-'50.50G", "100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'1g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'3g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'50g", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'3.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'50.0g", "+1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'1.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'50.1g", " +1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'1.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'3.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'1.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'3.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'50.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'1G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'3G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'50G", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'3.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'50.0G", "+1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'1.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'50.1G", " +1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'1.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'3.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#+'.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#-+'1.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0+'3.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0-+'50.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '1g", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '3g", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '50g", " 00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '.0g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '3.0g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '50.0g", " 1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '1.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '50.1g", " 1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '.3g", " 1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '1.3g", " 1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '3.3g", " 1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '1.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '3.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '50.50g", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '1G", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '3G", " 100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '50G", " 00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '.0G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '3.0G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '50.0G", " 1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '1.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '50.1G", " 1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '.3G", " 1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '1.3G", " 1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '3.3G", " 1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# '.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- '1.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 '3.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- '50.50G", " 100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'1g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'3g", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'3.0g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'50.0g", "+1.e+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'1.1g", "+1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'50.1g", " +1.e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'1.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'3.3g", "+1.00e+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'1.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'3.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'50.50g", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'1G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'3G", "+100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000000000100,000.", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'3.0G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'50.0G", "+1.E+05 ", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'1.1G", "+1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'50.1G", " +1.E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'1.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'3.3G", "+1.00E+05", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%# +'.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#- +'1.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0 +'3.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%#0- +'50.50G", "+100,000.00000000000000000000000000000000000000000000", { 0, 0, 0, 0, 0, 106, 248, 64 } },
- { "%'1g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'3g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'50g", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'.0g", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'3.0g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'50.0g", "3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'.1g", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'1.1g", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'50.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'1.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'3.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'1.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'3.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'50.50g", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'1G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'3G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'50G", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'.0G", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'3.0G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'50.0G", "3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'.1G", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'1.1G", "3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'50.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'1.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'3.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-'1.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0'3.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-'50.50G", "3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'.0g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'3.0g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'50.0g", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'1.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'50.1g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'1.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'3.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'50.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'.0G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'3.0G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'50.0G", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'1.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'50.1G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%+'.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%-+'1.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0+'3.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0-+'50.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '1g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '3g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '.0g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '3.0g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '50.0g", " 3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '1.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '50.1g", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '1.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '3.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '1.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '3.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '50.50g", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '1G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '3G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '.0G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '3.0G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '50.0G", " 3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '1.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '50.1G", " 3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '1.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '3.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% '.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- '1.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 '3.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- '50.50G", " 3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'.0g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'3.0g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'50.0g", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'1.1g", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'50.1g", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'1.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'3.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'50.50g", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'.0G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'3.0G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'50.0G", "+3 ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'1.1G", "+3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'50.1G", " +3", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "% +'.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%- +'1.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0 +'3.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%0- +'50.50G", "+3.141592653589793115997963468544185161590576171875", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'1g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'3g", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'50g", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'.0g", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'3.0g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'50.0g", "3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'.1g", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'1.1g", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'50.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'1.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'3.3g", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'1.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'3.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'50.50g", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'1G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'3G", "3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'50G", "00000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'.0G", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'3.0G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'50.0G", "3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'.1G", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'1.1G", "3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'50.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'1.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'3.3G", "3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#'.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-'1.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0'3.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-'50.50G", "3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'3.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'50.0g", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'1.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'50.1g", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'1.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'3.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'50.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'3.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'50.0G", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'1.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'50.1G", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#+'.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#-+'1.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0+'3.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0-+'50.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '1g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '3g", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '.0g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '3.0g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '50.0g", " 3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '1.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '50.1g", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '1.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '3.3g", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '1.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '3.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '50.50g", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '1G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '3G", " 3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '.0G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '3.0G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '50.0G", " 3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '1.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '50.1G", " 3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '1.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '3.3G", " 3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# '.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- '1.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 '3.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- '50.50G", " 3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'1g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'3g", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'3.0g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'50.0g", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'1.1g", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'50.1g", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'1.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'3.3g", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'1.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'3.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'50.50g", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'1G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'3G", "+3.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000003.14159", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'3.0G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'50.0G", "+3. ", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'1.1G", "+3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'50.1G", " +3.", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'1.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'3.3G", "+3.14", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%# +'.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#- +'1.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0 +'3.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%#0- +'50.50G", "+3.1415926535897931159979634685441851615905761718750", { 24, 45, 68, 84, 251, 33, 9, 64 } },
- { "%'1g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'3g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'50g", "0000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'.0g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'3.0g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'50.0g", "3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'.1g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'1.1g", "3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'50.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'1.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'3.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'1.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'3.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'50.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'1G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'3G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'50G", "0000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'.0G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'3.0G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'50.0G", "3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'.1G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'1.1G", "3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'50.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'1.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'3.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-'1.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0'3.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-'50.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'3.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'50.0g", "+3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'1.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'50.1g", " +3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'3.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'50.0G", "+3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'1.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'50.1G", " +3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%+'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%-+'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0+'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0-+'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '1g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '3g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '50g", " 000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '.0g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '3.0g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '50.0g", " 3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '1.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '50.1g", " 3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '1.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '3.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '1.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '3.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '50.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '1G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '3G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '50G", " 000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '.0G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '3.0G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '50.0G", " 3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '1.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '50.1G", " 3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '1.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '3.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% '.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- '1.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 '3.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- '50.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'3.0g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'50.0g", "+3e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'1.1g", "+3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'50.1g", " +3e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'3.0G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'50.0G", "+3E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'1.1G", "+3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'50.1G", " +3E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "% +'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%- +'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0 +'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%0- +'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'1g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'3g", "3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'50g", "0000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'.0g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'3.0g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'50.0g", "3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'.1g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'1.1g", "3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'50.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'1.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'3.3g", "3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'1.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'3.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'50.50g", "3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'1G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'3G", "3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'50G", "0000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'.0G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'3.0G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'50.0G", "3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'.1G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'1.1G", "3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'50.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'1.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'3.3G", "3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#'.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-'1.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0'3.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-'50.50G", "3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'3.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'50.0g", "+3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'1.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'50.1g", " +3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'3.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'50.0G", "+3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'1.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'50.1G", " +3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#+'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#-+'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0+'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0-+'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '1g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '3g", " 3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '50g", " 000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '.0g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '3.0g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '50.0g", " 3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '1.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '50.1g", " 3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '1.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '3.3g", " 3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '1.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '3.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '50.50g", " 3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '1G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '3G", " 3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '50G", " 000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '.0G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '3.0G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '50.0G", " 3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '1.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '50.1G", " 3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '1.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '3.3G", " 3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# '.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- '1.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 '3.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- '50.50G", " 3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'1g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'3g", "+3.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000003.14159e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'3.0g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'50.0g", "+3.e-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'1.1g", "+3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'50.1g", " +3.e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'1.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'3.3g", "+3.14e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'1.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'3.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'50.50g", "+3.1415926535897932727069897539156880721183917323596e-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'1G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'3G", "+3.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000003.14159E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'3.0G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'50.0G", "+3.E-50 ", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'1.1G", "+3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'50.1G", " +3.E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'1.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'3.3G", "+3.14E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%# +'.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#- +'1.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0 +'3.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%#0- +'50.50G", "+3.1415926535897932727069897539156880721183917323596E-50", { 33, 92, 244, 141, 24, 130, 167, 53 } },
- { "%'1g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'3g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'50g", "0000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'.0g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'3.0g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'50.0g", "3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'.1g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'1.1g", "3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'50.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'1.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'3.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'1.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'3.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'50.50g", "3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'1G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'3G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'50G", "0000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'.0G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'3.0G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'50.0G", "3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'.1G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'1.1G", "3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'50.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'1.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'3.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-'1.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0'3.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-'50.50G", "3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'3.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'50.0g", "+3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'1.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'50.1g", " +3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'1.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'3.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'50.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'3.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'50.0G", "+3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'1.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'50.1G", " +3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%+'.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%-+'1.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0+'3.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0-+'50.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '1g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '3g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '50g", " 000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '.0g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '3.0g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '50.0g", " 3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '1.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '50.1g", " 3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '1.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '3.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '1.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '3.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '50.50g", " 3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '1G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '3G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '50G", " 000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '.0G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '3.0G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '50.0G", " 3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '1.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '50.1G", " 3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '1.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '3.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% '.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- '1.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 '3.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- '50.50G", " 3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'3.0g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'50.0g", "+3e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'1.1g", "+3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'50.1g", " +3e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'1.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'3.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'50.50g", "+3.141592653589793652864438172706023653335508189184e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'3.0G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'50.0G", "+3E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'1.1G", "+3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'50.1G", " +3E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "% +'.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%- +'1.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0 +'3.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%0- +'50.50G", "+3.141592653589793652864438172706023653335508189184E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'1g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'3g", "3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'50g", "0000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'.0g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'3.0g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'50.0g", "3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'.1g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'1.1g", "3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'50.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'1.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'3.3g", "3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'1.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'3.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'50.50g", "3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'1G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'3G", "3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'50G", "0000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'.0G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'3.0G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'50.0G", "3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'.1G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'1.1G", "3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'50.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'1.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'3.3G", "3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#'.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-'1.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0'3.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-'50.50G", "3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'3.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'50.0g", "+3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'1.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'50.1g", " +3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'1.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'3.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'50.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'3.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'50.0G", "+3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'1.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'50.1G", " +3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#+'.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#-+'1.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0+'3.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0-+'50.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '1g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '3g", " 3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '50g", " 000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '.0g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '3.0g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '50.0g", " 3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '1.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '50.1g", " 3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '1.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '3.3g", " 3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '1.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '3.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '50.50g", " 3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '1G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '3G", " 3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '50G", " 000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '.0G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '3.0G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '50.0G", " 3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '1.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '50.1G", " 3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '1.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '3.3G", " 3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# '.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- '1.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 '3.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- '50.50G", " 3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'1g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'3g", "+3.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000003.14159e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'3.0g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'50.0g", "+3.e+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'1.1g", "+3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'50.1g", " +3.e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'1.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'3.3g", "+3.14e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'1.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'3.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'50.50g", "+3.1415926535897936528644381727060236533355081891840e+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'1G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'3G", "+3.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000003.14159E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'3.0G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'50.0G", "+3.E+50 ", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'1.1G", "+3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'50.1G", " +3.E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'1.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'3.3G", "+3.14E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%# +'.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#- +'1.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0 +'3.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%#0- +'50.50G", "+3.1415926535897936528644381727060236533355081891840E+50", { 209, 124, 155, 149, 155, 222, 106, 74 } },
- { "%'1g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'3g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'50g", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'.0g", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'3.0g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'50.0g", "3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'.1g", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'1.1g", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'50.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'1.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'3.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'1.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'3.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'50.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'1G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'3G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'50G", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'.0G", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'3.0G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'50.0G", "3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'.1G", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'1.1G", "3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'50.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'1.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'3.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-'1.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0'3.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-'50.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'.0g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'3.0g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'50.0g", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'1.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'50.1g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'.0G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'3.0G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'50.0G", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'1.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'50.1G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%+'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%-+'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0+'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0-+'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '1g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '3g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '.0g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '3.0g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '50.0g", " 3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '1.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '50.1g", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '1.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '3.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '1.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '3.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '50.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '1G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '3G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '.0G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '3.0G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '50.0G", " 3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '1.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '50.1G", " 3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '1.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '3.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% '.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- '1.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 '3.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- '50.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'.0g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'3.0g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'50.0g", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'1.1g", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'50.1g", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'.0G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'3.0G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'50.0G", "+3 ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'1.1G", "+3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'50.1G", " +3", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "% +'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%- +'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0 +'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%0- +'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'1g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'3g", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'50g", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'.0g", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'3.0g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'50.0g", "3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'.1g", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'1.1g", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'50.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'1.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'3.3g", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'1.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'3.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'50.50g", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'1G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'3G", "2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'50G", "00000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'.0G", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'3.0G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'50.0G", "3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'.1G", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'1.1G", "3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'50.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'1.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'3.3G", "2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#'.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-'1.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0'3.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-'50.50G", "2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'3.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'50.0g", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'1.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'50.1g", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'3.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'50.0G", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'1.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'50.1G", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#+'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#-+'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0+'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0-+'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '1g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '3g", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '.0g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '3.0g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '50.0g", " 3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '1.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '50.1g", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '1.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '3.3g", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '1.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '3.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '50.50g", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '1G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '3G", " 2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '.0G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '3.0G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '50.0G", " 3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '1.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '50.1G", " 3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '1.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '3.3G", " 2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# '.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- '1.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 '3.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- '50.50G", " 2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'1g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'3g", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'3.0g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'50.0g", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'1.1g", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'50.1g", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'1.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'3.3g", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'1.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'3.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'50.50g", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'1G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'3G", "+2.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000002.71828", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'3.0G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'50.0G", "+3. ", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'1.1G", "+3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'50.1G", " +3.", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'1.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'3.3G", "+2.72", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%# +'.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#- +'1.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0 +'3.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%#0- +'50.50G", "+2.7182818284590450907955982984276488423347473144531", { 105, 87, 20, 139, 10, 191, 5, 64 } },
- { "%'1g", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'3g", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'50g", "000000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'.0g", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'3.0g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'50.0g", "1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'.1g", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'1.1g", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'50.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'1.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'3.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'1.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'3.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'50.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'1G", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'3G", "1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'50G", "000000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'.0G", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'3.0G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'50.0G", "1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'.1G", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'1.1G", "1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'50.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'1.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'3.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-'1.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0'3.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-'50.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'1g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'3g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'50g", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'.0g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'3.0g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'50.0g", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'1.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'50.1g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'1G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'3G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'50G", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'.0G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'3.0G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'50.0G", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'1.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'50.1G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%+'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%-+'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0+'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0-+'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '1g", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '3g", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '50g", " 00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '.0g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '3.0g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '50.0g", " 1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '1.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '50.1g", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '1.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '3.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '1.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '3.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '50.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '1G", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '3G", " 1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '50G", " 00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '.0G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '3.0G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '50.0G", " 1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '1.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '50.1G", " 1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '1.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '3.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% '.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- '1.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 '3.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- '50.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'1g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'3g", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'50g", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'.0g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'3.0g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'50.0g", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'1.1g", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'50.1g", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'1G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'3G", "+1.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'50G", "+00000000000000000000000000000000000000000001.4427", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'.0G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'3.0G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'50.0G", "+1 ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'1.1G", "+1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'50.1G", " +1", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "% +'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%- +'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0 +'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%0- +'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'1g", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'3g", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'.0g", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'3.0g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'50.0g", "1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'.1g", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'1.1g", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'50.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'1.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'3.3g", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'1.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'3.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'50.50g", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'1G", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'3G", "1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'.0G", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'3.0G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'50.0G", "1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'.1G", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'1.1G", "1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'50.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'1.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'3.3G", "1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#'.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-'1.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0'3.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-'50.50G", "1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'1g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'3g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'3.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'50.0g", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'1.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'50.1g", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'1G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'3G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'3.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'50.0G", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'1.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'50.1G", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#+'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#-+'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0+'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0-+'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '1g", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '3g", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '.0g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '3.0g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '50.0g", " 1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '1.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '50.1g", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '1.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '3.3g", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '1.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '3.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '50.50g", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '1G", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '3G", " 1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '.0G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '3.0G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '50.0G", " 1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '1.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '50.1G", " 1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '1.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '3.3G", " 1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# '.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- '1.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 '3.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- '50.50G", " 1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'1g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'3g", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'3.0g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'50.0g", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'1.1g", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'50.1g", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'1.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'3.3g", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'1.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'3.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'50.50g", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'1G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'3G", "+1.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000001.44270", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'3.0G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'50.0G", "+1. ", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'1.1G", "+1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'50.1G", " +1.", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'1.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'3.3G", "+1.44", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%# +'.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#- +'1.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0 +'3.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%#0- +'50.50G", "+1.4426950408889633870046509400708600878715515136719", { 254, 130, 43, 101, 71, 21, 247, 63 } },
- { "%'1g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'3g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'50g", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'3.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'50.0g", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'1.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'1.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'3.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'1.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'3.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'50.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'1G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'3G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'50G", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'3.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'50.0G", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'1.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'1.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'3.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-'1.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0'3.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-'50.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%+'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%-+'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0+'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0-+'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '1g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '3g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '3.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '50.0g", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '1.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '1.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '3.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '1.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '3.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '50.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '1G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '3G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '3.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '50.0G", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '1.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '1.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '3.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% '.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- '1.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 '3.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- '50.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "% +'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%- +'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0 +'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%0- +'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'1g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'3g", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'50g", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'3.0g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'50.0g", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'1.1g", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'1.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'3.3g", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'1.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'3.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'50.50g", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'1G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'3G", "0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'50G", "0000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'3.0G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'50.0G", "0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'1.1G", "0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'1.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'3.3G", "0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#'.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-'1.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0'3.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-'50.50G", "0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#+'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#-+'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0+'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0-+'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '1g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '3g", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '50g", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '3.0g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '50.0g", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '1.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '50.1g", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '1.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '3.3g", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '1.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '3.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '50.50g", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '1G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '3G", " 0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '50G", " 000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '3.0G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '50.0G", " 0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '1.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '50.1G", " 0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '1.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '3.3G", " 0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# '.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- '1.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 '3.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- '50.50G", " 0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'1g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'3g", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'3.0g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'50.0g", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'1.1g", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'50.1g", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'1.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'3.3g", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'1.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'3.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'50.50g", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'1G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'3G", "+0.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000000000.434294", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'3.0G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'50.0G", "+0.4 ", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'1.1G", "+0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'50.1G", " +0.4", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'1.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'3.3G", "+0.434", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%# +'.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#- +'1.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0 +'3.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%#0- +'50.50G", "+0.43429448190325181666793241674895398318767547607422", { 14, 229, 38, 21, 123, 203, 219, 63 } },
- { "%'1g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'3g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'50g", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'3.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'50.0g", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'1.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'1.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'3.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'1.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'3.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'50.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'1G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'3G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'50G", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'3.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'50.0G", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'1.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'1.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'3.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-'1.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0'3.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-'50.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%+'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%-+'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0+'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0-+'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '1g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '3g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '3.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '50.0g", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '1.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '1.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '3.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '1.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '3.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '50.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '1G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '3G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '3.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '50.0G", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '1.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '1.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '3.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% '.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- '1.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 '3.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- '50.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "% +'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%- +'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0 +'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%0- +'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'1g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'3g", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'50g", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'3.0g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'50.0g", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'1.1g", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'1.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'3.3g", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'1.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'3.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'50.50g", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'1G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'3G", "0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'50G", "0000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'3.0G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'50.0G", "0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'1.1G", "0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'1.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'3.3G", "0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#'.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-'1.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0'3.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-'50.50G", "0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#+'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#-+'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0+'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0-+'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '1g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '3g", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '50g", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '3.0g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '50.0g", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '1.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '50.1g", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '1.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '3.3g", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '1.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '3.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '50.50g", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '1G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '3G", " 0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '50G", " 000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '3.0G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '50.0G", " 0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '1.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '50.1G", " 0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '1.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '3.3G", " 0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# '.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- '1.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 '3.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- '50.50G", " 0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'1g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'3g", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'3.0g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'50.0g", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'1.1g", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'50.1g", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'1.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'3.3g", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'1.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'3.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'50.50g", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'1G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'3G", "+0.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000000000.693147", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'3.0G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'50.0G", "+0.7 ", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'1.1G", "+0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'50.1G", " +0.7", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'1.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'3.3G", "+0.693", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%# +'.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#- +'1.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0 +'3.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%#0- +'50.50G", "+0.69314718055994528622676398299518041312694549560547", { 239, 57, 250, 254, 66, 46, 230, 63 } },
- { "%'1g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'3g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'50g", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'.0g", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'3.0g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'50.0g", "2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'.1g", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'1.1g", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'50.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'.3g", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'1.3g", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'3.3g", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'1.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'3.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'50.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'1G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'3G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'50G", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'.0G", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'3.0G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'50.0G", "2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'.1G", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'1.1G", "2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'50.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'.3G", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'1.3G", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'3.3G", "2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-'1.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0'3.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-'50.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'.0g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'3.0g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'50.0g", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'1.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'50.1g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'1.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'3.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'.0G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'3.0G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'50.0G", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'1.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'50.1G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'1.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'3.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%+'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%-+'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0+'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0-+'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '1g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '3g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '.0g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '3.0g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '50.0g", " 2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '1.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '50.1g", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '.3g", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '1.3g", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '3.3g", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '1.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '3.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '50.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '1G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '3G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '.0G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '3.0G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '50.0G", " 2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '1.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '50.1G", " 2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '.3G", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '1.3G", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '3.3G", " 2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% '.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- '1.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 '3.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- '50.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'.0g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'3.0g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'50.0g", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'1.1g", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'50.1g", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'1.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'3.3g", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'.0G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'3.0G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'50.0G", "+2 ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'1.1G", "+2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'50.1G", " +2", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'1.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'3.3G", "+2.3", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "% +'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%- +'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0 +'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%0- +'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'1g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'3g", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'50g", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'.0g", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'3.0g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'50.0g", "2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'.1g", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'1.1g", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'50.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'.3g", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'1.3g", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'3.3g", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'1.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'3.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'50.50g", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'1G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'3G", "2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'50G", "00000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'.0G", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'3.0G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'50.0G", "2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'.1G", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'1.1G", "2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'50.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'.3G", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'1.3G", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'3.3G", "2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#'.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-'1.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0'3.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-'50.50G", "2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'3.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'50.0g", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'1.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'50.1g", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'1.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'3.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'3.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'50.0G", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'1.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'50.1G", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'1.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'3.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#+'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#-+'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0+'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0-+'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '1g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '3g", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '.0g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '3.0g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '50.0g", " 2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '1.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '50.1g", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '.3g", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '1.3g", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '3.3g", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '1.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '3.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '50.50g", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '1G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '3G", " 2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '.0G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '3.0G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '50.0G", " 2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '1.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '50.1G", " 2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '.3G", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '1.3G", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '3.3G", " 2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# '.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- '1.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 '3.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- '50.50G", " 2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'1g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'3g", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'3.0g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'50.0g", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'1.1g", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'50.1g", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'1.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'3.3g", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'1.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'3.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'50.50g", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'1G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'3G", "+2.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000002.30259", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'3.0G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'50.0G", "+2. ", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'1.1G", "+2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'50.1G", " +2.", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'1.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'3.3G", "+2.30", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%# +'.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#- +'1.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0 +'3.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%#0- +'50.50G", "+2.3025850929940459010936137929093092679977416992188", { 22, 85, 181, 187, 177, 107, 2, 64 } },
- { "%'1g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'3g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'50g", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'.0g", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'3.0g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'50.0g", "1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'.1g", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'1.1g", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'50.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'1.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'3.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'1.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'3.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'50.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'1G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'3G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'50G", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'.0G", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'3.0G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'50.0G", "1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'.1G", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'1.1G", "1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'50.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'1.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'3.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-'1.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0'3.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-'50.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'.0g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'3.0g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'50.0g", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'1.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'50.1g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'.0G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'3.0G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'50.0G", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'1.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'50.1G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%+'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%-+'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0+'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0-+'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '1g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '3g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '.0g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '3.0g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '50.0g", " 1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '1.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '50.1g", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '1.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '3.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '1.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '3.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '50.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '1G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '3G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '.0G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '3.0G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '50.0G", " 1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '1.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '50.1G", " 1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '1.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '3.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% '.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- '1.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 '3.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- '50.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'.0g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'3.0g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'50.0g", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'1.1g", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'50.1g", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'.0G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'3.0G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'50.0G", "+1 ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'1.1G", "+1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'50.1G", " +1", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "% +'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%- +'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0 +'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%0- +'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'1g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'3g", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'.0g", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'3.0g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'50.0g", "1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'.1g", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'1.1g", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'50.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'1.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'3.3g", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'1.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'3.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'50.50g", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'1G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'3G", "1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'.0G", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'3.0G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'50.0G", "1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'.1G", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'1.1G", "1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'50.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'1.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'3.3G", "1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#'.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-'1.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0'3.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-'50.50G", "1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'3.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'50.0g", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'1.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'50.1g", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'3.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'50.0G", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'1.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'50.1G", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#+'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#-+'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0+'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0-+'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '1g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '3g", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '.0g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '3.0g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '50.0g", " 1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '1.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '50.1g", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '1.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '3.3g", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '1.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '3.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '50.50g", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '1G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '3G", " 1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '.0G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '3.0G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '50.0G", " 1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '1.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '50.1G", " 1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '1.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '3.3G", " 1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# '.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- '1.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 '3.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- '50.50G", " 1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'1g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'3g", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'3.0g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'50.0g", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'1.1g", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'50.1g", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'1.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'3.3g", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'1.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'3.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'50.50g", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'1G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'3G", "+1.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000001.12838", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'3.0G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'50.0G", "+1. ", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'1.1G", "+1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'50.1G", " +1.", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'1.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'3.3G", "+1.13", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%# +'.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#- +'1.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0 +'3.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%#0- +'50.50G", "+1.1283791670955125585606992899556644260883331298828", { 109, 155, 66, 80, 215, 13, 242, 63 } },
- { "%'1g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'3g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'50g", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'.0g", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'3.0g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'50.0g", "1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'.1g", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'1.1g", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'50.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'1.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'3.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'1.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'3.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'50.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'1G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'3G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'50G", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'.0G", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'3.0G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'50.0G", "1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'.1G", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'1.1G", "1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'50.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'1.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'3.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-'1.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0'3.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-'50.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'.0g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'3.0g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'50.0g", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'1.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'50.1g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'.0G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'3.0G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'50.0G", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'1.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'50.1G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%+'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%-+'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0+'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0-+'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '1g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '3g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '.0g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '3.0g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '50.0g", " 1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '1.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '50.1g", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '1.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '3.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '1.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '3.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '50.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '1G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '3G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '.0G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '3.0G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '50.0G", " 1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '1.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '50.1G", " 1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '1.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '3.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% '.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- '1.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 '3.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- '50.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'.0g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'3.0g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'50.0g", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'1.1g", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'50.1g", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'.0G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'3.0G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'50.0G", "+1 ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'1.1G", "+1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'50.1G", " +1", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "% +'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%- +'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0 +'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%0- +'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'1g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'3g", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'.0g", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'3.0g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'50.0g", "1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'.1g", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'1.1g", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'50.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'1.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'3.3g", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'1.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'3.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'50.50g", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'1G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'3G", "1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'.0G", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'3.0G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'50.0G", "1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'.1G", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'1.1G", "1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'50.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'1.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'3.3G", "1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#'.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-'1.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0'3.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-'50.50G", "1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'3.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'50.0g", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'1.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'50.1g", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'3.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'50.0G", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'1.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'50.1G", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#+'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#-+'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0+'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0-+'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '1g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '3g", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '.0g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '3.0g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '50.0g", " 1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '1.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '50.1g", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '1.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '3.3g", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '1.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '3.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '50.50g", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '1G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '3G", " 1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '.0G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '3.0G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '50.0G", " 1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '1.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '50.1G", " 1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '1.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '3.3G", " 1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# '.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- '1.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 '3.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- '50.50G", " 1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'1g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'3g", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'3.0g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'50.0g", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'1.1g", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'50.1g", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'1.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'3.3g", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'1.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'3.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'50.50g", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'1G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'3G", "+1.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000001.41421", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'3.0G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'50.0G", "+1. ", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'1.1G", "+1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'50.1G", " +1.", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'1.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'3.3G", "+1.41", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%# +'.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#- +'1.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0 +'3.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%#0- +'50.50G", "+1.4142135623730951454746218587388284504413604736328", { 205, 59, 127, 102, 158, 160, 246, 63 } },
- { "%'1g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'3g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'50g", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'3.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'50.0g", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'1.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'1.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'3.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'1.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'3.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'50.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'1G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'3G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'50G", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'3.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'50.0G", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'1.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'1.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'3.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-'1.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0'3.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-'50.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%+'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%-+'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0+'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0-+'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '1g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '3g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '3.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '50.0g", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '1.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '1.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '3.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '1.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '3.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '50.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '1G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '3G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '3.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '50.0G", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '1.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '1.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '3.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% '.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- '1.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 '3.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- '50.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "% +'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%- +'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0 +'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%0- +'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'1g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'3g", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'50g", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'3.0g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'50.0g", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'1.1g", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'1.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'3.3g", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'1.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'3.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'50.50g", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'1G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'3G", "0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'50G", "0000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'3.0G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'50.0G", "0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'1.1G", "0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'1.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'3.3G", "0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#'.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-'1.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0'3.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-'50.50G", "0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#+'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#-+'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0+'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0-+'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '1g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '3g", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '50g", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '3.0g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '50.0g", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '1.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '50.1g", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '1.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '3.3g", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '1.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '3.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '50.50g", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '1G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '3G", " 0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '50G", " 000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '3.0G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '50.0G", " 0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '1.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '50.1G", " 0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '1.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '3.3G", " 0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# '.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- '1.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 '3.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- '50.50G", " 0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'1g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'3g", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'3.0g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'50.0g", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'1.1g", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'50.1g", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'1.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'3.3g", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'1.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'3.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'50.50g", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'1G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'3G", "+0.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000000000.707107", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'3.0G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'50.0G", "+0.7 ", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'1.1G", "+0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'50.1G", " +0.7", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'1.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'3.3G", "+0.707", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%# +'.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#- +'1.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0 +'3.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%#0- +'50.50G", "+0.70710678118654757273731092936941422522068023681641", { 205, 59, 127, 102, 158, 160, 230, 63 } },
- { "%'1g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'50g", "0000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'.0g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'3.0g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'50.0g", "1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'.1g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'1.1g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'50.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'.3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'1.3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'3.3g", "1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'1.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'3.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'50.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'1G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'50G", "0000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'.0G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'3.0G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'50.0G", "1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'.1G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'1.1G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'50.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'.3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'1.3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'3.3G", "1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-'1.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0'3.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-'50.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'3.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'50.0g", "+1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'1.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'50.1g", " +1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'1.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'3.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'3.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'50.0G", "+1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'1.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'50.1G", " +1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'1.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'3.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%+'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%-+'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0+'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0-+'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '.0g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '3.0g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '50.0g", " 1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '1.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '50.1g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '.3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '1.3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '3.3g", " 1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '1.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '3.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '50.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '.0G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '3.0G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '50.0G", " 1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '1.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '50.1G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '.3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '1.3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '3.3G", " 1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% '.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- '1.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 '3.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- '50.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000001e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'3.0g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'50.0g", "+1e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'1.1g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'50.1g", " +1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'1.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'3.3g", "+1e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000001E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'3.0G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'50.0G", "+1E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'1.1G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'50.1G", " +1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'1.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'3.3G", "+1E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "% +'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%- +'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0 +'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%0- +'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'1g", "1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'3g", "1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'.0g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'3.0g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'50.0g", "1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'.1g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'1.1g", "1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'50.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'.3g", "1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'1.3g", "1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'3.3g", "1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'1.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'3.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'50.50g", "9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'1G", "1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'3G", "1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'.0G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'3.0G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'50.0G", "1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'.1G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'1.1G", "1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'50.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'.3G", "1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'1.3G", "1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'3.3G", "1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#'.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-'1.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0'3.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-'50.50G", "9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'1g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'3g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'3.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'50.0g", "+1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'1.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'50.1g", " +1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'1.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'3.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'1G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'3G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'3.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'50.0G", "+1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'1.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'50.1G", " +1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'1.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'3.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#+'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#-+'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0+'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0-+'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '1g", " 1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '3g", " 1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '.0g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '3.0g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '50.0g", " 1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '1.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '50.1g", " 1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '.3g", " 1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '1.3g", " 1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '3.3g", " 1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '1.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '3.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '50.50g", " 9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '1G", " 1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '3G", " 1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '.0G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '3.0G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '50.0G", " 1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '1.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '50.1G", " 1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '.3G", " 1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '1.3G", " 1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '3.3G", " 1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# '.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- '1.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 '3.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- '50.50G", " 9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'1g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'3g", "+1.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'3.0g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'50.0g", "+1.e-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'1.1g", "+1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'50.1g", " +1.e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'1.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'3.3g", "+1.00e-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'1.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'3.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'50.50g", "+9.9999999999999999881930935455989869713432907291639e-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'1G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'3G", "+1.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'3.0G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'50.0G", "+1.E-14 ", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'1.1G", "+1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'50.1G", " +1.E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'1.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'3.3G", "+1.00E-14", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%# +'.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#- +'1.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0 +'3.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%#0- +'50.50G", "+9.9999999999999999881930935455989869713432907291639E-15", { 155, 43, 161, 134, 155, 132, 6, 61 } },
- { "%'1g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'3g", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'50g", "00000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'.0g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'3.0g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'50.0g", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'.1g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'1.1g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'50.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'.3g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'1.3g", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'3.3g", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'1.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'3.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'50.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'1G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'3G", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'50G", "00000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'.0G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'3.0G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'50.0G", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'.1G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'1.1G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'50.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'.3G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'1.3G", "1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'3.3G", "1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-'1.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0'3.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-'50.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'50g", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'.0g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'3.0g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'50.0g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'1.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'50.1g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'1.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'3.3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'50G", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'.0G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'3.0G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'50.0G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'1.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'50.1G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'1.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'3.3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%+'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%-+'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0+'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0-+'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '3g", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '50g", " 0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '.0g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '3.0g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '50.0g", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '1.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '50.1g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '.3g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '1.3g", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '3.3g", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '1.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '3.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '50.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '3G", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '50G", " 0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '.0G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '3.0G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '50.0G", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '1.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '50.1G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '.3G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '1.3G", " 1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '3.3G", " 1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% '.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- '1.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 '3.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- '50.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'50g", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'.0g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'3.0g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'50.0g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'1.1g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'50.1g", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'1.3g", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'3.3g", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'50G", "+0000000000000000000000000000000000000000000000001", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'.0G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'3.0G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'50.0G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'1.1G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'50.1G", " +1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'1.3G", "+1", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'3.3G", "+1 ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "% +'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%- +'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0 +'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%0- +'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'1g", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'3g", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'50g", "00000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'.0g", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'3.0g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'50.0g", "1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'.1g", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'1.1g", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'50.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'.3g", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'1.3g", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'3.3g", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'1.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'3.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'50.50g", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'1G", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'3G", "1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'50G", "00000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'.0G", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'3.0G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'50.0G", "1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'.1G", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'1.1G", "1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'50.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'.3G", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'1.3G", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'3.3G", "1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#'.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-'1.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0'3.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-'50.50G", "0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'1g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'3g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'50g", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'3.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'50.0g", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'1.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'50.1g", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'1.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'3.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'1G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'3G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'50G", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'3.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'50.0G", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'1.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'50.1G", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'1.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'3.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#+'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#-+'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0+'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0-+'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '1g", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '3g", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '50g", " 0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '.0g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '3.0g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '50.0g", " 1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '1.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '50.1g", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '.3g", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '1.3g", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '3.3g", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '1.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '3.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '50.50g", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '1G", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '3G", " 1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '50G", " 0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '.0G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '3.0G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '50.0G", " 1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '1.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '50.1G", " 1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '.3G", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '1.3G", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '3.3G", " 1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# '.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- '1.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 '3.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- '50.50G", " 0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'1g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'3g", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'50g", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'3.0g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'50.0g", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'1.1g", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'50.1g", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'1.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'3.3g", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'1.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'3.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'50.50g", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'1G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'3G", "+1.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'50G", "+0000000000000000000000000000000000000000001.00000", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'3.0G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'50.0G", "+1. ", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'1.1G", "+1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'50.1G", " +1.", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'1.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'3.3G", "+1.00", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%# +'.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#- +'1.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0 +'3.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%#0- +'50.50G", "+0.99999999999999000799277837359113618731498718261719", { 166, 255, 255, 255, 255, 255, 239, 63 } },
- { "%'1g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'50g", "0000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'.0g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'3.0g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'50.0g", "1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'.1g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'1.1g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'50.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'.3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'1.3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'3.3g", "1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'1.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'3.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'50.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'1G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'50G", "0000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'.0G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'3.0G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'50.0G", "1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'.1G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'1.1G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'50.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'.3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'1.3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'3.3G", "1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-'1.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0'3.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-'50.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'3.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'50.0g", "+1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'1.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'50.1g", " +1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'1.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'3.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'3.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'50.0G", "+1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'1.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'50.1G", " +1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'1.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'3.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%+'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%-+'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0+'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0-+'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '.0g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '3.0g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '50.0g", " 1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '1.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '50.1g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '.3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '1.3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '3.3g", " 1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '1.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '3.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '50.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '.0G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '3.0G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '50.0G", " 1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '1.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '50.1G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '.3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '1.3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '3.3G", " 1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% '.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- '1.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 '3.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- '50.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000001e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'3.0g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'50.0g", "+1e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'1.1g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'50.1g", " +1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'1.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'3.3g", "+1e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000001E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'3.0G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'50.0G", "+1E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'1.1G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'50.1G", " +1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'1.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'3.3G", "+1E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "% +'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%- +'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0 +'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%0- +'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'1g", "1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'3g", "1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'.0g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'3.0g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'50.0g", "1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'.1g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'1.1g", "1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'50.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'.3g", "1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'1.3g", "1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'3.3g", "1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'1.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'3.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'50.50g", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'1G", "1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'3G", "1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'.0G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'3.0G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'50.0G", "1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'.1G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'1.1G", "1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'50.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'.3G", "1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'1.3G", "1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'3.3G", "1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#'.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-'1.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0'3.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-'50.50G", "99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'1g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'3g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'3.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'50.0g", "+1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'1.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'50.1g", " +1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'1.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'3.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'1G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'3G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'3.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'50.0G", "+1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'1.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'50.1G", " +1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'1.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'3.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#+'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#-+'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0+'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0-+'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '1g", " 1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '3g", " 1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '.0g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '3.0g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '50.0g", " 1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '1.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '50.1g", " 1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '.3g", " 1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '1.3g", " 1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '3.3g", " 1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '1.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '3.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '50.50g", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '1G", " 1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '3G", " 1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '.0G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '3.0G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '50.0G", " 1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '1.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '50.1G", " 1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '.3G", " 1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '1.3G", " 1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '3.3G", " 1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# '.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- '1.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 '3.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- '50.50G", " 99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'1g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'3g", "+1.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'3.0g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'50.0g", "+1.e+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'1.1g", "+1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'50.1g", " +1.e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'1.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'3.3g", "+1.00e+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'1.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'3.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'50.50g", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'1G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'3G", "+1.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'3.0G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'50.0G", "+1.E+50 ", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'1.1G", "+1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'50.1G", " +1.E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'1.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'3.3G", "+1.00E+50", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%# +'.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#- +'1.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0 +'3.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%#0- +'50.50G", "+99,999,999,999,999,010,708,773,002,404,982,325,439,669,760,688,128.", { 106, 100, 126, 197, 14, 27, 81, 74 } },
- { "%'1g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'50g", "0000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'.0g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'3.0g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'50.0g", "1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'.1g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'1.1g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'50.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'.3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'1.3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'3.3g", "1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'1.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'3.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'50.50g", "9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'1G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'50G", "0000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'.0G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'3.0G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'50.0G", "1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'.1G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'1.1G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'50.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'.3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'1.3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'3.3G", "1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-'1.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0'3.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-'50.50G", "9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'50g", "+000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'3.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'50.0g", "+1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'1.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'50.1g", " +1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'1.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'3.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'1.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'3.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'50.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'50G", "+000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'3.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'50.0G", "+1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'1.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'50.1G", " +1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'1.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'3.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%+'.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%-+'1.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0+'3.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0-+'50.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '50g", " 000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '.0g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '3.0g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '50.0g", " 1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '1.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '50.1g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '.3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '1.3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '3.3g", " 1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '1.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '3.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '50.50g", " 9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '50G", " 000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '.0G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '3.0G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '50.0G", " 1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '1.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '50.1G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '.3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '1.3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '3.3G", " 1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% '.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- '1.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 '3.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- '50.50G", " 9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'50g", "+000000000000000000000000000000000000000000001e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'3.0g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'50.0g", "+1e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'1.1g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'50.1g", " +1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'1.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'3.3g", "+1e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'1.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'3.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'50.50g", "+9.999999999999900372700906579936580106949261241377e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'50G", "+000000000000000000000000000000000000000000001E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'3.0G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'50.0G", "+1E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'1.1G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'50.1G", " +1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'1.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'3.3G", "+1E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "% +'.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%- +'1.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0 +'3.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%0- +'50.50G", "+9.999999999999900372700906579936580106949261241377E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'1g", "1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'3g", "1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'.0g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'3.0g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'50.0g", "1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'.1g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'1.1g", "1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'50.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'.3g", "1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'1.3g", "1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'3.3g", "1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'1.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'3.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'50.50g", "9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'1G", "1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'3G", "1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'.0G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'3.0G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'50.0G", "1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'.1G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'1.1G", "1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'50.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'.3G", "1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'1.3G", "1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'3.3G", "1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#'.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-'1.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0'3.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-'50.50G", "9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'1g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'3g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'3.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'50.0g", "+1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'1.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'50.1g", " +1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'1.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'3.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'1.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'3.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'50.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'1G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'3G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'3.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'50.0G", "+1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'1.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'50.1G", " +1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'1.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'3.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#+'.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#-+'1.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0+'3.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0-+'50.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '1g", " 1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '3g", " 1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '.0g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '3.0g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '50.0g", " 1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '1.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '50.1g", " 1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '.3g", " 1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '1.3g", " 1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '3.3g", " 1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '1.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '3.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '50.50g", " 9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '1G", " 1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '3G", " 1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '.0G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '3.0G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '50.0G", " 1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '1.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '50.1G", " 1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '.3G", " 1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '1.3G", " 1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '3.3G", " 1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# '.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- '1.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 '3.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- '50.50G", " 9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'1g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'3g", "+1.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.00000e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'3.0g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'50.0g", "+1.e-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'1.1g", "+1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'50.1g", " +1.e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'1.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'3.3g", "+1.00e-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'1.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'3.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'50.50g", "+9.9999999999999003727009065799365801069492612413770e-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'1G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'3G", "+1.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.00000E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'3.0G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'50.0G", "+1.E-50 ", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'1.1G", "+1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'50.1G", " +1.E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'1.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'3.3G", "+1.00E-50", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%# +'.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#- +'1.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0 +'3.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%#0- +'50.50G", "+9.9999999999999003727009065799365801069492612413770E-51", { 203, 183, 212, 74, 122, 238, 141, 53 } },
- { "%'1g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'50g", "000000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'.0g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'3.0g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'50.0g", "1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'.1g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'1.1g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'50.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'.3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'1.3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'3.3g", "1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'1.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'3.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'50.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'1G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'50G", "000000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'.0G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'3.0G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'50.0G", "1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'.1G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'1.1G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'50.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'.3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'1.3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'3.3G", "1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-'1.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0'3.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-'50.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'50g", "+00000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'3.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'50.0g", "+1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'1.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'50.1g", " +1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'1.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'3.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'50G", "+00000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'3.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'50.0G", "+1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'1.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'50.1G", " +1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'1.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'3.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%+'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%-+'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0+'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0-+'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '50g", " 00000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '.0g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '3.0g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '50.0g", " 1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '1.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '50.1g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '.3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '1.3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '3.3g", " 1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '1.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '3.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '50.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '50G", " 00000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '.0G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '3.0G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '50.0G", " 1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '1.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '50.1G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '.3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '1.3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '3.3G", " 1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% '.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- '1.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 '3.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- '50.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'50g", "+00000000000000000000000000000000000000000001e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'3.0g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'50.0g", "+1e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'1.1g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'50.1g", " +1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'1.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'3.3g", "+1e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'50G", "+00000000000000000000000000000000000000000001E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'3.0G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'50.0G", "+1E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'1.1G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'50.1G", " +1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'1.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'3.3G", "+1E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "% +'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%- +'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0 +'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%0- +'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'1g", "1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'3g", "1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'50g", "000000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'.0g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'3.0g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'50.0g", "1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'.1g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'1.1g", "1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'50.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'.3g", "1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'1.3g", "1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'3.3g", "1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'1.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'3.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'50.50g", "9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'1G", "1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'3G", "1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'50G", "000000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'.0G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'3.0G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'50.0G", "1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'.1G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'1.1G", "1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'50.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'.3G", "1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'1.3G", "1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'3.3G", "1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#'.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-'1.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0'3.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-'50.50G", "9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'1g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'3g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'50g", "+00000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'3.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'50.0g", "+1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'1.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'50.1g", " +1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'1.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'3.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'1G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'3G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'50G", "+00000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'3.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'50.0G", "+1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'1.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'50.1G", " +1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'1.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'3.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#+'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#-+'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0+'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0-+'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '1g", " 1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '3g", " 1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '50g", " 00000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '.0g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '3.0g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '50.0g", " 1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '1.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '50.1g", " 1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '.3g", " 1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '1.3g", " 1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '3.3g", " 1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '1.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '3.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '50.50g", " 9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '1G", " 1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '3G", " 1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '50G", " 00000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '.0G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '3.0G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '50.0G", " 1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '1.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '50.1G", " 1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '.3G", " 1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '1.3G", " 1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '3.3G", " 1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# '.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- '1.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 '3.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- '50.50G", " 9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'1g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'3g", "+1.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'3.0g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'50.0g", "+1.e+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'1.1g", "+1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'50.1g", " +1.e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'1.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'3.3g", "+1.00e+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'1.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'3.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'50.50g", "+9.9999999999998998680313710784262953737076155396797e+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'1G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'3G", "+1.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'3.0G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'50.0G", "+1.E+150 ", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'1.1G", "+1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'50.1G", " +1.E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'1.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'3.3G", "+1.00E+150", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%# +'.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#- +'1.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0 +'3.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%#0- +'50.50G", "+9.9999999999998998680313710784262953737076155396797E+149", { 120, 150, 80, 46, 53, 141, 19, 95 } },
- { "%'1g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'50g", "000000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'.0g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'3.0g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'50.0g", "1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'.1g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'1.1g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'50.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'.3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'1.3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'3.3g", "1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'1.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'3.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'50.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'1G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'50G", "000000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'.0G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'3.0G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'50.0G", "1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'.1G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'1.1G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'50.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'.3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'1.3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'3.3G", "1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-'1.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0'3.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-'50.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'50g", "+00000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'3.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'50.0g", "+1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'1.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'50.1g", " +1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'1.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'3.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'50G", "+00000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'3.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'50.0G", "+1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'1.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'50.1G", " +1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'1.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'3.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%+'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%-+'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0+'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0-+'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '50g", " 00000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '.0g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '3.0g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '50.0g", " 1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '1.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '50.1g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '.3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '1.3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '3.3g", " 1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '1.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '3.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '50.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '50G", " 00000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '.0G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '3.0G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '50.0G", " 1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '1.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '50.1G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '.3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '1.3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '3.3G", " 1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% '.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- '1.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 '3.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- '50.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'50g", "+00000000000000000000000000000000000000000001e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'3.0g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'50.0g", "+1e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'1.1g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'50.1g", " +1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'1.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'3.3g", "+1e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'50G", "+00000000000000000000000000000000000000000001E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'3.0G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'50.0G", "+1E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'1.1G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'50.1G", " +1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'1.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'3.3G", "+1E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "% +'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%- +'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0 +'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%0- +'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'1g", "1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'3g", "1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'50g", "000000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'.0g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'3.0g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'50.0g", "1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'.1g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'1.1g", "1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'50.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'.3g", "1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'1.3g", "1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'3.3g", "1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'1.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'3.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'50.50g", "9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'1G", "1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'3G", "1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'50G", "000000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'.0G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'3.0G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'50.0G", "1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'.1G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'1.1G", "1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'50.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'.3G", "1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'1.3G", "1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'3.3G", "1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#'.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-'1.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0'3.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-'50.50G", "9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'1g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'3g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'50g", "+00000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'3.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'50.0g", "+1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'1.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'50.1g", " +1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'1.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'3.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'1G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'3G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'50G", "+00000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'3.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'50.0G", "+1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'1.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'50.1G", " +1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'1.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'3.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#+'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#-+'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0+'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0-+'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '1g", " 1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '3g", " 1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '50g", " 00000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '.0g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '3.0g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '50.0g", " 1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '1.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '50.1g", " 1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '.3g", " 1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '1.3g", " 1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '3.3g", " 1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '1.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '3.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '50.50g", " 9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '1G", " 1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '3G", " 1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '50G", " 00000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '.0G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '3.0G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '50.0G", " 1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '1.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '50.1G", " 1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '.3G", " 1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '1.3G", " 1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '3.3G", " 1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# '.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- '1.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 '3.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- '50.50G", " 9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'1g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'3g", "+1.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'3.0g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'50.0g", "+1.e-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'1.1g", "+1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'50.1g", " +1.e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'1.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'3.3g", "+1.00e-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'1.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'3.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'50.50g", "+9.9999999999998996697971724732593184628359320226585e-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'1G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'3G", "+1.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'3.0G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'50.0G", "+1.E-150 ", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'1.1G", "+1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'50.1G", " +1.E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'1.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'3.3G", "+1.00E-150", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%# +'.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#- +'1.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0 +'3.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%#0- +'50.50G", "+9.9999999999998996697971724732593184628359320226585E-151", { 43, 148, 63, 106, 231, 47, 202, 32 } },
- { "%'1g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'50g", "000000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'.0g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'3.0g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'50.0g", "1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'.1g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'1.1g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'50.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'.3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'1.3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'3.3g", "1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'1.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'3.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'50.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'1G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'50G", "000000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'.0G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'3.0G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'50.0G", "1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'.1G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'1.1G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'50.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'.3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'1.3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'3.3G", "1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-'1.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0'3.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-'50.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'50g", "+00000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'3.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'50.0g", "+1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'1.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'50.1g", " +1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'1.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'3.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'50G", "+00000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'3.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'50.0G", "+1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'1.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'50.1G", " +1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'1.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'3.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%+'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%-+'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0+'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0-+'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '50g", " 00000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '.0g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '3.0g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '50.0g", " 1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '1.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '50.1g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '.3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '1.3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '3.3g", " 1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '1.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '3.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '50.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '50G", " 00000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '.0G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '3.0G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '50.0G", " 1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '1.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '50.1G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '.3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '1.3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '3.3G", " 1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% '.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- '1.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 '3.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- '50.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'50g", "+00000000000000000000000000000000000000000001e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'3.0g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'50.0g", "+1e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'1.1g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'50.1g", " +1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'1.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'3.3g", "+1e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'50G", "+00000000000000000000000000000000000000000001E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'3.0G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'50.0G", "+1E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'1.1G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'50.1G", " +1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'1.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'3.3G", "+1E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "% +'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%- +'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0 +'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%0- +'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'1g", "1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'3g", "1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'50g", "000000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'.0g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'3.0g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'50.0g", "1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'.1g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'1.1g", "1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'50.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'.3g", "1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'1.3g", "1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'3.3g", "1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'1.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'3.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'50.50g", "9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'1G", "1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'3G", "1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'50G", "000000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'.0G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'3.0G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'50.0G", "1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'.1G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'1.1G", "1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'50.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'.3G", "1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'1.3G", "1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'3.3G", "1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#'.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-'1.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0'3.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-'50.50G", "9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'1g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'3g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'50g", "+00000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'3.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'50.0g", "+1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'1.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'50.1g", " +1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'1.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'3.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'1G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'3G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'50G", "+00000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'3.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'50.0G", "+1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'1.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'50.1G", " +1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'1.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'3.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#+'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#-+'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0+'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0-+'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '1g", " 1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '3g", " 1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '50g", " 00000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '.0g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '3.0g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '50.0g", " 1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '1.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '50.1g", " 1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '.3g", " 1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '1.3g", " 1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '3.3g", " 1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '1.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '3.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '50.50g", " 9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '1G", " 1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '3G", " 1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '50G", " 00000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '.0G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '3.0G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '50.0G", " 1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '1.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '50.1G", " 1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '.3G", " 1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '1.3G", " 1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '3.3G", " 1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# '.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- '1.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 '3.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- '50.50G", " 9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'1g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'3g", "+1.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'3.0g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'50.0g", "+1.e+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'1.1g", "+1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'50.1g", " +1.e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'1.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'3.3g", "+1.00e+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'1.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'3.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'50.50g", "+9.9999999999998994184781783194753840004916356484734e+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'1G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'3G", "+1.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'3.0G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'50.0G", "+1.E+200 ", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'1.1G", "+1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'50.1G", " +1.E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'1.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'3.3G", "+1.00E+200", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%# +'.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#- +'1.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0 +'3.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%#0- +'50.50G", "+9.9999999999998994184781783194753840004916356484734E+199", { 31, 98, 215, 215, 24, 231, 116, 105 } },
- { "%'1g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'50g", "000000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'.0g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'3.0g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'50.0g", "1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'.1g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'1.1g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'50.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'.3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'1.3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'3.3g", "1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'1.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'3.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'50.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'1G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'50G", "000000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'.0G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'3.0G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'50.0G", "1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'.1G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'1.1G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'50.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'.3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'1.3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'3.3G", "1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-'1.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0'3.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-'50.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'50g", "+00000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'3.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'50.0g", "+1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'1.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'50.1g", " +1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'1.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'3.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'50G", "+00000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'3.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'50.0G", "+1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'1.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'50.1G", " +1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'1.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'3.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%+'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%-+'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0+'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0-+'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '50g", " 00000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '.0g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '3.0g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '50.0g", " 1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '1.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '50.1g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '.3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '1.3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '3.3g", " 1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '1.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '3.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '50.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '50G", " 00000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '.0G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '3.0G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '50.0G", " 1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '1.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '50.1G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '.3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '1.3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '3.3G", " 1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% '.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- '1.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 '3.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- '50.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'50g", "+00000000000000000000000000000000000000000001e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'3.0g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'50.0g", "+1e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'1.1g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'50.1g", " +1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'1.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'3.3g", "+1e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'50G", "+00000000000000000000000000000000000000000001E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'3.0G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'50.0G", "+1E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'1.1G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'50.1G", " +1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'1.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'3.3G", "+1E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "% +'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%- +'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0 +'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%0- +'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'1g", "1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'3g", "1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'50g", "000000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'.0g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'3.0g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'50.0g", "1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'.1g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'1.1g", "1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'50.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'.3g", "1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'1.3g", "1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'3.3g", "1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'1.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'3.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'50.50g", "9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'1G", "1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'3G", "1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'50G", "000000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'.0G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'3.0G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'50.0G", "1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'.1G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'1.1G", "1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'50.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'.3G", "1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'1.3G", "1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'3.3G", "1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#'.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-'1.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0'3.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-'50.50G", "9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'1g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'3g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'50g", "+00000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'3.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'50.0g", "+1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'1.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'50.1g", " +1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'1.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'3.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'1G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'3G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'50G", "+00000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'3.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'50.0G", "+1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'1.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'50.1G", " +1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'1.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'3.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#+'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#-+'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0+'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0-+'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '1g", " 1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '3g", " 1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '50g", " 00000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '.0g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '3.0g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '50.0g", " 1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '1.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '50.1g", " 1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '.3g", " 1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '1.3g", " 1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '3.3g", " 1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '1.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '3.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '50.50g", " 9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '1G", " 1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '3G", " 1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '50G", " 00000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '.0G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '3.0G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '50.0G", " 1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '1.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '50.1G", " 1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '.3G", " 1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '1.3G", " 1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '3.3G", " 1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# '.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- '1.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 '3.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- '50.50G", " 9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'1g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'3g", "+1.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000001.00000e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'3.0g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'50.0g", "+1.e-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'1.1g", "+1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'50.1g", " +1.e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'1.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'3.3g", "+1.00e-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'1.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'3.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'50.50g", "+9.9999999999998997421771888360822479533450192126953e-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'1G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'3G", "+1.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000001.00000E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'3.0G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'50.0G", "+1.E-200 ", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'1.1G", "+1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'50.1G", " +1.E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'1.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'3.3G", "+1.00E-200", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%# +'.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#- +'1.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0 +'3.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%#0- +'50.50G", "+9.9999999999998997421771888360822479533450192126953E-201", { 103, 247, 78, 21, 146, 126, 104, 22 } },
- { "%'1g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'3g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'50g", "000000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'.0g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'3.0g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'50.0g", "2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'.1g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'1.1g", "2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'50.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'.3g", "1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'1.3g", "1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'3.3g", "1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'1.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'3.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'50.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'1G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'3G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'50G", "000000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'.0G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'3.0G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'50.0G", "2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'.1G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'1.1G", "2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'50.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'.3G", "1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'1.3G", "1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'3.3G", "1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-'1.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0'3.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-'50.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'3.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'50.0g", "+2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'1.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'50.1g", " +2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'1.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'3.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'3.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'50.0G", "+2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'1.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'50.1G", " +2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'1.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'3.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%+'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%-+'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0+'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0-+'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '1g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '3g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '50g", " 00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '.0g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '3.0g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '50.0g", " 2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '1.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '50.1g", " 2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '.3g", " 1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '1.3g", " 1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '3.3g", " 1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '1.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '3.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '50.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '1G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '3G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '50G", " 00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '.0G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '3.0G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '50.0G", " 2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '1.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '50.1G", " 2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '.3G", " 1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '1.3G", " 1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '3.3G", " 1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% '.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- '1.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 '3.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- '50.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'3.0g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'50.0g", "+2e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'1.1g", "+2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'50.1g", " +2e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'1.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'3.3g", "+1.8e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'3.0G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'50.0G", "+2E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'1.1G", "+2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'50.1G", " +2E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'1.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'3.3G", "+1.8E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "% +'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%- +'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0 +'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%0- +'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'1g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'3g", "1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'50g", "000000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'.0g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'3.0g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'50.0g", "2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'.1g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'1.1g", "2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'50.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'.3g", "1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'1.3g", "1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'3.3g", "1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'1.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'3.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'50.50g", "1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'1G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'3G", "1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'50G", "000000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'.0G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'3.0G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'50.0G", "2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'.1G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'1.1G", "2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'50.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'.3G", "1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'1.3G", "1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'3.3G", "1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#'.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-'1.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0'3.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-'50.50G", "1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'3.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'50.0g", "+2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'1.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'50.1g", " +2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'1.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'3.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'3.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'50.0G", "+2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'1.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'50.1G", " +2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'1.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'3.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#+'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#-+'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0+'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0-+'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '1g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '3g", " 1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '50g", " 00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '.0g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '3.0g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '50.0g", " 2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '1.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '50.1g", " 2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '.3g", " 1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '1.3g", " 1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '3.3g", " 1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '1.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '3.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '50.50g", " 1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '1G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '3G", " 1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '50G", " 00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '.0G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '3.0G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '50.0G", " 2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '1.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '50.1G", " 2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '.3G", " 1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '1.3G", " 1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '3.3G", " 1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# '.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- '1.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 '3.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- '50.50G", " 1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'1g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'3g", "+1.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000001.79769e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'3.0g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'50.0g", "+2.e+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'1.1g", "+2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'50.1g", " +2.e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'1.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'3.3g", "+1.80e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'1.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'3.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'50.50g", "+1.7976931348623157081452742373170435679807056752584e+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'1G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'3G", "+1.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000001.79769E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'3.0G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'50.0G", "+2.E+308 ", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'1.1G", "+2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'50.1G", " +2.E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'1.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'3.3G", "+1.80E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%# +'.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#- +'1.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0 +'3.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%#0- +'50.50G", "+1.7976931348623157081452742373170435679807056752584E+308", { 255, 255, 255, 255, 255, 255, 239, 127 } },
- { "%'1g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'3g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'50g", "0000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'.0g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'3.0g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'50.0g", "3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'.1g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'1.1g", "3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'50.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'.3g", "3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'1.3g", "3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'3.3g", "3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'1.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'3.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'50.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'1G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'3G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'50G", "0000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'.0G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'3.0G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'50.0G", "3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'.1G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'1.1G", "3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'50.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'.3G", "3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'1.3G", "3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'3.3G", "3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-'1.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0'3.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-'50.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'3.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'50.0g", "+3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'1.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'50.1g", " +3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'1.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'3.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'3.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'50.0G", "+3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'1.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'50.1G", " +3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'1.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'3.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%+'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%-+'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0+'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0-+'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '1g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '3g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '50g", " 000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '.0g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '3.0g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '50.0g", " 3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '1.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '50.1g", " 3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '.3g", " 3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '1.3g", " 3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '3.3g", " 3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '1.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '3.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '50.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '1G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '3G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '50G", " 000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '.0G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '3.0G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '50.0G", " 3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '1.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '50.1G", " 3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '.3G", " 3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '1.3G", " 3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '3.3G", " 3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% '.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- '1.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 '3.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- '50.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'3.0g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'50.0g", "+3e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'1.1g", "+3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'50.1g", " +3e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'1.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'3.3g", "+3.4e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'3.0G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'50.0G", "+3E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'1.1G", "+3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'50.1G", " +3E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'1.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'3.3G", "+3.4E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "% +'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%- +'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0 +'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%0- +'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'1g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'3g", "3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'50g", "0000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'.0g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'3.0g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'50.0g", "3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'.1g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'1.1g", "3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'50.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'.3g", "3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'1.3g", "3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'3.3g", "3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'1.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'3.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'50.50g", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'1G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'3G", "3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'50G", "0000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'.0G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'3.0G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'50.0G", "3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'.1G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'1.1G", "3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'50.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'.3G", "3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'1.3G", "3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'3.3G", "3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#'.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-'1.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0'3.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-'50.50G", "340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'3.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'50.0g", "+3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'1.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'50.1g", " +3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'1.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'3.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'3.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'50.0G", "+3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'1.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'50.1G", " +3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'1.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'3.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#+'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#-+'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0+'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0-+'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '1g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '3g", " 3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '50g", " 000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '.0g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '3.0g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '50.0g", " 3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '1.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '50.1g", " 3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '.3g", " 3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '1.3g", " 3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '3.3g", " 3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '1.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '3.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '50.50g", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '1G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '3G", " 3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '50G", " 000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '.0G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '3.0G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '50.0G", " 3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '1.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '50.1G", " 3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '.3G", " 3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '1.3G", " 3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '3.3G", " 3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# '.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- '1.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 '3.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- '50.50G", " 340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'1g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'3g", "+3.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000003.40282e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'3.0g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'50.0g", "+3.e+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'1.1g", "+3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'50.1g", " +3.e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'1.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'3.3g", "+3.40e+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'1.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'3.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'50.50g", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'1G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'3G", "+3.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000003.40282E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'3.0G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'50.0G", "+3.E+38 ", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'1.1G", "+3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'50.1G", " +3.E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'1.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'3.3G", "+3.40E+38", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%# +'.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#- +'1.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0 +'3.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%#0- +'50.50G", "+340,282,346,638,528,859,811,704,183,484,516,925,440.00000000000", { 0, 0, 0, 224, 255, 255, 239, 71 } },
- { "%'1g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'3g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'50g", "0000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'.0g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'3.0g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'50.0g", "2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'.1g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'1.1g", "2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'50.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'1.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'3.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'.50g", "2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'1.50g", "2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'3.50g", "2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'50.50g", "2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'1G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'3G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'50G", "0000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'.0G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'3.0G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'50.0G", "2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'.1G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'1.1G", "2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'50.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'1.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'3.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'.50G", "2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-'1.50G", "2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0'3.50G", "2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-'50.50G", "2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'3.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'50.0g", "+2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'1.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'50.1g", " +2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'1.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'3.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'50.50g", "+2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'3.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'50.0G", "+2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'1.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'50.1G", " +2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%+'.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%-+'1.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0+'3.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0-+'50.50G", "+2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '1g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '3g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '50g", " 000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '.0g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '3.0g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '50.0g", " 2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '1.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '50.1g", " 2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '1.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '3.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '.50g", " 2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '1.50g", " 2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '3.50g", " 2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '50.50g", " 2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '1G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '3G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '50G", " 000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '.0G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '3.0G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '50.0G", " 2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '1.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '50.1G", " 2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '1.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '3.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% '.50G", " 2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- '1.50G", " 2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 '3.50G", " 2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- '50.50G", " 2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'3.0g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'50.0g", "+2e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'1.1g", "+2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'50.1g", " +2e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'1.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'3.50g", "+2.220446049250313080847263336181640625e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'50.50g", "+2.220446049250313080847263336181640625e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'3.0G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'50.0G", "+2E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'1.1G", "+2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'50.1G", " +2E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "% +'.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%- +'1.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0 +'3.50G", "+2.220446049250313080847263336181640625E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%0- +'50.50G", "+2.220446049250313080847263336181640625E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'1g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'3g", "2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'50g", "0000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'.0g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'3.0g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'50.0g", "2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'.1g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'1.1g", "2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'50.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'1.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'3.3g", "2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'1.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'3.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'50.50g", "2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'1G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'3G", "2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'50G", "0000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'.0G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'3.0G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'50.0G", "2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'.1G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'1.1G", "2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'50.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'1.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'3.3G", "2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#'.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-'1.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0'3.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-'50.50G", "2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'3.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'50.0g", "+2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'1.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'50.1g", " +2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'1.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'3.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'50.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'3.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'50.0G", "+2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'1.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'50.1G", " +2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#+'.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#-+'1.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0+'3.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0-+'50.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '1g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '3g", " 2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '50g", " 000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '.0g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '3.0g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '50.0g", " 2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '1.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '50.1g", " 2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '1.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '3.3g", " 2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '1.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '3.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '50.50g", " 2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '1G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '3G", " 2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '50G", " 000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '.0G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '3.0G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '50.0G", " 2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '1.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '50.1G", " 2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '1.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '3.3G", " 2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# '.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- '1.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 '3.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- '50.50G", " 2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'1g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'3g", "+2.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000002.22045e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'3.0g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'50.0g", "+2.e-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'1.1g", "+2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'50.1g", " +2.e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'1.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'3.3g", "+2.22e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'1.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'3.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'50.50g", "+2.2204460492503130808472633361816406250000000000000e-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'1G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'3G", "+2.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000002.22045E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'3.0G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'50.0G", "+2.E-16 ", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'1.1G", "+2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'50.1G", " +2.E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'1.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'3.3G", "+2.22E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%# +'.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#- +'1.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0 +'3.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%#0- +'50.50G", "+2.2204460492503130808472633361816406250000000000000E-16", { 0, 0, 0, 0, 0, 0, 176, 60 } },
- { "%'1g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'3g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'50g", "000000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'.0g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'3.0g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'50.0g", "2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'.1g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'1.1g", "2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'50.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'1.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'3.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'1.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'3.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'50.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'1G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'3G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'50G", "000000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'.0G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'3.0G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'50.0G", "2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'.1G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'1.1G", "2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'50.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'1.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'3.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-'1.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0'3.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-'50.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'3.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'50.0g", "+2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'1.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'50.1g", " +2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'3.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'50.0G", "+2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'1.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'50.1G", " +2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%+'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%-+'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0+'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0-+'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '1g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '3g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '50g", " 00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '.0g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '3.0g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '50.0g", " 2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '1.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '50.1g", " 2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '1.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '3.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '1.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '3.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '50.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '1G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '3G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '50G", " 00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '.0G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '3.0G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '50.0G", " 2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '1.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '50.1G", " 2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '1.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '3.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% '.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- '1.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 '3.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- '50.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'3.0g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'50.0g", "+2e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'1.1g", "+2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'50.1g", " +2e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'3.0G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'50.0G", "+2E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'1.1G", "+2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'50.1G", " +2E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "% +'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%- +'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0 +'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%0- +'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'1g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'3g", "2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'50g", "000000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'.0g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'3.0g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'50.0g", "2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'.1g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'1.1g", "2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'50.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'1.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'3.3g", "2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'1.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'3.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'50.50g", "2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'1G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'3G", "2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'50G", "000000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'.0G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'3.0G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'50.0G", "2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'.1G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'1.1G", "2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'50.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'1.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'3.3G", "2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#'.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-'1.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0'3.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-'50.50G", "2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'3.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'50.0g", "+2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'1.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'50.1g", " +2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'3.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'50.0G", "+2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'1.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'50.1G", " +2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#+'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#-+'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0+'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0-+'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '1g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '3g", " 2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '50g", " 00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '.0g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '3.0g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '50.0g", " 2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '1.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '50.1g", " 2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '1.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '3.3g", " 2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '1.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '3.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '50.50g", " 2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '1G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '3G", " 2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '50G", " 00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '.0G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '3.0G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '50.0G", " 2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '1.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '50.1G", " 2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '1.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '3.3G", " 2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# '.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- '1.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 '3.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- '50.50G", " 2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'1g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'3g", "+2.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'50g", "+00000000000000000000000000000000000002.22507e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'3.0g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'50.0g", "+2.e-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'1.1g", "+2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'50.1g", " +2.e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'1.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'3.3g", "+2.23e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'1.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'3.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'50.50g", "+2.2250738585072013830902327173324040642192159804623e-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'1G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'3G", "+2.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'50G", "+00000000000000000000000000000000000002.22507E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'3.0G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'50.0G", "+2.E-308 ", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'1.1G", "+2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'50.1G", " +2.E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'1.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'3.3G", "+2.23E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%# +'.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#- +'1.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0 +'3.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%#0- +'50.50G", "+2.2250738585072013830902327173324040642192159804623E-308", { 0, 0, 0, 0, 0, 0, 16, 0 } },
- { "%'1g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'3g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'50g", "0000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'.0g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'3.0g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'50.0g", "1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'.1g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'1.1g", "1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'50.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'1.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'3.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'1.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'3.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'50.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'1G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'3G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'50G", "0000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'.0G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'3.0G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'50.0G", "1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'.1G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'1.1G", "1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'50.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'1.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'3.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%'.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-'1.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0'3.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-'50.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'3.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'50.0g", "+1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'1.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'50.1g", " +1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'3.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'50.0G", "+1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'1.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'50.1G", " +1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%+'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%-+'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0+'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0-+'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '1g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '3g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '50g", " 000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '.0g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '3.0g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '50.0g", " 1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '1.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '50.1g", " 1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '1.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '3.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '1.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '3.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '50.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '1G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '3G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '50G", " 000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '.0G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '3.0G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '50.0G", " 1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '1.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '50.1G", " 1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '1.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '3.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% '.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- '1.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 '3.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- '50.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'3.0g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'50.0g", "+1e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'1.1g", "+1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'50.1g", " +1e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'3.0G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'50.0G", "+1E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'1.1G", "+1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'50.1G", " +1E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "% +'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%- +'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0 +'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%0- +'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'1g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'3g", "1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'50g", "0000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'.0g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'3.0g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'50.0g", "1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'.1g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'1.1g", "1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'50.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'1.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'3.3g", "1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'1.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'3.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'50.50g", "1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'1G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'3G", "1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'50G", "0000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'.0G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'3.0G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'50.0G", "1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'.1G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'1.1G", "1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'50.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'1.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'3.3G", "1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#'.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-'1.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0'3.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-'50.50G", "1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'3.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'50.0g", "+1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'1.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'50.1g", " +1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'3.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'50.0G", "+1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'1.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'50.1G", " +1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#+'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#-+'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0+'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0-+'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '1g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '3g", " 1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '50g", " 000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '.0g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '3.0g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '50.0g", " 1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '1.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '50.1g", " 1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '1.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '3.3g", " 1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '1.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '3.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '50.50g", " 1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '1G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '3G", " 1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '50G", " 000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '.0G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '3.0G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '50.0G", " 1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '1.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '50.1G", " 1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '1.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '3.3G", " 1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# '.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- '1.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 '3.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- '50.50G", " 1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'1g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'3g", "+1.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'50g", "+000000000000000000000000000000000000001.17549e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'3.0g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'50.0g", "+1.e-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'1.1g", "+1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'50.1g", " +1.e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'1.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'3.3g", "+1.18e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'1.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'3.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'50.50g", "+1.1754943508222875079687365372222456778186655567721e-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'1G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'3G", "+1.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'50G", "+000000000000000000000000000000000000001.17549E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'3.0G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'50.0G", "+1.E-38 ", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'1.1G", "+1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'50.1G", " +1.E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'1.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'3.3G", "+1.18E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%# +'.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#- +'1.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0 +'3.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { "%#0- +'50.50G", "+1.1754943508222875079687365372222456778186655567721E-38", { 0, 0, 0, 0, 0, 0, 16, 56 } },
- { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }
-};
-
diff --git a/tests/auto/corelib/tools/qstring/qstring.pro b/tests/auto/corelib/tools/qstring/qstring.pro
deleted file mode 100644
index ec8a9b5df5..0000000000
--- a/tests/auto/corelib/tools/qstring/qstring.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstring
-QT = core-private testlib
-SOURCES = tst_qstring.cpp
-DEFINES += QT_NO_CAST_TO_ASCII
-qtConfig(icu): DEFINES += QT_USE_ICU
-qtConfig(c++11): CONFIG += c++11
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-
-!qtConfig(doubleconversion):!qtConfig(system-doubleconversion) {
- DEFINES += QT_NO_DOUBLECONVERSION
-}
-
-mac {
- OBJECTIVE_SOURCES += tst_qstring_mac.mm
- LIBS += -framework Foundation
-}
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
deleted file mode 100644
index e8ed22e427..0000000000
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ /dev/null
@@ -1,7044 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifdef QT_NO_CAST_FROM_ASCII
-# undef QT_NO_CAST_FROM_ASCII
-#endif
-#ifdef QT_NO_CAST_TO_ASCII
-# undef QT_NO_CAST_TO_ASCII
-#endif
-#ifdef QT_ASCII_CAST_WARNINGS
-# undef QT_ASCII_CAST_WARNINGS
-#endif
-
-#include <QtTest/QtTest>
-#include <qregexp.h>
-#include <qregularexpression.h>
-#include <qtextcodec.h>
-#include <qtextstream.h>
-#include <qstringlist.h>
-#include <qstringmatcher.h>
-#include <qbytearraymatcher.h>
-#include <qvariant.h>
-
-#include <qlocale.h>
-#include <locale.h>
-#include <qhash.h>
-
-#include <string>
-#include <algorithm>
-
-#define CREATE_REF(string) \
- const QString padded = QLatin1Char(' ') + string + QLatin1Char(' '); \
- QStringRef ref = padded.midRef(1, padded.size() - 2);
-
-namespace {
-
-// this wraps an argument to a QString function, as well as how to apply
-// the argument to a given QString member function.
-template <typename T>
-class Arg;
-
-template <typename T>
-class Reversed {}; // marker for Arg<QChar> to apply the operation in reverse order (for prepend())
-
-class ArgBase
-{
-protected:
- QString pinned;
- explicit ArgBase(const char *str)
- : pinned(QString::fromLatin1(str)) {}
-};
-
-template <>
-class Arg<QChar> : protected ArgBase
-{
-public:
- explicit Arg(const char *str) : ArgBase(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { for (QChar ch : qAsConst(this->pinned)) (s.*mf)(ch); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { for (QChar ch : qAsConst(this->pinned)) (s.*mf)(a1, ch); }
-};
-
-template <>
-class Arg<Reversed<QChar> > : private Arg<QChar>
-{
-public:
- explicit Arg(const char *str) : Arg<QChar>(str)
- {
- std::reverse(this->pinned.begin(), this->pinned.end());
- }
-
- using Arg<QChar>::apply0;
- using Arg<QChar>::apply1;
-};
-
-template <>
-class Arg<QString> : ArgBase
-{
-public:
- explicit Arg(const char *str) : ArgBase(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { (s.*mf)(this->pinned); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { (s.*mf)(a1, this->pinned); }
-};
-
-template <>
-class Arg<QStringRef> : ArgBase
-{
- QStringRef ref() const
- { return QStringRef(&pinned); }
-public:
- explicit Arg(const char *str) : ArgBase(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { (s.*mf)(ref()); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { (s.*mf)(a1, ref()); }
-};
-
-template <>
-class Arg<QPair<const QChar *, int> > : ArgBase
-{
-public:
- explicit Arg(const char *str) : ArgBase(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { (s.*mf)(this->pinned.constData(), this->pinned.length()); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { (s.*mf)(a1, this->pinned.constData(), this->pinned.length()); }
-};
-
-template <>
-class Arg<QLatin1String>
-{
- QLatin1String l1;
-public:
- explicit Arg(const char *str) : l1(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { (s.*mf)(l1); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { (s.*mf)(a1, l1); }
-};
-
-template <>
-class Arg<char>
-{
-protected:
- const char *str;
-public:
- explicit Arg(const char *str) : str(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- {
- if (str) {
- for (const char *it = str; *it; ++it)
- (s.*mf)(*it);
- }
- }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- {
- if (str) {
- for (const char *it = str; *it; ++it)
- (s.*mf)(a1, *it);
- }
- }
-};
-
-template <>
-class Arg<Reversed<char> > : private Arg<char>
-{
- static const char *dupAndReverse(const char *s)
- {
- char *s2 = qstrdup(s);
- std::reverse(s2, s2 + qstrlen(s2));
- return s2;
- }
-public:
- explicit Arg(const char *str) : Arg<char>(dupAndReverse(str)) {}
- ~Arg() { delete[] str; }
-
- using Arg<char>::apply0;
- using Arg<char>::apply1;
-};
-
-template <>
-class Arg<const char*>
-{
- const char *str;
-public:
- explicit Arg(const char *str) : str(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { (s.*mf)(str); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { (s.*mf)(a1, str); }
-};
-
-template <>
-class Arg<QByteArray>
-{
- QByteArray ba;
-public:
- explicit Arg(const char *str) : ba(str) {}
-
- template <typename MemFun>
- void apply0(QString &s, MemFun mf) const
- { (s.*mf)(ba); }
-
- template <typename MemFun, typename A1>
- void apply1(QString &s, MemFun mf, A1 a1) const
- { (s.*mf)(a1, ba); }
-};
-
-// const char* is not allowed as columns in data-driven tests (causes static_assert failure),
-// so wrap it in a container (default ctor is a QMetaType/QVariant requirement):
-class CharStarContainer
-{
- const char *str;
-public:
- explicit Q_DECL_CONSTEXPR CharStarContainer(const char *s = nullptr) : str(s) {}
- Q_DECL_CONSTEXPR operator const char *() const { return str; }
-};
-
-} // unnamed namespace
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(CharStarContainer, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(CharStarContainer)
-
-// implementation helpers for append_impl/prepend_impl etc
-template <typename ArgType, typename MemFun>
-static void do_apply0(MemFun mf)
-{
- QFETCH(QString, s);
- QFETCH(CharStarContainer, arg);
- QFETCH(QString, expected);
-
- Arg<ArgType>(arg).apply0(s, mf);
-
- QCOMPARE(s, expected);
- QCOMPARE(s.isEmpty(), expected.isEmpty());
- QCOMPARE(s.isNull(), expected.isNull());
-}
-
-template <typename ArgType, typename A1, typename MemFun>
-static void do_apply1(MemFun mf)
-{
- QFETCH(QString, s);
- QFETCH(CharStarContainer, arg);
- QFETCH(A1, a1);
- QFETCH(QString, expected);
-
- Arg<ArgType>(arg).apply1(s, mf, a1);
-
- QCOMPARE(s, expected);
- QCOMPARE(s.isEmpty(), expected.isEmpty());
- QCOMPARE(s.isNull(), expected.isNull());
-}
-
-class tst_QString : public QObject
-{
- Q_OBJECT
-
- template<typename List, class RegExp>
- void split_regexp(const QString &string, const QString &pattern, QStringList result);
- template<typename List>
- void split(const QString &string, const QString &separator, QStringList result);
-
- template <typename ArgType, typename MemFun>
- void append_impl() const { do_apply0<ArgType>(MemFun(&QString::append)); }
- template <typename ArgType>
- void append_impl() const { append_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
- void append_data(bool emptyIsNoop = false);
- template <typename ArgType, typename MemFun>
- void operator_pluseq_impl() const { do_apply0<ArgType>(MemFun(&QString::operator+=)); }
- template <typename ArgType>
- void operator_pluseq_impl() const { operator_pluseq_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
- void operator_pluseq_data(bool emptyIsNoop = false);
- template <typename ArgType, typename MemFun>
- void prepend_impl() const { do_apply0<ArgType>(MemFun(&QString::prepend)); }
- template <typename ArgType>
- void prepend_impl() const { prepend_impl<ArgType, QString &(QString::*)(const ArgType&)>(); }
- void prepend_data(bool emptyIsNoop = false);
- template <typename ArgType, typename MemFun>
- void insert_impl() const { do_apply1<ArgType, int>(MemFun(&QString::insert)); }
- template <typename ArgType>
- void insert_impl() const { insert_impl<ArgType, QString &(QString::*)(int, const ArgType&)>(); }
- void insert_data(bool emptyIsNoop = false);
-
- class TransientDefaultLocale
- {
- const QLocale prior; // Records what *was* the default before we set it.
- public:
- TransientDefaultLocale(const QLocale &transient) { revise(transient); }
- void revise(const QLocale &transient) { QLocale::setDefault(transient); }
- ~TransientDefaultLocale() { QLocale::setDefault(prior); }
- };
-
-public:
- tst_QString();
-private slots:
- void fromStdString();
- void toStdString();
- void check_QTextIOStream();
- void check_QTextStream();
- void check_QDataStream();
- void fromRawData();
- void setRawData();
- void endsWith();
- void startsWith();
- void setNum();
- void toDouble_data();
- void toDouble();
- void toFloat();
- void toLong_data();
- void toLong();
- void toULong_data();
- void toULong();
- void toLongLong();
- void toULongLong();
- void toUInt();
- void toInt();
- void toShort();
- void toUShort();
- void replace_qchar_qchar_data();
- void replace_qchar_qchar();
- void replace_qchar_qstring_data();
- void replace_qchar_qstring();
- void replace_uint_uint_data();
- void replace_uint_uint();
- void replace_extra();
- void replace_string_data();
- void replace_string();
- void replace_regexp_data();
- void replace_regexp();
- void remove_uint_uint_data();
- void remove_uint_uint();
- void remove_string_data();
- void remove_string();
- void remove_regexp_data();
- void remove_regexp();
- void swap();
-
- void prepend_qstring() { prepend_impl<QString>(); }
- void prepend_qstring_data() { prepend_data(true); }
- void prepend_qstringref() { prepend_impl<QStringRef>(); }
- void prepend_qstringref_data() { prepend_data(true); }
- void prepend_qlatin1string() { prepend_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
- void prepend_qlatin1string_data() { prepend_data(true); }
- void prepend_qcharstar_int() { prepend_impl<QPair<const QChar *, int>, QString &(QString::*)(const QChar *, int)>(); }
- void prepend_qcharstar_int_data() { prepend_data(true); }
- void prepend_qchar() { prepend_impl<Reversed<QChar>, QString &(QString::*)(QChar)>(); }
- void prepend_qchar_data() { prepend_data(true); }
- void prepend_qbytearray() { prepend_impl<QByteArray>(); }
- void prepend_qbytearray_data() { prepend_data(true); }
- void prepend_char() { prepend_impl<Reversed<char>, QString &(QString::*)(QChar)>(); }
- void prepend_char_data() { prepend_data(true); }
- void prepend_charstar() { prepend_impl<const char *, QString &(QString::*)(const char *)>(); }
- void prepend_charstar_data() { prepend_data(true); }
- void prepend_bytearray_special_cases_data();
- void prepend_bytearray_special_cases();
-
- void append_qstring() { append_impl<QString>(); }
- void append_qstring_data() { append_data(); }
- void append_qstringref() { append_impl<QStringRef>(); }
- void append_qstringref_data() { append_data(); }
- void append_qlatin1string() { append_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
- void append_qlatin1string_data() { append_data(); }
- void append_qcharstar_int() { append_impl<QPair<const QChar *, int>, QString&(QString::*)(const QChar *, int)>(); }
- void append_qcharstar_int_data() { append_data(true); }
- void append_qchar() { append_impl<QChar, QString &(QString::*)(QChar)>(); }
- void append_qchar_data() { append_data(true); }
- void append_qbytearray() { append_impl<QByteArray>(); }
- void append_qbytearray_data() { append_data(); }
- void append_char() { append_impl<char, QString &(QString::*)(QChar)>(); }
- void append_char_data() { append_data(true); }
- void append_charstar() { append_impl<const char *, QString &(QString::*)(const char *)>(); }
- void append_charstar_data() { append_data(); }
- void append_special_cases();
- void append_bytearray_special_cases_data();
- void append_bytearray_special_cases();
-
- void operator_pluseq_qstring() { operator_pluseq_impl<QString>(); }
- void operator_pluseq_qstring_data() { operator_pluseq_data(); }
- void operator_pluseq_qstringref() { operator_pluseq_impl<QStringRef>(); }
- void operator_pluseq_qstringref_data() { operator_pluseq_data(); }
- void operator_pluseq_qlatin1string() { operator_pluseq_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
- void operator_pluseq_qlatin1string_data() { operator_pluseq_data(); }
- void operator_pluseq_qchar() { operator_pluseq_impl<QChar, QString &(QString::*)(QChar)>(); }
- void operator_pluseq_qchar_data() { operator_pluseq_data(true); }
- void operator_pluseq_qbytearray() { operator_pluseq_impl<QByteArray>(); }
- void operator_pluseq_qbytearray_data() { operator_pluseq_data(); }
- void operator_pluseq_char() { operator_pluseq_impl<char, QString &(QString::*)(char)>(); }
- void operator_pluseq_char_data() { operator_pluseq_data(true); }
- void operator_pluseq_charstar() { operator_pluseq_impl<const char *, QString &(QString::*)(const char *)>(); }
- void operator_pluseq_charstar_data() { operator_pluseq_data(); }
- void operator_pluseq_bytearray_special_cases_data();
- void operator_pluseq_bytearray_special_cases();
-
- void operator_eqeq_bytearray_data();
- void operator_eqeq_bytearray();
- void operator_eqeq_nullstring();
- void operator_smaller();
-
- void insert_qstring() { insert_impl<QString>(); }
- void insert_qstring_data() { insert_data(true); }
- void insert_qstringref() { insert_impl<QStringRef>(); }
- void insert_qstringref_data() { insert_data(true); }
- void insert_qlatin1string() { insert_impl<QLatin1String, QString &(QString::*)(int, QLatin1String)>(); }
- void insert_qlatin1string_data() { insert_data(true); }
- void insert_qcharstar_int() { insert_impl<QPair<const QChar *, int>, QString &(QString::*)(int, const QChar*, int) >(); }
- void insert_qcharstar_int_data() { insert_data(true); }
- void insert_qchar() { insert_impl<Reversed<QChar>, QString &(QString::*)(int, QChar)>(); }
- void insert_qchar_data() { insert_data(true); }
- void insert_qbytearray() { insert_impl<QByteArray>(); }
- void insert_qbytearray_data() { insert_data(true); }
- void insert_char() { insert_impl<Reversed<char>, QString &(QString::*)(int, QChar)>(); }
- void insert_char_data() { insert_data(true); }
- void insert_charstar() { insert_impl<const char *, QString &(QString::*)(int, const char*) >(); }
- void insert_charstar_data() { insert_data(true); }
- void insert_special_cases();
-
- void simplified_data();
- void simplified();
- void trimmed();
- void toUpper();
- void toLower();
- void isUpper();
- void isLower();
- void toCaseFolded();
- void rightJustified();
- void leftJustified();
- void mid();
- void right();
- void left();
- void midRef();
- void rightRef();
- void leftRef();
- void stringRef();
- void contains();
- void count();
- void lastIndexOf_data();
- void lastIndexOf();
- void lastIndexOfInvalidRegex();
- void indexOf_data();
- void indexOf();
- void indexOfInvalidRegex();
- void indexOf2_data();
- void indexOf2();
- void indexOf3_data();
-// void indexOf3();
- void sprintf();
- void sprintfS();
- void fill();
- void truncate();
- void chop_data();
- void chop();
- void constructor();
- void constructorQByteArray_data();
- void constructorQByteArray();
- void STL();
- void macTypes();
- void isEmpty();
- void isNull();
- void acc_01();
- void length_data();
- void length();
- void utf8_data();
- void utf8();
- void fromUtf8_data();
- void fromUtf8();
- void nullFromUtf8();
- void fromLocal8Bit_data();
- void fromLocal8Bit();
- void local8Bit_data();
- void local8Bit();
- void invalidToLocal8Bit_data();
- void invalidToLocal8Bit();
- void nullFromLocal8Bit();
- void fromLatin1Roundtrip_data();
- void fromLatin1Roundtrip();
- void toLatin1Roundtrip_data();
- void toLatin1Roundtrip();
- void stringRef_toLatin1Roundtrip_data();
- void stringRef_toLatin1Roundtrip();
- void stringRef_utf8_data();
- void stringRef_utf8();
- void stringRef_local8Bit_data();
- void stringRef_local8Bit();
- void fromLatin1();
- void fromAscii();
- void fromUcs4();
- void toUcs4();
- void arg();
- void number();
- void doubleOut();
- void arg_fillChar_data();
- void arg_fillChar();
- void capacity_data();
- void capacity();
- void section_data();
- void section();
- void double_conversion_data();
- void double_conversion();
- void integer_conversion_data();
- void integer_conversion();
- void tortureSprintfDouble();
- void toNum();
- void localeAwareCompare_data();
- void localeAwareCompare();
- void reverseIterators();
- void split_data();
- void split();
- void split_regexp_data();
- void split_regexp();
- void split_regularexpression_data();
- void split_regularexpression();
- void splitRef_data();
- void splitRef();
- void splitRef_regexp_data();
- void splitRef_regexp();
- void splitRef_regularexpression_data();
- void splitRef_regularexpression();
- void fromUtf16_data();
- void fromUtf16();
- void fromUtf16_char16_data();
- void fromUtf16_char16();
- void latin1String();
- void nanAndInf();
- void compare_data();
- void compare();
- void resize();
- void resizeAfterFromRawData();
- void resizeAfterReserve();
- void resizeWithNegative() const;
- void truncateWithNegative() const;
- void QCharRefMutableUnicode() const;
- void QCharRefDetaching() const;
- void sprintfZU() const;
- void repeatedSignature() const;
- void repeated() const;
- void repeated_data() const;
- void compareRef();
- void arg_locale();
-#ifdef QT_USE_ICU
- void toUpperLower_icu();
-#endif
-#if !defined(QT_NO_UNICODE_LITERAL) && defined(Q_COMPILER_LAMBDA)
- void literals();
-#endif
- void eightBitLiterals_data();
- void eightBitLiterals();
- void reserve();
- void toHtmlEscaped_data();
- void toHtmlEscaped();
- void operatorGreaterWithQLatin1String();
- void compareQLatin1Strings();
- void fromQLatin1StringWithLength();
- void assignQLatin1String();
- void assignQChar();
- void isRightToLeft_data();
- void isRightToLeft();
- void unicodeStrings();
-};
-
-template <class T> const T &verifyZeroTermination(const T &t) { return t; }
-
-QString verifyZeroTermination(const QString &str)
-{
- // This test does some evil stuff, it's all supposed to work.
-
- QString::DataPtr strDataPtr = const_cast<QString &>(str).data_ptr();
-
- // Skip if isStatic() or fromRawData(), as those offer no guarantees
- if (strDataPtr->ref.isStatic()
- || strDataPtr->offset != QString().data_ptr()->offset)
- return str;
-
- int strSize = str.size();
- QChar strTerminator = str.constData()[strSize];
- if (QChar('\0') != strTerminator)
- return QString::fromAscii(
- "*** Result ('%1') not null-terminated: 0x%2 ***").arg(str)
- .arg(strTerminator.unicode(), 4, 16, QChar('0'));
-
- // Skip mutating checks on shared strings
- if (strDataPtr->ref.isShared())
- return str;
-
- const QChar *strData = str.constData();
- const QString strCopy(strData, strSize); // Deep copy
-
- const_cast<QChar *>(strData)[strSize] = QChar('x');
- if (QChar('x') != str.constData()[strSize]) {
- return QString::fromAscii("*** Failed to replace null-terminator in "
- "result ('%1') ***").arg(str);
- }
- if (str != strCopy) {
- return QString::fromAscii( "*** Result ('%1') differs from its copy "
- "after null-terminator was replaced ***").arg(str);
- }
- const_cast<QChar *>(strData)[strSize] = QChar('\0'); // Restore sanity
-
- return str;
-}
-
-// Overriding QTest's QCOMPARE, to check QString for null termination
-#undef QCOMPARE
-#define QCOMPARE(actual, expected) \
- do { \
- if (!QTest::qCompare(verifyZeroTermination(actual), expected, \
- #actual, #expected, __FILE__, __LINE__)) \
- return; \
- } while (0) \
- /**/
-#undef QTEST
-#define QTEST(actual, testElement) \
- do { \
- if (!QTest::qTest(verifyZeroTermination(actual), testElement, \
- #actual, #testElement, __FILE__, __LINE__)) \
- return; \
- } while (0) \
- /**/
-
-typedef QVector<int> IntList;
-
-tst_QString::tst_QString()
-{
- QTextCodec::setCodecForLocale(QTextCodec::codecForName("ISO 8859-1"));
-}
-
-void tst_QString::remove_uint_uint_data()
-{
- replace_uint_uint_data();
-}
-
-void tst_QString::remove_string_data()
-{
- replace_string_data();
-}
-
-void tst_QString::remove_regexp_data()
-{
- replace_regexp_data();
-}
-
-void tst_QString::indexOf3_data()
-{
- indexOf2_data();
-}
-
-void tst_QString::length_data()
-{
- QTest::addColumn<QString>("s1" );
- QTest::addColumn<int>("res" );
-
- QTest::newRow( "data0" ) << QString("Test") << 4;
- QTest::newRow( "data1" ) << QString("The quick brown fox jumps over the lazy dog") << 43;
- QTest::newRow( "data2" ) << QString() << 0;
- QTest::newRow( "data3" ) << QString("A") << 1;
- QTest::newRow( "data4" ) << QString("AB") << 2;
- QTest::newRow( "data5" ) << QString("AB\n") << 3;
- QTest::newRow( "data6" ) << QString("AB\nC") << 4;
- QTest::newRow( "data7" ) << QString("\n") << 1;
- QTest::newRow( "data8" ) << QString("\nA") << 2;
- QTest::newRow( "data9" ) << QString("\nAB") << 3;
- QTest::newRow( "data10" ) << QString("\nAB\nCDE") << 7;
- QTest::newRow( "data11" ) << QString("shdnftrheid fhgnt gjvnfmd chfugkh bnfhg thgjf vnghturkf chfnguh bjgnfhvygh hnbhgutjfv dhdnjds dcjs d") << 100;
-}
-
-void tst_QString::replace_qchar_qchar_data()
-{
- QTest::addColumn<QString>("src" );
- QTest::addColumn<QChar>("before" );
- QTest::addColumn<QChar>("after" );
- QTest::addColumn<int>("cs" );
- QTest::addColumn<QString>("expected" );
-
- QTest::newRow( "1" ) << QString("foo") << QChar('o') << QChar('a')
- << int(Qt::CaseSensitive) << QString("faa");
- QTest::newRow( "2" ) << QString("foo") << QChar('o') << QChar('a')
- << int(Qt::CaseInsensitive) << QString("faa");
- QTest::newRow( "3" ) << QString("foo") << QChar('O') << QChar('a')
- << int(Qt::CaseSensitive) << QString("foo");
- QTest::newRow( "4" ) << QString("foo") << QChar('O') << QChar('a')
- << int(Qt::CaseInsensitive) << QString("faa");
- QTest::newRow( "5" ) << QString("ababABAB") << QChar('a') << QChar(' ')
- << int(Qt::CaseSensitive) << QString(" b bABAB");
- QTest::newRow( "6" ) << QString("ababABAB") << QChar('a') << QChar(' ')
- << int(Qt::CaseInsensitive) << QString(" b b B B");
- QTest::newRow( "7" ) << QString("ababABAB") << QChar() << QChar(' ')
- << int(Qt::CaseInsensitive) << QString("ababABAB");
-}
-
-void tst_QString::replace_qchar_qchar()
-{
- QFETCH(QString, src);
- QFETCH(QChar, before);
- QFETCH(QChar, after);
- QFETCH(int, cs);
- QFETCH(QString, expected);
-
- QCOMPARE(src.replace(before, after, Qt::CaseSensitivity(cs)), expected);
-}
-
-void tst_QString::replace_qchar_qstring_data()
-{
- QTest::addColumn<QString>("src" );
- QTest::addColumn<QChar>("before" );
- QTest::addColumn<QString>("after" );
- QTest::addColumn<int>("cs" );
- QTest::addColumn<QString>("expected" );
-
- QTest::newRow( "1" ) << QString("foo") << QChar('o') << QString("aA")
- << int(Qt::CaseSensitive) << QString("faAaA");
- QTest::newRow( "2" ) << QString("foo") << QChar('o') << QString("aA")
- << int(Qt::CaseInsensitive) << QString("faAaA");
- QTest::newRow( "3" ) << QString("foo") << QChar('O') << QString("aA")
- << int(Qt::CaseSensitive) << QString("foo");
- QTest::newRow( "4" ) << QString("foo") << QChar('O') << QString("aA")
- << int(Qt::CaseInsensitive) << QString("faAaA");
- QTest::newRow( "5" ) << QString("ababABAB") << QChar('a') << QString(" ")
- << int(Qt::CaseSensitive) << QString(" b bABAB");
- QTest::newRow( "6" ) << QString("ababABAB") << QChar('a') << QString(" ")
- << int(Qt::CaseInsensitive) << QString(" b b B B");
- QTest::newRow( "7" ) << QString("ababABAB") << QChar() << QString(" ")
- << int(Qt::CaseInsensitive) << QString("ababABAB");
- QTest::newRow( "8" ) << QString("ababABAB") << QChar() << QString()
- << int(Qt::CaseInsensitive) << QString("ababABAB");
-}
-
-void tst_QString::replace_qchar_qstring()
-{
- QFETCH(QString, src);
- QFETCH(QChar, before);
- QFETCH(QString, after);
- QFETCH(int, cs);
- QFETCH(QString, expected);
-
- QCOMPARE(src.replace(before, after, Qt::CaseSensitivity(cs)), expected);
-}
-
-void tst_QString::replace_uint_uint_data()
-{
- QTest::addColumn<QString>("string" );
- QTest::addColumn<int>("index" );
- QTest::addColumn<int>("len" );
- QTest::addColumn<QString>("after" );
- QTest::addColumn<QString>("result" );
-
- QTest::newRow( "rem00" ) << QString("-<>ABCABCABCABC>") << 0 << 3 << QString("") << QString("ABCABCABCABC>");
- QTest::newRow( "rem01" ) << QString("ABCABCABCABC>") << 1 << 4 << QString("") << QString("ACABCABC>");
- QTest::newRow( "rem04" ) << QString("ACABCABC>") << 8 << 4 << QString("") << QString("ACABCABC");
- QTest::newRow( "rem05" ) << QString("ACABCABC") << 7 << 1 << QString("") << QString("ACABCAB");
- QTest::newRow( "rem06" ) << QString("ACABCAB") << 4 << 0 << QString("") << QString("ACABCAB");
-
- QTest::newRow( "rep00" ) << QString("ACABCAB") << 4 << 0 << QString("X") << QString("ACABXCAB");
- QTest::newRow( "rep01" ) << QString("ACABXCAB") << 4 << 1 << QString("Y") << QString("ACABYCAB");
- QTest::newRow( "rep02" ) << QString("ACABYCAB") << 4 << 1 << QString("") << QString("ACABCAB");
- QTest::newRow( "rep03" ) << QString("ACABCAB") << 0 << 9999 << QString("XX") << QString("XX");
- QTest::newRow( "rep04" ) << QString("XX") << 0 << 9999 << QString("") << QString("");
- QTest::newRow( "rep05" ) << QString("ACABCAB") << 0 << 2 << QString("XX") << QString("XXABCAB");
- QTest::newRow( "rep06" ) << QString("ACABCAB") << 1 << 2 << QString("XX") << QString("AXXBCAB");
- QTest::newRow( "rep07" ) << QString("ACABCAB") << 2 << 2 << QString("XX") << QString("ACXXCAB");
- QTest::newRow( "rep08" ) << QString("ACABCAB") << 3 << 2 << QString("XX") << QString("ACAXXAB");
- QTest::newRow( "rep09" ) << QString("ACABCAB") << 4 << 2 << QString("XX") << QString("ACABXXB");
- QTest::newRow( "rep10" ) << QString("ACABCAB") << 5 << 2 << QString("XX") << QString("ACABCXX");
- QTest::newRow( "rep11" ) << QString("ACABCAB") << 6 << 2 << QString("XX") << QString("ACABCAXX");
- QTest::newRow( "rep12" ) << QString() << 0 << 10 << QString("X") << QString("X");
- QTest::newRow( "rep13" ) << QString("short") << 0 << 10 << QString("X") << QString("X");
- QTest::newRow( "rep14" ) << QString() << 0 << 10 << QString("XX") << QString("XX");
- QTest::newRow( "rep15" ) << QString("short") << 0 << 10 << QString("XX") << QString("XX");
-
- // This is a regression test for an old bug where QString would add index and len parameters,
- // potentially causing integer overflow.
- QTest::newRow( "no overflow" ) << QString("ACABCAB") << 1 << INT_MAX - 1 << QString("") << QString("A");
- QTest::newRow( "overflow" ) << QString("ACABCAB") << 1 << INT_MAX << QString("") << QString("A");
-}
-
-void tst_QString::replace_string_data()
-{
- QTest::addColumn<QString>("string" );
- QTest::addColumn<QString>("before" );
- QTest::addColumn<QString>("after" );
- QTest::addColumn<QString>("result" );
- QTest::addColumn<bool>("bcs" );
-
- QTest::newRow( "rem00" ) << QString("") << QString("") << QString("") << QString("") << true;
- QTest::newRow( "rem01" ) << QString("A") << QString("") << QString("") << QString("A") << true;
- QTest::newRow( "rem02" ) << QString("A") << QString("A") << QString("") << QString("") << true;
- QTest::newRow( "rem03" ) << QString("A") << QString("B") << QString("") << QString("A") << true;
- QTest::newRow( "rem04" ) << QString("AA") << QString("A") << QString("") << QString("") << true;
- QTest::newRow( "rem05" ) << QString("AB") << QString("A") << QString("") << QString("B") << true;
- QTest::newRow( "rem06" ) << QString("AB") << QString("B") << QString("") << QString("A") << true;
- QTest::newRow( "rem07" ) << QString("AB") << QString("C") << QString("") << QString("AB") << true;
- QTest::newRow( "rem08" ) << QString("ABA") << QString("A") << QString("") << QString("B") << true;
- QTest::newRow( "rem09" ) << QString("ABA") << QString("B") << QString("") << QString("AA") << true;
- QTest::newRow( "rem10" ) << QString("ABA") << QString("C") << QString("") << QString("ABA") << true;
- QTest::newRow( "rem11" ) << QString("banana") << QString("an") << QString("") << QString("ba") << true;
- QTest::newRow( "rem12" ) << QString("") << QString("A") << QString("") << QString("") << true;
- QTest::newRow( "rem13" ) << QString("") << QString("A") << QString() << QString("") << true;
- QTest::newRow( "rem14" ) << QString() << QString("A") << QString("") << QString() << true;
- QTest::newRow( "rem15" ) << QString() << QString("A") << QString() << QString() << true;
- QTest::newRow( "rem16" ) << QString() << QString("") << QString("") << QString("") << true;
- QTest::newRow( "rem17" ) << QString("") << QString() << QString("") << QString("") << true;
- QTest::newRow( "rem18" ) << QString("a") << QString("a") << QString("") << QString("") << false;
- QTest::newRow( "rem19" ) << QString("A") << QString("A") << QString("") << QString("") << false;
- QTest::newRow( "rem20" ) << QString("a") << QString("A") << QString("") << QString("") << false;
- QTest::newRow( "rem21" ) << QString("A") << QString("a") << QString("") << QString("") << false;
- QTest::newRow( "rem22" ) << QString("Alpha beta") << QString("a") << QString("") << QString("lph bet") << false;
-
- QTest::newRow( "rep00" ) << QString("ABC") << QString("B") << QString("-") << QString("A-C") << true;
- QTest::newRow( "rep01" ) << QString("$()*+.?[\\]^{|}") << QString("$()*+.?[\\]^{|}") << QString("X") << QString("X") << true;
- QTest::newRow( "rep02" ) << QString("ABCDEF") << QString("") << QString("X") << QString("XAXBXCXDXEXFX") << true;
- QTest::newRow( "rep03" ) << QString("") << QString("") << QString("X") << QString("X") << true;
- QTest::newRow( "rep04" ) << QString("a") << QString("a") << QString("b") << QString("b") << false;
- QTest::newRow( "rep05" ) << QString("A") << QString("A") << QString("b") << QString("b") << false;
- QTest::newRow( "rep06" ) << QString("a") << QString("A") << QString("b") << QString("b") << false;
- QTest::newRow( "rep07" ) << QString("A") << QString("a") << QString("b") << QString("b") << false;
- QTest::newRow( "rep08" ) << QString("a") << QString("a") << QString("a") << QString("a") << false;
- QTest::newRow( "rep09" ) << QString("A") << QString("A") << QString("a") << QString("a") << false;
- QTest::newRow( "rep10" ) << QString("a") << QString("A") << QString("a") << QString("a") << false;
- QTest::newRow( "rep11" ) << QString("A") << QString("a") << QString("a") << QString("a") << false;
- QTest::newRow( "rep12" ) << QString("Alpha beta") << QString("a") << QString("o") << QString("olpho beto") << false;
- QTest::newRow( "rep13" ) << QString() << QString("") << QString("A") << QString("A") << true;
- QTest::newRow( "rep14" ) << QString("") << QString() << QString("A") << QString("A") << true;
- QTest::newRow( "rep15" ) << QString("fooxbarxbazxblub") << QString("x") << QString("yz") << QString("fooyzbaryzbazyzblub") << true;
- QTest::newRow( "rep16" ) << QString("fooxbarxbazxblub") << QString("x") << QString("z") << QString("foozbarzbazzblub") << true;
- QTest::newRow( "rep17" ) << QString("fooxybarxybazxyblub") << QString("xy") << QString("z") << QString("foozbarzbazzblub") << true;
-}
-
-void tst_QString::replace_regexp_data()
-{
- QTest::addColumn<QString>("string" );
- QTest::addColumn<QString>("regexp" );
- QTest::addColumn<QString>("after" );
- QTest::addColumn<QString>("result" );
-
- QTest::newRow( "rem00" ) << QString("alpha") << QString("a+") << QString("") << QString("lph");
- QTest::newRow( "rem01" ) << QString("banana") << QString("^.a") << QString("") << QString("nana");
- QTest::newRow( "rem02" ) << QString("") << QString("^.a") << QString("") << QString("");
- QTest::newRow( "rem03" ) << QString("") << QString("^.a") << QString() << QString("");
- QTest::newRow( "rem04" ) << QString() << QString("^.a") << QString("") << QString();
- QTest::newRow( "rem05" ) << QString() << QString("^.a") << QString() << QString();
-
- QTest::newRow( "rep00" ) << QString("A <i>bon mot</i>.") << QString("<i>([^<]*)</i>") << QString("\\emph{\\1}") << QString("A \\emph{bon mot}.");
- QTest::newRow( "rep01" ) << QString("banana") << QString("^.a()") << QString("\\1") << QString("nana");
- QTest::newRow( "rep02" ) << QString("banana") << QString("(ba)") << QString("\\1X\\1") << QString("baXbanana");
- QTest::newRow( "rep03" ) << QString("banana") << QString("(ba)(na)na") << QString("\\2X\\1") << QString("naXba");
-
- QTest::newRow("backref00") << QString("\\1\\2\\3\\4\\5\\6\\7\\8\\9\\A\\10\\11") << QString("\\\\[34]")
- << QString("X") << QString("\\1\\2XX\\5\\6\\7\\8\\9\\A\\10\\11");
- QTest::newRow("backref01") << QString("foo") << QString("[fo]") << QString("\\1") << QString("\\1\\1\\1");
- QTest::newRow("backref02") << QString("foo") << QString("([fo])") << QString("(\\1)") << QString("(f)(o)(o)");
- QTest::newRow("backref03") << QString("foo") << QString("([fo])") << QString("\\2") << QString("\\2\\2\\2");
- QTest::newRow("backref04") << QString("foo") << QString("([fo])") << QString("\\10") << QString("f0o0o0");
- QTest::newRow("backref05") << QString("foo") << QString("([fo])") << QString("\\11") << QString("f1o1o1");
- QTest::newRow("backref06") << QString("foo") << QString("([fo])") << QString("\\19") << QString("f9o9o9");
- QTest::newRow("backref07") << QString("foo") << QString("(f)(o+)")
- << QString("\\2\\1\\10\\20\\11\\22\\19\\29\\3")
- << QString("ooff0oo0f1oo2f9oo9\\3");
- QTest::newRow("backref08") << QString("abc") << QString("(((((((((((((([abc]))))))))))))))")
- << QString("{\\14}") << QString("{a}{b}{c}");
- QTest::newRow("backref09") << QString("abcdefghijklmn")
- << QString("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)")
- << QString("\\19\\18\\17\\16\\15\\14\\13\\12\\11\\10"
- "\\9\\90\\8\\80\\7\\70\\6\\60\\5\\50\\4\\40\\3\\30\\2\\20\\1")
- << QString("a9a8a7a6a5nmlkjii0hh0gg0ff0ee0dd0cc0bb0a");
- QTest::newRow("backref10") << QString("abc") << QString("((((((((((((((abc))))))))))))))")
- << QString("\\0\\01\\011") << QString("\\0\\01\\011");
- QTest::newRow("invalid") << QString("") << QString("invalid regex\\") << QString("") << QString("");
-}
-
-void tst_QString::utf8_data()
-{
- QString str;
- QTest::addColumn<QByteArray>("utf8" );
- QTest::addColumn<QString>("res" );
-
- QTest::newRow( "str0" ) << QByteArray("abcdefgh")
- << QString("abcdefgh");
- QTest::newRow( "str1" ) << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
- << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") ;
- str += QChar( 0x05e9 );
- str += QChar( 0x05d3 );
- str += QChar( 0x05d2 );
- QTest::newRow( "str2" ) << QByteArray("\327\251\327\223\327\222")
- << str;
-
- str = QChar( 0x20ac );
- str += " some text";
- QTest::newRow( "str3" ) << QByteArray("\342\202\254 some text")
- << str;
-
- str = "Old Italic: ";
- str += QChar(0xd800);
- str += QChar(0xdf00);
- str += QChar(0xd800);
- str += QChar(0xdf01);
- str += QChar(0xd800);
- str += QChar(0xdf02);
- str += QChar(0xd800);
- str += QChar(0xdf03);
- str += QChar(0xd800);
- str += QChar(0xdf04);
- QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str;
-}
-
-void tst_QString::length()
-{
- QFETCH( QString, s1 );
- QTEST( (int)s1.length(), "res" );
-}
-
-#include <qfile.h>
-
-void tst_QString::acc_01()
-{
- QString a;
- QString b; //b(10);
- QString bb; //bb((int)0);
- QString c("String C");
- QChar tmp[10];
- tmp[0] = 'S';
- tmp[1] = 't';
- tmp[2] = 'r';
- tmp[3] = 'i';
- tmp[4] = 'n';
- tmp[5] = 'g';
- tmp[6] = ' ';
- tmp[7] = 'D';
- tmp[8] = 'X';
- tmp[9] = '\0';
- QString d(tmp,8);
- QString ca(a);
- QString cb(b);
- QString cc(c);
- QString n;
- QString e("String E");
- QString f;
- f = e;
- f[7]='F';
- QCOMPARE(e, QLatin1String("String E"));
- char text[]="String f";
- f = text;
- text[7]='!';
- QCOMPARE(f, QLatin1String("String f"));
- f[7]='F';
- QCOMPARE(text[7],'!');
-
- a="";
- a[0]='A';
- QCOMPARE(a, QLatin1String("A"));
- QCOMPARE(a.length(),1);
- a[1]='B';
- QCOMPARE(a, QLatin1String("AB"));
- QCOMPARE(a.length(),2);
- a[2]='C';
- QCOMPARE(a, QLatin1String("ABC"));
- QCOMPARE(a.length(),3);
- a = QString();
- QVERIFY(a.isNull());
- a[0]='A';
- QCOMPARE(a, QLatin1String("A"));
- QCOMPARE(a.length(),1);
- a[1]='B';
- QCOMPARE(a, QLatin1String("AB"));
- QCOMPARE(a.length(),2);
- a[2]='C';
- QCOMPARE(a, QLatin1String("ABC"));
- QCOMPARE(a.length(),3);
-
- a="123";
- b="456";
- a[0]=a[1];
- QCOMPARE(a, QLatin1String("223"));
- a[1]=b[1];
- QCOMPARE(b, QLatin1String("456"));
- QCOMPARE(a, QLatin1String("253"));
-
- char t[]="TEXT";
- a="A";
- a=t;
- QCOMPARE(a, QLatin1String("TEXT"));
- QCOMPARE(a,(QString)t);
- a[0]='X';
- QCOMPARE(a, QLatin1String("XEXT"));
- QCOMPARE(t[0],'T');
- t[0]='Z';
- QCOMPARE(a, QLatin1String("XEXT"));
-
- a="ABC";
- QCOMPARE(char(a.toLatin1()[1]),'B');
- QCOMPARE(strcmp(a.toLatin1(), QByteArrayLiteral("ABC")), 0);
- QCOMPARE(a+="DEF", QLatin1String("ABCDEF"));
- QCOMPARE(a+='G', QLatin1String("ABCDEFG"));
- QCOMPARE(a+=((const char*)(0)), QLatin1String("ABCDEFG"));
-
- // non-member operators
-
- a="ABC";
- b="ABC";
- c="ACB";
- d="ABCD";
- QVERIFY(a==b);
- QVERIFY(!(a==d));
- QVERIFY(!(a!=b));
- QVERIFY(a!=d);
- QVERIFY(!(a<b));
- QVERIFY(a<c);
- QVERIFY(a<d);
- QVERIFY(!(d<a));
- QVERIFY(!(c<a));
- QVERIFY(a<=b);
- QVERIFY(a<=d);
- QVERIFY(a<=c);
- QVERIFY(!(c<=a));
- QVERIFY(!(d<=a));
- QCOMPARE(QString(a+b), QLatin1String("ABCABC"));
- QCOMPARE(QString(a+"XXXX"), QLatin1String("ABCXXXX"));
- QCOMPARE(QString(a+'X'), QLatin1String("ABCX"));
- QCOMPARE(QString("XXXX"+a), QLatin1String("XXXXABC"));
- QCOMPARE(QString('X'+a), QLatin1String("XABC"));
- a = (const char*)0;
- QVERIFY(a.isNull());
- QVERIFY(*a.toLatin1().constData() == '\0');
- {
- QFile f("COMPARE.txt");
- f.open(QIODevice::ReadOnly);
- QTextStream ts( &f );
- ts.setCodec(QTextCodec::codecForName("UTF-16"));
- ts << "Abc";
- }
-}
-
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_GCC("-Wformat-security")
-QT_WARNING_DISABLE_CLANG("-Wformat-security")
-
-void tst_QString::isNull()
-{
- QString a;
- QVERIFY(a.isNull());
-
- const char *zero = 0;
- a.sprintf( zero );
- QVERIFY(!a.isNull());
-}
-
-QT_WARNING_POP
-
-void tst_QString::isEmpty()
-{
- QString a;
- QVERIFY(a.isEmpty());
- QString c("Not empty");
- QVERIFY(!c.isEmpty());
-}
-
-void tst_QString::constructor()
-{
- QString a;
- QString b; //b(10);
- QString c("String C");
- QChar tmp[10];
- tmp[0] = 'S';
- tmp[1] = 't';
- tmp[2] = 'r';
- tmp[3] = 'i';
- tmp[4] = 'n';
- tmp[5] = 'g';
- tmp[6] = ' ';
- tmp[7] = 'D';
- tmp[8] = 'X';
- tmp[9] = '\0';
- QString d(tmp,8);
- QString ca(a);
- QString cb(b);
- QString cc(c);
-
- QCOMPARE(a,ca);
- QVERIFY(a.isNull());
- QVERIFY(a == (QString)"");
- QCOMPARE(b,cb);
- QCOMPARE(c,cc);
- QCOMPARE(d, QLatin1String("String D"));
-
- QString nullStr;
- QVERIFY( nullStr.isNull() );
- QVERIFY( nullStr.isEmpty() );
- QString empty("");
- QVERIFY( !empty.isNull() );
- QVERIFY( empty.isEmpty() );
-}
-
-void tst_QString::constructorQByteArray_data()
-{
- QTest::addColumn<QByteArray>("src" );
- QTest::addColumn<QString>("expected" );
-
- QByteArray ba( 4, 0 );
- ba[0] = 'C';
- ba[1] = 'O';
- ba[2] = 'M';
- ba[3] = 'P';
-
- QTest::newRow( "1" ) << ba << QString("COMP");
-
- QByteArray ba1( 7, 0 );
- ba1[0] = 'a';
- ba1[1] = 'b';
- ba1[2] = 'c';
- ba1[3] = '\0';
- ba1[4] = 'd';
- ba1[5] = 'e';
- ba1[6] = 'f';
-
- QTest::newRow( "2" ) << ba1 << QString("abc");
-
- QTest::newRow( "3" ) << QByteArray::fromRawData("abcd", 3) << QString("abc");
- QTest::newRow( "4" ) << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
- QTest::newRow( "4-bis" ) << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
- QTest::newRow( "4-tre" ) << QByteArray("\xc3\xa9") << QString::fromLatin1("\xe9");
-}
-
-void tst_QString::constructorQByteArray()
-{
- QFETCH(QByteArray, src);
- QFETCH(QString, expected);
-
- QString str1(src);
- QCOMPARE(str1.length(), expected.length());
- QCOMPARE( str1, expected );
-
- QString strBA(src);
- QCOMPARE( strBA, expected );
-
- // test operator= too
- if (src.constData()[src.length()] == '\0') {
- str1.clear();
- str1 = src.constData();
- QCOMPARE( str1, expected );
- }
-
- strBA.clear();
- strBA = src;
- QCOMPARE( strBA, expected );
-}
-
-void tst_QString::STL()
-{
- std::string stdstr( "QString" );
-
- QString stlqt = QString::fromStdString(stdstr);
- QCOMPARE(stlqt, QString::fromLatin1(stdstr.c_str()));
- QCOMPARE(stlqt.toStdString(), stdstr);
-
- const wchar_t arr[] = {'h', 'e', 'l', 'l', 'o', 0};
- std::wstring stlStr = arr;
-
- QString s = QString::fromStdWString(stlStr);
-
- QCOMPARE(s, QString::fromLatin1("hello"));
- QCOMPARE(stlStr, s.toStdWString());
-}
-
-void tst_QString::macTypes()
-{
-#ifndef Q_OS_MAC
- QSKIP("This is a Mac-only test");
-#else
- extern void tst_QString_macTypes(); // in qcore_foundation.mm
- tst_QString_macTypes();
-#endif
-}
-
-void tst_QString::truncate()
-{
- QString e("String E");
- e.truncate(4);
- QCOMPARE(e, QLatin1String("Stri"));
-
- e = "String E";
- e.truncate(0);
- QCOMPARE(e, QLatin1String(""));
- QVERIFY(e.isEmpty());
- QVERIFY(!e.isNull());
-
-}
-
-void tst_QString::chop_data()
-{
- QTest::addColumn<QString>("input");
- QTest::addColumn<int>("count" );
- QTest::addColumn<QString>("result");
-
- const QString original("abcd");
-
- QTest::newRow("data0") << original << 1 << QString("abc");
- QTest::newRow("data1") << original << 0 << original;
- QTest::newRow("data2") << original << -1 << original;
- QTest::newRow("data3") << original << original.size() << QString();
- QTest::newRow("data4") << original << 1000 << QString();
-}
-
-void tst_QString::chop()
-{
- QFETCH(QString, input);
- QFETCH(int, count);
- QFETCH(QString, result);
-
- input.chop(count);
- QCOMPARE(input, result);
-}
-
-void tst_QString::fill()
-{
- QString e;
- e.fill('e',1);
- QCOMPARE(e, QLatin1String("e"));
- QString f;
- f.fill('f',3);
- QCOMPARE(f, QLatin1String("fff"));
- f.fill('F');
- QCOMPARE(f, QLatin1String("FFF"));
-}
-
-static inline const void *ptrValue(quintptr v)
-{
- return reinterpret_cast<const void *>(v);
-}
-
-void tst_QString::sprintf()
-{
- QString a;
- a.sprintf("COMPARE");
- QCOMPARE(a, QLatin1String("COMPARE"));
- a.sprintf("%%%d",1);
- QCOMPARE(a, QLatin1String("%1"));
- QCOMPARE(a.sprintf("X%dY",2), QLatin1String("X2Y"));
- QCOMPARE(a.sprintf("X%9iY", 50000 ), QLatin1String("X 50000Y"));
- QCOMPARE(a.sprintf("X%-9sY","hello"), QLatin1String("Xhello Y"));
- QCOMPARE(a.sprintf("X%-9iY", 50000 ), QLatin1String("X50000 Y"));
- QCOMPARE(a.sprintf("%lf", 1.23), QLatin1String("1.230000"));
- QCOMPARE(a.sprintf("%lf", 1.23456789), QLatin1String("1.234568"));
- QCOMPARE(a.sprintf("%p", ptrValue(0xbfffd350)), QLatin1String("0xbfffd350"));
- QCOMPARE(a.sprintf("%p", ptrValue(0)), QLatin1String("0x0"));
-
- int i = 6;
- long l = -2;
- float f = 4.023f;
- QString S1;
- S1.sprintf("%d %ld %f",i,l,f);
- QCOMPARE(S1, QLatin1String("6 -2 4.023000"));
-
- double d = -514.25683;
- S1.sprintf("%f",d);
- QCOMPARE(S1, QLatin1String("-514.256830"));
-}
-
-void tst_QString::sprintfS()
-{
- QString a;
- QCOMPARE(a.sprintf("%.3s", "Hello" ), QLatin1String("Hel"));
- QCOMPARE(a.sprintf("%10.3s", "Hello" ), QLatin1String(" Hel"));
- QCOMPARE(a.sprintf("%.10s", "Hello" ), QLatin1String("Hello"));
- QCOMPARE(a.sprintf("%10.10s", "Hello" ), QLatin1String(" Hello"));
- QCOMPARE(a.sprintf("%-10.10s", "Hello" ), QLatin1String("Hello "));
- QCOMPARE(a.sprintf("%-10.3s", "Hello" ), QLatin1String("Hel "));
- QCOMPARE(a.sprintf("%-5.5s", "Hello" ), QLatin1String("Hello"));
-
- // Check utf8 conversion for %s
- QCOMPARE(a.sprintf("%s", "\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205"), QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305"));
-
- int n1;
- a.sprintf("%s%n%s", "hello", &n1, "goodbye");
- QCOMPARE(n1, 5);
- QCOMPARE(a, QString("hellogoodbye"));
- qlonglong n2;
- a.sprintf("%s%s%lln%s", "foo", "bar", &n2, "whiz");
- QCOMPARE((int)n2, 6);
- QCOMPARE(a, QString("foobarwhiz"));
-
- { // %ls
- QCOMPARE(a.sprintf("%.3ls", qUtf16Printable("Hello")), QLatin1String("Hel"));
- QCOMPARE(a.sprintf("%10.3ls", qUtf16Printable("Hello")), QLatin1String(" Hel"));
- QCOMPARE(a.sprintf("%.10ls", qUtf16Printable("Hello")), QLatin1String("Hello"));
- QCOMPARE(a.sprintf("%10.10ls", qUtf16Printable("Hello")), QLatin1String(" Hello"));
- QCOMPARE(a.sprintf("%-10.10ls", qUtf16Printable("Hello")), QLatin1String("Hello "));
- QCOMPARE(a.sprintf("%-10.3ls", qUtf16Printable("Hello")), QLatin1String("Hel "));
- QCOMPARE(a.sprintf("%-5.5ls", qUtf16Printable("Hello")), QLatin1String("Hello"));
-
- // Check utf16 is preserved for %ls
- QCOMPARE(a.sprintf("%ls",
- qUtf16Printable("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")),
- QLatin1String("\366\344\374\326\304\334\370\346\345\330\306\305"));
-
- int n;
- a.sprintf("%ls%n%s", qUtf16Printable("hello"), &n, "goodbye");
- QCOMPARE(n, 5);
- QCOMPARE(a, QLatin1String("hellogoodbye"));
- }
-}
-
-/*
- indexOf() and indexOf02() test QString::indexOf(),
- QString::lastIndexOf(), and their QByteArray equivalents.
-
- lastIndexOf() tests QString::lastIndexOf() more in depth, but it
- should probably be rewritten to use a data table.
-*/
-
-void tst_QString::indexOf_data()
-{
- QTest::addColumn<QString>("haystack" );
- QTest::addColumn<QString>("needle" );
- QTest::addColumn<int>("startpos" );
- QTest::addColumn<bool>("bcs" );
- QTest::addColumn<int>("resultpos" );
-
- QTest::newRow( "data0" ) << QString("abc") << QString("a") << 0 << true << 0;
- QTest::newRow( "data1" ) << QString("abc") << QString("a") << 0 << false << 0;
- QTest::newRow( "data2" ) << QString("abc") << QString("A") << 0 << true << -1;
- QTest::newRow( "data3" ) << QString("abc") << QString("A") << 0 << false << 0;
- QTest::newRow( "data4" ) << QString("abc") << QString("a") << 1 << true << -1;
- QTest::newRow( "data5" ) << QString("abc") << QString("a") << 1 << false << -1;
- QTest::newRow( "data6" ) << QString("abc") << QString("A") << 1 << true << -1;
- QTest::newRow( "data7" ) << QString("abc") << QString("A") << 1 << false << -1;
- QTest::newRow( "data8" ) << QString("abc") << QString("b") << 0 << true << 1;
- QTest::newRow( "data9" ) << QString("abc") << QString("b") << 0 << false << 1;
- QTest::newRow( "data10" ) << QString("abc") << QString("B") << 0 << true << -1;
- QTest::newRow( "data11" ) << QString("abc") << QString("B") << 0 << false << 1;
- QTest::newRow( "data12" ) << QString("abc") << QString("b") << 1 << true << 1;
- QTest::newRow( "data13" ) << QString("abc") << QString("b") << 1 << false << 1;
- QTest::newRow( "data14" ) << QString("abc") << QString("B") << 1 << true << -1;
- QTest::newRow( "data15" ) << QString("abc") << QString("B") << 1 << false << 1;
- QTest::newRow( "data16" ) << QString("abc") << QString("b") << 2 << true << -1;
- QTest::newRow( "data17" ) << QString("abc") << QString("b") << 2 << false << -1;
-
- QTest::newRow( "data20" ) << QString("ABC") << QString("A") << 0 << true << 0;
- QTest::newRow( "data21" ) << QString("ABC") << QString("A") << 0 << false << 0;
- QTest::newRow( "data22" ) << QString("ABC") << QString("a") << 0 << true << -1;
- QTest::newRow( "data23" ) << QString("ABC") << QString("a") << 0 << false << 0;
- QTest::newRow( "data24" ) << QString("ABC") << QString("A") << 1 << true << -1;
- QTest::newRow( "data25" ) << QString("ABC") << QString("A") << 1 << false << -1;
- QTest::newRow( "data26" ) << QString("ABC") << QString("a") << 1 << true << -1;
- QTest::newRow( "data27" ) << QString("ABC") << QString("a") << 1 << false << -1;
- QTest::newRow( "data28" ) << QString("ABC") << QString("B") << 0 << true << 1;
- QTest::newRow( "data29" ) << QString("ABC") << QString("B") << 0 << false << 1;
- QTest::newRow( "data30" ) << QString("ABC") << QString("b") << 0 << true << -1;
- QTest::newRow( "data31" ) << QString("ABC") << QString("b") << 0 << false << 1;
- QTest::newRow( "data32" ) << QString("ABC") << QString("B") << 1 << true << 1;
- QTest::newRow( "data33" ) << QString("ABC") << QString("B") << 1 << false << 1;
- QTest::newRow( "data34" ) << QString("ABC") << QString("b") << 1 << true << -1;
- QTest::newRow( "data35" ) << QString("ABC") << QString("b") << 1 << false << 1;
- QTest::newRow( "data36" ) << QString("ABC") << QString("B") << 2 << true << -1;
- QTest::newRow( "data37" ) << QString("ABC") << QString("B") << 2 << false << -1;
-
- QTest::newRow( "data40" ) << QString("aBc") << QString("bc") << 0 << true << -1;
- QTest::newRow( "data41" ) << QString("aBc") << QString("Bc") << 0 << true << 1;
- QTest::newRow( "data42" ) << QString("aBc") << QString("bC") << 0 << true << -1;
- QTest::newRow( "data43" ) << QString("aBc") << QString("BC") << 0 << true << -1;
- QTest::newRow( "data44" ) << QString("aBc") << QString("bc") << 0 << false << 1;
- QTest::newRow( "data45" ) << QString("aBc") << QString("Bc") << 0 << false << 1;
- QTest::newRow( "data46" ) << QString("aBc") << QString("bC") << 0 << false << 1;
- QTest::newRow( "data47" ) << QString("aBc") << QString("BC") << 0 << false << 1;
- QTest::newRow( "data48" ) << QString("AbC") << QString("bc") << 0 << true << -1;
- QTest::newRow( "data49" ) << QString("AbC") << QString("Bc") << 0 << true << -1;
- QTest::newRow( "data50" ) << QString("AbC") << QString("bC") << 0 << true << 1;
- QTest::newRow( "data51" ) << QString("AbC") << QString("BC") << 0 << true << -1;
- QTest::newRow( "data52" ) << QString("AbC") << QString("bc") << 0 << false << 1;
- QTest::newRow( "data53" ) << QString("AbC") << QString("Bc") << 0 << false << 1;
-
- QTest::newRow( "data54" ) << QString("AbC") << QString("bC") << 0 << false << 1;
- QTest::newRow( "data55" ) << QString("AbC") << QString("BC") << 0 << false << 1;
- QTest::newRow( "data56" ) << QString("AbC") << QString("BC") << 1 << false << 1;
- QTest::newRow( "data57" ) << QString("AbC") << QString("BC") << 2 << false << -1;
-#if 0
- QTest::newRow( "null-in-null") << QString() << QString() << 0 << false << 0;
- QTest::newRow( "empty-in-null") << QString() << QString("") << 0 << false << 0;
- QTest::newRow( "null-in-empty") << QString("") << QString() << 0 << false << 0;
- QTest::newRow( "empty-in-empty") << QString("") << QString("") << 0 << false << 0;
-#endif
-
-
- QString s1 = "abc";
- s1 += QChar(0xb5);
- QString s2;
- s2 += QChar(0x3bc);
- QTest::newRow( "data58" ) << s1 << s2 << 0 << false << 3;
- s2.prepend(QLatin1Char('C'));
- QTest::newRow( "data59" ) << s1 << s2 << 0 << false << 2;
-
- QString veryBigHaystack(500, 'a');
- veryBigHaystack += 'B';
- QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0;
- QTest::newRow("BoyerMooreStressTest2") << QString(veryBigHaystack + 'c') << veryBigHaystack << 0 << true << 0;
- QTest::newRow("BoyerMooreStressTest3") << QString('c' + veryBigHaystack) << veryBigHaystack << 0 << true << 1;
- QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << QString(veryBigHaystack + 'c') << 0 << true << -1;
- QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << QString('c' + veryBigHaystack) << 0 << true << -1;
- QTest::newRow("BoyerMooreStressTest6") << QString('d' + veryBigHaystack) << QString('c' + veryBigHaystack) << 0 << true << -1;
- QTest::newRow("BoyerMooreStressTest7") << QString(veryBigHaystack + 'c') << QString('c' + veryBigHaystack) << 0 << true << -1;
-
- QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0;
-
-}
-
-void tst_QString::indexOf()
-{
- QFETCH( QString, haystack );
- QFETCH( QString, needle );
- QFETCH( int, startpos );
- QFETCH( bool, bcs );
- QFETCH( int, resultpos );
- CREATE_REF(needle);
-
- Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
-
- bool needleIsLatin = (QString::fromLatin1(needle.toLatin1()) == needle);
-
- QCOMPARE( haystack.indexOf(needle, startpos, cs), resultpos );
- QCOMPARE( haystack.indexOf(ref, startpos, cs), resultpos );
- if (needleIsLatin) {
- QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos, cs), resultpos );
- QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos, cs), resultpos );
- }
-
- {
- QRegExp rx1 = QRegExp(QRegExp::escape(needle), cs);
- QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
- QCOMPARE( haystack.indexOf(rx1, startpos), resultpos );
- QCOMPARE( haystack.indexOf(rx2, startpos), resultpos );
- // these QRegExp must have been modified
- QVERIFY( resultpos == -1 || rx1.matchedLength() > 0);
- QVERIFY( resultpos == -1 || rx2.matchedLength() > 0);
- }
-
- {
- const QRegExp rx1 = QRegExp(QRegExp::escape(needle), cs);
- const QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
- QCOMPARE( haystack.indexOf(rx1, startpos), resultpos );
- QCOMPARE( haystack.indexOf(rx2, startpos), resultpos );
- // our QRegExp mustn't have been modified
- QCOMPARE( rx1.matchedLength(), -1 );
- QCOMPARE( rx2.matchedLength(), -1 );
- }
-
- {
- QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
- if (!bcs)
- options |= QRegularExpression::CaseInsensitiveOption;
-
- QRegularExpression re(QRegularExpression::escape(needle), options);
- QCOMPARE( haystack.indexOf(re, startpos), resultpos );
- QCOMPARE(haystack.indexOf(re, startpos, nullptr), resultpos);
-
- QRegularExpressionMatch match;
- QVERIFY(!match.hasMatch());
- QCOMPARE(haystack.indexOf(re, startpos, &match), resultpos);
- QCOMPARE(match.hasMatch(), resultpos != -1);
- if (resultpos > -1 && needleIsLatin) {
- if (bcs)
- QVERIFY(match.captured() == needle);
- else
- QVERIFY(match.captured().toLower() == needle.toLower());
- }
- }
-
- if (cs == Qt::CaseSensitive) {
- QCOMPARE( haystack.indexOf(needle, startpos), resultpos );
- QCOMPARE( haystack.indexOf(ref, startpos), resultpos );
- if (needleIsLatin) {
- QCOMPARE( haystack.indexOf(needle.toLatin1(), startpos), resultpos );
- QCOMPARE( haystack.indexOf(needle.toLatin1().data(), startpos), resultpos );
- }
- if (startpos == 0) {
- QCOMPARE( haystack.indexOf(needle), resultpos );
- QCOMPARE( haystack.indexOf(ref), resultpos );
- if (needleIsLatin) {
- QCOMPARE( haystack.indexOf(needle.toLatin1()), resultpos );
- QCOMPARE( haystack.indexOf(needle.toLatin1().data()), resultpos );
- }
- }
- }
- if (needle.size() == 1) {
- QCOMPARE(haystack.indexOf(needle.at(0), startpos, cs), resultpos);
- QCOMPARE(haystack.indexOf(ref.at(0), startpos, cs), resultpos);
- }
-
-}
-
-void tst_QString::indexOf2_data()
-{
- QTest::addColumn<QString>("haystack" );
- QTest::addColumn<QString>("needle" );
- QTest::addColumn<int>("resultpos" );
-
- QTest::newRow( "data0" ) << QString() << QString() << 0;
- QTest::newRow( "data1" ) << QString() << QString("") << 0;
- QTest::newRow( "data2" ) << QString("") << QString() << 0;
- QTest::newRow( "data3" ) << QString("") << QString("") << 0;
- QTest::newRow( "data4" ) << QString() << QString("a") << -1;
- QTest::newRow( "data5" ) << QString() << QString("abcdefg") << -1;
- QTest::newRow( "data6" ) << QString("") << QString("a") << -1;
- QTest::newRow( "data7" ) << QString("") << QString("abcdefg") << -1;
-
- QTest::newRow( "data8" ) << QString("a") << QString() << 0;
- QTest::newRow( "data9" ) << QString("a") << QString("") << 0;
- QTest::newRow( "data10" ) << QString("a") << QString("a") << 0;
- QTest::newRow( "data11" ) << QString("a") << QString("b") << -1;
- QTest::newRow( "data12" ) << QString("a") << QString("abcdefg") << -1;
- QTest::newRow( "data13" ) << QString("ab") << QString() << 0;
- QTest::newRow( "data14" ) << QString("ab") << QString("") << 0;
- QTest::newRow( "data15" ) << QString("ab") << QString("a") << 0;
- QTest::newRow( "data16" ) << QString("ab") << QString("b") << 1;
- QTest::newRow( "data17" ) << QString("ab") << QString("ab") << 0;
- QTest::newRow( "data18" ) << QString("ab") << QString("bc") << -1;
- QTest::newRow( "data19" ) << QString("ab") << QString("abcdefg") << -1;
-
- QTest::newRow( "data30" ) << QString("abc") << QString("a") << 0;
- QTest::newRow( "data31" ) << QString("abc") << QString("b") << 1;
- QTest::newRow( "data32" ) << QString("abc") << QString("c") << 2;
- QTest::newRow( "data33" ) << QString("abc") << QString("d") << -1;
- QTest::newRow( "data34" ) << QString("abc") << QString("ab") << 0;
- QTest::newRow( "data35" ) << QString("abc") << QString("bc") << 1;
- QTest::newRow( "data36" ) << QString("abc") << QString("cd") << -1;
- QTest::newRow( "data37" ) << QString("abc") << QString("ac") << -1;
-
- // sizeof(whale) > 32
- QString whale = "a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn";
- QString minnow = "zby";
- QTest::newRow( "data40" ) << whale << minnow << 2;
- QTest::newRow( "data41" ) << QString(whale + whale) << minnow << 2;
- QTest::newRow( "data42" ) << QString(minnow + whale) << minnow << 0;
- QTest::newRow( "data43" ) << whale << whale << 0;
- QTest::newRow( "data44" ) << QString(whale + whale) << whale << 0;
- QTest::newRow( "data45" ) << whale << QString(whale + whale) << -1;
- QTest::newRow( "data46" ) << QString(whale + whale) << QString(whale + whale) << 0;
- QTest::newRow( "data47" ) << QString(whale + whale) << QString(whale + minnow) << -1;
- QTest::newRow( "data48" ) << QString(minnow + whale) << whale << (int)minnow.length();
-}
-
-void tst_QString::indexOf2()
-{
- QFETCH( QString, haystack );
- QFETCH( QString, needle );
- QFETCH( int, resultpos );
- CREATE_REF(needle);
-
- QByteArray chaystack = haystack.toLatin1();
- QByteArray cneedle = needle.toLatin1();
- int got;
-
- QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseSensitive), resultpos );
- QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseSensitive), resultpos );
- QCOMPARE( QStringMatcher(needle, Qt::CaseSensitive).indexIn(haystack, 0), resultpos );
- QCOMPARE( haystack.indexOf(needle, 0, Qt::CaseInsensitive), resultpos );
- QCOMPARE( haystack.indexOf(ref, 0, Qt::CaseInsensitive), resultpos );
- QCOMPARE( QStringMatcher(needle, Qt::CaseInsensitive).indexIn(haystack, 0), resultpos );
- if ( needle.length() > 0 ) {
- got = haystack.lastIndexOf( needle, -1, Qt::CaseSensitive );
- QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
- got = haystack.lastIndexOf( needle, -1, Qt::CaseInsensitive );
- QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
- }
-
- QCOMPARE( chaystack.indexOf(cneedle, 0), resultpos );
- QCOMPARE( QByteArrayMatcher(cneedle).indexIn(chaystack, 0), resultpos );
- if ( cneedle.length() > 0 ) {
- got = chaystack.lastIndexOf(cneedle, -1);
- QVERIFY( got == resultpos || (resultpos >= 0 && got >= resultpos) );
- }
-}
-
-void tst_QString::indexOfInvalidRegex()
-{
- QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object");
- QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\")), -1);
- QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object");
- QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, nullptr), -1);
-
- QRegularExpressionMatch match;
- QVERIFY(!match.hasMatch());
- QTest::ignoreMessage(QtWarningMsg, "QString::indexOf: invalid QRegularExpression object");
- QCOMPARE(QString("invalid regex\\").indexOf(QRegularExpression("invalid regex\\"), -1, &match), -1);
- QVERIFY(!match.hasMatch());
-}
-
-void tst_QString::lastIndexOf_data()
-{
- QTest::addColumn<QString>("haystack" );
- QTest::addColumn<QString>("needle" );
- QTest::addColumn<int>("from" );
- QTest::addColumn<int>("expected" );
- QTest::addColumn<bool>("caseSensitive" );
-
- QString a = "ABCDEFGHIEfGEFG";
-
- QTest::newRow("-1") << a << "G" << a.size() - 1 << 14 << true;
- QTest::newRow("1") << a << "G" << - 1 << 14 << true;
- QTest::newRow("2") << a << "G" << -3 << 11 << true;
- QTest::newRow("3") << a << "G" << -5 << 6 << true;
- QTest::newRow("4") << a << "G" << 14 << 14 << true;
- QTest::newRow("5") << a << "G" << 13 << 11 << true;
- QTest::newRow("6") << a << "B" << a.size() - 1 << 1 << true;
- QTest::newRow("7") << a << "B" << - 1 << 1 << true;
- QTest::newRow("8") << a << "B" << 1 << 1 << true;
- QTest::newRow("9") << a << "B" << 0 << -1 << true;
-
- QTest::newRow("10") << a << "G" << -1 << a.size()-1 << true;
- QTest::newRow("11") << a << "G" << a.size()-1 << a.size()-1 << true;
- QTest::newRow("12") << a << "G" << a.size() << -1 << true;
- QTest::newRow("13") << a << "A" << 0 << 0 << true;
- QTest::newRow("14") << a << "A" << -1*a.size() << 0 << true;
-
- QTest::newRow("15") << a << "efg" << 0 << -1 << false;
- QTest::newRow("16") << a << "efg" << a.size() << -1 << false;
- QTest::newRow("17") << a << "efg" << -1 * a.size() << -1 << false;
- QTest::newRow("19") << a << "efg" << a.size() - 1 << 12 << false;
- QTest::newRow("20") << a << "efg" << 12 << 12 << false;
- QTest::newRow("21") << a << "efg" << -12 << -1 << false;
- QTest::newRow("22") << a << "efg" << 11 << 9 << false;
-
- QTest::newRow("24") << "" << "asdf" << -1 << -1 << false;
- QTest::newRow("25") << "asd" << "asdf" << -1 << -1 << false;
- QTest::newRow("26") << "" << QString() << -1 << -1 << false;
-
- QTest::newRow("27") << a << "" << a.size() << a.size() << false;
- QTest::newRow("28") << a << "" << a.size() + 10 << -1 << false;
-}
-
-void tst_QString::lastIndexOf()
-{
- QFETCH(QString, haystack);
- QFETCH(QString, needle);
- QFETCH(int, from);
- QFETCH(int, expected);
- QFETCH(bool, caseSensitive);
- CREATE_REF(needle);
-
- Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
-
- QCOMPARE(haystack.lastIndexOf(needle, from, cs), expected);
- QCOMPARE(haystack.lastIndexOf(ref, from, cs), expected);
- QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from, cs), expected);
- QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from, cs), expected);
-
- if (from >= -1 && from < haystack.size()) {
- // unfortunately, QString and QRegExp don't have the same out of bound semantics
- // I think QString is wrong -- See file log for contact information.
- {
- QRegExp rx1 = QRegExp(QRegExp::escape(needle), cs);
- QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
- QCOMPARE(haystack.lastIndexOf(rx1, from), expected);
- QCOMPARE(haystack.lastIndexOf(rx2, from), expected);
- // our QRegExp mustn't have been modified
- QVERIFY(expected == -1 || rx1.matchedLength() > 0);
- QVERIFY(expected == -1 || rx2.matchedLength() > 0);
- }
-
- {
- const QRegExp rx1 = QRegExp(QRegExp::escape(needle), cs);
- const QRegExp rx2 = QRegExp(needle, cs, QRegExp::FixedString);
- QCOMPARE(haystack.lastIndexOf(rx1, from), expected);
- QCOMPARE(haystack.lastIndexOf(rx2, from), expected);
- // our QRegExp mustn't have been modified
- QCOMPARE(rx1.matchedLength(), -1);
- QCOMPARE(rx2.matchedLength(), -1);
- }
-
- {
- QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption;
- if (!caseSensitive)
- options |= QRegularExpression::CaseInsensitiveOption;
-
- QRegularExpression re(QRegularExpression::escape(needle), options);
- QCOMPARE(haystack.lastIndexOf(re, from), expected);
- QCOMPARE(haystack.lastIndexOf(re, from, nullptr), expected);
- QRegularExpressionMatch match;
- QVERIFY(!match.hasMatch());
- QCOMPARE(haystack.lastIndexOf(re, from, &match), expected);
- QCOMPARE(match.hasMatch(), expected > -1);
- if (expected > -1) {
- if (caseSensitive)
- QCOMPARE(match.captured(), needle);
- else
- QCOMPARE(match.captured().toLower(), needle.toLower());
- }
- }
- }
-
- if (cs == Qt::CaseSensitive) {
- QCOMPARE(haystack.lastIndexOf(needle, from), expected);
- QCOMPARE(haystack.lastIndexOf(ref, from), expected);
- QCOMPARE(haystack.lastIndexOf(needle.toLatin1(), from), expected);
- QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data(), from), expected);
- if (from == -1) {
- QCOMPARE(haystack.lastIndexOf(needle), expected);
- QCOMPARE(haystack.lastIndexOf(ref), expected);
- QCOMPARE(haystack.lastIndexOf(needle.toLatin1()), expected);
- QCOMPARE(haystack.lastIndexOf(needle.toLatin1().data()), expected);
- }
- }
- if (needle.size() == 1) {
- QCOMPARE(haystack.lastIndexOf(needle.at(0), from), expected);
- QCOMPARE(haystack.lastIndexOf(ref.at(0), from), expected);
- }
-}
-
-void tst_QString::lastIndexOfInvalidRegex()
-{
- QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object");
- QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), 0), -1);
- QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object");
- QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, nullptr), -1);
-
- QRegularExpressionMatch match;
- QVERIFY(!match.hasMatch());
- QTest::ignoreMessage(QtWarningMsg, "QString::lastIndexOf: invalid QRegularExpression object");
- QCOMPARE(QString("invalid regex\\").lastIndexOf(QRegularExpression("invalid regex\\"), -1, &match), -1);
- QVERIFY(!match.hasMatch());
-}
-
-void tst_QString::count()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
- QCOMPARE(a.count('A'),1);
- QCOMPARE(a.count('Z'),0);
- QCOMPARE(a.count('E'),3);
- QCOMPARE(a.count('F'),2);
- QCOMPARE(a.count('F',Qt::CaseInsensitive),3);
- QCOMPARE(a.count("FG"),2);
- QCOMPARE(a.count("FG",Qt::CaseInsensitive),3);
- QCOMPARE(a.count( QString(), Qt::CaseInsensitive), 16);
- QCOMPARE(a.count( "", Qt::CaseInsensitive), 16);
- QCOMPARE(a.count(QRegExp("[FG][HI]")),1);
- QCOMPARE(a.count(QRegExp("[G][HE]")),2);
- QCOMPARE(a.count(QRegularExpression("[FG][HI]")), 1);
- QCOMPARE(a.count(QRegularExpression("[G][HE]")), 2);
- QTest::ignoreMessage(QtWarningMsg, "QString::count: invalid QRegularExpression object");
- QCOMPARE(a.count(QRegularExpression("invalid regex\\")), 0);
-
- CREATE_REF(QLatin1String("FG"));
- QCOMPARE(a.count(ref),2);
- QCOMPARE(a.count(ref,Qt::CaseInsensitive),3);
- QCOMPARE(a.count( QStringRef(), Qt::CaseInsensitive), 16);
- QStringRef emptyRef(&a, 0, 0);
- QCOMPARE(a.count( emptyRef, Qt::CaseInsensitive), 16);
-
-}
-
-void tst_QString::contains()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
- QVERIFY(a.contains('A'));
- QVERIFY(!a.contains('Z'));
- QVERIFY(a.contains('E'));
- QVERIFY(a.contains('F'));
- QVERIFY(a.contains('F',Qt::CaseInsensitive));
- QVERIFY(a.contains("FG"));
- QVERIFY(a.contains("FG",Qt::CaseInsensitive));
- QVERIFY(a.contains(QLatin1String("FG")));
- QVERIFY(a.contains(QLatin1String("fg"),Qt::CaseInsensitive));
- QVERIFY(a.contains( QString(), Qt::CaseInsensitive));
- QVERIFY(a.contains( "", Qt::CaseInsensitive));
- QVERIFY(a.contains(QRegExp("[FG][HI]")));
- QVERIFY(a.contains(QRegExp("[G][HE]")));
- QVERIFY(a.contains(QRegularExpression("[FG][HI]")));
- QVERIFY(a.contains(QRegularExpression("[G][HE]")));
-
- {
- QRegularExpressionMatch match;
- QVERIFY(!match.hasMatch());
-
- QVERIFY(a.contains(QRegularExpression("[FG][HI]"), &match));
- QVERIFY(match.hasMatch());
- QCOMPARE(match.capturedStart(), 6);
- QCOMPARE(match.capturedEnd(), 8);
- QCOMPARE(match.captured(), QStringLiteral("GH"));
-
- QVERIFY(a.contains(QRegularExpression("[G][HE]"), &match));
- QVERIFY(match.hasMatch());
- QCOMPARE(match.capturedStart(), 6);
- QCOMPARE(match.capturedEnd(), 8);
- QCOMPARE(match.captured(), QStringLiteral("GH"));
-
- QVERIFY(a.contains(QRegularExpression("[f](.*)[FG]"), &match));
- QVERIFY(match.hasMatch());
- QCOMPARE(match.capturedStart(), 10);
- QCOMPARE(match.capturedEnd(), 15);
- QCOMPARE(match.captured(), QString("fGEFG"));
- QCOMPARE(match.capturedStart(1), 11);
- QCOMPARE(match.capturedEnd(1), 14);
- QCOMPARE(match.captured(1), QStringLiteral("GEF"));
-
- QVERIFY(a.contains(QRegularExpression("[f](.*)[F]"), &match));
- QVERIFY(match.hasMatch());
- QCOMPARE(match.capturedStart(), 10);
- QCOMPARE(match.capturedEnd(), 14);
- QCOMPARE(match.captured(), QString("fGEF"));
- QCOMPARE(match.capturedStart(1), 11);
- QCOMPARE(match.capturedEnd(1), 13);
- QCOMPARE(match.captured(1), QStringLiteral("GE"));
-
- QVERIFY(!a.contains(QRegularExpression("ZZZ"), &match));
- // doesn't match, but ensure match didn't change
- QVERIFY(match.hasMatch());
- QCOMPARE(match.capturedStart(), 10);
- QCOMPARE(match.capturedEnd(), 14);
- QCOMPARE(match.captured(), QStringLiteral("fGEF"));
- QCOMPARE(match.capturedStart(1), 11);
- QCOMPARE(match.capturedEnd(1), 13);
- QCOMPARE(match.captured(1), QStringLiteral("GE"));
-
- // don't crash with a null pointer
- QVERIFY(a.contains(QRegularExpression("[FG][HI]"), 0));
- QVERIFY(!a.contains(QRegularExpression("ZZZ"), 0));
- }
-
- CREATE_REF(QLatin1String("FG"));
- QVERIFY(a.contains(ref));
- QVERIFY(a.contains(ref, Qt::CaseInsensitive));
- QVERIFY(a.contains( QStringRef(), Qt::CaseInsensitive));
- QStringRef emptyRef(&a, 0, 0);
- QVERIFY(a.contains(emptyRef, Qt::CaseInsensitive));
-
- QTest::ignoreMessage(QtWarningMsg, "QString::contains: invalid QRegularExpression object");
- QVERIFY(!a.contains(QRegularExpression("invalid regex\\")));
-}
-
-
-void tst_QString::left()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
- QCOMPARE(a.left(3), QLatin1String("ABC"));
- QVERIFY(!a.left(0).isNull());
- QCOMPARE(a.left(0), QLatin1String(""));
-
- QString n;
- QVERIFY(n.left(3).isNull());
- QVERIFY(n.left(0).isNull());
- QVERIFY(n.left(0).isNull());
-
- QString l = "Left";
- QCOMPARE(l.left(-1), l);
- QCOMPARE(l.left(100), l);
-}
-
-void tst_QString::leftRef()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
- QCOMPARE(a.leftRef(3).toString(), QLatin1String("ABC"));
-
- QVERIFY(a.leftRef(0).toString().isEmpty());
- QCOMPARE(a.leftRef(0).toString(), QLatin1String(""));
-
- QString n;
- QVERIFY(n.leftRef(3).toString().isEmpty());
- QVERIFY(n.leftRef(0).toString().isEmpty());
- QVERIFY(n.leftRef(0).toString().isEmpty());
-
- QString l = "Left";
- QCOMPARE(l.leftRef(-1).toString(), l);
- QCOMPARE(l.leftRef(100).toString(), l);
-}
-
-void tst_QString::right()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
- QCOMPARE(a.right(3), QLatin1String("EFG"));
- QCOMPARE(a.right(0), QLatin1String(""));
-
- QString n;
- QVERIFY(n.right(3).isNull());
- QVERIFY(n.right(0).isNull());
-
- QString r = "Right";
- QCOMPARE(r.right(-1), r);
- QCOMPARE(r.right(100), r);
-}
-
-void tst_QString::rightRef()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
- QCOMPARE(a.rightRef(3).toString(), QLatin1String("EFG"));
- QCOMPARE(a.rightRef(0).toString(), QLatin1String(""));
-
- QString n;
- QVERIFY(n.rightRef(3).toString().isEmpty());
- QVERIFY(n.rightRef(0).toString().isEmpty());
-
- QString r = "Right";
- QCOMPARE(r.rightRef(-1).toString(), r);
- QCOMPARE(r.rightRef(100).toString(), r);
-}
-
-void tst_QString::mid()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
-
- QCOMPARE(a.mid(3,3), QLatin1String("DEF"));
- QCOMPARE(a.mid(0,0), QLatin1String(""));
- QVERIFY(!a.mid(15,0).isNull());
- QVERIFY(a.mid(15,0).isEmpty());
- QVERIFY(!a.mid(15,1).isNull());
- QVERIFY(a.mid(15,1).isEmpty());
- QVERIFY(a.mid(9999).isNull());
- QVERIFY(a.mid(9999,1).isNull());
-
- QCOMPARE(a.mid(-1, 6), a.mid(0, 5));
- QVERIFY(a.mid(-100, 6).isEmpty());
- QVERIFY(a.mid(INT_MIN, 0).isEmpty());
- QCOMPARE(a.mid(INT_MIN, -1), a);
- QVERIFY(a.mid(INT_MIN, INT_MAX).isNull());
- QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty());
- QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1));
- QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a);
- QVERIFY(a.mid(INT_MAX).isNull());
- QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
- QCOMPARE(a.mid(-5, INT_MAX), a);
- QCOMPARE(a.mid(-1, INT_MAX), a);
- QCOMPARE(a.mid(0, INT_MAX), a);
- QCOMPARE(a.mid(1, INT_MAX), QString("BCDEFGHIEfGEFG"));
- QCOMPARE(a.mid(5, INT_MAX), QString("FGHIEfGEFG"));
- QVERIFY(a.mid(20, INT_MAX).isNull());
- QCOMPARE(a.mid(-1, -1), a);
-
- QString n;
- QVERIFY(n.mid(3,3).isNull());
- QVERIFY(n.mid(0,0).isNull());
- QVERIFY(n.mid(9999,0).isNull());
- QVERIFY(n.mid(9999,1).isNull());
-
- QVERIFY(n.mid(-1, 6).isNull());
- QVERIFY(n.mid(-100, 6).isNull());
- QVERIFY(n.mid(INT_MIN, 0).isNull());
- QVERIFY(n.mid(INT_MIN, -1).isNull());
- QVERIFY(n.mid(INT_MIN, INT_MAX).isNull());
- QVERIFY(n.mid(INT_MIN + 1, INT_MAX).isNull());
- QVERIFY(n.mid(INT_MIN + 2, INT_MAX).isNull());
- QVERIFY(n.mid(INT_MIN + n.size() + 1, INT_MAX).isNull());
- QVERIFY(n.mid(INT_MAX).isNull());
- QVERIFY(n.mid(INT_MAX, INT_MAX).isNull());
- QVERIFY(n.mid(-5, INT_MAX).isNull());
- QVERIFY(n.mid(-1, INT_MAX).isNull());
- QVERIFY(n.mid(0, INT_MAX).isNull());
- QVERIFY(n.mid(1, INT_MAX).isNull());
- QVERIFY(n.mid(5, INT_MAX).isNull());
- QVERIFY(n.mid(20, INT_MAX).isNull());
- QVERIFY(n.mid(-1, -1).isNull());
-
- QString x = "Nine pineapples";
- QCOMPARE(x.mid(5, 4), QString("pine"));
- QCOMPARE(x.mid(5), QString("pineapples"));
-
- QCOMPARE(x.mid(-1, 6), x.mid(0, 5));
- QVERIFY(x.mid(-100, 6).isEmpty());
- QVERIFY(x.mid(INT_MIN, 0).isEmpty());
- QCOMPARE(x.mid(INT_MIN, -1), x);
- QVERIFY(x.mid(INT_MIN, INT_MAX).isNull());
- QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty());
- QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1));
- QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX), x);
- QVERIFY(x.mid(INT_MAX).isNull());
- QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
- QCOMPARE(x.mid(-5, INT_MAX), x);
- QCOMPARE(x.mid(-1, INT_MAX), x);
- QCOMPARE(x.mid(0, INT_MAX), x);
- QCOMPARE(x.mid(1, INT_MAX), QString("ine pineapples"));
- QCOMPARE(x.mid(5, INT_MAX), QString("pineapples"));
- QVERIFY(x.mid(20, INT_MAX).isNull());
- QCOMPARE(x.mid(-1, -1), x);
-}
-
-void tst_QString::midRef()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
-
- QCOMPARE(a.midRef(3,3).toString(), QLatin1String("DEF"));
- QCOMPARE(a.midRef(0,0).toString(), QLatin1String(""));
- QVERIFY(!a.midRef(15,0).toString().isNull());
- QVERIFY(a.midRef(15,0).toString().isEmpty());
- QVERIFY(!a.midRef(15,1).toString().isNull());
- QVERIFY(a.midRef(15,1).toString().isEmpty());
- QVERIFY(a.midRef(9999).toString().isEmpty());
- QVERIFY(a.midRef(9999,1).toString().isEmpty());
-
- QCOMPARE(a.midRef(-1, 6), a.midRef(0, 5));
- QVERIFY(a.midRef(-100, 6).isEmpty());
- QVERIFY(a.midRef(INT_MIN, 0).isEmpty());
- QCOMPARE(a.midRef(INT_MIN, -1).toString(), a);
- QVERIFY(a.midRef(INT_MIN, INT_MAX).isNull());
- QVERIFY(a.midRef(INT_MIN + 1, INT_MAX).isEmpty());
- QCOMPARE(a.midRef(INT_MIN + 2, INT_MAX), a.leftRef(1));
- QCOMPARE(a.midRef(INT_MIN + a.size() + 1, INT_MAX).toString(), a);
- QVERIFY(a.midRef(INT_MAX).isNull());
- QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull());
- QCOMPARE(a.midRef(-5, INT_MAX).toString(), a);
- QCOMPARE(a.midRef(-1, INT_MAX).toString(), a);
- QCOMPARE(a.midRef(0, INT_MAX).toString(), a);
- QCOMPARE(a.midRef(1, INT_MAX).toString(), QString("BCDEFGHIEfGEFG"));
- QCOMPARE(a.midRef(5, INT_MAX).toString(), QString("FGHIEfGEFG"));
- QVERIFY(a.midRef(20, INT_MAX).isNull());
- QCOMPARE(a.midRef(-1, -1).toString(), a);
-
- QString n;
- QVERIFY(n.midRef(3,3).toString().isEmpty());
- QVERIFY(n.midRef(0,0).toString().isEmpty());
- QVERIFY(n.midRef(9999,0).toString().isEmpty());
- QVERIFY(n.midRef(9999,1).toString().isEmpty());
-
- QVERIFY(n.midRef(-1, 6).isNull());
- QVERIFY(n.midRef(-100, 6).isNull());
- QVERIFY(n.midRef(INT_MIN, 0).isNull());
- QVERIFY(n.midRef(INT_MIN, -1).isNull());
- QVERIFY(n.midRef(INT_MIN, INT_MAX).isNull());
- QVERIFY(n.midRef(INT_MIN + 1, INT_MAX).isNull());
- QVERIFY(n.midRef(INT_MIN + 2, INT_MAX).isNull());
- QVERIFY(n.midRef(INT_MIN + n.size() + 1, INT_MAX).isNull());
- QVERIFY(n.midRef(INT_MAX).isNull());
- QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull());
- QVERIFY(n.midRef(-5, INT_MAX).isNull());
- QVERIFY(n.midRef(-1, INT_MAX).isNull());
- QVERIFY(n.midRef(0, INT_MAX).isNull());
- QVERIFY(n.midRef(1, INT_MAX).isNull());
- QVERIFY(n.midRef(5, INT_MAX).isNull());
- QVERIFY(n.midRef(20, INT_MAX).isNull());
- QVERIFY(n.midRef(-1, -1).isNull());
-
- QString x = "Nine pineapples";
- QCOMPARE(x.midRef(5, 4).toString(), QString("pine"));
- QCOMPARE(x.midRef(5).toString(), QString("pineapples"));
-
- QCOMPARE(x.midRef(-1, 6), x.midRef(0, 5));
- QVERIFY(x.midRef(-100, 6).isEmpty());
- QVERIFY(x.midRef(INT_MIN, 0).isEmpty());
- QCOMPARE(x.midRef(INT_MIN, -1).toString(), x);
- QVERIFY(x.midRef(INT_MIN, INT_MAX).isNull());
- QVERIFY(x.midRef(INT_MIN + 1, INT_MAX).isEmpty());
- QCOMPARE(x.midRef(INT_MIN + 2, INT_MAX), x.leftRef(1));
- QCOMPARE(x.midRef(INT_MIN + x.size() + 1, INT_MAX).toString(), x);
- QVERIFY(x.midRef(INT_MAX).isNull());
- QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull());
- QCOMPARE(x.midRef(-5, INT_MAX).toString(), x);
- QCOMPARE(x.midRef(-1, INT_MAX).toString(), x);
- QCOMPARE(x.midRef(0, INT_MAX).toString(), x);
- QCOMPARE(x.midRef(1, INT_MAX).toString(), QString("ine pineapples"));
- QCOMPARE(x.midRef(5, INT_MAX).toString(), QString("pineapples"));
- QVERIFY(x.midRef(20, INT_MAX).isNull());
- QCOMPARE(x.midRef(-1, -1).toString(), x);
-}
-
-void tst_QString::stringRef()
-{
- QString a;
- a="ABCDEFGHIEfGEFG"; // 15 chars
-
- QVERIFY(QStringRef(&a, 0, 0) == (QString)"");
-
- QVERIFY(QStringRef(&a, 3, 3) == (QString)"DEF");
- QVERIFY(QStringRef(&a, 3, 3) == QLatin1String("DEF"));
- QVERIFY(QStringRef(&a, 3, 3) == "DEF");
- QVERIFY((QString)"DEF" == QStringRef(&a, 3, 3));
- QVERIFY(QLatin1String("DEF") == QStringRef(&a, 3, 3));
- QVERIFY("DEF" == QStringRef(&a, 3, 3));
-
- QVERIFY(QStringRef(&a, 3, 3) != (QString)"DE");
- QVERIFY(QStringRef(&a, 3, 3) != QLatin1String("DE"));
- QVERIFY(QStringRef(&a, 3, 3) != "DE");
- QVERIFY((QString)"DE" != QStringRef(&a, 3, 3));
- QVERIFY(QLatin1String("DE") != QStringRef(&a, 3, 3));
- QVERIFY("DE" != QStringRef(&a, 3, 3));
-
- QString s_alpha("alpha");
- QString s_beta("beta");
- QStringRef alpha(&s_alpha);
- QStringRef beta(&s_beta);
-
- QVERIFY(alpha < beta);
- QVERIFY(alpha <= beta);
- QVERIFY(alpha <= alpha);
- QVERIFY(beta > alpha);
- QVERIFY(beta >= alpha);
- QVERIFY(beta >= beta);
-
- QString s_alpha2("alpha");
-
- QMap<QStringRef, QString> map;
- map.insert(alpha, "alpha");
- map.insert(beta, "beta");
- QVERIFY(alpha == map.value(QStringRef(&s_alpha2)));
-
- QHash<QStringRef, QString> hash;
- hash.insert(alpha, "alpha");
- hash.insert(beta, "beta");
-
- QVERIFY(alpha == hash.value(QStringRef(&s_alpha2)));
-}
-
-void tst_QString::leftJustified()
-{
- QString a;
- a="ABC";
- QCOMPARE(a.leftJustified(5,'-'), QLatin1String("ABC--"));
- QCOMPARE(a.leftJustified(4,'-'), QLatin1String("ABC-"));
- QCOMPARE(a.leftJustified(4), QLatin1String("ABC "));
- QCOMPARE(a.leftJustified(3), QLatin1String("ABC"));
- QCOMPARE(a.leftJustified(2), QLatin1String("ABC"));
- QCOMPARE(a.leftJustified(1), QLatin1String("ABC"));
- QCOMPARE(a.leftJustified(0), QLatin1String("ABC"));
-
- QString n;
- QVERIFY(!n.leftJustified(3).isNull());
- QCOMPARE(a.leftJustified(4,' ',true), QLatin1String("ABC "));
- QCOMPARE(a.leftJustified(3,' ',true), QLatin1String("ABC"));
- QCOMPARE(a.leftJustified(2,' ',true), QLatin1String("AB"));
- QCOMPARE(a.leftJustified(1,' ',true), QLatin1String("A"));
- QCOMPARE(a.leftJustified(0,' ',true), QLatin1String(""));
-}
-
-void tst_QString::rightJustified()
-{
- QString a;
- a="ABC";
- QCOMPARE(a.rightJustified(5,'-'), QLatin1String("--ABC"));
- QCOMPARE(a.rightJustified(4,'-'), QLatin1String("-ABC"));
- QCOMPARE(a.rightJustified(4), QLatin1String(" ABC"));
- QCOMPARE(a.rightJustified(3), QLatin1String("ABC"));
- QCOMPARE(a.rightJustified(2), QLatin1String("ABC"));
- QCOMPARE(a.rightJustified(1), QLatin1String("ABC"));
- QCOMPARE(a.rightJustified(0), QLatin1String("ABC"));
-
- QString n;
- QVERIFY(!n.rightJustified(3).isNull());
- QCOMPARE(a.rightJustified(4,'-',true), QLatin1String("-ABC"));
- QCOMPARE(a.rightJustified(4,' ',true), QLatin1String(" ABC"));
- QCOMPARE(a.rightJustified(3,' ',true), QLatin1String("ABC"));
- QCOMPARE(a.rightJustified(2,' ',true), QLatin1String("AB"));
- QCOMPARE(a.rightJustified(1,' ',true), QLatin1String("A"));
- QCOMPARE(a.rightJustified(0,' ',true), QLatin1String(""));
- QCOMPARE(a, QLatin1String("ABC"));
-}
-
-void tst_QString::toUpper()
-{
- QCOMPARE( QString().toUpper(), QString() );
- QCOMPARE( QString("").toUpper(), QString("") );
- QCOMPARE( QStringLiteral("text").toUpper(), QString("TEXT") );
- QCOMPARE( QString("text").toUpper(), QString("TEXT") );
- QCOMPARE( QString("Text").toUpper(), QString("TEXT") );
- QCOMPARE( QString("tExt").toUpper(), QString("TEXT") );
- QCOMPARE( QString("teXt").toUpper(), QString("TEXT") );
- QCOMPARE( QString("texT").toUpper(), QString("TEXT") );
- QCOMPARE( QString("TExt").toUpper(), QString("TEXT") );
- QCOMPARE( QString("teXT").toUpper(), QString("TEXT") );
- QCOMPARE( QString("tEXt").toUpper(), QString("TEXT") );
- QCOMPARE( QString("tExT").toUpper(), QString("TEXT") );
- QCOMPARE( QString("TEXT").toUpper(), QString("TEXT") );
- QCOMPARE( QString("@ABYZ[").toUpper(), QString("@ABYZ["));
- QCOMPARE( QString("@abyz[").toUpper(), QString("@ABYZ["));
- QCOMPARE( QString("`ABYZ{").toUpper(), QString("`ABYZ{"));
- QCOMPARE( QString("`abyz{").toUpper(), QString("`ABYZ{"));
-
- QCOMPARE( QString(1, QChar(0xdf)).toUpper(), QString("SS"));
- {
- QString s = QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e");
-
- // call lvalue-ref version, mustn't change the original
- QCOMPARE(s.toUpper(), QString("GROSSSTRASSE"));
- QCOMPARE(s, QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e"));
-
- // call rvalue-ref while shared (the original mustn't change)
- QString copy = s;
- QCOMPARE(qMove(copy).toUpper(), QString("GROSSSTRASSE"));
- QCOMPARE(s, QString::fromUtf8("Gro\xc3\x9fstra\xc3\x9f""e"));
-
- // call rvalue-ref version on detached case
- copy.clear();
- QCOMPARE(qMove(s).toUpper(), QString("GROSSSTRASSE"));
- }
-
- QString lower, upper;
- lower += QChar(QChar::highSurrogate(0x10428));
- lower += QChar(QChar::lowSurrogate(0x10428));
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::lowSurrogate(0x10400));
- QCOMPARE( lower.toUpper(), upper);
- lower += lower;
- upper += upper;
- QCOMPARE( lower.toUpper(), upper);
-
- // test for broken surrogate pair handling (low low hi low hi low)
- lower.prepend(QChar(QChar::lowSurrogate(0x10428)));
- lower.prepend(QChar(QChar::lowSurrogate(0x10428)));
- upper.prepend(QChar(QChar::lowSurrogate(0x10428)));
- upper.prepend(QChar(QChar::lowSurrogate(0x10428)));
- QCOMPARE(lower.toUpper(), upper);
- // test for broken surrogate pair handling (low low hi low hi low hi hi)
- lower += QChar(QChar::highSurrogate(0x10428));
- lower += QChar(QChar::highSurrogate(0x10428));
- upper += QChar(QChar::highSurrogate(0x10428));
- upper += QChar(QChar::highSurrogate(0x10428));
- QCOMPARE(lower.toUpper(), upper);
-
-#ifdef QT_USE_ICU
- // test doesn't work with ICU support, since QChar is unaware of any locale
- QEXPECT_FAIL("", "test doesn't work with ICU support, since QChar is unaware of any locale", Continue);
- QVERIFY(false);
-#else
- for (int i = 0; i < 65536; ++i) {
- QString str(1, QChar(i));
- QString upper = str.toUpper();
- QVERIFY(upper.length() >= 1);
- if (upper.length() == 1)
- QVERIFY(upper == QString(1, QChar(i).toUpper()));
- }
-#endif
-}
-
-void tst_QString::toLower()
-{
- QCOMPARE( QString().toLower(), QString() );
- QCOMPARE( QString("").toLower(), QString("") );
- QCOMPARE( QString("text").toLower(), QString("text") );
- QCOMPARE( QStringLiteral("Text").toLower(), QString("text") );
- QCOMPARE( QString("Text").toLower(), QString("text") );
- QCOMPARE( QString("tExt").toLower(), QString("text") );
- QCOMPARE( QString("teXt").toLower(), QString("text") );
- QCOMPARE( QString("texT").toLower(), QString("text") );
- QCOMPARE( QString("TExt").toLower(), QString("text") );
- QCOMPARE( QString("teXT").toLower(), QString("text") );
- QCOMPARE( QString("tEXt").toLower(), QString("text") );
- QCOMPARE( QString("tExT").toLower(), QString("text") );
- QCOMPARE( QString("TEXT").toLower(), QString("text") );
- QCOMPARE( QString("@ABYZ[").toLower(), QString("@abyz["));
- QCOMPARE( QString("@abyz[").toLower(), QString("@abyz["));
- QCOMPARE( QString("`ABYZ{").toLower(), QString("`abyz{"));
- QCOMPARE( QString("`abyz{").toLower(), QString("`abyz{"));
-
- QCOMPARE( QString(1, QChar(0x130)).toLower(), QString(QString(1, QChar(0x69)) + QChar(0x307)));
-
- QString lower, upper;
- lower += QChar(QChar::highSurrogate(0x10428));
- lower += QChar(QChar::lowSurrogate(0x10428));
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::lowSurrogate(0x10400));
- QCOMPARE( upper.toLower(), lower);
- lower += lower;
- upper += upper;
- QCOMPARE( upper.toLower(), lower);
-
- // test for broken surrogate pair handling (low low hi low hi low)
- lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
- lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
- upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
- upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
- QCOMPARE( upper.toLower(), lower);
- // test for broken surrogate pair handling (low low hi low hi low hi hi)
- lower += QChar(QChar::highSurrogate(0x10400));
- lower += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::highSurrogate(0x10400));
- QCOMPARE( upper.toLower(), lower);
-
-#ifdef QT_USE_ICU
- // test doesn't work with ICU support, since QChar is unaware of any locale
- QEXPECT_FAIL("", "test doesn't work with ICU support, since QChar is unaware of any locale", Continue);
- QVERIFY(false);
-#else
- for (int i = 0; i < 65536; ++i) {
- QString str(1, QChar(i));
- QString lower = str.toLower();
- QVERIFY(lower.length() >= 1);
- if (lower.length() == 1)
- QVERIFY(str.toLower() == QString(1, QChar(i).toLower()));
- }
-#endif
-}
-
-void tst_QString::isUpper()
-{
- QVERIFY(!QString().isUpper());
- QVERIFY(!QString("").isUpper());
- QVERIFY(QString("TEXT").isUpper());
- QVERIFY(!QString("text").isUpper());
- QVERIFY(!QString("Text").isUpper());
- QVERIFY(!QString("tExt").isUpper());
- QVERIFY(!QString("teXt").isUpper());
- QVERIFY(!QString("texT").isUpper());
- QVERIFY(!QString("TExt").isUpper());
- QVERIFY(!QString("teXT").isUpper());
- QVERIFY(!QString("tEXt").isUpper());
- QVERIFY(!QString("tExT").isUpper());
- QVERIFY(!QString("@ABYZ[").isUpper());
- QVERIFY(!QString("@abyz[").isUpper());
- QVERIFY(!QString("`ABYZ{").isUpper());
- QVERIFY(!QString("`abyz{").isUpper());
-}
-
-void tst_QString::isLower()
-{
- QVERIFY(!QString().isLower());
- QVERIFY(!QString("").isLower());
- QVERIFY(QString("text").isLower());
- QVERIFY(!QString("Text").isLower());
- QVERIFY(!QString("tExt").isLower());
- QVERIFY(!QString("teXt").isLower());
- QVERIFY(!QString("texT").isLower());
- QVERIFY(!QString("TExt").isLower());
- QVERIFY(!QString("teXT").isLower());
- QVERIFY(!QString("tEXt").isLower());
- QVERIFY(!QString("tExT").isLower());
- QVERIFY(!QString("TEXT").isLower());
- QVERIFY(!QString("@ABYZ[").isLower());
- QVERIFY(!QString("@abyz[").isLower());
- QVERIFY(!QString("`ABYZ{").isLower());
- QVERIFY(!QString("`abyz{").isLower());
-}
-
-void tst_QString::toCaseFolded()
-{
- QCOMPARE( QString().toCaseFolded(), QString() );
- QCOMPARE( QString("").toCaseFolded(), QString("") );
- QCOMPARE( QString("text").toCaseFolded(), QString("text") );
- QCOMPARE( QString("Text").toCaseFolded(), QString("text") );
- QCOMPARE( QString("tExt").toCaseFolded(), QString("text") );
- QCOMPARE( QString("teXt").toCaseFolded(), QString("text") );
- QCOMPARE( QString("texT").toCaseFolded(), QString("text") );
- QCOMPARE( QString("TExt").toCaseFolded(), QString("text") );
- QCOMPARE( QString("teXT").toCaseFolded(), QString("text") );
- QCOMPARE( QString("tEXt").toCaseFolded(), QString("text") );
- QCOMPARE( QString("tExT").toCaseFolded(), QString("text") );
- QCOMPARE( QString("TEXT").toCaseFolded(), QString("text") );
- QCOMPARE( QString("@ABYZ[").toCaseFolded(), QString("@abyz["));
- QCOMPARE( QString("@abyz[").toCaseFolded(), QString("@abyz["));
- QCOMPARE( QString("`ABYZ{").toCaseFolded(), QString("`abyz{"));
- QCOMPARE( QString("`abyz{").toCaseFolded(), QString("`abyz{"));
-
- QCOMPARE( QString(1, QChar(0xa77d)).toCaseFolded(), QString(1, QChar(0x1d79)));
- QCOMPARE( QString(1, QChar(0xa78d)).toCaseFolded(), QString(1, QChar(0x0265)));
-
- QString lower, upper;
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::lowSurrogate(0x10400));
- lower += QChar(QChar::highSurrogate(0x10428));
- lower += QChar(QChar::lowSurrogate(0x10428));
- QCOMPARE( upper.toCaseFolded(), lower);
- lower += lower;
- upper += upper;
- QCOMPARE( upper.toCaseFolded(), lower);
-
- // test for broken surrogate pair handling (low low hi low hi low)
- lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
- lower.prepend(QChar(QChar::lowSurrogate(0x10400)));
- upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
- upper.prepend(QChar(QChar::lowSurrogate(0x10400)));
- QCOMPARE(upper.toCaseFolded(), lower);
- // test for broken surrogate pair handling (low low hi low hi low hi hi)
- lower += QChar(QChar::highSurrogate(0x10400));
- lower += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::highSurrogate(0x10400));
- QCOMPARE(upper.toCaseFolded(), lower);
-
- //### we currently don't support full case foldings
- for (int i = 0; i < 65536; ++i) {
- QString str(1, QChar(i));
- QString lower = str.toCaseFolded();
- QVERIFY(lower.length() >= 1);
- if (lower.length() == 1)
- QVERIFY(str.toCaseFolded() == QString(1, QChar(i).toCaseFolded()));
- }
-}
-
-void tst_QString::trimmed()
-{
- QString a;
- a="Text";
- QCOMPARE(a, QLatin1String("Text"));
- QCOMPARE(a.trimmed(), QLatin1String("Text"));
- QCOMPARE(a, QLatin1String("Text"));
- a=" ";
- QCOMPARE(a.trimmed(), QLatin1String(""));
- QCOMPARE(a, QLatin1String(" "));
- a=" a ";
- QCOMPARE(a.trimmed(), QLatin1String("a"));
-
- a="Text";
- QCOMPARE(qMove(a).trimmed(), QLatin1String("Text"));
- a=" ";
- QCOMPARE(qMove(a).trimmed(), QLatin1String(""));
- a=" a ";
- QCOMPARE(qMove(a).trimmed(), QLatin1String("a"));
-}
-
-void tst_QString::simplified_data()
-{
- QTest::addColumn<QString>("full" );
- QTest::addColumn<QString>("simple" );
-
- QTest::newRow("null") << QString() << QString();
- QTest::newRow("empty") << "" << "";
- QTest::newRow("one char") << "a" << "a";
- QTest::newRow("one word") << "foo" << "foo";
- QTest::newRow("chars trivial") << "a b" << "a b";
- QTest::newRow("words trivial") << "foo bar" << "foo bar";
- QTest::newRow("allspace") << " \t\v " << "";
- QTest::newRow("char trailing") << "a " << "a";
- QTest::newRow("char trailing tab") << "a\t" << "a";
- QTest::newRow("char multitrailing") << "a " << "a";
- QTest::newRow("char multitrailing tab") << "a \t" << "a";
- QTest::newRow("char leading") << " a" << "a";
- QTest::newRow("char leading tab") << "\ta" << "a";
- QTest::newRow("char multileading") << " a" << "a";
- QTest::newRow("char multileading tab") << "\t a" << "a";
- QTest::newRow("chars apart") << "a b" << "a b";
- QTest::newRow("words apart") << "foo bar" << "foo bar";
- QTest::newRow("enclosed word") << " foo \t " << "foo";
- QTest::newRow("enclosed chars apart") << " a b " << "a b";
- QTest::newRow("enclosed words apart") << " foo bar " << "foo bar";
- QTest::newRow("chars apart posttab") << "a \tb" << "a b";
- QTest::newRow("chars apart pretab") << "a\t b" << "a b";
- QTest::newRow("many words") << " just some random\ttext here" << "just some random text here";
- QTest::newRow("newlines") << "a\nb\nc" << "a b c";
- QTest::newRow("newlines-trailing") << "a\nb\nc\n" << "a b c";
-}
-
-void tst_QString::simplified()
-{
- QFETCH(QString, full);
- QFETCH(QString, simple);
-
- QString orig_full = full;
- orig_full.data(); // forces a detach
-
- QString result = full.simplified();
- if (simple.isNull()) {
- QVERIFY2(result.isNull(), qPrintable("'" + full + "' did not yield null: " + result));
- } else if (simple.isEmpty()) {
- QVERIFY2(result.isEmpty() && !result.isNull(), qPrintable("'" + full + "' did not yield empty: " + result));
- } else {
- QCOMPARE(result, simple);
- }
- QCOMPARE(full, orig_full);
-
- // without detaching:
- QString copy1 = full;
- QCOMPARE(qMove(full).simplified(), simple);
- QCOMPARE(full, orig_full);
-
- // force a detach
- if (!full.isEmpty())
- full[0] = full[0];
- QCOMPARE(qMove(full).simplified(), simple);
-}
-
-void tst_QString::insert_data(bool emptyIsNoop)
-{
- QTest::addColumn<QString>("s");
- QTest::addColumn<CharStarContainer>("arg");
- QTest::addColumn<int>("a1");
- QTest::addColumn<QString>("expected");
-
- const CharStarContainer nullC;
- const CharStarContainer emptyC("");
- const CharStarContainer aC("a");
- const CharStarContainer bC("b");
- //const CharStarContainer abC("ab");
- const CharStarContainer baC("ba");
-
- const QString null;
- const QString empty("");
- const QString a("a");
- const QString b("b");
- const QString ab("ab");
- const QString ba("ba");
-
- QTest::newRow("null.insert(0, null)") << null << nullC << 0 << null;
- QTest::newRow("null.insert(0, empty)") << null << emptyC << 0 << (emptyIsNoop ? null : empty);
- QTest::newRow("null.insert(0, a)") << null << aC << 0 << a;
- QTest::newRow("empty.insert(0, null)") << empty << nullC << 0 << empty;
- QTest::newRow("empty.insert(0, empty)") << empty << emptyC << 0 << empty;
- QTest::newRow("empty.insert(0, a)") << empty << aC << 0 << a;
- QTest::newRow("a.insert(0, null)") << a << nullC << 0 << a;
- QTest::newRow("a.insert(0, empty)") << a << emptyC << 0 << a;
- QTest::newRow("a.insert(0, b)") << a << bC << 0 << ba;
- QTest::newRow("a.insert(0, ba)") << a << baC << 0 << (ba + a);
- QTest::newRow("a.insert(1, null)") << a << nullC << 1 << a;
- QTest::newRow("a.insert(1, empty)") << a << emptyC << 1 << a;
- QTest::newRow("a.insert(1, b)") << a << bC << 1 << ab;
- QTest::newRow("a.insert(1, ba)") << a << baC << 1 << (a + ba);
- QTest::newRow("ba.insert(1, a)") << ba << aC << 1 << (ba + a);
- QTest::newRow("ba.insert(2, b)") << ba << bC << 2 << (ba + b);
-}
-
-void tst_QString::insert_special_cases()
-{
- QString a;
-
- a = "Ys";
- QCOMPARE(a.insert(1,'e'), QString("Yes"));
- QCOMPARE(a.insert(3,'!'), QString("Yes!"));
- QCOMPARE(a.insert(5,'?'), QString("Yes! ?"));
-
- a = "ABC";
- QCOMPARE(a.insert(5,"DEF"), QString("ABC DEF"));
-
- a = "ABC";
- QCOMPARE(a.insert(2, QString()), QString("ABC"));
- QCOMPARE(a.insert(0,"ABC"), QString("ABCABC"));
- QCOMPARE(a, QString("ABCABC"));
- QCOMPARE(a.insert(0,a), QString("ABCABCABCABC"));
-
- QCOMPARE(a, QString("ABCABCABCABC"));
- QCOMPARE(a.insert(0,'<'), QString("<ABCABCABCABC"));
- QCOMPARE(a.insert(1,'>'), QString("<>ABCABCABCABC"));
-
- a = "Meal";
- const QString montreal = QStringLiteral("Montreal");
- QCOMPARE(a.insert(1, QLatin1String("ontr")), montreal);
- QCOMPARE(a.insert(4, ""), montreal);
- QCOMPARE(a.insert(3, QLatin1String("")), montreal);
- QCOMPARE(a.insert(3, QLatin1String(0)), montreal);
- QCOMPARE(a.insert(3, static_cast<const char *>(0)), montreal);
- QCOMPARE(a.insert(0, QLatin1String("a")), QLatin1String("aMontreal"));
-}
-
-void tst_QString::append_data(bool emptyIsNoop)
-{
- QTest::addColumn<QString>("s");
- QTest::addColumn<CharStarContainer>("arg");
- QTest::addColumn<QString>("expected");
-
- const CharStarContainer nullC;
- const CharStarContainer emptyC("");
- const CharStarContainer aC("a");
- const CharStarContainer bC("b");
- //const CharStarContainer abC("ab");
-
- const QString null;
- const QString empty("");
- const QString a("a");
- //const QString b("b");
- const QString ab("ab");
-
- QTest::newRow("null + null") << null << nullC << null;
- QTest::newRow("null + empty") << null << emptyC << (emptyIsNoop ? null : empty);
- QTest::newRow("null + a") << null << aC << a;
- QTest::newRow("empty + null") << empty << nullC << empty;
- QTest::newRow("empty + empty") << empty << emptyC << empty;
- QTest::newRow("empty + a") << empty << aC << a;
- QTest::newRow("a + null") << a << nullC << a;
- QTest::newRow("a + empty") << a << emptyC << a;
- QTest::newRow("a + b") << a << bC << ab;
-}
-
-void tst_QString::append_special_cases()
-{
- {
- QString a;
- static const QChar unicode[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
- a.append(unicode, sizeof unicode / sizeof *unicode);
- QCOMPARE(a, QLatin1String("Hello, World!"));
- static const QChar nl('\n');
- a.append(&nl, 1);
- QCOMPARE(a, QLatin1String("Hello, World!\n"));
- a.append(unicode, sizeof unicode / sizeof *unicode);
- QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
- a.append(unicode, 0); // no-op
- QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
- a.append(unicode, -1); // no-op
- QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
- a.append(0, 1); // no-op
- QCOMPARE(a, QLatin1String("Hello, World!\nHello, World!"));
- }
-}
-
-void tst_QString::append_bytearray_special_cases_data()
-{
- QTest::addColumn<QString>("str" );
- QTest::addColumn<QByteArray>("ba" );
- QTest::addColumn<QString>("res" );
-
- QByteArray ba( 5, 0 );
- ba[0] = 'a';
- ba[1] = 'b';
- ba[2] = 'c';
- ba[3] = 'd';
-
- // no 0 termination
- ba.resize( 4 );
- QTest::newRow( "notTerminated_0" ) << QString() << ba << QString("abcd");
- QTest::newRow( "notTerminated_1" ) << QString("") << ba << QString("abcd");
- QTest::newRow( "notTerminated_2" ) << QString("foobar ") << ba << QString("foobar abcd");
-
- // byte array with only a 0
- ba.resize( 1 );
- ba[0] = 0;
- QByteArray ba2("foobar ");
- ba2.append('\0');
- QTest::newRow( "emptyString" ) << QString("foobar ") << ba << QString(ba2);
-
- // empty byte array
- ba.resize( 0 );
- QTest::newRow( "emptyByteArray" ) << QString("foobar ") << ba << QString("foobar ");
-
- // non-ascii byte array
- QTest::newRow( "nonAsciiByteArray") << QString() << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
- QTest::newRow( "nonAsciiByteArray2") << QString() << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
-}
-
-void tst_QString::append_bytearray_special_cases()
-{
- {
- QFETCH( QString, str );
- QFETCH( QByteArray, ba );
-
- str.append( ba );
-
- QTEST( str, "res" );
- }
- {
- QFETCH( QString, str );
- QFETCH( QByteArray, ba );
-
- str.append( ba );
-
- QTEST( str, "res" );
- }
-
- QFETCH( QByteArray, ba );
- if (ba.constData()[ba.length()] == '\0') {
- QFETCH( QString, str );
-
- str.append(ba.constData());
- QTEST( str, "res" );
- }
-}
-
-void tst_QString::operator_pluseq_data(bool emptyIsNoop)
-{
- append_data(emptyIsNoop);
-}
-
-void tst_QString::operator_pluseq_bytearray_special_cases_data()
-{
- append_bytearray_special_cases_data();
-}
-
-void tst_QString::operator_pluseq_bytearray_special_cases()
-{
- {
- QFETCH( QString, str );
- QFETCH( QByteArray, ba );
-
- str += ba;
-
- QTEST( str, "res" );
- }
- {
- QFETCH( QString, str );
- QFETCH( QByteArray, ba );
-
- str += ba;
-
- QTEST( str, "res" );
- }
-
- QFETCH( QByteArray, ba );
- if (ba.constData()[ba.length()] == '\0') {
- QFETCH( QString, str );
-
- str += ba.constData();
- QTEST( str, "res" );
- }
-}
-
-void tst_QString::operator_eqeq_bytearray_data()
-{
- constructorQByteArray_data();
-}
-
-void tst_QString::operator_eqeq_bytearray()
-{
- QFETCH(QByteArray, src);
- QFETCH(QString, expected);
-
- QVERIFY(expected == src);
- QVERIFY(!(expected != src));
-
- if (src.constData()[src.length()] == '\0') {
- QVERIFY(expected == src.constData());
- QVERIFY(!(expected != src.constData()));
- }
-}
-
-void tst_QString::swap()
-{
- QString s1, s2;
- s1 = "s1";
- s2 = "s2";
- s1.swap(s2);
- QCOMPARE(s1,QLatin1String("s2"));
- QCOMPARE(s2,QLatin1String("s1"));
-}
-
-void tst_QString::prepend_data(bool emptyIsNoop)
-{
- QTest::addColumn<QString>("s");
- QTest::addColumn<CharStarContainer>("arg");
- QTest::addColumn<QString>("expected");
-
- const CharStarContainer nullC;
- const CharStarContainer emptyC("");
- const CharStarContainer aC("a");
- const CharStarContainer bC("b");
- const CharStarContainer baC("ba");
-
- const QString null;
- const QString empty("");
- const QString a("a");
- //const QString b("b");
- const QString ba("ba");
-
- QTest::newRow("null.prepend(null)") << null << nullC << null;
- QTest::newRow("null.prepend(empty)") << null << emptyC << (emptyIsNoop ? null : empty);
- QTest::newRow("null.prepend(a)") << null << aC << a;
- QTest::newRow("empty.prepend(null)") << empty << nullC << empty;
- QTest::newRow("empty.prepend(empty)") << empty << emptyC << empty;
- QTest::newRow("empty.prepend(a)") << empty << aC << a;
- QTest::newRow("a.prepend(null)") << a << nullC << a;
- QTest::newRow("a.prepend(empty)") << a << emptyC << a;
- QTest::newRow("a.prepend(b)") << a << bC << ba;
- QTest::newRow("a.prepend(ba)") << a << baC << (ba + a);
-}
-
-void tst_QString::prepend_bytearray_special_cases_data()
-{
- QTest::addColumn<QString>("str" );
- QTest::addColumn<QByteArray>("ba" );
- QTest::addColumn<QString>("res" );
-
- QByteArray ba( 5, 0 );
- ba[0] = 'a';
- ba[1] = 'b';
- ba[2] = 'c';
- ba[3] = 'd';
-
- // byte array with only a 0
- ba.resize( 1 );
- ba[0] = 0;
- QTest::newRow( "emptyString" ) << QString("foobar ") << ba << QString("foobar ");
-
- // empty byte array
- ba.resize( 0 );
- QTest::newRow( "emptyByteArray" ) << QString(" foobar") << ba << QString(" foobar");
-
- // non-ascii byte array
- QTest::newRow( "nonAsciiByteArray") << QString() << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
- QTest::newRow( "nonAsciiByteArray2") << QString() << QByteArray("\xc3\xa9") << QString::fromUtf8("\xc3\xa9");
-}
-
-void tst_QString::prepend_bytearray_special_cases()
-{
- {
- QFETCH( QString, str );
- QFETCH( QByteArray, ba );
-
- str.prepend( ba );
-
- QFETCH( QString, res );
- QCOMPARE( str, res );
- }
- {
- QFETCH( QString, str );
- QFETCH( QByteArray, ba );
-
- str.prepend( ba );
-
- QTEST( str, "res" );
- }
-
- QFETCH( QByteArray, ba );
- if (ba.constData()[ba.length()] == '\0') {
- QFETCH( QString, str );
-
- str.prepend(ba.constData());
- QTEST( str, "res" );
- }
-}
-
-void tst_QString::replace_uint_uint()
-{
- QFETCH( QString, string );
- QFETCH( int, index );
- QFETCH( int, len );
- QFETCH( QString, after );
-
- QString s1 = string;
- s1.replace( (uint) index, (int) len, after );
- QTEST( s1, "result" );
-
- QString s2 = string;
- s2.replace( (uint) index, (uint) len, after.unicode(), after.length() );
- QTEST( s2, "result" );
-
- if ( after.length() == 1 ) {
- QString s3 = string;
- s3.replace( (uint) index, (uint) len, QChar(after[0]) );
- QTEST( s3, "result" );
-
- QString s4 = string;
- s4.replace( (uint) index, (uint) len, QChar(after[0]).toLatin1() );
- QTEST( s4, "result" );
- }
-}
-
-void tst_QString::replace_extra()
-{
- /*
- This test is designed to be extremely slow if QString::replace() doesn't optimize the case
- len == after.size().
- */
- QString str("dsfkljfdsjklsdjsfjklfsdjkldfjslkjsdfkllkjdsfjklsfdkjsdflkjlsdfjklsdfkjldsflkjsddlkj");
- for (int j = 1; j < 12; ++j)
- str += str;
-
- QString str2("aaaaaaaaaaaaaaaaaaaa");
- for (int i = 0; i < 2000000; ++i) {
- str.replace(10, 20, str2);
- }
-
- /*
- Make sure that replacing with itself works.
- */
- QString copy(str);
- copy.detach();
- str.replace(0, str.length(), str);
- QVERIFY(copy == str);
-
- /*
- Make sure that replacing a part of oneself with itself works.
- */
- QString str3("abcdefghij");
- str3.replace(0, 1, str3);
- QCOMPARE(str3, QString("abcdefghijbcdefghij"));
-
- QString str4("abcdefghij");
- str4.replace(1, 3, str4);
- QCOMPARE(str4, QString("aabcdefghijefghij"));
-
- QString str5("abcdefghij");
- str5.replace(8, 10, str5);
- QCOMPARE(str5, QString("abcdefghabcdefghij"));
-
- // Replacements using only part of the string modified:
- QString str6("abcdefghij");
- str6.replace(1, 8, str6.constData() + 3, 3);
- QCOMPARE(str6, QString("adefj"));
-
- QString str7("abcdefghibcdefghij");
- str7.replace(str7.constData() + 1, 6, str7.constData() + 2, 3);
- QCOMPARE(str7, QString("acdehicdehij"));
-
- const int many = 1024;
- /*
- QS::replace(const QChar *, int, const QChar *, int, Qt::CaseSensitivity)
- does its replacements in batches of many (please keep in sync with any
- changes to batch size), which lead to misbehaviour if ether QChar * array
- was part of the data being modified.
- */
- QString str8("abcdefg"), ans8("acdeg");
- {
- // Make str8 and ans8 repeat themselves many + 1 times:
- int i = many;
- QString big(str8), small(ans8);
- while (i && !(i & 1)) { // Exploit many being a power of 2:
- big += big;
- small += small;
- i >>= 1;
- }
- while (i-- > 0) {
- str8 += big;
- ans8 += small;
- }
- }
- str8.replace(str8.constData() + 1, 5, str8.constData() + 2, 3);
- // Pre-test the bit where the diff happens, so it gets displayed:
- QCOMPARE(str8.mid((many - 3) * 5), ans8.mid((many - 3) * 5));
- // Also check the full values match, of course:
- QCOMPARE(str8.size(), ans8.size());
- QCOMPARE(str8, ans8);
-}
-
-void tst_QString::replace_string()
-{
- QFETCH( QString, string );
- QFETCH( QString, before );
- QFETCH( QString, after );
- QFETCH( bool, bcs );
-
- Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
-
- if ( before.length() == 1 ) {
- QChar ch = before.at( 0 );
-
- QString s1 = string;
- s1.replace( ch, after, cs );
- QTEST( s1, "result" );
-
- if ( QChar(ch.toLatin1()) == ch ) {
- QString s2 = string;
- s2.replace( ch.toLatin1(), after, cs );
- QTEST( s2, "result" );
- }
- }
-
- QString s3 = string;
- s3.replace( before, after, cs );
- QTEST( s3, "result" );
-
- QString s4 = string;
- s4.replace( QRegExp(QRegExp::escape(before), cs), after );
- QTEST( s4, "result" );
-
- QString s5 = string;
- s5.replace(QRegExp(before, cs, QRegExp::FixedString), after);
- QTEST( s5, "result" );
-}
-
-void tst_QString::replace_regexp()
-{
- QFETCH( QString, string );
- QFETCH( QString, regexp );
- QFETCH( QString, after );
-
- QString s2 = string;
- s2.replace( QRegExp(regexp), after );
- QTEST( s2, "result" );
- s2 = string;
- QRegularExpression regularExpression(regexp);
- if (!regularExpression.isValid())
- QTest::ignoreMessage(QtWarningMsg, "QString::replace: invalid QRegularExpression object");
- s2.replace( regularExpression, after );
- QTEST( s2, "result" );
-}
-
-void tst_QString::remove_uint_uint()
-{
- QFETCH( QString, string );
- QFETCH( int, index );
- QFETCH( int, len );
- QFETCH( QString, after );
-
- if ( after.length() == 0 ) {
- QString s1 = string;
- s1.remove( (uint) index, (uint) len );
- QTEST( s1, "result" );
- } else
- QCOMPARE( 0, 0 ); // shut Qt Test
-}
-
-void tst_QString::remove_string()
-{
- QFETCH( QString, string );
- QFETCH( QString, before );
- QFETCH( QString, after );
- QFETCH( bool, bcs );
-
- Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
-
- if ( after.length() == 0 ) {
- if ( before.length() == 1 && cs ) {
- QChar ch = before.at( 0 );
-
- QString s1 = string;
- s1.remove( ch );
- QTEST( s1, "result" );
-
- if ( QChar(ch.toLatin1()) == ch ) {
- QString s2 = string;
- s2.remove( ch );
- QTEST( s2, "result" );
- }
- }
-
- QString s3 = string;
- s3.remove( before, cs );
- QTEST( s3, "result" );
-
- QString s4 = string;
- s4.replace( QRegExp(QRegExp::escape(before), cs), after );
- QTEST( s4, "result" );
-
- QString s5 = string;
- s5.replace( QRegExp(before, cs, QRegExp::FixedString), after );
- QTEST( s5, "result" );
-
- if (QtPrivate::isLatin1(before)) {
- QString s6 = string;
- s6.remove( QLatin1String(before.toLatin1()), cs );
- QTEST( s6, "result" );
- }
- } else {
- QCOMPARE( 0, 0 ); // shut Qt Test
- }
-}
-
-void tst_QString::remove_regexp()
-{
- QFETCH( QString, string );
- QFETCH( QString, regexp );
- QFETCH( QString, after );
-
- if ( after.length() == 0 ) {
- QString s2 = string;
- s2.remove( QRegExp(regexp) );
- QTEST( s2, "result" );
-
- s2 = string;
- s2.remove( QRegularExpression(regexp) );
- QTEST( s2, "result" );
- } else {
- QCOMPARE( 0, 0 ); // shut Qt Test
- }
-}
-
-void tst_QString::toNum()
-{
-#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
-#define TEST_TO_INT(num, func) \
- a = #num; \
- QVERIFY2(a.func(&ok) == num ## i64 && ok, "Failed: num=" #num ", func=" #func);
-#else
-#define TEST_TO_INT(num, func) \
- a = #num; \
- QVERIFY2(a.func(&ok) == num ## LL && ok, "Failed: num=" #num ", func=" #func);
-#endif
-
- QString a;
- bool ok = false;
-
- TEST_TO_INT(0, toInt)
- TEST_TO_INT(-1, toInt)
- TEST_TO_INT(1, toInt)
- TEST_TO_INT(2147483647, toInt)
- TEST_TO_INT(-2147483648, toInt)
-
- TEST_TO_INT(0, toShort)
- TEST_TO_INT(-1, toShort)
- TEST_TO_INT(1, toShort)
- TEST_TO_INT(32767, toShort)
- TEST_TO_INT(-32768, toShort)
-
- TEST_TO_INT(0, toLong)
- TEST_TO_INT(-1, toLong)
- TEST_TO_INT(1, toLong)
- TEST_TO_INT(2147483647, toLong)
- TEST_TO_INT(-2147483648, toLong)
- TEST_TO_INT(0, toLongLong)
- TEST_TO_INT(-1, toLongLong)
- TEST_TO_INT(1, toLongLong)
- TEST_TO_INT(9223372036854775807, toLongLong)
- TEST_TO_INT(-9223372036854775807, toLongLong)
-
-#undef TEST_TO_INT
-
-#if defined (Q_OS_WIN) && defined (Q_CC_MSVC)
-#define TEST_TO_UINT(num, func) \
- a = #num; \
- QVERIFY2(a.func(&ok) == num ## i64 && ok, "Failed: num=" #num ", func=" #func);
-#else
-#define TEST_TO_UINT(num, func) \
- a = #num; \
- QVERIFY2(a.func(&ok) == num ## ULL && ok, "Failed: num=" #num ", func=" #func);
-#endif
-
- TEST_TO_UINT(0, toUInt)
- TEST_TO_UINT(1, toUInt)
- TEST_TO_UINT(4294967295, toUInt)
-
- TEST_TO_UINT(0, toUShort)
- TEST_TO_UINT(1, toUShort)
- TEST_TO_UINT(65535, toUShort)
-
- TEST_TO_UINT(0, toULong)
- TEST_TO_UINT(1, toULong)
- TEST_TO_UINT(4294967295, toULong)
-
- TEST_TO_UINT(0, toULongLong)
- TEST_TO_UINT(1, toULongLong)
- TEST_TO_UINT(18446744073709551615, toULongLong)
-#undef TEST_TO_UINT
-
-
-#define TEST_BASE(str, base, num) \
- a = str; \
- QVERIFY2(a.toInt(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toInt"); \
- QVERIFY2(a.toUInt(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toUInt"); \
- QVERIFY2(a.toShort(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toShort"); \
- QVERIFY2(a.toUShort(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toUShort"); \
- QVERIFY2(a.toLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLong"); \
- QVERIFY2(a.toULong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toULong"); \
- QVERIFY2(a.toLongLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLongLong"); \
- QVERIFY2(a.toULongLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toULongLong");
-
- TEST_BASE("FF", 16, 255)
- TEST_BASE("0xFF", 16, 255)
- TEST_BASE("77", 8, 63)
- TEST_BASE("077", 8, 63)
-
- TEST_BASE("0xFF", 0, 255)
- TEST_BASE("077", 0, 63)
- TEST_BASE("255", 0, 255)
-
- TEST_BASE(" FF", 16, 255)
- TEST_BASE(" 0xFF", 16, 255)
- TEST_BASE(" 77", 8, 63)
- TEST_BASE(" 077", 8, 63)
-
- TEST_BASE(" 0xFF", 0, 255)
- TEST_BASE(" 077", 0, 63)
- TEST_BASE(" 255", 0, 255)
-
- TEST_BASE("\tFF\t", 16, 255)
- TEST_BASE("\t0xFF ", 16, 255)
- TEST_BASE(" 77 ", 8, 63)
- TEST_BASE("77 ", 8, 63)
-
-#undef TEST_BASE
-
-#define TEST_NEG_BASE(str, base, num) \
- a = str; \
- QVERIFY2(a.toInt(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toInt"); \
- QVERIFY2(a.toShort(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toShort"); \
- QVERIFY2(a.toLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLong"); \
- QVERIFY2(a.toLongLong(&ok, base) == num && ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLongLong");
-
- TEST_NEG_BASE("-FE", 16, -254)
- TEST_NEG_BASE("-0xFE", 16, -254)
- TEST_NEG_BASE("-77", 8, -63)
- TEST_NEG_BASE("-077", 8, -63)
-
- TEST_NEG_BASE("-0xFE", 0, -254)
- TEST_NEG_BASE("-077", 0, -63)
- TEST_NEG_BASE("-254", 0, -254)
-
-#undef TEST_NEG_BASE
-
-#define TEST_DOUBLE(num, str) \
- a = str; \
- QCOMPARE(a.toDouble(&ok), num); \
- QVERIFY(ok);
-
- TEST_DOUBLE(1.2345, "1.2345")
- TEST_DOUBLE(12.345, "1.2345e+01")
- TEST_DOUBLE(12.345, "1.2345E+01")
- TEST_DOUBLE(12345.6, "12345.6")
-
-#undef TEST_DOUBLE
-
-
-#define TEST_BAD(str, func) \
- a = str; \
- a.func(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str " func=" #func);
-
- TEST_BAD("32768", toShort)
- TEST_BAD("-32769", toShort)
- TEST_BAD("65536", toUShort)
- TEST_BAD("2147483648", toInt)
- TEST_BAD("-2147483649", toInt)
- TEST_BAD("4294967296", toUInt)
- if (sizeof(long) == 4) {
- TEST_BAD("2147483648", toLong)
- TEST_BAD("-2147483649", toLong)
- TEST_BAD("4294967296", toULong)
- }
- TEST_BAD("9223372036854775808", toLongLong)
- TEST_BAD("-9223372036854775809", toLongLong)
- TEST_BAD("18446744073709551616", toULongLong)
- TEST_BAD("-1", toUShort)
- TEST_BAD("-1", toUInt)
- TEST_BAD("-1", toULong)
- TEST_BAD("-1", toULongLong)
-#undef TEST_BAD
-
-#define TEST_BAD_ALL(str) \
- a = str; \
- a.toShort(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toUShort(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toInt(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toUInt(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toLong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toULong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toLongLong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toULongLong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toFloat(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- a.toDouble(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str);
-
- TEST_BAD_ALL((const char*)0);
- TEST_BAD_ALL("");
- TEST_BAD_ALL(" ");
- TEST_BAD_ALL(".");
- TEST_BAD_ALL("-");
- TEST_BAD_ALL("hello");
- TEST_BAD_ALL("1.2.3");
- TEST_BAD_ALL("0x0x0x");
- TEST_BAD_ALL("123-^~<");
- TEST_BAD_ALL("123ThisIsNotANumber");
-
-#undef TEST_BAD_ALL
-
- a = "FF";
- a.toULongLong(&ok, 10);
- QVERIFY(!ok);
-
- a = "FF";
- a.toULongLong(&ok, 0);
- QVERIFY(!ok);
-
-#ifdef QT_NO_FPU
- double d = 3.40282346638528e+38; // slightly off FLT_MAX when using hardfloats
-#else
- double d = 3.4028234663852886e+38; // FLT_MAX
-#endif
- QString::number(d, 'e', 17).toFloat(&ok);
- QVERIFY(ok);
- QString::number(d + 1e32, 'e', 17).toFloat(&ok);
- QVERIFY(!ok);
- QString::number(-d, 'e', 17).toFloat(&ok);
- QVERIFY(ok);
- QString::number(-d - 1e32, 'e', 17).toFloat(&ok);
- QVERIFY(!ok);
- QString::number(d + 1e32, 'e', 17).toDouble(&ok);
- QVERIFY(ok);
- QString::number(-d - 1e32, 'e', 17).toDouble(&ok);
- QVERIFY(ok);
-}
-
-void tst_QString::toUShort()
-{
- QString a;
- bool ok;
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a="";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a="COMPARE";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a="123";
- QCOMPARE(a.toUShort(),(ushort)123);
- QCOMPARE(a.toUShort(&ok),(ushort)123);
- QVERIFY(ok);
-
- a="123A";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a="1234567";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a = "aaa123aaa";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a = "aaa123";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a = "123aaa";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a = "32767";
- QCOMPARE(a.toUShort(),(ushort)32767);
- QCOMPARE(a.toUShort(&ok),(ushort)32767);
- QVERIFY(ok);
-
- a = "-32767";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a = "65535";
- QCOMPARE(a.toUShort(),(ushort)65535);
- QCOMPARE(a.toUShort(&ok),(ushort)65535);
- QVERIFY(ok);
-
- if (sizeof(short) == 2) {
- a = "65536";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
-
- a = "123456";
- QCOMPARE(a.toUShort(),(ushort)0);
- QCOMPARE(a.toUShort(&ok),(ushort)0);
- QVERIFY(!ok);
- }
-}
-
-void tst_QString::toShort()
-{
- QString a;
- bool ok;
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a="";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a="COMPARE";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a="123";
- QCOMPARE(a.toShort(),(short)123);
- QCOMPARE(a.toShort(&ok),(short)123);
- QVERIFY(ok);
-
- a="123A";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a="1234567";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a = "aaa123aaa";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a = "aaa123";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a = "123aaa";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a = "32767";
- QCOMPARE(a.toShort(),(short)32767);
- QCOMPARE(a.toShort(&ok),(short)32767);
- QVERIFY(ok);
-
- a = "-32767";
- QCOMPARE(a.toShort(),(short)-32767);
- QCOMPARE(a.toShort(&ok),(short)-32767);
- QVERIFY(ok);
-
- a = "-32768";
- QCOMPARE(a.toShort(),(short)-32768);
- QCOMPARE(a.toShort(&ok),(short)-32768);
- QVERIFY(ok);
-
- if (sizeof(short) == 2) {
- a = "32768";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
-
- a = "-32769";
- QCOMPARE(a.toShort(),(short)0);
- QCOMPARE(a.toShort(&ok),(short)0);
- QVERIFY(!ok);
- }
-}
-
-void tst_QString::toInt()
-{
- QString a;
- bool ok;
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a = "";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a="COMPARE";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a="123";
- QCOMPARE(a.toInt(),123);
- QCOMPARE(a.toInt(&ok),123);
- QVERIFY(ok);
-
- a="123A";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a="1234567";
- QCOMPARE(a.toInt(),1234567);
- QCOMPARE(a.toInt(&ok),1234567);
- QVERIFY(ok);
-
- a="12345678901234";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a="3234567890";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a = "aaa12345aaa";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a = "aaa12345";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a = "12345aaa";
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a = "2147483647"; // 2**31 - 1
- QCOMPARE(a.toInt(),2147483647);
- QCOMPARE(a.toInt(&ok),2147483647);
- QVERIFY(ok);
-
- if (sizeof(int) == 4) {
- a = "-2147483647"; // -(2**31 - 1)
- QCOMPARE(a.toInt(),-2147483647);
- QCOMPARE(a.toInt(&ok),-2147483647);
- QVERIFY(ok);
-
- a = "2147483648"; // 2**31
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
-
- a = "-2147483648"; // -2**31
- QCOMPARE(a.toInt(),-2147483647 - 1);
- QCOMPARE(a.toInt(&ok),-2147483647 - 1);
- QVERIFY(ok);
-
- a = "2147483649"; // 2**31 + 1
- QCOMPARE(a.toInt(),0);
- QCOMPARE(a.toInt(&ok),0);
- QVERIFY(!ok);
- }
-}
-
-void tst_QString::toUInt()
-{
- bool ok;
- QString a;
- a="3234567890";
- QCOMPARE(a.toUInt(&ok),3234567890u);
- QVERIFY(ok);
-
- a = "-50";
- QCOMPARE(a.toUInt(),0u);
- QCOMPARE(a.toUInt(&ok),0u);
- QVERIFY(!ok);
-
- a = "4294967295"; // 2**32 - 1
- QCOMPARE(a.toUInt(),4294967295u);
- QCOMPARE(a.toUInt(&ok),4294967295u);
- QVERIFY(ok);
-
- if (sizeof(int) == 4) {
- a = "4294967296"; // 2**32
- QCOMPARE(a.toUInt(),0u);
- QCOMPARE(a.toUInt(&ok),0u);
- QVERIFY(!ok);
- }
-}
-
-///////////////////////////// to*Long //////////////////////////////////////
-
-void tst_QString::toULong_data()
-{
- QTest::addColumn<QString>("str" );
- QTest::addColumn<int>("base" );
- QTest::addColumn<ulong>("result" );
- QTest::addColumn<bool>("ok" );
-
- QTest::newRow( "default" ) << QString() << 10 << 0UL << false;
- QTest::newRow( "empty" ) << QString("") << 10 << 0UL << false;
- QTest::newRow( "ulong1" ) << QString("3234567890") << 10 << 3234567890UL << true;
- QTest::newRow( "ulong2" ) << QString("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true;
-}
-
-void tst_QString::toULong()
-{
- QFETCH( QString, str );
- QFETCH( int, base );
- QFETCH( ulong, result );
- QFETCH( bool, ok );
-
- bool b;
- QCOMPARE( str.toULong( 0, base ), result );
- QCOMPARE( str.toULong( &b, base ), result );
- QCOMPARE( b, ok );
-}
-
-void tst_QString::toLong_data()
-{
- QTest::addColumn<QString>("str" );
- QTest::addColumn<int>("base" );
- QTest::addColumn<long>("result" );
- QTest::addColumn<bool>("ok" );
-
- QTest::newRow( "default" ) << QString() << 10 << 0L << false;
- QTest::newRow( "empty" ) << QString("") << 10 << 0L << false;
- QTest::newRow( "normal" ) << QString("7fFFfFFf") << 16 << 0x7fFFfFFfL << true;
- QTest::newRow( "long_max" ) << QString("2147483647") << 10 << 2147483647L << true;
- if (sizeof(long) == 4) {
- QTest::newRow( "long_max+1" ) << QString("2147483648") << 10 << 0L << false;
- QTest::newRow( "long_min-1" ) << QString("-80000001") << 16 << 0L << false;
- }
- QTest::newRow( "negative" ) << QString("-7fffffff") << 16 << -0x7fffffffL << true;
-// QTest::newRow( "long_min" ) << QString("-80000000") << 16 << 0x80000000uL << true;
-}
-
-void tst_QString::toLong()
-{
- QFETCH( QString, str );
- QFETCH( int, base );
- QFETCH( long, result );
- QFETCH( bool, ok );
-
- bool b;
- QCOMPARE( str.toLong( 0, base ), result );
- QCOMPARE( str.toLong( &b, base ), result );
- QCOMPARE( b, ok );
-}
-
-
-////////////////////////// to*LongLong //////////////////////////////////////
-
-void tst_QString::toULongLong()
-{
- QString str;
- bool ok;
- str = "18446744073709551615"; // ULLONG_MAX
- QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(18446744073709551615) );
- QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(18446744073709551615) );
- QVERIFY( ok );
-
- str = "18446744073709551616"; // ULLONG_MAX + 1
- QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(0) );
- QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(0) );
- QVERIFY( !ok );
-
- str = "-150";
- QCOMPARE( str.toULongLong( 0 ), Q_UINT64_C(0) );
- QCOMPARE( str.toULongLong( &ok ), Q_UINT64_C(0) );
- QVERIFY( !ok );
-}
-
-void tst_QString::toLongLong()
-{
- QString str;
- bool ok;
-
- str = "9223372036854775807"; // LLONG_MAX
- QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(9223372036854775807) );
- QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(9223372036854775807) );
- QVERIFY( ok );
-
- str = "-9223372036854775808"; // LLONG_MIN
- QCOMPARE( str.toLongLong( 0 ),
- -Q_INT64_C(9223372036854775807) - Q_INT64_C(1) );
- QCOMPARE( str.toLongLong( &ok ),
- -Q_INT64_C(9223372036854775807) - Q_INT64_C(1) );
- QVERIFY( ok );
-
- str = "aaaa9223372036854775807aaaa";
- QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
- QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
- QVERIFY( !ok );
-
- str = "9223372036854775807aaaa";
- QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
- QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
- QVERIFY( !ok );
-
- str = "aaaa9223372036854775807";
- QCOMPARE( str.toLongLong( 0 ), Q_INT64_C(0) );
- QCOMPARE( str.toLongLong( &ok ), Q_INT64_C(0) );
- QVERIFY( !ok );
-
- static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- for (int i = 0; i < 36; ++i) {
- for (int j = 0; j < 36; ++j) {
- for (int k = 0; k < 36; ++k) {
- QString str;
- str += QChar(digits[i]);
- str += QChar(digits[j]);
- str += QChar(digits[k]);
- qlonglong value = (((i * 36) + j) * 36) + k;
- QVERIFY(str.toLongLong(0, 36) == value);
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-void tst_QString::toFloat()
-{
- QString a;
- bool ok;
- a="0.000000000931322574615478515625";
- QCOMPARE(a.toFloat(&ok),(float)(0.000000000931322574615478515625));
- QVERIFY(ok);
-}
-
-void tst_QString::toDouble_data()
-{
- QTest::addColumn<QString>("str" );
- QTest::addColumn<double>("result" );
- QTest::addColumn<bool>("result_ok" );
-
- QTest::newRow( "ok00" ) << QString("0.000000000931322574615478515625") << 0.000000000931322574615478515625 << true;
- QTest::newRow( "ok01" ) << QString(" 123.45") << 123.45 << true;
-
- QTest::newRow( "ok02" ) << QString("0.1e10") << 0.1e10 << true;
- QTest::newRow( "ok03" ) << QString("0.1e-10") << 0.1e-10 << true;
-
- QTest::newRow( "ok04" ) << QString("1e10") << 1.0e10 << true;
- QTest::newRow( "ok05" ) << QString("1e+10") << 1.0e10 << true;
- QTest::newRow( "ok06" ) << QString("1e-10") << 1.0e-10 << true;
-
- QTest::newRow( "ok07" ) << QString(" 1e10") << 1.0e10 << true;
- QTest::newRow( "ok08" ) << QString(" 1e+10") << 1.0e10 << true;
- QTest::newRow( "ok09" ) << QString(" 1e-10") << 1.0e-10 << true;
-
- QTest::newRow( "ok10" ) << QString("1.") << 1.0 << true;
- QTest::newRow( "ok11" ) << QString(".1") << 0.1 << true;
-
- QTest::newRow( "wrong00" ) << QString("123.45 ") << 123.45 << true;
- QTest::newRow( "wrong01" ) << QString(" 123.45 ") << 123.45 << true;
-
- QTest::newRow( "wrong02" ) << QString("aa123.45aa") << 0.0 << false;
- QTest::newRow( "wrong03" ) << QString("123.45aa") << 0.0 << false;
- QTest::newRow( "wrong04" ) << QString("123erf") << 0.0 << false;
-
- QTest::newRow( "wrong05" ) << QString("abc") << 0.0 << false;
- QTest::newRow( "wrong06" ) << QString() << 0.0 << false;
- QTest::newRow( "wrong07" ) << QString("") << 0.0 << false;
-}
-
-void tst_QString::toDouble()
-{
- QFETCH( QString, str );
- QFETCH( bool, result_ok );
- bool ok;
- double d = str.toDouble( &ok );
- if ( result_ok ) {
- QTEST( d, "result" );
- QVERIFY( ok );
- } else {
- QVERIFY( !ok );
- }
-}
-
-void tst_QString::setNum()
-{
- QString a;
- QCOMPARE(a.setNum(123), QLatin1String("123"));
- QCOMPARE(a.setNum(-123), QLatin1String("-123"));
- QCOMPARE(a.setNum(0x123,16), QLatin1String("123"));
- QCOMPARE(a.setNum((short)123), QLatin1String("123"));
- QCOMPARE(a.setNum(123L), QLatin1String("123"));
- QCOMPARE(a.setNum(123UL), QLatin1String("123"));
- QCOMPARE(a.setNum(2147483647L), QString("2147483647")); // 32 bit LONG_MAX
- QCOMPARE(a.setNum(-2147483647L), QString("-2147483647")); // LONG_MIN + 1
- QCOMPARE(a.setNum(-2147483647L-1L), QString("-2147483648")); // LONG_MIN
- QCOMPARE(a.setNum(1.23), QString("1.23"));
- QCOMPARE(a.setNum(1.234567), QString("1.23457"));
-#if defined(LONG_MAX) && defined(LLONG_MAX) && LONG_MAX == LLONG_MAX
- // LONG_MAX and LONG_MIN on 64 bit systems
- QCOMPARE(a.setNum(9223372036854775807L), QString("9223372036854775807"));
- QCOMPARE(a.setNum(-9223372036854775807L-1L), QString("-9223372036854775808"));
- QCOMPARE(a.setNum(18446744073709551615UL), QString("18446744073709551615"));
-#endif
- QCOMPARE(a.setNum(Q_INT64_C(123)), QString("123"));
- // 2^40 == 1099511627776
- QCOMPARE(a.setNum(Q_INT64_C(-1099511627776)), QString("-1099511627776"));
- QCOMPARE(a.setNum(Q_UINT64_C(1099511627776)), QString("1099511627776"));
- QCOMPARE(a.setNum(Q_INT64_C(9223372036854775807)), // LLONG_MAX
- QString("9223372036854775807"));
- QCOMPARE(a.setNum(-Q_INT64_C(9223372036854775807) - Q_INT64_C(1)),
- QString("-9223372036854775808"));
- QCOMPARE(a.setNum(Q_UINT64_C(18446744073709551615)), // ULLONG_MAX
- QString("18446744073709551615"));
- QCOMPARE(a.setNum(0.000000000931322574615478515625),QString("9.31323e-10"));
-
-// QCOMPARE(a.setNum(0.000000000931322574615478515625,'g',30),(QString)"9.31322574615478515625e-010");
-// QCOMPARE(a.setNum(0.000000000931322574615478515625,'f',30),(QString)"0.00000000093132257461547852");
-}
-
-void tst_QString::startsWith()
-{
- QString a;
- a = "AB";
- QVERIFY( a.startsWith("A") );
- QVERIFY( a.startsWith("AB") );
- QVERIFY( !a.startsWith("C") );
- QVERIFY( !a.startsWith("ABCDEF") );
- QVERIFY( a.startsWith("") );
- QVERIFY( a.startsWith(QString::null) );
- QVERIFY( a.startsWith('A') );
- QVERIFY( a.startsWith(QLatin1Char('A')) );
- QVERIFY( a.startsWith(QChar('A')) );
- QVERIFY( !a.startsWith('C') );
- QVERIFY( !a.startsWith(QChar()) );
- QVERIFY( !a.startsWith(QLatin1Char(0)) );
-
- QVERIFY( a.startsWith(QLatin1String("A")) );
- QVERIFY( a.startsWith(QLatin1String("AB")) );
- QVERIFY( !a.startsWith(QLatin1String("C")) );
- QVERIFY( !a.startsWith(QLatin1String("ABCDEF")) );
- QVERIFY( a.startsWith(QLatin1String("")) );
- QVERIFY( a.startsWith(QLatin1String(0)) );
-
- QVERIFY( a.startsWith("A", Qt::CaseSensitive) );
- QVERIFY( a.startsWith("A", Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith("a", Qt::CaseSensitive) );
- QVERIFY( a.startsWith("a", Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith("aB", Qt::CaseSensitive) );
- QVERIFY( a.startsWith("aB", Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith("C", Qt::CaseSensitive) );
- QVERIFY( !a.startsWith("C", Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith("c", Qt::CaseSensitive) );
- QVERIFY( !a.startsWith("c", Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith("abcdef", Qt::CaseInsensitive) );
- QVERIFY( a.startsWith("", Qt::CaseInsensitive) );
- QVERIFY( a.startsWith(QString::null, Qt::CaseInsensitive) );
- QVERIFY( a.startsWith('a', Qt::CaseInsensitive) );
- QVERIFY( a.startsWith('A', Qt::CaseInsensitive) );
- QVERIFY( a.startsWith(QLatin1Char('a'), Qt::CaseInsensitive) );
- QVERIFY( a.startsWith(QChar('a'), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith('c', Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QChar(), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseInsensitive) );
-
- QVERIFY( a.startsWith(QLatin1String("A"), Qt::CaseSensitive) );
- QVERIFY( a.startsWith(QLatin1String("A"), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QLatin1String("a"), Qt::CaseSensitive) );
- QVERIFY( a.startsWith(QLatin1String("a"), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QLatin1String("aB"), Qt::CaseSensitive) );
- QVERIFY( a.startsWith(QLatin1String("aB"), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QLatin1String("C"), Qt::CaseSensitive) );
- QVERIFY( !a.startsWith(QLatin1String("C"), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QLatin1String("c"), Qt::CaseSensitive) );
- QVERIFY( !a.startsWith(QLatin1String("c"), Qt::CaseInsensitive) );
- QVERIFY( !a.startsWith(QLatin1String("abcdef"), Qt::CaseInsensitive) );
- QVERIFY( a.startsWith(QLatin1String(""), Qt::CaseInsensitive) );
- QVERIFY( a.startsWith(QLatin1String(0), Qt::CaseInsensitive) );
- QVERIFY( a.startsWith('A', Qt::CaseSensitive) );
- QVERIFY( a.startsWith(QLatin1Char('A'), Qt::CaseSensitive) );
- QVERIFY( a.startsWith(QChar('A'), Qt::CaseSensitive) );
- QVERIFY( !a.startsWith('a', Qt::CaseSensitive) );
- QVERIFY( !a.startsWith(QChar(), Qt::CaseSensitive) );
- QVERIFY( !a.startsWith(QLatin1Char(0), Qt::CaseSensitive) );
-
-#define TEST_REF_STARTS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.startsWith(ref), yes); }
-
- TEST_REF_STARTS_WITH("A", true);
- TEST_REF_STARTS_WITH("AB", true);
- TEST_REF_STARTS_WITH("C", false);
- TEST_REF_STARTS_WITH("ABCDEF", false);
-#undef TEST_REF_STARTS_WITH
-
- a = "";
- QVERIFY( a.startsWith("") );
- QVERIFY( a.startsWith(QString::null) );
- QVERIFY( !a.startsWith("ABC") );
-
- QVERIFY( a.startsWith(QLatin1String("")) );
- QVERIFY( a.startsWith(QLatin1String(0)) );
- QVERIFY( !a.startsWith(QLatin1String("ABC")) );
-
- QVERIFY( !a.startsWith(QLatin1Char(0)) );
- QVERIFY( !a.startsWith(QLatin1Char('x')) );
- QVERIFY( !a.startsWith(QChar()) );
-
- a = QString();
- QVERIFY( !a.startsWith("") );
- QVERIFY( a.startsWith(QString::null) );
- QVERIFY( !a.startsWith("ABC") );
-
- QVERIFY( !a.startsWith(QLatin1String("")) );
- QVERIFY( a.startsWith(QLatin1String(0)) );
- QVERIFY( !a.startsWith(QLatin1String("ABC")) );
-
- QVERIFY( !a.startsWith(QLatin1Char(0)) );
- QVERIFY( !a.startsWith(QLatin1Char('x')) );
- QVERIFY( !a.startsWith(QChar()) );
-
- // this test is independent of encoding
- a = "\xc3\xa9";
- QVERIFY( a.startsWith("\xc3\xa9") );
- QVERIFY( !a.startsWith("\xc3\xa1") );
-
- // this one is dependent of encoding
- QVERIFY( a.startsWith("\xc3\x89", Qt::CaseInsensitive) );
-}
-
-void tst_QString::endsWith()
-{
- QString a;
- a = "AB";
- QVERIFY( a.endsWith("B") );
- QVERIFY( a.endsWith("AB") );
- QVERIFY( !a.endsWith("C") );
- QVERIFY( !a.endsWith("ABCDEF") );
- QVERIFY( a.endsWith("") );
- QVERIFY( a.endsWith(QString::null) );
- QVERIFY( a.endsWith('B') );
- QVERIFY( a.endsWith(QLatin1Char('B')) );
- QVERIFY( a.endsWith(QChar('B')) );
- QVERIFY( !a.endsWith('C') );
- QVERIFY( !a.endsWith(QChar()) );
- QVERIFY( !a.endsWith(QLatin1Char(0)) );
-
- QVERIFY( a.endsWith(QLatin1String("B")) );
- QVERIFY( a.endsWith(QLatin1String("AB")) );
- QVERIFY( !a.endsWith(QLatin1String("C")) );
- QVERIFY( !a.endsWith(QLatin1String("ABCDEF")) );
- QVERIFY( a.endsWith(QLatin1String("")) );
- QVERIFY( a.endsWith(QLatin1String(0)) );
-
- QVERIFY( a.endsWith("B", Qt::CaseSensitive) );
- QVERIFY( a.endsWith("B", Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith("b", Qt::CaseSensitive) );
- QVERIFY( a.endsWith("b", Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith("aB", Qt::CaseSensitive) );
- QVERIFY( a.endsWith("aB", Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith("C", Qt::CaseSensitive) );
- QVERIFY( !a.endsWith("C", Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith("c", Qt::CaseSensitive) );
- QVERIFY( !a.endsWith("c", Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith("abcdef", Qt::CaseInsensitive) );
- QVERIFY( a.endsWith("", Qt::CaseInsensitive) );
- QVERIFY( a.endsWith(QString::null, Qt::CaseInsensitive) );
- QVERIFY( a.endsWith('b', Qt::CaseInsensitive) );
- QVERIFY( a.endsWith('B', Qt::CaseInsensitive) );
- QVERIFY( a.endsWith(QLatin1Char('b'), Qt::CaseInsensitive) );
- QVERIFY( a.endsWith(QChar('b'), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith('c', Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QChar(), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseInsensitive) );
-
- QVERIFY( a.endsWith(QLatin1String("B"), Qt::CaseSensitive) );
- QVERIFY( a.endsWith(QLatin1String("B"), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QLatin1String("b"), Qt::CaseSensitive) );
- QVERIFY( a.endsWith(QLatin1String("b"), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QLatin1String("aB"), Qt::CaseSensitive) );
- QVERIFY( a.endsWith(QLatin1String("aB"), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QLatin1String("C"), Qt::CaseSensitive) );
- QVERIFY( !a.endsWith(QLatin1String("C"), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QLatin1String("c"), Qt::CaseSensitive) );
- QVERIFY( !a.endsWith(QLatin1String("c"), Qt::CaseInsensitive) );
- QVERIFY( !a.endsWith(QLatin1String("abcdef"), Qt::CaseInsensitive) );
- QVERIFY( a.endsWith(QLatin1String(""), Qt::CaseInsensitive) );
- QVERIFY( a.endsWith(QLatin1String(0), Qt::CaseInsensitive) );
- QVERIFY( a.endsWith('B', Qt::CaseSensitive) );
- QVERIFY( a.endsWith(QLatin1Char('B'), Qt::CaseSensitive) );
- QVERIFY( a.endsWith(QChar('B'), Qt::CaseSensitive) );
- QVERIFY( !a.endsWith('b', Qt::CaseSensitive) );
- QVERIFY( !a.endsWith(QChar(), Qt::CaseSensitive) );
- QVERIFY( !a.endsWith(QLatin1Char(0), Qt::CaseSensitive) );
-
-
-#define TEST_REF_ENDS_WITH(string, yes) { CREATE_REF(string); QCOMPARE(a.endsWith(ref), yes); }
- TEST_REF_ENDS_WITH(QLatin1String("B"), true);
- TEST_REF_ENDS_WITH(QLatin1String("AB"), true);
- TEST_REF_ENDS_WITH(QLatin1String("C"), false);
- TEST_REF_ENDS_WITH(QLatin1String("ABCDEF"), false);
- TEST_REF_ENDS_WITH(QLatin1String(""), true);
- TEST_REF_ENDS_WITH(QLatin1String(0), true);
-
-#undef TEST_REF_STARTS_WITH
-
- a = "";
- QVERIFY( a.endsWith("") );
- QVERIFY( a.endsWith(QString::null) );
- QVERIFY( !a.endsWith("ABC") );
- QVERIFY( !a.endsWith(QLatin1Char(0)) );
- QVERIFY( !a.endsWith(QLatin1Char('x')) );
- QVERIFY( !a.endsWith(QChar()) );
-
- QVERIFY( a.endsWith(QLatin1String("")) );
- QVERIFY( a.endsWith(QLatin1String(0)) );
- QVERIFY( !a.endsWith(QLatin1String("ABC")) );
-
- a = QString();
- QVERIFY( !a.endsWith("") );
- QVERIFY( a.endsWith(QString::null) );
- QVERIFY( !a.endsWith("ABC") );
-
- QVERIFY( !a.endsWith(QLatin1String("")) );
- QVERIFY( a.endsWith(QLatin1String(0)) );
- QVERIFY( !a.endsWith(QLatin1String("ABC")) );
-
- QVERIFY( !a.endsWith(QLatin1Char(0)) );
- QVERIFY( !a.endsWith(QLatin1Char('x')) );
- QVERIFY( !a.endsWith(QChar()) );
-
- // this test is independent of encoding
- a = "\xc3\xa9";
- QVERIFY( a.endsWith("\xc3\xa9") );
- QVERIFY( !a.endsWith("\xc3\xa1") );
-
- // this one is dependent of encoding
- QVERIFY( a.endsWith("\xc3\x89", Qt::CaseInsensitive) );
-}
-
-void tst_QString::check_QDataStream()
-{
- QString a;
- QByteArray ar;
- {
- QDataStream out(&ar,QIODevice::WriteOnly);
- out << QString("COMPARE Text");
- }
- {
- QDataStream in(&ar,QIODevice::ReadOnly);
- in >> a;
- QCOMPARE(a, QLatin1String("COMPARE Text"));
- }
-}
-
-void tst_QString::check_QTextStream()
-{
- QString a;
- QByteArray ar;
- {
- QTextStream out(&ar,QIODevice::WriteOnly);
- out << QString("This is COMPARE Text");
- }
- {
- QTextStream in(&ar,QIODevice::ReadOnly);
- in >> a;
- QCOMPARE(a, QLatin1String("This"));
- }
-}
-
-void tst_QString::check_QTextIOStream()
-{
- QString a;
- {
- a="";
- QTextStream ts(&a);
- ts << "pi \261= " << 3.125;
- QCOMPARE(a, QString::fromLatin1("pi \261= 3.125"));
- }
- {
- a="123 456";
- int x,y;
- QTextStream(&a) >> x >> y;
- QCOMPARE(x,123);
- QCOMPARE(y,456);
- }
-}
-
-void tst_QString::fromRawData()
-{
- const QChar ptr[] = { 0x1234, 0x0000 };
- QString cstr = QString::fromRawData(ptr, 1);
- QVERIFY(cstr.isDetached());
- QVERIFY(cstr.constData() == ptr);
- QVERIFY(cstr == QString(ptr, 1));
- cstr.squeeze();
- QVERIFY(cstr.constData() == ptr);
- cstr.detach();
- QVERIFY(cstr.size() == 1);
- QVERIFY(cstr.capacity() == 1);
- QVERIFY(cstr.constData() != ptr);
- QVERIFY(cstr.constData()[0] == QChar(0x1234));
- QVERIFY(cstr.constData()[1] == QChar(0x0000));
-}
-
-void tst_QString::setRawData()
-{
- const QChar ptr[] = { 0x1234, 0x0000 };
- const QChar ptr2[] = { 0x4321, 0x0000 };
- QString cstr;
-
- // This just tests the fromRawData() fallback
- QVERIFY(!cstr.isDetached());
- cstr.setRawData(ptr, 1);
- QVERIFY(cstr.isDetached());
- QVERIFY(cstr.constData() == ptr);
- QVERIFY(cstr == QString(ptr, 1));
-
- // This actually tests the recycling of the shared data object
- QString::DataPtr csd = cstr.data_ptr();
- cstr.setRawData(ptr2, 1);
- QVERIFY(cstr.isDetached());
- QVERIFY(cstr.constData() == ptr2);
- QVERIFY(cstr == QString(ptr2, 1));
- QVERIFY(cstr.data_ptr() == csd);
-
- // This tests the discarding of the shared data object
- cstr = "foo";
- QVERIFY(cstr.isDetached());
- QVERIFY(cstr.constData() != ptr2);
-
- // Another test of the fallback
- csd = cstr.data_ptr();
- cstr.setRawData(ptr2, 1);
- QVERIFY(cstr.isDetached());
- QVERIFY(cstr.constData() == ptr2);
- QVERIFY(cstr == QString(ptr2, 1));
- QVERIFY(cstr.data_ptr() != csd);
-}
-
-void tst_QString::fromStdString()
-{
- std::string stroustrup = "foo";
- QString eng = QString::fromStdString( stroustrup );
- QCOMPARE( eng, QString("foo") );
- const char cnull[] = "Embedded\0null\0character!";
- std::string stdnull( cnull, sizeof(cnull)-1 );
- QString qtnull = QString::fromStdString( stdnull );
- QCOMPARE( qtnull.size(), int(stdnull.size()) );
-}
-
-void tst_QString::toStdString()
-{
- QString nord = "foo";
- std::string stroustrup1 = nord.toStdString();
- QVERIFY( qstrcmp(stroustrup1.c_str(), "foo") == 0 );
- // For now, most QString constructors are also broken with respect
- // to embedded null characters, had to find one that works...
- const QChar qcnull[] = {
- 'E', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '\0',
- 'n', 'u', 'l', 'l', '\0',
- 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', '!'
- };
- QString qtnull( qcnull, sizeof(qcnull)/sizeof(QChar) );
- std::string stdnull = qtnull.toStdString();
- QCOMPARE( int(stdnull.size()), qtnull.size() );
-}
-
-void tst_QString::utf8()
-{
- QFETCH( QByteArray, utf8 );
- QFETCH( QString, res );
-
- QCOMPARE(res.toUtf8(), utf8);
-}
-
-void tst_QString::stringRef_utf8_data()
-{
- utf8_data();
-}
-
-void tst_QString::stringRef_utf8()
-{
- QFETCH( QByteArray, utf8 );
- QFETCH( QString, res );
-
- QStringRef ref(&res, 0, res.length());
- QCOMPARE( utf8, QByteArray(ref.toUtf8()) );
-}
-
-// copied to tst_QTextCodec::utf8Codec_data()
-void tst_QString::fromUtf8_data()
-{
- QTest::addColumn<QByteArray>("utf8");
- QTest::addColumn<QString>("res");
- QTest::addColumn<int>("len");
- QString str;
-
- QTest::newRow("str0") << QByteArray("abcdefgh") << QString("abcdefgh") << -1;
- QTest::newRow("str0-len") << QByteArray("abcdefgh") << QString("abc") << 3;
- QTest::newRow("str1") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
- << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") << -1;
- QTest::newRow("str1-len") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
- << QString::fromLatin1("\366\344\374\326\304") << 10;
-
- str += QChar(0x05e9);
- str += QChar(0x05d3);
- str += QChar(0x05d2);
- QTest::newRow("str2") << QByteArray("\327\251\327\223\327\222") << str << -1;
-
- str = QChar(0x05e9);
- QTest::newRow("str2-len") << QByteArray("\327\251\327\223\327\222") << str << 2;
-
- str = QChar(0x20ac);
- str += " some text";
- QTest::newRow("str3") << QByteArray("\342\202\254 some text") << str << -1;
-
- str = QChar(0x20ac);
- str += " some ";
- QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9;
-
- // test that QString::fromUtf8 suppresses an initial BOM, but not a ZWNBSP
- str = "hello";
- QByteArray bom("\357\273\277");
- QTest::newRow("bom0") << bom << QString() << 3;
- QTest::newRow("bom1") << bom + "hello" << str << -1;
- QTest::newRow("bom+zwnbsp0") << bom + bom << QString(QChar(0xfeff)) << -1;
- QTest::newRow("bom+zwnbsp1") << bom + "hello" + bom << str + QChar(0xfeff) << -1;
-
- str = "hello";
- str += QChar::ReplacementCharacter;
- str += QChar(0x68);
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += QChar(0x61);
- str += QChar::ReplacementCharacter;
- QTest::newRow("invalid utf8") << QByteArray("hello\344h\344\344\366\344a\304") << str << -1;
- QTest::newRow("invalid utf8-len") << QByteArray("hello\344h\344\344\366\344a\304") << QString("hello") << 5;
-
- str = "Prohl";
- str += QChar::ReplacementCharacter;
- str += QChar::ReplacementCharacter;
- str += "e";
- str += QChar::ReplacementCharacter;
- str += " plugin";
- str += QChar::ReplacementCharacter;
- str += " Netscape";
-
- QTest::newRow("invalid utf8 2") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << str << -1;
- QTest::newRow("invalid utf8-len 2") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << QString("") << 0;
-
- QTest::newRow("null-1") << QByteArray() << QString() << -1;
- QTest::newRow("null0") << QByteArray() << QString() << 0;
- QTest::newRow("null5") << QByteArray() << QString() << 5;
- QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << QString() << -1;
- QTest::newRow("empty0") << QByteArray() << QString() << 0;
- QTest::newRow("empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1("\0abcd", 5) << 5;
- QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab") << -1;
- QTest::newRow("other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab\0cd", 5) << 5;
-
- str = "Old Italic: ";
- str += QChar(0xd800);
- str += QChar(0xdf00);
- str += QChar(0xd800);
- str += QChar(0xdf01);
- str += QChar(0xd800);
- str += QChar(0xdf02);
- str += QChar(0xd800);
- str += QChar(0xdf03);
- str += QChar(0xd800);
- str += QChar(0xdf04);
- QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str << -1;
-
- QTest::newRow("surrogate-len") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str.left(16) << 20;
-
-}
-
-void tst_QString::fromUtf8()
-{
- QFETCH(QByteArray, utf8);
- QFETCH(QString, res);
- QFETCH(int, len);
-
- QCOMPARE(QString::fromUtf8(utf8.isNull() ? 0 : utf8.data(), len), res);
-}
-
-void tst_QString::nullFromUtf8()
-{
- QString a;
- a = QString::fromUtf8(0);
- QVERIFY(a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromUtf8("");
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromUtf8(QByteArray());
- QVERIFY(a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromUtf8(QByteArray(""));
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
-}
-
-void tst_QString::fromLocal8Bit_data()
-{
- QTest::addColumn<QByteArray>("local8Bit");
- QTest::addColumn<int>("len");
- QTest::addColumn<QString>("result");
-
- //QTest::newRow("nullString") << QByteArray() << -1 << QString();
- //QTest::newRow("emptyString") << QByteArray("") << -1 << QString("");
- //QTest::newRow("string") << QByteArray("test") << -1 << QString("test");
- //QTest::newRow("stringlen0") << QByteArray("test") << 0 << QString("");
- //QTest::newRow("stringlen3") << QByteArray("test") << 3 << QString("tes");
- QTest::newRow("stringlen99") << QByteArray("test\0foo", 8) << 8 << QString::fromLatin1("test\0foo", 8);
-
- QByteArray longQByteArray;
- QString longQString;
-
- for (int l=0;l<111;l++) {
- longQByteArray = longQByteArray + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- longQString += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- }
-
- //QTest::newRow("longString") << longQByteArray << -1 << longQString;
- //QTest::newRow("longStringlen0") << longQByteArray << 0 << QString("");
- //QTest::newRow("longStringlen3") << longQByteArray << 3 << QString("aaa");
- //QTest::newRow("someNonAlphaChars") << QByteArray("d:/this/is/a/test.h") << -1 << QString("d:/this/is/a/test.h");
-
- //QTest::newRow("null-1") << QByteArray() << -1 << QString();
- //QTest::newRow("null0") << QByteArray() << 0 << QString();
- //QTest::newRow("null5") << QByteArray() << 5 << QString();
- //QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << -1 << QString();
- //QTest::newRow("empty0") << QByteArray() << 0 << QString();
- //QTest::newRow("empty5") << QByteArray("\0abcd", 5) << 5 << QString::fromAscii("\0abcd", 5);
- //QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << -1 << QString::fromAscii("ab");
- //QTest::newRow("other5") << QByteArray("ab\0cd", 5) << 5 << QString::fromAscii("ab\0cd", 5);
-}
-
-void tst_QString::fromLocal8Bit()
-{
- QFETCH(QByteArray, local8Bit);
- QFETCH(int, len);
- QFETCH(QString, result);
-
- QCOMPARE(QString::fromLocal8Bit(local8Bit.isNull() ? 0 : local8Bit.data(), len).length(),
- result.length());
- QCOMPARE(QString::fromLocal8Bit(local8Bit.isNull() ? 0 : local8Bit.data(), len), result);
-}
-
-void tst_QString::local8Bit_data()
-{
- QTest::addColumn<QString>("local8Bit");
- QTest::addColumn<QByteArray>("result");
-
- QTest::newRow("nullString") << QString() << QByteArray();
- QTest::newRow("emptyString") << QString("") << QByteArray("");
- QTest::newRow("string") << QString("test") << QByteArray("test");
-
- QByteArray longQByteArray;
- QString longQString;
-
- for (int l=0;l<111;l++) {
- longQByteArray = longQByteArray + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- longQString += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- }
-
- QTest::newRow("longString") << longQString << longQByteArray;
- QTest::newRow("someNonAlphaChars") << QString("d:/this/is/a/test.h") << QByteArray("d:/this/is/a/test.h");
-}
-
-void tst_QString::local8Bit()
-{
- QFETCH(QString, local8Bit);
- QFETCH(QByteArray, result);
-
- QCOMPARE(local8Bit.toLocal8Bit(), QByteArray(result));
-}
-
-void tst_QString::invalidToLocal8Bit_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<QByteArray>("expect"); // Initial validly-converted prefix
-
- {
- const QChar malformed[] = { 'A', 0xd800, 'B', 0 };
- const char expected[] = "A";
- QTest::newRow("LoneHighSurrogate")
- << QString(malformed, sizeof(malformed) / sizeof(QChar))
- // Don't include the terminating '\0' of expected:
- << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
- }
- {
- const QChar malformed[] = { 'A', 0xdc00, 'B', 0 };
- const char expected[] = "A";
- QTest::newRow("LoneLowSurrogate")
- << QString(malformed, sizeof(malformed) / sizeof(QChar))
- << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
- }
- {
- const QChar malformed[] = { 'A', 0xd800, 0xd801, 'B', 0 };
- const char expected[] = "A";
- QTest::newRow("DoubleHighSurrogate")
- << QString(malformed, sizeof(malformed) / sizeof(QChar))
- << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
- }
- {
- const QChar malformed[] = { 'A', 0xdc00, 0xdc01, 'B', 0 };
- const char expected[] = "A";
- QTest::newRow("DoubleLowSurrogate")
- << QString(malformed, sizeof(malformed) / sizeof(QChar))
- << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
- }
- {
- const QChar malformed[] = { 'A', 0xdc00, 0xd800, 'B', 0 };
- const char expected[] = "A";
- QTest::newRow("ReversedSurrogates") // low before high
- << QString(malformed, sizeof(malformed) / sizeof(QChar))
- << QByteArray(expected, sizeof(expected) / sizeof(char) - 1);
- }
-}
-
-void tst_QString::invalidToLocal8Bit()
-{
- QFETCH(QString, unicode);
- QFETCH(QByteArray, expect);
- QByteArray local = unicode.toLocal8Bit();
- /*
- The main concern of this test is to check that any error-reporting that
- toLocal8Bit() prompts on failure isn't dependent on outputting the data
- it's converting via toLocal8Bit(), which would be apt to recurse. So the
- real purpose of this QVERIFY(), for all that we should indeed check we get
- the borked output that matches what we can reliably expect (despite
- variation in how codecs respond to errors), is to verify that we got here
- - i.e. we didn't crash in such a recursive stack over-flow.
- */
- QVERIFY(local.startsWith(expect));
-}
-
-void tst_QString::nullFromLocal8Bit()
-{
- QString a;
- a = QString::fromLocal8Bit(0);
- QVERIFY(a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromLocal8Bit("");
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromLocal8Bit(QByteArray());
- QVERIFY(a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromLocal8Bit(QByteArray(""));
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
-}
-
-void tst_QString::stringRef_local8Bit_data()
-{
- local8Bit_data();
-}
-
-void tst_QString::stringRef_local8Bit()
-{
- QFETCH(QString, local8Bit);
- QFETCH(QByteArray, result);
-
- QStringRef ref(&local8Bit, 0, local8Bit.length());
- QCOMPARE(ref.toLocal8Bit(), QByteArray(result));
-}
-
-void tst_QString::fromLatin1Roundtrip_data()
-{
- QTest::addColumn<QByteArray>("latin1");
- QTest::addColumn<QString>("unicode");
-
- QTest::newRow("null") << QByteArray() << QString();
- QTest::newRow("empty") << QByteArray("") << "";
-
- static const ushort unicode1[] = { 'H', 'e', 'l', 'l', 'o', 1, '\r', '\n', 0x7f };
- QTest::newRow("ascii-only") << QByteArray("Hello") << QString::fromUtf16(unicode1, 5);
- QTest::newRow("ascii+control") << QByteArray("Hello\1\r\n\x7f") << QString::fromUtf16(unicode1, 9);
-
- static const ushort unicode3[] = { 'a', 0, 'z' };
- QTest::newRow("ascii+nul") << QByteArray("a\0z", 3) << QString::fromUtf16(unicode3, 3);
-
- static const ushort unicode4[] = { 0x80, 0xc0, 0xff };
- QTest::newRow("non-ascii") << QByteArray("\x80\xc0\xff") << QString::fromUtf16(unicode4, 3);
-}
-
-void tst_QString::fromLatin1Roundtrip()
-{
- QFETCH(QByteArray, latin1);
- QFETCH(QString, unicode);
-
- // Qt Test safety check:
- QCOMPARE(latin1.isNull(), unicode.isNull());
- QCOMPARE(latin1.isEmpty(), unicode.isEmpty());
- QCOMPARE(latin1.length(), unicode.length());
-
- if (!latin1.isEmpty())
- while (latin1.length() < 128) {
- latin1 += latin1;
- unicode += unicode;
- }
-
- // fromLatin1
- QCOMPARE(QString::fromLatin1(latin1, latin1.length()).length(), unicode.length());
- QCOMPARE(QString::fromLatin1(latin1, latin1.length()), unicode);
-
- // and back:
- QCOMPARE(unicode.toLatin1().length(), latin1.length());
- QCOMPARE(unicode.toLatin1(), latin1);
-}
-
-void tst_QString::toLatin1Roundtrip_data()
-{
- QTest::addColumn<QByteArray>("latin1");
- QTest::addColumn<QString>("unicodesrc");
- QTest::addColumn<QString>("unicodedst");
-
- QTest::newRow("null") << QByteArray() << QString() << QString();
- QTest::newRow("empty") << QByteArray("") << "" << "";
-
- static const ushort unicode1[] = { 'H', 'e', 'l', 'l', 'o', 1, '\r', '\n', 0x7f };
- QTest::newRow("ascii-only") << QByteArray("Hello") << QString::fromUtf16(unicode1, 5) << QString::fromUtf16(unicode1, 5);
- QTest::newRow("ascii+control") << QByteArray("Hello\1\r\n\x7f") << QString::fromUtf16(unicode1, 9) << QString::fromUtf16(unicode1, 9);
-
- static const ushort unicode3[] = { 'a', 0, 'z' };
- QTest::newRow("ascii+nul") << QByteArray("a\0z", 3) << QString::fromUtf16(unicode3, 3) << QString::fromUtf16(unicode3, 3);
-
- static const ushort unicode4[] = { 0x80, 0xc0, 0xff };
- QTest::newRow("non-ascii") << QByteArray("\x80\xc0\xff") << QString::fromUtf16(unicode4, 3) << QString::fromUtf16(unicode4, 3);
-
- static const ushort unicodeq[] = { '?', '?', '?', '?', '?' };
- const QString questionmarks = QString::fromUtf16(unicodeq, 5);
-
- static const ushort unicode5[] = { 0x100, 0x101, 0x17f, 0x7f00, 0x7f7f };
- QTest::newRow("non-latin1a") << QByteArray("?????") << QString::fromUtf16(unicode5, 5) << questionmarks;
-
- static const ushort unicode6[] = { 0x180, 0x1ff, 0x8001, 0x8080, 0xfffc };
- QTest::newRow("non-latin1b") << QByteArray("?????") << QString::fromUtf16(unicode6, 5) << questionmarks;
-}
-
-void tst_QString::toLatin1Roundtrip()
-{
- QFETCH(QByteArray, latin1);
- QFETCH(QString, unicodesrc);
- QFETCH(QString, unicodedst);
-
- // Qt Test safety check:
- QCOMPARE(latin1.isNull(), unicodesrc.isNull());
- QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty());
- QCOMPARE(latin1.length(), unicodesrc.length());
- QCOMPARE(latin1.isNull(), unicodedst.isNull());
- QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty());
- QCOMPARE(latin1.length(), unicodedst.length());
-
- if (!latin1.isEmpty())
- while (latin1.length() < 128) {
- latin1 += latin1;
- unicodesrc += unicodesrc;
- unicodedst += unicodedst;
- }
-
- // toLatin1
- QCOMPARE(unicodesrc.toLatin1().length(), latin1.length());
- QCOMPARE(unicodesrc.toLatin1(), latin1);
-
- // and back:
- QCOMPARE(QString::fromLatin1(latin1, latin1.length()).length(), unicodedst.length());
- QCOMPARE(QString::fromLatin1(latin1, latin1.length()), unicodedst);
-
- // try the rvalue version of toLatin1()
- QString s = unicodesrc;
- QCOMPARE(qMove(s).toLatin1(), latin1);
-
- // and verify that the moved-from object can still be used
- s = "foo";
- s.clear();
-}
-
-void tst_QString::stringRef_toLatin1Roundtrip_data()
-{
- toLatin1Roundtrip_data();
-}
-
-void tst_QString::stringRef_toLatin1Roundtrip()
-{
- QFETCH(QByteArray, latin1);
- QFETCH(QString, unicodesrc);
- QFETCH(QString, unicodedst);
-
- // Qt Test safety check:
- QCOMPARE(latin1.isNull(), unicodesrc.isNull());
- QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty());
- QCOMPARE(latin1.length(), unicodesrc.length());
- QCOMPARE(latin1.isNull(), unicodedst.isNull());
- QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty());
- QCOMPARE(latin1.length(), unicodedst.length());
-
- if (!latin1.isEmpty())
- while (latin1.length() < 128) {
- latin1 += latin1;
- unicodesrc += unicodesrc;
- unicodedst += unicodedst;
- }
-
- // toLatin1
- QStringRef src(&unicodesrc, 0, unicodesrc.length());
- QCOMPARE(src.toLatin1().length(), latin1.length());
- QCOMPARE(src.toLatin1(), latin1);
-}
-
-void tst_QString::fromLatin1()
-{
- QString a;
- a = QString::fromLatin1( 0 );
- QVERIFY( a.isNull() );
- QVERIFY( a.isEmpty() );
- a = QString::fromLatin1( "" );
- QVERIFY( !a.isNull() );
- QVERIFY( a.isEmpty() );
- a = QString::fromLatin1(QByteArray());
- QVERIFY(a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromLatin1(QByteArray(""));
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
-
- a = QString::fromLatin1(0, 0);
- QVERIFY(a.isNull());
- a = QString::fromLatin1(0, 5);
- QVERIFY(a.isNull());
- a = QString::fromLatin1("\0abcd", 0);
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromLatin1("\0abcd", 5);
- QVERIFY(a.size() == 5);
-}
-
-void tst_QString::fromAscii()
-{
- QString a;
- a = QString::fromAscii( 0 );
- QVERIFY( a.isNull() );
- QVERIFY( a.isEmpty() );
- a = QString::fromAscii( "" );
- QVERIFY( !a.isNull() );
- QVERIFY( a.isEmpty() );
-
- a = QString::fromAscii(0, 0);
- QVERIFY(a.isNull());
- a = QString::fromAscii(0, 5);
- QVERIFY(a.isNull());
- a = QString::fromAscii("\0abcd", 0);
- QVERIFY(!a.isNull());
- QVERIFY(a.isEmpty());
- a = QString::fromAscii("\0abcd", 5);
- QVERIFY(a.size() == 5);
-}
-
-void tst_QString::fromUcs4()
-{
- const uint *null = 0;
- QString s;
- s = QString::fromUcs4( null );
- QVERIFY( s.isNull() );
- QCOMPARE( s.size(), 0 );
- s = QString::fromUcs4( null, 0 );
- QVERIFY( s.isNull() );
- QCOMPARE( s.size(), 0 );
- s = QString::fromUcs4( null, 5 );
- QVERIFY( s.isNull() );
- QCOMPARE( s.size(), 0 );
-
- uint nil = '\0';
- s = QString::fromUcs4( &nil );
- QVERIFY( !s.isNull() );
- QCOMPARE( s.size(), 0 );
- s = QString::fromUcs4( &nil, 0 );
- QVERIFY( !s.isNull() );
- QCOMPARE( s.size(), 0 );
-
- uint bmp = 'a';
- s = QString::fromUcs4( &bmp, 1 );
- QVERIFY( !s.isNull() );
- QCOMPARE( s.size(), 1 );
-
- uint smp = 0x10000;
- s = QString::fromUcs4( &smp, 1 );
- QVERIFY( !s.isNull() );
- QCOMPARE( s.size(), 2 );
-
-#ifdef Q_COMPILER_UNICODE_STRINGS
- static const char32_t str1[] = U"Hello Unicode World";
- s = QString::fromUcs4(str1, sizeof(str1) / sizeof(str1[0]) - 1);
- QCOMPARE(s, QString("Hello Unicode World"));
-
- s = QString::fromUcs4(str1);
- QCOMPARE(s, QString("Hello Unicode World"));
-
- s = QString::fromUcs4(str1, 5);
- QCOMPARE(s, QString("Hello"));
-
- s = QString::fromUcs4(U"\u221212\U000020AC\U00010000");
- QCOMPARE(s, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
-#endif
-}
-
-void tst_QString::toUcs4()
-{
- QString s;
- QVector<uint> ucs4;
- QCOMPARE( s.toUcs4().size(), 0 );
-
- static const QChar bmp = QLatin1Char('a');
- s = QString(&bmp, 1);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 1 );
- QCOMPARE( ucs4.at(0), 0x0061u );
-
-#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
-
- static const QChar smp[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
- s = QSTRING_FROM_QCHARARRAY(smp);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 1 );
- QCOMPARE( ucs4.at(0), 0x10000u );
-
- static const QChar smp2[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000), QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
- s = QSTRING_FROM_QCHARARRAY(smp2);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 2 );
- QCOMPARE( ucs4.at(0), 0x10000u );
- QCOMPARE( ucs4.at(1), 0x10000u );
-
- static const QChar invalid_01[] = { QChar(0xd800) };
- s = QSTRING_FROM_QCHARARRAY(invalid_01);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 1 );
- QCOMPARE( ucs4.at(0), 0xFFFDu );
-
- static const QChar invalid_02[] = { QChar(0xdc00) };
- s = QSTRING_FROM_QCHARARRAY(invalid_02);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 1 );
- QCOMPARE( ucs4.at(0), 0xFFFDu );
-
- static const QChar invalid_03[] = { QLatin1Char('a'), QChar(0xd800), QLatin1Char('b') };
- s = QSTRING_FROM_QCHARARRAY(invalid_03);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 3 );
- QCOMPARE( ucs4.at(0), 0x0061u );
- QCOMPARE( ucs4.at(1), 0xFFFDu );
- QCOMPARE( ucs4.at(2), 0x0062u );
-
- static const QChar invalid_04[] = { QLatin1Char('a'), QChar(0xdc00), QLatin1Char('b') };
- s = QSTRING_FROM_QCHARARRAY(invalid_04);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 3 );
- QCOMPARE( ucs4.at(0), 0x0061u );
- QCOMPARE( ucs4.at(1), 0xFFFDu );
- QCOMPARE( ucs4.at(2), 0x0062u );
-
- static const QChar invalid_05[] = { QLatin1Char('a'), QChar(0xd800), QChar(0xd800), QLatin1Char('b') };
- s = QSTRING_FROM_QCHARARRAY(invalid_05);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 4 );
- QCOMPARE( ucs4.at(0), 0x0061u );
- QCOMPARE( ucs4.at(1), 0xFFFDu );
- QCOMPARE( ucs4.at(2), 0xFFFDu );
- QCOMPARE( ucs4.at(3), 0x0062u );
-
- static const QChar invalid_06[] = { QLatin1Char('a'), QChar(0xdc00), QChar(0xdc00), QLatin1Char('b') };
- s = QSTRING_FROM_QCHARARRAY(invalid_06);
- ucs4 = s.toUcs4();
- QCOMPARE( ucs4.size(), 4 );
- QCOMPARE( ucs4.at(0), 0x0061u );
- QCOMPARE( ucs4.at(1), 0xFFFDu );
- QCOMPARE( ucs4.at(2), 0xFFFDu );
- QCOMPARE( ucs4.at(3), 0x0062u );
-
-#undef QSTRING_FROM_QCHARARRAY
-
-}
-
-void tst_QString::arg()
-{
-/*
- Warning: If any of these test fails, the warning given by Qt Test
- is all messed up, because Qt Test itself uses QString::arg().
-*/
-
- TransientDefaultLocale transient(QString("de_DE"));
-
- QString s4( "[%0]" );
- QString s5( "[%1]" );
- QString s6( "[%3]" );
- QString s7( "[%9]" );
- QString s8( "[%0 %1]" );
- QString s9( "[%0 %3]" );
- QString s10( "[%1 %2 %3]" );
- QString s11( "[%9 %3 %0]" );
- QString s12( "[%9 %1 %3 %9 %0 %8]" );
- QString s13( "%1% %x%c%2 %d%2-%" );
- QString s14( "%1%2%3" );
-
- QCOMPARE( s4.arg("foo"), QLatin1String("[foo]") );
- QCOMPARE( s5.arg(QLatin1String("foo")), QLatin1String("[foo]") );
- QCOMPARE( s6.arg(QStringViewLiteral("foo")), QLatin1String("[foo]") );
- QCOMPARE( s7.arg("foo"), QLatin1String("[foo]") );
- QCOMPARE( s8.arg("foo"), QLatin1String("[foo %1]") );
- QCOMPARE( s8.arg("foo").arg("bar"), QLatin1String("[foo bar]") );
- QCOMPARE( s8.arg("foo", "bar"), QLatin1String("[foo bar]") );
- QCOMPARE( s9.arg("foo"), QLatin1String("[foo %3]") );
- QCOMPARE( s9.arg("foo").arg("bar"), QLatin1String("[foo bar]") );
- QCOMPARE( s9.arg("foo", "bar"), QLatin1String("[foo bar]") );
- QCOMPARE( s10.arg("foo"), QLatin1String("[foo %2 %3]") );
- QCOMPARE( s10.arg("foo").arg("bar"), QLatin1String("[foo bar %3]") );
- QCOMPARE( s10.arg("foo", "bar"), QLatin1String("[foo bar %3]") );
- QCOMPARE( s10.arg("foo").arg("bar").arg("baz"), QLatin1String("[foo bar baz]") );
- QCOMPARE( s10.arg("foo", "bar", "baz"), QLatin1String("[foo bar baz]") );
- QCOMPARE( s11.arg("foo"), QLatin1String("[%9 %3 foo]") );
- QCOMPARE( s11.arg("foo").arg("bar"), QLatin1String("[%9 bar foo]") );
- QCOMPARE( s11.arg("foo", "bar"), QLatin1String("[%9 bar foo]") );
- QCOMPARE( s11.arg("foo").arg("bar").arg("baz"), QLatin1String("[baz bar foo]") );
- QCOMPARE( s11.arg("foo", "bar", "baz"), QLatin1String("[baz bar foo]") );
- QCOMPARE( s12.arg("a").arg("b").arg("c").arg("d").arg("e"),
- QLatin1String("[e b c e a d]") );
- QCOMPARE( s12.arg("a", "b", "c", "d").arg("e"), QLatin1String("[e b c e a d]") );
- QCOMPARE( s12.arg("a").arg("b", "c", "d", "e"), QLatin1String("[e b c e a d]") );
- QCOMPARE( s13.arg("alpha").arg("beta"),
- QLatin1String("alpha% %x%cbeta %dbeta-%") );
- QCOMPARE( s13.arg("alpha", "beta"), QLatin1String("alpha% %x%cbeta %dbeta-%") );
- QCOMPARE( s14.arg("a", "b", "c"), QLatin1String("abc") );
- QCOMPARE( s8.arg("%1").arg("foo"), QLatin1String("[foo foo]") );
- QCOMPARE( s8.arg("%1", "foo"), QLatin1String("[%1 foo]") );
- QCOMPARE( s4.arg("foo", 2), QLatin1String("[foo]") );
- QCOMPARE( s4.arg("foo", -2), QLatin1String("[foo]") );
- QCOMPARE( s4.arg("foo", 10), QLatin1String("[ foo]") );
- QCOMPARE( s4.arg("foo", -10), QLatin1String("[foo ]") );
-
- QString firstName( "James" );
- QString lastName( "Bond" );
- QString fullName = QString( "My name is %2, %1 %2" )
- .arg( firstName ).arg( lastName );
- QCOMPARE( fullName, QLatin1String("My name is Bond, James Bond") );
-
- // number overloads
- QCOMPARE( s4.arg(0), QLatin1String("[0]") );
- QCOMPARE( s4.arg(-1), QLatin1String("[-1]") );
- QCOMPARE( s4.arg(4294967295UL), QLatin1String("[4294967295]") ); // ULONG_MAX 32
- QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX
- QLatin1String("[9223372036854775807]") );
-
- QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0");
- QCOMPARE( QString().arg(0), QString() );
- QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"\" , 0");
- QCOMPARE( QString("").arg(0), QString("") );
- QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \" \" , 0");
- QCOMPARE( QString(" ").arg(0), QLatin1String(" ") );
- QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%\" , 0");
- QCOMPARE( QString("%").arg(0), QLatin1String("%") );
- QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%%\" , 0");
- QCOMPARE( QString("%%").arg(0), QLatin1String("%%") );
- QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: \"%%%\" , 0");
- QCOMPARE( QString("%%%").arg(0), QLatin1String("%%%") );
- QCOMPARE( QString("%%%1%%%2").arg("foo").arg("bar"), QLatin1String("%%foo%%bar") );
-
- QCOMPARE( QString("%1").arg("hello", -10), QLatin1String("hello ") );
- QCOMPARE( QString("%1").arg(QLatin1String("hello"), -5), QLatin1String("hello") );
- QCOMPARE( QString("%1").arg(QStringViewLiteral("hello"), -2), QLatin1String("hello") );
- QCOMPARE( QString("%1").arg("hello", 0), QLatin1String("hello") );
- QCOMPARE( QString("%1").arg(QLatin1String("hello"), 2), QLatin1String("hello") );
- QCOMPARE( QString("%1").arg(QStringViewLiteral("hello"), 5), QLatin1String("hello") );
- QCOMPARE( QString("%1").arg("hello", 10), QLatin1String(" hello") );
- QCOMPARE( QString("%1%1").arg("hello"), QLatin1String("hellohello") );
- QCOMPARE( QString("%2%1").arg("hello"), QLatin1String("%2hello") );
- QCOMPARE( QString("%1%1").arg(QString::null), QLatin1String("") );
- QCOMPARE( QString("%2%1").arg(""), QLatin1String("%2") );
-
- QCOMPARE( QString("%2 %L1").arg(12345.6789).arg(12345.6789),
- QLatin1String("12345.7 12.345,7") );
- QCOMPARE( QString("[%2] [%L1]").arg(12345.6789, 9).arg(12345.6789, 9),
- QLatin1String("[ 12345.7] [ 12.345,7]") );
- QCOMPARE( QString("[%2] [%L1]").arg(12345.6789, 9, 'g', 7).arg(12345.6789, 9, 'g', 7),
- QLatin1String("[ 12345.68] [12.345,68]") );
- QCOMPARE( QString("[%2] [%L1]").arg(12345.6789, 10, 'g', 7, QLatin1Char('0')).arg(12345.6789, 10, 'g', 7, QLatin1Char('0')),
- QLatin1String("[0012345.68] [012.345,68]") );
-
- QCOMPARE( QString("%2 %L1").arg(123456789).arg(123456789),
- QLatin1String("123456789 123.456.789") );
- QCOMPARE( QString("[%2] [%L1]").arg(123456789, 12).arg(123456789, 12),
- QLatin1String("[ 123456789] [ 123.456.789]") );
- QCOMPARE( QString("[%2] [%L1]").arg(123456789, 13, 10, QLatin1Char('0')).arg(123456789, 12, 10, QLatin1Char('0')),
- QLatin1String("[000123456789] [00123.456.789]") );
- QCOMPARE( QString("[%2] [%L1]").arg(123456789, 13, 16, QLatin1Char('0')).arg(123456789, 12, 16, QLatin1Char('0')),
- QLatin1String("[0000075bcd15] [00000075bcd15]") );
-
- QCOMPARE( QString("%L2 %L1 %3").arg(12345.7).arg(123456789).arg('c'),
- QLatin1String("123.456.789 12.345,7 c") );
-
- // multi-digit replacement
- QString input("%%%L0 %1 %02 %3 %4 %5 %L6 %7 %8 %%% %090 %10 %11 %L12 %14 %L9888 %9999 %%%%%%%L");
- input = input.arg("A").arg("B").arg("C")
- .arg("D").arg("E").arg("f")
- .arg("g").arg("h").arg("i").arg("j")
- .arg("k").arg("l").arg("m")
- .arg("n").arg("o").arg("p");
-
- QCOMPARE(input, QLatin1String("%%A B C D E f g h i %%% j0 k l m n o88 p99 %%%%%%%L"));
-
- QString str("%1 %2 %3 %4 %5 %6 %7 %8 %9 foo %10 %11 bar");
- str = str.arg("one", "2", "3", "4", "5", "6", "7", "8", "9");
- str = str.arg("ahoy", "there");
- QCOMPARE(str, QLatin1String("one 2 3 4 5 6 7 8 9 foo ahoy there bar"));
-
- QString str2("%123 %234 %345 %456 %567 %999 %1000 %1230");
- str2 = str2.arg("A", "B", "C", "D", "E", "F");
- QCOMPARE(str2, QLatin1String("A B C D E F %1000 %1230"));
-
- QCOMPARE(QString("%1").arg(-1, 3, 10, QChar('0')), QLatin1String("-01"));
- QCOMPARE(QString("%1").arg(-100, 3, 10, QChar('0')), QLatin1String("-100"));
- QCOMPARE(QString("%1").arg(-1, 3, 10, QChar(' ')), QLatin1String(" -1"));
- QCOMPARE(QString("%1").arg(-100, 3, 10, QChar(' ')), QLatin1String("-100"));
- QCOMPARE(QString("%1").arg(1U, 3, 10, QChar(' ')), QLatin1String(" 1"));
- QCOMPARE(QString("%1").arg(1000U, 3, 10, QChar(' ')), QLatin1String("1000"));
- QCOMPARE(QString("%1").arg(-1, 3, 10, QChar('x')), QLatin1String("x-1"));
- QCOMPARE(QString("%1").arg(-100, 3, 10, QChar('x')), QLatin1String("-100"));
- QCOMPARE(QString("%1").arg(1U, 3, 10, QChar('x')), QLatin1String("xx1"));
- QCOMPARE(QString("%1").arg(1000U, 3, 10, QChar('x')), QLatin1String("1000"));
-
- QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar('0')), QLatin1String("-01"));
- QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar('0')), QLatin1String("-100"));
- QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar(' ')), QLatin1String(" -1"));
- QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar(' ')), QLatin1String("-100"));
- QCOMPARE(QString("%1").arg(1., 3, 'g', -1, QChar('x')), QLatin1String("xx1"));
- QCOMPARE(QString("%1").arg(1000., 3, 'g', -1, QChar('x')), QLatin1String("1000"));
- QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar('x')), QLatin1String("x-1"));
- QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar('x')), QLatin1String("-100"));
-
- transient.revise(QString("ar"));
- QCOMPARE( QString("%L1").arg(12345.6789, 10, 'g', 7, QLatin1Char('0')),
- QString::fromUtf8("\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xac\xd9\xa3\xd9\xa4\xd9\xa5\xd9\xab\xd9\xa6\xd9\xa8") ); // "٠١٢٬٣٤٥٫٦٨"
- QCOMPARE( QString("%L1").arg(123456789, 13, 10, QLatin1Char('0')),
- QString("\xd9\xa0\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xa3\xd9\xac\xd9\xa4\xd9\xa5\xd9\xa6\xd9\xac\xd9\xa7\xd9\xa8\xd9\xa9") ); // ٠٠١٢٣٬٤٥٦٬٧٨٩
-}
-
-void tst_QString::number()
-{
- QCOMPARE( QString::number(int(0)), QLatin1String("0") );
- QCOMPARE( QString::number((unsigned int)(11)), QLatin1String("11") );
- QCOMPARE( QString::number(-22L), QLatin1String("-22") );
- QCOMPARE( QString::number(333UL), QLatin1String("333") );
- QCOMPARE( QString::number(4.4), QLatin1String("4.4") );
- QCOMPARE( QString::number(Q_INT64_C(-555)), QLatin1String("-555") );
- QCOMPARE( QString::number(Q_UINT64_C(6666)), QLatin1String("6666") );
-
-#ifndef QT_NO_DOUBLECONVERSION // snprintf_l is too stupid for this
- QCOMPARE( QString::number(12.05, 'f', 1), QString("12.1") );
- QCOMPARE( QString::number(12.5, 'f', 0), QString("13") );
-#endif
-}
-
-void tst_QString::doubleOut()
-{
- // Regression test for QTBUG-63620; the first two paths lost the exponent's
- // leading 0 at 5.7; C's printf() family guarantee a two-digit exponent (in
- // contrast with ECMAScript, which forbids leading zeros).
- const QString expect(QStringLiteral("1e-06"));
- const double micro = 1e-6;
- QCOMPARE(QString::number(micro), expect);
- QCOMPARE(QString("%1").arg(micro), expect);
- {
- QString text;
- text.sprintf("%g", micro);
- QCOMPARE(text, expect);
- }
- {
- QString text;
- QTextStream stream(&text);
- stream << micro;
- QCOMPARE(text, expect);
- }
-}
-
-void tst_QString::capacity_data()
-{
- length_data();
-}
-
-void tst_QString::capacity()
-{
- QFETCH( QString, s1 );
- QFETCH( int, res );
-
- QString s2( s1 );
- s2.reserve( res );
- QVERIFY( (int)s2.capacity() >= res );
- QCOMPARE( s2, s1 );
-
- s2 = s1; // share again
- s2.reserve( res * 2 );
- QVERIFY( (int)s2.capacity() >= res * 2 );
- QVERIFY(s2.constData() != s1.constData());
- QCOMPARE( s2, s1 );
-
- // don't share again -- s2 must be detached for squeeze() to do anything
- s2.squeeze();
- QVERIFY( (int)s2.capacity() == res );
- QCOMPARE( s2, s1 );
-
- s2 = s1; // share again
- int oldsize = s1.size();
- s2.reserve( res / 2 );
- QVERIFY( (int)s2.capacity() >= res / 2 );
- QVERIFY( (int)s2.capacity() >= oldsize );
- QCOMPARE( s2, s1 );
-}
-
-void tst_QString::section_data()
-{
- QTest::addColumn<QString>("wholeString" );
- QTest::addColumn<QString>("sep" );
- QTest::addColumn<int>("start" );
- QTest::addColumn<int>("end" );
- QTest::addColumn<int>("flags" );
- QTest::addColumn<QString>("sectionString" );
- QTest::addColumn<bool>("regexp" );
-
- QTest::newRow( "data0" ) << QString("forename,middlename,surname,phone") << QString(",") << 2 << 2 << int(QString::SectionDefault) << QString("surname") << false;
- QTest::newRow( "data1" ) << QString("/usr/local/bin/myapp") << QString("/") << 3 << 4 << int(QString::SectionDefault) << QString("bin/myapp") << false;
- QTest::newRow( "data2" ) << QString("/usr/local/bin/myapp") << QString("/") << 3 << 3 << int(QString::SectionSkipEmpty) << QString("myapp") << false;
- QTest::newRow( "data3" ) << QString("forename**middlename**surname**phone") << QString("**") << 2 << 2 << int(QString::SectionDefault) << QString("surname") << false;
- QTest::newRow( "data4" ) << QString("forename**middlename**surname**phone") << QString("**") << -3 << -2 << int(QString::SectionDefault) << QString("middlename**surname") << false;
- QTest::newRow( "data5" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 0 << 0 << int(QString::SectionSkipEmpty) << QString("Datt") << false;
- QTest::newRow( "data6" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 1 << 1 << int(QString::SectionSkipEmpty) << QString("wollen") << false;
- QTest::newRow( "data7" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 2 << 2 << int(QString::SectionSkipEmpty) << QString("wir") << false;
- QTest::newRow( "data8" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 3 << 3 << int(QString::SectionSkipEmpty) << QString("mal") << false;
- QTest::newRow( "data9" ) << QString("##Datt######wollen######wir######mal######sehen##") << QString("#") << 4 << 4 << int(QString::SectionSkipEmpty) << QString("sehen") << false;
- // not fixed for 3.1
- QTest::newRow( "data10" ) << QString("a/b/c/d") << QString("/") << 1 << -1 << int(QString::SectionIncludeLeadingSep | QString::SectionIncludeTrailingSep) << QString("/b/c/d") << false;
- QTest::newRow( "data11" ) << QString("aoLoboLocolod") << QString("olo") << -1 << -1 << int(QString::SectionCaseInsensitiveSeps) << QString("d") << false;
- QTest::newRow( "data12" ) << QString("F0") << QString("F") << 0 << 0 << int(QString::SectionSkipEmpty) << QString("0") << false;
- QTest::newRow( "foo1" ) << QString("foo;foo;") << QString(";") << 0 << 0
- << int(QString::SectionIncludeLeadingSep) << QString("foo") << false;
- QTest::newRow( "foo2" ) << QString("foo;foo;") << QString(";") << 1 << 1
- << int(QString::SectionIncludeLeadingSep) << QString(";foo") << false;
- QTest::newRow( "foo3" ) << QString("foo;foo;") << QString(";") << 2 << 2
- << int(QString::SectionIncludeLeadingSep) << QString(";") << false;
- QTest::newRow( "foo1rx" ) << QString("foo;foo;") << QString(";") << 0 << 0
- << int(QString::SectionIncludeLeadingSep) << QString("foo") << true;
- QTest::newRow( "foo2rx" ) << QString("foo;foo;") << QString(";") << 1 << 1
- << int(QString::SectionIncludeLeadingSep) << QString(";foo") << true;
- QTest::newRow( "foo3rx" ) << QString("foo;foo;") << QString(";") << 2 << 2
- << int(QString::SectionIncludeLeadingSep) << QString(";") << true;
-
- QTest::newRow( "qmake_path" ) << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode/")
- << QString("/") << 0 << -2 << int(QString::SectionDefault)
- << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode") << false;
- QTest::newRow( "qmake_pathrx" ) << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode/")
- << QString("/") << 0 << -2 << int(QString::SectionDefault)
- << QString("/Users/sam/troll/qt4.0/src/corelib/QtCore_debug.xcode") << true;
- QTest::newRow( "data13" ) << QString("||2|3|||")
- << QString("|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("||") << false;
- QTest::newRow( "data14" ) << QString("||2|3|||")
- << QString("\\|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("||") << true;
- QTest::newRow( "data15" ) << QString("|1|2|")
- << QString("|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("|1|") << false;
- QTest::newRow( "data16" ) << QString("|1|2|")
- << QString("\\|") << 0 << 1 << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("|1|") << true;
- QTest::newRow( "normal1" ) << QString("o1o2o")
- << QString("o") << 0 << 0
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o") << false;
- QTest::newRow( "normal2" ) << QString("o1o2o")
- << QString("o") << 1 << 1
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o1o") << false;
- QTest::newRow( "normal3" ) << QString("o1o2o")
- << QString("o") << 2 << 2
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o2o") << false;
- QTest::newRow( "normal4" ) << QString("o1o2o")
- << QString("o") << 2 << 3
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o2o") << false;
- QTest::newRow( "normal5" ) << QString("o1o2o")
- << QString("o") << 1 << 2
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o1o2o") << false;
- QTest::newRow( "range1" ) << QString("o1o2o")
- << QString("o") << -5 << -5
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString() << false;
- QTest::newRow( "range2" ) << QString("oo1o2o")
- << QString("o") << -5 << 1
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
- |QString::SectionSkipEmpty)
- << QString("oo1o2o") << false;
- QTest::newRow( "range3" ) << QString("o1o2o")
- << QString("o") << 2 << 1
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString() << false;
- QTest::newRow( "range4" ) << QString("o1o2o")
- << QString("o") << 4 << 4
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString() << false;
- QTest::newRow( "range5" ) << QString("o1oo2o")
- << QString("o") << -2 << -1
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
- |QString::SectionSkipEmpty)
- << QString("o1oo2o") << false;
- QTest::newRow( "rx1" ) << QString("o1o2o")
- << QString("[a-z]") << 0 << 0
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o") << true;
- QTest::newRow( "rx2" ) << QString("o1o2o")
- << QString("[a-z]") << 1 << 1
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o1o") << true;
- QTest::newRow( "rx3" ) << QString("o1o2o")
- << QString("[a-z]") << 2 << 2
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o2o") << true;
- QTest::newRow( "rx4" ) << QString("o1o2o")
- << QString("[a-z]") << 2 << 3
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o2o") << true;
- QTest::newRow( "rx5" ) << QString("o1o2o")
- << QString("[a-z]") << 1 << 2
- << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
- << QString("o1o2o") << true;
- QTest::newRow( "data17" ) << QString("This is a story, a small story")
- << QString("\\b") << 3 << 3
- << int(QString::SectionDefault)
- << QString("is") << true;
- QTest::newRow( "data18" ) << QString("99.0 42.3")
- << QString("\\s*[AaBb]\\s*") << 1 << 1
- << int(QString::SectionIncludeLeadingSep)
- << QString() << true;
-}
-
-void tst_QString::section()
-{
- QFETCH( QString, wholeString );
- QFETCH( QString, sep );
- QFETCH( int, start );
- QFETCH( int, end );
- QFETCH( int, flags );
- QFETCH( QString, sectionString );
- QFETCH( bool, regexp );
- if (regexp) {
- QCOMPARE( wholeString.section( QRegExp(sep), start, end, QString::SectionFlag(flags) ), sectionString );
- QCOMPARE( wholeString.section( QRegularExpression(sep), start, end, QString::SectionFlag(flags) ), sectionString );
- } else {
- if (sep.size() == 1)
- QCOMPARE( wholeString.section( sep[0], start, end, QString::SectionFlag(flags) ), sectionString );
- QCOMPARE( wholeString.section( sep, start, end, QString::SectionFlag(flags) ), sectionString );
- QCOMPARE( wholeString.section( QRegExp(QRegExp::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
- QCOMPARE( wholeString.section( QRegularExpression(QRegularExpression::escape(sep)), start, end, QString::SectionFlag(flags) ), sectionString );
-
- }
-}
-
-
-void tst_QString::operator_eqeq_nullstring()
-{
- /* Some of these might not be all that logical but it's the behaviour we've had since 3.0.0
- so we should probably stick with it. */
-
- QVERIFY( QString() == "" );
- QVERIFY( "" == QString() );
-
- QVERIFY( QString("") == "" );
- QVERIFY( "" == QString("") );
-
- QVERIFY(QString() == nullptr);
- QVERIFY(nullptr == QString());
-
- QVERIFY(QString("") == nullptr);
- QVERIFY(nullptr == QString(""));
-
- QVERIFY( QString().size() == 0 );
-
- QVERIFY( QString("").size() == 0 );
-
- QVERIFY( QString() == QString("") );
- QVERIFY( QString("") == QString() );
-}
-
-void tst_QString::operator_smaller()
-{
- QString null;
- QString empty("");
- QString foo("foo");
- const char *nullC = nullptr;
- const char *emptyC = "";
-
- QVERIFY( !(null < QString()) );
- QVERIFY( !(null > QString()) );
-
- QVERIFY( !(empty < QString("")) );
- QVERIFY( !(empty > QString("")) );
-
- QVERIFY( !(null < empty) );
- QVERIFY( !(null > empty) );
-
- QVERIFY( !(nullC < empty) );
- QVERIFY( !(nullC > empty) );
-
- QVERIFY( !(null < emptyC) );
- QVERIFY( !(null > emptyC) );
-
- QVERIFY( null < foo );
- QVERIFY( !(null > foo) );
- QVERIFY( foo > null );
- QVERIFY( !(foo < null) );
-
- QVERIFY( empty < foo );
- QVERIFY( !(empty > foo) );
- QVERIFY( foo > empty );
- QVERIFY( !(foo < empty) );
-
- QVERIFY( !(null < QLatin1String(0)) );
- QVERIFY( !(null > QLatin1String(0)) );
- QVERIFY( !(null < QLatin1String("")) );
- QVERIFY( !(null > QLatin1String("")) );
-
- QVERIFY( !(null < QLatin1String("")) );
- QVERIFY( !(null > QLatin1String("")) );
- QVERIFY( !(empty < QLatin1String("")) );
- QVERIFY( !(empty > QLatin1String("")) );
-
- QVERIFY( !(QLatin1String(0) < null) );
- QVERIFY( !(QLatin1String(0) > null) );
- QVERIFY( !(QLatin1String("") < null) );
- QVERIFY( !(QLatin1String("") > null) );
-
- QVERIFY( !(QLatin1String(0) < empty) );
- QVERIFY( !(QLatin1String(0) > empty) );
- QVERIFY( !(QLatin1String("") < empty) );
- QVERIFY( !(QLatin1String("") > empty) );
-
- QVERIFY( QLatin1String(0) < foo );
- QVERIFY( !(QLatin1String(0) > foo) );
- QVERIFY( QLatin1String("") < foo );
- QVERIFY( !(QLatin1String("") > foo) );
-
- QVERIFY( foo > QLatin1String(0) );
- QVERIFY( !(foo < QLatin1String(0)) );
- QVERIFY( foo > QLatin1String("") );
- QVERIFY( !(foo < QLatin1String("")) );
-
- QVERIFY( QLatin1String(0) == empty);
- QVERIFY( QLatin1String(0) == null);
- QVERIFY( QLatin1String("") == empty);
- QVERIFY( QLatin1String("") == null);
-
- QVERIFY( !(foo < QLatin1String("foo")));
- QVERIFY( !(foo > QLatin1String("foo")));
- QVERIFY( !(QLatin1String("foo") < foo));
- QVERIFY( !(QLatin1String("foo") > foo));
-
- QVERIFY( !(foo < QLatin1String("a")));
- QVERIFY( (foo > QLatin1String("a")));
- QVERIFY( (QLatin1String("a") < foo));
- QVERIFY( !(QLatin1String("a") > foo));
-
- QVERIFY( (foo < QLatin1String("z")));
- QVERIFY( !(foo > QLatin1String("z")));
- QVERIFY( !(QLatin1String("z") < foo));
- QVERIFY( (QLatin1String("z") > foo));
-
- // operator< is not locale-aware (or shouldn't be)
- QVERIFY( foo < QString("\xc3\xa9") );
- QVERIFY( foo < "\xc3\xa9" );
-
- QVERIFY(QString("a") < QString("b"));
- QVERIFY(QString("a") <= QString("b"));
- QVERIFY(QString("a") <= QString("a"));
- QVERIFY(QString("a") == QString("a"));
- QVERIFY(QString("a") >= QString("a"));
- QVERIFY(QString("b") >= QString("a"));
- QVERIFY(QString("b") > QString("a"));
-
- QVERIFY("a" < QString("b"));
- QVERIFY("a" <= QString("b"));
- QVERIFY("a" <= QString("a"));
- QVERIFY("a" == QString("a"));
- QVERIFY("a" >= QString("a"));
- QVERIFY("b" >= QString("a"));
- QVERIFY("b" > QString("a"));
-
- QVERIFY(QString("a") < "b");
- QVERIFY(QString("a") <= "b");
- QVERIFY(QString("a") <= "a");
- QVERIFY(QString("a") == "a");
- QVERIFY(QString("a") >= "a");
- QVERIFY(QString("b") >= "a");
- QVERIFY(QString("b") > "a");
-
- QVERIFY(QString("a") < QByteArray("b"));
- QVERIFY(QString("a") <= QByteArray("b"));
- QVERIFY(QString("a") <= QByteArray("a"));
- QVERIFY(QString("a") == QByteArray("a"));
- QVERIFY(QString("a") >= QByteArray("a"));
- QVERIFY(QString("b") >= QByteArray("a"));
- QVERIFY(QString("b") > QByteArray("a"));
-
- QVERIFY(QByteArray("a") < QString("b"));
- QVERIFY(QByteArray("a") <= QString("b"));
- QVERIFY(QByteArray("a") <= QString("a"));
- QVERIFY(QByteArray("a") == QString("a"));
- QVERIFY(QByteArray("a") >= QString("a"));
- QVERIFY(QByteArray("b") >= QString("a"));
- QVERIFY(QByteArray("b") > QString("a"));
-
- QVERIFY(QLatin1String("a") < QString("b"));
- QVERIFY(QLatin1String("a") <= QString("b"));
- QVERIFY(QLatin1String("a") <= QString("a"));
- QVERIFY(QLatin1String("a") == QString("a"));
- QVERIFY(QLatin1String("a") >= QString("a"));
- QVERIFY(QLatin1String("b") >= QString("a"));
- QVERIFY(QLatin1String("b") > QString("a"));
-
- QVERIFY(QString("a") < QLatin1String("b"));
- QVERIFY(QString("a") <= QLatin1String("b"));
- QVERIFY(QString("a") <= QLatin1String("a"));
- QVERIFY(QString("a") == QLatin1String("a"));
- QVERIFY(QString("a") >= QLatin1String("a"));
- QVERIFY(QString("b") >= QLatin1String("a"));
- QVERIFY(QString("b") > QLatin1String("a"));
-
- QVERIFY("a" < QLatin1String("b"));
- QVERIFY("a" <= QLatin1String("b"));
- QVERIFY("a" <= QLatin1String("a"));
- QVERIFY("a" == QLatin1String("a"));
- QVERIFY("a" >= QLatin1String("a"));
- QVERIFY("b" >= QLatin1String("a"));
- QVERIFY("b" > QLatin1String("a"));
-
- QVERIFY(QLatin1String("a") < "b");
- QVERIFY(QLatin1String("a") <= "b");
- QVERIFY(QLatin1String("a") <= "a");
- QVERIFY(QLatin1String("a") == "a");
- QVERIFY(QLatin1String("a") >= "a");
- QVERIFY(QLatin1String("b") >= "a");
- QVERIFY(QLatin1String("b") > "a");
-}
-
-void tst_QString::integer_conversion_data()
-{
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<int>("base");
- QTest::addColumn<bool>("good");
- QTest::addColumn<qlonglong>("num");
-
- QTest::newRow("C empty 0") << QString("") << 0 << false << (qlonglong)0;
- QTest::newRow("C empty 8") << QString("") << 8 << false << (qlonglong)0;
- QTest::newRow("C empty 10") << QString("") << 10 << false << (qlonglong)0;
- QTest::newRow("C empty 16") << QString("") << 16 << false << (qlonglong)0;
-
- QTest::newRow("C null 0") << QString() << 0 << false << (qlonglong)0;
- QTest::newRow("C null 8") << QString() << 8 << false << (qlonglong)0;
- QTest::newRow("C null 10") << QString() << 10 << false << (qlonglong)0;
- QTest::newRow("C null 16") << QString() << 16 << false << (qlonglong)0;
-
- QTest::newRow("C -0xf 0") << QString(" -0xf") << 0 << true << (qlonglong)-15;
- QTest::newRow("C -0xf 0") << QString("-0xf ") << 0 << true << (qlonglong)-15;
- QTest::newRow("C \t0xf\t 0") << QString("\t0xf\t") << 0 << true << (qlonglong)15;
- QTest::newRow("C -010 0") << QString(" -010") << 0 << true << (qlonglong)-8;
- QTest::newRow("C 010 0") << QString("010 ") << 0 << true << (qlonglong)8;
- QTest::newRow("C \t-010\t 0") << QString("\t-010\t") << 0 << true << (qlonglong)-8;
- QTest::newRow("C 123 10") << QString(" 123") << 10 << true << (qlonglong)123;
- QTest::newRow("C 123 10") << QString("123 ") << 10 << true << (qlonglong)123;
- QTest::newRow("C \t123\t 10") << QString("\t123\t") << 10 << true << (qlonglong)123;
- QTest::newRow("C -0xf 16") << QString(" -0xf") << 16 << true << (qlonglong)-15;
- QTest::newRow("C -0xf 16") << QString("-0xf ") << 16 << true << (qlonglong)-15;
- QTest::newRow("C \t0xf\t 16") << QString("\t0xf\t") << 16 << true << (qlonglong)15;
-
- QTest::newRow("C -0 0") << QString("-0") << 0 << true << (qlonglong)0;
- QTest::newRow("C -0 8") << QString("-0") << 8 << true << (qlonglong)0;
- QTest::newRow("C -0 10") << QString("-0") << 10 << true << (qlonglong)0;
- QTest::newRow("C -0 16") << QString("-0") << 16 << true << (qlonglong)0;
-
- QTest::newRow("C 1.234 10") << QString("1.234") << 10 << false << (qlonglong)0;
- QTest::newRow("C 1,234 10") << QString("1,234") << 10 << false << (qlonglong)0;
-
- QTest::newRow("C 0x 0") << QString("0x") << 0 << false << (qlonglong)0;
- QTest::newRow("C 0x 16") << QString("0x") << 16 << false << (qlonglong)0;
-
- QTest::newRow("C 10 0") << QString("10") << 0 << true << (qlonglong)10;
- QTest::newRow("C 010 0") << QString("010") << 0 << true << (qlonglong)8;
- QTest::newRow("C 0x10 0") << QString("0x10") << 0 << true << (qlonglong)16;
- QTest::newRow("C 10 8") << QString("10") << 8 << true << (qlonglong)8;
- QTest::newRow("C 010 8") << QString("010") << 8 << true << (qlonglong)8;
- QTest::newRow("C 0x10 8") << QString("0x10") << 8 << false << (qlonglong)0;
- QTest::newRow("C 10 10") << QString("10") << 10 << true << (qlonglong)10;
- QTest::newRow("C 010 10") << QString("010") << 10 << true << (qlonglong)10;
- QTest::newRow("C 0x10 10") << QString("0x10") << 10 << false << (qlonglong)0;
- QTest::newRow("C 10 16") << QString("10") << 16 << true << (qlonglong)16;
- QTest::newRow("C 010 16") << QString("010") << 16 << true << (qlonglong)16;
- QTest::newRow("C 0x10 16") << QString("0x10") << 16 << true << (qlonglong)16;
-
- QTest::newRow("C -10 0") << QString("-10") << 0 << true << (qlonglong)-10;
- QTest::newRow("C -010 0") << QString("-010") << 0 << true << (qlonglong)-8;
- QTest::newRow("C -0x10 0") << QString("-0x10") << 0 << true << (qlonglong)-16;
- QTest::newRow("C -10 8") << QString("-10") << 8 << true << (qlonglong)-8;
- QTest::newRow("C -010 8") << QString("-010") << 8 << true << (qlonglong)-8;
- QTest::newRow("C -0x10 8") << QString("-0x10") << 8 << false << (qlonglong)0;
- QTest::newRow("C -10 10") << QString("-10") << 10 << true << (qlonglong)-10;
- QTest::newRow("C -010 10") << QString("-010") << 10 << true << (qlonglong)-10;
- QTest::newRow("C -0x10 10") << QString("-0x10") << 10 << false << (qlonglong)0;
- QTest::newRow("C -10 16") << QString("-10") << 16 << true << (qlonglong)-16;
- QTest::newRow("C -010 16") << QString("-010") << 16 << true << (qlonglong)-16;
- QTest::newRow("C -0x10 16") << QString("-0x10") << 16 << true << (qlonglong)-16;
-
- // Let's try some Arabic
- const quint16 arabic_str[] = { 0x0661, 0x0662, 0x0663, 0x0664, 0x0000 }; // "1234"
- QTest::newRow("ar_SA 1234 0") << QString::fromUtf16(arabic_str) << 0 << false << (qlonglong)0;
-}
-
-void tst_QString::integer_conversion()
-{
- QFETCH(QString, num_str);
- QFETCH(int, base);
- QFETCH(bool, good);
- QFETCH(qlonglong, num);
-
- bool ok;
- qlonglong d = num_str.toLongLong(&ok, base);
- QCOMPARE(ok, good);
-
- if (ok) {
- QCOMPARE(d, num);
- }
-}
-
-void tst_QString::double_conversion_data()
-{
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<bool>("good");
- QTest::addColumn<double>("num");
-
- // The good...
-
- QTest::newRow("C 1") << QString("1") << true << 1.0;
- QTest::newRow("C 1.0") << QString("1.0") << true << 1.0;
- QTest::newRow("C 1.234") << QString("1.234") << true << 1.234;
- QTest::newRow("C 1.234e-10") << QString("1.234e-10") << true << 1.234e-10;
- QTest::newRow("C 1.234E10") << QString("1.234E10") << true << 1.234e10;
- QTest::newRow("C 1e10") << QString("1e10") << true << 1.0e10;
-
- // The bad...
-
- QTest::newRow("C empty") << QString("") << false << 0.0;
- QTest::newRow("C null") << QString() << false << 0.0;
- QTest::newRow("C .") << QString(".") << false << 0.0;
- QTest::newRow("C 1e") << QString("1e") << false << 0.0;
- QTest::newRow("C 1,") << QString("1,") << false << 0.0;
- QTest::newRow("C 1,0") << QString("1,0") << false << 0.0;
- QTest::newRow("C 1,000") << QString("1,000") << false << 0.0;
- QTest::newRow("C 1e1.0") << QString("1e1.0") << false << 0.0;
- QTest::newRow("C 1e+") << QString("1e+") << false << 0.0;
- QTest::newRow("C 1e-") << QString("1e-") << false << 0.0;
- QTest::newRow("de_DE 1,0") << QString("1,0") << false << 0.0;
- QTest::newRow("de_DE 1,234") << QString("1,234") << false << 0.0;
- QTest::newRow("de_DE 1,234e-10") << QString("1,234e-10") << false << 0.0;
- QTest::newRow("de_DE 1,234E10") << QString("1,234E10") << false << 0.0;
-
- // And the ugly...
-
- QTest::newRow("C .1") << QString(".1") << true << 0.1;
- QTest::newRow("C -.1") << QString("-.1") << true << -0.1;
- QTest::newRow("C 1.") << QString("1.") << true << 1.0;
- QTest::newRow("C 1.E10") << QString("1.E10") << true << 1.0e10;
- QTest::newRow("C 1e+10") << QString("1e+10") << true << 1.0e+10;
- QTest::newRow("C 1") << QString(" 1") << true << 1.0;
- QTest::newRow("C 1 ") << QString("1 ") << true << 1.0;
-
- // Let's try some Arabic
- const quint16 arabic_str[] = { 0x0660, 0x066B, 0x0661, 0x0662,
- 0x0663, 0x0664, 0x0065, 0x0662,
- 0x0000 }; // "0.1234e2"
- QTest::newRow("ar_SA") << QString::fromUtf16(arabic_str) << false << 0.0;
-}
-
-void tst_QString::double_conversion()
-{
-#define MY_DOUBLE_EPSILON (2.22045e-16)
-
- QFETCH(QString, num_str);
- QFETCH(bool, good);
- QFETCH(double, num);
-
- bool ok;
- double d = num_str.toDouble(&ok);
- QCOMPARE(ok, good);
-
- if (ok) {
- double diff = d - num;
- if (diff < 0)
- diff = -diff;
- QVERIFY(diff <= MY_DOUBLE_EPSILON);
- }
-}
-
-#ifndef Q_MOC_RUN
-#include "double_data.h"
-#endif
-
-void tst_QString::tortureSprintfDouble()
-{
- const SprintfDoubleData *data = g_sprintf_double_data;
-
- QString s;
-
- for (; data->fmt != 0; ++data) {
- double d;
- char *buff = (char *)&d;
-# ifndef Q_BYTE_ORDER
-# error "Q_BYTE_ORDER not defined"
-# endif
-
-# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- for (uint i = 0; i < 8; ++i)
- buff[i] = data->bytes[i];
-# else
- for (uint i = 0; i < 8; ++i)
- buff[7 - i] = data->bytes[i];
-# endif
- s.sprintf(data->fmt, d);
-#ifdef QT_NO_FPU // reduced precision when running with hardfloats in qemu
- if (d - 0.1 < 1e12)
- QSKIP("clib sprintf doesn't fill with 0's on this platform");
- QCOMPARE(s.left(16), QString(data->expected).left(16));
-#else
- QCOMPARE(s, QString(data->expected));
-#endif
- }
-}
-
-#include <locale.h>
-
-void tst_QString::localeAwareCompare_data()
-{
- QTest::addColumn<QString>("locale");
- QTest::addColumn<QString>("s1");
- QTest::addColumn<QString>("s2");
- QTest::addColumn<int>("result");
-
- // Compare decomposed and composed form
- {
- // From ES6 test262 test suite (built-ins/String/prototype/localeCompare/15.5.4.9_CE.js). The test cases boil down to code like this:
- // console.log("\u1111\u1171\u11B6".localeCompare("\ud4db")
-
- // example from Unicode 5.0, section 3.7, definition D70
- QTest::newRow("normalize1") << QString("en_US") << QString::fromUtf8("o\xCC\x88") << QString::fromUtf8("\xC3\xB6") << 0;
- // examples from Unicode 5.0, chapter 3.11
- QTest::newRow("normalize2") << QString("en_US") << QString::fromUtf8("\xC3\xA4\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
- QTest::newRow("normalize3") << QString("en_US") << QString::fromUtf8("a\xCC\x88\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
- QTest::newRow("normalize4") << QString("en_US") << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
- QTest::newRow("normalize5") << QString("en_US") << QString::fromUtf8("\xC3\xA4\xCC\x86") << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0;
- QTest::newRow("normalize6") << QString("en_US") << QString::fromUtf8("\xC4\x83\xCC\x88") << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0;
- // example from Unicode 5.0, chapter 3.12
- QTest::newRow("normalize7") << QString("en_US") << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8("\xED\x93\x9B") << 0;
- // examples from UTS 10, Unicode Collation Algorithm
- QTest::newRow("normalize8") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("\xC3\x85") << 0;
- QTest::newRow("normalize9") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0;
- QTest::newRow("normalize10") << QString("en_US") << QString::fromUtf8("x\xCC\x9B\xCC\xA3") << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0;
- QTest::newRow("normalize11") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0;
- QTest::newRow("normalize12") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0;
- QTest::newRow("normalize13") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0;
- QTest::newRow("normalize14") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0;
- // examples from UAX 15, Unicode Normalization Forms
- QTest::newRow("normalize15") << QString("en_US") << QString::fromUtf8("\xC3\x87") << QString::fromUtf8("C\xCC\xA7") << 0;
- QTest::newRow("normalize16") << QString("en_US") << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0;
- QTest::newRow("normalize17") << QString("en_US") << QString::fromUtf8("\xEA\xB0\x80") << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0;
- QTest::newRow("normalize18") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0;
- QTest::newRow("normalize19") << QString("en_US") << QString::fromUtf8("\xE2\x84\xA6") << QString::fromUtf8("\xCE\xA9") << 0;
- QTest::newRow("normalize20") << QString("en_US") << QString::fromUtf8("\xC3\x85") << QString::fromUtf8("A\xCC\x8A") << 0;
- QTest::newRow("normalize21") << QString("en_US") << QString::fromUtf8("\xC3\xB4") << QString::fromUtf8("o\xCC\x82") << 0;
- QTest::newRow("normalize22") << QString("en_US") << QString::fromUtf8("\xE1\xB9\xA9") << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0;
- QTest::newRow("normalize23") << QString("en_US") << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0;
- QTest::newRow("normalize24") << QString("en_US") << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0;
- QTest::newRow("normalize25") << QString("en_US") << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0;
-
- }
-
-#if !defined(Q_OS_WIN)
-// On Q_OS_WIN, we cannot set the system or user locale
- /*
- The C locale performs pure byte comparisons for
- Latin-1-specific characters (I think). Compare with Swedish
- below.
- */
- QTest::newRow("c1") << QString("C") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << 1;
- QTest::newRow("c2") << QString("C") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("c3") << QString("C") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1;
-
- /*
- It's hard to test English, because it's treated differently
- on different platforms. For example, on Linux, it uses the
- iso14651_t1 template file, which happens to provide good
- defaults for Swedish. OS X seems to do a pure bytewise
- comparison of Latin-1 values, although I'm not sure. So I
- just test digits to make sure that it's not totally broken.
- */
- QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1;
- QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1;
- QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1;
- /*
- In Swedish, a with ring above (E5) comes before a with
- diaresis (E4), which comes before o diaresis (F6), which
- all come after z.
- */
-#ifdef Q_OS_MAC
- QTest::newRow("swedish1") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1;
- QTest::newRow("swedish2") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("swedish3") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("swedish4") << QString("sv_SE.ISO8859-1") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1;
-#else
- QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1;
- QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1;
-#endif
-
-#if 0
- /*
- In Norwegian, ae (E6) comes before o with stroke (D8), which
- comes before a with ring above (E5).
- */
- QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1;
- QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1;
- QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1;
-#endif
-
- /*
- In German, z comes *after* a with diaresis (E4),
- which comes before o diaresis (F6).
- */
-#ifdef Q_OS_MAC
- QTest::newRow("german1") << QString("de_DE.ISO8859-1") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1;
- QTest::newRow("german2") << QString("de_DE.ISO8859-1") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("german3") << QString("de_DE.ISO8859-1") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1;
-#else
- QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1;
- QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
- QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1;
-#endif
-#endif //!defined(Q_OS_WIN)
-}
-
-void tst_QString::localeAwareCompare()
-{
- QFETCH(QString, locale);
- QFETCH(QString, s1);
- QFETCH(QString, s2);
- QFETCH(int, result);
-
- QStringRef r1(&s1, 0, s1.length());
- QStringRef r2(&s2, 0, s2.length());
-
- if (!locale.isEmpty()) {
-#if defined (Q_OS_DARWIN) || defined(QT_USE_ICU)
- QSKIP("Setting the locale is not supported on OS X or ICU (you can set the C locale, but that won't affect localeAwareCompare)");
-#else
- const char *newLocale = setlocale(LC_ALL, locale.toLatin1());
- if (!newLocale) {
- setlocale(LC_ALL, "");
- QSKIP("Please install the proper locale on this machine to test properly");
- }
-#endif
- }
-
-#ifdef QT_USE_ICU
- // ### for c1, ICU disagrees with libc on how to compare
- QEXPECT_FAIL("c1", "ICU disagrees with test", Abort);
-#endif
-
- int testres = QString::localeAwareCompare(s1, s2);
- if (result < 0) {
- QVERIFY(testres < 0);
- } else if (result > 0) {
- QVERIFY(testres > 0);
- } else {
- QVERIFY(testres == 0);
- }
-
- testres = QString::localeAwareCompare(s2, s1);
- if (result > 0) {
- QVERIFY(testres < 0);
- } else if (result < 0) {
- QVERIFY(testres > 0);
- } else {
- QVERIFY(testres == 0);
- }
-
- testres = QString::localeAwareCompare(s1, r2);
- if (result < 0) {
- QVERIFY(testres < 0);
- } else if (result > 0) {
- QVERIFY(testres > 0);
- } else {
- QVERIFY(testres == 0);
- }
-
- testres = QStringRef::localeAwareCompare(r1, r2);
- if (result < 0) {
- QVERIFY(testres < 0);
- } else if (result > 0) {
- QVERIFY(testres > 0);
- } else {
- QVERIFY(testres == 0);
- }
-
- testres = QStringRef::localeAwareCompare(r2, r1);
- if (result > 0) {
- QVERIFY(testres < 0);
- } else if (result < 0) {
- QVERIFY(testres > 0);
- } else {
- QVERIFY(testres == 0);
- }
-
- if (!locale.isEmpty())
- setlocale(LC_ALL, "");
-}
-
-void tst_QString::reverseIterators()
-{
- QString s = "1234";
- QString sr = s;
- std::reverse(sr.begin(), sr.end());
- const QString &csr = sr;
- QVERIFY(std::equal(s.begin(), s.end(), sr.rbegin()));
- QVERIFY(std::equal(s.begin(), s.end(), sr.crbegin()));
- QVERIFY(std::equal(s.begin(), s.end(), csr.rbegin()));
- QVERIFY(std::equal(sr.rbegin(), sr.rend(), s.begin()));
- QVERIFY(std::equal(sr.crbegin(), sr.crend(), s.begin()));
- QVERIFY(std::equal(csr.rbegin(), csr.rend(), s.begin()));
-}
-
-void tst_QString::split_data()
-{
- QTest::addColumn<QString>("str");
- QTest::addColumn<QString>("sep");
- QTest::addColumn<QStringList>("result");
-
- QTest::newRow("1") << "a,b,c" << "," << (QStringList() << "a" << "b" << "c");
- QTest::newRow("2") << QString("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile")
- << " "
- << (QStringList() << "-rw-r--r--" << "" << "1" << "0" << "" << "0" << ""
- << "519240" << "Jul" << "" << "9" << "" << "2002" << "bigfile");
- QTest::newRow("one-empty") << "" << " " << (QStringList() << "");
- QTest::newRow("two-empty") << " " << " " << (QStringList() << "" << "");
- QTest::newRow("three-empty") << " " << " " << (QStringList() << "" << "" << "");
-
- QTest::newRow("all-empty") << "" << "" << (QStringList() << "" << "");
- QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
-}
-
-template<class> struct StringSplitWrapper;
-template<> struct StringSplitWrapper<QString>
-{
- const QString &string;
-
- QStringList split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
- QStringList split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.split(sep, behavior, cs); }
- QStringList split(const QRegExp &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
- QStringList split(const QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.split(sep, behavior); }
-};
-
-template<> struct StringSplitWrapper<QStringRef>
-{
- const QString &string;
- QVector<QStringRef> split(const QString &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
- QVector<QStringRef> split(QChar sep, QString::SplitBehavior behavior = QString::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return string.splitRef(sep, behavior, cs); }
- QVector<QStringRef> split(const QRegExp &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
- QVector<QStringRef> split(const QRegularExpression &sep, QString::SplitBehavior behavior = QString::KeepEmptyParts) const { return string.splitRef(sep, behavior); }
-};
-
-static bool operator ==(const QStringList &left, const QVector<QStringRef> &right)
-{
- if (left.size() != right.size())
- return false;
-
- QStringList::const_iterator iLeft = left.constBegin();
- QVector<QStringRef>::const_iterator iRight = right.constBegin();
- for (; iLeft != left.end(); ++iLeft, ++iRight) {
- if (*iLeft != *iRight)
- return false;
- }
- return true;
-}
-static inline bool operator ==(const QVector<QStringRef> &left, const QStringList &right) { return right == left; }
-
-template<class List>
-void tst_QString::split(const QString &string, const QString &sep, QStringList result)
-{
- QRegExp rx = QRegExp(QRegExp::escape(sep));
- QRegularExpression re(QRegularExpression::escape(sep));
-
- List list;
- StringSplitWrapper<typename List::value_type> str = {string};
-
- list = str.split(sep);
- QVERIFY(list == result);
- list = str.split(rx);
- QVERIFY(list == result);
- list = str.split(re);
- QVERIFY(list == result);
- if (sep.size() == 1) {
- list = str.split(sep.at(0));
- QVERIFY(list == result);
- }
-
- list = str.split(sep, QString::KeepEmptyParts);
- QVERIFY(list == result);
- list = str.split(rx, QString::KeepEmptyParts);
- QVERIFY(list == result);
- list = str.split(re, QString::KeepEmptyParts);
- QVERIFY(list == result);
- if (sep.size() == 1) {
- list = str.split(sep.at(0), QString::KeepEmptyParts);
- QVERIFY(list == result);
- }
-
- result.removeAll("");
- list = str.split(sep, QString::SkipEmptyParts);
- QVERIFY(list == result);
- list = str.split(rx, QString::SkipEmptyParts);
- QVERIFY(list == result);
- list = str.split(re, QString::SkipEmptyParts);
- QVERIFY(list == result);
- if (sep.size() == 1) {
- list = str.split(sep.at(0), QString::SkipEmptyParts);
- QVERIFY(list == result);
- }
-}
-
-void tst_QString::split()
-{
- QFETCH(QString, str);
- QFETCH(QString, sep);
- QFETCH(QStringList, result);
- split<QStringList>(str, sep, result);
-}
-
-void tst_QString::splitRef_data()
-{
- split_data();
-}
-
-void tst_QString::splitRef()
-{
- QFETCH(QString, str);
- QFETCH(QString, sep);
- QFETCH(QStringList, result);
- split<QVector<QStringRef> >(str, sep, result);
-}
-
-void tst_QString::split_regexp_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("result");
-
- QTest::newRow("data01") << "Some text\n\twith strange whitespace."
- << "\\s+"
- << (QStringList() << "Some" << "text" << "with" << "strange" << "whitespace." );
-
- QTest::newRow("data02") << "This time, a normal English sentence."
- << "\\W+"
- << (QStringList() << "This" << "time" << "a" << "normal" << "English" << "sentence" << "");
-
- QTest::newRow("data03") << "Now: this sentence fragment."
- << "\\b"
- << (QStringList() << "" << "Now" << ": " << "this" << " " << "sentence" << " " << "fragment" << ".");
-}
-
-template<class List, class RegExp>
-void tst_QString::split_regexp(const QString &_string, const QString &pattern, QStringList result)
-{
- List list;
- StringSplitWrapper<typename List::value_type> string = {_string};
-
- list = string.split(RegExp(pattern));
- QVERIFY(list == result);
-
- result.removeAll(QString());
-
- list = string.split(RegExp(pattern), QString::SkipEmptyParts);
- QVERIFY(list == result);
-}
-
-void tst_QString::split_regexp()
-{
- QFETCH(QString, string);
- QFETCH(QString, pattern);
- QFETCH(QStringList, result);
- split_regexp<QStringList, QRegExp>(string, pattern, result);
-}
-
-void tst_QString::split_regularexpression_data()
-{
- split_regexp_data();
-}
-
-void tst_QString::split_regularexpression()
-{
- QFETCH(QString, string);
- QFETCH(QString, pattern);
- QFETCH(QStringList, result);
- split_regexp<QStringList, QRegularExpression>(string, pattern, result);
-}
-
-void tst_QString::splitRef_regularexpression_data()
-{
- split_regexp_data();
-}
-
-void tst_QString::splitRef_regularexpression()
-{
- QFETCH(QString, string);
- QFETCH(QString, pattern);
- QFETCH(QStringList, result);
- split_regexp<QVector<QStringRef>, QRegularExpression>(string, pattern, result);
-}
-
-void tst_QString::splitRef_regexp_data()
-{
- split_regexp_data();
-}
-
-void tst_QString::splitRef_regexp()
-{
- QFETCH(QString, string);
- QFETCH(QString, pattern);
- QFETCH(QStringList, result);
- split_regexp<QVector<QStringRef>, QRegExp>(string, pattern, result);
-}
-
-void tst_QString::fromUtf16_data()
-{
- QTest::addColumn<QString>("ucs2");
- QTest::addColumn<QString>("res");
- QTest::addColumn<int>("len");
-
- QTest::newRow("str0") << QString("abcdefgh") << QString("abcdefgh") << -1;
- QTest::newRow("str0-len") << QString("abcdefgh") << QString("abc") << 3;
-}
-
-void tst_QString::fromUtf16()
-{
- QFETCH(QString, ucs2);
- QFETCH(QString, res);
- QFETCH(int, len);
-
- QCOMPARE(QString::fromUtf16(ucs2.utf16(), len), res);
-}
-
-void tst_QString::fromUtf16_char16_data()
-{
-#ifdef Q_COMPILER_UNICODE_STRINGS
- fromUtf16_data();
-#else
- QSKIP("Compiler does not support C++11 unicode strings");
-#endif
-}
-
-void tst_QString::fromUtf16_char16()
-{
-#ifdef Q_COMPILER_UNICODE_STRINGS
- QFETCH(QString, ucs2);
- QFETCH(QString, res);
- QFETCH(int, len);
-
- QCOMPARE(QString::fromUtf16(reinterpret_cast<const char16_t *>(ucs2.utf16()), len), res);
-#endif
-}
-
-void tst_QString::unicodeStrings()
-{
-#ifdef Q_STDLIB_UNICODE_STRINGS
- QString s1, s2;
- static const std::u16string u16str1(u"Hello Unicode World");
- static const std::u32string u32str1(U"Hello Unicode World");
- s1 = QString::fromStdU16String(u16str1);
- s2 = QString::fromStdU32String(u32str1);
- QCOMPARE(s1, QString("Hello Unicode World"));
- QCOMPARE(s1, s2);
-
- QCOMPARE(s2.toStdU16String(), u16str1);
- QCOMPARE(s1.toStdU32String(), u32str1);
-
- s1 = QString::fromStdU32String(std::u32string(U"\u221212\U000020AC\U00010000"));
- QCOMPARE(s1, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
-#else
- QSKIP("Standard Library does not support C++11 unicode strings");
-#endif
-}
-
-void tst_QString::latin1String()
-{
- QString s("Hello");
-
- QVERIFY(s == QLatin1String("Hello"));
- QVERIFY(s != QLatin1String("Hello World"));
- QVERIFY(s < QLatin1String("Helloa"));
- QVERIFY(!(s > QLatin1String("Helloa")));
- QVERIFY(s > QLatin1String("Helln"));
- QVERIFY(s > QLatin1String("Hell"));
- QVERIFY(!(s < QLatin1String("Helln")));
- QVERIFY(!(s < QLatin1String("Hell")));
-}
-
-void tst_QString::nanAndInf()
-{
- bool ok;
- double d;
-
-#define CHECK_DOUBLE(str, expected_ok, expected_inf) \
- d = QString(str).toDouble(&ok); \
- QVERIFY(ok == expected_ok); \
- QVERIFY(qIsInf(d) == expected_inf);
-
- CHECK_DOUBLE("inf", true, true)
- CHECK_DOUBLE("INF", true, true)
- CHECK_DOUBLE("inf ", true, true)
- CHECK_DOUBLE("+inf", true, true)
- CHECK_DOUBLE("\t +INF", true, true)
- CHECK_DOUBLE("\t INF", true, true)
- CHECK_DOUBLE("inF ", true, true)
- CHECK_DOUBLE("+iNf", true, true)
- CHECK_DOUBLE("INFe-10", false, false)
- CHECK_DOUBLE("0xINF", false, false)
- CHECK_DOUBLE("- INF", false, false)
- CHECK_DOUBLE("+ INF", false, false)
- CHECK_DOUBLE("-- INF", false, false)
- CHECK_DOUBLE("inf0", false, false)
- CHECK_DOUBLE("--INF", false, false)
- CHECK_DOUBLE("++INF", false, false)
- CHECK_DOUBLE("INF++", false, false)
- CHECK_DOUBLE("INF--", false, false)
- CHECK_DOUBLE("INF +", false, false)
- CHECK_DOUBLE("INF -", false, false)
- CHECK_DOUBLE("0INF", false, false)
-#undef CHECK_INF
-
-#define CHECK_NAN(str, expected_ok, expected_nan) \
- d = QString(str).toDouble(&ok); \
- QVERIFY(ok == expected_ok); \
- QVERIFY(qIsNaN(d) == expected_nan);
-
- CHECK_NAN("nan", true, true)
- CHECK_NAN("NAN", true, true)
- CHECK_NAN("nan ", true, true)
- CHECK_NAN("\t NAN", true, true)
- CHECK_NAN("\t NAN ", true, true)
- CHECK_NAN("-nan", false, false)
- CHECK_NAN("+NAN", false, false)
- CHECK_NAN("NaN", true, true)
- CHECK_NAN("nAn", true, true)
- CHECK_NAN("NANe-10", false, false)
- CHECK_NAN("0xNAN", false, false)
- CHECK_NAN("0NAN", false, false)
-#undef CHECK_NAN
-
- d = QString("-INF").toDouble(&ok);
- QVERIFY(ok);
- QVERIFY(d == -qInf());
-
- QString("INF").toLong(&ok);
- QVERIFY(!ok);
-
- QString("INF").toLong(&ok, 36);
- QVERIFY(ok);
-
- QString("INF0").toLong(&ok, 36);
- QVERIFY(ok);
-
- QString("0INF0").toLong(&ok, 36);
- QVERIFY(ok);
-
- // Check that inf (float) => "inf" (QString) => inf (float).
- float value = qInf();
- QString valueAsString = QString::number(value);
- QCOMPARE(valueAsString, QString::fromLatin1("inf"));
- float valueFromString = valueAsString.toFloat();
- QVERIFY(qIsInf(valueFromString));
-
- // Check that -inf (float) => "-inf" (QString) => -inf (float).
- value = -qInf();
- valueAsString = QString::number(value);
- QCOMPARE(valueAsString, QString::fromLatin1("-inf"));
- valueFromString = valueAsString.toFloat();
- QVERIFY(value == -qInf());
- QVERIFY(qIsInf(valueFromString));
-}
-
-void tst_QString::arg_fillChar_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QList<QVariant> >("replaceValues");
- QTest::addColumn<IntList>("widths");
- QTest::addColumn<QString>("fillChars");
- QTest::addColumn<QString>("expected");
-
- QList<QVariant> replaceValues;
- IntList widths;
- QString fillChars;
-
- replaceValues << QVariant((int)5) << QVariant(QString("f")) << QVariant((int)0);
- widths << 3 << 2 << 5;
- QTest::newRow("str0") << QString("%1%2%3") << replaceValues << widths << QString("abc") << QString("aa5bfcccc0");
-
- replaceValues.clear();
- widths.clear();
- replaceValues << QVariant((int)5.5) << QVariant(QString("foo")) << QVariant((qulonglong)INT_MAX);
- widths << 10 << 2 << 5;
- QTest::newRow("str1") << QString("%3.%1.%3.%2") << replaceValues << widths << QString("0 c")
- << QString("2147483647.0000000005.2147483647.foo");
-
- replaceValues.clear();
- widths.clear();
- replaceValues << QVariant(QString("fisk"));
- widths << 100;
- QTest::newRow("str2") << QString("%9 og poteter") << replaceValues << widths << QString("f")
- << QString("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffisk og poteter");
-}
-
-void tst_QString::arg_fillChar()
-{
- static const int base = 10;
- static const char fmt = 'g';
- static const int prec = -1;
-
- QFETCH(QString, pattern);
- QFETCH(QList<QVariant>, replaceValues);
- QFETCH(IntList, widths);
- QFETCH(QString, fillChars);
- QFETCH(QString, expected);
- QCOMPARE(replaceValues.count(), fillChars.count());
- QCOMPARE(replaceValues.count(), widths.count());
-
- QString actual = pattern;
- for (int i=0; i<replaceValues.count(); ++i) {
- const QVariant &var = replaceValues.at(i);
- const int width = widths.at(i);
- const QChar fillChar = fillChars.at(i);
- switch (var.type()) {
- case QVariant::String: actual = actual.arg(var.toString(), width, fillChar); break;
- case QVariant::Int: actual = actual.arg(var.toInt(), width, base, fillChar); break;
- case QVariant::UInt: actual = actual.arg(var.toUInt(), width, base, fillChar); break;
- case QVariant::Double: actual = actual.arg(var.toDouble(), width, fmt, prec, fillChar); break;
- case QVariant::LongLong: actual = actual.arg(var.toLongLong(), width, base, fillChar); break;
- case QVariant::ULongLong: actual = actual.arg(var.toULongLong(), width, base, fillChar); break;
- default: QVERIFY(0); break;
- }
- }
-
- QCOMPARE(actual, expected);
-}
-
-static inline int sign(int x)
-{
- return x == 0 ? 0 : (x < 0 ? -1 : 1);
-}
-
-void tst_QString::compare_data()
-{
- QTest::addColumn<QString>("s1");
- QTest::addColumn<QString>("s2");
- QTest::addColumn<int>("csr"); // case sensitive result
- QTest::addColumn<int>("cir"); // case insensitive result
-
- // null strings
- QTest::newRow("null-null") << QString() << QString() << 0 << 0;
- QTest::newRow("text-null") << QString("a") << QString() << 1 << 1;
- QTest::newRow("null-text") << QString() << QString("a") << -1 << -1;
- QTest::newRow("null-empty") << QString() << QString("") << 0 << 0;
- QTest::newRow("empty-null") << QString("") << QString() << 0 << 0;
-
- // empty strings
- QTest::newRow("data0") << QString("") << QString("") << 0 << 0;
- QTest::newRow("data1") << QString("a") << QString("") << 1 << 1;
- QTest::newRow("data2") << QString("") << QString("a") << -1 << -1;
-
- // equal length
- QTest::newRow("data3") << QString("abc") << QString("abc") << 0 << 0;
- QTest::newRow("data4") << QString("abC") << QString("abc") << -1 << 0;
- QTest::newRow("data5") << QString("abc") << QString("abC") << 1 << 0;
-
- // different length
- QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1;
- QTest::newRow("data7") << QString("abCdef") << QString("abc") << -1 << 1;
- QTest::newRow("data8") << QString("abc") << QString("abcdef") << -1 << -1;
-
- QString upper;
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::lowSurrogate(0x10400));
- QString lower;
- lower += QChar(QChar::highSurrogate(0x10428));
- lower += QChar(QChar::lowSurrogate(0x10428));
- QTest::newRow("data8") << upper << lower << -1 << 0;
-
- // embedded nulls
- // These don't work as of now. It's OK that these don't work since \0 is not a valid unicode
- /*QTest::newRow("data10") << QString(QByteArray("\0", 1)) << QString(QByteArray("\0", 1)) << 0 << 0;
- QTest::newRow("data11") << QString(QByteArray("\0", 1)) << QString("") << 1 << 1;
- QTest::newRow("data12") << QString("") << QString(QByteArray("\0", 1)) << -1 << -1;
- QTest::newRow("data13") << QString("ab\0c") << QString(QByteArray("ab\0c", 4)) << 0 << 0;
- QTest::newRow("data14") << QString(QByteArray("ab\0c", 4)) << QString("abc") << -1 << -1;
- QTest::newRow("data15") << QString("abc") << QString(QByteArray("ab\0c", 4)) << 1 << 1;*/
-
- // All tests below (generated by the 3 for-loops) are meant to excercise the vectorized versions
- // of ucstrncmp.
-
- QString in1, in2;
- for (int i = 0; i < 70; ++i) {
- in1 += QString::number(i % 10);
- in2 += QString::number((70 - i + 1) % 10);
- }
- Q_ASSERT(in1.length() == in2.length());
- Q_ASSERT(in1 != in2);
- Q_ASSERT(in1.at(0) < in2.at(0));
- for (int i = 0; i < in1.length(); ++i) {
- Q_ASSERT(in1.at(i) != in2.at(i));
- }
-
- for (int i = 1; i <= 65; ++i) {
- QString inp1 = in1.left(i);
- QString inp2 = in2.left(i);
- QTest::addRow("all-different-%d", i) << inp1 << inp2 << -1 << -1;
- }
-
- for (int i = 1; i <= 65; ++i) {
- QString start(i - 1, 'a');
-
- QString in = start + QLatin1Char('a');
- QTest::addRow("all-same-%d", i) << in << in << 0 << 0;
-
- QString in2 = start + QLatin1Char('b');
- QTest::addRow("last-different-%d", i) << in << in2 << -1 << -1;
- }
-
- for (int i = 0; i < 16; ++i) {
- QString in1(16, 'a');
- QString in2 = in1;
- in2[i] = 'b';
- QTest::addRow("all-same-except-char-%d", i) << in1 << in2 << -1 << -1;
- }
-}
-
-static bool isLatin(const QString &s)
-{
- for (int i = 0; i < s.length(); ++i)
- if (s.at(i).unicode() > 0xff)
- return false;
- return true;
-}
-
-void tst_QString::compare()
-{
- QFETCH(QString, s1);
- QFETCH(QString, s2);
- QFETCH(int, csr);
- QFETCH(int, cir);
-
- QStringRef r1(&s1, 0, s1.length());
- QStringRef r2(&s2, 0, s2.length());
-
- const QStringView v2(s2);
-
- QCOMPARE(sign(QString::compare(s1, s2)), csr);
- QCOMPARE(sign(QStringRef::compare(r1, r2)), csr);
- QCOMPARE(sign(s1.compare(s2)), csr);
- QCOMPARE(sign(s1.compare(r2)), csr);
- QCOMPARE(sign(r1.compare(r2)), csr);
- QCOMPARE(sign(s1.compare(v2)), csr);
-
- QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(s1.compare(r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(s1.compare(r2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(s1.compare(v2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(s1.compare(v2, Qt::CaseInsensitive)), cir);
-
- QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir);
-
- if (csr == 0) {
- QVERIFY(qHash(s1) == qHash(s2));
- QVERIFY(qHash(s1) == qHash(r2));
- QVERIFY(qHash(r1) == qHash(s2));
- QVERIFY(qHash(r1) == qHash(r2));
- }
-
- if (!cir) {
- QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded());
- }
-
- if (isLatin(s2)) {
- QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()))), csr);
- QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()))), csr);
- QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir);
- QByteArray l1 = s2.toLatin1();
- l1 += "x";
- QLatin1String l1str(l1.constData(), l1.size() - 1);
- QCOMPARE(sign(QString::compare(s1, l1str)), csr);
- QCOMPARE(sign(QString::compare(s1, l1str, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QStringRef::compare(r1, l1str)), csr);
- QCOMPARE(sign(QStringRef::compare(r1, l1str, Qt::CaseInsensitive)), cir);
- }
-
- if (isLatin(s1)) {
- QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2)), csr);
- QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2, Qt::CaseInsensitive)), cir);
- }
-}
-
-void tst_QString::resize()
-{
- QString s = QLatin1String("hello world");
-
- s.resize(5);
- QCOMPARE(s, QLatin1String("hello"));
- s.resize(8);
- QCOMPARE(s.size(), 8);
- QVERIFY(s.startsWith(QLatin1String("hello")));
-
- s.resize(10, QLatin1Char('n'));
- QCOMPARE(s.size(), 10);
- QVERIFY(s.startsWith(QLatin1String("hello")));
- QCOMPARE(s.right(2), QLatin1String("nn"));
-}
-
-void tst_QString::resizeAfterFromRawData()
-{
- QString buffer("hello world");
-
- QString array = QString::fromRawData(buffer.constData(), buffer.size());
- QVERIFY(array.constData() == buffer.constData());
- array.resize(5);
- QVERIFY(array.constData() == buffer.constData());
-}
-
-void tst_QString::resizeAfterReserve()
-{
-
- QString s;
- s.reserve(100);
-
- s += "hello world";
-
- // resize should not affect capacity
- s.resize(s.size());
- QVERIFY(s.capacity() == 100);
-
- // but squeeze does
- s.squeeze();
- QVERIFY(s.capacity() == s.size());
-
- // clear does too
- s.clear();
- QVERIFY(s.capacity() == 0);
-
- // test resize(0) border case
- s.reserve(100);
- s += "hello world";
- s.resize(0);
- QVERIFY(s.capacity() == 100);
-
- // reserve() can't be used to truncate data
- s.fill('x', 100);
- s.reserve(50);
- QVERIFY(s.capacity() == 100);
- QVERIFY(s.size() == 100);
-
- // even with increased ref count truncation isn't allowed
- QString t = s;
- s.reserve(50);
- QVERIFY(s.capacity() == 100);
- QVERIFY(s.size() == 100);
-}
-
-void tst_QString::resizeWithNegative() const
-{
- {
- QString string(QLatin1String("input"));
- string.resize(-1);
- QCOMPARE(string, QString());
- }
-
- {
- QString string(QLatin1String("input"));
- string.resize(-9099);
- QCOMPARE(string, QString());
- }
-
- {
- /* Example code from customer. */
- QString s(QLatin1String("hola"));
- s.reserve(1);
- s.resize(-1);
- QCOMPARE(s, QString());
- }
-}
-
-void tst_QString::truncateWithNegative() const
-{
- {
- QString string(QLatin1String("input"));
- string.truncate(-1);
- QCOMPARE(string, QString());
- }
-
- {
- QString string(QLatin1String("input"));
- string.truncate(-9099);
- QCOMPARE(string, QString());
- }
-
- {
- /* Example code from customer. */
- QString test(QLatin1String("c"));
-
- test.replace(QRegExp(QLatin1String("c")), QLatin1String("z"));
- test.truncate(-1);
- QCOMPARE(test, QString());
- }
-}
-
-void tst_QString::QCharRefMutableUnicode() const
-{
- QString str;
- str.resize(3);
- str[0].unicode() = 115;
- str[1].unicode() = 116;
- str[2].unicode() = 114;
-
- QCOMPARE(str, QString::fromLatin1("str"));
-}
-
-void tst_QString::QCharRefDetaching() const
-{
- {
- QString str = QString::fromLatin1("str");
- QString copy;
- copy[0] = QLatin1Char('S');
-
- QCOMPARE(str, QString::fromLatin1("str"));
- }
-
- {
- ushort buf[] = { 's', 't', 'r' };
- QString str = QString::fromRawData((const QChar *)buf, 3);
- str[0] = QLatin1Char('S');
-
- QCOMPARE(buf[0], ushort('s'));
- }
-
- {
- static const ushort buf[] = { 's', 't', 'r' };
- QString str = QString::fromRawData((const QChar *)buf, 3);
-
- // this causes a crash in most systems if the detaching doesn't work
- str[0] = QLatin1Char('S');
-
- QCOMPARE(buf[0], ushort('s'));
- }
-}
-
-void tst_QString::sprintfZU() const
-{
- {
- QString string;
- size_t s = 6;
- string.sprintf("%zu", s);
- QCOMPARE(string, QString::fromLatin1("6"));
- }
-
- {
- QString string;
- string.sprintf("%s\n", "foo");
- QCOMPARE(string, QString::fromLatin1("foo\n"));
- }
-
- {
- /* This code crashed. I don't know how to reduce it further. In other words,
- * both %zu and %s needs to be present. */
- size_t s = 6;
- QString string;
- string.sprintf("%zu%s", s, "foo");
- QCOMPARE(string, QString::fromLatin1("6foo"));
- }
-
- {
- size_t s = 6;
- QString string;
- string.sprintf("%zu %s\n", s, "foo");
- QCOMPARE(string, QString::fromLatin1("6 foo\n"));
- }
-}
-
-void tst_QString::repeatedSignature() const
-{
- /* repated() should be a const member. */
- const QString string;
- (void) string.repeated(3);
-}
-
-void tst_QString::repeated() const
-{
- QFETCH(QString, string);
- QFETCH(QString, expected);
- QFETCH(int, count);
-
- QCOMPARE(string.repeated(count), expected);
-}
-
-void tst_QString::repeated_data() const
-{
- QTest::addColumn<QString>("string" );
- QTest::addColumn<QString>("expected" );
- QTest::addColumn<int>("count" );
-
- /* Empty strings. */
- QTest::newRow("data1")
- << QString()
- << QString()
- << 0;
-
- QTest::newRow("data2")
- << QString()
- << QString()
- << -1004;
-
- QTest::newRow("data3")
- << QString()
- << QString()
- << 1;
-
- QTest::newRow("data4")
- << QString()
- << QString()
- << 5;
-
- /* On simple string. */
- QTest::newRow("data5")
- << QString(QLatin1String("abc"))
- << QString()
- << -1004;
-
- QTest::newRow("data6")
- << QString(QLatin1String("abc"))
- << QString()
- << -1;
-
- QTest::newRow("data7")
- << QString(QLatin1String("abc"))
- << QString()
- << 0;
-
- QTest::newRow("data8")
- << QString(QLatin1String("abc"))
- << QString(QLatin1String("abc"))
- << 1;
-
- QTest::newRow("data9")
- << QString(QLatin1String("abc"))
- << QString(QLatin1String("abcabc"))
- << 2;
-
- QTest::newRow("data10")
- << QString(QLatin1String("abc"))
- << QString(QLatin1String("abcabcabc"))
- << 3;
-
- QTest::newRow("data11")
- << QString(QLatin1String("abc"))
- << QString(QLatin1String("abcabcabcabc"))
- << 4;
-}
-
-void tst_QString::compareRef()
-{
- QString a = "ABCDEFGH";
-
- QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("BC")), 0);
- QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("BCD")) < 0);
- QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("Bc"), Qt::CaseInsensitive), 0);
- QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("bCD"), Qt::CaseInsensitive) < 0);
-
- QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BC")), 0);
- QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BCD")) < 0);
- QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("Bc"), Qt::CaseInsensitive), 0);
- QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("bCD"), Qt::CaseInsensitive) < 0);
-
- QCOMPARE(QString::fromLatin1("BC").compare(QStringRef(&a, 1, 2)), 0);
- QVERIFY(QString::fromLatin1("BCD").compare(QStringRef(&a, 1, 2)) > 0);
- QCOMPARE(QString::fromLatin1("Bc").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0);
- QVERIFY(QString::fromLatin1("bCD").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive) > 0);
-
- QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2)), 0);
- QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3)) < 0);
- QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0);
- QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0);
-
- QString a2 = "ABCDEFGh";
- QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2)), 0);
- QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3)) < 0);
- QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0);
- QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0);
-}
-
-void tst_QString::arg_locale()
-{
- QLocale l(QLocale::English, QLocale::UnitedKingdom);
- QString str("*%L1*%L2*");
-
- TransientDefaultLocale transient(l);
- QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123,456*1,234.56*"));
-
- l.setNumberOptions(QLocale::OmitGroupSeparator);
- transient.revise(l);
- QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*"));
-
- transient.revise(QLocale::C);
- QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*"));
-}
-
-
-#ifdef QT_USE_ICU
-// Qt has to be built with ICU support
-void tst_QString::toUpperLower_icu()
-{
- QString s = QString::fromLatin1("i");
-
- QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
- QCOMPARE(s.toLower(), QString::fromLatin1("i"));
-
- TransientDefaultLocale transient(QLocale(QLocale::Turkish, QLocale::Turkey));
-
- QCOMPARE(s.toUpper(), QString::fromLatin1("I"));
- QCOMPARE(s.toLower(), QString::fromLatin1("i"));
-
- // turkish locale has a capital I with a dot (U+0130, utf8 c4b0)
- QLocale l;
-
- QCOMPARE(l.toUpper(s), QString::fromUtf8("\xc4\xb0"));
- QCOMPARE(l.toLower(QString::fromUtf8("\xc4\xb0")), s);
-
- // nothing should happen here
- QCOMPARE(l.toLower(s), s);
- QCOMPARE(l.toUpper(QString::fromLatin1("I")), QString::fromLatin1("I"));
-
- // U+0131, utf8 c4b1 is the lower-case i without a dot
- QString sup = QString::fromUtf8("\xc4\xb1");
-
- QCOMPARE(l.toUpper(sup), QString::fromLatin1("I"));
- QCOMPARE(l.toLower(QString::fromLatin1("I")), sup);
-
- // nothing should happen here
- QCOMPARE(l.toLower(sup), sup);
- QCOMPARE(l.toLower(QString::fromLatin1("i")), QString::fromLatin1("i"));
-}
-#endif
-
-#if !defined(QT_NO_UNICODE_LITERAL) && defined(Q_COMPILER_LAMBDA)
-// Only tested on c++0x compliant compiler or gcc
-void tst_QString::literals()
-{
- QString str(QStringLiteral("abcd"));
-
- QVERIFY(str.length() == 4);
- QVERIFY(str == QLatin1String("abcd"));
- QVERIFY(str.data_ptr()->ref.isStatic());
- QVERIFY(str.data_ptr()->offset == sizeof(QStringData));
-
- const QChar *s = str.constData();
- QString str2 = str;
- QVERIFY(str2.constData() == s);
-
- // detach on non const access
- QVERIFY(str.data() != s);
-
- QVERIFY(str2.constData() == s);
- QVERIFY(str2.data() != s);
-}
-#endif
-
-void tst_QString::eightBitLiterals_data()
-{
- QTest::addColumn<QByteArray>("data");
- QTest::addColumn<QString>("stringData");
-
- QTest::newRow("null") << QByteArray() << QString();
- QTest::newRow("empty") << QByteArray("") << QString("");
- QTest::newRow("regular") << QByteArray("foo") << "foo";
- QTest::newRow("non-ascii") << QByteArray("\xc3\xa9") << QString::fromLatin1("\xe9");
-}
-
-void tst_QString::eightBitLiterals()
-{
- QFETCH(QByteArray, data);
- QFETCH(QString, stringData);
-
- {
- QString s(data);
- QCOMPARE(s, stringData);
- }
- {
- QString s(data.constData());
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s = data;
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s = data.constData();
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s.append(data);
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s.append(data.constData());
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s += data;
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s += data.constData();
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s.prepend(data);
- QCOMPARE(s, stringData);
- }
- {
- QString s;
- s.prepend(data.constData());
- QCOMPARE(s, stringData);
- }
- {
- QString s = QString() + data;
- QCOMPARE(s, stringData);
- }
- {
- QString s = QString() + data.constData();
- QCOMPARE(s, stringData);
- }
- {
- QString s = data + QString();
- QCOMPARE(s, stringData);
- }
- {
- QString s = QString() % data;
- QCOMPARE(s, stringData);
- }
- {
- QString s = QString() % data.constData();
- QCOMPARE(s, stringData);
- }
- {
- QString s = data % QString();
- QCOMPARE(s, stringData);
- }
-
- {
- QVERIFY(stringData == data);
- QVERIFY(stringData == data.constData());
- QVERIFY(!(stringData != data));
- QVERIFY(!(stringData != data.constData()));
- QVERIFY(!(stringData < data));
- QVERIFY(!(stringData < data.constData()));
- QVERIFY(!(stringData > data));
- QVERIFY(!(stringData > data.constData()));
- QVERIFY(stringData <= data);
- QVERIFY(stringData <= data.constData());
- QVERIFY(stringData >= data);
- QVERIFY(stringData >= data.constData());
- }
-}
-
-void tst_QString::reserve()
-{
- QString nil1, nil2;
- nil1.reserve(0);
- nil2.squeeze();
- nil1.squeeze();
- nil2.reserve(0);
-}
-
-void tst_QString::toHtmlEscaped_data()
-{
- QTest::addColumn<QString>("original");
- QTest::addColumn<QString>("expected");
-
- QTest::newRow("1") << "Hello World\n" << "Hello World\n";
- QTest::newRow("2") << "#include <QtCore>" << "#include &lt;QtCore&gt;";
- QTest::newRow("3") << "<p class=\"cool\"><a href=\"http://example.com/?foo=bar&amp;bar=foo\">plop --&gt; </a></p>"
- << "&lt;p class=&quot;cool&quot;&gt;&lt;a href=&quot;http://example.com/?foo=bar&amp;amp;bar=foo&quot;&gt;plop --&amp;gt; &lt;/a&gt;&lt;/p&gt;";
- QTest::newRow("4") << QString::fromUtf8("<\320\222\321\201>") << QString::fromUtf8("&lt;\320\222\321\201&gt;");
-}
-
-void tst_QString::toHtmlEscaped()
-{
- QFETCH(QString, original);
- QFETCH(QString, expected);
-
- QCOMPARE(original.toHtmlEscaped(), expected);
-}
-
-void tst_QString::operatorGreaterWithQLatin1String()
-{
- QLatin1String latin1foo("fooZZ", 3);
- QString stringfoo = QString::fromLatin1("foo");
- QVERIFY(stringfoo >= latin1foo);
- QVERIFY(!(stringfoo > latin1foo));
- QVERIFY(stringfoo <= latin1foo);
- QVERIFY(!(stringfoo < latin1foo));
-}
-
-void tst_QString::compareQLatin1Strings()
-{
- QLatin1String abc("abc");
- QLatin1String abcd("abcd");
- QLatin1String cba("cba");
- QLatin1String de("de");
-
- QVERIFY(abc == abc);
- QVERIFY(!(abc == cba));
- QVERIFY(!(cba == abc));
- QVERIFY(!(abc == abcd));
- QVERIFY(!(abcd == abc));
-
- QVERIFY(abc != cba);
- QVERIFY(!(abc != abc));
- QVERIFY(cba != abc);
- QVERIFY(abc != abcd);
- QVERIFY(abcd != abc);
-
- QVERIFY(abc < abcd);
- QVERIFY(abc < cba);
- QVERIFY(abc < de);
- QVERIFY(abcd < cba);
- QVERIFY(!(abc < abc));
- QVERIFY(!(abcd < abc));
- QVERIFY(!(de < cba));
-
- QVERIFY(abcd > abc);
- QVERIFY(cba > abc);
- QVERIFY(de > abc);
- QVERIFY(!(abc > abc));
- QVERIFY(!(abc > abcd));
- QVERIFY(!(abcd > cba));
-
- QVERIFY(abc <= abc);
- QVERIFY(abc <= abcd);
- QVERIFY(abc <= cba);
- QVERIFY(abc <= de);
- QVERIFY(!(abcd <= abc));
- QVERIFY(!(cba <= abc));
- QVERIFY(!(cba <= abcd));
- QVERIFY(!(de <= abc));
-
- QVERIFY(abc >= abc);
- QVERIFY(abcd >= abc);
- QVERIFY(!(abc >= abcd));
- QVERIFY(cba >= abc);
- QVERIFY(!(abc >= cba));
- QVERIFY(de >= abc);
- QVERIFY(!(abc >= de));
-
- QLatin1String subfoo("fooZZ", 3);
- QLatin1String foo("foo");
- QVERIFY(subfoo == foo);
- QVERIFY(foo == subfoo);
- QVERIFY(!(subfoo != foo));
- QVERIFY(!(foo != subfoo));
- QVERIFY(!(foo < subfoo));
- QVERIFY(!(subfoo < foo));
- QVERIFY(foo >= subfoo);
- QVERIFY(subfoo >= foo);
- QVERIFY(!(foo > subfoo));
- QVERIFY(!(subfoo > foo));
- QVERIFY(foo <= subfoo);
- QVERIFY(subfoo <= foo);
-
- QLatin1String subabc("abcZZ", 3);
- QLatin1String subab("abcZZ", 2);
- QVERIFY(subabc != subab);
- QVERIFY(subab != subabc);
- QVERIFY(!(subabc == subab));
- QVERIFY(!(subab == subabc));
- QVERIFY(subab < subabc);
- QVERIFY(!(subabc < subab));
- QVERIFY(subabc > subab);
- QVERIFY(!(subab > subabc));
- QVERIFY(subab <= subabc);
- QVERIFY(!(subabc <= subab));
- QVERIFY(subabc >= subab);
- QVERIFY(!(subab >= subabc));
-}
-
-void tst_QString::fromQLatin1StringWithLength()
-{
- QLatin1String latin1foo("foobar", 3);
- QString foo(latin1foo);
- QCOMPARE(foo.size(), latin1foo.size());
- QCOMPARE(foo, QString::fromLatin1("foo"));
-}
-
-void tst_QString::assignQLatin1String()
-{
- QString empty = QLatin1String("");
- QVERIFY(empty.isEmpty());
- QVERIFY(!empty.isNull());
-
- QString null = QLatin1String(0);
- QVERIFY(null.isEmpty());
- QVERIFY(null.isNull());
-
- QLatin1String latin1foo("foo");
- QString foo = latin1foo;
- QCOMPARE(foo.size(), latin1foo.size());
- QCOMPARE(foo, QString::fromLatin1("foo"));
-
- QLatin1String latin1subfoo("foobar", 3);
- foo = latin1subfoo;
- QCOMPARE(foo.size(), latin1subfoo.size());
- QCOMPARE(foo, QString::fromLatin1("foo"));
-
- // check capacity re-use:
- QString s;
- QCOMPARE(s.capacity(), 0);
-
- // assign to null QString:
- s = latin1foo;
- QCOMPARE(s, QString::fromLatin1("foo"));
- QCOMPARE(s.capacity(), 3);
-
- // assign to non-null QString with enough capacity:
- s = QString::fromLatin1("foofoo");
- const int capacity = s.capacity();
- s = latin1foo;
- QCOMPARE(s, QString::fromLatin1("foo"));
- QCOMPARE(s.capacity(), capacity);
-
- // assign to shared QString (enough capacity, but can't use):
- s = QString::fromLatin1("foofoo");
- QString s2 = s;
- s = latin1foo;
- QCOMPARE(s, QString::fromLatin1("foo"));
- QCOMPARE(s.capacity(), 3);
-
- // assign to QString with too little capacity:
- s = QString::fromLatin1("fo");
- QCOMPARE(s.capacity(), 2);
- s = latin1foo;
- QCOMPARE(s, QString::fromLatin1("foo"));
- QCOMPARE(s.capacity(), 3);
-
-}
-
-void tst_QString::assignQChar()
-{
- const QChar sp = QLatin1Char(' ');
- QString s;
- QCOMPARE(s.capacity(), 0);
-
- // assign to null QString:
- s = sp;
- QCOMPARE(s, QString(sp));
- QCOMPARE(s.capacity(), 1);
-
- // assign to non-null QString with enough capacity:
- s = QLatin1String("foo");
- const int capacity = s.capacity();
- QCOMPARE(capacity, 3);
- s = sp;
- QCOMPARE(s, QString(sp));
- QCOMPARE(s.capacity(), capacity);
-
- // assign to shared QString (enough capacity, but can't use):
- s = QLatin1String("foo");
- QString s2 = s;
- s = sp;
- QCOMPARE(s, QString(sp));
- QCOMPARE(s.capacity(), 1);
-
- // assign to empty QString:
- s = QString("");
- s.detach();
- QCOMPARE(s.capacity(), 0);
- s = sp;
- QCOMPARE(s, QString(sp));
- QCOMPARE(s.capacity(), 1);
-}
-
-void tst_QString::isRightToLeft_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<bool>("rtl");
-
- QTest::newRow("null") << QString() << false;
- QTest::newRow("empty") << QString("") << false;
-
- QTest::newRow("numbers-only") << QString("12345") << false;
- QTest::newRow("latin1-only") << QString("hello") << false;
- QTest::newRow("numbers-latin1") << (QString("12345") + QString("hello")) << false;
-
- static const ushort unicode1[] = { 0x627, 0x627 };
- QTest::newRow("arabic-only") << QString::fromUtf16(unicode1, 2) << true;
- QTest::newRow("numbers-arabic") << (QString("12345") + QString::fromUtf16(unicode1, 2)) << true;
- QTest::newRow("numbers-latin1-arabic") << (QString("12345") + QString("hello") + QString::fromUtf16(unicode1, 2)) << false;
- QTest::newRow("numbers-arabic-latin1") << (QString("12345") + QString::fromUtf16(unicode1, 2) + QString("hello")) << true;
-
- static const ushort unicode2[] = { QChar::highSurrogate(0xE01DAu), QChar::lowSurrogate(0xE01DAu), QChar::highSurrogate(0x2F800u), QChar::lowSurrogate(0x2F800u) };
- QTest::newRow("surrogates-VS-CJK") << QString::fromUtf16(unicode2, 4) << false;
-
- static const ushort unicode3[] = { QChar::highSurrogate(0x10800u), QChar::lowSurrogate(0x10800u), QChar::highSurrogate(0x10805u), QChar::lowSurrogate(0x10805u) };
- QTest::newRow("surrogates-cypriot") << QString::fromUtf16(unicode3, 4) << true;
-
- QTest::newRow("lre") << (QString("12345") + QChar(0x202a) + QString("9") + QChar(0x202c)) << false;
- QTest::newRow("rle") << (QString("12345") + QChar(0x202b) + QString("9") + QChar(0x202c)) << false;
- QTest::newRow("r in lre") << (QString("12345") + QChar(0x202a) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + QString("a")) << true;
- QTest::newRow("l in lre") << (QString("12345") + QChar(0x202a) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
- QTest::newRow("r in rle") << (QString("12345") + QChar(0x202b) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + QString("a")) << true;
- QTest::newRow("l in rle") << (QString("12345") + QChar(0x202b) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
-
- QTest::newRow("lro") << (QString("12345") + QChar(0x202d) + QString("9") + QChar(0x202c)) << false;
- QTest::newRow("rlo") << (QString("12345") + QChar(0x202e) + QString("9") + QChar(0x202c)) << false;
- QTest::newRow("r in lro") << (QString("12345") + QChar(0x202d) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + QString("a")) << true;
- QTest::newRow("l in lro") << (QString("12345") + QChar(0x202d) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
- QTest::newRow("r in rlo") << (QString("12345") + QChar(0x202e) + QString::fromUtf16(unicode1, 2) + QChar(0x202c) + QString("a")) << true;
- QTest::newRow("l in rlo") << (QString("12345") + QChar(0x202e) + QString("a") + QChar(0x202c) + QString::fromUtf16(unicode1, 2)) << false;
-
- QTest::newRow("lri") << (QString("12345") + QChar(0x2066) + QString("a") + QChar(0x2069) + QString::fromUtf16(unicode1, 2)) << true;
- QTest::newRow("rli") << (QString("12345") + QChar(0x2067) + QString::fromUtf16(unicode1, 2) + QChar(0x2069) + QString("a")) << false;
- QTest::newRow("fsi1") << (QString("12345") + QChar(0x2068) + QString("a") + QChar(0x2069) + QString::fromUtf16(unicode1, 2)) << true;
- QTest::newRow("fsi2") << (QString("12345") + QChar(0x2068) + QString::fromUtf16(unicode1, 2) + QChar(0x2069) + QString("a")) << false;
-}
-
-void tst_QString::isRightToLeft()
-{
- QFETCH(QString, unicode);
- QFETCH(bool, rtl);
-
- QCOMPARE(unicode.isRightToLeft(), rtl);
-}
-
-QTEST_APPLESS_MAIN(tst_QString)
-
-#include "tst_qstring.moc"
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm b/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm
deleted file mode 100644
index 60bd3f9b15..0000000000
--- a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QString>
-#include <QtTest/QtTest>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-void tst_QString_macTypes()
-{
- // QString <-> CFString
- {
- QString qtString("test string");
- const CFStringRef cfString = qtString.toCFString();
- QCOMPARE(QString::fromCFString(cfString), qtString);
- CFRelease(cfString);
- }
- {
- QString qtString("test string");
- const CFStringRef cfString = qtString.toCFString();
- QString qtStringCopy(qtString);
- qtString = qtString.toUpper(); // modify
- QCOMPARE(QString::fromCFString(cfString), qtStringCopy);
- }
- // QString <-> NSString
- {
- QMacAutoReleasePool pool;
-
- QString qtString("test string");
- const NSString *nsString = qtString.toNSString();
- QCOMPARE(QString::fromNSString(nsString), qtString);
- }
- {
- QMacAutoReleasePool pool;
-
- QString qtString("test string");
- const NSString *nsString = qtString.toNSString();
- QString qtStringCopy(qtString);
- qtString = qtString.toUpper(); // modify
- QCOMPARE(QString::fromNSString(nsString), qtStringCopy);
- }
-}
diff --git a/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro b/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro
deleted file mode 100644
index 14dbe779db..0000000000
--- a/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstring_no_cast_from_bytearray
-QT = core testlib
-SOURCES = tst_qstring_no_cast_from_bytearray.cpp
-DEFINES += QT_NO_CAST_FROM_BYTEARRAY
-
diff --git a/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp b/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp
deleted file mode 100644
index 47fbeb6069..0000000000
--- a/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QtCore>
-
-class tst_QString_NoCastFromByteArray: public QObject
-{
- Q_OBJECT
-private Q_SLOTS:
- void initTestCase();
-};
-
-void tst_QString_NoCastFromByteArray::initTestCase()
-{
- QWARN("This is a compile test only");
-}
-
-QTEST_APPLESS_MAIN(tst_QString_NoCastFromByteArray)
-
-#include "tst_qstring_no_cast_from_bytearray.moc"
diff --git a/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro b/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro
deleted file mode 100644
index a4e91e38bd..0000000000
--- a/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringapisymmetry
-QT = core testlib
-SOURCES = tst_qstringapisymmetry.cpp
-qtConfig(c++14): CONFIG += c++14
-qtConfig(c++1z): CONFIG += c++1z
diff --git a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp
deleted file mode 100644
index cb1fd9eb7d..0000000000
--- a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp
+++ /dev/null
@@ -1,1221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#undef QT_NO_CAST_FROM_ASCII
-#undef QT_NO_CAST_TO_ASCII
-#undef QT_ASCII_CAST_WARNINGS
-
-#include <QString>
-#include <QStringView>
-#include <QChar>
-#include <QScopedArrayPointer>
-#include <QStringRef>
-#include <QLatin1String>
-#include <QVector>
-
-#include <QTest>
-
-Q_DECLARE_METATYPE(QLatin1String)
-Q_DECLARE_METATYPE(QStringRef)
-
-template <typename T>
-QString toQString(const T &t) { return QString(t); }
-QString toQString(const QStringRef &ref) { return ref.toString(); }
-QString toQString(QStringView view) { return view.toString(); }
-
-// FIXME: these are missing at the time of writing, add them, then remove the dummies here:
-#define MAKE_RELOP(op, A1, A2) \
- static bool operator op (A1 lhs, A2 rhs) \
- { return toQString(lhs) op toQString(rhs); } \
- /*end*/
-#define MAKE_ALL(A1, A2) \
- MAKE_RELOP(==, A1, A2) \
- MAKE_RELOP(!=, A1, A2) \
- MAKE_RELOP(<, A1, A2) \
- MAKE_RELOP(>, A1, A2) \
- MAKE_RELOP(<=, A1, A2) \
- MAKE_RELOP(>=, A1, A2) \
- /*end*/
-
-MAKE_ALL(QByteArray, QChar)
-MAKE_ALL(QByteArray, QLatin1String)
-
-MAKE_ALL(const char*, QChar)
-
-#undef MAKE_ALL
-#undef MAKE_RELOP
-// END FIXME
-
-// Return a plain ASCII row name consisting of maximum 16 chars and the
-// size for data
-static QByteArray rowName(const QByteArray &data)
-{
- const int size = data.size();
- QScopedArrayPointer<char> prettyC(QTest::toPrettyCString(data.constData(), qMin(16, size)));
- QByteArray result = prettyC.data();
- result += " (";
- result += QByteArray::number(size);
- result += ')';
- return result;
-}
-
-class tst_QStringApiSymmetry : public QObject
-{
- Q_OBJECT
-
- //
- // Mixed UTF-16, UTF-8, Latin-1 checks:
- //
-
- void compare_data(bool hasConceptOfNullAndEmpty=true);
- template <typename LHS, typename RHS>
- void compare_impl() const;
-
-private Q_SLOTS:
- // test all combinations of {QChar, QStringRef, QString, QStringView, QLatin1String, QByteArray, const char*}
- void compare_QChar_QChar_data() { compare_data(false); }
- void compare_QChar_QChar() { compare_impl<QChar, QChar>(); }
- void compare_QChar_QStringRef_data() { compare_data(false); }
- void compare_QChar_QStringRef() { compare_impl<QChar, QStringRef>(); }
- void compare_QChar_QString_data() { compare_data(false); }
- void compare_QChar_QString() { compare_impl<QChar, QString>(); }
- void compare_QChar_QStringView_data() { compare_data(false); }
- void compare_QChar_QStringView() { compare_impl<QChar, QStringView>(); }
- void compare_QChar_QLatin1String_data() { compare_data(false); }
- void compare_QChar_QLatin1String() { compare_impl<QChar, QLatin1String>(); }
- void compare_QChar_QByteArray_data() { compare_data(false); }
- void compare_QChar_QByteArray() { compare_impl<QChar, QByteArray>(); }
- void compare_QChar_const_char_star_data() { compare_data(false); }
- void compare_QChar_const_char_star() { compare_impl<QChar, const char *>(); }
-
- void compare_QStringRef_QChar_data() { compare_data(false); }
- void compare_QStringRef_QChar() { compare_impl<QStringRef, QChar>(); }
- void compare_QStringRef_QStringRef_data() { compare_data(); }
- void compare_QStringRef_QStringRef() { compare_impl<QStringRef, QStringRef>(); }
- void compare_QStringRef_QString_data() { compare_data(); }
- void compare_QStringRef_QString() { compare_impl<QStringRef, QString>(); }
- void compare_QStringRef_QStringView_data() { compare_data(); }
- void compare_QStringRef_QStringView() { compare_impl<QStringRef, QStringView>(); }
- void compare_QStringRef_QLatin1String_data() { compare_data(); }
- void compare_QStringRef_QLatin1String() { compare_impl<QStringRef, QLatin1String>(); }
- void compare_QStringRef_QByteArray_data() { compare_data(); }
- void compare_QStringRef_QByteArray() { compare_impl<QStringRef, QByteArray>(); }
- void compare_QStringRef_const_char_star_data() { compare_data(); }
- void compare_QStringRef_const_char_star() { compare_impl<QStringRef, const char *>(); }
-
- void compare_QString_QChar_data() { compare_data(false); }
- void compare_QString_QChar() { compare_impl<QString, QChar>(); }
- void compare_QString_QStringRef_data() { compare_data(); }
- void compare_QString_QStringRef() { compare_impl<QString, QStringRef>(); }
- void compare_QString_QString_data() { compare_data(); }
- void compare_QString_QString() { compare_impl<QString, QString>(); }
- void compare_QString_QStringView_data() { compare_data(); }
- void compare_QString_QStringView() { compare_impl<QString, QStringView>(); }
- void compare_QString_QLatin1String_data() { compare_data(); }
- void compare_QString_QLatin1String() { compare_impl<QString, QLatin1String>(); }
- void compare_QString_QByteArray_data() { compare_data(); }
- void compare_QString_QByteArray() { compare_impl<QString, QByteArray>(); }
- void compare_QString_const_char_star_data() { compare_data(); }
- void compare_QString_const_char_star() { compare_impl<QString, const char *>(); }
-
- void compare_QStringView_QChar_data() { compare_data(false); }
- void compare_QStringView_QChar() { compare_impl<QStringView, QChar>(); }
- void compare_QStringView_QStringRef_data() { compare_data(); }
- void compare_QStringView_QStringRef() { compare_impl<QStringView, QStringRef>(); }
- void compare_QStringView_QString_data() { compare_data(); }
- void compare_QStringView_QString() { compare_impl<QStringView, QString>(); }
- void compare_QStringView_QStringView_data() { compare_data(); }
- void compare_QStringView_QStringView() { compare_impl<QStringView, QStringView>(); }
- void compare_QStringView_QLatin1String_data() { compare_data(); }
- void compare_QStringView_QLatin1String() { compare_impl<QStringView, QLatin1String>(); }
-
- void compare_QLatin1String_QChar_data() { compare_data(false); }
- void compare_QLatin1String_QChar() { compare_impl<QLatin1String, QChar>(); }
- void compare_QLatin1String_QStringRef_data() { compare_data(); }
- void compare_QLatin1String_QStringRef() { compare_impl<QLatin1String, QStringRef>(); }
- void compare_QLatin1String_QString_data() { compare_data(); }
- void compare_QLatin1String_QString() { compare_impl<QLatin1String, QString>(); }
- void compare_QLatin1String_QStringView_data() { compare_data(); }
- void compare_QLatin1String_QStringView() { compare_impl<QLatin1String, QStringView>(); }
- void compare_QLatin1String_QLatin1String_data() { compare_data(); }
- void compare_QLatin1String_QLatin1String() { compare_impl<QLatin1String, QLatin1String>(); }
- void compare_QLatin1String_QByteArray_data() { compare_data(); }
- void compare_QLatin1String_QByteArray() { compare_impl<QLatin1String, QByteArray>(); }
- void compare_QLatin1String_const_char_star_data() { compare_data(); }
- void compare_QLatin1String_const_char_star() { compare_impl<QLatin1String, const char *>(); }
-
- void compare_QByteArray_QChar_data() { compare_data(false); }
- void compare_QByteArray_QChar() { compare_impl<QByteArray, QChar>(); }
- void compare_QByteArray_QStringRef_data() { compare_data(); }
- void compare_QByteArray_QStringRef() { compare_impl<QByteArray, QStringRef>(); }
- void compare_QByteArray_QString_data() { compare_data(); }
- void compare_QByteArray_QString() { compare_impl<QByteArray, QString>(); }
- void compare_QByteArray_QLatin1String_data() { compare_data(); }
- void compare_QByteArray_QLatin1String() { compare_impl<QByteArray, QLatin1String>(); }
- void compare_QByteArray_QByteArray_data() { compare_data(); }
- void compare_QByteArray_QByteArray() { compare_impl<QByteArray, QByteArray>(); }
- void compare_QByteArray_const_char_star_data() { compare_data(); }
- void compare_QByteArray_const_char_star() { compare_impl<QByteArray, const char *>(); }
-
- void compare_const_char_star_QChar_data() { compare_data(false); }
- void compare_const_char_star_QChar() { compare_impl<const char *, QChar>(); }
- void compare_const_char_star_QStringRef_data() { compare_data(); }
- void compare_const_char_star_QStringRef() { compare_impl<const char *, QStringRef>(); }
- void compare_const_char_star_QString_data() { compare_data(); }
- void compare_const_char_star_QString() { compare_impl<const char *, QString>(); }
- void compare_const_char_star_QLatin1String_data() { compare_data(false); }
- void compare_const_char_star_QLatin1String() { compare_impl<const char *, QLatin1String>(); }
- void compare_const_char_star_QByteArray_data() { compare_data(); }
- void compare_const_char_star_QByteArray() { compare_impl<const char *, QByteArray>(); }
- //void compare_const_char_star_const_char_star_data() { compare_data(); }
- //void compare_const_char_star_const_char_star() { compare_impl<const char *, const char *>(); }
-
-private:
- void startsWith_data(bool rhsIsQChar = false);
- template <typename Haystack, typename Needle> void startsWith_impl() const;
-
- void endsWith_data(bool rhsIsQChar = false);
- template <typename Haystack, typename Needle> void endsWith_impl() const;
-
-private Q_SLOTS:
- // test all combinations of {QString, QStringRef, QStringView, QLatin1String} x {QString, QStringRef, QStringView, QLatin1String, QChar}:
- void startsWith_QString_QString_data() { startsWith_data(); }
- void startsWith_QString_QString() { startsWith_impl<QString, QString>(); }
- void startsWith_QString_QStringRef_data() { startsWith_data(); }
- void startsWith_QString_QStringRef() { startsWith_impl<QString, QStringRef>(); }
- void startsWith_QString_QStringView_data() { startsWith_data(); }
- void startsWith_QString_QStringView() { startsWith_impl<QString, QStringView>(); }
- void startsWith_QString_QLatin1String_data() { startsWith_data(); }
- void startsWith_QString_QLatin1String() { startsWith_impl<QString, QLatin1String>(); }
- void startsWith_QString_QChar_data() { startsWith_data(false); }
- void startsWith_QString_QChar() { startsWith_impl<QString, QChar>(); }
-
- void startsWith_QStringRef_QString_data() { startsWith_data(); }
- void startsWith_QStringRef_QString() { startsWith_impl<QStringRef, QString>(); }
- void startsWith_QStringRef_QStringRef_data() { startsWith_data(); }
- void startsWith_QStringRef_QStringRef() { startsWith_impl<QStringRef, QStringRef>(); }
- void startsWith_QStringRef_QStringView_data() { startsWith_data(); }
- void startsWith_QStringRef_QStringView() { startsWith_impl<QStringRef, QStringView>(); }
- void startsWith_QStringRef_QLatin1String_data() { startsWith_data(); }
- void startsWith_QStringRef_QLatin1String() { startsWith_impl<QStringRef, QLatin1String>(); }
- void startsWith_QStringRef_QChar_data() { startsWith_data(false); }
- void startsWith_QStringRef_QChar() { startsWith_impl<QStringRef, QChar>(); }
-
- void startsWith_QStringView_QString_data() { startsWith_data(); }
- void startsWith_QStringView_QString() { startsWith_impl<QStringView, QString>(); }
- void startsWith_QStringView_QStringRef_data() { startsWith_data(); }
- void startsWith_QStringView_QStringRef() { startsWith_impl<QStringView, QStringRef>(); }
- void startsWith_QStringView_QStringView_data() { startsWith_data(); }
- void startsWith_QStringView_QStringView() { startsWith_impl<QStringView, QStringView>(); }
- void startsWith_QStringView_QLatin1String_data() { startsWith_data(); }
- void startsWith_QStringView_QLatin1String() { startsWith_impl<QStringView, QLatin1String>(); }
- void startsWith_QStringView_QChar_data() { startsWith_data(false); }
- void startsWith_QStringView_QChar() { startsWith_impl<QStringView, QChar>(); }
-
- void startsWith_QLatin1String_QString_data() { startsWith_data(); }
- void startsWith_QLatin1String_QString() { startsWith_impl<QLatin1String, QString>(); }
- void startsWith_QLatin1String_QStringRef_data() { startsWith_data(); }
- void startsWith_QLatin1String_QStringRef() { startsWith_impl<QLatin1String, QStringRef>(); }
- void startsWith_QLatin1String_QStringView_data() { startsWith_data(); }
- void startsWith_QLatin1String_QStringView() { startsWith_impl<QLatin1String, QStringView>(); }
- void startsWith_QLatin1String_QLatin1String_data() { startsWith_data(); }
- void startsWith_QLatin1String_QLatin1String() { startsWith_impl<QLatin1String, QLatin1String>(); }
- void startsWith_QLatin1String_QChar_data() { startsWith_data(false); }
- void startsWith_QLatin1String_QChar() { startsWith_impl<QLatin1String, QChar>(); }
-
- void endsWith_QString_QString_data() { endsWith_data(); }
- void endsWith_QString_QString() { endsWith_impl<QString, QString>(); }
- void endsWith_QString_QStringRef_data() { endsWith_data(); }
- void endsWith_QString_QStringRef() { endsWith_impl<QString, QStringRef>(); }
- void endsWith_QString_QStringView_data() { endsWith_data(); }
- void endsWith_QString_QStringView() { endsWith_impl<QString, QStringView>(); }
- void endsWith_QString_QLatin1String_data() { endsWith_data(); }
- void endsWith_QString_QLatin1String() { endsWith_impl<QString, QLatin1String>(); }
- void endsWith_QString_QChar_data() { endsWith_data(false); }
- void endsWith_QString_QChar() { endsWith_impl<QString, QChar>(); }
-
- void endsWith_QStringRef_QString_data() { endsWith_data(); }
- void endsWith_QStringRef_QString() { endsWith_impl<QStringRef, QString>(); }
- void endsWith_QStringRef_QStringRef_data() { endsWith_data(); }
- void endsWith_QStringRef_QStringRef() { endsWith_impl<QStringRef, QStringRef>(); }
- void endsWith_QStringRef_QStringView_data() { endsWith_data(); }
- void endsWith_QStringRef_QStringView() { endsWith_impl<QStringRef, QStringView>(); }
- void endsWith_QStringRef_QLatin1String_data() { endsWith_data(); }
- void endsWith_QStringRef_QLatin1String() { endsWith_impl<QStringRef, QLatin1String>(); }
- void endsWith_QStringRef_QChar_data() { endsWith_data(false); }
- void endsWith_QStringRef_QChar() { endsWith_impl<QStringRef, QChar>(); }
-
- void endsWith_QStringView_QString_data() { endsWith_data(); }
- void endsWith_QStringView_QString() { endsWith_impl<QStringView, QString>(); }
- void endsWith_QStringView_QStringRef_data() { endsWith_data(); }
- void endsWith_QStringView_QStringRef() { endsWith_impl<QStringView, QStringRef>(); }
- void endsWith_QStringView_QStringView_data() { endsWith_data(); }
- void endsWith_QStringView_QStringView() { endsWith_impl<QStringView, QStringView>(); }
- void endsWith_QStringView_QLatin1String_data() { endsWith_data(); }
- void endsWith_QStringView_QLatin1String() { endsWith_impl<QStringView, QLatin1String>(); }
- void endsWith_QStringView_QChar_data() { endsWith_data(false); }
- void endsWith_QStringView_QChar() { endsWith_impl<QStringView, QChar>(); }
-
- void endsWith_QLatin1String_QString_data() { endsWith_data(); }
- void endsWith_QLatin1String_QString() { endsWith_impl<QLatin1String, QString>(); }
- void endsWith_QLatin1String_QStringRef_data() { endsWith_data(); }
- void endsWith_QLatin1String_QStringRef() { endsWith_impl<QLatin1String, QStringRef>(); }
- void endsWith_QLatin1String_QStringView_data() { endsWith_data(); }
- void endsWith_QLatin1String_QStringView() { endsWith_impl<QLatin1String, QStringView>(); }
- void endsWith_QLatin1String_QLatin1String_data() { endsWith_data(); }
- void endsWith_QLatin1String_QLatin1String() { endsWith_impl<QLatin1String, QLatin1String>(); }
- void endsWith_QLatin1String_QChar_data() { endsWith_data(false); }
- void endsWith_QLatin1String_QChar() { endsWith_impl<QLatin1String, QChar>(); }
-
-private:
- void mid_data();
- template <typename String> void mid_impl();
-
- void left_data();
- template <typename String> void left_impl();
-
- void right_data();
- template <typename String> void right_impl();
-
- void chop_data();
- template <typename String> void chop_impl();
-
- void truncate_data() { left_data(); }
- template <typename String> void truncate_impl();
-
-private Q_SLOTS:
-
- void mid_QString_data() { mid_data(); }
- void mid_QString() { mid_impl<QString>(); }
- void mid_QStringRef_data() { mid_data(); }
- void mid_QStringRef() { mid_impl<QStringRef>(); }
- void mid_QStringView_data() { mid_data(); }
- void mid_QStringView() { mid_impl<QStringView>(); }
- void mid_QLatin1String_data() { mid_data(); }
- void mid_QLatin1String() { mid_impl<QLatin1String>(); }
- void mid_QByteArray_data() { mid_data(); }
- void mid_QByteArray() { mid_impl<QByteArray>(); }
-
- void left_truncate_QString_data() { left_data(); }
- void left_truncate_QString() { left_impl<QString>(); }
- void left_truncate_QStringRef_data() { left_data(); }
- void left_truncate_QStringRef() { left_impl<QStringRef>(); }
- void left_truncate_QStringView_data() { left_data(); }
- void left_truncate_QStringView() { left_impl<QStringView>(); }
- void left_truncate_QLatin1String_data() { left_data(); }
- void left_truncate_QLatin1String() { left_impl<QLatin1String>(); }
- void left_truncate_QByteArray_data() { left_data(); }
- void left_truncate_QByteArray() { left_impl<QByteArray>(); }
-
- void right_QString_data() { right_data(); }
- void right_QString() { right_impl<QString>(); }
- void right_QStringRef_data() { right_data(); }
- void right_QStringRef() { right_impl<QStringRef>(); }
- void right_QStringView_data() { right_data(); }
- void right_QStringView() { right_impl<QStringView>(); }
- void right_QLatin1String_data() { right_data(); }
- void right_QLatin1String() { right_impl<QLatin1String>(); }
- void right_QByteArray_data() { right_data(); }
- void right_QByteArray() { right_impl<QByteArray>(); }
-
- void chop_QString_data() { chop_data(); }
- void chop_QString() { chop_impl<QString>(); }
- void chop_QStringRef_data() { chop_data(); }
- void chop_QStringRef() { chop_impl<QStringRef>(); }
- void chop_QStringView_data() { chop_data(); }
- void chop_QStringView() { chop_impl<QStringView>(); }
- void chop_QLatin1String_data() { chop_data(); }
- void chop_QLatin1String() { chop_impl<QLatin1String>(); }
- void chop_QByteArray_data() { chop_data(); }
- void chop_QByteArray() { chop_impl<QByteArray>(); }
-
-private:
- void trimmed_data();
- template <typename String> void trimmed_impl();
-
-private Q_SLOTS:
- void trim_trimmed_QString_data() { trimmed_data(); }
- void trim_trimmed_QString() { trimmed_impl<QString>(); }
- void trim_trimmed_QStringRef_data() { trimmed_data(); }
- void trim_trimmed_QStringRef() { trimmed_impl<QStringRef>(); }
- void trim_trimmed_QStringView_data() { trimmed_data(); }
- void trim_trimmed_QStringView() { trimmed_impl<QStringView>(); }
- void trim_trimmed_QLatin1String_data() { trimmed_data(); }
- void trim_trimmed_QLatin1String() { trimmed_impl<QLatin1String>(); }
- void trim_trimmed_QByteArray_data() { trimmed_data(); }
- void trim_trimmed_QByteArray() { trimmed_impl<QByteArray>(); }
-
- //
- // UTF-16-only checks:
- //
-private:
-
- void toLocal8Bit_data();
- template <typename String> void toLocal8Bit_impl();
-
- void toLatin1_data();
- template <typename String> void toLatin1_impl();
-
- void toUtf8_data();
- template <typename String> void toUtf8_impl();
-
- void toUcs4_data();
- template <typename String> void toUcs4_impl();
-
-private Q_SLOTS:
-
- void toLocal8Bit_QString_data() { toLocal8Bit_data(); }
- void toLocal8Bit_QString() { toLocal8Bit_impl<QString>(); }
- void toLocal8Bit_QStringRef_data() { toLocal8Bit_data(); }
- void toLocal8Bit_QStringRef() { toLocal8Bit_impl<QStringRef>(); }
- void toLocal8Bit_QStringView_data() { toLocal8Bit_data(); }
- void toLocal8Bit_QStringView() { toLocal8Bit_impl<QStringView>(); }
-
- void toLatin1_QString_data() { toLatin1_data(); }
- void toLatin1_QString() { toLatin1_impl<QString>(); }
- void toLatin1_QStringRef_data() { toLatin1_data(); }
- void toLatin1_QStringRef() { toLatin1_impl<QStringRef>(); }
- void toLatin1_QStringView_data() { toLatin1_data(); }
- void toLatin1_QStringView() { toLatin1_impl<QStringView>(); }
-
- void toUtf8_QString_data() { toUtf8_data(); }
- void toUtf8_QString() { toUtf8_impl<QString>(); }
- void toUtf8_QStringRef_data() { toUtf8_data(); }
- void toUtf8_QStringRef() { toUtf8_impl<QStringRef>(); }
- void toUtf8_QStringView_data() { toUtf8_data(); }
- void toUtf8_QStringView() { toUtf8_impl<QStringView>(); }
-
- void toUcs4_QString_data() { toUcs4_data(); }
- void toUcs4_QString() { toUcs4_impl<QString>(); }
- void toUcs4_QStringRef_data() { toUcs4_data(); }
- void toUcs4_QStringRef() { toUcs4_impl<QStringRef>(); }
- void toUcs4_QStringView_data() { toUcs4_data(); }
- void toUcs4_QStringView() { toUcs4_impl<QStringView>(); }
-};
-
-void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty)
-{
- QTest::addColumn<QStringRef>("lhsUnicode");
- QTest::addColumn<QLatin1String>("lhsLatin1");
- QTest::addColumn<QStringRef>("rhsUnicode");
- QTest::addColumn<QLatin1String>("rhsLatin1");
- QTest::addColumn<int>("caseSensitiveCompareResult");
- QTest::addColumn<int>("caseInsensitiveCompareResult");
-
- if (hasConceptOfNullAndEmpty) {
- QTest::newRow("null <> null") << QStringRef() << QLatin1String()
- << QStringRef() << QLatin1String()
- << 0 << 0;
- static const QString empty("");
- QTest::newRow("null <> empty") << QStringRef() << QLatin1String()
- << QStringRef(&empty) << QLatin1String("")
- << 0 << 0;
- QTest::newRow("empty <> null") << QStringRef(&empty) << QLatin1String("")
- << QStringRef() << QLatin1String()
- << 0 << 0;
- }
-
-#define ROW(lhs, rhs) \
- do { \
- static const QString pinned[] = { \
- QString(QLatin1String(lhs)), \
- QString(QLatin1String(rhs)), \
- }; \
- QTest::newRow(qUtf8Printable(QLatin1String("'" lhs "' <> '" rhs "': "))) \
- << QStringRef(&pinned[0]) << QLatin1String(lhs) \
- << QStringRef(&pinned[1]) << QLatin1String(rhs) \
- << qstrcmp(lhs, rhs) << qstricmp(lhs, rhs); \
- } while (false)
- ROW("", "0");
- ROW("0", "");
- ROW("0", "1");
- ROW("0", "0");
- ROW("\xE4", "\xE4"); // ä <> ä
- ROW("\xE4", "\xC4"); // ä <> Ä
-#undef ROW
-}
-
-template <typename String> String detached(String s)
-{
- if (!s.isNull()) { // detaching loses nullness, but we need to preserve it
- auto d = s.data();
- Q_UNUSED(d);
- }
- return s;
-}
-
-template <class Str> Str make(const QStringRef &sf, QLatin1String l1, const QByteArray &u8);
-template <> QChar make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf.isEmpty() ? QChar() : sf.at(0); }
-template <> QStringRef make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf; }
-template <> QString make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf.toString(); }
-template <> QStringView make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf; }
-template <> QLatin1String make(const QStringRef &, QLatin1String l1, const QByteArray &) { return l1; }
-template <> QByteArray make(const QStringRef &, QLatin1String, const QByteArray &u8) { return u8; }
-template <> const char * make(const QStringRef &, QLatin1String, const QByteArray &u8) { return u8.data(); }
-
-template <typename> struct is_utf8_encoded : std::false_type {};
-template <> struct is_utf8_encoded<const char*> : std::true_type {};
-template <> struct is_utf8_encoded<QByteArray> : std::true_type {};
-
-template <typename> struct is_latin1_encoded : std::false_type {};
-template <> struct is_latin1_encoded<QLatin1String> : std::true_type {};
-
-template <typename LHS, typename RHS>
-struct has_nothrow_compare {
- enum { value = is_utf8_encoded<LHS>::value == is_utf8_encoded<RHS>::value };
-};
-
-template <typename LHS, typename RHS>
-struct has_qCompareStrings {
- enum { value = !std::is_same<LHS, QChar>::value && !std::is_same<RHS, QChar>::value &&
- !is_utf8_encoded<LHS>::value && !is_utf8_encoded<RHS>::value };
-};
-
-template <typename LHS, typename RHS>
-void tst_QStringApiSymmetry::compare_impl() const
-{
- QFETCH(QStringRef, lhsUnicode);
- QFETCH(QLatin1String, lhsLatin1);
- QFETCH(QStringRef, rhsUnicode);
- QFETCH(QLatin1String, rhsLatin1);
- QFETCH(int, caseSensitiveCompareResult);
- QFETCH(const int, caseInsensitiveCompareResult);
- Q_UNUSED(caseInsensitiveCompareResult);
-
- const auto lhsU8 = lhsUnicode.toUtf8();
- const auto rhsU8 = rhsUnicode.toUtf8();
-
- const auto lhs = make<LHS>(lhsUnicode, lhsLatin1, lhsU8);
- const auto rhs = make<RHS>(rhsUnicode, rhsLatin1, rhsU8);
-
-#ifdef Q_COMPILER_NOEXCEPT
-# define QVERIFY_NOEXCEPT(expr) do { \
- if (has_nothrow_compare<LHS, RHS>::value) {} else \
- QEXPECT_FAIL("", "Qt is missing a nothrow utf8-utf16 comparator", Continue); \
- QVERIFY(noexcept(expr)); } while (0)
-#else
-# define QVERIFY_NOEXCEPT(expr)
-#endif
-
-#define CHECK(op) \
- QVERIFY_NOEXCEPT(lhs op rhs); \
- do { if (caseSensitiveCompareResult op 0) { \
- QVERIFY(lhs op rhs); \
- } else { \
- QVERIFY(!(lhs op rhs)); \
- } } while (false)
-
- CHECK(==);
- CHECK(!=);
- CHECK(<);
- CHECK(>);
- CHECK(<=);
- CHECK(>=);
-#undef CHECK
-}
-
-static QString empty = QLatin1String("");
-// the tests below rely on the fact that these objects' names match their contents:
-static QString a = QStringLiteral("a");
-static QString A = QStringLiteral("A");
-static QString b = QStringLiteral("b");
-static QString B = QStringLiteral("B");
-static QString c = QStringLiteral("c");
-static QString C = QStringLiteral("C");
-static QString ab = QStringLiteral("ab");
-static QString aB = QStringLiteral("aB");
-static QString Ab = QStringLiteral("Ab");
-static QString AB = QStringLiteral("AB");
-static QString bc = QStringLiteral("bc");
-static QString bC = QStringLiteral("bC");
-static QString Bc = QStringLiteral("Bc");
-static QString BC = QStringLiteral("BC");
-static QString abc = QStringLiteral("abc");
-static QString abC = QStringLiteral("abC");
-static QString aBc = QStringLiteral("aBc");
-static QString aBC = QStringLiteral("aBC");
-static QString Abc = QStringLiteral("Abc");
-static QString AbC = QStringLiteral("AbC");
-static QString ABc = QStringLiteral("ABc");
-static QString ABC = QStringLiteral("ABC");
-
-void tst_QStringApiSymmetry::startsWith_data(bool rhsHasVariableLength)
-{
- QTest::addColumn<QStringRef>("haystackU16");
- QTest::addColumn<QLatin1String>("haystackL1");
- QTest::addColumn<QStringRef>("needleU16");
- QTest::addColumn<QLatin1String>("needleL1");
- QTest::addColumn<bool>("resultCS");
- QTest::addColumn<bool>("resultCIS");
-
- if (rhsHasVariableLength) {
- QTest::addRow("null ~= ^null") << QStringRef() << QLatin1String()
- << QStringRef() << QLatin1String() << true << true;
- QTest::addRow("empty ~= ^null") << QStringRef(&empty) << QLatin1String("")
- << QStringRef() << QLatin1String() << true << true;
- QTest::addRow("a ~= ^null") << QStringRef(&a) << QLatin1String("a")
- << QStringRef() << QLatin1String() << true << true;
- QTest::addRow("null ~= ^empty") << QStringRef() << QLatin1String()
- << QStringRef(&empty) << QLatin1String("") << false << false;
- QTest::addRow("a ~= ^empty") << QStringRef(&a) << QLatin1String("a")
- << QStringRef(&empty) << QLatin1String("") << true << true;
- QTest::addRow("empty ~= ^empty") << QStringRef(&empty) << QLatin1String("")
- << QStringRef(&empty) << QLatin1String("") << true << true;
- }
- QTest::addRow("null ~= ^a") << QStringRef() << QLatin1String()
- << QStringRef(&a) << QLatin1String("a") << false << false;
- QTest::addRow("empty ~= ^a") << QStringRef(&empty) << QLatin1String("")
- << QStringRef(&a) << QLatin1String("a") << false << false;
-
-#define ROW(h, n, cs, cis) \
- QTest::addRow("%s ~= ^%s", #h, #n) << QStringRef(&h) << QLatin1String(#h) \
- << QStringRef(&n) << QLatin1String(#n) \
- << bool(cs) << bool(cis)
- ROW(a, a, 1, 1);
- ROW(a, A, 0, 1);
- ROW(a, b, 0, 0);
-
- if (rhsHasVariableLength)
- ROW(a, aB, 0, 0);
-
- ROW(ab, a, 1, 1);
- if (rhsHasVariableLength) {
- ROW(ab, ab, 1, 1);
- ROW(ab, aB, 0, 1);
- ROW(ab, Ab, 0, 1);
- }
- ROW(ab, c, 0, 0);
-
- if (rhsHasVariableLength)
- ROW(ab, abc, 0, 0);
-
- ROW(Abc, c, 0, 0);
- if (rhsHasVariableLength) {
- ROW(Abc, ab, 0, 1);
- ROW(Abc, aB, 0, 1);
- ROW(Abc, Ab, 1, 1);
- ROW(Abc, AB, 0, 1);
- ROW(aBC, ab, 0, 1);
- ROW(aBC, aB, 1, 1);
- ROW(aBC, Ab, 0, 1);
- ROW(aBC, AB, 0, 1);
- }
- ROW(ABC, b, 0, 0);
- ROW(ABC, a, 0, 1);
-#undef ROW
-}
-
-template <typename Haystack, typename Needle>
-void tst_QStringApiSymmetry::startsWith_impl() const
-{
- QFETCH(const QStringRef, haystackU16);
- QFETCH(const QLatin1String, haystackL1);
- QFETCH(const QStringRef, needleU16);
- QFETCH(const QLatin1String, needleL1);
- QFETCH(const bool, resultCS);
- QFETCH(const bool, resultCIS);
-
- const auto haystackU8 = haystackU16.toUtf8();
- const auto needleU8 = needleU16.toUtf8();
-
- const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
- const auto needle = make<Needle>(needleU16, needleL1, needleU8);
-
- QCOMPARE(haystack.startsWith(needle), resultCS);
- QCOMPARE(haystack.startsWith(needle, Qt::CaseSensitive), resultCS);
- QCOMPARE(haystack.startsWith(needle, Qt::CaseInsensitive), resultCIS);
-}
-
-void tst_QStringApiSymmetry::endsWith_data(bool rhsHasVariableLength)
-{
- QTest::addColumn<QStringRef>("haystackU16");
- QTest::addColumn<QLatin1String>("haystackL1");
- QTest::addColumn<QStringRef>("needleU16");
- QTest::addColumn<QLatin1String>("needleL1");
- QTest::addColumn<bool>("resultCS");
- QTest::addColumn<bool>("resultCIS");
-
- if (rhsHasVariableLength) {
- QTest::addRow("null ~= null$") << QStringRef() << QLatin1String()
- << QStringRef() << QLatin1String() << true << true;
- QTest::addRow("empty ~= null$") << QStringRef(&empty) << QLatin1String("")
- << QStringRef() << QLatin1String() << true << true;
- QTest::addRow("a ~= null$") << QStringRef(&a) << QLatin1String("a")
- << QStringRef() << QLatin1String() << true << true;
- QTest::addRow("null ~= empty$") << QStringRef() << QLatin1String()
- << QStringRef(&empty) << QLatin1String("") << false << false;
- QTest::addRow("a ~= empty$") << QStringRef(&a) << QLatin1String("a")
- << QStringRef(&empty) << QLatin1String("") << true << true;
- QTest::addRow("empty ~= empty$") << QStringRef(&empty) << QLatin1String("")
- << QStringRef(&empty) << QLatin1String("") << true << true;
- }
- QTest::addRow("null ~= a$") << QStringRef() << QLatin1String()
- << QStringRef(&a) << QLatin1String("a") << false << false;
- QTest::addRow("empty ~= a$") << QStringRef(&empty) << QLatin1String("")
- << QStringRef(&a) << QLatin1String("a") << false << false;
-
-#define ROW(h, n, cs, cis) \
- QTest::addRow("%s ~= %s$", #h, #n) << QStringRef(&h) << QLatin1String(#h) \
- << QStringRef(&n) << QLatin1String(#n) \
- << bool(cs) << bool(cis)
- ROW(a, a, 1, 1);
- ROW(a, A, 0, 1);
- ROW(a, b, 0, 0);
-
- if (rhsHasVariableLength)
- ROW(b, ab, 0, 0);
-
- ROW(ab, b, 1, 1);
- if (rhsHasVariableLength) {
- ROW(ab, ab, 1, 1);
- ROW(ab, aB, 0, 1);
- ROW(ab, Ab, 0, 1);
- }
- ROW(ab, c, 0, 0);
-
- if (rhsHasVariableLength)
- ROW(bc, abc, 0, 0);
-
- ROW(Abc, c, 1, 1);
- if (rhsHasVariableLength) {
- ROW(Abc, bc, 1, 1);
- ROW(Abc, bC, 0, 1);
- ROW(Abc, Bc, 0, 1);
- ROW(Abc, BC, 0, 1);
- ROW(aBC, bc, 0, 1);
- ROW(aBC, bC, 0, 1);
- ROW(aBC, Bc, 0, 1);
- ROW(aBC, BC, 1, 1);
- }
- ROW(ABC, b, 0, 0);
- ROW(ABC, a, 0, 0);
-#undef ROW
-}
-
-template <typename Haystack, typename Needle>
-void tst_QStringApiSymmetry::endsWith_impl() const
-{
- QFETCH(const QStringRef, haystackU16);
- QFETCH(const QLatin1String, haystackL1);
- QFETCH(const QStringRef, needleU16);
- QFETCH(const QLatin1String, needleL1);
- QFETCH(const bool, resultCS);
- QFETCH(const bool, resultCIS);
-
- const auto haystackU8 = haystackU16.toUtf8();
- const auto needleU8 = needleU16.toUtf8();
-
- const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
- const auto needle = make<Needle>(needleU16, needleL1, needleU8);
-
- QCOMPARE(haystack.endsWith(needle), resultCS);
- QCOMPARE(haystack.endsWith(needle, Qt::CaseSensitive), resultCS);
- QCOMPARE(haystack.endsWith(needle, Qt::CaseInsensitive), resultCIS);
-}
-
-void tst_QStringApiSymmetry::mid_data()
-{
- QTest::addColumn<QStringRef>("unicode");
- QTest::addColumn<QLatin1String>("latin1");
- QTest::addColumn<int>("pos");
- QTest::addColumn<int>("n");
- QTest::addColumn<QStringRef>("result");
- QTest::addColumn<QStringRef>("result2");
-
- QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << 0 << QStringRef() << QStringRef();
- QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << 0 << QStringRef(&empty) << QStringRef(&empty);
-
- // Some classes' mid() implementations have a wide contract, others a narrow one
- // so only test valid arguents here:
-#define ROW(base, p, n, r1, r2) \
- QTest::addRow("%s%d%d", #base, p, n) << QStringRef(&base) << QLatin1String(#base) << p << n << QStringRef(&r1) << QStringRef(&r2)
-
- ROW(a, 0, 0, a, empty);
- ROW(a, 0, 1, a, a);
- ROW(a, 1, 0, empty, empty);
-
- ROW(ab, 0, 0, ab, empty);
- ROW(ab, 0, 1, ab, a);
- ROW(ab, 0, 2, ab, ab);
- ROW(ab, 1, 0, b, empty);
- ROW(ab, 1, 1, b, b);
- ROW(ab, 2, 0, empty, empty);
-
- ROW(abc, 0, 0, abc, empty);
- ROW(abc, 0, 1, abc, a);
- ROW(abc, 0, 2, abc, ab);
- ROW(abc, 0, 3, abc, abc);
- ROW(abc, 1, 0, bc, empty);
- ROW(abc, 1, 1, bc, b);
- ROW(abc, 1, 2, bc, bc);
- ROW(abc, 2, 0, c, empty);
- ROW(abc, 2, 1, c, c);
- ROW(abc, 3, 0, empty, empty);
-#undef ROW
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::mid_impl()
-{
- QFETCH(const QStringRef, unicode);
- QFETCH(const QLatin1String, latin1);
- QFETCH(const int, pos);
- QFETCH(const int, n);
- QFETCH(const QStringRef, result);
- QFETCH(const QStringRef, result2);
-
- const auto utf8 = unicode.toUtf8();
-
- const auto s = make<String>(unicode, latin1, utf8);
-
- {
- const auto mid = s.mid(pos);
- const auto mid2 = s.mid(pos, n);
-
- QCOMPARE(mid, result);
- QCOMPARE(mid.isNull(), result.isNull());
- QCOMPARE(mid.isEmpty(), result.isEmpty());
-
- QCOMPARE(mid2, result2);
- QCOMPARE(mid2.isNull(), result2.isNull());
- QCOMPARE(mid2.isEmpty(), result2.isEmpty());
- }
- {
- const auto mid = detached(s).mid(pos);
- const auto mid2 = detached(s).mid(pos, n);
-
- QCOMPARE(mid, result);
- QCOMPARE(mid.isNull(), result.isNull());
- QCOMPARE(mid.isEmpty(), result.isEmpty());
-
- QCOMPARE(mid2, result2);
- QCOMPARE(mid2.isNull(), result2.isNull());
- QCOMPARE(mid2.isEmpty(), result2.isEmpty());
- }
-}
-
-void tst_QStringApiSymmetry::left_data()
-{
- QTest::addColumn<QStringRef>("unicode");
- QTest::addColumn<QLatin1String>("latin1");
- QTest::addColumn<int>("n");
- QTest::addColumn<QStringRef>("result");
-
- QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << QStringRef();
- QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty);
-
- // Some classes' left() implementations have a wide contract, others a narrow one
- // so only test valid arguents here:
-#define ROW(base, n, res) \
- QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res);
-
- ROW(a, 0, empty);
- ROW(a, 1, a);
-
- ROW(ab, 0, empty);
- ROW(ab, 1, a);
- ROW(ab, 2, ab);
-
- ROW(abc, 0, empty);
- ROW(abc, 1, a);
- ROW(abc, 2, ab);
- ROW(abc, 3, abc);
-#undef ROW
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::left_impl()
-{
- QFETCH(const QStringRef, unicode);
- QFETCH(const QLatin1String, latin1);
- QFETCH(const int, n);
- QFETCH(const QStringRef, result);
-
- const auto utf8 = unicode.toUtf8();
-
- const auto s = make<String>(unicode, latin1, utf8);
-
- {
- const auto left = s.left(n);
-
- QCOMPARE(left, result);
- QCOMPARE(left.isNull(), result.isNull());
- QCOMPARE(left.isEmpty(), result.isEmpty());
- }
- {
- const auto left = detached(s).left(n);
-
- QCOMPARE(left, result);
- QCOMPARE(left.isNull(), result.isNull());
- QCOMPARE(left.isEmpty(), result.isEmpty());
- }
- {
- auto left = s;
- left.truncate(n);
-
- QCOMPARE(left, result);
- QCOMPARE(left.isNull(), result.isNull());
- QCOMPARE(left.isEmpty(), result.isEmpty());
- }
-}
-
-void tst_QStringApiSymmetry::right_data()
-{
- QTest::addColumn<QStringRef>("unicode");
- QTest::addColumn<QLatin1String>("latin1");
- QTest::addColumn<int>("n");
- QTest::addColumn<QStringRef>("result");
-
- QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << QStringRef();
- QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty);
-
- // Some classes' right() implementations have a wide contract, others a narrow one
- // so only test valid arguents here:
-#define ROW(base, n, res) \
- QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res);
-
- ROW(a, 0, empty);
- ROW(a, 1, a);
-
- ROW(ab, 0, empty);
- ROW(ab, 1, b);
- ROW(ab, 2, ab);
-
- ROW(abc, 0, empty);
- ROW(abc, 1, c);
- ROW(abc, 2, bc);
- ROW(abc, 3, abc);
-#undef ROW
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::right_impl()
-{
- QFETCH(const QStringRef, unicode);
- QFETCH(const QLatin1String, latin1);
- QFETCH(const int, n);
- QFETCH(const QStringRef, result);
-
- const auto utf8 = unicode.toUtf8();
-
- const auto s = make<String>(unicode, latin1, utf8);
-
- {
- const auto right = s.right(n);
-
- QCOMPARE(right, result);
- QCOMPARE(right.isNull(), result.isNull());
- QCOMPARE(right.isEmpty(), result.isEmpty());
- }
- {
- const auto right = detached(s).right(n);
-
- QCOMPARE(right, result);
- QCOMPARE(right.isNull(), result.isNull());
- QCOMPARE(right.isEmpty(), result.isEmpty());
- }
-}
-
-void tst_QStringApiSymmetry::chop_data()
-{
- QTest::addColumn<QStringRef>("unicode");
- QTest::addColumn<QLatin1String>("latin1");
- QTest::addColumn<int>("n");
- QTest::addColumn<QStringRef>("result");
-
- QTest::addRow("null") << QStringRef() << QLatin1String() << 0 << QStringRef();
- QTest::addRow("empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty);
-
- // Some classes' truncate() implementations have a wide contract, others a narrow one
- // so only test valid arguents here:
-#define ROW(base, n, res) \
- QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res);
-
- ROW(a, 0, a);
- ROW(a, 1, empty);
-
- ROW(ab, 0, ab);
- ROW(ab, 1, a);
- ROW(ab, 2, empty);
-
- ROW(abc, 0, abc);
- ROW(abc, 1, ab);
- ROW(abc, 2, a);
- ROW(abc, 3, empty);
-#undef ROW
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::chop_impl()
-{
- QFETCH(const QStringRef, unicode);
- QFETCH(const QLatin1String, latin1);
- QFETCH(const int, n);
- QFETCH(const QStringRef, result);
-
- const auto utf8 = unicode.toUtf8();
-
- const auto s = make<String>(unicode, latin1, utf8);
-
- {
- const auto chopped = s.chopped(n);
-
- QCOMPARE(chopped, result);
- QCOMPARE(chopped.isNull(), result.isNull());
- QCOMPARE(chopped.isEmpty(), result.isEmpty());
- }
- {
- const auto chopped = detached(s).chopped(n);
-
- QCOMPARE(chopped, result);
- QCOMPARE(chopped.isNull(), result.isNull());
- QCOMPARE(chopped.isEmpty(), result.isEmpty());
- }
- {
- auto chopped = s;
- chopped.chop(n);
-
- QCOMPARE(chopped, result);
- QCOMPARE(chopped.isNull(), result.isNull());
- QCOMPARE(chopped.isEmpty(), result.isEmpty());
- }
-}
-
-void tst_QStringApiSymmetry::trimmed_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<QStringRef>("result");
-
- const auto latin1Whitespace = QLatin1String(" \r\n\t\f\v");
-
- QTest::addRow("null") << QString() << QStringRef();
-
- auto add = [latin1Whitespace](const QString &str) {
- // run through all substrings of latin1Whitespace
- for (int len = 0; len < latin1Whitespace.size(); ++len) {
- for (int pos = 0; pos < latin1Whitespace.size() - len; ++pos) {
- const QString unicode = latin1Whitespace.mid(pos, len) + str + latin1Whitespace.mid(pos, len);
- const QScopedPointer<const char> escaped(QTest::toString(unicode));
- QTest::addRow("%s", escaped.data()) << unicode << QStringRef(&str);
- }
- }
- };
-
- add(empty);
- add(a);
- add(ab);
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::trimmed_impl()
-{
- QFETCH(const QString, unicode);
- QFETCH(const QStringRef, result);
-
- const auto utf8 = unicode.toUtf8();
- const auto l1s = unicode.toLatin1();
- const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s);
-
- const auto ref = unicode.isNull() ? QStringRef() : QStringRef(&unicode);
- const auto s = make<String>(ref, l1, utf8);
-
- QCOMPARE(s.isNull(), unicode.isNull());
-
- {
- const auto trimmed = s.trimmed();
-
- QCOMPARE(trimmed, result);
- QCOMPARE(trimmed.isNull(), result.isNull());
- QCOMPARE(trimmed.isEmpty(), result.isEmpty());
- }
- {
- const auto trimmed = detached(s).trimmed();
-
- QCOMPARE(trimmed, result);
- QCOMPARE(trimmed.isNull(), result.isNull());
- QCOMPARE(trimmed.isEmpty(), result.isEmpty());
- }
-}
-
-//
-//
-// UTF-16-only checks:
-//
-//
-
-template <class Str> Str make(const QString &s);
-template <> QStringRef make(const QString &s) { return QStringRef(&s); }
-template <> QString make(const QString &s) { return s; }
-template <> QStringView make(const QString &s) { return s; }
-
-#define REPEAT_16X(X) X X X X X X X X X X X X X X X X
-#define LONG_STRING_256 REPEAT_16X("0123456789abcdef")
-
-void tst_QStringApiSymmetry::toLocal8Bit_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<QByteArray>("local");
-
- auto add = [](const char *local) {
- const QByteArray ba(local);
- QString s;
- for (char c : ba)
- s += QLatin1Char(c);
- QTest::newRow(rowName(ba).constData()) << s << ba;
- };
-
- QTest::addRow("null") << QString() << QByteArray();
- QTest::addRow("empty") << QString("") << QByteArray("");
-
- add("Moebius");
- add(LONG_STRING_256);
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::toLocal8Bit_impl()
-{
- QFETCH(const QString, unicode);
- QFETCH(const QByteArray, local);
-
- const auto str = make<String>(unicode);
-
- const auto result = str.toLocal8Bit();
-
- QCOMPARE(result, local);
- QCOMPARE(unicode.isEmpty(), result.isEmpty());
- QCOMPARE(unicode.isNull(), result.isNull());
-}
-
-void tst_QStringApiSymmetry::toLatin1_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<QByteArray>("latin1");
-
- auto add = [](const char *l1) {
- const QByteArray ba(l1);
- QString s;
- for (char c : ba)
- s += QLatin1Char(c);
- QTest::newRow(rowName(ba).constData()) << s << ba;
- };
-
- QTest::addRow("null") << QString() << QByteArray();
- QTest::addRow("empty") << QString("") << QByteArray("");
-
- add("M\xF6" "bius");
- add(LONG_STRING_256);
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::toLatin1_impl()
-{
- QFETCH(const QString, unicode);
- QFETCH(const QByteArray, latin1);
-
- const auto str = make<String>(unicode);
-
- const auto result = str.toLatin1();
-
- QCOMPARE(result, latin1);
- QCOMPARE(unicode.isEmpty(), result.isEmpty());
- QCOMPARE(unicode.isNull(), result.isNull());
-}
-
-void tst_QStringApiSymmetry::toUtf8_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<QByteArray>("utf8");
-
- auto add = [](const char *u8) {
- QByteArray ba(u8);
- QString s = ba;
- QTest::newRow(rowName(ba).constData()) << s << ba;
- };
-
- QTest::addRow("null") << QString() << QByteArray();
- QTest::addRow("empty") << QString("") << QByteArray("");
-
- add("M\xC3\xB6" "bius");
- add(LONG_STRING_256);
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::toUtf8_impl()
-{
- QFETCH(const QString, unicode);
- QFETCH(const QByteArray, utf8);
-
- const auto str = make<String>(unicode);
-
- const auto result = str.toUtf8();
-
- QCOMPARE(result, utf8);
- QCOMPARE(unicode.isEmpty(), result.isEmpty());
- QCOMPARE(unicode.isNull(), result.isNull());
-}
-
-void tst_QStringApiSymmetry::toUcs4_data()
-{
- QTest::addColumn<QString>("unicode");
- QTest::addColumn<QVector<uint>>("ucs4");
-
- auto add = [](const char *l1) {
- const QByteArray ba(l1);
- QString s;
- QVector<uint> ucs4;
- for (char c : ba) {
- s += QLatin1Char(c);
- ucs4.append(uint(uchar(c)));
- }
- QTest::newRow(rowName(ba).constData()) << s << ucs4;
- };
-
- QTest::addRow("null") << QString() << QVector<uint>();
- QTest::addRow("empty") << QString("") << QVector<uint>();
-
- add("M\xF6" "bius");
- add(LONG_STRING_256);
-}
-
-template <typename String>
-void tst_QStringApiSymmetry::toUcs4_impl()
-{
- QFETCH(const QString, unicode);
- QFETCH(const QVector<uint>, ucs4);
-
- const auto str = make<String>(unicode);
-
- const auto result = str.toUcs4();
-
- QCOMPARE(result, ucs4);
- QCOMPARE(unicode.isEmpty(), ucs4.isEmpty());
-}
-
-QTEST_APPLESS_MAIN(tst_QStringApiSymmetry)
-
-#include "tst_qstringapisymmetry.moc"
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder.pro b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder.pro
deleted file mode 100644
index d73d541502..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS= \
- qstringbuilder1 \
- qstringbuilder2 \
- qstringbuilder3 \
- qstringbuilder4
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/qstringbuilder1.pro b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/qstringbuilder1.pro
deleted file mode 100644
index d9cdad1bf5..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/qstringbuilder1.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringbuilder1
-QT = core testlib
-SOURCES = tst_qstringbuilder1.cpp
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp
deleted file mode 100644
index ac7f439248..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#define LITERAL "some literal"
-#define LITERAL_LEN (sizeof(LITERAL)-1)
-#define LITERAL_EXTRA "some literal" "EXTRA"
-
-// "some literal", but replacing all vowels by their umlauted UTF-8 string :)
-#define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l"
-#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1)
-#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA"
-
-#ifdef Q_COMPILER_UNICODE_STRINGS
-// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
-#define UNICODE_LITERAL u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l"
-#define UNICODE_LITERAL_LEN ((sizeof(UNICODE_LITERAL) - 1) / 2)
-#define UNICODE_LITERAL_EXTRA u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l" "EXTRA"
-#endif
-
-#ifndef P
-# error You need to define P
-# define P +
-#endif
-
-//fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS
-#ifndef QT_USE_FAST_CONCATENATION
-#define Q %
-#else
-#define Q P
-#endif
-
-template <typename T> QString toQString(const T &t);
-
-template <> QString toQString(const QString &s) { return s; }
-template <> QString toQString(const QStringRef &r) { return r.toString(); }
-template <> QString toQString(const QStringView &v) { return v.toString(); }
-template <> QString toQString(const QLatin1String &l) { return l; }
-template <> QString toQString(const QLatin1Char &l) { return QChar(l); }
-template <> QString toQString(const QChar &c) { return c; }
-template <> QString toQString(const QChar::SpecialCharacter &c) { return QChar(c); }
-#ifdef Q_COMPILER_UNICODE_STRINGS
-template <> QString toQString(char16_t * const &p) { return QStringView(p).toString(); }
-template <size_t N> QString toQString(const char16_t (&a)[N]) { return QStringView(a).toString(); }
-template <> QString toQString(const char16_t &c) { return QChar(c); }
-#endif
-
-template <typename T> QByteArray toQByteArray(const T &t);
-
-template <> QByteArray toQByteArray(const QByteArray &b) { return b; }
-template <> QByteArray toQByteArray(char * const &p) { return p; }
-template <size_t N> QByteArray toQByteArray(const char (&a)[N]) { return a; }
-template <> QByteArray toQByteArray(const char &c) { return QByteArray(&c, 1); }
-
-void runScenario()
-{
- // this code is latin1. TODO: replace it with the utf8 block below, once
- // strings default to utf8.
- QLatin1String l1string(LITERAL);
- QString string(l1string);
- QStringRef stringref(&string, 2, 10);
- QStringView stringview(stringref);
- QLatin1Char lchar('c');
- QChar qchar(lchar);
- QChar::SpecialCharacter special(QChar::Nbsp);
-#ifdef Q_COMPILER_UNICODE_STRINGS
- char16_t u16char = UNICODE_LITERAL[0];
- char16_t u16chararray[] = { u's', 0xF6, u'm', 0xEB, u' ', u'l', 0xEF, u't', 0xEB, u'r', 0xE4, u'l', 0x00 };
- QCOMPARE(QStringView(u16chararray), QStringView(UNICODE_LITERAL));
- char16_t *u16charstar = u16chararray;
-#endif
-
-#define CHECK(QorP, a1, a2) \
- do { \
- DO(QorP, a1, a2); \
- DO(QorP, a2, a1); \
- } while (0)
-
-#define DO(QorP, a1, a2) \
- QCOMPARE(QString(a1 QorP a2), \
- toQString(a1).append(toQString(a2))) \
- /* end */
-
- CHECK(P, l1string, l1string);
- CHECK(P, l1string, string);
- CHECK(P, l1string, stringref);
- CHECK(Q, l1string, stringview);
- CHECK(P, l1string, lchar);
- CHECK(P, l1string, qchar);
- CHECK(P, l1string, special);
- CHECK(P, l1string, QStringLiteral(LITERAL));
- CHECK(Q, l1string, u16char);
- CHECK(Q, l1string, u16chararray);
- CHECK(Q, l1string, u16charstar);
-
- CHECK(P, string, string);
- CHECK(P, string, stringref);
- CHECK(Q, string, stringview);
- CHECK(P, string, lchar);
- CHECK(P, string, qchar);
- CHECK(P, string, special);
- CHECK(P, string, QStringLiteral(LITERAL));
- CHECK(Q, string, u16char);
- CHECK(Q, string, u16chararray);
- CHECK(Q, string, u16charstar);
-
- CHECK(P, stringref, stringref);
- CHECK(Q, stringref, stringview);
- CHECK(P, stringref, lchar);
- CHECK(P, stringref, qchar);
- CHECK(P, stringref, special);
- CHECK(P, stringref, QStringLiteral(LITERAL));
- CHECK(Q, stringref, u16char);
- CHECK(Q, stringref, u16chararray);
- CHECK(Q, stringref, u16charstar);
-
- CHECK(Q, stringview, stringview);
- CHECK(Q, stringview, lchar);
- CHECK(Q, stringview, qchar);
- CHECK(Q, stringview, special);
- CHECK(P, stringview, QStringLiteral(LITERAL));
- CHECK(Q, stringview, u16char);
- CHECK(Q, stringview, u16chararray);
- CHECK(Q, stringview, u16charstar);
-
- CHECK(P, lchar, lchar);
- CHECK(P, lchar, qchar);
- CHECK(P, lchar, special);
- CHECK(P, lchar, QStringLiteral(LITERAL));
- CHECK(Q, lchar, u16char);
- CHECK(Q, lchar, u16chararray);
- CHECK(Q, lchar, u16charstar);
-
- CHECK(P, qchar, qchar);
- CHECK(P, qchar, special);
- CHECK(P, qchar, QStringLiteral(LITERAL));
- CHECK(Q, qchar, u16char);
- CHECK(Q, qchar, u16chararray);
- CHECK(Q, qchar, u16charstar);
-
- CHECK(P, special, special);
- CHECK(P, special, QStringLiteral(LITERAL));
- CHECK(Q, special, u16char);
- CHECK(Q, special, u16chararray);
- CHECK(Q, special, u16charstar);
-
- CHECK(P, QStringLiteral(LITERAL), QStringLiteral(LITERAL));
- CHECK(Q, QStringLiteral(LITERAL), u16char);
- CHECK(Q, QStringLiteral(LITERAL), u16chararray);
- CHECK(Q, QStringLiteral(LITERAL), u16charstar);
-
- // CHECK(Q, u16char, u16char); // BUILTIN <-> BUILTIN cat't be overloaded
- // CHECK(Q, u16char, u16chararray);
- // CHECK(Q, u16char, u16charstar);
-
- // CHECK(Q, u16chararray, u16chararray); // BUILTIN <-> BUILTIN cat't be overloaded
- // CHECK(Q, u16chararray, u16charstar);
-
- // CHECK(Q, u16charstar, u16charstar); // BUILTIN <-> BUILTIN cat't be overloaded
-
-#undef DO
-
-#define DO(QorP, a1, a2) \
- QCOMPARE(QByteArray(a1 QorP a2), \
- toQByteArray(a1).append(toQByteArray(a2))) \
- /* end */
-
- QByteArray bytearray = stringref.toUtf8();
- char *charstar = bytearray.data();
- char chararray[3] = { 'H', 'i', '\0' };
- const char constchararray[3] = { 'H', 'i', '\0' };
- char achar = 'a';
-
- CHECK(P, bytearray, bytearray);
- CHECK(P, bytearray, charstar);
-#ifndef Q_CC_MSVC // see QTBUG-65359
- CHECK(P, bytearray, chararray);
-#else
- Q_UNUSED(chararray);
-#endif
- CHECK(P, bytearray, constchararray);
- CHECK(P, bytearray, achar);
-
- //CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded
- //CHECK(Q, charstar, chararray);
- //CHECK(Q, charstar, achar);
-
- //CHECK(Q, chararray, chararray); // BUILTIN <-> BUILTIN cat't be overloaded
- //CHECK(Q, chararray, achar);
-
- //CHECK(Q, achar, achar); // BUILTIN <-> BUILTIN cat't be overloaded
-
-#undef DO
-#undef CHECK
-
- QString r2(QLatin1String(LITERAL LITERAL));
- QString r3 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
- QString r;
-
- // self-assignment:
- r = stringref.toString();
- r = lchar + r;
- QCOMPARE(r, QString(lchar P stringref));
-
-#ifdef Q_COMPILER_UNICODE_STRINGS
- r = QStringLiteral(UNICODE_LITERAL);
- r = r Q QStringLiteral(UNICODE_LITERAL);
- QCOMPARE(r, r3);
-#endif
-
-#ifndef QT_NO_CAST_FROM_ASCII
- r = string P LITERAL;
- QCOMPARE(r, r2);
- r = LITERAL P string;
- QCOMPARE(r, r2);
-
- QByteArray ba = QByteArray(LITERAL);
- r = ba P string;
- QCOMPARE(r, r2);
- r = string P ba;
- QCOMPARE(r, r2);
-
- r = string P QByteArrayLiteral(LITERAL);
- QCOMPARE(r, r2);
- r = QByteArrayLiteral(LITERAL) P string;
- QCOMPARE(r, r2);
-
- static const char badata[] = LITERAL_EXTRA;
- ba = QByteArray::fromRawData(badata, LITERAL_LEN);
- r = ba P string;
- QCOMPARE(r, r2);
- r = string P ba;
- QCOMPARE(r, r2);
-
- string = QString::fromUtf8(UTF8_LITERAL);
- ba = UTF8_LITERAL;
-
- r = string P UTF8_LITERAL;
- QCOMPARE(r.size(), r3.size());
- QCOMPARE(r, r3);
- r = UTF8_LITERAL P string;
- QCOMPARE(r, r3);
- r = ba P string;
- QCOMPARE(r, r3);
- r = string P ba;
- QCOMPARE(r, r3);
-
- ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
- r = ba P string;
- QCOMPARE(r, r3);
- r = string P ba;
- QCOMPARE(r, r3);
-
- ba = QByteArray(); // empty
- r = ba P string;
- QCOMPARE(r, string);
- r = string P ba;
- QCOMPARE(r, string);
-
- const char *zero = 0;
- r = string P zero;
- QCOMPARE(r, string);
- r = zero P string;
- QCOMPARE(r, string);
-#endif
-
- string = QString::fromLatin1(LITERAL);
- QCOMPARE(QByteArray(qPrintable(string P string)), QByteArray(string.toLatin1() + string.toLatin1()));
-
-
-
- //QByteArray
- {
- QByteArray ba = LITERAL;
- QByteArray superba = ba P ba P LITERAL;
- QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
-
- ba = QByteArrayLiteral(LITERAL);
- QCOMPARE(ba, QByteArray(LITERAL));
- superba = ba P QByteArrayLiteral(LITERAL) P LITERAL;
- QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
-
- QByteArray testWith0 = ba P "test\0with\0zero" P ba;
- QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL));
-
- QByteArray ba2 = ba P '\0' + LITERAL;
- QCOMPARE(ba2, QByteArray(LITERAL "\0" LITERAL, ba.size()*2+1));
-
- const char *mmh = "test\0foo";
- QCOMPARE(QByteArray(ba P mmh P ba), testWith0);
-
- QByteArray raw = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
- QByteArray r = "hello" P raw;
- QByteArray r2 = "hello" UTF8_LITERAL;
- QCOMPARE(r, r2);
- r2 = QByteArray("hello\0") P UTF8_LITERAL;
- QCOMPARE(r, r2);
-
- const char *zero = 0;
- r = ba P zero;
- QCOMPARE(r, ba);
- r = zero P ba;
- QCOMPARE(r, ba);
- }
-
- //operator QString +=
- {
- QString str = QString::fromUtf8(UTF8_LITERAL);
- str += QLatin1String(LITERAL) P str;
- QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
-#ifndef QT_NO_CAST_FROM_ASCII
- str = (QString::fromUtf8(UTF8_LITERAL) += QLatin1String(LITERAL) P UTF8_LITERAL);
- QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
-#endif
-
- QString str2 = QString::fromUtf8(UTF8_LITERAL);
- QString str2_e = QString::fromUtf8(UTF8_LITERAL);
- const char * nullData = 0;
- str2 += QLatin1String(nullData) P str2;
- str2_e += QLatin1String("") P str2_e;
- QCOMPARE(str2, str2_e);
- }
-
- //operator QByteArray +=
- {
- QByteArray ba = UTF8_LITERAL;
- ba += QByteArray(LITERAL) P UTF8_LITERAL;
- QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
- ba += LITERAL P QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
- QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL LITERAL UTF8_LITERAL));
- QByteArray withZero = QByteArray(LITERAL "\0" LITERAL, LITERAL_LEN*2+1);
- QByteArray ba2 = withZero;
- ba2 += ba2 P withZero;
- QCOMPARE(ba2, QByteArray(withZero + withZero + withZero));
-#ifndef QT_NO_CAST_TO_ASCII
- ba = UTF8_LITERAL;
- ba2 = (ba += QLatin1String(LITERAL) + QString::fromUtf8(UTF8_LITERAL));
- QCOMPARE(ba2, ba);
- QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
-#endif
- }
-
-}
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp
deleted file mode 100644
index 2d320748f2..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// SCENARIO 1
-// this is the "no harm done" version. Only operator% is active,
-// with NO_CAST * defined
-#define P %
-#undef QT_USE_QSTRINGBUILDER
-#define QT_NO_CAST_FROM_ASCII
-#define QT_NO_CAST_TO_ASCII
-
-
-#include <QtTest/QtTest>
-
-#define LITERAL "some literal"
-
-void runScenario(); // Defined in stringbuilder.cpp #included below.
-
-class tst_QStringBuilder1 : public QObject
-{
- Q_OBJECT
-
-private slots:
- void scenario() { runScenario(); }
-};
-
-#include "stringbuilder.cpp"
-#include "tst_qstringbuilder1.moc"
-
-QTEST_APPLESS_MAIN(tst_QStringBuilder1)
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/qstringbuilder2.pro b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/qstringbuilder2.pro
deleted file mode 100644
index e134c5d934..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/qstringbuilder2.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringbuilder2
-QT = core testlib
-SOURCES = tst_qstringbuilder2.cpp
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp
deleted file mode 100644
index 669990c9bc..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// SCENARIO 2
-// this is the "full" version. Operator+ is replaced by a QStringBuilder
-// based version
-// with NO_CAST * defined
-#define P +
-#define QT_USE_QSTRINGBUILDER
-#define QT_NO_CAST_FROM_ASCII
-#define QT_NO_CAST_TO_ASCII
-
-
-#include <QtTest/QtTest>
-
-#define LITERAL "some literal"
-
-void runScenario(); // Defined in stringbuilder.cpp #included below.
-
-class tst_QStringBuilder2 : public QObject
-{
- Q_OBJECT
-
-private slots:
- void scenario() { runScenario(); }
-};
-
-#include "../qstringbuilder1/stringbuilder.cpp"
-#include "tst_qstringbuilder2.moc"
-
-QTEST_APPLESS_MAIN(tst_QStringBuilder2)
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/qstringbuilder3.pro b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/qstringbuilder3.pro
deleted file mode 100644
index 29607551c3..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/qstringbuilder3.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringbuilder3
-QT = core testlib
-SOURCES = tst_qstringbuilder3.cpp
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp
deleted file mode 100644
index 397e3326bf..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// SCENARIO 3
-// this is the "no harm done" version. Only operator% is active,
-// with NO_CAST * _not_ defined
-#define P %
-#undef QT_USE_QSTRINGBUILDER
-#undef QT_NO_CAST_FROM_ASCII
-#undef QT_NO_CAST_TO_ASCII
-
-
-#include <QtTest/QtTest>
-
-#define LITERAL "some literal"
-
-void runScenario(); // Defined in stringbuilder.cpp #included below.
-
-class tst_QStringBuilder3 : public QObject
-{
- Q_OBJECT
-
-private slots:
- void scenario() { runScenario(); }
-};
-
-#include "../qstringbuilder1/stringbuilder.cpp"
-#include "tst_qstringbuilder3.moc"
-
-QTEST_APPLESS_MAIN(tst_QStringBuilder3)
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/qstringbuilder4.pro b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/qstringbuilder4.pro
deleted file mode 100644
index e55848e4bd..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/qstringbuilder4.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringbuilder4
-QT = core testlib
-SOURCES = tst_qstringbuilder4.cpp
diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp
deleted file mode 100644
index 05ce334c82..0000000000
--- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// SCENARIO 4
-// this is the "full" version. Operator+ is replaced by a QStringBuilder
-// based version
-// with NO_CAST * _not_ defined
-#define P +
-#define QT_USE_QSTRINGBUILDER
-#undef QT_NO_CAST_FROM_ASCII
-#undef QT_NO_CAST_TO_ASCII
-
-
-#include <QtTest/QtTest>
-
-#define LITERAL "some literal"
-
-void runScenario(); // Defined in stringbuilder.cpp #included below.
-
-class tst_QStringBuilder4 : public QObject
-{
- Q_OBJECT
-
-private slots:
- void scenario() { runScenario(); }
-};
-
-#include "../qstringbuilder1/stringbuilder.cpp"
-#include "tst_qstringbuilder4.moc"
-
-QTEST_APPLESS_MAIN(tst_QStringBuilder4)
diff --git a/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro b/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro
deleted file mode 100644
index 3a1678b5f3..0000000000
--- a/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringiterator
-QT = core core-private testlib
-SOURCES = tst_qstringiterator.cpp
-
diff --git a/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp b/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp
deleted file mode 100644
index 7d5504c22c..0000000000
--- a/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp
+++ /dev/null
@@ -1,662 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QString>
-#include <private/qstringiterator_p.h>
-
-class tst_QStringIterator : public QObject
-{
- Q_OBJECT
-private slots:
- void sweep_data();
- void sweep();
-
- void position();
-};
-
-void tst_QStringIterator::sweep_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<bool>("valid");
- QTest::addColumn<int>("count");
-
- QTest::newRow("sweep_00") << QString::fromUtf8("", 0) << true << 0;
- QTest::newRow("sweep_01") << QString::fromUtf8("a", 1) << true << 1;
- QTest::newRow("sweep_02") << QString::fromUtf8("a string", 8) << true << 8;
- QTest::newRow("sweep_03") << QString::fromUtf8("\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb2\xc3\xb9", 10) << true << 5;
- QTest::newRow("sweep_04") << QString::fromUtf8("\xc3\x9f\xe2\x80\x94\xc2\xa1", 7) << true << 3;
- QTest::newRow("sweep_05") << QString::fromUtf8("\xe6\xb0\xb4\xe6\xb0\xb5\xe6\xb0\xb6\xe6\xb0\xb7\xe6\xb0\xb8\xe6\xb0\xb9", 18) << true << 6;
- QTest::newRow("sweep_06") << QString::fromUtf8("\xf0\x9f\x98\x81\xf0\x9f\x98\x82\x61\x62\x63\xf0\x9f\x98\x83\xc4\x91\xc3\xa8\xef\xac\x80\xf0\x9f\x98\x84\xf0\x9f\x98\x85", 30) << true << 11;
- QTest::newRow("sweep_07") << QString::fromUtf8("\xf0\x9f\x82\xaa\xf0\x9f\x82\xab\xf0\x9f\x82\xad\xf0\x9f\x82\xae\xf0\x9f\x82\xa1\x20\x52\x4f\x59\x41\x4c\x20\x46\x4c\x55\x53\x48\x20\x4f\x46\x20\x53\x50\x41\x44\x45\x53", 42) << true << 27;
- QTest::newRow("sweep_08") << QString::fromUtf8("abc\0def", 7) << true << 7;
- QTest::newRow("sweep_09") << QString::fromUtf8("\xc3\xa0\xce\xb2\xc3\xa7\xf0\x9f\x80\xb9\xf0\x9f\x80\xb8\x00\xf0\x9f\x80\xb1\x00\xf0\x9f\x80\xb3\xf0\x9f\x81\x85\xe1\xb8\x8a\xc4\x99\xc6\x92", 35) << true << 13;
-
- QTest::newRow("sweep_invalid_00") << QString(QChar(0xd800)) << false << 1;
- QTest::newRow("sweep_invalid_01") << QString(QChar(0xdc00)) << false << 1;
- QTest::newRow("sweep_invalid_02") << QString(QChar(0xdbff)) << false << 1;
- QTest::newRow("sweep_invalid_03") << QString(QChar(0xdfff)) << false << 1;
-
-#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
-
- static const QChar invalid_04[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xd800)
- };
- QTest::newRow("sweep_invalid_04") << QSTRING_FROM_QCHARARRAY(invalid_04) << false << 8;
-
- static const QChar invalid_05[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
- };
- QTest::newRow("sweep_invalid_05") << QSTRING_FROM_QCHARARRAY(invalid_05) << false << 9;
-
- static const QChar invalid_06[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xdc00)
- };
- QTest::newRow("sweep_invalid_06") << QSTRING_FROM_QCHARARRAY(invalid_06) << false << 8;
-
- static const QChar invalid_07[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
- };
- QTest::newRow("sweep_invalid_07") << QSTRING_FROM_QCHARARRAY(invalid_07) << false << 9;
-
- static const QChar invalid_08[] = {
- QChar(0xd800),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_08") << QSTRING_FROM_QCHARARRAY(invalid_08) << false << 8;
-
- static const QChar invalid_09[] = {
- QChar(0xdc00),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_09") << QSTRING_FROM_QCHARARRAY(invalid_09) << false << 8;
-
- static const QChar invalid_10[] = {
- QChar(0xd800), QChar(0xd800),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_10") << QSTRING_FROM_QCHARARRAY(invalid_10) << false << 9;
-
- static const QChar invalid_11[] = {
- QChar(0xdc00), QChar(0xd800),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_11") << QSTRING_FROM_QCHARARRAY(invalid_11) << false << 9;
-
- static const QChar invalid_12[] = {
- QChar(0xdc00), QChar(0xdc00),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_12") << QSTRING_FROM_QCHARARRAY(invalid_12) << false << 9;
-
- static const QChar invalid_13[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xd800)
- };
- QTest::newRow("sweep_invalid_13") << QSTRING_FROM_QCHARARRAY(invalid_13) << false << 9;
-
- static const QChar invalid_14[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
- };
- QTest::newRow("sweep_invalid_14") << QSTRING_FROM_QCHARARRAY(invalid_14) << false << 10;
-
- static const QChar invalid_15[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xdc00)
- };
- QTest::newRow("sweep_invalid_15") << QSTRING_FROM_QCHARARRAY(invalid_15) << false << 9;
-
- static const QChar invalid_16[] = {
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
- };
- QTest::newRow("sweep_invalid_16") << QSTRING_FROM_QCHARARRAY(invalid_16) << false << 10;
-
- static const QChar invalid_17[] = {
- QChar(0xd800),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_17") << QSTRING_FROM_QCHARARRAY(invalid_17) << false << 9;
-
- static const QChar invalid_18[] = {
- QChar(0xdc00),
- QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
- QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
- QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
- QLatin1Char('d')
- };
- QTest::newRow("sweep_invalid_18") << QSTRING_FROM_QCHARARRAY(invalid_18) << false << 9;
-
-#undef QSTRING_FROM_QCHARARRAY
-}
-
-void tst_QStringIterator::sweep()
-{
- QFETCH(QString, string);
- QFETCH(bool, valid);
-
- QStringIterator i(string);
- int count = 0;
- QString rebuiltString;
-
- while (i.hasNext()) {
- const uint peekedCodePoint = i.peekNext(~0u);
- const uint codePoint = i.next(~0u);
-
- QVERIFY(peekedCodePoint == codePoint);
-
- if (codePoint == ~0u)
- rebuiltString += *(i.position() - 1);
- else
- rebuiltString += QString::fromUcs4(&codePoint, 1);
-
- ++count;
- }
-
- QTEST(count, "count");
- QTEST(rebuiltString, "string");
- rebuiltString.clear();
-
- while (i.hasPrevious()) {
- const uint peekedCodePoint = i.peekPrevious(~0u);
- const uint codePoint = i.previous(~0u);
-
- QVERIFY(peekedCodePoint == codePoint);
-
- --count;
- }
-
- QCOMPARE(count, 0);
-
- while (i.hasNext()) {
- i.advance();
- ++count;
- }
-
- QTEST(count, "count");
-
- while (i.hasPrevious()) {
- i.recede();
- --count;
- }
-
- QCOMPARE(count, 0);
-
- if (valid) {
- while (i.hasNext()) {
- const uint peekedCodePoint = i.peekNextUnchecked();
- const uint codePoint = i.nextUnchecked();
-
- QVERIFY(peekedCodePoint == codePoint);
- QVERIFY(codePoint <= 0x10FFFFu);
- rebuiltString += QString::fromUcs4(&codePoint, 1);
- ++count;
- }
-
- QTEST(count, "count");
- QTEST(rebuiltString, "string");
-
- while (i.hasPrevious()) {
- const uint peekedCodePoint = i.peekPreviousUnchecked();
- const uint codePoint = i.previousUnchecked();
-
- QVERIFY(peekedCodePoint == codePoint);
-
- --count;
- }
-
- QCOMPARE(count, 0);
-
- while (i.hasNext()) {
- i.advanceUnchecked();
- ++count;
- }
-
- QTEST(count, "count");
-
- while (i.hasPrevious()) {
- i.recedeUnchecked();
- --count;
- }
-
- QCOMPARE(count, 0);
- }
-}
-
-void tst_QStringIterator::position()
-{
- static const QChar stringData[] =
- {
- // codeunit count: 0
- QLatin1Char('a'), QLatin1Char('b'), QLatin1Char('c'),
- // codeunit count: 3
- QChar(0x00A9), // U+00A9 COPYRIGHT SIGN
- // codeunit count: 4
- QChar(0x00AE), // U+00AE REGISTERED SIGN
- // codeunit count: 5
- QLatin1Char('d'), QLatin1Char('e'), QLatin1Char('f'),
- // codeunit count: 8
- QLatin1Char('\0'),
- // codeunit count: 9
- QLatin1Char('g'), QLatin1Char('h'), QLatin1Char('i'),
- // codeunit count: 12
- QChar(0xD834), QChar(0xDD1E), // U+1D11E MUSICAL SYMBOL G CLEF
- // codeunit count: 14
- QChar(0xD834), QChar(0xDD21), // U+1D121 MUSICAL SYMBOL C CLEF
- // codeunit count: 16
- QLatin1Char('j'),
- // codeunit count: 17
- QChar(0xD800), // stray high surrogate
- // codeunit count: 18
- QLatin1Char('k'),
- // codeunit count: 19
- QChar(0xDC00), // stray low surrogate
- // codeunit count: 20
- QLatin1Char('l'),
- // codeunit count: 21
- QChar(0xD800), QChar(0xD800), // two high surrogates
- // codeunit count: 23
- QLatin1Char('m'),
- // codeunit count: 24
- QChar(0xDC00), QChar(0xDC00), // two low surrogates
- // codeunit count: 26
- QLatin1Char('n'),
- // codeunit count: 27
- QChar(0xD800), QChar(0xD800), QChar(0xDC00), // stray high surrogate followed by valid pair
- // codeunit count: 30
- QLatin1Char('o'),
- // codeunit count: 31
- QChar(0xDC00), QChar(0xD800), QChar(0xDC00), // stray low surrogate followed by valid pair
- // codeunit count: 34
- QLatin1Char('p')
- // codeunit count: 35
- };
- static const int stringDataSize = sizeof(stringData) / sizeof(stringData[0]);
-
- QStringIterator i(QStringView(stringData, stringDataSize));
-
- QCOMPARE(i.position(), stringData);
- QVERIFY(i.hasNext());
- QVERIFY(!i.hasPrevious());
-
- i.setPosition(stringData + stringDataSize);
- QCOMPARE(i.position(), stringData + stringDataSize);
- QVERIFY(!i.hasNext());
- QVERIFY(i.hasPrevious());
-
-#define QCHAR_UNICODE_VALUE(x) ((uint)(QChar(x).unicode()))
-
- const QChar *begin = stringData;
- i.setPosition(begin);
- QCOMPARE(i.position(), begin);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
-
- QCOMPARE(i.position(), begin + 1);
-
- i.setPosition(begin + 2);
- QCOMPARE(i.position(), begin + 2);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
-
- QCOMPARE(i.position(), begin + 3);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00A9));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00A9));
-
- QCOMPARE(i.position(), begin + 4);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00AE));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00AE));
-
- QCOMPARE(i.position(), begin + 5);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00AE));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00AE));
-
- QCOMPARE(i.position(), begin + 4);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00A9));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00A9));
-
- QCOMPARE(i.position(), begin + 3);
-
- i.setPosition(begin + 8);
- QCOMPARE(i.position(), begin + 8);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
-
- QCOMPARE(i.position(), begin + 9);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
-
- QCOMPARE(i.position(), begin + 10);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
-
- QCOMPARE(i.position(), begin + 9);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
-
- QCOMPARE(i.position(), begin + 8);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
-
- QCOMPARE(i.position(), begin + 7);
-
- i.advanceUnchecked();
- i.advanceUnchecked();
- i.advanceUnchecked();
- i.advanceUnchecked();
- i.advanceUnchecked();
-
- QCOMPARE(i.position(), begin + 12);
- QCOMPARE(i.peekNext(), 0x1D11Eu);
- QCOMPARE(i.next(), 0x1D11Eu);
-
- QCOMPARE(i.position(), begin + 14);
- QCOMPARE(i.peekNext(), 0x1D121u);
- QCOMPARE(i.next(), 0x1D121u);
-
- QCOMPARE(i.position(), begin + 16);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
-
- QCOMPARE(i.position(), begin + 17);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
-
- QCOMPARE(i.position(), begin + 16);
- QCOMPARE(i.peekPrevious(), 0x1D121u);
- QCOMPARE(i.previous(), 0x1D121u);
-
- QCOMPARE(i.position(), begin + 14);
- QCOMPARE(i.peekPrevious(), 0x1D11Eu);
- QCOMPARE(i.previous(), 0x1D11Eu);
-
- QCOMPARE(i.position(), begin + 12);
-
-
- i.setPosition(begin + 13);
- QCOMPARE(i.position(), begin + 13);
-
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 14);
- QCOMPARE(i.peekNext(), 0x1D121u);
- QCOMPARE(i.next(), 0x1D121u);
-
- QCOMPARE(i.position(), begin + 16);
-
-
- i.setPosition(begin + 15);
- QCOMPARE(i.position(), begin + 15);
-
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 14);
- QCOMPARE(i.peekPrevious(), 0x1D11Eu);
- QCOMPARE(i.previous(), 0x1D11Eu);
-
- QCOMPARE(i.position(), begin + 12);
-
- i.advanceUnchecked();
- i.advanceUnchecked();
-
- QCOMPARE(i.position(), begin + 16);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
-
- QCOMPARE(i.position(), begin + 17);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 18);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
-
- QCOMPARE(i.position(), begin + 19);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 20);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
-
- QCOMPARE(i.position(), begin + 21);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 22);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 23);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
-
- QCOMPARE(i.position(), begin + 24);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 25);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 26);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
-
- QCOMPARE(i.position(), begin + 27);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 28);
- QCOMPARE(i.peekNext(), 0x10000u);
- QCOMPARE(i.next(), 0x10000u);
-
- QCOMPARE(i.position(), begin + 30);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
-
- QCOMPARE(i.position(), begin + 31);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 32);
- QCOMPARE(i.peekNext(), 0x10000u);
- QCOMPARE(i.next(), 0x10000u);
-
- QCOMPARE(i.position(), begin + 34);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
-
- QVERIFY(!i.hasNext());
-
- QCOMPARE(i.position(), begin + 35);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
-
- QCOMPARE(i.position(), begin + 34);
- QCOMPARE(i.peekPrevious(), 0x10000u);
- QCOMPARE(i.previous(), 0x10000u);
-
- QCOMPARE(i.position(), begin + 32);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 31);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
-
- QCOMPARE(i.position(), begin + 30);
- QCOMPARE(i.peekPrevious(), 0x10000u);
- QCOMPARE(i.previous(), 0x10000u);
-
- QCOMPARE(i.position(), begin + 28);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 27);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
-
- QCOMPARE(i.position(), begin + 26);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 25);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 24);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
-
- QCOMPARE(i.position(), begin + 23);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 22);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 21);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
-
- QCOMPARE(i.position(), begin + 20);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 19);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
-
- QCOMPARE(i.position(), begin + 18);
- QCOMPARE(i.peekPrevious(), 0xFFFDu);
- QCOMPARE(i.previous(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 17);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
-
- i.setPosition(begin + 29);
- QCOMPARE(i.position(), begin + 29);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 30);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
-
- QCOMPARE(i.position(), begin + 31);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
-
- QCOMPARE(i.position(), begin + 30);
- QCOMPARE(i.peekPrevious(), 0x10000u);
- QCOMPARE(i.previous(), 0x10000u);
-
- QCOMPARE(i.position(), begin + 28);
-
- i.setPosition(begin + 33);
- QCOMPARE(i.position(), begin + 33);
- QCOMPARE(i.peekNext(), 0xFFFDu);
- QCOMPARE(i.next(), 0xFFFDu);
-
- QCOMPARE(i.position(), begin + 34);
- QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
- QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
-
- QCOMPARE(i.position(), begin + 35);
- QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
- QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
-
- QCOMPARE(i.position(), begin + 34);
- QCOMPARE(i.peekPrevious(), 0x10000u);
- QCOMPARE(i.previous(), 0x10000u);
-
- QCOMPARE(i.position(), begin + 32);
-
-
- i.setPosition(begin + 16);
- QCOMPARE(i.position(), begin + 16);
-
- i.recedeUnchecked();
- i.recedeUnchecked();
- QCOMPARE(i.position(), begin + 12);
-
- i.recedeUnchecked();
- i.recedeUnchecked();
- i.recedeUnchecked();
- i.recedeUnchecked();
- QCOMPARE(i.position(), begin + 8);
-
- i.recedeUnchecked();
- i.recedeUnchecked();
- i.recedeUnchecked();
- i.recedeUnchecked();
- i.recedeUnchecked();
- i.recedeUnchecked();
- QCOMPARE(i.position(), begin + 2);
-
-#undef QCHAR_UNICODE_VALUE
-}
-
-QTEST_APPLESS_MAIN(tst_QStringIterator)
-
-#include "tst_qstringiterator.moc"
diff --git a/tests/auto/corelib/tools/qstringlist/qstringlist.pro b/tests/auto/corelib/tools/qstringlist/qstringlist.pro
deleted file mode 100644
index a87257decb..0000000000
--- a/tests/auto/corelib/tools/qstringlist/qstringlist.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringlist
-QT = core testlib
-SOURCES = tst_qstringlist.cpp
diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
deleted file mode 100644
index a3aec4c299..0000000000
--- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qregexp.h>
-#include <qregularexpression.h>
-#include <qstringlist.h>
-
-#include <locale.h>
-
-class tst_QStringList : public QObject
-{
- Q_OBJECT
-private slots:
- void sort();
- void filter();
- void replaceInStrings();
- void removeDuplicates();
- void removeDuplicates_data();
- void contains();
- void indexOf();
- void lastIndexOf();
-
- void indexOf_regExp();
- void lastIndexOf_regExp();
-
- void streamingOperator();
- void assignmentOperator();
- void join() const;
- void join_data() const;
- void joinEmptiness() const;
- void joinChar() const;
- void joinChar_data() const;
-
-#ifdef Q_COMPILER_INITIALIZER_LISTS
- void initializeList() const;
-#endif
-};
-
-extern const char email[];
-
-void tst_QStringList::indexOf_regExp()
-{
- QStringList list;
- list << "harald" << "trond" << "vohi" << "harald";
- {
- QRegExp re(".*o.*");
-
- QCOMPARE(list.indexOf(re), 1);
- QCOMPARE(list.indexOf(re, 2), 2);
- QCOMPARE(list.indexOf(re, 3), -1);
-
- QCOMPARE(list.indexOf(QRegExp(".*x.*")), -1);
- QCOMPARE(list.indexOf(re, -1), -1);
- QCOMPARE(list.indexOf(re, -3), 1);
- QCOMPARE(list.indexOf(re, -9999), 1);
- QCOMPARE(list.indexOf(re, 9999), -1);
-
- QCOMPARE(list.indexOf(QRegExp("[aeiou]")), -1);
- }
-
- {
- QRegularExpression re(".*o.*");
-
- QCOMPARE(list.indexOf(re), 1);
- QCOMPARE(list.indexOf(re, 2), 2);
- QCOMPARE(list.indexOf(re, 3), -1);
-
- QCOMPARE(list.indexOf(QRegularExpression(".*x.*")), -1);
- QCOMPARE(list.indexOf(re, -1), -1);
- QCOMPARE(list.indexOf(re, -3), 1);
- QCOMPARE(list.indexOf(re, -9999), 1);
- QCOMPARE(list.indexOf(re, 9999), -1);
-
- QCOMPARE(list.indexOf(QRegularExpression("[aeiou]")), -1);
- }
-}
-
-void tst_QStringList::lastIndexOf_regExp()
-{
- QStringList list;
- list << "harald" << "trond" << "vohi" << "harald";
-
- {
- QRegExp re(".*o.*");
-
- QCOMPARE(list.lastIndexOf(re), 2);
- QCOMPARE(list.lastIndexOf(re, 2), 2);
- QCOMPARE(list.lastIndexOf(re, 1), 1);
-
- QCOMPARE(list.lastIndexOf(QRegExp(".*x.*")), -1);
- QCOMPARE(list.lastIndexOf(re, -1), 2);
- QCOMPARE(list.lastIndexOf(re, -3), 1);
- QCOMPARE(list.lastIndexOf(re, -9999), -1);
- QCOMPARE(list.lastIndexOf(re, 9999), 2);
-
- QCOMPARE(list.lastIndexOf(QRegExp("[aeiou]")), -1);
- }
-
- {
- QRegularExpression re(".*o.*");
-
- QCOMPARE(list.lastIndexOf(re), 2);
- QCOMPARE(list.lastIndexOf(re, 2), 2);
- QCOMPARE(list.lastIndexOf(re, 1), 1);
-
- QCOMPARE(list.lastIndexOf(QRegularExpression(".*x.*")), -1);
- QCOMPARE(list.lastIndexOf(re, -1), 2);
- QCOMPARE(list.lastIndexOf(re, -3), 1);
- QCOMPARE(list.lastIndexOf(re, -9999), -1);
- QCOMPARE(list.lastIndexOf(re, 9999), 2);
-
- QCOMPARE(list.lastIndexOf(QRegularExpression("[aeiou]")), -1);
- }
-
-
-}
-
-void tst_QStringList::indexOf()
-{
- QStringList list;
- list << "harald" << "trond" << "vohi" << "harald";
-
- QCOMPARE(list.indexOf("harald"), 0);
- QCOMPARE(list.indexOf("trond"), 1);
- QCOMPARE(list.indexOf("vohi"), 2);
- QCOMPARE(list.indexOf("harald", 1), 3);
-
- QCOMPARE(list.indexOf("hans"), -1);
- QCOMPARE(list.indexOf("trond", 2), -1);
- QCOMPARE(list.indexOf("harald", -1), 3);
- QCOMPARE(list.indexOf("vohi", -3), 2);
-}
-
-void tst_QStringList::lastIndexOf()
-{
- QStringList list;
- list << "harald" << "trond" << "vohi" << "harald";
-
- QCOMPARE(list.lastIndexOf("harald"), 3);
- QCOMPARE(list.lastIndexOf("trond"), 1);
- QCOMPARE(list.lastIndexOf("vohi"), 2);
- QCOMPARE(list.lastIndexOf("harald", 2), 0);
-
- QCOMPARE(list.lastIndexOf("hans"), -1);
- QCOMPARE(list.lastIndexOf("vohi", 1), -1);
- QCOMPARE(list.lastIndexOf("vohi", -1), 2);
- QCOMPARE(list.lastIndexOf("vohi", -3), -1);
-}
-
-void tst_QStringList::filter()
-{
- QStringList list1, list2;
- list1 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
- list1 = list1.filter( "Bill" );
- list2 << "Bill Gates" << "Bill Clinton";
- QCOMPARE( list1, list2 );
-
- QStringList list3, list4;
- list3 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
- list3 = list3.filter( QRegExp("[i]ll") );
- list4 << "Bill Gates" << "Bill Clinton";
- QCOMPARE( list3, list4 );
-
- QStringList list5, list6;
- list5 << "Bill Gates" << "Joe Blow" << "Bill Clinton";
- list5 = list5.filter( QRegularExpression("[i]ll") );
- list6 << "Bill Gates" << "Bill Clinton";
- QCOMPARE( list5, list6 );
-}
-
-void tst_QStringList::sort()
-{
- QStringList list1, list2;
- list1 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon";
- list1.sort();
- list2 << "BETA" << "Gamma" << "alpha" << "beta" << "epsilon" << "gAmma" << "gamma";
- QCOMPARE( list1, list2 );
-
- char *current_locale = setlocale(LC_ALL, "C");
- QStringList list3, list4;
- list3 << "alpha" << "beta" << "BETA" << "gamma" << "Gamma" << "gAmma" << "epsilon";
- list3.sort(Qt::CaseInsensitive);
- list4 << "alpha" << "beta" << "BETA" << "epsilon" << "Gamma" << "gAmma" << "gamma";
- // with this list, case insensitive sorting can give more than one permutation for "equivalent"
- // elements; so we check that the sort gave the formally correct result (list[i] <= list[i+1])
- for (int i = 0; i < list4.count() - 1; ++i)
- QVERIFY2(QString::compare(list4.at(i), list4.at(i + 1), Qt::CaseInsensitive) <= 0, qPrintable(QString("index %1 failed").arg(i)));
- // additional checks
- QCOMPARE(list4.at(0), QString("alpha"));
- QVERIFY(list4.indexOf("epsilon") > 0);
- QVERIFY(list4.indexOf("epsilon") < (list4.count() - 1));
- setlocale(LC_ALL, current_locale);
-}
-
-void tst_QStringList::replaceInStrings()
-{
- QStringList list1, list2;
- list1 << "alpha" << "beta" << "gamma" << "epsilon";
- list1.replaceInStrings( "a", "o" );
- list2 << "olpho" << "beto" << "gommo" << "epsilon";
- QCOMPARE( list1, list2 );
-
- QStringList list3, list4;
- list3 << "alpha" << "beta" << "gamma" << "epsilon";
- list3.replaceInStrings( QRegExp("^a"), "o" );
- list4 << "olpha" << "beta" << "gamma" << "epsilon";
- QCOMPARE( list3, list4 );
-
- QStringList list5, list6;
- list5 << "Bill Clinton" << "Gates, Bill";
- list6 << "Bill Clinton" << "Bill Gates";
- list5.replaceInStrings( QRegExp("^(.*), (.*)$"), "\\2 \\1" );
- QCOMPARE( list5, list6 );
-
- QStringList list7, list8;
- list7 << "alpha" << "beta" << "gamma" << "epsilon";
- list7.replaceInStrings( QRegularExpression("^a"), "o" );
- list8 << "olpha" << "beta" << "gamma" << "epsilon";
- QCOMPARE( list7, list8 );
-
- QStringList list9, list10;
- list9 << "Bill Clinton" << "Gates, Bill";
- list10 << "Bill Clinton" << "Bill Gates";
- list9.replaceInStrings( QRegularExpression("^(.*), (.*)$"), "\\2 \\1" );
- QCOMPARE( list9, list10 );
-}
-
-void tst_QStringList::contains()
-{
- QStringList list;
- list << "arthur" << "Arthur" << "arthuR" << "ARTHUR" << "Dent" << "Hans Dent";
-
- QVERIFY(list.contains("arthur"));
- QVERIFY(!list.contains("ArthuR"));
- QVERIFY(!list.contains("Hans"));
- QVERIFY(list.contains("arthur", Qt::CaseInsensitive));
- QVERIFY(list.contains("ArthuR", Qt::CaseInsensitive));
- QVERIFY(list.contains("ARTHUR", Qt::CaseInsensitive));
- QVERIFY(list.contains("dent", Qt::CaseInsensitive));
- QVERIFY(!list.contains("hans", Qt::CaseInsensitive));
-
- QVERIFY(list.contains(QLatin1String("arthur")));
- QVERIFY(!list.contains(QLatin1String("ArthuR")));
- QVERIFY(!list.contains(QLatin1String("Hans")));
- QVERIFY(list.contains(QLatin1String("arthur"), Qt::CaseInsensitive));
- QVERIFY(list.contains(QLatin1String("ArthuR"), Qt::CaseInsensitive));
- QVERIFY(list.contains(QLatin1String("ARTHUR"), Qt::CaseInsensitive));
- QVERIFY(list.contains(QLatin1String("dent"), Qt::CaseInsensitive));
- QVERIFY(!list.contains(QLatin1String("hans"), Qt::CaseInsensitive));
-
- QVERIFY(list.contains(QStringView(QString("arthur"))));
- QVERIFY(!list.contains(QStringView(QString("ArthuR"))));
- QVERIFY(!list.contains(QStringView(QString("Hans"))));
- QVERIFY(list.contains(QStringView(QString("arthur")), Qt::CaseInsensitive));
- QVERIFY(list.contains(QStringView(QString("ArthuR")), Qt::CaseInsensitive));
- QVERIFY(list.contains(QStringView(QString("ARTHUR")), Qt::CaseInsensitive));
- QVERIFY(list.contains(QStringView(QString("dent")), Qt::CaseInsensitive));
- QVERIFY(!list.contains(QStringView(QString("hans")), Qt::CaseInsensitive));
-}
-
-void tst_QStringList::removeDuplicates_data()
-{
- QTest::addColumn<QString>("before");
- QTest::addColumn<QString>("after");
- QTest::addColumn<int>("count");
- QTest::addColumn<bool>("detached");
-
- QTest::newRow("empty-1") << "Hello,Hello" << "Hello" << 1 << true;
- QTest::newRow("empty-2") << "Hello,World" << "Hello,World" << 0 << false;
- QTest::newRow("middle") << "Hello,World,Hello" << "Hello,World" << 1 << true;
-}
-
-void tst_QStringList::removeDuplicates()
-{
- QFETCH(QString, before);
- QFETCH(QString, after);
- QFETCH(int, count);
- QFETCH(bool, detached);
-
- QStringList lbefore = before.split(',');
- const QStringList oldlbefore = lbefore;
- QStringList lafter = after.split(',');
- int removed = lbefore.removeDuplicates();
-
- QCOMPARE(removed, count);
- QCOMPARE(lbefore, lafter);
- QCOMPARE(detached, !oldlbefore.isSharedWith(lbefore));
-}
-
-void tst_QStringList::streamingOperator()
-{
- QStringList list;
- list << "hei";
- list << list << "hopp" << list;
-
- QList<QString> slist = list;
- list << slist;
-
- QCOMPARE(list, QStringList()
- << "hei" << "hei" << "hopp"
- << "hei" << "hei" << "hopp"
- << "hei" << "hei" << "hopp"
- << "hei" << "hei" << "hopp");
-
- QStringList list2;
- list2 << "adam";
-
- QStringList list3;
- list3 << "eva";
-
- QCOMPARE(list2 << list3, QStringList() << "adam" << "eva");
-}
-
-void tst_QStringList::assignmentOperator()
-{
- // compile-only test
-
- QStringList adam;
- adam << "adam";
- QList<QString> eva;
- eva << "eva";
- QStringList result;
- QStringList &ref1 = (result = adam);
- QStringList &ref2 = (result = eva);
- Q_UNUSED(ref1);
- Q_UNUSED(ref2);
-}
-
-void tst_QStringList::join() const
-{
- QFETCH(QStringList, input);
- QFETCH(QString, separator);
- QFETCH(QString, expectedResult);
-
- QCOMPARE(input.join(separator), expectedResult);
- QCOMPARE(input.join(QLatin1String(separator.toLatin1())), expectedResult);
-}
-
-void tst_QStringList::join_data() const
-{
- QTest::addColumn<QStringList>("input");
- QTest::addColumn<QString>("separator");
- QTest::addColumn<QString>("expectedResult");
-
- QTest::newRow("data1")
- << QStringList()
- << QString()
- << QString();
-
- QTest::newRow("data2")
- << QStringList()
- << QString(QLatin1String("separator"))
- << QString();
-
- QTest::newRow("data3")
- << QStringList("one")
- << QString(QLatin1String("separator"))
- << QString("one");
-
- QTest::newRow("data4")
- << QStringList("one")
- << QString(QLatin1String("separator"))
- << QString("one");
-
-
- QTest::newRow("data5")
- << (QStringList()
- << QLatin1String("a")
- << QLatin1String("b"))
- << QString(QLatin1String(" "))
- << QString("a b");
-
- QTest::newRow("data6")
- << (QStringList()
- << QLatin1String("a")
- << QLatin1String("b")
- << QLatin1String("c"))
- << QString(QLatin1String(" "))
- << QString("a b c");
-}
-
-void tst_QStringList::joinChar() const
-{
- QFETCH(QStringList, input);
- QFETCH(QChar, separator);
- QFETCH(QString, expectedResult);
-
- QCOMPARE(input.join(separator), expectedResult);
-}
-
-void tst_QStringList::joinChar_data() const
-{
- QTest::addColumn<QStringList>("input");
- QTest::addColumn<QChar>("separator");
- QTest::addColumn<QString>("expectedResult");
-
- QTest::newRow("data1")
- << QStringList()
- << QChar(QLatin1Char(' '))
- << QString();
-
- QTest::newRow("data5")
- << (QStringList()
- << QLatin1String("a")
- << QLatin1String("b"))
- << QChar(QLatin1Char(' '))
- << QString("a b");
-
- QTest::newRow("data6")
- << (QStringList()
- << QLatin1String("a")
- << QLatin1String("b")
- << QLatin1String("c"))
- << QChar(QLatin1Char(' '))
- << QString("a b c");
-}
-
-void tst_QStringList::joinEmptiness() const
-{
- QStringList list;
- QString string = list.join(QString());
-
- QVERIFY(string.isEmpty());
- QVERIFY(string.isNull());
-}
-
-#ifdef Q_COMPILER_INITIALIZER_LISTS
-// C++0x support is required
-void tst_QStringList::initializeList() const
-{
-
- QStringList v1{QLatin1String("hello"),"world",QString::fromLatin1("plop")};
- QCOMPARE(v1, (QStringList() << "hello" << "world" << "plop"));
- QCOMPARE(v1, (QStringList{"hello","world","plop"}));
-}
-#endif
-
-QTEST_APPLESS_MAIN(tst_QStringList)
-#include "tst_qstringlist.moc"
diff --git a/tests/auto/corelib/tools/qstringmatcher/qstringmatcher.pro b/tests/auto/corelib/tools/qstringmatcher/qstringmatcher.pro
deleted file mode 100644
index e34928776f..0000000000
--- a/tests/auto/corelib/tools/qstringmatcher/qstringmatcher.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringmatcher
-QT = core testlib
-SOURCES = tst_qstringmatcher.cpp
-DEFINES += QT_NO_CAST_TO_ASCII
diff --git a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp b/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp
deleted file mode 100644
index 8a55f54449..0000000000
--- a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qstringmatcher.h>
-
-class tst_QStringMatcher : public QObject
-{
- Q_OBJECT
-
-private slots:
- void qstringmatcher();
- void caseSensitivity();
- void indexIn_data();
- void indexIn();
- void setCaseSensitivity_data();
- void setCaseSensitivity();
- void assignOperator();
-};
-
-void tst_QStringMatcher::qstringmatcher()
-{
- QStringMatcher matcher;
- QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
- QCOMPARE(matcher.indexIn("foo", 1), 1);
- QCOMPARE(matcher.pattern(), QString());
-}
-
-// public Qt::CaseSensitivity caseSensitivity() const
-void tst_QStringMatcher::caseSensitivity()
-{
- const QString haystack = QStringLiteral("foobarFoo");
- const QStringRef needle = haystack.rightRef(3); // "Foo"
- QStringMatcher matcher(needle.data(), needle.size());
-
- QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
- QCOMPARE(matcher.indexIn(haystack), 6);
-
- matcher.setCaseSensitivity(Qt::CaseInsensitive);
-
- QCOMPARE(matcher.caseSensitivity(), Qt::CaseInsensitive);
- QCOMPARE(matcher.indexIn(haystack), 0);
-
- matcher.setCaseSensitivity(Qt::CaseSensitive);
- QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
- QCOMPARE(matcher.indexIn(haystack), 6);
-}
-
-void tst_QStringMatcher::indexIn_data()
-{
- QTest::addColumn<QString>("needle");
- QTest::addColumn<QString>("haystack");
- QTest::addColumn<int>("from");
- QTest::addColumn<int>("indexIn");
- QTest::newRow("empty-1") << QString() << QString("foo") << 0 << 0;
- QTest::newRow("empty-2") << QString() << QString("foo") << 10 << -1;
- QTest::newRow("empty-3") << QString() << QString("foo") << -10 << 0;
-
- QTest::newRow("simple-1") << QString("a") << QString("foo") << 0 << -1;
- QTest::newRow("simple-2") << QString("a") << QString("bar") << 0 << 1;
- QTest::newRow("harder-1") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 0 << 26;
- QTest::newRow("harder-2") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 20 << 26;
- QTest::newRow("harder-3") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 26 << 26;
- QTest::newRow("harder-4") << QString("foo") << QString("slkdf sldkjf slakjf lskd ffools ldjf") << 27 << -1;
-}
-
-void tst_QStringMatcher::indexIn()
-{
- QFETCH(QString, needle);
- QFETCH(QString, haystack);
- QFETCH(int, from);
- QFETCH(int, indexIn);
-
- QStringMatcher matcher;
- matcher.setPattern(needle);
-
- QCOMPARE(matcher.indexIn(haystack, from), indexIn);
-}
-
-void tst_QStringMatcher::setCaseSensitivity_data()
-{
- QTest::addColumn<QString>("needle");
- QTest::addColumn<QString>("haystack");
- QTest::addColumn<int>("from");
- QTest::addColumn<int>("indexIn");
- QTest::addColumn<int>("cs");
-
- QTest::newRow("overshot") << QString("foo") << QString("baFooz foo bar") << 14 << -1 << (int) Qt::CaseSensitive;
- QTest::newRow("sensitive") << QString("foo") << QString("baFooz foo bar") << 1 << 7 << (int) Qt::CaseSensitive;
- QTest::newRow("insensitive") << QString("foo") << QString("baFooz foo bar") << 1 << 2 << (int) Qt::CaseInsensitive;
-}
-
-void tst_QStringMatcher::setCaseSensitivity()
-{
- QFETCH(QString, needle);
- QFETCH(QString, haystack);
- QFETCH(int, from);
- QFETCH(int, indexIn);
- QFETCH(int, cs);
-
- QStringMatcher matcher;
- matcher.setPattern(needle);
- matcher.setCaseSensitivity(static_cast<Qt::CaseSensitivity> (cs));
-
- QCOMPARE(matcher.indexIn(haystack, from), indexIn);
-}
-
-void tst_QStringMatcher::assignOperator()
-{
- QString needle("d");
- QString hayStack("abcdef");
- QStringMatcher m1(needle);
- QCOMPARE(m1.indexIn(hayStack), 3);
-
- QStringMatcher m2 = m1;
- QCOMPARE(m2.pattern(), needle);
- QCOMPARE(m2.indexIn(hayStack), 3);
-}
-
-QTEST_MAIN(tst_QStringMatcher)
-#include "tst_qstringmatcher.moc"
-
diff --git a/tests/auto/corelib/tools/qstringref/qstringref.pro b/tests/auto/corelib/tools/qstringref/qstringref.pro
deleted file mode 100644
index 04f3ba6a92..0000000000
--- a/tests/auto/corelib/tools/qstringref/qstringref.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringref
-QT = core testlib
-SOURCES = tst_qstringref.cpp
diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp
deleted file mode 100644
index 581e9152e6..0000000000
--- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp
+++ /dev/null
@@ -1,2158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qstringlist.h>
-#include <qvariant.h>
-
-#include <qlocale.h>
-#include <locale.h>
-
-
-class tst_QStringRef : public QObject
-{
- Q_OBJECT
-public slots:
- void cleanup();
-private slots:
- void at();
- void endsWith();
- void startsWith();
- void contains();
- void count();
- void lastIndexOf_data();
- void lastIndexOf();
- void indexOf_data();
- void indexOf();
- void indexOf2_data();
- void indexOf2();
- void iteration();
- void length_data();
- void length();
- void isEmpty();
- void compare_data();
- void compare();
- void compare2_data();
- void compare2();
- void operator_eqeq_nullstring();
- void toNum();
- void toDouble_data();
- void toDouble();
- void toFloat();
- void toLong_data();
- void toLong();
- void toULong_data();
- void toULong();
- void toLongLong();
- void toULongLong();
- void toUInt();
- void toInt();
- void toShort();
- void toUShort();
- void double_conversion_data();
- void double_conversion();
- void integer_conversion_data();
- void integer_conversion();
- void trimmed();
- void truncate();
- void chop();
- void left();
- void right();
- void mid();
- void split_data();
- void split();
-};
-
-static QStringRef emptyRef()
-{
- static const QString empty("");
- return empty.midRef(0);
-}
-
-#define CREATE_REF(string) \
- const QString padded = QLatin1Char(' ') + string + QLatin1Char(' '); \
- QStringRef ref = padded.midRef(1, padded.size() - 2);
-
-typedef QList<int> IntList;
-
-// This next bit is needed for the NAN and INF in string -> number conversion tests
-#include <float.h>
-#include <limits.h>
-#include <math.h>
-#if defined(Q_OS_WIN)
-# include <windows.h>
-// mingw defines NAN and INFINITY to 0/0 and x/0
-# if defined(Q_CC_GNU)
-# undef NAN
-# undef INFINITY
-# else
-# define isnan(d) _isnan(d)
-# endif
-#endif
-#if defined(Q_OS_MAC) && !defined isnan
-#define isnan(d) __isnand(d)
-#endif
-#if defined(Q_OS_SOLARIS)
-# include <ieeefp.h>
-#endif
-
-enum {
- LittleEndian,
- BigEndian
-#ifdef Q_BYTE_ORDER
-# if Q_BYTE_ORDER == Q_BIG_ENDIAN
- , ByteOrder = BigEndian
-# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- , ByteOrder = LittleEndian
-# else
-# error "undefined byte order"
-# endif
-};
-#else
-};
-static const unsigned int one = 1;
-static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian);
-#endif
-#if !defined(INFINITY)
-static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0,0 };
-static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
-static inline double inf()
-{
- if (ByteOrder == BigEndian)
- return *reinterpret_cast<const double *>(be_inf_bytes);
- return *reinterpret_cast<const double *>(le_inf_bytes);
-}
-# define INFINITY (::inf())
-#endif
-#if !defined(NAN)
-static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0,0 };
-static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
-static inline double nan()
-{
- if (ByteOrder == BigEndian)
- return *reinterpret_cast<const double *>(be_nan_bytes);
- return *reinterpret_cast<const double *>(le_nan_bytes);
-}
-# define NAN (::nan())
-#endif
-
-void tst_QStringRef::cleanup()
-{
- QLocale::setDefault(QString(QLatin1Char('C')));
-}
-
-void tst_QStringRef::at()
-{
- const QString hw = QStringLiteral("Hello World");
- const QStringRef ref = hw.midRef(6);
- QCOMPARE(ref.at(0), QChar('W'));
- QCOMPARE(ref.at(4), QChar('d'));
- QCOMPARE(ref[0], QChar('W'));
- QCOMPARE(ref[4], QChar('d'));
-}
-
-void tst_QStringRef::length_data()
-{
- QTest::addColumn<QString>("s1");
- QTest::addColumn<int>("res");
-
- QTest::newRow("data0") << QString("Test") << 4;
- QTest::newRow("data1") << QString("The quick brown fox jumps over the lazy dog") << 43;
- QTest::newRow("data2") << QString() << 0;
- QTest::newRow("data3") << QString("A") << 1;
- QTest::newRow("data4") << QString("AB") << 2;
- QTest::newRow("data5") << QString("AB\n") << 3;
- QTest::newRow("data6") << QString("AB\nC") << 4;
- QTest::newRow("data7") << QString("\n") << 1;
- QTest::newRow("data8") << QString("\nA") << 2;
- QTest::newRow("data9") << QString("\nAB") << 3;
- QTest::newRow("data10") << QString("\nAB\nCDE") << 7;
- QTest::newRow("data11") << QString("shdnftrheid fhgnt gjvnfmd chfugkh bnfhg thgjf vnghturkf chfnguh bjgnfhvygh hnbhgutjfv dhdnjds dcjs d") << 100;
- QTest::newRow("data12") << QString("") << 0;
-}
-
-
-void tst_QStringRef::length()
-{
- QFETCH(QString, s1);
- CREATE_REF(s1);
- QTEST(ref.length(), "res");
-}
-
-
-void tst_QStringRef::isEmpty()
-{
- QStringRef a;
- QVERIFY(a.isEmpty());
- QVERIFY(emptyRef().isEmpty());
- CREATE_REF("Not empty");
- QVERIFY(!ref.isEmpty());
-}
-
-void tst_QStringRef::indexOf_data()
-{
- QTest::addColumn<QString>("haystack");
- QTest::addColumn<QString>("needle");
- QTest::addColumn<int>("startpos");
- QTest::addColumn<bool>("bcs");
- QTest::addColumn<int>("resultpos");
-
- QTest::newRow("data0") << QString("abc") << QString("a") << 0 << true << 0;
- QTest::newRow("data1") << QString("abc") << QString("a") << 0 << false << 0;
- QTest::newRow("data2") << QString("abc") << QString("A") << 0 << true << -1;
- QTest::newRow("data3") << QString("abc") << QString("A") << 0 << false << 0;
- QTest::newRow("data4") << QString("abc") << QString("a") << 1 << true << -1;
- QTest::newRow("data5") << QString("abc") << QString("a") << 1 << false << -1;
- QTest::newRow("data6") << QString("abc") << QString("A") << 1 << true << -1;
- QTest::newRow("data7") << QString("abc") << QString("A") << 1 << false << -1;
- QTest::newRow("data8") << QString("abc") << QString("b") << 0 << true << 1;
- QTest::newRow("data9") << QString("abc") << QString("b") << 0 << false << 1;
- QTest::newRow("data10") << QString("abc") << QString("B") << 0 << true << -1;
- QTest::newRow("data11") << QString("abc") << QString("B") << 0 << false << 1;
- QTest::newRow("data12") << QString("abc") << QString("b") << 1 << true << 1;
- QTest::newRow("data13") << QString("abc") << QString("b") << 1 << false << 1;
- QTest::newRow("data14") << QString("abc") << QString("B") << 1 << true << -1;
- QTest::newRow("data15") << QString("abc") << QString("B") << 1 << false << 1;
- QTest::newRow("data16") << QString("abc") << QString("b") << 2 << true << -1;
- QTest::newRow("data17") << QString("abc") << QString("b") << 2 << false << -1;
-
- QTest::newRow("data20") << QString("ABC") << QString("A") << 0 << true << 0;
- QTest::newRow("data21") << QString("ABC") << QString("A") << 0 << false << 0;
- QTest::newRow("data22") << QString("ABC") << QString("a") << 0 << true << -1;
- QTest::newRow("data23") << QString("ABC") << QString("a") << 0 << false << 0;
- QTest::newRow("data24") << QString("ABC") << QString("A") << 1 << true << -1;
- QTest::newRow("data25") << QString("ABC") << QString("A") << 1 << false << -1;
- QTest::newRow("data26") << QString("ABC") << QString("a") << 1 << true << -1;
- QTest::newRow("data27") << QString("ABC") << QString("a") << 1 << false << -1;
- QTest::newRow("data28") << QString("ABC") << QString("B") << 0 << true << 1;
- QTest::newRow("data29") << QString("ABC") << QString("B") << 0 << false << 1;
- QTest::newRow("data30") << QString("ABC") << QString("b") << 0 << true << -1;
- QTest::newRow("data31") << QString("ABC") << QString("b") << 0 << false << 1;
- QTest::newRow("data32") << QString("ABC") << QString("B") << 1 << true << 1;
- QTest::newRow("data33") << QString("ABC") << QString("B") << 1 << false << 1;
- QTest::newRow("data34") << QString("ABC") << QString("b") << 1 << true << -1;
- QTest::newRow("data35") << QString("ABC") << QString("b") << 1 << false << 1;
- QTest::newRow("data36") << QString("ABC") << QString("B") << 2 << true << -1;
- QTest::newRow("data37") << QString("ABC") << QString("B") << 2 << false << -1;
-
- QTest::newRow("data40") << QString("aBc") << QString("bc") << 0 << true << -1;
- QTest::newRow("data41") << QString("aBc") << QString("Bc") << 0 << true << 1;
- QTest::newRow("data42") << QString("aBc") << QString("bC") << 0 << true << -1;
- QTest::newRow("data43") << QString("aBc") << QString("BC") << 0 << true << -1;
- QTest::newRow("data44") << QString("aBc") << QString("bc") << 0 << false << 1;
- QTest::newRow("data45") << QString("aBc") << QString("Bc") << 0 << false << 1;
- QTest::newRow("data46") << QString("aBc") << QString("bC") << 0 << false << 1;
- QTest::newRow("data47") << QString("aBc") << QString("BC") << 0 << false << 1;
- QTest::newRow("data48") << QString("AbC") << QString("bc") << 0 << true << -1;
- QTest::newRow("data49") << QString("AbC") << QString("Bc") << 0 << true << -1;
- QTest::newRow("data50") << QString("AbC") << QString("bC") << 0 << true << 1;
- QTest::newRow("data51") << QString("AbC") << QString("BC") << 0 << true << -1;
- QTest::newRow("data52") << QString("AbC") << QString("bc") << 0 << false << 1;
- QTest::newRow("data53") << QString("AbC") << QString("Bc") << 0 << false << 1;
-
- QTest::newRow("data54") << QString("AbC") << QString("bC") << 0 << false << 1;
- QTest::newRow("data55") << QString("AbC") << QString("BC") << 0 << false << 1;
- QTest::newRow("data56") << QString("AbC") << QString("BC") << 1 << false << 1;
- QTest::newRow("data57") << QString("AbC") << QString("BC") << 2 << false << -1;
-#if 0
- QTest::newRow("null-in-null") << QString() << QString() << 0 << false << 0;
- QTest::newRow("empty-in-null") << QString() << QString("") << 0 << false << 0;
- QTest::newRow("null-in-empty") << QString("") << QString() << 0 << false << 0;
- QTest::newRow("empty-in-empty") << QString("") << QString("") << 0 << false << 0;
-#endif
-
-
- QString s1 = "abc";
- s1 += QChar(0xb5);
- QString s2;
- s2 += QChar(0x3bc);
- QTest::newRow("data58") << QString(s1) << QString(s2) << 0 << false << 3;
- s2.prepend(QLatin1Char('C'));
- QTest::newRow("data59") << QString(s1) << QString(s2) << 0 << false << 2;
-
- QString veryBigHaystack(500, 'a');
- veryBigHaystack += 'B';
- QTest::newRow("BoyerMooreStressTest") << veryBigHaystack << veryBigHaystack << 0 << true << 0;
- QTest::newRow("BoyerMooreStressTest2") << veryBigHaystack + 'c' << veryBigHaystack << 0 << true << 0;
- QTest::newRow("BoyerMooreStressTest3") << 'c' + veryBigHaystack << veryBigHaystack << 0 << true << 1;
- QTest::newRow("BoyerMooreStressTest4") << veryBigHaystack << veryBigHaystack + 'c' << 0 << true << -1;
- QTest::newRow("BoyerMooreStressTest5") << veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1;
- QTest::newRow("BoyerMooreStressTest6") << 'd' + veryBigHaystack << 'c' + veryBigHaystack << 0 << true << -1;
- QTest::newRow("BoyerMooreStressTest7") << veryBigHaystack + 'c' << 'c' + veryBigHaystack << 0 << true << -1;
-
- QTest::newRow("BoyerMooreInsensitiveStressTest") << veryBigHaystack << veryBigHaystack << 0 << false << 0;
-
-}
-
-void tst_QStringRef::indexOf()
-{
- QFETCH(QString, haystack);
- QFETCH(QString, needle);
- QFETCH(int, startpos);
- QFETCH(bool, bcs);
- QFETCH(int, resultpos);
-
- const QString haystackPadded = QLatin1Char(' ') + haystack + QLatin1Char(' ');
- const QString needlePadded = QLatin1Char(' ') + needle + QLatin1Char(' ');
- const QStringRef haystackRef(&haystackPadded, 1, haystack.size());
- const QStringRef needleRef(&needlePadded, 1, needle.size());
-
- Qt::CaseSensitivity cs = bcs ? Qt::CaseSensitive : Qt::CaseInsensitive;
-
- QCOMPARE(haystack.indexOf(needle, startpos, cs), resultpos);
- QCOMPARE(haystackRef.indexOf(needle, startpos, cs), resultpos);
- QCOMPARE(haystackRef.indexOf(needleRef, startpos, cs), resultpos);
- QCOMPARE(haystack.indexOf(needleRef, startpos, cs), resultpos);
-
- if (cs == Qt::CaseSensitive) {
- QCOMPARE(haystack.indexOf(needle, startpos), resultpos);
- QCOMPARE(haystackRef.indexOf(needle, startpos), resultpos);
- QCOMPARE(haystackRef.indexOf(needleRef, startpos), resultpos);
- QCOMPARE(haystack.indexOf(needleRef, startpos), resultpos);
- if (startpos == 0) {
- QCOMPARE(haystack.indexOf(needle), resultpos);
- QCOMPARE(haystackRef.indexOf(needle), resultpos);
- QCOMPARE(haystackRef.indexOf(needleRef), resultpos);
- QCOMPARE(haystack.indexOf(needleRef), resultpos);
- }
- }
- if (needle.size() == 1) {
- QCOMPARE(needle.at(0), needleRef.at(0));
- QCOMPARE(haystack.indexOf(needleRef.at(0), startpos, cs), resultpos);
- QCOMPARE(haystackRef.indexOf(needle.at(0), startpos, cs), resultpos);
- QCOMPARE(haystackRef.indexOf(needleRef.at(0), startpos, cs), resultpos);
- QCOMPARE(haystack.indexOf(needleRef.at(0), startpos ,cs), resultpos);
- }
-}
-
-void tst_QStringRef::indexOf2_data()
-{
- QTest::addColumn<QString>("haystack");
- QTest::addColumn<QString>("needle");
- QTest::addColumn<int>("resultpos");
-
- QTest::newRow("data0") << QString() << QString() << 0;
- QTest::newRow("data1") << QString() << QString("") << 0;
- QTest::newRow("data2") << QString("") << QString() << 0;
- QTest::newRow("data3") << QString("") << QString("") << 0;
- QTest::newRow("data4") << QString() << QString("a") << -1;
- QTest::newRow("data5") << QString() << QString("abcdefg") << -1;
- QTest::newRow("data6") << QString("") << QString("a") << -1;
- QTest::newRow("data7") << QString("") << QString("abcdefg") << -1;
-
- QTest::newRow("data8") << QString("a") << QString() << 0;
- QTest::newRow("data9") << QString("a") << QString("") << 0;
- QTest::newRow("data10") << QString("a") << QString("a") << 0;
- QTest::newRow("data11") << QString("a") << QString("b") << -1;
- QTest::newRow("data12") << QString("a") << QString("abcdefg") << -1;
- QTest::newRow("data13") << QString("ab") << QString() << 0;
- QTest::newRow("data14") << QString("ab") << QString("") << 0;
- QTest::newRow("data15") << QString("ab") << QString("a") << 0;
- QTest::newRow("data16") << QString("ab") << QString("b") << 1;
- QTest::newRow("data17") << QString("ab") << QString("ab") << 0;
- QTest::newRow("data18") << QString("ab") << QString("bc") << -1;
- QTest::newRow("data19") << QString("ab") << QString("abcdefg") << -1;
-
- QTest::newRow("data30") << QString("abc") << QString("a") << 0;
- QTest::newRow("data31") << QString("abc") << QString("b") << 1;
- QTest::newRow("data32") << QString("abc") << QString("c") << 2;
- QTest::newRow("data33") << QString("abc") << QString("d") << -1;
- QTest::newRow("data34") << QString("abc") << QString("ab") << 0;
- QTest::newRow("data35") << QString("abc") << QString("bc") << 1;
- QTest::newRow("data36") << QString("abc") << QString("cd") << -1;
- QTest::newRow("data37") << QString("abc") << QString("ac") << -1;
-
- // sizeof(whale) > 32
- QString whale = "a5zby6cx7dw8evf9ug0th1si2rj3qkp4lomn";
- QString minnow = "zby";
- QTest::newRow("data40") << whale << minnow << 2;
- QTest::newRow("data41") << (whale + whale) << minnow << 2;
- QTest::newRow("data42") << (minnow + whale) << minnow << 0;
- QTest::newRow("data43") << whale << whale << 0;
- QTest::newRow("data44") << (whale + whale) << whale << 0;
- QTest::newRow("data45") << whale << (whale + whale) << -1;
- QTest::newRow("data46") << (whale + whale) << (whale + whale) << 0;
- QTest::newRow("data47") << (whale + whale) << (whale + minnow) << -1;
- QTest::newRow("data48") << (minnow + whale) << whale << (int)minnow.length();
-}
-
-void tst_QStringRef::indexOf2()
-{
- QFETCH(QString, haystack);
- QFETCH(QString, needle);
- QFETCH(int, resultpos);
-
- const QString haystackPadded = QLatin1Char(' ') + haystack + QLatin1Char(' ');
- const QString needlePadded = QLatin1Char(' ') + needle + QLatin1Char(' ');
- const QStringRef haystackRef(&haystackPadded, 1, haystack.size());
- const QStringRef needleRef(&needlePadded, 1, needle.size());
-
-
- int got;
-
- QCOMPARE(haystack.indexOf(needleRef, 0, Qt::CaseSensitive), resultpos);
- QCOMPARE(haystackRef.indexOf(needle, 0, Qt::CaseSensitive), resultpos);
- QCOMPARE(haystackRef.indexOf(needleRef, 0, Qt::CaseSensitive), resultpos);
- QCOMPARE(haystack.indexOf(needleRef, 0, Qt::CaseInsensitive), resultpos);
- QCOMPARE(haystackRef.indexOf(needle, 0, Qt::CaseInsensitive), resultpos);
- QCOMPARE(haystackRef.indexOf(needleRef, 0, Qt::CaseInsensitive), resultpos);
- if (needle.length() > 0) {
- got = haystackRef.lastIndexOf(needle, -1, Qt::CaseSensitive);
- QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos));
- got = haystackRef.lastIndexOf(needle, -1, Qt::CaseInsensitive);
- QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos));
-
- got = haystack.lastIndexOf(needleRef, -1, Qt::CaseSensitive);
- QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos));
- got = haystack.lastIndexOf(needleRef, -1, Qt::CaseInsensitive);
- QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos));
-
- got = haystackRef.lastIndexOf(needleRef, -1, Qt::CaseSensitive);
- QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos));
- got = haystackRef.lastIndexOf(needleRef, -1, Qt::CaseInsensitive);
- QVERIFY(got == resultpos || (resultpos >= 0 && got >= resultpos));
- }
-}
-
-void tst_QStringRef::iteration()
-{
- QString hello = "Hello";
- QString olleh = "olleH";
-
- QStringRef ref(&hello);
- QStringRef rref(&olleh);
-
- const QStringRef &cref = ref;
- const QStringRef &crref = rref;
-
- QVERIFY(std::equal( ref.begin(), ref.end(), hello.begin()));
- QVERIFY(std::equal( rref.begin(), rref.end(), olleh.begin()));
- QVERIFY(std::equal( cref.begin(), cref.end(), hello.begin()));
- QVERIFY(std::equal(crref.begin(), crref.end(), olleh.begin()));
-
- QVERIFY(std::equal( ref.cbegin(), ref.cend(), hello.begin()));
- QVERIFY(std::equal( rref.cbegin(), rref.cend(), olleh.begin()));
- QVERIFY(std::equal( cref.cbegin(), cref.cend(), hello.begin()));
- QVERIFY(std::equal(crref.cbegin(), crref.cend(), olleh.begin()));
-
- QVERIFY(std::equal( ref.rbegin(), ref.rend(), hello.rbegin()));
- QVERIFY(std::equal( rref.rbegin(), rref.rend(), olleh.rbegin()));
- QVERIFY(std::equal( cref.rbegin(), cref.rend(), hello.rbegin()));
- QVERIFY(std::equal(crref.rbegin(), crref.rend(), olleh.rbegin()));
-
- QVERIFY(std::equal( ref.crbegin(), ref.crend(), hello.rbegin()));
- QVERIFY(std::equal( rref.crbegin(), rref.crend(), olleh.rbegin()));
- QVERIFY(std::equal( cref.crbegin(), cref.crend(), hello.rbegin()));
- QVERIFY(std::equal(crref.crbegin(), crref.crend(), olleh.rbegin()));
-}
-
-void tst_QStringRef::lastIndexOf_data()
-{
- QTest::addColumn<QString>("haystack");
- QTest::addColumn<QString>("needle");
- QTest::addColumn<int>("from");
- QTest::addColumn<int>("expected");
- QTest::addColumn<bool>("caseSensitive");
-
- QString a = "ABCDEFGHIEfGEFG";
-
- QTest::newRow("-1") << a << "G" << a.size() - 1 << 14 << true;
- QTest::newRow("1") << a << "G" << - 1 << 14 << true;
- QTest::newRow("2") << a << "G" << -3 << 11 << true;
- QTest::newRow("3") << a << "G" << -5 << 6 << true;
- QTest::newRow("4") << a << "G" << 14 << 14 << true;
- QTest::newRow("5") << a << "G" << 13 << 11 << true;
- QTest::newRow("6") << a << "B" << a.size() - 1 << 1 << true;
- QTest::newRow("7") << a << "B" << - 1 << 1 << true;
- QTest::newRow("8") << a << "B" << 1 << 1 << true;
- QTest::newRow("9") << a << "B" << 0 << -1 << true;
-
- QTest::newRow("10") << a << "G" << -1 << a.size()-1 << true;
- QTest::newRow("11") << a << "G" << a.size()-1 << a.size()-1 << true;
- QTest::newRow("12") << a << "G" << a.size() << -1 << true;
- QTest::newRow("13") << a << "A" << 0 << 0 << true;
- QTest::newRow("14") << a << "A" << -1*a.size() << 0 << true;
-
- QTest::newRow("15") << a << "efg" << 0 << -1 << false;
- QTest::newRow("16") << a << "efg" << a.size() << -1 << false;
- QTest::newRow("17") << a << "efg" << -1 * a.size() << -1 << false;
- QTest::newRow("19") << a << "efg" << a.size() - 1 << 12 << false;
- QTest::newRow("20") << a << "efg" << 12 << 12 << false;
- QTest::newRow("21") << a << "efg" << -12 << -1 << false;
- QTest::newRow("22") << a << "efg" << 11 << 9 << false;
-
- QTest::newRow("24") << "" << "asdf" << -1 << -1 << false;
- QTest::newRow("25") << "asd" << "asdf" << -1 << -1 << false;
- QTest::newRow("26") << "" << QString() << -1 << -1 << false;
-
- QTest::newRow("27") << a << "" << a.size() << a.size() << false;
- QTest::newRow("28") << a << "" << a.size() + 10 << -1 << false;
-}
-
-void tst_QStringRef::lastIndexOf()
-{
- QFETCH(QString, haystack);
- QFETCH(QString, needle);
- QFETCH(int, from);
- QFETCH(int, expected);
- QFETCH(bool, caseSensitive);
-
- const QString haystackPadded = QLatin1Char(' ') + haystack + QLatin1Char(' ');
- const QString needlePadded = QLatin1Char(' ') + needle + QLatin1Char(' ');
- const QStringRef haystackRef(&haystackPadded, 1, haystack.size());
- const QStringRef needleRef(&needlePadded, 1, needle.size());
-
- Qt::CaseSensitivity cs = (caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
-
- QCOMPARE(haystack.lastIndexOf(needleRef, from, cs), expected);
- QCOMPARE(haystackRef.lastIndexOf(needle, from, cs), expected);
- QCOMPARE(haystackRef.lastIndexOf(needleRef, from, cs), expected);
-
-
- if (cs == Qt::CaseSensitive) {
- QCOMPARE(haystack.lastIndexOf(needleRef, from), expected);
- QCOMPARE(haystackRef.lastIndexOf(needle, from), expected);
- QCOMPARE(haystackRef.lastIndexOf(needleRef, from), expected);
-
- if (from == -1) {
- QCOMPARE(haystack.lastIndexOf(needleRef), expected);
- QCOMPARE(haystackRef.lastIndexOf(needle), expected);
- QCOMPARE(haystackRef.lastIndexOf(needleRef), expected);
-
- }
- }
- if (needle.size() == 1) {
- QCOMPARE(haystack.lastIndexOf(needleRef.at(0), from), expected);
- QCOMPARE(haystackRef.lastIndexOf(needle.at(0), from), expected);
- QCOMPARE(haystackRef.lastIndexOf(needleRef.at(0), from), expected);
- }
-}
-
-void tst_QStringRef::count()
-{
- const QString a = QString::fromLatin1("ABCDEFGHIEfGEFG"); // 15 chars
- CREATE_REF(a);
- QCOMPARE(ref.count('A'),1);
- QCOMPARE(ref.count('Z'),0);
- QCOMPARE(ref.count('E'),3);
- QCOMPARE(ref.count('F'),2);
- QCOMPARE(ref.count('F',Qt::CaseInsensitive),3);
- QCOMPARE(ref.count("FG"),2);
- QCOMPARE(ref.count("FG",Qt::CaseInsensitive),3);
- QCOMPARE(ref.count(QString(), Qt::CaseInsensitive), 16);
- QCOMPARE(ref.count("", Qt::CaseInsensitive), 16);
-}
-
-void tst_QStringRef::contains()
-{
- const QString a = QString::fromLatin1("ABCDEFGHIEfGEFG"); // 15 chars
- CREATE_REF(a);
- QVERIFY(ref.contains('A'));
- QVERIFY(!ref.contains('Z'));
- QVERIFY(ref.contains('E'));
- QVERIFY(ref.contains('F'));
- QVERIFY(ref.contains('F',Qt::CaseInsensitive));
- QVERIFY(ref.contains("FG"));
- QVERIFY(ref.contains(QString("FG").midRef(0)));
- const QString ref2 = QString::fromLatin1(" FG ");
- QVERIFY(ref.contains(ref2.midRef(1, 2),Qt::CaseInsensitive));
- QVERIFY(ref.contains(QString(), Qt::CaseInsensitive));
- QVERIFY(ref.contains("", Qt::CaseInsensitive)); // apparently
-}
-
-void tst_QStringRef::startsWith()
-{
- {
- const QString a = QString::fromLatin1("AB");
- CREATE_REF(a);
- QVERIFY(ref.startsWith("A"));
- QVERIFY(ref.startsWith("AB"));
- QVERIFY(!ref.startsWith("C"));
- QVERIFY(!ref.startsWith("ABCDEF"));
- QVERIFY(ref.startsWith(""));
- QVERIFY(ref.startsWith(QString::null));
- QVERIFY(ref.startsWith('A'));
- QVERIFY(ref.startsWith(QLatin1Char('A')));
- QVERIFY(ref.startsWith(QChar('A')));
- QVERIFY(!ref.startsWith('C'));
- QVERIFY(!ref.startsWith(QChar()));
- QVERIFY(!ref.startsWith(QLatin1Char(0)));
-
- QVERIFY(ref.startsWith(QLatin1String("A")));
- QVERIFY(ref.startsWith(QLatin1String("AB")));
- QVERIFY(!ref.startsWith(QLatin1String("C")));
- QVERIFY(!ref.startsWith(QLatin1String("ABCDEF")));
- QVERIFY(ref.startsWith(QLatin1String("")));
- QVERIFY(ref.startsWith(QLatin1String(0)));
-
- QVERIFY(ref.startsWith("A", Qt::CaseSensitive));
- QVERIFY(ref.startsWith("A", Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith("a", Qt::CaseSensitive));
- QVERIFY(ref.startsWith("a", Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith("aB", Qt::CaseSensitive));
- QVERIFY(ref.startsWith("aB", Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith("C", Qt::CaseSensitive));
- QVERIFY(!ref.startsWith("C", Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith("c", Qt::CaseSensitive));
- QVERIFY(!ref.startsWith("c", Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith("abcdef", Qt::CaseInsensitive));
- QVERIFY(ref.startsWith("", Qt::CaseInsensitive));
- QVERIFY(ref.startsWith(QString::null, Qt::CaseInsensitive));
- QVERIFY(ref.startsWith('a', Qt::CaseInsensitive));
- QVERIFY(ref.startsWith('A', Qt::CaseInsensitive));
- QVERIFY(ref.startsWith(QLatin1Char('a'), Qt::CaseInsensitive));
- QVERIFY(ref.startsWith(QChar('a'), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith('c', Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QChar(), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QLatin1Char(0), Qt::CaseInsensitive));
-
- QVERIFY(ref.startsWith(QLatin1String("A"), Qt::CaseSensitive));
- QVERIFY(ref.startsWith(QLatin1String("A"), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QLatin1String("a"), Qt::CaseSensitive));
- QVERIFY(ref.startsWith(QLatin1String("a"), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QLatin1String("aB"), Qt::CaseSensitive));
- QVERIFY(ref.startsWith(QLatin1String("aB"), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QLatin1String("C"), Qt::CaseSensitive));
- QVERIFY(!ref.startsWith(QLatin1String("C"), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QLatin1String("c"), Qt::CaseSensitive));
- QVERIFY(!ref.startsWith(QLatin1String("c"), Qt::CaseInsensitive));
- QVERIFY(!ref.startsWith(QLatin1String("abcdef"), Qt::CaseInsensitive));
- QVERIFY(ref.startsWith(QLatin1String(""), Qt::CaseInsensitive));
- QVERIFY(ref.startsWith(QLatin1String(0), Qt::CaseInsensitive));
- QVERIFY(ref.startsWith('A', Qt::CaseSensitive));
- QVERIFY(ref.startsWith(QLatin1Char('A'), Qt::CaseSensitive));
- QVERIFY(ref.startsWith(QChar('A'), Qt::CaseSensitive));
- QVERIFY(!ref.startsWith('a', Qt::CaseSensitive));
- QVERIFY(!ref.startsWith(QChar(), Qt::CaseSensitive));
- QVERIFY(!ref.startsWith(QLatin1Char(0), Qt::CaseSensitive));
- }
- {
- const QString a = QString::fromLatin1("");
- CREATE_REF(a);
- QVERIFY(ref.startsWith(""));
- QVERIFY(ref.startsWith(QString::null));
- QVERIFY(!ref.startsWith("ABC"));
-
- QVERIFY(ref.startsWith(QLatin1String("")));
- QVERIFY(ref.startsWith(QLatin1String(0)));
- QVERIFY(!ref.startsWith(QLatin1String("ABC")));
-
- QVERIFY(!ref.startsWith(QLatin1Char(0)));
- QVERIFY(!ref.startsWith(QLatin1Char('x')));
- QVERIFY(!ref.startsWith(QChar()));
- }
- {
- const QStringRef ref;
- QVERIFY(!ref.startsWith(""));
- QVERIFY(ref.startsWith(QString::null));
- QVERIFY(!ref.startsWith("ABC"));
-
- QVERIFY(!ref.startsWith(QLatin1String("")));
- QVERIFY(ref.startsWith(QLatin1String(0)));
- QVERIFY(!ref.startsWith(QLatin1String("ABC")));
-
- QVERIFY(!ref.startsWith(QLatin1Char(0)));
- QVERIFY(!ref.startsWith(QLatin1Char('x')));
- QVERIFY(!ref.startsWith(QChar()));
- }
-}
-
-void tst_QStringRef::endsWith()
-{
- {
- const QString a = QString::fromLatin1("AB");
- CREATE_REF(a);
- QVERIFY(ref.endsWith("B"));
- QVERIFY(ref.endsWith("AB"));
- QVERIFY(!ref.endsWith("C"));
- QVERIFY(!ref.endsWith("ABCDEF"));
- QVERIFY(ref.endsWith(""));
- QVERIFY(ref.endsWith(QString::null));
- QVERIFY(ref.endsWith('B'));
- QVERIFY(ref.endsWith(QLatin1Char('B')));
- QVERIFY(ref.endsWith(QChar('B')));
- QVERIFY(!ref.endsWith('C'));
- QVERIFY(!ref.endsWith(QChar()));
- QVERIFY(!ref.endsWith(QLatin1Char(0)));
-
- QVERIFY(ref.endsWith(QLatin1String("B")));
- QVERIFY(ref.endsWith(QLatin1String("AB")));
- QVERIFY(!ref.endsWith(QLatin1String("C")));
- QVERIFY(!ref.endsWith(QLatin1String("ABCDEF")));
- QVERIFY(ref.endsWith(QLatin1String("")));
- QVERIFY(ref.endsWith(QLatin1String(0)));
-
- QVERIFY(ref.endsWith("B", Qt::CaseSensitive));
- QVERIFY(ref.endsWith("B", Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith("b", Qt::CaseSensitive));
- QVERIFY(ref.endsWith("b", Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith("aB", Qt::CaseSensitive));
- QVERIFY(ref.endsWith("aB", Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith("C", Qt::CaseSensitive));
- QVERIFY(!ref.endsWith("C", Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith("c", Qt::CaseSensitive));
- QVERIFY(!ref.endsWith("c", Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith("abcdef", Qt::CaseInsensitive));
- QVERIFY(ref.endsWith("", Qt::CaseInsensitive));
- QVERIFY(ref.endsWith(QString::null, Qt::CaseInsensitive));
- QVERIFY(ref.endsWith('b', Qt::CaseInsensitive));
- QVERIFY(ref.endsWith('B', Qt::CaseInsensitive));
- QVERIFY(ref.endsWith(QLatin1Char('b'), Qt::CaseInsensitive));
- QVERIFY(ref.endsWith(QChar('b'), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith('c', Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QChar(), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QLatin1Char(0), Qt::CaseInsensitive));
-
- QVERIFY(ref.endsWith(QLatin1String("B"), Qt::CaseSensitive));
- QVERIFY(ref.endsWith(QLatin1String("B"), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QLatin1String("b"), Qt::CaseSensitive));
- QVERIFY(ref.endsWith(QLatin1String("b"), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QLatin1String("aB"), Qt::CaseSensitive));
- QVERIFY(ref.endsWith(QLatin1String("aB"), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QLatin1String("C"), Qt::CaseSensitive));
- QVERIFY(!ref.endsWith(QLatin1String("C"), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QLatin1String("c"), Qt::CaseSensitive));
- QVERIFY(!ref.endsWith(QLatin1String("c"), Qt::CaseInsensitive));
- QVERIFY(!ref.endsWith(QLatin1String("abcdef"), Qt::CaseInsensitive));
- QVERIFY(ref.endsWith(QLatin1String(""), Qt::CaseInsensitive));
- QVERIFY(ref.endsWith(QLatin1String(0), Qt::CaseInsensitive));
- QVERIFY(ref.endsWith('B', Qt::CaseSensitive));
- QVERIFY(ref.endsWith(QLatin1Char('B'), Qt::CaseSensitive));
- QVERIFY(ref.endsWith(QChar('B'), Qt::CaseSensitive));
- QVERIFY(!ref.endsWith('b', Qt::CaseSensitive));
- QVERIFY(!ref.endsWith(QChar(), Qt::CaseSensitive));
- QVERIFY(!ref.endsWith(QLatin1Char(0), Qt::CaseSensitive));
-
- }
- {
- const QString a = QString::fromLatin1("");
- CREATE_REF(a);
- QVERIFY(ref.endsWith(""));
- QVERIFY(ref.endsWith(QString::null));
- QVERIFY(!ref.endsWith("ABC"));
- QVERIFY(!ref.endsWith(QLatin1Char(0)));
- QVERIFY(!ref.endsWith(QLatin1Char('x')));
- QVERIFY(!ref.endsWith(QChar()));
-
- QVERIFY(ref.endsWith(QLatin1String("")));
- QVERIFY(ref.endsWith(QLatin1String(0)));
- QVERIFY(!ref.endsWith(QLatin1String("ABC")));
- }
-
- {
- QStringRef ref;
- QVERIFY(!ref.endsWith(""));
- QVERIFY(ref.endsWith(QString::null));
- QVERIFY(!ref.endsWith("ABC"));
-
- QVERIFY(!ref.endsWith(QLatin1String("")));
- QVERIFY(ref.endsWith(QLatin1String(0)));
- QVERIFY(!ref.endsWith(QLatin1String("ABC")));
-
- QVERIFY(!ref.endsWith(QLatin1Char(0)));
- QVERIFY(!ref.endsWith(QLatin1Char('x')));
- QVERIFY(!ref.endsWith(QChar()));
- }
-}
-
-void tst_QStringRef::operator_eqeq_nullstring()
-{
- /* Some of these might not be all that logical but it's the behaviour we've had since 3.0.0
- so we should probably stick with it. */
-
- QVERIFY(QStringRef() == "");
- QVERIFY("" == QStringRef());
-
- QVERIFY(QString("") == "");
- QVERIFY("" == QString(""));
-
- QVERIFY(QStringRef().size() == 0);
-
- QVERIFY(QString("").size() == 0);
-
- QVERIFY(QStringRef() == QString(""));
- QVERIFY(QString("") == QString());
-}
-
-static inline int sign(int x)
-{
- return x == 0 ? 0 : (x < 0 ? -1 : 1);
-}
-
-void tst_QStringRef::compare_data()
-{
- QTest::addColumn<QString>("s1");
- QTest::addColumn<QString>("s2");
- QTest::addColumn<int>("csr"); // case sensitive result
- QTest::addColumn<int>("cir"); // case insensitive result
-
-
- // null strings
- QTest::newRow("data0") << QString("") << QString("") << 0 << 0;
- QTest::newRow("data1") << QString("a") << QString("") << 1 << 1;
- QTest::newRow("data2") << QString("") << QString("a") << -1 << -1;
-
- // equal length
- QTest::newRow("data3") << QString("abc") << QString("abc") << 0 << 0;
- QTest::newRow("data4") << QString("abC") << QString("abc") << -1 << 0;
- QTest::newRow("data5") << QString("abc") << QString("abC") << 1 << 0;
- QTest::newRow("data10") << QString("abcdefgh") << QString("abcdefgh") << 0 << 0;
- QTest::newRow("data11") << QString("abcdefgh") << QString("abCdefgh") << 1 << 0;
- QTest::newRow("data12") << QString("0123456789012345") << QString("0123456789012345") << 0 << 0;
- QTest::newRow("data13") << QString("0123556789012345") << QString("0123456789012345") << 1 << 1;
-
- // different length
- QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1;
- QTest::newRow("data7") << QString("abCdef") << QString("abc") << -1 << 1;
- QTest::newRow("data8") << QString("abc") << QString("abcdef") << -1 << -1;
- QTest::newRow("data14") << QString("abcdefgh") << QString("abcdefghi") << -1 << -1;
- QTest::newRow("data15") << QString("01234567890123456") << QString("0123456789012345") << 1 << 1;
-
- QString upper;
- upper += QChar(QChar::highSurrogate(0x10400));
- upper += QChar(QChar::lowSurrogate(0x10400));
- QString lower;
- lower += QChar(QChar::highSurrogate(0x10428));
- lower += QChar(QChar::lowSurrogate(0x10428));
- QTest::newRow("data9") << upper << lower << -1 << 0;
-}
-
-static bool isLatin(const QString &s)
-{
- for (int i = 0; i < s.length(); ++i)
- if (s.at(i).unicode() > 0xff)
- return false;
- return true;
-}
-
-void tst_QStringRef::compare()
-{
- QFETCH(QString, s1);
- QFETCH(QString, s2);
- QFETCH(int, csr);
- QFETCH(int, cir);
-
- QStringRef r1(&s1, 0, s1.length());
- QStringRef r2(&s2, 0, s2.length());
-
- QCOMPARE(sign(QString::compare(s1, s2)), csr);
- QCOMPARE(sign(QStringRef::compare(r1, r2)), csr);
- QCOMPARE(sign(s1.compare(s2)), csr);
- QCOMPARE(sign(s1.compare(r2)), csr);
- QCOMPARE(sign(r1.compare(r2)), csr);
-
- QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(s1.compare(r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(s1.compare(r2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir);
-
- QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QString::compare(s1, r2, Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir);
-
- if (!cir) {
- QCOMPARE(s1.toCaseFolded(), s2.toCaseFolded());
- }
-
- if (isLatin(s2)) {
- QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()))), csr);
- QCOMPARE(sign(QString::compare(s1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir);
- QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()))), csr);
- QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(s2.toLatin1()), Qt::CaseInsensitive)), cir);
- }
-
- if (isLatin(s1)) {
- QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2)), csr);
- QCOMPARE(sign(QString::compare(QLatin1String(s1.toLatin1()), s2, Qt::CaseInsensitive)), cir);
- }
-}
-
-void tst_QStringRef::compare2_data()
-{
- compare_data();
-}
-
-void tst_QStringRef::compare2()
-{
- QFETCH(QString, s1);
- QFETCH(QString, s2);
- QFETCH(int, csr);
- QFETCH(int, cir);
-
- // prepend and append data
- // we only use Latin1 here so isLatin1 still results true
- s1.prepend("xyz").append("zyx");
- s2.prepend("foobar").append("raboof");
-
- QStringRef r1(&s1, 3, s1.length() - 6);
- QStringRef r2(&s2, 6, s2.length() - 12);
-
- QCOMPARE(sign(QStringRef::compare(r1, r2)), csr);
- QCOMPARE(sign(r1.compare(r2)), csr);
-
- QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir);
-
- QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr);
- QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir);
-
- if (isLatin(s2)) {
- QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(r2.toLatin1()))), csr);
- QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(r2.toLatin1()), Qt::CaseInsensitive)), cir);
- }
-
- if (isLatin(s1)) {
- QCOMPARE(sign(QStringRef::compare(r2, QLatin1String(r1.toLatin1()))), -csr);
- QCOMPARE(sign(QStringRef::compare(r2, QLatin1String(r1.toLatin1()), Qt::CaseInsensitive)), -cir);
- }
-}
-
-void tst_QStringRef::toNum()
-{
-#define TEST_TO_INT(num, func, type) \
- a = #num; \
- b = a.leftRef(-1); \
- QCOMPARE(b.func(&ok), type(Q_INT64_C(num))); \
- QVERIFY2(ok, "Failed: num=" #num);
-
- QString a;
- QStringRef b;
- bool ok = false;
-
- TEST_TO_INT(0, toInt, int)
- TEST_TO_INT(-1, toInt, int)
- TEST_TO_INT(1, toInt, int)
- TEST_TO_INT(2147483647, toInt, int)
- TEST_TO_INT(-2147483648, toInt, int)
-
- TEST_TO_INT(0, toShort, short)
- TEST_TO_INT(-1, toShort, short)
- TEST_TO_INT(1, toShort, short)
- TEST_TO_INT(32767, toShort, short)
- TEST_TO_INT(-32768, toShort, short)
-
- TEST_TO_INT(0, toLong, long)
- TEST_TO_INT(-1, toLong, long)
- TEST_TO_INT(1, toLong, long)
- TEST_TO_INT(2147483647, toLong, long)
- TEST_TO_INT(-2147483648, toLong, long)
- TEST_TO_INT(0, toLongLong, (long long))
- TEST_TO_INT(-1, toLongLong, (long long))
- TEST_TO_INT(1, toLongLong, (long long))
- TEST_TO_INT(9223372036854775807, toLongLong, (long long))
- TEST_TO_INT(-9223372036854775807, toLongLong, (long long))
-
-#undef TEST_TO_INT
-
-#define TEST_TO_UINT(num, func, type) \
- a = #num; \
- b = a.leftRef(-1); \
- QCOMPARE(b.func(&ok), type(Q_UINT64_C(num))); \
- QVERIFY2(ok, "Failed: num=" #num);
-
- TEST_TO_UINT(0, toUInt, (unsigned int))
- TEST_TO_UINT(1, toUInt, (unsigned int))
- TEST_TO_UINT(4294967295, toUInt, (unsigned int))
-
- TEST_TO_UINT(0, toUShort, (unsigned short))
- TEST_TO_UINT(1, toUShort, (unsigned short))
- TEST_TO_UINT(65535, toUShort, (unsigned short))
-
- TEST_TO_UINT(0, toULong, (unsigned long))
- TEST_TO_UINT(1, toULong, (unsigned long))
- TEST_TO_UINT(4294967295, toULong, (unsigned long))
-
- TEST_TO_UINT(0, toULongLong, (unsigned long long))
- TEST_TO_UINT(1, toULongLong, (unsigned long long))
- TEST_TO_UINT(18446744073709551615, toULongLong, (unsigned long long))
-
-#undef TEST_TO_UINT
-
-#define TEST_BASE(str, base, num) \
- a = str; \
- b = a.leftRef(-1); \
- QCOMPARE(b.toInt(&ok,base), int(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toInt"); \
- QCOMPARE(b.toUInt(&ok, base), (unsigned int)(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toUInt"); \
- QCOMPARE(b.toShort(&ok, base), short(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toShort"); \
- QCOMPARE(b.toUShort(&ok, base), (unsigned short)(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toUShort"); \
- QCOMPARE(b.toLong(&ok, base), long(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toLong"); \
- QCOMPARE(b.toULong(&ok, base), (unsigned long)(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toULong"); \
- QCOMPARE(b.toLongLong(&ok, base), (long long)(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toLongLong"); \
- QCOMPARE(b.toULongLong(&ok, base), (unsigned long long)(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= " #base " num=" #num ", func=toULongLong");
-
- TEST_BASE("FF", 16, 255)
- TEST_BASE("0xFF", 16, 255)
- TEST_BASE("77", 8, 63)
- TEST_BASE("077", 8, 63)
-
- TEST_BASE("0xFF", 0, 255)
- TEST_BASE("077", 0, 63)
- TEST_BASE("255", 0, 255)
-
- TEST_BASE(" FF", 16, 255)
- TEST_BASE(" 0xFF", 16, 255)
- TEST_BASE(" 77", 8, 63)
- TEST_BASE(" 077", 8, 63)
-
- TEST_BASE(" 0xFF", 0, 255)
- TEST_BASE(" 077", 0, 63)
- TEST_BASE(" 255", 0, 255)
-
- TEST_BASE("\tFF\t", 16, 255)
- TEST_BASE("\t0xFF ", 16, 255)
- TEST_BASE(" 77 ", 8, 63)
- TEST_BASE("77 ", 8, 63)
-
-#undef TEST_BASE
-
-#define TEST_NEG_BASE(str, base, num) \
- a = str; \
- b = a.leftRef(-1); \
- QCOMPARE(b.toInt(&ok, base), int(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toInt"); \
- QCOMPARE(b.toShort(&ok,base), short(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toShort"); \
- QCOMPARE(b.toLong(&ok, base), long(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLong"); \
- QCOMPARE(b.toLongLong(&ok, base), (long long)(num)); \
- QVERIFY2(ok, "Failed: str=" #str " base= "#base " num=" #num ", func=toLongLong");
-
- TEST_NEG_BASE("-FE", 16, -254)
- TEST_NEG_BASE("-0xFE", 16, -254)
- TEST_NEG_BASE("-77", 8, -63)
- TEST_NEG_BASE("-077", 8, -63)
-
- TEST_NEG_BASE("-0xFE", 0, -254)
- TEST_NEG_BASE("-077", 0, -63)
- TEST_NEG_BASE("-254", 0, -254)
-
-#undef TEST_NEG_BASE
-
-#define TEST_DOUBLE(num, str) \
- a = str; \
- b = a.leftRef(-1); \
- QCOMPARE(b.toDouble(&ok), num); \
- QVERIFY(ok);
-
- TEST_DOUBLE(1.2345, "1.2345")
- TEST_DOUBLE(12.345, "1.2345e+01")
- TEST_DOUBLE(12.345, "1.2345E+01")
- TEST_DOUBLE(12345.6, "12345.6")
-
-#undef TEST_DOUBLE
-
-#define TEST_BAD(str, func) \
- a = str; \
- b = a.leftRef(-1); \
- b.func(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str " func=" #func);
-
- TEST_BAD("32768", toShort)
- TEST_BAD("-32769", toShort)
- TEST_BAD("65536", toUShort)
- TEST_BAD("2147483648", toInt)
- TEST_BAD("-2147483649", toInt)
- TEST_BAD("4294967296", toUInt)
- if (sizeof(long) == 4) {
- TEST_BAD("2147483648", toLong)
- TEST_BAD("-2147483649", toLong)
- TEST_BAD("4294967296", toULong)
- }
- TEST_BAD("9223372036854775808", toLongLong)
- TEST_BAD("-9223372036854775809", toLongLong)
- TEST_BAD("18446744073709551616", toULongLong)
- TEST_BAD("-1", toUShort)
- TEST_BAD("-1", toUInt)
- TEST_BAD("-1", toULong)
- TEST_BAD("-1", toULongLong)
-
-#undef TEST_BAD
-
-#define TEST_BAD_ALL(str) \
- a = str; \
- b = a.leftRef(-1); \
- b.toShort(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toUShort(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toInt(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toUInt(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toLong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toULong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toLongLong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toULongLong(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toFloat(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str); \
- b.toDouble(&ok); \
- QVERIFY2(!ok, "Failed: str=" #str);
-
- TEST_BAD_ALL((const char*)0);
- TEST_BAD_ALL("");
- TEST_BAD_ALL(" ");
- TEST_BAD_ALL(".");
- TEST_BAD_ALL("-");
- TEST_BAD_ALL("hello");
- TEST_BAD_ALL("1.2.3");
- TEST_BAD_ALL("0x0x0x");
- TEST_BAD_ALL("123-^~<");
- TEST_BAD_ALL("123ThisIsNotANumber");
-
-#undef TEST_BAD_ALL
-
- a = "FF";
- b = a.leftRef(-1);
- b.toULongLong(&ok, 10);
- QVERIFY(!ok);
-
- a = "FF";
- b = a.leftRef(-1);
- b.toULongLong(&ok, 0);
- QVERIFY(!ok);
-
-#ifdef QT_NO_FPU
- double d = 3.40282346638528e+38; // slightly off FLT_MAX when using hardfloats
-#else
- double d = 3.4028234663852886e+38; // FLT_MAX
-#endif
- QString::number(d, 'e', 17).leftRef(-1).toFloat(&ok);
- QVERIFY(ok);
- QString::number(d + 1e32, 'e', 17).leftRef(-1).toFloat(&ok);
- QVERIFY(!ok);
- a = QString::number(-d, 'e', 17).leftRef(-1).toFloat(&ok);
- QVERIFY(ok);
- QString::number(-d - 1e32, 'e', 17).leftRef(-1).toFloat(&ok);
- QVERIFY(!ok);
- QString::number(d + 1e32, 'e', 17).leftRef(-1).toDouble(&ok);
- QVERIFY(ok);
- QString::number(-d - 1e32, 'e', 17).leftRef(-1).toDouble(&ok);
- QVERIFY(ok);
-}
-
-void tst_QStringRef::toUShort()
-{
- QString a;
- QStringRef b;
- bool ok;
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "COMPARE";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "123";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(123));
- QCOMPARE(b.toUShort(&ok), ushort(123));
- QVERIFY(ok);
-
- a = "123A";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "1234567";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "aaa123aaa";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "aaa123";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "123aaa";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "32767";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(32767));
- QCOMPARE(b.toUShort(&ok), ushort(32767));
- QVERIFY(ok);
-
- a = "-32767";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "65535";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(65535));
- QCOMPARE(b.toUShort(&ok), ushort(65535));
- QVERIFY(ok);
-
- if (sizeof(short) == 2) {
- a = "65536";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
-
- a = "123456";
- b = a.leftRef(-1);
- QCOMPARE(b.toUShort(), ushort(0));
- QCOMPARE(b.toUShort(&ok), ushort(0));
- QVERIFY(!ok);
- }
-}
-
-void tst_QStringRef::toShort()
-{
- QString a;
- QStringRef b;
- bool ok;
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "COMPARE";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "123";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(123));
- QCOMPARE(b.toShort(&ok), short(123));
- QVERIFY(ok);
-
- a = "123A";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "1234567";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "aaa123aaa";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "aaa123";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "123aaa";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "32767";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(32767));
- QCOMPARE(b.toShort(&ok), short(32767));
- QVERIFY(ok);
-
- a = "-32767";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(-32767));
- QCOMPARE(b.toShort(&ok), short(-32767));
- QVERIFY(ok);
-
- a = "-32768";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(-32768));
- QCOMPARE(b.toShort(&ok), short(-32768));
- QVERIFY(ok);
-
- if (sizeof(short) == 2) {
- a = "32768";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
-
- a = "-32769";
- b = a.leftRef(-1);
- QCOMPARE(b.toShort(), short(0));
- QCOMPARE(b.toShort(&ok), short(0));
- QVERIFY(!ok);
- }
-}
-
-void tst_QStringRef::toInt()
-{
- QString a;
- QStringRef b;
- bool ok;
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "COMPARE";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "123";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 123);
- QCOMPARE(b.toInt(&ok), 123);
- QVERIFY(ok);
-
- a = "123A";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "1234567";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 1234567);
- QCOMPARE(b.toInt(&ok), 1234567);
- QVERIFY(ok);
-
- a = "12345678901234";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "3234567890";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "aaa12345aaa";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "aaa12345";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "12345aaa";
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "2147483647"; // 2**31 - 1
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 2147483647);
- QCOMPARE(b.toInt(&ok), 2147483647);
- QVERIFY(ok);
-
- if (sizeof(int) == 4) {
- a = "-2147483647"; // -(2**31 - 1)
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), -2147483647);
- QCOMPARE(b.toInt(&ok), -2147483647);
- QVERIFY(ok);
-
- a = "2147483648"; // 2**31
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
-
- a = "-2147483648"; // -2**31
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), -2147483647 - 1);
- QCOMPARE(b.toInt(&ok), -2147483647 - 1);
- QVERIFY(ok);
-
- a = "2147483649"; // 2**31 + 1
- b = a.leftRef(-1);
- QCOMPARE(b.toInt(), 0);
- QCOMPARE(b.toInt(&ok), 0);
- QVERIFY(!ok);
- }
-}
-
-void tst_QStringRef::toUInt()
-{
- bool ok;
- QString a;
- QStringRef b;
- a = "3234567890";
- b = a.leftRef(-1);
- QCOMPARE(b.toUInt(&ok), 3234567890u);
- QVERIFY(ok);
-
- a = "-50";
- b = a.leftRef(-1);
- QCOMPARE(b.toUInt(), 0u);
- QCOMPARE(b.toUInt(&ok), 0u);
- QVERIFY(!ok);
-
- a = "4294967295"; // 2**32 - 1
- b = a.leftRef(-1);
- QCOMPARE(b.toUInt(), 4294967295u);
- QCOMPARE(b.toUInt(&ok), 4294967295u);
- QVERIFY(ok);
-
- if (sizeof(int) == 4) {
- a = "4294967296"; // 2**32
- b = a.leftRef(-1);
- QCOMPARE(b.toUInt(), 0u);
- QCOMPARE(b.toUInt(&ok), 0u);
- QVERIFY(!ok);
- }
-}
-
-///////////////////////////// to*Long //////////////////////////////////////
-
-void tst_QStringRef::toULong_data()
-{
- QTest::addColumn<QString>("str");
- QTest::addColumn<int>("base");
- QTest::addColumn<ulong>("result");
- QTest::addColumn<bool>("ok");
-
- QTest::newRow("default") << QString() << 10 << 0UL << false;
- QTest::newRow("empty") << QString("") << 10 << 0UL << false;
- QTest::newRow("ulong1") << QString("3234567890") << 10 << 3234567890UL << true;
- QTest::newRow("ulong2") << QString("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true;
-}
-
-void tst_QStringRef::toULong()
-{
- QFETCH(QString, str);
- QFETCH(int, base);
- QFETCH(ulong, result);
- QFETCH(bool, ok);
- QStringRef strRef = str.leftRef(-1);
-
- bool b;
- QCOMPARE(strRef.toULong(0, base), result);
- QCOMPARE(strRef.toULong(&b, base), result);
- QCOMPARE(b, ok);
-}
-
-void tst_QStringRef::toLong_data()
-{
- QTest::addColumn<QString>("str");
- QTest::addColumn<int>("base");
- QTest::addColumn<long>("result");
- QTest::addColumn<bool>("ok");
-
- QTest::newRow("default") << QString() << 10 << 0L << false;
- QTest::newRow("empty") << QString("") << 10 << 0L << false;
- QTest::newRow("normal") << QString("7fFFfFFf") << 16 << 0x7fFFfFFfL << true;
- QTest::newRow("long_max") << QString("2147483647") << 10 << 2147483647L << true;
- if (sizeof(long) == 4) {
- QTest::newRow("long_max+1") << QString("2147483648") << 10 << 0L << false;
- QTest::newRow("long_min-1") << QString("-80000001") << 16 << 0L << false;
- }
- QTest::newRow("negative") << QString("-7fffffff") << 16 << -0x7fffffffL << true;
-// QTest::newRow("long_min") << QString("-80000000") << 16 << 0x80000000uL << true;
-}
-
-void tst_QStringRef::toLong()
-{
- QFETCH(QString, str);
- QFETCH(int, base);
- QFETCH(long, result);
- QFETCH(bool, ok);
- QStringRef strRef = str.leftRef(-1);
-
- bool b;
- QCOMPARE(strRef.toLong(0, base), result);
- QCOMPARE(strRef.toLong(&b, base), result);
- QCOMPARE(b, ok);
-}
-
-
-////////////////////////// to*LongLong //////////////////////////////////////
-
-void tst_QStringRef::toULongLong()
-{
- QString str;
- QStringRef strRef;
- bool ok;
- str = "18446744073709551615"; // ULLONG_MAX
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toULongLong(0), Q_UINT64_C(18446744073709551615));
- QCOMPARE(strRef.toULongLong(&ok), Q_UINT64_C(18446744073709551615));
- QVERIFY(ok);
-
- str = "18446744073709551616"; // ULLONG_MAX + 1
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toULongLong(0), Q_UINT64_C(0));
- QCOMPARE(strRef.toULongLong(&ok), Q_UINT64_C(0));
- QVERIFY(!ok);
-
- str = "-150";
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toULongLong(0), Q_UINT64_C(0));
- QCOMPARE(strRef.toULongLong(&ok), Q_UINT64_C(0));
- QVERIFY(!ok);
-}
-
-void tst_QStringRef::toLongLong()
-{
- QString str;
- QStringRef strRef;
- bool ok;
-
- str = "9223372036854775807"; // LLONG_MAX
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toLongLong(0), Q_INT64_C(9223372036854775807));
- QCOMPARE(strRef.toLongLong(&ok), Q_INT64_C(9223372036854775807));
- QVERIFY(ok);
-
- str = "-9223372036854775808"; // LLONG_MIN
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toLongLong(0),
- -Q_INT64_C(9223372036854775807) - Q_INT64_C(1));
- QCOMPARE(strRef.toLongLong(&ok),
- -Q_INT64_C(9223372036854775807) - Q_INT64_C(1));
- QVERIFY(ok);
-
- str = "aaaa9223372036854775807aaaa";
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toLongLong(0), Q_INT64_C(0));
- QCOMPARE(strRef.toLongLong(&ok), Q_INT64_C(0));
- QVERIFY(!ok);
-
- str = "9223372036854775807aaaa";
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toLongLong(0), Q_INT64_C(0));
- QCOMPARE(strRef.toLongLong(&ok), Q_INT64_C(0));
- QVERIFY(!ok);
-
- str = "aaaa9223372036854775807";
- strRef = str.leftRef(-1);
- QCOMPARE(strRef.toLongLong(0), Q_INT64_C(0));
- QCOMPARE(strRef.toLongLong(&ok), Q_INT64_C(0));
- QVERIFY(!ok);
-
- static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- for (int i = 0; i < 36; ++i) {
- for (int j = 0; j < 36; ++j) {
- for (int k = 0; k < 36; ++k) {
- QString str;
- str += QChar(digits[i]);
- str += QChar(digits[j]);
- str += QChar(digits[k]);
- strRef = str.leftRef(-1);
- qlonglong value = (((i * 36) + j) * 36) + k;
- QVERIFY(strRef.toLongLong(0, 36) == value);
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-void tst_QStringRef::toFloat()
-{
- QString a;
- QStringRef b;
- bool ok;
- a = "0.000000000931322574615478515625";
- b = a.leftRef(-1);
- QCOMPARE(b.toFloat(&ok), float(0.000000000931322574615478515625));
- QVERIFY(ok);
-}
-
-void tst_QStringRef::toDouble_data()
-{
- QTest::addColumn<QString>("str");
- QTest::addColumn<double>("result");
- QTest::addColumn<bool>("result_ok");
-
- QTest::newRow("ok00") << QString("0.000000000931322574615478515625") << 0.000000000931322574615478515625 << true;
- QTest::newRow("ok01") << QString(" 123.45") << 123.45 << true;
-
- QTest::newRow("ok02") << QString("0.1e10") << 0.1e10 << true;
- QTest::newRow("ok03") << QString("0.1e-10") << 0.1e-10 << true;
-
- QTest::newRow("ok04") << QString("1e10") << 1.0e10 << true;
- QTest::newRow("ok05") << QString("1e+10") << 1.0e10 << true;
- QTest::newRow("ok06") << QString("1e-10") << 1.0e-10 << true;
-
- QTest::newRow("ok07") << QString(" 1e10") << 1.0e10 << true;
- QTest::newRow("ok08") << QString(" 1e+10") << 1.0e10 << true;
- QTest::newRow("ok09") << QString(" 1e-10") << 1.0e-10 << true;
-
- QTest::newRow("ok10") << QString("1.") << 1.0 << true;
- QTest::newRow("ok11") << QString(".1") << 0.1 << true;
-
- QTest::newRow("wrong00") << QString("123.45 ") << 123.45 << true;
- QTest::newRow("wrong01") << QString(" 123.45 ") << 123.45 << true;
-
- QTest::newRow("wrong02") << QString("aa123.45aa") << 0.0 << false;
- QTest::newRow("wrong03") << QString("123.45aa") << 0.0 << false;
- QTest::newRow("wrong04") << QString("123erf") << 0.0 << false;
-
- QTest::newRow("wrong05") << QString("abc") << 0.0 << false;
- QTest::newRow("wrong06") << QString() << 0.0 << false;
- QTest::newRow("wrong07") << QString("") << 0.0 << false;
-}
-
-void tst_QStringRef::toDouble()
-{
- QFETCH(QString, str);
- QFETCH(bool, result_ok);
- QStringRef strRef = str.leftRef(-1);
- bool ok;
- double d = strRef.toDouble(&ok);
- if (result_ok) {
- QTEST(d, "result");
- QVERIFY(ok);
- } else {
- QVERIFY(!ok);
- }
-}
-
-void tst_QStringRef::integer_conversion_data()
-{
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<int>("base");
- QTest::addColumn<bool>("good");
- QTest::addColumn<qlonglong>("num");
-
- QTest::newRow("C empty 0") << QString("") << 0 << false << (qlonglong)0;
- QTest::newRow("C empty 8") << QString("") << 8 << false << (qlonglong)0;
- QTest::newRow("C empty 10") << QString("") << 10 << false << (qlonglong)0;
- QTest::newRow("C empty 16") << QString("") << 16 << false << (qlonglong)0;
-
- QTest::newRow("C null 0") << QString() << 0 << false << (qlonglong)0;
- QTest::newRow("C null 8") << QString() << 8 << false << (qlonglong)0;
- QTest::newRow("C null 10") << QString() << 10 << false << (qlonglong)0;
- QTest::newRow("C null 16") << QString() << 16 << false << (qlonglong)0;
-
- QTest::newRow("C -0xf 0") << QString(" -0xf") << 0 << true << (qlonglong)-15;
- QTest::newRow("C -0xf 0") << QString("-0xf ") << 0 << true << (qlonglong)-15;
- QTest::newRow("C \t0xf\t 0") << QString("\t0xf\t") << 0 << true << (qlonglong)15;
- QTest::newRow("C -010 0") << QString(" -010") << 0 << true << (qlonglong)-8;
- QTest::newRow("C 010 0") << QString("010 ") << 0 << true << (qlonglong)8;
- QTest::newRow("C \t-010\t 0") << QString("\t-010\t") << 0 << true << (qlonglong)-8;
- QTest::newRow("C 123 10") << QString(" 123") << 10 << true << (qlonglong)123;
- QTest::newRow("C 123 10") << QString("123 ") << 10 << true << (qlonglong)123;
- QTest::newRow("C \t123\t 10") << QString("\t123\t") << 10 << true << (qlonglong)123;
- QTest::newRow("C -0xf 16") << QString(" -0xf") << 16 << true << (qlonglong)-15;
- QTest::newRow("C -0xf 16") << QString("-0xf ") << 16 << true << (qlonglong)-15;
- QTest::newRow("C \t0xf\t 16") << QString("\t0xf\t") << 16 << true << (qlonglong)15;
-
- QTest::newRow("C -0 0") << QString("-0") << 0 << true << (qlonglong)0;
- QTest::newRow("C -0 8") << QString("-0") << 8 << true << (qlonglong)0;
- QTest::newRow("C -0 10") << QString("-0") << 10 << true << (qlonglong)0;
- QTest::newRow("C -0 16") << QString("-0") << 16 << true << (qlonglong)0;
-
- QTest::newRow("C 1.234 10") << QString("1.234") << 10 << false << (qlonglong)0;
- QTest::newRow("C 1,234 10") << QString("1,234") << 10 << false << (qlonglong)0;
-
- QTest::newRow("C 0x 0") << QString("0x") << 0 << false << (qlonglong)0;
- QTest::newRow("C 0x 16") << QString("0x") << 16 << false << (qlonglong)0;
-
- QTest::newRow("C 10 0") << QString("10") << 0 << true << (qlonglong)10;
- QTest::newRow("C 010 0") << QString("010") << 0 << true << (qlonglong)8;
- QTest::newRow("C 0x10 0") << QString("0x10") << 0 << true << (qlonglong)16;
- QTest::newRow("C 10 8") << QString("10") << 8 << true << (qlonglong)8;
- QTest::newRow("C 010 8") << QString("010") << 8 << true << (qlonglong)8;
- QTest::newRow("C 0x10 8") << QString("0x10") << 8 << false << (qlonglong)0;
- QTest::newRow("C 10 10") << QString("10") << 10 << true << (qlonglong)10;
- QTest::newRow("C 010 10") << QString("010") << 10 << true << (qlonglong)10;
- QTest::newRow("C 0x10 10") << QString("0x10") << 10 << false << (qlonglong)0;
- QTest::newRow("C 10 16") << QString("10") << 16 << true << (qlonglong)16;
- QTest::newRow("C 010 16") << QString("010") << 16 << true << (qlonglong)16;
- QTest::newRow("C 0x10 16") << QString("0x10") << 16 << true << (qlonglong)16;
-
- QTest::newRow("C -10 0") << QString("-10") << 0 << true << (qlonglong)-10;
- QTest::newRow("C -010 0") << QString("-010") << 0 << true << (qlonglong)-8;
- QTest::newRow("C -0x10 0") << QString("-0x10") << 0 << true << (qlonglong)-16;
- QTest::newRow("C -10 8") << QString("-10") << 8 << true << (qlonglong)-8;
- QTest::newRow("C -010 8") << QString("-010") << 8 << true << (qlonglong)-8;
- QTest::newRow("C -0x10 8") << QString("-0x10") << 8 << false << (qlonglong)0;
- QTest::newRow("C -10 10") << QString("-10") << 10 << true << (qlonglong)-10;
- QTest::newRow("C -010 10") << QString("-010") << 10 << true << (qlonglong)-10;
- QTest::newRow("C -0x10 10") << QString("-0x10") << 10 << false << (qlonglong)0;
- QTest::newRow("C -10 16") << QString("-10") << 16 << true << (qlonglong)-16;
- QTest::newRow("C -010 16") << QString("-010") << 16 << true << (qlonglong)-16;
- QTest::newRow("C -0x10 16") << QString("-0x10") << 16 << true << (qlonglong)-16;
-
- // Let's try some Arabic
- const quint16 arabic_str[] = { 0x0661, 0x0662, 0x0663, 0x0664, 0x0000 }; // "1234"
- QTest::newRow("ar_SA 1234 0") << QString::fromUtf16(arabic_str) << 0 << false << (qlonglong)0;
-}
-
-void tst_QStringRef::integer_conversion()
-{
- QFETCH(QString, num_str);
- QFETCH(int, base);
- QFETCH(bool, good);
- QFETCH(qlonglong, num);
- QStringRef num_strRef = num_str.leftRef(-1);
-
- bool ok;
- qlonglong d = num_strRef.toLongLong(&ok, base);
- QCOMPARE(ok, good);
-
- if (ok) {
- QCOMPARE(d, num);
- }
-}
-
-void tst_QStringRef::double_conversion_data()
-{
- QTest::addColumn<QString>("num_str");
- QTest::addColumn<bool>("good");
- QTest::addColumn<double>("num");
-
- // The good...
-
- QTest::newRow("C 1") << QString("1") << true << 1.0;
- QTest::newRow("C 1.0") << QString("1.0") << true << 1.0;
- QTest::newRow("C 1.234") << QString("1.234") << true << 1.234;
- QTest::newRow("C 1.234e-10") << QString("1.234e-10") << true << 1.234e-10;
- QTest::newRow("C 1.234E10") << QString("1.234E10") << true << 1.234e10;
- QTest::newRow("C 1e10") << QString("1e10") << true << 1.0e10;
-
- // The bad...
-
- QTest::newRow("C empty") << QString("") << false << 0.0;
- QTest::newRow("C null") << QString() << false << 0.0;
- QTest::newRow("C .") << QString(".") << false << 0.0;
- QTest::newRow("C 1e") << QString("1e") << false << 0.0;
- QTest::newRow("C 1,") << QString("1,") << false << 0.0;
- QTest::newRow("C 1,0") << QString("1,0") << false << 0.0;
- QTest::newRow("C 1,000") << QString("1,000") << false << 0.0;
- QTest::newRow("C 1e1.0") << QString("1e1.0") << false << 0.0;
- QTest::newRow("C 1e+") << QString("1e+") << false << 0.0;
- QTest::newRow("C 1e-") << QString("1e-") << false << 0.0;
- QTest::newRow("de_DE 1,0") << QString("1,0") << false << 0.0;
- QTest::newRow("de_DE 1,234") << QString("1,234") << false << 0.0;
- QTest::newRow("de_DE 1,234e-10") << QString("1,234e-10") << false << 0.0;
- QTest::newRow("de_DE 1,234E10") << QString("1,234E10") << false << 0.0;
-
- // And the ugly...
-
- QTest::newRow("C .1") << QString(".1") << true << 0.1;
- QTest::newRow("C -.1") << QString("-.1") << true << -0.1;
- QTest::newRow("C 1.") << QString("1.") << true << 1.0;
- QTest::newRow("C 1.E10") << QString("1.E10") << true << 1.0e10;
- QTest::newRow("C 1e+10") << QString("1e+10") << true << 1.0e+10;
- QTest::newRow("C 1") << QString(" 1") << true << 1.0;
- QTest::newRow("C 1 ") << QString("1 ") << true << 1.0;
-
- // Let's try some Arabic
- const quint16 arabic_str[] = { 0x0660, 0x066B, 0x0661, 0x0662,
- 0x0663, 0x0664, 0x0065, 0x0662,
- 0x0000 }; // "0.1234e2"
- QTest::newRow("ar_SA") << QString::fromUtf16(arabic_str) << false << 0.0;
-}
-
-void tst_QStringRef::double_conversion()
-{
-#define MY_DOUBLE_EPSILON (2.22045e-16)
-
- QFETCH(QString, num_str);
- QFETCH(bool, good);
- QFETCH(double, num);
- QStringRef num_strRef = num_str.leftRef(-1);
-
- bool ok;
- double d = num_strRef.toDouble(&ok);
- QCOMPARE(ok, good);
-
- if (ok) {
- double diff = d - num;
- if (diff < 0)
- diff = -diff;
- QVERIFY(diff <= MY_DOUBLE_EPSILON);
- }
-}
-
-void tst_QStringRef::trimmed()
-{
- QVERIFY(QStringRef().trimmed().isNull());
- QString a = "";
- QVERIFY(!QStringRef(&a).trimmed().isNull());
- QStringRef b;
- a = "Text";
- b = a.leftRef(-1);
- QCOMPARE(b.compare(QStringLiteral("Text")), 0);
- QCOMPARE(b.trimmed().compare(QStringLiteral("Text")), 0);
- a = " ";
- b = a.leftRef(-1);
- QCOMPARE(b.compare(QStringLiteral(" ")), 0);
- QCOMPARE(b.trimmed().compare(QStringLiteral("")), 0);
- a = " a ";
- b = a.leftRef(-1);
- QCOMPARE(b.trimmed().compare(QStringLiteral("a")), 0);
- a = "Text a ";
- b = a.midRef(4);
- QCOMPARE(b.compare(QStringLiteral(" a ")), 0);
- QCOMPARE(b.trimmed().compare(QStringLiteral("a")), 0);
-}
-
-void tst_QStringRef::truncate()
-{
- const QString str = "OriginalString~";
- const QStringRef cref = str.midRef(0);
- {
- QStringRef ref = cref;
- ref.truncate(1000);
- QCOMPARE(ref, cref);
- for (int i = str.size(); i >= 0; --i) {
- ref.truncate(i);
- QCOMPARE(ref.size(), i);
- QCOMPARE(ref, cref.left(i));
- }
- QVERIFY(ref.isEmpty());
- }
-
- {
- QStringRef ref = cref;
- QVERIFY(!ref.isEmpty());
- ref.truncate(-1);
- QVERIFY(ref.isEmpty());
- }
-}
-
-void tst_QStringRef::chop()
-{
- const QString originalString = QStringLiteral("OriginalString~");
- const QStringRef cref(&originalString);
- {
- const int n = 1;
- QStringRef ref = cref;
- QString str = originalString;
- ref.chop(n);
- str.chop(n);
- QCOMPARE(ref.toString(), QLatin1String("OriginalString"));
- QCOMPARE(ref.toString(), str);
- }
- {
- const int n = -1;
- QStringRef ref = cref;
- QString str = originalString;
- ref.chop(n);
- str.chop(n);
- QCOMPARE(ref.toString(), originalString);
- QCOMPARE(ref.toString(), str);
- }
- {
- const int n = 0;
- QStringRef ref = cref;
- QString str = originalString;
- ref.chop(n);
- str.chop(n);
- QCOMPARE(ref.toString(), originalString);
- QCOMPARE(ref.toString(), str);
- }
- {
- const int n = 1000;
- QStringRef ref = cref;
- QString str = originalString;
- ref.chop(n);
- str.chop(n);
- QCOMPARE(ref.toString(), str);
- QVERIFY(ref.isEmpty());
- }
-}
-
-void tst_QStringRef::left()
-{
- QString originalString = "OrginalString~";
- QStringRef ref = originalString.leftRef(originalString.size() - 1);
- QCOMPARE(ref.toString(), QStringLiteral("OrginalString"));
-
- QVERIFY(ref.left(0).toString().isEmpty());
- QCOMPARE(ref.left(ref.size()).toString(), QStringLiteral("OrginalString"));
-
- QStringRef nullRef;
- QVERIFY(nullRef.isNull());
- QVERIFY(nullRef.left(3).toString().isEmpty());
- QVERIFY(nullRef.left(0).toString().isEmpty());
- QVERIFY(nullRef.left(-1).toString().isEmpty());
-
- QStringRef emptyRef(&originalString, 0, 0);
- QVERIFY(emptyRef.isEmpty());
- QVERIFY(emptyRef.left(3).toString().isEmpty());
- QVERIFY(emptyRef.left(0).toString().isEmpty());
- QVERIFY(emptyRef.left(-1).toString().isEmpty());
-
- QCOMPARE(ref.left(-1), ref);
- QCOMPARE(ref.left(100), ref);
-}
-
-void tst_QStringRef::right()
-{
- QString originalString = "~OrginalString";
- QStringRef ref = originalString.rightRef(originalString.size() - 1);
- QCOMPARE(ref.toString(), QLatin1String("OrginalString"));
-
- QCOMPARE(ref.right(6).toString(), QLatin1String("String"));
- QCOMPARE(ref.right(ref.size()).toString(), QLatin1String("OrginalString"));
- QCOMPARE(ref.right(0).toString(), QLatin1String(""));
-
- QStringRef nullRef;
- QVERIFY(nullRef.isNull());
- QVERIFY(nullRef.right(3).toString().isEmpty());
- QVERIFY(nullRef.right(0).toString().isEmpty());
- QVERIFY(nullRef.right(-1).toString().isEmpty());
-
- QStringRef emptyRef(&originalString, 0, 0);
- QVERIFY(emptyRef.isEmpty());
- QVERIFY(emptyRef.right(3).toString().isEmpty());
- QVERIFY(emptyRef.right(0).toString().isEmpty());
- QVERIFY(emptyRef.right(-1).toString().isEmpty());
-
- QCOMPARE(ref.right(-1), ref);
- QCOMPARE(ref.right(100), ref);
-}
-
-void tst_QStringRef::mid()
-{
- QString orig = QStringLiteral("~ABCDEFGHIEfGEFG~"); // 15 + 2 chars
- QStringRef a = orig.midRef(1, 15);
- QCOMPARE(a.size(), orig.size() - 2);
-
- QCOMPARE(a.mid(3,3).toString(),(QString)"DEF");
- QCOMPARE(a.mid(0,0).toString(),(QString)"");
- QVERIFY(!a.mid(15,0).toString().isNull());
- QVERIFY(a.mid(15,0).toString().isEmpty());
- QVERIFY(!a.mid(15,1).toString().isNull());
- QVERIFY(a.mid(15,1).toString().isEmpty());
- QVERIFY(a.mid(9999).toString().isEmpty());
- QVERIFY(a.mid(9999,1).toString().isEmpty());
-
- QCOMPARE(a.mid(-1, 6), a.mid(0, 5));
- QVERIFY(a.mid(-100, 6).isEmpty());
- QVERIFY(a.mid(INT_MIN, 0).isEmpty());
- QCOMPARE(a.mid(INT_MIN, -1), a);
- QVERIFY(a.mid(INT_MIN, INT_MAX).isNull());
- QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty());
- QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1));
- QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a);
- QVERIFY(a.mid(INT_MAX).isNull());
- QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
- QCOMPARE(a.mid(-5, INT_MAX), a);
- QCOMPARE(a.mid(-1, INT_MAX), a);
- QCOMPARE(a.mid(0, INT_MAX), a);
- QCOMPARE(a.mid(1, INT_MAX).toString(), QString("BCDEFGHIEfGEFG"));
- QCOMPARE(a.mid(5, INT_MAX).toString(), QString("FGHIEfGEFG"));
- QVERIFY(a.mid(20, INT_MAX).isNull());
- QCOMPARE(a.mid(-1, -1), a);
-
- QStringRef nullRef;
- QVERIFY(nullRef.mid(3,3).toString().isEmpty());
- QVERIFY(nullRef.mid(0,0).toString().isEmpty());
- QVERIFY(nullRef.mid(9999,0).toString().isEmpty());
- QVERIFY(nullRef.mid(9999,1).toString().isEmpty());
-
- QVERIFY(nullRef.mid(-1, 6).isNull());
- QVERIFY(nullRef.mid(-100, 6).isNull());
- QVERIFY(nullRef.mid(INT_MIN, 0).isNull());
- QVERIFY(nullRef.mid(INT_MIN, -1).isNull());
- QVERIFY(nullRef.mid(INT_MIN, INT_MAX).isNull());
- QVERIFY(nullRef.mid(INT_MIN + 1, INT_MAX).isNull());
- QVERIFY(nullRef.mid(INT_MIN + 2, INT_MAX).isNull());
- QVERIFY(nullRef.mid(INT_MIN + nullRef.size() + 1, INT_MAX).isNull());
- QVERIFY(nullRef.mid(INT_MAX).isNull());
- QVERIFY(nullRef.mid(INT_MAX, INT_MAX).isNull());
- QVERIFY(nullRef.mid(-5, INT_MAX).isNull());
- QVERIFY(nullRef.mid(-1, INT_MAX).isNull());
- QVERIFY(nullRef.mid(0, INT_MAX).isNull());
- QVERIFY(nullRef.mid(1, INT_MAX).isNull());
- QVERIFY(nullRef.mid(5, INT_MAX).isNull());
- QVERIFY(nullRef.mid(20, INT_MAX).isNull());
- QVERIFY(nullRef.mid(-1, -1).isNull());
-
- QString ninePineapples = "~Nine pineapples~";
- QStringRef x = ninePineapples.midRef(1, ninePineapples.size() - 1);
- QCOMPARE(x.mid(5, 4).toString(), QString("pine"));
- QCOMPARE(x.mid(5).toString(), QString("pineapples~"));
-
- QCOMPARE(x.mid(-1, 6), x.mid(0, 5));
- QVERIFY(x.mid(-100, 6).isEmpty());
- QVERIFY(x.mid(INT_MIN, 0).isEmpty());
- QCOMPARE(x.mid(INT_MIN, -1).toString(), x.toString());
- QVERIFY(x.mid(INT_MIN, INT_MAX).isNull());
- QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty());
- QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1));
- QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX).toString(), x.toString());
- QVERIFY(x.mid(INT_MAX).isNull());
- QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
- QCOMPARE(x.mid(-5, INT_MAX).toString(), x.toString());
- QCOMPARE(x.mid(-1, INT_MAX).toString(), x.toString());
- QCOMPARE(x.mid(0, INT_MAX), x);
- QCOMPARE(x.mid(1, INT_MAX).toString(), QString("ine pineapples~"));
- QCOMPARE(x.mid(5, INT_MAX).toString(), QString("pineapples~"));
- QVERIFY(x.mid(20, INT_MAX).isNull());
- QCOMPARE(x.mid(-1, -1), x);
-
- QStringRef emptyRef(&ninePineapples, 0, 0);
- QVERIFY(emptyRef.mid(1).isEmpty());
- QVERIFY(emptyRef.mid(-1).isEmpty());
- QVERIFY(emptyRef.mid(0).isEmpty());
- QVERIFY(emptyRef.mid(0, 3).isEmpty());
- QVERIFY(emptyRef.mid(-10, 3).isEmpty());
-}
-
-static bool operator ==(const QStringList &left, const QVector<QStringRef> &right)
-{
- if (left.size() != right.size())
- return false;
-
- QStringList::const_iterator iLeft = left.constBegin();
- QVector<QStringRef>::const_iterator iRight = right.constBegin();
- for (; iLeft != left.end(); ++iLeft, ++iRight) {
- if (*iLeft != *iRight)
- return false;
- }
- return true;
-}
-static inline bool operator ==(const QVector<QStringRef> &left, const QStringList &right) { return right == left; }
-
-void tst_QStringRef::split_data()
-{
- QTest::addColumn<QString>("str");
- QTest::addColumn<QString>("sep");
- QTest::addColumn<QStringList>("result");
-
- QTest::newRow("a,b,c") << "a,b,c" << "," << (QStringList() << "a" << "b" << "c");
- QTest::newRow("a,b,c,a,b,c") << "a,b,c,a,b,c" << "," << (QStringList() << "a" << "b" << "c" << "a" << "b" << "c");
- QTest::newRow("a,b,c,,a,b,c") << "a,b,c,,a,b,c" << "," << (QStringList() << "a" << "b" << "c" << "" << "a" << "b" << "c");
- QTest::newRow("2") << QString("-rw-r--r-- 1 0 0 519240 Jul 9 2002 bigfile")
- << " "
- << (QStringList() << "-rw-r--r--" << "" << "1" << "0" << "" << "0" << ""
- << "519240" << "Jul" << "" << "9" << "" << "2002" << "bigfile");
- QTest::newRow("one-empty") << "" << " " << (QStringList() << "");
- QTest::newRow("two-empty") << " " << " " << (QStringList() << "" << "");
- QTest::newRow("three-empty") << " " << " " << (QStringList() << "" << "" << "");
-
- QTest::newRow("all-empty") << "" << "" << (QStringList() << "" << "");
- QTest::newRow("all-null") << QString() << QString() << (QStringList() << QString() << QString());
- QTest::newRow("sep-empty") << "abc" << "" << (QStringList() << "" << "a" << "b" << "c" << "");
-}
-
-void tst_QStringRef::split()
-{
- QFETCH(QString, str);
- QFETCH(QString, sep);
- QFETCH(QStringList, result);
-
- QVector<QStringRef> list;
- // we construct a bigger valid string to check
- // if ref.split is using the right size
- QString source = str + str + str;
- QStringRef ref = source.midRef(str.size(), str.size());
- QCOMPARE(ref.size(), str.size());
-
- list = ref.split(sep);
- QVERIFY(list == result);
- if (sep.size() == 1) {
- list = ref.split(sep.at(0));
- QVERIFY(list == result);
- }
-
- list = ref.split(sep, QString::KeepEmptyParts);
- QVERIFY(list == result);
- if (sep.size() == 1) {
- list = ref.split(sep.at(0), QString::KeepEmptyParts);
- QVERIFY(list == result);
- }
-
- result.removeAll("");
- list = ref.split(sep, QString::SkipEmptyParts);
- QVERIFY(list == result);
- if (sep.size() == 1) {
- list = ref.split(sep.at(0), QString::SkipEmptyParts);
- QVERIFY(list == result);
- }
-}
-
-QTEST_APPLESS_MAIN(tst_QStringRef)
-
-#include "tst_qstringref.moc"
diff --git a/tests/auto/corelib/tools/qstringview/qstringview.pro b/tests/auto/corelib/tools/qstringview/qstringview.pro
deleted file mode 100644
index e0e9973c91..0000000000
--- a/tests/auto/corelib/tools/qstringview/qstringview.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qstringview
-QT = core testlib
-contains(QT_CONFIG, c++14):CONFIG *= c++14
-contains(QT_CONFIG, c++1z):CONFIG *= c++1z
-SOURCES += tst_qstringview.cpp
diff --git a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp
deleted file mode 100644
index e800a0d794..0000000000
--- a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp
+++ /dev/null
@@ -1,639 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QStringView>
-#include <QString>
-#include <QChar>
-#include <QStringRef>
-
-#include <QTest>
-
-#include <string>
-
-template <typename T>
-using CanConvert = std::is_convertible<T, QStringView>;
-
-Q_STATIC_ASSERT(!CanConvert<QLatin1String>::value);
-Q_STATIC_ASSERT(!CanConvert<const char*>::value);
-Q_STATIC_ASSERT(!CanConvert<QByteArray>::value);
-
-// QStringView qchar_does_not_compile() { return QStringView(QChar('a')); }
-// QStringView qlatin1string_does_not_compile() { return QStringView(QLatin1String("a")); }
-// QStringView const_char_star_does_not_compile() { return QStringView("a"); }
-// QStringView qbytearray_does_not_compile() { return QStringView(QByteArray("a")); }
-
-//
-// QChar
-//
-
-Q_STATIC_ASSERT(!CanConvert<QChar>::value);
-
-Q_STATIC_ASSERT(CanConvert<QChar[123]>::value);
-
-Q_STATIC_ASSERT(CanConvert< QString >::value);
-Q_STATIC_ASSERT(CanConvert<const QString >::value);
-Q_STATIC_ASSERT(CanConvert< QString&>::value);
-Q_STATIC_ASSERT(CanConvert<const QString&>::value);
-
-Q_STATIC_ASSERT(CanConvert< QStringRef >::value);
-Q_STATIC_ASSERT(CanConvert<const QStringRef >::value);
-Q_STATIC_ASSERT(CanConvert< QStringRef&>::value);
-Q_STATIC_ASSERT(CanConvert<const QStringRef&>::value);
-
-
-//
-// ushort
-//
-
-Q_STATIC_ASSERT(!CanConvert<ushort>::value);
-
-Q_STATIC_ASSERT(CanConvert<ushort[123]>::value);
-
-Q_STATIC_ASSERT(CanConvert< ushort*>::value);
-Q_STATIC_ASSERT(CanConvert<const ushort*>::value);
-
-
-//
-// char16_t
-//
-
-#if defined(Q_COMPILER_UNICODE_STRINGS)
-
-Q_STATIC_ASSERT(!CanConvert<char16_t>::value);
-
-Q_STATIC_ASSERT(CanConvert< char16_t*>::value);
-Q_STATIC_ASSERT(CanConvert<const char16_t*>::value);
-
-#endif
-
-#if defined(Q_STDLIB_UNICODE_STRINGS)
-
-Q_STATIC_ASSERT(CanConvert< std::u16string >::value);
-Q_STATIC_ASSERT(CanConvert<const std::u16string >::value);
-Q_STATIC_ASSERT(CanConvert< std::u16string&>::value);
-Q_STATIC_ASSERT(CanConvert<const std::u16string&>::value);
-
-#endif
-
-
-//
-// wchar_t
-//
-
-Q_CONSTEXPR bool CanConvertFromWCharT =
-#ifdef Q_OS_WIN
- true
-#else
- false
-#endif
- ;
-
-Q_STATIC_ASSERT(!CanConvert<wchar_t>::value);
-
-Q_STATIC_ASSERT(CanConvert< wchar_t*>::value == CanConvertFromWCharT);
-Q_STATIC_ASSERT(CanConvert<const wchar_t*>::value == CanConvertFromWCharT);
-
-Q_STATIC_ASSERT(CanConvert< std::wstring >::value == CanConvertFromWCharT);
-Q_STATIC_ASSERT(CanConvert<const std::wstring >::value == CanConvertFromWCharT);
-Q_STATIC_ASSERT(CanConvert< std::wstring&>::value == CanConvertFromWCharT);
-Q_STATIC_ASSERT(CanConvert<const std::wstring&>::value == CanConvertFromWCharT);
-
-
-class tst_QStringView : public QObject
-{
- Q_OBJECT
-
-private Q_SLOTS:
- void constExpr() const;
- void basics() const;
- void literals() const;
- void at() const;
-
- void fromQString() const;
- void fromQStringRef() const;
-
- void fromQCharStar() const
- {
- const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
- fromLiteral(str);
- }
-
- void fromUShortStar() const
- {
- const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0 };
- fromLiteral(str);
- }
-
- void fromChar16TStar() const
- {
-#if defined(Q_COMPILER_UNICODE_STRINGS)
- fromLiteral(u"Hello, World!");
-#else
- QSKIP("This test requires C++11 char16_t support enabled in the compiler");
-#endif
- }
-
- void fromWCharTStar() const
- {
-#ifdef Q_OS_WIN
- fromLiteral(L"Hello, World!");
-#else
- QSKIP("This is a Windows-only test");
-#endif
- }
-
- void fromQCharRange() const
- {
- const QChar str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
- fromRange(std::begin(str), std::end(str));
- }
-
- void fromUShortRange() const
- {
- const ushort str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
- fromRange(std::begin(str), std::end(str));
- }
-
- void fromChar16TRange() const
- {
-#if defined(Q_COMPILER_UNICODE_STRINGS)
- const char16_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
- fromRange(std::begin(str), std::end(str));
-#else
- QSKIP("This test requires C++11 char16_t support enabled in the compiler");
-#endif
- }
-
- void fromWCharTRange() const
- {
-#ifdef Q_OS_WIN
- const wchar_t str[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
- fromRange(std::begin(str), std::end(str));
-#else
- QSKIP("This is a Windows-only test");
-#endif
- }
-
- // std::basic_string
- void fromStdStringWCharT() const
- {
-#ifdef Q_OS_WIN
- fromStdString<wchar_t>();
-#else
- QSKIP("This is a Windows-only test");
-#endif
- }
- void fromStdStringChar16T() const
- {
-#ifdef Q_STDLIB_UNICODE_STRINGS
- fromStdString<char16_t>();
-#else
- QSKIP("This test requires C++11 char16_t support enabled in compiler & stdlib");
-#endif
- }
-
- void comparison();
-
-private:
- template <typename String>
- void conversion_tests(String arg) const;
- template <typename Char>
- void fromLiteral(const Char *arg) const;
- template <typename Char>
- void fromRange(const Char *first, const Char *last) const;
- template <typename Char, typename Container>
- void fromContainer() const;
- template <typename Char>
- void fromStdString() const { fromContainer<Char, std::basic_string<Char> >(); }
-};
-
-void tst_QStringView::constExpr() const
-{
- // compile-time checks
-#ifdef Q_COMPILER_CONSTEXPR
- {
- constexpr QStringView sv;
- Q_STATIC_ASSERT(sv.size() == 0);
- Q_STATIC_ASSERT(sv.isNull());
- Q_STATIC_ASSERT(sv.empty());
- Q_STATIC_ASSERT(sv.isEmpty());
- Q_STATIC_ASSERT(sv.utf16() == nullptr);
-
- constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
- Q_STATIC_ASSERT(sv2.isNull());
- Q_STATIC_ASSERT(sv2.empty());
- }
- {
- constexpr QStringView sv = QStringViewLiteral("");
- Q_STATIC_ASSERT(sv.size() == 0);
- Q_STATIC_ASSERT(!sv.isNull());
- Q_STATIC_ASSERT(sv.empty());
- Q_STATIC_ASSERT(sv.isEmpty());
- Q_STATIC_ASSERT(sv.utf16() != nullptr);
-
- constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
- Q_STATIC_ASSERT(!sv2.isNull());
- Q_STATIC_ASSERT(sv2.empty());
- }
- {
- constexpr QStringView sv = QStringViewLiteral("Hello");
- Q_STATIC_ASSERT(sv.size() == 5);
- Q_STATIC_ASSERT(!sv.empty());
- Q_STATIC_ASSERT(!sv.isEmpty());
- Q_STATIC_ASSERT(!sv.isNull());
- Q_STATIC_ASSERT(*sv.utf16() == 'H');
- Q_STATIC_ASSERT(sv[0] == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.at(0) == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.front() == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.first() == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv[4] == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.at(4) == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.back() == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.last() == QLatin1Char('o'));
-
- constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
- Q_STATIC_ASSERT(!sv2.isNull());
- Q_STATIC_ASSERT(!sv2.empty());
- Q_STATIC_ASSERT(sv2.size() == 5);
- }
-#if !defined(Q_OS_WIN) || defined(Q_COMPILER_UNICODE_STRINGS)
- {
- Q_STATIC_ASSERT(QStringView(u"Hello").size() == 5);
- constexpr QStringView sv = u"Hello";
- Q_STATIC_ASSERT(sv.size() == 5);
- Q_STATIC_ASSERT(!sv.empty());
- Q_STATIC_ASSERT(!sv.isEmpty());
- Q_STATIC_ASSERT(!sv.isNull());
- Q_STATIC_ASSERT(*sv.utf16() == 'H');
- Q_STATIC_ASSERT(sv[0] == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.at(0) == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.front() == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.first() == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv[4] == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.at(4) == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.back() == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.last() == QLatin1Char('o'));
-
- constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
- Q_STATIC_ASSERT(!sv2.isNull());
- Q_STATIC_ASSERT(!sv2.empty());
- Q_STATIC_ASSERT(sv2.size() == 5);
-
- constexpr char16_t *null = nullptr;
- constexpr QStringView sv3(null);
- Q_STATIC_ASSERT(sv3.isNull());
- Q_STATIC_ASSERT(sv3.isEmpty());
- Q_STATIC_ASSERT(sv3.size() == 0);
- }
-#else // storage_type is wchar_t
- {
- Q_STATIC_ASSERT(QStringView(L"Hello").size() == 5);
- constexpr QStringView sv = L"Hello";
- Q_STATIC_ASSERT(sv.size() == 5);
- Q_STATIC_ASSERT(!sv.empty());
- Q_STATIC_ASSERT(!sv.isEmpty());
- Q_STATIC_ASSERT(!sv.isNull());
- Q_STATIC_ASSERT(*sv.utf16() == 'H');
- Q_STATIC_ASSERT(sv[0] == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.at(0) == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.front() == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv.first() == QLatin1Char('H'));
- Q_STATIC_ASSERT(sv[4] == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.at(4) == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.back() == QLatin1Char('o'));
- Q_STATIC_ASSERT(sv.last() == QLatin1Char('o'));
-
- constexpr QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
- Q_STATIC_ASSERT(!sv2.isNull());
- Q_STATIC_ASSERT(!sv2.empty());
- Q_STATIC_ASSERT(sv2.size() == 5);
-
- constexpr wchar_t *null = nullptr;
- constexpr QStringView sv3(null);
- Q_STATIC_ASSERT(sv3.isNull());
- Q_STATIC_ASSERT(sv3.isEmpty());
- Q_STATIC_ASSERT(sv3.size() == 0);
- }
-#endif
-#endif
-}
-
-void tst_QStringView::basics() const
-{
- QStringView sv1;
-
- // a default-constructed QStringView is null:
- QVERIFY(sv1.isNull());
- // which implies it's empty();
- QVERIFY(sv1.isEmpty());
-
- QStringView sv2;
-
- QVERIFY(sv2 == sv1);
- QVERIFY(!(sv2 != sv1));
-}
-
-void tst_QStringView::literals() const
-{
-#if !defined(Q_OS_WIN) || defined(Q_COMPILER_UNICODE_STRINGS)
- const char16_t hello[] = u"Hello";
- const char16_t longhello[] =
- u"Hello World. This is a much longer message, to exercise qustrlen.";
- const char16_t withnull[] = u"a\0zzz";
-#else // storage_type is wchar_t
- const wchar_t hello[] = L"Hello";
- const wchar_t longhello[] =
- L"Hello World. This is a much longer message, to exercise qustrlen.";
- const wchar_t withnull[] = L"a\0zzz";
-#endif
- Q_STATIC_ASSERT(sizeof(longhello) >= 16);
-
- QCOMPARE(QStringView(hello).size(), 5);
- QCOMPARE(QStringView(hello + 0).size(), 5); // forces decay to pointer
- QStringView sv = hello;
- QCOMPARE(sv.size(), 5);
- QVERIFY(!sv.empty());
- QVERIFY(!sv.isEmpty());
- QVERIFY(!sv.isNull());
- QCOMPARE(*sv.utf16(), 'H');
- QCOMPARE(sv[0], QLatin1Char('H'));
- QCOMPARE(sv.at(0), QLatin1Char('H'));
- QCOMPARE(sv.front(), QLatin1Char('H'));
- QCOMPARE(sv.first(), QLatin1Char('H'));
- QCOMPARE(sv[4], QLatin1Char('o'));
- QCOMPARE(sv.at(4), QLatin1Char('o'));
- QCOMPARE(sv.back(), QLatin1Char('o'));
- QCOMPARE(sv.last(), QLatin1Char('o'));
-
- QStringView sv2(sv.utf16(), sv.utf16() + sv.size());
- QVERIFY(!sv2.isNull());
- QVERIFY(!sv2.empty());
- QCOMPARE(sv2.size(), 5);
-
- QStringView sv3(longhello);
- QCOMPARE(size_t(sv3.size()), sizeof(longhello)/sizeof(longhello[0]) - 1);
- QCOMPARE(sv3.last(), QLatin1Char('.'));
- sv3 = longhello;
- QCOMPARE(size_t(sv3.size()), sizeof(longhello)/sizeof(longhello[0]) - 1);
-
- for (int i = 0; i < sv3.size(); ++i) {
- QStringView sv4(longhello + i);
- QCOMPARE(size_t(sv4.size()), sizeof(longhello)/sizeof(longhello[0]) - 1 - i);
- QCOMPARE(sv4.last(), QLatin1Char('.'));
- sv4 = longhello + i;
- QCOMPARE(size_t(sv4.size()), sizeof(longhello)/sizeof(longhello[0]) - 1 - i);
- }
-
- // these are different results
- QCOMPARE(size_t(QStringView(withnull).size()), sizeof(withnull)/sizeof(withnull[0]) - 1);
- QCOMPARE(QStringView(withnull + 0).size(), 1);
-}
-
-void tst_QStringView::at() const
-{
- QString hello("Hello");
- QStringView sv(hello);
- QCOMPARE(sv.at(0), QChar('H')); QCOMPARE(sv[0], QChar('H'));
- QCOMPARE(sv.at(1), QChar('e')); QCOMPARE(sv[1], QChar('e'));
- QCOMPARE(sv.at(2), QChar('l')); QCOMPARE(sv[2], QChar('l'));
- QCOMPARE(sv.at(3), QChar('l')); QCOMPARE(sv[3], QChar('l'));
- QCOMPARE(sv.at(4), QChar('o')); QCOMPARE(sv[4], QChar('o'));
-}
-
-void tst_QStringView::fromQString() const
-{
- QString null;
- QString empty = "";
-
- QVERIFY( QStringView(null).isNull());
- QVERIFY( QStringView(null).isEmpty());
- QVERIFY( QStringView(empty).isEmpty());
- QVERIFY(!QStringView(empty).isNull());
-
- conversion_tests(QString("Hello World!"));
-}
-
-void tst_QStringView::fromQStringRef() const
-{
- QStringRef null;
- QString emptyS = "";
- QStringRef empty(&emptyS);
-
- QVERIFY( QStringView(null).isNull());
- QVERIFY( QStringView(null).isEmpty());
- QVERIFY( QStringView(empty).isEmpty());
- QVERIFY(!QStringView(empty).isNull());
-
- conversion_tests(QString("Hello World!").midRef(6));
-}
-
-template <typename Char>
-void tst_QStringView::fromLiteral(const Char *arg) const
-{
- const Char *null = nullptr;
- const Char empty[] = { 0 };
-
- QCOMPARE(QStringView(null).size(), qsizetype(0));
- QCOMPARE(QStringView(null).data(), nullptr);
- QCOMPARE(QStringView(empty).size(), qsizetype(0));
- QCOMPARE(static_cast<const void*>(QStringView(empty).data()),
- static_cast<const void*>(empty));
-
- QVERIFY( QStringView(null).isNull());
- QVERIFY( QStringView(null).isEmpty());
- QVERIFY( QStringView(empty).isEmpty());
- QVERIFY(!QStringView(empty).isNull());
-
- conversion_tests(arg);
-}
-
-template <typename Char>
-void tst_QStringView::fromRange(const Char *first, const Char *last) const
-{
- const Char *null = nullptr;
- QCOMPARE(QStringView(null, null).size(), 0);
- QCOMPARE(QStringView(null, null).data(), nullptr);
- QCOMPARE(QStringView(first, first).size(), 0);
- QCOMPARE(static_cast<const void*>(QStringView(first, first).data()),
- static_cast<const void*>(first));
-
- const auto sv = QStringView(first, last);
- QCOMPARE(sv.size(), last - first);
- QCOMPARE(static_cast<const void*>(sv.data()),
- static_cast<const void*>(first));
-
- // can't call conversion_tests() here, as it requires a single object
-}
-
-template <typename Char, typename Container>
-void tst_QStringView::fromContainer() const
-{
- const QString s = "Hello World!";
-
- Container c;
- // unspecified whether empty containers make null QStringViews
- QVERIFY(QStringView(c).isEmpty());
-
- QCOMPARE(sizeof(Char), sizeof(QChar));
-
- const auto *data = reinterpret_cast<const Char *>(s.utf16());
- std::copy(data, data + s.size(), std::back_inserter(c));
- conversion_tests(std::move(c));
-}
-
-namespace help {
-template <typename T>
-size_t size(const T &t) { return size_t(t.size()); }
-template <typename T>
-size_t size(const T *t)
-{
- size_t result = 0;
- if (t) {
- while (*t++)
- ++result;
- }
- return result;
-}
-size_t size(const QChar *t)
-{
- size_t result = 0;
- if (t) {
- while (!t++->isNull())
- ++result;
- }
- return result;
-}
-
-template <typename T>
-typename T::const_iterator cbegin(const T &t) { return t.cbegin(); }
-template <typename T>
-const T * cbegin(const T *t) { return t; }
-
-template <typename T>
-typename T::const_iterator cend(const T &t) { return t.cend(); }
-template <typename T>
-const T * cend(const T *t) { return t + size(t); }
-
-template <typename T>
-typename T::const_reverse_iterator crbegin(const T &t) { return t.crbegin(); }
-template <typename T>
-std::reverse_iterator<const T*> crbegin(const T *t) { return std::reverse_iterator<const T*>(cend(t)); }
-
-template <typename T>
-typename T::const_reverse_iterator crend(const T &t) { return t.crend(); }
-template <typename T>
-std::reverse_iterator<const T*> crend(const T *t) { return std::reverse_iterator<const T*>(cbegin(t)); }
-
-} // namespace help
-
-template <typename String>
-void tst_QStringView::conversion_tests(String string) const
-{
- // copy-construct:
- {
- QStringView sv = string;
-
- QCOMPARE(help::size(sv), help::size(string));
-
- // check iterators:
-
- QVERIFY(std::equal(help::cbegin(string), help::cend(string),
- QT_MAKE_CHECKED_ARRAY_ITERATOR(sv.cbegin(), sv.size())));
- QVERIFY(std::equal(help::cbegin(string), help::cend(string),
- QT_MAKE_CHECKED_ARRAY_ITERATOR(sv.begin(), sv.size())));
- QVERIFY(std::equal(help::crbegin(string), help::crend(string),
- sv.crbegin()));
- QVERIFY(std::equal(help::crbegin(string), help::crend(string),
- sv.rbegin()));
-
- QCOMPARE(sv, string);
- }
-
- QStringView sv;
-
- // copy-assign:
- {
- sv = string;
-
- QCOMPARE(help::size(sv), help::size(string));
-
- // check relational operators:
-
- QCOMPARE(sv, string);
- QCOMPARE(string, sv);
-
- QVERIFY(!(sv != string));
- QVERIFY(!(string != sv));
-
- QVERIFY(!(sv < string));
- QVERIFY(sv <= string);
- QVERIFY(!(sv > string));
- QVERIFY(sv >= string);
-
- QVERIFY(!(string < sv));
- QVERIFY(string <= sv);
- QVERIFY(!(string > sv));
- QVERIFY(string >= sv);
- }
-
- // copy-construct from rvalue (QStringView never assumes ownership):
- {
- QStringView sv2 = std::move(string);
- QCOMPARE(sv2, sv);
- QCOMPARE(sv2, string);
- }
-
- // copy-assign from rvalue (QStringView never assumes ownership):
- {
- QStringView sv2;
- sv2 = std::move(string);
- QCOMPARE(sv2, sv);
- QCOMPARE(sv2, string);
- }
-}
-
-void tst_QStringView::comparison()
-{
- const QStringView aa = QStringViewLiteral("aa");
- const QStringView upperAa = QStringViewLiteral("AA");
- const QStringView bb = QStringViewLiteral("bb");
-
- QVERIFY(aa == aa);
- QVERIFY(aa != bb);
- QVERIFY(aa < bb);
- QVERIFY(bb > aa);
-
- QCOMPARE(aa.compare(aa), 0);
- QVERIFY(aa.compare(upperAa) != 0);
- QCOMPARE(aa.compare(upperAa, Qt::CaseInsensitive), 0);
- QVERIFY(aa.compare(bb) < 0);
- QVERIFY(bb.compare(aa) > 0);
-}
-
-QTEST_APPLESS_MAIN(tst_QStringView)
-#include "tst_qstringview.moc"
diff --git a/tests/auto/corelib/tools/qtaggedpointer/.gitignore b/tests/auto/corelib/tools/qtaggedpointer/.gitignore
new file mode 100644
index 0000000000..d027eb73b2
--- /dev/null
+++ b/tests/auto/corelib/tools/qtaggedpointer/.gitignore
@@ -0,0 +1 @@
+tst_qtaggedpointer
diff --git a/tests/auto/corelib/tools/qtaggedpointer/CMakeLists.txt b/tests/auto/corelib/tools/qtaggedpointer/CMakeLists.txt
new file mode 100644
index 0000000000..fb2e5dc922
--- /dev/null
+++ b/tests/auto/corelib/tools/qtaggedpointer/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtaggedpointer Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtaggedpointer LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtaggedpointer
+ SOURCES
+ tst_qtaggedpointer.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp b/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp
new file mode 100644
index 0000000000..a1e61fc3a1
--- /dev/null
+++ b/tests/auto/corelib/tools/qtaggedpointer/tst_qtaggedpointer.cpp
@@ -0,0 +1,478 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtCore/qtaggedpointer.h>
+
+class tst_QTaggedPointer : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void constExpr();
+ void construction();
+ void assignment();
+ void dereferenceOperator();
+ void pointerOperator();
+ void negationOperator();
+ void operatorBool();
+ void comparison();
+ void tag();
+ void objectMember();
+ void customTagType();
+ void taggedLinkedList();
+};
+
+void tst_QTaggedPointer::constExpr()
+{
+ {
+ constexpr QTaggedPointer<int> p;
+ Q_UNUSED(p);
+ }
+ {
+ enum Foo : uint {};
+ constexpr QTaggedPointer<int, Foo> p;
+ Q_UNUSED(p);
+ }
+ {
+ enum Foo : int {};
+ constexpr QTaggedPointer<int, Foo> p;
+ Q_UNUSED(p);
+ }
+ {
+ constexpr QTaggedPointer<int> p = nullptr;
+ Q_UNUSED(p);
+ }
+ {
+ enum Foo : uint {};
+ constexpr QTaggedPointer<int, Foo> p = nullptr;
+ Q_UNUSED(p);
+ }
+ {
+ enum Foo : int {};
+ constexpr QTaggedPointer<int, Foo> p = nullptr;
+ Q_UNUSED(p);
+ }
+}
+
+void tst_QTaggedPointer::construction()
+{
+ {
+ QTaggedPointer<int> p;
+ QCOMPARE(p.data(), nullptr);
+ QVERIFY(!p.tag());
+ }
+ {
+ QTaggedPointer<int> p(nullptr, 0x1);
+ QCOMPARE(p.data(), nullptr);
+ QCOMPARE(p.tag(), quintptr(0x1));
+ }
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ QTaggedPointer<int> p(rawPointer.data());
+ QCOMPARE(p.data(), rawPointer.data());
+ QVERIFY(!p.tag());
+ }
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ QTaggedPointer<int> p(rawPointer.data(), 0x1);
+ QCOMPARE(p.data(), rawPointer.data());
+ QCOMPARE(p.tag(), quintptr(0x1));
+ }
+}
+
+void tst_QTaggedPointer::assignment()
+{
+ QScopedPointer<int> rawPointer(new int(5));
+ QTaggedPointer<int> p(rawPointer.data(), 0x1);
+ QTaggedPointer<int> p2(rawPointer.data(), 0x2);
+
+ QCOMPARE(p.data(), rawPointer.data());
+ QCOMPARE(p.tag(), quintptr(0x1));
+
+ QCOMPARE(p2.data(), rawPointer.data());
+ QCOMPARE(p2.tag(), quintptr(0x2));
+
+ p = nullptr;
+ QCOMPARE(p.data(), nullptr);
+ QCOMPARE(p.tag(), quintptr(0x1));
+
+ p = rawPointer.data();
+ QCOMPARE(p.data(), rawPointer.data());
+ QCOMPARE(p.tag(), quintptr(0x1));
+
+ p = {};
+ QCOMPARE(p.data(), nullptr);
+ QCOMPARE(p.tag(), quintptr(0x0));
+
+ p = p2;
+ QCOMPARE(p.data(), rawPointer.data());
+ QCOMPARE(p.tag(), quintptr(0x2));
+
+ p = nullptr;
+ QCOMPARE(p.data(), nullptr);
+ QCOMPARE(p.tag(), quintptr(0x2));
+
+ p = {};
+ QCOMPARE(p.data(), nullptr);
+ QCOMPARE(p.tag(), quintptr(0x0));
+
+ p = rawPointer.data();
+ QCOMPARE(p.data(), rawPointer.data());
+ QCOMPARE(p.tag(), quintptr(0x0));
+}
+
+class AbstractClass
+{
+public:
+ virtual ~AbstractClass() {}
+ virtual int member() const = 0;
+};
+
+class SubClass : public AbstractClass
+{
+public:
+ int member() const override { return 5; }
+};
+
+void tst_QTaggedPointer::dereferenceOperator()
+{
+ /* Dereference a basic value. */
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ QTaggedPointer<int> p(rawPointer.data());
+ const int value = *p;
+ QCOMPARE(value, 5);
+ }
+
+ /* Dereference a basic value with tag. */
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ QTaggedPointer<int> p(rawPointer.data(), 0x1);
+ const int value = *p;
+ QCOMPARE(value, 5);
+ }
+
+ /* Dereference a pointer to an abstract class. This verifies
+ * that the operator returns a reference, when compiling
+ * with MSVC 2005. */
+ {
+ QScopedPointer<SubClass> ptr(new SubClass());
+ QTaggedPointer<AbstractClass> p(ptr.data());
+ QCOMPARE((*p).member(), 5);
+ }
+
+ /* The operator should be const. */
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ const QTaggedPointer<int> p(rawPointer.data());
+ *p;
+ }
+
+ /* A reference should be returned, not a value. */
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ const QTaggedPointer<int> p(rawPointer.data());
+ Q_UNUSED(static_cast<int &>(*p));
+ }
+
+ /* Instantiated on a const object, the returned object is a const reference. */
+ {
+ QScopedPointer<int> rawPointer(new int(5));
+ const QTaggedPointer<const int> p(rawPointer.data());
+ Q_UNUSED(static_cast<const int &>(*p));
+ }
+}
+
+class Value
+{
+public:
+ int value;
+};
+
+void tst_QTaggedPointer::pointerOperator()
+{
+ {
+ QScopedPointer<Value> valuePtr(new Value{5});
+ QTaggedPointer<Value> p(valuePtr.data());
+ QCOMPARE(p->value, 5);
+ }
+
+ {
+ QScopedPointer<Value> valuePtr(new Value{5});
+ QTaggedPointer<Value> p(valuePtr.data(), 0x1);
+ QCOMPARE(p->value, 5);
+ }
+
+ /* The operator should be const. */
+ {
+ QScopedPointer<Value> valuePtr(new Value{5});
+ const QTaggedPointer<Value> p(valuePtr.data());
+ QVERIFY(p->value);
+ }
+}
+
+void tst_QTaggedPointer::negationOperator()
+{
+ /* Invoke on default constructed value. */
+ {
+ QTaggedPointer<int> p;
+ QVERIFY(!p);
+ }
+
+ /* Invoke on nullptr value with tag. */
+ {
+ QTaggedPointer<int> p(nullptr, 0x1);
+ QVERIFY(!p);
+ }
+
+ /* Invoke on a value. */
+ {
+ QScopedPointer<int> rawPointer(new int(2));
+ QTaggedPointer<int> p(rawPointer.data());
+ QCOMPARE(!p, false);
+ }
+
+ /* Invoke on a value with tag. */
+ {
+ QScopedPointer<int> rawPointer(new int(2));
+ QTaggedPointer<int> p(rawPointer.data(), 0x1);
+ QCOMPARE(!p, false);
+ }
+
+ /* The signature should be const. */
+ {
+ const QTaggedPointer<int> p;
+ !p;
+ }
+
+ /* The return value should be bool. */
+ {
+ const QTaggedPointer<int> p;
+ Q_UNUSED(static_cast<bool>(!p));
+ }
+}
+
+void tst_QTaggedPointer::operatorBool()
+{
+ /* Invoke on default constructed value. */
+ {
+ QTaggedPointer<int> p;
+ QCOMPARE(bool(p), false);
+ }
+
+ /* Invoke on nullptr value with tag. */
+ {
+ QTaggedPointer<int> p(nullptr, 0x1);
+ QCOMPARE(bool(p), false);
+ }
+
+ /* Invoke on active value. */
+ {
+ QScopedPointer<int> rawPointer(new int(3));
+ QTaggedPointer<int> p(rawPointer.data());
+ QVERIFY(p);
+ }
+
+ /* Invoke on active value with tag. */
+ {
+ QScopedPointer<int> rawPointer(new int(3));
+ QTaggedPointer<int> p(rawPointer.data(), 0x1);
+ QVERIFY(p);
+ }
+
+ /* The signature should be const and return bool. */
+ {
+ const QTaggedPointer<int> p;
+ (void)static_cast<bool>(p);
+ }
+}
+
+template <class A1, class A2, class B>
+void comparisonTest(const A1 &a1, const A2 &a2, const B &b)
+{
+ // test equality on equal pointers
+ QVERIFY(a1 == a2);
+ QVERIFY(a2 == a1);
+
+ // test inequality on equal pointers
+ QVERIFY(!(a1 != a2));
+ QVERIFY(!(a2 != a1));
+
+ // test equality on unequal pointers
+ QVERIFY(!(a1 == b));
+ QVERIFY(!(a2 == b));
+ QVERIFY(!(b == a1));
+ QVERIFY(!(b == a2));
+
+ // test inequality on unequal pointers
+ QVERIFY(b != a1);
+ QVERIFY(b != a2);
+ QVERIFY(a1 != b);
+ QVERIFY(a2 != b);
+}
+
+void tst_QTaggedPointer::comparison()
+{
+ QScopedPointer<int> a(new int(5));
+
+ {
+ QTaggedPointer<int> a1(a.data());
+ QTaggedPointer<int> a2(a.data());
+ QScopedPointer<int> rawPointer(new int(6));
+ QTaggedPointer<int> b(rawPointer.data());
+
+ comparisonTest(a1, a1, b);
+ comparisonTest(a2, a2, b);
+ comparisonTest(a1, a2, b);
+ }
+ {
+ QTaggedPointer<int> a1(a.data(), 0x1);
+ QTaggedPointer<int> a2(a.data(), 0x1);
+ QScopedPointer<int> rawPointer(new int(6));
+ QTaggedPointer<int> b(rawPointer.data(), 0x1);
+
+ comparisonTest(a1, a1, b);
+ comparisonTest(a2, a2, b);
+ comparisonTest(a1, a2, b);
+ }
+ {
+ QTaggedPointer<int> a1(a.data(), 0x1);
+ QTaggedPointer<int> a2(a.data(), 0x2);
+ QScopedPointer<int> rawPointer(new int(6));
+ QTaggedPointer<int> b(rawPointer.data(), 0x2);
+
+ comparisonTest(a1, a1, b);
+ comparisonTest(a2, a2, b);
+ comparisonTest(a1, a2, b);
+ }
+ {
+ QTaggedPointer<int> p;
+ QVERIFY(p.isNull());
+ QVERIFY(p == nullptr);
+ QVERIFY(nullptr == p);
+ }
+ {
+ QTaggedPointer<int> p(nullptr, 0x1);
+ QVERIFY(p.isNull());
+ QVERIFY(p == nullptr);
+ QVERIFY(nullptr == p);
+ }
+ {
+ QScopedPointer<int> rawPointer(new int(42));
+ QTaggedPointer<int> p(rawPointer.data());
+ QVERIFY(!p.isNull());
+ QVERIFY(p != nullptr);
+ QVERIFY(nullptr != p);
+ }
+ {
+ QScopedPointer<int> rawPointer(new int(42));
+ QTaggedPointer<int> p(rawPointer.data(), 0x1);
+ QVERIFY(!p.isNull());
+ QVERIFY(p != nullptr);
+ QVERIFY(nullptr != p);
+ }
+}
+
+void tst_QTaggedPointer::tag()
+{
+ QScopedPointer<int> rawPointer(new int(3));
+ QTaggedPointer<int> p(rawPointer.data());
+ QCOMPARE(*p.data(), 3);
+ QVERIFY(!p.tag());
+
+ p.setTag(0x1);
+ QCOMPARE(p.tag(), 0x1);
+
+ p.setTag(0x2);
+ QCOMPARE(p.tag(), 0x2);
+}
+
+struct Foo
+{
+ Foo() : p(nullptr) {}
+ Foo(const Foo &other) : p(other.p) {}
+ Foo &operator=(const Foo &other) {
+ p = other.p;
+ return *this;
+ }
+ QTaggedPointer<int> p;
+};
+
+void tst_QTaggedPointer::objectMember()
+{
+ QScopedPointer<int> rawPointer(new int(42));
+ Foo f;
+ f.p = QTaggedPointer<int>(rawPointer.data(), 0x1);
+
+ Foo f2(f);
+ QCOMPARE(f2.p.data(), f.p.data());
+ QCOMPARE(f2.p.tag(), f.p.tag());
+
+ Foo f3 = f;
+ QCOMPARE(f3.p.data(), f.p.data());
+ QCOMPARE(f3.p.tag(), f.p.tag());
+}
+
+class Bar
+{
+ Q_GADGET
+public:
+ enum Tag {
+ NoTag = 0,
+ FirstTag = 1,
+ SecondTag = 2
+ };
+ Q_DECLARE_FLAGS(Tags, Tag)
+ Q_FLAG(Tags)
+
+ int value;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Bar::Tags)
+
+void tst_QTaggedPointer::customTagType()
+{
+ QScopedPointer<Bar> barPtr(new Bar{5});
+ typedef QTaggedPointer<Bar, Bar::Tags> TaggedBar;
+ TaggedBar p(barPtr.data());
+ QCOMPARE(p->value, 5);
+ QVERIFY(TaggedBar::maximumTag());
+
+ QVERIFY(!p.tag());
+ QCOMPARE(p.tag(), Bar::NoTag);
+
+ p.setTag(Bar::FirstTag | Bar::SecondTag);
+ QCOMPARE(p->value, 5);
+ QCOMPARE(p.tag(), Bar::FirstTag | Bar::SecondTag);
+}
+
+// Compile-only test to ensure it's possible to use tagged pointers
+// with incomplete types.
+struct LinkedListItem
+{
+ enum Tag {
+ NoTag = 0,
+ FirstTag = 1
+ };
+ Q_DECLARE_FLAGS(Tags, Tag)
+
+ QTaggedPointer<LinkedListItem, Tag> next;
+
+ ~LinkedListItem()
+ {
+ delete next.data();
+ }
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(LinkedListItem::Tags)
+
+void tst_QTaggedPointer::taggedLinkedList()
+{
+ QScopedPointer<LinkedListItem> lli(new LinkedListItem);
+ lli->next = QTaggedPointer<LinkedListItem, LinkedListItem::Tag>(new LinkedListItem);
+ lli->next.setTag(LinkedListItem::FirstTag);
+}
+
+QTEST_MAIN(tst_QTaggedPointer)
+#include "tst_qtaggedpointer.moc"
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt
deleted file mode 100644
index d7d8f90de0..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt
+++ /dev/null
@@ -1,850 +0,0 @@
-# GraphemeBreakTest-10.0.0.txt
-# Date: 2017-04-14, 05:40:29 GMT
-# © 2017 Unicode®, Inc.
-# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
-#
-# Default Grapheme_Cluster_Break Test
-#
-# Format:
-# <string> (# <comment>)?
-# <string> contains hex Unicode code points, with
-# ÷ wherever there is a break opportunity, and
-# × wherever there is not.
-# <comment> the format can change, but currently it shows:
-# - the sample character name
-# - (x) the Grapheme_Cluster_Break property value for the sample character
-# - [x] the rule that determines whether there is a break or not,
-# as listed in the Rules section of GraphemeBreakTest.html
-#
-# These samples may be extended or changed in the future.
-#
-÷ 0020 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0020 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0020 × 0308 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0020 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0020 × 0308 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0020 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0020 × 0308 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0020 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0020 × 0308 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0020 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0020 × 0308 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0020 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0020 × 0308 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0020 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0020 × 0308 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0020 ÷ 261D ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0020 × 0308 ÷ 261D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0020 ÷ 1F3FB ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0020 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0020 ÷ 2640 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0020 × 0308 ÷ 2640 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0020 ÷ 1F466 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0020 × 0308 ÷ 1F466 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0020 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0020 × 0308 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0020 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0020 × 0308 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 000D ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SPACE (Other) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 000D ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 000D ÷ 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 000D ÷ 0308 × 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 000D ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 000D ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 000D ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 000D ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 000D ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000D ÷ 261D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000D ÷ 1F3FB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 000D ÷ 2640 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000D ÷ 1F466 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] BOY (EBG) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 000D ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 000D ÷ D800 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 000A ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Other) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 000A ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 000A ÷ 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 000A ÷ 0308 × 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 000A ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 000A ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 000A ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 000A ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 000A ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000A ÷ 261D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000A ÷ 1F3FB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 000A ÷ 2640 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000A ÷ 1F466 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] BOY (EBG) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 000A ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 000A ÷ D800 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0001 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0001 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0001 ÷ 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0001 ÷ 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0001 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0001 ÷ 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0001 ÷ 0308 × 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0001 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0001 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0001 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0001 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0001 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0001 ÷ 261D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0001 ÷ 1F3FB ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0001 ÷ 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0001 ÷ 2640 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0001 ÷ 1F466 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] BOY (EBG) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0001 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0001 ÷ D800 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0001 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0300 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0300 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0300 × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0300 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0300 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0300 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0300 × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0300 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0300 × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0300 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0300 × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0300 ÷ 261D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0300 × 0308 ÷ 261D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0300 ÷ 1F3FB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0300 ÷ 2640 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0300 × 0308 ÷ 2640 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0300 ÷ 1F466 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1F466 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0300 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0300 × 0308 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0600 × 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] SPACE (Other) ÷ [0.3]
-÷ 0600 × 0308 ÷ 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0600 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0600 × 0308 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0600 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0600 × 0308 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0600 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0600 × 0308 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0600 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0600 × 0308 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0600 × 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0600 × 0308 ÷ 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0600 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0600 × 0308 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0600 × 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0600 × 0308 ÷ 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0600 × 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0600 × 0308 ÷ 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0600 × 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0600 × 0308 ÷ 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0600 × AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0600 × 0308 ÷ AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0600 × AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0600 × 0308 ÷ AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0600 × 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0600 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0600 × 261D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0600 × 0308 ÷ 261D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0600 × 1F3FB ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0600 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0600 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0600 × 0308 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0600 × 2640 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0600 × 0308 ÷ 2640 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0600 × 1F466 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] BOY (EBG) ÷ [0.3]
-÷ 0600 × 0308 ÷ 1F466 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0600 × 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] <reserved-0378> (Other) ÷ [0.3]
-÷ 0600 × 0308 ÷ 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0600 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0600 × 0308 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0903 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0903 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0903 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0903 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0903 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0903 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0903 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0903 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0903 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0903 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0903 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0903 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0903 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0903 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0903 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0903 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0903 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0903 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0903 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0903 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0903 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0903 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0903 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0903 ÷ 261D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0903 × 0308 ÷ 261D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0903 ÷ 1F3FB ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0903 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0903 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0903 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0903 ÷ 2640 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0903 × 0308 ÷ 2640 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0903 ÷ 1F466 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0903 × 0308 ÷ 1F466 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0903 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0903 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0903 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0903 × 0308 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1100 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1100 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1100 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1100 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1100 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1100 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1100 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1100 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1100 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1100 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1100 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1100 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1100 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1100 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1100 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1100 × 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1100 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1100 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1100 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1100 × AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1100 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1100 × AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1100 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1100 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1100 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1100 ÷ 261D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1100 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1100 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1100 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1100 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1100 × 0308 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1100 ÷ 2640 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1100 × 0308 ÷ 2640 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1100 ÷ 1F466 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1100 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1100 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1100 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1100 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1100 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1160 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1160 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1160 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1160 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1160 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1160 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1160 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1160 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1160 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1160 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1160 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1160 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1160 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1160 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1160 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1160 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1160 × 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1160 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1160 × 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1160 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1160 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1160 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1160 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1160 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1160 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1160 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1160 ÷ 261D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1160 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1160 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1160 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1160 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1160 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1160 ÷ 2640 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1160 × 0308 ÷ 2640 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1160 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1160 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1160 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1160 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1160 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1160 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 11A8 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 11A8 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 11A8 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 11A8 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 11A8 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 11A8 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 11A8 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 11A8 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 11A8 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 11A8 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 11A8 × 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 11A8 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 11A8 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 11A8 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 11A8 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 11A8 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 11A8 ÷ 261D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 11A8 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 11A8 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 11A8 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 11A8 ÷ 2640 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 2640 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 11A8 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 11A8 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 11A8 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 11A8 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 11A8 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ AC00 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ AC00 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ AC00 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ AC00 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ AC00 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ AC00 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ AC00 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ AC00 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ AC00 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ AC00 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ AC00 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ AC00 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ AC00 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ AC00 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ AC00 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ AC00 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ AC00 × 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ AC00 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ AC00 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ AC00 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ AC00 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ AC00 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ AC00 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ AC00 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ AC00 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ AC00 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ AC00 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ AC00 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ AC00 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ AC00 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ AC00 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ AC00 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ AC00 ÷ 2640 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ AC00 × 0308 ÷ 2640 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ AC00 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ AC00 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ AC00 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ AC00 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ AC00 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ AC00 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ AC01 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ AC01 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ AC01 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ AC01 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ AC01 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ AC01 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ AC01 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ AC01 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ AC01 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ AC01 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ AC01 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ AC01 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ AC01 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ AC01 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ AC01 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ AC01 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ AC01 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ AC01 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ AC01 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ AC01 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ AC01 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ AC01 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ AC01 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ AC01 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ AC01 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ AC01 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ AC01 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ AC01 × 0308 ÷ 261D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ AC01 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ AC01 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ AC01 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ AC01 ÷ 2640 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ AC01 × 0308 ÷ 2640 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ AC01 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ AC01 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ AC01 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ AC01 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1F1E6 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1F1E6 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1F1E6 × 0308 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1F1E6 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F1E6 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1F1E6 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1F1E6 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1F1E6 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F1E6 ÷ 261D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 261D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F1E6 ÷ 1F3FB ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1F1E6 ÷ 2640 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 2640 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F1E6 ÷ 1F466 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1F466 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F1E6 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1F1E6 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 261D ÷ 0020 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 261D × 0308 ÷ 0020 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 261D ÷ 000D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 261D × 0308 ÷ 000D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 261D ÷ 000A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 261D × 0308 ÷ 000A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 261D ÷ 0001 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 261D × 0308 ÷ 0001 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 261D × 0300 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 261D × 0308 × 0300 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 261D ÷ 0600 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 261D × 0308 ÷ 0600 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 261D × 0903 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 261D × 0308 × 0903 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 261D ÷ 1100 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 261D × 0308 ÷ 1100 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 261D ÷ 1160 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 261D × 0308 ÷ 1160 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 261D ÷ 11A8 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 261D × 0308 ÷ 11A8 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 261D ÷ AC00 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 261D × 0308 ÷ AC00 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 261D ÷ AC01 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 261D × 0308 ÷ AC01 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 261D ÷ 1F1E6 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 261D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 261D ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 261D × 0308 ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 261D × 1F3FB ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 261D × 0308 × 1F3FB ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 261D × 200D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 261D × 0308 × 200D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 261D ÷ 2640 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 261D × 0308 ÷ 2640 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 261D ÷ 1F466 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 261D × 0308 ÷ 1F466 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 261D ÷ 0378 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 261D × 0308 ÷ 0378 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 261D ÷ D800 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 261D × 0308 ÷ D800 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1F3FB ÷ 0020 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0020 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1F3FB ÷ 000D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 000D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F3FB ÷ 000A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 000A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F3FB ÷ 0001 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0001 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1F3FB × 0300 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1F3FB × 0308 × 0300 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1F3FB ÷ 0600 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0600 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1F3FB × 0903 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1F3FB × 0308 × 0903 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1F3FB ÷ 1100 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1100 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F3FB ÷ 1160 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1160 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1F3FB ÷ 11A8 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 11A8 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1F3FB ÷ AC00 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ AC00 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1F3FB ÷ AC01 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ AC01 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1F3FB ÷ 1F1E6 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F3FB ÷ 261D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 261D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F3FB ÷ 1F3FB ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1F3FB ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F3FB × 200D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1F3FB × 0308 × 200D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1F3FB ÷ 2640 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 2640 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F3FB ÷ 1F466 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1F466 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F3FB ÷ 0378 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0378 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1F3FB ÷ D800 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ D800 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 200D ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 200D × 0308 ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 200D × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 200D × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 200D ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 200D × 0308 ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 200D ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 200D × 0308 ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 200D ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 200D × 0308 ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 200D ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 200D × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 200D ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 200D × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 200D ÷ 261D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 200D × 0308 ÷ 261D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 200D ÷ 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 0308 ÷ 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 200D × 2640 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 200D × 0308 ÷ 2640 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 200D × 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] BOY (EBG) ÷ [0.3]
-÷ 200D × 0308 ÷ 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 200D ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 200D × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 200D ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 200D × 0308 ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 2640 ÷ 0020 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0020 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 2640 ÷ 000D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 2640 × 0308 ÷ 000D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 2640 ÷ 000A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 2640 × 0308 ÷ 000A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 2640 ÷ 0001 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0001 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 2640 × 0300 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 2640 × 0308 × 0300 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 2640 ÷ 0600 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0600 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 2640 × 0903 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 2640 × 0308 × 0903 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 2640 ÷ 1100 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1100 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 2640 ÷ 1160 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1160 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 2640 ÷ 11A8 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 2640 × 0308 ÷ 11A8 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 2640 ÷ AC00 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 2640 × 0308 ÷ AC00 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 2640 ÷ AC01 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 2640 × 0308 ÷ AC01 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 2640 ÷ 1F1E6 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 2640 ÷ 261D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 2640 × 0308 ÷ 261D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 2640 ÷ 1F3FB ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 2640 × 200D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 2640 × 0308 × 200D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 2640 ÷ 2640 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 2640 × 0308 ÷ 2640 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 2640 ÷ 1F466 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1F466 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 2640 ÷ 0378 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0378 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 2640 ÷ D800 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 2640 × 0308 ÷ D800 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1F466 ÷ 0020 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0020 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1F466 ÷ 000D ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 000D ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F466 ÷ 000A ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 000A ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F466 ÷ 0001 ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0001 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 1F466 × 0300 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1F466 × 0308 × 0300 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 1F466 ÷ 0600 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0600 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 1F466 × 0903 ÷ # ÷ [0.2] BOY (EBG) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1F466 × 0308 × 0903 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 1F466 ÷ 1100 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 1100 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F466 ÷ 1160 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 1160 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 1F466 ÷ 11A8 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 11A8 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 1F466 ÷ AC00 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1F466 × 0308 ÷ AC00 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 1F466 ÷ AC01 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1F466 × 0308 ÷ AC01 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 1F466 ÷ 1F1E6 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F466 ÷ 261D ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 261D ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F466 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F466 × 0308 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F466 × 200D ÷ # ÷ [0.2] BOY (EBG) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1F466 × 0308 × 200D ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 1F466 ÷ 2640 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 2640 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F466 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F466 ÷ 0378 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0378 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 1F466 ÷ D800 ÷ # ÷ [0.2] BOY (EBG) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 1F466 × 0308 ÷ D800 ÷ # ÷ [0.2] BOY (EBG) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0378 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0378 × 0308 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0378 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0378 × 0308 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0378 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0378 × 0308 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0378 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0378 × 0308 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ 0378 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0378 × 0308 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ 0378 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0378 × 0308 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ 0378 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0378 × 0308 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ 0378 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0378 × 0308 ÷ 1100 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 0378 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0378 × 0308 ÷ 1160 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ 0378 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0378 × 0308 ÷ 11A8 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ 0378 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0378 × 0308 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ 0378 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0378 × 0308 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ 0378 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0378 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0378 ÷ 261D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0378 × 0308 ÷ 261D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0378 ÷ 1F3FB ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0378 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0378 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0378 × 0308 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0378 ÷ 2640 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0378 × 0308 ÷ 2640 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0378 ÷ 1F466 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0378 × 0308 ÷ 1F466 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0378 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0378 × 0308 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ 0378 ÷ D800 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 0378 × 0308 ÷ D800 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ D800 ÷ 0020 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ D800 ÷ 000D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ D800 ÷ 000A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ D800 ÷ 0001 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3]
-÷ D800 ÷ 0300 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ D800 ÷ 0308 × 0300 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend) ÷ [0.3]
-÷ D800 ÷ 0600 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3]
-÷ D800 ÷ 0903 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ D800 ÷ 0308 × 0903 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3]
-÷ D800 ÷ 1100 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ D800 ÷ 1160 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3]
-÷ D800 ÷ 11A8 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3]
-÷ D800 ÷ AC00 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3]
-÷ D800 ÷ AC01 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3]
-÷ D800 ÷ 1F1E6 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ D800 ÷ 261D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ D800 ÷ 1F3FB ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ D800 ÷ 200D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ D800 ÷ 0308 × 200D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ D800 ÷ 2640 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ D800 ÷ 1F466 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] BOY (EBG) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ D800 ÷ 0378 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3]
-÷ D800 ÷ D800 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ D800 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3]
-÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend) ÷ [0.3]
-÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [0.3]
-÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] ARABIC LETTER NOON (Other) ÷ [0.3]
-÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ AC00 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ AC01 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3]
-÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 200D ÷ 1F1E7 × 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ) ÷ [0.3]
-÷ 0061 × 0308 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 × 0903 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 0061 ÷ 0600 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) × [9.2] LATIN SMALL LETTER B (Other) ÷ [0.3]
-÷ 261D × 1F3FB ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F466 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 1F466 × 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] BOY (EBG) × [10.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 2640 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 200D × 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ) × [11.0] BOY (EBG) ÷ [0.3]
-÷ 1F466 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] BOY (EBG) ÷ [0.3]
-#
-# Lines: 822
-#
-# EOF
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt
deleted file mode 100644
index 6715446aba..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt
+++ /dev/null
@@ -1,7344 +0,0 @@
-# LineBreakTest-10.0.0.txt
-# Date: 2017-04-14, 05:40:30 GMT
-# © 2017 Unicode®, Inc.
-# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
-#
-# Default Line_Break Test
-#
-# Format:
-# <string> (# <comment>)?
-# <string> contains hex Unicode code points, with
-# ÷ wherever there is a break opportunity, and
-# × wherever there is not.
-# <comment> the format can change, but currently it shows:
-# - the sample character name
-# - (x) the Line_Break property value for the sample character
-# - [x] the rule that determines whether there is a break or not,
-# as listed in the Rules section of LineBreakTest.html
-#
-# Note:
-# The Line_Break tests use tailoring of numbers described in
-# Example 7 of Section 8.2, "Examples of Customization" of UAX #14.
-#
-# These samples may be extended or changed in the future.
-#
-× 0023 × 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0023 × 0020 ÷ 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0023 × 0308 × 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0023 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0023 × 0020 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0023 × 0308 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0023 × 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0023 × 0020 ÷ 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0023 × 0308 × 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0023 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0023 × 0020 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0023 × 0308 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0023 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0023 × 0020 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0023 × 0308 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0023 × 0308 × 0020 × 000B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0023 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0023 × 0020 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0023 × 0308 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0023 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0023 × 0020 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0023 × 0308 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0023 × 0308 × 0020 × 007D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0023 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0023 × 0020 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0023 × 0308 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0023 × 0308 × 0020 × 0029 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0023 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0023 × 0020 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0023 × 0308 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0023 × 0308 × 0020 × 000D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0023 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0023 × 0020 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0023 × 0308 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0023 × 0308 × 0020 × 0021 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0023 × 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0023 × 0020 ÷ 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0023 × 0308 × 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0023 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0023 × 0020 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0023 × 0308 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0023 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0023 × 0020 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0023 × 0308 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0023 × 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0023 × 0020 ÷ 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0023 × 0308 × 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0023 × 002D ÷ # × [0.3] NUMBER SIGN (AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0023 × 0020 ÷ 002D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0023 × 0308 × 002D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 002D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0023 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0023 × 0020 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0023 × 0308 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 231A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0023 × 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0023 × 0020 ÷ 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0023 × 0308 × 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0023 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] COMMA (IS) ÷ [0.3]
-× 0023 × 0020 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0023 × 0308 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0023 × 0308 × 0020 × 002C ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0023 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0023 × 0020 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0023 × 0308 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0023 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0023 × 0020 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0023 × 0308 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0023 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0023 × 0020 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0023 × 0308 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0023 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0023 × 0020 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0023 × 0308 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0023 × 0308 × 0020 × 000A ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0023 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0023 × 0020 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0023 × 0308 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0023 × 0308 × 0020 × 0085 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0023 × 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0023 × 0020 ÷ 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0023 × 0308 × 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0023 × 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0023 × 0020 ÷ 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0023 × 0308 × 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0023 × 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0023 × 0020 ÷ 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0023 × 0308 × 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0023 × 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0023 × 0020 ÷ 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0023 × 0308 × 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0023 × 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0023 × 0020 ÷ 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0023 × 0308 × 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0023 × 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0023 × 0020 ÷ 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0023 × 0308 × 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0023 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 0023 × 0020 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0023 × 0308 × 0020 × 0020 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0023 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0023 × 0020 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0023 × 0308 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0023 × 0308 × 0020 × 002F ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0023 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0023 × 0020 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0023 × 0308 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0023 × 0308 × 0020 × 2060 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0023 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0023 × 0020 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0023 × 0308 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0023 × 0308 × 0020 × 200B ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0023 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0023 × 0020 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0023 × 0308 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0023 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0023 × 0020 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0023 × 0308 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 261D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0023 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0023 × 0020 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0023 × 0308 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0023 × 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0023 × 0020 ÷ 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0023 × 0308 × 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0023 × 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0023 × 0020 ÷ 200D ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0023 × 0308 × 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 200D ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0023 × 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0023 × 0020 ÷ 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0023 × 0308 × 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0023 × 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0023 × 0020 ÷ 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0023 × 0308 × 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0023 × 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0023 × 0020 ÷ 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0023 × 0308 × 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0023 × 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0023 × 0020 ÷ 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0023 × 0308 × 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0023 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] NUMBER SIGN (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2014 ÷ 0023 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2014 × 0020 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2014 × 0308 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2014 × 2014 ÷ # × [0.3] EM DASH (B2) × [17.0] EM DASH (B2) ÷ [0.3]
-× 2014 × 0020 × 2014 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [17.0] EM DASH (B2) ÷ [0.3]
-× 2014 × 0308 × 2014 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [17.0] EM DASH (B2) ÷ [0.3]
-× 2014 × 0308 × 0020 × 2014 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [17.0] EM DASH (B2) ÷ [0.3]
-× 2014 × 0009 ÷ # × [0.3] EM DASH (B2) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2014 × 0020 ÷ 0009 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2014 × 0308 × 0009 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2014 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2014 × 0020 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2014 × 0308 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2014 × 000B ÷ # × [0.3] EM DASH (B2) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2014 × 0020 × 000B ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2014 × 0308 × 000B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2014 × 0308 × 0020 × 000B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2014 ÷ FFFC ÷ # × [0.3] EM DASH (B2) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2014 × 0020 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2014 × 0308 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2014 × 007D ÷ # × [0.3] EM DASH (B2) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2014 × 0020 × 007D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2014 × 0308 × 007D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2014 × 0308 × 0020 × 007D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2014 × 0029 ÷ # × [0.3] EM DASH (B2) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2014 × 0020 × 0029 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2014 × 0308 × 0029 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2014 × 0308 × 0020 × 0029 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2014 × 000D ÷ # × [0.3] EM DASH (B2) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2014 × 0020 × 000D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2014 × 0308 × 000D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2014 × 0308 × 0020 × 000D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2014 × 0021 ÷ # × [0.3] EM DASH (B2) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2014 × 0020 × 0021 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2014 × 0308 × 0021 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2014 × 0308 × 0020 × 0021 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2014 × 00A0 ÷ # × [0.3] EM DASH (B2) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2014 × 0020 ÷ 00A0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2014 × 0308 × 00A0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2014 ÷ AC00 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2014 × 0020 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2014 × 0308 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2014 ÷ AC01 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2014 × 0020 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2014 × 0308 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2014 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2014 × 0020 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2014 × 0308 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2014 × 002D ÷ # × [0.3] EM DASH (B2) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2014 × 0020 ÷ 002D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2014 × 0308 × 002D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 002D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2014 ÷ 231A ÷ # × [0.3] EM DASH (B2) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 2014 × 0020 ÷ 231A ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 2014 × 0308 ÷ 231A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 231A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 2014 ÷ 2024 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2014 × 0020 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2014 × 0308 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2014 × 002C ÷ # × [0.3] EM DASH (B2) × [13.02] COMMA (IS) ÷ [0.3]
-× 2014 × 0020 × 002C ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 2014 × 0308 × 002C ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 2014 × 0308 × 0020 × 002C ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 2014 ÷ 1100 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2014 × 0020 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2014 × 0308 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2014 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2014 × 0020 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2014 × 0308 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2014 ÷ 1160 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2014 × 0020 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2014 × 0308 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2014 × 000A ÷ # × [0.3] EM DASH (B2) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2014 × 0020 × 000A ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2014 × 0308 × 000A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2014 × 0308 × 0020 × 000A ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2014 × 0085 ÷ # × [0.3] EM DASH (B2) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2014 × 0020 × 0085 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2014 × 0308 × 0085 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2014 × 0308 × 0020 × 0085 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2014 × 17D6 ÷ # × [0.3] EM DASH (B2) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2014 × 0020 ÷ 17D6 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2014 × 0308 × 17D6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2014 ÷ 0030 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2014 × 0020 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2014 × 0308 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2014 ÷ 0028 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2014 × 0020 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2014 × 0308 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2014 ÷ 0025 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2014 × 0020 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2014 × 0308 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2014 ÷ 0024 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2014 × 0020 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2014 × 0308 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2014 × 0022 ÷ # × [0.3] EM DASH (B2) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 2014 × 0020 ÷ 0022 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 2014 × 0308 × 0022 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 2014 × 0020 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [0.3]
-× 2014 × 0020 × 0020 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 2014 × 0308 × 0020 × 0020 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 2014 × 002F ÷ # × [0.3] EM DASH (B2) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2014 × 0020 × 002F ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2014 × 0308 × 002F ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 2014 × 0308 × 0020 × 002F ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2014 × 2060 ÷ # × [0.3] EM DASH (B2) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2014 × 0020 × 2060 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2014 × 0308 × 2060 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2014 × 0308 × 0020 × 2060 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2014 × 200B ÷ # × [0.3] EM DASH (B2) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2014 × 0020 × 200B ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2014 × 0308 × 200B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2014 × 0308 × 0020 × 200B ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2014 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2014 × 0020 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2014 × 0308 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2014 ÷ 261D ÷ # × [0.3] EM DASH (B2) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2014 × 0020 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2014 × 0308 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 261D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2014 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2014 × 0020 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2014 × 0308 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2014 × 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2014 × 0020 ÷ 0001 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2014 × 0308 × 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2014 × 200D ÷ # × [0.3] EM DASH (B2) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2014 × 0020 ÷ 200D ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2014 × 0308 × 200D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 200D ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2014 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2014 × 0020 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2014 × 0308 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2014 ÷ 50005 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2014 × 0020 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2014 × 0308 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2014 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2014 × 0020 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2014 × 0308 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2014 × 3041 ÷ # × [0.3] EM DASH (B2) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2014 × 0020 ÷ 3041 ÷ # × [0.3] EM DASH (B2) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2014 × 0308 × 3041 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2014 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EM DASH (B2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0009 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0009 × 0020 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0009 × 0308 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0009 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0009 × 0020 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0009 × 0308 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0009 × 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0009 × 0020 ÷ 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0009 × 0308 × 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0009 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0009 × 0020 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0009 × 0308 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0009 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0009 × 0020 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0009 × 0308 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0009 × 0308 × 0020 × 000B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0009 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0009 × 0020 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0009 × 0308 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0009 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0009 × 0020 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0009 × 0308 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0009 × 0308 × 0020 × 007D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0009 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0009 × 0020 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0009 × 0308 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0009 × 0308 × 0020 × 0029 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0009 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0009 × 0020 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0009 × 0308 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0009 × 0308 × 0020 × 000D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0009 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0009 × 0020 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0009 × 0308 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0009 × 0308 × 0020 × 0021 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0009 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0009 × 0020 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0009 × 0308 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0009 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0009 × 0020 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0009 × 0308 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0009 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0009 × 0020 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0009 × 0308 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0009 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0009 × 0020 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0009 × 0308 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0009 × 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0009 × 0020 ÷ 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0009 × 0308 × 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0009 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0009 × 0020 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0009 × 0308 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 231A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0009 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0009 × 0020 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0009 × 0308 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0009 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] COMMA (IS) ÷ [0.3]
-× 0009 × 0020 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0009 × 0308 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0009 × 0308 × 0020 × 002C ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0009 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0009 × 0020 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0009 × 0308 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0009 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0009 × 0020 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0009 × 0308 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0009 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0009 × 0020 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0009 × 0308 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0009 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0009 × 0020 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0009 × 0308 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0009 × 0308 × 0020 × 000A ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0009 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0009 × 0020 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0009 × 0308 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0009 × 0308 × 0020 × 0085 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0009 × 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0009 × 0020 ÷ 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0009 × 0308 × 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0009 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0009 × 0020 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0009 × 0308 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0009 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0009 × 0020 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0009 × 0308 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0009 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0009 × 0020 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0009 × 0308 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0009 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0009 × 0020 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0009 × 0308 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0009 × 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0009 × 0020 ÷ 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0009 × 0308 × 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0009 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [0.3]
-× 0009 × 0020 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0009 × 0308 × 0020 × 0020 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0009 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0009 × 0020 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0009 × 0308 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0009 × 0308 × 0020 × 002F ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0009 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0009 × 0020 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0009 × 0308 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0009 × 0308 × 0020 × 2060 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0009 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0009 × 0020 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0009 × 0308 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0009 × 0308 × 0020 × 200B ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0009 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0009 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0009 × 0308 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0009 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0009 × 0020 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0009 × 0308 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0009 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0009 × 0020 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0009 × 0308 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0009 × 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0009 × 0020 ÷ 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0009 × 0308 × 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0009 × 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0009 × 0020 ÷ 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0009 × 0308 × 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0009 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0009 × 0020 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0009 × 0308 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0009 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0009 × 0020 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0009 × 0308 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0009 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0009 × 0020 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0009 × 0308 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0009 × 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0009 × 0020 ÷ 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0009 × 0308 × 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0009 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <CHARACTER TABULATION> (BA) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00B4 × 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] NUMBER SIGN (AL) ÷ [0.3]
-× 00B4 × 0020 ÷ 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00B4 × 0308 × 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] NUMBER SIGN (AL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00B4 × 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] EM DASH (B2) ÷ [0.3]
-× 00B4 × 0020 ÷ 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 00B4 × 0308 × 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] EM DASH (B2) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 00B4 × 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00B4 × 0020 ÷ 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00B4 × 0308 × 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00B4 × 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] ACUTE ACCENT (BB) ÷ [0.3]
-× 00B4 × 0020 ÷ 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00B4 × 0308 × 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] ACUTE ACCENT (BB) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00B4 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00B4 × 0020 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00B4 × 0308 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 000B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00B4 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00B4 × 0020 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00B4 × 0308 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00B4 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00B4 × 0020 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00B4 × 0308 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 007D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00B4 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00B4 × 0020 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00B4 × 0308 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 0029 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00B4 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00B4 × 0020 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00B4 × 0308 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 000D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00B4 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00B4 × 0020 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00B4 × 0308 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 0021 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00B4 × 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00B4 × 0020 ÷ 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00B4 × 0308 × 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00B4 × AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00B4 × 0020 ÷ AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00B4 × 0308 × AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00B4 × AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00B4 × 0020 ÷ AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00B4 × 0308 × AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00B4 × 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00B4 × 0020 ÷ 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00B4 × 0308 × 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00B4 × 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00B4 × 0020 ÷ 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00B4 × 0308 × 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 002D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00B4 × 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] WATCH (ID) ÷ [0.3]
-× 00B4 × 0020 ÷ 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 00B4 × 0308 × 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] WATCH (ID) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 231A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 00B4 × 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] ONE DOT LEADER (IN) ÷ [0.3]
-× 00B4 × 0020 ÷ 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00B4 × 0308 × 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] ONE DOT LEADER (IN) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00B4 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] COMMA (IS) ÷ [0.3]
-× 00B4 × 0020 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 00B4 × 0308 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 002C ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 00B4 × 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00B4 × 0020 ÷ 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00B4 × 0308 × 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00B4 × 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00B4 × 0020 ÷ 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00B4 × 0308 × 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00B4 × 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00B4 × 0020 ÷ 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00B4 × 0308 × 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00B4 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00B4 × 0020 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00B4 × 0308 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 000A ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00B4 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00B4 × 0020 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00B4 × 0308 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 0085 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00B4 × 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00B4 × 0020 ÷ 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00B4 × 0308 × 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00B4 × 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] DIGIT ZERO (NU) ÷ [0.3]
-× 00B4 × 0020 ÷ 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00B4 × 0308 × 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] DIGIT ZERO (NU) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00B4 × 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00B4 × 0020 ÷ 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00B4 × 0308 × 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00B4 × 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] PERCENT SIGN (PO) ÷ [0.3]
-× 00B4 × 0020 ÷ 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00B4 × 0308 × 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] PERCENT SIGN (PO) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00B4 × 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] DOLLAR SIGN (PR) ÷ [0.3]
-× 00B4 × 0020 ÷ 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00B4 × 0308 × 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] DOLLAR SIGN (PR) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00B4 × 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 00B4 × 0020 ÷ 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00B4 × 0308 × 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00B4 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [0.3]
-× 00B4 × 0020 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 0020 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 00B4 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00B4 × 0020 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00B4 × 0308 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 002F ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00B4 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00B4 × 0020 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00B4 × 0308 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 2060 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00B4 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00B4 × 0020 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00B4 × 0308 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00B4 × 0308 × 0020 × 200B ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00B4 × 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00B4 × 0020 ÷ 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00B4 × 0308 × 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00B4 × 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00B4 × 0020 ÷ 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00B4 × 0308 × 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 261D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00B4 × 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00B4 × 0020 ÷ 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00B4 × 0308 × 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00B4 × 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00B4 × 0020 ÷ 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00B4 × 0308 × 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00B4 × 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00B4 × 0020 ÷ 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00B4 × 0308 × 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 200D ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00B4 × 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00B4 × 0020 ÷ 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00B4 × 0308 × 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00B4 × 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00B4 × 0020 ÷ 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00B4 × 0308 × 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00B4 × 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00B4 × 0020 ÷ 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00B4 × 0308 × 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00B4 × 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00B4 × 0020 ÷ 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00B4 × 0308 × 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00B4 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ACUTE ACCENT (BB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000B ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000B ÷ 0308 × 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000B ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EM DASH (B2) ÷ [0.3]
-× 000B ÷ 0020 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 000B ÷ 0308 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 000B ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000B ÷ 0308 × 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000B ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000B ÷ 0020 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000B ÷ 0308 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000B ÷ 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000B ÷ 0020 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000B ÷ 0308 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 000B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000B ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000B ÷ 0020 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000B ÷ 0308 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000B ÷ 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000B ÷ 0020 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000B ÷ 0308 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 007D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000B ÷ 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000B ÷ 0020 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000B ÷ 0308 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000B ÷ 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000B ÷ 0020 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000B ÷ 0308 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 000D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000B ÷ 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000B ÷ 0020 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000B ÷ 0308 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000B ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000B ÷ 0308 × 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000B ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000B ÷ 0020 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000B ÷ 0308 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000B ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000B ÷ 0020 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000B ÷ 0308 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000B ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000B ÷ 0308 × 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000B ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000B ÷ 0020 ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000B ÷ 0308 × 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000B ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WATCH (ID) ÷ [0.3]
-× 000B ÷ 0020 ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 000B ÷ 0308 ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 000B ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000B ÷ 0020 ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000B ÷ 0308 × 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000B ÷ 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMMA (IS) ÷ [0.3]
-× 000B ÷ 0020 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 000B ÷ 0308 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 002C ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 000B ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000B ÷ 0308 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000B ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000B ÷ 0020 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000B ÷ 0308 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000B ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000B ÷ 0020 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000B ÷ 0308 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000B ÷ 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000B ÷ 0020 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000B ÷ 0308 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 000A ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000B ÷ 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000B ÷ 0020 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000B ÷ 0308 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000B ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000B ÷ 0020 ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000B ÷ 0308 × 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000B ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000B ÷ 0308 × 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000B ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000B ÷ 0308 × 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000B ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000B ÷ 0308 × 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000B ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000B ÷ 0308 × 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000B ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000B ÷ 0308 × 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000B ÷ 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [0.3]
-× 000B ÷ 0020 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 000B ÷ 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SOLIDUS (SY) ÷ [0.3]
-× 000B ÷ 0020 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 000B ÷ 0308 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 002F ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 000B ÷ 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WORD JOINER (WJ) ÷ [0.3]
-× 000B ÷ 0020 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000B ÷ 0308 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000B ÷ 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000B ÷ 0020 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000B ÷ 0308 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000B ÷ 0308 × 0020 × 200B ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000B ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000B ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000B ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000B ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000B ÷ 0020 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000B ÷ 0308 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000B ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000B ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000B ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000B ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000B ÷ 0308 × 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000B ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000B ÷ 0020 ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000B ÷ 0308 × 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000B ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000B ÷ 0308 × 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000B ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000B ÷ 0308 × 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000B ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000B ÷ 0020 ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000B ÷ 0308 × 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000B ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000B ÷ 0020 ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000B ÷ 0308 × 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000B ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× FFFC ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] NUMBER SIGN (AL) ÷ [0.3]
-× FFFC × 0020 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× FFFC × 0308 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] NUMBER SIGN (AL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0023 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× FFFC ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] EM DASH (B2) ÷ [0.3]
-× FFFC × 0020 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× FFFC × 0308 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] EM DASH (B2) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 2014 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× FFFC ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× FFFC × 0020 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× FFFC × 0308 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0009 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× FFFC ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] ACUTE ACCENT (BB) ÷ [0.3]
-× FFFC × 0020 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× FFFC × 0308 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] ACUTE ACCENT (BB) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× FFFC × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× FFFC × 0020 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× FFFC × 0308 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× FFFC × 0308 × 0020 × 000B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× FFFC ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× FFFC × 0020 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× FFFC × 0308 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ FFFC ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× FFFC × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× FFFC × 0020 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× FFFC × 0308 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× FFFC × 0308 × 0020 × 007D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× FFFC × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× FFFC × 0020 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× FFFC × 0308 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× FFFC × 0308 × 0020 × 0029 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× FFFC × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× FFFC × 0020 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× FFFC × 0308 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× FFFC × 0308 × 0020 × 000D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× FFFC × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× FFFC × 0020 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× FFFC × 0308 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× FFFC × 0308 × 0020 × 0021 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× FFFC × 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× FFFC × 0020 ÷ 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× FFFC × 0308 × 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× FFFC ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× FFFC × 0020 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× FFFC × 0308 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ AC00 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× FFFC ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× FFFC × 0020 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× FFFC × 0308 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ AC01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× FFFC ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× FFFC × 0020 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× FFFC × 0308 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× FFFC ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× FFFC × 0020 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× FFFC × 0308 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 002D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× FFFC ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] WATCH (ID) ÷ [0.3]
-× FFFC × 0020 ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× FFFC × 0308 ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] WATCH (ID) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 231A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× FFFC ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] ONE DOT LEADER (IN) ÷ [0.3]
-× FFFC × 0020 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× FFFC × 0308 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] ONE DOT LEADER (IN) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 2024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× FFFC × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] COMMA (IS) ÷ [0.3]
-× FFFC × 0020 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× FFFC × 0308 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× FFFC × 0308 × 0020 × 002C ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× FFFC ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× FFFC × 0020 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× FFFC × 0308 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 1100 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× FFFC ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× FFFC × 0020 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× FFFC × 0308 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× FFFC ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× FFFC × 0020 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× FFFC × 0308 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 1160 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× FFFC × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× FFFC × 0020 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× FFFC × 0308 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× FFFC × 0308 × 0020 × 000A ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× FFFC × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× FFFC × 0020 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× FFFC × 0308 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× FFFC × 0308 × 0020 × 0085 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× FFFC ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× FFFC × 0020 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× FFFC × 0308 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× FFFC ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] DIGIT ZERO (NU) ÷ [0.3]
-× FFFC × 0020 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× FFFC × 0308 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] DIGIT ZERO (NU) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0030 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× FFFC ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] LEFT PARENTHESIS (OP) ÷ [0.3]
-× FFFC × 0020 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× FFFC × 0308 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] LEFT PARENTHESIS (OP) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0028 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× FFFC ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] PERCENT SIGN (PO) ÷ [0.3]
-× FFFC × 0020 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× FFFC × 0308 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] PERCENT SIGN (PO) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0025 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× FFFC ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] DOLLAR SIGN (PR) ÷ [0.3]
-× FFFC × 0020 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× FFFC × 0308 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] DOLLAR SIGN (PR) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0024 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× FFFC × 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× FFFC × 0020 ÷ 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× FFFC × 0308 × 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0022 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× FFFC × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [0.3]
-× FFFC × 0020 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× FFFC × 0308 × 0020 × 0020 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× FFFC × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× FFFC × 0020 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× FFFC × 0308 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× FFFC × 0308 × 0020 × 002F ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× FFFC × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× FFFC × 0020 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× FFFC × 0308 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× FFFC × 0308 × 0020 × 2060 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× FFFC × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× FFFC × 0020 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× FFFC × 0308 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× FFFC × 0308 × 0020 × 200B ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× FFFC ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× FFFC × 0020 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× FFFC × 0308 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× FFFC ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× FFFC × 0020 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× FFFC × 0308 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 261D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× FFFC ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× FFFC × 0020 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× FFFC × 0308 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× FFFC × 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× FFFC × 0020 ÷ 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× FFFC × 0308 × 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0001 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× FFFC × 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× FFFC × 0020 ÷ 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× FFFC × 0308 × 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 200D ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× FFFC ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× FFFC × 0020 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× FFFC × 0308 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× FFFC ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× FFFC × 0020 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× FFFC × 0308 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 50005 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× FFFC ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× FFFC × 0020 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× FFFC × 0308 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× FFFC ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× FFFC × 0020 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× FFFC × 0308 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× FFFC × 0308 × 0020 ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 007D ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 007D × 0020 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 007D × 0308 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 007D ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 007D × 0020 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 007D × 0308 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 007D × 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 007D × 0020 ÷ 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 007D × 0308 × 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 007D ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 007D × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 007D × 0308 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 007D × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 007D × 0020 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 007D × 0308 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 007D × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 007D ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 007D × 0020 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 007D × 0308 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 007D × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 007D × 0020 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 007D × 0308 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 007D × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 007D × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 007D × 0020 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 007D × 0308 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 007D × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 007D × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 007D × 0020 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 007D × 0308 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 007D × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 007D × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 007D × 0020 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 007D × 0308 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 007D × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 007D × 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 007D × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 007D × 0308 × 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 007D ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 007D × 0020 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 007D × 0308 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 007D ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 007D × 0020 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 007D × 0308 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 007D ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 007D × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 007D × 0308 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 007D × 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 007D × 0020 ÷ 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 007D × 0308 × 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 007D ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 007D × 0020 ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 007D × 0308 ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 231A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 007D ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 007D × 0020 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 007D × 0308 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 007D × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] COMMA (IS) ÷ [0.3]
-× 007D × 0020 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 007D × 0308 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 007D × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 007D ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 007D × 0020 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 007D × 0308 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 007D ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 007D × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 007D × 0308 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 007D ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 007D × 0020 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 007D × 0308 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 007D × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 007D × 0020 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 007D × 0308 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 007D × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 007D × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 007D × 0020 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 007D × 0308 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 007D × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 007D × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 007D × 0020 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 007D × 0308 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 007D × 0308 × 0020 × 17D6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 007D ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 007D × 0020 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 007D × 0308 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 007D ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 007D × 0020 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 007D × 0308 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 007D ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 007D × 0020 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 007D × 0308 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 007D ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 007D × 0020 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 007D × 0308 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 007D × 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 007D × 0020 ÷ 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 007D × 0308 × 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 007D × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [0.3]
-× 007D × 0020 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 007D × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 007D × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 007D × 0020 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 007D × 0308 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 007D × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 007D × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 007D × 0020 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 007D × 0308 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 007D × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 007D × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 007D × 0020 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 007D × 0308 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 007D × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 007D ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 007D × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 007D × 0308 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 007D ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 007D × 0020 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 007D × 0308 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 007D ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 007D × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 007D × 0308 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 007D × 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 007D × 0020 ÷ 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 007D × 0308 × 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 007D × 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 007D × 0020 ÷ 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 007D × 0308 × 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 007D ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 007D × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 007D × 0308 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 007D ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 007D × 0020 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 007D × 0308 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 007D ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 007D × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 007D × 0308 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 007D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 007D × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 007D × 0020 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 007D × 0308 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 007D × 0308 × 0020 × 3041 ÷ # × [0.3] RIGHT CURLY BRACKET (CL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0029 × 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0029 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0029 × 0308 × 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0029 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0029 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0029 × 0308 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0029 × 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0029 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0029 × 0308 × 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0029 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0029 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0029 × 0308 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0029 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0029 × 0020 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0029 × 0308 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0029 × 0308 × 0020 × 000B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0029 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0029 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0029 × 0308 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0029 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0029 × 0020 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0029 × 0308 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0029 × 0308 × 0020 × 007D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0029 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0029 × 0020 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0029 × 0308 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0029 × 0308 × 0020 × 0029 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0029 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0029 × 0020 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0029 × 0308 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0029 × 0308 × 0020 × 000D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0029 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0029 × 0020 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0029 × 0308 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0029 × 0308 × 0020 × 0021 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0029 × 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0029 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0029 × 0308 × 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0029 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0029 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0029 × 0308 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0029 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0029 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0029 × 0308 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0029 × 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0029 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0029 × 0308 × 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0029 × 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0029 × 0020 ÷ 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0029 × 0308 × 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 002D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0029 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0029 × 0020 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0029 × 0308 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 231A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0029 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0029 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0029 × 0308 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0029 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0029 × 0020 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0029 × 0308 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0029 × 0308 × 0020 × 002C ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0029 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0029 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0029 × 0308 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0029 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0029 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0029 × 0308 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0029 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0029 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0029 × 0308 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0029 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0029 × 0020 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0029 × 0308 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0029 × 0308 × 0020 × 000A ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0029 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0029 × 0020 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0029 × 0308 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0029 × 0308 × 0020 × 0085 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0029 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0029 × 0020 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0029 × 0308 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0029 × 0308 × 0020 × 17D6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0029 × 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0029 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0029 × 0308 × 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0029 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0029 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0029 × 0308 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0029 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0029 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0029 × 0308 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0029 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0029 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0029 × 0308 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0029 × 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0029 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0029 × 0308 × 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0029 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0029 × 0020 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0029 × 0308 × 0020 × 0020 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0029 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0029 × 0020 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0029 × 0308 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0029 × 0308 × 0020 × 002F ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0029 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0029 × 0020 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0029 × 0308 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0029 × 0308 × 0020 × 2060 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0029 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0029 × 0020 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0029 × 0308 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0029 × 0308 × 0020 × 200B ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0029 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0029 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0029 × 0308 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0029 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0029 × 0020 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0029 × 0308 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 261D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0029 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0029 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0029 × 0308 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0029 × 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0029 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0029 × 0308 × 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0029 × 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0029 × 0020 ÷ 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0029 × 0308 × 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 200D ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0029 × 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0029 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0029 × 0308 × 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0029 × 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0029 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0029 × 0308 × 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0029 × 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [30.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0029 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0029 × 0308 × 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0029 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0029 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0029 × 0020 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0029 × 0308 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0029 × 0308 × 0020 × 3041 ÷ # × [0.3] RIGHT PARENTHESIS (CP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [16.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000D ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] NUMBER SIGN (AL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000D ÷ 0308 × 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000D ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EM DASH (B2) ÷ [0.3]
-× 000D ÷ 0020 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 000D ÷ 0308 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 000D ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000D ÷ 0308 × 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000D ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ACUTE ACCENT (BB) ÷ [0.3]
-× 000D ÷ 0020 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000D ÷ 0308 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000D ÷ 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <LINE TABULATION> (BK) ÷ [0.3]
-× 000D ÷ 0020 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000D ÷ 0308 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 000B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000D ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000D ÷ 0020 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000D ÷ 0308 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000D ÷ 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000D ÷ 0020 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000D ÷ 0308 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 007D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000D ÷ 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000D ÷ 0020 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000D ÷ 0308 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000D ÷ 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000D ÷ 0020 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000D ÷ 0308 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 000D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000D ÷ 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000D ÷ 0020 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000D ÷ 0308 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000D ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000D ÷ 0308 × 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000D ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000D ÷ 0020 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000D ÷ 0308 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000D ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000D ÷ 0020 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000D ÷ 0308 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000D ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000D ÷ 0308 × 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000D ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000D ÷ 0020 ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000D ÷ 0308 × 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000D ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WATCH (ID) ÷ [0.3]
-× 000D ÷ 0020 ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 000D ÷ 0308 ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 000D ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 000D ÷ 0020 ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000D ÷ 0308 × 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000D ÷ 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMMA (IS) ÷ [0.3]
-× 000D ÷ 0020 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 000D ÷ 0308 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 002C ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 000D ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000D ÷ 0308 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000D ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000D ÷ 0020 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000D ÷ 0308 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000D ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000D ÷ 0020 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000D ÷ 0308 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000D × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) × [5.01] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000D ÷ 0020 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000D ÷ 0308 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 000A ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000D ÷ 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000D ÷ 0020 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000D ÷ 0308 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000D ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000D ÷ 0020 ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000D ÷ 0308 × 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000D ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] DIGIT ZERO (NU) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000D ÷ 0308 × 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000D ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000D ÷ 0308 × 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000D ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] PERCENT SIGN (PO) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000D ÷ 0308 × 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000D ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] DOLLAR SIGN (PR) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000D ÷ 0308 × 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000D ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] QUOTATION MARK (QU) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000D ÷ 0308 × 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000D ÷ 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [0.3]
-× 000D ÷ 0020 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 000D ÷ 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SOLIDUS (SY) ÷ [0.3]
-× 000D ÷ 0020 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 000D ÷ 0308 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 002F ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 000D ÷ 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WORD JOINER (WJ) ÷ [0.3]
-× 000D ÷ 0020 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000D ÷ 0308 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000D ÷ 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000D ÷ 0020 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000D ÷ 0308 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000D ÷ 0308 × 0020 × 200B ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000D ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000D ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000D ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000D ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000D ÷ 0020 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000D ÷ 0308 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000D ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000D ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000D ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000D ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000D ÷ 0308 × 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000D ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000D ÷ 0020 ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000D ÷ 0308 × 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000D ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000D ÷ 0308 × 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000D ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000D ÷ 0308 × 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000D ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000D ÷ 0020 ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000D ÷ 0308 × 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000D ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000D ÷ 0020 ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000D ÷ 0308 × 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000D ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0021 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0021 × 0020 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0021 × 0308 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0021 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0021 × 0020 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0021 × 0308 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0021 × 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0021 × 0020 ÷ 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0021 × 0308 × 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0021 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0021 × 0020 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0021 × 0308 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0021 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0021 × 0020 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0021 × 0308 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0021 × 0308 × 0020 × 000B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0021 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0021 × 0020 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0021 × 0308 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0021 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0021 × 0020 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0021 × 0308 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0021 × 0308 × 0020 × 007D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0021 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0021 × 0020 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0021 × 0308 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0021 × 0308 × 0020 × 0029 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0021 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0021 × 0020 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0021 × 0308 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0021 × 0308 × 0020 × 000D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0021 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0021 × 0020 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0021 × 0308 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0021 × 0308 × 0020 × 0021 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0021 × 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0021 × 0020 ÷ 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0021 × 0308 × 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0021 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0021 × 0020 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0021 × 0308 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0021 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0021 × 0020 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0021 × 0308 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0021 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0021 × 0020 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0021 × 0308 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0021 × 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0021 × 0020 ÷ 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0021 × 0308 × 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 002D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0021 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0021 × 0020 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0021 × 0308 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 231A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0021 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [22.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 0021 × 0020 ÷ 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0021 × 0308 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0021 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] COMMA (IS) ÷ [0.3]
-× 0021 × 0020 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0021 × 0308 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0021 × 0308 × 0020 × 002C ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0021 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0021 × 0020 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0021 × 0308 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0021 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0021 × 0020 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0021 × 0308 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0021 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0021 × 0020 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0021 × 0308 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0021 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0021 × 0020 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0021 × 0308 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0021 × 0308 × 0020 × 000A ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0021 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0021 × 0020 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0021 × 0308 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0021 × 0308 × 0020 × 0085 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0021 × 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0021 × 0020 ÷ 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0021 × 0308 × 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0021 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0021 × 0020 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0021 × 0308 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0021 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0021 × 0020 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0021 × 0308 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0021 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0021 × 0020 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0021 × 0308 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0021 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0021 × 0020 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0021 × 0308 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0021 × 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0021 × 0020 ÷ 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0021 × 0308 × 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0021 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [0.3]
-× 0021 × 0020 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0021 × 0308 × 0020 × 0020 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0021 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0021 × 0020 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0021 × 0308 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0021 × 0308 × 0020 × 002F ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0021 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0021 × 0020 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0021 × 0308 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0021 × 0308 × 0020 × 2060 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0021 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0021 × 0020 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0021 × 0308 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0021 × 0308 × 0020 × 200B ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0021 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0021 × 0020 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0021 × 0308 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0021 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0021 × 0020 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0021 × 0308 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 261D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0021 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0021 × 0020 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0021 × 0308 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0021 × 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0021 × 0020 ÷ 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0021 × 0308 × 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0021 × 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0021 × 0020 ÷ 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0021 × 0308 × 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 200D ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0021 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0021 × 0020 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0021 × 0308 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0021 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0021 × 0020 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0021 × 0308 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0021 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0021 × 0020 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0021 × 0308 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0021 × 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0021 × 0020 ÷ 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0021 × 0308 × 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0021 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EXCLAMATION MARK (EX) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A0 × 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A0 × 0020 ÷ 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A0 × 0308 × 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A0 × 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EM DASH (B2) ÷ [0.3]
-× 00A0 × 0020 ÷ 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 00A0 × 0308 × 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EM DASH (B2) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 00A0 × 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A0 × 0020 ÷ 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A0 × 0308 × 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A0 × 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A0 × 0020 ÷ 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A0 × 0308 × 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A0 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A0 × 0020 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A0 × 0308 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 000B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A0 × FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A0 × 0020 ÷ FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A0 × 0308 × FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A0 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A0 × 0020 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A0 × 0308 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 007D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A0 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A0 × 0020 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A0 × 0308 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 0029 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A0 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A0 × 0020 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A0 × 0308 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 000D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A0 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A0 × 0020 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A0 × 0308 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 0021 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A0 × 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A0 × 0020 ÷ 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A0 × 0308 × 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A0 × AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A0 × 0020 ÷ AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A0 × 0308 × AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A0 × AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A0 × 0020 ÷ AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A0 × 0308 × AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A0 × 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A0 × 0020 ÷ 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A0 × 0308 × 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A0 × 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A0 × 0020 ÷ 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A0 × 0308 × 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A0 × 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] WATCH (ID) ÷ [0.3]
-× 00A0 × 0020 ÷ 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 00A0 × 0308 × 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] WATCH (ID) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 231A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 00A0 × 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A0 × 0020 ÷ 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A0 × 0308 × 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A0 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] COMMA (IS) ÷ [0.3]
-× 00A0 × 0020 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 00A0 × 0308 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] COMMA (IS) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 002C ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 00A0 × 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A0 × 0020 ÷ 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A0 × 0308 × 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A0 × 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A0 × 0020 ÷ 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A0 × 0308 × 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A0 × 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A0 × 0020 ÷ 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A0 × 0308 × 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A0 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A0 × 0020 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A0 × 0308 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 000A ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A0 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A0 × 0020 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A0 × 0308 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 0085 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A0 × 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A0 × 0020 ÷ 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A0 × 0308 × 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A0 × 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00A0 × 0020 ÷ 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00A0 × 0308 × 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00A0 × 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A0 × 0020 ÷ 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A0 × 0308 × 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A0 × 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00A0 × 0020 ÷ 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00A0 × 0308 × 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00A0 × 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A0 × 0020 ÷ 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A0 × 0308 × 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A0 × 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00A0 × 0020 ÷ 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00A0 × 0308 × 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00A0 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A0 × 0020 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 0020 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A0 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] SOLIDUS (SY) ÷ [0.3]
-× 00A0 × 0020 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00A0 × 0308 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] SOLIDUS (SY) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 002F ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00A0 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A0 × 0020 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A0 × 0308 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 2060 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A0 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A0 × 0020 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A0 × 0308 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A0 × 0308 × 0020 × 200B ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A0 × 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A0 × 0020 ÷ 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A0 × 0308 × 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A0 × 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A0 × 0020 ÷ 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A0 × 0308 × 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A0 × 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A0 × 0020 ÷ 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A0 × 0308 × 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A0 × 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A0 × 0020 ÷ 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A0 × 0308 × 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A0 × 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A0 × 0020 ÷ 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A0 × 0308 × 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A0 × 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A0 × 0020 ÷ 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A0 × 0308 × 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A0 × 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A0 × 0020 ÷ 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A0 × 0308 × 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A0 × 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A0 × 0020 ÷ 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A0 × 0308 × 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A0 × 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [12.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A0 × 0020 ÷ 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A0 × 0308 × 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] NO-BREAK SPACE (GL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC00 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC00 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC00 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC00 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× AC00 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× AC00 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× AC00 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC00 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC00 × 0308 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC00 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC00 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC00 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC00 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC00 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC00 × 0308 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC00 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC00 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC00 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC00 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC00 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC00 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC00 × 0308 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC00 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC00 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC00 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC00 × 0308 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC00 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC00 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC00 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC00 × 0308 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC00 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC00 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC00 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC00 × 0308 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC00 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC00 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC00 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC00 × 0308 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC00 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC00 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC00 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC00 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC00 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC00 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC00 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC00 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC00 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC00 × 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC00 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC00 × 0308 × 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC00 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× AC00 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× AC00 × 0308 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× AC00 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× AC00 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× AC00 × 0308 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× AC00 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] COMMA (IS) ÷ [0.3]
-× AC00 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× AC00 × 0308 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× AC00 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× AC00 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC00 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC00 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC00 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC00 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC00 × 0308 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC00 × 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC00 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC00 × 0308 × 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC00 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC00 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC00 × 0308 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC00 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC00 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC00 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC00 × 0308 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC00 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC00 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC00 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC00 × 0308 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC00 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC00 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC00 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC00 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC00 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC00 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC00 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× AC00 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× AC00 × 0308 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× AC00 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC00 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC00 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC00 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× AC00 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× AC00 × 0308 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× AC00 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [0.3]
-× AC00 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× AC00 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× AC00 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× AC00 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× AC00 × 0308 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× AC00 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× AC00 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC00 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC00 × 0308 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC00 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC00 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC00 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC00 × 0308 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC00 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC00 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC00 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC00 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC00 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC00 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC00 × 0308 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC00 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC00 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC00 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC00 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC00 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC00 × 0308 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC00 × 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC00 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC00 × 0308 × 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC00 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC00 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC00 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC00 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC00 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC00 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC00 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC00 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC00 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC00 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC00 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC00 × 0308 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC00 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GA (H2) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC01 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC01 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC01 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× AC01 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× AC01 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× AC01 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× AC01 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC01 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC01 × 0308 × 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× AC01 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC01 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC01 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× AC01 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC01 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC01 × 0308 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC01 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× AC01 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC01 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC01 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× AC01 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC01 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC01 × 0308 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC01 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× AC01 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC01 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC01 × 0308 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC01 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× AC01 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC01 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC01 × 0308 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC01 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× AC01 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC01 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC01 × 0308 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC01 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× AC01 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC01 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC01 × 0308 × 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× AC01 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC01 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC01 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× AC01 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC01 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC01 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× AC01 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC01 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC01 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× AC01 × 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC01 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC01 × 0308 × 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× AC01 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× AC01 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× AC01 × 0308 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× AC01 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× AC01 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× AC01 × 0308 × 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× AC01 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] COMMA (IS) ÷ [0.3]
-× AC01 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× AC01 × 0308 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× AC01 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× AC01 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC01 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC01 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× AC01 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC01 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC01 × 0308 × 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× AC01 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC01 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC01 × 0308 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× AC01 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC01 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC01 × 0308 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC01 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× AC01 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC01 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC01 × 0308 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC01 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× AC01 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC01 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC01 × 0308 × 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× AC01 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC01 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC01 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× AC01 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC01 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC01 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× AC01 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× AC01 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× AC01 × 0308 × 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× AC01 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC01 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC01 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× AC01 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× AC01 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× AC01 × 0308 × 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× AC01 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [0.3]
-× AC01 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× AC01 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× AC01 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× AC01 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× AC01 × 0308 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× AC01 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× AC01 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC01 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC01 × 0308 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC01 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× AC01 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC01 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC01 × 0308 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC01 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× AC01 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC01 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC01 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× AC01 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC01 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC01 × 0308 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× AC01 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC01 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC01 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× AC01 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC01 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC01 × 0308 × 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× AC01 × 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC01 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC01 × 0308 × 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× AC01 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC01 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC01 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× AC01 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC01 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC01 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× AC01 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC01 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC01 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× AC01 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC01 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC01 × 0308 × 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× AC01 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL SYLLABLE GAG (H3) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 05D0 × 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 05D0 × 0020 ÷ 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 05D0 × 0308 × 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 05D0 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 05D0 × 0020 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 05D0 × 0308 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 05D0 × 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 05D0 × 0020 ÷ 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 05D0 × 0308 × 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 05D0 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 05D0 × 0020 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 05D0 × 0308 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 05D0 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 05D0 × 0020 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 05D0 × 0308 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 000B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 05D0 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 05D0 × 0020 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 05D0 × 0308 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 05D0 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 05D0 × 0020 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 05D0 × 0308 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 007D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 05D0 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 05D0 × 0020 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 05D0 × 0308 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 0029 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 05D0 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 05D0 × 0020 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 05D0 × 0308 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 000D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 05D0 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 05D0 × 0020 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 05D0 × 0308 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 0021 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 05D0 × 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 05D0 × 0020 ÷ 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 05D0 × 0308 × 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 05D0 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 05D0 × 0020 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 05D0 × 0308 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 05D0 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 05D0 × 0020 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 05D0 × 0308 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 05D0 × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 05D0 × 0020 ÷ 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 05D0 × 0308 × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 05D0 × 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 05D0 × 0020 ÷ 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 05D0 × 0308 × 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 05D0 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 05D0 × 0020 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 05D0 × 0308 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 05D0 × 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 05D0 × 0020 ÷ 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 05D0 × 0308 × 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 05D0 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] COMMA (IS) ÷ [0.3]
-× 05D0 × 0020 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 05D0 × 0308 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 002C ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 05D0 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 05D0 × 0020 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 05D0 × 0308 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 05D0 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 05D0 × 0020 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 05D0 × 0308 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 05D0 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 05D0 × 0020 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 05D0 × 0308 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 05D0 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 05D0 × 0020 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 05D0 × 0308 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 000A ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 05D0 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 05D0 × 0020 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 05D0 × 0308 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 0085 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 05D0 × 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 05D0 × 0020 ÷ 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 05D0 × 0308 × 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 05D0 × 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 05D0 × 0020 ÷ 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 05D0 × 0308 × 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 05D0 × 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 05D0 × 0020 ÷ 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 05D0 × 0308 × 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 05D0 × 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 05D0 × 0020 ÷ 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 05D0 × 0308 × 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 05D0 × 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 05D0 × 0020 ÷ 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 05D0 × 0308 × 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 05D0 × 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 05D0 × 0020 ÷ 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 05D0 × 0308 × 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 05D0 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [0.3]
-× 05D0 × 0020 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 0020 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 05D0 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 05D0 × 0020 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 05D0 × 0308 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 002F ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 05D0 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 05D0 × 0020 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 05D0 × 0308 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 2060 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 05D0 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 05D0 × 0020 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 05D0 × 0308 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 05D0 × 0308 × 0020 × 200B ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 05D0 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 05D0 × 0020 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 05D0 × 0308 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 05D0 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 05D0 × 0020 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 05D0 × 0308 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 05D0 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 05D0 × 0020 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 05D0 × 0308 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 05D0 × 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 05D0 × 0020 ÷ 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 05D0 × 0308 × 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 05D0 × 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 05D0 × 0020 ÷ 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 05D0 × 0308 × 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 05D0 × 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 05D0 × 0020 ÷ 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 05D0 × 0308 × 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 05D0 × 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 05D0 × 0020 ÷ 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 05D0 × 0308 × 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 05D0 × 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 05D0 × 0020 ÷ 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 05D0 × 0308 × 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 05D0 × 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 05D0 × 0020 ÷ 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 05D0 × 0308 × 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 05D0 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002D ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002D × 0020 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002D × 0308 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002D ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 002D × 0020 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 002D × 0308 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 002D × 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002D × 0020 ÷ 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002D × 0308 × 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002D ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002D × 0020 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002D × 0308 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002D × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002D × 0020 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002D × 0308 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002D × 0308 × 0020 × 000B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002D ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002D × 0020 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002D × 0308 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002D × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002D × 0020 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002D × 0308 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002D × 0308 × 0020 × 007D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002D × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002D × 0020 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002D × 0308 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002D × 0308 × 0020 × 0029 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002D × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002D × 0020 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002D × 0308 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002D × 0308 × 0020 × 000D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002D × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002D × 0020 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002D × 0308 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002D × 0308 × 0020 × 0021 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002D ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002D × 0020 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002D × 0308 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002D ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002D × 0020 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002D × 0308 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002D ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002D × 0020 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002D × 0308 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002D ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002D × 0020 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002D × 0308 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002D × 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002D × 0020 ÷ 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002D × 0308 × 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 002D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002D ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 002D × 0020 ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 002D × 0308 ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 231A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 002D ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002D × 0020 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002D × 0308 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002D × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] COMMA (IS) ÷ [0.3]
-× 002D × 0020 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 002D × 0308 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 002D × 0308 × 0020 × 002C ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 002D ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002D × 0020 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002D × 0308 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002D ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002D × 0020 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002D × 0308 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002D ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002D × 0020 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002D × 0308 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002D × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002D × 0020 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002D × 0308 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002D × 0308 × 0020 × 000A ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002D × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002D × 0020 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002D × 0308 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002D × 0308 × 0020 × 0085 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002D × 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002D × 0020 ÷ 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002D × 0308 × 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002D × 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [25.02] DIGIT ZERO (NU) ÷ [0.3]
-× 002D × 0020 ÷ 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002D × 0308 × 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.02] DIGIT ZERO (NU) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002D ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002D × 0020 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002D × 0308 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002D ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002D × 0020 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002D × 0308 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002D ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002D × 0020 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002D × 0308 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002D × 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 002D × 0020 ÷ 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 002D × 0308 × 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 002D × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [0.3]
-× 002D × 0020 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 002D × 0308 × 0020 × 0020 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002D × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002D × 0020 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002D × 0308 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 002D × 0308 × 0020 × 002F ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002D × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002D × 0020 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002D × 0308 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002D × 0308 × 0020 × 2060 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002D × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002D × 0020 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002D × 0308 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002D × 0308 × 0020 × 200B ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002D ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002D × 0020 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002D × 0308 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002D ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002D × 0020 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002D × 0308 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 261D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002D ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002D × 0020 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002D × 0308 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002D × 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002D × 0020 ÷ 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002D × 0308 × 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002D × 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002D × 0020 ÷ 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002D × 0308 × 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 200D ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002D ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002D × 0020 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002D × 0308 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002D ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002D × 0020 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002D × 0308 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002D ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002D × 0020 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002D × 0308 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002D × 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002D × 0020 ÷ 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002D × 0308 × 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HYPHEN-MINUS (HY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 231A ÷ 0023 ÷ # × [0.3] WATCH (ID) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 231A × 0020 ÷ 0023 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 231A × 0308 ÷ 0023 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 231A ÷ 2014 ÷ # × [0.3] WATCH (ID) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 231A × 0020 ÷ 2014 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 231A × 0308 ÷ 2014 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 231A × 0009 ÷ # × [0.3] WATCH (ID) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 231A × 0020 ÷ 0009 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 231A × 0308 × 0009 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 231A ÷ 00B4 ÷ # × [0.3] WATCH (ID) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 231A × 0020 ÷ 00B4 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 231A × 0308 ÷ 00B4 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 231A × 000B ÷ # × [0.3] WATCH (ID) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 231A × 0020 × 000B ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 231A × 0308 × 000B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 231A × 0308 × 0020 × 000B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 231A ÷ FFFC ÷ # × [0.3] WATCH (ID) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 231A × 0020 ÷ FFFC ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 231A × 0308 ÷ FFFC ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 231A × 007D ÷ # × [0.3] WATCH (ID) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 231A × 0020 × 007D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 231A × 0308 × 007D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 231A × 0308 × 0020 × 007D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 231A × 0029 ÷ # × [0.3] WATCH (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 231A × 0020 × 0029 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 231A × 0308 × 0029 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 231A × 0308 × 0020 × 0029 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 231A × 000D ÷ # × [0.3] WATCH (ID) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 231A × 0020 × 000D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 231A × 0308 × 000D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 231A × 0308 × 0020 × 000D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 231A × 0021 ÷ # × [0.3] WATCH (ID) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 231A × 0020 × 0021 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 231A × 0308 × 0021 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 231A × 0308 × 0020 × 0021 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 231A × 00A0 ÷ # × [0.3] WATCH (ID) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 231A × 0020 ÷ 00A0 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 231A × 0308 × 00A0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 231A ÷ AC00 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 231A × 0020 ÷ AC00 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 231A × 0308 ÷ AC00 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 231A ÷ AC01 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 231A × 0020 ÷ AC01 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 231A × 0308 ÷ AC01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 231A ÷ 05D0 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 231A × 0020 ÷ 05D0 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 231A × 0308 ÷ 05D0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 231A × 002D ÷ # × [0.3] WATCH (ID) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 231A × 0020 ÷ 002D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 231A × 0308 × 002D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 002D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 231A ÷ 231A ÷ # × [0.3] WATCH (ID) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 231A × 0020 ÷ 231A ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 231A × 0308 ÷ 231A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 231A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 231A × 2024 ÷ # × [0.3] WATCH (ID) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 231A × 0020 ÷ 2024 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 231A × 0308 × 2024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 231A × 002C ÷ # × [0.3] WATCH (ID) × [13.02] COMMA (IS) ÷ [0.3]
-× 231A × 0020 × 002C ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 231A × 0308 × 002C ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 231A × 0308 × 0020 × 002C ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 231A ÷ 1100 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 231A × 0020 ÷ 1100 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 231A × 0308 ÷ 1100 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 231A ÷ 11A8 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 231A × 0020 ÷ 11A8 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 231A × 0308 ÷ 11A8 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 231A ÷ 1160 ÷ # × [0.3] WATCH (ID) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 231A × 0020 ÷ 1160 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 231A × 0308 ÷ 1160 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 231A × 000A ÷ # × [0.3] WATCH (ID) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 231A × 0020 × 000A ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 231A × 0308 × 000A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 231A × 0308 × 0020 × 000A ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 231A × 0085 ÷ # × [0.3] WATCH (ID) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 231A × 0020 × 0085 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 231A × 0308 × 0085 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 231A × 0308 × 0020 × 0085 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 231A × 17D6 ÷ # × [0.3] WATCH (ID) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 231A × 0020 ÷ 17D6 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 231A × 0308 × 17D6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 231A ÷ 0030 ÷ # × [0.3] WATCH (ID) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 231A × 0020 ÷ 0030 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 231A × 0308 ÷ 0030 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 231A ÷ 0028 ÷ # × [0.3] WATCH (ID) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 231A × 0020 ÷ 0028 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 231A × 0308 ÷ 0028 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 231A × 0025 ÷ # × [0.3] WATCH (ID) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 231A × 0020 ÷ 0025 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 231A × 0308 × 0025 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 231A ÷ 0024 ÷ # × [0.3] WATCH (ID) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 231A × 0020 ÷ 0024 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 231A × 0308 ÷ 0024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 231A × 0022 ÷ # × [0.3] WATCH (ID) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 231A × 0020 ÷ 0022 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 231A × 0308 × 0022 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 231A × 0020 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [0.3]
-× 231A × 0020 × 0020 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 231A × 0308 × 0020 × 0020 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 231A × 002F ÷ # × [0.3] WATCH (ID) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 231A × 0020 × 002F ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 231A × 0308 × 002F ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 231A × 0308 × 0020 × 002F ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 231A × 2060 ÷ # × [0.3] WATCH (ID) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 231A × 0020 × 2060 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 231A × 0308 × 2060 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 231A × 0308 × 0020 × 2060 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 231A × 200B ÷ # × [0.3] WATCH (ID) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 231A × 0020 × 200B ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 231A × 0308 × 200B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 231A × 0308 × 0020 × 200B ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 231A ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 231A × 0020 ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 231A × 0308 ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 231A ÷ 261D ÷ # × [0.3] WATCH (ID) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 231A × 0020 ÷ 261D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 231A × 0308 ÷ 261D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 261D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 231A ÷ 1F3FB ÷ # × [0.3] WATCH (ID) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 231A × 0020 ÷ 1F3FB ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 231A × 0308 ÷ 1F3FB ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 231A × 0001 ÷ # × [0.3] WATCH (ID) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 231A × 0020 ÷ 0001 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 231A × 0308 × 0001 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 231A × 200D ÷ # × [0.3] WATCH (ID) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 231A × 0020 ÷ 200D ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 231A × 0308 × 200D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 200D ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 231A ÷ 00A7 ÷ # × [0.3] WATCH (ID) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 231A × 0020 ÷ 00A7 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 231A × 0308 ÷ 00A7 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 231A ÷ 50005 ÷ # × [0.3] WATCH (ID) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 231A × 0020 ÷ 50005 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 231A × 0308 ÷ 50005 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 231A ÷ 0E01 ÷ # × [0.3] WATCH (ID) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 231A × 0020 ÷ 0E01 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 231A × 0308 ÷ 0E01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 231A × 3041 ÷ # × [0.3] WATCH (ID) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 231A × 0020 ÷ 3041 ÷ # × [0.3] WATCH (ID) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 231A × 0308 × 3041 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 231A × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WATCH (ID) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2024 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2024 × 0020 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2024 × 0308 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2024 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 2024 × 0020 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 2024 × 0308 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 2024 × 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2024 × 0020 ÷ 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2024 × 0308 × 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2024 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2024 × 0020 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2024 × 0308 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2024 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2024 × 0020 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2024 × 0308 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2024 × 0308 × 0020 × 000B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2024 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2024 × 0020 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2024 × 0308 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2024 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2024 × 0020 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2024 × 0308 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2024 × 0308 × 0020 × 007D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2024 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2024 × 0020 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2024 × 0308 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2024 × 0308 × 0020 × 0029 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2024 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2024 × 0020 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2024 × 0308 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2024 × 0308 × 0020 × 000D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2024 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2024 × 0020 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2024 × 0308 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2024 × 0308 × 0020 × 0021 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2024 × 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2024 × 0020 ÷ 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2024 × 0308 × 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2024 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2024 × 0020 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2024 × 0308 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2024 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2024 × 0020 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2024 × 0308 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2024 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2024 × 0020 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2024 × 0308 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2024 × 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2024 × 0020 ÷ 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2024 × 0308 × 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 002D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2024 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 2024 × 0020 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 2024 × 0308 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 231A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 2024 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [22.04] ONE DOT LEADER (IN) ÷ [0.3]
-× 2024 × 0020 ÷ 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2024 × 0308 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.04] ONE DOT LEADER (IN) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2024 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] COMMA (IS) ÷ [0.3]
-× 2024 × 0020 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 2024 × 0308 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 2024 × 0308 × 0020 × 002C ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 2024 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2024 × 0020 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2024 × 0308 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2024 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2024 × 0020 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2024 × 0308 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2024 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2024 × 0020 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2024 × 0308 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2024 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2024 × 0020 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2024 × 0308 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2024 × 0308 × 0020 × 000A ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2024 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2024 × 0020 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2024 × 0308 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2024 × 0308 × 0020 × 0085 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2024 × 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2024 × 0020 ÷ 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2024 × 0308 × 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2024 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2024 × 0020 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2024 × 0308 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2024 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2024 × 0020 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2024 × 0308 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2024 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2024 × 0020 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2024 × 0308 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2024 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2024 × 0020 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2024 × 0308 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2024 × 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 2024 × 0020 ÷ 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 2024 × 0308 × 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 2024 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [0.3]
-× 2024 × 0020 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 2024 × 0308 × 0020 × 0020 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 2024 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2024 × 0020 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2024 × 0308 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 2024 × 0308 × 0020 × 002F ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2024 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2024 × 0020 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2024 × 0308 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2024 × 0308 × 0020 × 2060 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2024 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2024 × 0020 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2024 × 0308 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2024 × 0308 × 0020 × 200B ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2024 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2024 × 0020 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2024 × 0308 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2024 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2024 × 0020 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2024 × 0308 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 261D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2024 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2024 × 0020 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2024 × 0308 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2024 × 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2024 × 0020 ÷ 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2024 × 0308 × 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2024 × 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2024 × 0020 ÷ 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2024 × 0308 × 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 200D ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2024 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2024 × 0020 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2024 × 0308 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2024 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2024 × 0020 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2024 × 0308 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2024 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2024 × 0020 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2024 × 0308 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2024 × 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2024 × 0020 ÷ 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2024 × 0308 × 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2024 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ONE DOT LEADER (IN) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002C × 0023 ÷ # × [0.3] COMMA (IS) × [29.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002C × 0020 ÷ 0023 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002C × 0308 × 0023 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0023 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002C ÷ 2014 ÷ # × [0.3] COMMA (IS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 002C × 0020 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 002C × 0308 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 2014 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 002C × 0009 ÷ # × [0.3] COMMA (IS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002C × 0020 ÷ 0009 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002C × 0308 × 0009 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0009 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002C ÷ 00B4 ÷ # × [0.3] COMMA (IS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002C × 0020 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002C × 0308 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002C × 000B ÷ # × [0.3] COMMA (IS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002C × 0020 × 000B ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002C × 0308 × 000B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002C × 0308 × 0020 × 000B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002C ÷ FFFC ÷ # × [0.3] COMMA (IS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002C × 0020 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002C × 0308 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ FFFC ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002C × 007D ÷ # × [0.3] COMMA (IS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002C × 0020 × 007D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002C × 0308 × 007D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002C × 0308 × 0020 × 007D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002C × 0029 ÷ # × [0.3] COMMA (IS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002C × 0020 × 0029 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002C × 0308 × 0029 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002C × 0308 × 0020 × 0029 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002C × 000D ÷ # × [0.3] COMMA (IS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002C × 0020 × 000D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002C × 0308 × 000D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002C × 0308 × 0020 × 000D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002C × 0021 ÷ # × [0.3] COMMA (IS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002C × 0020 × 0021 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002C × 0308 × 0021 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002C × 0308 × 0020 × 0021 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002C × 00A0 ÷ # × [0.3] COMMA (IS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002C × 0020 ÷ 00A0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002C × 0308 × 00A0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002C ÷ AC00 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002C × 0020 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002C × 0308 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ AC00 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002C ÷ AC01 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002C × 0020 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002C × 0308 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ AC01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002C × 05D0 ÷ # × [0.3] COMMA (IS) × [29.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002C × 0020 ÷ 05D0 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002C × 0308 × 05D0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002C × 002D ÷ # × [0.3] COMMA (IS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002C × 0020 ÷ 002D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002C × 0308 × 002D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 002D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002C ÷ 231A ÷ # × [0.3] COMMA (IS) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 002C × 0020 ÷ 231A ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 002C × 0308 ÷ 231A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 231A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 002C ÷ 2024 ÷ # × [0.3] COMMA (IS) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002C × 0020 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002C × 0308 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 2024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002C × 002C ÷ # × [0.3] COMMA (IS) × [13.02] COMMA (IS) ÷ [0.3]
-× 002C × 0020 × 002C ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 002C × 0308 × 002C ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 002C × 0308 × 0020 × 002C ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 002C ÷ 1100 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002C × 0020 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002C × 0308 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 1100 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002C ÷ 11A8 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002C × 0020 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002C × 0308 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002C ÷ 1160 ÷ # × [0.3] COMMA (IS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002C × 0020 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002C × 0308 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 1160 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002C × 000A ÷ # × [0.3] COMMA (IS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002C × 0020 × 000A ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002C × 0308 × 000A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002C × 0308 × 0020 × 000A ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002C × 0085 ÷ # × [0.3] COMMA (IS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002C × 0020 × 0085 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002C × 0308 × 0085 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002C × 0308 × 0020 × 0085 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002C × 17D6 ÷ # × [0.3] COMMA (IS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002C × 0020 ÷ 17D6 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002C × 0308 × 17D6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002C ÷ 0030 ÷ # × [0.3] COMMA (IS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002C × 0020 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002C × 0308 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0030 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002C ÷ 0028 ÷ # × [0.3] COMMA (IS) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002C × 0020 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002C × 0308 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0028 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002C ÷ 0025 ÷ # × [0.3] COMMA (IS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002C × 0020 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002C × 0308 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0025 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002C ÷ 0024 ÷ # × [0.3] COMMA (IS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002C × 0020 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002C × 0308 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0024 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002C × 0022 ÷ # × [0.3] COMMA (IS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 002C × 0020 ÷ 0022 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 002C × 0308 × 0022 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0022 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 002C × 0020 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [0.3]
-× 002C × 0020 × 0020 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 002C × 0308 × 0020 × 0020 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002C × 002F ÷ # × [0.3] COMMA (IS) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002C × 0020 × 002F ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002C × 0308 × 002F ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 002C × 0308 × 0020 × 002F ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002C × 2060 ÷ # × [0.3] COMMA (IS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002C × 0020 × 2060 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002C × 0308 × 2060 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002C × 0308 × 0020 × 2060 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002C × 200B ÷ # × [0.3] COMMA (IS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002C × 0020 × 200B ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002C × 0308 × 200B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002C × 0308 × 0020 × 200B ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002C ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002C × 0020 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002C × 0308 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002C ÷ 261D ÷ # × [0.3] COMMA (IS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002C × 0020 ÷ 261D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002C × 0308 ÷ 261D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 261D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002C ÷ 1F3FB ÷ # × [0.3] COMMA (IS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002C × 0020 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002C × 0308 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002C × 0001 ÷ # × [0.3] COMMA (IS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002C × 0020 ÷ 0001 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002C × 0308 × 0001 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0001 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002C × 200D ÷ # × [0.3] COMMA (IS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002C × 0020 ÷ 200D ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002C × 0308 × 200D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 200D ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002C × 00A7 ÷ # × [0.3] COMMA (IS) × [29.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002C × 0020 ÷ 00A7 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002C × 0308 × 00A7 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002C × 50005 ÷ # × [0.3] COMMA (IS) × [29.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002C × 0020 ÷ 50005 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002C × 0308 × 50005 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 50005 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002C × 0E01 ÷ # × [0.3] COMMA (IS) × [29.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002C × 0020 ÷ 0E01 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002C × 0308 × 0E01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [29.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002C × 3041 ÷ # × [0.3] COMMA (IS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002C × 0020 ÷ 3041 ÷ # × [0.3] COMMA (IS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002C × 0308 × 3041 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002C × 0308 × 0020 ÷ 3041 ÷ # × [0.3] COMMA (IS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1100 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1100 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1100 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1100 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1100 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1100 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1100 × 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1100 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1100 × 0308 × 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1100 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1100 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1100 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1100 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1100 × 0020 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1100 × 0308 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1100 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1100 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1100 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1100 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1100 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1100 × 0020 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1100 × 0308 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1100 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1100 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1100 × 0020 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1100 × 0308 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1100 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1100 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1100 × 0020 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1100 × 0308 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1100 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1100 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1100 × 0020 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1100 × 0308 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1100 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1100 × 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1100 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1100 × 0308 × 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1100 × AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1100 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1100 × 0308 × AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1100 × AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1100 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1100 × 0308 × AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1100 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1100 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1100 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1100 × 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1100 × 0020 ÷ 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1100 × 0308 × 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1100 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1100 × 0020 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1100 × 0308 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1100 × 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 1100 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1100 × 0308 × 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1100 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] COMMA (IS) ÷ [0.3]
-× 1100 × 0020 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1100 × 0308 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 1100 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1100 × 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1100 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1100 × 0308 × 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1100 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1100 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1100 × 0308 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1100 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1100 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1100 × 0308 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1100 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1100 × 0020 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1100 × 0308 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1100 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1100 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1100 × 0020 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1100 × 0308 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1100 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1100 × 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1100 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1100 × 0308 × 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1100 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1100 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1100 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1100 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1100 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1100 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1100 × 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 1100 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1100 × 0308 × 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1100 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1100 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1100 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1100 × 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1100 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1100 × 0308 × 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1100 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [0.3]
-× 1100 × 0020 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 1100 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1100 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1100 × 0020 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1100 × 0308 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 1100 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1100 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1100 × 0020 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1100 × 0308 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1100 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1100 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1100 × 0020 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1100 × 0308 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1100 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1100 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1100 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1100 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1100 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1100 × 0020 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1100 × 0308 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1100 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1100 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1100 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1100 × 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1100 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1100 × 0308 × 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1100 × 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1100 × 0020 ÷ 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1100 × 0308 × 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1100 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1100 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1100 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1100 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1100 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1100 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1100 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1100 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1100 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1100 × 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1100 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1100 × 0308 × 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1100 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 11A8 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 11A8 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 11A8 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 11A8 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 11A8 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 11A8 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 11A8 × 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 11A8 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 11A8 × 0308 × 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 11A8 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 11A8 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 11A8 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 11A8 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 11A8 × 0020 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 11A8 × 0308 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 11A8 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 11A8 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 11A8 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 11A8 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 11A8 × 0020 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 11A8 × 0308 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 11A8 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 11A8 × 0020 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 11A8 × 0308 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 11A8 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 11A8 × 0020 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 11A8 × 0308 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 11A8 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 11A8 × 0020 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 11A8 × 0308 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 11A8 × 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 11A8 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 11A8 × 0308 × 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 11A8 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 11A8 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 11A8 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 11A8 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 11A8 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 11A8 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 11A8 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 11A8 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 11A8 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 11A8 × 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 11A8 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 11A8 × 0308 × 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 11A8 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 11A8 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 11A8 × 0308 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 11A8 × 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 11A8 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 11A8 × 0308 × 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 11A8 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] COMMA (IS) ÷ [0.3]
-× 11A8 × 0020 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 11A8 × 0308 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 11A8 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 11A8 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 11A8 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 11A8 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 11A8 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 11A8 × 0308 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 11A8 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 11A8 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 11A8 × 0308 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 11A8 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 11A8 × 0020 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 11A8 × 0308 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 11A8 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 11A8 × 0020 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 11A8 × 0308 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 11A8 × 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 11A8 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 11A8 × 0308 × 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 11A8 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 11A8 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 11A8 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 11A8 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 11A8 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 11A8 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 11A8 × 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 11A8 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 11A8 × 0308 × 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 11A8 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 11A8 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 11A8 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 11A8 × 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 11A8 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 11A8 × 0308 × 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 11A8 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [0.3]
-× 11A8 × 0020 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 11A8 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 11A8 × 0020 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 11A8 × 0308 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 11A8 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 11A8 × 0020 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 11A8 × 0308 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 11A8 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 11A8 × 0020 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 11A8 × 0308 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 11A8 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 11A8 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 11A8 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 11A8 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 11A8 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 11A8 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 11A8 × 0308 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 11A8 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 11A8 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 11A8 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 11A8 × 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 11A8 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 11A8 × 0308 × 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 11A8 × 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 11A8 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 11A8 × 0308 × 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 11A8 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 11A8 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 11A8 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 11A8 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 11A8 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 11A8 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 11A8 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 11A8 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 11A8 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 11A8 × 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 11A8 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 11A8 × 0308 × 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 11A8 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1160 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1160 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1160 × 0308 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1160 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1160 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1160 × 0308 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1160 × 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1160 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1160 × 0308 × 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1160 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1160 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1160 × 0308 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1160 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1160 × 0020 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1160 × 0308 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1160 × 0308 × 0020 × 000B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1160 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1160 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1160 × 0308 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1160 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1160 × 0020 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1160 × 0308 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1160 × 0308 × 0020 × 007D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1160 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1160 × 0020 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1160 × 0308 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1160 × 0308 × 0020 × 0029 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1160 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1160 × 0020 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1160 × 0308 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1160 × 0308 × 0020 × 000D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1160 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1160 × 0020 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1160 × 0308 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1160 × 0308 × 0020 × 0021 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1160 × 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1160 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1160 × 0308 × 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1160 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1160 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1160 × 0308 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1160 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1160 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1160 × 0308 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1160 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1160 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1160 × 0308 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1160 × 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1160 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1160 × 0308 × 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1160 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1160 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1160 × 0308 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1160 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 1160 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1160 × 0308 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1160 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] COMMA (IS) ÷ [0.3]
-× 1160 × 0020 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1160 × 0308 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 1160 × 0308 × 0020 × 002C ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1160 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1160 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1160 × 0308 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1160 × 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1160 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1160 × 0308 × 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1160 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1160 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1160 × 0308 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1160 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1160 × 0020 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1160 × 0308 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1160 × 0308 × 0020 × 000A ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1160 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1160 × 0020 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1160 × 0308 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1160 × 0308 × 0020 × 0085 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1160 × 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1160 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1160 × 0308 × 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1160 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1160 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1160 × 0308 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1160 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1160 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1160 × 0308 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1160 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 1160 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1160 × 0308 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1160 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1160 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1160 × 0308 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1160 × 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1160 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1160 × 0308 × 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1160 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [0.3]
-× 1160 × 0020 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 1160 × 0308 × 0020 × 0020 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1160 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1160 × 0020 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1160 × 0308 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 1160 × 0308 × 0020 × 002F ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1160 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1160 × 0020 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1160 × 0308 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1160 × 0308 × 0020 × 2060 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1160 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1160 × 0020 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1160 × 0308 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1160 × 0308 × 0020 × 200B ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1160 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1160 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1160 × 0308 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1160 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1160 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1160 × 0308 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1160 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1160 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1160 × 0308 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1160 × 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1160 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1160 × 0308 × 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1160 × 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1160 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1160 × 0308 × 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1160 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1160 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1160 × 0308 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1160 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1160 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1160 × 0308 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1160 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1160 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1160 × 0308 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1160 × 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1160 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1160 × 0308 × 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1160 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000A ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] NUMBER SIGN (AL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000A ÷ 0308 × 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 000A ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EM DASH (B2) ÷ [0.3]
-× 000A ÷ 0020 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 000A ÷ 0308 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 000A ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000A ÷ 0308 × 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 000A ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ACUTE ACCENT (BB) ÷ [0.3]
-× 000A ÷ 0020 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000A ÷ 0308 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 000A ÷ 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <LINE TABULATION> (BK) ÷ [0.3]
-× 000A ÷ 0020 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000A ÷ 0308 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 000B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 000A ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000A ÷ 0020 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000A ÷ 0308 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 000A ÷ 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000A ÷ 0020 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000A ÷ 0308 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 007D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 000A ÷ 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000A ÷ 0020 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000A ÷ 0308 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 000A ÷ 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000A ÷ 0020 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000A ÷ 0308 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 000D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 000A ÷ 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000A ÷ 0020 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000A ÷ 0308 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 000A ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000A ÷ 0308 × 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 000A ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000A ÷ 0020 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000A ÷ 0308 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 000A ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000A ÷ 0020 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000A ÷ 0308 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 000A ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000A ÷ 0308 × 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 000A ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000A ÷ 0020 ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000A ÷ 0308 × 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 000A ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WATCH (ID) ÷ [0.3]
-× 000A ÷ 0020 ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 000A ÷ 0308 ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 000A ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 000A ÷ 0020 ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000A ÷ 0308 × 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 000A ÷ 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMMA (IS) ÷ [0.3]
-× 000A ÷ 0020 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 000A ÷ 0308 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 002C ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 000A ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000A ÷ 0308 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 000A ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000A ÷ 0020 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000A ÷ 0308 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 000A ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000A ÷ 0020 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000A ÷ 0308 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 000A ÷ 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000A ÷ 0020 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000A ÷ 0308 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 000A ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 000A ÷ 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000A ÷ 0020 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000A ÷ 0308 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 000A ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000A ÷ 0020 ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000A ÷ 0308 × 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 000A ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] DIGIT ZERO (NU) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000A ÷ 0308 × 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 000A ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000A ÷ 0308 × 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 000A ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] PERCENT SIGN (PO) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000A ÷ 0308 × 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 000A ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000A ÷ 0308 × 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 000A ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] QUOTATION MARK (QU) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000A ÷ 0308 × 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 000A ÷ 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [0.3]
-× 000A ÷ 0020 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 000A ÷ 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SOLIDUS (SY) ÷ [0.3]
-× 000A ÷ 0020 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 000A ÷ 0308 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 002F ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 000A ÷ 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WORD JOINER (WJ) ÷ [0.3]
-× 000A ÷ 0020 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000A ÷ 0308 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 000A ÷ 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000A ÷ 0020 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000A ÷ 0308 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000A ÷ 0308 × 0020 × 200B ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 000A ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000A ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000A ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 000A ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000A ÷ 0020 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000A ÷ 0308 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 000A ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000A ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000A ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 000A ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000A ÷ 0308 × 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 000A ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000A ÷ 0020 ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000A ÷ 0308 × 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 000A ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000A ÷ 0308 × 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 000A ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000A ÷ 0308 × 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 000A ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000A ÷ 0020 ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000A ÷ 0308 × 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 000A ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000A ÷ 0020 ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000A ÷ 0308 × 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000A ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0085 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] NUMBER SIGN (AL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0085 ÷ 0308 × 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0085 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EM DASH (B2) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0085 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0085 ÷ 0308 × 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0085 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ACUTE ACCENT (BB) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0085 ÷ 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <LINE TABULATION> (BK) ÷ [0.3]
-× 0085 ÷ 0020 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0085 ÷ 0308 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 000B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0085 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0085 ÷ 0020 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0085 ÷ 0308 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0085 ÷ 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0085 ÷ 0020 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0085 ÷ 0308 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 007D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0085 ÷ 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0085 ÷ 0020 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0085 ÷ 0308 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 0029 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0085 ÷ 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0085 ÷ 0020 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0085 ÷ 0308 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 000D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0085 ÷ 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0085 ÷ 0020 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0085 ÷ 0308 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 0021 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0085 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0085 ÷ 0308 × 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0085 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0085 ÷ 0020 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0085 ÷ 0308 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0085 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0085 ÷ 0020 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0085 ÷ 0308 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0085 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0085 ÷ 0308 × 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0085 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0085 ÷ 0308 × 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0085 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WATCH (ID) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0085 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ONE DOT LEADER (IN) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0085 ÷ 0308 × 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0085 ÷ 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMMA (IS) ÷ [0.3]
-× 0085 ÷ 0020 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0085 ÷ 0308 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 002C ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0085 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0085 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0085 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0085 ÷ 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0085 ÷ 0020 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0085 ÷ 0308 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 000A ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0085 ÷ 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0085 ÷ 0020 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0085 ÷ 0308 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 0085 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0085 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0085 ÷ 0308 × 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0085 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] DIGIT ZERO (NU) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0085 ÷ 0308 × 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0085 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0085 ÷ 0308 × 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0085 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] PERCENT SIGN (PO) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0085 ÷ 0308 × 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0085 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] DOLLAR SIGN (PR) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0085 ÷ 0308 × 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0085 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] QUOTATION MARK (QU) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0085 ÷ 0308 × 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0085 ÷ 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [0.3]
-× 0085 ÷ 0020 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 0020 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0085 ÷ 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SOLIDUS (SY) ÷ [0.3]
-× 0085 ÷ 0020 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0085 ÷ 0308 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 002F ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0085 ÷ 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WORD JOINER (WJ) ÷ [0.3]
-× 0085 ÷ 0020 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0085 ÷ 0308 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 2060 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0085 ÷ 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0085 ÷ 0020 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0085 ÷ 0308 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 × 200B ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0085 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0085 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0085 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0085 ÷ 0308 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0085 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0085 ÷ 0308 × 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0085 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0085 ÷ 0308 × 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0085 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0085 ÷ 0308 × 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0085 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0085 ÷ 0308 × 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0085 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0085 ÷ 0308 × 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0085 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0085 ÷ 0020 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0085 ÷ 0308 × 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0085 ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 17D6 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 17D6 × 0020 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 17D6 × 0308 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 17D6 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 17D6 × 0020 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 17D6 × 0308 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 17D6 × 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 17D6 × 0020 ÷ 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 17D6 × 0308 × 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 17D6 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 17D6 × 0020 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 17D6 × 0308 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 17D6 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 17D6 × 0020 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 17D6 × 0308 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 000B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 17D6 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 17D6 × 0020 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 17D6 × 0308 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 17D6 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 17D6 × 0020 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 17D6 × 0308 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 007D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 17D6 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 17D6 × 0020 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 17D6 × 0308 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 0029 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 17D6 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 17D6 × 0020 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 17D6 × 0308 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 000D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 17D6 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 17D6 × 0020 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 17D6 × 0308 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 0021 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 17D6 × 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 17D6 × 0020 ÷ 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 17D6 × 0308 × 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 17D6 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 17D6 × 0020 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 17D6 × 0308 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 17D6 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 17D6 × 0020 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 17D6 × 0308 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 17D6 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 17D6 × 0020 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 17D6 × 0308 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 17D6 × 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 17D6 × 0020 ÷ 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 17D6 × 0308 × 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 002D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 17D6 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 17D6 × 0020 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 17D6 × 0308 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 231A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 17D6 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 17D6 × 0020 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 17D6 × 0308 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 17D6 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] COMMA (IS) ÷ [0.3]
-× 17D6 × 0020 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 17D6 × 0308 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 002C ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 17D6 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 17D6 × 0020 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 17D6 × 0308 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 17D6 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 17D6 × 0020 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 17D6 × 0308 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 17D6 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 17D6 × 0020 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 17D6 × 0308 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 17D6 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 17D6 × 0020 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 17D6 × 0308 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 000A ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 17D6 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 17D6 × 0020 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 17D6 × 0308 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 0085 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 17D6 × 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 17D6 × 0020 ÷ 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 17D6 × 0308 × 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 17D6 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 17D6 × 0020 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 17D6 × 0308 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 17D6 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 17D6 × 0020 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 17D6 × 0308 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 17D6 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 17D6 × 0020 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 17D6 × 0308 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 17D6 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 17D6 × 0020 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 17D6 × 0308 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 17D6 × 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 17D6 × 0020 ÷ 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 17D6 × 0308 × 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 17D6 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [0.3]
-× 17D6 × 0020 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 0020 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 17D6 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 17D6 × 0020 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 17D6 × 0308 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 002F ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 17D6 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 17D6 × 0020 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 17D6 × 0308 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 2060 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 17D6 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 17D6 × 0020 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 17D6 × 0308 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 17D6 × 0308 × 0020 × 200B ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 17D6 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 17D6 × 0020 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 17D6 × 0308 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 17D6 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 17D6 × 0020 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 17D6 × 0308 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 261D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 17D6 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 17D6 × 0020 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 17D6 × 0308 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 17D6 × 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 17D6 × 0020 ÷ 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 17D6 × 0308 × 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 17D6 × 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 17D6 × 0020 ÷ 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 17D6 × 0308 × 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 200D ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 17D6 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 17D6 × 0020 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 17D6 × 0308 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 17D6 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 17D6 × 0020 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 17D6 × 0308 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 17D6 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 17D6 × 0020 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 17D6 × 0308 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 17D6 × 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 17D6 × 0020 ÷ 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 17D6 × 0308 × 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 17D6 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] KHMER SIGN CAMNUC PII KUUH (NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0030 × 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] NUMBER SIGN (AL) ÷ [0.3]
-× 0030 × 0020 ÷ 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0030 × 0308 × 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] NUMBER SIGN (AL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0030 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0030 × 0020 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0030 × 0308 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0030 × 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0030 × 0020 ÷ 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0030 × 0308 × 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0030 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0030 × 0020 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0030 × 0308 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0030 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0030 × 0020 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0030 × 0308 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0030 × 0308 × 0020 × 000B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0030 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0030 × 0020 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0030 × 0308 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0030 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0030 × 0020 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0030 × 0308 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0030 × 0308 × 0020 × 007D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0030 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [25.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0030 × 0020 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0030 × 0308 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0030 × 0308 × 0020 × 0029 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0030 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0030 × 0020 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0030 × 0308 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0030 × 0308 × 0020 × 000D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0030 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0030 × 0020 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0030 × 0308 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0030 × 0308 × 0020 × 0021 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0030 × 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0030 × 0020 ÷ 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0030 × 0308 × 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0030 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0030 × 0020 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0030 × 0308 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0030 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0030 × 0020 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0030 × 0308 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0030 × 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0030 × 0020 ÷ 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0030 × 0308 × 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0030 × 002D ÷ # × [0.3] DIGIT ZERO (NU) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0030 × 0020 ÷ 002D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0030 × 0308 × 002D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 002D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0030 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0030 × 0020 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0030 × 0308 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 231A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0030 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [22.05] ONE DOT LEADER (IN) ÷ [0.3]
-× 0030 × 0020 ÷ 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0030 × 0308 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.05] ONE DOT LEADER (IN) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0030 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] COMMA (IS) ÷ [0.3]
-× 0030 × 0020 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0030 × 0308 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] COMMA (IS) ÷ [0.3]
-× 0030 × 0308 × 0020 × 002C ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0030 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0030 × 0020 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0030 × 0308 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0030 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0030 × 0020 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0030 × 0308 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0030 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0030 × 0020 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0030 × 0308 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0030 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0030 × 0020 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0030 × 0308 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0030 × 0308 × 0020 × 000A ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0030 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0030 × 0020 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0030 × 0308 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0030 × 0308 × 0020 × 0085 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0030 × 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0030 × 0020 ÷ 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0030 × 0308 × 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0030 × 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] DIGIT ZERO (NU) ÷ [0.3]
-× 0030 × 0020 ÷ 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0030 × 0308 × 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] DIGIT ZERO (NU) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0030 × 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0030 × 0020 ÷ 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0030 × 0308 × 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0030 × 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [25.05] PERCENT SIGN (PO) ÷ [0.3]
-× 0030 × 0020 ÷ 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0030 × 0308 × 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.05] PERCENT SIGN (PO) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0030 × 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [25.05] DOLLAR SIGN (PR) ÷ [0.3]
-× 0030 × 0020 ÷ 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0030 × 0308 × 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.05] DOLLAR SIGN (PR) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0030 × 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0030 × 0020 ÷ 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0030 × 0308 × 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0030 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [0.3]
-× 0030 × 0020 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0030 × 0308 × 0020 × 0020 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0030 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [25.03] SOLIDUS (SY) ÷ [0.3]
-× 0030 × 0020 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0030 × 0308 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.03] SOLIDUS (SY) ÷ [0.3]
-× 0030 × 0308 × 0020 × 002F ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0030 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0030 × 0020 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0030 × 0308 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0030 × 0308 × 0020 × 2060 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0030 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0030 × 0020 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0030 × 0308 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0030 × 0308 × 0020 × 200B ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0030 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0030 × 0020 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0030 × 0308 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0030 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0030 × 0020 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0030 × 0308 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 261D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0030 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0030 × 0020 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0030 × 0308 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0030 × 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0030 × 0020 ÷ 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0030 × 0308 × 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0030 × 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0030 × 0020 ÷ 200D ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0030 × 0308 × 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 200D ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0030 × 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0030 × 0020 ÷ 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0030 × 0308 × 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0030 × 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0030 × 0020 ÷ 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0030 × 0308 × 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0030 × 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [23.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0030 × 0020 ÷ 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0030 × 0308 × 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0030 × 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0030 × 0020 ÷ 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0030 × 0308 × 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0030 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] DIGIT ZERO (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0028 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0028 × 0020 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0028 × 0308 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0023 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0028 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] EM DASH (B2) ÷ [0.3]
-× 0028 × 0020 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
-× 0028 × 0308 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EM DASH (B2) ÷ [0.3]
-× 0028 × 0308 × 0020 × 2014 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EM DASH (B2) ÷ [0.3]
-× 0028 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0028 × 0020 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0028 × 0308 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0009 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0028 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0028 × 0020 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0028 × 0308 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0028 × 0308 × 0020 × 00B4 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0028 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0028 × 0020 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0028 × 0308 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0028 × 0308 × 0020 × 000B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0028 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0028 × 0020 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0028 × 0308 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0028 × 0308 × 0020 × FFFC ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0028 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0028 × 0020 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0028 × 0308 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 007D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0028 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0028 × 0020 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0028 × 0308 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0028 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0028 × 0020 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0028 × 0308 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0028 × 0308 × 0020 × 000D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0028 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0028 × 0020 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0028 × 0308 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0021 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0028 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0028 × 0020 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0028 × 0308 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 00A0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0028 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0028 × 0020 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0028 × 0308 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0028 × 0308 × 0020 × AC00 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0028 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0028 × 0020 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0028 × 0308 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0028 × 0308 × 0020 × AC01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0028 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0028 × 0020 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0028 × 0308 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 05D0 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0028 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0028 × 0020 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0028 × 0308 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0028 × 0308 × 0020 × 002D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0028 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] WATCH (ID) ÷ [0.3]
-× 0028 × 0020 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] WATCH (ID) ÷ [0.3]
-× 0028 × 0308 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] WATCH (ID) ÷ [0.3]
-× 0028 × 0308 × 0020 × 231A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] WATCH (ID) ÷ [0.3]
-× 0028 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0028 × 0020 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0028 × 0308 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0028 × 0308 × 0020 × 2024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0028 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0028 × 0020 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0028 × 0308 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0028 × 0308 × 0020 × 002C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0028 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0028 × 0020 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0028 × 0308 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 1100 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0028 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0028 × 0020 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0028 × 0308 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0028 × 0308 × 0020 × 11A8 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0028 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0028 × 0020 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0028 × 0308 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0028 × 0308 × 0020 × 1160 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0028 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0028 × 0020 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0028 × 0308 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0028 × 0308 × 0020 × 000A ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0028 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0028 × 0020 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0028 × 0308 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0085 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0028 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0028 × 0020 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0028 × 0308 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0028 × 0308 × 0020 × 17D6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0028 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0028 × 0020 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0028 × 0308 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0030 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0028 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0028 × 0020 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0028 × 0308 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0028 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0028 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0028 × 0020 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0028 × 0308 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0025 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0028 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0028 × 0020 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0028 × 0308 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0024 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0028 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0028 × 0020 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0028 × 0308 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0022 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0028 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0028 × 0020 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0028 × 0308 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0020 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0028 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0028 × 0020 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0028 × 0308 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0028 × 0308 × 0020 × 002F ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0028 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0028 × 0020 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0028 × 0308 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0028 × 0308 × 0020 × 2060 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0028 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0028 × 0020 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0028 × 0308 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0028 × 0308 × 0020 × 200B ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0028 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0028 × 0020 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0028 × 0308 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0028 × 0308 × 0020 × 1F1E6 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0028 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0028 × 0020 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0028 × 0308 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0028 × 0308 × 0020 × 261D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0028 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0028 × 0020 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0028 × 0308 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0028 × 0308 × 0020 × 1F3FB ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0028 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0028 × 0020 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0028 × 0308 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0001 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0028 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0028 × 0020 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0028 × 0308 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0028 × 0308 × 0020 × 200D ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0028 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0028 × 0020 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0028 × 0308 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 00A7 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0028 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0028 × 0020 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0028 × 0308 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 50005 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0028 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0028 × 0020 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0028 × 0308 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0028 × 0308 × 0020 × 0E01 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0028 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0028 × 0020 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0028 × 0308 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0028 × 0308 × 0020 × 3041 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [14.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0025 × 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0025 × 0020 ÷ 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0025 × 0308 × 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0025 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0025 × 0020 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0025 × 0308 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0025 × 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0025 × 0020 ÷ 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0025 × 0308 × 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0025 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0025 × 0020 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0025 × 0308 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0025 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0025 × 0020 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0025 × 0308 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0025 × 0308 × 0020 × 000B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0025 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0025 × 0020 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0025 × 0308 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0025 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0025 × 0020 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0025 × 0308 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0025 × 0308 × 0020 × 007D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0025 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0025 × 0020 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0025 × 0308 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0025 × 0308 × 0020 × 0029 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0025 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0025 × 0020 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0025 × 0308 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0025 × 0308 × 0020 × 000D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0025 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0025 × 0020 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0025 × 0308 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0025 × 0308 × 0020 × 0021 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0025 × 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0025 × 0020 ÷ 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0025 × 0308 × 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0025 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0025 × 0020 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0025 × 0308 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0025 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0025 × 0020 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0025 × 0308 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0025 × 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0025 × 0020 ÷ 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0025 × 0308 × 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0025 × 002D ÷ # × [0.3] PERCENT SIGN (PO) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0025 × 0020 ÷ 002D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0025 × 0308 × 002D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 002D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0025 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0025 × 0020 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0025 × 0308 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 231A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0025 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0025 × 0020 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0025 × 0308 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0025 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] COMMA (IS) ÷ [0.3]
-× 0025 × 0020 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0025 × 0308 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0025 × 0308 × 0020 × 002C ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0025 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0025 × 0020 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0025 × 0308 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0025 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0025 × 0020 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0025 × 0308 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0025 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0025 × 0020 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0025 × 0308 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0025 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0025 × 0020 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0025 × 0308 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0025 × 0308 × 0020 × 000A ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0025 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0025 × 0020 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0025 × 0308 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0025 × 0308 × 0020 × 0085 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0025 × 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0025 × 0020 ÷ 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0025 × 0308 × 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0025 × 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
-× 0025 × 0020 ÷ 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0025 × 0308 × 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0025 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0025 × 0020 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0025 × 0308 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0025 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0025 × 0020 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0025 × 0308 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0025 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0025 × 0020 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0025 × 0308 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0025 × 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0025 × 0020 ÷ 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0025 × 0308 × 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0025 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [0.3]
-× 0025 × 0020 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0025 × 0308 × 0020 × 0020 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0025 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0025 × 0020 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0025 × 0308 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0025 × 0308 × 0020 × 002F ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0025 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0025 × 0020 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0025 × 0308 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0025 × 0308 × 0020 × 2060 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0025 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0025 × 0020 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0025 × 0308 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0025 × 0308 × 0020 × 200B ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0025 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0025 × 0020 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0025 × 0308 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0025 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0025 × 0020 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0025 × 0308 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 261D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0025 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0025 × 0020 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0025 × 0308 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0025 × 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0025 × 0020 ÷ 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0025 × 0308 × 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0025 × 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0025 × 0020 ÷ 200D ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0025 × 0308 × 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 200D ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0025 × 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0025 × 0020 ÷ 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0025 × 0308 × 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0025 × 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0025 × 0020 ÷ 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0025 × 0308 × 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0025 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0025 × 0020 ÷ 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0025 × 0308 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0025 × 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0025 × 0020 ÷ 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0025 × 0308 × 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0025 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] PERCENT SIGN (PO) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0024 × 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0024 × 0020 ÷ 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0024 × 0308 × 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0024 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0024 × 0020 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0024 × 0308 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0024 × 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0024 × 0020 ÷ 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0024 × 0308 × 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0024 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0024 × 0020 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0024 × 0308 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0024 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0024 × 0020 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0024 × 0308 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0024 × 0308 × 0020 × 000B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0024 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0024 × 0020 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0024 × 0308 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0024 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0024 × 0020 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0024 × 0308 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0024 × 0308 × 0020 × 007D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0024 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0024 × 0020 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0024 × 0308 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0024 × 0308 × 0020 × 0029 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0024 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0024 × 0020 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0024 × 0308 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0024 × 0308 × 0020 × 000D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0024 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0024 × 0020 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0024 × 0308 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0024 × 0308 × 0020 × 0021 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0024 × 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0024 × 0020 ÷ 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0024 × 0308 × 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0024 × AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0024 × 0020 ÷ AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0024 × 0308 × AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0024 × AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0024 × 0020 ÷ AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0024 × 0308 × AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0024 × 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0024 × 0020 ÷ 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0024 × 0308 × 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0024 × 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0024 × 0020 ÷ 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0024 × 0308 × 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 002D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0024 × 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WATCH (ID) ÷ [0.3]
-× 0024 × 0020 ÷ 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0024 × 0308 × 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] WATCH (ID) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 231A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0024 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0024 × 0020 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0024 × 0308 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0024 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] COMMA (IS) ÷ [0.3]
-× 0024 × 0020 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0024 × 0308 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0024 × 0308 × 0020 × 002C ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0024 × 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0024 × 0020 ÷ 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0024 × 0308 × 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0024 × 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0024 × 0020 ÷ 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0024 × 0308 × 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0024 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0024 × 0020 ÷ 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0024 × 0308 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [27.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0024 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0024 × 0020 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0024 × 0308 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0024 × 0308 × 0020 × 000A ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0024 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0024 × 0020 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0024 × 0308 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0024 × 0308 × 0020 × 0085 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0024 × 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0024 × 0020 ÷ 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0024 × 0308 × 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0024 × 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
-× 0024 × 0020 ÷ 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0024 × 0308 × 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [25.01] DIGIT ZERO (NU) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0024 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0024 × 0020 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0024 × 0308 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0024 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0024 × 0020 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0024 × 0308 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0024 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0024 × 0020 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0024 × 0308 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0024 × 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0024 × 0020 ÷ 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0024 × 0308 × 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0024 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [0.3]
-× 0024 × 0020 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0024 × 0308 × 0020 × 0020 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0024 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0024 × 0020 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0024 × 0308 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0024 × 0308 × 0020 × 002F ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0024 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0024 × 0020 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0024 × 0308 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0024 × 0308 × 0020 × 2060 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0024 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0024 × 0020 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0024 × 0308 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0024 × 0308 × 0020 × 200B ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0024 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0024 × 0020 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0024 × 0308 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0024 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0024 × 0020 ÷ 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0024 × 0308 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0024 × 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0024 × 0020 ÷ 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0024 × 0308 × 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.12] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0024 × 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0024 × 0020 ÷ 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0024 × 0308 × 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0024 × 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0024 × 0020 ÷ 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0024 × 0308 × 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 200D ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0024 × 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0024 × 0020 ÷ 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0024 × 0308 × 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0024 × 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0024 × 0020 ÷ 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0024 × 0308 × 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0024 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0024 × 0020 ÷ 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0024 × 0308 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0024 × 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0024 × 0020 ÷ 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0024 × 0308 × 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0024 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] DOLLAR SIGN (PR) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0022 × 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0022 × 0020 ÷ 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0022 × 0308 × 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] NUMBER SIGN (AL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0022 × 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] EM DASH (B2) ÷ [0.3]
-× 0022 × 0020 ÷ 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0022 × 0308 × 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EM DASH (B2) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0022 × 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0022 × 0020 ÷ 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0022 × 0308 × 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0022 × 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
-× 0022 × 0020 ÷ 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0022 × 0308 × 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ACUTE ACCENT (BB) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0022 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0022 × 0020 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0022 × 0308 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0022 × 0308 × 0020 × 000B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0022 × FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0022 × 0020 ÷ FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0022 × 0308 × FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0022 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0022 × 0020 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0022 × 0308 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0022 × 0308 × 0020 × 007D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0022 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0022 × 0020 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0022 × 0308 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0022 × 0308 × 0020 × 0029 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0022 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0022 × 0020 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0022 × 0308 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0022 × 0308 × 0020 × 000D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0022 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0022 × 0020 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0022 × 0308 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0022 × 0308 × 0020 × 0021 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0022 × 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0022 × 0020 ÷ 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0022 × 0308 × 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0022 × AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0022 × 0020 ÷ AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0022 × 0308 × AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0022 × AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0022 × 0020 ÷ AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0022 × 0308 × AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0022 × 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0022 × 0020 ÷ 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0022 × 0308 × 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0022 × 002D ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0022 × 0020 ÷ 002D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0022 × 0308 × 002D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 002D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0022 × 231A ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] WATCH (ID) ÷ [0.3]
-× 0022 × 0020 ÷ 231A ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0022 × 0308 × 231A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] WATCH (ID) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 231A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0022 × 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 0022 × 0020 ÷ 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0022 × 0308 × 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0022 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] COMMA (IS) ÷ [0.3]
-× 0022 × 0020 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0022 × 0308 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0022 × 0308 × 0020 × 002C ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0022 × 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0022 × 0020 ÷ 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0022 × 0308 × 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0022 × 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0022 × 0020 ÷ 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0022 × 0308 × 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0022 × 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0022 × 0020 ÷ 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0022 × 0308 × 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0022 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0022 × 0020 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0022 × 0308 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0022 × 0308 × 0020 × 000A ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0022 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0022 × 0020 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0022 × 0308 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0022 × 0308 × 0020 × 0085 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0022 × 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0022 × 0020 ÷ 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0022 × 0308 × 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0022 × 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0022 × 0020 ÷ 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0022 × 0308 × 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0022 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0022 × 0020 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0022 × 0308 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0022 × 0308 × 0020 × 0028 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [15.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0022 × 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
-× 0022 × 0020 ÷ 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0022 × 0308 × 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] PERCENT SIGN (PO) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0022 × 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
-× 0022 × 0020 ÷ 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0022 × 0308 × 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] DOLLAR SIGN (PR) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0022 × 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0022 × 0020 ÷ 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0022 × 0308 × 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0022 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [0.3]
-× 0022 × 0020 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0022 × 0308 × 0020 × 0020 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0022 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0022 × 0020 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0022 × 0308 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0022 × 0308 × 0020 × 002F ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0022 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0022 × 0020 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0022 × 0308 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0022 × 0308 × 0020 × 2060 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0022 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0022 × 0020 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0022 × 0308 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0022 × 0308 × 0020 × 200B ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0022 × 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0022 × 0020 ÷ 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0022 × 0308 × 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0022 × 261D ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0022 × 0020 ÷ 261D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0022 × 0308 × 261D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 261D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0022 × 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0022 × 0020 ÷ 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0022 × 0308 × 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0022 × 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0022 × 0020 ÷ 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0022 × 0308 × 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0022 × 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0022 × 0020 ÷ 200D ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0022 × 0308 × 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 200D ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0022 × 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0022 × 0020 ÷ 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0022 × 0308 × 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0022 × 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0022 × 0020 ÷ 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0022 × 0308 × 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0022 × 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0022 × 0020 ÷ 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0022 × 0308 × 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0022 × 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0022 × 0020 ÷ 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0022 × 0308 × 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0022 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0020 × 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0020 ÷ 0308 × 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0020 × 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0020 × 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0020 ÷ 0308 × 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0020 × 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0020 × 000B ÷ # × [0.3] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0020 × 0020 × 000B ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0020 ÷ 0308 × 000B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 000B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0020 × 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0020 ÷ 0308 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0020 × 007D ÷ # × [0.3] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0020 × 0020 × 007D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0020 ÷ 0308 × 007D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 007D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0020 × 0029 ÷ # × [0.3] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0020 × 0020 × 0029 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0020 ÷ 0308 × 0029 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 0029 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0020 × 000D ÷ # × [0.3] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0020 × 0020 × 000D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0020 ÷ 0308 × 000D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 000D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0020 × 0021 ÷ # × [0.3] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0020 × 0020 × 0021 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0020 ÷ 0308 × 0021 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 0021 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0020 × 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0020 ÷ 0308 × 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0020 × 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0020 ÷ 0308 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0020 × 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0020 ÷ 0308 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0020 × 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0020 ÷ 0308 × 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0020 × 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0020 ÷ 0308 × 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0020 ÷ 231A ÷ # × [0.3] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0020 × 0020 ÷ 231A ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 231A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0020 × 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0020 ÷ 0308 × 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0020 × 002C ÷ # × [0.3] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0020 × 0020 × 002C ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0020 ÷ 0308 × 002C ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 002C ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0020 × 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0020 × 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0020 × 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0020 × 000A ÷ # × [0.3] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0020 × 0020 × 000A ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0020 ÷ 0308 × 000A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 000A ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0020 × 0085 ÷ # × [0.3] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0020 × 0020 × 0085 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0020 ÷ 0308 × 0085 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 0085 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0020 × 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0020 ÷ 0308 × 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0020 × 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0020 ÷ 0308 × 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0020 × 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0020 ÷ 0308 × 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0020 × 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0020 ÷ 0308 × 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0020 × 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0020 ÷ 0308 × 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0020 × 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0020 ÷ 0308 × 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0020 × 0020 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0020 × 0020 × 0020 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 0020 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0020 × 002F ÷ # × [0.3] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0020 × 0020 × 002F ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0020 ÷ 0308 × 002F ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 002F ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0020 × 2060 ÷ # × [0.3] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0020 × 0020 × 2060 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0020 ÷ 0308 × 2060 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 2060 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0020 × 200B ÷ # × [0.3] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0020 × 0020 × 200B ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0020 ÷ 0308 × 200B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 × 200B ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0020 × 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0020 × 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0020 × 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0020 ÷ 0308 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0020 × 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0020 ÷ 0308 × 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0020 × 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0020 ÷ 0308 × 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0020 × 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0020 ÷ 0308 × 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0020 × 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0020 ÷ 0308 × 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0020 × 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0020 ÷ 0308 × 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0020 × 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0020 ÷ 0308 × 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0020 ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002F ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002F × 0020 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002F × 0308 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0023 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 002F ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 002F × 0020 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 002F × 0308 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 2014 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 002F × 0009 ÷ # × [0.3] SOLIDUS (SY) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002F × 0020 ÷ 0009 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002F × 0308 × 0009 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0009 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 002F ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002F × 0020 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002F × 0308 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 002F × 000B ÷ # × [0.3] SOLIDUS (SY) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002F × 0020 × 000B ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002F × 0308 × 000B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002F × 0308 × 0020 × 000B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 002F ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002F × 0020 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002F × 0308 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ FFFC ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 002F × 007D ÷ # × [0.3] SOLIDUS (SY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002F × 0020 × 007D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002F × 0308 × 007D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002F × 0308 × 0020 × 007D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 002F × 0029 ÷ # × [0.3] SOLIDUS (SY) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002F × 0020 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002F × 0308 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002F × 0308 × 0020 × 0029 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 002F × 000D ÷ # × [0.3] SOLIDUS (SY) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002F × 0020 × 000D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002F × 0308 × 000D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002F × 0308 × 0020 × 000D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 002F × 0021 ÷ # × [0.3] SOLIDUS (SY) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002F × 0020 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002F × 0308 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002F × 0308 × 0020 × 0021 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 002F × 00A0 ÷ # × [0.3] SOLIDUS (SY) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002F × 0020 ÷ 00A0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002F × 0308 × 00A0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 002F ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002F × 0020 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002F × 0308 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ AC00 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 002F ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002F × 0020 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002F × 0308 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ AC01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 002F × 05D0 ÷ # × [0.3] SOLIDUS (SY) × [21.2] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002F × 0020 ÷ 05D0 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002F × 0308 × 05D0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.2] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 002F × 002D ÷ # × [0.3] SOLIDUS (SY) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002F × 0020 ÷ 002D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002F × 0308 × 002D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 002D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 002F ÷ 231A ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 002F × 0020 ÷ 231A ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 002F × 0308 ÷ 231A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 231A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 002F ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002F × 0020 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002F × 0308 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 2024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 002F × 002C ÷ # × [0.3] SOLIDUS (SY) × [13.02] COMMA (IS) ÷ [0.3]
-× 002F × 0020 × 002C ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 002F × 0308 × 002C ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 002F × 0308 × 0020 × 002C ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 002F ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002F × 0020 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002F × 0308 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 1100 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 002F ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002F × 0020 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002F × 0308 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 002F ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002F × 0020 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002F × 0308 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 1160 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 002F × 000A ÷ # × [0.3] SOLIDUS (SY) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002F × 0020 × 000A ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002F × 0308 × 000A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002F × 0308 × 0020 × 000A ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 002F × 0085 ÷ # × [0.3] SOLIDUS (SY) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002F × 0020 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002F × 0308 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002F × 0308 × 0020 × 0085 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 002F × 17D6 ÷ # × [0.3] SOLIDUS (SY) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002F × 0020 ÷ 17D6 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002F × 0308 × 17D6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 002F ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002F × 0020 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002F × 0308 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0030 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 002F ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002F × 0020 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002F × 0308 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0028 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 002F ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002F × 0020 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002F × 0308 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0025 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 002F ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002F × 0020 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002F × 0308 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0024 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 002F × 0022 ÷ # × [0.3] SOLIDUS (SY) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 002F × 0020 ÷ 0022 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 002F × 0308 × 0022 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0022 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 002F × 0020 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [0.3]
-× 002F × 0020 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 002F × 0308 × 0020 × 0020 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002F × 002F ÷ # × [0.3] SOLIDUS (SY) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002F × 0020 × 002F ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002F × 0308 × 002F ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 002F × 0308 × 0020 × 002F ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 002F × 2060 ÷ # × [0.3] SOLIDUS (SY) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002F × 0020 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002F × 0308 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002F × 0308 × 0020 × 2060 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 002F × 200B ÷ # × [0.3] SOLIDUS (SY) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002F × 0020 × 200B ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002F × 0308 × 200B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002F × 0308 × 0020 × 200B ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 002F ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002F × 0020 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002F × 0308 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 002F ÷ 261D ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002F × 0020 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002F × 0308 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 261D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 002F ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002F × 0020 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002F × 0308 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 002F × 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002F × 0020 ÷ 0001 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002F × 0308 × 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0001 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 002F × 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002F × 0020 ÷ 200D ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002F × 0308 × 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 200D ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 002F ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002F × 0020 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002F × 0308 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 002F ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002F × 0020 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002F × 0308 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 50005 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 002F ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002F × 0020 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002F × 0308 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 002F × 3041 ÷ # × [0.3] SOLIDUS (SY) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002F × 0020 ÷ 3041 ÷ # × [0.3] SOLIDUS (SY) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002F × 0308 × 3041 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 002F × 0308 × 0020 ÷ 3041 ÷ # × [0.3] SOLIDUS (SY) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2060 × 0023 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] NUMBER SIGN (AL) ÷ [0.3]
-× 2060 × 0020 ÷ 0023 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2060 × 0308 × 0023 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] NUMBER SIGN (AL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 2060 × 2014 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EM DASH (B2) ÷ [0.3]
-× 2060 × 0020 ÷ 2014 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 2060 × 0308 × 2014 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EM DASH (B2) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 2060 × 0009 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2060 × 0020 ÷ 0009 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2060 × 0308 × 0009 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 2060 × 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] ACUTE ACCENT (BB) ÷ [0.3]
-× 2060 × 0020 ÷ 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2060 × 0308 × 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] ACUTE ACCENT (BB) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 2060 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2060 × 0020 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2060 × 0308 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2060 × 0308 × 0020 × 000B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 2060 × FFFC ÷ # × [0.3] WORD JOINER (WJ) × [11.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2060 × 0020 ÷ FFFC ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2060 × 0308 × FFFC ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 2060 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2060 × 0020 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2060 × 0308 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2060 × 0308 × 0020 × 007D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 2060 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2060 × 0020 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2060 × 0308 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2060 × 0308 × 0020 × 0029 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 2060 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2060 × 0020 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2060 × 0308 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2060 × 0308 × 0020 × 000D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 2060 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2060 × 0020 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2060 × 0308 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2060 × 0308 × 0020 × 0021 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 2060 × 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2060 × 0020 ÷ 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2060 × 0308 × 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 2060 × AC00 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2060 × 0020 ÷ AC00 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2060 × 0308 × AC00 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 2060 × AC01 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2060 × 0020 ÷ AC01 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2060 × 0308 × AC01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 2060 × 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2060 × 0020 ÷ 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2060 × 0308 × 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 2060 × 002D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2060 × 0020 ÷ 002D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2060 × 0308 × 002D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 002D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 2060 × 231A ÷ # × [0.3] WORD JOINER (WJ) × [11.02] WATCH (ID) ÷ [0.3]
-× 2060 × 0020 ÷ 231A ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 2060 × 0308 × 231A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] WATCH (ID) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 231A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 2060 × 2024 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 2060 × 0020 ÷ 2024 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2060 × 0308 × 2024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 2060 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [11.02] COMMA (IS) ÷ [0.3]
-× 2060 × 0020 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 2060 × 0308 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] COMMA (IS) ÷ [0.3]
-× 2060 × 0308 × 0020 × 002C ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 2060 × 1100 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2060 × 0020 ÷ 1100 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2060 × 0308 × 1100 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 2060 × 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2060 × 0020 ÷ 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2060 × 0308 × 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 2060 × 1160 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2060 × 0020 ÷ 1160 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2060 × 0308 × 1160 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 2060 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2060 × 0020 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2060 × 0308 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2060 × 0308 × 0020 × 000A ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 2060 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2060 × 0020 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2060 × 0308 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2060 × 0308 × 0020 × 0085 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 2060 × 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2060 × 0020 ÷ 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2060 × 0308 × 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 2060 × 0030 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] DIGIT ZERO (NU) ÷ [0.3]
-× 2060 × 0020 ÷ 0030 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2060 × 0308 × 0030 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] DIGIT ZERO (NU) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 2060 × 0028 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2060 × 0020 ÷ 0028 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2060 × 0308 × 0028 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 2060 × 0025 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] PERCENT SIGN (PO) ÷ [0.3]
-× 2060 × 0020 ÷ 0025 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2060 × 0308 × 0025 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] PERCENT SIGN (PO) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 2060 × 0024 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] DOLLAR SIGN (PR) ÷ [0.3]
-× 2060 × 0020 ÷ 0024 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2060 × 0308 × 0024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] DOLLAR SIGN (PR) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 2060 × 0022 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] QUOTATION MARK (QU) ÷ [0.3]
-× 2060 × 0020 ÷ 0022 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 2060 × 0308 × 0022 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] QUOTATION MARK (QU) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 2060 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [0.3]
-× 2060 × 0020 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 2060 × 0308 × 0020 × 0020 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 2060 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [11.02] SOLIDUS (SY) ÷ [0.3]
-× 2060 × 0020 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2060 × 0308 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] SOLIDUS (SY) ÷ [0.3]
-× 2060 × 0308 × 0020 × 002F ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 2060 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2060 × 0020 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2060 × 0308 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2060 × 0308 × 0020 × 2060 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2060 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2060 × 0020 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2060 × 0308 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2060 × 0308 × 0020 × 200B ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 2060 × 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2060 × 0020 ÷ 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2060 × 0308 × 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 2060 × 261D ÷ # × [0.3] WORD JOINER (WJ) × [11.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2060 × 0020 ÷ 261D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2060 × 0308 × 261D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 261D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 2060 × 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [11.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2060 × 0020 ÷ 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2060 × 0308 × 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 2060 × 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2060 × 0020 ÷ 0001 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2060 × 0308 × 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 2060 × 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2060 × 0020 ÷ 200D ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2060 × 0308 × 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 200D ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 2060 × 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2060 × 0020 ÷ 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2060 × 0308 × 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 2060 × 50005 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2060 × 0020 ÷ 50005 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2060 × 0308 × 50005 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 2060 × 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2060 × 0020 ÷ 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2060 × 0308 × 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 2060 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2060 × 0020 ÷ 3041 ÷ # × [0.3] WORD JOINER (WJ) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2060 × 0308 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 2060 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WORD JOINER (WJ) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200B ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200B × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200B ÷ 0308 × 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200B ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EM DASH (B2) ÷ [0.3]
-× 200B × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EM DASH (B2) ÷ [0.3]
-× 200B ÷ 0308 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 200B ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200B × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200B ÷ 0308 × 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200B ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200B × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200B ÷ 0308 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200B × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200B × 0020 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200B ÷ 0308 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 000B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200B ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200B × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200B ÷ 0308 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200B ÷ 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200B × 0020 ÷ 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200B ÷ 0308 × 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 007D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200B ÷ 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200B × 0020 ÷ 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200B ÷ 0308 × 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200B × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200B × 0020 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200B ÷ 0308 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 000D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200B ÷ 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200B × 0020 ÷ 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200B ÷ 0308 × 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200B ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200B × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200B ÷ 0308 × 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200B ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200B × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200B ÷ 0308 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200B ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200B × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200B ÷ 0308 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200B ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200B × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200B ÷ 0308 × 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200B ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200B × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200B ÷ 0308 × 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200B ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WATCH (ID) ÷ [0.3]
-× 200B × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WATCH (ID) ÷ [0.3]
-× 200B ÷ 0308 ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 200B ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 200B × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 200B ÷ 0308 × 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 200B ÷ 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMMA (IS) ÷ [0.3]
-× 200B × 0020 ÷ 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] COMMA (IS) ÷ [0.3]
-× 200B ÷ 0308 × 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 002C ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 200B ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200B × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200B ÷ 0308 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200B ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200B × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200B ÷ 0308 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200B ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200B × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200B ÷ 0308 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200B × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200B × 0020 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200B ÷ 0308 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 000A ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200B × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200B × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200B ÷ 0308 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200B ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200B × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200B ÷ 0308 × 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200B ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] DIGIT ZERO (NU) ÷ [0.3]
-× 200B × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] DIGIT ZERO (NU) ÷ [0.3]
-× 200B ÷ 0308 × 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 200B ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200B × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200B ÷ 0308 × 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200B ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] PERCENT SIGN (PO) ÷ [0.3]
-× 200B × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] PERCENT SIGN (PO) ÷ [0.3]
-× 200B ÷ 0308 × 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 200B ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 200B × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 200B ÷ 0308 × 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 200B ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] QUOTATION MARK (QU) ÷ [0.3]
-× 200B × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] QUOTATION MARK (QU) ÷ [0.3]
-× 200B ÷ 0308 × 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 200B × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [0.3]
-× 200B × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 200B ÷ 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] SOLIDUS (SY) ÷ [0.3]
-× 200B × 0020 ÷ 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] SOLIDUS (SY) ÷ [0.3]
-× 200B ÷ 0308 × 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 002F ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 200B ÷ 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WORD JOINER (WJ) ÷ [0.3]
-× 200B × 0020 ÷ 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WORD JOINER (WJ) ÷ [0.3]
-× 200B ÷ 0308 × 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 200B × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200B × 0020 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200B ÷ 0308 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200B ÷ 0308 × 0020 × 200B ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200B ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200B × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200B ÷ 0308 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200B ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200B × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200B ÷ 0308 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200B ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200B × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200B ÷ 0308 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200B ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200B × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200B ÷ 0308 × 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200B ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200B × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200B ÷ 0308 × 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200B ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200B × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200B ÷ 0308 × 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200B ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200B × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200B ÷ 0308 × 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200B ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200B × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200B ÷ 0308 × 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200B ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200B × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) × [7.01] SPACE (SP) ÷ [8.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200B ÷ 0308 × 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200B ÷ 0308 × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH SPACE (ZW) ÷ [8.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F1E6 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F1E6 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1F1E6 × 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F1E6 × 0308 × 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F1E6 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F1E6 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F1E6 × 0020 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F1E6 × 0308 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 000B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F1E6 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F1E6 × 0020 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F1E6 × 0308 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F1E6 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F1E6 × 0020 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F1E6 × 0308 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 007D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F1E6 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F1E6 × 0020 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F1E6 × 0308 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 0029 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F1E6 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F1E6 × 0020 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F1E6 × 0308 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 000D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F1E6 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F1E6 × 0020 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F1E6 × 0308 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 0021 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F1E6 × 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F1E6 × 0308 × 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F1E6 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F1E6 × 0020 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F1E6 × 0308 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F1E6 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F1E6 × 0020 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F1E6 × 0308 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F1E6 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F1E6 × 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F1E6 × 0308 × 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 002D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F1E6 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 231A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1F1E6 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F1E6 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] COMMA (IS) ÷ [0.3]
-× 1F1E6 × 0020 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1F1E6 × 0308 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 002C ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1F1E6 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F1E6 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F1E6 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F1E6 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F1E6 × 0020 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F1E6 × 0308 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 000A ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F1E6 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F1E6 × 0020 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F1E6 × 0308 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 0085 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F1E6 × 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F1E6 × 0308 × 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F1E6 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F1E6 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F1E6 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1F1E6 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F1E6 × 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1F1E6 × 0308 × 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1F1E6 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F1E6 × 0020 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 0020 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F1E6 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1F1E6 × 0020 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1F1E6 × 0308 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 002F ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1F1E6 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F1E6 × 0020 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F1E6 × 0308 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 2060 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F1E6 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F1E6 × 0020 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F1E6 × 0308 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 × 200B ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F1E6 × 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F1E6 × 0308 × 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.11] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F1E6 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 261D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F1E6 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F1E6 × 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F1E6 × 0308 × 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F1E6 × 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F1E6 × 0308 × 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 200D ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F1E6 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F1E6 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F1E6 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F1E6 × 0308 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F1E6 × 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F1E6 × 0020 ÷ 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F1E6 × 0308 × 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F1E6 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 261D ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 261D × 0020 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 261D × 0308 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 261D ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 261D × 0020 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 261D × 0308 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 261D × 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 261D × 0020 ÷ 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 261D × 0308 × 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 261D ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 261D × 0020 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 261D × 0308 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 261D × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 261D × 0020 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 261D × 0308 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 261D × 0308 × 0020 × 000B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 261D ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 261D × 0020 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 261D × 0308 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 261D × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 261D × 0020 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 261D × 0308 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 261D × 0308 × 0020 × 007D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 261D × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 261D × 0020 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 261D × 0308 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 261D × 0308 × 0020 × 0029 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 261D × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 261D × 0020 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 261D × 0308 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 261D × 0308 × 0020 × 000D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 261D × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 261D × 0020 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 261D × 0308 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 261D × 0308 × 0020 × 0021 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 261D × 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 261D × 0020 ÷ 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 261D × 0308 × 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 261D ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 261D × 0020 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 261D × 0308 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 261D ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 261D × 0020 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 261D × 0308 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 261D ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 261D × 0020 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 261D × 0308 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 261D × 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 261D × 0020 ÷ 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 261D × 0308 × 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 002D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 261D ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 261D × 0020 ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 261D × 0308 ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 231A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 261D × 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 261D × 0020 ÷ 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 261D × 0308 × 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 261D × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] COMMA (IS) ÷ [0.3]
-× 261D × 0020 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 261D × 0308 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 261D × 0308 × 0020 × 002C ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 261D ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 261D × 0020 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 261D × 0308 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 261D ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 261D × 0020 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 261D × 0308 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 261D ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 261D × 0020 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 261D × 0308 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 261D × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 261D × 0020 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 261D × 0308 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 261D × 0308 × 0020 × 000A ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 261D × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 261D × 0020 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 261D × 0308 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 261D × 0308 × 0020 × 0085 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 261D × 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 261D × 0020 ÷ 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 261D × 0308 × 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 261D ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 261D × 0020 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 261D × 0308 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 261D ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 261D × 0020 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 261D × 0308 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 261D × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 261D × 0020 ÷ 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 261D × 0308 × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 261D ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 261D × 0020 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 261D × 0308 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 261D × 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 261D × 0020 ÷ 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 261D × 0308 × 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 261D × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [0.3]
-× 261D × 0020 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 261D × 0308 × 0020 × 0020 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 261D × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 261D × 0020 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 261D × 0308 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 261D × 0308 × 0020 × 002F ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 261D × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 261D × 0020 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 261D × 0308 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 261D × 0308 × 0020 × 2060 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 261D × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 261D × 0020 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 261D × 0308 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 261D × 0308 × 0020 × 200B ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 261D ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 261D × 0020 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 261D × 0308 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 261D ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 261D × 0020 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 261D × 0308 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 261D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 261D × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [30.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 261D × 0020 ÷ 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 261D × 0308 × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 261D × 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 261D × 0020 ÷ 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 261D × 0308 × 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 261D × 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 261D × 0020 ÷ 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 261D × 0308 × 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 200D ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 261D ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 261D × 0020 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 261D × 0308 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 261D ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 261D × 0020 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 261D × 0308 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 261D ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 261D × 0020 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 261D × 0308 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 261D × 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 261D × 0020 ÷ 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 261D × 0308 × 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 261D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F3FB ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F3FB × 0308 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0023 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 1F3FB ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1F3FB × 0020 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1F3FB × 0308 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 2014 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 1F3FB × 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F3FB × 0308 × 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0009 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 1F3FB ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F3FB × 0020 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F3FB × 0308 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 1F3FB × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F3FB × 0020 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F3FB × 0308 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 000B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 1F3FB ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F3FB × 0020 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F3FB × 0308 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ FFFC ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 1F3FB × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F3FB × 0020 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F3FB × 0308 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 007D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 1F3FB × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F3FB × 0020 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F3FB × 0308 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 0029 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 1F3FB × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F3FB × 0020 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F3FB × 0308 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 000D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 1F3FB × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F3FB × 0020 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F3FB × 0308 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 0021 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 1F3FB × 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F3FB × 0308 × 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 1F3FB ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F3FB × 0020 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F3FB × 0308 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ AC00 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 1F3FB ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F3FB × 0020 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F3FB × 0308 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ AC01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 1F3FB ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F3FB × 0308 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 1F3FB × 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F3FB × 0020 ÷ 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F3FB × 0308 × 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 002D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 1F3FB ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1F3FB × 0020 ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1F3FB × 0308 ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 231A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 1F3FB × 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F3FB × 0020 ÷ 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F3FB × 0308 × 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.03] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 2024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 1F3FB × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] COMMA (IS) ÷ [0.3]
-× 1F3FB × 0020 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1F3FB × 0308 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 002C ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 1F3FB ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F3FB × 0308 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 1100 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 1F3FB ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F3FB × 0020 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F3FB × 0308 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1F3FB ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F3FB × 0020 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F3FB × 0308 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 1160 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1F3FB × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F3FB × 0020 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F3FB × 0308 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 000A ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 1F3FB × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F3FB × 0020 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F3FB × 0308 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 0085 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 1F3FB × 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F3FB × 0020 ÷ 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F3FB × 0308 × 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 1F3FB ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F3FB × 0308 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0030 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 1F3FB ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F3FB × 0308 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0028 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 1F3FB × 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1F3FB × 0308 × 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0025 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 1F3FB ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F3FB × 0308 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0024 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 1F3FB × 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1F3FB × 0308 × 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0022 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 1F3FB × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F3FB × 0020 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 0020 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 1F3FB × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1F3FB × 0020 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1F3FB × 0308 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 002F ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 1F3FB × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F3FB × 0020 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F3FB × 0308 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 2060 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 1F3FB × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F3FB × 0020 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F3FB × 0308 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F3FB × 0308 × 0020 × 200B ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 1F3FB ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F3FB × 0020 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F3FB × 0308 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 1F3FB ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F3FB × 0020 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F3FB × 0308 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 261D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 1F3FB ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F3FB × 0020 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F3FB × 0308 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 1F3FB × 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F3FB × 0308 × 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0001 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 1F3FB × 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F3FB × 0020 ÷ 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F3FB × 0308 × 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 200D ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 1F3FB ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F3FB × 0308 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 1F3FB ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F3FB × 0308 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 50005 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 1F3FB ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F3FB × 0020 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F3FB × 0308 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1F3FB × 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F3FB × 0020 ÷ 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F3FB × 0308 × 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 1F3FB × 0308 × 0020 ÷ 3041 ÷ # × [0.3] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0001 × 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0001 × 0020 ÷ 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0001 × 0308 × 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0001 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0001 × 0020 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0001 × 0308 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0001 × 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0001 × 0020 ÷ 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0001 × 0308 × 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0001 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0001 × 0020 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0001 × 0308 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0001 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0001 × 0020 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0001 × 0308 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0001 × 0308 × 0020 × 000B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0001 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0001 × 0020 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0001 × 0308 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0001 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0001 × 0020 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0001 × 0308 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0001 × 0308 × 0020 × 007D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0001 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0001 × 0020 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0001 × 0308 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0001 × 0308 × 0020 × 0029 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0001 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0001 × 0020 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0001 × 0308 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0001 × 0308 × 0020 × 000D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0001 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0001 × 0020 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0001 × 0308 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0001 × 0308 × 0020 × 0021 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0001 × 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0001 × 0020 ÷ 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0001 × 0308 × 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0001 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0001 × 0020 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0001 × 0308 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0001 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0001 × 0020 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0001 × 0308 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0001 × 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0001 × 0020 ÷ 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0001 × 0308 × 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0001 × 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0001 × 0020 ÷ 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0001 × 0308 × 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0001 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0001 × 0020 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0001 × 0308 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 231A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0001 × 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0001 × 0020 ÷ 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0001 × 0308 × 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0001 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
-× 0001 × 0020 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0001 × 0308 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
-× 0001 × 0308 × 0020 × 002C ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0001 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0001 × 0020 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0001 × 0308 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0001 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0001 × 0020 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0001 × 0308 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0001 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0001 × 0020 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0001 × 0308 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0001 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0001 × 0020 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0001 × 0308 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0001 × 0308 × 0020 × 000A ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0001 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0001 × 0020 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0001 × 0308 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0001 × 0308 × 0020 × 0085 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0001 × 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0001 × 0020 ÷ 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0001 × 0308 × 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0001 × 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0001 × 0020 ÷ 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0001 × 0308 × 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0001 × 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0001 × 0020 ÷ 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0001 × 0308 × 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0001 × 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0001 × 0020 ÷ 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0001 × 0308 × 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0001 × 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0001 × 0020 ÷ 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0001 × 0308 × 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0001 × 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0001 × 0020 ÷ 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0001 × 0308 × 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0001 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0001 × 0020 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0001 × 0308 × 0020 × 0020 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0001 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
-× 0001 × 0020 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0001 × 0308 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
-× 0001 × 0308 × 0020 × 002F ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0001 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0001 × 0020 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0001 × 0308 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0001 × 0308 × 0020 × 2060 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0001 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0001 × 0020 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0001 × 0308 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0001 × 0308 × 0020 × 200B ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0001 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0001 × 0020 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0001 × 0308 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0001 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0001 × 0020 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0001 × 0308 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0001 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0001 × 0020 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0001 × 0308 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0001 × 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0001 × 0020 ÷ 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0001 × 0308 × 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0001 × 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0001 × 0020 ÷ 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0001 × 0308 × 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0001 × 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0001 × 0020 ÷ 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0001 × 0308 × 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0001 × 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0001 × 0020 ÷ 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0001 × 0308 × 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0001 × 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0001 × 0020 ÷ 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0001 × 0308 × 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0001 × 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0001 × 0020 ÷ 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0001 × 0308 × 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0001 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <START OF HEADING> (CM1_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200D × 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200D × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200D × 0308 × 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0023 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 200D ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 200D × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 200D × 0308 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 2014 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 200D × 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200D × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200D × 0308 × 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0009 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 200D ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200D × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200D × 0308 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 200D × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200D × 0020 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200D × 0308 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200D × 0308 × 0020 × 000B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 200D ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200D × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200D × 0308 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ FFFC ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 200D × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200D × 0020 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200D × 0308 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200D × 0308 × 0020 × 007D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 200D × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200D × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200D × 0308 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200D × 0308 × 0020 × 0029 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 200D × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200D × 0020 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200D × 0308 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200D × 0308 × 0020 × 000D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 200D × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200D × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200D × 0308 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200D × 0308 × 0020 × 0021 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 200D × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200D × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200D × 0308 × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200D ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200D × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200D × 0308 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ AC00 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 200D ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200D × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200D × 0308 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ AC01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 200D × 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200D × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200D × 0308 × 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 200D × 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200D × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200D × 0308 × 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 002D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 200D × 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WATCH (ID) ÷ [0.3]
-× 200D × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 200D × 0308 ÷ 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 231A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 200D × 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 200D × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 200D × 0308 × 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 2024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 200D × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] COMMA (IS) ÷ [0.3]
-× 200D × 0020 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 200D × 0308 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] COMMA (IS) ÷ [0.3]
-× 200D × 0308 × 0020 × 002C ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 200D ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200D × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200D × 0308 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 1100 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 200D ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200D × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200D × 0308 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 200D ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200D × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200D × 0308 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 1160 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 200D × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200D × 0020 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200D × 0308 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200D × 0308 × 0020 × 000A ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 200D × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200D × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200D × 0308 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200D × 0308 × 0020 × 0085 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 200D × 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200D × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200D × 0308 × 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 200D × 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 200D × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 200D × 0308 × 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0030 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 200D × 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200D × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200D × 0308 × 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0028 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 200D × 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 200D × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 200D × 0308 × 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0025 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 200D × 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 200D × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 200D × 0308 × 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0024 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 200D × 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 200D × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 200D × 0308 × 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0022 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 200D × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 200D × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 200D × 0308 × 0020 × 0020 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 200D × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
-× 200D × 0020 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 200D × 0308 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
-× 200D × 0308 × 0020 × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 200D × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 200D × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 200D × 0308 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 200D × 0308 × 0020 × 2060 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 200D × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200D × 0020 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200D × 0308 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200D × 0308 × 0020 × 200B ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 200D ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200D × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200D × 0308 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 200D × 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200D × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200D × 0308 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 200D × 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200D × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200D × 0308 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 200D × 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200D × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200D × 0308 × 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0001 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 200D × 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200D × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200D × 0308 × 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 200D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 200D × 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200D × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200D × 0308 × 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 200D × 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200D × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200D × 0308 × 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 50005 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 200D × 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200D × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200D × 0308 × 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 200D × 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200D × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200D × 0308 × 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200D × 0308 × 0020 ÷ 3041 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A7 × 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A7 × 0020 ÷ 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A7 × 0308 × 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 00A7 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 00A7 × 0020 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 00A7 × 0308 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 00A7 × 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A7 × 0020 ÷ 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A7 × 0308 × 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 00A7 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A7 × 0020 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A7 × 0308 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 00A7 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A7 × 0020 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A7 × 0308 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 000B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 00A7 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A7 × 0020 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A7 × 0308 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 00A7 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A7 × 0020 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A7 × 0308 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 007D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 00A7 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A7 × 0020 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A7 × 0308 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 0029 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 00A7 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A7 × 0020 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A7 × 0308 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 000D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 00A7 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A7 × 0020 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A7 × 0308 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 0021 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 00A7 × 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A7 × 0020 ÷ 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A7 × 0308 × 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 00A7 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A7 × 0020 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A7 × 0308 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 00A7 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A7 × 0020 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A7 × 0308 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 00A7 × 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A7 × 0020 ÷ 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A7 × 0308 × 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 00A7 × 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A7 × 0020 ÷ 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A7 × 0308 × 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 002D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 00A7 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 00A7 × 0020 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 00A7 × 0308 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 231A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 00A7 × 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A7 × 0020 ÷ 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A7 × 0308 × 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 00A7 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] COMMA (IS) ÷ [0.3]
-× 00A7 × 0020 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 00A7 × 0308 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 002C ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 00A7 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A7 × 0020 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A7 × 0308 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 00A7 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A7 × 0020 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A7 × 0308 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 00A7 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A7 × 0020 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A7 × 0308 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 00A7 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A7 × 0020 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A7 × 0308 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 000A ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 00A7 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A7 × 0020 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A7 × 0308 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 0085 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 00A7 × 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A7 × 0020 ÷ 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A7 × 0308 × 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 00A7 × 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 00A7 × 0020 ÷ 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00A7 × 0308 × 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 00A7 × 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A7 × 0020 ÷ 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A7 × 0308 × 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 00A7 × 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 00A7 × 0020 ÷ 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00A7 × 0308 × 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 00A7 × 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A7 × 0020 ÷ 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A7 × 0308 × 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 00A7 × 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 00A7 × 0020 ÷ 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00A7 × 0308 × 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 00A7 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A7 × 0020 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 0020 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 00A7 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00A7 × 0020 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00A7 × 0308 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 002F ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 00A7 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A7 × 0020 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A7 × 0308 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 2060 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 00A7 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A7 × 0020 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A7 × 0308 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A7 × 0308 × 0020 × 200B ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 00A7 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A7 × 0020 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A7 × 0308 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 00A7 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A7 × 0020 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A7 × 0308 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 261D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 00A7 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A7 × 0020 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A7 × 0308 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 00A7 × 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A7 × 0020 ÷ 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A7 × 0308 × 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 00A7 × 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A7 × 0020 ÷ 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A7 × 0308 × 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 200D ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 00A7 × 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A7 × 0020 ÷ 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A7 × 0308 × 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 00A7 × 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A7 × 0020 ÷ 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A7 × 0308 × 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 00A7 × 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A7 × 0020 ÷ 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A7 × 0308 × 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 00A7 × 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A7 × 0020 ÷ 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A7 × 0308 × 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 00A7 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] SECTION SIGN (AI_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 50005 × 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 50005 × 0020 ÷ 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 50005 × 0308 × 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 50005 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 50005 × 0020 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 50005 × 0308 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 50005 × 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 50005 × 0020 ÷ 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 50005 × 0308 × 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 50005 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 50005 × 0020 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 50005 × 0308 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 50005 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 50005 × 0020 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 50005 × 0308 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 50005 × 0308 × 0020 × 000B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 50005 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 50005 × 0020 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 50005 × 0308 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 50005 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 50005 × 0020 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 50005 × 0308 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 50005 × 0308 × 0020 × 007D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 50005 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 50005 × 0020 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 50005 × 0308 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 50005 × 0308 × 0020 × 0029 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 50005 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 50005 × 0020 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 50005 × 0308 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 50005 × 0308 × 0020 × 000D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 50005 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 50005 × 0020 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 50005 × 0308 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 50005 × 0308 × 0020 × 0021 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 50005 × 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 50005 × 0020 ÷ 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 50005 × 0308 × 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 50005 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 50005 × 0020 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 50005 × 0308 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 50005 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 50005 × 0020 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 50005 × 0308 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 50005 × 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 50005 × 0020 ÷ 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 50005 × 0308 × 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 50005 × 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 50005 × 0020 ÷ 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 50005 × 0308 × 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 002D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 50005 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 50005 × 0020 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 50005 × 0308 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 231A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 50005 × 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 50005 × 0020 ÷ 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 50005 × 0308 × 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 50005 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] COMMA (IS) ÷ [0.3]
-× 50005 × 0020 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 50005 × 0308 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 50005 × 0308 × 0020 × 002C ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 50005 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 50005 × 0020 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 50005 × 0308 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 50005 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 50005 × 0020 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 50005 × 0308 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 50005 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 50005 × 0020 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 50005 × 0308 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 50005 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 50005 × 0020 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 50005 × 0308 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 50005 × 0308 × 0020 × 000A ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 50005 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 50005 × 0020 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 50005 × 0308 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 50005 × 0308 × 0020 × 0085 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 50005 × 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 50005 × 0020 ÷ 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 50005 × 0308 × 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 50005 × 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 50005 × 0020 ÷ 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 50005 × 0308 × 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 50005 × 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 50005 × 0020 ÷ 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 50005 × 0308 × 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 50005 × 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 50005 × 0020 ÷ 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 50005 × 0308 × 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 50005 × 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 50005 × 0020 ÷ 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 50005 × 0308 × 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 50005 × 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 50005 × 0020 ÷ 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 50005 × 0308 × 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 50005 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 50005 × 0020 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 50005 × 0308 × 0020 × 0020 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 50005 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 50005 × 0020 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 50005 × 0308 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 50005 × 0308 × 0020 × 002F ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 50005 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 50005 × 0020 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 50005 × 0308 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 50005 × 0308 × 0020 × 2060 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 50005 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 50005 × 0020 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 50005 × 0308 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 50005 × 0308 × 0020 × 200B ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 50005 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 50005 × 0020 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 50005 × 0308 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 50005 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 50005 × 0020 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 50005 × 0308 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 261D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 50005 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 50005 × 0020 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 50005 × 0308 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 50005 × 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 50005 × 0020 ÷ 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 50005 × 0308 × 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 50005 × 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 50005 × 0020 ÷ 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 50005 × 0308 × 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 200D ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 50005 × 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 50005 × 0020 ÷ 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 50005 × 0308 × 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 50005 × 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 50005 × 0020 ÷ 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 50005 × 0308 × 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 50005 × 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 50005 × 0020 ÷ 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 50005 × 0308 × 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 50005 × 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 50005 × 0020 ÷ 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 50005 × 0308 × 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 50005 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] <reserved-50005> (XX_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0E01 × 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0E01 × 0020 ÷ 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0E01 × 0308 × 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 0E01 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0E01 × 0020 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0E01 × 0308 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 0E01 × 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0E01 × 0020 ÷ 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0E01 × 0308 × 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 0E01 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0E01 × 0020 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0E01 × 0308 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 0E01 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0E01 × 0020 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0E01 × 0308 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 000B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 0E01 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0E01 × 0020 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0E01 × 0308 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 0E01 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0E01 × 0020 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0E01 × 0308 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 007D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0E01 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0E01 × 0020 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0E01 × 0308 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 0029 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0E01 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0E01 × 0020 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0E01 × 0308 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 000D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 0E01 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0E01 × 0020 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0E01 × 0308 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 0021 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0E01 × 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0E01 × 0020 ÷ 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0E01 × 0308 × 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 0E01 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0E01 × 0020 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0E01 × 0308 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 0E01 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0E01 × 0020 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0E01 × 0308 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 0E01 × 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0E01 × 0020 ÷ 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0E01 × 0308 × 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 0E01 × 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0E01 × 0020 ÷ 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0E01 × 0308 × 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 002D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0E01 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0E01 × 0020 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0E01 × 0308 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 231A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 0E01 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0E01 × 0020 ÷ 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0E01 × 0308 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 0E01 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] COMMA (IS) ÷ [0.3]
-× 0E01 × 0020 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0E01 × 0308 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 002C ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 0E01 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0E01 × 0020 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0E01 × 0308 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 0E01 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0E01 × 0020 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0E01 × 0308 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 0E01 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0E01 × 0020 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0E01 × 0308 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 0E01 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0E01 × 0020 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0E01 × 0308 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 000A ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 0E01 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0E01 × 0020 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0E01 × 0308 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 0085 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 0E01 × 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0E01 × 0020 ÷ 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0E01 × 0308 × 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 0E01 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0E01 × 0020 ÷ 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0E01 × 0308 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 0E01 × 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0E01 × 0020 ÷ 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0E01 × 0308 × 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 0E01 × 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0E01 × 0020 ÷ 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0E01 × 0308 × 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] PERCENT SIGN (PO) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 0E01 × 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0E01 × 0020 ÷ 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0E01 × 0308 × 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [24.03] DOLLAR SIGN (PR) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 0E01 × 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0E01 × 0020 ÷ 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0E01 × 0308 × 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 0E01 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 0E01 × 0020 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 0020 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0E01 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0E01 × 0020 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0E01 × 0308 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 002F ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 0E01 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0E01 × 0020 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0E01 × 0308 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 2060 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 0E01 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0E01 × 0020 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0E01 × 0308 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0E01 × 0308 × 0020 × 200B ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 0E01 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0E01 × 0020 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0E01 × 0308 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 0E01 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0E01 × 0020 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0E01 × 0308 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 261D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0E01 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0E01 × 0020 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0E01 × 0308 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0E01 × 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0E01 × 0020 ÷ 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0E01 × 0308 × 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 0E01 × 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0E01 × 0020 ÷ 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0E01 × 0308 × 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 200D ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 0E01 × 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0E01 × 0020 ÷ 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0E01 × 0308 × 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 0E01 × 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0E01 × 0020 ÷ 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0E01 × 0308 × 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 0E01 × 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0E01 × 0020 ÷ 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0E01 × 0308 × 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [28.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0E01 × 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0E01 × 0020 ÷ 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0E01 × 0308 × 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0E01 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 3041 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 3041 × 0020 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 3041 × 0308 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] NUMBER SIGN (AL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0023 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NUMBER SIGN (AL) ÷ [0.3]
-× 3041 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 3041 × 0020 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 3041 × 0308 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EM DASH (B2) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 2014 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EM DASH (B2) ÷ [0.3]
-× 3041 × 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 3041 × 0020 ÷ 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 3041 × 0308 × 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.01] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0009 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <CHARACTER TABULATION> (BA) ÷ [0.3]
-× 3041 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 3041 × 0020 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 3041 × 0308 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 00B4 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ACUTE ACCENT (BB) ÷ [0.3]
-× 3041 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 3041 × 0020 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 3041 × 0308 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 3041 × 0308 × 0020 × 000B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE TABULATION> (BK) ÷ [0.3]
-× 3041 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 3041 × 0020 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 3041 × 0308 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× 3041 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 3041 × 0020 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 3041 × 0308 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 3041 × 0308 × 0020 × 007D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 3041 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 3041 × 0020 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 3041 × 0308 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 3041 × 0308 × 0020 × 0029 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 3041 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 3041 × 0020 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 3041 × 0308 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 3041 × 0308 × 0020 × 000D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-× 3041 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 3041 × 0020 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 3041 × 0308 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 3041 × 0308 × 0020 × 0021 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 3041 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [12.1] NO-BREAK SPACE (GL) ÷ [0.3]
-× 3041 × 0020 ÷ 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 3041 × 0308 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] NO-BREAK SPACE (GL) ÷ [0.3]
-× 3041 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 3041 × 0020 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 3041 × 0308 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ AC00 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GA (H2) ÷ [0.3]
-× 3041 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 3041 × 0020 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 3041 × 0308 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ AC01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE GAG (H3) ÷ [0.3]
-× 3041 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 3041 × 0020 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 3041 × 0308 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 05D0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HEBREW LETTER ALEF (HL) ÷ [0.3]
-× 3041 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 3041 × 0020 ÷ 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 3041 × 0308 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) ÷ [0.3]
-× 3041 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 3041 × 0020 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 3041 × 0308 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WATCH (ID) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 231A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WATCH (ID) ÷ [0.3]
-× 3041 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 3041 × 0020 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 3041 × 0308 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 2024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ONE DOT LEADER (IN) ÷ [0.3]
-× 3041 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] COMMA (IS) ÷ [0.3]
-× 3041 × 0020 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 3041 × 0308 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] COMMA (IS) ÷ [0.3]
-× 3041 × 0308 × 0020 × 002C ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] COMMA (IS) ÷ [0.3]
-× 3041 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 3041 × 0020 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 3041 × 0308 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 1100 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL CHOSEONG KIYEOK (JL) ÷ [0.3]
-× 3041 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 3041 × 0020 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 3041 × 0308 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 11A8 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 3041 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 3041 × 0020 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 3041 × 0308 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 1160 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 3041 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 3041 × 0020 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 3041 × 0308 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 3041 × 0308 × 0020 × 000A ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-× 3041 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 3041 × 0020 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 3041 × 0308 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 3041 × 0308 × 0020 × 0085 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [6.0] <NEXT LINE (NEL)> (NL) ÷ [0.3]
-× 3041 × 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 3041 × 0020 ÷ 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 3041 × 0308 × 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 17D6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] KHMER SIGN CAMNUC PII KUUH (NS) ÷ [0.3]
-× 3041 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 3041 × 0020 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 3041 × 0308 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DIGIT ZERO (NU) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0030 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DIGIT ZERO (NU) ÷ [0.3]
-× 3041 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 3041 × 0020 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 3041 × 0308 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0028 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) ÷ [0.3]
-× 3041 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 3041 × 0020 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 3041 × 0308 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] PERCENT SIGN (PO) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0025 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] PERCENT SIGN (PO) ÷ [0.3]
-× 3041 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 3041 × 0020 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 3041 × 0308 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0024 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] DOLLAR SIGN (PR) ÷ [0.3]
-× 3041 × 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 3041 × 0020 ÷ 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 3041 × 0308 × 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] QUOTATION MARK (QU) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0022 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) ÷ [0.3]
-× 3041 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [0.3]
-× 3041 × 0020 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 3041 × 0308 × 0020 × 0020 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 3041 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 3041 × 0020 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 3041 × 0308 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] SOLIDUS (SY) ÷ [0.3]
-× 3041 × 0308 × 0020 × 002F ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] SOLIDUS (SY) ÷ [0.3]
-× 3041 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 3041 × 0020 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 3041 × 0308 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 3041 × 0308 × 0020 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 3041 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 3041 × 0020 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 3041 × 0308 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 3041 × 0308 × 0020 × 200B ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [0.3]
-× 3041 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 3041 × 0020 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 3041 × 0308 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 1F1E6 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-× 3041 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 3041 × 0020 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 3041 × 0308 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 261D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 3041 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 3041 × 0020 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 3041 × 0308 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 1F3FB ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 3041 × 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 3041 × 0020 ÷ 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 3041 × 0308 × 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0001 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <START OF HEADING> (CM1_CM) ÷ [0.3]
-× 3041 × 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 3041 × 0020 ÷ 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 3041 × 0308 × 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 200D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) ÷ [0.3]
-× 3041 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 3041 × 0020 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 3041 × 0308 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 00A7 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] SECTION SIGN (AI_AL) ÷ [0.3]
-× 3041 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 3041 × 0020 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 3041 × 0308 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 50005 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] <reserved-50005> (XX_AL) ÷ [0.3]
-× 3041 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 3041 × 0020 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 3041 × 0308 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [999.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 0E01 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 3041 × 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 3041 × 0020 ÷ 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 3041 × 0308 × 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [21.03] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 3041 × 0308 × 0020 ÷ 3041 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) × [5.01] <LINE FEED (LF)> (LF) ÷ [5.03] LATIN SMALL LETTER A (AL) × [6.0] <LINE FEED (LF)> (LF) ÷ [5.03] COMBINING DIAERESIS (CM1_CM) ÷ [0.3]
-× 0061 × 0308 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) ÷ [0.3]
-× 0020 ÷ 200D × 0646 ÷ # × [0.3] SPACE (SP) ÷ [18.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [28.0] ARABIC LETTER NOON (AL) ÷ [0.3]
-× 0646 × 200D × 0020 ÷ # × [0.3] ARABIC LETTER NOON (AL) × [9.0] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 000B ÷ 3041 ÷ # × [0.3] <LINE TABULATION> (BK) ÷ [4.0] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 000D ÷ 3041 ÷ # × [0.3] <CARRIAGE RETURN (CR)> (CR) ÷ [5.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 0085 ÷ 3041 ÷ # × [0.3] <NEXT LINE (NEL)> (NL) ÷ [5.04] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 200D × 261D ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [8.1] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 3041 × 2060 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [11.01] WORD JOINER (WJ) ÷ [0.3]
-× 2060 × 3041 ÷ # × [0.3] WORD JOINER (WJ) × [11.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 3041 × 0308 × 00A0 ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [9.0] COMBINING DIAERESIS (CM1_CM) × [12.2] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200D × 00A0 ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [12.3] NO-BREAK SPACE (GL) ÷ [0.3]
-× 200D × 002F ÷ # × [0.3] ZERO WIDTH JOINER (ZWJ_O_ZWJ_CM) × [13.04] SOLIDUS (SY) ÷ [0.3]
-× 2014 × 2014 ÷ # × [0.3] EM DASH (B2) × [17.0] EM DASH (B2) ÷ [0.3]
-× 3041 ÷ FFFC ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [20.01] OBJECT REPLACEMENT CHARACTER (CB) ÷ [0.3]
-× FFFC ÷ 3041 ÷ # × [0.3] OBJECT REPLACEMENT CHARACTER (CB) ÷ [20.02] HIRAGANA LETTER SMALL A (CJ_NS) ÷ [0.3]
-× 3041 × 002D ÷ # × [0.3] HIRAGANA LETTER SMALL A (CJ_NS) × [21.02] HYPHEN-MINUS (HY) ÷ [0.3]
-× 0E01 × 2024 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [22.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 0021 × 2024 ÷ # × [0.3] EXCLAMATION MARK (EX) × [22.02] ONE DOT LEADER (IN) ÷ [0.3]
-× 2024 × 2024 ÷ # × [0.3] ONE DOT LEADER (IN) × [22.04] ONE DOT LEADER (IN) ÷ [0.3]
-× 0030 × 2024 ÷ # × [0.3] DIGIT ZERO (NU) × [22.05] ONE DOT LEADER (IN) ÷ [0.3]
-× 261D × 0025 ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [23.13] PERCENT SIGN (PO) ÷ [0.3]
-× 0E01 × 0030 ÷ # × [0.3] THAI CHARACTER KO KAI (SA_AL) × [23.02] DIGIT ZERO (NU) ÷ [0.3]
-× 0024 × 261D ÷ # × [0.3] DOLLAR SIGN (PR) × [23.12] WHITE UP POINTING INDEX (EB) ÷ [0.3]
-× 0024 × 0E01 ÷ # × [0.3] DOLLAR SIGN (PR) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 0025 × 0E01 ÷ # × [0.3] PERCENT SIGN (PO) × [24.02] THAI CHARACTER KO KAI (SA_AL) ÷ [0.3]
-× 1100 × 1160 ÷ # × [0.3] HANGUL CHOSEONG KIYEOK (JL) × [26.01] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 1160 × 1160 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [26.02] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 11A8 × 11A8 ÷ # × [0.3] HANGUL JONGSEONG KIYEOK (JT) × [26.03] HANGUL JONGSEONG KIYEOK (JT) ÷ [0.3]
-× 1160 × 2024 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.01] ONE DOT LEADER (IN) ÷ [0.3]
-× 1160 × 0025 ÷ # × [0.3] HANGUL JUNGSEONG FILLER (JV) × [27.02] PERCENT SIGN (PO) ÷ [0.3]
-× 0024 × 1160 ÷ # × [0.3] DOLLAR SIGN (PR) × [27.03] HANGUL JUNGSEONG FILLER (JV) ÷ [0.3]
-× 261D × 1F3FB ÷ # × [0.3] WHITE UP POINTING INDEX (EB) × [30.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (EM) ÷ [0.3]
-× 0066 × 0069 × 006E × 0061 × 006C ÷ # × [0.3] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) ÷ [0.3]
-× 0063 × 0061 × 006E × 0027 × 0074 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER T (AL) ÷ [0.3]
-× 0063 × 0061 × 006E × 2019 × 0074 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] RIGHT SINGLE QUOTATION MARK (QU) × [19.02] LATIN SMALL LETTER T (AL) ÷ [0.3]
-× 0027 × 0063 × 0061 × 006E × 0027 × 0020 ÷ 006E × 006F × 0074 ÷ # × [0.3] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [19.01] APOSTROPHE (QU) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER T (AL) ÷ [0.3]
-× 0063 × 0061 × 006E × 0020 ÷ 0027 × 006E × 006F × 0074 × 0027 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [7.01] SPACE (SP) ÷ [18.0] APOSTROPHE (QU) × [19.02] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER T (AL) × [19.01] APOSTROPHE (QU) ÷ [0.3]
-× 0062 × 0075 × 0067 × 0028 × 0073 × 0029 × 0020 × 0020 × 0020 × 0020 × 0020 ÷ # × [0.3] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 0062 × 0075 × 0067 × 0028 × 0073 × 0029 × 00A0 × 0020 × 0020 × 0020 × 0020 × 0020 ÷ # × [0.3] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NO-BREAK SPACE (GL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [0.3]
-× 002E × 002E ÷ 307E ÷ 3059 × 3002 ÷ 0058 × 004D × 004C ÷ 306E × 002E × 002E ÷ # × [0.3] FULL STOP (IS) × [13.02] FULL STOP (IS) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [999.0] HIRAGANA LETTER SU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN CAPITAL LETTER X (AL) × [28.0] LATIN CAPITAL LETTER M (AL) × [28.0] LATIN CAPITAL LETTER L (AL) ÷ [999.0] HIRAGANA LETTER NO (ID) × [13.02] FULL STOP (IS) × [13.02] FULL STOP (IS) ÷ [0.3]
-× 0061 × 0062 × 00AD ÷ 0062 × 0079 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER Y (AL) ÷ [0.3]
-× 002D × 0033 ÷ # × [0.3] HYPHEN-MINUS (HY) × [25.02] DIGIT THREE (NU) ÷ [0.3]
-× 0065 × 002E × 0067 × 002E ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [13.02] FULL STOP (IS) × [29.0] LATIN SMALL LETTER G (AL) × [13.02] FULL STOP (IS) ÷ [0.3]
-× 4E00 × 002E ÷ 4E00 × 002E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4E00 (ID) × [13.02] FULL STOP (IS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) × [13.02] FULL STOP (IS) ÷ [0.3]
-× 0061 × 0020 × 0020 ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
-× 0061 × 0020 × 0020 × 200B ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) × [7.01] SPACE (SP) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
-× 0061 × 0020 ÷ 0308 × 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [28.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
-× 0031 × 0308 × 0062 × 0028 × 0061 × 0029 × 002D ÷ 0028 × 0062 × 0029 ÷ # × [0.3] DIGIT ONE (NU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [23.03] LATIN SMALL LETTER B (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER B (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0067 × 0069 × 0076 × 0065 × 0020 ÷ 0062 × 006F × 006F × 006B × 0028 × 0073 × 0029 × 002E ÷ # × [0.3] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER V (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER K (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] FULL STOP (IS) ÷ [0.3]
-× 307E ÷ 0028 × 3059 × 0029 ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER SU (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0066 × 0069 × 006E × 0064 × 0020 × 002E × 0063 × 006F × 006D ÷ # × [0.3] LATIN SMALL LETTER F (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [7.01] SPACE (SP) × [13.02] FULL STOP (IS) × [29.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER M (AL) ÷ [0.3]
-× 0065 × 0071 × 0075 × 0061 × 006C × 0073 × 0020 × 002E ÷ 0033 × 0035 × 0020 ÷ 0063 × 0065 × 006E × 0074 × 0073 ÷ # × [0.3] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [25.03] DIGIT FIVE (NU) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
-× 0028 × 0073 × 0029 × 0068 × 0065 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) ÷ [0.3]
-× 007B × 0073 × 007D ÷ 0068 × 0065 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) ÷ [0.3]
-× 02C8 × 0073 × 0049 × 006C × 0259 × 0062 × 0028 × 0259 × 0029 × 006C ÷ # × [0.3] MODIFIER LETTER VERTICAL LINE (BB) × [21.04] LATIN SMALL LETTER S (AL) × [28.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER SCHWA (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER SCHWA (AL) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) ÷ [0.3]
-× 02C8 × 0073 × 0049 × 006C × 0259 × 0062 × 007B × 0259 × 007D ÷ 006C ÷ # × [0.3] MODIFIER LETTER VERTICAL LINE (BB) × [21.04] LATIN SMALL LETTER S (AL) × [28.0] LATIN CAPITAL LETTER I (AL) × [28.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER SCHWA (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER SCHWA (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0029 × 002E ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] FULL STOP (IS) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 002E × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] FULL STOP (IS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0029 × 0021 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 0028 × 0073 × 0021 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 005C ÷ 0028 × 0073 × 005C × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [24.03] REVERSE SOLIDUS (PR) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [24.03] REVERSE SOLIDUS (PR) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 0028 × 0020 × 0073 × 0020 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D × 002E ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [13.02] FULL STOP (IS) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 007B × 0073 × 007D × 0021 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [13.01] EXCLAMATION MARK (EX) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 005C ÷ 007B × 0073 × 005C × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [24.03] REVERSE SOLIDUS (PR) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [24.03] REVERSE SOLIDUS (PR) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0063 × 006F × 0064 × 0065 × 007B × 0020 × 0073 × 0020 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER E (AL) × [30.01] LEFT CURLY BRACKET (OP) × [7.01] SPACE (SP) × [14.0] LATIN SMALL LETTER S (AL) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0063 × 006F × 0064 × 0028 × 0065 × 0029 ÷ 2026 ÷ 0028 × 0073 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0028 × 0063 × 006F × 0064 × 0028 × 0065 × 0029 ÷ 2026 × 0029 × 0073 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER S (AL) ÷ [0.3]
-× 0063 × 006F × 0064 × 007B × 0065 × 007D ÷ 2026 ÷ 007B × 0073 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 007B × 0063 × 006F × 0064 × 007B × 0065 × 007D ÷ 2026 × 007D ÷ 0073 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] HORIZONTAL ELLIPSIS (IN) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER S (AL) ÷ [0.3]
-× 0028 × 0063 × 006F × 006E × 002D × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 0028 × 0063 × 006F × 006E × 00AD × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 0028 × 0063 × 006F × 006E × 2011 × 0029 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 0028 × 0063 × 006F × 006E × 0029 × 002D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 0028 × 0063 × 006F × 006E × 0029 × 00AD ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 0028 × 0063 × 006F × 006E × 0029 × 2011 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 007B × 0063 × 006F × 006E × 002D × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 007B × 0063 × 006F × 006E × 00AD × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 007B × 0063 × 006F × 006E × 2011 × 007D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 007B × 0063 × 006F × 006E × 007D × 002D ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 007B × 0063 × 006F × 006E × 007D × 00AD ÷ 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 007B × 0063 × 006F × 006E × 007D × 2011 × 006C × 0061 × 006E × 0067 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER L (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER G (AL) ÷ [0.3]
-× 0063 × 0072 × 0065 × 0301 × 0028 × 0065 × 0301 × 0029 ÷ 0028 × 0065 × 0029 ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0063 × 0072 × 0065 × 0301 × 005B × 0065 × 0072 × 007C ÷ 0065 × 0301 × 0028 × 0065 × 0029 ÷ 0028 × 0073 × 0029 × 005D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT SQUARE BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [21.01] VERTICAL LINE (BA) ÷ [999.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [0.3]
-× 0063 × 0072 × 0065 × 0301 × 007B × 0065 × 0072 × 007C ÷ 0065 × 0301 × 0028 × 0065 × 0029 ÷ 0028 × 0073 × 0029 × 007D ÷ # × [0.3] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [21.01] VERTICAL LINE (BA) ÷ [999.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING ACUTE ACCENT (CM1_CM) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 0308 × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 00AB × 0308 × 00BB × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 0028 × 00AB × 0020 ÷ 0308 × 0020 ÷ 00BB × 0029 ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 0020 × 0028 × 0020 × 0308 × 0020 × 0029 × 0020 ÷ 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.0] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 202F × 0028 × 0020 × 0308 × 0020 × 0029 × 202F × 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] LEFT PARENTHESIS (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 0308 × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 00AB × 0308 × 00BB × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [9.0] COMBINING DIAERESIS (CM1_CM) × [19.01] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 007B × 00AB × 0020 ÷ 0308 × 0020 ÷ 00BB × 007D ÷ 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 0020 × 007B × 0020 × 0308 × 0020 × 007D × 0020 ÷ 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [7.01] SPACE (SP) × [15.0] LEFT CURLY BRACKET (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) × [7.01] SPACE (SP) ÷ [18.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0061 × 006D × 0062 × 0069 × 0067 × 0075 × 00AB × 202F × 007B × 0020 × 0308 × 0020 × 007D × 202F × 00BB × 0028 × 0065 × 0308 × 0029 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER G (AL) × [28.0] LATIN SMALL LETTER U (AL) × [19.01] LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] LEFT CURLY BRACKET (OP) × [7.01] SPACE (SP) × [14.0] COMBINING DIAERESIS (CM1_CM) × [7.01] SPACE (SP) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NARROW NO-BREAK SPACE (GL) × [12.0] RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK (QU) × [15.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [9.0] COMBINING DIAERESIS (CM1_CM) × [13.03] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD ÷ 2011 × 0029 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD × 0029 × 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT PARENTHESIS (CP) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 0028 × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 0029 × 00AD ÷ 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] RIGHT PARENTHESIS (CP) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD ÷ 2011 × 007D ÷ 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 00AD × 007D × 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [21.01] SOFT HYPHEN (BA) × [13.02] RIGHT CURLY BRACKET (CL) × [12.1] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 007B × 0063 × 007A × 0065 × 0072 × 0077 × 006F × 006E × 006F × 007D × 00AD ÷ 2011 × 006E × 0069 × 0065 × 0062 × 0069 × 0065 × 0073 × 006B × 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER Z (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER W (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER O (AL) × [13.02] RIGHT CURLY BRACKET (CL) × [21.01] SOFT HYPHEN (BA) ÷ [999.0] NON-BREAKING HYPHEN (GL) × [12.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER S (AL) × [28.0] LATIN SMALL LETTER K (AL) × [28.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 006F × 0070 × 0065 × 0072 × 0061 × 0074 × 006F × 0072 × 005B × 005D ÷ 0028 × 0030 × 0029 × 003B ÷ # × [0.3] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [30.01] LEFT SQUARE BRACKET (OP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] DIGIT ZERO (NU) × [25.04] RIGHT PARENTHESIS (CP) × [13.02] SEMICOLON (IS) ÷ [0.3]
-× 006F × 0070 × 0065 × 0072 × 0061 × 0074 × 006F × 0072 × 005B × 005D ÷ 0028 × 0029 ÷ 007B × 007D ÷ # × [0.3] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [30.01] LEFT SQUARE BRACKET (OP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [999.0] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] LEFT CURLY BRACKET (OP) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 672C ÷ 0028 × 3092 × 0029 ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 672C ÷ 0028 × 300C × 3092 × 300D × 0029 ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 672C ÷ 300C × 0028 × 3092 × 0029 × 300D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 672C ÷ 007B × 3092 × 007D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 672C ÷ 007B × 300C × 3092 × 300D × 007D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT CURLY BRACKET (OP) × [14.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 672C ÷ 005B × 0028 × 3092 × 0029 × 005D ÷ 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] LEFT SQUARE BRACKET (OP) × [14.0] LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER WO (ID) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 0028 × 30CB × 30E5 × 30FC × 30FB × 0029 ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 0028 × 30CB × 30E5 × 30FC × 0029 × 30FB ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [13.02] RIGHT PARENTHESIS (CP) × [16.0] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 007B × 30CB × 30E5 × 30FC × 30FB × 007D ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 007B × 30CB × 30E5 × 30FC × 007D × 30FB ÷ 30E8 × 30FC ÷ 30AF ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] KATAKANA LETTER NI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [13.02] RIGHT CURLY BRACKET (CL) × [16.0] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER YO (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 0028 × 1850 × 1846 × 1851 × 1846 ÷ 1806 × 0029 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
-× 0028 × 1850 × 1846 × 1851 × 1846 × 0029 ÷ 1806 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [21.04] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
-× 007B × 1850 × 1846 × 1851 × 1846 ÷ 1806 × 007D ÷ 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
-× 007B × 1850 × 1846 × 1851 × 1846 × 007D ÷ 1806 × 182A × 1822 × 1834 × 1822 × 182D × 180C ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] MONGOLIAN LETTER TODO TA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [28.0] MONGOLIAN LETTER TODO DA (AL) × [28.0] MONGOLIAN LETTER TODO O (AL) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] MONGOLIAN TODO SOFT HYPHEN (BB) × [21.04] MONGOLIAN LETTER BA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER CHA (AL) × [28.0] MONGOLIAN LETTER I (AL) × [28.0] MONGOLIAN LETTER GA (AL) × [9.0] MONGOLIAN FREE VARIATION SELECTOR TWO (CM1_CM) ÷ [0.3]
-× 0028 × 0068 × 0074 × 0074 × 0070 × 003A × 002F × 002F × 0029 × 0078 × 006E × 002D × 002D ÷ 0061 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER P (AL) × [13.02] COLON (IS) × [13.02] SOLIDUS (SY) × [13.02] SOLIDUS (SY) × [13.02] RIGHT PARENTHESIS (CP) × [30.02] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 007B × 0068 × 0074 × 0074 × 0070 × 003A × 002F × 002F × 007D ÷ 0078 × 006E × 002D × 002D ÷ 0061 ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER T (AL) × [28.0] LATIN SMALL LETTER P (AL) × [13.02] COLON (IS) × [13.02] SOLIDUS (SY) × [13.02] SOLIDUS (SY) × [13.02] RIGHT CURLY BRACKET (CL) ÷ [999.0] LATIN SMALL LETTER X (AL) × [28.0] LATIN SMALL LETTER N (AL) × [21.02] HYPHEN-MINUS (HY) × [21.02] HYPHEN-MINUS (HY) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 0028 × 0030 × 002C × 0031 × 0029 × 002B × 0028 × 0032 × 002C × 0033 × 0029 × 2295 × 0028 × 2212 × 0034 × 002C × 0035 × 0029 × 2296 × 0028 × 0036 × 002C × 0037 × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] DIGIT ZERO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT ONE (NU) × [25.04] RIGHT PARENTHESIS (CP) × [25.05] PLUS SIGN (PR) × [25.01] LEFT PARENTHESIS (OP) × [14.0] DIGIT TWO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT THREE (NU) × [25.04] RIGHT PARENTHESIS (CP) × [30.02] CIRCLED PLUS (AI_AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] MINUS SIGN (PR) × [25.01] DIGIT FOUR (NU) × [25.03] COMMA (IS) × [25.04] DIGIT FIVE (NU) × [25.04] RIGHT PARENTHESIS (CP) × [30.02] CIRCLED MINUS (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] DIGIT SIX (NU) × [25.03] COMMA (IS) × [25.04] DIGIT SEVEN (NU) × [25.04] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 007B × 0030 × 002C × 0031 × 007D × 002B × 007B × 0032 × 002C × 0033 × 007D ÷ 2295 × 007B × 2212 × 0034 × 002C × 0035 × 007D ÷ 2296 × 007B × 0036 × 002C × 0037 × 007D ÷ # × [0.3] LEFT CURLY BRACKET (OP) × [14.0] DIGIT ZERO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT ONE (NU) × [25.04] RIGHT CURLY BRACKET (CL) × [25.05] PLUS SIGN (PR) × [25.01] LEFT CURLY BRACKET (OP) × [14.0] DIGIT TWO (NU) × [25.03] COMMA (IS) × [25.04] DIGIT THREE (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [999.0] CIRCLED PLUS (AI_AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] MINUS SIGN (PR) × [25.01] DIGIT FOUR (NU) × [25.03] COMMA (IS) × [25.04] DIGIT FIVE (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [999.0] CIRCLED MINUS (AL) × [30.01] LEFT CURLY BRACKET (OP) × [14.0] DIGIT SIX (NU) × [25.03] COMMA (IS) × [25.04] DIGIT SEVEN (NU) × [25.04] RIGHT CURLY BRACKET (CL) ÷ [0.3]
-× 0061 × 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
-× 0061 × 0062 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 0061 × 0062 × 0020 ÷ 0063 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) ÷ [0.3]
-× 0061 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 0939 × 093F × 0928 × 094D × 0926 × 0940 × 0020 ÷ # × [0.3] DEVANAGARI LETTER HA (AL) × [9.0] DEVANAGARI VOWEL SIGN I (CM1_CM) × [28.0] DEVANAGARI LETTER NA (AL) × [9.0] DEVANAGARI SIGN VIRAMA (CM1_CM) × [28.0] DEVANAGARI LETTER DA (AL) × [9.0] DEVANAGARI VOWEL SIGN II (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 092F × 0938 × 0917 × 0941 × 091A × 093F × 0924 × 0940 × 092F × 0938 × 093E × 0020 ÷ # × [0.3] DEVANAGARI LETTER YA (AL) × [28.0] DEVANAGARI LETTER SA (AL) × [28.0] DEVANAGARI LETTER GA (AL) × [9.0] DEVANAGARI VOWEL SIGN U (CM1_CM) × [28.0] DEVANAGARI LETTER CA (AL) × [9.0] DEVANAGARI VOWEL SIGN I (CM1_CM) × [28.0] DEVANAGARI LETTER TA (AL) × [9.0] DEVANAGARI VOWEL SIGN II (CM1_CM) × [28.0] DEVANAGARI LETTER YA (AL) × [28.0] DEVANAGARI LETTER SA (AL) × [9.0] DEVANAGARI VOWEL SIGN AA (CM1_CM) × [7.01] SPACE (SP) ÷ [0.3]
-× 5370 ÷ 672C ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5370 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 8AAD ÷ 3080 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8AAD (ID) ÷ [999.0] HIRAGANA LETTER MU (ID) ÷ [0.3]
-× 5165 ÷ 529B ÷ 3057 ÷ 30A8 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5165 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-529B (ID) ÷ [999.0] HIRAGANA LETTER SI (ID) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
-× 4F4D × 3002 ÷ 8A18 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F4D (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8A18 (ID) ÷ [0.3]
-× 672C × 3002 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
-× 967A × 300D ÷ 306E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-967A (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
-× 3057 × 3087 ÷ 3046 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) ÷ [0.3]
-× 307E ÷ 0061 ÷ 672C ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LATIN SMALL LETTER A (AL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× C5C6 ÷ C5B4 ÷ C694 × 0020 ÷ 006F × 0072 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE EOBS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER R (AL) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
-× 307E ÷ 0061 × 0062 × 0020 ÷ # × [0.3] HIRAGANA LETTER MA (ID) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 3067 ÷ 4F7F ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [0.3]
-× 3059 ÷ 308B ÷ # × [0.3] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
-× 306E ÷ 30D1 ÷ 30F3 ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
-× 3046 × 3000 ÷ 3048 × 3000 ÷ 304A × 300D ÷ # × [0.3] HIRAGANA LETTER U (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER E (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER O (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [0.3]
-× 308B × 0020 ÷ C740 ÷ C601 × 0020 ÷ 306B ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE EUN (H3) ÷ [999.0] HANGUL SYLLABLE YEONG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
-× 3057 × 3087 ÷ 3046 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
-× 30E0 ÷ 306E ÷ 4E00 ÷ # × [0.3] KATAKANA LETTER MU (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) ÷ [0.3]
-× 30D5 ÷ 30EA ÷ # × [0.3] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) ÷ [0.3]
-× 30D5 ÷ 30EA × 30FC ÷ 767E ÷ # × [0.3] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-767E (ID) ÷ [0.3]
-× 30D4 × 30E5 × 30FC ÷ 30BF ÷ 3067 ÷ 4F7F ÷ 7528 ÷ 3059 ÷ 308B ÷ # × [0.3] KATAKANA LETTER PI (ID) × [21.03] KATAKANA LETTER SMALL YU (CJ_NS) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER TA (ID) ÷ [999.0] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-7528 (ID) ÷ [999.0] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
-× 30BF × 30FC ÷ 30AD × 30FC ÷ 3092 ÷ 62BC ÷ # × [0.3] KATAKANA LETTER TA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-62BC (ID) ÷ [0.3]
-× 30B7 × 30E7 ÷ 30F3 ÷ # × [0.3] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 0020 ÷ 0915 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] DEVANAGARI LETTER KA (AL) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 0020 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 3000 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 3000 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 3000 ÷ 0033 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] DIGIT THREE (NU) ÷ [0.3]
-× 0061 × 0062 × 002E × 0020 ÷ 0032 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT TWO (NU) ÷ [0.3]
-× 0041 × 002E ÷ 0031 × 0020 ÷ BABB ÷ # × [0.3] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT ONE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
-× BD24 ÷ C5B4 × 002E × 0020 ÷ 0041 × 002E ÷ 0032 × 0020 ÷ BCFC ÷ # × [0.3] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE BOL (H3) ÷ [0.3]
-× BD10 ÷ C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0033 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE BWA (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
-× C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0034 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT FOUR (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
-× 0061 × 002E ÷ 0032 × 3000 ÷ 300C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] LEFT CORNER BRACKET (OP) ÷ [0.3]
-× 306B ÷ 300C × 30D0 ÷ 0028 × 0062 × 0061 × 0029 × 300D ÷ 3084 ÷ 300C × 30B9 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER BA (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER YA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER SU (ID) ÷ [0.3]
-× 308B ÷ 300C × 0055 × 004B ÷ 30DD ÷ 30F3 ÷ 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] HIRAGANA LETTER RU (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LATIN CAPITAL LETTER U (AL) × [28.0] LATIN CAPITAL LETTER K (AL) ÷ [999.0] KATAKANA LETTER PO (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [999.0] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
-× 306F × 3001 ÷ 300C × 003D × 0072 × 0061 × 006E × 0064 × 0028 × 0029 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] EQUALS SIGN (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 3067 × 3001 ÷ 300C × 0021 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER DE (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 8A33 ÷ 300C × 3059 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A33 (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SU (ID) ÷ [0.3]
-× 3066 ÷ 300C × BD24 ÷ C5B4 × 003F × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TE (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 306E ÷ 300C × 305D ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SO (ID) ÷ [0.3]
-× 306F ÷ 300C × 30A8 ÷ # × [0.3] HIRAGANA LETTER HA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER E (ID) ÷ [0.3]
-× 4F8B × FF1A ÷ 300C × 3042 × 3000 ÷ 3044 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER A (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER I (ID) ÷ [0.3]
-× 304F × 3001 ÷ 300C × D3C9 ÷ C591 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER KU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE PYEONG (H3) ÷ [999.0] HANGUL SYLLABLE YANG (H3) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
-× 306B ÷ 300C × C81C ÷ BAA9 ÷ 0028 × 984C ÷ 540D × 0029 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE JE (H2) ÷ [999.0] HANGUL SYLLABLE MOG (H3) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-984C (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
-× 5178 ÷ 300E × 30A6 × 30A3 ÷ 30AD ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5178 (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] KATAKANA LETTER U (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) ÷ [0.3]
-× 3067 ÷ 300E × 82F1 ÷ 8A9E ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] CJK UNIFIED IDEOGRAPH-82F1 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-8A9E (ID) ÷ [0.3]
-× 0028 × 0073 × 0029 × 0020 ÷ 672C ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 0028 × 0073 × 0029 × 0020 ÷ 307E ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 0028 × 0073 × 0029 × 0020 ÷ 30AF ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 308B × 3002 ÷ 0064 × 006F × 0067 × FF08 × 72AC × FF09 ÷ 3092 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER G (AL) × [30.01] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-72AC (ID) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
-× 672C ÷ FF08 × 307E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 672C × 0020 ÷ 0028 × 0061 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 70B9 × 0020 ÷ 005B × 7DE8 ÷ 96C6 × 005D ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-70B9 (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT SQUARE BRACKET (OP) × [14.0] CJK UNIFIED IDEOGRAPH-7DE8 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-96C6 (ID) × [13.02] RIGHT SQUARE BRACKET (CP) ÷ [0.3]
-× 0061 × 0028 × 0073 × 0029 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [30.01] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [0.3]
-× FF08 × 30B6 × 30FB ÷ 30AF ÷ 30A4 × 30C3 ÷ 30AF × 30FB ÷ 30D6 ÷ # × [0.3] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER ZA (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] KATAKANA LETTER I (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER BU (ID) ÷ [0.3]
-× 0070 × FF08 × 30AF ÷ 30A4 × 30C3 ÷ 30AF × 30FB ÷ 30D6 ÷ # × [0.3] LATIN SMALL LETTER P (AL) × [30.01] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER KU (ID) ÷ [999.0] KATAKANA LETTER I (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER BU (ID) ÷ [0.3]
-× 0061 × 0062 × FF08 × 30AF ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [30.01] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 0028 × 5370 ÷ 672C × 0029 ÷ # × [0.3] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-5370 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [0.3]
-× 30B9 ÷ FF08 × 3044 ÷ # × [0.3] KATAKANA LETTER SU (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER I (ID) ÷ [0.3]
-× 30C9 ÷ FF08 × 30DD ÷ # × [0.3] KATAKANA LETTER DO (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] KATAKANA LETTER PO (ID) ÷ [0.3]
-× 30C9 × 0020 ÷ 0028 × 8CEA ÷ # × [0.3] KATAKANA LETTER DO (ID) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-8CEA (ID) ÷ [0.3]
-× 0073 × 0029 × 300D ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER S (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 0061 × FF09 × 300F ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] RIGHT WHITE CORNER BRACKET (CL) ÷ [0.3]
-× 308B × 300D × FF09 ÷ 306F ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) ÷ [999.0] HIRAGANA LETTER HA (ID) ÷ [0.3]
-× 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
-× 0072 × 006B × 0029 × 300D ÷ 3082 ÷ # × [0.3] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER K (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MO (ID) ÷ [0.3]
-× 30AF ÷ 0028 × 0061 × 0062 × 0020 ÷ 0063 × 0064 × 0029 × 300D ÷ 3082 ÷ # × [0.3] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [18.0] LATIN SMALL LETTER C (AL) × [28.0] LATIN SMALL LETTER D (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MO (ID) ÷ [0.3]
-× 30F3 × 30FB ÷ 30DE × 30FC ÷ 30AF ÷ 0028 × 0065 × 0078 ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER E (AL) × [28.0] LATIN SMALL LETTER X (AL) ÷ [0.3]
-× 30DE × 30FC ÷ 0028 × 006D × 0061 × 0029 × 300D ÷ 306A ÷ # × [0.3] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER M (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER NA (ID) ÷ [0.3]
-× 30AC ÷ 30EF × 300D × 3002 ÷ 3053 ÷ # × [0.3] KATAKANA LETTER GA (ID) ÷ [999.0] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
-× 30AF × 300D ÷ 307E ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 30EF × 300D × 3002 ÷ 3053 ÷ # × [0.3] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
-× 30AF × 300D ÷ 307E × 3001 ÷ 672C ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 30AF × 300D × 3001 ÷ 30AF ÷ # × [0.3] KATAKANA LETTER KU (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 30C7 × 30A3 ÷ 30A2 ÷ FF08 × 0061 × 0062 × FF09 × 300F ÷ # × [0.3] KATAKANA LETTER DE (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER A (ID) ÷ [999.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] RIGHT WHITE CORNER BRACKET (CL) ÷ [0.3]
-× CABD ÷ C774 ÷ C5D0 ÷ C694 × 003F × 300D ÷ 3068 ÷ 805E ÷ # × [0.3] HANGUL SYLLABLE JJOG (H3) ÷ [999.0] HANGUL SYLLABLE I (H2) ÷ [999.0] HANGUL SYLLABLE E (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-805E (ID) ÷ [0.3]
-× 540D × 0029 ÷ C740 × 0020 ÷ C54C ÷ C544 ÷ C694 × 003F × 300D ÷ 3068 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE EUN (H3) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE AL (H3) ÷ [999.0] HANGUL SYLLABLE A (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 8CA8 × 0029 × 0020 ÷ 002D × 0020 ÷ 0028 × 0070 × 006F ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8CA8 (ID) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) ÷ [18.0] HYPHEN-MINUS (HY) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [0.3]
-× 91CF × 0029 × 0020 × 301C × 0020 ÷ 0028 × 0070 × 006F ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-91CF (ID) × [13.02] RIGHT PARENTHESIS (CP) × [7.01] SPACE (SP) × [16.0] WAVE DASH (NS) × [7.01] SPACE (SP) ÷ [18.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER P (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [0.3]
-× 30C9 ÷ 91CD × FF09 × 0020 × 301C × 0020 ÷ 529B × 30FB ÷ 91CD ÷ # × [0.3] KATAKANA LETTER DO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-91CD (ID) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [7.01] SPACE (SP) × [16.0] WAVE DASH (NS) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-529B (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-91CD (ID) ÷ [0.3]
-× 0061 × 0062 × 0022 × FF08 × 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [19.01] QUOTATION MARK (QU) × [15.0] FULLWIDTH LEFT PARENTHESIS (OP) × [14.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 306F × 0020 ÷ 0022 × 0073 × 0022 × 0020 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [7.01] SPACE (SP) ÷ [18.0] QUOTATION MARK (QU) × [19.02] LATIN SMALL LETTER S (AL) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [0.3]
-× 306F × 3001 × 0022 × 0054 × 0068 × 0065 × 0020 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [19.01] QUOTATION MARK (QU) × [19.02] LATIN CAPITAL LETTER T (AL) × [28.0] LATIN SMALL LETTER H (AL) × [28.0] LATIN SMALL LETTER E (AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 0064 × 006F × 0067 × 0022 × 0020 ÷ 3092 ÷ # × [0.3] LATIN SMALL LETTER D (AL) × [28.0] LATIN SMALL LETTER O (AL) × [28.0] LATIN SMALL LETTER G (AL) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
-× 0039 × 0030 × 0022 × 0020 ÷ 3068 ÷ # × [0.3] DIGIT NINE (NU) × [25.03] DIGIT ZERO (NU) × [19.01] QUOTATION MARK (QU) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 30B9 × 30FB ÷ 30AA × 30FC ÷ 30D0 × 30FC × 30FB ÷ 30B6 × 30FB ÷ 30EC ÷ # × [0.3] KATAKANA LETTER SU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER O (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER BA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER ZA (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER RE (ID) ÷ [0.3]
-× 30B9 × 30FB ÷ 30B8 × 30E3 ÷ 30F3 ÷ # × [0.3] KATAKANA LETTER SU (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER ZI (ID) × [21.03] KATAKANA LETTER SMALL YA (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
-× 30F3 × 30FB ÷ 30D5 × 30A9 × 30C3 ÷ 30AF ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER HU (ID) × [21.03] KATAKANA LETTER SMALL O (CJ_NS) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 30A4 ÷ 30B8 × 30FC × 30FB ÷ 30C9 × 30C3 ÷ 30B0 × 3001 ÷ 548C ÷ # × [0.3] KATAKANA LETTER I (ID) ÷ [999.0] KATAKANA LETTER ZI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER DO (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER GU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-548C (ID) ÷ [0.3]
-× 30E1 × 30FC ÷ 30B7 × 30E7 ÷ 30F3 × 30FB ÷ 30DE × 30FC ÷ 30AF ÷ # × [0.3] KATAKANA LETTER ME (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 30F3 × 30FB ÷ 30AF ÷ 0028 × 0061 ÷ # × [0.3] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER KU (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER A (AL) ÷ [0.3]
-× 30B7 × 30E7 ÷ 30F3 × 30FB ÷ 30DE ÷ # × [0.3] KATAKANA LETTER SI (ID) × [21.03] KATAKANA LETTER SMALL YO (CJ_NS) ÷ [999.0] KATAKANA LETTER N (ID) × [21.03] KATAKANA MIDDLE DOT (NS) ÷ [999.0] KATAKANA LETTER MA (ID) ÷ [0.3]
-× 672C × 003A × 0020 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [0.3]
-× 672C × 003A × 0020 ÷ 30AF ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-672C (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER KU (ID) ÷ [0.3]
-× 51FA ÷ 5178 × 003A × 0020 ÷ 30D5 ÷ 30EA × 30FC ÷ 767E ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-51FA (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5178 (ID) × [13.02] COLON (IS) × [7.01] SPACE (SP) ÷ [18.0] KATAKANA LETTER HU (ID) ÷ [999.0] KATAKANA LETTER RI (ID) × [21.03] KATAKANA-HIRAGANA PROLONGED SOUND MARK (CJ_NS) ÷ [999.0] CJK UNIFIED IDEOGRAPH-767E (ID) ÷ [0.3]
-× 5F8C × 2026 ÷ 306B ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5F8C (ID) × [22.03] HORIZONTAL ELLIPSIS (IN) ÷ [999.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
-× 3057 × 3087 ÷ 3046 × 3002 × 3002 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
-× 304D × 3001 × 0021 × 0021 × 3001 × 0021 × 0021 × 0021 ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER KI (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.01] EXCLAMATION MARK (EX) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 306F × 3001 × 003F ÷ 3068 × 0021 ÷ 3092 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [13.01] QUESTION MARK (EX) ÷ [999.0] HIRAGANA LETTER TO (ID) × [13.01] EXCLAMATION MARK (EX) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
-× 305F × 3001 × 2049 ÷ 0028 × 0021 × 003F × 0029 ÷ 306E ÷ # × [0.3] HIRAGANA LETTER TA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [16.0] EXCLAMATION QUESTION MARK (NS) ÷ [999.0] LEFT PARENTHESIS (OP) × [13.01] EXCLAMATION MARK (EX) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
-× 3084 × 3001 × 2048 ÷ 0028 × 003F × 0021 × 0029 ÷ 306E ÷ # × [0.3] HIRAGANA LETTER YA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) × [16.0] QUESTION EXCLAMATION MARK (NS) ÷ [999.0] LEFT PARENTHESIS (OP) × [13.01] QUESTION MARK (EX) × [13.01] EXCLAMATION MARK (EX) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [0.3]
-× 305F × 0020 ÷ 203D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TA (ID) × [7.01] SPACE (SP) ÷ [18.0] INTERROBANG (NS) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 305B × FF01 ÷ 0031 × 0030 × 0030 × 0025 ÷ 306E ÷ 5B8C ÷ # × [0.3] HIRAGANA LETTER SE (ID) × [13.01] FULLWIDTH EXCLAMATION MARK (EX) ÷ [999.0] DIGIT ONE (NU) × [25.03] DIGIT ZERO (NU) × [25.03] DIGIT ZERO (NU) × [25.05] PERCENT SIGN (PO) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B8C (ID) ÷ [0.3]
-× 0032 × 0033 ÷ 672C ÷ # × [0.3] DIGIT TWO (NU) × [25.03] DIGIT THREE (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 30A1 ÷ 30D9 × 30C3 ÷ 30C8 ÷ 0032 × 0036 ÷ 5B57 ÷ 3092 ÷ # × [0.3] KATAKANA LETTER SMALL A (CJ_NS) ÷ [999.0] KATAKANA LETTER BE (ID) × [21.03] KATAKANA LETTER SMALL TU (CJ_NS) ÷ [999.0] KATAKANA LETTER TO (ID) ÷ [999.0] DIGIT TWO (NU) × [25.03] DIGIT SIX (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B57 (ID) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
-× 4F8B × FF1A ÷ 00A3 × 0032 × 0033 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] POUND SIGN (PR) × [25.01] DIGIT TWO (NU) × [25.03] DIGIT THREE (NU) ÷ [0.3]
-× 8A18 ÷ 53F7 × 0020 ÷ 00A3 × 3002 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A18 (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-53F7 (ID) × [7.01] SPACE (SP) ÷ [18.0] POUND SIGN (PR) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
-× 308C ÷ 308B × 3002 ÷ 0071 × 0075 ÷ # × [0.3] HIRAGANA LETTER RE (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER Q (AL) × [28.0] LATIN SMALL LETTER U (AL) ÷ [0.3]
-× 307E × 3002 ÷ # × [0.3] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
-× 307E × 3002 ÷ 0061 × 0062 × 0020 ÷ # × [0.3] HIRAGANA LETTER MA (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [7.01] SPACE (SP) ÷ [0.3]
-× 308B × 3002 ÷ 6570 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-6570 (ID) ÷ [0.3]
-× 308B × 3002 ÷ 3053 ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [0.3]
-× 3044 × 3002 ÷ 30D1 ÷ # × [0.3] HIRAGANA LETTER I (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [0.3]
-× 30AC ÷ 30EF × 300D × 3002 ÷ 3053 ÷ 308C ÷ # × [0.3] KATAKANA LETTER GA (ID) ÷ [999.0] KATAKANA LETTER WA (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [999.0] HIRAGANA LETTER RE (ID) ÷ [0.3]
-× 8A9E ÷ 306E ÷ 0069 × 006F ÷ 306E × 3001 ÷ 0032 ÷ 5B57 ÷ 3092 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-8A9E (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] LATIN SMALL LETTER I (AL) × [28.0] LATIN SMALL LETTER O (AL) ÷ [999.0] HIRAGANA LETTER NO (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] CJK UNIFIED IDEOGRAPH-5B57 (ID) ÷ [999.0] HIRAGANA LETTER WO (ID) ÷ [0.3]
-× 3001 ÷ 548C ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] CJK UNIFIED IDEOGRAPH-548C (ID) ÷ [0.3]
-× 3001 ÷ 30BF ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER TA (ID) ÷ [0.3]
-× 3001 ÷ 304B ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] HIRAGANA LETTER KA (ID) ÷ [0.3]
-× 3001 ÷ 3053 ÷ 308C ÷ 3067 ÷ 306F × 0020 ÷ # × [0.3] IDEOGRAPHIC COMMA (CL) ÷ [999.0] HIRAGANA LETTER KO (ID) ÷ [999.0] HIRAGANA LETTER RE (ID) ÷ [999.0] HIRAGANA LETTER DE (ID) ÷ [999.0] HIRAGANA LETTER HA (ID) × [7.01] SPACE (SP) ÷ [0.3]
-× 3057 × 3001 ÷ 0061 × 0062 ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
-× 0061 ÷ 1F1E6 ÷ 0062 ÷ # × [0.3] LATIN SMALL LETTER A (AL) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER B (AL) ÷ [0.3]
-× 1F1F7 × 1F1FA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [0.3]
-× 1F1F7 × 1F1FA ÷ 1F1F8 ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [30.13] REGIONAL INDICATOR SYMBOL LETTER S (RI) ÷ [0.3]
-× 1F1F7 × 1F1FA ÷ 1F1F8 × 1F1EA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) ÷ [30.13] REGIONAL INDICATOR SYMBOL LETTER S (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER E (RI) ÷ [0.3]
-× 1F1F7 × 1F1FA × 200B ÷ 1F1F8 × 1F1EA ÷ # × [0.3] REGIONAL INDICATOR SYMBOL LETTER R (RI) × [30.11] REGIONAL INDICATOR SYMBOL LETTER U (RI) × [7.02] ZERO WIDTH SPACE (ZW) ÷ [8.0] REGIONAL INDICATOR SYMBOL LETTER S (RI) × [30.12] REGIONAL INDICATOR SYMBOL LETTER E (RI) ÷ [0.3]
-× 05D0 × 002D × 05D0 ÷ # × [0.3] HEBREW LETTER ALEF (HL) × [21.02] HYPHEN-MINUS (HY) × [21.1] HEBREW LETTER ALEF (HL) ÷ [0.3]
-#
-# Lines: 7312
-#
-# EOF
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt
deleted file mode 100644
index 2985b84cf8..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt
+++ /dev/null
@@ -1,530 +0,0 @@
-# SentenceBreakTest-10.0.0.txt
-# Date: 2017-04-14, 05:40:43 GMT
-# © 2017 Unicode®, Inc.
-# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
-#
-# Default Sentence_Break Test
-#
-# Format:
-# <string> (# <comment>)?
-# <string> contains hex Unicode code points, with
-# ÷ wherever there is a break opportunity, and
-# × wherever there is not.
-# <comment> the format can change, but currently it shows:
-# - the sample character name
-# - (x) the Sentence_Break property value for the sample character
-# - [x] the rule that determines whether there is a break or not,
-# as listed in the Rules section of SentenceBreakTest.html
-#
-# These samples may be extended or changed in the future.
-#
-÷ 0001 × 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0001 × 0308 × 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0001 × 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0001 × 0308 × 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0001 × 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0001 × 0308 × 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0001 × 0085 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0001 × 0308 × 0085 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0001 × 0009 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0001 × 0308 × 0009 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0001 × 0061 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0001 × 0308 × 0061 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0001 × 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0001 × 0308 × 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0001 × 01BB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0001 × 0308 × 01BB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0001 × 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0001 × 0308 × 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0001 × 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0001 × 0308 × 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0001 × 0021 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0001 × 0308 × 0021 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0001 × 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0001 × 0308 × 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0001 × 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0001 × 0308 × 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0001 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0001 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000D ÷ 0308 × 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000D ÷ 0308 × 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000D ÷ 0308 × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000D ÷ 0085 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 000D ÷ 0308 × 0085 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 000D ÷ 0009 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 000D ÷ 0308 × 0009 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 000D ÷ 0308 × 0061 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 000D ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 000D ÷ 0308 × 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 000D ÷ 01BB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 000D ÷ 0308 × 01BB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 000D ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000D ÷ 0308 × 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000D ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 000D ÷ 0308 × 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 000D ÷ 0021 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 000D ÷ 0308 × 0021 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 000D ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 000D ÷ 0308 × 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 000D ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
-÷ 000D ÷ 0308 × 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 000D ÷ 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000A ÷ 0308 × 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000A ÷ 0308 × 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000A ÷ 0308 × 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000A ÷ 0085 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 000A ÷ 0308 × 0085 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 000A ÷ 0009 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 000A ÷ 0308 × 0009 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 000A ÷ 0308 × 0061 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 000A ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 000A ÷ 0308 × 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 000A ÷ 01BB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 000A ÷ 0308 × 01BB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 000A ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000A ÷ 0308 × 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000A ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 000A ÷ 0308 × 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 000A ÷ 0021 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 000A ÷ 0308 × 0021 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 000A ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 000A ÷ 0308 × 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 000A ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
-÷ 000A ÷ 0308 × 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 000A ÷ 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0085 ÷ 0001 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0001 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0085 ÷ 000D ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0085 ÷ 0308 × 000D ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0085 ÷ 000A ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0085 ÷ 0308 × 000A ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0085 ÷ 0085 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0085 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0085 ÷ 0009 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0009 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0085 ÷ 0061 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0061 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0085 ÷ 0041 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0041 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0085 ÷ 01BB ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0085 ÷ 0308 × 01BB ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0085 ÷ 0030 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0030 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0085 ÷ 002E ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0085 ÷ 0308 × 002E ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0085 ÷ 0021 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0021 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0085 ÷ 0022 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0022 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0085 ÷ 002C ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMMA (SContinue) ÷ [0.3]
-÷ 0085 ÷ 0308 × 002C ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0085 ÷ 00AD ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0085 ÷ 0308 × 00AD ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0085 ÷ 0300 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0085 ÷ 0308 × 0300 ÷ # ÷ [0.2] <NEXT LINE (NEL)> (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0009 × 0001 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0009 × 0308 × 0001 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0009 × 000D ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0009 × 0308 × 000D ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0009 × 000A ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0009 × 0308 × 000A ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0009 × 0085 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0009 × 0308 × 0085 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0009 × 0009 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0009 × 0308 × 0009 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0009 × 0061 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0009 × 0308 × 0061 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0009 × 0041 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0009 × 0308 × 0041 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0009 × 01BB ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0009 × 0308 × 01BB ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0009 × 0030 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0009 × 0308 × 0030 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0009 × 002E ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0009 × 0308 × 002E ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0009 × 0021 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0009 × 0308 × 0021 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0009 × 0022 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0009 × 0308 × 0022 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0009 × 002C ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0009 × 0308 × 002C ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0009 × 00AD ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0009 × 0308 × 00AD ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0009 × 0300 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0009 × 0308 × 0300 ÷ # ÷ [0.2] <CHARACTER TABULATION> (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 × 0308 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 × 0308 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 × 0308 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0061 × 0308 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0061 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0061 × 0308 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0061 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0061 × 0308 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0061 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0061 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0061 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0061 × 0308 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0061 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0061 × 0308 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0061 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0061 × 0308 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0061 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0061 × 0308 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0061 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0061 × 0308 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0061 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0041 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0041 × 0308 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0041 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0041 × 0308 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0041 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0041 × 0308 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0041 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0041 × 0308 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0041 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0041 × 0308 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0041 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0041 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0041 × 0308 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0041 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0041 × 0308 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0041 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0041 × 0308 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0041 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0041 × 0308 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0041 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0041 × 0308 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 01BB × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 01BB × 0308 × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 01BB × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 01BB × 0308 × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 01BB × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 01BB × 0308 × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 01BB × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 01BB × 0308 × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 01BB × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 01BB × 0308 × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 01BB × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 01BB × 0308 × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 01BB × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 01BB × 0308 × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 01BB × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 01BB × 0308 × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 01BB × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 01BB × 0308 × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 01BB × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 01BB × 0308 × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 01BB × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 01BB × 0308 × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 01BB × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 01BB × 0308 × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 01BB × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 01BB × 0308 × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 01BB × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 01BB × 0308 × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 01BB × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 01BB × 0308 × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0030 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0030 × 0308 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0030 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0030 × 0308 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0030 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0030 × 0308 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0030 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0030 × 0308 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0030 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0030 × 0308 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0030 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0030 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0030 × 0308 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0030 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0030 × 0308 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0030 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0030 × 0308 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0030 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0030 × 0308 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0030 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0030 × 0308 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002E × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002E × 0308 × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002E × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002E × 0308 × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002E × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 002E × 0308 × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 002E × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 002E × 0308 × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 002E × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 002E × 0308 × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 002E ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 002E × 0308 ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 002E × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002E × 0308 × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002E × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] FULL STOP (ATerm) ÷ [0.3]
-÷ 002E × 0308 × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3]
-÷ 002E × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 002E × 0308 × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 002E × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 002E × 0308 × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 002E × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] COMMA (SContinue) ÷ [0.3]
-÷ 002E × 0308 × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3]
-÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0021 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0021 × 0308 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0021 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0021 × 0308 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0021 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0021 × 0308 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0021 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0021 × 0308 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0021 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0021 × 0308 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0021 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0021 × 0308 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0021 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0021 × 0308 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0021 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0021 × 0308 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0021 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0021 × 0308 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0021 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] FULL STOP (ATerm) ÷ [0.3]
-÷ 0021 × 0308 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3]
-÷ 0021 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0021 × 0308 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0021 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0021 × 0308 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0021 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] COMMA (SContinue) ÷ [0.3]
-÷ 0021 × 0308 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3]
-÷ 0021 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0021 × 0308 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0021 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0021 × 0308 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0022 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0022 × 0308 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0022 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0022 × 0308 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0022 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0022 × 0308 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0022 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0022 × 0308 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0022 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0022 × 0308 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0022 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0022 × 0308 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0022 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0022 × 0308 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0022 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0022 × 0308 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0022 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0022 × 0308 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0022 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0022 × 0308 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0022 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0022 × 0308 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0022 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0022 × 0308 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0022 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0022 × 0308 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002C × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002C × 0308 × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002C × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002C × 0308 × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002C × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002C × 0308 × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002C × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 002C × 0308 × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 002C × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 002C × 0308 × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 002C × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 002C × 0308 × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 002C × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 002C × 0308 × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 002C × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 002C × 0308 × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 002C × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002C × 0308 × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002C × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 002C × 0308 × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 002C × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 002C × 0308 × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 002C × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 002C × 0308 × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 002C × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 002C × 0308 × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 00AD × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 00AD × 0308 × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 00AD × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 00AD × 0308 × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 00AD × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 00AD × 0308 × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 00AD × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 00AD × 0308 × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 00AD × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 00AD × 0308 × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 00AD × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 00AD × 0308 × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 00AD × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 00AD × 0308 × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 00AD × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 00AD × 0308 × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 00AD × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 00AD × 0308 × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 00AD × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 00AD × 0308 × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 00AD × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 00AD × 0308 × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 00AD × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 00AD × 0308 × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 00AD × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 00AD × 0308 × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0300 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0300 × 0308 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0300 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0300 × 0308 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0300 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0300 × 0308 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0300 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0300 × 0308 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <NEXT LINE (NEL)> (Sep) ÷ [0.3]
-÷ 0300 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0300 × 0308 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] <CHARACTER TABULATION> (Sp) ÷ [0.3]
-÷ 0300 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0300 × 0308 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3]
-÷ 0300 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0300 × 0308 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3]
-÷ 0300 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0300 × 0308 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3]
-÷ 0300 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0300 × 0308 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0300 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0300 × 0308 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0300 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0300 × 0308 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3]
-÷ 0300 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0300 × 0308 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3]
-÷ 0300 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0300 × 0308 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3]
-÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) × [998.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
-÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
-÷ 0020 × 200D × 0646 ÷ # ÷ [0.2] SPACE (Sp) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] ARABIC LETTER NOON (OLetter) ÷ [0.3]
-÷ 0646 × 200D × 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (OLetter) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] SPACE (Sp) ÷ [0.3]
-÷ 0028 × 0022 × 0047 × 006F × 002E × 0022 × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3]
-÷ 0028 × 201C × 0047 × 006F × 003F × 201D × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] QUESTION MARK (STerm) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3]
-÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E × 0020 × 0069 × 0073 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER S (Lower) ÷ [0.3]
-÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 003F × 0020 ÷ 0048 × 0065 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [9.0] SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3]
-÷ 0033 × 002E × 0034 ÷ # ÷ [0.2] DIGIT THREE (Numeric) × [998.0] FULL STOP (ATerm) × [6.0] DIGIT FOUR (Numeric) ÷ [0.3]
-÷ 0063 × 002E × 0064 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3]
-÷ 0043 × 002E × 0064 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3]
-÷ 0063 × 002E × 0044 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3]
-÷ 0043 × 002E × 0044 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 2018 × 0028 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 2018 × 0028 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 0029 × 000A ÷ 0308 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 0074 × 0068 × 0065 × 0020 × 0072 × 0065 × 0073 × 0070 × 002E × 0020 × 006C × 0065 × 0061 × 0064 × 0065 × 0072 × 0073 × 0020 × 0061 × 0072 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] LATIN SMALL LETTER P (Lower) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER L (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3]
-÷ 5B57 × 002E ÷ 5B57 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E ÷ 5B83 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3]
-÷ 0065 × 0074 × 0063 × 002E × 3002 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.1] IDEOGRAPHIC FULL STOP (STerm) ÷ [0.3]
-÷ 5B57 × 3002 ÷ 5B83 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] IDEOGRAPHIC FULL STOP (STerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3]
-÷ 0021 × 0020 × 0020 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] SPACE (Sp) × [10.0] SPACE (Sp) ÷ [0.3]
-÷ 2060 × 0028 × 2060 × 0022 × 2060 × 0047 × 2060 × 006F × 2060 × 002E × 2060 × 0022 × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0028 × 2060 × 201C × 2060 × 0047 × 2060 × 006F × 2060 × 003F × 2060 × 201D × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 0020 × 2060 × 0069 × 2060 × 0073 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 003F × 2060 × 0020 × 2060 ÷ 0048 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0033 × 2060 × 002E × 2060 × 0034 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] DIGIT THREE (Numeric) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [6.0] DIGIT FOUR (Numeric) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0063 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0043 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0063 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0043 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 2018 × 2060 × 0028 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 2018 × 2060 × 0028 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 000A ÷ 2060 × 0308 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] <LINE FEED (LF)> (LF) ÷ [4.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 0020 × 2060 × 0072 × 2060 × 0065 × 2060 × 0073 × 2060 × 0070 × 2060 × 002E × 2060 × 0020 × 2060 × 006C × 2060 × 0065 × 2060 × 0061 × 2060 × 0064 × 2060 × 0065 × 2060 × 0072 × 2060 × 0073 × 2060 × 0020 × 2060 × 0061 × 2060 × 0072 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER P (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER L (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 5B57 × 2060 × 002E × 2060 ÷ 5B57 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 3002 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.1] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 5B57 × 2060 × 3002 × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2060 × 0021 × 2060 × 0020 × 2060 × 0020 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] EXCLAMATION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [10.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3]
-#
-# Lines: 502
-#
-# EOF
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt
deleted file mode 100644
index 63761026ce..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt
+++ /dev/null
@@ -1,2085 +0,0 @@
-# WordBreakTest-10.0.0.txt
-# Date: 2017-04-14, 05:40:44 GMT
-# © 2017 Unicode®, Inc.
-# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
-#
-# Default Word_Break Test
-#
-# Format:
-# <string> (# <comment>)?
-# <string> contains hex Unicode code points, with
-# ÷ wherever there is a break opportunity, and
-# × wherever there is not.
-# <comment> the format can change, but currently it shows:
-# - the sample character name
-# - (x) the Word_Break property value for the sample character
-# - [x] the rule that determines whether there is a break or not,
-# as listed in the Rules section of WordBreakTest.html
-#
-# These samples may be extended or changed in the future.
-#
-÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0001 × 0308 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0001 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0001 × 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0001 ÷ 000B ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0001 × 0308 ÷ 000B ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0001 ÷ 3031 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0001 × 0308 ÷ 3031 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0001 ÷ 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0041 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0001 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 × 0308 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 × 0308 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 ÷ 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0001 × 0308 ÷ 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0001 ÷ 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0001 ÷ 005F ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0001 × 0308 ÷ 005F ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0001 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0001 ÷ 05D0 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0001 × 0308 ÷ 05D0 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0001 ÷ 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0001 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0001 ÷ 261D ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0001 × 0308 ÷ 261D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0001 ÷ 1F3FB ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0001 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0001 ÷ 2640 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0001 × 0308 ÷ 2640 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0001 ÷ 1F466 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0001 × 0308 ÷ 1F466 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0001 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0001 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0001 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0001 × 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0001 ÷ 0061 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0001 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0001 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0001 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000D × 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000D ÷ 000B ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 000B ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 000D ÷ 3031 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 000D ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 000D ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 000D ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000D ÷ 005F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000D ÷ 05D0 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 000D ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 000D ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000D ÷ 261D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000D ÷ 1F3FB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000D ÷ 2640 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000D ÷ 1F466 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] BOY (EBG) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 000D ÷ 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 000D ÷ 0061 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000A ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000A ÷ 000B ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 000B ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 000A ÷ 3031 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 000A ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 000A ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 000A ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000A ÷ 005F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000A ÷ 05D0 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 000A ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 000A ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000A ÷ 261D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000A ÷ 1F3FB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000A ÷ 2640 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000A ÷ 1F466 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] BOY (EBG) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 000A ÷ 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 000A ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0001 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 000B ÷ 000D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 000B ÷ 000A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 000B ÷ 000B ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 000B ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 000B ÷ 3031 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 000B ÷ 0041 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 000B ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 002E ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 000B ÷ 0030 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 000B ÷ 005F ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 000B ÷ 1F1E6 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 000B ÷ 05D0 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 000B ÷ 0022 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 000B ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000B ÷ 261D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 261D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 000B ÷ 1F3FB ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 1F3FB ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 000B ÷ 2640 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 2640 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 000B ÷ 1F466 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] BOY (EBG) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 1F466 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 000B ÷ 00AD ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0300 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000B ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 000B ÷ 200D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 000B ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 000B ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 000B ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 ÷ 0001 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0001 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 3031 ÷ 000D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 3031 × 0308 ÷ 000D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 3031 ÷ 000A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 3031 × 0308 ÷ 000A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 3031 ÷ 000B ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 3031 × 0308 ÷ 000B ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 3031 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 3031 × 0308 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 3031 ÷ 0041 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0041 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 3031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 × 0308 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 × 0308 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 3031 × 0308 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 3031 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 3031 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 3031 × 0308 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 3031 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 3031 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 3031 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 3031 × 0308 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 3031 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 3031 ÷ 261D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 3031 × 0308 ÷ 261D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 3031 ÷ 1F3FB ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 3031 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 3031 ÷ 2640 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 3031 × 0308 ÷ 2640 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 3031 ÷ 1F466 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 3031 × 0308 ÷ 1F466 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 3031 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 3031 × 0308 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 3031 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 3031 × 0308 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 3031 × 200D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 3031 × 0308 × 200D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 3031 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 3031 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 ÷ 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0041 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0041 ÷ 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0041 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0041 ÷ 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0041 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0041 ÷ 000B ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0041 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0041 ÷ 3031 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0041 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0041 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0041 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0041 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0041 × 0308 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0041 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0041 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0041 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0041 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0041 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0041 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0041 ÷ 261D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0041 × 0308 ÷ 261D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0041 ÷ 1F3FB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0041 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0041 ÷ 2640 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0041 × 0308 ÷ 2640 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0041 ÷ 1F466 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0041 × 0308 ÷ 1F466 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0041 × 200D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0041 × 0308 × 200D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0041 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0041 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A ÷ 0001 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 003A ÷ 000D ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 003A ÷ 000A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 003A ÷ 000B ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 003A ÷ 3031 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 003A ÷ 0041 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 003A × 0308 ÷ 0041 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 003A ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 003A ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 003A ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 003A ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 003A ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 003A ÷ 261D ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 003A × 0308 ÷ 261D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 003A ÷ 1F3FB ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 003A × 0308 ÷ 1F3FB ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 003A ÷ 2640 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 003A × 0308 ÷ 2640 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 003A ÷ 1F466 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 003A × 0308 ÷ 1F466 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 003A × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 003A × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 003A × 200D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 003A × 0308 × 200D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 003A ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C ÷ 0001 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002C ÷ 000D ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002C ÷ 000A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002C ÷ 000B ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 002C ÷ 3031 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 002C ÷ 0041 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 002C ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 002C ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002C ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 002C ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 002C ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002C ÷ 261D ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 002C × 0308 ÷ 261D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 002C ÷ 1F3FB ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 002C × 0308 ÷ 1F3FB ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 002C ÷ 2640 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 002C × 0308 ÷ 2640 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 002C ÷ 1F466 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 002C × 0308 ÷ 1F466 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002C × 200D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 002C × 0308 × 200D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 002E ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002E × 0308 ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 002E ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002E × 0308 ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 002E ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 002E × 0308 ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 002E ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 002E × 0308 ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 002E ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002E × 0308 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002E ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002E × 0308 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002E ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 002E × 0308 ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 002E ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002E × 0308 ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 002E ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 002E × 0308 ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 002E ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 002E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 002E ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 002E × 0308 ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 002E ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 002E × 0308 ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 002E ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002E × 0308 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002E ÷ 261D ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 002E × 0308 ÷ 261D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 002E ÷ 1F3FB ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 002E × 0308 ÷ 1F3FB ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 002E ÷ 2640 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 002E × 0308 ÷ 2640 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 002E ÷ 1F466 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 002E × 0308 ÷ 1F466 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 002E × 200D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 002E × 0308 × 200D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 002E ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002E × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002E ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002E × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002E ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002E × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002E ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002E × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002E ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002E × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002E ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002E × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002E ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002E × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 002E ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002E × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002E ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002E × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0030 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0030 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0030 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0030 ÷ 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0030 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0030 ÷ 000B ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0030 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0030 ÷ 3031 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0030 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0030 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0030 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0030 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0030 × 0308 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0030 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0030 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0030 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0030 × 0308 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0030 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0030 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0030 ÷ 261D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0030 × 0308 ÷ 261D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0030 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0030 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0030 ÷ 2640 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0030 × 0308 ÷ 2640 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0030 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0030 × 0308 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0030 × 200D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0030 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0030 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0030 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F ÷ 0001 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 005F × 0308 ÷ 0001 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 005F ÷ 000D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 005F × 0308 ÷ 000D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 005F ÷ 000A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 005F × 0308 ÷ 000A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 005F ÷ 000B ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 005F × 0308 ÷ 000B ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 005F × 3031 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 005F × 0308 × 3031 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 005F × 0041 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 005F × 0308 × 0041 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 005F ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0308 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F × 0308 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 005F × 0308 ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 005F × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 005F × 0308 × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 005F × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 005F × 0308 × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 005F ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 005F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 005F × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 005F × 0308 × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 005F ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 005F × 0308 ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 005F ÷ 261D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 005F × 0308 ÷ 261D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 005F ÷ 1F3FB ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 005F × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 005F ÷ 2640 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 005F × 0308 ÷ 2640 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 005F ÷ 1F466 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 005F × 0308 ÷ 1F466 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 005F × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 005F × 0308 × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 005F × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 005F × 0308 × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 005F × 200D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 005F × 0308 × 200D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 005F × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 005F × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F1E6 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 1F1E6 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 1F1E6 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F1E6 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 1F1E6 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 1F1E6 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F1E6 × 0308 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [15.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F1E6 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 1F1E6 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 1F1E6 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F1E6 ÷ 261D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 261D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F1E6 ÷ 1F3FB ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F1E6 ÷ 2640 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 2640 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F1E6 ÷ 1F466 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 1F466 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F1E6 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F1E6 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 05D0 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 05D0 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 05D0 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 05D0 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 05D0 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 05D0 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 05D0 × 0308 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 05D0 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 05D0 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 05D0 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 05D0 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 05D0 × 0308 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 05D0 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 05D0 × 0308 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 05D0 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 05D0 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 05D0 × 0308 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 05D0 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 × 0308 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 ÷ 261D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 261D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 05D0 ÷ 1F3FB ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 05D0 ÷ 2640 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 2640 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 05D0 ÷ 1F466 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 05D0 × 0308 ÷ 1F466 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 05D0 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 05D0 × 0308 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 05D0 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 05D0 × 0308 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 05D0 × 200D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 05D0 × 0308 × 200D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 05D0 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 05D0 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 05D0 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 05D0 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 05D0 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 05D0 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 05D0 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 05D0 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 05D0 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 05D0 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 05D0 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 05D0 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 05D0 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 05D0 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0022 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0022 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0022 × 0308 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0022 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0022 × 0308 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0022 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0022 × 0308 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0022 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0022 × 0308 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0022 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0022 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0022 × 0308 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0022 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0022 × 0308 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0022 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0022 × 0308 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0022 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0022 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0022 × 0308 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0022 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0022 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0022 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0022 × 0308 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0022 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0022 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0022 ÷ 261D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0022 × 0308 ÷ 261D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0022 ÷ 1F3FB ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0022 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0022 ÷ 2640 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0022 × 0308 ÷ 2640 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0022 ÷ 1F466 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0022 × 0308 ÷ 1F466 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0022 × 200D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0022 × 0308 × 200D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0022 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0022 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0022 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0022 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0022 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0022 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0022 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0022 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0022 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0022 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0027 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0027 ÷ 261D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0027 × 0308 ÷ 261D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0027 ÷ 1F3FB ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0027 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0027 ÷ 2640 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0027 × 0308 ÷ 2640 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0027 ÷ 1F466 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0027 × 0308 ÷ 1F466 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0027 × 200D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 261D ÷ 0001 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 261D × 0308 ÷ 0001 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 261D ÷ 000D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 261D × 0308 ÷ 000D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 261D ÷ 000A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 261D × 0308 ÷ 000A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 261D ÷ 000B ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 261D × 0308 ÷ 000B ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 261D ÷ 3031 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 261D × 0308 ÷ 3031 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 261D ÷ 0041 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 261D × 0308 ÷ 0041 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 261D ÷ 003A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 261D × 0308 ÷ 003A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 261D ÷ 002C ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 261D × 0308 ÷ 002C ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 261D ÷ 002E ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 261D × 0308 ÷ 002E ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 261D ÷ 0030 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 261D × 0308 ÷ 0030 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 261D ÷ 005F ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 261D × 0308 ÷ 005F ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 261D ÷ 1F1E6 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 261D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 261D ÷ 05D0 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 261D × 0308 ÷ 05D0 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 261D ÷ 0022 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 261D × 0308 ÷ 0022 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 261D ÷ 0027 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 261D × 0308 ÷ 0027 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 261D ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 261D × 0308 ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 261D × 1F3FB ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 261D × 0308 × 1F3FB ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 261D ÷ 2640 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 261D × 0308 ÷ 2640 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 261D ÷ 1F466 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 261D × 0308 ÷ 1F466 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 261D × 00AD ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 261D × 0308 × 00AD ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 261D × 0300 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 261D × 0308 × 0300 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 261D × 200D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 261D × 0308 × 200D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 261D ÷ 0061 × 2060 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 261D × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 261D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 261D × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 261D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 261D × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 261D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 261D × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 261D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 261D × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 261D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 261D × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 261D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 261D × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 261D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 261D × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 261D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 261D × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F3FB ÷ 0001 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0001 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 1F3FB ÷ 000D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 000D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F3FB ÷ 000A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 000A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F3FB ÷ 000B ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 000B ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 1F3FB ÷ 3031 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 3031 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 1F3FB ÷ 0041 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0041 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F3FB ÷ 003A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 003A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F3FB ÷ 002C ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 002C ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F3FB ÷ 002E ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 002E ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 1F3FB ÷ 0030 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0030 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 1F3FB ÷ 005F ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 005F ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 1F3FB ÷ 1F1E6 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F3FB ÷ 05D0 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 05D0 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 1F3FB ÷ 0022 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0022 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 1F3FB ÷ 0027 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0027 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F3FB ÷ 261D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 261D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F3FB ÷ 1F3FB ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1F3FB ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F3FB ÷ 2640 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 2640 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F3FB ÷ 1F466 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 1F466 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F3FB × 00AD ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 1F3FB × 0308 × 00AD ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 1F3FB × 0300 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 1F3FB × 0308 × 0300 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 1F3FB × 200D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 1F3FB × 0308 × 200D ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 1F3FB ÷ 0061 × 2060 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F3FB ÷ 0061 ÷ 003A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F3FB ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F3FB ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F3FB ÷ 0061 ÷ 002C ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F3FB ÷ 0031 ÷ 003A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F3FB ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F3FB ÷ 0031 ÷ 002C ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F3FB ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F3FB × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2640 ÷ 0001 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0001 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 2640 ÷ 000D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 2640 × 0308 ÷ 000D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 2640 ÷ 000A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 2640 × 0308 ÷ 000A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 2640 ÷ 000B ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 2640 × 0308 ÷ 000B ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 2640 ÷ 3031 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 2640 × 0308 ÷ 3031 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 2640 ÷ 0041 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0041 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 2640 ÷ 003A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 2640 × 0308 ÷ 003A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 2640 ÷ 002C ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 2640 × 0308 ÷ 002C ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 2640 ÷ 002E ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 2640 × 0308 ÷ 002E ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 2640 ÷ 0030 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0030 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 2640 ÷ 005F ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 2640 × 0308 ÷ 005F ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 2640 ÷ 1F1E6 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 2640 ÷ 05D0 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 2640 × 0308 ÷ 05D0 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 2640 ÷ 0022 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0022 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 2640 ÷ 0027 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0027 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 2640 ÷ 261D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 2640 × 0308 ÷ 261D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 2640 ÷ 1F3FB ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 2640 ÷ 2640 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 2640 × 0308 ÷ 2640 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 2640 ÷ 1F466 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 2640 × 0308 ÷ 1F466 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 2640 × 00AD ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 2640 × 0308 × 00AD ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 2640 × 0300 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 2640 × 0308 × 0300 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 2640 × 200D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 2640 × 0308 × 200D ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 2640 ÷ 0061 × 2060 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2640 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 2640 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 2640 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2640 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 2640 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 2640 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 2640 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 2640 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 2640 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FEMALE SIGN (Glue_After_Zwj) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F466 ÷ 0001 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0001 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 1F466 ÷ 000D ÷ # ÷ [0.2] BOY (EBG) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 000D ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 1F466 ÷ 000A ÷ # ÷ [0.2] BOY (EBG) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 000A ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 1F466 ÷ 000B ÷ # ÷ [0.2] BOY (EBG) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 000B ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 1F466 ÷ 3031 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 3031 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 1F466 ÷ 0041 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0041 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F466 ÷ 003A ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 003A ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F466 ÷ 002C ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 002C ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F466 ÷ 002E ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 002E ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 1F466 ÷ 0030 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0030 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 1F466 ÷ 005F ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 005F ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 1F466 ÷ 1F1E6 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 1F466 ÷ 05D0 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 05D0 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 1F466 ÷ 0022 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0022 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 1F466 ÷ 0027 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0027 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F466 ÷ 261D ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 261D ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F466 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F466 × 0308 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 1F466 ÷ 2640 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 2640 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 1F466 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 1F466 × 00AD ÷ # ÷ [0.2] BOY (EBG) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 1F466 × 0308 × 00AD ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 1F466 × 0300 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 1F466 × 0308 × 0300 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 1F466 × 200D ÷ # ÷ [0.2] BOY (EBG) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 1F466 × 0308 × 200D ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 1F466 ÷ 0061 × 2060 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F466 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F466 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F466 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F466 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F466 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F466 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 1F466 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F466 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F466 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] BOY (EBG) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 00AD ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 00AD × 0308 ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 00AD ÷ 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 00AD × 0308 ÷ 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 00AD ÷ 000B ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 00AD × 0308 ÷ 000B ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 00AD ÷ 3031 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 00AD × 0308 ÷ 3031 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 00AD ÷ 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 00AD ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD × 0308 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD × 0308 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 00AD × 0308 ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 00AD ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 00AD ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 00AD × 0308 ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 00AD ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 00AD × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 00AD ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 00AD × 0308 ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 00AD ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 00AD ÷ 261D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 00AD × 0308 ÷ 261D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 00AD ÷ 1F3FB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 00AD × 0308 ÷ 1F3FB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 00AD ÷ 2640 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 00AD × 0308 ÷ 2640 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 00AD ÷ 1F466 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 00AD × 0308 ÷ 1F466 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 00AD × 200D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 00AD × 0308 × 200D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 00AD ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 00AD ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0300 ÷ 000B ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0300 × 0308 ÷ 000B ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0300 ÷ 3031 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0300 × 0308 ÷ 3031 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0300 ÷ 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0300 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 × 0308 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 × 0308 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0300 × 0308 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0300 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0300 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0300 × 0308 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0300 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0300 × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0300 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0300 ÷ 261D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0300 × 0308 ÷ 261D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0300 ÷ 1F3FB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0300 ÷ 2640 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0300 × 0308 ÷ 2640 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0300 ÷ 1F466 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0300 × 0308 ÷ 1F466 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0300 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0300 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 200D ÷ 000B ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 200D × 0308 ÷ 000B ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 200D ÷ 3031 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 200D × 0308 ÷ 3031 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 200D ÷ 0041 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 200D × 0308 ÷ 0041 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 200D ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 200D × 0308 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 200D ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 200D × 0308 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 200D ÷ 002E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 200D × 0308 ÷ 002E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 200D ÷ 0030 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 200D × 0308 ÷ 0030 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 200D ÷ 005F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 200D × 0308 ÷ 005F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 200D ÷ 05D0 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 200D × 0308 ÷ 05D0 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 200D ÷ 0022 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 200D × 0308 ÷ 0022 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 200D ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 200D × 0308 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 200D ÷ 261D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 200D × 0308 ÷ 261D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 200D ÷ 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 0308 ÷ 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 2640 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 200D × 0308 ÷ 2640 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 200D × 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] BOY (EBG) ÷ [0.3]
-÷ 200D × 0308 ÷ 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 200D × 00AD ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 200D × 0308 × 00AD ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 200D ÷ 0061 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 200D × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 200D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 200D × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 200D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 200D × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 200D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 200D × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 200D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 200D × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 200D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 200D × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 200D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 200D × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 200D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 200D × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 200D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 200D × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 × 2060 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 2060 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 × 2060 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 × 2060 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 × 2060 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 × 2060 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 003A × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 × 003A × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 003A × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 003A × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 003A × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 × 003A × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 003A × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 003A × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 × 0027 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 261D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 1F3FB ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 2640 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 1F466 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 ÷ 002C × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 003A × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 × 002C × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 002C × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 002C × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 002C × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 × 002C × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 002C × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 002C × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 × 002C × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 261D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F3FB ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 2640 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F466 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
-÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3]
-÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] ARABIC LETTER NOON (ALetter) ÷ [0.3]
-÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] SPACE (Other) ÷ [0.3]
-÷ 0041 × 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0041 × 003A × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0041 ÷ 003A ÷ 003A ÷ 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
-÷ 05D0 × 0022 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.2] QUOTATION MARK (Double_Quote) × [7.3] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
-÷ 0041 × 0030 × 0030 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0030 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0030 ÷ 002C ÷ 002C ÷ 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 3031 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0041 × 005F × 0030 × 005F × 3031 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0041 × 005F × 005F × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 200D × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
-÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
-÷ 261D × 1F3FB ÷ 261D ÷ # ÷ [0.2] WHITE UP POINTING INDEX (E_Base) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [999.0] WHITE UP POINTING INDEX (E_Base) ÷ [0.3]
-÷ 1F466 × 1F3FB ÷ # ÷ [0.2] BOY (EBG) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 1F466 × 1F3FB ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] BOY (EBG) × [14.0] EMOJI MODIFIER FITZPATRICK TYPE-1-2 (E_Modifier) ÷ [0.3]
-÷ 200D × 2640 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] FEMALE SIGN (Glue_After_Zwj) ÷ [0.3]
-÷ 200D × 1F466 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] BOY (EBG) ÷ [0.3]
-÷ 1F466 ÷ 1F466 ÷ # ÷ [0.2] BOY (EBG) ÷ [999.0] BOY (EBG) ÷ [0.3]
-÷ 0061 × 0308 × 200D × 0308 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-#
-# Lines: 2057
-#
-# EOF
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/qtextboundaryfinder.pro b/tests/auto/corelib/tools/qtextboundaryfinder/qtextboundaryfinder.pro
deleted file mode 100644
index 3c9f03842d..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/qtextboundaryfinder.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtextboundaryfinder
-QT = core testlib
-SOURCES = tst_qtextboundaryfinder.cpp
-
-TESTDATA += data
-
-android:!android-embedded {
- RESOURCES += \
- testdata.qrc
-}
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/testdata.qrc b/tests/auto/corelib/tools/qtextboundaryfinder/testdata.qrc
deleted file mode 100644
index 0cc4ccaa57..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/testdata.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>data/GraphemeBreakTest.txt</file>
- <file>data/LineBreakTest.txt</file>
- <file>data/SentenceBreakTest.txt</file>
- <file>data/WordBreakTest.txt</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
deleted file mode 100644
index 5467d438a3..0000000000
--- a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
+++ /dev/null
@@ -1,848 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-
-#include <qtextboundaryfinder.h>
-#include <qtextcodec.h>
-#include <qfile.h>
-#include <qdebug.h>
-#include <qlist.h>
-
-#include <algorithm>
-
-class tst_QTextBoundaryFinder : public QObject
-{
- Q_OBJECT
-private slots:
-#ifdef QT_BUILD_INTERNAL
- void graphemeBoundariesDefault_data();
- void graphemeBoundariesDefault();
- void wordBoundariesDefault_data();
- void wordBoundariesDefault();
- void sentenceBoundariesDefault_data();
- void sentenceBoundariesDefault();
- void lineBoundariesDefault_data();
- void lineBoundariesDefault();
-#endif
-
- void wordBoundaries_manual_data();
- void wordBoundaries_manual();
- void sentenceBoundaries_manual_data();
- void sentenceBoundaries_manual();
- void lineBoundaries_manual_data();
- void lineBoundaries_manual();
-
- void emptyText_data();
- void emptyText();
- void fastConstructor();
- void assignmentOperator();
- void isAtSoftHyphen_data();
- void isAtSoftHyphen();
- void thaiLineBreak();
-};
-
-
-QT_BEGIN_NAMESPACE
-namespace QTest {
-
-template<>
-inline char *toString(const QTextBoundaryFinder::BoundaryReasons &flags)
-{
- return qstrdup(QByteArray::number(int(flags)).constData());
-}
-
-template<>
-inline char *toString(const QList<int> &list)
-{
- QByteArray s;
- for (QList<int>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) {
- if (!s.isEmpty())
- s += ", ";
- s += QByteArray::number(*it);
- }
- s = "{ " + s + " }";
- return qstrdup(s.constData());
-}
-
-} // namespace QTest
-QT_END_NAMESPACE
-
-#ifdef QT_BUILD_INTERNAL
-static void generateDataFromFile(const QString &fname)
-{
- QTest::addColumn<QString>("testString");
- QTest::addColumn<QList<int> >("expectedBreakPositions");
-
- QString testFile = QFINDTESTDATA(fname);
- QVERIFY2(!testFile.isEmpty(), (fname.toLatin1() + QByteArray(" not found!")));
- QFile f(testFile);
- QVERIFY(f.exists());
-
- f.open(QIODevice::ReadOnly);
-
- int linenum = 0;
- while (!f.atEnd()) {
- linenum++;
-
- QByteArray line = f.readLine();
- if (line.startsWith('#'))
- continue;
-
- QString test = QString::fromUtf8(line);
- QString comments;
- int hash = test.indexOf('#');
- if (hash > 0) {
- comments = test.mid(hash + 1).simplified();
- test = test.left(hash);
- }
-
- QString testString;
- QList<int> expectedBreakPositions;
- foreach (const QString &part, test.simplified().split(QLatin1Char(' '), QString::SkipEmptyParts)) {
- if (part.size() == 1) {
- if (part.at(0).unicode() == 0xf7)
- expectedBreakPositions.append(testString.size());
- else
- QVERIFY(part.at(0).unicode() == 0xd7);
- continue;
- }
- bool ok = true;
- uint ucs4 = part.toInt(&ok, 16);
- QVERIFY(ok && ucs4 > 0);
- if (QChar::requiresSurrogates(ucs4)) {
- testString.append(QChar::highSurrogate(ucs4));
- testString.append(QChar::lowSurrogate(ucs4));
- } else {
- testString.append(QChar(ucs4));
- }
- }
- QVERIFY(!testString.isEmpty());
- QVERIFY(!expectedBreakPositions.isEmpty());
-
- if (!comments.isEmpty()) {
- const QStringList lst = comments.simplified().split(QLatin1Char(' '), QString::SkipEmptyParts);
- comments.clear();
- foreach (const QString &part, lst) {
- if (part.size() == 1) {
- if (part.at(0).unicode() == 0xf7)
- comments += QLatin1Char('+');
- else if (part.at(0).unicode() == 0xd7)
- comments += QLatin1Char('x');
- continue;
- }
- if (part.startsWith(QLatin1Char('(')) && part.endsWith(QLatin1Char(')')))
- comments += part;
- }
- }
-
- const QByteArray nm = "line #" + QByteArray::number(linenum) + ": " + comments.toLatin1();
- QTest::newRow(nm.constData()) << testString << expectedBreakPositions;
- }
-}
-#endif
-
-static void doTestData(const QString &testString, const QList<int> &expectedBreakPositions,
- QTextBoundaryFinder::BoundaryType type,
- QTextBoundaryFinder::BoundaryReasons reasons = QTextBoundaryFinder::BreakOpportunity)
-{
- QVERIFY(!testString.isEmpty());
-
- QTextBoundaryFinder boundaryFinder(type, testString);
-
- // test toNextBoundary()
- {
- QList<int> actualBreakPositions;
- do {
- QVERIFY(boundaryFinder.isAtBoundary());
- if (boundaryFinder.boundaryReasons() & reasons)
- actualBreakPositions.append(boundaryFinder.position());
- } while (boundaryFinder.toNextBoundary() != -1);
- QCOMPARE(actualBreakPositions, expectedBreakPositions);
- }
- QCOMPARE(boundaryFinder.position(), -1);
- QVERIFY(!boundaryFinder.isAtBoundary());
- QVERIFY(boundaryFinder.boundaryReasons() == QTextBoundaryFinder::NotAtBoundary);
-
- // test toPreviousBoundary()
- {
- QList<int> expectedBreakPositionsRev = expectedBreakPositions;
- std::sort(expectedBreakPositionsRev.begin(), expectedBreakPositionsRev.end(), qGreater<int>());
-
- QList<int> actualBreakPositions;
- boundaryFinder.toEnd();
- do {
- QVERIFY(boundaryFinder.isAtBoundary());
- if (boundaryFinder.boundaryReasons() & reasons)
- actualBreakPositions.append(boundaryFinder.position());
- } while (boundaryFinder.toPreviousBoundary() != -1);
- QCOMPARE(actualBreakPositions, expectedBreakPositionsRev);
- }
- QCOMPARE(boundaryFinder.position(), -1);
- QVERIFY(!boundaryFinder.isAtBoundary());
- QVERIFY(boundaryFinder.boundaryReasons() == QTextBoundaryFinder::NotAtBoundary);
-
- // test boundaryReasons()
- for (int i = 0; i <= testString.length(); ++i) {
- boundaryFinder.setPosition(i);
- QCOMPARE(!!(boundaryFinder.boundaryReasons() & reasons), expectedBreakPositions.contains(i));
- }
-}
-
-#ifdef QT_BUILD_INTERNAL
-
-QT_BEGIN_NAMESPACE
-extern Q_AUTOTEST_EXPORT int qt_initcharattributes_default_algorithm_only;
-QT_END_NAMESPACE
-
-void tst_QTextBoundaryFinder::graphemeBoundariesDefault_data()
-{
- generateDataFromFile("data/GraphemeBreakTest.txt");
-}
-
-void tst_QTextBoundaryFinder::graphemeBoundariesDefault()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
-
- QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
- qt_initcharattributes_default_algorithm_only++;
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Grapheme);
-}
-
-void tst_QTextBoundaryFinder::wordBoundariesDefault_data()
-{
- generateDataFromFile("data/WordBreakTest.txt");
-}
-
-void tst_QTextBoundaryFinder::wordBoundariesDefault()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
-
- QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
- qt_initcharattributes_default_algorithm_only++;
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Word);
-}
-
-void tst_QTextBoundaryFinder::sentenceBoundariesDefault_data()
-{
- generateDataFromFile("data/SentenceBreakTest.txt");
-}
-
-void tst_QTextBoundaryFinder::sentenceBoundariesDefault()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
-
- QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
- qt_initcharattributes_default_algorithm_only++;
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Sentence);
-}
-
-void tst_QTextBoundaryFinder::lineBoundariesDefault_data()
-{
- generateDataFromFile("data/LineBreakTest.txt");
-}
-
-void tst_QTextBoundaryFinder::lineBoundariesDefault()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
-
- QScopedValueRollback<int> default_algorithm(qt_initcharattributes_default_algorithm_only);
- qt_initcharattributes_default_algorithm_only++;
-
- expectedBreakPositions.prepend(0); // ### QTBF generates a boundary at start of text
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
-}
-#endif // QT_BUILD_INTERNAL
-
-void tst_QTextBoundaryFinder::wordBoundaries_manual_data()
-{
- QTest::addColumn<QString>("testString");
- QTest::addColumn<QList<int> >("expectedBreakPositions");
- QTest::addColumn<QList<int> >("expectedStartPositions");
- QTest::addColumn<QList<int> >("expectedEndPositions");
-
- {
- QChar s[] = { 0x000D, 0x000A, 0x000A };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 2 << 3;
-
- QTest::newRow("+CRxLF+LF+") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x000D, 0x0308, 0x000A, 0x000A };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 2 << 3 << 4;
-
- QTest::newRow("+CR+FE+LF+LF+") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 3 << 4 << 7 << 8 << 11 << 12 << 14 << 17 << 18 << 21 << 22 << 25 << 26;
- expectedStartPositions << 0 << 4 << 8 << 14 << 18 << 22;
- expectedEndPositions << 3 << 7 << 11 << 17 << 21 << 25;
-
- QTest::newRow("words1") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QString testString(QString::fromUtf8("Hello (sad) world !"));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 5 << 6 << 7 << 10 << 11 << 12 << 17 << 18 << 19;
- expectedStartPositions << 0 << 7 << 12;
- expectedEndPositions << 5 << 10 << 17;
-
- QTest::newRow("words2") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QString testString(QString::fromUtf8("mr.Hamster"));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 2 << 3 << 10;
- expectedStartPositions << 0 << 3;
- expectedEndPositions << 2 << 10;
-
- QTest::newRow("words3") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QString testString(QString::fromUtf8("This is a sample buffer.Please test me . He's don't Le'Clerk."));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 4 << 5 << 7 << 8 << 9 << 10 << 11 << 12 << 13 << 14 << 20 << 21 << 27
- << 28 << 34 << 35 << 39 << 40 << 42 << 43 << 44 << 45 << 46 << 47 << 48
- << 49 << 53 << 54 << 59 << 60 << 68 << 69;
- expectedStartPositions << 0 << 5 << 12 << 14 << 21 << 28 << 35 << 40 << 49 << 54 << 60;
- expectedEndPositions << 4 << 7 << 13 << 20 << 27 << 34 << 39 << 42 << 53 << 59 << 68;
-
- QTest::newRow("words4") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- // text with trailing space
- QString testString(QString::fromUtf8("Please test me. Finish "));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 6 << 7 << 11 << 12 << 14 << 15 << 16 << 22 << 23;
- expectedStartPositions << 0 << 7 << 12 << 16;
- expectedEndPositions << 6 << 11 << 14 << 22;
-
- QTest::newRow("qtbug6498") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
-
- // Sample Strings from WordBreakTest.html
- {
- QChar s[] = { 0x0063, 0x0061, 0x006E, 0x0027, 0x0074 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 5;
- expectedStartPositions << 0;
- expectedEndPositions << 5;
-
- QTest::newRow("ts 1") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x0063, 0x0061, 0x006E, 0x2019, 0x0074 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 5;
- expectedStartPositions << 0;
- expectedEndPositions << 5;
-
- QTest::newRow("ts 2") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x0061, 0x0062, 0x00AD, 0x0062, 0x0061 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 5;
- expectedStartPositions << 0;
- expectedEndPositions << 5;
-
- QTest::newRow("ts 3") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x0061, 0x0024, 0x002D, 0x0033, 0x0034, 0x002C, 0x0035, 0x0036,
- 0x0037, 0x002E, 0x0031, 0x0034, 0x0025, 0x0062 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 2 << 3 << 12 << 13 << 14;
- expectedStartPositions << 0 << 3 << 13;
- expectedEndPositions << 1 << 12 << 14;
-
- QTest::newRow("ts 4") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x0033, 0x0061 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 2;
- expectedStartPositions << 0;
- expectedEndPositions << 2;
-
- QTest::newRow("ts 5") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x2060, 0x0063, 0x2060, 0x0061, 0x2060, 0x006E, 0x2060, 0x0027,
- 0x2060, 0x0074, 0x2060, 0x2060 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 12;
- expectedStartPositions << 1;
- expectedEndPositions << 12;
-
- QTest::newRow("ts 1e") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x2060, 0x0063, 0x2060, 0x0061, 0x2060, 0x006E, 0x2060, 0x2019,
- 0x2060, 0x0074, 0x2060, 0x2060 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 12;
- expectedStartPositions << 1;
- expectedEndPositions << 12;
-
- QTest::newRow("ts 2e") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x2060, 0x0061, 0x2060, 0x0062, 0x2060, 0x00AD, 0x2060, 0x0062,
- 0x2060, 0x0061, 0x2060, 0x2060 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 12;
- expectedStartPositions << 1;
- expectedEndPositions << 12;
-
- QTest::newRow("ts 3e") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x2060, 0x0061, 0x2060, 0x0024, 0x2060, 0x002D, 0x2060, 0x0033,
- 0x2060, 0x0034, 0x2060, 0x002C, 0x2060, 0x0035, 0x2060, 0x0036,
- 0x2060, 0x0037, 0x2060, 0x002E, 0x2060, 0x0031, 0x2060, 0x0034,
- 0x2060, 0x0025, 0x2060, 0x0062, 0x2060, 0x2060 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 3 << 5 << 7 << 25 << 27 << 30;
- expectedStartPositions << 1 << 7 << 27;
- expectedEndPositions << 3 << 25 << 30;
-
- QTest::newRow("ts 4e") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
- {
- QChar s[] = { 0x2060, 0x0033, 0x2060, 0x0061, 0x2060, 0x2060 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedStartPositions, expectedEndPositions;
- expectedBreakPositions << 0 << 1 << 6;
- expectedStartPositions << 1;
- expectedEndPositions << 6;
-
- QTest::newRow("ts 5e") << testString << expectedBreakPositions
- << expectedStartPositions << expectedEndPositions;
- }
-}
-
-void tst_QTextBoundaryFinder::wordBoundaries_manual()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
- QFETCH(QList<int>, expectedStartPositions);
- QFETCH(QList<int>, expectedEndPositions);
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Word);
- doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Word, QTextBoundaryFinder::StartOfItem);
- doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Word, QTextBoundaryFinder::EndOfItem);
-}
-
-void tst_QTextBoundaryFinder::sentenceBoundaries_manual_data()
-{
- QTest::addColumn<QString>("testString");
- QTest::addColumn<QList<int> >("expectedBreakPositions");
-
- {
- QChar s[] = { 0x000D, 0x000A, 0x000A };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions;
- expectedBreakPositions << 0 << 2 << 3;
-
- QTest::newRow("+CRxLF+LF+") << testString << expectedBreakPositions;
- }
- {
- QChar s[] = { 0x000D, 0x0308, 0x000A, 0x000A };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions;
- expectedBreakPositions << 0 << 1 << 3 << 4;
-
- QTest::newRow("+CR+FExLF+LF+") << testString << expectedBreakPositions;
- }
- {
- QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
- QList<int> expectedBreakPositions;
- expectedBreakPositions << 0 << 14 << 26;
-
- QTest::newRow("data1") << testString << expectedBreakPositions;
- }
- {
- QString testString(QString::fromUtf8("Diga-nos qualé a sua opinião"));
- QList<int> expectedBreakPositions;
- expectedBreakPositions << 0 << 28;
-
- QTest::newRow("data2") << testString << expectedBreakPositions;
- }
- {
- QString testString(QString::fromUtf8("mr.Hamster"));
- QList<int> expectedBreakPositions;
- expectedBreakPositions << 0 << 3 << 10;
-
- QTest::newRow("data3") << testString << expectedBreakPositions;
- }
-}
-
-void tst_QTextBoundaryFinder::sentenceBoundaries_manual()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
-
- QVERIFY(expectedBreakPositions.size() >= 2);
- QList<int> expectedStartPositions = expectedBreakPositions; expectedStartPositions.removeLast();
- QList<int> expectedEndPositions = expectedBreakPositions; expectedEndPositions.removeFirst();
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Sentence);
- doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Sentence, QTextBoundaryFinder::StartOfItem);
- doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Sentence, QTextBoundaryFinder::EndOfItem);
-}
-
-void tst_QTextBoundaryFinder::lineBoundaries_manual_data()
-{
- QTest::addColumn<QString>("testString");
- QTest::addColumn<QList<int> >("expectedBreakPositions");
- QTest::addColumn<QList<int> >("expectedMandatoryBreakPositions");
-
- {
- QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
- QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
- expectedBreakPositions << 0 << 4 << 8 << 14 << 18 << 22 << 26;
- expectedMandatoryBreakPositions << 0 << 14 << 26;
-
- QTest::newRow("data1") << testString << expectedBreakPositions
- << expectedMandatoryBreakPositions;
- }
- {
- QString testString(QString::fromUtf8("Diga-nos qualé a sua opinião"));
- QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
- expectedBreakPositions << 0 << 5 << 9 << 15 << 17 << 21 << 28;
- expectedMandatoryBreakPositions << 0 << 28;
-
- QTest::newRow("data2") << testString << expectedBreakPositions
- << expectedMandatoryBreakPositions;
- }
-
- {
- QChar s[] = { 0x000D, 0x0308, 0x000A, 0x000A, 0x0020 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
- expectedBreakPositions << 0 << 1 << 3 << 4 << 5;
- expectedMandatoryBreakPositions << 0 << 1 << 3 << 4 << 5;
-
- QTest::newRow("x(CR)+(FE)x(LF)+(LF)+(SP)+") << testString << expectedBreakPositions
- << expectedMandatoryBreakPositions;
- }
- {
- QChar s[] = { 0x000A, 0x2E80, 0x0308, 0x0023, 0x0023 };
- QString testString(s, sizeof(s)/sizeof(QChar));
- QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
- expectedBreakPositions << 0 << 1 << 3 << 5;
- expectedMandatoryBreakPositions << 0 << 1 << 5;
-
- QTest::newRow("x(LF)+(ID)x(CM)+(AL)x(AL)+") << testString << expectedBreakPositions
- << expectedMandatoryBreakPositions;
- }
- {
- QChar s[] = { 0x000A, 0x0308, 0x0023, 0x0023 };
- QString testString(s, sizeof(s)/sizeof(QChar));
- QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
- expectedBreakPositions << 0 << 1 << 4;
- expectedMandatoryBreakPositions << 0 << 1 << 4;
-
- QTest::newRow("x(LF)+(CM)x(AL)x(AL)+") << testString << expectedBreakPositions
- << expectedMandatoryBreakPositions;
- }
-
- {
- QChar s[] = { 0x0061, 0x00AD, 0x0062, 0x0009, 0x0063, 0x0064 };
- QString testString(s, sizeof(s)/sizeof(s[0]));
- QList<int> expectedBreakPositions, expectedMandatoryBreakPositions;
- expectedBreakPositions << 0 << 2 << 4 << 6;
- expectedMandatoryBreakPositions << 0 << 6;
-
- QTest::newRow("x(AL)x(BA)+(AL)x(BA)+(AL)x(AL)+") << testString << expectedBreakPositions
- << expectedMandatoryBreakPositions;
- }
-}
-
-void tst_QTextBoundaryFinder::lineBoundaries_manual()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
- QFETCH(QList<int>, expectedMandatoryBreakPositions);
-
- QVERIFY(expectedMandatoryBreakPositions.size() >= 2);
- QList<int> expectedStartPositions = expectedMandatoryBreakPositions; expectedStartPositions.removeLast();
- QList<int> expectedEndPositions = expectedMandatoryBreakPositions; expectedEndPositions.removeFirst();
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
- doTestData(testString, expectedMandatoryBreakPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::MandatoryBreak);
- doTestData(testString, expectedStartPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::StartOfItem);
- doTestData(testString, expectedEndPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::EndOfItem);
-}
-
-Q_DECLARE_METATYPE(QTextBoundaryFinder)
-
-void tst_QTextBoundaryFinder::emptyText_data()
-{
- QTest::addColumn<QTextBoundaryFinder>("boundaryFinder");
-
- QString empty;
- QString notEmpty(QLatin1String("not empty"));
- uchar attrs[11];
-
- QTextBoundaryFinder invalidFinder(QTextBoundaryFinder::Word, empty);
- QTest::newRow("empty1") << invalidFinder;
- QTextBoundaryFinder finder(invalidFinder);
- QTest::newRow("empty2") << finder;
- finder = QTextBoundaryFinder(QTextBoundaryFinder::Grapheme, notEmpty);
- finder = invalidFinder;
- QTest::newRow("empty3") << finder;
- QTest::newRow("empty4") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, 0, 0);
- QTest::newRow("empty5") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, attrs, 11);
- QTest::newRow("invalid1") << QTextBoundaryFinder(QTextBoundaryFinder::Word, 0, 10, 0, 0);
- QTest::newRow("invalid2") << QTextBoundaryFinder(QTextBoundaryFinder::Word, 0, 10, attrs, 11);
-}
-
-void tst_QTextBoundaryFinder::emptyText()
-{
- QFETCH(QTextBoundaryFinder, boundaryFinder);
-
- QCOMPARE(boundaryFinder.position(), 0);
- QCOMPARE(boundaryFinder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
-
- boundaryFinder.toNextBoundary();
- QCOMPARE(boundaryFinder.position(), -1);
- QCOMPARE(boundaryFinder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
-}
-
-void tst_QTextBoundaryFinder::fastConstructor()
-{
- QString text("Hello World");
- QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text.constData(), text.length(), /*buffer*/0, /*buffer size*/0);
-
- QCOMPARE(finder.position(), 0);
- QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem);
-
- finder.toNextBoundary();
- QCOMPARE(finder.position(), 5);
- QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem);
-
- finder.toNextBoundary();
- QCOMPARE(finder.position(), 6);
- QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem);
-
- finder.toNextBoundary();
- QCOMPARE(finder.position(), text.length());
- QVERIFY(finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem);
-
- finder.toNextBoundary();
- QCOMPARE(finder.position(), -1);
- QCOMPARE(finder.boundaryReasons(), QTextBoundaryFinder::NotAtBoundary);
-}
-
-void tst_QTextBoundaryFinder::assignmentOperator()
-{
- QString text(QLatin1String("Hello World"));
-
- QTextBoundaryFinder invalidFinder;
- QVERIFY(!invalidFinder.isValid());
- QCOMPARE(invalidFinder.string(), QString());
-
- QTextBoundaryFinder validFinder(QTextBoundaryFinder::Word, text);
- QVERIFY(validFinder.isValid());
- QCOMPARE(validFinder.string(), text);
-
- QTextBoundaryFinder finder(QTextBoundaryFinder::Line, QLatin1String("dummy"));
- QVERIFY(finder.isValid());
-
- finder = invalidFinder;
- QVERIFY(!finder.isValid());
- QCOMPARE(finder.string(), QString());
-
- finder = validFinder;
- QVERIFY(finder.isValid());
- QCOMPARE(finder.string(), text);
-}
-
-void tst_QTextBoundaryFinder::isAtSoftHyphen_data()
-{
- QTest::addColumn<QString>("testString");
- QTest::addColumn<QList<int> >("expectedBreakPositions");
- QTest::addColumn<QList<int> >("expectedSoftHyphenPositions");
-
- {
- QString testString = QString::fromUtf8("I a-m break-able");
- testString.replace(QLatin1Char('-'), QChar(QChar::SoftHyphen));
- QList<int> expectedBreakPositions, expectedSoftHyphenPositions;
- expectedBreakPositions << 0 << 2 << 4 << 6 << 12 << 16;
- expectedSoftHyphenPositions << 4 << 12;
-
- QTest::newRow("Soft Hyphen") << testString << expectedBreakPositions
- << expectedSoftHyphenPositions;
- }
-}
-
-void tst_QTextBoundaryFinder::isAtSoftHyphen()
-{
- QFETCH(QString, testString);
- QFETCH(QList<int>, expectedBreakPositions);
- QFETCH(QList<int>, expectedSoftHyphenPositions);
-
- doTestData(testString, expectedBreakPositions, QTextBoundaryFinder::Line);
- doTestData(testString, expectedSoftHyphenPositions, QTextBoundaryFinder::Line, QTextBoundaryFinder::SoftHyphen);
-}
-
-#if QT_CONFIG(library)
-#include <qlibrary.h>
-#endif
-
-#define LIBTHAI_MAJOR 0
-typedef int (*th_brk_def) (const unsigned char*, int*, size_t);
-static th_brk_def th_brk = 0;
-
-static bool init_libthai()
-{
-#if QT_CONFIG(library)
- static bool triedResolve = false;
- if (!triedResolve) {
- th_brk = (th_brk_def) QLibrary::resolve("thai", (int)LIBTHAI_MAJOR, "th_brk");
- triedResolve = true;
- }
-#endif
- return th_brk != 0;
-}
-
-void tst_QTextBoundaryFinder::thaiLineBreak()
-{
- if (!init_libthai())
- QSKIP("This test requires libThai-0.1.1x to be installed.");
-#if 0
- // สวัสดีครับ นี่เป็นการงทดสอบตัวเอ
- QTextCodec *codec = QTextCodec::codecForMib(2259);
- QString text = codec->toUnicode(QByteArray("\xca\xc7\xd1\xca\xb4\xd5\xa4\xc3\xd1\xba\x20\xb9\xd5\xe8\xe0\xbb\xe7\xb9\xa1\xd2\xc3\xb7\xb4\xca\xcd\xba\xb5\xd1\xc7\xe0\xcd\xa7"));
- QCOMPARE(text.length(), 32);
-
- QTextBoundaryFinder finder(QTextBoundaryFinder::Line, text);
- finder.setPosition(0);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(1);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(2);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(3);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(4);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(5);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(6);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(7);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(8);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(9);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(10);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(11);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(12);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(13);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(14);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(15);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(16);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(17);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(18);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(19);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(20);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(21);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(22);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(23);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(24);
- QVERIFY(!finder.isAtBoundary());
- finder.setPosition(25);
- QVERIFY(finder.isAtBoundary());
- finder.setPosition(26);
- QVERIFY(finder.isAtBoundary());
- for (int i = 27; i < 32; ++i) {
- finder.setPosition(i);
- QVERIFY(!finder.isAtBoundary());
- }
-#endif
-}
-
-
-QTEST_MAIN(tst_QTextBoundaryFinder)
-#include "tst_qtextboundaryfinder.moc"
diff --git a/tests/auto/corelib/tools/qtime/qtime.pro b/tests/auto/corelib/tools/qtime/qtime.pro
deleted file mode 100644
index 0973b7a9ef..0000000000
--- a/tests/auto/corelib/tools/qtime/qtime.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtime
-QT = core testlib
-SOURCES = tst_qtime.cpp
diff --git a/tests/auto/corelib/tools/qtime/tst_qtime.cpp b/tests/auto/corelib/tools/qtime/tst_qtime.cpp
deleted file mode 100644
index 3e5724213e..0000000000
--- a/tests/auto/corelib/tools/qtime/tst_qtime.cpp
+++ /dev/null
@@ -1,802 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "qdatetime.h"
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-# include <locale.h>
-#endif
-
-class tst_QTime : public QObject
-{
- Q_OBJECT
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-public:
- tst_QTime()
- {
- // Some tests depend on C locale - BF&I it with belt *and* braces:
- qputenv("LC_ALL", "C");
- setlocale(LC_ALL, "C");
- // Need to instantiate as early as possible, before anything accesses
- // the QSystemLocale singleton; once it exists, there's no changing it.
- }
-#endif // remove for ### Qt 6
-
-private slots:
- void msecsTo_data();
- void msecsTo();
- void secsTo_data();
- void secsTo();
- void setHMS_data();
- void setHMS();
- void hour_data();
- void hour();
- void isValid();
- void isNull();
- void addMSecs_data();
- void addMSecs();
- void addSecs_data();
- void addSecs();
- void operator_eq_eq_data();
- void operator_eq_eq();
- void operator_lt();
- void operator_gt();
- void operator_lt_eq();
- void operator_gt_eq();
- void fromStringFormat_data();
- void fromStringFormat();
- void fromStringDateFormat_data();
- void fromStringDateFormat();
- void toStringDateFormat_data();
- void toStringDateFormat();
- void toStringFormat_data();
- void toStringFormat();
- void toStringLocale();
- void msecsSinceStartOfDay_data();
- void msecsSinceStartOfDay();
-
-private:
- QTime invalidTime() { return QTime(-1, -1, -1); }
-};
-
-Q_DECLARE_METATYPE(Qt::DateFormat)
-
-void tst_QTime::addSecs_data()
-{
- QTest::addColumn<QTime>("t1");
- QTest::addColumn<int>("i");
- QTest::addColumn<QTime>("exp");
-
- QTest::newRow("Data0") << QTime(0,0,0) << 200 << QTime(0,3,20);
- QTest::newRow("Data1") << QTime(0,0,0) << 20 << QTime(0,0,20);
- QTest::newRow("overflow") << QTime(0,0,0) << (INT_MAX / 1000 + 1)
- << QTime(0,0,0).addSecs((INT_MAX / 1000 + 1) % 86400);
-}
-
-void tst_QTime::addSecs()
-{
- QFETCH( QTime, t1 );
- QFETCH( int, i );
- QTime t2;
- t2 = t1.addSecs( i );
- QFETCH( QTime, exp );
- QCOMPARE( t2, exp );
-}
-
-void tst_QTime::addMSecs_data()
-{
- QTest::addColumn<QTime>("t1");
- QTest::addColumn<int>("i");
- QTest::addColumn<QTime>("exp");
-
- // start with testing positive values
- QTest::newRow( "Data1_0") << QTime(0,0,0,0) << 2000 << QTime(0,0,2,0);
- QTest::newRow( "Data1_1") << QTime(0,0,0,0) << 200 << QTime(0,0,0,200);
- QTest::newRow( "Data1_2") << QTime(0,0,0,0) << 20 << QTime(0,0,0,20);
- QTest::newRow( "Data1_3") << QTime(0,0,0,1) << 1 << QTime(0,0,0,2);
- QTest::newRow( "Data1_4") << QTime(0,0,0,0) << 0 << QTime(0,0,0,0);
-
- QTest::newRow( "Data2_0") << QTime(0,0,0,98) << 0 << QTime(0,0,0,98);
- QTest::newRow( "Data2_1") << QTime(0,0,0,98) << 1 << QTime(0,0,0,99);
- QTest::newRow( "Data2_2") << QTime(0,0,0,98) << 2 << QTime(0,0,0,100);
- QTest::newRow( "Data2_3") << QTime(0,0,0,98) << 3 << QTime(0,0,0,101);
-
- QTest::newRow( "Data3_0") << QTime(0,0,0,998) << 0 << QTime(0,0,0,998);
- QTest::newRow( "Data3_1") << QTime(0,0,0,998) << 1 << QTime(0,0,0,999);
- QTest::newRow( "Data3_2") << QTime(0,0,0,998) << 2 << QTime(0,0,1,0);
- QTest::newRow( "Data3_3") << QTime(0,0,0,998) << 3 << QTime(0,0,1,1);
-
- QTest::newRow( "Data4_0") << QTime(0,0,1,995) << 4 << QTime(0,0,1,999);
- QTest::newRow( "Data4_1") << QTime(0,0,1,995) << 5 << QTime(0,0,2,0);
- QTest::newRow( "Data4_2") << QTime(0,0,1,995) << 6 << QTime(0,0,2,1);
- QTest::newRow( "Data4_3") << QTime(0,0,1,995) << 100 << QTime(0,0,2,95);
- QTest::newRow( "Data4_4") << QTime(0,0,1,995) << 105 << QTime(0,0,2,100);
-
- QTest::newRow( "Data5_0") << QTime(0,0,59,995) << 4 << QTime(0,0,59,999);
- QTest::newRow( "Data5_1") << QTime(0,0,59,995) << 5 << QTime(0,1,0,0);
- QTest::newRow( "Data5_2") << QTime(0,0,59,995) << 6 << QTime(0,1,0,1);
- QTest::newRow( "Data5_3") << QTime(0,0,59,995) << 1006 << QTime(0,1,1,1);
-
- QTest::newRow( "Data6_0") << QTime(0,59,59,995) << 4 << QTime(0,59,59,999);
- QTest::newRow( "Data6_1") << QTime(0,59,59,995) << 5 << QTime(1,0,0,0);
- QTest::newRow( "Data6_2") << QTime(0,59,59,995) << 6 << QTime(1,0,0,1);
- QTest::newRow( "Data6_3") << QTime(0,59,59,995) << 106 << QTime(1,0,0,101);
- QTest::newRow( "Data6_4") << QTime(0,59,59,995) << 1004 << QTime(1,0,0,999);
- QTest::newRow( "Data6_5") << QTime(0,59,59,995) << 1005 << QTime(1,0,1,0);
- QTest::newRow( "Data6_6") << QTime(0,59,59,995) << 61006 << QTime(1,1,1,1);
-
- QTest::newRow( "Data7_0") << QTime(23,59,59,995) << 0 << QTime(23,59,59,995);
- QTest::newRow( "Data7_1") << QTime(23,59,59,995) << 4 << QTime(23,59,59,999);
- QTest::newRow( "Data7_2") << QTime(23,59,59,995) << 5 << QTime(0,0,0,0);
- QTest::newRow( "Data7_3") << QTime(23,59,59,995) << 6 << QTime(0,0,0,1);
- QTest::newRow( "Data7_4") << QTime(23,59,59,995) << 7 << QTime(0,0,0,2);
-
- // must test negative values too...
- QTest::newRow( "Data11_0") << QTime(0,0,2,0) << -2000 << QTime(0,0,0,0);
- QTest::newRow( "Data11_1") << QTime(0,0,0,200) << -200 << QTime(0,0,0,0);
- QTest::newRow( "Data11_2") << QTime(0,0,0,20) << -20 << QTime(0,0,0,0);
- QTest::newRow( "Data11_3") << QTime(0,0,0,2) << -1 << QTime(0,0,0,1);
- QTest::newRow( "Data11_4") << QTime(0,0,0,0) << -0 << QTime(0,0,0,0);
-
- QTest::newRow( "Data12_0") << QTime(0,0,0,98) << -0 << QTime(0,0,0,98);
- QTest::newRow( "Data12_1") << QTime(0,0,0,99) << -1 << QTime(0,0,0,98);
- QTest::newRow( "Data12_2") << QTime(0,0,0,100) << -2 << QTime(0,0,0,98);
- QTest::newRow( "Data12_3") << QTime(0,0,0,101) << -3 << QTime(0,0,0,98);
-
- QTest::newRow( "Data13_0") << QTime(0,0,0,998) << -0 << QTime(0,0,0,998);
- QTest::newRow( "Data13_1") << QTime(0,0,0,999) << -1 << QTime(0,0,0,998);
- QTest::newRow( "Data13_2") << QTime(0,0,1,0) << -2 << QTime(0,0,0,998);
- QTest::newRow( "Data13_3") << QTime(0,0,1,1) << -3 << QTime(0,0,0,998);
-
- QTest::newRow( "Data14_0") << QTime(0,0,1,999) << -4 << QTime(0,0,1,995);
- QTest::newRow( "Data14_1") << QTime(0,0,2,0) << -5 << QTime(0,0,1,995);
- QTest::newRow( "Data14_2") << QTime(0,0,2,1) << -6 << QTime(0,0,1,995);
- QTest::newRow( "Data14_3") << QTime(0,0,2,95) << -100 << QTime(0,0,1,995);
- QTest::newRow( "Data14_4") << QTime(0,0,2,100) << -105 << QTime(0,0,1,995);
-
- QTest::newRow( "Data15_0") << QTime(0,0,59,999) << -4 << QTime(0,0,59,995);
- QTest::newRow( "Data15_1") << QTime(0,1,0,0) << -5 << QTime(0,0,59,995);
- QTest::newRow( "Data15_2") << QTime(0,1,0,1) << -6 << QTime(0,0,59,995);
- QTest::newRow( "Data15_3") << QTime(0,1,1,1) << -1006 << QTime(0,0,59,995);
-
- QTest::newRow( "Data16_0") << QTime(0,59,59,999) << -4 << QTime(0,59,59,995);
- QTest::newRow( "Data16_1") << QTime(1,0,0,0) << -5 << QTime(0,59,59,995);
- QTest::newRow( "Data16_2") << QTime(1,0,0,1) << -6 << QTime(0,59,59,995);
- QTest::newRow( "Data16_3") << QTime(1,0,0,101) << -106 << QTime(0,59,59,995);
- QTest::newRow( "Data16_4") << QTime(1,0,0,999) << -1004 << QTime(0,59,59,995);
- QTest::newRow( "Data16_5") << QTime(1,0,1,0) << -1005 << QTime(0,59,59,995);
- QTest::newRow( "Data16_6") << QTime(1,1,1,1) << -61006 << QTime(0,59,59,995);
-
- QTest::newRow( "Data17_0") << QTime(23,59,59,995) << -0 << QTime(23,59,59,995);
- QTest::newRow( "Data17_1") << QTime(23,59,59,999) << -4 << QTime(23,59,59,995);
- QTest::newRow( "Data17_2") << QTime(0,0,0,0) << -5 << QTime(23,59,59,995);
- QTest::newRow( "Data17_3") << QTime(0,0,0,1) << -6 << QTime(23,59,59,995);
- QTest::newRow( "Data17_4") << QTime(0,0,0,2) << -7 << QTime(23,59,59,995);
-
- QTest::newRow( "Data18_0" ) << invalidTime() << 1 << invalidTime();
-}
-
-void tst_QTime::addMSecs()
-{
- QFETCH( QTime, t1 );
- QFETCH( int, i );
- QTime t2;
- t2 = t1.addMSecs( i );
- QFETCH( QTime, exp );
- QCOMPARE( t2, exp );
-}
-
-void tst_QTime::isNull()
-{
- QTime t1;
- QVERIFY( t1.isNull() );
- QTime t2(0,0,0);
- QVERIFY( !t2.isNull() );
- QTime t3(0,0,1);
- QVERIFY( !t3.isNull() );
- QTime t4(0,0,0,1);
- QVERIFY( !t4.isNull() );
- QTime t5(23,59,59);
- QVERIFY( !t5.isNull() );
-}
-
-void tst_QTime::isValid()
-{
- QTime t1;
- QVERIFY( !t1.isValid() );
- QTime t2(24,0,0,0);
- QVERIFY( !t2.isValid() );
- QTime t3(23,60,0,0);
- QVERIFY( !t3.isValid() );
- QTime t4(23,0,-1,0);
- QVERIFY( !t4.isValid() );
- QTime t5(23,0,60,0);
- QVERIFY( !t5.isValid() );
- QTime t6(23,0,0,1000);
- QVERIFY( !t6.isValid() );
-}
-
-void tst_QTime::hour_data()
-{
- QTest::addColumn<int>("hour");
- QTest::addColumn<int>("minute");
- QTest::addColumn<int>("sec");
- QTest::addColumn<int>("msec");
-
- QTest::newRow( "data0" ) << 0 << 0 << 0 << 0;
- QTest::newRow( "data1" ) << 0 << 0 << 0 << 1;
- QTest::newRow( "data2" ) << 1 << 2 << 3 << 4;
- QTest::newRow( "data3" ) << 2 << 12 << 13 << 65;
- QTest::newRow( "data4" ) << 23 << 59 << 59 << 999;
- QTest::newRow( "data5" ) << -1 << -1 << -1 << -1;
-}
-
-void tst_QTime::hour()
-{
- QFETCH( int, hour );
- QFETCH( int, minute );
- QFETCH( int, sec );
- QFETCH( int, msec );
-
- QTime t1( hour, minute, sec, msec );
- QCOMPARE( t1.hour(), hour );
- QCOMPARE( t1.minute(), minute );
- QCOMPARE( t1.second(), sec );
- QCOMPARE( t1.msec(), msec );
-}
-
-void tst_QTime::setHMS_data()
-{
- QTest::addColumn<int>("hour");
- QTest::addColumn<int>("minute");
- QTest::addColumn<int>("sec");
-
- QTest::newRow( "data0" ) << 0 << 0 << 0;
- QTest::newRow( "data1" ) << 1 << 2 << 3;
- QTest::newRow( "data2" ) << 0 << 59 << 0;
- QTest::newRow( "data3" ) << 0 << 59 << 59;
- QTest::newRow( "data4" ) << 23 << 0 << 0;
- QTest::newRow( "data5" ) << 23 << 59 << 0;
- QTest::newRow( "data6" ) << 23 << 59 << 59;
- QTest::newRow( "data7" ) << -1 << -1 << -1;
-}
-
-void tst_QTime::setHMS()
-{
- QFETCH( int, hour );
- QFETCH( int, minute );
- QFETCH( int, sec );
-
- QTime t(3,4,5);
- t.setHMS( hour, minute, sec );
- QCOMPARE( t.hour(), hour );
- QCOMPARE( t.minute(), minute );
- QCOMPARE( t.second(), sec );
-}
-
-void tst_QTime::secsTo_data()
-{
- QTest::addColumn<QTime>("t1");
- QTest::addColumn<QTime>("t2");
- QTest::addColumn<int>("delta");
-
- QTest::newRow( "data0" ) << QTime(0,0,0) << QTime(0,0,59) << 59;
- QTest::newRow( "data1" ) << QTime(0,0,0) << QTime(0,1,0) << 60;
- QTest::newRow( "data2" ) << QTime(0,0,0) << QTime(0,10,0) << 600;
- QTest::newRow( "data3" ) << QTime(0,0,0) << QTime(23,59,59) << 86399;
- QTest::newRow( "data4" ) << QTime(-1, -1, -1) << QTime(0, 0, 0) << 0;
- QTest::newRow( "data5" ) << QTime(0, 0, 0) << QTime(-1, -1, -1) << 0;
- QTest::newRow( "data6" ) << QTime(-1, -1, -1) << QTime(-1, -1, -1) << 0;
- QTest::newRow("disregard msec (1s)") << QTime(12, 30, 1, 500) << QTime(12, 30, 2, 400) << 1;
- QTest::newRow("disregard msec (0s)") << QTime(12, 30, 1, 500) << QTime(12, 30, 1, 900) << 0;
- QTest::newRow("disregard msec (-1s)") << QTime(12, 30, 2, 400) << QTime(12, 30, 1, 500) << -1;
- QTest::newRow("disregard msec (0s)") << QTime(12, 30, 1, 900) << QTime(12, 30, 1, 500) << 0;
-}
-
-void tst_QTime::secsTo()
-{
- QFETCH( QTime, t1 );
- QFETCH( QTime, t2 );
- QFETCH( int, delta );
-
- QCOMPARE( t1.secsTo( t2 ), delta );
-}
-
-void tst_QTime::msecsTo_data()
-{
- QTest::addColumn<QTime>("t1");
- QTest::addColumn<QTime>("t2");
- QTest::addColumn<int>("delta");
-
- QTest::newRow( "data0" ) << QTime(0,0,0,0) << QTime(0,0,0,0) << 0;
- QTest::newRow( "data1" ) << QTime(0,0,0,0) << QTime(0,0,1,0) << 1000;
- QTest::newRow( "data2" ) << QTime(0,0,0,0) << QTime(0,0,10,0) << 10000;
- QTest::newRow( "data3" ) << QTime(0,0,0,0) << QTime(23,59,59,0) << 86399000;
- QTest::newRow( "data4" ) << QTime(-1, -1, -1, -1) << QTime(0, 0, 0, 0) << 0;
- QTest::newRow( "data5" ) << QTime(0, 0, 0, 0) << QTime(-1, -1, -1, -1) << 0;
- QTest::newRow( "data6" ) << QTime(-1, -1, -1, -1) << QTime(-1, -1, -1, -1) << 0;
-}
-
-void tst_QTime::msecsTo()
-{
- QFETCH( QTime, t1 );
- QFETCH( QTime, t2 );
- QFETCH( int, delta );
-
- QCOMPARE( t1.msecsTo( t2 ), delta );
-}
-
-void tst_QTime::operator_eq_eq_data()
-{
- QTest::addColumn<QTime>("t1");
- QTest::addColumn<QTime>("t2");
- QTest::addColumn<bool>("expectEqual");
-
- QTime time1(0, 0, 0, 0);
- QTime time2 = time1.addMSecs(1);
- QTime time3 = time1.addMSecs(-1);
- QTime time4(23, 59, 59, 999);
-
- QTest::newRow("data0") << time1 << time2 << false;
- QTest::newRow("data1") << time2 << time3 << false;
- QTest::newRow("data2") << time4 << time1 << false;
- QTest::newRow("data3") << time1 << time1 << true;
- QTest::newRow("data4") << QTime(12,34,56,20) << QTime(12,34,56,20) << true;
- QTest::newRow("data5") << QTime(01,34,56,20) << QTime(13,34,56,20) << false;
-}
-
-void tst_QTime::operator_eq_eq()
-{
- QFETCH(QTime, t1);
- QFETCH(QTime, t2);
- QFETCH(bool, expectEqual);
-
- bool equal = t1 == t2;
- QCOMPARE(equal, expectEqual);
- bool notEqual = t1 != t2;
- QCOMPARE(notEqual, !expectEqual);
-
- if (equal)
- QVERIFY(qHash(t1) == qHash(t2));
-}
-
-void tst_QTime::operator_lt()
-{
- QTime t1(0,0,0,0);
- QTime t2(0,0,0,0);
- QVERIFY( !(t1 < t2) );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(12,34,56,30);
- QVERIFY( t1 < t2 );
-
- t1 = QTime(13,34,46,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 < t2 );
-
- t1 = QTime(13,24,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 < t2 );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 < t2 );
-
- t1 = QTime(14,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 < t2) );
-
- t1 = QTime(13,44,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 < t2) );
-
- t1 = QTime(13,34,56,20);
- t2 = QTime(13,34,46,20);
- QVERIFY( !(t1 < t2) );
-
- t1 = QTime(13,44,56,30);
- t2 = QTime(13,44,56,20);
- QVERIFY( !(t1 < t2) );
-}
-
-void tst_QTime::operator_gt()
-{
- QTime t1(0,0,0,0);
- QTime t2(0,0,0,0);
- QVERIFY( !(t1 > t2) );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(12,34,56,30);
- QVERIFY( !(t1 > t2) );
-
- t1 = QTime(13,34,46,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 > t2) );
-
- t1 = QTime(13,24,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 > t2) );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 > t2) );
-
- t1 = QTime(14,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 > t2 );
-
- t1 = QTime(13,44,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 > t2 );
-
- t1 = QTime(13,34,56,20);
- t2 = QTime(13,34,46,20);
- QVERIFY( t1 > t2 );
-
- t1 = QTime(13,44,56,30);
- t2 = QTime(13,44,56,20);
- QVERIFY( t1 > t2 );
-}
-
-void tst_QTime::operator_lt_eq()
-{
- QTime t1(0,0,0,0);
- QTime t2(0,0,0,0);
- QVERIFY( t1 <= t2 );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(12,34,56,30);
- QVERIFY( t1 <= t2 );
-
- t1 = QTime(13,34,46,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 <= t2 );
-
- t1 = QTime(13,24,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 <= t2 );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 <= t2 );
-
- t1 = QTime(14,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 <= t2) );
-
- t1 = QTime(13,44,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 <= t2) );
-
- t1 = QTime(13,34,56,20);
- t2 = QTime(13,34,46,20);
- QVERIFY( !(t1 <= t2) );
-
- t1 = QTime(13,44,56,30);
- t2 = QTime(13,44,56,20);
- QVERIFY( !(t1 <= t2) );
-}
-
-void tst_QTime::operator_gt_eq()
-{
- QTime t1(0,0,0,0);
- QTime t2(0,0,0,0);
- QVERIFY( t1 >= t2 );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(12,34,56,30);
- QVERIFY( !(t1 >= t2) );
-
- t1 = QTime(13,34,46,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 >= t2) );
-
- t1 = QTime(13,24,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 >= t2) );
-
- t1 = QTime(12,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( !(t1 >= t2) );
-
- t1 = QTime(14,34,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 >= t2 );
-
- t1 = QTime(13,44,56,20);
- t2 = QTime(13,34,56,20);
- QVERIFY( t1 >= t2 );
-
- t1 = QTime(13,34,56,20);
- t2 = QTime(13,34,46,20);
- QVERIFY( t1 >= t2 );
-
- t1 = QTime(13,44,56,30);
- t2 = QTime(13,44,56,20);
- QVERIFY( t1 >= t2 );
-}
-
-void tst_QTime::fromStringFormat_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QTime>("expected");
-
- QTest::newRow("data0") << QString("1010") << QString("mmm") << QTime(0, 10, 0);
- QTest::newRow("data1") << QString("00") << QString("hm") << invalidTime();
- QTest::newRow("data2") << QString("10am") << QString("hap") << QTime(10, 0, 0);
- QTest::newRow("data3") << QString("10pm") << QString("hap") << QTime(22, 0, 0);
- QTest::newRow("data4") << QString("10pmam") << QString("hapap") << invalidTime();
- QTest::newRow("data5") << QString("1070") << QString("hhm") << invalidTime();
- QTest::newRow("data6") << QString("1011") << QString("hh") << invalidTime();
- QTest::newRow("data7") << QString("25") << QString("hh") << invalidTime();
- QTest::newRow("data8") << QString("22pm") << QString("Hap") << QTime(22, 0, 0);
- QTest::newRow("data9") << QString("2221") << QString("hhhh") << invalidTime();
- QTest::newRow("data10") << QString("02:23PM") << QString("hh:mmAP") << QTime(14,23,0,0);
- QTest::newRow("data11") << QString("02:23pm") << QString("hh:mmap") << QTime(14,23,0,0);
- QTest::newRow("short-msecs-lt100") << QString("10:12:34:045") << QString("hh:m:ss:z") << QTime(10,12,34,45);
- QTest::newRow("short-msecs-gt100") << QString("10:12:34:45") << QString("hh:m:ss:z") << QTime(10,12,34,450);
- QTest::newRow("late") << QString("23:59:59.999") << QString("hh:mm:ss.z") << QTime(23, 59, 59, 999);
-}
-
-void tst_QTime::fromStringFormat()
-{
- QFETCH(QString, string);
- QFETCH(QString, format);
- QFETCH(QTime, expected);
-
- QTime dt = QTime::fromString(string, format);
- QCOMPARE(dt, expected);
-}
-
-void tst_QTime::fromStringDateFormat_data()
-{
- QTest::addColumn<QString>("string");
- QTest::addColumn<Qt::DateFormat>("format");
- QTest::addColumn<QTime>("expected");
-
- QTest::newRow("TextDate - data0") << QString("00:00:00") << Qt::TextDate << QTime(0,0,0,0);
- QTest::newRow("TextDate - data1") << QString("10:12:34") << Qt::TextDate << QTime(10,12,34,0);
- QTest::newRow("TextDate - data2") << QString("19:03:54.998601") << Qt::TextDate << QTime(19, 3, 54, 999);
- QTest::newRow("TextDate - data3") << QString("19:03:54.999601") << Qt::TextDate << QTime(19, 3, 54, 999);
- QTest::newRow("TextDate - data4") << QString("10:12") << Qt::TextDate << QTime(10, 12, 0, 0);
- QTest::newRow("TextDate - invalid, minutes") << QString::fromLatin1("23:XX:00") << Qt::TextDate << invalidTime();
- QTest::newRow("TextDate - invalid, minute fraction") << QString::fromLatin1("23:00.123456") << Qt::TextDate << invalidTime();
- QTest::newRow("TextDate - invalid, seconds") << QString::fromLatin1("23:00:XX") << Qt::TextDate << invalidTime();
- QTest::newRow("TextDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::TextDate << QTime(23, 1, 1, 0);
- QTest::newRow("TextDate - midnight 24") << QString("24:00:00") << Qt::TextDate << QTime();
-
- QTest::newRow("IsoDate - valid, start of day, omit seconds") << QString::fromLatin1("00:00") << Qt::ISODate << QTime(0, 0, 0);
- QTest::newRow("IsoDate - valid, omit seconds") << QString::fromLatin1("22:21") << Qt::ISODate << QTime(22, 21, 0);
- QTest::newRow("IsoDate - valid, omit seconds (2)") << QString::fromLatin1("23:59") << Qt::ISODate << QTime(23, 59, 0);
- QTest::newRow("IsoDate - valid, end of day") << QString::fromLatin1("23:59:59") << Qt::ISODate << QTime(23, 59, 59);
-
- QTest::newRow("IsoDate - invalid, empty string") << QString::fromLatin1("") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, too many hours") << QString::fromLatin1("25:00") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, too many minutes") << QString::fromLatin1("10:70") << Qt::ISODate << invalidTime();
- // This is a valid time if it happens on June 30 or December 31 (leap seconds).
- QTest::newRow("IsoDate - invalid, too many seconds") << QString::fromLatin1("23:59:60") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, minutes") << QString::fromLatin1("23:XX:00") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, not enough minutes") << QString::fromLatin1("23:0") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, minute fraction") << QString::fromLatin1("23:00,XX") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, seconds") << QString::fromLatin1("23:00:XX") << Qt::ISODate << invalidTime();
- QTest::newRow("IsoDate - invalid, milliseconds") << QString::fromLatin1("23:01:01:XXXX") << Qt::ISODate << QTime(23, 1, 1, 0);
-
- QTest::newRow("IsoDate - data0") << QString("00:00:00") << Qt::ISODate << QTime(0,0,0,0);
- QTest::newRow("IsoDate - data1") << QString("10:12:34") << Qt::ISODate << QTime(10,12,34,0);
- QTest::newRow("IsoDate - data2") << QString("19:03:54.998601") << Qt::ISODate << QTime(19, 3, 54, 999);
- QTest::newRow("IsoDate - data3") << QString("19:03:54.999601") << Qt::ISODate << QTime(19, 3, 54, 999);
- QTest::newRow("IsoDate - midnight 24") << QString("24:00:00") << Qt::ISODate << QTime(0, 0, 0, 0);
- QTest::newRow("IsoDate - minute fraction midnight") << QString("24:00,0") << Qt::ISODate << QTime(0, 0, 0, 0);
-
- // Test Qt::RFC2822Date format (RFC 2822).
- QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QTime(13, 24, 51);
- QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000")
- << Qt::RFC2822Date << QTime(0, 12, 34);
- // No timezone
- QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34")
- << Qt::RFC2822Date << QTime(0, 12, 34);
- // No time specified
- QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002")
- << Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002")
- << Qt::RFC2822Date << invalidTime();
- // Test invalid month, day, year
- QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QTime(13, 24, 51);
- QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100")
- << Qt::RFC2822Date << QTime(13, 24, 51);
- QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100")
- << Qt::RFC2822Date << QTime(13, 24, 51);
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!")
- << Qt::RFC2822Date << QTime(8, 0, 0);
- QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!")
- << Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..")
- << Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000")
- << Qt::RFC2822Date << invalidTime();
-
- // Test Qt::RFC2822Date format (RFC 850 and 1036).
- QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100")
- << Qt::RFC2822Date << QTime(13, 24, 51);
- // No timezone
- QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970")
- << Qt::RFC2822Date << QTime(0, 12, 34);
- // No time specified
- QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002")
- << Qt::RFC2822Date << invalidTime();
- // Test invalid characters (should ignore invalid characters at end of string).
- QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!")
- << Qt::RFC2822Date << QTime(8, 0, 0);
- QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000")
- << Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!")
- << Qt::RFC2822Date << invalidTime();
- QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..")
- << Qt::RFC2822Date << invalidTime();
-
- QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidTime();
-}
-
-void tst_QTime::fromStringDateFormat()
-{
- QFETCH(QString, string);
- QFETCH(Qt::DateFormat, format);
- QFETCH(QTime, expected);
-
- QTime dt = QTime::fromString(string, format);
- QCOMPARE(dt, expected);
-}
-
-void tst_QTime::toStringDateFormat_data()
-{
- QTest::addColumn<QTime>("time");
- QTest::addColumn<Qt::DateFormat>("format");
- QTest::addColumn<QString>("expected");
-
- QTest::newRow("00:00:00.000") << QTime(0, 0, 0, 0) << Qt::TextDate << QString("00:00:00");
- QTest::newRow("ISO 00:00:00.000") << QTime(0, 0, 0, 0) << Qt::ISODate << QString("00:00:00");
- QTest::newRow("Text 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::TextDate << QString("10:12:34");
- QTest::newRow("ISO 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::ISODate << QString("10:12:34");
- QTest::newRow("Text 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::TextDate << QString("10:12:34");
- QTest::newRow("ISO 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::ISODate << QString("10:12:34");
- QTest::newRow("Text 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::TextDate << QString("10:12:34");
- QTest::newRow("ISO 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::ISODate << QString("10:12:34");
- QTest::newRow("RFC2822Date") << QTime(10, 12, 34, 999) << Qt::RFC2822Date << QString("10:12:34");
- QTest::newRow("ISOWithMs 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::ISODateWithMs << QString("10:12:34.000");
- QTest::newRow("ISOWithMs 10:12:34.020") << QTime(10, 12, 34, 20) << Qt::ISODateWithMs << QString("10:12:34.020");
- QTest::newRow("ISOWithMs 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::ISODateWithMs << QString("10:12:34.999");
-}
-
-void tst_QTime::toStringDateFormat()
-{
- QFETCH(QTime, time);
- QFETCH(Qt::DateFormat, format);
- QFETCH(QString, expected);
-
- QCOMPARE(time.toString(format), expected);
-}
-
-void tst_QTime::toStringFormat_data()
-{
- QTest::addColumn<QTime>("t");
- QTest::addColumn<QString>("format");
- QTest::addColumn<QString>("str");
-
- QTest::newRow( "midnight" ) << QTime(0,0,0,0) << QString("h:m:s:z") << QString("0:0:0:0");
- QTest::newRow( "full" ) << QTime(10,12,34,53) << QString("hh:mm:ss:zzz") << QString("10:12:34:053");
- QTest::newRow( "short-msecs-lt100" ) << QTime(10,12,34,45) << QString("hh:m:ss:z") << QString("10:12:34:045");
- QTest::newRow( "short-msecs-gt100" ) << QTime(10,12,34,450) << QString("hh:m:ss:z") << QString("10:12:34:45");
- QTest::newRow( "am-pm" ) << QTime(10,12,34,45) << QString("hh:ss ap") << QString("10:34 am");
- QTest::newRow( "AM-PM" ) << QTime(22,12,34,45) << QString("hh:zzz AP") << QString("10:045 PM");
- QTest::newRow( "invalid" ) << QTime(230,230,230,230) << QString("hh:mm:ss") << QString();
-}
-
-void tst_QTime::toStringFormat()
-{
- QFETCH( QTime, t );
- QFETCH( QString, format );
- QFETCH( QString, str );
-
- QCOMPARE( t.toString( format ), str );
-}
-
-void tst_QTime::toStringLocale()
-{
- QTime time(18, 30);
- QCOMPARE(time.toString(Qt::SystemLocaleShortDate),
- QLocale::system().toString(time, QLocale::ShortFormat));
- QCOMPARE(time.toString(Qt::DefaultLocaleShortDate),
- QLocale().toString(time, QLocale::ShortFormat));
- QCOMPARE(time.toString(Qt::SystemLocaleLongDate),
- QLocale::system().toString(time, QLocale::LongFormat));
- QCOMPARE(time.toString(Qt::DefaultLocaleLongDate),
- QLocale().toString(time, QLocale::LongFormat));
- QLocale::setDefault(QLocale::German);
- QCOMPARE(time.toString(Qt::SystemLocaleShortDate),
- QLocale::system().toString(time, QLocale::ShortFormat));
- QCOMPARE(time.toString(Qt::DefaultLocaleShortDate),
- QLocale().toString(time, QLocale::ShortFormat));
- QCOMPARE(time.toString(Qt::SystemLocaleLongDate),
- QLocale::system().toString(time, QLocale::LongFormat));
- QCOMPARE(time.toString(Qt::DefaultLocaleLongDate),
- QLocale().toString(time, QLocale::LongFormat));
-}
-
-void tst_QTime::msecsSinceStartOfDay_data()
-{
- QTest::addColumn<int>("msecs");
- QTest::addColumn<bool>("isValid");
- QTest::addColumn<int>("hour");
- QTest::addColumn<int>("minute");
- QTest::addColumn<int>("second");
- QTest::addColumn<int>("msec");
-
- QTest::newRow("00:00:00.000") << 0 << true
- << 0 << 0 << 0 << 0;
- QTest::newRow("01:00:00.001") << ((1 * 3600 * 1000) + 1) << true
- << 1 << 0 << 0 << 1;
- QTest::newRow("03:04:05.678") << ((3 * 3600 + 4 * 60 + 5) * 1000 + 678) << true
- << 3 << 4 << 5 << 678;
- QTest::newRow("23:59:59.999") << ((23 * 3600 + 59 * 60 + 59) * 1000 + 999) << true
- << 23 << 59 << 59 << 999;
- QTest::newRow("24:00:00.000") << ((24 * 3600) * 1000) << false
- << -1 << -1 << -1 << -1;
- QTest::newRow("-1 invalid") << -1 << false
- << -1 << -1 << -1 << -1;
-}
-
-void tst_QTime::msecsSinceStartOfDay()
-{
- QFETCH(int, msecs);
- QFETCH(bool, isValid);
- QFETCH(int, hour);
- QFETCH(int, minute);
- QFETCH(int, second);
- QFETCH(int, msec);
-
- QTime time = QTime::fromMSecsSinceStartOfDay(msecs);
- QCOMPARE(time.isValid(), isValid);
- if (msecs >= 0)
- QCOMPARE(time.msecsSinceStartOfDay(), msecs);
- else
- QCOMPARE(time.msecsSinceStartOfDay(), 0);
- QCOMPARE(time.hour(), hour);
- QCOMPARE(time.minute(), minute);
- QCOMPARE(time.second(), second);
- QCOMPARE(time.msec(), msec);
-}
-
-QTEST_APPLESS_MAIN(tst_QTime)
-#include "tst_qtime.moc"
diff --git a/tests/auto/corelib/tools/qtimeline/BLACKLIST b/tests/auto/corelib/tools/qtimeline/BLACKLIST
index 5611969b4d..8040a529ba 100644
--- a/tests/auto/corelib/tools/qtimeline/BLACKLIST
+++ b/tests/auto/corelib/tools/qtimeline/BLACKLIST
@@ -1,9 +1,6 @@
[interpolation]
windows
-osx-10.12
-osx-10.13
-[duration]
-windows
+osx
[frameRate]
-osx-10.12
-osx-10.13
+macos
+
diff --git a/tests/auto/corelib/tools/qtimeline/CMakeLists.txt b/tests/auto/corelib/tools/qtimeline/CMakeLists.txt
new file mode 100644
index 0000000000..a43e93990a
--- /dev/null
+++ b/tests/auto/corelib/tools/qtimeline/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qtimeline Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtimeline LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtimeline
+ SOURCES
+ tst_qtimeline.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/tools/qtimeline/qtimeline.pro b/tests/auto/corelib/tools/qtimeline/qtimeline.pro
deleted file mode 100644
index 9424cf8fd2..0000000000
--- a/tests/auto/corelib/tools/qtimeline/qtimeline.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtimeline
-QT = core testlib
-SOURCES = tst_qtimeline.cpp
diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp
index b68c582732..3593a65c4e 100644
--- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp
+++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp
@@ -1,32 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtTest/private/qpropertytesthelper_p.h>
+#include <QSignalSpy>
#include <qtimeline.h>
@@ -36,15 +13,20 @@ class tst_QTimeLine : public QObject
private slots:
void range();
void currentTime();
+ void bindableCurrentTime();
void duration();
+ void bindableDuration();
void frameRate();
+ void bindableUpdateInterval();
void value();
void currentFrame();
void loopCount();
+ void bindableLoopCount();
void interpolation();
void reverse_data();
void reverse();
void toggleDirection();
+ void bindableDirection();
void frameChanged();
void stopped();
void finished();
@@ -57,6 +39,7 @@ private slots:
void resume();
void restart();
void setPaused();
+ void automatedBindableTests();
protected slots:
void finishedSlot();
@@ -97,7 +80,7 @@ void tst_QTimeLine::range()
timeLine.setStartFrame(5000);
QVERIFY(timeLine.currentFrame() > oldValue);
timeLine.setFrameRange(0, 500);
- QTRY_VERIFY(spy.count() > 1);
+ QTRY_VERIFY(spy.size() > 1);
QVERIFY(timeLine.currentFrame() < oldValue);
}
@@ -119,7 +102,7 @@ void tst_QTimeLine::currentTime()
spy.clear();
timeLine.setCurrentTime(timeLine.duration()/2);
timeLine.setCurrentTime(timeLine.duration()/2);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
QCOMPARE(timeLine.currentTime(), timeLine.duration()/2);
timeLine.resume();
@@ -143,6 +126,55 @@ void tst_QTimeLine::currentTime()
timeLine.stop();
}
+void tst_QTimeLine::bindableCurrentTime()
+{
+ QTimeLine timeLine(2000);
+ QProperty<int> currentTimeObserver([&]() { return timeLine.currentTime(); });
+
+ timeLine.setUpdateInterval((timeLine.duration() / 2) / 33);
+ timeLine.setFrameRange(10, 20);
+ QCOMPARE(timeLine.currentTime(), 0);
+ QCOMPARE(currentTimeObserver.value(), 0);
+ QCOMPARE(currentTimeObserver.value(), timeLine.currentTime());
+
+ timeLine.start();
+ QTRY_COMPARE(timeLine.state(), QTimeLine::Running);
+ QCOMPARE(currentTimeObserver.value(), timeLine.currentTime());
+ QTRY_VERIFY(timeLine.currentTime() > timeLine.duration() / 2 - timeLine.duration() / 4);
+ QVERIFY(timeLine.currentTime() < timeLine.duration() / 2 + timeLine.duration() / 4);
+ QCOMPARE(currentTimeObserver.value(), timeLine.currentTime());
+
+ QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning);
+ QCOMPARE(timeLine.currentTime(), timeLine.duration());
+ QCOMPARE(currentTimeObserver.value(), timeLine.currentTime());
+
+ QSignalSpy spy(&timeLine, &QTimeLine::valueChanged);
+ QVERIFY(spy.isValid());
+ spy.clear();
+ QProperty<int> referenceCurrentTime(timeLine.duration() / 2);
+ timeLine.bindableCurrentTime().setBinding([&]() { return referenceCurrentTime.value(); });
+ QCOMPARE(spy.size(), 1);
+ // setting it a second time to check that valueChanged() is emitted only once
+ referenceCurrentTime = timeLine.duration() / 2;
+ QCOMPARE(spy.size(), 1);
+
+ spy.clear();
+ QCOMPARE(timeLine.currentTime(), timeLine.duration() / 2);
+ QCOMPARE(currentTimeObserver.value(), timeLine.duration() / 2);
+ timeLine.resume();
+ // Let it update on its own
+ QCOMPARE(timeLine.state(), QTimeLine::Running);
+ QTRY_VERIFY(currentTimeObserver.value() > timeLine.duration() / 2);
+ QVERIFY(currentTimeObserver.value() < timeLine.duration());
+ QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning);
+ QCOMPARE(currentTimeObserver.value(), timeLine.duration());
+ // the resume above should have broken the connection to referenceCurrentTime, check that:
+ spy.clear();
+ referenceCurrentTime = 0;
+ QCOMPARE(currentTimeObserver.value(), timeLine.duration());
+ QCOMPARE(spy.size(), 0);
+}
+
void tst_QTimeLine::duration()
{
QTimeLine timeLine(200);
@@ -160,6 +192,35 @@ void tst_QTimeLine::duration()
QCOMPARE(timeLine.duration(), 1000);
}
+void tst_QTimeLine::bindableDuration()
+{
+ QTimeLine timeLine(200);
+ QProperty<int> durationObserver;
+ durationObserver.setBinding([&]() { return timeLine.duration(); });
+ QCOMPARE(durationObserver.value(), timeLine.duration());
+
+ timeLine.setFrameRange(10, 20);
+ QCOMPARE(timeLine.duration(), 200);
+
+ QProperty<int> referenceDuration(500);
+ timeLine.bindableDuration().setBinding([&]() { return referenceDuration.value(); });
+ QCOMPARE(durationObserver.value(), referenceDuration.value());
+
+ QCOMPARE(timeLine.duration(), 500);
+
+ timeLine.start();
+ QTRY_COMPARE(timeLine.state(), QTimeLine::Running);
+ QTRY_VERIFY(timeLine.currentTime() > 0);
+ QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning);
+ QCOMPARE(timeLine.currentTime(), 500);
+ // The duration shouldn't change
+ QCOMPARE(timeLine.duration(), 500);
+
+ referenceDuration = 30;
+ QCOMPARE(timeLine.duration(), 30);
+ QCOMPARE(durationObserver.value(), 30);
+}
+
void tst_QTimeLine::frameRate()
{
QTimeLine timeLine;
@@ -175,7 +236,7 @@ void tst_QTimeLine::frameRate()
timeLine.start();
QTest::qWait(timeLine.duration()*2);
QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
- int slowCount = spy.count();
+ int slowCount = spy.size();
// Faster!!
timeLine.setUpdateInterval(1000 / 100);
@@ -184,7 +245,41 @@ void tst_QTimeLine::frameRate()
timeLine.start();
QTest::qWait(timeLine.duration()*2);
QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
- QVERIFY2(slowCount < spy.count(), QByteArray::number(spy.count()));
+ QVERIFY2(slowCount < spy.size(), QByteArray::number(spy.size()));
+}
+
+void tst_QTimeLine::bindableUpdateInterval()
+{
+ QTimeLine timeLine;
+ timeLine.setFrameRange(100, 2000);
+
+ QProperty<int> updateIntervalObserver;
+ updateIntervalObserver.setBinding([&]() { return timeLine.updateInterval(); });
+
+ QCOMPARE(updateIntervalObserver.value(), 1000 / 25);
+ QProperty<int> updateIntervalReference(1000 / 60);
+ timeLine.bindableUpdateInterval().setBinding([&]() { return updateIntervalReference.value(); });
+
+ updateIntervalReference = 1000 / 60;
+ QCOMPARE(updateIntervalObserver.value(), 1000 / 60);
+
+ // Default speed
+ updateIntervalReference = 1000 / 33;
+ QSignalSpy spy(&timeLine, &QTimeLine::frameChanged);
+ QVERIFY(spy.isValid());
+ timeLine.start();
+ QTest::qWait(timeLine.duration() * 2);
+ QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
+ int slowCount = spy.size();
+
+ // Faster!!
+ updateIntervalReference = 1000 / 100;
+ spy.clear();
+ timeLine.setCurrentTime(0);
+ timeLine.start();
+ QTest::qWait(timeLine.duration() * 2);
+ QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
+ QVERIFY2(slowCount < spy.size(), QByteArray::number(spy.size()));
}
void tst_QTimeLine::value()
@@ -199,7 +294,7 @@ void tst_QTimeLine::value()
QTRY_VERIFY(timeLine.currentValue() > 0);
QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning);
QCOMPARE(timeLine.currentValue(), 1.0);
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
// Reverse should decrease the value
timeLine.setCurrentTime(100);
@@ -248,7 +343,7 @@ void tst_QTimeLine::loopCount()
timeLine.setLoopCount(0);
QCOMPARE(timeLine.loopCount(), 0);
- // Default speed infiniti looping
+ // Default speed endless looping
QSignalSpy spy(&timeLine, &QTimeLine::frameChanged);
QVERIFY(spy.isValid());
timeLine.start();
@@ -263,7 +358,7 @@ void tst_QTimeLine::loopCount()
QCOMPARE(timeLine.state(), QTimeLine::Running);
timeLine.stop();
- timeLine.setDuration(2500); // ### some platforms have a very low resolution timer
+ timeLine.setDuration(2500); // some platforms have a very low resolution timer
timeLine.setFrameRange(0, 2);
timeLine.setLoopCount(4);
@@ -278,41 +373,125 @@ void tst_QTimeLine::loopCount()
for(int i=0;i<2;i++) {
timeLine.start();
- //we clear te list after the start so we don't catch
- //a frameChanged signal for the frame 0 at the beginning
+ // we clear the list after the start so we don't catch
+ // a frameChanged signal for the frame 0 at the beginning
finishedSpy.clear();
frameChangedSpy.clear();
loop.exec();
- QCOMPARE(finishedSpy.count(), 1);
- QCOMPARE(frameChangedSpy.count(), 11);
- for (int i = 0; i < 11; ++i) {
+ QCOMPARE(finishedSpy.size(), 1);
+ QCOMPARE(frameChangedSpy.size(), 11);
+ for (int i = 0; i < 11; ++i)
QCOMPARE(frameChangedSpy.at(i).at(0).toInt(), (i+1) % 3);
- }
}
timeLine.setDirection(QTimeLine::Backward);
timeLine.start();
loop.exec();
- QCOMPARE(finishedSpy.count(), 2);
- QCOMPARE(frameChangedSpy.count(), 22);
+ QCOMPARE(finishedSpy.size(), 2);
+ QCOMPARE(frameChangedSpy.size(), 22);
for (int i = 11; i < 22; ++i) {
QCOMPARE(frameChangedSpy.at(i).at(0).toInt(), 2 - (i+2) % 3);
}
}
+void tst_QTimeLine::bindableLoopCount()
+{
+ QTimeLine timeLine(200);
+ QProperty<int> referenceLoopCount(1);
+ timeLine.bindableLoopCount().setBinding([&]() { return referenceLoopCount.value(); });
+ QProperty<int> loopCountObserver([&]() { return timeLine.loopCount(); });
+
+ QCOMPARE(referenceLoopCount.value(), 1);
+ QCOMPARE(timeLine.loopCount(), 1);
+ QCOMPARE(loopCountObserver.value(), 1);
+
+ timeLine.setFrameRange(10, 20);
+
+ QCOMPARE(referenceLoopCount.value(), 1);
+ QCOMPARE(timeLine.loopCount(), 1);
+ QCOMPARE(loopCountObserver.value(), 1);
+
+ referenceLoopCount = 0;
+
+ QCOMPARE(referenceLoopCount.value(), 0);
+ QCOMPARE(timeLine.loopCount(), 0);
+ QCOMPARE(loopCountObserver.value(), 0);
+
+ // Default speed endless looping
+ QSignalSpy spy(&timeLine, &QTimeLine::frameChanged);
+ QVERIFY(spy.isValid());
+ timeLine.start();
+ QTest::qWait(timeLine.duration());
+ QCOMPARE(timeLine.state(), QTimeLine::Running);
+ // QCOMPARE(timeLine.currentFrame(), 20);
+ QTest::qWait(timeLine.duration() * 6);
+ QCOMPARE(timeLine.state(), QTimeLine::Running);
+ QVERIFY(timeLine.currentTime() >= 0);
+ QVERIFY(timeLine.currentFrame() >= 10);
+ QVERIFY(timeLine.currentFrame() <= 20);
+ QCOMPARE(timeLine.state(), QTimeLine::Running);
+ timeLine.stop();
+
+ timeLine.setDuration(2500); // some platforms have a very low resolution timer
+ timeLine.setFrameRange(0, 2);
+ referenceLoopCount = 4;
+
+ QSignalSpy finishedSpy(&timeLine, &QTimeLine::finished);
+ QSignalSpy frameChangedSpy(&timeLine, &QTimeLine::frameChanged);
+ QVERIFY(finishedSpy.isValid());
+ QVERIFY(frameChangedSpy.isValid());
+ QEventLoop loop;
+ connect(&timeLine, SIGNAL(finished()), &loop, SLOT(quit()));
+
+ for (int i = 0; i < 2; i++) {
+
+ timeLine.start();
+ // we clear the list after the start so we don't catch
+ // a frameChanged signal for the frame 0 at the beginning
+ finishedSpy.clear();
+ frameChangedSpy.clear();
+
+ loop.exec();
+
+ QCOMPARE(finishedSpy.size(), 1);
+ QCOMPARE(frameChangedSpy.size(), 11);
+ for (int i = 0; i < 11; ++i)
+ QCOMPARE(frameChangedSpy.at(i).at(0).toInt(), (i + 1) % 3);
+ }
+
+ timeLine.setDirection(QTimeLine::Backward);
+ timeLine.start();
+ loop.exec();
+
+ QCOMPARE(finishedSpy.size(), 2);
+ QCOMPARE(frameChangedSpy.size(), 22);
+ for (int i = 11; i < 22; ++i)
+ QCOMPARE(frameChangedSpy.at(i).at(0).toInt(), 2 - (i + 2) % 3);
+}
+
void tst_QTimeLine::interpolation()
{
+ // also tests bindableEasingCurve
QTimeLine timeLine(400);
- QCOMPARE(timeLine.curveShape(), QTimeLine::EaseInOutCurve);
+ QProperty<QEasingCurve> easingCurveObserver([&]() { return timeLine.easingCurve(); });
+
+ QCOMPARE(timeLine.easingCurve(), QEasingCurve::InOutSine);
+ QCOMPARE(easingCurveObserver.value(), QEasingCurve::InOutSine);
+
timeLine.setFrameRange(100, 200);
- timeLine.setCurveShape(QTimeLine::LinearCurve);
- QCOMPARE(timeLine.curveShape(), QTimeLine::LinearCurve);
+ QProperty<QEasingCurve> referenceEasingCurve(QEasingCurve::Linear);
+ timeLine.bindableEasingCurve().setBinding([&]() { return referenceEasingCurve.value(); });
+ QCOMPARE(timeLine.easingCurve(), QEasingCurve::Linear);
+ QCOMPARE(easingCurveObserver.value(), QEasingCurve::Linear);
// smooth
- timeLine.setCurveShape(QTimeLine::EaseInOutCurve);
+ referenceEasingCurve = QEasingCurve::InOutSine;
+ QCOMPARE(timeLine.easingCurve(), QEasingCurve::InOutSine);
+ QCOMPARE(easingCurveObserver.value(), QEasingCurve::InOutSine);
+
timeLine.start();
QTest::qWait(100);
QCOMPARE(timeLine.state(), QTimeLine::Running);
@@ -323,7 +502,11 @@ void tst_QTimeLine::interpolation()
timeLine.setCurrentTime(0);
// linear
- timeLine.setCurveShape(QTimeLine::LinearCurve);
+ referenceEasingCurve = QEasingCurve::Linear;
+
+ QCOMPARE(timeLine.easingCurve(), QEasingCurve::Linear);
+ QCOMPARE(easingCurveObserver.value(), QEasingCurve::Linear);
+
timeLine.start();
QTest::qWait(100);
QCOMPARE(timeLine.state(), QTimeLine::Running);
@@ -373,7 +556,7 @@ void tst_QTimeLine::reverse()
QFETCH(int, wait2);
QTimeLine timeLine(duration);
- timeLine.setCurveShape(QTimeLine::LinearCurve);
+ timeLine.setEasingCurve(QEasingCurve::Linear);
timeLine.setFrameRange(start, end);
timeLine.setDirection((QTimeLine::Direction)direction);
@@ -406,20 +589,44 @@ void tst_QTimeLine::reverse()
void tst_QTimeLine::toggleDirection()
{
- // Note: enum values are cast to int so that QCOMPARE will show
- // the values if they don't match.
QTimeLine timeLine;
- QCOMPARE(int(timeLine.direction()), int(QTimeLine::Forward));
+ QCOMPARE(timeLine.direction(), QTimeLine::Forward);
timeLine.toggleDirection();
- QCOMPARE(int(timeLine.direction()), int(QTimeLine::Backward));
+ QCOMPARE(timeLine.direction(), QTimeLine::Backward);
timeLine.toggleDirection();
- QCOMPARE(int(timeLine.direction()), int(QTimeLine::Forward));
+ QCOMPARE(timeLine.direction(), QTimeLine::Forward);
+}
+
+void tst_QTimeLine::bindableDirection()
+{
+ // Note: enum values are cast to int so that QCOMPARE will show
+ // the values if they don't match.
+ QTimeLine timeLine;
+ QProperty<QTimeLine::Direction> directionObserver([&]() { return timeLine.direction(); });
+ QProperty<QTimeLine::Direction> referenceDirection(QTimeLine::Forward);
+ timeLine.bindableDirection().setBinding([&]() { return referenceDirection.value(); });
+
+ QCOMPARE(referenceDirection.value(), QTimeLine::Forward);
+ QCOMPARE(timeLine.direction(), QTimeLine::Forward);
+ QCOMPARE(directionObserver.value(), QTimeLine::Forward);
+
+ referenceDirection = QTimeLine::Backward;
+
+ QCOMPARE(referenceDirection.value(), QTimeLine::Backward);
+ QCOMPARE(timeLine.direction(), QTimeLine::Backward);
+ QCOMPARE(directionObserver.value(), QTimeLine::Backward);
+
+ referenceDirection = QTimeLine::Forward;
+
+ QCOMPARE(referenceDirection.value(), QTimeLine::Forward);
+ QCOMPARE(timeLine.direction(), QTimeLine::Forward);
+ QCOMPARE(directionObserver.value(), QTimeLine::Forward);
}
void tst_QTimeLine::frameChanged()
{
QTimeLine timeLine;
- timeLine.setCurveShape(QTimeLine::LinearCurve);
+ timeLine.setEasingCurve(QEasingCurve::Linear);
timeLine.setFrameRange(0,9);
timeLine.setUpdateInterval(800);
QSignalSpy spy(&timeLine, &QTimeLine::frameChanged);
@@ -429,14 +636,14 @@ void tst_QTimeLine::frameChanged()
timeLine.start();
QTest::qWait(timeLine.duration()/2);
QCOMPARE(timeLine.state(), QTimeLine::Running);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QTest::qWait(timeLine.duration());
if (timeLine.state() != QTimeLine::NotRunning)
QEXPECT_FAIL("", "QTBUG-24796: QTimeLine runs slower than it should", Abort);
QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
- if (spy.count() != 1)
+ if (spy.size() != 1)
QEXPECT_FAIL("", "QTBUG-24796: QTimeLine runs slower than it should", Abort);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
// Test what happens when the frames are all emitted well before duration expires.
timeLine.setUpdateInterval(5);
@@ -445,7 +652,7 @@ void tst_QTimeLine::frameChanged()
timeLine.start();
QTest::qWait(timeLine.duration()*2);
QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
- QCOMPARE(spy.count(), 10);
+ QCOMPARE(spy.size(), 10);
}
void tst_QTimeLine::stopped()
@@ -458,11 +665,11 @@ void tst_QTimeLine::stopped()
timeLine.start();
QTest::qWait(timeLine.duration()*2);
QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
spy.clear();
timeLine.start();
timeLine.stop();
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
timeLine.setDirection(QTimeLine::Backward);
QCOMPARE(timeLine.loopCount(), 1);
}
@@ -474,13 +681,13 @@ void tst_QTimeLine::finished()
QSignalSpy spy(&timeLine, &QTimeLine::finished);
QVERIFY(spy.isValid());
timeLine.start();
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(timeLine.state(), QTimeLine::NotRunning);
spy.clear();
timeLine.start();
timeLine.stop();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QTimeLine::isRunning()
@@ -513,13 +720,13 @@ void tst_QTimeLine::multipleTimeLines()
timeLine.start();
timeLineKiller.stop();
QTest::qWait(timeLine.duration()*2);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QTimeLine::sineCurve()
{
QTimeLine timeLine(1000);
- timeLine.setCurveShape(QTimeLine::SineCurve);
+ timeLine.setEasingCurve(QEasingCurve::SineCurve);
QCOMPARE(timeLine.valueForTime(0), qreal(0));
QCOMPARE(timeLine.valueForTime(250), qreal(0.5));
QCOMPARE(timeLine.valueForTime(500), qreal(1));
@@ -530,7 +737,7 @@ void tst_QTimeLine::sineCurve()
void tst_QTimeLine::cosineCurve()
{
QTimeLine timeLine(1000);
- timeLine.setCurveShape(QTimeLine::CosineCurve);
+ timeLine.setEasingCurve(QEasingCurve::CosineCurve);
QCOMPARE(timeLine.valueForTime(0), qreal(0.5));
QCOMPARE(timeLine.valueForTime(250), qreal(1));
QCOMPARE(timeLine.valueForTime(500), qreal(0.5));
@@ -544,7 +751,7 @@ void tst_QTimeLine::outOfRange()
QCOMPARE(timeLine.valueForTime(-100), qreal(0));
QCOMPARE(timeLine.valueForTime(2000), qreal(1));
- timeLine.setCurveShape(QTimeLine::SineCurve);
+ timeLine.setEasingCurve(QEasingCurve::SineCurve);
QCOMPARE(timeLine.valueForTime(2000), qreal(0));
}
@@ -659,6 +866,49 @@ void tst_QTimeLine::setPaused()
}
}
+void tst_QTimeLine::automatedBindableTests()
+{
+ QTimeLine timeLine(200);
+
+ QTestPrivate::testReadWritePropertyBasics(timeLine, 1000, 2000, "duration");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for duration";
+ return;
+ }
+
+ QTestPrivate::testReadWritePropertyBasics(timeLine, 10, 20, "updateInterval");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for updateInterval";
+ return;
+ }
+
+ QTestPrivate::testReadWritePropertyBasics(timeLine, 10, 20, "currentTime");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for currentTime";
+ return;
+ }
+
+ QTestPrivate::testReadWritePropertyBasics(timeLine, QTimeLine::Forward, QTimeLine::Backward,
+ "direction");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for direction";
+ return;
+ }
+
+ QTestPrivate::testReadWritePropertyBasics(timeLine, 4, 5, "loopCount");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for loopCount";
+ return;
+ }
+
+ QTestPrivate::testReadWritePropertyBasics<QTimeLine, QEasingCurve>(
+ timeLine, QEasingCurve::InQuad, QEasingCurve::OutQuad, "easingCurve");
+ if (QTest::currentTestFailed()) {
+ qDebug() << "Failed property test for easingCurve";
+ return;
+ }
+}
+
QTEST_MAIN(tst_QTimeLine)
#include "tst_qtimeline.moc"
diff --git a/tests/auto/corelib/tools/qtimezone/BLACKLIST b/tests/auto/corelib/tools/qtimezone/BLACKLIST
deleted file mode 100644
index 840c3b1181..0000000000
--- a/tests/auto/corelib/tools/qtimezone/BLACKLIST
+++ /dev/null
@@ -1,171 +0,0 @@
-# QTBUG-69122
-[dataStreamTest]
-android
-
-# QTBUG-69128
-[isTimeZoneIdAvailable]
-android
-
-# QTBUG-69129
-[specificTransition]
-android
-
-# QTBUG-69131
-[transitionEachZone:America/Cancun@2010]
-android
-[transitionEachZone:America/Eirunepe@2010]
-android
-[transitionEachZone:America/Montevideo@2010]
-android
-[transitionEachZone:America/Porto_Acre@2010]
-android
-[transitionEachZone:America/Rio_Branco@2010]
-android
-[transitionEachZone:Asia/Anadyr@2010]
-android
-[transitionEachZone:Asia/Chita@2010]
-android
-[transitionEachZone:Asia/Kamchatka@2010]
-android
-[transitionEachZone:Asia/Khandyga@2010]
-android
-[transitionEachZone:Asia/Magadan@2010]
-android
-[transitionEachZone:Asia/Novokuznetsk@2010]
-android
-[transitionEachZone:Asia/Pyongyang@2010]
-android
-[transitionEachZone:Asia/Ust-Nera@2010]
-android
-[transitionEachZone:Asia/Yerevan@2010]
-android
-[transitionEachZone:Europe/Kaliningrad@2010]
-android
-[transitionEachZone:Europe/Minsk@2010]
-android
-[transitionEachZone:Europe/Moscow@2010]
-android
-[transitionEachZone:Europe/Samara@2010]
-android
-[transitionEachZone:Europe/Simferopol@2010]
-android
-[transitionEachZone:Europe/Volgograd@2010]
-android
-[transitionEachZone:W-SU@2010]
-android
-[transitionEachZone:Africa/Bissau@1970]
-android
-[transitionEachZone:Africa/Juba@1970]
-android
-[transitionEachZone:Africa/Khartoum@1970]
-android
-[transitionEachZone:America/Metlakatla@1970]
-android
-[transitionEachZone:America/Montevideo@1970]
-android
-[transitionEachZone:America/Paramaribo@1970]
-android
-[transitionEachZone:America/Santarem@1970]
-android
-[transitionEachZone:America/Santo_Domingo@1970]
-android
-[transitionEachZone:Asia/Anadyr@1970]
-android
-[transitionEachZone:Asia/Bahrain@1970]
-android
-[transitionEachZone:Asia/Chita@1970]
-android
-[transitionEachZone:Asia/Dushanbe@1970]
-android
-[transitionEachZone:Asia/Ho_Chi_Minh@1970]
-android
-[transitionEachZone:Asia/Kathmandu@1970]
-android
-[transitionEachZone:Asia/Katmandu@1970]
-android
-[transitionEachZone:Asia/Kuala_Lumpur@1970]
-android
-[transitionEachZone:Asia/Magadan@1970]
-android
-[transitionEachZone:Asia/Novosibirsk@1970]
-android
-[transitionEachZone:Asia/Pontianak@1970]
-android
-[transitionEachZone:Asia/Pyongyang@1970]
-android
-[transitionEachZone:Asia/Qatar@1970]
-android
-[transitionEachZone:Asia/Qyzylorda@1970]
-android
-[transitionEachZone:Asia/Saigon@1970]
-android
-[transitionEachZone:Asia/Sakhalin@1970]
-android
-[transitionEachZone:Asia/Singapore@1970]
-android
-[transitionEachZone:Asia/Tashkent@1970]
-android
-[transitionEachZone:Asia/Thimbu@1970]
-android
-[transitionEachZone:Asia/Thimphu@1970]
-android
-[transitionEachZone:Asia/Ust-Nera@1970]
-android
-[transitionEachZone:Atlantic/Cape_Verde@1970]
-android
-[transitionEachZone:Chile/EasterIsland@1970]
-android
-[transitionEachZone:Europe/Kaliningrad@1970]
-android
-[transitionEachZone:Pacific/Bougainville@1970]
-android
-[transitionEachZone:Pacific/Easter@1970]
-android
-[transitionEachZone:Pacific/Enderbury@1970]
-android
-[transitionEachZone:Pacific/Galapagos@1970]
-android
-[transitionEachZone:Pacific/Kiritimati@1970]
-android
-[transitionEachZone:Pacific/Kosrae@1970]
-android
-[transitionEachZone:Pacific/Kwajalein@1970]
-android
-[transitionEachZone:Pacific/Nauru@1970]
-android
-[transitionEachZone:Pacific/Niue@1970]
-android
-[transitionEachZone:Singapore@1970]
-android
-[transitionEachZone:Brazil/Acre@2010]
-android
-[transitionEachZone:Pacific/Bougainville@2010]
-android
-[transitionEachZone:Africa/Algiers@1970]
-android
-[transitionEachZone:Africa/Monrovia@1970]
-android
-[transitionEachZone:Kwajalein@1970]
-android
-[transitionEachZone:Indian/Chagos@1970]
-android
-[transitionEachZone:Europe/Volgograd@1970]
-android
-[transitionEachZone:Atlantic/Stanley@1970]
-android
-[transitionEachZone:Antarctica/Mawson@1970]
-android
-[transitionEachZone:America/Swift_Current@1970]
-android
-[transitionEachZone:America/Guyana@1970]
-android
-[transitionEachZone:America/Grand_Turk@1970]
-android
-[transitionEachZone:America/Dawson_Creek@1970]
-android
-[transitionEachZone:America/Cancun@1970]
-android
-[transitionEachZone:America/Caracas@1970]
-android
-[transitionEachZone:America/Danmarkshavn@1970]
-android
diff --git a/tests/auto/corelib/tools/qtimezone/qtimezone.pro b/tests/auto/corelib/tools/qtimezone/qtimezone.pro
deleted file mode 100644
index 5ec8d008e7..0000000000
--- a/tests/auto/corelib/tools/qtimezone/qtimezone.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qtimezone
-QT = core-private testlib
-SOURCES = tst_qtimezone.cpp
-qtConfig(icu) {
- QMAKE_USE_PRIVATE += icu
-}
-
-darwin {
- OBJECTIVE_SOURCES += tst_qtimezone_darwin.mm
- LIBS += -framework Foundation
-}
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
deleted file mode 100644
index bb6c48a2ed..0000000000
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ /dev/null
@@ -1,1333 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qtimezone.h>
-#include <private/qtimezoneprivate_p.h>
-#include <qlocale.h>
-
-#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
-# define USING_WIN_TZ
-#endif
-
-class tst_QTimeZone : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QTimeZone();
-
-private slots:
- // Public class default system tests
- void createTest();
- void nullTest();
- void dataStreamTest();
- void isTimeZoneIdAvailable();
- void availableTimeZoneIds();
- void specificTransition_data();
- void specificTransition();
- void transitionEachZone_data();
- void transitionEachZone();
- void checkOffset_data();
- void checkOffset();
- void stressTest();
- void windowsId();
- void isValidId_data();
- void isValidId();
- // Backend tests
- void utcTest();
- void icuTest();
- void tzTest();
- void macTest();
- void darwinTypes();
- void winTest();
-
-private:
- void printTimeZone(const QTimeZone &tz);
-#ifdef QT_BUILD_INTERNAL
- // Generic tests of privates, called by implementation-specific private tests:
- void testCetPrivate(const QTimeZonePrivate &tzp);
- void testEpochTranPrivate(const QTimeZonePrivate &tzp);
-#endif // QT_BUILD_INTERNAL
- const bool debug;
-};
-
-tst_QTimeZone::tst_QTimeZone()
- // Set to true to print debug output, test Display Names and run long stress tests
- : debug(false)
-{
-}
-
-void tst_QTimeZone::printTimeZone(const QTimeZone &tz)
-{
- QDateTime now = QDateTime::currentDateTime();
- QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- qDebug() << "";
- qDebug() << "Time Zone = " << tz;
- qDebug() << "";
- qDebug() << "Is Valid = " << tz.isValid();
- qDebug() << "";
- qDebug() << "Zone ID = " << tz.id();
- qDebug() << "Country = " << QLocale::countryToString(tz.country());
- qDebug() << "Comment = " << tz.comment();
- qDebug() << "";
- qDebug() << "Locale = " << QLocale().name();
- qDebug() << "Name Long = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName);
- qDebug() << "Name Short = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::ShortName);
- qDebug() << "Name Offset = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName);
- qDebug() << "Name Long DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::LongName);
- qDebug() << "Name Short DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName);
- qDebug() << "Name Offset DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName);
- qDebug() << "Name Long Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::LongName);
- qDebug() << "Name Short Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::ShortName);
- qDebug() << "Name Offset Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName);
- qDebug() << "";
- QLocale locale = QLocale(QStringLiteral("de_DE"));
- qDebug() << "Locale = " << locale.name();
- qDebug() << "Name Long = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName, locale);
- qDebug() << "Name Short = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, locale);
- qDebug() << "Name Offset = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, locale);
- qDebug() << "Name Long DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::LongName,locale);
- qDebug() << "Name Short DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, locale);
- qDebug() << "Name Offset DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, locale);
- qDebug() << "Name Long Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::LongName, locale);
- qDebug() << "Name Short Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, locale);
- qDebug() << "Name Offset Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, locale);
- qDebug() << "";
- qDebug() << "Abbreviation Now = " << tz.abbreviation(now);
- qDebug() << "Abbreviation on 1 Jan = " << tz.abbreviation(jan);
- qDebug() << "Abbreviation on 1 June = " << tz.abbreviation(jun);
- qDebug() << "";
- qDebug() << "Offset on 1 January = " << tz.offsetFromUtc(jan);
- qDebug() << "Offset on 1 June = " << tz.offsetFromUtc(jun);
- qDebug() << "Offset Now = " << tz.offsetFromUtc(now);
- qDebug() << "";
- qDebug() << "UTC Offset Now = " << tz.standardTimeOffset(now);
- qDebug() << "UTC Offset on 1 January = " << tz.standardTimeOffset(jan);
- qDebug() << "UTC Offset on 1 June = " << tz.standardTimeOffset(jun);
- qDebug() << "";
- qDebug() << "DST Offset on 1 January = " << tz.daylightTimeOffset(jan);
- qDebug() << "DST Offset on 1 June = " << tz.daylightTimeOffset(jun);
- qDebug() << "DST Offset Now = " << tz.daylightTimeOffset(now);
- qDebug() << "";
- qDebug() << "Has DST = " << tz.hasDaylightTime();
- qDebug() << "Is DST Now = " << tz.isDaylightTime(now);
- qDebug() << "Is DST on 1 January = " << tz.isDaylightTime(jan);
- qDebug() << "Is DST on 1 June = " << tz.isDaylightTime(jun);
- qDebug() << "";
- qDebug() << "Has Transitions = " << tz.hasTransitions();
- qDebug() << "Transition after 1 Jan = " << tz.nextTransition(jan).atUtc;
- qDebug() << "Transition after 1 Jun = " << tz.nextTransition(jun).atUtc;
- qDebug() << "Transition before 1 Jan = " << tz.previousTransition(jan).atUtc;
- qDebug() << "Transition before 1 Jun = " << tz.previousTransition(jun).atUtc;
- qDebug() << "";
-}
-
-void tst_QTimeZone::createTest()
-{
- QTimeZone tz("Pacific/Auckland");
-
- if (debug)
- printTimeZone(tz);
-
- // If the tz is not valid then skip as is probably using the UTC backend which is tested later
- if (!tz.isValid())
- return;
-
- // Validity tests
- QCOMPARE(tz.isValid(), true);
-
- // Comparison tests
- QTimeZone tz2("Pacific/Auckland");
- QTimeZone tz3("Australia/Sydney");
- QCOMPARE((tz == tz2), true);
- QCOMPARE((tz != tz2), false);
- QCOMPARE((tz == tz3), false);
- QCOMPARE((tz != tz3), true);
-
- QCOMPARE(tz.country(), QLocale::NewZealand);
-
- QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC);
-
- QCOMPARE(tz.offsetFromUtc(jan), 13 * 3600);
- QCOMPARE(tz.offsetFromUtc(jun), 12 * 3600);
-
- QCOMPARE(tz.standardTimeOffset(jan), 12 * 3600);
- QCOMPARE(tz.standardTimeOffset(jun), 12 * 3600);
-
- QCOMPARE(tz.daylightTimeOffset(jan), 3600);
- QCOMPARE(tz.daylightTimeOffset(jun), 0);
-
- QCOMPARE(tz.hasDaylightTime(), true);
- QCOMPARE(tz.isDaylightTime(jan), true);
- QCOMPARE(tz.isDaylightTime(jun), false);
-
- // Only test transitions if host system supports them
- if (tz.hasTransitions()) {
- QTimeZone::OffsetData tran = tz.nextTransition(jan);
- // 2012-04-01 03:00 NZDT, +13 -> +12
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2012, 4, 1), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600));
- QCOMPARE(tran.offsetFromUtc, 12 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- tran = tz.nextTransition(jun);
- // 2012-09-30 02:00 NZST, +12 -> +13
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2012, 9, 30), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600));
- QCOMPARE(tran.offsetFromUtc, 13 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- tran = tz.previousTransition(jan);
- // 2011-09-25 02:00 NZST, +12 -> +13
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2011, 9, 25), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600));
- QCOMPARE(tran.offsetFromUtc, 13 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- tran = tz.previousTransition(jun);
- // 2012-04-01 03:00 NZDT, +13 -> +12 (again)
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2012, 4, 1), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600));
- QCOMPARE(tran.offsetFromUtc, 12 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- QTimeZone::OffsetDataList expected;
- tran.atUtc = QDateTime(QDate(2011, 4, 3), QTime(2, 0), Qt::OffsetFromUTC, 13 * 3600);
- tran.offsetFromUtc = 13 * 3600;
- tran.standardTimeOffset = 12 * 3600;
- tran.daylightTimeOffset = 3600;
- expected << tran;
- tran.atUtc = QDateTime(QDate(2011, 9, 25), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600);
- tran.offsetFromUtc = 12 * 3600;
- tran.standardTimeOffset = 12 * 3600;
- tran.daylightTimeOffset = 0;
- expected << tran;
- QTimeZone::OffsetDataList result = tz.transitions(janPrev, jan);
- QCOMPARE(result.count(), expected.count());
- for (int i = 0; i > expected.count(); ++i) {
- QCOMPARE(result.at(i).atUtc, expected.at(i).atUtc);
- QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
- QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
- QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
- }
- }
-}
-
-void tst_QTimeZone::nullTest()
-{
- QTimeZone nullTz1;
- QTimeZone nullTz2;
- QTimeZone utc("UTC");
-
- // Validity tests
- QCOMPARE(nullTz1.isValid(), false);
- QCOMPARE(nullTz2.isValid(), false);
- QCOMPARE(utc.isValid(), true);
-
- // Comparison tests
- QCOMPARE((nullTz1 == nullTz2), true);
- QCOMPARE((nullTz1 != nullTz2), false);
- QCOMPARE((nullTz1 == utc), false);
- QCOMPARE((nullTz1 != utc), true);
-
- // Assignment tests
- nullTz2 = utc;
- QCOMPARE(nullTz2.isValid(), true);
- utc = nullTz1;
- QCOMPARE(utc.isValid(), false);
-
- QCOMPARE(nullTz1.id(), QByteArray());
- QCOMPARE(nullTz1.country(), QLocale::AnyCountry);
- QCOMPARE(nullTz1.comment(), QString());
-
- QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC);
-
- QCOMPARE(nullTz1.abbreviation(jan), QString());
- QCOMPARE(nullTz1.displayName(jan), QString());
- QCOMPARE(nullTz1.displayName(QTimeZone::StandardTime), QString());
-
- QCOMPARE(nullTz1.offsetFromUtc(jan), 0);
- QCOMPARE(nullTz1.offsetFromUtc(jun), 0);
-
- QCOMPARE(nullTz1.standardTimeOffset(jan), 0);
- QCOMPARE(nullTz1.standardTimeOffset(jun), 0);
-
- QCOMPARE(nullTz1.daylightTimeOffset(jan), 0);
- QCOMPARE(nullTz1.daylightTimeOffset(jun), 0);
-
- QCOMPARE(nullTz1.hasDaylightTime(), false);
- QCOMPARE(nullTz1.isDaylightTime(jan), false);
- QCOMPARE(nullTz1.isDaylightTime(jun), false);
-
- QTimeZone::OffsetData data = nullTz1.offsetData(jan);
- QCOMPARE(data.atUtc, QDateTime());
- QCOMPARE(data.offsetFromUtc, std::numeric_limits<int>::min());
- QCOMPARE(data.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
-
- QCOMPARE(nullTz1.hasTransitions(), false);
-
- data = nullTz1.nextTransition(jan);
- QCOMPARE(data.atUtc, QDateTime());
- QCOMPARE(data.offsetFromUtc, std::numeric_limits<int>::min());
- QCOMPARE(data.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
-
- data = nullTz1.previousTransition(jan);
- QCOMPARE(data.atUtc, QDateTime());
- QCOMPARE(data.offsetFromUtc, std::numeric_limits<int>::min());
- QCOMPARE(data.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
-}
-
-void tst_QTimeZone::dataStreamTest()
-{
- // Test the OffsetFromUtc backend serialization. First with a custom timezone:
- QTimeZone tz1("QST", 123456, "Qt Standard Time", "QST", QLocale::Norway, "Qt Testing");
- QByteArray tmp;
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << tz1;
- }
- QTimeZone tz2("UTC");
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> tz2;
- }
- QCOMPARE(tz2.id(), QByteArray("QST"));
- QCOMPARE(tz2.comment(), QString("Qt Testing"));
- QCOMPARE(tz2.country(), QLocale::Norway);
- QCOMPARE(tz2.abbreviation(QDateTime::currentDateTime()), QString("QST"));
- QCOMPARE(tz2.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QString()),
- QString("Qt Standard Time"));
- QCOMPARE(tz2.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, QString()),
- QString("Qt Standard Time"));
- QCOMPARE(tz2.offsetFromUtc(QDateTime::currentDateTime()), 123456);
-
- // And then with a standard IANA timezone (QTBUG-60595):
- tz1 = QTimeZone("UTC");
- QCOMPARE(tz1.isValid(), true);
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << tz1;
- }
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> tz2;
- }
- QCOMPARE(tz2.isValid(), true);
- QCOMPARE(tz2.id(), tz1.id());
-
- // Test the system backend serialization
- tz1 = QTimeZone("Pacific/Auckland");
-
- // If not valid then probably using the UTC system backend so skip
- if (!tz1.isValid())
- return;
-
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << tz1;
- }
- tz2 = QTimeZone("UTC");
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> tz2;
- }
- QCOMPARE(tz2.id(), tz1.id());
-}
-
-void tst_QTimeZone::isTimeZoneIdAvailable()
-{
- QList<QByteArray> available = QTimeZone::availableTimeZoneIds();
- foreach (const QByteArray &id, available)
- QVERIFY(QTimeZone::isTimeZoneIdAvailable(id));
-
-#ifdef QT_BUILD_INTERNAL
- // a-z, A-Z, 0-9, '.', '-', '_' are valid chars
- // Can't start with '-'
- // Parts separated by '/', each part min 1 and max of 14 chars
- QCOMPARE(QTimeZonePrivate::isValidId("az"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("AZ"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("09"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a/z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a.z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a-z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a_z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId(".z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("_z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("12345678901234"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/12345678901234"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("a\\z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("a,z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("/z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("-z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("123456789012345"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("123456789012345/12345678901234"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/123456789012345"), false);
-#endif // QT_BUILD_INTERNAL
-}
-
-void tst_QTimeZone::specificTransition_data()
-{
- QTest::addColumn<QByteArray>("zone");
- QTest::addColumn<QDate>("start");
- QTest::addColumn<QDate>("stop");
- QTest::addColumn<int>("count");
- QTest::addColumn<QDateTime>("atUtc");
- // In minutes:
- QTest::addColumn<int>("offset");
- QTest::addColumn<int>("stdoff");
- QTest::addColumn<int>("dstoff");
-
- // Moscow ditched DST on 2010-10-31 but has since changed standard offset twice.
-#ifdef USING_WIN_TZ
- // Win7 is too old to know about this transition:
- if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7)
-#endif
- {
- QTest::newRow("Moscow/2014") // From original bug-report
- << QByteArray("Europe/Moscow")
- << QDate(2011, 4, 1) << QDate(2017, 12,31) << 1
- << QDateTime(QDate(2014, 10, 26), QTime(2, 0, 0),
- Qt::OffsetFromUTC, 4 * 3600).toUTC()
- << 3 * 3600 << 3 * 3600 << 0;
- }
- QTest::newRow("Moscow/2011") // Transition on 2011-03-27
- << QByteArray("Europe/Moscow")
- << QDate(2010, 11, 1) << QDate(2014, 10, 25) << 1
- << QDateTime(QDate(2011, 3, 27), QTime(2, 0, 0),
- Qt::OffsetFromUTC, 3 * 3600).toUTC()
- << 4 * 3600 << 4 * 3600 << 0;
-}
-
-void tst_QTimeZone::specificTransition()
-{
- // Regression test for QTBUG-42021 (on MS-Win)
- QFETCH(QByteArray, zone);
- QFETCH(QDate, start);
- QFETCH(QDate, stop);
- QFETCH(int, count);
- // No attempt to check abbreviations; to much cross-platform variation.
- QFETCH(QDateTime, atUtc);
- QFETCH(int, offset);
- QFETCH(int, stdoff);
- QFETCH(int, dstoff);
-
- QTimeZone timeZone(zone);
- if (!timeZone.isValid())
- QSKIP("Missing time-zone data");
- QTimeZone::OffsetDataList transits =
- timeZone.transitions(QDateTime(start, QTime(0, 0), timeZone),
- QDateTime(stop, QTime(23, 59), timeZone));
- QCOMPARE(transits.length(), count);
- const QTimeZone::OffsetData &transition = transits.at(0);
- QCOMPARE(transition.offsetFromUtc, offset);
- QCOMPARE(transition.standardTimeOffset, stdoff);
- QCOMPARE(transition.daylightTimeOffset, dstoff);
- QCOMPARE(transition.atUtc, atUtc);
-}
-
-void tst_QTimeZone::transitionEachZone_data()
-{
- QTest::addColumn<QByteArray>("zone");
- QTest::addColumn<qint64>("secs");
- QTest::addColumn<int>("start");
- QTest::addColumn<int>("stop");
-
- struct {
- qint64 baseSecs;
- int start, stop;
- int year;
- } table[] = {
- { 25666200, 3, 12, 1970 }, // 1970-10-25 01:30 UTC; North America
- { 1288488600, -4, 8, 2010 } // 2010-10-31 01:30 UTC; Europe, Russia
- };
-
- QString name;
- const auto zones = QTimeZone::availableTimeZoneIds();
- for (int k = sizeof(table) / sizeof(table[0]); k-- > 0; ) {
- for (const QByteArray &zone : zones) {
- name.sprintf("%s@%d", zone.constData(), table[k].year);
- QTest::newRow(name.toUtf8().constData())
- << zone
- << table[k].baseSecs
- << table[k].start
- << table[k].stop;
- }
- }
-}
-
-void tst_QTimeZone::transitionEachZone()
-{
- // Regression test: round-trip fromMsecs/toMSecs should be idempotent; but
- // various zones failed during fall-back transitions.
- QFETCH(QByteArray, zone);
- QFETCH(qint64, secs);
- QFETCH(int, start);
- QFETCH(int, stop);
- QTimeZone named(zone);
-
- for (int i = start; i < stop; i++) {
-#ifdef USING_WIN_TZ
- // See QTBUG-64985: MS's TZ APIs' misdescription of Europe/Samara leads
- // to mis-disambiguation of its fall-back here.
- if (zone == "Europe/Samara" && i == -3) {
- continue;
- }
-#endif
-#ifdef Q_OS_ANDROID
- if (zone == "America/Mazatlan" || zone == "Mexico/BajaSur")
- QSKIP("Crashes on Android, see QTBUG-69132");
-#endif
- qint64 here = secs + i * 3600;
- QDateTime when = QDateTime::fromMSecsSinceEpoch(here * 1000, named);
- qint64 stamp = when.toMSecsSinceEpoch();
- if (here * 1000 != stamp) // (The +1 is due to using *1*:30 as baseSecs.)
- qDebug() << "Failing for" << zone << "at half past" << (i + 1) << "UTC";
- QCOMPARE(stamp % 1000, 0);
- QCOMPARE(here - stamp / 1000, 0);
- }
-}
-
-void tst_QTimeZone::checkOffset_data()
-{
- QTest::addColumn<QByteArray>("zoneName");
- QTest::addColumn<QDateTime>("when");
- QTest::addColumn<int>("netOffset");
- QTest::addColumn<int>("stdOffset");
- QTest::addColumn<int>("dstOffset");
-
- struct {
- const char *zone, *nick;
- int year, month, day, hour, min, sec;
- int std, dst;
- } table[] = {
- // Zone with no transitions (QTBUG-74614, QTBUG-74666, when TZ backend uses minimal data)
- { "Etc/UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 },
- { "Etc/UTC", "pre_int32", 1901, 12, 13, 20, 45, 51, 0, 0 },
- { "Etc/UTC", "post_int32", 2038, 1, 19, 3, 14, 9, 0, 0 },
- { "Etc/UTC", "post_uint32", 2106, 2, 7, 6, 28, 17, 0, 0 },
- { "Etc/UTC", "initial", -292275056, 5, 16, 16, 47, 5, 0, 0 },
- { "Etc/UTC", "final", 292278994, 8, 17, 7, 12, 55, 0, 0 },
- // Kiev: regression test for QTBUG-64122 (on MS):
- { "Europe/Kiev", "summer", 2017, 10, 27, 12, 0, 0, 2 * 3600, 3600 },
- { "Europe/Kiev", "winter", 2017, 10, 29, 12, 0, 0, 2 * 3600, 0 }
- };
- for (const auto &entry : table) {
- QTimeZone zone(entry.zone);
- if (zone.isValid()) {
- QTest::addRow("%s@%s", entry.zone, entry.nick)
- << QByteArray(entry.zone)
- << QDateTime(QDate(entry.year, entry.month, entry.day),
- QTime(entry.hour, entry.min, entry.sec), zone)
- << entry.dst + entry.std << entry.std << entry.dst;
- } else {
- qWarning("Skipping %s@%s test as zone is invalid", entry.zone, entry.nick);
- }
- }
-}
-
-void tst_QTimeZone::checkOffset()
-{
- QFETCH(QByteArray, zoneName);
- QFETCH(QDateTime, when);
- QFETCH(int, netOffset);
- QFETCH(int, stdOffset);
- QFETCH(int, dstOffset);
-
- QTimeZone zone(zoneName);
- QVERIFY(zone.isValid()); // It was when _data() added the row !
- QCOMPARE(zone.offsetFromUtc(when), netOffset);
- QCOMPARE(zone.standardTimeOffset(when), stdOffset);
- QCOMPARE(zone.daylightTimeOffset(when), dstOffset);
- QCOMPARE(zone.isDaylightTime(when), dstOffset != 0);
-}
-
-void tst_QTimeZone::availableTimeZoneIds()
-{
- if (debug) {
- qDebug() << "";
- qDebug() << "Available Time Zones" ;
- qDebug() << QTimeZone::availableTimeZoneIds();
- qDebug() << "";
- qDebug() << "Available Time Zones in the US";
- qDebug() << QTimeZone::availableTimeZoneIds(QLocale::UnitedStates);
- qDebug() << "";
- qDebug() << "Available Time Zones with UTC Offset 0";
- qDebug() << QTimeZone::availableTimeZoneIds(0);
- qDebug() << "";
- } else {
- //Just test the calls work, we cannot know what any test machine has available
- QList<QByteArray> listAll = QTimeZone::availableTimeZoneIds();
- QList<QByteArray> listUs = QTimeZone::availableTimeZoneIds(QLocale::UnitedStates);
- QList<QByteArray> listZero = QTimeZone::availableTimeZoneIds(0);
- }
-}
-
-void tst_QTimeZone::stressTest()
-{
- QList<QByteArray> idList = QTimeZone::availableTimeZoneIds();
- foreach (const QByteArray &id, idList) {
- QTimeZone testZone = QTimeZone(id);
- QCOMPARE(testZone.isValid(), true);
- QCOMPARE(testZone.id(), id);
- QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0, 0), Qt::UTC);
- testZone.country();
- testZone.comment();
- testZone.displayName(testDate);
- testZone.displayName(QTimeZone::DaylightTime);
- testZone.displayName(QTimeZone::StandardTime);
- testZone.abbreviation(testDate);
- testZone.offsetFromUtc(testDate);
- testZone.standardTimeOffset(testDate);
- testZone.daylightTimeOffset(testDate);
- testZone.hasDaylightTime();
- testZone.isDaylightTime(testDate);
- testZone.offsetData(testDate);
- testZone.hasTransitions();
- testZone.nextTransition(testDate);
- testZone.previousTransition(testDate);
- // Dates known to be outside possible tz file pre-calculated rules range
- QDateTime lowDate1 = QDateTime(QDate(1800, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime lowDate2 = QDateTime(QDate(1800, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime highDate1 = QDateTime(QDate(2200, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime highDate2 = QDateTime(QDate(2200, 6, 1), QTime(0, 0, 0), Qt::UTC);
- testZone.nextTransition(lowDate1);
- testZone.nextTransition(lowDate2);
- testZone.previousTransition(lowDate2);
- testZone.previousTransition(lowDate2);
- testZone.nextTransition(highDate1);
- testZone.nextTransition(highDate2);
- testZone.previousTransition(highDate1);
- testZone.previousTransition(highDate2);
- if (debug) {
- // This could take a long time, depending on platform and database
- qDebug() << "Stress test calculating transistions for" << testZone.id();
- testZone.transitions(lowDate1, highDate1);
- }
- testDate.setTimeZone(testZone);
- testDate.isValid();
- testDate.offsetFromUtc();
- testDate.timeZoneAbbreviation();
- }
-}
-
-void tst_QTimeZone::windowsId()
-{
-/*
- Current Windows zones for "Central Standard Time":
- Region IANA Id(s)
- Default "America/Chicago"
- Canada "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute"
- Mexico "America/Matamoros"
- USA "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee"
- "America/North_Dakota/Beulah America/North_Dakota/Center"
- "America/North_Dakota/New_Salem"
- AnyCountry "CST6CDT"
-*/
- QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chicago"),
- QByteArray("Central Standard Time"));
- QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Resolute"),
- QByteArray("Central Standard Time"));
-
- // Partials shouldn't match
- QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chi"), QByteArray());
- QCOMPARE(QTimeZone::ianaIdToWindowsId("InvalidZone"), QByteArray());
- QCOMPARE(QTimeZone::ianaIdToWindowsId(QByteArray()), QByteArray());
-
- // Check default value
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time"),
- QByteArray("America/Chicago"));
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::Canada),
- QByteArray("America/Winnipeg"));
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::AnyCountry),
- QByteArray("CST6CDT"));
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId(QByteArray()), QByteArray());
-
- // No country is sorted list of all zones
- QList<QByteArray> list;
- list << "America/Chicago" << "America/Indiana/Knox" << "America/Indiana/Tell_City"
- << "America/Matamoros" << "America/Menominee" << "America/North_Dakota/Beulah"
- << "America/North_Dakota/Center" << "America/North_Dakota/New_Salem"
- << "America/Rainy_River" << "America/Rankin_Inlet" << "America/Resolute"
- << "America/Winnipeg" << "CST6CDT";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time"), list);
-
- // Check country with no match returns empty list
- list.clear();
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::NewZealand),
- list);
-
- // Check valid country returns list in preference order
- list.clear();
- list << "America/Winnipeg" << "America/Rainy_River" << "America/Rankin_Inlet"
- << "America/Resolute";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Canada), list);
-
- list.clear();
- list << "America/Matamoros";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Mexico), list);
-
- list.clear();
- list << "America/Chicago" << "America/Indiana/Knox" << "America/Indiana/Tell_City"
- << "America/Menominee" << "America/North_Dakota/Beulah" << "America/North_Dakota/Center"
- << "America/North_Dakota/New_Salem";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::UnitedStates),
- list);
-
- list.clear();
- list << "CST6CDT";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::AnyCountry),
- list);
-
- // Check no windowsId return empty
- list.clear();
- QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray()), list);
- QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray(), QLocale::AnyCountry), list);
-}
-
-void tst_QTimeZone::isValidId_data()
-{
-#ifdef QT_BUILD_INTERNAL
- QTest::addColumn<QByteArray>("input");
- QTest::addColumn<bool>("valid");
-
-#define TESTSET(name, section, valid) \
- QTest::newRow(name " front") << QByteArray(section "/xyz/xyz") << valid; \
- QTest::newRow(name " middle") << QByteArray("xyz/" section "/xyz") << valid; \
- QTest::newRow(name " back") << QByteArray("xyz/xyz/" section) << valid
-
- TESTSET("empty", "", false);
- TESTSET("minimal", "m", true);
- TESTSET("maximal", "12345678901234", true);
- TESTSET("too long", "123456789012345", false);
-
- TESTSET("bad hyphen", "-hyphen", false);
- TESTSET("good hyphen", "hy-phen", true);
-
- TESTSET("valid char _", "_", true);
- TESTSET("valid char .", ".", true);
- TESTSET("valid char :", ":", true);
- TESTSET("valid char +", "+", true);
- TESTSET("valid char A", "A", true);
- TESTSET("valid char Z", "Z", true);
- TESTSET("valid char a", "a", true);
- TESTSET("valid char z", "z", true);
- TESTSET("valid char 0", "0", true);
- TESTSET("valid char 9", "9", true);
-
- TESTSET("invalid char ^", "^", false);
- TESTSET("invalid char \"", "\"", false);
- TESTSET("invalid char $", "$", false);
- TESTSET("invalid char %", "%", false);
- TESTSET("invalid char &", "&", false);
- TESTSET("invalid char (", "(", false);
- TESTSET("invalid char )", ")", false);
- TESTSET("invalid char =", "=", false);
- TESTSET("invalid char ?", "?", false);
- TESTSET("invalid char ß", "ß", false);
- TESTSET("invalid char \\x01", "\x01", false);
- TESTSET("invalid char ' '", " ", false);
-
-#undef TESTSET
-#endif // QT_BUILD_INTERNAL
-}
-
-void tst_QTimeZone::isValidId()
-{
-#ifdef QT_BUILD_INTERNAL
- QFETCH(QByteArray, input);
- QFETCH(bool, valid);
-
- QCOMPARE(QTimeZonePrivate::isValidId(input), valid);
-#else
- QSKIP("This test requires a Qt -developer-build.");
-#endif
-}
-
-void tst_QTimeZone::utcTest()
-{
-#ifdef QT_BUILD_INTERNAL
- // Test default UTC constructor
- QUtcTimeZonePrivate tzp;
- QCOMPARE(tzp.isValid(), true);
- QCOMPARE(tzp.id(), QByteArray("UTC"));
- QCOMPARE(tzp.country(), QLocale::AnyCountry);
- QCOMPARE(tzp.abbreviation(0), QString("UTC"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QString()), QString("UTC"));
- QCOMPARE(tzp.offsetFromUtc(0), 0);
- QCOMPARE(tzp.standardTimeOffset(0), 0);
- QCOMPARE(tzp.daylightTimeOffset(0), 0);
- QCOMPARE(tzp.hasDaylightTime(), false);
- QCOMPARE(tzp.hasTransitions(), false);
-
- // Test create from UTC Offset
- QDateTime now = QDateTime::currentDateTime();
- QTimeZone tz(36000);
- QCOMPARE(tz.isValid(), true);
- QCOMPARE(tz.id(), QByteArray("UTC+10:00"));
- QCOMPARE(tz.offsetFromUtc(now), 36000);
- QCOMPARE(tz.standardTimeOffset(now), 36000);
- QCOMPARE(tz.daylightTimeOffset(now), 0);
-
- // Test invalid UTC offset, must be in range -14 to +14 hours
- int min = -14*60*60;
- int max = 14*60*60;
- QCOMPARE(QTimeZone(min - 1).isValid(), false);
- QCOMPARE(QTimeZone(min).isValid(), true);
- QCOMPARE(QTimeZone(min + 1).isValid(), true);
- QCOMPARE(QTimeZone(max - 1).isValid(), true);
- QCOMPARE(QTimeZone(max).isValid(), true);
- QCOMPARE(QTimeZone(max + 1).isValid(), false);
-
- // Test create from standard name
- tz = QTimeZone("UTC+10:00");
- QCOMPARE(tz.isValid(), true);
- QCOMPARE(tz.id(), QByteArray("UTC+10:00"));
- QCOMPARE(tz.offsetFromUtc(now), 36000);
- QCOMPARE(tz.standardTimeOffset(now), 36000);
- QCOMPARE(tz.daylightTimeOffset(now), 0);
-
- // Test invalid UTC ID, must be in available list
- tz = QTimeZone("UTC+00:01");
- QCOMPARE(tz.isValid(), false);
-
- // Test create custom zone
- tz = QTimeZone("QST", 123456, "Qt Standard Time", "QST", QLocale::Norway, "Qt Testing");
- QCOMPARE(tz.isValid(), true);
- QCOMPARE(tz.id(), QByteArray("QST"));
- QCOMPARE(tz.comment(), QString("Qt Testing"));
- QCOMPARE(tz.country(), QLocale::Norway);
- QCOMPARE(tz.abbreviation(now), QString("QST"));
- QCOMPARE(tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QString()),
- QString("Qt Standard Time"));
- QCOMPARE(tz.offsetFromUtc(now), 123456);
- QCOMPARE(tz.standardTimeOffset(now), 123456);
- QCOMPARE(tz.daylightTimeOffset(now), 0);
-#endif // QT_BUILD_INTERNAL
-}
-
-void tst_QTimeZone::icuTest()
-{
-#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu)
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QIcuTimeZonePrivate tzpd;
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QIcuTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QIcuTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Only test names in debug mode, names used can vary by ICU version installed
- if (debug) {
- // Test display names by type
- QLocale enUS("en_US");
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("Central European Summer Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("GMT+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- // ICU C api does not support Generic Time yet, C++ api does
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("CET"));
- QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QIcuTimeZonePrivate("America/Toronto"));
-#endif // icu
-}
-
-void tst_QTimeZone::tzTest()
-{
-#if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QTzTimeZonePrivate tzpd;
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QTzTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QTzTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Test display names by type, either ICU or abbreviation only
- QLocale enUS("en_US");
- // Only test names in debug mode, names used can vary by ICU version installed
- if (debug) {
-#if QT_CONFIG(icu)
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("Central European Summer Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("GMT+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- // ICU C api does not support Generic Time yet, C++ api does
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-#else
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("CEST"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("CEST"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("CEST"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("CET"));
-#endif // icu
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("CET"));
- QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QTzTimeZonePrivate("America/Toronto"));
-
- // Test first and last transition rule
- // Warning: This could vary depending on age of TZ file!
-
- // Test low date uses first rule found
- // Note: Depending on the OS in question, the database may be carrying the
- // Local Mean Time. which for Berlin is 0:53:28
- QTimeZonePrivate::Data dat = tzp.data(-9999999999999);
- QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-9999999999999);
- QCOMPARE(dat.daylightTimeOffset, 0);
- if (dat.abbreviation == "LMT") {
- QCOMPARE(dat.standardTimeOffset, 3208);
- } else {
- QCOMPARE(dat.standardTimeOffset, 3600);
-
- // Test previous to low value is invalid
- dat = tzp.previousTransition(-9999999999999);
- QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
- QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
- }
-
- dat = tzp.nextTransition(-9999999999999);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(1893, 4, 1), QTime(0, 6, 32), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- // Known high datetimes
- qint64 stdHi = QDateTime(QDate(2100, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dstHi = QDateTime(QDate(2100, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Tets high dates use the POSIX rule
- dat = tzp.data(stdHi);
- QCOMPARE(dat.atMSecsSinceEpoch - stdHi, (qint64)0);
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- dat = tzp.data(dstHi);
- QCOMPARE(dat.atMSecsSinceEpoch - dstHi, (qint64)0);
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
-
- dat = tzp.previousTransition(stdHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2099, 10, 26), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- dat = tzp.previousTransition(dstHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2100, 3, 29), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
-
- dat = tzp.nextTransition(stdHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2100, 3, 29), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
-
- dat = tzp.nextTransition(dstHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2100, 10, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- // Test TZ timezone vs UTC timezone for fractionary negative offset
- QTzTimeZonePrivate tztz1("America/Caracas");
- QUtcTimeZonePrivate tzutc1("UTC-04:30");
- QVERIFY(tztz1.isValid());
- QVERIFY(tzutc1.isValid());
- QTzTimeZonePrivate::Data datatz1 = tztz1.data(std);
- QTzTimeZonePrivate::Data datautc1 = tzutc1.data(std);
- QCOMPARE(datatz1.offsetFromUtc, datautc1.offsetFromUtc);
-
- // Test TZ timezone vs UTC timezone for fractionary positive offset
- QTzTimeZonePrivate tztz2("Asia/Calcutta");
- QUtcTimeZonePrivate tzutc2("UTC+05:30");
- QVERIFY(tztz2.isValid());
- QVERIFY(tzutc2.isValid());
- QTzTimeZonePrivate::Data datatz2 = tztz2.data(std);
- QTzTimeZonePrivate::Data datautc2 = tzutc2.data(std);
- QCOMPARE(datatz2.offsetFromUtc, datautc2.offsetFromUtc);
-
- // Test a timezone with a name that isn't all letters
- QTzTimeZonePrivate tzBarnaul("Asia/Barnaul");
- if (tzBarnaul.isValid()) {
- QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07"));
-
- // first full day of the new rule (tzdata2016b)
- QDateTime dt(QDate(2016, 3, 28), QTime(0, 0, 0), Qt::UTC);
- QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07"));
- }
-#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN
-}
-
-void tst_QTimeZone::macTest()
-{
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_DARWIN)
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QMacTimeZonePrivate tzpd;
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QMacTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QMacTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Only test names in debug mode, names used can vary by version
- if (debug) {
- // Test display names by type
- QLocale enUS("en_US");
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("Central European Summer Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("GMT+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- // ICU C api does not support Generic Time yet, C++ api does
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("Central European Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("Germany Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("CET"));
- QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QMacTimeZonePrivate("America/Toronto"));
-#endif // QT_BUILD_INTERNAL && Q_OS_DARWIN
-}
-
-void tst_QTimeZone::darwinTypes()
-{
-#ifndef Q_OS_DARWIN
- QSKIP("This is an Apple-only test");
-#else
- extern void tst_QTimeZone_darwinTypes(); // in tst_qtimezone_darwin.mm
- tst_QTimeZone_darwinTypes();
-#endif
-}
-
-void tst_QTimeZone::winTest()
-{
-#if defined(QT_BUILD_INTERNAL) && defined(USING_WIN_TZ)
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QWinTimeZonePrivate tzpd;
- if (debug)
- qDebug() << "System ID = " << tzpd.id()
- << tzpd.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QLocale())
- << tzpd.displayName(QTimeZone::GenericTime, QTimeZone::LongName, QLocale());
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QWinTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QWinTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Only test names in debug mode, names used can vary by version
- if (debug) {
- // Test display names by type
- QLocale enUS("en_US");
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("W. Europe Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("W. Europe Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("W. Europe Daylight Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("W. Europe Daylight Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("W. Europe Standard Time"));
- QCOMPARE(tzp.abbreviation(dst), QString("W. Europe Daylight Time"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QWinTimeZonePrivate("America/Toronto"));
-#endif // QT_BUILD_INTERNAL && USING_WIN_TZ
-}
-
-#ifdef QT_BUILD_INTERNAL
-// Test each private produces the same basic results for CET
-void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
-{
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 prev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- QCOMPARE(tzp.offsetFromUtc(std), 3600);
- QCOMPARE(tzp.offsetFromUtc(dst), 7200);
-
- QCOMPARE(tzp.standardTimeOffset(std), 3600);
- QCOMPARE(tzp.standardTimeOffset(dst), 3600);
-
- QCOMPARE(tzp.daylightTimeOffset(std), 0);
- QCOMPARE(tzp.daylightTimeOffset(dst), 3600);
-
- QCOMPARE(tzp.hasDaylightTime(), true);
- QCOMPARE(tzp.isDaylightTime(std), false);
- QCOMPARE(tzp.isDaylightTime(dst), true);
-
- QTimeZonePrivate::Data dat = tzp.data(std);
- QCOMPARE(dat.atMSecsSinceEpoch, std);
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
- QCOMPARE(dat.abbreviation, tzp.abbreviation(std));
-
- dat = tzp.data(dst);
- QCOMPARE(dat.atMSecsSinceEpoch, dst);
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
- QCOMPARE(dat.abbreviation, tzp.abbreviation(dst));
-
- // Only test transitions if host system supports them
- if (tzp.hasTransitions()) {
- QTimeZonePrivate::Data tran = tzp.nextTransition(std);
- // 2012-03-25 02:00 CET, +1 -> +2
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2012, 3, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(tran.offsetFromUtc, 7200);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- tran = tzp.nextTransition(dst);
- // 2012-10-28 03:00 CEST, +2 -> +1
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2012, 10, 28), QTime(3, 0), Qt::OffsetFromUTC, 2 * 3600));
- QCOMPARE(tran.offsetFromUtc, 3600);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- tran = tzp.previousTransition(std);
- // 2011-10-30 03:00 CEST, +2 -> +1
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2011, 10, 30), QTime(3, 0), Qt::OffsetFromUTC, 2 * 3600));
- QCOMPARE(tran.offsetFromUtc, 3600);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- tran = tzp.previousTransition(dst);
- // 2012-03-25 02:00 CET, +1 -> +2 (again)
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2012, 3, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(tran.offsetFromUtc, 7200);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- QTimeZonePrivate::DataList expected;
- // 2011-03-27 02:00 CET, +1 -> +2
- tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 3, 27), QTime(2, 0),
- Qt::OffsetFromUTC, 3600).toMSecsSinceEpoch();
- tran.offsetFromUtc = 7200;
- tran.standardTimeOffset = 3600;
- tran.daylightTimeOffset = 3600;
- expected << tran;
- // 2011-10-30 03:00 CEST, +2 -> +1
- tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 10, 30), QTime(3, 0),
- Qt::OffsetFromUTC, 2 * 3600).toMSecsSinceEpoch();
- tran.offsetFromUtc = 3600;
- tran.standardTimeOffset = 3600;
- tran.daylightTimeOffset = 0;
- expected << tran;
- QTimeZonePrivate::DataList result = tzp.transitions(prev, std);
- QCOMPARE(result.count(), expected.count());
- for (int i = 0; i < expected.count(); ++i) {
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(result.at(i).atMSecsSinceEpoch,
- Qt::OffsetFromUTC, 3600),
- QDateTime::fromMSecsSinceEpoch(expected.at(i).atMSecsSinceEpoch,
- Qt::OffsetFromUTC, 3600));
- QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
- QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
- QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
- }
- }
-}
-
-// Needs a zone with DST around the epoch; currently America/Toronto (EST5EDT)
-void tst_QTimeZone::testEpochTranPrivate(const QTimeZonePrivate &tzp)
-{
- if (!tzp.hasTransitions())
- return; // test only viable for transitions
-
- QTimeZonePrivate::Data tran = tzp.nextTransition(0); // i.e. first after epoch
- // 1970-04-26 02:00 EST, -5 -> -4
- const QDateTime after = QDateTime(QDate(1970, 4, 26), QTime(2, 0), Qt::OffsetFromUTC, -5 * 3600);
- const QDateTime found = QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC);
-#ifdef USING_WIN_TZ // MS gets the date wrong: 5th April instead of 26th.
- QCOMPARE(found.toOffsetFromUtc(-5 * 3600).time(), after.time());
-#else
- QCOMPARE(found, after);
-#endif
- QCOMPARE(tran.offsetFromUtc, -4 * 3600);
- QCOMPARE(tran.standardTimeOffset, -5 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- // Pre-epoch time-zones might not be supported at all:
- tran = tzp.nextTransition(QDateTime(QDate(1601, 1, 1), QTime(0, 0),
- Qt::UTC).toMSecsSinceEpoch());
- if (tran.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs()
- // Toronto *did* have a transition before 1970 (DST since 1918):
- && tran.atMSecsSinceEpoch < 0) {
- // ... but, if they are, we should be able to search back to them:
- tran = tzp.previousTransition(0); // i.e. last before epoch
- // 1969-10-26 02:00 EDT, -4 -> -5
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(1969, 10, 26), QTime(2, 0), Qt::OffsetFromUTC, -4 * 3600));
- QCOMPARE(tran.offsetFromUtc, -5 * 3600);
- QCOMPARE(tran.standardTimeOffset, -5 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
- } else {
- // Do not use QSKIP(): that would discard the rest of this sub-test's caller.
- qDebug() << "No support for pre-epoch time-zone transitions";
- }
-}
-#endif // QT_BUILD_INTERNAL
-
-QTEST_APPLESS_MAIN(tst_QTimeZone)
-#include "tst_qtimezone.moc"
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm b/tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm
deleted file mode 100644
index de801e55d0..0000000000
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone_darwin.mm
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QTimeZone>
-#include <QtTest/QtTest>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-void tst_QTimeZone_darwinTypes()
-{
-#if !defined(QT_NO_SYSTEMLOCALE)
- // QTimeZone <-> CFTimeZone
- {
- QTimeZone qtTimeZone("America/Los_Angeles");
- const CFTimeZoneRef cfTimeZone = qtTimeZone.toCFTimeZone();
- QCOMPARE(QTimeZone::fromCFTimeZone(cfTimeZone), qtTimeZone);
- CFRelease(cfTimeZone);
- }
- {
- CFTimeZoneRef cfTimeZone = CFTimeZoneCreateWithName(kCFAllocatorDefault,
- CFSTR("America/Los_Angeles"), false);
- const QTimeZone qtTimeZone = QTimeZone::fromCFTimeZone(cfTimeZone);
- QVERIFY(CFEqual(qtTimeZone.toCFTimeZone(), cfTimeZone));
- CFRelease(cfTimeZone);
- }
- // QTimeZone <-> NSTimeZone
- {
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
- QTimeZone qtTimeZone("America/Los_Angeles");
- const NSTimeZone *nsTimeZone = qtTimeZone.toNSTimeZone();
- QCOMPARE(QTimeZone::fromNSTimeZone(nsTimeZone), qtTimeZone);
- [autoreleasepool release];
- }
- {
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
- NSTimeZone *nsTimeZone = [NSTimeZone timeZoneWithName:@"America/Los_Angeles"];
- const QTimeZone qtTimeZone = QTimeZone::fromNSTimeZone(nsTimeZone);
- QVERIFY([qtTimeZone.toNSTimeZone() isEqual:nsTimeZone]);
- [autoreleasepool release];
- }
-#endif
-}
diff --git a/tests/auto/corelib/tools/qtyperevision/CMakeLists.txt b/tests/auto/corelib/tools/qtyperevision/CMakeLists.txt
new file mode 100644
index 0000000000..527156e3c2
--- /dev/null
+++ b/tests/auto/corelib/tools/qtyperevision/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtyperevision LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qtyperevision
+ SOURCES
+ tst_qtyperevision.cpp
+ LIBRARIES
+ Qt::TestPrivate
+)
diff --git a/tests/auto/corelib/tools/qtyperevision/tst_qtyperevision.cpp b/tests/auto/corelib/tools/qtyperevision/tst_qtyperevision.cpp
new file mode 100644
index 0000000000..66c746382a
--- /dev/null
+++ b/tests/auto/corelib/tools/qtyperevision/tst_qtyperevision.cpp
@@ -0,0 +1,202 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QtCore/qtyperevision.h>
+#include <QtTest/private/qcomparisontesthelper_p.h>
+
+using namespace Qt::StringLiterals;
+
+class tst_QTypeRevision : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void qTypeRevision_data();
+ void qTypeRevision();
+ void qTypeRevisionTypes();
+ void qTypeRevisionComparisonCompiles();
+ void qTypeRevisionComparison_data();
+ void qTypeRevisionComparison();
+};
+
+template<typename Integer>
+void compileTestRevisionMajorMinor()
+{
+ const Integer major = 8;
+ const Integer minor = 4;
+
+ const QTypeRevision r2 = QTypeRevision::fromVersion(major, minor);
+ QCOMPARE(r2.majorVersion(), 8);
+ QCOMPARE(r2.minorVersion(), 4);
+
+ const QTypeRevision r3 = QTypeRevision::fromMajorVersion(major);
+ QCOMPARE(r3.majorVersion(), 8);
+ QVERIFY(!r3.hasMinorVersion());
+
+ const QTypeRevision r4 = QTypeRevision::fromMinorVersion(minor);
+ QVERIFY(!r4.hasMajorVersion());
+ QCOMPARE(r4.minorVersion(), 4);
+}
+
+
+template<typename Integer>
+void compileTestRevision()
+{
+ if (std::is_signed<Integer>::value)
+ compileTestRevision<typename QIntegerForSize<sizeof(Integer) / 2>::Signed>();
+ else
+ compileTestRevision<typename QIntegerForSize<sizeof(Integer) / 2>::Unsigned>();
+
+ const Integer value = 0x0510;
+ const QTypeRevision r = QTypeRevision::fromEncodedVersion(value);
+
+ QCOMPARE(r.majorVersion(), 5);
+ QCOMPARE(r.minorVersion(), 16);
+ QCOMPARE(r.toEncodedVersion<Integer>(), value);
+
+ compileTestRevisionMajorMinor<Integer>();
+}
+
+template<>
+void compileTestRevision<qint16>()
+{
+ compileTestRevisionMajorMinor<quint8>();
+}
+
+template<>
+void compileTestRevision<quint8>()
+{
+ compileTestRevisionMajorMinor<quint8>();
+}
+
+template<>
+void compileTestRevision<qint8>()
+{
+ compileTestRevisionMajorMinor<qint8>();
+}
+
+void tst_QTypeRevision::qTypeRevision_data()
+{
+ QTest::addColumn<QTypeRevision>("revision");
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<int>("major");
+ QTest::addColumn<int>("minor");
+
+ QTest::addRow("Qt revision") << QTypeRevision::fromVersion(QT_VERSION_MAJOR, QT_VERSION_MINOR)
+ << true << QT_VERSION_MAJOR << QT_VERSION_MINOR;
+ QTest::addRow("invalid") << QTypeRevision() << false << 0xff << 0xff;
+ QTest::addRow("major") << QTypeRevision::fromMajorVersion(6) << true << 6 << 0xff;
+ QTest::addRow("minor") << QTypeRevision::fromMinorVersion(15) << true << 0xff << 15;
+ QTest::addRow("zero") << QTypeRevision::fromVersion(0, 0) << true << 0 << 0;
+
+ // We're intentionally not testing negative numbers.
+ // There are asserts against negative numbers in QTypeRevision.
+ // You must not pass them as major or minor versions, or values.
+}
+
+void tst_QTypeRevision::qTypeRevision()
+{
+ const QTypeRevision other = QTypeRevision::fromVersion(127, 128);
+
+ QFETCH(QTypeRevision, revision);
+
+ QFETCH(bool, valid);
+ QFETCH(int, major);
+ QFETCH(int, minor);
+
+ QCOMPARE(revision.isValid(), valid);
+ QCOMPARE(revision.majorVersion(), major);
+ QCOMPARE(revision.minorVersion(), minor);
+
+ QCOMPARE(revision.hasMajorVersion(), QTypeRevision::isValidSegment(major));
+ QCOMPARE(revision.hasMinorVersion(), QTypeRevision::isValidSegment(minor));
+
+ const QTypeRevision copy = QTypeRevision::fromEncodedVersion(revision.toEncodedVersion<int>());
+ QCOMPARE(copy, revision);
+
+ QVERIFY(revision != other);
+ QVERIFY(copy != other);
+}
+
+void tst_QTypeRevision::qTypeRevisionTypes()
+{
+ compileTestRevision<quint64>();
+ compileTestRevision<qint64>();
+
+ QVERIFY(!QTypeRevision::isValidSegment(0xff));
+ QVERIFY(!QTypeRevision::isValidSegment(-1));
+
+ const QTypeRevision maxRevision = QTypeRevision::fromVersion(254, 254);
+ QVERIFY(maxRevision.hasMajorVersion());
+ QVERIFY(maxRevision.hasMinorVersion());
+}
+
+void tst_QTypeRevision::qTypeRevisionComparisonCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<QTypeRevision>();
+}
+
+void tst_QTypeRevision::qTypeRevisionComparison_data()
+{
+ QTest::addColumn<QTypeRevision>("lhs");
+ QTest::addColumn<QTypeRevision>("rhs");
+ QTest::addColumn<Qt::strong_ordering>("expectedResult");
+
+ static auto versionStr = [](QTypeRevision r) {
+ QByteArray res = r.hasMajorVersion() ? QByteArray::number(r.majorVersion())
+ : "x"_ba;
+ res.append('.');
+ res.append(r.hasMinorVersion() ? QByteArray::number(r.minorVersion())
+ : "x"_ba);
+ return res;
+ };
+
+ const QTypeRevision revisions[] = {
+ QTypeRevision::zero(),
+ QTypeRevision::fromMajorVersion(0),
+ QTypeRevision::fromVersion(0, 1),
+ QTypeRevision::fromVersion(0, 20),
+ QTypeRevision::fromMinorVersion(0),
+ QTypeRevision(),
+ QTypeRevision::fromMinorVersion(1),
+ QTypeRevision::fromMinorVersion(20),
+ QTypeRevision::fromVersion(1, 0),
+ QTypeRevision::fromMajorVersion(1),
+ QTypeRevision::fromVersion(1, 1),
+ QTypeRevision::fromVersion(1, 20),
+ QTypeRevision::fromVersion(20, 0),
+ QTypeRevision::fromMajorVersion(20),
+ QTypeRevision::fromVersion(20, 1),
+ QTypeRevision::fromVersion(20, 20),
+ };
+
+ const int length = sizeof(revisions) / sizeof(QTypeRevision);
+ for (int i = 0; i < length; ++i) {
+ for (int j = i; j < length; ++j) {
+ const Qt::strong_ordering expectedRes = (i == j)
+ ? Qt::strong_ordering::equal
+ : (i < j) ? Qt::strong_ordering::less
+ : Qt::strong_ordering::greater;
+
+ const auto lhs = revisions[i];
+ const auto rhs = revisions[j];
+ QTest::addRow("%s_vs_%s", versionStr(lhs).constData(), versionStr(rhs).constData())
+ << lhs << rhs << expectedRes;
+ }
+ }
+}
+
+void tst_QTypeRevision::qTypeRevisionComparison()
+{
+ QFETCH(const QTypeRevision, lhs);
+ QFETCH(const QTypeRevision, rhs);
+ QFETCH(const Qt::strong_ordering, expectedResult);
+
+ QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, expectedResult);
+}
+
+QTEST_APPLESS_MAIN(tst_QTypeRevision)
+
+#include "tst_qtyperevision.moc"
diff --git a/tests/auto/corelib/tools/quniquehandle/CMakeLists.txt b/tests/auto/corelib/tools/quniquehandle/CMakeLists.txt
new file mode 100644
index 0000000000..fe46826f37
--- /dev/null
+++ b/tests/auto/corelib/tools/quniquehandle/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_quniquehandle LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_quniquehandle
+ SOURCES
+ tst_quniquehandle.cpp
+ LIBRARIES
+ Qt::CorePrivate
+)
diff --git a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp
new file mode 100644
index 0000000000..ed46999e73
--- /dev/null
+++ b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp
@@ -0,0 +1,308 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <private/quniquehandle_p.h>
+
+#include <QTest>
+
+QT_USE_NAMESPACE;
+
+// clang-format off
+namespace GlobalResource {
+
+std::array<bool, 3> s_resources = { false, false, false };
+
+using handle = size_t;
+constexpr handle s_invalidHandle = static_cast<handle>(-1);
+
+handle open()
+{
+ const auto it = std::find_if(s_resources.begin(), s_resources.end(),
+ [](bool resource) {
+ return !resource;
+ });
+
+ if (it == s_resources.end())
+ return s_invalidHandle;
+
+ *it = true;
+
+ return std::distance(s_resources.begin(), it);
+}
+
+bool open(handle* dest)
+{
+ const handle resource = open();
+
+ if (resource == s_invalidHandle)
+ return false;
+
+ *dest = resource;
+ return true;
+}
+
+bool close(handle h)
+{
+ if (h >= s_resources.size())
+ return false; // Invalid handle
+
+ if (!s_resources[h])
+ return false; // Un-allocated resource
+
+ s_resources[h] = false;
+ return true;
+}
+
+bool isOpen(handle h)
+{
+ return s_resources[h];
+}
+
+void reset()
+{
+ std::fill(s_resources.begin(), s_resources.end(), false);
+}
+
+bool isReset()
+{
+ return std::all_of(s_resources.begin(), s_resources.end(), [](bool res) {
+ return !res;
+ });
+}
+
+} // namespace GlobalResource
+
+struct TestTraits
+{
+ using Type = GlobalResource::handle;
+
+ static bool close(Type handle)
+ {
+ return GlobalResource::close(handle);
+ }
+
+ static Type invalidValue() noexcept
+ {
+ return GlobalResource::s_invalidHandle;
+ }
+};
+
+using Handle = QUniqueHandle<TestTraits>;
+
+class tst_QUniqueHandle : public QObject
+{
+ Q_OBJECT
+
+private slots:
+
+ void init() const
+ {
+ GlobalResource::reset();
+ }
+
+ void cleanup() const
+ {
+ QVERIFY(GlobalResource::isReset());
+ }
+
+ void defaultConstructor_initializesToInvalidHandle() const
+ {
+ const Handle h;
+ QCOMPARE_EQ(h.get(), TestTraits::invalidValue());
+ }
+
+ void constructor_initializesToValid_whenCalledWithValidHandle() const
+ {
+ const auto res = GlobalResource::open();
+
+ const Handle h{ res };
+
+ QCOMPARE_EQ(h.get(), res);
+ }
+
+ void copyConstructor_and_assignmentOperator_areDeleted() const
+ {
+ static_assert(!std::is_copy_constructible_v<Handle> && !std::is_copy_assignable_v<Handle>);
+ }
+
+ void moveConstructor_movesOwnershipAndResetsSource() const
+ {
+ Handle source{ GlobalResource::open() };
+ const Handle dest{ std::move(source) };
+
+ QVERIFY(!source.isValid());
+ QVERIFY(dest.isValid());
+ QVERIFY(GlobalResource::isOpen(dest.get()));
+ }
+
+ void moveAssignment_movesOwnershipAndResetsSource() const
+ {
+ Handle source{ GlobalResource::open() };
+ Handle dest;
+ dest = { std::move(source) };
+
+ QVERIFY(!source.isValid());
+ QVERIFY(dest.isValid());
+ QVERIFY(GlobalResource::isOpen(dest.get()));
+ }
+
+ void isValid_returnsFalse_onlyWhenHandleIsInvalid() const
+ {
+ const Handle invalid;
+ QVERIFY(!invalid.isValid());
+
+ const Handle valid{ GlobalResource::open() };
+ QVERIFY(valid.isValid());
+ }
+
+ void destructor_callsClose_whenHandleIsValid()
+ {
+ {
+ const Handle h0{ GlobalResource::open() };
+ const Handle h1{ GlobalResource::open() };
+ const Handle h2{ GlobalResource::open() };
+ QVERIFY(!GlobalResource::isReset());
+ }
+
+ QVERIFY(GlobalResource::isReset());
+ }
+
+ void operatorBool_returnsFalse_onlyWhenHandleIsInvalid() const
+ {
+ const Handle invalid;
+ QVERIFY(!invalid);
+
+ const Handle valid{ GlobalResource::open() };
+ QVERIFY(valid);
+ }
+
+ void get_returnsValue() const
+ {
+ const Handle invalid;
+ QCOMPARE_EQ(invalid.get(), GlobalResource::s_invalidHandle);
+
+ const auto resource = GlobalResource::open();
+ const Handle valid{ resource };
+ QCOMPARE_EQ(valid.get(), resource);
+ }
+
+ void reset_resetsPreviousValueAndTakesOwnership() const
+ {
+ const auto resource0 = GlobalResource::open();
+ const auto resource1 = GlobalResource::open();
+
+ Handle h1{ resource0 };
+ h1.reset(resource1);
+
+ QVERIFY(!GlobalResource::isOpen(resource0));
+ QVERIFY(GlobalResource::isOpen(resource1));
+ }
+
+ void release_returnsInvalidResource_whenCalledOnInvalidHandle() const
+ {
+ Handle h;
+ QCOMPARE_EQ(h.release(), GlobalResource::s_invalidHandle);
+ }
+
+ void release_releasesOwnershipAndReturnsResource_whenHandleOwnsObject() const
+ {
+ GlobalResource::handle resource{ GlobalResource::open() };
+ GlobalResource::handle released{};
+ {
+ Handle h{ resource };
+ released = h.release();
+ }
+ QVERIFY(GlobalResource::isOpen(resource));
+ QCOMPARE_EQ(resource, released);
+
+ GlobalResource::close(resource);
+ }
+
+ void swap_swapsOwnership() const
+ {
+ const auto resource0 = GlobalResource::open();
+ const auto resource1 = GlobalResource::open();
+
+ Handle h0{ resource0 };
+ Handle h1{ resource1 };
+
+ std::swap(h0, h1);
+
+ QCOMPARE_EQ(h0.get(), resource1);
+ QCOMPARE_EQ(h1.get(), resource0);
+ }
+
+ void comparison_behavesAsInt_whenHandleTypeIsInt_data() const
+ {
+ QTest::addColumn<int>("lhs");
+ QTest::addColumn<int>("rhs");
+
+ QTest::addRow("lhs == rhs") << 1 << 1;
+ QTest::addRow("lhs < rhs") << 0 << 1;
+ QTest::addRow("lhs > rhs") << 1 << 0;
+ }
+
+ void comparison_behavesAsInt_whenHandleTypeIsInt() const
+ {
+ struct IntTraits
+ {
+ using Type = int;
+
+ static bool close(Type)
+ {
+ return true;
+ }
+
+ static Type invalidValue() noexcept
+ {
+ return INT_MAX;
+ }
+ };
+
+ using Handle = QUniqueHandle<IntTraits>;
+
+ QFETCH(int, lhs);
+ QFETCH(int, rhs);
+
+ QCOMPARE_EQ(Handle{ lhs } == Handle{ rhs }, lhs == rhs);
+ QCOMPARE_EQ(Handle{ lhs } != Handle{ rhs }, lhs != rhs);
+ QCOMPARE_EQ(Handle{ lhs } < Handle{ rhs }, lhs < rhs);
+ QCOMPARE_EQ(Handle{ lhs } <= Handle{ rhs }, lhs <= rhs);
+ QCOMPARE_EQ(Handle{ lhs } > Handle{ rhs }, lhs > rhs);
+ QCOMPARE_EQ(Handle{ lhs } >= Handle{ rhs }, lhs >= rhs);
+
+ QCOMPARE_EQ(Handle{ }, Handle{ });
+ }
+
+ void sort_sortsHandles() const
+ {
+ const auto resource0 = GlobalResource::open();
+ const auto resource1 = GlobalResource::open();
+
+ QVERIFY(resource1 > resource0); // Precondition of underlying allocator
+
+ Handle h0{ resource0 };
+ Handle h1{ resource1 };
+
+ std::vector<Handle> handles;
+ handles.push_back(std::move(h1));
+ handles.push_back(std::move(h0));
+
+ std::sort(handles.begin(), handles.end());
+
+ QCOMPARE_LT(handles.front(), handles.back());
+ QCOMPARE_LT(handles.front().get(), handles.back().get());
+ }
+
+ void addressOf_returnsAddressOfHandle() const
+ {
+ Handle h;
+ QVERIFY(GlobalResource::open(&h));
+ QVERIFY(h.isValid());
+ }
+
+};
+
+// clang-format on
+QTEST_MAIN(tst_QUniqueHandle)
+#include "tst_quniquehandle.moc"
diff --git a/tests/auto/corelib/tools/qvarlengtharray/CMakeLists.txt b/tests/auto/corelib/tools/qvarlengtharray/CMakeLists.txt
new file mode 100644
index 0000000000..eccb2634cc
--- /dev/null
+++ b/tests/auto/corelib/tools/qvarlengtharray/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qvarlengtharray Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qvarlengtharray LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qvarlengtharray
+ SOURCES
+ tst_qvarlengtharray.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/tools/qvarlengtharray/qvarlengtharray.pro b/tests/auto/corelib/tools/qvarlengtharray/qvarlengtharray.pro
deleted file mode 100644
index 108fb33db5..0000000000
--- a/tests/auto/corelib/tools/qvarlengtharray/qvarlengtharray.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qvarlengtharray
-QT = core testlib
-SOURCES = tst_qvarlengtharray.cpp
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index 5737db760c..6a92663bc4 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -1,49 +1,95 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qvarlengtharray.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QtTest/QTest>
+#include <QVarLengthArray>
#include <qvariant.h>
+#include <qscopeguard.h>
+#include <qscopedvaluerollback.h>
+#include <algorithm>
+#include <q20iterator.h>
#include <memory>
+struct Tracker
+{
+ static int count;
+ Tracker() { ++count; }
+ Tracker(const Tracker &) { ++count; }
+ Tracker(Tracker &&) { ++count; }
+
+ Tracker &operator=(const Tracker &) = default;
+ Tracker &operator=(Tracker &&) = default;
+
+ ~Tracker() { --count; }
+
+};
+
+int Tracker::count = 0;
+
+template <typename T>
+class ValueTracker
+{
+ Tracker m_tracker;
+public:
+ ValueTracker() = default;
+ ValueTracker(T value) : value{std::move(value)} {}
+ T value;
+
+ friend bool operator==(const ValueTracker &lhs, const ValueTracker &rhs) noexcept
+ { return lhs.value == rhs.value; }
+ friend bool operator!=(const ValueTracker &lhs, const ValueTracker &rhs) noexcept
+ { return !operator==(lhs, rhs); }
+};
+
+class NonCopyable
+{
+ Q_DISABLE_COPY(NonCopyable)
+ int n;
+public:
+ NonCopyable() : n(0) {}
+ explicit NonCopyable(int n) : n(n) {}
+
+ friend bool operator==(const NonCopyable &lhs, const NonCopyable &rhs) noexcept
+ { return lhs.n == rhs.n; }
+ friend bool operator!=(const NonCopyable &lhs, const NonCopyable &rhs) noexcept
+ { return !operator==(lhs, rhs); }
+};
+
class tst_QVarLengthArray : public QObject
{
Q_OBJECT
private slots:
+ void defaultConstructor_int() { defaultConstructor<int>(); }
+ void defaultConstructor_QString() { defaultConstructor<QString>(); }
+ void sizeConstructor_int() { sizeConstructor<int>(); }
+ void sizeConstructor_QString() { sizeConstructor<QString>(); }
+ void sizeConstructor_NonCopyable() { sizeConstructor<NonCopyable>(); }
void append();
+ void preallocatedSize();
+#if QT_DEPRECATED_SINCE(6, 3)
+ void prepend();
+#endif
+ void emplace();
+ void move_int_1() { move_int<1>(); }
+ void move_int_2() { move_int<2>(); }
+ void move_int_3() { move_int<3>(); }
+ void move_QString_1() { move_QString<1>(); }
+ void move_QString_2() { move_QString<2>(); }
+ void move_QString_3() { move_QString<3>(); }
+ void move_Tracker_1() { move_Tracker<1>(); }
+ void move_Tracker_2() { move_Tracker<2>(); }
+ void move_Tracker_3() { move_Tracker<3>(); }
void removeLast();
void oldTests();
void appendCausingRealloc();
+ void appendIsStronglyExceptionSafe();
void resize();
void realloc();
+ void iterators();
void reverseIterators();
void count();
+ void cpp17ctad();
void first();
void last();
void squeeze();
@@ -57,26 +103,75 @@ private slots:
void initializeListComplex();
void insertMove();
void nonCopyable();
-
+ void implicitDefaultCtor();
+ void reserve();
+ void value();
+ void insert();
+ void insert_data();
+ void replace();
+ void remove();
+ void erase();
+
+ // special cases:
+ void copesWithCopyabilityOfMoveOnlyVector(); // QTBUG-109745
private:
+ template <typename T>
+ void defaultConstructor();
+ template <typename T>
+ void sizeConstructor();
+ template <qsizetype N, typename T>
+ void move(T t1, T t2);
+ template <qsizetype N>
+ void move_int() { move<N, int>(42, 24); }
+ template <qsizetype N>
+ void move_QString() { move<N, QString>("Hello", "World"); }
+ template <qsizetype N>
+ void move_Tracker();
template<typename T>
void initializeList();
};
-int fooCtor = 0;
-int fooDtor = 0;
-
-struct Foo
+template <typename T>
+void tst_QVarLengthArray::defaultConstructor()
{
- int *p;
-
- Foo() { p = new int; ++fooCtor; }
- Foo(const Foo &/*other*/) { p = new int; ++fooCtor; }
-
- void operator=(const Foo & /* other */) { }
+ {
+ QVarLengthArray<T, 123> vla;
+ QCOMPARE(vla.size(), 0);
+ QVERIFY(vla.empty());
+ QVERIFY(vla.isEmpty());
+ QCOMPARE(vla.begin(), vla.end());
+ QCOMPARE(vla.capacity(), 123);
+ }
+ {
+ QVarLengthArray<T> vla;
+ QCOMPARE(vla.capacity(), 256); // notice, should we change the default
+ }
+}
- ~Foo() { delete p; ++fooDtor; }
-};
+template <typename T>
+void tst_QVarLengthArray::sizeConstructor()
+{
+ {
+ QVarLengthArray<T, 123> vla(0);
+ QCOMPARE(vla.size(), 0);
+ QVERIFY(vla.empty());
+ QVERIFY(vla.isEmpty());
+ QCOMPARE(vla.begin(), vla.end());
+ QCOMPARE(vla.capacity(), 123);
+ }
+ {
+ QVarLengthArray<T, 124> vla(124);
+ QCOMPARE(vla.size(), 124);
+ QVERIFY(!vla.empty());
+ QCOMPARE(vla.capacity(), 124);
+ }
+ {
+ QVarLengthArray<T, 124> vla(125);
+ QCOMPARE(vla.size(), 125);
+ QVERIFY(!vla.empty());
+ QCOMPARE_GE(vla.capacity(), 125);
+ }
+}
void tst_QVarLengthArray::append()
{
@@ -100,6 +195,112 @@ void tst_QVarLengthArray::append()
v2.append(5);
}
+void tst_QVarLengthArray::preallocatedSize()
+{
+ // The default is 256:
+ static_assert(QVarLengthArray<int>::PreallocatedSize == 256);
+ // Otherwise, whatever was given as template argument:
+ static_assert(QVarLengthArray<int, 42>::PreallocatedSize == 42);
+ static_assert(QVarLengthArray<int, 1'000'000>::PreallocatedSize == 1'000'000);
+}
+
+#if QT_DEPRECATED_SINCE(6, 3)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+void tst_QVarLengthArray::prepend()
+{
+ QVarLengthArray<QString, 2> v;
+ v.prepend(QString("1"));
+ v.prepend(v.front());
+ QCOMPARE(v.capacity(), 2);
+ // transition from stack to heap
+ v.prepend(v.back());
+ QVERIFY(v.capacity() > 2);
+ QCOMPARE(v.front(), v.back());
+ while (v.size() < v.capacity())
+ v.prepend(v.back());
+ QCOMPARE(v.front(), v.back());
+ QCOMPARE(v.size(), v.capacity());
+ // transition from heap to larger heap:
+ v.prepend(v.back());
+ QCOMPARE(v.front(), v.back());
+}
+QT_WARNING_POP
+#endif // QT_DEPRECATED_SINCE(6, 3)
+
+void tst_QVarLengthArray::emplace()
+{
+ {
+ QVarLengthArray<QString, 2> strings;
+ strings.emplace_back();
+ QCOMPARE(strings.size(), 1);
+ QCOMPARE(strings.front().isNull(), true);
+ strings.emplace(strings.begin(), 42, u'x');
+ QCOMPARE(strings.size(), 2);
+ QCOMPARE(strings.back().isNull(), true);
+ QCOMPARE(strings.front(), QString(42, u'x'));
+ auto &r = strings.emplace_back(42, u'y');
+ QCOMPARE(&r, &strings.back());
+ QCOMPARE(strings.size(), 3);
+ QCOMPARE(strings.back(), QString(42, u'y'));
+
+ // test growing from empty arrays
+ QVarLengthArray<QString> emptyArrDefaultPrealloc;
+ QCOMPARE(emptyArrDefaultPrealloc.size(), 0);
+ emptyArrDefaultPrealloc.emplace_back();
+ QCOMPARE(emptyArrDefaultPrealloc.size(), 1);
+ emptyArrDefaultPrealloc.resize(1024);
+ QCOMPARE(emptyArrDefaultPrealloc.size(), 1024);
+ emptyArrDefaultPrealloc.resize(0);
+ QCOMPARE(emptyArrDefaultPrealloc.size(), 0);
+ emptyArrDefaultPrealloc.squeeze();
+ QCOMPARE(emptyArrDefaultPrealloc.size(), 0);
+ emptyArrDefaultPrealloc.emplace_back();
+ QCOMPARE(emptyArrDefaultPrealloc.size(), 1);
+
+ QVarLengthArray<QString, 1> emptyArrSmallPrealloc;
+ QCOMPARE(emptyArrSmallPrealloc.size(), 0);
+ emptyArrSmallPrealloc.emplace_back();
+ QCOMPARE(emptyArrSmallPrealloc.size(), 1);
+ emptyArrSmallPrealloc.resize(1024);
+ QCOMPARE(emptyArrSmallPrealloc.size(), 1024);
+ emptyArrSmallPrealloc.resize(0);
+ QCOMPARE(emptyArrSmallPrealloc.size(), 0);
+ emptyArrSmallPrealloc.squeeze();
+ QCOMPARE(emptyArrSmallPrealloc.size(), 0);
+ emptyArrSmallPrealloc.emplace_back();
+ QCOMPARE(emptyArrSmallPrealloc.size(), 1);
+ }
+}
+
+template <qsizetype N>
+void tst_QVarLengthArray::move_Tracker()
+{
+ const auto reset = qScopeGuard([] { Tracker::count = 0; });
+ move<N, ValueTracker<int>>({24}, {24});
+ QCOMPARE(Tracker::count, 0);
+}
+
+template <qsizetype N, typename T>
+void tst_QVarLengthArray::move(T t1, T t2)
+{
+ {
+ QVarLengthArray<T, N> v;
+ v.append(t1);
+ v.append(t2);
+
+ auto moved = std::move(v);
+ QCOMPARE(moved.size(), 2);
+ QCOMPARE(moved[0], t1);
+ QCOMPARE(moved[1], t2);
+
+ v = std::move(moved);
+ QCOMPARE(v.size(), 2);
+ QCOMPARE(v[0], t1);
+ QCOMPARE(v[1], t2);
+ }
+}
+
void tst_QVarLengthArray::removeLast()
{
{
@@ -129,6 +330,23 @@ void tst_QVarLengthArray::removeLast()
v.removeLast();
QCOMPARE(v.size(), 2);
}
+
+ {
+ Tracker t;
+ QCOMPARE(Tracker::count, 1);
+ QVarLengthArray<Tracker, 2> v;
+ v.append(t);
+ v.append({});
+ QCOMPARE(Tracker::count, 3);
+ v.removeLast();
+ QCOMPARE(Tracker::count, 2);
+ v.append(t);
+ v.append({});
+ QCOMPARE(Tracker::count, 4);
+ v.removeLast();
+ QCOMPARE(Tracker::count, 3);
+ }
+ QCOMPARE(Tracker::count, 0);
}
void tst_QVarLengthArray::oldTests()
@@ -224,10 +442,109 @@ void tst_QVarLengthArray::appendCausingRealloc()
QVarLengthArray<float, 1> d(1);
for (int i=0; i<30; i++)
d.append(i);
+
+ // Regression test for QTBUG-110412:
+ constexpr qsizetype InitialCapacity = 10;
+ QVarLengthArray<float, InitialCapacity> d2(InitialCapacity);
+ std::iota(d2.begin(), d2.end(), 0.0f);
+ QCOMPARE_EQ(d2.size(), d2.capacity()); // by construction
+ float floats[1000];
+ std::iota(std::begin(floats), std::end(floats), InitialCapacity + 0.0f);
+ d2.append(floats, q20::ssize(floats));
+ QCOMPARE_EQ(d2.size(), q20::ssize(floats) + InitialCapacity);
+ QCOMPARE_GE(d2.capacity(), d2.size());
+}
+
+void tst_QVarLengthArray::appendIsStronglyExceptionSafe()
+{
+#ifdef QT_NO_EXCEPTIONS
+ QSKIP("This test requires exception support enabled in the compiler.");
+#else
+ static bool throwOnCopyNow = false;
+ static bool throwOnMoveNow = false;
+ struct Thrower {
+ Thrower() = default;
+ Thrower(const Thrower &)
+ {
+ if (throwOnCopyNow)
+ throw 1;
+ }
+ Thrower &operator=(const Thrower &) = default;
+ Thrower(Thrower &&)
+ {
+ if (throwOnMoveNow)
+ throw 1;
+ }
+ Thrower &operator=(Thrower &&) = default;
+ ~Thrower() = default;
+ };
+
+ {
+ QVarLengthArray<Thrower, 2> vla(1);
+ {
+ Thrower t;
+ const QScopedValueRollback rb(throwOnCopyNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back(t));
+ QCOMPARE(vla.size(), 1);
+ }
+ {
+ const QScopedValueRollback rb(throwOnMoveNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back({}));
+ QCOMPARE(vla.size(), 1);
+ }
+ vla.push_back({});
+ QCOMPARE(vla.size(), 2);
+ {
+ Thrower t;
+ {
+ // tests the copy inside append()
+ const QScopedValueRollback rb(throwOnCopyNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back(t));
+ QCOMPARE(vla.size(), 2);
+ }
+ {
+ // tests the move inside reallocate()
+ const QScopedValueRollback rb(throwOnMoveNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back(t));
+ QCOMPARE(vla.size(), 2);
+ }
+ }
+ {
+ const QScopedValueRollback rb(throwOnMoveNow, true);
+ QVERIFY_THROWS_EXCEPTION(int, vla.push_back({}));
+ QCOMPARE(vla.size(), 2);
+ }
+ }
+#endif
}
void tst_QVarLengthArray::resize()
{
+ // Empty Movable
+ {
+ QVarLengthArray<QVariant, 1> values;
+ QCOMPARE(values.size(), 0);
+ values.resize(2);
+ QCOMPARE(values.size(), 2);
+ QCOMPARE(values[0], QVariant());
+ QCOMPARE(values[1], QVariant());
+ }
+
+ // Empty POD
+ {
+ QVarLengthArray<int, 1> values;
+ QCOMPARE(values.size(), 0);
+ values.resize(2);
+ QCOMPARE(values.size(), 2);
+ // POD values are uninitialized, but we can check that we can assign
+ // new values
+ values[0] = 0;
+ values[1] = 1;
+
+ QCOMPARE(values[0], 0);
+ QCOMPARE(values[1], 1);
+ }
+
//MOVABLE
{
QVarLengthArray<QVariant,1> values(1);
@@ -327,6 +644,12 @@ struct MyBase
bool hasMoved() const { return !wasConstructedAt(this); }
protected:
+ void swap(MyBase &other) {
+ using std::swap;
+ swap(data, other.data);
+ swap(isCopy, other.isCopy);
+ }
+
MyBase(const MyBase *data, bool isCopy)
: data(data), isCopy(isCopy) {}
@@ -401,6 +724,14 @@ struct MyMovable
return *this;
}
+ void swap(MyMovable &other) noexcept
+ {
+ MyBase::swap(other);
+ std::swap(i, other.i);
+ }
+
+ friend void swap(MyMovable &lhs, MyMovable &rhs) noexcept { lhs.swap(rhs); }
+
bool operator==(const MyMovable &other) const
{
return i == other.i;
@@ -416,24 +747,33 @@ struct MyComplex
{
return i == other.i;
}
+
+ void swap(MyComplex &other) noexcept
+ {
+ MyBase::swap(other);
+ std::swap(i, other.i);
+ }
+
+ friend void swap(MyComplex &lhs, MyComplex &rhs) noexcept { lhs.swap(rhs); }
+
char i;
};
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(MyMovable, Q_RELOCATABLE_TYPE);
Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE);
QT_END_NAMESPACE
bool reallocTestProceed = true;
-template <class T, int PreAlloc>
-int countMoved(QVarLengthArray<T, PreAlloc> const &c)
+template <class T, qsizetype PreAlloc>
+qsizetype countMoved(QVarLengthArray<T, PreAlloc> const &c)
{
- int result = 0;
- for (int i = 0; i < c.size(); ++i)
+ qsizetype result = 0;
+ for (qsizetype i = 0; i < c.size(); ++i)
if (c[i].hasMoved())
++result;
@@ -447,11 +787,11 @@ void reallocTest()
typedef QVarLengthArray<T, 16> Container;
enum {
- isStatic = QTypeInfo<T>::isStatic,
+ isRelocatable = QTypeInfo<T>::isRelocatable,
isComplex = QTypeInfo<T>::isComplex,
- isPrimitive = !isComplex && !isStatic,
- isMovable = !isStatic
+ isPrimitive = !isComplex && isRelocatable,
+ isMovable = isRelocatable
};
// Constructors
@@ -623,8 +963,53 @@ void tst_QVarLengthArray::realloc()
QVERIFY(reallocTestProceed);
}
+void tst_QVarLengthArray::iterators()
+{
+ QVarLengthArray<int> emptyArr;
+ QCOMPARE(emptyArr.constBegin(), emptyArr.constEnd());
+ QCOMPARE(emptyArr.cbegin(), emptyArr.cend());
+ QCOMPARE(emptyArr.begin(), emptyArr.end());
+
+ QVarLengthArray<int> arr { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+ auto it = arr.begin();
+ auto constIt = arr.cbegin();
+ qsizetype idx = 0;
+
+ QCOMPARE(*it, arr[idx]);
+ QCOMPARE(*constIt, arr[idx]);
+
+ it++;
+ constIt++;
+ idx++;
+ QCOMPARE(*it, arr[idx]);
+ QCOMPARE(*constIt, arr[idx]);
+
+ it += 5;
+ constIt += 5;
+ idx += 5;
+ QCOMPARE(*it, arr[idx]);
+ QCOMPARE(*constIt, arr[idx]);
+
+ it -= 3;
+ constIt -= 3;
+ idx -= 3;
+ QCOMPARE(*it, arr[idx]);
+ QCOMPARE(*constIt, arr[idx]);
+
+ it--;
+ constIt--;
+ idx--;
+ QCOMPARE(*it, arr[idx]);
+ QCOMPARE(*constIt, arr[idx]);
+}
+
void tst_QVarLengthArray::reverseIterators()
{
+ QVarLengthArray<int> emptyArr;
+ QCOMPARE(emptyArr.crbegin(), emptyArr.crend());
+ QCOMPARE(emptyArr.rbegin(), emptyArr.rend());
+
QVarLengthArray<int> v;
v << 1 << 2 << 3 << 4;
QVarLengthArray<int> vr = v;
@@ -643,26 +1028,29 @@ void tst_QVarLengthArray::count()
// tests size(), count() and length(), since they're the same thing
{
const QVarLengthArray<int> list;
- QCOMPARE(list.length(), 0);
- QCOMPARE(list.count(), 0);
QCOMPARE(list.size(), 0);
+ QCOMPARE(list.size(), 0);
+ QCOMPARE(list.size(), 0);
+ QVERIFY(list.isEmpty());
}
{
QVarLengthArray<int> list;
list.append(0);
- QCOMPARE(list.length(), 1);
- QCOMPARE(list.count(), 1);
QCOMPARE(list.size(), 1);
+ QCOMPARE(list.size(), 1);
+ QCOMPARE(list.size(), 1);
+ QVERIFY(!list.isEmpty());
}
{
QVarLengthArray<int> list;
list.append(0);
list.append(1);
- QCOMPARE(list.length(), 2);
- QCOMPARE(list.count(), 2);
QCOMPARE(list.size(), 2);
+ QCOMPARE(list.size(), 2);
+ QCOMPARE(list.size(), 2);
+ QVERIFY(!list.isEmpty());
}
{
@@ -670,9 +1058,10 @@ void tst_QVarLengthArray::count()
list.append(0);
list.append(0);
list.append(0);
- QCOMPARE(list.length(), 3);
- QCOMPARE(list.count(), 3);
QCOMPARE(list.size(), 3);
+ QCOMPARE(list.size(), 3);
+ QCOMPARE(list.size(), 3);
+ QVERIFY(!list.isEmpty());
}
// test removals too
@@ -681,24 +1070,51 @@ void tst_QVarLengthArray::count()
list.append(0);
list.append(0);
list.append(0);
- QCOMPARE(list.length(), 3);
- QCOMPARE(list.count(), 3);
QCOMPARE(list.size(), 3);
+ QCOMPARE(list.size(), 3);
+ QCOMPARE(list.size(), 3);
+ QVERIFY(!list.isEmpty());
list.removeLast();
- QCOMPARE(list.length(), 2);
- QCOMPARE(list.count(), 2);
QCOMPARE(list.size(), 2);
+ QCOMPARE(list.size(), 2);
+ QCOMPARE(list.size(), 2);
+ QVERIFY(!list.isEmpty());
list.removeLast();
- QCOMPARE(list.length(), 1);
- QCOMPARE(list.count(), 1);
QCOMPARE(list.size(), 1);
+ QCOMPARE(list.size(), 1);
+ QCOMPARE(list.size(), 1);
+ QVERIFY(!list.isEmpty());
list.removeLast();
- QCOMPARE(list.length(), 0);
- QCOMPARE(list.count(), 0);
QCOMPARE(list.size(), 0);
+ QCOMPARE(list.size(), 0);
+ QCOMPARE(list.size(), 0);
+ QVERIFY(list.isEmpty());
}
}
+void tst_QVarLengthArray::cpp17ctad()
+{
+#define QVERIFY_IS_VLA_OF(obj, Type) \
+ QVERIFY2((std::is_same<decltype(obj), QVarLengthArray<Type>>::value), \
+ QMetaType::fromType<decltype(obj)::value_type>().name())
+#define CHECK(Type, One, Two, Three) \
+ do { \
+ const Type v[] = {One, Two, Three}; \
+ QVarLengthArray v1 = {One, Two, Three}; \
+ QVERIFY_IS_VLA_OF(v1, Type); \
+ QVarLengthArray v2(v1.begin(), v1.end()); \
+ QVERIFY_IS_VLA_OF(v2, Type); \
+ QVarLengthArray v3(std::begin(v), std::end(v)); \
+ QVERIFY_IS_VLA_OF(v3, Type); \
+ } while (false) \
+ /*end*/
+ CHECK(int, 1, 2, 3);
+ CHECK(double, 1.0, 2.0, 3.0);
+ CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
+#undef QVERIFY_IS_VLA_OF
+#undef CHECK
+}
+
void tst_QVarLengthArray::first()
{
// append some items, make sure it stays sane
@@ -709,16 +1125,16 @@ void tst_QVarLengthArray::first()
QCOMPARE(list.first(), 27);
list.append(1987);
QCOMPARE(list.first(), 27);
- QCOMPARE(list.length(), 3);
+ QCOMPARE(list.size(), 3);
// remove some, make sure it stays sane
list.removeLast();
QCOMPARE(list.first(), 27);
- QCOMPARE(list.length(), 2);
+ QCOMPARE(list.size(), 2);
list.removeLast();
QCOMPARE(list.first(), 27);
- QCOMPARE(list.length(), 1);
+ QCOMPARE(list.size(), 1);
}
void tst_QVarLengthArray::last()
@@ -731,23 +1147,27 @@ void tst_QVarLengthArray::last()
QCOMPARE(list.last(), 4);
list.append(1987);
QCOMPARE(list.last(), 1987);
- QCOMPARE(list.length(), 3);
+ QCOMPARE(list.size(), 3);
// remove some, make sure it stays sane
list.removeLast();
QCOMPARE(list.last(), 4);
- QCOMPARE(list.length(), 2);
+ QCOMPARE(list.size(), 2);
list.removeLast();
QCOMPARE(list.last(), 27);
- QCOMPARE(list.length(), 1);
+ QCOMPARE(list.size(), 1);
}
void tst_QVarLengthArray::squeeze()
{
- QVarLengthArray<int> list;
- int sizeOnStack = list.capacity();
- int sizeOnHeap = sizeOnStack * 2;
+ QVarLengthArray<int, 100> list;
+ qsizetype sizeOnStack = list.capacity();
+ QCOMPARE(sizeOnStack, 100);
+ list.squeeze();
+ QCOMPARE(list.capacity(), sizeOnStack);
+
+ qsizetype sizeOnHeap = sizeOnStack * 2;
list.resize(0);
QCOMPARE(list.capacity(), sizeOnStack);
list.resize(sizeOnHeap);
@@ -768,11 +1188,11 @@ void tst_QVarLengthArray::squeeze()
void tst_QVarLengthArray::operators()
{
- QVarLengthArray<QString> myvla;
+ QVarLengthArray<QString, 6> myvla;
myvla << "A" << "B" << "C";
- QVarLengthArray<QString> myvlatwo;
+ QVarLengthArray<QString, 3> myvlatwo;
myvlatwo << "D" << "E" << "F";
- QVarLengthArray<QString> combined;
+ QVarLengthArray<QString, 7> combined;
combined << "A" << "B" << "C" << "D" << "E" << "F";
// !=
@@ -780,7 +1200,7 @@ void tst_QVarLengthArray::operators()
// +=: not provided, emulate
//myvla += myvlatwo;
- Q_FOREACH (const QString &s, myvlatwo)
+ for (const QString &s : std::as_const(myvlatwo))
myvla.push_back(s);
QCOMPARE(myvla, combined);
@@ -812,6 +1232,10 @@ void tst_QVarLengthArray::operators()
void tst_QVarLengthArray::indexOf()
{
QVarLengthArray<QString> myvec;
+
+ QCOMPARE(myvec.indexOf("A"), -1);
+ QCOMPARE(myvec.indexOf("A", 5), -1);
+
myvec << "A" << "B" << "C" << "B" << "A";
QVERIFY(myvec.indexOf("B") == 1);
@@ -836,6 +1260,10 @@ void tst_QVarLengthArray::indexOf()
void tst_QVarLengthArray::lastIndexOf()
{
QVarLengthArray<QString> myvec;
+
+ QCOMPARE(myvec.lastIndexOf("A"), -1);
+ QCOMPARE(myvec.lastIndexOf("A", 5), -1);
+
myvec << "A" << "B" << "C" << "B" << "A";
QVERIFY(myvec.lastIndexOf("B") == 3);
@@ -859,6 +1287,10 @@ void tst_QVarLengthArray::lastIndexOf()
void tst_QVarLengthArray::contains()
{
QVarLengthArray<QString> myvec;
+
+ QVERIFY(!myvec.contains(QLatin1String("aaa")));
+ QVERIFY(!myvec.contains(QString()));
+
myvec << "aaa" << "bbb" << "ccc";
QVERIFY(myvec.contains(QLatin1String("aaa")));
@@ -874,6 +1306,9 @@ void tst_QVarLengthArray::contains()
void tst_QVarLengthArray::clear()
{
QVarLengthArray<QString, 5> myvec;
+ QCOMPARE(myvec.size(), 0);
+ myvec.clear();
+ QCOMPARE(myvec.size(), 0);
for (int i = 0; i < 10; ++i)
myvec << "aaa";
@@ -908,7 +1343,6 @@ void tst_QVarLengthArray::initializeListComplex()
template<typename T>
void tst_QVarLengthArray::initializeList()
{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
T val1(110);
T val2(105);
T val3(101);
@@ -945,9 +1379,6 @@ void tst_QVarLengthArray::initializeList()
v6 = {}; // assign empty
QCOMPARE(v6.size(), 0);
-#else
- QSKIP("This tests requires a compiler that supports initializer lists.");
-#endif
}
void tst_QVarLengthArray::insertMove()
@@ -957,6 +1388,17 @@ void tst_QVarLengthArray::insertMove()
QCOMPARE(MyBase::copyCount, 0);
{
+ MyMovable m1, m2;
+ QCOMPARE(MyBase::liveCount, 2);
+ QCOMPARE(MyBase::copyCount, 0);
+ using std::swap;
+ swap(m1, m2);
+ QCOMPARE(MyBase::liveCount, 2);
+ QCOMPARE(MyBase::movedCount, 0);
+ QCOMPARE(MyBase::copyCount, 0);
+ }
+
+ {
QVarLengthArray<MyMovable, 6> vec;
MyMovable m1;
MyMovable m2;
@@ -982,7 +1424,7 @@ void tst_QVarLengthArray::insertMove()
QCOMPARE(MyBase::liveCount, 6);
QCOMPARE(MyBase::movedCount, 2);
- vec.prepend(std::move(m1));
+ vec.insert(vec.cbegin(), std::move(m1));
QVERIFY(m1.wasConstructedAt(nullptr));
QVERIFY(vec.at(0).wasConstructedAt(&m1));
QVERIFY(vec.at(1).wasConstructedAt(&m3));
@@ -1054,7 +1496,7 @@ void tst_QVarLengthArray::nonCopyable()
QVERIFY(!val4);
QVERIFY(ptr3 == vec.at(0).get());
QVERIFY(ptr4 == vec.at(1).get());
- vec.prepend(std::move(val1));
+ vec.insert(vec.cbegin(), std::move(val1));
QVERIFY(!val1);
QVERIFY(ptr1 == vec.at(0).get());
QVERIFY(ptr3 == vec.at(1).get());
@@ -1082,5 +1524,245 @@ void tst_QVarLengthArray::nonCopyable()
QVERIFY(ptr6 == vec.at(5).get());
}
+void tst_QVarLengthArray::implicitDefaultCtor()
+{
+ QVarLengthArray<int> def = {};
+ QCOMPARE(def.size(), 0);
+}
+
+void tst_QVarLengthArray::reserve()
+{
+ QVarLengthArray<int, 100> arr;
+ QCOMPARE(arr.capacity(), 100);
+ QCOMPARE(arr.size(), 0);
+
+ const auto *stackPtr = arr.constData();
+ arr.reserve(50);
+ // Nothing changed, as we reserve less than pre-allocated
+ QCOMPARE(arr.capacity(), 100);
+ QCOMPARE(arr.size(), 0);
+ QCOMPARE(arr.constData(), stackPtr);
+
+ arr.reserve(150);
+ // Allocate memory on heap, as we reserve more than pre-allocated
+ QCOMPARE(arr.capacity(), 150);
+ QCOMPARE(arr.size(), 0);
+ const auto *heapPtr = arr.constData();
+ QVERIFY(heapPtr != stackPtr);
+
+ arr.reserve(50);
+ // Nothing changed
+ QCOMPARE(arr.capacity(), 150);
+ QCOMPARE(arr.constData(), heapPtr);
+
+ arr.squeeze();
+ // After squeeze() we go back to using stack
+ QCOMPARE(arr.capacity(), 100);
+ QCOMPARE(arr.constData(), stackPtr);
+}
+
+void tst_QVarLengthArray::value()
+{
+ const QString def("default value");
+
+ QVarLengthArray<QString> arr;
+ QCOMPARE(arr.value(0), QString());
+ QCOMPARE(arr.value(1, def), def);
+ QCOMPARE(arr.value(-1, def), def);
+
+ const qsizetype size = 5;
+ const QString dataStr("data%1");
+ arr.resize(size);
+ for (qsizetype i = 0; i < size; ++i)
+ arr[i] = dataStr.arg(i);
+
+ for (qsizetype i = 0; i < size; ++i)
+ QCOMPARE(arr.value(i, def), dataStr.arg(i));
+
+ QCOMPARE(arr.value(size + 1), QString());
+ QCOMPARE(arr.value(-1, def), def);
+}
+
+void tst_QVarLengthArray::insert()
+{
+ QFETCH(QVarLengthArray<QString>, arr);
+ QFETCH(int, pos);
+ QFETCH(int, count);
+ QFETCH(QString, data);
+ QFETCH(QVarLengthArray<QString>, expected);
+
+ // Insert using index
+ {
+ QVarLengthArray<QString> copy = arr;
+ if (count == 1) {
+ copy.insert(pos, data);
+ QCOMPARE(copy, expected);
+
+ copy = arr;
+ QString d = data;
+ copy.insert(pos, std::move(d));
+ QCOMPARE(copy, expected);
+ } else {
+ copy.insert(pos, count, data);
+ QCOMPARE(copy, expected);
+ }
+ }
+
+ // Insert using iterator
+ {
+ QVarLengthArray<QString> copy = arr;
+ if (count == 1) {
+ copy.insert(copy.cbegin() + pos, data);
+ QCOMPARE(copy, expected);
+
+ copy = arr;
+ QString d = data;
+ copy.insert(copy.cbegin() + pos, std::move(d));
+ QCOMPARE(copy, expected);
+ } else {
+ copy.insert(copy.cbegin() + pos, count, data);
+ QCOMPARE(copy, expected);
+ }
+ }
+}
+
+void tst_QVarLengthArray::insert_data()
+{
+ QTest::addColumn<QVarLengthArray<QString>>("arr");
+ QTest::addColumn<int>("pos");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<QString>("data");
+ QTest::addColumn<QVarLengthArray<QString>>("expected");
+
+ const QString data("Test");
+
+ QTest::newRow("empty")
+ << QVarLengthArray<QString>() << 0 << 1 << data << QVarLengthArray<QString>({ data });
+ QTest::newRow("empty-none")
+ << QVarLengthArray<QString>() << 0 << 0 << data << QVarLengthArray<QString>();
+ QTest::newRow("begin")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 0 << 1 << data
+ << QVarLengthArray<QString>({ data, "value1", "value2" });
+ QTest::newRow("end")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 2 << 1 << data
+ << QVarLengthArray<QString>({ "value1", "value2", data });
+ QTest::newRow("middle")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 1 << 1 << data
+ << QVarLengthArray<QString>({ "value1", data, "value2" });
+ QTest::newRow("begin-none")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 0 << 0 << data
+ << QVarLengthArray<QString>({ "value1", "value2" });
+ QTest::newRow("end-none")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 2 << 0 << data
+ << QVarLengthArray<QString>({ "value1", "value2" });
+ QTest::newRow("middle-none")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 1 << 0 << data
+ << QVarLengthArray<QString>({ "value1", "value2" });
+ QTest::newRow("multi begin")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 0 << 2 << data
+ << QVarLengthArray<QString>({ data, data, "value1", "value2" });
+ QTest::newRow("multi end")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 2 << 2 << data
+ << QVarLengthArray<QString>({ "value1", "value2", data, data });
+ QTest::newRow("multi middle")
+ << QVarLengthArray<QString>({ "value1", "value2" }) << 1 << 2 << data
+ << QVarLengthArray<QString>({ "value1", data, data, "value2" });
+}
+
+void tst_QVarLengthArray::replace()
+{
+ QVarLengthArray<QString> arr({ "val0", "val1", "val2" });
+
+ arr.replace(0, "data0");
+ QCOMPARE(arr, QVarLengthArray<QString>({ "data0", "val1", "val2" }));
+
+ arr.replace(2, "data2");
+ QCOMPARE(arr, QVarLengthArray<QString>({ "data0", "val1", "data2" }));
+
+ arr.replace(1, "data1");
+ QCOMPARE(arr, QVarLengthArray<QString>({ "data0", "data1", "data2" }));
+}
+
+void tst_QVarLengthArray::remove()
+{
+ auto isVal2 = [](const QString &str) { return str == "val2"; };
+
+ QVarLengthArray<QString> arr;
+ QCOMPARE(arr.removeAll("val0"), 0);
+ QVERIFY(!arr.removeOne("val1"));
+ QCOMPARE(arr.removeIf(isVal2), 0);
+
+ arr << "val0" << "val1" << "val2";
+ arr << "val0" << "val1" << "val2";
+ arr << "val0" << "val1" << "val2";
+
+ QCOMPARE(arr.size(), 9);
+
+ arr.remove(1, 3);
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0", "val1", "val2", "val0", "val1", "val2" }));
+
+ arr.remove(2);
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0", "val1", "val0", "val1", "val2" }));
+
+ QVERIFY(arr.removeOne("val1"));
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0", "val0", "val1", "val2" }));
+
+ QCOMPARE(arr.removeAll("val0"), 2);
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val1", "val2" }));
+
+ QCOMPARE(arr.removeIf(isVal2), 1);
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val1" }));
+
+ arr.removeLast();
+ QVERIFY(arr.isEmpty());
+}
+
+void tst_QVarLengthArray::erase()
+{
+ QVarLengthArray<QString> arr;
+ QCOMPARE(arr.erase(arr.cbegin(), arr.cend()), arr.cend());
+
+ arr << "val0" << "val1" << "val2";
+ arr << "val0" << "val1" << "val2";
+ arr << "val0" << "val1" << "val2";
+
+ auto it = arr.erase(arr.cbegin() + 1, arr.cend() - 3);
+ QCOMPARE(it, arr.cend() - 3);
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0", "val0", "val1", "val2" }));
+
+ it = arr.erase(arr.cbegin());
+ QCOMPARE(it, arr.cbegin());
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0", "val1", "val2" }));
+
+ it = arr.erase(arr.cbegin() + 1);
+ QCOMPARE(it, arr.cend() - 1);
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0", "val2" }));
+
+ it = arr.erase(arr.cend() - 1);
+ QCOMPARE(it, arr.cend());
+ QCOMPARE(arr, QVarLengthArray<QString>({ "val0" }));
+}
+
+void tst_QVarLengthArray::copesWithCopyabilityOfMoveOnlyVector()
+{
+ // std::vector<move-only-type> is_copyable
+ // (https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable-except-when-its-not/)
+
+ QVarLengthArray<std::vector<std::unique_ptr<int>>, 2> vla;
+ vla.emplace_back(42);
+ vla.emplace_back(43);
+ vla.emplace_back(44); // goes to the heap
+ QCOMPARE_EQ(vla.size(), 3);
+ QCOMPARE_EQ(vla.front().size(), 42U);
+ QCOMPARE_EQ(vla.front().front(), nullptr);
+ QCOMPARE_EQ(vla.back().size(), 44U);
+
+ auto moved = std::move(vla);
+ QCOMPARE_EQ(moved.size(), 3);
+ QCOMPARE_EQ(moved.front().size(), 42U);
+ QCOMPARE_EQ(moved.front().front(), nullptr);
+ QCOMPARE_EQ(moved.back().size(), 44U);
+}
+
QTEST_APPLESS_MAIN(tst_QVarLengthArray)
#include "tst_qvarlengtharray.moc"
diff --git a/tests/auto/corelib/tools/qvector/.gitignore b/tests/auto/corelib/tools/qvector/.gitignore
deleted file mode 100644
index 5520039486..0000000000
--- a/tests/auto/corelib/tools/qvector/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qvector
diff --git a/tests/auto/corelib/tools/qvector/qvector.pro b/tests/auto/corelib/tools/qvector/qvector.pro
deleted file mode 100644
index b9a4ae747b..0000000000
--- a/tests/auto/corelib/tools/qvector/qvector.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG += testcase
-qtConfig(c++11): CONFIG += c++11
-TARGET = tst_qvector
-QT = core testlib
-SOURCES = $$PWD/tst_qvector.cpp
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
deleted file mode 100644
index a7faeb5ca5..0000000000
--- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp
+++ /dev/null
@@ -1,2956 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QAtomicInt>
-#include <QThread>
-#include <QSemaphore>
-#include <qvector.h>
-
-struct Movable {
- Movable(char input = 'j')
- : i(input)
- , that(this)
- , state(Constructed)
- {
- counter.fetchAndAddRelaxed(1);
- }
- Movable(const Movable &other)
- : i(other.i)
- , that(this)
- , state(Constructed)
- {
- check(other.state, Constructed);
- counter.fetchAndAddRelaxed(1);
- }
- Movable(Movable &&other)
- : i(other.i)
- , that(other.that)
- , state(Constructed)
- {
- check(other.state, Constructed);
- counter.fetchAndAddRelaxed(1);
- other.that = nullptr;
- }
-
- ~Movable()
- {
- check(state, Constructed);
- i = 0;
- counter.fetchAndAddRelaxed(-1);
- state = Destructed;
- }
-
- bool operator ==(const Movable &other) const
- {
- check(state, Constructed);
- check(other.state, Constructed);
- return i == other.i;
- }
-
- Movable &operator=(const Movable &other)
- {
- check(state, Constructed);
- check(other.state, Constructed);
- i = other.i;
- that = this;
- return *this;
- }
- Movable &operator=(Movable &&other)
- {
- check(state, Constructed);
- check(other.state, Constructed);
- i = other.i;
- that = other.that;
- other.that = nullptr;
- return *this;
- }
- bool wasConstructedAt(const Movable *other) const
- {
- return that == other;
- }
- char i;
- static QAtomicInt counter;
-private:
- Movable *that; // used to check if an instance was moved
-
- enum State { Constructed = 106, Destructed = 110 };
- State state;
-
- static void check(const State state1, const State state2)
- {
- QCOMPARE(state1, state2);
- }
-};
-
-inline uint qHash(const Movable &key, uint seed = 0) { return qHash(key.i, seed); }
-
-QAtomicInt Movable::counter = 0;
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-Q_DECLARE_METATYPE(Movable);
-
-struct Custom {
- Custom(char input = 'j')
- : i(input)
- , that(this)
- , state(Constructed)
- {
- counter.fetchAndAddRelaxed(1);
- }
- Custom(const Custom &other)
- : that(this)
- , state(Constructed)
- {
- check(&other);
- counter.fetchAndAddRelaxed(1);
- this->i = other.i;
- }
- ~Custom()
- {
- check(this);
- i = 0;
- counter.fetchAndAddRelaxed(-1);
- state = Destructed;
- }
-
- bool operator ==(const Custom &other) const
- {
- check(&other);
- check(this);
- return i == other.i;
- }
-
- bool operator<(const Custom &other) const
- {
- check(&other);
- check(this);
- return i < other.i;
- }
-
- Custom &operator=(const Custom &other)
- {
- check(&other);
- check(this);
- i = other.i;
- return *this;
- }
- static QAtomicInt counter;
-
- char i; // used to identify orgin of an instance
-private:
- Custom *that; // used to check if an instance was moved
-
- enum State { Constructed = 106, Destructed = 110 };
- State state;
-
- static void check(const Custom *c)
- {
- // check if c object has been moved
- QCOMPARE(c, c->that);
- QCOMPARE(c->state, Constructed);
- }
-};
-QAtomicInt Custom::counter = 0;
-
-inline uint qHash(const Custom &key, uint seed = 0) { return qHash(key.i, seed); }
-
-Q_DECLARE_METATYPE(Custom);
-
-// tests depends on the fact that:
-Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic);
-Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
-Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
-Q_STATIC_ASSERT(QTypeInfo<Custom>::isStatic);
-Q_STATIC_ASSERT(QTypeInfo<Custom>::isComplex);
-
-
-class tst_QVector : public QObject
-{
- Q_OBJECT
-private slots:
- void constructors_empty() const;
- void constructors_emptyReserveZero() const;
- void constructors_emptyReserve() const;
- void constructors_reserveAndInitialize() const;
- void copyConstructorInt() const;
- void copyConstructorMovable() const;
- void copyConstructorCustom() const;
- void assignmentInt() const;
- void assignmentMovable() const;
- void assignmentCustom() const;
- void addInt() const;
- void addMovable() const;
- void addCustom() const;
- void appendInt() const;
- void appendMovable() const;
- void appendCustom() const;
- void appendRvalue() const;
- void at() const;
- void capacityInt() const;
- void capacityMovable() const;
- void capacityCustom() const;
- void clearInt() const;
- void clearMovable() const;
- void clearCustom() const;
- void constData() const;
- void constFirst() const;
- void constLast() const;
- void contains() const;
- void countInt() const;
- void countMovable() const;
- void countCustom() const;
- void data() const;
- void emptyInt() const;
- void emptyMovable() const;
- void emptyCustom() const;
- void endsWith() const;
- void eraseEmptyInt() const;
- void eraseEmptyMovable() const;
- void eraseEmptyCustom() const;
- void eraseEmptyReservedInt() const;
- void eraseEmptyReservedMovable() const;
- void eraseEmptyReservedCustom() const;
- void eraseInt() const;
- void eraseIntShared() const;
- void eraseMovable() const;
- void eraseMovableShared() const;
- void eraseCustom() const;
- void eraseCustomShared() const;
- void eraseReservedInt() const;
- void eraseReservedMovable() const;
- void eraseReservedCustom() const;
- void fillInt() const;
- void fillMovable() const;
- void fillCustom() const;
- void first() const;
- void fromListInt() const;
- void fromListMovable() const;
- void fromListCustom() const;
- void fromStdVector() const;
- void indexOf() const;
- void insertInt() const;
- void insertMovable() const;
- void insertCustom() const;
- void isEmpty() const;
- void last() const;
- void lastIndexOf() const;
- void mid() const;
- void moveInt() const;
- void moveMovable() const;
- void moveCustom() const;
- void prependInt() const;
- void prependMovable() const;
- void prependCustom() const;
- void qhashInt() const { qhash<int>(); }
- void qhashMovable() const { qhash<Movable>(); }
- void qhashCustom() const { qhash<Custom>(); }
- void removeAllWithAlias() const;
- void removeInt() const;
- void removeMovable() const;
- void removeCustom() const;
- void removeFirstLast() const;
- void resizePOD_data() const;
- void resizePOD() const;
- void resizeComplexMovable_data() const;
- void resizeComplexMovable() const;
- void resizeComplex_data() const;
- void resizeComplex() const;
- void resizeCtorAndDtor() const;
- void reverseIterators() const;
- void sizeInt() const;
- void sizeMovable() const;
- void sizeCustom() const;
- void startsWith() const;
- void swapInt() const;
- void swapMovable() const;
- void swapCustom() const;
- void toList() const;
- void toStdVector() const;
- void value() const;
-
- void testOperators() const;
-
- void reserve();
- void reserveZero();
- void reallocAfterCopy_data();
- void reallocAfterCopy();
- void initializeListInt();
- void initializeListMovable();
- void initializeListCustom();
-
- void const_shared_null();
-#if 1
- // ### Qt6 remove this section
- void setSharableInt_data();
- void setSharableInt();
- void setSharableMovable_data();
- void setSharableMovable();
- void setSharableCustom_data();
- void setSharableCustom();
-#endif
-
- void detachInt() const;
- void detachMovable() const;
- void detachCustom() const;
- void detachThreadSafetyInt() const;
- void detachThreadSafetyMovable() const;
- void detachThreadSafetyCustom() const;
-
- void insertMove() const;
-
-private:
- template<typename T> void copyConstructor() const;
- template<typename T> void add() const;
- template<typename T> void append() const;
- template<typename T> void capacity() const;
- template<typename T> void clear() const;
- template<typename T> void count() const;
- template<typename T> void empty() const;
- template<typename T> void eraseEmpty() const;
- template<typename T> void eraseEmptyReserved() const;
- template<typename T> void erase(bool shared) const;
- template<typename T> void eraseReserved() const;
- template<typename T> void fill() const;
- template<typename T> void fromList() const;
- template<typename T> void insert() const;
- template<typename T> void qhash() const;
- template<typename T> void move() const;
- template<typename T> void prepend() const;
- template<typename T> void remove() const;
- template<typename T> void size() const;
- template<typename T> void swap() const;
- template<typename T> void initializeList();
- template<typename T> void setSharable_data() const;
- template<typename T> void setSharable() const;
- template<typename T> void detach() const;
- template<typename T> void detachThreadSafety() const;
-};
-
-
-template<typename T> struct SimpleValue
-{
- static T at(int index)
- {
- return Values[index % MaxIndex];
- }
-
- static QVector<T> vector(int size)
- {
- QVector<T> ret;
- for (int i = 0; i < size; i++)
- ret.append(at(i));
- return ret;
- }
-
- static const uint MaxIndex = 6;
- static const T Values[MaxIndex];
-};
-
-template<>
-const int SimpleValue<int>::Values[] = { 110, 105, 101, 114, 111, 98 };
-template<>
-const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 };
-template<>
-const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 };
-
-// Make some macros for the tests to use in order to be slightly more readable...
-#define T_FOO SimpleValue<T>::at(0)
-#define T_BAR SimpleValue<T>::at(1)
-#define T_BAZ SimpleValue<T>::at(2)
-#define T_CAT SimpleValue<T>::at(3)
-#define T_DOG SimpleValue<T>::at(4)
-#define T_BLAH SimpleValue<T>::at(5)
-
-void tst_QVector::constructors_empty() const
-{
- QVector<int> emptyInt;
- QVector<Movable> emptyMovable;
- QVector<Custom> emptyCustom;
-}
-
-void tst_QVector::constructors_emptyReserveZero() const
-{
- QVector<int> emptyInt(0);
- QVector<Movable> emptyMovable(0);
- QVector<Custom> emptyCustom(0);
-}
-
-void tst_QVector::constructors_emptyReserve() const
-{
- // pre-reserve capacity
- QVector<int> myInt(5);
- QVERIFY(myInt.capacity() == 5);
- QVector<Movable> myMovable(5);
- QVERIFY(myMovable.capacity() == 5);
- QVector<Custom> myCustom(4);
- QVERIFY(myCustom.capacity() == 4);
-}
-
-void tst_QVector::constructors_reserveAndInitialize() const
-{
- // default-initialise items
-
- QVector<int> myInt(5, 42);
- QVERIFY(myInt.capacity() == 5);
- foreach (int meaningoflife, myInt) {
- QCOMPARE(meaningoflife, 42);
- }
-
- QVector<QString> myString(5, QString::fromLatin1("c++"));
- QVERIFY(myString.capacity() == 5);
- // make sure all items are initialised ok
- foreach (QString meaningoflife, myString) {
- QCOMPARE(meaningoflife, QString::fromLatin1("c++"));
- }
-
- QVector<Custom> myCustom(5, Custom('n'));
- QVERIFY(myCustom.capacity() == 5);
- // make sure all items are initialised ok
- foreach (Custom meaningoflife, myCustom) {
- QCOMPARE(meaningoflife.i, 'n');
- }
-}
-
-template<typename T>
-void tst_QVector::copyConstructor() const
-{
- T value1(SimpleValue<T>::at(0));
- T value2(SimpleValue<T>::at(1));
- T value3(SimpleValue<T>::at(2));
- T value4(SimpleValue<T>::at(3));
- {
- QVector<T> v1;
- QVector<T> v2(v1);
- QCOMPARE(v1, v2);
- }
- {
- QVector<T> v1;
- v1 << value1 << value2 << value3 << value4;
- QVector<T> v2(v1);
- QCOMPARE(v1, v2);
- }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- {
- QVector<T> v1;
- v1.setSharable(false);
- QVector<T> v2(v1);
- QVERIFY(!v1.isSharedWith(v2));
- QCOMPARE(v1, v2);
- }
- {
- QVector<T> v1;
- v1 << value1 << value2 << value3 << value4;
- v1.setSharable(false);
- QVector<T> v2(v1);
- QVERIFY(!v1.isSharedWith(v2));
- QCOMPARE(v1, v2);
- }
-#endif
-}
-
-void tst_QVector::copyConstructorInt() const
-{
- copyConstructor<int>();
-}
-
-void tst_QVector::copyConstructorMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- copyConstructor<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::copyConstructorCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- copyConstructor<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template <class T>
-static inline void testAssignment()
-{
- QVector<T> v1(5);
- QCOMPARE(v1.size(), 5);
- QVERIFY(v1.isDetached());
-
- QVector<T> v2(7);
- QCOMPARE(v2.size(), 7);
- QVERIFY(v2.isDetached());
-
- QVERIFY(!v1.isSharedWith(v2));
-
- v1 = v2;
-
- QVERIFY(!v1.isDetached());
- QVERIFY(!v2.isDetached());
- QVERIFY(v1.isSharedWith(v2));
-
- const void *const data1 = v1.constData();
- const void *const data2 = v2.constData();
-
- QCOMPARE(data1, data2);
-
- v1.clear();
-
- QVERIFY(v2.isDetached());
- QVERIFY(!v1.isSharedWith(v2));
- QCOMPARE((void *)v2.constData(), data2);
-}
-
-void tst_QVector::assignmentInt() const
-{
- testAssignment<int>();
-}
-
-void tst_QVector::assignmentMovable() const
-{
- testAssignment<Movable>();
-}
-
-void tst_QVector::assignmentCustom() const
-{
- testAssignment<Custom>();
-}
-
-template<typename T>
-void tst_QVector::add() const
-{
- {
- QVector<T> empty1;
- QVector<T> empty2;
- QVERIFY((empty1 + empty2).isEmpty());
- empty1 += empty2;
- QVERIFY(empty1.isEmpty());
- QVERIFY(empty2.isEmpty());
- }
- {
- QVector<T> v(12);
- QVector<T> empty;
- QCOMPARE((v + empty), v);
- v += empty;
- QVERIFY(!v.isEmpty());
- QCOMPARE(v.size(), 12);
- QVERIFY(empty.isEmpty());
- }
- {
- QVector<T> v1(12);
- QVector<T> v2;
- v2 += v1;
- QVERIFY(!v1.isEmpty());
- QCOMPARE(v1.size(), 12);
- QVERIFY(!v2.isEmpty());
- QCOMPARE(v2.size(), 12);
- }
-}
-
-void tst_QVector::addInt() const
-{
- add<int>();
-}
-
-void tst_QVector::addMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- add<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::addCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- add<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::append() const
-{
- {
- QVector<T> myvec;
- myvec.append(SimpleValue<T>::at(0));
- QVERIFY(myvec.size() == 1);
- myvec.append(SimpleValue<T>::at(1));
- QVERIFY(myvec.size() == 2);
- myvec.append(SimpleValue<T>::at(2));
- QVERIFY(myvec.size() == 3);
-
- QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(0)
- << SimpleValue<T>::at(1)
- << SimpleValue<T>::at(2));
- }
- {
- QVector<T> v(2);
- v.append(SimpleValue<T>::at(0));
- QVERIFY(v.size() == 3);
- QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
- }
- {
- QVector<T> v(2);
- v.reserve(12);
- v.append(SimpleValue<T>::at(0));
- QVERIFY(v.size() == 3);
- QCOMPARE(v.at(v.size() - 1), SimpleValue<T>::at(0));
- }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- {
- QVector<T> v(2);
- v.reserve(12);
- v.setSharable(false);
- v.append(SimpleValue<T>::at(0));
- QVERIFY(v.size() == 3);
- QCOMPARE(v.last(), SimpleValue<T>::at(0));
- }
-#endif
- {
- QVector<int> v;
- v << 1 << 2 << 3;
- QVector<int> x;
- x << 4 << 5 << 6;
- v.append(x);
-
- QVector<int> combined;
- combined << 1 << 2 << 3 << 4 << 5 << 6;
-
- QCOMPARE(v, combined);
- }
-}
-
-void tst_QVector::appendInt() const
-{
- append<int>();
-}
-
-void tst_QVector::appendMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- append<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::appendCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- append<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::appendRvalue() const
-{
-#ifdef Q_COMPILER_RVALUE_REFS
- QVector<QString> v;
- v.append("hello");
- QString world = "world";
- v.append(std::move(world));
- QVERIFY(world.isEmpty());
- QCOMPARE(v.front(), QString("hello"));
- QCOMPARE(v.back(), QString("world"));
-#else
- QSKIP("This test requires that C++11 move semantics support is enabled in the compiler");
-#endif
-}
-
-void tst_QVector::at() const
-{
- QVector<QString> myvec;
- myvec << "foo" << "bar" << "baz";
-
- QVERIFY(myvec.size() == 3);
- QCOMPARE(myvec.at(0), QLatin1String("foo"));
- QCOMPARE(myvec.at(1), QLatin1String("bar"));
- QCOMPARE(myvec.at(2), QLatin1String("baz"));
-
- // append an item
- myvec << "hello";
- QVERIFY(myvec.size() == 4);
- QCOMPARE(myvec.at(0), QLatin1String("foo"));
- QCOMPARE(myvec.at(1), QLatin1String("bar"));
- QCOMPARE(myvec.at(2), QLatin1String("baz"));
- QCOMPARE(myvec.at(3), QLatin1String("hello"));
-
- // remove an item
- myvec.remove(1);
- QVERIFY(myvec.size() == 3);
- QCOMPARE(myvec.at(0), QLatin1String("foo"));
- QCOMPARE(myvec.at(1), QLatin1String("baz"));
- QCOMPARE(myvec.at(2), QLatin1String("hello"));
-}
-
-template<typename T>
-void tst_QVector::capacity() const
-{
- QVector<T> myvec;
-
- // TODO: is this guaranteed? seems a safe assumption, but I suppose preallocation of a
- // few items isn't an entirely unforseeable possibility.
- QVERIFY(myvec.capacity() == 0);
-
- // test it gets a size
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
- QVERIFY(myvec.capacity() >= 3);
-
- // make sure it grows ok
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
- QVERIFY(myvec.capacity() >= 6);
- // let's try squeeze a bit
- myvec.remove(3);
- myvec.remove(3);
- myvec.remove(3);
- // TODO: is this a safe assumption? presumably it won't release memory until shrink(), but can we asser that is true?
- QVERIFY(myvec.capacity() >= 6);
- myvec.squeeze();
- QVERIFY(myvec.capacity() >= 3);
-
- myvec.remove(0);
- myvec.remove(0);
- myvec.remove(0);
- // TODO: as above note
- QVERIFY(myvec.capacity() >= 3);
- myvec.squeeze();
- QVERIFY(myvec.capacity() == 0);
-}
-
-void tst_QVector::capacityInt() const
-{
- capacity<int>();
-}
-
-void tst_QVector::capacityMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- capacity<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::capacityCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- capacity<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::clear() const
-{
- QVector<T> myvec;
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
-
- const auto oldCapacity = myvec.capacity();
- QCOMPARE(myvec.size(), 3);
- myvec.clear();
- QCOMPARE(myvec.size(), 0);
- QCOMPARE(myvec.capacity(), oldCapacity);
-}
-
-void tst_QVector::clearInt() const
-{
- clear<int>();
-}
-
-void tst_QVector::clearMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- clear<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::clearCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- clear<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::constData() const
-{
- int arr[] = { 42, 43, 44 };
- QVector<int> myvec;
- myvec << 42 << 43 << 44;
-
- QVERIFY(memcmp(myvec.constData(), reinterpret_cast<const int *>(&arr), sizeof(int) * 3) == 0);
-}
-
-void tst_QVector::contains() const
-{
- QVector<QString> myvec;
- myvec << "aaa" << "bbb" << "ccc";
-
- QVERIFY(myvec.contains(QLatin1String("aaa")));
- QVERIFY(myvec.contains(QLatin1String("bbb")));
- QVERIFY(myvec.contains(QLatin1String("ccc")));
- QVERIFY(!myvec.contains(QLatin1String("I don't exist")));
-
- // add it and make sure it does :)
- myvec.append(QLatin1String("I don't exist"));
- QVERIFY(myvec.contains(QLatin1String("I don't exist")));
-}
-
-template<typename T>
-void tst_QVector::count() const
-{
- // total size
- {
- // zero size
- QVector<T> myvec;
- QVERIFY(myvec.count() == 0);
-
- // grow
- myvec.append(SimpleValue<T>::at(0));
- QVERIFY(myvec.count() == 1);
- myvec.append(SimpleValue<T>::at(1));
- QVERIFY(myvec.count() == 2);
-
- // shrink
- myvec.remove(0);
- QVERIFY(myvec.count() == 1);
- myvec.remove(0);
- QVERIFY(myvec.count() == 0);
- }
-
- // count of items
- {
- QVector<T> myvec;
- myvec << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2);
-
- // initial tests
- QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
- QVERIFY(myvec.count(SimpleValue<T>::at(3)) == 0);
-
- // grow
- myvec.append(SimpleValue<T>::at(0));
- QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 2);
-
- // shrink
- myvec.remove(0);
- QVERIFY(myvec.count(SimpleValue<T>::at(0)) == 1);
- }
-}
-
-void tst_QVector::countInt() const
-{
- count<int>();
-}
-
-void tst_QVector::countMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- count<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::countCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- count<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::data() const
-{
- QVector<int> myvec;
- myvec << 42 << 43 << 44;
-
- // make sure it starts off ok
- QCOMPARE(*(myvec.data() + 1), 43);
-
- // alter it
- *(myvec.data() + 1) = 69;
-
- // check it altered
- QCOMPARE(*(myvec.data() + 1), 69);
-
- int arr[] = { 42, 69, 44 };
- QVERIFY(memcmp(myvec.data(), reinterpret_cast<int *>(&arr), sizeof(int) * 3) == 0);
-}
-
-template<typename T>
-void tst_QVector::empty() const
-{
- QVector<T> myvec;
-
- // starts empty
- QVERIFY(myvec.empty());
-
- // not empty
- myvec.append(SimpleValue<T>::at(2));
- QVERIFY(!myvec.empty());
-
- // empty again
- myvec.remove(0);
- QVERIFY(myvec.empty());
-}
-
-void tst_QVector::emptyInt() const
-{
- empty<int>();
-}
-
-void tst_QVector::emptyMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- empty<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::emptyCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- empty<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::endsWith() const
-{
- QVector<int> myvec;
-
- // empty vector
- QVERIFY(!myvec.endsWith(1));
-
- // add the one, should work
- myvec.append(1);
- QVERIFY(myvec.endsWith(1));
-
- // add something else, fails now
- myvec.append(3);
- QVERIFY(!myvec.endsWith(1));
-
- // remove it again :)
- myvec.remove(1);
- QVERIFY(myvec.endsWith(1));
-}
-
-template<typename T>
-void tst_QVector::eraseEmpty() const
-{
- {
- QVector<T> v;
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- {
- QVector<T> v;
- v.setSharable(false);
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- }
-#endif
-}
-
-void tst_QVector::eraseEmptyInt() const
-{
- eraseEmpty<int>();
-}
-
-void tst_QVector::eraseEmptyMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- eraseEmpty<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseEmptyCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- eraseEmpty<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::eraseEmptyReserved() const
-{
- {
- QVector<T> v;
- v.reserve(10);
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- {
- QVector<T> v;
- v.reserve(10);
- v.setSharable(false);
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- }
-#endif
-}
-
-void tst_QVector::eraseEmptyReservedInt() const
-{
- eraseEmptyReserved<int>();
-}
-
-void tst_QVector::eraseEmptyReservedMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- eraseEmptyReserved<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseEmptyReservedCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- eraseEmptyReserved<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-struct SharedVectorChecker
-{
- SharedVectorChecker(const QVector<T> &original, bool doCopyVector)
- : originalSize(-1),
- copy(0)
- {
- if (doCopyVector) {
- originalSize = original.size();
- copy = new QVector<T>(original);
- // this is unlikely to fail, but if the check in the destructor fails it's good to know that
- // we were still alright here.
- QCOMPARE(originalSize, copy->size());
- }
- }
-
- ~SharedVectorChecker()
- {
- if (copy)
- QCOMPARE(copy->size(), originalSize);
- delete copy;
- }
-
- int originalSize;
- QVector<T> *copy;
-};
-
-template<typename T>
-void tst_QVector::erase(bool shared) const
-{
- // note: remove() is actually more efficient, and more dangerous, because it uses the non-detaching
- // begin() / end() internally. you can also use constBegin() and constEnd() with erase(), but only
- // using reinterpret_cast... because both iterator types are really just pointers.
- // so we use a mix of erase() and remove() to cover more cases.
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.erase(v.begin());
- QCOMPARE(v.size(), 11);
- for (int i = 0; i < 11; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.remove(1);
- QCOMPARE(v.size(), 11);
- QCOMPARE(v.at(0), SimpleValue<T>::at(0));
- for (int i = 1; i < 11; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
- v.erase(v.begin() + 1, v.end());
- QCOMPARE(v.size(), 1);
- QCOMPARE(v.at(0), SimpleValue<T>::at(0));
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.erase(v.begin(), v.end() - 1);
- QCOMPARE(v.size(), 1);
- QCOMPARE(v.at(0), SimpleValue<T>::at(11));
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
- {
- QVector<T> v = SimpleValue<T>::vector(12);
- SharedVectorChecker<T> svc(v, shared);
- v.remove(5);
- QCOMPARE(v.size(), 11);
- for (int i = 0; i < 5; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i));
- for (int i = 5; i < 11; i++)
- QCOMPARE(v.at(i), SimpleValue<T>::at(i + 1));
- v.erase(v.begin() + 1, v.end() - 1);
- QCOMPARE(v.at(0), SimpleValue<T>::at(0));
- QCOMPARE(v.at(1), SimpleValue<T>::at(11));
- QCOMPARE(v.size(), 2);
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(12), *svc.copy);
- }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- {
- QVector<T> v = SimpleValue<T>::vector(10);
- SharedVectorChecker<T> svc(v, shared);
- v.setSharable(false);
- SharedVectorChecker<T> svc2(v, shared);
- v.erase(v.begin() + 3);
- QCOMPARE(v.size(), 9);
- v.erase(v.begin(), v.end() - 1);
- QCOMPARE(v.size(), 1);
- if (shared)
- QCOMPARE(SimpleValue<T>::vector(10), *svc.copy);
- }
-#endif
-}
-
-void tst_QVector::eraseInt() const
-{
- erase<int>(false);
-}
-
-void tst_QVector::eraseIntShared() const
-{
- erase<int>(true);
-}
-
-void tst_QVector::eraseMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- erase<Movable>(false);
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseMovableShared() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- erase<Movable>(true);
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- erase<Custom>(false);
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::eraseCustomShared() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- erase<Custom>(true);
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T> void tst_QVector::eraseReserved() const
-{
- {
- QVector<T> v(12);
- v.reserve(16);
- v.erase(v.begin());
- QCOMPARE(v.size(), 11);
- v.erase(v.begin(), v.end());
- QCOMPARE(v.size(), 0);
- }
- {
- QVector<T> v(12);
- v.reserve(16);
- v.erase(v.begin() + 1);
- QCOMPARE(v.size(), 11);
- v.erase(v.begin() + 1, v.end());
- QCOMPARE(v.size(), 1);
- }
- {
- QVector<T> v(12);
- v.reserve(16);
- v.erase(v.begin(), v.end() - 1);
- QCOMPARE(v.size(), 1);
- }
- {
- QVector<T> v(12);
- v.reserve(16);
- v.erase(v.begin() + 5);
- QCOMPARE(v.size(), 11);
- v.erase(v.begin() + 1, v.end() - 1);
- QCOMPARE(v.size(), 2);
- }
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- {
- QVector<T> v(10);
- v.reserve(16);
- v.setSharable(false);
- v.erase(v.begin() + 3);
- QCOMPARE(v.size(), 9);
- v.erase(v.begin(), v.end() - 1);
- QCOMPARE(v.size(), 1);
- }
-#endif
-}
-
-void tst_QVector::eraseReservedInt() const
-{
- eraseReserved<int>();
-}
-
-void tst_QVector::eraseReservedMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- eraseReserved<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::eraseReservedCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- eraseReserved<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::fill() const
-{
- QVector<T> myvec;
-
- // resize
- myvec.resize(5);
- myvec.fill(SimpleValue<T>::at(1));
- QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(1) << SimpleValue<T>::at(1)
- << SimpleValue<T>::at(1) << SimpleValue<T>::at(1)
- << SimpleValue<T>::at(1));
-
- // make sure it can resize itself too
- myvec.fill(SimpleValue<T>::at(2), 10);
- QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
- << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
- << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
- << SimpleValue<T>::at(2) << SimpleValue<T>::at(2)
- << SimpleValue<T>::at(2) << SimpleValue<T>::at(2));
-}
-
-void tst_QVector::fillInt() const
-{
- fill<int>();
-}
-
-void tst_QVector::fillMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- fill<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::fillCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- fill<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::first() const
-{
- QVector<int> myvec;
- myvec << 69 << 42 << 3;
-
- // test it starts ok
- QCOMPARE(myvec.first(), 69);
- QCOMPARE(myvec.constFirst(), 69);
-
- // test removal changes
- myvec.remove(0);
- QCOMPARE(myvec.first(), 42);
- QCOMPARE(myvec.constFirst(), 42);
-
- // test prepend changes
- myvec.prepend(23);
- QCOMPARE(myvec.first(), 23);
- QCOMPARE(myvec.constFirst(), 23);
-}
-
-void tst_QVector::constFirst() const
-{
- QVector<int> myvec;
- myvec << 69 << 42 << 3;
-
- // test it starts ok
- QCOMPARE(myvec.constFirst(), 69);
- QVERIFY(myvec.isDetached());
-
- QVector<int> myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constFirst(), 69);
- QCOMPARE(myvecCopy.constFirst(), 69);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test removal changes
- myvec.remove(0);
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constFirst(), 42);
- QCOMPARE(myvecCopy.constFirst(), 69);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constFirst(), 42);
- QCOMPARE(myvecCopy.constFirst(), 42);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test prepend changes
- myvec.prepend(23);
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constFirst(), 23);
- QCOMPARE(myvecCopy.constFirst(), 42);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constFirst(), 23);
- QCOMPARE(myvecCopy.constFirst(), 23);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-}
-
-
-template<typename T>
-void tst_QVector::fromList() const
-{
- QList<T> list;
- list << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3);
-
- QVector<T> myvec;
- myvec = QVector<T>::fromList(list);
-
- // test it worked ok
- QCOMPARE(myvec, QVector<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3));
- QCOMPARE(list, QList<T>() << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3));
-}
-
-void tst_QVector::fromListInt() const
-{
- fromList<int>();
-}
-
-void tst_QVector::fromListMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- fromList<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::fromListCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- fromList<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::fromStdVector() const
-{
- // stl = :(
- std::vector<QString> svec;
- svec.push_back(QLatin1String("aaa"));
- svec.push_back(QLatin1String("bbb"));
- svec.push_back(QLatin1String("ninjas"));
- svec.push_back(QLatin1String("pirates"));
- QVector<QString> myvec = QVector<QString>::fromStdVector(svec);
-
- // test it converts ok
- QCOMPARE(myvec, QVector<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
-}
-
-void tst_QVector::indexOf() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C" << "B" << "A";
-
- QVERIFY(myvec.indexOf("B") == 1);
- QVERIFY(myvec.indexOf("B", 1) == 1);
- QVERIFY(myvec.indexOf("B", 2) == 3);
- QVERIFY(myvec.indexOf("X") == -1);
- QVERIFY(myvec.indexOf("X", 2) == -1);
-
- // add an X
- myvec << "X";
- QVERIFY(myvec.indexOf("X") == 5);
- QVERIFY(myvec.indexOf("X", 5) == 5);
- QVERIFY(myvec.indexOf("X", 6) == -1);
-
- // remove first A
- myvec.remove(0);
- QVERIFY(myvec.indexOf("A") == 3);
- QVERIFY(myvec.indexOf("A", 3) == 3);
- QVERIFY(myvec.indexOf("A", 4) == -1);
-}
-
-template <typename T>
-void tst_QVector::insert() const
-{
- QVector<T> myvec;
- const T
- tA = SimpleValue<T>::at(0),
- tB = SimpleValue<T>::at(1),
- tC = SimpleValue<T>::at(2),
- tX = SimpleValue<T>::at(3),
- tZ = SimpleValue<T>::at(4),
- tT = SimpleValue<T>::at(5),
- ti = SimpleValue<T>::at(6);
- myvec << tA << tB << tC;
- QVector<T> myvec2 = myvec;
-
- // first position
- QCOMPARE(myvec.at(0), tA);
- myvec.insert(0, tX);
- QCOMPARE(myvec.at(0), tX);
- QCOMPARE(myvec.at(1), tA);
-
- QCOMPARE(myvec2.at(0), tA);
- myvec2.insert(myvec2.begin(), tX);
- QCOMPARE(myvec2.at(0), tX);
- QCOMPARE(myvec2.at(1), tA);
-
- // middle
- myvec.insert(1, tZ);
- QCOMPARE(myvec.at(0), tX);
- QCOMPARE(myvec.at(1), tZ);
- QCOMPARE(myvec.at(2), tA);
-
- myvec2.insert(myvec2.begin() + 1, tZ);
- QCOMPARE(myvec2.at(0), tX);
- QCOMPARE(myvec2.at(1), tZ);
- QCOMPARE(myvec2.at(2), tA);
-
- // end
- myvec.insert(5, tT);
- QCOMPARE(myvec.at(5), tT);
- QCOMPARE(myvec.at(4), tC);
-
- myvec2.insert(myvec2.end(), tT);
- QCOMPARE(myvec2.at(5), tT);
- QCOMPARE(myvec2.at(4), tC);
-
- // insert a lot of garbage in the middle
- myvec.insert(2, 2, ti);
- QCOMPARE(myvec, QVector<T>() << tX << tZ << ti << ti
- << tA << tB << tC << tT);
-
- myvec2.insert(myvec2.begin() + 2, 2, ti);
- QCOMPARE(myvec2, myvec);
-
- // insert from references to the same container:
- myvec.insert(0, 1, myvec[5]); // inserts tB
- myvec2.insert(0, 1, myvec2[5]); // inserts tB
- QCOMPARE(myvec, QVector<T>() << tB << tX << tZ << ti << ti
- << tA << tB << tC << tT);
- QCOMPARE(myvec2, myvec);
-
- myvec.insert(0, 1, const_cast<const QVector<T>&>(myvec)[0]); // inserts tB
- myvec2.insert(0, 1, const_cast<const QVector<T>&>(myvec2)[0]); // inserts tB
- QCOMPARE(myvec, QVector<T>() << tB << tB << tX << tZ << ti << ti
- << tA << tB << tC << tT);
- QCOMPARE(myvec2, myvec);
-}
-
-void tst_QVector::insertInt() const
-{
- insert<int>();
-}
-
-void tst_QVector::insertMovable() const
-{
- insert<Movable>();
-}
-
-void tst_QVector::insertCustom() const
-{
- insert<Custom>();
-}
-
-void tst_QVector::isEmpty() const
-{
- QVector<QString> myvec;
-
- // starts ok
- QVERIFY(myvec.isEmpty());
-
- // not empty now
- myvec.append(QLatin1String("hello there"));
- QVERIFY(!myvec.isEmpty());
-
- // empty again
- myvec.remove(0);
- QVERIFY(myvec.isEmpty());
-}
-
-void tst_QVector::last() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- // test starts ok
- QCOMPARE(myvec.last(), QLatin1String("C"));
- QCOMPARE(myvec.constLast(), QLatin1String("C"));
-
- // test it changes ok
- myvec.append(QLatin1String("X"));
- QCOMPARE(myvec.last(), QLatin1String("X"));
- QCOMPARE(myvec.constLast(), QLatin1String("X"));
-
- // and remove again
- myvec.remove(3);
- QCOMPARE(myvec.last(), QLatin1String("C"));
- QCOMPARE(myvec.constLast(), QLatin1String("C"));
-}
-
-void tst_QVector::constLast() const
-{
- QVector<int> myvec;
- myvec << 69 << 42 << 3;
-
- // test it starts ok
- QCOMPARE(myvec.constLast(), 3);
- QVERIFY(myvec.isDetached());
-
- QVector<int> myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constLast(), 3);
- QCOMPARE(myvecCopy.constLast(), 3);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test removal changes
- myvec.removeLast();
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constLast(), 42);
- QCOMPARE(myvecCopy.constLast(), 3);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constLast(), 42);
- QCOMPARE(myvecCopy.constLast(), 42);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- // test prepend changes
- myvec.append(23);
- QVERIFY(myvec.isDetached());
- QVERIFY(!myvec.isSharedWith(myvecCopy));
- QCOMPARE(myvec.constLast(), 23);
- QCOMPARE(myvecCopy.constLast(), 42);
-
- myvecCopy = myvec;
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-
- QCOMPARE(myvec.constLast(), 23);
- QCOMPARE(myvecCopy.constLast(), 23);
-
- QVERIFY(!myvec.isDetached());
- QVERIFY(!myvecCopy.isDetached());
- QVERIFY(myvec.isSharedWith(myvecCopy));
- QVERIFY(myvecCopy.isSharedWith(myvec));
-}
-
-void tst_QVector::lastIndexOf() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C" << "B" << "A";
-
- QVERIFY(myvec.lastIndexOf("B") == 3);
- QVERIFY(myvec.lastIndexOf("B", 2) == 1);
- QVERIFY(myvec.lastIndexOf("X") == -1);
- QVERIFY(myvec.lastIndexOf("X", 2) == -1);
-
- // add an X
- myvec << "X";
- QVERIFY(myvec.lastIndexOf("X") == 5);
- QVERIFY(myvec.lastIndexOf("X", 5) == 5);
- QVERIFY(myvec.lastIndexOf("X", 3) == -1);
-
- // remove first A
- myvec.remove(0);
- QVERIFY(myvec.lastIndexOf("A") == 3);
- QVERIFY(myvec.lastIndexOf("A", 3) == 3);
- QVERIFY(myvec.lastIndexOf("A", 2) == -1);
-}
-
-void tst_QVector::mid() const
-{
- QVector<QString> list;
- list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty";
-
- QCOMPARE(list.mid(3, 3), QVector<QString>() << "bak" << "buck" << "hello");
- QCOMPARE(list.mid(6, 10), QVector<QString>() << "kitty");
- QCOMPARE(list.mid(-1, 20), list);
- QCOMPARE(list.mid(4), QVector<QString>() << "buck" << "hello" << "kitty");
-}
-
-template <typename T>
-void tst_QVector::qhash() const
-{
- QVector<T> l1, l2;
- QCOMPARE(qHash(l1), qHash(l2));
- l1 << SimpleValue<T>::at(0);
- l2 << SimpleValue<T>::at(0);
- QCOMPARE(qHash(l1), qHash(l2));
-}
-
-template <typename T>
-void tst_QVector::move() const
-{
- QVector<T> list;
- list << T_FOO << T_BAR << T_BAZ;
-
- // move an item
- list.move(0, list.count() - 1);
- QCOMPARE(list, QVector<T>() << T_BAR << T_BAZ << T_FOO);
-
- // move it back
- list.move(list.count() - 1, 0);
- QCOMPARE(list, QVector<T>() << T_FOO << T_BAR << T_BAZ);
-
- // move an item in the middle
- list.move(1, 0);
- QCOMPARE(list, QVector<T>() << T_BAR << T_FOO << T_BAZ);
-}
-
-void tst_QVector::moveInt() const
-{
- move<int>();
-}
-
-void tst_QVector::moveMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- move<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::moveCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- move<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::prepend() const
-{
- QVector<T> myvec;
- T val1 = SimpleValue<T>::at(0);
- T val2 = SimpleValue<T>::at(1);
- T val3 = SimpleValue<T>::at(2);
- T val4 = SimpleValue<T>::at(3);
- T val5 = SimpleValue<T>::at(4);
- myvec << val1 << val2 << val3;
-
- // starts ok
- QVERIFY(myvec.size() == 3);
- QCOMPARE(myvec.at(0), val1);
-
- // add something
- myvec.prepend(val4);
- QCOMPARE(myvec.at(0), val4);
- QCOMPARE(myvec.at(1), val1);
- QVERIFY(myvec.size() == 4);
-
- // something else
- myvec.prepend(val5);
- QCOMPARE(myvec.at(0), val5);
- QCOMPARE(myvec.at(1), val4);
- QCOMPARE(myvec.at(2), val1);
- QVERIFY(myvec.size() == 5);
-
- // clear and prepend to an empty vector
- myvec.clear();
- QVERIFY(myvec.size() == 0);
- myvec.prepend(val5);
- QVERIFY(myvec.size() == 1);
- QCOMPARE(myvec.at(0), val5);
-}
-
-void tst_QVector::prependInt() const
-{
- prepend<int>();
-}
-
-void tst_QVector::prependMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- prepend<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::prependCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- prepend<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::removeAllWithAlias() const
-{
- QVector<QString> strings;
- strings << "One" << "Two" << "Three" << "One" /* must be distinct, but equal */;
- QCOMPARE(strings.removeAll(strings.front()), 2); // will trigger asan/ubsan
-}
-
-template<typename T>
-void tst_QVector::remove() const
-{
- QVector<T> myvec;
- T val1 = SimpleValue<T>::at(1);
- T val2 = SimpleValue<T>::at(2);
- T val3 = SimpleValue<T>::at(3);
- T val4 = SimpleValue<T>::at(4);
- myvec << val1 << val2 << val3;
- myvec << val1 << val2 << val3;
- myvec << val1 << val2 << val3;
- // remove middle
- myvec.remove(1);
- QCOMPARE(myvec, QVector<T>() << val1 << val3 << val1 << val2 << val3 << val1 << val2 << val3);
-
- // removeOne()
- QVERIFY(!myvec.removeOne(val4));
- QVERIFY(myvec.removeOne(val2));
- QCOMPARE(myvec, QVector<T>() << val1 << val3 << val1 << val3 << val1 << val2 << val3);
-
- QVector<T> myvecCopy = myvec;
- QVERIFY(myvecCopy.isSharedWith(myvec));
- // removeAll()
- QCOMPARE(myvec.removeAll(val4), 0);
- QVERIFY(myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec.removeAll(val1), 3);
- QVERIFY(!myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec, QVector<T>() << val3 << val3 << val2 << val3);
- myvecCopy = myvec;
- QVERIFY(myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec.removeAll(val2), 1);
- QVERIFY(!myvecCopy.isSharedWith(myvec));
- QCOMPARE(myvec, QVector<T>() << val3 << val3 << val3);
-
- // remove rest
- myvec.remove(0, 3);
- QCOMPARE(myvec, QVector<T>());
-}
-
-void tst_QVector::removeInt() const
-{
- remove<int>();
-}
-
-void tst_QVector::removeMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- remove<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::removeCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- remove<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-struct RemoveLastTestClass
-{
- RemoveLastTestClass() { other = 0; deleted = false; }
- RemoveLastTestClass *other;
- bool deleted;
- ~RemoveLastTestClass()
- {
- deleted = true;
- if (other)
- other->other = 0;
- }
-};
-
-void tst_QVector::removeFirstLast() const
-{
- // pop_pack - pop_front
- QVector<int> t, t2;
- t.append(1);
- t.append(2);
- t.append(3);
- t.append(4);
- t2 = t;
- t.pop_front();
- QCOMPARE(t.size(), 3);
- QCOMPARE(t.at(0), 2);
- t.pop_back();
- QCOMPARE(t.size(), 2);
- QCOMPARE(t.at(0), 2);
- QCOMPARE(t.at(1), 3);
-
- // takefirst - takeLast
- int n1 = t2.takeLast();
- QCOMPARE(t2.size(), 3);
- QCOMPARE(n1, 4);
- QCOMPARE(t2.at(0), 1);
- QCOMPARE(t2.at(2), 3);
- n1 = t2.takeFirst();
- QCOMPARE(t2.size(), 2);
- QCOMPARE(n1, 1);
- QCOMPARE(t2.at(0), 2);
- QCOMPARE(t2.at(1), 3);
-
- // remove first
- QVector<int> x, y;
- x.append(1);
- x.append(2);
- y = x;
- x.removeFirst();
- QCOMPARE(x.size(), 1);
- QCOMPARE(y.size(), 2);
- QCOMPARE(x.at(0), 2);
-
- // remove Last
- QVector<RemoveLastTestClass> v;
- v.resize(2);
- v[0].other = &(v[1]);
- v[1].other = &(v[0]);
- // Check dtor - complex type
- QVERIFY(v.at(0).other != 0);
- v.removeLast();
- QVERIFY(v.at(0).other == 0);
- QCOMPARE(v.at(0).deleted, false);
- // check iterator
- int count = 0;
- for (QVector<RemoveLastTestClass>::const_iterator i = v.constBegin(); i != v.constEnd(); ++i) {
- ++count;
- QVERIFY(i->other == 0);
- QCOMPARE(i->deleted, false);
- }
- // Check size
- QCOMPARE(count, 1);
- QCOMPARE(v.size(), 1);
- v.removeLast();
- QCOMPARE(v.size(), 0);
- // Check if we do correct realloc
- QVector<int> v2, v3;
- v2.append(1);
- v2.append(2);
- v3 = v2; // shared
- v2.removeLast();
- QCOMPARE(v2.size(), 1);
- QCOMPARE(v3.size(), 2);
- QCOMPARE(v2.at(0), 1);
- QCOMPARE(v3.at(0), 1);
- QCOMPARE(v3.at(1), 2);
-
- // Remove last with shared
- QVector<int> z1, z2;
- z1.append(9);
- z2 = z1;
- z1.removeLast();
- QCOMPARE(z1.size(), 0);
- QCOMPARE(z2.size(), 1);
- QCOMPARE(z2.at(0), 9);
-}
-
-
-void tst_QVector::resizePOD_data() const
-{
- QTest::addColumn<QVector<int> >("vector");
- QTest::addColumn<int>("size");
-
- QVERIFY(!QTypeInfo<int>::isComplex);
- QVERIFY(!QTypeInfo<int>::isStatic);
-
- QVector<int> null;
- QVector<int> empty(0, 5);
- QVector<int> emptyReserved;
- QVector<int> nonEmpty;
- QVector<int> nonEmptyReserved;
-
- emptyReserved.reserve(10);
- nonEmptyReserved.reserve(15);
- nonEmpty << 0 << 1 << 2 << 3 << 4;
- nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6;
- QVERIFY(emptyReserved.capacity() >= 10);
- QVERIFY(nonEmptyReserved.capacity() >= 15);
-
- QTest::newRow("null") << null << 10;
- QTest::newRow("empty") << empty << 10;
- QTest::newRow("emptyReserved") << emptyReserved << 10;
- QTest::newRow("nonEmpty") << nonEmpty << 10;
- QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- QVector<int> nullNotShared;
- QVector<int> emptyNotShared(0, 5);
- QVector<int> emptyReservedNotShared;
- QVector<int> nonEmptyNotShared;
- QVector<int> nonEmptyReservedNotShared;
-
- emptyReservedNotShared.reserve(10);
- nonEmptyReservedNotShared.reserve(15);
- nonEmptyNotShared << 0 << 1 << 2 << 3 << 4;
- nonEmptyReservedNotShared << 0 << 1 << 2 << 3 << 4 << 5 << 6;
- QVERIFY(emptyReservedNotShared.capacity() >= 10);
- QVERIFY(nonEmptyReservedNotShared.capacity() >= 15);
-
- emptyNotShared.setSharable(false);
- emptyReservedNotShared.setSharable(false);
- nonEmptyNotShared.setSharable(false);
- nonEmptyReservedNotShared.setSharable(false);
-
- QTest::newRow("nullNotShared") << nullNotShared << 10;
- QTest::newRow("emptyNotShared") << emptyNotShared << 10;
- QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10;
- QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10;
- QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10;
-#endif
-}
-
-void tst_QVector::resizePOD() const
-{
- QFETCH(QVector<int>, vector);
- QFETCH(int, size);
-
- const int oldSize = vector.size();
-
- vector.resize(size);
- QCOMPARE(vector.size(), size);
- QVERIFY(vector.capacity() >= size);
- for (int i = oldSize; i < size; ++i)
- QVERIFY(vector[i] == 0); // check initialization
-
- const int capacity = vector.capacity();
-
- vector.clear();
- QCOMPARE(vector.size(), 0);
- QVERIFY(vector.capacity() <= capacity);
-}
-
-void tst_QVector::resizeComplexMovable_data() const
-{
- QTest::addColumn<QVector<Movable> >("vector");
- QTest::addColumn<int>("size");
-
- QVERIFY(QTypeInfo<Movable>::isComplex);
- QVERIFY(!QTypeInfo<Movable>::isStatic);
-
- QVector<Movable> null;
- QVector<Movable> empty(0, 'Q');
- QVector<Movable> emptyReserved;
- QVector<Movable> nonEmpty;
- QVector<Movable> nonEmptyReserved;
-
- emptyReserved.reserve(10);
- nonEmptyReserved.reserve(15);
- nonEmpty << '0' << '1' << '2' << '3' << '4';
- nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6';
- QVERIFY(emptyReserved.capacity() >= 10);
- QVERIFY(nonEmptyReserved.capacity() >= 15);
-
- QTest::newRow("null") << null << 10;
- QTest::newRow("empty") << empty << 10;
- QTest::newRow("emptyReserved") << emptyReserved << 10;
- QTest::newRow("nonEmpty") << nonEmpty << 10;
- QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- QVector<Movable> nullNotShared;
- QVector<Movable> emptyNotShared(0, 'Q');
- QVector<Movable> emptyReservedNotShared;
- QVector<Movable> nonEmptyNotShared;
- QVector<Movable> nonEmptyReservedNotShared;
-
- emptyReservedNotShared.reserve(10);
- nonEmptyReservedNotShared.reserve(15);
- nonEmptyNotShared << '0' << '1' << '2' << '3' << '4';
- nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6';
- QVERIFY(emptyReservedNotShared.capacity() >= 10);
- QVERIFY(nonEmptyReservedNotShared.capacity() >= 15);
-
- emptyNotShared.setSharable(false);
- emptyReservedNotShared.setSharable(false);
- nonEmptyNotShared.setSharable(false);
- nonEmptyReservedNotShared.setSharable(false);
-
- QTest::newRow("nullNotShared") << nullNotShared << 10;
- QTest::newRow("emptyNotShared") << emptyNotShared << 10;
- QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10;
- QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10;
- QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10;
-#endif
-}
-
-void tst_QVector::resizeComplexMovable() const
-{
- const int items = Movable::counter.loadAcquire();
- {
- QFETCH(QVector<Movable>, vector);
- QFETCH(int, size);
-
- const int oldSize = vector.size();
-
- vector.resize(size);
- QCOMPARE(vector.size(), size);
- QVERIFY(vector.capacity() >= size);
- for (int i = oldSize; i < size; ++i)
- QVERIFY(vector[i] == 'j'); // check initialization
-
- const int capacity = vector.capacity();
-
- vector.resize(0);
- QCOMPARE(vector.size(), 0);
- QVERIFY(vector.capacity() <= capacity);
- }
- QCOMPARE(items, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::resizeComplex_data() const
-{
- QTest::addColumn<QVector<Custom> >("vector");
- QTest::addColumn<int>("size");
-
- QVERIFY(QTypeInfo<Custom>::isComplex);
- QVERIFY(QTypeInfo<Custom>::isStatic);
-
- QVector<Custom> null;
- QVector<Custom> empty(0, '0');
- QVector<Custom> emptyReserved;
- QVector<Custom> nonEmpty;
- QVector<Custom> nonEmptyReserved;
-
- emptyReserved.reserve(10);
- nonEmptyReserved.reserve(15);
- nonEmpty << '0' << '1' << '2' << '3' << '4';
- nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6';
- QVERIFY(emptyReserved.capacity() >= 10);
- QVERIFY(nonEmptyReserved.capacity() >= 15);
-
- QTest::newRow("null") << null << 10;
- QTest::newRow("empty") << empty << 10;
- QTest::newRow("emptyReserved") << emptyReserved << 10;
- QTest::newRow("nonEmpty") << nonEmpty << 10;
- QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10;
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- QVector<Custom> nullNotShared;
- QVector<Custom> emptyNotShared(0, '0');
- QVector<Custom> emptyReservedNotShared;
- QVector<Custom> nonEmptyNotShared;
- QVector<Custom> nonEmptyReservedNotShared;
-
- emptyReservedNotShared.reserve(10);
- nonEmptyReservedNotShared.reserve(15);
- nonEmptyNotShared << '0' << '1' << '2' << '3' << '4';
- nonEmptyReservedNotShared << '0' << '1' << '2' << '3' << '4' << '5' << '6';
- QVERIFY(emptyReservedNotShared.capacity() >= 10);
- QVERIFY(nonEmptyReservedNotShared.capacity() >= 15);
-
- emptyNotShared.setSharable(false);
- emptyReservedNotShared.setSharable(false);
- nonEmptyNotShared.setSharable(false);
- nonEmptyReservedNotShared.setSharable(false);
-
- QTest::newRow("nullNotShared") << nullNotShared << 10;
- QTest::newRow("emptyNotShared") << emptyNotShared << 10;
- QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10;
- QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10;
- QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10;
-#endif
-}
-
-void tst_QVector::resizeComplex() const
-{
- const int items = Custom::counter.loadAcquire();
- {
- QFETCH(QVector<Custom>, vector);
- QFETCH(int, size);
-
- int oldSize = vector.size();
- vector.resize(size);
- QCOMPARE(vector.size(), size);
- QVERIFY(vector.capacity() >= size);
- for (int i = oldSize; i < size; ++i)
- QVERIFY(vector[i].i == 'j'); // check default initialization
-
- const int capacity = vector.capacity();
-
- vector.resize(0);
- QCOMPARE(vector.size(), 0);
- QVERIFY(vector.isEmpty());
- QVERIFY(vector.capacity() <= capacity);
- }
- QCOMPARE(Custom::counter.loadAcquire(), items);
-}
-
-void tst_QVector::resizeCtorAndDtor() const
-{
- const int items = Custom::counter.loadAcquire();
- {
- QVector<Custom> null;
- QVector<Custom> empty(0, '0');
- QVector<Custom> emptyReserved;
- QVector<Custom> nonEmpty;
- QVector<Custom> nonEmptyReserved;
-
- emptyReserved.reserve(10);
- nonEmptyReserved.reserve(15);
- nonEmpty << '0' << '1' << '2' << '3' << '4';
- nonEmptyReserved << '0' << '1' << '2' << '3' << '4' << '5' << '6';
- QVERIFY(emptyReserved.capacity() >= 10);
- QVERIFY(nonEmptyReserved.capacity() >= 15);
-
- // start playing with vectors
- null.resize(21);
- nonEmpty.resize(2);
- emptyReserved.resize(0);
- nonEmpty.resize(0);
- nonEmptyReserved.resize(2);
- }
- QCOMPARE(Custom::counter.loadAcquire(), items);
-}
-
-void tst_QVector::reverseIterators() const
-{
- QVector<int> v;
- v << 1 << 2 << 3 << 4;
- QVector<int> vr = v;
- std::reverse(vr.begin(), vr.end());
- const QVector<int> &cvr = vr;
- QVERIFY(std::equal(v.begin(), v.end(), vr.rbegin()));
- QVERIFY(std::equal(v.begin(), v.end(), vr.crbegin()));
- QVERIFY(std::equal(v.begin(), v.end(), cvr.rbegin()));
- QVERIFY(std::equal(vr.rbegin(), vr.rend(), v.begin()));
- QVERIFY(std::equal(vr.crbegin(), vr.crend(), v.begin()));
- QVERIFY(std::equal(cvr.rbegin(), cvr.rend(), v.begin()));
-}
-
-template<typename T>
-void tst_QVector::size() const
-{
- // zero size
- QVector<T> myvec;
- QVERIFY(myvec.size() == 0);
-
- // grow
- myvec.append(SimpleValue<T>::at(0));
- QVERIFY(myvec.size() == 1);
- myvec.append(SimpleValue<T>::at(1));
- QVERIFY(myvec.size() == 2);
-
- // shrink
- myvec.remove(0);
- QVERIFY(myvec.size() == 1);
- myvec.remove(0);
- QVERIFY(myvec.size() == 0);
-}
-
-void tst_QVector::sizeInt() const
-{
- size<int>();
-}
-
-void tst_QVector::sizeMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- size<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::sizeCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- size<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-// ::squeeze() is tested in ::capacity().
-
-void tst_QVector::startsWith() const
-{
- QVector<int> myvec;
-
- // empty vector
- QVERIFY(!myvec.startsWith(1));
-
- // add the one, should work
- myvec.prepend(1);
- QVERIFY(myvec.startsWith(1));
-
- // add something else, fails now
- myvec.prepend(3);
- QVERIFY(!myvec.startsWith(1));
-
- // remove it again :)
- myvec.remove(0);
- QVERIFY(myvec.startsWith(1));
-}
-
-template<typename T>
-void tst_QVector::swap() const
-{
- QVector<T> v1, v2;
- T val1 = SimpleValue<T>::at(0);
- T val2 = SimpleValue<T>::at(1);
- T val3 = SimpleValue<T>::at(2);
- T val4 = SimpleValue<T>::at(3);
- T val5 = SimpleValue<T>::at(4);
- T val6 = SimpleValue<T>::at(5);
- v1 << val1 << val2 << val3;
- v2 << val4 << val5 << val6;
-
- v1.swap(v2);
- QCOMPARE(v1,QVector<T>() << val4 << val5 << val6);
- QCOMPARE(v2,QVector<T>() << val1 << val2 << val3);
-}
-
-void tst_QVector::swapInt() const
-{
- swap<int>();
-}
-
-void tst_QVector::swapMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- swap<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::swapCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- swap<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::toList() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- // make sure it converts and doesn't modify the original vector
- QCOMPARE(myvec.toList(), QList<QString>() << "A" << "B" << "C");
- QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
-}
-
-void tst_QVector::toStdVector() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- std::vector<QString> svec = myvec.toStdVector();
- QCOMPARE(svec.at(0), QLatin1String("A"));
- QCOMPARE(svec.at(1), QLatin1String("B"));
- QCOMPARE(svec.at(2), QLatin1String("C"));
-
- QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
-}
-
-void tst_QVector::value() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
-
- // valid calls
- QCOMPARE(myvec.value(0), QLatin1String("A"));
- QCOMPARE(myvec.value(1), QLatin1String("B"));
- QCOMPARE(myvec.value(2), QLatin1String("C"));
-
- // default calls
- QCOMPARE(myvec.value(-1), QString());
- QCOMPARE(myvec.value(3), QString());
-
- // test calls with a provided default, valid calls
- QCOMPARE(myvec.value(0, QLatin1String("default")), QLatin1String("A"));
- QCOMPARE(myvec.value(1, QLatin1String("default")), QLatin1String("B"));
- QCOMPARE(myvec.value(2, QLatin1String("default")), QLatin1String("C"));
-
- // test calls with a provided default that will return the default
- QCOMPARE(myvec.value(-1, QLatin1String("default")), QLatin1String("default"));
- QCOMPARE(myvec.value(3, QLatin1String("default")), QLatin1String("default"));
-}
-
-void tst_QVector::testOperators() const
-{
- QVector<QString> myvec;
- myvec << "A" << "B" << "C";
- QVector<QString> myvectwo;
- myvectwo << "D" << "E" << "F";
- QVector<QString> combined;
- combined << "A" << "B" << "C" << "D" << "E" << "F";
-
- // !=
- QVERIFY(myvec != myvectwo);
-
- // +
- QCOMPARE(myvec + myvectwo, combined);
- QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
- QCOMPARE(myvectwo, QVector<QString>() << "D" << "E" << "F");
-
- // +=
- myvec += myvectwo;
- QCOMPARE(myvec, combined);
-
- // ==
- QVERIFY(myvec == combined);
-
- // <, >, <=, >=
- QVERIFY(!(myvec < combined));
- QVERIFY(!(myvec > combined));
- QVERIFY( myvec <= combined);
- QVERIFY( myvec >= combined);
- combined.push_back("G");
- QVERIFY( myvec < combined);
- QVERIFY(!(myvec > combined));
- QVERIFY( myvec <= combined);
- QVERIFY(!(myvec >= combined));
- QVERIFY(combined > myvec);
- QVERIFY(combined >= myvec);
-
- // []
- QCOMPARE(myvec[0], QLatin1String("A"));
- QCOMPARE(myvec[1], QLatin1String("B"));
- QCOMPARE(myvec[2], QLatin1String("C"));
- QCOMPARE(myvec[3], QLatin1String("D"));
- QCOMPARE(myvec[4], QLatin1String("E"));
- QCOMPARE(myvec[5], QLatin1String("F"));
-}
-
-
-int fooCtor;
-int fooDtor;
-
-struct Foo
-{
- int *p;
-
- Foo() { p = new int; ++fooCtor; }
- Foo(const Foo &other) { Q_UNUSED(other); p = new int; ++fooCtor; }
-
- void operator=(const Foo & /* other */) { }
-
- ~Foo() { delete p; ++fooDtor; }
-};
-
-void tst_QVector::reserve()
-{
- fooCtor = 0;
- fooDtor = 0;
- {
- QVector<Foo> a;
- a.resize(2);
- QCOMPARE(fooCtor, 2);
- QVector<Foo> b(a);
- b.reserve(1);
- QCOMPARE(b.size(), a.size());
- QCOMPARE(fooDtor, 0);
- }
- QCOMPARE(fooCtor, fooDtor);
-}
-
-// This is a regression test for QTBUG-51758
-void tst_QVector::reserveZero()
-{
- QVector<int> vec;
- vec.detach();
- vec.reserve(0); // should not crash
- QCOMPARE(vec.size(), 0);
- QCOMPARE(vec.capacity(), 0);
- vec.squeeze();
- QCOMPARE(vec.size(), 0);
- QCOMPARE(vec.capacity(), 0);
- vec.reserve(-1);
- QCOMPARE(vec.size(), 0);
- QCOMPARE(vec.capacity(), 0);
- vec.append(42);
- QCOMPARE(vec.size(), 1);
- QVERIFY(vec.capacity() >= 1);
-}
-
-// This is a regression test for QTBUG-11763, where memory would be reallocated
-// soon after copying a QVector.
-void tst_QVector::reallocAfterCopy_data()
-{
- QTest::addColumn<int>("capacity");
- QTest::addColumn<int>("fill_size");
- QTest::addColumn<int>("func_id");
- QTest::addColumn<int>("result1");
- QTest::addColumn<int>("result2");
- QTest::addColumn<int>("result3");
- QTest::addColumn<int>("result4");
-
- int result1, result2, result3, result4;
- int fill_size;
- for (int i = 70; i <= 100; i += 10) {
- const QByteArray prefix = "reallocAfterCopy:" + QByteArray::number(i) + ',';
- fill_size = i - 20;
- for (int j = 0; j <= 3; j++) {
- if (j == 0) { // append
- result1 = i;
- result2 = i;
- result3 = i - 19;
- result4 = i - 20;
- } else if (j == 1) { // insert(0)
- result1 = i;
- result2 = i;
- result3 = i - 19;
- result4 = i - 20;
- } else if (j == 2) { // insert(20)
- result1 = i;
- result2 = i;
- result3 = i - 19;
- result4 = i - 20;
- } else if (j == 3) { // insert(0, 10)
- result1 = i;
- result2 = i;
- result3 = i - 10;
- result4 = i - 20;
- }
- QTest::newRow((prefix + QByteArray::number(j)).constData())
- << i << fill_size << j << result1 << result2 << result3 << result4;
- }
- }
-}
-
-void tst_QVector::reallocAfterCopy()
-{
- QFETCH(int, capacity);
- QFETCH(int, fill_size);
- QFETCH(int, func_id);
- QFETCH(int, result1);
- QFETCH(int, result2);
- QFETCH(int, result3);
- QFETCH(int, result4);
-
- QVector<qreal> v1;
- QVector<qreal> v2;
-
- v1.reserve(capacity);
- v1.resize(0);
- v1.fill(qreal(1.0), fill_size);
-
- v2 = v1;
-
- // no need to test begin() and end(), there is a detach() in them
- if (func_id == 0) {
- v1.append(qreal(1.0)); //push_back is same as append
- } else if (func_id == 1) {
- v1.insert(0, qreal(1.0)); //push_front is same as prepend, insert(0)
- } else if (func_id == 2) {
- v1.insert(20, qreal(1.0));
- } else if (func_id == 3) {
- v1.insert(0, 10, qreal(1.0));
- }
-
- QCOMPARE(v1.capacity(), result1);
- QCOMPARE(v2.capacity(), result2);
- QCOMPARE(v1.size(), result3);
- QCOMPARE(v2.size(), result4);
-}
-
-template<typename T>
-void tst_QVector::initializeList()
-{
-#ifdef Q_COMPILER_INITIALIZER_LISTS
- T val1(SimpleValue<T>::at(1));
- T val2(SimpleValue<T>::at(2));
- T val3(SimpleValue<T>::at(3));
- T val4(SimpleValue<T>::at(4));
-
- QVector<T> v1 {val1, val2, val3};
- QCOMPARE(v1, QVector<T>() << val1 << val2 << val3);
- QCOMPARE(v1, (QVector<T> {val1, val2, val3}));
-
- QVector<QVector<T>> v2{ v1, {val4}, QVector<T>(), {val1, val2, val3} };
- QVector<QVector<T>> v3;
- v3 << v1 << (QVector<T>() << val4) << QVector<T>() << v1;
- QCOMPARE(v3, v2);
-
- QVector<T> v4({});
- QCOMPARE(v4.size(), 0);
-#endif
-}
-
-void tst_QVector::initializeListInt()
-{
- initializeList<int>();
-}
-
-void tst_QVector::initializeListMovable()
-{
- const int instancesCount = Movable::counter.loadAcquire();
- initializeList<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::initializeListCustom()
-{
- const int instancesCount = Custom::counter.loadAcquire();
- initializeList<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-void tst_QVector::const_shared_null()
-{
- QVector<int> v2;
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- // ### Qt6 remove this section
- QVector<int> v1;
- v1.setSharable(false);
- QVERIFY(v1.isDetached());
-
- v2.setSharable(true);
-#endif
- QVERIFY(!v2.isDetached());
-}
-
-#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
-// ### Qt6 remove this section
-template<typename T>
-void tst_QVector::setSharable_data() const
-{
- QTest::addColumn<QVector<T> >("vector");
- QTest::addColumn<int>("size");
- QTest::addColumn<int>("capacity");
- QTest::addColumn<bool>("isCapacityReserved");
-
- QVector<T> null;
- QVector<T> empty(0, SimpleValue<T>::at(1));
- QVector<T> emptyReserved;
- QVector<T> nonEmpty;
- QVector<T> nonEmptyReserved;
-
- emptyReserved.reserve(10);
- nonEmptyReserved.reserve(15);
-
- nonEmpty << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4);
- nonEmptyReserved << SimpleValue<T>::at(0) << SimpleValue<T>::at(1) << SimpleValue<T>::at(2) << SimpleValue<T>::at(3) << SimpleValue<T>::at(4) << SimpleValue<T>::at(5) << SimpleValue<T>::at(6);
-
- QVERIFY(emptyReserved.capacity() >= 10);
- QVERIFY(nonEmptyReserved.capacity() >= 15);
-
- QTest::newRow("null") << null << 0 << 0 << false;
- QTest::newRow("empty") << empty << 0 << 0 << false;
- QTest::newRow("empty, Reserved") << emptyReserved << 0 << 10 << true;
- QTest::newRow("non-empty") << nonEmpty << 5 << 0 << false;
- QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true;
-}
-
-template<typename T>
-void tst_QVector::setSharable() const
-{
- QFETCH(QVector<T>, vector);
- QFETCH(int, size);
- QFETCH(int, capacity);
- QFETCH(bool, isCapacityReserved);
-
- QVERIFY(!vector.isDetached()); // Shared with QTest
-
- vector.setSharable(true);
-
- QCOMPARE(vector.size(), size);
- if (isCapacityReserved)
- QVERIFY2(vector.capacity() >= capacity,
- qPrintable(QString("Capacity is %1, expected at least %2.")
- .arg(vector.capacity())
- .arg(capacity)));
-
- {
- QVector<T> copy(vector);
-
- QVERIFY(!copy.isDetached());
- QVERIFY(copy.isSharedWith(vector));
- }
-
- vector.setSharable(false);
- QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<T>()));
-
- {
- QVector<T> copy(vector);
-
- QVERIFY(copy.isDetached() || copy.isEmpty() || copy.isSharedWith(QVector<T>()));
- QCOMPARE(copy.size(), size);
- if (isCapacityReserved)
- QVERIFY2(copy.capacity() >= capacity,
- qPrintable(QString("Capacity is %1, expected at least %2.")
- .arg(copy.capacity())
- .arg(capacity)));
- QCOMPARE(copy, vector);
- }
-
- vector.setSharable(true);
-
- {
- QVector<T> copy(vector);
-
- QVERIFY(!copy.isDetached());
- QVERIFY(copy.isSharedWith(vector));
- }
-
- for (int i = 0; i < vector.size(); ++i)
- QCOMPARE(vector[i], SimpleValue<T>::at(i));
-
- QCOMPARE(vector.size(), size);
- if (isCapacityReserved)
- QVERIFY2(vector.capacity() >= capacity,
- qPrintable(QString("Capacity is %1, expected at least %2.")
- .arg(vector.capacity())
- .arg(capacity)));
-}
-#else
-template<typename T> void tst_QVector::setSharable_data() const
-{
-}
-
-template<typename T> void tst_QVector::setSharable() const
-{
-}
-#endif
-
-void tst_QVector::setSharableInt_data()
-{
- setSharable_data<int>();
-}
-
-void tst_QVector::setSharableMovable_data()
-{
- setSharable_data<Movable>();
-}
-
-void tst_QVector::setSharableCustom_data()
-{
- setSharable_data<Custom>();
-}
-
-void tst_QVector::setSharableInt()
-{
- setSharable<int>();
-}
-
-void tst_QVector::setSharableMovable()
-{
- const int instancesCount = Movable::counter.loadAcquire();
- setSharable<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::setSharableCustom()
-{
- const int instancesCount = Custom::counter.loadAcquire();
- setSharable<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-template<typename T>
-void tst_QVector::detach() const
-{
- {
- // detach an empty vector
- QVector<T> v;
- v.detach();
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 0);
- QCOMPARE(v.capacity(), 0);
- }
- {
- // detach an empty referenced vector
- QVector<T> v;
- QVector<T> ref(v);
- QVERIFY(!v.isDetached());
- v.detach();
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 0);
- QCOMPARE(v.capacity(), 0);
- }
- {
- // detach a not empty referenced vector
- QVector<T> v(31);
- QVector<T> ref(v);
- QVERIFY(!v.isDetached());
- v.detach();
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 31);
- QCOMPARE(v.capacity(), 31);
- }
- {
- // detach a not empty vector
- QVector<T> v(31);
- QVERIFY(v.isDetached());
- v.detach(); // detaching a detached vector
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 31);
- QCOMPARE(v.capacity(), 31);
- }
- {
- // detach a not empty vector with preallocated space
- QVector<T> v(3);
- v.reserve(8);
- QVector<T> ref(v);
- QVERIFY(!v.isDetached());
- v.detach();
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 3);
- QCOMPARE(v.capacity(), 8);
- }
- {
- // detach a not empty vector with preallocated space
- QVector<T> v(3);
- v.reserve(8);
- QVERIFY(v.isDetached());
- v.detach(); // detaching a detached vector
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 3);
- QCOMPARE(v.capacity(), 8);
- }
- {
- // detach a not empty, initialized vector
- QVector<T> v(7, SimpleValue<T>::at(1));
- QVector<T> ref(v);
- QVERIFY(!v.isDetached());
- v.detach();
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 7);
- for (int i = 0; i < v.size(); ++i)
- QCOMPARE(v[i], SimpleValue<T>::at(1));
- }
- {
- // detach a not empty, initialized vector
- QVector<T> v(7, SimpleValue<T>::at(2));
- QVERIFY(v.isDetached());
- v.detach(); // detaching a detached vector
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 7);
- for (int i = 0; i < v.size(); ++i)
- QCOMPARE(v[i], SimpleValue<T>::at(2));
- }
- {
- // detach a not empty, initialized vector with preallocated space
- QVector<T> v(7, SimpleValue<T>::at(3));
- v.reserve(31);
- QVector<T> ref(v);
- QVERIFY(!v.isDetached());
- v.detach();
- QVERIFY(v.isDetached());
- QCOMPARE(v.size(), 7);
- QCOMPARE(v.capacity(), 31);
- for (int i = 0; i < v.size(); ++i)
- QCOMPARE(v[i], SimpleValue<T>::at(3));
- }
-}
-
-void tst_QVector::detachInt() const
-{
- detach<int>();
-}
-
-void tst_QVector::detachMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- detach<Movable>();
- QCOMPARE(instancesCount, Movable::counter.loadAcquire());
-}
-
-void tst_QVector::detachCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- detach<Custom>();
- QCOMPARE(instancesCount, Custom::counter.loadAcquire());
-}
-
-static QAtomicPointer<QVector<int> > detachThreadSafetyDataInt;
-static QAtomicPointer<QVector<Movable> > detachThreadSafetyDataMovable;
-static QAtomicPointer<QVector<Custom> > detachThreadSafetyDataCustom;
-
-template<typename T> QAtomicPointer<QVector<T> > *detachThreadSafetyData();
-template<> QAtomicPointer<QVector<int> > *detachThreadSafetyData() { return &detachThreadSafetyDataInt; }
-template<> QAtomicPointer<QVector<Movable> > *detachThreadSafetyData() { return &detachThreadSafetyDataMovable; }
-template<> QAtomicPointer<QVector<Custom> > *detachThreadSafetyData() { return &detachThreadSafetyDataCustom; }
-
-static QSemaphore detachThreadSafetyLock;
-
-template<typename T>
-void tst_QVector::detachThreadSafety() const
-{
- delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(new QVector<T>(SimpleValue<T>::vector(400)));
-
- static const uint threadsCount = 5;
-
- struct : QThread {
- void run() override
- {
- QVector<T> copy(*detachThreadSafetyData<T>()->load());
- QVERIFY(!copy.isDetached());
- detachThreadSafetyLock.release();
- detachThreadSafetyLock.acquire(100);
- copy.detach();
- }
- } threads[threadsCount];
-
- for (uint i = 0; i < threadsCount; ++i)
- threads[i].start();
- QThread::yieldCurrentThread();
- detachThreadSafetyLock.acquire(threadsCount);
-
- // destroy static original data
- delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(0);
-
- QVERIFY(threadsCount < 100);
- detachThreadSafetyLock.release(threadsCount * 100);
- QThread::yieldCurrentThread();
-
- for (uint i = 0; i < threadsCount; ++i)
- threads[i].wait();
-}
-
-void tst_QVector::detachThreadSafetyInt() const
-{
- for (uint i = 0; i < 128; ++i)
- detachThreadSafety<int>();
-}
-
-void tst_QVector::detachThreadSafetyMovable() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- for (uint i = 0; i < 128; ++i) {
- detachThreadSafety<Movable>();
- QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
- }
-}
-
-void tst_QVector::detachThreadSafetyCustom() const
-{
- const int instancesCount = Custom::counter.loadAcquire();
- for (uint i = 0; i < 128; ++i) {
- detachThreadSafety<Custom>();
- QCOMPARE(Custom::counter.loadAcquire(), instancesCount);
- }
-}
-
-void tst_QVector::insertMove() const
-{
- const int instancesCount = Movable::counter.loadAcquire();
- {
- QVector<Movable> vec;
- vec.reserve(7);
- Movable m0;
- Movable m1;
- Movable m2;
- Movable m3;
- Movable m4;
- Movable m5;
- Movable m6;
-
- vec.append(std::move(m3));
- QVERIFY(m3.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m3));
- vec.push_back(std::move(m4));
- QVERIFY(m4.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m3));
- QVERIFY(vec.at(1).wasConstructedAt(&m4));
- vec.prepend(std::move(m1));
- QVERIFY(m1.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m3));
- QVERIFY(vec.at(2).wasConstructedAt(&m4));
- vec.insert(1, std::move(m2));
- QVERIFY(m2.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m2));
- QVERIFY(vec.at(2).wasConstructedAt(&m3));
- QVERIFY(vec.at(3).wasConstructedAt(&m4));
- vec += std::move(m5);
- QVERIFY(m5.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m2));
- QVERIFY(vec.at(2).wasConstructedAt(&m3));
- QVERIFY(vec.at(3).wasConstructedAt(&m4));
- QVERIFY(vec.at(4).wasConstructedAt(&m5));
- vec << std::move(m6);
- QVERIFY(m6.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m1));
- QVERIFY(vec.at(1).wasConstructedAt(&m2));
- QVERIFY(vec.at(2).wasConstructedAt(&m3));
- QVERIFY(vec.at(3).wasConstructedAt(&m4));
- QVERIFY(vec.at(4).wasConstructedAt(&m5));
- QVERIFY(vec.at(5).wasConstructedAt(&m6));
- vec.push_front(std::move(m0));
- QVERIFY(m0.wasConstructedAt(nullptr));
- QVERIFY(vec.at(0).wasConstructedAt(&m0));
- QVERIFY(vec.at(1).wasConstructedAt(&m1));
- QVERIFY(vec.at(2).wasConstructedAt(&m2));
- QVERIFY(vec.at(3).wasConstructedAt(&m3));
- QVERIFY(vec.at(4).wasConstructedAt(&m4));
- QVERIFY(vec.at(5).wasConstructedAt(&m5));
- QVERIFY(vec.at(6).wasConstructedAt(&m6));
-
- QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 14);
- }
- QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
-}
-
-QTEST_MAIN(tst_QVector)
-#include "tst_qvector.moc"
diff --git a/tests/auto/corelib/tools/qvector_strictiterators/qvector_strictiterators.pro b/tests/auto/corelib/tools/qvector_strictiterators/qvector_strictiterators.pro
deleted file mode 100644
index d6cad86aac..0000000000
--- a/tests/auto/corelib/tools/qvector_strictiterators/qvector_strictiterators.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-include(../qvector/qvector.pro)
-TARGET = tst_qvector_strictiterators
-DEFINES += QT_STRICT_ITERATORS=1 tst_QVector=tst_QVector_StrictIterators
diff --git a/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt b/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt
new file mode 100644
index 0000000000..8f6ed66841
--- /dev/null
+++ b/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qversionnumber Test:
+#####################################################################
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qversionnumber LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_qversionnumber
+ SOURCES
+ tst_qversionnumber.cpp
+)
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro b/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro
deleted file mode 100644
index e2ae91cb64..0000000000
--- a/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-CONFIG += testcase
-qtConfig(c++11): CONFIG += c++11
-qtConfig(c++14): CONFIG += c++14
-TARGET = tst_qversionnumber
-QT = core testlib
-SOURCES = tst_qversionnumber.cpp
diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
index 05579dce6e..da9dcc9366 100644
--- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
+++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <QtCore/qversionnumber.h>
#include <QtCore/qlibraryinfo.h>
@@ -73,10 +48,15 @@ private slots:
void assignment();
void fromString_data();
void fromString();
+ void fromString_extra();
void toString_data();
void toString();
void isNull_data();
void isNull();
+ void iterators_data();
+ void iterators();
+ void iteratorsAreDefaultConstructible();
+ void valueInitializedIteratorsCompareEqual();
void serialize_data();
void serialize();
void moveSemantics();
@@ -85,56 +65,56 @@ private slots:
void tst_QVersionNumber::singleInstanceData()
{
- QTest::addColumn<QVector<int> >("segments");
+ QTest::addColumn<QList<int>>("segments");
QTest::addColumn<QVersionNumber>("expectedVersion");
QTest::addColumn<QString>("expectedString");
QTest::addColumn<QString>("constructionString");
QTest::addColumn<int>("suffixIndex");
QTest::addColumn<bool>("isNull");
- // segments expectedVersion expectedString constructionString suffixIndex null
- QTest::newRow("null") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QString() << 0 << true;
- QTest::newRow("text") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QStringLiteral("text") << 0 << true;
- QTest::newRow(" text") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QStringLiteral(" text") << 0 << true;
- QTest::newRow("Empty String") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QStringLiteral("Empty String") << 0 << true;
- QTest::newRow("-1.-2") << (QVector<int>()) << QVersionNumber() << QStringLiteral("") << QStringLiteral("-1.-2") << 0 << true;
- QTest::newRow("1.-2-3") << (QVector<int>() << 1) << QVersionNumber(QVector<int>() << 1) << QStringLiteral("1") << QStringLiteral("1.-2-3") << 1 << false;
- QTest::newRow("1.2-3") << (QVector<int>() << 1 << 2) << QVersionNumber(QVector<int>() << 1 << 2) << QStringLiteral("1.2") << QStringLiteral("1.2-3") << 3 << false;
- QTest::newRow("0") << (QVector<int>() << 0) << QVersionNumber(QVector<int>() << 0) << QStringLiteral("0") << QStringLiteral("0") << 1 << false;
- QTest::newRow("0.1") << (QVector<int>() << 0 << 1) << QVersionNumber(QVector<int>() << 0 << 1) << QStringLiteral("0.1") << QStringLiteral("0.1") << 3 << false;
- QTest::newRow("0.1.2") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2") << 5 << false;
- QTest::newRow("0.1.2alpha") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2alpha") << 5 << false;
- QTest::newRow("0.1.2-alpha") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2-alpha") << 5 << false;
- QTest::newRow("0.1.2.alpha") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2.alpha") << 5 << false;
- QTest::newRow("0.1.2.3alpha") << (QVector<int>() << 0 << 1 << 2 << 3) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3) << QStringLiteral("0.1.2.3") << QStringLiteral("0.1.2.3alpha") << 7 << false;
- QTest::newRow("0.1.2.3.alpha") << (QVector<int>() << 0 << 1 << 2 << 3) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3) << QStringLiteral("0.1.2.3") << QStringLiteral("0.1.2.3.alpha") << 7 << false;
- QTest::newRow("0.1.2.3.4.alpha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4.alpha") << 9 << false;
- QTest::newRow("0.1.2.3.4 alpha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4 alpha") << 9 << false;
- QTest::newRow("0.1.2.3.4 alp ha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4 alp ha") << 9 << false;
- QTest::newRow("0.1.2.3.4alp ha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4alp ha") << 9 << false;
- QTest::newRow("0.1.2.3.4alpha ") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4alpha ") << 9 << false;
- QTest::newRow("0.1.2.3.4.5alpha ") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5) << QStringLiteral("0.1.2.3.4.5") << QStringLiteral("0.1.2.3.4.5alpha ") << 11 << false;
- QTest::newRow("0.1.2.3.4.5.6alpha ") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6) << QStringLiteral("0.1.2.3.4.5.6") << QStringLiteral("0.1.2.3.4.5.6alpha ") << 13 << false;
- QTest::newRow("0.1.2.3.4.5.6.7alpha ") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7) << QStringLiteral("0.1.2.3.4.5.6.7") << QStringLiteral("0.1.2.3.4.5.6.7alpha ") << 15 << false;
- QTest::newRow("0.1.2.3.4.5.6.7.8alpha ") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8alpha ") << 17 << false;
- QTest::newRow("0.1.2.3.4.5.6.7.8.alpha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8.alpha") << 17 << false;
- QTest::newRow("0.1.2.3.4.5.6.7.8 alpha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8 alpha") << 17 << false;
- QTest::newRow("0.1.2.3.4.5.6.7.8 alp ha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8 alp ha") << 17 << false;
- QTest::newRow("0.1.2.3.4.5.6.7.8alp ha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8alp ha") << 17 << false;
- QTest::newRow("10.09") << (QVector<int>() << 10 << 9) << QVersionNumber(QVector<int>() << 10 << 9) << QStringLiteral("10.9") << QStringLiteral("10.09") << 5 << false;
- QTest::newRow("10.0x") << (QVector<int>() << 10 << 0) << QVersionNumber(QVector<int>() << 10 << 0) << QStringLiteral("10.0") << QStringLiteral("10.0x") << 4 << false;
- QTest::newRow("10.0xTest") << (QVector<int>() << 10 << 0) << QVersionNumber(QVector<int>() << 10 << 0) << QStringLiteral("10.0") << QStringLiteral("10.0xTest") << 4 << false;
- QTest::newRow("127.09") << (QVector<int>() << 127 << 9) << QVersionNumber(QVector<int>() << 127 << 9) << QStringLiteral("127.9") << QStringLiteral("127.09") << 6 << false;
- QTest::newRow("127.0x") << (QVector<int>() << 127 << 0) << QVersionNumber(QVector<int>() << 127 << 0) << QStringLiteral("127.0") << QStringLiteral("127.0x") << 5 << false;
- QTest::newRow("127.0xTest") << (QVector<int>() << 127 << 0) << QVersionNumber(QVector<int>() << 127 << 0) << QStringLiteral("127.0") << QStringLiteral("127.0xTest") << 5 << false;
- QTest::newRow("128.09") << (QVector<int>() << 128 << 9) << QVersionNumber(QVector<int>() << 128 << 9) << QStringLiteral("128.9") << QStringLiteral("128.09") << 6 << false;
- QTest::newRow("128.0x") << (QVector<int>() << 128 << 0) << QVersionNumber(QVector<int>() << 128 << 0) << QStringLiteral("128.0") << QStringLiteral("128.0x") << 5 << false;
- QTest::newRow("128.0xTest") << (QVector<int>() << 128 << 0) << QVersionNumber(QVector<int>() << 128 << 0) << QStringLiteral("128.0") << QStringLiteral("128.0xTest") << 5 << false;
+ // segments expectedVersion expectedString constructionString suffixIndex null
+ QTest::newRow("null") << QList<int>() << QVersionNumber() << QString() << QString() << 0 << true;
+ QTest::newRow("text") << QList<int>() << QVersionNumber() << QString() << QStringLiteral("text") << 0 << true;
+ QTest::newRow(" text") << QList<int>() << QVersionNumber() << QString() << QStringLiteral(" text") << 0 << true;
+ QTest::newRow("Empty String") << QList<int>() << QVersionNumber() << QString() << QStringLiteral("Empty String") << 0 << true;
+ QTest::newRow("-1.-2") << QList<int>() << QVersionNumber() << QStringLiteral("") << QStringLiteral("-1.-2") << 0 << true;
+ QTest::newRow("1.-2-3") << QList<int> { 1 } << QVersionNumber(QList<int> { 1 }) << QStringLiteral("1") << QStringLiteral("1.-2-3") << 1 << false;
+ QTest::newRow("1.2-3") << QList<int> { 1, 2 } << QVersionNumber(QList<int> { 1, 2 }) << QStringLiteral("1.2") << QStringLiteral("1.2-3") << 3 << false;
+ QTest::newRow("0") << QList<int> { 0 } << QVersionNumber(QList<int> { 0 }) << QStringLiteral("0") << QStringLiteral("0") << 1 << false;
+ QTest::newRow("0.1") << QList<int> { 0, 1 } << QVersionNumber(QList<int> { 0, 1 }) << QStringLiteral("0.1") << QStringLiteral("0.1") << 3 << false;
+ QTest::newRow("0.1.2") << QList<int> { 0, 1, 2 } << QVersionNumber(QList<int> { 0, 1, 2 }) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2") << 5 << false;
+ QTest::newRow("0.1.2alpha") << QList<int> { 0, 1, 2 } << QVersionNumber(QList<int> { 0, 1, 2 }) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2alpha") << 5 << false;
+ QTest::newRow("0.1.2-alpha") << QList<int> { 0, 1, 2 } << QVersionNumber(QList<int> { 0, 1, 2 }) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2-alpha") << 5 << false;
+ QTest::newRow("0.1.2.alpha") << QList<int> { 0, 1, 2 } << QVersionNumber(QList<int> { 0, 1, 2 }) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2.alpha") << 5 << false;
+ QTest::newRow("0.1.2.3alpha") << QList<int> { 0, 1, 2, 3 } << QVersionNumber(QList<int> { 0, 1, 2, 3 }) << QStringLiteral("0.1.2.3") << QStringLiteral("0.1.2.3alpha") << 7 << false;
+ QTest::newRow("0.1.2.3.alpha") << QList<int> { 0, 1, 2, 3 } << QVersionNumber(QList<int> { 0, 1, 2, 3 }) << QStringLiteral("0.1.2.3") << QStringLiteral("0.1.2.3.alpha") << 7 << false;
+ QTest::newRow("0.1.2.3.4.alpha") << QList<int> { 0, 1, 2, 3, 4 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4 }) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4.alpha") << 9 << false;
+ QTest::newRow("0.1.2.3.4 alpha") << QList<int> { 0, 1, 2, 3, 4 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4 }) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4 alpha") << 9 << false;
+ QTest::newRow("0.1.2.3.4 alp ha") << QList<int> { 0, 1, 2, 3, 4 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4 }) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4 alp ha") << 9 << false;
+ QTest::newRow("0.1.2.3.4alp ha") << QList<int> { 0, 1, 2, 3, 4 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4 }) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4alp ha") << 9 << false;
+ QTest::newRow("0.1.2.3.4alpha ") << QList<int> { 0, 1, 2, 3, 4 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4 }) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4alpha ") << 9 << false;
+ QTest::newRow("0.1.2.3.4.5alpha ") << QList<int> { 0, 1, 2, 3, 4, 5 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5 }) << QStringLiteral("0.1.2.3.4.5") << QStringLiteral("0.1.2.3.4.5alpha ") << 11 << false;
+ QTest::newRow("0.1.2.3.4.5.6alpha ") << QList<int> { 0, 1, 2, 3, 4, 5, 6 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6 }) << QStringLiteral("0.1.2.3.4.5.6") << QStringLiteral("0.1.2.3.4.5.6alpha ") << 13 << false;
+ QTest::newRow("0.1.2.3.4.5.6.7alpha ") << QList<int> { 0, 1, 2, 3, 4, 5, 6, 7 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6, 7 }) << QStringLiteral("0.1.2.3.4.5.6.7") << QStringLiteral("0.1.2.3.4.5.6.7alpha ") << 15 << false;
+ QTest::newRow("0.1.2.3.4.5.6.7.8alpha ") << QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8alpha ") << 17 << false;
+ QTest::newRow("0.1.2.3.4.5.6.7.8.alpha") << QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8.alpha") << 17 << false;
+ QTest::newRow("0.1.2.3.4.5.6.7.8 alpha") << QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8 alpha") << 17 << false;
+ QTest::newRow("0.1.2.3.4.5.6.7.8 alp ha") << QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8 alp ha") << 17 << false;
+ QTest::newRow("0.1.2.3.4.5.6.7.8alp ha") << QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 } << QVersionNumber(QList<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }) << QStringLiteral("0.1.2.3.4.5.6.7.8") << QStringLiteral("0.1.2.3.4.5.6.7.8alp ha") << 17 << false;
+ QTest::newRow("10.09") << QList<int> { 10, 9 } << QVersionNumber(QList<int> { 10, 9 }) << QStringLiteral("10.9") << QStringLiteral("10.09") << 5 << false;
+ QTest::newRow("10.0x") << QList<int> { 10, 0 } << QVersionNumber(QList<int> { 10, 0 }) << QStringLiteral("10.0") << QStringLiteral("10.0x") << 4 << false;
+ QTest::newRow("10.0xTest") << QList<int> { 10, 0 } << QVersionNumber(QList<int> { 10, 0 }) << QStringLiteral("10.0") << QStringLiteral("10.0xTest") << 4 << false;
+ QTest::newRow("127.09") << QList<int> { 127, 9 } << QVersionNumber(QList<int> { 127, 9 }) << QStringLiteral("127.9") << QStringLiteral("127.09") << 6 << false;
+ QTest::newRow("127.0x") << QList<int> { 127, 0 } << QVersionNumber(QList<int> { 127, 0 }) << QStringLiteral("127.0") << QStringLiteral("127.0x") << 5 << false;
+ QTest::newRow("127.0xTest") << QList<int> { 127, 0 } << QVersionNumber(QList<int> { 127, 0 }) << QStringLiteral("127.0") << QStringLiteral("127.0xTest") << 5 << false;
+ QTest::newRow("128.09") << QList<int> { 128, 9 } << QVersionNumber(QList<int> { 128, 9 }) << QStringLiteral("128.9") << QStringLiteral("128.09") << 6 << false;
+ QTest::newRow("128.0x") << QList<int> { 128, 0 } << QVersionNumber(QList<int> { 128, 0 }) << QStringLiteral("128.0") << QStringLiteral("128.0x") << 5 << false;
+ QTest::newRow("128.0xTest") << QList<int> { 128, 0 } << QVersionNumber(QList<int> { 128, 0 }) << QStringLiteral("128.0") << QStringLiteral("128.0xTest") << 5 << false;
}
namespace UglyOperator {
// ugh, but the alternative (operator <<) is even worse...
-static inline QVector<int> operator+(QVector<int> v, int i) { v.push_back(i); return v; }
+static inline QList<int> operator+(QList<int> v, int i) { v.push_back(i); return v; }
}
void tst_QVersionNumber::comparisonData()
@@ -196,7 +176,7 @@ void tst_QVersionNumber::comparisonData()
QTest::newRow("0.-129, 0") << QVersionNumber(0, -129) << QVersionNumber(0) << false << true << true << true << false << false << -129 << false << QVersionNumber(0);
QTest::newRow("0, 0.-129") << QVersionNumber(0) << QVersionNumber(0, -129) << false << true << false << false << true << true << 129 << true << QVersionNumber(0);
- const QVector<int> common = QVector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6;
+ const QList<int> common = QList<int>({ 0, 1, 2, 3, 4, 5, 6 });
using namespace UglyOperator;
QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common + 0 + 1);
QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + 1 + 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(common + 0 + 1);
@@ -213,7 +193,7 @@ void tst_QVersionNumber::comparisonData()
void tst_QVersionNumber::initTestCase()
{
- qRegisterMetaType<QVector<int> >();
+ qRegisterMetaType<QList<int>>();
}
void tst_QVersionNumber::constructorDefault()
@@ -223,7 +203,7 @@ void tst_QVersionNumber::constructorDefault()
QCOMPARE(version.majorVersion(), 0);
QCOMPARE(version.minorVersion(), 0);
QCOMPARE(version.microVersion(), 0);
- QCOMPARE(version.segments(), QVector<int>());
+ QVERIFY(version.segments().isEmpty());
}
void tst_QVersionNumber::constructorVersioned_data()
@@ -233,7 +213,7 @@ void tst_QVersionNumber::constructorVersioned_data()
void tst_QVersionNumber::constructorVersioned()
{
- QFETCH(QVector<int>, segments);
+ QFETCH(QList<int>, segments);
QFETCH(QVersionNumber, expectedVersion);
QVersionNumber version(segments);
@@ -246,26 +226,29 @@ void tst_QVersionNumber::constructorVersioned()
void tst_QVersionNumber::constructorExplicit()
{
QVersionNumber v1(1);
- QVersionNumber v2(QVector<int>() << 1);
+ QVersionNumber v2(QList<int>({ 1 }));
QCOMPARE(v1.segments(), v2.segments());
QVersionNumber v3(1, 2);
- QVersionNumber v4(QVector<int>() << 1 << 2);
+ QVersionNumber v4(QList<int>({ 1, 2 }));
QCOMPARE(v3.segments(), v4.segments());
QVersionNumber v5(1, 2, 3);
- QVersionNumber v6(QVector<int>() << 1 << 2 << 3);
+ QVersionNumber v6(QList<int>({ 1, 2, 3 }));
QCOMPARE(v5.segments(), v6.segments());
-#ifdef Q_COMPILER_INITIALIZER_LISTS
QVersionNumber v7(4, 5, 6);
QVersionNumber v8 = {4, 5, 6};
QCOMPARE(v7.segments(), v8.segments());
-#endif
+
+ QVersionNumber v9(4, 5, 6);
+ QVersionNumber vA({4, 5, 6});
+
+ QCOMPARE(v9.segments(), vA.segments());
}
void tst_QVersionNumber::constructorCopy_data()
@@ -275,7 +258,7 @@ void tst_QVersionNumber::constructorCopy_data()
void tst_QVersionNumber::constructorCopy()
{
- QFETCH(QVector<int>, segments);
+ QFETCH(QList<int>, segments);
QFETCH(QVersionNumber, expectedVersion);
QVersionNumber original(segments);
@@ -420,14 +403,14 @@ void tst_QVersionNumber::normalized_data()
QTest::addColumn<QVersionNumber>("version");
QTest::addColumn<QVersionNumber>("expected");
- QTest::newRow("0") << QVersionNumber(0) << QVersionNumber();
- QTest::newRow("1") << QVersionNumber(1) << QVersionNumber(1);
- QTest::newRow("1.2") << QVersionNumber(1, 2) << QVersionNumber(1, 2);
- QTest::newRow("1.0") << QVersionNumber(1, 0) << QVersionNumber(1);
- QTest::newRow("1.0.0") << QVersionNumber(1, 0, 0) << QVersionNumber(1);
- QTest::newRow("1.0.1") << QVersionNumber(1, 0, 1) << QVersionNumber(1, 0, 1);
- QTest::newRow("1.0.1.0") << QVersionNumber(QVector<int>() << 1 << 0 << 1 << 0) << QVersionNumber(1, 0, 1);
- QTest::newRow("0.0.1.0") << QVersionNumber(QVector<int>() << 0 << 0 << 1 << 0) << QVersionNumber(0, 0, 1);
+ QTest::newRow("0") << QVersionNumber(0) << QVersionNumber();
+ QTest::newRow("1") << QVersionNumber(1) << QVersionNumber(1);
+ QTest::newRow("1.2") << QVersionNumber(1, 2) << QVersionNumber(1, 2);
+ QTest::newRow("1.0") << QVersionNumber(1, 0) << QVersionNumber(1);
+ QTest::newRow("1.0.0") << QVersionNumber(1, 0, 0) << QVersionNumber(1);
+ QTest::newRow("1.0.1") << QVersionNumber(1, 0, 1) << QVersionNumber(1, 0, 1);
+ QTest::newRow("1.0.1.0") << QVersionNumber(QList<int>({ 1, 0, 1, 0 })) << QVersionNumber(1, 0, 1);
+ QTest::newRow("0.0.1.0") << QVersionNumber(QList<int>({ 0, 0, 1, 0 })) << QVersionNumber(0, 0, 1);
}
void tst_QVersionNumber::normalized()
@@ -436,7 +419,7 @@ void tst_QVersionNumber::normalized()
QFETCH(QVersionNumber, expected);
QCOMPARE(version.normalized(), expected);
- QCOMPARE(qMove(version).normalized(), expected);
+ QCOMPARE(std::move(version).normalized(), expected);
}
void tst_QVersionNumber::isNormalized_data()
@@ -444,13 +427,13 @@ void tst_QVersionNumber::isNormalized_data()
QTest::addColumn<QVersionNumber>("version");
QTest::addColumn<bool>("expected");
- QTest::newRow("null") << QVersionNumber() << true;
- QTest::newRow("0") << QVersionNumber(0) << false;
- QTest::newRow("1") << QVersionNumber(1) << true;
- QTest::newRow("1.2") << QVersionNumber(1, 2) << true;
- QTest::newRow("1.0") << QVersionNumber(1, 0) << false;
- QTest::newRow("1.0.0") << QVersionNumber(1, 0, 0) << false;
- QTest::newRow("1.0.1") << QVersionNumber(1, 0, 1) << true;
+ QTest::newRow("null") << QVersionNumber() << true;
+ QTest::newRow("0") << QVersionNumber(0) << false;
+ QTest::newRow("1") << QVersionNumber(1) << true;
+ QTest::newRow("1.2") << QVersionNumber(1, 2) << true;
+ QTest::newRow("1.0") << QVersionNumber(1, 0) << false;
+ QTest::newRow("1.0.0") << QVersionNumber(1, 0, 0) << false;
+ QTest::newRow("1.0.1") << QVersionNumber(1, 0, 1) << true;
}
void tst_QVersionNumber::isNormalized()
@@ -468,7 +451,7 @@ void tst_QVersionNumber::assignment_data()
void tst_QVersionNumber::assignment()
{
- QFETCH(QVector<int>, segments);
+ QFETCH(QList<int>, segments);
QFETCH(QVersionNumber, expectedVersion);
QVersionNumber original(segments);
@@ -490,17 +473,17 @@ void tst_QVersionNumber::fromString_data()
const QString largerThanIntCanHoldString1 = "0." + QString::number(largerThanIntCanHold);
QTest::newRow(qPrintable(largerThanIntCanHoldString0))
- << QVector<int>() << QVersionNumber() << QString() << largerThanIntCanHoldString0 << 0 << true;
+ << QList<int>() << QVersionNumber() << QString() << largerThanIntCanHoldString0 << 0 << true;
QTest::newRow(qPrintable(largerThanIntCanHoldString1))
- << QVector<int>(0) << QVersionNumber(0) << QStringLiteral("0") << largerThanIntCanHoldString1 << 1 << true;
+ << QList<int>(0) << QVersionNumber(0) << QStringLiteral("0") << largerThanIntCanHoldString1 << 1 << true;
const QString largerThanULongLongCanHoldString0 = QString::number(std::numeric_limits<qulonglong>::max()) + "0.0"; // 10x ULLONG_MAX
const QString largerThanULongLongCanHoldString1 = "0." + QString::number(std::numeric_limits<qulonglong>::max()) + '0'; // 10x ULLONG_MAX
QTest::newRow(qPrintable(largerThanULongLongCanHoldString0))
- << QVector<int>() << QVersionNumber() << QString() << largerThanULongLongCanHoldString0 << 0 << true;
+ << QList<int>() << QVersionNumber() << QString() << largerThanULongLongCanHoldString0 << 0 << true;
QTest::newRow(qPrintable(largerThanULongLongCanHoldString1))
- << QVector<int>(0) << QVersionNumber(0) << QStringLiteral("0") << largerThanULongLongCanHoldString1 << 1 << true;
+ << QList<int>(0) << QVersionNumber(0) << QStringLiteral("0") << largerThanULongLongCanHoldString1 << 1 << true;
}
void tst_QVersionNumber::fromString()
@@ -509,7 +492,7 @@ void tst_QVersionNumber::fromString()
QFETCH(QVersionNumber, expectedVersion);
QFETCH(int, suffixIndex);
- int index;
+ qsizetype index;
QCOMPARE(QVersionNumber::fromString(constructionString), expectedVersion);
QCOMPARE(QVersionNumber::fromString(constructionString, &index), expectedVersion);
QCOMPARE(index, suffixIndex);
@@ -521,16 +504,56 @@ void tst_QVersionNumber::fromString()
QCOMPARE(QVersionNumber::fromString(QLatin1String(constructionString.toLatin1())), expectedVersion);
QCOMPARE(QVersionNumber::fromString(QLatin1String(constructionString.toLatin1()), &index), expectedVersion);
QCOMPARE(index, suffixIndex);
+
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_DEPRECATED
+ // check deprecated `int *suffixIndex` overload, too
+ {
+ int i;
+ QCOMPARE(QVersionNumber::fromString(constructionString, &i), expectedVersion);
+ QCOMPARE(i, suffixIndex);
+
+ QCOMPARE(QVersionNumber::fromString(QStringView(constructionString), &i), expectedVersion);
+ QCOMPARE(i, suffixIndex);
+
+ QCOMPARE(QVersionNumber::fromString(QLatin1String(constructionString.toLatin1()), &i), expectedVersion);
+ QCOMPARE(i, suffixIndex);
+ }
+ QT_WARNING_POP
+#endif
+}
+
+void tst_QVersionNumber::fromString_extra()
+{
+ // check the overloaded fromString() functions aren't ambiguous
+ // when passing explicit nullptr:
+ {
+ auto v = QVersionNumber::fromString("1.2.3-rc1", nullptr);
+ QCOMPARE(v, QVersionNumber({1, 2, 3}));
+ }
+ {
+ auto v = QVersionNumber::fromString("1.2.3-rc1", 0);
+ QCOMPARE(v, QVersionNumber({1, 2, 3}));
+ }
+
+ // check the UTF16->L1 conversion isn't doing something weird
+ {
+ qsizetype i = -1;
+ auto v = QVersionNumber::fromString(u"1.0ı", &i); // LATIN SMALL LETTER DOTLESS I
+ QCOMPARE(v, QVersionNumber(1, 0));
+ QCOMPARE(i, 3);
+ }
}
void tst_QVersionNumber::toString_data()
{
singleInstanceData();
- // segments expectedVersion expectedString constructionString suffixIndex null
- QTest::newRow("-1") << (QVector<int>() << -1) << QVersionNumber(-1) << QString("-1") << QString() << 0 << true;
- QTest::newRow("-1.0") << (QVector<int>() << -1 << 0) << QVersionNumber(-1, 0) << QString("-1.0") << QString() << 0 << true;
- QTest::newRow("1.-2") << (QVector<int>() << 1 << -2) << QVersionNumber(1, -2) << QString("1.-2") << QString() << 0 << true;
+ // segments expectedVersion expectedString constructionString suffixIndex null
+ QTest::newRow("-1") << (QList<int>({ -1 })) << QVersionNumber(-1) << QString("-1") << QString() << 0 << true;
+ QTest::newRow("-1.0") << (QList<int>({ -1, 0 })) << QVersionNumber(-1, 0) << QString("-1.0") << QString() << 0 << true;
+ QTest::newRow("1.-2") << (QList<int>({ 1, -2 })) << QVersionNumber(1, -2) << QString("1.-2") << QString() << 0 << true;
}
void tst_QVersionNumber::toString()
@@ -548,7 +571,7 @@ void tst_QVersionNumber::isNull_data()
void tst_QVersionNumber::isNull()
{
- QFETCH(QVector<int>, segments);
+ QFETCH(QList<int>, segments);
QFETCH(bool, isNull);
QVersionNumber version(segments);
@@ -556,6 +579,45 @@ void tst_QVersionNumber::isNull()
QCOMPARE(version.isNull(), isNull);
}
+void tst_QVersionNumber::iterators_data()
+{
+ singleInstanceData();
+}
+
+void tst_QVersionNumber::iterators()
+{
+ QFETCH(const QList<int>, segments);
+ QFETCH(QVersionNumber, expectedVersion);
+
+ QVERIFY(std::equal(expectedVersion.begin(), expectedVersion.end(),
+ segments.begin(), segments.end()));
+ QVERIFY(std::equal(std::as_const(expectedVersion).begin(), std::as_const(expectedVersion).end(),
+ segments.begin(), segments.end()));
+ QVERIFY(std::equal(expectedVersion.cbegin(), expectedVersion.cend(),
+ segments.cbegin(), segments.cend()));
+ QVERIFY(std::equal(expectedVersion.rbegin(), expectedVersion.rend(),
+ segments.rbegin(), segments.rend()));
+ QVERIFY(std::equal(std::as_const(expectedVersion).rbegin(), std::as_const(expectedVersion).rend(),
+ segments.rbegin(), segments.rend()));
+ QVERIFY(std::equal(expectedVersion.crbegin(), expectedVersion.crend(),
+ segments.crbegin(), segments.crend()));
+}
+
+void tst_QVersionNumber::iteratorsAreDefaultConstructible()
+{
+ static_assert(std::is_default_constructible_v<QVersionNumber::const_iterator>);
+ [[maybe_unused]] QVersionNumber::const_iterator ci;
+ [[maybe_unused]] QVersionNumber::const_reverse_iterator cri;
+}
+
+void tst_QVersionNumber::valueInitializedIteratorsCompareEqual()
+{
+ QVersionNumber::const_iterator it = {}, jt = {};
+ QCOMPARE_EQ(it, jt);
+ QVersionNumber::const_reverse_iterator rit = {}, rjt = {};
+ QCOMPARE_EQ(rit, rjt);
+}
+
void tst_QVersionNumber::serialize_data()
{
singleInstanceData();
@@ -563,7 +625,7 @@ void tst_QVersionNumber::serialize_data()
void tst_QVersionNumber::serialize()
{
- QFETCH(QVector<int>, segments);
+ QFETCH(QList<int>, segments);
QVersionNumber original(segments);
QVersionNumber version;
@@ -586,30 +648,28 @@ void tst_QVersionNumber::serialize()
void tst_QVersionNumber::moveSemantics()
{
-#ifdef Q_COMPILER_RVALUE_REFS
// QVersionNumber(QVersionNumber &&)
{
QVersionNumber v1(1, 2, 3);
- QVersionNumber v2 = qMove(v1);
+ QVersionNumber v2 = std::move(v1);
QCOMPARE(v2, QVersionNumber(1, 2, 3));
}
// QVersionNumber &operator=(QVersionNumber &&)
{
QVersionNumber v1(1, 2, 3);
QVersionNumber v2;
- v2 = qMove(v1);
+ v2 = std::move(v1);
QCOMPARE(v2, QVersionNumber(1, 2, 3));
}
- // QVersionNumber(QVector<int> &&)
+ // QVersionNumber(QList<int> &&)
{
- QVector<int> segments = QVector<int>() << 1 << 2 << 3;
+ QList<int> segments = QList<int>({ 1, 2, 3});
QVersionNumber v1(segments);
- QVersionNumber v2(qMove(segments));
+ QVersionNumber v2(std::move(segments));
QVERIFY(!v1.isNull());
QVERIFY(!v2.isNull());
QCOMPARE(v1, v2);
}
-#endif
#ifdef Q_COMPILER_REF_QUALIFIERS
// normalized()
{
@@ -620,7 +680,7 @@ void tst_QVersionNumber::moveSemantics()
QVERIFY(!v.isNull());
QVERIFY(!nv.isNull());
QVERIFY(nv.isNormalized());
- nv = qMove(v).normalized();
+ nv = std::move(v).normalized();
QVERIFY(!nv.isNull());
QVERIFY(nv.isNormalized());
}
@@ -628,17 +688,14 @@ void tst_QVersionNumber::moveSemantics()
{
QVersionNumber v(1, 2, 3);
QVERIFY(!v.isNull());
- QVector<int> segments;
+ QList<int> segments;
segments = v.segments();
QVERIFY(!v.isNull());
QVERIFY(!segments.empty());
- segments = qMove(v).segments();
+ segments = std::move(v).segments();
QVERIFY(!segments.empty());
}
#endif
-#if !defined(Q_COMPILER_RVALUE_REFS) && !defined(Q_COMPILER_REF_QUALIFIERS)
- QSKIP("This test requires C++11 move semantics support in the compiler.");
-#endif
}
void tst_QVersionNumber::qtVersion()
diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro
deleted file mode 100644
index f28cf21b8b..0000000000
--- a/tests/auto/corelib/tools/tools.pro
+++ /dev/null
@@ -1,71 +0,0 @@
-TEMPLATE=subdirs
-SUBDIRS=\
- collections \
- containerapisymmetry \
- qalgorithms \
- qarraydata \
- qarraydata_strictiterators \
- qbitarray \
- qbytearray \
- qbytearraylist \
- qbytearraymatcher \
- qbytedatabuffer \
- qcache \
- qchar \
- qcollator \
- qcommandlineparser \
- qcontiguouscache \
- qcryptographichash \
- qdate \
- qdatetime \
- qeasingcurve \
- qexplicitlyshareddatapointer \
- qfreelist \
- qhash \
- qhash_strictiterators \
- qhashfunctions \
- qlatin1string \
- qline \
- qlinkedlist \
- qlist \
- qlist_strictiterators \
- qlocale \
- qmakearray \
- qmap \
- qmap_strictiterators \
- qmargins \
- qmessageauthenticationcode \
- qpair \
- qpoint \
- qpointf \
- qqueue \
- qrect \
- qregexp \
- qregularexpression \
- qringbuffer \
- qscopedpointer \
- qscopedvaluerollback \
- qset \
- qsharedpointer \
- qsize \
- qsizef \
- qstl \
- qstring \
- qstring_no_cast_from_bytearray \
- qstringapisymmetry \
- qstringbuilder \
- qstringiterator \
- qstringlist \
- qstringmatcher \
- qstringref \
- qstringview \
- qtextboundaryfinder \
- qtime \
- qtimezone \
- qtimeline \
- qvarlengtharray \
- qvector \
- qvector_strictiterators \
- qversionnumber
-
-darwin: SUBDIRS += qmacautoreleasepool